diff --git a/.editorconfig b/.editorconfig index 5516cd9..c81366c 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,4 +8,6 @@ insert_final_newline = true trim_trailing_whitespace = true [*.{lua,xml}] -indent_size = 4 +tab_width = 4 +indent_size = tab +indent_style = tab diff --git a/.lua-format b/.lua-format index 9d58ad1..5c7cb67 100644 --- a/.lua-format +++ b/.lua-format @@ -1,4 +1,6 @@ indent_width: 1 continuation_indent_width: 1 use_tab: true -tab_width: 4 \ No newline at end of file +tab_width: 4 +chop_down_table: true +column_limit: 130 \ No newline at end of file diff --git a/data/lib/compat/compat.lua b/data/lib/compat/compat.lua index 6ab8aba..1e3fc71 100644 --- a/data/lib/compat/compat.lua +++ b/data/lib/compat/compat.lua @@ -38,26 +38,19 @@ NORTHWEST = DIRECTION_NORTHWEST NORTHEAST = DIRECTION_NORTHEAST do + local dummyStrTbl = {} + local dummyStrMetaTbl = {} + local function storageProxy(player) - return setmetatable({}, { - __index = function(_, key) - return player:getStorageValue(PlayerStorageKeys[key] or key) - end, - __newindex = function(_, key, value) - player:setStorageValue(PlayerStorageKeys[key] or key, value) - end - }) + dummyStrMetaTbl.__index = function(_, key) return player:getStorageValue(PlayerStorageKeys[key] or key) end + dummyStrMetaTbl.__newindex = function(_, key, value) player:setStorageValue(PlayerStorageKeys[key] or key, value) end + return setmetatable(dummyStrTbl, dummyStrMetaTbl) end local function accountStorageProxy(player) - return setmetatable({}, { - __index = function(_, key) - return Game.getAccountStorageValue(player:getAccountId(), key) - end, - __newindex = function(_, key, value) - Game.setAccountStorageValue(player:getAccountId(), key, value) - end - }) + dummyStrMetaTbl.__index = function(_, key) return Game.getAccountStorageValue(player:getAccountId(), key) end + dummyStrMetaTbl.__newindex = function(_, key, value) Game.setAccountStorageValue(player:getAccountId(), key, value) end + return setmetatable(dummyStrTbl, dummyStrMetaTbl) end local function CreatureIndex(self, key) @@ -79,13 +72,9 @@ do elseif key == "actionid" then return 0 elseif key == "storage" then - if methods.isPlayer(self) then - return storageProxy(self) - end + if methods.isPlayer(self) then return storageProxy(self) end elseif key == "accountStorage" then - if methods.isPlayer(self) then - return accountStorageProxy(self) - end + if methods.isPlayer(self) then return accountStorageProxy(self) end end return methods[key] @@ -345,13 +334,10 @@ end function doTargetCombatHealth(...) return doTargetCombat(...) end function doAreaCombatHealth(...) return doAreaCombat(...) end doCombatAreaHealth = doAreaCombatHealth -function doTargetCombatMana(cid, target, min, max, effect) - return doTargetCombat(cid, target, COMBAT_MANADRAIN, min, max, effect) -end +function doTargetCombatMana(cid, target, min, max, effect) return doTargetCombat(cid, target, COMBAT_MANADRAIN, min, max, effect) end doCombatAreaMana = doTargetCombatMana -function doAreaCombatMana(cid, pos, area, min, max, effect) - return doAreaCombat(cid, COMBAT_MANADRAIN, pos, area, min, max, effect) -end +function doAreaCombatMana(cid, pos, area, min, max, effect) return + doAreaCombat(cid, COMBAT_MANADRAIN, pos, area, min, max, effect) end createConditionObject = Condition setConditionParam = Condition.setParameter @@ -521,8 +507,9 @@ function doAddCondition(cid, conditionId) end function doRemoveCondition(cid, conditionType, subId) local c = Creature(cid) - return c and (c:removeCondition(conditionType, CONDITIONID_COMBAT, subId) or - c:removeCondition(conditionType, CONDITIONID_DEFAULT, subId) or true) + return c and + (c:removeCondition(conditionType, CONDITIONID_COMBAT, subId) or + c:removeCondition(conditionType, CONDITIONID_DEFAULT, subId) or true) end function getCreatureCondition(cid, type, subId) local c = Creature(cid) @@ -809,26 +796,20 @@ function getPlayersByIPAddress(ip, mask) if mask == nil then mask = 0xFFFFFFFF end local masked = ip & mask local result = {} - for _, player in ipairs(Game.getPlayers()) do - if player:getIp() & mask == masked then result[#result + 1] = player:getId() end - end + for _, player in ipairs(Game.getPlayers()) do if player:getIp() & mask == masked then result[#result + 1] = player:getId() end end return result end getPlayersByIp = getPlayersByIPAddress function getOnlinePlayers() local result = {} - for _, player in ipairs(Game.getPlayers()) do - result[#result + 1] = player:getName() - end + for _, player in ipairs(Game.getPlayers()) do result[#result + 1] = player:getName() end return result end getPlayersOnline = getOnlinePlayers function getPlayersByAccountNumber(accountNumber) local result = {} for _, player in ipairs(Game.getPlayers()) do - if player:getAccountId() == accountNumber then - result[#result + 1] = player:getId() - end + if player:getAccountId() == accountNumber then result[#result + 1] = player:getId() end end return result end @@ -836,8 +817,7 @@ function getPlayerGUIDByName(name) local player = Player(name) if player then return player:getGuid() end - local resultId = db.storeQuery("SELECT `id` FROM `players` WHERE `name` = " .. - db.escapeString(name)) + local resultId = db.storeQuery("SELECT `id` FROM `players` WHERE `name` = " .. db.escapeString(name)) if resultId ~= false then local guid = result.getNumber(resultId, "id") result.free(resultId) @@ -849,9 +829,7 @@ function getAccountNumberByPlayerName(name) local player = Player(name) if player then return player:getAccountId() end - local resultId = db.storeQuery( - "SELECT `account_id` FROM `players` WHERE `name` = " .. - db.escapeString(name)) + local resultId = db.storeQuery("SELECT `account_id` FROM `players` WHERE `name` = " .. db.escapeString(name)) if resultId ~= false then local accountId = result.getNumber(resultId, "account_id") result.free(resultId) @@ -873,8 +851,7 @@ function doPlayerSetNameDescription() end function doPlayerSendChannelMessage(cid, author, message, SpeakClasses, channel) local p = Player(cid) - return p and p:sendChannelMessage(author, message, SpeakClasses, channel) or - false + return p and p:sendChannelMessage(author, message, SpeakClasses, channel) or false end function doPlayerSetMaxCapacity(cid, cap) local p = Player(cid) @@ -1091,9 +1068,7 @@ function doPlayerJoinParty(cid, leaderId) local party = leader:getParty() if party == nil or party:getLeader() ~= leader then return true end - for _, invitee in ipairs(party:getInvitees()) do - if player ~= invitee then return true end - end + for _, invitee in ipairs(party:getInvitees()) do if player ~= invitee then return true end end party:addMember(player) return true @@ -1106,9 +1081,7 @@ function getPartyMembers(cid) if party == nil then return false end local result = {party:getLeader():getId()} - for _, member in ipairs(party:getMembers()) do - result[#result + 1] = member:getId() - end + for _, member in ipairs(party:getMembers()) do result[#result + 1] = member:getId() end return result end @@ -1132,9 +1105,7 @@ function getMonsterFriendList(cid) local result = {} for _, creature in ipairs(monster:getFriendList()) do - if not creature:isRemoved() and creature:getPosition().z == z then - result[#result + 1] = creature:getId() - end + if not creature:isRemoved() and creature:getPosition().z == z then result[#result + 1] = creature:getId() end end return result end @@ -1246,15 +1217,11 @@ function doAddContainerItemEx(uid, virtualId) return res end -function doSendMagicEffect(pos, magicEffect, ...) - return Position(pos):sendMagicEffect(magicEffect, ...) -end +function doSendMagicEffect(pos, magicEffect, ...) return Position(pos):sendMagicEffect(magicEffect, ...) end function doSendDistanceShoot(fromPos, toPos, distanceEffect, ...) return Position(fromPos):sendDistanceEffect(toPos, distanceEffect, ...) end -function isSightClear(fromPos, toPos, floorCheck) - return Position(fromPos):isSightClear(toPos, floorCheck) -end +function isSightClear(fromPos, toPos, floorCheck) return Position(fromPos):isSightClear(toPos, floorCheck) end function getPromotedVocation(vocationId) local vocation = Vocation(vocationId) @@ -1267,8 +1234,7 @@ end getPlayerPromotionLevel = getPromotedVocation function getGuildId(guildName) - local resultId = db.storeQuery("SELECT `id` FROM `guilds` WHERE `name` = " .. - db.escapeString(guildName)) + local resultId = db.storeQuery("SELECT `id` FROM `guilds` WHERE `name` = " .. db.escapeString(guildName)) if resultId == false then return false end local guildId = result.getNumber(resultId, "id") @@ -1335,9 +1301,7 @@ function getItemWeightByUID(uid, ...) if item == nil then return false end local itemType = ItemType(item:getId()) - return itemType:isStackable() and - (itemType:getWeight(item:getCount(), ...) / 100) or - (itemType:getWeight(1, ...) / 100) + return itemType:isStackable() and (itemType:getWeight(item:getCount(), ...) / 100) or (itemType:getWeight(1, ...) / 100) end function getItemRWInfo(uid) local item = Item(uid) @@ -1412,9 +1376,7 @@ function setHouseAccessList(id, listId, listText) end function getHouseByPlayerGUID(playerGUID) - for _, house in ipairs(Game.getHouses()) do - if house:getOwnerGuid() == playerGUID then return house:getId() end - end + for _, house in ipairs(Game.getHouses()) do if house:getOwnerGuid() == playerGUID then return house:getId() end end return nil end @@ -1578,9 +1540,7 @@ function doRelocate(fromPos, toPos) return true end -function getThing(uid) - return uid >= 0x10000000 and pushThing(Creature(uid)) or pushThing(Item(uid)) -end +function getThing(uid) return uid >= 0x10000000 and pushThing(Creature(uid)) or pushThing(Item(uid)) end function getConfigInfo(info) if type(info) ~= "string" then return nil end @@ -1643,8 +1603,7 @@ function doCreateTeleport(itemId, destination, position) end function getSpectators(centerPos, rangex, rangey, multifloor, onlyPlayers) - local result = Game.getSpectators(centerPos, multifloor, onlyPlayers or false, - rangex, rangex, rangey, rangey) + local result = Game.getSpectators(centerPos, multifloor, onlyPlayers or false, rangex, rangex, rangey, rangey) if #result == 0 then return nil end for index, spectator in ipairs(result) do result[index] = spectator:getId() end @@ -1658,9 +1617,7 @@ end doBroadcastMessage = broadcastMessage function Guild.addMember(self, player) return player:setGuild(self) end -function Guild.removeMember(self, player) - return player:getGuild() == self and player:setGuild(nil) -end +function Guild.removeMember(self, player) return player:getGuild() == self and player:setGuild(nil) end function getPlayerInstantSpellCount(cid) local p = Player(cid) @@ -1728,31 +1685,32 @@ function doMoveCreature(cid, direction) return c ~= nil and c:move(direction) end -function createFunctions(class) +do local exclude = {[2] = {"is"}, [3] = {"get", "set", "add", "can"}, [4] = {"need"}} - local temp = {} - for name, func in pairs(class) do - local add = true - for strLen, strTable in pairs(exclude) do - if table.contains(strTable, name:sub(1, strLen)) then - add = false + + local function isExclude(name) + for strLen, strTable in pairs(exclude) do if table.contains(strTable, name:sub(1, strLen)) then return true end end + return false + end + + function createFunctions(class) + local temp = {} + for name, func in pairs(class) do + if not isExclude(name) then + local titleCase = name:sub(1, 1):upper() .. name:sub(2) + local getFunc = function(self) return func(self) end + local setFunc = function(self, ...) return func(self, ...) end + local get = "get" .. titleCase + local set = "set" .. titleCase + if not (rawget(class, get) and rawget(class, set)) then table.insert(temp, {set, setFunc, get, getFunc}) end end end - if add then - local str = name:sub(1, 1):upper() .. name:sub(2) - local getFunc = function(self) return func(self) end - local setFunc = function(self, ...) return func(self, ...) end - local get = "get" .. str - local set = "set" .. str - if not (rawget(class, get) and rawget(class, set)) then - table.insert(temp, {set, setFunc, get, getFunc}) - end + + for _, func in ipairs(temp) do + rawset(class, func[1], func[2]) + rawset(class, func[3], func[4]) end end - for _, func in ipairs(temp) do - rawset(class, func[1], func[2]) - rawset(class, func[3], func[4]) - end end function isNumber(str) return tonumber(str) ~= nil end @@ -1816,9 +1774,7 @@ do [SPECIALSKILL_MANALEECHAMOUNT] = "mana leech amount" } - function getSpecialSkillName(specialSkill) - return specialSkills[specialSkill] or "unknown" - end + function getSpecialSkillName(specialSkill) return specialSkills[specialSkill] or "unknown" end end do @@ -1846,3 +1802,16 @@ function table.maxn(t) for k in pairs(t) do if type(k) == "number" and k > max then max = k end end return max end + +-- bit lib + +bit = { + band = function(a, b) return a & b end, + bor = function(a, b) return a | b end, + bxor = function(a, b) return a ~ b end, + bnot = function(a) return ~a end, + lshift = function(a, b) return a << b end, + rshift = function(a, b) return a >> b end +} + +ItemType.getDuration = ItemType.getDurationMin diff --git a/data/lib/core/container.lua b/data/lib/core/container.lua index e65175c..d1e02dd 100644 --- a/data/lib/core/container.lua +++ b/data/lib/core/container.lua @@ -24,15 +24,16 @@ function Container.createLootItem(self, item) local tmpItem = Game.createItem(item.itemId, subType) if not tmpItem then return false end - if tmpItem:isContainer() then + local tmpContainer = tmpItem:getContainer() + if tmpContainer then for i = 1, #item.childLoot do - if not tmpItem:createLootItem(item.childLoot[i]) then - tmpItem:remove() + if not tmpContainer:createLootItem(item.childLoot[i]) then + tmpContainer:remove() return false end end - if #item.childLoot > 0 and tmpItem:getSize() == 0 then + if #item.childLoot > 0 and tmpContainer:getSize() == 0 then tmpItem:remove() return true end diff --git a/data/lib/core/creature.lua b/data/lib/core/creature.lua index 45716d0..7b4a7bc 100644 --- a/data/lib/core/creature.lua +++ b/data/lib/core/creature.lua @@ -1,5 +1,4 @@ -function Creature.getClosestFreePosition(self, position, maxRadius, - mustBeReachable) +function Creature.getClosestFreePosition(self, position, maxRadius, mustBeReachable) maxRadius = maxRadius or 1 -- backward compatability (extended) @@ -18,24 +17,27 @@ function Creature.getClosestFreePosition(self, position, maxRadius, end local tile = Tile(checkPosition) - if tile and tile:getCreatureCount() == 0 and - not tile:hasProperty(CONST_PROP_IMMOVABLEBLOCKSOLID) and - (not mustBeReachable or self:getPathTo(checkPosition)) then - return checkPosition - end + if tile and tile:getCreatureCount() == 0 and not tile:hasProperty(CONST_PROP_IMMOVABLEBLOCKSOLID) and + (not mustBeReachable or self:getPathTo(checkPosition)) then return checkPosition end end end return Position() end +function Creature.getCreature(self) return self:isCreature() and self or nil end + function Creature.getPlayer(self) return self:isPlayer() and self or nil end function Creature.isContainer(self) return false end function Creature.isItem(self) return false end +function Creature.getItem(self) return nil end + function Creature.isMonster(self) return false end +function Creature.getMonster(self) return self:isMonster() and self or nil end + function Creature.isNpc(self) return false end function Creature.isPlayer(self) return false end @@ -48,10 +50,8 @@ function Creature:setMonsterOutfit(monster, time) local monsterType = MonsterType(monster) if not monsterType then return false end - if self:isPlayer() and - not (self:hasFlag(PlayerFlag_CanIllusionAll) or monsterType:isIllusionable()) then - return false - end + local player = self:getPlayer() + if player and not (player:hasFlag(PlayerFlag_CanIllusionAll) or monsterType:isIllusionable()) then return false end local condition = Condition(CONDITION_OUTFIT) condition:setOutfit(monsterType:getOutfit()) @@ -105,18 +105,17 @@ function Creature:addDamageCondition(target, type, list, damage, period, rounds) local condition = Condition(type) condition:setParameter(CONDITION_PARAM_OWNER, self:getId()) - condition:setParameter(CONDITION_PARAM_DELAYED, true) + condition:setParameter(CONDITION_PARAM_DELAYED, 1) if list == DAMAGELIST_EXPONENTIAL_DAMAGE then local exponent, value = -10, 0 while value < damage do - value = math.floor(10 * math.pow(1.2, exponent) + 0.5) + value = math.floor(10 * (-1.2 ^ exponent) + 0.5) condition:addDamage(1, period or 4000, -value) if value >= damage then local permille = math.random(10, 1200) / 1000 - condition:addDamage(1, period or 4000, - -math.max(1, math.floor(value * permille + 0.5))) + condition:addDamage(1, period or 4000, -math.max(1, math.floor(value * permille + 0.5))) else exponent = exponent + 1 end @@ -124,16 +123,14 @@ function Creature:addDamageCondition(target, type, list, damage, period, rounds) elseif list == DAMAGELIST_LOGARITHMIC_DAMAGE then local n, value = 0, damage while value > 0 do - value = math.floor(damage * math.pow(2.718281828459, -0.05 * n) + 0.5) + value = math.floor(damage * (2.718281828459 ^ -0.05 * n) + 0.5) if value ~= 0 then condition:addDamage(1, period or 4000, -value) n = n + 1 end end elseif list == DAMAGELIST_VARYING_PERIOD then - for _ = 1, rounds do - condition:addDamage(1, math.random(period[1], period[2]) * 1000, -damage) - end + for _ = 1, rounds do condition:addDamage(1, math.random(period[1], period[2]) * 1000, -damage) end elseif list == DAMAGELIST_CONSTANT_PERIOD then condition:addDamage(rounds, period * 1000, -damage) end @@ -143,8 +140,9 @@ function Creature:addDamageCondition(target, type, list, damage, period, rounds) end function Creature:canAccessPz() - if self:isMonster() or (self:isPlayer() and self:isPzLocked()) then - return false - end - return true + if self:isMonster() then return false end + local player = self:getPlayer() + return player and not player:isPzLocked() end + +function Creature:removeStorageValue(key) return self:setStorageValue(key, nil) end diff --git a/data/lib/core/game.lua b/data/lib/core/game.lua index bad551e..e8f8381 100644 --- a/data/lib/core/game.lua +++ b/data/lib/core/game.lua @@ -49,7 +49,7 @@ end if not globalStorageTable then globalStorageTable = {} end -function Game.getStorageValue(key) return globalStorageTable[key] end +function Game.getStorageValue(key) return globalStorageTable[key] or -1 end function Game.setStorageValue(key, value) globalStorageTable[key] = value end diff --git a/data/lib/core/item.lua b/data/lib/core/item.lua index 5fa9676..8b94a3d 100644 --- a/data/lib/core/item.lua +++ b/data/lib/core/item.lua @@ -1,59 +1,114 @@ -function Item.getType(self) return ItemType(self:getId()) end +function Item:getType() return ItemType(self:getId()) end -function Item.isContainer(self) return false end +function Item:getContainer() return Container(self:getUniqueId()) end -function Item.isCreature(self) return false end +function Item:isContainer() return false end -function Item.isMonster(self) return false end +function Item:isCreature() return false end -function Item.isNpc(self) return false end +function Item:getCreature() return nil end -function Item.isPlayer(self) return false end +function Item:isMonster() return false end -function Item.isTeleport(self) return false end +function Item:isNpc() return false end -function Item.isPodium(self) return false end +function Item:isPlayer() return false end -function Item.isTile(self) return false end +function Item:isTeleport() return false end + +function Item:isPodium() return false end + +function Item:isTile() return false end function Item:isItemType() return false end -do - local aux = { - ["Defense"] = {key = ITEM_ATTRIBUTE_DEFENSE}, - ["ExtraDefense"] = {key = ITEM_ATTRIBUTE_EXTRADEFENSE}, - ["Attack"] = {key = ITEM_ATTRIBUTE_ATTACK}, - ["AttackSpeed"] = {key = ITEM_ATTRIBUTE_ATTACK_SPEED}, - ["HitChance"] = {key = ITEM_ATTRIBUTE_HITCHANCE}, - ["ShootRange"] = {key = ITEM_ATTRIBUTE_SHOOTRANGE}, - ["Armor"] = {key = ITEM_ATTRIBUTE_ARMOR}, - ["Duration"] = { - key = ITEM_ATTRIBUTE_DURATION, - cmp = function(v) return v > 0 end - }, - ["Text"] = {key = ITEM_ATTRIBUTE_TEXT, cmp = function(v) return v ~= "" end}, - ["Date"] = {key = ITEM_ATTRIBUTE_DATE}, - ["Writer"] = { - key = ITEM_ATTRIBUTE_WRITER, - cmp = function(v) return v ~= "" end - } - } +function Item:getItem() return self end - function setAuxFunctions() - for name, def in pairs(aux) do - Item["get" .. name] = function(self) - local attr = self:getAttribute(def.key) - if def.cmp and def.cmp(attr) then - return attr - elseif not def.cmp and attr and attr ~= 0 then - return attr - end - local default = ItemType["get" .. name] - return default and default(self:getType()) or nil - end - end +function Item:getAttack() + if self:hasAttribute(ITEM_ATTRIBUTE_ATTACK) then return self:getAttribute(ITEM_ATTRIBUTE_ATTACK) --[[@as integer]] end + return self:getType():getAttack() +end + +function Item:getDefense() + if self:hasAttribute(ITEM_ATTRIBUTE_DEFENSE) then return self:getAttribute(ITEM_ATTRIBUTE_DEFENSE) --[[@as integer]] end + return self:getType():getDefense() +end + +function Item:getExtraDefense() + if self:hasAttribute(ITEM_ATTRIBUTE_EXTRADEFENSE) then return self:getAttribute(ITEM_ATTRIBUTE_EXTRADEFENSE) --[[@as integer]] end + return self:getType():getExtraDefense() +end + +function Item:getArmor() + if self:hasAttribute(ITEM_ATTRIBUTE_ARMOR) then return self:getAttribute(ITEM_ATTRIBUTE_ARMOR) --[[@as integer]] end + return self:getType():getArmor() +end + +function Item:getAttackSpeed() + if self:hasAttribute(ITEM_ATTRIBUTE_ATTACK_SPEED) then return self:getAttribute(ITEM_ATTRIBUTE_ATTACK_SPEED) --[[@as integer]] end + return self:getType():getAttackSpeed() +end + +function Item:getHitChance() + if self:hasAttribute(ITEM_ATTRIBUTE_HITCHANCE) then return self:getAttribute(ITEM_ATTRIBUTE_HITCHANCE) --[[@as integer]] end + return self:getType():getHitChance() +end + +function Item:getShootRange() + if self:hasAttribute(ITEM_ATTRIBUTE_SHOOTRANGE) then return self:getAttribute(ITEM_ATTRIBUTE_SHOOTRANGE) --[[@as integer]] end + return self:getType():getShootRange() +end + +function Item:getDuration() + if self:hasAttribute(ITEM_ATTRIBUTE_DURATION) then return self:getAttribute(ITEM_ATTRIBUTE_DURATION) --[[@as integer]] end + return self:getType():getDuration() +end + +function Item:getText() + if self:hasAttribute(ITEM_ATTRIBUTE_TEXT) then return self:getAttribute(ITEM_ATTRIBUTE_TEXT) --[[@as string]] end + return "" +end + +function Item:getDate() + if self:hasAttribute(ITEM_ATTRIBUTE_DATE) then return self:getAttribute(ITEM_ATTRIBUTE_DATE) --[[@as string]] end + return "" +end + +function Item:getWriter() + if self:hasAttribute(ITEM_ATTRIBUTE_WRITER) then return self:getAttribute(ITEM_ATTRIBUTE_WRITER) --[[@as string]] end + return "" +end + +function Item:setDuration(duration) + if duration > 0 then + return self:setAttribute(ITEM_ATTRIBUTE_DURATION, duration) + else + return self:removeAttribute(ITEM_ATTRIBUTE_DURATION) + end +end + +function Item:setText(text) + if text ~= "" then + return self:setAttribute(ITEM_ATTRIBUTE_TEXT, text) + else + return self:removeAttribute(ITEM_ATTRIBUTE_TEXT) + end +end + +function Item:setDate(date) + if date ~= 0 then + return self:setAttribute(ITEM_ATTRIBUTE_DATE, date) + else + return self:removeAttribute(ITEM_ATTRIBUTE_DATE) + end +end + +function Item:setWriter(writer) + if writer ~= "" then + return self:setAttribute(ITEM_ATTRIBUTE_WRITER, writer) + else + return self:removeAttribute(ITEM_ATTRIBUTE_WRITER) end - setAuxFunctions() end do @@ -76,9 +131,7 @@ do if it:hasShowCount() then ss:append("%d ", subType) end ss:append("%s", obj:getPluralName()) else - if addArticle and obj:getArticle() ~= "" then - ss:append("%s ", obj:getArticle()) - end + if addArticle and obj:getArticle() ~= "" then ss:append("%s ", obj:getArticle()) end ss:append("%s", obj:getName()) end else @@ -88,27 +141,19 @@ do end function Item:getNameDescription(subType, addArticle) - return internalItemGetNameDescription(self:getType(), self, subType, - addArticle) + return internalItemGetNameDescription(self:getType(), self, subType, addArticle) end - function ItemType:getNameDescription(subType, addArticle) - return internalItemGetNameDescription(self, nil, subType, addArticle) - end + function ItemType:getNameDescription(subType, addArticle) return internalItemGetNameDescription(self, nil, subType, addArticle) end end do -- Lua item descriptions created by Zbizu - local housePriceVisible = configManager.getBoolean( - configKeys.HOUSE_DOOR_SHOW_PRICE) + local housePriceVisible = configManager.getBoolean(configKeys.HOUSE_DOOR_SHOW_PRICE) local pricePerSQM = configManager.getNumber(configKeys.HOUSE_PRICE) - local showAtkWeaponTypes = { - WEAPON_CLUB, WEAPON_SWORD, WEAPON_AXE, WEAPON_DISTANCE - } - local showDefWeaponTypes = { - WEAPON_CLUB, WEAPON_SWORD, WEAPON_AXE, WEAPON_DISTANCE, WEAPON_SHIELD - } + local showAtkWeaponTypes = {WEAPON_CLUB, WEAPON_SWORD, WEAPON_AXE, WEAPON_DISTANCE} + local showDefWeaponTypes = {WEAPON_CLUB, WEAPON_SWORD, WEAPON_AXE, WEAPON_DISTANCE, WEAPON_SHIELD} local suppressedConditionNames = { -- NOTE: these names are made up just to match dwarven ring attribute style [CONDITION_POISON] = "antidote", @@ -125,8 +170,7 @@ do } -- first argument: Item, itemType or item id - local function internalItemGetDescription(item, lookDistance, subType, - addArticle) + local function internalItemGetDescription(item, lookDistance, subType, addArticle) -- optional, but true by default if addArticle == nil then addArticle = true end @@ -173,9 +217,7 @@ do -- spell words do local spellName = itemType:getRuneSpellName() - if spellName then - descriptions[#descriptions + 1] = string.format('"%s"', spellName) - end + if spellName then descriptions[#descriptions + 1] = string.format('"%s"', spellName) end end -- container capacity @@ -183,10 +225,7 @@ do -- show container capacity only on non-quest containers if not isUnique then local isContainer = itemType:isContainer() - if isContainer then - descriptions[#descriptions + 1] = string.format("Vol:%d", - itemType:getCapacity()) - end + if isContainer then descriptions[#descriptions + 1] = string.format("Vol:%d", itemType:getCapacity()) end end end @@ -195,11 +234,7 @@ do if not isVirtual then actionId = item:getActionId() end -- key - do - if not isVirtual and itemType:isKey() then - descriptions[#descriptions + 1] = string.format("Key:%0.4d", actionId) - end - end + do if not isVirtual and itemType:isKey() then descriptions[#descriptions + 1] = string.format("Key:%0.4d", actionId) end end -- weapon type (will be reused) local weaponType = itemType:getWeaponType() @@ -211,17 +246,12 @@ do -- bows and crossbows -- range, attack, hit% if itemType:isBow() then - descriptions[#descriptions + 1] = string.format("Range:%d", - item:getShootRange()) + descriptions[#descriptions + 1] = string.format("Range:%d", item:getShootRange()) - if attack ~= 0 then - descriptions[#descriptions + 1] = string.format("Atk+%d", attack) - end + if attack ~= 0 then descriptions[#descriptions + 1] = string.format("Atk+%d", attack) end local hitPercent = item:getHitChance() - if hitPercent ~= 0 then - descriptions[#descriptions + 1] = string.format("Hit%%+%d", hitPercent) - end + if hitPercent ~= 0 then descriptions[#descriptions + 1] = string.format("Hit%%+%d", hitPercent) end -- melee weapons and missiles -- atk x physical +y% element @@ -229,8 +259,7 @@ do local atkString = string.format("Atk:%d", attack) local elementDmg = itemType:getElementDamage() if elementDmg ~= 0 then - atkString = string.format("%s physical %+d %s", atkString, elementDmg, - getCombatName(itemType:getElementType())) + atkString = string.format("%s physical %+d %s", atkString, elementDmg, getCombatName(itemType:getElementType())) end descriptions[#descriptions + 1] = atkString @@ -240,10 +269,7 @@ do -- attack speed do local atkSpeed = item:getAttackSpeed() - if atkSpeed ~= 0 then - descriptions[#descriptions + 1] = string.format("AS:%0.2f/turn", - 2000 / atkSpeed) - end + if atkSpeed ~= 0 then descriptions[#descriptions + 1] = string.format("AS:%0.2f/turn", 2000 / atkSpeed) end end -- defense attributes @@ -251,34 +277,30 @@ do local showDef = table.contains(showDefWeaponTypes, weaponType) local ammoType = itemType:getAmmoType() if showDef then - local defense = item:getDefense() local defAttrs = {} - if weaponType == WEAPON_DISTANCE then - -- throwables - if ammoType ~= AMMO_ARROW and ammoType ~= AMMO_BOLT then + + local defense = item:getDefense() + if defense ~= 0 then + if weaponType == WEAPON_DISTANCE then + -- throwables + if ammoType ~= AMMO_ARROW and ammoType ~= AMMO_BOLT then defAttrs[#defAttrs + 1] = defense end + else defAttrs[#defAttrs + 1] = defense end - else - defAttrs[#defAttrs + 1] = defense end -- extra def local xD = item:getExtraDefense() if xD ~= 0 then defAttrs[#defAttrs + 1] = string.format("%+d", xD) end - if #defAttrs > 0 then - descriptions[#descriptions + 1] = string.format("Def:%s", table.concat( - defAttrs, " ")) - end + if #defAttrs > 0 then descriptions[#descriptions + 1] = string.format("Def:%s", table.concat(defAttrs, " ")) end end end -- armor do local arm = item:getArmor() - if arm > 0 then - descriptions[#descriptions + 1] = string.format("Arm:%d", arm) - end + if arm > 0 then descriptions[#descriptions + 1] = string.format("Arm:%d", arm) end end -- abilities (will be reused) @@ -294,27 +316,21 @@ do end -- percent buffs - for stat, value in pairs(abilities.statsPercent) do - if value ~= 0 then stats[stat].percent = value end - end + for stat, value in pairs(abilities.statsPercent) do if value ~= 0 then stats[stat].percent = value end end -- display the buffs for _, statData in pairs(stats) do local displayValues = {} if statData.flat then displayValues[#displayValues + 1] = statData.flat end - if statData.percent then - displayValues[#displayValues + 1] = statData.percent - end + if statData.percent then displayValues[#displayValues + 1] = statData.percent end -- desired format examples: -- +5% -- +20 and 5% if #displayValues > 0 then displayValues[1] = string.format("%+d", displayValues[1]) - descriptions[#descriptions + 1] = string.format("%s %s", statData.name, - table.concat(displayValues, - " and ")) + descriptions[#descriptions + 1] = string.format("%s %s", statData.name, table.concat(displayValues, " and ")) end end end @@ -322,11 +338,7 @@ do -- skill boosts do for skill, value in pairs(abilities.skills) do - if value ~= 0 then - descriptions[#descriptions + 1] = string.format("%s %+d", - getSkillName(skill - 1), - value) - end + if value ~= 0 then descriptions[#descriptions + 1] = string.format("%s %+d", getSkillName(skill - 1), value) end end end @@ -343,9 +355,7 @@ do value = string.format("%0.2f", value / 100) end - descriptions[#descriptions + 1] = string.format("%s %s%%", - getSpecialSkillName( - skill - 1), value) + descriptions[#descriptions + 1] = string.format("%s %s%%", getSpecialSkillName(skill - 1), value) end end end @@ -354,17 +364,10 @@ do do local protections = {} for element, value in pairs(abilities.absorbPercent) do - if value ~= 0 then - protections[#protections + 1] = string.format("%s %+d%%", getCombatName( - 2 ^ (element - 1)), value) - end + if value ~= 0 then protections[#protections + 1] = string.format("%s %+d%%", getCombatName(2 ^ (element - 1)), value) end end - if #protections > 0 then - descriptions[#descriptions + 1] = string.format("protection %s", - table.concat(protections, - ", ")) - end + if #protections > 0 then descriptions[#descriptions + 1] = string.format("protection %s", table.concat(protections, ", ")) end end -- damage reflection @@ -377,8 +380,7 @@ do -- to do -- regeneration - if abilities.manaGain > 0 or abilities.healthGain > 0 or - abilities.regeneration then + if abilities.manaGain > 0 or abilities.healthGain > 0 or abilities.regeneration then descriptions[#descriptions + 1] = "faster regeneration" end @@ -389,17 +391,12 @@ do do local suppressions = abilities.conditionSuppressions for conditionId, conditionName in pairs(suppressedConditionNames) do - if (abilities.conditionSuppressions & conditionId) ~= 0 then - descriptions[#descriptions + 1] = conditionName - end + if (abilities.conditionSuppressions & conditionId) ~= 0 then descriptions[#descriptions + 1] = conditionName end end end -- speed - if abilities.speed ~= 0 then - descriptions[#descriptions + 1] = string.format("speed %+d", math.floor( - abilities.speed / 2)) - end + if abilities.speed ~= 0 then descriptions[#descriptions + 1] = string.format("speed %+d", math.floor(abilities.speed / 2)) end -- collecting attributes finished -- build the output text @@ -410,11 +407,9 @@ do -- fluid type do - if (itemGroup == ITEM_GROUP_FLUID or itemGroup == ITEM_GROUP_SPLASH) and - subType > 0 then + if (itemGroup == ITEM_GROUP_FLUID or itemGroup == ITEM_GROUP_SPLASH) and subType > 0 then local subTypeName = getSubTypeName(subType) - response[#response + 1] = string.format(" of %s", (subTypeName ~= "" and - subTypeName or "unknown")) + response[#response + 1] = string.format(" of %s", (subTypeName ~= "" and subTypeName or "unknown")) end end @@ -426,19 +421,13 @@ do if not isVirtual then local minLevelDoor = itemType:getLevelDoor() if minLevelDoor ~= 0 then - if actionId >= minLevelDoor then - response[#response + 1] = string.format(" for level %d", - actionId - minLevelDoor) - end + if actionId >= minLevelDoor then response[#response + 1] = string.format(" for level %d", actionId - minLevelDoor) end end end end -- primary attributes parenthesis - if #descriptions > 0 then - response[#response + 1] = string.format(" (%s)", - table.concat(descriptions, ", ")) - end + if #descriptions > 0 then response[#response + 1] = string.format(" (%s)", table.concat(descriptions, ", ")) end -- charges and duration do @@ -447,8 +436,7 @@ do -- charges if itemType:hasShowCharges() then local charges = item:getCharges() - expireInfo[#expireInfo + 1] = string.format("has %d charge%s left", charges, - (charges ~= 1 and "s" or "")) + expireInfo[#expireInfo + 1] = string.format("has %d charge%s left", charges, (charges ~= 1 and "s" or "")) end -- duration @@ -461,8 +449,7 @@ do local transferType = itemType:getTransformEquipId() if transferType ~= 0 then transferType = ItemType(transferType) - maxDuration = transferType and transferType:getDuration() * 1000 or - maxDuration + maxDuration = transferType and transferType:getDuration() * 1000 or maxDuration end end @@ -470,26 +457,18 @@ do expireInfo[#expireInfo + 1] = "is brand-new" elseif currentDuration ~= 0 then expireInfo[#expireInfo + 1] = string.format("will expire in %s", - Game.getCountdownString( - math.floor( - currentDuration / 1000), - true, true)) + Game.getCountdownString(math.floor(currentDuration / 1000), true, true)) end end - if #expireInfo > 0 then - response[#response + 1] = string.format(" that %s", - table.concat(expireInfo, " and ")) - end + if #expireInfo > 0 then response[#response + 1] = string.format(" that %s", table.concat(expireInfo, " and ")) end end -- dot after primary attributes info response[#response + 1] = "." -- empty fluid container suffix - if itemGroup == ITEM_GROUP_FLUID and subType < 1 then - response[#response + 1] = " It is empty." - end + if itemGroup == ITEM_GROUP_FLUID and subType < 1 then response[#response + 1] = " It is empty." end -- house door if isDoor and not isVirtual then @@ -506,12 +485,9 @@ do isForSale = true end - response[#response + 1] = string.format( - " It belongs to house '%s'. %s owns this house.", - houseName, houseOwnerName) + response[#response + 1] = string.format(" It belongs to house '%s'. %s owns this house.", houseName, houseOwnerName) if housePriceVisible and isForSale and pricePerSQM > 0 then - response[#response + 1] = string.format(" It costs %d gold coins.", - pricePerSQM * house:getTileCount()) + response[#response + 1] = string.format(" It costs %d gold coins.", pricePerSQM * house:getTileCount()) end end end @@ -539,45 +515,29 @@ do else for _, vocName in ipairs(runeVocMap) do local vocation = Vocation(vocName) - if vocation and vocation:getPromotion() then - vocAttrs[#vocAttrs + 1] = vocName - end + if vocation and vocation:getPromotion() then vocAttrs[#vocAttrs + 1] = vocName end end end - if #vocAttrs > 1 then - vocAttrs[#vocAttrs - 1] = - string.format("and %s", vocAttrs[#vocAttrs - 1]) - end + if #vocAttrs > 1 then vocAttrs[#vocAttrs - 1] = string.format("and %s", vocAttrs[#vocAttrs - 1]) end local levelInfo = {} - if hasLevel then - levelInfo[#levelInfo + 1] = string.format("level %d", runeLevel) - end + if hasLevel then levelInfo[#levelInfo + 1] = string.format("level %d", runeLevel) end - if hasMLvl then - levelInfo[#levelInfo + 1] = string.format("magic level %d", runeMagLevel) - end + if hasMLvl then levelInfo[#levelInfo + 1] = string.format("magic level %d", runeMagLevel) end local levelStr = "" - if #levelInfo > 0 then - levelStr = string.format(" of %s or higher", - table.concat(levelInfo, " and ")) - end + if #levelInfo > 0 then levelStr = string.format(" of %s or higher", table.concat(levelInfo, " and ")) end - response[#response + 1] = string.format( - "\n%s can only be used properly by %s%s.", - (count > 1 and "They" or "It"), - table.concat(vocAttrs, ", "), levelStr) + response[#response + 1] = string.format("\n%s can only be used properly by %s%s.", (count > 1 and "They" or "It"), + table.concat(vocAttrs, ", "), levelStr) end end else local wieldInfo = itemType:getWieldInfo() if wieldInfo ~= 0 then local wieldAttrs = {} - if (wieldInfo & WIELDINFO_PREMIUM) ~= 0 then - wieldAttrs[#wieldAttrs + 1] = "premium" - end + if (wieldInfo & WIELDINFO_PREMIUM) ~= 0 then wieldAttrs[#wieldAttrs + 1] = "premium" end local vocStr = itemType:getVocationString() if vocStr ~= "" then @@ -588,25 +548,17 @@ do local levelInfo = {} if (wieldInfo & WIELDINFO_LEVEL) ~= 0 then - levelInfo[#levelInfo + 1] = string.format("level %d", - itemType:getMinReqLevel()) + levelInfo[#levelInfo + 1] = string.format("level %d", itemType:getMinReqLevel()) end if (wieldInfo & WIELDINFO_MAGLV) ~= 0 then - levelInfo[#levelInfo + 1] = string.format("magic level %d", - itemType:getMinReqMagicLevel()) + levelInfo[#levelInfo + 1] = string.format("magic level %d", itemType:getMinReqMagicLevel()) end - if #levelInfo > 0 then - wieldAttrs[#wieldAttrs + 1] = string.format("of %s or higher", - table.concat(levelInfo, - " and ")) - end + if #levelInfo > 0 then wieldAttrs[#wieldAttrs + 1] = string.format("of %s or higher", table.concat(levelInfo, " and ")) end - response[#response + 1] = string.format( - "\n%s can only be wielded properly by %s.", - (count > 1 and "They" or "It"), - table.concat(wieldAttrs, " ")) + response[#response + 1] = string.format("\n%s can only be wielded properly by %s.", (count > 1 and "They" or "It"), + table.concat(wieldAttrs, " ")) end end end @@ -614,9 +566,8 @@ do if lookDistance <= 1 then local weight = item:getWeight() if isPickupable and not isUnique then - response[#response + 1] = string.format("\n%s %0.2f oz.", (count == 1 or - not itemType:hasShowCount()) and - "It weighs" or "They weigh", + response[#response + 1] = string.format("\n%s %0.2f oz.", + (count == 1 or not itemType:hasShowCount()) and "It weighs" or "They weigh", weight / 100) end end @@ -632,15 +583,11 @@ do if writer and writer:len() > 0 then writeInfo[#writeInfo + 1] = string.format("\n%s wrote", writer) - if writeDate and writeDate > 0 then - writeInfo[#writeInfo + 1] = string.format(" on %s", - os.date("%d %b %Y", writeDate)) - end + if writeDate and writeDate > 0 then writeInfo[#writeInfo + 1] = string.format(" on %s", os.date("%d %b %Y", writeDate)) end end if #writeInfo > 0 then - response[#response + 1] = string.format("%s:\n%s", - table.concat(writeInfo, ""), text) + response[#response + 1] = string.format("%s:\n%s", table.concat(writeInfo, ""), text) else response[#response + 1] = string.format("\nYou read: %s", text) end @@ -662,13 +609,12 @@ do if not desc or desc == "" then desc = itemType:getDescription() end -- level door description - if isDoor and lookDistance <= 1 and (not desc or desc == "") and - itemType:getLevelDoor() ~= 0 then desc = "Only the worthy may pass." end + if isDoor and lookDistance <= 1 and (not desc or desc == "") and itemType:getLevelDoor() ~= 0 then + desc = "Only the worthy may pass." + end if desc and desc:len() > 0 then - if not (isBed and desc == "Nobody is sleeping there.") then - response[#response + 1] = string.format("\n%s", desc) - end + if not (isBed and desc == "Nobody is sleeping there.") then response[#response + 1] = string.format("\n%s", desc) end end end diff --git a/data/lib/core/player.lua b/data/lib/core/player.lua index ee1911b..43852ab 100644 --- a/data/lib/core/player.lua +++ b/data/lib/core/player.lua @@ -113,23 +113,6 @@ function Player.sendExtendedOpcode(self, opcode, buffer) return true end -APPLY_SKILL_MULTIPLIER = true -local addSkillTriesFunc = Player.addSkillTries -function Player.addSkillTries(...) - APPLY_SKILL_MULTIPLIER = false - local ret = addSkillTriesFunc(...) - APPLY_SKILL_MULTIPLIER = true - return ret -end - -local addManaSpentFunc = Player.addManaSpent -function Player.addManaSpent(...) - APPLY_SKILL_MULTIPLIER = false - local ret = addManaSpentFunc(...) - APPLY_SKILL_MULTIPLIER = true - return ret -end - -- Always pass the number through the isValidMoney function first before using the transferMoneyTo function Player.transferMoneyTo(self, target, amount) if not target then return false end diff --git a/data/lib/core/tile.lua b/data/lib/core/tile.lua index e99662d..c3a1ffc 100644 --- a/data/lib/core/tile.lua +++ b/data/lib/core/tile.lua @@ -1,25 +1,45 @@ function Tile.isCreature(self) return false end +function Tile.isPlayer(self) return false end + function Tile.isItem(self) return false end +function Tile.isMonster(self) return false end + +function Tile.isNpc(self) return false end + +function Tile.isTeleport(self) return false end + function Tile.isTile(self) return true end function Tile.isContainer(self) return false end +function Tile.isHouse(self) return self:getHouse() ~= nil end + +function Tile.getCreature(self) return nil end + +function Tile.getPlayer(self) return nil end + +function Tile.getItem(self) return nil end + +function Tile.getContainer(self) return nil end + function Tile.relocateTo(self, toPosition) if self:getPosition() == toPosition or not Tile(toPosition) then return false end for i = self:getThingCount() - 1, 0, -1 do local thing = self:getThing(i) if thing then - if thing:isItem() then - if thing:getFluidType() ~= 0 then - thing:remove() - elseif ItemType(thing:getId()):isMovable() then - thing:moveTo(toPosition) + local item = thing:getItem() + if item then + if item:getFluidType() ~= 0 then + item:remove() + elseif ItemType(item:getId()):isMovable() then + item:moveTo(toPosition) end - elseif thing:isCreature() then - thing:teleportTo(toPosition) + else + local creature = thing:getCreature() + if creature then creature:teleportTo(toPosition) end end end end @@ -35,8 +55,14 @@ function Tile.isWalkable(self) for i = 1, self:getItemCount() do local item = items[i] local itemType = item:getType() - if itemType:getType() ~= ITEM_TYPE_MAGICFIELD and not itemType:isMovable() and - item:hasProperty(CONST_PROP_BLOCKSOLID) then return false end + if itemType:getType() ~= ITEM_TYPE_MAGICFIELD and not itemType:isMovable() and item:hasProperty(CONST_PROP_BLOCKSOLID) then + return false + end end return true end + +function Tile.getTopPlayer(self) + local creature = self:getTopCreature() + return creature and creature:getPlayer() +end diff --git a/data/npc/lib/npc.lua b/data/npc/lib/npc.lua index 44adfa2..87de14b 100644 --- a/data/npc/lib/npc.lua +++ b/data/npc/lib/npc.lua @@ -56,7 +56,7 @@ function doNpcSellItem(cid, itemid, amount, subType, ignoreCap, inBackpacks, end local func = function(cid, text, type, e, pcid) - if Player(pcid):isPlayer() then + if Player(pcid) then local creature = Creature(cid) creature:say(text, type, false, pcid, creature:getPosition()) e.done = true @@ -64,7 +64,7 @@ local func = function(cid, text, type, e, pcid) end function doCreatureSayWithDelay(cid, text, type, delay, e, pcid) - if Player(pcid):isPlayer() then + if Player(pcid) then e.done = false e.event = addEvent(func, delay < 1 and 1000 or delay, cid, text, type, e, pcid) @@ -73,7 +73,7 @@ end function doPlayerSellItem(cid, itemid, count, cost) local player = Player(cid) - if player:removeItem(itemid, count) then + if player and player:removeItem(itemid, count) then if not player:addMoney(cost) then error('Could not add money to ' .. player:getName() .. '(' .. cost .. 'gp)') end @@ -84,6 +84,8 @@ end function doPlayerBuyItemContainer(cid, containerid, itemid, count, cost, charges) local player = Player(cid) + if not player then return false end + if not player:removeTotalMoney(cost) then return false end for i = 1, count do diff --git a/data/spells/lib/spells.lua b/data/spells/lib/spells.lua index 021d47c..3f9cf34 100644 --- a/data/spells/lib/spells.lua +++ b/data/spells/lib/spells.lua @@ -241,7 +241,7 @@ function Player:addPartyCondition(combat, variant, condition, baseMana) return false end - local mana = math.ceil(#affectedMembers * math.pow(0.9, #affectedMembers - 1) * baseMana) + local mana = math.ceil(#affectedMembers * (0.9 ^ #affectedMembers - 1) * baseMana) if self:getMana() < mana then self:sendCancelMessage(RETURNVALUE_NOTENOUGHMANA) self:getPosition():sendMagicEffect(CONST_ME_POFF) diff --git a/data/talkactions/scripts/attributes.lua b/data/talkactions/scripts/attributes.lua index 2303464..842fec3 100644 --- a/data/talkactions/scripts/attributes.lua +++ b/data/talkactions/scripts/attributes.lua @@ -2,14 +2,11 @@ local function setAttribute(player, thing, attribute, value) local attributeId = Game.getItemAttributeByName(attribute) if attributeId == ITEM_ATTRIBUTE_NONE then return "Invalid attribute name." end - if not thing:setAttribute(attribute, value) then - return "Could not set attribute." - end + if not thing:setAttribute(attribute, value) then return "Could not set attribute." end player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, - string.format("Attribute %s set to: %s", attribute, - thing:getAttribute(attributeId))) - position:sendMagicEffect(CONST_ME_MAGIC_GREEN) + string.format("Attribute %s set to: %s", attribute, thing:getAttribute(attributeId))) + thing:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) return true end @@ -19,27 +16,25 @@ function onSay(player, words, param) local tile = Tile(position) if not tile then - player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, - "There is no tile in front of you.") + player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "There is no tile in front of you.") return false end local thing = tile:getTopVisibleThing(player) if not thing then - player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, - "There is an empty tile in front of you.") + player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "There is an empty tile in front of you.") return false end local attribute, value, extra = unpack(param:splitTrimmed(",")) if attribute == "" then - player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, - string.format("Usage: %s attribute, value.", words)) + player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, string.format("Usage: %s attribute, value.", words)) return false end - if thing:isItem() then - local response = setAttribute(player, thing, attribute, value) + local item = thing:getItem() + if item then + local response = setAttribute(player, item, attribute, value) if response == true then return true end if attribute == "custom" then @@ -48,22 +43,19 @@ function onSay(player, words, param) return false end - if not thing:setCustomAttribute(value, extra) then - player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, - "Could not set custom attribute.") + if not item:setCustomAttribute(value, extra) then + player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Could not set custom attribute.") return false end player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, - string.format("Custom attribute %s set to: %s", value, - thing:getCustomAttribute(value))) + string.format("Custom attribute %s set to: %s", value, item:getCustomAttribute(value))) position:sendMagicEffect(CONST_ME_MAGIC_GREEN) else player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, response) end else - player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, - "Thing in front of you is not supported.") + player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Thing in front of you is not supported.") end return false end diff --git a/src/luascript.cpp b/src/luascript.cpp index 3057115..6fff1a7 100644 --- a/src/luascript.cpp +++ b/src/luascript.cpp @@ -3871,6 +3871,7 @@ int LuaScriptInterface::luaStopEvent(lua_State* L) int LuaScriptInterface::luaSaveServer(lua_State* L) { + // saveServer() g_game.saveGameState(); pushBoolean(L, true); return 1; @@ -3878,6 +3879,7 @@ int LuaScriptInterface::luaSaveServer(lua_State* L) int LuaScriptInterface::luaCleanMap(lua_State* L) { + // cleanMap() lua_pushinteger(L, g_game.map.clean()); return 1; }