From 8fdac5ecfcf91df675728d5c7fd6a710614ec362 Mon Sep 17 00:00:00 2001 From: aleos Date: Thu, 3 Aug 2023 13:18:00 -0400 Subject: [PATCH] Refactor out a lot of hard coded hit rates * Moves skills that adjust hit rate into the skill database. --- db/import-tmpl/skill_db.yml | 6 +- db/pre-re/skill_db.yml | 181 +++++++++++++++++++++- db/re/skill_db.yml | 300 +++++++++++++++++++++++++++++++++++- db/skill_db.yml | 6 +- doc/skill_db.txt | 23 ++- doc/yaml/db/skill_db.yml | 4 + src/map/battle.cpp | 125 +++++---------- src/map/skill.cpp | 34 ++++ src/map/skill.hpp | 10 +- 9 files changed, 597 insertions(+), 92 deletions(-) diff --git a/db/import-tmpl/skill_db.yml b/db/import-tmpl/skill_db.yml index 0378bf1a4c..ce73f8b42d 100644 --- a/db/import-tmpl/skill_db.yml +++ b/db/import-tmpl/skill_db.yml @@ -37,6 +37,10 @@ # HitCount: Skill hit count. (Default: 0) # - Level Skill level. # Count Number of hits at specific skill level. +# HitRate Skill hit rate. (Default: 100) +# - Level Skill level. +# Rate Rate is a percent of hit rate added to hit rate. +# Skills: Skill flagged as a requirement (players only). (Optional) # Element: Skill element. (Default: Neutral) # - Level Skill level. # Element Element at specific skill level. @@ -140,4 +144,4 @@ Header: Type: SKILL_DB - Version: 3 + Version: 4 diff --git a/db/pre-re/skill_db.yml b/db/pre-re/skill_db.yml index efa1820212..b32f564a5a 100644 --- a/db/pre-re/skill_db.yml +++ b/db/pre-re/skill_db.yml @@ -37,6 +37,10 @@ # HitCount: Skill hit count. (Default: 0) # - Level Skill level. # Count Number of hits at specific skill level. +# HitRate Skill hit rate. (Default: 100) +# - Level Skill level. +# Rate Rate is a percent of hit rate added to hit rate. +# Skills: Skill flagged as a requirement (players only). (Optional) # Element: Skill element. (Default: Neutral) # - Level Skill level. # Element Element at specific skill level. @@ -140,7 +144,7 @@ Header: Type: SKILL_DB - Version: 3 + Version: 4 Body: - Id: 1 @@ -170,6 +174,27 @@ Body: Range: -1 Hit: Single HitCount: 1 + HitRate: + - Level: 1 + Rate: 105 + - Level: 2 + Rate: 110 + - Level: 3 + Rate: 115 + - Level: 4 + Rate: 120 + - Level: 5 + Rate: 125 + - Level: 6 + Rate: 130 + - Level: 7 + Rate: 135 + - Level: 8 + Rate: 140 + - Level: 9 + Rate: 145 + - Level: 10 + Rate: 150 Element: Weapon CopyFlags: Skill: @@ -269,6 +294,27 @@ Body: TargetTrap: true Hit: Single HitCount: 1 + HitRate: + - Level: 1 + Rate: 110 + - Level: 2 + Rate: 120 + - Level: 3 + Rate: 130 + - Level: 4 + Rate: 140 + - Level: 5 + Rate: 150 + - Level: 6 + Rate: 160 + - Level: 7 + Rate: 170 + - Level: 8 + Rate: 180 + - Level: 9 + Rate: 190 + - Level: 10 + Rate: 200 Element: Fire SplashArea: - Level: 1 @@ -2088,6 +2134,27 @@ Body: Range: -2 Hit: Multi_Hit HitCount: 3 + HitRate: + - Level: 1 + Rate: 105 + - Level: 2 + Rate: 110 + - Level: 3 + Rate: 115 + - Level: 4 + Rate: 120 + - Level: 5 + Rate: 125 + - Level: 6 + Rate: 130 + - Level: 7 + Rate: 135 + - Level: 8 + Rate: 140 + - Level: 9 + Rate: 145 + - Level: 10 + Rate: 150 Element: Weapon Requires: SpCost: 7 @@ -2232,6 +2299,7 @@ Body: Critical: true Hit: Single HitCount: 1 + HitRate: 120 Element: Weapon Duration1: - Level: 1 @@ -4768,6 +4836,29 @@ Body: Range: 1 Hit: Multi_Hit HitCount: -8 + HitRate: + - Level: 1 + Rate: 50 + - Level: 2 + Rate: 50 + - Level: 3 + Rate: 50 + - Level: 4 + Rate: 50 + - Level: 5 + Rate: 50 + - Level: 6 + Rate: 50 + - Level: 7 + Rate: 50 + - Level: 8 + Rate: 50 + - Level: 9 + Rate: 50 + - Level: 10 + Rate: 50 + Skills: + AS_SONICACCEL: true Element: Weapon AfterCastActDelay: 2000 AfterCastWalkDelay: 2000 @@ -5605,6 +5696,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Weapon Duration2: 60000 Status: Poison @@ -5619,6 +5711,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Weapon Duration2: 30000 Status: Blind @@ -5633,6 +5726,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Weapon Duration2: 30000 Status: Silence @@ -5647,6 +5741,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Weapon Duration2: 5000 Status: Stun @@ -5661,6 +5756,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Weapon Duration1: 100 Duration2: 20000 @@ -5676,6 +5772,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Dark Duration2: 30000 Status: Curse @@ -5690,6 +5787,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Weapon Duration2: 30000 Status: Sleep @@ -5716,6 +5814,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Water - Id: 185 Name: NPC_GROUNDATTACK @@ -5729,6 +5828,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Earth - Id: 186 Name: NPC_FIREATTACK @@ -5741,6 +5841,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Fire - Id: 187 Name: NPC_WINDATTACK @@ -5753,6 +5854,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Wind - Id: 188 Name: NPC_POISONATTACK @@ -5765,6 +5867,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Poison Status: Poison - Id: 189 @@ -5778,6 +5881,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Holy - Id: 190 Name: NPC_DARKNESSATTACK @@ -5790,6 +5894,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Dark - Id: 191 Name: NPC_TELEKINESISATTACK @@ -5802,6 +5907,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Ghost - Id: 192 Name: NPC_MAGICALATTACK @@ -9380,6 +9486,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Undead - Id: 348 Name: NPC_CHANGEUNDEAD @@ -9392,6 +9499,7 @@ Body: Range: -2 Hit: Single HitCount: 1 + HitRate: 120 Element: Undead Duration2: 60000 Status: ChangeUndead @@ -13089,6 +13197,7 @@ Body: Range: 4 Hit: Multi_Hit HitCount: 5 + HitRate: 120 CastTime: 1000 AfterCastActDelay: 1000 Requires: @@ -15599,6 +15708,7 @@ Body: IgnoreLandProtector: true Hit: Multi_Hit HitCount: 1 + HitRate: 120 SplashArea: - Level: 1 Area: 5 @@ -15659,6 +15769,7 @@ Body: Range: 6 Hit: Single HitCount: 1 + HitRate: 200 Element: Fire SplashArea: 3 ActiveInstance: 14 @@ -15673,6 +15784,7 @@ Body: Range: 6 Hit: Single HitCount: 1 + HitRate: 200 Element: Water SplashArea: 3 ActiveInstance: 14 @@ -15689,6 +15801,7 @@ Body: Range: 6 Hit: Single HitCount: 1 + HitRate: 200 Element: Wind SplashArea: 3 ActiveInstance: 14 @@ -15703,6 +15816,7 @@ Body: Range: 6 Hit: Single HitCount: 1 + HitRate: 200 Element: Poison SplashArea: 3 ActiveInstance: 14 @@ -15719,6 +15833,7 @@ Body: Range: 6 Hit: Single HitCount: 1 + HitRate: 200 Element: Dark SplashArea: 3 ActiveInstance: 14 @@ -15766,6 +15881,7 @@ Body: Range: -9 Hit: Single HitCount: 1 + HitRate: 120 Element: Weapon Duration2: 120000 Status: Bleeding @@ -32261,6 +32377,27 @@ Body: Range: -1 Hit: Single HitCount: 1 + HitRate: + - Level: 1 + Rate: 105 + - Level: 2 + Rate: 110 + - Level: 3 + Rate: 115 + - Level: 4 + Rate: 120 + - Level: 5 + Rate: 125 + - Level: 6 + Rate: 130 + - Level: 7 + Rate: 135 + - Level: 8 + Rate: 140 + - Level: 9 + Rate: 145 + - Level: 10 + Rate: 150 Element: Weapon Requires: SpCost: @@ -32319,6 +32456,27 @@ Body: TargetTrap: true Hit: Single HitCount: 1 + HitRate: + - Level: 1 + Rate: 110 + - Level: 2 + Rate: 120 + - Level: 3 + Rate: 130 + - Level: 4 + Rate: 140 + - Level: 5 + Rate: 150 + - Level: 6 + Rate: 160 + - Level: 7 + Rate: 170 + - Level: 8 + Rate: 180 + - Level: 9 + Rate: 190 + - Level: 10 + Rate: 200 Element: Fire SplashArea: 2 Knockback: 2 @@ -32773,6 +32931,27 @@ Body: Range: -2 Hit: Multi_Hit HitCount: 3 + HitRate: + - Level: 1 + Rate: 105 + - Level: 2 + Rate: 110 + - Level: 3 + Rate: 115 + - Level: 4 + Rate: 120 + - Level: 5 + Rate: 125 + - Level: 6 + Rate: 130 + - Level: 7 + Rate: 135 + - Level: 8 + Rate: 140 + - Level: 9 + Rate: 145 + - Level: 10 + Rate: 150 Element: Weapon Requires: SpCost: 7 diff --git a/db/re/skill_db.yml b/db/re/skill_db.yml index cfd23900cf..e6abc0abe1 100644 --- a/db/re/skill_db.yml +++ b/db/re/skill_db.yml @@ -37,6 +37,10 @@ # HitCount: Skill hit count. (Default: 0) # - Level Skill level. # Count Number of hits at specific skill level. +# HitRate Skill hit rate. (Default: 100) +# - Level Skill level. +# Rate Rate is a percent of hit rate added to hit rate. +# Skills: Skill flagged as a requirement (players only). (Optional) # Element: Skill element. (Default: Neutral) # - Level Skill level. # Element Element at specific skill level. @@ -140,7 +144,7 @@ Header: Type: SKILL_DB - Version: 3 + Version: 4 Body: - Id: 1 @@ -170,6 +174,27 @@ Body: Range: -1 Hit: Single HitCount: 1 + HitRate: + - Level: 1 + Rate: 105 + - Level: 2 + Rate: 110 + - Level: 3 + Rate: 115 + - Level: 4 + Rate: 120 + - Level: 5 + Rate: 125 + - Level: 6 + Rate: 130 + - Level: 7 + Rate: 135 + - Level: 8 + Rate: 140 + - Level: 9 + Rate: 145 + - Level: 10 + Rate: 150 Element: Weapon CopyFlags: Skill: @@ -268,6 +293,27 @@ Body: TargetTrap: true Hit: Single HitCount: 1 + HitRate: + - Level: 1 + Rate: 110 + - Level: 2 + Rate: 120 + - Level: 3 + Rate: 130 + - Level: 4 + Rate: 140 + - Level: 5 + Rate: 150 + - Level: 6 + Rate: 160 + - Level: 7 + Rate: 170 + - Level: 8 + Rate: 180 + - Level: 9 + Rate: 190 + - Level: 10 + Rate: 200 Element: Fire SplashArea: - Level: 1 @@ -2102,6 +2148,27 @@ Body: Range: -2 Hit: Multi_Hit HitCount: 3 + HitRate: + - Level: 1 + Rate: 105 + - Level: 2 + Rate: 110 + - Level: 3 + Rate: 115 + - Level: 4 + Rate: 120 + - Level: 5 + Rate: 125 + - Level: 6 + Rate: 130 + - Level: 7 + Rate: 135 + - Level: 8 + Rate: 140 + - Level: 9 + Rate: 145 + - Level: 10 + Rate: 150 Element: Weapon Requires: SpCost: 7 @@ -2247,6 +2314,7 @@ Body: Critical: true Hit: Single HitCount: 1 + HitRate: 120 Element: Weapon Duration1: - Level: 1 @@ -5013,6 +5081,29 @@ Body: Range: 1 Hit: Multi_Hit HitCount: -8 + HitRate: + - Level: 1 + Rate: 90 + - Level: 2 + Rate: 90 + - Level: 3 + Rate: 90 + - Level: 4 + Rate: 90 + - Level: 5 + Rate: 90 + - Level: 6 + Rate: 90 + - Level: 7 + Rate: 90 + - Level: 8 + Rate: 90 + - Level: 9 + Rate: 90 + - Level: 10 + Rate: 90 + Skills: + AS_SONICACCEL: true Element: Weapon Duration2: 4500 Cooldown: 1000 @@ -5875,6 +5966,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Weapon Duration2: 18000 Status: Poison @@ -5889,6 +5981,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Weapon Duration2: 18000 Status: Blind @@ -5903,6 +5996,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Weapon Duration2: 18000 Status: Silence @@ -5917,6 +6011,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Weapon Duration2: 4500 Status: Stun @@ -5931,6 +6026,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Weapon Duration1: 100 Duration2: 17000 @@ -5946,6 +6042,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Dark Duration2: 28000 Status: Curse @@ -5960,6 +6057,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Weapon Duration2: 18000 Status: Sleep @@ -5986,6 +6084,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Water - Id: 185 Name: NPC_GROUNDATTACK @@ -5999,6 +6098,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Earth - Id: 186 Name: NPC_FIREATTACK @@ -6011,6 +6111,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Fire - Id: 187 Name: NPC_WINDATTACK @@ -6023,6 +6124,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Wind - Id: 188 Name: NPC_POISONATTACK @@ -6035,6 +6137,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Poison Status: Poison - Id: 189 @@ -6048,6 +6151,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Holy - Id: 190 Name: NPC_DARKNESSATTACK @@ -6060,6 +6164,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Dark - Id: 191 Name: NPC_TELEKINESISATTACK @@ -6072,6 +6177,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Ghost - Id: 192 Name: NPC_MAGICALATTACK @@ -6386,6 +6492,27 @@ Body: Range: -1 Hit: Single HitCount: 1 + HitRate: + - Level: 1 + Rate: 105 + - Level: 2 + Rate: 110 + - Level: 3 + Rate: 115 + - Level: 4 + Rate: 120 + - Level: 5 + Rate: 125 + - Level: 6 + Rate: 130 + - Level: 7 + Rate: 135 + - Level: 8 + Rate: 140 + - Level: 9 + Rate: 145 + - Level: 10 + Rate: 150 Element: Weapon CopyFlags: Skill: @@ -9690,6 +9817,7 @@ Body: Range: -7 Hit: Single HitCount: 1 + HitRate: 120 Element: Undead - Id: 348 Name: NPC_CHANGEUNDEAD @@ -9702,6 +9830,7 @@ Body: Range: -2 Hit: Single HitCount: 1 + HitRate: 120 Element: Undead Duration2: 60000 Status: ChangeUndead @@ -13412,6 +13541,7 @@ Body: Size: 11 Hit: Multi_Hit HitCount: 5 + HitRate: 120 Element: Weapon CastTime: 800 AfterCastActDelay: 1000 @@ -15985,6 +16115,7 @@ Body: IgnoreLandProtector: true Hit: Multi_Hit HitCount: 1 + HitRate: 120 SplashArea: - Level: 1 Area: 5 @@ -16046,6 +16177,7 @@ Body: Range: 6 Hit: Single HitCount: 1 + HitRate: 200 Element: Fire SplashArea: 3 ActiveInstance: 14 @@ -16060,6 +16192,7 @@ Body: Range: 6 Hit: Single HitCount: 1 + HitRate: 200 Element: Water SplashArea: 3 ActiveInstance: 14 @@ -16076,6 +16209,7 @@ Body: Range: 6 Hit: Single HitCount: 1 + HitRate: 200 Element: Wind SplashArea: 3 ActiveInstance: 14 @@ -16090,6 +16224,7 @@ Body: Range: 6 Hit: Single HitCount: 1 + HitRate: 200 Element: Poison SplashArea: 3 ActiveInstance: 14 @@ -16106,6 +16241,7 @@ Body: Range: 6 Hit: Single HitCount: 1 + HitRate: 200 Element: Dark SplashArea: 3 ActiveInstance: 14 @@ -16153,6 +16289,7 @@ Body: Range: -9 Hit: Single HitCount: 1 + HitRate: 120 Element: Weapon Duration2: 108000 Status: Bleeding @@ -18229,6 +18366,7 @@ Body: Range: -9 Hit: Single HitCount: 1 + HitRate: 120 Element: Neutral Duration2: 108000 Status: Bleeding @@ -18243,6 +18381,7 @@ Body: Range: 6 Hit: Single HitCount: 1 + HitRate: 200 Element: Water SplashArea: 4 ActiveInstance: 14 @@ -18857,6 +18996,27 @@ Body: Size: 11 Hit: Single HitCount: 3 + HitRate: # TODO: Confirm rate + - Level: 1 + Rate: 103 + - Level: 2 + Rate: 106 + - Level: 3 + Rate: 109 + - Level: 4 + Rate: 112 + - Level: 5 + Rate: 115 + - Level: 6 + Rate: 118 + - Level: 7 + Rate: 121 + - Level: 8 + Rate: 124 + - Level: 9 + Rate: 127 + - Level: 10 + Rate: 130 Element: Weapon CopyFlags: Skill: @@ -20781,6 +20941,17 @@ Body: Range: 1 Hit: Single HitCount: 1 + HitRate: + - Level: 1 + Rate: 114 + - Level: 2 + Rate: 118 + - Level: 3 + Rate: 122 + - Level: 4 + Rate: 126 + - Level: 5 + Rate: 130 Element: Weapon AfterCastActDelay: 1000 Requires: @@ -23466,6 +23637,27 @@ Body: Range: 2 Hit: Single HitCount: 1 + HitRate: + - Level: 1 + Rate: 70 + - Level: 2 + Rate: 75 + - Level: 3 + Rate: 80 + - Level: 4 + Rate: 85 + - Level: 5 + Rate: 90 + - Level: 6 + Rate: 100 + - Level: 7 + Rate: 105 + - Level: 8 + Rate: 110 + - Level: 9 + Rate: 115 + - Level: 10 + Rate: 120 Element: Weapon SplashArea: - Level: 1 @@ -24443,6 +24635,27 @@ Body: Range: 7 Hit: Single HitCount: 1 + HitRate: + - Level: 1 + Rate: 105 + - Level: 2 + Rate: 110 + - Level: 3 + Rate: 115 + - Level: 4 + Rate: 120 + - Level: 5 + Rate: 125 + - Level: 6 + Rate: 130 + - Level: 7 + Rate: 135 + - Level: 8 + Rate: 140 + - Level: 9 + Rate: 145 + - Level: 10 + Rate: 150 Element: Weapon Requires: SpCost: @@ -28738,6 +28951,17 @@ Body: Name: GN_REMODELING_CART Description: Cart Remodeling MaxLevel: 5 + HitRate: + - Level: 1 + Rate: 104 + - Level: 2 + Rate: 108 + - Level: 3 + Rate: 112 + - Level: 4 + Rate: 116 + - Level: 5 + Rate: 120 - Id: 2476 Name: GN_CART_TORNADO Description: Cart Tornado @@ -30438,6 +30662,17 @@ Body: Range: -9 Hit: Single HitCount: 1 + HitRate: + - Level: 1 + Rate: 10 + - Level: 2 + Rate: 9 + - Level: 3 + Rate: 8 + - Level: 4 + Rate: 7 + - Level: 5 + Rate: 6 Knockback: 6 CastTime: - Level: 1 @@ -44015,6 +44250,27 @@ Body: Range: -1 Hit: Single HitCount: 1 + HitRate: + - Level: 1 + Rate: 105 + - Level: 2 + Rate: 110 + - Level: 3 + Rate: 115 + - Level: 4 + Rate: 120 + - Level: 5 + Rate: 125 + - Level: 6 + Rate: 130 + - Level: 7 + Rate: 135 + - Level: 8 + Rate: 140 + - Level: 9 + Rate: 145 + - Level: 10 + Rate: 150 Element: Weapon Requires: SpCost: @@ -44073,6 +44329,27 @@ Body: TargetTrap: true Hit: Single HitCount: 1 + HitRate: + - Level: 1 + Rate: 110 + - Level: 2 + Rate: 120 + - Level: 3 + Rate: 130 + - Level: 4 + Rate: 140 + - Level: 5 + Rate: 150 + - Level: 6 + Rate: 160 + - Level: 7 + Rate: 170 + - Level: 8 + Rate: 180 + - Level: 9 + Rate: 190 + - Level: 10 + Rate: 200 Element: Fire SplashArea: 2 Knockback: 2 @@ -44566,6 +44843,27 @@ Body: Range: -2 Hit: Multi_Hit HitCount: 3 + HitRate: + - Level: 1 + Rate: 15 + - Level: 2 + Rate: 110 + - Level: 3 + Rate: 115 + - Level: 4 + Rate: 120 + - Level: 5 + Rate: 125 + - Level: 6 + Rate: 130 + - Level: 7 + Rate: 135 + - Level: 8 + Rate: 140 + - Level: 9 + Rate: 145 + - Level: 10 + Rate: 150 Element: Weapon Requires: SpCost: 7 diff --git a/db/skill_db.yml b/db/skill_db.yml index a65420614a..cf60ed9689 100644 --- a/db/skill_db.yml +++ b/db/skill_db.yml @@ -37,6 +37,10 @@ # HitCount: Skill hit count. (Default: 0) # - Level Skill level. # Count Number of hits at specific skill level. +# HitRate Skill hit rate. (Default: 100) +# - Level Skill level. +# Rate Rate is a percent of hit rate added to hit rate. +# Skills: Skill flagged as a requirement (players only). (Optional) # Element: Skill element. (Default: Neutral) # - Level Skill level. # Element Element at specific skill level. @@ -140,7 +144,7 @@ Header: Type: SKILL_DB - Version: 3 + Version: 4 Footer: Imports: diff --git a/doc/skill_db.txt b/doc/skill_db.txt index 6b6461b975..eabab091f6 100644 --- a/doc/skill_db.txt +++ b/doc/skill_db.txt @@ -3,7 +3,7 @@ //===== By: ================================================== //= rAthena Dev Team //===== Last Updated: ======================================== -//= 20220126 +//= 20230803 //===== Description: ========================================= //= Explanation of the skill_db.yml file and structure. //============================================================ @@ -157,6 +157,27 @@ Sequence Map Form --------------------------------------- +HitRate: Skill hit rate. Rate is 100 by default. + +Can be defined in scalar form or sequence map form: +Scalar Form + HitRate: 120 + +Sequence Map Form + HitRate: + - Level: 1 + Count: 120 + - Level: 2 + Count: 140 + - Level: 3 + Count: 160 + - Level: 4 + Count: 180 + - Level: 5 + Count: 200 + +--------------------------------------- + Element: Skill element. Neutral (Default) diff --git a/doc/yaml/db/skill_db.yml b/doc/yaml/db/skill_db.yml index d0640285f7..5dae938519 100644 --- a/doc/yaml/db/skill_db.yml +++ b/doc/yaml/db/skill_db.yml @@ -20,6 +20,10 @@ # HitCount: Skill hit count. (Default: 0) # - Level Skill level. # Count Number of hits at specific skill level. +# HitRate Skill hit rate. (Default: 100) +# - Level Skill level. +# Rate Rate is a percent of hit rate added to hit rate. +# Skills: Skill flagged as a requirement (players only). (Optional) # Element: Skill element. (Default: Neutral) # - Level Skill level. # Element Element at specific skill level. diff --git a/src/map/battle.cpp b/src/map/battle.cpp index 4e40a2cc81..4868829242 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -34,6 +34,8 @@ #include "pc_groups.hpp" #include "pet.hpp" +using namespace rathena; + struct Battle_Config battle_config; static struct eri *delay_damage_ers; //For battle delay damage structures. @@ -3097,98 +3099,49 @@ static bool is_attack_hitting(struct Damage* wd, struct block_list *src, struct hitrate += pc_checkskill(sd,AC_VULTURE); #endif - if(skill_id) { - switch(skill_id) { //Hit skill modifiers + if (skill_id > 0) { + switch (skill_id) { //Hit skill modifiers //It is proven that bonus is applied on final hitrate, not hit. - case SM_BASH: - case MS_BASH: - hitrate += hitrate * 5 * skill_lv / 100; - break; - case MS_MAGNUM: - case SM_MAGNUM: - hitrate += hitrate * 10 * skill_lv / 100; - break; - case KN_AUTOCOUNTER: - case PA_SHIELDCHAIN: - case NPC_WATERATTACK: - case NPC_GROUNDATTACK: - case NPC_FIREATTACK: - case NPC_WINDATTACK: - case NPC_POISONATTACK: - case NPC_HOLYATTACK: - case NPC_DARKNESSATTACK: - case NPC_TELEKINESISATTACK: - case NPC_UNDEADATTACK: - case NPC_CHANGEUNDEAD: - case NPC_EARTHQUAKE: - case NPC_POISON: - case NPC_BLINDATTACK: - case NPC_SILENCEATTACK: - case NPC_STUNATTACK: - case NPC_PETRIFYATTACK: - case NPC_CURSEATTACK: - case NPC_SLEEPATTACK: - case NPC_BLEEDING: - case NPC_BLEEDING2: - hitrate += hitrate * 20 / 100; - break; - case NPC_FIREBREATH: - case NPC_ICEBREATH: - case NPC_ICEBREATH2: - case NPC_THUNDERBREATH: - case NPC_ACIDBREATH: - case NPC_DARKNESSBREATH: - hitrate *= 2; - break; - case KN_PIERCE: - case ML_PIERCE: - hitrate += hitrate * 5 * skill_lv / 100; - break; - case AS_SONICBLOW: - if(sd && pc_checkskill(sd,AS_SONICACCEL) > 0) -#ifdef RENEWAL - hitrate += hitrate * 90 / 100; -#else - hitrate += hitrate * 50 / 100; -#endif - break; -#ifdef RENEWAL - case RG_BACKSTAP: - hitrate += skill_lv; // !TODO: What's the rate increase? - break; -#endif - case RK_SONICWAVE: - hitrate += hitrate * 3 * skill_lv / 100; // !TODO: Confirm the hitrate bonus - break; case MC_CARTREVOLUTION: case GN_CART_TORNADO: case GN_CARTCANNON: - if (sd && pc_checkskill(sd, GN_REMODELING_CART)) - hitrate += pc_checkskill(sd, GN_REMODELING_CART) * 4; - break; - case LG_BANISHINGPOINT: - hitrate += 5 * skill_lv; - break; - case GC_VENOMPRESSURE: - hitrate += 10 + 4 * skill_lv; - break; - case SC_FATALMENACE: - if (skill_lv < 6) - hitrate -= 35 - 5 * skill_lv; - else if (skill_lv > 6) - hitrate += 5 * skill_lv - 30; - break; + { + uint16 cart_remodel_lv = pc_checkskill(sd, GN_REMODELING_CART); + + if (sd && cart_remodel_lv > 0) + hitrate = hitrate * skill_get_hitrate(GN_REMODELING_CART, cart_remodel_lv) / 100; + } + break; case RL_SLUGSHOT: - { - int8 dist = distance_bl(src, target); - if (dist > 3) { - // Reduce n hitrate for each cell after initial 3 cells. Different each level - // -10:-9:-8:-7:-6 - dist -= 3; - hitrate -= ((11 - skill_lv) * dist); - } + { + uint32 dist = distance_bl(src, target); + + if (dist > 3) { + // Reduce n hitrate for each cell after initial 3 cells. + hitrate -= (skill_get_hitrate(RL_SLUGSHOT, skill_lv) * (dist - 3)); } - break; + } + break; + default: + { + struct s_skill_hitrate skill_hitrate = skill_db.find(skill_id)->hitrate; + + if (skill_hitrate.rate[skill_lv] != 100) { // Hit skill modifiers + bool req_fail = false; + + // List of skills required to be learned before adjusting hitrate (players only). + for (uint16 skill_req : skill_hitrate.skills) { + if (sd && pc_checkskill(sd, skill_req) == 0) { + req_fail = true; + break; + } + } + + if (!req_fail) + hitrate = hitrate * skill_hitrate.rate[skill_lv] / 100; + } + } + break; } } else if (sd && wd->type&DMG_MULTI_HIT && wd->div_ == 2) // +1 hit per level of Double Attack on a successful double attack (making sure other multi attack skills do not trigger this) [helvetica] hitrate += pc_checkskill(sd,TF_DOUBLE); diff --git a/src/map/skill.cpp b/src/map/skill.cpp index fe764c201a..9992125448 100755 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -172,6 +172,7 @@ static bool skill_check(uint16 id) { // Skill DB e_damage_type skill_get_hit( uint16 skill_id ) { if (!skill_check(skill_id)) return DMG_NORMAL; return skill_db.find(skill_id)->hit; } +int skill_get_hitrate( uint16 skill_id, uint16 skill_lv ) { skill_get_lv(skill_id, skill_lv, skill_db.find(skill_id)->hitrate.rate); } int skill_get_inf( uint16 skill_id ) { skill_get(skill_id, skill_db.find(skill_id)->inf); } int skill_get_ele( uint16 skill_id , uint16 skill_lv ) { skill_get_lv(skill_id, skill_lv, skill_db.find(skill_id)->element); } int skill_get_max( uint16 skill_id ) { skill_get(skill_id, skill_db.find(skill_id)->max); } @@ -23641,6 +23642,39 @@ uint64 SkillDatabase::parseBodyNode(const ryml::NodeRef& node) { memset(skill->num, 0, sizeof(skill->num)); } + if (this->nodeExists(node, "HitRate")) { + if (!this->parseNode("HitRate", "Rate", node, skill->hitrate.rate)) + return 0; + + const auto &skillsNode = node["HitRate"]; + + if (this->nodeExists(skillsNode, "Skills")) { + for (const auto &it : skillsNode) { + std::string req_skill_name; + c4::from_chars(it.key(), &req_skill_name); + uint16 req_skill_id = skill_name2id(req_skill_name.c_str()); + + if (skill_id == 0) { + this->invalidWarning(skillsNode, "HitRate requires skill %s is invalid.\n", req_skill_name.c_str()); + return 0; + } + + bool active; + + if (!this->asBool(skillsNode, req_skill_name, active)) + return 0; + + if (active) + skill->hitrate.skills.push_back(req_skill_id); + else + util::vector_erase_if_exists(skill->hitrate.skills, req_skill_id); + } + } + } else { + if (!exists) + memset(skill->hitrate.rate, 100, sizeof(skill->hitrate.rate)); + } + if (this->nodeExists(node, "Element")) { const auto elementNode = node["Element"]; std::string element; diff --git a/src/map/skill.hpp b/src/map/skill.hpp index c22e0ad702..2212a0a0dd 100644 --- a/src/map/skill.hpp +++ b/src/map/skill.hpp @@ -246,6 +246,12 @@ struct s_skill_copyable { // [Cydh] uint16 req_opt; }; +/// Skill HitRate structure. +struct s_skill_hitrate{ + int32 rate[MAX_SKILL_LEVEL]; + std::vector skills; +}; + /// Database skills struct s_skill_db { uint16 nameid; ///< Skill ID @@ -259,6 +265,7 @@ struct s_skill_db { int32 splash[MAX_SKILL_LEVEL]; ///< Splash effect uint16 max; ///< Max level int32 num[MAX_SKILL_LEVEL]; ///< Number of hit + struct s_skill_hitrate hitrate; ///< Hitrate bool castcancel; ///< Cancel cast when being hit uint16 cast_def_rate; ///< Def rate during cast a skill e_battle_flag skill_type; ///< Skill type @@ -315,7 +322,7 @@ private: template bool parseNode(const std::string& nodeName, const std::string& subNodeName, const ryml::NodeRef& node, T(&arr)[S]); public: - SkillDatabase() : TypesafeCachedYamlDatabase("SKILL_DB", 3, 1) { + SkillDatabase() : TypesafeCachedYamlDatabase("SKILL_DB", 4, 1) { this->clear(); } @@ -498,6 +505,7 @@ int skill_tree_get_max( uint16 skill_id, int b_class ); // Celest #define skill_get_index(skill_id) skill_db.get_index((skill_id), false, __FUNCTION__, __FILE__, __LINE__) /// Get skill index from skill_id (common usage on source) int skill_get_type( uint16 skill_id ); e_damage_type skill_get_hit( uint16 skill_id ); +int skill_get_hitrate( uint16 skill_id, uint16 skill_lv ); int skill_get_inf( uint16 skill_id ); int skill_get_ele( uint16 skill_id , uint16 skill_lv ); int skill_get_max( uint16 skill_id );