mirror of
https://github.com/IntQuant/noita_entangled_worlds.git
synced 2025-10-19 15:13:16 +00:00
Update NoitaPatcher to 1.34.0
This commit is contained in:
parent
4fbecb8bfe
commit
ebb66dfb0a
8 changed files with 264 additions and 102 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,5 +1,7 @@
|
|||
---@diagnostic disable: cast-local-type
|
||||
---World read / write functionality.
|
||||
---@module 'noitapatcher.nsew.world'
|
||||
---@class World
|
||||
local world = {}
|
||||
|
||||
local ffi = require("ffi")
|
||||
|
@ -10,7 +12,7 @@ local C = ffi.C
|
|||
ffi.cdef([[
|
||||
|
||||
enum ENCODE_CONST {
|
||||
PIXEL_RUN_MAX = 16000,
|
||||
PIXEL_RUN_MAX = 4096,
|
||||
|
||||
LIQUID_FLAG_STATIC = 1,
|
||||
};
|
||||
|
@ -37,40 +39,60 @@ struct __attribute__ ((__packed__)) EncodedArea {
|
|||
|
||||
]])
|
||||
|
||||
world.last_material_id = 0
|
||||
---@class PixelRun
|
||||
---@field flags integer
|
||||
---@field material integer
|
||||
---@field length integer
|
||||
|
||||
---@class EncodedAreaHeader
|
||||
---@field x integer
|
||||
---@field y integer
|
||||
---@field width integer
|
||||
---@field height integer
|
||||
---@field pixel_run_count integer
|
||||
|
||||
---@class EncodedArea
|
||||
---@field header EncodedAreaHeader
|
||||
---@field pixel_runs PixelRun[] a pointer
|
||||
|
||||
world.EncodedAreaHeader = ffi.typeof("struct EncodedAreaHeader")
|
||||
world.PixelRun = ffi.typeof("struct PixelRun")
|
||||
---@type fun(): EncodedArea
|
||||
---@diagnostic disable-next-line: assign-type-mismatch
|
||||
world.EncodedArea = ffi.typeof("struct EncodedArea")
|
||||
|
||||
local pliquid_cell = ffi.typeof("struct CLiquidCell*")
|
||||
|
||||
---Total bytes taken up by the encoded area
|
||||
-- @tparam EncodedArea encoded_area
|
||||
-- @treturn int total number of bytes that encodes the area
|
||||
-- @usage
|
||||
-- local data = ffi.string(area, world.encoded_size(area))
|
||||
-- peer:send(data)
|
||||
---@param encoded_area EncodedArea
|
||||
---@return integer total number of bytes that encodes the area
|
||||
---```lua
|
||||
---local data = ffi.string(area, world.encoded_size(area))
|
||||
---peer:send(data)
|
||||
---```
|
||||
function world.encoded_size(encoded_area)
|
||||
return (ffi.sizeof(world.EncodedAreaHeader) + encoded_area.header.pixel_run_count * ffi.sizeof(world.PixelRun))
|
||||
return ffi.sizeof(world.EncodedAreaHeader) + encoded_area.header.pixel_run_count * ffi.sizeof(world.PixelRun)
|
||||
end
|
||||
|
||||
---Encode the given rectangle of the world
|
||||
-- The rectangle defined by {`start_x`, `start_y`, `end_x`, `end_y`} must not
|
||||
-- exceed 256 in width or height.
|
||||
-- @param chunk_map
|
||||
-- @tparam int start_x coordinate
|
||||
-- @tparam int start_y coordinate
|
||||
-- @tparam int end_x coordinate
|
||||
-- @tparam int end_y coordinate
|
||||
-- @tparam EncodedArea encoded_area memory to use, if nil this function allocates its own memory
|
||||
-- @return returns an EncodedArea or nil if the area could not be encoded
|
||||
-- @see decode
|
||||
---The rectangle defined by {`start_x`, `start_y`, `end_x`, `end_y`} must not exceed 256 in width or height.
|
||||
---@param chunk_map unknown
|
||||
---@param start_x integer coordinate
|
||||
---@param start_y integer coordinate
|
||||
---@param end_x integer coordinate
|
||||
---@param end_y integer coordinate
|
||||
---@param encoded_area EncodedArea? memory to use, if nil this function allocates its own memory
|
||||
---@return EncodedArea? encoded_area returns an EncodedArea or nil if the area could not be encoded
|
||||
---@see decode
|
||||
function world.encode_area(chunk_map, start_x, start_y, end_x, end_y, encoded_area)
|
||||
start_x = ffi.cast('int32_t', start_x)
|
||||
start_y = ffi.cast('int32_t', start_y)
|
||||
end_x = ffi.cast('int32_t', end_x)
|
||||
end_y = ffi.cast('int32_t', end_y)
|
||||
---@cast start_x integer
|
||||
---@cast start_y integer
|
||||
---@cast end_x integer
|
||||
---@cast end_x integer
|
||||
|
||||
encoded_area = encoded_area or world.EncodedArea()
|
||||
|
||||
|
@ -163,13 +185,13 @@ function world.encode_area(chunk_map, start_x, start_y, end_x, end_y, encoded_ar
|
|||
return encoded_area
|
||||
end
|
||||
|
||||
--local PixelRun_const_ptr = ffi.typeof("struct PixelRun const*")
|
||||
local PixelRun_const_ptr = ffi.typeof("struct PixelRun const*")
|
||||
|
||||
---Load an encoded area back into the world.
|
||||
-- @param grid_world
|
||||
-- @tparam EncodedAreaHeader header header of the encoded area
|
||||
-- @param received pointer or ffi array of PixelRun from the encoded area
|
||||
-- @see encode_area
|
||||
---@param grid_world unknown
|
||||
---@param header EncodedAreaHeader header of the encoded area
|
||||
---@param pixel_runs PixelRun[] or ffi array of PixelRun from the encoded area
|
||||
---@see encode_area
|
||||
function world.decode(grid_world, header, pixel_runs)
|
||||
local chunk_map = grid_world.vtable.get_chunk_map(grid_world)
|
||||
|
||||
|
@ -192,19 +214,10 @@ function world.decode(grid_world, header, pixel_runs)
|
|||
while x < bottom_right_x do
|
||||
if world_ffi.chunk_loaded(chunk_map, x, y) then
|
||||
local ppixel = world_ffi.get_cell(chunk_map, x, y)
|
||||
|
||||
local current_material = 0
|
||||
|
||||
if new_material == -1 then
|
||||
goto next_pixel
|
||||
end
|
||||
|
||||
if ppixel[0] ~= nil then
|
||||
local pixel = ppixel[0]
|
||||
local cell_type = pixel.vtable.get_cell_type(pixel)
|
||||
if cell_type == C.CELL_TYPE_SOLID then
|
||||
goto next_pixel
|
||||
end
|
||||
current_material = world_ffi.get_material_id(pixel.vtable.get_material(pixel))
|
||||
|
||||
if new_material ~= current_material then
|
||||
|
@ -213,14 +226,7 @@ function world.decode(grid_world, header, pixel_runs)
|
|||
end
|
||||
|
||||
if current_material ~= new_material and new_material ~= 0 then
|
||||
if new_material > world.last_material_id then
|
||||
goto next_pixel
|
||||
end
|
||||
local mat_ptr = world_ffi.get_material_ptr(new_material)
|
||||
if mat_ptr == nil then
|
||||
goto next_pixel
|
||||
end
|
||||
local pixel = world_ffi.construct_cell(grid_world, x, y, mat_ptr, nil)
|
||||
local pixel = world_ffi.construct_cell(grid_world, x, y, world_ffi.get_material_ptr(new_material), nil)
|
||||
if pixel == nil then
|
||||
-- TODO: This can happen when the material texture has a
|
||||
-- transparent pixel at the given coordinate. There's
|
||||
|
@ -228,7 +234,6 @@ function world.decode(grid_world, header, pixel_runs)
|
|||
-- we skip positions like this.
|
||||
goto next_pixel
|
||||
end
|
||||
|
||||
local cell_type = pixel.vtable.get_cell_type(pixel)
|
||||
|
||||
if cell_type == C.CELL_TYPE_LIQUID then
|
||||
|
|
|
@ -37,6 +37,139 @@ struct AABB {
|
|||
struct Position bottom_right;
|
||||
};
|
||||
|
||||
struct std_string { /* VC++ std::string */
|
||||
char *buffer;
|
||||
char sso_buffer[12];
|
||||
size_t size;
|
||||
size_t capacity;
|
||||
};
|
||||
|
||||
typedef enum cell_type {
|
||||
none=0,
|
||||
liquid=1,
|
||||
gas=2,
|
||||
solid=3,
|
||||
fire=4,
|
||||
invalid=4294967295
|
||||
} cell_type;
|
||||
|
||||
struct CellData {
|
||||
struct std_string name;
|
||||
struct std_string ui_name;
|
||||
int material_type;
|
||||
int id_2;
|
||||
enum cell_type cell_type;
|
||||
int platform_type;
|
||||
unsigned int wang_color;
|
||||
int gfx_glow;
|
||||
unsigned int gfx_glow_color;
|
||||
char unknown1[24];
|
||||
unsigned int default_primary_colour;
|
||||
char unknown2[36];
|
||||
bool cell_holes_in_texture;
|
||||
bool stainable;
|
||||
bool burnable;
|
||||
bool on_fire;
|
||||
int fire_hp;
|
||||
int autoignition_temperature;
|
||||
int _100_minus_autoignition_temp;
|
||||
int temperature_of_fire;
|
||||
int generates_smoke;
|
||||
int generates_flames;
|
||||
bool requires_oxygen;
|
||||
char padding1[3];
|
||||
struct std_string on_fire_convert_to_material;
|
||||
int on_fire_convert_to_material_id;
|
||||
struct std_string on_fire_flame_material;
|
||||
int on_fire_flame_material_id;
|
||||
struct std_string on_fire_smoke_material;
|
||||
int on_fire_smoke_material_id;
|
||||
struct ConfigExplosion *explosion_config;
|
||||
int durability;
|
||||
int crackability;
|
||||
bool electrical_conductivity;
|
||||
bool slippery;
|
||||
char padding2[2];
|
||||
float stickyness;
|
||||
struct std_string cold_freezes_to_material;
|
||||
struct std_string warmth_melts_to_material;
|
||||
int warmth_melts_to_material_id;
|
||||
int cold_freezes_to_material_id;
|
||||
int16_t cold_freezes_chance_rev;
|
||||
int16_t warmth_melts_chance_rev;
|
||||
bool cold_freezes_to_dont_do_reverse_reaction;
|
||||
char padding3[3];
|
||||
int lifetime;
|
||||
int hp;
|
||||
float density;
|
||||
bool liquid_sand;
|
||||
bool liquid_slime;
|
||||
bool liquid_static;
|
||||
bool liquid_stains_self;
|
||||
int liquid_sticks_to_ceiling;
|
||||
float liquid_gravity;
|
||||
int liquid_viscosity;
|
||||
int liquid_stains;
|
||||
unsigned int liquid_stains_custom_color;
|
||||
float liquid_sprite_stain_shaken_drop_chance;
|
||||
float liquid_sprite_stain_ignited_drop_chance;
|
||||
int8_t liquid_sprite_stains_check_offset;
|
||||
char padding4[3];
|
||||
float liquid_sprite_stains_status_threshold;
|
||||
float liquid_damping;
|
||||
float liquid_flow_speed;
|
||||
bool liquid_sand_never_box2d;
|
||||
char unknown7[3];
|
||||
int8_t gas_speed;
|
||||
int8_t gas_upwards_speed;
|
||||
int8_t gas_horizontal_speed;
|
||||
int8_t gas_downwards_speed;
|
||||
float solid_friction;
|
||||
float solid_restitution;
|
||||
float solid_gravity_scale;
|
||||
int solid_static_type;
|
||||
float solid_on_collision_splash_power;
|
||||
bool solid_on_collision_explode;
|
||||
bool solid_on_sleep_convert;
|
||||
bool solid_on_collision_convert;
|
||||
bool solid_on_break_explode;
|
||||
bool solid_go_through_sand;
|
||||
bool solid_collide_with_self;
|
||||
char padding5[2];
|
||||
struct std_string solid_on_collision_material;
|
||||
int solid_on_collision_material_id;
|
||||
struct std_string solid_break_to_type;
|
||||
int solid_break_to_type_id;
|
||||
struct std_string convert_to_box2d_material;
|
||||
int convert_to_box2d_material_id;
|
||||
int vegetation_full_lifetime_growth;
|
||||
struct std_string vegetation_sprite;
|
||||
bool vegetation_random_flip_x_scale;
|
||||
char padding6[3];
|
||||
char unknown11[12];
|
||||
float wang_noise_percent;
|
||||
float wang_curvature;
|
||||
int wang_noise_type;
|
||||
char unknown12[12];
|
||||
bool danger_fire;
|
||||
bool danger_radioactive;
|
||||
bool danger_poison;
|
||||
bool danger_water;
|
||||
char unknown13[24];
|
||||
bool always_ignites_damagemodel;
|
||||
bool ignore_self_reaction_warning;
|
||||
char padding7[2];
|
||||
char unknown14[12];
|
||||
float audio_size_multiplier;
|
||||
bool audio_is_soft;
|
||||
char padding8[3];
|
||||
char unknown15[8];
|
||||
bool show_in_creative_mode;
|
||||
bool is_just_particle_fx;
|
||||
char padding9[2];
|
||||
// struct grid_CosmeticParticleConfig *ParticleEffect;
|
||||
};
|
||||
|
||||
enum CellType {
|
||||
CELL_TYPE_NONE = 0,
|
||||
CELL_TYPE_LIQUID = 1,
|
||||
|
@ -58,7 +191,7 @@ struct Cell_vtable {
|
|||
void* field9_0x24;
|
||||
void* field10_0x28;
|
||||
void* field11_0x2c;
|
||||
void* (__thiscall *get_material)(void *);
|
||||
struct CellData* (__thiscall *get_material)(void *);
|
||||
void* field13_0x34;
|
||||
void* field14_0x38;
|
||||
void* field15_0x3c;
|
||||
|
@ -189,9 +322,28 @@ typedef struct Cell* __thiscall construct_cell_f(struct GridWorld*, int x, int y
|
|||
|
||||
]])
|
||||
|
||||
--local function check_celldata_field(f, o)
|
||||
-- local offset = ffi.offsetof("struct CellData", f)
|
||||
-- assert(offset == o, "Expected field " .. f .. " to be at offset " .. o)
|
||||
--end
|
||||
--
|
||||
--check_celldata_field("wang_color", 0x40)
|
||||
--check_celldata_field("generates_flames", 0xa4)
|
||||
--check_celldata_field("durability", 0x104)
|
||||
--check_celldata_field("cold_freezes_to_material", 0x114)
|
||||
--check_celldata_field("liquid_sand", 0x160)
|
||||
--check_celldata_field("liquid_sprite_stain_ignited_drop_chance", 0x17c)
|
||||
--check_celldata_field("gas_horizontal_speed", 0x196)
|
||||
--check_celldata_field("solid_on_sleep_convert", 0x1ad)
|
||||
--check_celldata_field("solid_break_to_type", 0x1d0)
|
||||
--check_celldata_field("vegetation_sprite", 0x20c)
|
||||
--check_celldata_field("wang_noise_type", 0x23c)
|
||||
--check_celldata_field("ignore_self_reaction_warning", 0x269)
|
||||
--check_celldata_field("is_just_particle_fx", 0x289)
|
||||
|
||||
---@class ChunkMap pointer type
|
||||
---@class GridWorld pointer type
|
||||
---@class Material pointer type
|
||||
---@class CellData pointer type
|
||||
---@class Cell pointer type
|
||||
|
||||
---Access a pixel in the world.
|
||||
|
@ -205,7 +357,7 @@ world_ffi.get_cell = ffi.cast("get_cell_f*", world_info.get_cell)
|
|||
world_ffi.remove_cell = ffi.cast("remove_cell_f*", world_info.remove_cell)
|
||||
|
||||
---Create a new cell. If memory is null pointer it will allocate its own memory.
|
||||
---@type fun(grid_world: GridWorld, x: integer, y: integer, material: Material, memory: ffi.cdata*)
|
||||
---@type fun(grid_world: GridWorld, x: integer, y: integer, material: CellData, memory: ffi.cdata*)
|
||||
world_ffi.construct_cell = ffi.cast("construct_cell_f*", world_info.construct_cell)
|
||||
|
||||
---Check if a chunk is loaded. x and y are world coordinates.
|
||||
|
@ -239,10 +391,11 @@ function world_ffi.get_grid_world()
|
|||
end
|
||||
|
||||
local celldata_size = 0x290
|
||||
local CellData_ptr = ffi.typeof("struct CellData*")
|
||||
|
||||
---Turn a standard material id into a material pointer.
|
||||
---@param id integer material id that is used in the standard Noita functions
|
||||
---@return Material material to internal material data (aka cell data).
|
||||
---@return CellData material to internal material data (aka cell data).
|
||||
---```lua
|
||||
---local gold_ptr = world_ffi.get_material_ptr(CellFactory_GetType("gold"))
|
||||
---```
|
||||
|
@ -251,11 +404,11 @@ function world_ffi.get_material_ptr(id)
|
|||
local cell_factory = ffi.cast('char**', (game_global + 0x18))[0]
|
||||
local begin = ffi.cast('char**', cell_factory + 0x18)[0]
|
||||
local ptr = begin + celldata_size * id
|
||||
return ptr
|
||||
return ffi.cast(CellData_ptr, ptr) --[[@as CellData]]
|
||||
end
|
||||
|
||||
---Turn a material pointer into a standard material id.
|
||||
---@param material Material to a material (aka cell data)
|
||||
---@param material CellData to a material (aka cell data)
|
||||
---@return integer material id that is accepted by standard Noita functions such as `CellFactory_GetUIName` and `ConvertMaterialOnAreaInstantly`.
|
||||
---```lua
|
||||
---local mat_id = world_ffi.get_material_id(cell.vtable.get_material(cell))
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
---@diagnostic disable: cast-local-type
|
||||
--- World read / write functionality.
|
||||
---@module 'noitapatcher.nsew.world'
|
||||
---@class World
|
||||
local world = {}
|
||||
|
||||
local ffi = require("ffi")
|
||||
|
@ -12,7 +10,7 @@ local C = ffi.C
|
|||
ffi.cdef([[
|
||||
|
||||
enum ENCODE_CONST {
|
||||
PIXEL_RUN_MAX = 4096,
|
||||
PIXEL_RUN_MAX = 16000,
|
||||
|
||||
LIQUID_FLAG_STATIC = 1,
|
||||
};
|
||||
|
@ -39,60 +37,40 @@ struct __attribute__ ((__packed__)) EncodedArea {
|
|||
|
||||
]])
|
||||
|
||||
---@class PixelRun
|
||||
---@field flags integer
|
||||
---@field material integer
|
||||
---@field length integer
|
||||
|
||||
---@class EncodedAreaHeader
|
||||
---@field x integer
|
||||
---@field y integer
|
||||
---@field width integer
|
||||
---@field height integer
|
||||
---@field pixel_run_count integer
|
||||
|
||||
---@class EncodedArea
|
||||
---@field header EncodedAreaHeader
|
||||
---@field pixel_runs PixelRun[] a pointer
|
||||
world.last_material_id = 0
|
||||
|
||||
world.EncodedAreaHeader = ffi.typeof("struct EncodedAreaHeader")
|
||||
world.PixelRun = ffi.typeof("struct PixelRun")
|
||||
---@type fun(): EncodedArea
|
||||
---@diagnostic disable-next-line: assign-type-mismatch
|
||||
world.EncodedArea = ffi.typeof("struct EncodedArea")
|
||||
|
||||
local pliquid_cell = ffi.typeof("struct CLiquidCell*")
|
||||
|
||||
--- Total bytes taken up by the encoded area
|
||||
---@param encoded_area EncodedArea
|
||||
---@return integer total number of bytes that encodes the area
|
||||
---```lua
|
||||
---local data = ffi.string(area, world.encoded_size(area))
|
||||
---peer:send(data)
|
||||
---```
|
||||
-- @tparam EncodedArea encoded_area
|
||||
-- @treturn int total number of bytes that encodes the area
|
||||
-- @usage
|
||||
-- local data = ffi.string(area, world.encoded_size(area))
|
||||
-- peer:send(data)
|
||||
function world.encoded_size(encoded_area)
|
||||
return (ffi.sizeof(world.EncodedAreaHeader) + encoded_area.header.pixel_run_count * ffi.sizeof(world.PixelRun))
|
||||
end
|
||||
|
||||
--- Encode the given rectangle of the world
|
||||
---The rectangle defined by {`start_x`, `start_y`, `end_x`, `end_y`} must not exceed 256 in width or height.
|
||||
---@param chunk_map unknown
|
||||
---@param start_x integer coordinate
|
||||
---@param start_y integer coordinate
|
||||
---@param end_x integer coordinate
|
||||
---@param end_y integer coordinate
|
||||
---@param encoded_area EncodedArea? memory to use, if nil this function allocates its own memory
|
||||
---@return EncodedArea? encoded_area returns an EncodedArea or nil if the area could not be encoded
|
||||
---@see decode
|
||||
-- The rectangle defined by {`start_x`, `start_y`, `end_x`, `end_y`} must not
|
||||
-- exceed 256 in width or height.
|
||||
-- @param chunk_map
|
||||
-- @tparam int start_x coordinate
|
||||
-- @tparam int start_y coordinate
|
||||
-- @tparam int end_x coordinate
|
||||
-- @tparam int end_y coordinate
|
||||
-- @tparam EncodedArea encoded_area memory to use, if nil this function allocates its own memory
|
||||
-- @return returns an EncodedArea or nil if the area could not be encoded
|
||||
-- @see decode
|
||||
function world.encode_area(chunk_map, start_x, start_y, end_x, end_y, encoded_area)
|
||||
start_x = ffi.cast('int32_t', start_x)
|
||||
start_y = ffi.cast('int32_t', start_y)
|
||||
end_x = ffi.cast('int32_t', end_x)
|
||||
end_y = ffi.cast('int32_t', end_y)
|
||||
---@cast start_x integer
|
||||
---@cast start_y integer
|
||||
---@cast end_x integer
|
||||
---@cast end_x integer
|
||||
|
||||
encoded_area = encoded_area or world.EncodedArea()
|
||||
|
||||
|
@ -188,10 +166,10 @@ end
|
|||
--local PixelRun_const_ptr = ffi.typeof("struct PixelRun const*")
|
||||
|
||||
--- Load an encoded area back into the world.
|
||||
---@param grid_world unknown
|
||||
---@param header EncodedAreaHeader header of the encoded area
|
||||
---@param pixel_runs PixelRun[] or ffi array of PixelRun from the encoded area
|
||||
---@see encode_area
|
||||
-- @param grid_world
|
||||
-- @tparam EncodedAreaHeader header header of the encoded area
|
||||
-- @param received pointer or ffi array of PixelRun from the encoded area
|
||||
-- @see encode_area
|
||||
function world.decode(grid_world, header, pixel_runs)
|
||||
local chunk_map = grid_world.vtable.get_chunk_map(grid_world)
|
||||
|
||||
|
@ -214,10 +192,19 @@ function world.decode(grid_world, header, pixel_runs)
|
|||
while x < bottom_right_x do
|
||||
if world_ffi.chunk_loaded(chunk_map, x, y) then
|
||||
local ppixel = world_ffi.get_cell(chunk_map, x, y)
|
||||
|
||||
local current_material = 0
|
||||
|
||||
if new_material == -1 then
|
||||
goto next_pixel
|
||||
end
|
||||
|
||||
if ppixel[0] ~= nil then
|
||||
local pixel = ppixel[0]
|
||||
local cell_type = pixel.vtable.get_cell_type(pixel)
|
||||
if cell_type == C.CELL_TYPE_SOLID then
|
||||
goto next_pixel
|
||||
end
|
||||
current_material = world_ffi.get_material_id(pixel.vtable.get_material(pixel))
|
||||
|
||||
if new_material ~= current_material then
|
||||
|
@ -226,7 +213,22 @@ function world.decode(grid_world, header, pixel_runs)
|
|||
end
|
||||
|
||||
if current_material ~= new_material and new_material ~= 0 then
|
||||
local pixel = world_ffi.construct_cell(grid_world, x, y, world_ffi.get_material_ptr(new_material), nil)
|
||||
if new_material > world.last_material_id then
|
||||
goto next_pixel
|
||||
end
|
||||
local mat_ptr = world_ffi.get_material_ptr(new_material)
|
||||
if mat_ptr == nil then
|
||||
goto next_pixel
|
||||
end
|
||||
local pixel = world_ffi.construct_cell(grid_world, x, y, mat_ptr, nil)
|
||||
if pixel == nil then
|
||||
-- TODO: This can happen when the material texture has a
|
||||
-- transparent pixel at the given coordinate. There's
|
||||
-- probably a better way to deal with this, but for now
|
||||
-- we skip positions like this.
|
||||
goto next_pixel
|
||||
end
|
||||
|
||||
local cell_type = pixel.vtable.get_cell_type(pixel)
|
||||
|
||||
if cell_type == C.CELL_TYPE_LIQUID then
|
||||
|
@ -238,6 +240,8 @@ function world.decode(grid_world, header, pixel_runs)
|
|||
end
|
||||
end
|
||||
|
||||
::next_pixel::
|
||||
|
||||
left = left - 1
|
||||
if left <= 0 then
|
||||
current_run_ix = current_run_ix + 1
|
|
@ -1,5 +1,5 @@
|
|||
local world_ffi = require("noitapatcher.nsew.world_ffi")
|
||||
local world = require("noitapatcher.nsew.world")
|
||||
local world = dofile_once("mods/quant.ew/files/system/world_sync/world.lua")
|
||||
local rect = require("noitapatcher.nsew.rect")
|
||||
local ffi = require("ffi")
|
||||
|
|
@ -66,7 +66,7 @@ local function load_modules()
|
|||
ctx.dofile_and_add_hooks("mods/quant.ew/files/system/weather_sync.lua")
|
||||
ctx.load_system("polymorph")
|
||||
|
||||
ctx.dofile_and_add_hooks("mods/quant.ew/files/system/world_sync_v2.lua")
|
||||
ctx.load_system("world_sync")
|
||||
|
||||
ctx.load_system("spawn_hooks")
|
||||
ctx.dofile_and_add_hooks("mods/quant.ew/files/system/proxy_info.lua")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue