Skip to content

Commit e9d5391

Browse files
factory test
1 parent 902f169 commit e9d5391

File tree

14 files changed

+212
-112
lines changed

14 files changed

+212
-112
lines changed

src/Client.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,11 +324,11 @@ export default class Client {
324324
this.setHasCheated(true);
325325

326326
player.destroy();
327-
player.onKill(player);
328327
player.onDeath(player);
328+
player.onKill(player);
329329
}
330330
}
331-
331+
332332
return;
333333
}
334334
case ServerBound.Spawn: {

src/Entity/Misc/Mothership.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ export default class Mothership extends TankBody {
8989
this.game.broadcast()
9090
.u8(ClientBound.Notification)
9191
// If mothership has a team name, use it, otherwise just say has destroyed a mothership
92-
.stringNT(`${killerTeamIsATeam ? (killerTeam.teamName || "a mysterious group") : (killer.nameData?.values.name || "an unnamed tank")} has destroyed ${teamIsATeam ? team.teamName + "'s" : "a"} Mothership!`)
92+
.stringNT(`${killerTeamIsATeam ? (killerTeam.teamName || "a mysterious group") : (killer.nameData?.values.name || "an unnamed tank")} has destroyed ${teamIsATeam ? (team.teamName || "a mysterious group") + "'s" : "a"} Mothership!`)
9393
.u32(killerTeamIsATeam ? ColorsHexCode[killerTeam.teamData.values.teamColor] : 0x000000)
9494
.float(-1)
9595
.stringNT("").send();

src/Entity/Misc/TeamBase.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import GameServer from "../../Game";
2020

2121
import { HealthFlags, PhysicsFlags, StyleFlags } from "../../Const/Enums";
22-
import { TeamGroupEntity } from "./TeamEntity";
22+
import { TeamEntity, TeamGroupEntity } from "./TeamEntity";
2323
import LivingEntity from "../Live";
2424
import BaseDrones from "./BaseDrones";
2525
/**
@@ -34,6 +34,8 @@ export default class TeamBase extends LivingEntity {
3434

3535
this.relationsData.values.team = team;
3636

37+
if (team instanceof TeamEntity) team.base = this;
38+
3739
this.positionData.values.x = x;
3840
this.positionData.values.y = y;
3941

src/Entity/Misc/TeamEntity.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
*/
1818

1919
import GameServer from "../../Game";
20+
import TeamBase from "./TeamBase";
21+
import ObjectEntity from "../Object";
22+
import TankBody from "../Tank/TankBody";
2023

2124
import { Color } from "../../Const/Enums";
2225
import { Entity } from "../../Native/Entity";
@@ -51,6 +54,9 @@ export class TeamEntity extends Entity implements TeamGroupEntity {
5154

5255
/** Used for notifications in team based gamemodes */
5356
public teamName: string;
57+
58+
/** The team's spawn base. */
59+
public base: TeamBase | null = null;
5460

5561
public constructor(game: GameServer, color: Color, name: string = ColorsTeamName[color] || "UNKNOWN") {
5662
super(game);
@@ -64,4 +70,16 @@ export class TeamEntity extends Entity implements TeamGroupEntity {
6470

6571
return !!entity.teamData;
6672
}
73+
74+
public static setTeam(team: TeamGroupEntity, entity: ObjectEntity) {
75+
if (!Entity.exists(entity)) return;
76+
77+
entity.relationsData.values.team = team;
78+
79+
entity.styleData.values.color = team.teamData.values.teamColor;
80+
81+
if (TankBody.isTank(entity)) {
82+
entity.cameraEntity.relationsData.values.team = team;
83+
}
84+
}
6785
}

src/Entity/Object.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
import * as util from "../util";
2020
import GameServer from "../Game";
21-
import Vector from "../Physics/Vector";
21+
import Vector, { VectorAbstract } from "../Physics/Vector";
2222

2323
import { PhysicsGroup, PositionGroup, RelationsGroup, StyleGroup } from "../Native/FieldGroups";
2424
import { Entity } from "../Native/Entity";
@@ -204,6 +204,34 @@ export default class ObjectEntity extends Entity {
204204
return dX*dX + dY*dY <= rSum*rSum;
205205
}
206206
}
207+
208+
/** Returns a random position inside the given entity. */
209+
public static getRandomPosition(entity: ObjectEntity): VectorAbstract {
210+
if (entity.isChild) util.warn("Attached entities are not fully supported by physics engine for now");
211+
212+
const pos = {
213+
x: entity.positionData.values.x,
214+
y: entity.positionData.values.y
215+
}
216+
217+
const isRect = entity.physicsData.values.sides === 2;
218+
219+
if (isRect) { // Rectangular hitbox
220+
const xOffset = (Math.random() - 0.5) * entity.physicsData.values.size,
221+
yOffset = (Math.random() - 0.5) * entity.physicsData.values.width;
222+
223+
pos.x += xOffset;
224+
pos.y += yOffset;
225+
} else { // Circular hitbox
226+
const radius = Math.random() * entity.physicsData.values.size;
227+
const angle = Math.random() * util.PI2;
228+
229+
pos.x += Math.cos(angle) * radius;
230+
pos.y += Math.sin(angle) * radius;
231+
}
232+
233+
return pos;
234+
}
207235

208236
/** Calls the deletion animation, unless animate is set to false, in that case it instantly deletes. */
209237
public destroy(animate = true) {

src/Gamemodes/Domination.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import Client from "../Client";
2020
import { Color, ColorsHexCode, ArenaFlags, ValidScoreboardIndex, ClientBound } from "../Const/Enums";
21+
import ObjectEntity from "../Entity/Object";
2122
import Dominator from "../Entity/Misc/Dominator";
2223
import TeamBase from "../Entity/Misc/TeamBase";
2324
import { TeamEntity } from "../Entity/Misc/TeamEntity";
@@ -81,26 +82,25 @@ export default class DominationArena extends ArenaEntity {
8182
NE.prefix = "NE ";
8283
this.dominators.push(SE, SW, NW, NE);
8384
}
84-
85-
public spawnPlayer(tank: TankBody, client: Client) {
86-
tank.positionData.values.y = arenaSize * Math.random() - arenaSize;
87-
88-
const xOffset = (Math.random() - 0.5) * baseSize,
89-
yOffset = (Math.random() - 0.5) * baseSize;
90-
91-
const team = this.playerTeamMap.get(client) || randomFrom(this.teams);
92-
const teamBase: TeamBase = this.game.entities.inner.find((entity) => entity instanceof TeamBase && entity.relationsData.values.team === team) as TeamBase;
93-
94-
tank.relationsData.values.team = teamBase.relationsData.values.team;
95-
tank.styleData.values.color = teamBase.styleData.values.color;
96-
tank.positionData.values.x = teamBase.positionData.values.x + xOffset;
97-
tank.positionData.values.y = teamBase.positionData.values.y + yOffset;
85+
86+
public decideTeam(client: Client): TeamEntity {
87+
const team = this.playerTeamMap.get(client) || randomFrom(this.teams);
9888
this.playerTeamMap.set(client, team);
9989

100-
if (client.camera) client.camera.relationsData.team = tank.relationsData.values.team;
90+
return team;
91+
}
92+
93+
public spawnPlayer(tank: TankBody, client: Client) {
94+
const team = this.decideTeam(client);
95+
const teamBase = team.base as TeamBase;
96+
TeamEntity.setTeam(team, tank);
97+
98+
const pos = ObjectEntity.getRandomPosition(teamBase);
99+
tank.positionData.values.x = pos.x;
100+
tank.positionData.values.y = pos.y;
101101
}
102102

103-
public getTeamDominatorCount(team: TeamEntity) {
103+
public getTeamDominatorCount(team: TeamEntity): number {
104104
let doms: number = 0;
105105
for (const dominator of this.dominators) {
106106
if (dominator.relationsData.values.team === team) doms++;

src/Gamemodes/Mothership.ts

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,18 @@ export default class MothershipArena extends ArenaEntity {
3737

3838
/** All team entities in game */
3939
public teams: TeamEntity[] = [];
40+
4041
/** Motherships in game */
4142
public motherships: Mothership[] = [];
4243

43-
/** Maps clients to their mothership */
44-
public playerTeamMotMap: WeakMap<Client, Mothership> = new WeakMap();
44+
/** Maps clients to their team */
45+
public playerTeamMap: WeakMap<Client, TeamEntity> = new WeakMap();
4546

4647
public constructor(game: GameServer) {
4748
super(game);
49+
50+
this.updateBounds(arenaSize * 2, arenaSize * 2);
51+
4852
this.shapeScoreRewardMultiplier = 3.0;
4953

5054
this.arenaData.values.flags |= ArenaFlags.hiddenScores;
@@ -59,41 +63,34 @@ export default class MothershipArena extends ArenaEntity {
5963

6064
mot.relationsData.values.team = team;
6165
mot.styleData.values.color = team.teamData.values.teamColor;
62-
mot.positionData.values.x = Math.cos(randAngle) * arenaSize * 0.75;
63-
mot.positionData.values.y = Math.sin(randAngle) * arenaSize * 0.75;
66+
mot.positionData.values.x = Math.cos(randAngle) * arenaSize * 0.8;
67+
mot.positionData.values.y = Math.sin(randAngle) * arenaSize * 0.8;
6468

6569
randAngle += PI2 / TEAM_COLORS.length;
6670
}
71+
}
72+
73+
public decideTeam(client: Client): TeamEntity {
74+
const team = this.playerTeamMap.get(client) || randomFrom(this.teams);
75+
this.playerTeamMap.set(client, team);
6776

68-
this.updateBounds(arenaSize * 2, arenaSize * 2);
77+
return team;
6978
}
7079

7180
public spawnPlayer(tank: TankBody, client: Client) {
72-
if (!this.motherships.length && !this.playerTeamMotMap.has(client)) {
73-
const team = randomFrom(this.teams);
74-
const { x, y } = this.findPlayerSpawnLocation();
75-
76-
tank.positionData.values.x = x;
77-
tank.positionData.values.y = y;
78-
tank.relationsData.values.team = team;
79-
tank.styleData.values.color = team.teamData.teamColor;
80-
return;
81-
}
82-
83-
const mothership = this.playerTeamMotMap.get(client) || randomFrom(this.motherships);
84-
this.playerTeamMotMap.set(client, mothership);
81+
const team = this.decideTeam(client);
82+
TeamEntity.setTeam(team, tank);
8583

86-
tank.relationsData.values.team = mothership.relationsData.values.team;
87-
tank.styleData.values.color = mothership.styleData.values.color;
84+
const success = this.attemptFactorySpawn(tank);
85+
if (success) return; // This player was spawned from a factory instead
8886

8987
// TODO: Possess mothership if its unpossessed
9088
const { x, y } = this.findPlayerSpawnLocation();
9189

9290
tank.positionData.values.x = x;
9391
tank.positionData.values.y = y;
94-
95-
if (client.camera) client.camera.relationsData.team = tank.relationsData.values.team;
9692
}
93+
9794
public updateScoreboard() {
9895
this.motherships.sort((m1, m2) => m2.healthData.values.health - m1.healthData.values.health);
9996

@@ -113,6 +110,7 @@ export default class MothershipArena extends ArenaEntity {
113110

114111
this.arenaData.scoreboardAmount = length;
115112
}
113+
116114
public updateArenaState() {
117115
// backwards to preserve
118116
for (let i = this.motherships.length; i --> 0;) {

src/Gamemodes/Survival.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import TankBody from "../Entity/Tank/TankBody";
2424

2525
import ShapeManager from "../Misc/ShapeManager";
2626
import { ArenaFlags, ClientBound } from "../Const/Enums";
27-
import { tps, countdownTicks, scoreboardUpdateInterval } from "../config";
27+
import { tps, countdownDuration, scoreboardUpdateInterval } from "../config";
2828

2929
const MIN_PLAYERS = 4; // 6 in Diep.io
3030

@@ -104,7 +104,7 @@ export default class SurvivalArena extends ArenaEntity {
104104
if (this.arenaData.values.playersNeeded <= 0) {
105105
this.arenaData.flags |= ArenaFlags.gameReadyStart;
106106
} else {
107-
this.arenaData.ticksUntilStart = countdownTicks; // Reset countdown
107+
this.arenaData.ticksUntilStart = countdownDuration; // Reset countdown
108108
if (this.arenaData.flags & ArenaFlags.gameReadyStart) this.arenaData.flags &= ~ArenaFlags.gameReadyStart;
109109
}
110110
}

src/Gamemodes/Tag.ts

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,13 @@ export default class TagArena extends ArenaEntity {
8787

8888
this.updateBounds(ARENA_SIZE * 2, ARENA_SIZE * 2);
8989
}
90+
91+
public decideTeam(client: Client): TeamEntity {
92+
const team = this.playerTeamMap.get(client) || (this.getAlivePlayers().length <= MIN_PLAYERS ? this.teams[this.teams.length - 1] : this.teams[0]); // If there are not enough players to start the game, choose the team with least players. Otherwise choose the one with highest player count
93+
this.playerTeamMap.set(client, team);
94+
95+
return team;
96+
}
9097

9198
public spawnPlayer(tank: TankBody, client: Client) {
9299
const deathMixin = tank.onDeath.bind(tank);
@@ -105,33 +112,16 @@ export default class TagArena extends ArenaEntity {
105112
else this.playerTeamMap.set(client, team);
106113
}
107114

108-
if (!this.playerTeamMap.has(client)) {
109-
const team = this.getAlivePlayers().length <= MIN_PLAYERS ? this.teams[this.teams.length - 1] :
110-
this.teams[0]; // If there are not enough players to start the game, choose the team with least players. Otherwise choose the one with highest player count
111-
const { x, y } = this.findPlayerSpawnLocation();
112-
113-
tank.positionData.values.x = x;
114-
tank.positionData.values.y = y;
115-
tank.relationsData.values.team = team;
116-
tank.styleData.values.color = team.teamData.teamColor;
117-
118-
this.playerTeamMap.set(client, team)
119-
return;
120-
}
121-
122-
const team = this.playerTeamMap.get(client) || this.teams[0];
115+
const team = this.decideTeam(client);
116+
TeamEntity.setTeam(team, tank);
123117

124-
this.playerTeamMap.set(client, team);
125-
126-
tank.relationsData.values.team = team;
127-
tank.styleData.values.color = team.teamData.values.teamColor;
118+
const success = this.attemptFactorySpawn(tank);
119+
if (success) return; // This player was spawned from a factory instead
128120

129121
const { x, y } = this.findPlayerSpawnLocation();
130122

131123
tank.positionData.values.x = x;
132124
tank.positionData.values.y = y;
133-
134-
if (client.camera) client.camera.relationsData.team = tank.relationsData.values.team;
135125
}
136126

137127
public updateScoreboard() {

src/Gamemodes/Team2.ts

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import GameServer from "../Game";
2020
import ArenaEntity from "../Native/Arena";
2121
import Client from "../Client";
2222

23+
import ObjectEntity from "../Entity/Object";
2324
import TeamBase from "../Entity/Misc/TeamBase";
2425
import TankBody from "../Entity/Tank/TankBody";
2526

@@ -37,30 +38,40 @@ export default class Teams2Arena extends ArenaEntity {
3738
static override GAMEMODE_ID: string = "teams";
3839

3940
/** Blue Team entity */
40-
public blueTeamBase: TeamBase;
41+
public blueTeamEntity: TeamEntity;
4142
/** Red Team entity */
42-
public redTeamBase: TeamBase;
43+
public redTeamEntity: TeamEntity;
4344
/** Maps clients to their teams */
44-
public playerTeamMap: WeakMap<Client, TeamBase> = new WeakMap();
45+
public playerTeamMap: WeakMap<Client, TeamEntity> = new WeakMap();
4546

4647
public constructor(game: GameServer) {
4748
super(game);
4849
this.updateBounds(arenaSize * 2, arenaSize * 2);
49-
this.blueTeamBase = new TeamBase(game, new TeamEntity(this.game, Color.TeamBlue), -arenaSize + baseWidth / 2, 0, arenaSize * 2, baseWidth, true, 12, 2);
50-
this.redTeamBase = new TeamBase(game, new TeamEntity(this.game, Color.TeamRed), arenaSize - baseWidth / 2, 0, arenaSize * 2, baseWidth, true, 12, 2);
50+
51+
this.blueTeamEntity = new TeamEntity(this.game, Color.TeamBlue);
52+
this.redTeamEntity = new TeamEntity(this.game, Color.TeamRed);
53+
54+
new TeamBase(game, this.blueTeamEntity, -arenaSize + baseWidth / 2, 0, arenaSize * 2, baseWidth, true, 12, 2);
55+
new TeamBase(game, this.redTeamEntity, arenaSize - baseWidth / 2, 0, arenaSize * 2, baseWidth, true, 12, 2);
5156
}
5257

53-
public spawnPlayer(tank: TankBody, client: Client) {
54-
tank.positionData.values.y = 2 * arenaSize * Math.random() - arenaSize;
58+
public decideTeam(client: Client): TeamEntity {
59+
const team = this.playerTeamMap.get(client) || randomFrom([this.blueTeamEntity, this.redTeamEntity]);
60+
this.playerTeamMap.set(client, team);
5561

56-
const xOffset = (Math.random() - 0.5) * baseWidth;
62+
return team;
63+
}
64+
65+
public spawnPlayer(tank: TankBody, client: Client) {
66+
const team = this.decideTeam(client);
67+
TeamEntity.setTeam(team, tank);
5768

58-
const base = this.playerTeamMap.get(client) || randomFrom([this.blueTeamBase, this.redTeamBase]);
59-
tank.relationsData.values.team = base.relationsData.values.team;
60-
tank.styleData.values.color = base.styleData.values.color;
61-
tank.positionData.values.x = base.positionData.values.x + xOffset;
62-
this.playerTeamMap.set(client, base);
69+
const success = this.attemptFactorySpawn(tank);
70+
if (success) return; // This player was spawned from a factory instead
6371

64-
if (client.camera) client.camera.relationsData.team = tank.relationsData.values.team;
72+
const base = team.base as TeamBase;
73+
const pos = ObjectEntity.getRandomPosition(base);
74+
tank.positionData.x = pos.x;
75+
tank.positionData.y = pos.y;
6576
}
6677
}

0 commit comments

Comments
 (0)