generated from nhcarrigan/template
feat: initial elysium idle game prototype
Sets up the full monorepo with pnpm workspaces. Includes shared types package, Hono API with Discord OAuth/JWT auth, Prisma v6 + MongoDB Atlas, and React + Vite frontend with game loop, five tabs, and Discord-linked save/load.
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
import type { GameState } from "@elysium/types";
|
||||
|
||||
const MAX_OFFLINE_SECONDS = 8 * 60 * 60; // 8 hours
|
||||
|
||||
/**
|
||||
* Calculates the gold earned whilst the player was offline.
|
||||
* Capped at 8 hours to prevent exploit via system clock manipulation.
|
||||
*/
|
||||
export const calculateOfflineGold = (
|
||||
state: GameState,
|
||||
nowMs: number,
|
||||
): { offlineGold: number; offlineSeconds: number } => {
|
||||
const elapsedSeconds = Math.min(
|
||||
(nowMs - state.lastTickAt) / 1000,
|
||||
MAX_OFFLINE_SECONDS,
|
||||
);
|
||||
|
||||
const goldPerSecond = state.adventurers.reduce((total, adventurer) => {
|
||||
if (!adventurer.unlocked || adventurer.count === 0) {
|
||||
return total;
|
||||
}
|
||||
|
||||
const upgradeMultiplier = state.upgrades
|
||||
.filter(
|
||||
(u) =>
|
||||
u.purchased &&
|
||||
(u.target === "global" ||
|
||||
(u.target === "adventurer" && u.adventurerId === adventurer.id)),
|
||||
)
|
||||
.reduce((mult, u) => mult * u.multiplier, 1);
|
||||
|
||||
return (
|
||||
total +
|
||||
adventurer.goldPerSecond *
|
||||
adventurer.count *
|
||||
upgradeMultiplier *
|
||||
state.prestige.productionMultiplier
|
||||
);
|
||||
}, 0);
|
||||
|
||||
return {
|
||||
offlineGold: goldPerSecond * elapsedSeconds,
|
||||
offlineSeconds: elapsedSeconds,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user