2013-02-23 19:06:57 +01:00
|
|
|
/*
|
|
|
|
Minetest
|
|
|
|
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU Lesser General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2.1 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU Lesser General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Lesser General Public License along
|
|
|
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*/
|
|
|
|
|
2013-05-25 00:51:02 +02:00
|
|
|
#include "lua_api/l_object.h"
|
2018-04-02 23:51:08 +02:00
|
|
|
#include <cmath>
|
2013-08-11 04:09:45 +02:00
|
|
|
#include "lua_api/l_internal.h"
|
2013-05-25 00:51:02 +02:00
|
|
|
#include "lua_api/l_inventory.h"
|
|
|
|
#include "lua_api/l_item.h"
|
2018-04-06 10:52:29 +02:00
|
|
|
#include "lua_api/l_playermeta.h"
|
2013-08-11 04:09:45 +02:00
|
|
|
#include "common/c_converter.h"
|
|
|
|
#include "common/c_content.h"
|
2013-02-23 19:06:57 +01:00
|
|
|
#include "log.h"
|
|
|
|
#include "tool.h"
|
2017-08-18 19:25:07 +02:00
|
|
|
#include "remoteplayer.h"
|
2013-05-25 00:51:02 +02:00
|
|
|
#include "server.h"
|
2013-04-14 00:20:22 +02:00
|
|
|
#include "hud.h"
|
2017-04-25 19:38:08 +02:00
|
|
|
#include "scripting_server.h"
|
2020-04-11 11:22:15 +02:00
|
|
|
#include "server/luaentity_sao.h"
|
2020-04-11 09:59:09 +02:00
|
|
|
#include "server/player_sao.h"
|
2020-05-07 22:38:41 +02:00
|
|
|
#include "server/serverinventorymgr.h"
|
2013-04-14 00:20:22 +02:00
|
|
|
|
2013-02-23 19:06:57 +01:00
|
|
|
/*
|
|
|
|
ObjectRef
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
ObjectRef* ObjectRef::checkobject(lua_State *L, int narg)
|
|
|
|
{
|
|
|
|
luaL_checktype(L, narg, LUA_TUSERDATA);
|
|
|
|
void *ud = luaL_checkudata(L, narg, className);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (ud == nullptr)
|
|
|
|
luaL_typerror(L, narg, className);
|
2013-02-23 19:06:57 +01:00
|
|
|
return *(ObjectRef**)ud; // unbox pointer
|
|
|
|
}
|
|
|
|
|
|
|
|
ServerActiveObject* ObjectRef::getobject(ObjectRef *ref)
|
|
|
|
{
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = ref->m_object;
|
|
|
|
if (sao && sao->isGone())
|
|
|
|
return nullptr;
|
|
|
|
return sao;
|
2013-02-23 19:06:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
LuaEntitySAO* ObjectRef::getluaobject(ObjectRef *ref)
|
|
|
|
{
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
if (sao == nullptr)
|
|
|
|
return nullptr;
|
|
|
|
if (sao->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
|
|
|
|
return nullptr;
|
|
|
|
return (LuaEntitySAO*)sao;
|
2013-02-23 19:06:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
PlayerSAO* ObjectRef::getplayersao(ObjectRef *ref)
|
|
|
|
{
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
if (sao == nullptr)
|
|
|
|
return nullptr;
|
|
|
|
if (sao->getType() != ACTIVEOBJECT_TYPE_PLAYER)
|
|
|
|
return nullptr;
|
|
|
|
return (PlayerSAO*)sao;
|
2013-02-23 19:06:57 +01:00
|
|
|
}
|
|
|
|
|
2016-10-08 19:08:23 +02:00
|
|
|
RemotePlayer *ObjectRef::getplayer(ObjectRef *ref)
|
2013-02-23 19:06:57 +01:00
|
|
|
{
|
|
|
|
PlayerSAO *playersao = getplayersao(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (playersao == nullptr)
|
|
|
|
return nullptr;
|
2013-02-23 19:06:57 +01:00
|
|
|
return playersao->getPlayer();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Exported functions
|
|
|
|
|
|
|
|
// garbage collector
|
|
|
|
int ObjectRef::gc_object(lua_State *L) {
|
2020-10-22 17:18:01 +02:00
|
|
|
ObjectRef *obj = *(ObjectRef **)(lua_touserdata(L, 1));
|
|
|
|
delete obj;
|
2013-02-23 19:06:57 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// remove(self)
|
|
|
|
int ObjectRef::l_remove(lua_State *L)
|
|
|
|
{
|
2015-07-03 12:31:34 +02:00
|
|
|
GET_ENV_PTR;
|
|
|
|
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
if (sao == nullptr)
|
2015-07-03 12:31:34 +02:00
|
|
|
return 0;
|
2020-10-22 17:18:01 +02:00
|
|
|
if (sao->getType() == ACTIVEOBJECT_TYPE_PLAYER)
|
2015-07-03 12:31:34 +02:00
|
|
|
return 0;
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
sao->clearChildAttachments();
|
|
|
|
sao->clearParentAttachment();
|
2015-07-03 12:31:34 +02:00
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
verbosestream << "ObjectRef::l_remove(): id=" << sao->getId() << std::endl;
|
2021-01-02 15:14:29 +01:00
|
|
|
sao->markForRemoval();
|
2013-02-23 19:06:57 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-01-16 14:08:59 +01:00
|
|
|
// get_pos(self)
|
|
|
|
int ObjectRef::l_get_pos(lua_State *L)
|
2013-02-23 19:06:57 +01:00
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
if (sao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
push_v3f(L, sao->getBasePosition() / BS);
|
2013-02-23 19:06:57 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-01-16 14:08:59 +01:00
|
|
|
// set_pos(self, pos)
|
|
|
|
int ObjectRef::l_set_pos(lua_State *L)
|
2013-02-23 19:06:57 +01:00
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
if (sao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
2013-02-23 19:06:57 +01:00
|
|
|
v3f pos = checkFloatPos(L, 2);
|
2020-10-22 17:18:01 +02:00
|
|
|
|
|
|
|
sao->setPos(pos);
|
2013-02-23 19:06:57 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
// move_to(self, pos, continuous)
|
2017-01-16 14:08:59 +01:00
|
|
|
int ObjectRef::l_move_to(lua_State *L)
|
2013-02-23 19:06:57 +01:00
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
if (sao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
2013-02-23 19:06:57 +01:00
|
|
|
v3f pos = checkFloatPos(L, 2);
|
2018-06-30 17:11:38 +02:00
|
|
|
bool continuous = readParam<bool>(L, 3);
|
2020-10-22 17:18:01 +02:00
|
|
|
|
|
|
|
sao->moveTo(pos, continuous);
|
2013-02-23 19:06:57 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// punch(self, puncher, time_from_last_punch, tool_capabilities, dir)
|
|
|
|
int ObjectRef::l_punch(lua_State *L)
|
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2013-05-25 00:51:02 +02:00
|
|
|
ObjectRef *puncher_ref = checkobject(L, 2);
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
2013-05-25 00:51:02 +02:00
|
|
|
ServerActiveObject *puncher = getobject(puncher_ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (sao == nullptr || puncher == nullptr)
|
2019-04-11 21:45:39 +02:00
|
|
|
return 0;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
2020-11-04 21:43:18 +01:00
|
|
|
float time_from_last_punch = readParam<float>(L, 3, 1000000.0f);
|
2013-02-23 19:06:57 +01:00
|
|
|
ToolCapabilities toolcap = read_tool_capabilities(L, 4);
|
2020-11-04 21:43:18 +01:00
|
|
|
v3f dir = readParam<v3f>(L, 5, sao->getBasePosition() - puncher->getBasePosition());
|
2020-10-22 17:18:01 +02:00
|
|
|
dir.normalize();
|
2015-03-02 17:31:31 +01:00
|
|
|
|
2021-10-31 23:33:33 +01:00
|
|
|
u32 wear = sao->punch(dir, &toolcap, puncher, time_from_last_punch);
|
2019-09-22 22:12:21 +02:00
|
|
|
lua_pushnumber(L, wear);
|
2015-03-02 17:31:31 +01:00
|
|
|
|
2019-09-22 22:12:21 +02:00
|
|
|
return 1;
|
2013-02-23 19:06:57 +01:00
|
|
|
}
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
// right_click(self, clicker)
|
2013-02-23 19:06:57 +01:00
|
|
|
int ObjectRef::l_right_click(lua_State *L)
|
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
|
|
|
ObjectRef *ref2 = checkobject(L, 2);
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
ServerActiveObject *sao2 = getobject(ref2);
|
|
|
|
if (sao == nullptr || sao2 == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
sao->rightClick(sao2);
|
2013-02-23 19:06:57 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
// set_hp(self, hp, reason)
|
2013-02-23 19:06:57 +01:00
|
|
|
int ObjectRef::l_set_hp(lua_State *L)
|
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
if (sao == nullptr)
|
2018-03-28 17:05:18 +02:00
|
|
|
return 0;
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
int hp = readParam<float>(L, 2);
|
2018-03-28 17:05:18 +02:00
|
|
|
PlayerHPChangeReason reason(PlayerHPChangeReason::SET_HP);
|
2020-10-22 17:18:01 +02:00
|
|
|
|
2018-03-28 17:05:18 +02:00
|
|
|
reason.from_mod = true;
|
|
|
|
if (lua_istable(L, 3)) {
|
|
|
|
lua_pushvalue(L, 3);
|
|
|
|
|
|
|
|
lua_getfield(L, -1, "type");
|
2018-06-30 17:11:38 +02:00
|
|
|
if (lua_isstring(L, -1) &&
|
|
|
|
!reason.setTypeFromString(readParam<std::string>(L, -1))) {
|
2018-03-28 17:05:18 +02:00
|
|
|
errorstream << "Bad type given!" << std::endl;
|
|
|
|
}
|
|
|
|
lua_pop(L, 1);
|
|
|
|
|
|
|
|
reason.lua_reference = luaL_ref(L, LUA_REGISTRYINDEX);
|
|
|
|
}
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
sao->setHP(hp, reason);
|
2019-03-12 08:56:56 +01:00
|
|
|
if (reason.hasLuaReference())
|
|
|
|
luaL_unref(L, LUA_REGISTRYINDEX, reason.lua_reference);
|
2013-02-23 19:06:57 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get_hp(self)
|
|
|
|
int ObjectRef::l_get_hp(lua_State *L)
|
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
if (sao == nullptr) {
|
2013-02-23 19:06:57 +01:00
|
|
|
// Default hp is 1
|
|
|
|
lua_pushnumber(L, 1);
|
|
|
|
return 1;
|
|
|
|
}
|
2020-10-22 17:18:01 +02:00
|
|
|
|
|
|
|
int hp = sao->getHP();
|
|
|
|
|
2013-02-23 19:06:57 +01:00
|
|
|
lua_pushnumber(L, hp);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get_inventory(self)
|
|
|
|
int ObjectRef::l_get_inventory(lua_State *L)
|
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
if (sao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
InventoryLocation loc = sao->getInventoryLocation();
|
|
|
|
if (getServerInventoryMgr(L)->getInventory(loc) != nullptr)
|
2013-02-23 19:06:57 +01:00
|
|
|
InvRef::create(L, loc);
|
|
|
|
else
|
|
|
|
lua_pushnil(L); // An object may have no inventory (nil)
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get_wield_list(self)
|
|
|
|
int ObjectRef::l_get_wield_list(lua_State *L)
|
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
if (sao == nullptr)
|
2019-08-07 19:16:31 +02:00
|
|
|
return 0;
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
lua_pushstring(L, sao->getWieldList().c_str());
|
2013-02-23 19:06:57 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get_wield_index(self)
|
|
|
|
int ObjectRef::l_get_wield_index(lua_State *L)
|
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
if (sao == nullptr)
|
2019-08-07 19:16:31 +02:00
|
|
|
return 0;
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
lua_pushinteger(L, sao->getWieldIndex() + 1);
|
2013-02-23 19:06:57 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get_wielded_item(self)
|
|
|
|
int ObjectRef::l_get_wielded_item(lua_State *L)
|
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
if (sao == nullptr) {
|
2013-02-23 19:06:57 +01:00
|
|
|
// Empty ItemStack
|
|
|
|
LuaItemStack::create(L, ItemStack());
|
|
|
|
return 1;
|
|
|
|
}
|
2019-08-07 19:16:31 +02:00
|
|
|
|
2019-09-21 11:44:24 +02:00
|
|
|
ItemStack selected_item;
|
2020-10-22 17:18:01 +02:00
|
|
|
sao->getWieldedItem(&selected_item, nullptr);
|
2019-09-21 11:44:24 +02:00
|
|
|
LuaItemStack::create(L, selected_item);
|
2013-02-23 19:06:57 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
// set_wielded_item(self, item)
|
2013-02-23 19:06:57 +01:00
|
|
|
int ObjectRef::l_set_wielded_item(lua_State *L)
|
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
if (sao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
2017-01-31 14:18:52 +01:00
|
|
|
ItemStack item = read_item(L, 2, getServer(L)->idef());
|
2020-10-22 17:18:01 +02:00
|
|
|
|
|
|
|
bool success = sao->setWieldedItem(item);
|
|
|
|
if (success && sao->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
|
|
|
|
getServer(L)->SendInventory((PlayerSAO *)sao, true);
|
2015-03-04 11:29:34 +01:00
|
|
|
}
|
2013-02-23 19:06:57 +01:00
|
|
|
lua_pushboolean(L, success);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// set_armor_groups(self, groups)
|
|
|
|
int ObjectRef::l_set_armor_groups(lua_State *L)
|
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
if (sao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
2013-02-23 19:06:57 +01:00
|
|
|
ItemGroupList groups;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
2013-02-23 19:06:57 +01:00
|
|
|
read_groups(L, 2, groups);
|
2021-01-30 12:41:27 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
sao->setArmorGroups(groups);
|
2013-02-23 19:06:57 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-05-26 14:10:08 +02:00
|
|
|
// get_armor_groups(self)
|
|
|
|
int ObjectRef::l_get_armor_groups(lua_State *L)
|
|
|
|
{
|
|
|
|
NO_MAP_LOCK_REQUIRED;
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
if (sao == nullptr)
|
2015-05-26 14:10:08 +02:00
|
|
|
return 0;
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
push_groups(L, sao->getArmorGroups());
|
2015-05-26 14:10:08 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-02-21 22:38:53 +01:00
|
|
|
// set_animation(self, frame_range, frame_speed, frame_blend, frame_loop)
|
2013-02-23 19:06:57 +01:00
|
|
|
int ObjectRef::l_set_animation(lua_State *L)
|
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
if (sao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
2020-11-04 21:43:18 +01:00
|
|
|
v2f frame_range = readParam<v2f>(L, 2, v2f(1, 1));
|
|
|
|
float frame_speed = readParam<float>(L, 3, 15.0f);
|
|
|
|
float frame_blend = readParam<float>(L, 4, 0.0f);
|
|
|
|
bool frame_loop = readParam<bool>(L, 5, true);
|
2020-10-22 17:18:01 +02:00
|
|
|
|
2020-11-04 21:43:18 +01:00
|
|
|
sao->setAnimation(frame_range, frame_speed, frame_blend, frame_loop);
|
2013-02-23 19:06:57 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-05-26 14:10:08 +02:00
|
|
|
// get_animation(self)
|
|
|
|
int ObjectRef::l_get_animation(lua_State *L)
|
|
|
|
{
|
|
|
|
NO_MAP_LOCK_REQUIRED;
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
if (sao == nullptr)
|
2015-05-26 14:10:08 +02:00
|
|
|
return 0;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
2021-01-21 18:37:38 +01:00
|
|
|
v2f frames = v2f(1, 1);
|
2015-05-26 14:10:08 +02:00
|
|
|
float frame_speed = 15;
|
|
|
|
float frame_blend = 0;
|
2015-02-21 22:38:53 +01:00
|
|
|
bool frame_loop = true;
|
2015-05-26 14:10:08 +02:00
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
sao->getAnimation(&frames, &frame_speed, &frame_blend, &frame_loop);
|
2015-05-26 14:10:08 +02:00
|
|
|
push_v2f(L, frames);
|
|
|
|
lua_pushnumber(L, frame_speed);
|
|
|
|
lua_pushnumber(L, frame_blend);
|
2015-02-21 22:38:53 +01:00
|
|
|
lua_pushboolean(L, frame_loop);
|
|
|
|
return 4;
|
2015-05-26 14:10:08 +02:00
|
|
|
}
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
// set_local_animation(self, idle, walk, dig, walk_while_dig, frame_speed)
|
2014-01-08 13:47:53 +01:00
|
|
|
int ObjectRef::l_set_local_animation(lua_State *L)
|
|
|
|
{
|
2015-10-25 05:45:18 +01:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2014-01-08 13:47:53 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2016-10-08 12:21:41 +02:00
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2014-01-08 13:47:53 +01:00
|
|
|
return 0;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
2014-04-12 13:50:22 +02:00
|
|
|
v2s32 frames[4];
|
2014-01-08 13:47:53 +01:00
|
|
|
for (int i=0;i<4;i++) {
|
2015-06-25 14:57:10 +02:00
|
|
|
if (!lua_isnil(L, 2+1))
|
2014-04-12 13:50:22 +02:00
|
|
|
frames[i] = read_v2s32(L, 2+i);
|
2014-01-08 13:47:53 +01:00
|
|
|
}
|
2020-11-04 21:43:18 +01:00
|
|
|
float frame_speed = readParam<float>(L, 6, 30.0f);
|
2014-01-08 13:47:53 +01:00
|
|
|
|
2018-03-08 22:19:25 +01:00
|
|
|
getServer(L)->setLocalPlayerAnimations(player, frames, frame_speed);
|
2014-01-08 13:47:53 +01:00
|
|
|
lua_pushboolean(L, true);
|
2018-03-08 22:19:25 +01:00
|
|
|
return 1;
|
2014-01-08 13:47:53 +01:00
|
|
|
}
|
|
|
|
|
2015-05-26 14:10:08 +02:00
|
|
|
// get_local_animation(self)
|
|
|
|
int ObjectRef::l_get_local_animation(lua_State *L)
|
|
|
|
{
|
2020-04-10 22:06:24 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2015-05-26 14:10:08 +02:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2016-10-08 16:31:22 +02:00
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2015-05-26 14:10:08 +02:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
v2s32 frames[4];
|
|
|
|
float frame_speed;
|
|
|
|
player->getLocalAnimations(frames, &frame_speed);
|
|
|
|
|
2017-08-20 13:30:50 +02:00
|
|
|
for (const v2s32 &frame : frames) {
|
2017-08-19 22:23:47 +02:00
|
|
|
push_v2s32(L, frame);
|
2015-05-26 14:10:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
lua_pushnumber(L, frame_speed);
|
|
|
|
return 5;
|
|
|
|
}
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
// set_eye_offset(self, firstperson, thirdperson)
|
2014-04-11 15:32:46 +02:00
|
|
|
int ObjectRef::l_set_eye_offset(lua_State *L)
|
|
|
|
{
|
2015-10-25 05:45:18 +01:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2014-04-11 15:32:46 +02:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2016-10-08 12:21:41 +02:00
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2014-04-11 15:32:46 +02:00
|
|
|
return 0;
|
2015-01-07 20:08:51 +01:00
|
|
|
|
2021-01-21 18:37:38 +01:00
|
|
|
v3f offset_first = readParam<v3f>(L, 2, v3f(0, 0, 0));
|
|
|
|
v3f offset_third = readParam<v3f>(L, 3, v3f(0, 0, 0));
|
2014-04-11 15:32:46 +02:00
|
|
|
|
|
|
|
// Prevent abuse of offset values (keep player always visible)
|
|
|
|
offset_third.X = rangelim(offset_third.X,-10,10);
|
|
|
|
offset_third.Z = rangelim(offset_third.Z,-5,5);
|
2020-10-22 17:18:01 +02:00
|
|
|
/* TODO: if possible: improve the camera collision detection to allow Y <= -1.5) */
|
2014-04-11 15:32:46 +02:00
|
|
|
offset_third.Y = rangelim(offset_third.Y,-10,15); //1.5*BS
|
|
|
|
|
2018-03-08 22:19:25 +01:00
|
|
|
getServer(L)->setPlayerEyeOffset(player, offset_first, offset_third);
|
2014-04-11 15:32:46 +02:00
|
|
|
lua_pushboolean(L, true);
|
2018-03-08 22:19:25 +01:00
|
|
|
return 1;
|
2014-04-11 15:32:46 +02:00
|
|
|
}
|
|
|
|
|
2015-05-26 14:10:08 +02:00
|
|
|
// get_eye_offset(self)
|
|
|
|
int ObjectRef::l_get_eye_offset(lua_State *L)
|
|
|
|
{
|
2015-10-25 05:45:18 +01:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2015-05-26 14:10:08 +02:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2016-10-08 16:31:22 +02:00
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2015-05-26 14:10:08 +02:00
|
|
|
return 0;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
2015-05-26 14:10:08 +02:00
|
|
|
push_v3f(L, player->eye_offset_first);
|
|
|
|
push_v3f(L, player->eye_offset_third);
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
Force send a mapblock to a player (#8140)
* Force send a mapblock to a player.
Send a single mapblock to a specific remote player.
This is badly needed for mods and games where players are teleported
into terrain which may be not generated, loaded, or modified
significantly since the last player visit.
In all these cases, the player currently ends up in void, air, or
inside blocks which not only looks bad, but has the effect that the
player might end up falling and then the server needs to correct for
the player position again later, which is a hack.
The best solution is to send at least the single mapblock that the
player will be teleported to. I've tested this with ITB which does this
all the time, and I can see it functioning as expected (it even shows
a half loaded entry hallway, as the further blocks aren't loaded yet).
The parameter is a blockpos (table of x, y, z), not a regular pos.
The function may return false if the call failed. This is most likely
due to the target position not being generated or emerged yet, or
another internal failure, such as the player not being initialized.
* Always send mapblock on teleport or respawn.
This avoids the need for mods to send a mapblock on teleport or
respawn, since any call to `player:set_pos()` will pass this code.
2019-04-28 01:42:13 +02:00
|
|
|
// 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);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
Force send a mapblock to a player (#8140)
* Force send a mapblock to a player.
Send a single mapblock to a specific remote player.
This is badly needed for mods and games where players are teleported
into terrain which may be not generated, loaded, or modified
significantly since the last player visit.
In all these cases, the player currently ends up in void, air, or
inside blocks which not only looks bad, but has the effect that the
player might end up falling and then the server needs to correct for
the player position again later, which is a hack.
The best solution is to send at least the single mapblock that the
player will be teleported to. I've tested this with ITB which does this
all the time, and I can see it functioning as expected (it even shows
a half loaded entry hallway, as the further blocks aren't loaded yet).
The parameter is a blockpos (table of x, y, z), not a regular pos.
The function may return false if the call failed. This is most likely
due to the target position not being generated or emerged yet, or
another internal failure, such as the player not being initialized.
* Always send mapblock on teleport or respawn.
This avoids the need for mods to send a mapblock on teleport or
respawn, since any call to `player:set_pos()` will pass this code.
2019-04-28 01:42:13 +02:00
|
|
|
return 0;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
|
|
|
v3s16 pos = read_v3s16(L, 2);
|
Force send a mapblock to a player (#8140)
* Force send a mapblock to a player.
Send a single mapblock to a specific remote player.
This is badly needed for mods and games where players are teleported
into terrain which may be not generated, loaded, or modified
significantly since the last player visit.
In all these cases, the player currently ends up in void, air, or
inside blocks which not only looks bad, but has the effect that the
player might end up falling and then the server needs to correct for
the player position again later, which is a hack.
The best solution is to send at least the single mapblock that the
player will be teleported to. I've tested this with ITB which does this
all the time, and I can see it functioning as expected (it even shows
a half loaded entry hallway, as the further blocks aren't loaded yet).
The parameter is a blockpos (table of x, y, z), not a regular pos.
The function may return false if the call failed. This is most likely
due to the target position not being generated or emerged yet, or
another internal failure, such as the player not being initialized.
* Always send mapblock on teleport or respawn.
This avoids the need for mods to send a mapblock on teleport or
respawn, since any call to `player:set_pos()` will pass this code.
2019-04-28 01:42:13 +02:00
|
|
|
|
|
|
|
session_t peer_id = player->getPeerId();
|
2020-10-22 17:18:01 +02:00
|
|
|
bool r = getServer(L)->SendBlock(peer_id, pos);
|
Force send a mapblock to a player (#8140)
* Force send a mapblock to a player.
Send a single mapblock to a specific remote player.
This is badly needed for mods and games where players are teleported
into terrain which may be not generated, loaded, or modified
significantly since the last player visit.
In all these cases, the player currently ends up in void, air, or
inside blocks which not only looks bad, but has the effect that the
player might end up falling and then the server needs to correct for
the player position again later, which is a hack.
The best solution is to send at least the single mapblock that the
player will be teleported to. I've tested this with ITB which does this
all the time, and I can see it functioning as expected (it even shows
a half loaded entry hallway, as the further blocks aren't loaded yet).
The parameter is a blockpos (table of x, y, z), not a regular pos.
The function may return false if the call failed. This is most likely
due to the target position not being generated or emerged yet, or
another internal failure, such as the player not being initialized.
* Always send mapblock on teleport or respawn.
This avoids the need for mods to send a mapblock on teleport or
respawn, since any call to `player:set_pos()` will pass this code.
2019-04-28 01:42:13 +02:00
|
|
|
|
|
|
|
lua_pushboolean(L, r);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-09-01 11:15:12 +02:00
|
|
|
// 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);
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
if (sao == nullptr)
|
2017-09-01 11:15:12 +02:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!lua_isnil(L, 2)) {
|
2020-10-22 17:18:01 +02:00
|
|
|
float frame_speed = readParam<float>(L, 2);
|
|
|
|
sao->setAnimationSpeed(frame_speed);
|
2017-09-01 11:15:12 +02:00
|
|
|
lua_pushboolean(L, true);
|
|
|
|
} else {
|
|
|
|
lua_pushboolean(L, false);
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
// set_bone_position(self, bone, position, rotation)
|
2013-02-23 19:06:57 +01:00
|
|
|
int ObjectRef::l_set_bone_position(lua_State *L)
|
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
if (sao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
2021-01-21 18:37:38 +01:00
|
|
|
std::string bone = readParam<std::string>(L, 2, "");
|
|
|
|
v3f position = readParam<v3f>(L, 3, v3f(0, 0, 0));
|
|
|
|
v3f rotation = readParam<v3f>(L, 4, v3f(0, 0, 0));
|
2020-10-22 17:18:01 +02:00
|
|
|
|
|
|
|
sao->setBonePosition(bone, position, rotation);
|
2013-02-23 19:06:57 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-05-26 14:10:08 +02:00
|
|
|
// get_bone_position(self, bone)
|
|
|
|
int ObjectRef::l_get_bone_position(lua_State *L)
|
|
|
|
{
|
|
|
|
NO_MAP_LOCK_REQUIRED;
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
if (sao == nullptr)
|
2015-05-26 14:10:08 +02:00
|
|
|
return 0;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
2021-01-21 18:37:38 +01:00
|
|
|
std::string bone = readParam<std::string>(L, 2, "");
|
2015-05-26 14:10:08 +02:00
|
|
|
|
|
|
|
v3f position = v3f(0, 0, 0);
|
|
|
|
v3f rotation = v3f(0, 0, 0);
|
2020-10-22 17:18:01 +02:00
|
|
|
sao->getBonePosition(bone, &position, &rotation);
|
2015-05-26 14:10:08 +02:00
|
|
|
|
|
|
|
push_v3f(L, position);
|
|
|
|
push_v3f(L, rotation);
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:10:34 +02:00
|
|
|
// set_attach(self, parent, bone, position, rotation, force_visible)
|
2013-02-23 19:06:57 +01:00
|
|
|
int ObjectRef::l_set_attach(lua_State *L)
|
|
|
|
{
|
2015-07-03 12:31:34 +02:00
|
|
|
GET_ENV_PTR;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
|
|
|
ObjectRef *parent_ref = checkobject(L, 2);
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
2013-02-23 19:06:57 +01:00
|
|
|
ServerActiveObject *parent = getobject(parent_ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (sao == nullptr || parent == nullptr)
|
2015-07-03 12:31:34 +02:00
|
|
|
return 0;
|
2020-10-22 17:18:01 +02:00
|
|
|
if (sao == parent)
|
2020-04-27 11:27:27 +02:00
|
|
|
throw LuaError("ObjectRef::set_attach: attaching object to itself is not allowed.");
|
|
|
|
|
2021-01-21 18:37:38 +01:00
|
|
|
int parent_id;
|
2017-08-19 22:23:47 +02:00
|
|
|
std::string bone;
|
2021-01-21 18:37:38 +01:00
|
|
|
v3f position;
|
|
|
|
v3f rotation;
|
2020-10-04 15:10:34 +02:00
|
|
|
bool force_visible;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
|
|
|
sao->getAttachment(&parent_id, &bone, &position, &rotation, &force_visible);
|
2015-07-03 12:31:34 +02:00
|
|
|
if (parent_id) {
|
|
|
|
ServerActiveObject *old_parent = env->getActiveObject(parent_id);
|
2020-10-22 17:18:01 +02:00
|
|
|
old_parent->removeAttachmentChild(sao->getId());
|
2015-07-03 12:31:34 +02:00
|
|
|
}
|
|
|
|
|
2021-01-21 18:37:38 +01:00
|
|
|
bone = readParam<std::string>(L, 3, "");
|
|
|
|
position = readParam<v3f>(L, 4, v3f(0, 0, 0));
|
|
|
|
rotation = readParam<v3f>(L, 5, v3f(0, 0, 0));
|
2020-10-04 15:10:34 +02:00
|
|
|
force_visible = readParam<bool>(L, 6, false);
|
2020-10-22 17:18:01 +02:00
|
|
|
|
|
|
|
sao->setAttachment(parent->getId(), bone, position, rotation, force_visible);
|
|
|
|
parent->addAttachmentChild(sao->getId());
|
2013-02-23 19:06:57 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-05-26 14:10:08 +02:00
|
|
|
// get_attach(self)
|
|
|
|
int ObjectRef::l_get_attach(lua_State *L)
|
|
|
|
{
|
|
|
|
GET_ENV_PTR;
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
if (sao == nullptr)
|
2015-05-26 14:10:08 +02:00
|
|
|
return 0;
|
|
|
|
|
2021-01-21 18:37:38 +01:00
|
|
|
int parent_id;
|
2017-08-19 22:23:47 +02:00
|
|
|
std::string bone;
|
2021-01-21 18:37:38 +01:00
|
|
|
v3f position;
|
|
|
|
v3f rotation;
|
2020-10-04 15:10:34 +02:00
|
|
|
bool force_visible;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
|
|
|
sao->getAttachment(&parent_id, &bone, &position, &rotation, &force_visible);
|
|
|
|
if (parent_id == 0)
|
2015-05-26 14:10:08 +02:00
|
|
|
return 0;
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *parent = env->getActiveObject(parent_id);
|
2015-05-26 14:10:08 +02:00
|
|
|
getScriptApiBase(L)->objectrefGetOrCreate(L, parent);
|
|
|
|
lua_pushlstring(L, bone.c_str(), bone.size());
|
|
|
|
push_v3f(L, position);
|
|
|
|
push_v3f(L, rotation);
|
2020-10-04 15:10:34 +02:00
|
|
|
lua_pushboolean(L, force_visible);
|
|
|
|
return 5;
|
2015-05-26 14:10:08 +02:00
|
|
|
}
|
|
|
|
|
2020-10-13 21:27:52 +02:00
|
|
|
// get_children(self)
|
|
|
|
int ObjectRef::l_get_children(lua_State *L)
|
|
|
|
{
|
|
|
|
GET_ENV_PTR;
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
if (sao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
const std::unordered_set<int> child_ids = sao->getAttachmentChildIds();
|
|
|
|
int i = 0;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
2020-10-13 21:27:52 +02:00
|
|
|
lua_createtable(L, child_ids.size(), 0);
|
|
|
|
for (const int id : child_ids) {
|
|
|
|
ServerActiveObject *child = env->getActiveObject(id);
|
|
|
|
getScriptApiBase(L)->objectrefGetOrCreate(L, child);
|
|
|
|
lua_rawseti(L, -2, ++i);
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-02-23 19:06:57 +01:00
|
|
|
// set_detach(self)
|
|
|
|
int ObjectRef::l_set_detach(lua_State *L)
|
|
|
|
{
|
2015-07-03 12:31:34 +02:00
|
|
|
GET_ENV_PTR;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
if (sao == nullptr)
|
2015-07-03 12:31:34 +02:00
|
|
|
return 0;
|
2017-01-21 17:30:55 +01:00
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
sao->clearParentAttachment();
|
2013-02-23 19:06:57 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// set_properties(self, properties)
|
|
|
|
int ObjectRef::l_set_properties(lua_State *L)
|
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
if (sao == nullptr)
|
2019-05-21 19:37:58 +02:00
|
|
|
return 0;
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
ObjectProperties *prop = sao->accessObjectProperties();
|
|
|
|
if (prop == nullptr)
|
2013-02-23 19:06:57 +01:00
|
|
|
return 0;
|
2019-05-21 19:37:58 +02:00
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
read_object_properties(L, 2, sao, prop, getServer(L)->idef());
|
2021-08-19 20:14:22 +02:00
|
|
|
prop->validate();
|
2020-10-22 17:18:01 +02:00
|
|
|
sao->notifyObjectPropertiesModified();
|
2013-02-23 19:06:57 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-05-26 14:10:08 +02:00
|
|
|
// get_properties(self)
|
|
|
|
int ObjectRef::l_get_properties(lua_State *L)
|
|
|
|
{
|
|
|
|
NO_MAP_LOCK_REQUIRED;
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
if (sao == nullptr)
|
2015-05-26 14:10:08 +02:00
|
|
|
return 0;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
|
|
|
ObjectProperties *prop = sao->accessObjectProperties();
|
|
|
|
if (prop == nullptr)
|
2015-05-26 14:10:08 +02:00
|
|
|
return 0;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
2015-05-26 14:10:08 +02:00
|
|
|
push_object_properties(L, prop);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-05-12 05:49:14 +02:00
|
|
|
// is_player(self)
|
|
|
|
int ObjectRef::l_is_player(lua_State *L)
|
|
|
|
{
|
|
|
|
NO_MAP_LOCK_REQUIRED;
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2016-10-08 16:31:22 +02:00
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
lua_pushboolean(L, (player != nullptr));
|
2015-05-12 05:49:14 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-11-20 23:46:33 +01:00
|
|
|
// set_nametag_attributes(self, attributes)
|
|
|
|
int ObjectRef::l_set_nametag_attributes(lua_State *L)
|
|
|
|
{
|
|
|
|
NO_MAP_LOCK_REQUIRED;
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
if (sao == nullptr)
|
2015-11-20 23:46:33 +01:00
|
|
|
return 0;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
|
|
|
ObjectProperties *prop = sao->accessObjectProperties();
|
|
|
|
if (prop == nullptr)
|
2015-11-20 23:46:33 +01:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
lua_getfield(L, 2, "color");
|
|
|
|
if (!lua_isnil(L, -1)) {
|
|
|
|
video::SColor color = prop->nametag_color;
|
|
|
|
read_color(L, -1, &color);
|
|
|
|
prop->nametag_color = color;
|
|
|
|
}
|
|
|
|
lua_pop(L, 1);
|
|
|
|
|
2021-02-17 20:51:28 +01:00
|
|
|
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);
|
|
|
|
|
2015-11-20 23:46:33 +01:00
|
|
|
std::string nametag = getstringfield_default(L, 2, "text", "");
|
2017-01-11 20:25:25 +01:00
|
|
|
prop->nametag = nametag;
|
2015-11-20 23:46:33 +01:00
|
|
|
|
2021-08-19 20:14:22 +02:00
|
|
|
prop->validate();
|
2020-10-22 17:18:01 +02:00
|
|
|
sao->notifyObjectPropertiesModified();
|
2015-11-20 23:46:33 +01:00
|
|
|
lua_pushboolean(L, true);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get_nametag_attributes(self)
|
|
|
|
int ObjectRef::l_get_nametag_attributes(lua_State *L)
|
|
|
|
{
|
|
|
|
NO_MAP_LOCK_REQUIRED;
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
if (sao == nullptr)
|
2015-11-20 23:46:33 +01:00
|
|
|
return 0;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
|
|
|
ObjectProperties *prop = sao->accessObjectProperties();
|
2015-11-20 23:46:33 +01:00
|
|
|
if (!prop)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
lua_newtable(L);
|
2021-02-17 20:51:28 +01:00
|
|
|
|
|
|
|
push_ARGB8(L, prop->nametag_color);
|
2015-11-20 23:46:33 +01:00
|
|
|
lua_setfield(L, -2, "color");
|
2021-02-17 20:51:28 +01:00
|
|
|
|
|
|
|
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");
|
|
|
|
}
|
|
|
|
|
2015-11-20 23:46:33 +01:00
|
|
|
lua_pushstring(L, prop->nametag.c_str());
|
|
|
|
lua_setfield(L, -2, "text");
|
2021-02-17 20:51:28 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
2015-11-20 23:46:33 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-02-23 19:06:57 +01:00
|
|
|
/* LuaEntitySAO-only */
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
// set_velocity(self, velocity)
|
2017-01-16 14:08:59 +01:00
|
|
|
int ObjectRef::l_set_velocity(lua_State *L)
|
2013-02-23 19:06:57 +01:00
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
LuaEntitySAO *sao = getluaobject(ref);
|
|
|
|
if (sao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
v3f vel = checkFloatPos(L, 2);
|
|
|
|
|
|
|
|
sao->setVelocity(vel);
|
2013-02-23 19:06:57 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
// add_velocity(self, velocity)
|
2018-03-31 14:48:38 +02:00
|
|
|
int ObjectRef::l_add_velocity(lua_State *L)
|
|
|
|
{
|
|
|
|
NO_MAP_LOCK_REQUIRED;
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
if (sao == nullptr)
|
2018-03-31 14:48:38 +02:00
|
|
|
return 0;
|
2020-10-04 01:33:45 +02:00
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
v3f vel = checkFloatPos(L, 2);
|
|
|
|
|
|
|
|
if (sao->getType() == ACTIVEOBJECT_TYPE_LUAENTITY) {
|
|
|
|
LuaEntitySAO *entitysao = dynamic_cast<LuaEntitySAO*>(sao);
|
|
|
|
entitysao->addVelocity(vel);
|
|
|
|
} else if (sao->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
|
|
|
|
PlayerSAO *playersao = dynamic_cast<PlayerSAO*>(sao);
|
|
|
|
playersao->setMaxSpeedOverride(vel);
|
|
|
|
getServer(L)->SendPlayerSpeed(playersao->getPeerID(), vel);
|
2020-10-04 01:33:45 +02:00
|
|
|
}
|
|
|
|
|
2018-03-31 14:48:38 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-01-16 14:08:59 +01:00
|
|
|
// get_velocity(self)
|
|
|
|
int ObjectRef::l_get_velocity(lua_State *L)
|
2013-02-23 19:06:57 +01:00
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
ServerActiveObject *sao = getobject(ref);
|
|
|
|
if (sao == nullptr)
|
2020-10-04 01:33:45 +02:00
|
|
|
return 0;
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
if (sao->getType() == ACTIVEOBJECT_TYPE_LUAENTITY) {
|
|
|
|
LuaEntitySAO *entitysao = dynamic_cast<LuaEntitySAO*>(sao);
|
|
|
|
v3f vel = entitysao->getVelocity();
|
|
|
|
pushFloatPos(L, vel);
|
2020-10-04 01:33:45 +02:00
|
|
|
return 1;
|
2020-10-22 17:18:01 +02:00
|
|
|
} else if (sao->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
|
|
|
|
RemotePlayer *player = dynamic_cast<PlayerSAO*>(sao)->getPlayer();
|
2020-10-04 01:33:45 +02:00
|
|
|
push_v3f(L, player->getSpeed() / BS);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
lua_pushnil(L);
|
2013-02-23 19:06:57 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
// set_acceleration(self, acceleration)
|
2017-01-16 14:08:59 +01:00
|
|
|
int ObjectRef::l_set_acceleration(lua_State *L)
|
2013-02-23 19:06:57 +01:00
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
LuaEntitySAO *entitysao = getluaobject(ref);
|
|
|
|
if (entitysao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
v3f acceleration = checkFloatPos(L, 2);
|
|
|
|
|
|
|
|
entitysao->setAcceleration(acceleration);
|
2013-02-23 19:06:57 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-01-16 14:08:59 +01:00
|
|
|
// get_acceleration(self)
|
|
|
|
int ObjectRef::l_get_acceleration(lua_State *L)
|
2013-02-23 19:06:57 +01:00
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
LuaEntitySAO *entitysao = getluaobject(ref);
|
|
|
|
if (entitysao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
v3f acceleration = entitysao->getAcceleration();
|
|
|
|
pushFloatPos(L, acceleration);
|
2013-02-23 19:06:57 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
// set_rotation(self, rotation)
|
2018-11-28 09:38:50 +01:00
|
|
|
int ObjectRef::l_set_rotation(lua_State *L)
|
|
|
|
{
|
|
|
|
NO_MAP_LOCK_REQUIRED;
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
LuaEntitySAO *entitysao = getluaobject(ref);
|
|
|
|
if (entitysao == nullptr)
|
2018-11-28 09:38:50 +01:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
v3f rotation = check_v3f(L, 2) * core::RADTODEG;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
|
|
|
entitysao->setRotation(rotation);
|
2018-11-28 09:38:50 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get_rotation(self)
|
|
|
|
int ObjectRef::l_get_rotation(lua_State *L)
|
|
|
|
{
|
|
|
|
NO_MAP_LOCK_REQUIRED;
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
LuaEntitySAO *entitysao = getluaobject(ref);
|
|
|
|
if (entitysao == nullptr)
|
2018-11-28 09:38:50 +01:00
|
|
|
return 0;
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
v3f rotation = entitysao->getRotation() * core::DEGTORAD;
|
|
|
|
|
2018-11-28 09:38:50 +01:00
|
|
|
lua_newtable(L);
|
|
|
|
push_v3f(L, rotation);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
// set_yaw(self, yaw)
|
2017-01-16 14:08:59 +01:00
|
|
|
int ObjectRef::l_set_yaw(lua_State *L)
|
2013-02-23 19:06:57 +01:00
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
LuaEntitySAO *entitysao = getluaobject(ref);
|
|
|
|
if (entitysao == nullptr)
|
|
|
|
return 0;
|
2018-11-28 09:38:50 +01:00
|
|
|
|
2018-06-04 22:38:07 +02:00
|
|
|
float yaw = readParam<float>(L, 2) * core::RADTODEG;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
|
|
|
entitysao->setRotation(v3f(0, yaw, 0));
|
2013-02-23 19:06:57 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-01-16 14:08:59 +01:00
|
|
|
// get_yaw(self)
|
|
|
|
int ObjectRef::l_get_yaw(lua_State *L)
|
2013-02-23 19:06:57 +01:00
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
LuaEntitySAO *entitysao = getluaobject(ref);
|
|
|
|
if (entitysao == nullptr)
|
2018-11-28 09:38:50 +01:00
|
|
|
return 0;
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
float yaw = entitysao->getRotation().Y * core::DEGTORAD;
|
|
|
|
|
2013-02-23 19:06:57 +01:00
|
|
|
lua_pushnumber(L, yaw);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-01-16 14:08:59 +01:00
|
|
|
// set_texture_mod(self, mod)
|
|
|
|
int ObjectRef::l_set_texture_mod(lua_State *L)
|
2013-02-23 19:06:57 +01:00
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
LuaEntitySAO *entitysao = getluaobject(ref);
|
|
|
|
if (entitysao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
std::string mod = readParam<std::string>(L, 2);
|
|
|
|
|
|
|
|
entitysao->setTextureMod(mod);
|
2013-02-23 19:06:57 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-01-14 19:32:10 +01:00
|
|
|
// get_texture_mod(self)
|
|
|
|
int ObjectRef::l_get_texture_mod(lua_State *L)
|
|
|
|
{
|
|
|
|
NO_MAP_LOCK_REQUIRED;
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
LuaEntitySAO *entitysao = getluaobject(ref);
|
|
|
|
if (entitysao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
std::string mod = entitysao->getTextureMod();
|
|
|
|
|
2017-01-14 19:32:10 +01:00
|
|
|
lua_pushstring(L, mod.c_str());
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
// set_sprite(self, start_frame, num_frames, framelength, select_x_by_camera)
|
2017-01-16 14:08:59 +01:00
|
|
|
int ObjectRef::l_set_sprite(lua_State *L)
|
2013-02-23 19:06:57 +01:00
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
LuaEntitySAO *entitysao = getluaobject(ref);
|
|
|
|
if (entitysao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
2020-11-04 21:43:18 +01:00
|
|
|
v2s16 start_frame = readParam<v2s16>(L, 2, v2s16(0,0));
|
|
|
|
int num_frames = readParam<int>(L, 3, 1);
|
|
|
|
float framelength = readParam<float>(L, 4, 0.2f);
|
2020-10-22 17:18:01 +02:00
|
|
|
bool select_x_by_camera = readParam<bool>(L, 5, false);
|
|
|
|
|
|
|
|
entitysao->setSprite(start_frame, num_frames, framelength, select_x_by_camera);
|
2013-02-23 19:06:57 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// DEPRECATED
|
|
|
|
// get_entity_name(self)
|
|
|
|
int ObjectRef::l_get_entity_name(lua_State *L)
|
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
LuaEntitySAO *entitysao = getluaobject(ref);
|
2014-04-29 17:47:34 +02:00
|
|
|
log_deprecated(L,"Deprecated call to \"get_entity_name");
|
2020-10-22 17:18:01 +02:00
|
|
|
if (entitysao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
std::string name = entitysao->getName();
|
|
|
|
|
2013-02-23 19:06:57 +01:00
|
|
|
lua_pushstring(L, name.c_str());
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get_luaentity(self)
|
|
|
|
int ObjectRef::l_get_luaentity(lua_State *L)
|
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
LuaEntitySAO *entitysao = getluaobject(ref);
|
|
|
|
if (entitysao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
luaentity_get(L, entitysao->getId());
|
2013-02-23 19:06:57 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Player-only */
|
|
|
|
|
|
|
|
// get_player_name(self)
|
|
|
|
int ObjectRef::l_get_player_name(lua_State *L)
|
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2016-10-08 16:31:22 +02:00
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr) {
|
2013-02-23 19:06:57 +01:00
|
|
|
lua_pushlstring(L, "", 0);
|
|
|
|
return 1;
|
|
|
|
}
|
2020-10-22 17:18:01 +02:00
|
|
|
|
2013-02-23 19:06:57 +01:00
|
|
|
lua_pushstring(L, player->getName());
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get_look_dir(self)
|
|
|
|
int ObjectRef::l_get_look_dir(lua_State *L)
|
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
PlayerSAO* playersao = getplayersao(ref);
|
|
|
|
if (playersao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
float pitch = playersao->getRadLookPitchDep();
|
|
|
|
float yaw = playersao->getRadYawDep();
|
2018-04-02 23:51:08 +02:00
|
|
|
v3f v(std::cos(pitch) * std::cos(yaw), std::sin(pitch), std::cos(pitch) *
|
|
|
|
std::sin(yaw));
|
2020-10-22 17:18:01 +02:00
|
|
|
|
2013-02-23 19:06:57 +01:00
|
|
|
push_v3f(L, v);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2016-06-17 21:57:27 +02:00
|
|
|
// DEPRECATED
|
2013-02-23 19:06:57 +01:00
|
|
|
// get_look_pitch(self)
|
|
|
|
int ObjectRef::l_get_look_pitch(lua_State *L)
|
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2016-06-17 21:57:27 +02:00
|
|
|
|
|
|
|
log_deprecated(L,
|
|
|
|
"Deprecated call to get_look_pitch, use get_look_vertical instead");
|
|
|
|
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
PlayerSAO* playersao = getplayersao(ref);
|
|
|
|
if (playersao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
lua_pushnumber(L, playersao->getRadLookPitchDep());
|
2013-02-23 19:06:57 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2016-06-17 21:57:27 +02:00
|
|
|
// DEPRECATED
|
2013-02-23 19:06:57 +01:00
|
|
|
// get_look_yaw(self)
|
|
|
|
int ObjectRef::l_get_look_yaw(lua_State *L)
|
2016-06-17 21:57:27 +02:00
|
|
|
{
|
|
|
|
NO_MAP_LOCK_REQUIRED;
|
|
|
|
|
|
|
|
log_deprecated(L,
|
|
|
|
"Deprecated call to get_look_yaw, use get_look_horizontal instead");
|
|
|
|
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
PlayerSAO* playersao = getplayersao(ref);
|
|
|
|
if (playersao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
lua_pushnumber(L, playersao->getRadYawDep());
|
2016-06-17 21:57:27 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
// get_look_vertical(self)
|
2016-06-17 21:57:27 +02:00
|
|
|
int ObjectRef::l_get_look_vertical(lua_State *L)
|
|
|
|
{
|
|
|
|
NO_MAP_LOCK_REQUIRED;
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
PlayerSAO* playersao = getplayersao(ref);
|
|
|
|
if (playersao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
lua_pushnumber(L, playersao->getRadLookPitch());
|
2016-06-17 21:57:27 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
// get_look_horizontal(self)
|
2016-06-17 21:57:27 +02:00
|
|
|
int ObjectRef::l_get_look_horizontal(lua_State *L)
|
2013-02-23 19:06:57 +01:00
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
PlayerSAO* playersao = getplayersao(ref);
|
|
|
|
if (playersao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
lua_pushnumber(L, playersao->getRadRotation().Y);
|
2013-02-23 19:06:57 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2016-06-17 21:57:27 +02:00
|
|
|
// set_look_vertical(self, radians)
|
|
|
|
int ObjectRef::l_set_look_vertical(lua_State *L)
|
|
|
|
{
|
|
|
|
NO_MAP_LOCK_REQUIRED;
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
PlayerSAO* playersao = getplayersao(ref);
|
|
|
|
if (playersao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
2018-06-04 22:38:07 +02:00
|
|
|
float pitch = readParam<float>(L, 2) * core::RADTODEG;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
|
|
|
playersao->setLookPitchAndSend(pitch);
|
2016-06-17 21:57:27 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// set_look_horizontal(self, radians)
|
|
|
|
int ObjectRef::l_set_look_horizontal(lua_State *L)
|
|
|
|
{
|
|
|
|
NO_MAP_LOCK_REQUIRED;
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
PlayerSAO* playersao = getplayersao(ref);
|
|
|
|
if (playersao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
2018-06-04 22:38:07 +02:00
|
|
|
float yaw = readParam<float>(L, 2) * core::RADTODEG;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
|
|
|
playersao->setPlayerYawAndSend(yaw);
|
2016-06-17 21:57:27 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// DEPRECATED
|
2013-03-17 12:16:57 +01:00
|
|
|
// set_look_pitch(self, radians)
|
|
|
|
int ObjectRef::l_set_look_pitch(lua_State *L)
|
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2016-06-17 21:57:27 +02:00
|
|
|
|
|
|
|
log_deprecated(L,
|
|
|
|
"Deprecated call to set_look_pitch, use set_look_vertical instead.");
|
|
|
|
|
2013-03-17 12:16:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
PlayerSAO* playersao = getplayersao(ref);
|
|
|
|
if (playersao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
2018-06-04 22:38:07 +02:00
|
|
|
float pitch = readParam<float>(L, 2) * core::RADTODEG;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
|
|
|
playersao->setLookPitchAndSend(pitch);
|
2013-03-17 12:16:57 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2016-06-17 21:57:27 +02:00
|
|
|
// DEPRECATED
|
2013-03-17 12:16:57 +01:00
|
|
|
// set_look_yaw(self, radians)
|
|
|
|
int ObjectRef::l_set_look_yaw(lua_State *L)
|
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2016-06-17 21:57:27 +02:00
|
|
|
|
|
|
|
log_deprecated(L,
|
|
|
|
"Deprecated call to set_look_yaw, use set_look_horizontal instead.");
|
|
|
|
|
2013-03-17 12:16:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
PlayerSAO* playersao = getplayersao(ref);
|
|
|
|
if (playersao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
2018-06-04 22:38:07 +02:00
|
|
|
float yaw = readParam<float>(L, 2) * core::RADTODEG;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
|
|
|
playersao->setPlayerYawAndSend(yaw);
|
2013-03-17 12:16:57 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
// set_fov(self, degrees, is_multiplier, transition_time)
|
2018-07-15 02:26:30 +02:00
|
|
|
int ObjectRef::l_set_fov(lua_State *L)
|
|
|
|
{
|
|
|
|
NO_MAP_LOCK_REQUIRED;
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2018-07-15 02:26:30 +02:00
|
|
|
return 0;
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
float degrees = static_cast<f32>(luaL_checknumber(L, 2));
|
|
|
|
bool is_multiplier = readParam<bool>(L, 3, false);
|
|
|
|
float transition_time = lua_isnumber(L, 4) ?
|
|
|
|
static_cast<f32>(luaL_checknumber(L, 4)) : 0.0f;
|
2018-07-15 02:26:30 +02:00
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
player->setFov({degrees, is_multiplier, transition_time});
|
|
|
|
getServer(L)->SendPlayerFov(player->getPeerId());
|
2018-07-15 02:26:30 +02:00
|
|
|
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);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2018-07-15 02:26:30 +02:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
PlayerFovSpec fov_spec = player->getFov();
|
2020-10-22 17:18:01 +02:00
|
|
|
|
2018-07-15 02:26:30 +02:00
|
|
|
lua_pushnumber(L, fov_spec.fov);
|
|
|
|
lua_pushboolean(L, fov_spec.is_multiplier);
|
2020-05-02 12:52:11 +02:00
|
|
|
lua_pushnumber(L, fov_spec.transition_time);
|
|
|
|
return 3;
|
2018-07-15 02:26:30 +02:00
|
|
|
}
|
|
|
|
|
2013-07-19 19:50:33 +02:00
|
|
|
// set_breath(self, breath)
|
|
|
|
int ObjectRef::l_set_breath(lua_State *L)
|
|
|
|
{
|
|
|
|
NO_MAP_LOCK_REQUIRED;
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
PlayerSAO* playersao = getplayersao(ref);
|
|
|
|
if (playersao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
2013-07-19 19:50:33 +02:00
|
|
|
u16 breath = luaL_checknumber(L, 2);
|
2015-03-03 16:23:47 +01:00
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
playersao->setBreath(breath);
|
2013-07-19 19:50:33 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get_breath(self)
|
|
|
|
int ObjectRef::l_get_breath(lua_State *L)
|
|
|
|
{
|
|
|
|
NO_MAP_LOCK_REQUIRED;
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
PlayerSAO* playersao = getplayersao(ref);
|
|
|
|
if (playersao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
u16 breath = playersao->getBreath();
|
|
|
|
|
|
|
|
lua_pushinteger(L, breath);
|
2013-07-19 19:50:33 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-01-27 08:59:30 +01:00
|
|
|
// set_attribute(self, attribute, value)
|
|
|
|
int ObjectRef::l_set_attribute(lua_State *L)
|
|
|
|
{
|
2019-04-07 12:00:57 +02:00
|
|
|
log_deprecated(L,
|
|
|
|
"Deprecated call to set_attribute, use MetaDataRef methods instead.");
|
|
|
|
|
2017-01-27 08:59:30 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
PlayerSAO* playersao = getplayersao(ref);
|
|
|
|
if (playersao == nullptr)
|
2017-01-27 08:59:30 +01:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
std::string attr = luaL_checkstring(L, 2);
|
2017-05-07 12:13:15 +02:00
|
|
|
if (lua_isnil(L, 3)) {
|
2020-10-22 17:18:01 +02:00
|
|
|
playersao->getMeta().removeString(attr);
|
2017-05-07 12:13:15 +02:00
|
|
|
} else {
|
|
|
|
std::string value = luaL_checkstring(L, 3);
|
2020-10-22 17:18:01 +02:00
|
|
|
playersao->getMeta().setString(attr, value);
|
2017-01-27 08:59:30 +01:00
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get_attribute(self, attribute)
|
|
|
|
int ObjectRef::l_get_attribute(lua_State *L)
|
|
|
|
{
|
2019-04-07 12:00:57 +02:00
|
|
|
log_deprecated(L,
|
|
|
|
"Deprecated call to get_attribute, use MetaDataRef methods instead.");
|
|
|
|
|
2017-01-27 08:59:30 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
PlayerSAO* playersao = getplayersao(ref);
|
|
|
|
if (playersao == nullptr)
|
2017-01-27 08:59:30 +01:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
std::string attr = luaL_checkstring(L, 2);
|
|
|
|
|
2017-08-19 22:23:47 +02:00
|
|
|
std::string value;
|
2020-10-22 17:18:01 +02:00
|
|
|
if (playersao->getMeta().getStringToRef(attr, value)) {
|
2017-01-27 08:59:30 +01:00
|
|
|
lua_pushstring(L, value.c_str());
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-04-06 10:52:29 +02:00
|
|
|
// get_meta(self, attribute)
|
|
|
|
int ObjectRef::l_get_meta(lua_State *L)
|
|
|
|
{
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-10-22 17:18:01 +02:00
|
|
|
PlayerSAO *playersao = getplayersao(ref);
|
|
|
|
if (playersao == nullptr)
|
2018-04-06 10:52:29 +02:00
|
|
|
return 0;
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
PlayerMetaRef::create(L, &playersao->getMeta());
|
2018-04-06 10:52:29 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-02-23 19:06:57 +01:00
|
|
|
// set_inventory_formspec(self, formspec)
|
|
|
|
int ObjectRef::l_set_inventory_formspec(lua_State *L)
|
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2016-10-08 16:31:22 +02:00
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
2013-02-23 19:06:57 +01:00
|
|
|
std::string formspec = luaL_checkstring(L, 2);
|
|
|
|
|
|
|
|
player->inventory_formspec = formspec;
|
2013-08-11 04:09:45 +02:00
|
|
|
getServer(L)->reportInventoryFormspecModified(player->getName());
|
2013-02-23 19:06:57 +01:00
|
|
|
lua_pushboolean(L, true);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get_inventory_formspec(self) -> formspec
|
|
|
|
int ObjectRef::l_get_inventory_formspec(lua_State *L)
|
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2016-10-08 16:31:22 +02:00
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
|
|
|
return 0;
|
2013-02-23 19:06:57 +01:00
|
|
|
|
|
|
|
std::string formspec = player->inventory_formspec;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
2013-02-23 19:06:57 +01:00
|
|
|
lua_pushlstring(L, formspec.c_str(), formspec.size());
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2018-03-28 17:04:41 +02:00
|
|
|
// 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);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2018-03-28 17:04:41 +02:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
std::string formspec = luaL_checkstring(L, 2);
|
|
|
|
|
|
|
|
player->formspec_prepend = formspec;
|
|
|
|
getServer(L)->reportFormspecPrependModified(player->getName());
|
|
|
|
lua_pushboolean(L, true);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
// get_formspec_prepend(self)
|
2018-03-28 17:04:41 +02:00
|
|
|
int ObjectRef::l_get_formspec_prepend(lua_State *L)
|
|
|
|
{
|
|
|
|
NO_MAP_LOCK_REQUIRED;
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2018-03-28 17:04:41 +02:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
std::string formspec = player->formspec_prepend;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
2018-03-28 17:04:41 +02:00
|
|
|
lua_pushlstring(L, formspec.c_str(), formspec.size());
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-02-23 19:06:57 +01:00
|
|
|
// get_player_control(self)
|
|
|
|
int ObjectRef::l_get_player_control(lua_State *L)
|
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2016-10-08 16:31:22 +02:00
|
|
|
RemotePlayer *player = getplayer(ref);
|
2016-10-08 10:38:04 +02:00
|
|
|
|
2013-02-23 19:06:57 +01:00
|
|
|
lua_newtable(L);
|
2022-01-27 22:22:58 +01:00
|
|
|
if (player == nullptr)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
const PlayerControl &control = player->getPlayerControl();
|
2022-01-09 18:46:36 +01:00
|
|
|
lua_pushboolean(L, control.direction_keys & (1 << 0));
|
2013-02-23 19:06:57 +01:00
|
|
|
lua_setfield(L, -2, "up");
|
2022-01-09 18:46:36 +01:00
|
|
|
lua_pushboolean(L, control.direction_keys & (1 << 1));
|
2013-02-23 19:06:57 +01:00
|
|
|
lua_setfield(L, -2, "down");
|
2022-01-09 18:46:36 +01:00
|
|
|
lua_pushboolean(L, control.direction_keys & (1 << 2));
|
2013-02-23 19:06:57 +01:00
|
|
|
lua_setfield(L, -2, "left");
|
2022-01-09 18:46:36 +01:00
|
|
|
lua_pushboolean(L, control.direction_keys & (1 << 3));
|
2013-02-23 19:06:57 +01:00
|
|
|
lua_setfield(L, -2, "right");
|
|
|
|
lua_pushboolean(L, control.jump);
|
|
|
|
lua_setfield(L, -2, "jump");
|
|
|
|
lua_pushboolean(L, control.aux1);
|
|
|
|
lua_setfield(L, -2, "aux1");
|
|
|
|
lua_pushboolean(L, control.sneak);
|
|
|
|
lua_setfield(L, -2, "sneak");
|
2020-06-05 15:06:35 +02:00
|
|
|
lua_pushboolean(L, control.dig);
|
|
|
|
lua_setfield(L, -2, "dig");
|
|
|
|
lua_pushboolean(L, control.place);
|
|
|
|
lua_setfield(L, -2, "place");
|
|
|
|
// Legacy fields to ensure mod compatibility
|
|
|
|
lua_pushboolean(L, control.dig);
|
2013-02-23 19:06:57 +01:00
|
|
|
lua_setfield(L, -2, "LMB");
|
2020-06-05 15:06:35 +02:00
|
|
|
lua_pushboolean(L, control.place);
|
2013-02-23 19:06:57 +01:00
|
|
|
lua_setfield(L, -2, "RMB");
|
2020-06-13 22:46:20 +02:00
|
|
|
lua_pushboolean(L, control.zoom);
|
|
|
|
lua_setfield(L, -2, "zoom");
|
2013-02-23 19:06:57 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get_player_control_bits(self)
|
|
|
|
int ObjectRef::l_get_player_control_bits(lua_State *L)
|
|
|
|
{
|
2013-05-25 00:51:02 +02:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2016-10-08 16:31:22 +02:00
|
|
|
RemotePlayer *player = getplayer(ref);
|
2022-01-27 22:22:58 +01:00
|
|
|
if (player == nullptr) {
|
|
|
|
lua_pushinteger(L, 0);
|
|
|
|
return 1;
|
|
|
|
}
|
2022-01-09 18:46:36 +01:00
|
|
|
|
|
|
|
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)
|
|
|
|
;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
2022-01-09 18:46:36 +01:00
|
|
|
lua_pushinteger(L, keypress_bits);
|
2013-02-23 19:06:57 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
// set_physics_override(self, override_table)
|
|
|
|
int ObjectRef::l_set_physics_override(lua_State *L)
|
|
|
|
{
|
|
|
|
NO_MAP_LOCK_REQUIRED;
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-12-23 17:39:29 +01:00
|
|
|
PlayerSAO *playersao = getplayersao(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (playersao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
2020-11-10 21:02:53 +01:00
|
|
|
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);
|
|
|
|
if (modified)
|
|
|
|
playersao->m_physics_override_sent = false;
|
|
|
|
} else {
|
|
|
|
// old, non-table format
|
|
|
|
// TODO: Remove this code after version 5.4.0
|
|
|
|
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);
|
|
|
|
playersao->m_physics_override_sent = false;
|
|
|
|
}
|
|
|
|
if (!lua_isnil(L, 3)) {
|
|
|
|
playersao->m_physics_override_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);
|
|
|
|
playersao->m_physics_override_sent = false;
|
|
|
|
}
|
|
|
|
}
|
2020-10-22 17:18:01 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get_physics_override(self)
|
|
|
|
int ObjectRef::l_get_physics_override(lua_State *L)
|
|
|
|
{
|
|
|
|
NO_MAP_LOCK_REQUIRED;
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2020-12-23 17:39:29 +01:00
|
|
|
PlayerSAO *playersao = getplayersao(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (playersao == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
lua_newtable(L);
|
|
|
|
lua_pushnumber(L, playersao->m_physics_override_speed);
|
|
|
|
lua_setfield(L, -2, "speed");
|
|
|
|
lua_pushnumber(L, playersao->m_physics_override_jump);
|
|
|
|
lua_setfield(L, -2, "jump");
|
|
|
|
lua_pushnumber(L, playersao->m_physics_override_gravity);
|
|
|
|
lua_setfield(L, -2, "gravity");
|
|
|
|
lua_pushboolean(L, playersao->m_physics_override_sneak);
|
|
|
|
lua_setfield(L, -2, "sneak");
|
|
|
|
lua_pushboolean(L, playersao->m_physics_override_sneak_glitch);
|
|
|
|
lua_setfield(L, -2, "sneak_glitch");
|
|
|
|
lua_pushboolean(L, playersao->m_physics_override_new_move);
|
|
|
|
lua_setfield(L, -2, "new_move");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// hud_add(self, hud)
|
2013-04-11 20:23:38 +02:00
|
|
|
int ObjectRef::l_hud_add(lua_State *L)
|
|
|
|
{
|
2015-10-25 05:45:18 +01:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-04-11 20:23:38 +02:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2016-10-08 12:21:41 +02:00
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2013-04-14 00:20:22 +02:00
|
|
|
return 0;
|
2013-04-11 20:23:38 +02:00
|
|
|
|
2013-04-14 00:20:22 +02:00
|
|
|
HudElement *elem = new HudElement;
|
2018-01-20 14:09:58 +01:00
|
|
|
read_hud_element(L, elem);
|
2014-04-28 23:41:27 +02:00
|
|
|
|
2013-08-11 04:09:45 +02:00
|
|
|
u32 id = getServer(L)->hudAdd(player, elem);
|
2015-10-04 08:50:04 +02:00
|
|
|
if (id == U32_MAX) {
|
2013-04-14 00:20:22 +02:00
|
|
|
delete elem;
|
|
|
|
return 0;
|
|
|
|
}
|
2013-04-11 20:23:38 +02:00
|
|
|
|
|
|
|
lua_pushnumber(L, id);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-04-14 00:20:22 +02:00
|
|
|
// hud_remove(self, id)
|
|
|
|
int ObjectRef::l_hud_remove(lua_State *L)
|
2013-04-11 20:23:38 +02:00
|
|
|
{
|
2015-10-25 05:45:18 +01:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-04-11 20:23:38 +02:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2016-10-08 12:21:41 +02:00
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2013-04-14 00:20:22 +02:00
|
|
|
return 0;
|
2013-04-11 20:23:38 +02:00
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
u32 id = luaL_checkint(L, 2);
|
2013-05-25 00:51:02 +02:00
|
|
|
|
2013-08-11 04:09:45 +02:00
|
|
|
if (!getServer(L)->hudRemove(player, id))
|
2013-04-14 00:20:22 +02:00
|
|
|
return 0;
|
|
|
|
|
2013-04-11 20:23:38 +02:00
|
|
|
lua_pushboolean(L, true);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// hud_change(self, id, stat, data)
|
|
|
|
int ObjectRef::l_hud_change(lua_State *L)
|
|
|
|
{
|
2015-10-25 05:45:18 +01:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-04-11 20:23:38 +02:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2016-10-08 12:21:41 +02:00
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2013-04-14 00:20:22 +02:00
|
|
|
return 0;
|
2013-04-11 20:23:38 +02:00
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
u32 id = luaL_checkint(L, 2);
|
2014-05-25 14:34:32 +02:00
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
HudElement *elem = player->getHud(id);
|
|
|
|
if (elem == nullptr)
|
2013-04-14 00:20:22 +02:00
|
|
|
return 0;
|
2013-05-25 00:51:02 +02:00
|
|
|
|
2021-08-21 20:04:04 +02:00
|
|
|
HudElementStat stat;
|
2020-10-22 17:18:01 +02:00
|
|
|
void *value = nullptr;
|
2021-08-21 20:04:04 +02:00
|
|
|
bool ok = read_hud_change(L, stat, elem, &value);
|
2013-04-21 18:55:46 +02:00
|
|
|
|
2021-08-21 20:04:04 +02:00
|
|
|
if (ok)
|
|
|
|
getServer(L)->hudChange(player, id, stat, value);
|
2013-04-11 20:23:38 +02:00
|
|
|
|
2021-08-21 20:04:04 +02:00
|
|
|
lua_pushboolean(L, ok);
|
2013-04-11 20:23:38 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// hud_get(self, id)
|
|
|
|
int ObjectRef::l_hud_get(lua_State *L)
|
|
|
|
{
|
2015-10-25 05:45:18 +01:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-04-11 20:23:38 +02:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2016-10-08 16:31:22 +02:00
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2013-04-14 00:20:22 +02:00
|
|
|
return 0;
|
2013-04-11 20:23:38 +02:00
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
u32 id = luaL_checkint(L, 2);
|
2013-05-25 00:51:02 +02:00
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
HudElement *elem = player->getHud(id);
|
|
|
|
if (elem == nullptr)
|
2013-04-14 00:20:22 +02:00
|
|
|
return 0;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
|
|
|
push_hud_element(L, elem);
|
2013-04-11 20:23:38 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-04-26 01:27:22 +02:00
|
|
|
// hud_set_flags(self, flags)
|
|
|
|
int ObjectRef::l_hud_set_flags(lua_State *L)
|
2013-04-24 12:52:46 +02:00
|
|
|
{
|
2015-10-25 05:45:18 +01:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-04-24 12:52:46 +02:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2016-10-08 10:38:04 +02:00
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2013-04-24 12:52:46 +02:00
|
|
|
return 0;
|
|
|
|
|
2013-04-26 01:27:22 +02:00
|
|
|
u32 flags = 0;
|
|
|
|
u32 mask = 0;
|
|
|
|
bool flag;
|
2015-01-07 20:08:51 +01:00
|
|
|
|
2013-04-26 01:27:22 +02:00
|
|
|
const EnumString *esp = es_HudBuiltinElement;
|
|
|
|
for (int i = 0; esp[i].str; i++) {
|
|
|
|
if (getboolfield(L, 2, esp[i].str, flag)) {
|
|
|
|
flags |= esp[i].num * flag;
|
|
|
|
mask |= esp[i].num;
|
|
|
|
}
|
|
|
|
}
|
2013-08-11 04:09:45 +02:00
|
|
|
if (!getServer(L)->hudSetFlags(player, flags, mask))
|
2013-04-24 12:52:46 +02:00
|
|
|
return 0;
|
|
|
|
|
2013-04-26 01:27:22 +02:00
|
|
|
lua_pushboolean(L, true);
|
2013-04-24 12:52:46 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
// hud_get_flags(self)
|
2014-04-28 23:41:27 +02:00
|
|
|
int ObjectRef::l_hud_get_flags(lua_State *L)
|
|
|
|
{
|
2015-10-25 05:45:18 +01:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2014-04-28 23:41:27 +02:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2016-10-08 16:31:22 +02:00
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2014-04-28 23:41:27 +02:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
lua_newtable(L);
|
2022-03-05 22:16:17 +01:00
|
|
|
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);
|
|
|
|
}
|
2014-04-28 23:41:27 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-05-04 02:08:52 +02:00
|
|
|
// hud_set_hotbar_itemcount(self, hotbar_itemcount)
|
|
|
|
int ObjectRef::l_hud_set_hotbar_itemcount(lua_State *L)
|
|
|
|
{
|
2015-10-25 05:45:18 +01:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-05-04 02:08:52 +02:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2016-10-08 10:38:04 +02:00
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2013-05-04 02:08:52 +02:00
|
|
|
return 0;
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
s32 hotbar_itemcount = luaL_checkint(L, 2);
|
2013-05-04 02:08:52 +02:00
|
|
|
|
2013-08-11 04:09:45 +02:00
|
|
|
if (!getServer(L)->hudSetHotbarItemcount(player, hotbar_itemcount))
|
2013-05-04 02:08:52 +02:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
lua_pushboolean(L, true);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-05-26 14:10:08 +02:00
|
|
|
// hud_get_hotbar_itemcount(self)
|
|
|
|
int ObjectRef::l_hud_get_hotbar_itemcount(lua_State *L)
|
|
|
|
{
|
2015-10-25 05:45:18 +01:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2015-05-26 14:10:08 +02:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2016-10-08 10:38:04 +02:00
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2015-05-26 14:10:08 +02:00
|
|
|
return 0;
|
|
|
|
|
2018-03-08 22:03:45 +01:00
|
|
|
lua_pushnumber(L, player->getHotbarItemcount());
|
2015-05-26 14:10:08 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-09-03 19:51:40 +02:00
|
|
|
// hud_set_hotbar_image(self, name)
|
|
|
|
int ObjectRef::l_hud_set_hotbar_image(lua_State *L)
|
|
|
|
{
|
2015-10-25 05:45:18 +01:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-09-03 19:51:40 +02:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2016-10-08 12:21:41 +02:00
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2013-09-03 19:51:40 +02:00
|
|
|
return 0;
|
|
|
|
|
2018-06-30 17:11:38 +02:00
|
|
|
std::string name = readParam<std::string>(L, 2);
|
2013-09-03 19:51:40 +02:00
|
|
|
|
|
|
|
getServer(L)->hudSetHotbarImage(player, name);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-05-26 14:10:08 +02:00
|
|
|
// hud_get_hotbar_image(self)
|
|
|
|
int ObjectRef::l_hud_get_hotbar_image(lua_State *L)
|
|
|
|
{
|
2015-10-25 05:45:18 +01:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2015-05-26 14:10:08 +02:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2016-10-08 12:21:41 +02:00
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2015-05-26 14:10:08 +02:00
|
|
|
return 0;
|
|
|
|
|
2018-03-08 22:05:47 +01:00
|
|
|
const std::string &name = player->getHotbarImage();
|
2020-10-22 17:18:01 +02:00
|
|
|
|
2015-05-26 14:10:08 +02:00
|
|
|
lua_pushlstring(L, name.c_str(), name.size());
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-09-03 19:51:40 +02:00
|
|
|
// hud_set_hotbar_selected_image(self, name)
|
|
|
|
int ObjectRef::l_hud_set_hotbar_selected_image(lua_State *L)
|
|
|
|
{
|
2015-10-25 05:45:18 +01:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-09-03 19:51:40 +02:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2016-10-08 12:21:41 +02:00
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2013-09-03 19:51:40 +02:00
|
|
|
return 0;
|
|
|
|
|
2018-06-30 17:11:38 +02:00
|
|
|
std::string name = readParam<std::string>(L, 2);
|
2013-09-03 19:51:40 +02:00
|
|
|
|
|
|
|
getServer(L)->hudSetHotbarSelectedImage(player, name);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-05-26 14:10:08 +02:00
|
|
|
// hud_get_hotbar_selected_image(self)
|
|
|
|
int ObjectRef::l_hud_get_hotbar_selected_image(lua_State *L)
|
|
|
|
{
|
2015-10-25 05:45:18 +01:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2015-05-26 14:10:08 +02:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2016-10-08 12:21:41 +02:00
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2015-05-26 14:10:08 +02:00
|
|
|
return 0;
|
|
|
|
|
2018-03-08 22:06:48 +01:00
|
|
|
const std::string &name = player->getHotbarSelectedImage();
|
2020-10-22 17:18:01 +02:00
|
|
|
|
2015-05-26 14:10:08 +02:00
|
|
|
lua_pushlstring(L, name.c_str(), name.size());
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
// set_sky(self, sky_parameters)
|
2013-05-02 22:52:50 +02:00
|
|
|
int ObjectRef::l_set_sky(lua_State *L)
|
|
|
|
{
|
2015-10-25 05:45:18 +01:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-05-02 22:52:50 +02:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2016-10-08 12:21:41 +02:00
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2013-05-02 22:52:50 +02:00
|
|
|
return 0;
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
SkyboxParams sky_params = player->getSkyParams();
|
2013-05-02 22:52:50 +02:00
|
|
|
|
2022-01-22 12:42:49 +01:00
|
|
|
// 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)) {
|
2019-08-21 22:47:45 +02:00
|
|
|
lua_getfield(L, 2, "base_color");
|
|
|
|
if (!lua_isnil(L, -1))
|
2020-10-22 17:18:01 +02:00
|
|
|
read_color(L, -1, &sky_params.bgcolor);
|
2019-08-21 22:47:45 +02:00
|
|
|
lua_pop(L, 1);
|
2013-05-02 22:52:50 +02:00
|
|
|
|
2019-08-21 22:47:45 +02:00
|
|
|
lua_getfield(L, 2, "type");
|
|
|
|
if (!lua_isnil(L, -1))
|
2020-10-22 17:18:01 +02:00
|
|
|
sky_params.type = luaL_checkstring(L, -1);
|
2019-08-21 22:47:45 +02:00
|
|
|
lua_pop(L, 1);
|
|
|
|
|
|
|
|
lua_getfield(L, 2, "textures");
|
2020-10-22 17:18:01 +02:00
|
|
|
sky_params.textures.clear();
|
|
|
|
if (lua_istable(L, -1) && sky_params.type == "skybox") {
|
2019-08-21 22:47:45 +02:00
|
|
|
lua_pushnil(L);
|
|
|
|
while (lua_next(L, -2) != 0) {
|
|
|
|
// Key is at index -2 and value at index -1
|
2020-10-22 17:18:01 +02:00
|
|
|
sky_params.textures.emplace_back(readParam<std::string>(L, -1));
|
2019-08-21 22:47:45 +02:00
|
|
|
// Removes the value, but keeps the key for iteration
|
|
|
|
lua_pop(L, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
lua_pop(L, 1);
|
|
|
|
|
2022-01-22 12:42:49 +01:00
|
|
|
// Validate that we either have six or zero textures
|
|
|
|
if (sky_params.textures.size() != 6 && !sky_params.textures.empty())
|
2019-08-21 22:47:45 +02:00
|
|
|
throw LuaError("Skybox expects 6 textures!");
|
|
|
|
|
2022-01-22 12:42:49 +01:00
|
|
|
sky_params.clouds = getboolfield_default(L, 2, "clouds", sky_params.clouds);
|
2019-08-21 22:47:45 +02:00
|
|
|
|
|
|
|
lua_getfield(L, 2, "sky_color");
|
|
|
|
if (lua_istable(L, -1)) {
|
|
|
|
lua_getfield(L, -1, "day_sky");
|
2020-10-22 17:18:01 +02:00
|
|
|
read_color(L, -1, &sky_params.sky_color.day_sky);
|
2019-08-21 22:47:45 +02:00
|
|
|
lua_pop(L, 1);
|
|
|
|
|
|
|
|
lua_getfield(L, -1, "day_horizon");
|
2020-10-22 17:18:01 +02:00
|
|
|
read_color(L, -1, &sky_params.sky_color.day_horizon);
|
2019-08-21 22:47:45 +02:00
|
|
|
lua_pop(L, 1);
|
|
|
|
|
|
|
|
lua_getfield(L, -1, "dawn_sky");
|
2020-10-22 17:18:01 +02:00
|
|
|
read_color(L, -1, &sky_params.sky_color.dawn_sky);
|
2019-08-21 22:47:45 +02:00
|
|
|
lua_pop(L, 1);
|
|
|
|
|
|
|
|
lua_getfield(L, -1, "dawn_horizon");
|
2020-10-22 17:18:01 +02:00
|
|
|
read_color(L, -1, &sky_params.sky_color.dawn_horizon);
|
2019-08-21 22:47:45 +02:00
|
|
|
lua_pop(L, 1);
|
|
|
|
|
|
|
|
lua_getfield(L, -1, "night_sky");
|
2020-10-22 17:18:01 +02:00
|
|
|
read_color(L, -1, &sky_params.sky_color.night_sky);
|
2019-08-21 22:47:45 +02:00
|
|
|
lua_pop(L, 1);
|
|
|
|
|
|
|
|
lua_getfield(L, -1, "night_horizon");
|
2020-10-22 17:18:01 +02:00
|
|
|
read_color(L, -1, &sky_params.sky_color.night_horizon);
|
2019-08-21 22:47:45 +02:00
|
|
|
lua_pop(L, 1);
|
|
|
|
|
|
|
|
lua_getfield(L, -1, "indoors");
|
2020-10-22 17:18:01 +02:00
|
|
|
read_color(L, -1, &sky_params.sky_color.indoors);
|
2019-08-21 22:47:45 +02:00
|
|
|
lua_pop(L, 1);
|
|
|
|
|
|
|
|
// Prevent flickering clouds at dawn/dusk:
|
2020-10-22 17:18:01 +02:00
|
|
|
sky_params.fog_sun_tint = video::SColor(255, 255, 255, 255);
|
2019-08-21 22:47:45 +02:00
|
|
|
lua_getfield(L, -1, "fog_sun_tint");
|
2020-10-22 17:18:01 +02:00
|
|
|
read_color(L, -1, &sky_params.fog_sun_tint);
|
2019-08-21 22:47:45 +02:00
|
|
|
lua_pop(L, 1);
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
sky_params.fog_moon_tint = video::SColor(255, 255, 255, 255);
|
2019-08-21 22:47:45 +02:00
|
|
|
lua_getfield(L, -1, "fog_moon_tint");
|
2020-10-22 17:18:01 +02:00
|
|
|
read_color(L, -1, &sky_params.fog_moon_tint);
|
2019-08-21 22:47:45 +02:00
|
|
|
lua_pop(L, 1);
|
|
|
|
|
|
|
|
lua_getfield(L, -1, "fog_tint_type");
|
|
|
|
if (!lua_isnil(L, -1))
|
2020-10-22 17:18:01 +02:00
|
|
|
sky_params.fog_tint_type = luaL_checkstring(L, -1);
|
2019-08-21 22:47:45 +02:00
|
|
|
lua_pop(L, 1);
|
|
|
|
|
2022-01-22 12:42:49 +01:00
|
|
|
// pop "sky_color" table
|
2013-05-02 22:52:50 +02:00
|
|
|
lua_pop(L, 1);
|
|
|
|
}
|
2019-08-21 22:47:45 +02:00
|
|
|
} 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
|
2020-10-22 17:18:01 +02:00
|
|
|
sky_params.bgcolor = video::SColor(255, 255, 255, 255);
|
|
|
|
read_color(L, 2, &sky_params.bgcolor);
|
2019-08-21 22:47:45 +02:00
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
sky_params.type = luaL_checkstring(L, 3);
|
2019-08-21 22:47:45 +02:00
|
|
|
|
|
|
|
// Preserve old behaviour of the sun, moon and stars
|
|
|
|
// when using the old set_sky call.
|
2020-10-22 17:18:01 +02:00
|
|
|
if (sky_params.type == "regular") {
|
2019-08-21 22:47:45 +02:00
|
|
|
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;
|
|
|
|
}
|
2013-05-02 22:52:50 +02:00
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
sky_params.textures.clear();
|
2019-08-21 22:47:45 +02:00
|
|
|
if (lua_istable(L, 4)) {
|
|
|
|
lua_pushnil(L);
|
|
|
|
while (lua_next(L, 4) != 0) {
|
2022-01-22 12:42:49 +01:00
|
|
|
// Key at index -2, and value at index -1
|
|
|
|
sky_params.textures.emplace_back(readParam<std::string>(L, -1));
|
2019-08-21 22:47:45 +02:00
|
|
|
// Remove the value, keep the key for the next iteration
|
|
|
|
lua_pop(L, 1);
|
|
|
|
}
|
|
|
|
}
|
2020-10-22 17:18:01 +02:00
|
|
|
if (sky_params.type == "skybox" && sky_params.textures.size() != 6)
|
2019-08-21 22:47:45 +02:00
|
|
|
throw LuaError("Skybox expects 6 textures.");
|
2013-05-02 22:52:50 +02:00
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
sky_params.clouds = true;
|
2019-08-21 22:47:45 +02:00
|
|
|
if (lua_isboolean(L, 5))
|
2020-10-22 17:18:01 +02:00
|
|
|
sky_params.clouds = readParam<bool>(L, 5);
|
2017-04-28 04:06:49 +02:00
|
|
|
|
2019-08-21 22:47:45 +02:00
|
|
|
getServer(L)->setSun(player, sun_params);
|
|
|
|
getServer(L)->setMoon(player, moon_params);
|
|
|
|
getServer(L)->setStars(player, star_params);
|
|
|
|
}
|
2022-01-22 12:42:49 +01:00
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
getServer(L)->setSky(player, sky_params);
|
2013-05-02 22:52:50 +02:00
|
|
|
lua_pushboolean(L, true);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2022-03-05 22:15:41 +01:00
|
|
|
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)
|
2015-05-26 14:10:08 +02:00
|
|
|
int ObjectRef::l_get_sky(lua_State *L)
|
|
|
|
{
|
2015-10-25 05:45:18 +01:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2015-05-26 14:10:08 +02:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2016-10-08 16:31:22 +02:00
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2015-05-26 14:10:08 +02:00
|
|
|
return 0;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
2022-03-05 22:15:41 +01:00
|
|
|
const SkyboxParams &skybox_params = player->getSkyParams();
|
|
|
|
|
|
|
|
// handle the deprecated version
|
|
|
|
if (!readParam<bool>(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;
|
|
|
|
}
|
2015-05-26 14:10:08 +02:00
|
|
|
|
2022-03-05 22:15:41 +01:00
|
|
|
lua_newtable(L);
|
2019-08-21 22:47:45 +02:00
|
|
|
push_ARGB8(L, skybox_params.bgcolor);
|
2022-03-05 22:15:41 +01:00
|
|
|
lua_setfield(L, -2, "base_color");
|
2019-08-21 22:47:45 +02:00
|
|
|
lua_pushlstring(L, skybox_params.type.c_str(), skybox_params.type.size());
|
2022-03-05 22:15:41 +01:00
|
|
|
lua_setfield(L, -2, "type");
|
2015-05-26 14:10:08 +02:00
|
|
|
|
|
|
|
lua_newtable(L);
|
|
|
|
s16 i = 1;
|
2020-10-22 17:18:01 +02:00
|
|
|
for (const std::string &texture : skybox_params.textures) {
|
2019-08-21 22:47:45 +02:00
|
|
|
lua_pushlstring(L, texture.c_str(), texture.size());
|
2019-01-06 10:24:44 +01:00
|
|
|
lua_rawseti(L, -2, i++);
|
2015-05-26 14:10:08 +02:00
|
|
|
}
|
2022-03-05 22:15:41 +01:00
|
|
|
lua_setfield(L, -2, "textures");
|
2019-08-21 22:47:45 +02:00
|
|
|
lua_pushboolean(L, skybox_params.clouds);
|
2022-03-05 22:15:41 +01:00
|
|
|
lua_setfield(L, -2, "clouds");
|
|
|
|
|
|
|
|
push_sky_color(L, skybox_params);
|
|
|
|
lua_setfield(L, -2, "sky_color");
|
|
|
|
return 1;
|
2015-05-26 14:10:08 +02:00
|
|
|
}
|
|
|
|
|
2022-03-05 22:15:41 +01:00
|
|
|
// DEPRECATED
|
2019-08-21 22:47:45 +02:00
|
|
|
// get_sky_color(self)
|
|
|
|
int ObjectRef::l_get_sky_color(lua_State *L)
|
|
|
|
{
|
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2022-03-05 22:15:41 +01:00
|
|
|
|
|
|
|
log_deprecated(L, "Deprecated call to get_sky_color, use get_sky instead");
|
|
|
|
|
2019-08-21 22:47:45 +02:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2019-08-21 22:47:45 +02:00
|
|
|
return 0;
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
const SkyboxParams &skybox_params = player->getSkyParams();
|
2022-03-05 22:15:41 +01:00
|
|
|
push_sky_color(L, skybox_params);
|
2019-08-21 22:47:45 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
// set_sun(self, sun_parameters)
|
2019-08-21 22:47:45 +02:00
|
|
|
int ObjectRef::l_set_sun(lua_State *L)
|
|
|
|
{
|
|
|
|
NO_MAP_LOCK_REQUIRED;
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2019-08-21 22:47:45 +02:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
SunParams sun_params = player->getSunParams();
|
|
|
|
|
2022-01-22 12:42:49 +01:00
|
|
|
// 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);
|
|
|
|
}
|
2019-08-21 22:47:45 +02:00
|
|
|
|
|
|
|
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);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2019-08-21 22:47:45 +02:00
|
|
|
return 0;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
2019-08-21 22:47:45 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
// set_moon(self, moon_parameters)
|
2019-08-21 22:47:45 +02:00
|
|
|
int ObjectRef::l_set_moon(lua_State *L)
|
|
|
|
{
|
|
|
|
NO_MAP_LOCK_REQUIRED;
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2019-08-21 22:47:45 +02:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
MoonParams moon_params = player->getMoonParams();
|
|
|
|
|
2022-01-22 12:42:49 +01:00
|
|
|
// 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);
|
|
|
|
}
|
2019-08-21 22:47:45 +02:00
|
|
|
|
|
|
|
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);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2019-08-21 22:47:45 +02:00
|
|
|
return 0;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
2019-08-21 22:47:45 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
// set_stars(self, star_parameters)
|
2019-08-21 22:47:45 +02:00
|
|
|
int ObjectRef::l_set_stars(lua_State *L)
|
|
|
|
{
|
|
|
|
NO_MAP_LOCK_REQUIRED;
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2019-08-21 22:47:45 +02:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
StarParams star_params = player->getStarParams();
|
|
|
|
|
2022-01-22 12:42:49 +01:00
|
|
|
// 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);
|
2019-08-21 22:47:45 +02:00
|
|
|
|
2022-01-22 12:42:49 +01:00
|
|
|
lua_getfield(L, 2, "star_color");
|
|
|
|
if (!lua_isnil(L, -1))
|
|
|
|
read_color(L, -1, &star_params.starcolor);
|
|
|
|
lua_pop(L, 1);
|
2019-08-21 22:47:45 +02:00
|
|
|
|
2022-01-22 12:42:49 +01:00
|
|
|
star_params.scale = getfloatfield_default(L, 2,
|
|
|
|
"scale", star_params.scale);
|
|
|
|
}
|
2019-08-21 22:47:45 +02:00
|
|
|
|
|
|
|
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);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2019-08-21 22:47:45 +02:00
|
|
|
return 0;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
2019-08-21 22:47:45 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
// set_clouds(self, cloud_parameters)
|
2017-03-17 10:39:47 +01:00
|
|
|
int ObjectRef::l_set_clouds(lua_State *L)
|
|
|
|
{
|
|
|
|
NO_MAP_LOCK_REQUIRED;
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2017-03-17 10:39:47 +01:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
CloudParams cloud_params = player->getCloudParams();
|
|
|
|
|
2022-01-22 12:42:49 +01:00
|
|
|
// 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);
|
2017-03-17 10:39:47 +01:00
|
|
|
|
2022-01-22 12:42:49 +01:00
|
|
|
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);
|
2017-03-17 10:39:47 +01:00
|
|
|
|
2022-01-22 12:42:49 +01:00
|
|
|
cloud_params.height = getfloatfield_default(L, 2, "height", cloud_params.height);
|
|
|
|
cloud_params.thickness = getfloatfield_default(L, 2, "thickness", cloud_params.thickness);
|
2017-03-17 10:39:47 +01:00
|
|
|
|
2022-01-22 12:42:49 +01:00
|
|
|
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);
|
2017-03-17 10:39:47 +01:00
|
|
|
}
|
|
|
|
|
2018-03-08 22:19:25 +01:00
|
|
|
getServer(L)->setClouds(player, cloud_params);
|
2017-03-17 10:39:47 +01:00
|
|
|
lua_pushboolean(L, true);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ObjectRef::l_get_clouds(lua_State *L)
|
|
|
|
{
|
|
|
|
NO_MAP_LOCK_REQUIRED;
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2017-03-17 10:39:47 +01:00
|
|
|
return 0;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
2017-03-17 10:39:47 +01:00
|
|
|
const CloudParams &cloud_params = player->getCloudParams();
|
|
|
|
|
|
|
|
lua_newtable(L);
|
|
|
|
lua_pushnumber(L, cloud_params.density);
|
|
|
|
lua_setfield(L, -2, "density");
|
|
|
|
push_ARGB8(L, cloud_params.color_bright);
|
|
|
|
lua_setfield(L, -2, "color");
|
|
|
|
push_ARGB8(L, cloud_params.color_ambient);
|
|
|
|
lua_setfield(L, -2, "ambient");
|
|
|
|
lua_pushnumber(L, cloud_params.height);
|
|
|
|
lua_setfield(L, -2, "height");
|
|
|
|
lua_pushnumber(L, cloud_params.thickness);
|
|
|
|
lua_setfield(L, -2, "thickness");
|
|
|
|
lua_newtable(L);
|
|
|
|
lua_pushnumber(L, cloud_params.speed.X);
|
|
|
|
lua_setfield(L, -2, "x");
|
|
|
|
lua_pushnumber(L, cloud_params.speed.Y);
|
|
|
|
lua_setfield(L, -2, "y");
|
|
|
|
lua_setfield(L, -2, "speed");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
// override_day_night_ratio(self, ratio)
|
2013-10-18 10:53:19 +02:00
|
|
|
int ObjectRef::l_override_day_night_ratio(lua_State *L)
|
|
|
|
{
|
2015-10-25 05:45:18 +01:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2013-10-18 10:53:19 +02:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2016-10-08 10:38:04 +02:00
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2013-10-18 10:53:19 +02:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
bool do_override = false;
|
|
|
|
float ratio = 0.0f;
|
2020-10-22 17:18:01 +02:00
|
|
|
|
2015-06-25 14:57:10 +02:00
|
|
|
if (!lua_isnil(L, 2)) {
|
2013-10-18 10:53:19 +02:00
|
|
|
do_override = true;
|
2018-06-04 22:38:07 +02:00
|
|
|
ratio = readParam<float>(L, 2);
|
2020-10-22 17:18:01 +02:00
|
|
|
luaL_argcheck(L, ratio >= 0.0f && ratio <= 1.0f, 1,
|
|
|
|
"value must be between 0 and 1");
|
2013-10-18 10:53:19 +02:00
|
|
|
}
|
|
|
|
|
2020-05-07 22:38:41 +02:00
|
|
|
getServer(L)->overrideDayNightRatio(player, do_override, ratio);
|
2013-10-18 10:53:19 +02:00
|
|
|
lua_pushboolean(L, true);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-05-26 14:10:08 +02:00
|
|
|
// get_day_night_ratio(self)
|
|
|
|
int ObjectRef::l_get_day_night_ratio(lua_State *L)
|
|
|
|
{
|
2015-10-25 05:45:18 +01:00
|
|
|
NO_MAP_LOCK_REQUIRED;
|
2015-05-26 14:10:08 +02:00
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
2016-10-08 10:38:04 +02:00
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2015-05-26 14:10:08 +02:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
bool do_override;
|
|
|
|
float ratio;
|
|
|
|
player->getDayNightRatio(&do_override, &ratio);
|
|
|
|
|
|
|
|
if (do_override)
|
|
|
|
lua_pushnumber(L, ratio);
|
|
|
|
else
|
|
|
|
lua_pushnil(L);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
// set_minimap_modes(self, modes, selected_mode)
|
2020-10-04 15:24:29 +02:00
|
|
|
int ObjectRef::l_set_minimap_modes(lua_State *L)
|
|
|
|
{
|
|
|
|
NO_MAP_LOCK_REQUIRED;
|
|
|
|
ObjectRef *ref = checkobject(L, 1);
|
|
|
|
RemotePlayer *player = getplayer(ref);
|
2020-10-22 17:18:01 +02:00
|
|
|
if (player == nullptr)
|
2020-10-04 15:24:29 +02:00
|
|
|
return 0;
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
luaL_checktype(L, 2, LUA_TTABLE);
|
2020-10-04 15:24:29 +02:00
|
|
|
std::vector<MinimapMode> modes;
|
2021-01-21 18:37:38 +01:00
|
|
|
s16 selected_mode = readParam<s16>(L, 3);
|
2020-10-04 15:24:29 +02:00
|
|
|
|
|
|
|
lua_pushnil(L);
|
|
|
|
while (lua_next(L, 2) != 0) {
|
|
|
|
/* key is at index -2, value is at index -1 */
|
|
|
|
if (lua_istable(L, -1)) {
|
|
|
|
bool ok = true;
|
|
|
|
MinimapMode mode;
|
|
|
|
std::string type = getstringfield_default(L, -1, "type", "");
|
|
|
|
if (type == "off")
|
|
|
|
mode.type = MINIMAP_TYPE_OFF;
|
|
|
|
else if (type == "surface")
|
|
|
|
mode.type = MINIMAP_TYPE_SURFACE;
|
|
|
|
else if (type == "radar")
|
|
|
|
mode.type = MINIMAP_TYPE_RADAR;
|
|
|
|
else if (type == "texture") {
|
|
|
|
mode.type = MINIMAP_TYPE_TEXTURE;
|
|
|
|
mode.texture = getstringfield_default(L, -1, "texture", "");
|
|
|
|
mode.scale = getintfield_default(L, -1, "scale", 1);
|
|
|
|
} else {
|
|
|
|
warningstream << "Minimap mode of unknown type \"" << type.c_str()
|
|
|
|
<< "\" ignored.\n" << std::endl;
|
|
|
|
ok = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ok) {
|
|
|
|
mode.label = getstringfield_default(L, -1, "label", "");
|
|
|
|
// Size is limited to 512. Performance gets poor if size too large, and
|
|
|
|
// segfaults have been experienced.
|
|
|
|
mode.size = rangelim(getintfield_default(L, -1, "size", 0), 1, 512);
|
|
|
|
modes.push_back(mode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* removes 'value'; keeps 'key' for next iteration */
|
|
|
|
lua_pop(L, 1);
|
|
|
|
}
|
|
|
|
lua_pop(L, 1); // Remove key
|
|
|
|
|
2020-10-22 17:18:01 +02:00
|
|
|
getServer(L)->SendMinimapModes(player->getPeerId(), modes, selected_mode);
|
2020-10-04 15:24:29 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-03-26 16:58:26 +01:00
|
|
|
// 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)) {
|
|
|
|
lighting.shadow_intensity = getfloatfield_default(L, -1, "intensity", lighting.shadow_intensity);
|
|
|
|
}
|
|
|
|
lua_pop(L, -1);
|
|
|
|
|
|
|
|
getServer(L)->setLighting(player, lighting);
|
|
|
|
lua_pushboolean(L, true);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-02-23 19:06:57 +01:00
|
|
|
ObjectRef::ObjectRef(ServerActiveObject *object):
|
|
|
|
m_object(object)
|
2020-10-22 17:18:01 +02:00
|
|
|
{}
|
2013-02-23 19:06:57 +01:00
|
|
|
|
|
|
|
// Creates an ObjectRef and leaves it on top of stack
|
|
|
|
// Not callable from Lua; all references are created on the C side.
|
|
|
|
void ObjectRef::create(lua_State *L, ServerActiveObject *object)
|
|
|
|
{
|
2020-10-22 17:18:01 +02:00
|
|
|
ObjectRef *obj = new ObjectRef(object);
|
|
|
|
*(void **)(lua_newuserdata(L, sizeof(void *))) = obj;
|
2013-02-23 19:06:57 +01:00
|
|
|
luaL_getmetatable(L, className);
|
|
|
|
lua_setmetatable(L, -2);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjectRef::set_null(lua_State *L)
|
|
|
|
{
|
2020-10-22 17:18:01 +02:00
|
|
|
ObjectRef *obj = checkobject(L, -1);
|
|
|
|
obj->m_object = nullptr;
|
2013-02-23 19:06:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
|
2021-05-25 20:20:16 +02:00
|
|
|
luaL_register(L, nullptr, methods); // fill methodtable
|
2013-02-23 19:06:57 +01:00
|
|
|
lua_pop(L, 1); // drop methodtable
|
|
|
|
}
|
|
|
|
|
|
|
|
const char ObjectRef::className[] = "ObjectRef";
|
2018-07-01 12:31:49 +02:00
|
|
|
luaL_Reg ObjectRef::methods[] = {
|
2013-02-23 19:06:57 +01:00
|
|
|
// ServerActiveObject
|
|
|
|
luamethod(ObjectRef, remove),
|
2017-01-16 14:08:59 +01:00
|
|
|
luamethod_aliased(ObjectRef, get_pos, getpos),
|
|
|
|
luamethod_aliased(ObjectRef, set_pos, setpos),
|
|
|
|
luamethod_aliased(ObjectRef, move_to, moveto),
|
2013-02-23 19:06:57 +01:00
|
|
|
luamethod(ObjectRef, punch),
|
|
|
|
luamethod(ObjectRef, right_click),
|
|
|
|
luamethod(ObjectRef, set_hp),
|
|
|
|
luamethod(ObjectRef, get_hp),
|
|
|
|
luamethod(ObjectRef, get_inventory),
|
|
|
|
luamethod(ObjectRef, get_wield_list),
|
|
|
|
luamethod(ObjectRef, get_wield_index),
|
|
|
|
luamethod(ObjectRef, get_wielded_item),
|
|
|
|
luamethod(ObjectRef, set_wielded_item),
|
|
|
|
luamethod(ObjectRef, set_armor_groups),
|
2015-05-26 14:10:08 +02:00
|
|
|
luamethod(ObjectRef, get_armor_groups),
|
2013-02-23 19:06:57 +01:00
|
|
|
luamethod(ObjectRef, set_animation),
|
2015-05-26 14:10:08 +02:00
|
|
|
luamethod(ObjectRef, get_animation),
|
2017-09-01 11:15:12 +02:00
|
|
|
luamethod(ObjectRef, set_animation_frame_speed),
|
2013-02-23 19:06:57 +01:00
|
|
|
luamethod(ObjectRef, set_bone_position),
|
2015-05-26 14:10:08 +02:00
|
|
|
luamethod(ObjectRef, get_bone_position),
|
2013-02-23 19:06:57 +01:00
|
|
|
luamethod(ObjectRef, set_attach),
|
2015-05-26 14:10:08 +02:00
|
|
|
luamethod(ObjectRef, get_attach),
|
2020-10-13 21:27:52 +02:00
|
|
|
luamethod(ObjectRef, get_children),
|
2013-02-23 19:06:57 +01:00
|
|
|
luamethod(ObjectRef, set_detach),
|
|
|
|
luamethod(ObjectRef, set_properties),
|
2015-05-26 14:10:08 +02:00
|
|
|
luamethod(ObjectRef, get_properties),
|
2015-11-20 23:46:33 +01:00
|
|
|
luamethod(ObjectRef, set_nametag_attributes),
|
|
|
|
luamethod(ObjectRef, get_nametag_attributes),
|
2020-10-04 01:33:45 +02:00
|
|
|
|
2017-01-16 14:08:59 +01:00
|
|
|
luamethod_aliased(ObjectRef, set_velocity, setvelocity),
|
2020-10-31 19:19:23 +01:00
|
|
|
luamethod_aliased(ObjectRef, add_velocity, add_player_velocity),
|
2017-01-16 14:08:59 +01:00
|
|
|
luamethod_aliased(ObjectRef, get_velocity, getvelocity),
|
2020-10-31 19:19:23 +01:00
|
|
|
luamethod_dep(ObjectRef, get_velocity, get_player_velocity),
|
2020-10-04 01:33:45 +02:00
|
|
|
|
|
|
|
// LuaEntitySAO-only
|
2017-01-16 14:08:59 +01:00
|
|
|
luamethod_aliased(ObjectRef, set_acceleration, setacceleration),
|
|
|
|
luamethod_aliased(ObjectRef, get_acceleration, getacceleration),
|
|
|
|
luamethod_aliased(ObjectRef, set_yaw, setyaw),
|
|
|
|
luamethod_aliased(ObjectRef, get_yaw, getyaw),
|
2018-11-28 09:38:50 +01:00
|
|
|
luamethod(ObjectRef, set_rotation),
|
|
|
|
luamethod(ObjectRef, get_rotation),
|
2017-01-17 19:41:52 +01:00
|
|
|
luamethod_aliased(ObjectRef, set_texture_mod, settexturemod),
|
2020-08-27 21:47:38 +02:00
|
|
|
luamethod(ObjectRef, get_texture_mod),
|
2017-01-16 14:08:59 +01:00
|
|
|
luamethod_aliased(ObjectRef, set_sprite, setsprite),
|
2013-02-23 19:06:57 +01:00
|
|
|
luamethod(ObjectRef, get_entity_name),
|
|
|
|
luamethod(ObjectRef, get_luaentity),
|
2020-10-22 17:18:01 +02:00
|
|
|
|
2013-02-23 19:06:57 +01:00
|
|
|
// Player-only
|
|
|
|
luamethod(ObjectRef, is_player),
|
|
|
|
luamethod(ObjectRef, get_player_name),
|
|
|
|
luamethod(ObjectRef, get_look_dir),
|
|
|
|
luamethod(ObjectRef, get_look_pitch),
|
|
|
|
luamethod(ObjectRef, get_look_yaw),
|
2016-06-17 21:57:27 +02:00
|
|
|
luamethod(ObjectRef, get_look_vertical),
|
|
|
|
luamethod(ObjectRef, get_look_horizontal),
|
|
|
|
luamethod(ObjectRef, set_look_horizontal),
|
|
|
|
luamethod(ObjectRef, set_look_vertical),
|
2013-03-17 12:16:57 +01:00
|
|
|
luamethod(ObjectRef, set_look_yaw),
|
|
|
|
luamethod(ObjectRef, set_look_pitch),
|
2018-07-15 02:26:30 +02:00
|
|
|
luamethod(ObjectRef, get_fov),
|
|
|
|
luamethod(ObjectRef, set_fov),
|
2013-07-19 19:50:33 +02:00
|
|
|
luamethod(ObjectRef, get_breath),
|
|
|
|
luamethod(ObjectRef, set_breath),
|
2017-01-27 08:59:30 +01:00
|
|
|
luamethod(ObjectRef, get_attribute),
|
|
|
|
luamethod(ObjectRef, set_attribute),
|
2018-04-06 10:52:29 +02:00
|
|
|
luamethod(ObjectRef, get_meta),
|
2013-02-23 19:06:57 +01:00
|
|
|
luamethod(ObjectRef, set_inventory_formspec),
|
|
|
|
luamethod(ObjectRef, get_inventory_formspec),
|
2018-03-28 17:04:41 +02:00
|
|
|
luamethod(ObjectRef, set_formspec_prepend),
|
|
|
|
luamethod(ObjectRef, get_formspec_prepend),
|
2013-02-23 19:06:57 +01:00
|
|
|
luamethod(ObjectRef, get_player_control),
|
|
|
|
luamethod(ObjectRef, get_player_control_bits),
|
2015-05-26 14:10:08 +02:00
|
|
|
luamethod(ObjectRef, set_physics_override),
|
|
|
|
luamethod(ObjectRef, get_physics_override),
|
2013-04-11 20:23:38 +02:00
|
|
|
luamethod(ObjectRef, hud_add),
|
2013-04-14 00:20:22 +02:00
|
|
|
luamethod(ObjectRef, hud_remove),
|
2013-04-11 20:23:38 +02:00
|
|
|
luamethod(ObjectRef, hud_change),
|
|
|
|
luamethod(ObjectRef, hud_get),
|
2013-04-26 01:27:22 +02:00
|
|
|
luamethod(ObjectRef, hud_set_flags),
|
2014-04-28 23:41:27 +02:00
|
|
|
luamethod(ObjectRef, hud_get_flags),
|
2013-05-04 02:08:52 +02:00
|
|
|
luamethod(ObjectRef, hud_set_hotbar_itemcount),
|
2015-05-26 14:10:08 +02:00
|
|
|
luamethod(ObjectRef, hud_get_hotbar_itemcount),
|
2013-09-03 19:51:40 +02:00
|
|
|
luamethod(ObjectRef, hud_set_hotbar_image),
|
2015-05-26 14:10:08 +02:00
|
|
|
luamethod(ObjectRef, hud_get_hotbar_image),
|
2013-09-03 19:51:40 +02:00
|
|
|
luamethod(ObjectRef, hud_set_hotbar_selected_image),
|
2015-05-26 14:10:08 +02:00
|
|
|
luamethod(ObjectRef, hud_get_hotbar_selected_image),
|
2013-05-02 22:52:50 +02:00
|
|
|
luamethod(ObjectRef, set_sky),
|
2015-05-26 14:10:08 +02:00
|
|
|
luamethod(ObjectRef, get_sky),
|
2019-08-21 22:47:45 +02:00
|
|
|
luamethod(ObjectRef, get_sky_color),
|
|
|
|
luamethod(ObjectRef, set_sun),
|
|
|
|
luamethod(ObjectRef, get_sun),
|
|
|
|
luamethod(ObjectRef, set_moon),
|
|
|
|
luamethod(ObjectRef, get_moon),
|
|
|
|
luamethod(ObjectRef, set_stars),
|
|
|
|
luamethod(ObjectRef, get_stars),
|
2017-03-17 10:39:47 +01:00
|
|
|
luamethod(ObjectRef, set_clouds),
|
|
|
|
luamethod(ObjectRef, get_clouds),
|
2013-10-18 10:53:19 +02:00
|
|
|
luamethod(ObjectRef, override_day_night_ratio),
|
2015-05-26 14:10:08 +02:00
|
|
|
luamethod(ObjectRef, get_day_night_ratio),
|
2014-01-08 13:47:53 +01:00
|
|
|
luamethod(ObjectRef, set_local_animation),
|
2015-05-26 14:10:08 +02:00
|
|
|
luamethod(ObjectRef, get_local_animation),
|
2014-04-11 15:32:46 +02:00
|
|
|
luamethod(ObjectRef, set_eye_offset),
|
2015-05-26 14:10:08 +02:00
|
|
|
luamethod(ObjectRef, get_eye_offset),
|
Force send a mapblock to a player (#8140)
* Force send a mapblock to a player.
Send a single mapblock to a specific remote player.
This is badly needed for mods and games where players are teleported
into terrain which may be not generated, loaded, or modified
significantly since the last player visit.
In all these cases, the player currently ends up in void, air, or
inside blocks which not only looks bad, but has the effect that the
player might end up falling and then the server needs to correct for
the player position again later, which is a hack.
The best solution is to send at least the single mapblock that the
player will be teleported to. I've tested this with ITB which does this
all the time, and I can see it functioning as expected (it even shows
a half loaded entry hallway, as the further blocks aren't loaded yet).
The parameter is a blockpos (table of x, y, z), not a regular pos.
The function may return false if the call failed. This is most likely
due to the target position not being generated or emerged yet, or
another internal failure, such as the player not being initialized.
* Always send mapblock on teleport or respawn.
This avoids the need for mods to send a mapblock on teleport or
respawn, since any call to `player:set_pos()` will pass this code.
2019-04-28 01:42:13 +02:00
|
|
|
luamethod(ObjectRef, send_mapblock),
|
2020-10-04 15:24:29 +02:00
|
|
|
luamethod(ObjectRef, set_minimap_modes),
|
2022-03-26 16:58:26 +01:00
|
|
|
luamethod(ObjectRef, set_lighting),
|
|
|
|
luamethod(ObjectRef, get_lighting),
|
2013-02-23 19:06:57 +01:00
|
|
|
{0,0}
|
|
|
|
};
|