diff options
Diffstat (limited to 'src/light.cpp')
0 files changed, 0 insertions, 0 deletions
/*
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.
*/
#include "lua_api/l_object.h"
#include <cmath>
#include "lua_api/l_internal.h"
#include "lua_api/l_inventory.h"
#include "lua_api/l_item.h"
#include "lua_api/l_playermeta.h"
#include "common/c_converter.h"
#include "common/c_content.h"
#include "log.h"
#include "tool.h"
#include "remoteplayer.h"
#include "server.h"
#include "hud.h"
#include "scripting_server.h"
#include "server/luaentity_sao.h"
#include "server/player_sao.h"
#include "server/serverinventorymgr.h"
/*
ObjectRef
*/
ObjectRef* ObjectRef::checkobject(lua_State *L, int narg)
{
luaL_checktype(L, narg, LUA_TUSERDATA);
void *ud = luaL_checkudata(L, narg, className);
if (ud == nullptr)
luaL_typerror(L, narg, className);
return *(ObjectRef**)ud; // unbox pointer
}
ServerActiveObject* ObjectRef::getobject(ObjectRef *ref)
{
ServerActiveObject *sao = ref->m_object;
if (sao && sao->isGone())
return nullptr;
return sao;
}
LuaEntitySAO* ObjectRef::getluaobject(ObjectRef *ref)
{
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr)
return nullptr;
if (sao->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
return nullptr;
return (LuaEntitySAO*)sao;
}
PlayerSAO* ObjectRef::getplayersao(ObjectRef *ref)
{
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr)
return nullptr;
if (sao->getType() != ACTIVEOBJECT_TYPE_PLAYER)
return nullptr;
return (PlayerSAO*)sao;
}
RemotePlayer *ObjectRef::getplayer(ObjectRef *ref)
{
PlayerSAO *playersao = getplayersao(ref);
if (playersao == nullptr)
return nullptr;
return playersao->getPlayer();
}
// Exported functions
// garbage collector
int ObjectRef::gc_object(lua_State *L) {
ObjectRef *obj = *(ObjectRef **)(lua_touserdata(L, 1));
delete obj;
return 0;
}
// remove(self)
int ObjectRef::l_remove(lua_State *L)
{
GET_ENV_PTR;
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr)
return 0;
if (sao->getType() == ACTIVEOBJECT_TYPE_PLAYER)
return 0;
sao->clearChildAttachments();
sao->clearParentAttachment();
verbosestream << "ObjectRef::l_remove(): id=" << sao->getId() << std::endl;
sao->markForRemoval();
return 0;
}
// get_pos(self)
int ObjectRef::l_get_pos(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr)
return 0;
push_v3f(L, sao->getBasePosition() / BS);
return 1;
}
// set_pos(self, pos)
int ObjectRef::l_set_pos(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr)
return 0;
v3f pos = checkFloatPos(L, 2);
sao->setPos(pos);
return 0;
}
// move_to(self, pos, continuous)
int ObjectRef::l_move_to(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr)
return 0;
v3f pos = checkFloatPos(L, 2);
bool continuous = readParam<bool>(L, 3);
sao->moveTo(pos, continuous);
return 0;
}
// punch(self, puncher, time_from_last_punch, tool_capabilities, dir)
int ObjectRef::l_punch(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
ObjectRef *puncher_ref = checkobject(L, 2);
ServerActiveObject *sao = getobject(ref);
ServerActiveObject *puncher = getobject(puncher_ref);
if (sao == nullptr || puncher == nullptr)
return 0;
float time_from_last_punch = readParam<float>(L, 3, 1000000.0f);
ToolCapabilities toolcap = read_tool_capabilities(L, 4);
v3f dir = readParam<v3f>(L, 5, sao->getBasePosition() - puncher->getBasePosition());
dir.normalize();
u16 src_original_hp = sao->getHP();
u16 dst_origin_hp = puncher->getHP();
u16 wear = sao->punch(dir, &toolcap, puncher, time_from_last_punch);
lua_pushnumber(L, wear);
// If the punched is a player, and its HP changed
if (src_original_hp != sao->getHP() &&
sao->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
getServer(L)->SendPlayerHPOrDie((PlayerSAO *)sao,
PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, puncher));
}
// If the puncher is a player, and its HP changed
if (dst_origin_hp != puncher->getHP() &&
puncher->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
getServer(L)->SendPlayerHPOrDie((PlayerSAO *)puncher,
PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, sao));
}
return 1;
}
// right_click(self, clicker)
int ObjectRef::l_right_click(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
ObjectRef *ref2 = checkobject(L, 2);
ServerActiveObject *sao = getobject(ref);
ServerActiveObject *sao2 = getobject(ref2);
if (sao == nullptr || sao2 == nullptr)
return 0;
sao->rightClick(sao2);
return 0;
}
// set_hp(self, hp, reason)
int ObjectRef::l_set_hp(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr)
return 0;
int hp = readParam<float>(L, 2);
PlayerHPChangeReason reason(PlayerHPChangeReason::SET_HP);
reason.from_mod = true;
if (lua_istable(L, 3)) {
lua_pushvalue(L, 3);
lua_getfield(L, -1, "type");
if (lua_isstring(L, -1) &&
!reason.setTypeFromString(readParam<std::string>(L, -1))) {
errorstream << "Bad type given!" << std::endl;
}
lua_pop(L, 1);
reason.lua_reference = luaL_ref(L, LUA_REGISTRYINDEX);
}
sao->setHP(hp, reason);
if (sao->getType() == ACTIVEOBJECT_TYPE_PLAYER)
getServer(L)->SendPlayerHPOrDie((PlayerSAO *)sao, reason);
if (reason.hasLuaReference())
luaL_unref(L, LUA_REGISTRYINDEX, reason.lua_reference);
return 0;
}
// get_hp(self)
int ObjectRef::l_get_hp(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr) {
// Default hp is 1
lua_pushnumber(L, 1);
return 1;
}
int hp = sao->getHP();
lua_pushnumber(L, hp);
return 1;
}
// get_inventory(self)
int ObjectRef::l_get_inventory(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr)
return 0;
InventoryLocation loc = sao->getInventoryLocation();
if (getServerInventoryMgr(L)->getInventory(loc) != nullptr)
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)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr)
return 0;
lua_pushstring(L, sao->getWieldList().c_str());
return 1;
}
// get_wield_index(self)
int ObjectRef::l_get_wield_index(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr)
return 0;
lua_pushinteger(L, sao->getWieldIndex() + 1);
return 1;
}
// get_wielded_item(self)
int ObjectRef::l_get_wielded_item(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr) {
// Empty ItemStack
LuaItemStack::create(L, ItemStack());
return 1;
}
ItemStack selected_item;
sao->getWieldedItem(&selected_item, nullptr);
LuaItemStack::create(L, selected_item);
return 1;
}
// set_wielded_item(self, item)
int ObjectRef::l_set_wielded_item(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr)
return 0;
ItemStack item = read_item(L, 2, getServer(L)->idef());
bool success = sao->setWieldedItem(item);
if (success && sao->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
getServer(L)->SendInventory((PlayerSAO *)sao, true);
}
lua_pushboolean(L, success);
return 1;
}
// set_armor_groups(self, groups)
int ObjectRef::l_set_armor_groups(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr)
return 0;
ItemGroupList groups;
read_groups(L, 2, groups);
sao->setArmorGroups(groups);
return 0;
}
// get_armor_groups(self)
int ObjectRef::l_get_armor_groups(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr)
return 0;
push_groups(L, sao->getArmorGroups());
return 1;
}
// set_animation(self, frame_range, frame_speed, frame_blend, frame_loop)
int ObjectRef::l_set_animation(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr)
return 0;
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);
sao->setAnimation(frame_range, frame_speed, frame_blend, frame_loop);
return 0;
}
// get_animation(self)
int ObjectRef::l_get_animation(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr)
return 0;
v2f frames = v2f(1, 1);
float frame_speed = 15;
float frame_blend = 0;
bool frame_loop = true;
sao->getAnimation(&frames, &frame_speed, &frame_blend, &frame_loop);
push_v2f(L, frames);
lua_pushnumber(L, frame_speed);
lua_pushnumber(L, frame_blend);
lua_pushboolean(L, frame_loop);
return 4;
}
// set_local_animation(self, idle, walk, dig, walk_while_dig, frame_speed)
int ObjectRef::l_set_local_animation(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
if (player == nullptr)
return 0;
v2s32 frames[4];
for (int i=0;i<4;i++) {
if (!lua_isnil(L, 2+1))
frames[i] = read_v2s32(L, 2+i);
}
float frame_speed = readParam<float>(L, 6, 30.0f);
getServer(L)->setLocalPlayerAnimations(player, frames, frame_speed);
lua_pushboolean(L, true);
return 1;
}
// get_local_animation(self)
int ObjectRef::l_get_local_animation(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
if (player == nullptr)
return 0;
v2s32 frames[4];
float frame_speed;
player->getLocalAnimations(frames, &frame_speed);
for (const v2s32 &frame : frames) {
push_v2s32(L, frame);
}
lua_pushnumber(L, frame_speed);
return 5;
}
// set_eye_offset(self, firstperson, thirdperson)
int ObjectRef::l_set_eye_offset(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
if (player == nullptr)
return 0;
v3f offset_first = readParam<v3f>(L, 2, v3f(0, 0, 0));
v3f offset_third = readParam<v3f>(L, 3, v3f(0, 0, 0));
// 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);
/* TODO: if possible: improve the camera collision detection to allow Y <= -1.5) */
offset_third.Y = rangelim(offset_third.Y,-10,15); //1.5*BS
getServer(L)->setPlayerEyeOffset(player, offset_first, offset_third);
lua_pushboolean(L, true);
return 1;
}
// get_eye_offset(self)
int ObjectRef::l_get_eye_offset(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
if (player == nullptr)
return 0;
push_v3f(L, player->eye_offset_first);
push_v3f(L, player->eye_offset_third);
return 2;
}
// send_mapblock(self, pos)
int ObjectRef::l_send_mapblock(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
if (player == nullptr)
return 0;
v3s16 pos = read_v3s16(L, 2);
session_t peer_id = player->getPeerId();
bool r = getServer(L)->SendBlock(peer_id, pos);
lua_pushboolean(L, r);
return 1;
}
// set_animation_frame_speed(self, frame_speed)
int ObjectRef::l_set_animation_frame_speed(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr)
return 0;
if (!lua_isnil(L, 2)) {
float frame_speed = readParam<float>(L, 2);
sao->setAnimationSpeed(frame_speed);
lua_pushboolean(L, true);
} else {
lua_pushboolean(L, false);
}
return 1;
}
// set_bone_position(self, bone, position, rotation)
int ObjectRef::l_set_bone_position(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr)
return 0;
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));
sao->setBonePosition(bone, position, rotation);
return 0;
}
// get_bone_position(self, bone)
int ObjectRef::l_get_bone_position(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr)
return 0;
std::string bone = readParam<std::string>(L, 2, "");
v3f position = v3f(0, 0, 0);
v3f rotation = v3f(0, 0, 0);
sao->getBonePosition(bone, &position, &rotation);
push_v3f(L, position);
push_v3f(L, rotation);
return 2;
}
// set_attach(self, parent, bone, position, rotation, force_visible)
int ObjectRef::l_set_attach(lua_State *L)
{
GET_ENV_PTR;
ObjectRef *ref = checkobject(L, 1);
ObjectRef *parent_ref = checkobject(L, 2);
ServerActiveObject *sao = getobject(ref);
ServerActiveObject *parent = getobject(parent_ref);
if (sao == nullptr || parent == nullptr)
return 0;
if (sao == parent)
throw LuaError("ObjectRef::set_attach: attaching object to itself is not allowed.");
int parent_id;
std::string bone;
v3f position;
v3f rotation;
bool force_visible;
sao->getAttachment(&parent_id, &bone, &position, &rotation, &force_visible);
if (parent_id) {
ServerActiveObject *old_parent = env->getActiveObject(parent_id);
old_parent->removeAttachmentChild(sao->getId());
}
bone = readParam<std::string>(L, 3, "");
position = readParam<v3f>(L, 4, v3f(0, 0, 0));
rotation = readParam<v3f>(L, 5, v3f(0, 0, 0));
force_visible = readParam<bool>(L, 6, false);
sao->setAttachment(parent->getId(), bone, position, rotation, force_visible);
parent->addAttachmentChild(sao->getId());
return 0;
}
// get_attach(self)
int ObjectRef::l_get_attach(lua_State *L)
{
GET_ENV_PTR;
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr)
return 0;
int parent_id;
std::string bone;
v3f position;
v3f rotation;
bool force_visible;
sao->getAttachment(&parent_id, &bone, &position, &rotation, &force_visible);
if (parent_id == 0)
return 0;
ServerActiveObject *parent = env->getActiveObject(parent_id);
getScriptApiBase(L)->objectrefGetOrCreate(L, parent);
lua_pushlstring(L, bone.c_str(), bone.size());
push_v3f(L, position);
push_v3f(L, rotation);
lua_pushboolean(L, force_visible);
return 5;
}
// 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;
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;
}
// set_detach(self)
int ObjectRef::l_set_detach(lua_State *L)
{
GET_ENV_PTR;
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr)
return 0;
sao->clearParentAttachment();
return 0;
}
// set_properties(self, properties)
int ObjectRef::l_set_properties(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr)
return 0;
ObjectProperties *prop = sao->accessObjectProperties();
if (prop == nullptr)
return 0;
read_object_properties(L, 2, sao, prop, getServer(L)->idef());
sao->notifyObjectPropertiesModified();
return 0;
}
// get_properties(self)
int ObjectRef::l_get_properties(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr)
return 0;
ObjectProperties *prop = sao->accessObjectProperties();
if (prop == nullptr)
return 0;
push_object_properties(L, prop);
return 1;
}
// is_player(self)
int ObjectRef::l_is_player(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
lua_pushboolean(L, (player != nullptr));
return 1;
}
// set_nametag_attributes(self, attributes)
int ObjectRef::l_set_nametag_attributes(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr)
return 0;
ObjectProperties *prop = sao->accessObjectProperties();
if (prop == nullptr)
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);
std::string nametag = getstringfield_default(L, 2, "text", "");
prop->nametag = nametag;
sao->notifyObjectPropertiesModified();
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);
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr)
return 0;
ObjectProperties *prop = sao->accessObjectProperties();
if (!prop)
return 0;
video::SColor color = prop->nametag_color;
lua_newtable(L);
push_ARGB8(L, color);
lua_setfield(L, -2, "color");
lua_pushstring(L, prop->nametag.c_str());
lua_setfield(L, -2, "text");
return 1;
}
/* LuaEntitySAO-only */
// set_velocity(self, velocity)
int ObjectRef::l_set_velocity(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
LuaEntitySAO *sao = getluaobject(ref);
if (sao == nullptr)
return 0;
v3f vel = checkFloatPos(L, 2);
sao->setVelocity(vel);
return 0;
}
// add_velocity(self, velocity)
int ObjectRef::l_add_velocity(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr)
return 0;
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);
}
return 0;
}
// get_velocity(self)
int ObjectRef::l_get_velocity(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr)
return 0;
if (sao->getType() == ACTIVEOBJECT_TYPE_LUAENTITY) {
LuaEntitySAO *entitysao = dynamic_cast<LuaEntitySAO*>(sao);
v3f vel = entitysao->getVelocity();
pushFloatPos(L, vel);
return 1;
} else if (sao->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
RemotePlayer *player = dynamic_cast<PlayerSAO*>(sao)->getPlayer();
push_v3f(L, player->getSpeed() / BS);
return 1;
}
lua_pushnil(L);
return 1;
}
// set_acceleration(self, acceleration)
int ObjectRef::l_set_acceleration(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
LuaEntitySAO *entitysao = getluaobject(ref);
if (entitysao == nullptr)
return 0;
v3f acceleration = checkFloatPos(L, 2);
entitysao->setAcceleration(acceleration);
return 0;
}
// get_acceleration(self)
int ObjectRef::l_get_acceleration(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
LuaEntitySAO *entitysao = getluaobject(ref);
if (entitysao == nullptr)
return 0;
v3f acceleration = entitysao->getAcceleration();
pushFloatPos(L, acceleration);
return 1;
}
// set_rotation(self, rotation)
int ObjectRef::l_set_rotation(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
LuaEntitySAO *entitysao = getluaobject(ref);
if (entitysao == nullptr)
return 0;
v3f rotation = check_v3f(L, 2) * core::RADTODEG;
entitysao->setRotation(rotation);
return 0;
}
// get_rotation(self)
int ObjectRef::l_get_rotation(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
LuaEntitySAO *entitysao = getluaobject(ref);
if (entitysao == nullptr)
return 0;
v3f rotation = entitysao->getRotation() * core::DEGTORAD;
lua_newtable(L);
push_v3f(L, rotation);
return 1;
}
// set_yaw(self, yaw)
int ObjectRef::l_set_yaw(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
LuaEntitySAO *entitysao = getluaobject(ref);
if (entitysao == nullptr)
return 0;
float yaw = readParam<float>(L, 2) * core::RADTODEG;
entitysao->setRotation(v3f(0, yaw, 0));
return 0;
}
// get_yaw(self)
int ObjectRef::l_get_yaw(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
LuaEntitySAO *entitysao = getluaobject(ref);
if (entitysao == nullptr)
return 0;
float yaw = entitysao->getRotation().Y * core::DEGTORAD;
lua_pushnumber(L, yaw);
return 1;
}
// set_texture_mod(self, mod)
int ObjectRef::l_set_texture_mod(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
LuaEntitySAO *entitysao = getluaobject(ref);
if (entitysao == nullptr)
return 0;
std::string mod = readParam<std::string>(L, 2);
entitysao->setTextureMod(mod);
return 0;
}
// get_texture_mod(self)
int ObjectRef::l_get_texture_mod(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
LuaEntitySAO *entitysao = getluaobject(ref);
if (entitysao == nullptr)
return 0;
std::string mod = entitysao->getTextureMod();
lua_pushstring(L, mod.c_str());
return 1;
}
// set_sprite(self, start_frame, num_frames, framelength, select_x_by_camera)
int ObjectRef::l_set_sprite(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
LuaEntitySAO *entitysao = getluaobject(ref);
if (entitysao == nullptr)
return 0;
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);
bool select_x_by_camera = readParam<bool>(L, 5, false);
entitysao->setSprite(start_frame, num_frames, framelength, select_x_by_camera);
return 0;
}
// DEPRECATED
// get_entity_name(self)
int ObjectRef::l_get_entity_name(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
LuaEntitySAO *entitysao = getluaobject(ref);
log_deprecated(L,"Deprecated call to \"get_entity_name");
if (entitysao == nullptr)
return 0;
std::string name = entitysao->getName();
lua_pushstring(L, name.c_str());
return 1;
}
// get_luaentity(self)
int ObjectRef::l_get_luaentity(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
LuaEntitySAO *entitysao = getluaobject(ref);
if (entitysao == nullptr)
return 0;
luaentity_get(L, entitysao->getId());
return 1;
}
/* Player-only */
// get_player_name(self)
int ObjectRef::l_get_player_name(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
if (player == nullptr) {
lua_pushlstring(L, "", 0);
return 1;
}
lua_pushstring(L, player->getName());
return 1;
}
// get_look_dir(self)
int ObjectRef::l_get_look_dir(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
PlayerSAO* playersao = getplayersao(ref);
if (playersao == nullptr)
return 0;
float pitch = playersao->getRadLookPitchDep();
float yaw = playersao->getRadYawDep();
v3f v(std::cos(pitch) * std::cos(yaw), std::sin(pitch), std::cos(pitch) *
std::sin(yaw));
push_v3f(L, v);
return 1;
}
// DEPRECATED
// get_look_pitch(self)
int ObjectRef::l_get_look_pitch(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
log_deprecated(L,
"Deprecated call to get_look_pitch, use get_look_vertical instead");
ObjectRef *ref = checkobject(L, 1);
PlayerSAO* playersao = getplayersao(ref);
if (playersao == nullptr)
return 0;
lua_pushnumber(L, playersao->getRadLookPitchDep());
return 1;
}
// DEPRECATED
// get_look_yaw(self)
int ObjectRef::l_get_look_yaw(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
log_deprecated(L,
"Deprecated call to get_look_yaw, use get_look_horizontal instead");
ObjectRef *ref = checkobject(L, 1);
PlayerSAO* playersao = getplayersao(ref);
if (playersao == nullptr)
return 0;
lua_pushnumber(L, playersao->getRadYawDep());
return 1;
}
// get_look_vertical(self)
int ObjectRef::l_get_look_vertical(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
PlayerSAO* playersao = getplayersao(ref);
if (playersao == nullptr)
return 0;
lua_pushnumber(L, playersao->getRadLookPitch());
return 1;
}
// get_look_horizontal(self)
int ObjectRef::l_get_look_horizontal(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
PlayerSAO* playersao = getplayersao(ref);
if (playersao == nullptr)
return 0;
lua_pushnumber(L, playersao->getRadRotation().Y);
return 1;
}
// set_look_vertical(self, radians)
int ObjectRef::l_set_look_vertical(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
PlayerSAO* playersao = getplayersao(ref);
if (playersao == nullptr)
return 0;
float pitch = readParam<float>(L, 2) * core::RADTODEG;
playersao->setLookPitchAndSend(pitch);
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);
PlayerSAO* playersao = getplayersao(ref);
if (playersao == nullptr)
return 0;
float yaw = readParam<float>(L, 2) * core::RADTODEG;
playersao->setPlayerYawAndSend(yaw);
return 1;
}
// DEPRECATED
// set_look_pitch(self, radians)
int ObjectRef::l_set_look_pitch(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
log_deprecated(L,
"Deprecated call to set_look_pitch, use set_look_vertical instead.");
ObjectRef *ref = checkobject(L, 1);
PlayerSAO* playersao = getplayersao(ref);
if (playersao == nullptr)
return 0;
float pitch = readParam<float>(L, 2) * core::RADTODEG;
playersao->setLookPitchAndSend(pitch);
return 1;
}
// DEPRECATED
// set_look_yaw(self, radians)
int ObjectRef::l_set_look_yaw(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
log_deprecated(L,
"Deprecated call to set_look_yaw, use set_look_horizontal instead.");
ObjectRef *ref = checkobject(L, 1);
PlayerSAO* playersao = getplayersao(ref);
if (playersao == nullptr)
return 0;
float yaw = readParam<float>(L, 2) * core::RADTODEG;
playersao->setPlayerYawAndSend(yaw);
return 1;
}
// set_fov(self, degrees, is_multiplier, transition_time)
int ObjectRef::l_set_fov(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
if (player == nullptr)
return 0;
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;
player->setFov({degrees, is_multiplier, transition_time});
getServer(L)->SendPlayerFov(player->getPeerId());
return 0;
}
// get_fov(self)
int ObjectRef::l_get_fov(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
if (player == nullptr)
return 0;
PlayerFovSpec fov_spec = player->getFov();
lua_pushnumber(L, fov_spec.fov);
lua_pushboolean(L, fov_spec.is_multiplier);
lua_pushnumber(L, fov_spec.transition_time);
return 3;
}
// set_breath(self, breath)
int ObjectRef::l_set_breath(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
PlayerSAO* playersao = getplayersao(ref);
if (playersao == nullptr)
return 0;
u16 breath = luaL_checknumber(L, 2);
playersao->setBreath(breath);
return 0;
}
// get_breath(self)
int ObjectRef::l_get_breath(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
PlayerSAO* playersao = getplayersao(ref);
if (playersao == nullptr)
return 0;
u16 breath = playersao->getBreath();
lua_pushinteger(L, breath);
return 1;
}
// set_attribute(self, attribute, value)
int ObjectRef::l_set_attribute(lua_State *L)
{
log_deprecated(L,
"Deprecated call to set_attribute, use MetaDataRef methods instead.");
ObjectRef *ref = checkobject(L, 1);
PlayerSAO* playersao = getplayersao(ref);
if (playersao == nullptr)
return 0;
std::string attr = luaL_checkstring(L, 2);
if (lua_isnil(L, 3)) {
playersao->getMeta().removeString(attr);
} else {
std::string value = luaL_checkstring(L, 3);
playersao->getMeta().setString(attr, value);
}
return 1;
}
// get_attribute(self, attribute)
int ObjectRef::l_get_attribute(lua_State *L)
{
log_deprecated(L,
"Deprecated call to get_attribute, use MetaDataRef methods instead.");
ObjectRef *ref = checkobject(L, 1);
PlayerSAO* playersao = getplayersao(ref);
if (playersao == nullptr)
return 0;
std::string attr = luaL_checkstring(L, 2);
std::string value;
if (playersao->getMeta().getStringToRef(attr, value)) {
lua_pushstring(L, value.c_str());
return 1;
}
return 0;
}
// get_meta(self, attribute)
int ObjectRef::l_get_meta(lua_State *L)
{
ObjectRef *ref = checkobject(L, 1);
PlayerSAO *playersao = getplayersao(ref);
if (playersao == nullptr)
return 0;
PlayerMetaRef::create(L, &playersao->getMeta());
return 1;
}
// set_inventory_formspec(self, formspec)
int ObjectRef::l_set_inventory_formspec(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
if (player == nullptr)
return 0;
std::string formspec = luaL_checkstring(L, 2);
player->inventory_formspec = formspec;
getServer(L)->reportInventoryFormspecModified(player->getName());
lua_pushboolean(L, true);
return 1;
}
// get_inventory_formspec(self) -> formspec
int ObjectRef::l_get_inventory_formspec(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
if (player == nullptr)
return 0;
std::string formspec = player->inventory_formspec;
lua_pushlstring(L, formspec.c_str(), formspec.size());
return 1;
}
// set_formspec_prepend(self, formspec)
int ObjectRef::l_set_formspec_prepend(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
if (player == nullptr)
return 0;
std::string formspec = luaL_checkstring(L, 2);
player->formspec_prepend = formspec;
getServer(L)->reportFormspecPrependModified(player->getName());
lua_pushboolean(L, true);
return 1;
}
// get_formspec_prepend(self)
int ObjectRef::l_get_formspec_prepend(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
if (player == nullptr)
return 0;
std::string formspec = player->formspec_prepend;
lua_pushlstring(L, formspec.c_str(), formspec.size());
return 1;