Пример #1
0
void AVACombat::resolveCombat(Fleet* fleet){
    Logger::getLogger()->debug("AVACombat::resolveCombat : Entering");

    Game* game = Game::getGame();
    DesignStore::Ptr ds = game->getDesignStore();
    typedef std::map<uint32_t, uint32_t> shipList;
    shipList ships = fleet->getShips();
    uint32_t damage = fleet->getDamage();
    uint32_t hpPropID = ds->getPropertyByName("HitPoints");

    for (shipList::reverse_iterator itcurr = ships.rbegin(); itcurr != ships.rend(); ++itcurr){
        uint32_t shipNumber = itcurr->first;
        uint32_t shipQuantity = itcurr->second;
        Logger::getLogger()->debug("Working on ship %s", ds->getDesign(shipNumber)->getName().c_str());

        uint32_t damageNeeded = static_cast<uint32_t>(ds->getDesign(shipNumber)->getPropertyValue(hpPropID));
        Logger::getLogger()->debug("Damage needed to destroy this ship: %d Damage available: %d", damageNeeded, damage);


        if (damage >= damageNeeded) {
            uint32_t factor = damage % damageNeeded;
            if (factor > shipQuantity) {
                factor = shipQuantity;
            }
            fleet->removeShips(shipNumber, factor);
            fleet->setDamage(damage - (damageNeeded*factor));
            Logger::getLogger()->debug("Damage is greater than a ship can take, Total(%d), Delivering(%d), factor (%d), new setDamage(%d)",
                damage, damageNeeded*factor, factor, fleet->getDamage());
        }
    }

    Logger::getLogger()->debug("AVACombat::resolveCombat : Exiting");


}
Пример #2
0
void Build::inputFrame(InputFrame::Ptr f, uint32_t playerid)
{
  Order::inputFrame(f, playerid);
  
  Player::Ptr player = Game::getGame()->getPlayerManager()->getPlayer(playerid);
  DesignStore::Ptr ds = Game::getGame()->getDesignStore();
  
  uint32_t bldTmPropID = ds->getPropertyByName( "BuildTime");
  
  IdMap fleettype = fleetlist->getList();
  uint32_t usedshipres = 0;
  
  for(IdMap::iterator itcurr = fleettype.begin();
     itcurr != fleettype.end(); ++itcurr) {
    uint32_t type = itcurr->first;
    uint32_t number = itcurr->second; // number to build
    
    if(player->getPlayerView()->isUsableDesign(type) && number >= 0){
      
      Design::Ptr design = ds->getDesign(type);
      usedshipres += (int)(ceil(number * design->getPropertyValue(bldTmPropID)));
        design->addUnderConstruction(number);
        ds->designCountsUpdated(design);

    }else{
      throw FrameException( fec_FrameError, "The requested design was not valid.");
    }
  }
  if(usedshipres == 0 && !fleettype.empty()){
    throw FrameException( fec_FrameError, "To build was empty...");
  }
  
  resources[1] = usedshipres;
  
  if(fleetname->getString().length() == 0){
    fleetname->setString("A Fleet");
  }
}
Пример #3
0
std::map<uint32_t, std::pair<std::string, uint32_t> > Build::generateListOptions(){
  std::map<uint32_t, std::pair<std::string, uint32_t> > options;
  
  std::set<uint32_t> designs = Game::getGame()->getPlayerManager()->getPlayer(((Planet*)(Game::getGame()->getObjectManager()->getObject(Game::getGame()->getOrderManager()->getOrderQueue(orderqueueid)->getObjectId())->getObjectBehaviour()))->getOwner())->getPlayerView()->getUsableDesigns();
    Game::getGame()->getObjectManager()->doneWithObject(Game::getGame()->getOrderManager()->getOrderQueue(orderqueueid)->getObjectId());
    DesignStore::Ptr ds = Game::getGame()->getDesignStore();

  std::set<Design::Ptr> usable;
  for(std::set<uint32_t>::iterator itcurr = designs.begin(); itcurr != designs.end(); ++itcurr){
    Design::Ptr design = ds->getDesign(*itcurr);
      if(design->getCategoryId() == 1){
          usable.insert(design);
      }
  }

  for(std::set<Design::Ptr>::iterator itcurr = usable.begin();
      itcurr != usable.end(); ++itcurr){
    Design::Ptr design = (*itcurr);
    options[design->getDesignId()] = std::pair<std::string, uint32_t>(design->getName(), 100);
  }
  
  return options;
}
Пример #4
0
ListParameter::Options BuildFleet::generateListOptions(){
  ListParameter::Options options;
  
  IdSet designs = Game::getGame()->getPlayerManager()->getPlayer(((Planet*)(Game::getGame()->getObjectManager()->getObject(Game::getGame()->getOrderManager()->getOrderQueue(orderqueueid)->getObjectId())->getObjectBehaviour()))->getOwner())->getPlayerView()->getUsableDesigns();
    Game::getGame()->getObjectManager()->doneWithObject(Game::getGame()->getOrderManager()->getOrderQueue(orderqueueid)->getObjectId());
    DesignStore::Ptr ds = Game::getGame()->getDesignStore();

  std::set<Design::Ptr> usable;
  for(IdSet::iterator itcurr = designs.begin(); itcurr != designs.end(); ++itcurr){
    Design::Ptr design = ds->getDesign(*itcurr);
      if(design->getCategoryId() == 1){
          usable.insert(design);
      }
  }

  for(std::set<Design::Ptr>::iterator itcurr = usable.begin();
      itcurr != usable.end(); ++itcurr){
    Design::Ptr design = (*itcurr);
    options[design->getDesignId()] = ListParameter::Option(design->getName(), 100);
  }

  Logger::getLogger()->debug("Exiting BuildFleet::generateListOptions");
  return options;
}
Пример #5
0
//Award artifacts to any players who have a merchant leader
//in a region with two artifacts
void TaeTurn::awardArtifacts() {
    Game* game = Game::getGame();
    ObjectTypeManager* obtm = game->getObjectTypeManager();
    ObjectManager* objectmanager = game->getObjectManager();

    std::set<uint32_t> artifacts;
    std::set<uint32_t> regions;
    std::set<uint32_t> objects = objectmanager->getAllIds();
    std::set<uint32_t>::iterator itcurr;

    //Find any regions with 2 or more alien artifacts
    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) {
                StarSystem* sys = (StarSystem*)(objectmanager->getObject(ob->getParent())->getObjectBehaviour());
                if(sys->getRegion() != 0) {
                    if(regions.count(sys->getRegion()) > 0) {
                        artifacts.insert(*itcurr);
                    } else {
                        regions.insert(sys->getRegion());
                    }
                }
            }
        }
    }

    if(!artifacts.empty()) {
        uint32_t type;
        DesignStore::Ptr ds = game->getDesignStore();
        PlayerManager::Ptr pm = game->getPlayerManager();
        std::set<uint32_t> designs = ds->getDesignIds();
        //get leader ID
        for(itcurr = designs.begin(); itcurr != designs.end(); ++itcurr) {
            if(ds->getDesign(*itcurr)->getName().compare("MerchantLeaderShip")) {
                type = *itcurr;
            }
        }
        //Search the objects for a merchant leader
        for(itcurr = objects.begin(); itcurr != objects.end(); ++itcurr) {
            IGObject::Ptr ob = objectmanager->getObject(*itcurr);
            if(ob->getType() == obtm->getObjectTypeByName("Fleet")) {
                Fleet* f = (Fleet*) (ob->getObjectBehaviour());
                if(f->getShips().count(type) > 0) {
                    IGObject::Ptr parent = objectmanager->getObject(ob->getParent());
                    if(parent->getType() == obtm->getObjectTypeByName("Star System")) {
                        StarSystem* parentData = (StarSystem*) (parent->getObjectBehaviour());
                        //See if this leader is in a region with
                        //2 or more alien artifacts
                        for(std::set<uint32_t>::iterator i = artifacts.begin(); i != artifacts.end(); ++i) {
                            IGObject::Ptr obj = objectmanager->getObject(*i);
                            Planet* p = (Planet*) obj->getObjectBehaviour();
                            StarSystem* sys = (StarSystem*)(objectmanager->getObject(obj->getParent())->getObjectBehaviour());
                            if(sys->getRegion() == parentData->getRegion()) {
                                //+1 to leader's owner's artifact score
                                Player::Ptr owner = pm->getPlayer(f->getOwner());
                                owner->setScore(5, owner->getScore(5) + 1);
                                p->removeResource(3, 1);
                                artifacts.erase(*i);
                            }
                        }
                    }
                }
            }
        }
    }
}
Пример #6
0
//Setup the next turn to be ready for combat
void TaeTurn::initCombat() {
    std::set<uint32_t>::iterator itcurr;

    Game* game = Game::getGame();
    ObjectManager* objectmanager = game->getObjectManager();
    PlayerManager::Ptr playermanager = game->getPlayerManager();
    ObjectTypeManager* obtm = game->getObjectTypeManager();
    DesignStore::Ptr ds = game->getDesignStore();

    //Pop the combat queue and set the combatants
    pair<bool, map<uint32_t, uint32_t> > temp;
    temp = combatQueue.front();
    combatQueue.pop();
    isInternal = temp.first;
    combatants = temp.second;
    strength.clear();
    for(map<uint32_t, uint32_t>::iterator i = combatants.begin(); i != combatants.end(); ++i) {
        IGObject::Ptr ob = Game::getGame()->getObjectManager()->getObject(i->first);
        Fleet* f = (Fleet*) ob->getObjectBehaviour();
        strength[f->getOwner()] = 0;
    }

    set<uint32_t> owners;
    set<uint32_t> regions;
    string shipType;
    for(map<uint32_t, uint32_t>::iterator i = combatants.begin(); i != combatants.end(); ++i) {
        IGObject::Ptr ob = objectmanager->getObject(i->first);
        Fleet* leader = (Fleet*) (ob)->getObjectBehaviour();
        //look for the shiptype which this combat is associated with
        if(shipType.empty()) {
            if(isInternal) {
                shipType = "ScientistShip";
            } else {
                //Set shiptype to the type corresponding to the leader
                uint32_t ship = leader->getShips().begin()->first;
                shipType = ds->getDesign(ship)->getName();
                size_t pos = shipType.find("Leader");
                if(pos != shipType.npos) {
                    shipType.erase(pos, 6);
                }
            }
        }
        owners.insert(leader->getOwner());

        //Set which regions are involved in combat
        if(regions.count(i->second) <= 0) {
            regions.insert(i->second);
        }

        //Set initial internal combat strength
        if(isInternal) {
            IGObject::Ptr starSys = objectmanager->getObject(ob->getParent());
            StarSystem* starSysData = (StarSystem*)(starSys->getObjectBehaviour());
            Vector3d pos = starSysData->getPosition();
            //Search for bordering science colonies
            //east-west neighbors
            for(int i = -1; i < 2; i+=2) {
                set<uint32_t> ids = objectmanager->getObjectsByPos(pos+Vector3d(80000*i,0,0), 1);
                for(set<uint32_t>::iterator j=ids.begin(); j != ids.end(); j++) {
                    IGObject::Ptr tempObj = objectmanager->getObject(*j);
                    if(tempObj->getType() == obtm->getObjectTypeByName("Planet")) {
                        Planet* p = (Planet*)(tempObj->getObjectBehaviour());
                        if(p->getResource(5) > 0) {
                            addReinforcement(leader->getOwner());
                        }
                    }
                }
            }
            //north-south neighbors
            for(int i = -1; i < 2; i+=2) {
                set<uint32_t> ids = objectmanager->getObjectsByPos(pos+Vector3d(0,80000*i,0), 1);
                for(set<uint32_t>::iterator j=ids.begin(); j != ids.end(); j++) {
                    IGObject::Ptr tempObj = objectmanager->getObject(*j);
                    if(tempObj->getType() == obtm->getObjectTypeByName("Planet")) {
                        Planet* p = (Planet*)(tempObj->getObjectBehaviour());
                        if(p->getResource(5) > 0) {
                            addReinforcement(leader->getOwner());
                        }
                    }
                }
            }
        }
    }

    //Set which resource will be awarded
    int resourceType;
    if(shipType.compare("MerchantShip") == 0) {
        resourceType = 4;
    } else if(shipType.compare("ScientistShip") == 0) {
        resourceType = 5;
    } else if(shipType.compare("SettlerShip") == 0) {
        resourceType = 6;
    } else {
        resourceType = 7;
    }

    //Set all fleets to combat mode. Flag the fleets whose owners are
    //directly involved in combat.
    std::set<uint32_t> views;
    std::set<uint32_t> objects = objectmanager->getAllIds();
    for(itcurr = objects.begin(); itcurr != objects.end(); ++itcurr) {
        IGObject::Ptr ob = objectmanager->getObject(*itcurr);
        if(ob->getType() == obtm->getObjectTypeByName("Fleet")) {
            Fleet* f = (Fleet*) ob->getObjectBehaviour();
            f->toggleCombat();
            //check to see if this fleet is a combatant
            if(owners.count(f->getOwner()) > 0) {
                uint32_t ship = f->getShips().begin()->first;
                string name = ds->getDesign(ship)->getName();
                if(name.compare(shipType) == 0) {
                    f->setCombatant(true);
                }
            }

            //Set visibility
            views.insert(ob->getID());
        }
        //Set initial external combat strength
        else if(ob->getType() == obtm->getObjectTypeByName("Planet") && !isInternal) {
            Planet* p = (Planet*) ob->getObjectBehaviour();
            StarSystem* sys = (StarSystem*) objectmanager->getObject(ob->getParent())->getObjectBehaviour();
            if(regions.count(sys->getRegion()) > 0) {
                if(p->getResource(resourceType) > 0) {
                    for(map<uint32_t, uint32_t>::iterator i = combatants.begin(); i != combatants.end(); ++i) {
                        if(i->second == sys->getRegion()) {
                            Fleet* leader = (Fleet*) (objectmanager->getObject(i->first))->getObjectBehaviour();
                            addReinforcement(leader->getOwner());
                        }
                    }
                }
            }
        }
    }

    //Send message to players letting them know about combat
    Message::Ptr msg( new Message() );
    msg->setSubject("COMBAT!");
    stringstream out;
    out << "The next turn is an ";
    if(isInternal) {
        out << "INTERNAL ";
    } else {
        out << "EXTERNAL ";
    }
    out << "combat turn! Combatants are:  ";
    out << playermanager->getPlayer(*owners.begin())->getName();
    out << " with an initial strength of ";
    out << strength[*owners.begin()] << " and ";
    out << playermanager->getPlayer(*owners.end())->getName();
    out << " with an initial strength of ";
    out << strength[*owners.end()];
    msg->setBody(out.str());

    std::set<uint32_t> players = playermanager->getAllIds();
    for(itcurr = players.begin(); itcurr != players.end(); ++itcurr) {
        Player::Ptr player = playermanager->getPlayer(*itcurr);
        player->postToBoard(Message::Ptr( new Message(*msg)));
        player->getPlayerView()->addVisibleObjects( views );
    }
}
Пример #7
0
// This routine handles one combat round.
// fleets[2] are the combatants.
// msgs[0] is sent to the owner of fleet1,
// msgs[1] is sent to the owner of fleet2.
//
// Assume that 'number of missiles/torpedoes a ship can carry'
// really means 'number of missiles/torpedoes a ship can fire in one round'.
// Ships have an infinite amount of ammunition.
//
// Further assume that everyone fires his/her full load,
// then all the damage is done.  No 'this ship was destroyed
// in this round, so it can't fire any missiles'.
//
// I keep (for now) the policy of always targetting the largest
// ship.
//
// Likelihood of (correct) impact is 100% for missiles, and
// (1-dodge likelihood) for torpedoes.
//
// How about armor as a recurring damage absorber?  Like
// 20HP of damage hitting a ship that has 5HP of armor
// results in only 15HP of damage to that ship.  The next
// round, another 15HP of damage hits the ship, resulting
// in another 10HP of damage.  The armor itself is not
// damaged until the ship is destroyed.
//
// Keep the same damage effects?  Ships are at full
// capacity until they are destroyed?
//
// All that being said, I decreased the damage the two sides
// do to each other by a random 0-39% because I wanted some
// randomness involved.
bool AVACombat::doCombatRound( Fleet*   fleet1,
                               Message::Ptr msg1,
                               Fleet*   fleet2,
                               Message::Ptr msg2)
{
    Logger::getLogger()->debug("doCombatRound Entering");
    Game* game = Game::getGame();
    DesignStore::Ptr ds = game->getDesignStore();
    ResourceManager::Ptr resman = game->getResourceManager();

    typedef std::map<uint32_t, std::pair<uint32_t, uint32_t> > weaponList;
//                   ID/TYPE             AMOUNT
    typedef std::map<uint32_t, uint32_t> shipList;

    std::map<uint32_t, std::string> tubes;
    tubes[ds->getPropertyByName("AlphaMissileTube")] = "AlphaMissileTube";
    tubes[ds->getPropertyByName("BetaMissileTube")] = "BetaMissileTube";
    tubes[ds->getPropertyByName("GammaMissileTube")] = "GammaMissileTube";
    tubes[ds->getPropertyByName("DeltaMissileTube")] = "DeltaMissileTube";
    tubes[ds->getPropertyByName("EpsilonMissileTube")] = "EpsilonMissileTube";
    tubes[ds->getPropertyByName("OmegaTorpedoeTube")] = "OmegaTorpedoeTube";
    tubes[ds->getPropertyByName("UpsilonTorpedoeTube")] = "UpsilonTorpedoeTube";
    tubes[ds->getPropertyByName("TauTorpedoeTube")] = "TauTorpedoeTube";
    tubes[ds->getPropertyByName("SigmaTorpedoeTube")] = "SigmaTorpedoeTube";
    tubes[ds->getPropertyByName("RhoTorpedoeTube")] = "RhoTorpedoeTube";
    tubes[ds->getPropertyByName("XiTorpedoeTube")] = "XiTorpedoeTube";


    std::map<uint32_t, uint32_t> tubeList;
    std::set<Design::Ptr> designList;

    weaponList fleetweaponry[2];
    shipList fleetships[2];
    Fleet* fleets[2]; 
    std::map<uint32_t, std::pair<std::string, uint32_t> > fleettubes[2];
    std::map<uint32_t, uint32_t> fleetusable[2];
    //     resourceid, designid

    fleetweaponry[0] = fleet1->getResources();
    fleetweaponry[1] = fleet2->getResources();

    fleetships[0] = fleet1->getShips();
    fleetships[1] = fleet2->getShips();
    
    fleets[0] = fleet1;
    fleets[1] = fleet2;

    uint32_t damage[2] = {0};

    for (int i=0; i < 2; i++) {
        for (shipList::iterator itcurr = fleetships[i].begin(); itcurr != fleetships[i].end(); ++itcurr) {
            for (std::map<uint32_t, std::string>::iterator tubeit = tubes.begin(); tubeit != tubes.end(); ++tubeit) {
                if (ds->getDesign(itcurr->first)->getPropertyValue(tubeit->first) > 0.0) {
                    Logger::getLogger()->debug("Found usable Tube %s, inserting into Fleet %d", tubeit->second.c_str(), i);
                    //size of weapon
                    uint32_t weapSizePropID = ds->getPropertyByName(tubeit->second);
                    uint32_t weapNumPropID = ds->getPropertyByName("num-" + tubeit->second);
                    uint32_t weapSizePropValue = static_cast<uint32_t>(ds->getDesign(itcurr->first)->getPropertyValue(weapSizePropID));
                    uint32_t weapNumPropValue = static_cast<uint32_t>(ds->getDesign(itcurr->first)->getPropertyValue(weapNumPropID));
                    if (fleettubes[i].find(weapSizePropValue) != fleettubes[i].end()) {
                        std::pair<std::string, uint32_t>fleetpair = fleettubes[i][weapSizePropValue];
                        fleetpair.second += weapNumPropValue;
                        fleettubes[i][weapSizePropValue] = fleetpair;
                        Logger::getLogger()->debug("Adding %d into Tube List", weapSizePropValue);
                    } else {
                        fleettubes[i][weapSizePropValue] = std::pair<std::string, uint32_t> (tubeit->second, weapNumPropValue);
                    }
                }
            }
    
            for (weaponList::iterator weapit = fleetweaponry[i].begin(); weapit != fleetweaponry[i].end(); ++weapit) {
                Design::Ptr weapDesign;
                std::string weapName = resman->getResourceDescription(weapit->first)->getNameSingular();
                std::set<uint32_t>dIDs = ds->getDesignIds();
                for (std::set<uint32_t>::iterator dit = dIDs.begin(); dit != dIDs.end(); ++dit) {
                    if (weapName == ds->getDesign(*dit)->getName()) {
                        weapDesign = ds->getDesign(*dit);
                        Logger::getLogger()->debug("Found design %s", weapDesign->getName().c_str());
    
                        for (std::map<uint32_t, std::pair<std::string, uint32_t> >::iterator tubeit = fleettubes[i].begin(); tubeit != fleettubes[i].end(); ++tubeit) {
                            //property ID, name of the TUBE
                            uint32_t propID = ds->getPropertyByName("MissileSize");
                            //Logger::getLogger()->debug("Checking fleettubes list for propID %s", ds->getProperty(propID)->getName().c_str());
                            uint32_t weapPropVal = static_cast<uint32_t>(weapDesign->getPropertyValue(propID));
                            if (fleettubes[i].find(weapPropVal) != fleettubes[i].end()) {
                                Logger::getLogger()->debug("Found it, trying to remove resource %d from fleet", weapit->first);
                                fleetusable[i][weapit->first] = weapDesign->getDesignId();
                                if (fleets[i]->removeResource(weapit->first, 1)) {
                                    uint32_t explPropID = ds->getPropertyByName("AmmoExplosiveness");
                                    //damage to be deliveredt
                                    damage[!i] += static_cast<uint32_t>(weapDesign->getPropertyValue(explPropID));
                                    Logger::getLogger()->debug("Adding Damage (%d) Total (%d)", static_cast<uint32_t>(weapDesign->getPropertyValue(explPropID)), damage[!i]);
                                } else {
                                    Logger::getLogger()->debug("No available Weapon for this tube!");
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    fleet1->setDamage(damage[0]);
    fleet2->setDamage(damage[1]);

    resolveCombat(fleet1);
    resolveCombat(fleet2);

    //Tube format: std::map<double, std::pair<std::string, uint32_t> >
    //                   tube size            name         number

    bool tte = false;

    std::string body[2];

    if (fleet1->totalShips() == 0) {
        body[0] += "Your fleet was destroyed. ";
        body[1] += "You destroyed their fleet. ";
        c1.reset();
        tte = true;
    };
    if (fleet2->totalShips() == 0) {
        body[0] += "Your fleet was destroyed.";
        body[1] += "You destroyed their fleet.";
        c2.reset();
        tte = true;
    }
    if ( tte) {
        msg1->setBody( body[0]);
        msg2->setBody( body[1]);
    }

    Logger::getLogger()->debug("doCombatRound Exiting");
    return false;
}
Пример #8
0
// Combat always takes place between two fleets.  If one combatant
// or the other is actually a planet, the planet simulated by two
// battleships.
void AVACombat::doCombat()
{
    Logger::getLogger()->debug("AVACombat::doCombat : Entering");

    Fleet *fleets[2];

    Game* game = Game::getGame();
    DesignStore::Ptr ds = game->getDesignStore();
    uint32_t obT_Fleet = game->getObjectTypeManager()->getObjectTypeByName("Fleet");
    uint32_t obT_Planet = game->getObjectTypeManager()->getObjectTypeByName("Planet");

    // If one combatant or the other is actually a planet,
    // simulate this with two battleships.
    if ( c1->getType() == obT_Fleet) {
        fleets[0] = dynamic_cast<Fleet*>( c1->getObjectBehaviour());
    }
    else if ( c1->getType() == obT_Planet) {
        fleets[0] = new DummyFleet();

        std::set<uint32_t> dIDs = ds->getDesignIds();
        uint32_t scoutID=0;
        for (std::set<uint32_t>::iterator it = dIDs.begin(); it != dIDs.end(); ++it) {
            if (ds->getDesign(*it)->getName() == "Scout") {
                scoutID = *it;
            }
        }
        fleets[0] = new DummyFleet();
        fleets[0]->addShips(scoutID , 2);
        fleets[0]->setOwner( dynamic_cast<Planet*>(c1->getObjectBehaviour())->getOwner());
    }
    if ( c2->getType() == obT_Fleet) {
        fleets[1] = dynamic_cast<Fleet*>( c2->getObjectBehaviour());
    }
    else if ( c2->getType() == obT_Planet) {
        std::set<uint32_t> dIDs = ds->getDesignIds();
        uint32_t scoutID=0;
        for (std::set<uint32_t>::iterator it = dIDs.begin(); it != dIDs.end(); ++it) {
            if (ds->getDesign(*it)->getName() == "Scout") {
                scoutID = *it;
            }
        }
        fleets[1] = new DummyFleet();
        fleets[1]->addShips(scoutID, 2);
        fleets[1]->setOwner( dynamic_cast<Planet*>(c2->getObjectBehaviour())->getOwner());
    }
    if ( fleets[0] == NULL || fleets[1] == NULL) {
        return;
    }

    Message::Ptr msg1( new Message() );
    Message::Ptr msg2( new Message() );
    msg1->setSubject( "Combat");
    msg2->setSubject( "Combat");
    msg1->addReference( rst_Object, c1->getID());
    msg1->addReference( rst_Object, c2->getID());
    msg1->addReference( rst_Player, fleets[1]->getOwner());
    msg2->addReference( rst_Object, c2->getID());
    msg2->addReference( rst_Object, c1->getID());
    msg2->addReference( rst_Player, fleets[0]->getOwner());

    while ( doCombatRound( fleets[0], msg1, fleets[1], msg2)) {
        ;
    }

    Game::getGame()->getPlayerManager()->getPlayer( fleets[0]->getOwner())->postToBoard( msg1);
    Game::getGame()->getPlayerManager()->getPlayer( fleets[1]->getOwner())->postToBoard( msg2);

    return;
}
Пример #9
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();

}
Пример #10
0
bool Colonise::doOrder(IGObject::Ptr ob){
  //if not close, move
  IGObject::Ptr target = Game::getGame()->getObjectManager()->getObject(ob->getParent());
  if(target == NULL || target->getType() != Game::getGame()->getObjectTypeManager()->getObjectTypeByName("Planet")){
    
    Logger::getLogger()->debug("Object(%d)->Colonise->doOrder(): Target was not valid.", ob->getID());
    Game::getGame()->getObjectManager()->doneWithObject(ob->getParent());
    Message::Ptr msg( new Message() );
    msg->setSubject("Colonise order canceled");
    msg->setBody("Not at a planet, colonisation canceled");
    msg->addReference(rst_Action_Order, rsorav_Canceled);
    msg->addReference(rst_Object, ob->getID());
    Game::getGame()->getPlayerManager()->getPlayer(((Fleet*)(ob->getObjectBehaviour()))->getOwner())->postToBoard(msg);

    return true;
  }
  
  Fleet* fleet = (Fleet*)(ob->getObjectBehaviour());
  Planet* planet = (Planet*)(target->getObjectBehaviour());
  
    Message::Ptr msg( new Message() );
  msg->addReference(rst_Object, ob->getID());
  msg->addReference(rst_Object, target->getID());

  if(planet->getOwner() != fleet->getOwner()){

    if(planet->getOwner() != 0){
      Logger::getLogger()->debug("Object(%d)->Colonise->doOrder(): Planet already owned.", 
        ob->getID());
    
      msg->setSubject("Colonisation failed");
      msg->setBody("The planet you tried to colonise, is already owned by someone else.");
      msg->addReference(rst_Action_Order, rsorav_Canceled);
    }else{

      DesignStore::Ptr ds = Game::getGame()->getDesignStore();
      int shiptype = 0;
      int shiphp = 2000000;
      IdMap ships = fleet->getShips();
      uint32_t colonisePropID = ds->getPropertyByName( "Colonise");
      uint32_t armorPropID = ds->getPropertyByName( "Armour");
      for(IdMap::iterator itcurr = ships.begin();
	  itcurr != ships.end(); ++itcurr){
        Design::Ptr design = ds->getDesign(itcurr->first);
	if(design->getPropertyValue(colonisePropID) != 0.0 && shiphp > (int)design->getPropertyValue(armorPropID)){
	  shiptype = itcurr->first;
	  shiphp = (int)design->getPropertyValue(armorPropID);
	}
      }

      Logger::getLogger()->debug("Object(%d)->Colonise->doOrder(): shiptype %d", 
          ob->getID(), shiptype);
      if(shiptype != 0){
        uint32_t oldowner = planet->getOwner();
        planet->setOwner(fleet->getOwner());
        Game::getGame()->getPlayerManager()->getPlayer(fleet->getOwner())->getPlayerView()->addOwnedObject(target->getID());
        uint32_t queueid = static_cast<OrderQueueObjectParam*>(target->getParameterByType(obpT_Order_Queue))->getQueueId();
        OrderQueue::Ptr queue = Game::getGame()->getOrderManager()->getOrderQueue(queueid);
        queue->removeOwner(oldowner);
        queue->addOwner(fleet->getOwner());

        fleet->removeShips(shiptype, 1);

        msg->setSubject("Colonised planet");
        msg->setBody("You have colonised a planet!");
        msg->addReference(rst_Action_Order, rsorav_Completion);

      }else{
        msg->setSubject("Colonisation failed");
        msg->setBody("Your fleet did not have a frigate to colonise the planet");
        msg->addReference(rst_Action_Order, rsorav_Invalid);
      }

      if(fleet->totalShips() == 0){
        Game::getGame()->getObjectManager()->scheduleRemoveObject(ob->getID());
        Game::getGame()->getPlayerManager()->getPlayer(fleet->getOwner())->getPlayerView()->removeOwnedObject(ob->getID());
      }
      
    }
  }else{
    Logger::getLogger()->debug("Object(%d)->Colonise->doOrder(): Was already owned by the player!", 
      ob->getID());

    msg->setSubject("Colonisation failed");
    msg->setBody("You already own the planet you tried to colonise");
    msg->addReference(rst_Action_Order, rsorav_Canceled);
  }
  
  Game::getGame()->getPlayerManager()->getPlayer(fleet->getOwner())->postToBoard(msg);
  Game::getGame()->getObjectManager()->doneWithObject(target->getID());
  return true;
  
}