Name compat flags more consistently; add a couple; flip sliding blue tank behavior
This commit is contained in:
parent
3359c21387
commit
0119f45d54
11
js/game.js
11
js/game.js
@ -1461,13 +1461,6 @@ export class Level extends LevelInterface {
|
||||
}
|
||||
|
||||
make_actor_decision(actor, forced_only = false) {
|
||||
// Compat flag for blue tanks
|
||||
if (this.compat.sliding_tanks_ignore_button &&
|
||||
actor.slide_mode && actor.pending_reverse)
|
||||
{
|
||||
this._set_tile_prop(actor, 'pending_reverse', false);
|
||||
}
|
||||
|
||||
if (actor.pending_push) {
|
||||
// Blocks that were pushed while sliding will move in the push direction as soon as
|
||||
// they can make a decision, even if they're still sliding or are off-tic. Also used
|
||||
@ -2501,6 +2494,10 @@ export class Level extends LevelInterface {
|
||||
// Get the next direction a random force floor will use. They share global
|
||||
// state and cycle clockwise.
|
||||
get_force_floor_direction() {
|
||||
if (this.compat.rff_actually_random) {
|
||||
return DIRECTION_ORDER[this.prng() % 4];
|
||||
}
|
||||
|
||||
let d = this.force_floor_direction;
|
||||
this.force_floor_direction = DIRECTIONS[d].right;
|
||||
return d;
|
||||
|
||||
117
js/main.js
117
js/main.js
@ -2944,73 +2944,102 @@ const COMPAT_RULESETS = [
|
||||
['ms', "Microsoft"],
|
||||
['custom', "Custom"],
|
||||
];
|
||||
const COMPAT_FLAGS = [{
|
||||
// FIXME some of the names of the flags themselves kinda suck
|
||||
const COMPAT_FLAGS = [
|
||||
// Level loading
|
||||
{
|
||||
key: 'no_auto_convert_ccl_popwalls',
|
||||
label: "Don't fix populated recessed walls in CC1 levels",
|
||||
label: "Recessed walls under actors in CCL levels are left alone",
|
||||
rulesets: new Set(['steam-strict', 'lynx', 'ms']),
|
||||
}, {
|
||||
key: 'no_auto_convert_ccl_blue_walls',
|
||||
label: "Don't fix populated blue walls in CC1 levels",
|
||||
label: "Blue walls under blocks in CCL levels are left alone",
|
||||
rulesets: new Set(['steam-strict', 'lynx']),
|
||||
},
|
||||
|
||||
// Core
|
||||
{
|
||||
key: 'use_lynx_loop',
|
||||
label: "Game uses the Lynx-style update loop",
|
||||
rulesets: new Set(['steam', 'steam-strict', 'lynx', 'ms']),
|
||||
}, {
|
||||
key: 'emulate_60fps',
|
||||
label: "Game runs at 60 FPS",
|
||||
rulesets: new Set(['steam', 'steam-strict']),
|
||||
},
|
||||
|
||||
// Tiles
|
||||
{
|
||||
// XXX this is goofy
|
||||
key: 'tiles_react_instantly',
|
||||
label: "Tiles react when approached",
|
||||
rulesets: new Set(['ms']),
|
||||
}, {
|
||||
key: 'rff_actually_random',
|
||||
label: "Random force floors are actually random",
|
||||
rulesets: new Set(['ms']),
|
||||
},
|
||||
|
||||
// Items
|
||||
{
|
||||
key: 'no_immediate_detonate_bombs',
|
||||
label: "Don't immediately detonate populated mines",
|
||||
label: "Mines under non-player actors don't explode at level start",
|
||||
rulesets: new Set(['lynx', 'ms']),
|
||||
}, {
|
||||
key: 'detonate_bombs_under_players',
|
||||
label: "Detonate mines populated by players",
|
||||
label: "Mines under players explode at level start",
|
||||
rulesets: new Set(['steam', 'steam-strict']),
|
||||
}, {
|
||||
key: 'tanks_teeth_push_ice_blocks',
|
||||
label: "Blue tanks and teeth can push ice blocks",
|
||||
key: 'monsters_ignore_keys',
|
||||
label: "Monsters completely ignore keys",
|
||||
rulesets: new Set(['ms']),
|
||||
}, {
|
||||
key: 'sliding_tanks_ignore_button',
|
||||
label: "Blue tanks ignore blue buttons while sliding",
|
||||
// TODO ms?
|
||||
rulesets: new Set(['lynx']),
|
||||
}, {
|
||||
key: 'cloner_tanks_react_button',
|
||||
label: "Blue tanks on cloners respond to blue buttons",
|
||||
rulesets: new Set(['steam-strict']),
|
||||
},
|
||||
|
||||
// Blocks
|
||||
{
|
||||
key: 'no_early_push',
|
||||
label: "Player pushes blocks at move time",
|
||||
rulesets: new Set(['lynx', 'ms']),
|
||||
}, {
|
||||
key: 'use_legacy_hooking',
|
||||
label: "Player pulls blocks at decision time",
|
||||
// TODO maybe steam as well?
|
||||
rulesets: new Set(['steam-strict']),
|
||||
label: "Pulling blocks with the hook happens at decision time",
|
||||
rulesets: new Set(['steam', 'steam-strict']),
|
||||
}, {
|
||||
key: 'monsters_ignore_keys',
|
||||
label: "Monsters ignore keys",
|
||||
rulesets: new Set(['ms']),
|
||||
}, {
|
||||
// XXX this is goofy
|
||||
key: 'tiles_react_instantly',
|
||||
label: "Tiles react instantly",
|
||||
// FIXME this is kind of annoying, there are some collision rules too
|
||||
key: 'tanks_teeth_push_ice_blocks',
|
||||
label: "Ice blocks emulate pgchip rules",
|
||||
rulesets: new Set(['ms']),
|
||||
}, {
|
||||
key: 'emulate_spring_mining',
|
||||
label: "Emulate spring mining",
|
||||
label: "Spring mining is possible",
|
||||
rulesets: new Set(['steam-strict']),
|
||||
/* XXX not implemented
|
||||
}, {
|
||||
key: 'emulate_flicking',
|
||||
label: "Flicking is possible",
|
||||
rulesets: new Set(['ms']),
|
||||
*/
|
||||
},
|
||||
|
||||
// Monsters
|
||||
{
|
||||
// TODO? in lynx they ignore the button while in motion too
|
||||
// TODO what about in a trap, in every game??
|
||||
// TODO what does ms do when a tank is on ice or a ff? wiki's description is wacky
|
||||
// TODO yellow tanks seem to have memory too??
|
||||
key: 'tanks_always_obey_button',
|
||||
label: "Blue tanks always obey blue buttons",
|
||||
rulesets: new Set(['steam-strict']),
|
||||
}, {
|
||||
// XXX not implemented
|
||||
/*
|
||||
key: 'emulate_flicking',
|
||||
label: "Emulate flicking",
|
||||
key: 'rff_blocks_monsters',
|
||||
label: "Random force floors block monsters",
|
||||
rulesets: new Set(['ms']),
|
||||
}, {
|
||||
*/
|
||||
key: 'use_lynx_loop',
|
||||
label: "Use Lynx-style update loop",
|
||||
rulesets: new Set(['steam', 'steam-strict', 'lynx', 'ms']),
|
||||
}, {
|
||||
key: 'no_early_push',
|
||||
label: "Player doesn't push at decision time",
|
||||
rulesets: new Set(['lynx', 'ms']),
|
||||
}, {
|
||||
key: 'emulate_60fps',
|
||||
label: "Run at 60 FPS",
|
||||
rulesets: new Set(['steam', 'steam-strict']),
|
||||
}];
|
||||
key: 'fire_allows_monsters',
|
||||
label: "Fire doesn't block monsters",
|
||||
rulesets: new Set(['ms']),
|
||||
},
|
||||
];
|
||||
class CompatOverlay extends DialogOverlay {
|
||||
constructor(conductor) {
|
||||
super(conductor);
|
||||
|
||||
@ -372,6 +372,7 @@ const TILE_TYPES = {
|
||||
{
|
||||
// Blocks can be pushed off of blue walls in TW Lynx, which only works due to a tiny
|
||||
// quirk of the engine that I don't want to replicate, so replace them with popwalls
|
||||
// TODO this also works with invis walls apparently. maybe only for blocks?
|
||||
me.type = TILE_TYPES['popwall'];
|
||||
}
|
||||
},
|
||||
@ -741,7 +742,15 @@ const TILE_TYPES = {
|
||||
// Hazards
|
||||
fire: {
|
||||
layer: LAYERS.terrain,
|
||||
blocks_collision: COLLISION.monster_solid & ~COLLISION.fireball,
|
||||
// Fire blocks most monsters, except in MS where they walk right in and get roasted
|
||||
blocks(me, level, other) {
|
||||
if (other.type.collision_mask & (COLLISION.fireball | COLLISION.ghost))
|
||||
return false;
|
||||
if (other.type.collision_mask & COLLISION.monster_any) {
|
||||
return ! level.compat.fire_allows_monsters;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
on_arrive(me, level, other) {
|
||||
if (other.type.name === 'ghost') {
|
||||
// Ghosts with fire boots erase fire, otherwise are unaffected
|
||||
@ -986,6 +995,10 @@ const TILE_TYPES = {
|
||||
speed_factor: 2,
|
||||
on_begin: on_begin_force_floor,
|
||||
// TODO ms: this is random, and an acting wall to monsters (!)
|
||||
blocks(me, level, other) {
|
||||
return (level.compat.rff_blocks_monsters &&
|
||||
(other.type.collision_mask & COLLISION.monster_general));
|
||||
},
|
||||
on_arrive(me, level, other) {
|
||||
level.set_actor_direction(other, level.get_force_floor_direction());
|
||||
},
|
||||
@ -1871,12 +1884,17 @@ const TILE_TYPES = {
|
||||
// Flip direction of all blue tanks
|
||||
for (let actor of level.actors) {
|
||||
// TODO generify somehow??
|
||||
if (actor.type.name === 'tank_blue') {
|
||||
if (level.compat.cloner_tanks_react_button || ! actor.cell.has('cloner')) {
|
||||
if (actor.type.name !== 'tank_blue')
|
||||
continue;
|
||||
|
||||
if (! level.compat.tanks_always_obey_button &&
|
||||
(actor.slide_mode || actor.cell.has('cloner')))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
level._set_tile_prop(actor, 'pending_reverse', ! actor.pending_reverse);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
on_arrive(me, level, other) {
|
||||
level.sfx.play_once('button-press', me.cell);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user