Add player:set_sky() with simple skybox support

pull/1122/head
Perttu Ahola 2013-05-02 23:52:50 +03:00 committed by sapier
parent e258675eab
commit 86a6cca3cf
11 changed files with 181 additions and 5 deletions

View File

@ -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:

View File

@ -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 "

View File

@ -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;
};
};

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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}
};

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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();

View File

@ -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;