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 HOUSE_H
19 #define HOUSE_H
20 
21 #include <misc/InputStream.h>
22 #include <misc/OutputStream.h>
23 #include <Definitions.h>
24 #include <DataTypes.h>
25 #include <data.h>
26 #include <Choam.h>
27 
28 #include <players/Player.h>
29 
30 #include <memory>
31 
32 // forward declarations
33 class UnitBase;
34 class StructureBase;
35 class ObjectBase;
36 class HumanPlayer;
37 
38 class House
39 {
40 public:
41     House(int newHouse, int newCredits, int maxUnits, Uint8 team = 0, int quota = 0);
42     explicit House(InputStream& stream);
43     void init();
44     virtual ~House();
45     virtual void save(OutputStream& stream) const;
46 
47     void addPlayer(std::shared_ptr<Player> newPlayer);
48 
getHouseID()49     inline int getHouseID() const { return houseID; }
getTeam()50     inline int getTeam() const { return team; }
51 
isAI()52     inline bool isAI() const { return ai; }
isAlive()53     inline bool isAlive() const { return (team == 0) || !(((numStructures - numItem[Structure_Wall]) <= 0) && (((numUnits - numItem[Unit_Carryall] - numItem[Unit_Harvester] - numItem[Unit_Frigate] - numItem[Unit_Sandworm]) <= 0))); }
54 
hasCarryalls()55     inline bool hasCarryalls() const { return (numItem[Unit_Carryall] > 0); }
hasBarracks()56     inline bool hasBarracks() const { return (numItem[Structure_Barracks] > 0); }
hasIX()57     inline bool hasIX() const { return (numItem[Structure_IX] > 0); }
hasLightFactory()58     inline bool hasLightFactory() const { return (numItem[Structure_LightFactory] > 0); }
hasHeavyFactory()59     inline bool hasHeavyFactory() const { return (numItem[Structure_HeavyFactory] > 0); }
hasRefinery()60     inline bool hasRefinery() const { return (numItem[Structure_Refinery] > 0); }
hasRepairYard()61     inline bool hasRepairYard() const { return (numItem[Structure_RepairYard] > 0); }
hasStarPort()62     inline bool hasStarPort() const { return (numItem[Structure_StarPort] > 0); }
hasWindTrap()63     inline bool hasWindTrap() const { return (numItem[Structure_WindTrap] > 0); }
hasSandworm()64     inline bool hasSandworm() const { return (numItem[Unit_Sandworm] > 0); }
hasRadar()65     inline bool hasRadar() const { return (numItem[Structure_Radar] > 0); }
66 
hasRadarOn()67     inline bool hasRadarOn() const { return (hasRadar() && hasPower()); }
hasPower()68     inline bool hasPower() const { return (producedPower >= powerRequirement); }
69 
getNumStructures()70     inline int getNumStructures() const { return numStructures; };
getNumUnits()71     inline int getNumUnits() const { return numUnits; };
getNumItems(int itemID)72     inline int getNumItems(int itemID) const { return (isStructure(itemID) || isUnit(itemID)) ? numItem[itemID] : 0; };
73 
getCapacity()74     inline int getCapacity() const { return capacity; }
75 
getProducedPower()76     inline int getProducedPower() const { return producedPower; }
77     void setProducedPower(int newPower);
getPowerRequirement()78     inline int getPowerRequirement() const { return powerRequirement; }
79 
getBuiltValue()80     inline int getBuiltValue() const { return unitBuiltValue + structureBuiltValue; }
getUnitBuiltValue()81     inline int getUnitBuiltValue() const { return unitBuiltValue; }
getMilitaryValue()82     inline int getMilitaryValue() const { return militaryValue; }
getKillValue()83     inline int getKillValue() const { return killValue; }
getLossValue()84     inline int getLossValue() const { return lossValue; }
getStructureBuiltValue()85     inline int getStructureBuiltValue() const { return structureBuiltValue; }
getNumBuiltUnits()86     inline int getNumBuiltUnits() const { return numBuiltUnits; }
getNumBuiltStructures()87     inline int getNumBuiltStructures() const { return numBuiltStructures; }
getDestroyedValue()88     inline int getDestroyedValue() const { return destroyedValue; }
getNumDestroyedUnits()89     inline int getNumDestroyedUnits() const { return numDestroyedUnits; }
getNumDestroyedStructures()90     inline int getNumDestroyedStructures() const { return numDestroyedStructures; }
getNumBuiltItems(int itemID)91     inline int getNumBuiltItems(int itemID) const { return numItemBuilt[itemID]; }
getNumKilledItems(int itemID)92     inline int getNumKilledItems(int itemID) const { return numItemKills[itemID]; }
getNumLostItems(int itemID)93     inline int getNumLostItems(int itemID) const { return numItemLosses[itemID]; }
getNumItemDamageInflicted(int itemID)94     inline Sint32 getNumItemDamageInflicted(int itemID) const { return numItemDamageInflicted[itemID]; }
getHarvestedSpice()95     inline FixPoint getHarvestedSpice() const { return harvestedSpice; }
96 
getQuota()97     inline int getQuota() const { return quota; };
getMaxUnits()98     inline int getMaxUnits() const { return maxUnits; };
99 
100     /**
101         This function checks if the limit for ground units is already reached. Infantry units are only counted as 1/3.
102         \return true, if the limit is already reached, false if building further ground units is allowed
103     */
isGroundUnitLimitReached()104     inline bool isGroundUnitLimitReached() const {
105         int numGroundUnit = numUnits - numItem[Unit_Soldier] - numItem[Unit_Trooper] - numItem[Unit_Carryall] - numItem[Unit_Ornithopter];
106         return (numGroundUnit + (numItem[Unit_Soldier]+2)/3 + (numItem[Unit_Trooper]+2)/3  >= maxUnits);
107     };
108 
109     /**
110         This function checks if the limit for infantry units is already reached. Infantry units are only counted as 1/3.
111         \return true, if the limit is already reached, false if building further infantry units is allowed
112     */
isInfantryUnitLimitReached()113     inline bool isInfantryUnitLimitReached() const {
114         int numGroundUnit = numUnits - numItem[Unit_Soldier] - numItem[Unit_Trooper] - numItem[Unit_Carryall] - numItem[Unit_Ornithopter];
115         return (numGroundUnit + numItem[Unit_Soldier]/3 + numItem[Unit_Trooper]/3  >= maxUnits);
116     };
117 
118     /**
119         This function checks if the limit for air units is already reached.
120         \return true, if the limit is already reached, false if building further air units is allowed
121     */
isAirUnitLimitReached()122     inline bool isAirUnitLimitReached() const {
123         return (numItem[Unit_Carryall] + numItem[Unit_Ornithopter] >= 11);
124     }
125 
getChoam()126     inline Choam& getChoam() { return choam; };
getChoam()127     inline const Choam& getChoam() const { return choam; };
128 
129 
getStartingCredits()130     inline FixPoint getStartingCredits() const { return startingCredits; }
getStoredCredits()131     inline FixPoint getStoredCredits() const { return storedCredits; }
getCredits()132     inline int getCredits() const { return lround(storedCredits+startingCredits); }
133     void addCredits(FixPoint newCredits, bool wasRefined = false);
134     void returnCredits(FixPoint newCredits);
135     FixPoint takeCredits(FixPoint amount);
136 
137     void printStat() const;
138 
139     void updateBuildLists();
140 
141     void update();
142 
143     void incrementUnits(int itemID);
144     void decrementUnits(int itemID);
145     void incrementStructures(int itemID);
146     void decrementStructures(int itemID, const Coord& location);
147 
148     /**
149         An object was hit by something or damaged somehow else.
150         \param  pObject     the object that was damaged
151         \param  damage      the damage taken
152         \param  damagerID   the shooter of the bullet, rocket, etc. if known; NONE_ID otherwise
153     */
154     void noteDamageLocation(ObjectBase* pObject, int damage, Uint32 damagerID);
155 
156     void informWasBuilt(Uint32 itemID);
157     void informHasKilled(Uint32 itemID);
158     void informHasDamaged(Uint32 itemID, Uint32 damage);
159 
160     void lose(bool bSilent = false);
161     void win();
162 
163     void freeHarvester(int xPos, int yPos);
freeHarvester(const Coord & coord)164     void freeHarvester(const Coord& coord) { freeHarvester(coord.x, coord.y); };
165     StructureBase* placeStructure(Uint32 builderID, int itemID, int xPos, int yPos, bool bForcePlacing = false);
166     UnitBase* createUnit(int itemID);
167     UnitBase* placeUnit(int itemID, int xPos, int yPos);
168 
169     Coord getCenterOfMainBase() const;
170 
171     Coord getStrongestUnitPosition() const;
172 
getPlayerList()173     const std::list<std::shared_ptr<Player> >& getPlayerList() const { return players; };
174 
175 protected:
176     void decrementHarvesters();
177 
178     std::list<std::shared_ptr<Player> > players;        ///< List of associated players that control this house
179 
180     bool    ai;             ///< Is this an ai player?
181 
182     Uint8   houseID;        ///< The house number
183     Uint8   team;           ///< The team number
184 
185     int numStructures;          ///< How many structures does this player have?
186     int numUnits;               ///< How many units does this player have?
187     int numItem[Num_ItemID];    ///< This array contains the number of structures/units of a certain type this player has
188     int numItemBuilt[Num_ItemID];  /// Number of items built by player
189     int numItemKills[Num_ItemID]; /// Number of items killed by player
190     int numItemLosses [Num_ItemID]; /// Number of items lost by player
191     Sint32 numItemDamageInflicted[Num_ItemID]; /// Amount of damage inflicted by a specific unit type owned by the player
192 
193     int capacity;             ///< Total spice capacity
194     int producedPower;        ///< Power prodoced by this player
195     int powerRequirement;     ///< How much power does this player use?
196 
197     FixPoint storedCredits;   ///< current number of credits that are stored in refineries/silos
198     FixPoint startingCredits; ///< number of starting credits this player still has
199     int oldCredits;           ///< amount of credits in the last game cycle (used for playing the credits tick sound)
200 
201     int maxUnits;             ///< maximum number of units this house is allowed to build
202     int quota;                ///< number of credits to win
203 
204     Choam   choam;            ///< the things that are deliverable at the starport
205 
206     int powerUsageTimer;      ///< every N ticks you have to pay for your power usage
207 
208     // statistic
209     int unitBuiltValue;
210     int structureBuiltValue;
211     int militaryValue;
212     int killValue;
213     int lossValue;
214     int numBuiltUnits;
215     int numBuiltStructures;
216     int destroyedValue;
217     int numDestroyedUnits;
218     int numDestroyedStructures;
219     FixPoint harvestedSpice;
220 };
221 
222 #endif // HOUSE_H
223