| 
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -68,6 +68,7 @@ inline void lua_swap(lua_State *state) { lua_insert(state, -2); }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#define DFHACK_COMPARE_NAME "DFHack::ComparePtrs"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#define DFHACK_TYPE_TOSTRING_NAME "DFHack::TypeToString"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#define DFHACK_SIZEOF_NAME "DFHack::Sizeof"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#define DFHACK_DISPLACE_NAME "DFHack::Displace"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				/*
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * Upvalue: contents of DFHACK_TYPETABLE_NAME
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -514,7 +515,8 @@ static void *get_object_internal(lua_State *state, type_identity *type, int val_
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				/**
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * Given a DF object reference or type, safely retrieve its identity pointer.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static type_identity *get_object_identity(lua_State *state, int objidx, const char *ctx)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static type_identity *get_object_identity(lua_State *state, int objidx,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                          const char *ctx, bool allow_type = false)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (!lua_getmetatable(state, objidx))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        luaL_error(state, "Invalid object in %s", ctx);
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -527,6 +529,9 @@ static type_identity *get_object_identity(lua_State *state, int objidx, const ch
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if (!allow_type)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            luaL_error(state, "Object expected in %s", ctx);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        lua_pushvalue(state, objidx);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        LookupInTable(state, DFHACK_TYPEID_TABLE_NAME);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -604,7 +609,7 @@ static int meta_sizeof(lua_State *state)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return 2;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    type_identity *id = get_object_identity(state, 1, "df.sizeof()");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    type_identity *id = get_object_identity(state, 1, "df.sizeof()", true);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    lua_pushinteger(state, id->byte_size());
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -617,6 +622,62 @@ static int meta_sizeof(lua_State *state)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return 1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				/**
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * Method: displace for DF object references.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 *
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * Returns: a reference with the same type, but modified address
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static int meta_displace(lua_State *state)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    int argc = lua_gettop(state);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    bool has_step = (argc >= 3);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if ((argc < 2 || argc > 3) ||
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        !lua_isnumber(state, 2) ||
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        (has_step && !lua_isnumber(state, 3)))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        luaL_error(state, "Usage: object:_displace(index[,step]) or df._displace(object,...)");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    int index = lua_tointeger(state, 2);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    int step = has_step ? lua_tointeger(state, 3) : 1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    // Two special cases: nil and lightuserdata for NULL and void*
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (lua_isnil(state, 1))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        lua_pushnil(state);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return 1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (lua_islightuserdata(state, 1))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if (!has_step)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            luaL_error(state, "Step is mandatory in _displace of void*");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        auto ptr = (uint8_t*)lua_touserdata(state, 1);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        lua_pushlightuserdata(state, ptr + index*step);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return 1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    type_identity *id = get_object_identity(state, 1, "df._displace()");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (!has_step)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        step = id->byte_size();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (index == 0 || step == 0)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        lua_pushvalue(state, 1);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        auto ptr = (uint8_t*)get_object_ref(state, 1);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        lua_getmetatable(state, 1);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        push_object_ref(state, ptr + index*step);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return 1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				/**
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * Resolve the field name in UPVAL_FIELDTABLE, die if not found.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 */
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -1063,9 +1124,14 @@ static void SetPtrMethods(lua_State *state, int meta_idx, int read_idx)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_SIZEOF_NAME);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    lua_setfield(state, meta_idx, "sizeof");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_DISPLACE_NAME);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    lua_setfield(state, meta_idx, "_displace");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    EnableMetaField(state, read_idx, "_type");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    EnableMetaField(state, read_idx, "_kind");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    EnableMetaField(state, read_idx, "sizeof");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    EnableMetaField(state, read_idx, "_displace");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				/**
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -1485,6 +1551,9 @@ static void DoAttach(lua_State *state)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    lua_pushcfunction(state, meta_sizeof);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    lua_setfield(state, LUA_REGISTRYINDEX, DFHACK_SIZEOF_NAME);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    lua_pushcfunction(state, meta_displace);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    lua_setfield(state, LUA_REGISTRYINDEX, DFHACK_DISPLACE_NAME);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    luaL_register(state, "df", no_functions);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -1496,6 +1565,8 @@ static void DoAttach(lua_State *state)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_SIZEOF_NAME);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        lua_setfield(state, -2, "sizeof");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_DISPLACE_NAME);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        lua_setfield(state, -2, "_displace");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        freeze_table(state, true, "df");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        lua_remove(state, -2);
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
			
			 | 
			 | 
			
				
 
 |