From 0bd146341608b02a578f388bb753ec747ff1388c Mon Sep 17 00:00:00 2001 From: Kistaro Windrider Date: Sat, 31 May 2025 21:29:54 -0700 Subject: [PATCH] replace demo level with infinite copies of flotilla 0 --- vacuum_gambit.p8 | 388 ++++++----------------------------------------- 1 file changed, 49 insertions(+), 339 deletions(-) diff --git a/vacuum_gambit.p8 b/vacuum_gambit.p8 index aa61b9d..2c7c667 100644 --- a/vacuum_gambit.p8 +++ b/vacuum_gambit.p8 @@ -171,6 +171,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 +189,42 @@ function call_move(x) return x:move() end +function ones(n) + local ret = 0 + while n != 0 do + ret += + end +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 += 1 + 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_level(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 +288,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 @@ -619,7 +653,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 @@ -641,10 +675,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 @@ -813,12 +847,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 @@ -1251,81 +1285,10 @@ shield will 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, @@ -1658,259 +1621,6 @@ function flotilla:update() return false -- some ships remain end --->8 --- level and event system - --- 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. - --- effective frame number stops --- when freeze count is nonzero - --- 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, -} - -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, - } - 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 - end - end} -end - -function demo_spawn_f(ttn) - local spx,spy=rnd_spawn_loc() - local s = _ENV[ttn].new{ - x = spx, - y = spy, - want_x = 8 + rnd(96), - want_y = 8 + rnd(64) - } - eships:push_back(s) - return s -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. - -example_level_csv=[[1,spawn_frownie -20,demo_spawn_f,ship_mook -25,demo_spawn_f,ship_defender -30,demo_spawn_f,ship_turret -35,demo_spawn_f,ship_skirmisher -80,spawn_vulcan_chasey -81,spawn_blocky -100,spawn_spewy -125,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]] - -->8 -- standard events @@ -2017,10 +1727,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, @@ -2046,7 +1756,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