diff options
37 files changed, 1258 insertions, 76 deletions
diff --git a/world/map/conf/magic-config.sex b/world/map/conf/magic-config.sex index 5b20a19b..a130becf 100644 --- a/world/map/conf/magic-config.sex +++ b/world/map/conf/magic-config.sex @@ -32,6 +32,7 @@ (CONST SC_MBARRIER 197) (CONST SC_HASTE 198) (CONST SC_PHYS_SHIELD 199) +(CONST SO_GMHIDE 64) (CONST SO_GMINVISIBLE 4096) "Special effects" diff --git a/world/map/conf/magic-level1.sex b/world/map/conf/magic-level1.sex index 3e673170..01864666 100644 --- a/world/map/conf/magic-level1.sex +++ b/world/map/conf/magic-level1.sex @@ -7,7 +7,8 @@ (GUARD (CASTTIME 500)) (EFFECT - (SCRIPT "{callfunc \"CheckWand\";}") + (CALL fightclub_check) + (SCRIPT "{callfunc \"CheckWand\";}") (IF (== (script_int caster "@Wand") 0) @@ -23,7 +24,7 @@ (CALL gain_xp 1 3) (ATTRIGGER (CALL attack_check target) - (SCRIPT "{callfunc \"WandMana\";}") + (SCRIPT "{callfunc \"WandMana\";}") (IF (== (script_int caster "@WandAttack") 0) @@ -199,6 +200,25 @@ (pc target))) (+ 2 (/ spellpower 100))))) + (REQUIRE + (not + (|| + (&& + (is_in (location (pc target)) + (@+ + (@ "009-7.gat" (script_int caster "$@fightclub_x1") (script_int caster "$@fightclub_y1")) + (- (script_int caster "$@fightclub_x2") (script_int caster "$@fightclub_x1")) + (- (script_int caster "$@fightclub_y2") (script_int caster "$@fightclub_y1")))) + (!= (pc target) caster)) + (&& + (&& + (is_in (location (pc target)) + (@+ + (@ "009-7.gat" (script_int caster "$@fightclub_x1") (script_int caster "$@fightclub_y1")) + (- (script_int caster "$@fightclub_x2") (script_int caster "$@fightclub_x1")) + (- (script_int caster "$@fightclub_y2") (script_int caster "$@fightclub_y1")))) + (== (pc target) caster)) + (== (script_int caster "$@Duel_NoMagic") 1))))) (GUARD (COMPONENTS "Lifestone"))) (EFFECT @@ -262,6 +282,7 @@ 2)) (COMPONENTS "SulphurPowder")))) (EFFECT + (CALL fightclub_check) (CALL adjust_spellpower school) (CALL default_effect) (SET damage @@ -298,6 +319,7 @@ (=> (COMPONENTS "SharpKnife") (EFFECT + (CALL fightclub_check) (CALL adjust_spellpower WAR) (CALL default_effect) (CALL install_melee_spell @@ -313,6 +335,7 @@ (=> (COMPONENTS "Knife") (EFFECT + (CALL fightclub_check) (CALL adjust_spellpower WAR) (CALL default_effect) (CALL install_melee_spell @@ -365,20 +388,22 @@ level)) (COMPONENTS "MauveHerb" "Root")) (EFFECT + (CALL fightclub_check) (CALL adjust_spellpower school) (CALL default_effect) (CALL gain_xp 1 6) - (spawn - (rbox location 2) - caster - 1029 - 1 + (CALL summon_spell 1029 (+ (/ (skill caster school) 2) 1) - 10000)))) + (- 4000 + (* spellpower 9)) + (+ 10000 + (* spellpower 50)) + 999999 + school)))) (SPELL () grow-alizarin "#modriphoo" () (LET level 0) @@ -393,20 +418,22 @@ level)) (COMPONENTS "AlizarinHerb" "Root")) (EFFECT + (CALL fightclub_check) (CALL adjust_spellpower school) (CALL default_effect) (CALL gain_xp 1 7) - (spawn - (rbox location 2) - caster - 1032 - 1 + (CALL summon_spell 1032 (+ (/ (skill caster school) 2) 1) - 10000)))) + (- 4000 + (* spellpower 9)) + (+ 10000 + (* spellpower 50)) + 999999 + school)))) (SPELL () grow-gamboge "#modriyikam" () (LET level 0) @@ -421,20 +448,22 @@ level)) (COMPONENTS "GambogeHerb" "Root")) (EFFECT + (CALL fightclub_check) (CALL adjust_spellpower school) (CALL default_effect) (CALL gain_xp 1 8) - (spawn - (rbox location 2) - caster - 1031 - 1 + (CALL summon_spell 1031 (+ (/ (skill caster school) 2) 1) - 10000)))) + (- 4000 + (* spellpower 9)) + (+ 10000 + (* spellpower 50)) + 999999 + school)))) (SPELL () grow-cobalt "#modrisump" () (LET level 0) @@ -449,20 +478,22 @@ level)) (COMPONENTS "CobaltHerb" "Root")) (EFFECT + (CALL fightclub_check) (CALL adjust_spellpower school) (CALL default_effect) (CALL gain_xp 1 9) - (spawn - (rbox location 2) - caster - 1030 - 1 + (CALL summon_spell 1030 (+ (/ (skill caster school) 2) 1) - 10000)))) + (- 4000 + (* spellpower 9)) + (+ 10000 + (* spellpower 50)) + 999999 + school)))) (SPELL (LOCAL) summon-maggots "#kalmurk" () (LET level 0) @@ -477,6 +508,7 @@ level)) (COMPONENTS "MaggotSlime" "Root")) (EFFECT + (CALL fightclub_check) (CALL adjust_spellpower school) (CALL gain_xp 1 10) (CALL summon_spell 1002 @@ -490,7 +522,8 @@ (* spellpower 5)) (+ 10000 (* spellpower 50)) - 1)))) + 1 + school)))) (SPELL () detect-magic "#miteyo" () (LET level 0) diff --git a/world/map/conf/magic-level2.sex b/world/map/conf/magic-level2.sex index af805160..0f1f32b1 100644 --- a/world/map/conf/magic-level2.sex +++ b/world/map/conf/magic-level2.sex @@ -221,6 +221,13 @@ (skill caster school) level)) (REQUIRE + (not + (is_in (location (pc target)) + (@+ + (@ "009-7.gat" (script_int caster "$@fightclub_x1") (script_int caster "$@fightclub_y1")) + (- (script_int caster "$@fightclub_x2") (script_int caster "$@fightclub_x1")) + (- (script_int caster "$@fightclub_y2") (script_int caster "$@fightclub_y1")))))) + (REQUIRE (if_then_else (failed (pc target)) @@ -354,6 +361,7 @@ 3)) (COMPONENTS "IronPowder")))) (EFFECT + (CALL fightclub_check) (CALL adjust_spellpower school) (SET damage spellpower) (SET damage_bonus @@ -556,6 +564,7 @@ 3)) (COMPONENTS "Beer")))) (EFFECT + (CALL fightclub_check) (CALL adjust_spellpower WAR) (SET str (str caster)) @@ -590,16 +599,18 @@ 40)) (COMPONENTS "DarkCrystal" "SnakeEgg")) (EFFECT + (CALL fightclub_check) (CALL adjust_spellpower school) (CALL default_effect) (CALL gain_xp 3 31) - (CALL summon_dark_spell 1010 + (CALL summon_spell 1010 (+ 1 (/ spellpower 300)) (- 4000 (* spellpower 9)) (* spellpower 80) - 2)))) + 2 + school)))) (SPELL () toxic-dart "#phlex" () (LET level 1) @@ -625,6 +636,7 @@ (COMPONENTS (2 "Root"))))) (EFFECT + (CALL fightclub_check) (CALL adjust_spellpower school) (CALL default_effect) (SET damage @@ -679,16 +691,18 @@ level)) (COMPONENTS "SmallMushroom" "DarkCrystal")) (EFFECT + (CALL fightclub_check) (CALL adjust_spellpower school) (CALL default_effect) (CALL gain_xp 3 36) - (CALL summon_dark_spell 1106 + (CALL summon_spell 1106 (+ 1 (/ spellpower 250)) (- 4000 (* spellpower 9)) (* spellpower 80) - 2)))) + 2 + school)))) (SPELL () flying-backpack "#plugh" (PC target) (LET level 1) @@ -720,6 +734,7 @@ (+ 2 (/ spellpower 30))))) (EFFECT + (CALL fightclub_check) (CALL adjust_spellpower school) (CALL default_effect) (IF (!= caster target) @@ -768,6 +783,7 @@ (+ 2 (/ spellpower 30))))) (EFFECT + (CALL fightclub_check) (CALL adjust_spellpower school) (sfx target 11 0) (IF (!= caster target) @@ -1059,6 +1075,7 @@ (+ 2 (/ spellpower 30))))) (EFFECT + (CALL fightclub_check) (CALL adjust_spellpower school) (sfx target SFX_BARRIER 0) (IF (!= caster target) @@ -1095,6 +1112,7 @@ level)) (COMPONENTS "HardSpike" "Root")) (EFFECT + (CALL fightclub_check) (CALL adjust_spellpower school) (CALL default_effect) (CALL gain_xp 1 26) @@ -1104,7 +1122,8 @@ (- 5000 (* spellpower 9)) (* spellpower 400) - 2)))) + 2 + school)))) (SPELL (LOCAL) summon-fluffies "#kalakarenk" () (LET level 1) @@ -1123,6 +1142,7 @@ level)) (COMPONENTS "WhiteFur" "Root")) (EFFECT + (CALL fightclub_check) (CALL adjust_spellpower school) (CALL default_effect) (CALL gain_xp 1 27) @@ -1134,7 +1154,8 @@ (- 5000 (* spellpower 8)) (* spellpower 350) - 2)))) + 2 + school)))) (SPELL (LOCAL) summon-mouboo "#kalboo" () (LET level 1) @@ -1153,6 +1174,7 @@ level)) (COMPONENTS "MoubooFigurine" "Root")) (EFFECT + (CALL fightclub_check) (CALL adjust_spellpower school) (CALL default_effect) (CALL gain_xp 2 37) @@ -1162,7 +1184,8 @@ (- 4000 (* spellpower 9)) (* spellpower 100) - 2)))) + 2 + school)))) (SPELL (LOCAL) summon-pinkie "#kalgina" () (LET level 1) @@ -1181,6 +1204,7 @@ level)) (COMPONENTS "PinkAntenna" "Root")) (EFFECT + (CALL fightclub_check) (CALL adjust_spellpower school) (CALL default_effect) (CALL gain_xp 2 38) @@ -1190,7 +1214,8 @@ (- 5000 (* spellpower 9)) (* spellpower 150) - 2)))) + 2 + school)))) (SPELL () detect-players "#inwilt" () (LET level 1) diff --git a/world/map/conf/magic-level3.sex b/world/map/conf/magic-level3.sex index 2550da3e..b4b3e030 100644 --- a/world/map/conf/magic-level3.sex +++ b/world/map/conf/magic-level3.sex @@ -53,6 +53,7 @@ level)) (COMPONENTS "PileOfAsh")) (EFFECT + (CALL fightclub_check) (CALL adjust_spellpower school) (SET damage (min diff --git a/world/map/conf/magic-misc.sex b/world/map/conf/magic-misc.sex index 97263a03..4a08f118 100644 --- a/world/map/conf/magic-misc.sex +++ b/world/map/conf/magic-misc.sex @@ -1,6 +1,69 @@ "--------------------------------------------------------------------------------" "Special-purpose quasispells" "--------------------------------------------------------------------------------" +(SPELL (NONMAGIC) dueloff "#dueloff" () + (=> + (GUARD + (REQUIRE + (== (substr (location caster) 2 5) "009-7"))) + (EFFECT + (IF (== (script_int caster "@Duels_Off") 1) + (BLOCK + (SCRIPT "{set @Duels_Off, 0;}") + (message caster "Now accepting incoming duel requests.") + (ABORT))) + (SCRIPT "{set @Duels_Off, 1;}") + (message caster "Now blocking incoming duel requests.")))) + +(SPELL (NONMAGIC) duel "#duel" (PC target) + (=> + (GUARD + (REQUIRE + (== (% (script_int target "$fightclub_enabled") 5) 3))) + (EFFECT + (IF (== target caster) + (BLOCK + (message caster "You can not fight against yourself.") + (ABORT))) + (IF (is_dead target) + (BLOCK + (message caster "You can not fight against a corpse.") + (ABORT))) + (IF (status_option caster SO_GMINVISIBLE) + (BLOCK + (message caster "You can not fight while being invisible.") + (ABORT))) + (IF (status_option target SO_GMHIDE) + (BLOCK + (message caster "This player have @hide enabled.") + (ABORT))) + (IF (status_option target SO_GMINVISIBLE) + (ABORT)) + (IF (status_option caster SO_GMHIDE) + (ABORT)) + (IF (!= (substr (location caster) 2 5) "009-7") + (BLOCK + (message caster "You need to be in the fight club to challenge someone to a duel.") + (ABORT))) + (IF (!= (substr (location target) 2 5) "009-7") + (BLOCK + (message caster "This player is not in the fight club at the moment.") + (ABORT))) + (IF (> (script_int target "@Duels_Off") 0) + (BLOCK + (message caster "This player is automatically ignoring incoming duel requests.") + (ABORT))) + (IF (> (script_int caster "$@Duel_Queue_ID[($@Duel_QueueLimit)]") 0) + (BLOCK + (message caster (+ (+ "There is already " (script_int caster "$@Duel_QueueLimit")) " duel(s) in the queue, which is the maximum.")) + (ABORT))) + (IF (> (script_int target "@Duel_Queue[($@Duel_PlayerQueueLimit)]") 0) + (BLOCK + (message caster (+ (+ "There is already " (script_int caster "$@Duel_PlayerQueueLimit")) " duel request(s) in the queue of this player, which is the maximum.")) + (ABORT))) + (SET script_target target) + (SCRIPT "{callfunc \"fightclub_sendrequest\";}")))) + (SPELL (NONMAGIC SILENT) marriage "marry" (PC target) (=> (GUARD diff --git a/world/map/conf/magic-procedures.sex b/world/map/conf/magic-procedures.sex index 6f9c3246..bce579fc 100644 --- a/world/map/conf/magic-procedures.sex +++ b/world/map/conf/magic-procedures.sex @@ -280,36 +280,35 @@ (PROCEDURE install_melee_spell (charges base_delay attack_animation) (CALL install_attack_spell charges base_delay 1 attack_animation)) -(PROCEDURE summon_spell (mob_id count delay lifetime control_level) - (CALL default_effect) - (sfx location SFX_SUMMON_START 0) - (WAIT delay) - (sfx location SFX_SUMMON_FIRE 0) - (spawn - (rbox location 2) - caster - mob_id - (if_then_else - (>= - (skill caster ASTRAL) - control_level) - 2 - 1) - count - lifetime)) "pets when level is high enough" +(PROCEDURE fightclub_check () + (IF (&& + (is_in (location caster) + (@+ + (@ "009-7.gat" (script_int caster "$@fightclub_x1") (script_int caster "$@fightclub_y1")) + (- (script_int caster "$@fightclub_x2") (script_int caster "$@fightclub_x1")) + (- (script_int caster "$@fightclub_y2") (script_int caster "$@fightclub_y1")))) + (|| + (== (script_int caster "$@Duel_NoMagic") 1) + (!= (script_int caster "@Duel_Fighter") 1))) + (ABORT))) -(PROCEDURE summon_dark_spell (mob_id count delay lifetime control_level) +(PROCEDURE summon_spell (mob_id count delay lifetime control_level school) (CALL default_effect) (sfx location SFX_SUMMON_START 0) (WAIT delay) (sfx location SFX_SUMMON_FIRE 0) (spawn - (rbox location 2) + (rbox location (if_then_else + (is_in (location caster) + (@+ + (@ "009-7.gat" (- (script_int caster "$@fightclub_x1") 2) (- (script_int caster "$@fightclub_y1") 2)) + (+ (- (script_int caster "$@fightclub_x2") (script_int caster "$@fightclub_x1")) 2) + (+ (- (script_int caster "$@fightclub_y2") (script_int caster "$@fightclub_y1")) 2))) 1 2)) caster mob_id (if_then_else (>= - (skill caster DARK) + (skill caster school) control_level) 2 1) diff --git a/world/map/data/001-1.wlk b/world/map/data/001-1.wlk Binary files differindex 05f949c1..9050ad38 100644 --- a/world/map/data/001-1.wlk +++ b/world/map/data/001-1.wlk diff --git a/world/map/data/009-2.wlk b/world/map/data/009-2.wlk Binary files differindex 13657806..15e0d179 100644 --- a/world/map/data/009-2.wlk +++ b/world/map/data/009-2.wlk diff --git a/world/map/data/009-7.wlk b/world/map/data/009-7.wlk Binary files differnew file mode 100644 index 00000000..ed9615d7 --- /dev/null +++ b/world/map/data/009-7.wlk diff --git a/world/map/data/021-1.wlk b/world/map/data/021-1.wlk Binary files differindex af614879..e7afe900 100644 --- a/world/map/data/021-1.wlk +++ b/world/map/data/021-1.wlk diff --git a/world/map/data/022-1.wlk b/world/map/data/022-1.wlk Binary files differindex ae5f314d..f84df1d7 100644 --- a/world/map/data/022-1.wlk +++ b/world/map/data/022-1.wlk diff --git a/world/map/data/024-1.wlk b/world/map/data/024-1.wlk Binary files differindex c15f1d51..26d6e3fc 100644 --- a/world/map/data/024-1.wlk +++ b/world/map/data/024-1.wlk diff --git a/world/map/data/042-1.wlk b/world/map/data/042-1.wlk Binary files differindex da320f7e..ccd506c8 100644 --- a/world/map/data/042-1.wlk +++ b/world/map/data/042-1.wlk diff --git a/world/map/data/resnametable.txt b/world/map/data/resnametable.txt index 9284d5e9..645cce18 100644 --- a/world/map/data/resnametable.txt +++ b/world/map/data/resnametable.txt @@ -27,6 +27,7 @@ 009-4.gat#009-4.wlk# 009-5.gat#009-5.wlk# 009-6.gat#009-6.wlk# +009-7.gat#009-7.wlk# 010-1.gat#010-1.wlk# 010-2.gat#010-2.wlk# 011-1.gat#011-1.wlk# diff --git a/world/map/db/const.txt b/world/map/db/const.txt index 655de746..b8debd26 100644 --- a/world/map/db/const.txt +++ b/world/map/db/const.txt @@ -323,6 +323,7 @@ FX_MAGIC_BLACK 4 FX_MAGIC_RED 5 FX_MAGIC_GREEN 6 FX_MAGIC_BLUE 7 +FX_MAGIC_DARKRED 8 FX_MAGIC_DEFAULT 10 FX_MAGIC_SHIELD 11 FX_MAGIC_HIT 13 diff --git a/world/map/npc/001-1/_warps.txt b/world/map/npc/001-1/_warps.txt index d113ba85..a15050cf 100644 --- a/world/map/npc/001-1/_warps.txt +++ b/world/map/npc/001-1/_warps.txt @@ -4,5 +4,5 @@ 001-1.gat,44,87|warp|To Sandstorm Desert|3,-1,002-1.gat,58,14 001-1.gat,44,20|warp|To North Tulimshar|3,-1,021-1.gat,55,145 001-1.gat,125,21|warp|To North Tulimshar|0,-1,021-1.gat,136,146 -001-1.gat,32,70|warp|To Tulimshar Indoor|-1,-1,001-2.gat,25,34 -001-1.gat,75,40|warp|To Tulimshar Indoor|-1,-1,001-2.gat,71,72 +001-1.gat,32,71|warp|To Tulimshar Indoor|-1,-1,001-2.gat,25,34 +001-1.gat,75,41|warp|To Tulimshar Indoor|-1,-1,001-2.gat,71,72 diff --git a/world/map/npc/001-3/guards.txt b/world/map/npc/001-3/guards.txt index 699d46ba..0c79d3a2 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(DUELS & $@DuelPvpBit) goto L_FightClub; warp "001-2.gat", 25, 23; close; + +L_FightClub: + set DUELS, DUELS &~ $@DuelPvpBit; + 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..e981e603 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,19 @@ L_SkipItem: set $@BRODOMIR_PLAYERS, 0; end; +L_Dead_Duels: + set DUELS, DUELS &~ $@DuelPvpBit; + warp "009-7.gat", 39, 37; + end; + L_Dead: + if(DUELS & $@DuelPvpBit) 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..cdb79923 --- /dev/null +++ b/world/map/npc/009-7/battlemaster.txt @@ -0,0 +1,102 @@ +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 DUELS, DUELS | $@DuelPvpBit; // 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 DUELS, DUELS | $@DuelPvpBit; // 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|, +{ + set @Duel_PVP, DUELS & $@DuelPvpBit; + if((@Duel_PVP == 0) && ((getmap() == "009-6") || (getmap() == "009-5"))) goto L_NormalExit; + if((getmap() != "009-6") && (getmap() != "009-5") && (getmap() != "001-2") && (getmap() != "001-3")) goto L_Clean; + if(@Duel_PVP != 0) goto L_GoBack; + return; + +L_GoBack: + set DUELS, DUELS &~ $@DuelPvpBit; + warp "009-7.gat", 39, 37; + gmcommand "@alive"; + message strcharinfo(0), "Thank you for participating!"; + return; + +L_Clean: + set DUELS, DUELS &~ $@DuelPvpBit; + return; + +OnResave: + if(@Duel_PVP == 0) 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; +} + + +001-2.gat,130,22,0|script|#GoBack4#Duels|127,1,1, +{ + callfunc "fightclub_GoBack"; + end; +} +001-3.gat,73,28,0|script|#GoBack#Duels|127,0,1, +{ + callfunc "fightclub_GoBack"; + 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..3a92a928 --- /dev/null +++ b/world/map/npc/009-7/core.txt @@ -0,0 +1,447 @@ +// 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, (DUELS & $@NoMagicBit); + 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, (DUELS & $@NoMagicBit); // 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; + // flags below + set $@DuelPvpBit, (1 << 1); + set $@NoMagicBit, (1 << 2); + 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 DUELS, DUELS | $@NoMagicBit; + goto L_NoMagic; + +L_NoMagic: + if((DUELS & $@NoMagicBit) != 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 DUELS, DUELS &~ $@NoMagicBit; + 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(($@Duel_CurrentDuel < 1) || ($@Duel_Started != 1)) goto L_Reset; + 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"; + return; + +L_NoDuel: + if(debug) donpcevent "Debug#Duels::OnVictimNotInDuel"; + return; + +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 + return; +} + +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..6ca0de8d --- /dev/null +++ b/world/map/npc/009-7/debug.txt @@ -0,0 +1,160 @@ +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..4098e14a --- /dev/null +++ b/world/map/npc/009-7/eventHandler.txt @@ -0,0 +1,132 @@ +// 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; +} 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..72a4e9f8 --- /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..34df9dd4 --- /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/021-1/_warps.txt b/world/map/npc/021-1/_warps.txt index daa1a89d..429a522f 100644 --- a/world/map/npc/021-1/_warps.txt +++ b/world/map/npc/021-1/_warps.txt @@ -8,18 +8,18 @@ 021-1.gat,135,119|warp|To Tulimshar Musuem|-1,-1,021-2.gat,90,177 021-1.gat,55,146|warp|To South Tulimshar|3,-1,001-1.gat,44,21 021-1.gat,136,147|warp|To South Tulimshar|0,-1,001-1.gat,125,22 -021-1.gat,53,133|warp|To Government Building|-1,-1,021-2.gat,27,29 -021-1.gat,55,133|warp|To Government Building|-1,-1,021-2.gat,33,29 -021-1.gat,57,133|warp|To Government Building|-1,-1,021-2.gat,39,29 -021-1.gat,103,99|warp|To Tulimshar Bakery|-1,-1,021-2.gat,91,27 +021-1.gat,53,134|warp|To Government Building|-1,-1,021-2.gat,27,29 +021-1.gat,55,134|warp|To Government Building|-1,-1,021-2.gat,33,29 +021-1.gat,57,134|warp|To Government Building|-1,-1,021-2.gat,39,29 +021-1.gat,103,100|warp|To Tulimshar Bakery|-1,-1,021-2.gat,91,27 021-1.gat,103,96|warp|To Bakery|-1,-1,021-2.gat,122,23 021-1.gat,49,64|warp|To Tulimshar Canyon|3,-1,024-1.gat,86,73 -021-1.gat,53,98|warp|To Wizard's Rest|-1,-1,021-2.gat,25,66 +021-1.gat,53,99|warp|To Wizard's Rest|-1,-1,021-2.gat,25,66 021-1.gat,52,95|warp|To Wizard's Rest|-1,-1,021-2.gat,70,63 021-1.gat,73,22|warp|To Tulimshar Port|3,-1,022-1.gat,73,109 021-1.gat,113,22|warp|To Tulimshar Port|3,-1,022-1.gat,113,109 -021-1.gat,132,30|warp|To Tulimshar Forge|-1,-1,021-2.gat,79,138 +021-1.gat,132,31|warp|To Tulimshar Forge|-1,-1,021-2.gat,79,138 021-1.gat,133,24|warp|To Tulimshar Forge|-1,-1,021-2.gat,75,92 021-1.gat,125,27|warp|To Tulimshar Forge|-1,-1,021-2.gat,124,68 -021-1.gat,125,30|warp|To Tulimshar Forge|-1,-1,021-2.gat,72,138 -021-1.gat,43,109|warp|To Store|-1,-1,021-2.gat,28,129 +021-1.gat,125,31|warp|To Tulimshar Forge|-1,-1,021-2.gat,72,138 +021-1.gat,43,110|warp|To Store|-1,-1,021-2.gat,28,129 diff --git a/world/map/npc/042-1/_warps.txt b/world/map/npc/042-1/_warps.txt index b8e20944..8c1043ea 100644 --- a/world/map/npc/042-1/_warps.txt +++ b/world/map/npc/042-1/_warps.txt @@ -3,12 +3,12 @@ 042-1.gat,97,41|warp|To Tulismhar Docks|-1,2,022-1.gat,21,37 042-1.gat,65,20|warp|To Lighthouse Beach|0,-1,023-1.gat,64,143 -042-1.gat,91,72|warp|To Store House|-1,-1,042-2.gat,22,92 -042-1.gat,104,72|warp|To Store House|-1,-1,042-2.gat,44,92 -042-1.gat,65,74|warp|To Tulimshar Suburbs House|-1,-1,042-2.gat,29,61 +042-1.gat,91,73|warp|To Store House|-1,-1,042-2.gat,22,92 +042-1.gat,104,73|warp|To Store House|-1,-1,042-2.gat,44,92 +042-1.gat,65,75|warp|To Tulimshar Suburbs House|-1,-1,042-2.gat,29,61 042-1.gat,62,42|warp|To Sorfina's Dinner|-1,-1,042-2.gat,112,85 042-1.gat,51,43|warp|To Sorfina's House|-1,-1,042-2.gat,44,30 -042-1.gat,117,101|warp|To Magic School Research|-1,-1,042-2.gat,103,62 +042-1.gat,117,102|warp|To Magic School Research|-1,-1,042-2.gat,103,62 042-1.gat,112,95|warp|To Magic School Research|-1,-1,042-2.gat,94,54 042-1.gat,120,95|warp|To Magic School Research|-1,-1,042-2.gat,112,54 042-1.gat,117,85|warp|To Tulismhar Docks|-1,-1,022-1.gat,49,82 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/functions/global_event_handler.txt b/world/map/npc/functions/global_event_handler.txt new file mode 100644 index 00000000..acb328f4 --- /dev/null +++ b/world/map/npc/functions/global_event_handler.txt @@ -0,0 +1,43 @@ +017-9.gat,0,0,0|script|#GlobalHandler|-1,-1,-1, +{ + end; + +OnPCLoginEvent: // this does not work yet but as soon as it is implemented it will start working + callfunc "ClearVariables"; + end; + +OnPCKillEvent: + set Death_Kill, Death_Kill + 1; // this counts the number of players you have killed + end; + +OnPCKilledEvent: + goto L_Fightclub_Killed; // this is used by the 1v1 arena + +OnPCDieEvent: + callfunc "fightclub_GoBack"; // this used by the battle master + goto L_Fightclub_Die; // this is used by the 1v1 arena + +// custom handlers below + +L_Fightclub_Killed: + set @killer, 0; + if(@Duel_Fighter != 1) goto L_End; + if(getmap() != "009-7") goto L_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"; + goto L_End; + +L_Fightclub_Die: + set @killer, 0; + if(@Duel_Fighter != 1) goto L_End; + if(getmap() != "009-7") goto L_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"; + goto L_End; + +L_End: + end; +} diff --git a/world/map/npc/items/check_wand.txt b/world/map/npc/items/check_wand.txt index 4d8016bb..29129eab 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; diff --git a/world/map/npc/scripts.conf b/world/map/npc/scripts.conf index 047d7dbb..d37a8c57 100644 --- a/world/map/npc/scripts.conf +++ b/world/map/npc/scripts.conf @@ -23,6 +23,7 @@ npc: npc/functions/lockpicking.txt npc: npc/functions/default_npc_checks.txt npc: npc/functions/undead_debug.txt npc: npc/functions/headstyles.txt +npc: npc/functions/global_event_handler.txt // Item Functions npc: npc/items/magic_gm_top_hat.txt |