forked from 0ad/0ad
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:
parent
75a9b2f357
commit
d0c6805725
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 );
|
||||
|
@ -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 );
|
||||
|
Loading…
Reference in New Issue
Block a user