summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/models/monster_spawn.rb11
-rw-r--r--app/models/monster_spawn_combat.rb70
-rw-r--r--data/monsters.yml2
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"