⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trigger.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 2 页
字号:
   if (!mDataBlock || !Parent::onNewDataBlock(dptr))
      return false;

   scriptOnNewDataBlock();
   return true;
}

void Trigger::onDeleteNotify(SimObject* obj)
{
   GameBase* pScene = dynamic_cast<GameBase*>(obj);
   if (pScene != NULL) 
   {
      for (U32 i = 0; i < mObjects.size(); i++) 
      {
         if (pScene == mObjects[i]) 
         {
            mObjects.erase(i);
            Con::executef(mDataBlock, 3, "onLeaveTrigger", scriptThis(), Con::getIntArg(pScene->getId()));
            break;
         }
      }
   }

   Parent::onDeleteNotify(obj);
}

void Trigger::onEditorEnable()
{
   // Enable scoping so we can see this thing on the client.
   mNetFlags.set(Ghostable);
   setScopeAlways();
}

void Trigger::onEditorDisable()
{
   // Disable scoping so we can see this thing on the client
   mNetFlags.clear(Ghostable);
   clearScopeAlways();
}

//--------------------------------------------------------------------------

void Trigger::buildConvex(const Box3F& box, Convex* convex)
{
   // These should really come out of a pool
   mConvexList->collectGarbage();

   Box3F realBox = box;
   mWorldToObj.mul(realBox);
   realBox.min.convolveInverse(mObjScale);
   realBox.max.convolveInverse(mObjScale);

   if (realBox.isOverlapped(getObjBox()) == false)
      return;

   // Just return a box convex for the entire shape...
   Convex* cc = 0;
   CollisionWorkingList& wl = convex->getWorkingList();
   for (CollisionWorkingList* itr = wl.wLink.mNext; itr != &wl; itr = itr->wLink.mNext) {
      if (itr->mConvex->getType() == BoxConvexType &&
          itr->mConvex->getObject() == this) {
         cc = itr->mConvex;
         break;
      }
   }
   if (cc)
      return;

   // Create a new convex.
   BoxConvex* cp = new BoxConvex;
   mConvexList->registerObject(cp);
   convex->addToWorkingList(cp);
   cp->init(this);

   mObjBox.getCenter(&cp->mCenter);
   cp->mSize.x = mObjBox.len_x() / 2.0f;
   cp->mSize.y = mObjBox.len_y() / 2.0f;
   cp->mSize.z = mObjBox.len_z() / 2.0f;
}


//------------------------------------------------------------------------------

void Trigger::setTransform(const MatrixF & mat)
{
   Parent::setTransform(mat);

   if (isServerObject()) {
      MatrixF base(true);
      base.scale(Point3F(1.0/mObjScale.x,
                         1.0/mObjScale.y,
                         1.0/mObjScale.z));
      base.mul(mWorldToObj);
      mClippedList.setBaseTransform(base);

      setMaskBits(GameBase::InitialUpdateMask);
   }
}

void Trigger::setTriggerPolyhedron(const Polyhedron& rPolyhedron)
{
   mTriggerPolyhedron = rPolyhedron;

   if (mTriggerPolyhedron.pointList.size() != 0) {
      mObjBox.min.set(1e10, 1e10, 1e10);
      mObjBox.max.set(-1e10, -1e10, -1e10);
      for (U32 i = 0; i < mTriggerPolyhedron.pointList.size(); i++) {
         mObjBox.min.setMin(mTriggerPolyhedron.pointList[i]);
         mObjBox.max.setMax(mTriggerPolyhedron.pointList[i]);
      }
   } else {
      mObjBox.min.set(-0.5, -0.5, -0.5);
      mObjBox.max.set( 0.5,  0.5,  0.5);
   }

   MatrixF xform = getTransform();
   setTransform(xform);

   mClippedList.clear();
   mClippedList.mPlaneList = mTriggerPolyhedron.planeList;
//   for (U32 i = 0; i < mClippedList.mPlaneList.size(); i++)
//      mClippedList.mPlaneList[i].neg();

   MatrixF base(true);
   base.scale(Point3F(1.0/mObjScale.x,
                      1.0/mObjScale.y,
                      1.0/mObjScale.z));
   base.mul(mWorldToObj);

   mClippedList.setBaseTransform(base);
}


//--------------------------------------------------------------------------

bool Trigger::testObject(GameBase* enter)
{
   if (mTriggerPolyhedron.pointList.size() == 0)
      return false;

   mClippedList.clear();

   SphereF sphere;
   sphere.center = (mWorldBox.min + mWorldBox.max) * 0.5;
   VectorF bv = mWorldBox.max - sphere.center;
   sphere.radius = bv.len();

   enter->buildPolyList(&mClippedList, mWorldBox, sphere);
   return mClippedList.isEmpty() == false;
}


void Trigger::potentialEnterObject(GameBase* enter)
{
   AssertFatal(isServerObject(), "Error, should never be called on the client!");

   for (U32 i = 0; i < mObjects.size(); i++) {
      if (mObjects[i] == enter)
         return;
   }

   if (testObject(enter) == true) {
      mObjects.push_back(enter);
      deleteNotify(enter);

      Con::executef(mDataBlock, 3, "onEnterTrigger", scriptThis(), Con::getIntArg(enter->getId()));
   }
}


