File size: 4,870 Bytes
b29710c
 
 
 
 
 
9e6ef9c
 
 
 
 
 
 
 
b29710c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
import * as THREE from "three";

// Game settings
export const INITIAL_MONEY = 200;
export const INITIAL_LIVES = 10;

// Audio settings
export const AUDIO_CONFIG = {
  musicVolume: 0.4, // Background music volume (0-1)
  effectsVolume: 0.3, // Sound effects volume (0-1)
  musicEnabled: true, // Enable/disable background music
  effectsEnabled: true, // Enable/disable sound effects
};

// Tower settings
// Define multiple tower types, keeping the original as "basic"
export const TOWER_TYPES = {
  basic: {
    key: "basic",
    name: "Basic Tower",
    type: "basic",
    cost: 50,
    range: 9,
    fireRate: 1.0, // shots per second
    damage: 6,
  },
  slow: {
    key: "slow",
    name: "Slow Tower",
    type: "slow",
    cost: 60,
    range: 8.5,
    fireRate: 0.9,
    damage: 4,
    // On-hit slow: 40% slow (mult 0.6) for 2.5s, refresh on re-hit
    projectileEffect: {
      type: "slow",
      mult: 0.6,
      duration: 2.5,
      color: 0x80d8ff,
      emissive: 0x104a70,
    },
  },
  sniper: {
    key: "sniper",
    name: "Sniper Tower",
    type: "sniper",
    cost: 130,
    // 2x the range of basic
    range: 18,
    // slow fire rate
    fireRate: 0.7, // shots per second (reload ≈ 3.33s)
    damage: 32, // high damage per shot
    // Sniper specific parameters
    aimTime: 0.8, // seconds to aim before firing
    projectileSpeed: 40, // high-speed dart
    // Targeting priority identifier
    targetPriority: "closestToExit",
    // If target moves out of this threshold (>= range) during aiming, cancel
    cancelThreshold: 18,
    // Optional chance to pierce; behavior can be extended later
    pierceChance: 0.0,
  },
  electric: {
    key: "electric",
    name: "Electric Tower",
    type: "electric",
    cost: 200,
    // Set to the smallest tower range (slow tower = 8.5)
    range: 8.5, // world units (scene uses world units; 1 cell = 2 units, so ~4.25 cells)
    fireRate: 1.0, // shots per second
    damage: 25, // per target
    maxTargets: 3,
    // Persist electric arc visuals for 2 seconds
    arcDurationMs: 2000,
    // Visual tuning for arcs (can be read by Tower)
    arc: {
      color: 0x9ad6ff, // light electric blue
      coreColor: 0xe6fbff,
      thickness: 2,
      jitter: 0.25,
      segments: 10,
    },
    // Targeting priority
    targetPriority: "closestToExit",
  },
};
// Back-compat alias for existing code that expects TOWER_CONFIG
export const TOWER_CONFIG = TOWER_TYPES.basic;

// Projectile settings
export const PROJECTILE_SPEED = 18;

// Upgrade settings
export const UPGRADE_MAX_LEVEL = 5;
export const UPGRADE_START_COST = 40;
export const UPGRADE_COST_SCALE = 1.6;
export const UPGRADE_RANGE_SCALE = 1.1; // +10% per level
export const UPGRADE_RATE_SCALE = 1.15; // +15% per level
export const UPGRADE_DAMAGE_SCALE = 1.12; // +12% per level
export const SELL_REFUND_RATE = 0.7;

// Infinite wave scaling configuration (replaces static WAVES array)
export const WAVE_SCALING = {
  // base values (wave 1)
  baseCount: 8,
  baseHP: 12,
  baseSpeed: 3.0,
  baseReward: 5,
  baseSpawnInterval: 0.8,

  // per-wave growth (applied from wave 2 onward)
  countPerWave: 3, // +3 enemies each wave
  hpMultiplierPerWave: 1.15, // HP *= 1.18 each wave
  speedIncrementPerWave: 0.025, // +0.05 speed per wave
  rewardMultiplierPerWave: 1.03, // reward *= 1.03 each wave
  spawnIntervalDecayPerWave: 0.01, // -0.02s per wave

  // safeguards/limits
  minSpawnInterval: 0.3,
  maxSpeed: 5.5,
  roundCountToInt: true,
};

// Compute wave parameters for a given wave number (1-based)
export function getWaveParams(n) {
  const w = WAVE_SCALING;
  const waveNum = Math.max(1, Math.floor(n));

  const countBase = w.baseCount + (waveNum - 1) * w.countPerWave;
  const count = w.roundCountToInt
    ? Math.max(1, Math.round(countBase))
    : Math.max(1, countBase);

  const hp = Math.max(
    1,
    Math.round(w.baseHP * Math.pow(w.hpMultiplierPerWave, waveNum - 1))
  );

  const speed = Math.min(
    w.maxSpeed,
    w.baseSpeed + (waveNum - 1) * w.speedIncrementPerWave
  );

  const reward = Math.max(
    1,
    Math.round(w.baseReward * Math.pow(w.rewardMultiplierPerWave, waveNum - 1))
  );

  const spawnInterval = Math.max(
    w.minSpawnInterval,
    w.baseSpawnInterval - (waveNum - 1) * w.spawnIntervalDecayPerWave
  );

  return { count, hp, speed, reward, spawnInterval };
}

// Path waypoints
export const PATH_POINTS = [
  new THREE.Vector3(-24, 0, -24),
  new THREE.Vector3(-24, 0, 0),
  new THREE.Vector3(0, 0, 0),
  new THREE.Vector3(0, 0, 16),
  new THREE.Vector3(20, 0, 16),
  new THREE.Vector3(26, 0, 26),
];

// Grid settings
export const GROUND_SIZE = 60;
export const GRID_CELL_SIZE = 2;

// Visual settings
export const SCENE_BACKGROUND = 0x202432;

// Road settings
export const ROAD_HALF_WIDTH = 1.5;
export const ROAD_BEVEL_SIZE = 1.2;
export const ROAD_ARC_SEGMENTS = 16;