Consolidate some repeated tile properties

This commit is contained in:
Eevee (Evelyn Woods) 2021-03-01 14:28:56 -07:00
parent a294338080
commit 3359c21387
3 changed files with 73 additions and 202 deletions

View File

@ -95,6 +95,7 @@ export const COLLISION = {
rover: 0x1000, rover: 0x1000,
ghost: 0x8000, ghost: 0x8000,
// For a tile's COLLISION, use one of these bit combinations // For a tile's COLLISION, use one of these bit combinations
monster_general: 0x6f00, // everything but ghost and rover
monster_solid: 0x7f00, // everything but ghost monster_solid: 0x7f00, // everything but ghost
monster_any: 0xff00, // everything including ghost monster_any: 0xff00, // everything including ghost

View File

@ -1,5 +1,5 @@
import * as algorithms from './algorithms.js'; import * as algorithms from './algorithms.js';
import { DIRECTIONS, DIRECTION_ORDER, LAYERS, INPUT_BITS, TICS_PER_SECOND } from './defs.js'; import { DIRECTIONS, DIRECTION_ORDER, LAYERS, INPUT_BITS, PICKUP_PRIORITIES, TICS_PER_SECOND } from './defs.js';
import { LevelInterface } from './format-base.js'; import { LevelInterface } from './format-base.js';
import TILE_TYPES from './tiletypes.js'; import TILE_TYPES from './tiletypes.js';
@ -16,7 +16,9 @@ export class Tile {
this.movement_cooldown = 0; this.movement_cooldown = 0;
} }
if (type.has_inventory) { // Pre-seed actors who are expected to have inventories, with one
// TODO do i need this at all?
if (type.item_pickup_priority <= PICKUP_PRIORITIES.normal) {
this.keyring = {}; this.keyring = {};
this.toolbelt = []; this.toolbelt = [];
} }

View File

