summaryrefslogtreecommitdiff
path: root/src/map/status.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/status.c')
-rw-r--r--src/map/status.c591
1 files changed, 526 insertions, 65 deletions
diff --git a/src/map/status.c b/src/map/status.c
index 1f0f31119..589acff5c 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -696,6 +696,7 @@ static void initChangeTables(void)
status->set_sc( WM_BEYOND_OF_WARCRY , SC_BEYOND_OF_WARCRY , SCB_STR|SCB_CRI|SCB_MAXHP );
status->set_sc( WM_UNLIMITED_HUMMING_VOICE, SC_UNLIMITED_HUMMING_VOICE, SCB_NONE );
status->set_sc( WM_FRIGG_SONG , SC_FRIGG_SONG , SCB_MAXHP );
+ status->set_sc( WM_SEVERE_RAINSTORM , SC_NO_SWITCH_EQUIP , SCB_NONE );
/**
* Sorcerer
@@ -801,21 +802,21 @@ static void initChangeTables(void)
set_sc_with_vfx( GN_ILLUSIONDOPING , SC_ILLUSIONDOPING , SCB_HIT );
// Storing the target job rather than simply SC_SOULLINK simplifies code later on.
- status->dbs->Skill2SCTable[SL_ALCHEMIST] = (sc_type)MAPID_ALCHEMIST,
- status->dbs->Skill2SCTable[SL_MONK] = (sc_type)MAPID_MONK,
- status->dbs->Skill2SCTable[SL_STAR] = (sc_type)MAPID_STAR_GLADIATOR,
- status->dbs->Skill2SCTable[SL_SAGE] = (sc_type)MAPID_SAGE,
- status->dbs->Skill2SCTable[SL_CRUSADER] = (sc_type)MAPID_CRUSADER,
- status->dbs->Skill2SCTable[SL_SUPERNOVICE] = (sc_type)MAPID_SUPER_NOVICE,
- status->dbs->Skill2SCTable[SL_KNIGHT] = (sc_type)MAPID_KNIGHT,
- status->dbs->Skill2SCTable[SL_WIZARD] = (sc_type)MAPID_WIZARD,
- status->dbs->Skill2SCTable[SL_PRIEST] = (sc_type)MAPID_PRIEST,
- status->dbs->Skill2SCTable[SL_BARDDANCER] = (sc_type)MAPID_BARDDANCER,
- status->dbs->Skill2SCTable[SL_ROGUE] = (sc_type)MAPID_ROGUE,
- status->dbs->Skill2SCTable[SL_ASSASIN] = (sc_type)MAPID_ASSASSIN,
- status->dbs->Skill2SCTable[SL_BLACKSMITH] = (sc_type)MAPID_BLACKSMITH,
- status->dbs->Skill2SCTable[SL_HUNTER] = (sc_type)MAPID_HUNTER,
- status->dbs->Skill2SCTable[SL_SOULLINKER] = (sc_type)MAPID_SOUL_LINKER,
+ status->dbs->Skill2SCTable[skill->get_index(SL_ALCHEMIST)] = (sc_type)MAPID_ALCHEMIST,
+ status->dbs->Skill2SCTable[skill->get_index(SL_MONK)] = (sc_type)MAPID_MONK,
+ status->dbs->Skill2SCTable[skill->get_index(SL_STAR)] = (sc_type)MAPID_STAR_GLADIATOR,
+ status->dbs->Skill2SCTable[skill->get_index(SL_SAGE)] = (sc_type)MAPID_SAGE,
+ status->dbs->Skill2SCTable[skill->get_index(SL_CRUSADER)] = (sc_type)MAPID_CRUSADER,
+ status->dbs->Skill2SCTable[skill->get_index(SL_SUPERNOVICE)] = (sc_type)MAPID_SUPER_NOVICE,
+ status->dbs->Skill2SCTable[skill->get_index(SL_KNIGHT)] = (sc_type)MAPID_KNIGHT,
+ status->dbs->Skill2SCTable[skill->get_index(SL_WIZARD)] = (sc_type)MAPID_WIZARD,
+ status->dbs->Skill2SCTable[skill->get_index(SL_PRIEST)] = (sc_type)MAPID_PRIEST,
+ status->dbs->Skill2SCTable[skill->get_index(SL_BARDDANCER)] = (sc_type)MAPID_BARDDANCER,
+ status->dbs->Skill2SCTable[skill->get_index(SL_ROGUE)] = (sc_type)MAPID_ROGUE,
+ status->dbs->Skill2SCTable[skill->get_index(SL_ASSASIN)] = (sc_type)MAPID_ASSASSIN,
+ status->dbs->Skill2SCTable[skill->get_index(SL_BLACKSMITH)] = (sc_type)MAPID_BLACKSMITH,
+ status->dbs->Skill2SCTable[skill->get_index(SL_HUNTER)] = (sc_type)MAPID_HUNTER,
+ status->dbs->Skill2SCTable[skill->get_index(SL_SOULLINKER)] = (sc_type)MAPID_SOUL_LINKER,
// Other SC which are not necessarily associated to skills.
status->dbs->ChangeFlagTable[SC_ATTHASTE_POTION1] |= SCB_ASPD;
@@ -865,6 +866,10 @@ static void initChangeTables(void)
status->dbs->ChangeFlagTable[SC_WEDDING] |= SCB_SPEED;
status->dbs->ChangeFlagTable[SC_ARMORPROPERTY] |= SCB_ALL;
status->dbs->ChangeFlagTable[SC_ARMOR_RESIST] |= SCB_ALL;
+ status->dbs->ChangeFlagTable[SC_RESIST_PROPERTY_WATER] |= SCB_ALL;
+ status->dbs->ChangeFlagTable[SC_RESIST_PROPERTY_GROUND] |= SCB_ALL;
+ status->dbs->ChangeFlagTable[SC_RESIST_PROPERTY_FIRE] |= SCB_ALL;
+ status->dbs->ChangeFlagTable[SC_RESIST_PROPERTY_WIND] |= SCB_ALL;
status->dbs->ChangeFlagTable[SC_ATKER_BLOOD] |= SCB_ALL;
status->dbs->ChangeFlagTable[SC_WALKSPEED] |= SCB_SPEED;
status->dbs->ChangeFlagTable[SC_TARGET_BLOOD] |= SCB_ALL;
@@ -884,6 +889,13 @@ static void initChangeTables(void)
status->dbs->ChangeFlagTable[SC_PHI_DEMON] |= SCB_ALL;
status->dbs->ChangeFlagTable[SC_MAGIC_CANDY] |= SCB_MATK | SCB_ALL;
status->dbs->ChangeFlagTable[SC_MYSTICPOWDER] |= SCB_FLEE | SCB_LUK;
+ status->dbs->ChangeFlagTable[SC_POPECOOKIE] |= SCB_BASE | SCB_BATK | SCB_MATK;
+ status->dbs->ChangeFlagTable[SC_VITALIZE_POTION] |= SCB_BATK | SCB_MATK;
+ status->dbs->ChangeFlagTable[SC_SKF_MATK] |= SCB_MATK;
+ status->dbs->ChangeFlagTable[SC_SKF_ATK] |= SCB_BATK;
+ status->dbs->ChangeFlagTable[SC_SKF_ASPD] |= SCB_ASPD;
+ status->dbs->ChangeFlagTable[SC_SKF_CAST] |= SCB_NONE;
+ status->dbs->ChangeFlagTable[SC_ALMIGHTY] |= SCB_BATK | SCB_MATK;
// Cash Items
status->dbs->ChangeFlagTable[SC_FOOD_STR_CASH] |= SCB_STR;
@@ -1189,7 +1201,7 @@ static int status_damage(struct block_list *src, struct block_list *target, int6
if ((sce=sc->data[SC_GRAVITATION]) && sce->val3 == BCT_SELF) {
struct skill_unit_group* sg = skill->id2group(sce->val4);
if (sg) {
- skill->del_unitgroup(sg, ALC_MARK);
+ skill->del_unitgroup(sg);
sce->val4 = 0;
status_change_end(target, SC_GRAVITATION, INVALID_TIMER);
}
@@ -1584,7 +1596,7 @@ static int status_check_skilluse(struct block_list *src, struct block_list *targ
}
if( skill_id ) {
- if (src != NULL && (sd == NULL || sd->skillitem == 0)) {
+ if (src != NULL && (sd == NULL || sd->auto_cast_current.type != AUTOCAST_ITEM)) {
// Items that cast skills using 'itemskill' will not be handled by map_zone_db.
int i;
@@ -1628,7 +1640,7 @@ static int status_check_skilluse(struct block_list *src, struct block_list *targ
if (src != NULL
&& map->getcell(src->m, src, src->x, src->y, CELL_CHKLANDPROTECTOR)
&& !(st->mode&MD_BOSS)
- && (src->type != BL_PC || sd->skillitem != skill_id))
+ && (src->type != BL_PC || sd->auto_cast_current.type != AUTOCAST_ITEM))
return 0;
break;
default:
@@ -1707,7 +1719,7 @@ static int status_check_skilluse(struct block_list *src, struct block_list *targ
return 0; //Can't amp out of Wand of Hermode :/ [Skotlex]
}
- if (skill_id != 0 /* Do not block item-casted skills.*/ && (src->type != BL_PC || sd->skillitem != skill_id)) {
+ if (skill_id != 0 /* Do not block item-casted skills.*/ && (src->type != BL_PC || sd->auto_cast_current.type != AUTOCAST_ITEM)) {
//Skills blocked through status changes...
if (!flag && ( //Blocked only from using the skill (stuff like autospell may still go through
sc->data[SC_SILENCE] ||
@@ -1725,6 +1737,7 @@ static int status_check_skilluse(struct block_list *src, struct block_list *targ
(sc->data[SC_MARIONETTE] && skill_id == CG_MARIONETTE) || //Cannot use marionette if you are being buffed by another
(sc->data[SC_STASIS] && skill->block_check(src, SC_STASIS, skill_id)) ||
(sc->data[SC_KG_KAGEHUMI] && skill->block_check(src, SC_KG_KAGEHUMI, skill_id))
+ || sc->data[SC_ALL_RIDING] != NULL // New mounts can't attack nor use skills in the client; this check makes it cheat-safe. [Ind]
))
return 0;
@@ -1773,8 +1786,6 @@ static int status_check_skilluse(struct block_list *src, struct block_list *targ
} else if ( skill_id != ST_CHASEWALK )
return 0;
}
- if( sc->data[SC_ALL_RIDING] )
- return 0;//New mounts can't attack nor use skills in the client; this check makes it cheat-safe [Ind]
}
if (target == NULL || target == src) //No further checking needed.
@@ -2572,12 +2583,16 @@ static int status_calc_pc_(struct map_session_data *sd, enum e_status_calc_opt o
status->calc_pc_additional(sd, opt);
- if( sd->pd ) { // Pet Bonus
+ if (sd->pd != NULL) { // Pet bonus.
struct pet_data *pd = sd->pd;
- if( pd && pd->petDB && pd->petDB->equip_script && pd->pet.intimate >= battle_config.pet_equip_min_friendly )
- script->run(pd->petDB->equip_script,0,sd->bl.id,0);
- if( pd && pd->pet.intimate > 0 && (!battle_config.pet_equip_required || pd->pet.equip > 0) && pd->state.skillbonus == 1 && pd->bonus )
- pc->bonus(sd,pd->bonus->type, pd->bonus->val);
+
+ if (pd->petDB != NULL && pd->petDB->equip_script != NULL)
+ script->run(pd->petDB->equip_script, 0, sd->bl.id, 0);
+
+ if (pd->pet.intimate > PET_INTIMACY_NONE && pd->state.skillbonus == 1 && pd->bonus != NULL
+ && (battle_config.pet_equip_required == 0 || pd->pet.equip > 0)) {
+ pc->bonus(sd, pd->bonus->type, pd->bonus->val);
+ }
}
//param_bonus now holds card bonuses.
@@ -3018,6 +3033,22 @@ static int status_calc_pc_(struct map_session_data *sd, enum e_status_calc_opt o
sd->subele[ELE_FIRE] += sc->data[SC_ARMOR_RESIST]->val3;
sd->subele[ELE_WIND] += sc->data[SC_ARMOR_RESIST]->val4;
}
+ if (sc->data[SC_RESIST_PROPERTY_WATER] != NULL) { // Coldproof Potion
+ sd->subele[ELE_WATER] += sc->data[SC_RESIST_PROPERTY_WATER]->val1;
+ sd->subele[ELE_WIND] += sc->data[SC_RESIST_PROPERTY_WATER]->val2;
+ }
+ if (sc->data[SC_RESIST_PROPERTY_GROUND] != NULL) { // Earthproof Potion
+ sd->subele[ELE_EARTH] += sc->data[SC_RESIST_PROPERTY_GROUND]->val1;
+ sd->subele[ELE_FIRE] += sc->data[SC_RESIST_PROPERTY_GROUND]->val2;
+ }
+ if (sc->data[SC_RESIST_PROPERTY_FIRE] != NULL) { // Fireproof Potion
+ sd->subele[ELE_FIRE] += sc->data[SC_RESIST_PROPERTY_FIRE]->val1;
+ sd->subele[ELE_WATER] += sc->data[SC_RESIST_PROPERTY_FIRE]->val2;
+ }
+ if (sc->data[SC_RESIST_PROPERTY_WIND] != NULL) { // Thunderproof Potion
+ sd->subele[ELE_WIND] += sc->data[SC_RESIST_PROPERTY_WIND]->val1;
+ sd->subele[ELE_EARTH] += sc->data[SC_RESIST_PROPERTY_WIND]->val2;
+ }
if (sc->data[SC_FIRE_CLOAK_OPTION]) {
i = sc->data[SC_FIRE_CLOAK_OPTION]->val2;
sd->subele[ELE_FIRE] += i;
@@ -3038,6 +3069,18 @@ static int status_calc_pc_(struct map_session_data *sd, enum e_status_calc_opt o
sd->subele[ELE_EARTH] += i;
sd->subele[ELE_FIRE] -= i;
}
+ if (sc->data[SC_POPECOOKIE] != NULL) {
+ i = sc->data[SC_POPECOOKIE]->val3;
+ sd->subele[ELE_WATER] += i;
+ sd->subele[ELE_EARTH] += i;
+ sd->subele[ELE_FIRE] += i;
+ sd->subele[ELE_WIND] += i;
+ sd->subele[ELE_POISON] += i;
+ sd->subele[ELE_HOLY] += i;
+ sd->subele[ELE_DARK] += i;
+ sd->subele[ELE_GHOST] += i;
+ sd->subele[ELE_UNDEAD] += i;
+ }
if (sc->data[SC_MTF_MLEATKED])
sd->subele[ELE_NEUTRAL] += sc->data[SC_MTF_MLEATKED]->val1;
if (sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 3)
@@ -4801,6 +4844,10 @@ static int status_calc_batk(struct block_list *bl, struct status_change *sc, int
/* some statuses that are hidden in the status window */
if(sc->data[SC_PLUSATTACKPOWER])
batk += sc->data[SC_PLUSATTACKPOWER]->val1;
+ if (sc->data[SC_POPECOOKIE] != NULL)
+ batk += batk * sc->data[SC_POPECOOKIE]->val1 / 100;
+ if (sc->data[SC_VITALIZE_POTION] != NULL)
+ batk += batk * sc->data[SC_VITALIZE_POTION]->val1 / 100;
return cap_value(batk, battle_config.batk_min, battle_config.batk_max);
}
#ifndef RENEWAL
@@ -4880,6 +4927,10 @@ static int status_calc_batk(struct block_list *bl, struct status_change *sc, int
batk += batk * sc->data[SC_2011RWC]->val2 / 100;
if (sc->data[SC_STEAMPACK])
batk += sc->data[SC_STEAMPACK]->val1;
+ if (sc->data[SC_SKF_ATK] != NULL)
+ batk += sc->data[SC_SKF_ATK]->val1;
+ if (sc->data[SC_ALMIGHTY] != NULL)
+ batk += sc->data[SC_ALMIGHTY]->val1;
if (sc->data[SC_SHRIMP])
batk += batk * sc->data[SC_SHRIMP]->val2 / 100;
@@ -5020,6 +5071,10 @@ static int status_calc_matk(struct block_list *bl, struct status_change *sc, int
/* some statuses that are hidden in the status window */
if (sc->data[SC_MINDBREAKER])
matk += matk * sc->data[SC_MINDBREAKER]->val2 / 100;
+ if (sc->data[SC_POPECOOKIE] != NULL)
+ matk += matk * sc->data[SC_POPECOOKIE]->val2 / 100;
+ if (sc->data[SC_VITALIZE_POTION] != NULL)
+ matk += matk * sc->data[SC_VITALIZE_POTION]->val2 / 100;
return cap_value(matk, battle_config.matk_min, battle_config.matk_max);
}
@@ -5077,6 +5132,10 @@ static int status_calc_matk(struct block_list *bl, struct status_change *sc, int
matk += matk * sc->data[SC_2011RWC]->val2 / 100;
if (sc->data[SC_MAGIC_CANDY])
matk += sc->data[SC_MAGIC_CANDY]->val1;
+ if (sc->data[SC_SKF_MATK] != NULL)
+ matk += sc->data[SC_SKF_MATK]->val1;
+ if (sc->data[SC_ALMIGHTY] != NULL)
+ matk += sc->data[SC_ALMIGHTY]->val2;
return cap_value(matk, battle_config.matk_min, battle_config.matk_max);
}
@@ -5901,6 +5960,8 @@ static short status_calc_aspd(struct block_list *bl, struct status_change *sc, s
bonus += sc->data[SC_BATTLESCROLL]->val1;
if (sc->data[SC_STEAMPACK])
bonus += sc->data[SC_STEAMPACK]->val2;
+ if (sc->data[SC_SKF_ASPD] != NULL)
+ bonus += sc->data[SC_SKF_ASPD]->val1;
}
return (bonus + pots);
@@ -6068,6 +6129,8 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change *
aspd_rate += sc->data[SC_BATTLESCROLL]->val1 * 10;
if (sc->data[SC_STEAMPACK])
aspd_rate += sc->data[SC_STEAMPACK]->val2 * 10;
+ if (sc->data[SC_SKF_ASPD] != NULL)
+ aspd_rate -= sc->data[SC_SKF_ASPD]->val1 * 10;
return (short)cap_value(aspd_rate,0,SHRT_MAX);
}
@@ -6344,13 +6407,24 @@ static int status_get_class(const struct block_list *bl)
{
nullpo_ret(bl);
switch (bl->type) {
- case BL_PC: return BL_UCCAST(BL_PC, bl)->status.class;
- case BL_MOB: return BL_UCCAST(BL_MOB, bl)->vd->class; //Class used on all code should be the view class of the mob.
- case BL_PET: return BL_UCCAST(BL_PET, bl)->pet.class_;
- case BL_HOM: return BL_UCCAST(BL_HOM, bl)->homunculus.class_;
- case BL_MER: return BL_UCCAST(BL_MER, bl)->mercenary.class_;
- case BL_NPC: return BL_UCCAST(BL_NPC, bl)->class_;
- case BL_ELEM: return BL_UCCAST(BL_ELEM, bl)->elemental.class_;
+ case BL_PC:
+ return BL_UCCAST(BL_PC, bl)->status.class;
+ case BL_MOB:
+ {
+ const struct view_data *const vd = BL_UCCAST(BL_MOB, bl)->vd;
+ nullpo_ret(vd);
+ return vd->class; //Class used on all code should be the view class of the mob.
+ }
+ case BL_PET:
+ return BL_UCCAST(BL_PET, bl)->pet.class_;
+ case BL_HOM:
+ return BL_UCCAST(BL_HOM, bl)->homunculus.class_;
+ case BL_MER:
+ return BL_UCCAST(BL_MER, bl)->mercenary.class_;
+ case BL_NPC:
+ return BL_UCCAST(BL_NPC, bl)->class_;
+ case BL_ELEM:
+ return BL_UCCAST(BL_ELEM, bl)->elemental.class_;
}
return 0;
}
@@ -6440,7 +6514,7 @@ static defType status_get_def(struct block_list *bl)
int def = st ? st->def : 0;
ud = unit->bl2ud(bl);
if (ud && ud->skilltimer != INVALID_TIMER)
- def -= def * skill->get_castdef(ud->skill_id)/100;
+ def -= def * skill->get_castdef(ud->skill_id, ud->skill_lv) / 100;
return cap_value(def, DEFTYPE_MIN, DEFTYPE_MAX);
}
@@ -7710,6 +7784,10 @@ static int status_change_start_sub(struct block_list *src, struct block_list *bl
case SC_ENCHANTARMS:
case SC_ARMORPROPERTY:
case SC_ARMOR_RESIST:
+ case SC_RESIST_PROPERTY_WATER:
+ case SC_RESIST_PROPERTY_GROUND:
+ case SC_RESIST_PROPERTY_FIRE:
+ case SC_RESIST_PROPERTY_WIND:
break;
case SC_GOSPEL:
//Must not override a casting gospel char.
@@ -7765,6 +7843,9 @@ static int status_change_start_sub(struct block_list *src, struct block_list *bl
calc_flag = status->dbs->ChangeFlagTable[type];
if(!(flag&SCFLAG_LOADED)) { // Do not parse val settings when loading SCs
switch(type) {
+ case SC_AUTOTRADE:
+ case SC_KSPROTECTED:
+ break; // Prevent calling status_change_start_unknown_sc().
case SC_ADORAMUS:
sc_start(src,bl,SC_BLIND,100,val1,skill->get_time(status->sc2skill(type),val1));
// Fall through to SC_INC_AGI
@@ -8009,7 +8090,6 @@ static int status_change_start_sub(struct block_list *src, struct block_list *bl
// This is done this way because the message that the client displays is hardcoded, and only
// shows how many minutes are remaining. [Panikon]
total_tick = 60000;
- val1 = battle_config.manner_system; //Mute filters.
if (sd)
{
clif->changestatus(sd,SP_MANNER,sd->status.manner);
@@ -8656,6 +8736,210 @@ static int status_change_start_sub(struct block_list *src, struct block_list *bl
//associated, and yet are not wrong/unknown. [Skotlex]
//break;
}
+ case SC_ARMOR_RESIST: {
+ struct status_change_entry *sce_water = sc->data[SC_RESIST_PROPERTY_WATER];
+ struct status_change_entry *sce_ground = sc->data[SC_RESIST_PROPERTY_GROUND];
+ struct status_change_entry *sce_fire = sc->data[SC_RESIST_PROPERTY_FIRE];
+ struct status_change_entry *sce_wind = sc->data[SC_RESIST_PROPERTY_WIND];
+
+ // Water
+ int sum_water = val1 + ((sce_fire != NULL) ? sce_fire->val2 : 0);
+ bool show_icon = true;
+ if (sce_water != NULL && sce_water->timer != INVALID_TIMER) {
+ const struct TimerData *td = timer->get(sce_water->timer);
+ if (td != NULL) {
+ sum_water += sce_water->val1;
+ int left = (int)DIFF_TICK(td->tick, timer->gettick());
+ if (left > total_tick && sum_water - val1 > 0)
+ show_icon = false;
+ }
+ }
+ if (val1 > 0 && sum_water > 0 && show_icon) {
+ int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_WATER);
+ int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_WATER);
+ clif->status_change(bl, sc_icn, sc_typ, 1, total_tick, 0, 0, 0);
+ } else if (sum_water <= 0) {
+ clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_WATER));
+ }
+
+ // Ground
+ int sum_ground = val2 + ((sce_wind != NULL) ? sce_wind->val2 : 0);
+ show_icon = true;
+ if (sce_ground != NULL && sce_ground->timer != INVALID_TIMER) {
+ const struct TimerData *td = timer->get(sce_ground->timer);
+ if (td != NULL) {
+ sum_ground += sce_ground->val1;
+ int left = (int)DIFF_TICK(td->tick, timer->gettick());
+ if (left > total_tick && sum_ground - val2 > 0)
+ show_icon = false;
+ }
+ }
+ if (val2 > 0 && sum_ground > 0 && show_icon) {
+ int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_GROUND);
+ int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_GROUND);
+ clif->status_change(bl, sc_icn, sc_typ, 1, total_tick, 0, 0, 0);
+ } else if (sum_ground <= 0) {
+ clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_GROUND));
+ }
+
+ // Fire
+ int sum_fire = val3 + ((sce_ground != NULL) ? sce_ground->val2 : 0);
+ show_icon = true;
+ if (sce_fire != NULL && sce_fire->timer != INVALID_TIMER) {
+ const struct TimerData *td = timer->get(sce_fire->timer);
+ if (td != NULL) {
+ sum_fire += sce_fire->val1;
+ int left = (int)DIFF_TICK(td->tick, timer->gettick());
+ if (left > total_tick && sum_fire - val3 > 0)
+ show_icon = false;
+ }
+ }
+ if (val3 > 0 && sum_fire > 0 && show_icon) {
+ int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_FIRE);
+ int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_FIRE);
+ clif->status_change(bl, sc_icn, sc_typ, 1, total_tick, 0, 0, 0);
+ } else if (sum_fire <= 0) {
+ clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_FIRE));
+ }
+
+ // Wind
+ int sum_wind = val4 + ((sce_water != NULL) ? sce_water->val2 : 0);
+ show_icon = true;
+ if (sce_wind != NULL && sce_wind->timer != INVALID_TIMER) {
+ const struct TimerData *td = timer->get(sce_wind->timer);
+ if (td != NULL) {
+ sum_wind += sce_wind->val1;
+ int left = (int)DIFF_TICK(td->tick, timer->gettick());
+ if (left > total_tick && sum_wind - val4 > 0)
+ show_icon = false;
+ }
+ }
+ if (val4 > 0 && sum_wind > 0 && show_icon) {
+ int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_WIND);
+ int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_WIND);
+ clif->status_change(bl, sc_icn, sc_typ, 1, total_tick, 0, 0, 0);
+ } else if (sum_wind <= 0) {
+ clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_WIND));
+ }
+
+ break;
+ }
+ case SC_RESIST_PROPERTY_WATER: {
+ struct status_change_entry *sce_all = sc->data[SC_ARMOR_RESIST];
+ struct status_change_entry *sce_fire = sc->data[SC_RESIST_PROPERTY_FIRE];
+ struct status_change_entry *sce_wind = sc->data[SC_RESIST_PROPERTY_WIND];
+
+ // Water
+ int sum_water = val1 + ((sce_fire != NULL) ? sce_fire->val2 : 0);
+ if (sce_all != NULL && sce_all->timer != INVALID_TIMER) {
+ const struct TimerData *td = timer->get(sce_all->timer);
+ if (td != NULL) {
+ sum_water += sce_all->val1;
+ int left = (int)DIFF_TICK(td->tick, timer->gettick());
+ if (left > total_tick && sum_water - val1 > 0)
+ flag |= SCFLAG_NOICON;
+ }
+ }
+ if (sum_water <= 0) {
+ clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_WATER));
+ flag |= SCFLAG_NOICON;
+ }
+
+ // Wind
+ int sum_wind = val2 + ((sce_wind != NULL) ? sce_wind->val1 : 0);
+ sum_wind += (sce_all != NULL) ? sce_all->val4 : 0;
+ if (sum_wind <= 0)
+ clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_WIND));
+
+ break;
+ }
+ case SC_RESIST_PROPERTY_GROUND: {
+ struct status_change_entry *sce_all = sc->data[SC_ARMOR_RESIST];
+ struct status_change_entry *sce_wind = sc->data[SC_RESIST_PROPERTY_WIND];
+ struct status_change_entry *sce_fire = sc->data[SC_RESIST_PROPERTY_FIRE];
+
+ // Ground
+ int sum_ground = val1 + ((sce_wind != NULL) ? sce_wind->val2 : 0);
+ if (sce_all != NULL && sce_all->timer != INVALID_TIMER) {
+ const struct TimerData *td = timer->get(sce_all->timer);
+ if (td != NULL) {
+ sum_ground += sce_all->val2;
+ int left = (int)DIFF_TICK(td->tick, timer->gettick());
+ if (left > total_tick && sum_ground - val1 > 0)
+ flag |= SCFLAG_NOICON;
+ }
+ }
+ if (sum_ground <= 0) {
+ clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_GROUND));
+ flag |= SCFLAG_NOICON;
+ }
+
+ // Fire
+ int sum_fire = val2 + ((sce_fire != NULL) ? sce_fire->val1 : 0);
+ sum_fire += (sce_all != NULL) ? sce_all->val3 : 0;
+ if (sum_fire <= 0)
+ clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_FIRE));
+
+ break;
+ }
+ case SC_RESIST_PROPERTY_FIRE: {
+ struct status_change_entry *sce_all = sc->data[SC_ARMOR_RESIST];
+ struct status_change_entry *sce_ground = sc->data[SC_RESIST_PROPERTY_GROUND];
+ struct status_change_entry *sce_water = sc->data[SC_RESIST_PROPERTY_WATER];
+
+ // Fire
+ int sum_fire = val1 + ((sce_ground != NULL) ? sce_ground->val2 : 0);
+ if (sce_all != NULL && sce_all->timer != INVALID_TIMER) {
+ const struct TimerData *td = timer->get(sce_all->timer);
+ if (td != NULL) {
+ sum_fire += sce_all->val3;
+ int left = (int)DIFF_TICK(td->tick, timer->gettick());
+ if (left > total_tick && sum_fire - val1 > 0)
+ flag |= SCFLAG_NOICON;
+ }
+ }
+ if (sum_fire <= 0) {
+ clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_FIRE));
+ flag |= SCFLAG_NOICON;
+ }
+
+ // Water
+ int sum_water = val2 + ((sce_water != NULL) ? sce_water->val1 : 0);
+ sum_water += (sce_all != NULL) ? sce_all->val1 : 0;
+ if (sum_water <= 0)
+ clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_WATER));
+
+ break;
+ }
+ case SC_RESIST_PROPERTY_WIND: {
+ struct status_change_entry *sce_all = sc->data[SC_ARMOR_RESIST];
+ struct status_change_entry *sce_water = sc->data[SC_RESIST_PROPERTY_WATER];
+ struct status_change_entry *sce_ground = sc->data[SC_RESIST_PROPERTY_GROUND];
+
+ // Wind
+ int sum_wind = val1 + ((sce_water != NULL) ? sce_water->val2 : 0);
+ if (sce_all != NULL && sce_all->timer != INVALID_TIMER) {
+ const struct TimerData *td = timer->get(sce_all->timer);
+ if (td != NULL) {
+ sum_wind += sce_all->val4;
+ int left = (int)DIFF_TICK(td->tick, timer->gettick());
+ if (left > total_tick && sum_wind - val1 > 0)
+ flag |= SCFLAG_NOICON;
+ }
+ }
+ if (sum_wind <= 0) {
+ clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_WIND));
+ flag |= SCFLAG_NOICON;
+ }
+
+ // Ground
+ int sum_ground = val2 + ((sce_ground != NULL) ? sce_ground->val1 : 0);
+ sum_ground += (sce_all != NULL) ? sce_all->val2 : 0;
+ if (sum_ground <= 0)
+ clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_GROUND));
+
+ break;
+ }
case SC_MER_FLEE:
case SC_MER_ATK:
case SC_MER_HIT:
@@ -10514,7 +10798,7 @@ static int status_change_clear(struct block_list *bl, int type)
/*==========================================
* Special condition we want to effectuate, check before ending a status.
*------------------------------------------*/
-static int status_change_end_(struct block_list *bl, enum sc_type type, int tid, const char *file, int line)
+static int status_change_end_(struct block_list *bl, enum sc_type type, int tid)
{
struct map_session_data *sd;
struct status_change *sc;
@@ -10582,6 +10866,9 @@ static int status_change_end_(struct block_list *bl, enum sc_type type, int tid,
vd = status->get_viewdata(bl);
calc_flag = status->dbs->ChangeFlagTable[type];
+
+ bool remove_icon = true;
+
switch(type) {
case SC_GRANITIC_ARMOR:
{
@@ -10681,23 +10968,9 @@ static int status_change_end_(struct block_list *bl, enum sc_type type, int tid,
break;
case SC_DANCING:
{
- const char* prevfile = "<unknown>";
- int prevline = 0;
struct map_session_data *dsd;
struct status_change_entry *dsc;
- if (sd) {
- if (sd->delunit_prevfile) {
- // initially this is NULL, when a character logs in
- prevfile = sd->delunit_prevfile;
- prevline = sd->delunit_prevline;
- } else {
- prevfile = "<none>";
- }
- sd->delunit_prevfile = file;
- sd->delunit_prevline = line;
- }
-
if (sce->val4 && sce->val4 != BCT_SELF && (dsd=map->id2sd(sce->val4)) != NULL) {
// end status on partner as well
dsc = dsd->sc.data[SC_DANCING];
@@ -10713,19 +10986,10 @@ static int status_change_end_(struct block_list *bl, enum sc_type type, int tid,
// erase associated land skill
struct skill_unit_group *group = skill->id2group(sce->val2);
- if (group == NULL) {
- ShowDebug("status_change_end: SC_DANCING is missing skill unit group (val1=%d, val2=%d, val3=%d, val4=%d, timer=%d, tid=%d, char_id=%d, map=%s, x=%d, y=%d, prev=%s:%d, from=%s:%d). Please report this! (#3504)\n",
- sce->val1, sce->val2, sce->val3, sce->val4, sce->timer, tid,
- sd ? sd->status.char_id : 0,
- mapindex_id2name(map_id2index(bl->m)), bl->x, bl->y,
- prevfile, prevline,
- file, line);
- }
-
sce->val2 = 0;
if( group )
- skill->del_unitgroup(group,ALC_MARK);
+ skill->del_unitgroup(group);
}
if ((sce->val1&0xFFFF) == CG_MOONLIT)
@@ -10829,7 +11093,7 @@ static int status_change_end_(struct block_list *bl, enum sc_type type, int tid,
struct skill_unit_group* group = skill->id2group(sce->val3);
sce->val3 = 0;
if( group )
- skill->del_unitgroup(group,ALC_MARK);
+ skill->del_unitgroup(group);
}
break;
case SC_HERMODE:
@@ -10848,7 +11112,7 @@ static int status_change_end_(struct block_list *bl, enum sc_type type, int tid,
struct skill_unit_group* group = skill->id2group(sce->val4);
sce->val4 = 0;
if( group ) /* might have been cleared before status ended, e.g. land protector */
- skill->del_unitgroup(group,ALC_MARK);
+ skill->del_unitgroup(group);
}
break;
case SC_KAAHI:
@@ -10946,7 +11210,7 @@ static int status_change_end_(struct block_list *bl, enum sc_type type, int tid,
struct skill_unit_group* group = skill->id2group(sce->val2);
sce->val2 = 0;
if (group) /* might have been cleared before status ended, e.g. land protector */
- skill->del_unitgroup(group,ALC_MARK);
+ skill->del_unitgroup(group);
}
break;
case SC_BANDING:
@@ -10954,7 +11218,7 @@ static int status_change_end_(struct block_list *bl, enum sc_type type, int tid,
struct skill_unit_group *group = skill->id2group(sce->val4);
sce->val4 = 0;
if( group ) /* might have been cleared before status ended, e.g. land protector */
- skill->del_unitgroup(group,ALC_MARK);
+ skill->del_unitgroup(group);
}
break;
case SC_CURSEDCIRCLE_ATKER:
@@ -11013,6 +11277,202 @@ static int status_change_end_(struct block_list *bl, enum sc_type type, int tid,
break;
}
break;
+ case SC_ARMOR_RESIST: {
+ struct status_change_entry *sce_water = sc->data[SC_RESIST_PROPERTY_WATER];
+ struct status_change_entry *sce_ground = sc->data[SC_RESIST_PROPERTY_GROUND];
+ struct status_change_entry *sce_fire = sc->data[SC_RESIST_PROPERTY_FIRE];
+ struct status_change_entry *sce_wind = sc->data[SC_RESIST_PROPERTY_WIND];
+
+ // Water
+ clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_WATER));
+ if (sce_water != NULL && sce_water->timer != INVALID_TIMER) {
+ int sum_water = sce_water->val1 + ((sce_fire != NULL) ? sce_fire->val2 : 0);
+ const struct TimerData *td = timer->get(sce_water->timer);
+ if (td != NULL && sce_water->val1 > 0 && sum_water > 0) {
+ int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_WATER);
+ int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_WATER);
+ int sc_tck = (int)DIFF_TICK(td->tick, timer->gettick());
+ int sc_ttl = sce_water->total_tick;
+ clif->status_change_sub(bl, sc_icn, sc_typ, 1, sc_tck, sc_ttl, 0, 0, 0);
+ }
+ }
+
+ // Ground
+ clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_GROUND));
+ if (sce_ground != NULL && sce_ground->timer != INVALID_TIMER) {
+ int sum_ground = sce_ground->val1 + ((sce_wind != NULL) ? sce_wind->val2 : 0);
+ const struct TimerData *td = timer->get(sce_ground->timer);
+ if (td != NULL && sce_ground->val1 > 0 && sum_ground > 0) {
+ int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_GROUND);
+ int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_GROUND);
+ int sc_tck = (int)DIFF_TICK(td->tick, timer->gettick());
+ int sc_ttl = sce_ground->total_tick;
+ clif->status_change_sub(bl, sc_icn, sc_typ, 1, sc_tck, sc_ttl, 0, 0, 0);
+ }
+ }
+
+ // Fire
+ clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_FIRE));
+ if (sce_fire != NULL && sce_fire->timer != INVALID_TIMER) {
+ int sum_fire = sce_fire->val1 + ((sce_ground != NULL) ? sce_ground->val2 : 0);
+ const struct TimerData *td = timer->get(sce_fire->timer);
+ if (td != NULL && sce_fire->val1 > 0 && sum_fire > 0) {
+ int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_FIRE);
+ int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_FIRE);
+ int sc_tck = (int)DIFF_TICK(td->tick, timer->gettick());
+ int sc_ttl = sce_fire->total_tick;
+ clif->status_change_sub(bl, sc_icn, sc_typ, 1, sc_tck, sc_ttl, 0, 0, 0);
+ }
+ }
+
+ // Wind
+ clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_WIND));
+ if (sce_wind != NULL && sce_wind->timer != INVALID_TIMER) {
+ int sum_wind = sce_wind->val1 + ((sce_water != NULL) ? sce_water->val2 : 0);
+ const struct TimerData *td = timer->get(sce_wind->timer);
+ if (td != NULL && sce_wind->val1 > 0 && sum_wind > 0) {
+ int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_WIND);
+ int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_WIND);
+ int sc_tck = (int)DIFF_TICK(td->tick, timer->gettick());
+ int sc_ttl = sce_wind->total_tick;
+ clif->status_change_sub(bl, sc_icn, sc_typ, 1, sc_tck, sc_ttl, 0, 0, 0);
+ }
+ }
+
+ break;
+ }
+ case SC_RESIST_PROPERTY_WATER:
+ if (sc->data[SC_ARMOR_RESIST] != NULL && sc->data[SC_ARMOR_RESIST]->timer != INVALID_TIMER) {
+ const struct TimerData *td = timer->get(sc->data[SC_ARMOR_RESIST]->timer);
+ if (td == NULL)
+ break;
+
+ // Water
+ int sum_water = sc->data[SC_ARMOR_RESIST]->val1;
+ if (sc->data[SC_RESIST_PROPERTY_FIRE] != NULL)
+ sum_water += sc->data[SC_RESIST_PROPERTY_FIRE]->val2;
+ if (sc->data[SC_ARMOR_RESIST]->val1 > 0 && sum_water > 0) {
+ int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_WATER);
+ int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_WATER);
+ int sc_tck = (int)DIFF_TICK(td->tick, timer->gettick());
+ int sc_ttl = sc->data[SC_ARMOR_RESIST]->total_tick;
+ clif->status_change_sub(bl, sc_icn, sc_typ, 1, sc_tck, sc_ttl, 0, 0, 0);
+ remove_icon = false;
+ }
+
+ // Wind
+ int sum_wind = sc->data[SC_ARMOR_RESIST]->val4;
+ if (sc->data[SC_RESIST_PROPERTY_WIND] != NULL)
+ sum_wind += sc->data[SC_RESIST_PROPERTY_WIND]->val1;
+ if (sc->data[SC_ARMOR_RESIST]->val4 > 0 && sum_wind > 0) {
+ int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_WIND);
+ int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_WIND);
+ int sc_tck = (int)DIFF_TICK(td->tick, timer->gettick());
+ int sc_ttl = sc->data[SC_ARMOR_RESIST]->total_tick;
+ clif->status_change_sub(bl, sc_icn, sc_typ, 1, sc_tck, sc_ttl, 0, 0, 0);
+ }
+ }
+
+ break;
+ case SC_RESIST_PROPERTY_GROUND:
+ if (sc->data[SC_ARMOR_RESIST] != NULL && sc->data[SC_ARMOR_RESIST]->timer != INVALID_TIMER) {
+ const struct TimerData *td = timer->get(sc->data[SC_ARMOR_RESIST]->timer);
+ if (td == NULL)
+ break;
+
+ // Ground
+ int sum_ground = sc->data[SC_ARMOR_RESIST]->val2;
+ if (sc->data[SC_RESIST_PROPERTY_WIND] != NULL)
+ sum_ground += sc->data[SC_RESIST_PROPERTY_WIND]->val2;
+ if (sc->data[SC_ARMOR_RESIST]->val2 > 0 && sum_ground > 0) {
+ int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_GROUND);
+ int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_GROUND);
+ int sc_tck = (int)DIFF_TICK(td->tick, timer->gettick());
+ int sc_ttl = sc->data[SC_ARMOR_RESIST]->total_tick;
+ clif->status_change_sub(bl, sc_icn, sc_typ, 1, sc_tck, sc_ttl, 0, 0, 0);
+ remove_icon = false;
+ }
+
+ // Fire
+ int sum_fire = sc->data[SC_ARMOR_RESIST]->val3;
+ if (sc->data[SC_RESIST_PROPERTY_FIRE] != NULL)
+ sum_fire += sc->data[SC_RESIST_PROPERTY_FIRE]->val1;
+ if (sc->data[SC_ARMOR_RESIST]->val3 > 0 && sum_fire > 0) {
+ int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_FIRE);
+ int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_FIRE);
+ int sc_tck = (int)DIFF_TICK(td->tick, timer->gettick());
+ int sc_ttl = sc->data[SC_ARMOR_RESIST]->total_tick;
+ clif->status_change_sub(bl, sc_icn, sc_typ, 1, sc_tck, sc_ttl, 0, 0, 0);
+ }
+ }
+
+ break;
+ case SC_RESIST_PROPERTY_FIRE:
+ if (sc->data[SC_ARMOR_RESIST] != NULL && sc->data[SC_ARMOR_RESIST]->timer != INVALID_TIMER) {
+ const struct TimerData *td = timer->get(sc->data[SC_ARMOR_RESIST]->timer);
+ if (td == NULL)
+ break;
+
+ // Fire
+ int sum_fire = sc->data[SC_ARMOR_RESIST]->val3;
+ if (sc->data[SC_RESIST_PROPERTY_GROUND] != NULL)
+ sum_fire += sc->data[SC_RESIST_PROPERTY_GROUND]->val2;
+ if (sc->data[SC_ARMOR_RESIST]->val3 > 0 && sum_fire > 0) {
+ int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_FIRE);
+ int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_FIRE);
+ int sc_tck = (int)DIFF_TICK(td->tick, timer->gettick());
+ int sc_ttl = sc->data[SC_ARMOR_RESIST]->total_tick;
+ clif->status_change_sub(bl, sc_icn, sc_typ, 1, sc_tck, sc_ttl, 0, 0, 0);
+ remove_icon = false;
+ }
+
+ // Water
+ int sum_water = sc->data[SC_ARMOR_RESIST]->val1;
+ if (sc->data[SC_RESIST_PROPERTY_WATER] != NULL)
+ sum_water += sc->data[SC_RESIST_PROPERTY_WATER]->val1;
+ if (sc->data[SC_ARMOR_RESIST]->val1 > 0 && sum_water > 0) {
+ int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_WATER);
+ int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_WATER);
+ int sc_tck = (int)DIFF_TICK(td->tick, timer->gettick());
+ int sc_ttl = sc->data[SC_ARMOR_RESIST]->total_tick;
+ clif->status_change_sub(bl, sc_icn, sc_typ, 1, sc_tck, sc_ttl, 0, 0, 0);
+ }
+ }
+
+ break;
+ case SC_RESIST_PROPERTY_WIND:
+ if (sc->data[SC_ARMOR_RESIST] != NULL && sc->data[SC_ARMOR_RESIST]->timer != INVALID_TIMER) {
+ const struct TimerData *td = timer->get(sc->data[SC_ARMOR_RESIST]->timer);
+ if (td == NULL)
+ break;
+
+ // Wind
+ int sum_wind = sc->data[SC_ARMOR_RESIST]->val4;
+ if (sc->data[SC_RESIST_PROPERTY_WATER] != NULL)
+ sum_wind += sc->data[SC_RESIST_PROPERTY_WATER]->val2;
+ if (sc->data[SC_ARMOR_RESIST]->val4 > 0 && sum_wind > 0) {
+ int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_WIND);
+ int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_WIND);
+ int sc_tck = (int)DIFF_TICK(td->tick, timer->gettick());
+ int sc_ttl = sc->data[SC_ARMOR_RESIST]->total_tick;
+ clif->status_change_sub(bl, sc_icn, sc_typ, 1, sc_tck, sc_ttl, 0, 0, 0);
+ remove_icon = false;
+ }
+
+ // Ground
+ int sum_ground = sc->data[SC_ARMOR_RESIST]->val2;
+ if (sc->data[SC_RESIST_PROPERTY_GROUND] != NULL)
+ sum_ground += sc->data[SC_RESIST_PROPERTY_GROUND]->val1;
+ if (sc->data[SC_ARMOR_RESIST]->val2 > 0 && sum_ground > 0) {
+ int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_GROUND);
+ int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_GROUND);
+ int sc_tck = (int)DIFF_TICK(td->tick, timer->gettick());
+ int sc_ttl = sc->data[SC_ARMOR_RESIST]->total_tick;
+ clif->status_change_sub(bl, sc_icn, sc_typ, 1, sc_tck, sc_ttl, 0, 0, 0);
+ }
+ }
+
+ break;
}
opt_flag = 1;
@@ -11226,7 +11686,8 @@ static int status_change_end_(struct block_list *bl, enum sc_type type, int tid,
#endif
//On Aegis, when turning off a status change, first goes the sc packet, then the option packet.
- clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(type));
+ if (remove_icon)
+ clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(type));
if( opt_flag&8 ) //bugreport:681
clif->changeoption2(bl);