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

📄 missionareaeditor.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 3 页
字号:

void MissionAreaEditor::onMouseUp(const GuiEvent & event)
{
   if(!bool(mMissionArea))
      return;

   RectI box;
   getScreenMissionArea(box);
   S32 hit = getSizingHitKnobs(event.mousePoint, box);

   // set the current cursor
   updateCursor(hit);
   mLastHitMode = hit;
}

void MissionAreaEditor::onMouseDown(const GuiEvent & event)
{
   if(!bool(mMissionArea))
      return;

   if(!mEnableEditing || mEnableMirroring)
   {
      Point2F pos = screenToWorld(Point2F(event.mousePoint.x, event.mousePoint.y));
      setControlObjPos(pos);
      return;
   }

   RectI box;
   getScreenMissionArea(box);

   mLastHitMode = getSizingHitKnobs(event.mousePoint, box);
   if(mLastHitMode == moving)
      setCursor(GrabCursor);
   mLastMousePoint = event.mousePoint;
}

void MissionAreaEditor::onMouseMove(const GuiEvent & event)
{
   if(!bool(mMissionArea))
      return;

   RectI box;
   getScreenMissionArea(box);
   S32 hit = getSizingHitKnobs(event.mousePoint, box);

   // set the current cursor...
   updateCursor(hit);
   mLastHitMode = hit;
}

// update the mission area here...
void MissionAreaEditor::onMouseDragged(const GuiEvent & event)
{
   if(!bool(mMissionArea))
      return;

   if(!mLastHitMode)
      return;

   RectF box;
   getScreenMissionArea(box);
   Point2F mouseDiff(event.mousePoint.x - mLastMousePoint.x,
      event.mousePoint.y - mLastMousePoint.y);

   // what we drag'n?
   if(mLastHitMode == moving)
      box.point += mouseDiff;
   else
   {
      // dont allow the box to be < 1x1 'pixels'
      if(mLastHitMode & sizingLeft)
      {
         if(mouseDiff.x >= box.extent.x)
            mouseDiff.x = box.extent.x - 1;

         box.point.x += mouseDiff.x;
         box.extent.x -= mouseDiff.x;
      }

      if(mLastHitMode & sizingRight)
      {
         if(mouseDiff.x + box.extent.x <= 0)
            mouseDiff.x = -(box.extent.x - 1);
         box.extent.x += mouseDiff.x;
      }

      if(mLastHitMode & sizingTop)
      {
         if(mouseDiff.y >= box.extent.y)
            mouseDiff.y = box.extent.y - 1;

         box.point.y += mouseDiff.y;
         box.extent.y -= mouseDiff.y;
      }

      if(mLastHitMode & sizingBottom)
      {
         if(mouseDiff.y + box.extent.y <= 0)
            mouseDiff.y = -(box.extent.y - 1);
         box.extent.y += mouseDiff.y;
      }
   }

   //
   Point2F min = screenToWorld(box.point);
   Point2F max = screenToWorld(box.point + box.extent);

   RectI iBox((S32)round_local(min.x), (S32)round_local(min.y), (S32)round_local(max.x - min.x), (S32)round_local(max.y - min.y));
   setArea(iBox);

   mLastMousePoint = event.mousePoint;
}

void MissionAreaEditor::onMouseEnter(const GuiEvent &)
{
   mLastHitMode = nothing;
   setCursor(DefaultCursor);
}

void MissionAreaEditor::onMouseLeave(const GuiEvent &)
{
   mLastHitMode = nothing;
   setCursor(DefaultCursor);
}

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

void MissionAreaEditor::setControlObjPos(const Point2F & pos)
{
   GameConnection * connection = GameConnection::getLocalClientConnection();

   ShapeBase * obj = 0;
   if(connection)
      obj = connection->getControlObject();

   if(!obj)
   {
      Con::errorf(ConsoleLogEntry::General, "MissionAreaEditor::setControlObjPos: could not get a control object!");
      return;
   }

   // move it
   MatrixF mat = obj->getTransform();

   Point3F current;
   mat.getColumn(3, &current);

   //
   if(bool(mTerrainBlock))
   {
      F32 height;
      mTerrainBlock->getHeight(pos, &height);
      if(current.z < height)
         current.z = height + 10.f;
   }

   //
   current.set(pos.x, pos.y, current.z);
   mat.setColumn(3, current);
   obj->setTransform(mat);
}