void Trigger::processTick(const Move* move)
{
   Parent::processTick(move);

#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
   if (isClientObject())
      return;
#endif

   //
   if (mObjects.size() == 0)
      return;

   if (mLastThink + mDataBlock->tickPeriodMS < mCurrTick) {
      mCurrTick  = 0;
      mLastThink = 0;

      for (S32 i = S32(mObjects.size() - 1); i >= 0; i--) {
         if (testObject(mObjects[i]) == false) {
            GameBase* remove = mObjects[i];
            mObjects.erase(i);
            clearNotify(remove);
            Con::executef(mDataBlock, 3, "onLeaveTrigger", scriptThis(), remove->scriptThis());
         }
      }

      if (mObjects.size() != 0)
         Con::executef(mDataBlock, 2, "onTickTrigger", scriptThis());
   } else {
      mCurrTick += TickMs;
   }
}


//--------------------------------------------------------------------------

bool Trigger::prepRenderImage(SceneState* state, const U32 stateKey,
                              const U32 /*startZone*/, const bool /*modifyBaseState*/)
{
   if (isLastState(state, stateKey))
      return false;
   setLastState(state, stateKey);

   // This should be sufficient for most objects that don't manage zones, and
   //  don't need to return a specialized RenderImage...
   if (state->isObjectRendered(this)) {
      SceneRenderImage* image = new SceneRenderImage;
      image->obj = this;
      image->isTranslucent = true;
      image->sortType = SceneRenderImage::Point;
      state->insertRenderImage(image);
   }

   return false;
}

void Trigger::renderObject(SceneState* state, SceneRenderImage*)
{
   AssertFatal(dglIsInCanonicalState(), "Error, GL not in canonical state on entry");

   RectI viewport;
   glMatrixMode(GL_PROJECTION);
   glPushMatrix();
   dglGetViewport(&viewport);

   // Uncomment this if this is a "simple" (non-zone managing) object
   state->setupObjectProjection(this);

   glMatrixMode(GL_MODELVIEW);
   glPushMatrix();
   dglMultMatrix(&mObjToWorld);
   glScalef(mObjScale.x, mObjScale.y, mObjScale.z);

   mTriggerPolyhedron.render();

   glMatrixMode(GL_MODELVIEW);
   glPopMatrix();

   glMatrixMode(GL_PROJECTION);
   glPopMatrix();
   glMatrixMode(GL_MODELVIEW);
   dglSetViewport(viewport);

   AssertFatal(dglIsInCanonicalState(), "Error, GL not in canonical state on exit");
}


//--------------------------------------------------------------------------

U32 Trigger::packUpdate(NetConnection* con, U32 mask, BitStream* stream)
{
   U32 i;
   U32 retMask = Parent::packUpdate(con, mask, stream);

   // Note that we don't really care about efficiency here, since this is an
   //  edit-only ghost...
   stream->writeAffineTransform(mObjToWorld);
   mathWrite(*stream, mObjScale);

   // Write the polyhedron
   stream->write(mTriggerPolyhedron.pointList.size());
   for (i = 0; i < mTriggerPolyhedron.pointList.size(); i++)
      mathWrite(*stream, mTriggerPolyhedron.pointList[i]);

   stream->write(mTriggerPolyhedron.planeList.size());
   for (i = 0; i < mTriggerPolyhedron.planeList.size(); i++)
      mathWrite(*stream, mTriggerPolyhedron.planeList[i]);

   stream->write(mTriggerPolyhedron.edgeList.size());
   for (i = 0; i < mTriggerPolyhedron.edgeList.size(); i++) {
      const Polyhedron::Edge& rEdge = mTriggerPolyhedron.edgeList[i];

      stream->write(rEdge.face[0]);
      stream->write(rEdge.face[1]);
      stream->write(rEdge.vertex[0]);
      stream->write(rEdge.vertex[1]);
   }

   return retMask;
}

void Trigger::unpackUpdate(NetConnection* con, BitStream* stream)
{
   Parent::unpackUpdate(con, stream);

   U32 i, size;
   MatrixF temp;
   Point3F tempScale;
   Polyhedron tempPH;

   // Transform
   stream->readAffineTransform(&temp);
   mathRead(*stream, &tempScale);

   // Read the polyhedron
   stream->read(&size);
   tempPH.pointList.setSize(size);
   for (i = 0; i < tempPH.pointList.size(); i++)
      mathRead(*stream, &tempPH.pointList[i]);

   stream->read(&size);
   tempPH.planeList.setSize(size);
   for (i = 0; i < tempPH.planeList.size(); i++)
      mathRead(*stream, &tempPH.planeList[i]);

   stream->read(&size);
   tempPH.edgeList.setSize(size);
   for (i = 0; i < tempPH.edgeList.size(); i++) {
      Polyhedron::Edge& rEdge = tempPH.edgeList[i];

      stream->read(&rEdge.face[0]);
      stream->read(&rEdge.face[1]);
      stream->read(&rEdge.vertex[0]);
      stream->read(&rEdge.vertex[1]);
   }

   setTriggerPolyhedron(tempPH);
   setScale(tempScale);
   setTransform(temp);
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -