Skip to content

Commit

Permalink
Removed Freezing and Crystalize from OPT1
Browse files Browse the repository at this point in the history
* Fixes #1955.
* Freezing and Crystalize are no longer considered Body Status Changes (OPT1).
* They are now stackable with other non-OPT1 statuses.
* Crystalize now works on monsters.
* Crystalize no longer has a Wind element damage bonus.
* Targets under Crystalize and Deep Sleep no can no longer consume items.
* Targets under Stun and White Imprison can no longer be affected by OPT1 statuses.
* Freezing no longer removes Burning.
Thanks to @FrFrMako, @Playtester, and Fyrus!
  • Loading branch information
aleos89 committed Feb 10, 2017
1 parent ce1429d commit ca051d1
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 34 deletions.
4 changes: 1 addition & 3 deletions src/map/battle.c
Expand Up @@ -493,7 +493,7 @@ int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 d
}
if (tsc->data[SC_THORNSTRAP] && battle_getcurrentskill(src) != GN_CARTCANNON)
status_change_end(target, SC_THORNSTRAP, INVALID_TIMER);
if (tsc->data[SC_CRYSTALIZE] && target->type != BL_MOB)
if (tsc->data[SC_CRYSTALIZE])
status_change_end(target, SC_CRYSTALIZE, INVALID_TIMER);
if (tsc->data[SC_EARTH_INSIGNIA])
ratio += 50;
Expand All @@ -507,8 +507,6 @@ int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 d
ratio += tsc->data[SC_VENOMIMPRESS]->val2;
break;
case ELE_WIND:
if (tsc->data[SC_CRYSTALIZE] && target->type != BL_MOB)
ratio += 50;
if (tsc->data[SC_WATER_INSIGNIA])
ratio += 50;
break;
Expand Down
2 changes: 1 addition & 1 deletion src/map/mob.c
Expand Up @@ -1613,7 +1613,7 @@ static bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick)
return false;

