chroma_solstice/room.lua

381 lines
9.7 KiB
Lua
Raw Normal View History

2015-03-11 20:11:29 -04:00
Room = class("Room")
2015-03-11 21:41:02 -04:00
2015-03-11 21:08:15 -04:00
require "player"
2015-03-12 03:04:09 -04:00
require "box"
require "wall"
2015-03-12 05:13:04 -04:00
require "artifact"
2015-03-14 05:36:02 -04:00
require "npc"
require "art"
require "assorted"
2015-03-15 05:26:47 -04:00
require "switch"
2015-03-11 20:11:29 -04:00
2015-03-11 21:08:15 -04:00
function Room:initialize(t)
self.exits = t.exits
self.name = t.name
self.player = Player:new(t.player.x, t.player.y, t.player.activeColors)
2015-03-15 05:26:47 -04:00
self.switches = { red = {}, green = {}, blue = {} }
self.switchMatrices = {}
2015-03-15 05:26:47 -04:00
self.collideables = { red = {}, green = {}, blue = {} }
self.collidableMatrices = {} --{red = {{...}{...}{...}}, ...
2015-03-12 03:04:09 -04:00
self.activeColors = {
red = true, green = true, blue = true
2015-03-12 03:04:09 -04:00
}
2015-03-11 21:08:15 -04:00
2015-03-12 03:04:09 -04:00
-- for color, coords in pairs(t.player) do
-- self.player[color] = Player:new(coords.x, coords.y, color)
-- self.activeColors[color] = true
-- end
for i=0, 2 do
2015-03-12 03:04:09 -04:00
local c = randomColor()
local x, y = math.random(1, gridWidth), math.random(1, gridHeight)
self.collideables[c]["b: " .. x .. ", " .. y] = Box:new(x, y, c)
self.collideables[c]["b: " .. x .. ", " .. y]:getOccupiedCells()
2015-03-11 21:08:15 -04:00
end
2015-03-11 20:11:29 -04:00
-- for i=0, 5 do
-- local x, y = math.random(1, gridWidth), math.random(1, gridHeight)
-- for color, active in pairs(self.activeColors) do
-- self.collideables[color]["w: " .. x .. ", " .. y] = Wall:new(x, y, color)
-- end
-- end
2015-03-12 05:13:04 -04:00
2015-03-15 05:26:47 -04:00
for i = 0, 5 do
local x, y = randomPosition()
print(x, y)
local c = randomColor()
table.insert(self.switches[c], Switch:new(x, y, c))
end
for color, active in pairs(self.activeColors) do
local x, y = 6, 3
-- if active then self.collideables[color]["n: " .. x .. ", " .. y] = Ass:new(x, y, color, "animals/processed/", "me_rach") end
2015-03-14 05:36:02 -04:00
local x, y = 1, 1
if active then self.collideables[color]["n: " .. x .. ", " .. y] = Ass:new(x, y, color, "tech/processed/", "mac_smaller") end
self.collideables[color]["n: " .. x .. ", " .. y]:getOccupiedCells()
2015-03-14 05:36:02 -04:00
local x, y = 7, 7
if active then self.collideables[color]["n: " .. x .. ", " .. y] = Ass:new(x, y, color, "tech/processed/", "cd") end
2015-03-14 05:36:02 -04:00
end
2015-03-14 05:36:02 -04:00
-- self.collideables["green"]["fpp"] = Artifact:new(6, 6, "green")
2015-03-12 05:13:04 -04:00
for color, entities in pairs(self.collideables) do
self.collidableMatrices[color] = self:createEntityMatrix(entities)
end
2015-03-11 20:11:29 -04:00
end
2015-03-11 21:41:02 -04:00
function Room:update(dt)
self.player:update(dt)
2015-03-11 20:11:29 -04:00
end
2015-03-11 21:41:02 -04:00
function Room:draw()
self.player:draw()
2015-03-12 03:04:09 -04:00
for color, entityArray in pairs(self.collideables) do
for _, entity in pairs(entityArray) do
entity:draw()
end
end
2015-03-15 05:26:47 -04:00
for color, switchArray in pairs(self.switches) do
for _, switch in pairs(switchArray) do
switch:draw()
end
end
2015-03-12 03:04:09 -04:00
end
function Room:createCollideablesMatrix()
for color, entities in pairs(self.collideables) do
self.collidableMatrices[color] = self:createEntityMatrix(entities)
end
2015-03-12 03:04:09 -04:00
end
function Room:createSwitchMatrix()
for color, switches in pairs(self.switches) do
self.switchMatrices[color] = self:createEntityMatrix(switches)
end
end
function Room:createEntityMatrix(entities)
local matrix = {}
2015-03-12 03:04:09 -04:00
--lets populate it w/ empty stuff first
for i = 1, gridWidth do
local row = {}
for i = 1, gridHeight do
table.insert(row, false)
2015-03-12 03:04:09 -04:00
end
table.insert(matrix, row)
2015-03-12 03:04:09 -04:00
end
--assumes that entities table is set up li_e {index = ent1, anotherIndex = ent2, ...}
for _, entity in pairs(entities) do
for _, occupiedCells in pairs(entity:getOccupiedCells()) do
--we store a table reference so we can call a method on it during a chec_
matrix[occupiedCells.y][occupiedCells.x] = entity
end
end
-- printMatrix(matrix)
return matrix
2015-03-12 03:04:09 -04:00
end
function Room:getCellInMatrix(matrix, cell)
return matrix[cell.y][cell.x]
2015-03-12 03:04:09 -04:00
end
function Room:movePlayer(key)
local activeColors = self.player:getActiveColors()
local pos = self.player:getGridPos()
local x, y = pos.x, pos.y
local dir = {x = 0, y = 0}
local axis
if key == "up" then
dir.y, axis = -1, "y"
elseif key == "down" then
dir.y, axis = 1, "y"
elseif key == "left" then
dir.x, axis = -1, "x"
elseif key == "right" then
dir.x, axis = 1, "x"
end
2015-03-12 03:04:09 -04:00
2015-03-15 05:26:47 -04:00
local move = true
local entitiesToPush = {
red = {},
green = {},
blue = {}
}
local entitiesToPull = {
red = {},
green = {},
blue = {}
}
-- PUSHHHHHHHHHHHHHHHHHHHHHH---------------------
2015-03-12 03:04:09 -04:00
local initialTargetCell = {
x = pos.x + dir.x, y = pos.y + dir.y
} -- this is for reference for each color as we change the targetCells table
2015-03-12 03:04:09 -04:00
2015-03-15 05:26:47 -04:00
if not self:isInBounds(initialTargetCell) then
move = true
else
local targetCells
--so the way this worx is....
for _, color in pairs(activeColors) do
--for each color...
targetCells = {initialTargetCell} -- ...we start with our attempted movement...
local doneSearching
while not doneSearching do
nextTargetCells = {} -- ...then we create this array to save our next group of cells
local emptyCells = {}
for _, cell in pairs(targetCells) do
if self:isInBounds(cell) then
local entity = self:getCellInMatrix(self.collidableMatrices[color], cell)
if entity then
--something is here!!
if not entitiesToPush[color][entity] then --if the entity hasnt been found already
if entity:canMove() then
local projectedCells = entity:getOccupiedCells(dir) -- we project the movement here
entitiesToPush[color][entity] = entity
for _, projectedCell in ipairs(projectedCells) do
table.insert(nextTargetCells, projectedCell)
end
else
move = false
doneSearching = true
end
end
2015-03-15 05:26:47 -04:00
else
--there's nothin there!!
table.insert(emptyCells, cell)
end
2015-03-15 05:26:47 -04:00
else
--we are out of bounds now
move = false
doneSearching = true
end
2015-03-15 05:26:47 -04:00
end
--if every projected cell is empty then we can do the move
if #emptyCells == #targetCells then
move = true
doneSearching = true
end
2015-03-15 05:26:47 -04:00
targetCells = nextTargetCells
end
2015-03-15 05:26:47 -04:00
--let's get out of this loop b/c if we can't move one color we can't move at all
if move == false then break end
end
end
---PULL CHEC
local initialTargetCell = {x = pos.x - dir.x, y = pos.y - dir.y}
local targetCells
local pull = {}
--so the way this worx is....
for _, color in pairs(activeColors) do
--for each color...
targetCells = {initialTargetCell} -- ...we start with our attempted movement...
local doneSearching
while not doneSearching do
nextTargetCells = {} -- ...then we create this array to save our next group of cells
local emptyCells = {}
for _, cell in pairs(targetCells) do
if self:isInBounds(cell) then
local entity = self:getCellInMatrix(self.collidableMatrices[color], cell)
if entity then
--something is here!!
if not entitiesToPull[color][entity] then --if the entity hasnt been found already
if entity:canMove() then
local projectedCells = entity:getOccupiedCells(dir) -- we project the movement here
entitiesToPull[color][entity] = entity
for _, projectedCell in ipairs(projectedCells) do
table.insert(nextTargetCells, projectedCell)
end
else
pull[color] = false
doneSearching = true
end
end
else
--there's nothin there!!
table.insert(emptyCells, cell)
end
else
pull[color] = true
--we are out of bounds now
doneSearching = true
end
end
--if every projected cell is empty then we can do the move
if #emptyCells == #targetCells then
pull[color] = true
doneSearching = true
end
targetCells = nextTargetCells
end
--let's get out of this loop b/c if we can't move one color we can't move at all
if move == false then break end
end
if move then
for color, entities in pairs(entitiesToPush) do
for _, entity in pairs(entities) do
entity:move(axis, dir[axis])
end
end
for color, entities in pairs(entitiesToPull) do
if pull[color] then
for _, entity in pairs(entities) do
entity:move(axis, dir[axis])
end
end
end
self.player:move(axis, dir[axis])
self:tick()
end
end
function Room:attemptPush(dirVector)
-- should return array of things to push or nil/falsey value
2015-03-12 03:04:09 -04:00
end
function Room:switchPlayerColor(color)
if color == "white" then
self.player:setActiveColors({"red", "green", "blue"})
else
self.player:setActiveColors({color})
end
end
function Room:setActiveColor(color, bool)
self.activeColors[color] = bool
2015-03-11 21:08:15 -04:00
end
function Room:tick()
2015-03-12 03:04:09 -04:00
for color, entityArray in pairs(self.collideables) do
for _, entity in pairs(entityArray) do
entity:tick()
end
end
self:createCollideablesMatrix()
self:createSwitchMatrix()
local doorsToUnloc = self:switchChec()
for _, color in pairs(doorsToUnloc) do
print("unloc " .. color .. " doors!!")
end
2015-03-11 21:08:15 -04:00
self:nextRoomCheck()
end
function Room:switchChec()
local doorsToUnloc = {}
for color, switchArray in pairs(self.switches) do
local onSwitches = {}
for _, switch in pairs(switchArray) do
local targetCell = self:getCellInMatrix(self.collidableMatrices[color], switch:getGridPos())
if targetCell then
--switch is on
switch:activate()
table.insert(onSwitches, switch) --doesn't rly matter what we put here as long as it's true-y
end
end
if #onSwitches == #switchArray then table.insert(doorsToUnloc, color) end
end
return doorsToUnloc
end
function Room:isInBounds(cell)
if cell.x > 0 and cell.x <= gridWidth and
cell.y > 0 and cell.y <= gridHeight then
return true
end
return false
end
2015-03-11 21:08:15 -04:00
function Room:nextRoomCheck()
2015-03-15 05:26:47 -04:00
if not self:isInBounds(self.player:getGridPos()) then
nextRoom(self.player:getGridPos())
end
2015-03-11 21:08:15 -04:00
end
2015-03-15 05:26:47 -04:00
function nextRoom(pos)
local exit
local newPos = {x = pos.x, y = pos.y}
if pos.x > gridWidth then
exit = "right"
newPos.x = 1
elseif pos.x < 1 then
exit = "left"
newPos.x = gridWidth
elseif pos.y > gridHeight then
exit = "bottom"
newPos.y = 1
elseif pos.y < 1 then
exit = "top"
newPos.y = gridHeight
end
2015-03-12 03:04:09 -04:00
2015-03-15 05:26:47 -04:00
currentRoom = Room:new{
player = {
x = newPos.x, y = newPos.y, activeColors = currentRoom.player:getActiveColors()
}
}
2015-03-11 20:11:29 -04:00
end