diff --git a/db/pre-re/skill_db.conf b/db/pre-re/skill_db.conf index b1f0707d802..be95667f2f1 100644 --- a/db/pre-re/skill_db.conf +++ b/db/pre-re/skill_db.conf @@ -6538,8 +6538,8 @@ skill_db: ( SplashArea: true } SplashRange: 1 - SkillData1: 5000 - SkillData2: 30000 + SkillData1: 5_000 // Stun duration (in milliseconds) + SkillData2: 30_000 // Blind duration (in milliseconds) CoolDown: 0 Requirements: { SPCost: 20 @@ -6909,17 +6909,29 @@ skill_db: ( } InterruptCast: true CastTime: 1000 - SkillData1: { - Lv1: 40000 - Lv2: 45000 - Lv3: 50000 - Lv4: 55000 - Lv5: 60000 - Lv6: 65000 - Lv7: 70000 - Lv8: 75000 - Lv9: 80000 - Lv10: 85000 + SkillData1: { // Fire unit duration (in milliseconds) + Lv1: 40_000 + Lv2: 45_000 + Lv3: 50_000 + Lv4: 55_000 + Lv5: 60_000 + Lv6: 65_000 + Lv7: 70_000 + Lv8: 75_000 + Lv9: 80_000 + Lv10: 85_000 + } + SkillData2: { // Chance to break enemy weapon (100 = 1%) + Lv1: 1_00 + Lv2: 2_00 + Lv3: 3_00 + Lv4: 4_00 + Lv5: 5_00 + Lv6: 6_00 + Lv7: 7_00 + Lv8: 8_00 + Lv9: 9_00 + Lv10: 10_00 } CoolDown: 0 Requirements: { @@ -6961,7 +6973,7 @@ skill_db: ( } InterruptCast: true CastTime: 1000 - SkillData1: { + SkillData1: { // Chance to break target's armor (1 = 1%) Lv1: 3 Lv2: 7 Lv3: 10 @@ -6973,7 +6985,7 @@ skill_db: ( Lv9: 13 Lv10: 13 } - SkillData2: 120000 + SkillData2: 120000 // Bleeding duration (in milliseconds) CoolDown: 0 Requirements: { SPCost: 15 diff --git a/db/re/skill_db.conf b/db/re/skill_db.conf index d6e65ad6a6a..aa3bc9bd56e 100644 --- a/db/re/skill_db.conf +++ b/db/re/skill_db.conf @@ -6625,7 +6625,7 @@ skill_db: ( StatusChange: "SC_STUN" Description: "Back Stab" MaxLevel: 10 - Range: -1 + Range: 1 Hit: "BDT_SKILL" SkillType: { Enemy: true @@ -6636,14 +6636,12 @@ skill_db: ( } AttackType: "Weapon" Element: "Ele_Weapon" - DamageType: { - IgnoreFlee: true - } AfterCastActDelay: 500 - SkillData1: 5000 + SkillData1: 5_000 // Stun duration (in milliseconds) + CoolDown: 500 FixedCastTime: 0 Requirements: { - SPCost: 16 + SPCost: 12 } }, { @@ -6669,11 +6667,11 @@ skill_db: ( SplashArea: true } SplashRange: 3 - SkillData1: 5000 - SkillData2: 20000 + SkillData1: 5_000 // Stun duration (in milliseconds) + SkillData2: 20_000 // Blind duration (in milliseconds) FixedCastTime: 0 Requirements: { - SPCost: 20 + SPCost: 15 State: "Hiding" } }, @@ -7129,17 +7127,29 @@ skill_db: ( InterruptCast: true CastTime: 800 AfterCastActDelay: 500 - SkillData1: { - Lv1: 40000 - Lv2: 45000 - Lv3: 50000 - Lv4: 55000 - Lv5: 60000 - Lv6: 65000 - Lv7: 70000 - Lv8: 75000 - Lv9: 80000 - Lv10: 85000 + SkillData1: { // Fire unit duration (in milliseconds) + Lv1: 40_000 + Lv2: 45_000 + Lv3: 50_000 + Lv4: 55_000 + Lv5: 60_000 + Lv6: 65_000 + Lv7: 70_000 + Lv8: 75_000 + Lv9: 80_000 + Lv10: 85_000 + } + SkillData2: { // Chance to break enemy weapon (100 = 1%) + Lv1: 3_00 + Lv2: 6_00 + Lv3: 9_00 + Lv4: 12_00 + Lv5: 15_00 + Lv6: 18_00 + Lv7: 21_00 + Lv8: 24_00 + Lv9: 27_00 + Lv10: 30_00 } FixedCastTime: 200 Requirements: { @@ -7166,7 +7176,7 @@ skill_db: ( Description: "Acid Terror" MaxLevel: 5 Range: 9 - Hit: "BDT_SKILL" + Hit: "BDT_MULTIHIT" SkillType: { Enemy: true } @@ -7179,22 +7189,23 @@ skill_db: ( IgnoreCards: true IgnoreFlee: true } + NumberOfHits: -5 InterruptCast: true CastTime: 500 AfterCastActDelay: 500 - SkillData1: { - Lv1: 3 - Lv2: 7 - Lv3: 10 - Lv4: 12 - Lv5: 13 - Lv6: 13 - Lv7: 13 - Lv8: 13 - Lv9: 13 - Lv10: 13 - } - SkillData2: 120000 + SkillData1: { // Chance to break target's armor (1 = 1%) + Lv1: 5 + Lv2: 15 + Lv3: 25 + Lv4: 35 + Lv5: 45 + Lv6: 45 + Lv7: 45 + Lv8: 45 + Lv9: 45 + Lv10: 45 + } + SkillData2: 120_000 // Bleeding duration (in milliseconds) FixedCastTime: 500 Requirements: { SPCost: 15 @@ -7725,7 +7736,6 @@ skill_db: ( Self: true } SkillInfo: { - TargetSelf: true AllowReproduce: true } AttackType: "Magic" @@ -7735,23 +7745,24 @@ skill_db: ( IgnoreFlee: true } CastDefRate: 33 - CastTime: 1500 - AfterCastActDelay: 1500 + CastTime: 1_000 + CoolDown: 1_000 + AfterCastActDelay: 500 AfterCastWalkDelay: 900 - SkillData1: 900 - SkillData2: { - Lv1: 10000 - Lv2: 11000 - Lv3: 12000 - Lv4: 13000 - Lv5: 14000 - Lv6: 15000 - Lv7: 16000 - Lv8: 17000 - Lv9: 18000 - Lv10: 19000 + SkillData1: 900 // Ground unit duration/ground effect duration (in milliseconds) + SkillData2: { // Duration of the blind effect (in milliseconds) + Lv1: 10_000 + Lv2: 11_000 + Lv3: 12_000 + Lv4: 13_000 + Lv5: 14_000 + Lv6: 15_000 + Lv7: 16_000 + Lv8: 17_000 + Lv9: 18_000 + Lv10: 19_000 } - FixedCastTime: 1500 + FixedCastTime: 500 Requirements: { SPCost: { Lv1: 37 @@ -32750,7 +32761,7 @@ skill_db: ( Lv9: 15 Lv10: 16 } - + SkillType: { Enemy: true } @@ -33374,7 +33385,7 @@ skill_db: ( MaxLevel: 10 Hit: "BDT_MULTIHIT" SkillType: { - Self: true + Self: true } SkillInfo: { Chorus: true diff --git a/src/map/battle.c b/src/map/battle.c index 053ebb524cf..257784b8a25 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -2179,12 +2179,16 @@ static int battle_calc_skillratio(int attack_type, struct block_list *src, struc break; case RG_BACKSTAP: if (sd != NULL && sd->weapontype == W_BOW && battle_config.backstab_bow_penalty) - skillratio += (200 + 40 * skill_lv) / 2; + skillratio += -100 + (300 + 40 * skill_lv) / 2; else skillratio += 200 + 40 * skill_lv; break; case RG_RAID: +#ifndef RENEWAL skillratio += 40 * skill_lv; +#else + skillratio += -50 + 150 * skill_lv; +#endif break; case RG_INTIMIDATE: skillratio += 30 * skill_lv; @@ -2193,7 +2197,20 @@ static int battle_calc_skillratio(int attack_type, struct block_list *src, struc skillratio += 20 * skill_lv; break; case CR_SHIELDBOOMERANG: +#ifndef RENEWAL skillratio += 30 * skill_lv; +#else + skillratio += -100 + 80 * skill_lv; + if (sd != NULL) { + short shield_index = sd->equip_index[EQI_HAND_L]; + + if (shield_index >= 0 && sd->inventory_data[shield_index] != NULL + && sd->inventory_data[shield_index]->type == IT_ARMOR) { + skillratio += sd->inventory_data[shield_index]->weight / 10; // + % + skillratio += sd->status.inventory[shield_index].refine * 4; // + % + } + } +#endif break; case NPC_DARKCROSS: case CR_HOLYCROSS: @@ -2207,11 +2224,20 @@ static int battle_calc_skillratio(int attack_type, struct block_list *src, struc break; } case AM_DEMONSTRATION: +#ifndef RENEWAL skillratio += 20 * skill_lv; +#else + skillratio += -100 + 60 * skill_lv; + if (sd != NULL) + skillratio += 10 * pc->checkskill(sd, AM_LEARNINGPOTION); +#endif break; case AM_ACIDTERROR: #ifdef RENEWAL - skillratio += 80 * skill_lv + 100; + skillratio += -100 + 200 * skill_lv; + + if (sd != NULL) + skillratio += 100 * pc->checkskill(sd, AM_LEARNINGPOTION); #else skillratio += 40 * skill_lv; #endif @@ -3272,12 +3298,8 @@ static int64 battle_calc_damage(struct block_list *src, struct block_list *bl, s } #ifdef RENEWAL - if( sc->data[SC_RAID] ) { - damage += damage * 20 / 100; - - if (--sc->data[SC_RAID]->val1 == 0) - status_change_end(bl, SC_RAID, INVALID_TIMER); - } + if (sc->data[SC_RAID] != NULL) + damage += damage * sc->data[SC_RAID]->val2 / 100; #endif if( damage ) { @@ -4777,9 +4799,14 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl break; #ifdef RENEWAL + case RG_BACKSTAP: + if (sd != NULL && sd->weapontype == W_DAGGER) + wd.div_ = 2; + break; + case KN_BOWLINGBASH: wd.div_ = 2; - + // wflag stores the number of affected targets if (sd != NULL && sd->weapontype == W_2HSWORD) { if (wflag >= 2 && wflag < 4) @@ -4829,8 +4856,6 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl #ifdef RENEWAL case MO_EXTREMITYFIST: case GS_PIERCINGSHOT: - case AM_ACIDTERROR: - case AM_DEMONSTRATION: case NJ_ISSEN: case PA_SACRIFICE: case KO_HAPPOKUNAI: @@ -5143,6 +5168,11 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl if (sd != NULL && pc->checkskill(sd, AS_SONICACCEL) > 0) hitpercbonus += 50; break; +#ifdef RENEWAL + case RG_BACKSTAP: + hitrate += 4 * skill_lv; + break; +#endif case MC_CARTREVOLUTION: case GN_CART_TORNADO: case GN_CARTCANNON: @@ -5280,17 +5310,29 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl case PA_SHIELDCHAIN: #endif case CR_SHIELDBOOMERANG: +#ifndef RENEWAL wd.damage = sstatus->batk; - if (sd) { + if (sd != NULL) { int damagevalue = 0; short index = sd->equip_index[EQI_HAND_L]; - if( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_ARMOR ) + if (index >= 0 && sd->inventory_data[index] != NULL && sd->inventory_data[index]->type == IT_ARMOR) damagevalue = sd->inventory_data[index]->weight/10; ATK_ADD(damagevalue); - } else + } else { ATK_ADD(sstatus->rhw.atk2); //Else use Atk2 + } +#else // RENEWAL + if (sd != NULL) { + GET_NORMAL_ATTACK(0, skill_id); + } else { + // @TODO: Does this still applies for Renewal after rebalance? + wd.damage = sstatus->batk; + ATK_ADD(sstatus->rhw.atk2); //Else use Atk2 + } +#endif break; + case HFLI_SBR44: //[orn] if (src->type == BL_HOM) { const struct homun_data *hd = BL_UCCAST(BL_HOM, src); @@ -5461,24 +5503,6 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl ATK_ADD(sstatus->rhw.atk2); //Else use Atk2 ATK_RATE(battle->calc_skillratio(BF_WEAPON, src, target, skill_id, skill_lv, skillratio, wflag)); break; - case AM_DEMONSTRATION: - case AM_ACIDTERROR: // [malufett/Hercules] - { - int64 matk; - int totaldef = status->get_total_def(target) + status->get_total_mdef(target); - matk = battle->calc_cardfix(BF_MAGIC, src, target, nk, s_ele, 0, status->get_matk(src, 2), 0, wd.flag); - matk = battle->attr_fix(src, target, matk, ELE_NEUTRAL, tstatus->def_ele, tstatus->ele_lv); - matk = matk * battle->calc_skillratio(BF_WEAPON, src, target, skill_id, skill_lv, skillratio, wflag) / 100; - GET_NORMAL_ATTACK((sc && sc->data[SC_MAXIMIZEPOWER] ? 1 : 0) | (sc && sc->data[SC_WEAPONPERFECT] ? 8 : 0), 0); - ATK_RATE(battle->calc_skillratio(BF_WEAPON, src, target, skill_id, skill_lv, skillratio, wflag)); - ATK_ADD(matk); - ATK_ADD(-totaldef); - if ( skill_id == AM_ACIDTERROR && is_boss(target) ) - ATK_RATE(50); - if ( skill_id == AM_DEMONSTRATION ) - wd.damage = max(wd.damage, 1); - } - break; case GN_CARTCANNON: GET_NORMAL_ATTACK((sc && sc->data[SC_MAXIMIZEPOWER] ? 1 : 0) | (sc && sc->data[SC_WEAPONPERFECT] ? 8 : 0), skill_id); ATK_ADD(sd ? sd->bonus.arrow_atk : 0); diff --git a/src/map/skill.c b/src/map/skill.c index 330cdb87694..4cd42faa5b8 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -1798,14 +1798,14 @@ static int skill_additional_effect(struct block_list *src, struct block_list *bl case AM_ACIDTERROR: sc_start2(src, bl, SC_BLOODING, (skill_lv * 3), skill_lv, src->id, skill->get_time2(skill_id, skill_lv), skill_id); - if ( bl->type == BL_PC && rnd() % 1000 < 10 * skill->get_time(skill_id, skill_lv) ) { + if (bl->type == BL_PC && (rnd() % 1000) < (10 * skill->get_time(skill_id, skill_lv))) { skill->break_equip(bl, EQP_ARMOR, 10000, BCT_ENEMY); clif->emotion(bl, E_OMG); // emote icon still shows even there is no armor equip. } break; case AM_DEMONSTRATION: - skill->break_equip(bl, EQP_WEAPON, 100*skill_lv, BCT_ENEMY); + skill->break_equip(bl, EQP_WEAPON, skill->get_time2(skill_id, skill_lv), BCT_ENEMY); break; case CR_SHIELDCHARGE: @@ -1820,14 +1820,16 @@ static int skill_additional_effect(struct block_list *src, struct block_list *bl sc_start(src, bl, SC_STUN, (10 + 3 * skill_lv), skill_lv, skill->get_time(skill_id, skill_lv), skill_id); sc_start(src, bl, SC_BLIND, (10 + 3 * skill_lv), skill_lv, skill->get_time2(skill_id, skill_lv), skill_id); - #ifdef RENEWAL - sc_start(src, bl, SC_RAID, 100, 7, 5000, skill_id); +#ifdef RENEWAL + sc_start(src, bl, SC_RAID, 100, 7, 10000, skill_id); +#endif break; +#ifdef RENEWAL case RG_BACKSTAP: sc_start(src, bl, SC_STUN, (5 + 2 * skill_lv), skill_lv, skill->get_time(skill_id, skill_lv), skill_id); - #endif break; +#endif case BA_FROSTJOKE: sc_start(src, bl, SC_FREEZE, (15 + 5 * skill_lv), skill_lv, skill->get_time2(skill_id, skill_lv), skill_id); @@ -4994,20 +4996,40 @@ static int skill_castend_damage_id(struct block_list *src, struct block_list *bl status_change_end(src, SC_BLADESTOP, INVALID_TIMER); break; - case RG_BACKSTAP: - { - enum unit_dir dir = map->calc_dir(src, bl->x, bl->y); - enum unit_dir t_dir = unit->getdir(bl); - if ((!check_distance_bl(src, bl, 0) && map->check_dir(dir, t_dir) == 0) || bl->type == BL_SKILL) { - status_change_end(src, SC_HIDING, INVALID_TIMER); - skill->attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag); - dir = unit_get_opposite_dir(dir); // change direction [Celest] - unit->set_dir(bl, dir); - } - else if (sd) - clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0, 0); + case RG_BACKSTAP: { +#ifndef RENEWAL + enum unit_dir dir = map->calc_dir(src, bl->x, bl->y); + enum unit_dir t_dir = unit->getdir(bl); + if ((!check_distance_bl(src, bl, 0) && map->check_dir(dir, t_dir) == 0) || bl->type == BL_SKILL) { + status_change_end(src, SC_HIDING, INVALID_TIMER); + skill->attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag); + dir = unit_get_opposite_dir(dir); // change direction [Celest] + unit->set_dir(bl, dir); + } + else if (sd) + clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0, 0); +#else + // Finds out where the unit will be after using the skill + enum unit_dir dir = map->calc_dir(src, bl->x, bl->y); + if (Assert_chk(dir >= UNIT_DIR_FIRST && dir < UNIT_DIR_MAX)) { + map->freeblock_unlock(); // unblock before assert-returning + return 0; } + + short x = bl->x + dirx[dir]; + short y = bl->y + diry[dir]; + if (unit->move_pos(src, x, y, 1, true) != 0) { + clif->skill_fail(sd, skill_id, USESKILL_FAIL_POS, 0, 0); + break; + } + + clif->slide(src, x, y); + clif->fixpos(src); + + skill->attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag); +#endif break; + } case MO_FINGEROFFENSIVE: skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag); @@ -5300,7 +5322,7 @@ static int skill_castend_damage_id(struct block_list *src, struct block_list *bl } else { sc_start(src, src, SC_NO_SWITCH_WEAPON, 100, 1, skill->get_time(skill_id, skill_lv), skill_id); skill->area_temp[0] = map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), BL_CHAR, src, skill_id, skill_lv, tick, BCT_ENEMY, skill->area_sub_count); - + // recursive invocation of skill->castend_damage_id() with flag|1 map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), skill->splash_target(src), src, skill_id, skill_lv, tick, flag | BCT_ENEMY | SD_SPLASH | 1, skill->castend_damage_id); } @@ -6405,13 +6427,15 @@ static int skill_castend_id(int tid, int64 tick, int id, intptr_t data) break; } - if(ud->skill_id == RG_BACKSTAP) { +#ifndef RENEWAL + if (ud->skill_id == RG_BACKSTAP) { enum unit_dir dir = map->calc_dir(src, target->x, target->y); enum unit_dir t_dir = unit->getdir(target); if (check_distance_bl(src, target, 0) || map->check_dir(dir, t_dir) != 0) { break; } } +#endif if( ud->skill_id == PR_TURNUNDEAD ) { struct status_data *tstatus = status->get_status_data(target); @@ -10117,7 +10141,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * int level = 0; if (sd != NULL) level = skill_id == AB_CLEMENTIA ? pc->checkskill(sd, AL_BLESSING) : pc->checkskill(sd, AL_INCAGI); - + if (sd == NULL || sd->status.party_id == 0 || flag & 1) { clif->skill_nodamage(bl, bl, skill_id, skill_lv, sc_start(src, bl, type, 100, level, skill->get_time(skill_id, skill_lv), skill_id)); } else if (sd != NULL) { diff --git a/src/map/status.c b/src/map/status.c index b15c0c8be09..236d952ab6c 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -989,7 +989,9 @@ static int status_check_skilluse(struct block_list *src, struct block_list *targ switch (skill_id) { //Usable skills while hiding. case TF_HIDING: case AS_GRIMTOOTH: +#ifndef RENEWAL case RG_BACKSTAP: +#endif case RG_RAID: case NJ_SHADOWJUMP: case NJ_KIRIKAGE: @@ -3697,8 +3699,10 @@ static int status_base_amotion_pc(struct map_session_data *sd, struct status_dat temp = (float)(sqrt(temp) * 0.25f) + 0xc4; if (sd->weapontype == W_BOOK && (skill_lv = pc->checkskill(sd, SA_ADVANCEDBOOK)) > 0) val += (skill_lv - 1) / 2 + 1; - if ( (skill_lv = pc->checkskill(sd, GS_SINGLEACTION)) > 0 ) + if ((skill_lv = pc->checkskill(sd, GS_SINGLEACTION)) > 0) val += ((skill_lv + 1) / 2); + if ((skill_lv = pc->checkskill(sd, RG_PLAGIARISM)) > 0) + val += skill_lv; amotion = ((int)(temp + ((float)(status->calc_aspd(&sd->bl, &sd->sc, 1) + val) * st->agi / 200)) - min(amotion, 200)); #else // base weapon delay @@ -5510,6 +5514,8 @@ static short status_calc_aspd(struct block_list *bl, struct status_change *sc, s bonus += 10; if (sc->data[SC_ADRENALINE] != NULL) bonus += 10; + if (sc->data[SC_SPEARQUICKEN] != NULL) + bonus += 10; #endif } @@ -7278,6 +7284,16 @@ static int status_change_start_sub(struct block_list *src, struct block_list *bl } if (total_tick == 1) return 1; //Minimal duration: Only strip without causing the SC break; + +#ifdef RENEWAL + case SC_RAID: + if (bl->type == BL_MOB && is_boss(bl)) + val2 = 15; // Receives 15% more damage + else + val2 = 30; // Receives 30% more damage + break; +#endif + case SC_MER_FLEE: case SC_MER_ATK: case SC_MER_HP: