X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fscript%2Flua_api%2Fl_object.cpp;h=23ed1ffe005f81fed662fe3be849fb937574df89;hb=a87805a9445f280ca71da322c4b32cf357744511;hp=7d2eba8e252e28a5e46075ec3227d7b61e512781;hpb=c50a57c070749f6b58c1490539cb6ff6e4289315;p=dragonfireclient.git diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index 7d2eba8e2..23ed1ffe0 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -18,56 +18,22 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "lua_api/l_object.h" +#include #include "lua_api/l_internal.h" #include "lua_api/l_inventory.h" #include "lua_api/l_item.h" +#include "lua_api/l_playermeta.h" #include "common/c_converter.h" #include "common/c_content.h" #include "log.h" #include "tool.h" #include "serverobject.h" #include "content_sao.h" +#include "remoteplayer.h" #include "server.h" #include "hud.h" #include "scripting_server.h" -struct EnumString es_HudElementType[] = -{ - {HUD_ELEM_IMAGE, "image"}, - {HUD_ELEM_TEXT, "text"}, - {HUD_ELEM_STATBAR, "statbar"}, - {HUD_ELEM_INVENTORY, "inventory"}, - {HUD_ELEM_WAYPOINT, "waypoint"}, -{0, NULL}, -}; - -struct EnumString es_HudElementStat[] = -{ - {HUD_STAT_POS, "position"}, - {HUD_STAT_POS, "pos"}, /* Deprecated, only for compatibility's sake */ - {HUD_STAT_NAME, "name"}, - {HUD_STAT_SCALE, "scale"}, - {HUD_STAT_TEXT, "text"}, - {HUD_STAT_NUMBER, "number"}, - {HUD_STAT_ITEM, "item"}, - {HUD_STAT_DIR, "direction"}, - {HUD_STAT_ALIGN, "alignment"}, - {HUD_STAT_OFFSET, "offset"}, - {HUD_STAT_WORLD_POS, "world_pos"}, - {0, NULL}, -}; - -struct EnumString es_HudBuiltinElement[] = -{ - {HUD_FLAG_HOTBAR_VISIBLE, "hotbar"}, - {HUD_FLAG_HEALTHBAR_VISIBLE, "healthbar"}, - {HUD_FLAG_CROSSHAIR_VISIBLE, "crosshair"}, - {HUD_FLAG_WIELDITEM_VISIBLE, "wielditem"}, - {HUD_FLAG_BREATHBAR_VISIBLE, "breathbar"}, - {HUD_FLAG_MINIMAP_VISIBLE, "minimap"}, - {0, NULL}, -}; - /* ObjectRef */ @@ -94,6 +60,8 @@ LuaEntitySAO* ObjectRef::getluaobject(ObjectRef *ref) return NULL; if (obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY) return NULL; + if (obj->isGone()) + return NULL; return (LuaEntitySAO*)obj; } @@ -104,6 +72,8 @@ PlayerSAO* ObjectRef::getplayersao(ObjectRef *ref) return NULL; if (obj->getType() != ACTIVEOBJECT_TYPE_PLAYER) return NULL; + if (obj->isGone()) + return NULL; return (PlayerSAO*)obj; } @@ -137,16 +107,11 @@ int ObjectRef::l_remove(lua_State *L) if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER) return 0; - const std::unordered_set &child_ids = co->getAttachmentChildIds(); - std::unordered_set::const_iterator it; - for (it = child_ids.begin(); it != child_ids.end(); ++it) { - // Child can be NULL if it was deleted earlier - if (ServerActiveObject *child = env->getActiveObject(*it)) - child->setAttachment(0, "", v3f(0, 0, 0), v3f(0, 0, 0)); - } + co->clearChildAttachments(); + co->clearParentAttachment(); - verbosestream<<"ObjectRef::l_remove(): id="<getId()<m_removed = true; + verbosestream << "ObjectRef::l_remove(): id=" << co->getId() << std::endl; + co->m_pending_removal = true; return 0; } @@ -195,7 +160,7 @@ int ObjectRef::l_move_to(lua_State *L) // pos v3f pos = checkFloatPos(L, 2); // continuous - bool continuous = lua_toboolean(L, 3); + bool continuous = readParam(L, 3); // Do it co->moveTo(pos, continuous); return 0; @@ -209,8 +174,8 @@ int ObjectRef::l_punch(lua_State *L) ObjectRef *puncher_ref = checkobject(L, 2); ServerActiveObject *co = getobject(ref); ServerActiveObject *puncher = getobject(puncher_ref); - if (co == NULL) return 0; - if (puncher == NULL) return 0; + if (!co || !puncher) + return 0; v3f dir; if (lua_type(L, 5) != LUA_TTABLE) dir = co->getBasePosition() - puncher->getBasePosition(); @@ -222,24 +187,27 @@ int ObjectRef::l_punch(lua_State *L) ToolCapabilities toolcap = read_tool_capabilities(L, 4); dir.normalize(); - s16 src_original_hp = co->getHP(); - s16 dst_origin_hp = puncher->getHP(); + u16 src_original_hp = co->getHP(); + u16 dst_origin_hp = puncher->getHP(); // Do it - co->punch(dir, &toolcap, puncher, time_from_last_punch); + u16 wear = co->punch(dir, &toolcap, puncher, time_from_last_punch); + lua_pushnumber(L, wear); // If the punched is a player, and its HP changed if (src_original_hp != co->getHP() && co->getType() == ACTIVEOBJECT_TYPE_PLAYER) { - getServer(L)->SendPlayerHPOrDie((PlayerSAO *)co); + getServer(L)->SendPlayerHPOrDie((PlayerSAO *)co, + PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, puncher)); } // If the puncher is a player, and its HP changed if (dst_origin_hp != puncher->getHP() && puncher->getType() == ACTIVEOBJECT_TYPE_PLAYER) { - getServer(L)->SendPlayerHPOrDie((PlayerSAO *)puncher); + getServer(L)->SendPlayerHPOrDie((PlayerSAO *)puncher, + PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, co)); } - return 0; + return 1; } // right_click(self, clicker); clicker = an another ObjectRef @@ -263,17 +231,40 @@ int ObjectRef::l_right_click(lua_State *L) int ObjectRef::l_set_hp(lua_State *L) { NO_MAP_LOCK_REQUIRED; + + // Get Object ObjectRef *ref = checkobject(L, 1); luaL_checknumber(L, 2); ServerActiveObject *co = getobject(ref); - if (co == NULL) return 0; + if (co == NULL) + return 0; + + // Get HP int hp = lua_tonumber(L, 2); - /*infostream<<"ObjectRef::l_set_hp(): id="<getId() - <<" hp="<(L, -1))) { + errorstream << "Bad type given!" << std::endl; + } + lua_pop(L, 1); + + reason.lua_reference = luaL_ref(L, LUA_REGISTRYINDEX); + } + // Do it - co->setHP(hp); + co->setHP(hp, reason); if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER) - getServer(L)->SendPlayerHPOrDie((PlayerSAO *)co); + getServer(L)->SendPlayerHPOrDie((PlayerSAO *)co, reason); + + if (reason.hasLuaReference()) + luaL_unref(L, LUA_REGISTRYINDEX, reason.lua_reference); // Return return 0; @@ -322,8 +313,9 @@ int ObjectRef::l_get_wield_list(lua_State *L) NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); ServerActiveObject *co = getobject(ref); - if (co == NULL) return 0; - // Do it + if (!co) + return 0; + lua_pushstring(L, co->getWieldList().c_str()); return 1; } @@ -334,8 +326,9 @@ int ObjectRef::l_get_wield_index(lua_State *L) NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); ServerActiveObject *co = getobject(ref); - if (co == NULL) return 0; - // Do it + if (!co) + return 0; + lua_pushinteger(L, co->getWieldIndex() + 1); return 1; } @@ -346,13 +339,15 @@ int ObjectRef::l_get_wielded_item(lua_State *L) NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); ServerActiveObject *co = getobject(ref); - if (co == NULL) { + if (!co) { // Empty ItemStack LuaItemStack::create(L, ItemStack()); return 1; } - // Do it - LuaItemStack::create(L, co->getWieldedItem()); + + ItemStack selected_item; + co->getWieldedItem(&selected_item, nullptr); + LuaItemStack::create(L, selected_item); return 1; } @@ -367,7 +362,7 @@ int ObjectRef::l_set_wielded_item(lua_State *L) ItemStack item = read_item(L, 2, getServer(L)->idef()); bool success = co->setWieldedItem(item); if (success && co->getType() == ACTIVEOBJECT_TYPE_PLAYER) { - getServer(L)->SendInventory(((PlayerSAO*)co)); + getServer(L)->SendInventory((PlayerSAO *)co, true); } lua_pushboolean(L, success); return 1; @@ -476,7 +471,7 @@ int ObjectRef::l_set_animation(lua_State *L) // Do it v2f frames = v2f(1, 1); if (!lua_isnil(L, 2)) - frames = read_v2f(L, 2); + frames = readParam(L, 2); float frame_speed = 15; if (!lua_isnil(L, 3)) frame_speed = lua_tonumber(L, 3); @@ -485,7 +480,7 @@ int ObjectRef::l_set_animation(lua_State *L) frame_blend = lua_tonumber(L, 4); bool frame_loop = true; if (lua_isboolean(L, 5)) - frame_loop = lua_toboolean(L, 5); + frame_loop = readParam(L, 5); co->setAnimation(frames, frame_speed, frame_blend, frame_loop); return 0; } @@ -530,11 +525,9 @@ int ObjectRef::l_set_local_animation(lua_State *L) if (!lua_isnil(L, 6)) frame_speed = lua_tonumber(L, 6); - if (!getServer(L)->setLocalPlayerAnimations(player, frames, frame_speed)) - return 0; - + getServer(L)->setLocalPlayerAnimations(player, frames, frame_speed); lua_pushboolean(L, true); - return 0; + return 1; } // get_local_animation(self) @@ -550,8 +543,8 @@ int ObjectRef::l_get_local_animation(lua_State *L) float frame_speed; player->getLocalAnimations(frames, &frame_speed); - for (int i = 0; i < 4; i++) { - push_v2s32(L, frames[i]); + for (const v2s32 &frame : frames) { + push_v2s32(L, frame); } lua_pushnumber(L, frame_speed); @@ -581,11 +574,9 @@ int ObjectRef::l_set_eye_offset(lua_State *L) /* TODO: if possible: improve the camera colision detetion to allow Y <= -1.5) */ offset_third.Y = rangelim(offset_third.Y,-10,15); //1.5*BS - if (!getServer(L)->setPlayerEyeOffset(player, offset_first, offset_third)) - return 0; - + getServer(L)->setPlayerEyeOffset(player, offset_first, offset_third); lua_pushboolean(L, true); - return 0; + return 1; } // get_eye_offset(self) @@ -602,6 +593,44 @@ int ObjectRef::l_get_eye_offset(lua_State *L) return 2; } +// send_mapblock(self, pos) +int ObjectRef::l_send_mapblock(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + + RemotePlayer *player = getplayer(ref); + if (!player) + return 0; + v3s16 p = read_v3s16(L, 2); + + session_t peer_id = player->getPeerId(); + bool r = getServer(L)->SendBlock(peer_id, p); + + lua_pushboolean(L, r); + return 1; +} + +// set_animation_frame_speed(self, frame_speed) +int ObjectRef::l_set_animation_frame_speed(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + ServerActiveObject *co = getobject(ref); + if (co == NULL) + return 0; + + // Do it + if (!lua_isnil(L, 2)) { + float frame_speed = lua_tonumber(L, 2); + co->setAnimationSpeed(frame_speed); + lua_pushboolean(L, true); + } else { + lua_pushboolean(L, false); + } + return 1; +} + // set_bone_position(self, std::string bone, v3f position, v3f rotation) int ObjectRef::l_set_bone_position(lua_State *L) { @@ -610,9 +639,9 @@ int ObjectRef::l_set_bone_position(lua_State *L) ServerActiveObject *co = getobject(ref); if (co == NULL) return 0; // Do it - std::string bone = ""; + std::string bone; if (!lua_isnil(L, 2)) - bone = lua_tostring(L, 2); + bone = readParam(L, 2); v3f position = v3f(0, 0, 0); if (!lua_isnil(L, 3)) position = check_v3f(L, 3); @@ -632,9 +661,9 @@ int ObjectRef::l_get_bone_position(lua_State *L) if (co == NULL) return 0; // Do it - std::string bone = ""; + std::string bone; if (!lua_isnil(L, 2)) - bone = lua_tostring(L, 2); + bone = readParam(L, 2); v3f position = v3f(0, 0, 0); v3f rotation = v3f(0, 0, 0); @@ -660,7 +689,7 @@ int ObjectRef::l_set_attach(lua_State *L) return 0; // Do it int parent_id = 0; - std::string bone = ""; + std::string bone; v3f position = v3f(0, 0, 0); v3f rotation = v3f(0, 0, 0); co->getAttachment(&parent_id, &bone, &position, &rotation); @@ -671,7 +700,7 @@ int ObjectRef::l_set_attach(lua_State *L) bone = ""; if (!lua_isnil(L, 3)) - bone = lua_tostring(L, 3); + bone = readParam(L, 3); position = v3f(0, 0, 0); if (!lua_isnil(L, 4)) position = read_v3f(L, 4); @@ -695,7 +724,7 @@ int ObjectRef::l_get_attach(lua_State *L) // Do it int parent_id = 0; - std::string bone = ""; + std::string bone; v3f position = v3f(0, 0, 0); v3f rotation = v3f(0, 0, 0); co->getAttachment(&parent_id, &bone, &position, &rotation); @@ -720,21 +749,7 @@ int ObjectRef::l_set_detach(lua_State *L) if (co == NULL) return 0; - int parent_id = 0; - std::string bone = ""; - v3f position; - v3f rotation; - co->getAttachment(&parent_id, &bone, &position, &rotation); - ServerActiveObject *parent = NULL; - if (parent_id) { - parent = env->getActiveObject(parent_id); - co->setAttachment(0, "", position, rotation); - } else { - co->setAttachment(0, "", v3f(0, 0, 0), v3f(0, 0, 0)); - } - // Do it - if (parent != NULL) - parent->removeAttachmentChild(co->getId()); + co->clearParentAttachment(); return 0; } @@ -744,11 +759,14 @@ int ObjectRef::l_set_properties(lua_State *L) NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); ServerActiveObject *co = getobject(ref); - if (co == NULL) return 0; + if (!co) + return 0; + ObjectProperties *prop = co->accessObjectProperties(); if (!prop) return 0; - read_object_properties(L, 2, prop, getServer(L)->idef()); + + read_object_properties(L, 2, co, prop, getServer(L)->idef()); co->notifyObjectPropertiesModified(); return 0; } @@ -845,6 +863,20 @@ int ObjectRef::l_set_velocity(lua_State *L) return 0; } +// add_velocity(self, {x=num, y=num, z=num}) +int ObjectRef::l_add_velocity(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + LuaEntitySAO *co = getluaobject(ref); + if (!co) + return 0; + v3f pos = checkFloatPos(L, 2); + // Do it + co->addVelocity(pos); + return 0; +} + // get_velocity(self) int ObjectRef::l_get_velocity(lua_State *L) { @@ -885,16 +917,51 @@ int ObjectRef::l_get_acceleration(lua_State *L) return 1; } +// set_rotation(self, {x=num, y=num, z=num}) +// Each 'num' is in radians +int ObjectRef::l_set_rotation(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + LuaEntitySAO *co = getluaobject(ref); + if (!co) + return 0; + + v3f rotation = check_v3f(L, 2) * core::RADTODEG; + co->setRotation(rotation); + return 0; +} + +// get_rotation(self) +// returns: {x=num, y=num, z=num} +// Each 'num' is in radians +int ObjectRef::l_get_rotation(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + LuaEntitySAO *co = getluaobject(ref); + if (!co) + return 0; + + lua_newtable(L); + v3f rotation = co->getRotation() * core::DEGTORAD; + push_v3f(L, rotation); + return 1; +} + // set_yaw(self, radians) int ObjectRef::l_set_yaw(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); LuaEntitySAO *co = getluaobject(ref); + if (co == NULL) return 0; - float yaw = luaL_checknumber(L, 2) * core::RADTODEG; - // Do it - co->setYaw(yaw); + if (isNaN(L, 2)) + throw LuaError("ObjectRef::set_yaw: NaN value is not allowed."); + + float yaw = readParam(L, 2) * core::RADTODEG; + co->setRotation(v3f(0, yaw, 0)); return 0; } @@ -904,9 +971,10 @@ int ObjectRef::l_get_yaw(lua_State *L) NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); LuaEntitySAO *co = getluaobject(ref); - if (co == NULL) return 0; - // Do it - float yaw = co->getYaw() * core::DEGTORAD; + if (!co) + return 0; + + float yaw = co->getRotation().Y * core::DEGTORAD; lua_pushnumber(L, yaw); return 1; } @@ -948,7 +1016,7 @@ int ObjectRef::l_set_sprite(lua_State *L) // Do it v2s16 p(0,0); if (!lua_isnil(L, 2)) - p = read_v2s16(L, 2); + p = readParam(L, 2); int num_frames = 1; if (!lua_isnil(L, 3)) num_frames = lua_tonumber(L, 3); @@ -957,7 +1025,7 @@ int ObjectRef::l_set_sprite(lua_State *L) framelength = lua_tonumber(L, 4); bool select_horiz_by_yawpitch = false; if (!lua_isnil(L, 5)) - select_horiz_by_yawpitch = lua_toboolean(L, 5); + select_horiz_by_yawpitch = readParam(L, 5); co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch); return 0; } @@ -995,9 +1063,12 @@ int ObjectRef::l_get_luaentity(lua_State *L) int ObjectRef::l_is_player_connected(lua_State *L) { NO_MAP_LOCK_REQUIRED; + // This method was once added for a bugfix, but never documented + log_deprecated(L, "is_player_connected is undocumented and " + "will be removed in a future release"); ObjectRef *ref = checkobject(L, 1); RemotePlayer *player = getplayer(ref); - lua_pushboolean(L, (player != NULL && player->peer_id != 0)); + lua_pushboolean(L, (player != NULL && player->getPeerId() != PEER_ID_INEXISTENT)); return 1; } @@ -1031,6 +1102,27 @@ int ObjectRef::l_get_player_velocity(lua_State *L) return 1; } +// add_player_velocity(self, {x=num, y=num, z=num}) +int ObjectRef::l_add_player_velocity(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + v3f vel = checkFloatPos(L, 2); + + RemotePlayer *player = getplayer(ref); + PlayerSAO *co = getplayersao(ref); + if (!player || !co) + return 0; + + session_t peer_id = player->getPeerId(); + if (peer_id == PEER_ID_INEXISTENT) + return 0; + // Do it + co->setMaxSpeedOverride(vel); + getServer(L)->SendPlayerSpeed(peer_id, vel); + return 0; +} + // get_look_dir(self) int ObjectRef::l_get_look_dir(lua_State *L) { @@ -1039,9 +1131,10 @@ int ObjectRef::l_get_look_dir(lua_State *L) PlayerSAO* co = getplayersao(ref); if (co == NULL) return 0; // Do it - float pitch = co->getRadPitchDep(); + float pitch = co->getRadLookPitchDep(); float yaw = co->getRadYawDep(); - v3f v(cos(pitch)*cos(yaw), sin(pitch), cos(pitch)*sin(yaw)); + v3f v(std::cos(pitch) * std::cos(yaw), std::sin(pitch), std::cos(pitch) * + std::sin(yaw)); push_v3f(L, v); return 1; } @@ -1059,7 +1152,7 @@ int ObjectRef::l_get_look_pitch(lua_State *L) PlayerSAO* co = getplayersao(ref); if (co == NULL) return 0; // Do it - lua_pushnumber(L, co->getRadPitchDep()); + lua_pushnumber(L, co->getRadLookPitchDep()); return 1; } @@ -1088,7 +1181,7 @@ int ObjectRef::l_get_look_vertical(lua_State *L) PlayerSAO* co = getplayersao(ref); if (co == NULL) return 0; // Do it - lua_pushnumber(L, co->getRadPitch()); + lua_pushnumber(L, co->getRadLookPitch()); return 1; } @@ -1100,7 +1193,7 @@ int ObjectRef::l_get_look_horizontal(lua_State *L) PlayerSAO* co = getplayersao(ref); if (co == NULL) return 0; // Do it - lua_pushnumber(L, co->getRadYaw()); + lua_pushnumber(L, co->getRadRotation().Y); return 1; } @@ -1111,9 +1204,9 @@ int ObjectRef::l_set_look_vertical(lua_State *L) ObjectRef *ref = checkobject(L, 1); PlayerSAO* co = getplayersao(ref); if (co == NULL) return 0; - float pitch = luaL_checknumber(L, 2) * core::RADTODEG; + float pitch = readParam(L, 2) * core::RADTODEG; // Do it - co->setPitchAndSend(pitch); + co->setLookPitchAndSend(pitch); return 1; } @@ -1124,9 +1217,9 @@ int ObjectRef::l_set_look_horizontal(lua_State *L) ObjectRef *ref = checkobject(L, 1); PlayerSAO* co = getplayersao(ref); if (co == NULL) return 0; - float yaw = luaL_checknumber(L, 2) * core::RADTODEG; + float yaw = readParam(L, 2) * core::RADTODEG; // Do it - co->setYawAndSend(yaw); + co->setPlayerYawAndSend(yaw); return 1; } @@ -1142,9 +1235,9 @@ int ObjectRef::l_set_look_pitch(lua_State *L) ObjectRef *ref = checkobject(L, 1); PlayerSAO* co = getplayersao(ref); if (co == NULL) return 0; - float pitch = luaL_checknumber(L, 2) * core::RADTODEG; + float pitch = readParam(L, 2) * core::RADTODEG; // Do it - co->setPitchAndSend(pitch); + co->setLookPitchAndSend(pitch); return 1; } @@ -1160,12 +1253,43 @@ int ObjectRef::l_set_look_yaw(lua_State *L) ObjectRef *ref = checkobject(L, 1); PlayerSAO* co = getplayersao(ref); if (co == NULL) return 0; - float yaw = luaL_checknumber(L, 2) * core::RADTODEG; + float yaw = readParam(L, 2) * core::RADTODEG; // Do it - co->setYawAndSend(yaw); + co->setPlayerYawAndSend(yaw); return 1; } +// set_fov(self, degrees[, is_multiplier]) +int ObjectRef::l_set_fov(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (!player) + return 0; + + player->setFov({ static_cast(luaL_checknumber(L, 2)), readParam(L, 3) }); + getServer(L)->SendPlayerFov(player->getPeerId()); + + return 0; +} + +// get_fov(self) +int ObjectRef::l_get_fov(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (!player) + return 0; + + PlayerFovSpec fov_spec = player->getFov(); + lua_pushnumber(L, fov_spec.fov); + lua_pushboolean(L, fov_spec.is_multiplier); + + return 2; +} + // set_breath(self, breath) int ObjectRef::l_set_breath(lua_State *L) { @@ -1195,18 +1319,20 @@ int ObjectRef::l_get_breath(lua_State *L) // set_attribute(self, attribute, value) int ObjectRef::l_set_attribute(lua_State *L) { + log_deprecated(L, + "Deprecated call to set_attribute, use MetaDataRef methods instead."); + ObjectRef *ref = checkobject(L, 1); PlayerSAO* co = getplayersao(ref); - if (co == NULL) { + if (co == NULL) return 0; - } std::string attr = luaL_checkstring(L, 2); if (lua_isnil(L, 3)) { - co->removeExtendedAttribute(attr); + co->getMeta().removeString(attr); } else { std::string value = luaL_checkstring(L, 3); - co->setExtendedAttribute(attr, value); + co->getMeta().setString(attr, value); } return 1; } @@ -1214,16 +1340,18 @@ int ObjectRef::l_set_attribute(lua_State *L) // get_attribute(self, attribute) int ObjectRef::l_get_attribute(lua_State *L) { + log_deprecated(L, + "Deprecated call to get_attribute, use MetaDataRef methods instead."); + ObjectRef *ref = checkobject(L, 1); PlayerSAO* co = getplayersao(ref); - if (co == NULL) { + if (co == NULL) return 0; - } std::string attr = luaL_checkstring(L, 2); - std::string value = ""; - if (co->getExtendedAttribute(attr, &value)) { + std::string value; + if (co->getMeta().getStringToRef(attr, value)) { lua_pushstring(L, value.c_str()); return 1; } @@ -1232,6 +1360,19 @@ int ObjectRef::l_get_attribute(lua_State *L) } +// get_meta(self, attribute) +int ObjectRef::l_get_meta(lua_State *L) +{ + ObjectRef *ref = checkobject(L, 1); + PlayerSAO *co = getplayersao(ref); + if (co == NULL) + return 0; + + PlayerMetaRef::create(L, &co->getMeta()); + return 1; +} + + // set_inventory_formspec(self, formspec) int ObjectRef::l_set_inventory_formspec(lua_State *L) { @@ -1260,6 +1401,37 @@ int ObjectRef::l_get_inventory_formspec(lua_State *L) return 1; } +// set_formspec_prepend(self, formspec) +int ObjectRef::l_set_formspec_prepend(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == NULL) + return 0; + + std::string formspec = luaL_checkstring(L, 2); + + player->formspec_prepend = formspec; + getServer(L)->reportFormspecPrependModified(player->getName()); + lua_pushboolean(L, true); + return 1; +} + +// get_formspec_prepend(self) -> formspec +int ObjectRef::l_get_formspec_prepend(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == NULL) + return 0; + + std::string formspec = player->formspec_prepend; + lua_pushlstring(L, formspec.c_str(), formspec.size()); + return 1; +} + // get_player_control(self) int ObjectRef::l_get_player_control(lua_State *L) { @@ -1319,48 +1491,7 @@ int ObjectRef::l_hud_add(lua_State *L) return 0; HudElement *elem = new HudElement; - - elem->type = (HudElementType)getenumfield(L, 2, "hud_elem_type", - es_HudElementType, HUD_ELEM_TEXT); - - lua_getfield(L, 2, "position"); - elem->pos = lua_istable(L, -1) ? read_v2f(L, -1) : v2f(); - lua_pop(L, 1); - - lua_getfield(L, 2, "scale"); - elem->scale = lua_istable(L, -1) ? read_v2f(L, -1) : v2f(); - lua_pop(L, 1); - - lua_getfield(L, 2, "size"); - elem->size = lua_istable(L, -1) ? read_v2s32(L, -1) : v2s32(); - lua_pop(L, 1); - - elem->name = getstringfield_default(L, 2, "name", ""); - elem->text = getstringfield_default(L, 2, "text", ""); - elem->number = getintfield_default(L, 2, "number", 0); - elem->item = getintfield_default(L, 2, "item", 0); - elem->dir = getintfield_default(L, 2, "direction", 0); - - // Deprecated, only for compatibility's sake - if (elem->dir == 0) - elem->dir = getintfield_default(L, 2, "dir", 0); - - lua_getfield(L, 2, "alignment"); - elem->align = lua_istable(L, -1) ? read_v2f(L, -1) : v2f(); - lua_pop(L, 1); - - lua_getfield(L, 2, "offset"); - elem->offset = lua_istable(L, -1) ? read_v2f(L, -1) : v2f(); - lua_pop(L, 1); - - lua_getfield(L, 2, "world_pos"); - elem->world_pos = lua_istable(L, -1) ? read_v3f(L, -1) : v3f(); - lua_pop(L, 1); - - /* check for known deprecated element usage */ - if ((elem->type == HUD_ELEM_STATBAR) && (elem->size == v2s32())) { - log_deprecated(L,"Deprecated usage of statbar without size!"); - } + read_hud_element(L, elem); u32 id = getServer(L)->hudAdd(player, elem); if (id == U32_MAX) { @@ -1407,61 +1538,8 @@ int ObjectRef::l_hud_change(lua_State *L) if (!e) return 0; - HudElementStat stat = HUD_STAT_NUMBER; - if (lua_isstring(L, 3)) { - int statint; - std::string statstr = lua_tostring(L, 3); - stat = string_to_enum(es_HudElementStat, statint, statstr) ? - (HudElementStat)statint : HUD_STAT_NUMBER; - } - void *value = NULL; - switch (stat) { - case HUD_STAT_POS: - e->pos = read_v2f(L, 4); - value = &e->pos; - break; - case HUD_STAT_NAME: - e->name = luaL_checkstring(L, 4); - value = &e->name; - break; - case HUD_STAT_SCALE: - e->scale = read_v2f(L, 4); - value = &e->scale; - break; - case HUD_STAT_TEXT: - e->text = luaL_checkstring(L, 4); - value = &e->text; - break; - case HUD_STAT_NUMBER: - e->number = luaL_checknumber(L, 4); - value = &e->number; - break; - case HUD_STAT_ITEM: - e->item = luaL_checknumber(L, 4); - value = &e->item; - break; - case HUD_STAT_DIR: - e->dir = luaL_checknumber(L, 4); - value = &e->dir; - break; - case HUD_STAT_ALIGN: - e->align = read_v2f(L, 4); - value = &e->align; - break; - case HUD_STAT_OFFSET: - e->offset = read_v2f(L, 4); - value = &e->offset; - break; - case HUD_STAT_WORLD_POS: - e->world_pos = read_v3f(L, 4); - value = &e->world_pos; - break; - case HUD_STAT_SIZE: - e->size = read_v2s32(L, 4); - value = &e->size; - break; - } + HudElementStat stat = read_hud_change(L, e, &value); getServer(L)->hudChange(player, id, stat, value); @@ -1483,40 +1561,7 @@ int ObjectRef::l_hud_get(lua_State *L) HudElement *e = player->getHud(id); if (!e) return 0; - - lua_newtable(L); - - lua_pushstring(L, es_HudElementType[(u8)e->type].str); - lua_setfield(L, -2, "type"); - - push_v2f(L, e->pos); - lua_setfield(L, -2, "position"); - - lua_pushstring(L, e->name.c_str()); - lua_setfield(L, -2, "name"); - - push_v2f(L, e->scale); - lua_setfield(L, -2, "scale"); - - lua_pushstring(L, e->text.c_str()); - lua_setfield(L, -2, "text"); - - lua_pushnumber(L, e->number); - lua_setfield(L, -2, "number"); - - lua_pushnumber(L, e->item); - lua_setfield(L, -2, "item"); - - lua_pushnumber(L, e->dir); - lua_setfield(L, -2, "direction"); - - // Deprecated, only for compatibility's sake - lua_pushnumber(L, e->dir); - lua_setfield(L, -2, "dir"); - - push_v3f(L, e->world_pos); - lua_setfield(L, -2, "world_pos"); - + push_hud_element(L, e); return 1; } @@ -1568,6 +1613,8 @@ int ObjectRef::l_hud_get_flags(lua_State *L) lua_setfield(L, -2, "breathbar"); lua_pushboolean(L, player->hud_flags & HUD_FLAG_MINIMAP_VISIBLE); lua_setfield(L, -2, "minimap"); + lua_pushboolean(L, player->hud_flags & HUD_FLAG_MINIMAP_RADAR_VISIBLE); + lua_setfield(L, -2, "minimap_radar"); return 1; } @@ -1599,9 +1646,7 @@ int ObjectRef::l_hud_get_hotbar_itemcount(lua_State *L) if (player == NULL) return 0; - s32 hotbar_itemcount = getServer(L)->hudGetHotbarItemcount(player); - - lua_pushnumber(L, hotbar_itemcount); + lua_pushnumber(L, player->getHotbarItemcount()); return 1; } @@ -1614,7 +1659,7 @@ int ObjectRef::l_hud_set_hotbar_image(lua_State *L) if (player == NULL) return 0; - std::string name = lua_tostring(L, 2); + std::string name = readParam(L, 2); getServer(L)->hudSetHotbarImage(player, name); return 1; @@ -1629,7 +1674,7 @@ int ObjectRef::l_hud_get_hotbar_image(lua_State *L) if (player == NULL) return 0; - std::string name = getServer(L)->hudGetHotbarImage(player); + const std::string &name = player->getHotbarImage(); lua_pushlstring(L, name.c_str(), name.size()); return 1; } @@ -1643,7 +1688,7 @@ int ObjectRef::l_hud_set_hotbar_selected_image(lua_State *L) if (player == NULL) return 0; - std::string name = lua_tostring(L, 2); + std::string name = readParam(L, 2); getServer(L)->hudSetHotbarSelectedImage(player, name); return 1; @@ -1658,49 +1703,162 @@ int ObjectRef::l_hud_get_hotbar_selected_image(lua_State *L) if (player == NULL) return 0; - const std::string &name = getServer(L)->hudGetHotbarSelectedImage(player); + const std::string &name = player->getHotbarSelectedImage(); lua_pushlstring(L, name.c_str(), name.size()); return 1; } -// set_sky(self, bgcolor, type, list, clouds = true) +// set_sky(self, {base_color=, type=, textures=, clouds=, sky_colors={}}) int ObjectRef::l_set_sky(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); RemotePlayer *player = getplayer(ref); - if (player == NULL) + if (!player) return 0; - video::SColor bgcolor(255,255,255,255); - read_color(L, 2, &bgcolor); + bool is_colorspec = is_color_table(L, 2); + + SkyboxParams skybox_params = player->getSkyParams(); + if (lua_istable(L, 2) && !is_colorspec) { + lua_getfield(L, 2, "base_color"); + if (!lua_isnil(L, -1)) + read_color(L, -1, &skybox_params.bgcolor); + lua_pop(L, 1); + + lua_getfield(L, 2, "type"); + if (!lua_isnil(L, -1)) + skybox_params.type = luaL_checkstring(L, -1); + lua_pop(L, 1); + + lua_getfield(L, 2, "textures"); + skybox_params.textures.clear(); + if (lua_istable(L, -1) && skybox_params.type == "skybox") { + lua_pushnil(L); + while (lua_next(L, -2) != 0) { + // Key is at index -2 and value at index -1 + skybox_params.textures.emplace_back(readParam(L, -1)); + // Removes the value, but keeps the key for iteration + lua_pop(L, 1); + } + } + lua_pop(L, 1); - std::string type = luaL_checkstring(L, 3); + /* + We want to avoid crashes, so we're checking even if we're not using them. + However, we want to ensure that the skybox can be set to nil when + using "regular" or "plain" skybox modes as textures aren't needed. + */ - std::vector params; - if (lua_istable(L, 4)) { - lua_pushnil(L); - while (lua_next(L, 4) != 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 + if (skybox_params.textures.size() != 6 && skybox_params.textures.size() > 0) + throw LuaError("Skybox expects 6 textures!"); + + skybox_params.clouds = getboolfield_default(L, 2, + "clouds", skybox_params.clouds); + + lua_getfield(L, 2, "sky_color"); + if (lua_istable(L, -1)) { + lua_getfield(L, -1, "day_sky"); + read_color(L, -1, &skybox_params.sky_color.day_sky); lua_pop(L, 1); - } - } - if (type == "skybox" && params.size() != 6) - throw LuaError("skybox expects 6 textures"); + lua_getfield(L, -1, "day_horizon"); + read_color(L, -1, &skybox_params.sky_color.day_horizon); + lua_pop(L, 1); - bool clouds = true; - if (lua_isboolean(L, 5)) - clouds = lua_toboolean(L, 5); + lua_getfield(L, -1, "dawn_sky"); + read_color(L, -1, &skybox_params.sky_color.dawn_sky); + lua_pop(L, 1); - if (!getServer(L)->setSky(player, bgcolor, type, params, clouds)) - return 0; + lua_getfield(L, -1, "dawn_horizon"); + read_color(L, -1, &skybox_params.sky_color.dawn_horizon); + lua_pop(L, 1); + + lua_getfield(L, -1, "night_sky"); + read_color(L, -1, &skybox_params.sky_color.night_sky); + lua_pop(L, 1); + + lua_getfield(L, -1, "night_horizon"); + read_color(L, -1, &skybox_params.sky_color.night_horizon); + lua_pop(L, 1); + + lua_getfield(L, -1, "indoors"); + read_color(L, -1, &skybox_params.sky_color.indoors); + lua_pop(L, 1); + + // Prevent flickering clouds at dawn/dusk: + skybox_params.sun_tint = video::SColor(255, 255, 255, 255); + lua_getfield(L, -1, "fog_sun_tint"); + read_color(L, -1, &skybox_params.sun_tint); + lua_pop(L, 1); + + skybox_params.moon_tint = video::SColor(255, 255, 255, 255); + lua_getfield(L, -1, "fog_moon_tint"); + read_color(L, -1, &skybox_params.moon_tint); + lua_pop(L, 1); + + lua_getfield(L, -1, "fog_tint_type"); + if (!lua_isnil(L, -1)) + skybox_params.tint_type = luaL_checkstring(L, -1); + lua_pop(L, 1); + // Because we need to leave the "sky_color" table. + lua_pop(L, 1); + } + } else { + // Handle old set_sky calls, and log deprecated: + log_deprecated(L, "Deprecated call to set_sky, please check lua_api.txt"); + + // Fix sun, moon and stars showing when classic textured skyboxes are used + SunParams sun_params = player->getSunParams(); + MoonParams moon_params = player->getMoonParams(); + StarParams star_params = player->getStarParams(); + + // Prevent erroneous background colors + skybox_params.bgcolor = video::SColor(255, 255, 255, 255); + read_color(L, 2, &skybox_params.bgcolor); + + skybox_params.type = luaL_checkstring(L, 3); + + // Preserve old behaviour of the sun, moon and stars + // when using the old set_sky call. + if (skybox_params.type == "regular") { + sun_params.visible = true; + sun_params.sunrise_visible = true; + moon_params.visible = true; + star_params.visible = true; + } else { + sun_params.visible = false; + sun_params.sunrise_visible = false; + moon_params.visible = false; + star_params.visible = false; + } + + skybox_params.textures.clear(); + if (lua_istable(L, 4)) { + lua_pushnil(L); + while (lua_next(L, 4) != 0) { + // Key at index -2, and value at index -1 + if (lua_isstring(L, -1)) + skybox_params.textures.emplace_back(readParam(L, -1)); + else + skybox_params.textures.emplace_back(""); + // Remove the value, keep the key for the next iteration + lua_pop(L, 1); + } + } + if (skybox_params.type == "skybox" && skybox_params.textures.size() != 6) + throw LuaError("Skybox expects 6 textures."); + + skybox_params.clouds = true; + if (lua_isboolean(L, 5)) + skybox_params.clouds = readParam(L, 5); + + getServer(L)->setSun(player, sun_params); + getServer(L)->setMoon(player, moon_params); + getServer(L)->setStars(player, star_params); + } + getServer(L)->setSky(player, skybox_params); lua_pushboolean(L, true); return 1; } @@ -1711,30 +1869,226 @@ int ObjectRef::l_get_sky(lua_State *L) NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); RemotePlayer *player = getplayer(ref); - if (player == NULL) + + if (!player) return 0; - video::SColor bgcolor(255, 255, 255, 255); - std::string type; - std::vector params; - bool clouds; + SkyboxParams skybox_params; + skybox_params = player->getSkyParams(); - player->getSky(&bgcolor, &type, ¶ms, &clouds); - type = type == "" ? "regular" : type; + push_ARGB8(L, skybox_params.bgcolor); + lua_pushlstring(L, skybox_params.type.c_str(), skybox_params.type.size()); - push_ARGB8(L, bgcolor); - lua_pushlstring(L, type.c_str(), type.size()); lua_newtable(L); s16 i = 1; - for (std::vector::iterator it = params.begin(); - it != params.end(); ++it) { - lua_pushlstring(L, it->c_str(), it->size()); - lua_rawseti(L, -2, i); - i++; + for (const std::string& texture : skybox_params.textures) { + lua_pushlstring(L, texture.c_str(), texture.size()); + lua_rawseti(L, -2, i++); } - lua_pushboolean(L, clouds); + lua_pushboolean(L, skybox_params.clouds); return 4; } +// get_sky_color(self) +int ObjectRef::l_get_sky_color(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + + if (!player) + return 0; + + const SkyboxParams& skybox_params = player->getSkyParams(); + + lua_newtable(L); + if (skybox_params.type == "regular") { + push_ARGB8(L, skybox_params.sky_color.day_sky); + lua_setfield(L, -2, "day_sky"); + push_ARGB8(L, skybox_params.sky_color.day_horizon); + lua_setfield(L, -2, "day_horizon"); + push_ARGB8(L, skybox_params.sky_color.dawn_sky); + lua_setfield(L, -2, "dawn_sky"); + push_ARGB8(L, skybox_params.sky_color.dawn_horizon); + lua_setfield(L, -2, "dawn_horizon"); + push_ARGB8(L, skybox_params.sky_color.night_sky); + lua_setfield(L, -2, "night_sky"); + push_ARGB8(L, skybox_params.sky_color.night_horizon); + lua_setfield(L, -2, "night_horizon"); + push_ARGB8(L, skybox_params.sky_color.indoors); + lua_setfield(L, -2, "indoors"); + } + push_ARGB8(L, skybox_params.sun_tint); + lua_setfield(L, -2, "sun_tint"); + push_ARGB8(L, skybox_params.moon_tint); + lua_setfield(L, -2, "moon_tint"); + lua_pushstring(L, skybox_params.tint_type.c_str()); + lua_setfield(L, -2, "tint_type"); + return 1; +} + +// set_sun(self, {visible, texture=, tonemap=, sunrise=, rotation=, scale=}) +int ObjectRef::l_set_sun(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; + + SunParams sun_params = player->getSunParams(); + + sun_params.visible = getboolfield_default(L, 2, + "visible", sun_params.visible); + sun_params.texture = getstringfield_default(L, 2, + "texture", sun_params.texture); + sun_params.tonemap = getstringfield_default(L, 2, + "tonemap", sun_params.tonemap); + sun_params.sunrise = getstringfield_default(L, 2, + "sunrise", sun_params.sunrise); + sun_params.sunrise_visible = getboolfield_default(L, 2, + "sunrise_visible", sun_params.sunrise_visible); + sun_params.scale = getfloatfield_default(L, 2, + "scale", sun_params.scale); + + getServer(L)->setSun(player, sun_params); + lua_pushboolean(L, true); + return 1; +} + +//get_sun(self) +int ObjectRef::l_get_sun(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (!player) + return 0; + const SunParams &sun_params = player->getSunParams(); + + lua_newtable(L); + lua_pushboolean(L, sun_params.visible); + lua_setfield(L, -2, "visible"); + lua_pushstring(L, sun_params.texture.c_str()); + lua_setfield(L, -2, "texture"); + lua_pushstring(L, sun_params.tonemap.c_str()); + lua_setfield(L, -2, "tonemap"); + lua_pushstring(L, sun_params.sunrise.c_str()); + lua_setfield(L, -2, "sunrise"); + lua_pushboolean(L, sun_params.sunrise_visible); + lua_setfield(L, -2, "sunrise_visible"); + lua_pushnumber(L, sun_params.scale); + lua_setfield(L, -2, "scale"); + + return 1; +} + +// set_moon(self, {visible, texture=, tonemap=, sunrise=, rotation=, scale=}) +int ObjectRef::l_set_moon(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; + + MoonParams moon_params = player->getMoonParams(); + + moon_params.visible = getboolfield_default(L, 2, + "visible", moon_params.visible); + moon_params.texture = getstringfield_default(L, 2, + "texture", moon_params.texture); + moon_params.tonemap = getstringfield_default(L, 2, + "tonemap", moon_params.tonemap); + moon_params.scale = getfloatfield_default(L, 2, + "scale", moon_params.scale); + + getServer(L)->setMoon(player, moon_params); + lua_pushboolean(L, true); + return 1; +} + +// get_moon(self) +int ObjectRef::l_get_moon(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (!player) + return 0; + const MoonParams &moon_params = player->getMoonParams(); + + lua_newtable(L); + lua_pushboolean(L, moon_params.visible); + lua_setfield(L, -2, "visible"); + lua_pushstring(L, moon_params.texture.c_str()); + lua_setfield(L, -2, "texture"); + lua_pushstring(L, moon_params.tonemap.c_str()); + lua_setfield(L, -2, "tonemap"); + lua_pushnumber(L, moon_params.scale); + lua_setfield(L, -2, "scale"); + + return 1; +} + +// set_stars(self, {visible, count=, starcolor=, rotation=, scale=}) +int ObjectRef::l_set_stars(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; + + StarParams star_params = player->getStarParams(); + + star_params.visible = getboolfield_default(L, 2, + "visible", star_params.visible); + star_params.count = getintfield_default(L, 2, + "count", star_params.count); + + lua_getfield(L, 2, "star_color"); + if (!lua_isnil(L, -1)) + read_color(L, -1, &star_params.starcolor); + lua_pop(L, 1); + + star_params.scale = getfloatfield_default(L, 2, + "scale", star_params.scale); + + getServer(L)->setStars(player, star_params); + lua_pushboolean(L, true); + return 1; +} + +// get_stars(self) +int ObjectRef::l_get_stars(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (!player) + return 0; + const StarParams &star_params = player->getStarParams(); + + lua_newtable(L); + lua_pushboolean(L, star_params.visible); + lua_setfield(L, -2, "visible"); + lua_pushnumber(L, star_params.count); + lua_setfield(L, -2, "count"); + push_ARGB8(L, star_params.starcolor); + lua_setfield(L, -2, "star_color"); + lua_pushnumber(L, star_params.scale); + lua_setfield(L, -2, "scale"); + + return 1; +} + // set_clouds(self, {density=, color=, ambient=, height=, thickness=, speed=}) int ObjectRef::l_set_clouds(lua_State *L) { @@ -1771,14 +2125,7 @@ int ObjectRef::l_set_clouds(lua_State *L) } 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); - + getServer(L)->setClouds(player, cloud_params); lua_pushboolean(L, true); return 1; } @@ -1827,7 +2174,7 @@ int ObjectRef::l_override_day_night_ratio(lua_State *L) float ratio = 0.0f; if (!lua_isnil(L, 2)) { do_override = true; - ratio = luaL_checknumber(L, 2); + ratio = readParam(L, 2); } if (!getServer(L)->overrideDayNightRatio(player, do_override, ratio)) @@ -1864,15 +2211,6 @@ ObjectRef::ObjectRef(ServerActiveObject *object): //infostream<<"ObjectRef created for id="<getId()<