Skip to content

Commit 9bccd75

Browse files
committed
Weather: Clean up getHeat/getHumidity somewhat
1 parent c9eb17a commit 9bccd75

13 files changed

+143
-77
lines changed

src/biome.cpp

+52
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2121
#include "nodedef.h"
2222
#include "map.h" //for ManualMapVoxelManipulator
2323
#include "log.h"
24+
#include "util/numeric.h"
2425
#include "main.h"
2526

2627

@@ -203,3 +204,54 @@ u8 BiomeDefManager::getBiomeIdByName(const char *name) {
203204

204205
return 0;
205206
}
207+
208+
209+
///////////////////////////// Weather
210+
211+
212+
s16 BiomeDefManager::calcBlockHeat(v3s16 p, u64 seed, float timeofday, float totaltime) {
213+
//variant 1: full random
214+
//f32 heat = NoisePerlin3D(np_heat, p.X, env->getGameTime()/100, p.Z, seed);
215+
216+
//variant 2: season change based on default heat map
217+
const f32 offset = 20; // = np_heat->offset
218+
const f32 scale = 20; // = np_heat->scale
219+
const f32 range = 20;
220+
f32 heat = NoisePerlin2D(np_heat, p.X, p.Z, seed); // 0..50..100
221+
222+
heat -= np_heat->offset; // -50..0..+50
223+
224+
// normalizing - todo REMOVE after fixed NoiseParams nparams_biome_def_heat = {50, 50, -> 20, 50,
225+
if (np_heat->scale)
226+
heat /= np_heat->scale / scale; // -20..0..+20
227+
228+
f32 seasonv = totaltime;
229+
seasonv /= 86400 * g_settings->getS16("year_days"); // season change speed
230+
seasonv += (f32)p.X / 3000; // you can walk to area with other season
231+
seasonv = sin(seasonv * M_PI);
232+
heat += (range * (heat < 0 ? 2 : 0.5)) * seasonv; // -60..0..30
233+
234+
heat += offset; // -40..0..50
235+
heat += p.Y / -333; // upper=colder, lower=hotter, 3c per 1000
236+
237+
// daily change, hotter at sun +4, colder at night -4
238+
heat += 8 * (sin(cycle_shift(timeofday, -0.25) * M_PI) - 0.5); //-44..20..54
239+
240+
return heat;
241+
}
242+
243+
244+
s16 BiomeDefManager::calcBlockHumidity(v3s16 p, u64 seed, float timeofday, float totaltime) {
245+
246+
f32 humidity = NoisePerlin2D(np_humidity, p.X, p.Z, seed);
247+
248+
f32 seasonv = totaltime;
249+
seasonv /= 86400 * 2; // bad weather change speed (2 days)
250+
seasonv += (f32)p.Z / 300;
251+
humidity += 30 * sin(seasonv * M_PI);
252+
253+
humidity += -12 * (sin(cycle_shift(timeofday, -0.1) * M_PI) - 0.5);
254+
humidity = rangelim(humidity, 0, 100);
255+
256+
return humidity;
257+
}

src/biome.h

+3
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ class BiomeDefManager {
9191
void addBiome(Biome *b);
9292
void resolveNodeNames(INodeDefManager *ndef);
9393
u8 getBiomeIdByName(const char *name);
94+
95+
s16 calcBlockHeat(v3s16 p, u64 seed, float timeofday, float totaltime);
96+
s16 calcBlockHumidity(v3s16 p, u64 seed, float timeofday, float totaltime);
9497
};
9598

9699
#endif

src/constants.h

+6
Original file line numberDiff line numberDiff line change
@@ -89,5 +89,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
8989
// Maximum hit points of a player
9090
#define PLAYER_MAX_HP 20
9191

92+
/*
93+
Environmental condition constants
94+
*/
95+
#define HEAT_UNDEFINED (-0x7fff-1)
96+
#define HUMIDITY_UNDEFINED (-0x7fff-1)
97+
9298
#endif
9399

