class GameController < ApplicationController def finish_activity @results = [] return unless current_char.activity_time_remaining <= 0 activity = current_char.activity return unless current_char.can_do_activity?(activity) # TODO: Add error message current_char.update(activity_started_at: Time.now) Character.transaction do current_char.pay_cost_for(activity) 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 score = item_data[:score] if result[:table_scaling] result[:table_scaling][:skills]&.each do |skill_gid, scale_value| score = score**(1 + (scale_value * current_char.skill_level(skill_gid))) end end if table_roll >= score item = Item.find_by_gid(item_gid) xp_awards = {} if item.whatnot && item.whatnot.key?(:xp_value) xp_awards = item.whatnot[:xp_value] .map { |gid, amount| { skill: Skill.find_by_gid(gid.to_s), amount: amount } } xp_awards.each do |award| current_char.add_skill_xp(award[:skill], award[:amount]) end end current_char.shift_item(item_gid, quantity) @results.push({ type: type, item: Item.find_by_gid(item_gid), quantity: quantity, xp: xp_awards }) break end end when "hearth_amenity" bhi = current_char.hearth.built_hearth_amenities .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 }) else raise "Invalid result type (#{type})" # TODO: Improve this. end end end rescue ItemQuantityError @results.replace({ type: "error", message: "You don't have enough items to complete this activity." }) end end