diff options
author | David Gay <david@davidgay.org> | 2021-06-06 14:15:59 -0400 |
---|---|---|
committer | David Gay <david@davidgay.org> | 2021-06-06 14:15:59 -0400 |
commit | d2afb75b2cf512158d82ea2513ee4fb6662362a7 (patch) | |
tree | 8a939fc049446372440ba030cf2843db5c80ed35 /app | |
parent | bce9b7729ec148d0b728602309fea6787802468b (diff) |
Switch from power-based damage to damage types, replace block with resistance, and make natural 20 accuracy rolls always hit (and crit)
Diffstat (limited to 'app')
-rw-r--r-- | app/lib/activity_processor.rb | 30 | ||||
-rw-r--r-- | app/models/character.rb | 22 | ||||
-rw-r--r-- | app/models/monster.rb | 8 | ||||
-rw-r--r-- | app/views/characters/show.html.erb | 8 |
4 files changed, 31 insertions, 37 deletions
diff --git a/app/lib/activity_processor.rb b/app/lib/activity_processor.rb index 73f296d..5e6acaf 100644 --- a/app/lib/activity_processor.rb +++ b/app/lib/activity_processor.rb @@ -210,18 +210,30 @@ class ActivityProcessor base_accuracy_roll = roll(20) accuracy_roll = base_accuracy_roll + actor.accuracy(with_combat_style: true) evasion_roll = roll(20) + target.evasion(with_combat_style: true) - if accuracy_roll >= evasion_roll - dealt_damage = roll(4) + actor.power(with_combat_style: true) # TODO: Replace d4 with weapon damage + if accuracy_roll >= evasion_roll || base_accuracy_roll == 20 + + dealt_damage = {} + actor.damage_ranges.each do |data| + damage_roll = rand(data[:min]..data[:max]) + dealt_damage[data[:gid]] = damage_roll + end + if base_accuracy_roll == 20 combat_message.call("#{actor.name} landed a critical hit!") - dealt_damage = dealt_damage * 2 + dealt_damage.each do |gid, amount| + dealt_damage[gid] = amount * 2 + end end - blocked_damage = (accuracy_roll >= (roll(20) + target.block(with_combat_style: true))) ? 0 : target.block_value - blocked_damage = [blocked_damage, (dealt_damage - 1)].min - resolved_damage = dealt_damage - blocked_damage - actor == char ? mon_hp -= resolved_damage : char_hp -= resolved_damage - damage_text = "#{resolved_damage} damage." - damage_text += " (#{dealt_damage} - #{blocked_damage} blocked)" if blocked_damage > 0 + + resolved_damage = {} + dealt_damage.each do |gid, amount| + effective_resistance = [target.resistance(gid), amount].min + resolved_damage[gid] = amount - (effective_resistance * rand(0.5..1)).round + end + + total_damage = resolved_damage.values.sum + actor == char ? mon_hp -= total_damage : char_hp -= total_damage + damage_text = "#{total_damage} damage (#{resolved_damage.to_a.map { |gid, amount| "#{amount} #{gid}" }.join(", ")})" combat_message.call("#{actor.name} hit for #{damage_text}") elsif evasion_roll > accuracy_roll combat_message.call("#{target.name} evaded #{actor.name}'s attack.") diff --git a/app/models/character.rb b/app/models/character.rb index 0f434cf..15169a4 100644 --- a/app/models/character.rb +++ b/app/models/character.rb @@ -312,6 +312,10 @@ class Character < ApplicationRecord effects.filter_map { |e| e[:modifier] if e[:type] == "stat_change" && e[:gid] == gid }.sum end + def damage_ranges + effects.filter_map { |e| { gid: e[:gid], min: e[:min], max: e[:max] } if e[:type] == "damage" } + end + def planting_spots [total_stat_change("planting_spots"), 0].max end @@ -325,12 +329,16 @@ class Character < ApplicationRecord bleed physical energy].include?(damage_type) raise "Invalid damage type" end + res = total_stat_change("#{damage_type}_resistance") if %w[slash pierce bash].include?(damage_type) res += resistance("physical") elsif %w[arcane fire frost lightning acid thunder radiant necrotic].include?(damage_type) res += resistance("energy") end + + res = (res * 0.75).ceil if elusive? + res = (res * 1.25).floor if protective? [res, 0].max end @@ -376,20 +384,6 @@ class Character < ApplicationRecord base end - def block(with_combat_style: false) - base = [self.beastslay_level + total_stat_change("block"), 0].max - if with_combat_style && self.elusive? - base = (base * 0.75).ceil - elsif with_combat_style && self.protective? - base = (base * 1.25).floor - end - base - end - - def block_value - [total_stat_change("block_value"), 0].max - end - private def create_skills Skill.all.each { |skill| self.character_skills.create(skill: skill, xp: 0) } diff --git a/app/models/monster.rb b/app/models/monster.rb index f4ae7a7..40018fd 100644 --- a/app/models/monster.rb +++ b/app/models/monster.rb @@ -21,12 +21,8 @@ class Monster < ApplicationRecord self.whatnot[:evasion][:base] end - def block(with_combat_style: false) - self.whatnot[:block][:base] - end - - def block_value - self.whatnot[:block_value][:base] + def damage_ranges + self.whatnot[:hit_effects].filter_map { |e| { gid: e[:gid], min: e[:min], max: e[:max] } if e[:type] == "damage" } end def resistance(damage_type) diff --git a/app/views/characters/show.html.erb b/app/views/characters/show.html.erb index 75143ec..896280d 100644 --- a/app/views/characters/show.html.erb +++ b/app/views/characters/show.html.erb @@ -74,14 +74,6 @@ <th class="table-cell-padded text-right">Evasion</th> <td class="table-cell-padded"><%= @character.evasion(with_combat_style: true) %></td> </tr> - <tr> - <th class="table-cell-padded text-right">Block</th> - <td class="table-cell-padded"><%= @character.block(with_combat_style: true) %></td> - </tr> - <tr> - <th class="table-cell-padded text-right">Block Value</th> - <td class="table-cell-padded"><%= @character.block_value %></td> - </tr> </tbody> </table> </div> |