2006-04-24 01:14:18 +02:00
|
|
|
#include "precompiled.h"
|
2006-06-09 20:32:00 +02:00
|
|
|
|
2006-04-24 01:14:18 +02:00
|
|
|
#include "Aura.h"
|
2006-06-09 20:32:00 +02:00
|
|
|
|
2006-04-24 01:14:18 +02:00
|
|
|
#include "EntityManager.h"
|
2006-06-09 20:32:00 +02:00
|
|
|
#include "Entity.h"
|
2006-04-24 01:14:18 +02:00
|
|
|
|
2006-06-09 20:32:00 +02:00
|
|
|
#include <algorithm>
|
2006-04-24 01:14:18 +02:00
|
|
|
|
2006-08-25 08:04:33 +02:00
|
|
|
CAura::CAura( JSContext* cx, CEntity* source, CStrW& name, float radius, size_t tickRate, const CVector4D& color, JSObject* handler )
|
2006-05-16 06:41:37 +02:00
|
|
|
: m_cx(cx), m_source(source), m_name(name), m_radius(radius), m_handler(handler),
|
2006-08-25 08:04:33 +02:00
|
|
|
m_tickRate(tickRate), m_tickCyclePos(0), m_color(color)
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
|
|
|
JS_AddRoot( m_cx, &m_handler ); // don't GC it so we can call it later
|
|
|
|
}
|
|
|
|
|
|
|
|
CAura::~CAura()
|
|
|
|
{
|
|
|
|
JS_RemoveRoot( m_cx, &m_handler );
|
|
|
|
}
|
|
|
|
|
2006-05-16 06:41:37 +02:00
|
|
|
void CAura::Update( size_t timestep )
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
2006-06-09 20:32:00 +02:00
|
|
|
std::vector<CEntity*> inRange;
|
2006-04-24 01:14:18 +02:00
|
|
|
CVector3D pos = m_source->m_position;
|
|
|
|
g_EntityManager.GetInRange( pos.X, pos.Z, m_radius, inRange );
|
|
|
|
|
2006-06-09 20:32:00 +02:00
|
|
|
std::vector<CEntity*> prevInfluenced, curInfluenced, entered, exited;
|
2006-04-24 01:14:18 +02:00
|
|
|
|
2007-01-21 04:33:52 +01:00
|
|
|
prevInfluenced.reserve(m_influenced.size());
|
|
|
|
curInfluenced.reserve(m_influenced.size());
|
|
|
|
|
2006-06-09 20:32:00 +02:00
|
|
|
for( std::vector<HEntity>::iterator it = m_influenced.begin(); it != m_influenced.end(); it++ )
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
|
|
|
CEntity* ent = *it;
|
2008-02-04 09:24:17 +01:00
|
|
|
if( ent && ent->m_extant )
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
|
|
|
prevInfluenced.push_back(ent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
m_influenced.clear();
|
|
|
|
|
2006-06-09 20:32:00 +02:00
|
|
|
for( std::vector<CEntity*>::iterator it = inRange.begin(); it != inRange.end(); it++ )
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
|
|
|
CEntity* ent = *it;
|
|
|
|
if(ent != m_source)
|
|
|
|
{
|
|
|
|
curInfluenced.push_back(ent);
|
|
|
|
m_influenced.push_back( HEntity(ent->me) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sort( prevInfluenced.begin(), prevInfluenced.end() );
|
|
|
|
sort( curInfluenced.begin(), curInfluenced.end() );
|
|
|
|
|
|
|
|
jsval rval;
|
|
|
|
jsval argv[1];
|
|
|
|
|
2006-05-16 06:41:37 +02:00
|
|
|
// Call onEnter on any new unit that has entered the aura
|
2006-04-24 01:14:18 +02:00
|
|
|
jsval enterFunction;
|
2007-01-24 21:17:28 +01:00
|
|
|
if( JS_GetProperty( m_cx, m_handler, "onEnter", &enterFunction )
|
2006-05-16 06:41:37 +02:00
|
|
|
&& enterFunction != JSVAL_VOID)
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
2006-06-09 20:32:00 +02:00
|
|
|
std::back_insert_iterator<std::vector<CEntity*> > ins( entered );
|
2006-04-24 01:14:18 +02:00
|
|
|
set_difference( curInfluenced.begin(), curInfluenced.end(),
|
|
|
|
prevInfluenced.begin(), prevInfluenced.end(),
|
|
|
|
ins );
|
2006-06-09 20:32:00 +02:00
|
|
|
for( std::vector<CEntity*>::iterator it = entered.begin(); it != entered.end(); it++ )
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
|
|
|
argv[0] = OBJECT_TO_JSVAL( (*it)->GetScript() );
|
|
|
|
JS_CallFunctionValue( m_cx, m_handler, enterFunction, 1, argv, &rval );
|
|
|
|
(*it)->m_aurasInfluencingMe.insert( this );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-05-16 06:41:37 +02:00
|
|
|
// Call onExit on any unit that has exited the aura
|
2006-04-24 01:14:18 +02:00
|
|
|
jsval exitFunction;
|
2007-01-24 21:17:28 +01:00
|
|
|
if( JS_GetProperty( m_cx, m_handler, "onExit", &exitFunction )
|
2006-05-16 06:41:37 +02:00
|
|
|
&& exitFunction != JSVAL_VOID )
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
2006-06-09 20:32:00 +02:00
|
|
|
std::back_insert_iterator<std::vector<CEntity*> > ins( exited );
|
2006-04-24 01:14:18 +02:00
|
|
|
set_difference( prevInfluenced.begin(), prevInfluenced.end(),
|
|
|
|
curInfluenced.begin(), curInfluenced.end(),
|
|
|
|
ins );
|
2006-06-09 20:32:00 +02:00
|
|
|
for( std::vector<CEntity*>::iterator it = exited.begin(); it != exited.end(); it++ )
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
|
|
|
argv[0] = OBJECT_TO_JSVAL( (*it)->GetScript() );
|
|
|
|
JS_CallFunctionValue( m_cx, m_handler, exitFunction, 1, argv, &rval );
|
|
|
|
(*it)->m_aurasInfluencingMe.erase( this );
|
|
|
|
}
|
|
|
|
}
|
2006-05-16 06:41:37 +02:00
|
|
|
|
|
|
|
m_tickCyclePos += timestep;
|
|
|
|
|
|
|
|
if( m_tickRate > 0 && m_tickCyclePos > m_tickRate )
|
|
|
|
{
|
|
|
|
// It's time to tick; call OnTick on any unit that is in the aura
|
|
|
|
jsval tickFunction;
|
2007-01-24 21:17:28 +01:00
|
|
|
if( JS_GetProperty( m_cx, m_handler, "onTick", &tickFunction )
|
2006-05-16 06:41:37 +02:00
|
|
|
&& tickFunction != JSVAL_VOID )
|
|
|
|
{
|
2006-06-09 20:32:00 +02:00
|
|
|
for( std::vector<CEntity*>::iterator it = curInfluenced.begin(); it != curInfluenced.end(); it++ )
|
2006-05-16 06:41:37 +02:00
|
|
|
{
|
|
|
|
argv[0] = OBJECT_TO_JSVAL( (*it)->GetScript() );
|
|
|
|
JS_CallFunctionValue( m_cx, m_handler, tickFunction, 1, argv, &rval );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reset cycle pos
|
|
|
|
m_tickCyclePos %= m_tickRate;
|
|
|
|
}
|
2006-04-24 01:14:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void CAura::RemoveAll()
|
|
|
|
{
|
|
|
|
jsval rval;
|
|
|
|
jsval argv[1];
|
|
|
|
jsval exitFunction;
|
2007-01-24 21:17:28 +01:00
|
|
|
if( JS_GetProperty( m_cx, m_handler, "onExit", &exitFunction )
|
2006-05-16 06:41:37 +02:00
|
|
|
&& exitFunction != JSVAL_VOID )
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
2006-05-16 06:41:37 +02:00
|
|
|
// Call the exit function on everything in our influence
|
2006-06-09 20:32:00 +02:00
|
|
|
for( std::vector<HEntity>::iterator it = m_influenced.begin(); it != m_influenced.end(); it++ )
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
|
|
|
CEntity* ent = *it;
|
2008-02-04 09:24:17 +01:00
|
|
|
if( ent && ent->m_extant )
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
|
|
|
argv[0] = OBJECT_TO_JSVAL( ent->GetScript() );
|
|
|
|
JS_CallFunctionValue( m_cx, m_handler, exitFunction, 1, argv, &rval );
|
|
|
|
(*it)->m_aurasInfluencingMe.erase( this );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m_influenced.clear();
|
|
|
|
}
|
|
|
|
|
2007-01-25 08:00:31 +01:00
|
|
|
// Remove an entity from the aura, but does not remove the aura from its
|
|
|
|
// m_aurasInfluencingMe. (Used when the entity is asking to be removed from
|
|
|
|
// the aura and will clear its own m_aurasInfluencingMe list afterwards).
|
2006-04-24 01:14:18 +02:00
|
|
|
void CAura::Remove( CEntity* ent )
|
|
|
|
{
|
|
|
|
jsval rval;
|
|
|
|
jsval argv[1];
|
|
|
|
jsval exitFunction;
|
2007-01-24 21:17:28 +01:00
|
|
|
if( JS_GetProperty( m_cx, m_handler, "onExit", &exitFunction )
|
2006-05-16 06:41:37 +02:00
|
|
|
&& exitFunction != JSVAL_VOID )
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
2006-05-16 06:41:37 +02:00
|
|
|
// Call the exit function on it
|
2006-04-24 01:14:18 +02:00
|
|
|
argv[0] = OBJECT_TO_JSVAL( ent->GetScript() );
|
|
|
|
JS_CallFunctionValue( m_cx, m_handler, exitFunction, 1, argv, &rval );
|
2006-05-16 06:41:37 +02:00
|
|
|
|
|
|
|
// Remove it from the m_influenced array
|
2006-04-24 01:14:18 +02:00
|
|
|
for( size_t i=0; i < m_influenced.size(); i++ )
|
|
|
|
{
|
|
|
|
if( ((CEntity*) m_influenced[i]) == ent )
|
|
|
|
{
|
|
|
|
m_influenced.erase( m_influenced.begin() + i );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|