1 /*
2  Copyright (c) 2013 yvt
3  based on code of pysnip (c) Mathias Kaerlev 2011-2012.
4 
5  This file is part of OpenSpades.
6 
7  OpenSpades is free software: you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation, either version 3 of the License, or
10  (at your option) any later version.
11 
12  OpenSpades is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with OpenSpades.  If not, see <http://www.gnu.org/licenses/>.
19 
20  */
21 
22 #pragma once
23 
24 #include <list>
25 #include <memory>
26 #include <unordered_map>
27 #include <unordered_set>
28 #include <vector>
29 #include <map>
30 
31 #include "GameMapWrapper.h"
32 #include "PhysicsConstants.h"
33 #include <Core/Debug.h>
34 #include <Core/Math.h>
35 
36 namespace spades {
37 	namespace client {
38 		class GameMap;
39 		class GameMapWrapper;
40 		class Player;
41 		class IWorldListener;
42 		class Grenade;
43 		class IGameMode;
44 		class Client; // FIXME: for debug
45 		class HitTestDebugger;
46 		struct GameProperties;
47 		class World {
48 			friend class Client; // FIXME: for debug
49 		public:
50 			struct Team {
51 				IntVector3 color;
52 				std::string name;
53 			};
54 			struct PlayerPersistent {
55 				std::string name;
56 				int kills;
PlayerPersistentPlayerPersistent57 				PlayerPersistent() : kills(0) { ; }
58 			};
59 
60 		private:
61 			IWorldListener *listener;
62 
63 			IGameMode *mode;
64 
65 			GameMap *map;
66 			GameMapWrapper *mapWrapper;
67 			float time;
68 			IntVector3 fogColor;
69 			Team teams[3];
70 
71 			std::shared_ptr<GameProperties> gameProperties;
72 
73 			std::vector<Player *> players;
74 			std::vector<PlayerPersistent> playerPersistents;
75 			int localPlayerIndex;
76 
77 			std::list<Grenade *> grenades;
78 			std::unique_ptr<HitTestDebugger> hitTestDebugger;
79 
80 			std::unordered_map<CellPos, spades::IntVector3, CellPosHash> createdBlocks;
81 			std::unordered_set<CellPos, CellPosHash> destroyedBlocks;
82 
83 			std::multimap<float, IntVector3> blockRegenerationQueue;
84 			std::unordered_map<IntVector3, std::multimap<float, IntVector3>::iterator>
85 			  blockRegenerationQueueMap;
86 
87 			void ApplyBlockActions();
88 
89 		public:
90 			World(const std::shared_ptr<GameProperties>&);
91 			~World();
GetMap()92 			GameMap *GetMap() { return map; }
GetMapWrapper()93 			GameMapWrapper *GetMapWrapper() { return mapWrapper; }
GetTime()94 			float GetTime() { return time; }
95 
96 			/** Returns a non-null reference to `GameProperties`. */
GetGameProperties()97 			const std::shared_ptr<GameProperties> &GetGameProperties() { return gameProperties; }
98 
99 			void SetMap(GameMap *);
100 
GetFogColor()101 			IntVector3 GetFogColor() { return fogColor; }
SetFogColor(IntVector3 v)102 			void SetFogColor(IntVector3 v) { fogColor = v; }
103 
104 			void Advance(float dt);
105 
106 			void AddGrenade(Grenade *);
107 			std::vector<Grenade *> GetAllGrenades();
108 
109 			void MarkBlockForRegeneration(const IntVector3 &blockLocation);
110 			void UnmarkBlockForRegeneration(const IntVector3 &blockLocation);
111 
112 			std::vector<IntVector3> CubeLine(IntVector3 v1, IntVector3 v2, int maxLength);
113 
GetPlayer(unsigned int i)114 			Player *GetPlayer(unsigned int i) {
115 				// SPAssert(i >= 0);	lm: unsigned cannot be smaller than 0 :)
116 				SPAssert(i < players.size());
117 				return players[i];
118 			}
119 
120 			void SetPlayer(int i, Player *p);
121 
GetMode()122 			IGameMode *GetMode() { return mode; }
123 			void SetMode(IGameMode *);
124 
GetTeam(int t)125 			Team &GetTeam(int t) {
126 				if (t >= 2 || t < 0) // spectator
127 					return teams[2];
128 				return teams[t];
129 			}
130 
131 			PlayerPersistent &GetPlayerPersistent(int index);
132 
133 			void CreateBlock(IntVector3 pos, IntVector3 color);
134 			void DestroyBlock(std::vector<IntVector3> &pos);
135 
136 			struct WeaponRayCastResult {
137 				bool hit, startSolid;
138 				Player *player;
139 				IntVector3 blockPos;
140 				Vector3 hitPos;
141 				hitTag_t hitFlag;
142 			};
143 
144 			WeaponRayCastResult WeaponRayCast(Vector3 startPos, Vector3 dir, Player *exclude);
145 
GetNumPlayerSlots()146 			size_t GetNumPlayerSlots() { return players.size(); }
147 
148 			size_t GetNumPlayers();
149 
GetLocalPlayerIndex()150 			int GetLocalPlayerIndex() { return localPlayerIndex; }
151 
SetLocalPlayerIndex(int p)152 			void SetLocalPlayerIndex(int p) { localPlayerIndex = p; }
153 
GetLocalPlayer()154 			Player *GetLocalPlayer() {
155 				if (GetLocalPlayerIndex() == -1)
156 					return NULL;
157 				return GetPlayer(GetLocalPlayerIndex());
158 			}
159 
160 			HitTestDebugger *GetHitTestDebugger();
161 
SetListener(IWorldListener * l)162 			void SetListener(IWorldListener *l) { listener = l; }
GetListener()163 			IWorldListener *GetListener() { return listener; }
164 		};
165 	}
166 }
167