summaryrefslogtreecommitdiff
path: root/npc/025-1
diff options
context:
space:
mode:
authorJesusaves <cpntb1@ymail.com>2022-10-23 21:44:22 -0300
committerJesusaves <cpntb1@ymail.com>2022-10-23 21:44:22 -0300
commita7c45a192268da2601cef47a4cdba987ae2327ca (patch)
treec5fb5b97db109fe7106496dd96498c475881046b /npc/025-1
downloadserverdata-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.txt25
-rw-r--r--npc/025-1/_import.txt17
-rw-r--r--npc/025-1/_mobs.txt13
-rw-r--r--npc/025-1/_warps.txt3
-rw-r--r--npc/025-1/anin.txt79
-rw-r--r--npc/025-1/commander.txt253
-rw-r--r--npc/025-1/ctrl.c572
-rw-r--r--npc/025-1/drahcir.txt16
-rw-r--r--npc/025-1/ihclot.txt148
-rw-r--r--npc/025-1/phoenix.txt230
-rw-r--r--npc/025-1/rum.txt181
-rw-r--r--npc/025-1/salohcin.txt55
-rw-r--r--npc/025-1/selim.txt81
-rw-r--r--npc/025-1/teleporter.txt23
-rw-r--r--npc/025-1/xovilam.txt47
-rw-r--r--npc/025-1/yuko.txt71
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;
+}
+