FACTORY.CPP 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  1. /*
  2. ** Command & Conquer(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  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. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /* $Header: F:\projects\c&c\vcs\code\factory.cpv 2.18 16 Oct 1995 16:51:26 JOE_BOSTIC $ */
  19. /***********************************************************************************************
  20. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  21. ***********************************************************************************************
  22. * *
  23. * Project Name : Command & Conquer *
  24. * *
  25. * File Name : FACTORY.CPP *
  26. * *
  27. * Programmer : Joe L. Bostic *
  28. * *
  29. * Start Date : 12/26/94 *
  30. * *
  31. * Last Update : May 22, 1995 [JLB] *
  32. * *
  33. *---------------------------------------------------------------------------------------------*
  34. * Functions: *
  35. * FactoryClass::AI -- Process factory production logic. *
  36. * FactoryClass::Abandon -- Abandons current construction with money refunded. *
  37. * FactoryClass::Completed -- Clears factory object after a completed production process. *
  38. * FactoryClass::Completion -- Fetchs the completion step for this factory. *
  39. * FactoryClass::Cost_Per_Tick -- Breaks entire production cost into managable chunks. *
  40. * FactoryClass::FactoryClass -- Default constructor for factory objects. *
  41. * FactoryClass::Get_Object -- Fetches pointer to object being constructed. *
  42. * FactoryClass::Get_Special_Item -- gets factorys spc prod item *
  43. * FactoryClass::Has_Changed -- Checks to see if a production step has occurred? *
  44. * FactoryClass::Has_Completed -- Checks to see if object has completed production. *
  45. * FactoryClass::Set -- Assigns a factory to produce an object. *
  46. * FactoryClass::Set -- Fills a factory with an already completed object. *
  47. * FactoryClass::Set -- Force factory to "produce" special object. *
  48. * FactoryClass::Start -- Resumes production after suspension or creation. *
  49. * FactoryClass::Suspend -- Temporarily stop production. *
  50. * FactoryClass::operator delete -- Returns a factory to the free factory pool. *
  51. * FactoryClass::operator new -- Allocates a factory object from the free factory pool. *
  52. * FactoryClass::~FactoryClass -- Default destructor for factory objects. *
  53. * FactoryClass::Validate -- validates factory pointer *
  54. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  55. #include "function.h"
  56. /***********************************************************************************************
  57. * FactoryClass::Validate -- validates factory pointer *
  58. * *
  59. * INPUT: *
  60. * none. *
  61. * *
  62. * OUTPUT: *
  63. * 1 = ok, 0 = error *
  64. * *
  65. * WARNINGS: *
  66. * none. *
  67. * *
  68. * HISTORY: *
  69. * 08/09/1995 BRR : Created. *
  70. *=============================================================================================*/
  71. #ifdef CHEAT_KEYS
  72. int FactoryClass::Validate(void) const
  73. {
  74. int num;
  75. num = Factories.ID(this);
  76. if (num < 0 || num >= FACTORY_MAX) {
  77. Validate_Error("FACTORY");
  78. return (0);
  79. }
  80. else
  81. return (1);
  82. }
  83. #else
  84. #define Validate()
  85. #endif
  86. /***********************************************************************************************
  87. * FactoryClass::FactoryClass -- Default constructor for factory objects. *
  88. * *
  89. * This brings the factory into a null state. It is called when a factory object is *
  90. * created. *
  91. * *
  92. * INPUT: none *
  93. * *
  94. * OUTPUT: none *
  95. * *
  96. * WARNINGS: none *
  97. * *
  98. * HISTORY: *
  99. * 12/26/1994 JLB : Created. *
  100. *=============================================================================================*/
  101. FactoryClass::FactoryClass(void)
  102. {
  103. IsSuspended = false;
  104. IsDifferent = false;
  105. Balance = 0;
  106. SpecialItem = SPC_NONE;
  107. Object = NULL;
  108. House = NULL;
  109. Set_Rate(0);
  110. Set_Stage(0);
  111. }
  112. /***********************************************************************************************
  113. * FactoryClass::~FactoryClass -- Default destructor for factory objects. *
  114. * *
  115. * This cleans up a factory object in preparation for deletion. If there is currently *
  116. * an object in production, it is abandoned and money is refunded. *
  117. * *
  118. * INPUT: none *
  119. * *
  120. * OUTPUT: none *
  121. * *
  122. * WARNINGS: none *
  123. * *
  124. * HISTORY: *
  125. * 12/26/1994 JLB : Created. *
  126. *=============================================================================================*/
  127. FactoryClass::~FactoryClass(void)
  128. {
  129. if (GameActive) {
  130. Abandon();
  131. }
  132. }
  133. /***********************************************************************************************
  134. * FactoryClass::Init -- Clears all units for scenario preparation. *
  135. * *
  136. * This routine will zero out the factory list and objects. This routine is typically *
  137. * used in preparation for a new scenario load. All factorys are guaranteed to be eliminated*
  138. * by this routine. *
  139. * *
  140. * INPUT: none *
  141. * *
  142. * OUTPUT: none *
  143. * *
  144. * WARNINGS: none *
  145. * *
  146. * HISTORY: *
  147. * 08/15/1994 JLB : Created. *
  148. *=============================================================================================*/
  149. void FactoryClass::Init(void)
  150. {
  151. Factories.Free_All();
  152. }
  153. /***********************************************************************************************
  154. * FactoryClass::operator new -- Allocates a factory object from the free factory pool. *
  155. * *
  156. * This routine allocates a factory from the free factory pool. If there is no more room *
  157. * to allocate a factory, then NULL is returned. *
  158. * *
  159. * INPUT: none *
  160. * *
  161. * OUTPUT: Returns with pointer to the newly allocated factory object. *
  162. * *
  163. * WARNINGS: none *
  164. * *
  165. * HISTORY: *
  166. * 12/26/1994 JLB : Created. *
  167. *=============================================================================================*/
  168. void * FactoryClass::operator new(size_t)
  169. {
  170. void * ptr = Factories.Allocate();
  171. if (ptr) {
  172. ((FactoryClass *)ptr)->IsActive = true;
  173. }
  174. return(ptr);
  175. }
  176. /***********************************************************************************************
  177. * FactoryClass::operator delete -- Returns a factory to the free factory pool. *
  178. * *
  179. * This returns the factory object back to the factory allocation pool. The factory is then *
  180. * available to be allocated. *
  181. * *
  182. * INPUT: ptr -- Pointer to the factory object to delete. *
  183. * *
  184. * OUTPUT: none *
  185. * *
  186. * WARNINGS: none *
  187. * *
  188. * HISTORY: *
  189. * 12/26/1994 JLB : Created. *
  190. *=============================================================================================*/
  191. void FactoryClass::operator delete(void *ptr)
  192. {
  193. if (ptr) {
  194. ((FactoryClass *)ptr)->IsActive = false;
  195. }
  196. Factories.Free((FactoryClass *)ptr);
  197. }
  198. /***********************************************************************************************
  199. * FactoryClass::AI -- Process factory production logic. *
  200. * *
  201. * This routine should be called once per game tick. It handles the production process. *
  202. * As production proceeds, money is deducted from the owner object's house. When production *
  203. * completes, the factory stop processing. A call to Abandon, Delete, or Completed is *
  204. * required after that point. *
  205. * *
  206. * INPUT: none *
  207. * *
  208. * OUTPUT: none *
  209. * *
  210. * WARNINGS: none *
  211. * *
  212. * HISTORY: *
  213. * 12/26/1994 JLB : Created. *
  214. * 01/04/1995 JLB : Uses exact installment payment method. *
  215. *=============================================================================================*/
  216. void FactoryClass::AI(void)
  217. {
  218. Validate();
  219. if (!IsSuspended && (Object != NULL || SpecialItem)) {
  220. int stages = 1;
  221. /*
  222. ** Determine the acceleration factor for factory production.
  223. ** This applies only to human players. The computer builds
  224. ** units on a building by building basis -- quantity of building
  225. ** factory types doesn't affect individual factories.
  226. */
  227. if (Object && House->IsHuman) {
  228. switch (Object->What_Am_I()) {
  229. case RTTI_AIRCRAFT:
  230. stages = House->AircraftFactories;
  231. break;
  232. case RTTI_INFANTRY:
  233. stages = House->InfantryFactories;
  234. break;
  235. case RTTI_UNIT:
  236. stages = House->UnitFactories;
  237. break;
  238. case RTTI_BUILDING:
  239. stages = House->BuildingFactories;
  240. break;
  241. }
  242. stages = MAX(stages, 1);
  243. }
  244. for (int index = 0; index < stages; index++) {
  245. if (!Has_Completed() && Graphic_Logic()) {
  246. IsDifferent = true;
  247. int cost = Cost_Per_Tick();
  248. cost = MIN(cost, Balance);
  249. /*
  250. ** Enough time has expired so that another production step can occur.
  251. ** If there is insufficient funds, then go back one production step and
  252. ** continue the countdown. The idea being that by the time the next
  253. ** production step occurs, there may be sufficient funds available.
  254. */
  255. if (cost > House->Available_Money()) {
  256. Set_Stage(Fetch_Stage()-1);
  257. } else {
  258. House->Spend_Money(cost);
  259. Balance -= cost;
  260. }
  261. if ( Debug_Instant_Build ) {
  262. Set_Stage(STEP_COUNT);
  263. }
  264. /*
  265. ** If the production has completed, then suspend further production.
  266. */
  267. if (Fetch_Stage() == STEP_COUNT) {
  268. IsSuspended = true;
  269. Set_Rate(0);
  270. House->Spend_Money(Balance);
  271. Balance = 0;
  272. }
  273. }
  274. }
  275. }
  276. }
  277. /***********************************************************************************************
  278. * FactoryClass::Has_Changed -- Checks to see if a production step has occurred? *
  279. * *
  280. * Use this routine to determine if production has advanced at least one step. By using *
  281. * this function, intelligent rendering may be performed. *
  282. * *
  283. * INPUT: none *
  284. * *
  285. * OUTPUT: bool; Has the production process advanced one step since the last time this *
  286. * function was called? *
  287. * *
  288. * WARNINGS: This function clears the changed status flag as a side effect. *
  289. * *
  290. * HISTORY: *
  291. * 12/26/1994 JLB : Created. *
  292. *=============================================================================================*/
  293. bool FactoryClass::Has_Changed(void)
  294. {
  295. Validate();
  296. bool changed = IsDifferent;
  297. IsDifferent = false;
  298. return(changed);
  299. }
  300. /***********************************************************************************************
  301. * FactoryClass::Set -- Assigns a factory to produce an object. *
  302. * *
  303. * This routine initializes a factory to produce the object specified. The desired object *
  304. * type is created and placed in suspended animation (limbo) until such time as production *
  305. * completes. Production is not actually started by this routine. An explicit call to *
  306. * Start() is required to begin production. *
  307. * *
  308. * INPUT: object -- Reference to the object type class that is to be produced. *
  309. * *
  310. * house -- Reference to the owner of the object to be produced. *
  311. * *
  312. * OUTPUT: bool; Was production successfully prepared for this factory object. Failure means *
  313. * that the object could not be created. This is catastrophic and in such *
  314. * cases, the factory object should be deleted. *
  315. * *
  316. * WARNINGS: Be sure to examine the return value from this function. Failure to initialize *
  317. * the factory means that the factory is useless and should be deleted. *
  318. * *
  319. * HISTORY: *
  320. * 12/26/1994 JLB : Created. *
  321. *=============================================================================================*/
  322. bool FactoryClass::Set(TechnoTypeClass const & object, HouseClass & house)
  323. {
  324. Validate();
  325. /*
  326. ** If there is any production currently in progress, abandon it.
  327. */
  328. Abandon();
  329. /*
  330. ** Set up the factory for the new production process.
  331. */
  332. IsDifferent = true;
  333. IsSuspended = true;
  334. Set_Rate(0);
  335. Set_Stage(0);
  336. /*
  337. ** Create an object of the type requested.
  338. */
  339. Object = (TechnoClass *)object.Create_One_Of(&house);
  340. if (Object) {
  341. House = Object->House;
  342. Balance = object.Cost_Of();
  343. Object->PurchasePrice = Balance;
  344. }
  345. /*
  346. ** If all was set up successfully, then return true.
  347. */
  348. return(Object != NULL);
  349. }
  350. /***********************************************************************************************
  351. * FactoryClass::Set -- Force factory to "produce" special object. *
  352. * *
  353. * Use this routine to force the factory into special production mode. Such production is *
  354. * used for the ion cannon and other timed special weapon events. *
  355. * *
  356. * INPUT: type -- The special weapon type to begin "production" of. *
  357. * *
  358. * house -- The owner of this production object. *
  359. * *
  360. * OUTPUT: Was the assignment successful? *
  361. * *
  362. * WARNINGS: none *
  363. * *
  364. * HISTORY: *
  365. * 05/22/1995 JLB : Created. *
  366. *=============================================================================================*/
  367. bool FactoryClass::Set(int const & type, HouseClass & house)
  368. {
  369. Validate();
  370. /*
  371. ** If there is any production currently in progress, abandon it.
  372. */
  373. Abandon();
  374. /*
  375. ** Set up the factory for the new production process.
  376. */
  377. IsDifferent = true;
  378. IsSuspended = true;
  379. Set_Rate(0);
  380. Set_Stage(0);
  381. /*
  382. ** Create an object of the type requested.
  383. */
  384. SpecialItem = type;
  385. House = &house;
  386. Balance = 0;
  387. /*
  388. ** If all was set up successfully, then return true.
  389. */
  390. return(SpecialItem != SPC_NONE);
  391. }
  392. /***********************************************************************************************
  393. * FactoryClass::Set -- Fills a factory with an already completed object. *
  394. * *
  395. * This routine is called when a produced object is in placement mode but then placement *
  396. * is suspended. The object must then return to the factory as if it were newly completed *
  397. * and awaiting removal. *
  398. * *
  399. * INPUT: object -- The object to return to the factory. *
  400. * *
  401. * OUTPUT: none *
  402. * *
  403. * WARNINGS: This will abandon any current object being produced at the factory in order *
  404. * to set the new object into it. *
  405. * *
  406. * HISTORY: *
  407. * 12/26/1994 JLB : Created. *
  408. *=============================================================================================*/
  409. void FactoryClass::Set(TechnoClass & object)
  410. {
  411. Validate();
  412. Abandon();
  413. Object = &object;
  414. House = Object->House;
  415. Balance = 0;
  416. Set_Rate(0);
  417. Set_Stage(STEP_COUNT);
  418. IsDifferent = true;
  419. IsSuspended = true;
  420. }
  421. /***********************************************************************************************
  422. * FactoryClass::Suspend -- Temporarily stop production. *
  423. * *
  424. * This routine will suspend production until a subsiquent call to Start() or Abandon(). *
  425. * Typical use of this function is when the player puts production on hold or when there *
  426. * is insufficient funds. *
  427. * *
  428. * INPUT: none *
  429. * *
  430. * OUTPUT: bool; Was production actually stopped? A false return value indicates that the *
  431. * factory was empty or production was already stopped (or never started). *
  432. * *
  433. * WARNINGS: none *
  434. * *
  435. * HISTORY: *
  436. * 12/26/1994 JLB : Created. *
  437. *=============================================================================================*/
  438. bool FactoryClass::Suspend(void)
  439. {
  440. Validate();
  441. if (!IsSuspended) {
  442. IsSuspended = true;
  443. Set_Rate(0);
  444. return(true);
  445. }
  446. return(false);
  447. }
  448. /***********************************************************************************************
  449. * FactoryClass::Start -- Resumes production after suspension or creation. *
  450. * *
  451. * This function will start the production process. It works for newly created factory *
  452. * objects, as well as if production had been suspended previously. *
  453. * *
  454. * INPUT: none *
  455. * *
  456. * OUTPUT: bool; Was production started? A false return value means that the factory is *
  457. * empty or there is unsufficient credits to begin production. *
  458. * *
  459. * WARNINGS: none *
  460. * *
  461. * HISTORY: *
  462. * 12/26/1994 JLB : Created. *
  463. *=============================================================================================*/
  464. bool FactoryClass::Start(void)
  465. {
  466. Validate();
  467. if ((Object || SpecialItem) && IsSuspended && !Has_Completed()) {
  468. if (House->Available_Money() >= Cost_Per_Tick()) {
  469. int time;
  470. if (Object) {
  471. time = Object->Class_Of().Time_To_Build(House->Class->House);
  472. } else {
  473. time = TICKS_PER_MINUTE * 5;
  474. }
  475. int frac = House->Power_Fraction();
  476. frac = Bound(frac, 0x0010, 0x0100);
  477. int rate = (time*256) / frac;
  478. rate /= STEP_COUNT;
  479. rate = Bound(rate, 1, 255);
  480. Set_Rate(rate);
  481. IsSuspended = false;
  482. return(true);
  483. }
  484. }
  485. return(false);
  486. }
  487. /***********************************************************************************************
  488. * FactoryClass::Abandon -- Abandons current construction with money refunded. *
  489. * *
  490. * This routine is used when construction is to be abandoned and current money spend is *
  491. * to be refunded. This function effectively clears out this factory of all record of the *
  492. * producing object so that it may either be deleted or started anew with the Set() *
  493. * function. *
  494. * *
  495. * INPUT: none *
  496. * *
  497. * OUTPUT: bool; Was an object actually abandoned? A false return value indicates that the *
  498. * factory was not producing any object. *
  499. * *
  500. * WARNINGS: none *
  501. * *
  502. * HISTORY: *
  503. * 12/26/1994 JLB : Created. *
  504. *=============================================================================================*/
  505. bool FactoryClass::Abandon(void)
  506. {
  507. Validate();
  508. if (Object) {
  509. if (Object) {
  510. /*
  511. ** Refund all money expended so far, back to the owner of the object under construction.
  512. */
  513. House->Refund_Money(Object->Class_Of().Cost_Of() - Balance);
  514. Balance = 0;
  515. /*
  516. ** Delete the object under construction.
  517. */
  518. ScenarioInit++;
  519. delete Object;
  520. Object = NULL;
  521. ScenarioInit--;
  522. }
  523. if (SpecialItem) {
  524. SpecialItem = SPC_NONE;
  525. }
  526. /*
  527. ** Set the factory back to the idle and empty state.
  528. */
  529. Set_Rate(0);
  530. Set_Stage(0);
  531. IsSuspended = true;
  532. IsDifferent = true;
  533. return(true);
  534. }
  535. return(false);
  536. }
  537. /***********************************************************************************************
  538. * FactoryClass::Completion -- Fetchs the completion step for this factory. *
  539. * *
  540. * Use this routine to determine what animation (or completion step) the factory is *
  541. * currently on. *
  542. * *
  543. * INPUT: none *
  544. * *
  545. * OUTPUT: Returns a completion step number beteen 0 (uncompleted), to STEP_COUNT (completed) *
  546. * *
  547. * WARNINGS: none *
  548. * *
  549. * HISTORY: *
  550. * 12/26/1994 JLB : Created. *
  551. *=============================================================================================*/
  552. int FactoryClass::Completion(void)
  553. {
  554. Validate();
  555. return(Fetch_Stage());
  556. }
  557. /***********************************************************************************************
  558. * FactoryClass::Has_Completed -- Checks to see if object has completed production. *
  559. * *
  560. * Use this routine to examine the factory object in order to determine if the associated *
  561. * object has completed production and is awaiting placement. *
  562. * *
  563. * INPUT: none *
  564. * *
  565. * OUTPUT: bool; Is the associated object to the factory completed and ready for placement? *
  566. * *
  567. * WARNINGS: none *
  568. * *
  569. * HISTORY: *
  570. * 12/26/1994 JLB : Created. *
  571. *=============================================================================================*/
  572. bool FactoryClass::Has_Completed(void)
  573. {
  574. Validate();
  575. if (Object && Fetch_Stage() == STEP_COUNT) {
  576. return(true);
  577. }
  578. if (SpecialItem && Fetch_Stage() == STEP_COUNT) {
  579. return(true);
  580. }
  581. return(false);
  582. }
  583. /***********************************************************************************************
  584. * FactoryClass::Get_Object -- Fetches pointer to object being constructed. *
  585. * *
  586. * This routine gets the pointer to the currently constructing object. *
  587. * *
  588. * INPUT: none *
  589. * *
  590. * OUTPUT: Returns with a pointer to the object undergoing construction. *
  591. * *
  592. * WARNINGS: none *
  593. * *
  594. * HISTORY: *
  595. * 12/26/1994 JLB : Created. *
  596. *=============================================================================================*/
  597. TechnoClass * FactoryClass::Get_Object(void) const
  598. {
  599. Validate();
  600. return(Object);
  601. }
  602. /***************************************************************************
  603. * FactoryClass::Get_Special_Item -- gets factorys spc prod item *
  604. * *
  605. * INPUT: none *
  606. * *
  607. * OUTPUT: int the item the factory is currently working on *
  608. * *
  609. * HISTORY: *
  610. * 05/05/1995 PWG : Created. *
  611. *=========================================================================*/
  612. int FactoryClass::Get_Special_Item(void) const
  613. {
  614. Validate();
  615. return(SpecialItem);
  616. }
  617. /***********************************************************************************************
  618. * FactoryClass::Cost_Per_Tick -- Breaks entire production cost into managable chunks. *
  619. * *
  620. * Use this routine to determine the cost per game "tick" to produce the object. *
  621. * *
  622. * INPUT: none *
  623. * *
  624. * OUTPUT: Returns the number of credits necessary to advance production one game tick. *
  625. * *
  626. * WARNINGS: none *
  627. * *
  628. * HISTORY: *
  629. * 12/26/1994 JLB : Created. *
  630. *=============================================================================================*/
  631. int FactoryClass::Cost_Per_Tick(void)
  632. {
  633. Validate();
  634. if (Object) {
  635. int steps = STEP_COUNT - Fetch_Stage();
  636. if (steps) {
  637. return(Balance / steps);
  638. }
  639. return(Balance);
  640. }
  641. return(0);
  642. }
  643. /***********************************************************************************************
  644. * FactoryClass::Completed -- Clears factory object after a completed production process. *
  645. * *
  646. * This routine is called after production completes, and the object produced has been *
  647. * placed into the game. It resets the factory for deletion or starting of new production. *
  648. * *
  649. * INPUT: none *
  650. * *
  651. * OUTPUT: bool; Did any resetting occur? Failure is the result of the factory not having *
  652. * any completed object. An immediate second call to this routine will also *
  653. * yield false. *
  654. * *
  655. * WARNINGS: none *
  656. * *
  657. * HISTORY: *
  658. * 12/26/1994 JLB : Created. *
  659. *=============================================================================================*/
  660. bool FactoryClass::Completed(void)
  661. {
  662. Validate();
  663. if (Object && Fetch_Stage() == STEP_COUNT) {
  664. Object = NULL;
  665. IsSuspended = true;
  666. IsDifferent = true;
  667. Set_Stage(0);
  668. Set_Rate(0);
  669. return(true);
  670. }
  671. if (SpecialItem && Fetch_Stage() == STEP_COUNT) {
  672. SpecialItem = SPC_NONE;
  673. IsSuspended = true;
  674. IsDifferent = true;
  675. Set_Stage(0);
  676. Set_Rate(0);
  677. return(true);
  678. }
  679. return(false);
  680. }