diff options
author | Ben Deutsch <ben@bendeutsch.de> | 2017-03-17 10:39:47 +0100 |
---|---|---|
committer | paramat <mat.gregory@virginmedia.com> | 2017-04-30 00:06:13 +0100 |
commit | f1d7a26b7c341b468f34325cec5c3d495f175a8f (patch) | |
tree | 9926a816208ec7b9384ba718be739953d9d3d773 | |
parent | 95409da87d009c352f27c737621972c2225796c9 (diff) | |
download | minetest-f1d7a26b7c341b468f34325cec5c3d495f175a8f.tar.gz minetest-f1d7a26b7c341b468f34325cec5c3d495f175a8f.tar.bz2 minetest-f1d7a26b7c341b468f34325cec5c3d495f175a8f.zip |
Add clouds API
-rw-r--r-- | doc/lua_api.txt | 9 | ||||
-rw-r--r-- | src/client.h | 11 | ||||
-rw-r--r-- | src/cloudparams.h | 33 | ||||
-rw-r--r-- | src/clouds.cpp | 90 | ||||
-rw-r--r-- | src/clouds.h | 54 | ||||
-rw-r--r-- | src/game.cpp | 13 | ||||
-rw-r--r-- | src/network/clientopcodes.cpp | 2 | ||||
-rw-r--r-- | src/network/clientpackethandler.cpp | 28 | ||||
-rw-r--r-- | src/network/networkprotocol.h | 10 | ||||
-rw-r--r-- | src/network/serveropcodes.cpp | 2 | ||||
-rw-r--r-- | src/remoteplayer.cpp | 8 | ||||
-rw-r--r-- | src/remoteplayer.h | 12 | ||||
-rw-r--r-- | src/script/lua_api/l_object.cpp | 81 | ||||
-rw-r--r-- | src/script/lua_api/l_object.h | 6 | ||||
-rw-r--r-- | src/server.cpp | 30 | ||||
-rw-r--r-- | src/server.h | 12 | ||||
-rw-r--r-- | src/sky.cpp | 6 |
17 files changed, 357 insertions, 50 deletions
diff --git a/doc/lua_api.txt b/doc/lua_api.txt index eba8a5fef..479e38a2e 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -3077,6 +3077,15 @@ This is basically a reference to a C++ `ServerActiveObject` * `"skybox"`: Uses 6 textures, `bgcolor` used * `"plain"`: Uses 0 textures, `bgcolor` used * `get_sky()`: returns bgcolor, type and a table with the textures +* `set_clouds(parameters)`: set cloud parameters + * `parameters` is a table with the following optional fields: + * `density`: from `0` (no clouds) to `1` (full clouds) (default `0.4`) + * `color`: basic cloud color, with alpha channel (default `#fff0f0e5`) + * `ambient`: cloud color lower bound, use for a "glow at night" effect (default `#000000`) + * `height`: cloud height, i.e. y of cloud base (default per conf, usually `120`) + * `thickness`: cloud thickness in nodes (default `16`) + * `speed`: 2D cloud speed + direction in nodes per second (default `{x=0, y=-2}`) +* `get_clouds()`: returns a table with the current cloud parameters as in `set_clouds` * `override_day_night_ratio(ratio or nil)` * `0`...`1`: Overrides day-night ratio, controlling sunlight to a specific amount * `nil`: Disables override, defaulting to sunlight based on day-night cycle diff --git a/src/client.h b/src/client.h index f5b03f19d..7cbfadd50 100644 --- a/src/client.h +++ b/src/client.h @@ -77,6 +77,7 @@ enum ClientEventType CE_HUDCHANGE, CE_SET_SKY, CE_OVERRIDE_DAY_NIGHT_RATIO, + CE_CLOUD_PARAMS, }; struct ClientEvent @@ -178,6 +179,15 @@ struct ClientEvent bool do_override; float ratio_f; } override_day_night_ratio; + struct { + f32 density; + u32 color_bright; + u32 color_ambient; + f32 height; + f32 thickness; + f32 speed_x; + f32 speed_y; + } cloud_params; }; }; @@ -331,6 +341,7 @@ public: void handleCommand_HudSetFlags(NetworkPacket* pkt); void handleCommand_HudSetParam(NetworkPacket* pkt); void handleCommand_HudSetSky(NetworkPacket* pkt); + void handleCommand_CloudParams(NetworkPacket* pkt); void handleCommand_OverrideDayNightRatio(NetworkPacket* pkt); void handleCommand_LocalPlayerAnimations(NetworkPacket* pkt); void handleCommand_EyeOffset(NetworkPacket* pkt); diff --git a/src/cloudparams.h b/src/cloudparams.h new file mode 100644 index 000000000..dafec4b27 --- /dev/null +++ b/src/cloudparams.h @@ -0,0 +1,33 @@ +/* +Minetest +Copyright (C) 2017 bendeutsch, Ben Deutsch <ben@bendeutsch.de> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef CLOUDPARAMS_HEADER +#define CLOUDPARAMS_HEADER + +struct CloudParams +{ + float density; + video::SColor color_bright; + video::SColor color_ambient; + float thickness; + float height; + v2f speed; +}; + +#endif diff --git a/src/clouds.cpp b/src/clouds.cpp index 82b63b6b3..627fac47a 100644 --- a/src/clouds.cpp +++ b/src/clouds.cpp @@ -32,6 +32,7 @@ irr::scene::ISceneManager *g_menucloudsmgr = NULL; static void cloud_3d_setting_changed(const std::string &settingname, void *data) { + // TODO: only re-read cloud settings, not height or radius ((Clouds *)data)->readSettings(); } @@ -44,9 +45,10 @@ Clouds::Clouds( ): scene::ISceneNode(parent, mgr, id), m_seed(seed), - m_camera_pos(0,0), - m_time(0), - m_camera_offset(0,0,0) + m_camera_pos(0.0f, 0.0f), + m_origin(0.0f, 0.0f), + m_camera_offset(0.0f, 0.0f, 0.0f), + m_color(1.0f, 1.0f, 1.0f, 1.0f) { m_material.setFlag(video::EMF_LIGHTING, false); //m_material.setFlag(video::EMF_BACK_FACE_CULLING, false); @@ -57,14 +59,18 @@ Clouds::Clouds( //m_material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; m_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + m_params.density = 0.4f; + m_params.thickness = 16.0f; + m_params.color_bright = video::SColor(229, 255, 240, 240); + m_params.color_ambient = video::SColor(255, 0, 0, 0); + m_params.speed = v2f(0.0f, -2.0f); + m_passed_cloud_y = cloudheight; readSettings(); g_settings->registerChangedCallback("enable_3d_clouds", &cloud_3d_setting_changed, this); - m_box = aabb3f(-BS*1000000,m_cloud_y-BS,-BS*1000000, - BS*1000000,m_cloud_y+BS,BS*1000000); - + updateBox(); } Clouds::~Clouds() @@ -88,6 +94,10 @@ void Clouds::OnRegisterSceneNode() void Clouds::render() { + + if (m_params.density <= 0.0f) + return; // no need to do anything + video::IVideoDriver* driver = SceneManager->getVideoDriver(); if(SceneManager->getSceneNodeRenderPass() != scene::ESNRP_TRANSPARENT) @@ -107,15 +117,12 @@ void Clouds::render() Clouds move from Z+ towards Z- */ - const float cloud_size = BS * 64; - const v2f cloud_speed(0, -BS * 2); + static const float cloud_size = BS * 64.0f; const float cloud_full_radius = cloud_size * m_cloud_radius_i; - // Position of cloud noise origin in world coordinates - v2f world_cloud_origin_pos_f = m_time * cloud_speed; // Position of cloud noise origin from the camera - v2f cloud_origin_from_camera_f = world_cloud_origin_pos_f - m_camera_pos; + v2f cloud_origin_from_camera_f = m_origin - m_camera_pos; // The center point of drawing in the noise v2f center_of_drawing_in_noise_f = -cloud_origin_from_camera_f; // The integer center point of drawing in the noise @@ -127,7 +134,7 @@ void Clouds::render() v2f world_center_of_drawing_in_noise_f = v2f( center_of_drawing_in_noise_i.X * cloud_size, center_of_drawing_in_noise_i.Y * cloud_size - ) + world_cloud_origin_pos_f; + ) + m_origin; /*video::SColor c_top(128,b*240,b*240,b*255); video::SColor c_side_1(128,b*230,b*230,b*255); @@ -146,10 +153,6 @@ void Clouds::render() c_bottom_f.r *= 0.80; c_bottom_f.g *= 0.80; c_bottom_f.b *= 0.80; - c_top_f.a = 0.9; - c_side_1_f.a = 0.9; - c_side_2_f.a = 0.9; - c_bottom_f.a = 0.9; video::SColor c_top = c_top_f.toSColor(); video::SColor c_side_1 = c_side_1_f.toSColor(); video::SColor c_side_2 = c_side_2_f.toSColor(); @@ -187,11 +190,14 @@ void Clouds::render() zi + center_of_drawing_in_noise_i.Y ); - double noise = noise2d_perlin( + float noise = noise2d_perlin( (float)p_in_noise_i.X * cloud_size_noise, (float)p_in_noise_i.Y * cloud_size_noise, m_seed, 3, 0.5); - grid[i] = (noise >= 0.4); + // normalize to 0..1 (given 3 octaves) + static const float noise_bound = 1.0f + 0.5f + 0.25f; + float density = noise / noise_bound * 0.5f + 0.5f; + grid[i] = (density < m_params.density); } } @@ -236,8 +242,9 @@ void Clouds::render() v[3].Color.setBlue(255); }*/ - f32 rx = cloud_size/2; - f32 ry = 8 * BS; + f32 rx = cloud_size / 2.0f; + // if clouds are flat, the top layer should be at the given height + f32 ry = m_enable_3d ? m_params.thickness * BS : 0.0f; f32 rz = cloud_size / 2; for(int i=0; i<num_faces_to_draw; i++) @@ -265,8 +272,8 @@ void Clouds::render() } v[0].Pos.set(-rx, ry,-rz); v[1].Pos.set( rx, ry,-rz); - v[2].Pos.set( rx,-ry,-rz); - v[3].Pos.set(-rx,-ry,-rz); + v[2].Pos.set( rx, 0,-rz); + v[3].Pos.set(-rx, 0,-rz); break; case 2: //right if (INAREA(xi + 1, zi, m_cloud_radius_i)) { @@ -280,8 +287,8 @@ void Clouds::render() } v[0].Pos.set( rx, ry,-rz); v[1].Pos.set( rx, ry, rz); - v[2].Pos.set( rx,-ry, rz); - v[3].Pos.set( rx,-ry,-rz); + v[2].Pos.set( rx, 0, rz); + v[3].Pos.set( rx, 0,-rz); break; case 3: // front if (INAREA(xi, zi + 1, m_cloud_radius_i)) { @@ -295,8 +302,8 @@ void Clouds::render() } v[0].Pos.set( rx, ry, rz); v[1].Pos.set(-rx, ry, rz); - v[2].Pos.set(-rx,-ry, rz); - v[3].Pos.set( rx,-ry, rz); + v[2].Pos.set(-rx, 0, rz); + v[3].Pos.set( rx, 0, rz); break; case 4: // left if (INAREA(xi-1, zi, m_cloud_radius_i)) { @@ -310,22 +317,22 @@ void Clouds::render() } v[0].Pos.set(-rx, ry, rz); v[1].Pos.set(-rx, ry,-rz); - v[2].Pos.set(-rx,-ry,-rz); - v[3].Pos.set(-rx,-ry, rz); + v[2].Pos.set(-rx, 0,-rz); + v[3].Pos.set(-rx, 0, rz); break; case 5: // bottom for(int j=0;j<4;j++){ v[j].Color = c_bottom; v[j].Normal.set(0,-1,0); } - v[0].Pos.set( rx,-ry, rz); - v[1].Pos.set(-rx,-ry, rz); - v[2].Pos.set(-rx,-ry,-rz); - v[3].Pos.set( rx,-ry,-rz); + v[0].Pos.set( rx, 0, rz); + v[1].Pos.set(-rx, 0, rz); + v[2].Pos.set(-rx, 0,-rz); + v[3].Pos.set( rx, 0,-rz); break; } - v3f pos(p0.X, m_cloud_y, p0.Y); + v3f pos(p0.X, m_params.height * BS, p0.Y); pos -= intToFloat(m_camera_offset, BS); for(u16 i=0; i<4; i++) @@ -345,22 +352,25 @@ void Clouds::render() void Clouds::step(float dtime) { - m_time += dtime; + m_origin = m_origin + dtime * BS * m_params.speed; } -void Clouds::update(v2f camera_p, video::SColorf color) +void Clouds::update(v2f camera_p, video::SColorf color_diffuse) { m_camera_pos = camera_p; - m_color = color; - //m_brightness = brightness; - //dstream<<"m_brightness="<<m_brightness<<std::endl; + m_color.r = MYMIN(MYMAX(color_diffuse.r * m_params.color_bright.getRed(), + m_params.color_ambient.getRed()), 255) / 255.0f; + m_color.g = MYMIN(MYMAX(color_diffuse.r * m_params.color_bright.getGreen(), + m_params.color_ambient.getGreen()), 255) / 255.0f; + m_color.b = MYMIN(MYMAX(color_diffuse.b * m_params.color_bright.getBlue(), + m_params.color_ambient.getBlue()), 255) / 255.0f; + m_color.a = m_params.color_bright.getAlpha() / 255.0f; } void Clouds::readSettings() { - m_cloud_y = BS * (m_passed_cloud_y ? m_passed_cloud_y : + m_params.height = (m_passed_cloud_y ? m_passed_cloud_y : g_settings->getS16("cloud_height")); m_cloud_radius_i = g_settings->getU16("cloud_radius"); m_enable_3d = g_settings->getBool("enable_3d_clouds"); } - diff --git a/src/clouds.h b/src/clouds.h index 9c6b41786..a0bda28df 100644 --- a/src/clouds.h +++ b/src/clouds.h @@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "irrlichttypes_extrabloated.h" #include <iostream> #include "constants.h" +#include "cloudparams.h" // Menu clouds class Clouds; @@ -79,27 +80,68 @@ public: void updateCameraOffset(v3s16 camera_offset) { m_camera_offset = camera_offset; - m_box = aabb3f(-BS * 1000000, m_cloud_y - BS - BS * camera_offset.Y, -BS * 1000000, - BS * 1000000, m_cloud_y + BS - BS * camera_offset.Y, BS * 1000000); + updateBox(); } void readSettings(); + void setDensity(float density) + { + m_params.density = density; + // currently does not need bounding + } + + void setColorBright(const video::SColor &color_bright) + { + m_params.color_bright = color_bright; + } + + void setColorAmbient(const video::SColor &color_ambient) + { + m_params.color_ambient = color_ambient; + } + + void setHeight(float height) + { + m_params.height = height; // add bounding when necessary + updateBox(); + } + + void setSpeed(v2f speed) + { + m_params.speed = speed; + } + + void setThickness(float thickness) + { + m_params.thickness = thickness; + updateBox(); + } + private: + void updateBox() + { + float height_bs = m_params.height * BS; + float thickness_bs = m_params.thickness * BS; + m_box = aabb3f(-BS * 1000000.0f, height_bs - BS * m_camera_offset.Y, -BS * 1000000.0f, + BS * 1000000.0f, height_bs + thickness_bs - BS * m_camera_offset.Y, BS * 1000000.0f); + } + video::SMaterial m_material; aabb3f m_box; s16 m_passed_cloud_y; - float m_cloud_y; u16 m_cloud_radius_i; bool m_enable_3d; - video::SColorf m_color; u32 m_seed; v2f m_camera_pos; - float m_time; + v2f m_origin; + v2f m_speed; v3s16 m_camera_offset; + video::SColorf m_color; + CloudParams m_params; + }; #endif - diff --git a/src/game.cpp b/src/game.cpp index a1cc1ab15..ba6530d80 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -3295,6 +3295,19 @@ void Game::processClientEvents(CameraOrientation *cam) event.override_day_night_ratio.ratio_f * 1000); break; + case CE_CLOUD_PARAMS: + if (clouds) { + clouds->setDensity(event.cloud_params.density); + clouds->setColorBright(video::SColor(event.cloud_params.color_bright)); + clouds->setColorAmbient(video::SColor(event.cloud_params.color_ambient)); + clouds->setHeight(event.cloud_params.height); + clouds->setThickness(event.cloud_params.thickness); + clouds->setSpeed(v2f( + event.cloud_params.speed_x, + event.cloud_params.speed_y)); + } + break; + default: // unknown or unhandled type break; diff --git a/src/network/clientopcodes.cpp b/src/network/clientopcodes.cpp index 563baf77b..1be6e5522 100644 --- a/src/network/clientopcodes.cpp +++ b/src/network/clientopcodes.cpp @@ -108,7 +108,7 @@ const ToClientCommandHandler toClientCommandTable[TOCLIENT_NUM_MSG_TYPES] = { "TOCLIENT_LOCAL_PLAYER_ANIMATIONS", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_LocalPlayerAnimations }, // 0x51 { "TOCLIENT_EYE_OFFSET", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_EyeOffset }, // 0x52 { "TOCLIENT_DELETE_PARTICLESPAWNER", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_DeleteParticleSpawner }, // 0x53 - null_command_handler, + { "TOCLIENT_CLOUD_PARAMS", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_CloudParams }, // 0x54 null_command_handler, null_command_handler, null_command_handler, diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 772ffe905..defc83f31 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -1168,6 +1168,34 @@ void Client::handleCommand_HudSetSky(NetworkPacket* pkt) m_client_event_queue.push(event); } +void Client::handleCommand_CloudParams(NetworkPacket* pkt) +{ + f32 density; + video::SColor color_bright; + video::SColor color_ambient; + f32 height; + f32 thickness; + v2f speed; + + *pkt >> density >> color_bright >> color_ambient + >> height >> thickness >> speed; + + ClientEvent event; + event.type = CE_CLOUD_PARAMS; + event.cloud_params.density = density; + // use the underlying u32 representation, because we can't + // use struct members with constructors here, and this way + // we avoid using new() and delete() for no good reason + event.cloud_params.color_bright = color_bright.color; + event.cloud_params.color_ambient = color_ambient.color; + event.cloud_params.height = height; + event.cloud_params.thickness = thickness; + // same here: deconstruct to skip constructor + event.cloud_params.speed_x = speed.X; + event.cloud_params.speed_y = speed.Y; + m_client_event_queue.push(event); +} + void Client::handleCommand_OverrideDayNightRatio(NetworkPacket* pkt) { bool do_override; diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h index e7a3469b7..a1a4f5bfa 100644 --- a/src/network/networkprotocol.h +++ b/src/network/networkprotocol.h @@ -610,6 +610,16 @@ enum ToClientCommand u32 id */ + TOCLIENT_CLOUD_PARAMS = 0x54, + /* + f1000 density + u8[4] color_diffuse (ARGB) + u8[4] color_ambient (ARGB) + f1000 height + f1000 thickness + v2f1000 speed + */ + TOCLIENT_SRP_BYTES_S_B = 0x60, /* Belonging to AUTH_MECHANISM_LEGACY_PASSWORD and AUTH_MECHANISM_SRP. diff --git a/src/network/serveropcodes.cpp b/src/network/serveropcodes.cpp index 31b571ff0..450730ca2 100644 --- a/src/network/serveropcodes.cpp +++ b/src/network/serveropcodes.cpp @@ -197,7 +197,7 @@ const ClientCommandFactory clientCommandFactoryTable[TOCLIENT_NUM_MSG_TYPES] = { "TOCLIENT_LOCAL_PLAYER_ANIMATIONS", 0, true }, // 0x51 { "TOCLIENT_EYE_OFFSET", 0, true }, // 0x52 { "TOCLIENT_DELETE_PARTICLESPAWNER", 0, true }, // 0x53 - null_command_factory, + { "TOCLIENT_CLOUD_PARAMS", 0, true }, // 0x54 null_command_factory, null_command_factory, null_command_factory, diff --git a/src/remoteplayer.cpp b/src/remoteplayer.cpp index 2dbfe9d9d..2b4db62f5 100644 --- a/src/remoteplayer.cpp +++ b/src/remoteplayer.cpp @@ -65,6 +65,14 @@ RemotePlayer::RemotePlayer(const char *name, IItemDefManager *idef): movement_liquid_fluidity_smooth = g_settings->getFloat("movement_liquid_fluidity_smooth") * BS; movement_liquid_sink = g_settings->getFloat("movement_liquid_sink") * BS; movement_gravity = g_settings->getFloat("movement_gravity") * BS; + + // copy defaults + m_cloud_params.density = 0.4f; + m_cloud_params.color_bright = video::SColor(255, 255, 240, 240); + m_cloud_params.color_ambient = video::SColor(255, 0, 0, 0); + m_cloud_params.height = 120.0f; + m_cloud_params.thickness = 16.0f; + m_cloud_params.speed = v2f(0.0f, -2.0f); } void RemotePlayer::serializeExtraAttributes(std::string &output) diff --git a/src/remoteplayer.h b/src/remoteplayer.h index 4b96835fc..b9d9c74f5 100644 --- a/src/remoteplayer.h +++ b/src/remoteplayer.h @@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #define REMOTEPLAYER_HEADER #include "player.h" +#include "cloudparams.h" class PlayerSAO; @@ -99,6 +100,16 @@ public: *params = m_sky_params; } + void setCloudParams(const CloudParams &cloud_params) + { + m_cloud_params = cloud_params; + } + + const CloudParams &getCloudParams() const + { + return m_cloud_params; + } + bool checkModified() const { return m_dirty || inventory.checkModified(); } void setModified(const bool x) @@ -154,6 +165,7 @@ private: std::string m_sky_type; video::SColor m_sky_bgcolor; std::vector<std::string> m_sky_params; + CloudParams m_cloud_params; }; #endif diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index a5b6e3941..6cd852299 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -1729,6 +1729,85 @@ int ObjectRef::l_get_sky(lua_State *L) return 3; } +// set_clouds(self, {density=, color=, ambient=, height=, thickness=, speed=}) +int ObjectRef::l_set_clouds(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (!player) + return 0; + if (!lua_istable(L, 2)) + return 0; + + CloudParams cloud_params = player->getCloudParams(); + + cloud_params.density = getfloatfield_default(L, 2, "density", cloud_params.density); + + lua_getfield(L, 2, "color"); + if (!lua_isnil(L, -1)) + read_color(L, -1, &cloud_params.color_bright); + lua_pop(L, 1); + lua_getfield(L, 2, "ambient"); + if (!lua_isnil(L, -1)) + read_color(L, -1, &cloud_params.color_ambient); + lua_pop(L, 1); + + cloud_params.height = getfloatfield_default(L, 2, "height", cloud_params.height ); + cloud_params.thickness = getfloatfield_default(L, 2, "thickness", cloud_params.thickness); + + lua_getfield(L, 2, "speed"); + if (lua_istable(L, -1)) { + v2f new_speed; + new_speed.X = getfloatfield_default(L, -1, "x", 0); + new_speed.Y = getfloatfield_default(L, -1, "y", 0); + cloud_params.speed = new_speed; + } + lua_pop(L, 1); + + if (!getServer(L)->setClouds(player, cloud_params.density, + cloud_params.color_bright, cloud_params.color_ambient, + cloud_params.height, cloud_params.thickness, + cloud_params.speed)) + return 0; + + player->setCloudParams(cloud_params); + + lua_pushboolean(L, true); + return 1; +} + +int ObjectRef::l_get_clouds(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (!player) + return 0; + const CloudParams &cloud_params = player->getCloudParams(); + + lua_newtable(L); + lua_pushnumber(L, cloud_params.density); + lua_setfield(L, -2, "density"); + push_ARGB8(L, cloud_params.color_bright); + lua_setfield(L, -2, "color"); + push_ARGB8(L, cloud_params.color_ambient); + lua_setfield(L, -2, "ambient"); + lua_pushnumber(L, cloud_params.height); + lua_setfield(L, -2, "height"); + lua_pushnumber(L, cloud_params.thickness); + lua_setfield(L, -2, "thickness"); + lua_newtable(L); + lua_pushnumber(L, cloud_params.speed.X); + lua_setfield(L, -2, "x"); + lua_pushnumber(L, cloud_params.speed.Y); + lua_setfield(L, -2, "y"); + lua_setfield(L, -2, "speed"); + + return 1; +} + + // override_day_night_ratio(self, brightness=0...1) int ObjectRef::l_override_day_night_ratio(lua_State *L) { @@ -1911,6 +1990,8 @@ const luaL_Reg ObjectRef::methods[] = { luamethod(ObjectRef, hud_get_hotbar_selected_image), luamethod(ObjectRef, set_sky), luamethod(ObjectRef, get_sky), + luamethod(ObjectRef, set_clouds), + luamethod(ObjectRef, get_clouds), luamethod(ObjectRef, override_day_night_ratio), luamethod(ObjectRef, get_day_night_ratio), luamethod(ObjectRef, set_local_animation), diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h index 98f5c2b11..0912a1c49 100644 --- a/src/script/lua_api/l_object.h +++ b/src/script/lua_api/l_object.h @@ -289,6 +289,12 @@ private: // get_sky(self, type, list) static int l_get_sky(lua_State *L); + // set_clouds(self, {density=, color=, ambient=, height=, thickness=, speed=}) + static int l_set_clouds(lua_State *L); + + // get_clouds(self) + static int l_get_clouds(lua_State *L); + // override_day_night_ratio(self, type) static int l_override_day_night_ratio(lua_State *L); diff --git a/src/server.cpp b/src/server.cpp index 2edf83947..9ef69cb37 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1882,6 +1882,20 @@ void Server::SendSetSky(u16 peer_id, const video::SColor &bgcolor, Send(&pkt); } +void Server::SendCloudParams(u16 peer_id, float density, + const video::SColor &color_bright, + const video::SColor &color_ambient, + float height, + float thickness, + const v2f &speed) +{ + NetworkPacket pkt(TOCLIENT_CLOUD_PARAMS, 0, peer_id); + pkt << density << color_bright << color_ambient + << height << thickness << speed; + + Send(&pkt); +} + void Server::SendOverrideDayNightRatio(u16 peer_id, bool do_override, float ratio) { @@ -3196,6 +3210,22 @@ bool Server::setSky(RemotePlayer *player, const video::SColor &bgcolor, return true; } +bool Server::setClouds(RemotePlayer *player, float density, + const video::SColor &color_bright, + const video::SColor &color_ambient, + float height, + float thickness, + const v2f &speed) +{ + if (!player) + return false; + + SendCloudParams(player->peer_id, density, + color_bright, color_ambient, height, + thickness, speed); + return true; +} + bool Server::overrideDayNightRatio(RemotePlayer *player, bool do_override, float ratio) { diff --git a/src/server.h b/src/server.h index 948fb8fc2..3a082b9a4 100644 --- a/src/server.h +++ b/src/server.h @@ -332,6 +332,12 @@ public: bool setSky(RemotePlayer *player, const video::SColor &bgcolor, const std::string &type, const std::vector<std::string> ¶ms); + bool setClouds(RemotePlayer *player, float density, + const video::SColor &color_bright, + const video::SColor &color_ambient, + float height, + float thickness, + const v2f &speed); bool overrideDayNightRatio(RemotePlayer *player, bool do_override, float brightness); @@ -401,6 +407,12 @@ private: void SendHUDSetParam(u16 peer_id, u16 param, const std::string &value); void SendSetSky(u16 peer_id, const video::SColor &bgcolor, const std::string &type, const std::vector<std::string> ¶ms); + void SendCloudParams(u16 peer_id, float density, + const video::SColor &color_bright, + const video::SColor &color_ambient, + float height, + float thickness, + const v2f &speed); void SendOverrideDayNightRatio(u16 peer_id, bool do_override, float ratio); /* diff --git a/src/sky.cpp b/src/sky.cpp index 211a2dcdc..7f999feb0 100644 --- a/src/sky.cpp +++ b/src/sky.cpp @@ -534,8 +534,10 @@ void Sky::update(float time_of_day, float time_brightness, video::SColorf skycolor_bright_dawn_f = video::SColor(255, 180, 186, 250); video::SColorf skycolor_bright_night_f = video::SColor(255, 0, 107, 255); - video::SColorf cloudcolor_bright_normal_f = video::SColor(255, 240, 240, 255); - video::SColorf cloudcolor_bright_dawn_f = video::SColor(255, 255, 223, 191); + // pure white: becomes "diffuse light component" for clouds + video::SColorf cloudcolor_bright_normal_f = video::SColor(255, 255, 255, 255); + // dawn-factoring version of pure white (note: R is above 1.0) + video::SColorf cloudcolor_bright_dawn_f(255.0f/240.0f, 223.0f/240.0f, 191.0f/255.0f); float cloud_color_change_fraction = 0.95; if (sunlight_seen) { |