/*
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 "serverobject.h"
#include "content_sao.h"
#include "remoteplayer.h"
#include "server.h"
#include "hud.h"
#include "scripting_server.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) luaL_typerror(L, narg, className);
return *(ObjectRef**)ud; // unbox pointer
}
ServerActiveObject* ObjectRef::getobject(ObjectRef *ref)
{
ServerActiveObject *co = ref->m_object;
return co;
}
LuaEntitySAO* ObjectRef::getluaobject(ObjectRef *ref)
{
ServerActiveObject *obj = getobject(ref);
if (obj == NULL)
return NULL;
if (obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
return NULL;
return (LuaEntitySAO*)obj;
}
PlayerSAO* ObjectRef::getplayersao(ObjectRef *ref)
{
ServerActiveObject *obj = getobject(ref);
if (obj == NULL)
return NULL;
if (obj->getType() != ACTIVEOBJECT_TYPE_PLAYER)
return NULL;
return (PlayerSAO*)obj;
}
RemotePlayer *ObjectRef::getplayer(ObjectRef *ref)
{
PlayerSAO *playersao = getplayersao(ref);
if (playersao == NULL)
return NULL;
return playersao->getPlayer();
}
// Exported functions
// garbage collector
int ObjectRef::gc_object(lua_State *L) {
ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
//infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
delete o;
return 0;
}
// remove(self)
int ObjectRef::l_remove(lua_State *L)
{
GET_ENV_PTR;
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *co = getobject(ref);
if (co == NULL)
return 0;
if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER)
return 0;
co->clearChildAttachments();
co->clearParentAttachment();
verbosestream << "ObjectRef::l_remove(): id=" << co->getId() << std::endl;
co->m_pending_removal = true;
return 0;
}
// get_pos(self)
// returns: {x=num, y=num, z=num}
int ObjectRef::l_get_pos(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *co = getobject(ref);
if (co == NULL) return 0;
v3f pos = co->getBasePosition() / BS;
lua_newtable(L);
lua_pushnumber(L, pos.X);
lua_setfield(L, -2, "x");
lua_pushnumber(L, pos.Y);
lua_setfield(L, -2, "y");
lua_pushnumber(L, pos.Z);
lua_setfield(L, -2, "z");
return 1;
}
// set_pos(self, pos)
int ObjectRef::l_set_pos(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
//LuaEntitySAO *co = getluaobject(ref);
ServerActiveObject *co = getobject(ref);
if (co == NULL) return 0;
// pos
v3f pos = checkFloatPos(L, 2);
// Do it
co->setPos(pos);
return 0;
}
// move_to(self, pos, continuous=false)
int ObjectRef::l_move_to(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
//LuaEntitySAO *co = getluaobject(ref);
ServerActiveObject *co = getobject(ref);
if (co == NULL) return 0;
// pos
v3f pos = checkFloatPos(L, 2);
// continuous
bool continuous = readParam<bool>(L, 3);
// Do it
co->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 *co = getobject(ref);
ServerActiveObject *puncher = getobject(puncher_ref);
if (!co || !puncher)
return 0;
v3f dir;
if (lua_type(L, 5) != LUA_TTABLE)
dir = co->getBasePosition() - puncher->getBasePosition();
else
dir = read_v3f(L, 5);
float time_from_last_punch = 1000000;
if (lua_isnumber(L, 3))
|