summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorDavid Gay <david@davidgay.org>2021-06-02 22:15:02 -0400
committerDavid Gay <david@davidgay.org>2021-06-02 22:15:02 -0400
commit4c96893a114059dc4e748307c6d046ec1faa778f (patch)
tree10e3af95e7a3749e6bd0d1ab63fffebf5b567258 /app
parent6ec57509c6f1d44fb80a1cb2ae020b8a033dd370 (diff)
Magiculture
Diffstat (limited to 'app')
-rw-r--r--app/controllers/characters/hearth/hearth_plantings_controller.rb39
-rw-r--r--app/controllers/game_controller.rb12
-rw-r--r--app/errors/hearth_planting_error.rb2
-rw-r--r--app/models/character.rb10
-rw-r--r--app/models/concerns/has_whatnot.rb4
-rw-r--r--app/models/hearth.rb11
-rw-r--r--app/models/hearth_planting.rb9
-rw-r--r--app/views/characters/hearth/hearth_plantings/index.html.erb29
-rw-r--r--app/views/characters/hearth/index.html.erb3
-rw-r--r--app/views/look/_results.html.erb3
10 files changed, 122 insertions, 0 deletions
diff --git a/app/controllers/characters/hearth/hearth_plantings_controller.rb b/app/controllers/characters/hearth/hearth_plantings_controller.rb
new file mode 100644
index 0000000..198943f
--- /dev/null
+++ b/app/controllers/characters/hearth/hearth_plantings_controller.rb
@@ -0,0 +1,39 @@
+class Characters::Hearth::HearthPlantingsController < ApplicationController
+ before_action :redirect_unless_character_has_loamspire, :set_hearth
+
+ def index
+ @hearth_plantings = @hearth.hearth_plantings
+ @planting_activities = Activity.where("gid like ?", "plant_%")
+ end
+
+ def create
+ item = Item.find(params[:item_id])
+ unless item.tags&.include?("seed")
+ flash[:alert] = "You can only plant seeds here."
+ redirect_to character_hearth_loamspire_path and return
+ end
+
+ quantity = [params[:quantity], @hearth.available_planting_spots].min
+ if quantity < 1
+ flash[:alert] = "You don't have any available planting slots."
+ redirect_to character_hearth_loamspire_path and return
+ end
+
+ @hearth_planting = @hearth.hearth_plantings.new(item: item, quantity: quantity)
+ if @hearth_planting.save
+ flash[:notice] = "Planted #{quantity} #{item.name}."
+ else
+ flash[:alert] = "Failed to plant seeds."
+ end
+ redirect_to character_hearth_loamspire_path
+ end
+
+ private
+ def redirect_unless_character_has_loamspire
+ redirect_to character_hearth_path(current_char) unless current_char.hearth.has_amenity?("loamspire", 1)
+ end
+
+ def set_hearth
+ @hearth = current_char.hearth
+ end
+end
diff --git a/app/controllers/game_controller.rb b/app/controllers/game_controller.rb
index 2de342a..04d743c 100644
--- a/app/controllers/game_controller.rb
+++ b/app/controllers/game_controller.rb
@@ -129,6 +129,15 @@ class GameController < ApplicationController
.find_or_initialize_by(hearth_amenity: HearthAmenity.find_by_gid(result[:gid]))
bhi.update(level: result[:level])
@results.push({ type: type, hearth_amenity: bhi.hearth_amenity })
+ when "hearth_planting"
+ unless current_char.hearth.available_planting_spots > 0
+ @results.replace([{ type: "error", message: "You're out of space to plant seeds." }])
+ current_char.stop_activity
+ return
+ end
+ item = Item.find_by_gid(result[:gid])
+ hp = current_char.hearth.hearth_plantings.create(item: item)
+ @results.push({ type: type, hearth_planting: hp })
when "activity"
next if rand > (result[:chance] || 1)
table_roll = rand
@@ -174,6 +183,9 @@ class GameController < ApplicationController
rescue ItemQuantityError
current_char.stop_activity
@results.replace([{ type: "error", message: "You don't have enough items to complete this activity." }])
+ rescue HearthPlantingError
+ current_char.stop_activity
+ @results.replace([{ type: "error", message: "You don't have that crop planted." }])
rescue TooManyWoundsError
current_char.stop_activity
@results.replace([{ type: "error",
diff --git a/app/errors/hearth_planting_error.rb b/app/errors/hearth_planting_error.rb
new file mode 100644
index 0000000..4a2306f
--- /dev/null
+++ b/app/errors/hearth_planting_error.rb
@@ -0,0 +1,2 @@
+class HearthPlantingError < StandardError
+end
diff --git a/app/models/character.rb b/app/models/character.rb
index b7b323d..84583a8 100644
--- a/app/models/character.rb
+++ b/app/models/character.rb
@@ -106,6 +106,10 @@ class Character < ApplicationRecord
case cost[:type]
when "item"
self.shift_item(cost[:gid], -(cost[:quantity] || 1))
+ when "hearth_planting"
+ hp = hearth.ripe_hearth_plantings_of(cost[:gid]).first
+ raise HearthPlantingError unless hp
+ hp.destroy
end
end
end
@@ -217,6 +221,8 @@ class Character < ApplicationRecord
case cost[:type]
when "item"
return false unless self.has_item?(cost[:gid], cost[:quantity] || 1)
+ when "hearth_planting"
+ return false unless hearth.ripe_hearth_plantings_of(cost[:gid]).first
else
raise "Invalid cost type string (#{cost[:type]})"
end
@@ -288,6 +294,10 @@ class Character < ApplicationRecord
effects.filter_map { |e| e[:modifier] if e[:type] == "stat_change" && e[:gid] == gid }.sum
end
+ def planting_spots
+ [total_stat_change("planting_spots"), 0].max
+ end
+
def can_fight?
self.wounds < max_wounds
end
diff --git a/app/models/concerns/has_whatnot.rb b/app/models/concerns/has_whatnot.rb
index a4dcfa0..289fe40 100644
--- a/app/models/concerns/has_whatnot.rb
+++ b/app/models/concerns/has_whatnot.rb
@@ -5,5 +5,9 @@ module HasWhatnot
def whatnot
@whatnot ||= super.is_a?(Hash) ? super.deep_symbolize_keys! : nil
end
+
+ def tags
+ whatnot[:tags] if whatnot
+ end
end
end
diff --git a/app/models/hearth.rb b/app/models/hearth.rb
index 1bd54a5..ee00c0c 100644
--- a/app/models/hearth.rb
+++ b/app/models/hearth.rb
@@ -2,6 +2,7 @@ class Hearth < ApplicationRecord
belongs_to :character
has_many :built_hearth_amenities
has_many :hearth_amenities, through: :built_hearth_amenities
+ has_many :hearth_plantings
def has_amenity?(hearth_amenity, level = 1)
hearth_amenity = HearthAmenity.find_by_gid(hearth_amenity) if hearth_amenity.is_a? String
@@ -15,4 +16,14 @@ class Hearth < ApplicationRecord
bhi = self.built_hearth_amenities.find_by(hearth_amenity: hearth_amenity)
bhi ? bhi.level : 0
end
+
+ def available_planting_spots
+ character.planting_spots - hearth_plantings.count
+ end
+
+ def ripe_hearth_plantings_of(item)
+ item = Item.find_by_gid(item) if item.is_a? String
+ # TODO: Proper querey instead of loading all into memory.
+ hearth_plantings.all.select { |hp| hp.item == item && hp.ripens_at < Time.now }
+ end
end
diff --git a/app/models/hearth_planting.rb b/app/models/hearth_planting.rb
new file mode 100644
index 0000000..d6ae714
--- /dev/null
+++ b/app/models/hearth_planting.rb
@@ -0,0 +1,9 @@
+class HearthPlanting < ApplicationRecord
+ belongs_to :hearth
+ belongs_to :item
+
+ def ripens_at
+ created_at + item.whatnot[:ripen_duration][:base].seconds
+ end
+end
+
diff --git a/app/views/characters/hearth/hearth_plantings/index.html.erb b/app/views/characters/hearth/hearth_plantings/index.html.erb
new file mode 100644
index 0000000..8aaefcc
--- /dev/null
+++ b/app/views/characters/hearth/hearth_plantings/index.html.erb
@@ -0,0 +1,29 @@
+<h1 class="text-3xl mb-2">Loamspire</h1>
+
+<p>You have <span class="font-bold"><%= @hearth.available_planting_spots %></span> available planting spots.</p>
+
+<div class="my-4">
+ <%= form_with url: start_activity_path, method: :post do |f| %>
+ <%= f.select :id, @planting_activities.sort_by { |a| a.name }.map { |a| [a.name, a.id] } %>
+ <%= f.number_field :actions, value: 1, size: 5, min: 1, max: 2_000_000_000 %>
+ <%= f.submit "Plant" %>
+ <% end %>
+</div>
+
+<div class="grid grid-cols-1 lg:grid-cols-2 gap-4">
+ <% @hearth_plantings.each do |hp| %>
+ <div class="flex justify-between items-center border-2 border-yellow-900 rounded p-2">
+ <h2 class="font-bold"><%= hp.item.name %></h2>
+ <% if hp.ripens_at > Time.now %>
+ <p class="text-sm">Ripens in <%= distance_of_time_in_words_to_now(hp.ripens_at) %></p>
+ <% else %>
+ <% harvest_activity = Activity.find_by_gid(hp.item.whatnot[:harvest_activity]) %>
+ <%= form_with url: start_activity_path(harvest_activity) do |f| %>
+ <%= f.hidden_field :id, value: harvest_activity.id %>
+ <%= f.hidden_field :actions, value: current_char.hearth.ripe_hearth_plantings_of(hp.item).count %>
+ <%= f.submit "Harvest" %>
+ <% end %>
+ <% end %>
+ </div>
+ <% end %>
+</div>
diff --git a/app/views/characters/hearth/index.html.erb b/app/views/characters/hearth/index.html.erb
index c058007..7ff34c5 100644
--- a/app/views/characters/hearth/index.html.erb
+++ b/app/views/characters/hearth/index.html.erb
@@ -24,6 +24,9 @@
<% if built_amenity.usable? %>
<%= button_to "Use", hearth_amenity_use_path(built_amenity.hearth_amenity) %>
<% end %>
+ <% if built_amenity.hearth_amenity.gid == "loamspire" %>
+ <%= link_to "Manage", character_hearth_loamspire_path, class: "btn btn-primary" %>
+ <% end %>
<% end %>
<% next_level = built_amenity ? built_amenity.level + 1 : 1 %>
<% construct_activity = ha.construct_activity(next_level) %>
diff --git a/app/views/look/_results.html.erb b/app/views/look/_results.html.erb
index beb2deb..2c79812 100644
--- a/app/views/look/_results.html.erb
+++ b/app/views/look/_results.html.erb
@@ -9,6 +9,9 @@
</p>
<% when "hearth_amenity" %>
<p>You constructed <%= result[:hearth_amenity].name %>.</p>
+ <% when "hearth_planting" %>
+ <p>You planted <%= link_to result[:hearth_planting].item.name,
+ item_path(result[:hearth_planting].item) %> in the loam.</p>
<% when "activity" %>
<p>You realized how to <%= result[:activity].name %>!</p>
<% when "monster" %>