X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fscript%2Flua_api%2Fl_object.cpp;h=0a3e05907bb60e7e46e978f3d33c3e137d81a2e3;hb=03e710160f5c573b74097173b8202f209e5106ad;hp=bc59bd55cb1fe6b0f60d64eb0230aa9940dca604;hpb=fca4db4184ac054c53446c0960ec578ebc6b5857;p=minetest.git diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index bc59bd55c..0a3e05907 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -40,15 +40,6 @@ with this program; if not, write to the Free Software Foundation, Inc., */ -ObjectRef* ObjectRef::checkobject(lua_State *L, int narg) -{ - luaL_checktype(L, narg, LUA_TUSERDATA); - void *ud = luaL_checkudata(L, narg, className); - if (ud == nullptr) - luaL_typerror(L, narg, className); - return *(ObjectRef**)ud; // unbox pointer -} - ServerActiveObject* ObjectRef::getobject(ObjectRef *ref) { ServerActiveObject *sao = ref->m_object; @@ -99,7 +90,7 @@ int ObjectRef::l_remove(lua_State *L) { GET_ENV_PTR; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) return 0; @@ -110,7 +101,7 @@ int ObjectRef::l_remove(lua_State *L) sao->clearParentAttachment(); verbosestream << "ObjectRef::l_remove(): id=" << sao->getId() << std::endl; - sao->m_pending_removal = true; + sao->markForRemoval(); return 0; } @@ -118,7 +109,7 @@ int ObjectRef::l_remove(lua_State *L) int ObjectRef::l_get_pos(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) return 0; @@ -131,7 +122,7 @@ int ObjectRef::l_get_pos(lua_State *L) int ObjectRef::l_set_pos(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) return 0; @@ -146,7 +137,7 @@ int ObjectRef::l_set_pos(lua_State *L) int ObjectRef::l_move_to(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) return 0; @@ -162,8 +153,8 @@ int ObjectRef::l_move_to(lua_State *L) int ObjectRef::l_punch(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); - ObjectRef *puncher_ref = checkobject(L, 2); + ObjectRef *ref = checkObject(L, 1); + ObjectRef *puncher_ref = checkObject(L, 2); ServerActiveObject *sao = getobject(ref); ServerActiveObject *puncher = getobject(puncher_ref); if (sao == nullptr || puncher == nullptr) @@ -172,27 +163,11 @@ int ObjectRef::l_punch(lua_State *L) float time_from_last_punch = readParam(L, 3, 1000000.0f); ToolCapabilities toolcap = read_tool_capabilities(L, 4); v3f dir = readParam(L, 5, sao->getBasePosition() - puncher->getBasePosition()); - dir.normalize(); - u16 src_original_hp = sao->getHP(); - u16 dst_origin_hp = puncher->getHP(); - u16 wear = sao->punch(dir, &toolcap, puncher, time_from_last_punch); + u32 wear = sao->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 != sao->getHP() && - sao->getType() == ACTIVEOBJECT_TYPE_PLAYER) { - getServer(L)->SendPlayerHPOrDie((PlayerSAO *)sao, - 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, - PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, sao)); - } return 1; } @@ -200,8 +175,8 @@ int ObjectRef::l_punch(lua_State *L) int ObjectRef::l_right_click(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); - ObjectRef *ref2 = checkobject(L, 2); + ObjectRef *ref = checkObject(L, 1); + ObjectRef *ref2 = checkObject(L, 2); ServerActiveObject *sao = getobject(ref); ServerActiveObject *sao2 = getobject(ref2); if (sao == nullptr || sao2 == nullptr) @@ -215,7 +190,7 @@ int ObjectRef::l_right_click(lua_State *L) int ObjectRef::l_set_hp(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) return 0; @@ -238,8 +213,6 @@ int ObjectRef::l_set_hp(lua_State *L) } sao->setHP(hp, reason); - if (sao->getType() == ACTIVEOBJECT_TYPE_PLAYER) - getServer(L)->SendPlayerHPOrDie((PlayerSAO *)sao, reason); if (reason.hasLuaReference()) luaL_unref(L, LUA_REGISTRYINDEX, reason.lua_reference); return 0; @@ -249,7 +222,7 @@ int ObjectRef::l_set_hp(lua_State *L) int ObjectRef::l_get_hp(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) { // Default hp is 1 @@ -267,7 +240,7 @@ int ObjectRef::l_get_hp(lua_State *L) int ObjectRef::l_get_inventory(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) return 0; @@ -284,7 +257,7 @@ int ObjectRef::l_get_inventory(lua_State *L) int ObjectRef::l_get_wield_list(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) return 0; @@ -297,7 +270,7 @@ int ObjectRef::l_get_wield_list(lua_State *L) int ObjectRef::l_get_wield_index(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) return 0; @@ -310,7 +283,7 @@ int ObjectRef::l_get_wield_index(lua_State *L) int ObjectRef::l_get_wielded_item(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) { // Empty ItemStack @@ -328,7 +301,7 @@ int ObjectRef::l_get_wielded_item(lua_State *L) int ObjectRef::l_set_wielded_item(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) return 0; @@ -347,7 +320,7 @@ int ObjectRef::l_set_wielded_item(lua_State *L) int ObjectRef::l_set_armor_groups(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) return 0; @@ -355,6 +328,15 @@ int ObjectRef::l_set_armor_groups(lua_State *L) ItemGroupList groups; read_groups(L, 2, groups); + if (sao->getType() == ACTIVEOBJECT_TYPE_PLAYER) { + if (!g_settings->getBool("enable_damage") && !itemgroup_get(groups, "immortal")) { + warningstream << "Mod tried to enable damage for a player, but it's " + "disabled globally. Ignoring." << std::endl; + infostream << script_get_backtrace(L) << std::endl; + groups["immortal"] = 1; + } + } + sao->setArmorGroups(groups); return 0; } @@ -363,7 +345,7 @@ int ObjectRef::l_set_armor_groups(lua_State *L) int ObjectRef::l_get_armor_groups(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) return 0; @@ -376,7 +358,7 @@ int ObjectRef::l_get_armor_groups(lua_State *L) int ObjectRef::l_set_animation(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) return 0; @@ -394,12 +376,12 @@ int ObjectRef::l_set_animation(lua_State *L) int ObjectRef::l_get_animation(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) return 0; - v2f frames = v2f(1,1); + v2f frames = v2f(1, 1); float frame_speed = 15; float frame_blend = 0; bool frame_loop = true; @@ -416,7 +398,7 @@ int ObjectRef::l_get_animation(lua_State *L) int ObjectRef::l_set_local_animation(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; @@ -429,15 +411,14 @@ int ObjectRef::l_set_local_animation(lua_State *L) float frame_speed = readParam(L, 6, 30.0f); getServer(L)->setLocalPlayerAnimations(player, frames, frame_speed); - lua_pushboolean(L, true); - return 1; + return 0; } // get_local_animation(self) int ObjectRef::l_get_local_animation(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; @@ -458,13 +439,13 @@ int ObjectRef::l_get_local_animation(lua_State *L) int ObjectRef::l_set_eye_offset(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; - v3f offset_first = read_v3f(L, 2); - v3f offset_third = read_v3f(L, 3); + v3f offset_first = readParam(L, 2, v3f(0, 0, 0)); + v3f offset_third = readParam(L, 3, v3f(0, 0, 0)); // Prevent abuse of offset values (keep player always visible) offset_third.X = rangelim(offset_third.X,-10,10); @@ -473,15 +454,14 @@ int ObjectRef::l_set_eye_offset(lua_State *L) offset_third.Y = rangelim(offset_third.Y,-10,15); //1.5*BS getServer(L)->setPlayerEyeOffset(player, offset_first, offset_third); - lua_pushboolean(L, true); - return 1; + return 0; } // get_eye_offset(self) int ObjectRef::l_get_eye_offset(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; @@ -495,7 +475,7 @@ int ObjectRef::l_get_eye_offset(lua_State *L) int ObjectRef::l_send_mapblock(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; @@ -513,7 +493,7 @@ int ObjectRef::l_send_mapblock(lua_State *L) int ObjectRef::l_set_animation_frame_speed(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) return 0; @@ -532,14 +512,14 @@ int ObjectRef::l_set_animation_frame_speed(lua_State *L) int ObjectRef::l_set_bone_position(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) return 0; - std::string bone = readParam(L, 2); - v3f position = check_v3f(L, 3); - v3f rotation = check_v3f(L, 4); + std::string bone = readParam(L, 2, ""); + v3f position = readParam(L, 3, v3f(0, 0, 0)); + v3f rotation = readParam(L, 4, v3f(0, 0, 0)); sao->setBonePosition(bone, position, rotation); return 0; @@ -549,12 +529,12 @@ int ObjectRef::l_set_bone_position(lua_State *L) int ObjectRef::l_get_bone_position(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) return 0; - std::string bone = readParam(L, 2); + std::string bone = readParam(L, 2, ""); v3f position = v3f(0, 0, 0); v3f rotation = v3f(0, 0, 0); @@ -569,8 +549,8 @@ int ObjectRef::l_get_bone_position(lua_State *L) int ObjectRef::l_set_attach(lua_State *L) { GET_ENV_PTR; - ObjectRef *ref = checkobject(L, 1); - ObjectRef *parent_ref = checkobject(L, 2); + ObjectRef *ref = checkObject(L, 1); + ObjectRef *parent_ref = checkObject(L, 2); ServerActiveObject *sao = getobject(ref); ServerActiveObject *parent = getobject(parent_ref); if (sao == nullptr || parent == nullptr) @@ -578,10 +558,10 @@ int ObjectRef::l_set_attach(lua_State *L) if (sao == parent) throw LuaError("ObjectRef::set_attach: attaching object to itself is not allowed."); - int parent_id = 0; + int parent_id; std::string bone; - v3f position = v3f(0, 0, 0); - v3f rotation = v3f(0, 0, 0); + v3f position; + v3f rotation; bool force_visible; sao->getAttachment(&parent_id, &bone, &position, &rotation, &force_visible); @@ -590,9 +570,9 @@ int ObjectRef::l_set_attach(lua_State *L) old_parent->removeAttachmentChild(sao->getId()); } - bone = readParam(L, 3, ""); - position = read_v3f(L, 4); - rotation = read_v3f(L, 5); + bone = readParam(L, 3, ""); + position = readParam(L, 4, v3f(0, 0, 0)); + rotation = readParam(L, 5, v3f(0, 0, 0)); force_visible = readParam(L, 6, false); sao->setAttachment(parent->getId(), bone, position, rotation, force_visible); @@ -604,15 +584,15 @@ int ObjectRef::l_set_attach(lua_State *L) int ObjectRef::l_get_attach(lua_State *L) { GET_ENV_PTR; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) return 0; - int parent_id = 0; + int parent_id; std::string bone; - v3f position = v3f(0, 0, 0); - v3f rotation = v3f(0, 0, 0); + v3f position; + v3f rotation; bool force_visible; sao->getAttachment(&parent_id, &bone, &position, &rotation, &force_visible); @@ -632,7 +612,7 @@ int ObjectRef::l_get_attach(lua_State *L) int ObjectRef::l_get_children(lua_State *L) { GET_ENV_PTR; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) return 0; @@ -653,7 +633,7 @@ int ObjectRef::l_get_children(lua_State *L) int ObjectRef::l_set_detach(lua_State *L) { GET_ENV_PTR; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) return 0; @@ -666,7 +646,7 @@ int ObjectRef::l_set_detach(lua_State *L) int ObjectRef::l_set_properties(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) return 0; @@ -676,6 +656,7 @@ int ObjectRef::l_set_properties(lua_State *L) return 0; read_object_properties(L, 2, sao, prop, getServer(L)->idef()); + prop->validate(); sao->notifyObjectPropertiesModified(); return 0; } @@ -684,7 +665,7 @@ int ObjectRef::l_set_properties(lua_State *L) int ObjectRef::l_get_properties(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) return 0; @@ -701,7 +682,7 @@ int ObjectRef::l_get_properties(lua_State *L) int ObjectRef::l_is_player(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); lua_pushboolean(L, (player != nullptr)); return 1; @@ -711,7 +692,7 @@ int ObjectRef::l_is_player(lua_State *L) int ObjectRef::l_set_nametag_attributes(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) return 0; @@ -728,19 +709,30 @@ int ObjectRef::l_set_nametag_attributes(lua_State *L) } lua_pop(L, 1); - std::string nametag = getstringfield_default(L, 2, "text", ""); - prop->nametag = nametag; + lua_getfield(L, -1, "bgcolor"); + if (!lua_isnil(L, -1)) { + if (lua_toboolean(L, -1)) { + video::SColor color; + if (read_color(L, -1, &color)) + prop->nametag_bgcolor = color; + } else { + prop->nametag_bgcolor = nullopt; + } + } + lua_pop(L, 1); + + prop->nametag = getstringfield_default(L, 2, "text", prop->nametag); + prop->validate(); sao->notifyObjectPropertiesModified(); - lua_pushboolean(L, true); - return 1; + return 0; } // get_nametag_attributes(self) int ObjectRef::l_get_nametag_attributes(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) return 0; @@ -749,13 +741,24 @@ int ObjectRef::l_get_nametag_attributes(lua_State *L) if (!prop) return 0; - video::SColor color = prop->nametag_color; - lua_newtable(L); - push_ARGB8(L, color); + + push_ARGB8(L, prop->nametag_color); lua_setfield(L, -2, "color"); + + if (prop->nametag_bgcolor) { + push_ARGB8(L, prop->nametag_bgcolor.value()); + lua_setfield(L, -2, "bgcolor"); + } else { + lua_pushboolean(L, false); + lua_setfield(L, -2, "bgcolor"); + } + lua_pushstring(L, prop->nametag.c_str()); lua_setfield(L, -2, "text"); + + + return 1; } @@ -765,7 +768,7 @@ int ObjectRef::l_get_nametag_attributes(lua_State *L) int ObjectRef::l_set_velocity(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); LuaEntitySAO *sao = getluaobject(ref); if (sao == nullptr) return 0; @@ -780,7 +783,7 @@ int ObjectRef::l_set_velocity(lua_State *L) int ObjectRef::l_add_velocity(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) return 0; @@ -803,7 +806,7 @@ int ObjectRef::l_add_velocity(lua_State *L) int ObjectRef::l_get_velocity(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) return 0; @@ -827,7 +830,7 @@ int ObjectRef::l_get_velocity(lua_State *L) int ObjectRef::l_set_acceleration(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); LuaEntitySAO *entitysao = getluaobject(ref); if (entitysao == nullptr) return 0; @@ -842,7 +845,7 @@ int ObjectRef::l_set_acceleration(lua_State *L) int ObjectRef::l_get_acceleration(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); LuaEntitySAO *entitysao = getluaobject(ref); if (entitysao == nullptr) return 0; @@ -856,7 +859,7 @@ int ObjectRef::l_get_acceleration(lua_State *L) int ObjectRef::l_set_rotation(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); LuaEntitySAO *entitysao = getluaobject(ref); if (entitysao == nullptr) return 0; @@ -871,7 +874,7 @@ int ObjectRef::l_set_rotation(lua_State *L) int ObjectRef::l_get_rotation(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); LuaEntitySAO *entitysao = getluaobject(ref); if (entitysao == nullptr) return 0; @@ -887,14 +890,11 @@ int ObjectRef::l_get_rotation(lua_State *L) int ObjectRef::l_set_yaw(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); LuaEntitySAO *entitysao = getluaobject(ref); if (entitysao == nullptr) return 0; - if (isNaN(L, 2)) - throw LuaError("ObjectRef::set_yaw: NaN value is not allowed."); - float yaw = readParam(L, 2) * core::RADTODEG; entitysao->setRotation(v3f(0, yaw, 0)); @@ -905,7 +905,7 @@ int ObjectRef::l_set_yaw(lua_State *L) int ObjectRef::l_get_yaw(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); LuaEntitySAO *entitysao = getluaobject(ref); if (entitysao == nullptr) return 0; @@ -920,7 +920,7 @@ int ObjectRef::l_get_yaw(lua_State *L) int ObjectRef::l_set_texture_mod(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); LuaEntitySAO *entitysao = getluaobject(ref); if (entitysao == nullptr) return 0; @@ -935,7 +935,7 @@ int ObjectRef::l_set_texture_mod(lua_State *L) int ObjectRef::l_get_texture_mod(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); LuaEntitySAO *entitysao = getluaobject(ref); if (entitysao == nullptr) return 0; @@ -950,7 +950,7 @@ int ObjectRef::l_get_texture_mod(lua_State *L) int ObjectRef::l_set_sprite(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); LuaEntitySAO *entitysao = getluaobject(ref); if (entitysao == nullptr) return 0; @@ -969,7 +969,7 @@ int ObjectRef::l_set_sprite(lua_State *L) int ObjectRef::l_get_entity_name(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); LuaEntitySAO *entitysao = getluaobject(ref); log_deprecated(L,"Deprecated call to \"get_entity_name"); if (entitysao == nullptr) @@ -985,7 +985,7 @@ int ObjectRef::l_get_entity_name(lua_State *L) int ObjectRef::l_get_luaentity(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); LuaEntitySAO *entitysao = getluaobject(ref); if (entitysao == nullptr) return 0; @@ -1000,7 +1000,7 @@ int ObjectRef::l_get_luaentity(lua_State *L) int ObjectRef::l_get_player_name(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) { lua_pushlstring(L, "", 0); @@ -1015,7 +1015,7 @@ int ObjectRef::l_get_player_name(lua_State *L) int ObjectRef::l_get_look_dir(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); PlayerSAO* playersao = getplayersao(ref); if (playersao == nullptr) return 0; @@ -1038,7 +1038,7 @@ int ObjectRef::l_get_look_pitch(lua_State *L) log_deprecated(L, "Deprecated call to get_look_pitch, use get_look_vertical instead"); - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); PlayerSAO* playersao = getplayersao(ref); if (playersao == nullptr) return 0; @@ -1056,7 +1056,7 @@ int ObjectRef::l_get_look_yaw(lua_State *L) log_deprecated(L, "Deprecated call to get_look_yaw, use get_look_horizontal instead"); - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); PlayerSAO* playersao = getplayersao(ref); if (playersao == nullptr) return 0; @@ -1069,7 +1069,7 @@ int ObjectRef::l_get_look_yaw(lua_State *L) int ObjectRef::l_get_look_vertical(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); PlayerSAO* playersao = getplayersao(ref); if (playersao == nullptr) return 0; @@ -1082,7 +1082,7 @@ int ObjectRef::l_get_look_vertical(lua_State *L) int ObjectRef::l_get_look_horizontal(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); PlayerSAO* playersao = getplayersao(ref); if (playersao == nullptr) return 0; @@ -1095,7 +1095,7 @@ int ObjectRef::l_get_look_horizontal(lua_State *L) int ObjectRef::l_set_look_vertical(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); PlayerSAO* playersao = getplayersao(ref); if (playersao == nullptr) return 0; @@ -1103,14 +1103,14 @@ int ObjectRef::l_set_look_vertical(lua_State *L) float pitch = readParam(L, 2) * core::RADTODEG; playersao->setLookPitchAndSend(pitch); - return 1; + return 0; } // set_look_horizontal(self, radians) int ObjectRef::l_set_look_horizontal(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); PlayerSAO* playersao = getplayersao(ref); if (playersao == nullptr) return 0; @@ -1118,7 +1118,7 @@ int ObjectRef::l_set_look_horizontal(lua_State *L) float yaw = readParam(L, 2) * core::RADTODEG; playersao->setPlayerYawAndSend(yaw); - return 1; + return 0; } // DEPRECATED @@ -1130,7 +1130,7 @@ int ObjectRef::l_set_look_pitch(lua_State *L) log_deprecated(L, "Deprecated call to set_look_pitch, use set_look_vertical instead."); - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); PlayerSAO* playersao = getplayersao(ref); if (playersao == nullptr) return 0; @@ -1138,7 +1138,7 @@ int ObjectRef::l_set_look_pitch(lua_State *L) float pitch = readParam(L, 2) * core::RADTODEG; playersao->setLookPitchAndSend(pitch); - return 1; + return 0; } // DEPRECATED @@ -1150,7 +1150,7 @@ int ObjectRef::l_set_look_yaw(lua_State *L) log_deprecated(L, "Deprecated call to set_look_yaw, use set_look_horizontal instead."); - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); PlayerSAO* playersao = getplayersao(ref); if (playersao == nullptr) return 0; @@ -1158,14 +1158,14 @@ int ObjectRef::l_set_look_yaw(lua_State *L) float yaw = readParam(L, 2) * core::RADTODEG; playersao->setPlayerYawAndSend(yaw); - return 1; + return 0; } // set_fov(self, degrees, is_multiplier, transition_time) int ObjectRef::l_set_fov(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; @@ -1184,7 +1184,7 @@ int ObjectRef::l_set_fov(lua_State *L) int ObjectRef::l_get_fov(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; @@ -1201,7 +1201,7 @@ int ObjectRef::l_get_fov(lua_State *L) int ObjectRef::l_set_breath(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); PlayerSAO* playersao = getplayersao(ref); if (playersao == nullptr) return 0; @@ -1216,7 +1216,7 @@ int ObjectRef::l_set_breath(lua_State *L) int ObjectRef::l_get_breath(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); PlayerSAO* playersao = getplayersao(ref); if (playersao == nullptr) return 0; @@ -1233,7 +1233,7 @@ 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); + ObjectRef *ref = checkObject(L, 1); PlayerSAO* playersao = getplayersao(ref); if (playersao == nullptr) return 0; @@ -1254,7 +1254,7 @@ 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); + ObjectRef *ref = checkObject(L, 1); PlayerSAO* playersao = getplayersao(ref); if (playersao == nullptr) return 0; @@ -1274,7 +1274,7 @@ 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); + ObjectRef *ref = checkObject(L, 1); PlayerSAO *playersao = getplayersao(ref); if (playersao == nullptr) return 0; @@ -1288,7 +1288,7 @@ int ObjectRef::l_get_meta(lua_State *L) int ObjectRef::l_set_inventory_formspec(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; @@ -1297,15 +1297,14 @@ int ObjectRef::l_set_inventory_formspec(lua_State *L) player->inventory_formspec = formspec; getServer(L)->reportInventoryFormspecModified(player->getName()); - lua_pushboolean(L, true); - return 1; + return 0; } // get_inventory_formspec(self) -> formspec int ObjectRef::l_get_inventory_formspec(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; @@ -1320,7 +1319,7 @@ int ObjectRef::l_get_inventory_formspec(lua_State *L) int ObjectRef::l_set_formspec_prepend(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; @@ -1329,15 +1328,14 @@ int ObjectRef::l_set_formspec_prepend(lua_State *L) player->formspec_prepend = formspec; getServer(L)->reportFormspecPrependModified(player->getName()); - lua_pushboolean(L, true); - return 1; + return 0; } // get_formspec_prepend(self) int ObjectRef::l_get_formspec_prepend(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; @@ -1352,22 +1350,21 @@ int ObjectRef::l_get_formspec_prepend(lua_State *L) int ObjectRef::l_get_player_control(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); - if (player == nullptr) { - lua_pushlstring(L, "", 0); + + lua_newtable(L); + if (player == nullptr) return 1; - } const PlayerControl &control = player->getPlayerControl(); - lua_newtable(L); - lua_pushboolean(L, control.up); + lua_pushboolean(L, control.direction_keys & (1 << 0)); lua_setfield(L, -2, "up"); - lua_pushboolean(L, control.down); + lua_pushboolean(L, control.direction_keys & (1 << 1)); lua_setfield(L, -2, "down"); - lua_pushboolean(L, control.left); + lua_pushboolean(L, control.direction_keys & (1 << 2)); lua_setfield(L, -2, "left"); - lua_pushboolean(L, control.right); + lua_pushboolean(L, control.direction_keys & (1 << 3)); lua_setfield(L, -2, "right"); lua_pushboolean(L, control.jump); lua_setfield(L, -2, "jump"); @@ -1393,14 +1390,28 @@ int ObjectRef::l_get_player_control(lua_State *L) int ObjectRef::l_get_player_control_bits(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) { - lua_pushlstring(L, "", 0); + lua_pushinteger(L, 0); return 1; } - lua_pushnumber(L, player->keyPressed); + const auto &c = player->getPlayerControl(); + + // This is very close to PlayerControl::getKeysPressed() but duplicated + // here so the encoding in the API is not inadvertedly changed. + u32 keypress_bits = + c.direction_keys | + ( (u32)(c.jump & 1) << 4) | + ( (u32)(c.aux1 & 1) << 5) | + ( (u32)(c.sneak & 1) << 6) | + ( (u32)(c.dig & 1) << 7) | + ( (u32)(c.place & 1) << 8) | + ( (u32)(c.zoom & 1) << 9) + ; + + lua_pushinteger(L, keypress_bits); return 1; } @@ -1408,19 +1419,22 @@ int ObjectRef::l_get_player_control_bits(lua_State *L) int ObjectRef::l_set_physics_override(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); - PlayerSAO *playersao = (PlayerSAO *) getobject(ref); + ObjectRef *ref = checkObject(L, 1); + PlayerSAO *playersao = getplayersao(ref); if (playersao == nullptr) return 0; + RemotePlayer *player = playersao->getPlayer(); + auto &phys = player->physics_override; + if (lua_istable(L, 2)) { bool modified = false; - modified |= getfloatfield(L, 2, "speed", playersao->m_physics_override_speed); - modified |= getfloatfield(L, 2, "jump", playersao->m_physics_override_jump); - modified |= getfloatfield(L, 2, "gravity", playersao->m_physics_override_gravity); - modified |= getboolfield(L, 2, "sneak", playersao->m_physics_override_sneak); - modified |= getboolfield(L, 2, "sneak_glitch", playersao->m_physics_override_sneak_glitch); - modified |= getboolfield(L, 2, "new_move", playersao->m_physics_override_new_move); + modified |= getfloatfield(L, 2, "speed", phys.speed); + modified |= getfloatfield(L, 2, "jump", phys.jump); + modified |= getfloatfield(L, 2, "gravity", phys.gravity); + modified |= getboolfield(L, 2, "sneak", phys.sneak); + modified |= getboolfield(L, 2, "sneak_glitch", phys.sneak_glitch); + modified |= getboolfield(L, 2, "new_move", phys.new_move); if (modified) playersao->m_physics_override_sent = false; } else { @@ -1429,15 +1443,15 @@ int ObjectRef::l_set_physics_override(lua_State *L) log_deprecated(L, "Deprecated use of set_physics_override(num, num, num)"); if (!lua_isnil(L, 2)) { - playersao->m_physics_override_speed = lua_tonumber(L, 2); + phys.speed = lua_tonumber(L, 2); playersao->m_physics_override_sent = false; } if (!lua_isnil(L, 3)) { - playersao->m_physics_override_jump = lua_tonumber(L, 3); + phys.jump = lua_tonumber(L, 3); playersao->m_physics_override_sent = false; } if (!lua_isnil(L, 4)) { - playersao->m_physics_override_gravity = lua_tonumber(L, 4); + phys.gravity = lua_tonumber(L, 4); playersao->m_physics_override_sent = false; } } @@ -1448,23 +1462,24 @@ int ObjectRef::l_set_physics_override(lua_State *L) int ObjectRef::l_get_physics_override(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); - PlayerSAO *playersao = (PlayerSAO *)getobject(ref); - if (playersao == nullptr) + ObjectRef *ref = checkObject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) return 0; + const auto &phys = player->physics_override; lua_newtable(L); - lua_pushnumber(L, playersao->m_physics_override_speed); + lua_pushnumber(L, phys.speed); lua_setfield(L, -2, "speed"); - lua_pushnumber(L, playersao->m_physics_override_jump); + lua_pushnumber(L, phys.jump); lua_setfield(L, -2, "jump"); - lua_pushnumber(L, playersao->m_physics_override_gravity); + lua_pushnumber(L, phys.gravity); lua_setfield(L, -2, "gravity"); - lua_pushboolean(L, playersao->m_physics_override_sneak); + lua_pushboolean(L, phys.sneak); lua_setfield(L, -2, "sneak"); - lua_pushboolean(L, playersao->m_physics_override_sneak_glitch); + lua_pushboolean(L, phys.sneak_glitch); lua_setfield(L, -2, "sneak_glitch"); - lua_pushboolean(L, playersao->m_physics_override_new_move); + lua_pushboolean(L, phys.new_move); lua_setfield(L, -2, "new_move"); return 1; } @@ -1473,7 +1488,7 @@ int ObjectRef::l_get_physics_override(lua_State *L) int ObjectRef::l_hud_add(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; @@ -1495,7 +1510,7 @@ int ObjectRef::l_hud_add(lua_State *L) int ObjectRef::l_hud_remove(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; @@ -1513,7 +1528,7 @@ int ObjectRef::l_hud_remove(lua_State *L) int ObjectRef::l_hud_change(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; @@ -1524,12 +1539,14 @@ int ObjectRef::l_hud_change(lua_State *L) if (elem == nullptr) return 0; + HudElementStat stat; void *value = nullptr; - HudElementStat stat = read_hud_change(L, elem, &value); + bool ok = read_hud_change(L, stat, elem, &value); - getServer(L)->hudChange(player, id, stat, value); + if (ok) + getServer(L)->hudChange(player, id, stat, value); - lua_pushboolean(L, true); + lua_pushboolean(L, ok); return 1; } @@ -1537,7 +1554,7 @@ int ObjectRef::l_hud_change(lua_State *L) int ObjectRef::l_hud_get(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; @@ -1556,7 +1573,7 @@ int ObjectRef::l_hud_get(lua_State *L) int ObjectRef::l_hud_set_flags(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; @@ -1575,34 +1592,24 @@ int ObjectRef::l_hud_set_flags(lua_State *L) if (!getServer(L)->hudSetFlags(player, flags, mask)) return 0; - lua_pushboolean(L, true); - return 1; + return 0; } // hud_get_flags(self) int ObjectRef::l_hud_get_flags(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; lua_newtable(L); - lua_pushboolean(L, player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE); - lua_setfield(L, -2, "hotbar"); - lua_pushboolean(L, player->hud_flags & HUD_FLAG_HEALTHBAR_VISIBLE); - lua_setfield(L, -2, "healthbar"); - lua_pushboolean(L, player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE); - lua_setfield(L, -2, "crosshair"); - lua_pushboolean(L, player->hud_flags & HUD_FLAG_WIELDITEM_VISIBLE); - lua_setfield(L, -2, "wielditem"); - lua_pushboolean(L, player->hud_flags & HUD_FLAG_BREATHBAR_VISIBLE); - 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"); + const EnumString *esp = es_HudBuiltinElement; + for (int i = 0; esp[i].str; i++) { + lua_pushboolean(L, (player->hud_flags & esp[i].num) != 0); + lua_setfield(L, -2, esp[i].str); + } return 1; } @@ -1610,7 +1617,7 @@ int ObjectRef::l_hud_get_flags(lua_State *L) int ObjectRef::l_hud_set_hotbar_itemcount(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; @@ -1628,7 +1635,7 @@ int ObjectRef::l_hud_set_hotbar_itemcount(lua_State *L) int ObjectRef::l_hud_get_hotbar_itemcount(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; @@ -1641,7 +1648,7 @@ int ObjectRef::l_hud_get_hotbar_itemcount(lua_State *L) int ObjectRef::l_hud_set_hotbar_image(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; @@ -1656,7 +1663,7 @@ int ObjectRef::l_hud_set_hotbar_image(lua_State *L) int ObjectRef::l_hud_get_hotbar_image(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; @@ -1671,7 +1678,7 @@ int ObjectRef::l_hud_get_hotbar_image(lua_State *L) int ObjectRef::l_hud_set_hotbar_selected_image(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; @@ -1686,7 +1693,7 @@ int ObjectRef::l_hud_set_hotbar_selected_image(lua_State *L) int ObjectRef::l_hud_get_hotbar_selected_image(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; @@ -1701,15 +1708,17 @@ int ObjectRef::l_hud_get_hotbar_selected_image(lua_State *L) int ObjectRef::l_set_sky(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; SkyboxParams sky_params = player->getSkyParams(); - bool is_colorspec = is_color_table(L, 2); - if (lua_istable(L, 2) && !is_colorspec) { + // reset if empty + if (lua_isnoneornil(L, 2) && lua_isnone(L, 3)) { + sky_params = SkyboxDefaults::getSkyDefaults(); + } else if (lua_istable(L, 2) && !is_color_table(L, 2)) { lua_getfield(L, 2, "base_color"); if (!lua_isnil(L, -1)) read_color(L, -1, &sky_params.bgcolor); @@ -1733,17 +1742,11 @@ int ObjectRef::l_set_sky(lua_State *L) } lua_pop(L, 1); - /* - 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. - */ - - if (sky_params.textures.size() != 6 && sky_params.textures.size() > 0) + // Validate that we either have six or zero textures + if (sky_params.textures.size() != 6 && !sky_params.textures.empty()) throw LuaError("Skybox expects 6 textures!"); - sky_params.clouds = getboolfield_default(L, 2, - "clouds", sky_params.clouds); + sky_params.clouds = getboolfield_default(L, 2, "clouds", sky_params.clouds); lua_getfield(L, 2, "sky_color"); if (lua_istable(L, -1)) { @@ -1791,7 +1794,7 @@ int ObjectRef::l_set_sky(lua_State *L) sky_params.fog_tint_type = luaL_checkstring(L, -1); lua_pop(L, 1); - // Because we need to leave the "sky_color" table. + // pop "sky_color" table lua_pop(L, 1); } } else { @@ -1809,7 +1812,7 @@ int ObjectRef::l_set_sky(lua_State *L) sky_params.type = luaL_checkstring(L, 3); - // Preserve old behaviour of the sun, moon and stars + // Preserve old behavior of the sun, moon and stars // when using the old set_sky call. if (sky_params.type == "regular") { sun_params.visible = true; @@ -1827,11 +1830,8 @@ int ObjectRef::l_set_sky(lua_State *L) 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)) - sky_params.textures.emplace_back(readParam(L, -1)); - else - sky_params.textures.emplace_back(""); + // Key at index -2, and value at index -1 + sky_params.textures.emplace_back(readParam(L, -1)); // Remove the value, keep the key for the next iteration lua_pop(L, 1); } @@ -1847,24 +1847,71 @@ int ObjectRef::l_set_sky(lua_State *L) getServer(L)->setMoon(player, moon_params); getServer(L)->setStars(player, star_params); } + getServer(L)->setSky(player, sky_params); - lua_pushboolean(L, true); - return 1; + return 0; } -// get_sky(self) +static void push_sky_color(lua_State *L, const SkyboxParams ¶ms) +{ + lua_newtable(L); + if (params.type == "regular") { + push_ARGB8(L, params.sky_color.day_sky); + lua_setfield(L, -2, "day_sky"); + push_ARGB8(L, params.sky_color.day_horizon); + lua_setfield(L, -2, "day_horizon"); + push_ARGB8(L, params.sky_color.dawn_sky); + lua_setfield(L, -2, "dawn_sky"); + push_ARGB8(L, params.sky_color.dawn_horizon); + lua_setfield(L, -2, "dawn_horizon"); + push_ARGB8(L, params.sky_color.night_sky); + lua_setfield(L, -2, "night_sky"); + push_ARGB8(L, params.sky_color.night_horizon); + lua_setfield(L, -2, "night_horizon"); + push_ARGB8(L, params.sky_color.indoors); + lua_setfield(L, -2, "indoors"); + } + push_ARGB8(L, params.fog_sun_tint); + lua_setfield(L, -2, "fog_sun_tint"); + push_ARGB8(L, params.fog_moon_tint); + lua_setfield(L, -2, "fog_moon_tint"); + lua_pushstring(L, params.fog_tint_type.c_str()); + lua_setfield(L, -2, "fog_tint_type"); +} + +// get_sky(self, as_table) int ObjectRef::l_get_sky(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; - SkyboxParams skybox_params = player->getSkyParams(); + const SkyboxParams &skybox_params = player->getSkyParams(); + + // handle the deprecated version + if (!readParam(L, 2, false)) { + log_deprecated(L, "Deprecated call to get_sky, please check lua_api.txt"); + + push_ARGB8(L, skybox_params.bgcolor); + lua_pushlstring(L, skybox_params.type.c_str(), skybox_params.type.size()); + + lua_newtable(L); + s16 i = 1; + for (const std::string &texture : skybox_params.textures) { + lua_pushlstring(L, texture.c_str(), texture.size()); + lua_rawseti(L, -2, i++); + } + lua_pushboolean(L, skybox_params.clouds); + return 4; + } + lua_newtable(L); push_ARGB8(L, skybox_params.bgcolor); + lua_setfield(L, -2, "base_color"); lua_pushlstring(L, skybox_params.type.c_str(), skybox_params.type.size()); + lua_setfield(L, -2, "type"); lua_newtable(L); s16 i = 1; @@ -1872,44 +1919,30 @@ int ObjectRef::l_get_sky(lua_State *L) lua_pushlstring(L, texture.c_str(), texture.size()); lua_rawseti(L, -2, i++); } + lua_setfield(L, -2, "textures"); lua_pushboolean(L, skybox_params.clouds); - return 4; + lua_setfield(L, -2, "clouds"); + + push_sky_color(L, skybox_params); + lua_setfield(L, -2, "sky_color"); + return 1; } +// DEPRECATED // get_sky_color(self) int ObjectRef::l_get_sky_color(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + + log_deprecated(L, "Deprecated call to get_sky_color, use get_sky instead"); + + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) 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.fog_sun_tint); - lua_setfield(L, -2, "fog_sun_tint"); - push_ARGB8(L, skybox_params.fog_moon_tint); - lua_setfield(L, -2, "fog_moon_tint"); - lua_pushstring(L, skybox_params.fog_tint_type.c_str()); - lua_setfield(L, -2, "fog_tint_type"); + push_sky_color(L, skybox_params); return 1; } @@ -1917,37 +1950,35 @@ int ObjectRef::l_get_sky_color(lua_State *L) int ObjectRef::l_set_sun(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; - luaL_checktype(L, 2, LUA_TTABLE); 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); + // reset if empty + if (lua_isnoneornil(L, 2)) { + sun_params = SkyboxDefaults::getSunDefaults(); + } else { + luaL_checktype(L, 2, LUA_TTABLE); + 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; + return 0; } //get_sun(self) int ObjectRef::l_get_sun(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; @@ -1974,33 +2005,33 @@ int ObjectRef::l_get_sun(lua_State *L) int ObjectRef::l_set_moon(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; - luaL_checktype(L, 2, LUA_TTABLE); 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); + // reset if empty + if (lua_isnoneornil(L, 2)) { + moon_params = SkyboxDefaults::getMoonDefaults(); + } else { + luaL_checktype(L, 2, LUA_TTABLE); + 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; + return 0; } // get_moon(self) int ObjectRef::l_get_moon(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; @@ -2023,37 +2054,41 @@ int ObjectRef::l_get_moon(lua_State *L) int ObjectRef::l_set_stars(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; - luaL_checktype(L, 2, LUA_TTABLE); 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); + // reset if empty + if (lua_isnoneornil(L, 2)) { + star_params = SkyboxDefaults::getStarDefaults(); + } else { + luaL_checktype(L, 2, LUA_TTABLE); + 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); + 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); + star_params.scale = getfloatfield_default(L, 2, + "scale", star_params.scale); + star_params.day_opacity = getfloatfield_default(L, 2, + "day_opacity", star_params.day_opacity); + } getServer(L)->setStars(player, star_params); - lua_pushboolean(L, true); - return 1; + return 0; } // get_stars(self) int ObjectRef::l_get_stars(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; @@ -2069,6 +2104,8 @@ int ObjectRef::l_get_stars(lua_State *L) lua_setfield(L, -2, "star_color"); lua_pushnumber(L, star_params.scale); lua_setfield(L, -2, "scale"); + lua_pushnumber(L, star_params.day_opacity); + lua_setfield(L, -2, "day_opacity"); return 1; } @@ -2076,46 +2113,50 @@ int ObjectRef::l_get_stars(lua_State *L) int ObjectRef::l_set_clouds(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; - luaL_checktype(L, 2, LUA_TTABLE); CloudParams cloud_params = player->getCloudParams(); - cloud_params.density = getfloatfield_default(L, 2, "density", cloud_params.density); + // reset if empty + if (lua_isnoneornil(L, 2)) { + cloud_params = SkyboxDefaults::getCloudDefaults(); + } else { + luaL_checktype(L, 2, LUA_TTABLE); + 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); + 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); + 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, "z", 0); - cloud_params.speed = new_speed; + 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, "z", 0); + cloud_params.speed = new_speed; + } + lua_pop(L, 1); } - lua_pop(L, 1); getServer(L)->setClouds(player, cloud_params); - lua_pushboolean(L, true); - return 1; + return 0; } int ObjectRef::l_get_clouds(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; @@ -2147,7 +2188,7 @@ int ObjectRef::l_get_clouds(lua_State *L) int ObjectRef::l_override_day_night_ratio(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; @@ -2163,15 +2204,14 @@ int ObjectRef::l_override_day_night_ratio(lua_State *L) } getServer(L)->overrideDayNightRatio(player, do_override, ratio); - lua_pushboolean(L, true); - return 1; + return 0; } // get_day_night_ratio(self) int ObjectRef::l_get_day_night_ratio(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; @@ -2192,14 +2232,14 @@ int ObjectRef::l_get_day_night_ratio(lua_State *L) int ObjectRef::l_set_minimap_modes(lua_State *L) { NO_MAP_LOCK_REQUIRED; - ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref = checkObject(L, 1); RemotePlayer *player = getplayer(ref); if (player == nullptr) return 0; luaL_checktype(L, 2, LUA_TTABLE); std::vector modes; - s16 selected_mode = luaL_checkint(L, 3); + s16 selected_mode = readParam(L, 3); lua_pushnil(L); while (lua_next(L, 2) != 0) { @@ -2241,6 +2281,64 @@ int ObjectRef::l_set_minimap_modes(lua_State *L) return 0; } +// set_lighting(self, lighting) +int ObjectRef::l_set_lighting(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkObject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + luaL_checktype(L, 2, LUA_TTABLE); + Lighting lighting = player->getLighting(); + lua_getfield(L, 2, "shadows"); + if (lua_istable(L, -1)) { + getfloatfield(L, -1, "intensity", lighting.shadow_intensity); + } + lua_pop(L, 1); // shadows + getfloatfield(L, -1, "saturation", lighting.saturation); + + getServer(L)->setLighting(player, lighting); + return 0; +} + +// get_lighting(self) +int ObjectRef::l_get_lighting(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkObject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + const Lighting &lighting = player->getLighting(); + + lua_newtable(L); // result + lua_newtable(L); // "shadows" + lua_pushnumber(L, lighting.shadow_intensity); + lua_setfield(L, -2, "intensity"); + lua_setfield(L, -2, "shadows"); + lua_pushnumber(L, lighting.saturation); + lua_setfield(L, -2, "saturation"); + return 1; +} + +// respawn(self) +int ObjectRef::l_respawn(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkObject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + getServer(L)->RespawnPlayer(player->getPeerId()); + lua_pushboolean(L, true); + return 1; +} + + ObjectRef::ObjectRef(ServerActiveObject *object): m_object(object) {} @@ -2257,33 +2355,17 @@ void ObjectRef::create(lua_State *L, ServerActiveObject *object) void ObjectRef::set_null(lua_State *L) { - ObjectRef *obj = checkobject(L, -1); + ObjectRef *obj = checkObject(L, -1); obj->m_object = nullptr; } void ObjectRef::Register(lua_State *L) { - lua_newtable(L); - int methodtable = lua_gettop(L); - luaL_newmetatable(L, className); - int metatable = lua_gettop(L); - - lua_pushliteral(L, "__metatable"); - lua_pushvalue(L, methodtable); - lua_settable(L, metatable); // hide metatable from Lua getmetatable() - - lua_pushliteral(L, "__index"); - lua_pushvalue(L, methodtable); - lua_settable(L, metatable); - - lua_pushliteral(L, "__gc"); - lua_pushcfunction(L, gc_object); - lua_settable(L, metatable); - - lua_pop(L, 1); // drop metatable - - luaL_openlib(L, 0, methods, 0); // fill methodtable - lua_pop(L, 1); // drop methodtable + static const luaL_Reg metamethods[] = { + {"__gc", gc_object}, + {0, 0} + }; + registerClass(L, className, methods, metamethods); } const char ObjectRef::className[] = "ObjectRef"; @@ -2394,5 +2476,9 @@ luaL_Reg ObjectRef::methods[] = { luamethod(ObjectRef, get_eye_offset), luamethod(ObjectRef, send_mapblock), luamethod(ObjectRef, set_minimap_modes), + luamethod(ObjectRef, set_lighting), + luamethod(ObjectRef, get_lighting), + luamethod(ObjectRef, respawn), + {0,0} };