Fixed bug that was causing population to go negative. It was due to a unit being killed by multiple enemies in the same frame, which led to multiple calls of the death event handler. The fix is twofold: First, kill() only calls the event handler the first time the unit is killed. Second, damage() (in JS), which apart from killing things also loots them, makes sure that the unit is not already being destroyed. This latter fix is to ensure that we don't get a huge amount of loot by simply attacking a low-HP unit with many soldiers simultaneously, so they kill it in the same frame.

This was SVN commit r6276.
This commit is contained in:
Matei 2008-07-24 05:50:45 +00:00
parent 75a9b2f357
commit d0c6805725
4 changed files with 13 additions and 4 deletions

View File

@ -862,6 +862,9 @@ function damage( dmg, inflictor )
var arm = this.traits.armour;
if( !arm ) return; // corpses have no armour, everything else should
// Unit has already been destroyed this frame, don't loot for everything hitting it
if( this.isDestroyed() ) return;
// Use traits.health.max = 0 to signify immortal things like settlements
if( this.traits.health.max == 0 ) return;

View File

@ -247,6 +247,10 @@ void CEntity::Kill(bool keepActor)
{
return; // We were already killed this frame
}
entf_set(ENTF_DESTROYED);
CEventDeath evt;
DispatchEvent( &evt );
g_FormationManager.RemoveUnit(this);
@ -279,7 +283,6 @@ void CEntity::Kill(bool keepActor)
g_Selection.RemoveAll( me );
entf_set(ENTF_DESTROYED);
g_EntityManager.m_refd[me.m_handle] = false; // refd must be made false when DESTROYED is set
g_EntityManager.SetDeath(true); // remember that a unit died this frame

View File

@ -468,6 +468,11 @@ public:
return( m_orderQueue.empty() );
}
bool IsDestroyed( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) )
{
return( entf_get(ENTF_DESTROYED) );
}
bool HasClass( JSContext* cx, uintN argc, jsval* argv )
{
debug_assert( argc >= 1 );

View File

@ -57,6 +57,7 @@ void CEntity::ScriptingInit()
AddMethod<jsval_t, &CEntity::TerminateOrder>( "terminateOrder", 1 );
AddMethod<bool, &CEntity::Kill>( "kill", 0 );
AddMethod<bool, &CEntity::IsIdle>( "isIdle", 0 );
AddMethod<bool, &CEntity::IsDestroyed>( "isDestroyed", 0 );
AddMethod<bool, &CEntity::HasClass>( "hasClass", 1 );
AddMethod<jsval_t, &CEntity::GetSpawnPoint>( "getSpawnPoint", 1 );
AddMethod<jsval_t, &CEntity::AddAura>( "addAura", 3 );
@ -364,9 +365,6 @@ bool CEntity::Order( JSContext* cx, uintN argc, jsval* argv, CEntityOrder::EOrde
bool CEntity::Kill( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) )
{
CEventDeath evt;
DispatchEvent( &evt );
Kill(true);
return( true );