32 Commits

Author SHA1 Message Date
3151db5430 fix precedence error 2025-05-31 22:27:03 -07:00
2964159858 fix offset, try but fail to fix variants 2025-05-31 22:19:35 -07:00
95d4b6eb37 what the hell was I thinking when I wrote this 2025-05-31 22:06:48 -07:00
96312e3adf fix offset bugs 2025-05-31 22:05:47 -07:00
bf9a45d87e fix gframe unit 2025-05-31 21:55:21 -07:00
36f7c6572f fix ship spawning 2025-05-31 21:54:02 -07:00
45b70d3aca did you know that 4 is not 1? mindboggling! 2025-05-31 21:43:51 -07:00
35980d801a forgot my increments! 2025-05-31 21:40:17 -07:00
734811bd62 math works better when you return your values 2025-05-31 21:33:06 -07:00
4fddbea82c use the right loader 2025-05-31 21:31:20 -07:00
f675e31967 oops, I accidentally 2025-05-31 21:30:30 -07:00
0bd1463416 replace demo level with infinite copies of flotilla 0 2025-05-31 21:29:54 -07:00
267f8a3667 actually add ships we keep 2025-05-31 21:02:26 -07:00
fa206c37c5 "redistribute"-type flotilla: update 2025-05-31 21:00:27 -07:00
928e7f7418 prototype flotilla loader 2025-05-31 20:39:07 -07:00
2439fda068 ship prototype tweaks 2025-05-31 20:38:59 -07:00
d13290f438 placeholder flotilla ships 2025-05-31 19:03:38 -07:00
e3a2810f0a Prototype a flotilla template. 2025-05-25 21:03:51 -07:00
3764063b20 abandon "offset" sprites, use "row tier" sprites 2025-05-25 20:49:27 -07:00
90f6df2922 flotilla notes and sprites 2025-05-25 19:11:44 -07:00
b7c3e6ee92 adjust menu renderer 2025-05-03 17:26:48 -07:00
c91e5f4bd1 shorten RATE message
not enough room to describe "fractions add up" -- maybe I can just fit
in the "remainder" to hint that it will be considered in future
upgrades?
2025-05-03 17:19:33 -07:00
ea2ddadb15 oops, method call syntax is special 2025-05-03 17:12:20 -07:00
9333c03bf3 add main gun rate upgrade to ship pool 2025-05-03 17:11:47 -07:00
1b45bd3dc3 fix rate formatting 2025-05-03 17:11:35 -07:00
71a7351d77 oops, miscalculated box width 2025-05-03 17:04:29 -07:00
80bb848468 options work better when I return them 2025-05-03 16:51:59 -07:00
b227844d12 Restyle ship stat upgrades. 2025-05-03 16:48:18 -07:00
ce14d03669 offer gun upgrades 2025-05-03 16:38:39 -07:00
ccd2c64103 update gun pick description style 2025-05-03 16:38:26 -07:00
e5b8a30cb6 cooldown reduction prototype
I decided to keep cooldown in the same unit as the frame counter,
because the extra math when calculating an upgrade is going to happen
much less frequently than actual cooldown checks and calculations, so
leaving the upgrade logic as the less efficient path seems like the
more appropriate choice.
2025-05-03 16:28:54 -07:00
7ed305d2d9 Ammo quantity upgrade prototype
Not yet tested. Will crash until I also get rate_upgrade_opt up.
2025-05-03 16:06:16 -07:00

View File

