Add rough implementations of dynamite and bowling ball
This commit is contained in:
parent
9ade84c6fe
commit
3e18e38f15
27
js/game.js
27
js/game.js
@ -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];
|
||||
|
||||
@ -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]],
|
||||
|
||||
119
js/tiletypes.js
119
js/tiletypes.js
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user