/* ### nhlobj.c ### */
#if !defined(CROSSCOMPILE) || defined(CROSSCOMPILE_TARGET)
+E void FDECL(nhl_push_obj, (lua_State *, struct obj *));
E int FDECL(l_obj_register, (lua_State *));
#endif
unsigned oeaten; /* nutrition left in food, if partly eaten */
long age; /* creation date */
long owornmask;
+ unsigned lua_ref_cnt; /* # of lua script references for this object */
struct oextra *oextra; /* pointer to oextra struct */
};
* Incrementing EDITLEVEL can be used to force invalidation of old bones
* and save files.
*/
-#define EDITLEVEL 5
+#define EDITLEVEL 6
#define COPYRIGHT_BANNER_A "NetHack, Copyright 1985-2019"
#define COPYRIGHT_BANNER_B \
obj->owt = weight(obj);
otmp->quan = num;
otmp->owt = weight(otmp); /* -= obj->owt ? */
+ otmp->lua_ref_cnt = 0;
g.context.objsplit.parent_oid = obj->o_id;
g.context.objsplit.child_oid = otmp->o_id;
otmp->lknown = 0;
otmp->cknown = 0;
otmp->corpsenm = NON_PM;
+ otmp->lua_ref_cnt = 0;
if (init) {
switch (let) {
* list must track all objects that can have a light source
* attached to it (and also requires lamplit to be set).
*/
- if (obj_sheds_light(obj))
+ if (obj_sheds_light(obj)) {
del_light_source(LS_OBJECT, obj_to_any(obj));
+ obj->lamplit = 0;
+ }
if (obj == g.thrownobj)
g.thrownobj = 0;
if (obj->oextra)
dealloc_oextra(obj);
+ if (obj->lua_ref_cnt)
+ return; /* obj is referenced from a lua script, let lua gc free it */
free((genericptr_t) obj);
}
struct _lua_obj *lo = l_obj_check(L, 1);
if (lo && lo->obj) {
- /* free-floating objects are deallocated */
- if (lo->obj->where == OBJ_FREE) {
+ if (lo->obj->lua_ref_cnt > 0)
+ lo->obj->lua_ref_cnt--;
+ /* free-floating objects with no other refs are deallocated. */
+ if (lo->obj->where == OBJ_FREE && !lo->obj->lua_ref_cnt) {
if (Has_contents(lo->obj)) {
struct obj *otmp;
while ((otmp = lo->obj->cobj) != 0) {
lo->state = 0;
lo->obj = otmp;
+ if (otmp)
+ otmp->lua_ref_cnt++;
return lo;
}
+void
+nhl_push_obj(L, otmp)
+lua_State *L;
+struct obj *otmp;
+{
+ (void) l_obj_push(L, otmp);
+}
+
/* local o = obj.new("large chest");
local cobj = o:contents(); */
static int
return nhl_push_anything(L, ustruct[i].type, ustruct[i].ptr);
}
+ if (!strcmp(tkey, "inventory")) {
+ nhl_push_obj(L, g.invent);
+ return 1;
+ }
+
nhl_error(L, "Unknown u table index");
return 0;
}
if (nhfp->structlevel)
mread(nhfp->fd, (genericptr_t) otmp, sizeof(struct obj));
+ otmp->lua_ref_cnt = 0;
/* next object pointers are invalid; otmp->cobj needs to be left
as is--being non-null is key to restoring container contents */
otmp->nobj = otmp->nexthere = (struct obj *) 0;