diff --git a/Engine/source/T3D/trigger.cpp b/Engine/source/T3D/trigger.cpp index 8a88a379c..5f043ed38 100644 --- a/Engine/source/T3D/trigger.cpp +++ b/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 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(); +} diff --git a/Engine/source/T3D/trigger.h b/Engine/source/T3D/trigger.h index c394d5c03..2f7eee0f0 100644 --- a/Engine/source/T3D/trigger.h +++ b/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