summaryrefslogtreecommitdiff
path: root/src/map/skill.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/skill.c')
-rw-r--r--src/map/skill.c764
1 files changed, 608 insertions, 156 deletions
diff --git a/src/map/skill.c b/src/map/skill.c
index 40001659c..b2d788b57 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -86,6 +86,7 @@ struct skill_interface *skill;
//Since only mob-casted splash skills can hit ice-walls
int skill_splash_target(struct block_list* bl)
{
+ nullpo_retr(BL_CHAR, bl);
#ifndef RENEWAL
return ( bl->type == BL_MOB ) ? BL_SKILL|BL_CHAR : BL_CHAR;
#else // Some skills can now hit ground skills(traps, ice wall & etc.)
@@ -94,7 +95,8 @@ int skill_splash_target(struct block_list* bl)
}
/// Returns the id of the skill, or 0 if not found.
-int skill_name2id(const char* name) {
+int skill_name2id(const char* name)
+{
if( name == NULL )
return 0;
@@ -103,7 +105,8 @@ int skill_name2id(const char* name) {
/// Maps skill ids to skill db offsets.
/// Returns the skill's array index, or 0 (Unknown Skill).
-int skill_get_index( uint16 skill_id ) {
+int skill_get_index (uint16 skill_id)
+{
// avoid ranges reserved for mapping guild/homun/mercenary skills
if( (skill_id >= GD_SKILLRANGEMIN && skill_id <= GD_SKILLRANGEMAX)
|| (skill_id >= HM_SKILLRANGEMIN && skill_id <= HM_SKILLRANGEMAX)
@@ -128,7 +131,7 @@ int skill_get_index( uint16 skill_id ) {
skill_id = (1077) + skill_id - 2201;
else if ( skill_id < 3036 ) // 2549 - 3000 are empty - 1020+57+348
skill_id = (1425) + skill_id - 3001;
- else if ( skill_id < 5019 ) // 3036 - 5000 are empty - 1020+57+348+35
+ else if ( skill_id < 5044 ) // 3036 - 5000 are empty - 1020+57+348+35
skill_id = (1460) + skill_id - 5001;
else
ShowWarning("skill_get_index: skill id '%d' is not being handled!\n",skill_id);
@@ -215,6 +218,7 @@ int skill_get_fixed_cast( uint16 skill_id ,uint16 skill_lv ) {
return 0;
#endif
}
+
int skill_tree_get_max(uint16 skill_id, int b_class)
{
int i;
@@ -227,7 +231,8 @@ int skill_tree_get_max(uint16 skill_id, int b_class)
return skill->get_max(skill_id);
}
-int skill_get_casttype (uint16 skill_id) {
+int skill_get_casttype(uint16 skill_id)
+{
int inf = skill->get_inf(skill_id);
if (inf&(INF_GROUND_SKILL))
return CAST_GROUND;
@@ -243,8 +248,11 @@ int skill_get_casttype (uint16 skill_id) {
return CAST_DAMAGE;
}
-int skill_get_casttype2 (uint16 index) {
- int inf = skill->dbs->db[index].inf;
+int skill_get_casttype2(uint16 index)
+{
+ int inf;
+ Assert_retr(CAST_NODAMAGE, index < MAX_SKILL_DB);
+ inf = skill->dbs->db[index].inf;
if (inf&(INF_GROUND_SKILL))
return CAST_GROUND;
if (inf&INF_SUPPORT_SKILL)
@@ -260,7 +268,8 @@ int skill_get_casttype2 (uint16 index) {
}
//Returns actual skill range taking into account attack range and AC_OWL [Skotlex]
-int skill_get_range2 (struct block_list *bl, uint16 skill_id, uint16 skill_lv) {
+int skill_get_range2(struct block_list *bl, uint16 skill_id, uint16 skill_lv)
+{
int range;
struct map_session_data *sd = BL_CAST(BL_PC, bl);
if( bl->type == BL_MOB && battle_config.mob_ai&0x400 )
@@ -356,7 +365,10 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, uint16 sk
nullpo_ret(src);
- switch( skill_id ) {
+ switch (skill_id) {
+ case SU_TUNABELLY:
+ hp = status_get_max_hp(target) * ((20 * skill_lv) - 10) / 100;
+ break;
case BA_APPLEIDUN:
#ifdef RENEWAL
hp = 100+5*skill_lv+5*(status_get_vit(src)/10); // HP recovery
@@ -388,6 +400,11 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, uint16 sk
hp += hp * skill2_lv * 2 / 100;
else if (src->type == BL_HOM && (skill2_lv = homun->checkskill(BL_UCAST(BL_HOM, src), HLIF_BRAIN)) > 0)
hp += hp * skill2_lv * 2 / 100;
+ if (sd != NULL && ((skill2_lv = pc->checkskill(sd, SU_POWEROFSEA)) > 0)) {
+ hp += hp * 10 / 100;
+ if (pc->checkskill(sd, SU_TUNABELLY) == 5 && pc->checkskill(sd, SU_TUNAPARTY) == 5 && pc->checkskill(sd, SU_BUNCHOFSHRIMP) == 5 && pc->checkskill(sd, SU_FRESHSHRIMP) == 5)
+ hp += hp * 20 / 100;
+ }
break;
}
@@ -437,6 +454,7 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, uint16 sk
// Making plagiarize check its own function [Aru]
int can_copy (struct map_session_data *sd, uint16 skill_id, struct block_list* bl)
{
+ nullpo_ret(sd);
// Never copy NPC/Wedding Skills
if (skill->get_inf2(skill_id)&(INF2_NPC_SKILL|INF2_WEDDING_SKILL))
return 0;
@@ -456,8 +474,11 @@ int can_copy (struct map_session_data *sd, uint16 skill_id, struct block_list* b
skill_id == MER_INCAGI || skill_id == MER_BLESSING))
return 0;
- // Couldn't preserve 3rd Class skills except only when using Reproduce skill. [Jobbie]
- if( !(sd->sc.data[SC__REPRODUCE]) && ((skill_id >= RK_ENCHANTBLADE && skill_id <= LG_OVERBRAND_PLUSATK) || (skill_id >= RL_GLITTERING_GREED && skill_id <= OB_AKAITSUKI) || (skill_id >= GC_DARKCROW && skill_id <= NC_MAGMA_ERUPTION_DOTDAMAGE)))
+ // Couldn't preserve 3rd Class/Summoner skills except only when using Reproduce skill. [Jobbie]
+ if (!(sd->sc.data[SC__REPRODUCE]) &&
+ ((skill_id >= RK_ENCHANTBLADE && skill_id <= LG_OVERBRAND_PLUSATK) ||
+ (skill_id >= RL_GLITTERING_GREED && skill_id <= OB_AKAITSUKI) ||
+ (skill_id >= GC_DARKCROW && skill_id <= SU_FRESHSHRIMP)))
return 0;
// Reproduce will only copy skills according on the list. [Jobbie]
else if( sd->sc.data[SC__REPRODUCE] && !skill->dbs->reproduce_db[skill->get_index(skill_id)] )
@@ -547,6 +568,7 @@ int skillnotok (uint16 skill_id, struct map_session_data *sd)
clif->skill_fail(sd,skill_id,USESKILL_FAIL_THERE_ARE_NPC_AROUND,0);
return 1;
}
+ FALLTHROUGH
case MC_IDENTIFY:
return 0; // always allowed
case WZ_ICEWALL:
@@ -631,6 +653,7 @@ int skillnotok_hom(uint16 skill_id, struct homun_data *hd)
int skillnotok_hom_unknown(uint16 skill_id, struct homun_data *hd)
{
+ nullpo_retr(1, hd);
//Use master's criteria.
return skill->not_ok(skill_id, hd->master);
}
@@ -648,10 +671,12 @@ int skillnotok_mercenary(uint16 skill_id, struct mercenary_data *md)
return skill->not_ok(skill_id, md->master);
}
-struct s_skill_unit_layout* skill_get_unit_layout (uint16 skill_id, uint16 skill_lv, struct block_list* src, int x, int y) {
+struct s_skill_unit_layout* skill_get_unit_layout(uint16 skill_id, uint16 skill_lv, struct block_list* src, int x, int y)
+{
int pos = skill->get_unit_layout_type(skill_id,skill_lv);
uint8 dir;
+ nullpo_retr(&skill->dbs->unit_layout[0], src);
if (pos < -1 || pos >= MAX_SKILL_UNIT_LAYOUT) {
ShowError("skill_get_unit_layout: unsupported layout type %d for skill %d (level %d)\n", pos, skill_id, skill_lv);
pos = cap_value(pos, 0, MAX_SQUARE_LAYOUT); // cap to nearest square layout
@@ -888,6 +913,10 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
break;
#endif
+ case WZ_HEAVENDRIVE:
+ status_change_end(bl, SC_SV_ROOTTWIST, INVALID_TIMER);
+ break;
+
case WZ_STORMGUST:
/**
* Storm Gust counter was dropped in renewal
@@ -1401,6 +1430,25 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
case MH_XENO_SLASHER:
sc_start2(src, bl, SC_BLOODING, 10 * skill_lv, skill_lv, src->id, skill->get_time(skill_id,skill_lv));
break;
+ /**
+ * Summoner
+ */
+ case SU_SCRATCH:
+ sc_start2(src, bl, SC_BLOODING, (skill_lv * 3), skill_lv, src->id, skill->get_time(skill_id, skill_lv)); // TODO: What's the chance/time?
+ break;
+ case SU_SV_STEMSPEAR:
+ sc_start2(src, bl, SC_BLOODING, 10, skill_lv, src->id, skill->get_time(skill_id, skill_lv));
+ break;
+ case SU_CN_METEOR:
+ sc_start(src, bl, SC_CURSE, 10, skill_lv, skill->get_time2(skill_id, skill_lv)); // TODO: What's the chance/time?
+ break;
+ case SU_SCAROFTAROU:
+ sc_start(src, bl, SC_STUN, 10, skill_lv, skill->get_time2(skill_id, skill_lv)); // TODO: What's the chance/time?
+ break;
+ case SU_LUNATICCARROTBEAT:
+ if (skill->area_temp[3] == 1)
+ sc_start(src, bl, SC_STUN, 10, skill_lv, skill_get_time(skill_id, skill_lv)); // TODO: What's the chance/time?
+ break;
default:
skill->additional_effect_unknown(src, bl, &skill_id, &skill_lv, &attack_type, &dmg_lv, &tick);
break;
@@ -2036,7 +2084,8 @@ int skill_break_equip (struct block_list *bl, unsigned short where, int rate, in
return where; //Return list of pieces broken.
}
-int skill_strip_equip(struct block_list *bl, unsigned short where, int rate, int lv, int time) {
+int skill_strip_equip(struct block_list *bl, unsigned short where, int rate, int lv, int time)
+{
struct status_change *sc;
const int pos[5] = {EQP_WEAPON, EQP_SHIELD, EQP_ARMOR, EQP_HELM, EQP_ACC};
const enum sc_type sc_atk[5] = {SC_NOEQUIPWEAPON, SC_NOEQUIPSHIELD, SC_NOEQUIPARMOR, SC_NOEQUIPHELM, SC__STRIPACCESSARY};
@@ -2062,6 +2111,7 @@ int skill_strip_equip(struct block_list *bl, unsigned short where, int rate, int
}
return where?1:0;
}
+
/*=========================================================================
* Used to knock back players, monsters, traps, etc
* 'count' is the number of squares to knock back
@@ -2072,11 +2122,14 @@ int skill_strip_equip(struct block_list *bl, unsigned short where, int rate, int
int skill_blown(struct block_list* src, struct block_list* target, int count, int8 dir, int flag)
{
int dx = 0, dy = 0;
+ struct status_change *tsc = status->get_sc(target);
nullpo_ret(src);
if (src != target && map->list[src->m].flag.noknockback)
return 0; // No knocking
+
+ nullpo_ret(target);
if (count == 0)
return 0; // Actual knockback distance is 0.
@@ -2117,6 +2170,9 @@ int skill_blown(struct block_list* src, struct block_list* target, int count, in
dy = -diry[dir];
}
+ if (tsc != NULL && tsc->data[SC_SU_STOOP]) // Any knockback will cancel it.
+ status_change_end(target, SC_SU_STOOP, INVALID_TIMER);
+
return unit->blown(target, dx, dy, count, flag); // send over the proper flag
}
@@ -2127,10 +2183,12 @@ int skill_blown(struct block_list* src, struct block_list* target, int count, in
1 - Regular reflection (Maya)
2 - SL_KAITE reflection
*/
-int skill_magic_reflect(struct block_list* src, struct block_list* bl, int type) {
+int skill_magic_reflect(struct block_list* src, struct block_list* bl, int type)
+{
struct status_change *sc = status->get_sc(bl);
struct map_session_data* sd = BL_CAST(BL_PC, bl);
+ nullpo_ret(src);
if( sc && sc->data[SC_KYOMU] ) // Nullify reflecting ability
return 0;
@@ -2174,7 +2232,8 @@ int skill_magic_reflect(struct block_list* src, struct block_list* bl, int type)
* client (causes player characters to not scream skill name)
* flag&0x4000 - Return 0 if damage was reflected
*-------------------------------------------------------------------------*/
-int skill_attack(int attack_type, struct block_list* src, struct block_list *dsrc, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) {
+int skill_attack(int attack_type, struct block_list* src, struct block_list *dsrc, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag)
+{
struct Damage dmg;
struct status_data *sstatus, *tstatus;
struct status_change *sc;
@@ -2488,6 +2547,7 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
case KO_MUCHANAGE:
if( dmg.dmg_lv == ATK_FLEE )
break;
+ FALLTHROUGH
case WL_SOULEXPANSION:
case WL_COMET:
case NJ_HUUMA:
@@ -2500,6 +2560,7 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
case LG_OVERBRAND:
/* Fall through */
dmg.amotion = status_get_amotion(src) * 2;
+ FALLTHROUGH
case LG_OVERBRAND_PLUSATK:
dmg.dmotion = clif->skill_damage(dsrc,bl,tick,status_get_amotion(src),dmg.dmotion,damage,dmg.div_,skill_id,-1,BDT_SPLASH);
break;
@@ -2558,6 +2619,7 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
dmg.dmotion = clif->skill_damage(src,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, (flag&SD_LEVEL) ? -1 : skill_lv, BDT_SPLASH);
if( dsrc != src ) // avoid damage display redundancy
break;
+ FALLTHROUGH
case HT_LANDMINE:
dmg.dmotion = clif->skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, -1, type);
break;
@@ -2570,6 +2632,7 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
case AB_DUPLELIGHT_MELEE:
case AB_DUPLELIGHT_MAGIC:
dmg.amotion = 300;/* makes the damage value not overlap with previous damage (when displayed by the client) */
+ FALLTHROUGH
default:
skill->attack_display_unknown(&attack_type, src, dsrc, bl, &skill_id, &skill_lv, &tick, &flag, &type, &dmg, &damage);
break;
@@ -2865,15 +2928,27 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
return (int)cap_value(damage,INT_MIN,INT_MAX);
}
-void skill_attack_combo1_unknown(int *attack_type, struct block_list* src, struct block_list *dsrc, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag, struct status_change_entry *sce, int *combo) {
+void skill_attack_combo1_unknown(int *attack_type, struct block_list* src, struct block_list *dsrc, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag, struct status_change_entry *sce, int *combo)
+{
if (src == dsrc) // Ground skills are exceptions. [Inkfish]
status_change_end(src, SC_COMBOATTACK, INVALID_TIMER);
}
-void skill_attack_combo2_unknown(int *attack_type, struct block_list* src, struct block_list *dsrc, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag, int *combo) {
+void skill_attack_combo2_unknown(int *attack_type, struct block_list* src, struct block_list *dsrc, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag, int *combo)
+{
}
-void skill_attack_display_unknown(int *attack_type, struct block_list* src, struct block_list *dsrc, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag, int *type, struct Damage *dmg, int64 *damage) {
+void skill_attack_display_unknown(int *attack_type, struct block_list* src, struct block_list *dsrc, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag, int *type, struct Damage *dmg, int64 *damage)
+{
+ nullpo_retv(bl);
+ nullpo_retv(dmg);
+ nullpo_retv(tick);
+ nullpo_retv(flag);
+ nullpo_retv(damage);
+ nullpo_retv(skill_id);
+ nullpo_retv(skill_lv);
+ nullpo_retv(type);
+
if (*flag & SD_ANIMATION && dmg->div_ < 2) //Disabling skill animation doesn't works on multi-hit.
*type = BDT_SPLASH;
if (bl->type == BL_SKILL) {
@@ -2884,15 +2959,24 @@ void skill_attack_display_unknown(int *attack_type, struct block_list* src, stru
dmg->dmotion = clif->skill_damage(dsrc, bl, *tick, dmg->amotion, dmg->dmotion, *damage, dmg->div_, *skill_id, (*flag & SD_LEVEL) ? -1 : *skill_lv, *type);
}
-int skill_attack_copy_unknown(int *attack_type, struct block_list* src, struct block_list *dsrc, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag) {
+int skill_attack_copy_unknown(int *attack_type, struct block_list* src, struct block_list *dsrc, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag)
+{
+ nullpo_ret(skill_id);
return *skill_id;
}
-int skill_attack_dir_unknown(int *attack_type, struct block_list* src, struct block_list *dsrc, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag) {
+int skill_attack_dir_unknown(int *attack_type, struct block_list* src, struct block_list *dsrc, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag)
+{
return -1;
}
-void skill_attack_blow_unknown(int *attack_type, struct block_list* src, struct block_list *dsrc, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag, int *type, struct Damage *dmg, int64 *damage, int8 *dir) {
+void skill_attack_blow_unknown(int *attack_type, struct block_list* src, struct block_list *dsrc, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag, int *type, struct Damage *dmg, int64 *damage, int8 *dir)
+{
+ nullpo_retv(bl);
+ nullpo_retv(dmg);
+ nullpo_retv(dir);
+ nullpo_retv(damage);
+
skill->blown(dsrc, bl, dmg->blewcount, *dir, 0x0);
if (!dmg->blewcount && bl->type == BL_SKILL && *damage > 0){
struct skill_unit *su = BL_UCAST(BL_SKILL, bl);
@@ -2901,7 +2985,8 @@ void skill_attack_blow_unknown(int *attack_type, struct block_list* src, struct
}
}
-void skill_attack_post_unknown(int *attack_type, struct block_list* src, struct block_list *dsrc, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag) {
+void skill_attack_post_unknown(int *attack_type, struct block_list* src, struct block_list *dsrc, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag)
+{
}
/*==========================================
@@ -2909,7 +2994,8 @@ void skill_attack_post_unknown(int *attack_type, struct block_list* src, struct
* Checking bl battle flag and display damage
* then call func with source,target,skill_id,skill_lv,tick,flag
*------------------------------------------*/
-int skill_area_sub(struct block_list *bl, va_list ap) {
+int skill_area_sub(struct block_list *bl, va_list ap)
+{
struct block_list *src;
uint16 skill_id,skill_lv;
int flag;
@@ -2960,6 +3046,7 @@ int skill_check_unit_range_sub(struct block_list *bl, va_list ap)
case AL_PNEUMA:
if(g_skill_id == SA_LANDPROTECTOR)
break;
+ FALLTHROUGH
case MG_SAFETYWALL:
case MH_STEINWAND:
case SC_MAELSTROM:
@@ -3382,6 +3469,7 @@ int skill_timerskill(int tid, int64 tick, int id, intptr_t data) {
skill->blown(src,target,skill->get_blewcount(skl->skill_id, skl->skill_lv), -1, 0x0 );
break;
}
+ FALLTHROUGH
}
default:
skill->timerskill_target_unknown(tid, tick, src, target, ud, skl);
@@ -3392,7 +3480,8 @@ int skill_timerskill(int tid, int64 tick, int id, intptr_t data) {
break;
switch( skl->skill_id ) {
case WZ_METEOR:
- if( skl->type >= 0 ) {
+ case SU_CN_METEOR:
+ if (skl->type >= 0) {
int x = skl->type>>16, y = skl->type&0xFFFF;
if( path->search_long(NULL, src, src->m, src->x, src->y, x, y, CELL_CHKWALL) )
skill->unitsetting(src,skl->skill_id,skl->skill_lv,x,y,skl->flag);
@@ -3408,6 +3497,7 @@ int skill_timerskill(int tid, int64 tick, int id, intptr_t data) {
map->foreachinarea(skill->cell_overlap,src->m,skl->x-i,skl->y-i,skl->x+i,skl->y+i,BL_SKILL,skl->skill_id,&dummy,src);
}
+ FALLTHROUGH
// fall through ...
case WL_EARTHSTRAIN:
skill->unitsetting(src,skl->skill_id,skl->skill_lv,skl->x,skl->y,(skl->type<<16)|skl->flag);
@@ -3435,6 +3525,7 @@ bool skill_timerskill_dead_unknown(struct block_list *src, struct unit_data *ud,
void skill_timerskill_target_unknown(int tid, int64 tick, struct block_list *src, struct block_list *target, struct unit_data *ud, struct skill_timerskill *skl)
{
+ nullpo_retv(skl);
skill->attack(skl->type, src, src, target, skl->skill_id, skl->skill_lv, tick, skl->flag);
}
@@ -3445,7 +3536,8 @@ void skill_timerskill_notarget_unknown(int tid, int64 tick, struct block_list *s
/*==========================================
*
*------------------------------------------*/
-int skill_addtimerskill(struct block_list *src, int64 tick, int target, int x,int y, uint16 skill_id, uint16 skill_lv, int type, int flag) {
+int skill_addtimerskill(struct block_list *src, int64 tick, int target, int x,int y, uint16 skill_id, uint16 skill_lv, int type, int flag)
+{
int i;
struct unit_data *ud;
nullpo_retr(1, src);
@@ -3553,6 +3645,7 @@ void skill_castend_type(int type, struct block_list *src, struct block_list *bl,
{
switch (type) {
case CAST_GROUND:
+ nullpo_retv(bl);
skill->castend_pos2(src, bl->x, bl->y, skill_id, skill_lv, tick, flag);
break;
case CAST_NODAMAGE:
@@ -3568,7 +3661,8 @@ void skill_castend_type(int type, struct block_list *src, struct block_list *bl,
*
*
*------------------------------------------*/
-int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) {
+int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag)
+{
struct map_session_data *sd = NULL;
struct status_data *tstatus;
struct status_change *sc;
@@ -3906,11 +4000,22 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag);
break;
- //Splash attack skills.
+ case SU_BITE:
+ skill->attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag);
+ if (status->get_lv(src) >= 30 && (rnd() % 100 < (int)(status->get_lv(src) / 30) + 10)) // TODO: Need activation chance.
+ skill->addtimerskill(src, tick + skill->get_delay(skill_id, skill_lv), bl->id, 0, 0, skill_id, skill_lv, BF_WEAPON, flag);
+ break;
+
+ case SU_PICKYPECK:
+ clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
+ break;
+
+ // Splash attack skills.
case AS_GRIMTOOTH:
case MC_CARTREVOLUTION:
case NPC_SPLASHATTACK:
flag |= SD_PREAMBLE; // a fake packet will be sent for the first target to be hit
+ FALLTHROUGH
case AS_SPLASHER:
case HT_BLITZBEAT:
case AC_SHOWER:
@@ -3958,7 +4063,9 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
case KO_BAKURETSU:
case GN_ILLUSIONDOPING:
case MH_XENO_SLASHER:
- if( flag&1 ) {//Recursive invocation
+ case SU_SCRATCH:
+ case SU_LUNATICCARROTBEAT:
+ if (flag&1) { //Recursive invocation
// skill->area_temp[0] holds number of targets in area
// skill->area_temp[1] holds the id of the original target
// skill->area_temp[2] counts how many targets have already been processed
@@ -3973,15 +4080,19 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
break;
heal = skill->attack(skill->get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, sflag);
- if( skill_id == NPC_VAMPIRE_GIFT && heal > 0 ) {
+ if (skill_id == NPC_VAMPIRE_GIFT && heal > 0) {
clif->skill_nodamage(NULL, src, AL_HEAL, heal, 1);
status->heal(src,heal,0,0);
}
+ if (skill_id == SU_SCRATCH && status->get_lv(src) >= 30 && (rnd() % 100 < (int)(status->get_lv(src) / 30) + 10)) // TODO: Need activation chance.
+ skill->addtimerskill(src, tick + skill->get_delay(skill_id, skill_lv), bl->id, 0, 0, skill_id, skill_lv, BF_WEAPON, flag);
} else {
switch ( skill_id ) {
case NJ_BAKUENRYU:
case LG_EARTHDRIVE:
case GN_CARTCANNON:
+ case SU_SCRATCH:
+ case SU_LUNATICCARROTBEAT:
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
break;
case SR_TIGERCANNON:
@@ -4000,13 +4111,19 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
skill->area_temp[0] = 0;
skill->area_temp[1] = bl->id;
skill->area_temp[2] = 0;
- if( skill_id == WL_CRIMSONROCK ) {
+ if (skill_id == WL_CRIMSONROCK) {
skill->area_temp[4] = bl->x;
skill->area_temp[5] = bl->y;
}
+ if (skill_id == SU_LUNATICCARROTBEAT) {
+ skill->area_temp[3] = 0;
+ }
- if( skill_id == NC_VULCANARM )
- if (sd) pc->overheat(sd,1);
+ if (skill_id == NC_VULCANARM) {
+ if (sd != NULL) {
+ pc->overheat(sd,1);
+ }
+ }
// if skill damage should be split among targets, count them
//SD_LEVEL -> Forced splash damage for Auto Blitz-Beat -> count targets
@@ -4016,6 +4133,15 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
// recursive invocation of skill->castend_damage_id() with flag|1
map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), skill->splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill->castend_damage_id);
+
+ if (sd && skill_id == SU_LUNATICCARROTBEAT) {
+ short item_idx = pc->search_inventory(sd, ITEMID_CARROT);
+
+ if (item_idx >= 0) {
+ pc->delitem(sd, item_idx, 1, 0, 1, LOG_TYPE_CONSUME);
+ skill->area_temp[3] = 1;
+ }
+ }
}
break;
@@ -4291,6 +4417,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
if( (tsc = status->get_sc(bl)) && tsc->data[SC_HIDING] )
break;
}
+ FALLTHROUGH
case HVAN_EXPLOSION:
if (src != bl)
skill->attack(BF_MISC,src,src,bl,skill_id,skill_lv,tick,flag);
@@ -4548,6 +4675,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
}
break;
}
+ FALLTHROUGH
case RA_WUGBITE:
if( path->search(NULL,src,src->m,src->x,src->y,bl->x,bl->y,1,CELL_CHKNOREACH) ) {
skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag);
@@ -4571,7 +4699,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
if( !(sg->unit_id == UNT_USED_TRAPS || (sg->unit_id == UNT_ANKLESNARE && sg->val2 != 0 )) ) {
struct item item_tmp;
memset(&item_tmp,0,sizeof(item_tmp));
- item_tmp.nameid = sg->item_id?sg->item_id:ITEMID_TRAP;
+ item_tmp.nameid = sg->item_id ? sg->item_id : ITEMID_BOOBY_TRAP;
item_tmp.identify = 1;
if( item_tmp.nameid )
map->addflooritem(bl, &item_tmp, 1, bl->m, bl->x, bl->y, 0, 0, 0, 0);
@@ -4823,6 +4951,15 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
skill->attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag);
break;
+ case SU_SV_STEMSPEAR:
+ skill->attack(skill->get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag);
+ if (status->get_lv(src) >= 30 && (rnd() % 100 < (int)(status->get_lv(src) / 30) + 10)) // TODO: Need activation chance.
+ skill->addtimerskill(src, tick + skill->get_delay(skill_id, skill_lv), bl->id, 0, 0, skill_id, skill_lv, (skill_id == SU_SV_STEMSPEAR) ? BF_MAGIC : BF_WEAPON, flag);
+ break;
+ case SU_SCAROFTAROU:
+ sc_start(src, bl, status->skill2sc(skill_id), 10, skill_lv, skill->get_time(skill_id, skill_lv)); // TODO: What's the activation chance for the effect?
+ break;
+
case 0:/* no skill - basic/normal attack */
if(sd) {
if (flag & 3){
@@ -4868,6 +5005,10 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
bool skill_castend_damage_id_unknown(struct block_list* src, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag, struct status_data *tstatus, struct status_change *sc)
{
+ nullpo_retr(true, skill_id);
+ nullpo_retr(true, skill_lv);
+ nullpo_retr(true, tick);
+ nullpo_retr(true, tstatus);
ShowWarning("skill_castend_damage_id: Unknown skill used:%d\n", *skill_id);
clif->skill_damage(src, bl, *tick, status_get_amotion(src), tstatus->dmotion,
0, abs(skill->get_num(*skill_id, *skill_lv)),
@@ -4879,7 +5020,8 @@ bool skill_castend_damage_id_unknown(struct block_list* src, struct block_list *
/*==========================================
*
*------------------------------------------*/
-int skill_castend_id(int tid, int64 tick, int id, intptr_t data) {
+int skill_castend_id(int tid, int64 tick, int id, intptr_t data)
+{
struct block_list *target, *src;
struct map_session_data *sd;
struct mob_data *md;
@@ -4955,6 +5097,8 @@ int skill_castend_id(int tid, int64 tick, int id, intptr_t data) {
ud->skilltimer=tid;
return skill->castend_pos(tid,tick,id,data);
case GN_WALLOFTHORN:
+ case SU_CN_POWDERING:
+ case SU_SV_ROOTTWIST:
ud->skillx = target->x;
ud->skilly = target->y;
ud->skilltimer = tid;
@@ -5223,7 +5367,8 @@ bool skill_castend_id_unknown(struct unit_data *ud, struct block_list *src, stru
/*==========================================
*
*------------------------------------------*/
-int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) {
+int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag)
+{
struct map_session_data *sd, *dstsd;
struct mob_data *md, *dstmd;
struct homun_data *hd;
@@ -5300,6 +5445,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
if (sd) clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0) ;
break ;
}
+ FALLTHROUGH
case AL_HEAL:
/**
@@ -5415,6 +5561,10 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
* Arch Bishop
**/
case AB_HIGHNESSHEAL:
+ /**
+ * Summoner
+ */
+ case SU_TUNABELLY:
{
int heal = skill->calc_heal(src, bl, (skill_id == AB_HIGHNESSHEAL)?AL_HEAL:skill_id, (skill_id == AB_HIGHNESSHEAL)?10:skill_lv, true);
int heal_get_jobexp;
@@ -5444,6 +5594,9 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
else if (tsc->data[SC_BERSERK])
heal = 0; //Needed so that it actually displays 0 when healing.
}
+ if (skill_id == AL_HEAL) {
+ status_change_end(bl, SC_BITESCAR, INVALID_TIMER);
+ }
clif->skill_nodamage (src, bl, skill_id, heal, 1);
if( tsc && tsc->data[SC_AKAITSUKI] && heal && skill_id != HLIF_HEAL )
heal = ~heal + 1;
@@ -5823,6 +5976,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
case PR_KYRIE:
case MER_KYRIE:
+ case SU_TUNAPARTY:
clif->skill_nodamage(bl, bl, skill_id, -1,
sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)));
break;
@@ -5939,9 +6093,18 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
case RK_ABUNDANCE:
case RK_CRUSHSTRIKE:
case ALL_ODINS_POWER:
+ case SU_FRESHSHRIMP:
+ case SU_ARCLOUSEDASH:
clif->skill_nodamage(src,bl,skill_id,skill_lv,
sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
break;
+ // Works just like the above list of skills, except animation caused by
+ // status must trigger AFTER the skill cast animation or it will cancel
+ // out the status's animation.
+ case SU_STOOP:
+ clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
+ sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv));
+ break;
case KN_AUTOCOUNTER:
sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv));
skill->addtimerskill(src, tick + 100, bl->id, 0, 0, skill_id, skill_lv, BF_WEAPON, flag);
@@ -6166,7 +6329,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
sd->devotion[i] = bl->id;
}
- else
+ else if (mer != NULL)
mer->devotion_flag = 1; // Mercenary Devoting Owner
clif->skill_nodamage(src, bl, skill_id, skill_lv,
@@ -6539,7 +6702,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
case RG_STEALCOIN:
if(sd) {
int amount = pc->steal_coin(sd, bl, skill_lv);
- if( amount > 0 ) {
+ if (amount > 0 && dstmd != NULL) {
dstmd->state.provoke_flag = src->id;
mob->target(dstmd, src, skill->get_range2(src, skill_id, skill_lv));
clif->skill_nodamage(src, bl, skill_id, amount, 1);
@@ -6596,7 +6759,8 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
status_change_end(bl, SC_SILENCE, INVALID_TIMER);
status_change_end(bl, SC_BLIND, INVALID_TIMER);
status_change_end(bl, SC_CONFUSION, INVALID_TIMER);
- clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
+ status_change_end(bl, SC_BITESCAR, INVALID_TIMER);
+ clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
break;
case TF_DETOXIFY:
@@ -7513,7 +7677,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
// get back 1 trap
struct item item_tmp;
memset(&item_tmp,0,sizeof(item_tmp));
- item_tmp.nameid = su->group->item_id?su->group->item_id:ITEMID_TRAP;
+ item_tmp.nameid = su->group->item_id ? su->group->item_id : ITEMID_BOOBY_TRAP;
item_tmp.identify = 1;
if (item_tmp.nameid && (flag=pc->additem(sd,&item_tmp,1,LOG_TYPE_SKILL)) != 0) {
clif->additem(sd,0,0,flag);
@@ -7539,6 +7703,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
// remove trap should be used instead
break;
// otherwise fall through to below
+ FALLTHROUGH
case UNT_BLASTMINE:
case UNT_SKIDTRAP:
case UNT_LANDMINE:
@@ -7576,7 +7741,8 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
clif->skill_nodamage(src,bl,skill_id,skill_lv,
sc_start4(src,bl,type,100,skill_lv,skill_id,src->id,skill->get_time(skill_id,skill_lv),1000));
#ifndef RENEWAL
- if (sd) skill->blockpc_start (sd, skill_id, skill->get_time(skill_id, skill_lv)+3000);
+ if (sd)
+ skill->blockpc_start(sd, skill_id, skill->get_time(skill_id, skill_lv) + 3000);
#endif
break;
@@ -8388,7 +8554,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
case AB_ANCILLA:
if( sd ) {
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
- skill->produce_mix(sd, skill_id, ITEMID_ANCILLA, 0, 0, 0, 1);
+ skill->produce_mix(sd, skill_id, ITEMID_ANSILA, 0, 0, 0, 1);
}
break;
@@ -8856,6 +9022,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
case LG_TRAMPLE:
clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
map->foreachinrange(skill->destroy_trap,bl,skill->get_splash(skill_id,skill_lv),BL_SKILL,tick);
+ status_change_end(bl, SC_SV_ROOTTWIST, INVALID_TIMER);
break;
case LG_REFLECTDAMAGE:
@@ -9385,6 +9552,25 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, 0, 1, skill_id, -2, BDT_SKILL);
break;
+ case SU_HIDE:
+ if (tsce != NULL) {
+ clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
+ status_change_end(bl, type, INVALID_TIMER);
+ map->freeblock_unlock();
+ return 0;
+ }
+ clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
+ sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv));
+ break;
+
+ case SU_BUNCHOFSHRIMP:
+ if (sd == NULL || sd->status.party_id == 0 || flag&1) {
+ clif->skill_nodamage(bl, bl, skill_id, skill_lv, sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)));
+ } else if (sd != NULL) {
+ party->foreachsamemap(skill->area_sub, sd, skill->get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill->castend_nodamage_id);
+ }
+ break;
+
case GM_SANDMAN:
if( tsc ) {
if( tsc->opt1 == OPT1_SLEEP )
@@ -9791,6 +9977,8 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
SC_MANDRAGORA, SC_HARMONIZE, SC_DEEP_SLEEP, SC_SIREN, SC_SLEEP, SC_CONFUSION, SC_ILLUSION
};
int heal;
+ if (hd == NULL)
+ break;
if(tsc){
int i;
for (i = 0; i < ARRAYLENGTH(scs); i++) {
@@ -9912,6 +10100,8 @@ bool skill_castend_nodamage_id_mado_unknown(struct block_list *src, struct block
bool skill_castend_nodamage_id_unknown(struct block_list *src, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag)
{
+ nullpo_retr(true, skill_id);
+ nullpo_retr(true, skill_lv);
ShowWarning("skill_castend_nodamage_id: Unknown skill used:%d\n", *skill_id);
clif->skill_nodamage(src, bl, *skill_id, *skill_lv, 1);
map->freeblock_unlock();
@@ -9928,6 +10118,7 @@ int skill_castend_pos(int tid, int64 tick, int id, intptr_t data)
struct unit_data *ud = unit->bl2ud(src);
struct mob_data *md;
+ nullpo_ret(src);
nullpo_ret(ud);
sd = BL_CAST(BL_PC , src);
@@ -10094,10 +10285,13 @@ int skill_check_npc_chaospanic(struct block_list *bl, va_list args)
return 1;
}
+
/* skill count without self */
int skill_count_wos(struct block_list *bl, va_list ap)
{
struct block_list* src = va_arg(ap, struct block_list*);
+ nullpo_retr(1, bl);
+ nullpo_retr(1, src);
if( src->id != bl->id ) {
return 1;
}
@@ -10107,8 +10301,10 @@ int skill_count_wos(struct block_list *bl, va_list ap)
/*==========================================
*
*------------------------------------------*/
-int skill_castend_map (struct map_session_data *sd, uint16 skill_id, const char *mapname) {
+int skill_castend_map (struct map_session_data *sd, uint16 skill_id, const char *mapname)
+{
nullpo_ret(sd);
+ nullpo_ret(mapname);
//Simplify skill_failed code.
#define skill_failed(sd) ( (sd)->menuskill_id = (sd)->menuskill_val = 0 )
@@ -10245,7 +10441,8 @@ int skill_castend_map (struct map_session_data *sd, uint16 skill_id, const char
/*==========================================
*
*------------------------------------------*/
-int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) {
+int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, uint16 skill_lv, int64 tick, int flag)
+{
struct map_session_data* sd;
struct status_change* sc;
struct status_change_entry *sce;
@@ -10274,6 +10471,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
case HW_GANBANTEIN:
case LG_EARTHDRIVE:
case SC_ESCAPE:
+ case SU_CN_METEOR:
break; //Effect is displayed on respective switch case.
default:
skill->castend_pos2_effect_unknown(src, &x, &y, &skill_id, &skill_lv, &tick, &flag);
@@ -10342,6 +10540,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
break;
}
+ FALLTHROUGH
case MG_SAFETYWALL:
{
@@ -10351,6 +10550,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
return 0; // Don't consume gems if cast on LP
}
}
+ FALLTHROUGH
case MG_FIREWALL:
case MG_THUNDERSTORM:
@@ -10460,7 +10660,10 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
case SO_ELEMENTAL_SHIELD:
case RL_B_TRAP:
case MH_XENO_SLASHER:
- flag|=1;//Set flag to 1 to prevent deleting ammo (it will be deleted on group-delete).
+ case SU_CN_POWDERING:
+ case SU_SV_ROOTTWIST:
+ flag |= 1; // Set flag to 1 to prevent deleting ammo (it will be deleted on group-delete).
+ FALLTHROUGH
case GS_GROUNDDRIFT: //Ammo should be deleted right away.
if ( skill_id == WM_SEVERE_RAINSTORM )
sc_start(src,src,SC_NO_SWITCH_EQUIP,100,0,skill->get_time(skill_id,skill_lv));
@@ -10512,11 +10715,24 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
break;
case WZ_METEOR:
+ case SU_CN_METEOR:
{
int area = skill->get_splash(skill_id, skill_lv);
short tmpx = 0, tmpy = 0, x1 = 0, y1 = 0;
int i;
+#if 0
+ // The Meteor should inflict curse if Catnip fruit is consumed.
+ // Currently Catnip fruit is added as requirement.
+ if (sd && skill_id == SU_CN_METEOR) {
+ short item_idx = pc->search_inventory(sd, ITEMID_CATNIP_FRUIT);
+ if (item_idx >= 0) {
+ pc->delitem(sd, item_idx, 1, 0, 1, LOG_TYPE_SKILL);
+ flag |= 1;
+ }
+ }
+#endif
+
for( i = 0; i < 2 + (skill_lv>>1); i++ ) {
// Creates a random Cell in the Splash Area
tmpx = x - area + rnd()%(area * 2 + 1);
@@ -10568,6 +10784,19 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
}
status_change_end(src, SC_HIDING, INVALID_TIMER);
break;
+ case SU_LOPE:
+ {
+ if (map->list[src->m].flag.noteleport && !(map->list[src->m].flag.battleground || map_flag_gvg2(src->m))) {
+ x = src->x;
+ y = src->y;
+ }
+ clif->skill_nodamage(src, src, SU_LOPE, skill_lv, 1);
+ if(!map->count_oncell(src->m, x, y, BL_PC | BL_NPC | BL_MOB, 0) && map->getcell(src->m, src, x, y, CELL_CHKREACH)) {
+ clif->slide(src, x, y);
+ unit->movepos(src, x, y, 1, 0);
+ }
+ }
+ break;
case AM_SPHEREMINE:
case AM_CANNIBALIZE:
{
@@ -11037,7 +11266,8 @@ int skill_dance_overlap_sub(struct block_list *bl, va_list ap)
//Does the song/dance overlapping -> dissonance check. [Skotlex]
//When flag is 0, this unit is about to be removed, cancel the dissonance effect
//When 1, this unit has been positioned, so start the cancel effect.
-int skill_dance_overlap(struct skill_unit* su, int flag) {
+int skill_dance_overlap(struct skill_unit* su, int flag)
+{
if (!su || !su->group || !(su->group->state.song_dance&0x1))
return 0;
@@ -11059,7 +11289,8 @@ int skill_dance_overlap(struct skill_unit* su, int flag) {
* @param flag 1 Revert
* @retval true success
**/
-bool skill_dance_switch(struct skill_unit* su, int flag) {
+bool skill_dance_switch(struct skill_unit* su, int flag)
+{
static int prevflag = 1; // by default the backup is empty
static struct skill_unit_group backup;
struct skill_unit_group* group;
@@ -11115,7 +11346,8 @@ bool skill_dance_switch(struct skill_unit* su, int flag) {
* Initializes and sets a ground skill.
* flag&1 is used to determine when the skill 'morphs' (Warp portal becomes active, or Fire Pillar becomes active)
*------------------------------------------*/
-struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_id, uint16 skill_lv, int16 x, int16 y, int flag) {
+struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_id, uint16 skill_lv, int16 x, int16 y, int flag)
+{
struct skill_unit_group *group;
int i,limit,val1=0,val2=0,val3=0;
int target,interval,range,unit_flag,req_item=0;
@@ -11145,9 +11377,10 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_
sd = BL_CAST(BL_PC, src);
st = status->get_status_data(src);
+ nullpo_retr(NULL, st);
sc = status->get_sc(src); // for traps, firewall and fogwall - celest
- switch( skill_id ) {
+ switch (skill_id) {
case SO_ELEMENTAL_SHIELD:
val2 = 300 * skill_lv + 65 * (st->int_ + status->get_lv(src)) + st->max_sp;
break;
@@ -11216,8 +11449,10 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_
case HT_ANKLESNARE:
if( flag&2 )
val3 = SC_ESCAPE;
+ FALLTHROUGH
case HT_SHOCKWAVE:
val1=skill_lv*15+10;
+ FALLTHROUGH
case HT_SANDMAN:
case MA_SANDMAN:
case HT_CLAYMORETRAP:
@@ -11242,7 +11477,7 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_
case RA_ICEBOUNDTRAP:
{
struct skill_condition req = skill->get_requirement(sd,skill_id,skill_lv);
- ARR_FIND(0, MAX_SKILL_ITEM_REQUIRE, i, req.itemid[i] && (req.itemid[i] == ITEMID_TRAP || req.itemid[i] == ITEMID_TRAP_ALLOY));
+ ARR_FIND(0, MAX_SKILL_ITEM_REQUIRE, i, req.itemid[i] && (req.itemid[i] == ITEMID_BOOBY_TRAP || req.itemid[i] == ITEMID_SPECIAL_ALLOY_TRAP));
if( i != MAX_SKILL_ITEM_REQUIRE && req.itemid[i] )
req_item = req.itemid[i];
if( map_flag_gvg2(src->m) || map->list[src->m].flag.battleground )
@@ -11402,12 +11637,16 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_
{
case ELE_FIRE:
subunt++;
+ FALLTHROUGH
case ELE_WATER:
subunt++;
+ FALLTHROUGH
case ELE_POISON:
subunt++;
+ FALLTHROUGH
case ELE_DARK:
subunt++;
+ FALLTHROUGH
case ELE_WIND:
break;
default:
@@ -11444,6 +11683,7 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_
target = BCT_ALL;
val1 = skill_lv + 1;
val2 = 1;
+ FALLTHROUGH
case WM_POEMOFNETHERWORLD: // Can't be placed on top of Land Protector.
case SO_WATER_INSIGNIA:
case SO_FIRE_INSIGNIA:
@@ -11486,6 +11726,7 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_
break;
}
+ nullpo_retr(NULL, layout);
nullpo_retr(NULL, group=skill->init_unitgroup(src,layout->count,skill_id,skill_lv,skill->get_unit_id(skill_id,flag&1)+subunt, limit, interval));
group->val1=val1;
group->val2=val2;
@@ -11626,10 +11867,15 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_
return group;
}
-void skill_unitsetting1_unknown(struct block_list *src, uint16 *skill_id, uint16 *skill_lv, int16 *x, int16 *y, int *flag, int *val1, int *val2, int *val3) {
+void skill_unitsetting1_unknown(struct block_list *src, uint16 *skill_id, uint16 *skill_lv, int16 *x, int16 *y, int *flag, int *val1, int *val2, int *val3)
+{
}
-void skill_unitsetting2_unknown(struct block_list *src, uint16 *skill_id, uint16 *skill_lv, int16 *x, int16 *y, int *flag, int *unit_flag, int *val1, int *val2, int *val3, struct skill_unit_group *group) {
+void skill_unitsetting2_unknown(struct block_list *src, uint16 *skill_id, uint16 *skill_lv, int16 *x, int16 *y, int *flag, int *unit_flag, int *val1, int *val2, int *val3, struct skill_unit_group *group)
+{
+ nullpo_retv(group);
+ nullpo_retv(val2);
+ nullpo_retv(unit_flag);
if (group->state.song_dance & 0x1)
*val2 = *unit_flag & (UF_DANCE | UF_SONG); //Store whether this is a song/dance
}
@@ -11637,7 +11883,8 @@ void skill_unitsetting2_unknown(struct block_list *src, uint16 *skill_id, uint16
/*==========================================
*
*------------------------------------------*/
-int skill_unit_onplace(struct skill_unit *src, struct block_list *bl, int64 tick) {
+int skill_unit_onplace(struct skill_unit *src, struct block_list *bl, int64 tick)
+{
struct skill_unit_group *sg;
struct block_list *ss;
struct status_change *sc;
@@ -11761,6 +12008,7 @@ int skill_unit_onplace(struct skill_unit *src, struct block_list *bl, int64 tick
case UNT_HERMODE:
if (sg->src_id!=bl->id && battle->check_target(&src->bl,bl,BCT_PARTY|BCT_GUILD) > 0)
status->change_clear_buffs(bl,1); //Should dispell only allies.
+ FALLTHROUGH
case UNT_RICHMANKIM:
case UNT_ETERNALCHAOS:
case UNT_DRUMBATTLEFIELD:
@@ -11779,6 +12027,7 @@ int skill_unit_onplace(struct skill_unit *src, struct block_list *bl, int64 tick
if (!battle_config.song_timer_reset && sc && sce)
return 0;
// Let it fall through
+ FALLTHROUGH
case UNT_WHISTLE:
case UNT_ASSASSINCROSS:
case UNT_POEMBRAGI:
@@ -11868,6 +12117,13 @@ int skill_unit_onplace(struct skill_unit *src, struct block_list *bl, int64 tick
sc_start(ss, bl, SC_VOLCANIC_ASH, 100, sg->skill_lv, skill->get_time(MH_VOLCANIC_ASH, sg->skill_lv));
break;
+ case UNT_CATNIPPOWDER:
+ if (sg->src_id == bl->id || (status_get_mode(bl)&MD_BOSS))
+ break; // Does not affect the caster or Boss.
+ if (sce == NULL && battle->check_target(&src->bl, bl, BCT_ENEMY) > 0)
+ sc_start(ss, bl, type, 100, sg->skill_lv, skill->get_time(sg->skill_id, sg->skill_lv));
+ break;
+
case UNT_GD_LEADERSHIP:
case UNT_GD_GLORYWOUNDS:
case UNT_GD_SOULCOLD:
@@ -11889,7 +12145,8 @@ void skill_unit_onplace_unknown(struct skill_unit *src, struct block_list *bl, i
/*==========================================
*
*------------------------------------------*/
-int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int64 tick) {
+int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int64 tick)
+{
struct skill_unit_group *sg;
struct block_list *ss;
struct map_session_data *tsd;
@@ -11917,7 +12174,9 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
return 0;
tstatus = status->get_status_data(bl);
+ nullpo_ret(tstatus);
bst = status->get_base_status(bl);
+ nullpo_ret(bst);
type = status->skill2sc(sg->skill_id);
skill_id = sg->skill_id;
@@ -12074,12 +12333,12 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
tsc->sg_counter++; //SG hit counter.
if (skill->attack(skill->get_type(sg->skill_id),ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0) <= 0 && tsc)
tsc->sg_counter=0; //Attack absorbed.
- break;
+ break;
#endif
case GS_DESPERADO:
if (rnd()%100 < src->val1)
skill->attack(BF_WEAPON,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
- break;
+ break;
default:
skill->attack(skill->get_type(sg->skill_id),ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
}
@@ -12160,11 +12419,13 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
case UNT_VERDURETRAP:
if( bl->type == BL_PC )// it won't work on players
break;
+ FALLTHROUGH
case UNT_FIRINGTRAP:
case UNT_ICEBOUNDTRAP:
case UNT_CLUSTERBOMB:
if( bl->id == ss->id )// it won't trigger on caster
break;
+ FALLTHROUGH
case UNT_LANDMINE:
case UNT_BLASTMINE:
case UNT_SHOCKWAVE:
@@ -12456,6 +12717,7 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
case UNT_STEALTHFIELD:
if( bl->id == sg->src_id )
break; // Don't work on Self (video shows that)
+ FALLTHROUGH
case UNT_NEUTRALBARRIER:
sc_start(ss,bl,type,100,sg->skill_lv,sg->interval + 100);
break;
@@ -12646,6 +12908,30 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
status->change_start(ss, bl, SC_BLIND, rnd() % 100 > sg->skill_lv * 10, sg->skill_lv, sg->skill_id, 0, 0,
skill->get_time2(sg->skill_id, sg->skill_lv), SCFLAG_FIXEDTICK|SCFLAG_FIXEDRATE);
break;
+ case UNT_SV_ROOTTWIST:
+ if (status_get_mode(bl)&MD_BOSS) {
+ break;
+ }
+ if (tsc) {
+ if (!sg->val2) {
+ int sec = skill->get_time(sg->skill_id, sg->skill_lv);
+
+ if (sc_start2(ss, bl, type, 100, sg->skill_lv, sg->group_id, sec)) {
+ const struct TimerData* td = ((tsc->data[type])? timer->get(tsc->data[type]->timer) : NULL);
+
+ if (td != NULL)
+ sec = DIFF_TICK32(td->tick, tick);
+ clif->fixpos(bl);
+ sg->val2 = bl->id;
+ } else { // Couldn't trap it?
+ sec = 7000;
+ }
+ sg->limit = DIFF_TICK32(tick, sg->tick) + sec;
+ } else if (tsc->data[type] && bl->id == sg->val2) {
+ skill->attack(skill->get_type(SU_SV_ROOTTWIST_ATK), ss, &src->bl, bl, SU_SV_ROOTTWIST_ATK, sg->skill_lv, tick, SD_LEVEL|SD_ANIMATION);
+ }
+ }
+ break;
default:
skill->unit_onplace_timer_unknown(src, bl, &tick);
break;
@@ -12664,7 +12950,8 @@ void skill_unit_onplace_timer_unknown(struct skill_unit *src, struct block_list
/*==========================================
* Triggered when a char steps out of a skill cell
*------------------------------------------*/
-int skill_unit_onout(struct skill_unit *src, struct block_list *bl, int64 tick) {
+int skill_unit_onout(struct skill_unit *src, struct block_list *bl, int64 tick)
+{
struct skill_unit_group *sg;
struct status_change *sc;
struct status_change_entry *sce;
@@ -12729,7 +13016,8 @@ int skill_unit_onout(struct skill_unit *src, struct block_list *bl, int64 tick)
/*==========================================
* Triggered when a char steps out of a skill group (entirely) [Skotlex]
*------------------------------------------*/
-int skill_unit_onleft(uint16 skill_id, struct block_list *bl, int64 tick) {
+int skill_unit_onleft(uint16 skill_id, struct block_list *bl, int64 tick)
+{
struct status_change *sc;
struct status_change_entry *sce;
enum sc_type type;
@@ -12814,7 +13102,8 @@ int skill_unit_onleft(uint16 skill_id, struct block_list *bl, int64 tick) {
case PF_FOGWALL:
if (sce) {
status_change_end(bl, type, INVALID_TIMER);
- if ((sce=sc->data[SC_BLIND])) {
+ nullpo_retb(sc);
+ if ((sce = sc->data[SC_BLIND])) {
if (bl->type == BL_PC) //Players get blind ended immediately, others have it still for 30 secs. [Skotlex]
status_change_end(bl, SC_BLIND, INVALID_TIMER);
else {
@@ -12842,14 +13131,19 @@ int skill_unit_onleft(uint16 skill_id, struct block_list *bl, int64 tick) {
* flag&1: Invoke onplace function (otherwise invoke onout)
* flag&4: Invoke a onleft call (the unit might be scheduled for deletion)
*------------------------------------------*/
-int skill_unit_effect(struct block_list* bl, va_list ap) {
+int skill_unit_effect(struct block_list* bl, va_list ap)
+{
struct skill_unit* su = va_arg(ap,struct skill_unit*);
- struct skill_unit_group* group = su->group;
+ struct skill_unit_group* group;
int64 tick = va_arg(ap,int64);
unsigned int flag = va_arg(ap,unsigned int);
uint16 skill_id;
bool dissonance;
+ nullpo_ret(bl);
+ nullpo_ret(su);
+ group = su->group;
+
if( (!su->alive && !(flag&4)) || bl->prev == NULL )
return 0;
@@ -12881,7 +13175,8 @@ int skill_unit_effect(struct block_list* bl, va_list ap) {
/*==========================================
*
*------------------------------------------*/
-int skill_unit_ondamaged(struct skill_unit *src, struct block_list *bl, int64 damage, int64 tick) {
+int skill_unit_ondamaged(struct skill_unit *src, struct block_list *bl, int64 damage, int64 tick)
+{
struct skill_unit_group *sg;
nullpo_ret(src);
@@ -13002,12 +13297,16 @@ int skill_check_condition_char_sub (struct block_list *bl, va_list ap)
/*==========================================
* Checks and stores partners for ensemble skills [Skotlex]
*------------------------------------------*/
-int skill_check_pc_partner (struct map_session_data *sd, uint16 skill_id, uint16* skill_lv, int range, int cast_flag) {
+int skill_check_pc_partner(struct map_session_data *sd, uint16 skill_id, uint16* skill_lv, int range, int cast_flag)
+{
static int c=0;
static int p_sd[2] = { 0, 0 };
int i;
bool is_chorus = ( skill->get_inf2(skill_id)&INF2_CHORUS_SKILL );
+ nullpo_ret(sd);
+ nullpo_ret(skill_lv);
+
if (!battle_config.player_skill_partner_check || pc_has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL))
return is_chorus ? MAX_PARTY : 99; //As if there were infinite partners.
@@ -13084,6 +13383,7 @@ int skill_check_condition_mob_master_sub (struct block_list *bl, va_list ap)
*------------------------------------------*/
int skill_isammotype (struct map_session_data *sd, int skill_id)
{
+ nullpo_ret(sd);
return (
battle_config.arrow_decrement==2 &&
(sd->status.weapon == W_BOW || (sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE)) &&
@@ -13123,7 +13423,8 @@ bool skill_is_combo( int skill_id )
return false;
}
-int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id, uint16 skill_lv) {
+int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id, uint16 skill_lv)
+{
struct status_data *st;
struct status_change *sc;
struct skill_condition require;
@@ -13220,8 +13521,10 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
case SG_FUSION:
case RA_WUGDASH:
case KO_YAMIKUMO:
- if( sc && sc->data[status->skill2sc(skill_id)] )
+ case SU_HIDE:
+ if (sc && sc->data[status->skill2sc(skill_id)])
return 1;
+ FALLTHROUGH
default:
{
int ret = skill->check_condition_castbegin_off_unknown(sc, &skill_id);
@@ -13328,6 +13631,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
}
+ FALLTHROUGH
case SA_CASTCANCEL:
if(sd->ud.skilltimer == INVALID_TIMER) {
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
@@ -13577,6 +13881,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
}
+ FALLTHROUGH
case GD_EMERGENCYCALL:
// other checks were already done in skillnotok()
if (!sd->status.guild_id || !sd->state.gmaster_flag)
@@ -13599,6 +13904,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
}
+ FALLTHROUGH
case NJ_BUNSINJYUTSU:
if (!(sc && sc->data[SC_NJ_NEN])) {
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
@@ -13637,7 +13943,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
{
int count = 0, i;
for( i = 0; i < MAX_INVENTORY; i ++ )
- if( sd->status.inventory[i].nameid == ITEMID_ANCILLA )
+ if (sd->status.inventory[i].nameid == ITEMID_ANSILA)
count += sd->status.inventory[i].amount;
if( count >= 3 ) {
clif->skill_fail(sd, skill_id, USESKILL_FAIL_ANCILLA_NUMOVER, 0);
@@ -13925,6 +14231,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
}
+ FALLTHROUGH
case ST_CART:
if(!pc_iscarton(sd)) {
clif->skill_fail(sd,skill_id,USESKILL_FAIL_CART,0);
@@ -14018,11 +14325,13 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
}
+ FALLTHROUGH
case ST_MH_GRAPPLING:
if (!(sc && sc->data[SC_STYLE_CHANGE] && sc->data[SC_STYLE_CHANGE]->val2 == MH_MD_GRAPPLING)){
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
}
+ FALLTHROUGH
case ST_PECO:
if (!pc_isridingpeco(sd)) {
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
@@ -14089,7 +14398,8 @@ int skill_check_condition_castbegin_unknown(struct status_change *sc, uint16 *sk
return -1;
}
-int skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id, uint16 skill_lv) {
+int skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id, uint16 skill_lv)
+{
struct skill_condition require;
struct status_data *st;
int i;
@@ -14266,7 +14576,7 @@ int skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id,
cause = USESKILL_FAIL_BLUEJAMSTONE; break;
case ITEMID_HOLY_WATER:
cause = USESKILL_FAIL_HOLYWATER; break;
- case ITEMID_ANCILLA:
+ case ITEMID_ANSILA:
cause = USESKILL_FAIL_ANCILLA; break;
case ITEMID_ACCELERATOR:
case ITEMID_HOVERING_BOOSTER:
@@ -14293,12 +14603,14 @@ int skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id,
return 1;
}
-void skill_check_condition_castend_unknown(struct map_session_data* sd, uint16 *skill_id, uint16 *skill_lv) {
+void skill_check_condition_castend_unknown(struct map_session_data* sd, uint16 *skill_id, uint16 *skill_lv)
+{
}
// type&2: consume items (after skill was used)
// type&1: consume the others (before skill was used)
-int skill_consume_requirement( struct map_session_data *sd, uint16 skill_id, uint16 skill_lv, short type) {
+int skill_consume_requirement(struct map_session_data *sd, uint16 skill_id, uint16 skill_lv, short type)
+{
struct skill_condition req;
nullpo_ret(sd);
@@ -14379,7 +14691,8 @@ int skill_consume_requirement( struct map_session_data *sd, uint16 skill_id, uin
return 1;
}
-struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16 skill_id, uint16 skill_lv) {
+struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16 skill_id, uint16 skill_lv)
+{
struct skill_condition req;
struct status_data *st;
struct status_change *sc;
@@ -14421,7 +14734,8 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
case TK_READYTURN:
case SG_FUSION:
case KO_YAMIKUMO:
- if( sc && sc->data[status->skill2sc(skill_id)] )
+ case SU_HIDE:
+ if (sc && sc->data[status->skill2sc(skill_id)])
return req;
/* Fall through */
default:
@@ -14577,7 +14891,7 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
if ((item_index = pc->search_inventory(sd, req.itemid[i])) == INDEX_NOT_FOUND
|| sd->status.inventory[item_index].amount < req.amount[i]
) {
- req.itemid[i] = ITEMID_TRAP_ALLOY;
+ req.itemid[i] = ITEMID_SPECIAL_ALLOY_TRAP;
req.amount[i] = 1;
}
break;
@@ -14604,14 +14918,14 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
switch(skill_lv) {
case 1:
case 2:
- req.itemid[1] = ITEMID_REPAIR_A;
+ req.itemid[1] = ITEMID_REPAIRA;
break;
case 3:
case 4:
- req.itemid[1] = ITEMID_REPAIR_B;
+ req.itemid[1] = ITEMID_REPAIRB;
break;
case 5:
- req.itemid[1] = ITEMID_REPAIR_C;
+ req.itemid[1] = ITEMID_REPAIRC;
break;
}
req.amount[1] = 1;
@@ -14724,7 +15038,8 @@ void skill_get_requirement_unknown(struct status_change *sc, struct map_session_
/*==========================================
* Does cast-time reductions based on dex, item bonuses and config setting
*------------------------------------------*/
-int skill_castfix (struct block_list *bl, uint16 skill_id, uint16 skill_lv) {
+int skill_castfix (struct block_list *bl, uint16 skill_id, uint16 skill_lv)
+{
int time = skill->get_cast(skill_id, skill_lv);
nullpo_ret(bl);
@@ -14774,11 +15089,13 @@ int skill_castfix (struct block_list *bl, uint16 skill_id, uint16 skill_lv) {
/*==========================================
* Does cast-time reductions based on sc data.
*------------------------------------------*/
-int skill_castfix_sc (struct block_list *bl, int time) {
+int skill_castfix_sc (struct block_list *bl, int time)
+{
struct status_change *sc = status->get_sc(bl);
if( time < 0 )
return 0;
+ nullpo_ret(bl);
if( bl->type == BL_MOB ) // mobs casttime is fixed nothing to alter.
return time;
@@ -14807,7 +15124,9 @@ int skill_castfix_sc (struct block_list *bl, int time) {
//ShowInfo("Castime castfix_sc = %d\n",time);
return time;
}
-int skill_vfcastfix(struct block_list *bl, double time, uint16 skill_id, uint16 skill_lv) {
+
+int skill_vfcastfix(struct block_list *bl, double time, uint16 skill_id, uint16 skill_lv)
+{
#ifdef RENEWAL_CAST
struct status_change *sc = status->get_sc(bl);
struct map_session_data *sd = BL_CAST(BL_PC,bl);
@@ -14815,6 +15134,7 @@ int skill_vfcastfix(struct block_list *bl, double time, uint16 skill_id, uint16
if( time < 0 )
return 0;
+ nullpo_ret(bl);
if( bl->type == BL_MOB ) // mobs casttime is fixed nothing to alter.
return (int)time;
@@ -14886,6 +15206,7 @@ int skill_vfcastfix(struct block_list *bl, double time, uint16 skill_id, uint16
case WZ_FIREPILLAR:
if(skill_lv < 5)
break;
+ FALLTHROUGH
case HW_GRAVITATION:
case MG_SAFETYWALL:
case MG_STONECURSE:
@@ -14947,7 +15268,8 @@ int skill_vfcastfix(struct block_list *bl, double time, uint16 skill_id, uint16
/*==========================================
* Does delay reductions based on dex/agi, sc data, item bonuses, ...
*------------------------------------------*/
-int skill_delay_fix (struct block_list *bl, uint16 skill_id, uint16 skill_lv) {
+int skill_delay_fix (struct block_list *bl, uint16 skill_id, uint16 skill_lv)
+{
int delaynodex = skill->get_delaynodex(skill_id, skill_lv);
int time = skill->get_delay(skill_id, skill_lv);
struct map_session_data *sd;
@@ -15046,7 +15368,8 @@ struct square {
int val2[5];
};
-void skill_brandishspear_first (struct square *tc, uint8 dir, int16 x, int16 y) {
+void skill_brandishspear_first (struct square *tc, uint8 dir, int16 x, int16 y)
+{
nullpo_retv(tc);
if(dir == 0){
@@ -15141,7 +15464,8 @@ void skill_brandishspear_first (struct square *tc, uint8 dir, int16 x, int16 y)
}
-void skill_brandishspear_dir (struct square* tc, uint8 dir, int are) {
+void skill_brandishspear_dir (struct square* tc, uint8 dir, int are)
+{
int c;
nullpo_retv(tc);
@@ -15159,11 +15483,17 @@ void skill_brandishspear_dir (struct square* tc, uint8 dir, int are) {
}
}
-void skill_brandishspear(struct block_list* src, struct block_list* bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) {
+void skill_brandishspear(struct block_list* src, struct block_list* bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag)
+{
int c,n=4;
- uint8 dir = map->calc_dir(src,bl->x,bl->y);
+ uint8 dir;
struct square tc;
- int x=bl->x,y=bl->y;
+ int x, y;
+
+ nullpo_retv(bl);
+ x = bl->x;
+ y = bl->y;
+ dir = map->calc_dir(src, x, y);
skill->brandishspear_first(&tc,dir,x,y);
skill->brandishspear_dir(&tc,dir,4);
skill->area_temp[1] = bl->id;
@@ -15208,7 +15538,8 @@ void skill_brandishspear(struct block_list* src, struct block_list* bl, uint16 s
/*==========================================
* Weapon Repair [Celest/DracoRPG]
*------------------------------------------*/
-void skill_repairweapon (struct map_session_data *sd, int idx) {
+void skill_repairweapon (struct map_session_data *sd, int idx)
+{
int material;
int materials[4] = {
ITEMID_IRON_ORE,
@@ -15552,10 +15883,12 @@ int skill_frostjoke_scream(struct block_list *bl, va_list ap)
/*==========================================
*
*------------------------------------------*/
-void skill_unitsetmapcell (struct skill_unit *src, uint16 skill_id, uint16 skill_lv, cell_t cell, bool flag) {
+void skill_unitsetmapcell (struct skill_unit *src, uint16 skill_id, uint16 skill_lv, cell_t cell, bool flag)
+{
int range = skill->get_unit_range(skill_id,skill_lv);
int x,y;
+ nullpo_retv(src);
for( y = src->bl.y - range; y <= src->bl.y + range; ++y )
for( x = src->bl.x - range; x <= src->bl.x + range; ++x )
map->list[src->bl.m].setcell(src->bl.m, x, y, cell, flag);
@@ -15564,11 +15897,14 @@ void skill_unitsetmapcell (struct skill_unit *src, uint16 skill_id, uint16 skill
/*==========================================
*
*------------------------------------------*/
-int skill_attack_area(struct block_list *bl, va_list ap) {
+int skill_attack_area(struct block_list *bl, va_list ap)
+{
struct block_list *src,*dsrc;
int atk_type,skill_id,skill_lv,flag,type;
int64 tick;
+ nullpo_ret(bl);
+
if(status->isdead(bl))
return 0;
@@ -15648,7 +15984,8 @@ int skill_clear_group (struct block_list *bl, int flag)
/*==========================================
* Returns the first element field found [Skotlex]
*------------------------------------------*/
-struct skill_unit_group *skill_locate_element_field(struct block_list *bl) {
+struct skill_unit_group *skill_locate_element_field(struct block_list *bl)
+{
struct unit_data *ud = unit->bl2ud(bl);
int i;
nullpo_ret(bl);
@@ -15986,7 +16323,8 @@ int skill_trap_splash(struct block_list *bl, va_list ap)
/*==========================================
*
*------------------------------------------*/
-int skill_enchant_elemental_end (struct block_list *bl, int type) {
+int skill_enchant_elemental_end(struct block_list *bl, int type)
+{
struct status_change *sc;
const enum sc_type scs[] = { SC_ENCHANTPOISON, SC_ASPERSIO, SC_PROPERTYFIRE, SC_PROPERTYWATER, SC_PROPERTYWIND, SC_PROPERTYGROUND, SC_PROPERTYDARK, SC_PROPERTYTELEKINESIS, SC_ENCHANTARMS };
int i;
@@ -16006,6 +16344,7 @@ bool skill_check_cloaking(struct block_list *bl, struct status_change_entry *sce
{
bool wall = true;
+ nullpo_retr(false, bl);
if( (bl->type == BL_PC && battle_config.pc_cloak_check_type&1)
|| (bl->type != BL_PC && battle_config.monster_cloak_check_type&1)
) {
@@ -16040,7 +16379,8 @@ bool skill_check_cloaking(struct block_list *bl, struct status_change_entry *sce
/**
* Verifies if an user can use SC_CLOAKING
**/
-bool skill_can_cloak(struct map_session_data *sd) {
+bool skill_can_cloak(struct map_session_data *sd)
+{
nullpo_retr(false, sd);
//Avoid cloaking with no wall and low skill level. [Skotlex]
@@ -16071,6 +16411,7 @@ bool skill_check_camouflage(struct block_list *bl, struct status_change_entry *s
{
bool wall = true;
+ nullpo_retr(false, bl);
if( bl->type == BL_PC ) { //Check for walls.
static int dx[] = { 0, 1, 0, -1, -1, 1, 1, -1};
static int dy[] = {-1, 0, 1, 0, -1, -1, 1, 1};
@@ -16133,7 +16474,8 @@ bool skill_check_shadowform(struct block_list *bl, int64 damage, int hit)
/*==========================================
*
*------------------------------------------*/
-struct skill_unit *skill_initunit (struct skill_unit_group *group, int idx, int x, int y, int val1, int val2) {
+struct skill_unit *skill_initunit (struct skill_unit_group *group, int idx, int x, int y, int val1, int val2)
+{
struct skill_unit *su;
nullpo_retr(NULL, group);
@@ -16185,7 +16527,8 @@ struct skill_unit *skill_initunit (struct skill_unit_group *group, int idx, int
/*==========================================
*
*------------------------------------------*/
-int skill_delunit (struct skill_unit* su) {
+int skill_delunit (struct skill_unit* su)
+{
struct skill_unit_group *group;
nullpo_ret(su);
@@ -16506,6 +16849,7 @@ struct skill_unit_group_tickset *skill_unitgrouptickset_search(struct block_list
struct skill_unit_group_tickset *set;
nullpo_ret(bl);
+ nullpo_ret(group);
if (group->interval==-1)
return NULL;
@@ -16540,10 +16884,16 @@ struct skill_unit_group_tickset *skill_unitgrouptickset_search(struct block_list
/*==========================================
*
*------------------------------------------*/
-int skill_unit_timer_sub_onplace(struct block_list* bl, va_list ap) {
- struct skill_unit* su = va_arg(ap,struct skill_unit *);
- struct skill_unit_group* group = su->group;
- int64 tick = va_arg(ap,int64);
+int skill_unit_timer_sub_onplace(struct block_list* bl, va_list ap)
+{
+ struct skill_unit* su;
+ struct skill_unit_group* group;
+ int64 tick;
+
+ su = va_arg(ap,struct skill_unit *);
+ nullpo_ret(su);
+ group = su->group;
+ tick = va_arg(ap,int64);
if( !su->alive || bl->prev == NULL )
return 0;
@@ -16566,11 +16916,16 @@ int skill_unit_timer_sub_onplace(struct block_list* bl, va_list ap) {
*/
int skill_unit_timer_sub(union DBKey key, struct DBData *data, va_list ap)
{
- struct skill_unit* su = DB->data2ptr(data);
- struct skill_unit_group* group = su->group;
+ struct skill_unit* su;
+ struct skill_unit_group* group;
int64 tick = va_arg(ap,int64);
bool dissonance;
- struct block_list* bl = &su->bl;
+ struct block_list* bl;
+
+ su = DB->data2ptr(data);
+ nullpo_ret(su);
+ group = su->group;
+ bl = &su->bl;
if( !su->alive )
return 0;
@@ -16603,6 +16958,7 @@ int skill_unit_timer_sub(union DBKey key, struct DBData *data, va_list ap)
skill->delunit(su);
break;
}
+ FALLTHROUGH
case UNT_SKIDTRAP:
case UNT_LANDMINE:
case UNT_SHOCKWAVE:
@@ -16627,7 +16983,7 @@ int skill_unit_timer_sub(union DBKey key, struct DBData *data, va_list ap)
// revert unit back into a trap
struct item item_tmp;
memset(&item_tmp,0,sizeof(item_tmp));
- item_tmp.nameid = group->item_id?group->item_id:ITEMID_TRAP;
+ item_tmp.nameid = group->item_id ? group->item_id : ITEMID_BOOBY_TRAP;
item_tmp.identify = 1;
map->addflooritem(bl, &item_tmp, 1, bl->m, bl->x, bl->y, 0, 0, 0, 0);
}
@@ -16778,7 +17134,8 @@ int skill_unit_timer_sub(union DBKey key, struct DBData *data, va_list ap)
/*==========================================
* Executes on all skill units every SKILLUNITTIMER_INTERVAL milliseconds.
*------------------------------------------*/
-int skill_unit_timer(int tid, int64 tick, int id, intptr_t data) {
+int skill_unit_timer(int tid, int64 tick, int id, intptr_t data)
+{
map->freeblock_lock();
skill->unit_db->foreach(skill->unit_db, skill->unit_timer_sub, tick);
@@ -16804,6 +17161,7 @@ int skill_unit_move_sub(struct block_list* bl, va_list ap)
uint16 skill_id;
int i;
+ nullpo_ret(target);
nullpo_ret(bl);
Assert_ret(bl->type == BL_SKILL);
su = BL_UCAST(BL_SKILL, bl);
@@ -16890,7 +17248,8 @@ int skill_unit_move_sub(struct block_list* bl, va_list ap)
* units to figure out when they have left a group.
* flag&4: Force a onleft event (triggered when the bl is killed, for example)
*------------------------------------------*/
-int skill_unit_move(struct block_list *bl, int64 tick, int flag) {
+int skill_unit_move(struct block_list *bl, int64 tick, int flag)
+{
nullpo_ret(bl);
if( bl->prev == NULL )
@@ -16915,7 +17274,8 @@ int skill_unit_move(struct block_list *bl, int64 tick, int flag) {
/*==========================================
*
*------------------------------------------*/
-int skill_unit_move_unit_group(struct skill_unit_group *group, int16 m, int16 dx, int16 dy) {
+int skill_unit_move_unit_group(struct skill_unit_group *group, int16 m, int16 dx, int16 dy)
+{
int i,j;
int64 tick = timer->gettick();
int *m_flag;
@@ -17067,7 +17427,8 @@ int skill_can_produce_mix (struct map_session_data *sd, int nameid, int trigger,
/*==========================================
*
*------------------------------------------*/
-int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, int slot1, int slot2, int slot3, int qty) {
+int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, int slot1, int slot2, int slot3, int qty)
+{
int slot[3];
int i,sc,ele,idx,equip,wlv,make_per = 0,flag = 0,skill_lv = 0;
int num = -1; // exclude the recipe
@@ -17262,12 +17623,15 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid,
case ITEMID_HAGALAZ:
case ITEMID_OTHILA:
D -= 500; //Rank C
+ FALLTHROUGH
case ITEMID_ISA:
case ITEMID_WYRD:
D -= 500; //Rank B
+ FALLTHROUGH
case ITEMID_NAUTHIZ:
case ITEMID_URUZ:
D -= 500; //Rank A
+ FALLTHROUGH
case ITEMID_BERKANA:
case ITEMID_LUX_ANIMA:
D -= 500; //Rank S
@@ -17712,7 +18076,9 @@ int skill_arrow_create (struct map_session_data *sd, int nameid)
return 0;
}
-int skill_poisoningweapon( struct map_session_data *sd, int nameid) {
+
+int skill_poisoningweapon(struct map_session_data *sd, int nameid)
+{
sc_type type;
int chance, i;
nullpo_ret(sd);
@@ -17743,7 +18109,8 @@ int skill_poisoningweapon( struct map_session_data *sd, int nameid) {
return 0;
}
-void skill_toggle_magicpower(struct block_list *bl, uint16 skill_id) {
+void skill_toggle_magicpower(struct block_list *bl, uint16 skill_id)
+{
struct status_change *sc = status->get_sc(bl);
// non-offensive and non-magic skills do not affect the status
@@ -17767,7 +18134,8 @@ void skill_toggle_magicpower(struct block_list *bl, uint16 skill_id) {
}
}
-int skill_magicdecoy(struct map_session_data *sd, int nameid) {
+int skill_magicdecoy(struct map_session_data *sd, int nameid)
+{
int x, y, i, class_ = 0, skill_id;
struct mob_data *md;
nullpo_ret(sd);
@@ -17789,16 +18157,16 @@ int skill_magicdecoy(struct map_session_data *sd, int nameid) {
sd->menuskill_val = 0;
switch (nameid) {
- case ITEMID_SCARLET_POINT:
+ case ITEMID_SCARLET_PTS:
class_ = MOBID_MAGICDECOY_FIRE;
break;
- case ITEMID_INDIGO_POINT:
+ case ITEMID_INDIGO_PTS:
class_ = MOBID_MAGICDECOY_WATER;
break;
- case ITEMID_LIME_GREEN_POINT:
+ case ITEMID_LIME_GREEN_PTS:
class_ = MOBID_MAGICDECOY_WIND;
break;
- case ITEMID_YELLOW_WISH_POINT:
+ case ITEMID_YELLOW_WISH_PTS:
class_ = MOBID_MAGICDECOY_EARTH;
break;
}
@@ -17818,7 +18186,8 @@ int skill_magicdecoy(struct map_session_data *sd, int nameid) {
}
// Warlock Spellbooks. [LimitLine/3CeAM]
-int skill_spellbook (struct map_session_data *sd, int nameid) {
+int skill_spellbook(struct map_session_data *sd, int nameid)
+{
int i, max_preserve, skill_id, point;
struct status_change *sc;
@@ -17866,7 +18235,9 @@ int skill_spellbook (struct map_session_data *sd, int nameid) {
return 1;
}
-int skill_select_menu(struct map_session_data *sd,uint16 skill_id) {
+
+int skill_select_menu(struct map_session_data *sd,uint16 skill_id)
+{
int id, lv, prob, aslvl = 0, idx = 0;
nullpo_ret(sd);
@@ -18012,6 +18383,7 @@ int skill_changematerial(struct map_session_data *sd, const struct itemlist *ite
return 0;
}
+
/**
* for Royal Guard's LG_TRAMPLE
**/
@@ -18047,10 +18419,12 @@ int skill_destroy_trap(struct block_list *bl, va_list ap)
}
return 0;
}
+
/*==========================================
*
*------------------------------------------*/
-int skill_blockpc_end(int tid, int64 tick, int id, intptr_t data) {
+int skill_blockpc_end(int tid, int64 tick, int id, intptr_t data)
+{
struct map_session_data *sd = map->id2sd(id);
struct skill_cd * cd = NULL;
@@ -18102,7 +18476,8 @@ int skill_blockpc_end(int tid, int64 tick, int id, intptr_t data) {
* @param tick the length of time the delay should last
* @return 0 if successful, -1 otherwise
*/
-int skill_blockpc_start_(struct map_session_data *sd, uint16 skill_id, int tick) {
+int skill_blockpc_start_(struct map_session_data *sd, uint16 skill_id, int tick)
+{
struct skill_cd* cd = NULL;
uint16 idx = skill->get_index(skill_id);
int64 now = timer->gettick();
@@ -18197,7 +18572,9 @@ int skill_blockhomun_end(int tid, int64 tick, int id, intptr_t data)
return 1;
}
-int skill_blockhomun_start(struct homun_data *hd, uint16 skill_id, int tick) { // [orn]
+// [orn]
+int skill_blockhomun_start(struct homun_data *hd, uint16 skill_id, int tick)
+{
uint16 idx = skill->get_index(skill_id);
nullpo_retr (-1, hd);
@@ -18239,12 +18616,15 @@ int skill_blockmerc_start(struct mercenary_data *md, uint16 skill_id, int tick)
md->blockskill[idx] = 1;
return timer->add(timer->gettick() + tick, skill->blockmerc_end, md->bl.id, idx);
}
+
/**
* Adds a new skill unit entry for this player to recast after map load
**/
-void skill_usave_add(struct map_session_data * sd, uint16 skill_id, uint16 skill_lv) {
+void skill_usave_add(struct map_session_data * sd, uint16 skill_id, uint16 skill_lv)
+{
struct skill_unit_save * sus = NULL;
+ nullpo_retv(sd);
if( idb_exists(skill->usave_db,sd->status.char_id) ) {
idb_remove(skill->usave_db,sd->status.char_id);
}
@@ -18257,9 +18637,12 @@ void skill_usave_add(struct map_session_data * sd, uint16 skill_id, uint16 skill
return;
}
-void skill_usave_trigger(struct map_session_data *sd) {
+
+void skill_usave_trigger(struct map_session_data *sd)
+{
struct skill_unit_save * sus = NULL;
+ nullpo_retv(sd);
if( ! (sus = idb_get(skill->usave_db,sd->status.char_id)) ) {
return;
}
@@ -18277,6 +18660,8 @@ int skill_split_atoi(char *str, int *val)
{
int i, j, step = 1;
+ nullpo_ret(val);
+
for (i=0; i<MAX_SKILL_LEVEL; i++) {
if (!str) break;
val[i] = atoi(str);
@@ -18595,7 +18980,8 @@ void skill_init_unit_layout_unknown(int skill_idx)
ShowError("unknown unit layout at skill %d\n", skill_idx);
}
-int skill_block_check(struct block_list *bl, sc_type type , uint16 skill_id) {
+int skill_block_check(struct block_list *bl, sc_type type , uint16 skill_id)
+{
int inf = 0;
struct status_change *sc = status->get_sc(bl);
@@ -18742,7 +19128,8 @@ int skill_block_check(struct block_list *bl, sc_type type , uint16 skill_id) {
return 0;
}
-int skill_get_elemental_type( uint16 skill_id , uint16 skill_lv ) {
+int skill_get_elemental_type(uint16 skill_id , uint16 skill_lv)
+{
int type = 0;
switch (skill_id) {
@@ -18761,7 +19148,8 @@ int skill_get_elemental_type( uint16 skill_id , uint16 skill_lv ) {
* update stored skill cooldowns for player logout
* @param sd the affected player structure
*/
-void skill_cooldown_save(struct map_session_data * sd) {
+void skill_cooldown_save(struct map_session_data * sd)
+{
int i;
struct skill_cd* cd = NULL;
int64 now = 0;
@@ -18789,7 +19177,8 @@ void skill_cooldown_save(struct map_session_data * sd) {
* reload stored skill cooldowns when a player logs in.
* @param sd the affected player structure
*/
-void skill_cooldown_load(struct map_session_data * sd) {
+void skill_cooldown_load(struct map_session_data * sd)
+{
int i;
struct skill_cd* cd = NULL;
int64 now = 0;
@@ -18813,11 +19202,14 @@ void skill_cooldown_load(struct map_session_data * sd) {
}
}
-bool skill_parse_row_producedb(char* split[], int columns, int current) {
+bool skill_parse_row_producedb(char* split[], int columns, int current)
+{
// ProduceItemID,ItemLV,RequireSkill,Requireskill_lv,MaterialID1,MaterialAmount1,......
int x,y;
+ int i;
- int i = atoi(split[0]);
+ nullpo_retr(false, split);
+ i = atoi(split[0]);
if( !i )
return false;
@@ -18834,11 +19226,14 @@ bool skill_parse_row_producedb(char* split[], int columns, int current) {
return true;
}
-bool skill_parse_row_createarrowdb(char* split[], int columns, int current) {
+bool skill_parse_row_createarrowdb(char* split[], int columns, int current)
+{
// SourceID,MakeID1,MakeAmount1,...,MakeID5,MakeAmount5
int x,y;
- int i = atoi(split[0]);
+ int i;
+ nullpo_retr(false, split);
+ i = atoi(split[0]);
if( !i )
return false;
@@ -18851,12 +19246,19 @@ bool skill_parse_row_createarrowdb(char* split[], int columns, int current) {
return true;
}
-bool skill_parse_row_spellbookdb(char* split[], int columns, int current) {
+
+bool skill_parse_row_spellbookdb(char* split[], int columns, int current)
+{
// skill_id,PreservePoints
- uint16 skill_id = atoi(split[0]);
- int points = atoi(split[1]);
- int nameid = atoi(split[2]);
+ uint16 skill_id;
+ int points;
+ int nameid;
+
+ nullpo_retr(false, split);
+ skill_id = atoi(split[0]);
+ points = atoi(split[1]);
+ nameid = atoi(split[2]);
if( !skill->get_index(skill_id) || !skill->get_max(skill_id) )
ShowError("spellbook_db: Invalid skill ID %d\n", skill_id);
@@ -18874,10 +19276,16 @@ bool skill_parse_row_spellbookdb(char* split[], int columns, int current) {
return false;
}
-bool skill_parse_row_improvisedb(char* split[], int columns, int current) {
+
+bool skill_parse_row_improvisedb(char* split[], int columns, int current)
+{
// SkillID,Rate
- uint16 skill_id = atoi(split[0]);
- short j = atoi(split[1]);
+ uint16 skill_id;
+ short j;
+
+ nullpo_retr(false, split);
+ skill_id = atoi(split[0]);
+ j = atoi(split[1]);
if( !skill->get_index(skill_id) || !skill->get_max(skill_id) ) {
ShowError("skill_improvise_db: Invalid skill ID %d\n", skill_id);
@@ -18900,10 +19308,14 @@ bool skill_parse_row_improvisedb(char* split[], int columns, int current) {
return true;
}
-bool skill_parse_row_magicmushroomdb(char* split[], int column, int current) {
+
+bool skill_parse_row_magicmushroomdb(char* split[], int column, int current)
+{
// SkillID
- uint16 skill_id = atoi(split[0]);
+ uint16 skill_id;
+ nullpo_retr(false, split);
+ skill_id = atoi(split[0]);
if( !skill->get_index(skill_id) || !skill->get_max(skill_id) ) {
ShowError("magicmushroom_db: Invalid skill ID %d\n", skill_id);
return false;
@@ -18918,9 +19330,13 @@ bool skill_parse_row_magicmushroomdb(char* split[], int column, int current) {
return true;
}
-bool skill_parse_row_reproducedb(char* split[], int column, int current) {
- uint16 skill_id = atoi(split[0]);
- uint16 idx = skill->get_index(skill_id);
+bool skill_parse_row_reproducedb(char* split[], int column, int current)
+{
+ uint16 skill_id;
+ uint16 idx;
+ nullpo_retr(false, split);
+ skill_id = atoi(split[0]);
+ idx = skill->get_index(skill_id);
if( !idx )
return false;
@@ -18929,9 +19345,12 @@ bool skill_parse_row_reproducedb(char* split[], int column, int current) {
return true;
}
-bool skill_parse_row_abradb(char* split[], int columns, int current) {
+bool skill_parse_row_abradb(char* split[], int columns, int current)
+{
// skill_id,DummyName,RequiredHocusPocusLevel,Rate
- uint16 skill_id = atoi(split[0]);
+ uint16 skill_id;
+ nullpo_retr(false, split);
+ skill_id = atoi(split[0]);
if( !skill->get_index(skill_id) || !skill->get_max(skill_id) ) {
ShowError("abra_db: Invalid skill ID %d\n", skill_id);
return false;
@@ -18948,12 +19367,16 @@ bool skill_parse_row_abradb(char* split[], int columns, int current) {
return true;
}
-bool skill_parse_row_changematerialdb(char* split[], int columns, int current) {
+bool skill_parse_row_changematerialdb(char* split[], int columns, int current)
+{
// ProductID,BaseRate,MakeAmount1,MakeAmountRate1...,MakeAmount5,MakeAmountRate5
- uint16 skill_id = atoi(split[0]);
- short j = atoi(split[1]);
+ uint16 skill_id;
+ short j;
int x,y;
+ nullpo_retr(false, split);
+ skill_id = atoi(split[0]);
+ j = atoi(split[1]);
for(x=0; x<MAX_SKILL_PRODUCE_DB; x++){
if( skill->dbs->produce_db[x].nameid == skill_id )
if( skill->dbs->produce_db[x].req_skill == GN_CHANGEMATERIAL )
@@ -18993,9 +19416,10 @@ void skill_config_set_level(struct config_setting_t *conf, int *arr)
{
int i=0;
+ nullpo_retv(arr);
if (config_setting_is_group(conf)) {
for (i=0; i<MAX_SKILL_LEVEL; i++) {
- char level[5];
+ char level[6]; // enough to contain "Lv100" in case of custom MAX_SKILL_LEVEL
sprintf(level, "Lv%d", i+1);
libconfig->setting_lookup_int(conf, level, &arr[i]);
}
@@ -19020,7 +19444,8 @@ void skill_config_set_level(struct config_setting_t *conf, int *arr)
void skill_level_set_value(int *arr, int value)
{
int i=0;
-
+
+ nullpo_retv(arr);
for(i=0; i<MAX_SKILL_LEVEL; i++) {
arr[i] = value;
}
@@ -19030,6 +19455,7 @@ void skill_validate_hittype(struct config_setting_t *conf, struct s_skill_db *sk
{
const char *type = NULL;
+ nullpo_retv(sk);
if (libconfig->setting_lookup_string(conf, "Hit", &type)) {
if (strcmpi(type, "BDT_SKILL") == 0) {
sk->hit = BDT_SKILL;
@@ -19054,6 +19480,7 @@ void skill_validate_skilltype(struct config_setting_t *conf, struct s_skill_db *
{
struct config_setting_t *t = NULL, *tt = NULL;
+ nullpo_retv(sk);
if((t=libconfig->setting_get_member(conf, "SkillType")) && config_setting_is_group(t)) {
int j=0;
while ((tt = libconfig->setting_get_elem(t, j++))) {
@@ -19107,6 +19534,7 @@ void skill_validate_skillinfo(struct config_setting_t *conf, struct s_skill_db *
{
struct config_setting_t *t = NULL, *tt = NULL;
+ nullpo_retv(sk);
if ((t=libconfig->setting_get_member(conf, "SkillInfo")) && config_setting_is_group(t)) {
int j=0;
while ((tt = libconfig->setting_get_elem(t, j++))) {
@@ -19232,6 +19660,7 @@ void skill_validate_attacktype(struct config_setting_t *conf, struct s_skill_db
{
const char *type = NULL;
+ nullpo_retv(sk);
if (libconfig->setting_lookup_string(conf, "AttackType", &type)) {
if (!strcmpi(type, "Weapon")) {
sk->skill_type = BF_WEAPON;
@@ -19257,9 +19686,10 @@ void skill_validate_element(struct config_setting_t *conf, struct s_skill_db *sk
const char *type = NULL;
struct config_setting_t *t = NULL;
+ nullpo_retv(sk);
if ((t=libconfig->setting_get_member(conf, "Element")) && config_setting_is_group(t)) {
int j = 0;
- char lv[5];
+ char lv[6]; // enough to contain "Lv100" in case of custom MAX_SKILL_LEVEL
for (j=0; j < MAX_SKILL_LEVEL; j++) {
sprintf(lv, "Lv%d",j+1);
@@ -19303,6 +19733,7 @@ void skill_validate_damagetype(struct config_setting_t *conf, struct s_skill_db
{
struct config_setting_t *t = NULL, *tt = NULL;
+ nullpo_retv(sk);
if ((t=libconfig->setting_get_member(conf, "DamageType")) && config_setting_is_group(t)) {
int j=0;
while ((tt = libconfig->setting_get_elem(t, j++))) {
@@ -19375,6 +19806,7 @@ void skill_validate_castnodex(struct config_setting_t *conf, struct s_skill_db *
{
struct config_setting_t *t = NULL, *tt = NULL;
+ nullpo_retv(sk);
if ((t=libconfig->setting_get_member(conf, delay?"SkillDelayOptions":"CastTimeOptions")) && config_setting_is_group(t)) {
int j = 0, tmpopt = 0;
while ((tt = libconfig->setting_get_elem(t, j++)) && j < 4) {
@@ -19417,8 +19849,9 @@ void skill_validate_castnodex(struct config_setting_t *conf, struct s_skill_db *
* @param *sk struct, pointer to s_skill_db
* @return void
*/
-int skill_validate_weapontype_sub(const char *type, bool on, struct s_skill_db *sk )
+int skill_validate_weapontype_sub(const char *type, bool on, struct s_skill_db *sk)
{
+ nullpo_ret(sk);
if (strcmpi(type, "NoWeapon") == 0) {
if (on) {
sk->weapon |= 1<<W_FIST;
@@ -19624,15 +20057,16 @@ void skill_validate_weapontype(struct config_setting_t *conf, struct s_skill_db
struct config_setting_t *tt = NULL;
const char *type = NULL;
+ nullpo_retv(sk);
if ((tt = libconfig->setting_get_member(conf, "WeaponTypes")) && config_setting_is_group(tt)) {
int j = 0;
struct config_setting_t *wpt = NULL;
while ((wpt = libconfig->setting_get_elem(tt, j++)) != NULL) {
- if (skill_validate_weapontype_sub(config_setting_name(wpt), libconfig->setting_get_bool_real(wpt), sk))
+ if (skill->validate_weapontype_sub(config_setting_name(wpt), libconfig->setting_get_bool_real(wpt), sk))
skilldb_invalid_error(config_setting_name(wpt), config_setting_name(tt), sk->nameid);
}
} else if (libconfig->setting_lookup_string(conf, "WeaponTypes", &type)) {
- if (skill_validate_weapontype_sub(type, true, sk))
+ if (skill->validate_weapontype_sub(type, true, sk))
skilldb_invalid_error(type, "WeaponTypes", sk->nameid);
}
}
@@ -19647,6 +20081,7 @@ void skill_validate_weapontype(struct config_setting_t *conf, struct s_skill_db
*/
int skill_validate_ammotype_sub(const char *type, bool on, struct s_skill_db *sk)
{
+ nullpo_ret(sk);
if (strcmpi(type, "A_ARROW") == 0) {
if (on) {
sk->ammo |= 1<<A_ARROW;
@@ -19726,15 +20161,16 @@ void skill_validate_ammotype(struct config_setting_t *conf, struct s_skill_db *s
struct config_setting_t *tt = NULL;
const char *tstr = NULL;
+ nullpo_retv(sk);
if ((tt = libconfig->setting_get_member(conf, "AmmoTypes")) && config_setting_is_group(tt)) {
int j = 0;
struct config_setting_t *amt = { 0 };
while ((amt = libconfig->setting_get_elem(tt, j++))) {
- if (skill_validate_ammotype_sub(config_setting_name(amt), libconfig->setting_get_bool_real(amt), sk))
+ if (skill->validate_ammotype_sub(config_setting_name(amt), libconfig->setting_get_bool_real(amt), sk))
skilldb_invalid_error(config_setting_name(amt), config_setting_name(tt), sk->nameid);
}
} else if( libconfig->setting_lookup_string(conf, "AmmoTypes", &tstr)) {
- if (skill_validate_ammotype_sub(tstr, true, sk))
+ if (skill->validate_ammotype_sub(tstr, true, sk))
skilldb_invalid_error(tstr, "AmmoTypes", sk->nameid);
}
}
@@ -19750,6 +20186,7 @@ void skill_validate_state(struct config_setting_t *conf, struct s_skill_db *sk)
{
const char *type = NULL;
+ nullpo_retv(sk);
if (libconfig->setting_lookup_string(conf, "State", &type) && strcmpi(type,"None") != ST_NONE) {
if ( strcmpi(type,"Hiding") == 0 ) sk->state = ST_HIDING;
else if (strcmpi(type,"Cloaking") == 0 ) sk->state = ST_CLOAKING;
@@ -19790,6 +20227,7 @@ void skill_validate_item_requirements(struct config_setting_t *conf, struct s_sk
{
struct config_setting_t *tt = NULL;
+ nullpo_retv(sk);
if ((tt=libconfig->setting_get_member(conf, "Items")) && config_setting_is_group(conf)) {
int itx=-1;
struct config_setting_t *it;
@@ -19826,6 +20264,7 @@ void skill_validate_unit_target(struct config_setting_t *conf, struct s_skill_db
{
const char *type = NULL;
+ nullpo_retv(sk);
if(libconfig->setting_lookup_string(conf, "Target", &type)) {
if(!strcmpi(type,"NotEnemy")) sk->unit_target = BCT_NOENEMY;
@@ -19865,6 +20304,8 @@ void skill_validate_unit_target(struct config_setting_t *conf, struct s_skill_db
*/
int skill_validate_unit_flag_sub(const char *type, bool on, struct s_skill_db *sk)
{
+ nullpo_ret(type);
+ nullpo_ret(sk);
if (strcmpi(type, "UF_DEFNOTENEMY") == 0) {
if (on) {
sk->unit_flag |= UF_DEFNOTENEMY;
@@ -19961,13 +20402,14 @@ void skill_validate_unit_flag(struct config_setting_t *conf, struct s_skill_db *
{
struct config_setting_t *t = NULL;
+ nullpo_retv(sk);
if ((t=libconfig->setting_get_member(conf, "Flag")) && config_setting_is_group(t)) {
int j=0;
struct config_setting_t *tt = NULL;
while ((tt = libconfig->setting_get_elem(t, j++))) {
const char *name = config_setting_name(tt);
- if (skill_validate_unit_flag_sub(name, libconfig->setting_get_bool_real(tt), sk))
+ if (skill->validate_unit_flag_sub(name, libconfig->setting_get_bool_real(tt), sk))
skilldb_invalid_error(name, config_setting_name(t), sk->nameid);
}
}
@@ -19992,8 +20434,10 @@ void skill_validate_additional_fields(struct config_setting_t *conf, struct s_sk
*/
bool skill_validate_skilldb(struct s_skill_db *sk, const char *source)
{
- int idx = skill->get_index(sk->nameid);
+ int idx;
+ nullpo_retr(false, sk);
+ idx = skill->get_index(sk->nameid);
if (idx == 0) {
ShowWarning("skill_validate_skilldb: Invalid skill Id %d provided in '%s'! ... skipping\n", sk->nameid, source);
ShowInfo("It is possible that the skill Id is 0 or unavailable (interferes with guild/homun/mercenary skill mapping).\n");
@@ -20276,7 +20720,8 @@ bool skill_read_skilldb(const char *filename)
* create_arrow_db.txt
* abra_db.txt
*------------------------------*/
-void skill_readdb(bool minimal) {
+void skill_readdb(bool minimal)
+{
// init skill db structures
db_clear(skill->name2id_db);
@@ -20348,7 +20793,8 @@ void skill_reload(void)
/*==========================================
*
*------------------------------------------*/
-int do_init_skill(bool minimal) {
+int do_init_skill(bool minimal)
+{
skill->name2id_db = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, MAX_SKILL_NAME_LENGTH);
skill->read_db(minimal);
@@ -20381,7 +20827,8 @@ int do_init_skill(bool minimal) {
return 0;
}
-int do_final_skill(void) {
+int do_final_skill(void)
+{
db_destroy(skill->name2id_db);
db_destroy(skill->group_db);
db_destroy(skill->unit_db);
@@ -20394,8 +20841,10 @@ int do_final_skill(void) {
ers_destroy(skill->cd_entry_ers);
return 0;
}
+
/* initialize the interface */
-void skill_defaults(void) {
+void skill_defaults(void)
+{
const int skill_enchant_eff[5] = { 10, 14, 17, 19, 20 };
const int skill_deluge_eff[5] = { 5, 9, 12, 14, 15 };
@@ -20605,6 +21054,9 @@ void skill_defaults(void) {
skill->validate_unit_flag = skill_validate_unit_flag;
skill->validate_additional_fields = skill_validate_additional_fields;
skill->validate_skilldb = skill_validate_skilldb;
+ skill->validate_weapontype_sub = skill_validate_weapontype_sub;
+ skill->validate_ammotype_sub = skill_validate_ammotype_sub;
+ skill->validate_unit_flag_sub = skill_validate_unit_flag_sub;
skill->read_skilldb = skill_read_skilldb;
skill->config_set_level = skill_config_set_level;
skill->level_set_value = skill_level_set_value;