summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/controllers/characters/items_controller.rb21
-rw-r--r--app/errors/equipment_error.rb2
-rw-r--r--app/models/character.rb25
-rw-r--r--app/models/equipment.rb11
-rw-r--r--app/models/item.rb9
-rw-r--r--app/views/characters/items/index.html.erb42
-rw-r--r--config/routes.rb5
-rw-r--r--data/items.yml6
-rw-r--r--data/skills.yml2
-rw-r--r--db/migrate/20210522184444_create_equipment.rb13
-rw-r--r--db/schema.rb15
-rw-r--r--test/fixtures/equipment.yml11
-rw-r--r--test/models/equipment_test.rb7
13 files changed, 152 insertions, 17 deletions
diff --git a/app/controllers/characters/items_controller.rb b/app/controllers/characters/items_controller.rb
index e1a30f8..8df23c8 100644
--- a/app/controllers/characters/items_controller.rb
+++ b/app/controllers/characters/items_controller.rb
@@ -1,5 +1,24 @@
class Characters::ItemsController < ApplicationController
def index
- @character_items = Character.find(params[:character_id]).character_items
+ @character = Character.find(params[:character_id])
+ end
+
+ def equip
+ @item = Item.find(params[:item_id])
+ current_char.equip(@item)
+ flash[:notice] = "Equipped #{@item.name}."
+ rescue EquipmentError
+ flash[:alert] = "Couldn't equip #{@item.name}."
+ ensure
+ redirect_to character_items_path(current_char)
+ end
+
+ def unequip
+ current_char.unequip(params[:slot].to_sym)
+ flash[:notice] = "Unequipped item."
+ rescue EquipmentError
+ flash[:alert] = "Couldn't unequip item."
+ ensure
+ redirect_to character_items_path(current_char)
end
end
diff --git a/app/errors/equipment_error.rb b/app/errors/equipment_error.rb
new file mode 100644
index 0000000..0d24e8a
--- /dev/null
+++ b/app/errors/equipment_error.rb
@@ -0,0 +1,2 @@
+class EquipmentError < StandardError
+end
diff --git a/app/models/character.rb b/app/models/character.rb
index 73d2c4b..59ed5ae 100644
--- a/app/models/character.rb
+++ b/app/models/character.rb
@@ -5,6 +5,7 @@ class Character < ApplicationRecord
has_many :titles, through: :title_awards
belongs_to :active_title, class_name: "Title", optional: true
has_one :hearth
+ has_many :equipment
has_many :character_items
has_many :learned_activities
has_many :items, through: :character_items
@@ -44,6 +45,30 @@ class Character < ApplicationRecord
ci && ci.quantity >= quantity
end
+ def open_slots_for(item)
+ full_slots = self.equipment.map { |e| e.slot }
+ item.equip_slots.reject { |slot| full_slots.include?(slot) }
+ end
+
+ def equip(item)
+ Character.transaction do
+ open_slots = self.open_slots_for(item)
+ raise EquipmentError unless open_slots.any?
+ self.shift_item(item, -1)
+ self.equipment.create(item: item, slot: open_slots.first)
+ end
+ end
+
+ def unequip(slot)
+ Character.transaction do
+ equipment = self.equipment.find_by(slot: slot)
+ raise EquipmentError unless equipment
+ item = equipment.item
+ equipment.destroy
+ self.shift_item(item, 1)
+ end
+ end
+
def add_skill_xp(skill, amount)
CharacterSkill.find_by(skill: skill).increment!(:xp, amount)
end
diff --git a/app/models/equipment.rb b/app/models/equipment.rb
new file mode 100644
index 0000000..11030fd
--- /dev/null
+++ b/app/models/equipment.rb
@@ -0,0 +1,11 @@
+class Equipment < ApplicationRecord
+ belongs_to :character
+ belongs_to :item
+ enum slot: [:mainhand, :offhand, :head, :neck, :back, :torso, :grip,
+ :left_ring, :right_ring, :waist, :legs, :feet, :curio]
+ validates :slot, presence: true, uniqueness: { scope: :character }
+
+ def slot
+ self[:slot].to_sym
+ end
+end
diff --git a/app/models/item.rb b/app/models/item.rb
index d42460b..5e60f04 100644
--- a/app/models/item.rb
+++ b/app/models/item.rb
@@ -5,4 +5,13 @@ class Item < ApplicationRecord
:left_ring, :right_ring, :waist, :legs, :feet, :curio]
validates :gid, :name, :description, presence: true
validates :usable, inclusion: { in: [true, false] }
+
+ def equipment?
+ self.whatnot && self.whatnot[:equip_slots]&.any?
+ end
+
+ def equip_slots
+ return [] unless self.equipment?
+ self.whatnot[:equip_slots].map { |data| data.to_sym }
+ end
end
diff --git a/app/views/characters/items/index.html.erb b/app/views/characters/items/index.html.erb
index e313f7e..a7c932d 100644
--- a/app/views/characters/items/index.html.erb
+++ b/app/views/characters/items/index.html.erb
@@ -1,23 +1,49 @@
-<h1 class="text-xl">Inventory</h1>
+<h1 class="text-3xl mb-4">Inventory</h1>
-<table class="table-auto">
+<h2 class="text-xl mb-4">Equipment</h2>
+
+<table class="table-auto mb-8">
+ <thead>
+ <tr>
+ <th class="table-header-padded">Slot</th>
+ <th class="table-header-padded">Item</th>
+ <th class="table-header-padded">Unequip</th>
+ </tr>
+ </thead>
+ <tbody>
+ <% @character.equipment.each do |eq| %>
+ <tr>
+ <td class="table-cell-padded"><%= eq.slot.to_s %></td>
+ <td class="table-cell-padded"><%= eq.item.name %></td>
+ <td class="table-cell-padded">
+ <%= button_to "Unequip", character_item_unequip_path(slot: eq.slot ) %>
+ </td>
+ </tr>
+ <% end %>
+ </tbody>
+</table>
+
+
+
+<h2 class="text-xl mb-4">Inventory</h2>
+
+<table class="table-auto mb-8">
<thead>
<tr>
<th class="table-header-padded">Amount</th>
<th class="table-header-padded">Item</th>
<th class="table-header-padded">Equip</th>
<th class="table-header-padded">Use</th>
- <th class="table-header-padded">Destroy</th>
</tr>
</thead>
<tbody>
- <% @character_items.ordered_by_item_name.each do |ci| %>
+ <% @character.character_items.ordered_by_item_name.each do |ci| %>
<tr>
<td class="table-cell-padded text-right"><%= ci.quantity %></td>
<td class="table-cell-padded"><%= ci.item.name %></td>
<td class="table-cell-padded">
- <% if ci.item.equip_slot %>
- <%= link_to "[Equip]", "#" %>
+ <% if ci.item.equipment? %>
+ <%= button_to "Equip", character_item_equip_path(item_id: ci.item.id) %>
<% end %>
</td>
<td class="table-cell-padded">
@@ -25,10 +51,6 @@
<%= link_to "[Use]", "#" %>
<% end %>
</td>
- <td class="table-cell-padded">
- <%= link_to "[Destroy]", "#" %>
- <%= link_to "[Destroy All]", "#" %>
- </td>
</tr>
<% end %>
</tbody>
diff --git a/config/routes.rb b/config/routes.rb
index e29f9e9..f9c1f7b 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -17,7 +17,10 @@ Rails.application.routes.draw do
resources :characters, only: [:show, :new, :create] do
scope module: :characters do
- resources :items, only: [:index]
+ post "/items/unequip/:slot", to: "items#unequip", as: :item_unequip
+ resources :items, only: [:index] do
+ post "/equip", to: "items#equip"
+ end
resources :titles, only: [:index] do
post "/activate", to: "titles#activate"
end
diff --git a/data/items.yml b/data/items.yml
index 5b5bc3b..ae1db0f 100644
--- a/data/items.yml
+++ b/data/items.yml
@@ -32,12 +32,14 @@ iron_short_sword:
name: "Iron short sword"
description: "A short sword made of iron."
whatnot:
- equip_slot: "mainhand"
+ equip_slots:
+ - "mainhand"
iron_longsword:
name: "Iron longsword"
description: "A longsword made of iron."
- equip_slot: "mainhand"
whatnot:
+ equip_slots:
+ - "mainhand"
equip_requirements:
skills:
beastslay: 3
diff --git a/data/skills.yml b/data/skills.yml
index 7f3f5e9..68de599 100644
--- a/data/skills.yml
+++ b/data/skills.yml
@@ -59,7 +59,7 @@ otherforge:
description: >-
Materials of all kinds -- from all planes -- are combined in an arcane forge by otherforgers, who have the ability
to craft weapons, armor, and materials from even the most bizarre and phenomenal resources. Masterful otherforgers
- have the power to smelt and temper magical energy itself into physical equipments, with incredible and otherworldly
+ have the power to smelt and temper magical energy itself into physical equipment, with incredible and otherworldly
results.
planequarry:
name: "Planequarry"
diff --git a/db/migrate/20210522184444_create_equipment.rb b/db/migrate/20210522184444_create_equipment.rb
new file mode 100644
index 0000000..4ac9543
--- /dev/null
+++ b/db/migrate/20210522184444_create_equipment.rb
@@ -0,0 +1,13 @@
+class CreateEquipment < ActiveRecord::Migration[6.1]
+ def change
+ create_table :equipment do |t|
+ t.references :character, null: false, foreign_key: true
+ t.references :item, null: false, foreign_key: true
+ t.integer :slot
+
+ t.timestamps
+ end
+
+ remove_column :items, :equip_slot
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index f2d776a..5649a54 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_20_230859) do
+ActiveRecord::Schema.define(version: 2021_05_22_184444) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -92,6 +92,16 @@ ActiveRecord::Schema.define(version: 2021_05_20_230859) do
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
+ t.integer "slot"
+ t.datetime "created_at", precision: 6, null: false
+ t.datetime "updated_at", precision: 6, null: false
+ t.index ["character_id"], name: "index_equipment_on_character_id"
+ t.index ["item_id"], name: "index_equipment_on_item_id"
+ end
+
create_table "hearth_amenities", force: :cascade do |t|
t.string "gid"
t.string "name"
@@ -113,7 +123,6 @@ ActiveRecord::Schema.define(version: 2021_05_20_230859) do
t.string "gid"
t.string "name"
t.text "description"
- t.integer "equip_slot"
t.boolean "usable"
t.jsonb "whatnot"
t.datetime "created_at", precision: 6, null: false
@@ -206,6 +215,8 @@ ActiveRecord::Schema.define(version: 2021_05_20_230859) do
add_foreign_key "chat_messages", "characters", column: "sender_id"
add_foreign_key "chat_messages", "characters", column: "target_id"
add_foreign_key "chat_messages", "chat_rooms"
+ add_foreign_key "equipment", "characters"
+ add_foreign_key "equipment", "items"
add_foreign_key "hearths", "characters"
add_foreign_key "learned_activities", "activities"
add_foreign_key "learned_activities", "characters"
diff --git a/test/fixtures/equipment.yml b/test/fixtures/equipment.yml
new file mode 100644
index 0000000..a454920
--- /dev/null
+++ b/test/fixtures/equipment.yml
@@ -0,0 +1,11 @@
+# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+one:
+ character: one
+ item: one
+ slot: 1
+
+two:
+ character: two
+ item: two
+ slot: 1
diff --git a/test/models/equipment_test.rb b/test/models/equipment_test.rb
new file mode 100644
index 0000000..48c29d5
--- /dev/null
+++ b/test/models/equipment_test.rb
@@ -0,0 +1,7 @@
+require "test_helper"
+
+class EquipmentTest < ActiveSupport::TestCase
+ # test "the truth" do
+ # assert true
+ # end
+end