/* Copyright (c) 2013 yvt based on code of pysnip (c) Mathias Kaerlev 2011-2012. This file is part of OpenSpades. OpenSpades is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenSpades is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenSpades. If not, see . */ #pragma once #include #include #include #include #include #include #include #include "GameMapWrapper.h" #include "PhysicsConstants.h" #include #include #include #include namespace spades { namespace client { class GameMap; class GameMapWrapper; class Player; class IWorldListener; class Grenade; class IGameMode; class Client; // FIXME: for debug class HitTestDebugger; struct GameProperties; constexpr std::size_t NumPlayerSlots = 128; class World { friend class Client; // FIXME: for debug public: struct Team { IntVector3 color; std::string name; }; struct PlayerPersistent { std::string name; int kills; PlayerPersistent() : kills(0) { ; } }; private: IWorldListener *listener = nullptr; std::unique_ptr mode; Handle map; std::unique_ptr mapWrapper; float time = 0.0f; IntVector3 fogColor; Team teams[3]; std::shared_ptr gameProperties; std::array, NumPlayerSlots> players; std::array playerPersistents; stmp::optional localPlayerIndex; std::list> grenades; std::unique_ptr hitTestDebugger; std::unordered_map createdBlocks; std::unordered_set destroyedBlocks; std::multimap blockRegenerationQueue; std::unordered_map::iterator> blockRegenerationQueueMap; void ApplyBlockActions(); public: World(const std::shared_ptr &); ~World(); const Handle &GetMap() { return map; } GameMapWrapper &GetMapWrapper() { return *mapWrapper; } float GetTime() { return time; } /** Returns a non-null reference to `GameProperties`. */ const std::shared_ptr &GetGameProperties() { return gameProperties; } void SetMap(Handle); IntVector3 GetFogColor() { return fogColor; } void SetFogColor(IntVector3 v) { fogColor = v; } void Advance(float dt); void AddGrenade(std::unique_ptr); const std::list> &GetAllGrenades() { return grenades; } void MarkBlockForRegeneration(const IntVector3 &blockLocation); void UnmarkBlockForRegeneration(const IntVector3 &blockLocation); std::vector CubeLine(IntVector3 v1, IntVector3 v2, int maxLength); stmp::optional GetPlayer(unsigned int i) { SPAssert(i < players.size()); return players[i].get(); } void SetPlayer(int i, std::unique_ptr p); /** * Get the object containing data specific to the current game mode. * Can be `{}` if the game mode is not specified yet. */ stmp::optional GetMode() { return mode.get(); } void SetMode(std::unique_ptr); Team &GetTeam(int t) { if (t >= 2 || t < 0) // spectator return teams[2]; return teams[t]; } PlayerPersistent &GetPlayerPersistent(int index); void CreateBlock(IntVector3 pos, IntVector3 color); void DestroyBlock(std::vector &pos); struct WeaponRayCastResult { bool hit, startSolid; stmp::optional playerId; IntVector3 blockPos; Vector3 hitPos; hitTag_t hitFlag; }; WeaponRayCastResult WeaponRayCast(Vector3 startPos, Vector3 dir, stmp::optional excludePlayerId); size_t GetNumPlayerSlots() { return players.size(); } size_t GetNumPlayers(); stmp::optional GetLocalPlayerIndex() { return localPlayerIndex; } void SetLocalPlayerIndex(stmp::optional p) { localPlayerIndex = p; } /** Get the local player. Can be `nullptr`. */ stmp::optional GetLocalPlayer() { if (!GetLocalPlayerIndex()) return {}; return GetPlayer(*GetLocalPlayerIndex()); } /** Can be `nullptr`. */ HitTestDebugger *GetHitTestDebugger(); void SetListener(IWorldListener *newListener) { listener = newListener; } IWorldListener *GetListener() { return listener; } }; } // namespace client } // namespace spades