From: <tz...@us...> - 2009-03-29 02:15:43
|
Revision: 2951 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=2951&view=rev Author: tzlaine Date: 2009-03-29 02:15:33 +0000 (Sun, 29 Mar 2009) Log Message: ----------- - Remediated lack of consideration for PD ships (which are handled very differently) in the ShipMission::DEFEND_THIS mission. - Removed INTERCEPTOR-only policy for attacking fighters in CombatFighter::WeakestAttacker(), in favor of any-fighter-that-can-attack- fighters policy. Modified Paths: -------------- trunk/FreeOrion/combat/OpenSteer/CombatFighter.cpp trunk/FreeOrion/combat/OpenSteer/CombatShip.cpp trunk/FreeOrion/combat/OpenSteer/CombatShip.h Modified: trunk/FreeOrion/combat/OpenSteer/CombatFighter.cpp =================================================================== --- trunk/FreeOrion/combat/OpenSteer/CombatFighter.cpp 2009-03-29 01:23:59 UTC (rev 2950) +++ trunk/FreeOrion/combat/OpenSteer/CombatFighter.cpp 2009-03-29 02:15:33 UTC (rev 2951) @@ -816,9 +816,7 @@ CombatFighterPtr fighter; CombatShipPtr ship; float strength = FLT_MAX; - // Note that this condition (type == INTERCEPTOR) implies that bombers - // cannot attack fighters at all. - if (m_stats.m_type == INTERCEPTOR && + if (m_stats.m_anti_fighter_damage && (fighter = boost::dynamic_pointer_cast<CombatFighter>(it->second.lock()))) { strength = fighter->HealthAndShield() * (1.0 + fighter->AntiFighterStrength()); } else if (ship = boost::dynamic_pointer_cast<CombatShip>(it->second.lock())) { Modified: trunk/FreeOrion/combat/OpenSteer/CombatShip.cpp =================================================================== --- trunk/FreeOrion/combat/OpenSteer/CombatShip.cpp 2009-03-29 01:23:59 UTC (rev 2950) +++ trunk/FreeOrion/combat/OpenSteer/CombatShip.cpp 2009-03-29 02:15:33 UTC (rev 2951) @@ -54,7 +54,8 @@ m_pathing_engine(0), m_raw_PD_strength(0.0), m_raw_SR_strength(0.0), - m_raw_LR_strength(0.0) + m_raw_LR_strength(0.0), + m_is_PD_ship(false) ,m_instrument(false) ,m_last_mission(ShipMission::NONE) {} @@ -69,7 +70,8 @@ m_pathing_engine(&pathing_engine), m_raw_PD_strength(0.0), m_raw_SR_strength(0.0), - m_raw_LR_strength(0.0) + m_raw_LR_strength(0.0), + m_is_PD_ship(false) ,m_instrument(false) ,m_last_mission(ShipMission::NONE) { Init(position, direction); } @@ -285,6 +287,7 @@ } } + double PD_minus_non_PD = 0.0; const std::vector<std::string>& part_names = m_ship->Design()->Parts(); for (std::size_t i = 0; i < part_names.size(); ++i) { if (part_names[i].empty()) @@ -295,14 +298,18 @@ if (part->Class() == PC_POINT_DEFENSE) { const DirectFireStats& stats = boost::get<DirectFireStats>(part->Stats()); m_raw_PD_strength += stats.m_damage * stats.m_ROF * stats.m_range; + PD_minus_non_PD += stats.m_damage; } else if (part->Class() == PC_SHORT_RANGE) { const DirectFireStats& stats = boost::get<DirectFireStats>(part->Stats()); m_raw_SR_strength += stats.m_damage * stats.m_ROF * stats.m_range; + PD_minus_non_PD -= stats.m_damage; } else if (part->Class() == PC_MISSILES) { const LRStats& stats = boost::get<LRStats>(part->Stats()); m_raw_LR_strength += stats.m_damage * stats.m_ROF * stats.m_range; + PD_minus_non_PD -= stats.m_damage; } } + m_is_PD_ship = 0.0 < PD_minus_non_PD; } void CombatShip::PushMission(const ShipMission& mission) @@ -393,12 +400,46 @@ case ShipMission::DEFEND_THIS: { if (CombatObjectPtr target = m_mission_queue.back().m_target.lock()) { m_mission_weight = DEFAULT_MISSION_WEIGHT; - if (m_mission_subtarget.expired()) { - m_mission_subtarget = WeakestAttacker(target); - if (CombatObjectPtr subtarget = m_mission_subtarget.lock()) - m_mission_destination = subtarget->position(); - else - m_mission_destination = target->position(); + if (m_is_PD_ship) { + PathingEngine::ConstAttackerRange attackers = + m_pathing_engine->Attackers(target); + CombatShipPtr ship; + for (PathingEngine::Attackees::const_iterator it = attackers.first; + it != attackers.second; + ++it) { + if (CombatShipPtr tmp = + boost::dynamic_pointer_cast<CombatShip>(it->second.lock())) { + if (!ship || ship->m_raw_LR_strength < tmp->m_raw_LR_strength) + ship = tmp; + } + } + if (ship) { + m_mission_weight = MAX_MISSION_WEIGHT; + OpenSteer::Vec3 target_position = target->position(); + OpenSteer::Vec3 attacker_position = ship->position(); + OpenSteer::Vec3 target_to_attacker = + (attacker_position - target_position).normalize(); + double min_PD_range = m_ship->Design()->PDWeapons().begin()->first; + m_mission_destination = + target_position + target_to_attacker * min_PD_range / 2.0; + } else { + // No attacker found; just get close to the target to keep + // it blanketted with PD. + OpenSteer::Vec3 target_position = target->position(); + OpenSteer::Vec3 target_to_here = + (position() - target->position()).normalize(); + double min_PD_range = m_ship->Design()->PDWeapons().begin()->first; + m_mission_destination = + target_position + target_to_here * min_PD_range / 3.0; + } + } else { + if (m_mission_subtarget.expired()) { + m_mission_subtarget = WeakestAttacker(target); + if (CombatObjectPtr subtarget = m_mission_subtarget.lock()) + m_mission_destination = subtarget->position(); + else + m_mission_destination = target->position(); + } } } else { if (print_needed) std::cout << " [DEFEND TARGET GONE]\n"; @@ -497,9 +538,17 @@ void CombatShip::FireAtHostiles() { + assert(!m_mission_queue.empty()); + +#if 0 //const ShipDesign& design = *m_ship->Design(); - // TODO: Don't forget to take into account the ineffectiveness of PD - // against ships, and non-PD against fighters. + const double PD_VS_SHIP_FACTOR = 1.0 / 50.0; + const double NON_PD_VS_FIGHTER_FACTOR = 1.0 / 50.0; + + CombatObjectPtr target = m_mission_subtarget.lock(); + if () { + } +#endif } OpenSteer::Vec3 CombatShip::Steer() Modified: trunk/FreeOrion/combat/OpenSteer/CombatShip.h =================================================================== --- trunk/FreeOrion/combat/OpenSteer/CombatShip.h 2009-03-29 01:23:59 UTC (rev 2950) +++ trunk/FreeOrion/combat/OpenSteer/CombatShip.h 2009-03-29 02:15:33 UTC (rev 2951) @@ -75,6 +75,7 @@ double m_raw_PD_strength; double m_raw_SR_strength; double m_raw_LR_strength; + bool m_is_PD_ship; // map from part type name to (number of parts in the design of that type, // the unlaunched fighters of that part type) pairs |