diff options
-rw-r--r-- | app/models/monster_spawn.rb | 11 | ||||
-rw-r--r-- | app/models/monster_spawn_combat.rb | 70 | ||||
-rw-r--r-- | data/monsters.yml | 2 |
3 files changed, 71 insertions, 12 deletions
diff --git a/app/models/monster_spawn.rb b/app/models/monster_spawn.rb index d34e390..4423557 100644 --- a/app/models/monster_spawn.rb +++ b/app/models/monster_spawn.rb @@ -3,7 +3,6 @@ class MonsterSpawn < ApplicationRecord belongs_to :location has_many :monster_spawn_combats - after_update :check_hp after_create :send_chat_message def alive? @@ -22,14 +21,4 @@ class MonsterSpawn < ApplicationRecord ChatRoomChannel.broadcast_chat_message(chat_message) end end - - def check_hp - if alive? - chat_message = ChatMessage.new(body: "The #{monster.name} in #{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 end 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 diff --git a/data/monsters.yml b/data/monsters.yml index 59024d6..a8714d0 100644 --- a/data/monsters.yml +++ b/data/monsters.yml @@ -301,7 +301,7 @@ balgoloth: awards: - type: "xp" gid: "beastslay" - base: 100 + base: 15 - type: "item" chance: 1 gid: "balgoloth_skull" |