int HullType::ProductionTime(int empire_id, int location_id) const { if (CHEAP_AND_FAST_SHIP_PRODUCTION || !m_production_time) { return 1; } else { if (ValueRef::ConstantExpr(m_production_time)) return m_production_time->Eval(); UniverseObject* location = GetUniverseObject(location_id); if (!location) return 9999; // arbitrary large number const UniverseObject* source = SourceForEmpire(empire_id); ScriptingContext context(source, location); return m_production_time->Eval(context); } }
float HullType::ProductionCost(int empire_id, int location_id) const { if (CHEAP_AND_FAST_SHIP_PRODUCTION || !m_production_cost) { return 1.0f; } else { if (ValueRef::ConstantExpr(m_production_cost)) return static_cast<float>(m_production_cost->Eval()); TemporaryPtr<UniverseObject> location = GetUniverseObject(location_id); if (!location) return 999999.9f; // arbitrary large number TemporaryPtr<const UniverseObject> source = SourceForEmpire(empire_id); ScriptingContext context(source, location); return static_cast<float>(m_production_cost->Eval(context)); } }
int PartType::ProductionTime(int empire_id, int location_id) const { if (CHEAP_AND_FAST_SHIP_PRODUCTION || !m_production_time) { return 1; } else { if (ValueRef::ConstantExpr(m_production_time)) return m_production_time->Eval(); TemporaryPtr<UniverseObject> location = GetUniverseObject(location_id); if (!location) return 9999; // arbitrary large number TemporaryPtr<const UniverseObject> source = SourceForEmpire(empire_id); if (!source && !m_production_time->SourceInvariant()) return 9999; ScriptingContext context(source, location); return m_production_time->Eval(context); } }
bool ShipDesign::ProductionLocation(int empire_id, int location_id) const { const UniverseObject* location = GetUniverseObject(location_id); if (!location) return false; // currently ships can only be built at planets, and by species that are // not planetbound const Planet* planet = universe_object_cast<const Planet*>(location); if (!planet) return false; const std::string& species_name = planet->SpeciesName(); if (species_name.empty()) return false; const Species* species = GetSpecies(species_name); if (!species) return false; if (!species->CanProduceShips()) return false; // also, species that can't colonize can't produce colony ships if (this->CanColonize() && !species->CanColonize()) return false; Empire* empire = Empires().Lookup(empire_id); if (!empire) { Logger().debugStream() << "ShipDesign::ProductionLocation: Unable to get pointer to empire " << empire_id; return false; } // get a source object, which is owned by the empire with the passed-in // empire id. this is used in conditions to reference which empire is // doing the producing. Ideally this will be the capital, but any object // owned by the empire will work. const UniverseObject* source = SourceForEmpire(empire_id); // if this empire doesn't own ANYTHING, then how is it producing anyway? if (!source) return false; // apply hull location conditions to potential location const HullType* hull = GetHull(); if (!hull) { Logger().errorStream() << "ShipDesign::ProductionLocation ShipDesign couldn't get its own hull with name " << m_hull; return false; } if (!hull->Location()->Eval(ScriptingContext(source), location)) return false; // apply external and internal parts' location conditions to potential location for (std::vector<std::string>::const_iterator part_it = m_parts.begin(); part_it != m_parts.end(); ++part_it) { std::string part_name = *part_it; if (part_name.empty()) continue; // empty slots don't limit build location const PartType* part = GetPartType(part_name); if (!part) { Logger().errorStream() << "ShipDesign::ProductionLocation ShipDesign couldn't get part with name " << part_name; return false; } if (!part->Location()->Eval(ScriptingContext(source), location)) return false; } // location matched all hull and part conditions, so is a valid build location return true; }