mirror of
https://github.com/otland/forgottenserver
synced 2026-08-15 16:32:07 -04:00
* Move Position functions to Lua * Cleanup unused Position functions * Remove unused and confusing methods * Add addition and subtraction * Add __concat to Position metatable
106 lines
3 KiB
Lua
106 lines
3 KiB
Lua
local mt = rawgetmetatable("Position")
|
|
|
|
function mt.__add(lhs, rhs)
|
|
local stackpos = lhs.stackpos or rhs.stackpos
|
|
return Position(lhs.x + (rhs.x or 0), lhs.y + (rhs.y or 0), lhs.z + (rhs.z or 0), stackpos)
|
|
end
|
|
|
|
function mt.__sub(lhs, rhs)
|
|
local stackpos = lhs.stackpos or rhs.stackpos
|
|
return Position(lhs.x - (rhs.x or 0), lhs.y - (rhs.y or 0), lhs.z - (rhs.z or 0), stackpos)
|
|
end
|
|
|
|
function mt.__concat(lhs, rhs) return tostring(lhs) .. tostring(rhs) end
|
|
function mt.__eq(lhs, rhs) return lhs.x == rhs.x and lhs.y == rhs.y and lhs.z == rhs.z end
|
|
function mt.__tostring(self) return string.format("Position(%d, %d, %d)", self.x, self.y, self.z) end
|
|
|
|
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}
|
|
}
|
|
|
|
local abs, max = math.abs, math.max
|
|
function Position:getDistance(positionEx)
|
|
local dx = abs(self.x - positionEx.x)
|
|
local dy = abs(self.y - positionEx.y)
|
|
local dz = abs(self.z - positionEx.z)
|
|
return max(dx, dy, dz)
|
|
end
|
|
|
|
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 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]
|
|
local toTile = Tile(defaultPosition)
|
|
if not toTile or not toTile:isWalkable() then
|
|
for direction = DIRECTION_NORTH, DIRECTION_NORTHEAST do
|
|
if direction == DIRECTION_SOUTH then
|
|
direction = DIRECTION_WEST
|
|
end
|
|
|
|
local position = Position(self)
|
|
position:getNextPosition(direction)
|
|
toTile = Tile(position)
|
|
if toTile and toTile:isWalkable() then
|
|
swap(self, position)
|
|
return self
|
|
end
|
|
end
|
|
end
|
|
swap(self, defaultPosition)
|
|
return self
|
|
end
|
|
|
|
function Position:isInRange(from, to)
|
|
-- No matter what corner from and to is, we want to make
|
|
-- life easier by calculating north-west and south-east
|
|
local zone = {
|
|
nW = {
|
|
x = (from.x < to.x and from.x or to.x),
|
|
y = (from.y < to.y and from.y or to.y),
|
|
z = (from.z < to.z and from.z or to.z)
|
|
},
|
|
sE = {
|
|
x = (to.x > from.x and to.x or from.x),
|
|
y = (to.y > from.y and to.y or from.y),
|
|
z = (to.z > from.z and to.z or from.z)
|
|
}
|
|
}
|
|
|
|
if self.x >= zone.nW.x and self.x <= zone.sE.x
|
|
and self.y >= zone.nW.y and self.y <= zone.sE.y
|
|
and self.z >= zone.nW.z and self.z <= zone.sE.z then
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
function Position:notifySummonAppear(summon)
|
|
local spectators = Game.getSpectators(self)
|
|
for _, spectator in ipairs(spectators) do
|
|
if spectator:isMonster() and spectator ~= summon then
|
|
spectator:addTarget(summon)
|
|
end
|
|
end
|
|
end
|