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

📄 terraineditor.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 4 页
字号:
   }
   else
   {
      glEnable(GL_DEPTH_TEST);
      GridSquare * gs = mTerrainBlock->findSquare(TerrainBlock::BlockShift, Point2I(0,0));
      F32 height = F32(gs->maxHeight) * 0.03125f + mBorderHeight;

      const MatrixF & mat = mTerrainBlock->getTransform();
      Point3F pos;
      mat.getColumn(3, &pos);

      Point2F min(pos.x, pos.y);
      Point2F max(pos.x + TerrainBlock::BlockSize * mTerrainBlock->getSquareSize(),
                  pos.y + TerrainBlock::BlockSize * mTerrainBlock->getSquareSize());

      ColorI & a = mBorderFillColor;
      ColorI & b = mBorderFrameColor;

      for(U32 i = 0; i < 2; i++)
      {
         //
         if(i){glColor4ub(a.red,a.green,a.blue,a.alpha);glBegin(GL_QUADS);} else {glColor4f(b.red,b.green,b.blue,b.alpha); glBegin(GL_LINE_LOOP);}
         glVertex3f(min.x, min.y, 0);
         glVertex3f(max.x, min.y, 0);
         glVertex3f(max.x, min.y, height);
         glVertex3f(min.x, min.y, height);
         glEnd();

         //
         if(i){glColor4ub(a.red,a.green,a.blue,a.alpha);glBegin(GL_QUADS);} else {glColor4f(b.red,b.green,b.blue,b.alpha); glBegin(GL_LINE_LOOP);}
         glVertex3f(min.x, max.y, 0);
         glVertex3f(max.x, max.y, 0);
         glVertex3f(max.x, max.y, height);
         glVertex3f(min.x, max.y, height);
         glEnd();

         //
         if(i){glColor4ub(a.red,a.green,a.blue,a.alpha);glBegin(GL_QUADS);} else {glColor4f(b.red,b.green,b.blue,b.alpha); glBegin(GL_LINE_LOOP);}
         glVertex3f(min.x, min.y, 0);
         glVertex3f(min.x, max.y, 0);
         glVertex3f(min.x, max.y, height);
         glVertex3f(min.x, min.y, height);
         glEnd();

         //
         if(i){glColor4ub(a.red,a.green,a.blue,a.alpha);glBegin(GL_QUADS);} else {glColor4f(b.red,b.green,b.blue,b.alpha); glBegin(GL_LINE_LOOP);}
         glVertex3f(max.x, min.y, 0);
         glVertex3f(max.x, max.y, 0);
         glVertex3f(max.x, max.y, height);
         glVertex3f(max.x, min.y, height);
         glEnd();
      }
      glDisable(GL_DEPTH_TEST);
   }

   glDisable(GL_BLEND);
}

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

void TerrainEditor::addUndo(Vector<Selection *> & list, Selection * sel)
{
   AssertFatal(sel!=NULL, "TerrainEditor::addUndo - invalid selection");
   list.push_front(sel);
   if(list.size() == mUndoLimit)
   {
      Selection * undo = list[list.size()-1];
      delete undo;
      list.pop_back();
   }
   setDirty();
}

void TerrainEditor::clearUndo(Vector<Selection *> & list)
{
   for(U32 i = 0; i < list.size(); i++)
      delete list[i];
   list.clear();
}

bool TerrainEditor::processUndo(Vector<Selection *> & src, Vector<Selection *> & dest)
{
   if(!src.size())
      return(false);

   Selection * task = src.front();
   src.pop_front();

   Selection * save = new Selection;
   for(U32 i = 0; i < task->size(); i++)
   {
      GridInfo info;
      getGridInfo((*task)[i].mGridPos, info);
      save->add(info);
      setGridInfo((*task)[i]);
   }
   gridUpdateComplete();

   delete task;
   addUndo(dest, save);

   rebuild();

   return(true);
}

//------------------------------------------------------------------------------
//
void TerrainEditor::rebuild()
{
   // empty
   if(mRebuildEmpty)
   {
      mTerrainBlock->rebuildEmptyFlags();
      mTerrainBlock->packEmptySquares();
      mRebuildEmpty = false;
   }
}

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

void TerrainEditor::on3DMouseUp(const Gui3DMouseEvent & event)
{
   if(!mTerrainBlock)
      return;

   if(isMouseLocked())
   {
      mouseUnlock();
      mMouseDownSeq++;
      mCurrentAction->process(mMouseBrush, event, false, TerrainAction::End);
      setCursor(0);

      if(mUndoSel->size())
      {
         addUndo(mUndoList, mUndoSel);
         clearUndo(mRedoList);
      }
      else
         delete mUndoSel;

      mUndoSel = 0;
      mInAction = false;

      rebuild();
   }
}

