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 +++++++++++++ data/conditions.yml | 9 +++++++++ data/items.yml | 9 +++++++++ db/migrate/20210529195709_create_conditions.rb | 12 ++++++++++++ db/migrate/20210529195809_create_states.rb | 11 +++++++++++ db/schema.rb | 23 ++++++++++++++++++++++- db/seeds.rb | 5 +++++ test/fixtures/conditions.yml | 11 +++++++++++ test/fixtures/states.yml | 9 +++++++++ test/models/condition_test.rb | 7 +++++++ test/models/state_test.rb | 7 +++++++ 15 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 app/models/condition.rb create mode 100644 app/models/state.rb create mode 100644 data/conditions.yml create mode 100644 db/migrate/20210529195709_create_conditions.rb create mode 100644 db/migrate/20210529195809_create_states.rb create mode 100644 test/fixtures/conditions.yml create mode 100644 test/fixtures/states.yml create mode 100644 test/models/condition_test.rb create mode 100644 test/models/state_test.rb 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| %> diff --git a/data/conditions.yml b/data/conditions.yml new file mode 100644 index 0000000..99aacc4 --- /dev/null +++ b/data/conditions.yml @@ -0,0 +1,9 @@ +quarrying_draught: + name: "quarrying draught" + description: "Increases the speed of planequarrying for some time." + whatnot: + effects: + - type: "stat_change" + level: 2 + gid: "planequarry_speed" + modifier: 5 diff --git a/data/items.yml b/data/items.yml index f5be768..70dbc48 100644 --- a/data/items.yml +++ b/data/items.yml @@ -343,3 +343,12 @@ aethermesh: whatnot: equip_slots: - "mainhand" +quarrying_draught: + name: "quarrying draught" + description: "Increases the speed of planequarrying for an hour." + whatnot: + use_effects: + - type: "condition" + gid: "quarrying_draught" + duration: 3600 # 1 Hour + message: "The draught increases your planequarry speed." diff --git a/db/migrate/20210529195709_create_conditions.rb b/db/migrate/20210529195709_create_conditions.rb new file mode 100644 index 0000000..8330fcb --- /dev/null +++ b/db/migrate/20210529195709_create_conditions.rb @@ -0,0 +1,12 @@ +class CreateConditions < ActiveRecord::Migration[6.1] + def change + create_table :conditions do |t| + t.string :gid + t.string :name + t.text :description + t.jsonb :whatnot + + t.timestamps + end + end +end diff --git a/db/migrate/20210529195809_create_states.rb b/db/migrate/20210529195809_create_states.rb new file mode 100644 index 0000000..6922e0a --- /dev/null +++ b/db/migrate/20210529195809_create_states.rb @@ -0,0 +1,11 @@ +class CreateStates < ActiveRecord::Migration[6.1] + def change + create_table :states do |t| + t.references :character, null: false, foreign_key: true + t.references :condition, null: false, foreign_key: true + t.timestamp :expires_at + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index eae72c9..5d9fffe 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2021_05_27_002712) do +ActiveRecord::Schema.define(version: 2021_05_29_195809) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -109,6 +109,15 @@ ActiveRecord::Schema.define(version: 2021_05_27_002712) do t.datetime "updated_at", precision: 6, null: false end + create_table "conditions", force: :cascade do |t| + t.string "gid" + t.string "name" + t.text "description" + t.jsonb "whatnot" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + end + create_table "equipment", force: :cascade do |t| t.bigint "character_id", null: false t.bigint "item_id", null: false @@ -183,6 +192,16 @@ ActiveRecord::Schema.define(version: 2021_05_27_002712) do t.index ["gid"], name: "index_skills_on_gid" end + create_table "states", force: :cascade do |t| + t.bigint "character_id", null: false + t.bigint "condition_id", null: false + t.datetime "expires_at" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["character_id"], name: "index_states_on_character_id" + t.index ["condition_id"], name: "index_states_on_condition_id" + end + create_table "title_awards", force: :cascade do |t| t.bigint "title_id", null: false t.bigint "character_id", null: false @@ -247,6 +266,8 @@ ActiveRecord::Schema.define(version: 2021_05_27_002712) do add_foreign_key "hearths", "characters" add_foreign_key "learned_activities", "activities" add_foreign_key "learned_activities", "characters" + add_foreign_key "states", "characters" + add_foreign_key "states", "conditions" add_foreign_key "title_awards", "characters" add_foreign_key "title_awards", "titles" add_foreign_key "users", "characters", column: "active_character_id" diff --git a/db/seeds.rb b/db/seeds.rb index a1459cc..1e2888a 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -51,3 +51,8 @@ load_data_file("data/monsters.yml").map do |gid, hash| monster = Monster.find_or_create_by(gid: gid) monster.update(hash) end + +load_data_file("data/conditions.yml").map do |gid, hash| + condition = Condition.find_or_create_by(gid: gid) + condition.update(hash) +end diff --git a/test/fixtures/conditions.yml b/test/fixtures/conditions.yml new file mode 100644 index 0000000..3bcd27d --- /dev/null +++ b/test/fixtures/conditions.yml @@ -0,0 +1,11 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + name: MyString + descriptions: MyText + whatnot: + +two: + name: MyString + descriptions: MyText + whatnot: diff --git a/test/fixtures/states.yml b/test/fixtures/states.yml new file mode 100644 index 0000000..8352bf6 --- /dev/null +++ b/test/fixtures/states.yml @@ -0,0 +1,9 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + character: one + condition: one + +two: + character: two + condition: two diff --git a/test/models/condition_test.rb b/test/models/condition_test.rb new file mode 100644 index 0000000..59d3e62 --- /dev/null +++ b/test/models/condition_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class ConditionTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/state_test.rb b/test/models/state_test.rb new file mode 100644 index 0000000..3ac43a7 --- /dev/null +++ b/test/models/state_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class StateTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end -- cgit v1.2.3