eraser.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. #define ERASER_CPP
  2. /*************************************************************************************************\
  3. eraser.cpp : Implementation of the eraser component.
  4. //---------------------------------------------------------------------------//
  5. // Copyright (C) Microsoft Corporation. All rights reserved. //
  6. //===========================================================================//
  7. \*************************************************************************************************/
  8. #include "eraser.h"
  9. #include "MineBrush.h"
  10. #ifndef OBJECTMGR_H
  11. #include "EditorObjectMgr.h"
  12. #endif
  13. //---------------------------------------------------------------------------
  14. inline bool isCementType (DWORD type)
  15. {
  16. bool isCement = ((type == BASE_CEMENT_TYPE) ||
  17. ((type >= START_CEMENT_TYPE) && (type <= END_CEMENT_TYPE)));
  18. return isCement;
  19. }
  20. bool Eraser::beginPaint()
  21. {
  22. gosASSERT( !pCurAction );
  23. pCurAction = new EraserAction;
  24. return true;
  25. }
  26. Action* Eraser::endPaint()
  27. {
  28. Action* pRetAction = NULL;
  29. if (pCurAction)
  30. {
  31. if ( pCurAction->vertexInfoList.Count() || pCurAction->bldgAction.objInfoPtrList.Count() )
  32. {
  33. pRetAction = pCurAction;
  34. }
  35. else
  36. {
  37. delete pCurAction;
  38. }
  39. }
  40. pCurAction = NULL;
  41. return pRetAction;
  42. }
  43. #define DEFAULT_TERRAIN 2
  44. bool Eraser::paint( Stuff::Vector3D& worldPos, int screenX, int screenY )
  45. {
  46. EditorObject* pInfo = EditorObjectMgr::instance()->getObjectAtPosition( worldPos );
  47. if ( pInfo )
  48. {
  49. CTeams originalTeams = EditorData::instance->TeamsRef();
  50. EditorData::instance->handleObjectInvalidation(pInfo);
  51. if (!(originalTeams == EditorData::instance->TeamsRef())) {
  52. pCurAction->teamsAction.PreviousTeams(originalTeams);
  53. pCurAction->teamsActionIsSet = true;
  54. }
  55. {
  56. BuildingLink* pLink = EditorObjectMgr::instance()->getLinkWithParent( pInfo );
  57. if ( pLink )
  58. {
  59. pCurAction->linkAction.AddToListOnce( LinkBrush::LinkInfo( pLink, LinkBrush::LinkInfo::REMOVE ) );
  60. EditorObjectMgr::instance()->deleteLink( pLink );
  61. }
  62. {
  63. pLink = EditorObjectMgr::instance()->getLinkWithBuilding( pInfo );
  64. if ( pLink )
  65. {
  66. pCurAction->linkAction.AddToListOnce( LinkBrush::LinkInfo( pLink, LinkBrush::LinkInfo::EDIT ) );
  67. pLink->RemoveObject( pInfo );
  68. }
  69. }
  70. }
  71. pCurAction->bldgAction.addBuildingInfo( *pInfo ); // undo!
  72. bool retval = EditorObjectMgr::instance()->deleteObject( pInfo );
  73. return retval;
  74. }
  75. else
  76. {
  77. long tileRow, tileCol;
  78. long cellRow, cellCol;
  79. land->worldToTileCell( worldPos, tileRow, tileCol, cellRow, cellCol );
  80. cellRow += tileRow * MAPCELL_DIM;
  81. cellCol += tileCol * MAPCELL_DIM;
  82. Overlays type;
  83. unsigned long Offset;
  84. land->getOverlay( tileRow, tileCol, type, Offset );
  85. if ( type != INVALID_OVERLAY )
  86. {
  87. pCurAction->addChangedVertexInfo( tileRow, tileCol ); // undo!
  88. land->setOverlay( tileRow, tileCol, INVALID_OVERLAY, 0 );
  89. return true;
  90. }
  91. if ( GameMap->getMine( cellRow, cellCol ) )
  92. {
  93. GameMap->setMine( cellRow, cellCol, 0 );
  94. }
  95. long terrainType = land->getTerrain(tileRow, tileCol);
  96. if (isCementType(terrainType))
  97. {
  98. land->setTerrain(tileRow, tileCol, DEFAULT_TERRAIN);
  99. }
  100. }
  101. return false;
  102. }
  103. bool Eraser::canPaint( Stuff::Vector3D& worldPos, int screenX, int screenY, int flags )
  104. {
  105. if ( EditorObjectMgr::instance()->getObjectAtPosition( worldPos ) )
  106. return true;
  107. long tileRow, tileCol;
  108. long cellRow, cellCol;
  109. land->worldToTileCell( worldPos, tileRow, tileCol, cellRow, cellCol );
  110. cellRow += tileRow * MAPCELL_DIM;
  111. cellCol += tileCol * MAPCELL_DIM;
  112. Overlays type;
  113. unsigned long Offset;
  114. land->getOverlay( tileRow, tileCol, type, Offset );
  115. if ( type != INVALID_OVERLAY )
  116. {
  117. return true;
  118. }
  119. long terrainType = land->getTerrain(tileRow, tileCol);
  120. if (isCementType(terrainType))
  121. {
  122. return true;
  123. }
  124. if ( GameMap->getMine( cellRow, cellCol ) )
  125. {
  126. return true;
  127. }
  128. return false;
  129. }
  130. Action* Eraser::applyToSelection()
  131. {
  132. EraserAction* pRetAction = new EraserAction;
  133. {
  134. CTeams originalTeams = EditorData::instance->TeamsRef();
  135. /*first remove all references to objects that are about to be deleted*/
  136. EditorObjectMgr::EDITOR_OBJECT_LIST selectedObjectsList = EditorObjectMgr::instance()->getSelectedObjectList();
  137. EditorObjectMgr::EDITOR_OBJECT_LIST::EIterator it = selectedObjectsList.Begin();
  138. while (!it.IsDone())
  139. {
  140. const EditorObject* pInfo = (*it);
  141. if ( pInfo )
  142. {
  143. EditorData::instance->handleObjectInvalidation(pInfo);
  144. }
  145. it++;
  146. }
  147. if (!(originalTeams == EditorData::instance->TeamsRef())) {
  148. /*record undo info regarding removal of references to deleted objects before we actually
  149. delete the objects (because we need info from the actual objects before they're deleted)*/
  150. pRetAction->teamsAction.PreviousTeams(originalTeams);
  151. pRetAction->teamsActionIsSet = true;
  152. }
  153. }
  154. EditorObjectMgr::EDITOR_OBJECT_LIST selectedObjectsList = EditorObjectMgr::instance()->getSelectedObjectList();
  155. EditorObjectMgr::EDITOR_OBJECT_LIST::EIterator it = selectedObjectsList.Begin();
  156. while (!it.IsDone())
  157. {
  158. EditorObject* pInfo = (*it);
  159. if ( pInfo )
  160. {
  161. {
  162. BuildingLink* pLink = EditorObjectMgr::instance()->getLinkWithParent( pInfo );
  163. if ( pLink )
  164. {
  165. pRetAction->linkAction.AddToListOnce( LinkBrush::LinkInfo( pLink, LinkBrush::LinkInfo::REMOVE ) );
  166. EditorObjectMgr::instance()->deleteLink( pLink );
  167. }
  168. {
  169. pLink = EditorObjectMgr::instance()->getLinkWithBuilding( pInfo );
  170. if ( pLink )
  171. {
  172. pRetAction->linkAction.AddToListOnce( LinkBrush::LinkInfo( pLink, LinkBrush::LinkInfo::EDIT ) );
  173. pLink->RemoveObject( pInfo );
  174. }
  175. }
  176. }
  177. pRetAction->bldgAction.addBuildingInfo( *pInfo ); // undo!
  178. EditorObjectMgr::instance()->deleteObject( pInfo );
  179. }
  180. it++;
  181. }
  182. //EditorObjectMgr::instance()->deleteSelectedObjects();
  183. for ( int i = 0; i < land->realVerticesMapSide; ++i )
  184. {
  185. for ( int j = 0; j < land->realVerticesMapSide; ++j )
  186. {
  187. if ( land->isVertexSelected( j, i ) )
  188. {
  189. pRetAction->addChangedVertexInfo( j, i );
  190. land->setOverlay( j, i, INVALID_OVERLAY, 0 );
  191. land->setTerrain(j, i, DEFAULT_TERRAIN);
  192. for (long icell = 0;icell<MAPCELL_DIM;icell++)
  193. {
  194. for (long jcell = 0;jcell<MAPCELL_DIM;jcell++)
  195. {
  196. long cellRow = j * MAPCELL_DIM + jcell;
  197. long cellCol = i * MAPCELL_DIM + icell;
  198. GameMap->setMine(cellRow,cellCol,0);
  199. }
  200. }
  201. }
  202. }
  203. }
  204. return pRetAction;
  205. }
  206. bool Eraser::EraserAction::undo()
  207. {
  208. bool bRetVal = bldgAction.redo();
  209. bRetVal = linkAction.undo() && bRetVal;
  210. /*teamAction.undo() must occur after bldgAction.redo() (after the deleted buildings have
  211. been restored)*/
  212. if (teamsActionIsSet)
  213. {
  214. bRetVal = teamsAction.undo() && bRetVal;
  215. }
  216. bRetVal = ActionPaintTile::undo() && bRetVal;
  217. return bRetVal;
  218. }
  219. bool Eraser::EraserAction::redo()
  220. {
  221. bool bRetVal = true;
  222. /*teamAction.redo() must occur before bldgAction.undo() (before the buildings are deleted)*/
  223. if (teamsActionIsSet)
  224. {
  225. bRetVal = teamsAction.redo();
  226. }
  227. bRetVal = linkAction.redo() && bRetVal;
  228. bRetVal = bldgAction.undo() && bRetVal;
  229. bRetVal = ActionPaintTile::undo() && bRetVal;
  230. return bRetVal;
  231. }
  232. //*************************************************************************************************
  233. // end of file ( eraser.cpp )