Skip to content

Commit 1ae2f40

Browse files
authored
Merge pull request #303 from Ido-Barnea/feature/inventory-system
Feature/inventory system
2 parents 9b7beac + 09b5a22 commit 1ae2f40

File tree

32 files changed

+439
-46
lines changed

32 files changed

+439
-46
lines changed

chess-but-better/package-lock.json

Lines changed: 15 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

chess-but-better/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
"react": "^18.3.1",
1616
"react-dnd": "^16.0.1",
1717
"react-dnd-html5-backend": "^16.0.1",
18-
"react-dom": "^18.3.1"
18+
"react-dom": "^18.3.1",
19+
"uuid": "^11.1.0"
1920
},
2021
"devDependencies": {
2122
"@eslint/js": "^9.17.0",
Lines changed: 3 additions & 0 deletions
Loading

chess-but-better/src/controller/events/Events.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,7 @@ export enum EventType {
66
AFTER_PIECE_KILLED,
77
PIECE_SPAWNED,
88
AFTER_PIECE_SPAWNED,
9+
ITEM_PLACED,
10+
AFTER_ITEM_PLACED,
11+
ITEM_TRIGGERED,
912
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { Position } from "../../../model/piece/utilities/position/Position";
2+
import { BaseEventHandler } from "../abstract/BaseEventHandler";
3+
import { BaseItem } from "../../../model/player/inventory/abstract/BaseItem";
4+
import { TileOccupantType } from "../../game-state/services/board/TileOccupantType";
5+
import { IPiecesService } from "../../game-state/services/pieces/abstract/IPiecesService";
6+
import { IItemsService } from "../../game-state/services/items/abstract/IItemsService";
7+
import { GameEventEmitter } from "../GameEventEmitter";
8+
import { EventType } from "../Events";
9+
10+
export class ItemPlacedEventHandler extends BaseEventHandler {
11+
private eventEmitter: GameEventEmitter;
12+
private piecesService: IPiecesService;
13+
private itemsService: IItemsService;
14+
15+
constructor(eventEmitter: GameEventEmitter, piecesService: IPiecesService, itemsService: IItemsService) {
16+
super();
17+
this.eventEmitter = eventEmitter;
18+
this.piecesService = piecesService;
19+
this.itemsService = itemsService;
20+
}
21+
22+
determineTileOccupantByPosition(position: Position): TileOccupantType {
23+
const matchingPiece = this.piecesService.getPieceByPosition(position);
24+
if (matchingPiece) TileOccupantType.PIECE;
25+
26+
const matchingItem = this.itemsService.getItemByPosition(position);
27+
if (matchingItem) return TileOccupantType.ITEM;
28+
29+
return TileOccupantType.EMPTY;
30+
}
31+
32+
handle(context: Record<string, any>): void {
33+
const item: BaseItem = context['item'];
34+
const position: Position = context['position'];
35+
36+
const occupantType = this.determineTileOccupantByPosition(position);
37+
if (item.isValidPlacement(occupantType)) {
38+
item.position = position;
39+
this.eventEmitter.emit(EventType.AFTER_ITEM_PLACED);
40+
}
41+
}
42+
}

chess-but-better/src/controller/events/handlers/PieceMovedEventHandler.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,25 @@
1-
import { isEqual } from "lodash";
21
import { BasePiece } from "../../../model/piece/abstract/BasePiece";
3-
import { IPiecesStorage } from "../../storages/pieces-storage/abstract/IPiecesStorage";
42
import { Position } from "../../../model/piece/utilities/position/Position";
53
import { EventType } from "../Events";
64
import { GameEventEmitter } from "../GameEventEmitter";
75
import { BaseEventHandler } from "../abstract/BaseEventHandler";
86
import { CauseOfDeath } from "./PieceKilledEventHandler";
97
import { IBoardService } from "../../game-state/services/board/abstract/IBoardService";
8+
import { IPiecesService } from "../../game-state/services/pieces/abstract/IPiecesService";
9+
import { IItemsService } from "../../game-state/services/items/abstract/IItemsService";
1010

1111
export class PieceMovedEventHandler extends BaseEventHandler {
1212
private eventEmitter: GameEventEmitter;
13-
private piecesStorage: IPiecesStorage;
13+
private piecesService: IPiecesService;
1414
private boardService: IBoardService;
15+
private itemsService: IItemsService;
1516

16-
constructor(eventEmitter: GameEventEmitter, piecesStorage: IPiecesStorage, boardService: IBoardService) {
17+
constructor(eventEmitter: GameEventEmitter, piecesService: IPiecesService, boardService: IBoardService, itemsService: IItemsService) {
1718
super();
1819
this.eventEmitter = eventEmitter;
19-
this.piecesStorage = piecesStorage;
20+
this.piecesService = piecesService;
2021
this.boardService = boardService;
22+
this.itemsService = itemsService;
2123
}
2224

2325
calculateMovementDistance(from: Position, to: Position): number {
@@ -29,6 +31,12 @@ export class PieceMovedEventHandler extends BaseEventHandler {
2931

3032
handleMove(piece: BasePiece, movedTo: Position) {
3133
piece.position = movedTo;
34+
35+
const itemInTargetPosition = this.itemsService.getItemByPosition(movedTo);
36+
if (itemInTargetPosition) {
37+
this.itemsService.useItem(itemInTargetPosition, piece);
38+
this.eventEmitter.emit(EventType.ITEM_TRIGGERED);
39+
}
3240
}
3341

3442
handleAttack(piece: BasePiece, attackedPiece: BasePiece) {
@@ -55,11 +63,11 @@ export class PieceMovedEventHandler extends BaseEventHandler {
5563
const movementDistance = this.calculateMovementDistance(piece.position, movedTo);
5664
piece.stats.tilesMoved += movementDistance;
5765

58-
const piecesInTargetPosition = this.piecesStorage.getPieces((p) => isEqual(p.position, movedTo));
59-
if (piecesInTargetPosition.length === 0) {
66+
const pieceInTargetPosition = this.piecesService.getPieceByPosition(movedTo);
67+
if (!pieceInTargetPosition) {
6068
this.handleMove(piece, movedTo);
6169
} else {
62-
this.handleAttack(piece, piecesInTargetPosition[0]);
70+
this.handleAttack(piece, pieceInTargetPosition);
6371
}
6472

6573
this.eventEmitter.emit(EventType.AFTER_PIECE_MOVED);

chess-but-better/src/controller/game-state/Game.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ import { FirstBloodHandler } from "../events/handlers/end-of-move-handlers/secre
3636
import { FriendlyFireHandler } from "../events/handlers/end-of-move-handlers/secret-rules/FriendlyFireHandler";
3737
import { VeteranHandler } from "../events/handlers/end-of-move-handlers/secret-rules/VeteranHandler";
3838
import { BeggersHandler } from "../events/handlers/end-of-move-handlers/secret-rules/Beggers";
39+
import { IItemsStorage } from "../storages/items-storage/abstract/IItemsStorage";
40+
import { ItemsStorage } from "../storages/items-storage/ItemsStorage";
41+
import { PiggyBank } from "../items/PiggyBank";
42+
import { ItemsService } from "./services/items/ItemsService";
43+
import { IItemsService } from "./services/items/abstract/IItemsService";
44+
import { ItemPlacedEventHandler } from "../events/handlers/ItemPlacedEventHandler";
3945

4046
export class Game {
4147
// Teams
@@ -51,11 +57,13 @@ export class Game {
5157

5258
// Storage
5359
public playersStorage: IPlayersStorage;
54-
public piecesStorage: IPiecesStorage;
60+
private piecesStorage: IPiecesStorage;
61+
public itemsStorage: IItemsStorage;
5562

5663
// Services
5764
public piecesService: IPiecesService;
5865
public boardService: IBoardService;
66+
public itemsService: IItemsService;
5967

6068
// Counters
6169
public turnCounter: ITurnCounter;
@@ -82,6 +90,7 @@ export class Game {
8290

8391
// Storage
8492
this.playersStorage = new PlayersStorage([this.whitePlayer, this.blackPlayer]);
93+
this.itemsStorage = new ItemsStorage([new PiggyBank(undefined)]);
8594

8695
// Counters
8796
this.turnCounter = new TurnCounter(this.playersStorage);
@@ -128,6 +137,7 @@ export class Game {
128137
// Services
129138
this.piecesService = new PiecesService(this.piecesStorage, this.turnCounter);
130139
this.boardService = new BoardService(this.boards, this.piecesStorage, this.piecesService, this.eventEmitter);
140+
this.itemsService = new ItemsService(this.itemsStorage);
131141

132142
// Event Handlers - End Of Move
133143
const endOfMoveHandler = new EndOfMoveEventHandler();
@@ -136,7 +146,7 @@ export class Game {
136146
this.eventEmitter.on(EventType.END_OF_TURN, endOfMoveHandler.handle);
137147

138148
// Event Handlers - Piece Moved
139-
const pieceMovedHandler = new PieceMovedEventHandler(this.eventEmitter, this.piecesStorage, this.boardService);
149+
const pieceMovedHandler = new PieceMovedEventHandler(this.eventEmitter, this.piecesService, this.boardService, this.itemsService);
140150
this.eventEmitter.on(EventType.PIECE_MOVED, pieceMovedHandler.handle);
141151

142152
// Event Handlers - Piece Killed
@@ -147,6 +157,10 @@ export class Game {
147157
const pieceSpawnedHandler = new PieceSpawnedEventHandler(this.eventEmitter, this.piecesStorage);
148158
this.eventEmitter.on(EventType.PIECE_SPAWNED, pieceSpawnedHandler.handle);
149159

160+
// Event Handler - Item Placed
161+
const itemPlacedHandler = new ItemPlacedEventHandler(this.eventEmitter, this.piecesService, this.itemsService);
162+
this.eventEmitter.on(EventType.ITEM_PLACED, itemPlacedHandler.handle);
163+
150164
// Event Handlers - Secret Rules
151165
const firstBloodHandler = new FirstBloodHandler();
152166
this.eventEmitter.on(EventType.AFTER_PIECE_KILLED, firstBloodHandler.handle);

chess-but-better/src/controller/game-state/services/board/BoardService.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { BoardType } from "../../../../model/board/BoardTypes";
77
import { IPiecesStorage } from "../../../storages/pieces-storage/abstract/IPiecesStorage";
88
import { IPiecesService } from "../pieces/abstract/IPiecesService";
99
import { GameEventEmitter } from "../../../events/GameEventEmitter";
10+
import { BaseItem } from "../../../../model/player/inventory/abstract/BaseItem";
1011

1112
export class BoardService implements IBoardService {
1213
private boards: Record<BoardType, BaseBoard>;
@@ -41,7 +42,7 @@ export class BoardService implements IBoardService {
4142
}, [] as Array<BaseBoard>);
4243
}
4344

44-
movePiece(piece: BasePiece, to: Position) {
45+
movePiece(piece: BasePiece, to: Position): void {
4546
if (!this.piecesService.isLegalMove(piece, to)) return;
4647

4748
this.eventEmitter.emit(EventType.PIECE_MOVED, {piece, to});
@@ -57,4 +58,10 @@ export class BoardService implements IBoardService {
5758
board: this.getBoard(position.board.name),
5859
}
5960
}
61+
62+
placeItem(item: BaseItem, position: Position): void {
63+
if (!item) return;
64+
65+
this.eventEmitter.emit(EventType.ITEM_PLACED, {item, position});
66+
}
6067
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export enum TileOccupantType {
2+
PIECE,
3+
ITEM,
4+
EMPTY,
5+
}

chess-but-better/src/controller/game-state/services/board/abstract/IBoardService.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ import { BaseBoard } from "../../../../../model/board/abstract/BaseBoard";
22
import { BoardType } from "../../../../../model/board/BoardTypes";
33
import { BasePiece } from "../../../../../model/piece/abstract/BasePiece";
44
import { Position } from "../../../../../model/piece/utilities/position/Position";
5+
import { BaseItem } from "../../../../../model/player/inventory/abstract/BaseItem";
56

67
export interface IBoardService {
78
getBoard: (type: BoardType) => BaseBoard;
89
retrievePopulatedBoards: () => Array<BaseBoard>;
910
movePiece(piece: BasePiece, to: Position): void;
1011
copyPosition(position: Position): Position;
12+
placeItem(item: BaseItem, position: Position): void;
1113
}

0 commit comments

Comments
 (0)