Starting state: my generic shmup engine from a while back
This commit is contained in:
		
							
								
								
									
										
											BIN
										
									
								
								genericshmup-basic-collision..p8.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								genericshmup-basic-collision..p8.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 15 KiB | 
							
								
								
									
										945
									
								
								genericshmup.p8
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										945
									
								
								genericshmup.p8
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,945 @@ | ||||
| pico-8 cartridge // http://www.pico-8.com | ||||
| version 34 | ||||
| __lua__ | ||||
| -- generic shmup | ||||
| -- by kistaro windrider | ||||
|  | ||||
| game = 1 | ||||
| win = 2 | ||||
| lose = 3 | ||||
|  | ||||
| debug = {} | ||||
|  | ||||
| function _init() | ||||
| -- create the pwr gradient | ||||
| -- 15 is the gradient color | ||||
|  poke(0x5f5f,0x3f) | ||||
|  poke(0x5f68,10) | ||||
|  poke(0x5f69,10) | ||||
|  poke(0x5f6a,9) | ||||
|  poke(0x5f6b,4) | ||||
|  memset(0x5f78,0xa8,3) | ||||
|  init_bullet_mt() | ||||
|  init_ship_mt() | ||||
| 	wipe_level() | ||||
| 	primary_ship.special_gun = new_gun_of(blast_gun_t) | ||||
| 	load_level(example_level) | ||||
| 	state = game | ||||
| end | ||||
|  | ||||
| function wipe_level() | ||||
|  primary_ship = new_p1() | ||||
|  pships = {primary_ship} | ||||
|  eships = {} | ||||
|  pbullets = {} | ||||
|  ebullets = {} | ||||
|  intangibles = {} | ||||
|  events = {} | ||||
| end | ||||
|  | ||||
| function _update60() | ||||
|  if (state == game) updategame() | ||||
| end | ||||
|  | ||||
| function updategame() | ||||
|  local leveldone = level_frame() | ||||
| 	local deaths = {} | ||||
| 	for i, e in ipairs(events) do | ||||
| 	 if (e()) add(deaths, i) | ||||
| 	end | ||||
| 	bury_the_dead(events, deaths) | ||||
|  for _, tbl in ipairs({pships, eships, pbullets, ebullets, intangibles}) do | ||||
| 	 local deaths = {} | ||||
| 	 for i, x in ipairs(tbl) do | ||||
| 	  if (x:move()) add(deaths, i) | ||||
| 	 end | ||||
| 	 bury_the_dead(tbl, deaths) | ||||
| 	end | ||||
| 	--then, calculate collisions | ||||
| 	local pdeaths = {} | ||||
| 	local edeaths = {} | ||||
| 	for ip, ps in ipairs(pships) do | ||||
| 	 for ie, es in ipairs(eships) do | ||||
| 	  if collides(hurtbox(ps), hurtbox(es)) then | ||||
| 	   if (es:hitship(ps)) add(edeaths, ie) | ||||
| 	   if ps:hitship(es) then | ||||
| 	    add(pdeaths, ip) | ||||
| 	    break | ||||
| 	   end | ||||
| 	  end | ||||
| 	 end | ||||
| 	end | ||||
| 	bury_the_dead(pships, pdeaths) | ||||
| 	bury_the_dead(eships, edeaths) | ||||
| 	pdeaths = {} | ||||
| 	edeaths = {} | ||||
| 	for ip, ps in ipairs(pships) do | ||||
| 	 for ie, eb in ipairs(ebullets) do | ||||
| 	  if collides(hurtobx(ps), hurtbox(eb)) then | ||||
| 	   if (eb:hitship(ps)) add(edeaths, ie) | ||||
| 	   if ps:hitbullet(eb) then | ||||
| 	    add(pdeaths, ip) | ||||
| 	    break | ||||
| 	   end | ||||
| 	  end | ||||
| 	 end | ||||
| 	end | ||||
| 	bury_the_dead(pships, pdeaths) | ||||
| 	bury_the_dead(ebullets, edeaths) | ||||
| 	pdeaths = {} | ||||
| 	edeaths = {} | ||||
| 	for ip, pb in ipairs(pbullets) do | ||||
| 	 for ie, es in ipairs(eships) do | ||||
| 	  if collides(hurtbox(pb), hurtbox(es)) then | ||||
| 	   if (es:hitbullet(pb)) add(edeaths, ie) | ||||
| 	   if pb:hitship(es) then | ||||
| 	    add(pdeaths, ip) | ||||
| 					break | ||||
| 				end | ||||
| 	  end | ||||
| 	 end | ||||
| 	end | ||||
| 	bury_the_dead(eships, edeaths) | ||||
| 	bury_the_dead(pbullets, pdeaths) | ||||
| 	 | ||||
| 	if leveldone and ((#eships + #ebullets + #events) == 0) then | ||||
| 	  state = win | ||||
| 	end | ||||
| 	if #pships == 0 then | ||||
| 	  state = lose | ||||
| 	end | ||||
| end | ||||
|  | ||||
| function _draw() | ||||
|  drawgame() | ||||
|  draw_debug() | ||||
|  if (state == win) dropshadow("win",50,61,11) | ||||
|  if (state == lose) dropshadow("fail",48,61,8) | ||||
| end | ||||
|  | ||||
| function draw_debug() | ||||
|  if (#debug==0) return | ||||
|  cursor(0,0,7) | ||||
|  foreach(debug,print) | ||||
|  debug={} | ||||
| end | ||||
|  | ||||
| function drawgame() | ||||
|  cls() | ||||
|  clip(0,0,112,128) | ||||
|  for tbl in all{pbullets, pships, eships, intangibles, ebullets} do | ||||
|   for x in all(tbl) do | ||||
|    x:draw() | ||||
|   end | ||||
|  end | ||||
|  clip(0,0,128,128) | ||||
|  drawhud() | ||||
| end | ||||
|  | ||||
| function drawhud() | ||||
|  -- 112-and-right is hud zone | ||||
|  rectfill(112, 0, 127, 127,0x56) | ||||
|  rect(112,0,127,127,7) | ||||
|  line(127,1,127,127,5) | ||||
|  line(113,127) | ||||
|   | ||||
|  draw_gun_info("❎",116,3,primary_ship.main_gun) | ||||
|  draw_gun_info("🅾️",116,31,primary_ship.special_gun) | ||||
|   | ||||
|  dropshadow("pwr",114,59,1) | ||||
|  inset(114,66,125,92) | ||||
|  vertmeter(115,67,124,91,primary_ship.power, primary_ship.max_power, 15) | ||||
|   | ||||
|  dropshadow("h s",114,97,1) | ||||
|  inset(114,104,125,125) | ||||
|  line(119,105,119,124,7) | ||||
|  line(120,105,120,125,5) | ||||
|  vertmeter(115,105,118,124,primary_ship.hp, primary_ship.maxhp, 8) | ||||
|  vertmeter(121,105,124,124,primary_ship.shield, primary_ship.maxshield,12) | ||||
| end | ||||
|  | ||||
| function draw_gun_info(lbl,x,y,gun) | ||||
|  dropshadow(lbl,x,y,1) | ||||
|  inset(114,y+7,125,y+18) | ||||
|  inset(114,y+20,125,y+24) | ||||
|  if(gun) then | ||||
|   spr(gun.icon,116,y+9,1,1) | ||||
|   --115 to 124 - ammo bar. round up | ||||
|   if gun.ammo == nil then | ||||
|    fillp(0xa5a5) | ||||
|    rectfill(115,y+21,124,y+23,0xea) | ||||
|    fillp(0) | ||||
|   elseif gun.ammo > 0 then | ||||
|    rectfill( | ||||
|      115,y+21, | ||||
|      115+flr(9*gun.ammo/gun.maxammo), | ||||
|      y+23,10) | ||||
|   else | ||||
|    line(118, y+22, 121, y+22, 2) | ||||
|   end | ||||
|  end | ||||
| end | ||||
|  | ||||
| function vertmeter(x0,y0,x1,y1,val,maxval,col) | ||||
|  if (val <= 0) return | ||||
|  local h = y1-y0 | ||||
|  local pxm1 = flr(h*val/maxval) | ||||
|  rectfill(x0,y1-pxm1,x1,y1,col) | ||||
| end | ||||
|  | ||||
| function inset(x0,y0,x1,y1) | ||||
|  rectfill(x0,y0,x1,y1,0) | ||||
|  rect(x0,y0,x1,y1,7) | ||||
|  line(x1,y0,x0,y0,5) | ||||
|  line(x0,y1,5) | ||||
| end | ||||
|  | ||||
| function dropshadow(str, x, y, col) | ||||
|  print(str, x+1, y+1, 5) | ||||
|  print(str, x, y, col) | ||||
| end | ||||
|  | ||||
| function grab_p1_butts() | ||||
|   | ||||
|  local b = btn() | ||||
|  return { | ||||
|   [0]=b&0x1, | ||||
|   [1]=(b&0x2)>>1, | ||||
|   [2]=(b&0x4)>>2, | ||||
|   [3]=(b&0x8)>>3, | ||||
|   [4]=(b&0x10)>>4, | ||||
|   [5]=(b&0x20)>>5 | ||||
|  } | ||||
| end | ||||
|  | ||||
| function bury_the_dead(tbl, dead) | ||||
|  if (#dead == 0) return | ||||
|  local tail = dead[1] | ||||
|  local head = tail + 1 | ||||
|  local deaddex = 2 | ||||
|   | ||||
|  while head <= #tbl do | ||||
|   while deaddex <= #dead and head == dead[deaddex] do | ||||
|    deaddex += 1 | ||||
|    head += 1 | ||||
|   end | ||||
|   if (head > #tbl) break | ||||
|   tbl[tail] = tbl[head]  | ||||
|   head += 1 | ||||
|   tail += 1 | ||||
|  end | ||||
|   | ||||
|  for i=1,(head-tail) do | ||||
|   deli(tbl) | ||||
|  end | ||||
| end | ||||
| -->8 | ||||
| --ships, including player | ||||
|  | ||||
| function init_ship_mt() | ||||
|  setmetatable(player, ship_t) | ||||
|  setmetatable(frownie, ship_t) | ||||
|  setmetatable(blocky, frownie_t) | ||||
| end | ||||
|  | ||||
| player = { | ||||
|  --shape | ||||
|  sprite = 1, --index of ship sprite | ||||
|  size = 2, --all ships are square; how many 8x8 sprites? | ||||
|  hurt = { -- hurtbox - where this ship can be hit | ||||
|   x_off = 6, -- upper left corner | ||||
|   y_off = 6, -- relative to ship ulc | ||||
|   width = 4, | ||||
|   height = 4 | ||||
|  }, | ||||
|   | ||||
|  -- health and power | ||||
|  hp = 3, -- current health, non-regenerating | ||||
|  maxhp = 3, -- player only; other ships never heal | ||||
|  shield = 2, -- regenerates, using power | ||||
|  maxshield = 2, | ||||
|  shieldcost = 300, -- power cost to refill shield | ||||
|  generator = 1.5,  -- 1 feels too slow | ||||
|  | ||||
|  -- gun | ||||
|  main_gun = nil, -- assign at spawn time | ||||
|  special_gun = nil, | ||||
|  fire_off_x = 8,  -- offset where bullets come from | ||||
|  fire_off_y = 0, | ||||
|  | ||||
|  -- position | ||||
|  x=52, -- x and y are for upper left corner | ||||
|  y=96, | ||||
|  xmomentum = 0, | ||||
|  ymomentum = 0, | ||||
|  maxspd = 2.5, -- momentum cap | ||||
|  thrust = 0.25, -- momentum added from button | ||||
|  drag = 0.125, -- momentum lost per frame | ||||
|  slip = false, -- does not slide down screen | ||||
|  grab_butts = grab_p1_butts, -- button fetch algorithm | ||||
| } | ||||
|  | ||||
| player_t = { | ||||
|  __index = player | ||||
| } | ||||
|  | ||||
| function new_p1() | ||||
|  p = { | ||||
|   main_gun = new_gun_of(zap_gun_t, false) | ||||
|  } | ||||
|  setmetatable(p, player_t) | ||||
|  return p | ||||
| end | ||||
|  | ||||
| frownie = { | ||||
|  --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 = 1, -- upper left corner | ||||
|   y_off = 1, -- relative to ship ulc | ||||
|   width = 6, | ||||
|   height = 6 | ||||
|  }, | ||||
|   | ||||
|  -- health and power | ||||
|  hp = 1, -- enemy ships need no max hp | ||||
|  | ||||
|  -- 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, | ||||
|  grab_butts = function(discard_self) | ||||
|   -- buttons are effectively analog | ||||
|   -- and negative buttons work just fine! | ||||
|   local butts = {} | ||||
|   local tstate = (1 + flr(4*t() + 0.5)) % 6 | ||||
|   butts[0] = ((tstate==1 or tstate==2) and 1) or 0 | ||||
|   butts[1] = ((tstate==4 or tstate==5) and 1) or 0 | ||||
|   for b=2, 5 do | ||||
|    butts[b]=0 | ||||
|   end | ||||
|   return butts | ||||
|  end, -- button fetch algorithm | ||||
| } | ||||
| frownie_t = { | ||||
|  __index = frownie | ||||
| } | ||||
|  | ||||
| blocky = { | ||||
|  sprite = 10, | ||||
|  hp = 2, | ||||
|  ow = function(self) | ||||
|   if self.hp <= 1 then | ||||
|    self.sprite = 11 | ||||
|   else | ||||
|    self.sprite = 10 | ||||
|   end | ||||
|  end | ||||
| } | ||||
|  | ||||
| blocky_t = { | ||||
|  __index = blocky | ||||
| } | ||||
| -->8 | ||||
| --ship behavior | ||||
|  | ||||
| scrollrate = 0.25 --in px/frame | ||||
|  | ||||
| ship_m = { | ||||
|  | ||||
|  -- ships have no shield by default | ||||
|  shield = 0, | ||||
|  maxshield = 0, | ||||
|  shieldcost = 32767.9, | ||||
|  shieldcooldown =  180, | ||||
|   | ||||
|  -- default generator behavior: | ||||
|  -- 10 seconds for a full charge | ||||
|  max_power = 600, | ||||
|  power = 600, | ||||
|  generator = 1, -- power gen per frame | ||||
|  | ||||
|  invincible_until = -32768, | ||||
|   | ||||
|  slip = true  -- most enemies slide | ||||
| } | ||||
|  | ||||
| ship_t = { | ||||
|   __index = ship_m, | ||||
| } | ||||
|  | ||||
| function ship_m.die(_) | ||||
| end | ||||
|  | ||||
| function ship_m.move(ship) | ||||
|  ship:refresh_shield() | ||||
|  ship.power = min(ship.max_power, ship.power + ship.generator) | ||||
|  butt = ship.grab_butts() | ||||
|  if (butt[5] > 0) ship:maybe_shoot(ship.main_gun) | ||||
|  if (butt[4] > 0) ship:maybe_shoot(ship.special_gun) | ||||
|  ship.xmomentum += (ship.thrust * butt[1]) - (ship.thrust * butt[0]) | ||||
|  ship.ymomentum += (ship.thrust * butt[3]) - (ship.thrust * butt[2]) | ||||
|  ship.xmomentum = mid(-ship.maxspd, ship.maxspd, ship.xmomentum) | ||||
|  ship.ymomentum = mid(-ship.maxspd, ship.maxspd, ship.ymomentum) | ||||
|  | ||||
|  ship.x = mid(0, 112 - 8 * ship.size, ship.x + ship.xmomentum) | ||||
|  if not ship.slip then | ||||
|   ship.y = mid(0, 128 - 8 * ship.size, ship.y + ship.ymomentum) | ||||
|  end | ||||
|   | ||||
|  --friction | ||||
|  local xfric = 0 | ||||
|  local yfric = 0 | ||||
|  if (ship.xmomentum > 0) xfric = min(ship.xmomentum, ship.drag) | ||||
|  if (ship.xmomentum < 0) xfric = max(ship.xmomentum, -ship.drag) | ||||
|  if (ship.ymomentum > 0) yfric = min(ship.ymomentum, ship.drag) | ||||
|  if (ship.ymomentum < 0) yfric = max(ship.ymomentum, -ship.drag) | ||||
|  ship.xmomentum -= xfric | ||||
|  ship.ymomentum -= yfric | ||||
|   | ||||
|  -- "scrolling" behavior | ||||
|  if ship.slip then | ||||
|   ship.y += scrollrate | ||||
|   if ship.y >= 128 then | ||||
|    ship:die() | ||||
|    return true | ||||
|   end | ||||
|  end | ||||
|  return false | ||||
| end  -- moveship(ship) | ||||
|  | ||||
| function ship_m.draw(ship) | ||||
| 	spr(ship.sprite, ship.x, ship.y, ship.size, ship.size) | ||||
| end | ||||
|  | ||||
| function hurtbox(ship) | ||||
|  return { | ||||
|   x=ship.x + ship.hurt.x_off, | ||||
|   y=ship.y + ship.hurt.y_off, | ||||
|   width=ship.hurt.width, | ||||
|   height=ship.hurt.height | ||||
|  } | ||||
| end | ||||
|  | ||||
| function ship_m:maybe_shoot(gun) | ||||
|  if (not gun) return | ||||
|  if (self.power < gun.power) return | ||||
|  if (not gun:shoot(self.x + self.fire_off_x, self.y + self.fire_off_y)) return | ||||
|  self.power -= gun.power | ||||
| end | ||||
|  | ||||
| function ship_m:hitship(other) | ||||
|  return self:hitsomething(1) | ||||
| end | ||||
|  | ||||
| function ship_m:hitbullet(b) | ||||
|  return self:hitsomething(b.damage) | ||||
| end | ||||
|  | ||||
| function ship_m:hitsomething(dmg) | ||||
|  if (dmg <= 0) return false | ||||
|  if (lframe < self.invincible_until) return false | ||||
|  self.shield_refresh_ready = lframe + self.shieldcooldown | ||||
|  if self.shield >= dmg then | ||||
|   self.shield -= dmg | ||||
|   self:ow() | ||||
|   return false | ||||
|  end	 | ||||
|  dmg -= self.shield | ||||
|  self.shield = 0 | ||||
|  self.hp -= dmg | ||||
|  if self.hp <= 0 then | ||||
|   self:die() | ||||
|   return true | ||||
|  end | ||||
|  self:ow() | ||||
|  return false | ||||
| end | ||||
|  | ||||
| function ship_m:ow() | ||||
|  -- todo: implement damage blink | ||||
| end | ||||
|  | ||||
| function ship_m:refresh_shield() | ||||
|  if (self.shield >= self.maxshield) return | ||||
|  if (lframe < self.shield_refresh_ready) return | ||||
|  if (self.power < self.shieldcost) return | ||||
|  self.shield += 1 | ||||
|  self.power -= self.shieldcost | ||||
|  self.shield_refresh_ready = lframe + self.shieldcooldown | ||||
| end | ||||
| -->8 | ||||
| -- collisions | ||||
|  | ||||
| -- box: x, y, width, height | ||||
|  | ||||
| function collides(box1, box2) | ||||
| 	local dx = box2.x - box1.x | ||||
| 	local cx = dx >= 0 and dx <= (box1.width or 0) | ||||
| 	dx = box1.x - box2.x | ||||
| 	cx = cx or (dx >= 0 and dx <= (box2.width or 0)) | ||||
| 	if (not cx) return false | ||||
| 	 | ||||
| 	local dy = box2.y - box1.y | ||||
| 	local cy = dy >= 0 and dy <= (box1.height or 0) | ||||
| 	dy = box1.y - box2.y | ||||
| 	cy = cy or (dy >= 0 and dy <= (box2.height or 0)) | ||||
| 	return cy | ||||
| end | ||||
| -->8 | ||||
| -- level and event system | ||||
|  | ||||
| -- a level is a map from | ||||
| -- effective frame number to | ||||
| -- callback for that frame. | ||||
|  | ||||
| -- 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 | ||||
| lframe = 0 | ||||
|  | ||||
| -- do not advance distance when | ||||
| -- nonzero | ||||
| freeze = 0 | ||||
|  | ||||
| eol = {} | ||||
|  | ||||
| function load_level(lvltbl) | ||||
|  distance = 0 | ||||
|  lframe = 0 | ||||
|  freeze = 0 | ||||
|  current_level = {} | ||||
|  for frame, cb in pairs(lvltbl) do | ||||
|   current_level[frame] = cb | ||||
|  end | ||||
| end | ||||
|  | ||||
| function level_frame() | ||||
|  lframe += 1 | ||||
|  if (current_level == nil) return true | ||||
|  if freeze == 0 then  | ||||
|   distance += 1 | ||||
|   local cb = current_level[distance] | ||||
|   if cb ~= nil then | ||||
|    if cb == eol then | ||||
|     current_level = nil | ||||
|     return true | ||||
|    else | ||||
|     cb() | ||||
|    end | ||||
|   end | ||||
|  end | ||||
|  return false | ||||
| end | ||||
| -->8 | ||||
| -- example level | ||||
|  | ||||
| function spawn_rnd_x(mt) | ||||
|  s = { | ||||
|   x = rnd(104), | ||||
|   y = -(mt.__index.size * 8 - 1) | ||||
|  } | ||||
|  setmetatable(s, mt) | ||||
|  add(eships, s) | ||||
| end | ||||
|  | ||||
| function spawn_blocking_rnd_x(mt) | ||||
|  freeze += 1 | ||||
|  s = { | ||||
|   x = rnd(104), | ||||
|   y = -7, | ||||
|   die = function(self) | ||||
|    freeze -= 1 | ||||
|    mt.__index.die(self) | ||||
|   end | ||||
|  } | ||||
|  setmetatable(s, mt) | ||||
|  add(eships, s) | ||||
| end | ||||
|  | ||||
| function spawn_frownie() | ||||
|  spawn_rnd_x(frownie_t) | ||||
| end | ||||
|  | ||||
| function spawn_blocking_frownie() | ||||
|  spawn_blocking_rnd_x(frownie_t) | ||||
| end | ||||
|  | ||||
| function spawn_blocky() | ||||
|  spawn_rnd_x(blocky_t) | ||||
| end | ||||
|  | ||||
| function spawn_blocking_blocky() | ||||
|  spawn_blocking_rnd_x(blocky_t) | ||||
| end | ||||
|  | ||||
| example_level = { | ||||
|  [1]=spawn_frownie, | ||||
|  [60]=spawn_blocky, | ||||
|  [61]=spawn_blocky, | ||||
|  [250]=spawn_blocking_blocky, | ||||
|  [310]=function() | ||||
|   spawn_blocking_blocky() | ||||
|   spawn_blocking_blocky() | ||||
|   spawn_blocking_blocky() | ||||
|  end, | ||||
|  [311]=spawn_frownie, | ||||
|  [401]=spawn_frownie, | ||||
|  [420]=spawn_blocking_frownie, | ||||
|  [450]=spawn_frownie, | ||||
|  [451]=eol | ||||
| } | ||||
| -->8 | ||||
| -- bullets and guns | ||||
|  | ||||
| function init_bullet_mt() | ||||
|  setmetatable(zap, bullet_t) | ||||
|  setmetatable(zap_gun, gun_t) | ||||
|  setmetatable(blast, bullet_t) | ||||
|  setmetatable(blast_gun, gun_t) | ||||
| end | ||||
|  | ||||
| zap = { | ||||
|  --shape | ||||
|  psprite = 8, --index of player ammo sprite | ||||
|  esprite = 9, -- index of enemy ammo sprite | ||||
|  width = 1, --in 8x8 blocks | ||||
|  height = 1, | ||||
|  hurt = { -- hurtbox - where this ship can be hit | ||||
|   x_off = 0, -- upper left corner | ||||
|   y_off = 0, -- relative to sprite | ||||
|   width = 2, | ||||
|   height = 8 | ||||
|  }, | ||||
|  center_x_off = 1, -- how to position by ship | ||||
|  bottom_y_off = 0, | ||||
|  top_y_off = 0, | ||||
|   | ||||
|  damage = 1, | ||||
|  dx = 0,  -- px/frame | ||||
|  dy = 8, | ||||
|  | ||||
|  hitship = function(_, _) | ||||
|   return true | ||||
|  end | ||||
| } | ||||
| zap_t = { | ||||
|  __index = zap | ||||
| } | ||||
|  | ||||
| zap_gun = { | ||||
|  enemy = false, | ||||
|  power = 30, -- power consumed per shot | ||||
|  cooldown = 10, -- frames between shots | ||||
|  ammo = nil, -- unlimited ammo - main gun | ||||
|  t = zap_t -- metatable of bullet to fire | ||||
| } | ||||
|  | ||||
| zap_gun_t = { | ||||
|  __index = zap_gun | ||||
| } | ||||
|  | ||||
| blast = { | ||||
|  --shape | ||||
|  psprite = 12, --index of player ammo sprite | ||||
|  esprite = 3, -- index of enemy ammo sprite | ||||
|  width = 1, --in 8x8 blocks | ||||
|  height = 1, | ||||
|  hurt = { -- hurtbox - where this ship can be hit | ||||
|   x_off = 1, -- upper left corner | ||||
|   y_off = 1, -- relative to sprite | ||||
|   width = 6, | ||||
|   height = 6 | ||||
|  }, | ||||
|  center_x_off = 4, -- how to position by ship | ||||
|  bottom_y_off = 0, | ||||
|  top_y_off = 0, | ||||
|   | ||||
|  damage = 4, | ||||
|  dx = 0,  -- px/frame | ||||
|  dy = 2, | ||||
|  | ||||
|  -- disable damage for 2 frames | ||||
|  -- when hitting something | ||||
|  hitship = function(self, _) | ||||
|   self.damage = 0 | ||||
|   local wait = 2 | ||||
|   e = function() | ||||
|    wait -= 1 | ||||
|    if wait <= 0 then | ||||
|     self.damage = 4 | ||||
|     return true | ||||
|    end | ||||
|    return false | ||||
|   end | ||||
|   add(events, e) | ||||
|  end | ||||
| } | ||||
| blast_t = { | ||||
|  __index = blast | ||||
| } | ||||
|  | ||||
| blast_gun = { | ||||
|  icon = 13, | ||||
|  enemy = false, | ||||
|  power = 0, -- ammo, not power | ||||
|  cooldown = 30, -- frames between shots | ||||
|  ammo = 5, | ||||
|  maxammo = 5, | ||||
|  t = blast_t -- metatable of bullet to fire | ||||
| } | ||||
|  | ||||
| blast_gun_t = { | ||||
|  __index = blast_gun | ||||
| } | ||||
|  | ||||
| function new_gun_of(mt, is_enemy) | ||||
|  g = { | ||||
|   enemy = e | ||||
|  } | ||||
|  setmetatable(g, mt) | ||||
|  return g | ||||
| end | ||||
| -->8 | ||||
| -- bullet and gun behaviors | ||||
|  | ||||
| bullet_base = { } | ||||
|  | ||||
| bullet_t = { | ||||
|  __index = bullet_base | ||||
| } | ||||
|  | ||||
| gun_base = {  | ||||
|  shoot_ready = -32768, | ||||
|   | ||||
|  icon = 20 | ||||
| } | ||||
|  | ||||
| gun_t = { | ||||
|  __index = gun_base | ||||
| } | ||||
|  | ||||
| function bullet_base:hitship(_) | ||||
|  self:die() | ||||
|  return true | ||||
| end | ||||
|  | ||||
| function bullet_base:die() | ||||
| end | ||||
|  | ||||
| function bullet_base:move() | ||||
|  self.x += self.dx | ||||
|  if self.enemy then | ||||
|   self.y += self.dy | ||||
|   if self.y > 128 then | ||||
|    self:die() | ||||
|    return true | ||||
|   end | ||||
|  else | ||||
|   self.y -= self.dy | ||||
|   if self.y < -8*self.height then | ||||
|    self:die() | ||||
|    return true | ||||
|   end | ||||
|  end | ||||
|  return false | ||||
| end | ||||
|  | ||||
| function bullet_base:draw() | ||||
|  spr(self.sprite, self.x, self.y, self.width, self.height) | ||||
| end | ||||
|  | ||||
| function bullet_base:spawn_at(x, y) | ||||
|  self.x = x - self.center_x_off | ||||
|  if self.enemy then | ||||
|   self.y = y + self.top_y_off | ||||
|   add(ebullets, self) | ||||
|  else | ||||
|   self.y = y - (8 * self.height) + self.bottom_y_off | ||||
|   add(pbullets, self) | ||||
|  end | ||||
| end | ||||
|  | ||||
| function gun_base:shoot(x, y) | ||||
|  if (lframe < 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 | ||||
|  b = { } | ||||
|  setmetatable(b, self.t) | ||||
|  if self.enemy then | ||||
|   b.enemy = true | ||||
|   b.sprite = b.esprite | ||||
|  else | ||||
|   b.enemy = false | ||||
|   b.sprite = b.psprite | ||||
|  end | ||||
|  b:spawn_at(x, y) | ||||
|  return true | ||||
| end | ||||
| __gfx__ | ||||
| 000000000000000aa00000000088880090000009e00000000000000e00dddd003b00000082000000066666600555555000333300002222000000000000000000 | ||||
| 000000000000000aa00000000822228099000009ee0000000000000e0d1111d037000000a2000000655555565555555503bbbb30028888200000000000000000 | ||||
| 00700700000000aaaa00000082a22a280990009000ee0000000000eed171171db7000000a800000065755756557557553bbaabb3288aa8820000000000000000 | ||||
| 00077000000000aaaa0000008222222800990900000ee00000000ee0d111111db7000000a800000065555556555555553ba77ab328a77a820000000000000000 | ||||
| 0007700000000aaaaaa00000822aa228000990000000ee000000ee00d117711db7000000a800000065555556555775553ba77ab328a77a820000000000000000 | ||||
| 0070070000000aaaaaa0000082a22a2800999900000000eee00ee000d171171db7000000a800000065777756557557553bbaabb3288aa8820000000000000000 | ||||
| 000000000000aaaaaaaa0000082222800990099000000000eeee00000d1111d037000000a2000000655555565557755503bbbb30028888200000000000000000 | ||||
| 000000000000aa8888aa0000008888009900009900000000eeee000000dddd003b00000082000000066666600555555000333300002222000000000000000000 | ||||
| 00000000000aaa8888aaa00000000000b000000b0000000ee00ee000000000000000000000000000000000000000000000000000000000000000000000000000 | ||||
| 00000000000aaa8888aaa0000000000000bbbb00000000ee000eeee0000000000000000000000000000000000000000000000000000000000000000000000000 | ||||
| 0000000000aaaa8888aaaa00000000000b0000b000000ee0000eeee0000000000000000000000000000000000000000000000000000000000000000000000000 | ||||
| 0000000000aaaaaaaaaaaa00000000000b0bb0b00000ee000000eee0000000000000000000000000000000000000000000000000000000000000000000000000 | ||||
| 000000000aaaaaaaaaaaaaa0000000000b0bb0b0000ee00000000eee000000000000000000000000000000000000000000000000000000000000000000000000 | ||||
| 000000000aaaaaaaaaaaaaa0000000000b0000b000ee000000000eee000000000000000000000000000000000000000000000000000000000000000000000000 | ||||
| 00000000aaaaaaaaaaaaaaaa0000000000bbbb00ee000000000000ee000000000000000000000000000000000000000000000000000000000000000000000000 | ||||
| 00000000aaaaaaaaaaaaaaaa00000000b000000be0000000000000ee000000000000000000000000000000000000000000000000000000000000000000000000 | ||||
| __label__ | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007777777777777777 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666666666666665 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666666666666665 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666611111666665 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666115151166665 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666111611156665 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666115161156665 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666611111556665 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666665555566665 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666666666666665 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007655555555555565 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650b000000b0765 | ||||
| 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765000bbbb000765 | ||||
| 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076500b0000b00765 | ||||
| 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076500b0bb0b00765 | ||||
| 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076500b0bb0b00765 | ||||
| 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076500b0000b00765 | ||||
| 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765000bbbb000765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650b000000b0765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007657777777777765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666666666666665 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007655555555555565 | ||||
| 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765aeaeaeaeae765 | ||||
| 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765eaeaeaeaea765 | ||||
| 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765aeaeaeaeae765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007657777777777765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666666666666665 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666666666666665 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666666666666665 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666611111666665 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666115551166665 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666115161156665 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666115651156665 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666611111556665 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666665555566665 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666666666666665 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007655555555555565 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650002222000765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650028888200765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650288aa8820765 | ||||
| 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765028a77a820765 | ||||
| 0000000000000000000000000000000000006666660000000000000000000000000000000000000005555550006666660000000000000000765028a77a820765 | ||||
| 00000000000000000000000000000000000655555560000000000000000000000000000000000000555555550655555560000000000000007650288aa8820765 | ||||
| 00000000000000000000000000000000000657557560000000000000000000000000000000000000557557550657557560000000000000007650028888200765 | ||||
| 00000000000000000000000000000000000655555560000000000000000000000000000000000000555555550655555560000000000000007650002222000765 | ||||
| 00000000000000000000000000000000000655555560000000000000000000000000000000000000555775550655555560000000000000007650000000000765 | ||||
| 00000000000000000000000000000000000657777560000000000000000000000000000000000000557557550657777560000000000000007657777777777765 | ||||
| 00000000000000000000000000000000000655555560000000000000000000000000000000000000555775550655555560000000000000007666666666666665 | ||||
| 00000000000000000000000000000000000066666600000000000000000000000000000000000000055555500066666600000000000000007655555555555565 | ||||
| 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765aaaaaaaaaa765 | ||||
| 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765aaaaaaaaaa765 | ||||
| 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765aaaaaaaaaa765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007657777777777765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666666666666665 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666666666666665 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666666666666665 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007611161616111665 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007615151515151565 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007611151515116565 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007615551115151665 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007615661115151565 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007665666555656565 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666666666666665 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007655555555555565 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007659999999999765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007659999999999765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007659999999999765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007654444444444765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007659999999999765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007654444444444765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007659999999999765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007654444444444765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007654444444444765 | ||||
| 000000000000000000000000000000000000000000000000aa000000000000000000000000000000000000000000000000000000000000007654444444444765 | ||||
| 000000000000000000000000000000000000000000000000aa000000000000000000000000000000000000000000000000000000000000007654444444444765 | ||||
| 00000000000000000000000000000000000000000000000aaaa00000000000000000000000000000000000000000000000000000000000007654444444444765 | ||||
| 00000000000000000000000000000000000000000000000aaaa00000000000000000000000000000000000000000000000000000000000007657777777777765 | ||||
| 0000000000000000000000000000000000000000000000aaaaaa0000000000000000000000000000000000000000000000000000000000007666666666666665 | ||||
| 0000000000000000000000000000000000000000000000aaaaaa0000000000000000000000000000000000000000000000000000000000007666666666666665 | ||||
| 000000000000000000000000000000000000000000000aaaaaaaa000000000000000000000000000000000000000000000000000000000007666666666666665 | ||||
| 000000000000000000000000000000000000000000000aa8888aa000000000000000000000000000000000000000000000000000000000007666666666666665 | ||||
| 00000000000000000000000000000000000000000000aaa8888aaa00000000000000000000000000000000000000000000000000000000007616166666611665 | ||||
| 00000000000000000000000000000000000000000000aaa8888aaa00000000000000000000000000000000000000000000000000000000007615156666165565 | ||||
| 0000000000000000000000000000000000000000000aaaa8888aaaa0000000000000000000000000000000000000000000000000000000007611156666111665 | ||||
| 0000000000000000000000000000000000000000000aaaaaaaaaaaa0000000000000000000000000000000000000000000000000000000007615156666651565 | ||||
| 000000000000000000000000000000000000000000aaaaaaaaaaaaaa000000000000000000000000000000000000000000000000000000007615156666116565 | ||||
| 000000000000000000000000000000000000000000aaaaaaaaaaaaaa000000000000000000000000000000000000000000000000000000007665656666655665 | ||||
| 00000000000000000000000000000000000000000aaaaaaaaaaaaaaaa00000000000000000000000000000000000000000000000000000007666666666666665 | ||||
| 00000000000000000000000000000000000000000aaaaaaaaaaaaaaaa00000000000000000000000000000000000000000000000000000007655555555555565 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007658888750000765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007658888750000765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007658888750000765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007658888750000765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007658888750000765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007658888750000765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007658888750000765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007658888750000765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007658888750000765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007658888750000765 | ||||
| 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765888875cccc765 | ||||
| 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765888875cccc765 | ||||
| 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765888875cccc765 | ||||
| 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765888875cccc765 | ||||
| 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765888875cccc765 | ||||
| 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765888875cccc765 | ||||
| 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765888875cccc765 | ||||
| 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765888875cccc765 | ||||
| 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765888875cccc765 | ||||
| 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765888875cccc765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007657777757777765 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666666666666665 | ||||
| 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007555555555555555 | ||||
|  | ||||
							
								
								
									
										
											BIN
										
									
								
								genericshmup.p8.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								genericshmup.p8.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 31 KiB | 
		Reference in New Issue
	
	Block a user