示例#1
0
def _get_production_bonus_unmodified(planet: fo.planet, stability: float) -> float:
    """
    Calculate bonus production per population which we would get independent of the species production skill.
    """
    specials_bonus = sum(
        # growth.macros: STANDARD_INDUSTRY_BOOST
        AIDependencies.INDUSTRY_PER_POP
        for s in planet.specials
        if s in AIDependencies.industry_boost_specials_unmodified
    )

    # TBD: check connections?
    bonuses = [
        Bonus(
            bool(BuildingType.SOL_ORB_GEN.built_or_queued_at()),  # TBD: check star type
            get_named_real("BLD_SOL_ORB_GEN_MIN_STABILITY"),
            get_named_real("BLD_SOL_ORB_GEN_BRIGHT_TARGET_INDUSTRY_PERPOP"),
        ),
        Bonus(
            have_honeycomb(),
            0.0,
            get_named_real("HONEYCOMB_TARGET_INDUSTRY_PERPOP"),
        ),
        # TBD: Collective Thought Network? Ignored for now, AI doesn't know how to handle it.
        # It shouldn't make a big difference for selecting which planets to colonise anyway.
    ]
    return specials_bonus + sum(bonus.get_bonus(stability) for bonus in bonuses)
示例#2
0
def _get_asteroid_and_ggg_value(planet: fo.planet, stability: float) -> float:
    """
    Calculate an estimate of the bonus we may get from asteroids (microgravity) and gas giant generators.
    """
    universe = fo.getUniverse()
    system = universe.getSystem(planet.systemID)
    ast_min_stability = get_named_real("PRO_MICROGRAV_MAN_MIN_STABILITY")
    count_asteroids = ast_min_stability <= stability and tech_soon_available(AIDependencies.PRO_MICROGRAV_MAN, 5)
    ggg_min_stability = get_named_real("BLD_GAS_GIANT_GEN_MIN_STABILITY")
    count_ggg = ggg_min_stability <= stability and tech_soon_available(AIDependencies.PRO_ORBITAL_GEN, 5)
    asteroid_value = 0.0
    ggg_value = 0.0
    for pid in system.planetIDs:
        p2 = universe.getPlanet(pid)
        if p2:
            if count_asteroids and p2.size == fo.planetSize.asteroids:
                full_bonus = get_named_real("PRO_MICROGRAV_MAN_TARGET_INDUSTRY_FLAT")
                if p2.owner == fo.empireID or pid == planet.id:
                    asteroid_value = full_bonus
                elif p2.unowned:
                    asteroid_value = max(asteroid_value, 0.5 * full_bonus)
                # TODO prospective_invasion_targets?
            if count_ggg:
                ggg_value = max(ggg_value, _ggg_value(planet, p2))
    debug_rating(
        f"_get_asteroid_and_ggg_value amin={ast_min_stability:.1f}->{count_asteroids:.1f}, "
        f"gmin={ggg_min_stability:.1f}->{count_ggg:.1f}, aval={asteroid_value:.1f}, gval={ggg_value:.1f}"
    )
    return asteroid_value + ggg_value
示例#3
0
def _get_policy_multiplier(stability) -> float:
    # if fo.getEmpire().policyAdopted("TECHNOCRACY") and stability >= get_named_real("PLC_TECHNOCRACY_MIN_STABILITY"):
    #     return 1.0 + get_named_real("PLC_TECHNOCRACY_TARGET_RESEARCH_PERCENT")
    if fo.getEmpire().policyAdopted(
            "TECHNOCRACY"
    ) and stability >= get_named_real("PLC_TECHNOCRACY_MIN_STABILITY"):
        return 1.0 + get_named_real("PLC_TECHNOCRACY_TARGET_RESEARCH_PERCENT")
    return 1.0
示例#4
0
def _get_production_bonus_mod_by_policy(stability: float) -> float:
    """
    Calculate bonus production per population which we would get independent of the species production skill,
    but still affected by industrialism.
    """
    # TBD: check connections?
    bonuses = [
        Bonus(
            bool(BuildingType.BLACK_HOLE_POW_GEN.built_or_queued_at()),
            get_named_real("BLD_BLACK_HOLE_POW_GEN_MIN_STABILITY"),
            get_named_real("BLD_BLACK_HOLE_POW_GEN_TARGET_INDUSTRY_PERPOP"),
        ),
    ]
    return sum(bonus.get_bonus(stability) for bonus in bonuses)
