virtual void Decide(const DataObject &input, DataObject &output) { wxASSERT(2 <= input.numItems()); bool valid = true; size_t die1 = input.read<size_t>(); size_t die2 = input.read<size_t>(1); if(7 == (die1 + die2)) { wxInt32 turn = gameData<wxInt32>(shTurn); wxInt32 players = numPlayers(); wxInt32 round = ((turn - 1) / players) + 1; wxInt32 rounds = gameData<wxInt32>(shNo7Rounds); if(rounds >= round) { valid = false; } } output = DataObject(valid); }
void BuildAttackPlacements(wxInt32 strength, TileCornerSet& placements) { // Gather up all of the knights that are below this knight in strength. // If any exist on the board, they are potential attack victims. wxInt32 players = numPlayers(); for(wxInt32 i = 0; i < players; ++i) { // Can't attack self. if(i == mPlayer) { continue; } const PlayerGame::CornerObjectArray& knights = playerGame(i).getCornerObjects(shKnights); PlayerGame::CornerObjectArray::const_iterator it, itEnd = knights.end(); for(it = knights.begin(); it != itEnd; ++it) { const KnightObject* knight = static_cast<KnightObject*>( (*it).get()); if(knight->strength() < strength) { placements.insert(knight->tile1()); placements.insert(knight->tile2()); placements.insert(knight->tile3()); } } } }
virtual void Decide(const DataObject &, DataObject &output) { // If any player has a progress card besides this player, the Spy // is playable. bool canPlay = false; wxInt32 curPlayer = current(); for(wxInt32 i = 0; i < numPlayers(); ++i) { if(i != curPlayer) { // The player must have any progress card. wxInt32 total = 0; total += CountCards(shPlayableTradeCards, i); total += CountCards(shPlayablePoliticsCards, i); total += CountCards(shPlayableScienceCards, i); if(0 < total) { canPlay = true; break; } } } output = DataObject(canPlay); }
virtual void Decide(const DataObject &, DataObject &output) { // Determine if there are any players with more VPs than this player. // If there are not, they cannot play the card. wxInt32 points = playerGameData<wxInt32>(shPoints); bool canPlay = false; for(wxInt32 i = 0; i < numPlayers(); ++i) { if(points < playerGameData<wxInt32>(shPoints, i)) { // The player must also have cards to donate. wxInt32 total = 0; const Data::IntHash& resources = playerGameData<Data::IntHash>(shResources, i); Data::IntHash::const_iterator it, itEnd = resources.end(); for(it = resources.begin(); it != itEnd; ++it) { total += it->second; } if(0 < total) { canPlay = true; break; } } } output = DataObject(canPlay); }
virtual void Execute(const DataObject &) { wxString players; // Empty all of the players in the game so they can be filled in as // players rejoin. for(wxInt32 i = 0; i < numPlayers(); ++i) { if(0 != i) { players += swCommaSpace; } players += playerGame(i).player().Name(); playerGame(i).newPlayer(NullPlayer); } wxLogDebug(wxT("Restarting a network game with %s."), players.c_str()); gameData<HashString>(shNetworkRestartState) = gameData<HashString>(shState); gameData<HashString>(shState) = shNetworkRestart; RULE.Execute(shRulePrepareUI, DataObject()); RULE.Execute(shRuleRestartGame, DataObject()); // Immediately check to see if the host takes any of the seats // in the game. RULE.Execute(shNetworkRuleTakeSeat, DataObject(NET.Players().GetThisPlayer())); }
virtual void Execute(const DataObject &) { wxString players; for(wxInt32 i = 0; i < numPlayers(); ++i) { if(0 != i) { players += swCommaSpace; } players += playerGame(i).player().Name(); } wxLogDebug(wxT("Starting a new network game with %s."), players.c_str()); // Set the state different than New so anyone joining in the brief // time between when the host will not be able to add themself as a // player to the game. gameData<HashString>(shState) = shNetworkLaunch; // Randomize the players. This works because every client is using // the same pool of random numbers. RULE.Execute(shRuleRandomizePlayers, DataObject()); // Start the game. const Map::StringPairArray& rulesets = MAP.rulesets(); Controller::get().Transmit(shEventLoadRulesets, rulesets); Controller::get().Transmit(shEventStartGame, true); // Start with the first rule. RULE.Execute(shRule0, DataObject()); }
virtual void Execute(const DataObject &object) { const Player &player = object.read<Player>(); const wxBOOL ready = object.read<wxInt32>(2); // First, see if this player is already assigned a color, because // they might actually be switching colors with someone else if the // host is doing it for them. DataObject output; RULE.Decide(shNetworkLogicPlayerColor, object, output); const ColorType color = output.read<ColorType>(); // Now actually change the color. RULE.Execute(shRuleChangeColor, object); // Set their ready flag. for(wxInt32 i = 0; i < numPlayers(); ++i) { const Player &thisPlayer = playerGame(i).player(); if(player == thisPlayer) { playerGameData<wxInt32>(shReady, i) = ready; break; } } //fire the update mechanism Controller::get().Transmit(shEventPreGame, GetGame()); // Update the UI. RULE.Execute(shNetworkRuleChangeColorMessage, object); // Finally, if they had a previous color, see if someone else is // now that color, and if so, update the UI. if(CR_SIZE != color) { for(wxInt32 i = 0; i < numPlayers(); ++i) { if(playerGame(i).color() == color) { RULE.Execute(shNetworkRuleChangeColorMessage, DataObject(playerGame(i).player(), color)); } } } }
virtual void Execute(const DataObject &) { //initialize player data needed for(wxInt32 i = 0; i < numPlayers(); ++i) { playerGameData<wxInt32>(shReceivedBonus, i) = FALSE; } }
void BuildHashes() { // Just like longest road, build a set of blocked corners, and a set // of bridge corners. // First, build the hash of all side objects for this player. PlayerGame::SideObjectArray sides; playerGame(mPlayer).getAllSideObjects(sides); PlayerGame::SideObjectArray::const_iterator it, itEnd = sides.end(); for(it = sides.begin(); it != itEnd; ++it) { // Add each to the hash. SideObject::TileSide side = (*it)->tile1(); wxInt32 id = Utility::encodeSel(side.first, side.second); mSegmentHash[id].object = (*it); mSegmentHash[id].counted = false; side = (*it)->tile2(); id = Utility::encodeSel(side.first, side.second); mSegmentHash[id].object = (*it); mSegmentHash[id].counted = false; } // Now build the sets of all bridge and dead end corners. for(wxInt32 i = 0; i < numPlayers(); ++i) { // If this is the current player, they are bridge corners, // otherwise, dead end corners. IntSet &set = (i == mPlayer) ? mBridgeCorners : mDeadEndCorners; PlayerGame::CornerObjectArray objects; playerGame(i).getAllCornerObjects(objects); PlayerGame::CornerObjectArray::const_iterator it, itEnd = objects.end(); for(it = objects.begin(); it != itEnd; ++it) { // Only add them if they are dead ends, or bridges with the // bridge flag set. const CornerObjectPtr& object = (*it); if( (i != mPlayer) || (true == object->bridge())) { CornerObject::TileCorner corner = object->tile1(); set.insert(Utility::encodeSel( corner.first, corner.second)); corner = object->tile2(); set.insert(Utility::encodeSel( corner.first, corner.second)); corner = object->tile3(); set.insert(Utility::encodeSel( corner.first, corner.second)); } } } }
BehaviorTreeNode* CNormalMode::askQuestionToPlayerSequence(int player, int round) { std::string playerCam = (std::string)"player"+data2string(player+1)+(std::string)"cam1"; BehaviorTreeInternalNode* sequence; (sequence = new ParallelNode(FAIL_ON_ONE, SUCCEED_ON_ALL)) ->addChild((new SequentialNode()) ->addChild(new CPlayDialogue(_questions[player+(numPlayers()*round)]->getId())) ->addChild(new CAnimateAvatarNode(_players[player], "LEGS_NERVOUS", "TORSO_JUMP", "HEAD_HARD_SWINGING")) ->addChild(new CSetButtonStatus(_bPlayerName[player], CButton::HIGHLIGHTED)) ->addChild(new CCameraNode(playerCam)) // Camara a jugador 1 ->addChild(new CSetQuestionInHud(_questions[player+(numPlayers()*round)])) ->addChild(new CUiComponentVisibility(_game->questionsGui(), true)) // Muestra interfaz pregunta ->addChild(new CFadeUiNode(_fQuestionsGui, 0.001f)) // Hacemos un fade para mostrar el interfaz ) //->addChild(new CTimerButtonNode(_bClock, _timePerQuestion)) ; return sequence; }
virtual void Execute(const DataObject &) { for(wxInt32 i = 0; i < numPlayers(); ++i) { // Initialize space for players to "lose" their metropolises to the // volcano. playerGameData<IntArray>(shVolcanoMetropolis, i); playerGameData<wxInt32>(shMoveMetropolis, i) = FALSE; } }
virtual void Execute(const DataObject &) { wxInt32 &player = gameData<wxInt32>(shCurrentPlayer); ++player; if(numPlayers() <= player) { player = 0; } }
virtual void Execute(const DataObject &) { wxInt32 &player = gameData<wxInt32>(shCurrentPlayer); --player; if(-1 == player) { player = (numPlayers() - 1); } }
virtual void Execute(const DataObject &) { wxInt32 switchVal; //make a pass through and randomize for(wxInt32 i = 0; i < numPlayers(); i++) { //get the random value switchVal = RAND.pooled(numPlayers()); //sanity check if(switchVal == i) { continue; } std::swap(playerGames()[i], playerGames()[switchVal]); } }
virtual void Execute(const DataObject &) { for(wxInt32 i = 0; i < numPlayers(); ++i) { playerGameData<wxInt32>(shStockRoads, i) = sRoads; playerGameData<wxInt32>(shStockSettlements, i) = sSettlements; playerGameData<wxInt32>(shStockCities, i) = sCities; } }
virtual void Decide(const DataObject &input, DataObject &output) { wxASSERT(1 <= input.numItems()); wxInt32 thisTile = input.read<wxInt32>(); wxInt32 tileIsland = tile<wxInt32>(shIsland, thisTile); wxInt32 playerIsland = playerGameData<wxInt32>(shHomeIsland); //if the player has already selected an island, this tile must //be on the same island if(0 != playerIsland) { output = DataObject(tileIsland == playerIsland); return; } //total up the number of islands selected by players WX_DECLARE_HASH_MAP(wxInt32, wxInt32, wxIntegerHash, wxIntegerEqual, IntHash); IntHash hash; for(wxInt32 i = 0; i < numPlayers(); ++i) { wxInt32 island = playerGameData<wxInt32>(shHomeIsland, i); if(0 != island) { hash[island]++; } } //if the player has not yet selected a home island, then this //location will be allowed, as long as half of the players or //less (round up) are not on the island float dif = numPlayers() - hash[tileIsland]; float half = float(numPlayers()) * 0.5f; output = DataObject((dif > half)); }
virtual void Decide(const DataObject &input, DataObject &output) { const Player &player = input.read<Player>(); ColorType color = CR_SIZE; for(wxInt32 i = 0; i < numPlayers(); ++i) { if(player == playerGame(i).player()) { color = playerGame(i).color(); break; } } output = DataObject(color); }
virtual void Execute(const DataObject &object) { wxLogDebug(wxT("NetworkRuleConnectionLostInGame: Entry.")); // Execute any extensions that want to handle this. ExecuteExtensions(object); const Player &player = object.read<Player>(); // No matter what the case, the player needs to be replaced with the // NullPlayer in the current game so their seat becomes open. for(wxInt32 i = 0; i < numPlayers(); ++i) { if(player == playerGame(i).player()) { // Set them as Null. playerGame(i).newPlayer(NullPlayer); // Refresh the PlayerUI with the new name. Controller::get().Transmit(shEventNewPlayer, DataObject(GetGame(), i)); break; } } // If we are in the game right now we need to shut everything // down and fire up the Network Restart dialog. if(shNetworkRestart != gameData<HashString>(shState)) { Controller::get().Transmit(shEventShutdownUI, 0); gameData<HashString>(shNetworkRestartState) = gameData<HashString>(shState); gameData<HashString>(shState) = shNetworkRestart; wxLogDebug(wxT("NetworkRuleConnectionLostInGame: State is now ") wxT("NetworkRestart.")); RULE.Execute(shRuleRestartGame, DataObject()); } // Always update the players in the network restart list. Controller::get().Transmit(shEventNetworkRestartPlayers, GetGame()); Controller::get().Transmit(shEventSpectator, 0); wxLogDebug(wxT("NetworkRuleConnectionLostInGame: Exit.")); }
virtual void Execute(const DataObject &object) { // Only do stuff is this is the server and if we are still in the New // game state. if( (true == NET.Players().IsHost()) && (shNew == gameData<HashString>(shState)) ) { const Player &player = object.read<Player>(); const ColorType color = object.read<ColorType>(1); // The reason we scan the game like this is that due to network // latency, two players may request the same color at the same // time before either of them gets updated with who has that color. // This rule protects the game by only allowing the request to go // through if the color is free. bool safe = true; for(wxInt32 i = 0; i < numPlayers(); ++i) { const PlayerGame &playergame = this->playerGame(i); const Player &indexPlayer = playergame.player(); // If we find the color being used or, heaven forbid, the // player already in the game, forbid the assignment. if( (color == playergame.color()) || (player == indexPlayer)) { safe = false; break; } } // If we made it through safely, assign the color. if(true == safe) { // Since we are calling this from within another rule, the // RuleEngine isn't going to send it on to the network. // Therefore, we have to do it manually. wxASSERT(NET.IsConnected()); NET.SendRule(shNetworkRuleAddPlayer, object); } } }
void BuildInvalidSet(TileSideSet &invalids) { PlayerGame::SideObjectArray objects; for(wxInt32 i = 0; i < numPlayers(); ++i) { const PlayerGame &thisGame = playerGame(i); thisGame.getAllSideObjects(objects); } // Build the hash. PlayerGame::SideObjectArray::const_iterator it, itEnd = objects.end(); for(it = objects.begin(); it != itEnd; ++it) { invalids.insert((*it)->tile1()); invalids.insert((*it)->tile2()); } }
virtual void Execute(const DataObject &object) { const HashString& card = object.read<HashString>(); RULE.Execute(shRulePlayProgressCardStart, DataObject(card, shTrade)); // Set things up to be able to use the Commercial Harbor throughout // the rest of the turn. wxInt32 curPlayer = current(); for(wxInt32 i = 0; i < numPlayers(); ++i) { if(i != curPlayer) { playerGameData<wxInt32>(shCommercialHarbor, i) = TRUE; } } // Play the sound. RULE.Execute(shRulePlaySound, DataObject(SOUND_PLAY_COMMERCIAL_HARBOR_CARD)); RULE.Execute(shRulePlayProgressCardEnd, DataObject()); }
BehaviorTreeNode* CNormalMode::roundsSequence(){ BehaviorTreeInternalNode* sequence = new SequentialNode(); for(int r=0; r<numRounds(); ++r){ sequence->addChild(new CCleanHud); sequence->addChild(getPlayerHudVisbility(true)); for(int p=0; p<numPlayers(); ++p) { sequence->addChild(new CResetTimeNode((CModeBT*)this)); sequence->addChild(askQuestionToPlayerSequence(p, r)); sequence->addChild(answerSequence()); sequence->addChild(new CSetButtonStatus(_bColorAnswers[0], CButton::NORMAL)); /// Limpio las respuestas sequence->addChild(new CSetButtonStatus(_bColorAnswers[1], CButton::NORMAL)); sequence->addChild(new CSetButtonStatus(_bColorAnswers[2], CButton::NORMAL)); sequence->addChild(new CSetButtonStatus(_bColorAnswers[3], CButton::NORMAL)); sequence->addChild(new CRandomIdleNode(1000)); sequence->addChild(new CAnimateAvatarNode(_players[p], "LEGS_SWINGING", "TORSO_SWINGING", "HEAD_IDLE")); sequence->addChild(new CSetButtonStatus(_bPlayerName[p], CButton::NORMAL)); sequence->addChild(new CNextQuestionNode(this)); sequence->addChild(new CNextPlayerNode(this)); //std::cout<<"Jugador: "<<p<<" Pregunta: "<<p+(numPlayers()*r)<<" en ronda: "<<r<<"\n"; } sequence->addChild(new CNextRoundNode(this)); sequence->addChild((new CConditionNode(new CEndModeCondition)) /// Compruebo si quedan rondas ->addChild((new SequentialNode()) ->addChild(new CClearCameraQueue) ->addChild(new COrientAvatarNode(_host,180.0f)) ->addChild(new CChangeStateNode("intro_ganadores")) ) ); sequence->addChild((new CInvertedConditionNode(new CEndModeCondition)) ->addChild(scoreReviewSequence()) ); sequence->addChild(new CClearCameraQueue); } return sequence; }
virtual void Execute(const DataObject &) { bool cardFound = false; wxInt32 players = numPlayers(); wxInt32 curPlayer = current(); bool thisPlayerCard = false; wxString thisPlayerName; // Go through each player, starting with the current player. If // they get a progress card, run the card dialog. for(wxInt32 i = 0; i < players; ++i) { wxInt32 thisPlayer = (i + curPlayer) % players; if(TRUE == playerGameData<wxInt32>(shGainProgressCard, thisPlayer)) { // This player is now in a blocking action. RULE.Execute(shRuleBeginBlockingAction, DataObject(thisPlayer)); // They have some. cardFound = true; // Shut everything down. Controller::get().Transmit(shEventBuildUI, DataObject(false, GetGame())); Controller::get().Transmit(shEventControlsUI, DataObject(false)); Controller::get().Transmit(shEventProgressCards, DataObject(thisPlayer, GetGame())); thisPlayerName = playerGame(thisPlayer).player().Name(); // See if this player is spending gold. DataObject input(thisPlayer), output; RULE.Decide(shLogicIsThisPlayer, input, output); if(true == output.read<bool>()) { thisPlayerCard = true; } // Only do this one at a time. break; } } // If all cards have been selected, continue on. if(false == cardFound) { RULE.Execute(shRuleMarkerPostDiceRoll, DataObject()); } // Otherwise, set the text. else { wxString str1; if(true == thisPlayerCard) { str1 = wxString::Format(stSelectAProgressCard.c_str(), thisPlayerName.c_str()); } else { str1 = wxString::Format(stWaitingSelectAProgressCard.c_str(), thisPlayerName.c_str()); } Controller::get().Transmit(shEventMessageUI, DataObject(str1, GetGame())); } }
virtual void Execute(const DataObject &) { bool goldFound = false; wxInt32 players = numPlayers(); wxInt32 curPlayer = current(); bool thisPlayerGold = false; wxString thisPlayerName; // Go through each player, starting with the current player. If // they have gold, stop and run the gold selection dialog. for(wxInt32 i = 0; i < players; ++i) { wxInt32 thisPlayer = (i + curPlayer) % players; const Data::IntHash& resources = playerGameData<Data::IntHash>(shResources, thisPlayer); // See if they have gold. Data::IntHash::const_iterator it = resources.find(shGold); if( (resources.end() != it) && (0 < it->second)) { // They have some. goldFound = true; // This player is now in a blocking action. RULE.Execute(shRuleBeginBlockingAction, DataObject(thisPlayer)); // Shut everything down. Controller::get().Transmit(shEventBuildUI, DataObject(false, GetGame())); Controller::get().Transmit(shEventControlsUI, DataObject(false)); Controller::get().Transmit(shEventGold, DataObject(thisPlayer, GetGame())); thisPlayerName = playerGame(thisPlayer).player().Name(); // See if this player is spending gold. DataObject input(thisPlayer), output; RULE.Decide(shLogicIsThisPlayer, input, output); if(true == output.read<bool>()) { thisPlayerGold = true; } // Only do this one at a time. break; } } // If all gold has been spent, continue on. if(false == goldFound) { RULE.Execute(shRuleMarkerPostDiceRoll, DataObject()); } // Otherwise, set the text. else { wxString str1; if(true == thisPlayerGold) { str1 = wxString::Format(stStringSpendYourGold.c_str(), thisPlayerName.c_str()); } else { str1 = wxString::Format(stWaitingSpendGold.c_str(), thisPlayerName.c_str()); } Controller::get().Transmit(shEventMessageUI, DataObject(str1, GetGame())); } }
virtual void Execute(const DataObject &object) { // Only execute if we're supposed to. if(false == object.read<bool>()) { return; } // So, here's how the Longest Road algorithm works: // // 1. If no player currently has Longest Road... // a) and no one has more than 5 connected roads, no one gets // Longest Road. // b) and multiple players have more than 5 connected roads, but // are tied, no one gets Longest Road. // c) and any one player has more than 5 connected roads and is in // the lead, they get Longest Road. // 2. If someone already has Longest Road... // a) and anyone else ties them in length, the original player // retains Longest Road. // b) and multiple players surpass them in length, but are tied, // Longest Road reverts to unclaimed. // c) and any one person surpasses them and everyone else in // length, they get Longest Road. // d) and the player drops below 5 in road length, loses Longest // Road, with Longest Road going to the appropriate player // based on the previous criteria. // // With that in mind, run through each player, retrieving their // longest chain of roads. wxInt32 players = numPlayers(); wxInt32 current = gameData<wxInt32>(shLongestRoadPlayer); std::vector<wxInt32> lengths(numPlayers(), 0); std::vector<PlayerGame::SideObjectArray> chains(numPlayers()); PlayerGame::SideObjectArray longestChain; for(wxInt32 i = 0; i < players; ++i) { DataObject input(i), output; RULE.Decide(shLogicRoadLength, input, output); lengths[i] = output.read<wxInt32>(); chains[i] = output.read<PlayerGame::SideObjectArray>(1); // While we're going through each player, clear any Longest Road // highlighting. PlayerGame::SideObjectArray objects; playerGame(i).getAllSideObjects(objects); PlayerGame::SideObjectArray::const_iterator it, itEnd = objects.end(); for(it = objects.begin(); it != itEnd; ++it) { (*it)->longest(false); } } // Now that we have all the lengths, figure out if Longest Road // changes. wxInt32 longestLength = 0; wxInt32 longestPlayer = -1; // In the special case where the original player drops below 5 in road // length, clear them out first and then apply the normal rules. if( (-1 != current) && (5 > lengths[current])) { RULE.Execute(shRuleLoseLongestRoad, DataObject(current)); current = -1; } // No current holder. if(-1 == current) { // With no current holder, see if anyone is over 5 and the clear // leader (no ties). for(wxInt32 i = 0; i < players; ++i) { wxInt32 len = lengths[i]; if(5 <= len) { // A clear leader. if(longestLength < len) { longestLength = len; longestPlayer = i; } // A tie. else if(longestLength == len) { longestPlayer = -1; } } } } // Someone already has it. else { // Set the mark that must be beaten. longestPlayer = current; longestLength = lengths[current]; for(wxInt32 i = 0; i < players; ++i) { // Skip the current holder. if(i == current) { continue; } wxInt32 len = lengths[i]; // Look for a clear leader. if(longestLength < len) { longestLength = len; longestPlayer = i; } // Here's where it gets interesting. If they tie the original // player, it counts for nothing. However, if they tie a new // player who has already surpassed the original player, then // it's a deadlock, and no one is the longest player. else if((longestLength == len) && (longestPlayer != current)) { longestPlayer = -1; } } } // Always update the highlighting on the longest road. if(-1 != longestPlayer) { PlayerGame::SideObjectArray& chain = chains[longestPlayer]; // Mark all of the longest chain. PlayerGame::SideObjectArray::const_iterator it, itEnd = chain.end(); for(it = chain.begin(); it != itEnd; ++it) { (*it)->longest(true); } } // If it has changed hands, take it away from the loser and award it // to the winner. if(current != longestPlayer) { // Take it away from the loser. if(-1 != current) { RULE.Execute(shRuleLoseLongestRoad, DataObject(current)); } // Give it to the winner. if(-1 != longestPlayer) { RULE.Execute(shRuleGainLongestRoad, DataObject(longestPlayer)); } } // Regardless of what happens, update every player. Controller::get().Transmit(shEventPlayerUI, DataObject(GetGame(), -1)); }
virtual void Execute(const DataObject &object) { bool done = true; bool first = true; bool thisPlayer = false; wxString thisName; // If there's no data in the object, this is the first time through, // so show the dialogs. bool showDialog = true; wxInt32 player = -1; if(1 <= object.numItems()) { // It's possible for a player to have 6 cards, if they get 5 on // their turn, don't use any, then get another on the next roll. // In that case, they may have to discard again. player = object.read<wxInt32>(); } wxString str; wxInt32 curPlayer = current(); // See if any players need to discard a progress card. for(wxInt32 i = 0; i < numPlayers(); ++i) { if( (i != curPlayer) && (4 < FindTotal(i))) { if( (true == showDialog) || (player == i)) { // This player is now in a blocking action. RULE.Execute(shRuleBeginBlockingAction, DataObject(curPlayer)); // Shut everything down. Controller::get().Transmit(shEventBuildUI, DataObject(false, GetGame())); Controller::get().Transmit(shEventControlsUI, DataObject(false)); Controller::get().Transmit(shEventDiscardProgressCards, DataObject(i, GetGame())); } // Add their name to the waiting list. if(true == first) { first = false; } else { str += swCommaSpace; } const wxString& name = playerGame(i).player().Name(); str += name; // See if this player is losing cards. DataObject input(i), output; RULE.Decide(shLogicIsThisPlayer, input, output); if(true == output.read<bool>()) { thisPlayer = true; thisName = name; } done = false; } } if(true == done) { RULE.Execute(shRuleMarkerPostDiceRoll, DataObject()); } else { wxString str1; if(true == thisPlayer) { str1 = wxString::Format(stDiscardOneProgressCard.c_str(), thisName.c_str()); } else { str1 = wxString::Format(stWaitingDiscardOneProgressCard.c_str(), str.c_str()); } Controller::get().Transmit(shEventMessageUI, DataObject(str1, GetGame())); } }
virtual void Execute(const DataObject &object) { // This isn't purely accurate, but the current player is now 100% // dependent on the other players finishing and should not have a // turn timer. RULE.Execute(shRuleEndBlockingAction, DataObject(current())); bool done = true; bool first = true; bool thisPlayer = false; wxString thisName; // If there's no data in the object, this is the first time through, // so show the lose card dialogs. bool showDialog = true; if(1 <= object.numItems()) { showDialog = object.read<bool>(); } wxString str; // See if any players need to lose cards. for(wxInt32 i = 0; i < numPlayers(); ++i) { if(TRUE == playerGameData<wxInt32>(shWedding, i)) { if(true == showDialog) { // This player is now in a blocking action. RULE.Execute(shRuleBeginBlockingAction, DataObject(i)); // Shut everything down. Controller::get().Transmit(shEventBuildUI, DataObject(false, GetGame())); Controller::get().Transmit(shEventControlsUI, DataObject(false)); Controller::get().Transmit(shEventWedding, DataObject(i, GetGame())); } // Add their name to the waiting list. if(true == first) { first = false; } else { str += swCommaSpace; } const wxString& name = playerGame(i).player().Name(); str += name; // See if this player is losing cards. DataObject input(i), output; RULE.Decide(shLogicIsThisPlayer, input, output); if(true == output.read<bool>()) { thisPlayer = true; thisName = name; } done = false; } } if(true == done) { RULE.Execute(shRulePlayProgressCardEnd, DataObject()); } else { wxString str1; if(true == thisPlayer) { str1 = wxString::Format(stSelectTwoResourcesOrCommoditiesToGive.c_str(), thisName.c_str()); } else { str1 = wxString::Format(stWaitingSelectTwoResourcesOrCommoditiesToGive.c_str(), str.c_str()); } Controller::get().Transmit(shEventMessageUI, DataObject(str1, GetGame())); } }