8 Commits

Author SHA1 Message Date
c514c61b3a look at me. *look at me.* I'm the gun_base now 2025-06-01 17:41:07 -07:00
9be828dd5c blast gun is a trig gun
now there are no more base guns
2025-06-01 17:38:45 -07:00
2b51a3472b protron trig gun 2025-06-01 17:36:15 -07:00
95ea70baae vulcan_gun as trig gun
causes x offset to reverse for negative aim; may need to be careful
with how I make aiming guns actually work, but this should work for
deriving player guns from enemy guns (by using negative aim)!
2025-06-01 17:26:29 -07:00
b18b4f885d trig zap gun; fixes
use the trig gun for the zap gun
2025-06-01 17:00:28 -07:00
2fdb8d1a05 trigenometry gun prototype 2025-06-01 16:48:39 -07:00
fc1f84fa28 Delete slip behavior 2025-06-01 16:15:46 -07:00
93b63a5831 Prevent new calls that won't work as expected 2025-06-01 16:11:35 -07:00

View File

@ -41,12 +41,13 @@ function mknew(tt)
local mt,oldinit,more = {__index=tt},tt.superinit,rawget(tt, "init") local mt,oldinit,more = {__index=tt},tt.superinit,rawget(tt, "init")
tt.new=function(ret) tt.new=function(ret)
if(not ret) ret = {} if(not ret) ret = {}
ret.new = false
setmetatable(ret, mt) setmetatable(ret, mt)
if(oldinit) oldinit(ret) if(oldinit) oldinit(ret)
if (more) more(ret) if (more) more(ret)
return ret return ret
end end
if oldinit and more then if oldinit and more then
tt.superinit = function(ret) tt.superinit = function(ret)
oldinit(ret) oldinit(ret)
@ -529,8 +530,6 @@ ship_m = mknew{
shieldpenalty = 0x0.012c, --5s shieldpenalty = 0x0.012c, --5s
shield_refresh_ready = 0, shield_refresh_ready = 0,
slip = true, -- most enemies slide
xmomentum = 0, xmomentum = 0,
ymomentum = 0, ymomentum = 0,
@ -620,15 +619,7 @@ function ship_m:move()
self.x += self.xmomentum self.x += self.xmomentum
self.y += self.ymomentum self.y += self.ymomentum
-- "scrolling" behavior
if self.slip then
self.y += scrollrate
if self.y >= 128 then
self:die()
return true
end
end
return false return false
end end
@ -739,6 +730,27 @@ gun_base = mknew{
-- cooldown reduction from -- cooldown reduction from
-- upgrades, not yet applied -- upgrades, not yet applied
cd_remainder = 0, cd_remainder = 0,
veloc = 1,
aim = 0.75, -- down; 0.25, or -0.75, is up
shot_idx = 0,
-- shots: list<list<[3]num>>
-- describing a cycling
-- firing pattern. shot_idx
-- tracks offset into pattern.
-- each nested list: a burst
-- of shots to fire; takes
-- 1 ammo; sequential
-- each shot: angle (turns,
-- relative to `aim`),
-- firing x-offset, velocity;
-- if x-offset is nil, use 0;
-- if velocity is nil, use
-- self.veloc instead
init = function(self)
if (not self.shots) self.shots = {{{0}}}
end
} }
-- gun_base subtypes are -- gun_base subtypes are
@ -763,12 +775,6 @@ function gun_base:peel()
self.munition = mknew(self.munition.new()) self.munition = mknew(self.munition.new())
end end
-- default firing behavior:
-- single shot
function gun_base:actually_shoot(x, y)
self.munition.new{}:spawn_at(x, y)
end
-- upgrade -- upgrade
function gun_base:small_upgrade_opts() function gun_base:small_upgrade_opts()
local ret = { local ret = {
@ -883,6 +889,35 @@ function gun_base:shoot(x, y)
return true return true
end end
function gun_base:actually_shoot(x, y)
local shots,veloc,aim,munition = self.shots,self.veloc,self.aim,self.munition
local idx = self.shot_idx % #shots + 1
self.shot_idx = idx
shots = shots[idx]
for s in all(shots) do
local a,xo,v = unpack(s)
v = v or veloc
xo = xo or 0
-- reverse x-offset for negative base angle
if (aim < 0) xo = -xo
a += aim
-- todo: switch munition
-- depending on angle
-- (allows for non-round
-- sprites and hitboxes on
-- shots from guns with
-- widely varying angles)
local m = munition.new{}
-- todo: automatically make
-- high velocity shots do
-- multiple collision checks
m.dy = sin(a) * veloc
m.dx = cos(a) * veloc
m:spawn_at(x+(xo or 0), y)
end
end
-->8 -->8
-- bullets and guns -- bullets and guns
@ -901,8 +936,6 @@ zap_e = mknew(bullet_base.new{
y_off = 8, y_off = 8,
damage = 1, damage = 1,
dx = 0, -- px/frame
dy = 4,
hitship = const_fxn(true), hitship = const_fxn(true),
@ -911,19 +944,21 @@ zap_e = mknew(bullet_base.new{
zap_p = mknew(zap_e.new{ zap_p = mknew(zap_e.new{
sprite = 8, sprite = 8,
dy = -8,
y_off = 0, y_off = 0,
category = player_blt_cat, category = player_blt_cat,
}) })
zap_gun_e = mknew(gun_base.new{ zap_gun_e = mknew(gun_base.new{
cooldown = 0x0.0020, -- frames between shots cooldown = 0x0.0020, -- frames between shots
veloc = 4,
munition = zap_e, munition = zap_e,
}) })
zap_gun_p = mknew(zap_gun_e.new{ zap_gun_p = mknew(zap_gun_e.new{
icon = 19, icon = 19,
munition = zap_p, munition = zap_p,
veloc = 8,
aim = 0.25,
hdr = "mAIN gUN", hdr = "mAIN gUN",
}) })
@ -980,6 +1015,7 @@ blast = mknew(bullet_base.new{
blast_gun = mknew(gun_base.new{ blast_gun = mknew(gun_base.new{
icon = 13, icon = 13,
cooldown = 0x0.0078, -- 120 frames between shots cooldown = 0x0.0078, -- 120 frames between shots
aim = -0.75,
ammo = 5, ammo = 5,
maxammo = 5, maxammo = 5,
munition = blast, munition = blast,
@ -1012,8 +1048,6 @@ protron_e = mknew(bullet_base.new{
y_off = 4, y_off = 4,
damage = 1, damage = 1,
dym = 0.5, -- gun sets dy;
-- this is mult
category = enemy_blt_cat, category = enemy_blt_cat,
}) })
@ -1029,34 +1063,17 @@ protron_gun_e = mknew(gun_base.new{
cooldown = 0x0.0040, -- frames between shots cooldown = 0x0.0040, -- frames between shots
ammo = nil, ammo = nil,
maxammo = nil, maxammo = nil,
munition = protron_e munition = protron_e,
veloc = 2,
shots = {{{-0.25}, {-0.165}, {-0.0825}, {0}, {0.0825}, {0.165}, {0.25}}}
}) })
function protron_gun_e:actually_shoot(x, y)
local m = self.munition.dym
for i=1,3 do
local b = self.munition.new{
dx = i*m,
dy = (4-i)*m,
}
b:spawn_at(x,y)
local b2 = self.munition.new{
dx = -i*m,
dy = (4-i)*m,
}
b2:spawn_at(x,y)
end
local bup = self.munition.new{
dx=0,
dy=4*m,
}
bup:spawn_at(x,y)
end
protron_gun_p = mknew(protron_gun_e.new{ protron_gun_p = mknew(protron_gun_e.new{
munition = protron_p, munition = protron_p,
maxammo = 20, maxammo = 20,
cooldown = 0x0.0018, cooldown = 0x0.0018,
veloc = 4,
aim = -0.75,
hdr = "pROTRON", hdr = "pROTRON",
body = [[---------GUN body = [[---------GUN
@ -1085,15 +1102,12 @@ vulcan_e = mknew(bullet_base.new{
y_off = 0, y_off = 0,
damage = 0.5, damage = 0.5,
-- dx from gun
dy = 2,
category=enemy_blt_cat category=enemy_blt_cat
}) })
vulcan_p = mknew(vulcan_e.new{ vulcan_p = mknew(vulcan_e.new{
sprite=22, sprite=22,
y_off = 4, y_off = 4,
dy = -4,
category=player_blt_cat category=player_blt_cat
}) })
@ -1103,30 +1117,22 @@ vulcan_gun_e = mknew(gun_base.new{
ammo = nil, ammo = nil,
maxammo = nil, maxammo = nil,
munition=vulcan_e, munition=vulcan_e,
dxs = {0.35, -0.35, -0.7, 0.7, 0.35, -0.35}, veloc = 2,
xoffs = {1, 0, -1, 1, 0, -1}, shots = {{{0.02, 2}}, {{-0.02,0}}, {{-0.03, -2}}, {{0.03, 2}}, {{0.02, 0}}, {{-0.02, -2}}}
dxidx = 1,
actually_shoot = function(self, x, y)
local b = self.munition.new{
dx = self.dxs[self.dxidx],
}
b:spawn_at(self.xoffs[self.dxidx]+x,y)
self.dxidx += 1
if (self.dxidx > #self.dxs) self.dxidx = 1
end
}) })
machine_gun_e = mknew(vulcan_gun_e.new{ machine_gun_e = mknew(vulcan_gun_e.new{
icon = 38, icon = 38,
clip_size = 12, clip_size = 12,
clip_interval = 0x0.005a, clip_interval = 0x0.005a,
dxs = {0, 0}, shots = {{{0, 2}}, {{0, -2}}}
xoffs = {1, -1},
}) })
vulcan_gun_p = mknew(vulcan_gun_e.new{ vulcan_gun_p = mknew(vulcan_gun_e.new{
munition=vulcan_p, munition=vulcan_p,
maxammo = 100, maxammo = 100,
aim=-0.75,
veloc=4,
hdr = "vULCAN", hdr = "vULCAN",
body = [[---------GUN body = [[---------GUN
@ -1188,7 +1194,6 @@ player = mknew(ship_m.new{
thrust = 0.1875, -- momentum added from button thrust = 0.1875, -- momentum added from button
ymin = 0, ymax = 120, -- stay on screen ymin = 0, ymax = 120, -- stay on screen
drag = 0.0625, -- momentum lost per frame drag = 0.0625, -- momentum lost per frame
slip = false, -- does not slide down screen
act = function(self) -- fetch buttons act = function(self) -- fetch buttons
local b,th = btn(),self.thrust local b,th = btn(),self.thrust
local blr = b&0x3 local blr = b&0x3
@ -1344,7 +1349,6 @@ chasey = mknew(ship_m.new{
maxspd = 2, maxspd = 2,
thrust = 0.2, thrust = 0.2,
drag = 0.075, drag = 0.075,
slip = true,
init = function(ship) init = function(ship)
ship.main_gun=ship.main_gun or zap_gun_e.new{} ship.main_gun=ship.main_gun or zap_gun_e.new{}
@ -1372,7 +1376,6 @@ xl_chasey=mknew(chasey.new{
hp = 19.5, hp = 19.5,
shield = 5, shield = 5,
boss = true, boss = true,
slip = false,
act = function(self) act = function(self)
local dx,dy,shoot_spec,shoot_main = chasey.act(self) local dx,dy,shoot_spec,shoot_main = chasey.act(self)
if (self.y < 4) dy=self.thrust if (self.y < 4) dy=self.thrust
@ -1400,7 +1403,6 @@ ship_f = mknew(ship_m.new{
maxspd = 3, maxspd = 3,
thrust = 0.1, thrust = 0.1,
drag = 0.05, drag = 0.05,
slip = false,
act = function(self) act = function(self)
local wx,wy=self.want_x,self.want_y local wx,wy=self.want_x,self.want_y
self.xmin,self.xmax,self.ymin,self.ymax = wx,wx,wy,wy self.xmin,self.xmax,self.ymin,self.ymax = wx,wx,wy,wy
@ -1845,6 +1847,7 @@ end
-- add a new gun -- add a new gun
function spec_gun_opts() function spec_gun_opts()
-- todo: avoid duplicates
return pick(spec_gunt, 2) return pick(spec_gunt, 2)
end end
@ -1866,7 +1869,6 @@ end
-- ordinary upgrades -- ordinary upgrades
function small_opts() function small_opts()
-- todo: include gun opts
if(not primary_ship.special_guns) return pick(primary_ship:small_upgrade_opts(), 2) if(not primary_ship.special_guns) return pick(primary_ship:small_upgrade_opts(), 2)
local opts = {rnd(primary_ship:small_upgrade_opts())} local opts = {rnd(primary_ship:small_upgrade_opts())}
for g in all(primary_ship.special_guns) do for g in all(primary_ship.special_guns) do
@ -1947,7 +1949,10 @@ function rearm_mode:shuffle()
-- until the upgrade deck -- until the upgrade deck
-- is a thing that exists -- is a thing that exists
local lev = primary_ship.level + 1 local lev = primary_ship.level + 1
if lev == 4 or lev == 12 then
-- for testing: more guns really early
-- if lev == 4 or lev == 12 then
if lev == 2 or lev == 3 then
self.options = spec_gun_opts() self.options = spec_gun_opts()
elseif lev % 4 == 0 then elseif lev % 4 == 0 then
self.options = big_opts() self.options = big_opts()