示例#5
0
def _get_modified_research_bonuses(planet: fo.planet) -> List[Bonus]:
    """
    Get list of per-population bonuses which are added before multiplication with the species skill value.
    """
    # use fo.getEmpire().researchQueue directly here to simplify caching this function
    specials = planet.specials
    return [
        Bonus(
            AIDependencies.ANCIENT_RUINS_SPECIAL in specials
            or AIDependencies.ANCIENT_RUINS_SPECIAL2 in specials,
            get_named_real("ANCIENT_RUINS_MIN_STABILITY"),
            get_named_real("ANCIENT_RUINS_TARGET_RESEARCH_PERPOP"),
        ),
        Bonus(
            fo.getEmpire().policyAdopted("PLC_DIVERSITY"),
            get_named_real("PLC_DIVERSITY_MIN_STABILITY"),
            (len(get_empire_planets_by_species()) -
             get_named_int("PLC_DIVERSITY_THRESHOLD")) *
            get_named_real("PLC_DIVERSITY_SCALING"),
        ),
        Bonus(
            tech_soon_available("GRO_ENERGY_META", 3),
            get_named_real("GRO_ENERGY_META_MIN_STABILITY"),
            get_named_real("GRO_ENERGY_META_TARGET_RESEARCH_PERPOP"),
        ),
        Bonus(
            bool(BuildingType.ENCLAVE_VOID.built_or_queued_at()),
            get_named_real("BLD_ENCLAVE_VOID_MIN_STABILITY"),
            get_named_real("BLD_ENCLAVE_VOID_TARGET_RESEARCH_PERPOP"),
        ),
    ]
示例#6
0
def _get_production_flat(planet: fo.planet, stability: float) -> float:
    """
    Calculate population independent production bonus.
    """
    value = _get_asteroid_and_ggg_value(planet, stability)
    # this is a rather expensive one, so consider it only if it is on top of the list
    if tech_soon_available(AIDependencies.PRO_AUTO_2, 1):
        value += get_named_real("PRO_SENTIENT_AUTO_TARGET_INDUSTRY_FLAT")
    return value
示例#7
0
def _get_research_bonus_unmodified(planet: fo.planet, stability: float):
    """
    Calculate bonus research per population which we would get independent of the species research skill.
    """
    bonuses = [
        Bonus(
            fo.getEmpire().policyAdopted("PLC_ALGORITHMIC_RESEARCH"),
            get_named_real("LRN_ALGO_RESEARCH_MIN_STABILITY"),
            get_named_real(
                "LRN_ALGO_RESEARCH_TARGET_RESEARCH_PERCONSTRUCTION"),
        ),
        Bonus(
            tech_soon_available("LRN_DISTRIB_THOUGHT", 3),
            get_named_real("LRN_DISTRIB_THOUGHT_MIN_STABILITY"),
            _get_distributed_thought_bonus(planet.systemID),
        ),
        # TODO: distributed thought and collective thought
    ]
    return sum(bonus.get_bonus(stability) for bonus in bonuses)
示例#8
0
def _ggg_value(planet: fo.planet, p2: fo.planet) -> float:
    """
    Check if p2 not planet and is a gas giant. If determines a value for the potential GGG on p2.
    """
    if p2.id != planet.id and p2.size == fo.planetSize.gasGiant:
        ggg_colony_flat = get_named_real("BLD_GAS_GIANT_GEN_COLONY_TARGET_INDUSTRY_FLAT")
        ggg_outpost_flat = get_named_real("BLD_GAS_GIANT_GEN_OUTPOST_TARGET_INDUSTRY_FLAT")
        # species living on a GG do not like a GGG, so we ignore the planet itself here
        if p2.owner == fo.empireID():
            if not p2.speciesName:
                return ggg_outpost_flat
            if p2.id in BuildingType.GAS_GIANT_GEN.built_or_queued_at():
                return ggg_colony_flat
            else:
                return 0.4 * ggg_colony_flat  # we could build one, but inhabitants won't like it
        if p2.unowned:
            return 0.5 * ggg_colony_flat  # unowned means we could probably get it easily
        # TODO prospective_invasion_targets?
        #  So far we do not consider owned gas giant for planets here
    return 0.0
示例#9
0
def _get_distributed_thought_bonus(system_id: SystemId) -> float:
    universe = fo.getUniverse()
    max_distance = max(
        (universe.linearDistance(system_id, p.systemID)
         for p in get_empire_populated_planets()
         if p.focus == FocusType.FOCUS_RESEARCH),
        default=0.0,
    )
    # TBD? This could also affect other planets...
    return get_named_real(
        "DISTRIB_THOUGH_RESEARCH_SCALING") * max_distance**0.5
