virtual void Unexecute(const DataObject &object) { wxASSERT(1 <= object.numItems()); wxInt32 player = current(); if(2 <= object.numItems()) { player = object.read<wxInt32>(1); } //first, determine the tile and corner being built on wxInt32 tile, corner; boost::tie(tile, corner) = Utility::decodeSel(object.read<wxInt32>()); PlayerGame &playergame(playerGame(player)); wxInt32 turn = gameData<wxInt32>(shTurn); //now create the settlement object for this player and remove it from //their list CornerObjectPtr settlement(CornerObjectPtr(new SettlementObject( player, turn, playergame.color(), GetGame(), tile, corner))); playergame.removeCornerObject(shSettlements, settlement); //add one to the player's stock settlements playerGameData<wxInt32>(shStockSettlements, player) += 1; // Subtract one point from the player's score. RULE.Execute(shRuleAdjustPoints, DataObject(player, -1)); }
//---------------------------- PRIVATE -----------------------------// void wxMessageUI::OnUpdate(const DataObject &object) { wxASSERT(2 == object.numItems()); //read the data out of the UI wxString message = object.read<wxString>(); const GamePtr &game = object.read<GamePtr>(1); spText->Freeze(); spText->SetLabel(message); //set the label color to be the current player, unless the game has ended, //in which case it should be white if(shComplete == game->read<HashString>(shState)) { wxColour colour = SKIN.Element(shGameUIText); spText->SetForegroundColour(colour); } else { ColorType type; type = game->playerGame(game->read<wxInt32>( shCurrentPlayer)).color(); spText->SetForegroundColour(ColorInfoData::UIColor(type)); } spText->Thaw(); spText->Refresh(); }
virtual void Decide(const DataObject &input, DataObject &output) { // There are two conditions that must be met in order for a player to // be allowed to build a knight: // // 1) They must have the resources to activate a knight. // 2) They must have at least one inactive knight on the board // // None of these conditions can be affected by other rulesets. bool can = false; wxInt32 trades = 0; // Condition 1. RULE.Decide(shLogicCanPurchaseActivateKnight, input, output); wxASSERT(2 <= output.numItems()); if(true == output.read<bool>()) { trades = output.read<wxInt32>(1); // Condition 2. output.reset(); RULE.Decide(shLogicCanPlaceActivateKnight, input, output); can = (false == output.read<PlayerGame::CornerObjectArray>().empty()); } output = DataObject(can, trades); }
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); }
virtual void Execute(const DataObject &object) { // The current player has ended a blocking action. RULE.Execute(shRuleEndBlockingAction, DataObject(current())); wxASSERT(1 <= object.numItems()); typedef std::map<HashString, wxInt32> ResourceMap; const ResourceMap& map = object.read<ResourceMap>(); // Read the two dice values. const HashString& str1 = map.begin()->first; const HashString& str2 = (++map.begin())->first; wxASSERT(1 == str1.size()); wxASSERT(4 == str2.size()); wxInt32 die1 = boost::lexical_cast<wxInt32>(str1); wxInt32 die2 = boost::lexical_cast<wxInt32>(str2.at(3)); gameData<wxInt32>(shAlchemistDie1) = die1; gameData<wxInt32>(shAlchemistDie2) = die2; // The player has now played an Alchemist on their turn. playerGameData<wxInt32>(shAlchemist) = TRUE; RULE.Execute(shRulePlayProgressCardEnd, DataObject()); }
virtual void Decide(const DataObject &input, DataObject &output) { // There are three conditions that must be met in order for a player to // be allowed to build a city: // // 1) They must have at least one city in stock. // 2) They must have the resources to purchase a city. // 3) They must have a settlement on the board to replace with the // city. // // None of these conditions can be affected by other rulesets. bool canBuild = false; wxInt32 trades = 0; // Condition 1. if(0 < playerGameData<wxInt32>(shStockCities)) { // Condition 2. RULE.Decide(shLogicCanPurchaseCity, input, output); wxASSERT(2 <= output.numItems()); if(true == output.read<bool>()) { trades = output.read<wxInt32>(1); // Condition 3. canBuild = !(playerGame().getCornerObjects(shSettlements).empty()); } } output = DataObject(canBuild, trades); }
virtual void Execute(const DataObject &object) { wxASSERT(3 <= object.numItems()); wxInt32 tile, corner; boost::tie(tile, corner) = Utility::decodeSel(object.read<wxInt32>()); wxInt32 player = object.read<wxInt32>(1); const HashString& type = object.read<HashString>(2); bool found = false; // First, see if there are even any extra objects here. PlayerGame::CornerObjectArray extras = playerGame(player).getCornerObjects(shExtra); PlayerGame::CornerObjectArray::const_iterator it, itEnd = extras.end(); for(it = extras.begin(); it != itEnd; ++it) { CornerObjectPtr extra = (*it); if(true == extra->onTileCorner(std::make_pair(tile, corner))) { // Remove it. playerGame(player).removeCornerObject(shExtra, extra); found = true; } } if(true == found) { // If they have an extra, find the object that was built. CornerObjectPtr obj; const PlayerGame::CornerObjectArray& objects = playerGame(player).getCornerObjects(type); itEnd = objects.end(); for(it = objects.begin(); it != itEnd; ++it) { CornerObjectPtr object = (*it); if(true == object->onTileCorner(std::make_pair(tile, corner))) { obj = object; break; } } wxASSERT(obj); // Add a new extra to replace the old one. wxInt32 turn = gameData<wxInt32>(shTurn); CornerObjectPtr extra(new ExtraObject(player, turn, CR_SIZE, GetGame(), tile, corner, obj)); obj->below(extra); playerGame(player).addCornerObject(shExtra, extra); AggregatorObjectPtr aggregate(new AggregatorObject); aggregate->add(extra); Controller::get().Transmit(shEventGameObjects, aggregate); } }
virtual void Execute(const DataObject &object) { wxASSERT(1 <= object.numItems()); wxInt32 player = current(); if(2 <= object.numItems()) { player = object.read<wxInt32>(1); } //first, determine the tile and corner being built on wxInt32 tile, corner; boost::tie(tile, corner) = Utility::decodeSel(object.read<wxInt32>()); PlayerGame &playergame(playerGame(player)); ColorType color = playergame.color(); wxInt32 turn = gameData<wxInt32>(shTurn); //now create the settlement object for this player and add it to their //list CornerObjectPtr settlement(CornerObjectPtr(new SettlementObject( player, turn, color, GetGame(), tile, corner))); playergame.addCornerObject(shSettlements, settlement); //subtract one from the player's stock settlements playerGameData<wxInt32>(shStockSettlements, player) -= 1; //send it to the view AggregatorObjectPtr aggregate(new AggregatorObject); aggregate->add(settlement); Controller::get().Transmit(shEventGameObjects, aggregate); // Run an animation if needed. RULE.Execute(shRuleAnimatePlacement, DataObject(playergame.player(), GameObjectPtr(settlement), color)); // Adjust stats. RULE.Execute(shRulePurchaseItem, DataObject(current(), shSettlement)); // Add one point to the player's score. RULE.Execute(shRuleAdjustPoints, DataObject(player, 1)); }
virtual void Execute(const DataObject &object) { wxASSERT(1 <= object.numItems()); wxInt32 player = object.read<wxInt32>(); wxASSERT(-1 != player); Controller::get().Transmit(shEventAcceptOffer, player); }
virtual void Execute(const DataObject &object) { wxASSERT(2 <= object.numItems()); const TileSideSet &sides = object.read<TileSideSet>(); wxASSERT(false == sides.empty()); const HashString& rule = object.read<HashString>(1); // Create a SideSelectionObject that holds all of the ship placement // possibilities. ColorType color = playerGame().color(); SideSelectionObject *selections = new SideSelectionObject(rule, color); float rotation = 0.0f; TileSideSet::const_iterator it, itEnd = sides.end(); for(it = sides.begin(); it != itEnd; ++it) { Vector coords = tile(it->first)->coords(); UtilityGL::sideCoords(coords, rotation, it->second); selections->add(SideSelectionObject::SideSelectionTuple( Utility::encodeSel(it->first, it->second), coords, rotation)); } // Transmit the selections. Controller::get().Transmit(shEventSelectionObject, SelectionObjectPtr(selections)); // For visual help, dim all tiles except those on which the ships can // be placed. RULE.Execute(shRuleResetObjectFlags, DataObject(IGameObject::Dim)); RULE.Execute(shRuleResetTileFlags, DataObject(IGameObject::Dim)); for(it = sides.begin(); it != itEnd; ++it) { wxInt32 tile1 = it->first; wxInt32 tile2 = tile<IntArray>(shSides, tile1)[it->second]; tile(tile1)->reset(); if(-1 != tile2) { tile(tile2)->reset(); } } // In addition, turn on the pirate tile with the angry red outline. const HexObjectPtr& pirate = GetGame()->getHexObject(shPirate); wxASSERT(pirate); wxInt32 pirateTile = pirate->tile(); if(-1 != pirateTile) { tile(pirateTile)->reset(); tile(pirateTile)->set(TileObject::OutlineRed); } }
virtual void Decide(const DataObject &input, DataObject &output) { wxASSERT(1 <= input.numItems()); const HashString& type = input.read<HashString>(); bool isGold = (shGold == type); output = DataObject(!isGold); }
virtual void Decide(const DataObject &input, DataObject &output) { wxASSERT(1 <= input.numItems()); //query the default logic that determines if a tile land or not bool initial = (TRUE == tile<wxInt32>(shInitial, input.read<wxInt32>())); output = DataObject(initial); }
virtual void Execute(const DataObject &object) { wxASSERT(2 <= object.numItems()); HashString rule = object.read<HashString>(); wxInt32 priority = object.read<wxInt32>(1); //mark it in the game data so it can be saved gameData<wxInt32>(rule) = priority; }
virtual void Execute(const DataObject &object) { wxASSERT(1 <= object.numItems()); typedef std::map<HashString, wxInt32> ResourceMap; const ResourceMap& resources = object.read<ResourceMap>(); wxInt32 player = object.read<wxInt32>(1); // This player has ended a blocking action. RULE.Execute(shRuleEndBlockingAction, DataObject(player)); // First off, the player has now received a resource. playerGameData<wxInt32>(shResourcesGained, player) = 1; wxString str; bool first = true; // Execute the transactions. ResourceMap::const_iterator it, itEnd = resources.end(); for(it = resources.begin(); it != itEnd; ++it) { const HashString& res = it->first; wxInt32 amount = it->second; // Adjust counts. RULE.Execute(shRuleBankTransact, DataObject(player, res, amount)); DataObject input(res), output; RULE.Decide(shLogicResourceName, input, output); const wxString& name = output.read<wxString>(); if(true == first) { first = false; } else { str += swCommaSpace; } str += wxString::Format(swIntStringFormat.c_str(), amount, name.c_str()); } wxString text = wxString::Format(stSelects.c_str(), swStringFormat.c_str(), str.c_str()); RULE.Execute(shRuleUpdateNetworkUI, DataObject(text, player)); Controller::get().Transmit(shEventPlayerUI, DataObject(GetGame(), player)); RULE.Execute(shRuleAqueduct, DataObject()); }
void OnNetworkConnectionAttempt(const DataObject& object) { wxASSERT(2 <= object.numItems()); const wxIPV4address& address = object.read<wxIPV4address>(); INetworkClient* client = object.read<INetworkClient*>(1); wxNetworkConnectionAttemptDialog dialog(GetMainFrame(), address, client); dialog.ShowModal(); }
virtual void Execute(const DataObject &object) { wxASSERT(1 <= object.numItems()); // Update the UI. RULE.Execute(shRuleUpdateNetworkUI, DataObject(stPlacesASettlement)); //play the correct sound RULE.Execute(shRulePlaySettlementSound, object); RULE.Execute(shRulePlaceSettlementCommon, object); }
void wxNetworkRestartListCtrl::OnCountdownTime(const DataObject &object) { wxASSERT(2 <= object.numItems()); const wxInt32 index = object.read<wxInt32>(); const wxTimeSpan &time = object.read<wxTimeSpan>(1); // Update the player. wxString str = stWaiting + time.Format(swMinutesSeconds.c_str()); SetItemText(index, swPlayer, str); }
virtual void Execute(const DataObject &object) { wxInt32 id = object.read<wxInt32>(); wxInt32 player = current(); if(2 <= object.numItems()) { player = object.read<wxInt32>(1); } RULE.Execute(shRuleReplaceExtras, DataObject(id, player, shSettlements)); }
virtual void Execute(const DataObject &object) { wxASSERT(1 <= object.numItems()); wxInt32 player = object.read<wxInt32>(); wxASSERT(-1 != player); RULE.Execute(shRulePlaySound, DataObject(SOUND_TRADE_REFUSE)); // If a player says they won't trade, it should also immediately reject // any trade offers they are currently in. Controller::get().Transmit(shEventRejectOffer, player); Controller::get().Transmit(shEventWontTrade, player); }
virtual void Decide(const DataObject &input, DataObject &output) { wxASSERT(1 <= input.numItems()); wxInt32 index = input.read<wxInt32>(); wxString name; if(-1 != index) { name = playerGame(index).player().Name(); } output = DataObject(name); }
virtual void Execute(const DataObject &object) { // The current player is now in a blocking action. RULE.Execute(shRuleBeginBlockingAction, DataObject(current())); wxASSERT(1 <= object.numItems()); //retrieve the text to put in the MessageUI DataObject input(0), output; const HashString& state = gameData<HashString>(shState); if(false == DecideHash(state, input, output)) { wxLogError( wxString::Format(wxT("Programmer Error: No State %s in ") wxT("RuleRequestInitialRoadSeafarers"), state.cwx_str())); return; } wxASSERT(3 == output.numItems()); wxString text1 = output.read<wxString>(); wxString text2 = output.read<wxString>(1); HashString logic = HashString::Format(shLogicStringFormat.c_str(), output.read<HashString>(2).c_str()); HashString rule = HashString::Format(shRuleStringFormat.c_str(), output.read<HashString>(2).c_str()); //if this involves ships, do some crazy mojo if(TRUE == gameData<wxInt32>(shInitialShip)) { text1 = stPlaceAShip; text2 = stWaitingPlaceAShip; wxInt32 index = logic.find(shRoad); wxASSERT(-1 != index); logic.replace(index, 4, shShip); logic = HashString(logic.c_str()); } RULE.Execute(shRuleUpdateMessageUI, DataObject(text1, text2)); RULE.Execute(shRuleLocateInitialRoad, DataObject( object.read<wxInt32>(), logic, rule)); }
virtual void Decide(const DataObject &input, DataObject &output) { TileCorner knight = input.read<TileCorner>(); mPlayer = input.read<wxInt32>(1); bool attack = false; wxInt32 strength = -1; // Check for the attack flag. if(3 <= input.numItems()) { attack = true; strength = input.read<wxInt32>(2); } TileCornerSet placements; // If we're attacking another knight, we need to build the set of all // opponent knights that could possibly be attacked by this knight. if(true == attack) { BuildAttackPlacements(strength, placements); } // Otherwise, if we're moving the knight, build the set of all valid // move locations (which is just where can a new knight be placed). else { RULE.Decide(shLogicCanPlaceKnight, DataObject(mPlayer), output); placements = output.read<TileCornerSet>(); } if(false == placements.empty()) { BuildPossiblePlacements(knight, placements); BuildPlacements(knight); } output = DataObject(mAvailablePlacements); mAvailablePlacements.clear(); mSegmentHash.clear(); mPossiblePlacements.clear(); mBridgeCorners.clear(); mDeadEndCorners.clear(); }
virtual void Decide(const DataObject &input, DataObject &output) { wxASSERT(1 <= input.numItems()); //read the tile and side from the input wxInt32 thisTile, side; boost::tie(thisTile, side) = input.read<TileCorner>(); //if both this tile and the opposing tile are oceans, no good wxInt32 otherTile = tile<IntArray>(shSides, thisTile)[side]; bool border1 = (TRUE == tile<wxInt32>(shBorder, thisTile)); bool border2 = (TRUE == tile<wxInt32>(shBorder, otherTile)); bool valid = (false == border1) || (false == border2); output = DataObject(valid); }
virtual void Execute(const DataObject &object) { wxInt32 index = -1; if(2 <= object.numItems()) { index = object.read<wxInt32>(1); } const wxString& message = object.read<wxString>(); const wxString& name = playerGame(index).player().Name(); // Use the given string as the format string and add the player's name. wxString str = wxString::Format(message.c_str(), name.c_str()); HTML::Color(str, playerGame(index).color()); RULE.Execute(shRuleGenerateSystemMessage, DataObject(str)); }
virtual void Decide(const DataObject &input, DataObject &output) { // There are three conditions that must be met in order for a player to // be allowed to build a road: // // 1) They must have at least one road in stock. // 2) They must have the resources to purchase a road. // 3) They must have a location on the board to place the road. // // Condition 1 is static and cannot be affected by any other rulesets. // Condition 2 may be affected by other rulesets (i.e. Road Building // card). // Condition 3 may be affected by other rulesets (i.e. Seafarers). bool canBuild = false; wxInt32 trades = 0; // Condition 1. if(0 < playerGameData<wxInt32>(shStockRoads)) { // Condition 2. RULE.Decide(shLogicCanPurchaseRoad, input, output); wxASSERT(2 <= output.numItems()); if(true == output.read<bool>()) { trades = output.read<wxInt32>(1); // Condition 3. output.reset(); RULE.Decide(shLogicCanPlaceRoad, input, output); typedef std::pair<wxInt32, wxInt32> TileSide; typedef std::set<TileSide> TileSideSet; canBuild = (false == output.read<TileSideSet>().empty()); } } output = DataObject(canBuild, trades); }
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 Execute(const DataObject &object) { wxASSERT(2 <= object.numItems()); wxInt32 offerPlayer = object.read<wxInt32>(2); DataObject input(-1), output; RULE.Decide(shLogicIsThisPlayer, input, output); wxInt32 thisPlayer = output.read<wxInt32>(1); // Going from trader to tradees. if(offerPlayer == current()) { RULE.Execute(shRulePlaySound, DataObject(SOUND_TRADE_OFFER)); // Handle spectators. if(-1 == thisPlayer) { thisPlayer = -2; } // Launch the tradee stuff if needed. Controller::get().Transmit(shEventOthersTrade, DataObject(GetGame(), thisPlayer)); // The current trade offer is always updated. Controller::get().Transmit(shEventCurrentOffer, object); // Going from trader to tradees. RULE.Execute(shRuleCurrentOffer, object); // The user performed a game action. RULE.Execute(shRulePerformGameAction, DataObject()); } // Going from tradee to trader. else { Controller::get().Transmit(shEventPlayerOffer, object); } }
virtual void Decide(const DataObject &input, DataObject &output) { // There are two conditions that must be met in order for a player to // be allowed to buy a dev card. // // 1) There must be at least one card left in the bank. // 2) They must have the resources to purchase a card. // // Condition 1 is static and cannot be affected by any other rulesets. // Condition 2 is static and cannot be affected by any other rulesets. bool canBuild = false; wxInt32 trades = 0; // Count how many dev cards are left. wxInt32 cards = 0; const Data::IntHash& devCards = gameData<Data::IntHash>(shBankDevCards); Data::IntHash::const_iterator it, itEnd = devCards.end(); for(it = devCards.begin(); it != itEnd; ++it) { cards += it->second; } // Condition 1. if(0 < cards) { // Condition 2. RULE.Decide(shLogicCanPurchaseDevCard, input, output); wxASSERT(2 <= output.numItems()); canBuild = output.read<bool>(); if(true == canBuild) { trades = output.read<wxInt32>(1); } } output = DataObject(canBuild, trades); }
virtual void Execute(const DataObject &object) { wxASSERT(1 <= object.numItems()); //remove the player from the game const Player &player = object.read<Player>(); Game::PlayerGameArray::iterator it = playerGames().begin(), itEnd = playerGames().end(); for(; it != itEnd; ++it) { if(player == it->player()) { playerGames().erase(it); //fire the update mechanism Controller::get().Transmit(shEventPreGame, GetGame()); break; } } }
virtual void Decide(const DataObject &input, DataObject &output) { wxASSERT(1 <= input.numItems()); bool win = false; // Ignore any point adjustments during an undo. if(false == RULE.InUndo()) { wxInt32 player = input.read<wxInt32>(); wxInt32 points = playerGameData<wxInt32>(shPoints, player); wxInt32 curPlayer = current(); wxInt32 winPoints = gameData<wxInt32>(shPoints); if( (player == curPlayer) && (points >= winPoints)) { win = true; } } output = DataObject(win); }