Remove liquid_finite and weather

This commit is contained in:
proller 2014-04-18 21:08:03 +04:00
parent 674be38fc2
commit 0279f32db7
18 changed files with 8 additions and 836 deletions

@ -714,9 +714,6 @@ function tabbuilder.handle_settings_buttons(fields)
if fields["cb_particles"] then if fields["cb_particles"] then
engine.setting_set("enable_particles", fields["cb_particles"]) engine.setting_set("enable_particles", fields["cb_particles"])
end end
if fields["cb_finite_liquid"] then
engine.setting_set("liquid_finite", fields["cb_finite_liquid"])
end
if fields["cb_bumpmapping"] then if fields["cb_bumpmapping"] then
engine.setting_set("enable_bumpmapping", fields["cb_bumpmapping"]) engine.setting_set("enable_bumpmapping", fields["cb_bumpmapping"])
end end
@ -997,9 +994,6 @@ function tabbuilder.tab_settings()
.. dump(engine.setting_getbool("preload_item_visuals")) .. "]".. .. dump(engine.setting_getbool("preload_item_visuals")) .. "]"..
"checkbox[1,2.5;cb_particles;".. fgettext("Enable Particles") .. ";" "checkbox[1,2.5;cb_particles;".. fgettext("Enable Particles") .. ";"
.. dump(engine.setting_getbool("enable_particles")) .. "]".. .. dump(engine.setting_getbool("enable_particles")) .. "]"..
"checkbox[1,3.0;cb_finite_liquid;".. fgettext("Finite Liquid") .. ";"
.. dump(engine.setting_getbool("liquid_finite")) .. "]"..
"checkbox[4.5,0;cb_mipmapping;".. fgettext("Mip-Mapping") .. ";" "checkbox[4.5,0;cb_mipmapping;".. fgettext("Mip-Mapping") .. ";"
.. dump(engine.setting_getbool("mip_map")) .. "]".. .. dump(engine.setting_getbool("mip_map")) .. "]"..
"checkbox[4.5,0.5;cb_anisotrophic;".. fgettext("Anisotropic Filtering") .. ";" "checkbox[4.5,0.5;cb_anisotrophic;".. fgettext("Anisotropic Filtering") .. ";"

@ -1443,10 +1443,6 @@ minetest.set_node_level(pos, level)
^ set level of leveled node, default level = 1, if totallevel > maxlevel returns rest (total-max). ^ set level of leveled node, default level = 1, if totallevel > maxlevel returns rest (total-max).
minetest.add_node_level(pos, level) minetest.add_node_level(pos, level)
^ increase level of leveled node by level, default level = 1, if totallevel > maxlevel returns rest (total-max). can be negative for decreasing ^ increase level of leveled node by level, default level = 1, if totallevel > maxlevel returns rest (total-max). can be negative for decreasing
minetest.get_heat(pos)
^ heat at pos
minetest.get_humidity(pos)
^ humidity at pos
Inventory: Inventory:
minetest.get_inventory(location) -> InvRef minetest.get_inventory(location) -> InvRef

@ -93,24 +93,10 @@
#enable_fog = true #enable_fog = true
# Enable a bit lower water surface; disable for speed (not quite optimized) # Enable a bit lower water surface; disable for speed (not quite optimized)
#new_style_water = false #new_style_water = false
# Constant volume liquids
#liquid_finite = false
# Max liquids processed per step # Max liquids processed per step
#liquid_loop_max = 10000 #liquid_loop_max = 10000
# Update liquids every .. recommend for finite: 0.2 # Update liquids every .. recommend for finite: 0.2
#liquid_update = 1.0 #liquid_update = 1.0
# Relax flowing blocks to source if level near max and N nearby
# source blocks, more realistic, but not true constant.
# values: 0,1,2,3,4 : 0 - disable, 1 - most aggresive
# (for finite liquids)
#liquid_relax = 2
# Optimization: faster cave flood (and not true constant)
# (for finite liquids)
#liquid_fast_flood = 1
# Underground water and lava springs, its infnity sources if liquid_finite enabled
#underground_springs = 1
# Enable weather (cold-hot, water freeze-melt). use only with liquid_finite=1
#weather = false
# Enable nice leaves; disable for speed # Enable nice leaves; disable for speed
#new_style_leaves = true #new_style_leaves = true
# Enable smooth lighting with simple ambient occlusion; # Enable smooth lighting with simple ambient occlusion;

@ -203,54 +203,3 @@ u8 BiomeDefManager::getBiomeIdByName(const char *name) {
return 0; return 0;
} }
///////////////////////////// Weather
s16 BiomeDefManager::calcBlockHeat(v3s16 p, u64 seed, float timeofday, float totaltime) {
//variant 1: full random
//f32 heat = NoisePerlin3D(np_heat, p.X, env->getGameTime()/100, p.Z, seed);
//variant 2: season change based on default heat map
const f32 offset = 20; // = np_heat->offset
const f32 scale = 20; // = np_heat->scale
const f32 range = 20;
f32 heat = NoisePerlin2D(np_heat, p.X, p.Z, seed); // 0..50..100
heat -= np_heat->offset; // -50..0..+50
// normalizing - todo REMOVE after fixed NoiseParams nparams_biome_def_heat = {50, 50, -> 20, 50,
if (np_heat->scale)
heat /= np_heat->scale / scale; // -20..0..+20
f32 seasonv = totaltime;
seasonv /= 86400 * g_settings->getS16("year_days"); // season change speed
seasonv += (f32)p.X / 3000; // you can walk to area with other season
seasonv = sin(seasonv * M_PI);
heat += (range * (heat < 0 ? 2 : 0.5)) * seasonv; // -60..0..30
heat += offset; // -40..0..50
heat += p.Y / -333; // upper=colder, lower=hotter, 3c per 1000
// daily change, hotter at sun +4, colder at night -4
heat += 8 * (sin(cycle_shift(timeofday, -0.25) * M_PI) - 0.5); //-44..20..54
return heat;
}
s16 BiomeDefManager::calcBlockHumidity(v3s16 p, u64 seed, float timeofday, float totaltime) {
f32 humidity = NoisePerlin2D(np_humidity, p.X, p.Z, seed);
f32 seasonv = totaltime;
seasonv /= 86400 * 2; // bad weather change speed (2 days)
seasonv += (f32)p.Z / 300;
humidity += 30 * sin(seasonv * M_PI);
humidity += -12 * (sin(cycle_shift(timeofday, -0.1) * M_PI) - 0.5);
humidity = rangelim(humidity, 0, 100);
return humidity;
}

