From 061e586a1fc7330a0f98ac0c6076b6c6c840d6dc Mon Sep 17 00:00:00 2001 From: Aleos Date: Wed, 13 May 2020 21:02:57 -0400 Subject: [PATCH] Few Genetic skill fixes (#4813) * Fixes Acid Demonstration to use the target's VIT and not casters. * Fixes Fire Expansion - Acid to behave like Acid Demonstration. * Fixes Crazy Weed not doing 2 damage attacks. * Crazy Weed is now a long ranged physical attack. * Adjusts Hell's Plant behavior to no longer be removed on map change. * Adds missing status icon for Hell's Plant. * Fixes Hell's Plant attack formula when learning Summon Flora. * Hell's Plant now uses the caster's weapon as the element. * Hell's Plant no longer ignores the target's DEF and Element. * Fixes Hell's Plant removing Thorns Trap. * Removes fixed cast time from Xeno Slasher. * Adds new Genetic Pharmacy potions (items are disabled until int32 item ID support). * Fixes Spore Explosion's splash attack doing the same damage as the initial. Thanks to @teededung, @Badarosk0, @cahya1992, and @OptimusM! --- db/pre-re/skill_db.yml | 4 +-- db/re/item_db.txt | 7 ++++++ db/re/produce_db.txt | 4 +-- db/re/skill_db.yml | 16 +++--------- src/map/battle.cpp | 49 +++++++++++++----------------------- src/map/pc.cpp | 14 +++++++---- src/map/script_constants.hpp | 3 +++ src/map/skill.cpp | 13 ++-------- src/map/status.cpp | 5 +++- src/map/status.hpp | 3 +++ src/map/unit.cpp | 1 - 11 files changed, 53 insertions(+), 66 deletions(-) diff --git a/db/pre-re/skill_db.yml b/db/pre-re/skill_db.yml index f9dffe81d0..a01fc0e56f 100644 --- a/db/pre-re/skill_db.yml +++ b/db/pre-re/skill_db.yml @@ -26706,8 +26706,8 @@ Body: DamageFlags: Splash: true Range: 11 - Hit: Single - HitCount: 3 + Hit: Multi_Hit + HitCount: 2 Element: Weapon SplashArea: - Level: 1 diff --git a/db/re/item_db.txt b/db/re/item_db.txt index 32f4bc30d2..0c7c77e842 100644 --- a/db/re/item_db.txt +++ b/db/re/item_db.txt @@ -13457,3 +13457,10 @@ //=================================================================== 32350,Farthezan,Farthezan,5,20,,1100,130:180,,1,2,0x00004000,56,2,2,4,170,1,2,{ .@r = getrefine(); bonus2 bSkillAtk,"PA_PRESSURE",40; bonus bVariableCastrate,-.@r; if (.@r>=9) bonus2 bSkillAtk,"LG_RAYOFGENESIS",30; if (.@r>=11) { bonus2 bSkillAtk,"LG_RAYOFGENESIS",20; bonus2 bSkillAtk,"PA_PRESSURE",20; } },{},{} 32351,Estal,Estal,5,20,,700,195,,1,2,0x00040000,56,2,2,4,170,1,2,{ .@r = getrefine(); bonus2 bSkillCooldown,"GN_SPORE_EXPLOSION",-1000; bonus bBaseAtk,4*.@r; if (.@r>=11) .@val = 50; else if (.@r>=9) .@val = 30; bonus2 bSkillAtk,"GN_SPORE_EXPLOSION",.@val; },{},{} + +//100231,Ref_T_Potion,Golden X,0,10,,30,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_REF_T_POTION,30000,0; },{},{} +//100232,Add_Atk_Potion,Red Herb Activator,0,10,,30,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_ADD_ATK_DAMAGE,500000,15; },{},{} +//100233,Add_Matk_Potion,Blue Herb Activator,0,10,,30,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_ADD_MATK_DAMAGE,500000,15; },{},{} +//1100003,Concentrated_R_P,Concentrated Red Potion,0,10,,2,,,,,0xFFFFFFFF,63,2,,,120,,,{ itemheal rand(655,675),0; },{},{} +//1100004,Concentrated_B_P,Concentrated Blue Potion,0,10,,2,,,,,0xFFFFFFFF,63,2,,,120,,,{ itemheal 0,rand(340,360); },{},{} +//1100005,Concentrated_G_P,Concentrated Gold Potion,0,10,,2,,,,,0xFFFFFFFF,63,2,,,180,,,{ itemheal rand(2730,2750),0; },{},{} diff --git a/db/re/produce_db.txt b/db/re/produce_db.txt index 6160b53b91..8016bc9fd0 100644 --- a/db/re/produce_db.txt +++ b/db/re/produce_db.txt @@ -665,8 +665,8 @@ //267,1100003,29,2497,1,1092,10,1093,10,11621,15 //-- Concentrated Blue Syrup Potion <-- GN_S_PHARMACY Lvl, 10 Empty Testtube, 10 Empty Potion Bottle, 15 Blue Syrup //268,1100004,29,2497,1,1092,10,1093,10,11624,15 -//-- Concentrated Golden Syrup Potion <-- GN_S_PHARMACY Lvl, 10 Empty Testtube, 10 Empty Potion Bottle, 15 White Syrup, 15 Yellow Syrup -//269,1100005,29,2497,1,1092,10,1093,10,11623,15,11622,15 +//-- Concentrated Golden Syrup Potion <-- GN_S_PHARMACY Lvl, 10 Empty Testtube, 10 Empty Potion Bottle, 15 White Syrup, 10 Yellow Syrup +//269,1100005,29,2497,1,1092,10,1093,10,11623,15,11622,10 //=============================================== //--------------------LEVEL 30----------- diff --git a/db/re/skill_db.yml b/db/re/skill_db.yml index e4226fda02..523b3f10c7 100644 --- a/db/re/skill_db.yml +++ b/db/re/skill_db.yml @@ -27990,6 +27990,7 @@ Body: Flags: TargetTrap: true IgnoreLandProtector: true + Range: 5 Hit: Multi_Hit HitCount: 2 Element: Weapon @@ -28177,15 +28178,9 @@ Body: Name: GN_FIRE_EXPANSION_ACID Description: Fire Expansion Acid MaxLevel: 10 - Type: Misc + Type: Weapon TargetType: Attack - DamageFlags: - IgnoreDefense: true - IgnoreFlee: true - Flags: - IgnoreBgReduction: true - IgnoreGvgReduction: true - Range: 11 + Range: 9 Hit: Multi_Hit HitCount: - Level: 1 @@ -28273,11 +28268,9 @@ Body: MaxLevel: 5 Type: Weapon TargetType: Attack - DamageFlags: - IgnoreElement: true - IgnoreDefCard: true Hit: Single HitCount: 1 + Element: Weapon CopyFlags: Skill: Reproduce: true @@ -34493,7 +34486,6 @@ Body: Time: 3500 Duration1: 500 Duration2: 120000 - FixedCastTime: 500 Requires: SpCost: - Level: 1 diff --git a/src/map/battle.cpp b/src/map/battle.cpp index b2d7d05fd2..205ae04655 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -1351,13 +1351,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam } #endif - if (sc->data[SC_DEFENDER] && - skill_id != NJ_ZENYNAGE && skill_id != KO_MUCHANAGE && -#ifdef RENEWAL - ((flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON) || skill_id == GN_FIRE_EXPANSION_ACID)) -#else - (flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON)) -#endif + if (sc->data[SC_DEFENDER] && skill_id != NJ_ZENYNAGE && skill_id != KO_MUCHANAGE && (flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON)) damage -= damage * sc->data[SC_DEFENDER]->val2 / 100; if(sc->data[SC_ADJUSTMENT] && (flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON)) @@ -1625,6 +1619,11 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam if (hd && (rnd()%100<50) ) hom_addspiritball(hd, 10); // According to WarpPortal, this is a flat 50% chance } + + if (flag & BF_WEAPON && (sce = sc->data[SC_ADD_ATK_DAMAGE])) + damage += damage * sce->val1 / 100; + if (flag & BF_MAGIC && (sce = sc->data[SC_ADD_MATK_DAMAGE])) + damage += damage * sce->val1 / 100; } //End of caster SC_ check if (tsc && tsc->count) { @@ -3902,9 +3901,10 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list * skillratio += 100 + 50 * skill_lv; #endif break; + case GN_FIRE_EXPANSION_ACID: #ifdef RENEWAL case CR_ACIDDEMONSTRATION: - skillratio += -100 + 200 * skill_lv + sstatus->int_ + sstatus->vit; // !TODO: Confirm status bonus + skillratio += -100 + 200 * skill_lv + sstatus->int_ + tstatus->vit; // !TODO: Confirm status bonus if (target->type == BL_PC) skillratio /= 2; break; @@ -4446,9 +4446,9 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list * RE_LVL_DMOD(100); break; case GN_SPORE_EXPLOSION: - if (wd->miscflag & 2048) - skillratio += 200; // Target - skillratio += -100 + 180 * skill_lv + sstatus->int_; + skillratio += -100 + 180 * skill_lv; + if (wd->miscflag & 8) + skillratio += 200 + sstatus->int_; // Target receives extra damage RE_LVL_DMOD(100); break; case GN_WALLOFTHORN: @@ -4488,7 +4488,7 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list * } break; case GN_HELLS_PLANT_ATK: - skillratio += -100 + 500 * skill_lv + sstatus->int_ * (10 - (sd ? pc_checkskill(sd, AM_CANNIBALIZE) : 0)); // !TODO: Confirm INT and Cannibalize bonus + skillratio += -100 + 500 * skill_lv + sstatus->int_ * (sd ? pc_checkskill(sd, AM_CANNIBALIZE) : 5); // !TODO: Confirm INT and Cannibalize bonus RE_LVL_DMOD(100); break; // Physical Elemantal Spirits Attack Skills @@ -5864,7 +5864,6 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl switch(skill_id) { case NJ_ISSEN: case ASC_BREAKER: - case GN_FIRE_EXPANSION_ACID: break; //These skills will do a card fix later default: #endif @@ -5885,7 +5884,6 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl case MC_CARTREVOLUTION: case MO_INVESTIGATE: case SR_GATEOFHELL: - case GN_FIRE_EXPANSION_ACID: case KO_BAKURETSU: //case NC_MAGMA_ERUPTION: // Forced to neutral element @@ -5945,7 +5943,6 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl switch (skill_id) { case NJ_ISSEN: case ASC_BREAKER: - case GN_FIRE_EXPANSION_ACID: return wd; //These skills will do a GVG fix later default: #endif @@ -6940,30 +6937,15 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list * md.damage = 0; } break; - case GN_FIRE_EXPANSION_ACID: -#ifdef RENEWAL - // Official Renewal formula [helvetica] - // damage = 7 * ((atk + matk)/skill level) * (target vit/100) - // skill is a "forced neutral" type skill, it benefits from weapon element but final damage - // is considered "neutral" for purposes of resistances - { - struct Damage atk = battle_calc_weapon_attack(src, target, skill_id, skill_lv, 0); - struct Damage matk = battle_calc_magic_attack(src, target, skill_id, skill_lv, 0); - md.damage = 7 * ((atk.damage/skill_lv + matk.damage/skill_lv) * tstatus->vit / 100 ); - - // AD benefits from endow/element but damage is forced back to neutral - md.damage = battle_attr_fix(src, target, md.damage, ELE_NEUTRAL, tstatus->def_ele, tstatus->ele_lv); - } - // Fall through -#else +#ifndef RENEWAL case CR_ACIDDEMONSTRATION: if(tstatus->vit+sstatus->int_) //crash fix md.damage = (int)((int64)7*tstatus->vit*sstatus->int_*sstatus->int_ / (10*(tstatus->vit+sstatus->int_))); else md.damage = 0; if (tsd) md.damage>>=1; -#endif break; +#endif case NJ_ZENYNAGE: case KO_MUCHANAGE: md.damage = skill_get_zeny(skill_id, skill_lv); @@ -7274,6 +7256,9 @@ int64 battle_calc_return_damage(struct block_list* bl, struct block_list *src, i if (sc && sc->data[SC_WHITEIMPRISON]) return 0; // White Imprison does not reflect any damage + if (ssc && ssc->data[SC_REF_T_POTION]) + return 0; + if (flag & BF_SHORT) {//Bounces back part of the damage. if ( (skill_get_inf2(skill_id, INF2_ISTRAP) || !status_reflect) && sd && sd->bonus.short_weapon_damage_return ) { rdamage += damage * sd->bonus.short_weapon_damage_return / 100; diff --git a/src/map/pc.cpp b/src/map/pc.cpp index ded9f0889e..be33c709d3 100755 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -5822,6 +5822,7 @@ enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, in int16 m = map_mapindex2mapid(mapindex); struct map_data *mapdata = map_getmapdata(m); + status_change *sc = status_get_sc(&sd->bl); sd->state.changemap = (sd->mapindex != mapindex); sd->state.warping = 1; @@ -5842,8 +5843,8 @@ enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, in bg_team_leave(sd, false, true); sd->state.pmap = sd->bl.m; - if (sd->sc.count) { // Cancel some map related stuff. - if (sd->sc.data[SC_JAILED]) + if (sc && sc->count) { // Cancel some map related stuff. + if (sc->data[SC_JAILED]) return SETPOS_MAPINDEX; //You may not get out! status_change_end(&sd->bl, SC_BOSSMAPINFO, INVALID_TIMER); status_change_end(&sd->bl, SC_WARM, INVALID_TIMER); @@ -5851,8 +5852,8 @@ enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, in status_change_end(&sd->bl, SC_MOON_COMFORT, INVALID_TIMER); status_change_end(&sd->bl, SC_STAR_COMFORT, INVALID_TIMER); status_change_end(&sd->bl, SC_MIRACLE, INVALID_TIMER); - if (sd->sc.data[SC_KNOWLEDGE]) { - struct status_change_entry *sce = sd->sc.data[SC_KNOWLEDGE]; + if (sc->data[SC_KNOWLEDGE]) { + struct status_change_entry *sce = sc->data[SC_KNOWLEDGE]; if (sce->timer != INVALID_TIMER) delete_timer(sce->timer, status_change_timer); sce->timer = add_timer(gettick() + skill_get_time(SG_KNOWLEDGE, sce->val1), status_change_timer, sd->bl.id, SC_KNOWLEDGE); @@ -5962,6 +5963,9 @@ enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, in } else if(sd->state.active) //Tag player for rewarping after map-loading is done. [Skotlex] sd->state.rewarp = 1; + if (sc && sc->data[SC_HELLS_PLANT]) + skill_unit_move_unit_group(skill_id2group(sc->data[SC_HELLS_PLANT]->val4), m, x - sd->bl.x, y - sd->bl.y); + sd->mapindex = mapindex; sd->bl.m = m; sd->bl.x = sd->ud.to_x = x; @@ -6006,7 +6010,7 @@ enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, in } pc_cell_basilica(sd); - + //check if we gonna be rewarped [lighta] if(npc_check_areanpc(1,m,x,y,0)){ sd->count_rewarp++; diff --git a/src/map/script_constants.hpp b/src/map/script_constants.hpp index fb2b68cc1a..cae9051e67 100644 --- a/src/map/script_constants.hpp +++ b/src/map/script_constants.hpp @@ -1579,6 +1579,9 @@ export_constant(SC_INCREASE_MAXHP); export_constant(SC_INCREASE_MAXSP); export_constant(SC_HELPANGEL); + export_constant(SC_REF_T_POTION); + export_constant(SC_ADD_ATK_DAMAGE); + export_constant(SC_ADD_MATK_DAMAGE); #ifdef RENEWAL export_constant(SC_EXTREMITYFIST2); #endif diff --git a/src/map/skill.cpp b/src/map/skill.cpp index 34b1862845..549c238fff 100755 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -3631,7 +3631,6 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list * case EL_HURRICANE: case EL_HURRICANE_ATK: case KO_BAKURETSU: - case GN_CRAZYWEED_ATK: case GN_HELLS_PLANT_ATK: case SU_SV_ROOTTWIST_ATK: dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id,-1,DMG_SPLASH); @@ -5217,13 +5216,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint if( skill_area_temp[1] != bl->id && !inf2[INF2_ISNPC] ) sflag |= SD_ANIMATION; // original target gets no animation (as well as all NPC skills) - switch (skill_id) { - case GN_SPORE_EXPLOSION: - if (flag&2 && skill_area_temp[1] == bl->id) - sflag |= 2048; // Flag for main target - break; - } - // If a enemy player is standing next to a mob when splash Es- skill is casted, the player won't get hurt. if ((skill_id == SP_SHA || skill_id == SP_SWHOO) && !battle_config.allow_es_magic_pc && bl->type != BL_MOB) break; @@ -11101,7 +11093,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; case GN_SPORE_EXPLOSION: clif_skill_nodamage(src, bl, skill_id, skill_lv, 1); - skill_castend_damage_id(src, bl, skill_id, skill_lv, tick, flag|1|2); // First attack to target + skill_attack(skill_get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag|8); sc_start4(src, bl, type, 100, skill_lv, skill_id, src->id, 0, skill_get_time(skill_id, skill_lv)); break; case GN_MANDRAGORA: @@ -13046,7 +13038,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui break; case GN_HELLS_PLANT: - skill_clear_unitgroup(src); + status_change_end(src, type, INVALID_TIMER); // Remove previous group if ((sg = skill_unitsetting(src, skill_id, skill_lv, src->x, src->y, 0)) != nullptr) sc_start4(src, src, type, 100, skill_lv, 0, 0, sg->group_id, skill_get_time(skill_id, skill_lv)); break; @@ -19110,7 +19102,6 @@ int skill_delunitgroup_(struct skill_unit_group *group, const char* file, int li case SG_MOON_WARM: case SG_STAR_WARM: case LG_BANDING: - case GN_HELLS_PLANT: { status_change *sc = status_get_sc(src); sc_type type = status_skill2sc(group->skill_id); diff --git a/src/map/status.cpp b/src/map/status.cpp index 98fce72184..acadfaa983 100644 --- a/src/map/status.cpp +++ b/src/map/status.cpp @@ -966,7 +966,7 @@ void initChangeTables(void) set_sc( GN_SPORE_EXPLOSION , SC_SPORE_EXPLOSION , EFST_SPORE_EXPLOSION, SCB_NONE ); set_sc( GN_FIRE_EXPANSION_SMOKE_POWDER , SC_SMOKEPOWDER , EFST_FIRE_EXPANSION_SMOKE_POWDER, SCB_FLEE ); set_sc( GN_FIRE_EXPANSION_TEAR_GAS , SC_TEARGAS , EFST_FIRE_EXPANSION_TEAR_GAS , SCB_HIT|SCB_FLEE ); - add_sc( GN_HELLS_PLANT , SC_HELLS_PLANT ); + set_sc( GN_HELLS_PLANT , SC_HELLS_PLANT , EFST_HELLS_PLANT_ARMOR , SCB_NONE ); set_sc( GN_MANDRAGORA , SC_MANDRAGORA , EFST_MANDRAGORA , SCB_INT ); set_sc_with_vfx( GN_ILLUSIONDOPING , SC_ILLUSIONDOPING , EFST_ILLUSIONDOPING , SCB_HIT ); @@ -1381,6 +1381,9 @@ void initChangeTables(void) StatusIconChangeTable[SC_ANCILLA] = EFST_ANCILLA; StatusIconChangeTable[SC_WEAPONBLOCK_ON] = EFST_WEAPONBLOCK_ON; + StatusIconChangeTable[SC_REF_T_POTION] = EFST_REF_T_POTION; + StatusIconChangeTable[SC_ADD_ATK_DAMAGE] = EFST_ADD_ATK_DAMAGE; + StatusIconChangeTable[SC_ADD_MATK_DAMAGE] = EFST_ADD_MATK_DAMAGE; // Battleground Queue StatusIconChangeTable[SC_ENTRY_QUEUE_APPLY_DELAY] = EFST_ENTRY_QUEUE_APPLY_DELAY; diff --git a/src/map/status.hpp b/src/map/status.hpp index ff114ac473..447316faec 100644 --- a/src/map/status.hpp +++ b/src/map/status.hpp @@ -923,6 +923,9 @@ enum sc_type : int16 { SC_HELLS_PLANT, SC_INCREASE_MAXHP, // EFST_ATKER_ASPD SC_INCREASE_MAXSP, // EFST_ATKER_MOVESPEED + SC_REF_T_POTION, + SC_ADD_ATK_DAMAGE, + SC_ADD_MATK_DAMAGE, SC_HELPANGEL, diff --git a/src/map/unit.cpp b/src/map/unit.cpp index 25acc3c751..6c8b6de35b 100644 --- a/src/map/unit.cpp +++ b/src/map/unit.cpp @@ -2957,7 +2957,6 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file, status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER); status_change_end(bl, SC_NEUTRALBARRIER_MASTER, INVALID_TIMER); status_change_end(bl, SC_STEALTHFIELD_MASTER, INVALID_TIMER); - status_change_end(bl, SC_HELLS_PLANT, INVALID_TIMER); status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER); status_change_end(bl, SC__MANHOLE, INVALID_TIMER); status_change_end(bl, SC_VACUUM_EXTREME, INVALID_TIMER);