- Game state with localStorage save/load + reset (type DELETE to confirm) - Alpine.js + Tailwind CSS + Lucide UI overlay (HUD bar, shop modal, settings, toasts) - Economy: fish prices, tank tier costs/capacities, rarity multipliers, sell value formula - Genetic system: hue/saturation/size/speed/pattern/rarity/gender + breeding inheritance - Fish selection via raycaster (click fish = select, click empty = drop food) - Buy/Sell/Breed/Upgrade actions wired to game state
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
import type { FishData, FishSpecies, Rarity } from "./types";
|
||||
import { RARITY_MULT } from "./types";
|
||||
|
||||
/** Base prices for buying fish (shop) */
|
||||
export const FISH_PRICES: Record<FishSpecies, number> = {
|
||||
angelfish: 100,
|
||||
goldfish: 80,
|
||||
guppy: 60,
|
||||
fish1: 50,
|
||||
fish2: 70,
|
||||
fish3: 65,
|
||||
};
|
||||
|
||||
/** Cost to upgrade TO tank tier (index = target tier) */
|
||||
export const TANK_TIER_COSTS: number[] = [0, 500, 1500, 4000];
|
||||
|
||||
/** Tank tier capacities */
|
||||
export const TANK_CAPACITY: number[] = [12, 20, 30, 45];
|
||||
|
||||
/** Tank tier names */
|
||||
export const TANK_TIER_NAMES: string[] = ["Small", "Medium", "Large", "XL"];
|
||||
|
||||
/** Tank tier dimensions */
|
||||
export const TANK_TIER_DIMS: { w: number; h: number; d: number; camZ: number; cap: number }[] = [
|
||||
{ w: 4, h: 2.5, d: 3, camZ: 6, cap: 12 },
|
||||
{ w: 6, h: 3.5, d: 4, camZ: 8, cap: 20 },
|
||||
{ w: 8, h: 4.5, d: 5, camZ: 10, cap: 30 },
|
||||
{ w: 10, h: 5, d: 6, camZ: 12, cap: 45 },
|
||||
];
|
||||
|
||||
/** Food prices */
|
||||
export const FOOD_PRICES: Record<string, number> = {
|
||||
basic: 10,
|
||||
premium: 30,
|
||||
special: 75,
|
||||
};
|
||||
|
||||
/** Decor prices */
|
||||
export const DECOR_PRICES: Record<string, number> = {
|
||||
plant0: 25,
|
||||
plant1: 40,
|
||||
rock0: 15,
|
||||
rock1: 20,
|
||||
rock2: 20,
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculate sell value of a fish.
|
||||
* Formula: basePrice * 0.6 * sizeMult * rarityMult * ageMult
|
||||
*/
|
||||
export function getFishSellValue(fish: FishData): number {
|
||||
const base = FISH_PRICES[fish.species] || 50;
|
||||
const ageMult = getAgeMultiplier(fish.age);
|
||||
const value = base * 0.6 * fish.genetics.sizeMult * RARITY_MULT[fish.genetics.rarity] * ageMult;
|
||||
return Math.round(value);
|
||||
}
|
||||
|
||||
/** Age-based value multiplier */
|
||||
function getAgeMultiplier(ageHours: number): number {
|
||||
if (ageHours < 24) return 0.5;
|
||||
if (ageHours < 72) return 0.8;
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
/** Get the display value breakdown for UI */
|
||||
export function getFishValueBreakdown(fish: FishData): { label: string; value: number }[] {
|
||||
const base = FISH_PRICES[fish.species] || 50;
|
||||
return [
|
||||
{ label: `Base (${fish.species})`, value: base },
|
||||
{ label: `Size (${fish.genetics.sizeMult.toFixed(2)}x)`, value: Math.round(base * 0.6 * fish.genetics.sizeMult) },
|
||||
{ label: `Rarity (${fish.genetics.rarity}, ${RARITY_MULT[fish.genetics.rarity]}x)`, value: Math.round(base * 0.6 * fish.genetics.sizeMult * RARITY_MULT[fish.genetics.rarity]) },
|
||||
{ label: "Total", value: getFishSellValue(fish) },
|
||||
];
|
||||
}
|
||||
|
||||
/** Species rarity distributions for shop rolls */
|
||||
export const SPECIES_RARITY_DIST: Record<FishSpecies, Record<Rarity, number>> = {
|
||||
angelfish: { common: 60, uncommon: 25, rare: 10, epic: 4, legendary: 1 },
|
||||
goldfish: { common: 65, uncommon: 20, rare: 9, epic: 5, legendary: 1 },
|
||||
guppy: { common: 70, uncommon: 18, rare: 7, epic: 4, legendary: 1 },
|
||||
fish1: { common: 75, uncommon: 15, rare: 6, epic: 3, legendary: 1 },
|
||||
fish2: { common: 65, uncommon: 20, rare: 10, epic: 4, legendary: 1 },
|
||||
fish3: { common: 68, uncommon: 18, rare: 9, epic: 4, legendary: 1 },
|
||||
};
|
||||
|
||||
/** Available species in shop */
|
||||
export const SHOP_SPECIES: FishSpecies[] = ["angelfish", "goldfish", "guppy", "fish1", "fish2", "fish3"];
|
||||
|
||||
/** Species display names */
|
||||
export const SPECIES_NAMES: Record<FishSpecies, string> = {
|
||||
angelfish: "Angelfish",
|
||||
goldfish: "Goldfish",
|
||||
guppy: "Guppy",
|
||||
fish1: "Cute Fish I",
|
||||
fish2: "Cute Fish II",
|
||||
fish3: "Cute Fish III",
|
||||
};
|
||||
Reference in New Issue
Block a user