Files
OpenFrontIO/src/client/Transport.ts
T
2024-09-29 11:26:31 -07:00

145 lines
4.5 KiB
TypeScript

import {EventBus, GameEvent} from "../core/EventBus"
import {AllianceRequest, Cell, Game, Player, PlayerID, PlayerType} from "../core/game/Game"
import {ClientID, ClientIntentMessageSchema, GameID, Intent} from "../core/Schemas"
export class SendAllianceRequestIntentEvent implements GameEvent {
constructor(
public readonly requestor: Player,
public readonly recipient: Player
) { }
}
export class SendBreakAllianceIntentEvent implements GameEvent {
constructor(
public readonly requestor: Player,
public readonly recipient: Player
) { }
}
export class SendAllianceReplyIntentEvent implements GameEvent {
constructor(
public readonly allianceRequest: AllianceRequest,
public readonly accepted: boolean
) { }
}
export class SendSpawnIntentEvent implements GameEvent {
constructor(
public readonly cell: Cell,
) { }
}
export class SendAttackIntentEvent implements GameEvent {
constructor(
public readonly targetID: PlayerID,
) { }
}
export class SendBoatAttackIntentEvent implements GameEvent {
constructor(
public readonly targetID: PlayerID,
public readonly cell: Cell,
public readonly troops: number
) { }
}
export class Transport {
constructor(
private socket: WebSocket,
private eventBus: EventBus,
private gameID: GameID,
private clientID: ClientID,
private playerID: PlayerID,
private playerName: () => string,
) {
this.eventBus.on(SendAllianceRequestIntentEvent, (e) => this.onSendAllianceRequest(e))
this.eventBus.on(SendAllianceReplyIntentEvent, (e) => this.onAllianceRequestReplyUIEvent(e))
this.eventBus.on(SendBreakAllianceIntentEvent, (e) => this.onBreakAllianceRequestUIEvent(e))
this.eventBus.on(SendSpawnIntentEvent, (e) => this.onSendSpawnIntentEvent(e))
this.eventBus.on(SendAttackIntentEvent, (e) => this.onSendAttackIntent(e))
this.eventBus.on(SendBoatAttackIntentEvent, (e) => this.onSendBoatAttackIntent(e))
}
private onSendAllianceRequest(event: SendAllianceRequestIntentEvent) {
this.sendIntent({
type: "allianceRequest",
clientID: this.clientID,
requestor: event.requestor.id(),
recipient: event.recipient.id(),
})
}
private onAllianceRequestReplyUIEvent(event: SendAllianceReplyIntentEvent) {
this.sendIntent({
type: "allianceRequestReply",
clientID: this.clientID,
requestor: event.allianceRequest.requestor().id(),
recipient: event.allianceRequest.recipient().id(),
accept: event.accepted,
})
}
private onBreakAllianceRequestUIEvent(event: SendBreakAllianceIntentEvent) {
this.sendIntent({
type: "breakAlliance",
clientID: this.clientID,
requestor: event.requestor.id(),
recipient: event.recipient.id(),
})
}
private onSendSpawnIntentEvent(event: SendSpawnIntentEvent) {
this.sendIntent({
type: "spawn",
clientID: this.clientID,
playerID: this.playerID,
name: this.playerName(),
playerType: PlayerType.Human,
x: event.cell.x,
y: event.cell.y
})
}
private onSendAttackIntent(event: SendAttackIntentEvent) {
this.sendIntent({
type: "attack",
clientID: this.clientID,
attackerID: this.playerID,
targetID: event.targetID,
troops: null,
sourceX: null,
sourceY: null,
targetX: null,
targetY: null,
})
}
private onSendBoatAttackIntent(event: SendBoatAttackIntentEvent) {
this.sendIntent({
type: "boat",
clientID: this.clientID,
attackerID: this.playerID,
targetID: event.targetID,
troops: event.troops,
x: event.cell.x,
y: event.cell.y,
})
}
private sendIntent(intent: Intent) {
if (this.socket.readyState === WebSocket.OPEN) {
const msg = ClientIntentMessageSchema.parse({
type: "intent",
clientID: this.clientID,
gameID: this.gameID,
intent: intent
})
this.socket.send(JSON.stringify(msg))
} else {
console.log('WebSocket is not open. Current state:', this.socket.readyState);
console.log('attempting reconnect')
}
}
}