summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorDavid Gay <david@davidgay.org>2021-05-04 17:55:28 -0400
committerDavid Gay <david@davidgay.org>2021-05-04 17:57:12 -0400
commit73744a9c6840fb0ba6f285ca81f9fba75ec22d5f (patch)
tree837333e9e46c5ccc6cf50214a94c2b9b6d0bb7f3 /app
parentdddbf75428477f5e073584939d098e55d6324be3 (diff)
Initial draft of timer setup, with results outputting and items being awarded
Diffstat (limited to 'app')
-rw-r--r--app/controllers/activities_controller.rb11
-rw-r--r--app/controllers/game_controller.rb25
-rw-r--r--app/javascript/controllers/activities/timer_controller.js43
-rw-r--r--app/javascript/packs/application.js7
-rw-r--r--app/models/character.rb15
-rw-r--r--app/views/activities/_results.html.erb7
-rw-r--r--app/views/activities/_timer.html.erb8
-rw-r--r--app/views/activities/show.html.erb11
-rw-r--r--app/views/game/finish_activity.js.erb12
-rw-r--r--app/views/locations/show.html.erb3
10 files changed, 141 insertions, 1 deletions
diff --git a/app/controllers/activities_controller.rb b/app/controllers/activities_controller.rb
new file mode 100644
index 0000000..a535f99
--- /dev/null
+++ b/app/controllers/activities_controller.rb
@@ -0,0 +1,11 @@
+class ActivitiesController < ApplicationController
+ def show
+ @activity = Activity.find(params[:id])
+ end
+
+ def start
+ @activity = Activity.find(params[:id])
+ current_char.update(activity: @activity, activity_started_at: Time.now)
+ redirect_to action: :show
+ end
+end
diff --git a/app/controllers/game_controller.rb b/app/controllers/game_controller.rb
new file mode 100644
index 0000000..3516056
--- /dev/null
+++ b/app/controllers/game_controller.rb
@@ -0,0 +1,25 @@
+class GameController < ApplicationController
+ def finish_activity
+ @results = []
+ return unless current_char.activity_time_remaining <= 0
+ current_char.update(activity_started_at: Time.now)
+ current_char.activity.whatnot["results"].each do |result|
+ type = result["type"]
+ case type
+ when "item"
+ next if rand > result["chance"]
+ table_roll = rand
+ result["table"].sort_by { |_, v| -v["score"] }.each do |item_gid, item_data|
+ quantity = item_data["quantity"] || 1
+ if table_roll >= item_data["score"]
+ current_char.shift_item(item_gid, quantity)
+ @results.push({ type: type, item: Item.find_by_gid(item_gid), quantity: quantity })
+ break
+ end
+ end
+ else
+ raise "Invalid result type (#{type})" # TODO: Improve this.
+ end
+ end
+ end
+end
diff --git a/app/javascript/controllers/activities/timer_controller.js b/app/javascript/controllers/activities/timer_controller.js
new file mode 100644
index 0000000..11057c0
--- /dev/null
+++ b/app/javascript/controllers/activities/timer_controller.js
@@ -0,0 +1,43 @@
+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/packs/application.js b/app/javascript/packs/application.js
index 856724b..a18528e 100644
--- a/app/javascript/packs/application.js
+++ b/app/javascript/packs/application.js
@@ -13,3 +13,10 @@ Turbolinks.start()
ActiveStorage.start()
require("stylesheets/application.css")
+
+// Stimulus
+import { Application } from "stimulus"
+import { definitionsFromContext } from "stimulus/webpack-helpers"
+const application = Application.start()
+const context = require.context("../controllers", true, /\.js$/)
+application.load(definitionsFromContext(context))
diff --git a/app/models/character.rb b/app/models/character.rb
index 1e75b63..aa434ef 100644
--- a/app/models/character.rb
+++ b/app/models/character.rb
@@ -19,6 +19,21 @@ class Character < ApplicationRecord
end
end
+ def skill_level(gid)
+ self.character_skills.find_by(skill: Skill.find_by_gid(gid.to_s)).level
+ end
+
+ def activity_time_remaining
+ return nil unless self.activity
+ duration_data = self.activity.whatnot["duration"]
+ duration = duration_data["base"]
+ duration_data["scaling"].each do |skill, scaling_amount|
+ duration -= self.skill_level(skill) * scaling_amount
+ end
+ duration = [duration, duration_data["minimum"]].max
+ duration - (Time.now - self.activity_started_at)
+ end
+
private
def create_skills
Skill.all.each { |skill| self.character_skills.create(skill: skill, xp: 0) }
diff --git a/app/views/activities/_results.html.erb b/app/views/activities/_results.html.erb
new file mode 100644
index 0000000..baa4ab0
--- /dev/null
+++ b/app/views/activities/_results.html.erb
@@ -0,0 +1,7 @@
+<div>
+ <% results.each do |result| %>
+ <% if result[:type] == "item" %>
+ <p>You got <%= result[:quantity] %> <%= result[:item].name %>.</p>
+ <% end %>
+ <% end %>
+</div>
diff --git a/app/views/activities/_timer.html.erb b/app/views/activities/_timer.html.erb
new file mode 100644
index 0000000..418c378
--- /dev/null
+++ b/app/views/activities/_timer.html.erb
@@ -0,0 +1,8 @@
+<% if current_char.activity %>
+ <div data-controller="activities--timer"
+ data-activities--timer-start-value="<%= current_char.activity_time_remaining.ceil %>"
+ class="text-center">
+ <span data-activities--timer-target="timer" class="text-3xl"></span>
+ </div>
+ <%= link_to "Stop", location_path(current_char.activity.location) %>
+<% end %>
diff --git a/app/views/activities/show.html.erb b/app/views/activities/show.html.erb
new file mode 100644
index 0000000..4e77061
--- /dev/null
+++ b/app/views/activities/show.html.erb
@@ -0,0 +1,11 @@
+<h1 class="text-2xl"><%= @activity.name %></h1>
+<p><%= @activity.description %></p>
+
+<div class="border-gray-800 rounded p-2" id="result_output">
+</div>
+
+<div id="result_controls">
+ <%= render "timer" %>
+</div>
+
+<%= link_to "Start", start_activity_path(@activity), method: :post %>
diff --git a/app/views/game/finish_activity.js.erb b/app/views/game/finish_activity.js.erb
new file mode 100644
index 0000000..99d200c
--- /dev/null
+++ b/app/views/game/finish_activity.js.erb
@@ -0,0 +1,12 @@
+var resultOutputDiv = document.getElementById("result_output");
+var resultControlsDiv = document.getElementById("result_controls");
+
+var outputHTML = "<%= j render(partial: "activities/results", locals: { results: @results }) %>"
+
+if (resultOutputDiv) {
+ resultOutputDiv.innerHTML += outputHTML;
+}
+
+if (resultControlsDiv) {
+ resultControlsDiv.innerHTML = "<%= j render(partial: "activities/timer") %>"
+}
diff --git a/app/views/locations/show.html.erb b/app/views/locations/show.html.erb
index c3a75e1..bc63541 100644
--- a/app/views/locations/show.html.erb
+++ b/app/views/locations/show.html.erb
@@ -2,6 +2,7 @@
<ul>
<% @location.activities.each do |activity| %>
- <li><span class="font-bold"><%= link_to activity.name, "#" %></span> – <%= activity.description %></li>
+ <li><span class="font-bold"><%= link_to activity.name, activity_path(activity) %></span>
+ – <%= activity.description %></li>
<% end %>
</ul>