sonic-radiance/sonic-radiance.love/scenes/overworld/actors/player/interactions.lua
2021-04-21 16:46:41 +02:00

170 lines
4.5 KiB
Lua

local PlayerInteractions = Object:extend()
local terrainData = require "datas.gamedata.maps.terrains"
local MIN_X = 2
local MAX_X = 14
local MIN_Y = 9
local MAX_Y = 15
local TERRAIN_CHECKER = {
{x = MIN_X, y = MIN_Y},
{x = MIN_X, y = MAX_Y},
{x = MAX_X, y = MIN_Y},
{x = MAX_X, y = MAX_Y},
}
function PlayerInteractions:initInteractions()
self.lastCollision = -1
self.haveCollided = false
self.terrain = {}
self.terrain.name = ""
self.terrain.data = {}
self.terrain.new = false
self.lastPos = {}
self.lastPos.x = self.x
self.lastPos.y = self.y
end
function PlayerInteractions:updateInteraction()
if (self.haveCollided == false) then
self.lastCollision = nil
end
self.haveCollided = false
end
function PlayerInteractions:collideWithGizmo(other)
if (other.needButton) then
if (self.keys["A"].isPressed) then
other:doAction()
self.haveCollided = true
self.lastCollision = other.creationID
end
else
if (self.lastCollision ~= other.creationID) then
other:doAction()
end
self.haveCollided = true
self.lastCollision = other.creationID
end
end
function PlayerInteractions:talkToGizmo(other)
if (self.keys["A"].isPressed and (self:faceRightDirection(other))) then
other:doAction()
self.haveCollided = true
self.lastCollision = other.creationID
end
end
function PlayerInteractions:faceRightDirection(other)
if (self.charDir == "up") then
return (self.y >= other.y + other.h)
end
if (self.charDir == "down") then
return (self.y + self.h <= other.y)
end
if (self.charDir == "left") then
return (self.x >= other.x + other.w)
end
if (self.charDir == "right") then
return (self.x + self.w <= other.x)
end
end
function PlayerInteractions:updateTerrain()
local newTerrain = self:getCurrentTerrain()
if (newTerrain ~= self.terrain.name) then
self.terrain.new = true
end
self.terrain.name = newTerrain
self:updateTerrainData()
if (newTerrain == "non-solid") then
self:updateLastPosition()
end
end
function PlayerInteractions:updateLastPosition()
local canUpdate = true
for _, coord in ipairs(TERRAIN_CHECKER) do
local xx, yy = coord.x, coord.y
if (xx == MIN_X) then xx=0 else xx=16 end
if (yy == MIN_Y) then yy=0 else yy=16 end
local newTerrain = self.world:getTileTypeAtPoint(self.x + xx, self.y + yy)
if (newTerrain ~= "non-solid") then
canUpdate = false
end
end
if (canUpdate and self.onGround) then
self.lastPos = {}
self.lastPos.x = self.x
self.lastPos.y = self.y
end
end
function PlayerInteractions:updateTerrainData()
local dataPack = terrainData.list[self.terrain.name]
local newData = terrainData.list["non-solid"][1]
if (dataPack == nil) then
dataPack = terrainData.list["non-solid"]
end
for id, data in ipairs(dataPack) do
local useThisData = true
if (data.mustHaveAction ~= nil and not self:canDoAction(data.mustHaveAction)) then
useThisData = false
end
if (data.mustDoAction ~= nil and data.mustDoAction ~= self.currentAction) then
useThisData = false
end
if (useThisData) then
newData = data
end
end
self:setTerrainData(newData)
end
function PlayerInteractions:setTerrainData(data)
self.groundLevel = data.level or 0
self.groundHeight = data.height or 0
if (self.onGround) then
self.speedFactor = data.speedFactor or 1
self.canJump = data.canJump ~= false
self.canAct = data.canAct ~= false
self.forceAction = data.forceAction
end
if (self.terrain.new and (self.z < 0)) then
self.terrain.new = false
if (not utils.string.isEmpty(data.sound)) then
self.assets:playSFX(data.sound)
end
end
self.fallDamage = data.fallDamage or 0
self.fallSound = data.fallSound or ""
self.terrain.data = data
end
function PlayerInteractions:getCurrentTerrain()
local terrain = ""
local highpriority = terrainData.highpriority
for _, coord in ipairs(TERRAIN_CHECKER) do
local newTerrain = self.world:getTileTypeAtPoint(self.x + coord.x, self.y + coord.y)
if (utils.table.contain(highpriority, newTerrain)) then
terrain = newTerrain
elseif (newTerrain == "non-solid") then
if (not utils.table.contain(highpriority, terrain)) then
terrain = newTerrain
end
else
if (not (utils.table.contain(highpriority, terrain) or terrain == "non-solid")) then
terrain = newTerrain
end
end
end
return terrain
end
return PlayerInteractions