Add rough implementations of dynamite and bowling ball

This commit is contained in:
Eevee (Evelyn Woods) 2020-12-14 23:25:48 -07:00
parent 9ade84c6fe
commit 3e18e38f15
3 changed files with 147 additions and 5 deletions

View File

@ -654,6 +654,10 @@ export class Level {
if (! actor.cell)
continue;
if (actor.type.on_tic) {
actor.type.on_tic(actor, this);
}
// Check this again, since an earlier pass may have caused us to start moving
if (actor.movement_cooldown > 0)
continue;
@ -1354,7 +1358,19 @@ export class Level {
this.transmute_tile(terrain, 'teleport_yellow');
}
else {
this.add_tile(new Tile(TILE_TYPES[name]), actor.cell);
let type = TILE_TYPES[name];
if (type.on_drop) {
name = type.on_drop(this, actor);
if (name) {
type = TILE_TYPES[name];
}
}
let tile = new Tile(type);
if (type.is_actor) {
tile.direction = actor.direction;
this.add_actor(tile);
}
this.add_tile(tile, actor.cell);
}
actor.toolbelt.shift();
@ -1542,6 +1558,15 @@ export class Level {
return (x >= 0 && x < this.width && y >= 0 && y < this.height);
}
cell(x, y) {
if (this.is_point_within_bounds(x, y)) {
return this.cells[y][x];
}
else {
return null;
}
}
get_neighboring_cell(cell, direction) {
let move = DIRECTIONS[direction].movement;
let goal_x = cell.x + move[0];

View File

@ -131,8 +131,9 @@ export const CC2_TILESET_LAYOUT = {
canopy: [14, 3],
// canopy xray
// TODO lit
dynamite: [0, 4],
// FIXME lit frames
dynamite_lit: [0, 4],
bomb: [5, 4],
green_bomb: [6, 4],
// TODO bomb fuse tile, ugh
@ -349,7 +350,8 @@ export const CC2_TILESET_LAYOUT = {
south: [[1, 17], [0, 17]],
west: [[5, 17], [4, 17]],
},
bowling_ball: [6, 17], // TODO also +18 when rolling
bowling_ball: [6, 17],
rolling_ball: [[6, 17], [7, 17]],
tank_yellow: {
north: [[8, 17], [9, 17]],
east: [[10, 17], [11, 17]],

View File

@ -2036,14 +2036,129 @@ const TILE_TYPES = {
is_item: true,
is_tool: true,
blocks_collision: COLLISION.block_cc1 | COLLISION.monster_solid,
// FIXME does a thing when dropped, but that isn't implemented at all yet
on_drop(level, owner) {
// FIXME not if the cell has a no sign
if (! owner.type.is_real_player) {
// Only players can activate dynamite
return;
}
return 'dynamite_lit';
},
},
dynamite_lit: {
draw_layer: DRAW_LAYERS.item,
is_actor: true,
// FIXME collision?
// FIXME kills player on touch
// FIXME inherits a copy of player's inventory!
// FIXME holds down buttons, so needs an on_arrive
// FIXME speaking of buttons, destroyed actors should on_depart
on_tic(me, level) {
// FIXME When Chip or Melinda leaves a tile with a time bomb and no no sign on it, the
// time bomb will count down for about 4.3 seconds before exploding; it does not matter
// whether the player dropped the item (e.g. if the player teleported)????
if (me.slide_mode || me.movement_cooldown)
return;
if (me.timer === undefined) {
me.timer = 86; // FIXME?? wiki just says about 4.3 seconds what
return;
}
me.timer -= 1;
if (me.timer > 0)
return;
// Kaboom! Blow up a 5x5 square
level.sfx.play_once('bomb', me.cell);
let x = me.cell.x, y = me.cell.y;
for (let dx = -2; dx <= 2; dx++) {
for (let dy = -2; dy <= 2; dy++) {
// Exclude the far corners
if (Math.abs(dx) + Math.abs(dy) >= 4)
continue;
let cell = level.cell(x + dx, y + dy);
if (! cell)
continue;
let tiles = Array.from(cell);
tiles.sort((a, b) => b.type.draw_layer - a.type.draw_layer);
let actor, terrain, removed_anything;
for (let tile of tiles) {
if (tile.type.name === 'canopy') {
// Canopy protects everything else
break;
}
if (tile.type.is_actor) {
actor = tile;
}
if (tile.type.draw_layer === 0) {
// Terrain gets transmuted afterwards
terrain = tile;
}
else {
// Everything else is destroyed
level.remove_tile(tile);
removed_anything = true;
}
}
if (actor) {
// Actors protect terrain, but floor becomes fire
if (terrain && terrain.type.name === 'floor' && terrain.wire_directions === 0 && terrain.wire_tunnel_directions === 0) {
if (actor.type.name === 'ice_block') {
level.transmute_tile(terrain, 'water');
}
else {
level.transmute_tile(terrain, 'fire');
}
}
}
else if (terrain) {
// Anything other than these babies gets blown up and turned into floor
if (!(
terrain.type.name === 'steel' || terrain.type.name === 'socket' || terrain.type.name === 'logic_gate' || terrain.type.name === 'floor'))
{
level.transmute_tile(terrain, 'floor');
removed_anything = true;
}
}
if (removed_anything) {
level.spawn_animation(cell, 'explosion');
}
}
}
},
},
bowling_ball: {
// TODO not implemented, rolls when dropped, has an inventory, yadda yadda
draw_layer: DRAW_LAYERS.item,
is_item: true,
is_tool: true,
blocks_collision: COLLISION.block_cc1 | COLLISION.monster_solid,
on_drop(level, owner) {
return 'rolling_ball';
},
},
rolling_ball: {
draw_layer: DRAW_LAYERS.actor,
is_actor: true,
has_inventory: true,
// FIXME collision...?
// FIXME do i start moving immediately when dropped, or next turn?
movement_speed: 4,
decide_movement(me, level) {
return [
me.direction,
function() {
// FIXME lol this is incredibly stupid but i have no way to react when /i/ hit
// something /else/ yet
level.transmute_tile(me, 'explosion');
return me.direction;
},
];
},
},
xray_eye: {
// TODO not implemented