1 /************************************************************************************
2 
3 	AstroMenace
4 	Hardcore 3D space scroll-shooter with spaceship upgrade possibilities.
5 	Copyright (c) 2006-2019 Mikhail Kurinnoi, Viewizard
6 
7 
8 	AstroMenace is free software: you can redistribute it and/or modify
9 	it under the terms of the GNU General Public License as published by
10 	the Free Software Foundation, either version 3 of the License, or
11 	(at your option) any later version.
12 
13 	AstroMenace is distributed in the hope that it will be useful,
14 	but WITHOUT ANY WARRANTY; without even the implied warranty of
15 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 	GNU General Public License for more details.
17 
18 	You should have received a copy of the GNU General Public License
19 	along with AstroMenace. If not, see <https://www.gnu.org/licenses/>.
20 
21 
22 	Website: https://viewizard.com/
23 	Project: https://github.com/viewizard/astromenace
24 	E-mail: viewizard@viewizard.com
25 
26 *************************************************************************************/
27 
28 // TODO switch fire type to enumeration
29 
30 // TODO split earth fighter and player ship classes
31 
32 #ifndef OBJECT3D_SPACESHIP_SPACESHIP_H
33 #define OBJECT3D_SPACESHIP_SPACESHIP_H
34 
35 #include "../object3d.h"
36 #include "../shake.h"
37 #include "../weapon/weapon.h"
38 
39 // NOTE switch to nested namespace definition (namespace A::B::C { ... }) (since C++17)
40 namespace viewizard {
41 namespace astromenace {
42 
43 enum class eShipCycle {
44 	Continue,
45 	Break,
46 	DeleteObjectAndContinue,
47 	DeleteObjectAndBreak
48 };
49 
50 enum class eShipPairCycle {
51 	Continue,
52 	DeleteFirstObjectAndContinue,
53 	DeleteSecondObjectAndContinue,
54 	DeleteBothObjectsAndContinue
55 };
56 
57 struct sShipWeaponSlot {
58 	bool SetFire{false};
59 	std::weak_ptr<cWeapon> Weapon{};
60 	sVECTOR3D Location{};
61 	int Type{1};
62 	float YAngle{0.0f};
63 
64 	sShipWeaponSlot() = default;
sShipWeaponSlotsShipWeaponSlot65 	sShipWeaponSlot(const std::weak_ptr<cWeapon> &_Weapon, const sVECTOR3D &_Location) :
66 		Weapon{_Weapon},
67 		Location{_Location}
68 	{}
sShipWeaponSlotsShipWeaponSlot69 	sShipWeaponSlot(int _Type, const sVECTOR3D &_Location) :
70 		Location{_Location},
71 		Type{_Type}
72 	{}
~sShipWeaponSlotsShipWeaponSlot73 	~sShipWeaponSlot()
74 	{
75 		ReleaseWeaponLazy(Weapon);
76 	}
77 
operatorsShipWeaponSlot78 	void operator () (const std::weak_ptr<cWeapon> &_Weapon, const sVECTOR3D &_Location)
79 	{
80 		Weapon = _Weapon;
81 		Location = _Location;
82 	}
83 };
84 
85 class cSpaceShip : public cObject3D {
86 protected:
87 	// don't allow object of this class creation
88 	cSpaceShip() = default;
89 	~cSpaceShip();
90 
91 public:
92 	virtual bool Update(float Time) override;
93 	virtual void SetLocation(const sVECTOR3D &NewLocation) override;
94 	virtual void SetLocationArcadePlayer(const sVECTOR3D &NewLocation);
95 	virtual void SetRotation(const sVECTOR3D &NewRotation) override;
96 
97 	sVECTOR3D Velocity{0.0f, 0.0f, 0.0f};
98 
99 	sVECTOR3D NeedRotate{0.0f, 0.0f, 0.0f};
100 	sVECTOR3D RotationSpeed{1.0f, 1.0f, 1.0f};
101 
102 	float MaxSpeed{0.0f};
103 	float MaxAcceler{0.0f};
104 	float MaxSpeedRotate{0.0f};
105 
106 	float Speed{0.0f};
107 	float NeedSpeed{0.0f};
108 	float Acceler{0.0f};
109 	float NeedAcceler{1.0f};
110 
111 	float SpeedLR{0.0f};
112 	float NeedSpeedLR{0.0f};
113 	float AccelerLR{0.0f};
114 	float NeedAccelerLR{1.0f};
115 
116 	float SpeedUD{0.0f};
117 	float NeedSpeedUD{0.0f};
118 	float AccelerUD{0.0f};
119 	float NeedAccelerUD{1.0f};
120 
121 	float SpeedByCamFB{0.0f};
122 	float NeedSpeedByCamFB{0.0f};
123 	float AccelerByCamFB{0.0f};
124 	float NeedAccelerByCamFB{1.0f};
125 
126 	float SpeedByCamLR{0.0f};
127 	float NeedSpeedByCamLR{0.0f};
128 	float AccelerByCamLR{0.0f};
129 	float NeedAccelerByCamLR{1.0f};
130 
131 	float SpeedByCamUD{0.0f};
132 	float NeedSpeedByCamUD{0.0f};
133 	float AccelerByCamUD{0.0f};
134 	float NeedAccelerByCamUD{1.0f};
135 
136 	float MoveForward{0.0f};
137 	float MoveBackward{0.0f};
138 	float MoveLeft{0.0f};
139 	float MoveRight{0.0f};
140 	float MoveUp{0.0f};
141 	float MoveDown{0.0f};
142 
143 	std::vector<cShake> ShipShake{};
144 
145 	std::vector<sShipWeaponSlot> WeaponSlots{};
146 	int WeaponFireType{2}; // 1- volley fire, 2 - alternate fire
147 	int WeaponGroupCurrentFireNum{-1};
148 	float WeaponGroupCurrentFireDelay{0.0f};
149 
150 	std::vector<sShipWeaponSlot> BossWeaponSlots{};
151 	int BossWeaponFireType{2}; // 1- volley fire, 2 - alternate fire
152 	int BossWeaponGroupCurrentFireNum{-1};
153 	float BossWeaponGroupCurrentFireDelay{0.0f};
154 
155 	std::vector<sShipWeaponSlot> FlareWeaponSlots{};
156 
157 	bool EngineDestroyType{false};
158 	std::vector<std::weak_ptr<cParticleSystem>> Engines{};
159 	std::vector<sVECTOR3D> EnginesLocation{};
160 
161 	std::vector<std::weak_ptr<cParticleSystem>> EnginesLeft{};
162 	std::vector<sVECTOR3D> EnginesLeftLocation{};
163 
164 	std::vector<std::weak_ptr<cParticleSystem>> EnginesRight{};
165 	std::vector<sVECTOR3D> EnginesRightLocation{};
166 };
167 
168 class cAlienSpaceFighter final : public cSpaceShip {
169 	friend std::weak_ptr<cSpaceShip> CreateAlienSpaceFighter(const int SpaceShipNum);
170 private:
171 	// Don't allow direct new/delete usage in code, only CreateAlienSpaceFighter()
172 	// allowed for cAlienSpaceFighter creation and release setup (deleter must be provided).
173 	explicit cAlienSpaceFighter(const int SpaceShipNum);
174 	~cAlienSpaceFighter() = default;
175 };
176 
177 class cAlienSpaceMotherShip final : public cSpaceShip {
178 	friend std::weak_ptr<cSpaceShip> CreateAlienSpaceMotherShip(const int SpaceShipNum);
179 private:
180 	// Don't allow direct new/delete usage in code, only CreateAlienSpaceMotherShip()
181 	// allowed for cAlienSpaceMotherShip creation and release setup (deleter must be provided).
182 	explicit cAlienSpaceMotherShip(const int SpaceShipNum);
183 	~cAlienSpaceMotherShip() = default;
184 };
185 
186 class cEarthSpaceFighter final : public cSpaceShip {
187 	friend std::weak_ptr<cSpaceShip> CreateEarthSpaceFighter(const int SpaceShipNum);
188 private:
189 	// Don't allow direct new/delete usage in code, only cEarthSpaceFighter()
190 	// allowed for cEarthSpaceFighter creation and release setup (deleter must be provided).
191 	explicit cEarthSpaceFighter(const int SpaceShipNum);
192 	~cEarthSpaceFighter() = default;
193 };
194 
195 class cPirateShip final : public cSpaceShip {
196 	friend std::weak_ptr<cSpaceShip> CreatePirateShip(const int SpaceShipNum);
197 private:
198 	// Don't allow direct new/delete usage in code, only cPirateShip()
199 	// allowed for cPirateShip creation and release setup (deleter must be provided).
200 	explicit cPirateShip(const int SpaceShipNum);
201 	~cPirateShip() = default;
202 };
203 
204 
205 // Create cAlienSpaceFighter object.
206 std::weak_ptr<cSpaceShip> CreateAlienSpaceFighter(const int SpaceShipNum);
207 // Create cAlienSpaceMotherShip object.
208 std::weak_ptr<cSpaceShip> CreateAlienSpaceMotherShip(const int SpaceShipNum);
209 // Create cEarthSpaceFighter object.
210 std::weak_ptr<cSpaceShip> CreateEarthSpaceFighter(const int SpaceShipNum);
211 // Create cPirateShip object.
212 std::weak_ptr<cSpaceShip> CreatePirateShip(const int SpaceShipNum);
213 
214 // Update and remove (erase) dead objects.
215 void UpdateAllSpaceShip(float Time);
216 // Draw all objects.
217 void DrawAllSpaceShips(bool VertexOnlyPass, unsigned int ShadowMap);
218 // Release particular space ship.
219 void ReleaseSpaceShip(std::weak_ptr<cSpaceShip> &Ship);
220 // Release all objects.
221 void ReleaseAllSpaceShips();
222 // Cycle for each space ship.
223 // Note, caller must guarantee, that 'Object' will not released in callback function call.
224 void ForEachSpaceShip(std::function<void (cSpaceShip &Object)> function);
225 // Managed cycle for each space ship.
226 // Note, caller must guarantee, that 'Object' will not released in callback function call.
227 void ForEachSpaceShip(std::function<void (cSpaceShip &Object, eShipCycle &Command)> function);
228 // Managed cycle for each space ship pair.
229 // Note, caller must guarantee, that 'FirstObject' and 'SecondObject' will not released in callback function call.
230 void ForEachSpaceShipPair(std::function<void (cSpaceShip &FirstObject,
231 					      cSpaceShip &SecondObject,
232 					      eShipPairCycle &Command)> function);
233 // Get object ptr by reference.
234 std::weak_ptr<cObject3D> GetSpaceShipPtr(const cSpaceShip &Object);
235 
236 // Setup engines.
237 void SetEarthSpaceFighterEngine(std::weak_ptr<cSpaceShip> &SpaceShip, const int EngineType);
238 // Setup armor.
239 void SetEarthSpaceFighterArmor(std::weak_ptr<cSpaceShip> &SpaceShip, const int ArmorType);
240 // Setup weapon.
241 bool SetEarthSpaceFighterWeapon(std::weak_ptr<cSpaceShip> &SpaceShip, const int WeaponSlot, const int WeaponNum);
242 // Get max and min weapon slot angle for particular ship.
243 void GetShipWeaponSlotAngle(const int ShipNum, const int SlotNum, float &Min, float &Max);
244 // Get max engine acceleration.
245 float GetEngineAcceleration(const int EngineType);
246 // Get engine power.
247 float GetEnginePower(const int EngineType);
248 // Get rotate engine power.
249 float GetEngineRotatePower(const int EngineType);
250 // Get armor for particular ship.
251 float GetShipArmor(const int SpaceShipNum);
252 
253 } // astromenace namespace
254 } // viewizard namespace
255 
256 #endif // OBJECT3D_SPACESHIP_SPACESHIP_H
257