Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5,854 changes: 5,263 additions & 591 deletions data/cpplinter.lua

Large diffs are not rendered by default.

321 changes: 319 additions & 2 deletions data/lib/compat/compat.lua

Large diffs are not rendered by default.

55 changes: 54 additions & 1 deletion data/lib/core/achievements.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ Storages:
(Ex: this storage + the id of achievement 'Allowance Collector' to save how many piggy banks has been broken
]]

---@class AchievementInfo
---@field clientId number
---@field name string
---@field grade number
---@field points number
---@field secret? boolean
---@field description string

---@type table<number, AchievementInfo>
achievements = {
-- 8.6
[1] = {clientId = 60, name = "Allow Cookies?", grade = 1, points = 2, description = "With a perfectly harmless smile you fooled all of those wisecrackers into eating your exploding cookies. Consider a boy or girl scout outfit next time to make the trick even better."},
Expand Down Expand Up @@ -618,6 +627,9 @@ achievements = {
ACHIEVEMENT_FIRST = 1
ACHIEVEMENT_LAST = #achievements

---Returns the achievement info table using the achievement ID.
---@param id number
---@return AchievementInfo|boolean
function getAchievementInfoById(id)
for k, v in pairs(achievements) do
if k == id then
Expand Down Expand Up @@ -687,9 +699,14 @@ function isAchievementSecret(ach)
return achievement.secret
end

---Checks if a player has a specific achievement, either by the ID or the name.
---@param self Player
---@param ach number|string
---@return boolean
function Player.hasAchievement(self, ach)
local achievement
if tonumber(ach) then
---@diagnostic disable-next-line: param-type-mismatch
achievement = getAchievementInfoById(ach)
else
achievement = getAchievementInfoByName(ach)
Expand All @@ -702,6 +719,9 @@ function Player.hasAchievement(self, ach)
return self:getStorageValue(PlayerStorageKeys.achievementsBase + achievement.id) > 0
end

---Returns a table of all achievements the player has.
---@param self Player
---@return table
function Player.getAchievements(self)
local targetAchievement = {}
for k = 1, #achievements do
Expand All @@ -712,9 +732,15 @@ function Player.getAchievements(self)
return targetAchievement
end

---Adds an achievement to the player. If the achievement is already owned, it does nothing.
---@param self Player
---@param ach number|string
---@param hideMsg boolean|nil
---@return boolean
function Player.addAchievement(self, ach, hideMsg)
local achievement
if tonumber(ach) then
---@diagnostic disable-next-line: param-type-mismatch
achievement = getAchievementInfoById(ach)
else
achievement = getAchievementInfoByName(ach)
Expand All @@ -740,9 +766,14 @@ function Player.addAchievement(self, ach, hideMsg)
return true
end

---Removes an achievement from the player. If the achievement is not owned, it does nothing.
---@param self Player
---@param ach number|string
---@return boolean
function Player.removeAchievement(self, ach)
local achievement
if tonumber(ach) then
---@diagnostic disable-next-line: param-type-mismatch
achievement = getAchievementInfoById(ach)
else
achievement = getAchievementInfoByName(ach)
Expand All @@ -762,13 +793,20 @@ function Player.removeAchievement(self, ach)
return true
end

---Adds all achievements to the player
---@param self Player
---@param hideMsg boolean
---@return boolean
function Player.addAllAchievements(self, hideMsg)
for i = ACHIEVEMENT_FIRST, ACHIEVEMENT_LAST do
self:addAchievement(i, hideMsg)
end
return true
end

---Removes all achievements from the player
---@param self Player
---@return boolean
function Player.removeAllAchievements(self)
for k = 1, #achievements do
if self:hasAchievement(k) then
Expand All @@ -778,6 +816,9 @@ function Player.removeAllAchievements(self)
return true
end

---Returns a table of all secret achievements the player has.
---@param self Player
---@return table
function Player.getSecretAchievements(self)
local targetAchievement = {}
for k, v in pairs(achievements) do
Expand All @@ -788,6 +829,9 @@ function Player.getSecretAchievements(self)
return targetAchievement
end

---Returns a table of all achievements that are not secret the player has.
---@param self Player
---@return table
function Player.getPublicAchievements(self)
local targetAchievement = {}
for k, v in pairs(achievements) do
Expand All @@ -798,21 +842,30 @@ function Player.getPublicAchievements(self)
return targetAchievement
end

---Returns the total amount of achievement points the player has.
---@param self Player
---@return integer
function Player.getAchievementPoints(self)
local points = 0
local list = self:getAchievements()
if #list > 0 then -- has achievements
for i = 1, #list do
local targetAchievement = getAchievementInfoById(list[i])
if targetAchievement.points > 0 then -- avoid achievements with unknow points
if targetAchievement and targetAchievement.points > 0 then -- avoid achievements with unknown points
points = points + targetAchievement.points
end
end
end
return points
end

---Adds progress to an achievement. If the progress is equal to the value, it will add the achievement.
---@param self Player
---@param ach number|string
---@param value number
---@return boolean
function Player.addAchievementProgress(self, ach, value)
---@diagnostic disable-next-line: param-type-mismatch
local achievement = tonumber(ach) and getAchievementInfoById(ach) or getAchievementInfoByName(ach)
if not achievement then
print('[!] -> Invalid achievement "' .. ach .. '".')
Expand Down
2 changes: 2 additions & 0 deletions data/lib/core/actionids.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
---@type table<string, number>
actionIds = {
sandHole = 100, -- hidden sand hole
pickHole = 105, -- hidden mud hole
Expand All @@ -7,5 +8,6 @@ actionIds = {
citizenshipLast = 30050, -- citizenship teleport last
}

---@type table<string, number>
uniqueIds = {
}
8 changes: 8 additions & 0 deletions data/lib/core/combat.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
---Returns a table with all positions that the combat would hit when executed.
---@param creature Player|Monster
---@param variant Variant
---@return table<number, Position>
function Combat:getPositions(creature, variant)
local positions = {}
function onTargetTile(creature, position)
Expand All @@ -9,6 +13,10 @@ function Combat:getPositions(creature, variant)
return positions
end

---Returns a table of all creatures that the combat would hit when executed.
---@param creature Player|Monster
---@param variant Variant
---@return table<number, Player|Monster>
function Combat:getTargets(creature, variant)
local targets = {}
function onTargetCreature(creature, target)
Expand Down
6 changes: 6 additions & 0 deletions data/lib/core/container.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ function Container.isContainer(self)
return true
end

---Creates a loot item in the container.
---@param self Container
---@param item MonsterLootBlock
---@return boolean
function Container.createLootItem(self, item)
if self:getEmptySlots() == 0 then
return true
Expand Down Expand Up @@ -68,6 +72,8 @@ function Container.createLootItem(self, item)
return true
end

---Returns a string with all the loot that was dropped.
---@return table<number, string>|string
function Container:getContentDescription()
local items = self:getItems()
if items and #items > 0 then
Expand Down
53 changes: 53 additions & 0 deletions data/lib/core/creature.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
---Returns a random position within the given radius of the given position. Verifies that the position does not already have a creature on it, it is reachable, and the tile does not have CONST_PROP_IMMOVABLEBLOCKSOLID property.
---@param self Creature
---@param position Position
---@param maxRadius number
---@param mustBeReachable boolean
---@return Position
function Creature.getClosestFreePosition(self, position, maxRadius, mustBeReachable)
maxRadius = maxRadius or 1

Expand All @@ -6,6 +12,7 @@ function Creature.getClosestFreePosition(self, position, maxRadius, mustBeReacha
maxRadius = 2
end

---@type Position
local checkPosition = Position(position)
for radius = 0, maxRadius do
checkPosition.x = checkPosition.x - math.min(1, radius)
Expand All @@ -28,14 +35,23 @@ function Creature.getClosestFreePosition(self, position, maxRadius, mustBeReacha
return Position()
end

---Returns the creature if a creature is a player, or nil if not
---@param self Creature
---@return Player|nil
function Creature.getPlayer(self)
return self:isPlayer() and self or nil
end

---Returns false as creatures cannot be containers
---@param self Creature
---@return boolean
function Creature.isContainer(self)
return false
end

---Retruns false as creatures cannot be items
---@param self Creature
---@return boolean
function Creature.isItem(self)
return false
end
Expand All @@ -60,12 +76,17 @@ function Creature.isTile(self)
return false
end

---Sets the outfit of a creature to a specific monster type for a specific amount of time.
---@param monster string
---@param time number
---@return boolean
function Creature:setMonsterOutfit(monster, time)
local monsterType = MonsterType(monster)
if not monsterType then
return false
end

---@type Condition
local condition = Condition(CONDITION_OUTFIT)
condition:setOutfit(monsterType:getOutfit())
condition:setTicks(time)
Expand All @@ -74,6 +95,10 @@ function Creature:setMonsterOutfit(monster, time)
return true
end

---Sets a creature's outfit to a specific item type, for a specific amount of time.
---@param item number
---@param time number
---@return boolean
function Creature:setItemOutfit(item, time)
local itemType = ItemType(item)
if not itemType then
Expand All @@ -90,6 +115,9 @@ function Creature:setItemOutfit(item, time)
return true
end

---Adds a summon to a creature.
---@param monster Monster
---@return boolean
function Creature:addSummon(monster)
local summon = Monster(monster)
if not summon then
Expand All @@ -109,6 +137,9 @@ function Creature:addSummon(monster)
return true
end

---Removes a summon from a creature.
---@param monster Monster
---@return boolean
function Creature:removeSummon(monster)
local summon = Monster(monster)
if not summon or summon:getMaster() ~= self then
Expand All @@ -124,11 +155,20 @@ function Creature:removeSummon(monster)
return true
end

---Adds a damage condition to a target creature.
---@param target any
---@param type ConditionType
---@param list number
---@param damage number
---@param period number
---@param rounds number
---@return boolean
function Creature:addDamageCondition(target, type, list, damage, period, rounds)
if damage <= 0 or not target or target:isImmune(type) then
return false
end

---@type Condition
local condition = Condition(type)
condition:setParameter(CONDITION_PARAM_OWNER, self:getId())
condition:setParameter(CONDITION_PARAM_DELAYED, true)
Expand Down Expand Up @@ -167,17 +207,26 @@ function Creature:addDamageCondition(target, type, list, damage, period, rounds)
return true
end

---Returns true if the creature is a player and can access the PZ (protection zone).
---@return boolean
function Creature:canAccessPz()
if self:isMonster() or (self:isPlayer() and self:isPzLocked()) then
return false
end
return true
end

---Returns itself if the creature is a monster, or nil if not.
---@param self Creature
---@return Monster|nil
function Creature.getMonster(self)
return self:isMonster() and self or nil
end

---Returns a table of all creatures that have dealt damage to the given creature. If onlyPlayers is true, it will only return players.
---@param self Creature
---@param onlyPlayers boolean
---@return table<number, Player|Monster>
function Creature.getKillers(self, onlyPlayers)
local killers = {}
local inFightTicks = configManager.getNumber(configKeys.PZ_LOCKED)
Expand All @@ -200,6 +249,10 @@ function Creature.getKillers(self, onlyPlayers)
return killers
end

---Removes a storage value from the creature.
---@param self Creature
---@param key number
---@return boolean
function Creature.removeStorageValue(self, key)
return self:setStorageValue(key, nil)
end
15 changes: 12 additions & 3 deletions data/lib/core/game/account_storage.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
do
local accountsStorage = {}

---Returns the accounts storage table.
---@return table
function Game.getAccountsStorage() return accountsStorage end

function Game.clearAccountStorageValue(accountId, key)
Expand All @@ -9,19 +10,27 @@ do
accountStorage[key] = nil
end
end

--- Returns the value of the specified key in the account storage.
---@param accountId number
---@param key any
---@return any
function Game.getAccountStorageValue(accountId, key)
local accountStorage = accountsStorage[accountId]
return accountStorage and accountStorage[key] or nil
end

--- Sets the value of the specified key in the account storage.
---@param accountId number
---@param key any
---@param value any
function Game.setAccountStorageValue(accountId, key, value)
if not accountsStorage[accountId] then
accountsStorage[accountId] = {}
end
accountsStorage[accountId][key] = value
end

--- Saves the current account storage table to the database.
---@return boolean
function Game.saveAccountsStorage()
local transaction = DBTransaction()
if not transaction:begin() then
Expand Down
Loading