diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/controllers/activities_controller.rb | 11 | ||||
-rw-r--r-- | app/controllers/game_controller.rb | 25 | ||||
-rw-r--r-- | app/javascript/controllers/activities/timer_controller.js | 43 | ||||
-rw-r--r-- | app/javascript/packs/application.js | 7 | ||||
-rw-r--r-- | app/models/character.rb | 15 | ||||
-rw-r--r-- | app/views/activities/_results.html.erb | 7 | ||||
-rw-r--r-- | app/views/activities/_timer.html.erb | 8 | ||||
-rw-r--r-- | app/views/activities/show.html.erb | 11 | ||||
-rw-r--r-- | app/views/game/finish_activity.js.erb | 12 | ||||
-rw-r--r-- | app/views/locations/show.html.erb | 3 |
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> |