diff options
author | Jesusaves <cpntb1@ymail.com> | 2023-06-30 23:16:02 -0300 |
---|---|---|
committer | Jesusaves <cpntb1@ymail.com> | 2023-06-30 23:16:02 -0300 |
commit | 4df5a7396cac11a600f3acfb69649a2ab977ceca (patch) | |
tree | 7ad8ced05ea33498ea03c90dfb24544321f476c5 /npc | |
parent | 01111a347ba3546b941c73c8ad70e9507b8d1f9b (diff) | |
download | serverdata-4df5a7396cac11a600f3acfb69649a2ab977ceca.tar.gz serverdata-4df5a7396cac11a600f3acfb69649a2ab977ceca.tar.bz2 serverdata-4df5a7396cac11a600f3acfb69649a2ab977ceca.tar.xz serverdata-4df5a7396cac11a600f3acfb69649a2ab977ceca.zip |
Add Magic System
Diffstat (limited to 'npc')
-rw-r--r-- | npc/033-2/_import.txt | 1 | ||||
-rw-r--r-- | npc/033-2/magic.txt | 254 | ||||
-rw-r--r-- | npc/033-4/malindou.txt | 3 | ||||
-rw-r--r-- | npc/033-5/_import.txt | 1 | ||||
-rw-r--r-- | npc/033-5/tamiloc.txt | 83 |
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; +} |