summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--npc/config/magic.txt39
-rw-r--r--npc/functions/filters.txt42
-rw-r--r--npc/functions/hub.txt27
3 files changed, 97 insertions, 11 deletions
diff --git a/npc/config/magic.txt b/npc/config/magic.txt
index 340f89c08..b0ebea7a6 100644
--- a/npc/config/magic.txt
+++ b/npc/config/magic.txt
@@ -112,6 +112,45 @@ function script SummonMagic {
return;
}
+// areaharm(target, range, DMG, {type, element, filter, bl})
+// Defaults to HARM_MISC, Ele_Neutral, filter filter_hostile and all BLs
+// Valid BL: BL_MOB | BL_PC | BL_HOM | BL_MER
+// Do not use: NPC, PET, ELEM
+// Range centers on caster (player), implement and use areaharm2 elsewhere
+function script areaharm {
+ .@t=getarg(0);
+ .@r=getarg(1);
+ .@d=getarg(2);
+ .@h=getarg(3, HARM_MISC);
+ .@e=getarg(4, Ele_Neutral);
+ .@f$=getarg(5, "filter_hostile");
+ .@b=getarg(6, BL_PC | BL_MOB | BL_MER | BL_HOM);
+
+ // FIXME: Retrieve from .@t not from "0"/caster
+ //getmapxy(.@m$, .@x, .@y, 0);
+ // Ideally we would have @skillTargetX/Y and not use getmap() but meh
+ .@m$=getmap();
+ getunitdata(.@t, UDT_MAPIDXY, .@loc);
+ .@x=.@loc[1];
+ .@y=.@loc[2];
+ debugmes("Loc %s (%d, %d) - Real loc %s", .@m$, .@x, .@y, str(.@loc[0]));
+
+ .@c=getunits(.@b, .@mbs, false, .@m$, .@x-.@r, .@y-.@r, .@x+.@r, .@y+.@r);
+ debugmes "Begin";
+ for (.@i = 0; .@i < .@c; .@i++) {
+ // Filtering
+ if (!callfunc(.@f$, .@mbs[.@i]))
+ continue;
+ debugmes "Target %d", .@mbs[.@i];
+ harm(.@mbs[.@i], .@d, .@t, .@e);
+ debugmes "Harmed";
+ specialeffect(FX_ATTACK, AREA, .@mbs[.@i]);
+ debugmes "FX'ed";
+ }
+ debugmes "Done";
+ return;
+}
+
// mescordialog(text, color, {dialog=1})
function script mescordialog {
if (getarg(2, true))
diff --git a/npc/functions/filters.txt b/npc/functions/filters.txt
index cec7a15af..f47c16beb 100644
--- a/npc/functions/filters.txt
+++ b/npc/functions/filters.txt
@@ -62,6 +62,48 @@ function script filter_sameguildorpartynotyou {
return ((getcharid(1) > 0 && .@party) || (getcharid(2) > 0 && .@guild));
}
+// filter_hostile( id )
+function script filter_hostile {
+ debugmes "filter_hostile %d", getarg(0);
+ .@type=getunitdata(getarg(0), UDT_TYPE);
+ .@chkid=getarg(0);
+
+ debugmes "filter_hostile: Checking %d (BL %d)", getarg(0), .@type;
+
+ // Monsters
+ if (.@type == BL_MOB)
+ return true;
+
+ // NPCs
+ if (.@type == BL_NPC)
+ return false;
+
+ // Homunculus
+ if (.@type == BL_HOM)
+ .@chkid=charid2rid(getunitdata(getarg(0), UDT_MASTERCID));
+
+ // Pets
+ if (.@type == BL_PET)
+ .@chkid=getunitdata(getarg(0), UDT_MASTERAID);
+
+ // Mercenaries
+ if (.@type == BL_MER)
+ .@chkid=charid2rid(getunitdata(getarg(0), UDT_MASTERCID));
+
+ // Elementals
+ if (.@type == BL_ELEM)
+ .@chkid=charid2rid(getunitdata(getarg(0), UDT_MASTERCID));
+
+ debugmes "filter_hostile: Filtering %d (original %d) (BL %d)", .@chkid, getarg(0), .@type;
+ // Players (and slaves)
+ return !(filter_sameguildorparty(.@chkid));
+}
+
+// filter_friendly( id )
+function script filter_friendly {
+ return !(filter_hostile(.@chkid));
+}
+
// filter_notboss( id )
function script filter_notboss {
// 32 = MD_BOSS
diff --git a/npc/functions/hub.txt b/npc/functions/hub.txt
index eade2a4d5..eb5a1f63c 100644
--- a/npc/functions/hub.txt
+++ b/npc/functions/hub.txt
@@ -305,7 +305,8 @@ function script HUB_SkillInvoke {
debugmes "Target: %d (%d,%d)", @skillTarget, @skillTargetX, @skillTargetY;
areasc2(getmap(), @skillTargetX, @skillTargetY, 2, 10000, SC_BLOODING, BL_MOB|BL_PC);
.@dmg=AdjustSpellpower(300);
- harm(@skillTarget, .@dmg, HARM_MAGI, Ele_Holy);
+ //harm(@skillTarget, .@dmg, HARM_MAGI, Ele_Holy);
+ areaharm(@skillTarget, 8, .@dmg, HARM_MAGI, Ele_Holy);
break;
/*
case TMW2_MANABOMB:
@@ -314,14 +315,14 @@ function script HUB_SkillInvoke {
// And is a trick. Each level improves ratio in 1
// Has no cooldown, so it is powerful with pots
// And is a good starter offensive skill
- harm(@skillTarget, Sp*@skillLv, HARM_MAGI, Ele_Ghost);
+ areaharm(@skillTarget, 0, Sp*@skillLv, HARM_MAGI, Ele_Ghost);
Sp=0;
break;
// Weapon Overload attack
case TMW2_OVERLOAD:
.@PW=67+(33*@skillLv);
- harm(@skillTarget, AdjustAttackpower(.@PW), HARM_MISC);
+ areaharm(@skillTarget, 0, AdjustAttackpower(.@PW), HARM_MISC);
break;
// TODO: Ultimate Skills (T5/0)
@@ -340,9 +341,9 @@ function script HUB_SkillInvoke {
harm(@skillTarget, -AdjustSpellpower(.@PW), HARM_MISC);
break;
case TMW2_MAGNUSHEAL:
- // TODO: Area healing
+ // Area healing
.@PW=200+(20*@skillLv);
- harm(@skillTarget, -AdjustSpellpower(.@PW), HARM_MISC);
+ areaharm(@skillTarget, 4, -AdjustSpellpower(.@PW), HARM_MISC, "filter_friendly");
break;
// Provoke: builtin, Mass Provoke: See above
@@ -356,14 +357,12 @@ function script HUB_SkillInvoke {
break;
case TMW2_FIREBALL:
.@PW=140+(10*@skillLv);
- // TODO: areaharm()
- harm(@skillTarget, AdjustSpellpower(.@PW), HARM_MAGI, Ele_Fire);
+ areaharm(@skillTarget, 3, AdjustSpellpower(.@PW), HARM_MAGI, Ele_Fire);
break;
case TMW2_ARMAGEDDON:
.@PW=140+(10*@skillLv);
- // TODO: areaharm()
areasc2(getmap(), @skillTargetX, @skillTargetY, 2, 10000, SC_BLOODING, BL_MOB|BL_PC);
- harm(@skillTarget, AdjustSpellpower(.@PW), HARM_MAGI, Ele_Fire);
+ areaharm(@skillTarget, 8, AdjustSpellpower(.@PW), HARM_MAGI, Ele_Fire);
break;
case TMW2_FROSTDIVER:
@@ -377,9 +376,15 @@ function script HUB_SkillInvoke {
// TODO: All this in area
// 8% chance, 10s
sc_start SC_FREEZE, 10000, 1, 800, flag?, @skillTarget;
- harm(@skillTarget, AdjustSpellpower(.@PW), HARM_MAGI, Ele_Water);
+ areaharm(@skillTarget, 6, AdjustSpellpower(.@PW), HARM_MAGI, Ele_Water);
+ break;
+ case TMW2_NILFHEIM:
+ // FIXME SK_Nilfheim
+ // Nilfheim cast on self?
+ .@PW=80+(10*@skillLv);
+ areasc(8, 10000, SC_FREEZE, BL_PC | BL_MOB | BL_MER | BL_HOM, "filter_hostile"); // Maybe filter_notme() would work better, indeed
+ areaharm(getcharid(3), 8, AdjustSpellpower(.@PW), HARM_MAGI, Ele_Water);
break;
- // FIXME SK_Nilfheim
case TMW2_MAGICSTRIKE:
case TMW2_LIGHTNINGBOLT: