private void Handle_Play_Shortform_Command( CMatchPlayShortformSlashCommand command ) { ECardColor play_color; ECardValue play_value; ECardColor draw_color; CCardUtils.Convert_Card_From_Short_Form( command.CardShortform, out play_color, out play_value ); if ( play_color == ECardColor.Invalid || play_value == ECardValue.Invalid ) { CClientResource.Output_Text< EClientTextID >( EClientTextID.Client_Game_Action_Invalid_Card_Shortform, command.CardShortform ); return; } CCardUtils.Extract_Color_From_Short_Form( command.DrawCode, out draw_color ); CGameActionBase draw_action = null; if ( draw_color == ECardColor.Invalid ) { draw_action = new CDrawFromDeckGameAction(); } else { draw_action = new CDrawFromDiscardGameAction( draw_color ); } Handle_Pending_Turn( new CMatchTakeTurnRequest( new CPlayCardGameAction( new CCard( play_color, play_value ) ), draw_action ) ); if ( m_PendingTurn != null ) { CClientResource.Output_Text< EClientTextID >( EClientTextID.Client_Game_Action_Turn_Submitted ); CClientLogicalThread.Instance.Send_Message_To_Server( m_PendingTurn ); m_PendingTurn = null; } }
private void Handle_Reset_Turn_Command( CMatchResetTurnSlashCommand command ) { EGameActionFailure failure_message = Is_Local_Player_Turn(); if ( failure_message != EGameActionFailure.None ) { CClientResource.Output_Text< EClientTextID >( Convert_Game_Action_Failure_To_Text_ID( failure_message ) ); return; } CClientResource.Output_Text< EClientTextID >( EClientTextID.Client_Game_Action_Turn_Reset ); m_PendingTurn = null; }
private void Handle_Pass_Shortform_Command( CMatchPassShortformSlashCommand command ) { ECardColor pass_color1; ECardValue pass_value1; CCardUtils.Convert_Card_From_Short_Form( command.CardShortform1, out pass_color1, out pass_value1 ); if ( pass_color1 == ECardColor.Invalid || pass_value1 == ECardValue.Invalid ) { CClientResource.Output_Text< EClientTextID >( EClientTextID.Client_Game_Action_Invalid_Card_Shortform, command.CardShortform1 ); return; } ECardColor pass_color2; ECardValue pass_value2; CCardUtils.Convert_Card_From_Short_Form( command.CardShortform2, out pass_color2, out pass_value2 ); if ( pass_color2 == ECardColor.Invalid || pass_value2 == ECardValue.Invalid ) { CClientResource.Output_Text< EClientTextID >( EClientTextID.Client_Game_Action_Invalid_Card_Shortform, command.CardShortform2 ); return; } Handle_Pending_Turn( new CMatchTakeTurnRequest( new CPassCardsGameAction( new CCard( pass_color1, pass_value1 ), new CCard( pass_color2, pass_value2 ) ) ) ); if ( m_PendingTurn != null ) { CClientResource.Output_Text< EClientTextID >( EClientTextID.Client_Game_Action_Turn_Submitted ); CClientLogicalThread.Instance.Send_Message_To_Server( m_PendingTurn ); m_PendingTurn = null; } }
private void Handle_Pending_Turn( CMatchTakeTurnRequest pending_turn ) { EGameActionFailure failure_message = Is_Local_Player_Turn(); if ( failure_message != EGameActionFailure.None ) { CClientResource.Output_Text< EClientTextID >( Convert_Game_Action_Failure_To_Text_ID( failure_message ) ); return; } if ( m_PendingTurn != null ) { CClientResource.Output_Text< EClientTextID >( EClientTextID.Client_Game_Action_Turn_Is_Already_Complete ); return; } failure_message = Match.Validate_Turn( pending_turn, CClientLogicalThread.Instance.ConnectedID ); if ( failure_message != EGameActionFailure.None ) { CClientResource.Output_Text< EClientTextID >( Convert_Game_Action_Failure_To_Text_ID( failure_message ) ); return; } CClientResource.Output_Text< EClientTextID >( EClientTextID.Client_Game_Action_Queued, CClientResource.Get_Text< EClientTextID >( EClientTextID.Client_Command_Name_Match_End_Turn ) ); m_PendingTurn = pending_turn; }
private void Handle_End_Turn_Command( CMatchEndTurnSlashCommand command ) { EGameActionFailure failure_message = Is_Local_Player_Turn(); if ( failure_message != EGameActionFailure.None ) { CClientResource.Output_Text< EClientTextID >( Convert_Game_Action_Failure_To_Text_ID( failure_message ) ); return; } if ( m_PendingTurn == null ) { CClientResource.Output_Text< EClientTextID >( EClientTextID.Client_Game_Action_Your_Turn_Is_Incomplete ); return; } CClientResource.Output_Text< EClientTextID >( EClientTextID.Client_Game_Action_Turn_Submitted ); CClientLogicalThread.Instance.Send_Message_To_Server( m_PendingTurn ); m_PendingTurn = null; }
public void Try_Take_Turn( CMatchTakeTurnRequest request, EPersistenceID source_player ) { if ( !MatchState.Is_Player( source_player ) ) { CServerMessageRouter.Send_Message_To_Player( new CMatchTakeTurnResponse( request.RequestID, EGameActionFailure.Not_A_Player ), source_player ); return; } EGameActionFailure failure_reason = Validate_Turn( request, source_player ); if ( failure_reason != EGameActionFailure.None ) { CServerMessageRouter.Send_Message_To_Player( new CMatchTakeTurnResponse( request.RequestID, failure_reason ), source_player ); return; } CServerMessageRouter.Send_Message_To_Player( new CMatchTakeTurnResponse( request.RequestID, EGameActionFailure.None ), source_player ); // Build, Apply, Broadcast deltas List< IObservedClonableDelta > deltas = new List< IObservedClonableDelta >(); Build_Turn_Deltas( request, source_player, deltas ); Apply_Turn_Deltas( deltas ); foreach ( var pid in ConnectedPlayersAndObservers ) { List< IObservedClonableDelta > cloned_deltas = new List< IObservedClonableDelta >( deltas.Select( delta => delta.Clone( pid, MatchState.Is_Admin_Observer( pid ) ) ) ); CServerMessageRouter.Send_Message_To_Player( new CMatchDeltaSetMessage( cloned_deltas ), pid ); } if ( GameState.Is_Game_Finished() ) { On_Game_End_Naturally(); } }
public void Build_Turn_Deltas( CMatchTakeTurnRequest request, EPersistenceID source_player, List< IObservedClonableDelta > deltas ) { foreach ( var action in request.Actions ) { switch ( action.Action ) { case EGameAction.Play_Card: CPlayCardGameAction play_action = action as CPlayCardGameAction; ECardColor play_color = play_action.Card.Color; ECardValue play_value = play_action.Card.Value; deltas.Add( new CPlayerHand.CPlayerHandDelta( source_player, ECardDelta.Remove, play_color, play_value ) ); deltas.Add( new CCardCollection.CCardCollectionDelta( MatchState.Get_Side_For_Player( source_player ), play_color, play_value ) ); break; case EGameAction.Discard_Card: CDiscardCardGameAction discard_action = action as CDiscardCardGameAction; ECardColor discard_color = discard_action.Card.Color; ECardValue discard_value = discard_action.Card.Value; deltas.Add( new CPlayerHand.CPlayerHandDelta( source_player, ECardDelta.Remove, discard_color, discard_value ) ); deltas.Add( new CDiscardPile.CDiscardPileDelta( ECardDelta.Add, discard_color, discard_value ) ); break; case EGameAction.Draw_From_Deck: CDeck deck = GameState.Get_Deck(); CCard top_card = deck.Peek_Top_Card(); deltas.Add( new CDeck.CDeckDelta() ); deltas.Add( new CPlayerHand.CPlayerHandDelta( source_player, ECardDelta.Add, top_card.Color, top_card.Value ) ); break; case EGameAction.Draw_From_Discard: CDrawFromDiscardGameAction draw_from_discard_action = action as CDrawFromDiscardGameAction; ECardColor draw_color = draw_from_discard_action.Color; CDiscardPile discard_pile = GameState.Get_Discard_Pile( draw_color ); ECardValue draw_value = discard_pile.Get_Top_Card().Value; deltas.Add( new CPlayerHand.CPlayerHandDelta( source_player, ECardDelta.Add, draw_color, draw_value ) ); deltas.Add( new CDiscardPile.CDiscardPileDelta( ECardDelta.Remove, draw_color, draw_value ) ); break; case EGameAction.Pass_Cards: CPassCardsGameAction pass_action = action as CPassCardsGameAction; deltas.Add( new CPlayerHand.CPlayerHandDelta( source_player, ECardDelta.Remove, pass_action.Card1.Color, pass_action.Card1.Value ) ); deltas.Add( new CPlayerHand.CPlayerHandDelta( source_player, ECardDelta.Remove, pass_action.Card2.Color, pass_action.Card2.Value ) ); EPersistenceID partner_id = MatchState.Get_Partner_For( source_player ); deltas.Add( new CPlayerHand.CPlayerHandDelta( partner_id, ECardDelta.Add, pass_action.Card1.Color, pass_action.Card1.Value ) ); deltas.Add( new CPlayerHand.CPlayerHandDelta( partner_id, ECardDelta.Add, pass_action.Card2.Color, pass_action.Card2.Value ) ); break; } } deltas.Add( new CGameState.CGameStateDelta( ( GameState.CurrentTurnIndex + 1 ) % CGameModeUtils.Player_Count_For_Game_Mode( GameState.Mode ) ) ); }
private void Handle_Match_Take_Turn_Message( CMatchTakeTurnRequest request, EPersistenceID source_player ) { CConnectedPlayer player = CConnectedPlayerManager.Instance.Get_Player_By_Persistence_ID( source_player ); if ( player == null ) { return; } CServerMatchInstance match_instance = Get_Match_Instance( player.MatchID ); if ( match_instance == null ) { CServerMessageRouter.Send_Message_To_Player( new CMatchTakeTurnResponse( request.RequestID, EGameActionFailure.Not_In_Match ), source_player ); return; } match_instance.Try_Take_Turn( request, source_player ); }
public EGameActionFailure Validate_Turn( CMatchTakeTurnRequest pending_turn, EPersistenceID player_id ) { if ( MatchState.State != EMatchInstanceState.Idle ) { return EGameActionFailure.Match_Halted; } if ( GameState.CurrentPlayer != player_id ) { return EGameActionFailure.Not_Your_Turn; } if ( pending_turn.Actions.Count > 2 ) { return EGameActionFailure.Invalid_Turn; } if ( pending_turn.Actions.Count == 0 ) { return EGameActionFailure.Turn_Is_Incomplete; } for ( int i = 0; i < pending_turn.Actions.Count; i++ ) { CGameActionBase action = pending_turn.Actions[ i ]; switch ( action.Action ) { case EGameAction.Play_Card: if ( i != 0 ) { return EGameActionFailure.Play_Card_Must_Be_First_Action; } if ( pending_turn.Actions.Count != 2 ) { return EGameActionFailure.Turn_Is_Incomplete; } CPlayCardGameAction play_action = action as CPlayCardGameAction; ECardColor color = play_action.Card.Color; ECardValue value = play_action.Card.Value; if ( !GameState.Get_Player_Hand( player_id ).Contains_Card( color, value ) ) { return EGameActionFailure.Card_Is_Not_In_Your_Hand; } CCardCollection local_collection = GameState.Get_Card_Collection( Get_Side_For_Player( player_id ), color ); int local_collection_top_value = local_collection.Get_Top_Card_Score_Value(); if ( CCardUtils.Get_Card_Score_Value( value ) <= local_collection_top_value && local_collection_top_value != 0 ) { return EGameActionFailure.A_Higher_Card_Already_Exists; } break; case EGameAction.Discard_Card: if ( i != 0 ) { return EGameActionFailure.Discard_Card_Must_Be_First_Action; } if ( pending_turn.Actions.Count != 2 ) { return EGameActionFailure.Turn_Is_Incomplete; } CDiscardCardGameAction discard_action = action as CDiscardCardGameAction; if ( !GameState.Get_Player_Hand( player_id ).Contains_Card( discard_action.Card.Color, discard_action.Card.Value ) ) { return EGameActionFailure.Card_Is_Not_In_Your_Hand; } break; case EGameAction.Draw_From_Deck: if ( i != 1 ) { return EGameActionFailure.You_Must_Play_A_Card_Before_Drawing; } if ( GameState.Get_Deck().Count == 0 ) { return EGameActionFailure.Deck_Is_Empty; } break; case EGameAction.Draw_From_Discard: if ( i != 1 ) { return EGameActionFailure.You_Must_Play_A_Card_Before_Drawing; } CDrawFromDiscardGameAction draw_action = action as CDrawFromDiscardGameAction; if ( GameState.Get_Discard_Pile( draw_action.Color ).Count == 0 ) { // handle pathological case of "spinning in place" where you discard a card and then redraw it; if the discard pile is empty when you attempt this, then // the simple validation approach of checking current state is insufficient CDiscardCardGameAction discard_to_pile_action = pending_turn.Actions[ 0 ] as CDiscardCardGameAction; if ( discard_to_pile_action == null || discard_to_pile_action.Card.Color != draw_action.Color ) { return EGameActionFailure.Discard_Pile_Is_Empty; } } break; case EGameAction.Pass_Cards: if ( GameState.Mode != EGameModeType.Four_Players ) { return EGameActionFailure.Can_Only_Pass_Cards_In_A_Four_Player_Game; } if ( i != 0 ) { return EGameActionFailure.Passing_Cards_Must_Be_Only_Action; } if ( pending_turn.Actions.Count != 1 ) { return EGameActionFailure.Passing_Cards_Must_Be_Only_Action; } CPassCardsGameAction pass_action = action as CPassCardsGameAction; CPlayerHand player_hand = GameState.Get_Player_Hand( player_id ); if ( !player_hand.Contains_Card( pass_action.Card1.Color, pass_action.Card1.Value ) || !player_hand.Contains_Card( pass_action.Card2.Color, pass_action.Card2.Value ) ) { return EGameActionFailure.Card_Is_Not_In_Your_Hand; } if ( pass_action.Card1.Color == pass_action.Card2.Color && pass_action.Card1.Value == pass_action.Card2.Value ) { return EGameActionFailure.Two_Distinct_Cards_Must_Be_Passed; } if ( player_hand.Count < 8 ) { return EGameActionFailure.Not_Enough_Cards_In_Hand_To_Pass; } break; } } return EGameActionFailure.None; }