Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -1941,6 +1941,8 @@ function getEffectiveMPS() {
return effectiveMPS;
}

let autoClickerTick = 0;

function gameLoop() {
// Skip production if in prestige mode
if (PrestigeModule.isPrestigeMode()) {
Expand All @@ -1956,6 +1958,20 @@ function gameLoop() {
}
StatisticsModule.setCurrentMana(mana);

// Auto-clicker from prestige upgrade (1 click per second)
if (PrestigeModule.hasAutoClicker && PrestigeModule.hasAutoClicker()) {
autoClickerTick++;
if (autoClickerTick >= 10) {
autoClickerTick = 0;
let autoMPC = manaPerClick;
if (typeof RunestonesModule !== 'undefined') autoMPC += RunestonesModule.getTempMPCBonus();
if (typeof SpellcastingModule !== 'undefined') autoMPC *= SpellcastingModule.getMPCMultiplier();
if (autoMPC < 1) autoMPC = 1;
mana += autoMPC;
StatisticsModule.addManaByClick(autoMPC);
}
}

// Check achievements and unlocks
AchievementsModule.checkAchievements(StatisticsModule.getStats());
checkUnlocks();
Expand All @@ -1976,6 +1992,10 @@ function gameLoop() {
if (typeof SpellcastingModule !== 'undefined') {
coinRate *= SpellcastingModule.getWishingWellMultiplier();
}
// Apply Well Keeper prestige upgrade
if (PrestigeModule.hasWellBoost && PrestigeModule.hasWellBoost()) {
coinRate *= 2;
}
WishingWellModule.addCoins(coinRate / 10); // Divide by 10 since loop runs 10x per second
WishingWellModule.updateDisplay();
}
Expand Down Expand Up @@ -2014,6 +2034,21 @@ function resetForPrestige() {

// Apply prestige building boosts and recalculate
PrestigeModule.applyAllPrestigeBuildingBoosts();

// Apply starting mana from prestige upgrades
const startingMana = PrestigeModule.getStartingMana();
if (startingMana > 0) mana = startingMana;

// Apply starting buildings from prestige upgrades
const startingBuildings = PrestigeModule.getStartingBuildings();
Object.entries(startingBuildings).forEach(([id, count]) => {
const building = buildings.find(b => b.id === id);
if (building) {
building.owned += count;
building.isUnlocked = true;
}
});

recalculateMPS();

// Reset upgrades (all upgrades reset each run)
Expand Down
109 changes: 108 additions & 1 deletion modules/prestige.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,91 @@ const PrestigeModule = (function() {
isPurchased: false,
unlockCost: 0,
requiresUpgrade: 'mana-crystal-upgrade'
},
{
id: 'arcane-auto-gather',
name: 'Arcane Auto-Gather',
description: 'Automatically gathers Mana once per second (as if clicking).',
flavorText: 'Why click when magic can do it for you?',
cost: 15,
isAutoClicker: true,
isPurchased: false,
unlockCost: 0,
requiresUpgrade: 'spell-core'
},
{
id: 'head-start',
name: 'Head Start',
description: 'Start each run with 1,000 Mana.',
flavorText: 'A small gift from your past self.',
cost: 5,
startingMana: 1000,
isPurchased: false,
unlockCost: 0
},
{
id: 'greater-head-start',
name: 'Greater Head Start',
description: 'Start each run with 100,000 Mana.',
flavorText: 'A generous gift from your much wiser past self.',
cost: 20,
startingMana: 100000,
isPurchased: false,
unlockCost: 0,
requiresUpgrade: 'head-start'
},
{
id: 'runestone-affinity',
name: 'Runestone Affinity',
description: 'Runestones appear 30% more frequently.',
flavorText: 'The stones sense your presence and are drawn to you.',
cost: 8,
isRunestoneBoost: true,
isPurchased: false,
unlockCost: 0
},
{
id: 'spell-power-reservoir',
name: 'Spell Power Reservoir',
description: 'Spell Power regenerates 50% faster.',
flavorText: 'A deeper well of arcane energy to draw from.',
cost: 12,
isSpellRegenBoost: true,
isPurchased: false,
unlockCost: 0,
requiresUpgrade: 'mana-crystal-upgrade'
},
{
id: 'crystal-multiplication',
name: 'Crystal Multiplication',
description: 'Boosts MPS by 10%.',
flavorText: 'Your crystals resonate with accumulated power.',
cost: 25,
mpsBonus: 0.10,
isPurchased: false,
unlockCost: 0,
requiresUpgrade: 'spell-core'
},
{
id: 'hand-of-the-ancients',
name: 'Hand of the Ancients',
description: 'Start each run with 5 Wizard\'s Hands.',
flavorText: 'Spectral hands from past lives join your cause.',
cost: 10,
startingBuilding: { id: 'wizards-hand', count: 5 },
isPurchased: false,
unlockCost: 0
},
{
id: 'well-keeper',
name: 'Well Keeper',
description: 'Wishing Well coin generation doubled.',
flavorText: 'The well remembers your generosity.',
cost: 15,
isWellBoost: true,
isPurchased: false,
unlockCost: 0
}
// Future prestige upgrades go here
];

// Calculate Mana Crystals from total mana using Cookie Clicker formula
Expand Down Expand Up @@ -718,6 +801,26 @@ const PrestigeModule = (function() {
prestigeUpgrades.forEach(u => u.isPurchased = false);
}

function hasAutoClicker() {
const upgrade = prestigeUpgrades.find(u => u.id === 'arcane-auto-gather');
return upgrade && upgrade.isPurchased;
}

function hasRunestoneBoost() {
const upgrade = prestigeUpgrades.find(u => u.id === 'runestone-affinity');
return upgrade && upgrade.isPurchased;
}

function hasSpellRegenBoost() {
const upgrade = prestigeUpgrades.find(u => u.id === 'spell-power-reservoir');
return upgrade && upgrade.isPurchased;
}

function hasWellBoost() {
const upgrade = prestigeUpgrades.find(u => u.id === 'well-keeper');
return upgrade && upgrade.isPurchased;
}

function getPrestigeUpgrades() {
return prestigeUpgrades;
}
Expand Down Expand Up @@ -745,6 +848,10 @@ const PrestigeModule = (function() {
getPrestigeUpgrades,
getStartingMana,
getStartingBuildings,
hasAutoClicker,
hasRunestoneBoost,
hasSpellRegenBoost,
hasWellBoost,
addPrestigePotential,
getPrestigePotential,
getHighestPotentialTier,
Expand Down
6 changes: 5 additions & 1 deletion modules/runestones.js
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,11 @@ const RunestonesModule = (function() {
];

function getRandomSpawnInterval() {
return Math.floor(Math.random() * (MAX_SPAWN_INTERVAL - MIN_SPAWN_INTERVAL)) + MIN_SPAWN_INTERVAL;
let interval = Math.floor(Math.random() * (MAX_SPAWN_INTERVAL - MIN_SPAWN_INTERVAL)) + MIN_SPAWN_INTERVAL;
if (typeof PrestigeModule !== 'undefined' && PrestigeModule.hasRunestoneBoost && PrestigeModule.hasRunestoneBoost()) {
interval = Math.floor(interval * 0.7);
}
return interval;
}

function init() {
Expand Down
8 changes: 6 additions & 2 deletions modules/spellcasting.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,13 @@ const SpellcastingModule = (function() {

// Update spell timers (called every 100ms from game loop)
function update(deltaSeconds) {
// Regenerate spell power
// Regenerate spell power (with optional prestige boost)
if (spellPower < MAX_SPELL_POWER) {
spellPower = Math.min(MAX_SPELL_POWER, spellPower + SPELL_POWER_REGEN_RATE * deltaSeconds);
let regenRate = SPELL_POWER_REGEN_RATE;
if (typeof PrestigeModule !== 'undefined' && PrestigeModule.hasSpellRegenBoost && PrestigeModule.hasSpellRegenBoost()) {
regenRate *= 1.5;
}
spellPower = Math.min(MAX_SPELL_POWER, spellPower + regenRate * deltaSeconds);
}

// Update active spell durations
Expand Down