Phase 5: active items — room-clear charged, dedicated pedestals, Space to use
- ACTIVES table with 10 actives (Bone Nova, Offal Bomb, Blood Transfusion, Cleaver Storm, Butcher's Bell, Marrow Draught, Slaughter Time, Panic Room, Skinner's Coin, Gut Reroll); charges accrue +1/combat room, +2/boss - Dedicated 'active' pickup with weapon-style swap-drop; 30% boss / 15% item-room bonus pedestal spawns; flat +2 powerScore while held - HUD active slot with charge pips + READY state; ACTIVES help page (12 pages); teal medallion frame variant in draw_sprites.py; 10 generated icons - Procedural Sfx.active()/activeEmpty() (real clips deferred to audio batch) - Fix: toast panel width now fits the wider of title/subtitle and clamps to screen - Bump asset cache to v=40
This commit is contained in:
1 parent
f71d202850
commit
0ec12cd72c
27 files changed
+337
-37
No files matched your search
+43
-3
@@ -61,7 +61,7 @@ for (const f of files) {
|
||||
}
|
||||
// const/let top-level bindings live in the context's lexical scope, not on the
|
||||
// global object — expose the ones the harness pokes at directly.
|
||||
vm.runInContext('Object.assign(this, { G, Input, WEAPONS, Music, Sfx, SfxBank, W, H, WALL, ITEMS, PERKS, ENEMY_TYPES, BOSS_DEFS, SPRITE_MANIFEST, Sprites, ACTOR_ANIMS, PRESSURE_UNIT, PRESSURE_DIAL_MIN, PRESSURE_DIAL_MAX, HELP_PAGES, HELP_RENDERERS, SPAWN_WARN })', sandbox);
|
||||
vm.runInContext('Object.assign(this, { G, Input, WEAPONS, Music, Sfx, SfxBank, W, H, WALL, ITEMS, ACTIVES, PERKS, ENEMY_TYPES, BOSS_DEFS, SPRITE_MANIFEST, Sprites, ACTOR_ANIMS, PRESSURE_UNIT, PRESSURE_DIAL_MIN, PRESSURE_DIAL_MAX, HELP_PAGES, HELP_RENDERERS, SPAWN_WARN })', sandbox);
|
||||
|
||||
let simTime = 0;
|
||||
const ctx = sandbox;
|
||||
@@ -530,6 +530,46 @@ console.log('== phase-4 boss-exclusive legendaries ==');
|
||||
ctx.startRun(); step(3, 16);
|
||||
}
|
||||
|
||||
console.log('== active items (room-clear charged) ==');
|
||||
{
|
||||
const p = ctx.G.player;
|
||||
p.active = null;
|
||||
// pickup grants a full-charge active
|
||||
ctx.spawnPickup('active', p.x, p.y, { aid: 'bonenova' });
|
||||
step(2, 16);
|
||||
check('active pickup equips fully charged', p.active && p.active.iid === 'bonenova' && p.active.charges === ctx.ACTIVES.bonenova.cost);
|
||||
// swap: picking up a second active drops the first
|
||||
ctx.spawnPickup('active', p.x, p.y, { aid: 'offalbomb' });
|
||||
step(2, 16);
|
||||
check('second active equips and drops the old one', p.active.iid === 'offalbomb' && ctx.G.pickups.some(k => k.type === 'active' && k.aid === 'bonenova'));
|
||||
// use: charges spend, effect fires
|
||||
const powerBefore = ctx.powerScore();
|
||||
check('holding an active adds flat power', powerBefore > 0);
|
||||
ctx.useActive();
|
||||
check('using an active spends all charges', p.active.charges === 0);
|
||||
// charge accrues from room clears
|
||||
ctx.recordRoomClear({ type: 'combat' });
|
||||
check('combat clear grants +1 charge', p.active.charges === 1);
|
||||
ctx.recordRoomClear({ type: 'boss' });
|
||||
check('boss clear grants +2 charges', p.active.charges === ctx.ACTIVES.offalbomb.cost);
|
||||
// under-charged use is blocked
|
||||
p.active.charges = 0;
|
||||
const enemiesBefore = ctx.G.enemies.length;
|
||||
ctx.useActive();
|
||||
check('under-charged active does not fire', p.active.charges === 0 && ctx.G.enemies.length === enemiesBefore);
|
||||
// panic room blocks firing
|
||||
p.active = { iid: 'panicroom', charges: ctx.ACTIVES.panicroom.cost };
|
||||
ctx.useActive();
|
||||
check('panic room grants invulnerability', p.invT >= 2.4 && p.panicRoomT > 0);
|
||||
p.weapon = { id: 'bonepopper', ammo: Infinity };
|
||||
p.fireT = 0;
|
||||
ctx.Input.mdown = true; step(3, 16); ctx.Input.mdown = false;
|
||||
check('panic room prevents firing', ctx.G.bullets.length === 0);
|
||||
p.panicRoomT = 0; p.invT = 1;
|
||||
p.active = null;
|
||||
ctx.G.pickups.length = 0;
|
||||
}
|
||||
|
||||
console.log('== phase-3 hook passives ==');
|
||||
{
|
||||
const p = ctx.G.player;
|
||||
@@ -1016,8 +1056,8 @@ console.log('== item stickiness ramps with owned count ==');
|
||||
|
||||
console.log('== help manual grows with the implant roster ==');
|
||||
{
|
||||
check('11 help pages (5 implant pages for 82 items)', ctx.HELP_PAGES.length === 11);
|
||||
check('11 help renderers', ctx.HELP_RENDERERS.length === 11);
|
||||
check('12 help pages (5 implants + actives)', ctx.HELP_PAGES.length === 12);
|
||||
check('12 help renderers', ctx.HELP_RENDERERS.length === 12);
|
||||
check('help tabs never overflow the panel', (() => {
|
||||
const last = ctx.helpTabRect(ctx.HELP_PAGES.length - 1);
|
||||
const first = ctx.helpTabRect(0);
|
||||
|
||||
Reference in new issue
Block a user