Browse Source

new trigger features: triponce, tripcondition, and trippedby.
once fires off callbacks one time,
condition lets you plug in an a==b, or method that returns a true/false;
trippedby lets us plug in things like $TypeMasks::PlayerObjectType ( https://github.com/TorqueGameEngines/Torque3D/blob/ac395775439985cc7332e777485d252055bdb042/Engine/source/T3D/gameFunctions.cpp#L658 ) so that *only* players can trigger it

AzaezelX 5 years ago
parent
commit
91ff953c19
2 changed files with 99 additions and 11 deletions
  1. 76 10
      Engine/source/T3D/trigger.cpp
  2. 23 1
      Engine/source/T3D/trigger.h

+ 76 - 10
Engine/source/T3D/trigger.cpp

@@ -170,6 +170,9 @@ Trigger::Trigger()
    mConvexList = new Convex;
 
    mPhysicsRep = NULL;
+   mTripOnce = false;
+   mTrippedBy = 0xFFFFFFFF;
+   mTripCondition = "";
 }
 
 Trigger::~Trigger()
@@ -361,6 +364,9 @@ void Trigger::initPersistFields()
       "trigger area.  The quadrilateral is defined as a corner point followed by three vectors "
       "representing the edges extending from the corner.\n");
 
+   addField("TripOnce", TypeBool, Offset(mTripOnce, Trigger),"Do we trigger callacks just the once?");
+   addField("TripCondition", TypeRealString, Offset(mTripCondition, Trigger),"evaluation condition to trip callbacks (true/false)");
+   addField("TrippedBy", TypeS32, Offset(mTrippedBy, Trigger), "typemask filter");
    addProtectedField("enterCommand", TypeCommand, Offset(mEnterCommand, Trigger), &setEnterCmd, &defaultProtectedGetFn,
       "The command to execute when an object enters this trigger. Object id stored in %%obj. Maximum 1023 characters." );
    addProtectedField("leaveCommand", TypeCommand, Offset(mLeaveCommand, Trigger), &setLeaveCmd, &defaultProtectedGetFn,
@@ -396,7 +402,7 @@ void Trigger::testObjects()
    Vector<SceneObject*> foundobjs;
    foundobjs.clear();
    if (getSceneManager() && getSceneManager()->getContainer() && getSceneManager()->getZoneManager())
-      getSceneManager()->getContainer()->findObjectList(getWorldBox(), 0xFFFFFFFF, &foundobjs);
+      getSceneManager()->getContainer()->findObjectList(getWorldBox(), mTrippedBy, &foundobjs);
    else return;
 
    for (S32 i = 0; i < foundobjs.size(); i++)
@@ -418,7 +424,7 @@ bool Trigger::onAdd()
 
    Polyhedron temp = mTriggerPolyhedron;
    setTriggerPolyhedron(temp);
-
+   mTripped = false;
    addToScene();
 
    if (isServerObject())
@@ -517,7 +523,6 @@ void Trigger::buildConvex(const Box3F& box, Convex* convex)
    cp->mSize.z = mObjBox.len_z() / 2.0f;
 }
 
-
 //------------------------------------------------------------------------------
 
 void Trigger::setTransform(const MatrixF & mat)
@@ -655,6 +660,9 @@ bool Trigger::testObject(GameBase* enter)
    if (mTriggerPolyhedron.mPointList.size() == 0)
       return false;
 
+   if (!(enter->getTypeMask() & mTrippedBy))
+      return false; //not the right type of object
+   
    mClippedList.clear();
 
    SphereF sphere;
@@ -666,6 +674,39 @@ bool Trigger::testObject(GameBase* enter)
    return mClippedList.isEmpty() == false;
 }
 
