1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
-|script|arrow-hail|32767
{
// we can not start here because for the puppets this is OnClick
end;
OnCast:
if(call("magic_checks")) end;
if (getskilllv(.school) < .level) end;
if (getskilllv(SKILL_MAGIC) < .level) end;
if (Sp < 25) end;
explode .@map_ext[0], getmap(), "-";
if (.@map_ext[1] != 1 && getmap() != "099-5") end; // XXX this is fugly, in the future let's use MF_OUTSIDE to detect if a map is "outside" or "inside"
if (getmapflag(getmap(), MF_TOWN)) end;
if (countitem("Arrow") >= 20 && countitem("SulphurPowder") >= 1) goto L_Continue;
elif (countitem("IronArrow") >= 20 && countitem("SulphurPowder") >= 1) goto L_Continue;
else end;
goto L_Continue;
L_Continue:
if (getmap() == "033-1") goto L_SpecialRules6;
goto L_Pay;
L_Pay:
if (countitem("Arrow") >= 20) delitem "Arrow", 20;
else delitem "IronArrow", 20;
delitem "SulphurPowder", 1;
set Sp, Sp - 25;
set CASTS, CASTS + 1;
if (CASTS < 0) set CASTS, 1; // overflow
set @_M_BLOCK, 1; // block casting, until the timer clears it
addtimer 5000, "Magic Timer::OnClear"; // set the new debuff
sc_start SC_COOLDOWN, 5000, 0, BL_ID;
sc_start SC_COOLDOWN_AR, 30000, 0, BL_ID; // Set it to lenght of timeout
setarray @away[0], POS_X, POS_Y, getdir(), (.range + 1), 0;
callsub S_AwayFrom;
set @nearby, 0;
foreach 1, getmap(), @away[0] - 14, @away[1] - 14, @away[0] + 14, @away[1] + 14,
strnpcinfo(0) + "::OnNearbyNpc";
if (@nearby) goto L_Absorb;
callfunc "adjust_spellpower";
set @new_npc_name$, "#" + strnpcinfo(0) + "#" + getcharid(3); // make a unique puppet name for every player
callfunc "magic_exp";
misceffect FX_MAGIC_AHAIL_CAST, strcharinfo(0);
set @spell_npc, puppet(getmap(), POS_X, POS_Y, @new_npc_name$, 127); // clone npc => get puppet id
if (@spell_npc < 1) end;
set .max_hit, (@spellpower / 8), @spell_npc; // set .max_hit in the puppet
set .caster, getcharid(3), @spell_npc; // tell the puppet who controls it
set .damage, 125, @spell_npc;
set .damage_bonus, (@spellpower / 5), @spell_npc;
set .area_x, @away[0], @spell_npc; set .area_y, @away[1], @spell_npc;
donpcevent @new_npc_name$+"::OnLaunch"; // start the puppet timer and strike
initnpctimer @new_npc_name$; // start the destroy timer
end;
S_AwayFrom:
if(@away[2] == 6 && !(iscollision(getmap(), (@away[0] + 1), @away[1]))) // right
set @away[0], @away[0] + 1;
if(@away[2] == 4 && !(iscollision(getmap(), @away[0], (@away[1] - 1)))) // up
set @away[1], @away[1] - 1;
if(@away[2] == 2 && !(iscollision(getmap(), (@away[0] - 1), @away[1]))) // left
set @away[0], @away[0] - 1;
if(@away[2] == 0 && !(iscollision(getmap(), @away[0], (@away[1] + 1)))) // down
set @away[1], @away[1] + 1;
set @away[4], @away[4] + 1;
if(@away[4] < @away[3]) goto S_AwayFrom;
return;
L_Absorb:
message strcharinfo(0), "##3Arrow Hail : ##BA nearby arrow hail absorbs your magic!";
end;
OnNearbyNpc:
explode .@nearby$[0], strnpcinfo(0,@target_id), "#";
if(.@nearby$[0] == "arrow-hail" || .@nearby$[1] == "arrow-hail")
set @nearby, @nearby + 1;
end;
OnLaunch:
if (!(isloggedin(.caster))) destroy;
if(get(Hp, .caster) < 1) destroy; // destroy if caster is missing
if(getmap(.caster) != strnpcinfo(3)) destroy; // destroy if caster left the map
set .hit, .hit + 1;
if(.hit > .max_hit) goto L_Destroy;
goto L_Launch;
L_Launch:
set .launch, 0;
callsub S_Launch;
addnpctimer 250 + rand(50) + rand(50), strnpcinfo(0)+"::OnLaunch"; // loop until max
end;
S_Launch:
npcareawarp .area_x - 6, .area_y - 6, .area_x + 6, .area_y + 6, 0, strnpcinfo(0);
misceffect FX_ARROW_HAIL;
set .done, 0;
foreach 2, strnpcinfo(3), getnpcx(), getnpcy(), getnpcx(), getnpcy(), strnpcinfo(0) + "::OnHit", .caster;
if (get(PVP_CHANNEL, .caster) || getmapflag(getmap(.caster), MF_PVP))
foreach 0, strnpcinfo(3), getnpcx(), getnpcy(), getnpcx(), getnpcy(), strnpcinfo(0) + "::OnHit", .caster;
if(!.done && get(POS_X, .caster) == getnpcx() && get(POS_Y, .caster) == getnpcy())
set Hp, get(Hp, .caster) - (.damage + rand(.damage_bonus) + rand(.damage_bonus)), .caster; // injure caster
set .launch, .launch + 1;
if(.launch < 3) goto S_Launch;
return;
L_Destroy:
if (attachrid(.caster)) sc_end SC_COOLDOWN_AR;
destroy;
OnTimer30000:
debugmes "frillyar timeout! [this shouldn't happen]";
destroy;
OnHit:
if (!(isloggedin(.caster))) destroy;
if(get(Hp, .caster) < 1) destroy; // destroy if caster is missing
if(getmap(.caster) != strnpcinfo(3)) destroy; // destroy if caster left the map
if(target(.caster, @target_id, 16) != 16 && .caster != @target_id) end;
if((get(BL_TYPE, @target_id) & 1) == 0) end; // either mob or pc
set .@damage, .damage + rand(.damage_bonus) + rand(.damage_bonus);
if(.caster != @target_id)
set .@damage, (.@damage * (100 - get(MDEF1, @target_id))) / 100;
injure .caster, @target_id, .@damage;
set .done, 1;
end;
L_SpecialRules6:
if ($@KIMARR_EVENT < 1) goto L_Pay;
if ($@Fluffy_FighterID == BL_ID) goto L_Pay;
message strcharinfo(0), "You can't use this spell here unless hunting fluffies.";
end;
OnInit:
set .school, SKILL_MAGIC_WAR;
set .range, 7;
set .invocation$, chr(MAGIC_SYMBOL) + "frillyar"; // used in npcs that refer to this spell
void call("magic_register", "OnCast");
set .level, 2;
set .exp_gain, 2;
end;
}
|