예제 #1
0
//Sends a fleet back to it's home planet
void TaeTurn::sendHome(uint32_t fleet) {
    Game* game = Game::getGame();
    ObjectManager* obm = game->getObjectManager();
    ObjectTypeManager* obtm = game->getObjectTypeManager();
    PlayerManager::Ptr pm = game->getPlayerManager();

    IGObject::Ptr fleetobj = obm->getObject(fleet);
    //Check to make sure it is really a fleet
    if(fleetobj->getType() != obtm->getObjectTypeByName("Fleet")) {
        return;
    }

    //Get all the required objects
    Fleet* f = (Fleet*) fleetobj->getObjectBehaviour();
    Player::Ptr p = pm->getPlayer(f->getOwner());
    IGObject::Ptr sys = obm->getObject(fleetobj->getParent());
    StarSystem* sysData = (StarSystem*) sys->getObjectBehaviour();

    //Remove fleet from system
    sysData->setRegion(0);
    fleetobj->removeFromParent();

    //Find it's home planet
    std::set<uint32_t> objects = obm->getAllIds();
    std::set<uint32_t>::iterator itcurr;
    for(itcurr = objects.begin(); itcurr != objects.end(); ++itcurr) {
        IGObject::Ptr ob = obm->getObject(*itcurr);
        if(ob->getName().compare(string(p->getName() + "'s Home Planet")) == 0) {
            Planet* p = (Planet*) ob->getObjectBehaviour();
            f->setPosition(p->getPosition());
            fleetobj->addToParent(ob->getID());
        }
    }
}
예제 #2
0
//End the game
void gameOver() {
    Game* game = Game::getGame();
    PlayerManager::Ptr pm = game->getPlayerManager();

    map<uint32_t, uint32_t> finalScore;
    set<uint32_t>::iterator itcurr;
    set<uint32_t> players = pm->getAllIds();

    //Find each player's final score
    for(itcurr = players.begin(); itcurr != players.end(); itcurr++) {
        Player::Ptr p = pm->getPlayer(*itcurr);
        uint32_t artifacts = p->getScore(5);
        //change artifact points to improve the types with the lowest
        //points
        while(artifacts > 0) {
            int lowest = 1;
            for(int i = 2; i < 5; i++) {
                if(p->getScore(i) < p->getScore(lowest)) {
                    lowest = i;
                }
            }
            p->setScore(lowest, p->getScore(lowest) + 1);
            artifacts--;
        }

        //Find the final score
        int low = 1;
        for(int i = 2; i < 5; i++) {
            if(p->getScore(i) < p->getScore(low)) {
                low = i;
            }
        }

        finalScore[*itcurr] = p->getScore(low);
    }

    //Find the winner
    uint32_t winner = 0;
    for(map<uint32_t, uint32_t>::iterator i = finalScore.begin(); i != finalScore.end(); i++) {
        if(winner == 0 || i->second > finalScore[winner]) {
            winner = i->first;
        }
    }

    for(itcurr = players.begin(); itcurr != players.end(); itcurr++) {
        Player::Ptr p = pm->getPlayer(*itcurr);

        //Send message to each player
        Message::Ptr msg( new Message() );
        msg->setSubject("GAME OVER!");
        stringstream out;
        Player::Ptr win = pm->getPlayer(winner);
        out << win->getName() << " has won the game with a score of ";
        out << finalScore[winner] << "!  ";
        out << "Your final score after distributing your alien artifacts was: ";
        out << finalScore[*itcurr];
        msg->setBody(out.str());
        p->postToBoard(msg);

        p->setIsAlive(false);
    }

}
예제 #3
0
void TaeTurn::doTurn() {
    //check to make sure the game is still ging and this is not a combat turn
    if(isGameOver) {
        gameOver();
        return;
    } else if(combat) {
        doCombatTurn();
        return;
    }

    std::set<uint32_t>::iterator itcurr;

    Game* game = Game::getGame();
    OrderManager* ordermanager = game->getOrderManager();
    ObjectManager* objectmanager = game->getObjectManager();
    ObjectTypeManager* obtm = game->getObjectTypeManager();
    PlayerManager::Ptr playermanager = game->getPlayerManager();

    //build map for storing orders
    std::map<uint32_t, std::list<IGObject::Ptr > > playerOrders;

    containerids.clear();
    //separate orders by player
    std::set<uint32_t> objects = objectmanager->getAllIds();
    for(itcurr = objects.begin(); itcurr != objects.end(); ++itcurr) {
        IGObject::Ptr ob = objectmanager->getObject(*itcurr);
        if(ob->getType() == planettype || ob->getType() == fleettype) {
            OrderQueueObjectParam* oqop = dynamic_cast<OrderQueueObjectParam*>(ob->getParameterByType(obpT_Order_Queue));
            if(oqop != NULL) {
                OrderQueue::Ptr orderqueue = ordermanager->getOrderQueue(oqop->getQueueId());
                if(orderqueue != NULL) {
                    Order * currOrder = orderqueue->getFirstOrder();
                    if(currOrder != NULL) {
                        uint32_t owner = ((OwnedObject*)(ob->getObjectBehaviour()))->getOwner();
                        std::list<IGObject::Ptr >::iterator i = playerOrders[owner].end();
                        playerOrders[owner].insert(i, ob);
                    }
                }
            }
        }
    }

    //Do orders for players in the correct order
    //The order in which orders are processed is rotated each turn
    std::set<uint32_t> players = playermanager->getAllIds();
    itcurr = players.begin();
    for(int i = 0; i < playerTurn; i++) {
        itcurr++;
    }
    for(uint32_t it = 0; it < players.size(); it++) {
        if(itcurr == players.end()) {
            itcurr = players.begin();
        }
        if(playerOrders[*itcurr].size() > 0) {
            for(std::list<IGObject::Ptr >::iterator i = playerOrders[*itcurr].begin(); i != playerOrders[*itcurr].end(); i++) {
                OrderQueue::Ptr orderqueue = ordermanager->getOrderQueue(((OrderQueueObjectParam*)((*i)->getParameterByType(obpT_Order_Queue)))->getQueueId());
                Order* currOrder = orderqueue->getFirstOrder();
                if(currOrder!= NULL) {
                    if(currOrder->doOrder(*i)) {
                        orderqueue->removeFirstOrder();
                    } else {
                        orderqueue->updateFirstOrder();
                    }
                }
                if((*i)->getContainerType() >= 1) {
                    containerids.insert((*i)->getID());
                }
                objectmanager->doneWithObject((*i)->getID());
            }
        }
        itcurr++;
    }

    awardArtifacts();
    //Check for end game condition of less than 3 artifacts remaining
    objects = objectmanager->getAllIds();
    int numArtifacts = 0;
    for(itcurr = objects.begin(); itcurr != objects.end(); itcurr++) {
        IGObject::Ptr ob = objectmanager->getObject(*itcurr);
        if(ob->getType() == obtm->getObjectTypeByName("Planet")) {
            Planet* p = (Planet*) ob->getObjectBehaviour();
            if(p->getResource(3) > 0) {
                numArtifacts++;
            }
        }
    }
    if(numArtifacts < 3) {
        isGameOver = true;
        gameOver();
        return;
    }

    //Update which player's turn it is
    playerTurn = (playerTurn + 1) % playermanager->getNumPlayers();

    objectmanager->clearRemovedObjects();


    // to once a turn
    for(itcurr = objects.begin(); itcurr != objects.end(); ++itcurr) {
        IGObject::Ptr ob = objectmanager->getObject(*itcurr);
        if(ob->isAlive()) {
            ob->getObjectBehaviour()->doOnceATurn();
        }
        objectmanager->doneWithObject(ob->getID());
    }

    // find the objects that are visible to each player
    std::set<uint32_t> vis = objectmanager->getAllIds();
    for(std::set<uint32_t>::iterator itplayer = players.begin(); itplayer != players.end(); ++itplayer) {
        Player::Ptr player = playermanager->getPlayer(*itplayer);
        PlayerView::Ptr playerview = player->getPlayerView();

        for(std::set<uint32_t>::iterator itob = vis.begin(); itob != vis.end(); ++itob) {
            ObjectView::Ptr obv = playerview->getObjectView(*itob);
            if(obv == NULL) {
                if(objectmanager->getObject(*itob)->isAlive()) {
                    playerview->addVisibleObject( *itob, true );
                }
                objectmanager->doneWithObject(*itob);
            } else {
                IGObject::Ptr ro = objectmanager->getObject(*itob);
                uint64_t obmt = ro->getModTime();
                objectmanager->doneWithObject(*itob);
                if(obmt > obv->getModTime()) {
                    obv->setModTime(obmt);
                    playerview->updateObjectView(*itob);
                }
            }
        }

        // remove dead objects
        std::set<uint32_t> goneobjects;
        std::set<uint32_t> knownobjects = playerview->getVisibleObjects();
        set_difference(knownobjects.begin(), knownobjects.end(), vis.begin(), vis.end(), inserter(goneobjects, goneobjects.begin()));

        for(std::set<uint32_t>::iterator itob = goneobjects.begin(); itob != goneobjects.end(); ++itob) {
            ObjectView::Ptr obv = playerview->getObjectView(*itob);
            if(!obv->isGone()) {
                obv->setGone(true);
                playerview->updateObjectView(*itob);
            }
        }

        //Replace colonist fleets
        int fleets = 0;
        IGObject::Ptr homePlanet;
        for(std::set<uint32_t>::iterator itob = objects.begin(); itob != objects.end(); ++itob) {
            IGObject::Ptr ob = objectmanager->getObject(*itob);
            if(ob->getName().compare("Colonist Fleet") == 0) {
                uint32_t owner = ((OwnedObject*)(ob->getObjectBehaviour()))->getOwner();
                if(owner == *itplayer) {
                    fleets++;
                }
            }
            if(ob->getName().compare(string(player->getName() + "'s Home Planet")) == 0) {
                homePlanet = ob;
            }
        }

        for(int i = fleets; i < 6; i++) {
            IGObject::Ptr fleet = fleetBuilder->createFleet(FleetBuilder::PASSENGER_FLEET, FleetBuilder::RANDOM_SHIP, player, homePlanet, "Colonist Fleet");
            game->getObjectManager()->addObject(fleet);
            player->getPlayerView()->addVisibleObject(fleet->getID(), true);
        }

        //Send end of turn message to each player
        Message::Ptr msg( new Message() );
        msg->setSubject("Turn complete");
        stringstream out;
        out << "Your Current Score: \n";
        out << "Money: " << player->getScore(1) << "\n";
        out << "Technology: " << player->getScore(2) << "\n";
        out << "People: " << player->getScore(3) << "\n";
        out << "Raw Materials: " << player->getScore(4) << "\n";
        out << "Alien Artifacts: " << player->getScore(5);
        msg->setBody(out.str());
        player->postToBoard(msg);

        //Alert players to the turn order for next round
        msg.reset( new Message() );
        msg->setSubject("Turn Order");
        string body = "The order for the next turn is: ";
        itcurr = players.begin();
        for(int i = 0; i < playerTurn; i++) {
            itcurr++;
        }
        for(uint32_t it = 0; it < players.size(); it++) {
            if(itcurr == players.end()) {
                itcurr = players.begin();
            }
            body += playermanager->getPlayer(*itcurr)->getName();
            body += " ";
            itcurr++;
        }
        msg->setBody(body);
        player->postToBoard(msg);
    }

    //Initialize combat if the next turn is a combat turn
    if(combat) {
        initCombat();
    }

    playermanager->updateAll();

}
예제 #4
0
void TaeTurn::doCombatTurn() {
    std::set<uint32_t>::iterator itcurr;

    Game* game = Game::getGame();
    OrderManager* ordermanager = game->getOrderManager();
    ObjectManager* objectmanager = game->getObjectManager();
    ObjectTypeManager* obtm = game->getObjectTypeManager();
    PlayerManager::Ptr playermanager = game->getPlayerManager();

    containerids.clear();

    // Do orders
    std::set<uint32_t> objects = objectmanager->getAllIds();
    for(itcurr = objects.begin(); itcurr != objects.end(); ++itcurr) {
        IGObject::Ptr ob = objectmanager->getObject(*itcurr);
        if(ob->getType() == planettype || ob->getType() == fleettype) {
            OrderQueueObjectParam* oqop = dynamic_cast<OrderQueueObjectParam*>(ob->getParameterByType(obpT_Order_Queue));
            if(oqop != NULL) {
                OrderQueue::Ptr orderqueue = ordermanager->getOrderQueue(oqop->getQueueId());
                if(orderqueue != NULL) {
                    Order * currOrder = orderqueue->getFirstOrder();
                    if(currOrder != NULL) {
                        if(currOrder->doOrder(ob)) {
                            orderqueue->removeFirstOrder();
                        } else {
                            orderqueue->updateFirstOrder();
                        }
                    }
                    if(ob->getContainerType() >= 1) {
                        containerids.insert(ob->getID());
                    }
                    objectmanager->doneWithObject((ob)->getID());
                }
            }
        }
    }


    //Determine winner
    uint32_t winner = 0;
    uint32_t loser = 0;
    for(map<uint32_t, int>::iterator i = strength.begin(); i != strength.end(); ++i) {
        if(winner == 0) {
            winner = i->first;
        } else {
            if(strength[winner] < i->second) {
                winner = i->first;
            } else {
                loser = i->first;
            }
        }
    }

    //Remove losing combatants
    uint32_t losingRegion;
    uint32_t winningRegion;
    set<uint32_t> removedSystems;
    if(isInternal) {
        //Internal combat removes losing leader and awards one point to the winner
        for(map<uint32_t, uint32_t>::iterator i = combatants.begin(); i != combatants.end(); ++i) {
            IGObject::Ptr ob = objectmanager->getObject(i->first);
            Fleet* f = (Fleet*) ob->getObjectBehaviour();
            if(f->getOwner() != winner) {
                sendHome(i->first);
                Player::Ptr p = playermanager->getPlayer(winner);
                p->setScore(2, p->getScore(2) + 1);
                losingRegion = i->second;
                winningRegion = losingRegion;
            }
        }
        objects = objectmanager->getAllIds();
        for(itcurr = objects.begin(); itcurr!= objects.end(); ++itcurr) {
            IGObject::Ptr ob = objectmanager->getObject(*itcurr);
            if(ob->getType() == obtm->getObjectTypeByName("Star System")) {
                StarSystem* sysData = (StarSystem*) ob->getObjectBehaviour();
                if(sysData->getRegion() == losingRegion) {
                    sysData->setRegion(0);
                    removedSystems.insert(*itcurr);
                }
            }
        }
    } else {
        //External combat removes the losing leader and losing colonies.
        //1 point is awarded for the leader and each colony removed
        string shipType;
        //set shiptype, losing/winning regions, and send home the losing leader
        for(map<uint32_t, uint32_t>::iterator i = combatants.begin(); i != combatants.end(); ++i) {
            IGObject::Ptr ob = objectmanager->getObject(i->first);
            Fleet* f = (Fleet*) ob->getObjectBehaviour();
            if(f->getOwner() != winner) {
                losingRegion = i->second;
                shipType = ob->getName();
                sendHome(i->first);
            } else {
                winningRegion = i->second;
            }
        }

        //set the correct resource type
        int resourceType;
        if(shipType.compare("Merchant Leader") == 0) {
            resourceType = 4;
        } else if(shipType.compare("Scientist Leader") == 0) {
            resourceType = 5;
        } else if(shipType.compare("Settler Leader") == 0) {
            resourceType = 6;
        } else {
            resourceType = 7;
        }

        //add 1 to the winner for removing the leader
        Player::Ptr player = playermanager->getPlayer(winner);
        player->setScore(resourceType - 3, player->getScore(resourceType-3) + 1);

        //remove all losing colonies
        objects = objectmanager->getAllIds();
        for(itcurr = objects.begin(); itcurr!= objects.end(); ++itcurr) {
            IGObject::Ptr ob = objectmanager->getObject(*itcurr);
            if(ob->getType() == obtm->getObjectTypeByName("Planet")) {
                IGObject::Ptr sys = objectmanager->getObject(ob->getParent());
                StarSystem* sysData = (StarSystem*) sys->getObjectBehaviour();
                if(sysData->getRegion() == losingRegion) {
                    Planet* p = (Planet*) ob->getObjectBehaviour();
                    sysData->setRegion(0);
                    if(p->getResource(resourceType) > 0) {
                        p->removeResource(resourceType, 1);
                        player->setScore(resourceType - 3, player->getScore(resourceType-3) + 1);
                    } else {
                        removedSystems.insert(sys->getID());
                    }
                } else if(sysData->getRegion() == winningRegion) {
                    sysData->setRegion(0);
                    removedSystems.insert(sys->getID());
                }
            }
        }
    }

    //rebuild region
    for(itcurr = removedSystems.begin(); itcurr!= removedSystems.end(); ++itcurr) {
        rebuildRegion(*itcurr);
    }

    //Check for combat
    combat = false;
    while(!combatQueue.empty() && !combat) {
        pair<bool, map<uint32_t, uint32_t> > temp = combatQueue.front();
        combatQueue.pop();
        isInternal = temp.first;
        combatants = temp.second;
        combat = true;
        uint32_t region = 0;
        for(map<uint32_t, uint32_t>::iterator i = combatants.begin(); i != combatants.end() && combat; i++) {
            IGObject::Ptr ob = objectmanager->getObject(i->first);
            IGObject::Ptr sys = objectmanager->getObject(ob->getParent());
            StarSystem* sysData = (StarSystem*) sys->getObjectBehaviour();
            i->second = sysData->getRegion();
            if(region == 0) {
                region = sysData->getRegion();
            } else if(region != sysData->getRegion()) {
                combat = false;
            }
        }
    }

    //Cleanup and Set visibility
    objects = objectmanager->getAllIds();
    set<uint32_t> views;
    for(itcurr = objects.begin(); itcurr != objects.end(); ++itcurr) {
        IGObject::Ptr ob = objectmanager->getObject(*itcurr);
        if(ob->getType() == obtm->getObjectTypeByName("Fleet") && !combat) {
            Fleet* f = (Fleet*) ob->getObjectBehaviour();
            f->toggleCombat();
            f->setCombatant(false);
        }
        //Set visibility
        views.insert(ob->getID());
    }

    std::set<uint32_t> players = playermanager->getAllIds();
    std::set<uint32_t> vis = objectmanager->getAllIds();

    //clear the removed objecs
    objectmanager->clearRemovedObjects();
    objects = objectmanager->getAllIds();
    for(itcurr = objects.begin(); itcurr != objects.end(); ++itcurr) {
        IGObject::Ptr ob = objectmanager->getObject(*itcurr);
        if(ob->isAlive()) {
            ob->getObjectBehaviour()->doOnceATurn();
        }
        objectmanager->doneWithObject(ob->getID());
    }

    for(std::set<uint32_t>::iterator itplayer = players.begin(); itplayer != players.end(); ++itplayer) {
        Player::Ptr player = playermanager->getPlayer(*itplayer);
        PlayerView::Ptr playerview = player->getPlayerView();

        //Update visibility
        playerview->addVisibleObjects(views);

        for(std::set<uint32_t>::iterator itob = vis.begin(); itob != vis.end(); ++itob) {
            ObjectView::Ptr obv = playerview->getObjectView(*itob);
            if(obv == NULL) {
                if(objectmanager->getObject(*itob)->isAlive()) {
                    playerview->addVisibleObject(*itob, true);
                }
                objectmanager->doneWithObject(*itob);
            } else {
                IGObject::Ptr ro = objectmanager->getObject(*itob);
                uint64_t obmt = ro->getModTime();
                objectmanager->doneWithObject(*itob);
                if(obmt > obv->getModTime()) {
                    obv->setModTime(obmt);
                    playerview->updateObjectView(*itob);
                }
            }
        }

        // remove dead objects
        std::set<uint32_t> goneobjects;
        std::set<uint32_t> knownobjects = playerview->getVisibleObjects();
        set_difference(knownobjects.begin(), knownobjects.end(), vis.begin(), vis.end(), inserter(goneobjects, goneobjects.begin()));

        for(std::set<uint32_t>::iterator itob = goneobjects.begin(); itob != goneobjects.end(); ++itob) {
            ObjectView::Ptr obv = playerview->getObjectView(*itob);
            if(!obv->isGone()) {
                obv->setGone(true);
                playerview->updateObjectView(*itob);
            }
        }

        //Replace colonist fleets
        int fleets = 0;
        IGObject::Ptr homePlanet;
        for(std::set<uint32_t>::iterator itob = objects.begin(); itob != objects.end(); ++itob) {
            IGObject::Ptr ob = objectmanager->getObject(*itob);
            if(ob->getName().compare("Colonist Fleet") == 0) {
                uint32_t owner = ((OwnedObject*)(ob->getObjectBehaviour()))->getOwner();
                if(owner == *itplayer) {
                    fleets++;
                }
            }
            if(ob->getName().compare(string(player->getName() + "'s Home Planet")) == 0) {
                homePlanet = ob;
            }
        }

        for(int i = fleets; i < 6; i++) {
            IGObject::Ptr fleet = fleetBuilder->createFleet(FleetBuilder::PASSENGER_FLEET, FleetBuilder::RANDOM_SHIP, player, homePlanet, "Colonist Fleet");
            game->getObjectManager()->addObject(fleet);
            player->getPlayerView()->addVisibleObject(fleet->getID(), true);
        }

        //Send end of turn message to each player
        Message::Ptr msg( new Message() );
        msg->setSubject("Combat Complete!");
        stringstream out;
        Player::Ptr win = playermanager->getPlayer(winner);
        out << win->getName() << " has won the battle with a strength of ";
        out << strength[winner] << "!";
        msg->setBody(out.str());
        player->postToBoard(msg);

        msg.reset( new Message() );
        msg->setSubject("Turn complete");
        stringstream out2;
        out2 << "Your Current Score: \n";
        out2 << "Money: " << player->getScore(1) << "\n";
        out2 << "Technology: " << player->getScore(2) << "\n";
        out2 << "People: " << player->getScore(3) << "\n";
        out2 << "Raw Materials: " << player->getScore(4) << "\n";
        out2 << "Alien Artifacts: " << player->getScore(5);
        msg->setBody(out2.str());
        player->postToBoard(msg);

    }

    if(combat) {
        initCombat();
    }

    playermanager->updateAll();

}
예제 #5
0
void RftsTurn::doTurn() {

   Game* game = Game::getGame();
   OrderManager* ordermanager = game->getOrderManager();
   ObjectManager* objectmanager = game->getObjectManager();
   PlayerManager::Ptr pm = game->getPlayerManager();

   set<uint32_t> objectsIds = objectmanager->getAllIds();

   // currently just go through each obj and do each order
   // will be prioritized/sorted soon TODO

   for(set<uint32_t>::iterator i = objectsIds.begin();
         i != objectsIds.end(); ++i)
   {
      IGObject::Ptr currObj = objectmanager->getObject(*i);

      OrderQueueObjectParam* oqop = dynamic_cast<OrderQueueObjectParam*>(currObj->getParameterByType(obpT_Order_Queue));
      OrderQueue::Ptr oq;
      if(oqop != NULL && 
         (oq = ordermanager->getOrderQueue(oqop->getQueueId())) != NULL)
      {
         for(uint32_t j = 0; j < oq->getNumberOrders(); j++)
         {
            OwnedObject *orderedObj = dynamic_cast<OwnedObject*>(currObj->getObjectBehaviour());
            assert(orderedObj);

            Order* order = oq->getOrder(j, orderedObj->getOwner());
            if(order->doOrder(currObj))
            {
               oq->removeOrder(j, orderedObj->getOwner());
               j--; // list has been reordered
            }
            else
               oq->updateFirstOrder(); // CHECK
         }
         currObj->touchModTime();
      }
      objectmanager->doneWithObject(currObj->getID());
          
   }
   
   objectmanager->clearRemovedObjects();

   // re-explore new area
   setPlayerVisibleObjects();

   // to once a turn (right at the end)
   objectsIds = objectmanager->getAllIds();
   for(std::set<uint32_t>::iterator i = objectsIds.begin(); 
       i != objectsIds.end(); ++i)
   {
      IGObject::Ptr obj = objectmanager->getObject(*i);
      obj->getObjectBehaviour()->doOnceATurn();
      objectmanager->doneWithObject(obj->getID());
   }

   objectmanager->clearRemovedObjects();
   
   // update in case fleets were destroyed in combat
   setPlayerVisibleObjects();

   set<uint32_t> players = pm->getAllIds();
   for(set<uint32_t>::iterator i = players.begin(); i != players.end(); ++i)
      PlayerInfo::getPlayerInfo(*i).clearPdbUpgrade();

   Player::Ptr winner = getWinner();
   if(winner != NULL)
   {
      string body;
      Message::Ptr gameOver( new Message() );
      gameOver->setSubject("Game over!");
      
      if( game->getTurnNumber() ==
            static_cast<unsigned>(strtol(Settings::getSettings()->get("game_length").c_str(), NULL, 10)) )
         body = "Game length elapsed, winner is: ";
      else
         body = "Overwhelming victory by: ";
         
      body += winner->getName();
      gameOver->setBody(PlayerInfo::appAllVictoryPoints(body));

      for(set<uint32_t>::iterator i = players.begin(); i != players.end(); ++i)
         pm->getPlayer(*i)->postToBoard( Message::Ptr( new Message(*gameOver) ));
   }
   
   int turn = game->getTurnNumber() % 3;
   if(turn == 0){
       game->setTurnName("Production, Construction, Movement");
   }else if(turn == 1){
       game->setTurnName("Construction, Movement");
   }else{
       game->setTurnName("Movement");
   }
}
예제 #6
0
void RSPCombat::doCombat(std::map<uint32_t, IdSet> sides) {
    Game* game = Game::getGame();
    PlayerManager::Ptr playermanager = game->getPlayerManager();
    ObjectManager* objectmanager = game->getObjectManager();
    DesignStore::Ptr ds = game->getDesignStore();

    const char * const rsp[] = {"rock", "scissors", "paper"};

    IdSet listallobids;
    IdSet listallplayerids;

    std::map<uint32_t, std::vector<Combatant*> > fleetcache;

    battlelogger.reset(new BattleXML::BattleLogger());
    msgstrings.clear();

    for(std::map<uint32_t, IdSet>::iterator itmap = sides.begin(); itmap != sides.end(); ++itmap) {
        std::vector<Combatant*> pcombatant;
        Player::Ptr player = playermanager->getPlayer(itmap->first);
        battlelogger->startSide(player->getName());
        IdSet theset = itmap->second;
        for(IdSet::iterator itset = theset.begin(); itset != theset.end(); ++itset) {
            listallobids.insert(*itset);
            IGObject::Ptr obj = objectmanager->getObject (*itset);
            objectcache[*itset] = obj;
            if(obj->getType() == obT_Fleet) {
                Fleet* f2 = (Fleet*)(obj->getObjectBehaviour());
                IdMap shiplist = f2->getShips();
                uint32_t damage = f2->getDamage();
                for(IdMap::reverse_iterator itship = shiplist.rbegin(); itship != shiplist.rend(); ++itship) {
                    for(uint32_t i = 0; i < itship->second; i++) {
                        Combatant* f1 = new Combatant();
                        f1->setOwner(itmap->first);
                        f1->setObject(obj->getID());
                        f1->setShipType(itship->first);
                        uint32_t mydamage = damage / std::max(1U, (unsigned int)(shiplist.size() - i));
                        f1->setDamage(mydamage);
                        damage -= mydamage;
                        std::string type = ds->getDesign(itship->first)->getName();
                        f1->setBattleXmlType(type);
                        f1->setBattleXmlId(str(boost::format("%1%-%2%-%3%") % type % obj->getID() % i));
                        f1->setBattleXmlName(str(boost::format("%1%'s %2%, %3% %4%") % player->getName() % obj->getName() % type % i));
                        battlelogger->addCombatant(f1);
                        pcombatant.push_back(f1);
                    }
                }
            } else {
                int shipcount = 2;
                int homeplanetid = game->getResourceManager()->getResourceDescription("Home Planet")->getResourceType();
                if(((Planet*)(obj->getObjectBehaviour()))->getResource(homeplanetid) == 1) {
                    //three more for home planets
                    shipcount += 3;
                }
                for(int i = 0; i < shipcount; i++) {
                    Combatant* f1 = new Combatant();
                    f1->setOwner(itmap->first);
                    f1->setObject(obj->getID());
                    f1->setShipType(0);
                    f1->setBattleXmlType("planet");
                    f1->setBattleXmlId(str(boost::format("planet-%1%-%2%") % obj->getID() % i));
                    f1->setBattleXmlName(str(boost::format("%1%'s colony on %2%, Defense battery %3%") % player->getName() % obj->getName() % i));
                    battlelogger->addCombatant(f1);
                    pcombatant.push_back(f1);
                }
            }
        }
        listallplayerids.insert(itmap->first);
        battlelogger->endSide();
        //sort combatant list by ship type, descending
        sort(pcombatant.begin(), pcombatant.end(), CombatantSorter());
        fleetcache[itmap->first] = pcombatant;
    }

    for(std::set<uint32_t>::iterator itplayer = listallplayerids.begin(); itplayer != listallplayerids.end(); ++itplayer) {
        msgstrings[*itplayer] = "";
    }



    Random* random = Game::getGame()->getRandom();

    Logger::getLogger()->debug("Combat start");

    while(fleetcache.size() >= 2) {
        battlelogger->startRound();
        uint32_t pos1, pos2;
        if(fleetcache.size() == 2) {
            pos1 = 0;
            pos2 = 1;
        } else {
            pos1 = pos2 = random->getInRange(0U, ((uint32_t)(fleetcache.size() - 1)));
            while(pos2 == pos1) {
                pos2 = random->getInRange(0U, ((uint32_t)(fleetcache.size() - 1)));
            }
        }

        std::map<uint32_t, std::vector<Combatant*> >::iterator itpa = fleetcache.begin();
        advance(itpa, pos1);
        std::map<uint32_t, std::vector<Combatant*> >::iterator itpb = fleetcache.begin();
        advance(itpb, pos2);

        std::vector<Combatant*> f1 = itpa->second;
        std::vector<Combatant*> f2 = itpb->second;

        uint32_t ownerid1 = f1[0]->getOwner();
        uint32_t ownerid2 = f2[0]->getOwner();

        std::string p1name = playermanager->getPlayer(ownerid1)->getName();
        std::string p2name = playermanager->getPlayer(ownerid2)->getName();

        int32_t r1 = random->getInRange((int32_t)0, (int32_t)2);
        int32_t r2 = random->getInRange((int32_t)0, (int32_t)2);

        std::map<Combatant*, uint32_t> d1, d2;

        battlelogger->log(str(boost::format("%1%'s fleet chooses %2%.") % p1name % rsp[r2]));
        battlelogger->log(str(boost::format("%1%'s fleet chooses %2%.") % p2name % rsp[(r2 + r1) % 3]));

        if(r1 == 0) {
            //draw
            battlelogger->log("It's a draw");
            d1 = buildShotList(f1, true);
            d2 = buildShotList(f2, true);

            if(d1.size() != 0)
                doDamage(d1, f2);
            if(d2.size() != 0)
                doDamage(d2, f1);
        } else {

            if(r1 == 1) {
                //pa win
                battlelogger->log(str(boost::format("%1% wins.") % p1name));

                d1 = buildShotList(f1);
                if(d1.size() == 0) {
                    battlelogger->log(str(boost::format("%1%'s forces escape") % p1name));
                    msgstrings[ownerid1] += "Your Fleet escaped. ";
                    for(std::map<uint32_t, std::string>::iterator msgit = msgstrings.begin();
                            msgit != msgstrings.end(); ++msgit) {
                        if(msgit->first == ownerid1)
                            continue;
                        msgit->second += str(boost::format("%1%'s fleet of escaped. ") % p1name);
                    }
                    resolveCombatantsToObjects(f1);
                    for(std::vector<Combatant*>::iterator itcombatant = f1.begin(); itcombatant != f1.end();
                            ++itcombatant) {
                        delete *itcombatant;
                    }
                    fleetcache.erase(itpa);
                    battlelogger->endRound();
                    continue;
                }
                doDamage(d1, f2);
            } else {
                //pb win
                battlelogger->log(str(boost::format("%1% wins.") % p2name));
                d2 = buildShotList(f2);
                if(d2.size() == 0) {
                    battlelogger->log(str(boost::format("%1%'s forces escape") % p2name));
                    msgstrings[ownerid2] += "Your Fleet escaped. ";
                    for(std::map<uint32_t, std::string>::iterator msgit = msgstrings.begin();
                            msgit != msgstrings.end(); ++msgit) {
                        if(msgit->first == ownerid2)
                            continue;
                        msgit->second += str(boost::format("%1%'s fleet of escaped. ") % p2name);
                    }
                    resolveCombatantsToObjects(f2);
                    for(std::vector<Combatant*>::iterator itcombatant = f2.begin(); itcombatant != f2.end();
                            ++itcombatant) {
                        delete *itcombatant;
                    }
                    fleetcache.erase(itpb);
                    battlelogger->endRound();
                    continue;
                }
                doDamage(d2, f1);
            }

        }

        if(isAllDead(f1)) {
            msgstrings[ownerid1] += str(boost::format("Your fleet was destroyed by %1%'s fleet. ") % p2name);
            msgstrings[ownerid2] += str(boost::format("You destroyed %1%'s fleet. ") % p1name);
            std::string deathmsg = str(boost::format("%1%'s fleet destroyed %2%'s fleet. ") % p1name % p2name);
            for(std::map<uint32_t, std::string>::iterator msgit = msgstrings.begin();
                    msgit != msgstrings.end(); ++msgit) {
                if(msgit->first == ownerid1 || msgit->first == ownerid2)
                    continue;
                msgit->second += deathmsg;
            }
            resolveCombatantsToObjects(f1);
            for(std::vector<Combatant*>::iterator itcombatant = f1.begin(); itcombatant != f1.end();
                    ++itcombatant) {
                delete *itcombatant;
            }
            fleetcache.erase(itpa);
        }
        if(isAllDead(f2)) {
            msgstrings[ownerid2] += str(boost::format("Your fleet was destroyed by %1%'s fleet. ") % p1name);
            msgstrings[ownerid1] += str(boost::format("You destroyed %1%'s fleet. ") % p2name);
            std::string deathmsg = str(boost::format("%1%'s fleet destroyed %2%'s fleet. ") % p2name % p1name);
            for(std::map<uint32_t, std::string>::iterator msgit = msgstrings.begin();
                    msgit != msgstrings.end(); ++msgit) {
                if(msgit->first == ownerid1 || msgit->first == ownerid2)
                    continue;
                msgit->second += deathmsg;
            }
            resolveCombatantsToObjects(f2);
            for(std::vector<Combatant*>::iterator itcombatant = f2.begin(); itcombatant != f2.end();
                    ++itcombatant) {
                delete *itcombatant;
            }
            fleetcache.erase(itpb);
        }

        battlelogger->endRound();

    }

    std::string file = battlelogger->save();

    if(!fleetcache.empty()) {
        std::vector<Combatant*> flast = fleetcache.begin()->second;
        resolveCombatantsToObjects(flast);
        msgstrings[flast[0]->getOwner()] += "Your Fleet survived combat.";
        for(std::vector<Combatant*>::iterator itcombatant = flast.begin(); itcombatant != flast.end();
                ++itcombatant) {
            delete *itcombatant;
        }
        fleetcache.erase(fleetcache.begin());
        if(!fleetcache.empty()) {
            Logger::getLogger()->warning("fleetcache not empty at end of combat");
        }
    }
    for(std::map<uint32_t, std::string>::iterator msgit = msgstrings.begin();
            msgit != msgstrings.end(); ++msgit) {
        Message::Ptr msg( new Message() );
        msg->setSubject("Combat");
        for(std::set<uint32_t>::iterator itob = listallobids.begin(); itob != listallobids.end();
                ++itob) {
            msg->addReference(rst_Object, *itob);
        }
        for(std::set<uint32_t>::iterator itpl = listallplayerids.begin();
                itpl != listallplayerids.end(); ++itpl) {
            msg->addReference(rst_Player, *itpl);
        }

        msg->setBody(msgit->second);

        Game::getGame()->getPlayerManager()->getPlayer(msgit->first)->postToBoard(msg);
    }

    for(std::map<uint32_t, IGObject::Ptr>::iterator itob = objectcache.begin();
            itob != objectcache.end(); ++itob) {
        Game::getGame()->getObjectManager()->doneWithObject(itob->first);
    }
    objectcache.clear();

}