summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesusaves <cpntb1@ymail.com>2023-06-30 23:16:02 -0300
committerJesusaves <cpntb1@ymail.com>2023-06-30 23:16:02 -0300
commit4df5a7396cac11a600f3acfb69649a2ab977ceca (patch)
tree7ad8ced05ea33498ea03c90dfb24544321f476c5
parent01111a347ba3546b941c73c8ad70e9507b8d1f9b (diff)
downloadserverdata-4df5a7396cac11a600f3acfb69649a2ab977ceca.tar.gz
serverdata-4df5a7396cac11a600f3acfb69649a2ab977ceca.tar.bz2
serverdata-4df5a7396cac11a600f3acfb69649a2ab977ceca.tar.xz
serverdata-4df5a7396cac11a600f3acfb69649a2ab977ceca.zip
Add Magic System
-rw-r--r--npc/033-2/_import.txt1
-rw-r--r--npc/033-2/magic.txt254
-rw-r--r--npc/033-4/malindou.txt3
-rw-r--r--npc/033-5/_import.txt1
-rw-r--r--npc/033-5/tamiloc.txt83
5 files changed, 341 insertions, 1 deletions
diff --git a/npc/033-2/_import.txt b/npc/033-2/_import.txt
index 6941e78..7f4b3ac 100644
--- a/npc/033-2/_import.txt
+++ b/npc/033-2/_import.txt
@@ -1,3 +1,4 @@
// Map 033-2: Building 1
// This file is generated automatically. All manually added changes will be removed when running the Converter.
"npc/033-2/_warps.txt",
+"npc/033-2/magic.txt",
diff --git a/npc/033-2/magic.txt b/npc/033-2/magic.txt
new file mode 100644
index 0000000..fc5cc91
--- /dev/null
+++ b/npc/033-2/magic.txt
@@ -0,0 +1,254 @@
+// TMW2 Script
+// Author:
+// Jesusalva
+// Description:
+// Magic Blackbox
+// Contains the internals for Scripture skill.
+/* Type dictionary:
+ 0 = Do nothing
+ 1 = areaharm (healing will multiply power by -1)
+ 2 = areasc
+ 4 = summon elemental
+ */
+
+033-2,49,27,0 script Grandmaster NPC_BLUESAGE,{
+ mesn;
+ mes l("In the Crossroads, magic works differently. Chants have a flexible structure and are awfully powerful.");
+ next;
+ mesn;
+ mes l("The basic structure, for example, is:");
+ mesc l("Great fire, destroy everything!"), 1;
+ next;
+ mesn;
+ mes l("The first word is the ##Bintensity##b: Meager, Violent, Great, Epic, Legendary.");
+ mes l("The second word is the ##Belement##b: magic, fire, water, sacrament, darkness, hocus.");
+ mes l("The third word is the ##Baction##b: destroy, manifest, heal, blind, curse, poison, neutralize.");
+ mes l("The fourth and last word is the ##Brange##b: me, here, around, everything, everywhere.");
+ //mesc l("The range is centered on... I'm not sure. I believe on you!");
+ next;
+ mesn;
+ mes l("The more powerful the chant is, the more mana is consumed. If you don't have enough mana, your health will also be drained. \"Manifest\" is a summoning magic, \"neutralize\" will temporarily stop monsters, and the others... should be self-evident.");
+ mes l("Sacrament is holy magic. Hocus is actually ethereal magic, with extremely limited uses. Magic is a neutral element. You cannot use nature magic, I'm not sure why, but monsters can - so consider the element you'll use carefully.");
+ close;
+OnInit:
+ .distance=6;
+ end;
+}
+
+
+
+
+function script Crossroads_Magic {
+ // Structure: "«Power» «Element», «Action» «Range»!"
+ .@msg$ = getarg(0);
+ explode(.@x$, .@msg$, " ");
+
+ // Not enough arguments
+ if (getarraysize(.@x$) != 4) return;
+
+ // Prepare the environment variables, including offset
+ .@o = 0; // Array Offset
+ .@Cost = 0; // MP Cost
+ .@PW = 20; // Power (in % of MATK)
+ .@RG = 0; // Range (circular tiles)
+ .@EL = 0; // Element
+ .@TY = 0; // Type uses a special logic
+ .@SC = 0; // Status Condition, if any
+ .@F$ = "filter_hostile"; // Skill Target
+
+ // Power word (optional)
+ .@mp = 10+(readparam2(bInt)*20);
+ .@w$ = .@x$[.@o];
+ if (.@w$ == "meager") {
+ .@PW += min(25, .@mp);
+ .@Cost += 25;
+ } else if (.@w$ == "violent") {
+ .@PW += min(50, .@mp);
+ .@Cost += 50;
+ } else if (.@w$ == "great") {
+ .@PW += min(75, .@mp);
+ .@Cost += 75;
+ } else if (.@w$ == "epic") {
+ .@PW += min(100, .@mp);
+ .@Cost += 100;
+ } else if (.@w$ == "legendary") {
+ .@PW += min(150, .@mp);
+ .@Cost += 150;
+ } else {
+ // Not a valid power, so not a valid magic
+ return;
+ }
+ .@o += 1;
+
+ // Element
+ .@w$ = .@x$[.@o];
+ if (.@w$ == "magic") {
+ .@EL = Ele_Neutral;
+ } else if (.@w$ == "water" ||
+ .@w$ == "ice") {
+ .@EL = Ele_Water;
+ } else if (.@w$ == "fire") {
+ .@EL = Ele_Fire;
+ } else if (.@w$ == "sacrament") {
+ .@EL = Ele_Holy;
+ } else if (.@w$ == "darkness") {
+ .@EL = Ele_Dark;
+ } else if (.@w$ == "hocus") {
+ .@EL = Ele_Ghost;
+ } else {
+ // Not a valid element, so not a valid magic
+ return;
+ }
+ .@o += 1;
+
+ // Action Verb
+ .@w$ = .@x$[.@o];
+ /* Damage Only */
+ if (.@w$ == "destroy" ||
+ .@w$ == "beat" ||
+ .@w$ == "eviscerate") {
+ .@TY = 1;
+ .@PW += rand2(3);
+ /* HP recovery */
+ } else if (
+ .@w$ == "heal" ||
+ .@w$ == "recover") {
+ .@PW *= -1;
+ .@TY = 1;
+ .@F$ = "filter_friendlynotme";
+ /* Damage + Ailment */
+ } else if (.@w$ == "blind") {
+ .@SC = SC_BLIND;
+ .@TY = 1 | 2;
+ .@Cost *= 2;
+ .@PW /= 2;
+ if (.@EL != Ele_Ghost) .@PW = .@PW * 4 / 5; // Bonus: Hocus
+ } else if (.@w$ == "curse") {
+ .@SC = SC_CURSE;
+ .@TY = 1 | 2;
+ .@Cost *= 2;
+ .@PW /= 2;
+ if (.@EL != Ele_Ghost) .@PW = .@PW * 4 / 5; // Bonus: Hocus
+ } else if (.@w$ == "poison") {
+ .@SC = SC_POISON;
+ .@TY = 1 | 2;
+ .@Cost *= 2;
+ .@PW /= 2;
+ if (.@EL != Ele_Ghost) .@PW = .@PW * 4 / 5; // Bonus: Hocus
+ } else if (.@w$ == "tranquilize" || .@w$ == "neutralize") {
+ .@SC = SC_SLEEP;
+ .@TY = 1 | 2;
+ .@Cost *= 2;
+ .@PW /= 2;
+ if (.@EL != Ele_Ghost) .@PW = .@PW * 4 / 5; // Bonus: Hocus
+ /* Elemental Summoning */
+ } else if (.@w$ == "manifest") {
+ .@TY = 4;
+ } else {
+ // Invalid magic type
+ return;
+ }
+ .@o += 1;
+
+ // Range or filter, please do not simplify the fractions
+ .@w$ = .@x$[.@o];
+ if (.@w$ == "me") {
+ .@F$ = "filter_onlyme";
+ .@Cost /= 2;
+ } else if (.@w$ == "here") {
+ .@RG = 1;
+ .@Cost = .@Cost * 12 / 10;
+ } else if (.@w$ == "around") {
+ .@RG = 3;
+ .@PW = .@PW * 9 / 10;
+ .@Cost = .@Cost * 14 / 10;
+ } else if (.@w$ == "everything") {
+ .@RG = 5;
+ .@PW = .@PW * 7 / 10;
+ .@Cost = .@Cost * 16 / 10;
+ } else if (.@w$ == "everywhere") {
+ .@RG = 7;
+ .@PW = .@PW * 5 / 10;
+ .@Cost = .@Cost * 18 / 10;
+ } else {
+ // Invalid range
+ return;
+ }
+ .@o+=1;
+
+ /* Final Adjustments */
+ // This spell is too costly currently as it is based on ML, give a discount
+ .@Cost = .@Cost * 2 / 5;
+
+ // Cast Delay
+ .@agi = min(readparam2(bAgi), 150);
+ .@dex = min(readparam2(bDex), 150);
+ .@agi += rand2(readparam2(bLuk)) / 5;
+ .@dex += rand2(readparam2(bVit)) / 5;
+ .@del = (500 + .@PW) - ((.@agi + .@dex / 2) * 5 / 3);
+ sleep2(.@del);
+
+ // Check if you were killed while casting
+ if (ispcdead())
+ return;
+
+ /* Note: You cannot heal if MP cost go over, to stop cheaters */
+ if (.@PW < 0 && .@Cost > Sp)
+ return;
+
+ /* Chanting success! */
+ if ($@GM_OVERRIDE)
+ debugmes "Chanting » \"%s\" (PW %d Cost %d)", .@msg$, .@PW, .@Cost;
+ /* Deduct the MP, HP is paid in a 3:1 ratio */
+ if (.@Cost > Sp)
+ Hp -= (.@Cost - Sp) * 3;
+ Sp -= min(.@Cost, Sp);
+
+ // areaharm()
+ if (.@TY & 1) {
+ .@dmg = AdjustSpellpower(.@PW);
+ areaharm(getcharid(3), .@RG, .@dmg, HARM_MAGI, .@EL, .@F$);
+ }
+
+ // areasc()
+ if (.@TY & 2) {
+ .@ch = 60 * readparam2(bInt); // 0.6% per intelligence point
+ .@du = (readparam2(bVit) + readparam2(bInt)) * 10; // 0.1s per str+int
+ // Power multipliers
+ .@du *= .@PW / 100;
+ .@ch *= .@PW / 100;
+ areasc(.@RG, .@du, .@SC, BL_MOB|BL_PC|BL_HOM|BL_MER, 1, .@F$, getcharid(3), .@ch);
+ }
+
+ // summon()
+ if (.@TY & 4) {
+ switch (.@EL) {
+ case Ele_Neutral: .@MB = ElectroWorm; break;
+ case Ele_Water: .@MB = WaterFairy; break;
+ case Ele_Fire: .@MB = FireFairy; break;
+ case Ele_Holy: .@MB = PoisonFairy; break;
+ case Ele_Dark: .@MB = BlackScorpion; break;
+ case Ele_Ghost: .@MB = MisterPrickel; break;
+ default: .@MB = Assassin; break; // ???
+ }
+ .@t = 1 + (min(readparam2(bInt), 150) / 15) + (.@PW/10);
+ .@a = 1 + (.@PW/25) + (.@RG/2); // Amount of spawns
+ // Actual summoning core
+ for (.@i=0; .@i < .@a; .@i++) {
+ .@m = summon("Summoned Monster", .@MB, .@t);
+ /* Monster final stats depends on the power you're using */
+ .@bhp = getunitdata(.@m, UDT_MAXHP);
+ .@ak1 = getunitdata(.@m, UDT_ATKMIN);
+ .@ak2 = getunitdata(.@m, UDT_ATKMAX);
+ .@bhp = .@bhp * (.@PW) / 100;
+ .@ak1 = .@ak1 * (.@PW) / 100;
+ .@ak2 = .@ak2 * (.@PW) / 100;
+ setunitdata(.@m, UDT_MAXHP, .@bhp);
+ setunitdata(.@m, UDT_HP, .@bhp);
+ setunitdata(.@m, UDT_ATKMIN, .@ak1);
+ setunitdata(.@m, UDT_ATKMAX, .@ak2);
+ }
+ }
+ return;
+}
+
diff --git a/npc/033-4/malindou.txt b/npc/033-4/malindou.txt
index 9403e27..4b8040b 100644
--- a/npc/033-4/malindou.txt
+++ b/npc/033-4/malindou.txt
@@ -109,7 +109,8 @@ OnGlobalChat:
.@msg$ = replacestr(.@msg$, ">", "");
.@msg$ = replacestr(.@msg$, "*", "");
- // SK_Scripture(.@msg$); // TODO: This is necessary for magic hack (CR)
+ // Magic System
+ callfunc "Crossroads_Magic", .@msg$;
end;
// Level up events
diff --git a/npc/033-5/_import.txt b/npc/033-5/_import.txt
index d6b8ba2..c6e4a1f 100644
--- a/npc/033-5/_import.txt
+++ b/npc/033-5/_import.txt
@@ -2,3 +2,4 @@
// This file is generated automatically. All manually added changes will be removed when running the Converter.
"npc/033-5/_warps.txt",
"npc/033-5/shop.txt",
+"npc/033-5/tamiloc.txt",
diff --git a/npc/033-5/tamiloc.txt b/npc/033-5/tamiloc.txt
new file mode 100644
index 0000000..e43635b
--- /dev/null
+++ b/npc/033-5/tamiloc.txt
@@ -0,0 +1,83 @@
+// TMW2 scripts.
+// Authors:
+// Saulc
+// Jesusalva
+// Reid
+// Travolta
+// Description:
+// We also need specific barbers for other games I guess? This is ML's.
+
+033-5,46,22,0 script Tamiloc 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?"),
+ 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;
+}