- Joined
- Oct 30, 2010
- Messages
- 356
- Solutions
- 13
- Reaction score
- 815
Hello everyone,
I want to share a script that gives reward bag to all the players participating in fight against boss. The reward will be sent automatically as soon as boss dies, to players' inventory, or when no cap or space, will be sent to players' mailbox.
It features:
I want to share a script that gives reward bag to all the players participating in fight against boss. The reward will be sent automatically as soon as boss dies, to players' inventory, or when no cap or space, will be sent to players' mailbox.
It features:
- any player who has dealt damage to the boss (DamageMap) and was within a certain distance of the fallen boss at the time of death (local allowedDistance) will receive a reward
- if players' inventory is full, or player has no capacity, the reward will be sent to depot mailbox
- a reward can be obtained once for a certain time (delayTimer), killing the boss before that time passes will result in no loot for the impatient player
- support for items with charges and possiblity to set minimal count of a dropped item
- [new] unique items supported, like ferumbras hat, where only top damager receives the item
- [new] configs for multiple bosses in one place, for clearer and easier usage
- register the event in given monster file
XML:<script> <event name="bossDeath"/> </script>
- set boss corpse to 0, otherwise you will get additional loot message
XML:<look type="201" corpse="0" />
- put the script anywhere in data/scripts folder
LUA:
local bossConfig = {
["orshabaal"] = {
timeCounterStorage = 66666,
delayTimer = 10, --in seconds
bagId = 1993,
allowedDistance = 20, --max distance between boss and player, above this value no reward will be given to the remote player
loot = {
{item = 2160, minCount = 25, count = 50, chance = 100000, unique = 1}, --crystal coin
{item = 2494, count = 1, chance = 100000}, --demon armor
{item = 18408, count = 1, chance = 100000}, --prismatic ring
{item = 18407, charges = 750, count = 1, chance = 100000, unique = 1}, --prismatic necklace
{item = 5903, count = 1, chance = 100000, unique = 1} --ferumbras hat
}
},
["demodras"] = {
timeCounterStorage = 66667,
delayTimer = 20, --in seconds
bagId = 1991,
allowedDistance = 20, --max distance between boss and player, above this value no reward will be given to the remote player
loot = {
{item = 2160, minCount = 5, count = 5, chance = 100000, unique = 1}, --crystal coin
{item = 2492, count = 1, chance = 100000}, --dsm
{item = 18408, count = 1, chance = 100000}, --prismatic ring
{item = 18407, charges = 750, count = 1, chance = 100000, unique = 1}, --prismatic necklace
{item = 5919, count = 1, chance = 100000, unique = 1} --dragon claw
}
},
}
local creatureevent = CreatureEvent("bossDeath")
function creatureevent.onDeath(creature, corpse, killer, mostDamageKiller, unjustified, mostDamageUnjustified)
local creatureKey = creature:getName():lower()
local bossData = bossConfig[creatureKey]
if bossData then
local creaturePos = getCreaturePosition(creature)
local topDamage = 0
local topDamagerId = nil
for i, damage in pairs(creature:getDamageMap()) do
local totalDamage = damage.total or 0
if totalDamage > topDamage then
topDamage = totalDamage
topDamagerId = i
end
end
for i, damage in pairs(creature:getDamageMap()) do
local p = Player(i)
if p then
local ppos = p:getPosition()
if ppos:getDistance(creaturePos) <= bossData.allowedDistance then
sendReward(p, bossData, topDamagerId == i)
else
p:sendTextMessage(MESSAGE_EVENT_ADVANCE,"The monster you fought has fallen, but you are too far away to claim your prize.")
end
end
end
end
end
creatureevent:register()
function sendReward(player, bossData, isTopDamager)
local currentTime, currentStorage = os.time(), player:getStorageValue(bossData.timeCounterStorage)
if currentStorage > currentTime then
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You can obtain the reward again in " .. os.date("!%H hours %M minutes and %S seconds", currentStorage - currentTime) .. ".")
return false
end
local message = "You found reward bag containing: "
local bag = Game.createItem(bossData.bagId, 1)
for i = 1, #bossData.loot do
local rand = math.random(100000)
local itemConfig = bossData.loot[i]
if rand <= itemConfig.chance then
local randomcount = math.random(itemConfig.minCount or 1, itemConfig.count or 100)
if not itemConfig.count then itemConfig.count = 100 end
if itemConfig.count >= 2 and not itemConfig.charges then --for items with count 2 or more and without charges obviously
if itemConfig.unique == 1 then
if isTopDamager then
item = Game.createItem(itemConfig.item, randomcount)
else
item = nil
end
else
item = Game.createItem(itemConfig.item, randomcount)
end
elseif itemConfig.charges then --for items with charges
if itemConfig.unique == 1 then
if isTopDamager then
item = Game.createItem(itemConfig.item, itemConfig.charges)
else
item = nil
end
else
item = Game.createItem(itemConfig.item, itemConfig.charges)
end
else --no charges and no count
if itemConfig.unique == 1 then
if isTopDamager then
item = Game.createItem(itemConfig.item, count)
else
item = nil
end
else
item = Game.createItem(itemConfig.item, count)
end
end
if item then
bag:addItemEx(item)
if message ~= "You found reward bag containing: " then
message = message .. ", "
end
message = message .. randomcount .. " " .. ItemType(itemConfig.item):getName()
end
end
end
if message == "You found reward bag containing: " then
message = message .. "nothing"
end
if player:addItemEx(bag) ~= RETURNVALUE_NOERROR then
local inbox = player:getInbox()
if not inbox then
print("Failed to get inbox for player: " .. player:getName())
return false
end
local addResult = inbox:addItemEx(bag, 1, FLAG_NOLIMIT)
if addResult ~= RETURNVALUE_NOERROR then
print("Failed to add item to inbox for player: " .. player:getName())
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "An error occurred while delivering your reward. Contact support.")
return false
end
message = message .. ".\n\nIt was sent directly to your inbox due to lack of space/capacity."
end
currentTime = currentTime + bossData.delayTimer
player:setStorageValue(bossData.timeCounterStorage, currentTime)
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, message .. ".")
return true
end
LUA:
local creatureName = "orshabaal"
local timeCounterStorage = 66666
local delayTimer = 30 --in seconds
local bagId = 1993
local mailboxPos = Position(1993, 1328, 7) --mailbox at this coordinates is required to send the reward, when no space in inventory or no cap
local allowedDistance = 20 --max distance between boss and player, above this value no reward will be given to the remote player
local loot = {
{item = 2160, count = 5, chance = 100000}, --crystal coin
{item = 2494, count = 1, chance = 50000}, --demon armor
{item = 18408, count = 1, chance = 15000}, --prismatic ring
{item = 18407, charges = 750, count = 1, chance = 15000} --prismatic necklace
}
local creatureevent = CreatureEvent("OrshabaalDeath")
function creatureevent.onDeath(creature, corpse, killer, mostDamageKiller, unjustified, mostDamageUnjustified)
if getCreatureName(creature):lower() == creatureName then
local creaturePos = getCreaturePosition(creature)
for i, damage in pairs(creature:getDamageMap()) do
local p = Player(i)
local ppos = p:getPosition()
if p then
if ppos:getDistance(creaturePos) <= allowedDistance then
sendReward(p)
else
p:sendTextMessage(MESSAGE_EVENT_ADVANCE,"The monster you fought has fallen, but you are too far away to claim your prize.")
end
end
end
end
end
creatureevent:register()
function sendReward(player)
local currentTime, currentStorage = os.time(), player:getStorageValue(timeCounterStorage)
if currentStorage > currentTime then
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You can obtain the reward again in " .. os.date("!%H hours %M minutes and %S seconds", currentStorage - currentTime) .. ".")
return false
end
local message = "You found reward bag containing: "
local bag = Game.createItem(bagId, 1)
for i = 1, #loot do
local rand = math.random(100000)
if rand <= loot[i].chance then
local randomcount = math.random(loot[i].count)
if loot[i].count >= 2 and not loot[i].charges then
item = Game.createItem(loot[i].item, randomcount)
bag:addItemEx(item)
elseif loot[i].charges then
item = Game.createItem(loot[i].item, loot[i].charges)
bag:addItemEx(item)
else
item = Game.createItem(loot[i].item, loot[i].count)
bag:addItemEx(item)
end
if message ~= "You found reward bag containing: " then
message = message .. ", "
end
message = message .. randomcount .. " " .. ItemType(loot[i].item):getName()
end
end
if message == "You found reward bag containing: " then
message = message .. "nothing"
end
if player:addItemEx(bag) ~= RETURNVALUE_NOERROR then
local mailboxCheck = player:getInbox()
if not mailboxCheck then
print("Mailbox not found!")
return false
else
--print("Mailbox is fine.")
end
player:getPosition():sendMagicEffect(CONST_ME_POFF)
message = message .. ".\n\nIt was sent to you mailbox due to lack of space/capacity"
local parcel = Game.createItem(ITEM_PARCEL, 1)
local label = Game.createItem(2599, 1)
local mailbox = Tile(mailboxPos)
doSetItemText(label.uid, player:getName())
parcel:addItemEx(bag)
parcel:addItemEx(label)
mailbox:addItemEx(parcel)
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have received a parcel with reward to your mailbox!")
end
currentTime = currentTime + delayTimer
player:setStorageValue(timeCounterStorage, currentTime)
player:sendTextMessage(MESSAGE_LOOT, message .. ".")
return true
end
Last edited: