3 Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
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 General Public License for more details.
15 You should have received a copy of the GNU 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.
20 #include "environment.h"
21 #include "main.h" // g_device for timing debug
23 Environment::Environment(Map *map, std::ostream &dout):
29 Environment::~Environment()
32 for(core::list<Player*>::Iterator i = m_players.begin();
33 i != m_players.end(); i++)
41 void Environment::step(float dtime)
43 DSTACK(__FUNCTION_NAME);
47 //TimeTaker maptimerupdatetimer("m_map->timerUpdate()", g_device);
49 m_map->timerUpdate(dtime);
50 //maptimerupdatetimer.stop();
53 Get the highest speed some player is going
55 //TimeTaker playerspeed("playerspeed", g_device);
57 f32 maximum_player_speed = 0.001; // just some small value
58 for(core::list<Player*>::Iterator i = m_players.begin();
59 i != m_players.end(); i++)
61 f32 speed = (*i)->getSpeed().getLength();
62 if(speed > maximum_player_speed)
63 maximum_player_speed = speed;
67 // Maximum time increment (for collision detection etc)
68 // Allow 0.1 blocks per increment
69 // time = distance / speed
70 f32 dtime_max_increment = 0.1*BS / maximum_player_speed;
71 // Maximum time increment is 10ms or lower
72 if(dtime_max_increment > 0.01)
73 dtime_max_increment = 0.01;
75 //TimeTaker playerupdate("playerupdate", g_device);
78 Stuff that has a maximum time increment
80 // Don't allow overly huge dtime
90 if(dtime > dtime_max_increment)
91 dtime_part = dtime_max_increment;
99 for(core::list<Player*>::Iterator i = m_players.begin();
100 i != m_players.end(); i++)
104 // Apply physics to local player
105 if(player->isLocal())
107 // Apply gravity to local player
108 v3f speed = player->getSpeed();
109 speed.Y -= 9.81 * BS * dtime_part * 2;
112 Apply water resistance
116 f32 max_down = 1.0*BS;
117 if(speed.Y < -max_down) speed.Y = -max_down;
120 if(speed.getLength() > max)
122 speed = speed / speed.getLength() * max;
126 player->setSpeed(speed);
131 For local player, this also calculates collision detection.
133 player->move(dtime_part, *m_map);
136 Add footsteps to grass
138 //TimeTaker footsteptimer("footstep", g_device);
140 v3f playerpos = player->getPosition();
141 // Get node that is at BS/4 under player
142 v3s16 bottompos = floatToInt(playerpos + v3f(0,-BS/4,0));
144 MapNode n = m_map->getNode(bottompos);
145 if(n.d == CONTENT_GRASS)
147 n.d = CONTENT_GRASS_FOOTSTEPS;
148 m_map->setNode(bottompos, n);
150 // Update mesh on client
151 if(m_map->mapType() == MAPTYPE_CLIENT)
153 v3s16 p_blocks = getNodeBlockPos(bottompos);
154 MapBlock *b = m_map->getBlockNoCreate(p_blocks);
159 catch(InvalidPositionException &e)
162 //footsteptimer.stop();
165 while(dtime > 0.001);
167 //std::cout<<"Looped "<<loopcount<<" times."<<std::endl;
170 Map & Environment::getMap()
175 void Environment::addPlayer(Player *player)
177 DSTACK(__FUNCTION_NAME);
178 //Check that only one local player exists and peer_ids are unique
179 assert(player->isLocal() == false || getLocalPlayer() == NULL);
180 assert(getPlayer(player->peer_id) == NULL);
181 m_players.push_back(player);
184 void Environment::removePlayer(u16 peer_id)
186 DSTACK(__FUNCTION_NAME);
188 for(core::list<Player*>::Iterator i = m_players.begin();
189 i != m_players.end(); i++)
192 if(player->peer_id != peer_id)
197 // See if there is an another one
198 // (shouldn't be, but just to be sure)
203 LocalPlayer * Environment::getLocalPlayer()
205 for(core::list<Player*>::Iterator i = m_players.begin();
206 i != m_players.end(); i++)
209 if(player->isLocal())
210 return (LocalPlayer*)player;
215 Player * Environment::getPlayer(u16 peer_id)
217 for(core::list<Player*>::Iterator i = m_players.begin();
218 i != m_players.end(); i++)
221 if(player->peer_id == peer_id)
227 core::list<Player*> Environment::getPlayers()
232 void Environment::printPlayers(std::ostream &o)
234 o<<"Players in environment:"<<std::endl;
235 for(core::list<Player*>::Iterator i = m_players.begin();
236 i != m_players.end(); i++)
239 o<<"Player peer_id="<<player->peer_id<<std::endl;