added right click option break alliance

This commit is contained in:
evanpelle
2024-09-21 09:42:43 -07:00
parent 6600c4cbe0
commit 5f38d2a544
8 changed files with 106 additions and 18 deletions
+5 -1
View File
@@ -131,7 +131,11 @@
* eventbox events dissapear after timeout DONE 9/20/2024 * eventbox events dissapear after timeout DONE 9/20/2024
* auto reject alliance when event dissapears DONE 9/20/2024 * auto reject alliance when event dissapears DONE 9/20/2024
* first place has crown DONE 9/20/2024 * first place has crown DONE 9/20/2024
* make fake humans easier * can't attack ally
* make alliances expire
* color code events
* add updates to eventbox: boats (max count, too far)
* broken alliances
* BUG: FakeHuman don't be enemy if don't share border * BUG: FakeHuman don't be enemy if don't share border
* BUG: when send boat only captures one pixel * BUG: when send boat only captures one pixel
* store cookies * store cookies
+11 -1
View File
@@ -10,7 +10,7 @@ import {TerrainMap} from "../core/game/TerrainMapLoader";
import {and, bfs, dist, manhattanDist} from "../core/Util"; import {and, bfs, dist, manhattanDist} from "../core/Util";
import {TerrainLayer} from "./graphics/layers/TerrainLayer"; import {TerrainLayer} from "./graphics/layers/TerrainLayer";
import {WinCheckExecution} from "../core/execution/WinCheckExecution"; import {WinCheckExecution} from "../core/execution/WinCheckExecution";
import {SendAllianceRequestUIEvent} from "./graphics/layers/UILayer"; import {SendAllianceRequestUIEvent, SendBreakAllianceUIEvent} from "./graphics/layers/UILayer";
import {createCanvas} from "./graphics/Utils"; import {createCanvas} from "./graphics/Utils";
import {AllianceRequestReplyUIEvent as SendAllianceRequestReplyUIEvent} from "./graphics/layers/EventsDisplay"; import {AllianceRequestReplyUIEvent as SendAllianceRequestReplyUIEvent} from "./graphics/layers/EventsDisplay";
@@ -127,6 +127,7 @@ export class ClientGame {
this.eventBus.on(MouseUpEvent, (e) => this.inputEvent(e)) this.eventBus.on(MouseUpEvent, (e) => this.inputEvent(e))
this.eventBus.on(SendAllianceRequestUIEvent, (e) => this.onSendAllianceRequest(e)) this.eventBus.on(SendAllianceRequestUIEvent, (e) => this.onSendAllianceRequest(e))
this.eventBus.on(SendAllianceRequestReplyUIEvent, (e) => this.onAllianceRequestReplyUIEvent(e)) this.eventBus.on(SendAllianceRequestReplyUIEvent, (e) => this.onAllianceRequestReplyUIEvent(e))
this.eventBus.on(SendBreakAllianceUIEvent, (e) => this.onBreakAllianceRequestUIEvent(e))
this.renderer.initialize() this.renderer.initialize()
this.input.initialize() this.input.initialize()
@@ -294,6 +295,15 @@ export class ClientGame {
}) })
} }
private onBreakAllianceRequestUIEvent(event: SendBreakAllianceUIEvent) {
this.sendIntent({
type: "breakAlliance",
clientID: this.id,
requestor: event.requestor.id(),
recipient: event.recipient.id(),
})
}
private sendSpawnIntent(cell: Cell) { private sendSpawnIntent(cell: Cell) {
this.sendIntent({ this.sendIntent({
type: "spawn", type: "spawn",
+32 -10
View File
@@ -14,6 +14,14 @@ export class SendAllianceRequestUIEvent implements GameEvent {
) { } ) { }
} }
export class SendBreakAllianceUIEvent implements GameEvent {
constructor(
public readonly requestor: Player,
public readonly recipient: Player
) { }
}
interface MenuOption { interface MenuOption {
label: string; label: string;
action: () => void; action: () => void;
@@ -236,34 +244,48 @@ export class UILayer implements Layer {
if (!tile.hasOwner()) { if (!tile.hasOwner()) {
return return
} }
const options: MenuOption[] = []
const owner = tile.owner() as Player const owner = tile.owner() as Player
if (owner.clientID() == this.clientID) { if (owner.clientID() == this.clientID) {
return return
} }
// TODO: check if already allied with
const myPlayer = this.game.players().find(p => p.clientID() == this.clientID) const myPlayer = this.game.players().find(p => p.clientID() == this.clientID)
if (!myPlayer) { if (!myPlayer) {
console.warn('my player not found') console.warn('my player not found')
return return
} }
if (myPlayer.alliedWith(owner) || myPlayer.pendingAllianceRequestWith(owner)) {
if (myPlayer.pendingAllianceRequestWith(owner)) {
return return
} }
this.customMenu!.style.display = 'block'; if (myPlayer.alliedWith(owner)) {
this.customMenu!.style.left = `${e.x}px`; options.push({
this.customMenu!.style.top = `${e.y}px`; label: "Break Alliance",
this.populateMenu([ action: (): void => {
{ this.eventBus.emit(
new SendBreakAllianceUIEvent(myPlayer, owner)
)
},
})
} else {
options.push({
label: "Request Alliance", label: "Request Alliance",
action: (): void => { action: (): void => {
this.eventBus.emit( this.eventBus.emit(
new SendAllianceRequestUIEvent(myPlayer, owner) new SendAllianceRequestUIEvent(myPlayer, owner)
) )
}, },
} })
]) }
this.customMenu!.style.display = 'block';
this.customMenu!.style.left = `${e.x}px`;
this.customMenu!.style.top = `${e.y}px`;
this.populateMenu(options)
} }
private populateMenu(options: MenuOption[]) { private populateMenu(options: MenuOption[]) {
+16 -2
View File
@@ -4,7 +4,13 @@ import {PlayerType} from './game/Game';
export type GameID = string export type GameID = string
export type ClientID = string export type ClientID = string
export type Intent = SpawnIntent | AttackIntent | BoatAttackIntent | UpdateNameIntent | AllianceRequestIntent | AllianceRequestReplyIntent export type Intent = SpawnIntent
| AttackIntent
| BoatAttackIntent
| UpdateNameIntent
| AllianceRequestIntent
| AllianceRequestReplyIntent
| BreakAllianceIntent
export type AttackIntent = z.infer<typeof AttackIntentSchema> export type AttackIntent = z.infer<typeof AttackIntentSchema>
export type SpawnIntent = z.infer<typeof SpawnIntentSchema> export type SpawnIntent = z.infer<typeof SpawnIntentSchema>
@@ -12,6 +18,7 @@ export type BoatAttackIntent = z.infer<typeof BoatAttackIntentSchema>
export type UpdateNameIntent = z.infer<typeof UpdateNameIntentSchema> export type UpdateNameIntent = z.infer<typeof UpdateNameIntentSchema>
export type AllianceRequestIntent = z.infer<typeof AllianceRequestIntentSchema> export type AllianceRequestIntent = z.infer<typeof AllianceRequestIntentSchema>
export type AllianceRequestReplyIntent = z.infer<typeof AllianceRequestReplyIntentSchema> export type AllianceRequestReplyIntent = z.infer<typeof AllianceRequestReplyIntentSchema>
export type BreakAllianceIntent = z.infer<typeof BreakAllianceIntentSchema>
export type Turn = z.infer<typeof TurnSchema> export type Turn = z.infer<typeof TurnSchema>
@@ -91,13 +98,20 @@ export const AllianceRequestReplyIntentSchema = BaseIntentSchema.extend({
accept: z.boolean(), accept: z.boolean(),
}) })
export const BreakAllianceIntentSchema = BaseIntentSchema.extend({
type: z.literal('breakAlliance'),
requestor: z.string(), // The one who made the original alliance request
recipient: z.string(),
})
const IntentSchema = z.union([ const IntentSchema = z.union([
AttackIntentSchema, AttackIntentSchema,
SpawnIntentSchema, SpawnIntentSchema,
BoatAttackIntentSchema, BoatAttackIntentSchema,
UpdateNameIntentSchema, UpdateNameIntentSchema,
AllianceRequestIntentSchema, AllianceRequestIntentSchema,
AllianceRequestReplyIntentSchema AllianceRequestReplyIntentSchema,
BreakAllianceIntentSchema
]); ]);
const TurnSchema = z.object({ const TurnSchema = z.object({
+5 -2
View File
@@ -9,8 +9,9 @@ import {UpdateNameExecution} from "./UpdateNameExecution";
import {FakeHumanExecution} from "./FakeHumanExecution"; import {FakeHumanExecution} from "./FakeHumanExecution";
import Usernames from '../../../resources/Usernames.txt' import Usernames from '../../../resources/Usernames.txt'
import {simpleHash} from "../Util"; import {simpleHash} from "../Util";
import {AllianceRequestExecution} from "./AllianceRequestExecution"; import {AllianceRequestExecution} from "./alliance/AllianceRequestExecution";
import {AllianceRequestReplyExecution} from "./AllianceRequestReplyExecution"; import {AllianceRequestReplyExecution} from "./alliance/AllianceRequestReplyExecution";
import {BreakAllianceExecution} from "./alliance/BreakAllianceExecution";
@@ -61,6 +62,8 @@ export class Executor {
return new AllianceRequestExecution(intent.requestor, intent.recipient) return new AllianceRequestExecution(intent.requestor, intent.recipient)
} else if (intent.type == "allianceRequestReply") { } else if (intent.type == "allianceRequestReply") {
return new AllianceRequestReplyExecution(intent.requestor, intent.recipient, intent.accept) return new AllianceRequestReplyExecution(intent.requestor, intent.recipient, intent.accept)
} else if (intent.type == "breakAlliance") {
return new BreakAllianceExecution(intent.requestor, intent.recipient)
} }
else { else {
throw new Error(`intent type ${intent} not found`) throw new Error(`intent type ${intent} not found`)
@@ -1,4 +1,4 @@
import {AllianceRequest, Execution, MutableGame, MutablePlayer, Player, PlayerID} from "../game/Game"; import {AllianceRequest, Execution, MutableGame, MutablePlayer, Player, PlayerID} from "../../game/Game";
export class AllianceRequestExecution implements Execution { export class AllianceRequestExecution implements Execution {
private active = true private active = true
@@ -1,4 +1,4 @@
import {AllianceRequest, Execution, MutableGame, MutablePlayer, Player, PlayerID} from "../game/Game"; import {AllianceRequest, Execution, MutableGame, MutablePlayer, Player, PlayerID} from "../../game/Game";
export class AllianceRequestReplyExecution implements Execution { export class AllianceRequestReplyExecution implements Execution {
private active = true private active = true
@@ -0,0 +1,35 @@
import {AllianceRequest, Execution, MutableGame, MutablePlayer, Player, PlayerID} from "../../game/Game";
export class BreakAllianceExecution implements Execution {
private active = true
private requestor: MutablePlayer;
private recipient: MutablePlayer
constructor(private requestorID: PlayerID, private recipientID: PlayerID) { }
init(mg: MutableGame, ticks: number): void {
this.requestor = mg.player(this.requestorID)
this.recipient = mg.player(this.recipientID)
}
tick(ticks: number): void {
if (!this.requestor.alliedWith(this.recipient)) {
console.warn('cant break alliance, not allied')
} else {
this.requestor.breakAllianceWith(this.recipient)
}
this.active = false
}
owner(): MutablePlayer {
return null
}
isActive(): boolean {
return this.active
}
activeDuringSpawnPhase(): boolean {
return false
}
}