--[[
[+] = done
[-] = not done
[+] random spawn location
[+] lost hp% mob/item spawn
[+] spawn items + monsters on death & start next spawn countdown
[-] DPS
]]
local config = {
SPAWN_AREAS = {
{
TOP_LEFT = Position(47, 399, 7),
BOTTOM_RIGHT = Position(61, 409, 7)
}
},
BOSS_NAME = 'cyclops smith',
-- How long after death should the boss respawn?
SPAWN_INTERVAL = 10, -- seconds
-- Item rewards
MIN_REWARD_AMOUNT = 1,
MAX_REWARD_AMOUNT = 3,
REWARDS = {
{2160, 1},
{2159, 2},
{8976, 1},
{13537, 1},
{2148, 5},
{2135, 1}
},
-- What the boss will spawn
SUMMONS = { 'rat', 'orc', 'troll', 'bear', 'wolf', 'snake', 'larva', 'donkey' },
-- Minimum and maximum amount of mobs to be spawned.
MIN_SUMMON_AMOUNT = 1,
MAX_SUMMON_AMOUNT = 5,
-- What will be created everytime a certain HP% is reached.
SPAWN_CHOICE_ITEMS = 1,
SPAWN_CHOICE_MOBS = 2,
SPAWN_CHOICE_BOTH = 3,
-- Radius to top-left & to bottom-right from boss position.
SPAWN_OBJECT_RADIUS = 3
}
local DAMAGE_REWARD_CONFIG = {
[1] = { hpPercent = 10 },
[2] = { hpPercent = 30 },
[3] = { hpPercent = 60 },
[4] = { hpPercent = 90 }
}
------------------------------------------------------------------------------------
---------------------------------[ GLOBALEVENT ]----------------------------------
------------------------------------------------------------------------------------
local function spawnLootBoss()
local area = config.SPAWN_AREAS[math.random(1, #config.SPAWN_AREAS)]
local spawnPos = Position(
math.random(area.TOP_LEFT.x, area.BOTTOM_RIGHT.x),
math.random(area.TOP_LEFT.y, area.BOTTOM_RIGHT.y),
area.TOP_LEFT.z
)
Game.createMonster(config.BOSS_NAME, spawnPos, false, true)
Game.broadcastMessage('The vicious boss '.. config.BOSS_NAME ..' has risen from the dead', MESSAGE_EVENT_ADVANCE)
REWARDS_COLLECTED = {}
end
local lootBoss = GlobalEvent('lootBoss')
function lootBoss.onStartup()
spawnLootBoss()
return true
end
lootBoss:register()
------------------------------------------------------------------------------------
-------------------------------[ CREATURESCRIPTS ]--------------------------------
------------------------------------------------------------------------------------
local function secondsToReadable(s)
local hours = math.floor(s / 3600)
local minutes = math.floor(math.mod(s, 3600)/60)
local seconds = math.floor(math.mod(s, 60))
return (hours > 0 and (hours .. ' hour' .. (hours > 1 and 's ' or ' ')) or '') ..
(minutes > 0 and (minutes .. ' minute' .. (minutes > 1 and 's ' or ' ')) or '') ..
(seconds > 0 and (seconds .. ' second' .. (seconds > 1 and 's ' or ' ')) or '')
end
local function getClosestFreeTile(pos, radius)
for y = pos.y - radius, pos.y + radius do
for x = pos.x - radius, pos.x + radius do
local tile = Tile(x, y, pos.z)
if tile and tile:isWalkable() then
return Position(x, y, pos.z)
end
end
end
return nil
end
local function spawnItem(spawnObjectArea)
local reward_idx = math.random(1, #config.REWARDS)
local reward_item_pos = Position(
math.random(spawnObjectArea.TOP_LEFT.x, spawnObjectArea.BOTTOM_RIGHT.x),
math.random(spawnObjectArea.TOP_LEFT.y, spawnObjectArea.BOTTOM_RIGHT.y),
spawnObjectArea.TOP_LEFT.z
)
local tile = Tile(reward_item_pos)
if (not tile) or (not tile:isWalkable()) then
reward_item_pos = getClosestFreeTile(reward_item_pos, 1)
end
if not reward_item_pos then
return
end
Game.createItem(config.REWARDS[reward_idx][1], config.REWARDS[reward_idx][2], reward_item_pos)
reward_item_pos:sendMagicEffect(CONST_ME_MAGIC_BLUE)
end
local function spawnMob(spawnObjectArea)
local mob_pos = Position(
math.random(spawnObjectArea.TOP_LEFT.x, spawnObjectArea.BOTTOM_RIGHT.x),
math.random(spawnObjectArea.TOP_LEFT.y, spawnObjectArea.BOTTOM_RIGHT.y),
spawnObjectArea.TOP_LEFT.z
)
local tile = Tile(mob_pos)
if (not tile) or (not tile:isWalkable()) then
mob_pos = getClosestFreeTile(mob_pos, 1)
end
if not mob_pos then
return
end
Game.createMonster(config.SUMMONS[math.random(1, #config.SUMMONS)], mob_pos, true, true)
mob_pos:sendMagicEffect(CONST_ME_MAGIC_BLUE)
end
------------------------------------------------------------------------------------
REWARDS_COLLECTED = {}
local lootBoss_ce = CreatureEvent('lootBossCE')
function lootBoss_ce.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
local hpAfterDmg = creature:getHealth() - (primaryDamage + secondaryDamage)
local hpDiffPercent = math.floor((creature:getMaxHealth() - hpAfterDmg) * 100 / creature:getMaxHealth())
local bossPos = creature:getPosition()
for i = #DAMAGE_REWARD_CONFIG, 1, -1 do
local f = (function(hpPercent)
----------------------------------------
if hpDiffPercent < hpPercent then
return false
end
if REWARDS_COLLECTED[i] then
return false
end
REWARDS_COLLECTED[i] = 1
local spawnObjectArea = {
TOP_LEFT = Position(
bossPos.x - config.SPAWN_OBJECT_RADIUS,
bossPos.y - config.SPAWN_OBJECT_RADIUS,
bossPos.z
),
BOTTOM_RIGHT = Position(
bossPos.x + config.SPAWN_OBJECT_RADIUS,
bossPos.y + config.SPAWN_OBJECT_RADIUS,
bossPos.z
),
}
local spawnChoice = math.random(config.SPAWN_CHOICE_ITEMS, config.SPAWN_CHOICE_BOTH)
if spawnChoice == config.SPAWN_CHOICE_ITEMS then
for ix = config.MIN_REWARD_AMOUNT, config.MAX_REWARD_AMOUNT do
spawnItem(spawnObjectArea)
end
return true
end
if spawnChoice == config.SPAWN_CHOICE_MOBS then
for ix = config.MIN_REWARD_AMOUNT, config.MAX_REWARD_AMOUNT do
spawnMob(spawnObjectArea)
end
return true
end
if spawnChoice == config.SPAWN_CHOICE_BOTH then
for ix = config.MIN_REWARD_AMOUNT, config.MAX_SUMMON_AMOUNT do
spawnChoice = math.random(config.SPAWN_CHOICE_ITEMS, config.SPAWN_CHOICE_MOBS)
if spawnChoice == config.SPAWN_CHOICE_ITEMS then
spawnItem(spawnObjectArea)
else
spawnMob(spawnObjectArea)
end
end
return true
end
----------------------------------------
end)(DAMAGE_REWARD_CONFIG[i].hpPercent)
if f then break end
end
return primaryDamage, primaryType, secondaryDamage, secondaryType
end
lootBoss_ce:register()
local lootBossDeath = CreatureEvent('lootBossDeath')
function lootBossDeath.onDeath(creature, corpse, killer, mostDamageKiller, lastHitUnjustified, mostDamageUnjustified)
REWARDS_COLLECTED = {}
local bossPos = creature:getPosition()
local spawnObjectArea = {
TOP_LEFT = Position(
bossPos.x - config.SPAWN_OBJECT_RADIUS,
bossPos.y - config.SPAWN_OBJECT_RADIUS,
bossPos.z
),
BOTTOM_RIGHT = Position(
bossPos.x + config.SPAWN_OBJECT_RADIUS,
bossPos.y + config.SPAWN_OBJECT_RADIUS,
bossPos.z
),
}
for i = config.MIN_REWARD_AMOUNT, config.MAX_REWARD_AMOUNT * 2 do
spawnItem(spawnObjectArea)
end
Game.broadcastMessage(creature:getName() .. ' has been killed. Next spawn in ' .. secondsToReadable(config.SPAWN_INTERVAL), MESSAGE_EVENT_ADVANCE)
addEvent(spawnLootBoss, config.SPAWN_INTERVAL * 1000)
return true
end
lootBossDeath:register()