popa45
Member
how you fixed ?This works!! thanks bud.
the only issue is now i get error regarding the loot xD haha
But i fixed this tho
how you fixed ?This works!! thanks bud.
the only issue is now i get error regarding the loot xD haha
But i fixed this tho
function statChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
function statChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
-- Defaults
local chance = 0 -- Crit Chance
local spellmodifier = 0 -- Spell Damage
local manaleech = 0
local lifeleech = 0
local stunDuration = 2000
local sourceDamage = primaryDamage -- Used for multi-shot when secondary targets are immune
local elementalroll = false -- Flag for if weapon has an element on it
local doubleroll = false -- Flag for if the weapon has two elements on it
--local dawnbreaker = false
--local rainbowshield = false
-- What elements should be checked when calculating resistances
local resistances = {
[COMBAT_PHYSICALDAMAGE] = {Native = 0, Custom = 0, String = "Physical"},
[COMBAT_FIREDAMAGE] = {Native = 0, Custom = 0, String = "Fire"},
[COMBAT_ICEDAMAGE] = {Native = 0, Custom = 0, String = "Ice"},
[COMBAT_ENERGYDAMAGE] = {Native = 0, Custom = 0, String = "Energy"},
[COMBAT_POISONDAMAGE] = {Native = 0, Custom = 0, String = "Poison"},
[COMBAT_PHYSICALDAMAGE] = {Native = 0, Custom = 0, String = "Death"}
}
-- Check resistences if victim is a player before applying extra elemental damage below
if creature:isPlayer() then
for i = 1,#checkallslots do
if creature:getSlotItem(checkallslots[i]) ~= nil then
local resistanceitem = creature:getSlotItem(checkallslots[i])
local resistanceitemdesc = resistanceitem:getDescription()
getResistences(resistanceitemdesc, resistances, true)
--[[
-- if rainbow shield
if resistanceitem.itemid == 8905 then
if checkallslots[i] == CONST_SLOT_LEFT or checkallslots[i] == CONST_SLOT_RIGHT then -- Only if equipped
rainbowshield = resistanceitem
end
end
--]]
end
end
-- Reduce main damage on custom resistance rolls before applying extra elemental damage below
if primaryType ~= 0 then
if resistances[primaryType] then
if resistances[primaryType].Custom ~= 0 then
local resistancePercent = (100 - resistances[primaryType].Custom)
primaryDamage = (resistancePercent / 100) * primaryDamage
end
end
end
if secondaryType ~= 0 then
if resistances[secondaryType] then
if resistances[secondaryType].Custom ~= 0 then
local resistancePercent = (100 - resistances[secondaryType].Custom)
secondaryDamage = (resistancePercent / 100) * secondaryDamage
end
end
end
end
if attacker then -- Ignore HP changes from healing fountains, terrain elemental fields (neutral sources basically)
if attacker:isPlayer() then
if origin == ORIGIN_RANGED or origin == ORIGIN_MELEE then -- Skip if player is using spells
-- Natural elemental damage (wand, fire sword, flaming arrow etc) swap Types around for better visuals and set flags
if secondaryType ~= 0 or primaryType ~= COMBAT_PHYSICALDAMAGE then
-- Cache original physical damage
local originalDamage = primaryDamage
local originalType = primaryType
-- Swap primary & secondary
primaryDamage = secondaryDamage
primaryType = secondaryType
secondaryDamage = originalDamage
secondaryType = originalType
-- damageTypes have been swapped, flag it
elementalroll = true
end
-- Check weapons for crit/elemental damage
for i = 1,#checkweaponslots do -- Roll for each slot
if attacker:getSlotItem(checkweaponslots[i]) ~= nil then
local slotitem = attacker:getSlotItem(checkweaponslots[i])
local slotitemdesc = slotitem:getDescription()
function doTargetCombatCondition(attacker, creature, condition, effect)
-- Implementação da função
end
-- Verificar dano elemental
if slotitemdesc:find("%[Enhanced Fire Damage") then
primaryDamage, primaryType, secondaryDamage, secondaryType, elementalroll = elementalDmg(slotitemdesc, COMBAT_FIREDAMAGE, true, creature, resistances, primaryDamage, primaryType, secondaryDamage, secondaryType, elementalroll)
-- 33% de chance de aplicar queimadura
if math.random(1, 3) == 3 then
local condition = createConditionObject(CONDITION_FIRE)
local burnDamage = 20
-- Ajustar dano de queimadura com base nas resistências
if creature:isPlayer() then
if resistances[COMBAT_FIREDAMAGE].Custom ~= 0 or resistances[COMBAT_FIREDAMAGE].Native ~= 0 then
local resistancePercent = (100 - (resistances[COMBAT_FIREDAMAGE].Custom + resistances[COMBAT_FIREDAMAGE].Native))
burnDamage = (resistancePercent / 100) * burnDamage
end
elseif creature:isMonster() then
local resistance = creature:getType():getElementList()
local immunity = creature:getType():getCombatImmunities()
-- Ajustar dano de queimadura com base nas resistências do monstro
if resistance[COMBAT_FIREDAMAGE] then
local resistancePercent = (100 - resistance[COMBAT_FIREDAMAGE])
burnDamage = (resistancePercent / 100) * burnDamage
end
-- Se o monstro for imune ao dano de fogo, definir dano de queimadura como zero
if bit.band(immunity, COMBAT_FIREDAMAGE) == COMBAT_FIREDAMAGE then
burnDamage = 0
end
end
-- Se o dano de queimadura não for zero, criar condição e aplicar ao alvo
if burnDamage ~= 0 then
addDamageCondition(condition, 10, 2000, burnDamage)
setConditionParam(condition, CONDITION_PARAM_DELAYED, true)
doTargetCombatCondition(attacker, creature, condition, CONST_ME_FIRE)
end
end
end
if slotitemdesc:find "%[Enhanced Ice Damage" then
primaryDamage, primaryType, secondaryDamage, secondaryType, elementalroll = elementalDmg(slotitemdesc, COMBAT_ICEDAMAGE, false, creature, resistances, primaryDamage, primaryType, secondaryDamage, secondaryType, elementalroll)
if math.random(1,5) == 5 then -- 20% to paralyze/slow
local condition = createConditionObject(CONDITION_PARALYZE)
setConditionParam(condition, CONDITION_PARAM_TICKS, 3000)
setConditionParam(condition, CONDITION_PARAM_SPEED, -300)
doTargetCombatCondition(attacker, creature, condition, CONST_ME_MAGIC_ICEAREA)
end
end
if slotitemdesc:find "%[Enhanced Energy Damage" then
primaryDamage, primaryType, secondaryDamage, secondaryType, elementalroll = elementalDmg(slotitemdesc, COMBAT_ENERGYDAMAGE, true, creature, resistances, primaryDamage, primaryType, secondaryDamage, secondaryType, elementalroll)
end
-- Check crit chance of slots and add together
if slotitemdesc:find "%[Crit Chance" then
local crit = string.match(slotitemdesc, "Crit Chance: [+-](%d+)%%")
chance = chance + crit
end
-- Mana leech gather %
if slotitemdesc:find "%[Mana Leech" then
manaleech = string.match(slotitemdesc, '%[Mana Leech: %+(%d+)%%%]') or 0
end
-- Life leech gather %
if slotitemdesc:find "%[Life Leech" then
lifeleech = string.match(slotitemdesc, '%[Life Leech: %+(%d+)%%%]') or 0
end
-- Stun Chance
if slotitemdesc:find "%[Stun Chance" then
local stunchance = tonumber(string.match(slotitemdesc, '%[Stun Chance: %+(%d+)%%%]')) or 0
local rollchance = math.random(1,100)
if stunchance >= rollchance and attacker ~= creature then
stunTarget(creature.uid, stunDuration)
end
end
-- Multi-shot
if slotitemdesc:find "%[Multi Shot" then
if attacker:getSlotItem(CONST_SLOT_AMMO) ~= nil then -- Does player have ammo
local multishot = tonumber(string.match(slotitemdesc, "%[Multi Shot: %+(%d+)%]"))
local ammoSlot = attacker:getSlotItem(CONST_SLOT_AMMO).itemid
local validammo = false
for k,v in pairs(animation) do
if k == ammoSlot then
validammo = true -- Ammo they're using exists in animation table
break
end
end
if validammo then -- (!) You may need to add more CONST_ANI_XXXX animations to the animation table
local targetpos = creature:getPosition()
local targets = getSpectators(targetpos, 2, 2) -- get possible multi-shot targets
local victims = {}
if targets ~= nil then
-- do the shuffle
shuffle(targets)
for i = 1,#targets do
local target = Creature(targets[i])
if target:isMonster() then -- only target monsters
if isSightClear(attacker:getPosition(), target:getPosition()) then -- that are in sight
if target:getPosition() ~= targetpos then -- ignore the original target
local victimcount = #victims or 0
if victimcount < multishot then
table.insert(victims, target) -- collate valid targets into victims table
else
break -- exit the for loop, have enough targets
end
end
end
end
end
end
function doTargetCombatHealth(attacker, target, damageType, adjustedDamage, originalDamage)
-- Implementação da função aqui
end
-- this a rats nest due to swapping primaryType/secondaryType above for visuals
if victims ~= nil then
for i = 1, #victims do
-- Defaults
local damage = 0
local elementalDamage = 0
local backupDamage = 0
local mainType = primaryType
local altType = secondaryType
local resistance = victims[i]:getType():getElementList()
local immunity = victims[i]:getType():getCombatImmunities()
local distanceEffect = animation[ammoSlot]
-- Animation
attacker:getPosition():sendDistanceEffect(victims[i]:getPosition(), animation[ammoSlot])
-- Damage calculation
if elementalroll then -- Check if types are swapped
mainType = secondaryType
altType = primaryType
damage = filterResistance(secondaryDamage, secondaryType, immunity, resistance)
elementalDamage = filterResistance(primaryDamage, primaryType, immunity, resistance)
else -- Types haven't been swapped
damage = filterResistance(primaryDamage, primaryType, immunity, resistance)
elementalDamage = filterResistance(secondaryDamage, secondaryType, immunity, resistance)
end
-- Apply secondary damage if any
if elementalDamage ~= 0 then
doTargetCombatHealth(attacker, victims[i], altType, math.ceil((80 / 100) * elementalDamage), elementalDamage)
end
-- Apply main damage if any
if damage ~= 0 then
doTargetCombatHealth(attacker, victims[i], mainType, math.ceil((80 / 100) * damage), damage)
else -- No damage; fallback to original physical damage
backupDamage = filterResistance(sourceDamage, COMBAT_PHYSICALDAMAGE, immunity, resistance)
if backupDamage ~= 0 then -- Try rolling back to base physical damage
doTargetCombatHealth(attacker, victims[i], COMBAT_PHYSICALDAMAGE, math.ceil((80 / 100) * sourceDamage), sourceDamage)
else -- Monster is immune to physical damage too
victims[i]:getPosition():sendMagicEffect(CONST_ME_BLOCKHIT)
end
end
end
end
end
end
end
end
end
-- Roll crit chance and apply if critical strike
if chance > 0 then
if math.random(100) <= chance then
local pos = creature:getPosition()
pos:sendMagicEffect(criteffect)
-- if elemental roll flag, crit the swapped secondaryDamage instead of primaryDamage
if elementalroll then
secondaryDamage = secondaryDamage * critmodifier
else
primaryDamage = primaryDamage * critmodifier
end
end
end
-- Apply mana leech
if manaleech ~= 0 then
local manatoadd = math.floor((manaleech / 100) * (primaryDamage + secondaryDamage))
local attackerpos = attacker:getPosition()
addEvent(manaLeechConcat, 5, attacker.uid, manatoadd)
end
-- Apply life leech
if lifeleech ~= 0 then
-- Calcula a quantidade de vida a ser roubada com base na porcentagem de life leech
local lifetoadd = math.floor((lifeleech / 100) * (primaryDamage + secondaryDamage))
-- Obtém a posição do atacante (se necessário)
local attackerpos = attacker:getPosition()
print("Life leech applied. Attacker ID: " .. attacker.uid .. ", Lifetoadd: " .. lifetoadd)
-- Agende o evento para adicionar a vida roubada ao jogador
addEvent(lifeLeechConcat, 5, attacker.uid, lifetoadd)
else
print("Life leech not applied. Lifeleech is zero.")
end
elseif origin == ORIGIN_SPELL then
-- Reduce spell damage based on custom resistances
if resistances[primaryType] then
if resistances[primaryType].Custom ~= 0 then
local resistancePercent = (100 - resistances[primaryType].Custom)
primaryDamage = (resistancePercent / 100) * primaryDamage
end
end
-- Check slots that can roll the following attributes
for i = 1,#checkweaponslots do
if attacker:getSlotItem(checkweaponslots[i]) ~= nil then
local slotitem = attacker:getSlotItem(checkweaponslots[i])
local slotitemdesc = slotitem:getDescription()
-- Check crit chance of slots and add together
if slotitemdesc:find "%[Spell Damage" then
local spellDamage = string.match(slotitemdesc, "Spell Damage: [+-](%d+)%%")
spellmodifier = spellmodifier + spellDamage
end
-- Mana leech gather %
if slotitemdesc:find "%[Mana Leech" then
manaleech = string.match(slotitemdesc, '%[Mana Leech: %+(%d+)%%%]') or 0
end
-- Life leech gather %
if slotitemdesc:find "%[Life Leech" then
lifeleech = string.match(slotitemdesc, '%[Life Leech: %+(%d+)%%%]') or 0
end
-- Stun Chance
if slotitemdesc:find "%[Stun Chance" then
local stunchance = tonumber(string.match(slotitemdesc, '%[Stun Chance: %+(%d+)%%%]')) or 0
local rollchance = math.random(1,100)
if stunchance >= rollchance and attacker ~= creature then
stunTarget(creature.uid, stunDuration)
end
end
end
end
-- if using a +%spelldamage wand, adjust damage
if spellmodifier > 0 then
local extraDamage = (spellmodifier / 100) * primaryDamage
primaryDamage = primaryDamage + extraDamage
end
-- Apply mana leech
if manaleech ~= 0 and primaryType ~= COMBAT_HEALING and secondaryType ~= COMBAT_HEALING then
local manatoadd = math.floor((manaleech / 100) * (primaryDamage + secondaryDamage))
manaLeechConcat(attacker.uid, manatoadd)
end
-- Apply life leech
if lifeleech ~= 0 and primaryType ~= COMBAT_HEALING and secondaryType ~= COMBAT_HEALING then
local lifetoadd = math.floor((lifeleech / 100) * (primaryDamage + secondaryDamage))
lifeLeechConcat(attacker.uid, lifetoadd)
end
end
end
end
return primaryDamage, primaryType, secondaryDamage, secondaryType, origin
end
function onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
if primaryType ~= 128 then -- Ignore health potions
-- Call statChange for both player and monster attacks
primaryDamage, primaryType, secondaryDamage, secondaryType, origin = statChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
end
return primaryDamage, primaryType, secondaryDamage, secondaryType, origin
end
function onManaChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
if primaryType ~= 64 then -- Ignore mana potions
-- Call statChange for both player and monster attacks
primaryDamage, primaryType, secondaryDamage, secondaryType, origin = statChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
-- Apply magic shield bonus, even if neutral source
if creature:isPlayer() then
local manashield = 0
for i = 1,#checkweaponslots do
if creature:getSlotItem(checkweaponslots[i]) ~= nil then
local slotitem = creature:getSlotItem(checkweaponslots[i])
local slotitemdesc = slotitem:getDescription()
if slotitemdesc:find "%[Mana Shield" then
manashield = manashield + tonumber(string.match(slotitemdesc, '%[Mana Shield: %+(%d+)%%%]'))
end
end
end
if manashield ~= 0 then
local shieldPercent = (100 - manashield)
primaryDamage = (shieldPercent / 100) * primaryDamage
secondaryDamage = (shieldPercent / 100) * secondaryDamage
end
end
end
return primaryDamage, primaryType, secondaryDamage, secondaryType, origin
end
how you fix it?I can't seem to get onInventoryUpdate to work correctly, I have tried numerous times... and compiled my heart out...I am burned out trying
Is there another way to get items to update correctly instead of log off/log on?
< 10.94
The first post is for versions earlier than 10.94, before crit and mana/life leech was added to the game.
Someone should try it on an 8.6 server
10.94+
If you are using the latest TFS release, refer to the post here.
What is this?A newer version of this:
A variant of this, this and this mod.Rare, Epic and Legendary Loot Rolls
Hey Guys, This is something I've been working on for a while, taking the time to get it right and get all rolls and damages to apply properly. Thought I'd give you a look, see what y'all think. When a monster drops loot, there is a chance that it rolls Rare, Epic or Legendary: Basic rolls...otland.net
It gives items a chance to roll rare, epic or legendary when it drops from a monster:
With the following possible attributes:
(For config and if you want to understand the code, start at the stats table in lib/core/attributes.lua)
LUA:[1] = { -- Attack [2] = { -- Defense [3] = { -- Extra Defense [4] = { -- Armor [5] = { -- Accuracy [6] = { -- Range [7] = { -- Equipment with < 50 charges [8] = { -- Equipment with >= 50 charges [9] = { -- Time [10] = { -- Crit Chance [11] = { -- Crit Amount (Currently Unused) [12] = { -- Fire Damage [13] = { -- Ice Damage [14] = { -- Energy Damage [15] = { -- Fire Resistance [16] = { -- Ice Resistance [17] = { -- Energy Resistance [18] = { -- Earth Resistance [19] = { -- Physical Resistance [20] = { -- Death Resistance [21] = { -- Spell Damage [22] = { -- Multi Shot [23] = { -- Stun Chance [24] = { -- Mana Shield [25] = { -- Sword Skill [26] = { -- Skill Axe [27] = { -- Skill Club [28] = { -- Skill Melee [29] = { -- Skill Distance [30] = { -- Skill Shielding [31] = { -- Magic Level [32] = { -- Max Health i.e +100 [33] = { -- Max Mana i.e +100 [34] = { -- Max Health % i.e +10% [35] = { -- Max Mana % i.e +10% [36] = { -- Life Leech Chance (Currently Unused) [37] = { -- Life Leech Amount [38] = { -- Mana Leech Chance (Currently Unused) [39] = { -- Mana Leech Amount
Some of these are completely custom attributes, like elemental damage:
This requires the following updates/features:
1) Loot drop handled via Lua
2) Add the new health/mana gain coloured text messages
3) onInventoryUpdate()
4) onSpawn()Player:onInventoryUpdate(item, slot, equip) · infernumx/forgottenserver@960a3f5
A free and open-source MMORPG server emulator written in C++ - Player:onInventoryUpdate(item, slot, equip) · infernumx/forgottenserver@960a3f5github.com
Adding Monster:onSpawn(position, startup, artificial) by Leo32onGIT · Pull Request #2822 · otland/forgottenserver
This allows you to manipulate monsters as they spawn. Use example: to register onHealthChange and onManaChange events on all monsters. Thread from author @infernumx: https://otland.net/threads/tfs-...github.com
rollAttributes.zip
Installation:
paste in /data
lib/core/core.lua
add below:
LUA:-- Rolls & Custom Item Attributes dofile('data/lib/core/attributes.lua')
talkactions.xml
add below:
XML:<talkaction words="/roll" separator=" " script="roll.lua" />
creaturescripts.xml
add below:
XML:<!-- Roll & Attribute Damage --> <event type="healthchange" name="rollHealth" script="attributes.lua"/> <event type="manachange" name="rollMana" script="attributes.lua"/>
creaturescripts/scripts/login.lua
add below:
LUA:-- Activate Custom Item Attributes for i = 1,10 do -- CONST_SLOT_FIRST,CONST_SLOT_LAST local item = player:getSlotItem(i) if item then itemAttributes(player, item, i, true) end end -- If player logged with more 'current health' than their db 'max health' due to an item attribute local query = db.storeQuery("SELECT `health`,`mana` FROM players where `id`="..player:getGuid()) if query then local health = tonumber(result.getDataString(query, 'health')) local mana = tonumber(result.getDataString(query, 'mana')) local playerHealth = player:getHealth() local playerMana = player:getMana() if playerHealth < health then player:addHealth(health - playerHealth) end if playerMana < mana then player:addMana(mana - playerMana) end result.free(query) end
add below:
LUA:player:registerEvent("rollHealth") player:registerEvent("rollMana")
events/scripts/player.lua
add to the bottom:
LUA:function Player:onInventoryUpdate(item, slot, equip) itemAttributes(self, item, slot, equip) end
events/scripts/monster.lua
add to the top of the file:
add between:LUA:-- Rarity Animations local rare_popup = true local rare_effect = true local rare_effect_id = CONST_ME_STUN
add at the end:LUA:-- Apply rarity chance to corpse contents and apply animation if rollRarity(corpse) > 0 then -- If a rare item was rolled, play animation if rare_popup then local spectators = Game.getSpectators(corpse:getPosition(), false, true, 7, 7, 5, 5) for i = 1, #spectators do spectators[i]:say(rare_text, TALKTYPE_MONSTER_SAY, false, spectators[i], corpse:getPosition()) end end if rare_effect then corpse:getPosition():sendMagicEffect(rare_effect_id) end end
LUA:function Monster:onSpawn(position, startup, artificial) self:registerEvent("rollHealth") self:registerEvent("rollMana") return true end
The core scripts are attached because they are to big to embed in post, so they're attached as rollAttributes.zip
Don't forget to paste the core scripts into your /data dir.
Extras
- 'Stun Target' is disabled by default, add the condition from here and uncomment the lines in creaturescripts/scripts/attributes.lua
- primaryDamage and primaryType are swapped with secondaryDamage and secondaryType on elemental damage (better, consistent visuals)
- Use the included /roll <rarity> talkaction for testing i.e /roll legendary
- Mana Leech and Life Leech apply 5ms after damage is done, this may feel different to vanilla Tibia.
- Multi shot ignores creature armor/shielding - its quite primitive.
- If you want to re-roll an item you should item:remove() it and re-create it (so it has stock base stats).
- Custom resistances apply after natural resistances and are additive.
- A unique weapon & shield using this systems on-hit mechanics can be found in extras.xml
Overwrite their information in items.xml and uncomment their code in attributes.lua for cool points.
ive got the same problem, share how you fix thatfinally got it to work! Now it seems i got the same problem as people above also have.
Lua Script Error: [CreatureScript Interface]
data/creaturescripts/scripts/attributes.luanHealthChange
data/creaturescripts/scripts/attributes.lua:418: attempt to call global 'doTargetCombatCondition' (a nil value)
stack traceback:
[C]: in function 'doTargetCombatCondition'
data/creaturescripts/scripts/attributes.lua:418: in function 'statChange'
data/creaturescripts/scripts/attributes.lua:685: in function <data/creaturescripts/scripts/attributes.lua:682>
tfs 1.5 772 downgrade
I need help make it work with canary 13.21 @amoxicilina , br?Do you want to deploy to canary datapack? If yes, I can help you very easily.
This system works flawless ;DAfter my second try I managed to get it to work on a downgraded TFS, monsters weren't dropping loot at first, and had to double check the commits that I pushed, forgot the very first edit... it is working flawlessly now and will play around with it for sure!
Merci!
this is working on canary, you need make some changesAny hint for canary?
Which changes, could you help?this is working on canary, you need make some changes
Here are the 10.94+ files for the latest version of TFS.
It uses the native Crit and Leech system.
Here is a branch you can simply merge:
Comparison can be found here.GitHub - Leo32onGIT/forgottenserver at rarity-custom-attributes
A free and open-source MMORPG server emulator written in C++ - GitHub - Leo32onGIT/forgottenserver at rarity-custom-attributesgithub.com
Alternatively, follow the instructions below if you want to install it manually:
You need these commits/changes:
1) Leech fix (If you don't have your leech amounts will be all messed up)
2) onInventoryUpdate()Combat and boosts changes by nekiro · Pull Request #2497 · otland/forgottenserver
To apply these changes #2485 needs to be merged. What does this pr brings? completely rewritten combat.cpp, instead of bunch of functions, we are now using only two "internal" ones. one ...github.com
3) onSpawn()Player:onInventoryUpdate(item, slot, equip) · infernumx/forgottenserver@960a3f5
A free and open-source MMORPG server emulator written in C++ - Player:onInventoryUpdate(item, slot, equip) · infernumx/forgottenserver@960a3f5github.com
Adding Monster:onSpawn(position, startup, artificial) by Leo32onGIT · Pull Request #2822 · otland/forgottenserver
This allows you to manipulate monsters as they spawn. Use example: to register onHealthChange and onManaChange events on all monsters. Thread from author @infernumx: https://otland.net/threads/tfs-...github.com
local rare_popup = true
local rare_effect = true
local rare_effect_id = 56
-- local roll_drop_effect = 56
-- Custom special item drops
local jewelDrops = true
local jewelChance = 75000 -- 2%
local jewelCorpse = {
[4097] = { -- Demon
2493, -- Demon Helmet
2494, -- Demon Armor
2495, -- Demon Legs
2400, -- Magic Sword
2431, -- SCA
2421, -- Thunder Hammer
16112,-- Spellbook of Arcana
8852, -- The Devileye
8905, -- Rainbow Shield
2131 -- Star Amulet
},
[5999] = { -- Behemoth
2503, -- Dwarven Armor
2504, -- Dwarven Legs
2502 -- Dwarven Helmet
},
[6332] = { -- Hellhound
15406, -- Ornate Chest
15414, -- Ornate Mace
15412, -- Ornate Legs
15644, -- Ornate Crossbow
15407, -- Depth Lorica
8905, -- Rainbow Shield
22424, -- Master Umbral Spellbook
12644, -- Shield of Corruption
12649, -- Blade of Corruption
7390, -- Justice Seeker
7435 -- Impaler
},
[8955] = { -- Grim Reaper
9778, -- Yalahari Mask
9776, -- Yalahari Armor
7429, -- Blessed Sceptre
14327, -- Bronze Ring
12645 -- Elite Draken Helmet
},
[5984] = { -- Dragon Lord
11118, -- Dragon Scale Boots
2506, -- Dragon Scale Helmet
8886, -- Molten Plate
},
[19963] = {-- Lost Basher
2503, -- Dwarven Armor
2504, -- Dwarven Legs
2502, -- Dwarven Helmet
},
[19998] = {-- Lost Thrower
2503, -- Dwarven Armor
2504, -- Dwarven Legs
2502, -- Dwarven Helmet
},
[17408] = {-- Enslaved Dwarf
2503, -- Dwarven Armor
2504, -- Dwarven Legs
2502, -- Dwarven Helmet
},
[17416] = {-- Lost Berserker
2503, -- Dwarven Armor
2504, -- Dwarven Legs
2502, -- Dwarven Helmet
},
[6320] = { -- Destroyer
2503, -- Dwarven Armor
2504, -- Dwarven Legs
2502, -- Dwarven Helmet
7455, -- Mythril Axe
7390, -- Justice Seeker
8888 -- MAA
},
[6324] = { -- Hellfire Fighter
18409, -- Wand of Everblazing
8925, -- Solar Axe
7417, -- Runed Sword
8927, -- Dark Trinity Mace
8905, -- Rainbow Shield
12647, -- Snakegod's Wristguard
8881 -- Fireborn
},
[6336] = { -- Juggernaut
2522, -- Great Shield
21693, -- Horn
8882, -- Earthborn
8930, -- Emerald Sword
8929, -- Stomper
8932, -- The Calamity
7405, -- Havoc
2415 -- Great Axe
},
[10524] = { -- Medusa
8869, -- Greenwood Coat
2537, -- Amazon Shield
5803 -- Arbalest
},
[8951] = { -- Bog Raider
21706, -- Goo Shell
23528 -- Glooth Cape
},
[6532] = { -- Defiler
21706 -- Goo Shell
},
[6061] = { -- Serpent Spawn
12642, -- Royal Draken Mail
12643, -- Royal Scale Robe
8851 -- Royal Crossbow
},
[6012] = { -- Elf Scout
2505 -- Elven Mail
},
[6011] = { -- Elf Arcanist
2505 -- Elven Mail
},
[6028] = { -- Lich
7429, -- Blessed Sceptre
7730 -- Blue Legs
},
[15354] = { -- Kollos
8883, -- Windborn
16111, -- Thorn Spitter
15413 -- Ornate Shield
},
[15296] = { -- Spidris
11374, -- Beetle Necklace
16111 -- Thorn Spitter
},
[20455] = { -- Necromancer
6433, -- Necromancer Shield
7429 -- Blessed Sceptre
},
[9923] = { -- Hellspawn
12607, -- Elite Draken Mail
7390, -- Justice Seeker
21693, -- Horn
7433 -- Ravenwing
},
[6328] = { -- Dark Torturer
12607, -- Elite Draken Mail
12644, -- Shield of Corruption
12649, -- Blade of Corruption
8924, -- Hellforged Axe
8927, -- Dark Trinity Mace
21693, -- Horn
7453, -- Executioner
6391, -- Nightmare Shield
2415 -- Great Axe
},
[6048] = { -- Hydra
2424, -- Silver Mace
14327, -- Bronze Ring
11305, -- Drakinata
7411, -- Ornamented Axe
7384, -- Mystic Blade
2508 -- Native Armor
},
[20527] = { -- Warlock
2542, -- Tempest Shield
7410, -- Queen's Sceptre
2662 -- Magician Hat
},
[20415] = { -- Hero
8885, -- Divine Plate
11302, -- Zaoan Helmet
7384, -- Mystic Blade
2424, -- Silver Mace
14327, -- Bronze Ring
2508 -- Native Armor
}
}
[/CÓDIGO]
add below:
[CODE=lua]
local lootTable = mType:generateLootRoll({ factor = factor, gut = gut }, {})
corpse:addLoot(lootTable)
-- Apply rarity chance to corpse contents and apply animation
if rollRarity(corpse) > 0 then -- If a rare item was rolled, play animation
if rare_popup then
local spectators = Game.getSpectators(corpse:getPosition(), false, true, 7, 7, 5, 5)
for i = 1, #spectators do
spectators[i]:say(rare_text, TALKTYPE_MONSTER_SAY, false, spectators[i], corpse:getPosition())
end
end
if rare_effect then
corpse:getPosition():sendMagicEffect(rare_effect_id)
corpse:getPosition():sendMagicEffect(57)
end
if jewelCorpse[corpse:getId()] then
if math.random(50,50) == 1 then -- 1/50 = 2%
local jewelCase = corpse:addItem(6104, 1)
if jewelCase then
local jewelItem = jewelCase:addItem(jewelCorpse[corpse:getId()][math.random(1,#jewelCorpse[corpse:getId()])], 1)
if checkrollable(jewelItem) then
rollItems(jewelItem, true) -- Force roll a rarity
end
jewel = 1
end
end
end
end
function Player:onInventoryUpdate(item, slot, equip)
itemAttributes(self, item, slot, equip)
end
-- rollAtributos
dofile(CORE_DIRECTORY .. "/libs/core/attributes.lua")
-- Activate Custom Item Attributes
for i = 1,10 do -- CONST_SLOT_FIRST,CONST_SLOT_LAST
local item = player:getSlotItem(i)
if item then
itemAttributes(player, item, i, true)
end
end
-- If player logged with more 'current health' than their db 'max health' due to an item attribute
local query = db.storeQuery("SELECT `health`,`mana` FROM players where `id`="..player:getGuid())
if query then
local health = tonumber(result.getDataString(query, 'health'))
local mana = tonumber(result.getDataString(query, 'mana'))
local playerHealth = player:getHealth()
local playerMana = player:getMana()
if playerHealth < health then
player:addHealth(health - playerHealth)
end
if playerMana < mana then
player:addMana(mana - playerMana)
end
result.free(query)
end
"rollHealth",
"rollMana",