Stamina bars, run order
This was SVN commit r3364.
This commit is contained in:
parent
a917ffa711
commit
1175b5cdba
@ -14,7 +14,7 @@ STL_HASH_SET<CStr, CStr_hash_compare> CBaseEntity::scriptsLoaded;
|
||||
CBaseEntity::CBaseEntity()
|
||||
{
|
||||
m_base = NULL;
|
||||
|
||||
|
||||
AddProperty( L"tag", &m_Tag, false );
|
||||
AddProperty( L"parent", &m_base, false );
|
||||
AddProperty( L"actions.move.speed", &m_speed );
|
||||
@ -22,6 +22,8 @@ CBaseEntity::CBaseEntity()
|
||||
AddProperty( L"actions.move.run.speed", &( m_run.m_Speed ) );
|
||||
AddProperty( L"actions.move.run.rangemin", &( m_run.m_MinRange ) );
|
||||
AddProperty( L"actions.move.run.range", &( m_run.m_MaxRange ) );
|
||||
AddProperty( L"actions.move.run.regen_rate", &m_runRegenRate );
|
||||
AddProperty( L"actions.move.run.decay_rate", &m_runDecayRate );
|
||||
AddProperty( L"actions.attack.range", &( m_melee.m_MaxRange ) );
|
||||
AddProperty( L"actions.attack.rangemin", &( m_melee.m_MinRange ) );
|
||||
AddProperty( L"actions.attack.speed", &( m_melee.m_Speed ) );
|
||||
@ -35,8 +37,13 @@ CBaseEntity::CBaseEntity()
|
||||
AddProperty( L"traits.extant", &m_extant );
|
||||
AddProperty( L"traits.corpse", &m_corpse );
|
||||
AddProperty( L"traits.health.curr", &m_healthCurr );
|
||||
AddProperty( L"traits.health.max", &m_healthMax );
|
||||
AddProperty( L"traits.health.bar_height", &m_healthBarHeight );
|
||||
AddProperty( L"traits.health.max", &m_healthMax );
|
||||
AddProperty( L"traits.health.bar_height", &m_healthBarHeight );
|
||||
AddProperty( L"traits.health.bar_size", &m_healthBarSize );
|
||||
AddProperty( L"traits.stamina.curr", &m_staminaCurr );
|
||||
AddProperty( L"traits.stamina.max", &m_staminaMax );
|
||||
AddProperty( L"traits.stamina.bar_height", &m_staminaBarHeight );
|
||||
AddProperty( L"traits.stamina.bar_size", &m_staminaBarSize );
|
||||
AddProperty( L"traits.minimap.type", &m_minimapType );
|
||||
AddProperty( L"traits.minimap.red", &m_minimapR );
|
||||
AddProperty( L"traits.minimap.green", &m_minimapG );
|
||||
|
@ -55,11 +55,18 @@ public:
|
||||
CBoundingCircle* m_bound_circle;
|
||||
CBoundingBox* m_bound_box;
|
||||
CBoundingObject::EBoundingType m_bound_type;
|
||||
|
||||
|
||||
//SP properties
|
||||
float m_staminaCurr;
|
||||
float m_staminaMax;
|
||||
float m_staminaBarHeight;
|
||||
int m_staminaBarSize;
|
||||
|
||||
// HP properties
|
||||
float m_healthCurr;
|
||||
float m_healthMax;
|
||||
float m_healthBarHeight;
|
||||
int m_healthBarSize;
|
||||
|
||||
// Minimap properties
|
||||
CStrW m_minimapType;
|
||||
@ -75,7 +82,9 @@ public:
|
||||
bool m_permanent;
|
||||
|
||||
float m_speed;
|
||||
|
||||
float m_runRegenRate;
|
||||
float m_runDecayRate;
|
||||
|
||||
SEntityAction m_run;
|
||||
SEntityAction m_melee;
|
||||
SEntityAction m_gather;
|
||||
|
@ -33,11 +33,16 @@ CEntity::CEntity( CBaseEntity* base, CVector3D position, float orientation )
|
||||
m_orientation = orientation;
|
||||
m_ahead.x = sin( m_orientation );
|
||||
m_ahead.y = cos( m_orientation );
|
||||
|
||||
/* Anything added to this list MUST be added to BaseEntity.cpp (and variables used should
|
||||
also be added to BaseEntity.h */
|
||||
|
||||
AddProperty( L"actions.move.speed", &m_speed );
|
||||
AddProperty( L"actions.move.run.speed", &( m_run.m_Speed ) );
|
||||
AddProperty( L"actions.move.run.rangemin", &( m_run.m_MinRange ) );
|
||||
AddProperty( L"actions.move.run.range", &( m_run.m_MaxRange ) );
|
||||
AddProperty( L"actions.move.run.regen_rate", &m_runRegenRate );
|
||||
AddProperty( L"actions.move.run.decay_rate", &m_runDecayRate );
|
||||
AddProperty( L"selected", &m_selected, false, (NotifyFn)&CEntity::checkSelection );
|
||||
AddProperty( L"group", &m_grouped, false, (NotifyFn)&CEntity::checkGroup );
|
||||
AddProperty( L"traits.extant", &m_extant );
|
||||
@ -58,6 +63,11 @@ CEntity::CEntity( CBaseEntity* base, CVector3D position, float orientation )
|
||||
AddProperty( L"traits.health.curr", &m_healthCurr );
|
||||
AddProperty( L"traits.health.max", &m_healthMax );
|
||||
AddProperty( L"traits.health.bar_height", &m_healthBarHeight );
|
||||
AddProperty( L"traits.health.bar_size", &m_healthBarSize );
|
||||
AddProperty( L"traits.stamina.curr", &m_staminaCurr );
|
||||
AddProperty( L"traits.stamina.max", &m_staminaMax );
|
||||
AddProperty( L"traits.stamina.bar_height", &m_staminaBarHeight );
|
||||
AddProperty( L"traits.stamina.bar_size", &m_staminaBarSize );
|
||||
AddProperty( L"traits.minimap.type", &m_minimapType );
|
||||
AddProperty( L"traits.minimap.red", &m_minimapR );
|
||||
AddProperty( L"traits.minimap.green", &m_minimapG );
|
||||
@ -102,6 +112,12 @@ CEntity::CEntity( CBaseEntity* base, CVector3D position, float orientation )
|
||||
|
||||
m_isRunning = false;
|
||||
|
||||
m_shouldRun = false;
|
||||
|
||||
m_triggerRun = false;
|
||||
|
||||
m_frameCheck = 0;
|
||||
|
||||
m_grouped = -1;
|
||||
|
||||
m_player = g_Game->GetPlayer( 0 );
|
||||
@ -304,8 +320,21 @@ void CEntity::update( size_t timestep )
|
||||
{
|
||||
m_position_previous = m_position;
|
||||
m_orientation_previous = m_orientation;
|
||||
|
||||
|
||||
// Note: aura processing is done before state processing because the state
|
||||
if ( m_triggerRun )
|
||||
m_frameCheck++;
|
||||
|
||||
CalculateRun( timestep );
|
||||
|
||||
if ( m_frameCheck != 0 )
|
||||
{
|
||||
m_shouldRun = true;
|
||||
m_triggerRun = false;
|
||||
m_frameCheck = 0;
|
||||
}
|
||||
|
||||
// Note: aura processing is done before state processing because the state
|
||||
// processing code is filled with all kinds of returns
|
||||
|
||||
PROFILE_START( "aura processing" );
|
||||
@ -410,6 +439,7 @@ void CEntity::update( size_t timestep )
|
||||
updateCollisionPatch();
|
||||
return;
|
||||
case CEntityOrder::ORDER_GOTO:
|
||||
case CEntityOrder::ORDER_RUN:
|
||||
if( processGoto( current, timestep ) )
|
||||
break;
|
||||
updateCollisionPatch();
|
||||
@ -647,90 +677,13 @@ bool CEntity::acceptsOrder( int orderType, CEntity* orderTarget )
|
||||
return( DispatchEvent( &evt ) );
|
||||
}
|
||||
|
||||
jsval CEntity::RequestNotification( JSContext* cx, uintN argc, jsval* argv )
|
||||
{
|
||||
debug_assert( argc > 3 );
|
||||
CEntityListener notify;
|
||||
|
||||
notify.m_sender = this;
|
||||
//(Convert from int to enum)
|
||||
CEntity *target = ToNative<CEntity>( argv[0] );
|
||||
*( (uint*) &(notify.m_type) ) = ToPrimitive<int>( argv[1] );
|
||||
|
||||
bool destroy = ToPrimitive<bool>( argv[2] );
|
||||
|
||||
std::deque<CEntityListener>::iterator it = target->m_listeners.begin();
|
||||
for ( ; it != target->m_listeners.end(); it++)
|
||||
{
|
||||
if ( destroy && it->m_sender == this )
|
||||
target->m_listeners.erase(it);
|
||||
}
|
||||
|
||||
target->m_listeners.push_back( notify );
|
||||
return JSVAL_VOID;
|
||||
}
|
||||
void CEntity::DispatchNotification( CEntityOrder order, uint type )
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CEntity::repath()
|
||||
{
|
||||
CVector2D destination;
|
||||
@ -855,11 +808,8 @@ void CEntity::render()
|
||||
glShadeModel( GL_FLAT );
|
||||
glBegin( GL_LINE_STRIP );
|
||||
|
||||
|
||||
|
||||
glVertex3f( m_position.X, m_position.Y + 0.25f, m_position.Z );
|
||||
|
||||
|
||||
x = m_position.X;
|
||||
y = m_position.Z;
|
||||
|
||||
@ -1047,9 +997,8 @@ void CEntity::renderHealthBar()
|
||||
g_Camera.GetScreenCoordinates(above, sx, sy);
|
||||
float fraction = clamp(m_healthCurr / m_healthMax, 0.0f, 1.0f);
|
||||
|
||||
const float SIZE = 20;
|
||||
float x1 = sx - SIZE/2;
|
||||
float x2 = sx + SIZE/2;
|
||||
float x1 = sx - m_healthBarSize/2;
|
||||
float x2 = sx + m_healthBarSize/2;
|
||||
float y = g_yres - sy;
|
||||
|
||||
glBegin(GL_LINES);
|
||||
@ -1058,19 +1007,61 @@ void CEntity::renderHealthBar()
|
||||
glColor3f( 0, 1, 0 );
|
||||
glVertex3f( x1, y, 0 );
|
||||
glColor3f( 0, 1, 0 );
|
||||
glVertex3f( x1 + SIZE*fraction, y, 0 );
|
||||
glVertex3f( x1 + m_healthBarSize*fraction, y, 0 );
|
||||
|
||||
// red part of bar
|
||||
glColor3f( 1, 0, 0 );
|
||||
glVertex3f( x1 + SIZE*fraction, y, 0 );
|
||||
glVertex3f( x1 + m_healthBarSize*fraction, y, 0 );
|
||||
glColor3f( 1, 0, 0 );
|
||||
glVertex3f( x2, y, 0 );
|
||||
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void CEntity::renderStaminaBar()
|
||||
{
|
||||
if( !m_bounds )
|
||||
return;
|
||||
if( m_staminaBarHeight < 0 )
|
||||
return; // negative bar height means don't display health bar
|
||||
|
||||
CCamera *g_Camera=g_Game->GetView()->GetCamera();
|
||||
|
||||
float sx, sy;
|
||||
CVector3D above;
|
||||
above.X = m_position.X;
|
||||
above.Z = m_position.Z;
|
||||
above.Y = getAnchorLevel(m_position.X, m_position.Z) + m_staminaBarHeight;
|
||||
g_Camera->GetScreenCoordinates(above, sx, sy);
|
||||
float fraction = clamp(m_staminaCurr / m_staminaMax, 0.0f, 1.0f);
|
||||
|
||||
float x1 = sx - m_staminaBarSize/2;
|
||||
float x2 = sx + m_staminaBarSize/2;
|
||||
float y = g_yres - sy;
|
||||
|
||||
glBegin(GL_LINES);
|
||||
|
||||
// blue part of bar
|
||||
glColor3f( 0, 0, 1 );
|
||||
glVertex3f( x1, y, 0 );
|
||||
glColor3f( 0, 0, 1 );
|
||||
glVertex3f( x1 + m_staminaBarSize*fraction, y, 0 );
|
||||
|
||||
// red part of bar
|
||||
glColor3f( 1, 0, 0 );
|
||||
glVertex3f( x1 + m_staminaBarSize*fraction, y, 0 );
|
||||
glColor3f( 1, 0, 0 );
|
||||
glVertex3f( x2, y, 0 );
|
||||
|
||||
glEnd();
|
||||
}
|
||||
void CEntity::CalculateRun(float timestep)
|
||||
{
|
||||
if ( m_isRunning )
|
||||
m_staminaCurr = max( 0.0f, m_staminaCurr - timestep / 1000.0f / m_runDecayRate * m_staminaMax );
|
||||
else if ( m_orderQueue.empty() )
|
||||
m_staminaCurr = min( m_staminaMax, m_staminaCurr + timestep / 1000.0f / m_runRegenRate * m_staminaMax );
|
||||
}
|
||||
/*
|
||||
|
||||
Scripting interface
|
||||
@ -1092,6 +1083,11 @@ void CEntity::ScriptingInit()
|
||||
AddMethod<jsval, &CEntity::AddAura>( "addAura", 3 );
|
||||
AddMethod<jsval, &CEntity::RemoveAura>( "removeAura", 1 );
|
||||
AddMethod<jsval, &CEntity::SetActionParams>( "setActionParams", 5 );
|
||||
AddMethod<jsval, &CEntity::CheckListeners>( "checkListeners", 1 );
|
||||
AddMethod<jsval, &CEntity::RequestNotification>( "requestNotification", 3 );
|
||||
AddMethod<jsval, &CEntity::TriggerRun>( "triggerRun", 1 );
|
||||
AddMethod<jsval, &CEntity::SetRun>( "setRun", 1 );
|
||||
|
||||
|
||||
AddClassProperty( L"template", (CBaseEntity* CEntity::*)&CEntity::m_base, false, (NotifyFn)&CEntity::loadBase );
|
||||
AddClassProperty( L"traits.id.classes", (GetFn)&CEntity::getClassSet, (SetFn)&CEntity::setClassSet );
|
||||
@ -1549,3 +1545,90 @@ jsval CEntity::SetActionParams( JSContext* UNUSED(cx), uintN argc, jsval* argv )
|
||||
|
||||
return JSVAL_VOID;
|
||||
}
|
||||
|
||||
jsval CEntity::RequestNotification( JSContext* cx, uintN argc, jsval* argv )
|
||||
{
|
||||
if( argc < 3 )
|
||||
{
|
||||
JS_ReportError( cx, "Too few parameters" );
|
||||
return( false );
|
||||
}
|
||||
CEntityListener notify;
|
||||
|
||||
notify.m_sender = this;
|
||||
//(Convert from int to enum)
|
||||
CEntity *target = ToNative<CEntity>( argv[0] );
|
||||
*( (uint*) &(notify.m_type) ) = ToPrimitive<int>( argv[1] );
|
||||
|
||||
bool destroy = ToPrimitive<bool>( argv[2] );
|
||||
|
||||
std::deque<CEntityListener>::iterator it = target->m_listeners.begin();
|
||||
for ( ; it != target->m_listeners.end(); 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 )
|
||||
{
|
||||
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)
|
||||
{
|
||||
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:
|
||||
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 );
|
||||
break;
|
||||
|
||||
default:
|
||||
JS_ReportError( cx, "Invalid order type" );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return JSVAL_VOID;
|
||||
}
|
||||
|
||||
jsval CEntity::TriggerRun( JSContext* cx, uintN argc, jsval* argv )
|
||||
{
|
||||
m_triggerRun = true;
|
||||
return JSVAL_VOID;
|
||||
}
|
||||
jsval CEntity::SetRun( JSContext* cx, uintN argc, jsval* argv )
|
||||
{
|
||||
if( argc < 1 )
|
||||
{
|
||||
JS_ReportError( cx, "Too few parameters" );
|
||||
return( false );
|
||||
}
|
||||
m_isRunning = ToPrimitive<bool> ( argv[0] );
|
||||
return JSVAL_VOID;
|
||||
}
|
||||
|
@ -72,8 +72,9 @@ public:
|
||||
|
||||
float m_speed;
|
||||
float m_turningRadius;
|
||||
float m_trampleStart;
|
||||
|
||||
float m_runRegenRate;
|
||||
float m_runDecayRate;
|
||||
|
||||
SEntityAction m_run;
|
||||
SEntityAction m_melee;
|
||||
SEntityAction m_gather;
|
||||
@ -91,12 +92,23 @@ public:
|
||||
// If this unit is still active in the gameworld - i.e. not a corpse.
|
||||
bool m_extant;
|
||||
|
||||
bool m_isRunning;
|
||||
bool m_isRunning; //is it actually running
|
||||
bool m_shouldRun; //if run was issued, it will remain true until it is stopped
|
||||
bool m_triggerRun; //used in SetRun, corrects 1 frame stamina imbalance
|
||||
int m_frameCheck; //counts the frame
|
||||
|
||||
|
||||
//SP properties
|
||||
float m_staminaCurr;
|
||||
float m_staminaMax;
|
||||
float m_staminaBarHeight;
|
||||
int m_staminaBarSize;
|
||||
|
||||
// HP properties
|
||||
float m_healthCurr;
|
||||
float m_healthMax;
|
||||
float m_healthBarHeight;
|
||||
int m_healthBarSize;
|
||||
|
||||
// Minimap properties
|
||||
CStrW m_minimapType;
|
||||
@ -237,9 +249,13 @@ public:
|
||||
void render();
|
||||
void renderSelectionOutline( float alpha = 1.0f );
|
||||
void renderHealthBar();
|
||||
void renderStaminaBar();
|
||||
|
||||
// After a collision, recalc the path to the next fixed waypoint.
|
||||
void repath();
|
||||
|
||||
//Calculate stamina points
|
||||
void CalculateRun(float timestep);
|
||||
|
||||
// Reset properties after the entity-template we use changes.
|
||||
void loadBase();
|
||||
@ -257,10 +273,8 @@ public:
|
||||
void clearOrders();
|
||||
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
|
||||
|
||||
static JSBool Construct( JSContext* cx, JSObject* obj, uint argc, jsval* argv, jsval* rval );
|
||||
@ -277,6 +291,12 @@ public:
|
||||
jsval RemoveAura( JSContext* cx, uintN argc, jsval* argv );
|
||||
|
||||
jsval SetActionParams( JSContext* cx, uintN argc, jsval* argv );
|
||||
jsval TriggerRun( JSContext* cx, uintN argc, jsval* argv );
|
||||
jsval SetRun( JSContext* cx, uintN argc, jsval* argv );
|
||||
jsval IsRunning( JSContext* cx, uintN argc, jsval* argv );
|
||||
|
||||
jsval RequestNotification( JSContext* cx, uintN argc, jsval* argv );
|
||||
jsval CheckListeners( JSContext* cx, uintN argc, jsval* argv );
|
||||
|
||||
bool Order( JSContext* cx, uintN argc, jsval* argv, bool Queued );
|
||||
inline bool OrderSingle( JSContext* cx, uintN argc, jsval* argv )
|
||||
|
@ -53,8 +53,8 @@ public:
|
||||
enum
|
||||
{
|
||||
NOTIFY_GOTO = 0x01,
|
||||
//NOTIFY_ = 0x02, reservered for possible second goto like command
|
||||
//NOTIFY_FOLLOW = 0x03, //GOTO | RUN
|
||||
NOTIFY_RUN = 0x02,
|
||||
NOTIFY_FOLLOW = 0x03, //GOTO | RUN
|
||||
|
||||
NOTIFY_ATTACK = 0x04,
|
||||
NOTIFY_DAMAGE = 0x08,
|
||||
|
@ -47,7 +47,10 @@ uint CEntity::processGotoHelper( CEntityOrder* current, size_t timestep_millis,
|
||||
// Here there be trig.
|
||||
|
||||
float scale;
|
||||
if ( m_run.m_Speed > 0 && len < m_run.m_MaxRange && ( len > m_run.m_MinRange || m_isRunning ) )
|
||||
|
||||
//Should we run or walk
|
||||
if (m_shouldRun && m_staminaCurr > 0 && len < m_run.m_MaxRange &&
|
||||
( len > m_run.m_MinRange || m_isRunning ) )
|
||||
{
|
||||
scale = m_run.m_Speed * timestep;
|
||||
if ( m_actor )
|
||||
@ -57,7 +60,7 @@ uint CEntity::processGotoHelper( CEntityOrder* current, size_t timestep_millis,
|
||||
CSkeletonAnim* run = m_actor->GetRandomAnimation( "run" );
|
||||
if ( 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 );
|
||||
m_isRunning = true;
|
||||
@ -66,28 +69,29 @@ uint CEntity::processGotoHelper( CEntityOrder* current, size_t timestep_millis,
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = m_speed * timestep;
|
||||
scale = m_speed * timestep;
|
||||
if ( m_actor )
|
||||
{
|
||||
//Should we update animation?
|
||||
if ( !m_actor->IsPlayingAnimation( "walk" ) )
|
||||
{
|
||||
CSkeletonAnim* walk = m_actor->GetRandomAnimation( "walk" );
|
||||
if ( 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Note: Easy optimization: flag somewhere that this unit
|
||||
// is already pointing the right way, and don't do this
|
||||
// trig every time.
|
||||
// is already pointing the way, and don't do this
|
||||
// trig every time.right
|
||||
|
||||
m_targetorientation = atan2( delta.x, delta.y );
|
||||
|
||||
@ -237,6 +241,7 @@ bool CEntity::processGotoNoPathing( CEntityOrder* current, size_t timestep_milli
|
||||
{
|
||||
m_orderQueue.pop_front();
|
||||
m_isRunning = false;
|
||||
m_shouldRun = false;
|
||||
}
|
||||
return( false );
|
||||
case COLLISION_OVERLAPPING_OBJECTS:
|
||||
@ -245,6 +250,7 @@ bool CEntity::processGotoNoPathing( CEntityOrder* current, size_t timestep_milli
|
||||
// We're here...
|
||||
m_orderQueue.pop_front();
|
||||
m_isRunning = false;
|
||||
m_shouldRun = false;
|
||||
|
||||
return( false );
|
||||
case COLLISION_NEAR_DESTINATION:
|
||||
@ -309,6 +315,7 @@ bool CEntity::processGotoNoPathing( CEntityOrder* current, size_t timestep_milli
|
||||
// Just stop here, repath if necessary.
|
||||
m_orderQueue.pop_front();
|
||||
m_isRunning = false;
|
||||
m_shouldRun = false;
|
||||
return( false );
|
||||
default:
|
||||
|
||||
@ -329,31 +336,41 @@ bool CEntity::processContactAction( CEntityOrder* current, size_t UNUSED(timeste
|
||||
if( Distance < action->m_MaxRange )
|
||||
{
|
||||
(int&)current->m_type = transition;
|
||||
m_isRunning = false;
|
||||
m_orderQueue.push_front(*current); // Seems to be needed since we do a pop above
|
||||
return( true );
|
||||
}
|
||||
|
||||
if( m_transition && m_actor )
|
||||
if ( m_actor )
|
||||
{
|
||||
if ( m_run.m_Speed > 0 && Distance < m_run.m_MaxRange && ( Distance > m_run.m_MinRange || m_isRunning ) )
|
||||
//Should we run or walk
|
||||
if (m_shouldRun && m_staminaCurr > 0 && Distance < m_run.m_MaxRange &&
|
||||
( Distance > m_run.m_MinRange || m_isRunning ) )
|
||||
{
|
||||
CSkeletonAnim* run = m_actor->GetRandomAnimation( "run" );
|
||||
if ( 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 );
|
||||
m_isRunning = true;
|
||||
if ( !m_actor->IsPlayingAnimation( "run" ) )
|
||||
{
|
||||
CSkeletonAnim* run = m_actor->GetRandomAnimation( "run" );
|
||||
if ( 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 );
|
||||
m_isRunning = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CSkeletonAnim* walk = m_actor->GetRandomAnimation( "walk" );
|
||||
if( 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;
|
||||
//Should we update animation?
|
||||
if ( !m_actor->IsPlayingAnimation( "walk" ) )
|
||||
{
|
||||
CSkeletonAnim* walk = m_actor->GetRandomAnimation( "walk" );
|
||||
if ( 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -419,6 +436,7 @@ bool CEntity::processContactActionNoPathing( CEntityOrder* current, size_t times
|
||||
|
||||
m_orderQueue.pop_front();
|
||||
m_isRunning = false;
|
||||
m_shouldRun = false;
|
||||
return( false );
|
||||
}
|
||||
|
||||
@ -433,6 +451,7 @@ bool CEntity::processContactActionNoPathing( CEntityOrder* current, size_t times
|
||||
{
|
||||
// Too close... do nothing.
|
||||
m_isRunning = false;
|
||||
m_shouldRun = false;
|
||||
return( false );
|
||||
}
|
||||
}
|
||||
@ -445,28 +464,37 @@ bool CEntity::processContactActionNoPathing( CEntityOrder* current, size_t times
|
||||
delta = delta.normalize() * ( adjRange - m_bounds->m_radius );
|
||||
float deltaLength = delta.length();
|
||||
|
||||
if( m_transition && m_actor )
|
||||
if ( m_actor )
|
||||
{
|
||||
if ( m_run.m_Speed > 0 && deltaLength < m_run.m_MaxRange && ( deltaLength > m_run.m_MinRange || m_isRunning ) )
|
||||
//Should we run or walk
|
||||
if (m_shouldRun && m_staminaCurr > 0 && deltaLength < m_run.m_MaxRange &&
|
||||
( deltaLength > m_run.m_MinRange || m_isRunning ) )
|
||||
{
|
||||
CSkeletonAnim* run = m_actor->GetRandomAnimation( "run" );
|
||||
if ( 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 );
|
||||
m_isRunning = true;
|
||||
if ( !m_actor->IsPlayingAnimation( "run" ) )
|
||||
{
|
||||
CSkeletonAnim* run = m_actor->GetRandomAnimation( "run" );
|
||||
if ( 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 );
|
||||
m_isRunning = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CSkeletonAnim* walk = m_actor->GetRandomAnimation( "walk" );
|
||||
if( 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;
|
||||
}
|
||||
//Should we update animation?
|
||||
if ( !m_actor->IsPlayingAnimation( "walk" ) )
|
||||
{
|
||||
CSkeletonAnim* walk = m_actor->GetRandomAnimation( "walk" );
|
||||
if ( 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
current->m_data[0].location = (CVector2D)current->m_data[0].entity->m_position - delta;
|
||||
@ -639,29 +667,42 @@ bool CEntity::processGoto( CEntityOrder* current, size_t UNUSED(timestep_millis)
|
||||
|
||||
// Let's just check we're going somewhere...
|
||||
if( Distance < 0.1f )
|
||||
return( false );
|
||||
|
||||
if( m_transition && m_actor )
|
||||
{
|
||||
if ( m_run.m_Speed > 0 && Distance < m_run.m_MaxRange && ( Distance > m_run.m_MinRange || m_isRunning ) )
|
||||
m_isRunning = false;
|
||||
m_shouldRun = false;
|
||||
return( false );
|
||||
}
|
||||
|
||||
if ( m_actor )
|
||||
{
|
||||
//Should we run or walk
|
||||
if (m_shouldRun && m_staminaCurr > 0 && Distance < m_run.m_MaxRange &&
|
||||
( Distance > m_run.m_MinRange || m_isRunning ) )
|
||||
{
|
||||
CSkeletonAnim* run = m_actor->GetRandomAnimation( "run" );
|
||||
if ( 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 );
|
||||
m_isRunning = true;
|
||||
if ( !m_actor->IsPlayingAnimation( "run" ) )
|
||||
{
|
||||
CSkeletonAnim* run = m_actor->GetRandomAnimation( "run" );
|
||||
if ( 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 );
|
||||
m_isRunning = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CSkeletonAnim* walk = m_actor->GetRandomAnimation( "walk" );
|
||||
if( 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;
|
||||
//Should we update animation?
|
||||
if ( !m_actor->IsPlayingAnimation( "walk" ) )
|
||||
{
|
||||
CSkeletonAnim* walk = m_actor->GetRandomAnimation( "walk" );
|
||||
if ( 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,10 +42,19 @@ CEventTargetChanged::CEventTargetChanged( CEntity* target ) : CScriptEvent( L"ta
|
||||
m_defaultOrder = -1;
|
||||
m_defaultAction = 0;
|
||||
m_defaultCursor = L"arrow-default";
|
||||
|
||||
m_secondaryOrder = -1;
|
||||
m_secondaryAction = 0;
|
||||
m_secondaryCursor = L"arrow-default";
|
||||
|
||||
|
||||
AddLocalProperty( L"target", &m_target, true );
|
||||
AddLocalProperty( L"defaultOrder", &m_defaultOrder );
|
||||
AddLocalProperty( L"defaultAction", &m_defaultAction );
|
||||
AddLocalProperty( L"defaultCursor", &m_defaultCursor );
|
||||
AddLocalProperty( L"secondaryOrder", &m_secondaryOrder );
|
||||
AddLocalProperty( L"secondaryCursor", &m_secondaryCursor );
|
||||
AddLocalProperty( L"secondaryAction", &m_secondaryAction );
|
||||
}
|
||||
|
||||
CEventPrepareOrder::CEventPrepareOrder( CEntity* target, int orderType ) : CScriptEvent( L"prepareOrder", EVENT_PREPARE_ORDER, true )
|
||||
|
@ -67,6 +67,9 @@ public:
|
||||
int m_defaultOrder;
|
||||
int m_defaultAction;
|
||||
CStrW m_defaultCursor;
|
||||
CStrW m_secondaryCursor;
|
||||
int m_secondaryOrder;
|
||||
int m_secondaryAction;
|
||||
CEventTargetChanged( CEntity* target );
|
||||
};
|
||||
|
||||
|
@ -263,6 +263,9 @@ uint CSimulation::TranslateMessage(CNetMessage* pMsg, uint clientMask, void* UNU
|
||||
case NMT_Goto:
|
||||
ENTITY_POSITION(CGoto, ORDER_GOTO);
|
||||
break;
|
||||
case NMT_Run:
|
||||
ENTITY_POSITION(CRun, ORDER_RUN);
|
||||
break;
|
||||
case NMT_Patrol:
|
||||
ENTITY_POSITION(CPatrol, ORDER_PATROL);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user