summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorDavid Gay <david@davidgay.org>2021-05-26 19:26:00 -0400
committerDavid Gay <david@davidgay.org>2021-05-26 19:26:00 -0400
commit9b2acceda7e36946f9bb15ff8d1a93f9c45a964f (patch)
tree67ebf8f7fcefb4a1811074c9eec519d865c70391 /app
parent0b9b45d573cc4f836ba7a99de77e9da18e768f10 (diff)
Combat styles
Diffstat (limited to 'app')
-rw-r--r--app/controllers/characters_controller.rb15
-rw-r--r--app/controllers/game_controller.rb8
-rw-r--r--app/models/character.rb49
-rw-r--r--app/models/monster.rb8
-rw-r--r--app/views/characters/show.html.erb13
5 files changed, 76 insertions, 17 deletions
diff --git a/app/controllers/characters_controller.rb b/app/controllers/characters_controller.rb
index d851ad5..77e1a94 100644
--- a/app/controllers/characters_controller.rb
+++ b/app/controllers/characters_controller.rb
@@ -21,6 +21,21 @@ class CharactersController < ApplicationController
end
end
+ def set_combat_styles
+ @character = Character.find(params[:character_id])
+ unless @character == current_char
+ flash[:alert] = "You can't set the combat styles of another character."
+ redirect_to character_path(@character) and return
+ end
+ if @character.update(offensive_style: params[:offensive_style],
+ defensive_style: params[:defensive_style])
+ flash[:notice] = "Changed combat styles to #{@character.offensive_style} and #{@character.defensive_style}."
+ else
+ flash[:alert] = "Failed to set combat styles."
+ end
+ redirect_to character_path(@character)
+ end
+
private
def character_params
params.require(:character).permit(:name)
diff --git a/app/controllers/game_controller.rb b/app/controllers/game_controller.rb
index 32ddd12..922301a 100644
--- a/app/controllers/game_controller.rb
+++ b/app/controllers/game_controller.rb
@@ -149,15 +149,15 @@ class GameController < ApplicationController
end
turn_order.cycle do |actor, target|
base_accuracy_roll = roll(20)
- accuracy_roll = base_accuracy_roll + actor.accuracy
- evasion_roll = roll(20) + target.evasion
+ 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 # TODO: Replace d4 with weapon damage
+ dealt_damage = roll(4) + actor.power(with_combat_style: true) # TODO: Replace d4 with weapon damage
if base_accuracy_roll == 20
combat_message.call("#{actor.name} landed a critical hit!")
dealt_damage = dealt_damage * 2
end
- blocked_damage = (accuracy_roll >= (roll(20) + target.block)) ? 0 : target.block_value
+ blocked_damage = (accuracy_roll >= (roll(20) + target.block(with_combat_style: true))) ? 0 : target.block_value
resolved_damage = dealt_damage - blocked_damage
actor == char ? mon_hp -= resolved_damage : char_hp -= resolved_damage
damage_text = "#{resolved_damage} damage."
diff --git a/app/models/character.rb b/app/models/character.rb
index 52c0959..d1faeb0 100644
--- a/app/models/character.rb
+++ b/app/models/character.rb
@@ -19,7 +19,10 @@ class Character < ApplicationRecord
attribute :wounds, :integer, default: 0
- after_create :create_skills
+ enum offensive_style: [:balanced, :precise, :brutal]
+ enum defensive_style: [:centered, :elusive, :protective]
+
+ after_create :create_skills, :set_combat_styles
after_create { Hearth.create(character: self) }
def beastslay_level; skill_level("beastslay"); end
@@ -184,20 +187,44 @@ class Character < ApplicationRecord
self.beastslay_level + (equipment_stats["speed"] || 0)
end
- def accuracy
- self.beastslay_level + (equipment_stats["accuracy"] || 0)
+ def accuracy(with_combat_style: false)
+ base = self.beastslay_level + (equipment_stats["accuracy"] || 0)
+ if with_combat_style && self.precise?
+ base = (base * 1.25).floor
+ elsif with_combat_style && self.brutal?
+ base = (base * 0.75).ceil
+ end
+ base
end
- def power
- self.beastslay_level + (equipment_stats["power"] || 0)
+ def power(with_combat_style: false)
+ base = self.beastslay_level + (equipment_stats["power"] || 0)
+ if with_combat_style && self.precise?
+ base = (base * 0.75).ceil
+ elsif with_combat_style && self.brutal?
+ base = (base * 1.25).floor
+ end
+ base
end
- def evasion
- self.beastslay_level + (equipment_stats["evasion"] || 0)
+ def evasion(with_combat_style: false)
+ base = self.beastslay_level + (equipment_stats["evasion"] || 0)
+ if with_combat_style && self.elusive?
+ base = (base * 1.25).floor
+ elsif with_combat_style && self.protective?
+ base = (base * 0.75).ceil
+ end
+ base
end
- def block
- self.beastslay_level + (equipment_stats["block"] || 0)
+ def block(with_combat_style: false)
+ base = self.beastslay_level + (equipment_stats["block"] || 0)
+ 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
@@ -208,4 +235,8 @@ class Character < ApplicationRecord
def create_skills
Skill.all.each { |skill| self.character_skills.create(skill: skill, xp: 0) }
end
+
+ def set_combat_styles
+ self.update(offensive_style: :balanced, defensive_style: :centered)
+ end
end
diff --git a/app/models/monster.rb b/app/models/monster.rb
index 1b521aa..d1e1b99 100644
--- a/app/models/monster.rb
+++ b/app/models/monster.rb
@@ -9,19 +9,19 @@ class Monster < ApplicationRecord
self.whatnot[:speed][:base]
end
- def accuracy
+ def accuracy(with_combat_style: false)
self.whatnot[:accuracy][:base]
end
- def power
+ def power(with_combat_style: false)
self.whatnot[:power][:base]
end
- def evasion
+ def evasion(with_combat_style: false)
self.whatnot[:evasion][:base]
end
- def block
+ def block(with_combat_style: false)
self.whatnot[:block][:base]
end
diff --git a/app/views/characters/show.html.erb b/app/views/characters/show.html.erb
index e7f9696..84e1ff5 100644
--- a/app/views/characters/show.html.erb
+++ b/app/views/characters/show.html.erb
@@ -11,6 +11,19 @@
<p class="mb-4">Learned <%= @character.learned_activities.count %> recipe(s) or technique(s).</p>
+<% if @character == current_char %>
+ <h2 class="text-2xl mb-4">Combat Styles</h2>
+ <%= form_with url: character_combat_styles_path(character_id: @character) do |f| %>
+ <%= f.label :offensive_style, "Offensive" %>
+ <%= f.select :offensive_style, Character.offensive_styles.keys.to_a, selected: @character.offensive_style %>
+
+ <%= f.label :defensive_style, "Defensive" %>
+ <%= f.select :defensive_style, Character.defensive_styles.keys.to_a, selected: @character.defensive_style %>
+
+ <%= f.submit "Set" %>
+ <% end %>
+<% end %>
+
<div class="my-6">
<h2 class="text-2xl mb-4">Combat Statistics</h2>
<table class="table-auto">