summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Gay <david@davidgay.org>2021-05-03 20:08:28 -0400
committerDavid Gay <david@davidgay.org>2021-05-03 20:08:28 -0400
commitdddbf75428477f5e073584939d098e55d6324be3 (patch)
treec35291b32f1ba19bda66839d778b9758549a140f
parentaa25545eb204d0ca842ab948af4c27cb217352d6 (diff)
Add CharacterSkills
-rw-r--r--app/models/character.rb8
-rw-r--r--app/models/character_skill.rb45
-rw-r--r--db/migrate/20210503235646_create_character_skills.rb11
-rw-r--r--db/schema.rb14
-rw-r--r--test/fixtures/character_skills.yml11
-rw-r--r--test/models/character_skill_test.rb7
6 files changed, 95 insertions, 1 deletions
diff --git a/app/models/character.rb b/app/models/character.rb
index ebda598..1e75b63 100644
--- a/app/models/character.rb
+++ b/app/models/character.rb
@@ -3,11 +3,14 @@ class Character < ApplicationRecord
belongs_to :activity, optional: true
has_many :character_items
has_many :items, through: :character_items
+ has_many :character_skills
validates :name, presence: true
validates_length_of :name, maximum: 15, message: "can't be longer than 15 characters"
validates_uniqueness_of :name, message: "is already being used"
validates_format_of :name, with: /\A[a-z]+\z/i, message: "must consist of letters only"
+ after_create :create_skills
+
def shift_item(gid, amount)
CharacterItem.transaction do
item = self.character_items.find_or_initialize_by(item: Item.find_by_gid(gid))
@@ -15,4 +18,9 @@ class Character < ApplicationRecord
item.save
end
end
+
+ private
+ def create_skills
+ Skill.all.each { |skill| self.character_skills.create(skill: skill, xp: 0) }
+ end
end
diff --git a/app/models/character_skill.rb b/app/models/character_skill.rb
new file mode 100644
index 0000000..189f386
--- /dev/null
+++ b/app/models/character_skill.rb
@@ -0,0 +1,45 @@
+class CharacterSkill < ApplicationRecord
+ belongs_to :character
+ belongs_to :skill
+ validates :skill_id, uniqueness: { scope: :character_id }
+ validates :xp, numericality: { greater_than_or_equal_to: 0, only_integer: true }
+
+ scope :ordered_by_skill_name, -> { includes(:skill).order("skills.name") }
+
+ XP_TOTALS_PER_LEVEL = [
+ 0, 117, 436, 959, 1685, 2615, 3749, 5088, 6634, 8387, 10347, 12517, 14897,
+ 17489, 20296, 23318, 26559, 30022, 33709, 37624, 41773, 46158, 50788,
+ 55667, 60804, 66207, 71886, 77853, 84122, 90706, 97626, 104899, 112551,
+ 120608, 129101, 138067, 147545, 157584, 168239, 179572, 191657, 204576,
+ 218427, 233319, 249382, 266761, 285626, 306173, 328626, 353243, 380324,
+ 410211, 443300, 480046, 520974, 566687, 617881, 675357, 740038, 812987,
+ 895428, 988769, 1094635, 1214895, 1351701, 1507535, 1685252, 1888141,
+ 2119991, 2385164, 2688687, 3036344, 3434803, 3891738, 4415991, 5017743,
+ 5708720, 6502428, 7414420, 8462610, 9667629, 11053238, 12646801, 14479834,
+ 16588636, 19015009, 21807100, 25020357, 28718640, 32975498, 37875637,
+ 43516611, 50010775, 57487528, 66095898, 76007520, 87420069, 100561203,
+ 115693120, 133117791, 153182996, 176289273, 202897924, 233540227,
+ 268828058, 309466113, 356265990, 410162408, 472231880, 543714231,
+ 626037362, 720845790, 830033503, 955781810, 1100602922, 1267390153,
+ 1459475733, 1680697391, 1935475040, 2228899094
+ ].freeze
+
+ def level
+ XP_TOTALS_PER_LEVEL.each_with_index do |total, index|
+ return index if total > self.xp
+ end
+ end
+
+ def total_xp_for_next_level
+ xp_required_for_level(level + 1)
+ end
+
+ def xp_to_next_level
+ total_xp_for_next_level - self.xp
+ end
+
+ private
+ def xp_required_for_level(level)
+ level <= 120 ? XP_TOTALS_PER_LEVEL[level - 1] : nil
+ end
+end
diff --git a/db/migrate/20210503235646_create_character_skills.rb b/db/migrate/20210503235646_create_character_skills.rb
new file mode 100644
index 0000000..d579ea0
--- /dev/null
+++ b/db/migrate/20210503235646_create_character_skills.rb
@@ -0,0 +1,11 @@
+class CreateCharacterSkills < ActiveRecord::Migration[6.1]
+ def change
+ create_table :character_skills do |t|
+ t.references :character, null: false, foreign_key: true
+ t.references :skill, null: false, foreign_key: true
+ t.bigint :xp
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index bddf880..626ec36 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_03_221405) do
+ActiveRecord::Schema.define(version: 2021_05_03_235646) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -37,6 +37,16 @@ ActiveRecord::Schema.define(version: 2021_05_03_221405) do
t.index ["item_id"], name: "index_character_items_on_item_id"
end
+ create_table "character_skills", force: :cascade do |t|
+ t.bigint "character_id", null: false
+ t.bigint "skill_id", null: false
+ t.bigint "xp"
+ t.datetime "created_at", precision: 6, null: false
+ t.datetime "updated_at", precision: 6, null: false
+ t.index ["character_id"], name: "index_character_skills_on_character_id"
+ t.index ["skill_id"], name: "index_character_skills_on_skill_id"
+ end
+
create_table "characters", force: :cascade do |t|
t.string "name"
t.bigint "user_id", null: false
@@ -110,6 +120,8 @@ ActiveRecord::Schema.define(version: 2021_05_03_221405) do
add_foreign_key "character_items", "characters"
add_foreign_key "character_items", "items"
+ add_foreign_key "character_skills", "characters"
+ add_foreign_key "character_skills", "skills"
add_foreign_key "characters", "activities"
add_foreign_key "characters", "users"
add_foreign_key "users", "characters", column: "active_character_id"
diff --git a/test/fixtures/character_skills.yml b/test/fixtures/character_skills.yml
new file mode 100644
index 0000000..16d363c
--- /dev/null
+++ b/test/fixtures/character_skills.yml
@@ -0,0 +1,11 @@
+# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+one:
+ character: one
+ skill: one
+ xp:
+
+two:
+ character: two
+ skill: two
+ xp:
diff --git a/test/models/character_skill_test.rb b/test/models/character_skill_test.rb
new file mode 100644
index 0000000..a31b736
--- /dev/null
+++ b/test/models/character_skill_test.rb
@@ -0,0 +1,7 @@
+require "test_helper"
+
+class CharacterSkillTest < ActiveSupport::TestCase
+ # test "the truth" do
+ # assert true
+ # end
+end