diff options
Diffstat (limited to 'world/map/npc')
-rw-r--r-- | world/map/npc/001-3/guards.txt | 8 | ||||
-rw-r--r-- | world/map/npc/001-3/mapflags.txt | 3 | ||||
-rw-r--r-- | world/map/npc/009-5/mapflags.txt | 1 | ||||
-rw-r--r-- | world/map/npc/009-6/brodomir.txt | 7 | ||||
-rw-r--r-- | world/map/npc/009-6/mapflags.txt | 1 | ||||
-rw-r--r-- | world/map/npc/009-7/_import.txt | 12 | ||||
-rw-r--r-- | world/map/npc/009-7/_mobs.txt | 9 | ||||
-rw-r--r-- | world/map/npc/009-7/_warps.txt | 4 | ||||
-rw-r--r-- | world/map/npc/009-7/battlemaster.txt | 128 | ||||
-rw-r--r-- | world/map/npc/009-7/core.txt | 438 | ||||
-rw-r--r-- | world/map/npc/009-7/debug.txt | 151 | ||||
-rw-r--r-- | world/map/npc/009-7/eventHandler.txt | 156 | ||||
-rw-r--r-- | world/map/npc/009-7/mapflags.txt | 4 | ||||
-rw-r--r-- | world/map/npc/009-7/npcs.txt | 20 | ||||
-rw-r--r-- | world/map/npc/009-7/rouge.txt | 112 | ||||
-rw-r--r-- | world/map/npc/_import.txt | 1 | ||||
-rw-r--r-- | world/map/npc/items/check_wand.txt | 4 |
17 files changed, 1052 insertions, 7 deletions
diff --git a/world/map/npc/001-3/guards.txt b/world/map/npc/001-3/guards.txt index 699d46ba..7b18f252 100644 --- a/world/map/npc/001-3/guards.txt +++ b/world/map/npc/001-3/guards.txt @@ -1,5 +1,3 @@ -// - 001-3.gat,77,37,0|script|Phaet#arena|125, { mes "[Phaet the Royal Guard]"; @@ -17,8 +15,14 @@ L_Sure: mes "[Phaet the Royal Guard]"; mes "\"Ok.\""; next; + if(Duel_PVP == 1) goto L_FightClub; warp "001-2.gat", 25, 23; close; + +L_FightClub: + set Duel_PVP, 0; + warp "009-7.gat", 39, 37; + close; } 001-3.gat,69,37,0|script|Aradin|126, diff --git a/world/map/npc/001-3/mapflags.txt b/world/map/npc/001-3/mapflags.txt index 9d9d2fe2..75eb45d1 100644 --- a/world/map/npc/001-3/mapflags.txt +++ b/world/map/npc/001-3/mapflags.txt @@ -1,2 +1 @@ -001-3.gat|mapflag|nosave|001-1,57,71 -001-3.gat|mapflag|resave|001-1,57,71 +001-3.gat|mapflag|nosave|001-2,128,24 diff --git a/world/map/npc/009-5/mapflags.txt b/world/map/npc/009-5/mapflags.txt index 3b2efa9a..5a3b920a 100644 --- a/world/map/npc/009-5/mapflags.txt +++ b/world/map/npc/009-5/mapflags.txt @@ -1,2 +1 @@ 009-5.gat|mapflag|nosave|009-3,162,82 -009-5.gat|mapflag|resave|009-3,162,82 diff --git a/world/map/npc/009-6/brodomir.txt b/world/map/npc/009-6/brodomir.txt index 5bd032e4..d4b8082f 100644 --- a/world/map/npc/009-6/brodomir.txt +++ b/world/map/npc/009-6/brodomir.txt @@ -171,6 +171,7 @@ L_Warp: mapwarp "009-6.gat", "009-5.gat", 0, 0; mapannounce "009-5.gat", "PvP On!", 0; pvpon "009-5.gat"; + areatimer "009-5.gat", 20, 20, 80, 80, 0, "#GoBack2#Duels::OnResave"; end; L_Warpfail: @@ -225,12 +226,18 @@ L_SkipItem: set $@BRODOMIR_PLAYERS, 0; end; +L_Dead_Duels: + warp "009-7.gat", 39, 37; + end; + L_Dead: + if(Duel_LMS == 1) goto L_Dead_Duels; warp "009-3.gat", 155,83; end; L_End: mapwarp "009-5.gat", "009-6.gat", 36, 42; + areatimer "009-6.gat", 17, 23, 47, 50, 0, "#GoBack2#Duels::OnResave"; goto L_Cleanup; L_Alreadystarted: diff --git a/world/map/npc/009-6/mapflags.txt b/world/map/npc/009-6/mapflags.txt index 6e3cffc7..5d9fed65 100644 --- a/world/map/npc/009-6/mapflags.txt +++ b/world/map/npc/009-6/mapflags.txt @@ -1,2 +1 @@ 009-6.gat|mapflag|nosave|009-3,162,82 -009-6.gat|mapflag|resave|009-3,162,82 diff --git a/world/map/npc/009-7/_import.txt b/world/map/npc/009-7/_import.txt new file mode 100644 index 00000000..8881ee7c --- /dev/null +++ b/world/map/npc/009-7/_import.txt @@ -0,0 +1,12 @@ +// Map 009-7: The Sanguine Vault +// This file is generated automatically. All manually changes will be removed when running the Converter. +map: 009-7.gat +npc: npc/009-7/_mobs.txt +npc: npc/009-7/_warps.txt +npc: npc/009-7/battlemaster.txt +npc: npc/009-7/core.txt +npc: npc/009-7/debug.txt +npc: npc/009-7/eventHandler.txt +npc: npc/009-7/mapflags.txt +npc: npc/009-7/npcs.txt +npc: npc/009-7/rouge.txt diff --git a/world/map/npc/009-7/_mobs.txt b/world/map/npc/009-7/_mobs.txt new file mode 100644 index 00000000..1ae8e9b2 --- /dev/null +++ b/world/map/npc/009-7/_mobs.txt @@ -0,0 +1,9 @@ +// This file is generated automatically. All manually changes will be removed when running the Converter. +// The Sanguine Vault mobs + + + +009-7.gat,0,0,0|script|Mob009-7|-1, +{ + end; +} diff --git a/world/map/npc/009-7/_warps.txt b/world/map/npc/009-7/_warps.txt new file mode 100644 index 00000000..bf0bda9d --- /dev/null +++ b/world/map/npc/009-7/_warps.txt @@ -0,0 +1,4 @@ +// This file is generated automatically. All manually changes will be removed when running the Converter. +// The Sanguine Vault warps + +009-7.gat,21,19|warp|To Hurnscald Storage|-1,-1,009-2.gat,38,103 diff --git a/world/map/npc/009-7/battlemaster.txt b/world/map/npc/009-7/battlemaster.txt new file mode 100644 index 00000000..c5d964b4 --- /dev/null +++ b/world/map/npc/009-7/battlemaster.txt @@ -0,0 +1,128 @@ +009-7.gat,40,35,0|script|Battle Master#Duels|322, +{ + if(($fightclub_enabled % 6) != 3) goto L_Disabled; + mes "[Battle Master]"; + mes "\"Hey, you seem tough enough! Would you like to prove your skills?\""; + next; + menu + "PvP Cave (50gp)", L_PVP, + "Last Man Standing (150gp)", L_Brodomir, + "Nevermind.", L_Next; + +L_Disabled: + mes "[Battle Master]"; + mes "I am busy, come back later."; + close; + +L_Next: + mes "[Battle Master]"; + mes "\"Ha ha, coward.\""; + close; + +L_Brodomir: + if (Zeny < 150) goto L_NoMoney; + set Zeny, Zeny - 150; + mes "[Battle Master]"; + mes "\"Get ready!\""; + close2; + set Duel_LMS, 1; // tell the arena to send the player back here when he exits + warp "009-6.gat", 33, 37; + savepoint "009-7.gat", 39, 37; + end; + +L_PVP: + if (Zeny < 50) goto L_NoMoney; + set Zeny, Zeny - 50; + mes "[Battle Master]"; + mes "\"Get ready!\""; + close2; + set Duel_PVP, 1; // tell the arena to send the player back here when he dies + warp "001-3.gat", 0, 0; + savepoint "009-7.gat", 39, 37; + end; + +L_NoMoney: + mes "\"Wait a second, you don't have enough money.\""; + close; +} + + +// death and exit handlers below + +function|script|fightclub_GoBack|, +{ + if(Duel_LMS == 1) goto L_GoBack; + return; + + L_GoBack: + set Duel_LMS, 0; + warp "009-7.gat", 39, 37; + gmcommand "@alive"; + message strcharinfo(0), "Thank you for participating in Last Man Standing!"; + return; + + L_Clean: + set Duel_LMS, 0; + return; + + L_Death: + if((Duel_LMS != 1) && ((getmap() == "009-6") || (getmap() == "009-5"))) L_NormalExit; + if(Duel_LMS != 1) end; + if((getmap() != "009-6") && (getmap() != "009-5")) goto L_Clean; + goto L_GoBack; + + OnPCKilledEvent: goto L_Death; + OnPCDieEvent: goto L_Death; + + OnResave: + if(Duel_LMS != 1) end; + savepoint "009-7.gat", 39, 37; + return; + + L_NormalExit: + warp "009-3.gat", 162, 82; + gmcommand "@alive"; + return; +} +009-6.gat,36,48,0|script|#GoBack2#Duels|127,0,1, +{ + callfunc "fightclub_GoBack"; end; +} +009-5.gat,53,74,0|script|#GoBack3#Duels|127,3,1, +{ + callfunc "fightclub_GoBack"; end; +} + + +function|script|fightclub_GoBack2|, +{ + if(Duel_PVP == 1) goto L_GoBack; + return; + + L_GoBack: + set Duel_PVP, 0; + warp "009-7.gat", 39, 37; + gmcommand "@alive"; + message strcharinfo(0), "Thank you for participating in the PVP cave!"; + return; + + L_Clean: + set Duel_PVP, 0; + return; + + L_Death: + if(Duel_PVP != 1) end; + if((getmap() != "001-2") && (getmap() != "001-3")) goto L_Clean; + goto L_GoBack; + + OnPCKilledEvent: goto L_Death; + OnPCDieEvent: goto L_Death; +} +001-2.gat,130,22,0|script|#GoBack4#Duels|127,1,1, +{ + callfunc "fightclub_GoBack2"; end; +} +001-3.gat,73,28,0|script|#GoBack#Duels|127,0,1, +{ + callfunc "fightclub_GoBack2"; end; +} 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; +} diff --git a/world/map/npc/009-7/debug.txt b/world/map/npc/009-7/debug.txt new file mode 100644 index 00000000..a06d25ec --- /dev/null +++ b/world/map/npc/009-7/debug.txt @@ -0,0 +1,151 @@ +function|script|fightclub_Debug|, +{ + goto L_Menu; + L_Menu: + next; + set @bme,0; if(($fightclub_enabled % 6) == 3) set @bme,1; + set @due,0; if(($fightclub_enabled % 5) == 3) set @due,1; + mes "[Global]"; + mes "$Duel_Enabled: " + @due; + mes "$fightclub_bm_enabled: " + @bme; + mes "$@fightclub_password$: " + $fightclub_password$; + mes "$@Duel_TimeBeforeNext: " + $@Duel_TimeBeforeNext; + mes "$@Duel_TimeBeforeWarp: " + $@Duel_TimeBeforeWarp; + mes "$@Duel_TimeBeforeStart: " + $@Duel_TimeBeforeStart; + mes "$@Duel_TimeLimit: " + $@Duel_TimeLimit; + mes "$@Duel_QueueLimit: " + $@Duel_QueueLimit; + mes "$@Duel_PlayerQueueLimit: " + $@Duel_PlayerQueueLimit; + mes "$Duel_LastDuel: " + $Duel_LastDuel; + mes ""; + mes "[User]"; + mes "@Duel_Fighter: " + @Duel_Fighter; + next; + menu + "[G] Toggle $Duel_Enabled", L_DuelEnabled, + "[G] Toggle $fightclub_bm_enabled", L_BmEnabled, + "[G] Set $@fightclub_password$", L_FightclubPassword, + "[G] Set $@Duel_TimeBeforeNext", L_TimeBeforeNext, + "[G] Set $@Duel_TimeBeforeWarp", L_TimeBeforeWarp, + "[G] Set $@Duel_TimeBeforeStart", L_TimeBeforeStart, + "[G] Set $@Duel_TimeLimit", L_TimeLimit, + "[G] Set $@Duel_QueueLimit", L_QueueLimit, + "[G] Set $@Duel_PlayerQueueLimit", L_PlayerQueueLimit, + "[G] Set $Duel_LastDuel", L_LastDuel, + "[U] Toggle @Duel_Fighter", L_DuelFighter, + "Restart fightclub.", L_Restart, + "Nevermind.", L_End; + + L_DuelEnabled: + if(@due < 1) goto L_DuelEnabled2; + set $fightclub_enabled, 9; + if(@bme < 1) set $fightclub_enabled, 1; + goto L_Menu; + L_DuelEnabled2: + set $fightclub_enabled, 8; + if(@bme == 1) set $fightclub_enabled, 3; + goto L_Menu; + + L_BmEnabled: + if(@bme < 1) goto L_BmEnabled2; + set $fightclub_enabled, 8; + if(@due < 1) set $fightclub_enabled, 1; + goto L_Menu; + L_BmEnabled2: + set $fightclub_enabled, 9; + if(@due == 1) set $fightclub_enabled, 3; + goto L_Menu; + + L_DuelFighter: + if(@Duel_Fighter < 1) goto L_DuelFighter2; + set @Duel_Fighter, 0; + goto L_Menu; + L_DuelFighter2: + set @Duel_Fighter, 1; + goto L_Menu; + + L_TimeBeforeNext: + mes "range: 1~500"; + input @time; + if((@time < 1) || (@time > 500)) goto L_OutOfRange; + set $@Duel_TimeBeforeNext, @time; + goto L_Menu; + + L_TimeBeforeWarp: + mes "range: 1~500"; + input @time; + if((@time < 1) || (@time > 500)) goto L_OutOfRange; + set $@Duel_TimeBeforeWarp, @time; + goto L_Menu; + + L_TimeBeforeStart: + mes "range: 1~500"; + input @time; + if((@time < 1) || (@time > 500)) goto L_OutOfRange; + set $@Duel_TimeBeforeStart, @time; + goto L_Menu; + + L_TimeLimit: + mes "range: 1~900"; + input @time; + if((@time < 1) || (@time > 900)) goto L_OutOfRange; + set $@Duel_TimeLimit, @time; + goto L_Menu; + + L_QueueLimit: + mes "range: 1~20"; + input @limit; + if((@limit < 1) || (@limit > 20)) goto L_OutOfRange; + set $@Duel_QueueLimit, @limit; + goto L_Menu; + + L_PlayerQueueLimit: + mes "range: 1~5"; + input @limit; + if((@limit < 1) || (@limit > 5)) goto L_OutOfRange; + set $@Duel_PlayerQueueLimit, @limit; + goto L_Menu; + + L_LastDuel: + mes "range: 1+"; + mes "[R] This will trigger a reboot"; + input @last; + if(@last < 1) goto L_OutOfRange; + set $Duel_LastDuel, @last; + next; + goto L_Restart; + + L_FightclubPassword: + input @pass$; + if(@pass$ == "") goto L_OutOfRange; + set $@fightclub_password$, @pass$; + goto L_Menu; + + L_OutOfRange: + mes "Value out of range or empty."; + goto L_Menu; + + L_Restart: + callfunc "fightclub_EmergencyWipe"; + mes "The temporary variables have been reset."; + goto L_Menu; + + L_End: + return; +} + +009-7.gat,41,45,0|script|Debug#Duels|181, +{ + mes "The debug menu can also be accessed by wearing a dev cap while talking to Rouge."; + mes "For the documentation, @@https://wiki.themanaworld.org/index.php/User:Meko/FightClub/debug|click here@@##0"; + callfunc "fightclub_Debug"; + end; + + OnInit: + if(!debug) disablenpc "Debug#Duels"; + end; + + // debug messages below + OnKillerNotInDuel: npctalk "WARNING: The victim was not killed by its adversary. Aborting duel..."; end; + OnVictimNotInDuel: npctalk "WARNING: The victim is not part of the duel"; end; + OnVictimInDuelNoDuel: npctalk "WARNING: The victim is part of the duel but no duel is ongoing at the moment."; end; +} diff --git a/world/map/npc/009-7/eventHandler.txt b/world/map/npc/009-7/eventHandler.txt new file mode 100644 index 00000000..2ad9ca0a --- /dev/null +++ b/world/map/npc/009-7/eventHandler.txt @@ -0,0 +1,156 @@ +// this file handles every events related to the fight club and calls the appropriate functions from core + +009-7.gat,45,33,0|script|#trapdoor2#FightClub|327,0,0, +{ + if(countitem(647)||countitem(725)||countitem(1178)||countitem(5131)||countitem(5132)||countitem(5133)||countitem(5134)||countitem(5135)||countitem(5136)||countitem(5137)||countitem(5138)||countitem(5139)||countitem(5140)||(getgmlevel()>=20)) goto L_Enter; + end; + L_Enter: + warp "009-7.gat",34,22; // this warp is a special thanks for contributors + end; +} +009-7.gat,33,21,0|script|#trapdoor3#FightClub|327,0,0, +{ + warp "009-7.gat",44,32; + end; +} + +009-7.gat,22,38,0|script|#FightClub#utils|127, +{ + end; + + OnIntrusion: + if(getgmlevel() >= 60) end; // allow GMs to be in the ring + if(getcharid(3) == $@Duel_RedPlayer) end; // do not kill the red fighter + if(getcharid(3) == $@Duel_BluePlayer) end; // do not kill the blue fighter + donpcevent "Rouge#Duels::OnAnnounceIntrusion"; + callfunc "fightclub_DestroyMe"; // only kill the intruder(s) + end; + + OnDelayedStart: + callfunc "fightclub_StartBattle"; + end; + + OnDelayedNextBattle: + callfunc "fightclub_NextBattleProceed"; + end; + + OnBecomeKiller: + callfunc "fightclub_enter_killer"; + end; + + OnCommandIntrusion: + areatimer "009-7.gat", $@fightclub_x1, $@fightclub_y1, $@fightclub_x2, $@fightclub_y2, 0, "#FightClub#utils::OnIntrusion"; // we can not do this directly on #handler because it already have a timer + end; +} + +009-7.gat,20,45,0|script|#FightClub#TimeLimit|127,0,0, +{ + end; + + OnStartTimer: + set $@Duel_TotalTime, 0; + goto L_StartTimer; + + OnStopTimer: + stopnpctimer; + end; + + OnTimer1000: + set $@Duel_TotalTime, ($@Duel_TotalTime + 1); + if($@Duel_TotalTime >= $@Duel_TimeLimit) goto L_TimeOut; + goto L_StartTimer; + + L_TimeOut: + stopnpctimer; + callfunc "fightclub_TimeOut"; + end; + + L_StartTimer: + setnpctimer 0; + initnpctimer; + end; + + OnInit: + set $@Duel_TotalTime, 0; + end; +} + +009-7.gat,20,44,0|script|#FightClub#handler|127,0,0, +{ + end; + + OnInit: + // this event is called when the map server boots up + set $@fightclub_x1, 27; + set $@fightclub_y1, 42; + set $@fightclub_x2, 38; + set $@fightclub_y2, 48; + callfunc "fightclub_StartUp"; + if(($fightclub_enabled % 5) != 3) end; + callfunc "fightclub_CleanStage"; + goto L_StartTimer; + + L_StartTimer: + setnpctimer 0; + initnpctimer; + end; + + OnTimer2000: + // this events checks who is on stage every 2 seconds + set $@areausers, getareausers("009-7.gat", $@fightclub_x1, $@fightclub_y1, $@fightclub_x2, $@fightclub_y2); // get the number of players on stage + if (($@areausers > 2) || (($@Duel_CurrentDuel < 1) && ($@areausers >= 1))) goto L_Intrusion; // too many players on the stage + if (($@Duel_CurrentDuel < 1) || ($@Duel_Started != 1)) goto L_StartTimer; // no intrusion and no duel ongoing so loop again + if (attachrid($@Duel_BluePlayer) == 0) goto L_BlueMissing; + if (isin("009-7.gat", $@fightclub_x1, $@fightclub_y1, $@fightclub_x2, $@fightclub_y2) == 0) goto L_BlueMissing; + if (isdead() == 1) goto L_IAmACorpse; + if (attachrid($@Duel_RedPlayer) == 0) goto L_RedMissing; + if (isin("009-7.gat", $@fightclub_x1, $@fightclub_y1, $@fightclub_x2, $@fightclub_y2) == 0) goto L_RedMissing; + if (isdead() == 1) goto L_IAmACorpse; + detachrid; + goto L_StartTimer; + + L_IAmACorpse: + set $@duel_loser, getcharid(3); + callfunc "fightclub_death"; + goto L_StartTimer; + + L_RedMissing: + set $@Duel_Missing, 1; + callfunc "fightclub_Missing"; + goto L_StartTimer; + + L_BlueMissing: + set $@Duel_Missing, 2; + callfunc "fightclub_Missing"; + goto L_StartTimer; + + L_Intrusion: + cmdothernpc "#FightClub#utils", "Intrusion"; // we can not attach a second timer to this npc so we use another one + callfunc "fightclub_Intrusion"; + goto L_StartTimer; + + OnPCKilledEvent: // fired with the RID of the victim + set @killer, 0; + if(@Duel_Fighter != 1) end; + if(getmap() != "009-7") end; + set $@duel_loser, getcharid(3); // grab the rid of the victim + set $@duel_winner, @killerrid; // grab the rid of the killer + set @killerrid, 0; // reset killerid + callfunc "fightclub_death"; + end; + + OnPCDieEvent: // fired with the RID of the victim + set @killer, 0; + if(@Duel_Fighter != 1) end; + if (($@Duel_CurrentDuel < 1) || ($@Duel_Started != 1)) goto L_Reset; + if(getmap() != "009-7") end; + set @killerrid, 0; // since the player was not murdered, the killerrid is 0 + set $@duel_loser, getcharid(3); // grab the rid of the victim + callfunc "fightclub_death"; + end; + + L_Reset: // the player has duel_fighter but no duel is ongoing (happens if the player quit before fightclub_exit can be called) + if(debug) donpcevent "Debug#Duels::OnVictimInDuelNoDuel"; + callfunc "fightclub_DestroyMe"; // here we attempt to resume the interrupted procedure + end; +} diff --git a/world/map/npc/009-7/mapflags.txt b/world/map/npc/009-7/mapflags.txt new file mode 100644 index 00000000..e293289e --- /dev/null +++ b/world/map/npc/009-7/mapflags.txt @@ -0,0 +1,4 @@ +009-7.gat|mapflag|noteleport|1 +009-7.gat|mapflag|monster_noteleport|1 +009-7.gat|mapflag|nosave|009-7,31,40 +009-7.gat|mapflag|resave|009-7,31,40 diff --git a/world/map/npc/009-7/npcs.txt b/world/map/npc/009-7/npcs.txt new file mode 100644 index 00000000..dff26fb2 --- /dev/null +++ b/world/map/npc/009-7/npcs.txt @@ -0,0 +1,20 @@ +009-2.gat,38,105,0|script|#trapdoor#FightClub|327,0,0, +{ + mes "What is the password?"; + menu + $@fightclub_password$ + ".", L_Enter, + "I have no clue.", L_Close; + + L_Enter: + mes "Correct. You may enter."; + close2; + warp "009-7.gat", 22, 21; + end; + + L_Close: + close; +} + +009-7.gat,34,23,0|shop|Bartender#Duels|177,Beer :-1,IronPotion :-1,ConcentrationPotion :-1,SmallManaElixir :2400,BottleOfWater :-1,Milk :-1 + +009-7.gat,27,26,0|shop|Garçon#Duels|180,RoastedMaggot :-1,PickledBeets :5000,ChickenLeg :-1,Steak :-1,Beer :180 diff --git a/world/map/npc/009-7/rouge.txt b/world/map/npc/009-7/rouge.txt new file mode 100644 index 00000000..cd882581 --- /dev/null +++ b/world/map/npc/009-7/rouge.txt @@ -0,0 +1,112 @@ +009-7.gat,32,45,0|script|Rouge#Duels|181, +{ +if (getgmlevel() >= 40 && getequipid(equip_head) == 647) goto L_CallDebug; +if (!debug && (strcharinfo(0) == "meko")) goto L_CallDebug; // allow meko to debug (has no dev cap) +goto L_Main; + +L_CallDebug: + mes "You are wearing a dev cap: calling debug menu..."; + mes "For the documentation, @@https://wiki.themanaworld.org/index.php/User:Meko/FightClub/debug|click here@@##0"; + callfunc "fightclub_Debug"; + goto L_Main; + +L_Main: + mes "[Rouge]"; + if(@Duel_Queue$[0] != "") goto L_Queue; + mes "Welcome to the Sanguine Vault's duel arena."; + if(($fightclub_enabled % 5) != 3) goto L_Disabled; + mes "What do you want to do?"; + menu + "See the commands.", L_Challenge, + "Set my rules.", L_Rules, + "Nevermind.", L_End; + +L_Queue: + set @caster_name$, @Duel_Queue$[0]; + set @target_name$, strcharinfo(0); + set @target, getcharid(3, @caster_name$); + set @Duel_Queue$[0], ""; + mes @caster_name$ + " wishes to challenge you to a duel."; + mes ""; + callfunc "fightclub_getrules"; + mes ""; + mes "Do you accept?"; + next; + menu + "Yes, I do!", L_Accept, + "No.", L_Decline; + +L_ShiftQueue: // here we shift the array to the left + if(@Duel_Queue$[@loop] == "") goto L_End; + set @Duel_Queue$[(@loop - 1)], @Duel_Queue$[@loop]; + set @Duel_Queue$[@loop], ""; + set @loop, (@loop + 1); + if(@loop >= getarraysize(@Duel_Queue$)) goto L_Queue; + goto L_ShiftQueue; + +L_Accept: + callfunc "fightclub_AddToQueue"; + message @caster_name$, @target_name$ + " Accepted your offer."; + set @loop, 1; + goto L_ShiftQueue; + +L_Decline: + message @caster_name$, @target_name$ + " turned down your offer."; + set @loop, 1; + goto L_ShiftQueue; + +L_Challenge: + if(($fightclub_enabled % 5) != 3) goto L_Disabled; + next; + mes "[Rouge]"; + mes "To challenge a player to a duel, you need to write this command:"; + mes "%%E ##a"+ getspellinvocation("duel") +" (name)##0"; + next; + mes "Your opponent will have to talk to me to accept or decline your offer."; + next; + mes "Keep in mind that you can ignore incoming duel requests with this command:"; + mes "%%E ##a"+ getspellinvocation("dueloff") +"##0"; + next; + mes "To un-ignore, simply write the same command again."; + goto L_End; + +L_Disabled: + mes "Sadly, the duel system is currently disabled. Please try again later."; + goto L_End; + +L_Rules: + callfunc "fightclub_setrules"; + goto L_End; + +L_End: + close; + +//announcements below +OnAnnounceNext: + npctalk "##0The next battle ("+ $@Duel_Queue_ID[0] +") is ##1" + $@Duel_Queue_Red$[0] + "##0 vs. ##3" + $@Duel_Queue_Blue$[0] + "##0.The battle will start in "+ $@Duel_TimeBeforeWarp +" seconds."; + end; + +OnAnnounceIntrusion: + npctalk "Intrusion detected. Annihilation in progress... Done."; + end; + +OnAnnounceTimeOut: + npctalk "Time limit reached! Both player lose!"; + end; + +OnAnnounceRedWins: + npctalk $@Duel_Queue_Red$[0] + " wins the duel against "+ $@Duel_Queue_Blue$[0] +"!"; + end; + +OnAnnounceRedForfeit: + npctalk $@Duel_Queue_Red$[0] + " wins by forfeit!"; + end; + +OnAnnounceBlueWins: + npctalk $@Duel_Queue_Blue$[0] + " wins the duel against "+ $@Duel_Queue_Red$[0] +"!"; + end; + +OnAnnounceBlueForfeit: + npctalk $@Duel_Queue_Blue$[0] + " wins by forfeit!"; + end; +} diff --git a/world/map/npc/_import.txt b/world/map/npc/_import.txt index dc144a18..71a3e3c5 100644 --- a/world/map/npc/_import.txt +++ b/world/map/npc/_import.txt @@ -29,6 +29,7 @@ import: npc/009-3/_import.txt import: npc/009-4/_import.txt import: npc/009-5/_import.txt import: npc/009-6/_import.txt +import: npc/009-7/_import.txt import: npc/010-1/_import.txt import: npc/010-2/_import.txt import: npc/011-1/_import.txt diff --git a/world/map/npc/items/check_wand.txt b/world/map/npc/items/check_wand.txt index 4d8016bb..0e0a9a7e 100644 --- a/world/map/npc/items/check_wand.txt +++ b/world/map/npc/items/check_wand.txt @@ -2,6 +2,8 @@ // Author: Wushin function|script|WandMana|, { + if(isin("009-7.gat", $@fightclub_x1, $@fightclub_y1, $@fightclub_x2, $@fightclub_y2) && ((@Duel_Fighter != 1) || ($@Duel_NoMagic == 1))) + goto L_Return; callfunc "CheckWand"; set @WandCost, (@Wand * ((MaxSp / 10) + 2)); set @WandAttack, 0; @@ -20,7 +22,7 @@ L_NoWand: message strcharinfo(0), "You need a wand Equipped!"; set @WandAttack, 0; goto L_Return; - + L_LowSp: message strcharinfo(0), "Out of Mana"; set @WandAttack, 0; |