示例#1
0
void Planet::PopGrowthProductionResearchPhase() {
    UniverseObject::PopGrowthProductionResearchPhase();

    // do not do production if planet was just conquered
    if (m_just_conquered)
        m_just_conquered = false;
    else
        ResourceCenterPopGrowthProductionResearchPhase();

    PopCenterPopGrowthProductionResearchPhase();

    // check for planets with zero population.  If they have a species set, then
    // they probably just starved
    if (!SpeciesName().empty() && GetMeter(METER_POPULATION)->Current() == 0.0) {
        // generate starvation sitrep for empire that owns this depopulated planet
        if (Empire* empire = Empires().Lookup(this->Owner()))
            empire->AddSitRepEntry(CreatePlanetStarvedToDeathSitRep(this->ID()));

        // remove species
        SetSpecies("");

    }

    GetMeter(METER_SHIELD)->SetCurrent(Planet::NextTurnCurrentMeterValue(METER_SHIELD));
    GetMeter(METER_DEFENSE)->SetCurrent(Planet::NextTurnCurrentMeterValue(METER_DEFENSE));
    GetMeter(METER_TROOPS)->SetCurrent(Planet::NextTurnCurrentMeterValue(METER_TROOPS));
    GetMeter(METER_REBEL_TROOPS)->SetCurrent(Planet::NextTurnCurrentMeterValue(METER_REBEL_TROOPS));

    StateChangedSignal();
}
示例#2
0
void Planet::PopGrowthProductionResearchPhase() {
    UniverseObject::PopGrowthProductionResearchPhase();

    // do not do production if planet was just conquered
    if (m_just_conquered)
        m_just_conquered = false;
    else
        ResourceCenterPopGrowthProductionResearchPhase();

    PopCenterPopGrowthProductionResearchPhase();

    // check for planets with zero population.  If they have any owners
    // then the planet has likely just starved.  Regardless, resetting the
    // planet keeps things consistent.
    if (GetMeter(METER_POPULATION)->Current() == 0.0 && !Unowned()) {
        // generate starvation sitrep for empire that owns this depopulated planet
        if (Empire* empire = Empires().Lookup(this->Owner()))
            empire->AddSitRepEntry(CreatePlanetStarvedToDeathSitRep(this->ID()));

        // reset planet to empty and unowned
        Reset();

    } else {
        GetMeter(METER_SHIELD)->SetCurrent(Planet::NextTurnCurrentMeterValue(METER_SHIELD));
        GetMeter(METER_DEFENSE)->SetCurrent(Planet::NextTurnCurrentMeterValue(METER_SHIELD));
        GetMeter(METER_TROOPS)->SetCurrent(Planet::NextTurnCurrentMeterValue(METER_SHIELD));
    }

    StateChangedSignal();
}
示例#3
0
void Steps::TidyUpData()
{
	// Don't set the StepsType to dance single if it's invalid.  That just
	// causes unrecognized charts to end up where they don't belong.
	// Leave it as StepsType_Invalid so the Song can handle it specially.  This
	// is a forwards compatibility feature, so that if a future version adds a
	// new style, editing a simfile with unrecognized Steps won't silently
	// delete them. -Kyz
	if( m_StepsType == StepsType_Invalid )
	{
		LOG->Warn("Detected steps with unknown style '%s' in '%s'", m_StepsTypeStr.c_str(), m_pSong->m_sSongFileName.c_str());
	}
	else if(m_StepsTypeStr == "")
	{
		m_StepsTypeStr= GAMEMAN->GetStepsTypeInfo(m_StepsType).szName;
	}

	if( GetDifficulty() == Difficulty_Invalid )
		SetDifficulty( StringToDifficulty(GetDescription()) );

	if( GetDifficulty() == Difficulty_Invalid )
	{
		if(	 GetMeter() == 1 )	SetDifficulty( Difficulty_Beginner );
		else if( GetMeter() <= 3 )	SetDifficulty( Difficulty_Easy );
		else if( GetMeter() <= 6 )	SetDifficulty( Difficulty_Medium );
		else				SetDifficulty( Difficulty_Hard );
	}

	if( GetMeter() < 1) // meter is invalid
		SetMeter( int(PredictMeter()) );
}
示例#4
0
void Planet::Depopulate() {
    PopCenter::Depopulate();

    GetMeter(METER_INDUSTRY)->Reset();
    GetMeter(METER_RESEARCH)->Reset();
    GetMeter(METER_TRADE)->Reset();
    GetMeter(METER_CONSTRUCTION)->Reset();

    ClearFocus();
}
示例#5
0
double Planet::NextTurnCurrentMeterValue(MeterType type) const
{
    MeterType max_meter_type = INVALID_METER_TYPE;
    switch (type) {
    case METER_TARGET_POPULATION:
    case METER_TARGET_HEALTH:
    case METER_POPULATION:
    case METER_HEALTH:
    case METER_FOOD_CONSUMPTION:
        return PopCenterNextTurnMeterValue(type);
        break;
    case METER_TARGET_FARMING:
    case METER_TARGET_INDUSTRY:
    case METER_TARGET_RESEARCH:
    case METER_TARGET_TRADE:
    case METER_TARGET_MINING:
    case METER_TARGET_CONSTRUCTION:
    case METER_FARMING:
    case METER_INDUSTRY:
    case METER_RESEARCH:
    case METER_TRADE:
    case METER_MINING:
    case METER_CONSTRUCTION:
        return ResourceCenterNextTurnMeterValue(type);
        break;
    case METER_SHIELD:  max_meter_type = METER_MAX_SHIELD;  break;
    case METER_TROOPS:  max_meter_type = METER_MAX_TROOPS;  break;
    case METER_DEFENSE: max_meter_type = METER_MAX_DEFENSE; break;
        break;
    default:
        return UniverseObject::NextTurnCurrentMeterValue(type);
    }

    const Meter* meter = GetMeter(type);
    if (!meter) {
        throw std::invalid_argument("Planet::NextTurnCurrentMeterValue passed meter type that the Planet does not have, but should.");
    }
    double current_meter_value = meter->Current();

    const Meter* max_meter = GetMeter(max_meter_type);
    if (!max_meter) {
        throw std::runtime_error("Planet::NextTurnCurrentMeterValue dealing with invalid meter type");
    }
    double max_meter_value = max_meter->Current();

    // being attacked prevents meter growth
    if (LastTurnAttackedByShip() >= CurrentTurn()) {
        return std::min(current_meter_value, max_meter_value);
    }

    // currently meter growth is one per turn.
    return std::min(current_meter_value + 1.0, max_meter_value);
}
示例#6
0
void Planet::Reset() {
    PopCenter::Reset();
    ResourceCenter::Reset();

    GetMeter(METER_SUPPLY)->Reset();
    GetMeter(METER_MAX_SUPPLY)->Reset();
    GetMeter(METER_SHIELD)->Reset();
    GetMeter(METER_MAX_SHIELD)->Reset();
    GetMeter(METER_DEFENSE)->Reset();
    GetMeter(METER_MAX_DEFENSE)->Reset();
    GetMeter(METER_DETECTION)->Reset();
    GetMeter(METER_REBEL_TROOPS)->Reset();

    if (m_is_about_to_be_colonized && !OwnedBy(ALL_EMPIRES)) {
        for (std::set<int>::const_iterator it = m_buildings.begin(); it != m_buildings.end(); ++it)
            if (TemporaryPtr<Building> building = GetBuilding(*it))
                building->Reset();
    }

    m_just_conquered = false;
    m_is_about_to_be_colonized = false;
    m_is_about_to_be_invaded = false;
    m_is_about_to_be_bombarded = false;
    SetOwner(ALL_EMPIRES);
}
示例#7
0
void Planet::Reset() {
    PopCenter::Reset();
    ResourceCenter::Reset();

    GetMeter(METER_SUPPLY)->Reset();
    GetMeter(METER_MAX_SUPPLY)->Reset();
    GetMeter(METER_SHIELD)->Reset();
    GetMeter(METER_MAX_SHIELD)->Reset();
    GetMeter(METER_DEFENSE)->Reset();
    GetMeter(METER_MAX_DEFENSE)->Reset();
    GetMeter(METER_DETECTION)->Reset();
    GetMeter(METER_REBEL_TROOPS)->Reset();

    if (m_is_about_to_be_colonized && !OwnedBy(ALL_EMPIRES)) {
        for (int building_id : m_buildings)
            if (auto building = GetBuilding(building_id))
                building->Reset();
    }

    m_just_conquered = false;
    m_is_about_to_be_colonized = false;
    m_is_about_to_be_invaded = false;
    m_is_about_to_be_bombarded = false;
    SetOwner(ALL_EMPIRES);
}
示例#8
0
float PopCenter::NextTurnPopGrowth() const {
    float target_pop = GetMeter(METER_TARGET_POPULATION)->Current();
    float cur_pop = GetMeter(METER_POPULATION)->Current();
    float pop_change = 0.0f;

    if (target_pop > cur_pop) {
        pop_change = cur_pop * (target_pop + 1 - cur_pop) / 100; // Using target population slightly above actual population avoids excessively slow asymptotic growth towards target.
        pop_change = std::min(pop_change, target_pop - cur_pop);
    } else {
        pop_change = -(cur_pop - target_pop) / 10;
        pop_change = std::max(pop_change, target_pop - cur_pop);
    }

    return pop_change;
}
示例#9
0
float PopCenter::CurrentMeterValue(MeterType type) const {
    const Meter* meter = GetMeter(type);
    if (!meter) {
        throw std::invalid_argument("PopCenter::CurrentMeterValue was passed a MeterType that this PopCenter does not have");
    }
    return meter->Current();
}
示例#10
0
float Planet::NextTurnCurrentMeterValue(MeterType type) const {
    MeterType max_meter_type = INVALID_METER_TYPE;
    switch (type) {
    case METER_TARGET_POPULATION:
    case METER_POPULATION:
    case METER_TARGET_HAPPINESS:
    case METER_HAPPINESS:
        return PopCenterNextTurnMeterValue(type);
        break;
    case METER_TARGET_INDUSTRY:
    case METER_TARGET_RESEARCH:
    case METER_TARGET_TRADE:
    case METER_TARGET_CONSTRUCTION:
    case METER_INDUSTRY:
    case METER_RESEARCH:
    case METER_TRADE:
    case METER_CONSTRUCTION:
        return ResourceCenterNextTurnMeterValue(type);
        break;
    case METER_SHIELD:      max_meter_type = METER_MAX_SHIELD;          break;
    case METER_TROOPS:      max_meter_type = METER_MAX_TROOPS;          break;
    case METER_DEFENSE:     max_meter_type = METER_MAX_DEFENSE;         break;
    case METER_SUPPLY:      max_meter_type = METER_MAX_SUPPLY;          break;
        break;
    default:
        return UniverseObject::NextTurnCurrentMeterValue(type);
    }

    const Meter* meter = GetMeter(type);
    if (!meter) {
        throw std::invalid_argument("Planet::NextTurnCurrentMeterValue passed meter type that the Planet does not have, but should: " + boost::lexical_cast<std::string>(type));
    }
    float current_meter_value = meter->Current();

    const Meter* max_meter = GetMeter(max_meter_type);
    if (!max_meter) {
        throw std::runtime_error("Planet::NextTurnCurrentMeterValue dealing with invalid meter type: " + boost::lexical_cast<std::string>(type));
    }
    float max_meter_value = max_meter->Current();

    // being attacked prevents meter growth
    if (LastTurnAttackedByShip() >= CurrentTurn())
        return std::min(current_meter_value, max_meter_value);

    // currently meter growth is one per turn.
    return std::min(current_meter_value + 1.0f, max_meter_value);
}
示例#11
0
void Planet::Reset() {
    // remove owner
    SetOwner(ALL_EMPIRES);

    // reset popcenter meters
    PopCenter::Reset();

    // reset resourcecenter meters
    ResourceCenter::Reset();

    // reset planet meters
    GetMeter(METER_SUPPLY)->Reset();
    GetMeter(METER_SHIELD)->Reset();
    GetMeter(METER_MAX_SHIELD)->Reset();
    GetMeter(METER_DEFENSE)->Reset();
    GetMeter(METER_MAX_DEFENSE)->Reset();
    GetMeter(METER_DETECTION)->Reset();
    GetMeter(METER_REBEL_TROOPS)->Reset();

    // reset buildings
    for (std::set<int>::const_iterator it = m_buildings.begin(); it != m_buildings.end(); ++it)
        if (Building* building = GetBuilding(*it))
            building->Reset();

    // reset other state
    m_available_trade = 0.0;
    m_just_conquered = false;
    m_is_about_to_be_colonized = false;
    m_is_about_to_be_invaded = false;
}
示例#12
0
double PopCenter::NextTurnPopGrowth() const {
    double target_pop = std::max(GetMeter(METER_TARGET_POPULATION)->Current(), 0.01);   // clamping target pop to at least 1 prevents divide by zero cases
    double cur_pop = GetMeter(METER_POPULATION)->Current();
    Logger().debugStream() << "pop: " << cur_pop << " / " << target_pop;
    double population_fraction = (target_pop - cur_pop) / target_pop;
    Logger().debugStream() << "pop frac: " << population_fraction;
    double change_potential = cur_pop * population_fraction * 0.05;
    Logger().debugStream() << "change potential: " << change_potential;
    double max_growth = target_pop - cur_pop;
    double max_loss = -cur_pop;
    double change = 0.0;
    if (change_potential > 0)
        change = std::min(max_growth, change_potential);
    else if (change_potential < 0)
        change = std::max(max_loss, change_potential);
    Logger().debugStream() << "pop change: " << change;
    return change;
}
示例#13
0
bool Field::InField(double x, double y) const {
    const Meter* size_meter = GetMeter(METER_SIZE);
    double radius = 1.0;
    if (size_meter)
        radius = size_meter->Current();

    double dist2 = (x - this->X())*(x - this->X()) + (y - this->Y())*(y - this->Y());
    return dist2 < radius*radius;
}
示例#14
0
void ResourceCenter::ResourceCenterClampMeters() {
    GetMeter(METER_TARGET_INDUSTRY)->ClampCurrentToRange();
    GetMeter(METER_TARGET_RESEARCH)->ClampCurrentToRange();
    GetMeter(METER_TARGET_TRADE)->ClampCurrentToRange();
    GetMeter(METER_TARGET_CONSTRUCTION)->ClampCurrentToRange();

    GetMeter(METER_INDUSTRY)->ClampCurrentToRange();
    GetMeter(METER_RESEARCH)->ClampCurrentToRange();
    GetMeter(METER_TRADE)->ClampCurrentToRange();
    GetMeter(METER_CONSTRUCTION)->ClampCurrentToRange();
}
示例#15
0
void Steps::TidyUpData()
{
    if( m_StepsType == StepsType_Invalid )
        m_StepsType = StepsType_dance_single;

    if( GetDifficulty() == Difficulty_Invalid )
        SetDifficulty( StringToDifficulty(GetDescription()) );

    if( GetDifficulty() == Difficulty_Invalid )
    {
        if(	 GetMeter() == 1 )	SetDifficulty( Difficulty_Beginner );
        else if( GetMeter() <= 3 )	SetDifficulty( Difficulty_Easy );
        else if( GetMeter() <= 6 )	SetDifficulty( Difficulty_Medium );
        else				SetDifficulty( Difficulty_Hard );
    }

    if( GetMeter() < 1) // meter is invalid
        SetMeter( int(PredictMeter()) );
}
示例#16
0
void System::ResetTargetMaxUnpairedMeters() {
    UniverseObject::ResetTargetMaxUnpairedMeters();

    // give systems base stealth slightly above zero, so that they can't be
    // seen from a distance without high detection ability
    if (Meter* stealth = GetMeter(METER_STEALTH)) {
        stealth->ResetCurrent();
        stealth->AddToCurrent(0.01f);
    }
}
示例#17
0
void ResourceCenter::Reset() {
    m_focus.clear();

    GetMeter(METER_INDUSTRY)->Reset();
    GetMeter(METER_RESEARCH)->Reset();
    GetMeter(METER_TRADE)->Reset();
    GetMeter(METER_CONSTRUCTION)->Reset();

    GetMeter(METER_TARGET_INDUSTRY)->Reset();
    GetMeter(METER_TARGET_RESEARCH)->Reset();
    GetMeter(METER_TARGET_TRADE)->Reset();
    GetMeter(METER_TARGET_CONSTRUCTION)->Reset();
}
示例#18
0
void Fleet::ResetTargetMaxUnpairedMeters() {
    UniverseObject::ResetTargetMaxUnpairedMeters();

    // give fleets base stealth very high, so that they can (almost?) never be
    // seen by empires that don't own them, unless their ships are seen and
    // that visibility is propegated to the fleet that contains the ships
    if (Meter* stealth = GetMeter(METER_STEALTH)) {
        stealth->ResetCurrent();
        stealth->AddToCurrent(2000.0);
    }
}
示例#19
0
void UniverseObject::ResetPairedActiveMeters() {
    // iterate over paired active meters (those that have an associated max or
    // target meter.  if another paired meter type is added to Enums.h, it
    // should be added here as well.
    for (MeterType meter_type = MeterType(METER_POPULATION);
         meter_type <= MeterType(METER_TROOPS);
         meter_type = MeterType(meter_type + 1))
    {
        if (Meter* meter = GetMeter(meter_type))
            meter->SetCurrent(meter->Initial());
    }
}
示例#20
0
void ResourceCenter::Reset() {
    m_focus.clear();
    m_last_turn_focus_changed = INVALID_GAME_TURN;

    GetMeter(METER_INDUSTRY)->Reset();
    GetMeter(METER_RESEARCH)->Reset();
    GetMeter(METER_TRADE)->Reset();
    GetMeter(METER_CONSTRUCTION)->Reset();

    GetMeter(METER_TARGET_INDUSTRY)->Reset();
    GetMeter(METER_TARGET_RESEARCH)->Reset();
    GetMeter(METER_TARGET_TRADE)->Reset();
    GetMeter(METER_TARGET_CONSTRUCTION)->Reset();
}
示例#21
0
double ResourceCenter::ResourceCenterNextTurnMeterValue(MeterType type) const {
    const Meter* meter = GetMeter(type);
    if (!meter) {
        throw std::invalid_argument("ResourceCenter::ResourceCenterNextTurnMeterValue passed meter type that the ResourceCenter does not have.");
    }
    double current_meter_value = meter->Current();

    MeterType target_meter_type = INVALID_METER_TYPE;
    switch (type) {
    case METER_TARGET_INDUSTRY:
    case METER_TARGET_RESEARCH:
    case METER_TARGET_TRADE:
    case METER_TARGET_CONSTRUCTION:
        return current_meter_value;
        break;
    case METER_INDUSTRY:    target_meter_type = METER_TARGET_INDUSTRY;      break;
    case METER_RESEARCH:    target_meter_type = METER_TARGET_RESEARCH;      break;
    case METER_TRADE:       target_meter_type = METER_TARGET_TRADE;         break;
    case METER_CONSTRUCTION:target_meter_type = METER_TARGET_CONSTRUCTION;  break;
    default:
        Logger().errorStream() << "ResourceCenter::ResourceCenterNextTurnMeterValue dealing with invalid meter type";
        return 0.0;
    }

    const Meter* target_meter = GetMeter(target_meter_type);
    if (!target_meter) {
        throw std::runtime_error("ResourceCenter::ResourceCenterNextTurnMeterValue dealing with invalid meter type");
    }
    double target_meter_value = target_meter->Current();

    // currently meter growth is one per turn.
    if (target_meter_value > current_meter_value)
        return std::min(current_meter_value + 1.0, target_meter_value);
    else if (target_meter_value < current_meter_value)
        return std::max(target_meter_value, current_meter_value - 1.0);
    else
        return current_meter_value;
}
示例#22
0
void PopCenter::PopCenterPopGrowthProductionResearchPhase() {
    double cur_pop = CurrentMeterValue(METER_POPULATION);
    double pop_growth = NextTurnPopGrowth();                        // may be negative
    double new_pop = cur_pop + pop_growth;

    Logger().debugStream() << "Planet Pop: " << cur_pop << " growth: " << pop_growth;

    if (new_pop >= MINIMUM_POP_CENTER_POPULATION) {
        GetMeter(METER_POPULATION)->SetCurrent(new_pop);
    } else {
        // if population falls below threshold, kill off the remainder
        Reset();
    }
}
示例#23
0
float PopCenter::PopCenterNextTurnMeterValue(MeterType meter_type) const {
    const Meter* meter = GetMeter(meter_type);
    if (!meter) {
        throw std::invalid_argument("PopCenter::PopCenterNextTurnMeterValue passed meter type that the PopCenter does not have.");

    } else if (meter_type == METER_POPULATION) {
        return meter->Current() + NextTurnPopGrowth();

    } else if (meter_type == METER_TARGET_POPULATION) {
        Logger().debugStream() << "PopCenter::PopCenterNextTurnMeterValue passed valid but unusual (TARGET) meter_type.  Returning meter->Current()";
        return meter->Current();

    } else {
        Logger().errorStream() << "PopCenter::PopCenterNextTurnMeterValue dealing with invalid meter type";
        return 0.0f;
    }
}
示例#24
0
bool Planet::HostileToEmpire(int empire_id) const
{
    if (OwnedBy(empire_id))
        return false;

    // Empire owned planets are hostile to ALL_EMPIRES
    if (empire_id == ALL_EMPIRES)
        return !Unowned();

    // Unowned planets are only considered hostile if populated
    auto pop_meter = GetMeter(METER_TARGET_POPULATION);
    if (Unowned())
        return pop_meter && (pop_meter->Current() != 0.0f);

    // both empires are normal empires
    return Empires().GetDiplomaticStatus(Owner(), empire_id) == DIPLO_WAR;
}
示例#25
0
void Planet::ResetTargetMaxUnpairedMeters() {
    UniverseObject::ResetTargetMaxUnpairedMeters();
    ResourceCenterResetTargetMaxUnpairedMeters();
    PopCenterResetTargetMaxUnpairedMeters();

    // give planets base stealth slightly above zero, so that they can't be
    // seen from a distance without high detection ability
    if (Meter* stealth = GetMeter(METER_STEALTH)) {
        stealth->ResetCurrent();
        //stealth->AddToCurrent(0.01f);
    }

    GetMeter(METER_MAX_SUPPLY)->ResetCurrent();
    GetMeter(METER_MAX_SHIELD)->ResetCurrent();
    GetMeter(METER_MAX_DEFENSE)->ResetCurrent();
    GetMeter(METER_MAX_TROOPS)->ResetCurrent();
    GetMeter(METER_REBEL_TROOPS)->ResetCurrent();
    GetMeter(METER_DETECTION)->ResetCurrent();
}
示例#26
0
void Planet::PopGrowthProductionResearchPhase() {
    UniverseObject::PopGrowthProductionResearchPhase();

    bool just_conquered = m_just_conquered;
    // do not do production if planet was just conquered
    m_just_conquered = false;

    if (!just_conquered)
        ResourceCenterPopGrowthProductionResearchPhase();

    PopCenterPopGrowthProductionResearchPhase();

    // check for planets with zero population.  If they have a species set, then
    // they probably just starved
    if (!SpeciesName().empty() && GetMeter(METER_POPULATION)->Current() == 0.0) {
        if (Empire* empire = Empires().Lookup(this->Owner())) {
            // generate starvation sitrep for empire that owns this depopulated planet
            empire->AddSitRepEntry(CreatePlanetStarvedToDeathSitRep(this->ID()));

            // record depopulation of planet with species while owned by this empire
            std::map<std::string, int>::iterator species_it =
                empire->SpeciesShipsLost().find(SpeciesName());
            if (species_it == empire->SpeciesPlanetsDepoped().end())
                empire->SpeciesPlanetsDepoped()[SpeciesName()] = 1;
            else
                species_it->second++;
        }
        // remove species
        SetSpecies("");
    }

    if (!just_conquered) {
        GetMeter(METER_SHIELD)->SetCurrent(Planet::NextTurnCurrentMeterValue(METER_SHIELD));
        GetMeter(METER_DEFENSE)->SetCurrent(Planet::NextTurnCurrentMeterValue(METER_DEFENSE));
        GetMeter(METER_TROOPS)->SetCurrent(Planet::NextTurnCurrentMeterValue(METER_TROOPS));
        GetMeter(METER_REBEL_TROOPS)->SetCurrent(Planet::NextTurnCurrentMeterValue(METER_REBEL_TROOPS));
        GetMeter(METER_SUPPLY)->SetCurrent(Planet::NextTurnCurrentMeterValue(METER_SUPPLY));
    }

    StateChangedSignal();
}
示例#27
0
void Planet::PopGrowthProductionResearchPhase() {
    UniverseObject::PopGrowthProductionResearchPhase();

    bool just_conquered = m_just_conquered;
    // do not do production if planet was just conquered
    m_just_conquered = false;

    if (!just_conquered)
        ResourceCenterPopGrowthProductionResearchPhase();

    PopCenterPopGrowthProductionResearchPhase();

    // check for colonies without positive population, and change to outposts
    if (!SpeciesName().empty() && GetMeter(METER_POPULATION)->Current() <= 0.0f) {
        if (Empire* empire = GetEmpire(this->Owner())) {
            empire->AddSitRepEntry(CreatePlanetDepopulatedSitRep(this->ID()));

            if (!HasTag(TAG_STAT_SKIP_DEPOP)) {
                // record depopulation of planet with species while owned by this empire
                std::map<std::string, int>::iterator species_it = empire->SpeciesPlanetsDepoped().find(SpeciesName());
                if (species_it == empire->SpeciesPlanetsDepoped().end())
                    empire->SpeciesPlanetsDepoped()[SpeciesName()] = 1;
                else
                    species_it->second++;
            }
        }
        // remove species
        PopCenter::Reset();
    }

    if (!just_conquered) {
        GetMeter(METER_SHIELD)->SetCurrent(Planet::NextTurnCurrentMeterValue(METER_SHIELD));
        GetMeter(METER_DEFENSE)->SetCurrent(Planet::NextTurnCurrentMeterValue(METER_DEFENSE));
        GetMeter(METER_TROOPS)->SetCurrent(Planet::NextTurnCurrentMeterValue(METER_TROOPS));
        GetMeter(METER_REBEL_TROOPS)->SetCurrent(Planet::NextTurnCurrentMeterValue(METER_REBEL_TROOPS));
        GetMeter(METER_SUPPLY)->SetCurrent(Planet::NextTurnCurrentMeterValue(METER_SUPPLY));
    }

    StateChangedSignal();
}
示例#28
0
bool Planet::Colonize(int empire_id, const std::string& species_name, double population) {
    const Species* species = nullptr;

    // if desired pop > 0, we want a colony, not an outpost, so we need to do some checks
    if (population > 0.0) {
        // check if specified species exists and get reference
        species = GetSpecies(species_name);
        if (!species) {
            ErrorLogger() << "Planet::Colonize couldn't get species already on planet with name: " << species_name;
            return false;
        }
        // check if specified species can colonize this planet
        if (EnvironmentForSpecies(species_name) < PE_HOSTILE) {
            ErrorLogger() << "Planet::Colonize: can't colonize planet already populated by species " << species_name;
            return false;
        }
    }

    // reset the planet to unowned/unpopulated
    if (!OwnedBy(empire_id)) {
        Reset();
    } else {
        PopCenter::Reset();
        for (int building_id : m_buildings)
            if (auto building = GetBuilding(building_id))
                building->Reset();
        m_just_conquered = false;
        m_is_about_to_be_colonized = false;
        m_is_about_to_be_invaded = false;
        m_is_about_to_be_bombarded = false;
        SetOwner(ALL_EMPIRES);
    }

    // if desired pop > 0, we want a colony, not an outpost, so we have to set the colony species
    if (population > 0.0)
        SetSpecies(species_name);

    // find a default focus. use first defined available focus.
    // AvailableFoci function should return a vector of all names of
    // available foci.
    std::vector<std::string> available_foci = AvailableFoci();
    if (species && !available_foci.empty()) {
        bool found_preference = false;
        for (const std::string& focus : available_foci) {
            if (!focus.empty() && focus == species->PreferredFocus()) {
                SetFocus(focus);
                found_preference = true;
                break;
            }
        }

        if (!found_preference)
            SetFocus(*available_foci.begin());
    } else {
        DebugLogger() << "Planet::Colonize unable to find a focus to set for species " << species_name;
    }

    // set colony population
    GetMeter(METER_POPULATION)->SetCurrent(population);
    GetMeter(METER_TARGET_POPULATION)->SetCurrent(population);
    BackPropagateMeters();


    // set specified empire as owner
    SetOwner(empire_id);

    // if there are buildings on the planet, set the specified empire as their owner too
    for (auto& building : Objects().FindObjects<Building>(BuildingIDs()))
    { building->SetOwner(empire_id); }

    return true;
}
示例#29
0
void Planet::Conquer(int conquerer) {
    m_just_conquered = true;

    // deal with things on production queue located at this planet
    Empire::ConquerProductionQueueItemsAtLocation(ID(), conquerer);

    // deal with UniverseObjects (eg. buildings) located on this planet
    for (auto& building : Objects().FindObjects<Building>(m_buildings)) {
        const BuildingType* type = GetBuildingType(building->BuildingTypeName());

        // determine what to do with building of this type...
        const CaptureResult cap_result = type->GetCaptureResult(building->Owner(), conquerer, this->ID(), false);

        if (cap_result == CR_CAPTURE) {
            // replace ownership
            building->SetOwner(conquerer);
        } else if (cap_result == CR_DESTROY) {
            // destroy object
            //DebugLogger() << "Planet::Conquer destroying object: " << building->Name();
            this->RemoveBuilding(building->ID());
            if (auto system = GetSystem(this->SystemID()))
                system->Remove(building->ID());
            GetUniverse().Destroy(building->ID());
        } else if (cap_result == CR_RETAIN) {
            // do nothing
        }
    }

    // replace ownership
    SetOwner(conquerer);

    GetMeter(METER_SUPPLY)->SetCurrent(0.0f);
    GetMeter(METER_SUPPLY)->BackPropagate();
    GetMeter(METER_INDUSTRY)->SetCurrent(0.0f);
    GetMeter(METER_INDUSTRY)->BackPropagate();
    GetMeter(METER_RESEARCH)->SetCurrent(0.0f);
    GetMeter(METER_RESEARCH)->BackPropagate();
    GetMeter(METER_TRADE)->SetCurrent(0.0f);
    GetMeter(METER_TRADE)->BackPropagate();
    GetMeter(METER_CONSTRUCTION)->SetCurrent(0.0f);
    GetMeter(METER_CONSTRUCTION)->BackPropagate();
    GetMeter(METER_DEFENSE)->SetCurrent(0.0f);
    GetMeter(METER_DEFENSE)->BackPropagate();
    GetMeter(METER_SHIELD)->SetCurrent(0.0f);
    GetMeter(METER_SHIELD)->BackPropagate();
    GetMeter(METER_HAPPINESS)->SetCurrent(0.0f);
    GetMeter(METER_HAPPINESS)->BackPropagate();
    GetMeter(METER_DETECTION)->SetCurrent(0.0f);
    GetMeter(METER_DETECTION)->BackPropagate();
}
示例#30
0
void UniverseObject::ClampMeters()
{ GetMeter(METER_STEALTH)->ClampCurrentToRange(); }