[Tutorial] Sending commands to NPC
#1

This tutorial shows how you can send commands to NPC.

To send a command from gamemode/filterscript to NPC, you need to call a function in the npcmode. Normally you would use CallRemoteFunction. But CallRemoteFunction doesn't work for npcmodes, so you have to use something else, for example sending client messages.

Basically the method works like this:

(gamemode/filterscript) SendClientMessage > OnClientMessage (npcmode)

In gamemode/filterscript you use the format function to pack the data to a string and send it with SendClientMessage function.
In npcmode you use OnClientMessage callback to receive the data and unpack it with sscanf (for example).

With this method you can send ANY data you want from server to NPC.


Now I will show an example using zcmd and sscanf

gamemode/filterscript:
pawn Code:
CMD:sendcmd(playerid, params[])
{
    new npcid, cmd[128], msg[128];
    if(sscanf(params, "us[128]", npcid, cmd)) return SendClientMessage(playerid, 0xFFFFFFFF, "USAGE: /sendcmd [npc] [cmd]");
    if(!IsPlayerConnected(npcid)) return SendClientMessage(playerid, 0xEE0000FF, "Invalid player!");
    if(!IsPlayerNPC(npcid)) return SendClientMessage(playerid, 0xEE0000FF, "Player is not NPC!");
    format(msg, sizeof(msg), "/sendcmd %s", cmd);
    SendClientMessage(npcid, 123456, msg);
    return 1;
}

CMD:playback(playerid, params[])
{
    new npcid, playbacktype, recordname[64], msg[128];
    if(sscanf(params, "uds[64]", npcid, playbacktype, recordname))
        return SendClientMessage(playerid, 0xFFFFFFFF, "USAGE: /playback [npc] [type] [name]");
    if(!IsPlayerConnected(npcid)) return SendClientMessage(playerid, 0xEE0000FF, "Invalid player!");
    if(!IsPlayerNPC(npcid)) return SendClientMessage(playerid, 0xEE0000FF, "Player is not NPC!");
    format(msg, sizeof(msg), "/playback %d %s", playbacktype, recordname);
    SendClientMessage(npcid, 123456, msg);
    return 1;
}
npcmode:
pawn Code:
public OnClientMessage(color, text[])
{
    if(text[0] != '/' || color != 123456) return; // ignore all other client messages that NPC receives
   
    new cmd[64], params[128];
    sscanf(text, "s[64]s[128]", cmd, params);
   
    if(strcmp(cmd, "/sendcmd", true) == 0)
    {
        SendCommand(params);
        return;
    }
   
    if(strcmp(cmd, "/playback", true) == 0)
    {
        new playbacktype, recordname[64], msg[128];
        sscanf(params, "ds[64]", playbacktype, recordname);
        format(msg, sizeof(msg), "Starting playback (type: %d  name: %s)", playbacktype, recordname);
        SendChat(msg);
        StartRecordingPlayback(playbacktype, recordname);
        return;
    }
}
Now if you have NPC connected with ID 0 and you have a /me command in your script, you can use /sendcmd command to make the NPC use the /me command.

Example:
Code:
/sendcmd 0 /me is a bot
Or you can make the NPC play any recording file in ...\npcmodes\recordings\ folder.

Example:
Code:
/playback 0 2 animtest1
zcmd - https://sampforum.blast.hk/showthread.php?tid=91354
sscanf - https://sampforum.blast.hk/showthread.php?tid=120356
Reply
#2

I don't really understand why you are sending a message to the NPC. Why don't you just call the ZCMD function or even the strcmp function directly from the command.

pawn Code:
CMD:sendcmd(playerid, params[])
{
    new npcid, cmd[128], msg[128], str[150];
    if(sscanf(params, "us[128]s[150]", npcid, cmd, str)) return SendClientMessage(playerid, 0xFFFFFFFF, "USAGE: /sendcmd [npc] [cmd] [params]");
    if(!IsPlayerConnected(npcid)) return SendClientMessage(playerid, 0xEE0000FF, "Invalid player!");
    if(!IsPlayerNPC(npcid)) return SendClientMessage(playerid, 0xEE0000FF, "Player is not NPC!");
    format(msg, sizeof(msg), "cmd_%s", cmd);
    CallRemoteFunction(msg, "is", npcid, str);
    return 1;
}
Anyway, a little explanation would go a long way .
Reply
#3

Quote:
Originally Posted by [HiC]TheKiller
View Post
I don't really understand why you are sending a message to the NPC. Why don't you just call the ZCMD function or even the strcmp function directly from the command.

pawn Code:
CMD:sendcmd(playerid, params[])
{
    new npcid, cmd[128], msg[128], str[150];
    if(sscanf(params, "us[128]s[150]", npcid, cmd, str)) return SendClientMessage(playerid, 0xFFFFFFFF, "USAGE: /sendcmd [npc] [cmd] [params]");
    if(!IsPlayerConnected(npcid)) return SendClientMessage(playerid, 0xEE0000FF, "Invalid player!");
    if(!IsPlayerNPC(npcid)) return SendClientMessage(playerid, 0xEE0000FF, "Player is not NPC!");
    format(msg, sizeof(msg), "cmd_%s", cmd);
    CallRemoteFunction(msg, "is", npcid, str);
    return 1;
}
Anyway, a little explanation would go a long way .
Read carefully.

Quote:
Originally Posted by MadeMan
View Post
To send a command from gamemode/filterscript to NPC, you need to call a function in the npcmode. Normally you would use CallRemoteFunction. But CallRemoteFunction doesn't work for npcmodes, so you have to use something else, for example sending client messages.
Reply
#4

I misunderstood the topic. I thought that you meant applying a current ZCMD command to a bot. This is for sending SendCommand / SendChat messages. It still would be nice to have a bit more explanation to why you do what you do.
Reply
#5

Quote:
Originally Posted by MadeMan
View Post
Normally you would use CallRemoteFunction. But CallRemoteFunction doesn't work for npcmodes, so you have to use something else, for example sending client messages.
I'll translate for people:

ZCMD uses "CallRemoteFunction" and that's where it gets its speed. But since you can't use that function with NPC's, then you can't call the ZCMD command directly.
Reply
#6

Awesome, Thanks for the playback part!
Reply
#7

thanks dude..works all who say bump f*ck you! i just wanted to thank the author and help others maybe
Reply
#8

hi man my code , its not wokring for me what is the problem plz tell me every thing will compile complete but not work in game D:
in game mode
Code:
dcmd_sendcmd(playerid,params[])
{
	#pragma unused params

		new npcid, cmd[128], msg[128];
		 if(!IsPlayerConnected(npcid)) return SendClientMessage(playerid, 0xEE0000FF, "Invalid player!");
        format(msg, sizeof(msg), "/sendcmd %s", cmd);
    	SendClientMessage(npcid, 123456, msg);
    
	return 1;
}
in npc filterscript
Code:
public OnClientMessage(color, text[])
{
   if(text[0] != '/' || color != 123456) return; // ignore all other client messages that NPC receives

    new cmd[64], params[128];
    sscanf(text, "s[64]s[128]", cmd, params);

    if(strcmp(cmd, "/sendcmd", true) == 0)
    {
        SendCommand(params);
        return;
    }
	return 1;
}
Reply
#9

I puted all in what you said and how you said, In GM and Npcmode ,and in game the /sendcmd works but when i /sendcmd 0 /me is cool , the NPC don't say nothing ... weird
Reply


Forum Jump:


Users browsing this thread: 3 Guest(s)