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