Serverside Ammu-Nations! -
OstGot - 10.02.2016
Serverside Ammu-Nations!
Foreword:
Have you ever noticed when your anticheat falsely detects if player buys weapons and armour in the ammu-nation either when buying player get back his money?
After this you probably immediately tried to disable all the default places or made huge checks in your anticheats, which would give the opportunity to cheat in these places.
Both of these options are not the best solution, so a couple of days ago I started to do it all from scratch on the server side.
This system retains all capabilities of Ammu-nation, but with this it makes cheating impossible (be it money, weapons or armor) in these places.
Attention! If you don't have an anti-money, weapons or armour hack, then cheating will be possible. This just saves your anticheat from unnecessary checks.
So, let's begin:
First, add defines for comfortable editing in future
Somewhere in the beginning:
PHP код:
#define COST_9MM 200
#define COST_SILENCED 600
#define COST_DEAGLE 1200
#define COST_TEC9 300
#define COST_MICRO_SMG 500
#define COST_SHOTGUN 600
#define COST_SAWNOFF 800
#define COST_COMBAT 1000
#define COST_ARMOR 200
#define COST_SMG 2000
#define COST_AK47 3500
#define COST_M4 4500
The values on the right indicate the price in gaming $.
All prices are default, change it if you want.
Next we add an array with coordinates of Ammu-nations, so that you can easily find out where is the player.
Also add this somewhere in the beginning:
PHP код:
static const Float:AmmuCoords[][] =
{
{286.1489, -40.6443, 1001.5156},
{286.8009, -82.5475, 1001.5156},
{296.9199, -108.0719, 1001.5156},
{314.8209, -141.4319, 999.6015},
{316.5249, -167.7069, 999.5937}
};
Ok now you need to add some variables which will keep IDs of created actors-sellers, menus and purchases weapons objects
(to be able to set the animation to the actors and add items to menus)
Again, paste to the variables (in beginning):
PHP код:
new
AmmuObjects[MAX_PLAYERS],
Menu:AmmuMenus[19],
AmmuActors[5];
Memory allocation is finished.
Add a couple of forward for public to be used.
To "forward"s (either at the beginning of script):
PHP код:
forward OnPlayerBuyInAmmuNation(playerid, weaponid, ammo, cost);
forward DisableDefaultAmmu(playerid);
forward AmmuCheckPoint(playerid);
Ok, now let's move to the creation of the actors and the menus.
In OnGameModeInit (or in OnFilterScriptInit, if you make the filterscript):
PHP код:
AmmuActors[0] = CreateActor(179, 296.4576, -40.1324, 1001.5156, 0.0);
ApplyActorAnimation(AmmuActors[0], "FOOD", "SHP_Tray_Pose", 4.1, 1, 1, 1, 0, 0);
AmmuActors[1] = CreateActor(179, 295.6974, -82.5119, 1001.5156, 0.0);
ApplyActorAnimation(AmmuActors[1], "FOOD", "SHP_Tray_Pose", 4.1, 1, 1, 1, 0, 0);
AmmuActors[2] = CreateActor(179, 290.1882, -111.4814, 1001.5156, 0.0);
ApplyActorAnimation(AmmuActors[2], "FOOD", "SHP_Tray_Pose", 4.1, 1, 1, 1, 0, 0);
AmmuActors[3] = CreateActor(179, 308.1035, -143.0616, 999.6016, 0.0);
ApplyActorAnimation(AmmuActors[3], "FOOD", "SHP_Tray_Pose", 4.1, 1, 1, 1, 0, 0);
AmmuActors[4] = CreateActor(179, 312.7362, -167.84, 999.5938, 0.0);
ApplyActorAnimation(AmmuActors[4], "FOOD", "SHP_Tray_Pose", 4.1, 1, 1, 1, 0, 0);
AmmuMenus[0] = CreateMenu("Ammu-Nation", 1, 30.0, 150.0, 190.0, 180.0);
AddMenuItem(AmmuMenus[0], 0, "Pistols");
AddMenuItem(AmmuMenus[0], 0, "Micro SMGs");
AddMenuItem(AmmuMenus[0], 0, "Shotguns");
AddMenuItem(AmmuMenus[0], 0, "Armor");
AddMenuItem(AmmuMenus[0], 0, "SMG");
AddMenuItem(AmmuMenus[0], 0, "Assault");
AmmuMenus[1] = CreateMenu("Ammu-Nation", 1, 30.0, 150.0, 190.0, 180.0);
AddMenuItem(AmmuMenus[1], 0, "9mm");
AddMenuItem(AmmuMenus[1], 0, "Silenced 9mm");
AddMenuItem(AmmuMenus[1], 0, "Desert Eagle");
AmmuMenus[2] = CreateMenu("Ammu-Nation", 1, 30.0, 150.0, 190.0, 180.0);
AddMenuItem(AmmuMenus[2], 0, "Tec9");
AddMenuItem(AmmuMenus[2], 0, "Micro SMG");
AmmuMenus[3] = CreateMenu("Ammu-Nation", 1, 30.0, 150.0, 190.0, 180.0);
AddMenuItem(AmmuMenus[3], 0, "Shotgun");
AddMenuItem(AmmuMenus[3], 0, "Sawnoff Shotgun");
AddMenuItem(AmmuMenus[3], 0, "Combat Shotgun");
AmmuMenus[4] = CreateMenu("Ammu-Nation", 1, 30.0, 150.0, 190.0, 180.0);
AddMenuItem(AmmuMenus[4], 0, "Body Armor");
AmmuMenus[5] = CreateMenu("Ammu-Nation", 1, 30.0, 150.0, 190.0, 180.0);
AddMenuItem(AmmuMenus[5], 0, "SMG");
AmmuMenus[6] = CreateMenu("Ammu-Nation", 1, 30.0, 150.0, 190.0, 180.0);
AddMenuItem(AmmuMenus[6], 0, "AK47");
AddMenuItem(AmmuMenus[6], 0, "M4");
AmmuMenus[7] = CreateMenu("Ammu-Nation", 2, 30.0, 150.0, 100.0, 180.0);
SetMenuColumnHeader(AmmuMenus[7], 0, "Weapon");
SetMenuColumnHeader(AmmuMenus[7], 1, "Cost");
AddMenuItem(AmmuMenus[7], 0, "9mm");
AddMenuItem(AmmuMenus[7], 1, "$"#COST_9MM);
AmmuMenus[8] = CreateMenu("Ammu-Nation", 2, 30.0, 150.0, 100.0, 180.0);
SetMenuColumnHeader(AmmuMenus[8], 0, "Weapon");
SetMenuColumnHeader(AmmuMenus[8], 1, "Cost");
AddMenuItem(AmmuMenus[8], 0, "Silenced 9mm");
AddMenuItem(AmmuMenus[8], 1, "$"#COST_SILENCED);
AmmuMenus[9] = CreateMenu("Ammu-Nation", 2, 30.0, 150.0, 100.0, 180.0);
SetMenuColumnHeader(AmmuMenus[9], 0, "Weapon");
SetMenuColumnHeader(AmmuMenus[9], 1, "Cost");
AddMenuItem(AmmuMenus[9], 0, "Desert Eagle");
AddMenuItem(AmmuMenus[9], 1, "$"#COST_DEAGLE);
AmmuMenus[10] = CreateMenu("Ammu-Nation", 2, 30.0, 150.0, 100.0, 180.0);
SetMenuColumnHeader(AmmuMenus[10], 0, "Weapon");
SetMenuColumnHeader(AmmuMenus[10], 1, "Cost");
AddMenuItem(AmmuMenus[10], 0, "Tec9");
AddMenuItem(AmmuMenus[10], 1, "$"#COST_TEC9);
AmmuMenus[11] = CreateMenu("Ammu-Nation", 2, 30.0, 150.0, 100.0, 180.0);
SetMenuColumnHeader(AmmuMenus[11], 0, "Weapon");
SetMenuColumnHeader(AmmuMenus[11], 1, "Cost");
AddMenuItem(AmmuMenus[11], 0, "Micro SMG");
AddMenuItem(AmmuMenus[11], 1, "$"#COST_MICRO_SMG);
AmmuMenus[12] = CreateMenu("Ammu-Nation", 2, 30.0, 150.0, 100.0, 180.0);
SetMenuColumnHeader(AmmuMenus[12], 0, "Weapon");
SetMenuColumnHeader(AmmuMenus[12], 1, "Cost");
AddMenuItem(AmmuMenus[12], 0, "Shotgun");
AddMenuItem(AmmuMenus[12], 1, "$"#COST_SHOTGUN);
AmmuMenus[13] = CreateMenu("Ammu-Nation", 2, 30.0, 150.0, 100.0, 180.0);
SetMenuColumnHeader(AmmuMenus[13], 0, "Weapon");
SetMenuColumnHeader(AmmuMenus[13], 1, "Cost");
AddMenuItem(AmmuMenus[13], 0, "Sawnoff Shotgun");
AddMenuItem(AmmuMenus[13], 1, "$"#COST_SAWNOFF);
AmmuMenus[14] = CreateMenu("Ammu-Nation", 2, 30.0, 150.0, 100.0, 180.0);
SetMenuColumnHeader(AmmuMenus[14], 0, "Weapon");
SetMenuColumnHeader(AmmuMenus[14], 1, "Cost");
AddMenuItem(AmmuMenus[14], 0, "Combat Shotgun");
AddMenuItem(AmmuMenus[14], 1, "$"#COST_COMBAT);
AmmuMenus[15] = CreateMenu("Ammu-Nation", 2, 30.0, 150.0, 100.0, 180.0);
SetMenuColumnHeader(AmmuMenus[15], 0, "Weapon");
SetMenuColumnHeader(AmmuMenus[15], 1, "Cost");
AddMenuItem(AmmuMenus[15], 0, "Body Armor");
AddMenuItem(AmmuMenus[15], 1, "$"#COST_ARMOR);
AmmuMenus[16] = CreateMenu("Ammu-Nation", 2, 30.0, 150.0, 100.0, 180.0);
SetMenuColumnHeader(AmmuMenus[16], 0, "Weapon");
SetMenuColumnHeader(AmmuMenus[16], 1, "Cost");
AddMenuItem(AmmuMenus[16], 0, "SMG");
AddMenuItem(AmmuMenus[16], 1, "$"#COST_SMG);
AmmuMenus[17] = CreateMenu("Ammu-Nation", 2, 30.0, 150.0, 100.0, 180.0);
SetMenuColumnHeader(AmmuMenus[17], 0, "Weapon");
SetMenuColumnHeader(AmmuMenus[17], 1, "Cost");
AddMenuItem(AmmuMenus[17], 0, "AK47");
AddMenuItem(AmmuMenus[17], 1, "$"#COST_AK47);
AmmuMenus[18] = CreateMenu("Ammu-Nation", 2, 30.0, 150.0, 100.0, 180.0);
SetMenuColumnHeader(AmmuMenus[18], 0, "Weapon");
SetMenuColumnHeader(AmmuMenus[18], 1, "Cost");
AddMenuItem(AmmuMenus[18], 0, "M4");
AddMenuItem(AmmuMenus[18], 1, "$"#COST_M4);
Now in each Ammu-Nation we have added the sellers and created all the necessary menu for buy weapons.
Now we go to OnGameModeExit (or OnFilterScriptExit) and insert following:
PHP код:
new i;
for(i = sizeof(AmmuActors) - 1; i != -1; --i) DestroyActor(AmmuActors[i]);
for(i = sizeof(AmmuMenus) - 1; i != -1; --i) DestroyMenu(AmmuMenus[i]);
The sense of the code: destroy all created actors and the menus when the server/filterscript shuts down.
So, now we need to remove the object (which we will create below) when player exit, if he suddenly decides to quit during the purchase of weapons.
In OnPlayerDisconnect:
PHP код:
DestroyPlayerObject(playerid, AmmuObjects[playerid]);
AmmuObjects[playerid] = 0;
Now in OnPlayerInteriorChange:
PHP код:
switch(newinteriorid)
{
case 1, 4, 6, 7: SetTimerEx("DisableDefaultAmmu", 1000, 0, "i", playerid);
default: DisablePlayerCheckpoint(playerid);
}
At the entrance to the interiors of Ammu-Nations will be called a timer, in which we disable default ammu-nations.
I use the timer because after changing the interior player still doesn't move to it.
Otherwise we hide checkpoint (which also will created below) for player, if for example he left this interior and went to another.
In OnPlayerEnterCheckpoint add the following:
PHP код:
if(IsPlayerInRangeOfPoint(playerid, 5.0, 296.3255, -38.3040, 1001.5156))
{
DisablePlayerCheckpoint(playerid);
TogglePlayerControllable(playerid, 0);
SetPlayerFacingAngle(playerid, 180.0);
ShowMenuForPlayer(AmmuMenus[0], playerid);
SetPlayerCameraPos(playerid, 296.55, -38.4, 1002.2);
SetPlayerCameraLookAt(playerid, 296.4576, -40.1324, 1001.7156);
SetTimerEx("AmmuCheckPoint", 1000, 0, "i", playerid);
}
else if(IsPlayerInRangeOfPoint(playerid, 5.0, 295.7595, -80.5579, 1001.5156))
{
DisablePlayerCheckpoint(playerid);
TogglePlayerControllable(playerid, 0);
SetPlayerFacingAngle(playerid, 180.0);
ShowMenuForPlayer(AmmuMenus[0], playerid);
SetPlayerCameraPos(playerid, 295.7895, -80.55, 1002.2);
SetPlayerCameraLookAt(playerid, 295.6974, -82.5119, 1001.5156);
SetTimerEx("AmmuCheckPoint", 1000, 0, "i", playerid);
}
else if(IsPlayerInRangeOfPoint(playerid, 5.0, 290.1898, -109.482, 1001.5156))
{
DisablePlayerCheckpoint(playerid);
TogglePlayerControllable(playerid, 0);
SetPlayerFacingAngle(playerid, 180.0);
ShowMenuForPlayer(AmmuMenus[0], playerid);
SetPlayerCameraPos(playerid, 290.2898, -109.482, 1002.2);
SetPlayerCameraLookAt(playerid, 290.1882, -111.4814, 1001.5156);
SetTimerEx("AmmuCheckPoint", 1000, 0, "i", playerid);
}
else if(IsPlayerInRangeOfPoint(playerid, 5.0, 308.2072, -141.0583, 999.6016))
{
DisablePlayerCheckpoint(playerid);
TogglePlayerControllable(playerid, 0);
SetPlayerFacingAngle(playerid, 180.0);
ShowMenuForPlayer(AmmuMenus[0], playerid);
SetPlayerCameraPos(playerid, 308.2072, -141.0583, 1000.3016);
SetPlayerCameraLookAt(playerid, 308.1035, -143.0616, 999.6016);
SetTimerEx("AmmuCheckPoint", 1000, 0, "i", playerid);
}
else if(IsPlayerInRangeOfPoint(playerid, 5.0, 312.6785, -165.5487, 999.601))
{
DisablePlayerCheckpoint(playerid);
TogglePlayerControllable(playerid, 0);
SetPlayerFacingAngle(playerid, 180.0);
ShowMenuForPlayer(AmmuMenus[0], playerid);
SetPlayerCameraPos(playerid, 312.8785, -165.8487, 1000.301);
SetPlayerCameraLookAt(playerid, 312.7362, -167.84, 999.5938);
SetTimerEx("AmmuCheckPoint", 1000, 0, "i", playerid);
}
When the player enters the checkpoint, he will see buy menu.
Now go to in OnPlayerSelectedMenuRow, which contains main code.
In OnPlayerSelectedMenuRow:
PHP код:
new Menu:menu = GetPlayerMenu(playerid);
if(menu == AmmuMenus[0])
{
if(-1 < row < 6) ShowMenuForPlayer(AmmuMenus[row + 1], playerid);
}
else if(menu == AmmuMenus[1])
{
if(-1 < row < 3)
{
new weapon, ammo;
GetPlayerWeaponData(playerid, 2, weapon, ammo);
if(weapon && weapon != row + 22) AmmuSlotReplace(playerid);
if(IsPlayerInRangeOfPoint(playerid, 5.0, 296.3255, -38.3040, 1001.5156))
AmmuObjects[playerid] = CreatePlayerObject(playerid, row + 346, 296.6729, -39.5667, 1001.5991, 270.0, 0.0, 155.0);
else if(IsPlayerInRangeOfPoint(playerid, 5.0, 295.7595, -80.5579, 1001.5156))
AmmuObjects[playerid] = CreatePlayerObject(playerid, row + 346, 295.9295, -81.7579, 1001.5991, 270.0, 0.0, 155.0);
else if(IsPlayerInRangeOfPoint(playerid, 5.0, 290.1898, -109.482, 1001.5156))
AmmuObjects[playerid] = CreatePlayerObject(playerid, row + 346, 290.3998, -110.782, 1001.5991, 270.0, 0.0, 155.0);
else if(IsPlayerInRangeOfPoint(playerid, 5.0, 308.2072, -141.0583, 999.6016))
AmmuObjects[playerid] = CreatePlayerObject(playerid, row + 346, 308.3452, -142.3583, 999.6851, 270.0, 0.0, 155.0);
else if(IsPlayerInRangeOfPoint(playerid, 5.0, 312.6785, -165.5487, 999.601))
AmmuObjects[playerid] = CreatePlayerObject(playerid, row + 346, 312.9585, -167.1187, 999.6845, 270.0, 0.0, 155.0);
ShowMenuForPlayer(AmmuMenus[row + 7], playerid);
}
}
else if(menu == AmmuMenus[2])
{
if(-1 < row < 2)
{
new weapon, ammo;
GetPlayerWeaponData(playerid, 4, weapon, ammo);
if(weapon && (!row && weapon != 32 || row && weapon != 28)) AmmuSlotReplace(playerid);
if(IsPlayerInRangeOfPoint(playerid, 5.0, 296.3255, -38.3040, 1001.5156))
{
if(!row) AmmuObjects[playerid] = CreatePlayerObject(playerid, 372, 296.7229, -39.5667, 1001.5991, 270.0, 3.0, 155.0);
else AmmuObjects[playerid] = CreatePlayerObject(playerid, 352, 296.6529, -39.5667, 1001.5991, 265.0, 3.0, 155.0);
}
else if(IsPlayerInRangeOfPoint(playerid, 5.0, 295.7595, -80.5579, 1001.5156))
{
if(!row) AmmuObjects[playerid] = CreatePlayerObject(playerid, 372, 295.9595, -81.7579, 1001.5991, 270.0, 3.0, 155.0);
else AmmuObjects[playerid] = CreatePlayerObject(playerid, 352, 295.8895, -81.7579, 1001.5991, 265.0, 3.0, 155.0);
}
else if(IsPlayerInRangeOfPoint(playerid, 5.0, 290.1898, -109.482, 1001.5156))
{
if(!row) AmmuObjects[playerid] = CreatePlayerObject(playerid, 372, 290.4598, -110.782, 1001.5991, 270.0, 3.0, 155.0);
else AmmuObjects[playerid] = CreatePlayerObject(playerid, 352, 290.3898, -110.782, 1001.5991, 265.0, 3.0, 155.0);
}
else if(IsPlayerInRangeOfPoint(playerid, 5.0, 308.2072, -141.0583, 999.6016))
{
if(!row) AmmuObjects[playerid] = CreatePlayerObject(playerid, 372, 308.3852, -142.3583, 999.6851, 270.0, 3.0, 155.0);
else AmmuObjects[playerid] = CreatePlayerObject(playerid, 352, 308.3152, -142.3583, 999.6851, 265.0, 3.0, 155.0);
}
else if(IsPlayerInRangeOfPoint(playerid, 5.0, 312.6785, -165.5487, 999.601))
{
if(!row) AmmuObjects[playerid] = CreatePlayerObject(playerid, 372, 313.0085, -167.1187, 999.6845, 270.0, 3.0, 155.0);
else AmmuObjects[playerid] = CreatePlayerObject(playerid, 352, 312.9185, -167.1187, 999.6845, 265.0, 3.0, 155.0);
}
ShowMenuForPlayer(AmmuMenus[row + 10], playerid);
}
}
else if(menu == AmmuMenus[3])
{
if(-1 < row < 3)
{
new weapon, ammo;
GetPlayerWeaponData(playerid, 3, weapon, ammo);
if(weapon && weapon != row + 25) AmmuSlotReplace(playerid);
if(IsPlayerInRangeOfPoint(playerid, 5.0, 296.3255, -38.3040, 1001.5156))
AmmuObjects[playerid] = CreatePlayerObject(playerid, row + 349, 296.7829, -39.5667, 1001.5991, 265.0, 10.0, 155.0);
else if(IsPlayerInRangeOfPoint(playerid, 5.0, 295.7595, -80.5579, 1001.5156))
AmmuObjects[playerid] = CreatePlayerObject(playerid, row + 349, 296.0295, -81.7879, 1001.5991, 265.0, 10.0, 155.0);
else if(IsPlayerInRangeOfPoint(playerid, 5.0, 290.1898, -109.482, 1001.5156))
AmmuObjects[playerid] = CreatePlayerObject(playerid, row + 349, 290.4898, -110.782, 1001.5991, 265.0, 10.0, 155.0);
else if(IsPlayerInRangeOfPoint(playerid, 5.0, 308.2072, -141.0583, 999.6016))
AmmuObjects[playerid] = CreatePlayerObject(playerid, row + 349, 308.4182, -142.3583, 999.6851, 265.0, 10.0, 155.0);
else if(IsPlayerInRangeOfPoint(playerid, 5.0, 312.6785, -165.5487, 999.601))
AmmuObjects[playerid] = CreatePlayerObject(playerid, row + 349, 313.0585, -167.1187, 999.6845, 265.0, 10.0, 155.0);
ShowMenuForPlayer(AmmuMenus[row + 12], playerid);
}
}
else if(menu == AmmuMenus[4])
{
if(IsPlayerInRangeOfPoint(playerid, 5.0, 296.3255, -38.3040, 1001.5156))
AmmuObjects[playerid] = CreatePlayerObject(playerid, 373, 296.6629, -39.5667, 1002.0, 332.0, 295.0, 85.0);
else if(IsPlayerInRangeOfPoint(playerid, 5.0, 295.7595, -80.5579, 1001.5156))
AmmuObjects[playerid] = CreatePlayerObject(playerid, 373, 295.9095, -81.7579, 1002.0, 332.0, 295.0, 85.0);
else if(IsPlayerInRangeOfPoint(playerid, 5.0, 290.1898, -109.482, 1001.5156))
AmmuObjects[playerid] = CreatePlayerObject(playerid, 373, 290.3998, -110.782, 1002.0, 332.0, 295.0, 85.0);
else if(IsPlayerInRangeOfPoint(playerid, 5.0, 308.2072, -141.0583, 999.6016))
AmmuObjects[playerid] = CreatePlayerObject(playerid, 373, 308.3182, -142.3583, 1000.1051, 332.0, 295.0, 85.0);
else if(IsPlayerInRangeOfPoint(playerid, 5.0, 312.6785, -165.5487, 999.601))
AmmuObjects[playerid] = CreatePlayerObject(playerid, 373, 312.9685, -167.1187, 1000.1045, 332.0, 295.0, 85.0);
ShowMenuForPlayer(AmmuMenus[15], playerid);
}
else if(menu == AmmuMenus[5])
{
new weapon, ammo;
GetPlayerWeaponData(playerid, 4, weapon, ammo);
if(weapon && weapon != 29) AmmuSlotReplace(playerid);
if(IsPlayerInRangeOfPoint(playerid, 5.0, 296.3255, -38.3040, 1001.5156))
AmmuObjects[playerid] = CreatePlayerObject(playerid, 353, 296.6829, -39.4867, 1001.5991, 265.0, 8.0, 155.0);
else if(IsPlayerInRangeOfPoint(playerid, 5.0, 295.7595, -80.5579, 1001.5156))
AmmuObjects[playerid] = CreatePlayerObject(playerid, 353, 295.9595, -81.7579, 1001.5991, 265.0, 8.0, 155.0);
else if(IsPlayerInRangeOfPoint(playerid, 5.0, 290.1898, -109.482, 1001.5156))
AmmuObjects[playerid] = CreatePlayerObject(playerid, 353, 290.4198, -110.782, 1001.5991, 265.0, 8.0, 155.0);
else if(IsPlayerInRangeOfPoint(playerid, 5.0, 308.2072, -141.0583, 999.6016))
AmmuObjects[playerid] = CreatePlayerObject(playerid, 353, 308.3382, -142.3583, 999.6851, 265.0, 8.0, 155.0);
else if(IsPlayerInRangeOfPoint(playerid, 5.0, 312.6785, -165.5487, 999.601))
AmmuObjects[playerid] = CreatePlayerObject(playerid, 353, 312.9785, -167.1187, 999.6845, 265.0, 8.0, 155.0);
ShowMenuForPlayer(AmmuMenus[16], playerid);
}
else if(menu == AmmuMenus[6])
{
if(-1 < row < 2)
{
new weapon, ammo;
GetPlayerWeaponData(playerid, 5, weapon, ammo);
if(weapon && weapon != row + 30) AmmuSlotReplace(playerid);
if(IsPlayerInRangeOfPoint(playerid, 5.0, 296.3255, -38.3040, 1001.5156))
AmmuObjects[playerid] = CreatePlayerObject(playerid, row + 355, 296.7529, -39.5667, 1001.5991, 265.0, 3.0, 155.0);
else if(IsPlayerInRangeOfPoint(playerid, 5.0, 295.7595, -80.5579, 1001.5156))
AmmuObjects[playerid] = CreatePlayerObject(playerid, row + 355, 295.9595, -81.7579, 1001.5991, 265.0, 3.0, 155.0);
else if(IsPlayerInRangeOfPoint(playerid, 5.0, 290.1898, -109.482, 1001.5156))
AmmuObjects[playerid] = CreatePlayerObject(playerid, row + 355, 290.4198, -110.782, 1001.5991, 265.0, 3.0, 155.0);
else if(IsPlayerInRangeOfPoint(playerid, 5.0, 308.2072, -141.0583, 999.6016))
AmmuObjects[playerid] = CreatePlayerObject(playerid, row + 355, 308.3582, -142.3583, 999.6851, 265.0, 3.0, 155.0);
else if(IsPlayerInRangeOfPoint(playerid, 5.0, 312.6785, -165.5487, 999.601))
AmmuObjects[playerid] = CreatePlayerObject(playerid, row + 355, 312.9985, -167.1187, 999.6845, 265.0, 3.0, 155.0);
ShowMenuForPlayer(AmmuMenus[row + 17], playerid);
}
}
else if(menu == AmmuMenus[7])
{
if(GetPlayerMoney(playerid) < COST_9MM) AmmuBuyDenied(playerid);
else OnPlayerBuyInAmmuNation(playerid, 22, 30, COST_9MM);
ShowMenuForPlayer(AmmuMenus[7], playerid);
}
else if(menu == AmmuMenus[8])
{
if(GetPlayerMoney(playerid) < COST_SILENCED) AmmuBuyDenied(playerid);
else OnPlayerBuyInAmmuNation(playerid, 23, 30, COST_SILENCED);
ShowMenuForPlayer(AmmuMenus[8], playerid);
}
else if(menu == AmmuMenus[9])
{
if(GetPlayerMoney(playerid) < COST_DEAGLE) AmmuBuyDenied(playerid);
else OnPlayerBuyInAmmuNation(playerid, 24, 10, COST_DEAGLE);
ShowMenuForPlayer(AmmuMenus[9], playerid);
}
else if(menu == AmmuMenus[10])
{
if(GetPlayerMoney(playerid) < COST_TEC9) AmmuBuyDenied(playerid);
else OnPlayerBuyInAmmuNation(playerid, 32, 60, COST_TEC9);
ShowMenuForPlayer(AmmuMenus[10], playerid);
}
else if(menu == AmmuMenus[11])
{
if(GetPlayerMoney(playerid) < COST_MICRO_SMG) AmmuBuyDenied(playerid);
else OnPlayerBuyInAmmuNation(playerid, 28, 60, COST_MICRO_SMG);
ShowMenuForPlayer(AmmuMenus[11], playerid);
}
else if(menu == AmmuMenus[12])
{
if(GetPlayerMoney(playerid) < COST_SHOTGUN) AmmuBuyDenied(playerid);
else OnPlayerBuyInAmmuNation(playerid, 25, 15, COST_SHOTGUN);
ShowMenuForPlayer(AmmuMenus[12], playerid);
}
else if(menu == AmmuMenus[13])
{
if(GetPlayerMoney(playerid) < COST_SAWNOFF) AmmuBuyDenied(playerid);
else OnPlayerBuyInAmmuNation(playerid, 26, 12, COST_SAWNOFF);
ShowMenuForPlayer(AmmuMenus[13], playerid);
}
else if(menu == AmmuMenus[14])
{
if(GetPlayerMoney(playerid) < COST_COMBAT) AmmuBuyDenied(playerid);
else OnPlayerBuyInAmmuNation(playerid, 27, 10, COST_COMBAT);
ShowMenuForPlayer(AmmuMenus[14], playerid);
}
else if(menu == AmmuMenus[15])
{
if(GetPlayerMoney(playerid) < COST_ARMOR) AmmuBuyDenied(playerid);
else
{
new Float:armour;
GetPlayerArmour(playerid, armour);
if(armour >= 100.0)
{
PlayerPlaySound(playerid, 1053, 0.0, 0.0, 0.0);
GameTextForPlayer(playerid, "~n~~n~~n~~n~~n~~n~~n~~n~~w~You cannot buy any more armor.", 5000, 3);
}
else OnPlayerBuyInAmmuNation(playerid, 0, 100, COST_ARMOR);
}
ShowMenuForPlayer(AmmuMenus[15], playerid);
}
else if(menu == AmmuMenus[16])
{
if(GetPlayerMoney(playerid) < COST_SMG) AmmuBuyDenied(playerid);
else OnPlayerBuyInAmmuNation(playerid, 29, 90, COST_SMG);
ShowMenuForPlayer(AmmuMenus[16], playerid);
}
else if(menu == AmmuMenus[17])
{
if(GetPlayerMoney(playerid) < COST_AK47) AmmuBuyDenied(playerid);
else OnPlayerBuyInAmmuNation(playerid, 30, 120, COST_AK47);
ShowMenuForPlayer(AmmuMenus[17], playerid);
}
else if(menu == AmmuMenus[18])
{
if(GetPlayerMoney(playerid) < COST_M4) AmmuBuyDenied(playerid);
else OnPlayerBuyInAmmuNation(playerid, 31, 90, COST_M4);
ShowMenuForPlayer(AmmuMenus[18], playerid);
}
If you use a custom function for get the money of the player (not GetPlayerMoney), you need to find in the above code all these functions and replace it on your function.
The hardest part behind)
Here we check what dialog has chosen by player and depending on the choice we give him weapon, showing the same weapon object on the counter. Ibid at confirmation of purchase we called public OnPlayerBuyInAmmuNation, which we add later.
But first you need to make exit of our menu.
Therefore, insert in OnPlayerExitedMenu:
PHP код:
new Menu:menu = GetPlayerMenu(playerid);
if(menu == AmmuMenus[17] || menu == AmmuMenus[18])
{
DestroyPlayerObject(playerid, AmmuObjects[playerid]);
ShowMenuForPlayer(AmmuMenus[6], playerid);
}
else if(menu == AmmuMenus[16])
{
DestroyPlayerObject(playerid, AmmuObjects[playerid]);
ShowMenuForPlayer(AmmuMenus[5], playerid);
}
else if(menu == AmmuMenus[15])
{
DestroyPlayerObject(playerid, AmmuObjects[playerid]);
ShowMenuForPlayer(AmmuMenus[4], playerid);
}
else if(menu == AmmuMenus[12] || menu == AmmuMenus[13] || menu == AmmuMenus[14])
{
DestroyPlayerObject(playerid, AmmuObjects[playerid]);
ShowMenuForPlayer(AmmuMenus[3], playerid);
}
else if(menu == AmmuMenus[10] || menu == AmmuMenus[11])
{
DestroyPlayerObject(playerid, AmmuObjects[playerid]);
ShowMenuForPlayer(AmmuMenus[2], playerid);
}
else if(menu == AmmuMenus[7] || menu == AmmuMenus[8] || menu == AmmuMenus[9])
{
DestroyPlayerObject(playerid, AmmuObjects[playerid]);
ShowMenuForPlayer(AmmuMenus[1], playerid);
}
else if(menu == AmmuMenus[1] || menu == AmmuMenus[2] || menu == AmmuMenus[3]
|| menu == AmmuMenus[4] || menu == AmmuMenus[5] || menu == AmmuMenus[6]) ShowMenuForPlayer(AmmuMenus[0], playerid);
else if(menu == AmmuMenus[0])
{
TogglePlayerControllable(playerid, 1);
SetCameraBehindPlayer(playerid);
}
We have made exit of the menus, where at the exit from the last menu we go back to the back menu until they don't close and player will not return to the old position.
Things are easy: add our created publics and functions.
Somewhere (maybe at the end of your script):
PHP код:
public DisableDefaultAmmu(playerid)
{
if(IsPlayerConnected(playerid))
{
new Float:pX, Float:pY, Float:pZ;
GetPlayerPos(playerid, pX, pY, pZ);
if(pZ > 800.0)
{
SetPlayerShopName(playerid, "");
AmmuCheckPoint(playerid);
}
else SetTimerEx("DisableDefaultAmmu", 1000, 0, "i", playerid);
}
return 1;
}
This is called by the timer, remember? Disables default ammu-nation.
Then, somewhere at the end too:
PHP код:
public AmmuCheckPoint(playerid)
{
new interior = GetPlayerInterior(playerid);
if(interior == 1 && IsPlayerInRangeOfPoint(playerid, 30.0, AmmuCoords[0][0], AmmuCoords[0][1], AmmuCoords[0][2]))
{
if(IsPlayerInRangeOfPoint(playerid, 1.2, 296.3255, -38.3040, 1001.5156))
SetTimerEx("AmmuCheckPoint", 1000, 0, "i", playerid);
else SetPlayerCheckpoint(playerid, 296.3255, -38.3040, 1001.5156, 1.0);
}
else if(interior == 4 && IsPlayerInRangeOfPoint(playerid, 30.0, AmmuCoords[1][0], AmmuCoords[1][1], AmmuCoords[1][2]))
{
if(IsPlayerInRangeOfPoint(playerid, 1.2, 295.7595, -80.5579, 1001.5156))
SetTimerEx("AmmuCheckPoint", 1000, 0, "i", playerid);
else SetPlayerCheckpoint(playerid, 295.7595, -80.5579, 1001.5156, 1.0);
}
else if(interior == 6 && IsPlayerInRangeOfPoint(playerid, 30.0, AmmuCoords[2][0], AmmuCoords[2][1], AmmuCoords[2][2]))
{
if(IsPlayerInRangeOfPoint(playerid, 1.2, 290.1898, -109.482, 1001.5156))
SetTimerEx("AmmuCheckPoint", 1000, 0, "i", playerid);
else SetPlayerCheckpoint(playerid, 290.1898, -109.482, 1001.5156, 1.0);
}
else if(interior == 7 && IsPlayerInRangeOfPoint(playerid, 30.0, AmmuCoords[3][0], AmmuCoords[3][1], AmmuCoords[3][2]))
{
if(IsPlayerInRangeOfPoint(playerid, 1.2, 308.2072, -141.0583, 999.6016))
SetTimerEx("AmmuCheckPoint", 1000, 0, "i", playerid);
else SetPlayerCheckpoint(playerid, 308.2072, -141.0583, 999.6016, 1.0);
}
else if(interior == 6 && IsPlayerInRangeOfPoint(playerid, 30.0, AmmuCoords[4][0], AmmuCoords[4][1], AmmuCoords[4][2]))
{
if(IsPlayerInRangeOfPoint(playerid, 1.2, 312.6785, -165.5487, 999.601))
SetTimerEx("AmmuCheckPoint", 1000, 0, "i", playerid);
else SetPlayerCheckpoint(playerid, 312.6785, -165.5487, 999.601, 1.0);
}
return 1;
}
This shows our checkpoint, when player enters the ammu-nation. The above code checks in which ammu-nation the player is and if player is already at the checkpoint, we run the timer again as long as he doesn't move from it. Otherwise, we create a checkpoint (but only if player in the Ammu-Nation).
Finally, create OnPlayerBuyInAmmuNation, which is called when player has bought weapons/armor.
PHP код:
public OnPlayerBuyInAmmuNation(playerid, weaponid, ammo, cost)
{
new const fmt_str[] = "Weapon purchased at the price of $%d"; //Here your text
new str[sizeof(fmt_str) + 3];
GivePlayerMoney(playerid, -cost); //If there is an anti-money hack, then replace this function
GivePlayerWeapon(playerid, weaponid, ammo); //If there is an anti-weapon hack, too, replace if necessary
if(!weaponid) SetPlayerArmour(playerid, ammo); //And here too, just with the armour
format(str, sizeof str, fmt_str, cost);
SendClientMessage(playerid, -1, str);
return 1;
}
Yay, almost everything already created!
![Smiley](images/smilies/smile.png)
Only a little things (they too at the end):
PHP код:
AmmuBuyDenied(playerid)
{
PlayerPlaySound(playerid, 1053, 0.0, 0.0, 0.0);
GameTextForPlayer(playerid, "~n~~n~~n~~n~~n~~n~~n~~n~~w~You don't have enough money to buy this item.", 5000, 3);
return 1;
}
AmmuSlotReplace(playerid)
{
GameTextForPlayer(playerid, "~n~~n~~n~~n~~n~~n~~n~~n~~w~Buying this item will replace the weapon in this slot.", 5000, 3);
return 1;
}
The first function is called when player doesn't have enough money to buy some weapon. In this case we send to player the corresponding text (can be replaced).
The second function is called when player wants to buy a weapon, but he already has a counterpart. Script will send message to player that his weapon will be replaced by a purchased weapon.
Again, change the text if you need.
And because this is only the foundation, you can modify this script to your liking: by adding, for example, the choice of weapons with the smooth movement of the camera or something else.
Thanks:
Carlton - coordinates of ammu-nations
Good luck.
Re: Serverside Ammu-Nations! -
Crayder - 10.02.2016
Tutorial? You literally just gave all of the code to do it. Why not just release an include?