From aac7563767c5fbc5ef67f4d615833e7523a46df7 Mon Sep 17 00:00:00 2001 From: David Gay Date: Sat, 29 May 2021 17:19:56 -0400 Subject: Conditions and states (boons & banes), with `quarrying_draught` --- app/controllers/characters/items_controller.rb | 8 ++++++++ app/models/character.rb | 9 ++++++++- app/models/condition.rb | 5 +++++ app/models/state.rb | 23 +++++++++++++++++++++++ app/views/characters/show.html.erb | 13 +++++++++++++ 5 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 app/models/condition.rb create mode 100644 app/models/state.rb (limited to 'app') diff --git a/app/controllers/characters/items_controller.rb b/app/controllers/characters/items_controller.rb index 93dc683..722c8ff 100644 --- a/app/controllers/characters/items_controller.rb +++ b/app/controllers/characters/items_controller.rb @@ -47,6 +47,14 @@ class Characters::ItemsController < ApplicationController end when "activity" start_activity(Activity.find_by_gid(effect[:gid])) and return + when "condition" + condition = Condition.find_by_gid(effect[:gid]) + Character.transaction do + current_char.shift_item(@item, -1) + current_char.states.create!(condition: condition, expires_at: Time.now + effect[:duration]) + flash[:notice] = "#{effect[:message]}" + flash[:notice] += " You gain the #{condition.name} condition." + end else raise "Invalid use effect type string (#{effect[:type]})" end diff --git a/app/models/character.rb b/app/models/character.rb index a5c871b..7e80d65 100644 --- a/app/models/character.rb +++ b/app/models/character.rb @@ -10,6 +10,8 @@ class Character < ApplicationRecord has_many :learned_activities has_many :items, through: :character_items has_many :character_skills + has_many :conditions, through: :states + has_many :states has_many :chat_messages has_many :bazaar_orders validates :name, presence: true @@ -91,6 +93,10 @@ class Character < ApplicationRecord end end + def active_states + self.states.all.select { |s| !s.expired? } + end + def pay_cost_for(activity) CharacterItem.transaction do activity.whatnot[:cost]&.each do |cost| @@ -230,7 +236,8 @@ class Character < ApplicationRecord # TODO: Review this filter_map to see if it can be simplified hearth_amenity_effects = self.hearth.built_hearth_amenities.filter_map { |a| a.effects if a.effects } equipment_effects = self.equipment.filter_map { |a| a.effects if a.effects } - (hearth_amenity_effects + equipment_effects).flatten + state_effects = self.states.filter_map { |a| a.effects if a.effects && !a.expired? } + (hearth_amenity_effects + equipment_effects + state_effects).flatten end def total_stat_change(gid) diff --git a/app/models/condition.rb b/app/models/condition.rb new file mode 100644 index 0000000..f2b048f --- /dev/null +++ b/app/models/condition.rb @@ -0,0 +1,5 @@ +class Condition < ApplicationRecord + include HasWhatnot + + validates :gid, :name, :description, presence: true +end diff --git a/app/models/state.rb b/app/models/state.rb new file mode 100644 index 0000000..27c8741 --- /dev/null +++ b/app/models/state.rb @@ -0,0 +1,23 @@ +class State < ApplicationRecord + belongs_to :character + belongs_to :condition + + after_create :destroy_duplicates + + def expired? + self.expires_at < Time.now + end + + def remaining_duration + (self.expires_at - Time.now).to_i + end + + def effects + self.condition.whatnot[:effects] + end + + private + def destroy_duplicates + self.character.states.where(condition: self.condition).where.not(id: self.id).destroy_all + end +end diff --git a/app/views/characters/show.html.erb b/app/views/characters/show.html.erb index 1b5439a..ee81e76 100644 --- a/app/views/characters/show.html.erb +++ b/app/views/characters/show.html.erb @@ -14,6 +14,19 @@

Learned <%= @character.learned_activities.count %> recipe(s) or technique(s).

+
+

Boons & Banes

+ <% if @character.active_states.any? %> + + <% else %> +

No boons or banes affect you.

+ <% end %> +
+ <% if @character == current_char %>

Combat Styles

<%= form_with url: character_combat_styles_path(character_id: @character) do |f| %> -- cgit v1.2.3