From e9513374889ceefcfa366999625fa4aefef13310 Mon Sep 17 00:00:00 2001 From: AurZum Date: Wed, 30 Dec 2015 22:23:27 +0300 Subject: [PATCH] Ver 1.0 --- amxmodx/configs/spawn_models.ini | 0 amxmodx/plugins/amx_model_spawner_menu.amxx | Bin 0 -> 3980 bytes amxmodx/scripting/amx_model_spawner_menu.sma | 240 +++++++++ amxmodx/scripting/include/cellarray.inc | 525 +++++++++++++++++++ 4 files changed, 765 insertions(+) create mode 100644 amxmodx/configs/spawn_models.ini create mode 100644 amxmodx/plugins/amx_model_spawner_menu.amxx create mode 100644 amxmodx/scripting/amx_model_spawner_menu.sma create mode 100644 amxmodx/scripting/include/cellarray.inc diff --git a/amxmodx/configs/spawn_models.ini b/amxmodx/configs/spawn_models.ini new file mode 100644 index 0000000..e69de29 diff --git a/amxmodx/plugins/amx_model_spawner_menu.amxx b/amxmodx/plugins/amx_model_spawner_menu.amxx new file mode 100644 index 0000000000000000000000000000000000000000..e6cb10b713c38496fc24e9fffe8b046956d62f8b GIT binary patch literal 3980 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 literal 0 HcmV?d00001 diff --git a/amxmodx/scripting/amx_model_spawner_menu.sma b/amxmodx/scripting/amx_model_spawner_menu.sma new file mode 100644 index 0000000..f2b2185 --- /dev/null +++ b/amxmodx/scripting/amx_model_spawner_menu.sma @@ -0,0 +1,240 @@ +#include < amxmodx > +#include < amxmisc > +#include < engine > +#include < cellarray > + +#define PLUGIN "AMX Model Spawner Menu" +#define VERSION "1.0" +#define AUTHOR "AurZum" + +new const NAME_CONFIG_FILE[] = "%s/spawn_models.ini"; +new const CLASS_NAME[] = "env_tree"; +new const NAME_FOLD_MAP_MODELS[] = "%s/map_spawn_models"; + +new Array:model_list; +new g_szConfigFile[ 128 ]; + +public plugin_init( ) { + register_plugin(PLUGIN, VERSION, AUTHOR); + register_clcmd("amx_model_spawner_menu", "show_model_spawner_menu", ADMIN_LEVEL_E, ""); +} + +public show_model_spawner_menu(id) { + new menu = menu_create("AMX Model Spawner Menu", "menuHandel_model_spawner_menu"); + + menu_additem(menu, "Add model", "", 0); + menu_additem(menu, "Remove model", "", 0); + //menu_additem(menu, "Remove all models", "", 0); + + menu_setprop(menu, MPROP_EXIT, MEXIT_ALL); + menu_setprop(menu, MPROP_NUMBER_COLOR, "\w"); + + menu_display(id, menu, 0); + return PLUGIN_HANDLED; +} + +public menuHandel_model_spawner_menu(id, menu, item) { + if(item == MENU_EXIT) { + menu_cancel(id); + return PLUGIN_HANDLED; + } + + new command[6], name[64], access, callback; + + menu_item_getinfo(menu, item, access, command, charsmax(command), name, charsmax(name), callback); + + switch(item) { + case 0: show_list_model_menu(id); + case 1: CmdSpawnRemove(id); + //case 2: client_print(id, print_chat, "You have selected RAM"); + } + + menu_destroy(menu); + + return PLUGIN_HANDLED; +} + +public show_list_model_menu(id) { + new menu = menu_create("List of model : ", "menuHandel_list_model_menu"); + + new buffer[64]; + new size = ArraySize (model_list); + for(new i=0;i < size;i++) { + ArrayGetString(model_list, i, buffer,charsmax(buffer)); + menu_additem(menu, buffer, "", 0); + } + + menu_setprop(menu, MPROP_EXIT, MEXIT_ALL); + menu_setprop(menu, MPROP_NUMBER_COLOR, "\w"); + + menu_display(id, menu, 0); + + return PLUGIN_HANDLED; +} + +public menuHandel_list_model_menu(id, menu, item) { + if(item == MENU_EXIT) { + menu_cancel(id); + return PLUGIN_HANDLED; + } + + new command[6], name[64], access, callback; + + menu_item_getinfo(menu, item, access, command, charsmax(command), name, charsmax(name), callback); + + + new buffer[64]; + ArrayGetString(model_list, item, buffer,charsmax(buffer)); + CmdSpawnTree(id,buffer); + + + menu_destroy(menu); + + return PLUGIN_HANDLED; +} + +public plugin_precache( ) { + model_list = ArrayCreate(64,1); + new configsdir[128], configFile [128]; + get_configsdir(configsdir,charsmax(configsdir)); + formatex(configFile,charsmax(configFile),NAME_CONFIG_FILE,configsdir); + if (!file_exists(configFile)) + return; + + new buffer_line[64], len, i; + new index = read_file(configFile, 0, buffer_line, charsmax(buffer_line),len); + + while (index != 0) { + if(!equali(buffer_line[4],"")) { + if (file_exists(buffer_line)) { + precache_model(buffer_line); + ArrayPushString(model_list,buffer_line); + i++; + } + } + index = read_file(configFile, index, buffer_line, charsmax(buffer_line),len); + } +} + +public plugin_cfg( ) { + new szMapName[ 32 ]; + get_mapname( szMapName, charsmax (szMapName) ); + strtolower( szMapName ); + + new datadir[128], dataFolder [128]; + get_datadir(datadir,charsmax(datadir)); + formatex(dataFolder,charsmax(dataFolder),NAME_FOLD_MAP_MODELS,datadir); + + formatex( g_szConfigFile, charsmax (g_szConfigFile), dataFolder ); + + if( !dir_exists( g_szConfigFile ) ) { + mkdir( g_szConfigFile ); + format( g_szConfigFile, charsmax (g_szConfigFile), "%s/%s.txt", g_szConfigFile, szMapName ); + return; + } + + format( g_szConfigFile, charsmax (g_szConfigFile), "%s/%s.txt", g_szConfigFile, szMapName ); + + if( !file_exists( g_szConfigFile ) ) + return; + + new iFile = fopen( g_szConfigFile, "rt" ); + + if( !iFile ) + return; + + new model[64]; + new Float:vOrigin[ 3 ], x[ 16 ], y[ 16 ], z[ 16 ], szData[sizeof (model) + sizeof( x ) + sizeof( y ) + sizeof( z ) + 4 ]; + + while( !feof( iFile ) ) { + fgets( iFile, szData, charsmax( szData ) ); + trim( szData ); + + if( !szData[ 0 ] ) + continue; + + parse(szData, model, charsmax(model), x, charsmax(x), y, charsmax(y), z, charsmax(z) ); + + vOrigin[ 0 ] = str_to_float( x ); + vOrigin[ 1 ] = str_to_float( y ); + vOrigin[ 2 ] = str_to_float( z ); + + if (-1 != ArrayFindString(model_list, model)) + CreateTree( vOrigin , model); + } + + fclose( iFile ); +} + +CmdSpawnTree( const id, const model[]) { + + new Float:vOrigin[ 3 ]; + entity_get_vector( id, EV_VEC_origin, vOrigin ); + + if( CreateTree( vOrigin,model) ) + SaveTrees(); + + return PLUGIN_HANDLED; +} + +CmdSpawnRemove(const id) { + new Float:vOrigin[ 3 ], szClassName[ 10 ], iEntity = -1, iDeleted; + entity_get_vector( id, EV_VEC_origin, vOrigin ); + + while( ( iEntity = find_ent_in_sphere( iEntity, vOrigin, 100.0 ) ) > 0 ) { + entity_get_string( iEntity, EV_SZ_classname, szClassName, charsmax(szClassName) ); + + if( equal( szClassName, CLASS_NAME ) ) { + remove_entity( iEntity ); + + iDeleted++; + } + } + + if( iDeleted > 0 ) + SaveTrees(); + + console_print( id, "[AMXX] Deleted %i trees.%s", iDeleted, iDeleted == 0 ? " You need to stand in tree to remove it" : "" ); + + return PLUGIN_HANDLED; +} + +CreateTree( const Float:vOrigin[ 3 ], const model[] ) { + new iEntity = create_entity( "info_target" ); + + if( !iEntity ) + return 0; + + entity_set_string( iEntity, EV_SZ_classname, CLASS_NAME ); + entity_set_int( iEntity, EV_INT_solid, SOLID_NOT ); + entity_set_int( iEntity, EV_INT_movetype, MOVETYPE_NONE ); + + entity_set_size( iEntity, Float:{ -1.0, -1.0, -1.0 }, Float:{ 1.0, 1.0, 36.0 } ); + entity_set_origin( iEntity, vOrigin ); + entity_set_model( iEntity, model ); + + drop_to_floor( iEntity ); + return iEntity; +} + +SaveTrees() { + if( file_exists( g_szConfigFile ) ) + delete_file( g_szConfigFile ); + + new iFile = fopen( g_szConfigFile, "wt" ); + + if( !iFile ) + return; + + new Float:vOrigin[ 3 ], iEntity; + new model[64]; + + while( ( iEntity = find_ent_by_class( iEntity, CLASS_NAME ) ) > 0 ) { + entity_get_vector( iEntity, EV_VEC_origin, vOrigin ); + entity_get_string( iEntity, EV_SZ_model, model, charsmax(model)); + + fprintf( iFile, "%s %f %f %f^n", model, vOrigin[ 0 ], vOrigin[ 1 ], vOrigin[ 2 ] ); + } + + fclose( iFile ); +} \ No newline at end of file diff --git a/amxmodx/scripting/include/cellarray.inc b/amxmodx/scripting/include/cellarray.inc new file mode 100644 index 0000000..992e42c --- /dev/null +++ b/amxmodx/scripting/include/cellarray.inc @@ -0,0 +1,525 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +#if defined _cellarray_included + #endinput +#endif + +#define _cellarray_included + +/** + * Cellarray tag declaration + * + * @note These dynamic arrays are intended to be used for a form of global + * storage without requiring a #define that needs to be increased each + * time the plugin author requires more storage. These are not designed + * to be a full replacement for normal arrays, as those are faster and + * should be used whenever possible. + * @note Plugins are responsible for freeing all Array handles they acquire, + * including those from ArrayClone. Failing to free handles will result + * in the plugin and AMXX leaking memory. + */ +enum Array +{ + Invalid_Array = 0 +}; + +/** + * Returns the number of cells required to fit a string of the specified size + * (including the null terminator). + * + * @param size Number of bytes. + * + * @return Minimum number of cells required to fit the byte count. + */ +stock ByteCountToCells(size) +{ + if (!size) + { + return 1; + } + + return (size + 3) / 4; +} + +/** + * Creates a handle to a dynamically sized array. + * + * @note It is very important that the provided cellsize matches up with the + * buffer sizes that are passed with subsequent Array[Get|Set|Push] calls. + * @note Initially the "reserved" parameter was intended to create blank entries + * that would immediately be usable with Array[Get|Set] functions. This + * functionality was never working as intended, and can now be achieved + * using ArrayResize(). + * + * @param cellsize Size of each array entry in cells + * @param reserved Pre-allocates space in the array for the specified + * number of items. The items are not valid to read or set + * until they have actually been pushed into the array. + * + * @return New array handle, which must be freed via ArrayDestroy() + * @error If an invalid cellsize is provided an error will be + * thrown. + */ +native Array:ArrayCreate(cellsize = 1, reserved = 32); + +/** + * Clones an array, returning a new handle with the same size and data. + * + * @param which Array handle + * + * @return Handle to the cloned array on success, 0 otherwise + * @error If an invalid handle is provided an error will be + * thrown. + */ +native Array:ArrayClone(Array:which); + +/** + * Clears all entries from the array. + * + * @param which Array handle + * + * @noreturn + * @error Invalid handle + */ +native ArrayClear(Array:which); + +/** + * Returns the number of elements in the array. + * + * @param which Array handle + * + * @return Number of elements in the array + * @error If an invalid handle is provided an error will be + * thrown. + */ +native ArraySize(Array:which); + +/** + * Resizes an array. + * + * @note If the size is smaller than the current array size the array is + * truncated and data lost. + * + * @param which Array handle + * @param newsize New size + * + * @noreturn + * @error If an invalid handle is provided or the resizing + * operation runs out of memory, an error will be thrown. + */ +native bool:ArrayResize(Array:which, newsize); + +/** + * Retrieves an array of data from a cellarray. + * + * @note If the size parameter is specified as -1 the output buffer has to match + * the size the array was created with. + * + * @param which Array handle + * @param item Item index in the array + * @param output Buffer to copy value to + * @param size If not set, assumes the buffer size is equal to the + * cellsize. Otherwise, the specified size is used. + * + * @return Number of cells copied + * @error If an invalid handle or index is provided an error will + * be thrown. + */ +native ArrayGetArray(Array:which, item, any:output[], size = -1); + +/** + * Returns a single cell of data from an array + * + * @param which Array handle + * @param item Item index in the array + * @param block If the array has a cellsize >1 this optionally specifies + * which block to read from + * @param asChar If true reads the value as a byte instead of a cell + * + * @return Integer value + * @error If an invalid handle, index or block is provided an + * error will be thrown. + */ +native any:ArrayGetCell(Array:which, item, block = 0, bool:asChar = false); + +/** + * Returieves string data from an array. + * + * @param which Array handle + * @param item Item index in the array + * @param output Buffer to copy value to + * @param size Maximum size of the buffer + * + * @return Number of characters copied + * @error If an invalid handle or an invalid index is provided an + * error will be thrown. + */ +native ArrayGetString(Array:which, item, output[], size); + +/** + * Fills an item's data with the contents of an array. + * + * @note If the size parameter is specified as -1 the input buffer has to match + * the size the array was created with. + * @note The item index must already be valid. Use ArrayPushArray to create + * a new array item in the cellarray. + * + * @param which Array handle + * @param item Item index in the array + * @param input Array to copy to the cellarray + * @param size If not set, assumes the buffer size is equal to the + * cellsize. Otherwise, the specified size is used. + * + * @return Number of cells copied + * @error If an invalid handle or an invalid index is provided an + * error will be thrown. + */ +native ArraySetArray(Array:which, item, const any:input[], size =-1); + +/** + * Sets an item's data to a single cell value. + * + * @note The item index must already be valid. Use ArrayPushArray to create + * a new array item in the cellarray. + * + * @param which Array handle + * @param item Item index in the array + * @param input Value to set + * @param block If the array has a cellsize >1 this optionally specifies + * which block to write to + * @param asChar If true writes the value as a byte instead of a cell + * + * @noreturn + * @error If an invalid handle, index or block is provided an + * error will be thrown. + */ +native ArraySetCell(Array:which, item, any:input, block = 0, bool:asChar = false); + +/** + * Sets an item's data to a string value. + * + * @note The input will be truncated if it is longer than the cellsize the array + * was created with. + * @note The item index must already be valid. Use ArrayPushString to create + * a new array item in the cellarray. + * + * @param which Array handle + * @param item Item index in the array + * @param input String to copy to the array + * + * @return Number of characters copied + * @error If an invalid handle or an invalid index is provided an + * error will be thrown. + */ +native ArraySetString(Array:which, item, const input[]); + +/** + * Creates a new item at the end of the cellarray and copies the provided array + * into it. + * + * @note The input will be truncated if it is bigger than the cellsize the array + * was created with. + * + * @param which Array handle + * @param input Array to copy to the cellarray + * @param size If not set, assumes the buffer size is equal to the + * cellsize. Otherwise, the specified size is used. + * + * @return Index of the new entry + * @error If an invalid handle is provided or the resizing + * operation runs out of memory, an error will be thrown. + */ +native ArrayPushArray(Array:which, const any:input[], size = -1); + +/** + * Creates a new item ath the end of the array and sets the item's single cell + * value. + * + * @param which Array handle + * @param input Value to set + * + * @return Index of the new entry + * @error If an invalid handle is provided or the resizing + * operation runs out of memory, an error will be thrown. + */ +native ArrayPushCell(Array:which, any:input); + +/** + * Creates a new item at the end of the array and copies the provided string + * into it. + * + * @note The input will be truncated if it is longer than the cellsize the array + * was created with. + * + * @param which Array handle + * @param input String to copy to the array + * + * @return Index of the new entry + * @error If an invalid handle is provided or the resizing + * operation runs out of memory, an error will be thrown. + */ +native ArrayPushString(Array:which, const input[]); + +/** + * Creates a new item behind the specified item and copies the provided array + * into it. All items beyond it get shifted up by one. + * + * @param which Array handle + * @param item Item index in the array + * @param input Array to copy to the cellarray + * + * @noreturn + * @error If an invalid handle or an invalid index is provided an + * error will be thrown. + */ +native ArrayInsertArrayAfter(Array:which, item, const any:input[]); + +/** + * Creates a new item behind the specified item and sets the item's single cell + * value. All items beyond it get shifted up by one. + * + * @param which Array handle + * @param item Item index in the array + * @param input Value to set + * + * @noreturn + * @error If an invalid handle or an invalid index is provided an + * error will be thrown. + */ +native ArrayInsertCellAfter(Array:which, item, any:input); + +/** + * Creates a new item behind the specified item and copies the provided string + * into it. All items beyond it get shifted up by one. + * + * @note The input will be truncated if it is longer than the cellsize the array + * was created with. + * + * @param which Array handle + * @param item Item index in the array + * @param input String to copy to the array + * + * @noreturn + * @error If an invalid handle or an invalid index is provided an + * error will be thrown. + */ +native ArrayInsertStringAfter(Array:which, item, const input[]); + +/** + * Creates a new item in front of the specified item and copies the provided + * array into it. All items beyond it get shifted up by one. + * + * @param which Array handle + * @param item Item index in the array + * @param input Array to copy to the cellarray + * + * @noreturn + * @error If an invalid handle or an invalid index is provided an + * error will be thrown. + */ +native ArrayInsertArrayBefore(Array:which, item, const any:input[]); + +/** + * Creates a new item in front of the specified item and sets the item's single + * cell value. All items beyond it get shifted up by one. + * + * @param which Array handle + * @param item Item index in the array + * @param input Value to set + * + * @noreturn + * @error If an invalid handle or an invalid index is provided an + * error will be thrown. + */ +native ArrayInsertCellBefore(Array:which, item, const any:input); + +/** + * Creates a new item in front of the specified item and copies the provided + * string into it. All items beyond it get shifted up by one. + * + * @note The input will be truncated if it is longer than the cellsize the array + * was created with. + * + * @param which Array handle + * @param item Item index in the array + * @param input String to copy to the array + * + * @noreturn + * @error If an invalid handle or an invalid index is provided an + * error will be thrown. + */ +native ArrayInsertStringBefore(Array:which, item, const input[]); + +/** + * Swaps the position of two items. + * + * @param which Array handle + * @param item1,item2 Item pair to swap + * + * @noreturn + * @error If an invalid handle or an invalid index is provided an + * error will be thrown. + */ +native ArraySwap(Array:which, item1, item2); + +/** + * Deletes an item from the array. All items beyond it get shifted down by one. + * + * @param which Array handle + * @param item Item to delete + * + * @noreturn + * @error If an invalid handle or an invalid index is provided an + * error will be thrown. + */ +native ArrayDeleteItem(Array:which, item); + +/** + * Searches through the array and returns the index of the first occurence of + * the specified string. + * + * @param which Array handle + * @param item String to search for + * + * @return Array index on success, -1 if the string can't be found + * @error Invalid handle. + */ +native ArrayFindString(Array:which, const item[]); + +/** + * Searches through the array and returns the index of the first occurence of + * the specified value. + * + * @param which Array handle + * @param item Value to search for + * + * @return Array index on success, -1 if the value can't be found + * @error If an invalid handle is provided an error will be + * thrown. + */ +native ArrayFindValue(Array:which, any:item); + +/** + * Creates a special handle that can be passed to a string format routine for + * printing as a string (with the %a format option). + * + * @note It is recommended to pass the function as a parameter to the format + * routine directly. The array item must contain a null-terminated string! + * @note Do not save or otherwise use the handles returned by this function. + * @note Example usage: + * console_print(id, "%a", ArrayGetStringHandle(MessageArray, i)); + * + * @param which Array handle + * @param item Item to retrieve handle of + * + * @return Handle to the item + * @error If an invalid handle or an invalid index is provided an + * error will be thrown. + */ +native DoNotUse:ArrayGetStringHandle(Array:which, item); + +/** + * Destroys the array and frees its memory. + * + * @note The function automatically sets the variable passed to it to 0 to aid + * in preventing accidental usage after destroy. + * + * @param which Array to destroy + * + * @return 1 if the Array was destroyed, 0 if nothing had to be + * destroyed (invalid handle) + */ +native ArrayDestroy(&Array:which); + +/** + * Similar to sorting.inc's CustomSort, the sorting algorithm then uses the + * custom comparison function to sort the data. + * + * @note The function is called in the following manner: + * + * public MySortFunc(Array:array, item1, item2, const data[], data_size) + * + * array - Array handle in its current un-sorted state + * item1, item2 - Current item pair being compared + * data[] - Extra data array passed to the sort func + * data_size - Size of extra data + * + * @note The comparison function should return: + * -1 if item1 should go before item2 + * 0 if item1 and item2 are equal + * 1 if item1 should go after item2 + * + * @note All parameters after item2 are optional and do not need to be specified + * and used. + * @note Unlike the sorting.inc version, the array passed to the callback is not + * in mid-sorted state. + * + * @param array Array handle + * @param comparefunc Callback function used for comparison + * @param data Extra data that is passed through to the callback + * @param data_size Size of extra data + * + * @noreturn + * @error If an invalid handle or an invalid callback is provided + * an error will be thrown. + */ +native ArraySort(Array:array, const comparefunc[], data[]="", data_size=0); + +/** + * A faster version of ArraySort, the sorting algorithm then uses the custom + * comparison function to sort the data. + * + * @note The advantage of this function is that the data of the elements being + * compared is directly passed to the function, instead of the item + * indexes that are passed by ArraySort. This removes the need for calling + * ArrayGet[Cell|String|Array] every time before being able to compare the + * elements. + * + * @note For Arrays with a cellsize of 1 (used for storing integers and floats), + * the function is called in the following manner: + * + * public MySortFunc(Array:array, elem1, elem2, const data[], data_size) + * + * array - Array handle in its current un-sorted state + * elem1, elem2 - Current element pair being compared + * data[] - Extra data array passed to the sort func + * data_size - Size of extra data + * + * @note For Arrays with a cellsize larger than 1 (used for storing arrays and + * strings), the function is called in the following manner: + * + * public MySortFunc(Array:array, elem1[], elem2[], const data[], data_size) + * + * array - Array handle in its current un-sorted state + * elem1[], elem2[] - Current element pair being compared + * data[] - Extra data array passed to the sort func + * data_size - Size of extra data + * + * + * @note The comparison function should return: + * -1 if elem1 should go before elem2 + * 0 if elem1 and elem2 are equal + * 1 if elem1 should go after elem2 + * + * @note All parameters after item2 are optional and do not need to be specified + * and used. + * @note Unlike the sorting.inc version, the array passed to the callback is not + * in mid-sorted state. + * + * @param array Array handle + * @param comparefunc Callback function used for comparison + * @param data Extra data that is passed through to the callback + * @param data_size Size of extra data + * + * @noreturn + * @error If an invalid handle or an invalid callback is provided + * an error will be thrown. + */ +native ArraySortEx(Array:array, const comparefunc[], data[]="", data_size=0);