summaryrefslogtreecommitdiff
path: root/world/map/npc/magic/level2-rain.txt
blob: 291af009d947559206fc493c278db989462e32a0 (plain) (blame)
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
-|script|rain|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 (getskilllv(.school) < 4 && countitem("BottleOfWater") < 1) end;
    if (Sp < 17) 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 (getmap() == "033-1") goto L_SpecialRules6;
    goto L_Pay;

L_Pay:
    if (getskilllv(.school) < 4) delitem "BottleOfWater", 1;
    set Sp, Sp - 17;
    set CASTS, CASTS + 1;
    if (CASTS < 0) set CASTS, 1; // overflow
    set @_M_BLOCK, 1; // block casting, until the timer clears it
    addtimer 3000, "Magic Timer::OnClear"; // set the new debuff
    sc_start SC_COOLDOWN, 3000, 0, BL_ID;
    sc_start SC_COOLDOWN_R, 30000, 0, BL_ID; // Set it to lenght of timeout

    callfunc "adjust_spellpower";
    set @krad, min(.max_radius,(min(@spellpower,200)/30)+3); // kaflosh radius

    set @nearby, 0;
    foreach 1, getmap(), POS_X - .max_radius, POS_Y - .max_radius, POS_X + .max_radius, POS_Y + .max_radius,
            strnpcinfo(0) + "::OnNearbyNpc";
    if (@nearby) goto L_Absorb;

    set @new_npc_name$, "#" + strnpcinfo(0) + "#" + getcharid(3); // make a unique puppet name for every player
    callfunc "magic_exp";
    misceffect FX_MAGIC_RAIN_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 .caster, getcharid(3), @spell_npc; // tell the puppet who controls it
    set .radius, @krad, @spell_npc; // this is also used by ingrav, don't rename
    set .initial_x, POS_X, @spell_npc;
    set .initial_y, POS_Y, @spell_npc;
    set .max, @spellpower/3, @spell_npc;
    set .max_launch, min(200,@spellpower/2)/100, @spell_npc;
    donpcevent @new_npc_name$+"::OnLaunch"; // start
    addnpctimer 30000, @new_npc_name$+"::OnDestroy"; // this is just a failsafe in case the npc is not properly destroyed
    if(isin("011-1", 85, 31, 103, 45)) goto L_Pumpkins;
    end;

L_Absorb:
    message strcharinfo(0), "##3Rain : ##BA nearby raincloud absorbs your magic.";
    end;

OnNearbyNpc:
    explode .@nearby$[0], strnpcinfo(0,@target_id), "#";
    if(.@nearby$[0] == "DruidTree0" || .@nearby$[1] == "DruidTree0") goto L_Tree;
    if(.@nearby$[0] == "rain" || .@nearby$[1] == "rain")
        set @nearby, @nearby + 1;
    end;

L_Pumpkins:
    callfunc "HalloweenQuestWaterPumpkins";
    end;

L_Tree:
    set .@x, get(POS_X, @target_id); set .@y, get(POS_Y, @target_id);
    if (.@x < POS_X-@krad || .@y < POS_Y-@krad || .@x > POS_X+@krad || .@y > POS_Y+@krad) end; // in max radius but not in puppet area
    set @flag, 1;
    callfunc "QuestTreeTrigger";
    close;

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 .count, .count + 1;
    if(.count > .max) goto L_Destroy;
    goto L_Launch;

L_Launch:
    set .launch, 0;
    callsub S_Launch;
    addnpctimer 400 + rand(100), strnpcinfo(0)+"::OnLaunch"; // loop until max
    end;

S_Launch:
    npcareawarp .initial_x - .radius, .initial_y - .radius, .initial_x + .radius, .initial_y + .radius, 0, strnpcinfo(0);
    misceffect FX_RAIN;
    foreach 2, strnpcinfo(3), getnpcx()-1, getnpcy()-1, getnpcx()+1, getnpcy()+1, strnpcinfo(0) + "::OnHit", .caster;
    set .launch, .launch + 1;
    if(.launch < .max_launch) goto S_Launch;
    return;

L_Destroy:
    if (attachrid(.caster)) sc_end SC_COOLDOWN_R;
    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
    if(get(ELTTYPE, @target_id) == ELT_FIRE)
        injure .caster, @target_id, ((rand((@spellpower/15)+5)+2) * (100 - get(MDEF1, @target_id))) / 100;
    if ($NO_RAIN_SPAWNS) end;                     // server-wide killswitch for rain pranks if spawns logic would backfire.
    if (mobcount(getmap(), "rain::OnRainSpawnDeath") > 30) end; // Abort if too crowded.
    if(get(Class, @target_id) == EntAbomination)                // Rain hit Ent? This scores little perk!
        monster getmap(), getnpcx(), getnpcy(), "", LogHead, 1+rand(1+(.max/150)), "rain::OnRainSpawnDeath";
    if((get(Class, @target_id) == LogHead) && (rand(5) == 3))   // Rain hit LogHead? Little perk as well (plants)
        monster getmap(), getnpcx(), getnpcy(), "", MauvePlant+rand(5), 1, "rain::OnRainSpawnDeath";
    end;

OnRainSpawnDeath:
    end;

OnDestroy:
    debugmes "kaflosh timeout! [this shouldn't happen]"; // XXX: looks like this CAN happen with higher levels of magic, so we might want to cap max charges
    destroy;

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_NATURE;
    set .invocation$, chr(MAGIC_SYMBOL) + "kaflosh"; // used in npcs that refer to this spell
    void call("magic_register", "OnCast");
    set .level, 2;
    set .exp_gain, 1;
    set .max_radius, 15;
    end;
}