Skip to content

Commit

Permalink
Changed landed collision entity to custom empty box collider
Browse files Browse the repository at this point in the history
Ejects out player when trapped
Fixed error in migration file with 0.16.2
Contains dbg messages
  • Loading branch information
kumpuu committed Dec 16, 2017
1 parent b2714f3 commit a19896b
Show file tree
Hide file tree
Showing 7 changed files with 439 additions and 11 deletions.
17 changes: 17 additions & 0 deletions control.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
math3d = require("math3d")

require("logic.util")

require("logic.heliBase")
Expand Down Expand Up @@ -226,6 +228,20 @@ function OnPlayerRespawned(e)
callInGlobal("remoteGuis", "OnPlayerRespawned", game.players[e.player_index])
end

function OnDrivingStateChanged(e)
local p = game.players[e.player_index]
local ent = e.entity
local entName = ent.name

if not p.driving and string.find(heliEntityNames, entName .. ",", 1, true) then
for i,val in ipairs(global.helis) do
if val:isBaseOrChild(ent) then
val:OnPlayerEjected(p)
end
end
end
end

script.on_event(defines.events.on_built_entity, OnBuilt)
script.on_event(defines.events.on_robot_built_entity, OnBuilt)

Expand Down Expand Up @@ -254,3 +270,4 @@ script.on_event(defines.events.on_player_left_game, OnPlayerLeft)
script.on_event(defines.events.on_player_respawned, OnPlayerRespawned)

script.on_event(defines.events.on_player_armor_inventory_changed, OnArmorInventoryChanged)
script.on_event(defines.events.on_player_driving_changed_state, OnDrivingStateChanged)
301 changes: 301 additions & 0 deletions logic/emptyBoxCollider.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,301 @@
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]

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}},
name = "player",
}

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,
}

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,
}
3 changes: 2 additions & 1 deletion logic/heliAttack.lua
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ setmetatable(heliAttack, {__index = heliBase})
heliEntityNames = heliEntityNames .. concatStrTable({
"heli-entity-_-",
"heli-body-entity-_-",
"heli-landed-collision-entity-_-",
"heli-landed-collision-end-entity-_-",
"heli-landed-collision-side-entity-_-",
"heli-shadow-entity-_-",
"heli-flying-collision-entity-_-",
"heli-burner-entity-_-",
Expand Down
28 changes: 22 additions & 6 deletions logic/heliBase.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
local math3d = require("math3d")
require("logic.basicAnimator")
require("logic.basicState")
require("logic.emptyBoxCollider")

function getHeliFromBaseEntity(ent)
for k,v in pairs(global.helis) do
Expand Down Expand Up @@ -240,6 +240,12 @@ heliBase = {
end
end,

OnPlayerEjected = function(self)
if self.childs.collisionEnt and self.hasLandedCollider then
self.childs.collisionEnt.ejectPlayers()
end
end,


---------------- states ----------------

Expand Down Expand Up @@ -555,12 +561,22 @@ heliBase = {
self.hasLandedCollider = false
end

if name == "landede" then
self.childs.collisionEnt = self.surface.create_entity{
name = "heli-landed-collision-entity-_-",
force = game.forces.neutral,
if name == "landed" then
self.childs.collisionEnt = emptyBoxCollider.new({
surface = self.surface,
position = self.baseEnt.position,
}
orientation = self.baseEnt.orientation,
force = game.forces.neutral,
boxLengths =
{
ends = 3,
sides = 4.8,
},
nameEnds = "heli-landed-collision-end-entity-_-",
nameSides = "heli-landed-collision-side-entity-_-",
})

self.childs.collisionEnt.ejectPlayers()
self.hasLandedCollider = true

elseif name == "flying" then
Expand Down
Loading

0 comments on commit a19896b

Please sign in to comment.