summaryrefslogtreecommitdiff
path: root/src/emap/skill.c
blob: 30aa9c735f6e090e65d9142481fe6593ef5abcb0 (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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
// Copyright (c) Copyright (c) Hercules Dev Team, licensed under GNU GPL.
// Copyright (c) 2014 - 2015 Evol developers

#include "common/hercules.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "common/conf.h"
#include "common/db.h"
#include "common/HPMi.h"
#include "common/memmgr.h"
#include "common/mmo.h"
#include "common/nullpo.h"
#include "common/socket.h"
#include "common/strlib.h"
#include "common/timer.h"
#include "map/pc.h"
#include "map/npc.h"
#include "map/script.h"

#include "emap/skill.h"
#include "emap/skill_const.h"
#include "emap/skill_ground.h"
#include "emap/skill_targeted.h"
#include "emap/status.h"
#include "emap/data/skilld.h"
#include "emap/struct/skilldext.h"

#include "plugins/HPMHooking.h"

int eskill_get_index_post(int retVal,
                          int skill_id)
{
    if (skill_id >= EVOL_FIRST_SKILL && skill_id < EVOL_FIRST_SKILL + MAX_EVOL_SKILLS)
    {
        // 1478 + skill_id - 20000
        skill_id = OLD_MAX_SKILL_DB + skill_id - EVOL_FIRST_SKILL;
        return skill_id;
    }
    return retVal;
}

int eskill_check_condition_castend_post(int retVal,
                                        TBL_PC* sd __attribute__ ((unused)),
                                        uint16 skill_id __attribute__ ((unused)),
                                        uint16 skill_lv __attribute__ ((unused)))
{
    return retVal;
}

bool eskill_castend_nodamage_id_unknown(struct block_list *src,
                                        struct block_list *bl,
                                        uint16 *skill_id,
                                        uint16 *skill_lv,
                                        int64 *tick __attribute__ ((unused)),
                                        int *flag __attribute__ ((unused)))
{
    switch (*skill_id)
    {
        case EVOL_PHYSICAL_SHIELD:
            eskill_physical_shield(src, bl, *skill_id, *skill_lv);
            break;

        default:
            clif->skill_nodamage(src, bl, *skill_id, *skill_lv, 1);
            break;
    }

    struct map_session_data *sd = NULL;
    sd = BL_CAST(BL_PC, src);

    if (sd)
    {
        // Add skill info
        pc->setreg(sd, script->add_variable("@skillId"), *skill_id);
        pc->setreg(sd, script->add_variable("@skillLv"), *skill_lv);
        pc->setreg(sd, script->add_variable("@skillTarget"),  bl->id);
        pc->setreg(sd, script->add_variable("@skillTargetX"), bl->x);
        pc->setreg(sd, script->add_variable("@skillTargetY"), bl->y);
        pc->setreg(sd, script->add_variable("@skillCaster"),  src->id);
        // Summon scripts
        struct linkdb_node **label_linkdb = strdb_get(npc->ev_label_db, "OnSkillInvoke");
        if (label_linkdb == NULL)
            return true;

        struct linkdb_node *node = *label_linkdb;
        while (node)
        {
            struct event_data* ev = node->data;
            if (ev)
            {
                script->run(ev->nd->u.scr.script, ev->pos, sd->bl.id, ev->nd->bl.id);
            }
            node = node->next;
        }
    }

    map->freeblock_unlock();
    return true;
}

void eskill_additional_effect_unknown(struct block_list* src __attribute__ ((unused)),
                                      struct block_list *bl __attribute__ ((unused)),
                                      uint16 *skill_id __attribute__ ((unused)),
                                      uint16 *skill_lv __attribute__ ((unused)),
                                      int *attack_type __attribute__ ((unused)),
                                      int *dmg_lv __attribute__ ((unused)),
                                      int64 *tick __attribute__ ((unused)))
{
}

void eskill_counter_additional_effect_unknown(struct block_list *src __attribute__ ((unused)),
                                              struct block_list *bl __attribute__ ((unused)),
                                              uint16 *skill_id __attribute__ ((unused)),
                                              uint16 *skill_lv __attribute__ ((unused)),
                                              int *attack_type __attribute__ ((unused)),
                                              int64 *tick __attribute__ ((unused)))
{
}

void eskill_attack_combo2_unknown(int *attack_type __attribute__ ((unused)),
                                  struct block_list *src __attribute__ ((unused)),
                                  struct block_list *dsrc __attribute__ ((unused)),
                                  struct block_list *bl __attribute__ ((unused)),
                                  uint16 *skill_id __attribute__ ((unused)),
                                  uint16 *skill_lv __attribute__ ((unused)),
                                  int64 *tick __attribute__ ((unused)),
                                  int *flag __attribute__ ((unused)),
                                  int *combo __attribute__ ((unused)))
{
}

void eskill_attack_post_unknown(int *attack_type __attribute__ ((unused)),
                                struct block_list *src __attribute__ ((unused)),
                                struct block_list *dsrc __attribute__ ((unused)),
                                struct block_list *bl __attribute__ ((unused)),
                                uint16 *skill_id __attribute__ ((unused)),
                                uint16 *skill_lv __attribute__ ((unused)),
                                int64 *tick __attribute__ ((unused)),
                                int *flag __attribute__ ((unused)))
{
}

void eskill_timerskill_notarget_unknown(int tid __attribute__ ((unused)),
                                        int64 tick __attribute__ ((unused)),
                                        struct block_list *src __attribute__ ((unused)),
                                        struct unit_data *ud __attribute__ ((unused)),
                                        struct skill_timerskill *skl __attribute__ ((unused)))
{
}

void eskill_unitsetting1_unknown(struct block_list *src __attribute__ ((unused)),
                                 uint16 *skill_id __attribute__ ((unused)),
                                 uint16 *skill_lv __attribute__ ((unused)),
                                 int16 *x __attribute__ ((unused)),
                                 int16 *y __attribute__ ((unused)),
                                 int *flag __attribute__ ((unused)),
                                 int *val1 __attribute__ ((unused)),
                                 int *val2 __attribute__ ((unused)),
                                 int *val3 __attribute__ ((unused)))
{
}

void eskill_unit_onplace_unknown(struct skill_unit *src __attribute__ ((unused)),
                                 struct block_list *bl __attribute__ ((unused)),
                                 int64 *tick __attribute__ ((unused)))
{
}

bool eskill_check_condition_castend_unknown(struct map_session_data *sd __attribute__ ((unused)),
                                            uint16 *skill_id __attribute__ ((unused)),
                                            uint16 *skill_lv __attribute__ ((unused)))
{
    return false;
}

void eskill_get_requirement_unknown(struct status_change *sc __attribute__ ((unused)),
                                    struct map_session_data *sd __attribute__ ((unused)),
                                    uint16 *skill_id __attribute__ ((unused)),
                                    uint16 *skill_lv __attribute__ ((unused)),
                                    struct skill_condition *req __attribute__ ((unused)))
{
}

bool eskill_castend_pos2_unknown(struct block_list* src,
                                 int *x,
                                 int *y,
                                 uint16 *skill_id,
                                 uint16 *skill_lv,
                                 int64 *tick,
                                 int *flag)
{
    switch (*skill_id)
    {
        case EVOL_MASS_PROVOKE:
            return eskill_massprovoke_castend(src, x, y, skill_id, skill_lv, tick, flag);
        default:
            ShowWarning("skill_castend_pos2: Unknown skill used:%d\n", *skill_id);
            return true;
    }
}

// probably this function must be implimented in server
bool eskill_lookup_const(const struct config_setting_t *it,
                         const char *name,
                         int *value)
{
    nullpo_retr(false, name);
    nullpo_retr(false, value);
    if (libconfig->setting_lookup_int(it, name, value))
    {
        return true;
    }
    else
    {
        const char *str = NULL;
        if (libconfig->setting_lookup_string(it, name, &str))
        {
            if (*str && script->get_constant(str, value))
                return true;
        }
    }
    return false;
}

void eskill_validate_additional_fields(struct config_setting_t *conf,
                                       struct s_skill_db *sk)
{
    nullpo_retv(conf);
    nullpo_retv(sk);
    Assert_retv(sk->nameid < MAX_SKILL_ID);

    int i32 = 0;
    struct config_setting_t *t = NULL;
    struct SkilldExt *skilld = skilld_get_id(sk->nameid);
    nullpo_retv(skilld);

    if ((t = libconfig->setting_get_member(conf, "MiscEffects")))
    {
        if (config_setting_is_array(t))
        {
            for (int i = 0; i < libconfig->setting_length(t) && i < SKILLD_MAXMISCEFFECTS; i++)
            {
                skilld->miscEffects[i] = libconfig->setting_get_int_elem(t, i);
            }
        }
        else
        {
            if (eskill_lookup_const(conf, "MiscEffects", &i32) && i32 >= 0)
            {
                for (int i = 0; i < SKILLD_MAXMISCEFFECTS; i++)
                {
                    skilld->miscEffects[i] = i32;
                }
            }
        }
    }
    if (eskill_lookup_const(conf, "TargetMiscEffect", &i32) && i32 >= 0)
    {
        skilld->miscEffects[0] = i32;
    }
    else if (eskill_lookup_const(conf, "TargetMiscEffect1", &i32) && i32 >= 0)
    {
        skilld->miscEffects[0] = i32;
    }
    if (eskill_lookup_const(conf, "TargetMiscEffect2", &i32) && i32 >= 0)
    {
        skilld->miscEffects[1] = i32;
    }
}