//------------------------------------------------------------------------------
// the following globals allocations needed for cCenterWorld are allocated when first refd.
static U16 *heights = NULL;
static U8 *baseMaterials = NULL;
static TerrainBlock::Material *materials = NULL;
static bool cwAllocs = false;

//------------------------------------------------------------------------------
ConsoleMethod( MissionAreaEditor, centerWorld, void, 2, 2, "Realign the world so that the mission area is centered.\n\n"
              "This method moves every SceneObject (including terrain) in the world so that the center of the world is "
              "the center of the mission area.")
{
   if(!object->missionAreaObjValid())
   {
      Con::errorf(ConsoleLogEntry::General, "MissionAreaEditor::cCenterWorld: no MissionArea obj!");
      return;
   }

   //
   SimSet * missionGroup = dynamic_cast<SimSet*>(Sim::findObject("missionGroup"));
   if(!missionGroup)
   {
      Con::errorf(ConsoleLogEntry::General, "MissionAreaEditor::cCenterWorld: no mission group found!");
      return;
   }

	// make sure we're allocated.
	// !!!!!TBD -- NOTE THAT THIS IS LEAKED ON EXIT!
	if (!cwAllocs)
	{
		U32 allocSize = TerrainBlock::BlockSize * TerrainBlock::BlockSize;
		heights = new U16[allocSize];
		if (NULL==heights)
		{
         Con::errorf(ConsoleLogEntry::General, "MissionAreaEditor::cCenterWorld: out of memory!");
         return;
		}
		baseMaterials = new U8[allocSize];
		if (NULL==baseMaterials)
		{
         Con::errorf(ConsoleLogEntry::General, "MissionAreaEditor::cCenterWorld: out of memory!");
         return;
		}
		materials = new TerrainBlock::Material[allocSize];
		if (NULL==materials)
		{
         Con::errorf(ConsoleLogEntry::General, "MissionAreaEditor::cCenterWorld: out of memory!");
         return;
		}
		cwAllocs = true;
	}

   // make sure area is clamped to terrain square size!
   object->setArea(object->getArea());
   RectI area = object->getArea();

   // calc offset
   Point2I offset(area.point.x + (area.extent.x >> 1),
                  area.point.y + (area.extent.y >> 1));

   if(!offset.x || !offset.y)
      return;

   Point3F offset3F(offset.x, offset.y, 0.f);

   // update all the scene objects
   for(SimSetIterator itr(missionGroup); *itr; ++itr)
   {
      SceneObject * obj = dynamic_cast<SceneObject*>(*itr);
      if(!obj)
         continue;

      // terrain is handled special like (mission area is forced to align to
      // terrain square sizes because terrain cannot move)
      TerrainBlock * terrain = dynamic_cast<TerrainBlock*>(*itr);
      if(terrain)
      {
         // get the new start location in gridSquare space
         Point2I start((offset.x / (S32) terrain->getSquareSize()) & TerrainBlock::BlockMask,
                       (offset.y / (S32) terrain->getSquareSize()) & TerrainBlock::BlockMask);

         // update the grid block
         if(start.x || start.y)
         {
            for(U32 y = 0; y < TerrainBlock::BlockSize; y++)
               for(U32 x = 0; x < TerrainBlock::BlockSize; x++)
               {
                  Point2I pos((start.x + x) & TerrainBlock::BlockMask,
                              (start.y + y) & TerrainBlock::BlockMask);

                  heights[x + y * TerrainBlock::BlockSize] = terrain->getHeight(pos.x, pos.y);
                  baseMaterials[x + y * TerrainBlock::BlockSize] = terrain->getBaseMaterial(pos.x, pos.y);
                  materials[x + y * TerrainBlock::BlockSize] = *terrain->getMaterial(pos.x, pos.y);
               }

            U16 * heightsAddr = terrain->getHeightAddress(0,0);
            U8 * baseMaterialsAddr = terrain->getBaseMaterialAddress(0,0);
            TerrainBlock::Material * materialsAddr = terrain->getMaterial(0,0);

            dMemcpy(heightsAddr, heights, sizeof(heights));
            dMemcpy(baseMaterialsAddr, baseMaterials, sizeof(baseMaterials));
            dMemcpy(materialsAddr, materials, sizeof(materials));

            terrain->buildGridMap();
            terrain->rebuildEmptyFlags();
            terrain->packEmptySquares();
         }

         object->updateTerrainBitmap();
      }
      else
      {
         MatrixF objMat = obj->getTransform();
         Point3F pos;
         objMat.getColumn(3, &pos);

         pos -= offset3F;
         objMat.setColumn(3, pos);

         obj->setTransform(objMat);
      }
   }

   char buf[64];
   dSprintf(buf, sizeof(buf), "%g %g %g", -offset3F.x, -offset3F.y, -offset3F.z);
   Con::executef(object, 2, "onWorldOffset", buf);

   // move the mission area
   area.point.x -= offset.x;
   area.point.y -= offset.y;

   object->setArea(area);
}

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