@ -52,7 +52,7 @@ function _define_door(key) {
return { return {
layer: LAYERS.terrain, layer: LAYERS.terrain,
// Doors can be opened by ice blocks, but not dirt blocks or monsters // Doors can be opened by ice blocks, but not dirt blocks or monsters
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover), blocks_collision: COLLISION.block_cc1 | COLLISION.monster_general,
blocks(me, level, other) { blocks(me, level, other) {
if (other.type.name === 'ghost') if (other.type.name === 'ghost')
return false; return false;
@ -73,7 +73,7 @@ function _define_gate(key) {
return { return {
layer: LAYERS.item, layer: LAYERS.item,
// Doors can be opened by ice blocks, but not dirt blocks or monsters // Doors can be opened by ice blocks, but not dirt blocks or monsters
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover), blocks_collision: COLLISION.block_cc1 | COLLISION.monster_general,
blocks(me, level, other) { blocks(me, level, other) {
if (other.type.name === 'ghost') if (other.type.name === 'ghost')
return false; return false;
@ -219,6 +219,25 @@ function pursue_player(me, level) {
} }
} }
// Chunks of properties that are shared among bunches of tiles
const COMMON_MONSTER = {
layer: LAYERS.actor,
is_actor: true,
is_monster: true,
collision_mask: COLLISION.monster_generic,
blocks_collision: COLLISION.all_but_real_player,
// Despite the name, this means we only pick up items that are always picked up
item_pickup_priority: PICKUP_PRIORITIES.always,
movement_speed: 4,
};
const COMMON_TOOL = {
layer: LAYERS.item,
is_item: true,
is_tool: true,
blocks_collision: COLLISION.block_cc1 | COLLISION.monster_general,
item_priority: PICKUP_PRIORITIES.normal,
};
const TILE_TYPES = { const TILE_TYPES = {
// Floors and walls // Floors and walls
floor: { floor: {
@ -301,7 +320,7 @@ const TILE_TYPES = {
}, },
popwall: { popwall: {
layer: LAYERS.terrain, layer: LAYERS.terrain,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover), blocks_collision: COLLISION.block_cc1 | COLLISION.monster_general,
on_ready(me, level) { on_ready(me, level) {
if (! level.compat.no_auto_convert_ccl_popwalls && if (! level.compat.no_auto_convert_ccl_popwalls &&
level.stored_level.format === 'ccl' && level.stored_level.format === 'ccl' &&
@ -364,7 +383,7 @@ const TILE_TYPES = {
}, },
fake_floor: { fake_floor: {
layer: LAYERS.terrain, layer: LAYERS.terrain,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover), blocks_collision: COLLISION.block_cc1 | COLLISION.monster_general,
on_bumped(me, level, other) { on_bumped(me, level, other) {
if (other.type.can_reveal_walls) { if (other.type.can_reveal_walls) {
level.spawn_animation(me.cell, 'puff'); level.spawn_animation(me.cell, 'puff');
@ -624,7 +643,7 @@ const TILE_TYPES = {
// Terrain // Terrain
dirt: { dirt: {
layer: LAYERS.terrain, layer: LAYERS.terrain,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover), blocks_collision: COLLISION.block_cc1 | COLLISION.monster_general,
blocks(me, level, other) { blocks(me, level, other) {
return ((other.type.name === 'player2' || other.type.name === 'doppelganger2') && return ((other.type.name === 'player2' || other.type.name === 'doppelganger2') &&
! other.has_item('hiking_boots')); ! other.has_item('hiking_boots'));
@ -641,7 +660,7 @@ const TILE_TYPES = {
}, },
gravel: { gravel: {
layer: LAYERS.terrain, layer: LAYERS.terrain,
blocks_collision: COLLISION.monster_solid & ~COLLISION.rover, blocks_collision: COLLISION.monster_general,
blocks(me, level, other) { blocks(me, level, other) {
return ((other.type.name === 'player2' || other.type.name === 'doppelganger2') && return ((other.type.name === 'player2' || other.type.name === 'doppelganger2') &&
! other.has_item('hiking_boots')); ! other.has_item('hiking_boots'));
@ -1364,7 +1383,7 @@ const TILE_TYPES = {
layer: LAYERS.item, layer: LAYERS.item,
is_chip: true, is_chip: true,
is_required_chip: true, is_required_chip: true,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover), blocks_collision: COLLISION.block_cc1 | COLLISION.monster_general,
item_priority: PICKUP_PRIORITIES.real_player, item_priority: PICKUP_PRIORITIES.real_player,
on_pickup(me, level, other) { on_pickup(me, level, other) {
level.collect_chip(); level.collect_chip();
@ -2270,13 +2289,8 @@ const TILE_TYPES = {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Critters // Critters
bug: { bug: {
layer: LAYERS.actor, ...COMMON_MONSTER,
is_actor: true,
is_monster: true,
collision_mask: COLLISION.bug, collision_mask: COLLISION.bug,
blocks_collision: COLLISION.all_but_real_player,
item_pickup_priority: PICKUP_PRIORITIES.always,
movement_speed: 4,
decide_movement(me, level) { decide_movement(me, level) {
// always try turning as left as possible, and fall back to less-left turns // always try turning as left as possible, and fall back to less-left turns
let d = DIRECTIONS[me.direction]; let d = DIRECTIONS[me.direction];
@ -2284,13 +2298,7 @@ const TILE_TYPES = {
}, },
}, },
paramecium: { paramecium: {
layer: LAYERS.actor, ...COMMON_MONSTER,
is_actor: true,
is_monster: true,
collision_mask: COLLISION.monster_generic,
blocks_collision: COLLISION.all_but_real_player,
item_pickup_priority: PICKUP_PRIORITIES.always,
movement_speed: 4,
decide_movement(me, level) { decide_movement(me, level) {
// always try turning as right as possible, and fall back to less-right turns // always try turning as right as possible, and fall back to less-right turns
let d = DIRECTIONS[me.direction]; let d = DIRECTIONS[me.direction];
@ -2298,13 +2306,7 @@ const TILE_TYPES = {
}, },
}, },
ball: { ball: {
layer: LAYERS.actor, ...COMMON_MONSTER,
is_actor: true,
is_monster: true,
collision_mask: COLLISION.monster_generic,
blocks_collision: COLLISION.all_but_real_player,
item_pickup_priority: PICKUP_PRIORITIES.always,
movement_speed: 4,
decide_movement(me, level) { decide_movement(me, level) {
// preserve current direction; if that doesn't work, bounce back the way we came // preserve current direction; if that doesn't work, bounce back the way we came
let d = DIRECTIONS[me.direction]; let d = DIRECTIONS[me.direction];
@ -2312,13 +2314,7 @@ const TILE_TYPES = {
}, },
}, },
walker: { walker: {
layer: LAYERS.actor, ...COMMON_MONSTER,
is_actor: true,
is_monster: true,
collision_mask: COLLISION.monster_generic,
blocks_collision: COLLISION.all_but_real_player,
item_pickup_priority: PICKUP_PRIORITIES.always,
movement_speed: 4,
decide_movement(me, level) { decide_movement(me, level) {
// preserve current direction; if that doesn't work, pick a random direction, even the // preserve current direction; if that doesn't work, pick a random direction, even the
// one we failed to move in (but ONLY then; important for RNG sync) // one we failed to move in (but ONLY then; important for RNG sync)
@ -2336,13 +2332,7 @@ const TILE_TYPES = {
}, },
}, },
tank_blue: { tank_blue: {
layer: LAYERS.actor, ...COMMON_MONSTER,
is_actor: true,
is_monster: true,
collision_mask: COLLISION.monster_generic,
blocks_collision: COLLISION.all_but_real_player,
item_pickup_priority: PICKUP_PRIORITIES.always,
movement_speed: 4,
decide_movement(me, level) { decide_movement(me, level) {
// always keep moving forward, but reverse if the flag is set // always keep moving forward, but reverse if the flag is set
let direction = me.direction; let direction = me.direction;
@ -2359,12 +2349,7 @@ const TILE_TYPES = {
} }
}, },
tank_yellow: { tank_yellow: {
layer: LAYERS.actor, ...COMMON_MONSTER,
is_actor: true,
is_monster: true,
collision_mask: COLLISION.monster_generic,
blocks_collision: COLLISION.all_but_real_player,
item_pickup_priority: PICKUP_PRIORITIES.always,
pushes: { pushes: {
dirt_block: true, dirt_block: true,
ice_block: true, ice_block: true,
@ -2373,7 +2358,6 @@ const TILE_TYPES = {
boulder: true, boulder: true,
glass_block: true, glass_block: true,
}, },
movement_speed: 4,
decide_movement(me, level) { decide_movement(me, level) {
if (me.pending_decision) { if (me.pending_decision) {
let decision = me.pending_decision; let decision = me.pending_decision;
@ -2387,12 +2371,7 @@ const TILE_TYPES = {
} }
}, },
blob: { blob: {
layer: LAYERS.actor, ...COMMON_MONSTER,
is_actor: true,
is_monster: true,
collision_mask: COLLISION.monster_generic,
blocks_collision: COLLISION.all_but_real_player,
item_pickup_priority: PICKUP_PRIORITIES.always,
movement_speed: 8, movement_speed: 8,
decide_movement(me, level) { decide_movement(me, level) {
// move completely at random // move completely at random
@ -2401,13 +2380,7 @@ const TILE_TYPES = {
}, },
}, },
teeth: { teeth: {
layer: LAYERS.actor, ...COMMON_MONSTER,
is_actor: true,
is_monster: true,
collision_mask: COLLISION.monster_generic,
blocks_collision: COLLISION.all_but_real_player,
item_pickup_priority: PICKUP_PRIORITIES.always,
movement_speed: 4,
movement_parity: 2, movement_parity: 2,
decide_movement(me, level) { decide_movement(me, level) {
let preference = pursue_player(me, level); let preference = pursue_player(me, level);
@ -2421,13 +2394,7 @@ const TILE_TYPES = {
}, },
}, },
teeth_timid: { teeth_timid: {
layer: LAYERS.actor, ...COMMON_MONSTER,
is_actor: true,
is_monster: true,
collision_mask: COLLISION.monster_generic,
blocks_collision: COLLISION.all_but_real_player,
item_pickup_priority: PICKUP_PRIORITIES.always,
movement_speed: 4,
movement_parity: 2, movement_parity: 2,
decide_movement(me, level) { decide_movement(me, level) {
let preference = pursue_player(me, level); let preference = pursue_player(me, level);
@ -2441,13 +2408,8 @@ const TILE_TYPES = {
}, },
}, },
fireball: { fireball: {
layer: LAYERS.actor, ...COMMON_MONSTER,
is_actor: true,
is_monster: true,
collision_mask: COLLISION.fireball, collision_mask: COLLISION.fireball,
blocks_collision: COLLISION.all_but_real_player,
item_pickup_priority: PICKUP_PRIORITIES.always,
movement_speed: 4,
ignores: new Set(['fire', 'flame_jet_on']), ignores: new Set(['fire', 'flame_jet_on']),
decide_movement(me, level) { decide_movement(me, level) {
// turn right: preserve current direction; if that doesn't work, turn right, then left, // turn right: preserve current direction; if that doesn't work, turn right, then left,
@ -2457,13 +2419,7 @@ const TILE_TYPES = {
}, },
}, },
glider: { glider: {
layer: LAYERS.actor, ...COMMON_MONSTER,
is_actor: true,
is_monster: true,
collision_mask: COLLISION.monster_generic,
blocks_collision: COLLISION.all_but_real_player,
item_pickup_priority: PICKUP_PRIORITIES.always,
movement_speed: 4,
ignores: new Set(['water', 'turtle']), // doesn't cause turtles to disappear ignores: new Set(['water', 'turtle']), // doesn't cause turtles to disappear
decide_movement(me, level) { decide_movement(me, level) {
// turn left: preserve current direction; if that doesn't work, turn left, then right, // turn left: preserve current direction; if that doesn't work, turn left, then right,
@ -2473,13 +2429,9 @@ const TILE_TYPES = {
}, },
}, },
ghost: { ghost: {
layer: LAYERS.actor, ...COMMON_MONSTER,
is_actor: true,
is_monster: true,
collision_mask: COLLISION.ghost, collision_mask: COLLISION.ghost,
blocks_collision: COLLISION.all_but_real_player,
item_pickup_priority: PICKUP_PRIORITIES.normal, item_pickup_priority: PICKUP_PRIORITIES.normal,
has_inventory: true,
ignores: new Set([ ignores: new Set([
'bomb', 'green_bomb', 'bomb', 'green_bomb',
'water', 'water',
@ -2489,7 +2441,6 @@ const TILE_TYPES = {
'popwall', 'swivel_nw', 'swivel_ne', 'swivel_se', 'swivel_sw', 'popwall', 'swivel_nw', 'swivel_ne', 'swivel_se', 'swivel_sw',
'hole', 'cracked_floor', 'hole', 'cracked_floor',
]), ]),
movement_speed: 4,
// TODO ignores /most/ walls. collision is basically completely different. has a regular inventory, except red key. good grief // TODO ignores /most/ walls. collision is basically completely different. has a regular inventory, except red key. good grief
decide_movement(me, level) { decide_movement(me, level) {
// turn left: preserve current direction; if that doesn't work, turn left, then right, // turn left: preserve current direction; if that doesn't work, turn left, then right,
@ -2503,23 +2454,13 @@ const TILE_TYPES = {
}, },
}, },
floor_mimic: { floor_mimic: {
layer: LAYERS.actor, ...COMMON_MONSTER,
is_actor: true,
is_monster: true,
collision_mask: COLLISION.monster_generic,
blocks_collision: COLLISION.all_but_real_player,
item_pickup_priority: PICKUP_PRIORITIES.always,
movement_speed: 4,
movement_parity: 4, movement_parity: 4,
decide_movement: pursue_player, decide_movement: pursue_player,
}, },
rover: { rover: {
layer: LAYERS.actor, ...COMMON_MONSTER,
is_actor: true,
is_monster: true,
has_inventory: true,
collision_mask: COLLISION.rover, collision_mask: COLLISION.rover,
blocks_collision: COLLISION.all_but_real_player,
item_pickup_priority: PICKUP_PRIORITIES.normal, item_pickup_priority: PICKUP_PRIORITIES.normal,
can_reveal_walls: true, can_reveal_walls: true,
movement_speed: 8, movement_speed: 8,
@ -2582,33 +2523,25 @@ const TILE_TYPES = {
is_item: true, is_item: true,
is_key: true, is_key: true,
// FIXME ok this is ghastly // FIXME ok this is ghastly
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover), blocks_collision: COLLISION.block_cc1 | COLLISION.monster_general,
item_priority: PICKUP_PRIORITIES.normal, item_priority: PICKUP_PRIORITIES.normal,
}, },
key_green: { key_green: {
layer: LAYERS.item, layer: LAYERS.item,
is_item: true, is_item: true,
is_key: true, is_key: true,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover), blocks_collision: COLLISION.block_cc1 | COLLISION.monster_general,
item_priority: PICKUP_PRIORITIES.normal, item_priority: PICKUP_PRIORITIES.normal,
}, },
// Boots // Boots
// TODO note: ms allows blocks to pass over tools // TODO note: ms allows blocks to pass over tools
cleats: { cleats: {
layer: LAYERS.item, ...COMMON_TOOL,
is_item: true,
is_tool: true,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover),
item_priority: PICKUP_PRIORITIES.normal,
item_ignores: new Set(['ice', 'ice_nw', 'ice_ne', 'ice_sw', 'ice_se', ]), item_ignores: new Set(['ice', 'ice_nw', 'ice_ne', 'ice_sw', 'ice_se', ]),
item_slide_ignores: new Set(['cracked_ice']), item_slide_ignores: new Set(['cracked_ice']),
}, },
suction_boots: { suction_boots: {
layer: LAYERS.item, ...COMMON_TOOL,
is_item: true,
is_tool: true,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover),
item_priority: PICKUP_PRIORITIES.normal,
item_ignores: new Set([ item_ignores: new Set([
'force_floor_n', 'force_floor_n',
'force_floor_s', 'force_floor_s',
@ -2618,39 +2551,23 @@ const TILE_TYPES = {
]), ]),
}, },
fire_boots: { fire_boots: {
layer: LAYERS.item, ...COMMON_TOOL,
is_item: true,
is_tool: true,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover),
item_priority: PICKUP_PRIORITIES.normal,
// Note that these do NOT ignore fire because of the ghost interaction // Note that these do NOT ignore fire because of the ghost interaction
// XXX starting to wonder if this is even useful really // XXX starting to wonder if this is even useful really
item_ignores: new Set(['flame_jet_on']), item_ignores: new Set(['flame_jet_on']),
}, },
flippers: { flippers: {
layer: LAYERS.item, ...COMMON_TOOL,
is_item: true,
is_tool: true,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover),
item_priority: PICKUP_PRIORITIES.normal,
item_ignores: new Set(['water']), item_ignores: new Set(['water']),
}, },
hiking_boots: { hiking_boots: {
layer: LAYERS.item, ...COMMON_TOOL,
is_item: true,
is_tool: true,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover),
item_priority: PICKUP_PRIORITIES.normal,
item_ignores: new Set(['sand']), item_ignores: new Set(['sand']),
// FIXME uhh these "ignore" that dirt and gravel block us, but they don't ignore the on_arrive, so, uhhhh // FIXME uhh these "ignore" that dirt and gravel block us, but they don't ignore the on_arrive, so, uhhhh
}, },
// Other tools // Other tools
dynamite: { dynamite: {
layer: LAYERS.item, ...COMMON_TOOL,
is_item: true,
is_tool: true,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover),
item_priority: PICKUP_PRIORITIES.normal,
on_depart(me, level, other) { on_depart(me, level, other) {
if (other.type.is_real_player && ! me.cell.get_item_mod()) { if (other.type.is_real_player && ! me.cell.get_item_mod()) {
level._set_tile_prop(me, 'timer', 85); // FIXME?? wiki just says about 4.3 seconds what level._set_tile_prop(me, 'timer', 85); // FIXME?? wiki just says about 4.3 seconds what
@ -2775,11 +2692,7 @@ const TILE_TYPES = {
}, },
}, },
bowling_ball: { bowling_ball: {
layer: LAYERS.item, ...COMMON_TOOL,
is_item: true,
is_tool: true,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover),
item_priority: PICKUP_PRIORITIES.normal,
on_drop(level) { on_drop(level) {
return 'rolling_ball'; return 'rolling_ball';
}, },
@ -2788,7 +2701,6 @@ const TILE_TYPES = {
layer: LAYERS.actor, layer: LAYERS.actor,
is_actor: true, is_actor: true,
is_monster: true, is_monster: true,
has_inventory: true,
can_reveal_walls: true, can_reveal_walls: true,
collision_mask: COLLISION.bowling_ball, collision_mask: COLLISION.bowling_ball,
item_pickup_priority: PICKUP_PRIORITIES.normal, item_pickup_priority: PICKUP_PRIORITIES.normal,
@ -2833,75 +2745,35 @@ const TILE_TYPES = {
}, },
}, },
xray_eye: { xray_eye: {
layer: LAYERS.item, ...COMMON_TOOL,
is_item: true,
is_tool: true,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover),
item_priority: PICKUP_PRIORITIES.normal,
}, },
helmet: { helmet: {
layer: LAYERS.item, ...COMMON_TOOL,
is_item: true,
is_tool: true,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover),
item_priority: PICKUP_PRIORITIES.normal,
}, },
railroad_sign: { railroad_sign: {
layer: LAYERS.item, ...COMMON_TOOL,
is_item: true,
is_tool: true,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover),
item_priority: PICKUP_PRIORITIES.normal,
}, },
foil: { foil: {
layer: LAYERS.item, ...COMMON_TOOL,
is_item: true,
is_tool: true,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover),
item_priority: PICKUP_PRIORITIES.normal,
}, },
lightning_bolt: { lightning_bolt: {
layer: LAYERS.item, ...COMMON_TOOL,
is_item: true,
is_tool: true,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover),
item_ignores: new Set(['electrified_floor']), item_ignores: new Set(['electrified_floor']),
item_priority: PICKUP_PRIORITIES.normal,
}, },
speed_boots: { speed_boots: {
layer: LAYERS.item, ...COMMON_TOOL,
is_item: true,
is_tool: true,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover),
item_priority: PICKUP_PRIORITIES.normal,
}, },
bribe: { bribe: {
layer: LAYERS.item, ...COMMON_TOOL,
is_item: true,
is_tool: true,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover),
item_priority: PICKUP_PRIORITIES.normal,
}, },
hook: { hook: {
layer: LAYERS.item, ...COMMON_TOOL,
is_item: true,
is_tool: true,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover),
item_priority: PICKUP_PRIORITIES.normal,
}, },
skeleton_key: { skeleton_key: {
layer: LAYERS.item, ...COMMON_TOOL,
is_item: true,
is_tool: true,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover),
item_priority: PICKUP_PRIORITIES.normal,
}, },
halo: { halo: {
layer: LAYERS.item, ...COMMON_TOOL,
is_item: true,
is_tool: true,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover),
item_priority: PICKUP_PRIORITIES.normal,
}, },
// Progression // Progression
@ -2913,7 +2785,6 @@ const TILE_TYPES = {
collision_mask: COLLISION.real_player1, collision_mask: COLLISION.real_player1,
blocks_collision: COLLISION.real_player, blocks_collision: COLLISION.real_player,
item_pickup_priority: PICKUP_PRIORITIES.real_player, item_pickup_priority: PICKUP_PRIORITIES.real_player,
has_inventory: true,
can_reveal_walls: true, can_reveal_walls: true,
movement_speed: 4, movement_speed: 4,
pushes: { pushes: {
@ -2937,7 +2808,6 @@ const TILE_TYPES = {
collision_mask: COLLISION.real_player2, collision_mask: COLLISION.real_player2,
blocks_collision: COLLISION.real_player, blocks_collision: COLLISION.real_player,
item_pickup_priority: PICKUP_PRIORITIES.real_player, item_pickup_priority: PICKUP_PRIORITIES.real_player,
has_inventory: true,
can_reveal_walls: true, can_reveal_walls: true,
movement_speed: 4, movement_speed: 4,
ignores: new Set(['ice', 'ice_nw', 'ice_ne', 'ice_sw', 'ice_se', 'cracked_ice']), ignores: new Set(['ice', 'ice_nw', 'ice_ne', 'ice_sw', 'ice_se', 'cracked_ice']),
@ -2962,7 +2832,6 @@ const TILE_TYPES = {
collision_mask: COLLISION.doppel1, collision_mask: COLLISION.doppel1,
blocks_collision: COLLISION.all_but_real_player, blocks_collision: COLLISION.all_but_real_player,
item_pickup_priority: PICKUP_PRIORITIES.player, item_pickup_priority: PICKUP_PRIORITIES.player,
has_inventory: true,
can_reveal_walls: true, // XXX i think? can_reveal_walls: true, // XXX i think?
movement_speed: 4, movement_speed: 4,
pushes: { pushes: {
@ -2989,7 +2858,6 @@ const TILE_TYPES = {
collision_mask: COLLISION.doppel2, collision_mask: COLLISION.doppel2,
blocks_collision: COLLISION.all_but_real_player, blocks_collision: COLLISION.all_but_real_player,
item_pickup_priority: PICKUP_PRIORITIES.player, item_pickup_priority: PICKUP_PRIORITIES.player,
has_inventory: true,
can_reveal_walls: true, // XXX i think? can_reveal_walls: true, // XXX i think?
movement_speed: 4, movement_speed: 4,
ignores: new Set(['ice', 'ice_nw', 'ice_ne', 'ice_sw', 'ice_se', 'cracked_ice']), ignores: new Set(['ice', 'ice_nw', 'ice_ne', 'ice_sw', 'ice_se', 'cracked_ice']),
@ -3013,7 +2881,7 @@ const TILE_TYPES = {
layer: LAYERS.item, layer: LAYERS.item,
is_chip: true, is_chip: true,
is_required_chip: true, is_required_chip: true,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover), blocks_collision: COLLISION.block_cc1 | COLLISION.monster_general,
item_priority: PICKUP_PRIORITIES.real_player, item_priority: PICKUP_PRIORITIES.real_player,
on_pickup(me, level, other) { on_pickup(me, level, other) {
level.collect_chip(); level.collect_chip();
@ -3023,7 +2891,7 @@ const TILE_TYPES = {
chip_extra: { chip_extra: {
layer: LAYERS.item, layer: LAYERS.item,
is_chip: true, is_chip: true,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover), blocks_collision: COLLISION.block_cc1 | COLLISION.monster_general,
item_priority: PICKUP_PRIORITIES.real_player, item_priority: PICKUP_PRIORITIES.real_player,
on_pickup(me, level, other) { on_pickup(me, level, other) {
level.collect_chip(); level.collect_chip();
@ -3034,7 +2902,7 @@ const TILE_TYPES = {
// actually add to the player's bonus // actually add to the player's bonus
score_10: { score_10: {
layer: LAYERS.item, layer: LAYERS.item,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover), blocks_collision: COLLISION.block_cc1 | COLLISION.monster_general,
item_priority: PICKUP_PRIORITIES.normal, item_priority: PICKUP_PRIORITIES.normal,
on_pickup(me, level, other) { on_pickup(me, level, other) {
if (other.type.name === 'ghost') if (other.type.name === 'ghost')
@ -3048,7 +2916,7 @@ const TILE_TYPES = {
}, },
score_100: { score_100: {
layer: LAYERS.item, layer: LAYERS.item,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover), blocks_collision: COLLISION.block_cc1 | COLLISION.monster_general,
item_priority: PICKUP_PRIORITIES.normal, item_priority: PICKUP_PRIORITIES.normal,
on_pickup(me, level, other) { on_pickup(me, level, other) {
if (other.type.name === 'ghost') if (other.type.name === 'ghost')
@ -3062,7 +2930,7 @@ const TILE_TYPES = {
}, },
score_1000: { score_1000: {
layer: LAYERS.item, layer: LAYERS.item,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover), blocks_collision: COLLISION.block_cc1 | COLLISION.monster_general,
item_priority: PICKUP_PRIORITIES.normal, item_priority: PICKUP_PRIORITIES.normal,
on_pickup(me, level, other) { on_pickup(me, level, other) {
if (other.type.name === 'ghost') if (other.type.name === 'ghost')
@ -3076,7 +2944,7 @@ const TILE_TYPES = {
}, },
score_2x: { score_2x: {
layer: LAYERS.item, layer: LAYERS.item,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover), blocks_collision: COLLISION.block_cc1 | COLLISION.monster_general,
item_priority: PICKUP_PRIORITIES.normal, item_priority: PICKUP_PRIORITIES.normal,
on_pickup(me, level, other) { on_pickup(me, level, other) {
if (other.type.name === 'ghost') if (other.type.name === 'ghost')
@ -3090,7 +2958,7 @@ const TILE_TYPES = {
}, },
score_5x: { score_5x: {
layer: LAYERS.item, layer: LAYERS.item,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover), blocks_collision: COLLISION.block_cc1 | COLLISION.monster_general,
item_priority: PICKUP_PRIORITIES.normal, item_priority: PICKUP_PRIORITIES.normal,
on_pickup(me, level, other) { on_pickup(me, level, other) {
if (other.type.name === 'ghost') if (other.type.name === 'ghost')
@ -3113,7 +2981,7 @@ const TILE_TYPES = {
}, },
socket: { socket: {
layer: LAYERS.terrain, layer: LAYERS.terrain,
blocks_collision: COLLISION.block_cc1 | (COLLISION.monster_solid & ~COLLISION.rover), blocks_collision: COLLISION.block_cc1 | COLLISION.monster_general,
blocks(me, level, other) { blocks(me, level, other) {
return ! (other.type.name === 'ghost' || level.chips_remaining <= 0); return ! (other.type.name === 'ghost' || level.chips_remaining <= 0);
}, },
@ -3127,7 +2995,7 @@ const TILE_TYPES = {
}, },
exit: { exit: {
layer: LAYERS.terrain, layer: LAYERS.terrain,
blocks_collision: COLLISION.block_cc1 | COLLISION.monster_solid & ~COLLISION.rover, blocks_collision: COLLISION.block_cc1 | COLLISION.monster_general,
on_arrive(me, level, other) { on_arrive(me, level, other) {
if (other.type.is_real_player) { if (other.type.is_real_player) {
level.remaining_players -= 1; level.remaining_players -= 1;