From 9fec79398a34d26be1042e35cae429b88f8b96d0 Mon Sep 17 00:00:00 2001 From: David Gay Date: Wed, 19 May 2021 18:39:35 -0400 Subject: Revise and progress with hearth amenity construction --- app/controllers/activities_controller.rb | 8 +++- app/controllers/game_controller.rb | 1 + .../controllers/activities/timer_controller.js | 43 --------------------- app/javascript/controllers/timer_controller.js | 44 ++++++++++++++++++++++ app/models/activity.rb | 12 +++++- app/models/character.rb | 28 +++++++++++++- app/models/hearth.rb | 9 +++++ app/models/hearth_amenity.rb | 11 ++---- app/views/activities/_timer.html.erb | 9 +++-- app/views/characters/hearth/index.html.erb | 8 ++-- 10 files changed, 110 insertions(+), 63 deletions(-) delete mode 100644 app/javascript/controllers/activities/timer_controller.js create mode 100644 app/javascript/controllers/timer_controller.js (limited to 'app') diff --git a/app/controllers/activities_controller.rb b/app/controllers/activities_controller.rb index a535f99..a32ffab 100644 --- a/app/controllers/activities_controller.rb +++ b/app/controllers/activities_controller.rb @@ -5,7 +5,11 @@ class ActivitiesController < ApplicationController def start @activity = Activity.find(params[:id]) - current_char.update(activity: @activity, activity_started_at: Time.now) - redirect_to action: :show + if current_char.can_do_activity?(@activity) + redirect_to action: :show + else + flash[:alert] = "You can't do that. Make sure you have the items and meet the requirements." + redirect_to character_path(current_char) + end end end diff --git a/app/controllers/game_controller.rb b/app/controllers/game_controller.rb index d69645f..147b692 100644 --- a/app/controllers/game_controller.rb +++ b/app/controllers/game_controller.rb @@ -2,6 +2,7 @@ class GameController < ApplicationController def finish_activity @results = [] return unless current_char.activity_time_remaining <= 0 + return unless current_char.can_do_activity?(current_char.activity) # TODO: Add error message current_char.update(activity_started_at: Time.now) current_char.activity.whatnot[:results].each do |result| diff --git a/app/javascript/controllers/activities/timer_controller.js b/app/javascript/controllers/activities/timer_controller.js deleted file mode 100644 index 11057c0..0000000 --- a/app/javascript/controllers/activities/timer_controller.js +++ /dev/null @@ -1,43 +0,0 @@ -import { Controller } from "stimulus"; -import Rails from "@rails/ujs"; - -export default class extends Controller { - static targets = [ "timer" ]; - - static values = { - start: Number, - } - - initialize() { - this.counter = this.startValue; - this.timerTarget.textContent = this.counter; - } - - connect() { - this.startUpdating(); - } - - disconnect() { - this.stopUpdating(); - } - - startUpdating() { - this.timerInterval = setInterval(() => { - if (this.counter > 0) { - this.timerTarget.textContent = this.counter.toString(); - this.counter--; - } else if (this.counter === 0) { - Rails.ajax({ - type: "POST", - url: "/finish_activity", - }); - } - }, 1000); - } - - stopUpdating() { - if (this.timerInterval) { - clearInterval(this.timerInterval); - } - } -} diff --git a/app/javascript/controllers/timer_controller.js b/app/javascript/controllers/timer_controller.js new file mode 100644 index 0000000..7714bad --- /dev/null +++ b/app/javascript/controllers/timer_controller.js @@ -0,0 +1,44 @@ +import { Controller } from "stimulus"; +import Rails from "@rails/ujs"; + +export default class extends Controller { + static targets = [ "timer" ]; + + static values = { + start: Number, + postUrl: String, + } + + initialize() { + this.counter = this.startValue; + this.timerTarget.textContent = this.counter; + } + + connect() { + this.startUpdating(); + } + + disconnect() { + this.stopUpdating(); + } + + startUpdating() { + this.timerInterval = setInterval(() => { + if (this.counter > 0) { + this.timerTarget.textContent = this.counter.toString(); + this.counter--; + } else if (this.counter === 0) { + Rails.ajax({ + type: "POST", + url: this.postUrlValue, + }); + } + }, 1000); + } + + stopUpdating() { + if (this.timerInterval) { + clearInterval(this.timerInterval); + } + } +} diff --git a/app/models/activity.rb b/app/models/activity.rb index fb99e1d..e70121e 100644 --- a/app/models/activity.rb +++ b/app/models/activity.rb @@ -1,6 +1,16 @@ class Activity < ApplicationRecord include HasWhatnot - belongs_to :location + belongs_to :location, optional: true validates :gid, :name, :description, presence: true + + def cost_string + requirements = [] + data = self.whatnot[:cost] + return nil unless data + data[:items].each do |item_gid, quantity| + requirements.push "#{quantity} #{Item.find_by_gid(item_gid).name}" + end + requirements.join(", ") + end end diff --git a/app/models/character.rb b/app/models/character.rb index 661521b..a55230e 100644 --- a/app/models/character.rb +++ b/app/models/character.rb @@ -11,6 +11,7 @@ class Character < ApplicationRecord validates_format_of :name, with: /\A[a-z]+\z/i, message: "must consist of letters only" after_create :create_skills + after_create { Hearth.create(character: self) } def shift_item(gid, amount) CharacterItem.transaction do @@ -20,6 +21,11 @@ class Character < ApplicationRecord end end + def has_item?(item, quantity = 1) + ci = self.character_items.find_by(item: item) + ci && ci.quantity >= quantity + end + def add_skill_xp(skill, amount) CharacterSkill.find_by(skill: skill).increment!(:xp, amount) end @@ -32,13 +38,31 @@ class Character < ApplicationRecord return nil unless self.activity duration_data = self.activity.whatnot[:duration] duration = duration_data[:base] - duration_data[:scaling].each do |skill, scaling_amount| + duration_data[:scaling]&.each do |skill, scaling_amount| duration -= self.skill_level(skill) * scaling_amount end - duration = [duration, duration_data[:minimum]].max + duration = [duration, duration_data[:minimum] || 10].max duration - (Time.now - self.activity_started_at) end + def can_do_activity?(activity) + if activity.whatnot[:cost] + activity.whatnot[:cost][:items]&.each do |item_gid, quantity| + return false unless self.has_item?(item_gid, quantity) + end + end + activity.whatnot[:requirements]&.each do |requirement| + case requirement[:type] + when "hearth_amenity" + return false unless self.hearth.has_amenity?(requirement[:gid], requirement[:level]) + end + end + end + + def start_activity(activity) + self.update(activity: activity, activity_started_at: Time.now) if self.can_do_activity?(activity) + end + private def create_skills Skill.all.each { |skill| self.character_skills.create(skill: skill, xp: 0) } diff --git a/app/models/hearth.rb b/app/models/hearth.rb index 8885a08..5d244ec 100644 --- a/app/models/hearth.rb +++ b/app/models/hearth.rb @@ -1,3 +1,12 @@ class Hearth < ApplicationRecord belongs_to :character + has_many :built_hearth_amenities + has_many :hearth_amenities, through: :built_hearth_amenities + + def has_amenity?(hearth_amenity, level = 1) + hearth_amenity = HearthAmenity.find_by_gid(hearth_amenity) if hearth_amenity.is_a? String + bhi = self.built_hearth_amenities.find_by(hearth_amenity: hearth_amenity) + return false unless bhi + bhi.level >= level + end end diff --git a/app/models/hearth_amenity.rb b/app/models/hearth_amenity.rb index 16d8f97..f8ebad5 100644 --- a/app/models/hearth_amenity.rb +++ b/app/models/hearth_amenity.rb @@ -1,14 +1,9 @@ class HearthAmenity < ApplicationRecord include HasWhatnot - validates :gid, :name, :description, :whatnot, presence: true + validates :gid, :name, :description, presence: true - def build_requirements_string(level) - requirements = [] - data = self.whatnot[:constructions].find { |d| d[:level] == level } - data[:cost][:items].each do |item_gid, quantity| - requirements.push "#{quantity} #{Item.find_by_gid(item_gid).name}" - end - requirements.join(", ") + def construct_activity(level) + Activity.find_by_gid("construct_#{self.name.underscore}_level#{level}") end end diff --git a/app/views/activities/_timer.html.erb b/app/views/activities/_timer.html.erb index 418c378..27d9272 100644 --- a/app/views/activities/_timer.html.erb +++ b/app/views/activities/_timer.html.erb @@ -1,8 +1,9 @@ <% if current_char.activity %> -
- +
- <%= link_to "Stop", location_path(current_char.activity.location) %> + <%= link_to "Stop", character_path(current_char) %> <% end %> diff --git a/app/views/characters/hearth/index.html.erb b/app/views/characters/hearth/index.html.erb index 421d5e6..f087ede 100644 --- a/app/views/characters/hearth/index.html.erb +++ b/app/views/characters/hearth/index.html.erb @@ -1,8 +1,10 @@ +<% foundation = @all_amenities.find_by_gid("foundation") %>

Hearth

-<% if current_char.hearth %> +<% if current_char.hearth.has_amenity?(foundation) %> <% else %>

You haven't built your hearth yet. First, you'll need to start with a foundation.

- <% foundation = @all_amenities.find_by_gid("foundation") %> - <%= link_to "Build #{foundation.name}", "#" %> (requires <%= foundation.build_requirements_string(1) %>) + <% construct_activity = foundation.construct_activity(1) %> + <%= link_to construct_activity.name, start_activity_path(construct_activity), method: :post %> + (costs <%= construct_activity.cost_string %>) <% end %> -- cgit v1.2.3