diff --git a/source/scripting/EventTypes.h b/source/scripting/EventTypes.h index 242cf24e7b..532ce206ff 100644 --- a/source/scripting/EventTypes.h +++ b/source/scripting/EventTypes.h @@ -14,6 +14,7 @@ enum EEventType EVENT_DEATH, EVENT_TICK, EVENT_GENERIC, + EVENT_TARGET_EXHAUSTED, EVENT_START_CONSTRUCTION, EVENT_START_PRODUCTION, EVENT_CANCEL_PRODUCTION, @@ -43,7 +44,8 @@ static const wchar_t* const EventNames[EVENT_LAST] = /* EVENT_INITIALIZE */ L"onInitialize", /* EVENT_DEATH */ L"onDeath", /* EVENT_TICK */ L"onTick", - /* EVENT_GENERIC */ L"onGeneric", /* For generic actions on a target unit, like attack or gather */ + /* EVENT_GENERIC */ L"onGeneric", /* For generic contact actions on a target unit, like attack or gather */ + /* EVENT_TARGET_EXHAUSTED*/ L"onTargetExhausted", /* Called when the target of a generic action dies */ /* EVENT_START_CONSTRUCTION */ L"onStartConstruction", /* We were selected when the user placed a building */ /* EVENT_START_PRODUCTION */ L"onStartProduction", /* We're about to start training/researching something (deduct resources, etc) */ /* EVENT_CANCEL_PRODUCTION */ L"onCancelProduction", /* Something in production has been cancelled */ diff --git a/source/simulation/Entity.h b/source/simulation/Entity.h index 765924ab0d..c305c5c4a0 100644 --- a/source/simulation/Entity.h +++ b/source/simulation/Entity.h @@ -411,6 +411,10 @@ public: jsval OnDamaged( JSContext* cx, uintN argc, jsval* argv ); + jsval GetVisibleEntities( JSContext* cx, uintN argc, jsval* argv ); + + float GetDistance( JSContext* cx, uintN argc, jsval* argv ); + bool RequestNotification( JSContext* cx, uintN argc, jsval* argv ); //Just in case we want to explicitly check the listeners without waiting for the order to be pushed bool ForceCheckListeners( JSContext* cx, uintN argc, jsval* argv ); @@ -447,6 +451,7 @@ public: debug_assert( argc >= 1 ); return( m_classes.IsMember( ToPrimitive( cx, argv[0] ) ) ); } + jsval TerminateOrder( JSContext* UNUSED(cx), uintN argc, jsval* argv ) { debug_assert( argc >= 1); @@ -456,10 +461,12 @@ public: m_orderQueue.pop_front(); return JSVAL_VOID; } + jsval GetHeight( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) ) { return ToJSVal(m_position.Y); } + static void ScriptingInit(); // Functions that call script code diff --git a/source/simulation/EntityScriptInterface.cpp b/source/simulation/EntityScriptInterface.cpp index c21597125c..c84d560d7d 100644 --- a/source/simulation/EntityScriptInterface.cpp +++ b/source/simulation/EntityScriptInterface.cpp @@ -14,6 +14,7 @@ #include "renderer/Renderer.h" #include "renderer/WaterManager.h" #include "scripting/ScriptableComplex.inl" +#include "ps/scripting/JSCollection.h" #include "Aura.h" #include "Collision.h" @@ -80,6 +81,8 @@ void CEntity::ScriptingInit() AddMethod( "setRallyPoint", 0 ); AddMethod( "getRallyPoint", 0 ); AddMethod( "onDamaged", 1 ); + AddMethod( "getVisibleEntities", 0 ); + AddMethod( "getDistance", 1 ); AddClassProperty( L"traits.id.classes", (GetFn)&CEntity::getClassSet, (SetFn)&CEntity::setClassSet ); AddClassProperty( L"template", (CEntityTemplate* CEntity::*)&CEntity::m_base, false, (NotifyFn)&CEntity::loadBase ); @@ -593,7 +596,7 @@ jsval CEntity::SetActionParams( JSContext* UNUSED(cx), uintN argc, jsval* argv ) uint speed = ToPrimitive( argv[3] ); CStr8 animation = ToPrimitive( argv[4] ); - m_actions[id] = SEntityAction( minRange, maxRange, speed, animation ); + m_actions[id] = SEntityAction( id, minRange, maxRange, speed, animation ); return JSVAL_VOID; } @@ -860,6 +863,7 @@ jsval CEntity::SetRallyPoint( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* return JS_TRUE; } +// Called by the script when the entity is damaged, to let it retaliate jsval CEntity::OnDamaged( JSContext* cx, uintN argc, jsval* argv ) { JSU_REQUIRE_PARAMS_CPP(1); @@ -868,6 +872,25 @@ jsval CEntity::OnDamaged( JSContext* cx, uintN argc, jsval* argv ) return JSVAL_VOID; } +jsval CEntity::GetVisibleEntities( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) ) +{ + std::vector pointers; + g_EntityManager.GetInLOS( this, pointers ); + std::vector handles( pointers.size() ); + for( size_t i=0; ime; + return OBJECT_TO_JSVAL( EntityCollection::Create( handles ) ); +} + +float CEntity::GetDistance( JSContext* cx, uintN argc, jsval* argv ) +{ + JSU_REQUIRE_PARAMS_CPP(1); + CEntity* target = ToNative( argv[0] ); + if( !target ) + return -1.0f; + return this->distance2D( target ); +} + /* Methods that provide an interface from C++ to JavaScript functions. diff --git a/source/simulation/EntityStateProcessing.cpp b/source/simulation/EntityStateProcessing.cpp index fa169b1e65..adc7b0f3aa 100644 --- a/source/simulation/EntityStateProcessing.cpp +++ b/source/simulation/EntityStateProcessing.cpp @@ -365,10 +365,21 @@ bool CEntity::processContactAction( CEntityOrder* current, size_t UNUSED(timeste HEntity target = current->m_data[0].entity; if( !target || !target->m_extant ) - return( false ); + { + popOrder(); + if( m_orderQueue.empty() && target ) + { + CEventTargetExhausted evt( target, action->m_Id ); + DispatchEvent( &evt ); + } + return false; + } if( g_Game->GetWorld()->GetLOSManager()->GetUnitStatus( target, m_player ) == UNIT_HIDDEN ) + { + popOrder(); return false; + } current->m_data[0].location = target->m_position; float Distance = distance2D(current->m_data[0].location); @@ -431,11 +442,16 @@ bool CEntity::processContactActionNoPathing( CEntityOrder* current, size_t times if(!DispatchEvent( contactEvent )) { // Cancel current order - popOrder(); entf_clear(ENTF_IS_RUNNING); entf_clear(ENTF_SHOULD_RUN); m_actor->SetEntitySelection( "idle" ); m_actor->SetRandomAnimation( "idle" ); + popOrder(); + if( m_orderQueue.empty() && target ) + { + CEventTargetExhausted evt( target, action->m_Id ); + DispatchEvent( &evt ); + } return( false ); } } @@ -456,10 +472,13 @@ bool CEntity::processContactActionNoPathing( CEntityOrder* current, size_t times if( !target || !target->m_extant || g_Game->GetWorld()->GetLOSManager()->GetUnitStatus( target, m_player ) == UNIT_HIDDEN ) { - //TODO: eventually when stances/formations are implemented, if applicable (e.g. not - //heal or if defensive stance), the unit should expand and continue the order. - popOrder(); + if( m_orderQueue.empty() && target ) + { + CEventTargetExhausted evt( target, action->m_Id ); + DispatchEvent( &evt ); + } + entf_clear(ENTF_IS_RUNNING); entf_clear(ENTF_SHOULD_RUN); return( false ); diff --git a/source/simulation/EntitySupport.h b/source/simulation/EntitySupport.h index b9106bc416..b55df80816 100644 --- a/source/simulation/EntitySupport.h +++ b/source/simulation/EntitySupport.h @@ -11,13 +11,15 @@ class CEntityManager; struct SEntityAction { + int m_Id; float m_MaxRange; float m_MinRange; size_t m_Speed; 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) {} + SEntityAction() + : m_Id(0), m_MinRange(0), m_MaxRange(0), m_Speed(1000), m_Animation("walk") {} + SEntityAction(int id, float minRange, float maxRange, size_t speed, CStr8& animation) + : m_Id(id), m_MinRange(minRange), m_MaxRange(maxRange), m_Speed(speed), m_Animation(animation) {} }; class CClassSet diff --git a/source/simulation/EventHandlers.cpp b/source/simulation/EventHandlers.cpp index 8a796d7046..53bdc0c471 100644 --- a/source/simulation/EventHandlers.cpp +++ b/source/simulation/EventHandlers.cpp @@ -10,6 +10,14 @@ CEventGeneric::CEventGeneric( CEntity* target, int action ) : CScriptEvent( L"ge AddLocalProperty( L"action", &m_action ); } +CEventTargetExhausted::CEventTargetExhausted( CEntity* target, int action ) : CScriptEvent( L"TargetExhausted", EVENT_TARGET_EXHAUSTED, true) +{ + m_target = target; + m_action = action; + AddLocalProperty( L"target", &m_target ); + AddLocalProperty( L"action", &m_action ); +} + CEventStartConstruction::CEventStartConstruction( CEntity* target ) : CScriptEvent( L"startConstruction", EVENT_START_CONSTRUCTION, true) { m_target = target; diff --git a/source/simulation/EventHandlers.h b/source/simulation/EventHandlers.h index fa85f1fd99..facdd90027 100644 --- a/source/simulation/EventHandlers.h +++ b/source/simulation/EventHandlers.h @@ -35,6 +35,14 @@ public: CEventGeneric( CEntity* target, int action ); }; +class CEventTargetExhausted : public CScriptEvent +{ + CEntity* m_target; + int m_action; +public: + CEventTargetExhausted( CEntity* target, int action ); +}; + class CEventStartConstruction : public CScriptEvent { CEntity* m_target;