AncientAngelus
New Member
- Joined
- Dec 13, 2009
- Messages
- 25
- Reaction score
- 3
Anyone? this is for tfs 1.4
Worked for me, only advice I can give is to completely reinstall and make sure you follow step by step exactlyAnyone? this is for tfs 1.4
Lua Script Error: [CreatureScript Interface]
data/creaturescripts/scripts/attributes.lua:onHealthChange
data/lib/core/item.lua:505: attempt to compare nil with number
stack traceback:
[C]: in function '__le'
data/lib/core/item.lua:505: in function 'getDescription'
data/creaturescripts/scripts/attributes.lua:249: in function 'statChange'
data/creaturescripts/scripts/attributes.lua:533: in function <data/creaturescripts/scripts/attributes.lua:530>
Lua Script Error: [CreatureScript Interface]
data/creaturescripts/scripts/attributes.lua:onHealthChange
data/lib/core/item.lua:505: attempt to compare nil with number
stack traceback:
[C]: in function '__le'
data/lib/core/item.lua:505: in function 'getDescription'
data/creaturescripts/scripts/attributes.lua:249: in function 'statChange'
data/creaturescripts/scripts/attributes.lua:533: in function <data/creaturescripts/scripts/attributes.lua:530>
Hi, Im using nekitro 1.5 tfs tbia 7.7 downgrade and i have this kind of problem. Anyone can help?
LUA:Lua Script Error: [CreatureScript Interface] data/creaturescripts/scripts/attributes.lua:onHealthChange data/lib/core/item.lua:505: attempt to compare nil with number stack traceback: [C]: in function '__le' data/lib/core/item.lua:505: in function 'getDescription' data/creaturescripts/scripts/attributes.lua:249: in function 'statChange' data/creaturescripts/scripts/attributes.lua:533: in function <data/creaturescripts/scripts/attributes.lua:530> Lua Script Error: [CreatureScript Interface] data/creaturescripts/scripts/attributes.lua:onHealthChange data/lib/core/item.lua:505: attempt to compare nil with number stack traceback: [C]: in function '__le' data/lib/core/item.lua:505: in function 'getDescription' data/creaturescripts/scripts/attributes.lua:249: in function 'statChange' data/creaturescripts/scripts/attributes.lua:533: in function <data/creaturescripts/scripts/attributes.lua:530>
does it work for a tfs 1.2 8.0?< 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.
support canary=?
finally got it to work! Now it seems i got the same problem as people above also have.Got it to slightly work! But I now have to relog to update changes. Please help!
Using tfs 1.5 772
appreciate your comment, the sources are kind old and also modified, i hope someone is interested in adapt the current script, i only know very basics of c++ i think i could not achieve that alone u.uthis is from the onInventoryUpdate function:
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
it looks like TFS code has changed in a way that now conflicts
I'd say my code is now out-of-date and isn't just plug and play anymore, it could be used as a base but requires changes to work properly.
I don't really bother with OTs anymore so it would be up to someone else to clean up this codebase and resolve the conflicts.
sorry bruz
Its the other way around, his source code is oldI'd say my code is now out-of-date
Im using Sabrehaven 8.0 sources (based on tfs 1.2)
but im experiencing some difficulties, is it possible to adapt it?
info
is not declaredinfo.
> on the code, on here:Pretty nice system! I want to implement the roll on chests using this code: [TFS 1.3] Advanced quest chests (https://otland.net/threads/tfs-1-3-advanced-quest-chests.277772/) is is posible?
LUA:function capAll(str) return (str:gsub("(%l)(%w*)", function(a,b) return string.upper(a)..b end)) end local advanceChest = Action() function advanceChest.onUse(player, item, fromPosition, itemEx, toPosition) ----------------------------------------------------------------------------------- -- Local Variables -- ----------------------------------------------------------------------------------- local questChest = item:getUniqueId() ----------------------------------------------------------------------------------- -- Check if player has already opened box -- ----------------------------------------------------------------------------------- if player:getStorageValue(questChest) == 1 then player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The chest is empty.") toPosition:sendMagicEffect(10) return true end local storageOne = questChests[questChest].storageUnique ----------------------------------------------------------------------------------- -- Check if player has already opened box multiple chest only 1 reward -- ----------------------------------------------------------------------------------- if player:getStorageValue(storageOne) == 1 then player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The chest is empty.") toPosition:sendMagicEffect(10) return true end ----------------------------------------------------------------------------------- -- Check if player meets level requirment ----------------------------------------------------------------------------------- local playerLevel = player:getLevel() local minLevel = questChests[questChest].minLevel if questChests[questChest].minLevel => playerLevel then player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You need to be level "..minLevel.." to open this chest.") return true end ----------------------------------------------------------------------------------- -- Give rewward if player has not yet opened box -- ----------------------------------------------------------------------------------- for i = 1, #questChests[questChest].items do local rewardType = questChests[questChest].items[i].type ----------------------------------------------------------------------------------- -- Item Type Reward -- ----------------------------------------------------------------------------------- if rewardType == "item" then local item = questChests[questChest].items[i].item local count = questChests[questChest].items[i].count player:addItem(item, count) player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "You earned ["..count.."x] "..capAll(getItemName(item))) end ----------------------------------------------------------------------------------- -- Experience Type Reward -- ----------------------------------------------------------------------------------- if rewardType == "experience" then local amount = questChests[questChest].items[i].amount player:addExperience(amount) player:say(amount.." EXP gained!", TALKTYPE_MONSTER_SAY) player:getPosition():sendMagicEffect(CONST_ME_STUN) player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "You gained "..amount.." experience points.") end ----------------------------------------------------------------------------------- -- Outfit Type Reward -- ----------------------------------------------------------------------------------- if rewardType == "outfit" then local outfitName = questChests[questChest].items[i].name local maleOutfit = questChests[questChest].items[i].maleId local femaleOutfit = questChests[questChest].items[i].femaleId if player:getSex() == 0 then player:addOutfit(femaleOutfit) else player:addOutfit(maleOutfit) end player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "You gained the "..outfitName.." outfit.") end ----------------------------------------------------------------------------------- -- Addon Type Reward -- ----------------------------------------------------------------------------------- if rewardType == "addon" then local outfitName = questChests[questChest].items[i].outfit local addon = questChests[questChest].items[i].addonNumber local maleAddon = questChests[questChest].items[i].maleId local femaleAddon = questChests[questChest].items[i].femaleId if player:getSex() == 0 then player:addOutfitAddon(femaleAddon, addon) else player:addOutfitAddon(maleAddon, addon) end if addon == 1 then player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "You gained the first "..outfitName.." outfit addon.") elseif addon == 2 then player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "You gained the second "..outfitName.." outfit addon.") elseif addon == 3 then player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "You gained the third "..outfitName.." outfit addon.") end end ----------------------------------------------------------------------------------- -- Mount Type Reward -- ----------------------------------------------------------------------------------- if rewardType == "mount" then local mountName = questChests[questChest].items[i].mountName local mountId = questChests[questChest].items[i].mountId player:addMount(mountId) player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "You have unlocked the "..mountName.." mount.") end ----------------------------------------------------------------------------------- -- Add in any cooldowns/storages -- ----------------------------------------------------------------------------------- player:setStorageValue(questChest, 1) player:setStorageValue(storageOne, 1) return true end end for i = 2000, 2100 do advanceChest:uid(i) end advanceChest:register()
Thanks in advance!
local containerID = ChestUid.containerID
local bag = nil
local text = nil
local textTwo = ""
local addItem = 0
-----------------------------------------------------------------------------------
for index, details in pairs(ChestUid.items) do
local itemCheck = ItemType(details.item)
local rollText = ""
-----------------------------------------------------------------------------------
-- Item Type Reward --
-----------------------------------------------------------------------------------
if details.type == "item" then
-- Add items inside a container if container == 1
if details.container == 1 then
if not bag then
bag = player:addItem(containerID, 1)
end
addItem = bag:addItem(details.item,details.count)
else
addItem = player:addItem(details.item, details.count)
end
-- Add key with Action ID if Key and actionId is defined in table "Key = true/false, actionID = "
if details.key == true then
addItem:setActionId(details.actionID)
end
if addItem ~= nil and not itemCheck:isStackable() then
if details.item then
local randomRoll = math.random(0,100)
if randomRoll <= INSERT CHANCE then
randomRoll = "rare"
elseif randomRoll <= INSERT CHANCE then
randomRoll = "epic"
elseif randomRoll <= INSERT CHANCE then
randomRoll = "legendary"
else
randomRoll = ""
end
rollRarity(addItem,randomRoll)
rollText = ""..addItem:getArticle().." "
end
end
if details.count > 1 then
text = ""..details.count.." "
textTwo = "s"
else
text = ""
textTwo = ""
end
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "You found "..text..""..rollText..""..getItemName(details.item)..""..textTwo..".")