diff --git a/db/pre-re/skill_db.yml b/db/pre-re/skill_db.yml index 5dc034633d..f7cd7e6f3e 100644 --- a/db/pre-re/skill_db.yml +++ b/db/pre-re/skill_db.yml @@ -30822,7 +30822,6 @@ Body: TargetType: Self DamageFlags: NoDamage: true - Hit: Single AfterCastActDelay: 1000 AfterCastWalkDelay: 1000 Requires: @@ -30834,7 +30833,6 @@ Body: TargetType: Self DamageFlags: NoDamage: true - Hit: Single AfterCastActDelay: 30000 AfterCastWalkDelay: 1000 Duration1: @@ -30865,8 +30863,6 @@ Body: Name: HAMI_SKIN Description: Adamantium Skin MaxLevel: 5 - DamageFlags: - NoDamage: true - Id: 8008 Name: HAMI_BLOODLUST Description: Bloodlust @@ -30874,7 +30870,6 @@ Body: TargetType: Self DamageFlags: NoDamage: true - Hit: Single AfterCastActDelay: - Level: 1 Time: 300000 diff --git a/db/pre-re/status.yml b/db/pre-re/status.yml index 92ad77b8f2..91f92fd45d 100644 --- a/db/pre-re/status.yml +++ b/db/pre-re/status.yml @@ -2496,6 +2496,9 @@ Body: CalcFlags: Batk: true Watk: true + Flags: + NoSave: true + RemoveFromHomOnWarp: true - Status: Fleet DurationLookup: HFLI_FLEET CalcFlags: @@ -2510,6 +2513,10 @@ Body: DurationLookup: HAMI_DEFENCE CalcFlags: Def: true + Vit: true + Flags: + NoSave: true + RemoveFromHomOnWarp: true - Status: Incaspdrate CalcFlags: Aspd: true diff --git a/db/re/skill_db.yml b/db/re/skill_db.yml index eb8f3251b7..348c45bac2 100644 --- a/db/re/skill_db.yml +++ b/db/re/skill_db.yml @@ -43106,7 +43106,6 @@ Body: TargetType: Self DamageFlags: NoDamage: true - Hit: Single AfterCastWalkDelay: 1000 Cooldown: 1000 Requires: @@ -43118,7 +43117,6 @@ Body: TargetType: Self DamageFlags: NoDamage: true - Hit: Single AfterCastWalkDelay: 1000 Duration1: - Level: 1 @@ -43149,8 +43147,6 @@ Body: Name: HAMI_SKIN Description: Adamantium Skin MaxLevel: 5 - DamageFlags: - NoDamage: true - Id: 8008 Name: HAMI_BLOODLUST Description: Bloodlust @@ -43158,7 +43154,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 3c6aafca15..d1692dc5d9 100644 --- a/db/re/status.yml +++ b/db/re/status.yml @@ -2618,6 +2618,9 @@ Body: CalcFlags: Batk: true Watk: true + Flags: + NoSave: true + RemoveFromHomOnMapWarp: true - Status: Fleet DurationLookup: HFLI_FLEET CalcFlags: @@ -2631,7 +2634,11 @@ Body: - Status: Defence DurationLookup: HAMI_DEFENCE CalcFlags: + Def: true Vit: true + Flags: + NoSave: true + RemoveFromHomOnMapWarp: true - Status: Incaspdrate CalcFlags: Aspd: true diff --git a/doc/status_change.txt b/doc/status_change.txt index a4b7264b77..7ac1fe1906 100644 --- a/doc/status_change.txt +++ b/doc/status_change.txt @@ -1012,9 +1012,12 @@ SC_CHANGE (EFST_HLIF_CHANGE) val2: VIT increase (20 * val1) val3: INT increase (30 * val1) -SC_BLOODLUST () - desc: - val1: +SC_BLOODLUST (EFST_HAMI_BLOODLUST) + desc: Increase the homunculus ATK and has a chance to leech HP from the target + val1: Skill Level + val2: ATK increase (20 + (10 * val1)) + val3: Chance to leech HP (9 * val1)% + val4: Leeched HP percentage 20% SC_FLEET () desc: @@ -1024,10 +1027,10 @@ SC_SPEED () desc: val1: -SC_DEFENCE () - desc: Increase Defense, HAMI_DEFENCE effect - val1: (none) - val2: + Def(Pre-renewal) or VIT (Renewal) +SC_DEFENCE (EFST_HAMI_DEFENCE) + desc: Increase VIT and as result VIT-based DEF of the Player and plain VIT of the Homunculus + val1: Skill Level + val2: VIT increase for players, DEF increase for homunculus (5 + (5 * val1)) [Renewal], (2 * val1) [Pre-Renewal] SC_INCASPDRATE () desc: Increase ASPD diff --git a/src/map/battle.cpp b/src/map/battle.cpp index 5889923ae8..52cf218c58 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -1900,8 +1900,8 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam } } - if ((sce = sc->getSCE(SC_BLOODLUST)) && flag&BF_WEAPON && damage > 0 && rnd()%100 < sce->val3) - status_heal(src, damage * sce->val4 / 100, 0, 3); + if ((sce = sc->getSCE(SC_BLOODLUST)) && flag & BF_WEAPON && damage > 0 && rnd_chance(sce->val3, 100)) + status_heal(src, damage * sce->val4 / 100, 0, 1); if ((sce = sc->getSCE(SC_BLOODSUCKER)) && flag & BF_WEAPON && damage > 0 && rnd() % 100 < (2 * sce->val1 - 1)) status_heal(src, damage * sce->val1 / 100, 0, 3); diff --git a/src/map/skill.cpp b/src/map/skill.cpp index 5112236830..64287c2ded 100755 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -8236,8 +8236,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; case HLIF_AVOID: case HAMI_DEFENCE: - sc_start(src,bl,type,100,skill_lv,skill_get_time(skill_id,skill_lv)); // Master - clif_skill_nodamage(src,src,skill_id,skill_lv,sc_start(src,src,type,100,skill_lv,skill_get_time(skill_id,skill_lv))); // Homunc + // Master + sc_start(src, bl, type, 100, skill_lv, skill_get_time(skill_id, skill_lv)); + // Homunculus + clif_skill_nodamage(src, src, skill_id, skill_lv, sc_start(src, src, type, 100, skill_lv, skill_get_time(skill_id, skill_lv))); break; case NJ_BUNSINJYUTSU: status_change_end(bl, SC_BUNSINJYUTSU); // on official recasting cancels existing mirror image [helvetica] @@ -10670,23 +10672,26 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case HAMI_CASTLE: //[orn] if (src != bl && rnd_chance(20 * skill_lv, 100)) { - int x = src->x, y = src->y; + // Get one of the monsters targeting the player and set the homunculus as its new target + if (block_list* tbl = battle_getenemy(bl, BL_MOB, AREA_SIZE); tbl != nullptr) { + if (unit_data* ud = unit_bl2ud(tbl); ud != nullptr) + unit_changetarget_sub(*ud, *src); + } - // Move source - if (unit_movepos(src,bl->x,bl->y,0,0)) { - clif_skill_nodamage(src,src,skill_id,skill_lv,1); // Homunc + int16 x = src->x, y = src->y; + // Move homunculus + if (unit_movepos(src, bl->x, bl->y, 0, false)) { clif_blown(src); - // Move target - if (unit_movepos(bl,x,y,0,0)) { - clif_skill_nodamage(bl,bl,skill_id,skill_lv,1); + // Move player + if (unit_movepos(bl, x, y, 0, false)) clif_blown(bl); - } - map_foreachinallrange(unit_changetarget,src,AREA_SIZE,BL_MOB,bl,src); + // Show the animation on the homunculus only + clif_skill_nodamage(src, src, skill_id, skill_lv, 1); } } - else if (hd && hd->master) // Failed + else if (hd != nullptr && hd->master != nullptr) clif_skill_fail( *hd->master, skill_id ); - else if (sd) + else if (sd != nullptr) clif_skill_fail( *sd, skill_id ); break; case HVAN_CHAOTIC: //[orn] diff --git a/src/map/status.cpp b/src/map/status.cpp index 3afe5c9c00..f9e229de41 100644 --- a/src/map/status.cpp +++ b/src/map/status.cpp @@ -6686,10 +6686,8 @@ static unsigned short status_calc_vit(struct block_list *bl, status_change *sc, vit -= vit * sc->getSCE(SC_STRIPARMOR)->val2/100; if(sc->getSCE(SC_FULL_THROTTLE)) vit += vit * sc->getSCE(SC_FULL_THROTTLE)->val3 / 100; -#ifdef RENEWAL - if(sc->getSCE(SC_DEFENCE)) + if(bl->type == BL_PC && sc->getSCE(SC_DEFENCE)) vit += sc->getSCE(SC_DEFENCE)->val2; -#endif if(sc->getSCE(SC_CHEERUP)) vit += 3; if(sc->getSCE(SC_GLASTHEIM_STATE)) @@ -7707,10 +7705,9 @@ static defType status_calc_def(struct block_list *bl, status_change *sc, int def #ifdef RENEWAL if (sc->getSCE(SC_ASSUMPTIO)) def += sc->getSCE(SC_ASSUMPTIO)->val1 * 50; -#else - if(sc->getSCE(SC_DEFENCE)) - def += sc->getSCE(SC_DEFENCE)->val2; #endif + if (bl->type == BL_HOM && sc->getSCE(SC_DEFENCE)) + def += sc->getSCE(SC_DEFENCE)->val2; if(sc->getSCE(SC_INCDEFRATE)) def += def * sc->getSCE(SC_INCDEFRATE)->val1/100; if(sc->getSCE(SC_EARTH_INSIGNIA) && sc->getSCE(SC_EARTH_INSIGNIA)->val1 == 2) @@ -11506,16 +11503,21 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty val2 = 10 * val1; break; case SC_DEFENCE: + // Vit bonus for players / Def bonus for homunculus #ifdef RENEWAL - val2 = 5 + (val1 * 5); // Vit bonus + val2 = 5 + (5 * val1); #else - val2 = 2*val1; // Def bonus + val2 = 2 * val1; #endif break; case SC_BLOODLUST: - val2 = 20+10*val1; // Atk rate change. - val3 = 3*val1; // Leech chance - val4 = 20; // Leech percent + // Atk rate change + val2 = 20 + (10 * val1); + // Leech chance + // It's actually 9 * level on both pre-re and renewal, despite the description + val3 = 9 * val1; + // Leech percent + val4 = 20; break; case SC_FLEET: val2 = 30*val1; // Aspd change diff --git a/src/map/unit.cpp b/src/map/unit.cpp index 9153eb7049..1bff17e9fd 100644 --- a/src/map/unit.cpp +++ b/src/map/unit.cpp @@ -3130,32 +3130,44 @@ int unit_counttargeted(struct block_list* bl) * @param src Current target * @param target New target **/ -int unit_changetarget(struct block_list *bl, va_list ap) { - struct unit_data *ud = unit_bl2ud(bl); - struct block_list *src = va_arg(ap,struct block_list *); - struct block_list *target = va_arg(ap,struct block_list *); - - if (!ud || !target || ud->target == target->id) +int unit_changetarget(block_list *bl, va_list ap) { + if (bl == nullptr) return 1; - if (!ud->target && !ud->target_to) + unit_data *ud = unit_bl2ud(bl); + block_list *src = va_arg(ap, block_list *); + block_list *target = va_arg(ap, block_list *); + + if (ud == nullptr || src == nullptr || target == nullptr || ud->target == target->id) + return 1; + if (ud->target <= 0 && ud->target_to <= 0) return 1; if (ud->target != src->id && ud->target_to != src->id) return 1; - if (bl->type == BL_MOB) - (BL_CAST(BL_MOB,bl))->target_id = target->id; - if (ud->target_to) - ud->target_to = target->id; - else - ud->target_to = 0; - if (ud->skilltarget) - ud->skilltarget = target->id; - unit_set_target(ud, target->id); + unit_changetarget_sub(*ud, *target); //unit_attack(bl, target->id, ud->state.attack_continue); return 0; } +/** + * Changes the target of a unit + * @param ud: Unit data + * @param target: New target data + **/ +void unit_changetarget_sub(unit_data& ud, block_list& target) { + if (status_isdead(target)) + return; + + if (ud.bl->type == BL_MOB) + reinterpret_cast(ud.bl)->target_id = target.id; + if (ud.target_to > 0) + ud.target_to = target.id; + if (ud.skilltarget > 0) + ud.skilltarget = target.id; + unit_set_target(&ud, target.id); +} + /** * Removes a bl/ud from the map * On kill specifics are not performed here, check status_damage() diff --git a/src/map/unit.hpp b/src/map/unit.hpp index eaa4e990b7..ba3030d330 100644 --- a/src/map/unit.hpp +++ b/src/map/unit.hpp @@ -172,8 +172,8 @@ void unit_free_pc(map_session_data *sd); #define unit_remove_map(bl,clrtype) unit_remove_map_(bl,clrtype,__FILE__,__LINE__,__func__) int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file, int line, const char* func); int unit_free(struct block_list *bl, clr_type clrtype); -int unit_changeviewsize(struct block_list *bl,short size); -int unit_changetarget(struct block_list *bl,va_list ap); +int unit_changetarget(block_list *bl,va_list ap); +void unit_changetarget_sub(unit_data& ud, block_list& target); // Shadow Scar void unit_addshadowscar(unit_data &ud, int interval);