diff options
-rw-r--r-- | db/re/mob_db.conf | 44 | ||||
-rw-r--r-- | npc/001-13/_import.txt | 1 | ||||
-rw-r--r-- | npc/001-13/main.txt | 195 | ||||
-rw-r--r-- | npc/003-1/events.txt | 2 | ||||
-rw-r--r-- | npc/commands/event.txt | 14 | ||||
-rw-r--r-- | npc/functions/aurora.txt | 55 | ||||
-rw-r--r-- | npc/functions/news.txt | 13 | ||||
-rw-r--r-- | npc/functions/soul_menhir.txt | 7 | ||||
-rw-r--r-- | npc/functions/util.txt | 2 |
9 files changed, 327 insertions, 6 deletions
diff --git a/db/re/mob_db.conf b/db/re/mob_db.conf index 2f13cfdfb..959a35571 100644 --- a/db/re/mob_db.conf +++ b/db/re/mob_db.conf @@ -11879,6 +11879,50 @@ mob_db: ( }, // System { + Id: 1491 + SpriteName: "WanderingShadow" + Name: "Wandering Shadow" + Lv: 60 + Hp: 9987 + Sp: 1248 + Exp: 1674 + JExp: 168 + AttackRange: 2 + Attack: [380, 460] + Def: 75 + Mdef: 75 + WalkMask: "WALK_AIR" + Stats: { + Str: 30 + Agi: 60 + Vit: 62 + Int: 0 + Dex: 60 + Luk: 33 + } + ViewRange: 9 + ChaseRange: 14 + Race: 9 + Element: (8, 2) + Mode: { + CanMove: true + Aggressive: true + Angry: true + CanAttack: true + ChangeTargetMelee: true + ChangeChase: true + Boss: true + } + MoveSpeed: 480 + AttackDelay: 1600 + AttackMotion: 672 + DamageMotion: 480 + Drops: { + HastePotion: 500 + StrengthPotion: 500 + } +}, +{ Id: 1492 SpriteName: "Gladiator" Name: "Gladiator" diff --git a/npc/001-13/_import.txt b/npc/001-13/_import.txt index 8f6744511..1ec37b78f 100644 --- a/npc/001-13/_import.txt +++ b/npc/001-13/_import.txt @@ -1,2 +1,3 @@ // Map 001-13: Showdown // This file is generated automatically. All manually added changes will be removed when running the Converter. +"npc/001-13/main.txt", diff --git a/npc/001-13/main.txt b/npc/001-13/main.txt new file mode 100644 index 000000000..1b7e145d1 --- /dev/null +++ b/npc/001-13/main.txt @@ -0,0 +1,195 @@ +// TMW2 Scripts +// Author: +// Jesusalva +// Description: +// Controls boss raid showdown (Freeyorp Event System - Boss Raid) + +function script FYRaid_Select { + if ($EVENT$ != "Raid") return; + sleep2(100); // Anti-flood protection: Hold execution for 100ms + mes l("Current Boss: %s", $RAIDING_BOSS$); + .@id = array_find($FYRAID_OWNER, getcharid(3)); + if (.@id >= 0) { + // Same level (challenge ongoing) + if ($FYRAID_LV[.@id] == FYRAID_LV) { + // Was defeated when you weren't loooking (limited precedence) + if ($FYRAID_HP[.@id] <= 0) { + mesc l("Boss defeated!"), 3; + FYRAID_LV+=1; + $FYRAID_HP[.@id]=0; + Mobpt += FYRAID_LV * 10; + getitem EventNaftalin, FYRAID_LV; + } + // Time is running out + if (gettimetick(2) < $FYRAID_TIME[.@id]) { + mesc l("You found a Level %d %s!", FYRAID_LV, $RAIDING_BOSS$), 2; + mesc l("Time left: %s", FuzzyTime($FYRAID_TIME[.@id])), 1; + } + // Time has expired - free for next boss + if (gettimetick(2) > $FYRAID_TIME[.@id]) { + mesc l("The boss you discovered has ran away!"); + $FYRAID_LV[.@id] = 0; + $FYRAID_HP[.@id] = 0; + $FYRAID_TIME[.@id] = 0; + Mobpt += rand2(FYRAID_LV); + } + } + } + next; + setarray .@opt$, l("Cancel"), -1; + freeloop(true); + // Build menu + for (.@i=0; .@i < getarraysize($FYRAID_OWNER) ; .@i++) { + if ($FYRAID_HP[.@i] <= 0) + continue; + if ($FYRAID_TIME[.@i] < gettimetick(2)) + continue; + .@hp=$FYRAID_HP[.@i]; + .@lv=$FYRAID_LV[.@i]; + .@on=$FYRAID_OWNER[.@i]; + array_push(.@opt$, (.@on == getcharid(3) ? "##B" : "") + l("Level %d (%s HP) (Found by %s)", .@lv, .@hp, strcharinfo(0, l("offline player"), .@on)) + (.@on == getcharid(3) ? "##b" : "")); + array_push(.@opt$, str(.@i)); + } + freeloop(false); + menuint2(.@opt$); + if (@menuret < 0) + return; + // Validate again if the prey is still valid + .@i = @menuret; + if ($FYRAID_HP[.@i] <= 0) { + mesc l("Someone else has already defeated this bounty."); + return; + } + if ($FYRAID_TIME[.@i] < gettimetick(2)) { + mesc l("This bounty has expired."); + return; + } + // Prepare the room (time limit = 3 minutes) + .@inst = instance_create("Showdown "+getcharid(0), getcharid(3), IOT_CHAR); + // Failed + if (.@inst < 0) { + mesc l("You can only try every %d minutes.", 3); + return; + } + // Attach map + .@mp$="fyrb@"+getcharid(0); + instance_attachmap("001-13", .@inst, false, .@mp$); + + // Recreate the boss + .@lv = $FYRAID_HP[.@i]; + .@mob=monster(.@mp$, 47, 33, $RAIDING_BOSS$, WanderingShadow, 1, "sBossRaid::OnBossDie"); + setunitdata(.@mob, UDT_LEVEL, min(.@lv * 10, 200)); + setunitdata(.@mob, UDT_STR, .@lv * 4); + setunitdata(.@mob, UDT_AGI, .@lv * 4); + setunitdata(.@mob, UDT_VIT, .@lv * 5); + setunitdata(.@mob, UDT_INT, .@lv * 2); + setunitdata(.@mob, UDT_DEX, .@lv * 6); + setunitdata(.@mob, UDT_LUK, .@lv * 5); + setunitdata(.@mob, UDT_ADELAY, max(640, 1672-(.@lv * 24))); + setunitdata(.@mob, UDT_MAXHP, 2000+.@lv*1000); + setunitdata(.@mob, UDT_HP, $FYRAID_HP[.@i]); + setunitdata(.@mob, UDT_ATKMIN, 90+.@lv*10); + setunitdata(.@mob, UDT_ATKMAX, 90+.@lv*12); + setunitdata(.@mob, UDT_DEF, 10+.@lv*5); + setunitdata(.@mob, UDT_MDEF, 10+.@lv*3); + setunitdata(.@mob, UDT_HIT, (BaseLevel+.@lv)*45/10); + setunitdata(.@mob, UDT_FLEE, min((BaseLevel+.@lv)*27/10, 750)); + setunitdata(.@mob, UDT_CRIT, rand2(60, min(180, 60+.@lv))); + + // Save some persistent data + @map$=.@mp$; + @id=.@i; + @mb=.@mob; + @tm=gettimetick(2)+180; + + // Good luck! + instance_set_timeout(190, 190, .@inst); + instance_init(.@inst); + warp .@mp$, 47, 52; + addtimer 180000, "sBossRaid::OnTimeout"; + addtimer 60000, "sBossRaid::OnPump"; + dispbottom l("Time left: %s", FuzzyTime(@tm)); + closeclientdialog; + return; +} + +// ------------------------------------------------------------------------------ +- script sBossRaid NPC_HIDDEN,{ + +OnPump: + if (@map$ != getmap()) end; + .@msg$=l("In all the mana worlds, I alone am feared."); + .@lv=$FYRAID_LV[@id]; + + // Apply boss skill based on their name + if ($RAIDING_BOSS$ == "Xakabael the Dark") { + .@msg$ = l("Witness my sublime rain of death. Regeneration!"); + .@hp=getunitdata(@mb, UDT_HP); + .@mp=getunitdata(@mb, UDT_MAXHP); + setunitdata(@mb, UDT_HP, min(.@mp, .@hp+(.@lv * 50))); + } else if ($RAIDING_BOSS$ == "Janeb the Evil") { + .@msg$ = l("Chaos shall be the founding stone of my town! Falling star!"); + percentheal -5, -10; + } else if ($RAIDING_BOSS$ == "Platyna the Red") { + .@msg$ = l("I, the rightful ruler, demand back this world! Tyranny!"); + percentheal -1, -1; + SC_Bonus(10+.@lv, any(SC_BLIND, SC_POISON), 1); + } else if ($RAIDING_BOSS$ == "Benjamin the Frost") { + .@msg$ = l("Stop on your tracks, unfair being! Freeze!"); + SC_Bonus(10+.@lv, any(SC_FREEZE, SC_SLEEP), 1); + } else if ($RAIDING_BOSS$ == "Reid the Terrific") { + .@msg$ = l("There is no free speech. Censorship!"); + SC_Bonus(10+.@lv, SC_SILENCE, 1); + } else if ($RAIDING_BOSS$ == "Nu'Rem the Destroyer") { + .@msg$ = l("And then... There was a quake. And all life died. Bleed!"); + SC_Bonus(10+.@lv, SC_BLOODING, 1); + } else if ($RAIDING_BOSS$ == "Golbenez the Cruel") { + .@msg$ = l("Puny mortal, do your best to entertain me! Curse!"); + SC_Bonus(10+.@lv, SC_CURSE, 1); + } else if ($RAIDING_BOSS$ == "King of Typos") { + .@msg$ = l("The problem with typos is - unpredictable side effects."); + SC_Bonus(10+.@lv, any(SC_SILENCE, SC_CURSE, SC_FREEZE, SC_BLOODING, SC_BLIND, SC_POISON, SC_DPOISON, SC_POISON, SC_BURNING, SC_SLEEP), 1); + } else { + consolewarn("Unknown raiding boss: %s. No skill will be used.", $RAIDING_BOSS$); + } + + unittalk(@mb, .@msg$); + dispbottom l("Time left: %s", FuzzyTime(@tm)); + addtimer 60000, "sBossRaid::OnPump"; + end; + +// Boss defeated +OnBossDie: + dispbottom l("Boss defeated!"); + // Clear bonus + getitem EventNaftalin, $FYRAID_LV[@id]/2+1; + .@new = 0; + goto OnClose; + +// Ran out of time +OnTimeout: + dispbottom l("Time out!"); + .@new = getunitdata(@mb, UDT_HP); + goto OnClose; + +// Warp you back +OnClose: + .@old = $FYRAID_HP[@id]; + .@dmg = .@new - .@old; + // Damage Bonus + if (.@dmg / 1000 > 1) + getitem EventNaftalin, .@dmg / 1000; + + // Record new HP info and give you rewards + $FYRAID_HP[@id] = .@new; + Mobpt += $FYRAID_LV[@id]; + getexp $FYRAID_LV[@id], $FYRAID_LV[@id]/2+1; + + // Send you back + deltimer("sBossRaid::OnPump"); + sleep2(500); + teleporthome(); + end; +} + +001-13 mapflag zone MMO diff --git a/npc/003-1/events.txt b/npc/003-1/events.txt index 5540cc211..6175b9ebd 100644 --- a/npc/003-1/events.txt +++ b/npc/003-1/events.txt @@ -333,6 +333,8 @@ L_Aurora: .@WHAT$=l("candor battle season"); } else if ($EVENT$ == "Tower") { .@WHAT$=l("dream tower apparition"); + } else if ($EVENT$ == "Raid") { + .@WHAT$=l("boss raid"); } mesn; diff --git a/npc/commands/event.txt b/npc/commands/event.txt index 31fd527f2..ba81ca96c 100644 --- a/npc/commands/event.txt +++ b/npc/commands/event.txt @@ -535,11 +535,23 @@ OnEffect: message strcharinfo(0), l("You are now at the Christmas Workshop."); end; } - // FIXME: Dream Tower Warp if ($EVENT$ == "Tower" && countitem(EventDreamTicket)) { doevent "sDreamTower::OnWarpTo"; end; } + if ($EVENT$ == "Raid") { + .@id = array_find($FYRAID_OWNER, getcharid(3)); + if (.@id >= 0) { + if ($FYRAID_TIME[.@id] > gettimetick(2) && + $FYRAID_HP[.@id] > 0) { + teleporthome(); + dispbottom l("Talk to Soul Menhir to start."); + end; + } + // Boss expired or already defeated - ignore + } + // Have not yet taken part on boss raid - ignore + } } // Block here diff --git a/npc/functions/aurora.txt b/npc/functions/aurora.txt index d02f7747c..859bdd48f 100644 --- a/npc/functions/aurora.txt +++ b/npc/functions/aurora.txt @@ -39,6 +39,16 @@ // // $WORLDEXPO_ENEMY$ // Name of the enemy responsible for ruining the World's Expo +// $RAIDING_BOSS$ +// Name of the enemy who is raiding down the world +// $DREAMTOWER_SAGE$ +// Name of the sage who owns the Dream Towers +// DTOWER_DAY (CharReg) +// Player variable which controls Dream Tower reset +// DTOWER_ROLL (CharReg) +// Player variable which controls Dream Ticket drop rate +// DTOWER_FLOOR (CharReg) +// Player variable which controls current Dream Tower floor // AEF: BEGIN @@ -60,9 +70,11 @@ function script FYNewEvent { DelItemFromEveryPlayer(EventOre); DelItemFromEveryPlayer(BrokenMedal); DelItemFromEveryPlayer(EventDreamTicket); + DelItemFromEveryPlayer(EventNaftalin); DelChrRegFromEveryPlayer(DTOWER_DAY); DelChrRegFromEveryPlayer(DTOWER_ROLL); DelChrRegFromEveryPlayer(DTOWER_FLOOR); + DelChrRegFromEveryPlayer(FYRAID_LV); // Select the event switch ($FYEVENT_CYCLE % 12) { case 1: @@ -122,7 +134,6 @@ function script FYNewEvent { kamibroadcast("Candor Battle Season is now open!", "Aurora Events"); break; default: - // FIXME: PLACEHOLDER $EVENT$="Tower"; callfunc("FYEConf_Tower"); kamibroadcast("Dream Towers have appeared!", "Aurora Events"); @@ -394,6 +405,40 @@ function script FYE_Tower1 { +// Configure Boss Raid +function script FYEConf_Raid { + $RAIDING_BOSS$=any("Xakabael the Dark", "Janeb the Evil", "Platyna the Red", "Benjamin the Frost", "Reid the Terrific", "Nu'Rem the Destroyer", "Golbenez the Cruel", "King of Typos"); + deletearray $FYRAID_OWNER; + deletearray $FYRAID_TIME; + deletearray $FYRAID_HP; + deletearray $FYRAID_LV; + setarray $FYREWARD_PT, 10, 25, 50, 100, 150, + 200, 300, 500, 750, 1000, + 1250, 1500, 1750, 2000, 2500, + 3000, 3500, 4000, 5000, 6000, + 7500, 9000, 11000, 15000, 20000, + 25000, 30000, 35000, 40000, 50000; + // PS. Max Est. ? + + FYE_Autoset(); + $FYLOGIN_PTS=rand2(1, 2); + return; +} + +// Boss Raid Appears! +function script FYE_Raid { + .@mob=getarg(0, killedrid); + // Obtain the monster level and roll a hidden counter + .@lv=getmonsterinfo(.@mob, MOB_LV); + DTOWER_ROLL+=.@lv; + return; +} + + + + + + // Configure Fishing function script FYEConf_Fishing { @@ -504,6 +549,12 @@ function script FYE_Submit { setq2 Q_AuroraEvent, .@pts; delitem BrokenMedal, countitem(BrokenMedal); + } else if ($EVENT$ == "Raid") { + // .:: BOSS RAID ::. + .@pts+=countitem(EventNaftalin)*1; + + setq2 Q_AuroraEvent, .@pts; + delitem EventNaftalin, countitem(EventNaftalin); } else { // Wut? This is not an Aurora Event Exception($EVENT$+" is NOT a valid Aurora Event; Misdefinition.\n\nPlease ensure that it is defined in utils, aurora, news, and command/event.\n\nFYE_Submit - FYEventUsesRanking - FYE_* - FYEConf_* - FYStopEvent", RB_DEFAULT|RB_ISFATAL); @@ -518,7 +569,7 @@ function script FYE_Submit { // Stops any Aurora Event function script FYStopEvent { - setarray .@av$, "Kamelot", "Regnum", "Expo", "Fishing", "Candor", "Mining", "Tower"; + setarray .@av$, "Kamelot", "Regnum", "Expo", "Fishing", "Candor", "Mining", "Tower", "Raid"; if (array_find(.@av$, $EVENT$) >= 0) { sClear(); $EVENT$=""; diff --git a/npc/functions/news.txt b/npc/functions/news.txt index ab5be1b52..1b1e51ae2 100644 --- a/npc/functions/news.txt +++ b/npc/functions/news.txt @@ -288,13 +288,24 @@ function script EventHelp { mes l("The dream towers have shown up. They have several floors filled with treasure and dangerous monsters."); mes l("Every day, they disappear and a new one shows up on its place."); mes ""; - mes l("You need a %s for each floor, and defeat the gatekeeper to advance.", "Dream Ticket"); + mes l("You need a %s for each floor, and defeat the gatekeeper to advance.", getitemlink(EventDreamTicket)); mes l("Floors cannot be re-visited, and rewards increase at each floor."); mes ""; mes l("These towers must hold unfathomable secrets from %s.", $DREAMTOWER_SAGE$); mes l("We must find out what lies at the top, whatever the cost!"); mesc l("Location: The Mana Plane, Dream Tower"), 3; ///////////////////////////////////////////////////////////////////////// + } else if ($EVENT$ == "Raid") { + mesc ".:: " + l("Boss Raid") + " ::.", 2; + mes ""; + mes l("This is terrible - a fiend from a parallel dimension has broken in ours!"); + mes l("We are unsure of the cause, but they must be repelled at any cost!"); + mes l("Meanwhile, the sages of destiny will prepare a way to kick them back to wherever they belong!"); + mes ""; + mes l("Can we keep %s at bay long enough?", $RAIDING_BOSS$); + mes l("Collect their %s as well, so our wizards can do their magic!", getitemlink(EventNaftalin)); + mesc l("Location: The Mana Plane, Showdown Chamber"), 3; + ///////////////////////////////////////////////////////////////////////// } else { mesc l("There's no help available for this event."); ///////////////////////////////////////////////////////////////////////// diff --git a/npc/functions/soul_menhir.txt b/npc/functions/soul_menhir.txt index 2b2b1a897..92fd8b688 100644 --- a/npc/functions/soul_menhir.txt +++ b/npc/functions/soul_menhir.txt @@ -22,6 +22,7 @@ function script SoulMenhir { rif($EVENT$ == "Worker", l("[Worker Day] Send soul to the Contributor Cave!")), L_Worker, rif($EVENT$ == "Christmas" && BaseLevel >= 20, l("[Christmas] Send soul to the Christmas Workshop!")), L_Xmas, // TODO: In future there'll be an event map rif($EVENT$ == "Tower" && countitem(EventDreamTicket), l("Dream Tower")), L_Tower, + rif($EVENT$ == "Raid", l("Boss Raid")), L_Raid, l("Leave it alone."), -; return; @@ -92,13 +93,17 @@ L_Xmas: message strcharinfo(0), l("You are now at the Christmas Workshop."); close; -// FIXME: Dream Tower Warp L_Tower: if ($EVENT$ != "Tower") goto L_DontPanic; if (!countitem(EventDreamTicket)) goto L_DontPanic; doevent "sDreamTower::OnWarpTo"; close; +L_Raid: + if ($EVENT$ != "Raid") goto L_DontPanic; + callfunc("FYRaid_Select"); + close; + L_DontPanic: message strcharinfo(0), l("(A strange barrier keeps you from touching the stone at this time.)"); return; diff --git a/npc/functions/util.txt b/npc/functions/util.txt index abcbfc903..f64383b69 100644 --- a/npc/functions/util.txt +++ b/npc/functions/util.txt @@ -662,7 +662,7 @@ function script islegendary { // Returns if an event is a ranked Aurora Event or not // (Had to be moved from functions/aurora.txt) function script FYEventUsesRanking { - setarray .@av$, "Expo", "Fishing", "Mining", "Tower"; + setarray .@av$, "Expo", "Fishing", "Mining", "Tower", "Raid"; if (array_find(.@av$, $EVENT$) >= 0) { return true; } |