Raised This Month: $51 Target: $400
 12% 

Call_StartFunction - help passing arguments correctly


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Misfired
Junior Member
Join Date: Nov 2015
Location: USA
Old 11-27-2015 , 19:54   Call_StartFunction - help passing arguments correctly
Reply With Quote #1

Brand new to sourcemod and very rusty on C/C++, so pardon the code.
As a learning exercise I'm trying to identify dead bots and revive when they die.
This is for more or less a HL2DM mod.

CommandChangeTeam function works as expected when called from chat console.
PHP Code:
public Action CommandChangeTeam(int clientint argc
Example of Bot1 moving to team #2 from spectator...
!changeteam Bot1 2
Player Bot1 joined team 2
[SM] Admin switched Bot1 to 2


However It's clear I'm not passing args correctly from my function call based on the error message.
Guessing I'm not passing the int client parameter correctly, and not sure of the fix.
Here's a snippet of the realavent code, and the error out put below.


PHP Code:
public Action BotDeathRespawn(Handle:event, const String:name[], bool:dontBroadcast){
    new 
id GetClientOfUserId(GetEventInt(event"userid")); // Player userid
    
decl String:ClientName[64]; 
    
GetClientName(idClientName64// Client name to ClientName string
    
PrintToServer("Player Bot %s died and will be respawned."ClientName// Message to Admin
    
decl String:bMsg[64]; //Bot message string
    
    //changeteam 
    
if (StrContains(ClientName"Bot1"false) !=-|| StrContains(ClientName"Bot2"false) !=-1){
        
bMsg ClientName;
        
StrCat(bMsgsizeof(bMsg), " 2");
        }
    else if (
StrContains(ClientName"Bot3"false) !=-|| StrContains(ClientName"Bot4"false) !=-1){
        
bMsg ClientName;
        
StrCat(bMsgsizeof(bMsg), " 3");
        }
    
PrintToServer("[SM] @ @ Bot Team bMsg %s @ @"bMsg);    //Give name of dead bot
    
Call_StartFunction(INVALID_HANDLECommandChangeTeam);    //Let's revive,re-equip
    
Call_PushString(bMsg);
    
Call_Finish();

[SM] Player Bot1 died and will be respawned.
[SM] @ @ Bot Team bMsg "Bot1 2" @ @
L 11/27/2015 - 19:01:27: [SM] Native "ReplyToCommand" reported: Client index 4744 is invalid
L 11/27/2015 - 19:01:27: [SM] Displaying call stack trace for plugin "emp_bot_tools3.smx":
L 11/27/2015 - 19:01:27: [SM] [0] Line 204, emp_bot_tools3.sp::CommandChangeTeam()


Thanks for your help
Misfired is offline
Wliu
Veteran Member
Join Date: Apr 2013
Old 11-27-2015 , 22:25   Re: Call_StartFunction - help passing arguments correctly
Reply With Quote #2

You don't seem to be passing id over to the function, only bMsg.
__________________
~Wliu
Wliu is offline
Misfired
Junior Member
Join Date: Nov 2015
Location: USA
Old 11-27-2015 , 23:09   Re: Call_StartFunction - help passing arguments correctly
Reply With Quote #3

bMsg contain both the player name "Bot1" and the team number as seen in the print message.
[SM] @ @ Bot Team bMsg "Bot1 2" @ @

Adding a third field to the string like ... "id Bot1 2" ... gives the same error.

When executing the function from chat, (!changeteam Bot1 2) "Bot1 2" would be the "int args" side, I'm trying to understand how to properly fulfill the "int client" parameter will my call.

Last edited by Misfired; 11-27-2015 at 23:30.
Misfired is offline
fakuivan
Senior Member
Join Date: Nov 2015
Old 11-28-2015 , 00:29   Re: Call_StartFunction - help passing arguments correctly
Reply With Quote #4

Quote:
Originally Posted by Misfired View Post
bMsg contain both the player name "Bot1" and the team number as seen in the print message.
[SM] @ @ Bot Team bMsg "Bot1 2" @ @

Adding a third field to the string like ... "id Bot1 2" ... gives the same error.

When executing the function from chat, (!changeteam Bot1 2) "Bot1 2" would be the "int args" side, I'm trying to understand how to properly fulfill the "int client" parameter will my call.
Can you tell us what arguments does CommandChangeTeam takes? CommandChangeTeam(int client)?
fakuivan is offline
Misfired
Junior Member
Join Date: Nov 2015
Location: USA
Old 11-28-2015 , 00:54   Re: Call_StartFunction - help passing arguments correctly
Reply With Quote #5

It takes two objects. 'client' I assume is the client index of the funtion caller? argc is the list of options.
In this case argc would contain 'Bot1' and the team number '1'

public Action CommandChangeTeam(int client, int argc)

It takes this default structure from its RegConsoleCmd creation in OnPluginStart()
RegConsoleCmd("sm_changeteam", CommandChangeTeam);

There's nothing too special about the function itself. Which works fine if called with sm_changeteam or !changeteam from chat.

PHP Code:
 public Action CommandChangeTeam(int clientint argc) {
    if (
argc != 2) {
        
ReplyToCommand(client,"[SM] Usage: !changeteam <#userid|name> <team>");
        return 
Plugin_Handled;
    }

    
// Get first argument
    
char arg1[MAX_NAME_LENGTH];
    
GetCmdArg(1arg1sizeof(arg1));

    
// Find the client index of the specified target
    
int target FindTarget(clientarg1);
    if (
target 1) {
        return 
Plugin_Handled;
    }

    
// Get second argument
    
char arg2[MAX_NAME_LENGTH];
    
GetCmdArg(2arg2sizeof(arg2));

    
// Change team of the target client
    // 0 Unassigned
    // 1 Spectator
    // 2 Team 1
    // 3 Team 2
    
int team StringToInt(arg2);
    
ChangeClientTeam(targetteam);
    
DispatchSpawn(target);

    
// Get player name
    
char targetName[MAX_NAME_LENGTH];
    
GetClientName(targettargetNamesizeof(targetName));

    
// Get team name
    
char teamName[MAX_NAME_LENGTH];
    
GetTeamName(teamteamNamesizeof(teamName));

    
PrintToChatAll("[SM] Admin switched %s to team %s."targetNameteamName);
    return 
Plugin_Handled;


Last edited by Misfired; 11-28-2015 at 00:55.
Misfired is offline
Misfired
Junior Member
Join Date: Nov 2015
Location: USA
Old 11-28-2015 , 01:02   Re: Call_StartFunction - help passing arguments correctly
Reply With Quote #6

I can see I'm way off here.... first I'm pushing strings to a function that's expecting ints.
Second I think I understand your comment now Wliu.
I'm only pushing one combined object, when I should be pushing 2 to satisfy the function.
hmmm.... rethinking
Misfired is offline
fakuivan
Senior Member
Join Date: Nov 2015
Old 11-28-2015 , 01:39   Re: Call_StartFunction - help passing arguments correctly
Reply With Quote #7

Quote:
Originally Posted by Misfired View Post
It takes two objects. 'client' I assume is the client index of the funtion caller? argc is the list of options.
In this case argc would contain 'Bot1' and the team number '1'

public Action CommandChangeTeam(int client, int argc)

It takes this default structure from its RegConsoleCmd creation in OnPluginStart()
RegConsoleCmd("sm_changeteam", CommandChangeTeam);

There's nothing too special about the function itself. Which works fine if called with sm_changeteam or !changeteam from chat.

PHP Code:
 public Action CommandChangeTeam(int clientint argc) {
    if (
argc != 2) {
        
ReplyToCommand(client,"[SM] Usage: !changeteam <#userid|name> <team>");
        return 
Plugin_Handled;
    }

    
// Get first argument
    
char arg1[MAX_NAME_LENGTH];
    
GetCmdArg(1arg1sizeof(arg1));

    
// Find the client index of the specified target
    
int target FindTarget(clientarg1);
    if (
target 1) {
        return 
Plugin_Handled;
    }

    
// Get second argument
    
char arg2[MAX_NAME_LENGTH];
    
GetCmdArg(2arg2sizeof(arg2));

    
// Change team of the target client
    // 0 Unassigned
    // 1 Spectator
    // 2 Team 1
    // 3 Team 2
    
int team StringToInt(arg2);
    
ChangeClientTeam(targetteam);
    
DispatchSpawn(target);

    
// Get player name
    
char targetName[MAX_NAME_LENGTH];
    
GetClientName(targettargetNamesizeof(targetName));

    
// Get team name
    
char teamName[MAX_NAME_LENGTH];
    
GetTeamName(teamteamNamesizeof(teamName));

    
PrintToChatAll("[SM] Admin switched %s to team %s."targetNameteamName);
    return 
Plugin_Handled;

In this case what you are doing is calling the function (not what you need), what I think you want to do is execute a console command (not a function), you can do that using the ServerCommand() function, but this is completely unnecessary and even dangerous at some point (if the name of the client contains ;exit, the console will interpret the ; as a command terminator, so It'll execute the exit command).


One solution to this is to do what I said avobe, The other way to do this (recommended) is to recreate the function using just the parts that you need: in this case the

ChangeClientTeam(target, team);
and
DispatchSpawn(target);

functions

PHP Code:
public void BotDeathRespawn(Handle event, const char[] namebool dontBroadcast)
{
    
int id GetClientOfUserId(GetEventInt(event"userid"));
    if (
IsFakeClient(id)) //just for bots
    
{
        
char botname[MAX_NAME_LENGTH];
        
GetClientName(idClientNamesizeof(botname));
        
PrintToServer("Player Bot %s died and will be respawned."ClientName
        
        
ChangeClientTeam(id2);    //team 2, you can create a convar that controls which team the bot will respawn, if you want
        
DispatchSpawn(id);
        
        
/*or 
        CS_RespawnPlayer(id)
        TF2_RespawnPlayer(id)
        */
        
PrintToServer("[SM] @ @ Bot Team bMsg %s @ @"ClientName);
   }

Keep in mind that this loop is not yet controlable by the admin, you need to create convars if you want the plguin from respawning bots all the time

Last edited by fakuivan; 11-28-2015 at 01:55. Reason: #datgrammar
fakuivan is offline
asherkin
SourceMod Developer
Join Date: Aug 2009
Location: OnGameFrame()
Old 11-28-2015 , 04:01   Re: Call_StartFunction - help passing arguments correctly
Reply With Quote #8

You should check the return value of GetClientOfUserId first, and use the %N format specifier rather than GetClientName.
__________________
asherkin is offline
Misfired
Junior Member
Join Date: Nov 2015
Location: USA
Old 11-28-2015 , 11:57   Re: Call_StartFunction - help passing arguments correctly
Reply With Quote #9

Quote:
Originally Posted by fakuivan View Post
In this case what you are doing is calling the function (not what you need), what I think you want to do is execute a console command (not a function), you can do that using the ServerCommand() function
After my last post I did exactly as you have, simplified the function down to just changeteam and dispatchspawn. That does get the bots on the correct team after death, but they don't spawn. Timing issue maybe? Also it's only part of the story. They also need to be assigned a class and given a weapons load out. Again these tasks are already taken care of by other functions successfully from chat console. (!changeclass !giveloadout)

So that's why I was trying to workout how to recall existing functions from within the plugin when needed. Otherwise I think Im doubling the size of my plugin, once for console commands, and repeated again, for autorespawns. I see how SeverCommand() would be one solution IF I filter ";exit". But not the way I would prefer to do it.
Misfired is offline
fakuivan
Senior Member
Join Date: Nov 2015
Old 11-28-2015 , 13:33   Re: Call_StartFunction - help passing arguments correctly
Reply With Quote #10

Quote:
Originally Posted by Misfired View Post
After my last post I did exactly as you have, simplified the function down to just changeteam and dispatchspawn. That does get the bots on the correct team after death, but they don't spawn. Timing issue maybe? Also it's only part of the story. They also need to be assigned a class and given a weapons load out. Again these tasks are already taken care of by other functions successfully from chat console. (!changeclass !giveloadout)

So that's why I was trying to workout how to recall existing functions from within the plugin when needed. Otherwise I think Im doubling the size of my plugin, once for console commands, and repeated again, for autorespawns. I see how SeverCommand() would be one solution IF I filter ";exit". But not the way I would prefer to do it.
I strongly encourage you to not use SeverCommand() (simply beacuse it is a workaround), try to find out what those commands are doing and create your own functions and even if you can call the CommandChangeTeam indirectly you can't expect it to work since it fetches the client and and the team from GetCmdArg and you didn't issued any command to call the function. Don't worry about the size of your plugin.
fakuivan is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 20:33.


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