OnPlayerKeyStateChange always called?
#1

Hello,

I've been trying to make a script in which a missile is fired whenever a player is holding the KEY_ACTION button.
This missile will be fully automatic, shooting multiple missiles per second if the player is still holding that button.
The script works fine so far. However, OnPlayerKeyStateChange is obviously only called when the keystate of a player changes. Is there any other function to make it so that the function is always called? I've done some searching but I couldn't find anything.

Thanks in advance!
Reply
#2

Timer
Reply
#3

Thanks, but could you provide me with some sort of example?
Reply
#4

Код:
new bool:actionButton[MAX_PLAYERS];
static const c_missileFireRate = 200;

public OnGameModeInit()
{
    SetTimer("missileTimer", c_missileFireRate, true);
    return 1;
}

forward missileTimer();
public missileTimer()
{
    foreach(new i : Player)
    {
        if(actionButton[i])
        //And some other condition... (is player in a plane or something)
        {
            //Shoot missile
        }
    }
    return 1;
}

public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
    if(newkeys & KEY_ACTION)
    {
        actionButton[playerid] = true;
    } else {
        actionButton[playerid] = false;
    }
    return 1;
}
Reply
#5

I've been trying for a few days now to get your code working Lollypap54, and I am glad to say I got it working with my script! thanks a lot!
Reply
#6

Put a timer activated on PRESSING(button) and kill them on RELEASED(button)
Reply
#7

A small problem has appeared, sadly.

