aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/clientenvironment.cpp11
-rw-r--r--src/client/game.cpp2
-rw-r--r--src/script/common/c_content.cpp63
-rw-r--r--src/script/cpp_api/s_base.cpp16
-rw-r--r--src/script/cpp_api/s_base.h5
-rw-r--r--src/script/cpp_api/s_client.cpp4
-rw-r--r--src/script/lua_api/l_client.cpp2
-rw-r--r--src/script/lua_api/l_clientobject.cpp59
-rw-r--r--src/script/lua_api/l_clientobject.h2
-rw-r--r--src/script/lua_api/l_localplayer.cpp2
-rw-r--r--src/serverenvironment.cpp8
11 files changed, 141 insertions, 33 deletions
diff --git a/src/client/clientenvironment.cpp b/src/client/clientenvironment.cpp
index fd56c8f44..8e0d00bc9 100644
--- a/src/client/clientenvironment.cpp
+++ b/src/client/clientenvironment.cpp
@@ -352,6 +352,7 @@ void ClientEnvironment::addActiveObject(u16 id, u8 type,
{
ClientActiveObject* obj =
ClientActiveObject::create((ActiveObjectType) type, m_client, this);
+
if(obj == NULL)
{
infostream<<"ClientEnvironment::addActiveObject(): "
@@ -362,6 +363,9 @@ void ClientEnvironment::addActiveObject(u16 id, u8 type,
obj->setId(id);
+ if (m_client->modsLoaded())
+ m_client->getScript()->addObjectReference(dynamic_cast<ActiveObject*>(obj));
+
try
{
obj->initialize(init_data);
@@ -394,9 +398,14 @@ void ClientEnvironment::removeActiveObject(u16 id)
{
// Get current attachment childs to detach them visually
std::unordered_set<int> attachment_childs;
- if (auto *obj = getActiveObject(id))
+ auto *obj = getActiveObject(id);
+ if (obj) {
attachment_childs = obj->getAttachmentChildIds();
+ if (m_client->modsLoaded())
+ m_client->getScript()->removeObjectReference(dynamic_cast<ActiveObject*>(obj));
+ }
+
m_ao_manager.removeObject(id);
// Perform a proper detach in Irrlicht
diff --git a/src/client/game.cpp b/src/client/game.cpp
index 104a6e374..e1f2fbe75 100644
--- a/src/client/game.cpp
+++ b/src/client/game.cpp
@@ -734,7 +734,7 @@ bool Game::connectToServer(const GameStartData &start_data,
} else {
wait_time += dtime;
// Only time out if we aren't waiting for the server we started
- if (!start_data.isSinglePlayer() && wait_time > 10) {
+ if (!start_data.local_server && !start_data.isSinglePlayer() && wait_time > 10) {
*error_message = "Connection timed out.";
errorstream << *error_message << std::endl;
break;
diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp
index 8543b70ce..e56d07cc6 100644
--- a/src/script/common/c_content.cpp
+++ b/src/script/common/c_content.cpp
@@ -516,6 +516,35 @@ TileDef read_tiledef(lua_State *L, int index, u8 drawtype)
}
/******************************************************************************/
+void push_tiledef(lua_State *L, TileDef tiledef)
+{
+ lua_newtable(L);
+ setstringfield(L, -1, "name", tiledef.name);
+ setboolfield(L, -1, "backface_culling", tiledef.backface_culling);
+ setboolfield(L, -1, "tileable_horizontal", tiledef.tileable_horizontal);
+ setboolfield(L, -1, "tileable_vertical", tiledef.tileable_vertical);
+ std::string align_style;
+ switch (tiledef.align_style) {
+ case ALIGN_STYLE_USER_DEFINED:
+ align_style = "user";
+ break;
+ case ALIGN_STYLE_WORLD:
+ align_style = "world";
+ break;
+ default:
+ align_style = "node";
+ }
+ setstringfield(L, -1, "align_style", align_style);
+ setintfield(L, -1, "scale", tiledef.scale);
+ if (tiledef.has_color) {
+ push_ARGB8(L, tiledef.color);
+ lua_setfield(L, -2, "color");
+ }
+ push_animation_definition(L, tiledef.animation);
+ lua_setfield(L, -2, "animation");
+}
+
+/******************************************************************************/
void read_content_features(lua_State *L, ContentFeatures &f, int index)
{
if(index < 0)
@@ -835,9 +864,32 @@ void push_content_features(lua_State *L, const ContentFeatures &c)
std::string drawtype(ScriptApiNode::es_DrawType[(int)c.drawtype].str);
std::string liquid_type(ScriptApiNode::es_LiquidType[(int)c.liquid_type].str);
- /* Missing "tiles" because I don't see a usecase (at least not yet). */
+ lua_newtable(L);
+ // tiles
lua_newtable(L);
+ for (int i = 0; i < 6; i++) {
+ push_tiledef(L, c.tiledef[i]);
+ lua_rawseti(L, -2, i + 1);
+ }
+ lua_setfield(L, -2, "tiles");
+
+ // overlay_tiles
+ lua_newtable(L);
+ for (int i = 0; i < 6; i++) {
+ push_tiledef(L, c.tiledef_overlay[i]);
+ lua_rawseti(L, -2, i + 1);
+ }
+ lua_setfield(L, -2, "overlay_tiles");
+
+ // special_tiles
+ lua_newtable(L);
+ for (int i = 0; i < CF_SPECIAL_COUNT; i++) {
+ push_tiledef(L, c.tiledef_special[i]);
+ lua_rawseti(L, -2, i + 1);
+ }
+ lua_setfield(L, -2, "special_tiles");
+
lua_pushboolean(L, c.has_on_construct);
lua_setfield(L, -2, "has_on_construct");
lua_pushboolean(L, c.has_on_destruct);
@@ -1886,14 +1938,7 @@ void push_pointed_thing(lua_State *L, const PointedThing &pointed, bool csm,
} else if (pointed.type == POINTEDTHING_OBJECT) {
lua_pushstring(L, "object");
lua_setfield(L, -2, "type");
- if (csm) {
-#ifndef SERVER
- ClientObjectRef::create(L, pointed.object_id);
-#endif
- } else {
- push_objectRef(L, pointed.object_id);
- }
-
+ push_objectRef(L, pointed.object_id);
lua_setfield(L, -2, "ref");
} else {
lua_pushstring(L, "nothing");
diff --git a/src/script/cpp_api/s_base.cpp b/src/script/cpp_api/s_base.cpp
index 1d62d8b65..867f61e0c 100644
--- a/src/script/cpp_api/s_base.cpp
+++ b/src/script/cpp_api/s_base.cpp
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "cpp_api/s_internal.h"
#include "cpp_api/s_security.h"
#include "lua_api/l_object.h"
+#include "lua_api/l_clientobject.h"
#include "common/c_converter.h"
#include "server/player_sao.h"
#include "filesys.h"
@@ -354,13 +355,16 @@ void ScriptApiBase::setOriginFromTableRaw(int index, const char *fxn)
* since we lose control over the ref and the contained pointer.
*/
-void ScriptApiBase::addObjectReference(ServerActiveObject *cobj)
+void ScriptApiBase::addObjectReference(ActiveObject *cobj)
{
SCRIPTAPI_PRECHECKHEADER
//infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
// Create object on stack
- ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
+ if (m_type == ScriptingType::Client)
+ ClientObjectRef::create(L, dynamic_cast<ClientActiveObject *>(cobj));
+ else
+ ObjectRef::create(L, dynamic_cast<ServerActiveObject *>(cobj)); // Puts ObjectRef (as userdata) on stack
int object = lua_gettop(L);
// Get core.object_refs table
@@ -375,7 +379,7 @@ void ScriptApiBase::addObjectReference(ServerActiveObject *cobj)
lua_settable(L, objectstable);
}
-void ScriptApiBase::removeObjectReference(ServerActiveObject *cobj)
+void ScriptApiBase::removeObjectReference(ActiveObject *cobj)
{
SCRIPTAPI_PRECHECKHEADER
//infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
@@ -390,7 +394,10 @@ void ScriptApiBase::removeObjectReference(ServerActiveObject *cobj)
lua_pushnumber(L, cobj->getId()); // Push id
lua_gettable(L, objectstable);
// Set object reference to NULL
- ObjectRef::set_null(L);
+ if (m_type == ScriptingType::Client)
+ ClientObjectRef::set_null(L);
+ else
+ ObjectRef::set_null(L);
lua_pop(L, 1); // pop object
// Set object_refs[id] = nil
@@ -413,7 +420,6 @@ void ScriptApiBase::objectrefGetOrCreate(lua_State *L,
<< ", this is probably a bug." << std::endl;
}
}
-
void ScriptApiBase::pushPlayerHPChangeReason(lua_State *L, const PlayerHPChangeReason &reason)
{
if (reason.hasLuaReference())
diff --git a/src/script/cpp_api/s_base.h b/src/script/cpp_api/s_base.h
index 36331ad37..a7a2c7203 100644
--- a/src/script/cpp_api/s_base.h
+++ b/src/script/cpp_api/s_base.h
@@ -73,6 +73,7 @@ class Game;
class IGameDef;
class Environment;
class GUIEngine;
+class ActiveObject;
class ServerActiveObject;
struct PlayerHPChangeReason;
@@ -99,8 +100,8 @@ public:
RunCallbacksMode mode, const char *fxn);
/* object */
- void addObjectReference(ServerActiveObject *cobj);
- void removeObjectReference(ServerActiveObject *cobj);
+ void addObjectReference(ActiveObject *cobj);
+ void removeObjectReference(ActiveObject *cobj);
IGameDef *getGameDef() { return m_gamedef; }
Server* getServer();
diff --git a/src/script/cpp_api/s_client.cpp b/src/script/cpp_api/s_client.cpp
index 2231cf573..7971e4081 100644
--- a/src/script/cpp_api/s_client.cpp
+++ b/src/script/cpp_api/s_client.cpp
@@ -302,7 +302,7 @@ void ScriptApiClient::on_object_properties_change(s16 id)
lua_getfield(L, -1, "registered_on_object_properties_change");
// Push data
- ClientObjectRef::create(L, id);
+ push_objectRef(L, id);
// Call functions
runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
@@ -317,7 +317,7 @@ void ScriptApiClient::on_object_hp_change(s16 id)
lua_getfield(L, -1, "registered_on_object_hp_change");
// Push data
- ClientObjectRef::create(L, id);
+ push_objectRef(L, id);
// Call functions
runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
diff --git a/src/script/lua_api/l_client.cpp b/src/script/lua_api/l_client.cpp
index 484af2ec3..916983982 100644
--- a/src/script/lua_api/l_client.cpp
+++ b/src/script/lua_api/l_client.cpp
@@ -520,7 +520,7 @@ int ModApiClient::l_get_objects_inside_radius(lua_State *L)
int i = 0;
lua_createtable(L, objs.size(), 0);
for (const auto obj : objs) {
- ClientObjectRef::create(L, obj.obj); // TODO: getObjectRefOrCreate
+ push_objectRef(L, obj.obj->getId());
lua_rawseti(L, -2, ++i);
}
return 1;
diff --git a/src/script/lua_api/l_clientobject.cpp b/src/script/lua_api/l_clientobject.cpp
index 8a4647d45..5a1123169 100644
--- a/src/script/lua_api/l_clientobject.cpp
+++ b/src/script/lua_api/l_clientobject.cpp
@@ -48,6 +48,8 @@ ClientActiveObject *ClientObjectRef::get_cao(ClientObjectRef *ref)
GenericCAO *ClientObjectRef::get_generic_cao(ClientObjectRef *ref, lua_State *L)
{
ClientActiveObject *obj = get_cao(ref);
+ if (! obj)
+ return nullptr;
ClientEnvironment &env = getClient(L)->getEnv();
GenericCAO *gcao = env.getGenericCAO(obj->getId());
return gcao;
@@ -57,6 +59,8 @@ int ClientObjectRef::l_get_pos(lua_State *L)
{
ClientObjectRef *ref = checkobject(L, 1);
ClientActiveObject *cao = get_cao(ref);
+ if (! cao)
+ return 0;
push_v3f(L, cao->getPosition() / BS);
return 1;
}
@@ -65,6 +69,8 @@ int ClientObjectRef::l_get_velocity(lua_State *L)
{
ClientObjectRef *ref = checkobject(L, 1);
GenericCAO *gcao = get_generic_cao(ref, L);
+ if (! gcao)
+ return 0;
push_v3f(L, gcao->getVelocity() / BS);
return 1;
}
@@ -73,6 +79,8 @@ int ClientObjectRef::l_get_acceleration(lua_State *L)
{
ClientObjectRef *ref = checkobject(L, 1);
GenericCAO *gcao = get_generic_cao(ref, L);
+ if (! gcao)
+ return 0;
push_v3f(L, gcao->getAcceleration() / BS);
return 1;
}
@@ -81,6 +89,8 @@ int ClientObjectRef::l_get_rotation(lua_State *L)
{
ClientObjectRef *ref = checkobject(L, 1);
GenericCAO *gcao = get_generic_cao(ref, L);
+ if (! gcao)
+ return 0;
push_v3f(L, gcao->getRotation());
return 1;
}
@@ -89,6 +99,8 @@ int ClientObjectRef::l_is_player(lua_State *L)
{
ClientObjectRef *ref = checkobject(L, 1);
GenericCAO *gcao = get_generic_cao(ref, L);
+ if (! gcao)
+ return 0;
lua_pushboolean(L, gcao->isPlayer());
return 1;
}
@@ -97,6 +109,8 @@ int ClientObjectRef::l_is_local_player(lua_State *L)
{
ClientObjectRef *ref = checkobject(L, 1);
GenericCAO *gcao = get_generic_cao(ref, L);
+ if (! gcao)
+ return 0;
lua_pushboolean(L, gcao->isLocalPlayer());
return 1;
}
@@ -105,6 +119,8 @@ int ClientObjectRef::l_get_name(lua_State *L)
{
ClientObjectRef *ref = checkobject(L, 1);
GenericCAO *gcao = get_generic_cao(ref, L);
+ if (! gcao)
+ return 0;
lua_pushstring(L, gcao->getName().c_str());
return 1;
}
@@ -113,7 +129,12 @@ int ClientObjectRef::l_get_attach(lua_State *L)
{
ClientObjectRef *ref = checkobject(L, 1);
GenericCAO *gcao = get_generic_cao(ref, L);
- create(L, gcao->getParent());
+ if (! gcao)
+ return 0;
+ ClientActiveObject *parent = gcao->getParent();
+ if (! parent)
+ return 0;
+ push_objectRef(L, parent->getId());
return 1;
}
@@ -122,6 +143,8 @@ int ClientObjectRef::l_get_nametag(lua_State *L)
log_deprecated(L,"Deprecated call to get_nametag, use get_properties().nametag instead");
ClientObjectRef *ref = checkobject(L, 1);
GenericCAO *gcao = get_generic_cao(ref, L);
+ if (! gcao)
+ return 0;
ObjectProperties *props = gcao->getProperties();
lua_pushstring(L, props->nametag.c_str());
return 1;
@@ -132,6 +155,8 @@ int ClientObjectRef::l_get_item_textures(lua_State *L)
log_deprecated(L,"Deprecated call to get_item_textures, use get_properties().textures instead");
ClientObjectRef *ref = checkobject(L, 1);
GenericCAO *gcao = get_generic_cao(ref, L);
+ if (! gcao)
+ return 0;
ObjectProperties *props = gcao->getProperties();
lua_newtable(L);
@@ -146,6 +171,8 @@ int ClientObjectRef::l_get_max_hp(lua_State *L)
log_deprecated(L,"Deprecated call to get_max_hp, use get_properties().hp_max instead");
ClientObjectRef *ref = checkobject(L, 1);
GenericCAO *gcao = get_generic_cao(ref, L);
+ if (! gcao)
+ return 0;
ObjectProperties *props = gcao->getProperties();
lua_pushnumber(L, props->hp_max);
return 1;
@@ -155,6 +182,8 @@ int ClientObjectRef::l_get_properties(lua_State *L)
{
ClientObjectRef *ref = checkobject(L, 1);
GenericCAO *gcao = get_generic_cao(ref, L);
+ if (! gcao)
+ return 0;
ObjectProperties *prop = gcao->getProperties();
push_object_properties(L, prop);
return 1;
@@ -164,6 +193,8 @@ int ClientObjectRef::l_set_properties(lua_State *L)
{
ClientObjectRef *ref = checkobject(L, 1);
GenericCAO *gcao = get_generic_cao(ref, L);
+ if (! gcao)
+ return 0;
ObjectProperties prop = *gcao->getProperties();
read_object_properties(L, 2, nullptr, &prop, getClient(L)->idef());
gcao->setProperties(prop);
@@ -174,6 +205,8 @@ int ClientObjectRef::l_get_hp(lua_State *L)
{
ClientObjectRef *ref = checkobject(L, 1);
GenericCAO *gcao = get_generic_cao(ref, L);
+ if (! gcao)
+ return 0;
lua_pushnumber(L, gcao->getHp());
return 1;
}
@@ -182,6 +215,8 @@ int ClientObjectRef::l_punch(lua_State *L)
{
ClientObjectRef *ref = checkobject(L, 1);
GenericCAO *gcao = get_generic_cao(ref, L);
+ if (! gcao)
+ return 0;
PointedThing pointed(gcao->getId(), v3f(0, 0, 0), v3s16(0, 0, 0), 0);
getClient(L)->interact(INTERACT_START_DIGGING, pointed);
return 0;
@@ -191,6 +226,8 @@ int ClientObjectRef::l_rightclick(lua_State *L)
{
ClientObjectRef *ref = checkobject(L, 1);
GenericCAO *gcao = get_generic_cao(ref, L);
+ if (! gcao)
+ return 0;
PointedThing pointed(gcao->getId(), v3f(0, 0, 0), v3s16(0, 0, 0), 0);
getClient(L)->interact(INTERACT_PLACE, pointed);
return 0;
@@ -200,6 +237,8 @@ int ClientObjectRef::l_remove(lua_State *L)
{
ClientObjectRef *ref = checkobject(L, 1);
ClientActiveObject *cao = get_cao(ref);
+ if (! cao)
+ return 0;
getClient(L)->getEnv().removeActiveObject(cao->getId());
return 0;
@@ -209,6 +248,8 @@ int ClientObjectRef::l_set_nametag_images(lua_State *L)
{
ClientObjectRef *ref = checkobject(L, 1);
GenericCAO *gcao = get_generic_cao(ref, L);
+ if (! gcao)
+ return 0;
gcao->nametag_images.clear();
if(lua_istable(L, 2)){
lua_pushnil(L);
@@ -228,12 +269,10 @@ ClientObjectRef::ClientObjectRef(ClientActiveObject *object) : m_object(object)
void ClientObjectRef::create(lua_State *L, ClientActiveObject *object)
{
- if (object) {
- ClientObjectRef *o = new ClientObjectRef(object);
- *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
- luaL_getmetatable(L, className);
- lua_setmetatable(L, -2);
- }
+ ClientObjectRef *o = new ClientObjectRef(object);
+ *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
+ luaL_getmetatable(L, className);
+ lua_setmetatable(L, -2);
}
void ClientObjectRef::create(lua_State *L, s16 id)
@@ -241,6 +280,12 @@ void ClientObjectRef::create(lua_State *L, s16 id)
create(L, ((ClientEnvironment *)getEnv(L))->getActiveObject(id));
}
+void ClientObjectRef::set_null(lua_State *L)
+{
+ ClientObjectRef *obj = checkobject(L, -1);
+ obj->m_object = nullptr;
+}
+
int ClientObjectRef::gc_object(lua_State *L)
{
ClientObjectRef *obj = *(ClientObjectRef **)(lua_touserdata(L, 1));
diff --git a/src/script/lua_api/l_clientobject.h b/src/script/lua_api/l_clientobject.h
index 60d10dcf6..c4c95cb41 100644
--- a/src/script/lua_api/l_clientobject.h
+++ b/src/script/lua_api/l_clientobject.h
@@ -35,6 +35,8 @@ public:
static void create(lua_State *L, ClientActiveObject *object);
static void create(lua_State *L, s16 id);
+ static void set_null(lua_State *L);
+
static ClientObjectRef *checkobject(lua_State *L, int narg);
private:
diff --git a/src/script/lua_api/l_localplayer.cpp b/src/script/lua_api/l_localplayer.cpp
index 747657016..b8673379a 100644
--- a/src/script/lua_api/l_localplayer.cpp
+++ b/src/script/lua_api/l_localplayer.cpp
@@ -483,7 +483,7 @@ int LuaLocalPlayer::l_get_object(lua_State *L)
ClientEnvironment &env = getClient(L)->getEnv();
ClientActiveObject *obj = env.getGenericCAO(player->getCAO()->getId());
- ClientObjectRef::create(L, obj);
+ push_objectRef(L, obj->getId());
return 1;
}
diff --git a/src/serverenvironment.cpp b/src/serverenvironment.cpp
index 3d9ba132b..cd5ac0753 100644
--- a/src/serverenvironment.cpp
+++ b/src/serverenvironment.cpp
@@ -1170,7 +1170,7 @@ void ServerEnvironment::clearObjects(ClearObjectsMode mode)
// Tell the object about removal
obj->removingFromEnvironment();
// Deregister in scripting api
- m_script->removeObjectReference(obj);
+ m_script->removeObjectReference(dynamic_cast<ActiveObject *>(obj));
// Delete active object
if (obj->environmentDeletes())
@@ -1736,7 +1736,7 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object,
}
// Register reference in scripting api (must be done before post-init)
- m_script->addObjectReference(object);
+ m_script->addObjectReference(dynamic_cast<ActiveObject *>(object));
// Post-initialize object
object->addedToEnvironment(dtime_s);
@@ -1826,7 +1826,7 @@ void ServerEnvironment::removeRemovedObjects()
// Tell the object about removal
obj->removingFromEnvironment();
// Deregister in scripting api
- m_script->removeObjectReference(obj);
+ m_script->removeObjectReference(dynamic_cast<ActiveObject *>(obj));
// Delete
if (obj->environmentDeletes())
@@ -2091,7 +2091,7 @@ void ServerEnvironment::deactivateFarObjects(bool _force_delete)
// Tell the object about removal
obj->removingFromEnvironment();
// Deregister in scripting api
- m_script->removeObjectReference(obj);
+ m_script->removeObjectReference(dynamic_cast<ActiveObject *>(obj));
// Delete active object
if (obj->environmentDeletes())