1
0
forked from mirrors/0ad

# Order system refactoring.

This was SVN commit r4716.
This commit is contained in:
Matei
2006-12-21 14:57:13 +00:00
parent 805981519e
commit d672674bc6
12 changed files with 151 additions and 142 deletions
+8 -8
View File
@@ -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();
}
+1 -1
View File
@@ -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;
+3
View File
@@ -105,4 +105,7 @@ struct CEntityList: public std::vector<HEntity>
operator CStr8() const;
};
typedef CEntityList::iterator CEntityIt;
typedef CEntityList::const_iterator CEntityCIt;
#endif
+33 -3
View File
@@ -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
+7 -6
View File
@@ -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();
}
+6 -6
View File
@@ -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 )
{
+29 -34
View File
@@ -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*)&current->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 );
}
+4 -4
View File
@@ -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 );
+15 -15
View File
@@ -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;
}
+3 -3
View File
@@ -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 );
}
}
+36 -57
View File
@@ -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)
+6 -5
View File
@@ -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;
}