summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md8
-rw-r--r--app/lib/activity_processor.rb30
-rw-r--r--app/models/character.rb22
-rw-r--r--app/models/monster.rb8
-rw-r--r--app/views/characters/show.html.erb8
-rw-r--r--data/items.yml98
-rw-r--r--data/monsters.yml44
7 files changed, 103 insertions, 115 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ffb0af2..d7674b2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,14 @@ All notable changes to this project will be documented in this file.
### General
- Implemented monitoring (error tracking, uptime, server health, etc.) via Honeybadger.
+### Combat
+- A natural 20 on an accuracy roll now always results in a (critical) hit. Previously, if a 20 was rolled, it
+ could still miss. Now it's always a hit and always a critical hit.
+- The block and block value stats have been removed.
+
+### Items
+- Granite ring now increases physical resistance by 2, since block has been removed.
+
### UI
- New inventory view, with items sorted into categories, and a (hopefully) better section for equipped items.
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>
diff --git a/data/items.yml b/data/items.yml
index 0fdc49c..760a7b6 100644
--- a/data/items.yml
+++ b/data/items.yml
@@ -83,12 +83,10 @@ iron_dagger:
equip_slots:
- "mainhand"
equip_effects:
- - type: "stat_change"
- gid: "accuracy"
- modifier: 2
- - type: "stat_change"
- gid: "power"
- modifier: 2
+ - type: "damage"
+ gid: "pierce"
+ min: 1
+ max: 4
iron_short_sword:
name: "iron short sword"
description: "A short sword made of iron."
@@ -100,12 +98,14 @@ iron_short_sword:
gid: "beastslay"
level: 2
equip_effects:
- - type: "stat_change"
- gid: "accuracy"
- modifier: 3
- - type: "stat_change"
- gid: "power"
- modifier: 3
+ - type: "damage"
+ gid: "slash"
+ min: 1
+ max: 3
+ - type: "damage"
+ gid: "pierce"
+ min: 1
+ max: 3
iron_longsword:
name: "iron longsword"
description: "A longsword made of iron."
@@ -117,12 +117,10 @@ iron_longsword:
gid: "beastslay"
level: 5
equip_effects:
- - type: "stat_change"
- gid: "accuracy"
- modifier: 4
- - type: "stat_change"
- gid: "power"
- modifier: 4
+ - type: "damage"
+ gid: "slash"
+ min: 1
+ max: 8
iron_buckler:
name: "iron buckler"
description: "A buckler made of iron."
@@ -131,10 +129,7 @@ iron_buckler:
- "offhand"
equip_effects:
- type: "stat_change"
- gid: "block"
- modifier: 1
- - type: "stat_change"
- gid: "block_value"
+ gid: "physical_resistance"
modifier: 1
iron_shield:
name: "iron shield"
@@ -148,11 +143,11 @@ iron_shield:
level: 3
equip_effects:
- type: "stat_change"
- gid: "block"
+ gid: "physical_resistance"
modifier: 2
- type: "stat_change"
- gid: "block_value"
- modifier: 2
+ gid: "energy_resistance"
+ modifier: 1
arcanite_dagger:
name: "arcanite dagger"
description: "A dagger made of arcanite."
@@ -164,12 +159,10 @@ arcanite_dagger:
gid: "beastslay"
level: 10
equip_effects:
- - type: "stat_change"
- gid: "accuracy"
- modifier: 6
- - type: "stat_change"
- gid: "power"
- modifier: 6
+ - type: "damage"
+ gid: "pierce"
+ min: 2
+ max: 6
arcanite_short_sword:
name: "arcanite short sword"
description: "A short sword made of iron."
@@ -181,12 +174,14 @@ arcanite_short_sword:
gid: "beastslay"
level: 12
equip_effects:
- - type: "stat_change"
- gid: "accuracy"
- modifier: 7
- - type: "stat_change"
- gid: "power"
- modifier: 7
+ - type: "damage"
+ gid: "slash"
+ min: 2
+ max: 5
+ - type: "damage"
+ gid: "pierce"
+ min: 2
+ max: 5
arcanite_longsword:
name: "arcanite longsword"
description: "A longsword made of arcanite."
@@ -198,12 +193,10 @@ arcanite_longsword:
gid: "beastslay"
level: 15
equip_effects:
- - type: "stat_change"
- gid: "accuracy"
- modifier: 8
- - type: "stat_change"
- gid: "power"
- modifier: 8
+ - type: "damage"
+ gid: "slash"
+ min: 3
+ max: 12
arcanite_buckler:
name: "arcanite buckler"
description: "A buckler made of arcanite."
@@ -216,11 +209,8 @@ arcanite_buckler:
- "offhand"
equip_effects:
- type: "stat_change"
- gid: "block"
- modifier: 4
- - type: "stat_change"
- gid: "block_value"
- modifier: 4
+ gid: "physical_resistance"
+ modifier: 3
arcanite_shield:
name: "arcanite shield"
description: "A shield made of arcanite."
@@ -233,11 +223,11 @@ arcanite_shield:
level: 13
equip_effects:
- type: "stat_change"
- gid: "block"
- modifier: 5
+ gid: "physical_resistance"
+ modifier: 4
- type: "stat_change"
- gid: "block_value"
- modifier: 5
+ gid: "energy_resistance"
+ modifier: 2
mending_salve:
name: "mending salve"
description: "A healing mixture capable of closing wounds."
@@ -478,8 +468,8 @@ granite_ring:
- "right_ring"
equip_effects:
- type: "stat_change"
- gid: "block"
- modifier: 1
+ gid: "physical_resistance"
+ modifier: 2
mudtub_seed:
name: "mudtub seed"
description: "The seed of a mudtub plant."
diff --git a/data/monsters.yml b/data/monsters.yml
index 4a8dc40..ca55a64 100644
--- a/data/monsters.yml
+++ b/data/monsters.yml
@@ -14,10 +14,11 @@ pit_leech:
base: 1
evasion:
base: 1
- block:
- base: 1
- block_value:
- base: 1
+ hit_effects:
+ - type: "damage"
+ gid: "pierce"
+ min: 1
+ max: 5
awards:
- type: "xp"
gid: "beastslay"
@@ -47,10 +48,11 @@ stalk_beast:
base: 2
evasion:
base: 2
- block:
- base: 1
- block_value:
- base: 1
+ hit_effects:
+ - type: "damage"
+ gid: "bash"
+ min: 3
+ max: 8
awards:
- type: "xp"
gid: "beastslay"
@@ -82,10 +84,11 @@ grinpad:
base: 2
evasion:
base: 5
- block:
- base: 1
- block_value:
- base: 1
+ hit_effects:
+ - type: "damage"
+ gid: "slash"
+ min: 5
+ max: 12
awards:
- type: "xp"
gid: "beastslay"
@@ -122,10 +125,11 @@ lesser_trodgeathomp:
base: 10
evasion:
base: 5
- block:
- base: 10
- block_value:
- base: 3
+ hit_effects:
+ - type: "damage"
+ gid: "bash"
+ min: 12
+ max: 20
awards:
- type: "xp"
gid: "beastslay"
@@ -160,10 +164,6 @@ bollyrot:
base: 7
evasion:
base: 7
- block:
- base: 6
- block_value:
- base: 2
awards:
- type: "xp"
gid: "beastslay"
@@ -195,10 +195,6 @@ crypt_writhe:
base: 12
evasion:
base: 10
- block:
- base: 8
- block_value:
- base: 4
awards:
- type: "xp"
gid: "beastslay"