Compare commits

...

2 Commits

Author SHA1 Message Date
bad8452f3c
migrate ships to mknew style 2023-09-30 14:24:31 -07:00
f49407baca
move ship typedefs before ship impls 2023-09-30 14:11:36 -07:00

View File

@ -153,7 +153,7 @@ function init_hpcols()
end end
function wipe_level() function wipe_level()
primary_ship = new_p1() primary_ship = player.new()
init_hpcols() init_hpcols()
pships = linked_list.new() pships = linked_list.new()
pships:push_back(primary_ship) pships:push_back(primary_ship)
@ -441,21 +441,149 @@ function grab_p1_butts()
end end
-->8 -->8
--ships, including player --ship behavior
-- XXX BOOKMARK XXX scrollrate = 0.25 --in px/frame
function init_ship_mt() ship_m = {
setmetatable(player, ship_t)
setmetatable(frownie, ship_t) -- ships have no shield by default
setmetatable(blocky, frownie_t) shield = 0,
setmetatable(chasey, ship_t) maxshield = 0,
shieldcost = 32767.9,
shieldcooldown = 180,
-- default generator behavior:
-- 10 seconds for a full charge
max_power = 600,
power = 600,
generator = 1, -- power gen per frame
invincible_until = -32768,
slip = true, -- most enemies slide
xmomentum = 0,
ymomentum = 0,
}
mknew(ship_m)
function ship_m:die()
self.dead = true
if (self.hp <= 0) boom(self.x+self.size*4, self.y+self.size*4,12*self.size, self.boss)
end end
function ship_m:move()
self:refresh_shield()
self.power = min(self.max_power, self.power + self.generator)
butt = self:grab_butts()
if (butt[5] > 0) self:maybe_shoot(self.main_gun)
if (butt[4] > 0) self:maybe_shoot(self.special_gun)
if (butt[0]-butt[1] ~= 0 or butt[2]-butt[3] ~= 0) spark(self.sparks, self.x + 4*self.size, self.y + 4*self.size, butt, self.thrust, self.sparkodds)
self.xmomentum += (self.thrust * butt[1]) - (self.thrust * butt[0])
self.ymomentum += (self.thrust * butt[3]) - (self.thrust * butt[2])
self.xmomentum = mid(-self.maxspd, self.maxspd, self.xmomentum)
self.ymomentum = mid(-self.maxspd, self.maxspd, self.ymomentum)
self.x += self.xmomentum
self.y += self.ymomentum
if self == primary_self then
self.x = mid(0, 112 - 8 * self.size, self.x)
self.y = mid(0, 128 - 8 * self.size, self.y)
end
--friction
local d = self.drag
self.xmomentum -= mid(d, -d, self.xmomentum)
self.ymomentum -= mid(d, -d, self.ymomentum)
-- "scrolling" behavior
if self.slip then
self.y += scrollrate
if self.y >= 128 then
self:die()
return true
end
end
return false
end
function ship_m:draw()
if(self.fx_pal) pal(self.fx_pal)
spr(self.sprite, self.x, self.y, self.size, self.size)
pal()
end
function hurtbox(ship)
local h = ship.hurt
return {
x=ship.x + h.x_off,
y=ship.y + h.y_off,
width=h.width,
height=h.height
}
end
function ship_m:maybe_shoot(gun)
if (not gun) return
if (self.power < gun.power) return
if (not gun:shoot(self.x + self.fire_off_x, self.y + self.fire_off_y)) return
self.power -= gun.power
end
function ship_m:hitship(other)
return self:hitsomething(1)
end
function ship_m:hitbullet(b)
return self:hitsomething(b.damage)
end
function ship_m:hitsomething(dmg)
if (dmg <= 0) return false
if (lframe < self.invincible_until) return false
self.shield_refresh_ready = lframe + self.shieldcooldown
if self.shield >= dmg then
self.shield -= dmg
self:ow(true)
return false
end
dmg -= self.shield
self.shield = 0
self.hp -= dmg
if self.hp <= 0 then
self:die()
return true
end
self:ow(false)
return false
end
function ship_m:ow(shielded)
if (shielded) then
blip(self,12,3)
return
end
blip(self, 7, 3)
end
function ship_m:refresh_shield()
if (self.shield >= self.maxshield) return
if (lframe < self.shield_refresh_ready) return
if (self.power < self.shieldcost) return
self.shield += 1
self.power -= self.shieldcost
self.shield_refresh_ready = lframe + self.shieldcooldown
end
-->8
--ships, including player
firespark = split"9, 8, 2, 5, 1" firespark = split"9, 8, 2, 5, 1"
smokespark = split"13, 13, 5, 5" smokespark = split"13, 13, 5, 5"
player = { player = ship_m.new{
--shape --shape
sprite = 1, --index of ship sprite sprite = 1, --index of ship sprite
size = 1, --all ships are square; how many 8x8 sprites? size = 1, --all ships are square; how many 8x8 sprites?
@ -504,20 +632,13 @@ player = {
return butts return butts
end end
} }
mknew(player,
function(p)
p.main_gun = new_gun_of(zap_gun_t, false)
end
)
player_t = { frownie = ship_m.new{
__index = player
}
function new_p1()
p = {
main_gun = new_gun_of(zap_gun_t, false)
}
setmetatable(p, player_t)
return p
end
frownie = {
--shape --shape
sprite = 3, --index of ship sprite sprite = 3, --index of ship sprite
size = 1, --all ships are square; how many 8x8 sprites? size = 1, --all ships are square; how many 8x8 sprites?
@ -555,11 +676,9 @@ frownie = {
return butts return butts
end, -- button fetch algorithm end, -- button fetch algorithm
} }
frownie_t = { mknew(frownie)
__index = frownie
}
blocky = { blocky = frownie.new{
sprite = 10, sprite = 10,
hp = 2, hp = 2,
hurt = { hurt = {
@ -575,16 +694,13 @@ blocky = {
else else
self.sprite = 10 self.sprite = 10
end end
ship_t.__index.ow(self) ship_m.ow(self)
end end
} }
mknew(blocky)
blocky_t = {
__index = blocky
}
function spawn_spewy_at(x, y) function spawn_spewy_at(x, y)
local spewy = { local spewy = frownie.new{
x = x, x = x,
y = y, y = y,
sprite = 26, sprite = 26,
@ -608,12 +724,11 @@ function spawn_spewy_at(x, y)
return butts return butts
end, end,
} }
setmetatable(spewy, frownie_t)
eships:push_back(spewy) eships:push_back(spewy)
return spewy return spewy
end end
chasey = { chasey = ship_m.new{
sprite = 5, sprite = 5,
size = 1, size = 1,
hurt = { hurt = {
@ -646,22 +761,20 @@ chasey = {
return butts return butts
end, end,
} }
chasey_t = { mknew(chasey)
__index = chasey
}
function spawn_chasey_at(x, y) function spawn_chasey_at(x, y)
local c = { local c = chasey.new{
x = x, x = x,
y = y, y = y,
main_gun = new_gun_of(zap_gun_t, true) main_gun = new_gun_of(zap_gun_t, true)
} }
setmetatable(c, chasey_t)
eships:push_back(c) eships:push_back(c)
return c return c
end end
function spawn_xl_chasey_at(x, y) function spawn_xl_chasey_at(x, y)
local c = { local c = chasey.new{
x = x, x = x,
y = y, y = y,
size = 2, size = 2,
@ -688,150 +801,10 @@ function spawn_xl_chasey_at(x, y)
pal() pal()
end, end,
} }
setmetatable(c, chasey_t)
eships:push_back(c) eships:push_back(c)
return c return c
end end
-->8 -->8
--ship behavior
scrollrate = 0.25 --in px/frame
ship_m = {
-- ships have no shield by default
shield = 0,
maxshield = 0,
shieldcost = 32767.9,
shieldcooldown = 180,
-- default generator behavior:
-- 10 seconds for a full charge
max_power = 600,
power = 600,
generator = 1, -- power gen per frame
invincible_until = -32768,
slip = true, -- most enemies slide
xmomentum = 0,
ymomentum = 0,
}
ship_t = {
__index = ship_m,
}
function ship_m:die()
self.dead = true
if (self.hp <= 0) boom(self.x+self.size*4, self.y+self.size*4,12*self.size, self.boss)
end
function ship_m:move()
self:refresh_shield()
self.power = min(self.max_power, self.power + self.generator)
butt = self:grab_butts()
if (butt[5] > 0) self:maybe_shoot(self.main_gun)
if (butt[4] > 0) self:maybe_shoot(self.special_gun)
if (butt[0]-butt[1] ~= 0 or butt[2]-butt[3] ~= 0) spark(self.sparks, self.x + 4*self.size, self.y + 4*self.size, butt, self.thrust, self.sparkodds)
self.xmomentum += (self.thrust * butt[1]) - (self.thrust * butt[0])
self.ymomentum += (self.thrust * butt[3]) - (self.thrust * butt[2])
self.xmomentum = mid(-self.maxspd, self.maxspd, self.xmomentum)
self.ymomentum = mid(-self.maxspd, self.maxspd, self.ymomentum)
self.x += self.xmomentum
self.y += self.ymomentum
if self == primary_self then
self.x = mid(0, 112 - 8 * self.size, self.x)
self.y = mid(0, 128 - 8 * self.size, self.y)
end
--friction
local d = self.drag
self.xmomentum -= mid(d, -d, self.xmomentum)
self.ymomentum -= mid(d, -d, self.ymomentum)
-- "scrolling" behavior
if self.slip then
self.y += scrollrate
if self.y >= 128 then
self:die()
return true
end
end
return false
end
function ship_m:draw()
if(self.fx_pal) pal(self.fx_pal)
spr(self.sprite, self.x, self.y, self.size, self.size)
pal()
end
function hurtbox(ship)
local h = ship.hurt
return {
x=ship.x + h.x_off,
y=ship.y + h.y_off,
width=h.width,
height=h.height
}
end
function ship_m:maybe_shoot(gun)
if (not gun) return
if (self.power < gun.power) return
if (not gun:shoot(self.x + self.fire_off_x, self.y + self.fire_off_y)) return
self.power -= gun.power
end
function ship_m:hitship(other)
return self:hitsomething(1)
end
function ship_m:hitbullet(b)
return self:hitsomething(b.damage)
end
function ship_m:hitsomething(dmg)
if (dmg <= 0) return false
if (lframe < self.invincible_until) return false
self.shield_refresh_ready = lframe + self.shieldcooldown
if self.shield >= dmg then
self.shield -= dmg
self:ow(true)
return false
end
dmg -= self.shield
self.shield = 0
self.hp -= dmg
if self.hp <= 0 then
self:die()
return true
end
self:ow(false)
return false
end
function ship_m:ow(shielded)
if (shielded) then
blip(self,12,3)
return
end
blip(self, 7, 3)
end
function ship_m:refresh_shield()
if (self.shield >= self.maxshield) return
if (lframe < self.shield_refresh_ready) return
if (self.power < self.shieldcost) return
self.shield += 1
self.power -= self.shieldcost
self.shield_refresh_ready = lframe + self.shieldcooldown
end
-->8
-- collisions -- collisions
-- box: x, y, width, height -- box: x, y, width, height
@ -963,19 +936,18 @@ end
-->8 -->8
-- example level -- example level
function spawn_rnd_x(mt) function spawn_rnd_x(typ)
s = { s = typ.new{
x = rnd(104), x = rnd(104),
y = -(mt.__index.size * 8 - 1) y = -(mt.__index.size * 8 - 1)
} }
setmetatable(s, mt)
eships:push_back(s) eships:push_back(s)
return s return s
end end
function spawn_blocking_rnd_x(mt) function spawn_blocking_rnd_x(typ)
freeze += 1 freeze += 1
s = { s = typ.new{
x = rnd(104), x = rnd(104),
y = -7, y = -7,
ice = 1, ice = 1,
@ -985,25 +957,24 @@ function spawn_blocking_rnd_x(mt)
mt.__index.die(self) mt.__index.die(self)
end end
} }
setmetatable(s, mt)
eships:push_back(s) eships:push_back(s)
return s return s
end end
function spawn_frownie() function spawn_frownie()
return spawn_rnd_x(frownie_t) return spawn_rnd_x(frownie)
end end
function spawn_blocking_frownie() function spawn_blocking_frownie()
spawn_blocking_rnd_x(frownie_t) spawn_blocking_rnd_x(frownie)
end end
function spawn_blocky() function spawn_blocky()
spawn_rnd_x(blocky_t) spawn_rnd_x(blocky)
end end
function spawn_blocking_blocky() function spawn_blocking_blocky()
spawn_blocking_rnd_x(blocky_t) spawn_blocking_rnd_x(blocky)
end end
function spawn_spewy() function spawn_spewy()
@ -1021,7 +992,7 @@ function spawn_blocking_spewy()
s.die = function(self) s.die = function(self)
freeze -= self.ice freeze -= self.ice
self.ice = 0 self.ice = 0
frownie_t.__index.die(self) frownie.die(self)
end end
end end
@ -1030,7 +1001,7 @@ function spawn_bonus_frownie()
f.sprite = 7 f.sprite = 7
f.die = function(self) f.die = function(self)
spawn_repair_at(self.x+4, self.y+4) spawn_repair_at(self.x+4, self.y+4)
frownie_t.__index.die(self) frownie.die(self)
end end
end end
@ -1062,7 +1033,7 @@ function spawn_blocking_boss_chasey()
c.die = function(self) c.die = function(self)
freeze -= self.ice freeze -= self.ice
self.ice = 0 self.ice = 0
chasey_t.__index.die(self) chasey.die(self)
end end
local nextspawn = lframe + 120 local nextspawn = lframe + 120