Compare commits

...

5 Commits

18 changed files with 445 additions and 440 deletions

29
FixMime
View File

@ -1,16 +1,39 @@
#!sh
#adjust the next line... not sure how to figure this out from a shellscript, sorry :)
cd ~/proj/poppy-client-loeve
# This mechanism is fairly unreliable, but it is the only "okay" way currently :/
# realpath is also not part of any POSIX standard
cd $(dirname $(realpath "$0"))
if test $? -eq 1; then
alert --stop "cant figure out where this script is" "Ill adjust it!"
exit
fi
touch log
for i in lua/*.lua; do
echo "$i" >> log
addattr -t mime BEOS:TYPE text/x-source-code $i;
done
for i in server/*.lua; do
echo "$i" >> log
addattr -t mime BEOS:TYPE text/x-source-code $i;
done
for i in server/commands/*.lua; do
echo "$i" >> log
addattr -t mime BEOS:TYPE text/x-source-code $i;
done
for i in server/unpriviliged_commands/*.lua; do
echo "$i" >> log
addattr -t mime BEOS:TYPE text/x-source-code $i;
done
for i in shared/*.lua; do
echo "$i" >> log
addattr -t mime BEOS:TYPE text/x-source-code $i;
done
alert --info "Fixed mime types
$(cat log)"
rm log

View File

@ -95,7 +95,7 @@ end
function camera.setplayer()
if camera.target == 0 then return end
player = players[camera.target]
player = participants[camera.target]
camera.offsetclamp()
local perfectx = math.floor(player.x * -1) + ((window.x -300)/2 -((player.avatar:getWidth() /2) / scale)) / scale + camera.offset.x
local perfecty = math.floor(player.y * -1) + (window.y/2 -((player.avatar:getHeight() /2) / scale)) / scale + camera.offset.y
@ -107,7 +107,7 @@ end
function camera.update()
if camera.target == 0 then return end
player = players[camera.target]
player = participants[camera.target]
--[[ Update camera to track player ]]--
local perfectx = math.floor(player.x * -1) + ((window.x -300)/2 -(player.avatar:getWidth() /2)) / scale + camera.offset.x
local perfecty = math.floor(player.y * -1) + (window.y/2 -(player.avatar:getHeight() /2)) / scale + camera.offset.y

View File

@ -3,114 +3,91 @@ local player = require("lua.player")
local utils = require("shared.utils")
local fonts = require("shared.fonts")
local commands = {}
local sharedCommands = require("shared.commands")
return function(commands)
commands.init = function(clientID, args)
local nickname, args = utils.nextStringRecord(args)
local avatarEncoded, args = utils.nextStringRecord(args)
local worldID, args = utils.nextStringRecord(args)
local x, args = utils.nextIntRecord(args)
local y = tonumber(args)
local avatar = love.data.decode("string", "base64", avatarEncoded)
print("Connected as " .. clientID .. " with name " .. nickname)
print("New world is " .. worldID .. " Size is [" .. x .. "|" .. y .. "]")
participants[clientID] = player.newPlayer({name = nickname, avatar = levelloop.avatars[avatar].image})
camera.target = clientID
_G.clientID = clientID
commands.commandsInit = sharedCommands.commandsInit
commands.commandsWorldInit = sharedCommands.commandsWorldInit
commands.init = function(clientID, args)
local nickname, args = utils.nextStringRecord(args)
local avatarEncoded, args = utils.nextStringRecord(args)
local worldID, args = utils.nextStringRecord(args)
local x, args = utils.nextIntRecord(args)
local y = tonumber(args)
local avatar = love.data.decode("string", "base64", avatarEncoded)
print("Connected as " .. clientID .. " with name " .. nickname)
print("New world is " .. worldID .. " Size is [" .. x .. "|" .. y .. "]")
players[clientID] = player.newPlayer({name = nickname, avatar = gameloop.avatars[avatar].image})
camera.target = clientID
_G.clientID = clientID
local world = { id = worldID, x = x, y = y }
gameloop.loadworld(world)
end
commands.ping = function(clientID)
gameloop.networkSend("pong")
end
commands.saveWorld = function(clientID, args)
local status, savename = utils.nextStringRecord(args)
if status == "failed" then
ui.addChatEntry("SERVER", "Failed to save world!")
elseif status == "sucess" then
ui.addChatEntry("SERVER", "saved world. " .. savename)
local world = { id = worldID, x = x, y = y }
levelloop.loadworld(world)
end
end
commands.playerJoin = function(clientID, args)
local nickname, avatarEncoded = utils.nextStringRecord(args)
avatarHash = love.data.decode("string", "base64", avatarEncoded)
ui.addChatEntry("", nickname .. " Joined the game")
local avatar = { image = love.graphics.newImage("textures/player/nephele/fallback.png") }
if gameloop.avatars[avatarHash] then
avatar = gameloop.avatars[avatarHash]
commands.ping = function(clientID)
levelloop.networkSend("pong")
end
players[clientID] = player.newPlayer({name = nickname, avatar = avatar.image})
players[clientID].label = love.graphics.newText(fonts.smallFont, nickname)
end
commands.playerLeave = function(clientID)
if players[clientID] then
local name = players[clientID].name
ui.addChatEntry("", name .. " Left the game")
players[clientID] = nil
end
end
commands.deletePhysics = function(clientID, args)
if clientID == camera.target then return end
if not players[clientID] then return end
physics.remove_solid(utils.getIntRecords(4, args))
end
commands.drawPhysics = function(clientID, args)
if clientID == camera.target then return end
if not players[clientID] then return end
physics.draw_solid(utils.getIntRecords(4, args))
end
commands.chatMessage = function(clientID, args)
local name
if clientID == "0" then
name = ""
else
if players[clientID] and players[clientID].name then
name = players[clientID].name
else
name = "UNKNOWN?"
commands.saveWorld = function(clientID, args)
local status, savename = utils.nextStringRecord(args)
if status == "failed" then
ui.addChatEntry("SERVER", "Failed to save world!")
elseif status == "sucess" then
ui.addChatEntry("SERVER", "saved world. " .. savename)
end
end
ui.addChatEntry(name, args)
commands.playerJoin = function(clientID, args)
local nickname, avatarEncoded = utils.nextStringRecord(args)
avatarHash = love.data.decode("string", "base64", avatarEncoded)
ui.addChatEntry("", nickname .. " Joined the game")
local avatar = { image = love.graphics.newImage("textures/player/nephele/fallback.png") }
if levelloop.avatars[avatarHash] then
avatar = levelloop.avatars[avatarHash]
end
participants[clientID] = player.newPlayer({name = nickname, avatar = avatar.image})
participants[clientID].label = love.graphics.newText(fonts.smallFont, nickname)
end
commands.playerLeave = function(clientID)
if participants[clientID] then
local name = participants[clientID].name
ui.addChatEntry("", name .. " Left the game")
participants[clientID] = nil
end
end
commands.deletePhysics = function(clientID, args)
if clientID == camera.target then return end
if not participants[clientID] then return end
physics.remove_solid(utils.getIntRecords(4, args))
end
commands.drawPhysics = function(clientID, args)
if clientID == camera.target then return end
if not participants[clientID] then return end
physics.draw_solid(utils.getIntRecords(4, args))
end
commands.chatMessage = function(clientID, args)
local name
if clientID == "0" then
name = ""
else
if participants[clientID] and participants[clientID].name then
name = participants[clientID].name
else
name = "UNKNOWN?"
end
end
ui.addChatEntry(name, args)
end
commands.clearCanvas = function(clientID)
drawing.clearAllCanvases()
end
end
commands.deleteTexture = sharedCommands.deleteTexture
commands.drawTexture = sharedCommands.drawTexture
commands.moveUpdate = sharedCommands.moveUpdate
commands.moveFlying = sharedCommands.moveFlying
commands.clearCanvas = function(clientID)
drawing.clearAllCanvases()
end
commands.fillCanvas = function(clientID, args)
local layer, hash = utils.nextStringRecord(args)
hash = love.data.decode("string", "base64", hash)
drawing.fillCanvas(layer, hash)
end
return commands

View File

@ -6,58 +6,64 @@ end
local utils = require("shared.utils")
function drawing.clearAllCanvases()
love.graphics.setCanvas(gameloop.Canvas.fg)
love.graphics.setCanvas(levelloop.Canvas.fg)
love.graphics.clear()
love.graphics.setCanvas(gameloop.Canvas.bg)
love.graphics.setCanvas(levelloop.Canvas.bg)
love.graphics.clear()
love.graphics.setCanvas(gameloop.Canvas.dbg)
love.graphics.setCanvas(levelloop.Canvas.dbg)
love.graphics.clear()
love.graphics.setCanvas()
gameloop.Canvas.physics = {}
levelloop.Canvas.physics = {}
end
function drawing.clearAllCanvasesNetwork()
gameloop.networkSend("clearCanvas")
levelloop.networkSend("clearCanvas")
drawing.clearAllCanvases()
end
function drawing.fillCanvas(layer, hash)
love.graphics.setCanvas(gameloop.Canvas[layer])
function drawing.fillCanvas(layer, hash, color)
love.graphics.setCanvas(levelloop.Canvas[layer])
love.graphics.clear()
for x = 0, gameloop.world.x -gameloop.textures[hash].image:getPixelWidth(),
gameloop.textures[hash].image:getPixelWidth() do
for y = 0, gameloop.world.y -gameloop.textures[hash].image:getPixelHeight(),
gameloop.textures[hash].image:getPixelHeight() do
love.graphics.draw(gameloop.textures[hash].image, x, y)
utils.color_push()
love.graphics.setColor(color)
for x = 0, levelloop.world.x -levelloop.textures[hash].image:getPixelWidth(),
levelloop.textures[hash].image:getPixelWidth() do
for y = 0, levelloop.world.y -levelloop.textures[hash].image:getPixelHeight(),
levelloop.textures[hash].image:getPixelHeight() do
love.graphics.draw(levelloop.textures[hash].image, x, y)
end
end
utils.color_pop()
love.graphics.setCanvas()
end
function drawing.fillCanvasNetwork(layer, hash)
gameloop.networkSend(utils.unit("fillCanvas", layer, love.data.encode("string", "base64", hash)))
drawing.fillCanvas(layer, hash)
function drawing.fillCanvasNetwork(layer, hash, color)
levelloop.networkSend(utils.unit("fillCanvas", layer,
love.data.encode("string", "base64", hash),
color[1], color[2], color[3], color[4] or "1"))
drawing.fillCanvas(layer, hash, color)
end
function drawing.keyreleased(key, _)
assert(drawing.color)
if key == "c" then
drawing.clearAllCanvasesNetwork()
end
if key == "f" then
drawing.fillCanvasNetwork("fg", drawing.cursorHash)
drawing.fillCanvasNetwork("fg", drawing.cursorHash, drawing.color)
end
if key == "b" then
drawing.fillCanvasNetwork("bg", drawing.cursorHash)
drawing.fillCanvasNetwork("bg", drawing.cursorHash, drawing.color)
end
end
local drawmouse = {}
function drawing.input(dt)
local textures = gameloop.textures
local textures = levelloop.textures
local cursor = drawing.cursor
if not cursor or not cursor.data then return end
assert(cursor, "Failed to find cursor")
@ -74,8 +80,8 @@ function drawing.input(dt)
end
mousex = mousex / scale - view.x
mousey = mousey / scale - view.y
if mousex > gameloop.world.x or
mousey > gameloop.world.y or
if mousex > levelloop.world.x or
mousey > levelloop.world.y or
mousex < 0 or
mousey < 0 then
return
@ -101,9 +107,9 @@ function drawing.input(dt)
local ctrlDown = love.keyboard.isDown("lctrl") or love.keyboard.isDown("rctrl")
if ctrlDown then
love.graphics.setCanvas(gameloop.Canvas.bg)
love.graphics.setCanvas(levelloop.Canvas.bg)
else
love.graphics.setCanvas(gameloop.Canvas.fg)
love.graphics.setCanvas(levelloop.Canvas.fg)
end
if love.mouse.isDown(1) then -- only delete
@ -156,7 +162,7 @@ function drawing.draw_texture(hash, x, y, layer, color)
if not color[4] then color[4] = 1 end
local last = drawing.lastTexture
if hash ~= last.hash or x ~= last.x or y ~= last.y or layer ~= last.layer then
gameloop.networkSend(utils.unit("drawTexture", x, y,
levelloop.networkSend(utils.unit("drawTexture", x, y,
layer, love.data.encode("string", "base64", hash), color[1], color[2], color[3], color[4]))
end
last.hash, last.x, last.y, last.layer = hash, x, y, layer
@ -169,7 +175,7 @@ function drawing.del_texture(x, y, width, height, layer)
local last = drawing.lastTextureDel
if x ~= last.x or y ~= last.y or width ~= last.width
or height ~= last.height or layer ~= last.layer then
gameloop.networkSend(utils.unit("deleteTexture", x, y, width, height, layer))
levelloop.networkSend(utils.unit("deleteTexture", x, y, width, height, layer))
last.x, last.y, last.width, last.height, last.layer = x, y, width, height, layer
end
end
@ -178,7 +184,7 @@ end
local lastDWP = { x = 0, y = 0, width = 0, height = 0}
function drawing.draw_solid(x, y, width, height)
if x ~= lastDWP.x or y ~= lastDWP.y or width ~= lastDWP.width or height ~= lastDWP.height then
gameloop.networkSend(utils.unit("drawPhysics", x, y, width, height))
levelloop.networkSend(utils.unit("drawPhysics", x, y, width, height))
physics.draw_solid(x, y, width, height)
lastDWP.x, lastDWP.y, lastDWP.width, lastDWP.height = x, y, width, height
end
@ -188,7 +194,7 @@ end
local lastRMP = { x = 0, y = 0, width = 0, height = 0}
function drawing.remove_solid(x, y, width, height)
if x ~= lastRMP.x or y ~= lastRMP.y or width ~= lastRMP.width or height ~= lastRMP.height then
gameloop.networkSend(utils.unit("deletePhysics", x, y, width, height))
levelloop.networkSend(utils.unit("deletePhysics", x, y, width, height))
physics.remove_solid(x, y, width, height)
lastRMP.x, lastRMP.y, lastRMP.width, lastRMP.height = x, y, width, height
end

View File

@ -1,8 +1,12 @@
gameloop = {}
gameloop.world = nil
gameloop.textures = {}
gameloop.avatars = {}
commands = require("lua.commands")
levelloop = {}
levelloop.CLIENT = true
levelloop.world = nil
levelloop.textures = {}
levelloop.avatars = {}
commands = {}
require("lua.commands")(commands)
require("shared.commands")(commands)
local socket = require "socket"
local utils = require("shared.utils")
@ -12,8 +16,8 @@ local errorHandler = require("shared.error")
local rpc = require("server.rpc")
local constants = require("server.constants")
gameloop.nwChecklist = {}
gameloop.Canvas = {}
levelloop.nwChecklist = {}
levelloop.Canvas = {}
local count = 1
local function normalDraw()
if count == 1 then print("use canvas!") count = 2 end
@ -23,14 +27,14 @@ local function normalDraw()
if drawBackground then
utils.color_push()
love.graphics.setColor(0.05, 0.05, 0.05)
love.graphics.rectangle("fill", math.floor(view.x) * scale, math.floor(view.y) * scale, gameloop.world.x * scale, gameloop.world.y * scale)
love.graphics.rectangle("fill", math.floor(view.x) * scale, math.floor(view.y) * scale, levelloop.world.x * scale, levelloop.world.y * scale)
love.graphics.setColor(1, 1, 1, 1)
love.graphics.draw(gameloop.Canvas.bg, layerTransform)
love.graphics.draw(levelloop.Canvas.bg, layerTransform)
utils.color_pop()
end
-- draw player
for i, player in pairs(players) do
for i, player in pairs(participants) do
local playerTransform = love.math.newTransform(
math.floor(player.x) * scale + math.floor(view.x) * scale,
math.floor(player.y) * scale + math.floor(view.y) * scale,
@ -51,7 +55,7 @@ local function normalDraw()
end
-- Draw foreground
love.graphics.draw(gameloop.Canvas.fg, layerTransform)
love.graphics.draw(levelloop.Canvas.fg, layerTransform)
-- Draw UI
love.graphics.draw(ui.buffer)
@ -62,10 +66,10 @@ local function debugDraw()
normalDraw()
local layerTransform = love.math.newTransform(math.floor(view.x) * scale, math.floor(view.y) * scale, 0, scale, scale)
love.graphics.draw(gameloop.Canvas.dbg, layerTransform)
love.graphics.draw(gameloop.Canvas.dbg2, layerTransform)
love.graphics.draw(levelloop.Canvas.dbg, layerTransform)
love.graphics.draw(levelloop.Canvas.dbg2, layerTransform)
love.graphics.setCanvas(gameloop.Canvas.dbg2)
love.graphics.setCanvas(levelloop.Canvas.dbg2)
love.graphics.clear()
love.graphics.setCanvas()
end
@ -74,7 +78,7 @@ end
local function normalNetworkSend(args)
if clientID == "0" then print("Invalid clientID?") end
local request = constants.protocolVersion ..US.. clientID ..US.. args
gameloop.client:send(request)
levelloop.client:send(request)
end
@ -82,14 +86,14 @@ local function debugNetworkSend(args)
assert(clientID ~= 0)
local request = constants.protocolVersion ..constants.US.. clientID ..constants.US.. args
print("=> " .. utils.pprint(request))
gameloop.client:send(request)
levelloop.client:send(request)
end
function normalNetworkSync()
local message, errorString = nil, false
while not errorString do
local message, errorString = gameloop.client:receive()
local message, errorString = levelloop.client:receive()
if not message then
if errorString == "timeout" then return else
error(errorString)
@ -109,7 +113,7 @@ end
function debugNetworkSync()
local message, errorString = nil, false
while not errorString do
local message, errorString = gameloop.client:receive()
local message, errorString = levelloop.client:receive()
if message then print("<= " .. utils.pprint(message)) end
if not message then
if errorString == "timeout" then return else
@ -129,17 +133,17 @@ end
local function errorhandlerNetwork(msg)
gameloop.networkSend(unit("playerLeave"))
levelloop.networkSend(unit("playerLeave"))
return errorHandler.redscreen(msg)
end
function gameloop.mousepressed(mousex, mousey)
function levelloop.mousepressed(mousex, mousey)
ui.mousepressed(mousex, mousey)
end
function gameloop.loadAvatars()
function levelloop.loadAvatars()
local container = {}
local entries = love.filesystem.getDirectoryItems("textures/player")
if #entries == 0 then return error("no avatars found") end
@ -157,17 +161,17 @@ function gameloop.loadAvatars()
end
end
end
gameloop.avatars = container
levelloop.avatars = container
end
function gameloop.init(server, nickname, avatarHash)
function levelloop.init(server, nickname, avatarHash)
local US = constants.US
love.errorhandler = errorHandler.redscreen
assert(server, "Gameloop called without server to connect to?")
assert(nickname, "Gameloop called without nickname?")
assert(avatarHash, "Gameloop called without avatar?")
gameloop.server = server
assert(server, "levelloop called without server to connect to?")
assert(nickname, "levelloop called without nickname?")
assert(avatarHash, "levelloop called without avatar?")
levelloop.server = server
scale = 1
@ -182,7 +186,7 @@ function gameloop.init(server, nickname, avatarHash)
window = {}
window.x, window.y = love.graphics.getDimensions()
players = {}
participants = {}
textures = {}
view = {}
@ -192,30 +196,29 @@ function gameloop.init(server, nickname, avatarHash)
-- Must be done now because it has to be ready before "init" returns from the server
-- which is /before/ the game world is loaded
gameloop.loadAvatars()
commands.commandsInit()
levelloop.loadAvatars()
gameloop.client = socket.udp()
gameloop.client:setpeername(server.adress, server.port)
gameloop.client:settimeout(0)
levelloop.client = socket.udp()
levelloop.client:setpeername(server.adress, server.port)
levelloop.client:settimeout(0)
print("Socketnname: " .. gameloop.client:getsockname())
print("Socketnname: " .. levelloop.client:getsockname())
print("Connecting to [" .. server.adress .."]:" .. server.port)
local request = constants.protocolVersion ..US.. "0" ..US.. utils.unit("init", nickname, love.data.encode("string", "base64", avatarHash))
gameloop.client:send(request)
levelloop.client:send(request)
if NETWORK_DEBUG then print("=> " .. utils.pprint(request)) end
if not NETWORK_DEBUG then
gameloop.networkSend = normalNetworkSend
gameloop.networkSync = normalNetworkSync
levelloop.networkSend = normalNetworkSend
levelloop.networkSync = normalNetworkSync
else
gameloop.networkSend = debugNetworkSend
gameloop.networkSync = debugNetworkSync
levelloop.networkSend = debugNetworkSend
levelloop.networkSync = debugNetworkSync
end
love.update = function(dt)
gameloop.networkSync(dt)
levelloop.networkSync(dt)
love.timer.sleep((1/60) -dt)
end
@ -236,8 +239,8 @@ function gameloop.init(server, nickname, avatarHash)
end
function gameloop.normalVisible(dt)
gameloop.networkSync(dt)
function levelloop.normalVisible(dt)
levelloop.networkSync(dt)
camera.input(dt)
physics.input(dt)
drawing.input(dt)
@ -247,20 +250,20 @@ function gameloop.normalVisible(dt)
end
function gameloop.reducedVisible(dt)
gameloop.networkSync(dt)
function levelloop.reducedVisible(dt)
levelloop.networkSync(dt)
physics.update(dt)
love.timer.sleep((1/60) -dt)
end
function gameloop.keypressed(key, _)
function levelloop.keypressed(key, _)
physics.keypressed(key, _)
camera.keypressed(key, _)
end
function gameloop.keyreleased(key, _)
function levelloop.keyreleased(key, _)
if key == "r" then
drawBackground = not drawBackground
end
@ -270,36 +273,35 @@ function gameloop.keyreleased(key, _)
end
function gameloop.loadworld(world)
function levelloop.loadworld(world)
-- Game connected!
--love.errorhandler = errorhandlerNetwork
print("make canvas!")
gameloop.Canvas.fg = love.graphics.newCanvas(world.x, world.y)
gameloop.Canvas.bg = love.graphics.newCanvas(world.x, world.y)
levelloop.Canvas.fg = love.graphics.newCanvas(world.x, world.y)
levelloop.Canvas.bg = love.graphics.newCanvas(world.x, world.y)
if PHYSICS_DEBUG then
gameloop.Canvas.dbg = love.graphics.newCanvas(world.x, world.y)
gameloop.Canvas.dbg2 = love.graphics.newCanvas(world.x, world.y)
levelloop.Canvas.dbg = love.graphics.newCanvas(world.x, world.y)
levelloop.Canvas.dbg2 = love.graphics.newCanvas(world.x, world.y)
end
gameloop.Canvas.physics = {}
commands.commandsWorldInit()
levelloop.Canvas.physics = {}
ui.init()
drawing.init()
love.update = gameloop.normalVisible
love.update = levelloop.normalVisible
love.visible = function(visible)
if visible then
love.update = gameloop.normalVisible
love.update = levelloop.normalVisible
else
love.update = gameloop.reducedVisible
love.update = levelloop.reducedVisible
end
end
drawBackground = true
love.keyreleased = gameloop.keyreleased
love.keypressed = gameloop.keypressed
love.mousepressed = gameloop.mousepressed
love.keyreleased = levelloop.keyreleased
love.keypressed = levelloop.keypressed
love.mousepressed = levelloop.mousepressed
if not PHYSICS_DEBUG then
love.draw = normalDraw
else
@ -315,8 +317,8 @@ function gameloop.loadworld(world)
end
love.quit = function()
gameloop.networkSend(utils.unit("playerLeave"))
levelloop.networkSend(utils.unit("playerLeave"))
end
gameloop.world = world
levelloop.world = world
end

View File

@ -118,7 +118,7 @@ end
function layout.drawHash(container, x, y, simulate)
local texture = gameloop.textures[container.hash]
local texture = levelloop.textures[container.hash]
local scale = container.scale or 1
if not texture.image then
texture.image = love.graphics.newImage(texture.data)
@ -153,7 +153,7 @@ function layout.bwColorPicker(container, x, y, simulate)
local iterationCount = (1.0 / granularity)
maxx = x + pointSize * iterationCount
table.insert(uiState, { granularity = granularity, pointSize = pointSize,
table.insert(layout.uiState, { granularity = granularity, pointSize = pointSize,
kind=container.kind,
x=x, x2=maxx, y=y, y2=y + pointSize })
else
@ -196,7 +196,7 @@ function layout.colorPicker(container, x, y, simulate)
local iterationCount = (1.0 / granularity) + 1
maxx = x + pointSize * iterationCount * iterationCount
table.insert(uiState, { granularity = granularity, pointSize = pointSize,
table.insert(layout.uiState, { granularity = granularity, pointSize = pointSize,
kind=container.kind,
x=x, x2=maxx, y=y, y2=myy })
else

View File

@ -80,7 +80,7 @@ function menu.mousepressed(mousex, mousey)
NETWORK_DEBUG = true
firstclient = false
end
local textures = gameloop.textures
local textures = levelloop.textures
local names = { "Herbert", "Thorben", "Martin", "Heinrich", "Dietrich", "Markus", "Florian", "Helmut", "Willhelm", "Fritz", "Gustav", "Konrad", "Berta", "Charlotte", "Hildegard", "Lieselotte", "Gudrun", "Giesela", "Margarete", "Antonia", "Friederike", "Clotilde", "Marlies", "Hedwig", "Agathe" }
local lastNames = { "Müller", "Schmidt", "Meier", "Bauer", "Werner", "Schumacher", "Bergmann", "Eisenhauer", "Heisenberg" }
@ -89,7 +89,7 @@ function menu.mousepressed(mousex, mousey)
local serverEntry = menu.serverlist[serverID]
local avatar = love.image.newImageData("textures/player/nephele/dog.png")
local avatarHash = love.data.hash("sha512", avatar:getString())
gameloop.init({ adress = serverEntry.host, port = serverEntry.port }, fullName, avatarHash)
levelloop.init({ adress = serverEntry.host, port = serverEntry.port }, fullName, avatarHash)
layout.uiState = {}
end
end

View File

@ -23,7 +23,7 @@ function physics.remove_solid(x, y, sizex, sizey)
asserts.number("physics.remove_solid", 4, x, y, sizex, sizey)
for coord_x=x, x + sizex-1 do
for coord_y=y, y + sizey-1 do
gameloop.Canvas.physics[coord_x*gameloop.world.x+coord_y] = nil
levelloop.Canvas.physics[coord_x*levelloop.world.x+coord_y] = nil
end
end
end
@ -33,7 +33,7 @@ function physics.draw_solid(x, y, sizex, sizey)
asserts.number("physics.draw_solid", 4, x, y, sizex, sizey)
for coord_x=x, x + sizex-1 do
for coord_y=y, y + sizey-1 do
gameloop.Canvas.physics[coord_x*gameloop.world.x+coord_y] = {0, 0, 0, true }
levelloop.Canvas.physics[coord_x*levelloop.world.x+coord_y] = {0, 0, 0, true }
end
end
end
@ -43,7 +43,7 @@ function draw_colision(x, y, x2, y2, pixelx, pixely)
utils.color_push()
love.graphics.setLineWidth(1)
love.graphics.setDefaultFilter("nearest", "nearest", 0)
love.graphics.setCanvas(gameloop.Canvas.dbg2)
love.graphics.setCanvas(levelloop.Canvas.dbg2)
if pixelx then
love.graphics.setColor(.6, 0, .6, 1)
love.graphics.rectangle("fill", x, y, x2, y2)
@ -62,7 +62,7 @@ function physics.is_blocked_x(x, y, sizex)
x, y = math.floor(x), math.floor(y)
asserts.number("physics.is_blocked_x", 3, x, y, sizex)
for coord_x=x ,x + sizex -1 do
if gameloop.Canvas.physics[coord_x * gameloop.world.x+y] and gameloop.Canvas.physics[coord_x*gameloop.world.x+y][4] then
if levelloop.Canvas.physics[coord_x * levelloop.world.x+y] and levelloop.Canvas.physics[coord_x*levelloop.world.x+y][4] then
if PHYSICS_DEBUG then draw_colision(x, y, sizex, 1, coord_x, y) end
return true
end
@ -76,7 +76,7 @@ function physics.is_blocked_y(x, y, sizey)
x, y = math.floor(x), math.floor(y)
asserts.number("physics.is_blocked_y", 3, x, y, sizey)
for coord_y=y, y + sizey -1 do
if gameloop.Canvas.physics[x*gameloop.world.x+coord_y] and gameloop.Canvas.physics[x*gameloop.world.x+coord_y][4] then
if levelloop.Canvas.physics[x*levelloop.world.x+coord_y] and levelloop.Canvas.physics[x*levelloop.world.x+coord_y][4] then
if PHYSICS_DEBUG then draw_colision(x, y, 1, sizey, x, coord_y) end
return true
end
@ -90,14 +90,14 @@ function physics.keypressed( key, code, isrepeat)
if isrepeat then return end
if camera.target == 0 then return end
player = players[camera.target]
player = participants[camera.target]
if key == "p" then
player.flying = not player.flying
if player.flying then
player.speed.y = 0
gameloop.networkSend(utils.unit("moveFlying", "true"))
levelloop.networkSend(utils.unit("moveFlying", "true"))
else
gameloop.networkSend(utils.unit("moveFlying", "false"))
levelloop.networkSend(utils.unit("moveFlying", "false"))
end
end
end
@ -105,7 +105,7 @@ end
function physics.input(dt)
if camera.target == 0 then return end
player = players[camera.target]
player = participants[camera.target]
local speedModified = dt * 20
if love.keyboard.isDown("rshift") or love.keyboard.isDown("lshift")
then
@ -127,7 +127,7 @@ function physics.input(dt)
local posx = player.x + player.avatar:getWidth()
local posy = player.y + player.avatar:getHeight()
if physics.is_blocked_x(posx - player.avatar:getWidth(), posy, player.avatar:getWidth()) or
player.y == gameloop.world.y - player.avatar:getHeight() then
player.y == levelloop.world.y - player.avatar:getHeight() then
player.speed.y = -25
end
end
@ -135,16 +135,16 @@ end
function physics.cap_world(width, height, newx, newy, new_sx, new_sy)
if newx > gameloop.world.x - width then
newx = gameloop.world.x - width
if newx > levelloop.world.x - width then
newx = levelloop.world.x - width
new_sx = 0
end
if newx < 0 then
newx = 0
new_sx = 0
end
if newy > gameloop.world.y - height then
newy = gameloop.world.y - height
if newy > levelloop.world.y - height then
newy = levelloop.world.y - height
new_sy = 0
end
if newy < 0 then
@ -157,7 +157,7 @@ end
local SKIP = false
function physics.update(dt)
SKIP = false
for i, player in pairs(players) do
for i, player in pairs(participants) do
assert(player.x and player.y and player.speed.y and player.speed.x, "Player " .. i .. " has an invalid position!")
--friction
@ -285,7 +285,7 @@ last.packet, last.x, last.y, last.speedx, last.speedy = 0, 0, 0, 0, 0
function physics.send_update(player, dt)
if last.packet > 0.03 then
if last.x ~= player.x or last.y ~= player.y then
gameloop.networkSend(utils.unit("moveUpdate", player.x, player.y, player.speed.x, player.speed.y))
levelloop.networkSend(utils.unit("moveUpdate", player.x, player.y, player.speed.x, player.speed.y))
last.packet = 0
last.x, last.y = player.x, player.y
last.speedx, last.speedy = player.speedx, player.speedy

View File

@ -37,14 +37,14 @@ function ui.keyreleased(key, _)
love.visible = function(visible)
if visible then
love.update = function(dt)
gameloop.networkSync(dt)
levelloop.networkSync(dt)
physics.update(dt)
camera.update(dt)
love.timer.sleep((1/60) -dt)
end
else
love.update = function(dt)
gameloop.networkSync(dt)
levelloop.networkSync(dt)
physics.update(dt)
end
end
@ -53,9 +53,9 @@ function ui.keyreleased(key, _)
else
love.visible = function(visible)
if visible then
love.update = gameloop.normalVisible
love.update = levelloop.normalVisible
else
love.update = gameloop.reducedVisible
love.update = levelloop.reducedVisible
end
end
ui.draw(window.x, window.y)
@ -72,14 +72,14 @@ function ui.keyreleased(key, _)
love.visible = function(visible)
if visible then
love.update = function(dt)
gameloop.networkSync(dt)
levelloop.networkSync(dt)
drawing.input(dt)
physics.update(dt)
camera.update(dt)
end
else
love.update = function(dt)
gameloop.networkSync(dt)
levelloop.networkSync(dt)
physics.update(dt)
end
end
@ -89,14 +89,14 @@ function ui.keyreleased(key, _)
if key == "return" and not love.keyboard.isDown("lalt") then
textEnabled = false
if textEntry ~= "" then
gameloop.networkSend(utils.unit("chatMessage", textEntry))
levelloop.networkSend(utils.unit("chatMessage", textEntry))
textEntry = ""
end
ui.draw(window.x, window.y)
love.keyboard.setTextInput(false)
love.keyreleased = gameloop.keyreleased
love.keypressed = gameloop.keypressed
love.update = gameloop.normalVisible
love.keyreleased = levelloop.keyreleased
love.keypressed = levelloop.keypressed
love.update = levelloop.normalVisible
elseif key == "backspace" then
textEntry = string.sub(textEntry, 0, #textEntry -1)
ui.draw(window.x, window.y)
@ -104,8 +104,8 @@ function ui.keyreleased(key, _)
end
love.keypressed = function(key, _) return end
else
love.keyreleased = gameloop.keyreleased
love.keypressed = gameloop.keypressed
love.keyreleased = levelloop.keyreleased
love.keypressed = levelloop.keypressed
end
end
@ -188,7 +188,7 @@ function ui.loadTextures(directory, container)
local status, imageData = pcall(love.image.newImageData, path);
if status then
local hash = love.data.hash("sha512", imageData:getString())
gameloop.textures[hash] = {data = imageData}
levelloop.textures[hash] = {data = imageData}
container[file] = hash
end
end
@ -198,7 +198,7 @@ end
function textureEntry(hash)
local texture = gameloop.textures[hash]
local texture = levelloop.textures[hash]
assert(texture, "No texture found for textureentry?")
assert(texture.data, "No imagedata found for textureentry?")
if not texture.image then
@ -228,7 +228,7 @@ end
function textureRun(entryTable, width)
local textures = gameloop.textures
local textures = levelloop.textures
local entries = {name = "naiveGrid", width = width - 20}
local entryTableSorted = {}
@ -384,7 +384,7 @@ function ui.menuDrawer(w, h)
}
end
function ui.draw(w, h)
window.x, window.y = w, h
love.graphics.setCanvas(ui.buffer)
@ -412,64 +412,65 @@ end
function ui.mousepressed(mousex, mousey)
local textures = gameloop.textures
local textures = levelloop.textures
if menuVisible then
for i, v in ipairs(layout.uiStateMenu) do
if mousex >= v.x and mousex <= v.x2 then
if mousey >= v.y and mousey <= v.y2 then
if v.kind == "button" then
if v.identifier == "save" then
gameloop.networkSend("saveWorld")
ui.keyreleased("escape")
elseif v.identifier == "disconnect" then
gameloop.networkSend(utils.unit("playerLeave"))
menu.init()
elseif v.identifier == "sideBarScaleTwo" then
ui.sidebarScale = 2
ui.draw(window.x, window.y)
ui.keyreleased("escape")
elseif v.identifier == "sideBarScaleOne" then
ui.sidebarScale = 1
ui.draw(window.x, window.y)
ui.keyreleased("escape")
end
if mousex >= v.x and mousex <= v.x2 and --hit testing
mousey >= v.y and mousey <= v.y2 then
if v.kind == "button" then
if v.identifier == "save" then
levelloop.networkSend("saveWorld")
ui.keyreleased("escape")
elseif v.identifier == "disconnect" then
levelloop.networkSend(utils.unit("playerLeave"))
menu.init()
elseif v.identifier == "sideBarScaleTwo" then
ui.sidebarScale = 2
ui.draw(window.x, window.y)
ui.keyreleased("escape")
elseif v.identifier == "sideBarScaleOne" then
ui.sidebarScale = 1
ui.draw(window.x, window.y)
ui.keyreleased("escape")
end
end
return -- Return after the first hit...
end
end
else
for i, v in ipairs(layout.uiState) do
if mousex >= v.x and mousex <= v.x2 then
if mousey >= v.y and mousey <= v.y2 then
if v.kind == "picker" then
assert(v.identifier, "No identifier in picker!")
drawing.cursorHash = v.identifier
drawing.cursor = textures[v.identifier]
assert(drawing.cursor, "No cursor texture found!")
ui.draw(window.x, window.y)
return
elseif v.kind == "tab" then
selectedTab = v.identifier
ui.draw(window.x, window.y)
return
elseif v.kind == "colorpicker" then
local scale = 1.0 / granularity
local red = math.floor((mousey - v.y) / v.pointSize) / scale
local green = math.floor((mousex - v.x) / v.pointSize / (scale + 1)) / scale
local blue = (math.floor((mousex - v.x) / v.pointSize) % (scale + 1)) / scale
drawing.color = {red, green, blue, 1}
ui.draw(window.x, window.y)
return
elseif v.kind == "bwColorPicker" then
local scale = 1.0 / granularity
local saturation = math.floor((mousex - v.x) / v.pointSize) / scale
drawing.color = {saturation, saturation, saturation, 1}
ui.draw(window.x, window.y)
return
end
if mousex >= v.x and mousex <= v.x2 and
mousey >= v.y and mousey <= v.y2 then
if v.kind == "picker" then
assert(v.identifier, "No identifier in picker!")
drawing.cursorHash = v.identifier
drawing.cursor = textures[v.identifier]
assert(drawing.cursor, "No cursor texture found!")
ui.draw(window.x, window.y)
return
elseif v.kind == "tab" then
selectedTab = v.identifier
ui.draw(window.x, window.y)
return
elseif v.kind == "colorpicker" then
print("Picker hit :D")
local scale = 1.0 / granularity
local red = math.floor((mousey - v.y) / v.pointSize) / scale
local green = math.floor((mousex - v.x) / v.pointSize / (scale + 1)) / scale
local blue = (math.floor((mousex - v.x) / v.pointSize) % (scale + 1)) / scale
print("I think the color is " .. red .. ":" .. green .. ":" .. blue)
drawing.color = {red, green, blue, 1}
ui.draw(window.x, window.y)
return
elseif v.kind == "bwColorPicker" then
local scale = 1.0 / granularity
local saturation = math.floor((mousex - v.x) / v.pointSize) / scale
drawing.color = {saturation, saturation, saturation, 1}
ui.draw(window.x, window.y)
return
end
return
end
end
end

View File

@ -6,9 +6,56 @@ end
function love.load(args)
if args[1] == "--server" then
print("Starting server!")
if not args[2]then
print("Missing server adress!")
love.event.quit()
return
end
local host = args[2]
local port = "11150"
if args[3] then port = args[3] end
local serverloop = require("server.main")
serverloop.init()
print("Starting server! [" .. host .. "] <" .. port .. ">")
serverloop.init({host, port})
elseif args[1] == "--client" then
if not args[2]then
print("Missing server adress!")
love.event.quit()
return
end
dofile "lua/gameloop.lua"
dofile "lua/layout.lua"
dofile "lua/ui.lua"
dofile "lua/camera.lua"
dofile "lua/physics.lua"
dofile "lua/drawing.lua"
setmetatable(_G, {
__index = function(self, idx)
if rawget(self, idx) == nil then
error("attempted to read implicit global:" .. idx)
end
end
})
PHYSICS_DEBUG = false
NETWORK_DEBUG = true
local host = args[2]
local port = "11150"
if args[3] then port = args[3] end
local avatar = love.image.newImageData("textures/player/nephele/fallback.png")
local avatarHash = love.data.hash("sha512", avatar:getString())
levelloop.init({ adress = host, port = port }, "Fallback player", avatarHash)
elseif args[1] == "--help" then
print(" --server [host] <port>")
print(" Start a local server")
print("")
print(" --help")
print(" print this help")
return
else
constants = require("server.constants")
local menu = require("lua.menuloop")

View File

@ -5,8 +5,8 @@ local rpc = require("server.rpc")
return function(commands)
function commands.chatMessage(clientID, args)
assert(clients[clientID])
print("Chat " .. clients[clientID].name .. ": " .. args)
assert(participants[clientID])
print("Chat " .. participants[clientID].name .. ": " .. args)
broadcast(clientID, utils.unit("chatMessage", args))
end
end

View File

@ -5,30 +5,30 @@ require("server.compat")
return function(commands)
function commands.moveUpdate(clientID, args)
if not clients[clientID] then rpc.print("moveUpdate: invalid clientid [" .. clientID .. "]") return end
if not participants[clientID] then rpc.print("moveUpdate: invalid clientid [" .. clientID .. "]") return end
local x, y, speedx, speedy = table.unpack(util.resolve(args))
clients[clientID].x = x
clients[clientID].y = y
clients[clientID].speedx = speedx
clients[clientID].speedy = speedy
participants[clientID].x = x
participants[clientID].y = y
participants[clientID].speedx = speedx
participants[clientID].speedy = speedy
broadcast(clientID, util.unit("moveUpdate", x, y, speedx, speedy))
end
function commands.moveFlying(clientID, args)
if not clients[clientID] then rpc.print("moveFlying: invalid clientid [" .. clientID .. "]") return end
if not participants[clientID] then rpc.print("moveFlying: invalid clientid [" .. clientID .. "]") return end
broadcast(clientID, util.unit("moveFlying", args))
end
function commands.deletePhysics(clientID, args)
if not clients[clientID] then rpc.print("deletePhysics: invalid clientid [" .. clientID .. "]") return end
if not participants[clientID] then rpc.print("deletePhysics: invalid clientid [" .. clientID .. "]") return end
broadcast(clientID, util.unit("deletePhysics", args))
end
function commands.drawPhysics(clientID, args)
if not clients[clientID] then rpc.print("drawPhysics: invalid clientid [" .. clientID .. "]") return end
if not participants[clientID] then rpc.print("drawPhysics: invalid clientid [" .. clientID .. "]") return end
broadcast(clientID, util.unit("drawPhysics", args))
end
end

View File

@ -3,7 +3,7 @@ local util = require("shared.utils")
return function(commands)
function commands.playerLeave(clientID)
print("Old client disconnected. id: [" .. clientID .. "]")
clients[clientID] = nil
participants[clientID] = nil
broadcast(clientID, "playerLeave")
end
end

View File

@ -26,8 +26,8 @@ return function(commands)
local result = love.filesystem.createDirectory(directory)
-- TODO check this result...
if result then
serverloop.Canvas.fg:newImageData():encode("png", directory .. "/fg.png")
serverloop.Canvas.bg:newImageData():encode("png", directory .. "/bg.png")
levelloop.Canvas.fg:newImageData():encode("png", directory .. "/fg.png")
levelloop.Canvas.bg:newImageData():encode("png", directory .. "/bg.png")
print("saved world. " .. savename)
broadcast("0", util.unit("saveWorld", "sucess", "" .. savename))
return

View File

@ -13,8 +13,7 @@ require("server.commands.physics")(commands)
require("server.commands.drawing")(commands)
require("server.commands.chat")(commands)
require("server.commands.saving")(commands)
sharedCommands = require("shared.commands")
require("shared.commands")(commands)
local errorHandler = require("shared.error")
@ -24,17 +23,17 @@ require("server.unpriviliged_commands.init")(unpriviligedCommands)
server = assert(socket.udp())
local ip, port = nil, nil
clients = {}
participants = {}
serverloop = {}
serverloop.textures = {}
levelloop = {}
levelloop.textures = {}
server:settimeout(0)
if not server or not socket then error("failed to listen on socket") end
function broadcast(clientID, message)
local payload = util.unit(protocolVersion, clientID, message)
for i, player in pairs(clients) do
for i, player in pairs(participants) do
if i ~= clientID then
server:sendto(payload, player.ip, player.port)
print("<= " .. payload)
@ -57,7 +56,7 @@ function loadTextures(directory, container)
local status, imageData = pcall(love.image.newImageData, path);
if status then
local hash = love.data.hash("sha512", imageData:getString())
serverloop.textures[hash] = {data = imageData}
levelloop.textures[hash] = {data = imageData}
container[file] = hash
end
end
@ -99,18 +98,18 @@ function mainloop(dt)
end
function serverloop.init(host)
function levelloop.init(host)
love.errorhandler = errorHandler.redscreen
status, value = server:setsockname(host[1], host[2])
if not status then
error("Server could not be started :( " .. value)
end
print("Server startup. listening on " .. server:getsockname())
loadTextures("textures/blocks", serverloop.textures)
serverloop.Canvas = {}
serverloop.Canvas.fg = love.graphics.newCanvas(constants.world.x, constants.world.y)
serverloop.Canvas.bg = love.graphics.newCanvas(constants.world.x, constants.world.y)
sharedCommands.commandsInit()
loadTextures("textures/blocks", levelloop.textures)
levelloop.world = constants.world
levelloop.Canvas = {}
levelloop.Canvas.fg = love.graphics.newCanvas(levelloop.world.x, levelloop.world.y)
levelloop.Canvas.bg = love.graphics.newCanvas(levelloop.world.x, levelloop.world.y)
print("Startup!")
love.update = mainloop
love.draw = function()
@ -123,4 +122,4 @@ function serverloop.init(host)
love.mousepressed = function() return end
end
return serverloop
return levelloop

View File

@ -1,49 +0,0 @@
print("Singleplayer Startup")
local constants = require("constants")
local rpc = require("rpc")
local socket = require("socket")
local v1_message = {}
require("physics")(v1_message)
require("world")(v1_message)
local server = assert(socket.udp())
local ip, port = nil, nil
local clientCount = 0
local clients = {}
client:settimeout(0)
local clientToServer = love.thread.getChannel ( "c2s" );
local serverToClient = love.thread.getChannel ( "s2c" );
assert(server:setsockname("*", 42069))
if not server or not socket then error("failed to listen on socket") end
while true do
::nw_next::
print("iteration start")
local data = clientToServer:demand()
print("received data from " .. ip)
for _, req in ipairs(rpc.parse_multiple(data)) do
if req.clientid == 0 then
count = count + 1
response = "rq" .. constants.US .. "cid" .. constants.US .. count
clients[count] = { ip = ip, port = port }
end
local response = rpc.eval(v1_message, req)
if response then
local payload = "poppyV001" .. constants.US .. "0" .. constants.US .. response
print("sending response " .. payload)
assert(serverToClient:send(payload))
else
print(req .. " had no return value!")
end
end
print("iteration over")
end
::nw_break::

View File

@ -10,10 +10,10 @@ return function(commands)
function commands.init(args, ip, port)
clientCount = clientCount +1
local nickname, avatar = utils.nextStringRecord(args)
clients[clientCount] = { ip = ip, port = port, name = nickname, avatar = avatar }
participants[clientCount] = { ip = ip, port = port, name = nickname, avatar = avatar }
print("New client connected. Granting id: [" .. clientCount .. "] IP: " .. ip .. " Port:" .. port)
for i, client in pairs(clients) do
for i, client in pairs(participants) do
if i ~= clientCount then
-- to Existing client
local payload = utils.unit(protocolVersion, clientCount, "playerJoin", nickname, avatar)

View File

@ -2,97 +2,96 @@ local player = require("lua.player")
local utils = require("shared.utils")
local commands = {}
local canvas = {}
local players
local textures
return function(commands)
commands.moveUpdate = function(clientID, args)
if not participants[clientID] then return end
local x, args = utils.nextIntRecord(args)
local y, args = utils.nextIntRecord(args)
local speedx, args = utils.nextIntRecord(args)
local speedy = utils.clean(args:gsub("^.-\31",""))
function commands.commandsInit()
if gameloop then -- client
CLIENT = true
players = _G.players
textures = gameloop.textures
else
SERVER = true
players = _G.clients
textures = serverloop.textures
canvas.fg = serverloop.Canvas.fg
canvas.bg = serverloop.Canvas.bg
participants[clientID].x = x
participants[clientID].y = y
if not participants[clientID].speed then participants[clientID].speed = {} end
participants[clientID].speed.x = speedx
participants[clientID].speed.y = speedy
end
end
function commands.commandsWorldInit()
if CLIENT then
canvas.fg = gameloop.Canvas.fg
canvas.bg = gameloop.Canvas.bg
commands.moveFlying = function(clientID, args)
if not participants[clientID] then return end
participants[clientID].flying = (args == "true")
end
end
commands.moveUpdate = function(clientID, args)
if not players[clientID] then return end
local x, args = utils.nextIntRecord(args)
local y, args = utils.nextIntRecord(args)
local speedx, args = utils.nextIntRecord(args)
local speedy = utils.clean(args:gsub("^.-\31",""))
players[clientID].x = x
players[clientID].y = y
players[clientID].speed.x = speedx
players[clientID].speed.y = speedy
end
commands.moveFlying = function(clientID, args)
if not players[clientID] then return end
players[clientID].flying = (args == "true")
end
commands.drawTexture = function(clientID, args)
if _G.camera then
if clientID == camera.target then return end
commands.drawTexture = function(clientID, args)
if _G.camera then
if clientID == camera.target then return end
end
local x, args = utils.nextIntRecord(args)
local y, args = utils.nextIntRecord(args)
local layer, args = utils.nextStringRecord(args)
local hashEncoded, args = utils.nextStringRecord(args)
hash = love.data.decode("string", "base64", hashEncoded)
local r, args = utils.nextIntRecord(args)
local g, args = utils.nextIntRecord(args)
local b, args = utils.nextIntRecord(args)
a = tonumber(args) or 1
if not textures[hash] then error("Failed to find hash!") return end
if not textures[hash].image then
textures[hash].image = love.graphics.newImage(textures[hash].data)
end
love.graphics.setCanvas(levelloop.Canvas[layer])
love.graphics.setBlendMode("alpha")
utils.color_push()
love.graphics.setColor(r, g, b ,a )
love.graphics.draw(textures[hash].image, x, y)
utils.color_pop()
love.graphics.setCanvas()
end
local x, args = utils.nextIntRecord(args)
local y, args = utils.nextIntRecord(args)
local layer, args = utils.nextStringRecord(args)
local hashEncoded, args = utils.nextStringRecord(args)
hash = love.data.decode("string", "base64", hashEncoded)
local r, args = utils.nextIntRecord(args)
local g, args = utils.nextIntRecord(args)
local b, args = utils.nextIntRecord(args)
a = tonumber(args) or 1
if not textures[hash] then error("Failed to find hash!") return end
if not textures[hash].image then
textures[hash].image = love.graphics.newImage(textures[hash].data)
end
love.graphics.setCanvas(canvas[layer])
love.graphics.setBlendMode("alpha")
commands.deleteTexture = function(clientID, args)
if _G.camera then
if clientID == camera.target then return end
end
local x, args = utils.nextIntRecord(args)
local y, args = utils.nextIntRecord(args)
local width, args = utils.nextIntRecord(args)
local height, layer = utils.nextIntRecord(args)
love.graphics.setCanvas(canvas[layer])
love.graphics.setBlendMode("replace")
utils.color_push()
love.graphics.setColor(r, g, b ,a )
love.graphics.draw(textures[hash].image, x, y)
love.graphics.setColor(0,0,0,0)
love.graphics.rectangle("fill", x, y, width, height)
utils.color_pop()
love.graphics.setCanvas()
end
commands.deleteTexture = function(clientID, args)
if _G.camera then
if clientID == camera.target then return end
love.graphics.setBlendMode("alpha")
love.graphics.setCanvas()
end
local x, args = utils.nextIntRecord(args)
local y, args = utils.nextIntRecord(args)
local width, args = utils.nextIntRecord(args)
local height, layer = utils.nextIntRecord(args)
love.graphics.setCanvas(canvas[layer])
love.graphics.setBlendMode("replace")
utils.color_push()
love.graphics.setColor(0,0,0,0)
love.graphics.rectangle("fill", x, y, width, height)
utils.color_pop()
love.graphics.setBlendMode("alpha")
love.graphics.setCanvas()
end
return commands
commands.fillCanvas = function(clientID, args)
local layer, args = utils.nextStringRecord(args)
local hashEncoded, args = utils.nextStringRecord(args)
hash = love.data.decode("string", "base64", hashEncoded)
local r, args = utils.nextIntRecord(args)
local g, args = utils.nextIntRecord(args)
local b, args = utils.nextIntRecord(args)
a = tonumber(args)
love.graphics.setCanvas(levelloop.Canvas[layer])
love.graphics.clear()
utils.color_push()
love.graphics.setColor({r, g, b, a})
for x = 0, levelloop.world.x -levelloop.textures[hash].image:getPixelWidth(),
levelloop.textures[hash].image:getPixelWidth() do
for y = 0, levelloop.world.y -levelloop.textures[hash].image:getPixelHeight(),
levelloop.textures[hash].image:getPixelHeight() do
love.graphics.draw(levelloop.textures[hash].image, x, y)
end
end
utils.color_pop()
love.graphics.setCanvas()
end
end