techtree.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. #include "pch.h"
  2. CTechItemList gCivList;
  3. CTechItemList gItemList;
  4. //
  5. // Console helper functions.
  6. //
  7. VOID ClearScreen()
  8. {
  9. CONSOLE_SCREEN_BUFFER_INFO csbi;
  10. DWORD dwConSize, cbWritten;
  11. COORD coordScreen = { 0, 0 };
  12. HANDLE hConsole;
  13. hConsole = CreateFile("CONOUT$",
  14. GENERIC_READ | GENERIC_WRITE,
  15. FILE_SHARE_READ | FILE_SHARE_WRITE,
  16. NULL,
  17. OPEN_EXISTING,
  18. 0,
  19. NULL);
  20. if (NULL != hConsole)
  21. {
  22. if (TRUE == GetConsoleScreenBufferInfo(hConsole, &csbi))
  23. {
  24. dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
  25. if (TRUE == FillConsoleOutputCharacter(hConsole,
  26. ' ',
  27. dwConSize,
  28. coordScreen,
  29. &cbWritten))
  30. {
  31. if (TRUE == GetConsoleScreenBufferInfo(hConsole, &csbi))
  32. {
  33. if (TRUE == FillConsoleOutputAttribute(hConsole,
  34. csbi.wAttributes,
  35. dwConSize,
  36. coordScreen,
  37. &cbWritten))
  38. {
  39. SetConsoleCursorPosition(hConsole, coordScreen);
  40. }
  41. }
  42. }
  43. }
  44. CloseHandle(hConsole);
  45. }
  46. }
  47. VOID GetLine(CHAR * szValid, DWORD dwMax, CHAR * pch, DWORD * pdw)
  48. {
  49. CHAR s[256], *pchStart;
  50. BOOL fValid;
  51. *pch = '\0';
  52. *pdw = 0;
  53. fValid = FALSE;
  54. do
  55. {
  56. gets(s);
  57. pchStart = s;
  58. while(' ' == *pchStart)
  59. pchStart++;
  60. if (NULL != strchr(szValid, *pchStart))
  61. {
  62. *pch = *pchStart;
  63. fValid = TRUE;
  64. } else
  65. {
  66. while((*pchStart >= '0') && (*pchStart <= '9'))
  67. {
  68. *pdw = *pdw * 10 + (*pchStart - '0');
  69. *pchStart++;
  70. }
  71. if ((*pdw > 0) && (*pdw <= dwMax))
  72. fValid = TRUE;
  73. }
  74. if (FALSE == fValid)
  75. {
  76. printf("Invalid selection.\n> ");
  77. *pdw = 0;
  78. }
  79. } while(FALSE == fValid);
  80. }
  81. //
  82. // Printing functions.
  83. //
  84. VOID PrintBoughtItems(CTechItemList * pBoughtList)
  85. {
  86. CTechItem * pItem;
  87. DWORD dwIndex;
  88. if (pBoughtList->Length() > 0)
  89. {
  90. printf("Items bought:\n");
  91. printf("--------------------------\n");
  92. for(dwIndex = pBoughtList->Length(); dwIndex > 0; dwIndex--)
  93. {
  94. pItem = pBoughtList->Dequeue();
  95. printf("%s (%s)\n", pItem->GetName(), pItem->GetObjectTypeName());
  96. pBoughtList->Enqueue(pItem);
  97. }
  98. printf("\n");
  99. }
  100. }
  101. VOID PrintBuyOptions(CTechItemList * pCanBuyList, DWORD dwLastLength)
  102. {
  103. DWORD dwIndex, dwLoop;
  104. CTechItem * pItem;
  105. dwIndex = 1;
  106. dwLoop = pCanBuyList->Length();
  107. if (dwLastLength > 0)
  108. {
  109. printf("Available items:\n");
  110. printf("--------------------------\n");
  111. for( ; (dwLoop > 0) && (dwIndex < dwLastLength); dwIndex++, dwLoop--)
  112. {
  113. pItem = pCanBuyList->Dequeue();
  114. printf("%2d) %s (%s)\n", dwIndex, pItem->GetName(),
  115. pItem->GetObjectTypeName());
  116. pCanBuyList->Enqueue(pItem);
  117. }
  118. printf("\n");
  119. }
  120. if (pCanBuyList->Length() >= dwLastLength)
  121. {
  122. //
  123. // These are items new since last time.
  124. //
  125. printf("New items:\n");
  126. printf("--------------------------\n");
  127. for( ; dwLoop > 0; dwIndex++, dwLoop--)
  128. {
  129. pItem = pCanBuyList->Dequeue();
  130. printf("%2d) %s (%s)\n", dwIndex,
  131. pItem->GetName(), pItem->GetObjectTypeName());
  132. pCanBuyList->Enqueue(pItem);
  133. }
  134. printf("\n");
  135. }
  136. }
  137. VOID BuyItem(DWORD dwBuy, PURCHASE_DATA * pPurchaseData)
  138. {
  139. CTechItem * pItem;
  140. pItem = pPurchaseData->CanBuyList.RemoveNth(dwBuy - 1);
  141. if (NULL != pItem)
  142. pItem->Purchase(pPurchaseData);
  143. }
  144. BOOL AutoProcessCiv(CCivTechItem * pCiv)
  145. {
  146. PURCHASE_DATA PurchaseData;
  147. BOOL fBought, fSuccess;
  148. fSuccess = TRUE;
  149. printf("====================\n");
  150. printf("%s\n", pCiv->GetName());
  151. printf("====================\n");
  152. PurchaseData.ttbmCurrent.ClearAll();
  153. PurchaseData.dwLastCanBuyLength = 0;
  154. if (TRUE == gItemList.CopyTo(&(PurchaseData.TechItemList)))
  155. {
  156. pCiv->Purchase(&PurchaseData);
  157. do
  158. {
  159. // these lines cause the list to be printed at every step along the way
  160. //PrintBoughtItems(&(PurchaseData.BoughtList));
  161. //PrintBuyOptions(&(PurchaseData.CanBuyList),
  162. // PurchaseData.dwLastCanBuyLength);
  163. PurchaseData.dwLastCanBuyLength = PurchaseData.CanBuyList.Length();
  164. fBought = FALSE;
  165. if (PurchaseData.CanBuyList.Length() > 0)
  166. {
  167. BuyItem(1, &PurchaseData);
  168. fBought = TRUE;
  169. }
  170. } while(TRUE == fBought);
  171. } else
  172. fSuccess = FALSE;
  173. printf("\n\n");
  174. PrintBoughtItems(&(PurchaseData.BoughtList));
  175. printf("\n\n");
  176. PurchaseData.TechItemList.Empty();
  177. PurchaseData.CanBuyList.Empty();
  178. PurchaseData.BoughtList.Empty();
  179. return(fSuccess);
  180. }
  181. VOID CheckForUnboughtItems()
  182. {
  183. CTechItem * pItem;
  184. while(NULL != (pItem = gItemList.Dequeue()))
  185. {
  186. if (FALSE == pItem->WasEverBought())
  187. {
  188. printf("Warning: Never bought %s (%s).\n",
  189. pItem->GetName(), pItem->GetObjectTypeName());
  190. }
  191. delete pItem;
  192. }
  193. }
  194. VOID AutoProcess()
  195. {
  196. CCivTechItem * pCiv;
  197. DWORD dwIndex;
  198. for(dwIndex = gCivList.Length(); dwIndex > 0; dwIndex--)
  199. {
  200. pCiv = (CCivTechItem *) gCivList.Dequeue();
  201. AutoProcessCiv(pCiv);
  202. gCivList.Enqueue(pCiv);
  203. }
  204. CheckForUnboughtItems();
  205. }
  206. CCivTechItem * PickCiv()
  207. {
  208. DWORD dwIndex, dwLoop, dwTemp;
  209. CCivTechItem * pCiv, * pRet;
  210. CHAR chCommand;
  211. //
  212. // Pick a civ, quit.
  213. //
  214. printf("Available Factions:\n");
  215. printf("------------------------\n");
  216. for(dwLoop = gCivList.Length(), dwIndex = 0; dwLoop > 0;
  217. dwLoop--, dwIndex++)
  218. {
  219. pCiv = (CCivTechItem *) gCivList.Dequeue();
  220. printf("%d) %s\n", dwIndex + 1, pCiv->GetName());
  221. gCivList.Enqueue(pCiv);
  222. }
  223. printf("\n");
  224. pRet = NULL;
  225. printf("Choose a faction or (Q)uit:\n> ");
  226. GetLine("Qq", gCivList.Length(), &chCommand, &dwTemp);
  227. if ('\0' == chCommand)
  228. {
  229. for(dwLoop = gCivList.Length(), dwIndex = 1; dwLoop > 0;
  230. dwLoop--, dwIndex++)
  231. {
  232. pCiv = (CCivTechItem *) gCivList.Dequeue();
  233. if (dwIndex == dwTemp)
  234. pRet = pCiv;
  235. gCivList.Enqueue(pCiv);
  236. }
  237. }
  238. return(pRet);
  239. }
  240. VOID InteractiveProcess()
  241. {
  242. PURCHASE_DATA PurchaseData;
  243. BOOL fDone, fDoneCiv;
  244. CCivTechItem * pCiv;
  245. CHAR chCommand;
  246. DWORD dwTemp;
  247. fDone = FALSE;
  248. do
  249. {
  250. pCiv = PickCiv();
  251. if (NULL != pCiv)
  252. {
  253. PurchaseData.ttbmCurrent.ClearAll();
  254. PurchaseData.dwLastCanBuyLength = 0;
  255. //
  256. // Initialize our lists.
  257. //
  258. if (TRUE == gItemList.CopyTo(&(PurchaseData.TechItemList)))
  259. {
  260. fDoneCiv = FALSE;
  261. pCiv->Purchase(&PurchaseData);
  262. do
  263. {
  264. ClearScreen();
  265. printf("====================\n");
  266. printf("%s\n", pCiv->GetName());
  267. printf("====================\n");
  268. printf("\n");
  269. PrintBoughtItems(&(PurchaseData.BoughtList));
  270. //
  271. // Print out the list of options.
  272. //
  273. PrintBuyOptions(&(PurchaseData.CanBuyList),
  274. PurchaseData.dwLastCanBuyLength);
  275. PurchaseData.dwLastCanBuyLength =
  276. PurchaseData.CanBuyList.Length();
  277. //
  278. // Get our choice and act on it.
  279. //
  280. printf("Pick a number, (C)hange Faction or (Q)uit:\n> ");
  281. GetLine("qQcC",
  282. PurchaseData.CanBuyList.Length(),
  283. &chCommand,
  284. &dwTemp);
  285. switch(chCommand)
  286. {
  287. case 'c':
  288. case 'C':
  289. fDoneCiv = TRUE;
  290. break;
  291. case 'q':
  292. case 'Q':
  293. fDone = TRUE;
  294. break;
  295. default:
  296. BuyItem(dwTemp, &PurchaseData);
  297. break;
  298. }
  299. } while((FALSE == fDoneCiv) && (FALSE == fDone));
  300. //
  301. // Clean up our lists.
  302. //
  303. PurchaseData.TechItemList.Empty();
  304. PurchaseData.CanBuyList.Empty();
  305. PurchaseData.BoughtList.Empty();
  306. if (FALSE == fDone)
  307. ClearScreen();
  308. }
  309. } else
  310. fDone = TRUE;
  311. } while(FALSE == fDone);
  312. }
  313. VOID Usage(CHAR * argv0)
  314. {
  315. printf("Usage: %s [/a]\n", argv0);
  316. printf("/a = autoparse civ trees\n");
  317. }
  318. int _cdecl main(int argc, char * argv[])
  319. {
  320. BOOL fAutoProcess;
  321. BOOL fUsage;
  322. INT iIndex;
  323. HRESULT hr;
  324. fAutoProcess = FALSE;
  325. fUsage = FALSE;
  326. for(iIndex = 1; iIndex < argc; iIndex++)
  327. {
  328. if (0 == strcmp(argv[iIndex], "/a"))
  329. fAutoProcess = TRUE;
  330. else
  331. fUsage = TRUE;
  332. }
  333. if (FALSE == fUsage)
  334. {
  335. if (FALSE == fAutoProcess)
  336. ClearScreen();
  337. hr = Initialize("Federation", &gCivList, &gItemList);
  338. if (SUCCEEDED(hr))
  339. {
  340. if (TRUE == fAutoProcess)
  341. AutoProcess();
  342. else
  343. InteractiveProcess();
  344. Terminate(&gCivList, &gItemList);
  345. }
  346. } else
  347. Usage(argv[0]);
  348. return(0);
  349. }