From 4a40baef3375c1698bedb7d29173e2c153ef5f6f Mon Sep 17 00:00:00 2001 From: Matei Date: Thu, 29 Dec 2005 08:42:44 +0000 Subject: [PATCH] Generic orders source commit. Also includes a fix to the animation bug where one frame of "idle" is played at the end of each cycle, and an enhancement to the entity script loading code to only load each script file once, which should save loading time and also allow script files to behave in a more logical way (e.g. no redeclaration errors when you have a constant). This was SVN commit r3309. --- source/ps/GameSetup/GameSetup.cpp | 1 + source/ps/Interact.cpp | 22 ++++++++++++-- source/ps/Interact.h | 2 ++ source/ps/Network/AllNetMessages.h | 6 ++++ source/ps/Network/NetMessage.cpp | 22 ++++++++++++++ source/scripting/EventTypes.h | 2 ++ source/scripting/GameEvents.h | 26 +++++++++++------ source/simulation/BaseEntity.cpp | 15 ++++++---- source/simulation/BaseEntity.h | 4 +++ source/simulation/Entity.h | 13 +++++++++ source/simulation/EntityOrders.h | 4 ++- source/simulation/EntityStateProcessing.cpp | 32 ++++++++++++++++++--- source/simulation/EntitySupport.h | 5 +++- source/simulation/EventHandlers.cpp | 16 +++++++++-- source/simulation/EventHandlers.h | 23 +++++++++++---- source/simulation/PathfindEngine.cpp | 7 ++--- source/simulation/PathfindEngine.h | 4 ++- source/simulation/Simulation.cpp | 11 +++++++ 18 files changed, 180 insertions(+), 35 deletions(-) diff --git a/source/ps/GameSetup/GameSetup.cpp b/source/ps/GameSetup/GameSetup.cpp index c2139b8f2c..858ec045f3 100644 --- a/source/ps/GameSetup/GameSetup.cpp +++ b/source/ps/GameSetup/GameSetup.cpp @@ -491,6 +491,7 @@ static void InitScripting() g_ScriptingHost.DefineConstant( "ORDER_ATTACK", CEntityOrder::ORDER_ATTACK_MELEE ); g_ScriptingHost.DefineConstant( "ORDER_GATHER", CEntityOrder::ORDER_GATHER ); g_ScriptingHost.DefineConstant( "ORDER_HEAL", CEntityOrder::ORDER_HEAL ); + g_ScriptingHost.DefineConstant( "ORDER_GENERIC", CEntityOrder::ORDER_GENERIC ); #define REG_JS_CONSTANT(_name) g_ScriptingHost.DefineConstant(#_name, _name) REG_JS_CONSTANT(SDL_BUTTON_LEFT); diff --git a/source/ps/Interact.cpp b/source/ps/Interact.cpp index ddd563bb39..5eb974f6bd 100755 --- a/source/ps/Interact.cpp +++ b/source/ps/Interact.cpp @@ -411,6 +411,7 @@ void CSelectedEntities::update() const int numCommands=NMT_COMMAND_LAST - NMT_COMMAND_FIRST; int defaultPoll[numCommands]; std::map defaultCursor[numCommands]; + std::map defaultAction[numCommands]; int t, vote; for( t = 0; t < numCommands; t++ ) @@ -421,12 +422,13 @@ void CSelectedEntities::update() { CEventTargetChanged evt( g_Mouseover.m_target ); (*it)->DispatchEvent( &evt ); - vote = evt.m_defaultAction - NMT_COMMAND_FIRST; + vote = evt.m_defaultOrder - NMT_COMMAND_FIRST; if( ( vote >= 0 ) && ( vote < numCommands ) ) { defaultPoll[vote]++; defaultCursor[vote][evt.m_defaultCursor]++; + defaultAction[vote][evt.m_defaultAction]++; } } @@ -438,16 +440,30 @@ void CSelectedEntities::update() } std::map::iterator itv; + std::map::iterator iti; m_defaultCommand = vote + NMT_COMMAND_FIRST; // Now find the most appropriate cursor t = 0; for( itv = defaultCursor[vote].begin(); itv != defaultCursor[vote].end(); itv++ ) + { if( itv->second > t ) { t = itv->second; g_CursorName = itv->first; } + } + + // Find the most appropriate action parameter too + t = 0; + for( iti = defaultAction[vote].begin(); iti != defaultAction[vote].end(); iti++ ) + { + if( iti->second > t ) + { + t = iti->second; + m_defaultAction = iti->first; + } + } m_selectionChanged = false; g_Mouseover.m_targetChanged = false; @@ -767,7 +783,9 @@ void FireWorldClickEvent(uint button, int clicks) button, clicks, g_Selection.m_defaultCommand, - -1, // FIXME Secondary command, depends entity scripts etc + g_Selection.m_defaultAction, + -1, // FIXME Secondary order, depends entity scripts etc + -1, // FIXME Secondary action, depends entity scripts etc g_Mouseover.m_target, (uint)g_Mouseover.m_worldposition.x, (uint)g_Mouseover.m_worldposition.y); diff --git a/source/ps/Interact.h b/source/ps/Interact.h index dd3cffddca..2c76678e81 100755 --- a/source/ps/Interact.h +++ b/source/ps/Interact.h @@ -31,6 +31,7 @@ struct CSelectedEntities : public Singleton m_group = -1; m_group_highlight = -1; m_defaultCommand = -1; + m_defaultAction = -1; m_selectionChanged = true; } std::vector m_selected; @@ -38,6 +39,7 @@ struct CSelectedEntities : public Singleton i8 m_group, m_group_highlight; bool m_selectionChanged; int m_defaultCommand; + int m_defaultAction; void addSelection( HEntity entity ); void removeSelection( HEntity entity ); diff --git a/source/ps/Network/AllNetMessages.h b/source/ps/Network/AllNetMessages.h index 6985fbf165..274b2b1727 100755 --- a/source/ps/Network/AllNetMessages.h +++ b/source/ps/Network/AllNetMessages.h @@ -62,6 +62,7 @@ enum ENetMessageType NMT_AttackMelee, NMT_Gather, NMT_Heal, + NMT_Generic, NMT_COMMAND_LAST, /* Post-Game Stage */ @@ -234,6 +235,11 @@ DERIVE_NMT_CLASS_(NetCommand, Heal) NMT_FIELD(HEntity, m_Target) END_NMT_CLASS() +DERIVE_NMT_CLASS_(NetCommand, Generic) + NMT_FIELD(HEntity, m_Target) + NMT_FIELD_INT(m_Action, u32, 4) +END_NMT_CLASS() + END_NMTS() #else diff --git a/source/ps/Network/NetMessage.cpp b/source/ps/Network/NetMessage.cpp index c095b0802b..8b103bab4f 100755 --- a/source/ps/Network/NetMessage.cpp +++ b/source/ps/Network/NetMessage.cpp @@ -83,6 +83,7 @@ void CNetMessage::ScriptingInit() def(NMT_AttackMelee); def(NMT_Gather); def(NMT_Heal); + def(NMT_Generic); } CNetCommand *CNetMessage::CommandFromJSArgs(const CEntityList &entities, JSContext *cx, uintN argc, jsval *argv) @@ -133,6 +134,15 @@ CNetCommand *CNetMessage::CommandFromJSArgs(const CEntityList &entities, JSConte } \ _msg->_field=ent->me; \ ) + #define ReadInt(_msg, _field) \ + STMT(\ + if (argIndex+1 > argc) \ + ArgumentCountError(); \ + if (!JSVAL_IS_INT(argv[argIndex])) \ + ArgumentTypeError(); \ + int val=ToPrimitive(argv[argIndex++]); \ + _msg->_field=val; \ + ) #define PositionMessage(_msg) \ case NMT_ ## _msg: \ @@ -151,6 +161,16 @@ CNetCommand *CNetMessage::CommandFromJSArgs(const CEntityList &entities, JSConte ReadEntity(msg, m_Target); \ return msg; \ } + + #define EntityIntMessage(_msg) \ + case NMT_ ## _msg: \ + { \ + C##_msg *msg = new C##_msg(); \ + msg->m_Entities = entities; \ + ReadEntity(msg, m_Target); \ + ReadInt(msg, m_Action); \ + return msg; \ + } // argIndex, incremented by reading macros. We have already "eaten" the // first argument (message type) @@ -166,6 +186,8 @@ CNetCommand *CNetMessage::CommandFromJSArgs(const CEntityList &entities, JSConte EntityMessage(Gather) EntityMessage(Heal) + EntityIntMessage(Generic) + default: JS_ReportError(cx, "Invalid order type"); return NULL; diff --git a/source/scripting/EventTypes.h b/source/scripting/EventTypes.h index 6a67ecc3d6..af8c333ee5 100644 --- a/source/scripting/EventTypes.h +++ b/source/scripting/EventTypes.h @@ -16,6 +16,7 @@ enum EEventType EVENT_GATHER, EVENT_DAMAGE, EVENT_HEAL, + EVENT_GENERIC, EVENT_TARGET_CHANGED, EVENT_PREPARE_ORDER, EVENT_ORDER_TRANSITION, @@ -41,6 +42,7 @@ static const wchar_t* const EventNames[EVENT_LAST] = /* EVENT_GATHER */ L"onGather", /* This unit is the one doing the gathering... */ /* EVENT_DAMAGE */ L"onTakesDamage", /* EVENT_HEAL */ L"onHeal", + /* EVENT_GENERIC */ L"onGeneric", /* EVENT_TARGET_CHANGED */ L"onTargetChanged", /* If this unit is selected and the mouseover object changes */ /* EVENT_PREPARE_ORDER */ L"onPrepareOrder", /* To check if a unit can execute a given order */ /* EVENT_ORDER_TRANSITION */ L"onOrderTransition" /* When we change orders (sometimes...) */ diff --git a/source/scripting/GameEvents.h b/source/scripting/GameEvents.h index c7f60b537d..9eb8ea7a56 100644 --- a/source/scripting/GameEvents.h +++ b/source/scripting/GameEvents.h @@ -33,25 +33,32 @@ class CGameEvents : public IEventTarget, public Singleton { int m_Button; int m_Clicks; - int m_Command; - int m_SecondaryCommand; + int m_Order; + int m_Action; + int m_SecondaryOrder; + int m_SecondaryAction; CEntity *m_Entity; uint m_X, m_Y; public: - CEventWorldClick(int button, int clicks, int command, int secCommand, CEntity *ent, uint x, uint y): + CEventWorldClick(int button, int clicks, int order, int action, + int secOrder, int secAction, CEntity *ent, uint x, uint y): CScriptEvent(L"worldClick", EVENT_WORLD_CLICK, false), m_Button(button), m_Clicks(clicks), - m_Command(command), - m_SecondaryCommand(secCommand), + m_Order(order), + m_Action(action), + m_SecondaryOrder(secOrder), + m_SecondaryAction(secAction), m_Entity(ent), m_X(x), m_Y(y) { AddLocalProperty(L"button", &m_Button); AddLocalProperty(L"clicks", &m_Clicks); - AddLocalProperty(L"command", &m_Command); - AddLocalProperty(L"secondaryCommand", &m_SecondaryCommand); + AddLocalProperty(L"order", &m_Order); + AddLocalProperty(L"action", &m_Action); + AddLocalProperty(L"secondaryOrder", &m_SecondaryOrder); + AddLocalProperty(L"secondaryAction", &m_SecondaryAction); if (ent) AddLocalProperty(L"entity", &m_Entity); else @@ -68,9 +75,10 @@ public: DispatchEvent( &evt ); } - void FireWorldClick(int button, int clicks, int command, int secCommand, CEntity *ent, uint x, uint y) + void FireWorldClick(int button, int clicks, int order, int action, + int secOrder, int secAction, CEntity *ent, uint x, uint y) { - CEventWorldClick evt(button, clicks, command, secCommand, ent, x, y); + CEventWorldClick evt(button, clicks, order, action, secOrder, secAction, ent, x, y); DispatchEvent(&evt); } }; diff --git a/source/simulation/BaseEntity.cpp b/source/simulation/BaseEntity.cpp index 8591a42f78..f1d52c6af8 100755 --- a/source/simulation/BaseEntity.cpp +++ b/source/simulation/BaseEntity.cpp @@ -9,6 +9,8 @@ #include "CLogger.h" #define LOG_CATEGORY "entity" +STL_HASH_SET CBaseEntity::scriptsLoaded; + CBaseEntity::CBaseEntity() { m_base = NULL; @@ -204,14 +206,17 @@ bool CBaseEntity::loadXML( CStr filename ) { CStr Include = Child.getAttributes().getNamedItem( at_file ); - // TODO: Probably try and determine if this file has already been loaded, and skip it. - - if( Include.Length() ) - g_ScriptingHost.RunScript(Include); + if( Include.Length() && scriptsLoaded.find( Include ) == scriptsLoaded.end() ) + { + scriptsLoaded.insert( Include ); + g_ScriptingHost.RunScript( Include ); + } CStr Inline = Child.getText(); if( Inline.Length() ) - g_ScriptingHost.RunMemScript(Inline.c_str(), Inline.Length(), filename.c_str(), Child.getLineNumber()); + { + g_ScriptingHost.RunMemScript( Inline.c_str(), Inline.Length(), filename.c_str(), Child.getLineNumber() ); + } } else if (ChildName == el_traits) { diff --git a/source/simulation/BaseEntity.h b/source/simulation/BaseEntity.h index 1214a4a8f6..1d2c32089e 100755 --- a/source/simulation/BaseEntity.h +++ b/source/simulation/BaseEntity.h @@ -75,9 +75,11 @@ public: bool m_permanent; float m_speed; + SEntityAction m_melee; SEntityAction m_gather; SEntityAction m_heal; + SEntityAction m_generic; float m_turningRadius; CScriptObject m_EventHandlers[EVENT_LAST]; @@ -100,6 +102,8 @@ private: // squelch "unable to generate" warnings CBaseEntity(const CBaseEntity& rhs); const CBaseEntity& operator=(const CBaseEntity& rhs); + + static STL_HASH_SET scriptsLoaded; }; #endif diff --git a/source/simulation/Entity.h b/source/simulation/Entity.h index d2eb5d18a9..6868080238 100755 --- a/source/simulation/Entity.h +++ b/source/simulation/Entity.h @@ -53,6 +53,7 @@ class CEntity : public CJSComplex, public IEventTarget friend class CEntityManager; typedef STL_HASH_MAP AuraTable; + typedef STL_HASH_MAP ActionTable; typedef std::set AuraSet; private: @@ -71,9 +72,13 @@ public: float m_speed; float m_turningRadius; + SEntityAction m_melee; SEntityAction m_gather; SEntityAction m_heal; + + ActionTable m_actions; + bool m_selected; i32 m_grouped; @@ -161,13 +166,19 @@ private: bool processAttackMelee( CEntityOrder* current, size_t timestep_milli ); bool processAttackMeleeNoPathing( CEntityOrder* current, size_t timestep_milli ); + bool processGather( CEntityOrder* current, size_t timestep_milli ); bool processGatherNoPathing( CEntityOrder* current, size_t timestep_milli ); + bool processHeal( CEntityOrder* current, size_t timestep_milli ); bool processHealNoPathing( CEntityOrder* current, size_t timestep_milli ); + + bool processGeneric( CEntityOrder* current, size_t timestep_milli ); + bool processGenericNoPathing( CEntityOrder* current, size_t timestep_milli ); bool processGotoNoPathing( CEntityOrder* current, size_t timestep_milli ); bool processGoto( CEntityOrder* current, size_t timestep_milli ); + bool processPatrol( CEntityOrder* current, size_t timestep_milli ); public: @@ -262,6 +273,8 @@ public: jsval AddAura( JSContext* cx, uintN argc, jsval* argv ); jsval RemoveAura( JSContext* cx, uintN argc, jsval* argv ); + jsval SetActionParams( 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 ) { diff --git a/source/simulation/EntityOrders.h b/source/simulation/EntityOrders.h index 6d81f799d8..af073022b4 100755 --- a/source/simulation/EntityOrders.h +++ b/source/simulation/EntityOrders.h @@ -34,7 +34,7 @@ #ifndef ENTITY_ORDER_INCLUDED #define ENTITY_ORDER_INCLUDED -#define ORDER_MAX_DATA 1 +#define ORDER_MAX_DATA 2 #include "EntityHandles.h" #include "Vector2D.h" @@ -63,6 +63,8 @@ public: ORDER_HEAL, ORDER_HEAL_NOPATHING, ORDER_PATH_END_MARKER, + ORDER_GENERIC, + ORDER_GENERIC_NOPATHING, ORDER_LAST } m_type; SOrderData m_data[ORDER_MAX_DATA]; diff --git a/source/simulation/EntityStateProcessing.cpp b/source/simulation/EntityStateProcessing.cpp index 8c78c06016..df9f4afa7d 100755 --- a/source/simulation/EntityStateProcessing.cpp +++ b/source/simulation/EntityStateProcessing.cpp @@ -284,6 +284,7 @@ bool CEntity::processContactAction( CEntityOrder* current, size_t UNUSED(timeste if( ( current->m_data[0].location - m_position ).length() < action->m_MaxRange ) { (int&)current->m_type = transition; + m_orderQueue.push_front(*current); // Seems to be needed since we do a pop above return( true ); } @@ -295,9 +296,10 @@ bool CEntity::processContactAction( CEntityOrder* current, size_t UNUSED(timeste m_actor->GetModel()->Update( ( rand() * 1000.0f ) / 1000.0f ); } - // The pathfinder will push its result back into this unit's queue. - - g_Pathfinder.requestContactPath( me, current->m_data[0].entity, transition ); + // The pathfinder will push its result back into this unit's queue and + // add back the current order at the end with the transition type. + (int&)current->m_type = transition; + g_Pathfinder.requestContactPath( me, current ); return( true ); } @@ -314,7 +316,7 @@ bool CEntity::processContactActionNoPathing( CEntityOrder* current, size_t times // few hundred ms, at the 'action point' of the animation we're // now setting. - m_actor->GetModel()->SetAnimation( m_fsm_animation, true, 1000.0f * m_fsm_animation->m_AnimDef->GetDuration() / (float)action->m_Speed, m_actor->GetRandomAnimation( "idle" ) ); + m_actor->GetModel()->SetAnimation( m_fsm_animation, true, 1000.0f * m_fsm_animation->m_AnimDef->GetDuration() / (float)action->m_Speed, m_fsm_animation ); } if( ( m_fsm_cyclepos <= m_fsm_anipos2 ) && ( nextpos > m_fsm_anipos2 ) ) @@ -487,6 +489,7 @@ bool CEntity::processAttackMelee( CEntityOrder* current, size_t timestep_millis { return( processContactAction( current, timestep_millis, CEntityOrder::ORDER_ATTACK_MELEE_NOPATHING, &m_melee ) ); } + bool CEntity::processAttackMeleeNoPathing( CEntityOrder* current, size_t timestep_milli ) { CEventAttack evt( current->m_data[0].entity ); @@ -505,16 +508,37 @@ bool CEntity::processGatherNoPathing( CEntityOrder* current, size_t timestep_mil if( !m_actor ) return( false ); return( processContactActionNoPathing( current, timestep_millis, "gather", &evt, &m_gather ) ); } + bool CEntity::processHeal( CEntityOrder* current, size_t timestep_millis ) { return( processContactAction( current, timestep_millis, CEntityOrder::ORDER_HEAL_NOPATHING, &m_heal ) ); } + bool CEntity::processHealNoPathing( CEntityOrder* current, size_t timestep_millis ) { CEventHeal evt( current->m_data[0].entity ); if( !m_actor ) return( false ); return( processContactActionNoPathing( current, timestep_millis, "heal", &evt, &m_heal ) ); } + +bool CEntity::processGeneric( CEntityOrder* current, size_t timestep_millis ) +{ + int id = current->m_data[1].data; + debug_assert( m_actions.find( id ) != m_actions.end() ); + SEntityAction& action = m_actions[id]; + return( processContactAction( current, timestep_millis, CEntityOrder::ORDER_GENERIC_NOPATHING, &action ) ); +} + +bool CEntity::processGenericNoPathing( CEntityOrder* current, size_t timestep_millis ) +{ + int id = current->m_data[1].data; + debug_assert( m_actions.find( id ) != m_actions.end() ); + SEntityAction& action = m_actions[id]; + CEventGeneric evt( current->m_data[0].entity, id ); + if( !m_actor ) return( false ); + return( processContactActionNoPathing( current, timestep_millis, action.m_Animation, &evt, &action ) ); +} + bool CEntity::processGoto( CEntityOrder* current, size_t UNUSED(timestep_millis) ) { // float timestep=timestep_millis/1000.0f; diff --git a/source/simulation/EntitySupport.h b/source/simulation/EntitySupport.h index f64730153e..cadc214884 100755 --- a/source/simulation/EntitySupport.h +++ b/source/simulation/EntitySupport.h @@ -80,7 +80,10 @@ struct SEntityAction float m_MaxRange; float m_MinRange; size_t m_Speed; - SEntityAction() { m_MaxRange = m_MinRange = 0.0f; m_Speed = 1000; } + CStr8 m_Animation; + SEntityAction() { m_MaxRange = m_MinRange = 0.0f; m_Speed = 1000; m_Animation = "walk"; } + SEntityAction(float minRange, float maxRange, size_t speed, CStr8& animation) + : m_MinRange(minRange), m_MaxRange(maxRange), m_Speed(speed), m_Animation(animation) {} }; struct SClassSet diff --git a/source/simulation/EventHandlers.cpp b/source/simulation/EventHandlers.cpp index adb0eec1cf..ed6ff7531c 100755 --- a/source/simulation/EventHandlers.cpp +++ b/source/simulation/EventHandlers.cpp @@ -7,15 +7,25 @@ CEventAttack::CEventAttack( CEntity* target ) : CScriptEvent( L"attack", EVENT_A m_target = target; AddLocalProperty( L"target", &m_target ); } + +CEventGather::CEventGather( CEntity* target ) : CScriptEvent( L"gather", EVENT_GATHER, true ) +{ + m_target = target; + AddLocalProperty( L"target", &m_target ); +} + CEventHeal::CEventHeal( CEntity* target ) : CScriptEvent( L"heal", EVENT_HEAL, true) { m_target = target; AddLocalProperty( L"target", &m_target ); } -CEventGather::CEventGather( CEntity* target ) : CScriptEvent( L"gather", EVENT_GATHER, true ) + +CEventGeneric::CEventGeneric( CEntity* target, int action ) : CScriptEvent( L"generic", EVENT_GENERIC, true) { m_target = target; + m_action = action; AddLocalProperty( L"target", &m_target ); + AddLocalProperty( L"action", &m_action ); } CEventDamage::CEventDamage( CEntity* inflictor, CDamageType* damage ) : CScriptEvent( L"takesDamage", EVENT_DAMAGE, true ) @@ -29,9 +39,11 @@ CEventDamage::CEventDamage( CEntity* inflictor, CDamageType* damage ) : CScriptE CEventTargetChanged::CEventTargetChanged( CEntity* target ) : CScriptEvent( L"targetChanged", EVENT_TARGET_CHANGED, false ) { m_target = target; - m_defaultAction = -1; + m_defaultOrder = -1; + m_defaultAction = 0; m_defaultCursor = L"arrow-default"; AddLocalProperty( L"target", &m_target, true ); + AddLocalProperty( L"defaultOrder", &m_defaultOrder ); AddLocalProperty( L"defaultAction", &m_defaultAction ); AddLocalProperty( L"defaultCursor", &m_defaultCursor ); } diff --git a/source/simulation/EventHandlers.h b/source/simulation/EventHandlers.h index 67ed07cee8..942f2da882 100755 --- a/source/simulation/EventHandlers.h +++ b/source/simulation/EventHandlers.h @@ -35,12 +35,7 @@ class CEventGather : public CScriptEvent public: CEventGather( CEntity* target ); }; -class CEventHeal : public CScriptEvent -{ - CEntity* m_target; -public: - CEventHeal( CEntity* target ); -}; + class CEventDamage : public CScriptEvent { CEntity* m_inflictor; @@ -49,10 +44,26 @@ public: CEventDamage( CEntity* inflictor, CDamageType* damage ); }; +class CEventHeal : public CScriptEvent +{ + CEntity* m_target; +public: + CEventHeal( CEntity* target ); +}; + +class CEventGeneric : public CScriptEvent +{ + CEntity* m_target; + int m_action; +public: + CEventGeneric( CEntity* target, int m_action ); +}; + class CEventTargetChanged : public CScriptEvent { CEntity* m_target; public: + int m_defaultOrder; int m_defaultAction; CStrW m_defaultCursor; CEventTargetChanged( CEntity* target ); diff --git a/source/simulation/PathfindEngine.cpp b/source/simulation/PathfindEngine.cpp index 4d862c05d1..9c53cb1861 100755 --- a/source/simulation/PathfindEngine.cpp +++ b/source/simulation/PathfindEngine.cpp @@ -16,9 +16,9 @@ void CPathfindEngine::requestPath( HEntity entity, const CVector2D& destination pathSparse( entity, destination ); } -void CPathfindEngine::requestContactPath( HEntity entity, HEntity target, int transition ) +void CPathfindEngine::requestContactPath( HEntity entity, CEntityOrder* current ) { - pathSparse( entity, target->m_position ); + pathSparse( entity, current->m_data[0].entity->m_position ); // For attack orders, do some additional postprocessing (replace goto/nopathing // with attack/nopathing, up until the attack order marker) std::deque::iterator it; @@ -28,8 +28,7 @@ void CPathfindEngine::requestContactPath( HEntity entity, HEntity target, int tr break; if( it->m_type == CEntityOrder::ORDER_GOTO_NOPATHING ) { - (int&)it->m_type = transition; - it->m_data[0].entity = target; + *it = *current; } } } diff --git a/source/simulation/PathfindEngine.h b/source/simulation/PathfindEngine.h index 575cde0d9f..8468bbeee5 100755 --- a/source/simulation/PathfindEngine.h +++ b/source/simulation/PathfindEngine.h @@ -17,6 +17,8 @@ #define g_Pathfinder CPathfindEngine::GetSingleton() +class CEntityOrder; + enum EPathType { PF_STANDARD, @@ -28,7 +30,7 @@ class CPathfindEngine : public Singleton public: CPathfindEngine(); void requestPath( HEntity entity, const CVector2D& destination ); - void requestContactPath( HEntity entity, HEntity target, int transition ); + void requestContactPath( HEntity entity, CEntityOrder* current ); }; #endif diff --git a/source/simulation/Simulation.cpp b/source/simulation/Simulation.cpp index aa92108a82..56e0e6631a 100755 --- a/source/simulation/Simulation.cpp +++ b/source/simulation/Simulation.cpp @@ -216,6 +216,14 @@ uint CSimulation::TranslateMessage(CNetMessage* pMsg, uint clientMask, void* UNU order.m_data[0].entity=msg->m_Target; \ QueueOrder(order, msg->m_Entities, clearQueue); \ } while(0) +#define ENTITY_ENTITY_INT(_msg, _order) do\ + { \ + _msg *msg=(_msg *)pMsg; \ + order.m_type=CEntityOrder::_order; \ + order.m_data[0].entity=msg->m_Target; \ + order.m_data[1].data=msg->m_Action; \ + QueueOrder(order, msg->m_Entities, clearQueue); \ + } while(0) switch (pMsg->GetType()) { @@ -267,6 +275,9 @@ uint CSimulation::TranslateMessage(CNetMessage* pMsg, uint clientMask, void* UNU case NMT_Heal: ENTITY_ENTITY(CHeal, ORDER_HEAL); break; + case NMT_Generic: + ENTITY_ENTITY_INT(CGeneric, ORDER_GENERIC); + break; } return clientMask;