1 /*
2  *  This file is part of Dune Legacy.
3  *
4  *  Dune Legacy is free software: you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation, either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  Dune Legacy 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  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with Dune Legacy.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef BUILDERBASE_H
19 #define BUILDERBASE_H
20 
21 #include <structures/StructureBase.h>
22 
23 #include <data.h>
24 
25 #include <list>
26 #include <string>
27 
28 class BuildItem {
29 public:
BuildItem()30     BuildItem() {
31         itemID = ItemID_Invalid;
32         price = 0;
33         num = 0;
34     }
35 
BuildItem(int itemID,int price)36     BuildItem(int itemID, int price) {
37         this->itemID = itemID;
38         this->price = price;
39         num = 0;
40     }
41 
save(OutputStream & stream)42     void save(OutputStream& stream) const {
43         stream.writeUint32(itemID);
44         stream.writeUint32(price);
45         stream.writeUint32(num);
46     }
47 
load(InputStream & stream)48     void load(InputStream& stream) {
49         itemID = stream.readUint32();
50         price = stream.readUint32();
51         num = stream.readUint32();
52     }
53 
54     Uint32 itemID;
55     Uint32 price;
56     Uint32 num;
57 };
58 
59 class ProductionQueueItem {
60 public:
ProductionQueueItem()61     ProductionQueueItem()
62      : itemID(0), price(0) {
63 
64     }
65 
ProductionQueueItem(Uint32 _ItemID,Uint32 _price)66     ProductionQueueItem(Uint32 _ItemID, Uint32 _price)
67      : itemID(_ItemID), price(_price) {
68 
69     }
70 
save(OutputStream & stream)71     void save(OutputStream& stream) const {
72         stream.writeUint32(itemID);
73         stream.writeUint32(price);
74     }
75 
load(InputStream & stream)76     void load(InputStream& stream) {
77         itemID = stream.readUint32();
78         price = stream.readUint32();
79     }
80 
81     Uint32 itemID;
82     Uint32 price;
83 };
84 
85 
86 class BuilderBase : public StructureBase
87 {
88 public:
89     explicit BuilderBase(House* newOwner);
90     explicit BuilderBase(InputStream& stream);
91     void init();
92     virtual ~BuilderBase();
93 
94     virtual void save(OutputStream& stream) const;
95 
96     virtual ObjectInterface* getInterfaceContainer();
97 
98     void setOwner(House *no);
99 
setOriginalHouseID(int i)100     virtual void setOriginalHouseID(int i) {
101         StructureBase::setOriginalHouseID(i);
102         updateBuildList();
103     }
104 
105     /**
106         This method returns the maximum number of upgrades available in this building.
107         \return the maximum number of upgrades available (0 if none)
108     */
109     int getMaxUpgradeLevel() const;
110 
111     /**
112         This method checks what is available for purchase in this builder. It shall
113         modify buildList appropriately.
114     */
115     virtual void updateBuildList();
116 
117     void setWaitingToPlace();
118     void unSetWaitingToPlace();
119 
getBuildListSize()120     int getBuildListSize() const { return buildList.size(); };
121 
getProductionQueueSize()122     int getProductionQueueSize() const { return currentProductionQueue.size(); };
123 
124     /**
125         Updates this builder.
126         \return true if this object still exists, false if it was destroyed
127     */
128     virtual bool update();
129 
130     virtual void handleUpgradeClick();
131     virtual void handleProduceItemClick(Uint32 itemID, bool multipleMode = false);
132     virtual void handleCancelItemClick(Uint32 itemID, bool multipleMode = false);
133     virtual void handleSetOnHoldClick(bool OnHold);
134 
135 
136 
137     /**
138         Start upgrading this builder if possible.
139         \return true if upgrading was started, false if not possible or already upgrading
140     */
141     virtual bool doUpgrade();
142 
143     /**
144         Start production of the specified item.
145         \param  itemID          the item to produce
146         \param  multipleMode    false = 1 item, true = 5 items
147     */
148     virtual void doProduceItem(Uint32 itemID, bool multipleMode = false);
149 
150     /**
151         Cancel production of the specified item.
152         \param  itemID          the item to cancel
153         \param  multipleMode    false = 1 item, true = 5 items
154     */
155     virtual void doCancelItem(Uint32 itemID, bool multipleMode = false);
156 
157     /**
158         Sets the currently produced item on hold or continues production.
159         \param  bOnHold         true = hold production; false = resume production
160     */
doSetOnHold(bool bOnHold)161     inline void doSetOnHold(bool bOnHold) { bCurrentItemOnHold = bOnHold; };
162 
163     /**
164         Start building a random item in this builder.
165     */
166     virtual void doBuildRandom();
167 
168 
169 
isUpgrading()170     inline bool isUpgrading() const { return upgrading; };
isAllowedToUpgrade()171     inline bool isAllowedToUpgrade() const { return (curUpgradeLev < getMaxUpgradeLevel()); };
getCurrentUpgradeLevel()172     inline int getCurrentUpgradeLevel() const { return curUpgradeLev; };
173     int getUpgradeCost() const;
getUpgradeProgress()174     inline FixPoint getUpgradeProgress() const { return upgradeProgress; };
175 
getCurrentProducedItem()176     inline Uint32 getCurrentProducedItem() const { return currentProducedItem; };
isOnHold()177     inline bool isOnHold() const { return bCurrentItemOnHold; };
178     bool isWaitingToPlace() const;
179     bool isUnitLimitReached(Uint32 itemID) const;
getProductionProgress()180     inline FixPoint getProductionProgress() const { return productionProgress; };
getBuildList()181     inline const std::list<BuildItem>& getBuildList() const { return buildList; };
182 
isAvailableToBuild(Uint32 itemID)183     virtual inline bool isAvailableToBuild(Uint32 itemID) const {
184         return (getBuildItem(itemID) != nullptr);
185     }
186 
187 protected:
188     virtual void updateProductionProgress();
189 
190     void removeBuiltItemFromProductionQueue();
191 
192     virtual void insertItem(std::list<BuildItem>& buildItemList, std::list<BuildItem>::iterator& iter, Uint32 itemID, int price=-1);
193 
194     void removeItem(std::list<BuildItem>& buildItemList, std::list<BuildItem>::iterator& iter, Uint32 itemID);
195 
getBuildItem(Uint32 itemID)196     BuildItem* getBuildItem(Uint32 itemID) {
197         for(BuildItem& buildItem : buildList) {
198             if(buildItem.itemID == itemID) {
199                 return &buildItem;
200             }
201         }
202         return nullptr;
203     }
204 
getBuildItem(Uint32 itemID)205     const BuildItem* getBuildItem(Uint32 itemID) const {
206         for(const BuildItem& buildItem : buildList) {
207             if(buildItem.itemID == itemID) {
208                 return &buildItem;
209             }
210         }
211         return nullptr;
212     }
213 
214     void produceNextAvailableItem();
215 
216 protected:
217     static const int itemOrder[];  ///< the order in which items are in the build list
218 
219     // structure state
220     bool     upgrading;              ///< Currently upgrading?
221     FixPoint upgradeProgress;        ///< The current state of the upgrade progress (measured in money spent)
222     Uint8    curUpgradeLev;          ///< Current upgrade level
223 
224     bool     bCurrentItemOnHold;     ///< Is the currently produced item on hold?
225     Uint32   currentProducedItem;    ///< The ItemID of the currently produced item
226     FixPoint productionProgress;     ///< The current state of the production progress (measured in money spent)
227     Uint32   deployTimer;            ///< Timer for deploying a unit
228 
229     std::list<ProductionQueueItem>  currentProductionQueue;     ///< This list is the production queue (It contains the item IDs of the units/structures to produce)
230     std::list<BuildItem>            buildList;                  ///< This list contains all the things that can be produced by this builder
231 };
232 
233 #endif //BUILDERBASE_H
234