diff options
author | Jesusaves <cpntb1@ymail.com> | 2022-10-23 21:44:22 -0300 |
---|---|---|
committer | Jesusaves <cpntb1@ymail.com> | 2022-10-23 21:44:22 -0300 |
commit | a7c45a192268da2601cef47a4cdba987ae2327ca (patch) | |
tree | c5fb5b97db109fe7106496dd96498c475881046b /npc/025-1 | |
download | serverdata-a7c45a192268da2601cef47a4cdba987ae2327ca.tar.gz serverdata-a7c45a192268da2601cef47a4cdba987ae2327ca.tar.bz2 serverdata-a7c45a192268da2601cef47a4cdba987ae2327ca.tar.xz serverdata-a7c45a192268da2601cef47a4cdba987ae2327ca.zip |
Initial commit (Moubootaur Legends fork)
Diffstat (limited to 'npc/025-1')
-rw-r--r-- | npc/025-1/_config.txt | 25 | ||||
-rw-r--r-- | npc/025-1/_import.txt | 17 | ||||
-rw-r--r-- | npc/025-1/_mobs.txt | 13 | ||||
-rw-r--r-- | npc/025-1/_warps.txt | 3 | ||||
-rw-r--r-- | npc/025-1/anin.txt | 79 | ||||
-rw-r--r-- | npc/025-1/commander.txt | 253 | ||||
-rw-r--r-- | npc/025-1/ctrl.c | 572 | ||||
-rw-r--r-- | npc/025-1/drahcir.txt | 16 | ||||
-rw-r--r-- | npc/025-1/ihclot.txt | 148 | ||||
-rw-r--r-- | npc/025-1/phoenix.txt | 230 | ||||
-rw-r--r-- | npc/025-1/rum.txt | 181 | ||||
-rw-r--r-- | npc/025-1/salohcin.txt | 55 | ||||
-rw-r--r-- | npc/025-1/selim.txt | 81 | ||||
-rw-r--r-- | npc/025-1/teleporter.txt | 23 | ||||
-rw-r--r-- | npc/025-1/xovilam.txt | 47 | ||||
-rw-r--r-- | npc/025-1/yuko.txt | 71 |
16 files changed, 1814 insertions, 0 deletions
diff --git a/npc/025-1/_config.txt b/npc/025-1/_config.txt new file mode 100644 index 0000000..915bd51 --- /dev/null +++ b/npc/025-1/_config.txt @@ -0,0 +1,25 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 025-1: Fortress Town - Holy Land conf + +025-1,99,112,0 script #025-1_99_112 NPC_HIDDEN,{ + end; +OnDisable: + delcells "025-1_99_112"; end; +OnEnable: +OnInit: + setcells "025-1", 99, 112, 100, 112, 1, "025-1_99_112"; +} + +025-1,100,122,0 script #025-1_100_122 NPC_HIDDEN,7,0,{ + end; +OnTouch: + doevent "#DungeonCore::OnCurse"; + end; +} + +025-1,100,22,0 script #025-1_100_22 NPC_HIDDEN,3,0,{ + end; +OnTouch: + doevent "#DungeonCore::OnCurse"; + end; +} diff --git a/npc/025-1/_import.txt b/npc/025-1/_import.txt new file mode 100644 index 0000000..c373e04 --- /dev/null +++ b/npc/025-1/_import.txt @@ -0,0 +1,17 @@ +// Map 025-1: Fortress Town - Holy Land +// This file is generated automatically. All manually added changes will be removed when running the Converter. +"npc/025-1/_config.txt", +"npc/025-1/_mobs.txt", +"npc/025-1/_warps.txt", +"npc/025-1/anin.txt", +"npc/025-1/commander.txt", +"npc/025-1/ctrl.c", +"npc/025-1/drahcir.txt", +"npc/025-1/ihclot.txt", +"npc/025-1/phoenix.txt", +"npc/025-1/rum.txt", +"npc/025-1/salohcin.txt", +"npc/025-1/selim.txt", +"npc/025-1/teleporter.txt", +"npc/025-1/xovilam.txt", +"npc/025-1/yuko.txt", diff --git a/npc/025-1/_mobs.txt b/npc/025-1/_mobs.txt new file mode 100644 index 0000000..5de3a35 --- /dev/null +++ b/npc/025-1/_mobs.txt @@ -0,0 +1,13 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 025-1: Fortress Town - Holy Land mobs +025-1,39,96,15,6 monster Moubi 1038,6,60000,30000 +025-1,35,41,10,15 monster Moubi 1038,6,60000,30000 +025-1,78,33,12,11 monster Croc 1006,6,60000,30000 +025-1,120,30,12,8 monster Moubi 1038,6,60000,30000 +025-1,136,30,1,8 monster Croc 1006,6,60000,30000 +025-1,142,77,7,11 monster Croc 1006,6,60000,30000 +025-1,161,86,11,15 monster Moubi 1038,6,60000,30000 +025-1,79,97,12,6 monster Croc 1006,6,60000,30000 +025-1,42,115,15,4 monster Croc 1006,6,60000,30000 +025-1,45,116,20,3 monster Croc 1006,6,60000,30000 +025-1,154,116,20,3 monster Croc 1006,6,60000,30000 diff --git a/npc/025-1/_warps.txt b/npc/025-1/_warps.txt new file mode 100644 index 0000000..b2ec269 --- /dev/null +++ b/npc/025-1/_warps.txt @@ -0,0 +1,3 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 025-1: Fortress Town - Holy Land warps +025-1,100,123,0 warp #025-1_100_123 7,0,025-2,99,25 diff --git a/npc/025-1/anin.txt b/npc/025-1/anin.txt new file mode 100644 index 0000000..5b4cd96 --- /dev/null +++ b/npc/025-1/anin.txt @@ -0,0 +1,79 @@ +// TMW2 scripts. +// Author: +// Jesusalva +// Description: +// Anin is Nina spelled backwards + +025-1,109,71,0 script Anin The Traveler NPC_F_COINKEEPER,{ + + mesn; + if (strcharinfo(0) == $MOST_HEROIC$) mesq l("Wow! Are you @@? Everyone, in every city, talks about you!", $MOST_HEROIC$); + if (strcharinfo(0) == $MOST_HEROIC$) next; + + mesq l("Hello. I am @@, and I am from a family of travellers. We travel though the whole world, looking for exotic goods.", .name$); + next; + mesq l("You can buy rare items with me, or I can tell you about different cities in our world."); + +L_Menu: + mes ""; + menu + l("I want to trade with you."), L_Trade, + l("Tell me about Tulimshar."), L_Tulim, + l("Tell me about Fortress Town."), L_Town, + l("Sorry, I'll pass."), L_Close; + +L_Tulim: + mes ""; + mesn; + mesq l("Tulimshar is the oldest human city, and its foundation is the year zero of our calendar."); + next; + mesq l("The city only flourished because Janett Platinum had the idea to build city walls surrounding this city."); + next; + mesq l("The desert climate means you'll find mostly maggots and scorpions. Their drops include cactus drinks, cake, knifes, black pearls, gold, and other common things."); + next; + mesq l("You can find for a good price desert equipment and some kind of dyes. You find all sort of crafters, artisans and warriors here."); + next; + goto L_Menu; + +L_Town: + mes ""; + mesn; + mesq l("Fortress Town is connected to the prophecies of the death of all humans, wildlife, and the other lesser races."); + next; + mesq l("The World's Heart was shattered by the Ancient Families to serve as Soul Menhirs on the world, and this allows respawning after death, but at a cost."); + next; + mesq l("The World Edge, which is where we are, is a holy land, the place where all began and all shall perish. Which is why after the World's Heart was broken, it was vowed to never make a settlement here ever again."); + next; + mesq l("Right now this territory is under the Monster Army's control, but the Alliance has occupied it to raid the Impregnable Fortress."); + next; + mesq l("Nearly everyone around is a seasoned veteran or was sent here by the Alliance Council to support the war efforts. Including me. So, good luck!"); + next; + goto L_Menu; + + +L_Trade: + mesn; + mesq l("Use your @@ as currency!", getitemlink(StrangeCoin)); + tutmes l("%s is obtained during events, daily logins, heroic deeds, gifts, etc. But cannot be bought with real money.", getitemlink(StrangeCoin)); + next; + openshop "Aeros Trader"; + closedialog; + +L_Close: + close; + +OnInit: + .@npcId = getnpcid(.name$); + setunitdata(.@npcId, UDT_HEADTOP, NPCEyes); + setunitdata(.@npcId, UDT_HEADMIDDLE, UglyChristmasSweater); + setunitdata(.@npcId, UDT_HEADBOTTOM, JeansShorts); + setunitdata(.@npcId, UDT_WEAPON, CandorBoots); // Boots + setunitdata(.@npcId, UDT_HAIRSTYLE, 27); + setunitdata(.@npcId, UDT_HAIRCOLOR, 11); + npcsit; + + .sex = G_FEMALE; + .distance = 5; + end; +} + diff --git a/npc/025-1/commander.txt b/npc/025-1/commander.txt new file mode 100644 index 0000000..891c79d --- /dev/null +++ b/npc/025-1/commander.txt @@ -0,0 +1,253 @@ +// TMW2 scripts. +// Author: +// Jesusalva +// Description: +// Leads the Alliance in the Fortress Town + +025-1,96,26,0 script Commander Povo NPC_BRGUARD_SPEAR,{ + mesn; + mesq l("Greetings %s, I am %s, the man in charge for the Alliance occupation of Fortress Town.", (strcharinfo(0) == $MOST_HEROIC$ ? lg("Hero") : lg("Adventurer")), .name$); + next; + if (BARBARA_STATE == 2) { + inventoryplace NPCEyes, 1; + mesn; + mesq l("Sir Pyndragon and Lady Lalica asked to thank thee for the situation with the thief."); + next; + mesn; + mesq l("Therefore, please choose a permanent stat-boosting fruit."); + next; + menuint + l("I'll decide later"), 0, + l("Strength"), StrengthFruit, + l("Agility"), AgilityFruit, + l("Vitality"), VitalityFruit, + l("Intelligence"), IntelligenceFruit, + l("Dexterity"), DexterityFruit, + l("Luck"), LuckFruit; + mes ""; + if (@menuret) { + getitembound @menuret, 1, 4; + BARBARA_STATE += 10; + getexp 0, 250; + mesn; + mesq l("Here you go. Please, keep fighting and growing strong. Improving oneself is... Damn, I forgot the proverb."); + next; + } + } + + // Endtrail + mes ""; + mesc l("@@ You need to wait further releases to continue this quest!", b(l("WARNING:"))), 1; + close; + +OnInit: + .sex = G_MALE; + .distance = 5; + end; +} + +///////////////////////////////////////////////////////////////////////////////// +025-1,59,86,0 script Commander Cadis NPC_BRGUARD_SWORD,{ + function cadisReward; + mesn; + mesq l("Greetings %s, I am %s, I am in charge of monster extermination.", (strcharinfo(0) == $MOST_HEROIC$ ? lg("Hero") : lg("Adventurer")), .name$); + next; + // Check for ongoing quests + if (getq(FortressQuest_SlimeHunter) == 1) + goto L_SlimeHunter; + if (getq(FortressQuest_Over100) == 1) + goto L_Over100; + if (getq(FortressQuest_RangedHunt) == 1) + goto L_RangedHunt; + mesn; + mesq l("I have extremely difficult quests for you; They are more painful than a Grand Hunter Quest, because I don't admit wimps fighting with me."); + next; + mesn; + mesq l("You will be rewarded by me shall you succeed in any of the tasks."); + mesc l("%s: Once accepted, you must complete them before taking another one.", b(l("WARNING"))); + // Well, we *could* make it more GHQ-like but lazy devs are lazy. + next; + do + { + select + l("I'm not interested."), + rif(!getq(FortressQuest_SlimeHunter), l("The Great Slime Hunt")), + rif(!getq(FortressQuest_Over100), l("The Great Over 100 Hunt")), + rif(!getq(FortressQuest_RangedHunt), l("The Great Ranged Hunt")); + mes ""; + switch (@menu) { + case 1: + close; + case 2: + mesn; + mesq l("You'll have to slay %s %s for me! I don't care which ones, just SLAY THEM!", fnum(.million), l("slimes")); + next; + select + l("Accept"), + l("Reject"); + mes ""; + if (@menu == 1) { + setq1 FortressQuest_SlimeHunter, 1; + mesn; + mesq l("Then get to work already!"); + close; + } + break; + case 3: + mesn; + mesq l("You'll have to slay %s %s for me! I don't care which ones, just SLAY THEM!", fnum(.million), l("monsters of at least level 100")); + mesc l("Each monster will be counted as %d kills.", 2); + next; + select + l("Accept"), + l("Reject"); + mes ""; + if (@menu == 1) { + setq1 FortressQuest_Over100, 1; + mesn; + mesq l("Then get to work already!"); + close; + } + break; + case 4: + mesn; + mesq l("You'll have to slay %s %s for me! I don't care which ones, just SLAY THEM!", fnum(.million), l("ranged monsters")); + mesc l("Minimum range: %d", 3); + next; + select + l("Accept"), + l("Reject"); + mes ""; + if (@menu == 1) { + setq1 FortressQuest_RangedHunt, 1; + mesn; + mesq l("Then get to work already!"); + close; + } + break; + } + } while (true); + close; + +L_SlimeHunter: + cadisReward(FortressQuest_SlimeHunter, l("Slimes")); + close; + +L_Over100: + cadisReward(FortressQuest_Over100, l("over 100 mobs")); + close; + +L_RangedHunt: + cadisReward(FortressQuest_RangedHunt, l("ranged mobs")); + close; + +function cadisReward { + .@kill=getq2(getarg(0)); + .@rewa=getq3(getarg(0)); + mesn; + mesq l("Thus far you've slain %s/%s %s for me!", fnum(.@kill), fnum(.million), b(getarg(1, "monsters"))); + inventoryplace NPCEyes, 4, Iten, 2; + + // ***** ***** ***** Rewards ***** ***** ***** + if (.@kill >= .tier1 && .@rewa < 1) { + mesc l("Milestone reached: %s kills", fnum(.tier1)); + setq3 getarg(0), 1; + getitem MercenaryBoxsetDD, 3; + getitem SacredImmortalityPotion, 2; + getitem MercenaryBoxsetE, 1; + } + + if (.@kill >= .tier2 && .@rewa < 2) { + mesc l("Milestone reached: %s kills", fnum(.tier2)); + setq3 getarg(0), 2; + getitem MercenaryBoxsetEE, 1; + getitem MagicApple, 1; + getitem EquipmentBlueprintE, 1; + getitem IridiumOre, 2; + } + + if (.@kill >= .tier3 && .@rewa < 3) { + mesc l("Milestone reached: %s kills", fnum(.tier3)); + setq3 getarg(0), 3; + getitem MercenaryBoxsetEE, 2; + getitem StrangeCoin, 50; + getitem EarthPowder, 2; + getitem PlatinumOre, 1; + } + + if (.@kill >= .tier4 && .@rewa < 4) { + mesc l("Milestone reached: %s kills", fnum(.tier4)); + setq3 getarg(0), 4; + getitem MercenaryBoxsetEE, 3; + getitem ElixirOfLife, 5; + getitem EarthPowder, 2; + getitem PlatinumOre, 1; + } + + + // Quest complete + if (.@kill >= .million) { + mesc b(l("Quest complete: Congratulations!")), 3; + setq1 getarg(0), 2; + setq3 getarg(0), 5; + getitem MercenaryBoxsetEE, 5; + getitem StrangeCoin, 100; + getitem EarthPowder, 3; + getitem any(LuckFruit, DexterityFruit, IntelligenceFruit, VitalityFruit, AgilityFruit, StrengthFruit), 1; + getitem MysteriousFruit, 1; + } + return; +} + +OnInit: + .sex = G_MALE; + .distance = 5; + .million = 1000000; + + .tier1 = 10000; + .tier2 = 50000; + .tier3 = 250000; + .tier4 = 500000; + end; +} + +// Commander Cadis Questcheck +function script CadisQuestCheck { + if (!playerattached()) + return; + + .@mobId=getarg(0, killedrid); + + if (getq(FortressQuest_SlimeHunter) == 1) { + // Register the kill + if (compare("slime", strtolower(strmobinfo(1, .@mobId)))) { + setq2 FortressQuest_SlimeHunter, getq2(FortressQuest_SlimeHunter)+1; + // Report every 1000 kills + if (getq2(FortressQuest_SlimeHunter) % 1000 == 0) + dispbottom l("Cadis : You have slain %s %s out of a million.", fnum(getq2(FortressQuest_SlimeHunter)), l("slimes")); + } + } + + if (getq(FortressQuest_Over100) == 1) { + // Register the kill as doubled (to make easier) + if (getmonsterinfo(.@mobId, MOB_LV) >= 100) { + setq2 FortressQuest_Over100, getq2(FortressQuest_Over100)+2; + // Report every 1000 kills + if (getq2(FortressQuest_Over100) % 1000 == 0) + dispbottom l("Cadis : You have slain %s %s out of a million.", fnum(getq2(FortressQuest_SlimeHunter)), l("mobs over lv 100")); + } + } + + if (getq(FortressQuest_RangedHunt) == 1) { + // Register the kill + if (getmonsterinfo(.@mobId, MOB_RANGE) >= 3) { + setq2 FortressQuest_RangedHunt, getq2(FortressQuest_RangedHunt)+1; + // Report every 1000 kills + if (getq2(FortressQuest_RangedHunt) % 1000 == 0) + dispbottom l("Cadis : You have slain %s %s out of a million.", fnum(getq2(FortressQuest_SlimeHunter)), l("ranged mobs")); + } + } + + return; +} + diff --git a/npc/025-1/ctrl.c b/npc/025-1/ctrl.c new file mode 100644 index 0000000..7b1d768 --- /dev/null +++ b/npc/025-1/ctrl.c @@ -0,0 +1,572 @@ +// TMW2 Script +// Notes: The Monster King will retake the town every +// OnTue0000 +// (Tuesday, midnight) +// Only the world hero may begin a siege. +// Only one siege per day is allowed +// Writes to MK Temp Var. This variable will unlock the castle gates +// Then the inner gates, and finally, will be a co-requisite to the floors +// Variables: +// $FORTRESS_STATE = int +// 0 - Locked +// 1 - Unlocked +// $@FORTRESS_STATUE = bitmask +// 1,2,4,8,16 - broken statues +// 1024 - Fortress Gate +// 2048 - Siege started +// 4096 - Governor was spawned +// $@FORT_BLACKLIST = int array +// Char ID which already raided this week + +// MAPFLAGS +025-1 mapflag zone SuperMMO +025-3 mapflag zone SuperMMO +026-0 mapflag zone SuperMMO +026-1 mapflag zone SuperMMO +026-2 mapflag zone SuperMMO + +///////////////////////////////////////// +// FUNCTIONS + +// FTCleanup(status) +function script FTCleanup { + // Kills whatever called this function if time is wrong + if ($GAME_STORYLINE < 3) + end; + // Reset variables + $FORTRESS_STATE=getarg(0); + $@FORTRESS_STATUE=0; + // Enable the Magic Statues + enablenpc "Magic Statue#1"; + enablenpc "Magic Statue#2"; + enablenpc "Magic Statue#4"; + enablenpc "Magic Statue#8"; + enablenpc "Magic Statue#16"; + // Kill stray monsters (including town gate) + killmonsterall("025-1"); + // Main gate + if ($FORTRESS_STATE) { + hideonnpc "Gate#F"; + enablenpc "Yuko"; + enablenpc "Ihclot"; + enablenpc "Salohnic"; + enablenpc "Xovilam"; + enablenpc "Drahcir"; + enablenpc "Selim"; + enablenpc "Rum Barrel"; + enablenpc "Commander Povo"; + enablenpc "Commander Cadis"; + enablenpc "Phoenix Rebirth"; + enablenpc "Anin The Traveler"; + enablenpc "The Impregnable Fortress"; + enablenpc "#025-3_100_179"; + donpcevent "#025-1_99_112::OnDisable"; + deletearray $@FORT_BLACKLIST; + } else { + hideoffnpc "Gate#F"; + disablenpc "Yuko"; + disablenpc "Ihclot"; + disablenpc "Salohnic"; + disablenpc "Xovilam"; + disablenpc "Drahcir"; + disablenpc "Selim"; + disablenpc "Rum Barrel"; + disablenpc "Commander Povo"; + disablenpc "Commander Cadis"; + disablenpc "Phoenix Rebirth"; + disablenpc "Anin The Traveler"; + disablenpc "The Impregnable Fortress"; + disablenpc "#025-3_100_179"; + donpcevent "#025-1_99_112::OnEnable"; + mapwarp("025-1", "025-2", 100, 27); + } + enablenpc "#025-1_100_123"; + return; +} + +// FTStatue(id) +function script FTStatue { + .@id=getarg(0); + mesn l("Magic Statue"); + mes l("There is a reading: The Mana Source. The Moubootaur. The Monster King."); + mes l("The war. The blood. The inspiration. The mana. The world. The defiance."); + mes l("The guard. The heir. The originals. The races. The later. The seal."); + mes l("The fragments. The war. The Terranite. AEGIS MAGNA PROTECTIVE SCUTUM."); + next; + mesc l("It seems to be a defensive spell."); + if ($FORTRESS_STATE) + return false; + + // Break the statues? + mesc l("Break the Statue?"), 1; + if (!islegendary()) + mesc l("* May stun you for 10 seconds!"); + next; + if (askyesno() == ASK_YES) { + if ($@FORTRESS_STATUE & .@id) + return false; + if (!islegendary()) + sc_start SC_STUN, 10000, 1; + doevent("Gate#F::OnStatueBreach"); + mapannounce("025-1", strcharinfo(0)+" has broken a statue!", bc_map); + $@FORTRESS_STATUE=$@FORTRESS_STATUE|.@id; + return true; + } + + return false; +} + + + + + + + + + + + + +///////////////////////////////////////// +// NPC SCRIPTS + +// Main gate - Also where the World Hero can begin the siege +025-1,99,112,0 script Gate#F NPC_NO_SPRITE,{ + function spawnMob; + function spawnCore; + // Main Story block - WHAT + if ($GAME_STORYLINE < 3) + die(); + // Still open + if ($FORTRESS_STATE) + end; + // Siege ongoing + if ($@FORTRESS_STATUE) + end; + // Only World Hero may interact + if (strcharinfo(0) != $MOST_HEROIC$ && !is_master()) { + dispbottom l("I will not assault the Fortress Island by myself. Instead, I'll wait for %s.", $MOST_HEROIC$); + end; + } + + // Hey, you can assault the town! + mesc ".:: "+l("THE FORTRESS ISLAND TOWN") + " ::.", 1; + mes l("Behind this gate, lies the Fortress Island Town."); + next; + mesc ".:: "+l("THE FORTRESS ISLAND TOWN") + " ::.", 1; + mesc l("Assault?"), 1; + mes l("* Ensure you and your team is ready and at their positions."); + next; + select + l("Not now."), + l("Information"), + l("Bring it on, we're ready!"); + mes ""; + if (@menu == 1) { + close; + } else if (@menu == 2) { + mesc l("* The siege resets at Tuesday 00:00"); + mesc l("* Sieges increase in difficulty as they are won"); + mesc l("* Unlike monster sieges, the difficulty does not fluctuates based on nº of players or their level!"); + dnext; + mesc l("* The warp to this map will be suspended until the siege is finished."); + mesc l("* The town is liberated once the Monster Governor is slain."); + mesc l("* Monster Governor will only show up when the town magic shield is broken."); + mesc l("* Monster Governor gives 500,000 exp and 100,000 jexp to whoever deals most damage to it"); + dnext; + mesc l("* All monsters in the town and Impregnable Fortress give +25%% EXP"); + mesc l("* You cannot teleport in the town."); + mesc l("* This is a Cursed Lands map, watch out for MP during the fights as well"); + mesc l("* The siege is lost if all players die."); + mesc l("* Only one attempt can be made per day."); + close; + } + + // FIRE THE EVENT + hideonnpc "Gate#F"; + disablenpc "#025-1_100_123"; + initnpctimer; + + // Reset variables + $@FORTRESS_STATUE=2048; + + // Spawn the gate + .@g=monster("025-1", 99, 113, strmobinfo(1, FortressGate), FortressGate, 1, "Gate#F::OnSesame"); + .@bhp=getunitdata(.@g, UDT_MAXHP); + .@bhp=.@bhp*(25+$MK_TEMPVAR)/25; // +4% per success or 8,000 HP + setunitdata(.@g, UDT_MAXHP, .@bhp); + setunitdata(.@g, UDT_HP, .@bhp); + + // Initial defending waves + spawnCore(true); + spawnCore(false); + + // Front Gate Guardians (Lv 70~80) + getmapxy(.@m$, .@x, .@y, 0); + .@x1=.@x-5; + .@x2=.@x+5; + .@y1=.@y-5; + .@y2=.@y+5; + for (.@i = 0; .@i < 4; ++.@i) { + spawnMob(any(AzulSkullSlime, YellowSkullSlime, Forain, GreenDragon, Michel, EliteDuck, Troll, Moonshroom, Terranite), .@x1, .@y1, .@x2, .@y2); + } + + // Player blacklist (unable to use 025-2 warp) + maptimer2("025-1", 10, "Gate#F::OnMPBlacklist"); + kamibroadcast($MOST_HEROIC$+"'s team has begun a siege on Fortress Town. Will they prevail?"); + close; + +///////////////////////////////////////////////////////// +OnSesame: + debugmes("[INFO] FORTRESS TOWN WAS BREACHED"); + $@FORTRESS_STATUE = $@FORTRESS_STATUE|1024; + donpcevent "#025-1_99_112::OnDisable"; + kamibroadcast("The Fortress Town Gate has been breached!"); + spawnCore(true); + close; + +// Heartbeat (B1) +OnTimer35000: + if ($FORTRESS_STATE) + end; + .@breach=($@FORTRESS_STATUE & 1024); + if (mobcount("025-1", "all") < (.@breach ? 180 : 90)) + spawnCore(.@breach); + end; + +// Heartbeat (B2) +OnTimer70000: + if ($FORTRESS_STATE) + end; + + // Initial variables + .@breach=($@FORTRESS_STATUE & 1024); + .@ppl=getmapusers("025-1"); + + // Fail condition + if (.@ppl <= 0) { + kamibroadcast("Players failed to conquer the Fortress Island!"); + FTCleanup($FORTRESS_STATE); + end; + } + + // Spawn mobs + spawnCore(.@breach); + + // Summon reinforcements + maptimer2("025-1", 10, "Gate#F::OnMPReinforce"); + + // Restart timer + initnpctimer; + end; +///////////////////////////////////////////////////////// +OnMPBlacklist: + array_push($@FORT_BLACKLIST, getcharid(0)); + goto OnMPReinforce; + +OnMPReinforce: + // Dispose dead bodies + if (ispcdead() || getmap() != "025-1") { + warp "025-2", 96, 25; + end; + } + // Summon allies + // Last a whole minute + summon("Allied Guard", any(FallenGuard1, FallenGuard2, FallenGuard3)); + end; + +///////////////////////////////////////////////////////// +OnStatueBreach: + spawnCore(true); + getmapxy(.@m$, .@x, .@y, 0); + .@x1=.@x-5; + .@x2=.@x+5; + .@y1=.@y-5; + .@y2=.@y+5; + // Statue Guardians (Lv 70~90) + for (.@i = 0; .@i < 5; ++.@i) { + spawnMob(any(AzulSkullSlime, YellowSkullSlime, Forain, GreenDragon, Michel, EliteDuck, Troll, Moonshroom, Terranite, JackO, BlackMamba, Centaur, GoboBear, TerraniteProtector), .@x1, .@y1, .@x2, .@y2); + } + // Maybe spawn monster governor + if ( + ($@FORTRESS_STATUE & 1) && + ($@FORTRESS_STATUE & 2) && + ($@FORTRESS_STATUE & 4) && + ($@FORTRESS_STATUE & 8) && + ($@FORTRESS_STATUE & 16)) { + // The monster Governor shall now make their appearance! + spawnCore(true); + .@x1=97; + .@y1=21; + .@x2=102; + .@y2=25; + // Governor's Personal Bodyguard (Lv 90~110) + for (.@i = 0; .@i < 4; ++.@i) { + spawnMob(any(TerraniteProtector, LavaSkullSlime, VanityPixie, HolyPixie, ShadowPixie, NulityPixie, BlackSkullSlime, Reaper, NightmareDragon, WhirlyBird, PinkieSuseran), .@x1, .@y1, .@x2, .@y2); + } + .@mob=monster("025-1", any(99, 100), any(22, 23, 24), "Monster Governor", MonsterGeneral, 1, "Gate#F::OnConquest"); + // Stat and Strengthen the governor + // Set governor metadata + setunitdata(.@mob, UDT_LEVEL, 100+$MK_TEMPVAR); + // Update monster modes + .@opt=getunitdata(.@mob, UDT_MODE); + .@opt=.@opt|MD_AGGRESSIVE; + .@opt=.@opt|MD_BOSS; + .@opt=.@opt|MD_NOKNOCKBACK; + setunitdata(.@mob, UDT_MODE, .@opt); + setunitdata(.@mob, UDT_RACE, RC_Legendary); + // Increase health in 2% per siege + .@bhp=75000; + .@bhp=.@bhp*(50+$MK_TEMPVAR)/50; + setunitdata(.@mob, UDT_MAXHP, .@bhp); + setunitdata(.@mob, UDT_HP, .@bhp); + // Accuracy is very very high, immune to crits, always crit + setunitdata(.@mob, UDT_HIT, 9999); + setunitdata(.@mob, UDT_LUK, 65535); + // Increase damage in 1% per siege (remember crit) + .@atk=320; + .@atk=.@atk*(100+$MK_TEMPVAR)/100; + setunitdata(.@mob, UDT_ATKMIN, .@atk); + setunitdata(.@mob, UDT_ATKMAX, .@atk); + // Ranged monster + setunitdata(.@mob, UDT_ATKRANGE, 8); + // Increase defenses in 0.5% per siege + .@def=getunitdata(.@mob, UDT_DEF); + .@def=.@def*(200+$MK_TEMPVAR)/200; + setunitdata(.@mob, UDT_DEF, .@def); + .@def=getunitdata(.@mob, UDT_MDEF); + .@def=.@def*(200+$MK_TEMPVAR)/200; + setunitdata(.@mob, UDT_MDEF, .@def); + .@def=getunitdata(.@mob, UDT_FLEE); + .@def=.@def*(200+$MK_TEMPVAR)/200; + setunitdata(.@mob, UDT_FLEE, .@def); + .@def=getunitdata(.@mob, UDT_PDODGE); + .@def=.@def*(200+$MK_TEMPVAR)/200; + setunitdata(.@mob, UDT_PDODGE, .@def); + // "Normalize" criticals + setunitdata(.@mob, UDT_CRIT, rand2(900, 2700)); + + // Announce that the Fortress Town can now be conquered + kamibroadcast("##1"+"Aegis Scutum has been nullified, the Monster Governor has appeared at Fortress Town!"); + mapannounce "025-1", "Defeat the Monster Governor to capture the fortress town.", bc_map; + } + end; + +///////////////////////////////////////////////////////// +// spawnMob(Mob, X1, Y1, X2, Y2) +function spawnMob { + //.@mob=monster("025-1", rand2(getarg(1), getarg(3)), rand2(getarg(2), getarg(4)), strmobinfo(1, getarg(0)), getarg(0), 1); + .@mob=areamonster("025-1", getarg(1), getarg(2), getarg(3), getarg(4), + strmobinfo(1, getarg(0)), getarg(0), 1); + .@opt=getunitdata(.@mob, UDT_MODE); + // Make aggressive + .@opt=.@opt|MD_AGGRESSIVE; + // All forces can suffer knockback + if (.@opt & MD_NOKNOCKBACK) + .@opt=.@opt^MD_NOKNOCKBACK; + // Save new options + setunitdata(.@mob, UDT_MODE, .@opt); + + // Increase health in 1%+1% per siege + .@bhp=getunitdata(.@mob, UDT_MAXHP); + .@bhp=.@bhp*(101+$MK_TEMPVAR)/100; + setunitdata(.@mob, UDT_MAXHP, .@bhp); + setunitdata(.@mob, UDT_HP, .@bhp); + + // Increase accuracy in 10%+1% per siege + .@acc=getunitdata(.@mob, UDT_HIT); + .@acc=.@acc*(110+$MK_TEMPVAR)/100; + setunitdata(.@mob, UDT_HIT, .@acc); + + // TODO: adjust ViewRange + return; +} + +// spawnCore(breach) +function spawnCore { + // Now, the thing is, I don't care with how powerful your invading forces are. + // I only care with how many success you have. + if (getarg(0)) { + .@x1=24; + .@y1=21; + .@x2=175; + .@y2=105; + .@am=2+$MK_TEMPVAR; + } else { + .@x1=25; + .@y1=110; + .@x2=180; + .@y2=120; + .@am=1+($MK_TEMPVAR/3); + } + freeloop(true); + // Level 40~60 Section + for (.@i = 0; .@i < .@am*2; ++.@i) { + spawnMob(any(Tipiou, Pollet, Wolvern, FireSkull, DarkLizard, BlackScorpion, EarthFairy, FireFairy, WaterFairy, WindFairy, PoisonFairy, DustGatling, DustRifle, DustRevolver, MountainSnake, HoodedNinja, ForestMushroom, GoldenScorpion, Yeti), .@x1, .@y1, .@x2, .@y2); + } + // Level 60~80 Section + for (.@i = 0; .@i < .@am*3/2+1; ++.@i) { + spawnMob(any(Yeti, WickedMushroom, Archant, Scar, Crafty, AzulSkullSlime, YellowSkullSlime, Forain, GreenDragon, Michel, EliteDuck, Troll, Moonshroom, Terranite), .@x1, .@y1, .@x2, .@y2); + } + // Level 80~100 section + for (.@i = 0; .@i < .@am; ++.@i) { + spawnMob(any(RedSkullSlime, Terranite, JackO, BlackMamba, GreenSkullSlime, Centaur, GoboBear, TerraniteProtector), .@x1, .@y1, .@x2, .@y2); + } + // Summoners Section + for (.@i = 0; .@i < .@am; ++.@i) { + spawnMob(any(GreenSlimeMother, BlueSlimeMother, YellowSlimeMother, RedSlimeMother, WhiteSlimeMother, AzulSlimeMother, LavaSlimeMother, BlackSlimeMother), .@x1, .@y1, .@x2, .@y2); + } + if (getarg(0)) { + // DemiBoss section (Internal only, increases every ~2 weeks) + for (.@i = 0; .@i < (.@am/2); ++.@i) { + spawnMob(any(VanityPixie, HolyPixie, ShadowPixie, NulityPixie, Reaper, BlackSkullSlime, NightmareDragon, WhirlyBird, PinkieSuseran), .@x1, .@y1, .@x2, .@y2); + } + } + freeloop(false); + return; +} + +///////////////////////////////////////////////////////// +OnInit: + sleep(200); // Ensure the NPCs will exist when this run + FTCleanup($FORTRESS_STATE); + end; + +OnTue0000: + .@cl=$FORTRESS_STATE; + FTCleanup(false); + if (.@cl) + kamibroadcast("The Monster Army has retaken Fortress Town!"); + end; + +OnConquest: + // Failsafe + if ($GAME_STORYLINE < 3) + end; + // Advance the victory count + $MK_TEMPVAR+=1; + // Handle rewards in low priority + freeloop(true); + for (.@i=0; .@i < getarraysize($@FORT_BLACKLIST); .@i++) { + .@cid=$@FORT_BLACKLIST[.@i]; + rodex_sendmail(.@cid, "Commander Povo", "Fortress Town Reward", "For your bravure in Fortress Town conquest! Cheers!", 0, StrangeCoin, 1+$MK_TEMPVAR); + } + freeloop(false); + // Clean up the remainders of the fight + FTCleanup(true); + kamibroadcast("Fortress Town has been captured by the Allied Forces!"); + // Experience injection to the brave (500k EXP, 100k JEXP) + if (playerattached()) { + getexp 500000, 100000; + getitem StrangeCoin, rand2(40,50); + specialeffect(FX_FANFARE, AREA, getcharid(3)); + } + // Experience injection to the survivors + maptimer("025-1", 10, "Gate#F::OnConBonus"); + stopnpctimer; + // Begin Fires of Steam if needed + if (!$FIRESOFSTEAM && $MK_TEMPVAR >= MK_FIRESOFSTEAM_START) { + kamibroadcast("Andrei Sakar : It has been about three months since we begun battling for control overthe Fortress Town."); + sleep(5000); + kamibroadcast("Andrei Sakar : Since this begun, however, we've heard nothing of Artis Town."); + sleep(5000); + kamibroadcast("Andrei Sakar : Therefore, I invite all of you, brave adventurers, to go on an expedition with me to Artis."); + sleep(5000); + kamibroadcast("Andrei Sakar : "+b("Hopefully nothing terrible happened... Nard shall provide us transport.")); + sleep(5000); + kamibroadcast("Andrei Sakar : I only want people strong enough to battle on the Fortress because the risks are high. Onwards! To victory! I'll be waiting"); + $FIRESOFSTEAM = 1; + } + end; + +OnConBonus: + message strcharinfo(0), l("Commander Povo : Good job %s. You did well.", lg("girl", "man")); // TRANSLATORS: Preserve whitespace. + .@it=any(ApanaCake, SacredLifePotion, SacredManaPotion, SacredImmortalityPotion, DeathPotion, PurificationPotion, ApanaCake); + if (.@it == ApanaCake || .@it == PurificationPotion) + .@qn = rand2(2, 5); + else + .@qn = 1; + getitem .@it, .@qn; + getexp 25000, 10000; + end; +} + + +///////////////////////////////////////////////////////// +// Statue NPCs +025-1,32,55,0 script Magic Statue#1 NPC_STATUE_WIZARD,{ + .@b=FTStatue(strnpcinfo(2, "0")); + if (.@b) + disablenpc .name$; + close; + +OnInit: + .distance=2; + end; +} + +025-1,160,25,0 duplicate(Magic Statue#1) Magic Statue#2 NPC_STATUE_BACCHUS +025-1,156,97,0 duplicate(Magic Statue#1) Magic Statue#4 NPC_STATUE_FAFA +025-1,134,70,0 duplicate(Magic Statue#1) Magic Statue#8 NPC_STATUE_EVILMAN +025-1,80,37,0 duplicate(Magic Statue#1) Magic Statue#16 NPC_STATUE_GUARD + + + + + +///////////////////////////////////////////////////////// +// The Impregnable Fortress Gate +025-1,99,20,0 script The Impregnable Fortress NPC_NO_SPRITE,3,1,{ + // Operation not permitted + if (!$FORTRESS_STATE || $@FORTRESS_STATUE) + end; + // Not unlocked + if ($GAME_STORYLINE >= 3 && $MK_TEMPVAR < MKIF_LV_0F) { + mesc l("The gate is sealed shut."), 1; + mesc l("The monster army is still strong on this floor!"), 1; + mesc l("Minimum wins: %d/%d", $MK_TEMPVAR, MKIF_LV_0F), 1; + close; + } + mesc l("Visit the Impregnable Fortress, 0F?"); + mesc l("Minimum wins: %d/%d", $MK_TEMPVAR, MKIF_LV_0F); + if (askyesno() == ASK_YES) + warp "025-3", 100, 178; + closeclientdialog; + close; + +OnTouch: + // Operation not permitted + if (!$FORTRESS_STATE || $@FORTRESS_STATUE) + end; + // Not unlocked + if ($GAME_STORYLINE >= 3 && $MK_TEMPVAR < MKIF_LV_0F) + end; + warp "025-3", 100, 178; + end; + +OnInit: + .distance=4; + end; +} + + +///////////////////////////////////////////////////////// +// Real access to 025-1 map +025-2,96,24,0 script Fortress Town Access NPC_HIDDEN,8,0,{ + end; +OnTouch: + // Disabled + if ($GAME_STORYLINE < 3 || $@FORTRESS_STATUE) + end; + // Open + if ($FORTRESS_STATE) + cwarp "025-1", 99, 122; + // Blacklisted + if (array_find($@FORT_BLACKLIST, getcharid(0)) != -1) + end; + // Not blacklisted + warp "025-1", 99, 122; + end; +} + + diff --git a/npc/025-1/drahcir.txt b/npc/025-1/drahcir.txt new file mode 100644 index 0000000..72a3b7c --- /dev/null +++ b/npc/025-1/drahcir.txt @@ -0,0 +1,16 @@ +// TMW2 scripts. +// Author: +// Jesusalva +// Description: +// Drahcir is Richard spelled backwards + +025-1,167,61,0 script Drahcir NPC_LLOYD,{ + Banker(.name$, "Fortress Town", 2000); + close; + +OnInit: + .sex = G_MALE; + .distance = 5; + end; +} + diff --git a/npc/025-1/ihclot.txt b/npc/025-1/ihclot.txt new file mode 100644 index 0000000..cd093e2 --- /dev/null +++ b/npc/025-1/ihclot.txt @@ -0,0 +1,148 @@ +// TMW2 scripts. +// Author: +// Jesusalva +// Description: +// Ihclot is Tolchi spelled backwards + +025-1,96,66,0 script Ihclot NPC_RAIJIN_FEMALE_LEGION_ARTIS,{ + function apRefresh; + function getPrice; + function getPriceInt; + + .@left=apRefresh(); + mesn; + mesq l("I put options on items upon request, but I am very expensive! This is deducted from your tweaking quota."); + if (!.@left) { + mesc l("You currently have no Tweaking AP, so you will need to wait %02d minute(s).", 60-gettime(GETTIME_MINUTE)), 1; + close; + } + next; + mesn; + mesq l("I'll read the options from you, but the level will be paid by me, and failure rate is non-existant. I am the best. blacksmith. in. the. universe! Use %s if you need to change any options.", b("@ucp")); + csysGUI_Report(); + + mesc l("Please select the item you plan in tweaking."), 1; + // Request and confirm + .@id=requestitemindex(); + if (!csys_Confirm(.@id)) + close; + + // Find numeric ID + delinventorylist(); + getinventorylist(); + .@handle=@inventorylist_id[.@id]; + .@lv=getiteminfo(.@handle, ITEMINFO_ELV); + + // Invalid (absolutely should never happen) + if (.@handle < 1) { + mesn; + mesq l("...What? Which item? Sorry, too much smoke around here."); + next; + close; + } + // Multiple + if (countitem(.@handle) != 1) { + mesn; + mesq l("Sorry, but you have multiple %s.", getitemlink(.@handle)); + next; + close; + } + // Permission NG: (Not Granted) + if (.@lv < .minLevel) { + mesn; + mesq l("Sorry, but I won't dare touch a %s.", getitemlink(.@handle)); + next; + mesn; + mesq l("Depending on the case, Nicholas, in Hurnscald, can do a better job than me."); + tutmes l("The selected item is too weak. %s will only tweak items level %d or higher.", .name$, .minLevel); + next; + close; + } + // Aleady slotted + if (getitemoptionidbyindex(.@id, 0) > 0) { + mesn; + mesq l("I'm not going to try to improve this masterpiece. Look its options!"); + next; + close; + } + + // Calculate price + .@price=.@lv**3; // Cubic function to determine price. + .@price=max(1, .@price/7); + mesn; + mesq l("Please select the level I should use."); + menuint + l("Abort (%d GP)", fnum(.@price*0)), 0, + getPrice(.@price, 10), 10, + getPrice(.@price, 20), 20, + getPrice(.@price, 30), 30, + getPrice(.@price, 40), 40, + getPrice(.@price, 50), 50, + getPrice(.@price, 60), 60, + getPrice(.@price, 70), 70, + getPrice(.@price, 80), 80, + getPrice(.@price, 90), 90, + getPrice(.@price, 100), 100; + mes ""; + if (@menuret == 0) + close; + + // Ask player to confirm + if (!csys_Confirm(.@id)) + close; + + // Perform payment + Zeny-=getPriceInt(.@price, @menuret); + SMITH_TWEAKS+=1; + + // Apply the bonuses + csys_ApplyPerfect(.@id, .@level); + mesn; + mesc l("Well, here you are. I hope you enjoy ^^", 3); + // Act 5+ Grace Reroll + if ($GAME_STORYLINE >= 5) { + next; + mesc l("DO YOU WANT TO REROLL THE ITEM? THIS CANNOT BE UNDONE! (free)"), 1; + next; + if (askyesno() == ASK_YES) + csys_ApplyPerfect(.@id, .@level); + } + close; + +/* *************************************************************************** */ +function apRefresh { + .@left=gettimeparam(GETTIME_HOUR)-SMITH_TWEAKS; + if (.@left > 6) { + .@left=6; + SMITH_TWEAKS=gettimeparam(GETTIME_HOUR)-6; + } + return .@left; +} + +function getPriceInt { + .@price=getarg(0); + .@level=getarg(1); + .@final=.@price*.@level/5; + if (strcharinfo(0) == $MOST_HEROIC$) + .@final=max(1, .@final-(.@level*5000)); + return .@final; +} + +function getPrice { + .@price=getarg(0); + .@level=getarg(1); + .@final=getPriceInt(.@price, .@level); + if (Zeny >= .@final) + return l("Level %d (%s GP)", .@level, fnum(.@final)); + else + return ""; +} + +OnInit: + .sex = G_OTHER; + .distance = 5; + .minLevel = 50; + end; +} + + diff --git a/npc/025-1/phoenix.txt b/npc/025-1/phoenix.txt new file mode 100644 index 0000000..5e80f41 --- /dev/null +++ b/npc/025-1/phoenix.txt @@ -0,0 +1,230 @@ +// TMW-2 Script. +// Author: +// Jesusalva +// Notes: +// Phoenix Rebirth + +025-1,66,21,0 script Phoenix Rebirth NPC_BRGUARD_SPEAR,{ + setpcblock(PCBLOCK_HARD, true); + .@phoenix = true; + +OnMain: + mesn; + mesq l("Hello there. My name is %s.", .name$); + next; + mesn; + if (REBIRTH) + .@blvl=0-(REBIRTH_OVERLEVEL/REBIRTH); + else + .@blvl=0; + + switch (REBIRTH) { + case 0: + .@blvl+=99; + .@rebirth$=l("first"); + break; + case 1: + .@blvl+=120; + .@rebirth$=l("second"); + break; + case 2: + .@blvl+=135; + .@rebirth$=l("third"); + break; + case 3: + .@blvl+=150; + .@rebirth$=l("fourth"); + break; + case 4: + .@blvl+=175; + .@rebirth$=l("final"); + if ($GAME_STORYLINE >= 5) + break; + default: + setpcblock(PCBLOCK_HARD, false); + mesc l("Unfortunately you cannot rebirth anymore!"); + close; + break; + } + .@blvl=max(90, .@blvl); // Do not allow it to go too far below! + mesc l("Once you reach level %d, I'll offer you a life-time opportunity to delete all your levels and experience for your %s rebirth!", .@blvl, .@rebirth$); + next; + mesn; + mesq l("Rebirth is free. Here are the perks you'll get by doing the rebirth:"); + mes ""; + mes l("* +3 Inventory Slots")+" ##1##BWIP##b##0"; + mes l("* +1 in all attributes, permanently"); + mes l("* +1 Magic Skill Point"); + mes l("* +%d%% EXP Gain and Drop Chance, permanently", 2); + mes l("* 1 %s", getitemlink(SupremeGift)); + mes l("* 1 Trait"); + mes l("* Healing items improved"); + mes l("* %s Level up", getskillname(TMW2_DROPS)); + if (BaseLevel < .@blvl) { + setpcblock(PCBLOCK_HARD, false); + close; + } + next; + mesn; + mesq l("Are you interested? You'll keep %s your equipment, magic, quest progression, craft recipes, money, whatever else which is not a level. Not even Job level won't be reset!", b(l("ALL"))); + mesc l("This cannot be undo later!"), 1; + next; + setpcblock(PCBLOCK_HARD, false); + inventoryplace NPCEyes, 7; + select + l("Do not rebirth"), + l("Rebirth"), + l("Do not rebirth"); + mes ""; + if (@menu != 2) + close; + mesc l("ARE YOU SURE? THIS CANNOT BE UNDONE LATER!!"), 1; + if (askyesno() != ASK_YES) + close; + + setnpcdialogtitle l("Rebirth Trait Selection"); + mesc l("Please select a trait."); + mesc l("This choice CANNOT be undone later."), 1; + menuint + l("Cancel"), 0, + rif(!(PCBONUS & PCB_ATKBONUS), l("Atk +25")), PCB_ATKBONUS, + rif(!(PCBONUS & PCB_MATKBONUS), l("Matk +25")), PCB_MATKBONUS, + rif(!(PCBONUS & PCB_DEFBONUS), l("Def +20")), PCB_DEFBONUS, + rif(!(PCBONUS & PCB_MDEFBONUS), l("MDEF +10")), PCB_MDEFBONUS, + rif(!(PCBONUS & PCB_EVDBONUS), l("Evasion +20")), PCB_EVDBONUS, + rif(!(PCBONUS & PCB_HITBONUS), l("Accuracy +25")), PCB_HITBONUS, + rif(!(PCBONUS & PCB_CRITBONUS), l("Crit +5%")), PCB_CRITBONUS, + rif(!(PCBONUS & PCB_DOUBLEATK), l("Double Attack +5%")), PCB_DOUBLEATK, + rif(!(PCBONUS & PCB_ALLSTATS), l("All Stats +1")), PCB_ALLSTATS, + rif(!(PCBONUS & PCB_HPBONUS), l("HP +500")), PCB_HPBONUS, + rif(!(PCBONUS & PCB_MPBONUS), l("MP +200")), PCB_MPBONUS, + rif(!(PCBONUS & PCB_ASPDBONUS), l("Atk. Speed +10")), PCB_ASPDBONUS, + rif(!(PCBONUS & PCB_WSPDBONUS), l("Walk +5%")), PCB_WSPDBONUS, + rif(!(PCBONUS & PCB_WEIGHTBONUS), l("Max Weight +1kg")), PCB_WEIGHTBONUS, + rif(!(PCBONUS & PCB_EXPBONUS), l("EXP Gain +10%")), PCB_EXPBONUS, + rif(!(PCBONUS & PCB_NOKNOCKBACK), l("Knockback Immunity")), PCB_NOKNOCKBACK, + rif(REBIRTH && !(PCBONUS & PCB_SPLASHMASTER), l("AoE (not stackable)")), PCB_SPLASHMASTER, + rif(REBIRTH && !(PCBONUS & PCB_RANGEMASTER), l("Atk Range +1")), PCB_RANGEMASTER, + rif(REBIRTH < 5 && !(PCBONUS & PCB_LEGENDARY), l("No penalty against Legendary mobs")), PCB_LEGENDARY; + if (@menuret == 0) return; + PCBONUS=PCBONUS|@menuret; + + // Okay, then a rebirth it is! + expandinventory(3); + REBIRTH+=1; + REBIRTH_OVERLEVEL=max(0, BaseLevel-.@blvl-(REBIRTH_OVERLEVEL/REBIRTH)); + resetlvl(3); + sk_lvup(TMW2_DROPS); + NewcomerEXPDROPUP(); + getvaultexp(20); + getitembound SupremeGift, 1, 4; + warp "005-1", 40, 117; + LOCATION$="Candor"; + kamibroadcast(strcharinfo(0)+" has been reborn."); + // Maybe you were THE FIRST + if (!REBIRTH_WINNER) + REBIRTH_WINNER = gettimetick(2); + if ($REBIRTH_WINNER$ == "") { + $REBIRTH_WINNER$=strcharinfo(0); + channelmes("#world", $REBIRTH_WINNER$+" is the first player to REBIRTH!! They are so OP! %%N"); + announce "All hail ##B"+$REBIRTH_WINNER$+"##b, first player to REBIRTH and become OP!", bc_all|bc_npc; + getitem SupremeGift, 1; + next; + } + // These operations can be delayed or fail + StatusResetReinvest(); + if ($EVENT$ == "Rebirth" && .@phoenix) + BaseLevel = 3; + // Open a new dialog + clear; + setnpcdialogtitle l("Rebirth Race Selection"); + mesc l("Do you want to change your race?"); + mesc l("This can only be reverted at rebirth! Beware!"); + next; + if (askyesno() != ASK_YES) + close; + + // Rebirth: 0 + mes ""; + mes ".:: "+l("Human")+" ::."; + mesc l("The most widespread race in the continent, highly versatile, perfect all-rounders."); + mesc l("Strength: NONE"), 2; + mesc l("Weakness: NONE"), 1; + + + // Rebirth: 1 + if (REBIRTH >= 1) { + mes ""; + mes ".:: "+l("Elven")+" ::."; + mesc l("They are highly intelligent, and have higher magical affinity, and live longer, but lacks creativity."); + mesc l("Strength: INT+"), 2; + mesc l("Weakness: STR-"), 1; + mes ""; + mes ".:: "+l("Tritan")+" ::."; + mesc l("Blue from sea, learned how to hunt. But unfortunately, not how to withstand attacks."); + mesc l("Strength: DEX+"), 2; + mesc l("Weakness: VIT-"), 1; + } + + + // Rebirth: 2 + if (REBIRTH >= 2) { + mes ""; + mes ".:: "+l("Raijin")+" ::."; + mesc l("Lives undercover in human society. Luck led them to surviving this far."); + mesc l("Strength: LUK+"), 2; + mesc l("Weakness: DEX-"), 1; + mes ""; + mes ".:: "+l("Orc")+" ::."; + mesc l("Highly strong and bulky, faces their foes head-on."); + mesc l("Strength: STR+, Carry Weight +"), 2; + mesc l("Weakness: AGI-"), 1; + } + + + // Rebirth: 3 + if (REBIRTH >= 3) { + mes ""; + mes ".:: "+l("Ukar")+" ::."; + mesc l("Superb stealth, and quick on their toes."); + mesc l("Strength: AGI+, Walk Speed +"), 2; + mesc l("Weakness: LUK-"), 1; + mes ""; + mes ".:: "+l("Redy")+" ::."; + mesc l("Grown in harsh environments, withstand anything."); + mesc l("Strength: VIT++"), 2; + mesc l("Weakness: INT-"), 1; + } + + + // Rebirth: 5 + if (REBIRTH >= 5) { + mes ""; + mes ".:: "+l("Savior")+" ::."; + mesc l("Unparelled, strength without precedents. Ancient beings of pure mana, rumored to be immortal."); + mesc l("Strength: ALL"), 2; + mesc l("Weakness: NONE"), 1; + } + next; + menuint + l("Kaizei Human"), 0, + rif(REBIRTH >= 1, l("Elven")), 3, + rif(REBIRTH >= 1, l("Tritan")), 6, + rif(REBIRTH >= 2, l("Raijin")), 5, + rif(REBIRTH >= 2, l("Orc")), 4, + rif(REBIRTH >= 3, l("Ukar")), 7, + rif(REBIRTH >= 3, l("Redy")), 8, + rif(REBIRTH >= 5, l("Savior")), 9, + l("Argaes Human"), 1, + l("Tonori Human"), 2, + l("Don't change race"), Class; + + jobchange max(0, @menuret); + close; + +OnInit: + .sex = G_MALE; + .distance = 7; + end; +} + diff --git a/npc/025-1/rum.txt b/npc/025-1/rum.txt new file mode 100644 index 0000000..68a6e16 --- /dev/null +++ b/npc/025-1/rum.txt @@ -0,0 +1,181 @@ +// TMW2 Scripts +// Author: +// Jesusalva +// Description: +// Crazyfefe Rum +// Variables: +// FORTRESS_DATE = When the Rum started being done +// FORTRESS_DONE = When the Rum will be ready +// FORTRESS_AMMO = How much Rum you're trying to make +// Success Rate is based on how much you're trying to do and how long ago that was + +025-1,106,56,0 script Rum Barrel NPC_NO_SPRITE,{ + goto L_Main; + // rumbarrel_chance() + // Returns chance (0~10,000) to successfully obtain sake + // FORTRESS_DONE/FORTRESS_DATE is taken in account + function rumbarrel_chance { + .@max=10000; + .@base=FORTRESS_DATE;//-(FORTRESS_DONE-FORTRESS_DATE); + // .@c = how much time is left until completion + // .@d = original amount of time required + // .@e = Current time + .@c=FORTRESS_DONE-.@base; //-gettimetick(2); + .@d=FORTRESS_DATE-.@base; //-FORTRESS_DONE; + .@e=gettimetick(2)-.@base; + + // We must divide everything by 10 to cause imprecision + // aka. don't cause overflow bug + .@c=.@c/10; + .@d=.@d/10; + .@e=.@e/10; + + //debugmes "%d - %d - %d", .@d, .@e, .@c; + //debugmes "Start - Now - Finish"; + if (.@c == 0) + return .@max; + if ($@GM_OVERRIDE) debugmes "Ratio: %d/%d = %d", .@e, .@c, (.@e*.@max)/.@c; + return min(10000, (.@e*.@max)/.@c); + } + +L_Main: + if (!FORTRESS_DATE) { + mesn; + mesc l("Do you want to make %s?", l("Rum")); + mesc l("This barrel is a courtesy from Dimond Cove Inn."); + next; + select + l("Information"), + l("Yes"), + l("No"); + mes ""; + + switch (@menu) { + case 1: + mesc l("Produced item:"); + mesc l("@@", getitemlink(CrazyRum)); + mesc l("%s (rare)", getitemlink(WhiskeyAle)); + mes ""; + mesc l("Cost per %s glass:", l("twelve")); + mesc l("* @@/@@ @@", countitem(Beer), 5, getitemlink(Beer)); + mesc l("* @@/@@ @@", countitem(ArtichokeHerb), 25, getitemlink(ArtichokeHerb)); + mesc l("* @@/@@ @@", countitem(Fungus), 25, getitemlink(Fungus)); + mesc l("* @@/@@ @@", countitem(RedApple), 25, getitemlink(RedApple)); + mesc l("* @@/@@ @@", countitem(Milk), 25, getitemlink(Milk)); + mesc l("* @@/@@ @@", countitem(ShadowHerb), 100, getitemlink(ShadowHerb)); + mesc l("* @@ Water Bottle", 1); + next; + break; + case 2: + mesc l("How many batches do you want to produce? (max. 5)"); + input .@glass_count; + if (.@glass_count < 1 || + .@glass_count > 5 || + countitem(ArtichokeHerb) < 25*.@glass_count || + countitem(Fungus) < 25*.@glass_count || + countitem(RedApple) < 25*.@glass_count || + countitem(Beer) < 5*.@glass_count || + countitem(Milk) < 25*.@glass_count || + countitem(ShadowHerb) < 100*.@glass_count + ) { + mesc l("Not enough ingredients or invalid amount."), 1; + break; + } + mesc l("Which water will you use?"); + mesc l("The bottom-most the water, the better the bonus."); + menuint + l("Cancel"), -1, + rif(countitem(BottleOfSewerWater) >= .@glass_count, l("Sewer Water")), 0, + rif(countitem(BottleOfSeaWater) >= .@glass_count, l("Sea Water")), 3600, + rif(countitem(BottleOfTonoriWater) >= .@glass_count, l("Tonori Water")), 11760, + rif(countitem(BottleOfWoodlandWater) >= .@glass_count, l("Woodland Water")), 12000, + rif(countitem(BottleOfDivineWater) >= .@glass_count, l("Divine Water")), 21600; + mes ""; + if (@menuret < 0) + break; + switch (@menuret) { + case 0: + .@bonus=@menuret; + .@water=BottleOfSewerWater; + break; + case 3600: + .@bonus=@menuret; + .@water=BottleOfSeaWater; + break; + case 11760: + .@bonus=@menuret; + .@water=BottleOfTonoriWater; + break; + case 12000: + .@bonus=@menuret; + .@water=BottleOfWoodlandWater; + break; + case 21600: + .@bonus=@menuret; + .@water=BottleOfDivineWater; + break; + default: + mesc l("Error, invalid return code, blame Saulc"), 1; + mes "==== SCRIPT ABORTED"; + close; + } + + // Save data + delitem ArtichokeHerb, .@glass_count*25; + delitem Fungus, .@glass_count*25; + delitem RedApple, .@glass_count*25; + delitem Beer, .@glass_count*5; + delitem Milk, .@glass_count*25; + delitem ShadowHerb, .@glass_count*100; + delitem .@water, .@glass_count; + FORTRESS_AMMO=.@glass_count; + FORTRESS_DATE=gettimetick(2); + FORTRESS_DONE=gettimetick(2)-.@bonus+.mintime; + FORTRESS_DONE+=.cuptime*FORTRESS_AMMO; + break; + case 3: + close; + break; + } + goto L_Main; + } else { + mesn; + mesc l("Your request for @@ @@ are being fermented for @@.", FORTRESS_AMMO, getitemlink(CrazyRum), FuzzyTime(FORTRESS_DATE)); + next; + inventoryplace CrazyRum, FORTRESS_AMMO; + mesn; + mes l("Trying to retrieve it now will have @@ % chance to be successful.", rumbarrel_chance()/100); + mes l("Attempt to retrieve it now?"); + next; + if (askyesno() == ASK_YES) { + if (rand(1000,10000) < rumbarrel_chance()) { + mesc l("Success!"), 3; + if (REBIRTH > rand2(20)) + getitem WhiskeyAle, FORTRESS_AMMO*.cupammo; + else + getitem CrazyRum, FORTRESS_AMMO*.cupammo; + } else { + mesc l("The %s wasn't ready yet and you lost it...", l("Rum")), 1; + } + FORTRESS_DATE=0; + FORTRESS_AMMO=0; + } + } + close; + +OnInit: + .sex = G_OTHER; + .distance = 4; + + // Time to make each batch (48 hours) + .cuptime=(60*60*48); + // Base time to make any amount of cups (120 hours - five days) + .mintime=(60*60*120); + // Amount of cups + .cupammo=12; + end; + +} + + + diff --git a/npc/025-1/salohcin.txt b/npc/025-1/salohcin.txt new file mode 100644 index 0000000..6063eaa --- /dev/null +++ b/npc/025-1/salohcin.txt @@ -0,0 +1,55 @@ +// TMW-2 Script +// Author: +// Jesusalva +// Description: +// Nicholas the Blacksmith, spelled backwards + +025-1,108,67,0 script Salohnic NPC_NICHOLAS,{ + // Define variables + if ($GAME_STORYLINE >= 5) { + .@tx$=l("thrice"); + .@txn=4; + .@prc=150000; + } else if ($GAME_STORYLINE >= 4) { + .@tx$=l("twice"); + .@txn=3; + .@prc=90000; + } else { + .@tx$=l("once"); + .@txn=2; + .@prc=60000; + } + + // World Hero bonuses + if (reputation("Candor") >= 100 && + reputation("Tulim") >= 100 && + reputation("Halin") >= 100 && + reputation("Hurns") >= 100 && + reputation("LoF") >= 100 && + reputation("Nival") >= 100 && + reputation("Frostia") >= 100) + .@prc-=20000; + + if (strcharinfo(0) == $MOST_HEROIC$) + .@prc-=20000; + + // NPC body + mesn; + mesq l("Hello there, I am %s and I change item options, can I help you today?", .name$); + mes ""; + mesn; + mesq l("You'll be charged even if you fail, be warned. You can re-roll the same item %s, free of charge, but it may break and there will be no refunds!", .@tx$); + next; + + if (!SmithTweakSystem(.@prc, .@txn)) { + mes ""; + mesn; + mesq l("You can always try again another day!"); + } + close; + +OnInit: + .sex = G_MALE; + .distance = 5; + end; +} diff --git a/npc/025-1/selim.txt b/npc/025-1/selim.txt new file mode 100644 index 0000000..76fbd9b --- /dev/null +++ b/npc/025-1/selim.txt @@ -0,0 +1,81 @@ +// TMW2 scripts. +// Author: +// Jesusalva +// Description: +// Selim is just a barber. No puns this time. + +025-1,101,58,0 script Selim NPC_ELVEN_FEMALE_ARMOR_SHOP,{ + function setRace { + clear; + setnpcdialogtitle l("%s - Modify Race", .name$); + mes l("Race") + ": " + get_race(); + next; + mes l("Please select the desired race."); + select + l("Kaizei Human"), + l("Argaes Human"), + l("Tonori Human"), + l("Elf"), + l("Orc"), + l("Raijin"), + l("Tritan"), + l("Ukar"), + l("Redy"), + l("Savior"); + switch (@menu) + { + default: + jobchange max(0, @menu-1); + } + return; + } + + + mesn; + mesq l("Hi! Do you want a hair cut?"); + + do + { + select + l("What is my current hairstyle and hair color?"), + l("I'd like to get a different style."), + l("Can you do something with my color?"), + rif(is_gm() || REBIRTH >= 5, l("I want to change my Race!")), + l("I'm fine for now, thank you."); + + switch (@menu) + { + case 1: + BarberSayStyle 3; + break; + case 2: + BarberChangeStyle; + speech S_FIRST_BLANK_LINE | S_LAST_NEXT, + l("Enjoy your new style."); + l("Anything else?"); + break; + case 3: + BarberChangeColor; + speech S_FIRST_BLANK_LINE | S_LAST_NEXT, + l("I hope you like this color."); + l("Anything else?"); + break; + case 4: + setRace; + break; + case 5: + speech S_FIRST_BLANK_LINE | S_LAST_NEXT, + l("Feel free to come visit me another time."); + + goodbye; + } + } while (1); + close; + + +OnInit: + .sex = G_FEMALE; + .distance = 5; + end; +} + diff --git a/npc/025-1/teleporter.txt b/npc/025-1/teleporter.txt new file mode 100644 index 0000000..4fee051 --- /dev/null +++ b/npc/025-1/teleporter.txt @@ -0,0 +1,23 @@ +// TMW2 Script +// Authors: +// Jesusalva +// Description: +// Link portals to soul menhirs like the teleporters from old +// The price is temporary. This feature got in because no ship in Nivalis Port +// PS. Anise => “Aisen” Anagram + + +025-1,40,115,0 script #WarpGateFort NPC_HIDDEN,1,0,{ + end; + +OnTouch: + TeleporterGate(TP_FORT); + close; + + +OnInit: + .sex = G_OTHER; + .distance = 1; + end; +} + diff --git a/npc/025-1/xovilam.txt b/npc/025-1/xovilam.txt new file mode 100644 index 0000000..886b038 --- /dev/null +++ b/npc/025-1/xovilam.txt @@ -0,0 +1,47 @@ +// TMW2 Script +// Author: +// Jesusalva + +025-1,143,59,0 script Xovilam NPC_PLAYER,{ + + speech S_LAST_NEXT, + l("I am @@, an alchemist specialized in reset potions.", .name$); + + select + l("Can you reset my stats please?"), + l("You are weird, I have to go sorry."); + + switch (@menu) + { + case 1: + goto L_ResetStats; + case 2: + goto L_Quit; + } + +L_ResetStats: + mesn; + mesq l("Status point reset can't be undone. Do you really want this?"); + +L_ConfirmReset: + ConfirmStatusReset(1000, false); + goto L_Quit; + + +L_Quit: + goodbye; + end; + +OnInit: + .@npcId = getnpcid(.name$); + setunitdata(.@npcId, UDT_HEADTOP, FancyHat); + setunitdata(.@npcId, UDT_HEADMIDDLE, SailorShirt); + setunitdata(.@npcId, UDT_HEADBOTTOM, BromenalPants); + setunitdata(.@npcId, UDT_WEAPON, LousyMoccasins); // Boots + setunitdata(.@npcId, UDT_HAIRSTYLE, 7); + setunitdata(.@npcId, UDT_HAIRCOLOR, 17); + + .sex = G_MALE; + .distance = 4; + end; +} diff --git a/npc/025-1/yuko.txt b/npc/025-1/yuko.txt new file mode 100644 index 0000000..81336bf --- /dev/null +++ b/npc/025-1/yuko.txt @@ -0,0 +1,71 @@ +// TMW2 Script +// Author: +// Jesusalva +// Yuko Cuf is an anagram of YuckFou (see also 102 58) + +025-1,93,59,0 script Yuko NPC_PLAYER,{ + mesn; + mesq l("Cuf! Cuf!"); // --TRANSLATORS: NOT A TYPO + next; + mesn "Yuko Cuf"; + mesq l("Can I help you somehow today?"); + next; + closeclientdialog; + shop .name$; + goodbye; + close; + +OnInit: + .@npcId = getnpcid(.name$); + setunitdata(.@npcId, UDT_HEADTOP, DarkKnightHelmet); + setunitdata(.@npcId, UDT_HEADMIDDLE, RedknightArmor); + setunitdata(.@npcId, UDT_HEADBOTTOM, BromenalPants); + setunitdata(.@npcId, UDT_WEAPON, BlueKnightShield); // Boots + setunitdata(.@npcId, UDT_HAIRSTYLE, 7); + setunitdata(.@npcId, UDT_HAIRCOLOR, 17); + + .sex = G_MALE; + .distance = 4; + + sleep(SHOPWAIT); + tradertype(NST_MARKET); + sellitem InsuranceContract, -1, 1; + sellitem HomunResetPotion, -1, 5; + sellitem PurificationPotion, -1, 20; + sellitem AtroposMixture, -1, 50; + sellitem ThornAmmoBox, -1, 5; + sellitem PoisonAmmoBox, -1, 10; + sellitem CursedAmmoBox, -1, 15; + sellitem PileOfAsh, -1, 25; + sellitem BoneKnife, -1, 1; + sellitem LeaderWand, -1, 1; + sellitem BromenalShield, -1, 1; + sellitem LightPlatemail, -1, 1; + sellitem BromenalPants, -1, 1; + sellitem CandleHelmet, -1, 1; + sellitem WarlordHelmet, -1, 1; + end; + +OnWed0016: + restoreshopitem BoneKnife, 1; + restoreshopitem LeaderWand, 1; + restoreshopitem BromenalShield, 1; + restoreshopitem LightPlatemail, 1; + restoreshopitem BromenalPants, 1; + restoreshopitem CandleHelmet, 1; + restoreshopitem WarlordHelmet, 1; + end; + +OnClock1149: + restoreshopitem InsuranceContract, 1; + restoreshopitem ThornAmmoBox, 5; + restoreshopitem PileOfAsh, 25; +OnClock2359: + restoreshopitem HomunResetPotion, 5; + restoreshopitem PurificationPotion, 20; + restoreshopitem AtroposMixture, 50; + restoreshopitem PoisonAmmoBox, 10; + restoreshopitem CursedAmmoBox, 15; + end; +} + |