summaryrefslogtreecommitdiff
path: root/app/models/monster_spawn_combat.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/monster_spawn_combat.rb')
-rw-r--r--app/models/monster_spawn_combat.rb70
1 files changed, 70 insertions, 0 deletions
diff --git a/app/models/monster_spawn_combat.rb b/app/models/monster_spawn_combat.rb
index 50a565b..7ad06c8 100644
--- a/app/models/monster_spawn_combat.rb
+++ b/app/models/monster_spawn_combat.rb
@@ -3,4 +3,74 @@ class MonsterSpawnCombat < ApplicationRecord
belongs_to :character
validates :hp_lost, numericality: { greater_than_or_equal_to: 0, only_integer: true }
+
+ after_create :check_hp
+
+ private
+ def check_hp
+ return if monster_spawn.alive?
+ monster = monster_spawn.monster
+ message_body_parts = {}
+
+ # TODO: HACK (should allow multiple xp awards, eventually)
+ xp_award_data = monster.whatnot[:awards].find { |a| a[:type] == "xp" }
+ involved_character_ids = MonsterSpawnCombat.where(monster_spawn: monster_spawn).pluck(:character_id).uniq
+ involved_characters = Character.where(id: involved_character_ids)
+ involved_characters.each do |character|
+ total_xp = xp_award_data[:base] * MonsterSpawnCombat.where(monster_spawn: monster_spawn, character: character).count
+ character.add_skill_xp(xp_award_data[:gid], total_xp)
+ message_body_parts[character.id] ||= []
+ message_body_parts[character.id].push("You got #{total_xp} #{Skill.find_by_gid(xp_award_data[:gid]).name} XP.")
+ end
+
+ monster.whatnot[:awards]&.each do |data|
+ case data[:type]
+ when "item"
+ return if rand > (data[:chance] || 1)
+
+ if data[:table]
+ table_roll = rand
+
+ data[:table].sort_by { |t| -t[:score] }.each do |table_entry|
+ min_quantity = table_entry[:min_quantity] || table_entry[:quantity] || 1
+ max_quantity = table_entry[:max_quantity] || table_entry[:quantity] || 1
+ quantity = rand(min_quantity..max_quantity)
+
+ score = table_entry[:score]
+
+ if table_roll >= score
+ winning_character = involved_characters.sample
+ item = Item.find_by_gid(data[:gid])
+ winning_character.shift_item(item, quantity)
+ message_body_parts[winning_character.id] ||= []
+ message_body_parts[winning_character.id].push("You got #{quantity} #{item.name}.k")
+ break
+ end
+ end
+ else
+ min_quantity = data[:min_quantity] || data[:quantity] || 1
+ max_quantity = data[:max_quantity] || data[:quantity] || 1
+ quantity = rand(min_quantity..max_quantity)
+ winning_character = involved_characters.sample
+ item = Item.find_by_gid(data[:gid])
+ winning_character.shift_item(item, quantity)
+ message_body_parts[winning_character.id] ||= []
+ message_body_parts[winning_character.id].push("You got #{quantity} #{item.name}.")
+ break
+ end
+ end
+ end
+
+ message_body_parts.each do |character_id, body_parts|
+ if body_parts.any?
+ Message.create(recipient_id: character_id, subject: "#{monster.name} slain", body: body_parts.join(", "))
+ end
+ end
+
+ chat_message = ChatMessage.new(body: "The #{monster.name} in #{monster_spawn.location.name} has been slain!",
+ chat_room: ChatRoom.find_by_gid("news"))
+ if chat_message.save
+ ChatRoomChannel.broadcast_chat_message(chat_message)
+ end
+ end
end