Peggle Adjustments
This commit is contained in:
parent
bb91a21c8d
commit
3942b0b89e
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"width": 1200,
|
||||
"height": 900
|
||||
},
|
||||
"orangeCount": 25,
|
||||
"orangeCount": 18,
|
||||
"greenCount": 2,
|
||||
"pegs": [
|
||||
{
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 1.4 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.5 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.5 MiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -90,8 +90,8 @@ export const POWERS = {
|
|||
},
|
||||
meteor: { // Terry
|
||||
id: 'meteor', name: 'Meteor Strike', trigger: 'instant',
|
||||
desc: 'A meteor crashes down through the green peg, lighting every peg in its column.',
|
||||
params: { halfWidth: 70 },
|
||||
desc: 'A meteor crashes down through the green peg, lighting every peg in its column — then two more rain down on random orange pegs over the next 1.5s.',
|
||||
params: { halfWidth: 70, delays: [1, 1.5] },
|
||||
},
|
||||
overclock: { // Nicole
|
||||
id: 'overclock', name: 'Overclock', trigger: 'instant',
|
||||
|
|
@ -110,8 +110,8 @@ export const POWERS = {
|
|||
},
|
||||
beaverdam: { // Maurice
|
||||
id: 'beaverdam', name: 'Beaver Dam', trigger: 'charge',
|
||||
desc: 'The free-ball bucket is dammed up to nearly double width for your next 3 shots.',
|
||||
params: { widthScale: 1.9, shots: 3 },
|
||||
desc: 'The free-ball bucket is dammed up to nearly double width for your next 5 shots.',
|
||||
params: { widthScale: 1.9, shots: 5 },
|
||||
},
|
||||
shadowslash: { // Kage
|
||||
id: 'shadowslash', name: 'Shadow Slash', trigger: 'instant',
|
||||
|
|
@ -120,8 +120,8 @@ export const POWERS = {
|
|||
},
|
||||
tailwind: { // Schooner
|
||||
id: 'tailwind', name: 'Tailwind', trigger: 'nextBall',
|
||||
desc: 'Your next ball rides the sea breeze — light as a gull, it floats far longer.',
|
||||
params: { gravityScale: 0.55 },
|
||||
desc: 'Your next 3 balls ride the sea breeze — light as gulls, they float far longer.',
|
||||
params: { gravityScale: 0.55, shots: 3 },
|
||||
},
|
||||
cosmicbloom: { // Aiko
|
||||
id: 'cosmicbloom', name: 'Cosmic Bloom', trigger: 'instant',
|
||||
|
|
@ -333,6 +333,7 @@ export function createRound(levelDef, opts = {}) {
|
|||
wideBucketShots: 0,
|
||||
rewindCharges: 0,
|
||||
feverResolved: false,
|
||||
pendingMeteors: [], // absolute state.time values for Meteor Strike follow-ups
|
||||
};
|
||||
assignPurple(state);
|
||||
return state;
|
||||
|
|
@ -363,6 +364,7 @@ export function cloneState(state) {
|
|||
pegs: state.pegs.map((p) => ({ ...p })),
|
||||
balls: state.balls.map((b) => ({ ...b })),
|
||||
lastPegHit: state.lastPegHit ? { ...state.lastPegHit } : null,
|
||||
pendingMeteors: [...state.pendingMeteors],
|
||||
};
|
||||
c.rng.state = state.rng.state;
|
||||
return c;
|
||||
|
|
@ -604,6 +606,18 @@ function areaBlast(state, events, type, origin, predicate) {
|
|||
return hit;
|
||||
}
|
||||
|
||||
// Meteor Strike follow-up: crashes a meteor onto a random still-active orange
|
||||
// peg (scoring it directly, since no ball is involved) and blasts its column.
|
||||
function fireMeteorStrike(state, events) {
|
||||
const half = POWERS.meteor.params.halfWidth;
|
||||
const eligible = state.pegs.filter((q) => q.color === 'orange' && !q.lit && !q.removed).map((q) => q.id);
|
||||
if (!eligible.length) return;
|
||||
const [id] = pickN(state.rng, eligible, 1);
|
||||
const target = state.pegs[id];
|
||||
scorePeg(state, target, events, { fromBlast: true });
|
||||
areaBlast(state, events, 'meteorColumn', target, (q) => Math.abs(q.x - target.x) <= half);
|
||||
}
|
||||
|
||||
export function applyPower(state, powerId, ctx = {}) {
|
||||
const events = ctx.events ?? [];
|
||||
switch (powerId) {
|
||||
|
|
@ -669,6 +683,9 @@ export function applyPower(state, powerId, ctx = {}) {
|
|||
const half = POWERS.meteor.params.halfWidth;
|
||||
areaBlast(state, events, 'meteorColumn', peg, (q) => Math.abs(q.x - peg.x) <= half);
|
||||
events.push({ type: 'powerFired', powerId: 'meteor' });
|
||||
for (const delay of POWERS.meteor.params.delays) {
|
||||
state.pendingMeteors.push(state.time + delay);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -706,7 +723,7 @@ export function applyPower(state, powerId, ctx = {}) {
|
|||
break;
|
||||
}
|
||||
case 'tailwind': // Schooner
|
||||
state.floatyNext++;
|
||||
state.floatyNext += POWERS.tailwind.params.shots;
|
||||
break;
|
||||
case 'cosmicbloom': { // Aiko
|
||||
const blues = state.pegs.filter((q) => q.color === 'blue' && !q.lit && !q.removed).map((q) => q.id);
|
||||
|
|
@ -732,6 +749,15 @@ export function applyPower(state, powerId, ctx = {}) {
|
|||
export function stepSim(state, dt) {
|
||||
const events = [];
|
||||
state.time += dt;
|
||||
if (state.pendingMeteors.length) {
|
||||
const due = state.pendingMeteors.filter((t) => t <= state.time).sort((a, b) => a - b);
|
||||
if (due.length) {
|
||||
state.pendingMeteors = state.pendingMeteors.filter((t) => t > state.time);
|
||||
if (state.phase !== 'won' && state.phase !== 'lost') {
|
||||
for (let i = 0; i < due.length; i++) fireMeteorStrike(state, events);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (state.phase !== 'flight' && state.phase !== 'fever') return events;
|
||||
|
||||
state.flightTime += dt;
|
||||
|
|
|
|||
|
|
@ -1096,6 +1096,7 @@ for (const block of BLOCKS) {
|
|||
levelNo++;
|
||||
const file = `level-${String(levelNo).padStart(3, '0')}.json`;
|
||||
const data = block.build(v);
|
||||
if (levelNo >= 33) data.orangeCount -= 7;
|
||||
const info = validate(data, `${file} (${block.names[v]})`);
|
||||
writeFileSync(join(OUT_DIR, file), `${JSON.stringify(data, null, 2)}\n`);
|
||||
console.log(`${file}: ${block.names[v]} [${block.masterId}] — ${data.pegs.length} pegs + ${info.bricks} bricks (${info.eligible} orange-eligible)`);
|
||||
|
|
|
|||
|
|
@ -600,6 +600,27 @@ console.log('― powers (new wave)');
|
|||
met && JSON.stringify(met.pegIds));
|
||||
}
|
||||
|
||||
{
|
||||
// Meteor Strike: two follow-up meteors land on random active orange pegs,
|
||||
// 1s and 1.5s after the initial strike, for 3 total.
|
||||
const st = mkState([
|
||||
{ x: 600, y: 500 }, // green
|
||||
{ x: 100, y: 500 }, { x: 400, y: 500 }, { x: 1000, y: 500 }, // oranges, each >140 apart so blast columns don't overlap
|
||||
], { powerId: 'meteor' });
|
||||
st.pegs[0].color = 'green';
|
||||
st.pegs[1].color = 'orange';
|
||||
st.pegs[2].color = 'orange';
|
||||
st.pegs[3].color = 'orange';
|
||||
inject(st, { x: 600, y: 450, vx: 0, vy: 200 });
|
||||
const log = [];
|
||||
for (let t = 0; t < 3; t += 1 / 60) log.push(...stepSim(st, 1 / 60));
|
||||
const strikes = log.filter((e) => e.type === 'meteorColumn');
|
||||
check('meteor strikes 3 times total (1 instant + 2 follow-ups)', strikes.length === 3, `got ${strikes.length}`);
|
||||
const orangeHits = log.filter((e) => e.type === 'pegHit' && e.color === 'orange');
|
||||
check('the 2 follow-ups each score a distinct orange peg', orangeHits.length === 2
|
||||
&& new Set(orangeHits.map((e) => e.pegId)).size === 2, JSON.stringify(orangeHits));
|
||||
}
|
||||
|
||||
{
|
||||
// Overclock: doubles peg scoring for the rest of the shot only. An orange
|
||||
// far off the path keeps the round alive; force the target peg blue (the
|
||||
|
|
@ -649,16 +670,17 @@ console.log('― powers (new wave)');
|
|||
}
|
||||
|
||||
{
|
||||
// Beaver Dam: wider opening catches wide, expires after 3 launches.
|
||||
// Beaver Dam: wider opening catches wide, expires after N launches.
|
||||
const damShots = POWERS.beaverdam.params.shots;
|
||||
const st = mkState([]);
|
||||
applyPower(st, 'beaverdam');
|
||||
check('dam charges 3 shots', st.wideBucketShots === 3);
|
||||
check(`dam charges ${damShots} shots`, st.wideBucketShots === damShots);
|
||||
check('dam widens the bucket', bucketWidth(st) === T.BUCKET_W * POWERS.beaverdam.params.widthScale);
|
||||
st.time = 0;
|
||||
const bx = bucketX(st);
|
||||
const wideX = bx + T.BUCKET_W / 2 + 20; // outside normal opening, inside dam
|
||||
st.phase = 'flight';
|
||||
st.wideBucketShots = 3;
|
||||
st.wideBucketShots = damShots;
|
||||
st.balls.push({ x: wideX, y: T.BUCKET_Y - 30, vx: 0, vy: 300, stuckFor: 0, fireball: false, r: T.BALL_R, pierce: 0, spooky: 0 });
|
||||
let caught = false;
|
||||
for (let i = 0; i < 60 && !caught; i++) {
|
||||
|
|
@ -667,10 +689,11 @@ console.log('― powers (new wave)');
|
|||
check('dam catches outside the normal opening', caught);
|
||||
const st3 = mkState([]);
|
||||
applyPower(st3, 'beaverdam');
|
||||
launchBall(st3, 0); st3.balls.length = 0; st3.phase = 'aim';
|
||||
launchBall(st3, 0); st3.balls.length = 0; st3.phase = 'aim';
|
||||
for (let i = 0; i < damShots - 1; i++) {
|
||||
launchBall(st3, 0); st3.balls.length = 0; st3.phase = 'aim';
|
||||
}
|
||||
launchBall(st3, 0);
|
||||
check('dam expires after 3 launches', st3.wideBucketShots === 0 && bucketWidth(st3) === T.BUCKET_W);
|
||||
check(`dam expires after ${damShots} launches`, st3.wideBucketShots === 0 && bucketWidth(st3) === T.BUCKET_W);
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue