replace demo level with infinite copies of flotilla 0
This commit is contained in:
		
							
								
								
									
										388
									
								
								vacuum_gambit.p8
									
									
									
									
									
								
							
							
						
						
									
										388
									
								
								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 | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user