stock randomEx(min, max)
{
//Credits to y_less
new rand = random(max-min)+min;
return rand;
}
forward ProxDetectorS(Float:radi, playerid, targetid);
stock ProxDetector(Float:radi, playerid, string[], col1, col2, col3, col4, col5)
{
if(IsPlayerConnected(playerid))
{
new Float:posx, Float:posy, Float:posz;
new Float:oldposx, Float:oldposy, Float:oldposz;
new Float:tempposx, Float:tempposy, Float:tempposz;
new invehicle[MAX_PLAYERS];
new virtualworld = GetPlayerVirtualWorld(playerid);
new interior = GetPlayerInterior(playerid);
new vehicleid = GetPlayerVehicleID(playerid);
new ivehicleid;
if(vehicleid)
{
GetVehiclePos(vehicleid,oldposx,oldposy,oldposz);
}
else
{
GetPlayerPos(playerid, oldposx, oldposy, oldposz);
vehicleid = GetPlayerVehicleID(playerid);
}
while (strfind(string, PlayerName(playerid), false) != -1 && PlayerInfo[playerid][pMask])
{
new pos = strfind(string, PlayerName(playerid), false);
strdel(string, pos, pos + strlen(PlayerName(playerid)));
new string2[26];
format(string2, sizeof(string2), "Stranger %d", StrangerID[playerid]);
strins(string, string2, pos, 512);
}
for(new i = 0; i < MAX_PLAYERS; i++)
{
if(IsPlayerConnected(i))
{
if(!BigEar[i])
{
if(GetPlayerVirtualWorld(i) == virtualworld)
{
if((GetPlayerInterior(i) == interior))
{
if(vehicleid)
{
if(IsPlayerInVehicle(i,vehicleid)) invehicle[i] = 1;
}
if(!invehicle[i])
{
if(IsPlayerInAnyVehicle(i))
{
ivehicleid = GetPlayerVehicleID(i);
GetVehiclePos(ivehicleid,posx,posy,posz);
}
else
{
GetPlayerPos(i,posx,posy,posz);
}
tempposx = (oldposx -posx);
tempposy = (oldposy -posy);
tempposz = (oldposz -posz);
if (((tempposx < radi/16) && (tempposx > -radi/16)) && ((tempposy < radi/16) && (tempposy > -radi/16)) && ((tempposz < radi/16) && (tempposz > -radi/16))) SendClientMessage(i, col1, string);
else if (((tempposx < radi/8) && (tempposx > -radi/8)) && ((tempposy < radi/8) && (tempposy > -radi/8)) && ((tempposz < radi/8) && (tempposz > -radi/8))) SendClientMessage(i, col2, string);
else if (((tempposx < radi/4) && (tempposx > -radi/4)) && ((tempposy < radi/4) && (tempposy > -radi/4)) && ((tempposz < radi/4) && (tempposz > -radi/4))) SendClientMessage(i, col3, string);
else if (((tempposx < radi/2) && (tempposx > -radi/2)) && ((tempposy < radi/2) && (tempposy > -radi/2)) && ((tempposz < radi/2) && (tempposz > -radi/2))) SendClientMessage(i, col4, string);
else if (((tempposx < radi) && (tempposx > -radi)) && ((tempposy < radi) && (tempposy > -radi)) && ((tempposz < radi) && (tempposz > -radi))) SendClientMessage(i, col5, string);
}
else SendClientMessage(i, col1, string);
}
}
}
else SendClientMessage(i, col1, string);
}
}
}
return 1;
}
#define DIALOG_MASK 1
#define PURPLE 0xC2A2DAAA
new StrangerID[MAX_PLAYERS]; //Gets/Sets the player's stranger ID when the mask.
new Text3D:StrangerTag[MAX_PLAYERS]; //This will be the 3DTextLabel that shows their stranger ID
new Text3D:StrangerHealth[MAX_PLAYERS]; //This will show the stranger's health & armor (if they have armor)
CMD:mask(playerid, params[])
{
if(StrangerID[playerid]) == 0) //Checking to see if the player is already masked...
{
ShowPlayerDialog(playerid, DIALOG_MASK, DIALOG_STYLE_LIST, "Which mask?", "Sunglasses\nHandkerchief\nMask (default)", "Select", "Cancel"); //Asking them what style of mask they would like to wear...
}
else if(StrangerID[playerid] > 0) //But if the player is already masked...
{
SendClientMessage(playerid, -1, "ERROR: You already have a mask on. Use /unmask to take it off!"); //Send this message...
}
return 1;
}
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
switch(dialogid)
{
case DIALOG_MASK: //If the mask dialog is chosen...
{
if(!response) return 0; //If the cancel button is hit then do nothing.
new choice[64], string[128], bool:found = false; //The bool here is important as it states whether the system has found an available stranger ID for the player.
for(new i = 0; i < MAX_PLAYERS; i++) //Looping through all the players.
{
new randz = randomEx(1000, 5000);
if (StrangerID[i] == randz) //The Stranger ID is currently in use by another player, so we will continue the server for an ID...
{
while (!found) //When the system has still yet to find an available stranger ID...
{
randz = randomEx(1000, 5000); //Call another random to try to find an available Stranger ID
if (StrangerID[i] == randz) //If the attempted new Stranger ID is already taken...
{
found = false; //Let the search continue...
continue; //Continue the search...
}
else //If the attempted new Stranger ID is available...
{
found = true; //The search is over, we have found our Stranger ID!
break; //Get out of this section and continue on in the script.
}
}
}
StrangerID[playerid] = randz; //Set the stranger ID to the found random integer
ShowPlayerNameTagForPlayer(i, playerid, 0); //Hide the player's name tag for all players.
}
switch(listitem) //Switching between the three mask options (no difference between them other than the tag, which is intended for roleplay purposes.
{
case 0: //If they chose sunglasses...
{
format(string, sizeof(string), "* Stranger %d has put on a pair of sunglasses", StrangerID[playerid]); //Just formatting their RP message for ProxDetector.
format(choice, sizeof(choice), "Stranger %d (sunglasses)", StrangerID[playerid]); //Setting their Stranger Tag
}
case 1: //If they chose a handkerchief...
{
format(string, sizeof(string), "* Stranger %d has put on a handkerchief", StrangerID[playerid]); //Just formatting their RP message for ProxDetector.
format(choice, sizeof(choice), "Stranger %d (handkerchief)", StrangerID[playerid]);//Setting their Stranger Tag
}
case 2: //If they chose a regular mask...
{
format(string, sizeof(string), "* Stranger %d has put on a mask", StrangerID[playerid]); //Just formatting their RP message for ProxDetector.
format(choice, sizeof(choice), "Stranger %d (mask)", StrangerID[playerid]);//Setting their Stranger Tag
}
}
StrangerTag[playerid] = Create3DTextLabel(choice, 0xFFFFFFFF, 0, 0, 0, 15.0, 0, 1); //Let's define the player's StrangerTag and set it to their formatted tag from above.
Attach3DTextLabelToPlayer(StrangerTag[playerid], playerid, 0.0, 0.0, 0.3); //Attach their 3DTextLabel from the line above.
new Float:arm, Float:hps, healthstring[64]; //Float variables to detect a player's health and the string to format the information to.
GetPlayerHealth(playerid, hps); //Get the player's health and set it to Float:hps.
GetPlayerArmour(playerid, arm); //Get the player's armor and set it to Float:arm.
new hpe = floatround(hps); //Create a new variable (integer) and round the float to a whole number to display the health.
new arme = floatround(arm); //Create a new variable (integer) and round the float to a whole number to display the armor.
if(arm != 0) //If the player's armor is greater than zero...
{
format(healthstring, sizeof(healthstring), "HP: %d | Armour: %d", hpe, arme); //Format their health string to include both Health and Armor information.
}
else //If the player has no armor.
{
format(healthstring, sizeof(healthstring), "Health: %d", hpe); //Format their health string to only include their health.
}
StrangerHealth[playerid] = Create3DTextLabel(healthstring, 0xFFFFFFFF, 0, 0, 0, 15.0, 0, 1); //Create their 3DTextLabel for their health information and set it to the healthstring formatted in the if statement above.
Attach3DTextLabelToPlayer(StrangerHealth[playerid], playerid, 0.0, 0.0, 0.225); //Attach their health information.
ProxDetector(15.0, playerid, string, PURPLE, PURPLE, PURPLE, PURPLE, PURPLE); //Send the RP message that the person has put on a mask
}
return 1;
}
return 0;
}
stock RemoveMask(playerid)
{
if(StrangerID[playerid] == 0) return 0; //If the player doesn't have a mask to remove in the first place...
StrangerID[playerid] = 0; //Setting the stranger ID to zero, as the player no longer needs a Stranger ID.
Delete3DTextLabel(StrangerTag[playerid]); //Deleting the StrangerTag, as they are no longer a stranger.
Delete3DTextLabel(StrangerHealth[playerid]); //Deleting the StrangerHealth, as they are no longer a stranger.
for(new i=0;i<MAX_PLAYERS;i++) //Looping through all the players...
{
ShowPlayerNameTagForPlayer(i, playerid, 1); //Show the player's name again to other players.
}
return 1;
}
public OnPlayerDeath(playerid, killerid, reason) //We are using this here because SA:MP (by default) show's player nametags again to everyone when the player dies. You can make a workaround for this; however for the sake of time I will not go into that (merely hide the player's name again and you should be good.)
{
if(StrangerID[playerid] != 0) RemoveMask(playerid); //Call the RemoveMask function for the player when they die if the player is masked.
return 1;
}
public OnPlayerDisconnect(playerid, reason) //We are removing it here in order to clean up the 3DTextLabels and permit the StrangerID to be available for new people who /mask.
{
if(StrangerID[playerid] != 0) RemoveMask(playerid); //Call the RemoveMask function for the player when they disconnect if the player is masked so it cleans the old 3DTextLabels and can open up a StrangerID for the random search.
return 1;
}
CMD:unmask(playerid, params[]) //And finally, the command to unmask..
{
if(StrangerID[playerid] == 0) return SendClientMessage(playerid, -1, "You are not wearing a mask, use /mask to put one on!");
RemoveMask(playerid);
new string[128], Name[64];
GetPlayerName(playerid, Name, MAX_PLAYER_NAME);
format(string, sizeof(string), "* %s removes the clothing from their face, revealing their identity. *", Name); //formatting a RP message to show people nearly as the person removes their mask.
ProxDetector(15.0, playerid, string, PURPLE, PURPLE, PURPLE, PURPLE, PURPLE); //Send the RP message that the person has removed their mask.
return 1;
}
public OnGameModeInit()
{
SetTimer("StrangerHealthUpdate", 1000, true); //You can put everything that is called in this timer in any other 1-second timer to conserve on computer RAM and CPU, I just made a separate one because we only use one timer throughout the script.
return 1;
}
forward StrangerHealthUpdate();
public StrangerHealthUpdate()
{
for(new i=0;i<MAX_PLAYERS;i++) //Looping through all the players...
{
if(StrangerID[i] != 0) //If the player's Stranger ID does not equal zero...
{
new Float:hps, Float:arm, healthstring[64]; //All the stuff from when we got the health before.
GetPlayerHealth(playerid, hps); //Get their health in Float:hps
GetPlayerArmour(playerid, arm); //Get their armor in Float:arm
new armour = floatround(arm); //Round their armor to an integer
new hltz = floatround(hps); //Round their health to an integer
if(arm != 0) //If they have greater than zero armor...
{
format(healthstring, sizeof(healthstring), "HP: %d | Armour: %d", hltz, armour); //Format it as such...
}
else //If they have zero armor...
{
format(healthstring, sizeof(healthstring), "Health: %d", hltz); //Format it without armor
}
Update3DTextLabelText(StrangerHealth[playerid], 0xFFFFFFFF, healthstring); //And now we update the string.
}
}
return 1;
}
Now this is a great tutorial. Good to see a tutorial with such explanations
I am going to test it soon, and will let you know if I find any bug. |
I've actually found an annoyance, rather than a bug. I found out it is possible to do it with one textdraw, but I'm working on fixing that now. Thanks for your feedback!
|
I will be waiting for it!
By the way, I don't think sunglasses are masks . |