1 //       _________ __                 __
2 //      /   _____//  |_____________ _/  |______     ____  __ __  ______
3 //      \_____  \\   __\_  __ \__  \\   __\__  \   / ___\|  |  \/  ___/
4 //      /        \|  |  |  | \// __ \|  |  / __ \_/ /_/  >  |  /\___ |
5 //     /_______  /|__|  |__|  (____  /__| (____  /\___  /|____//____  >
6 //             \/                  \/          \//_____/            \/
7 //  ______________________                           ______________________
8 //                        T H E   W A R   B E G I N S
9 //         Stratagus - A free fantasy real time strategy game engine
10 //
11 /**@name unittype.h - The unit type header file. */
12 //
13 //      (c) Copyright 1998-2019 by Lutz Sammer, Jimmy Salmon and Andrettin
14 //
15 //      This program is free software; you can redistribute it and/or modify
16 //      it under the terms of the GNU General Public License as published by
17 //      the Free Software Foundation; only version 2 of the License.
18 //
19 //      This program is distributed in the hope that it will be useful,
20 //      but WITHOUT ANY WARRANTY; without even the implied warranty of
21 //      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 //      GNU General Public License for more details.
23 //
24 //      You should have received a copy of the GNU General Public License
25 //      along with this program; if not, write to the Free Software
26 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27 //      02111-1307, USA.
28 //
29 
30 #ifndef __UNITTYPE_H__
31 #define __UNITTYPE_H__
32 
33 /*----------------------------------------------------------------------------
34 --  Includes
35 ----------------------------------------------------------------------------*/
36 
37 #include "color.h"
38 #include "data_type.h"
39 #include "icons.h"
40 #include "missileconfig.h"
41 #include "unitsound.h"
42 #include "upgrade/upgrade_structs.h"
43 #include "vec2i.h"
44 
45 #include <algorithm>
46 #include <climits>
47 #include <cstring>
48 #include <map>
49 #include <vector>
50 
51 #ifdef __MORPHOS__
52 #undef Enable
53 #endif
54 
55 /*----------------------------------------------------------------------------
56 --  Declarations
57 ----------------------------------------------------------------------------*/
58 
59 class CAnimations;
60 class CConstruction;
61 class CDependency;
62 class CFile;
63 class CPlayerColorGraphic;
64 class CUnitTypeVariation;
65 class MissileType;
66 //Wyrmgus start
67 class CButtonLevel;
68 class CFaction;
69 class CPlane;
70 class CWorld;
71 class CTerrainType;
72 class CUniqueItem;
73 //Wyrmgus end
74 struct lua_State;
75 #ifdef USE_MNG
76 class Mng;
77 #endif
78 class LuaCallback;
79 
80 #define UnitSides 8
81 #define MaxAttackPos 5
82 
83 CUnitType *UnitTypeByIdent(const std::string &ident);
84 
85 enum GroupSelectionMode {
86 	SELECTABLE_BY_RECTANGLE_ONLY = 0,
87 	NON_SELECTABLE_BY_RECTANGLE_ONLY,
88 	SELECT_ALL
89 };
90 
91 //Wyrmgus start
92 enum ImageLayers {
93 	LeftArmImageLayer,
94 	RightArmImageLayer,
95 	RightHandImageLayer,
96 	HairImageLayer,
97 	ClothingImageLayer,
98 	ClothingLeftArmImageLayer,
99 	ClothingRightArmImageLayer,
100 	PantsImageLayer,
101 	BootsImageLayer,
102 	WeaponImageLayer,
103 	ShieldImageLayer,
104 	HelmetImageLayer,
105 	BackpackImageLayer,
106 	MountImageLayer,
107 
108 	MaxImageLayers
109 };
110 //Wyrmgus end
111 
112 class ResourceInfo
113 {
114 public:
ResourceInfo()115 	ResourceInfo() : WaitAtResource(0), ResourceStep(0),
116 		ResourceCapacity(0), WaitAtDepot(0), ResourceId(0),
117 		LoseResources(0),
118 		SpriteWhenLoaded(nullptr), SpriteWhenEmpty(nullptr)
119 	{}
120 
121 	std::string FileWhenLoaded;     /// Change the graphic when the unit is loaded.
122 	std::string FileWhenEmpty;      /// Change the graphic when the unit is empty.
123 	unsigned WaitAtResource;        /// Cycles the unit waits while mining.
124 	unsigned ResourceStep;          /// Resources the unit gains per mining cycle.
125 	int      ResourceCapacity;      /// Max amount of resources to carry.
126 	unsigned WaitAtDepot;           /// Cycles the unit waits while returning.
127 	unsigned ResourceId;            /// Id of the resource harvested. Redundant.
128 	unsigned char LoseResources;       /// The unit will lose it's resource when distracted.
129 	unsigned char RefineryHarvester;   /// Unit have to build Refinery buildings for harvesting.
130 	//  Runtime info:
131 	CPlayerColorGraphic *SpriteWhenLoaded; /// The graphic corresponding to FileWhenLoaded.
132 	CPlayerColorGraphic *SpriteWhenEmpty;  /// The graphic corresponding to FileWhenEmpty
133 };
134 
135 /**
136 **  User defined variable type.
137 **
138 **  It is used to define variables and use it after
139 **  to manage magic, energy, shield or other stuff.
140 */
141 class CVariable
142 {
143 public:
CVariable()144 	CVariable() : Max(0), Value(0), Increase(0), Enable(0) {}
145 
146 	bool operator ==(const CVariable &rhs) const
147 	{
148 		return this->Max == rhs.Max
149 			   && this->Value == rhs.Value
150 			   && this->Increase == rhs.Increase
151 			   && this->Enable == rhs.Enable;
152 	}
153 	bool operator !=(const CVariable &rhs) const { return !(*this == rhs); }
154 
155 public:
156 	int Max;        /// Maximum for the variable. (Assume min is 0.)
157 	int Value;      /// Current (or initial) value of the variable (or initial value).
158 	char Increase;  /// Number to increase(decrease) Value by second.
159 	char Enable;    /// True if the unit doesn't have this variable. (f.e shield)
160 };
161 
162 // Index for boolflag already defined
163 enum {
164 	COWARD_INDEX = 0,				/// Unit will only attack if instructed.
165 	BUILDING_INDEX,
166 	FLIP_INDEX,
167 	REVEALER_INDEX,					/// reveal the fog of war
168 	LANDUNIT_INDEX,
169 	AIRUNIT_INDEX,
170 	SEAUNIT_INDEX,
171 	EXPLODEWHENKILLED_INDEX,
172 	VISIBLEUNDERFOG_INDEX,			/// Unit is visible under fog of war.
173 	PERMANENTCLOAK_INDEX,			/// Is only visible by CloakDetectors.
174 	DETECTCLOAK_INDEX,				/// Can see Cloaked units.
175 	ATTACKFROMTRANSPORTER_INDEX,	/// Can attack from transporter
176 	VANISHES_INDEX,					/// Corpses & destroyed places.
177 	GROUNDATTACK_INDEX,				/// Can do ground attack command.
178 	SHOREBUILDING_INDEX,			/// Building must be built on coast.
179 	CANATTACK_INDEX,
180 	//Wyrmgus start
181 	CANDOCK_INDEX,
182 	//Wyrmgus end
183 	BUILDEROUTSIDE_INDEX,			/// The builder stays outside during the construction.
184 	BUILDERLOST_INDEX,				/// The builder is lost after the construction.
185 	CANHARVEST_INDEX,				/// Resource can be harvested.
186 	//Wyrmgus start
187 	INEXHAUSTIBLE_INDEX,			/// Resource is not exhaustible
188 	//Wyrmgus end
189 	HARVESTER_INDEX,				/// Unit is a resource harvester.
190 	SELECTABLEBYRECTANGLE_INDEX,	/// Selectable with mouse rectangle.
191 	ISNOTSELECTABLE_INDEX,
192 	DECORATION_INDEX,				/// Unit is a decoration (act as tile).
193 	INDESTRUCTIBLE_INDEX,			/// Unit is indestructible (take no damage).
194 	TELEPORTER_INDEX,				/// Can teleport other units.
195 	SHIELDPIERCE_INDEX,
196 	SAVECARGO_INDEX,				/// Unit unloads his passengers after death.
197 	NONSOLID_INDEX,					/// Unit can be entered by other units.
198 	WALL_INDEX,						/// Use special logic for Direction field.
199 	NORANDOMPLACING_INDEX,			/// Don't use random frame rotation
200 	ORGANIC_INDEX,					/// Organic unit (used for death coil spell)
201 	SIDEATTACK_INDEX,
202 	NOFRIENDLYFIRE_INDEX,           /// Unit accepts friendly fire for splash attacks
203 	//Wyrmgus start
204 	TOWNHALL_INDEX,
205 	MARKET_INDEX,
206 	RECRUITHEROES_INDEX,
207 	GARRISONTRAINING_INDEX,
208 	INCREASESLUXURYDEMAND_INDEX,
209 	ITEM_INDEX,
210 	POWERUP_INDEX,
211 	INVENTORY_INDEX,
212 	TRAP_INDEX,
213 	BRIDGE_INDEX,
214 	TRADER_INDEX,
215 	FAUNA_INDEX,
216 	PREDATOR_INDEX,
217 	SLIME_INDEX,
218 	PEOPLEAVERSION_INDEX,
219 	MOUNTED_INDEX,
220 	RAIL_INDEX,
221 	DIMINUTIVE_INDEX,
222 	GIANT_INDEX,
223 	DRAGON_INDEX,
224 	DETRITUS_INDEX,
225 	FLESH_INDEX,
226 	VEGETABLE_INDEX,
227 	INSECT_INDEX,
228 	DAIRY_INDEX,
229 	DETRITIVORE_INDEX,
230 	CARNIVORE_INDEX,
231 	HERBIVORE_INDEX,
232 	INSECTIVORE_INDEX,
233 	HARVESTFROMOUTSIDE_INDEX,
234 	OBSTACLE_INDEX,
235 	AIRUNPASSABLE_INDEX,
236 	SLOWS_INDEX,
237 	GRAVEL_INDEX,
238 	HACKDAMAGE_INDEX,
239 	PIERCEDAMAGE_INDEX,
240 	BLUNTDAMAGE_INDEX,
241 	ETHEREAL_INDEX,					/// is only visible by units with ethereal vision.
242 	HIDDENOWNERSHIP_INDEX,
243 	HIDDENINEDITOR_INDEX,
244 	INVERTEDSOUTHEASTARMS_INDEX,
245 	INVERTEDEASTARMS_INDEX,
246 	//Wyrmgus end
247 	NBARALREADYDEFINED
248 };
249 
250 // Index for variable already defined.
251 enum {
252 	HP_INDEX = 0,
253 	BUILD_INDEX,
254 	MANA_INDEX,
255 	TRANSPORT_INDEX,
256 	RESEARCH_INDEX,
257 	TRAINING_INDEX,
258 	UPGRADINGTO_INDEX,
259 	GIVERESOURCE_INDEX,
260 	CARRYRESOURCE_INDEX,
261 	XP_INDEX,
262 	KILL_INDEX,
263 	SUPPLY_INDEX,					/// Food supply
264 	DEMAND_INDEX,					/// Food demand
265 	ARMOR_INDEX,
266 	SIGHTRANGE_INDEX,
267 	ATTACKRANGE_INDEX,
268 	PIERCINGDAMAGE_INDEX,
269 	BASICDAMAGE_INDEX,
270 	//Wyrmgus start
271 	THORNSDAMAGE_INDEX,
272 	FIREDAMAGE_INDEX,
273 	COLDDAMAGE_INDEX,
274 	ARCANEDAMAGE_INDEX,
275 	LIGHTNINGDAMAGE_INDEX,
276 	AIRDAMAGE_INDEX,
277 	EARTHDAMAGE_INDEX,
278 	WATERDAMAGE_INDEX,
279 	ACIDDAMAGE_INDEX,
280 	SPEED_INDEX,
281 	FIRERESISTANCE_INDEX,
282 	COLDRESISTANCE_INDEX,
283 	ARCANERESISTANCE_INDEX,
284 	LIGHTNINGRESISTANCE_INDEX,
285 	AIRRESISTANCE_INDEX,
286 	EARTHRESISTANCE_INDEX,
287 	WATERRESISTANCE_INDEX,
288 	ACIDRESISTANCE_INDEX,
289 	HACKRESISTANCE_INDEX,
290 	PIERCERESISTANCE_INDEX,
291 	BLUNTRESISTANCE_INDEX,
292 	DEHYDRATIONIMMUNITY_INDEX,
293 	//Wyrmgus end
294 	POSX_INDEX,
295 	POSY_INDEX,
296 	TARGETPOSX_INDEX,
297 	TARGETPOSY_INDEX,
298 	RADAR_INDEX,
299 	RADARJAMMER_INDEX,
300 	AUTOREPAIRRANGE_INDEX,
301 	BLOODLUST_INDEX,
302 	HASTE_INDEX,
303 	SLOW_INDEX,
304 	INVISIBLE_INDEX,
305 	UNHOLYARMOR_INDEX,
306 	SLOT_INDEX,
307 	SHIELD_INDEX,
308 	POINTS_INDEX,
309 	MAXHARVESTERS_INDEX,
310 	POISON_INDEX,
311 	SHIELDPERMEABILITY_INDEX,
312 	SHIELDPIERCING_INDEX,
313 	ISALIVE_INDEX,
314 	PLAYER_INDEX,
315 	PRIORITY_INDEX,
316 	//Wyrmgus start
317 	STRENGTH_INDEX,
318 	DEXTERITY_INDEX,
319 	INTELLIGENCE_INDEX,
320 	CHARISMA_INDEX,
321 	ACCURACY_INDEX,
322 	EVASION_INDEX,
323 	LEVEL_INDEX,
324 	LEVELUP_INDEX,
325 	XPREQUIRED_INDEX,
326 	VARIATION_INDEX,
327 	HITPOINTHEALING_INDEX,
328 	HITPOINTBONUS_INDEX,
329 	CRITICALSTRIKECHANCE_INDEX,
330 	CHARGEBONUS_INDEX,
331 	BACKSTAB_INDEX,
332 	BONUSAGAINSTMOUNTED_INDEX,
333 	BONUSAGAINSTBUILDINGS_INDEX,
334 	BONUSAGAINSTAIR_INDEX,
335 	BONUSAGAINSTGIANTS_INDEX,
336 	BONUSAGAINSTDRAGONS_INDEX,
337 	DAYSIGHTRANGEBONUS_INDEX,
338 	NIGHTSIGHTRANGEBONUS_INDEX,
339 	KNOWLEDGEMAGIC_INDEX,
340 	KNOWLEDGEWARFARE_INDEX,
341 	KNOWLEDGEMINING_INDEX,
342 	MAGICLEVEL_INDEX,
343 	TRANSPARENCY_INDEX,
344 	GENDER_INDEX,
345 	BIRTHCYCLE_INDEX,
346 	STUN_INDEX,
347 	BLEEDING_INDEX,
348 	LEADERSHIP_INDEX,
349 	BLESSING_INDEX,
350 	INSPIRE_INDEX,
351 	PRECISION_INDEX,
352 	REGENERATION_INDEX,
353 	BARKSKIN_INDEX,
354 	TERROR_INDEX,
355 	WITHER_INDEX,
356 	DEHYDRATION_INDEX,
357 	HYDRATING_INDEX,
358 	TIMEEFFICIENCYBONUS_INDEX,
359 	RESEARCHSPEEDBONUS_INDEX,
360 	GARRISONEDRANGEBONUS_INDEX,
361 	SPEEDBONUS_INDEX, // dummy variable for terrain types that increase movement speed, so that their bonus shows up correctly in the interface
362 	GATHERINGBONUS_INDEX,
363 	COPPERGATHERINGBONUS_INDEX,
364 	SILVERGATHERINGBONUS_INDEX,
365 	GOLDGATHERINGBONUS_INDEX,
366 	IRONGATHERINGBONUS_INDEX,
367 	MITHRILGATHERINGBONUS_INDEX,
368 	LUMBERGATHERINGBONUS_INDEX,
369 	STONEGATHERINGBONUS_INDEX,
370 	COALGATHERINGBONUS_INDEX,
371 	JEWELRYGATHERINGBONUS_INDEX,
372 	FURNITUREGATHERINGBONUS_INDEX,
373 	LEATHERGATHERINGBONUS_INDEX,
374 	GEMSGATHERINGBONUS_INDEX,
375 	DISEMBARKMENTBONUS_INDEX,
376 	TRADECOST_INDEX,
377 	SALVAGEFACTOR_INDEX,
378 	MUGGING_INDEX,
379 	RAIDING_INDEX,
380 	DESERTSTALK_INDEX,
381 	FORESTSTALK_INDEX,
382 	SWAMPSTALK_INDEX,
383 	LEADERSHIPAURA_INDEX,
384 	REGENERATIONAURA_INDEX,
385 	HYDRATINGAURA_INDEX,
386 	ETHEREALVISION_INDEX,
387 	HERO_INDEX,
388 	OWNERSHIPINFLUENCERANGE_INDEX,
389 	//Wyrmgus end
390 	NVARALREADYDEFINED
391 };
392 
393 class CUnit;
394 class CUnitType;
395 class CFont;
396 
397 /**
398 **  Decoration for user defined variable.
399 **
400 **  It is used to show variables graphicly.
401 **  @todo add more stuff in this struct.
402 */
403 class CDecoVar
404 {
405 public:
406 
CDecoVar()407 	CDecoVar() {};
~CDecoVar()408 	virtual ~CDecoVar()
409 	{
410 	};
411 
412 	/// function to draw the decorations.
413 	virtual void Draw(int x, int y, const CUnitType &type, const CVariable &var) const = 0;
414 
415 	unsigned int Index;     /// Index of the variable. @see DefineVariables
416 
417 	//Wyrmgus start
418 	int MinValue;			/// Minimum value of the variable
419 	//Wyrmgus end
420 
421 	int OffsetX;            /// Offset in X coord.
422 	int OffsetY;            /// Offset in Y coord.
423 
424 	int OffsetXPercent;     /// Percent offset (TileSize.x) in X coord.
425 	int OffsetYPercent;     /// Percent offset (TileSize.y) in Y coord.
426 
427 	bool IsCenteredInX;     /// if true, use center of deco instead of left border
428 	bool IsCenteredInY;     /// if true, use center of deco instead of upper border
429 
430 	bool ShowIfNotEnable;   /// if false, Show only if var is enable
431 	bool ShowWhenNull;      /// if false, don't show if var is null (F.E poison)
432 	bool HideHalf;          /// if true, don't show when 0 < var < max.
433 	bool ShowWhenMax;       /// if false, don't show if var is to max. (Like mana)
434 	bool ShowOnlySelected;  /// if true, show only for selected units.
435 
436 	bool HideNeutral;       /// if true, don't show for neutral unit.
437 	bool HideAllied;        /// if true, don't show for allied unit. (but show own units)
438 	//Wyrmgus start
439 	bool HideSelf;			/// if true, don't show for own units.
440 	//Wyrmgus end
441 	bool ShowOpponent;      /// if true, show for opponent unit.
442 
443 	bool ShowIfCanCastAnySpell;   /// if true, only show if the unit can cast a spell.
444 };
445 
446 class CDecoVarBar : public CDecoVar
447 {
448 public:
449 	/// function to draw the decorations.
450 	virtual void Draw(int x, int y, const CUnitType &type, const CVariable &var) const;
451 
452 	bool IsVertical;            /// if true, vertical bar, else horizontal.
453 	bool SEToNW;                /// (SouthEastToNorthWest), if false value 0 is on the left or up of the bar.
454 	int Height;                 /// Height of the bar.
455 	int Width;                  /// Width of the bar.
456 	bool ShowFullBackground;    /// if true, show background like value equal to max.
457 	char BorderSize;            /// Size of the border, 0 for no border.
458 	// FIXME color depend of percent (red, Orange, Yellow, Green...)
459 	IntColor Color;             /// Color of bar.
460 	IntColor BColor;            /// Color of background.
461 };
462 
463 class CDecoVarText : public CDecoVar
464 {
465 public:
CDecoVarText()466 	CDecoVarText() : Font(nullptr) {};
467 	/// function to draw the decorations.
468 	virtual void Draw(int x, int y, const CUnitType &type, const CVariable &var) const;
469 
470 	CFont *Font;  /// Font to use to display value.
471 	// FIXME : Add Color, format
472 };
473 
474 /// Sprite contains frame from full (left)to empty state (right).
475 class CDecoVarSpriteBar : public CDecoVar
476 {
477 public:
CDecoVarSpriteBar()478 	CDecoVarSpriteBar() : NSprite(-1) {};
479 	/// function to draw the decorations.
480 	virtual void Draw(int x, int y,
481 					  const CUnitType &type, const CVariable &var) const;
482 
483 	char NSprite; /// Index of number. (@see DefineSprites and @see GetSpriteIndex)
484 	// FIXME Sprite info. better way ?
485 };
486 
487 /// use to show specific frame in a sprite.
488 class CDecoVarStaticSprite : public CDecoVar
489 {
490 public:
CDecoVarStaticSprite()491 	CDecoVarStaticSprite() : NSprite(-1), n(0), FadeValue(0) {}
492 	/// function to draw the decorations.
493 	virtual void Draw(int x, int y, const CUnitType &type, const CVariable &var) const;
494 
495 	// FIXME Sprite info. and Replace n with more appropriate var.
496 	char NSprite;  /// Index of sprite. (@see DefineSprites and @see GetSpriteIndex)
497 	int n;         /// identifiant in SpellSprite
498 	int FadeValue; /// if variable's value is below than FadeValue, it drawn transparent.
499 };
500 
501 enum UnitTypeType {
502 	UnitTypeLand,  /// Unit lives on land
503 	UnitTypeFly,   /// Unit lives in air
504 	//Wyrmgus start
505 	UnitTypeFlyLow,   /// Unit lives in air, but flies low, so that it can be attacked by melee land units and cannot fly over rocks
506 	//Wyrmgus end
507 	UnitTypeNaval  /// Unit lives on water
508 };
509 
510 enum DistanceTypeType {
511 	Equal,
512 	NotEqual,
513 	LessThan,
514 	LessThanEqual,
515 	GreaterThan,
516 	GreaterThanEqual
517 };
518 
519 class CBuildRestriction
520 {
521 public:
~CBuildRestriction()522 	virtual ~CBuildRestriction() {}
Init()523 	virtual void Init() {};
524 	//Wyrmgus start
525 //	virtual bool Check(const CUnit *builder, const CUnitType &type, const Vec2i &pos, CUnit *&ontoptarget) const = 0;
526 	virtual bool Check(const CUnit *builder, const CUnitType &type, const Vec2i &pos, CUnit *&ontoptarget, int z) const = 0;
527 	//Wyrmgus end
528 };
529 
530 class CBuildRestrictionAnd : public CBuildRestriction
531 {
532 public:
~CBuildRestrictionAnd()533 	virtual ~CBuildRestrictionAnd()
534 	{
535 		for (std::vector<CBuildRestriction *>::const_iterator i = _or_list.begin();
536 			 i != _or_list.end(); ++i) {
537 			delete *i;
538 		}
539 		_or_list.clear();
540 	}
Init()541 	virtual void Init()
542 	{
543 		for (std::vector<CBuildRestriction *>::const_iterator i = _or_list.begin();
544 			 i != _or_list.end(); ++i) {
545 			(*i)->Init();
546 		}
547 	}
548 	//Wyrmgus start
549 //	virtual bool Check(const CUnit *builder, const CUnitType &type, const Vec2i &pos, CUnit *&ontoptarget) const;
550 	virtual bool Check(const CUnit *builder, const CUnitType &type, const Vec2i &pos, CUnit *&ontoptarget, int z) const;
551 	//Wyrmgus end
552 
push_back(CBuildRestriction * restriction)553 	void push_back(CBuildRestriction *restriction) { _or_list.push_back(restriction); }
554 public:
555 	std::vector<CBuildRestriction *> _or_list;
556 };
557 
558 //Wyrmgus start
559 class CBuildRestrictionOr : public CBuildRestriction
560 {
561 public:
~CBuildRestrictionOr()562 	virtual ~CBuildRestrictionOr()
563 	{
564 		for (std::vector<CBuildRestriction *>::const_iterator i = _or_list.begin();
565 			 i != _or_list.end(); ++i) {
566 			delete *i;
567 		}
568 		_or_list.clear();
569 	}
Init()570 	virtual void Init()
571 	{
572 		for (std::vector<CBuildRestriction *>::const_iterator i = _or_list.begin();
573 			 i != _or_list.end(); ++i) {
574 			(*i)->Init();
575 		}
576 	}
577 	virtual bool Check(const CUnit *builder, const CUnitType &type, const Vec2i &pos, CUnit *&ontoptarget, int z) const;
578 
push_back(CBuildRestriction * restriction)579 	void push_back(CBuildRestriction *restriction) { _or_list.push_back(restriction); }
580 public:
581 	std::vector<CBuildRestriction *> _or_list;
582 };
583 //Wyrmgus end
584 
585 class CBuildRestrictionAddOn : public CBuildRestriction
586 {
587 	class functor
588 	{
589 	public:
functor(const CUnitType * type,const Vec2i & _pos)590 		functor(const CUnitType *type, const Vec2i &_pos): Parent(type), pos(_pos) {}
591 		inline bool operator()(const CUnit *const unit) const;
592 	private:
593 		const CUnitType *const Parent;   /// building that is unit is an addon too.
594 		const Vec2i pos; //functor work position
595 	};
596 public:
CBuildRestrictionAddOn()597 	CBuildRestrictionAddOn() : Offset(0, 0), Parent(nullptr) {}
~CBuildRestrictionAddOn()598 	virtual ~CBuildRestrictionAddOn() {}
Init()599 	virtual void Init() {this->Parent = UnitTypeByIdent(this->ParentName);}
600 	//Wyrmgus start
601 //	virtual bool Check(const CUnit *builder, const CUnitType &type, const Vec2i &pos, CUnit *&ontoptarget) const;
602 	virtual bool Check(const CUnit *builder, const CUnitType &type, const Vec2i &pos, CUnit *&ontoptarget, int z) const;
603 	//Wyrmgus end
604 
605 	Vec2i Offset;           /// offset from the main building to place this
606 	std::string ParentName; /// building that is unit is an addon too.
607 	CUnitType *Parent;      /// building that is unit is an addon too.
608 };
609 
610 class CBuildRestrictionOnTop : public CBuildRestriction
611 {
612 	class functor
613 	{
614 	public:
functor(const CUnitType * type,const Vec2i & _pos)615 		functor(const CUnitType *type, const Vec2i &_pos): ontop(0), Parent(type), pos(_pos) {}
616 		inline bool operator()(CUnit *const unit);
617 		CUnit *ontop;   /// building that is unit is an addon too.
618 	private:
619 		const CUnitType *const Parent;  /// building that is unit is an addon too.
620 		const Vec2i pos;  //functor work position
621 	};
622 public:
CBuildRestrictionOnTop()623 	CBuildRestrictionOnTop() : Parent(nullptr), ReplaceOnDie(0), ReplaceOnBuild(0) {};
~CBuildRestrictionOnTop()624 	virtual ~CBuildRestrictionOnTop() {};
Init()625 	virtual void Init() {this->Parent = UnitTypeByIdent(this->ParentName);};
626 	//Wyrmgus start
627 //	virtual bool Check(const CUnit *builder, const CUnitType &type, const Vec2i &pos, CUnit *&ontoptarget) const;
628 	virtual bool Check(const CUnit *builder, const CUnitType &type, const Vec2i &pos, CUnit *&ontoptarget, int z) const;
629 	//Wyrmgus end
630 
631 	std::string ParentName;  /// building that is unit is an addon too.
632 	CUnitType *Parent;       /// building that is unit is an addon too.
633 	int ReplaceOnDie: 1;     /// recreate the parent on destruction
634 	int ReplaceOnBuild: 1;   /// remove the parent, or just build over it.
635 };
636 
637 class CBuildRestrictionDistance : public CBuildRestriction
638 {
639 public:
CBuildRestrictionDistance()640 	CBuildRestrictionDistance() : Distance(0), CheckBuilder(false), RestrictType(nullptr), RestrictClass(-1), Diagonal(true) {};
~CBuildRestrictionDistance()641 	virtual ~CBuildRestrictionDistance() {};
642 	virtual void Init();
643 	//Wyrmgus start
644 //	virtual bool Check(const CUnit *builder, const CUnitType &type, const Vec2i &pos, CUnit *&ontoptarget) const;
645 	virtual bool Check(const CUnit *builder, const CUnitType &type, const Vec2i &pos, CUnit *&ontoptarget, int z) const;
646 	//Wyrmgus end
647 
648 	int Distance;        /// distance to build (circle)
649 	DistanceTypeType DistanceType;
650 	std::string RestrictTypeName;
651 	std::string RestrictTypeOwner;
652 	CUnitType *RestrictType;
653 	std::string RestrictClassName;
654 	int RestrictClass;
655 	bool CheckBuilder;
656 	bool Diagonal;
657 };
658 
659 class CBuildRestrictionHasUnit : public CBuildRestriction
660 {
661 public:
CBuildRestrictionHasUnit()662 	CBuildRestrictionHasUnit() : Count(0), RestrictType(nullptr) {};
~CBuildRestrictionHasUnit()663 	virtual ~CBuildRestrictionHasUnit() {};
Init()664 	virtual void Init() { this->RestrictType = UnitTypeByIdent(this->RestrictTypeName); };
665 	//Wyrmgus start
666 //	virtual bool Check(const CUnit *builder, const CUnitType &type, const Vec2i &pos, CUnit *&ontoptarget) const;
667 	virtual bool Check(const CUnit *builder, const CUnitType &type, const Vec2i &pos, CUnit *&ontoptarget, int z) const;
668 	//Wyrmgus end
669 
670 	int Count;
671 	DistanceTypeType CountType;
672 	std::string RestrictTypeName;
673 	CUnitType *RestrictType;
674 	std::string RestrictTypeOwner;
675 };
676 
677 class CBuildRestrictionSurroundedBy : public CBuildRestriction
678 {
679 public:
CBuildRestrictionSurroundedBy()680 	CBuildRestrictionSurroundedBy() : Count(0), Distance(0), DistanceType(Equal), CountType(Equal), RestrictType(nullptr), CheckBuilder(false) {};
~CBuildRestrictionSurroundedBy()681 	virtual ~CBuildRestrictionSurroundedBy() {};
Init()682 	virtual void Init() { this->RestrictType = UnitTypeByIdent(this->RestrictTypeName); };
683 	//Wyrmgus start
684 //	virtual bool Check(const CUnit *builder, const CUnitType &type, const Vec2i &pos, CUnit *&ontoptarget) const;
685 	virtual bool Check(const CUnit *builder, const CUnitType &type, const Vec2i &pos, CUnit *&ontoptarget, int z) const;
686 	//Wyrmgus end
687 
688 	int Distance;
689 	DistanceTypeType DistanceType;
690 	int Count;
691 	DistanceTypeType CountType;
692 	std::string RestrictTypeName;
693 	std::string RestrictTypeOwner;
694 	CUnitType *RestrictType;
695 	bool CheckBuilder;
696 };
697 
698 //Wyrmgus start
699 class CBuildRestrictionTerrain : public CBuildRestriction
700 {
701 public:
CBuildRestrictionTerrain()702 	CBuildRestrictionTerrain() : RestrictTerrainType(nullptr) {};
~CBuildRestrictionTerrain()703 	virtual ~CBuildRestrictionTerrain() {};
704 	virtual void Init();
705 	virtual bool Check(const CUnit *builder, const CUnitType &type, const Vec2i &pos, CUnit *&ontoptarget, int z) const;
706 
707 	std::string RestrictTerrainTypeName;
708 	CTerrainType *RestrictTerrainType;
709 };
710 //Wyrmgus end
711 
712 //Wyrmgus start
713 class CSpeciesPhylum
714 {
715 public:
CSpeciesPhylum()716 	CSpeciesPhylum() :
717 		Ident("")
718 	{
719 	}
720 
721 	std::string Ident;				/// Ident of the species phylum
722 	std::string Name;				/// Name of the species phylum
723 	std::string Kingdom;
724 	std::string Subkingdom;
725 	std::string Infrakingdom;
726 };
727 
728 class CSpeciesClass
729 {
730 public:
CSpeciesClass()731 	CSpeciesClass() :
732 		Phylum(nullptr)
733 	{
734 	}
735 
736 	std::string Ident;				/// Ident of the species class
737 	std::string Name;				/// Name of the species class
738 	CSpeciesPhylum *Phylum;
739 	std::string Subphylum;
740 	std::string Infraphylum;
741 	std::string Superclass;
742 };
743 
744 class CSpeciesOrder
745 {
746 public:
CSpeciesOrder()747 	CSpeciesOrder() :
748 		Class(nullptr)
749 	{
750 	}
751 
752 	std::string Ident;				/// Ident of the species order
753 	std::string Name;				/// Name of the species order
754 	CSpeciesClass *Class;
755 	std::string Subclass;
756 	std::string Infraclass;
757 };
758 
759 class CSpeciesFamily
760 {
761 public:
CSpeciesFamily()762 	CSpeciesFamily() :
763 		Order(nullptr)
764 	{
765 	}
766 
767 	std::string Ident;				/// Ident of the species family
768 	std::string Name;				/// Name of the species family
769 	CSpeciesOrder *Order;
770 	std::string Suborder;
771 	std::string Infraorder;
772 	std::string Superfamily;
773 };
774 
775 class CSpeciesGenus
776 {
777 public:
CSpeciesGenus()778 	CSpeciesGenus() :
779 		Family(nullptr)
780 	{
781 	}
782 
783 	std::string Ident;				/// Ident of the genus
784 	std::string Name;				/// Name of the genus
785 	std::string CommonName;			/// Common name of the genus
786 	CSpeciesFamily *Family;
787 	std::string Subfamily;
788 	std::string Tribe;
789 };
790 
791 class CSpecies
792 {
793 public:
794 	bool CanEvolveToAUnitType(CTerrainType *terrain = nullptr, bool sapient_only = false);
795 	CSpecies *GetRandomEvolution(CTerrainType *terrain);
796 
797 	int Era = -1;					/// Era ID
798 	bool Sapient = false;			/// Whether the species is sapient
799 	bool Prehistoric = false;		/// Whether the species is prehistoric or not
800 	std::string Ident;				/// Ident of the species
801 	std::string Name;				/// Name of the species
802 	std::string Description;		/// Description of the species
803 	std::string Quote;				/// Quote pertaining to the species
804 	std::string Background;			/// Background of the species
805 	CSpeciesGenus *Genus = nullptr;
806 	std::string Species;
807 	std::string ChildUpgrade;		/// Which individual upgrade the children of this species get
808 	CPlane *HomePlane = nullptr;
809 	CWorld *Homeworld = nullptr;
810 	CUnitType *Type = nullptr;
811 	std::vector<CTerrainType *> Terrains;	/// in which terrains does this species live
812 	std::vector<CSpecies *> EvolvesFrom;	/// from which species this one can evolve
813 	std::vector<CSpecies *> EvolvesTo;		/// to which species this one can evolve
814 };
815 //Wyrmgus end
816 
817 /// Base structure of unit-type
818 /// @todo n0body: AutoBuildRate not implemented.
819 class CUnitType : public CDataType
820 {
821 public:
822 	CUnitType();
823 	~CUnitType();
824 
825 	virtual void ProcessConfigData(const CConfigData *config_data) override;
826 
827 	Vec2i GetTileSize() const;
828 	Vec2i GetHalfTileSize() const;
GetHalfTilePixelSize(const int map_layer)829 	PixelSize GetHalfTilePixelSize(const int map_layer) const { return GetTilePixelSize(map_layer) / 2; }
830 	PixelSize GetTilePixelSize(const int map_layer) const;
831 	Vec2i GetTileCenterPosOffset() const;
832 
833 	bool CheckUserBoolFlags(const char *BoolFlags) const;
834 	//Wyrmgus start
835 //	bool CanTransport() const { return MaxOnBoard > 0 && !GivesResource; }
CanTransport()836 	bool CanTransport() const { return MaxOnBoard > 0; }
837 	//Wyrmgus end
838 	bool CanMove() const;
839 
840 	bool CanSelect(GroupSelectionMode mode = SELECTABLE_BY_RECTANGLE_ONLY) const;
841 
842 	//Wyrmgus start
843 	void SetParent(CUnitType *parent_type);
844 	void RemoveButtons(int button_action = -1, std::string mod_file = "");
845 	void UpdateDefaultBoolFlags();
846 	int GetAvailableLevelUpUpgrades() const;
847 	int GetResourceStep(const int resource, const int player) const;
848 	CUnitTypeVariation *GetDefaultVariation(CPlayer &player, int image_layer = -1) const;
849 	CUnitTypeVariation *GetVariation(const std::string &variation_name, int image_layer = -1) const;
850 	std::string GetRandomVariationIdent(int image_layer = -1) const;
851 	std::string GetDefaultName(CPlayer &player) const;
852 	CPlayerColorGraphic *GetDefaultLayerSprite(CPlayer &player, int image_layer) const;
853 	bool CanExperienceUpgradeTo(CUnitType *type) const;
854 	std::string GetNamePlural() const;
855 	std::string GeneratePersonalName(CFaction *faction, int gender) const;
856 	bool IsPersonalNameValid(const std::string &name, CFaction *faction, int gender) const;
857 	std::vector<std::string> GetPotentialPersonalNames(CFaction *faction, int gender) const;
858 	//Wyrmgus end
859 
860 public:
861 	std::string Name;               /// Pretty name shown from the engine
862 	bool Initialized = false;
863 	CUnitType *Parent;				/// Parent unit type
864 	//Wyrmgus start
865 	int Class;						/// Class identifier (i.e. infantry, archer, etc.)
866 	int Civilization;				/// Which civilization this unit belongs to, if any
867 	int Faction;					/// Which faction this unit belongs to, if any
868 	std::string Description;		/// Description of the unit type
869 	std::string Quote;				/// Quote of the unit type
870 	std::string Background;			/// Encyclopedia entry for the unit type
871 	std::string RequirementsString;	/// Requirements string of the unit type
872 	std::string ExperienceRequirementsString;	/// Experience requirements string of the unit type
873 	std::string BuildingRulesString;	/// Building rules string of the unit type
874 	CUpgrade *Elixir;						/// Which elixir does this (item) unit type always have
875 	std::vector<CUnitType *> SoldUnits;		/// Units which this unit can sell.
876 	std::vector<CUnitType *> SpawnUnits;	/// Units which this unit can spawn.
877 	std::vector<CUnitType *> Drops;			/// Units which can spawn upon death (i.e. items).
878 	std::vector<CUnitType *> AiDrops;		/// Units which can spawn upon death (i.e. items), only for AI-controlled units.
879 	std::vector<CSpell *> DropSpells;		/// Spells which can be applied to dropped items
880 	std::vector<CUpgrade *> Affixes;		/// Affixes which can be generated for this unit type
881 	std::vector<CUpgrade *> Traits;			/// Which traits this unit type can have
882 	std::vector<CUpgrade *> StartingAbilities;	/// Abilities which the unit starts out with
883 	std::vector<CUnitType *> Trains;		/// Units trained by this unit
884 	std::vector<CUnitType *> TrainedBy;		/// Units which can train this unit
885 	std::map<std::string, std::vector<CUnitType *>> ModTrains;	/// Units trained by this unit (as set in a mod)
886 	std::map<std::string, std::vector<CUnitType *>> ModTrainedBy;	/// Units which can train this unit (as set in a mod)
887 	std::map<std::string, std::vector<CUnitType *>> ModAiDrops;	/// Units dropped by this unit, if it is AI-controlled (as set in a mod)
888 	//Wyrmgus end
889 	int Slot;                       /// Type as number
890 	std::string File;               /// Sprite files
891 	std::string ShadowFile;         /// Shadow file
892 	//Wyrmgus start
893 	std::string LightFile;			/// Light file
894 	std::string LayerFiles[MaxImageLayers];	/// Layer files
895 	std::map<int, IconConfig> ButtonIcons;					/// icons for button actions
896 	std::map<int, CUnitType *> DefaultEquipment;			/// default equipment for the unit type, mapped to item slots
897 	//Wyrmgus end
898 
899 	int Width;                                            /// Sprite width
900 	int Height;                                           /// Sprite height
901 	int OffsetX;                                          /// Sprite horizontal offset
902 	int OffsetY;                                          /// Sprite vertical offset
903 	int DrawLevel;                                        /// Level to Draw UnitType at
904 	int ShadowWidth;                                      /// Shadow sprite width
905 	int ShadowHeight;                                     /// Shadow sprite height
906 	int ShadowOffsetX;                                    /// Shadow horizontal offset
907 	int ShadowOffsetY;                                    /// Shadow vertical offset
908 	//Wyrmgus start
909 	int TrainQuantity;										/// Quantity to be trained
910 	int CostModifier;										/// Cost modifier (cost increase for every unit of this type the player has)
911 	int ItemClass;											/// Item class (if the unit type is an item)
912 	CSpecies *Species;
913 	CTerrainType *TerrainType;
914 	std::vector<int> WeaponClasses;							/// Weapon classes that the unit type can use (if the unit type uses a weapon)
915 	std::map<int, std::vector<std::string>> PersonalNames;	/// Personal names for the unit type, mapped to the gender they pertain to (use NoGender for names which should be available for both genders)
916 	//Wyrmgus end
917 	PixelPos MissileOffsets[UnitSides][MaxAttackPos];     /// Attack offsets for missiles
918 
919 	CAnimations *Animations;        /// Animation scripts
920 	int StillFrame;                 /// Still frame
921 
922 	IconConfig Icon;                /// Icon to display for this unit
923 #ifdef USE_MNG
924 	struct _portrait_ {
925 		std::string *Files;
926 		int Num;
927 		Mng **Mngs;
928 		mutable int CurrMng;
929 		mutable int NumIterations;
930 	} Portrait;
931 #endif
932 	MissileConfig Missile;                           /// Missile weapon
933 	//Wyrmgus start
934 	MissileConfig FireMissile;						 /// Missile weapon if the unit has fire damage
935 	//Wyrmgus end
936 	MissileConfig Explosion;                         /// Missile for unit explosion
937 	MissileConfig Impact[ANIMATIONS_DEATHTYPES + 2]; /// Missiles spawned if unit is hit(+shield)
938 
939 	LuaCallback *DeathExplosion;
940 	LuaCallback *OnHit;             /// lua function called when unit is hit
941 	LuaCallback *OnEachCycle;       /// lua function called every cycle
942 	LuaCallback *OnEachSecond;      /// lua function called every second
943 	LuaCallback *OnInit;            /// lua function called on unit init
944 
945 	int TeleportCost;               /// mana used for teleportation
946 	LuaCallback *TeleportEffectIn;   /// lua function to create effects before teleportation
947 	LuaCallback *TeleportEffectOut;  /// lua function to create effects after teleportation
948 
949 	mutable std::string DamageType; /// DamageType (used for extra death animations and impacts)
950 
951 	std::string CorpseName;         /// Corpse type name
952 	CUnitType *CorpseType;          /// Corpse unit-type
953 
954 	CConstruction *Construction;    /// What is shown in construction phase
955 
956 	int RepairHP;                   /// Amount of HP per repair
957 	int RepairCosts[MaxCosts];      /// How much it costs to repair
958 
959 	Vec2i TileSize;					/// Tile size
960 	int BoxWidth;                   /// Selected box size width
961 	int BoxHeight;                  /// Selected box size height
962 	int BoxOffsetX;                 /// Selected box size horizontal offset
963 	int BoxOffsetY;                 /// Selected box size vertical offset
964 	int NumDirections;              /// Number of directions unit can face
965 	int MinAttackRange;             /// Minimal attack range
966 	//Wyrmgus start
967 	/*
968 	int ReactRangeComputer;         /// Reacts on enemy for computer
969 	int ReactRangePerson;           /// Reacts on enemy for person player
970 	*/
971 	//Wyrmgus end
972 	int BurnPercent;                /// Burning percent.
973 	int BurnDamageRate;             /// HP burn rate per sec
974 	int RepairRange;                /// Units repair range.
975 #define InfiniteRepairRange INT_MAX
976 	std::vector<CSpell *> Spells;	/// Spells the unit is able to cast.
977 	char *AutoCastActive;           /// Default value for autocast.
978 	int AutoBuildRate;              /// The rate at which the building builds itself
979 	int RandomMovementProbability;  /// Probability to move randomly.
980 	int RandomMovementDistance;  	/// Quantity of tiles to move randomly.
981 	int ClicksToExplode;            /// Number of consecutive clicks until unit suicides.
982 	int MaxOnBoard;                 /// Number of Transporter slots.
983 	int BoardSize;                  /// How much "cells" unit occupies inside transporter
984 	CButtonLevel *ButtonLevelForTransporter;  /// On which button level game will show units inside transporter
985 	//Wyrmgus start
986 	int ButtonPos;					/// Position of this unit as a train/build button
987 	CButtonLevel *ButtonLevel;		/// Level of this unit's button
988 	std::string ButtonPopup;		/// Popup of this unit's button
989 	std::string ButtonHint;			/// Hint of this unit's button
990 	std::string ButtonKey;			/// Hotkey of this unit's button
991 //	int StartingResources;          /// Amount of Resources on build
992 	std::vector<int> StartingResources;          /// Amount of Resources on build
993 	//Wyrmgus end
994 	/// originally only visual effect, we do more with this!
995 	UnitTypeType UnitType;          /// Land / fly / naval
996 	int DecayRate;                  /// Decay rate in 1/6 seconds
997 	// TODO: not used
998 	int AnnoyComputerFactor;        /// How much this annoys the computer
999 	int AiAdjacentRange;            /// Min radius for AI build surroundings checking
1000 	int MouseAction;                /// Right click action
1001 #define MouseActionNone      0      /// Nothing
1002 #define MouseActionAttack    1      /// Attack
1003 #define MouseActionMove      2      /// Move
1004 #define MouseActionHarvest   3      /// Harvest resources
1005 #define MouseActionSpellCast 5      /// Cast the first spell known
1006 #define MouseActionSail      6      /// Sail
1007 //Wyrmgus start
1008 #define MouseActionRallyPoint 7		/// Rally point
1009 #define MouseActionTrade      8		/// Trade
1010 //Wyrmgus end
1011 	int CanTarget;                  /// Which units can it attack
1012 #define CanTargetLand 1             /// Can attack land units
1013 #define CanTargetSea  2             /// Can attack sea units
1014 #define CanTargetAir  4             /// Can attack air units
1015 
1016 	unsigned Flip : 1;              /// Flip image when facing left
1017 	unsigned LandUnit : 1;          /// Land animated
1018 	unsigned AirUnit : 1;           /// Air animated
1019 	unsigned SeaUnit : 1;           /// Sea animated
1020 	unsigned ExplodeWhenKilled : 1; /// Death explosion animated
1021 	unsigned CanAttack : 1;         /// Unit can attack.
1022 	unsigned Neutral : 1;           /// Unit is neutral, used by the editor
1023 
1024 	CUnitStats DefaultStat;
1025 	CUnitStats MapDefaultStat;
1026 	//Wyrmgus start
1027 	std::map<std::string, CUnitStats> ModDefaultStats;
1028 	//Wyrmgus end
1029 	struct BoolFlags {
1030 		bool value;             /// User defined flag. Used for (dis)allow target.
1031 		char CanTransport;      /// Can transport units with this flag.
1032 		char CanTargetFlag;     /// Flag needed to target with missile.
1033 		char AiPriorityTarget;  /// Attack this units first.
1034 	};
1035 	std::vector<BoolFlags> BoolFlag;
1036 
1037 	int CanStore[MaxCosts];             /// Resources that we can store here.
1038 	int GivesResource;                  /// The resource this unit gives.
1039 	//Wyrmgus start
1040 	int GrandStrategyProductionEfficiencyModifier[MaxCosts];	/// production modifier for a particular resource for grand strategy mode (used for buildings)
1041 	//Wyrmgus end
1042 	ResourceInfo *ResInfo[MaxCosts];    /// Resource information.
1043 	std::vector<CUnitTypeVariation *> Variations;						/// Variation information
1044 	//Wyrmgus start
1045 	std::vector<CUnitTypeVariation *> LayerVariations[MaxImageLayers];	/// Layer variation information
1046 	//Wyrmgus end
1047 	std::vector<CBuildRestriction *> BuildingRules;   /// Rules list for building a building.
1048 	std::vector<CBuildRestriction *> AiBuildingRules; /// Rules list for for AI to build a building.
1049 	CColor NeutralMinimapColorRGB;   /// Minimap Color for Neutral Units.
1050 
1051 	CUnitSound Sound;				/// Sounds for events
1052 	CUnitSound MapSound;			/// Sounds for events, map-specific
1053 	//Wyrmgus start
1054 	std::map<std::string, CUnitSound> ModSounds;
1055 	//Wyrmgus end
1056 
1057 	int PoisonDrain;                /// How much health is drained every second when poisoned
1058 
1059 	// --- FILLED UP ---
1060 
1061 	//Wyrmgus start
1062 //	unsigned FieldFlags;            /// Unit map field flags
1063 //	unsigned MovementMask;          /// Unit check this map flags for move
1064 	unsigned long FieldFlags;            /// Unit map field flags
1065 	unsigned long MovementMask;          /// Unit check this map flags for move
1066 	//Wyrmgus end
1067 
1068 	/// @todo This stats should? be moved into the player struct
1069 	CUnitStats Stats[PlayerMax];     /// Unit status for each player
1070 
1071 	CPlayerColorGraphic *Sprite;     /// Sprite images
1072 	CGraphic *ShadowSprite;          /// Shadow sprite image
1073 	//Wyrmgus start
1074 	CGraphic *LightSprite;						/// Light sprite image
1075 	CPlayerColorGraphic *LayerSprites[MaxImageLayers];	/// Layer sprite images
1076 
1077 	CDependency *Predependency = nullptr;
1078 	CDependency *Dependency = nullptr;
1079 
1080 	std::string Mod;							/// To which mod (or map), if any, this unit type belongs
1081 	//Wyrmgus end
1082 };
1083 
1084 /*----------------------------------------------------------------------------
1085 --  Variables
1086 ----------------------------------------------------------------------------*/
1087 
1088 extern std::vector<CUnitType *> UnitTypes;   /// All unit-types
1089 
1090 /// @todo this hardcoded unit-types must be removed!!
1091 //Wyrmgus start
1092 //extern CUnitType *UnitTypeHumanWall;  /// Human wall
1093 //extern CUnitType *UnitTypeOrcWall;    /// Orc wall
1094 //Wyrmgus end
1095 
1096 /**
1097 **  Variable info for unit and unittype.
1098 */
1099 class CUnitTypeVar
1100 {
1101 public:
1102 
1103 	template <const unsigned int SIZE>
1104 	struct CKeys {
1105 
1106 		struct DataKey {
key_predCKeys::DataKey1107 			static bool key_pred(const DataKey &lhs,
1108 								 const DataKey &rhs)
1109 			{
1110 				return ((lhs.keylen == rhs.keylen) ?
1111 						(strcmp(lhs.key, rhs.key) < 0) : (lhs.keylen < rhs.keylen));
1112 			}
1113 			int offset;
1114 			unsigned int keylen;
1115 			const char *key;
1116 		};
1117 
CKeysCKeys1118 		CKeys(): TotalKeys(SIZE) {}
1119 
1120 		DataKey buildin[SIZE];
1121 		std::map<std::string, int> user;
1122 		unsigned int TotalKeys;
1123 
InitCKeys1124 		void Init()
1125 		{
1126 			std::sort(buildin, buildin + SIZE, DataKey::key_pred);
1127 		}
1128 
1129 		const char *operator[](int index)
1130 		{
1131 			for (unsigned int i = 0; i < SIZE; ++i) {
1132 				if (buildin[i].offset == index) {
1133 					return buildin[i].key;
1134 				}
1135 			}
1136 			for (std::map<std::string, int>::iterator
1137 				 it(user.begin()), end(user.end());
1138 				 it != end; ++it) {
1139 				if ((*it).second == index) {
1140 					return ((*it).first).c_str();
1141 				}
1142 			}
1143 			return nullptr;
1144 		}
1145 
1146 		/**
1147 		**  Return the index of the external storage array/vector.
1148 		**
1149 		**  @param varname  Name of the variable.
1150 		**
1151 		**  @return Index of the variable, -1 if not found.
1152 		*/
1153 		int operator[](const char *const key)
1154 		{
1155 			DataKey k;
1156 			k.key = key;
1157 			k.keylen = strlen(key);
1158 			const DataKey *p = std::lower_bound(buildin, buildin + SIZE,
1159 												k, DataKey::key_pred);
1160 			if ((p != buildin + SIZE) && p->keylen == k.keylen &&
1161 				0 == strcmp(p->key, key)) {
1162 				return p->offset;
1163 			} else {
1164 				std::map<std::string, int>::iterator
1165 				ret(user.find(key));
1166 				if (ret != user.end()) {
1167 					return (*ret).second;
1168 				}
1169 			}
1170 			return -1;
1171 		}
1172 
AddKeyCKeys1173 		int AddKey(const char *const key)
1174 		{
1175 			int index = this->operator[](key);
1176 			if (index != -1) {
1177 				DebugPrint("Warning, Key '%s' already defined\n" _C_ key);
1178 				return index;
1179 			}
1180 			user[key] = TotalKeys++;
1181 			return TotalKeys - 1;
1182 		}
1183 
1184 	};
1185 
1186 	struct CBoolKeys : public CKeys<NBARALREADYDEFINED> {
1187 		CBoolKeys();
1188 	};
1189 
1190 	struct CVariableKeys : public CKeys<NVARALREADYDEFINED> {
1191 		CVariableKeys();
1192 	};
1193 
CUnitTypeVar()1194 	CUnitTypeVar() {}
1195 
1196 	void Init();
1197 	void Clear();
1198 
1199 	CBoolKeys BoolFlagNameLookup;      /// Container of name of user defined bool flag.
1200 	CVariableKeys VariableNameLookup;  /// Container of names of user defined variables.
1201 
1202 	//EventType *Event;                  /// Array of functions sets to call when en event occurs.
1203 	std::vector<CVariable> Variable;   /// Array of user defined variables (default value for unittype).
1204 	std::vector<CDecoVar *> DecoVar;   /// Array to describe how showing variable.
1205 
GetNumberBoolFlag()1206 	unsigned int GetNumberBoolFlag() const
1207 	{
1208 		return BoolFlagNameLookup.TotalKeys;
1209 	}
1210 
GetNumberVariable()1211 	unsigned int GetNumberVariable() const
1212 	{
1213 		return VariableNameLookup.TotalKeys;
1214 	}
1215 };
1216 
1217 extern CUnitTypeVar UnitTypeVar;
1218 
1219 //Wyrmgus start
1220 extern std::vector<std::string> UnitTypeClasses; //list of unit type classes; built with CclDefineUnitType
1221 extern std::vector<std::vector<CUnitType *>> ClassUnitTypes; //list of unit types belonging to each class
1222 extern std::vector<std::string> UpgradeClasses; //list of upgrade classes; built with CclDefineModifier
1223 extern CUnitType *SettlementSiteUnitType;
1224 
1225 extern std::vector<CSpecies *> Species;
1226 extern std::vector<CSpeciesGenus *> SpeciesGenuses;
1227 extern std::vector<CSpeciesFamily *> SpeciesFamilies;
1228 extern std::vector<CSpeciesOrder *> SpeciesOrders;
1229 extern std::vector<CSpeciesClass *> SpeciesClasses;
1230 extern std::vector<CSpeciesPhylum *> SpeciesPhylums;
1231 //Wyrmgus end
1232 
1233 /*----------------------------------------------------------------------------
1234 --  Functions
1235 ----------------------------------------------------------------------------*/
1236 extern CUnitType *CclGetUnitType(lua_State *l);  /// Access unit-type object
1237 extern void UnitTypeCclRegister();               /// Register ccl features
1238 
1239 extern void UpdateUnitStats(CUnitType &type, int reset_to_default);       /// Update unit stats
1240 extern void UpdateStats(int reset_to_default);       /// Update unit stats
1241 extern CUnitType *UnitTypeByIdent(const std::string &ident);/// Get unit-type by ident
1242 //Wyrmgus start
1243 extern int GetUnitTypeClassIndexByName(const std::string &class_name);
1244 extern int GetOrAddUnitTypeClassIndexByName(const std::string &class_name);
1245 extern void SetUnitTypeClassStringToIndex(const std::string &class_name, int class_id);
1246 extern int GetUpgradeClassIndexByName(const std::string &class_name);
1247 extern void SetUpgradeClassStringToIndex(const std::string &class_name, int class_id);
1248 
1249 extern std::string GetUnitTypeStatsString(const std::string &unit_type_ident);
1250 
1251 extern CSpecies *GetSpecies(const std::string &species_ident);
1252 extern CSpeciesGenus *GetSpeciesGenus(const std::string &genus_ident);
1253 extern CSpeciesFamily *GetSpeciesFamily(const std::string &family_ident);
1254 extern CSpeciesOrder *GetSpeciesOrder(const std::string &order_ident);
1255 extern CSpeciesClass *GetSpeciesClass(const std::string &class_ident);
1256 extern CSpeciesPhylum *GetSpeciesPhylum(const std::string &phylum_ident);
1257 //Wyrmgus end
1258 
1259 extern void SaveUnitTypes(CFile &file);              /// Save the unit-type table
1260 extern CUnitType *NewUnitTypeSlot(const std::string &ident);/// Allocate an empty unit-type slot
1261 /// Draw the sprite frame of unit-type
1262 extern void DrawUnitType(const CUnitType &type, CPlayerColorGraphic *sprite,
1263 						 int player, int frame, const PixelPos &screenPos);
1264 
1265 extern void InitUnitTypes(int reset_player_stats);   /// Init unit-type table
1266 //Wyrmgus start
1267 extern void InitUnitType(CUnitType &type);			/// Init unit-type
1268 //Wyrmgus end
1269 extern void LoadUnitTypeSprite(CUnitType &unittype); /// Load the sprite for a unittype
1270 extern int GetUnitTypesCount();                     /// Get the amount of unit-types
1271 extern void LoadUnitTypes();                     /// Load the unit-type data
1272 //Wyrmgus start
1273 extern void LoadUnitType(CUnitType &unittype);	/// Load a unittype
1274 //Wyrmgus end
1275 extern void CleanUnitTypes();                    /// Cleanup unit-type module
1276 
1277 // in script_unittype.c
1278 
1279 /// Parse User Variables field.
1280 extern void DefineVariableField(lua_State *l, CVariable *var, int lua_index);
1281 
1282 /// Update custom Variables with other variable (like Hp, ...)
1283 extern void UpdateUnitVariables(CUnit &unit);
1284 
1285 extern void SetModStat(const std::string &mod_file, const std::string &ident, const std::string &variable_key, const int value, const std::string &variable_type);
1286 extern void SetModSound(const std::string &mod_file, const std::string &ident, const std::string &sound, const std::string &sound_type, const std::string &sound_subtype = "");
1287 
1288 //Wyrmgus start
1289 extern std::string GetImageLayerNameById(int image_layer);
1290 extern int GetImageLayerIdByName(const std::string &image_layer);
1291 
1292 extern std::map<std::string, CUnitType *> UnitTypeMap;
1293 //Wyrmgus end
1294 
1295 #endif
1296