Refactor bombs to use on_stand instead of on_begin

This commit is contained in:
Eevee (Evelyn Woods) 2024-04-11 01:52:44 -06:00
parent 25cb6f2f05
commit f417162f6f
3 changed files with 28 additions and 19 deletions

View File

@ -215,13 +215,13 @@ export const COMPAT_FLAGS = [
// Items // Items
{ {
key: 'no_immediate_detonate_bombs', key: 'bombs_detonate_on_arrive',
label: "Mines under non-player actors don't explode at level start", label: "Mines detonate only when stepped on",
rulesets: new Set(['lynx', 'ms']), rulesets: new Set(['lynx', 'ms']),
}, { }, {
key: 'detonate_bombs_under_players', key: 'bombs_immediately_detonate_under_players',
label: "Mines under players explode at level start", label: "Mines under players detonate at level start",
rulesets: new Set(['steam', 'steam-strict']), rulesets: new Set(['steam-strict']),
}, { }, {
key: 'cloned_bowling_balls_can_be_lost', key: 'cloned_bowling_balls_can_be_lost',
label: "Bowling balls on cloners are destroyed when fired at point blank", label: "Bowling balls on cloners are destroyed when fired at point blank",

View File

@ -855,9 +855,7 @@ export class Level extends LevelInterface {
_do_init_phase() { _do_init_phase() {
// At the beginning of the very first tic, some tiles want to do initialization that's not // At the beginning of the very first tic, some tiles want to do initialization that's not
// appropriate to do before the game begins. (For example, bombs blow up anything that // appropriate to do before the game begins
// starts on them in CC2, but we don't want to do that before the game has run at all. We
// DEFINITELY don't want to blow the PLAYER up before the game starts!)
if (! this.done_on_begin) { if (! this.done_on_begin) {
// Run backwards, to match actor order // Run backwards, to match actor order
for (let i = this.linear_cells.length - 1; i >= 0; i--) { for (let i = this.linear_cells.length - 1; i >= 0; i--) {
@ -1146,6 +1144,12 @@ export class Level extends LevelInterface {
if (terrain.type.on_stand && ! actor.ignores(terrain.type.name)) { if (terrain.type.on_stand && ! actor.ignores(terrain.type.name)) {
terrain.type.on_stand(terrain, this, actor); terrain.type.on_stand(terrain, this, actor);
} }
// You might think a loop would be good here but this is unbelievably faster and the
// only tile with an on_stand is the bomb anyway
let item = actor.cell.get_item();
if (item && item.type.on_stand && ! actor.ignores(item.type.name)) {
item.type.on_stand(item, this, actor);
}
} }
// Lynx gives everything in an open trap an extra cooldown, which makes things walk into // Lynx gives everything in an open trap an extra cooldown, which makes things walk into
// open traps at double speed and does weird things to the ejection timing // open traps at double speed and does weird things to the ejection timing

View File

@ -1002,19 +1002,23 @@ const TILE_TYPES = {
}, },
bomb: { bomb: {
layer: LAYERS.item, layer: LAYERS.item,
on_begin(me, level) { on_arrive(me, level, other) {
if (level.compat.no_immediate_detonate_bombs) if (level.compat.bombs_detonate_on_arrive) {
return; me.type._detonate(me, level, other);
// In CC2, actors on a bomb (but not a green one) are immediately blown up
let actor = me.cell.get_actor();
if (actor && ! actor.ignores(this.name)) {
if (actor.type.is_real_player && ! level.compat.detonate_bombs_under_players)
return;
this.on_arrive(me, level, actor);
} }
}, },
on_arrive(me, level, other) { on_stand(me, level, other) {
// Lynx: Bombs detonate on arrival, not on idle
// Steam: Bombs detonate when stood on, even if a player starts the level on one. This
// is useless in CC2 design and breaks some CC1 levels, so it's off by default
if (! level.compat.bombs_detonate_on_arrive &&
! (level.compat.bombs_immediately_detonate_under_players &&
level.tic_counter === 0 && other.type.is_real_player))
{
me.type._detonate(me, level, other);
}
},
_detonate(me, level, other) {
level.remove_tile(me); level.remove_tile(me);
level.kill_actor(other, me, 'explosion', 'bomb', 'exploded'); level.kill_actor(other, me, 'explosion', 'bomb', 'exploded');
}, },
@ -1328,6 +1332,7 @@ const TILE_TYPES = {
layer: LAYERS.item, layer: LAYERS.item,
is_required_chip: true, is_required_chip: true,
on_arrive(me, level, other) { on_arrive(me, level, other) {
// Unlike regular bombs, these only seem to respond to being stepped on, not stood on
level.remove_tile(me); level.remove_tile(me);
level.kill_actor(other, me, 'explosion', 'bomb', 'exploded'); level.kill_actor(other, me, 'explosion', 'bomb', 'exploded');
}, },