summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorDavid Gay <david@davidgay.org>2021-05-31 16:51:47 -0400
committerDavid Gay <david@davidgay.org>2021-05-31 16:51:47 -0400
commitdcbb8efcde93af6452af77fea6b1038784db477e (patch)
tree476f1ccde46a663f27a3183e5fa9b202fce89f39 /app
parent99e2507bea007e4aac17cf562139f53f7f9da9bf (diff)
Character resting
Diffstat (limited to 'app')
-rw-r--r--app/controllers/application_controller.rb4
-rw-r--r--app/controllers/game_controller.rb29
-rw-r--r--app/models/character.rb37
-rw-r--r--app/views/characters/show.html.erb11
4 files changed, 79 insertions, 2 deletions
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 0fc78a8..f28d30b 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -17,6 +17,10 @@ class ApplicationController < ActionController::Base
private
def start_activity(activity)
+ if current_char.resting?
+ flash[:alert] = "You can't do anything while you're resting. Go to the Character page to stop resting."
+ redirect_to character_path(current_char) and return
+ end
if current_char.start_activity(activity, queued_actions: params[:queued_actions])
redirect_to look_path
else
diff --git a/app/controllers/game_controller.rb b/app/controllers/game_controller.rb
index 9de6e8f..f6bb7b8 100644
--- a/app/controllers/game_controller.rb
+++ b/app/controllers/game_controller.rb
@@ -1,4 +1,21 @@
class GameController < ApplicationController
+ def toggle_resting
+ if current_char.resting?
+ if current_char.stop_resting
+ flash[:notice] = "You stop resting. You now have #{current_char.rested_duration} seconds of rest."
+ else
+ flash[:alert] = "Failed to stop resting. Are you sure you're resting?"
+ end
+ else
+ if current_char.start_resting
+ flash[:notice] = "You are now resting."
+ else
+ flash[:alert] = "Failed to start resting. Are you already resting?"
+ end
+ end
+ redirect_to character_path(current_char)
+ end
+
def stop_activity
current_char.stop_activity
redirect_to locations_path
@@ -9,6 +26,13 @@ class GameController < ApplicationController
return unless current_char.activity_time_remaining <= 0
activity = current_char.activity
+ if current_char.resting?
+ @results.replace([{ type: "error", message: "You can't do anything while you're resting. Go to the Character" \
+ " page to stop resting." }])
+ current_char.stop_activity
+ return
+ end
+
unless current_char.can_do_activity?(activity)
message = "You can't do this right now."
message += " (requires #{activity.requirements&.join(", ")})" if activity.requirements.any?
@@ -19,6 +43,11 @@ class GameController < ApplicationController
end
Character.transaction do
+ if current_char.rested_duration > 0
+ remaining_rested_duration = current_char.rested_duration - current_char.rested_duration_to_spend_on_activity
+ current_char.update!(rested_duration: remaining_rested_duration)
+ end
+
current_char.pay_cost_for(activity)
activity.whatnot[:results].each do |result|
diff --git a/app/models/character.rb b/app/models/character.rb
index 56be0c0..5b3a4ab 100644
--- a/app/models/character.rb
+++ b/app/models/character.rb
@@ -15,11 +15,14 @@ class Character < ApplicationRecord
has_many :chat_messages
has_many :bazaar_orders
validates :name, presence: true
+ # TODO: Make defaults better. This has to allow nil so the `attribute` default works, and I don't like that.
+ validates :rested_duration, numericality: { greater_than_or_equal_to: 0, only_integer: true }, allow_nil: 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"
attribute :wounds, :integer, default: 0
+ attribute :rested_duration, :integer, default: 0
enum offensive_style: [:balanced, :precise, :brutal], _default: "balanced"
enum defensive_style: [:centered, :elusive, :protective], _default: "centered"
@@ -180,6 +183,12 @@ class Character < ApplicationRecord
end
def activity_time_remaining
+ time = duration_of_activity - (Time.now - self.activity_started_at)
+ time -= rested_duration_to_spend_on_activity if self.rested_duration > 0
+ time
+ end
+
+ def duration_of_activity
return nil unless self.activity
duration_data = self.activity.whatnot[:duration]
duration = duration_data[:base]
@@ -193,8 +202,12 @@ class Character < ApplicationRecord
raise "Invalid scaling type." # TODO: Improve this
end
end
- duration = [duration, duration_data[:minimum] || 10].max
- duration - (Time.now - self.activity_started_at)
+ [duration, duration_data[:minimum] || 10].max
+ end
+
+ def rested_duration_to_spend_on_activity
+ return nil unless self.activity
+ [duration_of_activity - 10, self.rested_duration].min
end
def can_do_activity?(activity, ignore_cost: false, ignore_requirements: false)
@@ -238,6 +251,26 @@ class Character < ApplicationRecord
self.update(activity: nil, activity_started_at: nil, queued_actions: nil)
end
+ def resting?
+ self.started_resting_at
+ end
+
+ def start_resting
+ return false if self.started_resting_at
+ self.update(started_resting_at: Time.now)
+ end
+
+ def stop_resting
+ return false unless self.started_resting_at
+ Character.transaction do
+ byebug
+ seconds_of_this_rest = (Time.now - self.started_resting_at).to_i
+ # Maximum rested duration is 10 days.
+ new_rested_duration = [(seconds_of_this_rest + self.rested_duration), (60 * 60 * 24 * 10)].min
+ self.update(started_resting_at: nil, rested_duration: new_rested_duration)
+ end
+ end
+
def award_title(title)
title = Title.find_by_gid(title) if title.is_a? String
# TODO: Simplify these lines?
diff --git a/app/views/characters/show.html.erb b/app/views/characters/show.html.erb
index 71d75a5..b2e8f94 100644
--- a/app/views/characters/show.html.erb
+++ b/app/views/characters/show.html.erb
@@ -106,5 +106,16 @@
</div>
<% if @character == current_char %>
+ <div class="my-6">
+ <h2 class="text-2xl mb-4">Rest</h2>
+ <p class="mb-4">
+ You have <%= @character.rested_duration %> seconds of rested time stored.
+ <% if current_char.resting? %>
+ This does not include time from your current rest. That time will be added when you stop resting.
+ <% end %>
+ </p>
+ <%= button_to current_char.resting? ? "Stop Resting" : "Start Resting", toggle_resting_path %>
+ </div>
+
<%= link_to "Manage account", edit_user_registration_path, class: "text-sm" %>
<% end %>