class TerrainProcessActionEvent : public SimEvent
{
   U32 mSequence;
public:
   TerrainProcessActionEvent(U32 seq)
   {
      mSequence = seq;
   }
   void process(SimObject *object)
   {
      ((TerrainEditor *) object)->processActionTick(mSequence);
   }
};

void TerrainEditor::processActionTick(U32 sequence)
{
   if(mMouseDownSeq == sequence)
   {
      Sim::postEvent(this, new TerrainProcessActionEvent(mMouseDownSeq), Sim::getCurrentTime() + 30);
      mCurrentAction->process(mMouseBrush, mLastEvent, false, TerrainAction::Update);
   }
}

void TerrainEditor::on3DMouseDown(const Gui3DMouseEvent & event)
{
   if(!mTerrainBlock)
      return;

   mSelectionLocked = false;

   mouseLock();
   mMouseDownSeq++;
   mUndoSel = new Selection;
   mCurrentAction->process(mMouseBrush, event, true, TerrainAction::Begin);
   // process on ticks - every 30th of a second.
   Sim::postEvent(this, new TerrainProcessActionEvent(mMouseDownSeq), Sim::getCurrentTime() + 30);
}

void TerrainEditor::on3DMouseMove(const Gui3DMouseEvent & event)
{
   if(!mTerrainBlock)
      return;

   Point3F pos;
   if(!collide(event, pos))
   {
      mMouseBrush->reset();
      mCursorVisible = true;
   }
   else
   {
      //
      if(mRenderBrush)
         mCursorVisible = false;
      mMousePos = pos;

      mMouseBrush->setPosition(mMousePos);
   }
}

void TerrainEditor::on3DMouseDragged(const Gui3DMouseEvent & event)
{
   if(!mTerrainBlock)
      return;

   if(!isMouseLocked())
      return;

   Point3F pos;
   if(!mSelectionLocked)
   {
      if(!collide(event, pos))
      {
         mMouseBrush->reset();
         return;
      }
   }

   // check if the mouse has actually moved in grid space
   bool selChanged = false;
   if(!mSelectionLocked)
   {
      Point2I gMouse;
      Point2I gLastMouse;
      worldToGrid(pos, gMouse);
      worldToGrid(mMousePos, gLastMouse);

      //
      mMousePos = pos;
      mMouseBrush->setPosition(mMousePos);

      selChanged = gMouse != gLastMouse;
   }
   if(selChanged)
      mCurrentAction->process(mMouseBrush, event, true, TerrainAction::Update);
}

void TerrainEditor::getCursor(GuiCursor *&cursor, bool &visible, const GuiEvent &event)
{
   event;
   cursor = mCurrentCursor;
   visible = mCursorVisible;
}

//------------------------------------------------------------------------------
// any console function which depends on a terrainBlock attached to the editor
// should call this
bool checkTerrainBlock(TerrainEditor * object, const char * funcName)
{
   if(!object->terrainBlockValid())
   {
      Con::errorf(ConsoleLogEntry::Script, "TerrainEditor::%s: not attached to a terrain block!", funcName);
      return(false);
   }
   return(true);
}

//------------------------------------------------------------------------------
static void findObjectsCallback(SceneObject* obj, void *val)
{
   Vector<SceneObject*> * list = (Vector<SceneObject*>*)val;
   list->push_back(obj);
}

// XA: Methods added for interfacing with the consoleMethods.

void TerrainEditor::attachTerrain(TerrainBlock *terrBlock)
{
	mTerrainBlock = terrBlock;	
}

void TerrainEditor::setBrushType(const char* type)
{
   if(!dStricmp(type, "box"))
   {
      delete mMouseBrush;
      mMouseBrush = new BoxBrush(this);
   }
#ifdef TGE_RPG///TGE_TerrainScene
   else if(!dStricmp(type, "hline"))
   {
      delete mMouseBrush;
      mMouseBrush = new HLineBrush(this);
   }
   else if(!dStricmp(type, "vline"))
   {
      delete mMouseBrush;
      mMouseBrush = new VLineBrush(this);
   }
#endif
   else if(!dStricmp(type, "ellipse"))
   {
      delete mMouseBrush;
      mMouseBrush = new EllipseBrush(this);
   }
   else if(!dStricmp(type, "selection"))
   {
      delete mMouseBrush;
      mMouseBrush = new SelectionBrush(this);
   }
   else {}
}	

void TerrainEditor::setBrushSize(S32 w, S32 h)
{
	mBrushSize.set(w, h);
	mMouseBrush->setSize(mBrushSize);	
}

const char* TerrainEditor::getBrushPos()
{
   AssertFatal(mMouseBrush!=NULL, "TerrainEditor::getBrushPos: no mouse brush!");

   Point2I pos = mMouseBrush->getPosition();
   char * ret = Con::getReturnBuffer(32);
   dSprintf(ret, sizeof(ret), "%d %d", pos.x, pos.y);
   return(ret);	
}

