Skip to content

Commit f399031

Browse files
Spawning cleanup
1 parent e41a432 commit f399031

File tree

1 file changed

+30
-40
lines changed

1 file changed

+30
-40
lines changed

src/Native/Arena.ts

Lines changed: 30 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818

1919
import GameServer from "../Game";
2020
import ShapeManager from "../Misc/ShapeManager";
21+
import BossManager from "../Misc/BossManager";
2122
import TankBody from "../Entity/Tank/TankBody";
2223
import ArenaCloser from "../Entity/Misc/ArenaCloser";
24+
import AbstractBoss from "../Entity/Boss/AbstractBoss";
2325

2426
import { VectorAbstract } from "../Physics/Vector";
2527
import { ArenaGroup, TeamGroup } from "./FieldGroups";
@@ -30,13 +32,6 @@ import { TeamGroupEntity } from "../Entity/Misc/TeamEntity";
3032

3133
import Client from "../Client";
3234

33-
import AbstractBoss from "../Entity/Boss/AbstractBoss";
34-
import Guardian from "../Entity/Boss/Guardian";
35-
import Summoner from "../Entity/Boss/Summoner";
36-
import FallenOverlord from "../Entity/Boss/FallenOverlord";
37-
import FallenBooster from "../Entity/Boss/FallenBooster";
38-
import Defender from "../Entity/Boss/Defender";
39-
4035
import { countdownTicks, bossSpawningInterval, scoreboardUpdateInterval } from "../config";
4136

4237
export const enum ArenaState {
@@ -76,11 +71,8 @@ export default class ArenaEntity extends Entity implements TeamGroupEntity {
7671

7772
public shapeScoreRewardMultiplier: number = 1;
7873

79-
/** Enable or disable natural boss spawning */
80-
public allowBoss: boolean = true;
81-
82-
/** The current boss spawned into the game */
83-
public boss: AbstractBoss | null = null;
74+
/** The boss spawner. Set to null in gamemode file to disable boss spawning. */
75+
public bossManager: BossManager | null = new BossManager(this);
8476

8577
/** Scoreboard leader */
8678
public leader: TankBody | null = null;
@@ -134,21 +126,18 @@ export default class ArenaEntity extends Entity implements TeamGroupEntity {
134126
}
135127

136128
/**
137-
* Finds a spawnable location on the map.
129+
* Finds a spawnable location on the map within the given width and height.
138130
*/
139-
public findSpawnLocation(isPlayer: boolean=false): VectorAbstract {
131+
public findSpawnLocation(width: number = this.width, height: number = this.height): VectorAbstract {
140132
const pos = {
141-
x: ~~(Math.random() * this.width - this.width / 2),
142-
y: ~~(Math.random() * this.height - this.height / 2),
133+
x: ~~(Math.random() * width - width / 2),
134+
y: ~~(Math.random() * height - height / 2),
143135
}
144136

145137
for (let i = 0; i < 20; ++i) {
146-
if (
147-
!this.isValidSpawnLocation(pos.x, pos.y) ||
148-
isPlayer && Math.max(pos.x, pos.y) < this.arenaData.values.rightX / 2 && Math.min(pos.x, pos.y) > this.arenaData.values.leftX / 2
149-
) {
150-
pos.x = ~~(Math.random() * this.width - this.width / 2);
151-
pos.y = ~~(Math.random() * this.height - this.height / 2);
138+
if (!this.isValidSpawnLocation(pos.x, pos.y)) {
139+
pos.x = ~~(Math.random() * width - width / 2);
140+
pos.y = ~~(Math.random() * height - height / 2);
152141
continue;
153142
}
154143

@@ -163,8 +152,8 @@ export default class ArenaEntity extends Entity implements TeamGroupEntity {
163152
});
164153

165154
if (entity) {
166-
pos.x = ~~(Math.random() * this.width - this.width / 2);
167-
pos.y = ~~(Math.random() * this.height - this.height / 2);
155+
pos.x = ~~(Math.random() * width - width / 2);
156+
pos.y = ~~(Math.random() * height - height / 2);
168157
continue;
169158
}
170159

@@ -174,6 +163,21 @@ export default class ArenaEntity extends Entity implements TeamGroupEntity {
174163
return pos;
175164
}
176165

166+
public findPlayerSpawnLocation(): VectorAbstract {
167+
let pos = this.findSpawnLocation();
168+
for (let i = 0; i < 20; ++i) {
169+
if (
170+
Math.max(pos.x, pos.y) < this.arenaData.values.rightX / 2 &&
171+
Math.min(pos.x, pos.y) > this.arenaData.values.leftX / 2
172+
) {
173+
pos = this.findSpawnLocation(); // Players spawn away from the center
174+
continue;
175+
}
176+
break;
177+
}
178+
return pos;
179+
}
180+
177181
/** Checks if players or shapes can spawn at the given coordinates. */
178182
public isValidSpawnLocation(x: number, y: number): boolean {
179183
// Override in gamemode files
@@ -301,7 +305,7 @@ export default class ArenaEntity extends Entity implements TeamGroupEntity {
301305
* Allows the arena to decide how players are spawned into the game.
302306
*/
303307
public spawnPlayer(tank: TankBody, client: Client) {
304-
const { x, y } = this.findSpawnLocation(true);
308+
const { x, y } = this.findPlayerSpawnLocation();
305309

306310
tank.positionData.values.x = x;
307311
tank.positionData.values.y = y;
@@ -337,18 +341,6 @@ export default class ArenaEntity extends Entity implements TeamGroupEntity {
337341
this.state = ArenaState.OPEN;
338342
}
339343

340-
/** Spawns the boss into the arena */
341-
protected spawnBoss() {
342-
const TBoss = [Guardian, Summoner, FallenOverlord, FallenBooster, Defender]
343-
[~~(Math.random() * 5)];
344-
345-
this.boss = new TBoss(this.game);
346-
347-
const { x, y } = this.game.arena.findSpawnLocation();
348-
this.boss.positionData.values.x = x;
349-
this.boss.positionData.values.y = y;
350-
}
351-
352344
public tick(tick: number) {
353345
this.shapes.tick();
354346
this.updateArenaState();
@@ -359,8 +351,6 @@ export default class ArenaEntity extends Entity implements TeamGroupEntity {
359351
this.arenaData.leaderY = this.leader.positionData.values.y;
360352
}
361353

362-
if (this.allowBoss && this.game.tick >= 1 && (this.game.tick % bossSpawningInterval) === 0 && !this.boss) {
363-
this.spawnBoss();
364-
}
354+
this.bossManager?.tick(tick);
365355
}
366356
}

0 commit comments

Comments
 (0)