23.11.2013, 16:30
(
Последний раз редактировалось kN1GhT; 26.11.2013 в 08:23.
)
Advanced Capturable Zone Scripting [Easy,Very Fast,Efficient,Variable Time TO Capture For DONOR , More STOCKS ,Foreach]
Hello SAMP
In The Following Tutorial I Would Be Trying To Teach You How To Create Capture Zones
This Tutorial would be helpfull For TDM GM's
Some FAQ's
So Whats New and Unique About Your Tutorial.?
Well This Tutorial Would Allow You To Create Capture Zones Which Have Different Time For Capturing For Different Players According to The Privledges Available to Them(The Donations They MAKE)
Also This Kind OF Capturable Zones Are Faster , Logical and Easy To Make.
With the use of Foreach i would also unish the team who has Failed to save the Capture Zone from being Captured and rewarding the team who did it. :P
Why Do I See That You Keep Stocking All The Stuff.R U Retarded?
You Would See That I Stock Most Of The Things Like SetGangZoneColor ...This May Seem Useless To You If You Are Just Making Only 1 Capture Zone . But It IS Really Efficient For More Zones.
Why Shall You USe This Method?
You Can Use The Logic to Create More Capture Zones With Less Than 10 Extra Lines!!.
How DaHell Did U Add Public CallBacks On Your Own?
The Only CallBack i Made For This is
This Would Be Called When A Player IS Checked Of The
CallBack.
Ok Lets Start
You Would Need The foreach Include and the streamer Include & Plugin
First You Would Need To Call the the includes That You Are Using
Now Write Down The Following Color Defines
These Would Be The Colours We Are Going To Use In The Script
The Time Needed To Capture a Certain Zone For Different Players Depending on the privledges They Have
Lets Define The Teams Available
And Some More DEclarations
Lets Declare the Properties of the Zones
Now Lets Declare Some Enums About The Zone And Some About The Players
We Now Move On To The CallBack public OnGameModeInit() which is called when The Script is Completed and loaded
We Now Set The Properties of the Zones We Have Declared Above
We Need To Make the Zone Visible to Players
So We USe public OnPlayerConnect CallBack For IT
Now Lets Keep OurSelf Updated And Stock The Information About The Player , The Color of the Zone , and many Other Things
Now We use A CallBack which would be called when the player enters the checkpoint using The Streamer Plugin
Inside This We Do The Following
We Check For Conditions
Remember This is Under the condition if(checkpointid == ACP)
Wether The Player is in a vehicle
Wether The Player Is ON Admin Duty(To BE SET )
if None of the conditions are satisfied We Begin Our Code
Checks IF The Player Is a Donor and Correspondingly Sets The TIME For Capture
Notifying TO The Whole Server That The Zone is Being Taken Over and Prepares The Counting OF Seconds to Capture
Here PlayerCountTime Is Another CallBack Which Would Be Called From This.
So Together This Would Look Like
pff That was Some Real Work
But WE Still need to Count The Seconds
So Lets Start
WE DECLARE our CallBack
Now Lets Start Work
WE Count the Time And Display it to the Player as a GameText
We Are using the PlayerCount From The Previous CallBack
Now Once The Player Has Finished the Ammount of time required to Capture The PlayerCount Becomes 0
we use it to Stop Flashing the GangZone and other things
Now We Tell Everyone that the zone is captued and reward the player who captured the zone
punishment to for the Team Who Failed to save its Capture Zone From Being Captured and reward for the team which captured it
Last Thing here
Kill The Timer and Update the owner of the GangZone
Done And The Whole Callback Would look Like
Now We Deal When The Player Leaves The Zone]
Using Simple Logic
When A Player Enters and leaves a zone already owned By His TEAM WE Do Nothing
Now IF This is not the case
WE Would Kill The Timer adn send message that the person has failed to capture the zone
The Call BAck Would Look Like This When Done
What NExt ..we need to stop the Timer And Stop the zone from being captured if a player disconnects or Dies In The Process
WE DO THE Following
Questions And Answers
Q:I want to do more than One Zone.How do i do it?
A:This is Simple Just Follow the 7 Steps
Given with Example
1-u need to declare the properties of the Zones(read above) ,
2-Define them in the callback OnGamemodeInit ,
3-Set The Colour of the Gangzone OnPlayerConnect(as done for mine)
4-Add to The Stock PlayerArea(playerid)
Eg:
5- Add to stock ZoneName
EG:
6-Stock SetZoneColor
Eg:
7-Edit The PublicOnPlayerEnterDynamicCP and add a or condition
eg:
And DONE
Q:I Have More Than One Team in my script . How do i Do it Now?
Aefine a Colour
AND
Just Edit The stock PlayerGangColor(playerid)
eg :
Credits
Incognto [for streamer]
The Maker OF Foreach Include
SA-MP Team
Thank You.
Hope I HElped
Hello SAMP
In The Following Tutorial I Would Be Trying To Teach You How To Create Capture Zones
This Tutorial would be helpfull For TDM GM's
Some FAQ's
So Whats New and Unique About Your Tutorial.?
Well This Tutorial Would Allow You To Create Capture Zones Which Have Different Time For Capturing For Different Players According to The Privledges Available to Them(The Donations They MAKE)
Also This Kind OF Capturable Zones Are Faster , Logical and Easy To Make.
With the use of Foreach i would also unish the team who has Failed to save the Capture Zone from being Captured and rewarding the team who did it. :P
Why Do I See That You Keep Stocking All The Stuff.R U Retarded?
You Would See That I Stock Most Of The Things Like SetGangZoneColor ...This May Seem Useless To You If You Are Just Making Only 1 Capture Zone . But It IS Really Efficient For More Zones.
Why Shall You USe This Method?
You Can Use The Logic to Create More Capture Zones With Less Than 10 Extra Lines!!.
How DaHell Did U Add Public CallBacks On Your Own?
The Only CallBack i Made For This is
Код:
forward GangCount(playerid, checkpointid, zonename); public GangCount(playerid, checkpointid, zonename)
Код:
public OnPlayerEnterDynamicCP
Ok Lets Start
You Would Need The foreach Include and the streamer Include & Plugin
First You Would Need To Call the the includes That You Are Using
Код:
#include <a_samp> #include <foreach> #include <streamer>
These Would Be The Colours We Are Going To Use In The Script
Код:
#define LIGHTBLUE 0x33CCFFFF #define RED 0xFF0000FF #define WHITE 0xFFFFFFFF #define LIGHTGREEN 0x33FF33FF #define WHITE_ZONE_COLOR 0xFFFFFF77 #define GREEN_ZONE_COLOR 0x15FF0077 #define GREY 0xAFAFAFFF
Код:
#define NoDonorRankHolder 25 //for Regular Players #define Donor1CaptureTime 20 // For Gold VIP(dRank 3) #define Donor2CaptureTime 15 //For Silver VIP(dRank 2) #define Donor3CaptureTime 10 //For Bronze VIP(dRank 1)
Код:
#define T_1 100 #define T_2 101
Код:
new OnDuty[MAX_PLAYERS];//To BE USed When an admin goes On Duty... new PlayerCount[MAX_PLAYERS]; new PlayerCountTimer[MAX_PLAYERS]; new gTeam[MAX_PLAYERS]; //I Recomemd You To Set This During OnPlayerRequestClass
Код:
new AZone; new AArea; new ACP; new AColor;
Код:
//Enums enum CaptureInfo { gAttacked = 0, gOwner = 0, } new CaptureZoneInfo[][CaptureInfo]; enum PlayerData { pCaptureZone, drank } new PlayerInfo[MAX_PLAYERS][PlayerData];
We Now Set The Properties of the Zones We Have Declared Above
Код:
{ AZone = GangZoneCreate(-366, 1512, -270, 1578); AArea = CreateDynamicRectangle(-366, 1512, -270, 1578, -1, -1, -1); ACP = CreateDynamicCP(-308.9923,1537.8146,75.5625, 3.0, -1, -1, -1, 100.0); AColor = GREY; return 1; }
We Need To Make the Zone Visible to Players
So We USe public OnPlayerConnect CallBack For IT
Код:
{ GangZoneShowForPlayer(playerid, AZone, AColor); return 1; }
Код:
stock PlayerArea(playerid) { new pZone; if(IsPlayerInDynamicArea(playerid, AArea)) { GangZoneFlashForAll(AZone, PlayerGangColor(playerid)); pZone = AZone; } return pZone; }
Код:
//Which Team Color to FLASH? This Stock Helps stock PlayerGangColor(playerid) { new str; if (gTeam[playerid] == T_1) str =(WHITE_ZONE_COLOR); else if(gTeam[playerid] == T_2) str =(GREEN_ZONE_COLOR); return str; }
Код:
//Lets Stock The Names OF The ZONE stock ZoneName(checkpointid) { new str[32]; if (checkpointid == ACP) str = ("A Trial Zone"); return str; }
Код:
//The Color To BE Set stock SetZoneColor(zonename, playerid) { if(zonename == AZone) { AColor = PlayerGangColor(playerid); } }
Now We Are Ready To Start The Real Scripting Work
Now We use A CallBack which would be called when the player enters the checkpoint using The Streamer Plugin
Код:
forward OnPlayerEnterDynamicCP(playerid, checkpointid); public OnPlayerEnterDynamicCP(playerid, checkpointid)
We Check For Conditions
Remember This is Under the condition if(checkpointid == ACP)
Wether The Player is in a vehicle
Wether The Player Is ON Admin Duty(To BE SET )
if None of the conditions are satisfied We Begin Our Code
Checks IF The Player Is a Donor and Correspondingly Sets The TIME For Capture
Notifying TO The Whole Server That The Zone is Being Taken Over and Prepares The Counting OF Seconds to Capture
Here PlayerCountTime Is Another CallBack Which Would Be Called From This.
So Together This Would Look Like
Код:
forward OnPlayerEnterDynamicCP(playerid, checkpointid); public OnPlayerEnterDynamicCP(playerid, checkpointid) if(checkpointid == ACP) { //Messages InCase The Player Is Not Allowed To Capture new string[128], pZone; [COLOR="rgb(46, 139, 87)"]//If The ZONE is Already Getting Captured[/COLOR] if(CaptureZoneInfo[checkpointid][gAttacked] == 1) return SendClientMessage(playerid, RED, "The zone is being captured!"); //If The Zone Has Been Already Captured By That Team if(CaptureZoneInfo[checkpointid][gOwner] == gTeam[playerid]) return SendClientMessage(playerid, LIGHTBLUE, "Your team owns this zone."); [COLOR="rgb(46, 139, 87)"] //Wether The Player is in a vehicle[/COLOR] if(IsPlayerInAnyVehicle(playerid)) return SendClientMessage(playerid, RED, "You cant capture while in a vehicle!"); [COLOR="rgb(46, 139, 87)"] //Wether The Player Is ON Duty(To BE SET)[/COLOR] if(OnDuty[playerid] == 1) return SendClientMessage(playerid, RED, "You cant capture when on duty!"); CaptureZoneInfo[checkpointid][gAttacked] = 1; pZone = PlayerArea(playerid); PlayerInfo[playerid][pCaptureZone] = 1; [COLOR="rgb(46, 139, 87)"] //Checks IF The Player Is a Donor and Correspondingly Sets The TIME For Capture[/COLOR] if(PlayerInfo[playerid][drank] == 1) { PlayerCount[playerid] = Donor1CaptureTime; } else if(PlayerInfo[playerid][drank] == 2) { PlayerCount[playerid] = Donor2CaptureTime; } else if(PlayerInfo[playerid][drank] == 3) { PlayerCount[playerid] = Donor3CaptureTime; } else { PlayerCount[playerid] = NoDonorRankHolder; } [COLOR="rgb(46, 139, 87)"]//Notifying TO The Whole Server That The Zone is Being Taken Over and Prepares The Counting OF [/COLOR]Seconds to Capture PlayerCountTimer[playerid] = SetTimerEx("GangCount", 1000, true, "iii", playerid, checkpointid, pZone); format(string, sizeof(string), "[ZONE] %s is being taken over!", ZoneName(checkpointid)); SendClientMessageToAll(LIGHTGREEN, string); } return 1; }
pff That was Some Real Work
But WE Still need to Count The Seconds
So Lets Start
WE DECLARE our CallBack
Now Lets Start Work
WE Count the Time And Display it to the Player as a GameText
We Are using the PlayerCount From The Previous CallBack
Now Once The Player Has Finished the Ammount of time required to Capture The PlayerCount Becomes 0
we use it to Stop Flashing the GangZone and other things
Now We Tell Everyone that the zone is captued and reward the player who captured the zone
punishment to for the Team Who Failed to save its Capture Zone From Being Captured and reward for the team which captured it
Last Thing here
Kill The Timer and Update the owner of the GangZone
Done And The Whole Callback Would look Like
Код:
forward GangCount(playerid, checkpointid, zonename); public GangCount(playerid, checkpointid, zonename) { new time[16]; PlayerCount[playerid] --; format(time, sizeof(time), "~g~%i..", PlayerCount[playerid]); GameTextForPlayer(playerid, time, 1100, 3); if(PlayerCount[playerid] == 0) { CaptureZoneInfo[checkpointid][gAttacked] = 0; GangZoneStopFlashForAll(zonename); GangZoneShowForAll(zonename, PlayerGangColor(playerid)); SetZoneColor(zonename, playerid); //rewards new string[128], Float:armour; format(string, sizeof(string), "You get {FFFF00}+3 score, +20 armor and $2500{FFFFFF} for capturing zone {15FF00}%s!", ZoneName(checkpointid)); SendClientMessage(playerid, WHITE, string); //Cant Give More Than 99 Armour Hence Check IT GetPlayerArmour(playerid, armour); if(armour+20.0 > 99) SetPlayerArmour(playerid, 99); else SetPlayerArmour(playerid, armour+20.0); GivePlayerMoney(playerid, 5000); SetPlayerScore(playerid, GetPlayerScore(playerid)+3); PlayerInfo[playerid][pCaptureZone] = 0; foreach(Player, i) { if(CaptureZoneInfo[checkpointid][gOwner] == gTeam[i]) { format(string, sizeof(string), "Your team has lost the zone {FF0000}%s{FFFFFF}, you lose {FF0000}-1{FFFFFF} score!", ZoneName(checkpointid)); SetPlayerScore(i, GetPlayerScore(i)-1); SendClientMessage(i, WHITE, string); } else if(gTeam[i] == gTeam[playerid]) { if(i != playerid) { format(string, sizeof(string), "Your team has captured the zone {15FF00}%s{FFFFFF}, you get {15FF00}+1{FFFFFF} score!", ZoneName(checkpointid)); SetPlayerScore(i, GetPlayerScore(i)+1); SendClientMessage(i, WHITE, string); } } } KillTimer(PlayerCountTimer[playerid]); CaptureZoneInfo[checkpointid][gOwner] = gTeam[playerid]; } return 1; }
Using Simple Logic
When A Player Enters and leaves a zone already owned By His TEAM WE Do Nothing
Now IF This is not the case
WE Would Kill The Timer adn send message that the person has failed to capture the zone
The Call BAck Would Look Like This When Done
Код:
forward OnPlayerLeaveDynamicCP(playerid, checkpointid); public OnPlayerLeaveDynamicCP(playerid, checkpointid) { if(PlayerInfo[playerid][pCaptureZone] == 1) { if(CaptureZoneInfo[checkpointid][gOwner] == gTeam[playerid]) return 0; new pZone; CaptureZoneInfo[checkpointid][gAttacked] = 0; pZone = PlayerArea(playerid); GangZoneStopFlashForAll(pZone); SendClientMessage(playerid, RED, "You stopped capturing the zone!"); KillTimer(PlayerCountTimer[playerid]); PlayerInfo[playerid][pCaptureZone] = 0; } return 1; }
WE DO THE Following
Код:
public OnPlayerDeath(playerid, killerid, reason) { { SendClientMessageToAll(playerid, RED, "[Zone] was Not Captured Since The Played Died While Capturing It!"); KillTimer(PlayerCountTimer[playerid]); PlayerInfo[playerid][pCaptureZone] = 0; } return 1; } public OnPlayerDisconnect(playerid, reason) { { SendClientMessageToAll(playerid, RED, "[Zone] Was Not Captured Since The Player Left The Server"); KillTimer(PlayerCountTimer[playerid]); PlayerInfo[playerid][pCaptureZone] = 0; } return 1; }
Questions And Answers
Q:I want to do more than One Zone.How do i do it?
A:This is Simple Just Follow the 7 Steps
Given with Example
1-u need to declare the properties of the Zones(read above) ,
2-Define them in the callback OnGamemodeInit ,
3-Set The Colour of the Gangzone OnPlayerConnect(as done for mine)
4-Add to The Stock PlayerArea(playerid)
Eg:
Код:
stock PlayerArea(playerid) { new pZone; if(IsPlayerInDynamicArea(playerid, AArea)) { GangZoneFlashForAll(AZone, PlayerGangColor(playerid)); pZone = AZone; } if(IsPlayerInDynamicArea(playerid, AnotherCaptureArea)) { GangZoneFlashForAll(AnotherCaptureZone, PlayerGangColor(playerid)); pZone = AnotherCaptureZone; } return pZone; }
EG:
Код:
stock ZoneName(checkpointid) { new str[32]; if (checkpointid == ACP) str = ("A Trial Zone"); if (checkpointid == AnotherCaptureCP) str = ("second Trial Zone"); return str; }
Eg:
Код:
stock SetZoneColor(zonename, playerid) { if(zonename == AZone) { AColor = PlayerGangColor(playerid); } if(zonename == AnotherCaptureZone) { AnotherCaptureColor = PlayerGangColor(playerid); } }
eg:
Код:
public OnPlayerEnterDynamicCP(playerid, checkpointid) { if(checkpointid == ACP || checkpointid == AnotherCaptureCP )
Q:I Have More Than One Team in my script . How do i Do it Now?
Aefine a Colour
AND
Just Edit The stock PlayerGangColor(playerid)
eg :
Код:
stock PlayerGangColor(playerid) { new str; if (gTeam[playerid] == T_1) str =(WHITE_ZONE_COLOR); else if(gTeam[playerid] == T_2) str =(GREEN_ZONE_COLOR); else if(gTeam[playerid] == T_3) str =(Orange_ZONE_COLOR); return str; }
Incognto [for streamer]
The Maker OF Foreach Include
SA-MP Team
Thank You.
Hope I HElped