mirror of
				https://github.com/luanti-org/luanti.git
				synced 2025-11-04 09:15:29 +01:00 
			
		
		
		
	Weather: Clean up getHeat/getHumidity somewhat
This commit is contained in:
		@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
#include "nodedef.h"
 | 
			
		||||
#include "map.h" //for ManualMapVoxelManipulator
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "util/numeric.h"
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -203,3 +204,54 @@ u8 BiomeDefManager::getBiomeIdByName(const char *name) {
 | 
			
		||||
	
 | 
			
		||||
	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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -91,6 +91,9 @@ public:
 | 
			
		||||
	void addBiome(Biome *b);
 | 
			
		||||
	void resolveNodeNames(INodeDefManager *ndef);
 | 
			
		||||
	u8 getBiomeIdByName(const char *name);
 | 
			
		||||
	
 | 
			
		||||
	s16 calcBlockHeat(v3s16 p, u64 seed, float timeofday, float totaltime);
 | 
			
		||||
	s16 calcBlockHumidity(v3s16 p, u64 seed, float timeofday, float totaltime);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -89,5 +89,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
// Maximum hit points of a player
 | 
			
		||||
#define PLAYER_MAX_HP 20
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
	Environmental condition constants
 | 
			
		||||
*/
 | 
			
		||||
#define HEAT_UNDEFINED     (-0x7fff-1)
 | 
			
		||||
#define HUMIDITY_UNDEFINED (-0x7fff-1)
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -253,7 +253,7 @@ class LiquidFreeze : public ActiveBlockModifier {
 | 
			
		||||
			ServerMap *map = &env->getServerMap();
 | 
			
		||||
			INodeDefManager *ndef = env->getGameDef()->ndef();
 | 
			
		||||
 | 
			
		||||
			float heat = map->getHeat(env, p);
 | 
			
		||||
			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
 | 
			
		||||
@@ -315,7 +315,7 @@ class LiquidMeltWeather : public ActiveBlockModifier {
 | 
			
		||||
			ServerMap *map = &env->getServerMap();
 | 
			
		||||
			INodeDefManager *ndef = env->getGameDef()->ndef();
 | 
			
		||||
 | 
			
		||||
			float heat = map->getHeat(env, p);
 | 
			
		||||
			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);
 | 
			
		||||
@@ -378,7 +378,7 @@ void add_legacy_abms(ServerEnvironment *env, INodeDefManager *nodedef) {
 | 
			
		||||
		env->addActiveBlockModifier(new LiquidDropABM(env, nodedef));
 | 
			
		||||
		env->addActiveBlockModifier(new LiquidMeltHot(env, nodedef));
 | 
			
		||||
		//env->addActiveBlockModifier(new LiquidMeltAround(env, nodedef));
 | 
			
		||||
		if (g_settings->getBool("weather")) {
 | 
			
		||||
		if (env->m_use_weather) {
 | 
			
		||||
			env->addActiveBlockModifier(new LiquidFreeze(env, nodedef));
 | 
			
		||||
			env->addActiveBlockModifier(new LiquidMeltWeather(env, nodedef));
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -512,8 +512,7 @@ void *EmergeThread::Thread() {
 | 
			
		||||
						ign(&m_server->m_ignore_map_edit_events_area,
 | 
			
		||||
						VoxelArea(minp, maxp));
 | 
			
		||||
					{  // takes about 90ms with -O1 on an e3-1230v2
 | 
			
		||||
						m_server->getScriptIface()->
 | 
			
		||||
								environment_OnGenerated(
 | 
			
		||||
						m_server->getScriptIface()->environment_OnGenerated(
 | 
			
		||||
								minp, maxp, emerge->getBlockSeed(minp));
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
@@ -535,14 +534,6 @@ void *EmergeThread::Thread() {
 | 
			
		||||
		if (block)
 | 
			
		||||
			modified_blocks[p] = block;
 | 
			
		||||
 | 
			
		||||
		// Update weather data in mapblock
 | 
			
		||||
		for(std::map<v3s16, MapBlock *>::iterator
 | 
			
		||||
			i = modified_blocks.begin();
 | 
			
		||||
			i != modified_blocks.end(); ++i) {
 | 
			
		||||
			map->getHeat(m_server->m_env, MAP_BLOCKSIZE*i->first ,i->second);
 | 
			
		||||
			map->getHumidity(m_server->m_env, MAP_BLOCKSIZE*i->first, i->second);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Set the modified blocks unsent for all the clients
 | 
			
		||||
		for (std::map<u16, RemoteClient*>::iterator
 | 
			
		||||
			 i = m_server->m_clients.begin();
 | 
			
		||||
 
 | 
			
		||||
@@ -322,6 +322,7 @@ ServerEnvironment::ServerEnvironment(ServerMap *map,
 | 
			
		||||
	m_recommended_send_interval(0.1),
 | 
			
		||||
	m_max_lag_estimate(0.1)
 | 
			
		||||
{
 | 
			
		||||
	m_use_weather = g_settings->getBool("weather");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ServerEnvironment::~ServerEnvironment()
 | 
			
		||||
@@ -808,6 +809,16 @@ void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime)
 | 
			
		||||
	
 | 
			
		||||
	// Activate stored objects
 | 
			
		||||
	activateObjects(block, dtime_s);
 | 
			
		||||
	
 | 
			
		||||
	// Calculate weather conditions
 | 
			
		||||
	if (m_use_weather) {
 | 
			
		||||
		m_map->updateBlockHeat(this, block->getPos() *  MAP_BLOCKSIZE, block);
 | 
			
		||||
		m_map->updateBlockHumidity(this, block->getPos() * MAP_BLOCKSIZE, block);
 | 
			
		||||
	} else {
 | 
			
		||||
		block->heat     = HEAT_UNDEFINED;
 | 
			
		||||
		block->humidity = HUMIDITY_UNDEFINED;
 | 
			
		||||
		block->weather_update_time = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Run node timers
 | 
			
		||||
	std::map<v3s16, NodeTimer> elapsed_timers =
 | 
			
		||||
 
 | 
			
		||||
@@ -300,6 +300,10 @@ public:
 | 
			
		||||
 | 
			
		||||
	void reportMaxLagEstimate(float f) { m_max_lag_estimate = f; }
 | 
			
		||||
	float getMaxLagEstimate() { return m_max_lag_estimate; }
 | 
			
		||||
	
 | 
			
		||||
	// is weather active in this environment?
 | 
			
		||||
	bool m_use_weather;
 | 
			
		||||
	
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										112
									
								
								src/map.cpp
									
									
									
									
									
								
							
							
						
						
									
										112
									
								
								src/map.cpp
									
									
									
									
									
								
							@@ -39,6 +39,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
#include "mapgen_v6.h"
 | 
			
		||||
#include "biome.h"
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include "server.h"
 | 
			
		||||
#include "database.h"
 | 
			
		||||
#include "database-dummy.h"
 | 
			
		||||
#include "database-sqlite3.h"
 | 
			
		||||
@@ -2824,6 +2825,38 @@ MapBlock* ServerMap::finishBlockMake(BlockMakeData *data,
 | 
			
		||||
	/*infostream<<"finishBlockMake() done for ("<<blockpos_requested.X
 | 
			
		||||
			<<","<<blockpos_requested.Y<<","
 | 
			
		||||
			<<blockpos_requested.Z<<")"<<std::endl;*/
 | 
			
		||||
			
 | 
			
		||||
	/*
 | 
			
		||||
		Update weather data in central blocks if needed
 | 
			
		||||
	*/
 | 
			
		||||
	ServerEnvironment *senv = &((Server *)m_gamedef)->getEnv();
 | 
			
		||||
	if (senv->m_use_weather) {
 | 
			
		||||
		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);
 | 
			
		||||
			updateBlockHeat(senv, p * MAP_BLOCKSIZE, NULL);
 | 
			
		||||
			updateBlockHumidity(senv, p * MAP_BLOCKSIZE, NULL);
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		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++)
 | 
			
		||||
		{
 | 
			
		||||
			MapBlock *block = getBlockNoCreateNoEx(v3s16(x, y, z));
 | 
			
		||||
			block->heat     = HEAT_UNDEFINED;
 | 
			
		||||
			block->humidity = HUMIDITY_UNDEFINED;
 | 
			
		||||
			block->weather_update_time = 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
#if 0
 | 
			
		||||
	if(enable_mapgen_debug_info)
 | 
			
		||||
	{
 | 
			
		||||
@@ -3888,74 +3921,41 @@ void ServerMap::PrintInfo(std::ostream &out)
 | 
			
		||||
	out<<"ServerMap: ";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
s16 ServerMap::getHeat(ServerEnvironment *env, v3s16 p, MapBlock *block)
 | 
			
		||||
s16 ServerMap::updateBlockHeat(ServerEnvironment *env, v3s16 p, MapBlock *block)
 | 
			
		||||
{
 | 
			
		||||
	if(block == NULL)
 | 
			
		||||
		block = getBlockNoCreateNoEx(getNodeBlockPos(p));
 | 
			
		||||
	if(block != NULL) {
 | 
			
		||||
		if (env->getGameTime() - block->heat_time < 10)
 | 
			
		||||
	u32 gametime = env->getGameTime();
 | 
			
		||||
	
 | 
			
		||||
	if (block) {
 | 
			
		||||
		if (gametime - block->weather_update_time < 10)
 | 
			
		||||
			return block->heat;
 | 
			
		||||
	} else {
 | 
			
		||||
		block = getBlockNoCreateNoEx(getNodeBlockPos(p));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//variant 1: full random
 | 
			
		||||
	//f32 heat = NoisePerlin3D(m_emerge->biomedef->np_heat, p.X, env->getGameTime()/100, p.Z, m_emerge->params->seed);
 | 
			
		||||
	f32 heat = m_emerge->biomedef->calcBlockHeat(p, m_seed,
 | 
			
		||||
			env->getTimeOfDayF(), gametime * env->getTimeOfDaySpeed());
 | 
			
		||||
 | 
			
		||||
	//variant 2: season change based on default heat map
 | 
			
		||||
	const f32 offset = 20; // = m_emerge->biomedef->np_heat->offset
 | 
			
		||||
	const f32 scale  = 20; // = m_emerge->biomedef->np_heat->scale
 | 
			
		||||
	const f32 range  = 20;
 | 
			
		||||
	f32 heat = NoisePerlin2D(m_emerge->biomedef->np_heat, p.X, p.Z,
 | 
			
		||||
					m_emerge->params->seed); // 0..50..100
 | 
			
		||||
 | 
			
		||||
	heat -= m_emerge->biomedef->np_heat->offset; // -50..0..+50
 | 
			
		||||
 | 
			
		||||
	// normalizing - todo REMOVE after fixed NoiseParams nparams_biome_def_heat = {50, 50, -> 20, 50,
 | 
			
		||||
	if(m_emerge->biomedef->np_heat->scale)
 | 
			
		||||
		heat /= m_emerge->biomedef->np_heat->scale / scale; //  -20..0..+20
 | 
			
		||||
 | 
			
		||||
	f32 seasonv = (f32)env->getGameTime() * env->getTimeOfDaySpeed();
 | 
			
		||||
	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(env->getTimeOfDayF(), -0.25) * M_PI) - 0.5); //-44..20..54
 | 
			
		||||
 | 
			
		||||
	if(block != NULL) {
 | 
			
		||||
		block->heat = heat;
 | 
			
		||||
		block->heat_time = env->getGameTime();
 | 
			
		||||
	}
 | 
			
		||||
	block->heat = heat;
 | 
			
		||||
	block->weather_update_time = gametime;
 | 
			
		||||
	return heat;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
s16 ServerMap::getHumidity(ServerEnvironment *env, v3s16 p, MapBlock *block)
 | 
			
		||||
s16 ServerMap::updateBlockHumidity(ServerEnvironment *env, v3s16 p, MapBlock *block)
 | 
			
		||||
{
 | 
			
		||||
	if(block == NULL)
 | 
			
		||||
		block = getBlockNoCreateNoEx(getNodeBlockPos(p));
 | 
			
		||||
	if(block != NULL) {
 | 
			
		||||
		if (env->getGameTime() - block->humidity_time < 10)
 | 
			
		||||
	u32 gametime = env->getGameTime();
 | 
			
		||||
	
 | 
			
		||||
	if (block) {
 | 
			
		||||
		if (gametime - block->weather_update_time < 10)
 | 
			
		||||
			return block->humidity;
 | 
			
		||||
	} else {
 | 
			
		||||
		block = getBlockNoCreateNoEx(getNodeBlockPos(p));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	f32 humidity = NoisePerlin2D(m_emerge->biomedef->np_humidity, p.X, p.Z, 
 | 
			
		||||
						m_emerge->params->seed);
 | 
			
		||||
 | 
			
		||||
	f32 seasonv = (f32)env->getGameTime() * env->getTimeOfDaySpeed();
 | 
			
		||||
	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(env->getTimeOfDayF(), -0.1) * M_PI) - 0.5);
 | 
			
		||||
	humidity = rangelim(humidity, 0, 100);
 | 
			
		||||
 | 
			
		||||
	if(block != NULL) {
 | 
			
		||||
		block->humidity = humidity;
 | 
			
		||||
		block->humidity_time = env->getGameTime();
 | 
			
		||||
	}
 | 
			
		||||
	f32 humidity = m_emerge->biomedef->calcBlockHumidity(p, m_seed,
 | 
			
		||||
			env->getTimeOfDayF(), gametime * env->getTimeOfDaySpeed());
 | 
			
		||||
			
 | 
			
		||||
	block->humidity = humidity;
 | 
			
		||||
	block->weather_update_time = gametime;
 | 
			
		||||
	return humidity;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -477,8 +477,8 @@ public:
 | 
			
		||||
	// Parameters fed to the Mapgen
 | 
			
		||||
	MapgenParams *m_mgparams;
 | 
			
		||||
 | 
			
		||||
	virtual s16 getHeat(ServerEnvironment *env, v3s16 p, MapBlock *block = NULL);
 | 
			
		||||
	virtual s16 getHumidity(ServerEnvironment *env, v3s16 p, MapBlock *block = NULL);
 | 
			
		||||
	virtual s16 updateBlockHeat(ServerEnvironment *env, v3s16 p, MapBlock *block = NULL);
 | 
			
		||||
	virtual s16 updateBlockHumidity(ServerEnvironment *env, v3s16 p, MapBlock *block = NULL);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	// Seed used for all kinds of randomness in generation
 | 
			
		||||
 
 | 
			
		||||
@@ -44,9 +44,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
 | 
			
		||||
MapBlock::MapBlock(Map *parent, v3s16 pos, IGameDef *gamedef, bool dummy):
 | 
			
		||||
		heat(0),
 | 
			
		||||
		heat_time(0),
 | 
			
		||||
		humidity(0),
 | 
			
		||||
		humidity_time(0),
 | 
			
		||||
		weather_update_time(0),
 | 
			
		||||
		m_parent(parent),
 | 
			
		||||
		m_pos(pos),
 | 
			
		||||
		m_gamedef(gamedef),
 | 
			
		||||
 
 | 
			
		||||
@@ -515,9 +515,8 @@ public:
 | 
			
		||||
	StaticObjectList m_static_objects;
 | 
			
		||||
	
 | 
			
		||||
	s16 heat;
 | 
			
		||||
	u32 heat_time;
 | 
			
		||||
	s16 humidity;
 | 
			
		||||
	u32 humidity_time;
 | 
			
		||||
	u32 weather_update_time;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	/*
 | 
			
		||||
 
 | 
			
		||||
@@ -764,7 +764,7 @@ int ModApiEnvMod::l_get_heat(lua_State *L)
 | 
			
		||||
	GET_ENV_PTR;
 | 
			
		||||
 | 
			
		||||
	v3s16 pos = read_v3s16(L, 1);
 | 
			
		||||
	lua_pushnumber(L, env->getServerMap().getHeat(env, pos));
 | 
			
		||||
	lua_pushnumber(L, env->getServerMap().updateBlockHeat(env, pos));
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -775,7 +775,7 @@ int ModApiEnvMod::l_get_humidity(lua_State *L)
 | 
			
		||||
	GET_ENV_PTR;
 | 
			
		||||
 | 
			
		||||
	v3s16 pos = read_v3s16(L, 1);
 | 
			
		||||
	lua_pushnumber(L, env->getServerMap().getHumidity(env, pos));
 | 
			
		||||
	lua_pushnumber(L, env->getServerMap().updateBlockHumidity(env, pos));
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -489,6 +489,7 @@ public:
 | 
			
		||||
 | 
			
		||||
	bool showFormspec(const char *name, const std::string &formspec, const std::string &formname);
 | 
			
		||||
	Map & getMap() { return m_env->getMap(); }
 | 
			
		||||
	ServerEnvironment & getEnv() { return *m_env; }
 | 
			
		||||
	
 | 
			
		||||
	u32 hudAdd(Player *player, HudElement *element);
 | 
			
		||||
	bool hudRemove(Player *player, u32 id);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user