示例#10
0
def _get_stellar_tomography_bonus(system_id: SystemId) -> float:
    universe = fo.getUniverse()
    system = universe.getSystem(system_id)
    if system.starType == fo.starType.blackHole:
        factor = get_named_real(
            "LRN_STELLAR_TOMO_BLACK_TARGET_RESEARCH_PERPLANET")
    elif system.starType == fo.starType.neutron:
        factor = get_named_real(
            "LRN_STELLAR_TOMO_NEUTRON_TARGET_RESEARCH_PERPLANET")
    else:
        factor = get_named_real(
            "LRN_STELLAR_TOMO_NORMAL_STAR_TARGET_RESEARCH_PERPLANET")

    def is_our_researcher(pid):
        planet = universe.getPlanet(pid)
        return planet.focus == FocusType.FOCUS_RESEARCH and planet.owner == fo.empireID(
        )

    num_researcher = sum(1 for pid in system.planetIDs
                         if is_our_researcher(pid))
    # if we add another planet with research focus, all will profit. (n+1)^2 - n^2 = 2n + 1
    return (num_researcher * 2 + 1) * factor
示例#11
0
def _get_modified_industry_bonuses() -> List[Bonus]:
    """
    Get list of per-population bonuses which are added before multiplication with the species skill value.
    """
    # TBD check connection!?
    have_center = bool(BuildingType.INDUSTRY_CENTER.built_or_queued_at())
    centre_bonus1 = get_named_real("BLD_INDUSTRY_CENTER_1_TARGET_INDUSTRY_PERPOP")
    centre_bonus2 = get_named_real("BLD_INDUSTRY_CENTER_2_TARGET_INDUSTRY_PERPOP")
    centre_bonus3 = get_named_real("BLD_INDUSTRY_CENTER_3_TARGET_INDUSTRY_PERPOP")
    return [
        Bonus(
            tech_soon_available("PRO_FUSION_GEN", 3),
            get_named_real("PRO_FUSION_GEN_MIN_STABILITY"),
            get_named_real("PRO_FUSION_GEN_TARGET_INDUSTRY_PERPOP"),
        ),
        Bonus(
            tech_soon_available("GRO_ENERGY_META", 3),
            get_named_real("GRO_ENERGY_META_MIN_STABILITY"),
            get_named_real("GRO_ENERGY_META_TARGET_INDUSTRY_PERPOP"),
        ),
        # special case: these are not cumulative
        Bonus(
            have_center and tech_soon_available("PRO_INDUSTRY_CENTER_III", 1),  # expensive research
            get_named_real("BLD_INDUSTRY_CENTER_3_MIN_STABILITY"),
            centre_bonus3 - centre_bonus2,
        ),
        Bonus(
            have_center and tech_soon_available("PRO_INDUSTRY_CENTER_II", 2),
            get_named_real("BLD_INDUSTRY_CENTER_2_MIN_STABILITY"),
            centre_bonus2 - centre_bonus1,
        ),
        Bonus(
            # normally we have the tech when we have the building, but we could have conquered one
            have_center and tech_soon_available("PRO_INDUSTRY_CENTER_II", 3),
            get_named_real("BLD_INDUSTRY_CENTER_1_MIN_STABILITY"),
            centre_bonus1,
        ),
    ]
示例#12
0
def _get_modified_by_policy_research_bonuses(stability: float) -> List[Bonus]:
    return [
        Bonus(
            tech_soon_available("LRN_QUANT_NET", 3),
            get_named_real("LRN_QUANT_NET_MIN_STABILITY"),
            get_named_real("LRN_QUANT_NET_TARGET_RESEARCH_PERPOP"),
        ),
        # TBD check connection, _empire_resources should collect a list of systems or planets
        Bonus(
            have_computronium(),
            get_named_real("COMPUTRONIUM_MIN_STABILITY"),
            get_named_real("COMPUTRONIUM_TARGET_RESEARCH_PERPOP"),
        ),
        Bonus(
            fo.getEmpire().policyAdopted("PLC_LIBERTY"),
            get_named_real("PLC_LIBERTY_MIN_STABILITY"),
            (min(stability, get_named_real("PLC_LIBERTY_MAX_STABILITY")) -
             get_named_real("PLC_LIBERTY_MIN_STABILITY")) *
            get_named_real("PLC_LIBERTY_RESEARCH_BONUS_SCALING"),
        ),
    ]
示例#13
0
def _get_policy_multiplier(stability) -> float:
    if fo.getEmpire().policyAdopted("INDUSTRIALISM") and stability >= get_named_real("PLC_INDUSTRIALISM_MIN_STABILITY"):
        return 1.0 + get_named_real("PLC_INDUSTRIALISM_TARGET_INDUSTRY_PERCENT")
    return 1.0