313 lines
6.5 KiB
Lua
313 lines
6.5 KiB
Lua
emptyBoxCollider =
|
|
{
|
|
new = function(options)
|
|
local obj =
|
|
{
|
|
_orientation = options.orientation or 0,
|
|
surface = options.surface,
|
|
position = getIndexedPos(options.position),
|
|
force = options.force,
|
|
|
|
boxHalfs =
|
|
{
|
|
ends = options.boxLengths.ends / 2,
|
|
sides = options.boxLengths.sides / 2
|
|
},
|
|
childColliders = {},
|
|
childColliderOffsets = {},
|
|
}
|
|
|
|
if not obj.force then
|
|
obj.force = game.forces.enemy
|
|
end
|
|
|
|
obj.childColliders.top = obj.surface.create_entity{
|
|
name = options.nameEnds,
|
|
force = obj.force,
|
|
position = obj.position,
|
|
}
|
|
|
|
obj.childColliders.bottom = obj.surface.create_entity{
|
|
name = options.nameEnds,
|
|
force = obj.force,
|
|
position = obj.position,
|
|
}
|
|
|
|
obj.childColliders.left = obj.surface.create_entity{
|
|
name = options.nameSides,
|
|
force = obj.force,
|
|
position = obj.position,
|
|
}
|
|
|
|
obj.childColliders.right = obj.surface.create_entity{
|
|
name = options.nameSides,
|
|
force = obj.force,
|
|
position = obj.position,
|
|
}
|
|
|
|
setmetatable(obj, emptyBoxCollider.mt)
|
|
obj.setOrientation(obj._orientation)
|
|
|
|
return obj
|
|
end,
|
|
|
|
destroy = function(self)
|
|
for k,v in pairs(self.childColliders) do
|
|
if v.valid then
|
|
v.destroy()
|
|
end
|
|
end
|
|
end,
|
|
|
|
valid = function(self)
|
|
local val = true
|
|
|
|
for k,v in pairs(self.childColliders) do
|
|
if not v.valid then
|
|
val = false
|
|
break
|
|
end
|
|
end
|
|
|
|
if not val then
|
|
self.destroy()
|
|
end
|
|
|
|
return val
|
|
end,
|
|
|
|
moveChildColliders = function(self)
|
|
self.childColliders.top.teleport(math3d.vector2.add(self.position, self.childColliderOffsets.up))
|
|
self.childColliders.bottom.teleport(math3d.vector2.sub(self.position, self.childColliderOffsets.up))
|
|
|
|
self.childColliders.right.teleport(math3d.vector2.add(self.position, self.childColliderOffsets.right))
|
|
self.childColliders.left.teleport(math3d.vector2.sub(self.position, self.childColliderOffsets.right))
|
|
end,
|
|
|
|
setOrientation = function(self, orient)
|
|
self._orientation = orient
|
|
|
|
self.childColliderOffsets.up = math3d.vector2.rotate({0,self.boxHalfs.sides}, math.pi * 2 * orient)
|
|
self.childColliderOffsets.right = math3d.vector2.rotate({self.boxHalfs.ends,0}, math.pi * 2 * orient)
|
|
|
|
for k,v in pairs(self.childColliders) do
|
|
v.orientation = orient
|
|
end
|
|
|
|
self.moveChildColliders()
|
|
end,
|
|
|
|
teleport = function(self, pos)
|
|
self.position = getIndexedPos(pos)
|
|
|
|
self.moveChildColliders()
|
|
end,
|
|
|
|
getHealth = function(self)
|
|
local lowest = self.childColliders.top.health
|
|
|
|
for k,v in pairs(self.childColliders) do
|
|
if v.health < lowest then
|
|
lowest = v.health
|
|
end
|
|
end
|
|
|
|
return lowest
|
|
end,
|
|
|
|
setHealth = function(self, health)
|
|
for k,v in pairs(self.childColliders) do
|
|
v.health = health
|
|
end
|
|
end,
|
|
|
|
getSpeed = function(self)
|
|
local highest = self.childColliders.top.speed
|
|
|
|
for k,v in pairs(self.childColliders) do
|
|
if v.speed > highest then
|
|
speed = v.speed
|
|
end
|
|
end
|
|
|
|
return highest
|
|
end,
|
|
|
|
setSpeed = function(self, speed)
|
|
for k,v in pairs(self.childColliders) do
|
|
v.speed = speed
|
|
end
|
|
end,
|
|
|
|
setOperable = function(self, operable)
|
|
for k,v in pairs(self.childColliders) do
|
|
v.operable = operable
|
|
end
|
|
end,
|
|
|
|
get_driver = function(self)
|
|
for k,v in pairs(self.childColliders) do
|
|
local driver = v.get_driver()
|
|
if driver then
|
|
return driver
|
|
end
|
|
end
|
|
|
|
return nil
|
|
end,
|
|
|
|
set_driver = function(self, driver)
|
|
if driver == nil then
|
|
for k,v in pairs(self.childColliders) do
|
|
v.set_driver(nil)
|
|
end
|
|
end
|
|
end,
|
|
|
|
get_passenger = function(self)
|
|
for k,v in pairs(self.childColliders) do
|
|
local passenger = v.get_passenger()
|
|
if passenger then
|
|
return passenger
|
|
end
|
|
end
|
|
|
|
return nil
|
|
end,
|
|
|
|
set_passenger = function(self, passenger)
|
|
if passenger == nil then
|
|
for k,v in pairs(self.childColliders) do
|
|
v.set_passenger(nil)
|
|
end
|
|
end
|
|
end,
|
|
|
|
isPosInside = function(self, pos)
|
|
local delta = math3d.vector2.sub(getIndexedPos(pos), self.position)
|
|
|
|
local tX = delta[1]
|
|
local tY = delta[2]
|
|
|
|
local up = math3d.vector2.mul(self.childColliderOffsets.up, 1.1)
|
|
local right = math3d.vector2.mul(self.childColliderOffsets.right, 1.1)
|
|
|
|
local b1X = up[1]
|
|
local b1Y = up[2]
|
|
|
|
local b2X = right[1]
|
|
local b2Y = right[2]
|
|
|
|
--https://i.imgur.com/zQrgq0B.png
|
|
local a = (tY * b2X - tX * b2Y) / (b1Y * b2X - b1X * b2Y)
|
|
local b = (tY * b1X - tX * b1Y) / (b2Y * b1X - b2X * b1Y)
|
|
|
|
return math.abs(a) < 1 and math.abs(b) < 1, a, b
|
|
end,
|
|
|
|
ejectPlayers = function(self)
|
|
local rad = math.ceil(math.sqrt(self.boxHalfs.ends^2 + self.boxHalfs.sides^2))
|
|
local x = self.position[1]
|
|
local y = self.position[2]
|
|
|
|
local players = self.surface.find_entities_filtered{
|
|
area = {{x - rad, y - rad}, {x + rad, y + rad}},
|
|
type = "character",
|
|
}
|
|
|
|
for k, curPlayer in pairs(players) do
|
|
local pos = getIndexedPos(curPlayer.position)
|
|
local inside, a, b = self.isPosInside(pos)
|
|
|
|
if inside then
|
|
local deltaVec
|
|
if math.abs(a) > math.abs(b) then
|
|
local delta
|
|
if a > 0 then
|
|
delta = 1.2 - a
|
|
else
|
|
delta = -1.2 - a
|
|
end
|
|
|
|
deltaVec = math3d.vector2.mul(self.childColliderOffsets.up, delta)
|
|
else
|
|
local delta
|
|
if b > 0 then
|
|
delta = 1.2 - b
|
|
else
|
|
delta = -1.2 - b
|
|
end
|
|
|
|
deltaVec = math3d.vector2.mul(self.childColliderOffsets.right, delta)
|
|
end
|
|
|
|
curPlayer.teleport(math3d.vector2.add(pos, deltaVec))
|
|
end
|
|
end
|
|
end,
|
|
|
|
isChildEntity = function(self, ent)
|
|
for k,v in pairs(self.childColliders) do
|
|
if v == ent then
|
|
return true
|
|
end
|
|
end
|
|
|
|
return false
|
|
end,
|
|
}
|
|
|
|
emptyBoxCollider.mt =
|
|
{
|
|
__index = function(t, k)
|
|
if k == "valid" then
|
|
return emptyBoxCollider.valid(t)
|
|
|
|
elseif k == "orientation" then
|
|
return t._orientation
|
|
|
|
elseif k == "health" then
|
|
return emptyBoxCollider.getHealth(t)
|
|
|
|
elseif k == "speed" then
|
|
return emptyBoxCollider.getSpeed(t)
|
|
|
|
elseif k == "get_inventory" then
|
|
return function(...)
|
|
local params = {...}
|
|
return setmetatable({},
|
|
{__index = function(_t, _k)
|
|
return function(...)
|
|
for key, curCol in pairs(t.childColliders) do
|
|
curCol[k](unpack(params))[_k](...)
|
|
end
|
|
end
|
|
end})
|
|
end
|
|
|
|
elseif type(emptyBoxCollider[k]) == "function" then
|
|
return function(...)
|
|
return emptyBoxCollider[k](t, ...)
|
|
end
|
|
|
|
else
|
|
return emptyBoxCollider[k]
|
|
end
|
|
end,
|
|
|
|
__newindex = function(t, k, v)
|
|
if k == "orientation" then
|
|
emptyBoxCollider.setOrientation(t, v)
|
|
|
|
elseif k == "health" then
|
|
emptyBoxCollider.setHealth(t, v)
|
|
|
|
elseif k == "speed" then
|
|
emptyBoxCollider.setSpeed(t, v)
|
|
|
|
elseif k == "operable" then
|
|
emptyBoxCollider.setOperable(t, v)
|
|
end
|
|
end,
|
|
}
|