void TerrainEditor::setBrushPos(Point2I pos)
{
   AssertFatal(mMouseBrush!=NULL, "TerrainEditor::setBrushPos: no mouse brush!");
   mMouseBrush->setPosition(pos);	
}

void TerrainEditor::setAction(const char* action)
{
   for(U32 i = 0; i < mActions.size(); i++)
   {
      if(!dStricmp(mActions[i]->getName(), action))
      {
         mCurrentAction = mActions[i];

         //
         mRenderBrush = mCurrentAction->useMouseBrush();
         return;
      }
   }	
}

const char* TerrainEditor::getActionName(U32 index)
{
   if(index >= mActions.size())
      return("");
   return(mActions[index]->getName());
}

const char* TerrainEditor::getCurrentAction()
{
   return(mCurrentAction->getName());	
}

S32 TerrainEditor::getNumActions()
{
   return(mActions.size());
}

void TerrainEditor::resetSelWeights(bool clear)
{
   //
   if(!clear)
   {
      for(U32 i = 0; i < mDefaultSel.size(); i++)
      {
         mDefaultSel[i].mPrimarySelect = false;
         mDefaultSel[i].mWeight = 1.f;
      }
      return;
   }

   Selection sel;

   U32 i;
   for(i = 0; i < mDefaultSel.size(); i++)
   {
      if(mDefaultSel[i].mPrimarySelect)
      {
         mDefaultSel[i].mWeight = 1.f;
         sel.add(mDefaultSel[i]);
      }
   }

   mDefaultSel.reset();

   for(i = 0; i < sel.size(); i++)
      mDefaultSel.add(sel[i]);
}

void TerrainEditor::undo()
{
   if(!checkTerrainBlock(this, "undoAction"))
      return;

   processUndo(mUndoList, mRedoList);
}

void TerrainEditor::redo()
{
   if(!checkTerrainBlock(this, "redoAction"))
      return;

   processUndo(mRedoList, mUndoList);	
}

void TerrainEditor::clearSelection()
{
	mDefaultSel.reset();
}

void TerrainEditor::processAction(const char* sAction)
{
   if(!checkTerrainBlock(this, "processAction"))
      return;

   TerrainAction * action = mCurrentAction;
   if(sAction != "")
   {
      action = lookupAction(sAction);

      if(!action)
      {
         Con::errorf(ConsoleLogEntry::General, "TerrainEditor::cProcessAction: invalid action name '%s'.", sAction);
         return;
      }
   }

   if(!getCurrentSel()->size() && !mProcessUsesBrush)
      return;

   mUndoSel = new Selection;

   Gui3DMouseEvent event;
   if(mProcessUsesBrush)
      action->process(mMouseBrush, event, true, TerrainAction::Process);
   else
      action->process(getCurrentSel(), event, true, TerrainAction::Process);

   rebuild();

   // check if should delete the undo
   if(mUndoSel->size())
   {
      addUndo(mUndoList, mUndoSel);
      clearUndo(mRedoList);
   }
   else
      delete mUndoSel;

   mUndoSel = 0;	
}

void TerrainEditor::buildMaterialMap()
{
   if(!checkTerrainBlock(this, "buildMaterialMap"))
      return;
   mTerrainBlock->buildMaterialMap();
}

S32 TerrainEditor::getNumTextures()
{
   if(!checkTerrainBlock(this, "getNumTextures"))
      return(0);

   // walk all the possible material lists and count them..
   U32 count = 0;
   for(U32 i = 0; i < TerrainBlock::MaterialGroups; i++)
      if(mTerrainBlock->mMaterialFileName[i] &&
         *mTerrainBlock->mMaterialFileName[i])
         count++;
   return count;	
}

const char* TerrainEditor::getTextureName(S32 group)
{
   if(!checkTerrainBlock(this, "getTextureName"))
      return("");

#ifdef TGE_RPGCLIENT2 /// TGE_RPGGhost
   TerrainBlock * terrBlock = mTerrainBlock;
#else
   // textures only exist on the client..
   NetConnection * toServer = NetConnection::getConnectionToServer();
   NetConnection * toClient = NetConnection::getLocalClientConnection();

   S32 index = toClient->getGhostIndex(mTerrainBlock);

   TerrainBlock * terrBlock = dynamic_cast<TerrainBlock*>(toServer->resolveGhost(index));
#endif
   if(!terrBlock)
      return("");

   // possibly in range?
   if(group < 0 || group >= TerrainBlock::MaterialGroups)
      return("");

   // now find the i-th group
   U32 count = 0;
   bool found = false;
   for(U32 i = 0; !found && (i < TerrainBlock::MaterialGroups); i++)
   {
      // count it
      if(terrBlock->mMaterialFileName[i] &&
         *terrBlock->mMaterialFileName[i])
         count++;

      if((group + 1) == count)
      {
         group = i;

⌨️ 快捷键说明

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