Partially consolidate slide overriding on force floors vs teleports
This commit is contained in:
parent
e45a580d1a
commit
8efa3a572a
88
js/game.js
88
js/game.js
@ -658,7 +658,7 @@ export class Level extends LevelInterface {
|
|||||||
// not in an un-overrideable slide
|
// not in an un-overrideable slide
|
||||||
return this.player.movement_cooldown === 0 &&
|
return this.player.movement_cooldown === 0 &&
|
||||||
(this.player.slide_mode === null || (
|
(this.player.slide_mode === null || (
|
||||||
this.player.slide_mode === 'force' && this.player.last_move_was_force));
|
this.player.slide_mode === 'force' && this.player.can_override_slide));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Randomness -------------------------------------------------------------------------------------
|
// Randomness -------------------------------------------------------------------------------------
|
||||||
@ -1297,10 +1297,7 @@ export class Level extends LevelInterface {
|
|||||||
// as an override.
|
// as an override.
|
||||||
let terrain = actor.cell.get_terrain();
|
let terrain = actor.cell.get_terrain();
|
||||||
let may_move = ! forced_only && (
|
let may_move = ! forced_only && (
|
||||||
! actor.slide_mode ||
|
! actor.slide_mode || (actor.can_override_slide && terrain.type.allow_player_override));
|
||||||
(actor.slide_mode === 'force' && actor.last_move_was_force) ||
|
|
||||||
((actor.slide_mode === 'teleport' || actor.slide_mode === 'teleport-forever') &&
|
|
||||||
actor.cell.get_terrain().type.teleport_allow_override));
|
|
||||||
let [dir1, dir2] = this._extract_player_directions(input);
|
let [dir1, dir2] = this._extract_player_directions(input);
|
||||||
|
|
||||||
// Check for special player actions, which can only happen at decision time. Dropping can
|
// Check for special player actions, which can only happen at decision time. Dropping can
|
||||||
@ -1333,7 +1330,7 @@ export class Level extends LevelInterface {
|
|||||||
actor.decision = actor.direction;
|
actor.decision = actor.direction;
|
||||||
|
|
||||||
if (actor.slide_mode === 'force') {
|
if (actor.slide_mode === 'force') {
|
||||||
this._set_tile_prop(actor, 'last_move_was_force', true);
|
this._set_tile_prop(actor, 'can_override_slide', true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (dir1 === null || forced_only) {
|
else if (dir1 === null || forced_only) {
|
||||||
@ -1397,12 +1394,12 @@ export class Level extends LevelInterface {
|
|||||||
// If we're overriding a force floor but the direction we're moving in is blocked, this
|
// If we're overriding a force floor but the direction we're moving in is blocked, this
|
||||||
// counts as a forced move (but only under the CC2 behavior of instant bonking)
|
// counts as a forced move (but only under the CC2 behavior of instant bonking)
|
||||||
if (actor.slide_mode === 'force' && ! open && ! this.compat.bonking_isnt_instant) {
|
if (actor.slide_mode === 'force' && ! open && ! this.compat.bonking_isnt_instant) {
|
||||||
this._set_tile_prop(actor, 'last_move_was_force', true);
|
this._set_tile_prop(actor, 'can_override_slide', true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Otherwise this is 100% a conscious move so we lose our override power next tic
|
// Otherwise this is 100% a conscious move so we lose our override power next tic
|
||||||
// TODO how does this interact with teleports
|
// TODO how does this interact with teleports
|
||||||
this._set_tile_prop(actor, 'last_move_was_force', false);
|
this._set_tile_prop(actor, 'can_override_slide', false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1611,18 +1608,20 @@ export class Level extends LevelInterface {
|
|||||||
if (tile._trying_to_push)
|
if (tile._trying_to_push)
|
||||||
return false;
|
return false;
|
||||||
if (push_mode === 'bump' || push_mode === 'slap') {
|
if (push_mode === 'bump' || push_mode === 'slap') {
|
||||||
// FIXME this doesn't take railroad curves into account, e.g. it thinks a
|
if (tile.movement_cooldown > 0)
|
||||||
// rover can't push a block through a curve
|
|
||||||
if (tile.movement_cooldown > 0 ||
|
|
||||||
! this.check_movement(tile, tile.cell, direction, push_mode))
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
else if (push_mode === 'slap') {
|
let redirected_direction = tile.cell.redirect_exit(tile, direction);
|
||||||
|
if (! this.check_movement(tile, tile.cell, redirected_direction, push_mode))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (push_mode === 'slap') {
|
||||||
if (actor === this.player) {
|
if (actor === this.player) {
|
||||||
this._set_tile_prop(actor, 'is_pushing', true);
|
this._set_tile_prop(actor, 'is_pushing', true);
|
||||||
this.sfx.play_once('push');
|
this.sfx.play_once('push');
|
||||||
}
|
}
|
||||||
|
// FIXME we get here for monsters in lynx mode! check this is actually
|
||||||
|
// possible
|
||||||
tile.decision = direction;
|
tile.decision = direction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2026,17 +2025,15 @@ export class Level extends LevelInterface {
|
|||||||
// other actors cannot. (Normally, a teleport slide ends after one decision phase.)
|
// other actors cannot. (Normally, a teleport slide ends after one decision phase.)
|
||||||
// XXX this is useful when the exit is briefly blocked, but it can also get monsters
|
// XXX this is useful when the exit is briefly blocked, but it can also get monsters
|
||||||
// stuck forever :(
|
// stuck forever :(
|
||||||
|
// XXX kind of repeating myself here, there must be a more natural approach
|
||||||
this.make_slide(actor, 'teleport-forever');
|
this.make_slide(actor, 'teleport-forever');
|
||||||
|
if (actor.type.is_real_player && teleporter.type.allow_player_override) {
|
||||||
|
this._set_tile_prop(actor, 'can_override_slide', true);
|
||||||
|
}
|
||||||
// Also, there's no sound and whatnot, so everything else is skipped outright.
|
// Also, there's no sound and whatnot, so everything else is skipped outright.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Explicitly set us as teleport sliding, since in some very obscure cases (auto-dropping a
|
|
||||||
// yellow teleporter because you picked up an item with a full inventory and immediately
|
|
||||||
// teleporting through it) it may not have been applied
|
|
||||||
this.make_slide(actor, 'teleport');
|
|
||||||
|
|
||||||
let success = false;
|
|
||||||
let dest, direction;
|
let dest, direction;
|
||||||
for ([dest, direction] of teleporter.type.teleport_dest_order(teleporter, this, actor)) {
|
for ([dest, direction] of teleporter.type.teleport_dest_order(teleporter, this, actor)) {
|
||||||
// Teleporters already containing an actor are blocked and unusable
|
// Teleporters already containing an actor are blocked and unusable
|
||||||
@ -2046,29 +2043,8 @@ export class Level extends LevelInterface {
|
|||||||
|
|
||||||
// XXX lynx treats this as a slide and does it in a pass in the main loop
|
// XXX lynx treats this as a slide and does it in a pass in the main loop
|
||||||
|
|
||||||
// FIXME bleugh hardcode
|
if (dest === teleporter &&
|
||||||
if (dest === teleporter && teleporter.type.name === 'teleport_yellow') {
|
teleporter.type.item_priority !== undefined &&
|
||||||
break;
|
|
||||||
}
|
|
||||||
// Note that this uses 'bump' even for players; it would be very bad if we could
|
|
||||||
// initiate movement in this pass (in Lexy rules, anyway), because we might try to push
|
|
||||||
// something that's still waiting to teleport itself!
|
|
||||||
// XXX is this correct? it does mean you won't try to teleport to a teleporter that's
|
|
||||||
// "blocked" by a block that won't be there anyway by the time you try to move, but that
|
|
||||||
// seems very obscure and i haven't run into a case with it yet. offhand i don't think
|
|
||||||
// it can even come up under cc2 rules, since teleporting is done after an actor cools
|
|
||||||
// down and before the next actor even gets a chance to act
|
|
||||||
if (this.check_movement(actor, dest.cell, direction, 'bump')) {
|
|
||||||
success = true;
|
|
||||||
// Sound plays from the origin cell simply because that's where the sfx player
|
|
||||||
// thinks the player is currently; position isn't updated til next turn
|
|
||||||
this.sfx.play_once('teleport', teleporter.cell);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! success) {
|
|
||||||
if (teleporter.type.item_priority !== undefined &&
|
|
||||||
teleporter.type.item_priority >= actor.type.item_pickup_priority &&
|
teleporter.type.item_priority >= actor.type.item_pickup_priority &&
|
||||||
this.allow_taking_yellow_teleporters)
|
this.allow_taking_yellow_teleporters)
|
||||||
{
|
{
|
||||||
@ -2080,6 +2056,30 @@ export class Level extends LevelInterface {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note that this uses 'bump' even for players; it would be very bad if we could
|
||||||
|
// initiate movement in this pass (in Lexy rules, anyway), because we might try to push
|
||||||
|
// something that's still waiting to teleport itself!
|
||||||
|
// XXX is this correct? it does mean you won't try to teleport to a teleporter that's
|
||||||
|
// "blocked" by a block that won't be there anyway by the time you try to move, but that
|
||||||
|
// seems very obscure and i haven't run into a case with it yet. offhand i don't think
|
||||||
|
// it can even come up under cc2 rules, since teleporting is done after an actor cools
|
||||||
|
// down and before the next actor even gets a chance to act
|
||||||
|
if (this.check_movement(actor, dest.cell, direction, 'bump')) {
|
||||||
|
// Sound plays from the origin cell simply because that's where the sfx player
|
||||||
|
// thinks the player is currently; position isn't updated til next turn
|
||||||
|
this.sfx.play_once('teleport', teleporter.cell);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Explicitly set us as teleport sliding, since in some very obscure cases (auto-dropping a
|
||||||
|
// yellow teleporter because you picked up an item with a full inventory and immediately
|
||||||
|
// teleporting through it) it may not have been applied
|
||||||
|
this.make_slide(actor, 'teleport');
|
||||||
|
// Real players might be able to immediately override the resulting slide
|
||||||
|
if (actor.type.is_real_player && teleporter.type.allow_player_override) {
|
||||||
|
this._set_tile_prop(actor, 'can_override_slide', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.set_actor_direction(actor, direction);
|
this.set_actor_direction(actor, direction);
|
||||||
|
|||||||
@ -956,6 +956,7 @@ const TILE_TYPES = {
|
|||||||
layer: LAYERS.terrain,
|
layer: LAYERS.terrain,
|
||||||
slide_mode: 'force',
|
slide_mode: 'force',
|
||||||
speed_factor: 2,
|
speed_factor: 2,
|
||||||
|
allow_player_override: true,
|
||||||
on_begin: on_begin_force_floor,
|
on_begin: on_begin_force_floor,
|
||||||
on_arrive(me, level, other) {
|
on_arrive(me, level, other) {
|
||||||
level.set_actor_direction(other, 'north');
|
level.set_actor_direction(other, 'north');
|
||||||
@ -979,6 +980,7 @@ const TILE_TYPES = {
|
|||||||
layer: LAYERS.terrain,
|
layer: LAYERS.terrain,
|
||||||
slide_mode: 'force',
|
slide_mode: 'force',
|
||||||
speed_factor: 2,
|
speed_factor: 2,
|
||||||
|
allow_player_override: true,
|
||||||
on_begin: on_begin_force_floor,
|
on_begin: on_begin_force_floor,
|
||||||
on_arrive(me, level, other) {
|
on_arrive(me, level, other) {
|
||||||
level.set_actor_direction(other, 'east');
|
level.set_actor_direction(other, 'east');
|
||||||
@ -1000,6 +1002,7 @@ const TILE_TYPES = {
|
|||||||
layer: LAYERS.terrain,
|
layer: LAYERS.terrain,
|
||||||
slide_mode: 'force',
|
slide_mode: 'force',
|
||||||
speed_factor: 2,
|
speed_factor: 2,
|
||||||
|
allow_player_override: true,
|
||||||
on_begin: on_begin_force_floor,
|
on_begin: on_begin_force_floor,
|
||||||
on_arrive(me, level, other) {
|
on_arrive(me, level, other) {
|
||||||
level.set_actor_direction(other, 'south');
|
level.set_actor_direction(other, 'south');
|
||||||
@ -1021,6 +1024,7 @@ const TILE_TYPES = {
|
|||||||
layer: LAYERS.terrain,
|
layer: LAYERS.terrain,
|
||||||
slide_mode: 'force',
|
slide_mode: 'force',
|
||||||
speed_factor: 2,
|
speed_factor: 2,
|
||||||
|
allow_player_override: true,
|
||||||
on_begin: on_begin_force_floor,
|
on_begin: on_begin_force_floor,
|
||||||
on_arrive(me, level, other) {
|
on_arrive(me, level, other) {
|
||||||
level.set_actor_direction(other, 'west');
|
level.set_actor_direction(other, 'west');
|
||||||
@ -1042,6 +1046,7 @@ const TILE_TYPES = {
|
|||||||
layer: LAYERS.terrain,
|
layer: LAYERS.terrain,
|
||||||
slide_mode: 'force',
|
slide_mode: 'force',
|
||||||
speed_factor: 2,
|
speed_factor: 2,
|
||||||
|
allow_player_override: true,
|
||||||
on_begin: on_begin_force_floor,
|
on_begin: on_begin_force_floor,
|
||||||
// TODO ms: this is random, and an acting wall to monsters (!)
|
// TODO ms: this is random, and an acting wall to monsters (!)
|
||||||
blocks(me, level, other) {
|
blocks(me, level, other) {
|
||||||
@ -1839,7 +1844,7 @@ const TILE_TYPES = {
|
|||||||
slide_mode: 'teleport',
|
slide_mode: 'teleport',
|
||||||
contains_wire: true,
|
contains_wire: true,
|
||||||
wire_propagation_mode: 'none',
|
wire_propagation_mode: 'none',
|
||||||
teleport_allow_override: true,
|
allow_player_override: true,
|
||||||
on_begin(me, level) {
|
on_begin(me, level) {
|
||||||
// FIXME must be connected to something that can convey current: a wire, a switch, a
|
// FIXME must be connected to something that can convey current: a wire, a switch, a
|
||||||
// blue teleporter, etc; NOT nothing, a wall, a transmogrifier, a force floor, etc.
|
// blue teleporter, etc; NOT nothing, a wall, a transmogrifier, a force floor, etc.
|
||||||
@ -1934,7 +1939,7 @@ const TILE_TYPES = {
|
|||||||
layer: LAYERS.terrain,
|
layer: LAYERS.terrain,
|
||||||
item_priority: PICKUP_PRIORITIES.always,
|
item_priority: PICKUP_PRIORITIES.always,
|
||||||
slide_mode: 'teleport',
|
slide_mode: 'teleport',
|
||||||
teleport_allow_override: true,
|
allow_player_override: true,
|
||||||
*teleport_dest_order(me, level, other) {
|
*teleport_dest_order(me, level, other) {
|
||||||
let exit_direction = other.direction;
|
let exit_direction = other.direction;
|
||||||
for (let dest of level.iter_tiles_in_reading_order(me.cell, 'teleport_yellow', true)) {
|
for (let dest of level.iter_tiles_in_reading_order(me.cell, 'teleport_yellow', true)) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user