LinkBrush.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. //----------------------------------------------------------------------------
  2. //
  3. // LinkBrush.cpp - the link brush links turrets to turret controls, gates to
  4. // gate controls etc.
  5. //
  6. //---------------------------------------------------------------------------//
  7. // Copyright (C) Microsoft Corporation. All rights reserved. //
  8. //===========================================================================//
  9. #include "LinkBrush.h"
  10. #include "BuildingLink.h"
  11. #include "EditorObjectMgr.h"
  12. LinkBrush::LinkBrush( bool Link )
  13. {
  14. // here we need to get all of the links on the map
  15. // and add an interface element for each one.
  16. parentPos.x = parentPos.y = -1;
  17. bLink = Link;
  18. parent = NULL;
  19. }
  20. LinkBrush::~LinkBrush()
  21. {
  22. }
  23. bool LinkBrush::beginPaint()
  24. {
  25. pAction = new LinkAction();
  26. return true;
  27. }
  28. Action* LinkBrush::endPaint()
  29. {
  30. if ( pAction && pAction->changedLinks.Count() )
  31. {
  32. return pAction;
  33. }
  34. else
  35. delete pAction;
  36. return NULL;
  37. }
  38. bool LinkBrush::paint( Stuff::Vector3D& worldPos, int screenX, int screenY )
  39. {
  40. if ( !bLink )
  41. return unPaint( worldPos, screenX, screenY );
  42. const EditorObject* pObject = EditorObjectMgr::instance()->getObjectAtPosition( worldPos );
  43. if ( !pObject )
  44. return 0;
  45. if (BuildingLink::TypeCanBeParent( pObject ) &&
  46. ( !parent || ( parent && !BuildingLink::CanLink( parent, pObject ) ) ) )
  47. {
  48. parent = pObject;
  49. parentPos = parent->getPosition();
  50. BuildingLink* pLink = EditorObjectMgr::instance()->getLinkWithParent( pObject );
  51. if ( pLink )
  52. {
  53. pAction->AddToListOnce( LinkInfo(pLink, LinkInfo::EDIT) );
  54. }
  55. else
  56. {
  57. BuildingLink* pLink = new BuildingLink( pObject );
  58. EditorObjectMgr::instance()->addLink( pLink );
  59. pAction->AddToListOnce( LinkInfo(pLink, LinkInfo::ADD) );
  60. }
  61. }
  62. else // we already have a parnet, this is a child building
  63. {
  64. if ( !parent )
  65. {
  66. return false;
  67. }
  68. BuildingLink* pLink = EditorObjectMgr::instance()->getLinkWithParent( parent );
  69. if ( !pLink )
  70. {
  71. pLink = new BuildingLink( parent );
  72. EditorObjectMgr::instance()->addLink( pLink );
  73. pAction->AddToListOnce( LinkInfo(pLink, LinkInfo::ADD) );
  74. }
  75. BuildingLink* pOldLink = EditorObjectMgr::instance()->getLinkWithBuilding( pObject );
  76. if ( pOldLink && pOldLink != pLink )
  77. {
  78. pAction->AddToListOnce( LinkInfo(pOldLink, LinkInfo::EDIT ) );
  79. pOldLink->RemoveObject( pObject );
  80. pAction->AddToListOnce( LinkInfo( pLink, LinkInfo::EDIT ));
  81. }
  82. if ( !pLink->AddChild( pObject ) )
  83. {
  84. SPEW((0,"LinkBrush failed to add a link to a parent\n"));
  85. }
  86. if ( pObject->getSpecialType() != EditorObjectMgr::POWER_STATION )
  87. (const_cast<EditorObject*>(pObject))->setAlignment( parent->getAlignment() );
  88. return true;
  89. }
  90. return false;
  91. }
  92. bool LinkBrush::canPaint( Stuff::Vector3D& pos, int x, int y, int flags )
  93. {
  94. if ( !bLink )
  95. return canUnPaint( pos, x, y, flags );
  96. const EditorObject* pObject = EditorObjectMgr::instance()->getObjectAtPosition( pos );
  97. if ( !pObject )
  98. return false;
  99. if ( BuildingLink::TypeCanBeParent( pObject) ) // see if this can be a parent
  100. {
  101. return true;
  102. }
  103. else if ( parent )
  104. {
  105. if ( BuildingLink::CanLink( parent, pObject) )
  106. return true;
  107. }
  108. return false;
  109. }
  110. bool LinkBrush::canUnPaint( Stuff::Vector3D& pos, int x, int y, int flags )
  111. {
  112. const EditorObject* pBuilding = EditorObjectMgr::instance()->getObjectAtPosition( pos );
  113. if ( !pBuilding )
  114. return false;
  115. if ( EditorObjectMgr::instance()->getLinkWithParent( pBuilding ) )
  116. return true;
  117. else if ( EditorObjectMgr::instance()->getLinkWithBuilding( pBuilding) )
  118. return true;
  119. return false;
  120. }
  121. int LinkBrush::LinkAction::AddToListOnce( const LinkBrush::LinkInfo& Info )
  122. {
  123. for( EList< LinkInfo, const LinkInfo& >::EIterator iter = changedLinks.Begin();
  124. !iter.IsDone(); iter++ )
  125. {
  126. if ( (*iter).m_LinkCopy.GetParentPosition() == Info.m_LinkCopy.GetParentPosition() )
  127. {
  128. return 0; // assume if parents are in the same place, we have the same link
  129. }
  130. }
  131. changedLinks.Append( Info );
  132. return 1;
  133. }
  134. LinkBrush::LinkAction::LinkAction( )
  135. {
  136. }
  137. bool LinkBrush::LinkAction::undo( )
  138. {
  139. // go through each of the objects in the list
  140. for ( EList<LinkInfo, const LinkInfo& >::EIterator iter = changedLinks.End();
  141. !iter.IsDone(); iter-- )
  142. {
  143. if ( (*iter).type == LinkInfo::ADD )
  144. {
  145. // change the type to remove, and take it out of the map
  146. (*iter).type = LinkInfo::REMOVE;
  147. Stuff::Vector3D pos = (*iter).m_LinkCopy.GetParentPosition();
  148. const EditorObject* pBuilding = EditorObjectMgr::instance()->getObjectAtLocation( pos.x, pos.y );
  149. gosASSERT( pBuilding );
  150. if ( pBuilding )
  151. {
  152. BuildingLink* pLink = EditorObjectMgr::instance()->getLinkWithBuilding( pBuilding );
  153. if ( pLink )
  154. {
  155. (*iter).m_LinkCopy = *(pLink);
  156. EditorObjectMgr::instance()->deleteLink( pLink );
  157. }
  158. }
  159. }
  160. else if ( (*iter).type == LinkInfo::REMOVE )
  161. {
  162. // change the type to remove, and take it out of the map
  163. (*iter).type = LinkInfo::ADD;
  164. EditorObjectMgr::instance()->addLink( new BuildingLink((*iter).m_LinkCopy) );
  165. // make sure each of the buildings in the link has the right alignment
  166. int LinkCount = (*iter).m_LinkCopy.GetLinkCount();
  167. Stuff::Vector3D* pPoints = new Stuff::Vector3D[LinkCount];
  168. (*iter).m_LinkCopy.GetChildrenPositions( pPoints, LinkCount );
  169. Stuff::Vector3D pos = (*iter).m_LinkCopy.GetParentPosition();
  170. const EditorObject* pBuilding = EditorObjectMgr::instance()->getObjectAtLocation( pos.x, pos.y );
  171. if ( !pBuilding )
  172. return false;
  173. int align = pBuilding->getAlignment();
  174. for ( int i = 0; i < LinkCount; ++i )
  175. {
  176. const EditorObject* pObject = EditorObjectMgr::instance()->getObjectAtLocation( pPoints[i].x, pPoints[i].y );
  177. if ( pObject )
  178. {
  179. (const_cast<EditorObject*>(pObject))->setAlignment( align );
  180. }
  181. }
  182. }
  183. else if ( (*iter).type == LinkInfo::EDIT )
  184. {
  185. // need to find the original link, look for one with matching
  186. // parents
  187. Stuff::Vector3D pos = (*iter).m_LinkCopy.GetParentPosition();
  188. const EditorObject* pBuilding = EditorObjectMgr::instance()->getObjectAtLocation( pos.x, pos.y );
  189. if ( pBuilding )
  190. {
  191. BuildingLink* pLink = EditorObjectMgr::instance()->getLinkWithParent( pBuilding );
  192. if ( pLink )
  193. {
  194. BuildingLink tmp( *pLink );
  195. *pLink = (*iter).m_LinkCopy;
  196. (*iter).m_LinkCopy = tmp;
  197. }
  198. }
  199. else
  200. {
  201. SPEW(( 0,"LinkBursh::LinkAction::Undo failed because the map didn't have the link\n") );
  202. return false;
  203. }
  204. }
  205. }
  206. return true;
  207. }
  208. bool LinkBrush::unPaint( Stuff::Vector3D& pos, int XPos, int yPos )
  209. {
  210. const EditorObject* pBuilding = EditorObjectMgr::instance()->getObjectAtPosition( pos );
  211. if ( pBuilding )
  212. {
  213. BuildingLink* pLink = EditorObjectMgr::instance()->getLinkWithParent( pBuilding );
  214. if ( pLink ) // we are deleting a parent link
  215. {
  216. pAction->AddToListOnce( LinkInfo( pLink, LinkInfo::REMOVE ) );
  217. EditorObjectMgr::instance()->deleteLink( pLink );
  218. parent = NULL;
  219. parentPos.x = parentPos.y = 0;
  220. return true;
  221. }
  222. else
  223. {
  224. pLink = EditorObjectMgr::instance()->getLinkWithBuilding( pBuilding );
  225. if ( pLink )
  226. {
  227. pAction->AddToListOnce( LinkInfo( pLink, LinkInfo::EDIT ) );
  228. pLink->RemoveObject( pBuilding );
  229. }
  230. return true;
  231. }
  232. }
  233. return false;
  234. }
  235. bool LinkBrush::LinkAction::redo()
  236. {
  237. return undo();
  238. }
  239. LinkBrush::LinkInfo::LinkInfo( BuildingLink* pOriginal, LinkBrush::LinkInfo::TYPE Type ) :
  240. m_LinkCopy( *pOriginal )
  241. {
  242. type = Type;
  243. }
  244. void LinkBrush::render( int screenX, int screenY )
  245. {
  246. if ( parent )
  247. {
  248. Stuff::Vector3D parentPos = parent->getPosition();
  249. Stuff::Vector4D screenPos;
  250. Stuff::Vector4D curScreen;
  251. curScreen.x = screenX;
  252. curScreen.y = screenY;
  253. curScreen.z = 0.1f; //Gotta set Z or QNAN and crash!
  254. curScreen.w = 0.9999f; //Gotta set W, too!
  255. eye->projectZ( parentPos, screenPos );
  256. LineElement elem( curScreen, screenPos, 0xffff0000, 0, -1 );
  257. elem.draw();
  258. }
  259. }