@ -89,11 +89,5 @@ with this program; if not, write to the Free Software Foundation, Inc.,
// Maximum hit points of a player // Maximum hit points of a player
#define PLAYER_MAX_HP 20 #define PLAYER_MAX_HP 20
/*
Environmental condition constants
*/
#define HEAT_UNDEFINED (-0x7fff-1)
#define HUMIDITY_UNDEFINED (-0x7fff-1)
#endif #endif

@ -32,216 +32,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
class LiquidFlowABM : public ActiveBlockModifier {
private:
std::set<std::string> contents;
public:
LiquidFlowABM(ServerEnvironment *env, INodeDefManager *nodemgr) {
std::set<content_t> liquids;
nodemgr->getIds("group:liquid", liquids);
for(std::set<content_t>::const_iterator k = liquids.begin(); k != liquids.end(); k++)
contents.insert(nodemgr->get(*k).liquid_alternative_flowing);
}
virtual std::set<std::string> getTriggerContents() {
return contents;
}
virtual float getTriggerInterval()
{ return 10.0; }
virtual u32 getTriggerChance()
{ return 10; }
virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n) {
ServerMap *map = &env->getServerMap();
if (map->transforming_liquid_size() > 500)
return;
map->transforming_liquid_add(p);
}
};
class LiquidDropABM : public ActiveBlockModifier {
private:
std::set<std::string> contents;
public:
LiquidDropABM(ServerEnvironment *env, INodeDefManager *nodemgr) {
std::set<content_t> liquids;
nodemgr->getIds("group:liquid", liquids);
for(std::set<content_t>::const_iterator k = liquids.begin(); k != liquids.end(); k++)
contents.insert(nodemgr->get(*k).liquid_alternative_source);
}
virtual std::set<std::string> getTriggerContents()
{ return contents; }
virtual std::set<std::string> getRequiredNeighbors() {
std::set<std::string> neighbors;
neighbors.insert("air");
return neighbors;
}
virtual float getTriggerInterval()
{ return 20.0; }
virtual u32 getTriggerChance()
{ return 10; }
virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n) {
ServerMap *map = &env->getServerMap();
if (map->transforming_liquid_size() > 500)
return;
if ( map->getNodeNoEx(p - v3s16(0, 1, 0 )).getContent() != CONTENT_AIR // below
&& map->getNodeNoEx(p - v3s16(1, 0, 0 )).getContent() != CONTENT_AIR // right
&& map->getNodeNoEx(p - v3s16(-1, 0, 0 )).getContent() != CONTENT_AIR // left
&& map->getNodeNoEx(p - v3s16(0, 0, 1 )).getContent() != CONTENT_AIR // back
&& map->getNodeNoEx(p - v3s16(0, 0, -1)).getContent() != CONTENT_AIR // front
)
return;
map->transforming_liquid_add(p);
}
};
class LiquidFreeze : public ActiveBlockModifier {
public:
LiquidFreeze(ServerEnvironment *env, INodeDefManager *nodemgr) { }
virtual std::set<std::string> getTriggerContents() {
std::set<std::string> s;
s.insert("group:freezes");
return s;
}
virtual std::set<std::string> getRequiredNeighbors() {
std::set<std::string> s;
s.insert("air");
s.insert("group:melts");
return s;
}
virtual float getTriggerInterval()
{ return 10.0; }
virtual u32 getTriggerChance()
{ return 20; }
virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n) {
ServerMap *map = &env->getServerMap();
INodeDefManager *ndef = env->getGameDef()->ndef();
float heat = map->updateBlockHeat(env, p);
//heater = rare
content_t c = map->getNodeNoEx(p - v3s16(0, -1, 0 )).getContent(); // top
//more chance to freeze if air at top
if (heat <= -1 && (heat <= -50 || (myrand_range(-50, heat) <= (c == CONTENT_AIR ? -10 : -40)))) {
content_t c_self = n.getContent();
// making freeze not annoying, do not freeze random blocks in center of ocean
// todo: any block not water (dont freeze _source near _flowing)
bool allow = heat < -40;
// todo: make for(...)
if (!allow) {
c = map->getNodeNoEx(p - v3s16(0, 1, 0 )).getContent(); // below
if (c == CONTENT_AIR || c == CONTENT_IGNORE)
return; // do not freeze when falling
if (c != c_self && c != CONTENT_IGNORE) allow = 1;
if (!allow) {
c = map->getNodeNoEx(p - v3s16(1, 0, 0 )).getContent(); // right
if (c != c_self && c != CONTENT_IGNORE) allow = 1;
if (!allow) {
c = map->getNodeNoEx(p - v3s16(-1, 0, 0 )).getContent(); // left
if (c != c_self && c != CONTENT_IGNORE) allow = 1;
if (!allow) {
c = map->getNodeNoEx(p - v3s16(0, 0, 1 )).getContent(); // back
if (c != c_self && c != CONTENT_IGNORE) allow = 1;
if (!allow) {
c = map->getNodeNoEx(p - v3s16(0, 0, -1)).getContent(); // front
if (c != c_self && c != CONTENT_IGNORE) allow = 1;
}
}
}
}
}
if (allow) {
n.freezeMelt(ndef);
map->addNodeWithEvent(p, n);
}
}
}
};
class LiquidMeltWeather : public ActiveBlockModifier {
public:
LiquidMeltWeather(ServerEnvironment *env, INodeDefManager *nodemgr) { }
virtual std::set<std::string> getTriggerContents() {
std::set<std::string> s;
s.insert("group:melts");
return s;
}
virtual std::set<std::string> getRequiredNeighbors() {
std::set<std::string> s;
s.insert("air");
s.insert("group:freezes");
return s;
}
virtual float getTriggerInterval()
{ return 10.0; }
virtual u32 getTriggerChance()
{ return 20; }
virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n) {
ServerMap *map = &env->getServerMap();
INodeDefManager *ndef = env->getGameDef()->ndef();
float heat = map->updateBlockHeat(env, p);
content_t c = map->getNodeNoEx(p - v3s16(0, -1, 0 )).getContent(); // top
if (heat >= 1 && (heat >= 40 || ((myrand_range(heat, 40)) >= (c == CONTENT_AIR ? 10 : 20)))) {
n.freezeMelt(ndef);
map->addNodeWithEvent(p, n);
env->getScriptIface()->node_falling_update(p);
}
}
};
class LiquidMeltHot : public ActiveBlockModifier {
public:
LiquidMeltHot(ServerEnvironment *env, INodeDefManager *nodemgr) { }
virtual std::set<std::string> getTriggerContents() {
std::set<std::string> s;
s.insert("group:melts");
return s;
}
virtual std::set<std::string> getRequiredNeighbors() {
std::set<std::string> s;
s.insert("group:igniter");
s.insert("group:hot");
return s;
}
virtual float getTriggerInterval()
{ return 2.0; }
virtual u32 getTriggerChance()
{ return 4; }
virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n) {
ServerMap *map = &env->getServerMap();
INodeDefManager *ndef = env->getGameDef()->ndef();
n.freezeMelt(ndef);
map->addNodeWithEvent(p, n);
env->getScriptIface()->node_falling_update(p);
}
};
/* too buggy, later via liquid flow code
class LiquidMeltAround : public LiquidMeltHot {
public:
LiquidMeltAround(ServerEnvironment *env, INodeDefManager *nodemgr)
: LiquidMeltHot(env, nodemgr) { }
virtual std::set<std::string> getRequiredNeighbors() {
std::set<std::string> s;
s.insert("group:melt_around");
return s;
}
virtual float getTriggerInterval()
{ return 40.0; }
virtual u32 getTriggerChance()
{ return 60; }
};
*/
void add_legacy_abms(ServerEnvironment *env, INodeDefManager *nodedef) { void add_legacy_abms(ServerEnvironment *env, INodeDefManager *nodedef) {
if (g_settings->getBool("liquid_finite")) {
env->addActiveBlockModifier(new LiquidFlowABM(env, nodedef));
env->addActiveBlockModifier(new LiquidDropABM(env, nodedef));
env->addActiveBlockModifier(new LiquidMeltHot(env, nodedef));
//env->addActiveBlockModifier(new LiquidMeltAround(env, nodedef));
if (env->m_use_weather) {
env->addActiveBlockModifier(new LiquidFreeze(env, nodedef));
env->addActiveBlockModifier(new LiquidMeltWeather(env, nodedef));
}
}
} }

