import GameState from "../../../../GameState" ; import ReconcileArmiesGameState from "../ReconcileArmiesGameState" ; import House from "../../../game-data-structure/House" ; import Player from "../../../Player" ; import { ClientMessage } from "../../../../../messages/ClientMessage" ; import { ServerMessage } from "../../../../../messages/ServerMessage" ; import Unit from "../../../game-data-structure/Unit" ; import Region from "../../../game-data-structure/Region" ; import Game from "../../../game-data-structure/Game" ; import BetterMap from "../../../../../utils/BetterMap" ; import EntireGame from "../../../../EntireGame" ; import UnitType from "../../../game-data-structure/UnitType" ; import User from "../../../../../server/User" ; import _ from "lodash" ; export default class PlayerReconcileArmiesGameState extends GameState < ReconcileArmiesGameState < any > > { house : House ; get reconcileArmiesGameState ( ) : ReconcileArmiesGameState < any > { return this . parentGameState ; } get game ( ) : Game { return this . parentGameState . game ; } get entireGame ( ) : EntireGame { return this . parentGameState . entireGame ; } firstStart ( house ) { this . house = house ; } onPlayerMessage ( player , message ) { if ( message . type == "reconcile-armies" ) { if ( this . parentGameState . ingame . getControllerOfHouse ( this . house ) != player ) { return ; } const removedUnits = new BetterMap ( message . unitsToRemove . map ( ( [ regionId , unitIds ] ) => { const region = this . game . world . regions . get ( regionId ) ; const units = unitIds . map ( uid => region . units . get ( uid ) ) ; return [ region , units ] ; } ) ) ; if ( _ . flatMap ( removedUnits . values ) . some ( u => u . allegiance != this . house ) ) { return ; } if ( ! this . isEnoughToReconcile ( removedUnits ) ) { return ; } if ( this . isTooMuchReconciled ( removedUnits ) ) { return ; } removedUnits . forEach ( ( units , region ) => { units . forEach ( u => region . units . delete ( u . id ) ) ; this . entireGame . broadcastToClients ( { type : "remove-units" , regionId : region . id , unitIds : units . map ( u => u . id ) } ) ; } ) ; this . parentGameState . ingame . log ( { type : "armies-reconciled" , house : this . house . id , armies : removedUnits . map ( ( r , us ) => [ r . id , us . map ( u => u . type . id ) ] ) } ) ; this . reconcileArmiesGameState . onPlayerReconcileArmiesGameStateEnd ( this . house ) ; } } onServerMessage ( _message ) { return ; } getAllArmyUnitsOfHouse ( house ) { return _ . flatMap ( this . game . world . getControlledRegions ( house ) . filter ( r => r . units . size > 1 ) . map ( r => r . units . values ) ) ; } reconcileArmies ( removedUnits ) { this . entireGame . sendMessageToServer ( { type : "reconcile-armies" , unitsToRemove : removedUnits . entries . map ( ( [ region , units ] ) => [ region . id , units . map ( u => u . id ) ] ) } ) ; } isTooMuchReconciled ( removedUnits ) { const allRemovedUnitIds = _ . flatMap ( removedUnits . values ) . map ( u => u . id ) ; for ( const uid of allRemovedUnitIds ) { const newRemovedUnits = new BetterMap ( removedUnits . entries ) ; newRemovedUnits . keys . forEach ( region => { const newUnits = newRemovedUnits . get ( region ) . filter ( u => u . id != uid ) ; newRemovedUnits . set ( region , newUnits ) ; } ) ; if ( this . isEnoughToReconcile ( newRemovedUnits ) ) { return true ; } } return false ; } isEnoughToReconcile ( removedUnits ) { return ! this . game . hasTooMuchArmies ( this . house , new BetterMap < Region , UnitType [ ] > ( ) , removedUnits ) ; } getWaitedUsers ( ) { return [ this . parentGameState . ingame . getControllerOfHouse ( this . house ) . user ] ; } serializeToClient ( ) { return { house : this . house . id } ; } static deserializeFromServer ( reconcileArmies , data ) { const playerReconcileArmies = new PlayerReconcileArmiesGameState ( reconcileArmies ) ; playerReconcileArmies . house = reconcileArmies . game . houses . get ( data . house ) ; return playerReconcileArmies ; } } export interface SerializedPlayerReconcileArmiesGameState { house : string ; }