Revamp the halo into an ankh

This commit is contained in:
Eevee (Evelyn Woods) 2021-03-07 19:36:48 -07:00
parent c6c904ca68
commit a36862e65b
5 changed files with 78 additions and 40 deletions

View File

@ -895,7 +895,7 @@ const TILE_ENCODING = {
is_extension: true, is_extension: true,
}, },
0xed: { 0xed: {
name: 'halo', name: 'ankh',
has_next: true, has_next: true,
is_extension: true, is_extension: true,
}, },

View File

@ -518,6 +518,7 @@ export class Level extends LevelInterface {
let n = 0; let n = 0;
let connectables = []; let connectables = [];
this.remaining_players = 0; this.remaining_players = 0;
this.ankh_tile = null;
// If there's exactly one yellow teleporter when the level loads, it cannot be picked up // If there's exactly one yellow teleporter when the level loads, it cannot be picked up
let yellow_teleporter_count = 0; let yellow_teleporter_count = 0;
this.allow_taking_yellow_teleporters = false; this.allow_taking_yellow_teleporters = false;
@ -2507,8 +2508,17 @@ export class Level extends LevelInterface {
} }
} }
kill_actor(actor, animation_name = null) { kill_actor(actor, killer, animation_name = null, sfx = null, fail_reason = null) {
// FIXME use this everywhere, fail when it's a player, move on_death here // FIXME use this everywhere, fail when it's a player, move on_death here
if (actor.type.is_real_player) {
// FIXME move death here
this.fail(fail_reason, null, actor);
return;
}
if (sfx) {
this.sfx.play_once(sfx, actor.cell);
}
if (animation_name) { if (animation_name) {
this.transmute_tile(actor, animation_name); this.transmute_tile(actor, animation_name);
} }
@ -2521,6 +2531,34 @@ export class Level extends LevelInterface {
if (this.state !== 'playing') if (this.state !== 'playing')
return; return;
if (player === null) {
player = this.player;
}
// FIXME move to kill_actor
if (player != null && this.ankh_tile && reason !== 'time') {
let cell = this.ankh_tile.cell;
let actor = cell.get_actor();
if (! actor) {
// FIXME water should still splash, etc
this.sfx.play_once('revive');
this._set_tile_prop(player, 'movement_cooldown', null);
this._set_tile_prop(player, 'movement_speed', null);
this.make_slide(player, null);
this.move_to(player, cell);
this.transmute_tile(this.ankh_tile, 'floor');
this.spawn_animation(cell, 'resurrection');
let old_tile = this.ankh_tile;
this.ankh_tile = null;
this._push_pending_undo(() => {
this.ankh_tile = old_tile;
});
return;
}
}
if (reason === 'time') { if (reason === 'time') {
this.sfx.play_once('timeup'); this.sfx.play_once('timeup');
} }
@ -2528,33 +2566,6 @@ export class Level extends LevelInterface {
this.sfx.play_once('lose'); this.sfx.play_once('lose');
} }
if (player === null) {
player = this.player;
}
if (player != null && this.take_tool_from_actor(player, 'halo')) {
this.sfx.play_once('revive');
if (reason === 'time')
{
this.pause_timer();
}
else if (killer !== null)
{
if (killer.type.is_actor || killer.type.is_item)
{
if (killer.type.on_death) {
killer.type.on_death(killer, this);
}
this.remove_tile(killer);
}
else //presumably terrain
{
this.transmute_tile(killer, 'floor');
}
}
return;
}
this._push_pending_undo(() => { this._push_pending_undo(() => {
this.fail_reason = null; this.fail_reason = null;
if (player != null) { player.fail_reason = null; } if (player != null) { player.fail_reason = null; }

View File

@ -1607,7 +1607,7 @@ const EDITOR_PALETTE = [{
'turntable_ccw', 'turntable_ccw',
'teleport_blue_exit', 'teleport_blue_exit',
'electrified_floor', 'electrified_floor',
'halo', 'ankh',
'score_5x', 'score_5x',
'boulder', 'boulder',
'glass_block', 'glass_block',

View File

@ -1293,7 +1293,8 @@ export const LL_TILESET_LAYOUT = {
xray_eye: [3, 17], xray_eye: [3, 17],
helmet: [4, 17], helmet: [4, 17],
skeleton_key: [0, 18], skeleton_key: [0, 18],
halo: [1, 18], ankh: [1, 18],
floor_ankh: [2, 18],
no_sign: [6, 18], no_sign: [6, 18],
gift_bow: [7, 18], gift_bow: [7, 18],
score_10: [0, 19], score_10: [0, 19],
@ -1418,7 +1419,7 @@ export const LL_TILESET_LAYOUT = {
__special__: 'animated', __special__: 'animated',
duration: 12, duration: 12,
cc2_duration: 16, cc2_duration: 16,
all: [[8, 21], [9, 21], [10, 21], [11, 21]], all: [[8, 22], [9, 22], [10, 22], [11, 22]],
} }
}, },
turntable_ccw: { turntable_ccw: {
@ -1428,7 +1429,7 @@ export const LL_TILESET_LAYOUT = {
__special__: 'animated', __special__: 'animated',
duration: 12, duration: 12,
cc2_duration: 16, cc2_duration: 16,
all: [[8, 22], [9, 22], [10, 22], [11, 22]], all: [[8, 21], [9, 21], [10, 21], [11, 21]],
} }
}, },
flame_jet_off: [12, 21], flame_jet_off: [12, 21],
@ -1978,6 +1979,7 @@ export const LL_TILESET_LAYOUT = {
transmogrify_flash: [[24, 26], [25, 26], [26, 26], [27, 26], [28, 26], [29, 26], [30, 26], [31, 26]], transmogrify_flash: [[24, 26], [25, 26], [26, 26], [27, 26], [28, 26], [29, 26], [30, 26], [31, 26]],
teleport_flash: [[24, 27], [25, 27], [26, 27], [27, 27]], teleport_flash: [[24, 27], [25, 27], [26, 27], [27, 27]],
puff: [[24, 28], [25, 28], [26, 28], [27, 28]], puff: [[24, 28], [25, 28], [26, 28], [27, 28]],
resurrection: [[23, 28], [22, 28], [21, 28], [20, 28]],
}; };
export const TILESET_LAYOUTS = { export const TILESET_LAYOUTS = {

View File

@ -706,7 +706,7 @@ const TILE_TYPES = {
on_arrive(me, level, other) { on_arrive(me, level, other) {
if (other.type.name === 'glass_block') { if (other.type.name === 'glass_block') {
// FIXME need a glass shatter vfx // FIXME need a glass shatter vfx
level.kill_actor(other, 'explosion'); level.kill_actor(other, me, 'explosion');
} }
}, },
}, },
@ -770,12 +770,8 @@ const TILE_TYPES = {
level.transmute_tile(me, 'water'); level.transmute_tile(me, 'water');
level.sfx.play_once('splash', me.cell); level.sfx.play_once('splash', me.cell);
} }
else if (other.type.is_real_player) {
level.fail('burned', me, other);
}
else { else {
level.transmute_tile(other, 'explosion'); level.kill_actor(other, me, 'explosion', 'bomb', 'burned');
level.sfx.play_once('bomb', me.cell);
} }
}, },
}, },
@ -2922,8 +2918,31 @@ const TILE_TYPES = {
skeleton_key: { skeleton_key: {
...COMMON_TOOL, ...COMMON_TOOL,
}, },
halo: { ankh: {
...COMMON_TOOL, ...COMMON_TOOL,
on_depart(me, level, other) {
let terrain = me.cell.get_terrain();
if (other.type.is_real_player && terrain && terrain.type.name === 'floor' &&
terrain.wire_directions === 0 && terrain.wire_tunnel_directions === 0)
{
if (level.ankh_tile) {
level.transmute_tile(level.ankh_tile, 'floor');
level.spawn_animation(level.ankh_tile, 'puff');
}
let old_tile = level.ankh_tile;
level.ankh_tile = terrain;
level._push_pending_undo(() => {
level.ankh_tile = old_tile;
});
level.transmute_tile(terrain, 'floor_ankh');
// TODO some kinda vfx + sfx
level.remove_tile(me);
}
},
},
floor_ankh: {
layer: LAYERS.terrain,
blocks_collision: COLLISION.all_but_real_player,
}, },
// Progression // Progression
@ -3246,6 +3265,12 @@ const TILE_TYPES = {
collision_mask: 0, collision_mask: 0,
ttl: 4 * 3 + 1, ttl: 4 * 3 + 1,
}, },
resurrection: {
layer: LAYERS.vfx,
is_actor: true,
collision_mask: 0,
ttl: 4 * 3 + 1,
},
// Invalid tiles that appear in some CCL levels because community level // Invalid tiles that appear in some CCL levels because community level
// designers love to make nonsense // designers love to make nonsense