1 /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
2
3 #ifndef MOVEMATH_H
4 #define MOVEMATH_H
5
6 #include "Map/ReadMap.h"
7 #include "System/float3.h"
8 #include "System/Misc/BitwiseEnum.h"
9
10 struct MoveDef;
11 class CSolidObject;
12 class CMoveMath {
13 CR_DECLARE(CMoveMath)
14
15 protected:
16 static float GroundSpeedMod(const MoveDef& moveDef, float height, float slope);
17 static float GroundSpeedMod(const MoveDef& moveDef, float height, float slope, float dirSlopeMod);
18 static float HoverSpeedMod(const MoveDef& moveDef, float height, float slope);
19 static float HoverSpeedMod(const MoveDef& moveDef, float height, float slope, float dirSlopeMod);
20 static float ShipSpeedMod(const MoveDef& moveDef, float height, float slope);
21 static float ShipSpeedMod(const MoveDef& moveDef, float height, float slope, float dirSlopeMod);
22
23 public:
24 // gives the y-coordinate the unit will "stand on"
25 static float yLevel(const MoveDef& moveDef, const float3& pos);
26 static float yLevel(const MoveDef& moveDef, int xSquare, int zSquare);
27
28 public:
29 enum BlockTypes {
30 BLOCK_NONE = 0,
31 BLOCK_MOVING = 1,
32 BLOCK_MOBILE = 2,
33 BLOCK_MOBILE_BUSY = 4,
34 BLOCK_STRUCTURE = 8,
35 BLOCK_IMPASSABLE = 24 // := 16 | BLOCK_STRUCTURE;
36 };
37 typedef Bitwise::BitwiseEnum<BlockTypes> BlockType;
38
39
40 // returns a speed-multiplier for given position or data
41 static float GetPosSpeedMod(const MoveDef& moveDef, int xSquare, int zSquare);
42 static float GetPosSpeedMod(const MoveDef& moveDef, int xSquare, int zSquare, const float3& moveDir);
GetPosSpeedMod(const MoveDef & moveDef,const float3 & pos)43 static float GetPosSpeedMod(const MoveDef& moveDef, const float3& pos)
44 {
45 return (GetPosSpeedMod(moveDef, pos.x / SQUARE_SIZE, pos.z / SQUARE_SIZE));
46 }
GetPosSpeedMod(const MoveDef & moveDef,const float3 & pos,const float3 & moveDir)47 static float GetPosSpeedMod(const MoveDef& moveDef, const float3& pos, const float3& moveDir)
48 {
49 return (GetPosSpeedMod(moveDef, pos.x / SQUARE_SIZE, pos.z / SQUARE_SIZE, moveDir));
50 }
51
52 // tells whether a position is blocked (inaccessable for a given object's MoveDef)
53 static inline BlockType IsBlocked(const MoveDef& moveDef, const float3& pos, const CSolidObject* collider);
54 static inline BlockType IsBlocked(const MoveDef& moveDef, int xSquare, int zSquare, const CSolidObject* collider);
55 static BlockType IsBlockedNoSpeedModCheck(const MoveDef& moveDef, int xSquare, int zSquare, const CSolidObject* collider);
56 static inline BlockType IsBlockedStructure(const MoveDef& moveDef, int xSquare, int zSquare, const CSolidObject* collider);
57 static bool IsBlockedStructureXmax(const MoveDef& moveDef, int xSquare, int zSquare, const CSolidObject* collider);
58 static bool IsBlockedStructureZmax(const MoveDef& moveDef, int xSquare, int zSquare, const CSolidObject* collider);
59
60 // checks whether an object (collidee) is non-crushable by the given MoveDef
61 static bool CrushResistant(const MoveDef& colliderMD, const CSolidObject* collidee);
62 // checks whether an object (collidee) is non-blocking for the given MoveDef
63 // (eg. would return true for a submarine's moveDef vs. a surface ship object)
64 static bool IsNonBlocking(const MoveDef& colliderMD, const CSolidObject* collidee, const CSolidObject* collider);
65 static bool IsNonBlocking(const CSolidObject* collidee, const CSolidObject* collider);
66
67 // checks if a single square is accessable for any object which uses the given MoveDef
68 static BlockType SquareIsBlocked(const MoveDef& moveDef, int xSquare, int zSquare, const CSolidObject* collider);
SquareIsBlocked(const MoveDef & moveDef,const float3 & pos,const CSolidObject * collider)69 static BlockType SquareIsBlocked(const MoveDef& moveDef, const float3& pos, const CSolidObject* collider) {
70 return (SquareIsBlocked(moveDef, pos.x / SQUARE_SIZE, pos.z / SQUARE_SIZE, collider));
71 }
72
73 public:
74 static bool noHoverWaterMove;
75 static float waterDamageCost;
76 };
77
78
79
80 /* Check if a given square-position is accessable by the MoveDef footprint. */
IsBlocked(const MoveDef & moveDef,int xSquare,int zSquare,const CSolidObject * collider)81 inline CMoveMath::BlockType CMoveMath::IsBlocked(const MoveDef& moveDef, int xSquare, int zSquare, const CSolidObject* collider)
82 {
83 if (GetPosSpeedMod(moveDef, xSquare, zSquare) == 0.0f)
84 return BLOCK_IMPASSABLE;
85
86 return (IsBlockedNoSpeedModCheck(moveDef, xSquare, zSquare, collider));
87 }
88
89 /* Converts a point-request into a square-positional request. */
IsBlocked(const MoveDef & moveDef,const float3 & pos,const CSolidObject * collider)90 inline CMoveMath::BlockType CMoveMath::IsBlocked(const MoveDef& moveDef, const float3& pos, const CSolidObject* collider)
91 {
92 return (IsBlocked(moveDef, pos.x / SQUARE_SIZE, pos.z / SQUARE_SIZE, collider));
93 }
94
IsBlockedStructure(const MoveDef & moveDef,int xSquare,int zSquare,const CSolidObject * collider)95 inline CMoveMath::BlockType CMoveMath::IsBlockedStructure(const MoveDef& moveDef, int xSquare, int zSquare, const CSolidObject* collider) {
96 return (IsBlockedNoSpeedModCheck(moveDef, xSquare, zSquare, collider) & BLOCK_STRUCTURE);
97 }
98
99 #endif
100
101