13.08.2011, 13:38
This tutorial shows how you can create gang zones and zone wars.
Teams
I'm assuming that you have your teams set up.
If you don't, you can easily set them by following this tutorial: https://sampwiki.blast.hk/wiki/PAWN_tutorial
I will be using 3 example teams in this tutorial
Creating The Zones
I created 3 zones, 1 for each team.
Let's look at the first one
If you look at the enum, you see what each number means.
2337.9004 - zMinX
-1808.8383 - zMinY
2590.2043 - zMaxX
-1610.3673 - zMaxY
TEAM_GROVE - zTeam
The coordinates zMinX, zMinY, zMaxX, zMaxY are used in GangZoneCreate function to create the zones.
You should create the gang zones in OnGameModeInit or in OnFilterScriptInit if you are making a filterscript.
You also have to show the gang zones to the player. You can do this in OnPlayerSpawn.
You also need the GetTeamZoneColor function
Note that I added 88 to the end of the colors. This shows transparency. If you want to make the zones more transparent, use smaller values like 55. If you want to make the zones less transparent, use bigger values like AA.
Now the zones should be working.
Adding New Zones
If you want to add more zones, you need to get the coordinates.
You can do this with /save [comment] command in any SA-MP server or in Debug Mode.
Just go in game and find the location for the gang zone.
You have to use /save in 2 places: in point 1 and point 2 (see the picture):
1. Go to point 1 and do "/save example min"
2. Go to point 2 and do "/save example max"
Then you should have the lines in My Documents\GTA San Andreas User Files\SAMP\savedpositions.txt
You only need these coordinates
So if you want to add a zone for Grove, you have all the things you need to create a new gang zone
1429.3770 - zMinX
-1732.4554 - zMinY
1529.1932 - zMaxX
-1592.1989 - zMaxY
TEAM_GROVE - zTeam
Then add this line to ZoneInfo
So the ZoneInfo should look like this
Zone Attack
Now that you have your zones placed, let's make them attackable.
First we should make some additions to our code.
Add these new global variables
If a war is going on, the zone should be flashing. Make these changes to OnPlayerSpawn
There are many ways to start a gang zone war, but I will show you 2 of them.
Zone Attack #1
To start a war, you need to have some team members on enemy zone.
We will need some defines and stock functions
We define them so they can be easily changed later.
We need to make an array of all our teams to later use it in a loop. Add all your teams here.
Set up a timer in OnGameModeInit or in OnFilterScriptInit if you are making a filterscript.
Add a public function for the timer (don't forget to forward it)
And you are done. Now, if there are enough enemies in the zone, a war will start and last until enemies have left the zone or have been there enough time to capture it.
Zone Attack #2
To start a war, you need to kill some enemies on enemy zone.
We will need some defines
We define them so they can be easily changed later.
Set up a timer in OnGameModeInit or in OnFilterScriptInit if you are making a filterscript.
Add a public function for the timer (don't forget to forward it)
Now we need to trigger the attack in OnPlayerDeath
We also need a global variable ZoneDeaths and GetPlayerZone function.
And you are done. Now, if there has been enough kills in a zone, a war will start and last until enemies have left the zone or have been there enough time to capture it.
Notes
I'm using GetPlayerTeam to check player team. If you define your teams in some other way (gTeam[playerid] for example), just replace it with your define.
The End
This is the end of the tutorial. If you have any questions or recommendations, feel free to post them here
Teams
I'm assuming that you have your teams set up.
If you don't, you can easily set them by following this tutorial: https://sampwiki.blast.hk/wiki/PAWN_tutorial
I will be using 3 example teams in this tutorial
pawn Code:
#define TEAM_GROVE 1
#define TEAM_BALLAS 2
#define TEAM_VAGOS 3
pawn Code:
enum eZone
{
Float:zMinX,
Float:zMinY,
Float:zMaxX,
Float:zMaxY,
zTeam
}
new ZoneInfo[][eZone] = {
{2337.9004,-1808.8383,2590.2043,-1610.3673,TEAM_GROVE},
{2084.7,-1808.8383,2337.9004,-1610.3673,TEAM_BALLAS},
{2590.2043,-1808.8383,2842.3,-1610.3673,TEAM_VAGOS}
};
new ZoneID[sizeof(ZoneInfo)];
Let's look at the first one
pawn Code:
{2337.9004,-1808.8383,2590.2043,-1610.3673,TEAM_GROVE},
2337.9004 - zMinX
-1808.8383 - zMinY
2590.2043 - zMaxX
-1610.3673 - zMaxY
TEAM_GROVE - zTeam
The coordinates zMinX, zMinY, zMaxX, zMaxY are used in GangZoneCreate function to create the zones.
You should create the gang zones in OnGameModeInit or in OnFilterScriptInit if you are making a filterscript.
pawn Code:
for(new i=0; i < sizeof(ZoneInfo); i++)
{
ZoneID[i] = GangZoneCreate(ZoneInfo[i][zMinX], ZoneInfo[i][zMinY], ZoneInfo[i][zMaxX], ZoneInfo[i][zMaxY]);
}
pawn Code:
for(new i=0; i < sizeof(ZoneInfo); i++)
{
GangZoneShowForPlayer(playerid, ZoneID[i], GetTeamZoneColor(ZoneInfo[i][zTeam]));
}
pawn Code:
stock GetTeamZoneColor(teamid)
{
switch(teamid)
{
case TEAM_GROVE: return 0x00FF0088;
case TEAM_BALLAS: return 0xFF00FF88;
case TEAM_VAGOS: return 0xFFFF0088;
}
return -1;
}
Now the zones should be working.
Adding New Zones
If you want to add more zones, you need to get the coordinates.
You can do this with /save [comment] command in any SA-MP server or in Debug Mode.
Just go in game and find the location for the gang zone.
You have to use /save in 2 places: in point 1 and point 2 (see the picture):
1. Go to point 1 and do "/save example min"
2. Go to point 2 and do "/save example max"
Then you should have the lines in My Documents\GTA San Andreas User Files\SAMP\savedpositions.txt
Code:
AddPlayerClass(107,1429.3770,-1732.4554,13.3828,355.2560,0,0,0,0,0,0); // example min AddPlayerClass(107,1529.1932,-1592.1989,13.3828,90.5102,0,0,0,0,0,0); // example max
Code:
1429.3770,-1732.4554 1529.1932,-1592.1989
1429.3770 - zMinX
-1732.4554 - zMinY
1529.1932 - zMaxX
-1592.1989 - zMaxY
TEAM_GROVE - zTeam
Then add this line to ZoneInfo
pawn Code:
{1429.3770,-1732.4554,1529.1932,-1592.1989,TEAM_GROVE}
pawn Code:
new ZoneInfo[][eZone] = {
{2337.9004,-1808.8383,2590.2043,-1610.3673,TEAM_GROVE},
{2084.7,-1808.8383,2337.9004,-1610.3673,TEAM_BALLAS},
{2590.2043,-1808.8383,2842.3,-1610.3673,TEAM_VAGOS},
{1429.3770,-1732.4554,1529.1932,-1592.1989,TEAM_GROVE}
};
Now that you have your zones placed, let's make them attackable.
First we should make some additions to our code.
Add these new global variables
pawn Code:
new ZoneAttacker[sizeof(ZoneInfo)] = {-1, ...};
new ZoneAttackTime[sizeof(ZoneInfo)];
pawn Code:
for(new i=0; i < sizeof(ZoneInfo); i++)
{
GangZoneShowForPlayer(playerid, ZoneID[i], GetTeamZoneColor(ZoneInfo[i][zTeam]));
if(ZoneAttacker[i] != -1) GangZoneFlashForPlayer(playerid, ZoneID[i], GetTeamZoneColor(ZoneAttacker[i]));
}
Zone Attack #1
To start a war, you need to have some team members on enemy zone.
We will need some defines and stock functions
pawn Code:
#define TAKEOVER_TIME 120 // how many seconds needed to take over the zone
#define MIN_MEMBERS_TO_START_WAR 3 // how many team members needed in a zone to start a war
pawn Code:
new Teams[] = {
TEAM_GROVE,
TEAM_BALLAS,
TEAM_VAGOS
};
pawn Code:
stock IsPlayerInZone(playerid, zoneid)
{
new Float:x, Float:y, Float:z;
GetPlayerPos(playerid, x, y, z);
return (x > ZoneInfo[zoneid][zMinX] && x < ZoneInfo[zoneid][zMaxX] && y > ZoneInfo[zoneid][zMinY] && y < ZoneInfo[zoneid][zMaxY]);
}
stock GetPlayersInZone(zoneid, teamid)
{
new count;
for(new i=0; i < MAX_PLAYERS; i++)
{
if(IsPlayerConnected(i) && GetPlayerTeam(i) == teamid && IsPlayerInZone(i, zoneid))
{
count++;
}
}
return count;
}
pawn Code:
SetTimer("ZoneTimer", 1000, true);
pawn Code:
public ZoneTimer()
{
for(new i=0; i < sizeof(ZoneInfo); i++) // loop all zones
{
if(ZoneAttacker[i] != -1) // zone is being attacked
{
if(GetPlayersInZone(i, ZoneAttacker[i]) >= MIN_MEMBERS_TO_START_WAR) // team has enough members in the zone
{
ZoneAttackTime[i]++;
if(ZoneAttackTime[i] == TAKEOVER_TIME) // zone has been under attack for enough time and attackers take over the zone
{
GangZoneStopFlashForAll(ZoneID[i]);
ZoneInfo[i][zTeam] = ZoneAttacker[i];
GangZoneShowForAll(ZoneID[i], GetTeamZoneColor(ZoneInfo[i][zTeam])); // update the zone color for new team
ZoneAttacker[i] = -1;
}
}
else // attackers failed to take over the zone
{
GangZoneStopFlashForAll(ZoneID[i]);
ZoneAttacker[i] = -1;
}
}
else // check if somebody is attacking
{
for(new t=0; t < sizeof(Teams); t++) // loop all teams
{
if(Teams[t] != ZoneInfo[i][zTeam] && GetPlayersInZone(i, Teams[t]) >= MIN_MEMBERS_TO_START_WAR) // if there are enough enemies in the zone
{
ZoneAttacker[i] = Teams[t];
ZoneAttackTime[i] = 0;
GangZoneFlashForAll(ZoneID[i], GetTeamZoneColor(ZoneAttacker[i]));
}
}
}
}
}
Zone Attack #2
To start a war, you need to kill some enemies on enemy zone.
We will need some defines
pawn Code:
#define TAKEOVER_TIME 120 // how many seconds needed to take over the zone
#define MIN_DEATHS_TO_START_WAR 3 // how many team members must be killed in a zone to start a war
Set up a timer in OnGameModeInit or in OnFilterScriptInit if you are making a filterscript.
pawn Code:
SetTimer("ZoneTimer", 1000, true);
pawn Code:
public ZoneTimer()
{
for(new i=0; i < sizeof(ZoneInfo); i++) // loop all zones
{
if(ZoneAttacker[i] != -1) // zone is being attacked
{
if(GetPlayersInZone(i, ZoneAttacker[i]) >= 1) // there must be at least 1 attacker left
{
ZoneAttackTime[i]++;
if(ZoneAttackTime[i] == TAKEOVER_TIME) // zone has been under attack for enough time and attackers take over the zone
{
GangZoneStopFlashForAll(ZoneID[i]);
ZoneInfo[i][zTeam] = ZoneAttacker[i];
GangZoneShowForAll(ZoneID[i], GetTeamZoneColor(ZoneInfo[i][zTeam])); // update the zone color for new team
ZoneAttacker[i] = -1;
}
}
else // attackers failed to take over the zone
{
GangZoneStopFlashForAll(ZoneID[i]);
ZoneAttacker[i] = -1;
}
}
}
}
pawn Code:
if(IsPlayerConnected(killerid) && GetPlayerTeam(playerid) != GetPlayerTeam(killerid)) // not a suicide or team kill
{
new zoneid = GetPlayerZone(playerid);
if(zoneid != -1 && ZoneInfo[zoneid][zTeam] == GetPlayerTeam(playerid)) // zone member has been killed in the zone
{
ZoneDeaths[zoneid]++;
if(ZoneDeaths[zoneid] == MIN_DEATHS_TO_START_WAR)
{
ZoneDeaths[zoneid] = 0;
ZoneAttacker[zoneid] = GetPlayerTeam(killerid);
ZoneAttackTime[zoneid] = 0;
GangZoneFlashForAll(ZoneID[zoneid], GetTeamZoneColor(ZoneAttacker[zoneid]));
}
}
}
pawn Code:
new ZoneDeaths[sizeof(ZoneInfo)];
pawn Code:
stock GetPlayerZone(playerid)
{
for(new i=0; i < sizeof(ZoneInfo); i++)
{
if(IsPlayerInZone(playerid, i))
{
return i;
}
}
return -1;
}
Notes
I'm using GetPlayerTeam to check player team. If you define your teams in some other way (gTeam[playerid] for example), just replace it with your define.
The End
This is the end of the tutorial. If you have any questions or recommendations, feel free to post them here