The timer is only called for the first player connected to the server (That's what I think)
The automatic fire works perfectly for this player, but other players still have the manual fire rate.
How can I make the timer so that it's called for every player who presses the button?
Reply
#8

SetTimerEx and pass the playerid argument.
Reply
#9

Quote:
Originally Posted by TheToretto
Посмотреть сообщение
SetTimerEx and pass the playerid argument.
I think it is necessary,
Reply
#10

Quote:
Originally Posted by Hazon
Посмотреть сообщение
I think it is necessary,
Did I say it is optional? Of course it is, else you're calling a global timer.
Reply
#11

Quote:
Originally Posted by TheToretto
View Post
Did I say it is optional? Of course it is, else you\'re calling a global timer.
There is no such things you call a Timer for \'playerid\'. Both timers call any function. Ex ones just have parameters.
Reply
#12

Code:
SetTimerEx("missileTimer ", c_missileFireRate, false, "i", playerid);
Is not as same as SetTimer. Except if you are planning to play alone in the server.
Reply
#13

Quote:
Originally Posted by NoahAntilles
Посмотреть сообщение
A small problem has appeared, sadly.

The timer is only called for the first player connected to the server (That's what I think)
The automatic fire works perfectly for this player, but other players still have the manual fire rate.
How can I make the timer so that it's called for every player who presses the button?
Example:
Код:
#define PRESSED(%0) \
		(((newkeys & (%0)) == (%0)) && ((oldkeys & (%0)) != (%0)))
#define RELEASED(%0) \
		(((oldkeys & (%0)) == (%0)) && ((newkeys & (%0)) != (%0)))

if(PRESSED(KEY_SPRINT))
{
	if(missileTimer[playerid] != -1) return 1;
	missileTimer[playerid] = SetTimerEx("MissileFunction", 1000, true, "d", playerid);
}
if(RELEASED(KEY_SPRINT)) {
	if(missileTimer[playerid] != -1) {
		KillTimer(missileTimer[playerid]);
		missileTimer[playerid] = -1;
	}
}
Reply
#14

Thanks for all your replies! Sadly I\'ve been getting this error:

Code:
D:\Games\SAMP Server\filterscripts\1947_test.pwn(36) : error 028: invalid subscript (not an array or too many subscripts): "FireRateTimer"
D:\Games\SAMP Server\filterscripts\1947_test.pwn(36) : warning 215: expression has no effect
D:\Games\SAMP Server\filterscripts\1947_test.pwn(36) : error 001: expected token: ";", but found "]"
D:\Games\SAMP Server\filterscripts\1947_test.pwn(36) : error 029: invalid expression, assumed zero
D:\Games\SAMP Server\filterscripts\1947_test.pwn(36) : fatal error 107: too many error messages on one line
Here is the code I\'m using:
Code:
#include <a_samp>
#include <foreach>
#include <colandreas>
#include <streamer>
#include <3DTryg>
#include <Missile>
#include <VehicleMissileCol>

#define PRESSED(%0) \
		(((newkeys & (%0)) == (%0)) && ((oldkeys & (%0)) != (%0)))
#define RELEASED(%0) \
		(((oldkeys & (%0)) == (%0)) && ((newkeys & (%0)) != (%0)))

new bool:autoFireButton[MAX_PLAYERS];
static const c_AutoFireRate = 50; //define the rate of fire in milliseconds

public OnGameModeInit()
{
    SetTimer("FireRateTimer", c_AutoFireRate, true);
    return 1;
}

forward FireRateTimer(playerid,vehicleid);
public FireRateTimer(playerid,vehicleid)
{
    if(autoFireButton[playerid])
        OnVehicleShot(playerid,VEHICLE_MISSILE_TYPE_CON);
    return 1;
}

public OnPlayerKeyStateChange(playerid, newkeys, oldkeys){
    if(IsPlayerInAnyVehicle(playerid) && GetPlayerVehicleSeat(playerid) == 0){
        new vid = GetPlayerVehicleID(playerid);
        if(IsToggleVehicleCongreve(vid)){
            if(PRESSED(GetVehicleCongreveKey(vid))){
           	    if(FireRateTimer[playerid] != -1) return 1;
	            FireRateTimer[playerid] = SetTimerEx("MissileFunction", 1000, true, "d", playerid);
                SendClientMessage(playerid, 0x00FF00FF, "button pressed.");
            }
            if(RELEASED(GetVehicleCongreveKey(vid))){
            	if(FireRateTimer[playerid] != -1) {
                    KillTimer(FireRateTimer[playerid]);
		            FireRateTimer[playerid] = -1;
                    SendClientMessage(playerid, 0x00FF00FF, "button released.");
                }
            }
        }
    }
    return 1;
}
Not sure what\'s wrong now
Reply
#15

Quote:
Originally Posted by NoahAntilles
View Post
Thanks for all your replies! Sadly I\'ve been getting this error:

Code:
D:\Games\SAMP Server\filterscripts\1947_test.pwn(36) : error 028: invalid subscript (not an array or too many subscripts): "FireRateTimer"
D:\Games\SAMP Server\filterscripts\1947_test.pwn(36) : warning 215: expression has no effect
D:\Games\SAMP Server\filterscripts\1947_test.pwn(36) : error 001: expected token: ";", but found "]"
D:\Games\SAMP Server\filterscripts\1947_test.pwn(36) : error 029: invalid expression, assumed zero
D:\Games\SAMP Server\filterscripts\1947_test.pwn(36) : fatal error 107: too many error messages on one line
Can you just specify which line is 36.

And also try removing the vehicleid in public FireRate... and forward FireRate...
Reply
#16

I removed the vehicle ID and forwarded FireRateTimer, didn\'t work.


Here is the script with all lines, sorry for not posting it in the first place. It\'s line 37

Code:
1 #include <a_samp>
2 #include <foreach>
3 #include <colandreas>
4 #include <streamer>
5 #include <3DTryg>
6 #include <Missile>
7 #include <VehicleMissileCol>
8
9 #define PRESSED(%0) \
10		(((newkeys & (%0)) == (%0)) && ((oldkeys & (%0)) != (%0)))
11 #define RELEASED(%0) \
12		(((oldkeys & (%0)) == (%0)) && ((newkeys & (%0)) != (%0)))
13
14 new bool:autoFireButton[MAX_PLAYERS];
15 static const c_AutoFireRate = 50; //define the rate of fire in milliseconds
16
17 public OnGameModeInit()
18 {
19    SetTimer("FireRateTimer", c_AutoFireRate, true);
20    return 1;
21 }
22
23 forward FireRateTimer(playerid);
24 public FireRateTimer(playerid)
25 {
26    if(autoFireButton[playerid])
27        OnVehicleShot(playerid,VEHICLE_MISSILE_TYPE_CON);
28    return 1;
29 }
30
31 forward FireRateTimer(playerid);
32 public OnPlayerKeyStateChange(playerid, newkeys, oldkeys){
33    if(IsPlayerInAnyVehicle(playerid) && GetPlayerVehicleSeat(playerid) == 0){
34        new vid = GetPlayerVehicleID(playerid);
35        if(IsToggleVehicleCongreve(vid)){
36            if(PRESSED(GetVehicleCongreveKey(vid))){
37           	    if(FireRateTimer[playerid] != -1) return 1; // <-- This is the line which gives the error
38	            FireRateTimer[playerid] = SetTimerEx("MissileFunction", 1000, true, "d", playerid);
39                SendClientMessage(playerid, 0x00FF00FF, "button pressed.");
40            }
41            if(RELEASED(GetVehicleCongreveKey(vid))){
42            	if(FireRateTimer[playerid] != -1) {
43                    KillTimer(FireRateTimer[playerid]);
44		            FireRateTimer[playerid] = -1;
45                    SendClientMessage(playerid, 0x00FF00FF, "button released.");
46                }
47            }
48        }
49    }
50    return 1;
}
Reply
#17

Quote:
Originally Posted by NoahAntilles
View Post
I removed the vehicle ID and forwarded FireRateTimer, didn\'t work.


Here is the script with all lines, sorry for not posting it in the first place. It\'s line 37

Code:
1 #include <a_samp>
2 #include <foreach>
3 #include <colandreas>
4 #include <streamer>
5 #include <3DTryg>
6 #include <Missile>
7 #include <VehicleMissileCol>
8
9 #define PRESSED(%0) \
10		(((newkeys & (%0)) == (%0)) && ((oldkeys & (%0)) != (%0)))
11 #define RELEASED(%0) \
12		(((oldkeys & (%0)) == (%0)) && ((newkeys & (%0)) != (%0)))
13
14 new bool:autoFireButton[MAX_PLAYERS];
15 static const c_AutoFireRate = 50; //define the rate of fire in milliseconds
16
17 public OnGameModeInit()
18 {
19    SetTimer("FireRateTimer", c_AutoFireRate, true);
20    return 1;
21 }
22
23 forward FireRateTimer(playerid);
24 public FireRateTimer(playerid)
25 {
26    if(autoFireButton[playerid])
27        OnVehicleShot(playerid,VEHICLE_MISSILE_TYPE_CON);
28    return 1;
29 }
30
31 forward FireRateTimer(playerid);
32 public OnPlayerKeyStateChange(playerid, newkeys, oldkeys){
33    if(IsPlayerInAnyVehicle(playerid) && GetPlayerVehicleSeat(playerid) == 0){
34        new vid = GetPlayerVehicleID(playerid);
35        if(IsToggleVehicleCongreve(vid)){
36            if(PRESSED(GetVehicleCongreveKey(vid))){
37           	    if(FireRateTimer[playerid] != -1) return 1; // <-- This is the line which gives the error
38	            FireRateTimer[playerid] = SetTimerEx("MissileFunction", 1000, true, "d", playerid);
39                SendClientMessage(playerid, 0x00FF00FF, "button pressed.");
40            }
41            if(RELEASED(GetVehicleCongreveKey(vid))){
42            	if(FireRateTimer[playerid] != -1) {
43                    KillTimer(FireRateTimer[playerid]);
44		            FireRateTimer[playerid] = -1;
45                    SendClientMessage(playerid, 0x00FF00FF, "button released.");
46                }
47            }
48        }
49    }
50    return 1;
}
Code:
#include <a_samp>
#include <foreach>
#include <colandreas>
#include <streamer>
#include <3DTryg>
#include <Missile>
#include <VehicleMissileCol>

#define PRESSED(%0) \
		(((newkeys & (%0)) == (%0)) && ((oldkeys & (%0)) != (%0)))
#define RELEASED(%0) \
		(((oldkeys & (%0)) == (%0)) && ((newkeys & (%0)) != (%0)))

new bool:autoFireButton[MAX_PLAYERS],
	FireRateTimer[MAX_PLAYERS];
static const c_AutoFireRate = 50; //define the rate of fire in milliseconds

public OnGameModeInit()
{
	SetTimer("FireRateTimer", c_AutoFireRate, true);
    return 1;
}

forward MissileFunction(playerid);
public MissileFunction(playerid)
{
    if(autoFireButton[playerid]) // What is this? You don`t set autoFireButton on true anywhere
        OnVehicleShot(playerid,VEHICLE_MISSILE_TYPE_CON);
    return 1;
}

public OnPlayerConnect(playerid) {
	FireRateTimer[playerid] = -1;
	// other stuff from your gm
}

public OnPlayerKeyStateChange(playerid, newkeys, oldkeys) {
	if(IsPlayerInAnyVehicle(playerid) && GetPlayerVehicleSeat(playerid) == 0) {
		new vid = GetPlayerVehicleID(playerid);
		if(IsToggleVehicleCongreve(vid)) {
			if(PRESSED(GetVehicleCongreveKey(vid))) {
				if(FireRateTimer[playerid] != -1) return 1; // <-- This is the line which gives the error
	            FireRateTimer[playerid] = SetTimerEx("MissileFunction", 1000, true, "d", playerid);
                SendClientMessage(playerid, 0x00FF00FF, "button pressed.");
            }
            if(RELEASED(GetVehicleCongreveKey(vid))) {
            	if(FireRateTimer[playerid] != -1) {
                    KillTimer(FireRateTimer[playerid]);
		            FireRateTimer[playerid] = -1;
                    SendClientMessage(playerid, 0x00FF00FF, "button released.");
                }
            }
        }
    }
    return 1;
}
Reply
#18

Remove the line 31. Bcuz you forwarded same thing two times
Reply
#19

Thanks again Lunnox! it works perfectly now! thank you so much
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)