forked from mirrors/0ad
# Order system refactoring.
This was SVN commit r4716.
This commit is contained in:
@@ -385,10 +385,10 @@ void CEntity::update( size_t timestep )
|
||||
PROFILE( "state transition / order" );
|
||||
|
||||
CEntity* target = NULL;
|
||||
if( current->m_data[0].entity )
|
||||
target = &( *( current->m_data[0].entity ) );
|
||||
if( current->m_target_entity )
|
||||
target = &( *( current->m_target_entity ) );
|
||||
|
||||
CVector3D worldPosition = (CVector3D)current->m_data[0].location;
|
||||
CVector3D worldPosition = (CVector3D)current->m_target_location;
|
||||
|
||||
CEventOrderTransition evt( m_lastState, current->m_type, target, worldPosition );
|
||||
|
||||
@@ -399,8 +399,8 @@ void CEntity::update( size_t timestep )
|
||||
}
|
||||
else if( target )
|
||||
{
|
||||
current->m_data[0].location = worldPosition;
|
||||
current->m_data[0].entity = target->me;
|
||||
current->m_target_location = worldPosition;
|
||||
current->m_target_entity = target->me;
|
||||
}
|
||||
|
||||
m_lastState = current->m_type;
|
||||
@@ -426,7 +426,7 @@ void CEntity::update( size_t timestep )
|
||||
return;
|
||||
case CEntityOrder::ORDER_START_CONSTRUCTION:
|
||||
{
|
||||
CEventStartConstruction evt( current->m_data[0].entity );
|
||||
CEventStartConstruction evt( current->m_new_obj );
|
||||
m_orderQueue.pop_front();
|
||||
DispatchEvent( &evt );
|
||||
}
|
||||
@@ -714,7 +714,7 @@ void CEntity::popOrder()
|
||||
}
|
||||
void CEntity::pushOrder( CEntityOrder& order )
|
||||
{
|
||||
CEventPrepareOrder evt( order.m_data[0].entity, order.m_type, order.m_data[1].data, order.m_data[0].string );
|
||||
CEventPrepareOrder evt( order.m_target_entity, order.m_type, order.m_action, order.m_produce_name );
|
||||
if( DispatchEvent(&evt) )
|
||||
{
|
||||
m_orderQueue.push_back( order );
|
||||
@@ -793,7 +793,7 @@ void CEntity::repath()
|
||||
|| ( m_orderQueue.front().m_type == CEntityOrder::ORDER_GOTO_NOPATHING )
|
||||
|| ( m_orderQueue.front().m_type == CEntityOrder::ORDER_GOTO_SMOOTHED ) ) )
|
||||
{
|
||||
destination = m_orderQueue.front().m_data[0].location;
|
||||
destination = m_orderQueue.front().m_target_location;
|
||||
orderSource = m_orderQueue.front().m_source;
|
||||
m_orderQueue.pop_front();
|
||||
}
|
||||
|
||||
@@ -215,7 +215,7 @@ public:
|
||||
size_t m_fsm_anipos; // the time at which we should start playing it.
|
||||
size_t m_fsm_anipos2; // for when there are two animation-related events we need to take care of.
|
||||
|
||||
std::deque<CEntityOrder> m_orderQueue;
|
||||
CEntityOrders m_orderQueue;
|
||||
std::deque<CEntityListener> m_listeners;
|
||||
|
||||
std::vector<CEntity*> m_notifiers;
|
||||
|
||||
@@ -105,4 +105,7 @@ struct CEntityList: public std::vector<HEntity>
|
||||
operator CStr8() const;
|
||||
};
|
||||
|
||||
typedef CEntityList::iterator CEntityIt;
|
||||
typedef CEntityList::const_iterator CEntityCIt;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -98,16 +98,40 @@ public:
|
||||
ORDER_NOTIFY_REQUEST,
|
||||
ORDER_LAST
|
||||
};
|
||||
EOrderType m_type;
|
||||
|
||||
enum EOrderSource
|
||||
{
|
||||
SOURCE_PLAYER,
|
||||
SOURCE_UNIT_AI
|
||||
};
|
||||
|
||||
EOrderType m_type;
|
||||
EOrderSource m_source;
|
||||
SOrderData m_data[ORDER_MAX_DATA];
|
||||
|
||||
// all commands involving pathfinder (i.e. all :P)
|
||||
float m_pathfinder_radius;
|
||||
|
||||
// NMT_PlaceObject
|
||||
HEntity m_new_obj;
|
||||
|
||||
// NMT_Goto
|
||||
// NMT_FormationGoto
|
||||
// NMT_Run
|
||||
// NMT_Patrol
|
||||
// NMT_AddWaypoint
|
||||
CVector2D m_target_location;
|
||||
|
||||
// NMT_Generic
|
||||
// NMT_FormationGeneric
|
||||
// NMT_NotifyRequest
|
||||
HEntity m_target_entity;
|
||||
int m_action;
|
||||
|
||||
// NMT_Produce
|
||||
CStrW m_produce_name;
|
||||
int m_produce_type;
|
||||
|
||||
|
||||
//SOrderData m_data[ORDER_MAX_DATA];
|
||||
|
||||
CEntityOrder(): m_type(ORDER_INVALID), m_source(SOURCE_PLAYER) {}
|
||||
|
||||
@@ -115,4 +139,10 @@ public:
|
||||
: m_type(type), m_source(source) {}
|
||||
};
|
||||
|
||||
typedef std::deque<CEntityOrder> CEntityOrders;
|
||||
typedef CEntityOrders::iterator CEntityOrderIt;
|
||||
typedef CEntityOrders::const_iterator CEntityOrderCIt;
|
||||
typedef CEntityOrders::const_reverse_iterator CEntityOrderCRIt;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -45,15 +45,15 @@ void CEntity::render()
|
||||
CBoundingObject* destinationCollisionObject;
|
||||
float x0, y0, x, y;
|
||||
|
||||
x = m_orderQueue.front().m_data[0].location.x;
|
||||
y = m_orderQueue.front().m_data[0].location.y;
|
||||
x = m_orderQueue.front().m_target_location.x;
|
||||
y = m_orderQueue.front().m_target_location.y;
|
||||
|
||||
for( it = m_orderQueue.begin(); it < m_orderQueue.end(); it++ )
|
||||
{
|
||||
if( it->m_type == CEntityOrder::ORDER_PATROL )
|
||||
break;
|
||||
x = it->m_data[0].location.x;
|
||||
y = it->m_data[0].location.y;
|
||||
x = it->m_target_location.x;
|
||||
y = it->m_target_location.y;
|
||||
}
|
||||
destinationCollisionObject = getContainingObject( CVector2D( x, y ) );
|
||||
|
||||
@@ -69,8 +69,8 @@ void CEntity::render()
|
||||
{
|
||||
x0 = x;
|
||||
y0 = y;
|
||||
x = it->m_data[0].location.x;
|
||||
y = it->m_data[0].location.y;
|
||||
x = it->m_target_location.x;
|
||||
y = it->m_target_location.y;
|
||||
rayIntersectionResults r;
|
||||
CVector2D fwd( x - x0, y - y0 );
|
||||
float l = fwd.length();
|
||||
@@ -590,3 +590,4 @@ void CEntity::renderRallyPoint()
|
||||
sprite.Render();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -280,8 +280,8 @@ bool CEntity::Order( JSContext* cx, uintN argc, jsval* argv, bool Queued )
|
||||
JSU_REQUIRE_PARAMS_CPP(3);
|
||||
try
|
||||
{
|
||||
newOrder.m_data[0].location.x = ToPrimitive<float>( argv[1] );
|
||||
newOrder.m_data[0].location.y = ToPrimitive<float>( argv[2] );
|
||||
newOrder.m_target_location.x = ToPrimitive<float>( argv[1] );
|
||||
newOrder.m_target_location.y = ToPrimitive<float>( argv[2] );
|
||||
}
|
||||
catch( PSERROR_Scripting_ConversionFailed )
|
||||
{
|
||||
@@ -308,10 +308,10 @@ bool CEntity::Order( JSContext* cx, uintN argc, jsval* argv, bool Queued )
|
||||
JS_ReportError( cx, "Invalid target" );
|
||||
return( false );
|
||||
}
|
||||
newOrder.m_data[0].entity = target->me;
|
||||
newOrder.m_target_entity = target->me;
|
||||
try
|
||||
{
|
||||
newOrder.m_data[1].data = ToPrimitive<int>( argv[2] );
|
||||
newOrder.m_action = ToPrimitive<int>( argv[2] );
|
||||
}
|
||||
catch( PSERROR_Scripting_ConversionFailed )
|
||||
{
|
||||
@@ -331,8 +331,8 @@ bool CEntity::Order( JSContext* cx, uintN argc, jsval* argv, bool Queued )
|
||||
case CEntityOrder::ORDER_PRODUCE:
|
||||
JSU_REQUIRE_PARAMS_CPP(3);
|
||||
try {
|
||||
newOrder.m_data[0].string = ToPrimitive<CStrW>(argv[2]);
|
||||
newOrder.m_data[1].data = ToPrimitive<int>(argv[1]);
|
||||
newOrder.m_produce_name = ToPrimitive<CStrW>(argv[2]);
|
||||
newOrder.m_produce_type = ToPrimitive<int>(argv[1]);
|
||||
}
|
||||
catch( PSERROR_Scripting_ConversionFailed )
|
||||
{
|
||||
|
||||
@@ -94,8 +94,8 @@ uint CEntity::processGotoHelper( CEntityOrder* current, size_t timestep_millis,
|
||||
float timestep=timestep_millis/1000.0f;
|
||||
|
||||
CVector2D delta;
|
||||
delta.x = (float)current->m_data[0].location.x - m_position.X;
|
||||
delta.y = (float)current->m_data[0].location.y - m_position.Z;
|
||||
delta.x = (float)current->m_target_location.x - m_position.X;
|
||||
delta.y = (float)current->m_target_location.y - m_position.Z;
|
||||
|
||||
float len = delta.length();
|
||||
|
||||
@@ -205,14 +205,14 @@ uint CEntity::processGotoHelper( CEntityOrder* current, size_t timestep_millis,
|
||||
}
|
||||
|
||||
// No. Is our destination within the obstacle?
|
||||
if( collide->m_bounds->contains( current->m_data[0].location ) )
|
||||
if( collide->m_bounds->contains( current->m_target_location ) )
|
||||
return( COLLISION_WITH_DESTINATION );
|
||||
|
||||
// No. Are we nearing our destination, do we wish to stop there, and is it obstructed?
|
||||
|
||||
if( ( m_orderQueue.size() == 1 ) && ( len <= 10.0f ) )
|
||||
{
|
||||
CBoundingCircle destinationObs( current->m_data[0].location.x, current->m_data[0].location.y, m_bounds->m_radius, 0.0f );
|
||||
CBoundingCircle destinationObs( current->m_target_location.x, current->m_target_location.y, m_bounds->m_radius, 0.0f );
|
||||
if( getCollisionObject( &destinationObs ) )
|
||||
{
|
||||
// Yes. (Chances are a bunch of units were tasked to the same destination)
|
||||
@@ -290,11 +290,11 @@ bool CEntity::processGotoNoPathing( CEntityOrder* current, size_t timestep_milli
|
||||
{
|
||||
// Here's a weird idea: (I hope it works)
|
||||
// Spiral round the destination until a free point is found.
|
||||
CBoundingCircle destinationObs( current->m_data[0].location.x, current->m_data[0].location.y, m_bounds->m_radius, 0.0f );
|
||||
CBoundingCircle destinationObs( current->m_target_location.x, current->m_target_location.y, m_bounds->m_radius, 0.0f );
|
||||
|
||||
float interval = destinationObs.m_radius;
|
||||
float r = interval, theta = 0.0f, delta;
|
||||
float _x = current->m_data[0].location.x, _y = current->m_data[0].location.y;
|
||||
float _x = current->m_target_location.x, _y = current->m_target_location.y;
|
||||
|
||||
while( true )
|
||||
{
|
||||
@@ -306,8 +306,8 @@ bool CEntity::processGotoNoPathing( CEntityOrder* current, size_t timestep_milli
|
||||
}
|
||||
|
||||
// Reset our destination
|
||||
current->m_data[0].location.x = _x + r * cosf( theta );
|
||||
current->m_data[0].location.y = _y + r * sinf( theta );
|
||||
current->m_target_location.x = _x + r * cosf( theta );
|
||||
current->m_target_location.y = _y + r * sinf( theta );
|
||||
|
||||
return( false );
|
||||
}
|
||||
@@ -337,7 +337,7 @@ bool CEntity::processGotoNoPathing( CEntityOrder* current, size_t timestep_milli
|
||||
|
||||
// Create a short path representing this detour
|
||||
|
||||
avoidance.m_data[0].location = avoidancePosition;
|
||||
avoidance.m_target_location = avoidancePosition;
|
||||
if( current->m_type == CEntityOrder::ORDER_GOTO_COLLISION )
|
||||
|
||||
m_orderQueue.pop_front();
|
||||
@@ -362,7 +362,7 @@ bool CEntity::processGotoNoPathing( CEntityOrder* current, size_t timestep_milli
|
||||
// Handles processing common to (at the moment) gather and melee attack actions
|
||||
bool CEntity::processContactAction( CEntityOrder* current, size_t UNUSED(timestep_millis), CEntityOrder::EOrderType transition, SEntityAction* action )
|
||||
{
|
||||
HEntity target = current->m_data[0].entity;
|
||||
HEntity target = current->m_target_entity;
|
||||
|
||||
if( !target || !target->m_extant )
|
||||
{
|
||||
@@ -381,8 +381,8 @@ bool CEntity::processContactAction( CEntityOrder* current, size_t UNUSED(timeste
|
||||
return false;
|
||||
}
|
||||
|
||||
current->m_data[0].location = target->m_position;
|
||||
float Distance = distance2D(current->m_data[0].location);
|
||||
current->m_target_location = target->m_position;
|
||||
float Distance = distance2D(current->m_target_location);
|
||||
|
||||
if( Distance < action->m_MaxRange )
|
||||
{
|
||||
@@ -410,7 +410,7 @@ bool CEntity::processContactAction( CEntityOrder* current, size_t UNUSED(timeste
|
||||
}
|
||||
bool CEntity::processContactActionNoPathing( CEntityOrder* current, size_t timestep_millis, const CStr& animation, CScriptEvent* contactEvent, SEntityAction* action )
|
||||
{
|
||||
HEntity target = current->m_data[0].entity;
|
||||
HEntity target = current->m_target_entity;
|
||||
|
||||
if( m_fsm_cyclepos != NOT_IN_CYCLE )
|
||||
{
|
||||
@@ -531,7 +531,7 @@ bool CEntity::processContactActionNoPathing( CEntityOrder* current, size_t times
|
||||
|
||||
chooseMovementSpeed(deltaLength);
|
||||
|
||||
current->m_data[0].location = (CVector2D)target->m_position - delta;
|
||||
current->m_target_location = (CVector2D)target->m_position - delta;
|
||||
|
||||
HEntity collide;
|
||||
switch( processGotoHelper( current, timestep_millis, collide ) )
|
||||
@@ -576,7 +576,7 @@ bool CEntity::processContactActionNoPathing( CEntityOrder* current, size_t times
|
||||
|
||||
// Create a short path representing this detour
|
||||
|
||||
avoidance.m_data[0].location = avoidancePosition;
|
||||
avoidance.m_target_location = avoidancePosition;
|
||||
if( current->m_type == CEntityOrder::ORDER_GOTO_COLLISION )
|
||||
m_orderQueue.pop_front();
|
||||
m_orderQueue.push_front( avoidance );
|
||||
@@ -637,26 +637,24 @@ bool CEntity::processContactActionNoPathing( CEntityOrder* current, size_t times
|
||||
|
||||
bool CEntity::processGeneric( CEntityOrder* current, size_t timestep_millis )
|
||||
{
|
||||
int id = current->m_data[1].data;
|
||||
if( m_actions.find( id ) == m_actions.end() )
|
||||
if( m_actions.find( current->m_action ) == m_actions.end() )
|
||||
{
|
||||
return false; // we've been tasked as part of a group but we can't do this action
|
||||
}
|
||||
SEntityAction& action = m_actions[id];
|
||||
return( processContactAction( current, timestep_millis, CEntityOrder::ORDER_GENERIC_NOPATHING, &action ) );
|
||||
SEntityAction& action_obj = m_actions[current->m_action];
|
||||
return( processContactAction( current, timestep_millis, CEntityOrder::ORDER_GENERIC_NOPATHING, &action_obj ) );
|
||||
}
|
||||
|
||||
bool CEntity::processGenericNoPathing( CEntityOrder* current, size_t timestep_millis )
|
||||
{
|
||||
int id = current->m_data[1].data;
|
||||
if( m_actions.find( id ) == m_actions.end() )
|
||||
if( m_actions.find( current->m_action ) == m_actions.end() )
|
||||
{
|
||||
return false; // we've been tasked as part of a group but we can't do this action
|
||||
}
|
||||
SEntityAction& action = m_actions[id];
|
||||
CEventGeneric evt( current->m_data[0].entity, id );
|
||||
CEventGeneric evt( current->m_target_entity, current->m_action );
|
||||
if( !m_actor ) return( false );
|
||||
return( processContactActionNoPathing( current, timestep_millis, action.m_Animation, &evt, &action ) );
|
||||
SEntityAction& action_obj = m_actions[current->m_action];
|
||||
return( processContactActionNoPathing( current, timestep_millis, action_obj.m_Animation, &evt, &action_obj ) );
|
||||
}
|
||||
|
||||
bool CEntity::processGoto( CEntityOrder* current, size_t UNUSED(timestep_millis) )
|
||||
@@ -666,7 +664,7 @@ bool CEntity::processGoto( CEntityOrder* current, size_t UNUSED(timestep_millis)
|
||||
|
||||
|
||||
CVector2D pos( m_position.X, m_position.Z );
|
||||
CVector2D path_to = current->m_data[0].location;
|
||||
CVector2D path_to = current->m_target_location;
|
||||
m_orderQueue.pop_front();
|
||||
float Distance = ( path_to - pos ).length();
|
||||
|
||||
@@ -690,7 +688,7 @@ bool CEntity::processGoto( CEntityOrder* current, size_t UNUSED(timestep_millis)
|
||||
bool CEntity::processGotoWaypoint( CEntityOrder* current, size_t UNUSED(timestep_milli), bool contact )
|
||||
{
|
||||
CVector2D pos( m_position.X, m_position.Z );
|
||||
CVector2D path_to = current->m_data[0].location;
|
||||
CVector2D path_to = current->m_target_location;
|
||||
m_orderQueue.pop_front();
|
||||
float Distance = ( path_to - pos ).length();
|
||||
|
||||
@@ -704,8 +702,7 @@ bool CEntity::processGotoWaypoint( CEntityOrder* current, size_t UNUSED(timestep
|
||||
|
||||
chooseMovementSpeed( Distance );
|
||||
|
||||
float radius = *((float*)¤t->m_data[0].data);
|
||||
g_Pathfinder.requestLowLevelPath( me, path_to, contact, radius, current->m_source );
|
||||
g_Pathfinder.requestLowLevelPath( me, path_to, contact, current->m_pathfinder_radius, current->m_source );
|
||||
|
||||
return( true );
|
||||
}
|
||||
@@ -723,9 +720,9 @@ bool CEntity::processPatrol( CEntityOrder* current, size_t UNUSED(timestep_milli
|
||||
// queue (to keep us patrolling)
|
||||
|
||||
this_segment.m_type = CEntityOrder::ORDER_GOTO;
|
||||
this_segment.m_data[0] = current->m_data[0];
|
||||
this_segment.m_pathfinder_radius = current->m_pathfinder_radius;
|
||||
repeat_patrol.m_type = CEntityOrder::ORDER_PATROL;
|
||||
repeat_patrol.m_data[0] = current->m_data[0];
|
||||
repeat_patrol.m_pathfinder_radius = current->m_pathfinder_radius;
|
||||
m_orderQueue.pop_front();
|
||||
m_orderQueue.push_front( this_segment );
|
||||
m_orderQueue.push_back( repeat_patrol );
|
||||
@@ -734,12 +731,10 @@ bool CEntity::processPatrol( CEntityOrder* current, size_t UNUSED(timestep_milli
|
||||
|
||||
bool CEntity::processProduce( CEntityOrder* order )
|
||||
{
|
||||
int type = order->m_data[1].data;
|
||||
CStrW name = order->m_data[0].string;
|
||||
CEventStartProduction evt( type, name );
|
||||
CEventStartProduction evt( order->m_produce_type, order->m_produce_name );
|
||||
if( DispatchEvent( &evt ) && evt.GetTime() >= 0 )
|
||||
{
|
||||
m_productionQueue->AddItem( type, name, evt.GetTime() );
|
||||
m_productionQueue->AddItem( order->m_produce_type, order->m_produce_name, evt.GetTime() );
|
||||
}
|
||||
return( false );
|
||||
}
|
||||
|
||||
@@ -103,8 +103,8 @@ CEventOrderTransition::CEventOrderTransition( int orderPrevious, int orderCurren
|
||||
CEventNotification::CEventNotification( CEntityOrder order, int notifyType ) : CScriptEvent( L"notification", EVENT_NOTIFICATION, true )
|
||||
{
|
||||
m_notifyType = notifyType;
|
||||
m_target = order.m_data[0].entity;
|
||||
CVector3D convert( order.m_data[0].location.x, 0.0f, order.m_data[0].location.y );
|
||||
m_target = order.m_target_entity;
|
||||
CVector3D convert( order.m_target_location.x, 0.0f, order.m_target_location.y );
|
||||
m_location = convert;
|
||||
|
||||
AddLocalProperty( L"notifyType", &m_notifyType );
|
||||
@@ -120,8 +120,8 @@ CIdleEvent::CIdleEvent( CEntityOrder order, int notifyType ) : CScriptEvent( L"i
|
||||
{
|
||||
m_notifyType = notifyType;
|
||||
m_orderType = order.m_type;
|
||||
m_target = order.m_data[0].entity;
|
||||
CVector3D convert( order.m_data[0].location.x, 0.0f, order.m_data[0].location.y );
|
||||
m_target = order.m_target_entity;
|
||||
CVector3D convert( order.m_target_location.x, 0.0f, order.m_target_location.y );
|
||||
m_location = convert;
|
||||
|
||||
AddLocalProperty( L"notifyType", &m_notifyType );
|
||||
|
||||
@@ -24,8 +24,8 @@ void CPathfindEngine::requestPath( HEntity entity, const CVector2D& destination,
|
||||
CEntityOrder waypoint;
|
||||
waypoint.m_type = CEntityOrder::ORDER_GOTO_WAYPOINT;
|
||||
waypoint.m_source = orderSource;
|
||||
waypoint.m_data[0].location = destination;
|
||||
*((float*)&waypoint.m_data[0].data) = 0.0f;
|
||||
waypoint.m_target_location = destination;
|
||||
waypoint.m_pathfinder_radius = 0.0f;
|
||||
entity->m_orderQueue.push_front( waypoint );
|
||||
}
|
||||
|
||||
@@ -52,16 +52,16 @@ void CPathfindEngine::requestLowLevelPath( HEntity entity, const CVector2D& dest
|
||||
// (otherwise, go to wherever the pathfinder tells us since we just want to be in range)
|
||||
CVector2D finalDest = (radius==0 ? destination : path[path.size()-1]);
|
||||
node.m_type = CEntityOrder::ORDER_PATH_END_MARKER; // push end marker (used as a sentinel when repathing)
|
||||
node.m_data[0].location = finalDest;
|
||||
node.m_target_location = finalDest;
|
||||
entity->m_orderQueue.push_front(node);
|
||||
node.m_type = CEntityOrder::ORDER_GOTO_NOPATHING; // push final goto step
|
||||
node.m_data[0].location = finalDest;
|
||||
node.m_target_location = finalDest;
|
||||
entity->m_orderQueue.push_front(node);
|
||||
|
||||
for( int i = ((int) path.size()) - 2; i >= 0; i-- )
|
||||
{
|
||||
node.m_type = CEntityOrder::ORDER_GOTO_NOPATHING; // TODO: For non-contact paths, do we want some other order type?
|
||||
node.m_data[0].location = path[i];
|
||||
node.m_target_location = path[i];
|
||||
entity->m_orderQueue.push_front(node);
|
||||
}
|
||||
}
|
||||
@@ -73,10 +73,10 @@ void CPathfindEngine::requestLowLevelPath( HEntity entity, const CVector2D& dest
|
||||
{
|
||||
CEntityOrder node;
|
||||
node.m_type = CEntityOrder::ORDER_PATH_END_MARKER;
|
||||
node.m_data[0].location = destination;
|
||||
node.m_target_location = destination;
|
||||
entity->m_orderQueue.push_front(node);
|
||||
node.m_type = CEntityOrder::ORDER_GOTO_NOPATHING;
|
||||
node.m_data[0].location = destination;
|
||||
node.m_target_location = destination;
|
||||
entity->m_orderQueue.push_front(node);
|
||||
}
|
||||
}
|
||||
@@ -96,12 +96,12 @@ void CPathfindEngine::requestContactPath( HEntity entity, CEntityOrder* current,
|
||||
CEntityOrder waypoint;
|
||||
waypoint.m_type = CEntityOrder::ORDER_GOTO_WAYPOINT_CONTACT;
|
||||
waypoint.m_source = current->m_source;
|
||||
HEntity target = current->m_data[0].entity;
|
||||
waypoint.m_data[0].location = target->m_position;
|
||||
*((float*)&waypoint.m_data[0].data) = std::max( target->m_bounds->m_radius, range );
|
||||
HEntity target = current->m_target_entity;
|
||||
waypoint.m_target_location = target->m_position;
|
||||
waypoint.m_pathfinder_radius = std::max( target->m_bounds->m_radius, range );
|
||||
entity->m_orderQueue.push_front( waypoint );
|
||||
|
||||
//pathSparse( entity, current->m_data[0].entity->m_position );
|
||||
//pathSparse( entity, current->m_target_entity->m_position );
|
||||
//// For attack orders, do some additional postprocessing (replace goto/nopathing
|
||||
//// with attack/nopathing, up until the attack order marker)
|
||||
//std::deque<CEntityOrder>::iterator it;
|
||||
@@ -128,21 +128,21 @@ bool CPathfindEngine::requestAvoidPath( HEntity entity, CEntityOrder* current, f
|
||||
waypoint.m_source = current->m_source;
|
||||
|
||||
// Figure out a direction to move
|
||||
HEntity target = current->m_data[0].entity;
|
||||
HEntity target = current->m_target_entity;
|
||||
CVector3D dir = entity->m_position - target->m_position;
|
||||
if(dir.LengthSquared() == 0) // shouldn't happen, but just in case
|
||||
dir = CVector3D(1, 0, 0);
|
||||
float dist = dir.GetLength();
|
||||
dir.Normalize();
|
||||
|
||||
waypoint.m_data[0].location = entity->m_position + dir * (avoidRange - dist);
|
||||
waypoint.m_target_location = entity->m_position + dir * (avoidRange - dist);
|
||||
|
||||
if( !g_Game->GetWorld()->GetTerrain()->isOnMap( waypoint.m_data[0].location ) )
|
||||
if( !g_Game->GetWorld()->GetTerrain()->isOnMap( waypoint.m_target_location ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*((float*)&waypoint.m_data[0].data) = 0.0f;
|
||||
waypoint.m_pathfinder_radius = 0.0f;
|
||||
entity->m_orderQueue.push_front( waypoint );
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ void nodePostProcess( HEntity entity, std::vector<CVector2D>& nodelist )
|
||||
entity->m_orderQueue.push_front( node );
|
||||
|
||||
node.m_type = CEntityOrder::ORDER_GOTO_SMOOTHED;
|
||||
node.m_data[0].location = next;
|
||||
node.m_target_location = next;
|
||||
|
||||
entity->m_orderQueue.push_front( node );
|
||||
|
||||
@@ -223,7 +223,7 @@ void nodePostProcess( HEntity entity, std::vector<CVector2D>& nodelist )
|
||||
CVector2D ubar = u.beta();
|
||||
CVector2D vbar = v.beta();
|
||||
float alpha = entity->m_turningRadius * ( ubar - vbar ).length() / ( u + v ).length();
|
||||
node.m_data[0].location = current - u * alpha;
|
||||
node.m_target_location = current - u * alpha;
|
||||
entity->m_orderQueue.push_front( node );
|
||||
next = current;
|
||||
}
|
||||
@@ -257,7 +257,7 @@ void pathSparse( HEntity entity, CVector2D destination )
|
||||
// Try a straight line. All we can do, really.
|
||||
CEntityOrder direct;
|
||||
direct.m_type = CEntityOrder::ORDER_GOTO_NOPATHING;
|
||||
direct.m_data[0].location = destination;
|
||||
direct.m_target_location = destination;
|
||||
entity->m_orderQueue.push_front( direct );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,20 +162,13 @@ void RandomizeLocations(CEntityOrder order, const std::vector<HEntity> &entities
|
||||
}
|
||||
while( ( _x * _x ) + ( _y * _y ) > 1.0f );
|
||||
|
||||
randomizedOrder.m_data[0].location.x += _x * radius;
|
||||
randomizedOrder.m_data[0].location.y += _y * radius;
|
||||
randomizedOrder.m_target_location.x += _x * radius;
|
||||
randomizedOrder.m_target_location.y += _y * radius;
|
||||
|
||||
// Clamp it to within the map, just in case.
|
||||
float mapsize = (float)g_Game->GetWorld()->GetTerrain()->GetVerticesPerSide() * CELL_SIZE;
|
||||
|
||||
if( randomizedOrder.m_data[0].location.x < 0.0f )
|
||||
randomizedOrder.m_data[0].location.x = 0.0f;
|
||||
if( randomizedOrder.m_data[0].location.x >= mapsize )
|
||||
randomizedOrder.m_data[0].location.x = mapsize;
|
||||
if( randomizedOrder.m_data[0].location.y < 0.0f )
|
||||
randomizedOrder.m_data[0].location.y = 0.0f;
|
||||
if( randomizedOrder.m_data[0].location.y >= mapsize )
|
||||
randomizedOrder.m_data[0].location.y = mapsize;
|
||||
randomizedOrder.m_target_location.x = clamp(randomizedOrder.m_target_location.x, 0.0f, mapsize);
|
||||
randomizedOrder.m_target_location.y = clamp(randomizedOrder.m_target_location.y, 0.0f, mapsize);
|
||||
|
||||
if( !isQueued )
|
||||
(*it)->clearOrders();
|
||||
@@ -194,7 +187,7 @@ void FormationLocations(CEntityOrder order, const std::vector<HEntity> &entities
|
||||
for (; it != entities.end(); it++)
|
||||
{
|
||||
CEntityOrder orderCopy = order;
|
||||
CVector2D posDelta = orderCopy.m_data[0].location - formation->GetPosition();
|
||||
CVector2D posDelta = orderCopy.m_target_location - formation->GetPosition();
|
||||
CVector2D formDelta = formation->GetSlotPosition( (*it)->m_formationSlot );
|
||||
|
||||
posDelta = posDelta.normalize();
|
||||
@@ -205,19 +198,12 @@ void FormationLocations(CEntityOrder order, const std::vector<HEntity> &entities
|
||||
rotDelta.x = formDelta.x * deltaCos - formDelta.y * deltaSin;
|
||||
rotDelta.y = formDelta.x * deltaSin + formDelta.y * deltaCos;
|
||||
|
||||
orderCopy.m_data[0].location += rotDelta;
|
||||
orderCopy.m_target_location += rotDelta;
|
||||
|
||||
// Clamp it to within the map, just in case.
|
||||
float mapsize = (float)g_Game->GetWorld()->GetTerrain()->GetVerticesPerSide() * CELL_SIZE;
|
||||
|
||||
if( orderCopy.m_data[0].location.x < 0.0f )
|
||||
orderCopy.m_data[0].location.x = 0.0f;
|
||||
if( orderCopy.m_data[0].location.x >= mapsize )
|
||||
orderCopy.m_data[0].location.x = mapsize;
|
||||
if( orderCopy.m_data[0].location.y < 0.0f )
|
||||
orderCopy.m_data[0].location.y = 0.0f;
|
||||
if( orderCopy.m_data[0].location.y >= mapsize )
|
||||
orderCopy.m_data[0].location.y = mapsize;
|
||||
orderCopy.m_target_location.x = clamp(orderCopy.m_target_location.x, 0.0f, mapsize);
|
||||
orderCopy.m_target_location.y = clamp(orderCopy.m_target_location.y, 0.0f, mapsize);
|
||||
|
||||
if( !isQueued )
|
||||
(*it)->clearOrders();
|
||||
@@ -249,8 +235,8 @@ uint CSimulation::TranslateMessage(CNetMessage* pMsg, uint clientMask, void* UNU
|
||||
_msg *msg=(_msg *)pMsg; \
|
||||
isQueued = msg->m_IsQueued != 0; \
|
||||
order.m_type=CEntityOrder::_order; \
|
||||
order.m_data[0].location.x=(float)msg->m_TargetX; \
|
||||
order.m_data[0].location.y=(float)msg->m_TargetY; \
|
||||
order.m_target_location.x=(float)msg->m_TargetX; \
|
||||
order.m_target_location.y=(float)msg->m_TargetY; \
|
||||
RandomizeLocations(order, msg->m_Entities, isQueued); \
|
||||
} while(0)
|
||||
#define ENTITY_POSITION_FORM(_msg, _order) do\
|
||||
@@ -258,25 +244,17 @@ uint CSimulation::TranslateMessage(CNetMessage* pMsg, uint clientMask, void* UNU
|
||||
_msg *msg=(_msg *)pMsg; \
|
||||
isQueued = msg->m_IsQueued != 0; \
|
||||
order.m_type=CEntityOrder::_order; \
|
||||
order.m_data[0].location.x=(float)msg->m_TargetX; \
|
||||
order.m_data[0].location.y=(float)msg->m_TargetY; \
|
||||
order.m_target_location.x=(float)msg->m_TargetX; \
|
||||
order.m_target_location.y=(float)msg->m_TargetY; \
|
||||
FormationLocations(order, msg->m_Entities, isQueued); \
|
||||
} while(0)
|
||||
#define ENTITY_ENTITY(_msg, _order) do\
|
||||
{ \
|
||||
_msg *msg=(_msg *)pMsg; \
|
||||
isQueued = msg->m_IsQueued != 0; \
|
||||
order.m_type=CEntityOrder::_order; \
|
||||
order.m_data[0].entity=msg->m_Target; \
|
||||
QueueOrder(order, msg->m_Entities, isQueued); \
|
||||
} while(0)
|
||||
#define ENTITY_ENTITY_INT(_msg, _order) do\
|
||||
{ \
|
||||
_msg *msg=(_msg *)pMsg; \
|
||||
isQueued = msg->m_IsQueued != 0; \
|
||||
order.m_type=CEntityOrder::_order; \
|
||||
order.m_data[0].entity=msg->m_Target; \
|
||||
order.m_data[1].data=msg->m_Action; \
|
||||
order.m_target_entity=msg->m_Target; \
|
||||
order.m_action=msg->m_Action; \
|
||||
QueueOrder(order, msg->m_Entities, isQueued); \
|
||||
} while(0)
|
||||
#define ENTITY_INT_STRING(_msg, _order) do\
|
||||
@@ -284,8 +262,8 @@ uint CSimulation::TranslateMessage(CNetMessage* pMsg, uint clientMask, void* UNU
|
||||
_msg *msg=(_msg *)pMsg; \
|
||||
isQueued = msg->m_IsQueued != 0; \
|
||||
order.m_type=CEntityOrder::_order; \
|
||||
order.m_data[0].string=msg->m_Name; \
|
||||
order.m_data[1].data=msg->m_Type; \
|
||||
order.m_produce_name=msg->m_Name; \
|
||||
order.m_produce_type=msg->m_Type; \
|
||||
QueueOrder(order, msg->m_Entities, isQueued); \
|
||||
} while(0)
|
||||
|
||||
@@ -296,25 +274,25 @@ uint CSimulation::TranslateMessage(CNetMessage* pMsg, uint clientMask, void* UNU
|
||||
CAddWaypoint *msg=(CAddWaypoint *)pMsg;
|
||||
isQueued = msg->m_IsQueued != 0;
|
||||
order.m_type=CEntityOrder::ORDER_LAST;
|
||||
order.m_data[0].location.x=(float)msg->m_TargetX;
|
||||
order.m_data[0].location.y=(float)msg->m_TargetY;
|
||||
std::vector<HEntity>::iterator it = msg->m_Entities.begin();
|
||||
for (;it != msg->m_Entities.end(); ++it)
|
||||
order.m_target_location.x=(float)msg->m_TargetX;
|
||||
order.m_target_location.y=(float)msg->m_TargetY;
|
||||
for(CEntityIt it = msg->m_Entities.begin(); it != msg->m_Entities.end(); ++it)
|
||||
{
|
||||
std::deque<CEntityOrder>::const_iterator ord_it;
|
||||
ord_it=(*it)->m_orderQueue.end() - 1;
|
||||
for (;ord_it >= (*it)->m_orderQueue.begin();--ord_it)
|
||||
HEntity& hentity = *it;
|
||||
|
||||
CEntityOrders& order_queue = hentity->m_orderQueue;
|
||||
for(CEntityOrderCRIt ord_it = order_queue.rbegin(); ord_it != order_queue.rend(); ++ord_it)
|
||||
{
|
||||
if (ord_it->m_type == CEntityOrder::ORDER_PATH_END_MARKER)
|
||||
{
|
||||
order.m_type = CEntityOrder::ORDER_GOTO;
|
||||
(*it)->pushOrder(order);
|
||||
hentity->pushOrder(order);
|
||||
break;
|
||||
}
|
||||
if (ord_it->m_type == CEntityOrder::ORDER_PATROL)
|
||||
{
|
||||
order.m_type = ord_it->m_type;
|
||||
(*it)->pushOrder(order);
|
||||
hentity->pushOrder(order);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -328,28 +306,29 @@ uint CSimulation::TranslateMessage(CNetMessage* pMsg, uint clientMask, void* UNU
|
||||
case NMT_Goto:
|
||||
ENTITY_POSITION(CGoto, ORDER_GOTO);
|
||||
break;
|
||||
case NMT_FormationGoto:
|
||||
ENTITY_POSITION_FORM(CFormationGoto, ORDER_GOTO);
|
||||
break;
|
||||
//TODO: make formation move to within range of target and then attack normally
|
||||
case NMT_FormationGeneric:
|
||||
ENTITY_ENTITY_INT(CFormationGeneric, ORDER_GENERIC);
|
||||
break;
|
||||
case NMT_Run:
|
||||
ENTITY_POSITION(CRun, ORDER_RUN);
|
||||
break;
|
||||
case NMT_Patrol:
|
||||
ENTITY_POSITION(CPatrol, ORDER_PATROL);
|
||||
break;
|
||||
case NMT_FormationGoto:
|
||||
ENTITY_POSITION_FORM(CFormationGoto, ORDER_GOTO);
|
||||
break;
|
||||
|
||||
//TODO: make formation move to within range of target and then attack normally
|
||||
case NMT_Generic:
|
||||
ENTITY_ENTITY_INT(CGeneric, ORDER_GENERIC);
|
||||
break;
|
||||
case NMT_Produce:
|
||||
ENTITY_INT_STRING(CProduce, ORDER_PRODUCE);
|
||||
case NMT_FormationGeneric:
|
||||
ENTITY_ENTITY_INT(CFormationGeneric, ORDER_GENERIC);
|
||||
break;
|
||||
case NMT_NotifyRequest:
|
||||
ENTITY_ENTITY_INT(CNotifyRequest, ORDER_NOTIFY_REQUEST);
|
||||
break;
|
||||
case NMT_Produce:
|
||||
ENTITY_INT_STRING(CProduce, ORDER_PRODUCE);
|
||||
break;
|
||||
case NMT_PlaceObject:
|
||||
{
|
||||
CPlaceObject *msg = (CPlaceObject *) pMsg;
|
||||
@@ -370,7 +349,7 @@ uint CSimulation::TranslateMessage(CNetMessage* pMsg, uint clientMask, void* UNU
|
||||
{
|
||||
// Order all the selected units to work on the new object using the given action
|
||||
order.m_type = CEntityOrder::ORDER_START_CONSTRUCTION;
|
||||
order.m_data[0].entity = newObj;
|
||||
order.m_new_obj = newObj;
|
||||
QueueOrder(order, msg->m_Entities, isQueued);
|
||||
}
|
||||
} while(0)
|
||||
|
||||
@@ -66,8 +66,8 @@ void CDefendStance::onDamaged(CEntity *source)
|
||||
if( ( range + m_Entity->m_los * CELL_SIZE ) >= m_Entity->distance2D( source ) )
|
||||
{
|
||||
CEntityOrder order( CEntityOrder::ORDER_GENERIC, CEntityOrder::SOURCE_UNIT_AI );
|
||||
order.m_data[0].entity = source->me;
|
||||
order.m_data[1].data = action;
|
||||
order.m_target_entity = source->me;
|
||||
order.m_action = action;
|
||||
m_Entity->pushOrder( order );
|
||||
}
|
||||
}
|
||||
@@ -119,7 +119,7 @@ bool CDefendStance::checkMovement( CVector2D proposedPos )
|
||||
{
|
||||
// Let's just walk back to our idle spot
|
||||
CEntityOrder order( CEntityOrder::ORDER_GOTO, CEntityOrder::SOURCE_UNIT_AI );
|
||||
order.m_data[0].location = idlePos;
|
||||
order.m_target_location = idlePos;
|
||||
m_Entity->pushOrder( order );
|
||||
}
|
||||
|
||||
@@ -139,8 +139,8 @@ void CStanceUtils::attack(CEntity* entity, CEntity* target)
|
||||
if( action )
|
||||
{
|
||||
CEntityOrder order( CEntityOrder::ORDER_GENERIC, CEntityOrder::SOURCE_UNIT_AI );
|
||||
order.m_data[0].entity = target->me;
|
||||
order.m_data[1].data = action;
|
||||
order.m_target_entity = target->me;
|
||||
order.m_action = action;
|
||||
entity->pushOrder( order );
|
||||
}
|
||||
}
|
||||
@@ -175,3 +175,4 @@ CEntity* CStanceUtils::chooseTarget( float x, float z, float radius, CPlayer* my
|
||||
return bestTarget;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user