From cd5b79ef4abe2e40cac5f3690d7b55ea87421d89 Mon Sep 17 00:00:00 2001 From: Kistaro Windrider Date: Sun, 26 Jan 2025 11:21:32 -0800 Subject: [PATCH] prototype: gun picking --- vacuum_gambit.p8 | 287 ++++++++++++++--------------------------------- 1 file changed, 83 insertions(+), 204 deletions(-) diff --git a/vacuum_gambit.p8 b/vacuum_gambit.p8 index 513471b..c35c478 100644 --- a/vacuum_gambit.p8 +++ b/vacuum_gambit.p8 @@ -683,6 +683,18 @@ gun_base = mknew{ icon = 20 } +-- gun_base subtypes are +-- level-up options that, +-- as an action, assign +-- themselves to the player +function gun_base:action() + if not primary_ship.special_guns then + primary_ship.special_guns = {self.new()} + else + add(primary_ship.special_guns, self.new()) + end +end + function bullet_base:hitship(_) self:die() return true @@ -765,13 +777,13 @@ zap_p = mknew(zap_e.new{ }) zap_gun_e = mknew(gun_base.new{ - cooldown = 0x0.000a, -- frames between shots - ammo = nil, -- unlimited ammo - main gun + cooldown = 0x0.0020, -- frames between shots actually_shoot = spawn_one(zap_e), }) zap_gun_p = mknew(zap_gun_e.new{ actually_shoot = spawn_one(zap_p), + hdr = "mAIN gUN", }) blast = mknew(bullet_base.new{ @@ -790,17 +802,22 @@ blast = mknew(bullet_base.new{ damage = 4, dx = 0, -- px/frame - dy = -2, + dy = -1, awaitcancel = false, - -- disable damage for 2 frames + -- disable damage for 4 frames -- when hitting something + -- todo: rewrite all ship hit + -- logic so i can avoid + -- repeating hits to the + -- same ship instead of + -- using a cooldown hitship = function(self, _) if self.damage > 0 and not self.awaitcancel then self.awaitcancel = true once_next_frame(function() new_events:push_back{ - wait = 2, + wait = 4, obj = self, saved_dmg = self.damage, move = function(self) @@ -821,10 +838,19 @@ blast = mknew(bullet_base.new{ blast_gun = mknew(gun_base.new{ icon = 13, - cooldown = 0x0.0020, -- frames between shots + cooldown = 0x0.0078, -- 120 frames between shots ammo = 5, maxammo = 5, actually_shoot = spawn_one(blast), + hdr = "bLASTER", + body= [[plasma orb +floats through + enemies. + +ammo: 5 +rate: 1 / 2sec + dmg: 4 +]], }) protron_e = mknew(bullet_base.new{ @@ -856,7 +882,7 @@ protron_p = mknew(protron_e.new{ protron_gun_e = mknew(gun_base.new{ icon = 25, - cooldown = 0x0.000f, -- frames between shots + cooldown = 0x0.0040, -- frames between shots ammo = nil, maxammo = nil, munition = protron_e @@ -885,6 +911,16 @@ end protron_gun_p = mknew(protron_gun_e.new{ munition = protron_p, + maxammo = 20, + cooldown = 0x0.0018, + hdr = "pROTRON", + body = [[spray shots +in a dense arc. + +ammo: 20 +rate: 2 / sec + dmg: 1 +]], }) vulcan_e = mknew(bullet_base.new{ @@ -917,7 +953,7 @@ vulcan_p = mknew(vulcan_e.new{ vulcan_gun_e = mknew(gun_base.new{ icon = 37, enemy = false, - cooldown = 0x0.0002, -- frames between shots + cooldown = 0x0.0003, -- frames between shots ammo = nil, maxammo = nil, munition=vulcan_e, @@ -936,6 +972,15 @@ vulcan_gun_e = mknew(gun_base.new{ vulcan_gun_p = mknew(vulcan_gun_e.new{ munition=vulcan_p, + maxammo = 100, + hdr = "vULCAN", + body = [[rapid fire +in a v shape. + +ammo: 100 +rate: 20/sec + dmg: 0.5 +]], }) -->8 @@ -1115,6 +1160,7 @@ 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) @@ -1347,32 +1393,9 @@ function spawn_blocking_spewy() end end -function spawn_bonus_frownie() - local f = spawn_frownie() - f.sprite = 7 - f.die = function(self) - spawn_repair_at(self.x+4, self.y+4) - frownie.die(self) - end -end - -function spawn_bonus_vulcan_chasey() +function spawn_vulcan_chasey() local c = spawn_chasey() c.main_gun=vulcan_gun_e.new{enemy=true} - c.die = function(self) - spawn_main_gun_at(self.x-1, self.y-1, vulcan_gun_p) - chasey.die(self) - end - c.sprite=4 - return c -end - -function spawn_bonus_shield_chasey() - local c = spawn_chasey() - c.die = function(self) - spawn_shield_upgrade_at(self.x-1, self.y-1) - chasey.die(self) - end c.sprite=4 return c end @@ -1421,7 +1444,6 @@ function spawn_rnd(typ, blocking, goodie,altspr) freeze -= self.ice self.ice=0 typ.die(self) - spawn_goodie(goodie, self.x, self.y, self.size) end, } if (altspr) s.spr = altspr @@ -1429,14 +1451,6 @@ function spawn_rnd(typ, blocking, goodie,altspr) return s end --- TODO: spawn_goodie compatible versions of gun drops --- TODO: goodie table -function spawn_goodie(goodie_name, x, y, sz) - if (not goodie_name or #goodie_name == 0) return - local sh = sz and sz/2 or 0 - _ENV[goodie_name].new{}:spawn_at(x+sh,y+sh) -end - function multi(times, interval, fnm, ...) local f,irm,vargs = _ENV[fnm],interval,pack(...) assert(type(f) == "function", fnm.." not a function") @@ -1459,31 +1473,29 @@ end -- where offset,eol is a special case. example_level_csv=[[1,spawn_frownie -60,spawn_bonus_vulcan_chasey +60,spawn_vulcan_chasey 61,spawn_blocky 85,spawn_spewy 100,spawn_spewy 115,spawn_spewy -130,spawn_bonus_frownie +130,spawn_frownie 145,spawn_spewy -200,spawn_bonus_shield_chasey +200,spawn_chasey 250,spawn_blocking_blocky -285,spawn_spec_gun_at,35,-11,blast_gun 310,spawn_blocking_blocky 310,spawn_blocking_blocky 310,spawn_blocking_blocky 311,spawn_frownie -350,spawn_main_gun_at,70,-11,protron_gun_p 401,spawn_frownie 420,spawn_blocking_frownie -430,spawn_bonus_vulcan_chasey +430,spawn_vulcan_chasey 450,spawn_frownie -465,spawn_bonus_frownie +465,spawn_frownie 480,spawn_chasey 500,multi,20,12,spawn_blocking_blocky -501,spawn_bonus_frownie +501,spawns_frownie 620,spawn_blocking_blocky -630,spawn_bonus_shield_chasey +630,spawn_vulcan_chasey 720,spawn_blocking_boss_chasey 721,eol]] @@ -1626,148 +1638,6 @@ function spawn_xp_at(x, y, off, amt) }:spawn_at(mid(x, 0, 124),mid(y,-4,125)) end -powerup = mknew(bullet_base.new{ - -- animated sprite array: "sprites" - -- to draw under or over anim, - -- override draw, draw the - -- under-part, call into - -- powerup.draw(self), then - -- draw the over-part - width = 1, - height = 1, - -- note: make hurtboxes larger - -- than sprite by 2px per side - -- since ship hitbox is tiny - -- but powerups should feel - -- easy to pick up - dx = 0, - dy = 0.75, - category = enemy_blt_cat, -- collides with player ship - damage = 0, - - anim_speed = 2, - loop_pause = 30 -- affected by animspeed -}) - --- sprite indexes for "sheen" animation -sheen8x8 = split"2,54,55,56,57,58,59,60,61" - -function powerup:draw() - spr(self.sprites[max(1, - ((lframe<<16)\self.anim_speed) - %(#self.sprites+self.loop_pause) - -self.loop_pause - +1)], - self.x, self.y, - self.width, self.height) -end - -repair = mknew(powerup.new{ - hurt = { - x_off = -2, - y_off = -2, - width = 12, - height = 12 - }, - x_off = 4, - y_off = 0, - sprites = sheen8x8, - icon = 53, - hitship = function(self, ship) - if (ship ~= primary_ship) return false - primary_ship.hp = min(primary_ship.maxhp, primary_ship.hp + 1) - return true - end, - draw = function(self) - spr(self.icon, self.x, self.y, self.width, self.height) - powerup.draw(self) - end -}) - -function spawn_repair_at(x, y) - repair.new():spawn_at(x, y) -end - -shield_upgrade = mknew(repair.new{ - icon=52 -}) - -function shield_upgrade:hitship(ship) - if (ship ~= primary_ship) return false - primary_ship.maxshield += 1 - return true -end - -function spawn_shield_upgrade_at(x, y) - shield_upgrade.new():spawn_at(x,y) -end - -gun_swap = mknew(powerup.new{ - hurt = { - x_off = -2, - y_off = -2, - width = 16, - height = 16 - }, - -- gun = gun_type.new{} - x_off = 6, - y_off = 0, - width = 2, - height = 2, - sprites = {64, 66, 68, 70, 72, 74, 76, 78}, - hitship = function(self, ship) - if (ship ~= primary_ship) return false - ship.main_gun = self.gun - return true - end, - draw = function(self) - powerup.draw(self) - spr(self.gun.icon, self.x+2, self.y+2, 1, 1) - end -}) - -function spawn_main_gun_at(x, y, gunt) - if (type(gunt)=="string") gunt=_ENV[gunt] - local gun_p = gun_swap.new{ - gun = gunt.new() - } - gun_p:spawn_at(x, y) -end - -spec_gun_pl = { - [1] = 2, - [14] = 6, - [2] = 14 -} - -function spawn_spec_gun_at(x, y, gunt) - if (type(gunt)=="string") gunt=_ENV[gunt] - local gun_p = gun_swap.new{ - gun = gunt.new(), - hitship = function(self, ship) - if (ship ~= primary_ship) return false - local specs = ship.special_guns - if specs == nil then - specs = {self.gun} - elseif #specs == 1 then - add(specs, self.gun) - else - specs[1]=specs[2] - specs[2]=self.gun - end - ship.special_guns = specs - return true - end, - draw = function(self) - pal(spec_gun_pl) - powerup.draw(self) - pal() - spr(self.gun.icon, self.x+2, self.y+2, 1, 1) - end - } - gun_p:spawn_at(x, y) -end - -->8 -- upgrade options @@ -1780,20 +1650,29 @@ end -- action: callback -- (method) +spec_gunt = { + protron_gun_p, + vulcan_gun_p, + blast_gun, +} + +-- picks n random items from +-- tbl; permutes tbl, selected +-- items at end +function pick(tbl, n) + local ret, top={}, #tbl + for x=top,top-n,-1 do + local idx = 1+rnd(x)\1 + add(ret, tbl[idx]) + tbl[idx]=tbl[x] + tbl[x]=ret[#ret] + end + return ret +end + -- add a new gun function spec_gun_opts() - return {{ - s=1, - hdr="placeholder", - body="placeholder", - action = function() end, - }, - { - s=1, - hdr="placeholder", - body="placeholder", - action = function() end, - }} + return pick(spec_gunt, 2) end -- major upgrades