static void Terrain_set_material_textures (LIScrArgs* args) { int index; int top; int bottom; int side; int decor; LIExtTerrain* self; LIExtTerrainMaterial* material; /* Get the arguments. */ self = args->self; if (!liscr_args_geti_int (args, 0, &index) || index <= 0 || index >= LIEXT_TERRAIN_MATERIAL_MAX) return; if (!liscr_args_geti_int (args, 1, &top)) top = index - 1; if (!liscr_args_geti_int (args, 2, &bottom)) bottom = index - 1; if (!liscr_args_geti_int (args, 3, &side)) side = index - 1; if (!liscr_args_geti_int (args, 4, &decor)) decor = index - 1; /* Set the textures. */ material = self->materials + index; material->texture_top = top; material->texture_bottom = bottom; material->texture_side = side; material->texture_decoration = decor; }
static void Terrain_add_stick_corners (LIScrArgs* args) { int grid_x; int grid_z; float bot[4]; float top[4]; int material; /* Get the arguments. */ if (!liscr_args_geti_int (args, 0, &grid_x) || grid_x < 0) return; if (!liscr_args_geti_int (args, 1, &grid_z) || grid_z < 0) return; if (!liscr_args_geti_float (args, 2, bot + 0) || bot[0] < 0.0f) return; if (!liscr_args_geti_float (args, 3, bot + 1) || bot[1] < 0.0f) return; if (!liscr_args_geti_float (args, 4, bot + 2) || bot[2] < 0.0f) return; if (!liscr_args_geti_float (args, 5, bot + 3) || bot[3] < 0.0f) return; if (!liscr_args_geti_float (args, 6, top + 0) || top[0] < 0.0f) return; if (!liscr_args_geti_float (args, 7, top + 1) || top[1] < 0.0f) return; if (!liscr_args_geti_float (args, 8, top + 2) || top[2] < 0.0f) return; if (!liscr_args_geti_float (args, 9, top + 3) || top[3] < 0.0f) return; if (!liscr_args_geti_int (args, 10, &material) || material < 0) return; liscr_args_seti_bool (args, liext_terrain_add_stick_corners (args->self, grid_x, grid_z, bot[0], bot[1], bot[2], bot[3], top[0], top[1], top[2], top[3], material, NULL, NULL)); }
static void Terrain_add_stick_filter_mask (LIScrArgs* args) { int grid_x; int grid_z; float world_y; float world_h; int material; int mask; /* Get the arguments. */ if (!liscr_args_geti_int (args, 0, &grid_x) || grid_x < 0) return; if (!liscr_args_geti_int (args, 1, &grid_z) || grid_z < 0) return; if (!liscr_args_geti_float (args, 2, &world_y) || world_y < 0.0f) return; if (!liscr_args_geti_float (args, 3, &world_h)) return; world_h = LIMAT_MAX (world_h, LIEXT_STICK_EPSILON); if (!liscr_args_geti_int (args, 4, &material) || material < 0) return; if (!liscr_args_geti_int (args, 5, &mask) || mask < 0) return; liscr_args_seti_bool (args, liext_terrain_add_stick (args->self, grid_x, grid_z, world_y, world_h, material, liext_terrain_stick_filter_mask, &mask)); }
static void Terrain_add_box (LIScrArgs* args) { int grid_x1; int grid_z1; int grid_x2; int grid_z2; float world_y; float world_h; int material; /* Get the arguments. */ if (!liscr_args_geti_int (args, 0, &grid_x1) || grid_x1 < 0) return; if (!liscr_args_geti_int (args, 1, &grid_z1) || grid_z1 < 0) return; if (!liscr_args_geti_int (args, 2, &grid_x2) || grid_x2 < grid_x1) return; if (!liscr_args_geti_int (args, 3, &grid_z2) || grid_z2 < grid_z1) return; if (!liscr_args_geti_float (args, 4, &world_y) || world_y < 0.0f) return; if (!liscr_args_geti_float (args, 5, &world_h)) return; world_h = LIMAT_MAX (world_h, LIEXT_STICK_EPSILON); if (!liscr_args_geti_int (args, 6, &material) || material < 0) return; liscr_args_seti_int (args, liext_terrain_add_box (args->self, grid_x1, grid_z1, grid_x2, grid_z2, world_y, world_h, material, NULL, NULL)); }
static void Widget_set_request (LIScrArgs* args) { int internal = 0; int paddings[4]; const char* text; const char* font_name; LIMatVector vector; LIWdgSize size = { -1, -1 }; LIWdgSize size_tmp; LIWdgWidget* widget; widget = args->self; liscr_args_gets_bool (args, "internal", &internal); if (liscr_args_geti_vector (args, 0, &vector)) { size.width = (int) vector.x; size.height = (int) vector.y; } else { if (!liscr_args_geti_int (args, 0, &size.width)) liscr_args_gets_int (args, "width", &size.width); if (!liscr_args_geti_int (args, 1, &size.width)) liscr_args_gets_int (args, "height", &size.height); } /* Calculate from text if given. */ if (liscr_args_gets_string (args, "font", &font_name) && liscr_args_gets_string (args, "text", &text)) { if (liren_render_measure_text (widget->manager->render, font_name, text, size.width, &size_tmp.width, &size_tmp.height)) { if (size.width == -1) size.width = size_tmp.width; if (size.height == -1) size.height = size_tmp.height; } } /* Add paddings if given. */ if (liscr_args_gets_intv (args, "paddings", 4, paddings) == 4) { size.width += paddings[1] + paddings[2]; size.height += paddings[0] + paddings[3]; } /* Set the request. */ if (internal) liwdg_widget_set_request (args->self, 1, size.width, size.height); else liwdg_widget_set_request (args->self, 2, size.width, size.height); }
static void Terrain_calculate_smooth_normals (LIScrArgs* args) { int grid_x; int grid_z; /* Get the arguments. */ if (!liscr_args_geti_int (args, 0, &grid_x) || grid_x < 0) return; if (!liscr_args_geti_int (args, 1, &grid_z) || grid_z < 0) return; liscr_args_seti_bool (args, liext_terrain_calculate_smooth_normals (args->self, grid_x, grid_z)); }
static void Camera_set_viewport (LIScrArgs* args) { int viewport[4]; LIExtCamera* camera; camera = args->self; memcpy (viewport, camera->view.viewport, 4 * sizeof (int)); liscr_args_geti_int (args, 0, viewport + 0); liscr_args_geti_int (args, 1, viewport + 1); liscr_args_geti_int (args, 2, viewport + 2); liscr_args_geti_int (args, 3, viewport + 3); liext_camera_set_viewport (camera, viewport[0], viewport[1], viewport[2], viewport[3]); }
static void Terrain_unload_chunk (LIScrArgs* args) { int grid_x; int grid_z; /* Get the arguments. */ if (!liscr_args_geti_int (args, 0, &grid_x) || grid_x < 0) return; if (!liscr_args_geti_int (args, 1, &grid_z) || grid_z < 0) return; liscr_args_seti_bool (args, liext_terrain_unload_chunk (args->self, grid_x, grid_z)); }
static void Terrain_new (LIScrArgs* args) { int chunk_size; float grid_size; LIExtTerrain* self; LIExtTerrainModule* module; LIScrData* data; /* Get the arguments. */ if (!liscr_args_geti_int (args, 0, &chunk_size) || chunk_size < 1) return; if (!liscr_args_geti_float (args, 1, &grid_size) || grid_size <= 0.0f) return; module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_TERRAIN); /* Allocate the object. */ self = liext_terrain_new (module, chunk_size, grid_size); if (self == NULL) return; /* Allocate the userdata. */ data = liscr_data_new (args->script, args->lua, self, LIEXT_SCRIPT_TERRAIN, liext_terrain_free); if (data == NULL) { liext_terrain_free (self); return; } liscr_args_seti_stack (args); }
static void Widget_set_depth (LIScrArgs* args) { int value; if (liscr_args_geti_int (args, 0, &value)) liwdg_widget_set_depth (args->self, value); }
static void Heightmap_new (LIScrArgs* args) { int i; int size; float spacing; float scaling; LIExtHeightmap* heightmap; LIExtHeightmapModule* module; LIImgImage* image; LIMatVector position; LIScrData* data; /* Get arguments. */ module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_HEIGHTMAP); if (!liscr_args_geti_vector (args, 0, &position)) position = limat_vector_init (0.0f, 0.0f, 0.0f); if (!liscr_args_geti_int (args, 1, &size)) size = 33; else if (size < 0) size = 0; if (!liscr_args_geti_float (args, 2, &spacing)) spacing = 1.0f; else if (spacing <= 0.0f) spacing = 1.0f; if (!liscr_args_geti_float (args, 3, &scaling)) scaling = 1.0f; else if (scaling <= 0.0f) scaling = 1.0f; if (liscr_args_geti_data (args, 4, LIEXT_SCRIPT_IMAGE, &data)) image = liscr_data_get_data (data); else image = NULL; /* Ensure that the size is valid. */ for (i = 32 ; i < 65536 ; i *= 2) { if (size == i + 1) break; } if (size != i + 1) { lisys_error_set (EINVAL, "invalid heightmap size"); lisys_error_report (); return; } /* Allocate the heightmap. */ heightmap = liext_heightmap_new (module, image, &position, size, spacing, scaling); if (heightmap == NULL) return; /* Allocate the userdata. */ data = liscr_data_new (args->script, args->lua, heightmap, LIEXT_SCRIPT_HEIGHTMAP, liext_heightmap_free); if (data == NULL) { liext_heightmap_free (heightmap); return; } liscr_args_seti_stack (args); }
static void Terrain_get_column (LIScrArgs* args) { int i; int vtx_x; int vtx_z; int grid_x; int grid_z; LIExtTerrainColumn* column; LIExtTerrainStick* stick; /* Get the arguments. */ if (!liscr_args_geti_int (args, 0, &grid_x) || grid_x < 0) return; if (!liscr_args_geti_int (args, 1, &grid_z) || grid_z < 0) return; /* Get the column. */ column = liext_terrain_get_column (args->self, grid_x, grid_z); if (column == NULL) return; /* Pack the sticks into a table. */ liscr_args_set_output (args, LISCR_ARGS_OUTPUT_TABLE_FORCE); for (stick = column->sticks ; stick != NULL ; stick = stick->next) { i = 0; lua_newtable (args->lua); #define PUSHNUM(v) lua_pushnumber (args->lua, ++i);\ lua_pushnumber (args->lua, v);\ lua_settable (args->lua, -3); PUSHNUM (stick->material); PUSHNUM (stick->height); for (vtx_z = 0 ; vtx_z < 2 ; vtx_z++) { for (vtx_x = 0 ; vtx_x < 2 ; vtx_x++) { PUSHNUM (stick->vertices[vtx_x][vtx_z].offset); PUSHNUM (stick->vertices[vtx_x][vtx_z].splatting); PUSHNUM (stick->vertices[vtx_x][vtx_z].normal.x); PUSHNUM (stick->vertices[vtx_x][vtx_z].normal.y); PUSHNUM (stick->vertices[vtx_x][vtx_z].normal.z); } } #undef PUSHNUM liscr_args_seti_stack (args); } }
static void Terrain_build_chunk_model (LIScrArgs* args) { int grid_x; int grid_z; LIExtTerrain* self; LIExtTerrainModule* module; LIMatVector offset; LIMdlModel* model; LIScrData* data; /* Get the arguments. */ self = args->self; module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_TERRAIN); if (!liscr_args_geti_int (args, 0, &grid_x) || grid_x < 0) return; if (!liscr_args_geti_int (args, 1, &grid_z) || grid_z < 0) return; if (!liscr_args_geti_vector (args, 2, &offset)) offset = limat_vector_init (grid_x * self->grid_size, 0.0f, grid_z * self->grid_size); /* Build the model. */ model = liext_terrain_build_chunk_model (self, grid_x, grid_z, &offset); if (model == NULL) return; /* Copy the model. */ model = limdl_model_new_copy (model, 0); if (model == NULL) return; /* Allocate the unique ID. */ if (!limdl_manager_add_model (module->program->models, model)) { limdl_model_free (model); return; } /* Allocate the userdata. */ data = liscr_data_new (args->script, args->lua, model, LISCR_SCRIPT_MODEL, limdl_manager_free_model); if (data == NULL) { limdl_model_free (model); return; } liscr_args_seti_stack (args); }
static void Widget_set_y (LIScrArgs* args) { LIWdgRect rect; liwdg_widget_get_allocation (args->self, &rect); liscr_args_geti_int (args, 0, &rect.y); liwdg_widget_set_allocation (args->self, rect.x, rect.y, rect.width, rect.height); }
static void Camera_set_collision_mask (LIScrArgs* args) { int value; LIExtCamera* camera; camera = args->self; if (liscr_args_geti_int (args, 0, &value)) camera->config.collision_mask = value; }
static void Terrain_set_material_stick_type (LIScrArgs* args) { int index; int type; LIExtTerrain* self; LIExtTerrainMaterial* material; /* Get the arguments. */ self = args->self; if (!liscr_args_geti_int (args, 0, &index) || index <= 0 || index >= LIEXT_TERRAIN_MATERIAL_MAX) return; if (!liscr_args_geti_int (args, 1, &type) || type <= 0 || type >= LIEXT_TERRAIN_STICK_TYPE_MAX) return; /* Set the type. */ material = self->materials + index; material->stick_type = type; }
static void Terrain_get_nearest_chunk_with_outdated_model (LIScrArgs* args) { int grid_x; int grid_z; int result_x; int result_z; /* Get the arguments. */ if (!liscr_args_geti_int (args, 0, &grid_x)) return; if (!liscr_args_geti_int (args, 1, &grid_z)) return; /* Find the chunk. */ if (!liext_terrain_get_nearest_chunk_with_outdated_model (args->self, grid_x, grid_z, &result_x, &result_z)) return; liscr_args_seti_int (args, result_x); liscr_args_seti_int (args, result_z); }
static void Terrain_smoothen_column (LIScrArgs* args) { int grid_x; int grid_z; float y; float h; /* Get the arguments. */ if (!liscr_args_geti_int (args, 0, &grid_x) || grid_x < 0) return; if (!liscr_args_geti_int (args, 1, &grid_z) || grid_z < 0) return; if (!liscr_args_geti_float (args, 2, &y)) return; if (!liscr_args_geti_float (args, 3, &h) || h <= 0.0f) return; liscr_args_seti_bool (args, liext_terrain_smoothen_column (args->self, grid_x, grid_z, y, h)); }
static void Terrain_get_chunk_time_stamp (LIScrArgs* args) { int grid_x; int grid_z; LIExtTerrainChunk* chunk; /* Get the arguments. */ if (!liscr_args_geti_int (args, 0, &grid_x) || grid_x < 0) return; if (!liscr_args_geti_int (args, 1, &grid_z) || grid_z < 0) return; /* Get the chunk. */ chunk = liext_terrain_get_chunk (args->self, grid_x, grid_z); if (chunk == NULL) return; /* Return the time stamp. */ liscr_args_seti_int (args, chunk->stamp); }
static void Terrain_get_stick (LIScrArgs* args) { int grid_x; int grid_z; float y; float ref_y; LIExtTerrainColumn* column; LIExtTerrainStick* stick; /* Get the arguments. */ if (!liscr_args_geti_int (args, 0, &grid_x) || grid_x < 0) return; if (!liscr_args_geti_int (args, 1, &grid_z) || grid_z < 0) return; if (!liscr_args_geti_float (args, 2, &ref_y)) return; /* Get the column. */ column = liext_terrain_get_column (args->self, grid_x, grid_z); if (column == NULL) return; /* Find the stick. */ y = 0.0f; for (stick = column->sticks ; stick != NULL ; stick = stick->next) { if (ref_y < y + stick->height) { liscr_args_seti_float (args, y); liscr_args_seti_float (args, stick->height); liscr_args_seti_int (args, stick->material); return; } y += stick->height; } /* Return the infinite end stick. */ liscr_args_seti_float (args, y); liscr_args_seti_float (args, 1000000.0f); liscr_args_seti_int (args, 0); }
static void ImageMerger_blit_rect (LIScrArgs* args) { LIImgAsyncMerger* self; LIImgImage* image; LIScrData* data; LIMatRectInt dst_rect; LIMatRectInt src_rect; /* Get arguments. */ self = args->self; if (!liscr_args_geti_data (args, 0, LIEXT_SCRIPT_IMAGE, &data)) return; image = liscr_data_get_data (data); if (!liscr_args_geti_int (args, 1, &dst_rect.x)) return; if (!liscr_args_geti_int (args, 2, &dst_rect.y)) return; if (!liscr_args_geti_int (args, 3, &dst_rect.width)) return; if (!liscr_args_geti_int (args, 4, &dst_rect.height)) return; if (!liscr_args_geti_int (args, 5, &src_rect.x)) return; if (!liscr_args_geti_int (args, 6, &src_rect.y)) return; src_rect.width = dst_rect.width; src_rect.height = dst_rect.height; /* Add the task. */ liimg_async_merger_blit (self, image, &dst_rect, &src_rect); }
static void Terrain_clear_chunk_model (LIScrArgs* args) { int grid_x; int grid_z; LIExtTerrain* self; LIExtTerrainChunk* chunk; /* Get the arguments. */ self = args->self; if (!liscr_args_geti_int (args, 0, &grid_x) || grid_x < 0) return; if (!liscr_args_geti_int (args, 1, &grid_z) || grid_z < 0) return; /* Reset the stamp. */ chunk = liext_terrain_get_chunk (self, grid_x, grid_z); if (chunk == NULL) return; liext_terrain_chunk_clear_model (chunk); liscr_args_seti_bool (args, 1); }
static void Terrain_set_chunk_data (LIScrArgs* args) { int grid_x; int grid_z; LIArcPacket* packet; LIScrData* data; /* Get the arguments. */ if (!liscr_args_geti_int (args, 0, &grid_x) || grid_x < 0) return; if (!liscr_args_geti_int (args, 1, &grid_z) || grid_z < 0) return; /* Get the packet reader. */ if (!liscr_args_geti_data (args, 2, LISCR_SCRIPT_PACKET, &data)) return; packet = liscr_data_get_data (data); /* Read the data. */ if (packet->reader != NULL) liscr_args_seti_bool (args, liext_terrain_set_chunk_data (args->self, grid_x, grid_z, packet->reader)); }
static void Terrain_find_nearest_empty_stick (LIScrArgs* args) { int grid_x; int grid_z; float y; float min_height; /* Get the arguments. */ if (!liscr_args_geti_int (args, 0, &grid_x) || grid_x < 0 || !liscr_args_geti_int (args, 1, &grid_z) || grid_z < 0) { liscr_args_seti_float (args, 1000000000.0f); return; } if (!liscr_args_geti_float (args, 2, &y)) return; if (!liscr_args_geti_float (args, 3, &min_height)) min_height = 0.0f; /* Find the stick. */ y = liext_terrain_find_nearest_empty_stick (args->self, grid_x, grid_z, y, min_height); liscr_args_seti_float (args, y); }
static void Camera_calculate_3rd_person_clipped_distance (LIScrArgs* args) { int group = 0xFFFF; int mask = 0xFFFF; float distance; float radius; float result; LIMatTransform center; if (!liscr_args_geti_vector (args, 0, ¢er.position)) return; if (!liscr_args_geti_quaternion (args, 1, ¢er.rotation)) return; if (!liscr_args_geti_float (args, 2, &distance)) return; if (!liscr_args_geti_float (args, 3, &radius)) radius = 0.0f; liscr_args_geti_int (args, 4, &group); liscr_args_geti_int (args, 5, &mask); result = liext_camera_calculate_3rd_person_clipped_distance ( args->self, ¢er, distance, radius, group, mask); liscr_args_seti_float (args, result); }
static void FirFilter_new (LIScrArgs* args) { int i; int length; float* coeffs; LIExtFirFilter* fir; LIScrData* data; /* Get the number of coefficients. */ if (!liscr_args_geti_int (args, 0, &length)) return; if (length <= 0) return; /* Allocate the coefficients. */ coeffs = lisys_calloc (length, sizeof (float)); if (!coeffs) return; /* Read the coefficients. */ if (liscr_args_geti_table (args, 1)) { for (i = 0 ; i < length ; i++) { lua_pushnumber (args->lua, i + 1); lua_gettable (args->lua, -2); if (lua_type (args->lua, -1) == LUA_TNUMBER) coeffs[i] = lua_tonumber (args->lua, -1); lua_pop (args->lua, 1); } lua_pop (args->lua, 1); } /* Create the filter. */ fir = liext_fir_filter_new (length, coeffs); lisys_free (coeffs); if (fir == NULL) return; /* Allocate userdata. */ data = liscr_data_new (args->script, args->lua, fir, LIEXT_SCRIPT_FIR_FILTER, liext_fir_filter_free); if (data == NULL) { liext_fir_filter_free (fir); return; } liscr_args_seti_stack (args); }
static void Model_calculate_lod (LIScrArgs* args) { int levels = 5; float factor = 0.3f; LIEngModel* model; LIMdlBuilder* builder; model = args->self; if (liscr_args_geti_int (args, 0, &levels)) levels = LIMAT_MAX (1, levels); if (liscr_args_geti_float (args, 1, &factor)) factor = LIMAT_CLAMP (factor, 0.0f, 1.0f); builder = limdl_builder_new (model->model); if (builder == NULL) return; limdl_builder_calculate_lod (builder, levels, factor); limdl_builder_finish (builder); limdl_builder_free (builder); liscr_args_seti_bool (args, 1); }
static void Widgets_add_font_style (LIScrArgs* args) { int size = 16; const char* file; const char* name; LIExtModule* module; /* Arguments. */ if (!liscr_args_geti_string (args, 0, &name) && !liscr_args_gets_string (args, "name", &name)) return; if (!liscr_args_geti_string (args, 1, &file) && !liscr_args_gets_string (args, "file", &file)) return; if (!liscr_args_geti_int (args, 2, &size)) liscr_args_gets_int (args, "size", &size); /* Load the font. */ module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_WIDGETS); if (!liwdg_styles_load_font (module->widgets->styles, name, file, size)) lisys_error_report (); }
static void ImageMerger_blit_rect_hsv_add_weightv (LIScrArgs* args) { float val_range; LIImgAsyncMerger* self; LIImgColorHSV hsv; LIImgImage* image; LIScrData* data; LIMatRectInt dst_rect; LIMatRectInt src_rect; /* Get arguments. */ self = args->self; if (!liscr_args_geti_data (args, 0, LIEXT_SCRIPT_IMAGE, &data)) return; if (!liscr_args_geti_int (args, 1, &dst_rect.x)) return; if (!liscr_args_geti_int (args, 2, &dst_rect.y)) return; if (!liscr_args_geti_int (args, 3, &dst_rect.width)) return; if (!liscr_args_geti_int (args, 4, &dst_rect.height)) return; if (!liscr_args_geti_int (args, 5, &src_rect.x)) return; if (!liscr_args_geti_int (args, 6, &src_rect.y)) return; src_rect.width = dst_rect.width; src_rect.height = dst_rect.height; if (!liscr_args_geti_float (args, 7, &hsv.h)) hsv.h = 0.0f; if (!liscr_args_geti_float (args, 8, &hsv.s)) hsv.s = 0.0f; if (!liscr_args_geti_float (args, 9, &hsv.v)) hsv.v = 0.0f; if (!liscr_args_geti_float (args, 10, &val_range)) val_range = 0.2f; image = liscr_data_get_data (data); /* Add the task. */ liimg_async_merger_blit_hsv_add_weightv (self, image, &dst_rect, &src_rect, &hsv, val_range); }
static void Terrain_set_column (LIScrArgs* args) { float y; float height; float slope[4]; float slope_prev[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; int i; int j; int grid_x; int grid_z; int material; LIExtTerrainColumn* column; /* Get the arguments. */ if (!liscr_args_geti_int (args, 0, &grid_x) || grid_x < 0) return; if (!liscr_args_geti_int (args, 1, &grid_z) || grid_z < 0) return; if (!liscr_args_geti_table (args, 2)) return; /* Get the column. */ column = liext_terrain_get_column (args->self, grid_x, grid_z); if (column == NULL) return; /* Unpack the sticks from the table. */ for (y = 0.0f, i = 0 ; 1 ; i++) { /* Get the next stick table. */ lua_pushnumber (args->lua, i + 1); lua_gettable (args->lua, -2); if (lua_type (args->lua, -1) != LUA_TTABLE) break; /* Get the height. */ lua_pushnumber (args->lua, 1); lua_gettable (args->lua, -2); if (lua_type (args->lua, -1) != LUA_TNUMBER) { lua_pop (args->lua, 2); continue; } height = lua_tonumber (args->lua, -1); if (height <= LIEXT_STICK_EPSILON) { lua_pop (args->lua, 2); continue; } lua_pop (args->lua, 1); /* Get the material. */ lua_pushnumber (args->lua, 2); lua_gettable (args->lua, -2); if (lua_type (args->lua, -1) != LUA_TNUMBER) { lua_pop (args->lua, 2); continue; } material = lua_tointeger (args->lua, -1); if (material < 0) { lua_pop (args->lua, 2); continue; } lua_pop (args->lua, 1); /* Get the slope. */ for (j = 0 ; j < 4 ; j++) { slope[j] = 0.0f; lua_pushnumber (args->lua, 2 + j); lua_gettable (args->lua, -2); if (lua_type (args->lua, -1) != LUA_TNUMBER) { lua_pop (args->lua, 1); continue; } slope[j] = lua_tonumber (args->lua, -1); lua_pop (args->lua, 1); } lua_pop (args->lua, 1); /* Add the stick. */ liext_terrain_column_add_stick (column, y, height, slope_prev, slope, material, NULL, NULL); y += height; memcpy (slope_prev, slope, 4 * sizeof (float)); } liscr_args_seti_bool (args, 1); }