diff --git a/db/constants.conf b/db/constants.conf index c32678a6d7d..3170f1b65dd 100644 --- a/db/constants.conf +++ b/db/constants.conf @@ -1271,7 +1271,7 @@ constants_db: { SC_QD_SHOT_READY: 684 SC_HOWLING_MINE: 685 SC_BIND_TRAP: 686 - + // Star Emperor SC_SUNSTANCE: 687 SC_STARSTANCE: 688 @@ -1307,7 +1307,7 @@ constants_db: { SC_SOULDIVISION: 716 SC_ACTIVE_MONSTER_TRANSFORM: 717 - + SC_FIRE_EXPANSION_TEAR_GAS_SOB: 718 SC_TAROTCARD_ATK_PERC: 719 @@ -1316,7 +1316,10 @@ constants_db: { SC_GOSPEL_ATK_PERC: 722 SC_NO_SWITCH_WEAPON: 723 - + + SC_ENSEMBLEFATIGUE: 724 + SC_ADAPTATION: 725 + comment__: "Emotes" e_gasp: 0 e_what: 1 @@ -4307,6 +4310,21 @@ constants_db: { SI_DEFENDER: 62 SI_AUTOSPELL: 65 SI_SPEARQUICKEN: 68 + SI_WHISTLE: 70 + SI_ASSASSINCROSS: 71 + SI_POEMBRAGI: 72 + SI_APPLEIDUN: 73 + SI_HUMMING: 74 + SI_DONTFORGETME: 75 + SI_FORTUNEKISS: 76 + SI_SERVICEFORYOU: 77 + SI_RICHMANKIM: 78 + SI_ETERNALCHAOS: 79 + SI_DRUMBATTLEFIELD: 80 + SI_RINGNIBELUNGEN: 81 + SI_ROKISWEIL: 82 + SI_INTOABYSS: 83 + SI_SIEGFRIED: 84 SI_EXPLOSIONSPIRITS: 86 SI_STEELBODY: 87 SI_EXTREMITYFIST: 88 @@ -4926,6 +4944,8 @@ constants_db: { SI_USE_SKILL_SP_SPA: 1062 SI_USE_SKILL_SP_SHA: 1063 SI_SP_SHA: 1064 + SI_ENSEMBLEFATIGUE: 1088 + SI_ADAPTATION: 1089 SI_SOULCURSE: 1125 SI_MADOGEAR: 1149 } diff --git a/db/pre-re/sc_config.conf b/db/pre-re/sc_config.conf index 0c074d88854..6680fa70733 100644 --- a/db/pre-re/sc_config.conf +++ b/db/pre-re/sc_config.conf @@ -6450,3 +6450,29 @@ SC_NO_SWITCH_WEAPON: { } Icon: "SI_NOEQUIPWEAPON" } + +SC_ENSEMBLEFATIGUE: { + Visible: true + Flags: { + NoSave: true + NoDispelReset: true + NoBBReset: true + NoClearanceReset: true + Debuff: true + } + CalcFlags: { + Speed: true + Aspd: true + } + Icon: "SI_ENSEMBLEFATIGUE" +} + +SC_ADAPTATION: { + Visible: true + Flags: { + Buff: true + NoMadoReset: true + NoMagicBlocked: true + } + Icon: "SI_ADAPTATION" +} diff --git a/db/pre-re/skill_db.conf b/db/pre-re/skill_db.conf index b5b820b654f..e11f8900dad 100644 --- a/db/pre-re/skill_db.conf +++ b/db/pre-re/skill_db.conf @@ -9150,7 +9150,7 @@ skill_db: ( DamageType: { NoDamage: true } - SkillData2: 5000 + SkillData2: 5_000 // Time near start/end of performance where it is not possible to cancel (in miliseconds) CoolDown: 0 Requirements: { SPCost: 1 @@ -9651,8 +9651,8 @@ skill_db: ( DamageType: { NoDamage: true } - SkillData1: 60000 - SkillData2: 20000 + SkillData1: 60_000 // Duration of the performance (in miliseconds) + SkillData2: 20_000 // Duration of SC_WHISTLE when unit leaves the performance area (in miliseconds) CoolDown: 0 Requirements: { SPCost: { @@ -9702,8 +9702,8 @@ skill_db: ( DamageType: { NoDamage: true } - SkillData1: 120000 - SkillData2: 20000 + SkillData1: 120_000 // Duration of the performance (in miliseconds) + SkillData2: 20_000 // Duration of SC_ASSNCROS when unit leaves the performance area (in miliseconds) CoolDown: 0 Requirements: { SPCost: { @@ -9753,8 +9753,8 @@ skill_db: ( DamageType: { NoDamage: true } - SkillData1: 180000 - SkillData2: 20000 + SkillData1: 180_000 // Duration of the performance (in miliseconds) + SkillData2: 20_000 // Duration of SC_POEMBRAGI when unit leaves the performance area (in miliseconds) CoolDown: 0 Requirements: { SPCost: { @@ -9804,8 +9804,8 @@ skill_db: ( DamageType: { NoDamage: true } - SkillData1: 180000 - SkillData2: 20000 + SkillData1: 180_000 // Duration of the performance (in miliseconds) + SkillData2: 20_000 // Duration of SC_APPLEIDUN when unit leaves the performance area (in miliseconds) CoolDown: 0 Requirements: { SPCost: { @@ -9980,8 +9980,8 @@ skill_db: ( DamageType: { NoDamage: true } - SkillData1: 60000 - SkillData2: 20000 + SkillData1: 60_000 // Duration of the performance (in miliseconds) + SkillData2: 20_000 // Duration of SC_HUMMING when unit leaves the performance area (in miliseconds) CoolDown: 0 Requirements: { SPCost: { diff --git a/db/re/map_zone_db.conf b/db/re/map_zone_db.conf index c5191de61aa..ea3723ef8e2 100644 --- a/db/re/map_zone_db.conf +++ b/db/re/map_zone_db.conf @@ -116,6 +116,11 @@ zones: ( WM_SATURDAY_NIGHT_FEVER: "PLAYER" SO_ARRULLO: "PLAYER" CG_HERMODE: "PLAYER" + BA_DISSONANCE: "PLAYER" + DC_UGLYDANCE: "PLAYER" + DC_DONTFORGETME: "PLAYER" + BD_ETERNALCHAOS: "PLAYER" + BD_ROKISWEIL: "PLAYER" } disabled_items: { @@ -514,6 +519,11 @@ zones: ( SC_MANHOLE: "PLAYER" WM_POEMOFNETHERWORLD: "PLAYER" GN_WALLOFTHORN: "PLAYER" + BA_DISSONANCE: "PLAYER" + DC_UGLYDANCE: "PLAYER" + DC_DONTFORGETME: "PLAYER" + BD_ETERNALCHAOS: "PLAYER" + BD_ROKISWEIL: "PLAYER" } disabled_items: { diff --git a/db/re/sc_config.conf b/db/re/sc_config.conf index e94552d3fc1..1a9d301457a 100644 --- a/db/re/sc_config.conf +++ b/db/re/sc_config.conf @@ -4182,115 +4182,108 @@ SC_DANCING: { Skill: "BD_ENCORE" } SC_WHISTLE: { + Visible: true Flags: { - NoDeathReset: true - NoSave: true - NoDispelReset: true - NoBBReset: true - NoClearanceReset: true + Buff: true NoMadoReset: true + NoMagicBlocked: true } CalcFlags: { Flee: true Flee2: true } Skill: "BA_WHISTLE" + Icon: "SI_WHISTLE" } SC_ASSNCROS: { + Visible: true Flags: { - NoDeathReset: true - NoSave: true - NoDispelReset: true - NoBBReset: true - NoClearanceReset: true + Buff: true NoMadoReset: true + NoMagicBlocked: true } CalcFlags: { Aspd: true } Skill: "BA_ASSASSINCROSS" + Icon: "SI_ASSASSINCROSS" } SC_POEMBRAGI: { + Visible: true Flags: { - NoDeathReset: true - NoSave: true - NoDispelReset: true - NoBBReset: true - NoClearanceReset: true + Buff: true NoMadoReset: true + NoMagicBlocked: true } Skill: "BA_POEMBRAGI" + Icon: "SI_POEMBRAGI" } SC_APPLEIDUN: { + Visible: true Flags: { - NoDeathReset: true - NoSave: true - NoDispelReset: true - NoBBReset: true - NoClearanceReset: true + Buff: true NoMadoReset: true + NoMagicBlocked: true } CalcFlags: { Maxhp: true + Regen: true } Skill: "BA_APPLEIDUN" + Icon: "SI_APPLEIDUN" } SC_HUMMING: { + Visible: true Flags: { - NoDeathReset: true - NoSave: true - NoDispelReset: true - NoBBReset: true - NoClearanceReset: true + Buff: true NoMadoReset: true + NoMagicBlocked: true } CalcFlags: { Hit: true } Skill: "DC_HUMMING" + Icon: "SI_HUMMING" } SC_DONTFORGETME: { + Visible: true Flags: { - NoDeathReset: true - NoSave: true - NoDispelReset: true - NoBBReset: true - NoClearanceReset: true + Debuff: true NoMadoReset: true + NoMagicBlocked: true } CalcFlags: { Speed: true Aspd: true } Skill: "DC_DONTFORGETME" + Icon: "SI_DONTFORGETME" } SC_FORTUNE: { + Visible: true Flags: { - NoDeathReset: true - NoSave: true - NoDispelReset: true - NoBBReset: true - NoClearanceReset: true + Buff: true NoMadoReset: true + NoMagicBlocked: true } CalcFlags: { Cri: true } Skill: "DC_FORTUNEKISS" + Icon: "SI_FORTUNEKISS" } SC_SERVICEFORYOU: { + Visible: true Flags: { - NoDeathReset: true - NoSave: true - NoDispelReset: true - NoBBReset: true - NoClearanceReset: true + Buff: true NoMadoReset: true + NoMagicBlocked: true } CalcFlags: { All: true } Skill: "DC_SERVICEFORYOU" + Icon: "SI_SERVICEFORYOU" } SC_INCHIT: { Flags: { @@ -5433,16 +5426,25 @@ SC_COMA: { Skill: "NPC_DARKBLESSING" } SC_RICHMANKIM: { + Visible: true Flags: { - NoBoss: true + Buff: true + NoMadoReset: true + NoMagicBlocked: true } Skill: "BD_RICHMANKIM" + Icon: "SI_RICHMANKIM" } SC_ROKISWEIL: { + Visible: true Flags: { + Debuff: true + NoMadoReset: true NoBoss: true + NoMagicBlocked: true } Skill: "BD_ROKISWEIL" + Icon: "SI_ROKISWEIL" } SC_BURNING: { Flags: { @@ -5659,32 +5661,68 @@ SC_HERMODE: { Skill: "CG_HERMODE" } SC_ETERNALCHAOS: { + Visible: true + Flags: { + Debuff: true + NoMadoReset: true + NoMagicBlocked: true + } CalcFlags: { + Def: true Def2: true } Skill: "BD_ETERNALCHAOS" + Icon: "SI_ETERNALCHAOS" } SC_DRUMBATTLE: { + Visible: true + Flags: { + Buff: true + NoMadoReset: true + NoMagicBlocked: true + } CalcFlags: { - Watk: true + Batk: true Def: true } Skill: "BD_DRUMBATTLEFIELD" + Icon: "SI_DRUMBATTLEFIELD" } SC_NIBELUNGEN: { + Visible: true + Flags: { + Buff: true + NoMadoReset: true + NoMagicBlocked: true + } CalcFlags: { - Watk: true + All: true } Skill: "BD_RINGNIBELUNGEN" + Icon: "SI_RINGNIBELUNGEN" } SC_INTOABYSS: { + Visible: true + Flags: { + Buff: true + NoMadoReset: true + NoMagicBlocked: true + } Skill: "BD_INTOABYSS" + Icon: "SI_INTOABYSS" } SC_SIEGFRIED: { + Visible: true + Flags: { + Buff: true + NoMadoReset: true + NoMagicBlocked: true + } CalcFlags: { All: true } Skill: "BD_SIEGFRIED" + Icon: "SI_SIEGFRIED" } SC_MODECHANGE: { CalcFlags: { @@ -5989,7 +6027,7 @@ SC_FALLEN_ANGEL: { SC_HEAT_BARREL: { Flags: { Buff: true - } + } CalcFlags: { Hit: true Aspd: true @@ -6467,3 +6505,30 @@ SC_NO_SWITCH_WEAPON: { } Icon: "SI_NOEQUIPWEAPON" } + +SC_ENSEMBLEFATIGUE: { + Visible: true + Flags: { + NoSave: true + NoDispelReset: true + NoBBReset: true + NoClearanceReset: true + Debuff: true + } + CalcFlags: { + Speed: true + Aspd: true + } + Icon: "SI_ENSEMBLEFATIGUE" +} + +SC_ADAPTATION: { + Visible: true + Flags: { + Buff: true + NoMadoReset: true + NoMagicBlocked: true + } + Icon: "SI_ADAPTATION" + Skills: ["BD_ADAPTATION"] +} diff --git a/db/re/skill_db.conf b/db/re/skill_db.conf index 974e7a25929..7fdd395fdef 100644 --- a/db/re/skill_db.conf +++ b/db/re/skill_db.conf @@ -9353,6 +9353,7 @@ skill_db: ( { Id: 304 Name: "BD_ADAPTATION" + StatusChange: "SC_ADAPTATION" Description: "Amp" MaxLevel: 1 Hit: "BDT_SKILL" @@ -9362,10 +9363,12 @@ skill_db: ( DamageType: { NoDamage: true } - SkillData2: 5000 + SkillData1: 180_000 // Buff duration (in miliseconds) FixedCastTime: 0 + AfterCastActDelay: 300 + CoolDown: 300_000 Requirements: { - SPCost: 1 + SPCost: 10 } }, { @@ -9381,6 +9384,8 @@ skill_db: ( DamageType: { NoDamage: true } + AfterCastActDelay: 300 + CoolDown: 10_000 Requirements: { SPCost: 1 WeaponTypes: { @@ -9393,6 +9398,7 @@ skill_db: ( Id: 306 Name: "BD_LULLABY" Description: "Lullaby" + StatusChange: "SC_SLEEP" MaxLevel: 1 Hit: "BDT_SKILL" SkillType: { @@ -9404,26 +9410,21 @@ skill_db: ( AttackType: "Misc" DamageType: { NoDamage: true + SplashArea: true } - SkillData1: 60000 - SkillData2: 15000 + SplashRange: 4 + SkillData1: 15_000 // SC_SLEEP duration (in miliseconds) + CastTime: 1_000 FixedCastTime: 0 + CoolDown: 20_000 + AfterCastActDelay: 300 Requirements: { - SPCost: 20 + SPCost: 40 WeaponTypes: { Instruments: true Whips: true } } - Unit: { - Id: 0x9e - Layout: 4 - Interval: 6000 - Target: "Enemy" - Flag: { - UF_ENSEMBLE: true - } - } }, { Id: 307 @@ -9441,10 +9442,14 @@ skill_db: ( AttackType: "Misc" DamageType: { NoDamage: true + SplashArea: true } - SkillData1: 60000 - SkillData2: 60000 + SplashRange: -1 + SkillData1: 60_000 // SC_RICHMANKIM duration (in miliseconds) FixedCastTime: 0 + CastTime: 1_000 + AfterCastActDelay: 300 + CoolDown: 20_000 Requirements: { SPCost: 20 WeaponTypes: { @@ -9452,16 +9457,6 @@ skill_db: ( Whips: true } } - Unit: { - Id: 0x9f - Layout: 4 - Interval: -1 - Target: "Enemy" - Flag: { - UF_NOPC: true - UF_ENSEMBLE: true - } - } }, { Id: 308 @@ -9479,26 +9474,21 @@ skill_db: ( AttackType: "Misc" DamageType: { NoDamage: true + SplashArea: true } - SkillData1: 60000 - SkillData2: 60000 + SplashRange: 4 + SkillData1: 60_000 // SC_ETERNALCHAOS duration (in miliseconds) FixedCastTime: 0 + CastTime: 1_000 + AfterCastActDelay: 300 + CoolDown: 60_000 Requirements: { - SPCost: 30 + SPCost: 120 WeaponTypes: { Instruments: true Whips: true } } - Unit: { - Id: 0xa0 - Layout: 4 - Interval: -1 - Target: "Enemy" - Flag: { - UF_ENSEMBLE: true - } - } }, { Id: 309 @@ -9516,37 +9506,32 @@ skill_db: ( AttackType: "Misc" DamageType: { NoDamage: true + SplashArea: true } - SkillData1: 60000 - SkillData2: 60000 + SplashRange: -1 + SkillData1: 60_000 // Duration of SC_DRUMBATTLE (in miliseconds) FixedCastTime: 0 + CastTime: 1_000 + AfterCastActDelay: 300 + CoolDown: 20_000 Requirements: { SPCost: { - Lv1: 38 - Lv2: 41 - Lv3: 44 - Lv4: 47 - Lv5: 50 - Lv6: 53 - Lv7: 56 - Lv8: 59 - Lv9: 62 - Lv10: 65 + Lv1: 50 + Lv2: 54 + Lv3: 58 + Lv4: 62 + Lv5: 66 + Lv6: 70 + Lv7: 74 + Lv8: 78 + Lv9: 82 + Lv10: 86 } WeaponTypes: { Instruments: true Whips: true } } - Unit: { - Id: 0xa1 - Layout: 4 - Interval: -1 - Target: "Party" - Flag: { - UF_ENSEMBLE: true - } - } }, { Id: 310 @@ -9564,37 +9549,32 @@ skill_db: ( AttackType: "Misc" DamageType: { NoDamage: true + SplashArea: true } - SkillData1: 60000 - SkillData2: 60000 + SplashRange: -1 + SkillData1: 60_000 // SC_NIBELUNGEN duration (in miliseconds) FixedCastTime: 0 + CastTime: 1_000 + AfterCastActDelay: 300 + CoolDown: 20_000 Requirements: { SPCost: { - Lv1: 38 - Lv2: 41 - Lv3: 44 - Lv4: 47 - Lv5: 50 - Lv6: 53 - Lv7: 56 - Lv8: 59 - Lv9: 62 - Lv10: 65 + Lv1: 64 + Lv2: 60 + Lv3: 56 + Lv4: 52 + Lv5: 48 + Lv6: 44 + Lv7: 40 + Lv8: 36 + Lv9: 32 + Lv10: 28 } WeaponTypes: { Instruments: true Whips: true } } - Unit: { - Id: 0xa2 - Layout: 4 - Interval: -1 - Target: "Party" - Flag: { - UF_ENSEMBLE: true - } - } }, { Id: 311 @@ -9612,26 +9592,21 @@ skill_db: ( AttackType: "Misc" DamageType: { NoDamage: true + SplashArea: true } - SkillData1: 60000 - SkillData2: 60000 + SplashRange: 4 + SkillData1: 30_000 // Duration of SC_ROKISWEIL (in miliseconds) FixedCastTime: 0 + CastTime: 1_000 + AfterCastActDelay: 300 + CoolDown: 20_000 Requirements: { - SPCost: 15 + SPCost: 180 WeaponTypes: { Instruments: true Whips: true } } - Unit: { - Id: 0xa3 - Layout: 4 - Interval: -1 - Target: "All" - Flag: { - UF_ENSEMBLE: true - } - } }, { Id: 312 @@ -9649,27 +9624,21 @@ skill_db: ( AttackType: "Misc" DamageType: { NoDamage: true + SplashArea: true } - SkillData1: 60000 - SkillData2: 60000 + SplashRange: -1 + SkillData1: 60_000 // SC_INTOABYSS duration (in miliseconds) FixedCastTime: 0 + CastTime: 1_000 + AfterCastActDelay: 300 + CoolDown: 20_000 Requirements: { - SPCost: 10 + SPCost: 70 WeaponTypes: { Instruments: true Whips: true } } - Unit: { - Id: 0xa4 - Layout: 4 - Interval: -1 - Target: "Party" - Flag: { - UF_NOMOB: true - UF_ENSEMBLE: true - } - } }, { Id: 313 @@ -9687,26 +9656,29 @@ skill_db: ( AttackType: "Misc" DamageType: { NoDamage: true + SplashArea: true } - SkillData1: 60000 - SkillData2: 60000 + SplashRange: -1 + SkillData1: 60_000 // SC_SIEGFRIED duration (in miliseconds) FixedCastTime: 0 Requirements: { - SPCost: 20 + SPCost: { + Lv1: 40 + Lv2: 44 + Lv3: 48 + Lv4: 52 + Lv5: 56 + Lv6: 60 + Lv7: 64 + Lv8: 68 + Lv9: 72 + Lv10: 76 + } WeaponTypes: { Instruments: true Whips: true } } - Unit: { - Id: 0xa5 - Layout: 4 - Interval: -1 - Target: "Party" - Flag: { - UF_ENSEMBLE: true - } - } }, { Id: 315 @@ -9722,27 +9694,18 @@ skill_db: ( Description: "Melody Strike" MaxLevel: 5 Range: 9 - Hit: "BDT_SKILL" + Hit: "BDT_MULTIHIT" SkillType: { Enemy: true } AttackType: "Weapon" Element: "Ele_Weapon" - CastTime: 1200 + NumberOfHits: 2 + CastTime: 200 FixedCastTime: 300 + AfterCastActDelay: 300 Requirements: { - SPCost: { - Lv1: 1 - Lv2: 3 - Lv3: 5 - Lv4: 7 - Lv5: 9 - Lv6: 11 - Lv7: 13 - Lv8: 15 - Lv9: 17 - Lv10: 19 - } + SPCost: 12 WeaponTypes: { Instruments: true } @@ -9757,7 +9720,7 @@ skill_db: ( Name: "BA_DISSONANCE" Description: "Unchained Serenade" MaxLevel: 5 - Hit: "BDT_MULTIHIT" + Hit: "BDT_SKILL" SkillType: { Self: true } @@ -9765,40 +9728,33 @@ skill_db: ( Song: true BlockedByStasis: true } - AttackType: "Misc" + AttackType: "Magic" + Element: "Ele_Neutral" DamageType: { - NoDamage: true + SplashArea: true IgnoreFlee: true } - SkillData1: 30000 - SkillData2: 3000 + SplashRange: 4 + AfterCastActDelay: 300 + CoolDown: 5_000 FixedCastTime: 0 Requirements: { SPCost: { - Lv1: 18 - Lv2: 21 - Lv3: 24 - Lv4: 27 - Lv5: 30 - Lv6: 33 - Lv7: 36 - Lv8: 39 - Lv9: 42 - Lv10: 45 + Lv1: 35 + Lv2: 38 + Lv3: 41 + Lv4: 44 + Lv5: 47 + Lv6: 50 + Lv7: 53 + Lv8: 56 + Lv9: 59 + Lv10: 62 } WeaponTypes: { Instruments: true } } - Unit: { - Id: 0xa6 - Layout: 3 - Interval: 3000 - Target: "Enemy" - Flag: { - UF_SONG: true - } - } }, { Id: 318 @@ -9816,7 +9772,8 @@ skill_db: ( SplashArea: true } SplashRange: -1 - AfterCastActDelay: 4000 + AfterCastActDelay: 300 + CoolDown: 4_000 SkillData2: { Lv1: 10000 Lv2: 11000 @@ -9862,39 +9819,32 @@ skill_db: ( AttackType: "Misc" DamageType: { NoDamage: true + SplashArea: true } - SkillData1: 60000 - SkillData2: 20000 + SplashRange: -1 + SkillData1: 60_000 // SC_WHISTLE duration (in miliseconds) FixedCastTime: 0 + CastTime: 1_000 + AfterCastActDelay: 500 + CoolDown: 20_000 Requirements: { SPCost: { - Lv1: 24 - Lv2: 28 - Lv3: 32 - Lv4: 36 - Lv5: 40 - Lv6: 44 - Lv7: 48 - Lv8: 52 - Lv9: 56 - Lv10: 60 + Lv1: 22 + Lv2: 24 + Lv3: 26 + Lv4: 28 + Lv5: 30 + Lv6: 32 + Lv7: 34 + Lv8: 36 + Lv9: 38 + Lv10: 40 } WeaponTypes: { Instruments: true Whips: true } } - Unit: { - Id: 0xa7 - Layout: 3 - Interval: 3000 - Target: "All" - Flag: { - UF_NOMOB: true - UF_SONG: true - UF_DUALMODE: true - } - } }, { Id: 320 @@ -9913,39 +9863,32 @@ skill_db: ( AttackType: "Misc" DamageType: { NoDamage: true + SplashArea: true } - SkillData1: 120000 - SkillData2: 20000 + SplashRange: -1 + SkillData1: 60_000 // SC_ASSNCROS duration (in miliseconds) FixedCastTime: 0 + CastTime: 1_000 + AfterCastActDelay: 500 + CoolDown: 20_000 Requirements: { SPCost: { - Lv1: 38 - Lv2: 41 - Lv3: 44 - Lv4: 47 - Lv5: 50 - Lv6: 53 - Lv7: 56 - Lv8: 59 - Lv9: 62 - Lv10: 65 + Lv1: 40 + Lv2: 45 + Lv3: 50 + Lv4: 55 + Lv5: 60 + Lv6: 65 + Lv7: 70 + Lv8: 75 + Lv9: 80 + Lv10: 85 } WeaponTypes: { Instruments: true Whips: true } } - Unit: { - Id: 0xa8 - Layout: 3 - Interval: 3000 - Target: "All" - Flag: { - UF_NOMOB: true - UF_SONG: true - UF_DUALMODE: true - } - } }, { Id: 321 @@ -9964,39 +9907,32 @@ skill_db: ( AttackType: "Misc" DamageType: { NoDamage: true + SplashArea: true } - SkillData1: 180000 - SkillData2: 20000 + SplashRange: -1 + SkillData1: 60_000 // SC_POEMBRAGI duration (in miliseconds) FixedCastTime: 0 + CastTime: 1_000 + AfterCastActDelay: 500 + CoolDown: 20_000 Requirements: { SPCost: { - Lv1: 40 - Lv2: 45 - Lv3: 50 - Lv4: 55 - Lv5: 60 - Lv6: 65 - Lv7: 70 - Lv8: 75 - Lv9: 80 - Lv10: 85 + Lv1: 65 + Lv2: 70 + Lv3: 75 + Lv4: 80 + Lv5: 85 + Lv6: 90 + Lv7: 95 + Lv8: 100 + Lv9: 105 + Lv10: 110 } WeaponTypes: { Instruments: true Whips: true } } - Unit: { - Id: 0xa9 - Layout: 3 - Interval: 3000 - Target: "All" - Flag: { - UF_NOMOB: true - UF_SONG: true - UF_DUALMODE: true - } - } }, { Id: 322 @@ -10015,10 +9951,14 @@ skill_db: ( AttackType: "Misc" DamageType: { NoDamage: true + SplashArea: true } - SkillData1: 180000 - SkillData2: 20000 + SplashRange: -1 + SkillData1: 60_000 // SC_APPLEIDUN duration (in miliseconds) FixedCastTime: 0 + CastTime: 1_000 + AfterCastActDelay: 500 + CoolDown: 20_000 Requirements: { SPCost: { Lv1: 40 @@ -10037,17 +9977,6 @@ skill_db: ( Whips: true } } - Unit: { - Id: 0xaa - Layout: 3 - Interval: 6000 - Target: "All" - Flag: { - UF_NOMOB: true - UF_SONG: true - UF_DUALMODE: true - } - } }, { Id: 323 @@ -10063,27 +9992,18 @@ skill_db: ( Description: "Slinging Arrow" MaxLevel: 5 Range: 9 - Hit: "BDT_SKILL" + Hit: "BDT_MULTIHIT" SkillType: { Enemy: true } AttackType: "Weapon" Element: "Ele_Weapon" - CastTime: 1200 + NumberOfHits: 2 + CastTime: 200 FixedCastTime: 300 + AfterCastActDelay: 300 Requirements: { - SPCost: { - Lv1: 1 - Lv2: 3 - Lv3: 5 - Lv4: 7 - Lv5: 9 - Lv6: 11 - Lv7: 13 - Lv8: 15 - Lv9: 17 - Lv10: 19 - } + SPCost: 12 WeaponTypes: { Whips: true } @@ -10109,36 +10029,53 @@ skill_db: ( AttackType: "Misc" DamageType: { NoDamage: true + SplashArea: true + } + SplashRange: 4 + SkillData1: { // % of SP drained (100 = 100%) + Lv1: 12 + Lv2: 14 + Lv3: 16 + Lv4: 18 + Lv5: 20 + Lv6: 22 + Lv7: 24 + Lv8: 26 + Lv9: 28 + Lv10: 30 + } + SkillData2: { // Chance of draining SP (100 = 100%) + Lv1: 25 + Lv2: 30 + Lv3: 35 + Lv4: 40 + Lv5: 45 + Lv6: 50 + Lv7: 55 + Lv8: 60 + Lv9: 65 + Lv10: 70 } - SkillData1: 30000 - SkillData2: 3000 FixedCastTime: 0 + AfterCastActDelay: 300 + CoolDown: 5_000 Requirements: { SPCost: { - Lv1: 23 - Lv2: 26 - Lv3: 29 - Lv4: 32 - Lv5: 35 - Lv6: 38 - Lv7: 41 - Lv8: 44 - Lv9: 47 - Lv10: 50 + Lv1: 35 + Lv2: 38 + Lv3: 41 + Lv4: 44 + Lv5: 47 + Lv6: 50 + Lv7: 53 + Lv8: 56 + Lv9: 59 + Lv10: 62 } WeaponTypes: { Whips: true } } - Unit: { - Id: 0xab - Layout: 3 - Interval: 3000 - Target: "Enemy" - Flag: { - UF_DANCE: true - } - } }, { Id: 326 @@ -10191,39 +10128,32 @@ skill_db: ( AttackType: "Misc" DamageType: { NoDamage: true + SplashArea: true } - SkillData1: 60000 - SkillData2: 20000 + SplashRange: -1 + SkillData1: 60_000 // SC_HUMMING duration (in miliseconds) FixedCastTime: 0 + CastTime: 1_000 + AfterCastActDelay: 500 + CoolDown: 20_000 Requirements: { SPCost: { - Lv1: 22 - Lv2: 24 - Lv3: 26 - Lv4: 28 - Lv5: 30 - Lv6: 32 - Lv7: 34 - Lv8: 36 - Lv9: 38 - Lv10: 40 + Lv1: 33 + Lv2: 36 + Lv3: 39 + Lv4: 42 + Lv5: 45 + Lv6: 48 + Lv7: 51 + Lv8: 54 + Lv9: 57 + Lv10: 60 } WeaponTypes: { Instruments: true Whips: true } } - Unit: { - Id: 0xac - Layout: 3 - Interval: 3000 - Target: "All" - Flag: { - UF_NOMOB: true - UF_DANCE: true - UF_DUALMODE: true - } - } }, { Id: 328 @@ -10242,38 +10172,32 @@ skill_db: ( AttackType: "Misc" DamageType: { NoDamage: true + SplashArea: true } - SkillData1: 180000 - SkillData2: 20000 + SplashRange: 4 + SkillData1: 60_000 // SC_DONTFORGETME duration (in miliseconds) FixedCastTime: 0 + CastTime: 1_000 + AfterCastActDelay: 500 + CoolDown: 20_000 Requirements: { SPCost: { - Lv1: 28 - Lv2: 31 - Lv3: 34 - Lv4: 37 - Lv5: 40 - Lv6: 43 - Lv7: 46 - Lv8: 49 - Lv9: 52 - Lv10: 55 + Lv1: 38 + Lv2: 41 + Lv3: 44 + Lv4: 47 + Lv5: 50 + Lv6: 53 + Lv7: 56 + Lv8: 59 + Lv9: 62 + Lv10: 65 } WeaponTypes: { Instruments: true Whips: true } } - Unit: { - Id: 0xad - Layout: 3 - Interval: 3000 - Target: "Enemy" - Flag: { - UF_DANCE: true - UF_DUALMODE: true - } - } }, { Id: 329 @@ -10292,39 +10216,32 @@ skill_db: ( AttackType: "Misc" DamageType: { NoDamage: true + SplashArea: true } - SkillData1: 120000 - SkillData2: 20000 + SplashRange: -1 + SkillData1: 60_000 // SC_FORTUNE duration (in miliseconds) FixedCastTime: 0 + CastTime: 1_000 + AfterCastActDelay: 500 + CoolDown: 20_000 Requirements: { SPCost: { - Lv1: 43 - Lv2: 46 - Lv3: 49 - Lv4: 52 - Lv5: 55 - Lv6: 58 - Lv7: 61 - Lv8: 64 - Lv9: 67 - Lv10: 70 + Lv1: 40 + Lv2: 45 + Lv3: 50 + Lv4: 55 + Lv5: 60 + Lv6: 65 + Lv7: 70 + Lv8: 75 + Lv9: 80 + Lv10: 85 } WeaponTypes: { Instruments: true Whips: true } } - Unit: { - Id: 0xae - Layout: 3 - Interval: 3000 - Target: "All" - Flag: { - UF_NOMOB: true - UF_DANCE: true - UF_DUALMODE: true - } - } }, { Id: 330 @@ -10343,39 +10260,32 @@ skill_db: ( AttackType: "Misc" DamageType: { NoDamage: true + SplashArea: true } - SkillData1: 180000 - SkillData2: 20000 + SplashRange: -1 + SkillData1: 60_000 // SC_SERVICEFORYOU duration (in miliseconds) FixedCastTime: 0 + CastTime: 1_000 + AfterCastActDelay: 500 + CoolDown: 20_000 Requirements: { SPCost: { - Lv1: 40 - Lv2: 45 - Lv3: 50 - Lv4: 55 - Lv5: 60 - Lv6: 65 - Lv7: 70 - Lv8: 75 - Lv9: 80 - Lv10: 85 + Lv1: 60 + Lv2: 63 + Lv3: 66 + Lv4: 69 + Lv5: 72 + Lv6: 75 + Lv7: 78 + Lv8: 81 + Lv9: 84 + Lv10: 87 } WeaponTypes: { Instruments: true Whips: true } } - Unit: { - Id: 0xaf - Layout: 3 - Interval: 3000 - Target: "All" - Flag: { - UF_NOMOB: true - UF_DANCE: true - UF_DUALMODE: true - } - } }, { Id: 331 diff --git a/src/map/battle.c b/src/map/battle.c index f8738271356..31844ee5779 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -885,15 +885,6 @@ static int64 battle_calc_masteryfix(struct block_list *src, struct block_list *t if(sc->data[SC_CAMOUFLAGE]) damage += 30 * ( 10 - sc->data[SC_CAMOUFLAGE]->val4 ); #ifdef RENEWAL - if(sc->data[SC_NIBELUNGEN] && weapon) - damage += sc->data[SC_NIBELUNGEN]->val2; - if(sc->data[SC_DRUMBATTLE]){ - if(tstatus->size == SZ_SMALL) - damage += sc->data[SC_DRUMBATTLE]->val2; - else if(tstatus->size == SZ_MEDIUM) - damage += 10 * sc->data[SC_DRUMBATTLE]->val1; - //else no bonus for large target - } if(sc->data[SC_GS_MADNESSCANCEL]) damage += 100; if(sc->data[SC_GS_GATLINGFEVER]){ @@ -1678,6 +1669,19 @@ static int battle_calc_skillratio(int attack_type, struct block_list *src, struc case AL_RUWACH: skillratio += 45; break; + /** + * Bard + */ +#ifdef RENEWAL + case BA_DISSONANCE: + // @TODO: Confirm this formula. I have made it by combining some info from bRO Wiki + // with the skill description and some tweaking from my head. + // It is quite close, but I have no source for it. + // Skill description says 100 + 10 * skill_lv (110 / 120 / 130 / 140 / 150) + // But to match the real damage, we have to add an extra 10 * skill_lv (thus, 20 * skill_lv) + skillratio = ((100 + 20 * skill_lv) * sd->status.job_level) / 10; + break; +#endif /** * Priest **/ @@ -2315,7 +2319,11 @@ static int battle_calc_skillratio(int attack_type, struct block_list *src, struc break; case BA_MUSICALSTRIKE: case DC_THROWARROW: +#ifndef RENEWAL skillratio += 25 + 25 * skill_lv; +#else + skillratio += 10 + 40 * skill_lv; +#endif break; case CH_TIGERFIST: skillratio += 100 * skill_lv - 60; @@ -4368,11 +4376,14 @@ static struct Damage battle_calc_misc_attack(struct block_list *src, struct bloc case TF_THROWSTONE: md.damage=50; break; +#ifndef RENEWAL case BA_DISSONANCE: - md.damage=30+skill_lv*10; - if (sd) - md.damage+= 3*pc->checkskill(sd,BA_MUSICALLESSON); + md.damage = 30 + skill_lv * 10; + + if (sd != NULL) + md.damage += 3 * pc->checkskill(sd, BA_MUSICALLESSON); break; +#endif case NPC_SELFDESTRUCTION: md.damage = sstatus->hp; break; @@ -5488,6 +5499,10 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl ATK_ADDRATE(sd->bonus.crit_atk_rate); if(flag.cri && sc && sc->data[SC_MTF_CRIDAMAGE]) ATK_ADDRATE(sc->data[SC_MTF_CRIDAMAGE]->val1);// temporary it should be 'bonus.crit_atk_rate' +#ifdef RENEWAL + if (flag.cri && sc != NULL && sc->data[SC_FORTUNE] != NULL) + ATK_ADDRATE(sc->data[SC_FORTUNE]->val3); +#endif #ifndef RENEWAL if(sd->status.party_id && (temp=pc->checkskill(sd,TK_POWER)) > 0){ if ((i = party->foreachsamemap(party->sub_count, sd, 0, sd->status.char_id)) > 0) diff --git a/src/map/mob.c b/src/map/mob.c index 8c53a5bee65..052d2281b5d 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -2580,8 +2580,12 @@ static int mob_dead(struct mob_data *md, struct block_list *src, int type) ) { //Experience calculation. int bonus = 100; //Bonus on top of your share (common to all attackers). int pnum = 0; - if (md->sc.data[SC_RICHMANKIM]) + +#ifndef RENEWAL + if (md->sc.data[SC_RICHMANKIM] != NULL) bonus += md->sc.data[SC_RICHMANKIM]->val2; +#endif + if(sd) { temp = status->get_class(&md->bl); if(sd->sc.data[SC_MIRACLE]) i = 2; //All mobs are Star Targets @@ -2684,7 +2688,7 @@ static int mob_dead(struct mob_data *md, struct block_list *src, int type) if(flag) { if(base_exp || job_exp) { if( md->dmglog[i].flag != MDLF_PET || battle_config.pet_attack_exp_to_master ) { - pc->gainexp(tmpsd[i], &md->bl, base_exp, job_exp, false); + pc->gainexp(tmpsd[i], &md->bl, base_exp, job_exp, EXP_FLAG_NONE); } } if(zeny) // zeny from mobs [Valaris] @@ -2903,7 +2907,7 @@ static int mob_dead(struct mob_data *md, struct block_list *src, int type) clif->mvp_effect(mvp_sd); clif->mvp_exp(mvp_sd,mexp); - pc->gainexp(mvp_sd, &md->bl, mexp,0, false); + pc->gainexp(mvp_sd, &md->bl, mexp, 0, EXP_FLAG_MVP); log_mvp[1] = mexp; if (!(map->list[m].flag.nomvploot || type&1)) { diff --git a/src/map/npc.c b/src/map/npc.c index 0ea39b855f8..6c2281e60fa 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -2406,7 +2406,7 @@ static int npc_buylist(struct map_session_data *sd, struct itemlist *item_list) if (z < 1) z = 1; - pc->gainexp(sd, NULL, 0, (int)z, false); + pc->gainexp(sd, NULL, 0, (int) z, EXP_FLAG_NONE); } } @@ -2987,7 +2987,7 @@ static int npc_selllist(struct map_session_data *sd, struct itemlist *item_list) if (z < 1) z = 1; - pc->gainexp(sd, NULL, 0, (int)z, false); + pc->gainexp(sd, NULL, 0, (int) z, EXP_FLAG_NONE); } } diff --git a/src/map/party.c b/src/map/party.c index 90cdd90b683..f562345fb37 100644 --- a/src/map/party.c +++ b/src/map/party.c @@ -1073,7 +1073,7 @@ static int party_exp_share(struct party_data *p, struct block_list *src, unsigne } for (i = 0; i < c; i++) { - pc->gainexp(sd[i], src, base_exp, job_exp, false); + pc->gainexp(sd[i], src, base_exp, job_exp, EXP_FLAG_NONE); if (zeny) // zeny from mobs [Valaris] pc->getzeny(sd[i],zeny,LOG_TYPE_PICKDROP_MONSTER,NULL); diff --git a/src/map/pc.c b/src/map/pc.c index 48e8a3927c6..7ed772bd304 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -6806,7 +6806,7 @@ static int pc_checkjoblevelup(struct map_session_data *sd) /** * Alters EXP based on self bonuses that do not get shared with the party **/ -static void pc_calcexp(struct map_session_data *sd, uint64 *base_exp, uint64 *job_exp, struct block_list *src) +static void pc_calcexp(struct map_session_data *sd, uint64 *base_exp, uint64 *job_exp, struct block_list *src, enum gainexp_flags flags) { int buff_ratio = 0, buff_job_ratio = 0, race_ratio = 0, pk_ratio = 0; int64 jexp, bexp; @@ -6831,6 +6831,16 @@ static void pc_calcexp(struct map_session_data *sd, uint64 *base_exp, uint64 *jo } #endif +#ifdef RENEWAL + // after rebalance, boss monsters does give more EXP, but "MVP" exp is not increased + if (sd->sc.data[SC_RICHMANKIM] != NULL && src->type == BL_MOB && (flags & EXP_FLAG_MVP) == 0) { + buff_ratio += sd->sc.data[SC_RICHMANKIM]->val1; + // jexp is boosted by both buff_ration AND buff_job_ratio, so we should not use buff_job_ratio here + // or we will give the bonus twice for jexp + // buff_job_ratio += sd->sc.data[SC_RICHMANKIM]->val1; + } +#endif + //Race modifier if (sd->expaddrace[st->race]) race_ratio += sd->expaddrace[st->race]; @@ -6879,10 +6889,10 @@ static void pc_calcexp(struct map_session_data *sd, uint64 *base_exp, uint64 *jo /** * Gives a determined EXP amount to sd and calculates remaining EXP for next level * @param src if is NULL no bonuses are taken into account - * @param is_quest Used to let client know that the EXP was from a quest (clif->displayexp) PACKETVER >= 20091027 + * @param flags Used to give more info about where the exp is coming from * @retval true success **/ -static bool pc_gainexp(struct map_session_data *sd, struct block_list *src, uint64 base_exp, uint64 job_exp, bool is_quest) +static bool pc_gainexp(struct map_session_data *sd, struct block_list *src, uint64 base_exp, uint64 job_exp, enum gainexp_flags flags) { float nextbp = 0, nextjp = 0; uint64 nextb = 0, nextj = 0; @@ -6898,7 +6908,7 @@ static bool pc_gainexp(struct map_session_data *sd, struct block_list *src, uint return false; if (src) - pc->calcexp(sd, &base_exp, &job_exp, src); + pc->calcexp(sd, &base_exp, &job_exp, src, flags); if (sd->status.guild_id > 0) base_exp -= guild->payexp(sd, base_exp); @@ -6951,6 +6961,7 @@ static bool pc_gainexp(struct map_session_data *sd, struct block_list *src, uint } #if PACKETVER >= 20091027 + bool is_quest = ((flags & EXP_FLAG_QUEST) != 0); if(base_exp) clif->displayexp(sd, base_exp, SP_BASEEXP, is_quest); if(job_exp) @@ -8716,6 +8727,11 @@ static int pc_itemheal(struct map_session_data *sd, int itemid, int hp, int sp) // Activation Potion if (sd->sc.data[SC_VITALIZE_POTION] != NULL) hp += hp * sd->sc.data[SC_VITALIZE_POTION]->val3 / 100; + +#ifdef RENEWAL + if (sd->sc.data[SC_APPLEIDUN] != NULL) + hp += hp * sd->sc.data[SC_APPLEIDUN]->val3 / 100; +#endif } if(sp) { bonus = 100 + (sd->battle_status.int_<<1) diff --git a/src/map/pc.h b/src/map/pc.h index c0bcc2a758d..cb9fbcc5ff7 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -179,6 +179,12 @@ enum npc_timeout_type { NPCT_WAIT = 2, }; +enum gainexp_flags { + EXP_FLAG_NONE = 0, //< Normal EXP, no special flags + EXP_FLAG_QUEST = 0x01, //< EXP given by quests/NPCs (e.g. scripts getexp) + EXP_FLAG_MVP = 0x02, //< EXP given to the "MVP" player (when killing bosses) +}; + struct pc_combos { struct script_code *bonus;/* the script of the combo */ int id; /* this combo id */ @@ -1067,7 +1073,7 @@ END_ZEROED_BLOCK; /* End */ int (*checkbaselevelup) (struct map_session_data *sd); void (*checkbaselevelup_sc) (struct map_session_data *sd); int (*checkjoblevelup) (struct map_session_data *sd); - bool (*gainexp) (struct map_session_data *sd, struct block_list *src, uint64 base_exp, uint64 job_exp, bool is_quest); + bool (*gainexp) (struct map_session_data *sd, struct block_list *src, uint64 base_exp, uint64 job_exp, enum gainexp_flags flags); uint64 (*nextbaseexp) (const struct map_session_data *sd); uint64 (*thisbaseexp) (const struct map_session_data *sd); uint64 (*nextjobexp) (const struct map_session_data *sd); @@ -1216,7 +1222,7 @@ END_ZEROED_BLOCK; /* End */ int (*bonus_addeff) (struct s_addeffect* effect, int max, enum sc_type id, int16 rate, int16 arrow_rate, uint8 flag, uint16 duration); int (*bonus_addeff_onskill) (struct s_addeffectonskill* effect, int max, enum sc_type id, short rate, short skill_id, unsigned char target); int (*bonus_item_drop) (struct s_add_drop *drop, const short max, int id, bool is_group, int race, int rate); - void (*calcexp) (struct map_session_data *sd, uint64 *base_exp, uint64 *job_exp, struct block_list *src); + void (*calcexp) (struct map_session_data *sd, uint64 *base_exp, uint64 *job_exp, struct block_list *src, enum gainexp_flags flags); int (*respawn_timer) (int tid, int64 tick, int id, intptr_t data); int (*jobchange_killclone) (struct block_list *bl, va_list ap); int (*getstat) (struct map_session_data* sd, int type); diff --git a/src/map/script.c b/src/map/script.c index d72268764c1..ddb34db1b9a 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -12093,7 +12093,7 @@ static BUILDIN(getexp) base = cap_value(apply_percentrate(base, battle_config.quest_exp_rate, 100), 0, INT_MAX); job = cap_value(apply_percentrate(job, battle_config.quest_exp_rate, 100), 0, INT_MAX); - pc->gainexp(sd, &sd->bl, base, job, true); + pc->gainexp(sd, &sd->bl, base, job, EXP_FLAG_QUEST); return true; } diff --git a/src/map/skill.c b/src/map/skill.c index 21d52fad3e3..85c92fe1bbf 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -1158,15 +1158,13 @@ static int skill_calc_heal(struct block_list *src, struct block_list *target, ui case SU_TUNABELLY: hp = status_get_max_hp(target) * ((20 * skill_lv) - 10) / 100; break; +#ifndef RENEWAL case BA_APPLEIDUN: -#ifdef RENEWAL - hp = 100+5*skill_lv+5*(status_get_vit(src)/10); // HP recovery -#else // not RENEWAL - hp = 30+5*skill_lv+5*(status_get_vit(src)/10); // HP recovery -#endif // RENEWAL - if( sd ) - hp += 5*pc->checkskill(sd,BA_MUSICALLESSON); + hp = 30 + 5 * skill_lv + 5 * (status_get_vit(src) / 10); // HP recovery + if (sd != NULL) + hp += 5 * pc->checkskill(sd, BA_MUSICALLESSON); break; +#endif // not RENEWAL case PR_SANCTUARY: hp = (skill_lv>6)?777:skill_lv*100; break; @@ -1240,6 +1238,10 @@ static int skill_calc_heal(struct block_list *src, struct block_list *target, ui default: hp += status->get_matk(src, 3); } + + // In-game tests suggests that this effect applies AFTER the MATK bonus is calculated + if (sc->data[SC_APPLEIDUN] != NULL) + hp += hp * sc->data[SC_APPLEIDUN]->val3 / 100; #endif // RENEWAL return hp; } @@ -1862,16 +1864,20 @@ static int skill_additional_effect(struct block_list *src, struct block_list *bl sc_start(src, bl, SC_STUN, (25 + 5 * skill_lv), skill_lv, skill->get_time2(skill_id, skill_lv), skill_id); break; +#ifndef RENEWAL case BD_LULLABY: sc_start(src, bl, SC_SLEEP, 15, skill_lv, skill->get_time2(skill_id, skill_lv), skill_id); break; case DC_UGLYDANCE: rate = 5+5*skill_lv; - if (sd && (temp=pc->checkskill(sd,DC_DANCINGLESSON)) > 0) - rate += 5+temp; + + if (sd != NULL && (temp = pc->checkskill(sd, DC_DANCINGLESSON)) > 0) + rate += 5 + temp; status_zap(bl, 0, rate); break; +#endif + case SL_STUN: if (tstatus->size==SZ_MEDIUM) //Only stuns mid-sized mobs. sc_start(src, bl, SC_STUN, (30 + 10 * skill_lv), skill_lv, skill->get_time(skill_id, skill_lv), skill_id); @@ -4815,7 +4821,9 @@ static int skill_castend_damage_id(struct block_list *src, struct block_list *bl case AM_ACIDTERROR: case BA_MUSICALSTRIKE: case DC_THROWARROW: +#ifndef RENEWAL case BA_DISSONANCE: +#endif case CR_HOLYCROSS: case NPC_DARKCROSS: case CR_SHIELDCHARGE: @@ -4916,6 +4924,12 @@ static int skill_castend_damage_id(struct block_list *src, struct block_list *bl skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag); break; +#ifdef RENEWAL + case BA_DISSONANCE: + skill->attack(BF_MAGIC, src, src, bl, skill_id, skill_lv, tick, flag); + break; +#endif + /** * Mechanic (MADO GEAR) **/ @@ -6631,8 +6645,10 @@ static int skill_castend_id(int tid, int64 tick, int id, intptr_t data) ) sc->data[SC_SOULLINK]->val3 = 0; //Clear bounced spell check. - if( sc->data[SC_DANCING] && skill->get_inf2(ud->skill_id)&INF2_SONG_DANCE && sd ) +#ifndef RENEWAL + if (sc->data[SC_DANCING] != NULL && (skill->get_inf2(ud->skill_id) & INF2_SONG_DANCE) != 0 && sd != NULL) skill->blockpc_start(sd,BD_ADAPTATION,3000); +#endif } if (sd != NULL && ud->skill_id != SA_ABRACADABRA && ud->skill_id != WM_RANDOMIZESPELL @@ -6958,7 +6974,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * heal_get_jobexp = heal_get_jobexp * battle_config.heal_exp / 100; if (heal_get_jobexp <= 0) heal_get_jobexp = 1; - pc->gainexp(sd, bl, 0, heal_get_jobexp, false); + pc->gainexp(sd, bl, 0, heal_get_jobexp, EXP_FLAG_NONE); } } break; @@ -7034,7 +7050,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * if (jexp < 1) jexp = 1; } if(exp > 0 || jexp > 0) - pc->gainexp(sd, bl, exp, jexp, false); + pc->gainexp(sd, bl, exp, jexp, EXP_FLAG_NONE); } } } @@ -7177,7 +7193,8 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * break; case SA_LEVELUP: clif->skill_nodamage(src,bl,skill_id,skill_lv,1); - if (sd && pc->nextbaseexp(sd)) pc->gainexp(sd, NULL, pc->nextbaseexp(sd) * 10 / 100, 0, false); + if (sd != NULL && pc->nextbaseexp(sd)) + pc->gainexp(sd, NULL, pc->nextbaseexp(sd) * 10 / 100, 0, EXP_FLAG_NONE); break; case SA_INSTANTDEATH: clif->skill_nodamage(src,bl,skill_id,skill_lv,1); @@ -7486,6 +7503,9 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * case SJ_LIGHTOFSUN: case SJ_BOOKOFDIMENSION: case SP_SOULREAPER: +#ifdef RENEWAL + case BD_ADAPTATION: +#endif clif->skill_nodamage(src,bl,skill_id,skill_lv, sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv), skill_id)); break; @@ -7968,6 +7988,34 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * } break; +#ifdef RENEWAL + case BD_RICHMANKIM: + case BD_DRUMBATTLEFIELD: + case BD_RINGNIBELUNGEN: + case BD_INTOABYSS: + case BD_SIEGFRIED: + case BA_WHISTLE: + case BA_ASSASSINCROSS: + case BA_POEMBRAGI: + case BA_APPLEIDUN: + case DC_HUMMING: + case DC_FORTUNEKISS: + case DC_SERVICEFORYOU: + skill->castend_nodamage_id_sc_song(src, bl, skill_id, skill_lv, tick, flag | BCT_PARTY); + break; + + case BD_LULLABY: + case BD_ETERNALCHAOS: + case BD_ROKISWEIL: + case DC_DONTFORGETME: + skill->castend_nodamage_id_sc_song(src, bl, skill_id, skill_lv, tick, flag | BCT_ENEMY); + break; + + case DC_UGLYDANCE: + skill->castend_nodamage_id_ugly_dance(src, bl, skill_id, skill_lv, tick, flag); + break; +#endif + #ifdef RENEWAL case MC_LOUD: case PR_IMPOSITIO: @@ -8015,6 +8063,19 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * } break; +#ifdef RENEWAL + case BA_DISSONANCE: + if (sd != NULL) { + sd->skill_id_dance = skill_id; + sd->skill_lv_dance = skill_lv; + } + + clif->skill_nodamage(src, src, skill_id, skill_lv, 1); + map->foreachinrange(skill->area_sub, src, skill->get_splash(skill_id, skill_lv), BL_CHAR, + src, skill_id, skill_lv, tick, flag | BCT_ENEMY | 1, skill->castend_damage_id); + break; +#endif + case BS_ADRENALINE: case BS_ADRENALINE2: case BS_WEAPONPERFECT: @@ -8153,12 +8214,14 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * } break; +#ifndef RENEWAL case BD_ADAPTATION: - if(tsc && tsc->data[SC_DANCING]){ + if (tsc != NULL && tsc->data[SC_DANCING] != NULL) { clif->skill_nodamage(src,bl,skill_id,skill_lv,1); status_change_end(bl, SC_DANCING, INVALID_TIMER); } break; +#endif case BA_FROSTJOKE: case DC_SCREAM: @@ -8759,6 +8822,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * continue; } switch (i) { +#ifndef RENEWAL /** * bugreport:4888 these songs may only be dispelled if you're not in their song area anymore **/ @@ -8770,9 +8834,11 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * case SC_DONTFORGETME: case SC_FORTUNE: case SC_SERVICEFORYOU: - if( tsc->data[i]->val4 ) //val4 = out-of-song-area + if (tsc->data[i]->val4 != 0) // val4 = out-of-song-area continue; break; +#endif + case SC_ASSUMPTIO: if( bl->type == BL_MOB ) continue; @@ -11820,6 +11886,103 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * return 0; } +/** + * Castend handler for Song/Dance skills that simply cause SCs (RE-only) + * @param src Unit who cast the skill + * @param bl Unit being targeted by the skill + * @param skill_id skill being cast + * @param skill_lv level of the skill being cast + * @param tick + * @param flag castend flags + * - flag & 1 : + * when not set: it is the initial skill cast, + * when set: it is in the reiteration over targets to get buffed. + * - enum e_battle_check_target flags: defines who will be affected by the reiteration. examples: + * flag | BCT_PARTY -- affects party members (e.g. apply SC to all party members) + * flag | BCT_ENEMY -- affects enemies (e.g. apply SC to all enemies) + * + * - @TODO: Document other possible flag values + */ +static void skill_castend_nodamage_id_sc_song(struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) +{ +#ifdef RENEWAL + nullpo_retv(src); + nullpo_retv(bl); + + if ((flag & 1) == 0) { + struct map_session_data *sd = BL_CAST(BL_PC, src); + if (sd == NULL) + return; + + sd->skill_id_dance = skill_id; + sd->skill_lv_dance = skill_lv; + + if ((skill->get_inf2(skill_id) & INF2_ENSEMBLE_SKILL) != 0) + skill->check_pc_partner(sd, skill_id, &skill_lv, 1, 1); + + clif->skill_nodamage(src, src, skill_id, skill_lv, 1); + + int splash_range = skill->get_splash(skill_id, skill_lv); + int flags = flag | 1; // &1 will tell when we are iterating over the "execution" phase + + if ((flags & BCT_PARTY) != 0) + party->foreachsamemap(skill->area_sub, sd, splash_range, src, skill_id, skill_lv, tick, flags, skill->castend_nodamage_id); + else + map->foreachinrange(skill->area_sub, src, splash_range, BL_CHAR, src, skill_id, skill_lv, tick, flags, skill->castend_nodamage_id); + } else { + int chance = 100; + if (skill_id == BD_LULLABY) + chance = 15; // @TODO: Did chance of sleep changed in RE rebalance? + + enum sc_type sc = skill->get_sc_type(skill_id); + sc_start(src, bl, sc, chance, skill_lv, skill->get_time(skill_id, skill_lv), skill_id); + } +#endif +} + +/** + * Castend handler for Ugly Dance (RE-only) + * @param src Unit who cast the skill + * @param bl Unit being targeted by the skill + * @param skill_id skill being cast + * @param skill_lv level of the skill being cast + * @param tick + * @param flag castend flags + * - flag & 1 : + * when not set: it is the initial skill cast, + * when set: it is in the reiteration over targets to get affected + */ +static void skill_castend_nodamage_id_ugly_dance(struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) +{ +#ifdef RENEWAL + nullpo_retv(src); + nullpo_retv(bl); + + if ((flag & 1) == 0) { + struct map_session_data *sd = BL_CAST(BL_PC, src); + if (sd != NULL) { + sd->skill_id_dance = skill_id; + sd->skill_lv_dance = skill_lv; + + clif->skill_nodamage(src, src, skill_id, skill_lv, 1); + } + + int splash_range = skill->get_splash(skill_id, skill_lv); + int flags = flag | 1; // &1 will tell when we are iterating over the "execution" phase + map->foreachinrange(skill->area_sub, src, splash_range, BL_CHAR, src, skill_id, skill_lv, tick, flags | BCT_ENEMY, skill->castend_nodamage_id); + } else { + int chance = skill->get_time2(skill_id, skill_lv); + + if (rnd() % 100 < chance) { + int drain_rate = skill->get_time(skill_id, skill_lv); + int drain_amount = status_get_max_sp(bl) * drain_rate / 100; + + status_zap(bl, 0, drain_amount); + } + } +#endif +} + static bool skill_castend_nodamage_id_dead_unknown(struct block_list *src, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag) { return true; @@ -12061,6 +12224,7 @@ static int skill_castend_map(struct map_session_data *sd, uint16 skill_id, const return 0; } if(sd->sc.count && ( + sd->sc.data[SC_ENSEMBLEFATIGUE] || sd->sc.data[SC_SILENCE] || sd->sc.data[SC_ROKISWEIL] || sd->sc.data[SC_AUTOCOUNTER] || @@ -12342,6 +12506,8 @@ static int skill_castend_pos2(struct block_list *src, int x, int y, uint16 skill case AC_SHOWER: //Ground-placed skill implementation. case MA_SHOWER: case SA_LANDPROTECTOR: + case BA_DISSONANCE: +#ifndef RENEWAL case BD_LULLABY: case BD_RICHMANKIM: case BD_ETERNALCHAOS: @@ -12350,16 +12516,16 @@ static int skill_castend_pos2(struct block_list *src, int x, int y, uint16 skill case BD_ROKISWEIL: case BD_INTOABYSS: case BD_SIEGFRIED: - case BA_DISSONANCE: - case BA_POEMBRAGI: case BA_WHISTLE: case BA_ASSASSINCROSS: + case BA_POEMBRAGI: case BA_APPLEIDUN: case DC_UGLYDANCE: - case DC_HUMMING: - case DC_DONTFORGETME: case DC_FORTUNEKISS: case DC_SERVICEFORYOU: + case DC_HUMMING: + case DC_DONTFORGETME: +#endif case CG_MOONLIT: case GS_DESPERADO: case NJ_KAENSIN: @@ -13325,95 +13491,98 @@ static struct skill_unit_group *skill_unitsetting(struct block_list *src, uint16 case DC_UGLYDANCE: val1 = 10; //FIXME: This value is not used anywhere, what is it for? [Skotlex] break; + +#ifndef RENEWAL case BA_WHISTLE: - val1 = skill_lv +st->agi/10; // Flee increase - val2 = ((skill_lv+1)/2)+st->luk/10; // Perfect dodge increase - if(sd){ - val1 += pc->checkskill(sd,BA_MUSICALLESSON); - val2 += pc->checkskill(sd,BA_MUSICALLESSON); + val1 = skill_lv + st->agi / 10; // Flee increase + val2 = ((skill_lv + 1) / 2) + st->luk / 10; // Perfect dodge increase + + if (sd != NULL) { + val1 += pc->checkskill(sd, BA_MUSICALLESSON); + val2 += pc->checkskill(sd, BA_MUSICALLESSON); } break; + case DC_HUMMING: - val1 = 2*skill_lv+st->dex/10; // Hit increase - #ifdef RENEWAL - val1 *= 2; - #endif - if(sd) - val1 += pc->checkskill(sd,DC_DANCINGLESSON); + val1 = 2 * skill_lv + st->dex / 10; // Hit increase + + if (sd != NULL) + val1 += pc->checkskill(sd, DC_DANCINGLESSON); break; + case BA_POEMBRAGI: - val1 = 3*skill_lv+st->dex/10; // Casting time reduction + val1 = 3 * skill_lv + st->dex / 10; // Casting time reduction //For some reason at level 10 the base delay reduction is 50%. - val2 = (skill_lv<10?3*skill_lv:50)+st->int_/5; // After-cast delay reduction - if(sd){ - val1 += 2*pc->checkskill(sd,BA_MUSICALLESSON); - val2 += 2*pc->checkskill(sd,BA_MUSICALLESSON); + val2 = (skill_lv < 10 ? 3 * skill_lv : 50) + st->int_ / 5; // After-cast delay reduction + + if (sd != NULL) { + val1 += 2 * pc->checkskill(sd, BA_MUSICALLESSON); + val2 += 2 * pc->checkskill(sd, BA_MUSICALLESSON); } break; + case DC_DONTFORGETME: -#ifdef RENEWAL - val1 = st->dex/10 + 3*skill_lv; // ASPD decrease - val2 = st->agi/10 + 2*skill_lv; // Movement speed adjustment. -#else val1 = st->dex/10 + 3*skill_lv + 5; // ASPD decrease val2 = st->agi/10 + 3*skill_lv + 5; // Movement speed adjustment. -#endif - if(sd){ - val1 += pc->checkskill(sd,DC_DANCINGLESSON); - val2 += pc->checkskill(sd,DC_DANCINGLESSON); + + if (sd != NULL) { + val1 += pc->checkskill(sd, DC_DANCINGLESSON); + val2 += pc->checkskill(sd, DC_DANCINGLESSON); } break; + case BA_APPLEIDUN: - val1 = 5+2*skill_lv+st->vit/10; // MaxHP percent increase - if(sd) - val1 += pc->checkskill(sd,BA_MUSICALLESSON); + val1 = 5 + 2 * skill_lv + st->vit / 10; // MaxHP percent increase + + if (sd != NULL) { + val1 += pc->checkskill(sd, BA_MUSICALLESSON); + } break; + case DC_SERVICEFORYOU: - val1 = 15+skill_lv+(st->int_/10); // MaxSP percent increase - val2 = 20+3*skill_lv+(st->int_/10); // SP cost reduction - if(sd){ - val1 += pc->checkskill(sd,DC_DANCINGLESSON) / 2; - val2 += pc->checkskill(sd,DC_DANCINGLESSON) / 2; + val1 = 15 + skill_lv + (st->int_ / 10); // MaxSP percent increase + val2 = 20 + 3 * skill_lv + (st->int_ / 10); // SP cost reduction + + if (sd != NULL) { + val1 += pc->checkskill(sd, DC_DANCINGLESSON) / 2; + val2 += pc->checkskill(sd, DC_DANCINGLESSON) / 2; } break; + case BA_ASSASSINCROSS: - if(sd) - val1 = pc->checkskill(sd,BA_MUSICALLESSON) / 2; -#ifdef RENEWAL - // This formula was taken from a RE calculator - // and the changes published on irowiki - // Luckily, official tests show it's the right one - val1 += skill_lv + (st->agi/20); -#else + if (sd != NULL) + val1 = pc->checkskill(sd, BA_MUSICALLESSON) / 2; + val1 += 10 + skill_lv + (st->agi/10); // ASPD increase val1 *= 10; // ASPD works with 1000 as 100% -#endif break; + case DC_FORTUNEKISS: - val1 = 10+skill_lv+(st->luk/10); // Critical increase - if(sd) - val1 += pc->checkskill(sd,DC_DANCINGLESSON); - val1*=10; //Because every 10 crit is an actual cri point. + val1 = 10 + skill_lv + (st->luk / 10); // Critical increase + if (sd != NULL) + val1 += pc->checkskill(sd, DC_DANCINGLESSON); + + val1 *= 10; //Because every 10 crit is an actual cri point. break; + case BD_DRUMBATTLEFIELD: - #ifdef RENEWAL - val1 = (skill_lv+5)*25; //Watk increase - val2 = skill_lv*10; //Def increase - #else - val1 = (skill_lv+1)*25; //Watk increase - val2 = (skill_lv+1)*2; //Def increase - #endif + val1 = (skill_lv + 1) * 25; // Watk increase + val2 = (skill_lv + 1) * 2; // Def increase break; + case BD_RINGNIBELUNGEN: - val1 = (skill_lv+2)*25; //Watk increase + val1 = (skill_lv + 2) * 25; // Watk increase break; + case BD_RICHMANKIM: - val1 = 25 + 11*skill_lv; //Exp increase bonus. + val1 = 25 + 11 * skill_lv; //Exp increase bonus. break; + case BD_SIEGFRIED: - val1 = 55 + skill_lv*5; //Elemental Resistance - val2 = skill_lv*10; //Status ailment resistance + val1 = 55 + skill_lv * 5; // Elemental Resistance + val2 = skill_lv * 10; // Status ailment resistance break; +#endif case WE_CALLPARTNER: if (sd) val1 = sd->status.partner_id; break; @@ -15124,7 +15293,7 @@ static int skill_check_condition_char_sub(struct block_list *bl, va_list ap) if(pc_isdead(tsd)) return 0; - if (tsd->sc.data[SC_SILENCE] || ( tsd->sc.opt1 && tsd->sc.opt1 != OPT1_BURNING )) + if (tsd->sc.data[SC_SILENCE] || tsd->sc.data[SC_ENSEMBLEFATIGUE] || ( tsd->sc.opt1 && tsd->sc.opt1 != OPT1_BURNING )) return 0; if( skill->get_inf2(skill_id)&INF2_CHORUS_SKILL ) { @@ -15160,12 +15329,18 @@ static int skill_check_condition_char_sub(struct block_list *bl, va_list ap) return 1; default: //Warning: Assuming Ensemble Dance/Songs for code speed. [Skotlex] { - uint16 skill_lv; if(pc_issit(tsd) || !unit->can_move(&tsd->bl)) return 0; + + uint16 skill_lv = pc->checkskill(tsd, skill_id); +#ifdef RENEWAL // In Renewal, partner also gets the requirements consumed, so we must check it + if (skill->check_condition_castbegin(tsd, skill_id, skill_lv) == 0) + return 0; +#endif + if (sd->status.sex != tsd->status.sex && (tsd->job & MAPID_UPPERMASK) == MAPID_BARDDANCER && - (skill_lv = pc->checkskill(tsd, skill_id)) > 0 && + skill_lv > 0 && (tsd->weapontype1==W_MUSICAL || tsd->weapontype1==W_WHIP) && sd->status.party_id && tsd->status.party_id && sd->status.party_id == tsd->status.party_id && @@ -15219,6 +15394,7 @@ static int skill_check_pc_partner(struct map_session_data *sd, uint16 skill_id, default: //Warning: Assuming Ensemble skills here (for speed) if( is_chorus ) break;//Chorus skills are not to be parsed as ensambles +#ifndef RENEWAL if (c > 0 && sd->sc.data[SC_DANCING] && (tsd = map->id2sd(p_sd[0])) != NULL) { sd->sc.data[SC_DANCING]->val4 = tsd->bl.id; sc_start4(&tsd->bl, &tsd->bl, SC_DANCING, 100, skill_id, sd->sc.data[SC_DANCING]->val2, *skill_lv, sd->bl.id, skill->get_time(skill_id, *skill_lv) + 1000, skill_id); @@ -15226,6 +15402,17 @@ static int skill_check_pc_partner(struct map_session_data *sd, uint16 skill_id, tsd->skill_id_dance = skill_id; tsd->skill_lv_dance = *skill_lv; } +#else + if (c > 0 && (tsd = map->id2sd(p_sd[0])) != NULL) { + skill->consume_requirement(tsd, skill_id, *skill_lv, 1); + clif->skill_nodamage(&tsd->bl, &sd->bl, skill_id, *skill_lv, 1); + sc_start(&sd->bl, &sd->bl, SC_ENSEMBLEFATIGUE, 100, skill_id, 10000, skill_id); + sc_start(&tsd->bl, &tsd->bl, SC_ENSEMBLEFATIGUE, 100, skill_id, 10000, skill_id); + + tsd->skill_id_dance = skill_id; + tsd->skill_lv_dance = *skill_lv; + } +#endif return c; } } @@ -15738,25 +15925,29 @@ static int skill_check_condition_castbegin(struct map_session_data *sd, uint16 s return 0; } break; //Combo ready. - case BD_ADAPTATION: - { - int time; - if(!(sc && sc->data[SC_DANCING])) - { - clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0, 0); - return 0; - } - time = 1000*(sc->data[SC_DANCING]->val3>>16); - if (skill->get_time( - (sc->data[SC_DANCING]->val1&0xFFFF), //Dance Skill ID - (sc->data[SC_DANCING]->val1>>16)) //Dance Skill LV - - time < skill->get_time2(skill_id,skill_lv)) - { - clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0, 0); - return 0; - } + +#ifndef RENEWAL + case BD_ADAPTATION: { + if (sc == NULL || sc->data[SC_DANCING] == NULL) { + clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0, 0); + return 0; + } + + int time = 1000 * (sc->data[SC_DANCING]->val3 >> 16); + + int dance_skill_id = (sc->data[SC_DANCING]->val1 & 0xFFFF); + int dance_skill_lv = (sc->data[SC_DANCING]->val1 >> 16); + int dance_duration = skill->get_time(dance_skill_id, dance_skill_lv); + + int interrupt_ticks = skill->get_time2(skill_id, skill_lv); + + if (dance_duration - time < interrupt_ticks) { + clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0, 0); + return 0; } break; + } +#endif case PR_BENEDICTIO: if (skill->check_pc_partner(sd, skill_id, &skill_lv, 1, 0) < 2) @@ -17063,6 +17254,10 @@ static struct skill_condition skill_get_requirement(struct map_session_data *sd, req.sp -= req.sp * sc->data[SC_TARGET_ASPD]->val1 / 100; if (sc->data[SC_MVPCARD_MISTRESS]) req.sp -= req.sp * sc->data[SC_MVPCARD_MISTRESS]->val1 / 100; +#ifdef RENEWAL + if (sc->data[SC_ADAPTATION] && (skill->get_inf2(skill_id) & (INF2_SONG_DANCE | INF2_ENSEMBLE_SKILL)) != 0) + req.sp -= req.sp * sc->data[SC_ADAPTATION]->val2 / 100; +#endif } req.zeny = skill->dbs->db[idx].zeny[skill_lv-1]; @@ -25470,6 +25665,8 @@ void skill_defaults(void) skill->produce_mix = skill_produce_mix; skill->arrow_create = skill_arrow_create; skill->castend_nodamage_id = skill_castend_nodamage_id; + skill->castend_nodamage_id_sc_song = skill_castend_nodamage_id_sc_song; + skill->castend_nodamage_id_ugly_dance = skill_castend_nodamage_id_ugly_dance; skill->castend_damage_id = skill_castend_damage_id; skill->castend_pos2 = skill_castend_pos2; skill->blockpc_start = skill_blockpc_start_; diff --git a/src/map/skill.h b/src/map/skill.h index df88d518fa8..2af3e3fd4e5 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -2192,6 +2192,8 @@ struct skill_interface { int (*arrow_create) ( struct map_session_data *sd,int nameid); void (*castend_type) (enum cast_enum type, struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag); int (*castend_nodamage_id) (struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag); + void (*castend_nodamage_id_sc_song) (struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag); + void (*castend_nodamage_id_ugly_dance) (struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag); int (*castend_damage_id) (struct block_list* src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick,int flag); int (*castend_pos2) (struct block_list *src, int x, int y, uint16 skill_id, uint16 skill_lv, int64 tick, int flag); int (*blockpc_start) (struct map_session_data *sd, uint16 skill_id, int tick); diff --git a/src/map/status.c b/src/map/status.c index 64c920f58d8..706b3e245bc 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -912,7 +912,9 @@ static int status_check_skilluse(struct block_list *src, struct block_list *targ return 0; } else { switch (skill_id) { +#ifndef RENEWAL case BD_ADAPTATION: +#endif case CG_LONGINGFREEDOM: case BA_MUSICALSTRIKE: case DC_THROWARROW: @@ -921,13 +923,16 @@ static int status_check_skilluse(struct block_list *src, struct block_list *targ return 0; } } - if ((sc->data[SC_DANCING]->val1&0xFFFF) == CG_HERMODE && skill_id == BD_ADAPTATION) +#ifndef RENEWAL + if ((sc->data[SC_DANCING]->val1 & 0xFFFF) == CG_HERMODE && skill_id == BD_ADAPTATION) return 0; //Can't amp out of Wand of Hermode :/ [Skotlex] +#endif } if (skill_id != 0 /* Do not block item-casted skills.*/ && (src->type != BL_PC || sd->auto_cast_current.type != AUTOCAST_ITEM)) { //Skills blocked through status changes... if (!flag && ( //Blocked only from using the skill (stuff like autospell may still go through + sc->data[SC_ENSEMBLEFATIGUE] || sc->data[SC_SILENCE] || sc->data[SC_STEELBODY] || sc->data[SC_BERSERK] || @@ -952,7 +957,11 @@ static int status_check_skilluse(struct block_list *src, struct block_list *targ //Skill blocking. if ( (sc->data[SC_VOLCANO] && skill_id == WZ_ICEWALL) || - (sc->data[SC_ROKISWEIL] && skill_id != BD_ADAPTATION) || +#ifndef RENEWAL + (sc->data[SC_ROKISWEIL] != NULL && skill_id != BD_ADAPTATION) || +#else + sc->data[SC_ROKISWEIL] != NULL || +#endif (sc->data[SC_HERMODE] && skill->get_inf(skill_id) & INF_SUPPORT_SKILL) || pc_ismuted(sc, MANNER_NOSKILL) ) @@ -1967,6 +1976,12 @@ static int status_calc_pc_(struct map_session_data *sd, enum e_status_calc_opt o bstatus->max_sp += 30 * skill_lv; if ((pc->checkskill(sd,SU_SPRITEMABLE)) > 0) bstatus->max_sp += 100; +#ifdef RENEWAL + if((skill_lv = pc->checkskill(sd, BA_MUSICALLESSON)) > 0) + bstatus->max_sp += (int64) bstatus->max_sp * skill_lv / 100; + if((skill_lv = pc->checkskill(sd, DC_DANCINGLESSON)) > 0) + bstatus->max_sp += (int64) bstatus->max_sp * skill_lv / 100; +#endif // Apply relative modifiers from equipment if(sd->sprate < 0) @@ -2029,6 +2044,8 @@ static int status_calc_pc_(struct map_session_data *sd, enum e_status_calc_opt o #ifdef RENEWAL if ((skill_lv = pc->checkskill(sd, PR_MACEMASTERY)) > 0 && (sd->weapontype == W_MACE || sd->weapontype == W_2HMACE)) bstatus->cri += skill_lv * 10; + if ((skill_lv = pc->checkskill(sd, DC_DANCINGLESSON)) > 0 && sd->weapontype == W_WHIP) + bstatus->cri += skill_lv * 10; #endif if(sd->flee2_rate < 0) @@ -2178,6 +2195,11 @@ static int status_calc_pc_(struct map_session_data *sd, enum e_status_calc_opt o if(sc->data[SC_ATKER_BLOOD]) sd->dsprate -= sc->data[SC_ATKER_BLOOD]->val1; +#ifdef RENEWAL + if (sc->data[SC_NIBELUNGEN] != NULL && sc->data[SC_NIBELUNGEN]->val2 == RINGNBL_EFF_SP_CONSUMPTION) + sd->dsprate -= 30; +#endif + //Underflow protections. if(sd->dsprate < 0) sd->dsprate = 0; @@ -2881,6 +2903,11 @@ static void status_calc_regen_rate_pc(struct map_session_data *sd, struct regen_ } } +#ifdef RENEWAL + if (sc->data[SC_APPLEIDUN] != NULL) + regen->hp += regen->hp * sc->data[SC_APPLEIDUN]->val3 / 100; +#endif + if (sc->data[SC_CATNIPPOWDER] != NULL) { regen->rate.hp *= 2; regen->rate.sp *= 2; @@ -2894,6 +2921,13 @@ static void status_calc_regen_rate_pc(struct map_session_data *sd, struct regen_ regen->rate.hp *= 3; regen->skill->rate.hp *= 3; } + +#ifdef RENEWAL + if (sc->data[SC_NIBELUNGEN] != NULL && sc->data[SC_NIBELUNGEN]->val2 == RINGNBL_EFF_HP_RECOVERY) + regen->rate.hp += 100; + if (sc->data[SC_NIBELUNGEN] != NULL && sc->data[SC_NIBELUNGEN]->val2 == RINGNBL_EFF_SP_RECOVERY) + regen->rate.sp += 100; +#endif } static void status_calc_regen_rate_elemental(struct elemental_data *md, struct regen_data *regen) @@ -3718,6 +3752,9 @@ static int status_base_amotion_pc(struct map_session_data *sd, struct status_dat val += ((skill_lv + 1) / 2); if ((skill_lv = pc->checkskill(sd, RG_PLAGIARISM)) > 0) val += skill_lv; + if (sd->weapontype == W_MUSICAL && (skill_lv = pc->checkskill(sd, BA_MUSICALLESSON)) > 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 @@ -4015,6 +4052,11 @@ static unsigned short status_calc_str(struct block_list *bl, struct status_chang if (sc->data[SC_UNIVERSESTANCE] != NULL) str += sc->data[SC_UNIVERSESTANCE]->val2; +#ifdef RENEWAL + if (sc->data[SC_NIBELUNGEN] != NULL && sc->data[SC_NIBELUNGEN]->val2 == RINGNBL_EFF_ALLSTATS) + str += 15; +#endif + return (unsigned short)cap_value(str,0,USHRT_MAX); } @@ -4080,6 +4122,11 @@ static unsigned short status_calc_agi(struct block_list *bl, struct status_chang if (sc->data[SC_UNIVERSESTANCE] != NULL) agi += sc->data[SC_UNIVERSESTANCE]->val2; +#ifdef RENEWAL + if (sc->data[SC_NIBELUNGEN] != NULL && sc->data[SC_NIBELUNGEN]->val2 == RINGNBL_EFF_ALLSTATS) + agi += 15; +#endif + return (unsigned short)cap_value(agi,0,USHRT_MAX); } @@ -4133,6 +4180,11 @@ static unsigned short status_calc_vit(struct block_list *bl, struct status_chang if (sc->data[SC_UNIVERSESTANCE] != NULL) vit += sc->data[SC_UNIVERSESTANCE]->val2; +#ifdef RENEWAL + if (sc->data[SC_NIBELUNGEN] != NULL && sc->data[SC_NIBELUNGEN]->val2 == RINGNBL_EFF_ALLSTATS) + vit += 15; +#endif + return (unsigned short)cap_value(vit,0,USHRT_MAX); } @@ -4202,6 +4254,11 @@ static unsigned short status_calc_int(struct block_list *bl, struct status_chang if (sc->data[SC_UNIVERSESTANCE] != NULL) int_ += sc->data[SC_UNIVERSESTANCE]->val2; +#ifdef RENEWAL + if (sc->data[SC_NIBELUNGEN] != NULL && sc->data[SC_NIBELUNGEN]->val2 == RINGNBL_EFF_ALLSTATS) + int_ += 15; +#endif + return (unsigned short)cap_value(int_,0,USHRT_MAX); } @@ -4267,6 +4324,11 @@ static unsigned short status_calc_dex(struct block_list *bl, struct status_chang if (sc->data[SC_UNIVERSESTANCE] != NULL) dex += sc->data[SC_UNIVERSESTANCE]->val2; +#ifdef RENEWAL + if (sc->data[SC_NIBELUNGEN] != NULL && sc->data[SC_NIBELUNGEN]->val2 == RINGNBL_EFF_ALLSTATS) + dex += 15; +#endif + return (unsigned short)cap_value(dex,0,USHRT_MAX); } @@ -4324,6 +4386,11 @@ static unsigned short status_calc_luk(struct block_list *bl, struct status_chang if (sc->data[SC_UNIVERSESTANCE] != NULL) luk += sc->data[SC_UNIVERSESTANCE]->val2; +#ifdef RENEWAL + if (sc->data[SC_NIBELUNGEN] != NULL && sc->data[SC_NIBELUNGEN]->val2 == RINGNBL_EFF_ALLSTATS) + luk += 15; +#endif + return (unsigned short)cap_value(luk, 0, USHRT_MAX); } @@ -4566,17 +4633,22 @@ static int status_calc_batk(struct block_list *bl, struct status_change *sc, int if (sc->data[SC_SUNSTANCE] != NULL) batk += batk * sc->data[SC_SUNSTANCE]->val2 / 100; +#ifdef RENEWAL + if (sc->data[SC_NIBELUNGEN] != NULL && sc->data[SC_NIBELUNGEN]->val2 == RINGNBL_EFF_ATK) + batk += batk * 20/100; +#endif + return cap_value(batk, battle_config.batk_min, battle_config.batk_max); } /** * Calculates bl's Extra ATK gains from Buffs. - * + * * These are very specific bonus from SCs where: * - They show in status window ATK right side (after the + sign) * - They are given by SCs, but they work like equipment's ATK bonus * - They are not linked to the weapon attack value - * + * * @param bl unit whose status is being calculated * @param sc unit's SC list * @returns Value of Extra ATK conceded by buffs @@ -4596,6 +4668,8 @@ static int status_calc_buff_extra_batk(struct block_list *bl, struct status_chan batk += sc->data[SC_SHOUT]->val2; if (sc->data[SC_IMPOSITIO] != NULL) batk += sc->data[SC_IMPOSITIO]->val2; + if (sc->data[SC_DRUMBATTLE] != NULL) + batk += sc->data[SC_DRUMBATTLE]->val2; #endif return cap_value(batk, 0, battle_config.batk_max); @@ -4681,6 +4755,11 @@ static int status_calc_watk(struct block_list *bl, struct status_change *sc, int if (sc->data[SC_SOULFALCON] != NULL) watk += sc->data[SC_SOULFALCON]->val2; +#ifdef RENEWAL + if (sc->data[SC_NIBELUNGEN] != NULL && sc->data[SC_NIBELUNGEN]->val2 == SC_INCATKRATE) + watk += watk * 20/100; +#endif + return cap_value(watk, battle_config.watk_min, battle_config.watk_max); } @@ -4757,6 +4836,8 @@ static int status_calc_matk(struct block_list *bl, struct status_change *sc, int // FIXME: This (and SC_IMPOSITIO) should have their effects shown in status window. if (sc->data[SC_VOLCANO] != NULL) matk += sc->data[SC_VOLCANO]->val2; + if (sc->data[SC_NIBELUNGEN] != NULL && sc->data[SC_NIBELUNGEN]->val2 == RINGNBL_EFF_MATK) + matk += matk * 20/100; #endif if (sc->data[SC_ZANGETSU]) matk += sc->data[SC_ZANGETSU]->val3; @@ -4815,7 +4896,7 @@ static int status_calc_critical(struct block_list *bl, struct status_change *sc, critical += sc->data[SC_FOOD_CRITICALSUCCESSVALUE]->val1; if (sc->data[SC_EXPLOSIONSPIRITS]) critical += sc->data[SC_EXPLOSIONSPIRITS]->val2; - if (sc->data[SC_FORTUNE]) + if (sc->data[SC_FORTUNE] != NULL) critical += sc->data[SC_FORTUNE]->val2; if (sc->data[SC_TRUESIGHT]) critical += sc->data[SC_TRUESIGHT]->val2; @@ -4906,6 +4987,8 @@ static int status_calc_hit(struct block_list *bl, struct status_change *sc, int hit += 2 * sc->data[SC_TWOHANDQUICKEN]->val1; if (sc->data[SC_ADRENALINE] != NULL) hit += sc->data[SC_ADRENALINE]->val4; + if (sc->data[SC_NIBELUNGEN] != NULL && sc->data[SC_NIBELUNGEN]->val2 == RINGNBL_EFF_HIT) + hit += 50; #endif return cap_value(hit, battle_config.hit_min, battle_config.hit_max); @@ -4965,6 +5048,8 @@ static int status_calc_flee(struct block_list *bl, struct status_change *sc, int #ifdef RENEWAL if (sc->data[SC_SPEARQUICKEN]) flee += sc->data[SC_SPEARQUICKEN]->val1 * 2; + if (sc->data[SC_NIBELUNGEN] != NULL && sc->data[SC_NIBELUNGEN]->val2 == RINGNBL_EFF_FLEE) + flee += 50; #endif if (sc->data[SC_INCFLEERATE]) flee += flee * sc->data[SC_INCFLEERATE]->val1 / 100; @@ -5054,6 +5139,11 @@ static defType status_calc_def(struct block_list *bl, struct status_change *sc, return (defType)cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX); } +#ifdef RENEWAL + if (sc->data[SC_ETERNALCHAOS] != NULL) + return 0; +#endif + if (sc->data[SC_BERSERK]) return 0; if (sc->data[SC_SKA]) @@ -5411,6 +5501,8 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha } if (sc->data[SC_CATNIPPOWDER]) val = max(val, sc->data[SC_CATNIPPOWDER]->val3); + if (sc->data[SC_ENSEMBLEFATIGUE] != NULL) + val = max(val, 30); // 30% MoveSpeed reduction if (sc->data[SC_BIND_TRAP]) val = max(val, sc->data[SC_BIND_TRAP]->val3); if (sc->data[SC_CREATINGSTAR] != NULL) @@ -5564,6 +5656,8 @@ static short status_calc_aspd(struct block_list *bl, struct status_change *sc, s // ASPD percentage values if (sc->data[SC_DONTFORGETME]) bonus -= sc->data[SC_DONTFORGETME]->val2; + if (sc->data[SC_ENSEMBLEFATIGUE] != NULL) + bonus -= 30; // 30% Attack Speed reduction if (sc->data[SC_LONGING]) bonus -= sc->data[SC_LONGING]->val2; if (sc->data[SC_STEELBODY]) @@ -5636,6 +5730,8 @@ static short status_calc_aspd(struct block_list *bl, struct status_change *sc, s bonus += 10; if (sc->data[SC_SPEARQUICKEN] != NULL) bonus += 10; + if (sc->data[SC_NIBELUNGEN] != NULL && sc->data[SC_NIBELUNGEN]->val2 == RINGNBL_EFF_ASPD) + bonus += 20; #endif } @@ -5915,6 +6011,8 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang #ifdef RENEWAL if (sc->data[SC_ANGELUS] != NULL) maxhp += sc->data[SC_ANGELUS]->val3; + if (sc->data[SC_NIBELUNGEN] != NULL && sc->data[SC_NIBELUNGEN]->val2 == RINGNBL_EFF_MAXHP) + maxhp += maxhp * 30 / 100; #endif return (unsigned int)cap_value(maxhp, 1, UINT_MAX); @@ -5956,6 +6054,11 @@ static unsigned int status_calc_maxsp(struct block_list *bl, struct status_chang if (sc->data[SC_GM_BATTLE2]) maxsp -= maxsp * sc->data[SC_GM_BATTLE2]->val1 / 100; +#ifdef RENEWAL + if (sc->data[SC_NIBELUNGEN] != NULL && sc->data[SC_NIBELUNGEN]->val2 == RINGNBL_EFF_MAXSP) + maxsp += maxsp * 30 / 100; +#endif + return cap_value(maxsp, 1, UINT_MAX); } @@ -7651,6 +7754,7 @@ static int status_change_start_sub(struct block_list *src, struct block_list *bl case SC_FLASHKICK: case SC_SOULUNITY: case SC__AUTOSHADOWSPELL: // otherwise you can't change your shadow spell to a lower skill_id + case SC_ENSEMBLEFATIGUE: break; case SC_GOSPEL: //Must not override a casting gospel char. @@ -7888,7 +7992,7 @@ static int status_change_start_sub(struct block_list *src, struct block_list *bl case SC_VOLCANO: #ifndef RENEWAL val2 = val1 * 10; // Watk increase - + if (st->def_ele != ELE_FIRE) val2 = 0; #else @@ -7945,6 +8049,98 @@ static int status_change_start_sub(struct block_list *src, struct block_list *bl val3 = total_tick/1000; //Tick duration tick_time = 1000; // [GodLesZ] tick time break; + +#ifdef RENEWAL + case SC_RICHMANKIM: + val1 = 10 + 10 * val1; // EXP increase (%) + break; + + case SC_DRUMBATTLE: + // - val1: Skill Lv + val2 = 15 + val1 * 5; // ATK increase + val3 = val1 * 15; // Def increase + break; + + case SC_NIBELUNGEN: + // val1 = skill lv + val2 = rnd() % RINGNBL_EFF_MAX; + break; + + case SC_ROKISWEIL: + // val1 = skill lv + // TODO: needs more info. It is correct to cause confusion Health State, + // but I am not 100% sure about rate and time + sc_start(src, bl, SC_CONFUSION, 100, 1, 20000, skill_id); + break; + + case SC_SIEGFRIED: + // - val1: Skill Lv + val2 = val1 * 3; // Elemental Resistance + val3 = val1 * 5; // Status ailment resistance + break; + + case SC_WHISTLE: + // val1: Skill Lv + val2 = (val1 < 10 ? (18 + val1 * 2) : 40); // Flee Increase + val3 = (val1 + 1) / 2; // Perfect Dodge increase + break; + + case SC_ASSNCROS: + // val1 = skill lv + if (val1 < 10) + val2 = 1 + (val1 - 1) * 2; // ASPD increase + else + val2 = 20; // ASPD increase + break; + + case SC_POEMBRAGI: + // val1 = skill lv + val2 = val1 * 2; // Cast time reduction + val3 = val1 * 3; // After-cast delay reduction + break; + + case SC_APPLEIDUN: + // - val1: Skill Lv + val2 = (val1 < 10 ? (9 + val1) : 20); // MaxHP % + val3 = 2 * val1; // Recovery Boost % + break; + + case SC_HUMMING: + // Official servers uses "val1" for the bonus, but using val2 aligns with pre-re buff + // - val1: Skill Lv + val2 = 4 * val1; // Hit increase + break; + + case SC_DONTFORGETME: { + // - val1: Skill Lv + val2 = 3 * val1; // Base ASPD decrease + val3 = 2 * val1; // Base Movement speed adjustment. + + struct status_data *srcst; + if (src != NULL && (srcst = status->get_status_data(src)) != NULL) { + val2 += srcst->dex / 15; // Stats-based ASPD decrease + val3 += srcst->agi / 20; // Stats-based Movement speed adjustment. + } + break; + } + + case SC_FORTUNE: + // - val1: Skill Lv + val2 = val1 * 10; // Critical increase (10 = +1) + val3 = val1 * 2; // Critical Damage Increase + break; + + case SC_SERVICEFORYOU: + // - val1: Skill Lv + val2 = (val1 < 10 ? (9 + val1) : 20); // MaxSP percent increase + val3 = val1 + 5; // SP cost reduction + break; + + case SC_ADAPTATION: + val2 = 20; // 20% SP cost reduction + break; +#endif + case SC_LONGING: #ifdef RENEWAL val2 = 50 + 10 * val1; @@ -8395,7 +8591,7 @@ static int status_change_start_sub(struct block_list *src, struct block_list *bl } else { val2 = 0; //0 means that STR, DEX and INT should be halved } - + val1 += bonus; // Officially, val1 is incremented (for us, this doesn't make a difference) break; } @@ -10536,6 +10732,11 @@ static bool status_end_sc_before_start(struct block_list *bl, struct status_data status_change_end(bl, SC_ONEHANDQUICKEN, INVALID_TIMER); status_change_end(bl, SC_MER_QUICKEN, INVALID_TIMER); status_change_end(bl, SC_ACCELERATION, INVALID_TIMER); +#ifdef RENEWAL // Dancer performance buffs (don't overlap) + status_change_end(bl, SC_HUMMING, INVALID_TIMER); + status_change_end(bl, SC_FORTUNE, INVALID_TIMER); + status_change_end(bl, SC_SERVICEFORYOU, INVALID_TIMER); +#endif break; case SC_ONEHANDQUICKEN: // Removes the Aspd potion effect, as reported by Vicious. [Skotlex] @@ -10687,6 +10888,57 @@ static bool status_end_sc_before_start(struct block_list *bl, struct status_data status_change_end(bl, SC_ATTHASTE_POTION3, INVALID_TIMER); status_change_end(bl, SC_ATTHASTE_INFINITY, INVALID_TIMER); break; + +#ifdef RENEWAL + // Bard-only songs Group (doesn't overlap) + case SC_WHISTLE: + case SC_ASSNCROS: + case SC_POEMBRAGI: + case SC_APPLEIDUN: { + int group_scs[] = { SC_WHISTLE, SC_ASSNCROS, SC_POEMBRAGI, SC_APPLEIDUN }; + + for (int i = 0; i < ARRAYLENGTH(group_scs); ++i) { + if (type != group_scs[i]) + status_change_end(bl, group_scs[i], INVALID_TIMER); + } + break; + } + + // Dancer-only songs Group (doesn't overlap) + case SC_HUMMING: + case SC_FORTUNE: + // case SC_DONTFORGETME: // Independently checked above + case SC_SERVICEFORYOU: { + int group_scs[] = { SC_HUMMING, SC_FORTUNE, SC_SERVICEFORYOU, SC_DONTFORGETME }; + + for (int i = 0; i < ARRAYLENGTH(group_scs); ++i) { + if (type != group_scs[i]) + status_change_end(bl, group_scs[i], INVALID_TIMER); + } + break; + } + + // Ensemble songs Group (doesn't overlap) + case SC_ROKISWEIL: + case SC_ETERNALCHAOS: + case SC_SIEGFRIED: + case SC_DRUMBATTLE: + case SC_NIBELUNGEN: + case SC_RICHMANKIM: + case SC_INTOABYSS: { + int group_scs[] = { + SC_ROKISWEIL, SC_ETERNALCHAOS, SC_SIEGFRIED, SC_DRUMBATTLE, + SC_NIBELUNGEN, SC_RICHMANKIM, SC_INTOABYSS, + }; + + for (int i = 0; i < ARRAYLENGTH(group_scs); ++i) { + if (type != group_scs[i]) + status_change_end(bl, group_scs[i], INVALID_TIMER); + } + break; + } +#endif + // Group A Status (doesn't overlap) case SC_SWING: case SC_SYMPHONY_LOVE: @@ -12290,43 +12542,46 @@ static int status_change_timer(int tid, int64 tick, int id, intptr_t data) if (--sce->val3 <= 0) break; switch(sce->val1&0xFFFF){ - case BD_RICHMANKIM: +#ifndef RENEWAL case BD_DRUMBATTLEFIELD: - case BD_RINGNIBELUNGEN: case BD_SIEGFRIED: + case BD_RICHMANKIM: + case BD_RINGNIBELUNGEN: case BA_DISSONANCE: case BA_ASSASSINCROSS: case DC_UGLYDANCE: - s=3; + s = 3; break; case BD_LULLABY: - case BD_ETERNALCHAOS: case BD_ROKISWEIL: + case BD_ETERNALCHAOS: case DC_FORTUNEKISS: - s=4; + s = 4; break; +#endif case CG_HERMODE: +#ifndef RENEWAL case BD_INTOABYSS: - case BA_WHISTLE: case DC_HUMMING: + case BA_WHISTLE: case BA_POEMBRAGI: case DC_SERVICEFORYOU: - s=5; +#endif + s = 5; break; +#ifndef RENEWAL case BA_APPLEIDUN: - #ifdef RENEWAL - s=5; - #else - s=6; - #endif + s = 6; break; - case CG_MOONLIT: - //Moonlit's cost is 4sp*skill_lv [Skotlex] - sp= 4*(sce->val1>>16); - //Upkeep is also every 10 secs. - FALLTHROUGH + case DC_DONTFORGETME: - s=10; + s = 10; + break; +#endif + case CG_MOONLIT: + // Moonlit's cost is 4sp * skill_lv [Skotlex] + sp = 4*(sce->val1>>16); + s = 10; break; } if( s != 0 && sce->val3 % s == 0 ) { diff --git a/src/map/status.h b/src/map/status.h index c1a30ed817c..9d1f1687255 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -921,6 +921,10 @@ typedef enum sc_type { SC_NO_SWITCH_WEAPON, + // More SCs for bard/dancer + SC_ENSEMBLEFATIGUE, + SC_ADAPTATION, + #ifndef SC_MAX SC_MAX, //Automatically updated max, used in for's to check we are within bounds. #endif @@ -1121,6 +1125,26 @@ enum e_status_calc_opt { SCO_FORCE = 0x2, /* only relevant to BL_PC types, ensures call bypasses the queue caused by delayed damage */ }; +/** + * Possible bonuses given by Ring Nimbelung (Harmonic Lick) in RE + * (SC_NIBELUNGEN val2) + */ +enum e_ringnibelungen_effect { + RINGNBL_EFF_ASPD = 0, //< Increases attack speed (reduces delay after attack by 20%) + RINGNBL_EFF_ATK, //< Atk + 20% + RINGNBL_EFF_MATK, //< Matk + 20% + RINGNBL_EFF_MAXHP, //< MaxHP + 30% + RINGNBL_EFF_MAXSP, //< MaxSP + 30% + RINGNBL_EFF_ALLSTATS, //< All Stat + 15 + RINGNBL_EFF_HIT, //< Hit + 50 + RINGNBL_EFF_FLEE, //< Flee + 50 + RINGNBL_EFF_SP_CONSUMPTION, //< Reduces SP consumption of skills by 30% + RINGNBL_EFF_HP_RECOVERY, //< Increases HP recovery by 100% + RINGNBL_EFF_SP_RECOVERY, //< Increases SP recovery by 100% + // Must always be the last one + RINGNBL_EFF_MAX, +}; + //Define to determine who gets HP/SP consumed on doing skills/etc. [Skotlex] #define BL_CONSUME (BL_PC|BL_HOM|BL_MER|BL_ELEM) //Define to determine who has regen diff --git a/src/map/unit.c b/src/map/unit.c index 110fe50fa67..95045794d5a 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -1558,8 +1558,12 @@ static int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill tstatus = status->get_status_data(target); // Record the status of the previous skill) if (sd) { - - if ((skill->get_inf2(skill_id)&INF2_ENSEMBLE_SKILL) && skill->check_pc_partner(sd, skill_id, &skill_lv, 1, 0) < 1) { +#ifdef RENEWAL + static const int ensemble_range = 4; +#else + static const int ensemble_range = 1; +#endif + if ((skill->get_inf2(skill_id)&INF2_ENSEMBLE_SKILL) && skill->check_pc_partner(sd, skill_id, &skill_lv, ensemble_range, 0) < 1) { clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0, 0); return 0; } diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc index 9f05793b440..5a24f3d6c95 100644 --- a/src/plugins/HPMHooking/HPMHooking.Defs.inc +++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc @@ -7180,8 +7180,8 @@ typedef void (*HPMHOOK_pre_pc_checkbaselevelup_sc) (struct map_session_data **sd typedef void (*HPMHOOK_post_pc_checkbaselevelup_sc) (struct map_session_data *sd); typedef int (*HPMHOOK_pre_pc_checkjoblevelup) (struct map_session_data **sd); typedef int (*HPMHOOK_post_pc_checkjoblevelup) (int retVal___, struct map_session_data *sd); -typedef bool (*HPMHOOK_pre_pc_gainexp) (struct map_session_data **sd, struct block_list **src, uint64 *base_exp, uint64 *job_exp, bool *is_quest); -typedef bool (*HPMHOOK_post_pc_gainexp) (bool retVal___, struct map_session_data *sd, struct block_list *src, uint64 base_exp, uint64 job_exp, bool is_quest); +typedef bool (*HPMHOOK_pre_pc_gainexp) (struct map_session_data **sd, struct block_list **src, uint64 *base_exp, uint64 *job_exp, enum gainexp_flags *flags); +typedef bool (*HPMHOOK_post_pc_gainexp) (bool retVal___, struct map_session_data *sd, struct block_list *src, uint64 base_exp, uint64 job_exp, enum gainexp_flags flags); typedef uint64 (*HPMHOOK_pre_pc_nextbaseexp) (const struct map_session_data **sd); typedef uint64 (*HPMHOOK_post_pc_nextbaseexp) (uint64 retVal___, const struct map_session_data *sd); typedef uint64 (*HPMHOOK_pre_pc_thisbaseexp) (const struct map_session_data **sd); @@ -7434,8 +7434,8 @@ typedef int (*HPMHOOK_pre_pc_bonus_addeff_onskill) (struct s_addeffectonskill ** typedef int (*HPMHOOK_post_pc_bonus_addeff_onskill) (int retVal___, struct s_addeffectonskill *effect, int max, enum sc_type id, short rate, short skill_id, unsigned char target); typedef int (*HPMHOOK_pre_pc_bonus_item_drop) (struct s_add_drop **drop, const short *max, int *id, bool *is_group, int *race, int *rate); typedef int (*HPMHOOK_post_pc_bonus_item_drop) (int retVal___, struct s_add_drop *drop, const short max, int id, bool is_group, int race, int rate); -typedef void (*HPMHOOK_pre_pc_calcexp) (struct map_session_data **sd, uint64 **base_exp, uint64 **job_exp, struct block_list **src); -typedef void (*HPMHOOK_post_pc_calcexp) (struct map_session_data *sd, uint64 *base_exp, uint64 *job_exp, struct block_list *src); +typedef void (*HPMHOOK_pre_pc_calcexp) (struct map_session_data **sd, uint64 **base_exp, uint64 **job_exp, struct block_list **src, enum gainexp_flags *flags); +typedef void (*HPMHOOK_post_pc_calcexp) (struct map_session_data *sd, uint64 *base_exp, uint64 *job_exp, struct block_list *src, enum gainexp_flags flags); typedef int (*HPMHOOK_pre_pc_respawn_timer) (int *tid, int64 *tick, int *id, intptr_t *data); typedef int (*HPMHOOK_post_pc_respawn_timer) (int retVal___, int tid, int64 tick, int id, intptr_t data); typedef int (*HPMHOOK_pre_pc_jobchange_killclone) (struct block_list **bl, va_list ap); @@ -8524,6 +8524,10 @@ typedef void (*HPMHOOK_pre_skill_castend_type) (enum cast_enum *type, struct blo typedef void (*HPMHOOK_post_skill_castend_type) (enum cast_enum type, struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag); typedef int (*HPMHOOK_pre_skill_castend_nodamage_id) (struct block_list **src, struct block_list **bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag); typedef int (*HPMHOOK_post_skill_castend_nodamage_id) (int retVal___, struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag); +typedef void (*HPMHOOK_pre_skill_castend_nodamage_id_sc_song) (struct block_list **src, struct block_list **bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag); +typedef void (*HPMHOOK_post_skill_castend_nodamage_id_sc_song) (struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag); +typedef void (*HPMHOOK_pre_skill_castend_nodamage_id_ugly_dance) (struct block_list **src, struct block_list **bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag); +typedef void (*HPMHOOK_post_skill_castend_nodamage_id_ugly_dance) (struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag); typedef int (*HPMHOOK_pre_skill_castend_damage_id) (struct block_list **src, struct block_list **bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag); typedef int (*HPMHOOK_post_skill_castend_damage_id) (int retVal___, struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag); typedef int (*HPMHOOK_pre_skill_castend_pos2) (struct block_list **src, int *x, int *y, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag); @@ -9198,6 +9202,8 @@ typedef short (*HPMHOOK_pre_status_calc_mdef2) (struct block_list **bl, struct s typedef short (*HPMHOOK_post_status_calc_mdef2) (short retVal___, struct block_list *bl, struct status_change *sc, int mdef2, bool viewable); typedef int (*HPMHOOK_pre_status_calc_batk) (struct block_list **bl, struct status_change **sc, int *batk, bool *viewable); typedef int (*HPMHOOK_post_status_calc_batk) (int retVal___, struct block_list *bl, struct status_change *sc, int batk, bool viewable); +typedef int (*HPMHOOK_pre_status_calc_buff_extra_batk) (struct block_list **bl, struct status_change **sc); +typedef int (*HPMHOOK_post_status_calc_buff_extra_batk) (int retVal___, struct block_list *bl, struct status_change *sc); typedef int (*HPMHOOK_pre_status_base_matk) (struct block_list **bl, const struct status_data **st, int *level); typedef int (*HPMHOOK_post_status_base_matk) (int retVal___, struct block_list *bl, const struct status_data *st, int level); typedef int (*HPMHOOK_pre_status_get_weapon_atk) (struct block_list **src, struct weapon_atk **watk, int *flag); diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc index eaba4419a28..3aa47798f61 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc @@ -6446,6 +6446,10 @@ struct { struct HPMHookPoint *HP_skill_castend_type_post; struct HPMHookPoint *HP_skill_castend_nodamage_id_pre; struct HPMHookPoint *HP_skill_castend_nodamage_id_post; + struct HPMHookPoint *HP_skill_castend_nodamage_id_sc_song_pre; + struct HPMHookPoint *HP_skill_castend_nodamage_id_sc_song_post; + struct HPMHookPoint *HP_skill_castend_nodamage_id_ugly_dance_pre; + struct HPMHookPoint *HP_skill_castend_nodamage_id_ugly_dance_post; struct HPMHookPoint *HP_skill_castend_damage_id_pre; struct HPMHookPoint *HP_skill_castend_damage_id_post; struct HPMHookPoint *HP_skill_castend_pos2_pre; @@ -7114,6 +7118,8 @@ struct { struct HPMHookPoint *HP_status_calc_mdef2_post; struct HPMHookPoint *HP_status_calc_batk_pre; struct HPMHookPoint *HP_status_calc_batk_post; + struct HPMHookPoint *HP_status_calc_buff_extra_batk_pre; + struct HPMHookPoint *HP_status_calc_buff_extra_batk_post; struct HPMHookPoint *HP_status_base_matk_pre; struct HPMHookPoint *HP_status_base_matk_post; struct HPMHookPoint *HP_status_get_weapon_atk_pre; @@ -14023,6 +14029,10 @@ struct { int HP_skill_castend_type_post; int HP_skill_castend_nodamage_id_pre; int HP_skill_castend_nodamage_id_post; + int HP_skill_castend_nodamage_id_sc_song_pre; + int HP_skill_castend_nodamage_id_sc_song_post; + int HP_skill_castend_nodamage_id_ugly_dance_pre; + int HP_skill_castend_nodamage_id_ugly_dance_post; int HP_skill_castend_damage_id_pre; int HP_skill_castend_damage_id_post; int HP_skill_castend_pos2_pre; @@ -14691,6 +14701,8 @@ struct { int HP_status_calc_mdef2_post; int HP_status_calc_batk_pre; int HP_status_calc_batk_post; + int HP_status_calc_buff_extra_batk_pre; + int HP_status_calc_buff_extra_batk_post; int HP_status_base_matk_pre; int HP_status_base_matk_post; int HP_status_get_weapon_atk_pre; diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc index b6b47879c22..3e990f9d023 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc @@ -3299,6 +3299,8 @@ struct HookingPointData HookingPoints[] = { { HP_POP(skill->arrow_create, HP_skill_arrow_create) }, { HP_POP(skill->castend_type, HP_skill_castend_type) }, { HP_POP(skill->castend_nodamage_id, HP_skill_castend_nodamage_id) }, + { HP_POP(skill->castend_nodamage_id_sc_song, HP_skill_castend_nodamage_id_sc_song) }, + { HP_POP(skill->castend_nodamage_id_ugly_dance, HP_skill_castend_nodamage_id_ugly_dance) }, { HP_POP(skill->castend_damage_id, HP_skill_castend_damage_id) }, { HP_POP(skill->castend_pos2, HP_skill_castend_pos2) }, { HP_POP(skill->blockpc_start, HP_skill_blockpc_start) }, @@ -3636,6 +3638,7 @@ struct HookingPointData HookingPoints[] = { { HP_POP(status->calc_mdef, HP_status_calc_mdef) }, { HP_POP(status->calc_mdef2, HP_status_calc_mdef2) }, { HP_POP(status->calc_batk, HP_status_calc_batk) }, + { HP_POP(status->calc_buff_extra_batk, HP_status_calc_buff_extra_batk) }, { HP_POP(status->base_matk, HP_status_base_matk) }, { HP_POP(status->get_weapon_atk, HP_status_get_weapon_atk) }, { HP_POP(status->get_total_mdef, HP_status_get_total_mdef) }, diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc index 9861cbe91e5..0c2890d0939 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc @@ -68572,15 +68572,15 @@ int HP_pc_checkjoblevelup(struct map_session_data *sd) { } return retVal___; } -bool HP_pc_gainexp(struct map_session_data *sd, struct block_list *src, uint64 base_exp, uint64 job_exp, bool is_quest) { +bool HP_pc_gainexp(struct map_session_data *sd, struct block_list *src, uint64 base_exp, uint64 job_exp, enum gainexp_flags flags) { int hIndex = 0; bool retVal___ = false; if (HPMHooks.count.HP_pc_gainexp_pre > 0) { - bool (*preHookFunc) (struct map_session_data **sd, struct block_list **src, uint64 *base_exp, uint64 *job_exp, bool *is_quest); + bool (*preHookFunc) (struct map_session_data **sd, struct block_list **src, uint64 *base_exp, uint64 *job_exp, enum gainexp_flags *flags); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_pc_gainexp_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_pc_gainexp_pre[hIndex].func; - retVal___ = preHookFunc(&sd, &src, &base_exp, &job_exp, &is_quest); + retVal___ = preHookFunc(&sd, &src, &base_exp, &job_exp, &flags); } if (*HPMforce_return) { *HPMforce_return = false; @@ -68588,13 +68588,13 @@ bool HP_pc_gainexp(struct map_session_data *sd, struct block_list *src, uint64 b } } { - retVal___ = HPMHooks.source.pc.gainexp(sd, src, base_exp, job_exp, is_quest); + retVal___ = HPMHooks.source.pc.gainexp(sd, src, base_exp, job_exp, flags); } if (HPMHooks.count.HP_pc_gainexp_post > 0) { - bool (*postHookFunc) (bool retVal___, struct map_session_data *sd, struct block_list *src, uint64 base_exp, uint64 job_exp, bool is_quest); + bool (*postHookFunc) (bool retVal___, struct map_session_data *sd, struct block_list *src, uint64 base_exp, uint64 job_exp, enum gainexp_flags flags); for (hIndex = 0; hIndex < HPMHooks.count.HP_pc_gainexp_post; hIndex++) { postHookFunc = HPMHooks.list.HP_pc_gainexp_post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd, src, base_exp, job_exp, is_quest); + retVal___ = postHookFunc(retVal___, sd, src, base_exp, job_exp, flags); } } return retVal___; @@ -71979,14 +71979,14 @@ int HP_pc_bonus_item_drop(struct s_add_drop *drop, const short max, int id, bool } return retVal___; } -void HP_pc_calcexp(struct map_session_data *sd, uint64 *base_exp, uint64 *job_exp, struct block_list *src) { +void HP_pc_calcexp(struct map_session_data *sd, uint64 *base_exp, uint64 *job_exp, struct block_list *src, enum gainexp_flags flags) { int hIndex = 0; if (HPMHooks.count.HP_pc_calcexp_pre > 0) { - void (*preHookFunc) (struct map_session_data **sd, uint64 **base_exp, uint64 **job_exp, struct block_list **src); + void (*preHookFunc) (struct map_session_data **sd, uint64 **base_exp, uint64 **job_exp, struct block_list **src, enum gainexp_flags *flags); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_pc_calcexp_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_pc_calcexp_pre[hIndex].func; - preHookFunc(&sd, &base_exp, &job_exp, &src); + preHookFunc(&sd, &base_exp, &job_exp, &src, &flags); } if (*HPMforce_return) { *HPMforce_return = false; @@ -71994,13 +71994,13 @@ void HP_pc_calcexp(struct map_session_data *sd, uint64 *base_exp, uint64 *job_ex } } { - HPMHooks.source.pc.calcexp(sd, base_exp, job_exp, src); + HPMHooks.source.pc.calcexp(sd, base_exp, job_exp, src, flags); } if (HPMHooks.count.HP_pc_calcexp_post > 0) { - void (*postHookFunc) (struct map_session_data *sd, uint64 *base_exp, uint64 *job_exp, struct block_list *src); + void (*postHookFunc) (struct map_session_data *sd, uint64 *base_exp, uint64 *job_exp, struct block_list *src, enum gainexp_flags flags); for (hIndex = 0; hIndex < HPMHooks.count.HP_pc_calcexp_post; hIndex++) { postHookFunc = HPMHooks.list.HP_pc_calcexp_post[hIndex].func; - postHookFunc(sd, base_exp, job_exp, src); + postHookFunc(sd, base_exp, job_exp, src, flags); } } return; @@ -86019,6 +86019,58 @@ int HP_skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, } return retVal___; } +void HP_skill_castend_nodamage_id_sc_song(struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) { + int hIndex = 0; + if (HPMHooks.count.HP_skill_castend_nodamage_id_sc_song_pre > 0) { + void (*preHookFunc) (struct block_list **src, struct block_list **bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_skill_castend_nodamage_id_sc_song_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_skill_castend_nodamage_id_sc_song_pre[hIndex].func; + preHookFunc(&src, &bl, &skill_id, &skill_lv, &tick, &flag); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.skill.castend_nodamage_id_sc_song(src, bl, skill_id, skill_lv, tick, flag); + } + if (HPMHooks.count.HP_skill_castend_nodamage_id_sc_song_post > 0) { + void (*postHookFunc) (struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag); + for (hIndex = 0; hIndex < HPMHooks.count.HP_skill_castend_nodamage_id_sc_song_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_skill_castend_nodamage_id_sc_song_post[hIndex].func; + postHookFunc(src, bl, skill_id, skill_lv, tick, flag); + } + } + return; +} +void HP_skill_castend_nodamage_id_ugly_dance(struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) { + int hIndex = 0; + if (HPMHooks.count.HP_skill_castend_nodamage_id_ugly_dance_pre > 0) { + void (*preHookFunc) (struct block_list **src, struct block_list **bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_skill_castend_nodamage_id_ugly_dance_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_skill_castend_nodamage_id_ugly_dance_pre[hIndex].func; + preHookFunc(&src, &bl, &skill_id, &skill_lv, &tick, &flag); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.skill.castend_nodamage_id_ugly_dance(src, bl, skill_id, skill_lv, tick, flag); + } + if (HPMHooks.count.HP_skill_castend_nodamage_id_ugly_dance_post > 0) { + void (*postHookFunc) (struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag); + for (hIndex = 0; hIndex < HPMHooks.count.HP_skill_castend_nodamage_id_ugly_dance_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_skill_castend_nodamage_id_ugly_dance_post[hIndex].func; + postHookFunc(src, bl, skill_id, skill_lv, tick, flag); + } + } + return; +} int HP_skill_castend_damage_id(struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) { int hIndex = 0; int retVal___ = 0; @@ -95082,6 +95134,33 @@ int HP_status_calc_batk(struct block_list *bl, struct status_change *sc, int bat } return retVal___; } +int HP_status_calc_buff_extra_batk(struct block_list *bl, struct status_change *sc) { + int hIndex = 0; + int retVal___ = 0; + if (HPMHooks.count.HP_status_calc_buff_extra_batk_pre > 0) { + int (*preHookFunc) (struct block_list **bl, struct status_change **sc); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_buff_extra_batk_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_status_calc_buff_extra_batk_pre[hIndex].func; + retVal___ = preHookFunc(&bl, &sc); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.status.calc_buff_extra_batk(bl, sc); + } + if (HPMHooks.count.HP_status_calc_buff_extra_batk_post > 0) { + int (*postHookFunc) (int retVal___, struct block_list *bl, struct status_change *sc); + for (hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_buff_extra_batk_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_status_calc_buff_extra_batk_post[hIndex].func; + retVal___ = postHookFunc(retVal___, bl, sc); + } + } + return retVal___; +} int HP_status_base_matk(struct block_list *bl, const struct status_data *st, int level) { int hIndex = 0; int retVal___ = 0;