diff options
Diffstat (limited to 'src/map/status.c')
-rw-r--r-- | src/map/status.c | 178 |
1 files changed, 87 insertions, 91 deletions
diff --git a/src/map/status.c b/src/map/status.c index 933d18690..cf3d17228 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -673,7 +673,7 @@ int status_charge(struct block_list* bl, int hp, int sp) //If flag&1, damage is passive and does not triggers cancelling status changes. //If flag&2, fail if target does not has enough to substract. //If flag&4, if killed, mob must not give exp/loot. -//If flag&8, sp loss on dead target. +//flag will be set to &8 when damaging sp of a dead character int status_damage(struct block_list *src,struct block_list *target,int hp, int sp, int walkdelay, int flag) { struct status_data *status; @@ -683,18 +683,15 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s sp = 0; //Not a valid SP target. if (hp < 0) { //Assume absorbed damage. - status_heal(target, cap_value(-hp, INT_MIN, INT_MAX), 0, 1); + status_heal(target, -hp, 0, 1); hp = 0; } if (sp < 0) { - status_heal(target, 0, cap_value(-sp, INT_MIN, INT_MAX), 1); + status_heal(target, 0, -sp, 1); sp = 0; } - if (!hp && !sp) - return 0; - if (target->type == BL_SKILL) return skill_unit_ondamaged((struct skill_unit *)target, src, hp, gettick()); @@ -702,6 +699,19 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s if( status == &dummy_status ) return 0; + if ((unsigned int)hp >= status->hp) { + if (flag&2) return 0; + hp = status->hp; + } + + if ((unsigned int)sp > status->sp) { + if (flag&2) return 0; + sp = status->sp; + } + + if (!hp && !sp) + return 0; + if( !status->hp ) flag |= 8; @@ -711,10 +721,10 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s // return 0; //Cannot damage a bl not on a map, except when "charging" hp/sp sc = status_get_sc(target); - if( battle_config.invincible_nodamage && src && sc && sc->data[SC_INVINCIBLE] && !sc->data[SC_INVINCIBLEOFF] ) + if( hp && battle_config.invincible_nodamage && src && sc && sc->data[SC_INVINCIBLE] && !sc->data[SC_INVINCIBLEOFF] ) hp = 1; - if( hp && !(flag&(1|8)) ) { + if( hp && !(flag&1) ) { if( sc ) { struct status_change_entry *sce; if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE) @@ -748,16 +758,6 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s unit_skillcastcancel(target, 2); } - if ((unsigned int)hp >= status->hp) { - if (flag&2) return 0; - hp = status->hp; - } - - if ((unsigned int)sp > status->sp) { - if (flag&2) return 0; - sp = status->sp; - } - status->hp-= hp; status->sp-= sp; @@ -778,7 +778,7 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s case BL_MER: mercenary_damage((TBL_MER*)target,src,hp,sp); break; } - if( status->hp || flag&8 ) + if( status->hp || (flag&8) ) { //Still lives or has been dead before this damage. if (walkdelay) unit_set_walkdelay(target, gettick(), walkdelay, 0); @@ -822,11 +822,11 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s } } - if( !(flag&8) && sc && sc->data[SC_KAIZEL] ) + if( sc && sc->data[SC_KAIZEL] ) { //flag&8 = disable Kaizel int time = skill_get_time2(SL_KAIZEL,sc->data[SC_KAIZEL]->val1); //Look for Osiris Card's bonus effect on the character and revive 100% or revive normally - if ( target->type == BL_PC && BL_CAST(BL_PC,target)->special_state.restart_full_recover == 1 ) + if ( target->type == BL_PC && BL_CAST(BL_PC,target)->special_state.restart_full_recover ) status_revive(target, 100, 100); else status_revive(target, sc->data[SC_KAIZEL]->val2, 0); @@ -886,7 +886,8 @@ int status_heal(struct block_list *bl,int hp,int sp, int flag) sc = NULL; if (hp < 0) { - status_damage(NULL, bl, cap_value(-hp, INT_MIN, INT_MAX), 0, 0, 1); + if (hp == INT_MIN) hp++; //-INT_MIN == INT_MIN in some architectures! + status_damage(NULL, bl, -hp, 0, 0, 1); hp = 0; } @@ -899,7 +900,8 @@ int status_heal(struct block_list *bl,int hp,int sp, int flag) } if(sp < 0) { - status_damage(NULL, bl, 0, cap_value(-sp, INT_MIN, INT_MAX), 0, 1); + if (sp==INT_MIN) sp++; + status_damage(NULL, bl, 0, -sp, 0, 1); sp = 0; } @@ -1539,19 +1541,14 @@ int status_calc_mob_(struct mob_data* md, bool first) gc=guild_mapname2gc(map[md->bl.m].name); if (!gc) ShowError("status_calc_mob: No castle set at map %s\n", map[md->bl.m].name); - else { - if(gc->castle_id > 23) { - if(md->class_ == MOBID_EMPERIUM) { - status->max_hp += 1000 * gc->defense; - status->max_sp += 200 * gc->defense; - status->hp = status->max_hp; - status->sp = status->max_sp; - } - }else{ - status->max_hp += 1000 * gc->defense; - status->max_sp += 200 * gc->defense; - status->hp = status->max_hp; - status->sp = status->max_sp; + else + if(gc->castle_id < 24 || md->class_ == MOBID_EMPERIUM) { + status->max_hp += 1000 * gc->defense; + status->max_sp += 200 * gc->defense; + status->hp = status->max_hp; + status->sp = status->max_sp; + if( gc->castle_id < 24 ) + { status->def += (gc->defense+2)/3; status->mdef += (gc->defense+2)/3; } @@ -2034,11 +2031,15 @@ int status_calc_pc_(struct map_session_data* sd, bool first) if(!data->script) continue; if(data->flag.no_equip) { //Card restriction checks. - if(map[sd->bl.m].flag.restricted && data->flag.no_equip&map[sd->bl.m].zone) + if(map[sd->bl.m].flag.restricted && data->flag.no_equip&(8*map[sd->bl.m].zone)) + continue; + if(!map_flag_vs(sd->bl.m) && data->flag.no_equip&1) + continue; + if(map[sd->bl.m].flag.pvp && data->flag.no_equip&2) continue; - if(map[sd->bl.m].flag.pvp && data->flag.no_equip&1) + if(map_flag_gvg(sd->bl.m) && data->flag.no_equip&4) continue; - if(map_flag_gvg(sd->bl.m) && data->flag.no_equip&2) + if(map[sd->bl.m].flag.battleground && data->flag.no_equip&8) continue; } if(i == EQI_HAND_L && sd->status.inventory[index].equip == EQP_HAND_L) @@ -2466,6 +2467,11 @@ int status_calc_pc_(struct map_session_data* sd, bool first) status_cpy(&sd->battle_status, status); // ----- CLIENT-SIDE REFRESH ----- + if(!sd->bl.prev) { + //Will update on LoadEndAck + calculating = 0; + return 0; + } if(memcmp(b_skill,sd->status.skill,sizeof(sd->status.skill))) clif_skillinfoblock(sd); if(b_weight != sd->weight) @@ -2740,7 +2746,7 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str if ( sc->data[SC_DANCING] || ( - (((TBL_PC*)bl)->class_&MAPID_UPPERMASK) == MAPID_MONK && + (bl->type == BL_PC && ((TBL_PC*)bl)->class_&MAPID_UPPERMASK) == MAPID_MONK && (sc->data[SC_EXTREMITYFIST] || (sc->data[SC_EXPLOSIONSPIRITS] && (!sc->data[SC_SPIRIT] || sc->data[SC_SPIRIT]->val2 != SL_MONK))) ) || sc->data[SC_MAXIMIZEPOWER] @@ -2773,7 +2779,7 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str /// Recalculates parts of an object's battle status according to the specified flags. /// @param flag bitfield of values from enum scb_flag -void status_calc_bl_main(struct block_list *bl, enum scb_flag flag) +void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) { const struct status_data *b_status = status_get_base_status(bl); struct status_data *status = status_get_status_data(bl); @@ -5897,44 +5903,17 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val //val1: Skill ID //val2: When given, target (for autotargetting skills) //val3: When set, this combo time should NOT delay attack/movement - //val4: Combo time + //val3: TK: Last used kick + //val4: TK: Combo time struct unit_data *ud = unit_bl2ud(bl); - switch (val1) { - case TK_STORMKICK: - clif_skill_nodamage(bl,bl,TK_READYSTORM,1,1); - break; - case TK_DOWNKICK: - clif_skill_nodamage(bl,bl,TK_READYDOWN,1,1); - break; - case TK_TURNKICK: - clif_skill_nodamage(bl,bl,TK_READYTURN,1,1); - break; - case TK_COUNTER: - clif_skill_nodamage(bl,bl,TK_READYCOUNTER,1,1); - break; - case MO_COMBOFINISH: - case CH_TIGERFIST: - case CH_CHAINCRUSH: - if( sd ) - { - sd->state.combo = 1; - clif_skillinfoblock(sd); - } - break; - case TK_JUMPKICK: - if( sd ) - { - sd->state.combo = 2; - clif_skillinfoblock(sd); - } - break; - } if (ud && !val3) { + tick += 300 * battle_config.combo_delay_rate/100; ud->attackabletime = gettick()+tick; unit_set_walkdelay(bl, gettick(), tick, 1); } - val4 = tick; //Store combo-time in val4. + val3 = 0; + val4 = tick; } break; case SC_EARTHSCROLL: @@ -6498,6 +6477,31 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val case SC_MERC_SPUP: status_percent_heal(bl, 0, 100); // Recover Full SP break; + case SC_COMBO: + switch (sce->val1) { + case TK_STORMKICK: + clif_skill_nodamage(bl,bl,TK_READYSTORM,1,1); + break; + case TK_DOWNKICK: + clif_skill_nodamage(bl,bl,TK_READYDOWN,1,1); + break; + case TK_TURNKICK: + clif_skill_nodamage(bl,bl,TK_READYTURN,1,1); + break; + case TK_COUNTER: + clif_skill_nodamage(bl,bl,TK_READYCOUNTER,1,1); + break; + case MO_COMBOFINISH: + case CH_TIGERFIST: + case CH_CHAINCRUSH: + if (sd) + clif_skillinfo(sd,MO_EXTREMITYFIST, INF_SELF_SKILL); + break; + case TK_JUMPKICK: + if (sd) + clif_skillinfo(sd,TK_JUMPKICK, INF_SELF_SKILL); + break; + } } if( opt_flag&2 && sd && sd->touching_id ) @@ -6836,16 +6840,17 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const bl->m, bl->x-range, bl->y-range, bl->x+range,bl->y+range,BL_CHAR,bl,sce,type,gettick()); } break; - case SC_COMBO: //Clear last used skill when it is part of a combo. + case SC_COMBO: if( sd ) - { - if( sd->state.combo ) - { - sd->state.combo = 0; - clif_skillinfoblock(sd); - } - if( sd->skillid_old == sce->val1 ) - sd->skillid_old = sd->skilllv_old = 0; + switch (sce->val1) { + case MO_COMBOFINISH: + case CH_TIGERFIST: + case CH_CHAINCRUSH: + clif_skillinfo(sd, MO_EXTREMITYFIST, 0); + break; + case TK_JUMPKICK: + clif_skillinfo(sd, TK_JUMPKICK, 0); + break; } break; @@ -7404,15 +7409,6 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) } break; - case SC_DEVOTION: - //FIXME: use normal status duration instead of a looping timer - if( (sce->val4 -= 1000) > 0 ) - { - sc_timer_next(1000+tick, status_change_timer, bl->id, data); - return 0; - } - break; - case SC_BERSERK: // 5% every 10 seconds [DracoRPG] if( --( sce->val3 ) > 0 && status_charge(bl, sce->val2, 0) && status->hp > 100 ) |