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
{
key: 'no_immediate_detonate_bombs',
label: "Mines under non-player actors don't explode at level start",
key: 'bombs_detonate_on_arrive',
label: "Mines detonate only when stepped on",
rulesets: new Set(['lynx', 'ms']),
}, {
key: 'detonate_bombs_under_players',
label: "Mines under players explode at level start",
rulesets: new Set(['steam', 'steam-strict']),
key: 'bombs_immediately_detonate_under_players',
label: "Mines under players detonate at level start",
rulesets: new Set(['steam-strict']),
}, {
key: 'cloned_bowling_balls_can_be_lost',
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() {
// 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
// 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!)
// appropriate to do before the game begins
if (! this.done_on_begin) {
// Run backwards, to match actor order
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)) {
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
// open traps at double speed and does weird things to the ejection timing

View File

@ -1002,19 +1002,23 @@ const TILE_TYPES = {
},
bomb: {
layer: LAYERS.item,
on_begin(me, level) {
if (level.compat.no_immediate_detonate_bombs)
return;
// 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) {
if (level.compat.bombs_detonate_on_arrive) {
me.type._detonate(me, level, other);
}
},
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.kill_actor(other, me, 'explosion', 'bomb', 'exploded');
},
@ -1328,6 +1332,7 @@ const TILE_TYPES = {
layer: LAYERS.item,
is_required_chip: true,
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.kill_actor(other, me, 'explosion', 'bomb', 'exploded');
},