@ -127,7 +127,6 @@ function _init()
mode = game_mode
init_blip_pals()
wipe_game() -- redundant?
load_level(example_level_csv)
game_state = game
pal(2,129)
pal()
@ -171,6 +170,10 @@ function wipe_game()
new_events = linked_list.new()
primary_ship.main_gun = zap_gun_p.new()
primary_ship.main_gun:peel()
gframe = 0
interlude = 0
waves_complete = 0
current_wave = nil
end
function _update60()
@ -185,12 +188,44 @@ function call_move(x)
return x:move()
end
function ones(n)
local ret = 0
while n != 0 do
if (n&0x0.0001) ret += 1
n >>= 1
end
return ret
end
function updategame()
if (primary_ship.xp >= primary_ship.xptarget) and (lframe - primary_ship.last_xp_frame > 0x0.000f) and (not primary_ship.dead) then
if (primary_ship.xp >= primary_ship.xptarget) and (gframe - primary_ship.last_xp_frame > 0x0.000f) and (not primary_ship.dead) then
mode = rearm_mode.new()
return _update60()
end
leveldone = level_frame()
gframe += 0x0.0001
if current_wave then
if current_wave:update() then
-- end of stage
waves_complete += 1
current_wave = nil
if waves_complete < 32767 then
interlude = 59 -- plus one dead frame with load_level but no update
else
-- you maxed out the level
-- counter. what the fuck
-- is wrong with you?
-- go outside.
--
-- do not spawn more levels.
interlude = 32767
end
end
elseif interlude > 0 then
interlude -= 1
else
current_wave = flotilla.new()
current_wave:load(0, 0, min(ones(waves_complete)\2, 4))
end
events:vore(new_events)
events:strip(call_move)
for _, lst in ipairs{intangibles_bg, pships, eships, pbullets, ebullets} do
@ -254,7 +289,7 @@ function updategame()
intangibles_fg:strip(call_move)
if leveldone and not eships.next and not ebullets.next and not events.next then
if waves_complete == 32767 and not eships.next and not ebullets.next and not events.next then
game_state = win
end
if (not pships.next) game_state = lose
@ -466,6 +501,14 @@ end
-->8
--ship behavior
-- generic full sprite hurtbox
box8 = {
x_off = 0,
y_off = 1,
width = 8,
height = 8
}
scrollrate = 0.25 --in px/frame
ship_m = mknew{
@ -611,7 +654,7 @@ end
function ship_m:hitsomething(dmg)
if (dmg <= 0) return false
self.shield_refresh_ready = lframe + self.shieldpenalty
self.shield_refresh_ready = gframe + self.shieldpenalty
if self.shield > 0 then
self.shield -= dmg
if self.shield > 0 then
@ -633,10 +676,10 @@ end
function ship_m:refresh_shield()
if (self.shield >= self.maxshield) return
if (lframe < self.shield_refresh_ready) return
if (gframe < self.shield_refresh_ready) return
self.shield += 1
self.shield = min(self.shield, self.maxshield)
self.shield_refresh_ready = lframe + self.shieldcooldown
self.shield_refresh_ready = gframe + self.shieldcooldown
end
-->8
@ -676,7 +719,13 @@ bullet_base = mknew{ }
gun_base = mknew{
shoot_ready = -32768,
icon = 20
icon = 20,
ammobonus = 1,
-- fractional frames of
-- cooldown reduction from
-- upgrades, not yet applied
cd_remainder = 0,
}
-- gun_base subtypes are
@ -707,6 +756,68 @@ function gun_base:actually_shoot(x, y)
self.munition.new{}:spawn_at(x, y)
end
-- upgrade
function gun_base:small_upgrade_opts()
local ret = {
self:ammo_upgrade_opt(),
self:rate_upgrade_opt(),
}
local s = self.special_upgrade_opt
if (s) add(ret, s(self))
return ret
end
function gun_base:ammo_upgrade_opt()
local a=self.maxammo
local x=a\10+self.ammobonus
return {
icon=self.icon,
hdr=self.hdr,
body=[[--------AMMO
more shots
before you
run out.
is: ]]..tostr(a)..[[
add: ]]..tostr(x)..[[
----------
total: ]]..tostr(a+x),
action=function()
self.maxammo+=x
self.ammo+=x
end,
}
end
function gun_base:rate_upgrade_opt()
local c=self.cooldown<<16
local rawnewc=0.85*(c-self.cd_remainder)
local newc=ceil(rawnewc)
return {
icon=self.icon,
hdr=self.hdr,
body=[[--------RATE
reduce delay
between each
shot when
firing.
is: ]]..tostr(c)..[[f
minus: ]]..tostr(c-newc)..[[f
----------
total: ]]..tostr(newc)..[[f
remainder:
]]..sub(tostr(newc-rawnewc),0,5),
action=function()
self.cooldown=newc>>16
self.cd_remainder=newc-rawnewc
end,
}
end
function bullet_base:hitship(_)
self:die()
return true
@ -737,12 +848,12 @@ function bullet_base:spawn_at(x, y)
end
function gun_base:shoot(x, y)
if (lframe < self.shoot_ready) return false
if (gframe < self.shoot_ready) return false
if self.ammo then
if (self.ammo <= 0) return false
self.ammo -= 1
end
self.shoot_ready = lframe + self.cooldown
self.shoot_ready = gframe + self.cooldown
self:actually_shoot(x, y)
return true
end
@ -848,10 +959,12 @@ blast_gun = mknew(gun_base.new{
maxammo = 5,
munition = blast,
hdr = "bLASTER",
body= [[plasma orb
body= [[---------GUN
plasma orb
cuts through
enemies.
slow.
enemies.
slow.
ammo: 5
rate: 1/2sec
@ -920,9 +1033,11 @@ protron_gun_p = mknew(protron_gun_e.new{
maxammo = 20,
cooldown = 0x0.0018,
hdr = "pROTRON",
body = [[spray shots
in a dense
arc.
body = [[---------GUN
spray shots
in a dense
arc.
ammo: 20
rate: 2/sec
@ -981,9 +1096,10 @@ vulcan_gun_p = mknew(vulcan_gun_e.new{
munition=vulcan_p,
maxammo = 100,
hdr = "vULCAN",
body = [[rapid fire
in a v
shape.
body = [[---------GUN
rapidly fire
in a v.
ammo: 100
rate: 20/sec
@ -1074,7 +1190,11 @@ function player:small_upgrade_opts()
local ret = {{
icon=53,
hdr="hull",
body=[[ armor
body=[[--------SHIP
survive more
unshielded
hits.
+2 hp]],
action=function()
@ -1083,8 +1203,13 @@ function player:small_upgrade_opts()
end,
},{
icon=52,
hdr="shield",
body=[[ capacity
hdr="capacity",
body=[[------SHIELD
shield can
absorb more
hits before
recharging.
+1 hp]],
action=function()
@ -1094,10 +1219,11 @@ function player:small_upgrade_opts()
},{
icon=1,
hdr="thrusters",
body=[[performance
body=[[--------SHIP
move faster,
steer faster]],
steer more
sharply.]],
action=function()
--maxspd thrust drag
self.maxspd += 0.5
@ -1106,22 +1232,29 @@ steer faster]],
end,
},{
icon=20,
hdr="hull",
body=[[ magnet
hdr="magnet",
body=[[--------SHIP
pick up xp
from further
away]],
away.]],
action=function ()
self.magnet += 2
end,
}}
},
self.main_gun:rate_upgrade_opt(),
}
if cdr > 0 then
add(ret, {
icon = 6,
hdr = "shield",
body=[[charge rate
hdr = "recharge",
body=[[------SHIELD
shield will
recharge at
a faster
pace.
]] .. tostr(ceil(100 * cdr / self.shieldcooldown)) .. "% faster",
action = function()
@ -1133,8 +1266,15 @@ from further
if pr > 0 then
add(ret, {
icon = 6,
hdr = "shield",
body=[[disruption
hdr = "recovery",
body=[[------SHIELD
reduce the
delay after
a hit before
shield will
start to
recharge.
]] .. tostr(ceil(100 * pr / self.shieldpenalty)) .. "% shorter",
action = function()
@ -1146,81 +1286,10 @@ from further
return ret
end
frownie = mknew(ship_m.new{
--shape
sprite = 3, --index of ship sprite
size = 1, --all ships are square; how many 8x8 sprites?
hurt = { -- hurtbox - where this ship can be hit
x_off = 0, -- upper left corner
y_off = 1, -- relative to ship ulc
width = 8,
height = 6
},
sparks = smokespark,
sparkodds = 8,
hp = 0.5, -- enemy ships need no max hp
xp = 0x0.0001,
-- position
x=60, -- x and y are for upper left corner
y=8,
xmomentum = 0,
ymomentum = 0,
maxspd = 2, -- momentum cap
thrust = 0.12, -- momentum added from button
drag = 0.07, -- momentum lost per frame
slip = true,
act = function(self)
local tstate,dx = (1 + flr(4*t() + 0.5)) % 6,0
if (tstate==1 or tstate==2) dx=-self.thrust
if (tstate>=4) dx=self.thrust
return dx,0,false,false
end,
})
blocky = mknew(frownie.new{
sprite = 10,
hp = 1.5,
xp = 0x0.0002,
hurt = {
x_off = 0,
y_off = 0,
width = 8,
height = 7
},
ow = function(self)
if self.hp < 1 then
self.sprite = 11
else
self.sprite = 10
end
ship_m.ow(self)
end
})
spewy = mknew(frownie.new{
sprite=26,
xp = 0x0.0003,
hurt = {
x_off=0,
y_off=1,
width=8,
height=5
},
hp=0.5,
fire_off_x=4,
fire_off_y=7,
act=function(self)
local dx,dy,shoot_spec=frownie.act(self)
return dx, dy, shoot_spec, self.y > 10
end,
init = function(ship)
ship.main_gun=ship.main_gun or protron_gun_e.new{}
end
})
-- original prototype leftover;
-- likely to be the basis of a
-- standard raider type, so
-- i am keeping it around
chasey = mknew(ship_m.new{
sprite = 5,
xp = 0x0.0004,
@ -1250,7 +1319,6 @@ chasey = mknew(ship_m.new{
end
})
-- todo: use constraints
function chasey:act()
self.xmin = max(primary_ship.x-8, 0)
self.xmax = min(primary_ship.x + 8, 112 - 8*self.size)
@ -1288,6 +1356,53 @@ xl_chasey=mknew(chasey.new{
end,
})
-- flotilla ships
ship_f = mknew(ship_m.new{
-- sprite required
size = 1,
hurt = box8,
-- no sparks
hp = 0.5,
xp = 0x0.0001,
maxspd = 3,
thrust = 0.1,
drag = 0.05,
slip = false,
act = function(self)
local wx,wy=self.want_x,self.want_y
self.xmin,self.xmax,self.ymin,self.ymax = wx,wx,wy,wy
return 0,0,false,false
end,
})
ship_mook = mknew(ship_f.new{
sprite=103
})
ship_defender = mknew(ship_f.new{
sprite=105,
hp = 2.5,
xp = 0x0.0003,
})
ship_turret = mknew(ship_f.new{
sprite=106,
xp = 0x0.0002,
})
ship_skirmisher = mknew(ship_f.new{
sprite=107,
xp = 0x0.0004,
spark = smokespark,
sparkodds = 4,
})
function rnd_spawn_loc()
local x,y = flr(rnd(304)), flr(rnd(32))
if (x<184) return x-40,-y-8
if (x<244) return -y-8,x-184
return 112+y, x-244
end
-->8
-- collisions
@ -1352,242 +1467,163 @@ function collider:get_collisions(item)
end
return found
end
-->8
-- level and event system
-- flotillas
-- a level is a map from
-- effective frame number to
-- a list of actions for that
-- frame. an action is a
-- method name and its args.
-- a template for a wave, read
-- from the map. each ship can
-- alternate between "attack"
-- and "formation" modes, like
-- galaxian or galaga. ships
-- with different roles have
-- different rules for becoming
-- aggressive, but aggression
-- ramps up during the wave.
-- effective frame number stops
-- when freeze count is nonzero
-- flotilla placeholders are
-- defined by sprite flags.
-- see obsidian vault for
-- full docs.
-- a level is won when it hits
-- the end-of-level sentinel
-- and there are no more
-- tracked enemies.
-- lost when there are no
-- player ships left.
-- effective frame
distance = 0
-- actual frame count since
-- start of level times 0x0.0001
lframe = 0
-- do not advance distance when
-- nonzero
freeze = 0
eol = {}
function load_level(levelfile)
distance = 0
lframe = 0
freeze = 0
leveldone = false
current_level = {}
local found_eol = false
if (type(levelfile)=="string") levelfile = csv(levelfile)
for row in all(levelfile) do
local x = current_level[row[1]]
if row[2] == "eol" then
found_eol = true
assert(x==nil, "events on eol frame")
current_level[row[1]] = eol
else
row.next = x
current_level[row[1]]=row
end
end
assert(found_eol)
end
function level_frame()
lframe += 0x0.0001
if (current_level == nil) return true
if freeze == 0 then
distance += 1
local cbs = current_level[distance]
if cbs ~= nil then
if cbs == eol then
current_level = nil
return true
else
while cbs do
assert(cbs[1] == distance)
local f = _ENV[cbs[2]]
assert(type(f) == "function", cbs[2].." at "..distance.." is not a function")
f(unpack(cbs, 3))
cbs=cbs.next
end
end
end
end
return false
end
-->8
-- example level
function spawn_blocking_rnd_x(typ)
freeze += 1
s = typ.new{
x = rnd(104),
y = -7,
ice = 1,
orig_die = typ.die,
die = function(self)
freeze -= self.ice
self.ice = 0
self:orig_die()
end,
}
eships:push_back(s)
return s
end
function spawn_frownie()
return spawn_rnd(frownie)
end
function spawn_blocking_frownie()
spawn_blocking_rnd_x(frownie)
end
function spawn_blocky()
spawn_rnd(blocky)
end
function spawn_blocking_blocky()
spawn_rnd(blocky, 1)
end
function spawn_spewy()
return spawn_rnd(spewy)
end
function spawn_chasey()
return spawn_rnd(chasey)
end
function spawn_blocking_spewy()
freeze += 1
local s = spawn_spewy()
s.ice = 1
s.die = function(self)
freeze -= self.ice
self.ice = 0
frownie.die(self)
end
end
function spawn_vulcan_chasey()
local c = spawn_chasey()
c.main_gun=vulcan_gun_e.new{enemy=true}
c.sprite=4
return c
end
helpers = {
spawn_frownie,
spawn_frownie,
spawn_frownie,
spawn_blocky,
spawn_blocky,
spawn_chasey,
spawn_spewy,
flotilla = mknew{
use_var = 0x1111,
opt_odds = split"0.5,0.5,0.5,0.5",
init=function(this)
this.ship_bases={
[0]=mknew(ship_mook.new{ship_t=0}),
[1]=mknew(ship_mook.new{ship_t=1, sprite=104}),
[4]=mknew(ship_defender.new{ship_t=4}),
[5]=mknew(ship_defender.new{ship_t=5, sprite=10}),
[8]=mknew(ship_turret.new{ship_t=8}),
[9]=mknew(ship_turret.new{ship_t=9, sprite=4}),
[12]=mknew(ship_skirmisher.new{ship_t=12}),
[13]=mknew(ship_skirmisher.new{ship_t=13, sprite=26}),
}
end,
}
function spawn_blocking_boss_chasey()
local c = spawn_rnd(xl_chasey, 1)
local nextspawn = lframe + 0x0.0080
events:push_back{move=function()
if lframe >= nextspawn then
helpers[flr(rnd(#helpers))+1]()
nextspawn += 0x0.0040
end
return c.dead
end}
return c
end
function std_spawn(tnm, n, blocking, goodie,altspr)
local typ = _ENV[tnm]
assert(typ and typ.new, tostr(tnm).." not a class")
for i=1,(n or 1) do
spawn_rnd(typ, blocking, goodie,altspr)
end
end
-- blocking: 1 or 0
function spawn_rnd(typ, blocking, goodie,altspr)
blocking = blocking or 0
freeze += blocking
s = typ.new{
x = rnd(104),
y = -(typ.size * 8 - 1),
ice=blocking,
die=function(self)
freeze -= self.ice
self.ice=0
typ.die(self)
end,
function flotilla:load(ulc_cx, ulc_cy, lvl)
local rows,cy,uv,counts={},ulc_cy,self.use_var,{
[0]=0,
[1]=0,
[4]=0,
[5]=0,
[8]=0,
[9]=0,
[12]=0,
[13]=0,
}
if (altspr) s.spr = altspr
eships:push_back(s)
return s
end
function multi(times, interval, fnm, ...)
local f,irm,vargs = _ENV[fnm],interval,pack(...)
assert(type(f) == "function", fnm.." not a function")
f(...)
events:push_back{move=function()
irm-=1
if irm <= 0 then
irm=interval
times-=1
f(unpack(vargs))
return times <= 1
repeat
local row,cx,opt,f,mode= {},ulc_cx,{},0,0
for i,v in ipairs(self.opt_odds) do
opt[i*4-4]=rnd()<v
end
end}
repeat
f=fget(mget(cx, cy))
-- bits 0x03: control mark or ship?
mode = f&0x03
if mode==2 then
-- bits 0x0c: ship class
local ship_t = f&0x0c
-- bit 0x20: optional?
if f&0x20 == 0 or opt[ship_t] then
-- bit 0x10: alternate ship?
-- increment ship id if
-- alternate is requested
-- and we allow alternates
-- for this type of ship
ship_t+=(uv>>ship_t&0x1)&((f&0x10)>>4)
add(row, self.ship_bases[ship_t].new{col=cx-ulc_cx})
end
end
cx += 1
until mode==1
-- mode 1: end of line control mark
-- bits 0x18: what size flotilla is this row used for?
if (f&0x18)>>3 <= lvl then
-- keep the row; count it
for s in all(row) do
counts[s.ship_t] += 1
s.x,s.y=rnd_spawn_loc()
eships:push_back(s)
end
add(rows, row)
end
cy += 1
-- control mark bit 0x04: end of flotilla
until f&0x04 > 0
self.rows=rows
self:statisfy(counts)
end
-- then convert sample_level to csv.
-- spawn_spec_gun_at and spawn_main_gun_at will need parsed forms.
-- the boss also needs to be reachable, but one-off is fine.
-- each row of level csv is offset,event,event-args...
-- where offset,eol is a special case.
function flotilla:statisfy(counts)
-- TODO: now that we know how
-- many ships of each kind
-- exist, build ships to match
-- difficulty target
--
-- no difficulty model is yet
-- implemented, though, so
-- just use base ships only
-- for this prototype
end
example_level_csv=[[1,spawn_frownie
60,spawn_vulcan_chasey
61,spawn_blocky
85,spawn_spewy
115,spawn_spewy
130,spawn_frownie
145,spawn_frownie
180,spawn_spewy
230,spawn_chasey
250,spawn_blocking_blocky
310,spawn_blocking_blocky
310,spawn_blocking_blocky
310,spawn_blocking_blocky
311,spawn_frownie
401,spawn_frownie
420,spawn_blocking_frownie
430,spawn_vulcan_chasey
450,spawn_frownie
465,spawn_frownie
480,spawn_chasey
500,multi,20,12,spawn_blocking_blocky
501,spawn_frownie
620,spawn_blocking_blocky
630,spawn_vulcan_chasey
720,spawn_blocking_boss_chasey
721,eol]]
function flotilla:update()
-- algorithm: redistribute
-- TODO: alternate flotilla movement algorithms
-- find effective width and height
local min_col,max_col,live_rows=999,0,0
for row in all(self.rows) do
local row_alive=false
for ship in all(row) do
if not ship.dead then
row_alive=true
local col=ship.col
if (col < min_col) min_col = col
if (col > max_col) max_col = col
end
end -- scanned row
if (row_alive) live_rows += 1
end -- extent search
if (live_rows == 0) return true -- done
-- distribute across box:
-- x = [4, 100)
-- y = [4, 60)
local x_interval,x_offset = 0,52
if min_col < max_col then
x_interval=96/(max_col-min_col)
x_offset = 4-min_col*x_interval
end
local y_interval,y_offset=0,40
if live_rows > 1 then
y_interval=52/(live_rows-1)
y_offset=4-y_interval
end
-- now assign target locations
local real_row=0
for row in all(self.rows) do
local row_alive = false
for ship in all(row) do
if not ship.dead then
if not row_alive then
real_row += 1
row_alive = true
end
ship.want_x = ship.col * x_interval + x_offset
ship.want_y = real_row * y_interval + y_offset
end -- ship updated
end -- row updated
end -- table updated
return false -- some ships remain
end
-->8
-- standard events
@ -1695,10 +1731,10 @@ function xp_gem:draw()
-- sprite map position:
-- sprite id to x and y,
-- offset shifts specific low
-- bits of lframe up to the the
-- bits of gframe up to the the
-- bit with value 4 as a cheap
-- way to pick an anim frame
if (lframe&0x0.003 == 0) qx, qy = (lframe&0x0.0004)<<16, (lframe&0x0.0008)<<15
if (gframe&0x0.003 == 0) qx, qy = (gframe&0x0.0004)<<16, (gframe&0x0.0008)<<15
sspr(
(s%16<<3)+qx,
(s\16<<3)+qy,
@ -1724,7 +1760,7 @@ end
function xp_gem:hitship(ship)
if (ship ~= primary_ship or primary_ship.dead) return false
primary_ship.xp += self.val
primary_ship.last_xp_frame = lframe
primary_ship.last_xp_frame = gframe
return true
end
@ -1795,7 +1831,12 @@ end
-- ordinary upgrades
function small_opts()
-- todo: include gun opts
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())}
for g in all(primary_ship.special_guns) do
add(opts, rnd(g:small_upgrade_opts()))
end
return pick(opts, 2)
end
-->8
@ -1804,7 +1845,7 @@ end
rearm_mode = mknew{
sel=1,
bfm=1,
crt_frm = 1,
crt_frm = 0,
pos=-1,
init=function(this)
poke(0x5f5c, 255) --no btnp repeat
@ -1819,7 +1860,7 @@ function rearm_mode:glow_box(x0, y0, x1, y1, c, cf)
i -= 1
rect(x0+i,y0+i,x1-i,y1-i,v)
end
fillp(crt[self.crt_frm&0xff])
fillp(crt[1+(self.crt_frm&7)])
rectfill(x0+4, y0+4, x1-4, y1-4, cf)
fillp()
end
@ -1851,7 +1892,7 @@ end
function rearm_mode:draw_option(id)
local rec = self.options[id]
self:glow_box(0,0,55,100,self:frame_col(self.sel == id),1)
self:glow_box(0,0,55,101,self:frame_col(self.sel == id),1)
spr(rec.icon,5, 5)
print(rec.hdr, 13, 8, 7)
print(rec.body, 5, 15, 6)
@ -1887,9 +1928,9 @@ function rearm_mode:draw()
camera(frac * -128 + (1-frac) * -56, 0)
self:draw_option(2)
camera(0, -28 * frac)
self:glow_box(0,101,111,127,self:frame_col(self.sel < 0),1)
self:glow_box(0,102,111,127,self:frame_col(self.sel < 0),1)
spr(96,15,107,4,2)
print("full ammo\nfull shield\n+50% health",54, 106, 6)
print("full ammo\nfull shield\n+50% health",54, 107, 6)
end
function rearm_mode:update_pos()
@ -1909,6 +1950,7 @@ function rearm_mode:update_pos()
end
function rearm_mode:update()
self.crt_frm+=0.25
self:update_pos()
if self.pos > 1 then
mode = game_mode
@ -2003,21 +2045,21 @@ cddddddddddd0000cddddddddddd0000cddddddddddd0000cddddddddddd0000cddddddddddd0000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
04444400044444440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
447777700477777a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
477aaa7a0477aaaa0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
47a0047a047a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
47a0447a047a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
47a4477a047a44400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
477777a00477777a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
477770000422aaaa2222000200000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
47a77700022ee0002eeee002e00022e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
47a4777002ea2e002e002e02ee022ee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
47a0477a22ea2e002e002e02e2e2e2e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
47a0047a2e2222e02e222e02e02e02e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
47a0047a2eeeeeea2eeee002e02e02e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0aa000aa2e7aa2ea2e00e002e02e02e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000002e0002e02e002e02e02e02e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
044444000444444400000000000000000000000000000000000000000000000000000000000000000000000000000000000bb000000aa0000009900000088000
447777700477777a0000000000000000000000000000000000000000000666000077700008888800000ab00006000060000bb000000aa0000009900000088000
477aaa7a0477aaaa0000000000000000000000000000000000000000006ddd5007fff70008eeee20000ab00006c006d0000bb000000aa0000009900000088000
47a0047a047a0000000000000000000000000000000000000000000006dd7d5007ffff4008eeee200aaabbb006ccccd0000bb000000aa0000009900000088000
47a0447a047a0000000000000000000000000000000000000000000006d7dd5007ffff4008eeee200bbb333006ccccd0000bb000000aa0000009900000088000
47a4477a047a4440000000000000000000000000000000000000000006ddd500004fff4008eeee20000b300006d00cd0000bb000000aa0000009900000088000
477777a00477777a0000000000000000000000000000000000000000005550000004440002222200000b30000d0000d0000bb000000aa0000009900000088000
477770000422aaaa22220002000002000000000000000000000000000000000000000000000000000000000000000000000bb000000aa0000009900000088000
47a77700022ee0002eeee002e00022e00000000000000000000000000000000000000000000000000000000000000000000bb000000aa0000009900000088000
47a4777002ea2e002e002e02ee022ee00000000000000000000000000005600000474000028282000004b000060000000bbbbbb00aaaaaa00999999008888880
47a0477a22ea2e002e002e02e2e2e2e0000000000000000000000000005d0d0004f0f400080e0e00000a000000c000d00b0000b00a0000a00900009008000080
47a0047a2e2222e02e222e02e02e02e000000000000000000000000005d07050070f0f2002e0e02004a0b0b0060c0c000b0bb0b00a0aa0a00909909008088080
47a0047a2eeeeeea2eeee002e02e02e000000000000000000000000006070d1004f0f040080e0e000b0b035000c0c0d00b0bb0b00a0aa0a00909909008088080
0aa000aa2e7aa2ea2e00e002e02e02e000000000000000000000000000d0d100002f0f2002e0e0200000300006000c000b0000b00a0000a00900009008000080
000000002e0002e02e002e02e02e02e0000000000000000000000000000510000002420002020200000b5000000000d00bbbbbb00aaaaaa00999999008888880
000000000e0000e00e000e00e00e00e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
__label__
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007777777777777777
@ -2149,3 +2191,12 @@ __label__
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666666666666665
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007555555555555555
__gff__
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000212060a0e01091119000000000000002232363a3e050d151d
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
__map__
00006b6b00006f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
7b6a00006a7b6e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
7778686878776c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
6767777767676c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
7877676777787d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000