1 /*
2 Minetest
3 Copyright (C) 2010-2017 celeron55, Perttu Ahola <celeron55@gmail.com>
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14 
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 
20 #pragma once
21 
22 #include "environment.h"
23 #include <ISceneManager.h>
24 #include "clientobject.h"
25 #include "util/numeric.h"
26 #include "activeobjectmgr.h"
27 
28 class ClientSimpleObject;
29 class ClientMap;
30 class ClientScripting;
31 class ClientActiveObject;
32 class GenericCAO;
33 class LocalPlayer;
34 
35 /*
36 	The client-side environment.
37 
38 	This is not thread-safe.
39 	Must be called from main (irrlicht) thread (uses the SceneManager)
40 	Client uses an environment mutex.
41 */
42 
43 enum ClientEnvEventType
44 {
45 	CEE_NONE,
46 	CEE_PLAYER_DAMAGE
47 };
48 
49 struct ClientEnvEvent
50 {
51 	ClientEnvEventType type;
52 	union {
53 		//struct{
54 		//} none;
55 		struct{
56 			u16 amount;
57 			bool send_to_server;
58 		} player_damage;
59 	};
60 };
61 
62 typedef std::unordered_map<u16, ClientActiveObject*> ClientActiveObjectMap;
63 class ClientEnvironment : public Environment
64 {
65 public:
66 	ClientEnvironment(ClientMap *map, ITextureSource *texturesource, Client *client);
67 	~ClientEnvironment();
68 
69 	Map & getMap();
70 	ClientMap & getClientMap();
71 
getGameDef()72 	Client *getGameDef() { return m_client; }
setScript(ClientScripting * script)73 	void setScript(ClientScripting *script) { m_script = script; }
74 
75 	void step(f32 dtime);
76 
77 	virtual void setLocalPlayer(LocalPlayer *player);
getLocalPlayer()78 	LocalPlayer *getLocalPlayer() const { return m_local_player; }
79 
80 	/*
81 		ClientSimpleObjects
82 	*/
83 
84 	void addSimpleObject(ClientSimpleObject *simple);
85 
86 	/*
87 		ActiveObjects
88 	*/
89 
90 	GenericCAO* getGenericCAO(u16 id);
getActiveObject(u16 id)91 	ClientActiveObject* getActiveObject(u16 id)
92 	{
93 		return m_ao_manager.getActiveObject(id);
94 	}
95 
96 	/*
97 		Adds an active object to the environment.
98 		Environment handles deletion of object.
99 		Object may be deleted by environment immediately.
100 		If id of object is 0, assigns a free id to it.
101 		Returns the id of the object.
102 		Returns 0 if not added and thus deleted.
103 	*/
104 	u16 addActiveObject(ClientActiveObject *object);
105 
106 	void addActiveObject(u16 id, u8 type, const std::string &init_data);
107 	void removeActiveObject(u16 id);
108 
109 	void processActiveObjectMessage(u16 id, const std::string &data);
110 
111 	/*
112 		Callbacks for activeobjects
113 	*/
114 
115 	void damageLocalPlayer(u16 damage, bool handle_hp=true);
116 
117 	/*
118 		Client likes to call these
119 	*/
120 
121 	// Get all nearby objects
getActiveObjects(const v3f & origin,f32 max_d,std::vector<DistanceSortedActiveObject> & dest)122 	void getActiveObjects(const v3f &origin, f32 max_d,
123 		std::vector<DistanceSortedActiveObject> &dest)
124 	{
125 		return m_ao_manager.getActiveObjects(origin, max_d, dest);
126 	}
127 
hasClientEnvEvents()128 	bool hasClientEnvEvents() const { return !m_client_event_queue.empty(); }
129 
130 	// Get event from queue. If queue is empty, it triggers an assertion failure.
131 	ClientEnvEvent getClientEnvEvent();
132 
133 	virtual void getSelectedActiveObjects(
134 		const core::line3d<f32> &shootline_on_map,
135 		std::vector<PointedThing> &objects
136 	);
137 
getPlayerNames()138 	const std::list<std::string> &getPlayerNames() { return m_player_names; }
addPlayerName(const std::string & name)139 	void addPlayerName(const std::string &name) { m_player_names.push_back(name); }
removePlayerName(const std::string & name)140 	void removePlayerName(const std::string &name) { m_player_names.remove(name); }
updateCameraOffset(const v3s16 & camera_offset)141 	void updateCameraOffset(const v3s16 &camera_offset)
142 	{ m_camera_offset = camera_offset; }
getCameraOffset()143 	v3s16 getCameraOffset() const { return m_camera_offset; }
144 private:
145 	ClientMap *m_map;
146 	LocalPlayer *m_local_player = nullptr;
147 	ITextureSource *m_texturesource;
148 	Client *m_client;
149 	ClientScripting *m_script = nullptr;
150 	client::ActiveObjectMgr m_ao_manager;
151 	std::vector<ClientSimpleObject*> m_simple_objects;
152 	std::queue<ClientEnvEvent> m_client_event_queue;
153 	IntervalLimiter m_active_object_light_update_interval;
154 	std::list<std::string> m_player_names;
155 	v3s16 m_camera_offset;
156 };
157