mirror of
https://github.com/ErikasKontenis/SabrehavenServer.git
synced 2025-10-13 14:24:55 +02:00
Full Distribution
This commit is contained in:
1
data/lib/core/constants.lua
Normal file
1
data/lib/core/constants.lua
Normal file
@@ -0,0 +1 @@
|
||||
CONTAINER_POSITION = 0xFFFF
|
27
data/lib/core/container.lua
Normal file
27
data/lib/core/container.lua
Normal file
@@ -0,0 +1,27 @@
|
||||
function Container.isContainer(self)
|
||||
return true
|
||||
end
|
||||
|
||||
function Container.isItem(self)
|
||||
return true
|
||||
end
|
||||
|
||||
function Container.isMonster(self)
|
||||
return false
|
||||
end
|
||||
|
||||
function Container.isCreature(self)
|
||||
return false
|
||||
end
|
||||
|
||||
function Container.isPlayer(self)
|
||||
return false
|
||||
end
|
||||
|
||||
function Container.isTeleport(self)
|
||||
return false
|
||||
end
|
||||
|
||||
function Container.isTile(self)
|
||||
return false
|
||||
end
|
11
data/lib/core/core.lua
Normal file
11
data/lib/core/core.lua
Normal file
@@ -0,0 +1,11 @@
|
||||
dofile('data/lib/core/constants.lua')
|
||||
dofile('data/lib/core/container.lua')
|
||||
dofile('data/lib/core/creature.lua')
|
||||
dofile('data/lib/core/monster.lua')
|
||||
dofile('data/lib/core/game.lua')
|
||||
dofile('data/lib/core/item.lua')
|
||||
dofile('data/lib/core/itemtype.lua')
|
||||
dofile('data/lib/core/player.lua')
|
||||
dofile('data/lib/core/position.lua')
|
||||
dofile('data/lib/core/teleport.lua')
|
||||
dofile('data/lib/core/tile.lua')
|
116
data/lib/core/creature.lua
Normal file
116
data/lib/core/creature.lua
Normal file
@@ -0,0 +1,116 @@
|
||||
function Creature.getClosestFreePosition(self, position, extended)
|
||||
local usePosition = Position(position)
|
||||
local tiles = { Tile(usePosition) }
|
||||
local length = extended and 2 or 1
|
||||
|
||||
local tile
|
||||
for y = -length, length do
|
||||
for x = -length, length do
|
||||
if x ~= 0 or y ~= 0 then
|
||||
usePosition.x = position.x + x
|
||||
usePosition.y = position.y + y
|
||||
|
||||
tile = Tile(usePosition)
|
||||
if tile then
|
||||
tiles[#tiles + 1] = tile
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, #tiles do
|
||||
tile = tiles[i]
|
||||
if tile:getCreatureCount() == 0 and not tile:hasProperty(CONST_PROP_IMMOVABLEBLOCKSOLID) then
|
||||
return tile:getPosition()
|
||||
end
|
||||
end
|
||||
return Position()
|
||||
end
|
||||
|
||||
function Creature:setMonsterOutfit(monster, time)
|
||||
local monsterType = MonsterType(monster)
|
||||
if not monsterType then
|
||||
return false
|
||||
end
|
||||
|
||||
if self:isPlayer() and not (getPlayerFlagValue(self, PlayerFlag_CanIllusionAll) or monsterType:isIllusionable()) then
|
||||
return false
|
||||
end
|
||||
|
||||
local condition = Condition(CONDITION_OUTFIT)
|
||||
condition:setOutfit(monsterType:getOutfit())
|
||||
condition:setTicks(time)
|
||||
self:addCondition(condition)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function Creature:setItemOutfit(item, time)
|
||||
local itemType = ItemType(item)
|
||||
if not itemType then
|
||||
return false
|
||||
end
|
||||
|
||||
local condition = Condition(CONDITION_OUTFIT)
|
||||
condition:setOutfit({
|
||||
lookTypeEx = itemType:getId()
|
||||
})
|
||||
condition:setTicks(time)
|
||||
self:addCondition(condition)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function Creature:addSummon(monster)
|
||||
local summon = Monster(monster)
|
||||
if not summon then
|
||||
return false
|
||||
end
|
||||
|
||||
summon:setTarget(nil)
|
||||
summon:setFollowCreature(nil)
|
||||
summon:setDropLoot(false)
|
||||
summon:setMaster(self)
|
||||
return true
|
||||
end
|
||||
|
||||
function Creature:removeSummon(monster)
|
||||
local summon = Monster(monster)
|
||||
if not summon or summon:getMaster() ~= self then
|
||||
return false
|
||||
end
|
||||
|
||||
summon:setTarget(nil)
|
||||
summon:setFollowCreature(nil)
|
||||
summon:setDropLoot(true)
|
||||
summon:setMaster(nil)
|
||||
return true
|
||||
end
|
||||
|
||||
function Creature.getPlayer(self)
|
||||
return self:isPlayer() and self or nil
|
||||
end
|
||||
|
||||
function Creature.isItem(self)
|
||||
return false
|
||||
end
|
||||
|
||||
function Creature.isMonster(self)
|
||||
return false
|
||||
end
|
||||
|
||||
function Creature.isNpc(self)
|
||||
return false
|
||||
end
|
||||
|
||||
function Creature.isPlayer(self)
|
||||
return false
|
||||
end
|
||||
|
||||
function Creature.isTile(self)
|
||||
return false
|
||||
end
|
||||
|
||||
function Creature.isContainer(self)
|
||||
return false
|
||||
end
|
125
data/lib/core/game.lua
Normal file
125
data/lib/core/game.lua
Normal file
@@ -0,0 +1,125 @@
|
||||
function Game.sendMagicEffect(position, effect)
|
||||
local pos = Position(position)
|
||||
pos:sendMagicEffect(effect)
|
||||
end
|
||||
|
||||
function Game.removeItemsOnMap(position)
|
||||
local tile = Tile(position)
|
||||
local tileCount = tile:getThingCount()
|
||||
local i = 0
|
||||
while i < tileCount do
|
||||
local tileItem = tile:getThing(i)
|
||||
if tileItem and tileItem:getType():isMovable() then
|
||||
tileItem:remove()
|
||||
else
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Game.transformItemOnMap(position, itemId, toItemId, subtype)
|
||||
if not subtype then
|
||||
subtype = -1
|
||||
end
|
||||
|
||||
local tile = Tile(position)
|
||||
local item = tile:getItemById(itemId)
|
||||
item:transform(toItemId, subtype)
|
||||
item:decay()
|
||||
return item
|
||||
end
|
||||
|
||||
function Game.removeItemOnMap(position, itemId, subtype)
|
||||
if not subtype then
|
||||
subtype = -1
|
||||
end
|
||||
|
||||
local tile = Tile(position)
|
||||
local item = tile:getItemById(itemId, subtype)
|
||||
item:remove()
|
||||
end
|
||||
|
||||
function Game.isItemThere(position, itemId)
|
||||
local tile = Tile(position)
|
||||
return tile:getItemById(itemId) ~= nil
|
||||
end
|
||||
|
||||
function Game.isPlayerThere(position)
|
||||
local tile = Tile(position)
|
||||
local creatures = tile:getCreatures()
|
||||
for _, creature in ipairs(creatures) do
|
||||
if creature:isPlayer() then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function Game.broadcastMessage(message, messageType)
|
||||
if messageType == nil then
|
||||
messageType = MESSAGE_STATUS_WARNING
|
||||
end
|
||||
|
||||
for _, player in ipairs(Game.getPlayers()) do
|
||||
player:sendTextMessage(messageType, message)
|
||||
end
|
||||
end
|
||||
|
||||
function Game.convertIpToString(ip)
|
||||
local band = bit.band
|
||||
local rshift = bit.rshift
|
||||
return string.format("%d.%d.%d.%d",
|
||||
band(ip, 0xFF),
|
||||
band(rshift(ip, 8), 0xFF),
|
||||
band(rshift(ip, 16), 0xFF),
|
||||
rshift(ip, 24)
|
||||
)
|
||||
end
|
||||
|
||||
function Game.getReverseDirection(direction)
|
||||
if direction == WEST then
|
||||
return EAST
|
||||
elseif direction == EAST then
|
||||
return WEST
|
||||
elseif direction == NORTH then
|
||||
return SOUTH
|
||||
elseif direction == SOUTH then
|
||||
return NORTH
|
||||
elseif direction == NORTHWEST then
|
||||
return SOUTHEAST
|
||||
elseif direction == NORTHEAST then
|
||||
return SOUTHWEST
|
||||
elseif direction == SOUTHWEST then
|
||||
return NORTHEAST
|
||||
elseif direction == SOUTHEAST then
|
||||
return NORTHWEST
|
||||
end
|
||||
return NORTH
|
||||
end
|
||||
|
||||
function Game.getSkillType(weaponType)
|
||||
if weaponType == WEAPON_CLUB then
|
||||
return SKILL_CLUB
|
||||
elseif weaponType == WEAPON_SWORD then
|
||||
return SKILL_SWORD
|
||||
elseif weaponType == WEAPON_AXE then
|
||||
return SKILL_AXE
|
||||
elseif weaponType == WEAPON_DISTANCE then
|
||||
return SKILL_DISTANCE
|
||||
elseif weaponType == WEAPON_SHIELD then
|
||||
return SKILL_SHIELD
|
||||
end
|
||||
return SKILL_FIST
|
||||
end
|
||||
|
||||
if not globalStorageTable then
|
||||
globalStorageTable = {}
|
||||
end
|
||||
|
||||
function Game.getStorageValue(key)
|
||||
return globalStorageTable[key]
|
||||
end
|
||||
|
||||
function Game.setStorageValue(key, value)
|
||||
globalStorageTable[key] = value
|
||||
end
|
31
data/lib/core/item.lua
Normal file
31
data/lib/core/item.lua
Normal file
@@ -0,0 +1,31 @@
|
||||
function Item.getType(self)
|
||||
return ItemType(self:getId())
|
||||
end
|
||||
|
||||
function Item.isItem(self)
|
||||
return true
|
||||
end
|
||||
|
||||
function Item.isContainer(self)
|
||||
return false
|
||||
end
|
||||
|
||||
function Item.isCreature(self)
|
||||
return false
|
||||
end
|
||||
|
||||
function Item.isMonster(self)
|
||||
return false
|
||||
end
|
||||
|
||||
function Item.isPlayer(self)
|
||||
return false
|
||||
end
|
||||
|
||||
function Item.isTeleport(self)
|
||||
return false
|
||||
end
|
||||
|
||||
function Item.isTile(self)
|
||||
return false
|
||||
end
|
16
data/lib/core/itemtype.lua
Normal file
16
data/lib/core/itemtype.lua
Normal file
@@ -0,0 +1,16 @@
|
||||
local slotBits = {
|
||||
[CONST_SLOT_HEAD] = SLOTP_HEAD,
|
||||
[CONST_SLOT_NECKLACE] = SLOTP_NECKLACE,
|
||||
[CONST_SLOT_BACKPACK] = SLOTP_BACKPACK,
|
||||
[CONST_SLOT_ARMOR] = SLOTP_ARMOR,
|
||||
[CONST_SLOT_RIGHT] = SLOTP_RIGHT,
|
||||
[CONST_SLOT_LEFT] = SLOTP_LEFT,
|
||||
[CONST_SLOT_LEGS] = SLOTP_LEGS,
|
||||
[CONST_SLOT_FEET] = SLOTP_FEET,
|
||||
[CONST_SLOT_RING] = SLOTP_RING,
|
||||
[CONST_SLOT_AMMO] = SLOTP_AMMO
|
||||
}
|
||||
|
||||
function ItemType.usesSlot(self, slot)
|
||||
return bit.band(self:getSlotPosition(), slotBits[slot] or 0) ~= 0
|
||||
end
|
27
data/lib/core/monster.lua
Normal file
27
data/lib/core/monster.lua
Normal file
@@ -0,0 +1,27 @@
|
||||
function Monster.getMonster(self)
|
||||
return self:isMonster() and self or nil
|
||||
end
|
||||
|
||||
function Monster.isItem(self)
|
||||
return false
|
||||
end
|
||||
|
||||
function Monster.isMonster(self)
|
||||
return true
|
||||
end
|
||||
|
||||
function Monster.isNpc(self)
|
||||
return false
|
||||
end
|
||||
|
||||
function Monster.isPlayer(self)
|
||||
return false
|
||||
end
|
||||
|
||||
function Monster.isTile(self)
|
||||
return false
|
||||
end
|
||||
|
||||
function Monster.isContainer(self)
|
||||
return false
|
||||
end
|
99
data/lib/core/player.lua
Normal file
99
data/lib/core/player.lua
Normal file
@@ -0,0 +1,99 @@
|
||||
local foodCondition = Condition(CONDITION_REGENERATION, CONDITIONID_DEFAULT)
|
||||
|
||||
function Player.feed(self, food)
|
||||
local condition = self:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT)
|
||||
if condition then
|
||||
condition:setTicks(condition:getTicks() + (food * 1000))
|
||||
else
|
||||
local vocation = self:getVocation()
|
||||
if not vocation then
|
||||
return nil
|
||||
end
|
||||
|
||||
foodCondition:setTicks(food * 1000)
|
||||
foodCondition:setParameter(CONDITION_PARAM_HEALTHGAIN, vocation:getHealthGainAmount())
|
||||
foodCondition:setParameter(CONDITION_PARAM_HEALTHTICKS, vocation:getHealthGainTicks() * 1000)
|
||||
foodCondition:setParameter(CONDITION_PARAM_MANAGAIN, vocation:getManaGainAmount())
|
||||
foodCondition:setParameter(CONDITION_PARAM_MANATICKS, vocation:getManaGainTicks() * 1000)
|
||||
|
||||
self:addCondition(foodCondition)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function Player.getClosestFreePosition(self, position, extended)
|
||||
if self:getAccountType() >= ACCOUNT_TYPE_GOD then
|
||||
return position
|
||||
end
|
||||
return Creature.getClosestFreePosition(self, position, extended)
|
||||
end
|
||||
|
||||
function Player.getDepotItems(self, depotId)
|
||||
return self:getDepotChest(depotId, true):getItemHoldingCount()
|
||||
end
|
||||
|
||||
function Player.isNoVocation(self)
|
||||
return self:getVocation():getId() == 0
|
||||
end
|
||||
|
||||
function Player.isSorcerer(self)
|
||||
return self:getVocation():getId() == 1 or self:getVocation():getId() == 5
|
||||
end
|
||||
|
||||
function Player.isDruid(self)
|
||||
return self:getVocation():getId() == 2 or self:getVocation():getId() == 6
|
||||
end
|
||||
|
||||
function Player.isPaladin(self)
|
||||
return self:getVocation():getId() == 3 or self:getVocation():getId() == 7
|
||||
end
|
||||
|
||||
function Player.isKnight(self)
|
||||
return self:getVocation():getId() == 4 or self:getVocation():getId() == 8
|
||||
end
|
||||
|
||||
function Player.isPremium(self)
|
||||
return self:getPremiumDays() > 0 or configManager.getBoolean(configKeys.FREE_PREMIUM)
|
||||
end
|
||||
|
||||
function Player.sendCancelMessage(self, message)
|
||||
if type(message) == "number" then
|
||||
message = Game.getReturnMessage(message)
|
||||
end
|
||||
return self:sendTextMessage(MESSAGE_STATUS_SMALL, message)
|
||||
end
|
||||
|
||||
function Player.isUsingOtClient(self)
|
||||
return self:getClient().os >= CLIENTOS_OTCLIENT_LINUX
|
||||
end
|
||||
|
||||
function Player.sendExtendedOpcode(self, opcode, buffer)
|
||||
if not self:isUsingOtClient() then
|
||||
return false
|
||||
end
|
||||
|
||||
local networkMessage = NetworkMessage()
|
||||
networkMessage:addByte(0x32)
|
||||
networkMessage:addByte(opcode)
|
||||
networkMessage:addString(buffer)
|
||||
networkMessage:sendToPlayer(self)
|
||||
networkMessage:delete()
|
||||
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
|
75
data/lib/core/position.lua
Normal file
75
data/lib/core/position.lua
Normal file
@@ -0,0 +1,75 @@
|
||||
Position.directionOffset = {
|
||||
[DIRECTION_NORTH] = {x = 0, y = -1},
|
||||
[DIRECTION_EAST] = {x = 1, y = 0},
|
||||
[DIRECTION_SOUTH] = {x = 0, y = 1},
|
||||
[DIRECTION_WEST] = {x = -1, y = 0},
|
||||
[DIRECTION_SOUTHWEST] = {x = -1, y = 1},
|
||||
[DIRECTION_SOUTHEAST] = {x = 1, y = 1},
|
||||
[DIRECTION_NORTHWEST] = {x = -1, y = -1},
|
||||
[DIRECTION_NORTHEAST] = {x = 1, y = -1}
|
||||
}
|
||||
|
||||
function Position:getNextPosition(direction, steps)
|
||||
local offset = Position.directionOffset[direction]
|
||||
if offset then
|
||||
steps = steps or 1
|
||||
self.x = self.x + offset.x * steps
|
||||
self.y = self.y + offset.y * steps
|
||||
end
|
||||
end
|
||||
|
||||
function Position:moveUpstairs()
|
||||
local isWalkable = function (position)
|
||||
local tile = Tile(position)
|
||||
if not tile then
|
||||
return false
|
||||
end
|
||||
|
||||
local ground = tile:getGround()
|
||||
if not ground or ground:hasProperty(CONST_PROP_BLOCKSOLID) then
|
||||
return false
|
||||
end
|
||||
|
||||
local items = tile:getItems()
|
||||
for i = 1, tile: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
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local swap = function (lhs, rhs)
|
||||
lhs.x, rhs.x = rhs.x, lhs.x
|
||||
lhs.y, rhs.y = rhs.y, lhs.y
|
||||
lhs.z, rhs.z = rhs.z, lhs.z
|
||||
end
|
||||
|
||||
self.z = self.z - 1
|
||||
|
||||
local defaultPosition = self + Position.directionOffset[DIRECTION_SOUTH]
|
||||
if not isWalkable(defaultPosition) then
|
||||
for direction = DIRECTION_NORTH, DIRECTION_NORTHEAST do
|
||||
if direction == DIRECTION_SOUTH then
|
||||
direction = DIRECTION_WEST
|
||||
end
|
||||
|
||||
local position = self + Position.directionOffset[direction]
|
||||
if isWalkable(position) then
|
||||
swap(self, position)
|
||||
return self
|
||||
end
|
||||
end
|
||||
end
|
||||
swap(self, defaultPosition)
|
||||
return self
|
||||
end
|
||||
|
||||
function Position:moveRel(x, y, z)
|
||||
self.x = self.x + x
|
||||
self.y = self.y + y
|
||||
self.z = self.z + z
|
||||
return self
|
||||
end
|
3
data/lib/core/teleport.lua
Normal file
3
data/lib/core/teleport.lua
Normal file
@@ -0,0 +1,3 @@
|
||||
function Teleport.isTeleport(self)
|
||||
return true
|
||||
end
|
23
data/lib/core/tile.lua
Normal file
23
data/lib/core/tile.lua
Normal file
@@ -0,0 +1,23 @@
|
||||
function Tile.isItem(self)
|
||||
return false
|
||||
end
|
||||
|
||||
function Tile.isContainer(self)
|
||||
return false
|
||||
end
|
||||
|
||||
function Tile.isCreature(self)
|
||||
return false
|
||||
end
|
||||
|
||||
function Tile.isPlayer(self)
|
||||
return false
|
||||
end
|
||||
|
||||
function Tile.isTeleport(self)
|
||||
return false
|
||||
end
|
||||
|
||||
function Tile.isTile(self)
|
||||
return true
|
||||
end
|
Reference in New Issue
Block a user