예제 #1
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;
}
예제 #2
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);
                            }
                        }
                    }
                }
            }
        }
    }
}
예제 #3
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;
}