From e5190f9ddff51a2e246a7af5538909ec212e00db Mon Sep 17 00:00:00 2001 From: mekolat Date: Sun, 7 Sep 2014 15:44:33 -0400 Subject: add fight club --- world/map/npc/009-7/core.txt | 438 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 438 insertions(+) create mode 100644 world/map/npc/009-7/core.txt (limited to 'world/map/npc/009-7/core.txt') diff --git a/world/map/npc/009-7/core.txt b/world/map/npc/009-7/core.txt new file mode 100644 index 00000000..18487a50 --- /dev/null +++ b/world/map/npc/009-7/core.txt @@ -0,0 +1,438 @@ +// this file contains the game logic of the fight club + +function|script|fightclub_sendrequest|, +{ + set @loop, 0; + goto L_Loop; + + L_Loop: + if(@Duel_Queue$[@loop] == @caster_name$) goto L_Exists; + if(@Duel_Queue$[@loop] == "") goto L_Proceed; + set @loop, (@loop + 1); + if(@loop >= getarraysize(@Duel_Queue)) goto L_Full; // this shouldn't happen since we check in magic but we still handle it + goto L_Loop; + + L_Full: + message @caster_name$, "There is already "+ $@Duel_PlayerQueueLimit +" duel request(s) in the queue of this player, which is the maximum."; + return; + + L_Exists: + message @caster_name$, "You already requested a duel with this player."; + return; + + L_Proceed: + misceffect FX_MAGIC_DARKRED, @caster_name$; + message @caster_name$, "Your request has been sent."; + set @Duel_Queue$[@loop], @caster_name$; + if(@Duel_Fighter == 0) message strcharinfo(0), "You have received a new duel request. Talk to Rouge to accept or decline."; + if(@Duel_Fighter == 0) misceffect FX_MAGIC_DARKRED, strcharinfo(0); + if(@Duel_Fighter == 1) set @Duel_HasPendingRequest, 1; + return; +} + +function|script|fightclub_getrules|, +{ + set $@fightclub_myself, getcharid(3); + if(@target < 1) goto L_Proceed; // get our own rules + if(attachrid(@target) == 1) goto L_Proceed; + goto L_Missing; + + L_Proceed: + set $@Temp_NoMagic, Duel_NoMagic; + if($@fightclub_myself == getcharid(3)) goto L_Proceed2; // the target is ourselves + if(attachrid($@fightclub_myself) == 1) goto L_Proceed2; + goto L_Missing; + + L_Missing: + end; + + L_Proceed2: + set $@fightclub_myself, 0; + set @target, 0; + if($@Temp_NoMagic != 1) + mes "(no rules)"; + if($@Temp_NoMagic == 1) mes "- No Magic"; + set $@Temp_NoMagic, 0; // now we clean these vars ASAP because they're globals + return; +} + +function|script|fightclub_AddToQueue|, // ** called when someone agree to duel +{ + set @Duel_Loop, 0; + goto L_Loop; + + L_Loop: + if(($@Duel_Queue_Blue$[@Duel_Loop] == @caster_name$) && ($@Duel_Queue_Red$[@Duel_Loop] == @target_name$)) goto L_Exists; + if(($@Duel_Queue_Red$[@Duel_Loop] == @caster_name$) && ($@Duel_Queue_Blue$[@Duel_Loop] == @target_name$)) goto L_Exists; + set @Duel_Loop, (@Duel_Loop + 1); + if(@Duel_Loop >= getarraysize($@Duel_Queue_ID)) goto L_Proceed; + goto L_Loop; + + L_Exists: + mes "This battle is already in the queue."; + close; + + L_Full: + mes "There is already " + $@Duel_QueueLimit + " battles in the queue, which is the maximum. Please try again later."; + close; + + L_Proceed: + if(getarraysize($@Duel_Queue_ID) >= ($@Duel_QueueLimit + 1)) goto L_Full; + set @index, getarraysize($@Duel_Queue_ID); + if(@index >= 1) goto L_Proceed2; + set @index, 1; + goto L_Proceed2; + + L_Proceed2: + if($@Duel_Queue_Red$[@index] != "") goto L_NotClean; + set $@Duel_Queue_Red$[@index], @caster_name$; + if($@Duel_Queue_Blue$[@index] != "") goto L_NotClean; + set $@Duel_Queue_Blue$[@index], @target_name$; + if($@Duel_Queue_ID[@index] != 0) goto L_NotClean; + set $@Duel_Queue_ID[@index], ($@Duel_Queue_ID[(@index - 1)] + 1); + if($@Duel_Queue_ID[@index] <= $Duel_LastDuel) goto L_FixId; + if($@Duel_CurrentDuel < 1) goto L_Request; + return; + + L_NotClean: + message @caster_name$, "An error occured: array element not empty. Try again in 5 seconds."; + return; + + L_FixId: + set $@Duel_Queue_ID[@index], ($Duel_LastDuel + 1); + if($@Duel_CurrentDuel < 1) goto L_Request; + return; + + L_Request: + callfunc "fightclub_NextBattle"; + return; +} + +function|script|fightclub_NextBattle|, // ** called when a duel is finished +{ + set $@Duel_Queue_Blue$[0], ""; // clean the 0 index + set $@Duel_Queue_Red$[0], ""; + set $@Duel_Queue_ID[0], 0; + set $@Duel_Loop, 1; // start the loop at 1 + goto L_Loop; + + L_Loop: // here we shift the array to the left + if($@Duel_Queue_ID[$@Duel_Loop] < 1) goto L_Empty; + set $@Duel_Queue_Red$[($@Duel_Loop - 1)], $@Duel_Queue_Red$[$@Duel_Loop]; + set $@Duel_Queue_Red$[$@Duel_Loop], ""; // it is always important to clean + set $@Duel_Queue_Blue$[($@Duel_Loop - 1)], $@Duel_Queue_Blue$[$@Duel_Loop]; + set $@Duel_Queue_Blue$[$@Duel_Loop], ""; + set $@Duel_Queue_ID[($@Duel_Loop - 1)], $@Duel_Queue_ID[$@Duel_Loop]; + set $@Duel_Queue_ID[$@Duel_Loop], 0; + set $@Duel_Loop, ($@Duel_Loop + 1); + if($@Duel_Loop >= getarraysize($@Duel_Queue_ID)) goto L_Proceed; + goto L_Loop; + + L_Empty: + // the queue is now empty + return; + + L_Proceed: + callfunc "fightclub_CleanStage"; + set $@Duel_CurrentDuel, $@Duel_Queue_ID[0]; // since the array is shifted, the index is always 0 + set $Duel_LastDuel, $@Duel_Queue_ID[0]; // this is used to keep the same index across reboots + set $@Duel_BluePlayer, getcharid(3,$@Duel_Queue_Blue$[0]); + set $@Duel_RedPlayer, getcharid(3,$@Duel_Queue_Red$[0]); + if(attachrid($@Duel_BluePlayer) != 1) goto L_Missing; + if(attachrid($@Duel_RedPlayer) == 1) goto L_Proceed2; + goto L_Missing; + + L_Missing: + callfunc "fightclub_CleanStage"; + callfunc "fightclub_NextBattle"; + return; + + L_Proceed2: + addtimer ($@Duel_TimeBeforeNext * 1000), "#FightClub#utils::OnDelayedNextBattle"; + return; +} + +function|script|fightclub_NextBattleProceed|, // ** called after the delay +{ + set $@Duel_NoMagic, Duel_NoMagic; // get the rules of the caster + donpcevent "Rouge#Duels::OnAnnounceNext"; + set $@Duel_Started, 0; + addtimer ($@Duel_TimeBeforeWarp * 1000), "#FightClub#utils::OnDelayedStart"; + return; +} + +function|script|fightclub_StartBattle|, +{ + set $@Duel_Started, 1; + npcwarp 40, 45, "Rouge#Duels"; + donpcevent "#FightClub#TimeLimit::OnStartTimer"; + if(attachrid($@Duel_RedPlayer) != 1) goto L_Missing; + callfunc "fightclub_enter"; + if(attachrid($@Duel_BluePlayer) != 1) goto L_Missing; + callfunc "fightclub_enter"; + return; + + L_Missing: + callfunc "fightclub_CleanStage"; + callfunc "fightclub_NextBattle"; + return; +} + +function|script|fightclub_TimeOut|, +{ + debugmes "on time out"; + donpcevent "Rouge#Duels::OnAnnounceTimeOut"; + if(attachrid($@Duel_RedPlayer) != 1) goto L_Missing; + callfunc "fightclub_exit"; + if(attachrid($@Duel_BluePlayer) != 1) goto L_Missing; + callfunc "fightclub_exit"; + callfunc "fightclub_CleanStage"; + callfunc "fightclub_NextBattle"; + return; + + L_Missing: + callfunc "fightclub_CleanStage"; + callfunc "fightclub_NextBattle"; + return; +} + +function|script|fightclub_Intrusion|, // ** called when someone uninvited is on stage +{ + // nothing to do here (yet) + return; +} + +function|script|fightclub_EmergencyWipe|, +{ + callfunc "fightclub_CleanStage"; + callfunc "fightclub_StartUp"; + // TODO: check if everything is clean (function) and mapexit otherwise + return; +} + +function|script|fightclub_Victory|, // ** called whenever someone wins (to handle rewards and bids) +{ + // TODO: give some sort of reward + // TODO: increase score + // TODO: update leaderboard + return; +} + +function|script|fightclub_DestroyMe|, // ** called when the player needs to be reset +{ + callfunc "fightclub_exit"; + percentheal -100, 0; // dying removes @killable, @killer or any temp buff + return; +} + +function|script|fightclub_Missing|, // ** called when the red or blue player disappears from stage +{ + // $@Duel_Missing 1 = red, 2 = blue + if (attachrid($@Duel_BluePlayer) == 1) goto L_Proceed; // we need to attach to at least one player + if (attachrid($@Duel_RedPlayer) == 1) goto L_Proceed; + goto L_Resume; // can't attach either of them (this is not a problem since it means they are offline so their vars are clean anyway) + + L_Proceed: + if($@Duel_Missing == 1) goto L_BlueWins; + goto L_RedWins; + + L_BlueWins: + donpcevent "Rouge#Duels::OnAnnounceBlueForfeit"; + set $@duel_winner, $@Duel_BluePlayer; + callfunc "fightclub_Victory"; + goto L_Clean; + + L_RedWins: + donpcevent "Rouge#Duels::OnAnnounceRedForfeit"; + set $@duel_winner, $@Duel_RedPlayer; + callfunc "fightclub_Victory"; + goto L_Clean; + + L_KillBlue: + callfunc "fightclub_exit"; + if(attachrid($@Duel_RedPlayer) == 1) goto L_KillRed; + goto L_Resume; + + L_KillRed: + callfunc "fightclub_exit"; + goto L_Resume; + + L_Clean: + if(attachrid($@Duel_BluePlayer) == 1) goto L_KillBlue; + if(attachrid($@Duel_RedPlayer) == 1) goto L_KillRed; + goto L_Resume; // couldn't kill them + + L_Resume: + callfunc "fightclub_CleanStage"; + callfunc "fightclub_NextBattle"; + return; +} + +function|script|fightclub_StartUp|, // ** called after the server boots up +{ + if($fightclub_enabled < 1) set $fightclub_enabled, 1; // init the (permanent) enabled global (this will only be done once, when the duel system is merged with master) + if($@Duel_TimeBeforeNext < 1) set $@Duel_TimeBeforeNext, 5; // init the (temporary) TimeBeforeNext global + if($@Duel_TimeBeforeWarp < 1) set $@Duel_TimeBeforeWarp, 5; // init the (temporary) TimeBeforeWarp global + if($@Duel_TimeBeforeStart < 1) set $@Duel_TimeBeforeStart, 3; // init the (temporary) TimeBeforeStart global + if($@Duel_TimeLimit < 1) set $@Duel_TimeLimit, 120; // init the (temporary) TimeLimit global + if($@Duel_QueueLimit < 1) set $@Duel_QueueLimit, 5; // init the (temporary) QueueLimit global + if($@Duel_PlayerQueueLimit < 1) set $@Duel_PlayerQueueLimit, 2; // init the (temporary) PlayerQueueLimit global + if($@fightclub_password$ == "") set $@fightclub_password$, "Banana"; // init the (temporary) fightclub_password global + setarray $@Duel_Queue_ID, 0; + cleararray $@Duel_Queue_ID, 0, ($@Duel_QueueLimit + 1); + setarray $@Duel_Queue_Blue$, ""; + cleararray $@Duel_Queue_Blue$, "", ($@Duel_QueueLimit + 1); + setarray $@Duel_Queue_Red$, ""; + cleararray $@Duel_Queue_Red$, "", ($@Duel_QueueLimit + 1); + set $@Duel_TotalTime, 0; + return; +} + +function|script|fightclub_CleanStage|, // ** called before and after each duel to wipe the vars +{ + if($@Duel_NoWarp != 1) areawarp "009-7.gat", $@fightclub_x1, $@fightclub_y1, $@fightclub_x2, $@fightclub_y2, "009-7.gat", 31, 40; // kick all players from stage + set $@Duel_NoWarp, 0; + set $@Duel_NoMagic, 0; // clean the Duel parameters + set $@Duel_CurrentDuel, 0; // no duel atm + set $@Duel_Started, 0; // no duel atm + set $@Duel_RedPlayer, 0; + set $@Duel_BluePlayer, 0; + set $@Duel_Missing, 0; + set $@Duel_TotalTime, 0; + npcwarp 32, 45, "Rouge#Duels"; + donpcevent "#FightClub#TimeLimit::OnStopTimer"; + killmonster "009-7.gat", "All"; + return; +} + +function|script|fightclub_setrules|, // ** called by npc; allows the player to change their custom rules +{ + goto L_Main; + + L_Main: + mes "Your rules are the following: "; mes ""; + callfunc "fightclub_getrules"; + mes ""; mes "What do you want to do?"; + menu + "Change my rules.", L_Start, + "Nevermind.", L_Return; + + L_Start: + set Duel_NoMagic, 1; // set the rule to 1 to enable it + goto L_NoMagic; + + L_NoMagic: + if(Duel_NoMagic != 1) goto L_Done; + mes "Do you want to allow magic?"; + mes "If disabled, the fighters will not be able to use any kind of spell."; + menu + "Yes.", L_NoMagicYes, + "No.", L_Done; + L_NoMagicYes: + set Duel_NoMagic, 0; + goto L_Done; + + L_Done: + next; + mes "You have succesfully changed your options."; + goto L_Main; + + L_Return: + return; +} + +function|script|fightclub_death|, // ** called by event handler whenever someone dies +{ + if(@Duel_Fighter != 1) goto L_NoDuel; + if(@killerrid != 0) goto L_Murdered; + goto L_Killed; + + L_Killed: + if(getcharid(3) == $@Duel_RedPlayer) goto L_BlueWins; + goto L_RedWins; + + L_RedWins: + donpcevent "Rouge#Duels::OnAnnounceRedWins"; + set $@duel_winner, $@Duel_RedPlayer; + callfunc "fightclub_Victory"; + callfunc "fightclub_exit"; + if(attachrid($@Duel_RedPlayer) == 1) goto L_RedWins2; + goto L_Missing; + + L_RedWins2: + callfunc "fightclub_exit"; + goto L_Proceed; + + L_BlueWins: + donpcevent "Rouge#Duels::OnAnnounceBlueWins"; + set $@duel_winner, $@Duel_BluePlayer; + callfunc "fightclub_Victory"; + callfunc "fightclub_exit"; + if(attachrid($@Duel_BluePlayer) == 1) goto L_BlueWins2; + goto L_Missing; + + L_Missing: + callfunc "fightclub_CleanStage"; + callfunc "fightclub_NextBattle"; + return; + + L_BlueWins2: + callfunc "fightclub_exit"; + goto L_Proceed; + + L_Proceed: + callfunc "fightclub_CleanStage"; + callfunc "fightclub_NextBattle"; + return; + + L_Murdered: + if(($@Duel_RedPlayer != @killerrid) && ($@Duel_BluePlayer != @killerrid)) goto L_Stranger; + goto L_Killed; // now we proceed the same way as L_Killed + + L_Stranger: + // the victim was not murdered by its adversary (wtf) + if(debug) donpcevent "Debug#Duels::OnKillerNotInDuel"; + callfunc "fightclub_EmergencyWipe"; + end; + + L_NoDuel: + if(debug) donpcevent "Debug#Duels::OnVictimNotInDuel"; + end; +} + +function|script|fightclub_enter|, // ** called every time a player enters the ring +{ + set @Duel_Fighter, 1; + warp "009-7.gat", rand($@fightclub_x1,$@fightclub_x2), rand($@fightclub_y1,$@fightclub_y2); + gmcommand "@alive"; // ensure that you can't duel wih a corpse + message strcharinfo(0), "Get Ready."; + addtimer ($@Duel_TimeBeforeStart * 1000), "#FightClub#utils::OnBecomeKiller"; // call fightclub_enter_killer in 3 seconds + return; +} + +function|script|fightclub_enter_killer|, // ** called 3 seconds after a player enters the ring +{ + gmcommand "@killable"; + gmcommand "@killer"; // add both killable and killer so if one doesn't kick in, the other (hopefully) will + set @killer, 1; + message strcharinfo(0), "GO !"; + return; +} + +function|script|fightclub_exit|, // ** called every time a player exits the ring +{ + set @Duel_Fighter, 0; + if(getmap() == "009-7") warp "009-7.gat", 31, 40; // do not warp if player left the room + if(@killer != 1) goto L_Clean; + gmcommand "@killable"; + gmcommand "@killer"; + goto L_Clean; + + L_Clean: + set @killer, 0; // the player no longer have @killer + gmcommand "@alive"; // refill hp/mana + sc_end 132; sc_end 14; sc_end 37; sc_end 185; // remove effects + message strcharinfo(0), "Thank you for participating in the fight club!"; + if(@Duel_HasPendingRequest) message strcharinfo(0), "You have received a new duel request."; + return; +} -- cgit v1.2.3-60-g2f50