// 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 { // Respect SC_SILENCE if (getstatus(SC_SILENCE)) return; // 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*3)) - ((.@agi + .@dex / 2) * 5 / 3); .@del = max(10, .@del); 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) * 11 / 10; 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 = 10 + (min(readparam2(bInt), 150) / 15) + (.@PW/5); .@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; }