$quickstrings in commands
#1

Could anybody give me some information on how to make quickstrings work correctly in commands?
I have made multiple quickstrings under OnPlayerText which work fine when used as chat messages, but they don't work within commands (such as /whisper, /reply, /me)

Example of the string code under OnPlayerText:
(Most people already know how to do this anyway, but feel free to use it if you want to add similar $strings in your own gamemode )
Код:
	new idx = strfind(text, "$");

    if(idx != -1)
    {
        new string[144];
        strcat(string, text);
        do
        {
            if(strcmp(string[idx], "$loc", true, 4) == 0)
            {
                strdel(string, idx, idx + 4);
                strins(string, PlayerInfo[playerid][pLocation], idx);
                continue;
            }
How the string appears in the chat:


How the string appears when following a command:
Reply
#2

are u sure the code is able to see this $loc in command?
try debugging with this
PHP код:
            if(strcmp(string[idx], "$loc"true4) == 0)
            {
                
strdel(stringidxidx 4);
                
strins(stringPlayerInfo[playerid][pLocation], idx);
                
SendClientMessage(playerid,-1,"Here its visible");
                continue;
            } 
Reply
#3

Quote:
Originally Posted by Mugala
Посмотреть сообщение
are u sure the code is able to see this $loc in command?
try debugging with this
PHP код:
            if(strcmp(string[idx], "$loc"true4) == 0)
            {
                
strdel(stringidxidx 4);
                
strins(stringPlayerInfo[playerid][pLocation], idx);
                
SendClientMessage(playerid,-1,"Here its visible");
                continue;
            } 
The SendClientMessage doesn't print when the string is used in a command, what would I need to add in order to make the code able to see the $loc in a command?
Reply
#4

so if you can't see SendClientMessage it means that your code is not working good.
can u post the whole command? from the beginning.
Reply
#5

Quote:
Originally Posted by Mugala
Посмотреть сообщение
so if you can't see SendClientMessage it means that your code is not working good.
can u post the whole command? from the beginning.
Which command? I'm trying to get the $strings to work in all commands (like /privatemessage $loc, /info $player, etc)
Would I need to add something to each command individually?

Example of a command I want it to work in:
Код:
COMMAND:pm(playerid, params[])
{
	new idx,id,TargetID,string[256],tmp[256],cmd[256],message[256];

	tmp = strtok(params, idx);
	if (!strlen(tmp))
	{
		SendClientMessage(playerid, COLOR_ERROR, "USAGE: /pm (Name/Id) (message).");
		return 1;
	}

	if (PlayerInfo[playerid][pMuted] == 1)
	{
		SendClientMessage(playerid,COLOR_ERROR,"#Error: You Muted.");
		return 1;
	}

	if (!isNumeric(tmp))
	{
		TargetID = TargetID = ReturnUser(tmp, playerid);
		if (TargetID == INVALID_PLAYER_ID)
		{
			return 1;
		}
	}
	else
	{
		TargetID = strval(tmp);
		if (!IsPlayerConnected(TargetID))
		{
			format(string, sizeof(string), "%d Is Not A Valid ID.", TargetID);
			SendClientMessage(playerid, COLOR_ERROR, string);
			return 1;
		}
	}
	id = strlen(tmp);
	tmp = strtok(params, idx);


	if (TargetID == playerid)
	{
		SendClientMessage(playerid, COLOR_ERROR, "You Cannot PM Yourself!");
		return 1;
	}

	if (strmid(message, params, id + strlen(cmd) + 1, strlen(params), 256))
	{
		OnPlayerPrivmsg(playerid, TargetID, message);
	}
	else
	{
		SendClientMessage(playerid, COLOR_ERROR, "USAGE: /pm (Name/Id) (message).");
	}
	return 1;
}
The SendClientMessage appears fine when I use $loc in the main chat, just doesn't appear when I use /pm $loc (for example).
Reply
#6

what about to use sscanf?
Reply
#7

I hope this will work, P.S. uses sscanf. and u used strcmp instead of strfind.
PHP код:
COMMAND:pm(playeridparams[])
{
    new 
TargetIDmessage[128];
    if(
sscanf(params"is[128]"TargetIDmessage)) return SendClientMessage(playeridCOLOR_ERROR"USAGE: /pm (Name/Id) (message).");
    if(
PlayerInfo[playerid][pMuted] == 1) return SendClientMessage(playerid,COLOR_ERROR,"#Error: You Muted.");
    if(
TargetID == playerid) return SendClientMessage(playeridCOLOR_ERROR"You Cannot PM Yourself!");
    if(!
IsPlayerConnected(TargetID))
    {
            
format(stringsizeof(string), "%d Is Not A Valid ID."TargetID);
            
SendClientMessage(playerid, -1string);
            return 
1;
    }
    new 
value strfind(message"$loc"true);
    if(
value != -1)
    {
        
strdel(messagevaluevalue+4);
        
strins(message,  PlayerInfo[playerid][pLocation], value);
    }
    
OnPlayerPrivmsg(playeridTargetIDmessage);
    return 
1;

Reply
#8

You could write a function to process the phrases, and use that function in chat and in command arguments (you could replace the text BEFORE processing the actual commands so that you don't have to do that in each command).

strcmp is not a good choice here since it is comparing a whole string (or its start) with the keyword, but the keyword can be anywhere in the string.
sscanf is also not really suiting as it's used to check for a specific format and extract values/strings etc from it, not replace keywords with other text.

You can use strfind, strdel and strins.

Using strfind you can find a given string (eg. "$loc") and get its position in the string. Then you delete the quickword from it and insert the new string (repeat this step until no appearances of the keyword are left).

I used something similar in a Filterscript which lets you save coordinates/other stuff to text files using a dynamic and custom format - for example "&x" will get replaced with the current X coordinate:

Код:
zformat_replace(target[], specifier[], text[], size = sizeof target, bool:ignorecase = true)
{
	new idx = -1, count;
	while((idx = strfind(target, specifier, ignorecase)) != -1)
	{
		strdel(target, idx, idx + strlen(specifier));
		strins(target, text, idx, size);

		count ++;
	}

	return count;
}
This function does what I described above, it searches for a specifier in the "target" string and replaces all appearances with the "text" string.

You could use it like this:

Код:
new string[30] = "$name test string $name";

zformat_replace(string, "$name", PlayerName(playerid));
And the string will be "NaS test string NaS".

Depending on how many keywords you want to add this is a viable method I guess. If you plan on adding a lot of them, there are more efficient ways of doing that.

edit: Seems Mugala was faster. I still suggest using a seperate function for it and do it BEFORE processing commands as it's much easier to use and saves a lot of work.
Reply
#9

Ive tried using that zformat and can get the more simple strings like $me and $loc work inside individual commands by placing this between the string being formatted and the message being sent to players:
Код:
		zformat_replace(string, "$loc", PlayerInfo[playerid][pLocation]);
		zformat_replace(string, "$me", PlayerInfo[playerid][pName]);

		
		SendClientMessageToAll(GetPlayerColor(playerid), string);
However I cant seem to get it to work for the slightly more complex ones such as:
Код:
if(strcmp(string[idx], "$civ", true, 4) == 0)
            {
                new closeststr[100], closestplayer = GetCivWhoIsClosest(playerid);

                if(IsPlayerConnected(closestplayer))
                format(closeststr, sizeof(closeststr), "%s (%d)",PlayerInfo[closestplayer][pName],closestplayer);
                else
                format(closeststr, sizeof(closeststr), "%s (%d)",PlayerInfo[playerid][pName], playerid);

                strdel(string, idx, idx + 4);
                strins(string, closeststr, idx);
                continue;
            }
I cant get it to work under OnPlayerCommandReceived at all either, I'm sure I am missing something here. Any more advice or info you can give? (or anybody else, I'm really struggling with this lol)
Reply
#10

Quote:
Originally Posted by Ducati
Посмотреть сообщение
Ive tried using that zformat and can get the more simple strings like $me and $loc work inside individual commands by placing this between the string being formatted and the message being sent to players:
Код:
		zformat_replace(string, "$loc", PlayerInfo[playerid][pLocation]);
		zformat_replace(string, "$me", PlayerInfo[playerid][pName]);

		
		SendClientMessageToAll(GetPlayerColor(playerid), string);
However I cant seem to get it to work for the slightly more complex ones such as:
Код:
if(strcmp(string[idx], "$civ", true, 4) == 0)
            {
                new closeststr[100], closestplayer = GetCivWhoIsClosest(playerid);

                if(IsPlayerConnected(closestplayer))
                format(closeststr, sizeof(closeststr), "%s (%d)",PlayerInfo[closestplayer][pName],closestplayer);
                else
                format(closeststr, sizeof(closeststr), "%s (%d)",PlayerInfo[playerid][pName], playerid);

                strdel(string, idx, idx + 4);
                strins(string, closeststr, idx);
                continue;
            }
I cant get it to work under OnPlayerCommandReceived at all either, I'm sure I am missing something here. Any more advice or info you can give? (or anybody else, I'm really struggling with this lol)
You could use the zformat function as well here, format the final string and then replace "$civ" with it. Or is there another issue which I didn't see?

Anyway using ZCMD (or other command processors) I'm not sure if it's possible to modify the string before it gets passed to commands (especially making it larger), so I cannot really help you with that (I still used OnPlayerCommandText in my filterscript for this reason, as I can easily modify the cmdtext before it gets processed, however that were just about 3 commands so there was no need for ZCMD - in a more complex script this would not be a good solution).
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)