Fixed up running and notifications.
This was SVN commit r3341.
This commit is contained in:
parent
8f7202f00b
commit
19b33141c1
@ -100,6 +100,8 @@ CEntity::CEntity( CBaseEntity* base, CVector3D position, float orientation )
|
||||
|
||||
m_selected = false;
|
||||
|
||||
m_isRunning = false;
|
||||
|
||||
m_grouped = -1;
|
||||
|
||||
m_player = g_Game->GetPlayer( 0 );
|
||||
@ -408,7 +410,6 @@ void CEntity::update( size_t timestep )
|
||||
updateCollisionPatch();
|
||||
return;
|
||||
case CEntityOrder::ORDER_GOTO:
|
||||
case CEntityOrder::ORDER_RUN:
|
||||
if( processGoto( current, timestep ) )
|
||||
break;
|
||||
updateCollisionPatch();
|
||||
@ -648,35 +649,82 @@ bool CEntity::acceptsOrder( int orderType, CEntity* orderTarget )
|
||||
|
||||
jsval CEntity::RequestNotification( JSContext* cx, uintN argc, jsval* argv )
|
||||
{
|
||||
debug_assert( argc >= 3 );
|
||||
debug_assert( argc > 3 );
|
||||
CEntityListener notify;
|
||||
|
||||
notify.m_sender = this;
|
||||
//(Convert from int to enum)
|
||||
CEntity* target = ToPrimitive<CEntity*>( argv[0] );
|
||||
CEntity *target = ToNative<CEntity>( argv[0] );
|
||||
*( (uint*) &(notify.m_type) ) = ToPrimitive<int>( argv[1] );
|
||||
|
||||
if ( ToPrimitive<bool>( argv[2] ) )
|
||||
bool destroy = ToPrimitive<bool>( argv[2] );
|
||||
|
||||
std::deque<CEntityListener>::iterator it = target->m_listeners.begin();
|
||||
for ( ; it != target->m_listeners.end(); it++)
|
||||
{
|
||||
std::deque<CEntityListener>::iterator it = target->m_listeners.begin();
|
||||
for ( ; it != target->m_listeners.end(); it++)
|
||||
{
|
||||
if ( it->m_sender == this )
|
||||
target->m_listeners.erase(it);
|
||||
}
|
||||
if ( destroy && it->m_sender == this )
|
||||
target->m_listeners.erase(it);
|
||||
}
|
||||
|
||||
target->m_listeners.push_back( notify );
|
||||
return JSVAL_VOID;
|
||||
}
|
||||
jsval CEntity::CheckListeners( JSContext *cx, uintN argc, jsval* argv )
|
||||
void CEntity::DispatchNotification( CEntityOrder order, uint type )
|
||||
{
|
||||
debug_assert( argc >= 1);
|
||||
|
||||
int type = ToPrimitive<int>( argv[0] );
|
||||
for (int i=0; i<m_listeners.size(); i++)
|
||||
CEventNotification evt( order, type );
|
||||
DispatchEvent( &evt );
|
||||
}
|
||||
|
||||
jsval CEntity::CheckListeners( JSContext *cx, uintN argc, jsval* argv )
|
||||
{
|
||||
if( argc < 1 )
|
||||
{
|
||||
JS_ReportError( cx, "Too few parameters" );
|
||||
return( false );
|
||||
}
|
||||
int type = ToPrimitive<int>( argv[0] ); //notify code
|
||||
CEntityOrder order = this->m_orderQueue.front();
|
||||
CEntity* target;
|
||||
|
||||
for (int i=0; i<m_listeners.size(); i++)
|
||||
|
||||
if (m_listeners[i].m_type & type)
|
||||
m_listeners[i].m_sender->pushOrder( this->m_orderQueue.front() );
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case CEntityListener::NOTIFY_GOTO:
|
||||
m_listeners[i].m_sender->DispatchNotification( order, type );
|
||||
break;
|
||||
|
||||
case CEntityListener::NOTIFY_HEAL:
|
||||
case CEntityListener::NOTIFY_ATTACK:
|
||||
case CEntityListener::NOTIFY_GATHER:
|
||||
if( argc < 3 )
|
||||
{
|
||||
JS_ReportError( cx, "Too few parameters" );
|
||||
continue;
|
||||
}
|
||||
target = ToNative<CEntity>( argv[1] );
|
||||
order.m_data[1].data = ToPrimitive<int>( argv[2] ); //which action
|
||||
order.m_data[0].entity = target->me;
|
||||
|
||||
m_listeners[i].m_sender->DispatchNotification( order, type );
|
||||
break;
|
||||
case CEntityListener::NOTIFY_DAMAGE:
|
||||
if( argc < 2 )
|
||||
{
|
||||
JS_ReportError( cx, "Too few parameters" );
|
||||
continue;
|
||||
}
|
||||
target = ToNative<CEntity>( argv[1] );
|
||||
order.m_data[0].entity = target->me;
|
||||
|
||||
m_listeners[i].m_sender->DispatchNotification( order, type );
|
||||
|
||||
default:
|
||||
JS_ReportError( cx, "Invalid order type" );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return JSVAL_VOID;
|
||||
}
|
||||
|
@ -91,6 +91,8 @@ public:
|
||||
// If this unit is still active in the gameworld - i.e. not a corpse.
|
||||
bool m_extant;
|
||||
|
||||
bool m_isRunning;
|
||||
|
||||
// HP properties
|
||||
float m_healthCurr;
|
||||
float m_healthMax;
|
||||
@ -256,6 +258,7 @@ public:
|
||||
void pushOrder( CEntityOrder& order );
|
||||
|
||||
jsval RequestNotification( JSContext* cx, uintN argc, jsval* argv );
|
||||
void DispatchNotification( CEntityOrder order,uint type );
|
||||
jsval CheckListeners( JSContext* cx, uintN argc, jsval* argv );
|
||||
|
||||
// Script constructor
|
||||
|
@ -53,10 +53,13 @@ public:
|
||||
enum
|
||||
{
|
||||
NOTIFY_GOTO = 0x01,
|
||||
NOTIFY_RUN = 0x02,
|
||||
NOTIFY_FOLLOW = 0x03, //GOTO | RUN
|
||||
//NOTIFY_ = 0x02, reservered for possible second goto like command
|
||||
//NOTIFY_FOLLOW = 0x03, //GOTO | RUN
|
||||
|
||||
NOTIFY_ATTACK = 0x04,
|
||||
NOTIFY_DAMAGE = 0x08,
|
||||
NOTIFY_COMBAT = 0x0C, //ATTACK | DAMAGE
|
||||
|
||||
NOTIFY_ESCORT = 0x0D, //GOTO | ATTACK | DAMAGE
|
||||
NOTIFY_HEAL = 0x10,
|
||||
NOTIFY_GATHER = 0x20
|
||||
|
@ -46,7 +46,11 @@ uint CEntity::processGotoHelper( CEntityOrder* current, size_t timestep_millis,
|
||||
// Curve smoothing.
|
||||
// Here there be trig.
|
||||
|
||||
float scale = ( m_run.m_Speed > 0 ? m_run.m_Speed : m_speed ) * timestep;
|
||||
float scale;
|
||||
if ( m_run.m_Speed > 0 && len < m_run.m_MaxRange && ( m_isRunning || len > m_run.m_MinRange ) )
|
||||
scale = m_run.m_Speed * timestep;
|
||||
else
|
||||
scale = m_speed * timestep;
|
||||
|
||||
// Note: Easy optimization: flag somewhere that this unit
|
||||
// is already pointing the right way, and don't do this
|
||||
@ -290,18 +294,17 @@ bool CEntity::processContactAction( CEntityOrder* current, size_t UNUSED(timeste
|
||||
|
||||
if( m_transition && m_actor )
|
||||
{
|
||||
if (m_run.m_Speed > 0 )
|
||||
{
|
||||
if ( Distance > m_run.m_MinRange && Distance < m_run.m_MaxRange )
|
||||
{
|
||||
CSkeletonAnim* run = m_actor->GetRandomAnimation( "run" );
|
||||
m_actor->GetModel()->SetAnimation( run, false, m_run.m_Speed * run->m_AnimDef->GetDuration() );
|
||||
}
|
||||
if ( m_run.m_Speed > 0 && Distance < m_run.m_MaxRange && ( Distance > m_run.m_MinRange || m_isRunning ) )
|
||||
{
|
||||
CSkeletonAnim* run = m_actor->GetRandomAnimation( "run" );
|
||||
m_actor->GetModel()->SetAnimation( run, false, m_run.m_Speed * run->m_AnimDef->GetDuration() );
|
||||
m_isRunning = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
CSkeletonAnim* walk = m_actor->GetRandomAnimation( "walk" );
|
||||
m_actor->GetModel()->SetAnimation( walk, false, m_speed * walk->m_AnimDef->GetDuration() );
|
||||
m_isRunning = false;
|
||||
}
|
||||
// Animation desync
|
||||
m_actor->GetModel()->Update( ( rand() * 1000.0f ) / 1000.0f );
|
||||
@ -391,35 +394,30 @@ bool CEntity::processContactActionNoPathing( CEntityOrder* current, size_t times
|
||||
// We're aiming to end up at a location just inside our maximum range
|
||||
// (is this good enough?)
|
||||
delta = delta.normalize() * ( adjRange - m_bounds->m_radius );
|
||||
float deltaLength = delta.length();
|
||||
|
||||
//Determine whether to run or to walk
|
||||
if ( m_run.m_Speed > 0 )
|
||||
if ( m_actor )
|
||||
{
|
||||
float deltaLength = delta.length();
|
||||
if ( m_actor && ! m_actor->IsPlayingAnimation( "run" ) )
|
||||
//Can we run, are we in range, and are we already running?
|
||||
if ( m_run.m_Speed > 0 && deltaLength < m_run.m_MaxRange && ( deltaLength > m_run.m_MinRange ||
|
||||
m_isRunning ) && !m_actor->IsPlayingAnimation( "run ") )
|
||||
{
|
||||
//Are we in range?
|
||||
if ( deltaLength < m_run.m_MaxRange && deltaLength > m_run.m_MinRange )
|
||||
{
|
||||
CSkeletonAnim* run = m_actor->GetRandomAnimation( "run" );
|
||||
m_actor->GetModel()->SetAnimation( run, false, m_run.m_Speed * run->m_AnimDef->GetDuration() );
|
||||
// Animation desync
|
||||
m_actor->GetModel()->Update( ( rand() * 1000.0f ) / 1000.0f );
|
||||
}
|
||||
CSkeletonAnim* run = m_actor->GetRandomAnimation( "run" );
|
||||
m_actor->GetModel()->SetAnimation( run, false, m_run.m_Speed * run->m_AnimDef->GetDuration() );
|
||||
m_isRunning = true;
|
||||
}
|
||||
|
||||
// Play walk for a bit.
|
||||
else if( !m_actor->IsPlayingAnimation( "walk" ) )
|
||||
{
|
||||
CSkeletonAnim* walk = m_actor->GetRandomAnimation( "walk" );
|
||||
m_actor->GetModel()->SetAnimation( walk, false, m_speed * walk->m_AnimDef->GetDuration() );
|
||||
// Animation desync
|
||||
m_actor->GetModel()->Update( ( rand() * 1000.0f ) / 1000.0f );
|
||||
m_isRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Play walk for a bit.
|
||||
else if( m_actor && ! m_actor->IsPlayingAnimation( "walk" ) )
|
||||
{
|
||||
CSkeletonAnim* walk = m_actor->GetRandomAnimation( "walk" );
|
||||
m_actor->GetModel()->SetAnimation( walk, false, m_speed * walk->m_AnimDef->GetDuration() );
|
||||
// Animation desync
|
||||
m_actor->GetModel()->Update( ( rand() * 1000.0f ) / 1000.0f );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
current->m_data[0].location = (CVector2D)current->m_data[0].entity->m_position - delta;
|
||||
|
||||
HEntity collide;
|
||||
@ -594,13 +592,10 @@ bool CEntity::processGoto( CEntityOrder* current, size_t UNUSED(timestep_millis)
|
||||
|
||||
if( m_transition && m_actor )
|
||||
{
|
||||
if (m_run.m_Speed > 0 )
|
||||
if ( m_run.m_Speed > 0 && Distance < m_run.m_MaxRange && ( Distance > m_run.m_MinRange || m_isRunning ) )
|
||||
{
|
||||
if ( Distance > m_run.m_MinRange && Distance < m_run.m_MaxRange )
|
||||
{
|
||||
CSkeletonAnim* run = m_actor->GetRandomAnimation( "run" );
|
||||
m_actor->GetModel()->SetAnimation( run, false, m_run.m_Speed * run->m_AnimDef->GetDuration() );
|
||||
}
|
||||
CSkeletonAnim* run = m_actor->GetRandomAnimation( "run" );
|
||||
m_actor->GetModel()->SetAnimation( run, false, m_run.m_Speed * run->m_AnimDef->GetDuration() );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -67,3 +67,16 @@ CEventOrderTransition::CEventOrderTransition( int orderPrevious, int orderCurren
|
||||
AddLocalProperty( L"target", m_target );
|
||||
AddLocalProperty( L"position", m_worldPosition );
|
||||
}
|
||||
CEventNotification::CEventNotification( CEntityOrder order, uint type ) : CScriptEvent( L"notification", EVENT_NOTIFICATION, true )
|
||||
{
|
||||
m_type = type;
|
||||
m_target = order.m_data[0].entity;
|
||||
m_data = (uint) order.m_data[1].data;
|
||||
CVector3D convert( order.m_data[0].location.x, 0.0f, order.m_data[0].location.y );
|
||||
m_location = convert;
|
||||
|
||||
AddLocalProperty( L"type", &m_type );
|
||||
AddLocalProperty( L"target", &m_target );
|
||||
AddLocalProperty( L"data", &m_data );
|
||||
AddLocalProperty( L"location", &m_location );
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "scripting/DOMEvent.h"
|
||||
#include "Vector3D.h"
|
||||
#include "EntityOrders.h"
|
||||
|
||||
class CDamageType;
|
||||
|
||||
@ -86,5 +87,15 @@ class CEventOrderTransition : public CScriptEvent
|
||||
public:
|
||||
CEventOrderTransition( int orderPrevious, int orderCurrent, CEntity*& target, CVector3D& worldPosition );
|
||||
};
|
||||
class CEventNotification : public CScriptEvent
|
||||
{
|
||||
//Same as CEntityOrder data for support of all orders
|
||||
CEntity* m_target;
|
||||
uint m_data; //u64 is unsupported...will this work?
|
||||
uint m_type;
|
||||
CVector3D m_location; //No real use for y, but CVector2D unsupported
|
||||
public:
|
||||
CEventNotification( CEntityOrder order, uint type );
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user