From c07f685a31ea1323ff16c5f6a201e7a14ae2f432 Mon Sep 17 00:00:00 2001 From: Daegaladh Date: Mon, 16 Sep 2024 18:36:05 +0200 Subject: [PATCH] Fixes Vanilmirth skills --- db/pre-re/skill_db.yml | 25 +++++----------- db/re/skill_db.yml | 26 +++++------------ src/map/clif.cpp | 4 ++- src/map/skill.cpp | 66 +++++++++++++++++------------------------- src/map/status.cpp | 6 ++-- src/map/unit.cpp | 27 +++++++++++++++++ 6 files changed, 75 insertions(+), 79 deletions(-) diff --git a/db/pre-re/skill_db.yml b/db/pre-re/skill_db.yml index f7cd7e6f3e..c7a71caeca 100644 --- a/db/pre-re/skill_db.yml +++ b/db/pre-re/skill_db.yml @@ -31026,19 +31026,7 @@ Body: MaxLevel: 5 Type: Magic TargetType: Attack - Range: 15 - Hit: Single - HitCount: - - Level: 1 - Count: 1 - - Level: 2 - Count: 2 - - Level: 3 - Count: 3 - - Level: 4 - Count: 4 - - Level: 5 - Count: 5 + Range: 9 Requires: SpCost: - Level: 1 @@ -31055,10 +31043,10 @@ Body: Name: HVAN_CHAOTIC Description: Benediction of Chaos MaxLevel: 5 + Type: Magic TargetType: Self DamageFlags: NoDamage: true - Hit: Single AfterCastWalkDelay: 1500 Requires: SpCost: 40 @@ -31066,8 +31054,6 @@ Body: Name: HVAN_INSTRUCT Description: Instruct MaxLevel: 5 - DamageFlags: - NoDamage: true - Id: 8016 Name: HVAN_EXPLOSION Description: Bio Explosion @@ -31079,10 +31065,13 @@ Body: IgnoreElement: true IgnoreFlee: true IgnoreDefCard: true + Flags: + TargetTrap: true Hit: Single HitCount: 1 - Element: Weapon - SplashArea: 4 + Element: Neutral + SplashArea: 5 + Duration1: 1500 Requires: SpCost: 1 - Id: 8018 diff --git a/db/re/skill_db.yml b/db/re/skill_db.yml index 348c45bac2..0dfd59b95e 100644 --- a/db/re/skill_db.yml +++ b/db/re/skill_db.yml @@ -43312,19 +43312,7 @@ Body: MaxLevel: 5 Type: Magic TargetType: Attack - Range: 15 - Hit: Single - HitCount: - - Level: 1 - Count: 1 - - Level: 2 - Count: 2 - - Level: 3 - Count: 3 - - Level: 4 - Count: 4 - - Level: 5 - Count: 5 + Range: 9 Cooldown: - Level: 1 Time: 2000 @@ -43352,10 +43340,10 @@ Body: Name: HVAN_CHAOTIC Description: Benediction of Chaos MaxLevel: 5 + Type: Magic TargetType: Self DamageFlags: NoDamage: true - Hit: Single AfterCastWalkDelay: 1500 Cooldown: 3000 Requires: @@ -43364,8 +43352,6 @@ Body: Name: HVAN_INSTRUCT Description: Instruct MaxLevel: 5 - DamageFlags: - NoDamage: true - Id: 8016 Name: HVAN_EXPLOSION Description: Bio Explosion @@ -43377,11 +43363,13 @@ Body: IgnoreElement: true IgnoreFlee: true IgnoreDefCard: true + Flags: + TargetTrap: true Hit: Single HitCount: 1 - Element: Weapon - SplashArea: 4 - AfterCastActDelay: 5000 + Element: Neutral + SplashArea: 5 + Duration1: 1500 CoolDown: 1000 Requires: SpCost: 1 diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 29e25c8111..575867ded2 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -15457,6 +15457,9 @@ void clif_parse_HomMoveTo(int fd, map_session_data *sd){ else return; + if (x < 0 || y < 0 || x == bl->x || y == bl->y) + return; + unit_walktoxy(bl, x, y, 4); } @@ -15479,7 +15482,6 @@ void clif_parse_HomAttack(int fd,map_session_data *sd) bl = &sd->md->bl; else return; - unit_stop_attack(bl); unit_attack(bl, target_id, action_type != 0); } diff --git a/src/map/skill.cpp b/src/map/skill.cpp index a796625ffe..2e3af91be0 100755 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -3811,12 +3811,12 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list * dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, CR_HOLYCROSS, -1, DMG_SPLASH); break; //Skills that need be passed as a normal attack for the client to display correctly. - case HVAN_EXPLOSION: case NPC_SELFDESTRUCTION: if(src->type == BL_PC) dmg.blewcount = 10; dmg.amotion = 0; //Disable delay or attack will do no damage since source is dead by the time it takes effect. [Skotlex] [[fallthrough]]; + case HVAN_EXPLOSION: case KN_AUTOCOUNTER: case NPC_CRITICALSLASH: case TF_DOUBLE: @@ -4761,6 +4761,9 @@ static TIMER_FUNC(skill_timerskill){ case ABC_FRENZY_SHOT: skill_castend_damage_id(src, target, skl->skill_id, skl->skill_lv, tick, skl->flag); break; + case HVAN_EXPLOSION: + status_kill(src); + break; default: skill_attack(skl->type,src,src,target,skl->skill_id,skl->skill_lv,tick,skl->flag); break; @@ -6194,16 +6197,9 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint case HVAN_CAPRICE: //[blackhole89] { - int ran=rnd()%4; - int sid = 0; - switch(ran) - { - case 0: sid=MG_COLDBOLT; break; - case 1: sid=MG_FIREBOLT; break; - case 2: sid=MG_LIGHTNINGBOLT; break; - case 3: sid=WZ_EARTHSPIKE; break; - } - skill_attack(BF_MAGIC,src,src,bl,sid,skill_lv,tick,flag|SD_LEVEL); + static const e_skill subskills[] = { MG_COLDBOLT, MG_FIREBOLT, MG_LIGHTNINGBOLT, WZ_EARTHSPIKE }; + e_skill subskill_id = subskills[rnd()%ARRAYLENGTH(subskills)]; + skill_attack(skill_get_type(subskill_id), src, src, bl, subskill_id, skill_lv, tick, flag); } break; @@ -6323,7 +6319,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint [[fallthrough]]; case HVAN_EXPLOSION: if (src != bl) - skill_attack(BF_MISC,src,src,bl,skill_id,skill_lv,tick,flag); + skill_attack(skill_get_type(skill_id),src,src,bl,skill_id,skill_lv,tick,flag); break; // Celest @@ -8816,13 +8812,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui BF_MAGIC, src, src, skill_id, skill_lv, tick, flag, BCT_ENEMY); break; - case HVAN_EXPLOSION: //[orn] case NPC_SELFDESTRUCTION: //Self Destruction hits everyone in range (allies+enemies) //Except for Summoned Marine spheres on non-versus maps, where it's just enemy. i = ((!md || md->special_state.ai == AI_SPHERE) && !map_flag_vs(src->m))? BCT_ENEMY:BCT_ALL; - clif_skill_nodamage(src, src, skill_id, -1, 1); map_delblock(src); //Required to prevent chain-self-destructions hitting back. map_foreachinshootrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), BL_CHAR|BL_SKILL, @@ -8832,14 +8826,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui map_freeblock_unlock(); return 1; } - status_damage(src, src, sstatus->max_hp,0,0,1, skill_id); - if(skill_id == HVAN_EXPLOSION && src->type == BL_HOM) { - homun_data& hd = reinterpret_cast( *src ); - - hd.homunculus.intimacy = hom_intimacy_grade2intimacy(HOMGRADE_HATE_WITH_PASSION); - - clif_send_homdata( hd, SP_INTIMATE ); - } + status_kill(src); break; case AL_ANGELUS: #ifdef RENEWAL @@ -10695,25 +10682,26 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui clif_skill_fail( *sd, skill_id ); break; case HVAN_CHAOTIC: //[orn] - { - static const int per[5][2]={{20,50},{50,60},{25,75},{60,64},{34,67}}; - int r = rnd()%100; - i = (skill_lv-1)%5; - if(r(1, skill_lv), true); - if (!bl) bl = src; - i = skill_calc_heal(src, bl, skill_id, 1+rnd()%skill_lv, true); - //Eh? why double skill packet? - clif_skill_nodamage(src,bl,AL_HEAL,i,1); - clif_skill_nodamage(src,bl,skill_id,i,1); - status_heal(bl, i, 0, 0); - } + // Official servers send the Heal skill packet with the healed amount, and then the skill packet with 1 as healed amount + clif_skill_nodamage(src, bl, AL_HEAL, i, 1); + clif_skill_nodamage(src, bl, skill_id, 1, 1); + status_heal(bl, i, 0, 0); break; + case HVAN_EXPLOSION: + { + clif_skill_nodamage(src, src, skill_id, skill_lv, 1); + map_foreachinshootrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), BL_CHAR | BL_SKILL, src, skill_id, skill_lv, tick, flag | BCT_ENEMY, skill_castend_damage_id); + + homun_data& hd = reinterpret_cast(*src); + hd.homunculus.intimacy = hom_intimacy_grade2intimacy(HOMGRADE_HATE_WITH_PASSION); + clif_send_homdata(hd, SP_INTIMATE); + + // There's a delay between splash damage and the homunculus death + skill_addtimerskill(src, tick + skill_get_time(skill_id, skill_lv), src->id, 0, 0, skill_id, skill_lv, 0, flag); + break; + } // Homun single-target support skills [orn] case HLIF_CHANGE: #ifndef RENEWAL diff --git a/src/map/status.cpp b/src/map/status.cpp index 2a0710d4c7..7cf60ca540 100644 --- a/src/map/status.cpp +++ b/src/map/status.cpp @@ -5046,8 +5046,10 @@ int status_calc_homunculus_(struct homun_data *hd, uint8 opt) status->def += skill_lv * 4; if((skill_lv = hom_checkskill(hd, HVAN_INSTRUCT)) > 0) { - status->int_ += 1 + skill_lv / 2 + skill_lv / 4 + skill_lv / 5; - status->str += 1 + skill_lv / 3 + skill_lv / 3 + skill_lv / 4; + static const uint8 bonus_int[] = { 1, 2, 2, 4, 5 }; + static const uint8 bonus_str[] = { 1, 1, 3, 4, 4 }; + status->int_ += bonus_int[skill_lv - 1]; + status->str += bonus_str[skill_lv - 1]; } if((skill_lv = hom_checkskill(hd, HAMI_SKIN)) > 0) diff --git a/src/map/unit.cpp b/src/map/unit.cpp index 230949bcb2..53ed8eeb21 100644 --- a/src/map/unit.cpp +++ b/src/map/unit.cpp @@ -1831,6 +1831,33 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui target_id = target->id; break; + case HVAN_CHAOTIC: + { + // Chance per skill level + static const uint8 chance_table[2][5] = { + { 20, 50, 25, 50, 34 }, // Homunculus + { 30, 10, 50, 4, 33 } // Master + }; + + uint8 chance = rnd_value(1, 100); + + // Homunculus + if (chance <= chance_table[0][skill_lv - 1]) + target = src; + // Master + else if (chance <= (chance_table[0][skill_lv - 1] + chance_table[1][skill_lv - 1])) + target = battle_get_master(src); + // Enemy + else + target = map_id2bl(battle_gettarget(src)); + + // If there's no enemy the chance reverts to the homunculus + if (target == nullptr) + target = src; + + target_id = target->id; + break; + } case MH_SONIC_CRAW: case MH_TINDER_BREAKER: { int skill_id2 = ((skill_id==MH_SONIC_CRAW)?MH_MIDNIGHT_FRENZY:MH_EQC);