From: <geo...@us...> - 2008-08-05 08:07:42
|
Revision: 2651 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=2651&view=rev Author: geoffthemedio Date: 2008-08-05 08:07:51 +0000 (Tue, 05 Aug 2008) Log Message: ----------- -Added effect parser for MoveTo effect. Tested with player's empire's fleets, and seems to work fine. Tested with all fleets, and seems to work, but crashes server. I suspect this is due to visibility information not being properly updated after the enemy empire's fleet is inserted into the player's system, leading to an AI crash when it attempts to issue orders to an inconsistent universe. For now this doesn't affect the rest of the game, as nothing in trunk yet uses the MoveTo effect. -Added OrbitOccupied and FreeOrbits functions to System, which determine if there's anything in a particular orbit (by number) and returns a set of free orbit numbers, respectively. The latter is used to implement the MoveTo effect in the case of a planet target object. Modified Paths: -------------- trunk/FreeOrion/universe/Effect.cpp trunk/FreeOrion/universe/EffectParser.cpp trunk/FreeOrion/universe/System.cpp trunk/FreeOrion/universe/System.h Modified: trunk/FreeOrion/universe/Effect.cpp =================================================================== --- trunk/FreeOrion/universe/Effect.cpp 2008-08-05 03:00:46 UTC (rev 2650) +++ trunk/FreeOrion/universe/Effect.cpp 2008-08-05 08:07:51 UTC (rev 2651) @@ -19,7 +19,6 @@ using namespace Effect; using namespace boost::io; using boost::lexical_cast; -using boost::format; extern int g_indent; @@ -205,11 +204,11 @@ if (dynamic_cast<const Condition::Self*>(m_scope)) retval.scope_description = UserString("DESC_EFFECTS_GROUP_SELF_SCOPE"); else - retval.scope_description = str(format(UserString("DESC_EFFECTS_GROUP_SCOPE")) % m_scope->Description()); + retval.scope_description = str(FlexibleFormat(UserString("DESC_EFFECTS_GROUP_SCOPE")) % m_scope->Description()); if (dynamic_cast<const Condition::Self*>(m_activation) || dynamic_cast<const Condition::All*>(m_activation)) retval.activation_description = UserString("DESC_EFFECTS_GROUP_ALWAYS_ACTIVE"); else - retval.activation_description = str(format(UserString("DESC_EFFECTS_GROUP_ACTIVATION")) % m_activation->Description()); + retval.activation_description = str(FlexibleFormat(UserString("DESC_EFFECTS_GROUP_ACTIVATION")) % m_activation->Description()); for (unsigned int i = 0; i < m_effects.size(); ++i) { retval.effect_descriptions.push_back(m_effects[i]->Description()); } @@ -223,11 +222,11 @@ } else { std::stringstream retval; Description description = GetDescription(); - retval << str(format(UserString("DESC_EFFECTS_GROUP_SCOPE_DESC")) % description.scope_description); + retval << str(FlexibleFormat(UserString("DESC_EFFECTS_GROUP_SCOPE_DESC")) % description.scope_description); if (!dynamic_cast<const Condition::Self*>(m_activation) && !dynamic_cast<const Condition::All*>(m_activation)) - retval << str(format(UserString("DESC_EFFECTS_GROUP_ACTIVATION_DESC")) % description.activation_description); + retval << str(FlexibleFormat(UserString("DESC_EFFECTS_GROUP_ACTIVATION_DESC")) % description.activation_description); for (unsigned int i = 0; i < description.effect_descriptions.size(); ++i) { - retval << str(format(UserString("DESC_EFFECTS_GROUP_EFFECT_DESC")) % description.effect_descriptions[i]); + retval << str(FlexibleFormat(UserString("DESC_EFFECTS_GROUP_EFFECT_DESC")) % description.effect_descriptions[i]); } return retval.str(); } @@ -275,10 +274,10 @@ { std::stringstream retval; if (effects_groups.size() == 1) { - retval << str(format(UserString("DESC_EFFECTS_GROUP_EFFECTS_GROUP_DESC")) % effects_groups[0]->DescriptionString()); + retval << str(FlexibleFormat(UserString("DESC_EFFECTS_GROUP_EFFECTS_GROUP_DESC")) % effects_groups[0]->DescriptionString()); } else { for (unsigned int i = 0; i < effects_groups.size(); ++i) { - retval << str(format(UserString("DESC_EFFECTS_GROUP_NUMBERED_EFFECTS_GROUP_DESC")) % (i + 1) % effects_groups[i]->DescriptionString()); + retval << str(FlexibleFormat(UserString("DESC_EFFECTS_GROUP_NUMBERED_EFFECTS_GROUP_DESC")) % (i + 1) % effects_groups[i]->DescriptionString()); } } return retval.str(); @@ -331,12 +330,12 @@ case ValueRef::DIVIDES: op_char = '/'; break; default: op_char = '?'; } - return str(format(UserString(m_max ? "DESC_SIMPLE_SET_METER_MAX" : "DESC_SIMPLE_SET_METER_CURRENT")) + return str(FlexibleFormat(UserString(m_max ? "DESC_SIMPLE_SET_METER_MAX" : "DESC_SIMPLE_SET_METER_CURRENT")) % UserString(lexical_cast<std::string>(m_meter)) % op_char % lexical_cast<std::string>(const_operand)); } else { - return str(format(UserString(m_max ? "DESC_COMPLEX_SET_METER_MAX" : "DESC_COMPLEX_SET_METER_CURRENT")) + return str(FlexibleFormat(UserString(m_max ? "DESC_COMPLEX_SET_METER_MAX" : "DESC_COMPLEX_SET_METER_CURRENT")) % UserString(lexical_cast<std::string>(m_meter)) % m_value->Description()); } @@ -387,7 +386,7 @@ std::string SetEmpireStockpile::Description() const { std::string value_str = ValueRef::ConstantExpr(m_value) ? lexical_cast<std::string>(m_value->Eval(0, 0)) : m_value->Description(); - return str(format(UserString("DESC_SET_EMPIRE_STOCKPILE")) % UserString(lexical_cast<std::string>(m_stockpile)) % value_str); + return str(FlexibleFormat(UserString("DESC_SET_EMPIRE_STOCKPILE")) % UserString(lexical_cast<std::string>(m_stockpile)) % value_str); } std::string SetEmpireStockpile::Dump() const @@ -435,7 +434,7 @@ std::string SetPlanetType::Description() const { std::string value_str = ValueRef::ConstantExpr(m_type) ? UserString(lexical_cast<std::string>(m_type->Eval(0, 0))) : m_type->Description(); - return str(format(UserString("DESC_SET_PLANET_TYPE")) % value_str); + return str(FlexibleFormat(UserString("DESC_SET_PLANET_TYPE")) % value_str); } std::string SetPlanetType::Dump() const @@ -473,7 +472,7 @@ std::string SetPlanetSize::Description() const { std::string value_str = ValueRef::ConstantExpr(m_size) ? UserString(lexical_cast<std::string>(m_size->Eval(0, 0))) : m_size->Description(); - return str(format(UserString("DESC_SET_PLANET_SIZE")) % value_str); + return str(FlexibleFormat(UserString("DESC_SET_PLANET_SIZE")) % value_str); } std::string SetPlanetSize::Dump() const @@ -504,7 +503,7 @@ std::string AddOwner::Description() const { std::string value_str = ValueRef::ConstantExpr(m_empire_id) ? Empires().Lookup(m_empire_id->Eval(0, 0))->Name() : m_empire_id->Description(); - return str(format(UserString("DESC_ADD_OWNER")) % value_str); + return str(FlexibleFormat(UserString("DESC_ADD_OWNER")) % value_str); } std::string AddOwner::Dump() const @@ -535,7 +534,7 @@ std::string RemoveOwner::Description() const { std::string value_str = ValueRef::ConstantExpr(m_empire_id) ? Empires().Lookup(m_empire_id->Eval(0, 0))->Name() : m_empire_id->Description(); - return str(format(UserString("DESC_REMOVE_OWNER")) % value_str); + return str(FlexibleFormat(UserString("DESC_REMOVE_OWNER")) % value_str); } std::string RemoveOwner::Dump() const @@ -593,7 +592,7 @@ std::string AddSpecial::Description() const { - return str(format(UserString("DESC_ADD_SPECIAL")) % UserString(m_name)); + return str(FlexibleFormat(UserString("DESC_ADD_SPECIAL")) % UserString(m_name)); } std::string AddSpecial::Dump() const @@ -616,7 +615,7 @@ std::string RemoveSpecial::Description() const { - return str(format(UserString("DESC_REMOVE_SPECIAL")) % UserString(m_name)); + return str(FlexibleFormat(UserString("DESC_REMOVE_SPECIAL")) % UserString(m_name)); } std::string RemoveSpecial::Dump() const @@ -647,7 +646,7 @@ std::string SetStarType::Description() const { std::string value_str = ValueRef::ConstantExpr(m_type) ? UserString(lexical_cast<std::string>(m_type->Eval(0, 0))) : m_type->Description(); - return str(format(UserString("DESC_SET_STAR_TYPE")) % value_str); + return str(FlexibleFormat(UserString("DESC_SET_STAR_TYPE")) % value_str); } std::string SetStarType::Dump() const @@ -673,11 +672,14 @@ Universe& universe = GetUniverse(); int dest_id = m_destination_object_id->Eval(source, target); UniverseObject* destination = universe.Object(dest_id); - if (!destination) return; + if (!destination) { + Logger().errorStream() << "MoveTo::Execute couldn't get destination object with specified id: " << dest_id; + return; + } - // restrict movable object types to the following, as moving others (eg. ships, systems) isn't - // supported yet, due to complicated other bookeeping that would be required if (Fleet* fleet = universe_object_cast<Fleet*>(target)) { + // fleets can be inserted into the system that contains the destination object (or the + // destination object istelf if it is a system if (System* dest_system = destination->GetSystem()) { dest_system->Insert(target); } else { @@ -703,18 +705,24 @@ } } else if (Planet* planet = universe_object_cast<Planet*>(target)) { + // planets need to be located in systems, so get system that contains destination object if (System* dest_system = destination->GetSystem()) { // determine if and which orbits are available - // if an orbit is available... - // dest_system->Insert(target); + std::set<int> free_orbits = dest_system->FreeOrbits(); + if (!free_orbits.empty()) { + int orbit = *(free_orbits.begin()); + dest_system->Insert(target, orbit); + } } // don't move planets to a location outside a system } else if (Building* building = universe_object_cast<Building*>(target)) { + // buildings need to be located on planets, so if destination is a planet, insert building into it, + // or attempt to get the planet on which the destination object is located and insert target building into that if (Planet* dest_planet = universe_object_cast<Planet*>(destination)) { dest_planet->AddBuilding(building->ID()); - } - else if (Building* dest_building = universe_object_cast<Building*>(destination)) { + + } else if (Building* dest_building = universe_object_cast<Building*>(destination)) { if (Planet* dest_planet = dest_building->GetPlanet()) { dest_planet->AddBuilding(building->ID()); } @@ -725,13 +733,13 @@ std::string MoveTo::Description() const { - std::string value_str = ValueRef::ConstantExpr(m_destination_object_id) ? Empires().Lookup(m_destination_object_id->Eval(0, 0))->Name() : m_destination_object_id->Description(); - return str(format(UserString("DESC_ADD_OWNER")) % value_str); + std::string value_str = ValueRef::ConstantExpr(m_destination_object_id) ? GetUniverse().Object(m_destination_object_id->Eval(0, 0))->Name() : m_destination_object_id->Description(); + return str(FlexibleFormat(UserString("DESC_MOVE_TO")) % value_str); } std::string MoveTo::Dump() const { - return DumpIndent() + "AddOwner empire = " + m_destination_object_id->Dump() + "\n"; + return DumpIndent() + "MoveTo destination_object_id = empire = " + m_destination_object_id->Dump() + "\n"; } @@ -774,9 +782,9 @@ std::string SetTechAvailability::Description() const { - std::string affected = str(format(UserString(m_include_tech ? "DESC_TECH_AND_ITEMS_AFFECTED" : "DESC_ITEMS_ONLY_AFFECTED")) % m_tech_name); + std::string affected = str(FlexibleFormat(UserString(m_include_tech ? "DESC_TECH_AND_ITEMS_AFFECTED" : "DESC_ITEMS_ONLY_AFFECTED")) % m_tech_name); std::string empire_str = ValueRef::ConstantExpr(m_empire_id) ? Empires().Lookup(m_empire_id->Eval(0, 0))->Name() : m_empire_id->Description(); - return str(format(UserString(m_available ? "DESC_SET_TECH_AVAIL" : "DESC_SET_TECH_UNAVAIL")) + return str(FlexibleFormat(UserString(m_available ? "DESC_SET_TECH_AVAIL" : "DESC_SET_TECH_UNAVAIL")) % affected % empire_str); } Modified: trunk/FreeOrion/universe/EffectParser.cpp =================================================================== --- trunk/FreeOrion/universe/EffectParser.cpp 2008-08-05 03:00:46 UTC (rev 2650) +++ trunk/FreeOrion/universe/EffectParser.cpp 2008-08-05 08:07:51 UTC (rev 2651) @@ -52,6 +52,12 @@ member2 empire; }; + struct ObjectIDParamClosure : boost::spirit::closure<ObjectIDParamClosure, Effect::EffectBase*, ValueRef::ValueRefBase<int>*> + { + member1 this_; + member2 object_id; + }; + struct NameParamClosure : boost::spirit::closure<NameParamClosure, Effect::EffectBase*, std::string> { member1 this_; @@ -72,32 +78,35 @@ member4 include_tech; }; - typedef rule<Scanner, SetMeterClosure::context_t> SetMeterRule; - typedef rule<Scanner, SetOwnerStockpileClosure::context_t> SetOwnerStockpileRule; - typedef rule<Scanner, SetPlanetTypeClosure::context_t> SetPlanetTypeRule; - typedef rule<Scanner, SetPlanetSizeClosure::context_t> SetPlanetSizeRule; - typedef rule<Scanner, EmpireParamClosure::context_t> EmpireParamRule; - typedef rule<Scanner, NameParamClosure::context_t> NameParamRule; - typedef rule<Scanner, SetStarTypeClosure::context_t> SetStarTypeRule; - typedef rule<Scanner, SetTechAvailabilityClosure::context_t> SetTechAvailabilityRule; + typedef rule<Scanner, SetMeterClosure::context_t> SetMeterRule; + typedef rule<Scanner, SetOwnerStockpileClosure::context_t> SetOwnerStockpileRule; + typedef rule<Scanner, SetPlanetTypeClosure::context_t> SetPlanetTypeRule; + typedef rule<Scanner, SetPlanetSizeClosure::context_t> SetPlanetSizeRule; + typedef rule<Scanner, EmpireParamClosure::context_t> EmpireParamRule; + typedef rule<Scanner, ObjectIDParamClosure::context_t> ObjectIDParamRule; + typedef rule<Scanner, NameParamClosure::context_t> NameParamRule; + typedef rule<Scanner, SetStarTypeClosure::context_t> SetStarTypeRule; + typedef rule<Scanner, SetTechAvailabilityClosure::context_t> SetTechAvailabilityRule; - SetMeterRule set_meter; - SetOwnerStockpileRule set_owner_stockpile; - SetPlanetTypeRule set_planet_type; - SetPlanetSizeRule set_planet_size; - EmpireParamRule add_owner; - EmpireParamRule remove_owner; - Rule destroy; - NameParamRule add_special; - NameParamRule remove_special; - SetStarTypeRule set_star_type; + SetMeterRule set_meter; + SetOwnerStockpileRule set_owner_stockpile; + SetPlanetTypeRule set_planet_type; + SetPlanetSizeRule set_planet_size; + EmpireParamRule add_owner; + EmpireParamRule remove_owner; + ObjectIDParamRule move_to; + Rule destroy; + NameParamRule add_special; + NameParamRule remove_special; + SetStarTypeRule set_star_type; SetTechAvailabilityRule set_tech_availability; - ParamLabel value_label; - ParamLabel type_label; - ParamLabel planetsize_label; - ParamLabel empire_label; - ParamLabel name_label; + ParamLabel value_label; + ParamLabel type_label; + ParamLabel planetsize_label; + ParamLabel empire_label; + ParamLabel name_label; + ParamLabel object_id_label; }; EffectParserDefinition::EffectParserDefinition() : @@ -105,7 +114,8 @@ type_label("type"), planetsize_label("size"), empire_label("empire"), - name_label("name") + name_label("name"), + object_id_label("objectid") { set_meter = ((str_p("setmax")[set_meter.max_meter = val(true)] @@ -154,6 +164,11 @@ >> empire_label >> int_expr_p[remove_owner.empire = arg1]) [remove_owner.this_ = new_<Effect::RemoveOwner>(remove_owner.empire)]; + move_to = + (str_p("moveto") + >> object_id_label >> int_expr_p[move_to.object_id = arg1]) + [move_to.this_ = new_<Effect::MoveTo>(move_to.object_id)]; + destroy = str_p("destroy") [destroy.this_ = new_<Effect::Destroy>()]; @@ -188,6 +203,7 @@ | set_planet_size[effect_p.this_ = arg1] | add_owner[effect_p.this_ = arg1] | remove_owner[effect_p.this_ = arg1] + | move_to[effect_p.this_ = arg1] | destroy[effect_p.this_ = arg1] | add_special[effect_p.this_ = arg1] | remove_special[effect_p.this_ = arg1] Modified: trunk/FreeOrion/universe/System.cpp =================================================================== --- trunk/FreeOrion/universe/System.cpp 2008-08-05 03:00:46 UTC (rev 2650) +++ trunk/FreeOrion/universe/System.cpp 2008-08-05 08:07:51 UTC (rev 2651) @@ -475,6 +475,23 @@ return m_objects.equal_range(-1); } +bool System::OrbitOccupied(int orbit) const +{ + return (m_objects.find(orbit) != m_objects.end()); +} + +std::set<int> System::FreeOrbits() const +{ + std::set<int> occupied; + for (const_orbit_iterator it = begin(); it != end(); ++it) + occupied.insert(it->first); + std::set<int> retval; + for (int i = 0; i < m_orbits; ++i) + if (occupied.find(i) == occupied.end()) + retval.insert(i); + return retval; +} + System::lane_iterator System::begin_lanes() { return m_starlanes_wormholes.begin(); Modified: trunk/FreeOrion/universe/System.h =================================================================== --- trunk/FreeOrion/universe/System.h 2008-08-05 03:00:46 UTC (rev 2650) +++ trunk/FreeOrion/universe/System.h 2008-08-05 08:07:51 UTC (rev 2651) @@ -99,6 +99,9 @@ std::pair<const_orbit_iterator, const_orbit_iterator> non_orbit_range() const; ///< returns begin and end iterators for all system objects not in an orbit + bool OrbitOccupied(int orbit) const; ///< returns true if there is an object in \a orbit + std::set<int> FreeOrbits() const; ///< returns the set of orbit numbers that are unoccupied + const_lane_iterator begin_lanes() const; ///< begin iterator for all starlanes and wormholes terminating in this system const_lane_iterator end_lanes() const; ///< end iterator for all starlanes and wormholes terminating in this system |