Improved netcode, added chips

It also won't crash if a player dies!
This commit is contained in:
LDDestroier 2019-03-11 02:37:04 -04:00 committed by GitHub
parent e40e30798e
commit aa112c4965
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 311 additions and 96 deletions

407
ccbn.lua
View File

@ -381,15 +381,21 @@ act.player.newPlayer = function(x, y, owner, direction, image)
custom = false
},
chipQueue = {
"shockwave",
"invis",
"airshot",
"minibomb",
"lilbomb",
"crossbomb",
"bigbomb",
"boomer",
"cannon",
"sword",
"widesword",
"longsword",
"lifesword"
"fightersword",
"lifesword",
"muramasa",
}
}
end
@ -405,6 +411,100 @@ local checkPlayerAtPos = function(x, y, ignoreThisOne)
end
end
local control = {
moveUp = keys.up,
moveDown = keys.down,
moveLeft = keys.left,
moveRight = keys.right,
buster = keys.z,
chip = keys.x,
custom = keys.c
}
local getControls = function()
if players[you] then
for k,v in pairs(control) do
players[you].control[k] = keysDown[v] or false
end
end
end
local checkIfSolid = function(x, y)
x, y = round(x), round(y)
if stage.panels[y] then
if stage.panels[y][x] then
if stage.panels[y][x].crackedLevel < 2 then
return true
end
end
end
return false
end
local checkIfWalkable = function(x, y, p)
x, y = round(x), round(y)
if checkIfSolid(x, y) then
if (not stage.panels[y][x].reserved) or stage.panels[y][x].reserved == p then
if stage.panels[y][x].owner == players[p].owner or stage.panels[y][x].owner == 0 then
return true
end
end
end
return false
end
local movePlayer = function(pID, xmove, ymove, doCooldown)
local player = players[pID]
if (xmove ~= 0 or ymove ~= 0) and checkIfWalkable(player.x + xmove, player.y + ymove, pID) then
player.x = player.x + xmove
player.y = player.y + ymove
if doCooldown then
player.cooldown.move = 3
end
return true
else
return false
end
end
local movePlayers = function()
local xmove, ymove, p
for i = 1, #players do
xmove, ymove = 0, 0
p = players[i]
if p.cooldown.move == 0 then
if p.control.moveUp then
ymove = -1
elseif p.control.moveDown then
ymove = 1
elseif p.control.moveRight then
xmove = 1
elseif p.control.moveLeft then
xmove = -1
end
movePlayer(i, xmove, ymove, true)
end
end
end
local reduceCooldowns = function()
for i = 1, #players do
for k,v in pairs(players[i].cooldown) do
players[i].cooldown[k] = math.max(0, v - 1)
end
end
for y, row in pairs(stage.damage) do
for x, panel in pairs(row) do
for owner, damageData in pairs(panel) do
stage.damage[y][x][owner].time = math.max(0, damageData.time - 1)
if damageData.time == 0 then
stage.damage[y][x][owner] = nil
end
end
end
end
end
local chips = {
buster = {
@ -467,6 +567,99 @@ local chips = {
end
},
shockwave = {
info = {
name = "ShockWave",
description = "Piercing ground wave!",
cooldown = {
shoot = 14,
move = 7
}
},
logic = function(info)
if info.frame == 0 then
info.x = info.x + info.direction / 2
end
info.x = info.x + (3 / stage.panelWidth) * info.direction
info.y = info.y
act.stage.setDamage(info.x, info.y, 60, info.owner, 10)
if info.frame > 50 or not checkIfSolid(info.x, info.y) then
return false
else
return true
end
end
},
shotgun = {
info = {
name = "Cannon",
description = "Hits enemy as well as the panel behind!",
cooldown = {
shoot = 10,
move = 5
}
},
logic = function(info)
info.x = info.x + (2 / stage.panelWidth) * info.direction
info.y = info.y
act.stage.setDamage(info.x, info.y, 40, info.owner, 2)
-- delete projectile if collide with player
local hasStruck = false
local cPlayer = checkPlayerAtPos(info.x, info.y, info.owner)
if cPlayer then
if players[cPlayer].cooldown.iframe == 0 and players[cPlayer].owner ~= info.owner then
hasStruck = cPlayer
end
end
if info.frame > 50 or hasStruck then
if hasStruck then
act.stage.setDamage(info.x + info.direction, info.y, 40, info.owner, 2)
end
return false
else
return true, {{images.cannon, info.x, info.y}}
end
end
},
airshot = {
info = {
name = "AirShot",
description = "Fires a pushing shot forwards!",
cooldown = {
shoot = 8,
move = 5
}
},
logic = function(info)
info.x = info.x + (2 / stage.panelWidth) * info.direction
info.y = info.y
act.stage.setDamage(info.x, info.y, 20, info.owner, 2)
-- delete projectile if collide with player
local hasStruck = false
local cPlayer = checkPlayerAtPos(info.x, info.y, info.owner)
if cPlayer then
if players[cPlayer].cooldown.iframe == 0 and players[cPlayer].owner ~= info.owner then
hasStruck = cPlayer
end
end
if info.frame > 50 or hasStruck then
if hasStruck then
if movePlayer(hasStruck, info.direction, 0, true) then
act.stage.setDamage(info.x + info.direction, info.y, 20, info.owner, 2)
end
end
return false
else
return true, {{images.cannon, info.x, info.y}}
end
end
},
sword = {
info = {
name = "Sword",
@ -484,6 +677,23 @@ local chips = {
end
},
muramasa = {
info = {
name = "Muramasa",
description = "Slash for as much damage as you have taken!",
cooldown = {
shoot = 8,
move = 5
}
},
logic = function(info)
act.stage.setDamage(info.x + info.direction, info.y, math.min(info.player.maxHealth - info.player.health, 1000), info.owner, 4)
return false
end
},
longsword = {
info = {
name = "LongSword",
@ -502,6 +712,25 @@ local chips = {
end
},
fightersword = {
info = {
name = "FighterSword",
description = "Slash forwards 3 panels!",
cooldown = {
shoot = 8,
move = 5
}
},
logic = function(info)
act.stage.setDamage(info.x + info.direction, info.y, 100, info.owner, 4)
act.stage.setDamage(info.x + info.direction * 2, info.y, 100, info.owner, 4)
act.stage.setDamage(info.x + info.direction * 3, info.y, 100, info.owner, 4)
return false
end
},
widesword = {
info = {
name = "WideSword",
@ -543,6 +772,21 @@ local chips = {
end
},
invis = {
info = {
name = "Invis",
description = "Makes you invincible for a short time!",
cooldown = {
shoot = 10,
move = 5
}
},
logic = function(info)
info.player.cooldown.iframe = 50
return false
end
},
boomer = {
info = {
name = "Boomer",
@ -653,11 +897,37 @@ local chips = {
local maxFrames = 10
local parabola = math.sin((math.pi / maxFrames) * info.frame) * 2
if parabola < 0.1 and info.frame > 3 then
act.stage.setDamage(info.x, info.y - 1, 50, info.owner, 2, false)
act.stage.setDamage(info.x, info.y, 50, info.owner, 2, false)
act.stage.setDamage(info.x, info.y + 1, 50, info.owner, 2, false)
act.stage.setDamage(info.x - 1, info.y, 50, info.owner, 2, false)
act.stage.setDamage(info.x + 1, info.y, 50, info.owner, 2, false)
act.stage.setDamage(info.x, info.y - 1, 70, info.owner, 2, false)
act.stage.setDamage(info.x, info.y, 70, info.owner, 2, false)
act.stage.setDamage(info.x, info.y + 1, 70, info.owner, 2, false)
act.stage.setDamage(info.x - 1, info.y, 70, info.owner, 2, false)
act.stage.setDamage(info.x + 1, info.y, 70, info.owner, 2, false)
return false
else
info.x = info.x + (maxDist / maxFrames) * info.direction
end
return true, {{images.cannon, info.x, info.y - parabola}}
end
},
bigbomb = {
info = {
name = "BigBomb",
description = "Lob a 3x3 grenade 2 panels forward!",
cooldown = {
shoot = 10,
move = 5
}
},
logic = function(info)
local maxDist = 3
local maxFrames = 10
local parabola = math.sin((math.pi / maxFrames) * info.frame) * 2
if parabola < 0.1 and info.frame > 3 then
for y = -1, 1 do
for x = -1, 1 do
act.stage.setDamage(info.x + x, info.y + y, 90, info.owner, 2, false)
end
end
return false
else
info.x = info.x + (maxDist / maxFrames) * info.direction
@ -751,9 +1021,11 @@ local render = function()
buffer[#buffer + 1] = {makeRectangle(scr_x, scr_y, "f", "f", "f"), 1, 1}
drawImage(colorSwap(merge(table.unpack(buffer)), {[" "] = "f"}), 1, 1)
if chips[players[you].chipQueue[1]] then
term.setCursorPos(1, scr_y)
term.write(chips[players[you].chipQueue[1]].info.name)
if players[you] then
if chips[players[you].chipQueue[1]] then
term.setCursorPos(1, scr_y)
term.write(chips[players[you].chipQueue[1]].info.name)
end
end
local HPs = {{},{}}
@ -775,79 +1047,6 @@ local render = function()
end
end
local control = {
moveUp = keys.up,
moveDown = keys.down,
moveLeft = keys.left,
moveRight = keys.right,
buster = keys.z,
chip = keys.x,
custom = keys.c
}
local getControls = function()
for k,v in pairs(control) do
players[you].control[k] = keysDown[v] or false
end
end
local checkIfWalkable = function(x, y, p)
if stage.panels[y] then
if stage.panels[y][x] then
if stage.panels[y][x].crackedLevel < 2 then
if (not stage.panels[y][x].reserved) or stage.panels[y][x].reserved == p then
if stage.panels[y][x].owner == players[p].owner or stage.panels[y][x].owner == 0 then
return true
end
end
end
end
end
return false
end
local movePlayers = function()
local xmove, ymove, p
for i = 1, #players do
xmove, ymove = 0, 0
p = players[i]
if p.cooldown.move == 0 then
if p.control.moveUp then
ymove = -1
elseif p.control.moveDown then
ymove = 1
elseif p.control.moveRight then
xmove = 1
elseif p.control.moveLeft then
xmove = -1
end
if (xmove ~= 0 or ymove ~= 0) and checkIfWalkable(p.x + xmove, p.y + ymove, i) then
p.x = p.x + xmove
p.y = p.y + ymove
p.cooldown.move = 3
end
end
end
end
local reduceCooldowns = function()
for i = 1, #players do
for k,v in pairs(players[i].cooldown) do
players[i].cooldown[k] = math.max(0, v - 1)
end
end
for y, row in pairs(stage.damage) do
for x, panel in pairs(row) do
for owner, damageData in pairs(panel) do
stage.damage[y][x][owner].time = math.max(0, damageData.time - 1)
if damageData.time == 0 then
stage.damage[y][x][owner] = nil
end
end
end
end
end
local getInput = function()
local evt
while true do
@ -871,6 +1070,7 @@ local getInput = function()
end
local runGame = function()
local evt, getStateInfo
while true do
FRAME = FRAME + 1
@ -912,7 +1112,12 @@ local runGame = function()
for k,v in pairs(chips[player.chipQueue[1]].info.cooldown or {}) do
player.cooldown[k] = v
end
table.remove(player.chipQueue, 1)
if false then
table.remove(player.chipQueue, 1)
else
player.chipQueue[#player.chipQueue + 1] = player.chipQueue[1]
table.remove(player.chipQueue, 1)
end
end
end
elseif player.control.buster then
@ -930,23 +1135,31 @@ local runGame = function()
command = "get_state",
players = players,
projectiles = projectiles,
stage = stage,
stageDamage = stage.damage,
stagePanels = stage.panels,
id = id
})
sleep(gameDelayInit)
else
getControls()
transmit({
gameID = gameID,
command = "set_controls",
id = yourID,
pID = you,
control = players[you].control
})
if players[you] then
transmit({
gameID = gameID,
command = "set_controls",
id = yourID,
pID = you,
control = players[you].control
})
end
evt, getStateInfo = os.pullEvent("ccbn_get_state")
players = getStateInfo.players
projectiles = getStateInfo.projectiles
stage.damage = getStateInfo.stageDamage
stage.panels = getStateInfo.stagePanels
end
render()
sleep(gameDelayInit)
end
end
@ -970,10 +1183,12 @@ local interpretNetMessage = function(msg)
end
else
if msg.command == "get_state" then
players = msg.players
projectiles = msg.projectiles
stage.panels = msg.stage.panels
stage.damage = msg.stage.damage
os.queueEvent("ccbn_get_state", {
players = msg.players,
projectiles = msg.projectiles,
stageDamage = msg.stageDamage,
stagePanels = msg.stagePanels
})
end
end
end