src/content_abm.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ class LiquidFreeze : public ActiveBlockModifier {
253253
ServerMap *map = &env->getServerMap();
254254
INodeDefManager *ndef = env->getGameDef()->ndef();
255255

256-
float heat = map->getHeat(env, p);
256+
float heat = map->updateBlockHeat(env, p);
257257
//heater = rare
258258
content_t c = map->getNodeNoEx(p - v3s16(0, -1, 0 )).getContent(); // top
259259
//more chance to freeze if air at top
@@ -315,7 +315,7 @@ class LiquidMeltWeather : public ActiveBlockModifier {
315315
ServerMap *map = &env->getServerMap();
316316
INodeDefManager *ndef = env->getGameDef()->ndef();
317317

318-
float heat = map->getHeat(env, p);
318+
float heat = map->updateBlockHeat(env, p);
319319
content_t c = map->getNodeNoEx(p - v3s16(0, -1, 0 )).getContent(); // top
320320
if (heat >= 1 && (heat >= 40 || ((myrand_range(heat, 40)) >= (c == CONTENT_AIR ? 10 : 20)))) {
321321
n.freezeMelt(ndef);
@@ -378,7 +378,7 @@ void add_legacy_abms(ServerEnvironment *env, INodeDefManager *nodedef) {
378378
env->addActiveBlockModifier(new LiquidDropABM(env, nodedef));
379379
env->addActiveBlockModifier(new LiquidMeltHot(env, nodedef));
380380
//env->addActiveBlockModifier(new LiquidMeltAround(env, nodedef));
381-
if (g_settings->getBool("weather")) {
381+
if (env->m_use_weather) {
382382
env->addActiveBlockModifier(new LiquidFreeze(env, nodedef));
383383
env->addActiveBlockModifier(new LiquidMeltWeather(env, nodedef));
384384
}

src/emerge.cpp

+1-10
Original file line numberDiff line numberDiff line change
@@ -512,8 +512,7 @@ void *EmergeThread::Thread() {
512512
ign(&m_server->m_ignore_map_edit_events_area,
513513
VoxelArea(minp, maxp));
514514
{ // takes about 90ms with -O1 on an e3-1230v2
515-
m_server->getScriptIface()->
516-
environment_OnGenerated(
515+
m_server->getScriptIface()->environment_OnGenerated(
517516
minp, maxp, emerge->getBlockSeed(minp));
518517
}
519518

@@ -535,14 +534,6 @@ void *EmergeThread::Thread() {
535534
if (block)
536535
modified_blocks[p] = block;
537536

538-
// Update weather data in mapblock
539-
for(std::map<v3s16, MapBlock *>::iterator
540-
i = modified_blocks.begin();
541-
i != modified_blocks.end(); ++i) {
542-
map->getHeat(m_server->m_env, MAP_BLOCKSIZE*i->first ,i->second);
543-
map->getHumidity(m_server->m_env, MAP_BLOCKSIZE*i->first, i->second);
544-
}
545-
546537
// Set the modified blocks unsent for all the clients
547538
for (std::map<u16, RemoteClient*>::iterator
548539
i = m_server->m_clients.begin();

src/environment.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ ServerEnvironment::ServerEnvironment(ServerMap *map,
322322
m_recommended_send_interval(0.1),
323323
m_max_lag_estimate(0.1)
324324
{
325+
m_use_weather = g_settings->getBool("weather");
325326
}
326327

327328
ServerEnvironment::~ServerEnvironment()
@@ -808,6 +809,16 @@ void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime)
808809

809810
// Activate stored objects
810811
activateObjects(block, dtime_s);
812+
813+
// Calculate weather conditions
814+
if (m_use_weather) {
815+
m_map->updateBlockHeat(this, block->getPos() * MAP_BLOCKSIZE, block);
816+
m_map->updateBlockHumidity(this, block->getPos() * MAP_BLOCKSIZE, block);
817+
} else {
818+
block->heat = HEAT_UNDEFINED;
819+
block->humidity = HUMIDITY_UNDEFINED;
820+
block->weather_update_time = 0;
821+
}
811822

812823
// Run node timers
813824
std::map<v3s16, NodeTimer> elapsed_timers =

src/environment.h

+4
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,10 @@ class ServerEnvironment : public Environment
300300

301301
void reportMaxLagEstimate(float f) { m_max_lag_estimate = f; }
302302
float getMaxLagEstimate() { return m_max_lag_estimate; }
303+
304+
// is weather active in this environment?
305+
bool m_use_weather;
306+
303307
private:
304308

305309
/*

src/map.cpp

+56-56
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
3939
#include "mapgen_v6.h"
4040
#include "biome.h"
4141
#include "config.h"
42+
#include "server.h"
4243
#include "database.h"
4344
#include "database-dummy.h"
4445
#include "database-sqlite3.h"
@@ -2824,6 +2825,38 @@ MapBlock* ServerMap::finishBlockMake(BlockMakeData *data,
28242825
/*infostream<<"finishBlockMake() done for ("<<blockpos_requested.X
28252826
<<","<<blockpos_requested.Y<<","
28262827
<<blockpos_requested.Z<<")"<<std::endl;*/
2828+
2829+
/*
2830+
Update weather data in central blocks if needed
2831+
*/
2832+
ServerEnvironment *senv = &((Server *)m_gamedef)->getEnv();
2833+
if (senv->m_use_weather) {
2834+
for(s16 x=blockpos_min.X-extra_borders.X;
2835+
x<=blockpos_max.X+extra_borders.X; x++)
2836+
for(s16 z=blockpos_min.Z-extra_borders.Z;
2837+
z<=blockpos_max.Z+extra_borders.Z; z++)
2838+
for(s16 y=blockpos_min.Y-extra_borders.Y;
2839+
y<=blockpos_max.Y+extra_borders.Y; y++)
2840+
{
2841+
v3s16 p(x, y, z);
2842+
updateBlockHeat(senv, p * MAP_BLOCKSIZE, NULL);
2843+
updateBlockHumidity(senv, p * MAP_BLOCKSIZE, NULL);
2844+
}
2845+
} else {
2846+
for(s16 x=blockpos_min.X-extra_borders.X;
2847+
x<=blockpos_max.X+extra_borders.X; x++)
2848+
for(s16 z=blockpos_min.Z-extra_borders.Z;
2849+
z<=blockpos_max.Z+extra_borders.Z; z++)
2850+
for(s16 y=blockpos_min.Y-extra_borders.Y;
2851+
y<=blockpos_max.Y+extra_borders.Y; y++)
2852+
{
2853+
MapBlock *block = getBlockNoCreateNoEx(v3s16(x, y, z));
2854+
block->heat = HEAT_UNDEFINED;
2855+
block->humidity = HUMIDITY_UNDEFINED;
2856+
block->weather_update_time = 0;
2857+
}
2858+
}
2859+
28272860
#if 0
28282861
if(enable_mapgen_debug_info)
28292862
{
@@ -3888,74 +3921,41 @@ void ServerMap::PrintInfo(std::ostream &out)
38883921
out<<"ServerMap: ";
38893922
}
38903923

3891-
s16 ServerMap::getHeat(ServerEnvironment *env, v3s16 p, MapBlock *block)
3924+
s16 ServerMap::updateBlockHeat(ServerEnvironment *env, v3s16 p, MapBlock *block)
38923925
{
3893-
if(block == NULL)
3894-
block = getBlockNoCreateNoEx(getNodeBlockPos(p));
3895-
if(block != NULL) {
3896-
if (env->getGameTime() - block->heat_time < 10)
3926+
u32 gametime = env->getGameTime();
3927+
3928+
if (block) {
3929+
if (gametime - block->weather_update_time < 10)
38973930
return block->heat;
3931+
} else {
3932+
block = getBlockNoCreateNoEx(getNodeBlockPos(p));
38983933
}
38993934

3900-
//variant 1: full random
3901-
//f32 heat = NoisePerlin3D(m_emerge->biomedef->np_heat, p.X, env->getGameTime()/100, p.Z, m_emerge->params->seed);
3902-
3903-
//variant 2: season change based on default heat map
3904-
const f32 offset = 20; // = m_emerge->biomedef->np_heat->offset
3905-
const f32 scale = 20; // = m_emerge->biomedef->np_heat->scale
3906-
const f32 range = 20;
3907-
f32 heat = NoisePerlin2D(m_emerge->biomedef->np_heat, p.X, p.Z,
3908-
m_emerge->params->seed); // 0..50..100
3909-
3910-
heat -= m_emerge->biomedef->np_heat->offset; // -50..0..+50
3935+
f32 heat = m_emerge->biomedef->calcBlockHeat(p, m_seed,
3936+
env->getTimeOfDayF(), gametime * env->getTimeOfDaySpeed());
39113937

3912-
// normalizing - todo REMOVE after fixed NoiseParams nparams_biome_def_heat = {50, 50, -> 20, 50,
3913-
if(m_emerge->biomedef->np_heat->scale)
3914-
heat /= m_emerge->biomedef->np_heat->scale / scale; // -20..0..+20
3915-
3916-
f32 seasonv = (f32)env->getGameTime() * env->getTimeOfDaySpeed();
3917-
seasonv /= 86400 * g_settings->getS16("year_days"); // season change speed
3918-
seasonv += (f32)p.X / 3000; // you can walk to area with other season
3919-
seasonv = sin(seasonv * M_PI);
3920-
heat += (range * (heat < 0 ? 2 : 0.5)) * seasonv; // -60..0..30
3921-
3922-
heat += offset; // -40..0..50
3923-
heat += p.Y / -333; // upper=colder, lower=hotter, 3c per 1000
3924-
3925-
// daily change, hotter at sun +4, colder at night -4
3926-
heat += 8 * (sin(cycle_shift(env->getTimeOfDayF(), -0.25) * M_PI) - 0.5); //-44..20..54
3927-
3928-
if(block != NULL) {
3929-
block->heat = heat;
3930-
block->heat_time = env->getGameTime();
3931-
}
3938+
block->heat = heat;
3939+
block->weather_update_time = gametime;
39323940
return heat;
39333941
}
39343942

3935-
s16 ServerMap::getHumidity(ServerEnvironment *env, v3s16 p, MapBlock *block)
3943+
s16 ServerMap::updateBlockHumidity(ServerEnvironment *env, v3s16 p, MapBlock *block)
39363944
{
3937-
if(block == NULL)
3938-
block = getBlockNoCreateNoEx(getNodeBlockPos(p));
3939-
if(block != NULL) {
3940-
if (env->getGameTime() - block->humidity_time < 10)
3945+
u32 gametime = env->getGameTime();
3946+
3947+
if (block) {
3948+
if (gametime - block->weather_update_time < 10)
39413949
return block->humidity;
3950+
} else {
3951+
block = getBlockNoCreateNoEx(getNodeBlockPos(p));
39423952
}
39433953

3944-
f32 humidity = NoisePerlin2D(m_emerge->biomedef->np_humidity, p.X, p.Z,
3945-
m_emerge->params->seed);
3946-
3947-
f32 seasonv = (f32)env->getGameTime() * env->getTimeOfDaySpeed();
3948-
seasonv /= 86400 * 2; // bad weather change speed (2 days)
3949-
seasonv += (f32)p.Z / 300;
3950-
humidity += 30 * sin(seasonv * M_PI);
3951-
3952-
humidity += -12 * ( sin(cycle_shift(env->getTimeOfDayF(), -0.1) * M_PI) - 0.5);
3953-
humidity = rangelim(humidity, 0, 100);
3954-
3955-
if(block != NULL) {
3956-
block->humidity = humidity;
3957-
block->humidity_time = env->getGameTime();
3958-
}
3954+
f32 humidity = m_emerge->biomedef->calcBlockHumidity(p, m_seed,
3955+
env->getTimeOfDayF(), gametime * env->getTimeOfDaySpeed());
3956+
3957+
block->humidity = humidity;
3958+
block->weather_update_time = gametime;
39593959
return humidity;
39603960
}
39613961

src/map.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -477,8 +477,8 @@ class ServerMap : public Map
477477
// Parameters fed to the Mapgen
478478
MapgenParams *m_mgparams;
479479

480-
virtual s16 getHeat(ServerEnvironment *env, v3s16 p, MapBlock *block = NULL);
481-
virtual s16 getHumidity(ServerEnvironment *env, v3s16 p, MapBlock *block = NULL);
480+
virtual s16 updateBlockHeat(ServerEnvironment *env, v3s16 p, MapBlock *block = NULL);
481+
virtual s16 updateBlockHumidity(ServerEnvironment *env, v3s16 p, MapBlock *block = NULL);
482482

483483
private:
484484
// Seed used for all kinds of randomness in generation

src/mapblock.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
4444

4545
MapBlock::MapBlock(Map *parent, v3s16 pos, IGameDef *gamedef, bool dummy):
4646
heat(0),
47-
heat_time(0),
4847
humidity(0),
49-
humidity_time(0),
48+
weather_update_time(0),
5049
m_parent(parent),
5150
m_pos(pos),
5251
m_gamedef(gamedef),

src/mapblock.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -515,9 +515,8 @@ class MapBlock /*: public NodeContainer*/
515515
StaticObjectList m_static_objects;
516516

517517
s16 heat;
518-
u32 heat_time;
519518
s16 humidity;
520-
u32 humidity_time;
519+
u32 weather_update_time;
521520

522521
private:
523522
/*

src/script/lua_api/l_env.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -764,7 +764,7 @@ int ModApiEnvMod::l_get_heat(lua_State *L)
764764
GET_ENV_PTR;
765765

766766
v3s16 pos = read_v3s16(L, 1);
767-
lua_pushnumber(L, env->getServerMap().getHeat(env, pos));
767+
lua_pushnumber(L, env->getServerMap().updateBlockHeat(env, pos));
768768
return 1;
769769
}
770770

@@ -775,7 +775,7 @@ int ModApiEnvMod::l_get_humidity(lua_State *L)
775775
GET_ENV_PTR;
776776

777777
v3s16 pos = read_v3s16(L, 1);
778-
lua_pushnumber(L, env->getServerMap().getHumidity(env, pos));
778+
lua_pushnumber(L, env->getServerMap().updateBlockHumidity(env, pos));
779779
return 1;
780780
}
781781

src/server.h

+1
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,7 @@ class Server : public con::PeerHandler, public MapEventReceiver,
489489

490490
bool showFormspec(const char *name, const std::string &formspec, const std::string &formname);
491491
Map & getMap() { return m_env->getMap(); }
492+
ServerEnvironment & getEnv() { return *m_env; }
492493

493494
u32 hudAdd(Player *player, HudElement *element);
494495
bool hudRemove(Player *player, u32 id);

0 commit comments

Comments
 (0)