From: <geo...@us...> - 2010-05-29 18:59:44
|
Revision: 3613 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=3613&view=rev Author: geoffthemedio Date: 2010-05-29 18:59:38 +0000 (Sat, 29 May 2010) Log Message: ----------- Added safety checks to SetShipPartMeter::Execute in Effect.cpp to prevent a crash, although there still seem to be some issues since some parts aren't being gotten when they seemingly should be. Modified Paths: -------------- trunk/FreeOrion/universe/Effect.cpp Modified: trunk/FreeOrion/universe/Effect.cpp =================================================================== --- trunk/FreeOrion/universe/Effect.cpp 2010-05-29 17:50:55 UTC (rev 3612) +++ trunk/FreeOrion/universe/Effect.cpp 2010-05-29 18:59:38 UTC (rev 3613) @@ -549,16 +549,35 @@ void SetShipPartMeter::Execute(const UniverseObject* source, UniverseObject* target) const { - if (Ship* ship = universe_object_cast<Ship*>(target)) { - for (std::size_t i = 0; i < ship->Design()->Parts().size(); ++i) { - if (Meter* meter = ship->GetMeter(m_meter, m_part_name)) { - const PartType* part = GetPartType(ship->Design()->Parts()[i]); - if (PartMatchesEffect(*part, m_part_class, m_fighter_type, m_part_name, m_slot_type)) { - double val = m_value->Eval(source, target, meter->Current()); - meter->SetCurrent(val); - } - } + if (!target) { + Logger().debugStream() << "SetShipPartMeter::Execute passed null target pointer"; + return; + } + + Ship* ship = universe_object_cast<Ship*>(target); + if (!ship) { + Logger().errorStream() << "SetShipPartMeter::Execute acting on non-ship target:"; + target->Dump(); + return; + } + + for (std::size_t i = 0; i < ship->Design()->Parts().size(); ++i) { + Meter* meter = ship->GetMeter(m_meter, m_part_name); + if (!meter) + continue; + + const PartType* part = GetPartType(ship->Design()->Parts()[i]); + if (!part) { + Logger().errorStream() << "SetShipPartMeter::Execute acting on target:"; + ship->Dump(); + Logger().errorStream() << "Couldn't get part type: " << m_part_name; + return; } + + if (PartMatchesEffect(*part, m_part_class, m_fighter_type, m_part_name, m_slot_type)) { + double val = m_value->Eval(source, target, meter->Current()); + meter->SetCurrent(val); + } } } |