AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Scripting (https://forums.alliedmods.net/forumdisplay.php?f=107)
-   -   What am I doing wrong? (https://forums.alliedmods.net/showthread.php?t=306017)

Tank_in_Pink 03-12-2018 17:58

What am I doing wrong?
 
Hey guys,

I'm currently writing my first plugin in SourcePawn. I understand the basics of programming but have no idea of SourcePawn.
I think there are just some minor issues but the plugin should work if they are fixed.
I couldn't really figure out how the timer works so there might be some problems with it.
I also can't figure out what to put as parameters inside the brackets of "Event_PlayerDeath" and "PrintMessage".

This is my code:
Code:

#include <sourcemod>

public Plugin:myinfo =
{
        name = "...",
        author = "...",
        description = "...",
        version = "1.0",
        url = "..."
}

public OnPluginStart()
{
        HookEvent("player_death", Event_PlayerDeath);
        static int countdownTimer = 30;
}

public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
        CreateTimer(1.0, PrintMessage, _, TIMER_REPEAT);
        countdownTimer = 30;
}

public Action PrintMessage(Handle timer)
{
        if (countdownTimer > 0)
        {
                new client = GetClientOfUserId(GetEventInt(event, "userid"));
                PrintCenterText(client, "You are dead. You will be respawned at a random location in" + countdownTimer + "seconds.")
       
                countdownTimer--;
        }
 
        return Plugin_Continue;
}

Some help and explenation would be awesome :3

Thanks already,
hazetank

backwards 03-12-2018 18:36

Re: What am I doing wrong?
 
you can't add variables to a dynamic string like this in sourcemod:
PHP Code:

"You are dead. You will be respawned at a random location in" countdownTimer "seconds." 

you have a string that parses variables based off of tokens like this:
PHP Code:

PrintCenterText(client"You are dead. You will be respawned at a random location in %i seconds."countdownTimer

Also you are creating a repeating timer each player death event and never killing it. So you have infinite looping timers with a big memory leak, even worse then a memory leak you have code that's being run and useless. You're also using a variable that all clients would share instead of a variable per client. The variable you are defining is only accessible within that scope of code and not functions called under it. you have to define that variable outside of all scopes to be global for all functions to access. You're also trying to parse the event inside a child function which you can't do either in sp like this without passing the event itself.

Here's a fixed up version of your code to help you learn for your specific case.
PHP Code:

#include <sourcemod>

public Plugin:myinfo 
{
    
name "...",
    
author "...",
    
description "...",
    
version "1.0",
    
url "..."
}

int countdownTimer[MAXPLAYERS+1] = {30, ...};

public 
OnPluginStart()
{
    
HookEvent("player_death"Event_PlayerDeath);
}

public 
Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
    new 
client GetClientOfUserId(GetEventInt(event,"userid"));
    if(!
IsValidClient(client))
        return;
        
    
countdownTimer[client] = 30;
    
CreateTimer(1.0PrintMessageGetClientUserId(client), TIMER_REPEAT);
}

public 
Action PrintMessage(Handle timer)
{
    new 
client GetClientOfUserId(clientid);
    if(!
IsValidClient(client))
        return 
Plugin_Stop
    
    
countdownTimer[client]--;

    if(
countdownTimer[client] == 0)
        return 
Plugin_Stop;
        
    
PrintCenterText(client"You are dead. You will be respawned at a random location in %i seconds."countdownTimer[client]);
 
    return 
Plugin_Continue;
}

bool IsValidClient(int client)
{
    if (!(
<= client <= MaxClients) || !IsClientConnected(client) || !IsClientInGame(client) || IsClientSourceTV(client) || IsClientReplay(client))
        return 
false;
        
    return 
true;


Also search here how to correctly use functions:
https://sm.alliedmods.net/new-api/

OSWO 03-12-2018 20:20

Re: What am I doing wrong?
 
I suggest you also have a look at the new api, you never know 8

hmmmmm 03-12-2018 21:09

Re: What am I doing wrong?
 
The countdownTimer variable is never decremented and would stay as 30 with that code.

Tank_in_Pink 03-13-2018 04:17

Re: What am I doing wrong?
 
Thanks to all of you guys, especially thanks for this:

Quote:

Originally Posted by 1337norway (Post 2582767)
you can't add variables to a dynamic string like this in sourcemod:
PHP Code:

"You are dead. You will be respawned at a random location in" countdownTimer "seconds." 

you have a string that parses variables based off of tokens like this:
PHP Code:

PrintCenterText(client"You are dead. You will be respawned at a random location in %i seconds."countdownTimer

Also you are creating a repeating timer each player death event and never killing it. So you have infinite looping timers with a big memory leak, even worse then a memory leak you have code that's being run and useless. You're also using a variable that all clients would share instead of a variable per client. The variable you are defining is only accessible within that scope of code and not functions called under it. you have to define that variable outside of all scopes to be global for all functions to access. You're also trying to parse the event inside a child function which you can't do either in sp like this without passing the event itself.

Here's a fixed up version of your code to help you learn for your specific case.
PHP Code:

#include <sourcemod>

public Plugin:myinfo 
{
    
name "...",
    
author "...",
    
description "...",
    
version "1.0",
    
url "..."
}

int countdownTimer[MAXPLAYERS+1] = {30, ...};

public 
OnPluginStart()
{
    
HookEvent("player_death"Event_PlayerDeath);
}

public 
Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
    new 
client GetClientOfUserId(GetEventInt(event,"userid"));
    if(!
IsValidClient(client))
        return;
        
    
countdownTimer[client] = 30;
    
CreateTimer(1.0PrintMessageGetClientUserId(client), TIMER_REPEAT);
}

public 
Action PrintMessage(Handle timer)
{
    new 
client GetClientOfUserId(clientid);
    if(!
IsValidClient(client))
        return 
Plugin_Stop
    
    
countdownTimer[client]--;

    if(
countdownTimer[client] == 0)
        return 
Plugin_Stop;
        
    
PrintCenterText(client"You are dead. You will be respawned at a random location in %i seconds."countdownTimer[client]);
 
    return 
Plugin_Continue;
}

bool IsValidClient(int client)
{
    if (!(
<= client <= MaxClients) || !IsClientConnected(client) || !IsClientInGame(client) || IsClientSourceTV(client) || IsClientReplay(client))
        return 
false;
        
    return 
true;


Also search here how to correctly use functions:
https://sm.alliedmods.net/new-api/

I still have two questions about your code would be awesome if you could explain.

Why ''MAXPLAYRRS+1'' / what does is affect?

What does ''IsValidClient'' mean?


Thanks for your help already,
hazetank

hmmmmm 03-13-2018 05:29

Re: What am I doing wrong?
 
Quote:

Originally Posted by Tank_in_Pink (Post 2582806)
Why ''MAXPLAYRRS+1'' / what does is affect?

When you're creating a variable that stores client data you want to make sure that it can fit all the cilents. If you make the size only 32 players for example and you get 33 players on your server then you will get issues since their are more players than slots in your array.
MAXPLAYERS is simply a constant provided by sourcemod that translates into the maximum number of players that you can have on the server.

Quote:

Originally Posted by Tank_in_Pink (Post 2582806)
What does ''IsValidClient'' mean?

IsValidClient is a function that 1337norway made to ensure that when he does some action with a client that they aren't in some weird state. ie. if the player is still connecting you don't want to do any of this stuff, or if the player is some GOTV bot you don't want to apply that action to them either. You should look at the function definition to see what exactly it does.

Tank_in_Pink 03-13-2018 09:03

Re: What am I doing wrong?
 
Quote:

Originally Posted by hmmmmm (Post 2582812)
When you're creating a variable that stores client data you want to make sure that it can fit all the cilents. If you make the size only 32 players for example and you get 33 players on your server then you will get issues since their are more players than slots in your array.
MAXPLAYERS is simply a constant provided by sourcemod that translates into the maximum number of players that you can have on the server.


IsValidClient is a function that 1337norway made to ensure that when he does some action with a client that they aren't in some weird state. ie. if the player is still connecting you don't want to do any of this stuff, or if the player is some GOTV bot you don't want to apply that action to them either. You should look at the function definition to see what exactly it does.

Thanks dude, appreciate it :3

Tank_in_Pink 03-13-2018 09:34

Re: What am I doing wrong?
 
Quote:

Originally Posted by 1337norway (Post 2582767)
you can't add variables to a dynamic string like this in sourcemod:
PHP Code:

"You are dead. You will be respawned at a random location in" countdownTimer "seconds." 

you have a string that parses variables based off of tokens like this:
PHP Code:

PrintCenterText(client"You are dead. You will be respawned at a random location in %i seconds."countdownTimer

Also you are creating a repeating timer each player death event and never killing it. So you have infinite looping timers with a big memory leak, even worse then a memory leak you have code that's being run and useless. You're also using a variable that all clients would share instead of a variable per client. The variable you are defining is only accessible within that scope of code and not functions called under it. you have to define that variable outside of all scopes to be global for all functions to access. You're also trying to parse the event inside a child function which you can't do either in sp like this without passing the event itself.

Here's a fixed up version of your code to help you learn for your specific case.
PHP Code:

#include <sourcemod>

public Plugin:myinfo 
{
    
name "...",
    
author "...",
    
description "...",
    
version "1.0",
    
url "..."
}

int countdownTimer[MAXPLAYERS+1] = {30, ...};

public 
OnPluginStart()
{
    
HookEvent("player_death"Event_PlayerDeath);
}

public 
Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
    new 
client GetClientOfUserId(GetEventInt(event,"userid"));
    if(!
IsValidClient(client))
        return;
        
    
countdownTimer[client] = 30;
    
CreateTimer(1.0PrintMessageGetClientUserId(client), TIMER_REPEAT);
}

public 
Action PrintMessage(Handle timer)
{
    new 
client GetClientOfUserId(clientid);
    if(!
IsValidClient(client))
        return 
Plugin_Stop
    
    
countdownTimer[client]--;

    if(
countdownTimer[client] == 0)
        return 
Plugin_Stop;
        
    
PrintCenterText(client"You are dead. You will be respawned at a random location in %i seconds."countdownTimer[client]);
 
    return 
Plugin_Continue;
}

bool IsValidClient(int client)
{
    if (!(
<= client <= MaxClients) || !IsClientConnected(client) || !IsClientInGame(client) || IsClientSourceTV(client) || IsClientReplay(client))
        return 
false;
        
    return 
true;


Also search here how to correctly use functions:
https://sm.alliedmods.net/new-api/


I just wanted to compile your code but i got an error :(

Code:

/home/groups/sourcemod/upload_tmp/phpWyXe2k.sp(31) : error 017: undefined symbol "clientid"
I tried to replace
Code:

new client = GetClientOfUserId(clientid);
in line 31 by
Code:

new client = GetClientOfUserId(GetEventInt(event,"userid"));
like in line 21 but got this error when compiling:
Code:

/home/groups/sourcemod/upload_tmp/phpbyyDOm.sp(31) : error 017: undefined symbol "event"
So I think I have to edit something at the "Handle" parameter of "PrintMessage" but since it already says "Handle timer" inside the brackets I don't know what to do :(

Some last help would be amazing :3
Sorry for beeing unable to fix it myself :(

Thanks already,
hazetank

OSWO 03-13-2018 17:57

Re: What am I doing wrong?
 
PHP Code:

public Action PrintMessage(Handle timerany data) {
    
int client GetClientOfUserId(data);
...



Tank_in_Pink 03-14-2018 10:20

Re: What am I doing wrong?
 
Quote:

Originally Posted by OSWO (Post 2582914)
PHP Code:

public Action PrintMessage(Handle timerany data) {
    
int client GetClientOfUserId(data);
...



Thanks alot dude, fixed it :3


All times are GMT -4. The time now is 08:49.

Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.