diff --git a/.github/workflows/analysis-sonarcloud.yml b/.github/workflows/analysis-sonarcloud.yml index 71b910fa995..1b75d085097 100644 --- a/.github/workflows/analysis-sonarcloud.yml +++ b/.github/workflows/analysis-sonarcloud.yml @@ -2,8 +2,10 @@ name: Analysis - SonarCloud on: - pull_request_target: + pull_request: types: [opened, synchronize, reopened, ready_for_review] + branches-ignore: + - main paths: - "src/**" diff --git a/data-canary/scripts/lib/helper_constructors.lua b/data-canary/scripts/lib/helper_constructors.lua deleted file mode 100644 index fdcd1508c84..00000000000 --- a/data-canary/scripts/lib/helper_constructors.lua +++ /dev/null @@ -1,53 +0,0 @@ --- HelperConstructors -local classes = { Action, CreatureEvent, Spell, TalkAction, MoveEvent, EventCallback, GlobalEvent, Weapon } - -for _, class in ipairs(classes) do - local MT = getmetatable(class) - local DefaultConstructor = MT.__call - - MT.__call = function(self, def, ...) - -- Backwards compatibility for default obj() constructor - if type(def) ~= "table" then - return DefaultConstructor(self, def, ...) - end - - local obj = nil - if def.init then - obj = DefaultConstructor(self, unpack(def.init)) - else - obj = DefaultConstructor(self) - end - - -- Call each method from definition table with the value as params - local hasCallback = false - - for methodName, value in pairs(def) do - -- Strictly check if a correct callback is passed - if methodName:sub(1, 2) == "on" and type(value) == "function" and rawget(class, methodName) then - hasCallback = true - end - - if methodName ~= "register" then - local method = rawget(self, methodName) - if method then - if type(value) == "table" then - method(obj, unpack(value)) - else - method(obj, value) - end - end - end - end - - -- Only register if callback has already been defined, otherwise defining afterwards will not work - if def.register then - if not hasCallback then - logger.warn("[HelperConstructors] - Event not registered due to there being no callback") - else - obj:register() - end - end - - return obj - end -end diff --git a/data-canary/scripts/lib/register_actions.lua b/data-canary/scripts/lib/register_actions.lua deleted file mode 100644 index 7f2fed403fb..00000000000 --- a/data-canary/scripts/lib/register_actions.lua +++ /dev/null @@ -1,304 +0,0 @@ -local wildGrowth = { 2130, 10182 } -- wild growth destroyable by machete -local jungleGrass = { -- grass destroyable by machete - [3696] = 3695, - [3702] = 3701, - [17153] = 17151, -} -local holeId = { -- usable rope holes, for rope spots see global.lua - 294, - 369, - 370, - 383, - 392, - 408, - 409, - 410, - 427, - 428, - 429, - 430, - 462, - 469, - 470, - 482, - 484, - 485, - 489, - 924, - 1369, - 3135, - 3136, - 4835, - 4837, - 7933, - 7938, - 8170, - 8249, - 8250, - 8251, - 8252, - 8254, - 8255, - 8256, - 8276, - 8277, - 8279, - 8281, - 8284, - 8285, - 8286, - 8323, - 8567, - 8585, - 8595, - 8596, - 8972, - 9606, - 9625, - 13190, - 14461, - 19519, - 21536, - 23713, - 26020, -} -local groundIds = { 354, 355 } -- pick usable grounds -local holes = { 593, 606, 608, 867, 21341 } -- holes opened by shovel -local sandIds = { 231, 9059 } -- desert sand -local fruits = { 2673, 2674, 2675, 2676, 2677, 2678, 2679, 2680, 2681, 2682, 2684, 2685, 5097, 8839, 8840, 8841 } -- fruits to make decorated cake with knife - -ActionsLib = {} - -ActionsLib.destroyItem = function(player, target, toPosition) - if type(target) ~= "userdata" or not target:isItem() then - return false - end - - if target:hasAttribute(ITEM_ATTRIBUTE_UNIQUEID) or target:hasAttribute(ITEM_ATTRIBUTE_ACTIONID) then - return false - end - - if toPosition.x == CONTAINER_POSITION then - player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) - return true - end - - local destroyId = ItemType(target.itemid):getDestroyId() - if destroyId == 0 then - return false - end - - if math.random(7) == 1 then - local item = Game.createItem(destroyId, 1, toPosition) - if item then - item:decay() - end - - -- Move items outside the container - if target:isContainer() then - for i = target:getSize() - 1, 0, -1 do - local containerItem = target:getItem(i) - if containerItem then - containerItem:moveTo(toPosition) - end - end - end - - target:remove(1) - end - - toPosition:sendMagicEffect(CONST_ME_POFF) - return true -end - -ActionsLib.useMachete = function(player, item, fromPosition, target, toPosition, isHotkey) - local targetId = target.itemid - if not targetId then - return true - end - - if table.contains(wildGrowth, targetId) then - toPosition:sendMagicEffect(CONST_ME_POFF) - target:remove() - return true - end - - local grass = jungleGrass[targetId] - if grass then - target:transform(grass) - target:decay() - return true - end - return false -end - -ActionsLib.usePick = function(player, item, fromPosition, target, toPosition, isHotkey) - if target.itemid == 11227 then -- shiny stone refining - local chance = math.random(1, 100) - if chance == 1 then - player:addItem(ITEM_CRYSTAL_COIN) -- 1% chance of getting crystal coin - elseif chance <= 6 then - player:addItem(ITEM_GOLD_COIN) -- 5% chance of getting gold coin - elseif chance <= 51 then - player:addItem(ITEM_PLATINUM_COIN) -- 45% chance of getting platinum coin - else - player:addItem(2145) -- 49% chance of getting small diamond - end - target:getPosition():sendMagicEffect(CONST_ME_BLOCKHIT) - target:remove(1) - return true - end - - local tile = Tile(toPosition) - if not tile then - return false - end - - local ground = tile:getGround() - if not ground then - return false - end - - if table.contains(groundIds, ground.itemid) and (ground:hasAttribute(ITEM_ATTRIBUTE_UNIQUEID) or ground:hasAttribute(ITEM_ATTRIBUTE_ACTIONID)) then - ground:transform(392) - ground:decay() - - toPosition.z = toPosition.z + 1 - tile:relocateTo(toPosition) - end - return true -end - -ActionsLib.useRope = function(player, item, fromPosition, target, toPosition, isHotkey) - local tile = Tile(toPosition) - if not tile then - return false - end - - local RopeSpots = { 386, 421, 12935, 12936, 14238, 17238, 21501, 21965, 21966, 21967, 21968, 23363 } - if table.contains(ropeSpots, tile:getGround():getId()) or tile:getItemById(14435) then - if Tile(toPosition:moveUpstairs()):hasFlag(TILESTATE_PROTECTIONZONE) and player:isPzLocked() then - player:sendCancelMessage(RETURNVALUE_PLAYERISPZLOCKED) - return true - end - player:teleportTo(toPosition, false) - return true - elseif table.contains(holeId, target.itemid) then - toPosition.z = toPosition.z + 1 - tile = Tile(toPosition) - if tile then - local thing = tile:getTopVisibleThing() - if thing:isPlayer() then - if Tile(toPosition:moveUpstairs()):hasFlag(TILESTATE_PROTECTIONZONE) and thing:isPzLocked() then - return false - end - return thing:teleportTo(toPosition, false) - end - if thing:isItem() and thing:getType():isMovable() then - return thing:moveTo(toPosition:moveUpstairs()) - end - end - player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) - return true - end - return false -end - -ActionsLib.useShovel = function(player, item, fromPosition, target, toPosition, isHotkey) - local tile = Tile(toPosition) - if not tile then - return false - end - - local ground = tile:getGround() - if not ground then - return false - end - - local groundId = ground:getId() - if table.contains(holes, groundId) then - ground:transform(groundId + 1) - ground:decay() - toPosition:moveDownstairs() - toPosition.y = toPosition.y - 1 - if Tile(toPosition):hasFlag(TILESTATE_PROTECTIONZONE) and player:isPzLocked() then - player:sendCancelMessage(RETURNVALUE_PLAYERISPZLOCKED) - return true - end - player:teleportTo(toPosition, false) - toPosition.z = toPosition.z + 1 - tile:relocateTo(toPosition) - elseif table.contains(sandIds, groundId) then - local randomValue = math.random(1, 100) - if target.actionid == 100 and randomValue <= 20 then - ground:transform(489) - ground:decay() - elseif randomValue == 1 then - Game.createItem(3042, 1, toPosition) -- Scarab Coin - elseif randomValue > 95 then - Game.createMonster("Scarab", toPosition) - end - toPosition:sendMagicEffect(CONST_ME_POFF) - else - return false - end - return true -end - -ActionsLib.useScythe = function(player, item, fromPosition, target, toPosition, isHotkey) - if table.contains({ 9594, 9598 }, item.itemid) then - return false - end - - if target.itemid == 3653 then -- wheat - target:transform(3651) - target:decay() - Game.createItem(3605, 1, toPosition) -- bunch of wheat - return true - end - return false -end - -ActionsLib.useCrowbar = function(player, item, fromPosition, target, toPosition, isHotkey) - if table.contains({ 10511, 10513 }, item.itemid) then - return false - end - - return false -end - -ActionsLib.useSpoon = function(player, item, fromPosition, target, toPosition, isHotkey) - if table.contains({ 10515, 10513 }, item.itemid) then - return false - end - - return false -end - -ActionsLib.useSickle = function(player, item, fromPosition, target, toPosition, isHotkey) - if table.contains({ 10511, 10515 }, item.itemid) then - return false - end - - if target.itemid == 5463 then -- burning sugar cane - target:transform(5462) - target:decay() - Game.createItem(5466, 1, toPosition) -- bunch of sugar cane - return true - end - return false -end - -ActionsLib.useKitchenKnife = function(player, item, fromPosition, target, toPosition, isHotkey) - if item.itemid == 10513 then - return false - end - - if table.contains(fruits, target.itemid) and player:removeItem(6278, 1) then - target:remove(1) - player:addItem(6279, 1) - player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) - return true - end - return false -end diff --git a/data-canary/scripts/lib/register_item_tier.lua b/data-canary/scripts/lib/register_item_tier.lua deleted file mode 100644 index 51ad62ccc6e..00000000000 --- a/data-canary/scripts/lib/register_item_tier.lua +++ /dev/null @@ -1,24 +0,0 @@ -registerItemClassification = {} -setmetatable(registerItemClassification, { - __call = function(self, itemClass, mask) - for _, parse in pairs(self) do - parse(itemClass, mask) - end - end, -}) - -ItemClassification.register = function(self, mask) - return registerItemClassification(self, mask) -end - -registerItemClassification.Upgrades = function(itemClassification, mask) - if mask.Upgrades then - for _, value in ipairs(mask.Upgrades) do - if value.TierId and value.Price then - itemClassification:addTier(value.TierId, value.Price, value.Core) - else - logger.warn("[registerItemClassification.Upgrades] - Item classification failed on adquire TierID or Price attribute.") - end - end - end -end diff --git a/data-canary/scripts/lib/register_monster_type.lua b/data-canary/scripts/lib/register_monster_type.lua deleted file mode 100644 index 9e1f3848453..00000000000 --- a/data-canary/scripts/lib/register_monster_type.lua +++ /dev/null @@ -1,960 +0,0 @@ -local smallAreaRadius = 3 -local superDrunkDuration = 4000 - -registerMonsterType = {} -setmetatable(registerMonsterType, { - __call = function(self, mtype, mask) - for _, parse in pairs(self) do - parse(mtype, mask) - end - end, -}) - -MonsterType.register = function(self, mask) - return registerMonsterType(self, mask) -end - -registerMonsterType.name = function(mtype, mask) - if mask.name then - mtype:name(mask.name) - end -end -registerMonsterType.description = function(mtype, mask) - if mask.description then - mtype:nameDescription(mask.description) - end -end -registerMonsterType.experience = function(mtype, mask) - if mask.experience then - mtype:experience(mask.experience) - end -end -registerMonsterType.raceId = function(mtype, mask) - if mask.raceId then - mtype:raceId(mask.raceId) - end -end -registerMonsterType.Bestiary = function(mtype, mask) - if mask.Bestiary then - if mask.Bestiary.race then - mtype:Bestiaryrace(mask.Bestiary.race) - end - if mask.Bestiary.class then - mtype:Bestiaryclass(mask.Bestiary.class) - end - if mask.Bestiary.toKill then - mtype:BestiarytoKill(mask.Bestiary.toKill) - end - if mask.Bestiary.FirstUnlock then - mtype:BestiaryFirstUnlock(mask.Bestiary.FirstUnlock) - end - if mask.Bestiary.SecondUnlock then - mtype:BestiarySecondUnlock(mask.Bestiary.SecondUnlock) - end - if mask.Bestiary.CharmsPoints then - mtype:BestiaryCharmsPoints(mask.Bestiary.CharmsPoints) - end - if mask.Bestiary.Stars then - mtype:BestiaryStars(mask.Bestiary.Stars) - end - if mask.Bestiary.Occurrence then - mtype:BestiaryOccurrence(mask.Bestiary.Occurrence) - end - if mask.Bestiary.Locations then - mtype:BestiaryLocations(mask.Bestiary.Locations) - end - end -end -registerMonsterType.bosstiary = function(mtype, mask) - local bossClass = nil - if mask.bosstiary then - if mask.bosstiary.bossRaceId then - mtype:bossRaceId(mask.bosstiary.bossRaceId) - end - if mask.bosstiary.bossRace then - if mask.bosstiary.bossRace == RARITY_BANE then - bossClass = "Bane" - elseif mask.bosstiary.bossRace == RARITY_ARCHFOE then - bossClass = "Archfoe" - elseif mask.bosstiary.bossRace == RARITY_NEMESIS then - bossClass = "Nemesis" - end - if bossClass ~= nil then - mtype:bossRace(mask.bosstiary.bossRace, bossClass) - end - local storage = mask.bosstiary.storageCooldown - if storage ~= nil then - mtype:bossStorageCooldown(storage) - end - end - end -end -registerMonsterType.skull = function(mtype, mask) - if mask.skull then - mtype:skull(mask.skull) - end -end -registerMonsterType.outfit = function(mtype, mask) - if mask.outfit then - mtype:outfit(mask.outfit) - end -end -registerMonsterType.maxHealth = function(mtype, mask) - if mask.maxHealth then - mtype:maxHealth(mask.maxHealth) - end -end -registerMonsterType.health = function(mtype, mask) - if mask.health then - mtype:health(mask.health) - end -end -registerMonsterType.race = function(mtype, mask) - if mask.race then - mtype:race(mask.race) - end -end -registerMonsterType.manaCost = function(mtype, mask) - if mask.manaCost then - mtype:manaCost(mask.manaCost) - end -end -registerMonsterType.speed = function(mtype, mask) - if mask.speed then - mtype:baseSpeed(mask.speed) - end -end -registerMonsterType.corpse = function(mtype, mask) - if mask.corpse then - mtype:corpseId(mask.corpse) - end -end -registerMonsterType.faction = function(mtype, mask) - if mask.faction then - mtype:faction(mask.faction) - end -end -registerMonsterType.targetPreferPlayer = function(mtype, mask) - if mask.targetPreferPlayer then - mtype:targetPreferPlayer(mask.targetPreferPlayer) - end -end -registerMonsterType.targetPreferMaster = function(mtype, mask) - if mask.targetPreferMaster then - mtype:targetPreferMaster(mask.targetPreferMaster) - end -end -registerMonsterType.enemyFactions = function(mtype, mask) - if mask.enemyFactions then - for _, enemyFaction in pairs(mask.enemyFactions) do - if not enemyFaction then - print('[Error - Loading monsters] Monster: "' .. mtype:name() .. '". Unknown enemy faction.') - else - mtype:enemyFactions(enemyFaction) - end - end - end -end -registerMonsterType.flags = function(mtype, mask) - if mask.flags then - if mask.flags.attackable ~= nil then - mtype:isAttackable(mask.flags.attackable) - end - if mask.flags.convinceable ~= nil then - mtype:isConvinceable(mask.flags.convinceable) - end - if mask.flags.summonable ~= nil then - mtype:isSummonable(mask.flags.summonable) - end - if mask.flags.illusionable ~= nil then - mtype:isIllusionable(mask.flags.illusionable) - end - if mask.flags.hostile ~= nil then - mtype:isHostile(mask.flags.hostile) - end - if mask.flags.healthHidden ~= nil then - mtype:isHealthHidden(mask.flags.healthHidden) - end - if mask.flags.pushable ~= nil then - mtype:isPushable(mask.flags.pushable) - end - if mask.flags.canPushItems ~= nil then - mtype:canPushItems(mask.flags.canPushItems) - end - if mask.flags.rewardBoss then - mtype:isRewardBoss(mask.flags.rewardBoss) - end - if mask.flags.familiar then - mtype:familiar(mask.flags.familiar) - end - if mask.flags.respawntype or mask.flags.respawnType then - logger.warn("[registerMonsterType.flags] - Monster: {}. Deprecated flag 'respawnType', use instead table 'respawnType = { period = RespawnPeriod_t, underground = boolean}'", mtype:name()) - end - if mask.flags.canPushCreatures ~= nil then - mtype:canPushCreatures(mask.flags.canPushCreatures) - end - if mask.flags.targetDistance then - mtype:targetDistance(math.max(1, mask.flags.targetDistance)) - end - if mask.flags.runHealth then - mtype:runHealth(mask.flags.runHealth) - end - if mask.flags.staticAttackChance then - mtype:staticAttackChance(mask.flags.staticAttackChance) - end - if mask.flags.canWalkOnEnergy ~= nil then - mtype:canWalkOnEnergy(mask.flags.canWalkOnEnergy) - end - if mask.flags.canWalkOnFire ~= nil then - mtype:canWalkOnFire(mask.flags.canWalkOnFire) - end - if mask.flags.canWalkOnPoison ~= nil then - mtype:canWalkOnPoison(mask.flags.canWalkOnPoison) - end - if mask.flags.isBlockable ~= nil then - mtype:isBlockable(mask.flags.isBlockable) - end - if mask.flags.isForgeCreature ~= nil then - mtype:isForgeCreature(mask.flags.isForgeCreature) - end - end -end -registerMonsterType.light = function(mtype, mask) - if mask.light then - local color = 0 - if mask.light.color then - color = mask.light.color - end - if mask.light.level then - mtype:light(color, mask.light.level) - end - end -end -registerMonsterType.changeTarget = function(mtype, mask) - if mask.changeTarget then - if mask.changeTarget.chance then - mtype:changeTargetChance(mask.changeTarget.chance) - end - if mask.changeTarget.interval then - mtype:changeTargetSpeed(mask.changeTarget.interval) - end - end -end -registerMonsterType.strategiesTarget = function(mtype, mask) - if mask.strategiesTarget then - if mask.strategiesTarget.nearest then - mtype:strategiesTargetNearest(mask.strategiesTarget.nearest) - end - if mask.strategiesTarget.health then - mtype:strategiesTargetHealth(mask.strategiesTarget.health) - end - if mask.strategiesTarget.damage then - mtype:strategiesTargetDamage(mask.strategiesTarget.damage) - end - if mask.strategiesTarget.random then - mtype:strategiesTargetRandom(mask.strategiesTarget.random) - end - end -end -registerMonsterType.respawnType = function(mtype, mask) - if mask.respawnType then - if mask.respawnType.period then - mtype:respawnTypePeriod(mask.respawnType.period) - end - if mask.respawnType.underground then - mtype:respawnTypeIsUnderground(mask.respawnType.underground) - end - end -end -registerMonsterType.sounds = function(mtype, mask) - if type(mask.sounds) == "table" then - if mask.sounds.death then - mtype:deathSound(mask.sounds.death) - end - if mask.sounds.ticks and mask.sounds.chance and mask.sounds.ids and type(mask.sounds.ids) == "table" and #mask.sounds.ids > 0 then - mtype:soundSpeedTicks(mask.sounds.ticks) - mtype:soundChance(mask.sounds.chance) - for _, v in pairs(mask.sounds.ids) do - mtype:addSound(v) - end - end - end -end -registerMonsterType.voices = function(mtype, mask) - if type(mask.voices) == "table" then - local interval, chance - if mask.voices.interval then - interval = mask.voices.interval - end - if mask.voices.chance then - chance = mask.voices.chance - end - for k, v in pairs(mask.voices) do - if type(v) == "table" then - mtype:addVoice(v.text, interval, chance, v.yell) - end - end - end -end -registerMonsterType.summon = function(mtype, mask) - if mask.summon then - if mask.summon.maxSummons then - mtype:maxSummons(mask.summon.maxSummons) - end - if type(mask.summon.summons) == "table" then - for k, v in pairs(mask.summon.summons) do - mtype:addSummon(v.name, v.interval, v.chance, v.count) - end - end - end -end -registerMonsterType.events = function(mtype, mask) - if type(mask.events) == "table" then - for k, v in pairs(mask.events) do - mtype:registerEvent(v) - end - end -end - -function SortLootByChance(loot) - if not configManager.getBoolean(configKeys.SORT_LOOT_BY_CHANCE) then - return - end - - table.sort(loot, function(loot1, loot2) - if not loot1.chance or not loot2.chance then - return 0 - end - - return loot1.chance < loot2.chance - end) -end - -registerMonsterType.loot = function(mtype, mask) - if type(mask.loot) == "table" then - SortLootByChance(mask.loot) - local lootError = false - for _, loot in pairs(mask.loot) do - local parent = Loot() - if loot.name then - if not parent:setIdFromName(loot.name) then - lootError = true - end - else - if not isInteger(loot.id) or loot.id < 1 then - lootError = true - end - parent:setId(loot.id) - end - if loot.subType or loot.charges then - parent:setSubType(loot.subType or loot.charges) - else - local lType = ItemType(loot.name and loot.name or loot.id) - if lType and lType:getCharges() > 1 then - parent:setSubType(lType:getCharges()) - end - end - if loot.chance then - parent:setChance(loot.chance) - end - if loot.minCount then - parent:setMinCount(loot.minCount) - end - if loot.maxCount then - parent:setMaxCount(loot.maxCount) - end - if loot.aid or loot.actionId then - parent:setActionId(loot.aid or loot.actionId) - end - if loot.text or loot.description then - parent:setText(loot.text or loot.description) - end - if loot.name then - parent:setNameItem(loot.name) - end - if loot.article then - parent:setArticle(loot.article) - end - if loot.attack then - parent:setAttack(loot.attack) - end - if loot.defense then - parent:setDefense(loot.defense) - end - if loot.extraDefense or loot.extraDef then - parent:setExtraDefense(loot.extraDefense or loot.extraDef) - end - if loot.armor then - parent:setArmor(loot.armor) - end - if loot.shootRange or loot.range then - parent:setShootRange(loot.shootRange or loot.range) - end - if loot.unique then - parent:setUnique(loot.unique) - end - if loot.child then - SortLootByChance(loot.child) - for _, children in pairs(loot.child) do - local child = Loot() - if children.name then - if not child:setIdFromName(children.name) then - lootError = true - end - else - if not isInteger(children.id) or children.id < 1 then - lootError = true - end - child:setId(children.id) - end - if children.subType or children.charges then - child:setSubType(children.subType or children.charges) - else - local cType = ItemType(children.name and children.name or children.id) - if cType and cType:getCharges() > 1 then - child:setSubType(cType:getCharges()) - end - end - if children.chance then - child:setChance(children.chance) - end - if children.minCount then - child:setMinCount(children.minCount) - end - if children.maxCount then - child:setMaxCount(children.maxCount) - end - if children.aid or children.actionId then - child:setActionId(children.aid or children.actionId) - end - if children.text or children.description then - child:setText(children.text or children.description) - end - if loot.name then - child:setNameItem(loot.name) - end - if children.article then - child:setArticle(children.article) - end - if children.attack then - child:setAttack(children.attack) - end - if children.defense then - child:setDefense(children.defense) - end - if children.extraDefense or children.extraDef then - child:setExtraDefense(children.extraDefense or children.extraDef) - end - if children.armor then - child:setArmor(children.armor) - end - if children.shootRange or children.range then - child:setShootRange(children.shootRange or children.range) - end - if children.unique then - child:setUnique(children.unique) - end - parent:addChildLoot(child) - end - end - mtype:addLoot(parent) - end - if lootError then - logger.warn("[registerMonsterType.loot] - Monster: {} loot could not correctly be load", mtype:name()) - end - end -end -registerMonsterType.elements = function(mtype, mask) - if type(mask.elements) == "table" then - for _, element in pairs(mask.elements) do - if element.type and element.percent then - mtype:addElement(element.type, element.percent) - end - end - end -end -registerMonsterType.reflects = function(mtype, mask) - if type(mask.reflects) == "table" then - for _, reflect in pairs(mask.reflects) do - if reflect.type and reflect.percent then - mtype:addReflect(reflect.type, reflect.percent) - end - end - end -end -registerMonsterType.heals = function(mtype, mask) - if type(mask.heals) == "table" then - for _, heal in pairs(mask.heals) do - if heal.type and heal.percent then - mtype:addHealing(heal.type, heal.percent) - end - end - end -end -registerMonsterType.immunities = function(mtype, mask) - if type(mask.immunities) == "table" then - for _, immunity in pairs(mask.immunities) do - if immunity.type and immunity.combat then - mtype:combatImmunities(immunity.type) - end - if immunity.type and immunity.condition then - mtype:conditionImmunities(immunity.type) - end - end - end -end -registerMonsterType.attacks = function(mtype, mask) - if type(mask.attacks) == "table" then - for _, attack in pairs(mask.attacks) do - mtype:addAttack(readSpell(attack, mtype)) - end - end -end - -registerMonsterType.defenses = function(mtype, mask) - if type(mask.defenses) == "table" then - if mask.defenses.defense then - mtype:defense(mask.defenses.defense) - end - if mask.defenses.armor then - mtype:armor(mask.defenses.armor) - end - for _, defense in pairs(mask.defenses) do - if type(defense) == "table" then - mtype:addDefense(readSpell(defense, mtype)) - end - end - end -end - -local function loadcastSound(effect, incomingLua, mtype) - -- Throw shoottype - if - effect == CONST_ANI_SPEAR - or effect == CONST_ANI_THROWINGSTAR - or effect == CONST_ANI_THROWINGKNIFE - or effect == CONST_ANI_SMALLSTONE - or effect == CONST_ANI_LARGEROCK - or effect == CONST_ANI_SNOWBALL - or effect == CONST_ANI_HUNTINGSPEAR - or effect == CONST_ANI_ENCHANTEDSPEAR - or effect == CONST_ANI_REDSTAR - or effect == CONST_ANI_GREENSTAR - or effect == CONST_ANI_ROYALSPEAR - or effect == CONST_ANI_WHIRLWINDSWORD - or effect == CONST_ANI_WHIRLWINDAXE - or effect == CONST_ANI_WHIRLWINDCLUB - or effect == CONST_ANI_CAKE - or effect == CONST_ANI_GLOOTHSPEAR - or effect == CONST_ANI_LEAFSTAR - or effect == CONST_ANI_ROYALSTAR - then - return SOUND_EFFECT_TYPE_DIST_ATK_THROW - - -- Crossbow shoottype - elseif effect == CONST_ANI_BOLT or effect == CONST_ANI_POWERBOLT or effect == CONST_ANI_INFERNALBOLT or effect == CONST_ANI_PIERCINGBOLT or effect == CONST_ANI_VORTEXBOLT or effect == CONST_ANI_PRISMATICBOLT or effect == CONST_ANI_DRILLBOLT or effect == CONST_ANI_SPECTRALBOLT then - return SOUND_EFFECT_TYPE_DIST_ATK_CROSSBOW - - -- Bow shoottype - elseif - effect == CONST_ANI_POISONARROW - or effect == CONST_ANI_BURSTARROW - or effect == CONST_ANI_SNIPERARROW - or effect == CONST_ANI_ONYXARROW - or effect == CONST_ANI_FLASHARROW - or effect == CONST_ANI_FLAMMINGARROW - or effect == CONST_ANI_SHIVERARROW - or effect == CONST_ANI_EARTHARROW - or effect == CONST_ANI_TARSALARROW - or effect == CONST_ANI_CRYSTALLINEARROW - or effect == CONST_ANI_ENVENOMEDARROW - or effect == CONST_ANI_SIMPLEARROW - or effect == CONST_ANI_DIAMONDARROW - then - return SOUND_EFFECT_TYPE_DIST_ATK_BOW - - -- Magical shoottype - elseif - effect == CONST_ANI_FIRE - or effect == CONST_ANI_ENERGY - or effect == CONST_ANI_DEATH - or effect == CONST_ANI_POISON - or effect == CONST_ANI_ETHEREALSPEAR - or effect == CONST_ANI_ICE - or effect == CONST_ANI_EARTH - or effect == CONST_ANI_HOLY - or effect == CONST_ANI_SUDDENDEATH - or effect == CONST_ANI_ENERGYBALL - or effect == CONST_ANI_SMALLICE - or effect == CONST_ANI_SMALLHOLY - or effect == CONST_ANI_SMALLEARTH - or effect == CONST_ANI_EXPLOSION - then - return SOUND_EFFECT_TYPE_MAGICAL_RANGE_ATK - end - - return SOUND_EFFECT_TYPE_SILENCE -end - -local function loadImpactSound(incomingLua, mtype) - local nameType = "physical" - if incomingLua.name == "melee" then - local meleeSoundTable = {} - if mtype:targetDistance() <= 1 then - meleeSoundTable = { - [1] = SOUND_EFFECT_TYPE_MONSTER_MELEE_ATK_FIST, - [2] = SOUND_EFFECT_TYPE_MONSTER_MELEE_ATK_CLAW, - [3] = SOUND_EFFECT_TYPE_MONSTER_MELEE_ATK_BITE, - } - else - meleeSoundTable = { - [1] = SOUND_EFFECT_TYPE_MONSTER_MELEE_ATK_RIP, - --[2] = SOUND_EFFECT_TYPE_MONSTER_MELEE_ATK_ACID, - [2] = SOUND_EFFECT_TYPE_MONSTER_MELEE_ATK_MAGIC, - --[4] = SOUND_EFFECT_TYPE_MONSTER_MELEE_ATK_ETHEREAL, - --[5] = SOUND_EFFECT_TYPE_MONSTER_MELEE_ATK_CONSTRUCT, - } - end - return meleeSoundTable[math.random(1, #meleeSoundTable)] - elseif incomingLua.name == "combat" then - if incomingLua.type == COMBAT_PHYSICALDAMAGE then - nameType = "physical" - elseif incomingLua.type == COMBAT_ENERGYDAMAGE then - nameType = "energy" - elseif incomingLua.type == COMBAT_EARTHDAMAGE then - nameType = "earth" - elseif incomingLua.type == COMBAT_FIREDAMAGE then - nameType = "fire" - elseif incomingLua.type == COMBAT_UNDEFINEDDAMAGE then - nameType = "bleeding" - elseif incomingLua.type == COMBAT_LIFEDRAIN then - nameType = "lifedrain" - elseif incomingLua.type == COMBAT_MANADRAIN then - nameType = "manadrain" - elseif incomingLua.type == COMBAT_HEALING then - nameType = "healing" - elseif incomingLua.type == COMBAT_DROWNDAMAGE then - nameType = "drown" - elseif incomingLua.type == COMBAT_ICEDAMAGE then - nameType = "ice" - elseif incomingLua.type == COMBAT_HOLYDAMAGE then - nameType = "holy" - elseif incomingLua.type == COMBAT_DEATHDAMAGE then - nameType = "death" - end - elseif incomingLua.name == "drunk" then - if incomingLua.duration and incomingLua.duration > superDrunkDuration then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_SUPER_DRUNKEN - end - return SOUND_EFFECT_TYPE_MONSTER_SPELL_DRUNKEN - elseif incomingLua.name == "speed" then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_SPEED - elseif incomingLua.name == "outfit" then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_OUTFIT - elseif incomingLua.name == "strength" then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_STRENGTH - elseif incomingLua.name == "firefield" then - return SOUND_EFFECT_TYPE_SPELL_FIRE_FIELD_RUNE - elseif incomingLua.name == "energyfield" then - return SOUND_EFFECT_TYPE_SPELL_ENERGY_FIELD_RUNE - elseif incomingLua.name == "earthfield" or incomingLua.name == "poisonfield" then - return SOUND_EFFECT_TYPE_SPELL_POISON_FIELD_RUNE - elseif incomingLua.name == "condition" then - -- To-Do - end - - -- Waves - if incomingLua.length and incomingLua.spread then - if nameType == "bleeding" then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_WAVE_BLEEDING - elseif nameType == "energy" then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_WAVE_ENERGY - elseif nameType == "earth" then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_WAVE_EARTH - elseif nameType == "fire" then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_WAVE_FIRE - elseif nameType == "lifedrain" then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_WAVE_LIFEDRAIN - elseif nameType == "manadrain" then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_WAVE_MANADRAIN - elseif nameType == "healing" then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_WAVE_HEALING - elseif nameType == "drown" then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_WAVE_DROWNING - elseif nameType == "ice" then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_WAVE_ICE - elseif nameType == "holy" then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_WAVE_HOLY - elseif nameType == "death" then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_WAVE_DEATH - elseif nameType == "physical" then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_WAVE_HIT - end - - -- Bombs area (not field) - elseif incomingLua.radius then - if nameType == "bleeding" then - if incomingLua.radius <= smallAreaRadius then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_SMALL_AREA_BLEEDING - else - return SOUND_EFFECT_TYPE_MONSTER_SPELL_LARGE_AREA_BLEEDING - end - elseif nameType == "energy" then - if incomingLua.radius <= smallAreaRadius then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_SMALL_AREA_ENERGY - else - return SOUND_EFFECT_TYPE_MONSTER_SPELL_LARGE_AREA_ENERGY - end - elseif nameType == "earth" then - if incomingLua.radius <= smallAreaRadius then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_SMALL_AREA_EARTH - else - return SOUND_EFFECT_TYPE_MONSTER_SPELL_LARGE_AREA_EARTH - end - elseif nameType == "fire" then - if incomingLua.radius <= smallAreaRadius then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_SMALL_AREA_FIRE - else - return SOUND_EFFECT_TYPE_MONSTER_SPELL_LARGE_AREA_FIRE - end - elseif nameType == "lifedrain" then - if incomingLua.radius <= smallAreaRadius then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_SMALL_AREA_LIFEDRAIN - else - return SOUND_EFFECT_TYPE_MONSTER_SPELL_LARGE_AREA_LIFEDRAIN - end - elseif nameType == "manadrain" then - if incomingLua.radius <= smallAreaRadius then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_SMALL_AREA_MANADRAIN - else - return SOUND_EFFECT_TYPE_MONSTER_SPELL_LARGE_AREA_MANADRAIN - end - elseif nameType == "healing" then - if incomingLua.radius <= smallAreaRadius then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_SMALL_AREA_HEALING - else - return SOUND_EFFECT_TYPE_MONSTER_SPELL_LARGE_AREA_HEALING - end - elseif nameType == "drown" then - if incomingLua.radius <= smallAreaRadius then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_SMALL_AREA_DROWNING - else - return SOUND_EFFECT_TYPE_MONSTER_SPELL_LARGE_AREA_DROWNING - end - elseif nameType == "ice" then - if incomingLua.radius <= smallAreaRadius then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_SMALL_AREA_ICE - else - return SOUND_EFFECT_TYPE_MONSTER_SPELL_LARGE_AREA_ICE - end - elseif nameType == "holy" then - if incomingLua.radius <= smallAreaRadius then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_SMALL_AREA_HOLY - else - return SOUND_EFFECT_TYPE_MONSTER_SPELL_LARGE_AREA_HOLY - end - elseif nameType == "death" then - if incomingLua.radius <= smallAreaRadius then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_SMALL_AREA_DEATH - else - return SOUND_EFFECT_TYPE_MONSTER_SPELL_LARGE_AREA_DEATH - end - elseif nameType == "physical" then - if incomingLua.radius <= smallAreaRadius then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_SMALL_AREA_HIT - else - return SOUND_EFFECT_TYPE_MONSTER_SPELL_LARGE_AREA_HIT - end - end - - -- Since all failed, im assuming its a single target spell - else - if nameType == "bleeding" then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_SINGLE_TARGET_BLEEDING - elseif nameType == "energy" then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_SINGLE_TARGET_ENERGY - elseif nameType == "earth" then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_SINGLE_TARGET_EARTH - elseif nameType == "fire" then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_SINGLE_TARGET_FIRE - elseif nameType == "lifedrain" then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_SINGLE_TARGET_LIFEDRAIN - elseif nameType == "manadrain" then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_SINGLE_TARGET_MANADRAIN - elseif nameType == "healing" then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_SINGLE_TARGET_HEALING - elseif nameType == "drown" then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_SINGLE_TARGET_DROWNING - elseif nameType == "ice" then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_SINGLE_TARGET_ICE - elseif nameType == "holy" then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_SINGLE_TARGET_HOLY - elseif nameType == "death" then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_SINGLE_TARGET_DEATH - elseif nameType == "physical" then - return SOUND_EFFECT_TYPE_MONSTER_SPELL_SINGLE_TARGET_HIT - end - end - - return SOUND_EFFECT_TYPE_SILENCE -end - -local function loadSpellSoundType(incomingLua, mtype) - local castSound, impactSound = SOUND_EFFECT_TYPE_SILENCE, SOUND_EFFECT_TYPE_MONSTER_CLOSE_ATK_FIST - - -- Shoot effect - if incomingLua.shootEffect ~= nil then - castSound = loadcastSound(incomingLua.shootEffect, incomingLua, mtype) - end - - impactSound = loadImpactSound(incomingLua, mtype) - return { cast = castSound, impact = impactSound } -end - -function readSpell(incomingLua, mtype) - local hasCastSound, hasImpactSound = false, false - local spell = MonsterSpell() - if incomingLua.name then - if incomingLua.name == "melee" then - spell:setType("melee") - if incomingLua.attack and incomingLua.skill then - spell:setAttackValue(incomingLua.attack, incomingLua.skill) - end - if incomingLua.minDamage and incomingLua.maxDamage then - spell:setCombatValue(incomingLua.minDamage, incomingLua.maxDamage) - end - if incomingLua.interval then - spell:setInterval(incomingLua.interval) - end - if incomingLua.effect then - spell:setCombatEffect(incomingLua.effect) - end - if incomingLua.soundCast then - spell:castSound(incomingLua.soundCast) - hasCastSound = true - end - if incomingLua.impactCast then - spell:impactSound(incomingLua.impactCast) - hasImpactSound = true - end - else - spell:setType(incomingLua.name) - if incomingLua.type then - if incomingLua.name == "combat" then - spell:setCombatType(incomingLua.type) - elseif incomingLua.name == "condition" then - spell:setConditionType(incomingLua.type) - else - logger.warn("[readSpell] - Monster {}: Loading spell {}. Parameter type applies only for condition and combat.", mtype:name(), incomingLua.name) - end - end - if incomingLua.interval then - spell:setInterval(incomingLua.interval) - end - if incomingLua.chance then - spell:setChance(incomingLua.chance) - end - if incomingLua.range then - spell:setRange(incomingLua.range) - end - if incomingLua.duration then - spell:setConditionDuration(incomingLua.duration) - end - if incomingLua.speedChange then - spell:setConditionSpeedChange(incomingLua.speedChange) - end - if incomingLua.target then - spell:setNeedTarget(incomingLua.target) - end - if incomingLua.length then - spell:setCombatLength(incomingLua.length) - end - if incomingLua.spread then - spell:setCombatSpread(incomingLua.spread) - end - if incomingLua.radius then - spell:setCombatRadius(incomingLua.radius) - end - if incomingLua.outfitMonster then - spell:setOutfitMonster(incomingLua.outfitMonster) - end - if incomingLua.outfitItem then - spell:setOutfitItem(incomingLua.outfitItem) - end - if incomingLua.soundCast then - spell:castSound(incomingLua.soundCast) - hasCastSound = true - end - if incomingLua.impactCast then - spell:impactSound(incomingLua.impactCast) - hasImpactSound = true - end - if incomingLua.minDamage and incomingLua.maxDamage then - if incomingLua.name == "combat" or Spell(incomingLua.name) then - spell:setCombatValue(incomingLua.minDamage, incomingLua.maxDamage) - else - local startDamage = 0 - if incomingLua.startDamage then - startDamage = incomingLua.startDamage - end - spell:setConditionDamage(incomingLua.minDamage, incomingLua.maxDamage, startDamage) - end - end - if incomingLua.effect then - spell:setCombatEffect(incomingLua.effect) - end - if incomingLua.shootEffect then - spell:setCombatShootEffect(incomingLua.shootEffect) - end - end - - -- This is for a complex spell, that has combat damage AND some condition - -- For example scorpions, which attack and cause poison on attack - if incomingLua.condition then - if incomingLua.condition.type then - spell:setConditionType(incomingLua.condition.type) - end - if incomingLua.condition.duration then - spell:setConditionDuration(incomingLua.condition.duration) - end - if incomingLua.condition.interval then - spell:setConditionTickInterval(incomingLua.condition.interval) - end - - spell:setConditionDamage(incomingLua.condition.totalDamage, incomingLua.condition.totalDamage, 0) - end - elseif incomingLua.script then - spell:setScriptName("monster/" .. incomingLua.script .. ".lua") - if incomingLua.interval then - spell:setInterval(incomingLua.interval) - end - if incomingLua.chance then - spell:setChance(incomingLua.chance) - end - if incomingLua.minDamage and incomingLua.maxDamage then - spell:setCombatValue(incomingLua.minDamage, incomingLua.maxDamage) - end - if incomingLua.target then - spell:setNeedTarget(incomingLua.target) - end - if incomingLua.soundCast then - spell:castSound(incomingLua.soundCast) - hasCastSound = true - end - if incomingLua.impactCast then - spell:impactSound(incomingLua.impactCast) - hasImpactSound = true - end - end - - if not hasImpactSound or not hasCastSound then - local sounds = loadSpellSoundType(incomingLua, mtype) - if not hasCastSound and sounds.cast ~= SOUND_EFFECT_TYPE_SILENCE then - spell:castSound(sounds.cast) - end - if not hasImpactSound and sounds.impact ~= SOUND_EFFECT_TYPE_SILENCE then - spell:castSound(sounds.impact) - end - end - return spell -end diff --git a/data-canary/scripts/lib/register_spells.lua b/data-canary/scripts/lib/register_spells.lua deleted file mode 100644 index 6871ecc5651..00000000000 --- a/data-canary/scripts/lib/register_spells.lua +++ /dev/null @@ -1,515 +0,0 @@ ---Pre-made areas ---Waves -AREA_SHORTWAVE3 = { - { 1, 1, 1 }, - { 1, 1, 1 }, - { 0, 3, 0 }, -} - -AREA_WAVE10 = { - { 1, 1, 1, 1, 1, 1, 1 }, - { 0, 1, 1, 1, 1, 1, 0 }, - { 0, 1, 1, 1, 1, 1, 0 }, - { 0, 1, 1, 1, 1, 1, 0 }, - { 0, 0, 1, 1, 1, 0, 0 }, - { 0, 0, 1, 1, 1, 0, 0 }, - { 0, 0, 1, 1, 1, 0, 0 }, - { 0, 0, 0, 3, 0, 0, 0 }, -} - -AREA_WAVE11 = { - { 1, 1, 1, 1, 1, 1, 1 }, - { 0, 1, 1, 1, 1, 1, 0 }, - { 0, 1, 1, 1, 1, 1, 0 }, - { 0, 1, 1, 1, 1, 1, 0 }, - { 0, 0, 1, 1, 1, 0, 0 }, - { 0, 0, 1, 1, 1, 0, 0 }, - { 0, 0, 1, 1, 1, 0, 0 }, - { 0, 0, 0, 1, 0, 0, 0 }, - { 0, 0, 0, 3, 0, 0, 0 }, -} - -AREA_WAVE12 = { - { 0, 1, 1, 1, 1, 1, 0 }, - { 0, 1, 1, 1, 1, 1, 0 }, - { 0, 1, 1, 1, 1, 1, 0 }, - { 0, 0, 1, 1, 1, 0, 0 }, - { 0, 0, 1, 1, 1, 0, 0 }, - { 0, 0, 1, 1, 1, 0, 0 }, - { 0, 0, 0, 1, 0, 0, 0 }, - { 0, 0, 0, 3, 0, 0, 0 }, -} - -AREA_WAVE13 = { - { 1, 1, 1, 1, 1, 1, 1 }, - { 1, 1, 1, 1, 1, 1, 1 }, - { 0, 1, 1, 1, 1, 1, 0 }, - { 0, 1, 1, 1, 1, 1, 0 }, - { 0, 1, 1, 1, 1, 1, 0 }, - { 0, 0, 1, 1, 1, 0, 0 }, - { 0, 0, 1, 1, 1, 0, 0 }, - { 0, 0, 1, 1, 1, 0, 0 }, - { 0, 0, 0, 1, 0, 0, 0 }, - { 0, 0, 0, 3, 0, 0, 0 }, -} - -AREA_WAVE4 = { - { 1, 1, 1, 1, 1 }, - { 0, 1, 1, 1, 0 }, - { 0, 1, 1, 1, 0 }, - { 0, 0, 3, 0, 0 }, -} - -AREA_WAVE5 = { - { 1, 1, 1, 1, 1 }, - { 0, 1, 1, 1, 0 }, - { 0, 1, 1, 1, 0 }, - { 0, 1, 1, 1, 0 }, - { 0, 0, 1, 0, 0 }, - { 0, 0, 3, 0, 0 }, -} - -AREA_WAVE6 = { - { 0, 0, 0, 0, 0 }, - { 0, 1, 3, 1, 0 }, - { 0, 0, 0, 0, 0 }, -} - -AREA_WAVE7 = { - { 1, 1, 1, 1, 1 }, - { 1, 1, 1, 1, 1 }, - { 0, 1, 1, 1, 0 }, - { 0, 1, 1, 1, 0 }, - { 0, 0, 3, 0, 0 }, -} - -AREA_SQUAREWAVE5 = { - { 1, 1, 1 }, - { 1, 1, 1 }, - { 1, 1, 1 }, - { 0, 1, 0 }, - { 0, 3, 0 }, -} - -AREA_SQUAREWAVE6 = { - { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 }, - { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 }, - { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 }, - { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, - { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, - { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, - { 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0 }, - { 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0 }, -} - -AREA_SQUAREWAVE7 = { - { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, - { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, - { 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0 }, - { 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0 }, - { 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0 }, - { 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0 }, -} - ---Diagonal waves -AREADIAGONAL_WAVE4 = { - { 0, 0, 0, 0, 1, 0 }, - { 0, 0, 0, 1, 1, 0 }, - { 0, 0, 1, 1, 1, 0 }, - { 0, 1, 1, 1, 1, 0 }, - { 1, 1, 1, 1, 1, 0 }, - { 0, 0, 0, 0, 0, 3 }, -} - -AREADIAGONAL_SQUAREWAVE5 = { - { 1, 1, 1, 0, 0 }, - { 1, 1, 1, 0, 0 }, - { 1, 1, 1, 0, 0 }, - { 0, 0, 0, 1, 0 }, - { 0, 0, 0, 0, 3 }, -} - -AREADIAGONAL_WAVE6 = { - { 0, 0, 1 }, - { 0, 3, 0 }, - { 1, 0, 0 }, -} - -AREADIAGONAL_WAVE7 = { - { 0, 0, 0, 0, 0, 1, 0 }, - { 0, 0, 0, 0, 1, 1, 0 }, - { 0, 0, 0, 1, 1, 1, 0 }, - { 0, 0, 1, 1, 1, 1, 0 }, - { 0, 1, 1, 1, 1, 1, 0 }, - { 1, 1, 1, 1, 1, 1, 0 }, - { 0, 0, 0, 0, 0, 0, 3 }, -} - ---Beams -AREA_BEAM1 = { - { 3 }, -} - -AREA_BEAM5 = { - { 1 }, - { 1 }, - { 1 }, - { 1 }, - { 3 }, -} - -AREA_BEAM6 = { - { 1 }, - { 1 }, - { 1 }, - { 1 }, - { 1 }, - { 3 }, -} - -AREA_BEAM7 = { - { 1 }, - { 1 }, - { 1 }, - { 1 }, - { 1 }, - { 1 }, - { 3 }, -} - -AREA_BEAM8 = { - { 1 }, - { 1 }, - { 1 }, - { 1 }, - { 1 }, - { 1 }, - { 1 }, - { 3 }, -} - -AREA_BEAM10 = { - { 1 }, - { 1 }, - { 1 }, - { 1 }, - { 1 }, - { 1 }, - { 1 }, - { 1 }, - { 1 }, - { 3 }, -} - ---Diagonal Beams -AREADIAGONAL_BEAM5 = { - { 1, 0, 0, 0, 0 }, - { 0, 1, 0, 0, 0 }, - { 0, 0, 1, 0, 0 }, - { 0, 0, 0, 1, 0 }, - { 0, 0, 0, 0, 3 }, -} - -AREADIAGONAL_BEAM7 = { - { 1, 0, 0, 0, 0, 0, 0 }, - { 0, 1, 0, 0, 0, 0, 0 }, - { 0, 0, 1, 0, 0, 0, 0 }, - { 0, 0, 0, 1, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, 0 }, - { 0, 0, 0, 0, 0, 1, 0 }, - { 0, 0, 0, 0, 0, 0, 3 }, -} - ---Circles -AREA_CIRCLE2X2 = { - { 0, 1, 1, 1, 0 }, - { 1, 1, 1, 1, 1 }, - { 1, 1, 3, 1, 1 }, - { 1, 1, 1, 1, 1 }, - { 0, 1, 1, 1, 0 }, -} - -AREA_CIRCLE3X3 = { - { 0, 0, 1, 1, 1, 0, 0 }, - { 0, 1, 1, 1, 1, 1, 0 }, - { 1, 1, 1, 1, 1, 1, 1 }, - { 1, 1, 1, 3, 1, 1, 1 }, - { 1, 1, 1, 1, 1, 1, 1 }, - { 0, 1, 1, 1, 1, 1, 0 }, - { 0, 0, 1, 1, 1, 0, 0 }, -} - -AREA_CIRCLE3X32 = { - { 1, 1, 1, 1, 1, 1, 1 }, - { 1, 1, 1, 1, 1, 1, 1 }, - { 1, 1, 1, 1, 1, 1, 1 }, - { 1, 1, 1, 3, 1, 1, 1 }, - { 1, 1, 1, 1, 1, 1, 1 }, - { 1, 1, 1, 1, 1, 1, 1 }, - { 1, 1, 1, 1, 1, 1, 1 }, -} - -AREA_CIRCLE3X33 = { - { 1, 1, 1, 1, 1, 1, 1 }, - { 1, 1, 1, 1, 1, 1, 1 }, - { 1, 1, 0, 0, 1, 1, 1 }, - { 1, 1, 0, 3, 1, 1, 1 }, - { 1, 1, 0, 1, 1, 1, 1 }, - { 1, 1, 1, 1, 1, 1, 1 }, - { 1, 1, 1, 1, 1, 1, 1 }, -} - --- Crosses -AREA_CIRCLE1X1 = { - { 0, 1, 0 }, - { 1, 3, 1 }, - { 0, 1, 0 }, -} - -AREA_CIRCLE5X5 = { - { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0 }, - { 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0 }, - { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, - { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 }, - { 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1 }, - { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 }, - { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, - { 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, -} - -AREA_CIRCLE5X5V2 = { - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0 }, - { 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0 }, - { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, - { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 }, - { 0, 1, 1, 1, 1, 3, 1, 1, 1, 1, 0 }, - { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 }, - { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, - { 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, -} - -AREA_CIRCLE6X6 = { - { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, - { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 }, - { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, - { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 }, - { 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1 }, - { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 }, - { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, - { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, -} - ---Squares -AREA_SQUARE1X1 = { - { 1, 1, 1 }, - { 1, 3, 1 }, - { 1, 1, 1 }, -} - --- Walls -AREA_WALLFIELD = { - { 1, 1, 3, 1, 1 }, -} - -AREADIAGONAL_WALLFIELD = { - { 0, 0, 0, 0, 1 }, - { 0, 0, 0, 1, 1 }, - { 0, 1, 3, 1, 0 }, - { 1, 1, 0, 0, 0 }, - { 1, 0, 0, 0, 0 }, -} - --- Walls Energy -AREA_WALLFIELD_ENERGY = { - { 1, 1, 1, 3, 1, 1, 1 }, -} - -AREADIAGONAL_WALLFIELD_ENERGY = { - { 0, 0, 0, 0, 0, 0, 1 }, - { 0, 0, 0, 0, 0, 1, 1 }, - { 0, 0, 0, 0, 1, 1, 0 }, - { 0, 0, 1, 3, 1, 0, 0 }, - { 0, 1, 1, 0, 0, 0, 0 }, - { 0, 1, 0, 0, 0, 0, 0 }, - { 1, 0, 0, 0, 0, 0, 0 }, -} - -AREA_RING1_BURST3 = { - { 0, 0, 0, 1, 1, 1, 0, 0, 0 }, - { 0, 0, 1, 1, 1, 1, 1, 0, 0 }, - { 0, 1, 1, 1, 1, 1, 1, 1, 0 }, - { 1, 1, 1, 0, 0, 0, 1, 1, 1 }, - { 1, 1, 1, 0, 3, 0, 1, 1, 1 }, - { 1, 1, 1, 0, 0, 0, 1, 1, 1 }, - { 0, 1, 1, 1, 1, 1, 1, 1, 0 }, - { 0, 0, 1, 1, 1, 1, 1, 0, 0 }, - { 0, 0, 0, 1, 1, 1, 0, 0, 0 }, -} - --- The numbered-keys represents the damage values, and their table --- contains the minimum and maximum number of rounds of those damage values. -RANGE = { - [1] = { 19, 20 }, - [2] = { 10, 10 }, - [3] = { 6, 7 }, - [4] = { 4, 5 }, - [5] = { 3, 4 }, - [6] = { 3, 4 }, - [7] = { 2, 3 }, - [8] = { 2, 3 }, - [9] = { 2, 3 }, - [10] = { 1, 2 }, - [11] = { 1, 2 }, - [12] = { 1, 2 }, - [13] = { 1, 2 }, - [14] = { 1, 2 }, - [15] = { 1, 2 }, - [16] = { 1, 2 }, - [17] = { 1, 2 }, - [18] = { 1, 2 }, - [19] = { 1, 2 }, -} - -function Creature:addDamageCondition(target, conditionType, listType, damage, time, rounds) - if target:isImmune(conditionType) then - return false - end - - local condition = Condition(conditionType) - condition:setParameter(CONDITION_PARAM_OWNER, self:getId()) - condition:setParameter(CONDITION_PARAM_DELAYED, true) - - if listType == 0 then - local exponent, value = -10, 0 - while value < damage do - value = math.floor(10 * math.pow(1.2, exponent) + 0.5) - condition:addDamage(1, time or 4000, -value) - - if value >= damage then - local permille = math.random(10, 1200) / 1000 - condition:addDamage(1, time or 4000, -math.max(1, math.floor(value * permille + 0.5))) - else - exponent = exponent + 1 - end - end - elseif listType == 1 then - rounds = rounds or RANGE - if rounds[damage] then - condition:addDamage(math.random(1, rounds[damage][2]), time or 4000, -damage) - damage = damage - 1 - end - - while damage > 0 do - condition:addDamage(rounds[damage] and math.random(rounds[damage][1], rounds[damage][2]) or 1, time or 4000, -damage) - damage = damage - (damage > 21 and math.floor(damage / 20) + math.random(0, 1) or 1) - end - elseif listType == 2 then - for _ = 1, rounds do - condition:addDamage(1, math.random(time[1], time[2]) * 1000, -damage) - end - end - - target:addCondition(condition) - return true -end - -function Player:addPartyCondition(combat, variant, condition, baseMana) - local party = self:getParty() - if not party then - self:sendCancelMessage(RETURNVALUE_NOPARTYMEMBERSINRANGE) - self:getPosition():sendMagicEffect(CONST_ME_POFF) - return false - end - - local members = party:getMembers() - members[#members + 1] = party:getLeader() - - local position = self:getPosition() - local affectedMembers = {} - for _, member in ipairs(members) do - if member:getPosition():getDistance(position) <= 36 then - affectedMembers[#affectedMembers + 1] = member - end - end - - if #affectedMembers <= 1 then - self:sendCancelMessage(RETURNVALUE_NOPARTYMEMBERSINRANGE) - position:sendMagicEffect(CONST_ME_POFF) - return false - end - - local mana = math.ceil(math.pow(0.9, #affectedMembers - 1) * baseMana * #affectedMembers) - if self:getMana() < mana then - self:sendCancelMessage(RETURNVALUE_NOTENOUGHMANA) - position:sendMagicEffect(CONST_ME_POFF) - return false - end - - if not combat:execute(self, variant) then - self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) - position:sendMagicEffect(CONST_ME_POFF) - return false - end - - self:addMana(baseMana - mana, false) - self:addManaSpent(mana - baseMana) - - for _, member in ipairs(affectedMembers) do - member:addCondition(condition) - end - return true -end - -function Player:conjureItem(reagentId, conjureId, conjureCount, effect) - if not conjureCount and conjureId ~= 0 then - local itemType = ItemType(conjureId) - if itemType:getId() == 0 then - return false - end - - local charges = itemType:getCharges() - if charges ~= 0 then - conjureCount = charges - end - end - - if reagentId ~= 0 and not self:removeItem(reagentId, 1, -1) then - self:sendCancelMessage(RETURNVALUE_YOUNEEDAMAGICITEMTOCASTSPELL) - self:getPosition():sendMagicEffect(CONST_ME_POFF) - return false - end - - local item = self:addItem(conjureId, conjureCount) - if not item then - self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) - self:getPosition():sendMagicEffect(CONST_ME_POFF) - return false - end - - if item:hasAttribute(ITEM_ATTRIBUTE_DURATION) then - item:decay() - end - - self:getPosition():sendMagicEffect(item:getType():isRune() and CONST_ME_MAGIC_RED or effect) - return true -end diff --git a/data-canary/scripts/lib/talkactions.lua b/data-canary/scripts/lib/talkactions.lua deleted file mode 100644 index c962dd417ae..00000000000 --- a/data-canary/scripts/lib/talkactions.lua +++ /dev/null @@ -1,12 +0,0 @@ -local logFormat = "[%s] %s %s" - -function logCommand(player, words, param) - local file = io.open("data/logs/" .. player:getName() .. " commands.log", "a") - if not file then - return - end - - io.output(file) - io.write(logFormat:format(os.date("%d/%m/%Y %H:%M"), words, param):trim() .. "\n") - io.close(file) -end diff --git a/data-otservbr-global/scripts/lib/create_functions.lua b/data-otservbr-global/scripts/lib/create_functions.lua deleted file mode 100644 index 845b70375c3..00000000000 --- a/data-otservbr-global/scripts/lib/create_functions.lua +++ /dev/null @@ -1,3 +0,0 @@ -createFunctions(MonsterType) -- creates get/set functions for MonsterType -createFunctions(NpcType) -- creates get/set functions for NpcType -createFunctions(Spell) -- creates get/set functions for Spell diff --git a/data-otservbr-global/scripts/lib/defaults_move_event.lua b/data-otservbr-global/scripts/lib/defaults_move_event.lua deleted file mode 100644 index 75191a642dc..00000000000 --- a/data-otservbr-global/scripts/lib/defaults_move_event.lua +++ /dev/null @@ -1,25 +0,0 @@ --- default callbacks - -function defaultStepIn(creature, item, position, fromPosition) - return true -end - -function defaultStepOut(creature, item, position, fromPosition) - return true -end - -function defaultAddItem(moveitem, tileitem, pos) - return true -end - -function defaultRemoveItem(moveitem, tileitem, pos) - return true -end - -function defaultEquip(player, item, slot, isCheck) - return true -end - -function defaultDeEquip(player, item, slot, isCheck) - return true -end diff --git a/data-otservbr-global/scripts/lib/register_bestiary_charm.lua b/data-otservbr-global/scripts/lib/register_bestiary_charm.lua deleted file mode 100644 index c0daffff9f9..00000000000 --- a/data-otservbr-global/scripts/lib/register_bestiary_charm.lua +++ /dev/null @@ -1,83 +0,0 @@ -registerCharm = {} -setmetatable(registerCharm, { - __call = function(self, charm, mask) - for _, parse in pairs(self) do - parse(charm, mask) - end - end, -}) - -Charm.register = function(self, mask) - return registerCharm(self, mask) -end - -registerCharm.name = function(charm, mask) - if mask.name then - charm:name(mask.name) - end -end - -registerCharm.description = function(charm, mask) - if mask.description then - charm:description(mask.description) - end -end - -registerCharm.sounds = function(charm, mask) - if mask.sounds then - if mask.sounds.castSound then - charm:castSound(mask.sounds.castSound) - end - if mask.sounds.impactSound then - charm:impactSound(mask.sounds.impactSound) - end - end -end - -registerCharm.type = function(charm, mask) - if mask.type then - charm:type(mask.type) - end -end - -registerCharm.damageType = function(charm, mask) - if mask.damageType then - charm:damageType(mask.damageType) - end -end - -registerCharm.percent = function(charm, mask) - if mask.percent then - charm:percentage(mask.percent) - end -end - -registerCharm.chance = function(charm, mask) - if mask.chance then - charm:chance(mask.chance) - end -end - -registerCharm.messageCancel = function(charm, mask) - if mask.messageCancel then - charm:messageCancel(mask.messageCancel) - end -end - -registerCharm.messageServerLog = function(charm, mask) - if mask.messageServerLog then - charm:messageServerLog(mask.messageServerLog) - end -end - -registerCharm.effect = function(charm, mask) - if mask.effect then - charm:effect(mask.effect) - end -end - -registerCharm.points = function(charm, mask) - if mask.points then - charm:points(mask.points) - end -end diff --git a/data-otservbr-global/scripts/lib/register_npc_type.lua b/data-otservbr-global/scripts/lib/register_npc_type.lua deleted file mode 100644 index 53a5d525e59..00000000000 --- a/data-otservbr-global/scripts/lib/register_npc_type.lua +++ /dev/null @@ -1,211 +0,0 @@ -registerNpcType = {} -setmetatable(registerNpcType, { - __call = function(self, npcType, mask) - for _, parse in pairs(self) do - parse(npcType, mask) - end - end, -}) - -NpcType.register = function(self, mask) - return registerNpcType(self, mask) -end - -registerNpcType.name = function(npcType, mask) - if mask.name then - npcType:name(mask.name) - end -end - -registerNpcType.description = function(npcType, mask) - if mask.description then - npcType:nameDescription(mask.description) - end -end - -registerNpcType.outfit = function(npcType, mask) - if mask.outfit then - npcType:outfit(mask.outfit) - end -end - -registerNpcType.maxHealth = function(npcType, mask) - if mask.maxHealth then - npcType:maxHealth(mask.maxHealth) - end -end - -registerNpcType.health = function(npcType, mask) - if mask.health then - npcType:health(mask.health) - end -end - -registerNpcType.race = function(npcType, mask) - if mask.race then - npcType:race(mask.race) - end -end - -registerNpcType.walkInterval = function(npcType, mask) - if mask.walkInterval then - npcType:walkInterval(mask.walkInterval) - end -end - -registerNpcType.walkRadius = function(npcType, mask) - if mask.walkRadius then - npcType:walkRadius(mask.walkRadius) - end -end - -registerNpcType.speed = function(npcType, mask) - if mask.speed then - npcType:baseSpeed(mask.speed) - end -end - -registerNpcType.flags = function(npcType, mask) - if mask.flags then - if mask.flags.floorchange ~= nil then - npcType:floorChange(mask.flags.floorchange) - end - if mask.flags.canPushCreatures ~= nil then - npcType:canPushCreatures(mask.flags.canPushCreatures) - end - if mask.flags.canPushItems ~= nil then - npcType:canPushItems(mask.flags.canPushItems) - end - if mask.flags.pushable ~= nil then - npcType:isPushable(mask.flags.pushable) - end - end -end - -registerNpcType.light = function(npcType, mask) - if mask.light then - if mask.light.color then - local color = mask.light.color - end - if mask.light.level then - npcType:light(color, mask.light.level) - end - end -end - -registerNpcType.respawnType = function(npcType, mask) - if mask.respawnType then - if mask.respawnType.period then - npcType:respawnTypePeriod(mask.respawnType.period) - end - if mask.respawnType.underground then - npcType:respawnTypeIsUnderground(mask.respawnType.underground) - end - end -end - -registerNpcType.sounds = function(npcType, mask) - if type(mask.sounds) == "table" then - if mask.sounds.ticks and mask.sounds.chance and mask.sounds.ids and type(mask.sounds.ids) == "table" and #mask.sounds.ids > 0 then - npcType:soundSpeedTicks(mask.sounds.ticks) - npcType:soundChance(mask.sounds.chance) - for _, v in pairs(mask.sounds.ids) do - npcType:addSound(v) - end - end - end -end - -registerNpcType.voices = function(npcType, mask) - if type(mask.voices) == "table" then - local interval, chance - if mask.voices.interval then - interval = mask.voices.interval - end - if mask.voices.chance then - chance = mask.voices.chance - end - for k, v in pairs(mask.voices) do - if type(v) == "table" then - npcType:addVoice(v.text, interval, chance, v.yell) - end - end - end -end - -registerNpcType.events = function(npcType, mask) - if type(mask.events) == "table" then - for k, v in pairs(mask.events) do - npcType:registerEvent(v) - end - end -end - -registerNpcType.shop = function(npcType, mask) - if type(mask.shop) == "table" then - for _, shopItems in pairs(mask.shop) do - local parent = Shop() - if shopItems.itemName or shopItems.itemname then - parent:setNameItem(shopItems.itemName or shopItems.itemname) - end - if shopItems.clientId or shopItems.clientid then - parent:setId(shopItems.clientId or shopItems.clientid) - end - if shopItems.subType or shopItems.subtype or shopItems.count then - parent:setCount(shopItems.subType or shopItems.subtype or shopItems.count) - end - if shopItems.buy then - parent:setBuyPrice(shopItems.buy) - end - if shopItems.sell then - parent:setSellPrice(shopItems.sell) - end - if shopItems.storageKey or shopItems.storagekey then - parent:setStorageKey(shopItems.storageKey or shopItems.storagekey) - end - if shopItems.storageValue or shopItems.storagevalue then - parent:setStorageValue(shopItems.storageValue or shopItems.storagevalue) - end - if shopItems.child then - for _, children in pairs(shopItems.child) do - local child = Shop() - if shopItems.itemName or shopItems.itemname then - child:setNameItem(shopItems.itemName or shopItems.itemname) - end - if shopItems.clientId or shopItems.clientid then - child:setId(shopItems.clientId or shopItems.clientid) - end - if shopItems.subType or shopItems.subtype or shopItems.count then - child:setCount(shopItems.subType or shopItems.subtype or shopItems.count) - end - if shopItems.buy then - child:setBuyPrice(shopItems.buy) - end - if shopItems.sell then - child:setSellPrice(shopItems.sell) - end - if shopItems.storageKey or shopItems.storagekey then - child:setStorageKey(shopItems.storageKey or shopItems.storagekey) - end - if shopItems.storageValue or shopItems.storagevalue then - child:setStorageValue(shopItems.storageValue or shopItems.storagevalue) - end - parent:addChildShop(child) - end - end - npcType:addShopItem(parent) - end - end -end - -registerNpcType.currency = function(npcType, mask) - if mask.currency then - npcType:currency(mask.currency) - end -end - -registerNpcType.speechBubble = function(npcType, mask) - if mask.speechBubble then - npcType:speechBubble(mask.speechBubble) - end -end diff --git a/data/XML/imbuements.xml b/data/XML/imbuements.xml index 74a06dbd9f8..0a2fd90702f 100644 --- a/data/XML/imbuements.xml +++ b/data/XML/imbuements.xml @@ -201,7 +201,7 @@ - + diff --git a/data-canary/scripts/lib/create_functions.lua b/data/scripts/lib/create_functions.lua similarity index 100% rename from data-canary/scripts/lib/create_functions.lua rename to data/scripts/lib/create_functions.lua diff --git a/data-canary/scripts/lib/defaults_move_event.lua b/data/scripts/lib/defaults_move_event.lua similarity index 100% rename from data-canary/scripts/lib/defaults_move_event.lua rename to data/scripts/lib/defaults_move_event.lua diff --git a/data-otservbr-global/scripts/lib/helper_constructors.lua b/data/scripts/lib/helper_constructors.lua similarity index 100% rename from data-otservbr-global/scripts/lib/helper_constructors.lua rename to data/scripts/lib/helper_constructors.lua diff --git a/data-otservbr-global/scripts/lib/register_actions.lua b/data/scripts/lib/register_actions.lua similarity index 100% rename from data-otservbr-global/scripts/lib/register_actions.lua rename to data/scripts/lib/register_actions.lua diff --git a/data-canary/scripts/lib/register_bestiary_charm.lua b/data/scripts/lib/register_bestiary_charm.lua similarity index 100% rename from data-canary/scripts/lib/register_bestiary_charm.lua rename to data/scripts/lib/register_bestiary_charm.lua diff --git a/data-otservbr-global/scripts/lib/register_item_tier.lua b/data/scripts/lib/register_item_tier.lua similarity index 100% rename from data-otservbr-global/scripts/lib/register_item_tier.lua rename to data/scripts/lib/register_item_tier.lua diff --git a/data-otservbr-global/scripts/lib/register_lever_tables.lua b/data/scripts/lib/register_lever_tables.lua similarity index 100% rename from data-otservbr-global/scripts/lib/register_lever_tables.lua rename to data/scripts/lib/register_lever_tables.lua diff --git a/data-otservbr-global/scripts/lib/register_migrations.lua b/data/scripts/lib/register_migrations.lua similarity index 100% rename from data-otservbr-global/scripts/lib/register_migrations.lua rename to data/scripts/lib/register_migrations.lua diff --git a/data-otservbr-global/scripts/lib/register_monster_type.lua b/data/scripts/lib/register_monster_type.lua similarity index 99% rename from data-otservbr-global/scripts/lib/register_monster_type.lua rename to data/scripts/lib/register_monster_type.lua index c62ca0281d7..cf115a3af05 100644 --- a/data-otservbr-global/scripts/lib/register_monster_type.lua +++ b/data/scripts/lib/register_monster_type.lua @@ -547,6 +547,9 @@ registerMonsterType.defenses = function(mtype, mask) if mask.defenses.armor then mtype:armor(mask.defenses.armor) end + if mask.defenses.mitigation then + mtype:mitigation(mask.defenses.mitigation) + end for _, defense in pairs(mask.defenses) do if type(defense) == "table" then mtype:addDefense(readSpell(defense, mtype)) diff --git a/data-canary/scripts/lib/register_npc_type.lua b/data/scripts/lib/register_npc_type.lua similarity index 100% rename from data-canary/scripts/lib/register_npc_type.lua rename to data/scripts/lib/register_npc_type.lua diff --git a/data-otservbr-global/scripts/lib/register_spells.lua b/data/scripts/lib/register_spells.lua similarity index 100% rename from data-otservbr-global/scripts/lib/register_spells.lua rename to data/scripts/lib/register_spells.lua diff --git a/data-otservbr-global/scripts/lib/shops.lua b/data/scripts/lib/shops.lua similarity index 100% rename from data-otservbr-global/scripts/lib/shops.lua rename to data/scripts/lib/shops.lua diff --git a/src/canary_server.cpp b/src/canary_server.cpp index 9e13e8b05fd..1a2454a9ad0 100644 --- a/src/canary_server.cpp +++ b/src/canary_server.cpp @@ -349,7 +349,8 @@ void CanaryServer::loadModules() { logger.debug("Loading core scripts on folder: {}/", coreFolder); // Load first core Lua libs modulesLoadHelper((g_luaEnvironment().loadFile(coreFolder + "/core.lua", "core.lua") == 0), "core.lua"); - modulesLoadHelper(g_scripts().loadScripts(coreFolder + "/scripts", false, false), "/data/scripts"); + modulesLoadHelper(g_scripts().loadScripts(coreFolder + "/scripts/lib", true, false), coreFolder + "/scripts/libs"); + modulesLoadHelper(g_scripts().loadScripts(coreFolder + "/scripts", false, false), coreFolder + "/scripts"); // Second XML scripts modulesLoadHelper(g_vocations().loadFromXml(), "XML/vocations.xml"); @@ -363,7 +364,6 @@ void CanaryServer::loadModules() { modulesLoadHelper((g_npcs().load(true, false)), "npclib"); logger.debug("Loading datapack scripts on folder: {}/", datapackName); - modulesLoadHelper(g_scripts().loadScripts(datapackFolder + "/scripts/lib", true, false), datapackFolder + "/scripts/libs"); // Load scripts modulesLoadHelper(g_scripts().loadScripts(datapackFolder + "/scripts", false, false), datapackFolder + "/scripts"); // Load monsters diff --git a/src/creatures/npcs/npc.cpp b/src/creatures/npcs/npc.cpp index 5602f145807..7fe61491efd 100644 --- a/src/creatures/npcs/npc.cpp +++ b/src/creatures/npcs/npc.cpp @@ -405,24 +405,23 @@ void Npc::onPlayerSellItem(std::shared_ptr player, uint16_t itemId, uint } } - if (toRemove != 0) { - g_logger().error("[Npc::onPlayerSellItem] - Problem while removing items from player {} amount {} of items with id {} on shop for npc {}, the payment will be made based on amount of removed items.", player->getName(), toRemove, itemId, getName()); - } - auto totalRemoved = amount - toRemove; auto totalCost = static_cast(sellPrice * totalRemoved); - if (getCurrency() == ITEM_GOLD_COIN) { - totalPrice += totalCost; - if (g_configManager().getBoolean(AUTOBANK, __FUNCTION__)) { - player->setBankBalance(player->getBankBalance() + totalCost); + g_logger().debug("[Npc::onPlayerSellItem] - Removing items from player {} amount {} of items with id {} on shop for npc {}", player->getName(), toRemove, itemId, getName()); + if (totalRemoved > 0 && totalCost > 0) { + if (getCurrency() == ITEM_GOLD_COIN) { + totalPrice += totalCost; + if (g_configManager().getBoolean(AUTOBANK, __FUNCTION__)) { + player->setBankBalance(player->getBankBalance() + totalCost); + } else { + g_game().addMoney(player, totalCost); + } + g_metrics().addCounter("balance_increase", totalCost, { { "player", player->getName() }, { "context", "npc_sale" } }); } else { - g_game().addMoney(player, totalCost); - } - g_metrics().addCounter("balance_increase", totalCost, { { "player", player->getName() }, { "context", "npc_sale" } }); - } else { - std::shared_ptr newItem = Item::CreateItem(getCurrency(), totalCost); - if (newItem) { - g_game().internalPlayerAddItem(player, newItem, true); + std::shared_ptr newItem = Item::CreateItem(getCurrency(), totalCost); + if (newItem) { + g_game().internalPlayerAddItem(player, newItem, true); + } } } diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp index 9a2e04af8b4..0a02122ff26 100644 --- a/src/creatures/players/player.cpp +++ b/src/creatures/players/player.cpp @@ -7023,6 +7023,11 @@ bool Player::saySpell( // Forge system void Player::forgeFuseItems(ForgeAction_t actionType, uint16_t firstItemId, uint8_t tier, uint16_t secondItemId, bool success, bool reduceTierLoss, bool convergence, uint8_t bonus, uint8_t coreCount) { + if (getFreeBackpackSlots() == 0) { + sendCancelMessage(RETURNVALUE_NOTENOUGHROOM); + return; + } + ForgeHistory history; history.actionType = actionType; history.tier = tier; @@ -7261,6 +7266,11 @@ void Player::forgeFuseItems(ForgeAction_t actionType, uint16_t firstItemId, uint } void Player::forgeTransferItemTier(ForgeAction_t actionType, uint16_t donorItemId, uint8_t tier, uint16_t receiveItemId, bool convergence) { + if (getFreeBackpackSlots() == 0) { + sendCancelMessage(RETURNVALUE_NOTENOUGHROOM); + return; + } + ForgeHistory history; history.actionType = actionType; history.tier = tier; diff --git a/src/game/game.cpp b/src/game/game.cpp index 397695f822f..f1d02f38bd2 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -2152,11 +2152,23 @@ std::tuple Game::addItemBatch(const std::shared } if (!dropping) { uint32_t remainderCount = 0; - ret = internalCollectManagedItems(player, item, g_game().getObjectCategory(item), false); - // If cannot place it in the obtain containers, will add it normally - if (ret != RETURNVALUE_NOERROR) { + bool addedToAutoContainer = false; + // First, try adding to the autoContainer, if it is set + if (autoContainerId != 0) { ret = internalAddItem(destination, item, CONST_SLOT_WHEREEVER, flags, false, remainderCount); + if (ret == RETURNVALUE_NOERROR) { + addedToAutoContainer = true; + } + } + // If it failed to add to the autoContainer, or it's not set, use the current logic + if (!addedToAutoContainer) { + ret = internalCollectManagedItems(player, item, g_game().getObjectCategory(item), false); + // If it can't place in the player's backpacks, add normally + if (ret != RETURNVALUE_NOERROR) { + ret = internalAddItem(destination, item, CONST_SLOT_WHEREEVER, flags, false, remainderCount); + } } + if (remainderCount != 0) { std::shared_ptr remainderItem = Item::CreateItem(item->getID(), remainderCount); ReturnValue remaindRet = internalAddItem(destination->getTile(), remainderItem, INDEX_WHEREEVER, FLAG_NOLIMIT); @@ -3068,6 +3080,11 @@ void Game::playerEquipItem(uint32_t playerId, uint16_t itemId, bool hasTier /* = return; } + if (player->getFreeBackpackSlots() == 0) { + player->sendCancelMessage(RETURNVALUE_NOTENOUGHROOM); + return; + } + const ItemType &it = Item::items[itemId]; Slots_t slot = getSlotType(it); @@ -3075,6 +3092,7 @@ void Game::playerEquipItem(uint32_t playerId, uint16_t itemId, bool hasTier /* = auto equipItem = searchForItem(backpack, it.id, hasTier, tier); if (slotItem && slotItem->getID() == it.id && (!it.stackable || slotItem->getItemCount() == slotItem->getStackSize() || !equipItem)) { internalMoveItem(slotItem->getParent(), player, CONST_SLOT_WHEREEVER, slotItem, slotItem->getItemCount(), nullptr); + g_logger().debug("Item {} was unequipped", slotItem->getName()); } else if (equipItem) { if (it.weaponType == WEAPON_AMMO) { auto quiver = player->getInventoryItem(CONST_SLOT_RIGHT); @@ -3084,7 +3102,15 @@ void Game::playerEquipItem(uint32_t playerId, uint16_t itemId, bool hasTier /* = } } - internalMoveItem(equipItem->getParent(), player, slot, equipItem, equipItem->getItemCount(), nullptr); + if (slotItem) { + internalMoveItem(slotItem->getParent(), player, INDEX_WHEREEVER, slotItem, slotItem->getItemCount(), nullptr); + g_logger().debug("Item {} was moved back to player", slotItem->getName()); + } + + auto ret = internalMoveItem(equipItem->getParent(), player, slot, equipItem, equipItem->getItemCount(), nullptr); + if (ret == RETURNVALUE_NOERROR) { + g_logger().debug("Item {} was equipped", equipItem->getName()); + } } }