@ -244,13 +244,8 @@ void set_default_settings(Settings *settings)
settings->setDefault("movement_gravity", "9.81"); settings->setDefault("movement_gravity", "9.81");
//liquid stuff //liquid stuff
settings->setDefault("liquid_finite", "false");
settings->setDefault("liquid_loop_max", "10000"); settings->setDefault("liquid_loop_max", "10000");
settings->setDefault("liquid_update", "1.0"); settings->setDefault("liquid_update", "1.0");
settings->setDefault("liquid_relax", "2");
settings->setDefault("liquid_fast_flood", "1");
settings->setDefault("underground_springs", "1");
settings->setDefault("weather", "false");
//mapgen stuff //mapgen stuff
settings->setDefault("mg_name", "v6"); settings->setDefault("mg_name", "v6");

@ -321,7 +321,6 @@ ServerEnvironment::ServerEnvironment(ServerMap *map,
m_recommended_send_interval(0.1), m_recommended_send_interval(0.1),
m_max_lag_estimate(0.1) m_max_lag_estimate(0.1)
{ {
m_use_weather = g_settings->getBool("weather");
} }
ServerEnvironment::~ServerEnvironment() ServerEnvironment::~ServerEnvironment()

@ -314,9 +314,6 @@ public:
void reportMaxLagEstimate(float f) { m_max_lag_estimate = f; } void reportMaxLagEstimate(float f) { m_max_lag_estimate = f; }
float getMaxLagEstimate() { return m_max_lag_estimate; } float getMaxLagEstimate() { return m_max_lag_estimate; }
// is weather active in this environment?
bool m_use_weather;
std::set<v3s16>* getForceloadedBlocks() { return &m_active_blocks.m_forceloaded_list; }; std::set<v3s16>* getForceloadedBlocks() { return &m_active_blocks.m_forceloaded_list; };
private: private:

@ -1642,8 +1642,6 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
Hud hud(driver, smgr, guienv, font, text_height, Hud hud(driver, smgr, guienv, font, text_height,
gamedef, player, &local_inventory); gamedef, player, &local_inventory);
bool use_weather = g_settings->getBool("weather");
core::stringw str = L"Minetest ["; core::stringw str = L"Minetest [";
str += driver->getName(); str += driver->getName();
str += "]"; str += "]";
@ -3111,8 +3109,6 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
fog_range = 100000*BS; fog_range = 100000*BS;
else { else {
fog_range = draw_control.wanted_range*BS + 0.0*MAP_BLOCKSIZE*BS; fog_range = draw_control.wanted_range*BS + 0.0*MAP_BLOCKSIZE*BS;
if(use_weather)
fog_range *= (1.5 - 1.4*(float)client.getEnv().getClientMap().getHumidity(pos_i)/100);
fog_range = MYMIN(fog_range, (draw_control.farthest_drawn+20)*BS); fog_range = MYMIN(fog_range, (draw_control.farthest_drawn+20)*BS);
fog_range *= 0.9; fog_range *= 0.9;
} }
@ -3262,9 +3258,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
<<", "<<(player_position.Y/BS) <<", "<<(player_position.Y/BS)
<<", "<<(player_position.Z/BS) <<", "<<(player_position.Z/BS)
<<") (yaw="<<(wrapDegrees_0_360(camera_yaw)) <<") (yaw="<<(wrapDegrees_0_360(camera_yaw))
<<") (t="<<client.getEnv().getClientMap().getHeat(pos_i) <<") (seed = "<<((u64)client.getMapSeed())
<<"C, h="<<client.getEnv().getClientMap().getHumidity(pos_i)
<<"%) (seed = "<<((u64)client.getMapSeed())
<<")"; <<")";
guitext2->setText(narrow_to_wide(os.str()).c_str()); guitext2->setText(narrow_to_wide(os.str()).c_str());
guitext2->setVisible(true); guitext2->setVisible(true);

@ -1100,7 +1100,6 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
/* /*
Add neighboring liquid nodes and the node itself if it is Add neighboring liquid nodes and the node itself if it is
liquid (=water node was added) to transform queue. liquid (=water node was added) to transform queue.
note: todo: for liquid_finite enough to add only self node
*/ */
v3s16 dirs[7] = { v3s16 dirs[7] = {
v3s16(0,0,0), // self v3s16(0,0,0), // self
@ -1292,7 +1291,6 @@ void Map::removeNodeAndUpdate(v3s16 p,
/* /*
Add neighboring liquid nodes and this node to transform queue. Add neighboring liquid nodes and this node to transform queue.
(it's vital for the node itself to get updated last.) (it's vital for the node itself to get updated last.)
note: todo: for liquid_finite enough to add only self node
*/ */
v3s16 dirs[7] = { v3s16 dirs[7] = {
v3s16(0,0,1), // back v3s16(0,0,1), // back
@ -1619,7 +1617,6 @@ struct NodeNeighbor {
NeighborType t; NeighborType t;
v3s16 p; v3s16 p;
bool l; //can liquid bool l; //can liquid
bool i; //infinity
}; };
void Map::transforming_liquid_add(v3s16 p) { void Map::transforming_liquid_add(v3s16 p) {
@ -1630,383 +1627,8 @@ s32 Map::transforming_liquid_size() {
return m_transforming_liquid.size(); return m_transforming_liquid.size();
} }
const v3s16 g_7dirs[7] =
{
// +right, +top, +back
v3s16( 0,-1, 0), // bottom
v3s16( 0, 0, 0), // self
v3s16( 0, 0, 1), // back
v3s16( 0, 0,-1), // front
v3s16( 1, 0, 0), // right
v3s16(-1, 0, 0), // left
v3s16( 0, 1, 0) // top
};
#define D_BOTTOM 0
#define D_TOP 6
#define D_SELF 1
void Map::transformLiquidsFinite(std::map<v3s16, MapBlock*> & modified_blocks)
{
INodeDefManager *nodemgr = m_gamedef->ndef();
DSTACK(__FUNCTION_NAME);
//TimeTaker timer("transformLiquids()");
u32 loopcount = 0;
u32 initial_size = m_transforming_liquid.size();
u8 relax = g_settings->getS16("liquid_relax");
bool fast_flood = g_settings->getS16("liquid_fast_flood");
int water_level = g_settings->getS16("water_level");
// list of nodes that due to viscosity have not reached their max level height
UniqueQueue<v3s16> must_reflow, must_reflow_second;
// List of MapBlocks that will require a lighting update (due to lava)
std::map<v3s16, MapBlock*> lighting_modified_blocks;
u16 loop_max = g_settings->getU16("liquid_loop_max");
//if (m_transforming_liquid.size() > 0) errorstream << "Liquid queue size="<<m_transforming_liquid.size()<<std::endl;
while (m_transforming_liquid.size() > 0)
{
// This should be done here so that it is done when continue is used
if (loopcount >= initial_size || loopcount >= loop_max)
break;
loopcount++;
/*
Get a queued transforming liquid node
*/
v3s16 p0 = m_transforming_liquid.pop_front();
u16 total_level = 0;
// surrounding flowing liquid nodes
NodeNeighbor neighbors[7];
// current level of every block
s8 liquid_levels[7] = {-1, -1, -1, -1, -1, -1, -1};
// target levels
s8 liquid_levels_want[7] = {-1, -1, -1, -1, -1, -1, -1};
s8 can_liquid_same_level = 0;
content_t liquid_kind = CONTENT_IGNORE;
content_t liquid_kind_flowing = CONTENT_IGNORE;
/*
Collect information about the environment
*/
const v3s16 *dirs = g_7dirs;
for (u16 i = 0; i < 7; i++) {
NeighborType nt = NEIGHBOR_SAME_LEVEL;
switch (i) {
case D_TOP:
nt = NEIGHBOR_UPPER;
break;
case D_BOTTOM:
nt = NEIGHBOR_LOWER;
break;
}
v3s16 npos = p0 + dirs[i];
neighbors[i].n = getNodeNoEx(npos);
neighbors[i].t = nt;
neighbors[i].p = npos;
neighbors[i].l = 0;
neighbors[i].i = 0;
NodeNeighbor & nb = neighbors[i];
switch (nodemgr->get(nb.n.getContent()).liquid_type) {
case LIQUID_NONE:
if (nb.n.getContent() == CONTENT_AIR) {
liquid_levels[i] = 0;
nb.l = 1;
}
break;
case LIQUID_SOURCE:
// if this node is not (yet) of a liquid type,
// choose the first liquid type we encounter
if (liquid_kind_flowing == CONTENT_IGNORE)
liquid_kind_flowing = nodemgr->getId(
nodemgr->get(nb.n).liquid_alternative_flowing);
if (liquid_kind == CONTENT_IGNORE)
liquid_kind = nb.n.getContent();
if (nb.n.getContent() == liquid_kind) {
liquid_levels[i] = nb.n.getLevel(nodemgr); //LIQUID_LEVEL_SOURCE;
nb.l = 1;
nb.i = (nb.n.param2 & LIQUID_INFINITY_MASK);
}
break;
case LIQUID_FLOWING:
// if this node is not (yet) of a liquid type,
// choose the first liquid type we encounter
if (liquid_kind_flowing == CONTENT_IGNORE)
liquid_kind_flowing = nb.n.getContent();
if (liquid_kind == CONTENT_IGNORE)
liquid_kind = nodemgr->getId(
nodemgr->get(nb.n).liquid_alternative_source);
if (nb.n.getContent() == liquid_kind_flowing) {
liquid_levels[i] = nb.n.getLevel(nodemgr); //(nb.n.param2 & LIQUID_LEVEL_MASK);
nb.l = 1;
}
break;
}
if (nb.l && nb.t == NEIGHBOR_SAME_LEVEL)
++can_liquid_same_level;
if (liquid_levels[i] > 0)
total_level += liquid_levels[i];
/*
infostream << "get node i=" <<(int)i<<" " << PP(npos) << " c="
<< nb.n.getContent() <<" p0="<< (int)nb.n.param0 <<" p1="
<< (int)nb.n.param1 <<" p2="<< (int)nb.n.param2 << " lt="
<< nodemgr->get(nb.n.getContent()).liquid_type
//<< " lk=" << liquid_kind << " lkf=" << liquid_kind_flowing
<< " l="<< nb.l << " inf="<< nb.i << " nlevel=" << (int)liquid_levels[i]
<< " tlevel=" << (int)total_level << " cansame="
<< (int)can_liquid_same_level << std::endl;
*/
}
if (liquid_kind == CONTENT_IGNORE ||
!neighbors[D_SELF].l ||
total_level <= 0)
continue;
// fill bottom block
if (neighbors[D_BOTTOM].l) {
liquid_levels_want[D_BOTTOM] = total_level > LIQUID_LEVEL_SOURCE ?
LIQUID_LEVEL_SOURCE : total_level;
total_level -= liquid_levels_want[D_BOTTOM];
}
//relax up
if (relax && ((p0.Y == water_level) || (fast_flood && p0.Y <= water_level)) && liquid_levels[D_TOP] == 0 &&
liquid_levels[D_BOTTOM] == LIQUID_LEVEL_SOURCE &&
total_level >= LIQUID_LEVEL_SOURCE * can_liquid_same_level-
(can_liquid_same_level - relax) &&
can_liquid_same_level >= relax + 1) {
total_level = LIQUID_LEVEL_SOURCE * can_liquid_same_level;
}
// prevent lakes in air above unloaded blocks
if (liquid_levels[D_TOP] == 0 && (p0.Y > water_level) && neighbors[D_BOTTOM].n.getContent() == CONTENT_IGNORE && !(loopcount % 3)) {
--total_level;
}
// calculate self level 5 blocks
u8 want_level =
total_level >= LIQUID_LEVEL_SOURCE * can_liquid_same_level
? LIQUID_LEVEL_SOURCE
: total_level / can_liquid_same_level;
total_level -= want_level * can_liquid_same_level;
//relax down
if (relax && p0.Y == water_level + 1 && liquid_levels[D_TOP] == 0 &&
liquid_levels[D_BOTTOM] == LIQUID_LEVEL_SOURCE && want_level == 0 &&
total_level <= (can_liquid_same_level - relax) &&
can_liquid_same_level >= relax + 1) {
total_level = 0;
}
for (u16 ii = D_SELF; ii < D_TOP; ++ii) { // fill only same level
if (!neighbors[ii].l)
continue;
liquid_levels_want[ii] = want_level;
if (liquid_levels_want[ii] < LIQUID_LEVEL_SOURCE && total_level > 0) {
if (loopcount % 3 || liquid_levels[ii] <= 0){
if (liquid_levels[ii] > liquid_levels_want[ii]) {
++liquid_levels_want[ii];
--total_level;
}
} else if (neighbors[ii].l > 0){
++liquid_levels_want[ii];
--total_level;
}
}
}
for (u16 ii = 0; ii < 7; ++ii) {
if (total_level < 1) break;
if (liquid_levels_want[ii] >= 0 &&
liquid_levels_want[ii] < LIQUID_LEVEL_SOURCE) {
++liquid_levels_want[ii];
--total_level;
}
}
// fill top block if can
if (neighbors[D_TOP].l) {
liquid_levels_want[D_TOP] = total_level > LIQUID_LEVEL_SOURCE ?
LIQUID_LEVEL_SOURCE : total_level;
total_level -= liquid_levels_want[D_TOP];
}
for (u16 ii = 0; ii < 7; ii++) // infinity and cave flood optimization
if ( neighbors[ii].i ||
(liquid_levels_want[ii] >= 0 &&
(fast_flood && p0.Y < water_level &&
(initial_size >= 1000
&& ii != D_TOP
&& want_level >= LIQUID_LEVEL_SOURCE/4
&& can_liquid_same_level >= 5
&& liquid_levels[D_TOP] >= LIQUID_LEVEL_SOURCE))))
liquid_levels_want[ii] = LIQUID_LEVEL_SOURCE;
/*
if (total_level > 0) //|| flowed != volume)
infostream <<" AFTER level=" << (int)total_level
//<< " flowed="<<flowed<< " volume=" << volume
<< " wantsame="<<(int)want_level<< " top="
<< (int)liquid_levels_want[D_TOP]<< " topwas="
<< (int)liquid_levels[D_TOP]<< " bot="
<< (int)liquid_levels_want[D_BOTTOM]<<std::endl;
*/
//u8 changed = 0;
for (u16 i = 0; i < 7; i++) {
if (liquid_levels_want[i] < 0 || !neighbors[i].l)
continue;
MapNode & n0 = neighbors[i].n;
p0 = neighbors[i].p;
/*
decide on the type (and possibly level) of the current node
*/
content_t new_node_content;
s8 new_node_level = -1;
u8 viscosity = nodemgr->get(liquid_kind).liquid_viscosity;
if (viscosity > 1 && liquid_levels_want[i] != liquid_levels[i]) {
// amount to gain, limited by viscosity
// must be at least 1 in absolute value
s8 level_inc = liquid_levels_want[i] - liquid_levels[i];
if (level_inc < -viscosity || level_inc > viscosity)
new_node_level = liquid_levels[i] + level_inc/viscosity;
else if (level_inc < 0)
new_node_level = liquid_levels[i] - 1;
else if (level_inc > 0)
new_node_level = liquid_levels[i] + 1;
} else {
new_node_level = liquid_levels_want[i];
}
if (new_node_level >= LIQUID_LEVEL_SOURCE)
new_node_content = liquid_kind;
else if (new_node_level > 0)
new_node_content = liquid_kind_flowing;
else
new_node_content = CONTENT_AIR;
// last level must flow down on stairs
if (liquid_levels_want[i] != liquid_levels[i] &&
liquid_levels[D_TOP] <= 0 && !neighbors[D_BOTTOM].l &&
new_node_level >= 1 && new_node_level <= 2) {
for (u16 ii = D_SELF + 1; ii < D_TOP; ++ii) { // only same level
if (neighbors[ii].l)
must_reflow_second.push_back(p0 + dirs[ii]);
}
}
/*
check if anything has changed.
if not, just continue with the next node.
*/
/*
if (
new_node_content == n0.getContent()
&& (nodemgr->get(n0.getContent()).liquid_type != LIQUID_FLOWING ||
(n0.getLevel(nodemgr) == (u8)new_node_level
//&& ((n0.param2 & LIQUID_FLOW_DOWN_MASK) ==
//LIQUID_FLOW_DOWN_MASK) == flowing_down
))
&&
(nodemgr->get(n0.getContent()).liquid_type != LIQUID_SOURCE ||
(((n0.param2 & LIQUID_INFINITY_MASK) ==
LIQUID_INFINITY_MASK) == neighbors[i].i
))
)*/
if (liquid_levels[i] == new_node_level)
{
continue;
}
//++changed;
/*
update the current node
*/
/*
if (nodemgr->get(new_node_content).liquid_type == LIQUID_FLOWING) {
// set level to last 3 bits, flowing down bit to 4th bit
n0.param2 = (new_node_level & LIQUID_LEVEL_MASK);
} else if (nodemgr->get(new_node_content).liquid_type == LIQUID_SOURCE) {
//n0.param2 = ~(LIQUID_LEVEL_MASK | LIQUID_FLOW_DOWN_MASK);
n0.param2 = (neighbors[i].i ? LIQUID_INFINITY_MASK : 0x00);
}
*/
/*
infostream << "set node i=" <<(int)i<<" "<< PP(p0)<< " nc="
<<new_node_content<< " p2="<<(int)n0.param2<< " nl="
<<(int)new_node_level<<std::endl;
*/
n0.setContent(liquid_kind_flowing);
n0.setLevel(nodemgr, new_node_level);
// Find out whether there is a suspect for this action
std::string suspect;
if(m_gamedef->rollback()){
suspect = m_gamedef->rollback()->getSuspect(p0, 83, 1);
}
if(!suspect.empty()){
// Blame suspect
RollbackScopeActor rollback_scope(m_gamedef->rollback(), suspect, true);
// Get old node for rollback
RollbackNode rollback_oldnode(this, p0, m_gamedef);
// Set node
setNode(p0, n0);
// Report
RollbackNode rollback_newnode(this, p0, m_gamedef);
RollbackAction action;
action.setSetNode(p0, rollback_oldnode, rollback_newnode);
m_gamedef->rollback()->reportAction(action);
} else {
// Set node
setNode(p0, n0);
}
v3s16 blockpos = getNodeBlockPos(p0);
MapBlock *block = getBlockNoCreateNoEx(blockpos);
if(block != NULL) {
modified_blocks[blockpos] = block;
// If node emits light, MapBlock requires lighting update
if(nodemgr->get(n0).light_source != 0)
lighting_modified_blocks[block->getPos()] = block;
}
must_reflow.push_back(neighbors[i].p);
}
/* //for better relax only same level
if (changed) for (u16 ii = D_SELF + 1; ii < D_TOP; ++ii) {
if (!neighbors[ii].l) continue;
must_reflow.push_back(p0 + dirs[ii]);
}*/
}
/*
if (loopcount)
infostream<<"Map::transformLiquids(): loopcount="<<loopcount
<<" reflow="<<must_reflow.size()
<<" queue="<< m_transforming_liquid.size()<<std::endl;
*/
while (must_reflow.size() > 0)
m_transforming_liquid.push_back(must_reflow.pop_front());
while (must_reflow_second.size() > 0)
m_transforming_liquid.push_back(must_reflow_second.pop_front());
updateLighting(lighting_modified_blocks, modified_blocks);
}
void Map::transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks) void Map::transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks)
{ {
if (g_settings->getBool("liquid_finite"))
return Map::transformLiquidsFinite(modified_blocks);
INodeDefManager *nodemgr = m_gamedef->ndef(); INodeDefManager *nodemgr = m_gamedef->ndef();
DSTACK(__FUNCTION_NAME); DSTACK(__FUNCTION_NAME);
@ -2385,26 +2007,6 @@ void Map::removeNodeTimer(v3s16 p)
block->m_node_timers.remove(p_rel); block->m_node_timers.remove(p_rel);
} }
s16 Map::getHeat(v3s16 p)
{
MapBlock *block = getBlockNoCreateNoEx(getNodeBlockPos(p));
if(block != NULL) {
return block->heat;
}
//errorstream << "No heat for " << p.X<<"," << p.Z << std::endl;
return 0;
}
s16 Map::getHumidity(v3s16 p)
{
MapBlock *block = getBlockNoCreateNoEx(getNodeBlockPos(p));
if(block != NULL) {
return block->humidity;
}
//errorstream << "No humidity for " << p.X<<"," << p.Z << std::endl;
return 0;
}
/* /*
ServerMap ServerMap
*/ */
@ -2818,29 +2420,6 @@ MapBlock* ServerMap::finishBlockMake(BlockMakeData *data,
<<","<<blockpos_requested.Y<<"," <<","<<blockpos_requested.Y<<","
<<blockpos_requested.Z<<")"<<std::endl;*/ <<blockpos_requested.Z<<")"<<std::endl;*/
/*
Update weather data in blocks
*/
ServerEnvironment *senv = &((Server *)m_gamedef)->getEnv();
for(s16 x=blockpos_min.X-extra_borders.X;
x<=blockpos_max.X+extra_borders.X; x++)
for(s16 z=blockpos_min.Z-extra_borders.Z;
z<=blockpos_max.Z+extra_borders.Z; z++)
for(s16 y=blockpos_min.Y-extra_borders.Y;
y<=blockpos_max.Y+extra_borders.Y; y++)
{
v3s16 p(x, y, z);
MapBlock *block = getBlockNoCreateNoEx(p);
block->heat_last_update = 0;
block->humidity_last_update = 0;
if (senv->m_use_weather) {
updateBlockHeat(senv, p * MAP_BLOCKSIZE, block);
updateBlockHumidity(senv, p * MAP_BLOCKSIZE, block);
} else {
block->heat = HEAT_UNDEFINED;
block->humidity = HUMIDITY_UNDEFINED;
}
}
#if 0 #if 0
if(enable_mapgen_debug_info) if(enable_mapgen_debug_info)
@ -3176,18 +2755,6 @@ MapBlock *ServerMap::getBlockOrEmerge(v3s16 p3d)
void ServerMap::prepareBlock(MapBlock *block) { void ServerMap::prepareBlock(MapBlock *block) {
ServerEnvironment *senv = &((Server *)m_gamedef)->getEnv(); ServerEnvironment *senv = &((Server *)m_gamedef)->getEnv();
// Calculate weather conditions
block->heat_last_update = 0;
block->humidity_last_update = 0;
if (senv->m_use_weather) {
v3s16 p = block->getPos() * MAP_BLOCKSIZE;
updateBlockHeat(senv, p, block);
updateBlockHumidity(senv, p, block);
} else {
block->heat = HEAT_UNDEFINED;
block->humidity = HUMIDITY_UNDEFINED;
}
} }
s16 ServerMap::findGroundLevel(v2s16 p2d) s16 ServerMap::findGroundLevel(v2s16 p2d)
@ -3917,48 +3484,6 @@ void ServerMap::PrintInfo(std::ostream &out)
out<<"ServerMap: "; out<<"ServerMap: ";
} }
s16 ServerMap::updateBlockHeat(ServerEnvironment *env, v3s16 p, MapBlock *block)
{
u32 gametime = env->getGameTime();
if (block) {
if (gametime - block->heat_last_update < 10)
return block->heat;
} else {
block = getBlockNoCreateNoEx(getNodeBlockPos(p));
}
f32 heat = m_emerge->biomedef->calcBlockHeat(p, getSeed(),
env->getTimeOfDayF(), gametime * env->getTimeOfDaySpeed());
if(block) {
block->heat = heat;
block->heat_last_update = gametime;
}
return heat;
}
s16 ServerMap::updateBlockHumidity(ServerEnvironment *env, v3s16 p, MapBlock *block)
{
u32 gametime = env->getGameTime();
if (block) {
if (gametime - block->humidity_last_update < 10)
return block->humidity;
} else {
block = getBlockNoCreateNoEx(getNodeBlockPos(p));
}
f32 humidity = m_emerge->biomedef->calcBlockHumidity(p, getSeed(),
env->getTimeOfDayF(), gametime * env->getTimeOfDaySpeed());
if(block) {
block->humidity = humidity;
block->humidity_last_update = gametime;
}
return humidity;
}
/* /*
MapVoxelManipulator MapVoxelManipulator
*/ */

@ -304,7 +304,6 @@ public:
virtual void PrintInfo(std::ostream &out); virtual void PrintInfo(std::ostream &out);
void transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks); void transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks);
void transformLiquidsFinite(std::map<v3s16, MapBlock*> & modified_blocks);
/* /*
Node metadata Node metadata
@ -351,9 +350,6 @@ public:
void transforming_liquid_add(v3s16 p); void transforming_liquid_add(v3s16 p);
s32 transforming_liquid_size(); s32 transforming_liquid_size();
virtual s16 getHeat(v3s16 p);
virtual s16 getHumidity(v3s16 p);
protected: protected:
friend class LuaVoxelManip; friend class LuaVoxelManip;
@ -504,9 +500,6 @@ public:
u64 getSeed(); u64 getSeed();
s16 getWaterLevel(); s16 getWaterLevel();
virtual s16 updateBlockHeat(ServerEnvironment *env, v3s16 p, MapBlock *block = NULL);
virtual s16 updateBlockHumidity(ServerEnvironment *env, v3s16 p, MapBlock *block = NULL);
private: private:
// Emerge manager // Emerge manager
EmergeManager *m_emerge; EmergeManager *m_emerge;

@ -43,10 +43,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/ */
MapBlock::MapBlock(Map *parent, v3s16 pos, IGameDef *gamedef, bool dummy): MapBlock::MapBlock(Map *parent, v3s16 pos, IGameDef *gamedef, bool dummy):
heat(0),
humidity(0),
heat_last_update(0),
humidity_last_update(0),
m_parent(parent), m_parent(parent),
m_pos(pos), m_pos(pos),
m_gamedef(gamedef), m_gamedef(gamedef),
@ -647,8 +643,8 @@ void MapBlock::serializeNetworkSpecific(std::ostream &os, u16 net_proto_version)
if(net_proto_version >= 21){ if(net_proto_version >= 21){
int version = 1; int version = 1;
writeU8(os, version); writeU8(os, version);
writeF1000(os, heat); writeF1000(os, 0); // deprecated heat
writeF1000(os, humidity); writeF1000(os, 0); // deprecated humidity
} }
} }
@ -764,8 +760,8 @@ void MapBlock::deSerializeNetworkSpecific(std::istream &is)
//if(version != 1) //if(version != 1)
// throw SerializationError("unsupported MapBlock version"); // throw SerializationError("unsupported MapBlock version");
if(version >= 1) { if(version >= 1) {
heat = readF1000(is); readF1000(is); // deprecated heat
humidity = readF1000(is); readF1000(is); // deprecated humidity
} }
} }
catch(SerializationError &e) catch(SerializationError &e)

