summaryrefslogtreecommitdiff
path: root/src/environment.cpp
diff options
context:
space:
mode:
authorPerttu Ahola <celeron55@gmail.com>2010-11-27 01:02:21 +0200
committerPerttu Ahola <celeron55@gmail.com>2010-11-27 01:02:21 +0200
commit4e249fb3fbf75f0359758760d88e22aa5b14533c (patch)
tree323087d05efbd2ace27b316d4f017cf812a31992 /src/environment.cpp
downloadminetest-4e249fb3fbf75f0359758760d88e22aa5b14533c.tar.gz
minetest-4e249fb3fbf75f0359758760d88e22aa5b14533c.tar.bz2
minetest-4e249fb3fbf75f0359758760d88e22aa5b14533c.zip
Initial files
Diffstat (limited to 'src/environment.cpp')
-rw-r--r--src/environment.cpp206
1 files changed, 206 insertions, 0 deletions
diff --git a/src/environment.cpp b/src/environment.cpp
new file mode 100644
index 000000000..412bb33e8
--- /dev/null
+++ b/src/environment.cpp
@@ -0,0 +1,206 @@
+#include "environment.h"
+#include "main.h" // g_device for timing debug
+
+Environment::Environment(Map *map, std::ostream &dout):
+ m_dout(dout)
+{
+ m_map = map;
+}
+
+Environment::~Environment()
+{
+ // Deallocate players
+ for(core::list<Player*>::Iterator i = m_players.begin();
+ i != m_players.end(); i++)
+ {
+ delete (*i);
+ }
+
+ delete m_map;
+}
+
+void Environment::step(float dtime)
+{
+ DSTACK(__FUNCTION_NAME);
+ /*
+ Run Map's timers
+ */
+ //TimeTaker maptimerupdatetimer("m_map->timerUpdate()", g_device);
+ // 0ms
+ m_map->timerUpdate(dtime);
+ //maptimerupdatetimer.stop();
+
+ /*
+ Get the highest speed some player is going
+ */
+ //TimeTaker playerspeed("playerspeed", g_device);
+ // 0ms
+ f32 maximum_player_speed = 0.001; // just some small value
+ for(core::list<Player*>::Iterator i = m_players.begin();
+ i != m_players.end(); i++)
+ {
+ f32 speed = (*i)->getSpeed().getLength();
+ if(speed > maximum_player_speed)
+ maximum_player_speed = speed;
+ }
+ //playerspeed.stop();
+
+ // Maximum time increment (for collision detection etc)
+ // Allow 0.1 blocks per increment
+ // time = distance / speed
+ f32 dtime_max_increment = 0.1*BS / maximum_player_speed;
+ // Maximum time increment is 10ms or lower
+ if(dtime_max_increment > 0.01)
+ dtime_max_increment = 0.01;
+
+ //TimeTaker playerupdate("playerupdate", g_device);
+
+ /*
+ Stuff that has a maximum time increment
+ */
+ // Don't allow overly huge dtime
+ if(dtime > 0.5)
+ dtime = 0.5;
+
+ u32 loopcount = 0;
+ do
+ {
+ loopcount++;
+
+ f32 dtime_part;
+ if(dtime > dtime_max_increment)
+ dtime_part = dtime_max_increment;
+ else
+ dtime_part = dtime;
+ dtime -= dtime_part;
+
+ /*
+ Handle players
+ */
+ for(core::list<Player*>::Iterator i = m_players.begin();
+ i != m_players.end(); i++)
+ {
+ Player *player = *i;
+
+ // Apply gravity to local player
+ if(player->isLocal())
+ {
+ v3f speed = player->getSpeed();
+ speed.Y -= 9.81 * BS * dtime_part * 2;
+ player->setSpeed(speed);
+ }
+
+ /*
+ Move the player.
+ For local player, this also calculates collision detection.
+ */
+ player->move(dtime_part, *m_map);
+
+ /*
+ Add footsteps to grass
+ */
+ //TimeTaker footsteptimer("footstep", g_device);
+ // 0ms
+ v3f playerpos = player->getPosition();
+ // Get node that is at BS/4 under player
+ v3s16 bottompos = floatToInt(playerpos + v3f(0,-BS/4,0));
+ try{
+ MapNode n = m_map->getNode(bottompos);
+ if(n.d == MATERIAL_GRASS)
+ {
+ n.d = MATERIAL_GRASS_FOOTSTEPS;
+ m_map->setNode(bottompos, n);
+
+ // Update mesh on client
+ if(m_map->mapType() == MAPTYPE_CLIENT)
+ {
+ v3s16 p_blocks = getNodeBlockPos(bottompos);
+ MapBlock *b = m_map->getBlockNoCreate(p_blocks);
+ b->updateMesh();
+ }
+ }
+ }
+ catch(InvalidPositionException &e)
+ {
+ }
+ //footsteptimer.stop();
+ }
+ }
+ while(dtime > 0.001);
+
+ //std::cout<<"Looped "<<loopcount<<" times."<<std::endl;
+}
+
+Map & Environment::getMap()
+{
+ return *m_map;
+}
+
+void Environment::addPlayer(Player *player)
+{
+ DSTACK(__FUNCTION_NAME);
+ //Check that only one local player exists and peer_ids are unique
+ assert(player->isLocal() == false || getLocalPlayer() == NULL);
+ assert(getPlayer(player->peer_id) == NULL);
+ m_players.push_back(player);
+}
+
+void Environment::removePlayer(u16 peer_id)
+{
+ DSTACK(__FUNCTION_NAME);
+re_search:
+ for(core::list<Player*>::Iterator i = m_players.begin();
+ i != m_players.end(); i++)
+ {
+ Player *player = *i;
+ if(player->peer_id != peer_id)
+ continue;
+
+ delete player;
+ m_players.erase(i);
+ // See if there is an another one
+ // (shouldn't be, but just to be sure)
+ goto re_search;
+ }
+}
+
+LocalPlayer * Environment::getLocalPlayer()
+{
+ for(core::list<Player*>::Iterator i = m_players.begin();
+ i != m_players.end(); i++)
+ {
+ Player *player = *i;
+ if(player->isLocal())
+ return (LocalPlayer*)player;
+ }
+ return NULL;
+}
+
+Player * Environment::getPlayer(u16 peer_id)
+{
+ for(core::list<Player*>::Iterator i = m_players.begin();
+ i != m_players.end(); i++)
+ {
+ Player *player = *i;
+ if(player->peer_id == peer_id)
+ return player;
+ }
+ return NULL;
+}
+
+core::list<Player*> Environment::getPlayers()
+{
+ return m_players;
+}
+
+void Environment::printPlayers(std::ostream &o)
+{
+ o<<"Players in environment:"<<std::endl;
+ for(core::list<Player*>::Iterator i = m_players.begin();
+ i != m_players.end(); i++)
+ {
+ Player *player = *i;
+ o<<"Player peer_id="<<player->peer_id<<std::endl;
+ }
+}
+