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 as soon, as cSpaceShip will be moved to STL usage with weapon (shared_ptr?),
29 // switch to eDeleteAfterLeaveScene::enabled by default and remove SetDeleteAfterLeaveScene()
30 // also explosions creation code should be corrected (remove DeleteAfterLeaveScene setup)
31
32 // TODO in case DeleteAfterLeaveScene is 'enabled', also should be limited by time
33 // if object was never shown on the scene (during this time), should be deleted + warning output
34
35 // TODO check 'virtual' usage here, do we really need this class functions override?
36
37 #ifndef OBJECT3D_OBJECT3D_H
38 #define OBJECT3D_OBJECT3D_H
39
40 #include "../core/core.h"
41 #include "../enum.h"
42 #include "../script/script.h"
43
44 // NOTE switch to nested namespace definition (namespace A::B::C { ... }) (since C++17)
45 namespace viewizard {
46 namespace astromenace {
47
48 // FIXME should be fixed, don't allow global scope interaction for local variables
49 extern int GameEnemyWeaponPenalty;
50 extern int GameEnemyArmorPenalty;
51 extern int GameEnemyTargetingSpeedPenalty;
52 extern int GameUnlimitedAmmo;
53 extern int GameUndestroyableWeapon;
54 extern int GameWeaponTargetingMode;
55 extern int GameSpaceShipControlMode;
56 extern int GameEngineSystem;
57 extern int GameTargetingSystem;
58 extern int GameAdvancedProtectionSystem;
59 extern int GameTargetingMechanicSystem;
60
61 enum class eObjectStatus {
62 none,
63 Enemy,
64 Ally,
65 Player
66 };
67
ObjectsStatusFoe(eObjectStatus Object1,eObjectStatus Object2)68 inline bool ObjectsStatusFoe(eObjectStatus Object1, eObjectStatus Object2)
69 {
70 return ((Object1 == eObjectStatus::Enemy) && ((Object2 == eObjectStatus::Ally) || (Object2 == eObjectStatus::Player))) ||
71 ((Object2 == eObjectStatus::Enemy) && ((Object1 == eObjectStatus::Ally) || (Object1 == eObjectStatus::Player)));
72 }
73
74 enum class eObjectType {
75 none,
76 EarthFighter,
77 AlienFighter,
78 AlienMotherShip,
79 PirateShip,
80 PirateVehicle,
81 PirateBuilding,
82 SmallAsteroid,
83 SpaceDebris,
84 ShipWeapon,
85 Projectile,
86 Explosion,
87 CivilianBuilding,
88 BasePart,
89 Planet,
90 Planetoid,
91 BigAsteroid
92 // if you change this enum, make sure that AddBonusForKilledEnemy() also reflect this changes
93 };
94
95 enum class eDeleteAfterLeaveScene {
96 disabled,
97 enabled, // waiting, object should being shown on the scene first
98 showed, // object shown, waiting when it will be out of the scene
99 need_delete, // object shown and out of the scene, should be deleted
100 wait_delay // will be deleted after delay
101 };
102 // delay before object delete, since object could back to the scene
103 constexpr float DeleteAfterLeaveSceneDelay{1.0f};
104
105 /*
106 For now we have 2 types of damage:
107 Kinetic - good for armor and shield, stable damage value;
108 EM (electromagnetic) - good for shield (stable damage value), have a chance to kill alien (energy creature)
109 by one hit, have a chance to damage armor (random damage value), have a chance to disable some internal system;
110 */
111 // TODO probably, we also need "Explosion" damage type for shock wave, that now connected to 75% of Kinetic damage
112 class cDamage {
113 private:
114 float Kinetic_{0.0f};
115 float EM_{0.0f}; // electromagnetic
116
117 public:
118 cDamage() = default;
cDamage(float Value)119 explicit cDamage(float Value) :
120 Kinetic_{Value},
121 EM_{Value}
122 {}
cDamage(float Kinetic,float EM)123 explicit cDamage(float Kinetic, float EM) :
124 Kinetic_{Kinetic},
125 EM_{EM}
126 {}
127
128 cDamage& operator = (float Value)
129 {
130 Kinetic_ = Value;
131 EM_ = Value;
132 return *this;
133 }
134
135 cDamage& operator /= (float Value)
136 {
137 Kinetic_ /= Value;
138 EM_ /= Value;
139 return *this;
140 }
141
142 cDamage& operator *= (float Value)
143 {
144 Kinetic_ *= Value;
145 EM_ *= Value;
146 return *this;
147 }
148
Kinetic()149 float Kinetic() const
150 {
151 return Kinetic_;
152 }
153
Kinetic()154 float &Kinetic()
155 {
156 return Kinetic_;
157 }
158
EM()159 float EM() const
160 {
161 return EM_;
162 }
163
EM()164 float &EM()
165 {
166 return EM_;
167 }
168
Full()169 float Full() const
170 {
171 return Kinetic_ + EM_;
172 }
173 };
174
175 inline cDamage operator * (const cDamage &Damage, float Value)
176 {
177 return cDamage{Damage.Kinetic() * Value, Damage.EM() * Value};
178 }
179
180 class cObject3D : public sModel3D {
181 protected:
182 // don't allow object of this class creation
183 cObject3D() = default;
184 ~cObject3D() = default;
185
186 public:
187 virtual void Draw(bool VertexOnlyPass, bool ShadowMap = false);
188 bool NeedCullFaces{true};
189 bool NeedAlphaTest{false};
190 virtual bool Update(float Time);
191
192 void SetChunkLocation(const sVECTOR3D &NewLocation, unsigned ChunkNum);
193 void SetChunkRotation(const sVECTOR3D &NewRotation, unsigned ChunkNum);
194 virtual void SetLocation(const sVECTOR3D &NewLocation);
195 virtual void SetRotation(const sVECTOR3D &NewRotation);
196
197 // in-game object's status relatively to player
198 eObjectStatus ObjectStatus{eObjectStatus::none};
199 // global object type
200 eObjectType ObjectType{eObjectType::none};
201 // internal object's type for objects with same ObjectType, usually, same as creation type (num)
202 int InternalType{0};
203
204 // in case we need show object and delete after it leave scene (after DeleteAfterLeaveSceneDelay time)
205 eDeleteAfterLeaveScene DeleteAfterLeaveScene{eDeleteAfterLeaveScene::disabled};
206 // note, Lifetime could be changed by DeleteAfterLeaveScene settings
207 float Lifetime{-1.0f};
208
209 sVECTOR3D Orientation{0.0f, 0.0f, 1.0f};
210 sVECTOR3D Rotation{0.0f, 0.0f, 0.0f};
211 sVECTOR3D OldRotationInv{0.0f, 0.0f, 0.0f};
212 sVECTOR3D Location{0.0f, 0.0f, 0.0f};
213 sVECTOR3D PrevLocation{0.0f, 0.0f, 0.0f};
214
215 float TimeLastUpdate{-1.0f};
216 float TimeDelta{0.0f};
217
218 std::vector<GLtexture> Texture{};
219 std::vector<GLtexture> TextureIllum{};
220 std::vector<GLtexture> NormalMap{};
221
222 float PromptDrawDist2{-1.0f}; // LOD related
223 int InternalLights{0};
224
225 // material related
226 float Diffuse[4]{1.0f, 1.0f, 1.0f, 1.0f};
227 float Specular[4]{1.0f, 1.0f, 1.0f, 1.0f};
228 float Ambient[4]{0.1f, 0.1f, 0.1f, 0.1f};
229 float Power[1]{64.0f};
230
231 float ArmorCurrentStatus{0.0f};
232 float ArmorInitialStatus{0.0f};
233
234 float ShieldCurrentStatus{0.0f};
235 float ShieldInitialStatus{0.0f};
236 float ShieldRechargeRate{0.0f};
237
238 bool ShowStatus{true};
239 bool ShowStatusAllTime{false};
240
241 float CurrentRotationMat[9]{1.0f, 0.0f, 0.0f,
242 0.0f, 1.0f, 0.0f,
243 0.0f, 0.0f, 1.0f};
244 float OldInvRotationMat[9]{1.0f, 0.0f, 0.0f,
245 0.0f, 1.0f, 0.0f,
246 0.0f, 0.0f, 1.0f};
247
248 std::u32string ScriptLineNumberUTF32{}; // debug info, line number in script file
249
250 std::list<sTimeSheet> TimeSheetList{};
251 };
252
253
254 // we need fixed integers here, since we use them in scripts
255 enum class eRenderBoundingBoxes : int {
256 None = 0,
257 AABB_Only = 1,
258 AABB_And_OBB = 2,
259 All = 3 // AABB, OBB, HitBB
260 };
261
262 // Set bounding boxes render mode.
263 void SetObjectsBBRenderMode(eRenderBoundingBoxes Mode);
264
265
266 /*
267 * object3d_manager
268 */
269
270 // Draw all oblect3d.
271 void DrawAllObject3D(eDrawType DrawType);
272 // Update all oblect3d.
273 void UpdateAllObject3D(float Time);
274 // Release all oblect3d.
275 void ReleaseAllObject3D();
276
277 /*
278 * object3d_collision
279 */
280
281 // Проверяем все объекты на столкновение
282 void DetectCollisionAllObject3D();
283
284 /*
285 * object3d_functions
286 */
287
288 // Check for "mortal" objects, that could be used for collision detection.
289 bool NeedCheckCollision(const cObject3D &Object3D);
290 // Load 3D model data.
291 void LoadObjectData(const std::string &FileName, cObject3D &Object3D);
292 // Setup shaders.
293 bool SetupObject3DShaders();
294
295 } // astromenace namespace
296 } // viewizard namespace
297
298 #endif // OBJECT3D_OBJECT3D_H
299