Skip to content

Commit 69d1f08

Browse files
author
Picoseconds
committed
feat: added pit traps and spikes
1 parent 15e7b99 commit 69d1f08

File tree

8 files changed

+162
-16
lines changed

8 files changed

+162
-16
lines changed

src/gameobjects/GameObject.ts

+18-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import Vec2 from "vec2";
22
import { GameObjectType } from './gameobjects';
3+
import Player from "../moomoo/Player";
4+
import { Tribe } from "../moomoo/Tribes";
35

46
export default class GameObject {
57
constructor(
@@ -10,7 +12,8 @@ export default class GameObject {
1012
public type: GameObjectType = GameObjectType.Tree,
1113
public realScale: number = scale,
1214
public data: any = null,
13-
public ownerSID: number = -1
15+
public ownerSID: number = -1,
16+
public health: number = -1
1417
) {}
1518

1619
getData() {
@@ -25,4 +28,18 @@ export default class GameObject {
2528
this.ownerSID
2629
];
2730
}
31+
32+
isPlayerGameObject() {
33+
return this.type === -1 && typeof this.data === 'number';
34+
}
35+
36+
isEnemy(player: Player, tribes: Tribe[]) {
37+
if (this.ownerSID === player.id) return false;
38+
39+
for (let tribe of tribes) {
40+
if (tribe.membersSIDs.includes(player.id) && tribe.membersSIDs.includes(this.ownerSID)) return false;
41+
}
42+
43+
return true;
44+
}
2845
}

src/items/items.ts

+44-2
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,53 @@ function getGameObjID(item: ItemType) {
152152
}
153153

154154
function hasCollision(item: ItemType) {
155-
return items[item].group.layer >= 1;
155+
return items[item].group.layer >= 0;
156156
}
157157

158158
function getWeaponSpeedMultiplier(weapon: Weapons) {
159159
return weapons[weapon].spdMult || 1;
160160
}
161161

162-
export { PrimaryWeapons, SecondaryWeapons, getHitTime, Weapons, getWeaponAttackDetails, getWeaponDamage, getItemCost, getPlaceable, getPlaceOffset, getScale, getGameObjID, getWeaponGatherAmount, getPrerequisiteItem, getGroupID, getPrerequisiteWeapon, getWeaponSpeedMultiplier, hasCollision };
162+
function getStructureDamage(weapon: Weapons) {
163+
let weaponData = weapons[weapon];
164+
165+
if (weaponData.dmg) {
166+
if (weaponData.sDmg)
167+
return weaponData.dmg * weaponData.sDmg;
168+
169+
return weaponData.dmg;
170+
}
171+
172+
return 0;
173+
}
174+
175+
function getGameObjHealth(item: ItemType) {
176+
return items[item].health || -1;
177+
}
178+
179+
function getGameObjDamage(item: ItemType) {
180+
return items[item].dmg || 0;
181+
}
182+
183+
export {
184+
PrimaryWeapons,
185+
SecondaryWeapons,
186+
getHitTime,
187+
Weapons,
188+
getWeaponAttackDetails,
189+
getWeaponDamage,
190+
getItemCost,
191+
getPlaceable,
192+
getPlaceOffset,
193+
getScale,
194+
getGameObjID,
195+
getWeaponGatherAmount,
196+
getPrerequisiteItem,
197+
getGroupID,
198+
getPrerequisiteWeapon,
199+
getWeaponSpeedMultiplier,
200+
hasCollision,
201+
getStructureDamage,
202+
getGameObjHealth,
203+
getGameObjDamage
204+
};

src/moomoo/Game.ts

+37-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import GameObject from "../gameobjects/GameObject";
1414
import { PacketType } from "../packets/PacketType";
1515
import FileAsync from 'lowdb/adapters/FileAsync';
1616
import { PacketFactory } from "../packets/PacketFactory";
17-
import { getWeaponDamage, getWeaponAttackDetails, getItemCost, getPlaceable, PrimaryWeapons, getWeaponGatherAmount, getPrerequisiteItem, getGroupID, Weapons, getPrerequisiteWeapon, getPlaceOffset, getWeaponSpeedMultiplier } from "../items/items";
17+
import { getWeaponDamage, getWeaponAttackDetails, getItemCost, getPlaceable, PrimaryWeapons, getWeaponGatherAmount, getPrerequisiteItem, getGroupID, Weapons, getPrerequisiteWeapon, getPlaceOffset, getWeaponSpeedMultiplier, getStructureDamage } from "../items/items";
1818
import { gameObjectSizes, GameObjectType } from "../gameobjects/gameobjects";
1919
import { getUpgrades, getWeaponUpgrades } from './Upgrades';
2020
import { getHat } from './Hats';
@@ -507,6 +507,42 @@ export default class Game {
507507
}
508508

509509
for (let hitGameObject of hitGameObjects) {
510+
if (hitGameObject.health !== -1) {
511+
let dmgMult = 1;
512+
let hat = getHat(player.hatID);
513+
514+
if (hat && hat.bDmg)
515+
dmgMult *= hat.bDmg;
516+
517+
hitGameObject.health -= getStructureDamage(player.selectedWeapon) * dmgMult;
518+
519+
if (hitGameObject.health <= 0) {
520+
let itemCost = getItemCost(hitGameObject.data);
521+
let costs = chunk(itemCost, 2);
522+
523+
for (let cost of costs) {
524+
switch (cost[0]) {
525+
case "food":
526+
player.food += cost[1] as number;
527+
break;
528+
case "wood":
529+
player.wood += cost[1] as number;
530+
break;
531+
case "stone":
532+
player.stone += cost[1] as number;
533+
break;
534+
}
535+
}
536+
537+
this.state.removeGameObject(hitGameObject);
538+
this.sendGameObjects(player);
539+
540+
for (let otherPlayer of player.getNearbyPlayers(this.state)) {
541+
this.sendGameObjects(otherPlayer);
542+
}
543+
}
544+
}
545+
510546
for (let nearbyPlayer of nearbyPlayers) {
511547
nearbyPlayer.client?.socket.send(
512548
packetFactory.serializePacket(

src/moomoo/GameState.ts

+19
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,25 @@ export default class GameState {
1818
this.game = game;
1919
}
2020

21+
removeGameObject(gameObject: GameObject) {
22+
let packetFactory = PacketFactory.getInstance();
23+
this.gameObjects.splice(this.gameObjects.indexOf(gameObject), 1);
24+
25+
for (let player of this.players) {
26+
if (player.client && player.client.seenGameObjects.includes(gameObject.id)) {
27+
player.client.seenGameObjects.splice(player.client.seenGameObjects.indexOf(gameObject.id), 1);
28+
player.client.socket.send(
29+
packetFactory.serializePacket(
30+
new Packet(
31+
PacketType.REMOVE_GAME_OBJ,
32+
[gameObject.id]
33+
)
34+
)
35+
);
36+
}
37+
}
38+
}
39+
2140
joinClan(player: Player, tribe: Tribe) {
2241
if (!tribe.membersSIDs.includes(player.id))
2342
tribe.membersSIDs.push(player.id);

src/moomoo/Physics.ts

+36-7
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
import Vec2 from "vec2";
22
import Player from "./Player";
3-
import { eucDistance } from "./util";
43
import GameObject from '../gameobjects/GameObject';
5-
import { gameObjectSizes } from "../gameobjects/gameobjects";
6-
import { getWeaponAttackDetails, Weapons, hasCollision } from "../items/items";
4+
import { getWeaponAttackDetails, hasCollision, getGameObjDamage } from "../items/items";
75
import GameState from "./GameState";
6+
import { ItemType } from "../items/UpgradeItems";
7+
import { getHat } from "./Hats";
88

99
function collideCircles(pos1: Vec2, r1: number, pos2: Vec2, r2: number) {
1010
return pos1.distance(pos2) <= r1 + r2;
1111
}
1212

13-
function collideRectangles(x1: number, y1: number, w1: number, h1: number, x2: number, y2: number, w2: number, h2: number) {
13+
function collideRectangles(x1: number, y1: number, w1: number, x2: number, y2: number, w2: number, h2: number) {
1414
return x1 + w1 >= x2 && x1 <= x2 + w2 && y1 + w1 >= y2 && y1 <= y2 + h2;
1515
}
1616

@@ -32,13 +32,39 @@ function collidePlayerGameObject(player: Player, gameObj: GameObject) {
3232
}
3333

3434
function tryMovePlayer(player: Player, delta: number, xVel: number, yVel: number, state: GameState) {
35+
let inTrap = false;
36+
3537
let newLocation = new Vec2(
3638
player.location.x,
3739
player.location.y
3840
);
3941

4042
for (let gameObj of player.getNearbyGameObjects(state)) {
41-
if (!gameObj.type && typeof gameObj.data === 'number') {
43+
if (gameObj.isPlayerGameObject() && collidePlayerGameObject(player, gameObj)) {
44+
if (
45+
gameObj.data === ItemType.PitTrap &&
46+
gameObj.isEnemy(player, state.tribes)
47+
) {
48+
inTrap = true;
49+
}
50+
51+
let dmg = getGameObjDamage(gameObj.data);
52+
53+
if (
54+
dmg &&
55+
gameObj.isEnemy(player, state.tribes)
56+
) {
57+
let hat = getHat(player.hatID);
58+
59+
if (hat) {
60+
dmg *= hat.dmgMult || 1;
61+
}
62+
63+
let angle = Math.atan2(player.location.y - gameObj.location.y, player.location.x - gameObj.location.x);
64+
player.velocity.add(Math.cos(angle), Math.sin(angle));
65+
player.health -= dmg;
66+
}
67+
4268
if (!hasCollision(gameObj.data)) continue;
4369
}
4470

@@ -47,20 +73,23 @@ function tryMovePlayer(player: Player, delta: number, xVel: number, yVel: number
4773
yVel *= .75;
4874

4975
let angle = Math.atan2(newLocation.y - gameObj.location.y, newLocation.x - gameObj.location.x);
76+
5077
newLocation = new Vec2(
5178
gameObj.location.x + Math.cos(angle) * (gameObj.realScale + 35),
5279
gameObj.location.y + Math.sin(angle) * (gameObj.realScale + 35)
5380
);
5481
}
5582
}
5683

84+
player.inTrap = inTrap;
85+
if (inTrap) return;
86+
5787
newLocation.clamp(new Vec2(0 + 35, 0 + 35), new Vec2(14400 - 35, 14400 - 35));
5888
player.location = newLocation.add(delta * xVel, delta * yVel);
5989
}
6090

6191
function movePlayer(player: Player, delta: number, state: GameState) {
6292
if (player.velocity.x || player.velocity.y) {
63-
let angle = Math.atan2(player.velocity.y, player.velocity.x);
6493
tryMovePlayer(player, delta, player.velocity.x, player.velocity.y, state);
6594
player.velocity = player.velocity.multiply(0.993 ** delta, 0.993 ** delta);
6695
}
@@ -91,7 +120,7 @@ function checkAttack(player: Player, players: Player[]) {
91120
}
92121

93122
function collideGameObjects(gameObject1: GameObject, gameObject2: GameObject) {
94-
return collideCircles(gameObject1.location, gameObject1.scale, gameObject2.location, gameObject1.scale);
123+
return collideCircles(gameObject1.location, gameObject1.realScale * 0.9, gameObject2.location, gameObject1.realScale);
95124
}
96125

97126
function checkAttackGameObj(player: Player, gameObjects: GameObject[]) {

src/moomoo/Player.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ import {
1616
getPlaceable,
1717
getScale,
1818
getPlaceOffset,
19-
getGameObjID
19+
getGameObjID,
20+
getGameObjHealth
2021
} from "../items/items";
2122
import { ItemType } from "../items/UpgradeItems";
2223
import GameObject from "../gameobjects/GameObject";
@@ -306,10 +307,10 @@ export default class Player extends Entity {
306307
this.angle,
307308
getScale(item),
308309
-1,
309-
undefined,
310-
// getGameObjID(item),
310+
item === ItemType.PitTrap ? 0.3 * getScale(item) : undefined,
311311
item,
312-
this.id
312+
this.id,
313+
getGameObjHealth(item)
313314
);
314315

315316
for (let gameObject of gameState.gameObjects) {

src/packets/PacketFactory.ts

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ packetTypeMapping[PacketType.UPDATE_STATS] = { value: "9", side: Side.Client };
6666
packetTypeMapping[PacketType.IO_INIT] = { value: "io-init", side: Side.Client };
6767
packetTypeMapping[PacketType.HEALTH_CHANGE] = { value: "t", side: Side.Client };
6868
packetTypeMapping[PacketType.JOIN_REQUEST] = { value: "an", side: Side.Client };
69+
packetTypeMapping[PacketType.REMOVE_GAME_OBJ] = { value: "12", side: Side.Client };
6970

7071
let reversePacketTypeMapping: ReverseMapping[] = [];
7172

src/packets/PacketType.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ enum PacketType {
4747
CLAN_NOTIFY_SERVER,
4848
CLAN_NOTIFY_CLIENT,
4949
HEALTH_CHANGE,
50-
JOIN_REQUEST
50+
JOIN_REQUEST,
51+
REMOVE_GAME_OBJ
5152
}
5253

5354
export { PacketType };

0 commit comments

Comments
 (0)