CliffModifier.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. /*
  2. FinalSun/FinalAlert 2 Mission Editor
  3. Copyright (C) 1999-2024 Electronic Arts, Inc.
  4. Authored by Matthias Wagner
  5. This program is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <https://www.gnu.org/licenses/>.
  15. */
  16. // CliffModifier.cpp: Implementierung der Klasse CCliffModifier.
  17. //
  18. //////////////////////////////////////////////////////////////////////
  19. #include "stdafx.h"
  20. #include "stdafx.h"
  21. #include "CliffModifier.h"
  22. #include "variables.h"
  23. #ifdef _DEBUG
  24. #undef THIS_FILE
  25. static char THIS_FILE[]=__FILE__;
  26. #define new DEBUG_NEW
  27. #endif
  28. //////////////////////////////////////////////////////////////////////
  29. // Konstruktion/Destruktion
  30. //////////////////////////////////////////////////////////////////////
  31. CCliffModifier::CCliffModifier()
  32. {
  33. }
  34. CCliffModifier::~CCliffModifier()
  35. {
  36. }
  37. BOOL CCliffModifier::PlaceCliff(DWORD dwXFrom, DWORD dwYFrom, DWORD dwXDest, DWORD dwYDest, BOOL bAlternative)
  38. {
  39. m_bAlternative=bAlternative;
  40. int x_diff, y_diff;
  41. x_diff=dwXDest-dwXFrom;
  42. y_diff=dwYDest-dwYFrom;
  43. if(x_diff>0 && y_diff>0 && ((float)y_diff)/((float)x_diff) > 1.33f)
  44. {
  45. x_diff=0;
  46. dwXDest=dwXFrom;
  47. }
  48. if(x_diff<0 && y_diff>0 && ((float)y_diff)/(-(float)x_diff) > 1.33f)
  49. {
  50. x_diff=0;
  51. dwXDest=dwXFrom;
  52. }
  53. if(x_diff>0 && y_diff<0 && ((float)-y_diff)/((float)x_diff) > 1.33f)
  54. {
  55. x_diff=0;
  56. dwXDest=dwXFrom;
  57. }
  58. if(x_diff<0 && y_diff<0 && (-(float)y_diff)/(-(float)x_diff) > 1.33f)
  59. {
  60. x_diff=0;
  61. dwXDest=dwXFrom;
  62. }
  63. if(y_diff>0 && x_diff>0 && ((float)x_diff)/((float)y_diff) > 2)
  64. {
  65. y_diff=0;
  66. dwYDest=dwYFrom;
  67. }
  68. if(y_diff<0 && x_diff>0 && ((float)x_diff)/(-(float)y_diff) > 2)
  69. {
  70. y_diff=0;
  71. dwYDest=dwYFrom;
  72. }
  73. if(y_diff>0 && x_diff<0 && ((float)-x_diff)/((float)y_diff) > 2)
  74. {
  75. y_diff=0;
  76. dwYDest=dwYFrom;
  77. }
  78. if(y_diff<0 && x_diff<0 && (-(float)x_diff)/(-(float)y_diff) > 2)
  79. {
  80. y_diff=0;
  81. dwYDest=dwYFrom;
  82. }
  83. m_dwFrom=dwXFrom + dwYFrom*Map->GetIsoSize();
  84. m_dwTo=dwXDest + dwYDest*Map->GetIsoSize();
  85. if(!x_diff && !y_diff) return FALSE;
  86. if(x_diff && y_diff)
  87. {
  88. if((x_diff>0 && y_diff>0))
  89. {
  90. m_direction=cd_verticdiag_bottom;
  91. }
  92. else if((x_diff<0 && y_diff<0))
  93. {
  94. m_direction=cd_verticdiag_top;
  95. }
  96. else if((x_diff<0 && y_diff>0) )
  97. {
  98. m_direction=cd_horizdiag_right;
  99. }
  100. else if(x_diff>0 && y_diff<0)
  101. {
  102. m_direction=cd_horizdiag_left;
  103. }
  104. }
  105. else if(y_diff<0)
  106. {
  107. m_direction=cd_horiz_left;
  108. }
  109. else if(y_diff>0)
  110. {
  111. m_direction=cd_horiz_right;
  112. }
  113. else if(x_diff<0)
  114. {
  115. m_direction=cd_vertic_top;
  116. }
  117. else if(x_diff>0)
  118. {
  119. m_direction=cd_vertic_bottom;
  120. }
  121. switch(m_direction)
  122. {
  123. case cd_horiz_left:
  124. m_addx=0;
  125. m_addy=-1;
  126. break;
  127. case cd_horiz_right:
  128. m_addx=0;
  129. m_addy=1;
  130. break;
  131. case cd_horizdiag_left:
  132. m_addx=1;
  133. m_addy=-1;
  134. break;
  135. case cd_horizdiag_right:
  136. m_addx=-1;
  137. m_addy=1;
  138. break;
  139. case cd_vertic_top:
  140. m_addx=-1;
  141. m_addy=0;
  142. break;
  143. case cd_vertic_bottom:
  144. m_addx=1;
  145. m_addy=0;
  146. break;
  147. case cd_verticdiag_top:
  148. m_addx=-1;
  149. m_addy=-1;
  150. break;
  151. case cd_verticdiag_bottom:
  152. m_addx=1;
  153. m_addy=1;
  154. break;
  155. }
  156. int i,e;
  157. DWORD dwCurPos=m_dwFrom;
  158. int startheight=Map->GetHeightAt(dwCurPos);
  159. DWORD dwLastTile=-1;
  160. FIELDDATA* fd=Map->GetFielddataAt(dwCurPos);
  161. int ground=fd->wGround;
  162. int subtile=fd->bSubTile;
  163. if(ground==0xFFFF) ground=0;
  164. startheight-=(*tiledata)[ground].tiles[subtile].bZHeight;
  165. ModifyStartPos(&dwCurPos, FALSE);
  166. BOOL bSmall=FALSE;
  167. DWORD dwFirstStartPos=dwCurPos;
  168. DWORD dwTile=GetTileToPlace(dwCurPos, &bSmall);
  169. BOOL bFirstPos=TRUE;
  170. while(dwCurPos!=m_dwTo)
  171. {
  172. ModifyCurrentPos(&dwCurPos, TRUE, bSmall);
  173. if(!bFirstPos)
  174. {
  175. dwTile=GetTileToPlace(dwCurPos, &bSmall);
  176. dwLastTile=dwTile;
  177. }
  178. else
  179. bFirstPos=FALSE;
  180. if(dwTile==-1) break;
  181. TILEDATA* t=&(*tiledata)[dwTile];
  182. if(m_addx<0) dwCurPos+=t->cx*m_addx;
  183. if(m_addy<0) dwCurPos+=t->cy*m_addy*Map->GetIsoSize();
  184. int o=0;
  185. DWORD dwTmpTile=dwTile;
  186. while(dwFirstStartPos!=dwCurPos && dwTile==dwLastTile)
  187. {
  188. o++;
  189. if(o==10) break;
  190. dwTmpTile=GetTileToPlace(dwCurPos, &bSmall);
  191. if((*tiledata)[dwTmpTile].cx==(*tiledata)[dwTile].cx && (*tiledata)[dwTile].cy==(*tiledata)[dwTmpTile].cy)
  192. dwTile=dwTmpTile;
  193. }
  194. t=&(*tiledata)[dwTile];
  195. int p=0;
  196. for(i=0;i<t->cx;i++)
  197. {
  198. for(e=0;e<t->cy;e++)
  199. {
  200. if(t->tiles[p].pic!=NULL)
  201. {
  202. Map->SetHeightAt(dwCurPos+i+e*Map->GetIsoSize(), startheight+t->tiles[p].bZHeight);
  203. Map->SetTileAt(dwCurPos+i+e*Map->GetIsoSize(), dwTile, p);
  204. }
  205. p++;
  206. }
  207. }
  208. if(m_addx>0) dwCurPos+=t->cx*m_addx;
  209. if(m_addy>0) dwCurPos+=t->cy*m_addy*Map->GetIsoSize();
  210. ModifyCurrentPos(&dwCurPos, FALSE, bSmall);
  211. dwLastTile=dwTile;
  212. }
  213. return TRUE;
  214. }
  215. void CCliffModifier::ModifyStartPos(DWORD *dwStartPos, BOOL bSmall)
  216. {
  217. }
  218. void CCliffModifier::ModifyCurrentPos(DWORD *dwPos, BOOL bBeforePlacing, BOOL bSmall)
  219. {
  220. }
  221. DWORD CCliffModifier::GetTileToPlace(DWORD dwPos, BOOL* bSmall)
  222. {
  223. vector<DWORD> careables;
  224. vector<DWORD> useables;
  225. map<DWORD, BOOL> notusedascliff;
  226. CString type;
  227. int count=0;
  228. switch(m_direction)
  229. {
  230. case cd_horiz_left:
  231. case cd_horiz_right:
  232. type="horiz_";
  233. break;
  234. case cd_horizdiag_left:
  235. case cd_horizdiag_right:
  236. type="horiz_diag_";
  237. break;
  238. case cd_vertic_top:
  239. case cd_vertic_bottom:
  240. type="vertic_";
  241. break;
  242. case cd_verticdiag_top:
  243. case cd_verticdiag_bottom:
  244. type="vertic_diag_";
  245. break;
  246. }
  247. CString sec=GetDataSection();
  248. CIniFile& ini=Map->GetIniFile();
  249. if(g_data.sections.find(sec+ini.sections["Map"].values["Theater"])!=g_data.sections.end())
  250. sec=sec+ini.sections["Map"].values["Theater"];
  251. count=atoi(g_data.sections[sec].values[type+"c"]);
  252. int i;
  253. DWORD dwStartSet=0;
  254. /*for(i=0;i<(*tiledata_count);i++)
  255. {
  256. if( (!m_bAlternative && (*tiledata)[i].wTileSet==cliffset) || (m_bAlternative && (*tiledata)[i].wTileSet==cliff2set))
  257. {
  258. dwStartSet=i;
  259. break;
  260. }
  261. }*/
  262. // a bit faster:
  263. if(m_bAlternative) dwStartSet=cliff2set_start;
  264. else dwStartSet=cliffset_start;
  265. for(i=0;i<count;i++)
  266. {
  267. char c[50];
  268. itoa(i, c, 10);
  269. CString cur=type;
  270. cur+=c;
  271. notusedascliff[dwStartSet+atoi(g_data.sections[sec].values[cur])]=TRUE;
  272. }
  273. CString corner_searched="";
  274. DWORD dwCurPos=dwPos;
  275. int isosize=Map->GetIsoSize();
  276. ModifyStartPos(&dwCurPos, FALSE);
  277. int e;
  278. for(i=-1;i<2;i++)
  279. {
  280. for(e=-1;e<2;e++)
  281. {
  282. FIELDDATA* fd=Map->GetFielddataAt(dwCurPos+i+e*isosize);
  283. int ground=fd->wGround;
  284. if(ground==0xFFFF) ground=0;
  285. if( (*tiledata)[ground].wTileSet==cliffset && notusedascliff.find(ground)==notusedascliff.end())
  286. {
  287. if(i==0 && e==-1) {corner_searched="cornerleft_";break;}
  288. if(i==0 && e==1) {corner_searched="cornerright_";break;}
  289. if(i==-1 && e==0) {corner_searched="cornertop_";break;}
  290. if(i==1 && e==0) {corner_searched="cornerbottom_";break;}
  291. /*if(e==-1) {corner_searched="cornerleft_";break;}
  292. if(e==1) {corner_searched="cornerright_";break;}
  293. if(i==-1) {corner_searched="cornertop_";break;}
  294. if(i==1) {corner_searched="cornerbottom_";break;}*/
  295. }
  296. }
  297. if(corner_searched.GetLength()>0) break;
  298. }
  299. BOOL bCornerFound=FALSE;
  300. if(g_data.sections[sec].FindName(type+corner_searched+"c")>=0)
  301. {
  302. int icount=atoi(g_data.sections[sec].values[type+corner_searched+"c"]);
  303. if(icount)
  304. {
  305. bCornerFound=TRUE;
  306. count=icount;
  307. }
  308. }
  309. if(!bCornerFound) corner_searched="";
  310. if(count==0) return -1;
  311. DWORD dwX=dwPos%Map->GetIsoSize();
  312. DWORD dwY=dwPos/Map->GetIsoSize();
  313. DWORD dwDX=m_dwTo%Map->GetIsoSize();
  314. DWORD dwDY=m_dwTo/Map->GetIsoSize();
  315. for(i=0;i<count;i++)
  316. {
  317. char c[50];
  318. itoa(i,c,10);
  319. careables.push_back(dwStartSet+atoi(g_data.sections[sec].values[type+corner_searched+c]));
  320. }
  321. for(i=0;i<careables.size();i++)
  322. {
  323. TILEDATA& t=(*tiledata)[careables[i]];
  324. if(m_addx>0 && dwX+m_addx*t.cx>dwDX) continue;
  325. if(m_addy>0 && dwY+m_addy*t.cy>dwDY) continue;
  326. if(m_addx<0 && dwX+m_addx*t.cx<dwDX) continue;
  327. if(m_addy<0 && dwY+m_addy*t.cy<dwDY) continue;
  328. useables.push_back(careables[i]);
  329. }
  330. if(useables.size()<1) return -1;
  331. *bSmall=FALSE;
  332. int k;
  333. k=rand()%(useables.size());
  334. TILEDATA& t1=(*tiledata)[useables[k]];
  335. for(i=0;i<careables.size();i++)
  336. {
  337. TILEDATA& t=(*tiledata)[careables[i]];
  338. if(t.cx>t1.cx || t.cy>t1.cy) {*bSmall=TRUE; break;}
  339. }
  340. // check for water
  341. BOOL bWater=FALSE;
  342. for(i=0;i<t1.cx;i++)
  343. {
  344. for(e=0;e<t1.cy;e++)
  345. {
  346. FIELDDATA* fd=Map->GetFielddataAt(dwPos+i+e*Map->GetIsoSize());
  347. int ground=fd->wGround;
  348. if(ground==0xFFFF) ground=0;
  349. if((i==t1.cx-1 || e==t1.cy-1) && (*tiledata)[ground].tiles[fd->bSubTile].bHackedTerrainType==TERRAINTYPE_WATER)
  350. {
  351. bWater=TRUE;
  352. break;
  353. }
  354. }
  355. if(bWater) break;
  356. }
  357. if(bWater && useables[k]-dwStartSet<22)
  358. {
  359. CString tset;
  360. char c[50];
  361. int watercliffs=atoi(tiles->sections["General"].values["WaterCliffs"]);
  362. if(m_bAlternative) watercliffs=cliffwater2set;
  363. itoa(watercliffs, c, 10);
  364. int e;
  365. for(e=0;e<4-strlen(c);e++)
  366. tset+="0";
  367. tset+=c;
  368. CString sec="TileSet";
  369. sec+=tset;
  370. if(tiles->sections.find(sec)==tiles->sections.end()) return useables[k];
  371. if(atoi(tiles->sections[sec].values["TilesInSet"])>useables[k]-dwStartSet)
  372. {
  373. DWORD dwStartWaterSet=0;
  374. for(i=0;i<(*tiledata_count);i++)
  375. {
  376. if((*tiledata)[i].wTileSet==watercliffs)
  377. {
  378. dwStartWaterSet=i;
  379. return dwStartWaterSet+(useables[k]-dwStartSet);
  380. }
  381. }
  382. }
  383. }
  384. return useables[k];
  385. }