summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Gay <david@davidgay.org>2021-05-29 17:19:56 -0400
committerDavid Gay <david@davidgay.org>2021-05-29 17:19:56 -0400
commitaac7563767c5fbc5ef67f4d615833e7523a46df7 (patch)
tree807e708c32d6d8710bcc1b6f96862ed34b320072
parent8f9dcbf33d5cd3222e4d8e0cfa6f72b1596b917c (diff)
Conditions and states (boons & banes), with `quarrying_draught`
-rw-r--r--app/controllers/characters/items_controller.rb8
-rw-r--r--app/models/character.rb9
-rw-r--r--app/models/condition.rb5
-rw-r--r--app/models/state.rb23
-rw-r--r--app/views/characters/show.html.erb13
-rw-r--r--data/conditions.yml9
-rw-r--r--data/items.yml9
-rw-r--r--db/migrate/20210529195709_create_conditions.rb12
-rw-r--r--db/migrate/20210529195809_create_states.rb11
-rw-r--r--db/schema.rb23
-rw-r--r--db/seeds.rb5
-rw-r--r--test/fixtures/conditions.yml11
-rw-r--r--test/fixtures/states.yml9
-rw-r--r--test/models/condition_test.rb7
-rw-r--r--test/models/state_test.rb7
15 files changed, 159 insertions, 2 deletions
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 @@
<p class="mb-4">Learned <%= @character.learned_activities.count %> recipe(s) or technique(s).</p>
+<div class="my-4">
+ <h2 class="text-2xl mb-2">Boons & Banes</h2>
+ <% if @character.active_states.any? %>
+ <ul>
+ <% @character.active_states.each do |state| %>
+ <ul><%= state.condition.name %> (expires in <%= state.remaining_duration %> seconds)</ul>
+ <% end %>
+ </ul>
+ <% else %>
+ <p>No boons or banes affect you.</p>
+ <% end %>
+</div>
+
<% 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| %>
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