// Abnormalities
if(( md->sc.opt1 > 0 && md->sc.opt1 != OPT1_STONEWAIT && md->sc.opt1 != OPT1_BURNING && md->sc.opt1 != OPT1_CRYSTALIZE )
if(( md->sc.opt1 > 0 && md->sc.opt1 != OPT1_STONEWAIT && md->sc.opt1 != OPT1_BURNING )
|| md->sc.data[SC_BLADESTOP] || md->sc.data[SC__MANHOLE] || md->sc.data[SC_CURSEDCIRCLE_TARGET]) {//Should reset targets.
md->target_id = md->attacked_id = md->norm_attacked_id = 0;
return false;
Expand Down
4 changes: 3 additions & 1 deletion src/map/pc.c
Expand Up @@ -4861,6 +4861,8 @@ bool pc_isUseitem(struct map_session_data *sd,int n)
sd->sc.data[SC__SHADOWFORM] ||
sd->sc.data[SC__INVISIBILITY] ||
sd->sc.data[SC__MANHOLE] ||
sd->sc.data[SC_DEEPSLEEP] ||
sd->sc.data[SC_CRYSTALIZE] ||
sd->sc.data[SC_KAGEHUMI] ||
(sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOITEM) ||
sd->sc.data[SC_HEAT_BARREL_AFTER] ||
Expand Down Expand Up @@ -5223,7 +5225,7 @@ int pc_steal_item(struct map_session_data *sd,struct block_list *bl, uint16 skil

md = (TBL_MOB *)bl;

if(md->state.steal_flag == UCHAR_MAX || ( md->sc.opt1 && md->sc.opt1 != OPT1_BURNING && md->sc.opt1 != OPT1_CRYSTALIZE ) ) //already stolen from / status change check
if(md->state.steal_flag == UCHAR_MAX || ( md->sc.opt1 && md->sc.opt1 != OPT1_BURNING ) ) //already stolen from / status change check
return 0;

sd_status= status_get_status_data(&sd->bl);
Expand Down
45 changes: 19 additions & 26 deletions src/map/status.c
Expand Up @@ -1339,14 +1339,15 @@ void initChangeTables(void)
StatusChangeStateTable[SC_MADNESSCANCEL] |= SCS_NOMOVE;
StatusChangeStateTable[SC_GRAVITATION] |= SCS_NOMOVE|SCS_NOMOVECOND;
StatusChangeStateTable[SC_WHITEIMPRISON] |= SCS_NOMOVE;
StatusChangeStateTable[SC_DEEPSLEEP] |= SCS_NOMOVE;
StatusChangeStateTable[SC_ELECTRICSHOCKER] |= SCS_NOMOVE;
StatusChangeStateTable[SC_BITE] |= SCS_NOMOVE;
StatusChangeStateTable[SC_THORNSTRAP] |= SCS_NOMOVE;
StatusChangeStateTable[SC_MAGNETICFIELD] |= SCS_NOMOVE;
StatusChangeStateTable[SC__MANHOLE] |= SCS_NOMOVE;
StatusChangeStateTable[SC_CURSEDCIRCLE_ATKER] |= SCS_NOMOVE;
StatusChangeStateTable[SC_CURSEDCIRCLE_TARGET] |= SCS_NOMOVE;
StatusChangeStateTable[SC_CRYSTALIZE] |= SCS_NOMOVE|SCS_NOMOVECOND;
StatusChangeStateTable[SC_CRYSTALIZE] |= SCS_NOMOVE;
StatusChangeStateTable[SC_NETHERWORLD] |= SCS_NOMOVE;
StatusChangeStateTable[SC_CAMOUFLAGE] |= SCS_NOMOVE|SCS_NOMOVECOND;
StatusChangeStateTable[SC_MEIKYOUSISUI] |= SCS_NOMOVE;
Expand Down Expand Up @@ -1382,7 +1383,7 @@ void initChangeTables(void)
StatusChangeStateTable[SC_WHITEIMPRISON] |= SCS_NOCAST;
StatusChangeStateTable[SC__SHADOWFORM] |= SCS_NOCAST;
StatusChangeStateTable[SC__INVISIBILITY] |= SCS_NOCAST;
StatusChangeStateTable[SC_CRYSTALIZE] |= SCS_NOCAST|SCS_NOCASTCOND;
StatusChangeStateTable[SC_CRYSTALIZE] |= SCS_NOCAST;
StatusChangeStateTable[SC__IGNORANCE] |= SCS_NOCAST;
StatusChangeStateTable[SC__MANHOLE] |= SCS_NOCAST;
StatusChangeStateTable[SC_DEEPSLEEP] |= SCS_NOCAST;
Expand Down Expand Up @@ -2024,8 +2025,6 @@ bool status_check_skilluse(struct block_list *src, struct block_list *target, ui
// on dead characters, said checks are left to skill.c [Skotlex]
if (target && status_isdead(target))
return false;
if( src && (sc = status_get_sc(src)) && sc->data[SC_CRYSTALIZE] && src->type != BL_MOB)
return false;
}

switch( skill_id ) {
Expand Down Expand Up @@ -2076,7 +2075,7 @@ bool status_check_skilluse(struct block_list *src, struct block_list *target, ui
if (flag == 1 && sc->data[SC_CURSEDCIRCLE_TARGET] && skill_id == MO_ABSORBSPIRITS) // Absorb Spirits fails to go through
return false;

if (skill_id != RK_REFRESH && sc->opt1 && !(sc->opt1 == OPT1_CRYSTALIZE && src->type == BL_MOB) && sc->opt1 != OPT1_BURNING && skill_id != SR_GENTLETOUCH_CURE) { // Stuned/Frozen/etc
if (skill_id != RK_REFRESH && sc->opt1 && sc->opt1 != OPT1_BURNING && skill_id != SR_GENTLETOUCH_CURE) { // Stuned/Frozen/etc
if (flag != 1) // Can't cast, casted stuff can't damage.
return false;
if (!(skill_get_inf(skill_id)&INF_GROUND_SKILL))
Expand Down Expand Up @@ -4585,7 +4584,6 @@ void status_calc_state( struct block_list *bl, struct status_change *sc, enum sc
(sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF) // cannot move while gospel is in effect
|| (sc->data[SC_BASILICA] && sc->data[SC_BASILICA]->val4 == bl->id) // Basilica caster cannot move
|| (sc->data[SC_GRAVITATION] && sc->data[SC_GRAVITATION]->val3 == BCT_SELF)
|| (sc->data[SC_CRYSTALIZE] && bl->type != BL_MOB)
|| (sc->data[SC_CAMOUFLAGE] && sc->data[SC_CAMOUFLAGE]->val1 < 3)
)
sc->cant.move += ( start ? 1 : ((sc->cant.move)? -1:0) );
Expand All @@ -4595,8 +4593,6 @@ void status_calc_state( struct block_list *bl, struct status_change *sc, enum sc
if( flag&SCS_NOCAST ) {
if( !(flag&SCS_NOCASTCOND) )
sc->cant.cast += ( start ? 1 : -1 );
else if( (sc->data[SC_CRYSTALIZE] && bl->type != BL_MOB) )
sc->cant.cast += ( start ? 1 : -1 );
}

// Can't chat
Expand Down Expand Up @@ -8279,28 +8275,28 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
// Undead are immune to Stone
if (undead_flag && !(flag&SCSTART_NOAVOID))
return 0;
if(sc->data[SC_POWER_OF_GAIA])
return 0;
if (sc->data[SC_GVG_STONE])
if (sc->data[SC_POWER_OF_GAIA] || sc->data[SC_GVG_STONE])
return 0;
if (sc->opt1)
return 0; //Cannot override other OPT1 status changes [Skotlex]
break;
case SC_FREEZE:
// Undead are immune to Freeze
if (undead_flag && !(flag&SCSTART_NOAVOID))
return 0;
if (sc->data[SC_GVG_FREEZ])
if (sc->data[SC_GVG_FREEZ] || sc->data[SC_WARMER])
return 0;
case SC_FREEZING:
case SC_CRYSTALIZE:
if (sc->opt1)
return 0; // Cannot override other opt1 status changes. [Skotlex]
if (sc->data[SC_WARMER])
break;
case SC_FREEZING:
case SC_CRYSTALIZE:
if ((type == SC_FREEZING && sc->data[SC_BURNING]) || sc->data[SC_WARMER])
return 0; // Immune to Frozen and Freezing status if under Warmer status. [Jobbie]
break;
case SC_SLEEP:
if (sc->data[SC_GVG_SLEEP])
return 0;
case SC_DEEPSLEEP:
if (sc->opt1)
return 0; // Cannot override other opt1 status changes. [Skotlex]
break;
Expand Down Expand Up @@ -8339,8 +8335,12 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
return 0;
break;
case SC_BURNING:
if(sc->opt1 || sc->data[SC_FREEZING])
if (sc->data[SC_FREEZING])
return 0;
// Fall through
case SC_WHITEIMPRISON:
if (sc->opt1)
return 0; //Cannot override other OPT1 status changes [Skotlex]
break;
case SC_SIGNUMCRUCIS:
// Only affects demons and undead element (but not players)
Expand Down Expand Up @@ -8964,9 +8964,6 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
case SC_FEAR:
status_change_end(bl, SC_BLIND, INVALID_TIMER);
break;
case SC_FREEZING:
status_change_end(bl, SC_BURNING, INVALID_TIMER);
break;
case SC_KINGS_GRACE:
status_change_end(bl,SC_POISON,INVALID_TIMER);
status_change_end(bl,SC_BLIND,INVALID_TIMER);
Expand Down Expand Up @@ -11042,11 +11039,9 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
break;
case SC_FREEZE: sc->opt1 = OPT1_FREEZE; break;
case SC_STUN: sc->opt1 = OPT1_STUN; break;
case SC_DEEPSLEEP: opt_flag = 0;
case SC_SLEEP: sc->opt1 = OPT1_SLEEP; break;
case SC_BURNING: sc->opt1 = OPT1_BURNING; break; // Burning need this to be showed correctly. [pakpil]
case SC_WHITEIMPRISON: sc->opt1 = OPT1_IMPRISON; break;
case SC_CRYSTALIZE: sc->opt1 = OPT1_CRYSTALIZE; break;
// OPT2
case SC_POISON: sc->opt2 |= OPT2_POISON; break;
case SC_CURSE: sc->opt2 |= OPT2_CURSE; break;
Expand Down Expand Up @@ -12143,10 +12138,8 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
case SC_FREEZE:
case SC_STUN:
case SC_SLEEP:
case SC_DEEPSLEEP:
case SC_BURNING:
case SC_WHITEIMPRISON:
case SC_CRYSTALIZE:
sc->opt1 = 0;
break;

Expand Down Expand Up @@ -12989,8 +12982,8 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)

case SC_CRYSTALIZE:
if( --(sce->val4) >= 0 ) { // Drains 2% of HP and 1% of SP every seconds.
if( bl->type != BL_MOB) // Doesn't work on mobs
status_charge(bl, status->max_hp * 2 / 100, status->max_sp / 100);
if (!status_charge(bl, status->max_hp * 2 / 100, status->max_sp / 100))
break;
sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
return 0;
}
Expand Down
2 changes: 0 additions & 2 deletions src/map/status.h
Expand Up @@ -1834,9 +1834,7 @@ enum sc_opt1 {
//Aegis uses OPT1 = 5 to identify undead enemies (which also grants them immunity to the other opt1 changes)
OPT1_STONEWAIT = 6, //Petrifying
OPT1_BURNING,
OPT1_FREEZING,
OPT1_IMPRISON,
OPT1_CRYSTALIZE,
};

///opt2: (HEALTHSTATE_*) Stackable status changes.
Expand Down
2 changes: 1 addition & 1 deletion src/map/unit.c
Expand Up @@ -1366,7 +1366,7 @@ int unit_can_move(struct block_list *bl) {
)
return 0;

if (sc->opt1 > 0 && sc->opt1 != OPT1_STONEWAIT && sc->opt1 != OPT1_BURNING && !(sc->opt1 == OPT1_CRYSTALIZE && bl->type == BL_MOB))
if (sc->opt1 > 0 && sc->opt1 != OPT1_STONEWAIT && sc->opt1 != OPT1_BURNING)
return 0;

if ((sc->option & OPTION_HIDE) && (!sd || pc_checkskill(sd, RG_TUNNELDRIVE) <= 0))
Expand Down

0 comments on commit ca051d1

Please sign in to comment.