diff --git a/db/pre-re/skill_db.yml b/db/pre-re/skill_db.yml index 3386bf1ef49..3c7ab9e9b44 100644 --- a/db/pre-re/skill_db.yml +++ b/db/pre-re/skill_db.yml @@ -30726,9 +30726,6 @@ Body: TargetType: Self DamageFlags: NoDamage: true - Range: 9 - Hit: Single - HitCount: 1 AfterCastActDelay: 2000 AfterCastWalkDelay: 1000 Requires: @@ -30753,10 +30750,6 @@ Body: TargetType: Self DamageFlags: NoDamage: true - Splash: true - Hit: Single - HitCount: 1 - SplashArea: -1 AfterCastActDelay: 35000 AfterCastWalkDelay: 1000 Duration1: @@ -30787,7 +30780,6 @@ Body: Name: HLIF_BRAIN Description: Brain Surgery MaxLevel: 5 - SplashArea: 1 - Id: 8004 Name: HLIF_CHANGE Description: Change @@ -30795,7 +30787,6 @@ Body: TargetType: Self DamageFlags: NoDamage: true - Hit: Single AfterCastActDelay: - Level: 1 Time: 600000 diff --git a/db/pre-re/status.yml b/db/pre-re/status.yml index 2b777e4da55..f75a7d66419 100644 --- a/db/pre-re/status.yml +++ b/db/pre-re/status.yml @@ -2478,13 +2478,17 @@ Body: DurationLookup: HLIF_AVOID CalcFlags: Speed: true + Flags: + NoSave: true + RemoveFromHomOnWarp: true - Status: Change DurationLookup: HLIF_CHANGE CalcFlags: Vit: true Int: true Flags: - RemoveOnChangeMap: true + NoSave: true + RemoveFromHomOnWarp: true Fail: Change: true - Status: Bloodlust diff --git a/db/re/skill_db.yml b/db/re/skill_db.yml index 6fe845509d9..eb8f3251b76 100644 --- a/db/re/skill_db.yml +++ b/db/re/skill_db.yml @@ -43018,9 +43018,8 @@ Body: TargetType: Self DamageFlags: NoDamage: true - Range: 9 - Hit: Single - HitCount: 1 + Flags: + IgnoreGtb: true AfterCastWalkDelay: 1000 Cooldown: 20000 Requires: @@ -43045,10 +43044,6 @@ Body: TargetType: Self DamageFlags: NoDamage: true - Splash: true - Hit: Single - HitCount: 1 - SplashArea: -1 AfterCastWalkDelay: 1000 Duration1: - Level: 1 @@ -43079,7 +43074,6 @@ Body: Name: HLIF_BRAIN Description: Brain Surgery MaxLevel: 5 - SplashArea: 1 - Id: 8004 Name: HLIF_CHANGE Description: Change @@ -43087,7 +43081,6 @@ Body: TargetType: Self DamageFlags: NoDamage: true - Hit: Single AfterCastWalkDelay: 1000 Duration1: - Level: 1 diff --git a/db/re/status.yml b/db/re/status.yml index e7b737e68e9..a59e927bc38 100644 --- a/db/re/status.yml +++ b/db/re/status.yml @@ -2600,13 +2600,17 @@ Body: DurationLookup: HLIF_AVOID CalcFlags: Speed: true + Flags: + NoSave: true + RemoveFromHomOnMapWarp: true - Status: Change DurationLookup: HLIF_CHANGE CalcFlags: Vit: true Int: true Flags: - RemoveOnChangeMap: true + NoSave: true + RemoveFromHomOnMapWarp: true Fail: Change: true - Status: Bloodlust diff --git a/doc/status.txt b/doc/status.txt index 1133f95d3f4..36f306e5d74 100644 --- a/doc/status.txt +++ b/doc/status.txt @@ -254,6 +254,9 @@ Flags: Various status flags for specific status change events. SuperNoviceAngel - Status that is given from Super Novice Angel. TaekwonAngel - Status that is given from Taekwon Angel. + RemoveFromHomOnWarp - Removes the status from the Homunculus when teleporting or warping to another map. + RemoveFromHomOnMapWarp - Removes the status from the Homunculus when warping to another map. + --------------------------------------- MinDuration: Minimum duration, in milliseconds, after reduction calculation for status resistance. diff --git a/doc/status_change.txt b/doc/status_change.txt index 530f55645ab..a4b7264b775 100644 --- a/doc/status_change.txt +++ b/doc/status_change.txt @@ -1001,13 +1001,16 @@ SC_FLING () desc: val1: -SC_AVOID () - desc: - val1: +SC_AVOID (EFST_HLIF_AVOID) + desc: Increase walkspeed for Players and Homunculus + val1: Skill Level + val2: Walkspeed increase (10 * val1 for Players, 40 * val1 for Homunculus) -SC_CHANGE () - desc: - val1: +SC_CHANGE (EFST_HLIF_CHANGE) + desc: Increase some Homunculus' statuses (VIT, INT); Uses MATK for damage calculation; Sets Homunculus' HP and SP to 10 on expiration; On Pre-Renewal, sets Homunculus' HP and SP to 100% on cast + val1: Skill Level + val2: VIT increase (20 * val1) + val3: INT increase (30 * val1) SC_BLOODLUST () desc: diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 86a5475ac21..ae160f66dc7 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -10804,8 +10804,7 @@ void clif_parse_LoadEndAck(int fd,map_session_data *sd) clif_hominfo(sd,sd->hd,1); clif_hominfo(sd,sd->hd,0); //for some reason, at least older clients want this sent twice clif_homskillinfoblock( *sd->hd ); - if( battle_config.hom_setting&HOMSET_COPY_SPEED ) - status_calc_bl(&sd->hd->bl, { SCB_SPEED }); //Homunc mimic their master's speed on each map change + status_calc_bl(&sd->hd->bl, { SCB_SPEED }); if( !(battle_config.hom_setting&HOMSET_NO_INSTANT_LAND_SKILL) ) skill_unit_move(&sd->hd->bl,gettick(),1); // apply land skills immediately } diff --git a/src/map/homunculus.cpp b/src/map/homunculus.cpp index d61890a9654..c8cdef00792 100644 --- a/src/map/homunculus.cpp +++ b/src/map/homunculus.cpp @@ -293,6 +293,7 @@ int hom_vaporize(map_session_data *sd, int flag) hd->blockskill.clear(); hd->blockskill.shrink_to_fit(); } + status_change_clear(&hd->bl, 1); clif_hominfo(sd, sd->hd, 0); hom_save(hd); @@ -1138,8 +1139,7 @@ bool hom_call(map_session_data *sd) clif_hominfo(sd,hd,1); clif_hominfo(sd,hd,0); // send this x2. dunno why, but kRO does that [blackhole89] clif_homskillinfoblock( *hd ); - if (battle_config.hom_setting&HOMSET_COPY_SPEED) - status_calc_bl(&hd->bl, { SCB_SPEED }); + status_calc_bl(&hd->bl, { SCB_SPEED }); hom_save(hd); } else //Warp him to master. diff --git a/src/map/pc.cpp b/src/map/pc.cpp index 9e7c3045595..dfbc927b136 100755 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -7008,6 +7008,11 @@ enum e_setpos pc_setpos(map_session_data* sd, unsigned short mapindex, int x, in if( hom_is_active(sd->hd) ) { + if (sd->state.changemap) + status_db.removeByStatusFlag(&sd->hd->bl, { SCF_REMOVEFROMHOMONMAPWARP }); + else + status_db.removeByStatusFlag(&sd->hd->bl, { SCF_REMOVEFROMHOMONWARP }); + if (battle_config.hom_delay_reset_warp) { sd->hd->blockskill.clear(); sd->hd->blockskill.shrink_to_fit(); diff --git a/src/map/script_constants.hpp b/src/map/script_constants.hpp index 08c0db42f40..c060b151e41 100644 --- a/src/map/script_constants.hpp +++ b/src/map/script_constants.hpp @@ -11297,6 +11297,8 @@ export_constant(SCF_REMOVEONUNEQUIPARMOR); export_constant(SCF_REMOVEONHERMODE); export_constant(SCF_REQUIRENOWEAPON); + export_constant(SCF_REMOVEFROMHOMONWARP); + export_constant(SCF_REMOVEFROMHOMONMAPWARP); /* enchantgrades */ export_constant(ENCHANTGRADE_NONE); diff --git a/src/map/skill.cpp b/src/map/skill.cpp index f098fc72e19..c15ecc239b5 100755 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -7322,12 +7322,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui //Check for undead skills that convert a no-damage skill into a damage one. [Skotlex] switch (skill_id) { - case HLIF_HEAL: //[orn] - if (bl->type != BL_HOM) { - if (sd) clif_skill_fail( *sd, skill_id ); - break ; - } - [[fallthrough]]; case AL_HEAL: case ALL_RESURRECTION: case PR_ASPERSIO: @@ -10718,11 +10712,15 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui status_heal(bl, i, 0, 0); } break; - //Homun single-target support skills [orn] + // Homun single-target support skills [orn] + case HLIF_CHANGE: +#ifndef RENEWAL + status_percent_heal(bl, 100, 100); + [[fallthrough]]; +#endif case HAMI_BLOODLUST: case HFLI_FLEET: case HFLI_SPEED: - case HLIF_CHANGE: case MH_ANGRIFFS_MODUS: case MH_GOLDENE_FERSE: clif_skill_nodamage(src,bl,skill_id,skill_lv, diff --git a/src/map/status.cpp b/src/map/status.cpp index f15df6ad3c3..29ecc77fa42 100644 --- a/src/map/status.cpp +++ b/src/map/status.cpp @@ -5593,12 +5593,12 @@ void status_calc_state( struct block_list *bl, status_change *sc, std::bitset flag) +void status_calc_bl_main(struct block_list& bl, std::bitset flag) { - const struct status_data *b_status = status_get_base_status(bl); // Base Status - struct status_data *status = status_get_status_data(bl); // Battle Status - status_change *sc = status_get_sc(bl); - TBL_PC *sd = BL_CAST(BL_PC,bl); + const struct status_data *b_status = status_get_base_status(&bl); // Base Status + struct status_data *status = status_get_status_data(&bl); // Battle Status + status_change *sc = status_get_sc(&bl); + TBL_PC *sd = BL_CAST(BL_PC,&bl); int temp; if (!b_status || !status) @@ -5609,7 +5609,7 @@ void status_calc_bl_main(struct block_list *bl, std::bitset flag) * we need to update the speed on the client when the last status change ends. **/ if(flag[SCB_SPEED]) { - struct unit_data *ud = unit_bl2ud(bl); + struct unit_data *ud = unit_bl2ud(&bl); /** [Skotlex] * Re-walk to adjust speed (we do not check if walktimer != INVALID_TIMER * because if you step on something while walking, the moment this @@ -5620,60 +5620,60 @@ void status_calc_bl_main(struct block_list *bl, std::bitset flag) } if(flag[SCB_STR]) { - status->str = status_calc_str(bl, sc, b_status->str); + status->str = status_calc_str(&bl, sc, b_status->str); flag.set(SCB_BATK); - if( bl->type&BL_HOM ) + if( bl.type == BL_HOM ) flag.set(SCB_WATK); } if(flag[SCB_AGI]) { - status->agi = status_calc_agi(bl, sc, b_status->agi); + status->agi = status_calc_agi(&bl, sc, b_status->agi); flag.set(SCB_FLEE); #ifdef RENEWAL flag.set(SCB_DEF2); #endif - if( bl->type&(BL_PC|BL_HOM) ) { + if( bl.type&(BL_PC|BL_HOM) ) { flag.set(SCB_ASPD); flag.set(SCB_DSPD); } } if(flag[SCB_VIT]) { - status->vit = status_calc_vit(bl, sc, b_status->vit); + status->vit = status_calc_vit(&bl, sc, b_status->vit); flag.set(SCB_DEF2); flag.set(SCB_MDEF2); - if( bl->type&(BL_PC|BL_HOM|BL_MER|BL_ELEM) ) + if( bl.type&(BL_PC|BL_HOM|BL_MER|BL_ELEM) ) flag.set(SCB_MAXHP); - if( bl->type&BL_HOM ) + if( bl.type == BL_HOM ) flag.set(SCB_DEF); } if(flag[SCB_INT]) { - status->int_ = status_calc_int(bl, sc, b_status->int_); + status->int_ = status_calc_int(&bl, sc, b_status->int_); flag.set(SCB_MATK); flag.set(SCB_MDEF2); - if( bl->type&(BL_PC|BL_HOM|BL_MER|BL_ELEM) ) + if( bl.type&(BL_PC|BL_HOM|BL_MER|BL_ELEM) ) flag.set(SCB_MAXSP); - if( bl->type&BL_HOM ) + if( bl.type == BL_HOM ) flag.set(SCB_MDEF); } if(flag[SCB_DEX]) { - status->dex = status_calc_dex(bl, sc, b_status->dex); + status->dex = status_calc_dex(&bl, sc, b_status->dex); flag.set(SCB_BATK); flag.set(SCB_HIT); #ifdef RENEWAL flag.set(SCB_MATK); flag.set(SCB_MDEF2); #endif - if( bl->type&(BL_PC|BL_HOM) ) + if( bl.type&(BL_PC|BL_HOM) ) flag.set(SCB_ASPD); - if( bl->type&BL_HOM ) + if( bl.type == BL_HOM ) flag.set(SCB_WATK); } if(flag[SCB_LUK]) { - status->luk = status_calc_luk(bl, sc, b_status->luk); + status->luk = status_calc_luk(&bl, sc, b_status->luk); flag.set(SCB_BATK); flag.set(SCB_CRI); flag.set(SCB_FLEE2); @@ -5686,29 +5686,29 @@ void status_calc_bl_main(struct block_list *bl, std::bitset flag) #ifdef RENEWAL if (flag[SCB_POW]) { - status->pow = status_calc_pow(bl, sc, b_status->pow); + status->pow = status_calc_pow(&bl, sc, b_status->pow); flag.set(SCB_BATK); flag.set(SCB_PATK); } if (flag[SCB_STA]) { - status->sta = status_calc_sta(bl, sc, b_status->sta); + status->sta = status_calc_sta(&bl, sc, b_status->sta); flag.set(SCB_RES); } if (flag[SCB_WIS]) { - status->wis = status_calc_wis(bl, sc, b_status->wis); + status->wis = status_calc_wis(&bl, sc, b_status->wis); flag.set(SCB_MRES); } if (flag[SCB_SPL]) { - status->spl = status_calc_spl(bl, sc, b_status->spl); + status->spl = status_calc_spl(&bl, sc, b_status->spl); flag.set(SCB_MATK); flag.set(SCB_SMATK); } if (flag[SCB_CON]) { - status->con = status_calc_con(bl, sc, b_status->con); + status->con = status_calc_con(&bl, sc, b_status->con); flag.set(SCB_HIT); flag.set(SCB_FLEE); flag.set(SCB_PATK); @@ -5716,47 +5716,47 @@ void status_calc_bl_main(struct block_list *bl, std::bitset flag) } if (flag[SCB_CRT]) { - status->crt = status_calc_crt(bl, sc, b_status->crt); + status->crt = status_calc_crt(&bl, sc, b_status->crt); flag.set(SCB_HPLUS); flag.set(SCB_CRATE); } #endif if(flag[SCB_BATK] && b_status->batk) { - int lv = status_get_lv(bl); - status->batk = status_base_atk(bl, status, lv); - temp = b_status->batk - status_base_atk(bl, b_status, lv); + int lv = status_get_lv(&bl); + status->batk = status_base_atk(&bl, status, lv); + temp = b_status->batk - status_base_atk(&bl, b_status, lv); if (temp) { temp += status->batk; status->batk = cap_value(temp, 0, USHRT_MAX); } - status->batk = status_calc_batk(bl, sc, status->batk); + status->batk = status_calc_batk(&bl, sc, status->batk); } if(flag[SCB_WATK]) { #ifndef RENEWAL - status->rhw.atk = status_calc_watk(bl, sc, b_status->rhw.atk); + status->rhw.atk = status_calc_watk(&bl, sc, b_status->rhw.atk); if (!sd) // Should not affect weapon refine bonus - status->rhw.atk2 = status_calc_watk(bl, sc, b_status->rhw.atk2); + status->rhw.atk2 = status_calc_watk(&bl, sc, b_status->rhw.atk2); if (sd && sd->bonus.weapon_atk_rate) status->rhw.atk += status->rhw.atk * sd->bonus.weapon_atk_rate / 100; if(b_status->lhw.atk) { if (sd) { sd->state.lr_flag = 1; - status->lhw.atk = status_calc_watk(bl, sc, b_status->lhw.atk); + status->lhw.atk = status_calc_watk(&bl, sc, b_status->lhw.atk); sd->state.lr_flag = 0; } else { - status->lhw.atk = status_calc_watk(bl, sc, b_status->lhw.atk); - status->lhw.atk2= status_calc_watk(bl, sc, b_status->lhw.atk2); + status->lhw.atk = status_calc_watk(&bl, sc, b_status->lhw.atk); + status->lhw.atk2= status_calc_watk(&bl, sc, b_status->lhw.atk2); } } #else if(!b_status->watk) { // We only have left-hand weapon status->watk = 0; - status->watk2 = status_calc_watk(bl, sc, b_status->watk2); + status->watk2 = status_calc_watk(&bl, sc, b_status->watk2); } - else status->watk = status_calc_watk(bl, sc, b_status->watk); + else status->watk = status_calc_watk(&bl, sc, b_status->watk); #endif } @@ -5766,9 +5766,9 @@ void status_calc_bl_main(struct block_list *bl, std::bitset flag) && status->luk == b_status->luk && status->con == b_status->con #endif ) - status->hit = status_calc_hit(bl, sc, b_status->hit); + status->hit = status_calc_hit(&bl, sc, b_status->hit); else - status->hit = status_calc_hit(bl, sc, b_status->hit + (status->dex - b_status->dex) + status->hit = status_calc_hit(&bl, sc, b_status->hit + (status->dex - b_status->dex) #ifdef RENEWAL + (status->luk/3 - b_status->luk/3) + 2 * (status->con - b_status->con) #endif @@ -5781,9 +5781,9 @@ void status_calc_bl_main(struct block_list *bl, std::bitset flag) && status->luk == b_status->luk && status->con == b_status->con #endif ) - status->flee = status_calc_flee(bl, sc, b_status->flee); + status->flee = status_calc_flee(&bl, sc, b_status->flee); else - status->flee = status_calc_flee(bl, sc, b_status->flee +(status->agi - b_status->agi) + status->flee = status_calc_flee(&bl, sc, b_status->flee +(status->agi - b_status->agi) #ifdef RENEWAL + (status->luk/5 - b_status->luk/5) + 2 * (status->con - b_status->con) #endif @@ -5791,9 +5791,9 @@ void status_calc_bl_main(struct block_list *bl, std::bitset flag) } if(flag[SCB_DEF]) { - status->def = status_calc_def(bl, sc, b_status->def); + status->def = status_calc_def(&bl, sc, b_status->def); - if( bl->type&BL_HOM ) + if( bl.type == BL_HOM ) status->def += (status->vit/5 - b_status->vit/5); } @@ -5803,9 +5803,9 @@ void status_calc_bl_main(struct block_list *bl, std::bitset flag) && status->agi == b_status->agi #endif ) - status->def2 = status_calc_def2(bl, sc, b_status->def2); + status->def2 = status_calc_def2(&bl, sc, b_status->def2); else - status->def2 = status_calc_def2(bl, sc, b_status->def2 + status->def2 = status_calc_def2(&bl, sc, b_status->def2 #ifdef RENEWAL + (int)( ((float)status->vit/2 - (float)b_status->vit/2) + ((float)status->agi/5 - (float)b_status->agi/5) ) #else @@ -5815,9 +5815,9 @@ void status_calc_bl_main(struct block_list *bl, std::bitset flag) } if(flag[SCB_MDEF]) { - status->mdef = status_calc_mdef(bl, sc, b_status->mdef); + status->mdef = status_calc_mdef(&bl, sc, b_status->mdef); - if( bl->type&BL_HOM ) + if( bl.type == BL_HOM ) status->mdef += (status->int_/5 - b_status->int_/5); } @@ -5827,9 +5827,9 @@ void status_calc_bl_main(struct block_list *bl, std::bitset flag) && status->dex == b_status->dex #endif ) - status->mdef2 = status_calc_mdef2(bl, sc, b_status->mdef2); + status->mdef2 = status_calc_mdef2(&bl, sc, b_status->mdef2); else - status->mdef2 = status_calc_mdef2(bl, sc, b_status->mdef2 +(status->int_ - b_status->int_) + status->mdef2 = status_calc_mdef2(&bl, sc, b_status->mdef2 +(status->int_ - b_status->int_) #ifdef RENEWAL + (int)( ((float)status->dex/5 - (float)b_status->dex/5) + ((float)status->vit/5 - (float)b_status->vit/5) ) #else @@ -5839,29 +5839,67 @@ void status_calc_bl_main(struct block_list *bl, std::bitset flag) } if(flag[SCB_SPEED]) { - status->speed = status_calc_speed(bl, sc, b_status->speed); + status->speed = status_calc_speed(&bl, sc, b_status->speed); + + switch (bl.type) { + case BL_PC: + if (!sd->state.permanent_speed && status->speed < battle_config.max_walk_speed) + status->speed = battle_config.max_walk_speed; +#ifdef RENEWAL + // Recalculate homunculus speed if the player receives a speed buff/debuff + if (hom_is_active(sd->hd)) { + if (battle_config.hom_setting & HOMSET_COPY_SPEED) + sd->hd->battle_status.speed = status_get_speed(&sd->bl); + + // Homunculus speed buff/debuffs applies over the current speed + sd->hd->battle_status.speed = status_calc_speed(&sd->hd->bl, &sd->hd->sc, sd->hd->battle_status.speed); + } +#endif + break; + + case BL_PET:{ + pet_data* pd = reinterpret_cast(&bl); + + if (pd->master != nullptr) + status->speed = status_get_speed(&pd->master->bl); + } break; - if( bl->type&BL_PC && !(sd && sd->state.permanent_speed) && status->speed < battle_config.max_walk_speed ) - status->speed = battle_config.max_walk_speed; + case BL_HOM:{ + homun_data* hd = reinterpret_cast(&bl); - if( bl->type&BL_PET && ((TBL_PET*)bl)->master) - status->speed = status_get_speed(&((TBL_PET*)bl)->master->bl); - if( bl->type&BL_HOM && battle_config.hom_setting&HOMSET_COPY_SPEED && ((TBL_HOM*)bl)->master) - status->speed = status_get_speed(&((TBL_HOM*)bl)->master->bl); - if( bl->type&BL_MER && ((TBL_MER*)bl)->master) - status->speed = status_get_speed(&((TBL_MER*)bl)->master->bl); - if( bl->type&BL_ELEM && ((TBL_ELEM*)bl)->master) - status->speed = status_get_speed(&((TBL_ELEM*)bl)->master->bl); + if (hd->master != nullptr) { + if (battle_config.hom_setting & HOMSET_COPY_SPEED) + status->speed = status_get_speed(&hd->master->bl); + + // Homunculus speed buff/debuffs applies over the current speed + status->speed = status_calc_speed(&bl, &hd->sc, status->speed); + } + } break; + + case BL_MER:{ + s_mercenary_data* mc = reinterpret_cast(&bl); + + if (mc->master != nullptr) + status->speed = status_get_speed(&mc->master->bl); + } break; + + case BL_ELEM:{ + s_elemental_data* ed = reinterpret_cast(&bl); + + if (ed->master != nullptr) + status->speed = status_get_speed(&ed->master->bl); + } break; + } } if(flag[SCB_CRI] && b_status->cri) { if (status->luk == b_status->luk) - status->cri = status_calc_critical(bl, sc, b_status->cri); + status->cri = status_calc_critical(&bl, sc, b_status->cri); else #ifdef RENEWAL - status->cri = status_calc_critical(bl, sc, b_status->cri + 3*(status->luk - b_status->luk)); + status->cri = status_calc_critical(&bl, sc, b_status->cri + 3*(status->luk - b_status->luk)); #else - status->cri = status_calc_critical(bl, sc, b_status->cri + (status->luk - b_status->luk)*10/3); + status->cri = status_calc_critical(&bl, sc, b_status->cri + (status->luk - b_status->luk)*10/3); #endif /// After status_calc_critical so the bonus is applied despite if you have or not a sc bugreport:5240 @@ -5873,25 +5911,25 @@ void status_calc_bl_main(struct block_list *bl, std::bitset flag) if(flag[SCB_FLEE2] && b_status->flee2) { if (status->luk == b_status->luk) - status->flee2 = status_calc_flee2(bl, sc, b_status->flee2); + status->flee2 = status_calc_flee2(&bl, sc, b_status->flee2); else - status->flee2 = status_calc_flee2(bl, sc, b_status->flee2 +(status->luk - b_status->luk)); + status->flee2 = status_calc_flee2(&bl, sc, b_status->flee2 +(status->luk - b_status->luk)); } if(flag[SCB_ATK_ELE]) { - status->rhw.ele = status_calc_attack_element(bl, sc, b_status->rhw.ele); + status->rhw.ele = status_calc_attack_element(&bl, sc, b_status->rhw.ele); if (sd) sd->state.lr_flag = 1; - status->lhw.ele = status_calc_attack_element(bl, sc, b_status->lhw.ele); + status->lhw.ele = status_calc_attack_element(&bl, sc, b_status->lhw.ele); if (sd) sd->state.lr_flag = 0; } if(flag[SCB_DEF_ELE]) { - status->def_ele = status_calc_element(bl, sc, b_status->def_ele); - status->ele_lv = status_calc_element_lv(bl, sc, b_status->ele_lv); + status->def_ele = status_calc_element(&bl, sc, b_status->def_ele); + status->ele_lv = status_calc_element_lv(&bl, sc, b_status->ele_lv); } if(flag[SCB_MODE]) { - status->mode = status_calc_mode(bl, sc, b_status->mode); + status->mode = status_calc_mode(&bl, sc, b_status->mode); if (status_has_mode(status, MD_STATUSIMMUNE|MD_SKILLIMMUNE)) status->class_ = CLASS_BATTLEFIELD; @@ -5904,9 +5942,9 @@ void status_calc_bl_main(struct block_list *bl, std::bitset flag) // Since mode changed, reset their state. if (!status_has_mode(status,MD_CANATTACK)) - unit_stop_attack(bl); + unit_stop_attack(&bl); if (!status_has_mode(status,MD_CANMOVE)) - unit_stop_walking(bl,1); + unit_stop_walking(&bl,1); } /** @@ -5917,7 +5955,7 @@ void status_calc_bl_main(struct block_list *bl, std::bitset flag) **/ if(flag[SCB_MAXHP]) { - if( bl->type&BL_PC ) { + if( bl.type == BL_PC ) { status->max_hp = status_calc_maxhpsp_pc(sd,status->vit,true); if(battle_config.hp_rate != 100) @@ -5931,7 +5969,7 @@ void status_calc_bl_main(struct block_list *bl, std::bitset flag) status->max_hp = umin(status->max_hp,(unsigned int)battle_config.max_hp); } else - status->max_hp = status_calc_maxhp(bl, b_status->max_hp); + status->max_hp = status_calc_maxhp(&bl, b_status->max_hp); if( status->hp > status->max_hp ) { // !FIXME: Should perhaps a status_zap should be issued? status->hp = status->max_hp; @@ -5940,7 +5978,7 @@ void status_calc_bl_main(struct block_list *bl, std::bitset flag) } if(flag[SCB_MAXSP]) { - if( bl->type&BL_PC ) { + if( bl.type == BL_PC ) { status->max_sp = status_calc_maxhpsp_pc(sd,status->int_,false); if(battle_config.sp_rate != 100) @@ -5949,7 +5987,7 @@ void status_calc_bl_main(struct block_list *bl, std::bitset flag) status->max_sp = umin(status->max_sp,(unsigned int)battle_config.max_sp); } else - status->max_sp = status_calc_maxsp(bl, b_status->max_sp); + status->max_sp = status_calc_maxsp(&bl, b_status->max_sp); if( status->sp > status->max_sp ) { status->sp = status->max_sp; @@ -5966,11 +6004,11 @@ void status_calc_bl_main(struct block_list *bl, std::bitset flag) * RE MATK Formula (from irowiki:http:// irowiki.org/wiki/MATK) * MATK = (sMATK + wMATK + eMATK) * Multiplicative Modifiers **/ - int lv = status_get_lv(bl); - status->matk_min = status_base_matk_min(bl, status, lv); - status->matk_max = status_base_matk_max(bl, status, lv); + int lv = status_get_lv(&bl); + status->matk_min = status_base_matk_min(&bl, status, lv); + status->matk_max = status_base_matk_max(&bl, status, lv); - switch( bl->type ) { + switch( bl.type ) { case BL_PC: { int wMatk = 0; int variance = 0; @@ -5987,7 +6025,7 @@ void status_calc_bl_main(struct block_list *bl, std::bitset flag) status->matk_min += 15 * skill_lv + (skill_lv > 4 ? 25 : 0); } - status->matk_min = status_calc_ematk(bl, sc, status->matk_min); + status->matk_min = status_calc_ematk(&bl, sc, status->matk_min); status->matk_max = status->matk_min; // This is the only portion in MATK that varies depending on the weapon level and refinement rate. @@ -6022,12 +6060,12 @@ void status_calc_bl_main(struct block_list *bl, std::bitset flag) } #endif - if (bl->type&BL_PC && sd->matk_rate != 100) { + if (bl.type == BL_PC && sd->matk_rate != 100) { status->matk_max = status->matk_max * sd->matk_rate/100; status->matk_min = status->matk_min * sd->matk_rate/100; } - if ((bl->type&BL_HOM && battle_config.hom_setting&HOMSET_SAME_MATK) /// Hom Min Matk is always the same as Max Matk + if ((bl.type == BL_HOM && battle_config.hom_setting&HOMSET_SAME_MATK) /// Hom Min Matk is always the same as Max Matk || (sc && sc->getSCE(SC_RECOGNIZEDSPELL))) status->matk_min = status->matk_max; @@ -6038,35 +6076,35 @@ void status_calc_bl_main(struct block_list *bl, std::bitset flag) } #endif - status->matk_max = status_calc_matk(bl, sc, status->matk_max); - status->matk_min = status_calc_matk(bl, sc, status->matk_min); + status->matk_max = status_calc_matk(&bl, sc, status->matk_max); + status->matk_min = status_calc_matk(&bl, sc, status->matk_min); } if(flag[SCB_ASPD]) { int amotion; - if ( bl->type&BL_HOM ) { + if ( bl.type == BL_HOM ) { #ifdef RENEWAL_ASPD - amotion = ((TBL_HOM*)bl)->homunculusDB->baseASPD; - amotion = amotion - amotion * status_get_homdex(bl) / 1000 - status_get_homagi(bl) * amotion / 250; - amotion = (amotion * status_calc_aspd(bl, sc, true) + status_calc_aspd(bl, sc, false)) / - 100 + amotion; + amotion = (reinterpret_cast(&bl))->homunculusDB->baseASPD; + amotion = amotion - amotion * status_get_homdex(&bl) / 1000 - status_get_homagi(&bl) * amotion / 250; + amotion = (amotion * status_calc_aspd(&bl, sc, true) + status_calc_aspd(&bl, sc, false)) / - 100 + amotion; #else - amotion = (1000 - 4 * status->agi - status->dex) * ((TBL_HOM*)bl)->homunculusDB->baseASPD / 1000; + amotion = (1000 - 4 * status->agi - status->dex) * (reinterpret_cast(&bl))->homunculusDB->baseASPD / 1000; - amotion = status_calc_aspd_rate(bl, sc, amotion); + amotion = status_calc_aspd_rate(&bl, sc, amotion); amotion = amotion * status->aspd_rate / 1000; #endif - amotion = status_calc_fix_aspd(bl, sc, amotion); + amotion = status_calc_fix_aspd(&bl, sc, amotion); status->amotion = cap_value(amotion, battle_config.max_aspd, 2000); status->adelay = status->amotion; - } else if ( bl->type&BL_PC ) { + } else if ( bl.type == BL_PC ) { uint16 skill_lv; amotion = status_base_amotion_pc(sd,status); #ifndef RENEWAL_ASPD - status->aspd_rate = status_calc_aspd_rate(bl, sc, b_status->aspd_rate); + status->aspd_rate = status_calc_aspd_rate(&bl, sc, b_status->aspd_rate); #endif // Absolute ASPD % modifiers amotion = amotion * status->aspd_rate / 1000; @@ -6079,21 +6117,21 @@ void status_calc_bl_main(struct block_list *bl, std::bitset flag) #ifdef RENEWAL_ASPD // RE ASPD % modifier - amotion += (max(0xc3 - amotion, 2) * (status->aspd_rate2 + status_calc_aspd(bl, sc, false))) / 100; + amotion += (max(0xc3 - amotion, 2) * (status->aspd_rate2 + status_calc_aspd(&bl, sc, false))) / 100; amotion = 10 * (200 - amotion); amotion += sd->bonus.aspd_add; #endif - amotion = status_calc_fix_aspd(bl, sc, amotion); + amotion = status_calc_fix_aspd(&bl, sc, amotion); status->amotion = cap_value(amotion,pc_maxaspd(sd),2000); status->adelay = 2 * status->amotion; } else { // Mercenary and mobs amotion = b_status->amotion; - status->aspd_rate = status_calc_aspd_rate(bl, sc, b_status->aspd_rate); + status->aspd_rate = status_calc_aspd_rate(&bl, sc, b_status->aspd_rate); amotion = amotion*status->aspd_rate/1000; - amotion = status_calc_fix_aspd(bl, sc, amotion); + amotion = status_calc_fix_aspd(&bl, sc, amotion); status->amotion = cap_value(amotion, battle_config.monster_max_aspd, 2000); temp = b_status->adelay*status->aspd_rate/1000; @@ -6103,71 +6141,71 @@ void status_calc_bl_main(struct block_list *bl, std::bitset flag) if(flag[SCB_DSPD]) { int dmotion; - if( bl->type&BL_PC ) { + if( bl.type == BL_PC ) { if (b_status->agi == status->agi) - status->dmotion = status_calc_dmotion(bl, sc, b_status->dmotion); + status->dmotion = status_calc_dmotion(&bl, sc, b_status->dmotion); else { dmotion = 800-status->agi*4; status->dmotion = cap_value(dmotion, 400, 800); if(battle_config.pc_damage_delay_rate != 100) status->dmotion = status->dmotion*battle_config.pc_damage_delay_rate/100; // It's safe to ignore b_status->dmotion since no bonus affects it. - status->dmotion = status_calc_dmotion(bl, sc, status->dmotion); + status->dmotion = status_calc_dmotion(&bl, sc, status->dmotion); } - } else if( bl->type&BL_HOM ) { + } else if( bl.type == BL_HOM ) { dmotion = 800-status->agi*4; status->dmotion = cap_value(dmotion, 400, 800); - status->dmotion = status_calc_dmotion(bl, sc, b_status->dmotion); + status->dmotion = status_calc_dmotion(&bl, sc, b_status->dmotion); } else { // Mercenary and mobs - status->dmotion = status_calc_dmotion(bl, sc, b_status->dmotion); + status->dmotion = status_calc_dmotion(&bl, sc, b_status->dmotion); } } #ifdef RENEWAL if (flag[SCB_PATK]) { if (status->pow == b_status->pow && status->con == b_status->con) - status->patk = status_calc_patk(bl, sc, b_status->patk); + status->patk = status_calc_patk(&bl, sc, b_status->patk); else - status->patk = status_calc_patk(bl, sc, b_status->patk + (status->pow - b_status->pow) / 3 + (status->con - b_status->con) / 5); + status->patk = status_calc_patk(&bl, sc, b_status->patk + (status->pow - b_status->pow) / 3 + (status->con - b_status->con) / 5); } if (flag[SCB_SMATK]) { if (status->spl == b_status->spl && status->con == b_status->con) - status->smatk = status_calc_smatk(bl, sc, b_status->smatk); + status->smatk = status_calc_smatk(&bl, sc, b_status->smatk); else - status->smatk = status_calc_smatk(bl, sc, b_status->smatk) + (status->spl - b_status->spl) / 3 + (status->con - b_status->con) / 5; + status->smatk = status_calc_smatk(&bl, sc, b_status->smatk) + (status->spl - b_status->spl) / 3 + (status->con - b_status->con) / 5; } if (flag[SCB_RES]) { if (status->sta == b_status->sta) - status->res = status_calc_res(bl, sc, b_status->res); + status->res = status_calc_res(&bl, sc, b_status->res); else - status->res = status_calc_res(bl, sc, b_status->res + (status->sta - b_status->sta) + (status->sta - b_status->sta) / 3 * 5); + status->res = status_calc_res(&bl, sc, b_status->res + (status->sta - b_status->sta) + (status->sta - b_status->sta) / 3 * 5); } if (flag[SCB_MRES]) { if (status->wis == b_status->wis) - status->mres = status_calc_mres(bl, sc, b_status->mres); + status->mres = status_calc_mres(&bl, sc, b_status->mres); else - status->mres = status_calc_mres(bl, sc, b_status->mres + (status->wis - b_status->wis) + (status->wis - b_status->wis) / 3 * 5); + status->mres = status_calc_mres(&bl, sc, b_status->mres + (status->wis - b_status->wis) + (status->wis - b_status->wis) / 3 * 5); } if (flag[SCB_HPLUS]) { if (status->crt == b_status->crt) - status->hplus = status_calc_hplus(bl, sc, b_status->hplus); + status->hplus = status_calc_hplus(&bl, sc, b_status->hplus); else - status->hplus = status_calc_hplus(bl, sc, b_status->hplus + (status->crt - b_status->crt)); + status->hplus = status_calc_hplus(&bl, sc, b_status->hplus + (status->crt - b_status->crt)); } if (flag[SCB_CRATE]) { if (status->crt == b_status->crt) - status->crate = status_calc_crate(bl, sc, b_status->crate); + status->crate = status_calc_crate(&bl, sc, b_status->crate); else - status->crate = status_calc_crate(bl, sc, b_status->crate + (status->crt - b_status->crt) / 3); + status->crate = status_calc_crate(&bl, sc, b_status->crate + (status->crt - b_status->crt) / 3); } if (flag[SCB_MAXAP]) { - if (bl->type&BL_PC) { + if (bl.type == BL_PC) { status->max_ap = status_calc_maxap_pc(sd); if (battle_config.ap_rate != 100) @@ -6175,7 +6213,7 @@ void status_calc_bl_main(struct block_list *bl, std::bitset flag) status->max_ap = umin(status->max_ap, (unsigned int)battle_config.max_ap); } else - status->max_ap = status_calc_maxap(bl, b_status->max_ap); + status->max_ap = status_calc_maxap(&bl, b_status->max_ap); if (status->ap > status->max_ap) { status->ap = status->max_ap; @@ -6184,11 +6222,11 @@ void status_calc_bl_main(struct block_list *bl, std::bitset flag) } #endif - if((flag[SCB_VIT] || flag[SCB_MAXHP] || flag[SCB_INT] || flag[SCB_MAXSP]) && bl->type &BL_REGEN) - status_calc_regen(bl, status, status_get_regen_data(bl)); + if((flag[SCB_VIT] || flag[SCB_MAXHP] || flag[SCB_INT] || flag[SCB_MAXSP]) && bl.type & BL_REGEN) + status_calc_regen(&bl, status, status_get_regen_data(&bl)); - if(flag[SCB_REGEN] && bl->type&BL_REGEN) - status_calc_regen_rate(bl, status_get_regen_data(bl), sc); + if(flag[SCB_REGEN] && bl.type & BL_REGEN) + status_calc_regen_rate(&bl, status_get_regen_data(&bl), sc); } /** @@ -6239,7 +6277,7 @@ void status_calc_bl_(struct block_list* bl, std::bitset flag, uint8 opt if (opt&SCO_FIRST && bl->type == BL_MOB) return; // Assume there will be no statuses active - status_calc_bl_main(bl, flag); + status_calc_bl_main(*bl, flag); if (opt&SCO_FIRST && bl->type == BL_HOM) return; // Client update handled by caller @@ -8066,7 +8104,7 @@ static unsigned short status_calc_speed(struct block_list *bl, status_change *sc if( sc->getSCE(SC_RUN) ) val = max( val, 55 ); if( sc->getSCE(SC_AVOID) ) - val = max( val, 10 * sc->getSCE(SC_AVOID)->val1 ); + val = max( val, sc->getSCE(SC_AVOID)->val2 ); if (sc->getSCE(SC_INVINCIBLE)) val = max(val, sc->getSCE(SC_INVINCIBLE)->val3); if( sc->getSCE(SC_CLOAKINGEXCEED) ) @@ -11444,7 +11482,11 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty // val4 signals autoprovoke. break; case SC_AVOID: - // val2 = 10*val1; // Speed change rate. + // Speed change rate. + if (bl->type == BL_HOM) + val2 = 40 * val1; + else + val2 = 10 * val1; break; case SC_DEFENCE: #ifdef RENEWAL diff --git a/src/map/status.hpp b/src/map/status.hpp index 1db334c11ea..65f01251a21 100644 --- a/src/map/status.hpp +++ b/src/map/status.hpp @@ -3058,6 +3058,8 @@ enum e_status_change_flag : uint16 { SCF_REMOVEONUNEQUIPARMOR, SCF_REMOVEONHERMODE, SCF_REQUIRENOWEAPON, + SCF_REMOVEFROMHOMONWARP, + SCF_REMOVEFROMHOMONMAPWARP, SCF_MAX };