#include "log.h"
#include "profiler.h"
#include "scriptapi.h"
+#include "nodedef.h"
+#include "nodemetadata.h"
+#include "main.h" // For g_settings, g_profiler
+#include "gamedef.h"
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
ServerEnvironment
*/
-ServerEnvironment::ServerEnvironment(ServerMap *map, lua_State *L):
+ServerEnvironment::ServerEnvironment(ServerMap *map, lua_State *L,
+ IGameDef *gamedef):
m_map(map),
m_lua(L),
+ m_gamedef(gamedef),
m_random_spawn_timer(3),
m_send_recommended_timer(0),
m_game_time(0),
//infostream<<"Checking player file "<<path<<std::endl;
// Load player to see what is its name
- ServerRemotePlayer testplayer;
+ ServerRemotePlayer testplayer(this);
{
// Open file and deserialize
std::ifstream is(path.c_str(), std::ios_base::binary);
infostream<<"Checking player file "<<path<<std::endl;
// Load player to see what is its name
- ServerRemotePlayer testplayer;
+ ServerRemotePlayer testplayer(this);
{
// Open file and deserialize
std::ifstream is(path.c_str(), std::ios_base::binary);
if(player == NULL)
{
infostream<<"Is a new player"<<std::endl;
- player = new ServerRemotePlayer();
+ player = new ServerRemotePlayer(this);
newplayer = true;
}
MapNode n = block->getNodeNoEx(p);
if(n.getContent() == CONTENT_IGNORE)
continue;
- if(content_features(n).liquid_type != LIQUID_NONE)
+ if(m_gamedef->ndef()->get(n).liquid_type != LIQUID_NONE)
continue;
- if(content_features(n).walkable)
+ if(m_gamedef->ndef()->get(n).walkable)
{
last_node_walkable = true;
continue;
if(last_node_walkable)
{
// If block contains light information
- if(content_features(n).param_type == CPT_LIGHT)
+ if(m_gamedef->ndef()->get(n).param_type == CPT_LIGHT)
{
if(n.getLight(LIGHTBANK_DAY) <= 5)
{
activateObjects(block);
// Run node metadata
- bool changed = block->m_node_metadata.step((float)dtime_s);
+ bool changed = block->m_node_metadata->step((float)dtime_s);
if(changed)
{
MapEditEvent event;
#if 1
// Test something:
// Convert all mud under proper day lighting to grass
- if(n.getContent() == CONTENT_MUD)
+ if(n.getContent() == LEGN(m_gamedef->ndef(), "CONTENT_MUD"))
{
if(dtime_s > 300)
{
MapNode n_top = block->getNodeNoEx(p0+v3s16(0,1,0));
- if(content_features(n_top).air_equivalent &&
- n_top.getLight(LIGHTBANK_DAY) >= 13)
+ if(m_gamedef->ndef()->get(n_top).air_equivalent &&
+ n_top.getLight(LIGHTBANK_DAY, m_gamedef->ndef()) >= 13)
{
- n.setContent(CONTENT_GRASS);
+ n.setContent(LEGN(m_gamedef->ndef(), "CONTENT_GRASS"));
m_map->addNodeWithEvent(p, n);
}
}
v3s16 bottompos = floatToInt(playerpos + v3f(0,-BS/4,0), BS);
try{
MapNode n = m_map->getNode(bottompos);
- if(n.getContent() == CONTENT_GRASS)
+ if(n.getContent() == LEGN(m_gamedef->ndef(), "CONTENT_GRASS"))
{
- n.setContent(CONTENT_GRASS_FOOTSTEPS);
+ n.setContent(LEGN(m_gamedef->ndef(), "CONTENT_GRASS_FOOTSTEPS"));
m_map->setNode(bottompos, n);
}
}
block->setTimestampNoChangedFlag(m_game_time);
// Run node metadata
- bool changed = block->m_node_metadata.step(dtime);
+ bool changed = block->m_node_metadata->step(dtime);
if(changed)
{
MapEditEvent event;
Test something:
Convert mud under proper lighting to grass
*/
- if(n.getContent() == CONTENT_MUD)
+ if(n.getContent() == LEGN(m_gamedef->ndef(), "CONTENT_MUD"))
{
if(myrand()%20 == 0)
{
MapNode n_top = m_map->getNodeNoEx(p+v3s16(0,1,0));
- if(content_features(n_top).air_equivalent &&
- n_top.getLightBlend(getDayNightRatio()) >= 13)
+ if(m_gamedef->ndef()->get(n_top).air_equivalent &&
+ n_top.getLightBlend(getDayNightRatio(),
+ m_gamedef->ndef()) >= 13)
{
- n.setContent(CONTENT_GRASS);
+ n.setContent(LEGN(m_gamedef->ndef(), "CONTENT_GRASS"));
m_map->addNodeWithEvent(p, n);
}
}
/*
Convert grass into mud if under something else than air
*/
- if(n.getContent() == CONTENT_GRASS)
+ if(n.getContent() == LEGN(m_gamedef->ndef(), "CONTENT_GRASS"))
{
//if(myrand()%20 == 0)
{
MapNode n_top = m_map->getNodeNoEx(p+v3s16(0,1,0));
- if(content_features(n_top).air_equivalent == false)
+ if(m_gamedef->ndef()->get(n_top).air_equivalent == false)
{
- n.setContent(CONTENT_MUD);
+ n.setContent(LEGN(m_gamedef->ndef(), "CONTENT_MUD"));
m_map->addNodeWithEvent(p, n);
}
}
/*
Rats spawn around regular trees
*/
- if(n.getContent() == CONTENT_TREE ||
- n.getContent() == CONTENT_JUNGLETREE)
+ if(n.getContent() == LEGN(m_gamedef->ndef(), "CONTENT_TREE") ||
+ n.getContent() == LEGN(m_gamedef->ndef(), "CONTENT_JUNGLETREE"))
{
if(myrand()%200 == 0 && active_object_count_wider == 0)
{
0, myrand_range(-2, 2));
MapNode n1 = m_map->getNodeNoEx(p1);
MapNode n1b = m_map->getNodeNoEx(p1+v3s16(0,-1,0));
- if(n1b.getContent() == CONTENT_GRASS &&
+ if(n1b.getContent() == LEGN(m_gamedef->ndef(), "CONTENT_GRASS") &&
n1.getContent() == CONTENT_AIR)
{
v3f pos = intToFloat(p1, BS);
/*
Fun things spawn in caves and dungeons
*/
- if(n.getContent() == CONTENT_STONE ||
- n.getContent() == CONTENT_MOSSYCOBBLE)
+ if(n.getContent() == LEGN(m_gamedef->ndef(), "CONTENT_STONE") ||
+ n.getContent() == LEGN(m_gamedef->ndef(), "CONTENT_MOSSYCOBBLE"))
{
if(myrand()%200 == 0 && active_object_count_wider == 0)
{
v3s16 p1 = p + v3s16(0,1,0);
MapNode n1a = m_map->getNodeNoEx(p1+v3s16(0,0,0));
- if(n1a.getLightBlend(getDayNightRatio()) <= 3){
+ if(n1a.getLightBlend(getDayNightRatio(),
+ m_gamedef->ndef()) <= 3){
MapNode n1b = m_map->getNodeNoEx(p1+v3s16(0,1,0));
if(n1a.getContent() == CONTENT_AIR &&
n1b.getContent() == CONTENT_AIR)
/*
Make trees from saplings!
*/
- if(n.getContent() == CONTENT_SAPLING)
+ if(n.getContent() == LEGN(m_gamedef->ndef(), "CONTENT_SAPLING"))
{
if(myrand()%50 == 0)
{
v3s16 tree_blockp = getNodeBlockPos(tree_p);
vmanip.initialEmerge(tree_blockp - v3s16(1,1,1), tree_blockp + v3s16(1,1,1));
bool is_apple_tree = myrand()%4 == 0;
- mapgen::make_tree(vmanip, tree_p, is_apple_tree);
+ mapgen::make_tree(vmanip, tree_p, is_apple_tree,
+ m_gamedef->ndef());
vmanip.blitBackAll(&modified_blocks);
// update lighting
}
}
+ /*
+ Step script environment (run global on_step())
+ */
+ scriptapi_environment_step(m_lua, dtime);
+
/*
Step active objects
*/
// This helps the objects to send data at the same time
bool send_recommended = false;
m_send_recommended_timer += dtime;
- if(m_send_recommended_timer > 0.10)
+ if(m_send_recommended_timer > getSendRecommendedInterval())
{
- m_send_recommended_timer = 0;
+ m_send_recommended_timer -= getSendRecommendedInterval();
send_recommended = true;
}
<<" statically"<<std::endl;
}
- // Post-initialize object
- object->addedToEnvironment(object->getId());
- // Register reference in scripting api
+ // Register reference in scripting api (must be done before post-init)
scriptapi_add_object_reference(m_lua, object);
+ // Post-initialize object
+ object->addedToEnvironment();
return object->getId();
}
if(n){
StaticObject static_old = n->getValue();
+ float save_movem = obj->getMinimumSavedMovement();
+
if(static_old.data == staticdata_new &&
- (static_old.pos - objectpos).getLength() < 2*BS)
+ (static_old.pos - objectpos).getLength() < save_movem)
data_changed = false;
} else {
errorstream<<"ServerEnvironment::deactivateFarObjects(): "
<<PP(obj->m_static_block)<<std::endl;
}
}
+
+ bool shall_be_written = (!stays_in_same_block || data_changed);
// Delete old static object
if(obj->m_static_exists)
block->m_static_objects.remove(id);
obj->m_static_exists = false;
// Only mark block as modified if data changed considerably
- if(!stays_in_same_block || data_changed)
+ if(shall_be_written)
block->raiseModified(MOD_STATE_WRITE_NEEDED);
}
}
block->m_static_objects.insert(new_id, s_obj);
// Only mark block as modified if data changed considerably
- if(!stays_in_same_block || data_changed)
+ if(shall_be_written)
block->raiseModified(MOD_STATE_WRITE_NEEDED);
obj->m_static_exists = true;
ClientEnvironment
*/
-ClientEnvironment::ClientEnvironment(ClientMap *map, scene::ISceneManager *smgr):
+ClientEnvironment::ClientEnvironment(ClientMap *map, scene::ISceneManager *smgr,
+ ITextureSource *texturesource, IGameDef *gamedef):
m_map(map),
- m_smgr(smgr)
+ m_smgr(smgr),
+ m_texturesource(texturesource),
+ m_gamedef(gamedef)
{
assert(m_map);
assert(m_smgr);
u32 damage_per_second = 0;
damage_per_second = MYMAX(damage_per_second,
- content_features(n1).damage_per_second);
+ m_gamedef->ndef()->get(n1).damage_per_second);
damage_per_second = MYMAX(damage_per_second,
- content_features(n2).damage_per_second);
+ m_gamedef->ndef()->get(n2).damage_per_second);
damage_per_second = MYMAX(damage_per_second,
- content_features(n3).damage_per_second);
+ m_gamedef->ndef()->get(n3).damage_per_second);
if(damage_per_second != 0)
{
// Get node at head
v3s16 p = player->getLightPosition();
MapNode n = m_map->getNode(p);
- light = n.getLightBlend(getDayNightRatio());
+ light = n.getLightBlend(getDayNightRatio(), m_gamedef->ndef());
}
catch(InvalidPositionException &e) {}
player->updateLight(light);
v3s16 bottompos = floatToInt(playerpos + v3f(0,-BS/4,0), BS);
try{
MapNode n = m_map->getNode(bottompos);
- if(n.getContent() == CONTENT_GRASS)
+ if(n.getContent() == LEGN(m_gamedef->ndef(), "CONTENT_GRASS"))
{
- n.setContent(CONTENT_GRASS_FOOTSTEPS);
+ n.setContent(LEGN(m_gamedef->ndef(), "CONTENT_GRASS_FOOTSTEPS"));
m_map->setNode(bottompos, n);
// Update mesh on client
if(m_map->mapType() == MAPTYPE_CLIENT)
// Get node at head
v3s16 p = obj->getLightPosition();
MapNode n = m_map->getNode(p);
- light = n.getLightBlend(getDayNightRatio());
+ light = n.getLightBlend(getDayNightRatio(), m_gamedef->ndef());
}
catch(InvalidPositionException &e) {}
obj->updateLight(light);
infostream<<"ClientEnvironment::addActiveObject(): "
<<"added (id="<<object->getId()<<")"<<std::endl;
m_active_objects.insert(object->getId(), object);
- object->addToScene(m_smgr);
+ // TODO: Make g_texturesource non-global
+ object->addToScene(m_smgr, m_texturesource);
return object->getId();
}
void ClientEnvironment::addActiveObject(u16 id, u8 type,
const std::string &init_data)
{
- ClientActiveObject* obj = ClientActiveObject::create(type);
+ ClientActiveObject* obj = ClientActiveObject::create(type, m_gamedef);
if(obj == NULL)
{
infostream<<"ClientEnvironment::addActiveObject(): "