@ -513,11 +513,6 @@ public:
NodeMetadataList m_node_metadata; NodeMetadataList m_node_metadata;
NodeTimerList m_node_timers; NodeTimerList m_node_timers;
StaticObjectList m_static_objects; StaticObjectList m_static_objects;
s16 heat;
s16 humidity;
u32 heat_last_update;
u32 humidity_last_update;
private: private:
/* /*

@ -979,8 +979,6 @@ void Mapgen::updateHeightmap(v3s16 nmin, v3s16 nmax) {
void Mapgen::updateLiquid(UniqueQueue<v3s16> *trans_liquid, v3s16 nmin, v3s16 nmax) { void Mapgen::updateLiquid(UniqueQueue<v3s16> *trans_liquid, v3s16 nmin, v3s16 nmax) {
bool isliquid, wasliquid, rare; bool isliquid, wasliquid, rare;
v3s16 em = vm->m_area.getExtent(); v3s16 em = vm->m_area.getExtent();
rare = g_settings->getBool("liquid_finite");
int rarecnt = 0;
for (s16 z = nmin.Z; z <= nmax.Z; z++) { for (s16 z = nmin.Z; z <= nmax.Z; z++) {
for (s16 x = nmin.X; x <= nmax.X; x++) { for (s16 x = nmin.X; x <= nmax.X; x++) {
@ -990,8 +988,8 @@ void Mapgen::updateLiquid(UniqueQueue<v3s16> *trans_liquid, v3s16 nmin, v3s16 nm
for (s16 y = nmax.Y; y >= nmin.Y; y--) { for (s16 y = nmax.Y; y >= nmin.Y; y--) {
isliquid = ndef->get(vm->m_data[i]).isLiquid(); isliquid = ndef->get(vm->m_data[i]).isLiquid();
// there was a change between liquid and nonliquid, add to queue. no need to add every with liquid_finite // there was a change between liquid and nonliquid, add to queue.
if (isliquid != wasliquid && (!rare || !(rarecnt++ % 36))) if (isliquid != wasliquid)
trans_liquid->push_back(v3s16(x, y, z)); trans_liquid->push_back(v3s16(x, y, z));
wasliquid = isliquid; wasliquid = isliquid;

@ -765,7 +765,6 @@ int ModApiEnvMod::l_spawn_tree(lua_State *L)
return 1; return 1;
} }
// minetest.transforming_liquid_add(pos) // minetest.transforming_liquid_add(pos)
int ModApiEnvMod::l_transforming_liquid_add(lua_State *L) int ModApiEnvMod::l_transforming_liquid_add(lua_State *L)
{ {
@ -776,28 +775,6 @@ int ModApiEnvMod::l_transforming_liquid_add(lua_State *L)
return 1; return 1;
} }
// minetest.get_heat(pos)
// pos = {x=num, y=num, z=num}
int ModApiEnvMod::l_get_heat(lua_State *L)
{
GET_ENV_PTR;
v3s16 pos = read_v3s16(L, 1);
lua_pushnumber(L, env->getServerMap().updateBlockHeat(env, pos));
return 1;
}
// minetest.get_humidity(pos)
// pos = {x=num, y=num, z=num}
int ModApiEnvMod::l_get_humidity(lua_State *L)
{
GET_ENV_PTR;
v3s16 pos = read_v3s16(L, 1);
lua_pushnumber(L, env->getServerMap().updateBlockHumidity(env, pos));
return 1;
}
// minetest.forceload_block(blockpos) // minetest.forceload_block(blockpos)
// blockpos = {x=num, y=num, z=num} // blockpos = {x=num, y=num, z=num}
int ModApiEnvMod::l_forceload_block(lua_State *L) int ModApiEnvMod::l_forceload_block(lua_State *L)
@ -855,8 +832,6 @@ void ModApiEnvMod::Initialize(lua_State *L, int top)
API_FCT(find_path); API_FCT(find_path);
API_FCT(line_of_sight); API_FCT(line_of_sight);
API_FCT(transforming_liquid_add); API_FCT(transforming_liquid_add);
API_FCT(get_heat);
API_FCT(get_humidity);
API_FCT(forceload_block); API_FCT(forceload_block);
API_FCT(forceload_free_block); API_FCT(forceload_free_block);
} }

@ -148,9 +148,6 @@ private:
// minetest.transforming_liquid_add(pos) // minetest.transforming_liquid_add(pos)
static int l_transforming_liquid_add(lua_State *L); static int l_transforming_liquid_add(lua_State *L);
static int l_get_heat(lua_State *L);
static int l_get_humidity(lua_State *L);
// minetest.forceload_block(blockpos) // minetest.forceload_block(blockpos)
// forceloads a block // forceloads a block
static int l_forceload_block(lua_State *L); static int l_forceload_block(lua_State *L);

@ -218,7 +218,6 @@ void sendAnnounce(std::string action, const std::vector<std::string> & clients_n
server["dedicated"] = g_settings->get("server_dedicated"); server["dedicated"] = g_settings->get("server_dedicated");
server["privs"] = g_settings->get("default_privs"); server["privs"] = g_settings->get("default_privs");
server["rollback"] = g_settings->getBool("enable_rollback_recording"); server["rollback"] = g_settings->getBool("enable_rollback_recording");
server["liquid_finite"] = g_settings->getBool("liquid_finite");
server["mapgen"] = g_settings->get("mg_name"); server["mapgen"] = g_settings->get("mg_name");
server["can_see_far_names"] = g_settings->getBool("unlimited_player_transfer_distance"); server["can_see_far_names"] = g_settings->getBool("unlimited_player_transfer_distance");
server["mods"] = Json::Value(Json::arrayValue); server["mods"] = Json::Value(Json::arrayValue);