import {GameState, PerkId, RunParams} from "./types"; import {allLevels, allLevelsAndIcons, upgrades} from "./loadGameData"; import { defaultSounds, getHighScore, getPossibleUpgrades, highScoreText, reasonLevelIsLocked, makeEmptyPerksMap, sumOfValues, } from "./game_utils"; import { dontOfferTooSoon, resetBalls } from "./gameStateMutators"; import { isOptionOn } from "./options"; import { getHistory } from "./gameOver"; import { getTotalScore } from "./settings"; import { isStartingPerk } from "./startingPerks"; export function getRunLevels(params: RunParams, randomGift:PerkId|undefined) { const history = getHistory(); const unlocked = allLevels.filter( (l, li) => !reasonLevelIsLocked(li, history, false), ); const firstLevel = (params?.level && unlocked.filter((l) => l.name === params?.level)) || ( randomGift && allLevelsAndIcons.filter(l=>l.name=='icon:'+randomGift) ) || []; const restInRandomOrder = unlocked .filter((l) => l.name !== params?.level) .filter((l) => l.name !== params?.levelToAvoid) .sort(() => Math.random() - 0.5); return firstLevel.concat( restInRandomOrder.slice(0, 7 + 3).sort((a, b) => a.sortKey - b.sortKey), ); } export function newGameState(params: RunParams): GameState { const highScore= getHighScore() const perks = { ...makeEmptyPerksMap(upgrades), ...(params?.perks || {}) }; let randomGift:PerkId|undefined =undefined if (!sumOfValues(perks)) { const giftable = upgrades.filter((u) => highScore >= u.threshold && !u.requires && isStartingPerk(u)); randomGift = (isOptionOn("easy") && "slow_down") || giftable[Math.floor(Math.random() * giftable.length)].id; perks[randomGift] = 1; } const runLevels = getRunLevels(params,randomGift); console.log(randomGift, params,runLevels) const gameState: GameState = { runLevels, level: runLevels[0], currentLevel: 0, upgradesOfferedFor: -1, perks, puckWidth: 200, baseSpeed: 12, combo: 1, gridSize: 12, running: false, isGameOver: false, ballStickToPuck: true, puckPosition: 400, lastPuckPosition: 400, lastPuckMove: 0, pauseTimeout: null, canvasWidth: 0, canvasHeight: 0, offsetX: 0, offsetXRoundedDown: 0, gameZoneWidth: 0, gameZoneWidthRoundedUp: 0, gameZoneHeight: 0, brickWidth: 0, score: 0, lastScoreIncrease: -1000, lastExplosion: -1000, lastBrickBroken: 0, highScore, balls: [], ballsColor: "#FFFFFF", bricks: [], brickHP: [], lights: { indexMin: 0, total: 0, list: [] }, particles: { indexMin: 0, total: 0, list: [] }, texts: { indexMin: 0, total: 0, list: [] }, coins: { indexMin: 0, total: 0, list: [] }, respawns: { indexMin: 0, total: 0, list: [] }, levelStartScore: 0, levelMisses: 0, levelSpawnedCoins: 0, puckColor: "#FFFFFF", ballSize: 20, coinSize: 14, puckHeight: 20, totalScoreAtRunStart: getTotalScore(), pauseUsesDuringRun: 0, keyboardPuckSpeed: 0, lastTick: performance.now(), lastTickDown: 0, runStatistics: { started: Date.now(), levelsPlayed: 0, runTime: 0, coins_spawned: 0, score: 0, bricks_broken: 0, misses: 0, balls_lost: 0, puck_bounces: 0, wall_bounces: 0, upgrades_picked: 1, max_combo: 1, }, lastOffered: {}, levelTime: 0, winAt: 0, levelWallBounces: 0, needsRender: true, autoCleanUses: 0, ...defaultSounds(), rerolls: 0, creative: sumOfValues(params.perks) > 1, }; resetBalls(gameState); for (let perk of upgrades) { if (perks[perk.id]) { dontOfferTooSoon(gameState, perk.id); } } return gameState; }