ConsoleMethod(MissionAreaEditor, getArea, const char *, 2, 2, "Return a 4-tuple: area_x area_y area_width are_height")
{
   if(!object->missionAreaObjValid())
   {
      Con::errorf(ConsoleLogEntry::General, "MissionAreaEditor::cGetArea: no MissionArea obj!");
      return("");
   }

   //
   RectI area = object->getArea();
   char * ret = Con::getReturnBuffer(64);
   dSprintf(ret, 64, "%d %d %d %d", area.point.x, area.point.y, area.extent.x, area.extent.y);

   return(ret);
}

ConsoleMethod( MissionAreaEditor, setArea, void, 3, 6, "(int x, int y, int w, int h)"
              "Set the mission area to the specified co-ordinates/extents.")
{
   if(!object->missionAreaObjValid())
   {
      Con::errorf(ConsoleLogEntry::General, "MissionAreaEditor::cSetArea: no MissionArea obj!");
      return;
   }

   RectI area;

   //
   if(argc == 3)
      dSscanf(argv[2], "%d %d %d %d", &area.point.x, &area.point.y, &area.extent.x, &area.extent.y);
   else if(argc == 6)
   {
      area.point.x = dAtoi(argv[2]);
      area.point.y = dAtoi(argv[3]);
      area.extent.x = dAtoi(argv[4]);
      area.extent.y = dAtoi(argv[5]);
   }
   else
      Con::errorf(ConsoleLogEntry::General, "MissionAreaEditor::cSetArea: invalid number of arguments!");

   //
   object->setArea(area);
}

ConsoleMethod( MissionAreaEditor, updateTerrain, void, 2, 2, "Update the terrain bitmap that is rendered as background in the control.")
{
   //
   if(!object->getTerrainObj())
   {
      Con::errorf(ConsoleLogEntry::General, "MissionAreaEditor::cUpdateTerrain: no terrain found!");
      return;
   }

   //
   object->updateTerrainBitmap();
}

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

void MissionAreaEditor::initPersistFields()
{
   Parent::initPersistFields();

   addGroup("Mirror");	
   addField("enableMirroring", TypeBool, Offset(mEnableMirroring, MissionAreaEditor));
   addField("mirrorIndex", TypeS32, Offset(mMirrorIndex, MissionAreaEditor));
   addField("mirrorLineColor", TypeColorI, Offset(mMirrorLineColor, MissionAreaEditor));
   addField("mirrorArrowColor", TypeColorI, Offset(mMirrorArrowColor, MissionAreaEditor));
   endGroup("Mirror");	

   addGroup("Misc");	
   addField("handleFrameColor", TypeColorI, Offset(mHandleFrameColor, MissionAreaEditor));
   addField("handleFillColor", TypeColorI, Offset(mHandleFillColor, MissionAreaEditor));
   addField("defaultObjectColor", TypeColorI, Offset(mDefaultObjectColor, MissionAreaEditor));
   addField("waterObjectColor", TypeColorI, Offset(mWaterObjectColor, MissionAreaEditor));
   addField("missionBoundsColor", TypeColorI, Offset(mMissionBoundsColor, MissionAreaEditor));
   addField("cameraColor", TypeColorI, Offset(mCameraColor, MissionAreaEditor));
   addField("squareBitmap", TypeBool, Offset(mSquareBitmap, MissionAreaEditor));
   addField("enableEditing", TypeBool, Offset(mEnableEditing, MissionAreaEditor));
   addField("renderCamera", TypeBool, Offset(mRenderCamera, MissionAreaEditor));
   endGroup("Misc");	
}

⌨️ 快捷键说明

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