Implement Boulder

Similar to a dirt block, but rolls when pushed. Boulders transfer momentum to each other. Has ice block/frame block collision. Turns into gravel in water. Spreads slime.
This commit is contained in:
Timothy Stiles 2021-02-14 18:38:56 +11:00
parent 7bcb1ac018
commit 20dad5c76a
5 changed files with 68 additions and 3 deletions

View File

@ -812,6 +812,11 @@ const TILE_ENCODING = {
name: 'spikes',
is_extension: true,
},
0xd6: {
name: 'boulder',
has_next: true,
extra_args: [arg_direction],
},
0xe0: {
name: 'gift_bow',
has_next: true,

View File

@ -1577,6 +1577,10 @@ export class Level extends LevelInterface {
move_to(actor, goal_cell, speed) {
if (actor.cell === goal_cell)
return;
if (actor.type.on_starting_move) {
actor.type.on_starting_move(actor, this);
}
let original_cell = actor.cell;
// Physically remove the actor first, so that it won't get in the way of e.g. a splash

View File

@ -1609,7 +1609,8 @@ const EDITOR_PALETTE = [{
'cracked_floor',
'cracked_ice',
'score_5x',
'spikes'
'spikes',
'boulder',
],
}];
@ -2232,6 +2233,10 @@ const EDITOR_TILE_DESCRIPTIONS = {
name: "Spikes",
desc: "Stops players (and doppelgangers) unless they have hiking boots. Everything else can pass.",
},
boulder: {
name: "Boulder",
desc: "Similar to a dirt block, but rolls when pushed. Boulders transfer momentum to each other. Has ice block/frame block collision. Turns into gravel in water. Spreads slime.",
},
};
const SPECIAL_PALETTE_ENTRIES = {

View File

@ -1064,6 +1064,7 @@ export const LL_TILESET_LAYOUT = Object.assign({}, CC2_TILESET_LAYOUT, {
cracked_ice: [7, 40],
score_5x: [10, 40],
spikes: [5, 40],
boulder: [8, 40],
});
export const TILESET_LAYOUTS = {

View File

@ -259,7 +259,7 @@ const TILE_TYPES = {
floor: {
layer: LAYERS.terrain,
on_approach(me, level, other) {
if (other.type.name === 'blob') {
if (other.type.name === 'blob' || other.type.name === 'boulder') {
// Blobs spread slime onto floor
if (other.previous_cell && other.previous_cell.has('slime')) {
level.transmute_tile(me, 'slime');
@ -830,6 +830,10 @@ const TILE_TYPES = {
level.transmute_tile(other, 'splash');
level.transmute_tile(me, 'ice');
}
else if (other.type.name === 'boulder') {
level.transmute_tile(other, 'splash');
level.transmute_tile(me, 'gravel');
}
else if (other.type.is_real_player) {
level.fail('drowned', me, other);
}
@ -1021,7 +1025,7 @@ const TILE_TYPES = {
slime: {
layer: LAYERS.terrain,
on_arrive(me, level, other) {
if (other.type.name === 'ghost' || other.type.name === 'blob') {
if (other.type.name === 'ghost' || other.type.name === 'blob' || other.type.name === 'boulder') {
// No effect
return;
}
@ -1185,6 +1189,7 @@ const TILE_TYPES = {
pushes: {
ice_block: true,
frame_block: true,
boulder: true,
},
on_bumped(me, level, other) {
// Fireballs melt ice blocks on regular floor FIXME and water!
@ -1215,6 +1220,7 @@ const TILE_TYPES = {
dirt_block: true,
ice_block: true,
frame_block: true,
boulder: true,
},
on_clone(me, original) {
me.arrows = new Set(original.arrows);
@ -1228,6 +1234,43 @@ const TILE_TYPES = {
level._set_tile_prop(me, 'arrows', new_arrows);
},
},
boulder: {
layer: LAYERS.actor,
collision_mask: COLLISION.block_cc2,
blocks_collision: COLLISION.all,
is_actor: true,
is_block: true,
can_reveal_walls: true,
pushes: {
ice_block: true,
frame_block: true,
//boulders don't push each other; instead on_bumped will chain through them
},
ignores: new Set(['fire', 'flame_jet_on', 'electrified_floor']),
can_reverse_on_railroad: true,
movement_speed: 4,
decide_movement(me, level) {
if (me.rolling) {
level._set_tile_prop(me, 'rolling', false);
return [me.direction, null];
}
else {
return null;
}
},
on_bumped(me, level, other) {
if (other.type.name === 'boulder') {
level._set_tile_prop(me, 'rolling', true);
level._set_tile_prop(me, 'direction', other.direction);
level._set_tile_prop(other, 'rolling', false);
}
},
on_starting_move(me, level) {
if (!me.rolling) {
level._set_tile_prop(me, 'rolling', true);
}
},
},
glass_block: {
layer: LAYERS.actor,
collision_mask: COLLISION.block_cc2,
@ -1244,6 +1287,7 @@ const TILE_TYPES = {
dirt_block: true,
ice_block: true,
frame_block: true,
boulder: true,
},
on_clone(me, original) {
me.arrows = new Set(original.arrows);
@ -2490,6 +2534,7 @@ const TILE_TYPES = {
ice_block: true,
frame_block: true,
circuit_block: true,
boulder: true,
},
movement_speed: 4,
decide_movement(me, level) {
@ -2641,6 +2686,7 @@ const TILE_TYPES = {
ice_block: true,
frame_block: true,
circuit_block: true,
boulder: true,
},
on_ready(me, level) {
me.current_emulatee = 0;
@ -3004,6 +3050,7 @@ const TILE_TYPES = {
ice_block: true,
frame_block: true,
circuit_block: true,
boulder: true,
},
infinite_items: {
key_green: true,
@ -3026,6 +3073,7 @@ const TILE_TYPES = {
ice_block: true,
frame_block: true,
circuit_block: true,
boulder: true,
},
infinite_items: {
key_yellow: true,
@ -3047,6 +3095,7 @@ const TILE_TYPES = {
ice_block: true,
frame_block: true,
circuit_block: true,
boulder: true,
},
infinite_items: {
key_green: true,
@ -3072,6 +3121,7 @@ const TILE_TYPES = {
ice_block: true,
frame_block: true,
circuit_block: true,
boulder: true,
},
infinite_items: {
key_yellow: true,