static void Sound_effect (LIScrArgs* args) { #ifndef LI_DISABLE_SOUND int tmp; int flags = 0; float pitch; float volume; const char* effect; LIEngObject* object; LIExtModule* module; LIMatVector velocity; LIScrData* data; LISndSource* source; if (liscr_args_gets_string (args, "effect", &effect) && liscr_args_gets_data (args, "object", LISCR_SCRIPT_OBJECT, &data)) { if (liscr_args_gets_bool (args, "positional", &tmp) && !tmp) flags |= LIEXT_SOUND_FLAG_NONPOSITIONAL; if (liscr_args_gets_bool (args, "repeating", &tmp) && tmp) flags |= LIEXT_SOUND_FLAG_REPEAT; object = liscr_data_get_data (data); module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_SOUND); source = liext_sound_set_effect (module, object->id, effect, flags); if (source != NULL) { if (liscr_args_gets_float (args, "pitch", &pitch)) lisnd_source_set_pitch (source, pitch); if (liscr_args_gets_float (args, "volume", &volume)) lisnd_source_set_volume (source, volume); if (liscr_args_gets_vector (args, "velocity", &velocity)) lisnd_source_set_velocity (source, &velocity); } } #endif }
static void Model_edit_material (LIScrArgs* args) { int i; int j; int n; float color[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; const char* str; const char* shader = NULL; const char* texture = NULL; LIEngModel* model; LIMdlMaterial* material; /* Get the engine model. */ model = args->self; liscr_args_gets_string (args, "match_shader", &shader); liscr_args_gets_string (args, "match_texture", &texture); /* Edit each matching material. */ for (i = 0 ; i < model->model->materials.count ; i++) { material = model->model->materials.array + i; if (!limdl_material_compare_shader_and_texture (material, shader, texture)) continue; if (liscr_args_gets_floatv (args, "diffuse", 4, color)) limdl_material_set_diffuse (material, color); if (liscr_args_gets_floatv (args, "specular", 4, color)) limdl_material_set_specular (material, color); if (liscr_args_gets_string (args, "shader", &str)) limdl_material_set_shader (material, str); if (liscr_args_gets_table (args, "textures")) { /* Count textures. */ for (n = 0 ; n < 4 ; n++) { lua_pushnumber (args->lua, n + 1); lua_gettable (args->lua, -2); j = lua_type (args->lua, -1); lua_pop (args->lua, 1); if (j != LUA_TSTRING) break; } /* Allocate textures. */ if (material->textures.count != n) { if (!limdl_material_realloc_textures (material, n)) { lua_pop (args->lua, 1); continue; } } /* Set textures. */ for (j = 0 ; j < n ; j++) { lua_pushnumber (args->lua, j + 1); lua_gettable (args->lua, -2); limdl_material_set_texture (material, j, LIMDL_TEXTURE_TYPE_IMAGE, LIMDL_TEXTURE_FLAG_BILINEAR | LIMDL_TEXTURE_FLAG_MIPMAP | LIMDL_TEXTURE_FLAG_REPEAT, lua_tostring (args->lua, -1)); lua_pop (args->lua, 1); } lua_pop (args->lua, 1); } } }
/** Script callback Los.heightmap_generate This function converts the image data to Voxels: <li>First image contains height information in color values</li> <li>Second image contains material information in color values</li> <li>Position is the lower inferior voxel of the mapped area</li> <li>Size is the volume of the mapped area. Base size must fit with image size</li> <li>Materials is an array of mat ID used to associate voxel types</li> \param LIScrArgs* args */ static void Heightmap_heightmap_generate (LIScrArgs* args) { LIExtModule* module; LIVoxManager* voxels; LIVoxVoxel* tmp; const char* map_file; const char* tiles_file; LIMatVector posv; LIMatVector sizev; int materials[MAX_TEXTURES]; void* map_data; void* tiles_data; int min[3]; int max[3]; int size[3]; int x,y,z, y2, i, value; printf("Starting heightmap generation\n"); module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_HEIGHTMAP); voxels = limai_program_find_component (module->program, "voxels"); if (voxels == NULL) return; if (!liscr_args_geti_string (args, 0, &map_file) && liscr_args_gets_string (args, "map", &map_file)) return; if (!liscr_args_geti_string (args, 1, &tiles_file)) liscr_args_gets_string (args, "tiles", &tiles_file); if (!liscr_args_geti_vector (args, 2, &posv)) liscr_args_gets_vector (args, "pos", &posv); if (!liscr_args_geti_vector (args, 3, &sizev)) liscr_args_gets_vector (args, "size", &sizev); if (!liscr_args_geti_intv (args, 4, MAX_TEXTURES, materials)) liscr_args_gets_intv (args, "materials", MAX_TEXTURES, materials); if (liext_heightmap_generate(module, map_file, &map_data) != 0) { return; } if (liext_heightmap_generate(module, tiles_file, &tiles_data) != 0) { liext_heightmap_cleanup(module, &map_data); return; } /* Calculate the size of the area. */ size[0] = sizev.x; size[1] = sizev.y; size[2] = sizev.z; min[0] = posv.x; min[1] = posv.y; min[2] = posv.z; max[0] = (int)posv.x + size[0]; max[1] = (int)posv.y + size[1]; max[2] = (int)posv.z + size[2]; printf("Coords: %d %d %d / %d %d %d / %d %d %d\n", min[0], min[1], min[2], max[0], max[1], max[2], size[0], size[1], size[2]); /* Batch copy terrain data. */ /* Reading all tiles at once is faster than operating on individual tiles since there are fewer sector lookups. */ tmp = lisys_calloc (size[0] * size[1] * size[2], sizeof (LIVoxVoxel)); if (tmp == NULL) { liext_heightmap_cleanup(module, &map_data); liext_heightmap_cleanup(module, &tiles_data); return; } livox_manager_copy_voxels (voxels, min[0], min[1], min[2], size[0], size[1], size[2], tmp); /* Apply heightmap to the copied tiles. */ i = 0; for (z = min[2] ; z < max[2] ; z++) for (y = min[1] ; y < max[1] ; y++) for (x = min[0] ; x < max[0] ; x++) { //TODO: better resolution y2 = 255 - liext_heightmap_find(module, x, z, map_data); printf("gen y: %d\n", y2); if (y2 != -1 && y <= y2) { value = liext_heightmap_find(module, x, z, tiles_data); if (value < 0 || value >= MAX_TEXTURES) { value = 0; } livox_voxel_init (tmp + i, 15 /* materials[value] */); printf("voxel: %d %d\n", i, value); } i++; } /* Batch write the copied tiles. */ livox_manager_paste_voxels (voxels, min[0], min[1], min[2], size[0], size[1], size[2], tmp); lisys_free (tmp); printf("Area has been successfully loaded from heightmap\n"); liext_heightmap_cleanup(module, &map_data); liext_heightmap_cleanup(module, &tiles_data); }
static void Lobby_download_server_list (LIScrArgs* args) { #ifdef HAVE_CURL int ret; int port = 0; int players = 0; char* url; char* desc; char* ip; char* name; const char* master; char error_buffer[CURL_ERROR_SIZE]; LIArcReader* reader; LIArcWriter* writer; CURL* curl; /* Get arguments. */ if (!liscr_args_gets_string (args, "master", &master)) return; liscr_args_set_output (args, LISCR_ARGS_OUTPUT_TABLE_FORCE); /* Format the script URL. */ url = lisys_string_concat (master, "/lossrvapi.php"); if (url == NULL) return; /* GET from the master server. */ curl = curl_easy_init(); if (curl != NULL) { writer = liarc_writer_new (); curl_easy_setopt (curl, CURLOPT_URL, url); curl_easy_setopt (curl, CURLOPT_WRITEDATA, writer); curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, private_write); curl_easy_setopt (curl, CURLOPT_ERRORBUFFER, error_buffer); if (curl_easy_perform (curl)) { lisys_error_set (EINVAL, "lobby: %s", error_buffer); lisys_error_report (); curl_easy_cleanup (curl); liarc_writer_free (writer); lisys_free (url); return; } curl_easy_cleanup (curl); liarc_writer_append_nul (writer); reader = liarc_reader_new ( liarc_writer_get_buffer (writer), liarc_writer_get_length (writer)); while (!liarc_reader_check_end (reader)) { ip = NULL; name = NULL; desc = NULL; ret = liarc_reader_get_text (reader, "\t", &ip) && liarc_reader_get_text_int (reader, &port) && liarc_reader_skip_bytes (reader, 1) && liarc_reader_get_text_int (reader, &players) && liarc_reader_skip_bytes (reader, 1) && liarc_reader_get_text (reader, "\t", &name) && liarc_reader_get_text (reader, "\n", &desc); if (ret) { lua_newtable (args->lua); lua_pushstring (args->lua, ip); lua_setfield (args->lua, -2, "ip"); lua_pushnumber (args->lua, port); lua_setfield (args->lua, -2, "port"); lua_pushnumber (args->lua, players); lua_setfield (args->lua, -2, "players"); lua_pushstring (args->lua, name); lua_setfield (args->lua, -2, "name"); lua_pushstring (args->lua, desc); lua_setfield (args->lua, -2, "desc"); liscr_args_seti_stack (args); } lisys_free (ip); lisys_free (name); lisys_free (desc); if (!ret) break; } liarc_reader_free (reader); liarc_writer_free (writer); } lisys_free (url); #endif }
static void Database_new (LIScrArgs* args) { int ok; char* path; char* path1; const char* ptr; const char* name; sqlite3* sql; LIExtModule* module; LIScrData* data; module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_DATABASE); /* Get and validate the filename. */ if (!liscr_args_geti_string (args, 0, &name) && !liscr_args_gets_string (args, "name", &name)) return; for (ptr = name ; *ptr != '\0' ; ptr++) { if (*ptr >= 'a' && *ptr <= 'z') ok = 1; else if (*ptr >= 'A' && *ptr <= 'Z') ok = 1; else if (*ptr >= '0' && *ptr <= '9') ok = 1; else if (*ptr == '-') ok = 1; else if (*ptr == '_') ok = 1; else if (*ptr == '.') ok = 1; else ok = 0; if (!ok) { lisys_error_set (EINVAL, "invalid database name `%s'", name); lisys_error_report (); return; } } /* Format the path. */ ptr = lipth_paths_create_file (module->program->paths, name, 0); if (ptr == NULL) { lisys_error_report (); return; } path = lisys_string_dup (ptr); if (path == NULL) return; /* Convert the path to UTF-8. */ /* Unlike other file functions we use, SQLite requires the filename to be in UTF-8 instead of the system locale. */ path1 = lisys_string_convert_sys_to_utf8 (path); if (path1 != NULL) { lisys_free (path); path = path1; } /* Open database. */ if (sqlite3_open_v2 (path, &sql, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL) != SQLITE_OK) { lisys_error_set (EINVAL, "sqlite: %s", sqlite3_errmsg (sql)); lisys_error_report (); lisys_free (path); lisys_free (sql); return; } lisys_free (path); /* Allocate userdata. */ data = liscr_data_new (args->script, args->lua, sql, LIEXT_SCRIPT_DATABASE, private_free_database); if (data == NULL) { sqlite3_close (sql); return; } liscr_args_seti_stack (args); }
static void Database_query (LIScrArgs* args) { int i; int col; int row; int ret; int size; const char* query; const char* str; sqlite3* self; LIArcPacket* packet; LIScrData* data; sqlite3_stmt* statement; self = args->self; if (!liscr_args_geti_string (args, 0, &query) && !liscr_args_gets_string (args, "query", &query)) return; /* Create a statement. */ if (sqlite3_prepare_v2 (self, query, -1, &statement, NULL) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL prepare: %s", sqlite3_errmsg (self)); lisys_error_report (); return; } /* Bind variables. */ if (liscr_args_geti_table (args, 1) || liscr_args_gets_table (args, "bind")) { for (i = 1 ; i < sqlite3_bind_parameter_count (statement) + 1 ; i++) { /* We got a table that has the bound variables in fields matching the indices of the bound variables. We can simply loop through the table and use the binding index as the key. */ lua_pushnumber (args->lua, i); lua_gettable (args->lua, -2); switch (lua_type (args->lua, -1)) { /* Bind numbers as doubles. */ case LUA_TNUMBER: if (sqlite3_bind_double (statement, i, lua_tonumber (args->lua, -1)) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } break; /* Bind strings as text. */ case LUA_TSTRING: if (sqlite3_bind_text (statement, i, lua_tostring (args->lua, -1), -1, SQLITE_TRANSIENT) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } break; /* Bind packets as blobs. */ case LUA_TUSERDATA: data = liscr_isdata (args->lua, -1, LISCR_SCRIPT_PACKET); if (data == NULL) break; packet = liscr_data_get_data (data); if (packet->writer != NULL) { if (sqlite3_bind_blob (statement, i, packet->writer->memory.buffer, packet->writer->memory.length, SQLITE_TRANSIENT) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } } else { if (sqlite3_bind_blob (statement, i, packet->reader->buffer, packet->reader->length, SQLITE_TRANSIENT) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } } break; /* Bind any other values as NULL. */ default: if (sqlite3_bind_null (statement, i) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } break; } lua_pop (args->lua, 1); } lua_pop (args->lua, 1); } /* Execute the statement and process results. */ for (row = 0, ret = sqlite3_step (statement) ; ret != SQLITE_DONE ; ret = sqlite3_step (statement), row++) { /* Check for errors. */ if (ret != SQLITE_ROW) { lisys_error_set (EINVAL, "SQL step: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } if (!row) liscr_args_set_output (args, LISCR_ARGS_OUTPUT_TABLE_FORCE); /* Create a row table. */ lua_newtable (args->lua); /* Push the columns to the table. */ for (col = 0 ; col < sqlite3_column_count (statement) ; col++) { switch (sqlite3_column_type (statement, col)) { case SQLITE_INTEGER: lua_pushnumber (args->lua, col + 1); lua_pushnumber (args->lua, sqlite3_column_int (statement, col)); lua_settable (args->lua, -3); break; case SQLITE_FLOAT: lua_pushnumber (args->lua, col + 1); lua_pushnumber (args->lua, sqlite3_column_double (statement, col)); lua_settable (args->lua, -3); break; case SQLITE_TEXT: str = (const char*) sqlite3_column_text (statement, col); size = sqlite3_column_bytes (statement, col); lua_pushnumber (args->lua, col + 1); if (size > 0 && str != NULL) lua_pushstring (args->lua, str); else lua_pushstring (args->lua, str); lua_settable (args->lua, -3); break; case SQLITE_BLOB: str = sqlite3_column_blob (statement, col); size = sqlite3_column_bytes (statement, col); packet = liarc_packet_new_readable (str, size); if (packet != NULL) { lua_pushnumber (args->lua, col + 1); data = liscr_data_new (args->script, args->lua, packet, LISCR_SCRIPT_PACKET, liarc_packet_free); if (data != NULL) lua_settable (args->lua, -3); else { lua_pop (args->lua, 1); liarc_packet_free (packet); } } break; case SQLITE_NULL: break; default: lisys_assert (0 && "invalid column type"); break; } } /* Add the row to the return values. */ liscr_args_seti_stack (args); } if (!row) liscr_args_set_output (args, LISCR_ARGS_OUTPUT_TABLE_FORCE); sqlite3_finalize (statement); }