diff --git a/js/format-c2g.js b/js/format-c2g.js index e03d9a2..4a4bdf5 100644 --- a/js/format-c2g.js +++ b/js/format-c2g.js @@ -820,6 +820,11 @@ const TILE_ENCODING = { has_next: true, extra_args: [arg_direction], }, + 0xd7: { + name: 'item_lock', + has_next: true, + is_extension: true, + }, 0xe0: { name: 'gift_bow', has_next: true, diff --git a/js/game.js b/js/game.js index 1a83a59..3c6d65e 100644 --- a/js/game.js +++ b/js/game.js @@ -2646,9 +2646,9 @@ export class Level extends LevelInterface { return true; } - take_key_from_actor(actor, name) { + take_key_from_actor(actor, name, ignore_infinity = false) { if (actor.keyring && (actor.keyring[name] ?? 0) > 0) { - if (actor.type.infinite_items && actor.type.infinite_items[name]) { + if (!ignore_infinity && actor.type.infinite_items && actor.type.infinite_items[name]) { // Some items can't be taken away normally, by which I mean, green or yellow keys return true; } diff --git a/js/main-editor.js b/js/main-editor.js index 07a03fb..08b03f9 100644 --- a/js/main-editor.js +++ b/js/main-editor.js @@ -1607,6 +1607,7 @@ const EDITOR_PALETTE = [{ 'turntable_ccw', 'electrified_floor', 'halo', + 'item_lock', 'score_5x', 'boulder', 'logic_gate/diode', @@ -2242,6 +2243,10 @@ const EDITOR_TILE_DESCRIPTIONS = { 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.", }, + item_lock: { + name: "Item Lock", + desc: "When placed atop an item, you must have that item to enter the tile. When you do, pay the item and destroy the item lock. Also can be placed on top of a bonus, and you must pay that amount of bonus to enter.", + }, }; const SPECIAL_PALETTE_ENTRIES = { diff --git a/js/tileset.js b/js/tileset.js index 4ed4477..9abe4b6 100644 --- a/js/tileset.js +++ b/js/tileset.js @@ -1071,6 +1071,7 @@ export const LL_TILESET_LAYOUT = Object.assign({}, CC2_TILESET_LAYOUT, { score_5x: [10, 40], spikes: [5, 40], boulder: [8, 40], + item_lock: [12, 43], }); export const TILESET_LAYOUTS = { diff --git a/js/tiletypes.js b/js/tiletypes.js index c5f8949..e8d7eae 100644 --- a/js/tiletypes.js +++ b/js/tiletypes.js @@ -1171,6 +1171,60 @@ const TILE_TYPES = { layer: LAYERS.item_mod, item_modifier: 'pickup', }, + item_lock: { + layer: LAYERS.item_mod, + item_modifier: 'ignore', + blocks(me, level, other) { + let item = me.cell.get_item(); + if (item === null) { + return false; + } + if (item.type.name == 'score_10') { + return !(other.type.is_real_player && level.bonus_points >= 10); + } + else if (item.type.name == 'score_100') { + return !(other.type.is_real_player && level.bonus_points >= 100); + } + else if (item.type.name == 'score_1000') { + return !(other.type.is_real_player && level.bonus_points >= 1000); + } + else if (item.type.name == 'score_2x') { + return !(other.type.is_real_player && level.bonus_points >= 1); + } + else if (item.type.name == 'score_5x') { + return !(other.type.is_real_player && level.bonus_points >= 1); + } + return !other.has_item(item.type.name); + }, + on_arrive(me, level, other) { + let item = me.cell.get_item(); + if (item === null) { + return; + } + if (item.type.name == 'score_10') { + level.adjust_bonus(-10); + } + else if (item.type.name == 'score_100') { + level.adjust_bonus(-100); + } + else if (item.type.name == 'score_1000') { + level.adjust_bonus(-1000); + } + else if (item.type.name == 'score_2x') { + level.adjust_bonus(0, 1/2); + } + else if (item.type.name == 'score_5x') { + level.adjust_bonus(0, 1/5); + } + else { + level.take_key_from_actor(other, item.type.name, true) || level.take_tool_from_actor(other, item.type.name); + } + level.sfx.play_once('door', me.cell); + level.spawn_animation(me.cell, 'puff'); + level.remove_tile(me); + level.remove_tile(item); + }, + }, // Mechanisms dirt_block: { diff --git a/tileset-lexy.png b/tileset-lexy.png index 82152a7..8083fcc 100644 Binary files a/tileset-lexy.png and b/tileset-lexy.png differ