+bool Trigger::testTrippable()
+{
+   if ((mTripOnce == true) && (mTripped == true))
+      return false; // we've already fired the once
+   return true;
+}
+
+bool Trigger::testCondition()
+{
+   if (mTripCondition.isEmpty())
+      return true; //we've got no tests to run so just do it
+
+   //test the mapper plugged in condition line
+   String resVar = getIdString() + String(".result");
+   Con::setBoolVariable(resVar.c_str(), false);
+   String command = resVar + "=" + mTripCondition + ";";
+   Con::evaluatef(command.c_str());
+   if (Con::getBoolVariable(resVar.c_str()) == 1)
+   {
+      return true;
+   }
+   return false;
+}
+
+bool Trigger::evalCmD(String* cmd)
+{
+   if (!testTrippable()) return false;
+   if (cmd && cmd->isNotEmpty())//do we have a callback?
+   {
+      return testCondition();
+   }
+   return false;
+}
 
 void Trigger::potentialEnterObject(GameBase* enter)
 {
@@ -683,14 +724,15 @@ void Trigger::potentialEnterObject(GameBase* enter)
       mObjects.push_back(enter);
       deleteNotify(enter);
 
-      if(!mEnterCommand.isEmpty())
+      if(evalCmD(&mEnterCommand))
       {
          String command = String("%obj = ") + enter->getIdString() + ";" + mEnterCommand;
          Con::evaluate(command.c_str());
       }
 
-      if( mDataBlock )
+      if( mDataBlock && testTrippable() && testCondition())
          mDataBlock->onEnterTrigger_callback( this, enter );
+      mTripped = true;
    }
 }
 
@@ -730,20 +772,21 @@ void Trigger::processTick(const Move* move)
             mObjects.erase(i);
             clearNotify(remove);
             
-            if (!mLeaveCommand.isEmpty())
+            if (evalCmD(&mLeaveCommand))
             {
                String command = String("%obj = ") + remove->getIdString() + ";" + mLeaveCommand;
                Con::evaluate(command.c_str());
             }
-
-            mDataBlock->onLeaveTrigger_callback( this, remove );
+            if (testTrippable() && testCondition())
+               mDataBlock->onLeaveTrigger_callback( this, remove );
+            mTripped = true;
          }
       }
 
-      if (!mTickCommand.isEmpty())
+      if (evalCmD(&mTickCommand))
          Con::evaluate(mTickCommand.c_str());
 
-      if (mObjects.size() != 0)
+      if (mObjects.size() != 0 && testTrippable() && testCondition())
          mDataBlock->onTickTrigger_callback( this );
    }
    else
@@ -886,3 +929,26 @@ DefineEngineMethod( Trigger, getObject, S32, ( S32 index ),,
    else
       return object->getObject(U32(index))->getId();
 }
+
+IMPLEMENT_CO_NETOBJECT_V1(AITrigger);
+AITrigger::AITrigger()
+{
+   for (S32 i = 0; i < AI_NAVCHOICES; i++)
+   {
+      mProbability[i] = 100 / AI_NAVCHOICES;
+      mWaypoints[i] = StringTable->insert("-1");
+   }
+};
+
+AITrigger::~AITrigger()
+{
+};
+
+void AITrigger::initPersistFields()
+{
+   addField("waypoint", TypeString, Offset(mWaypoints, AITrigger), AI_NAVCHOICES,
+      "waypoint name\"\n");
+   addField("probability", TypeS32, Offset(mProbability, AITrigger), AI_NAVCHOICES, "chance of picking this object to path to.");
+
+   Parent::initPersistFields();
+}

+ 23 - 1
Engine/source/T3D/trigger.h

@@ -83,6 +83,11 @@ class Trigger : public GameBase
    U32               mCurrTick;
    Convex            *mConvexList;
 
+   bool              mTripOnce;
+   bool              mTripped;
+   S32               mTrippedBy;
+
+   String            mTripCondition;
    String            mEnterCommand;
    String            mLeaveCommand;
    String            mTickCommand;
@@ -105,6 +110,9 @@ class Trigger : public GameBase
 
    static bool smRenderTriggers;
    bool testObject(GameBase* enter);
+   bool testTrippable();
+   bool testCondition();
+   bool evalCmD(String*);
    void processTick(const Move *move);
    void interpolateTick(F32 delta);
 
@@ -113,7 +121,6 @@ class Trigger : public GameBase
    static bool setEnterCmd(void *object, const char *index, const char *data);
    static bool setLeaveCmd(void *object, const char *index, const char *data);
    static bool setTickCmd(void *object, const char *index, const char *data);
-
   public:
    Trigger();
    ~Trigger();
@@ -168,5 +175,20 @@ inline GameBase* Trigger::getObject(const U32 index)
    return mObjects[index];
 }
 
+#define AI_NAVCHOICES 8
+class AITrigger : public Trigger
+{
+   typedef Trigger Parent;
+public:
+   AITrigger();
+   ~AITrigger();
+
+   StringTableEntry mWaypoints[AI_NAVCHOICES];
+   S32 mProbability[AI_NAVCHOICES];
+   static void initPersistFields();
+   // SimObject
+   DECLARE_CONOBJECT(AITrigger);
+};
+
 #endif // _H_TRIGGER