aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/lua_api.txt8
-rw-r--r--src/client.cpp19
-rw-r--r--src/client.h8
-rw-r--r--src/clientserver.h12
-rw-r--r--src/game.cpp36
-rw-r--r--src/script/lua_api/l_object.cpp40
-rw-r--r--src/script/lua_api/l_object.h3
-rw-r--r--src/server.cpp30
-rw-r--r--src/server.h7
-rw-r--r--src/sky.cpp5
-rw-r--r--src/sky.h18
11 files changed, 181 insertions, 5 deletions
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index 9d97dd6fa..beec54085 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -1812,6 +1812,14 @@ Player-only: (no-op for other objects)
^ sets background image for hotbar
- hud_set_hotbar_selected_image(texturename)
^ sets image for selected item of hotbar
+- set_sky(bgcolor, type, {texture names})
+ ^ bgcolor: {r=0...255, g=0...255, b=0...255} or nil, defaults to white
+ ^ Available types:
+ - "regular": Uses 0 textures, bgcolor ignored
+ - "skybox": Uses 6 textures, bgcolor used
+ - "plain": Uses 0 textures, bgcolor used
+ ^ Note: currently does not work directly in on_joinplayer; use
+ minetest.after(0) in there.
InvRef: Reference to an inventory
methods:
diff --git a/src/client.cpp b/src/client.cpp
index cc1ec2a98..48b00377f 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -2026,6 +2026,25 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
((LocalPlayer *) player)->hotbar_selected_image = value;
}
}
+ else if(command == TOCLIENT_SET_SKY)
+ {
+ std::string datastring((char *)&data[2], datasize - 2);
+ std::istringstream is(datastring, std::ios_base::binary);
+
+ video::SColor *bgcolor = new video::SColor(readARGB8(is));
+ std::string *type = new std::string(deSerializeString(is));
+ u16 count = readU16(is);
+ std::vector<std::string> *params = new std::vector<std::string>;
+ for(size_t i=0; i<count; i++)
+ params->push_back(deSerializeString(is));
+
+ ClientEvent event;
+ event.type = CE_SET_SKY;
+ event.set_sky.bgcolor = bgcolor;
+ event.set_sky.type = type;
+ event.set_sky.params = params;
+ m_client_event_queue.push_back(event);
+ }
else
{
infostream<<"Client: Ignoring unknown command "
diff --git a/src/client.h b/src/client.h
index 9a788dfca..33d806f9f 100644
--- a/src/client.h
+++ b/src/client.h
@@ -133,7 +133,8 @@ enum ClientEventType
CE_DELETE_PARTICLESPAWNER,
CE_HUDADD,
CE_HUDRM,
- CE_HUDCHANGE
+ CE_HUDCHANGE,
+ CE_SET_SKY,
};
struct ClientEvent
@@ -217,6 +218,11 @@ struct ClientEvent
u32 data;
v3f *v3fdata;
} hudchange;
+ struct{
+ video::SColor *bgcolor;
+ std::string *type;
+ std::vector<std::string> *params;
+ } set_sky;
};
};
diff --git a/src/clientserver.h b/src/clientserver.h
index 0d66e1b50..ecdc644dc 100644
--- a/src/clientserver.h
+++ b/src/clientserver.h
@@ -507,6 +507,18 @@ enum ToClientCommand
u16 command
u16 breath
*/
+
+ TOCLIENT_SET_SKY = 0x4f,
+ /*
+ u16 command
+ u8[4] color (ARGB)
+ u8 len
+ u8[len] type
+ u16 count
+ foreach count:
+ u8 len
+ u8[len] param
+ */
};
enum ToServerCommand
diff --git a/src/game.cpp b/src/game.cpp
index 407672ac2..ef694b6af 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -1337,6 +1337,8 @@ void the_game(
Sky *sky = NULL;
sky = new Sky(smgr->getRootSceneNode(), smgr, -1, client.getEnv().getLocalPlayer());
+
+ scene::ISceneNode* skybox = NULL;
/*
A copy of the local inventory
@@ -2462,6 +2464,40 @@ void the_game(
delete event.hudchange.v2fdata;
delete event.hudchange.sdata;
}
+ else if (event.type == CE_SET_SKY)
+ {
+ sky->setVisible(false);
+ if(skybox){
+ skybox->drop();
+ skybox = NULL;
+ }
+ // Handle according to type
+ if(*event.set_sky.type == "regular"){
+ sky->setVisible(true);
+ }
+ else if(*event.set_sky.type == "skybox" &&
+ event.set_sky.params->size() == 6){
+ sky->setFallbackBgColor(*event.set_sky.bgcolor);
+ skybox = smgr->addSkyBoxSceneNode(
+ tsrc->getTexture((*event.set_sky.params)[0]),
+ tsrc->getTexture((*event.set_sky.params)[1]),
+ tsrc->getTexture((*event.set_sky.params)[2]),
+ tsrc->getTexture((*event.set_sky.params)[3]),
+ tsrc->getTexture((*event.set_sky.params)[4]),
+ tsrc->getTexture((*event.set_sky.params)[5]));
+ }
+ // Handle everything else as plain color
+ else {
+ if(*event.set_sky.type != "plain")
+ infostream<<"Unknown sky type: "
+ <<(*event.set_sky.type)<<std::endl;
+ sky->setFallbackBgColor(*event.set_sky.bgcolor);
+ }
+
+ delete event.set_sky.bgcolor;
+ delete event.set_sky.type;
+ delete event.set_sky.params;
+ }
}
}
diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp
index 6c6415a09..86e5a71cd 100644
--- a/src/script/lua_api/l_object.cpp
+++ b/src/script/lua_api/l_object.cpp
@@ -1090,6 +1090,45 @@ int ObjectRef::l_hud_set_hotbar_selected_image(lua_State *L)
return 1;
}
+// set_sky(self, bgcolor, type, list)
+int ObjectRef::l_set_sky(lua_State *L)
+{
+ ObjectRef *ref = checkobject(L, 1);
+ Player *player = getplayer(ref);
+ if (player == NULL)
+ return 0;
+
+ video::SColor bgcolor(255,255,255,255);
+ if (!lua_isnil(L, 2))
+ bgcolor = readARGB8(L, 2);
+
+ std::string type = luaL_checkstring(L, 3);
+
+ std::vector<std::string> params;
+ if (lua_istable(L, 4)) {
+ int table = lua_gettop(L);
+ lua_pushnil(L);
+ while (lua_next(L, table) != 0) {
+ // key at index -2 and value at index -1
+ if (lua_isstring(L, -1))
+ params.push_back(lua_tostring(L, -1));
+ else
+ params.push_back("");
+ // removes value, keeps key for next iteration
+ lua_pop(L, 1);
+ }
+ }
+
+ if (type == "skybox" && params.size() != 6)
+ throw LuaError(L, "skybox expects 6 textures");
+
+ if (!getServer(L)->setSky(player, bgcolor, type, params))
+ return 0;
+
+ lua_pushboolean(L, true);
+ return 1;
+}
+
ObjectRef::ObjectRef(ServerActiveObject *object):
m_object(object)
{
@@ -1207,5 +1246,6 @@ const luaL_reg ObjectRef::methods[] = {
luamethod(ObjectRef, hud_set_hotbar_itemcount),
luamethod(ObjectRef, hud_set_hotbar_image),
luamethod(ObjectRef, hud_set_hotbar_selected_image),
+ luamethod(ObjectRef, set_sky),
{0,0}
};
diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h
index c8c67f2c5..b41938ca7 100644
--- a/src/script/lua_api/l_object.h
+++ b/src/script/lua_api/l_object.h
@@ -225,6 +225,9 @@ private:
// hud_set_hotbar_selected_image(self, name)
static int l_hud_set_hotbar_selected_image(lua_State *L);
+ // set_sky(self, type, list)
+ static int l_set_sky(lua_State *L);
+
public:
ObjectRef(ServerActiveObject *object);
diff --git a/src/server.cpp b/src/server.cpp
index ce0b44110..644aec1f5 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -3271,6 +3271,26 @@ void Server::SendHUDSetParam(u16 peer_id, u16 param, const std::string &value)
m_clients.send(peer_id, 0, data, true);
}
+void Server::SendSetSky(u16 peer_id, const video::SColor &bgcolor,
+ const std::string &type, const std::vector<std::string> &params)
+{
+ std::ostringstream os(std::ios_base::binary);
+
+ // Write command
+ writeU16(os, TOCLIENT_SET_SKY);
+ writeARGB8(os, bgcolor);
+ os<<serializeString(type);
+ writeU16(os, params.size());
+ for(size_t i=0; i<params.size(); i++)
+ os<<serializeString(params[i]);
+
+ // Make data buffer
+ std::string s = os.str();
+ SharedBuffer<u8> data((u8 *)s.c_str(), s.size());
+ // Send as reliable
+ m_clients.send(peer_id, 0, data, true);
+}
+
void Server::SendTimeOfDay(u16 peer_id, u16 time, f32 time_speed)
{
DSTACK(__FUNCTION_NAME);
@@ -4435,6 +4455,16 @@ void Server::hudSetHotbarSelectedImage(Player *player, std::string name) {
SendHUDSetParam(player->peer_id, HUD_PARAM_HOTBAR_SELECTED_IMAGE, name);
}
+bool Server::setSky(Player *player, const video::SColor &bgcolor,
+ const std::string &type, const std::vector<std::string> &params)
+{
+ if (!player)
+ return false;
+
+ SendSetSky(player->peer_id, bgcolor, type, params);
+ return true;
+}
+
void Server::notifyPlayers(const std::wstring msg)
{
SendChatMessage(PEER_ID_INEXISTENT,msg);
diff --git a/src/server.h b/src/server.h
index 94b0b6a2d..e493c5ea9 100644
--- a/src/server.h
+++ b/src/server.h
@@ -319,6 +319,9 @@ public:
inline Address getPeerAddress(u16 peer_id)
{ return m_con.GetPeerAddress(peer_id); }
+
+ bool setSky(Player *player, const video::SColor &bgcolor,
+ const std::string &type, const std::vector<std::string> &params);
/* con::PeerHandler implementation. */
void peerAdded(con::Peer *peer);
@@ -355,7 +358,9 @@ private:
void SendHUDChange(u16 peer_id, u32 id, HudElementStat stat, void *value);
void SendHUDSetFlags(u16 peer_id, u32 flags, u32 mask);
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> &params);
+
/*
Send a node removal/addition event to all clients except ignore_id.
Additionally, if far_players!=NULL, players further away than
diff --git a/src/sky.cpp b/src/sky.cpp
index e8fd3a1d8..3ba9a44c0 100644
--- a/src/sky.cpp
+++ b/src/sky.cpp
@@ -14,6 +14,8 @@
//! constructor
Sky::Sky(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id, LocalPlayer* player):
scene::ISceneNode(parent, mgr, id),
+ m_visible(true),
+ m_fallback_bg_color(255,255,255,255),
m_first_update(true),
m_brightness(0.5),
m_cloud_brightness(0.5),
@@ -77,6 +79,9 @@ const core::aabbox3d<f32>& Sky::getBoundingBox() const
//! renders the node.
void Sky::render()
{
+ if(!m_visible)
+ return;
+
video::IVideoDriver* driver = SceneManager->getVideoDriver();
scene::ICameraSceneNode* camera = SceneManager->getActiveCamera();
diff --git a/src/sky.h b/src/sky.h
index 9de9d9947..06a993103 100644
--- a/src/sky.h
+++ b/src/sky.h
@@ -53,12 +53,22 @@ public:
float direct_brightness, bool sunlight_seen);
float getBrightness(){ return m_brightness; }
- video::SColor getBgColor(){ return m_bgcolor; }
- video::SColor getSkyColor(){ return m_skycolor; }
+
+ video::SColor getBgColor(){
+ return m_visible ? m_bgcolor : m_fallback_bg_color;
+ }
+ video::SColor getSkyColor(){
+ return m_visible ? m_skycolor : m_fallback_bg_color;
+ }
- bool getCloudsVisible(){ return m_clouds_visible; }
+ bool getCloudsVisible(){ return m_clouds_visible && m_visible; }
video::SColorf getCloudColor(){ return m_cloudcolor_f; }
+ void setVisible(bool visible){ m_visible = visible; }
+ void setFallbackBgColor(const video::SColor &fallback_bg_color){
+ m_fallback_bg_color = fallback_bg_color;
+ }
+
private:
core::aabbox3d<f32> Box;
video::SMaterial m_materials[SKY_MATERIAL_COUNT];
@@ -98,6 +108,8 @@ private:
return result;
}
+ bool m_visible;
+ video::SColor m_fallback_bg_color; // Used when m_visible=false
bool m_first_update;
float m_time_of_day;
float m_time_brightness;