├── README.md ├── addons └── sourcemod │ ├── plugins │ └── map-decals.smx │ ├── configs │ └── map-decals │ │ ├── maps │ │ └── example_map.cfg │ │ └── decals.cfg │ ├── translations │ └── map-decals.phrases.txt │ └── scripting │ └── map-decals.sp └── materials └── decals └── custom └── example ├── tsgkcorn512x512.vtf └── tsgkcorn512x512.vmt /README.md: -------------------------------------------------------------------------------- 1 | **This project is not actively maintained anymore, please fork this** 2 | -------------------------------------------------------------------------------- /addons/sourcemod/plugins/map-decals.smx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcserv/map-decals/HEAD/addons/sourcemod/plugins/map-decals.smx -------------------------------------------------------------------------------- /materials/decals/custom/example/tsgkcorn512x512.vtf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcserv/map-decals/HEAD/materials/decals/custom/example/tsgkcorn512x512.vtf -------------------------------------------------------------------------------- /addons/sourcemod/configs/map-decals/maps/example_map.cfg: -------------------------------------------------------------------------------- 1 | "Positions" 2 | { 3 | "Mais" 4 | { 5 | "pos1" "123.000000 456.000000 789.000000" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /addons/sourcemod/configs/map-decals/decals.cfg: -------------------------------------------------------------------------------- 1 | "Decals" 2 | { 3 | "Maize" 4 | { 5 | 6 | "path" "decals/custom/example/tsgkcorn512x512" 7 | 8 | } 9 | 10 | } -------------------------------------------------------------------------------- /materials/decals/custom/example/tsgkcorn512x512.vmt: -------------------------------------------------------------------------------- 1 | "lightmappedgeneric" { 2 | "$basetexture" "decals\custom\example\TSGKCorn512x512" 3 | "$translucent" 1 4 | "$decal" 1 5 | "$decalscale" 1.000000 6 | "$surfaceprop" "Default" 7 | } 8 | -------------------------------------------------------------------------------- /addons/sourcemod/translations/map-decals.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "usage_paintdecal" 4 | { 5 | "#format" "{1:c},{2:c},{3:c}" 6 | "en" "{1}[SM] {2}Usage: {3}sm_paintdecal " 7 | "de" "{1}[SM] {2}Anwendung: {3}sm_paintdecal " 8 | } 9 | "error_decal_not_found" 10 | { 11 | "#format" "{1:c},{2:c},{3:c},{4:c},{5:s},{6:c}" 12 | "en" "{1}[SM] {2}Error: {3}Decal {4}{5} {6}not found in list." 13 | "de" "{1}[SM] {2}Fehler: {3}Decal {4}{5} {6}konnte in der Liste nicht gefunden werden." 14 | } 15 | "error_another_decal" 16 | { 17 | "#format" "{1:c},{2:c},{3:c}" 18 | "en" "{1}[SM] {2}Error: {3}Another Decal is already painted on this position!" 19 | "de" "{1}[SM] {2}Fehler: {3}Ein anderes Decal befindet sich bereits an dieser Position!" 20 | } 21 | "paintdecal_aim" 22 | { 23 | "#format" "{1:c},{2:c},{3:d},{4:c},{5:c},{6:s},{7:c},{8:c},{9:s},{10:c}" 24 | "en" "{1}[SM] Decal {2}{3}{4}: {5}{6}{7} painted on Map {8}{9}{10}!" 25 | "de" "{1}[SM] Decal {2}{3}{4}: {5}{6}{7} angebracht auf Map {8}{9}{10}!" 26 | } 27 | "decal_position" 28 | { 29 | "#format" "{1:c},{2:c},{3:f},{4:f},{5:f}" 30 | "en" "{1}[SM] Decal Position: {2}{3}, {4}, {5}" 31 | "de" "{1}[SM] Decal Position: {2}{3}, {4}, {5}" 32 | } 33 | "error_entity" 34 | { 35 | "#format" "{1:c},{2:c},{3:c}" 36 | "en" "{1}[SM] {2}Error: {3}No Solid Entity found!" 37 | "de" "{1}[SM] {2}Error: {3}Keinen Festkörper gefunden!" 38 | } 39 | "no_decal" 40 | { 41 | "#format" "{1:c},{2:c},{3:s},{4:c}" 42 | "en" "{1}[SM] No Decals available on {2}{3}{4}." 43 | "de" "{1}[SM] Keine Decals verfügbar auf {2}{3}{4}." 44 | } 45 | "removedecal" 46 | { 47 | "#format" "{1:c},{2:c},{3:d},{4:c},{5:c},{6:s},{7:c},{8:c},{9:s},{10:c}" 48 | "en" "{1}[SM] Decal {2}{3}{4}: {5}{6}{7} removed from Map {8}{9}{10}." 49 | "de" "{1}[SM] Decal {2}{3}{4}: {5}{6}{7} entfernt von Map {8}{9}{10}." 50 | } 51 | "no_decal_found" 52 | { 53 | "#format" "{1:c},{2:c}" 54 | "en" "{1}[SM] {2}No Decal found on where you are looking at." 55 | "de" "{1}[SM] {2}Kein Decal im Zielbereich gefunden." 56 | } 57 | "removedecal_all_single" 58 | { 59 | "#format" "{1:c},{2:c},{3:d},{4:c},{5:c},{6:s},{7:c}" 60 | "en" "{1}[SM] {2}{3} {4}Decal removed from Map {5}{6}{7}." 61 | "de" "{1}[SM] {2}{3} {4}Decal entfernt von Map {5}{6}{7}." 62 | } 63 | "removedecal_all" 64 | { 65 | "#format" "{1:c},{2:c},{3:d},{4:c},{5:c},{6:s},{7:c}" 66 | "en" "{1}[SM] {2}{3} {4}Decals removed from Map {5}{6}{7}." 67 | "de" "{1}[SM] {2}{3} {4}Decals entfernt von Map {5}{6}{7}." 68 | } 69 | "removedecal_name" 70 | { 71 | "#format" "{1:c},{2:c},{3:s},{4:c},{5:c},{6:s},{7:c}" 72 | "en" "{1}[SM] Decal {2}{3}{4} removed from Map {5}{6}{7}." 73 | "de" "{1}[SM] Decal {2}{3}{4} entfernt von Map {5}{6}{7}." 74 | } 75 | "removedecal_names" 76 | { 77 | "#format" "{1:c},{2:c},{3:d},{4:c},{5:c},{6:s},{7:c}" 78 | "en" "{1}[SM] {2}{3} {4}Decals removed from Map {5}{6}{7}." 79 | "de" "{1}[SM] {2}{3} {4}Decals entfernt von Map {5}{6}{7}." 80 | } 81 | "decals_named" 82 | { 83 | "#format" "{1:c},{2:c},{3:s},{4:c}" 84 | "en" "{1}[SM] No Decals named {2}{3}{4} found on Map." 85 | "de" "{1}[SM] Keine Decals namens {2}{3}{4} auf Map gefunden." 86 | } 87 | "usage_removedecal" 88 | { 89 | "#format" "{1:c},{2:c},{3:c}" 90 | "en" "{1}[SM] {2}Usage: {3}sm_removedecal [all | id | last | name]" 91 | "de" "{1}[SM] {2}Anwendung: {3}sm_removedecal [all | id | last | name]" 92 | } 93 | "available_decals" 94 | { 95 | "#format" "{1:c},{2:c}" 96 | "en" "{1}[SM] {2}Available Decals:" 97 | "de" "{1}[SM] {2}Verfügbare Decals:" 98 | } 99 | "no_decals_available" 100 | { 101 | "#format" "{1:c},{2:c}" 102 | "en" "{1}[SM] {2}No Decals available." 103 | "de" "{1}[SM] {2}Keine Decals verfügbar." 104 | } 105 | "listdecal" 106 | { 107 | "#format" "{1:c},{2:c},{3:d},{4:c},{5:c},{6:s}" 108 | "en" "{1}[SM] Decal {2}{3}{4}: {5}{6}" 109 | "de" "{1}[SM] Decal {2}{3}{4}: {5}{6}" 110 | } 111 | "decals_file" 112 | { 113 | "#format" "{1:c},{2:c},{3:s},{4:c}" 114 | "en" "{1}[SM] Decals in File {2}{3}.cfg{4}:" 115 | "de" "{1}[SM] Decals in Datei {2}{3}.cfg{4}:" 116 | } 117 | "last_decal" 118 | { 119 | "#format" "{1:c},{2:c},{3:d},{4:c},{5:c},{6:s},{7:c}" 120 | "en" "{1}[SM] Last painted Decal {2}{3}{4}: {5}{6}{7}" 121 | "de" "{1}[SM] Zuletzt angebrachtes Decal {2}{3}{4}: {5}{6}{7}" 122 | } 123 | "decals_name_on_map" 124 | { 125 | "#format" "{1:c},{2:c},{3:s},{4:c},{5:c},{6:s},{7:c}" 126 | "en" "{1}[SM] Decals {2}{3}{4} on Map {5}{6}{7}:" 127 | "de" "{1}[SM] Decals {2}{3}{4} auf Map {5}{6}{7}:" 128 | } 129 | "decals_on_map" 130 | { 131 | "#format" "{1:c},{2:c},{3:s},{4:c}" 132 | "en" "{1}[SM] Decals on Map {2}{3}{4}:" 133 | "de" "{1}[SM] Decals auf Map {2}{3}{4}:" 134 | } 135 | "usage_listdecal" 136 | { 137 | "#format" "{1:c},{2:c},{3:c}" 138 | "en" "{1}[SM] {2}Usage: {3}sm_listdecal [all | id | last | map | name | saved]" 139 | "de" "{1}[SM] {2}Anwendung: {3}sm_listdecal [all | id | last | map | name | saved]" 140 | } 141 | "savedecal_file" 142 | { 143 | "#format" "{1:c},{2:c},{3:s},{4:c}" 144 | "en" "{1}[SM] Saving Decal to File {2}{3}{4}..." 145 | "de" "{1}[SM] Speichere Decal in Datei {2}{3}{4}..." 146 | } 147 | "error_decal_in_file" 148 | { 149 | "#format" "{1:c},{2:c},{3:c}" 150 | "en" "{1}[SM] {2}Error: {3}Decal position already found in File." 151 | "de" "{1}[SM] {2}Fehler: {3}Decal Position bereits in Datei vorhanden." 152 | } 153 | "saved_aim" 154 | { 155 | "#format" "{1:c},{2:c},{3:d},{4:c},{5:c},{6:s},{7:c}" 156 | "en" "{1}[SM] Saved {2}{3}{4} Decal Position (Name = {5}{6}{7})." 157 | "de" "{1}[SM] {2}{3}{4} Decal Position gespeichert (Name = {5}{6}{7})." 158 | } 159 | "savedecals_file" 160 | { 161 | "#format" "{1:c},{2:c},{3:s},{4:c}" 162 | "en" "{1}[SM] Saving Decals to File {2}{3}{4}..." 163 | "de" "{1}[SM] Speichere Decals in Datei {2}{3}{4}..." 164 | } 165 | "saved_one" 166 | { 167 | "#format" "{1:c},{2:c},{3:d},{4:c}" 168 | "en" "{1}[SM] Saved {2}{3}{4} Decal Position." 169 | "de" "{1}[SM] {2}{3}{4} Decal Position gespeichert." 170 | } 171 | "saved_more" 172 | { 173 | "#format" "{1:c},{2:c},{3:d},{4:c}" 174 | "en" "{1}[SM] Saved {2}{3}{4} Decal Positions." 175 | "de" "{1}[SM] {2}{3}{4} Decal Positionen gespeichert." 176 | } 177 | "no_decals_available_map" 178 | { 179 | "#format" "{1:c},{2:c},{3:s},{4:c}" 180 | "en" "{1}[SM] No Decals available on Map {2}{3}{4}." 181 | "de" "{1}[SM] Keine Decals verfügbar auf Map {2}{3}{4}." 182 | } 183 | "saving_last" 184 | { 185 | "#format" "{1:c},{2:c},{3:s},{4:c}" 186 | "en" "{1}[SM] Saving last painted Decal to File {2}{3}{4}..." 187 | "de" "{1}[SM] Speichere letzte Decal Position in Datei {2}{3}{4}..." 188 | } 189 | "saved_last" 190 | { 191 | "#format" "{1:c},{2:c},{3:s},{4:c}" 192 | "en" "{1}[SM] Saved last painted Decal Position (Name = {2}{3}{4})." 193 | "de" "{1}[SM] Letzte Decal Position gespeichert (Name = {2}{3}{4})." 194 | } 195 | "saved_one_name" 196 | { 197 | "#format" "{1:c},{2:c},{3:d},{4:c},{5:c},{6:s},{7:c}" 198 | "en" "{1}[SM] Saved {2}{3}{4} Decal Position (Name = {5}{6}{7})." 199 | "de" "{1}[SM] {2}{3}{4} Decal Position gespeichert (Name = {5}{6}{7})." 200 | } 201 | "saved_more_name" 202 | { 203 | "#format" "{1:c},{2:c},{3:d},{4:c},{5:c},{6:s},{7:c}" 204 | "en" "{1}[SM] Saved {2}{3}{4} Decal Positions (Name = {5}{6}{7})." 205 | "de" "{1}[SM] {2}{3}{4} Decal Positionen gespeichert (Name = {5}{6}{7})." 206 | } 207 | "saved_id" 208 | { 209 | "#format" "{1:c},{2:c},{3:d},{4:c},{5:c},{6:d},{7:c}" 210 | "en" "{1}[SM] Saved {2}{3}{4} Decal Position (ID = {5}{6}{7})." 211 | "de" "{1}[SM] {2}{3}{4} Decal Position gespeichert (ID = {5}{6}{7})." 212 | } 213 | "usage_savedecal" 214 | { 215 | "#format" "{1:c},{2:c},{3:c}" 216 | "en" "{1}[SM] {2}Usage: {3}sm_savedecal [all | id | last | name ]" 217 | "de" "{1}[SM] {2}Anwendung: {3}sm_savedecal [all | id | last | name ]" 218 | } 219 | "aimpos" 220 | { 221 | "#format" "{1:c},{2:c},{3:f},{4:f},{5:f}" 222 | "en" "{1}[SM] Position you are aiming at: {2}{3}, {4}, {5}" 223 | "de" "{1}[SM] Zielposition: {2}{3}, {4}, {5}" 224 | } 225 | "cfg_file_not_found" 226 | { 227 | "#format" "{1:c},{2:c},{3:c},{4:c},{5:s},{6:c}" 228 | "en" "{1}[SM] {2}Error: {3}Decal CFG File for Map {4}{5}{6} not found!" 229 | "de" "{1}[SM] {2}Fehler: {3}Decal CFG Datei für Map {4}{5}{6} konnte nicht gefunden werden!" 230 | } 231 | "list_decal" 232 | { 233 | "#format" "{1:c},{2:c},{3:s}" 234 | "en" "{1}[SM] Decal: {2}{3}" 235 | "de" "{1}[SM] Decal: {2}{3}" 236 | } 237 | "list_decal_id" 238 | { 239 | "#format" "{1:c},{2:c},{3:d}" 240 | "en" "{1}[SM] Decal ID: {2}{3}" 241 | "de" "{1}[SM] Decal ID: {2}{3}" 242 | } 243 | "list_decal_id_name" 244 | { 245 | "#format" "{1:c},{2:c},{3:d},{4:c},{5:c},{6:s}" 246 | "en" "{1}[SM] Decal {2}{3}{4}: {5}{6}" 247 | "de" "{1}[SM] Decal {2}{3}{4}: {5}{6}" 248 | } 249 | "no_decals_in_file" 250 | { 251 | "#format" "{1:c},{2:c},{3:s},{4:c}" 252 | "en" "{1}[SM] No Decals in File {2}{3}.cfg{4}." 253 | "de" "{1}[SM] Keine Decals in Datei {2}{3}.cfg{4}." 254 | } 255 | "decal_menu_title" 256 | { 257 | "en" "Map Decals:" 258 | "de" "Map Decals:" 259 | } 260 | "save_decal_title" 261 | { 262 | "en" "Save Decal:" 263 | "de" "Decal speichern:" 264 | } 265 | "remove_decal_title" 266 | { 267 | "en" "Remove Decal:" 268 | "de" "Decal entfernen:" 269 | } 270 | "list_decal_title" 271 | { 272 | "en" "List Decal:" 273 | "de" "Decal auflisten:" 274 | } 275 | "options_menu_title" 276 | { 277 | "en" "Choose an Option:" 278 | "de" "Eine Option wählen:" 279 | } 280 | "admin_menu_title" 281 | { 282 | "en" "Map Decals" 283 | "de" "Map Decals" 284 | } 285 | "paint_decal" 286 | { 287 | "en" "Paint Decal" 288 | "de" "Decal anbringen" 289 | } 290 | "remove_decal" 291 | { 292 | "en" "Remove Decal" 293 | "de" "Decal entfernen" 294 | } 295 | "list_decal_menu" 296 | { 297 | "en" "List Decal" 298 | "de" "Decal auflisten" 299 | } 300 | "save_decal" 301 | { 302 | "en" "Save Decal" 303 | "de" "Decal speichern" 304 | } 305 | "aim_position_menu" 306 | { 307 | "en" "Aim Position" 308 | "de" "Zielposition" 309 | } 310 | "all" 311 | { 312 | "en" "All" 313 | "de" "Alle" 314 | } 315 | "all_list" 316 | { 317 | "en" "All Decal Names available" 318 | "de" "Alle verfügbaren Decalbezeichnungen" 319 | } 320 | "by_aim" 321 | { 322 | "en" "By Aim Position" 323 | "de" "Im Zielfeld" 324 | } 325 | "by_id" 326 | { 327 | "en" "By ID (from List)" 328 | "de" "Wähle ID (aus Liste)" 329 | } 330 | "by_name" 331 | { 332 | "en" "By Name (from List)" 333 | "de" "Wähle Namen (aus Liste)" 334 | } 335 | "last_painted" 336 | { 337 | "en" "Last Painted" 338 | "de" "Zuletzt angebrachtes Decal" 339 | } 340 | "map" 341 | { 342 | "en" "Map" 343 | "de" "Map" 344 | } 345 | "saved" 346 | { 347 | "en" "Saved" 348 | "de" "Gespeicherte" 349 | } 350 | } 351 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/map-decals.sp: -------------------------------------------------------------------------------- 1 | 2 | // enforce semicolons after each code statement 3 | #pragma semicolon 1 4 | 5 | #include 6 | #include 7 | #undef REQUIRE_PLUGIN 8 | #include 9 | 10 | #define PLUGIN_VERSION "1.1" 11 | 12 | // Admin Level Defines: Level for Allowing Temp.Spray/Temp.Remove of Decals and Level for Saving Decals/getting aim position 13 | #define ADMIN_LEVEL_SPRAY ADMFLAG_CUSTOM3 14 | #define ADMIN_LEVEL_SAVE ADMFLAG_ROOT 15 | 16 | // Mode Defines for Function ReadDecals 17 | #define READ 0 18 | #define LIST 1 19 | 20 | // Color Defines 21 | #define COLOR_DEFAULT 0x01 22 | #define COLOR_GREEN 0x04 // DOD = Red 23 | 24 | 25 | 26 | /***************************************************************** 27 | 28 | 29 | P L U G I N I N F O 30 | 31 | 32 | *****************************************************************/ 33 | 34 | public Plugin:myinfo = { 35 | name = "", 36 | author = "Berni, Stingbyte", 37 | description = "Allows admins to place any decals into the map that are defined in the the config and save them permanently for each map", 38 | version = PLUGIN_VERSION, 39 | url = "http://forums.alliedmods.net/showthread.php?t=69502" 40 | } 41 | 42 | 43 | 44 | /***************************************************************** 45 | 46 | 47 | G L O B A L V A R S 48 | 49 | 50 | *****************************************************************/ 51 | 52 | // ConVar Handles 53 | new Handle:md_version = INVALID_HANDLE; 54 | new Handle:md_maxdis = INVALID_HANDLE; 55 | new Handle:md_pos = INVALID_HANDLE; 56 | new Handle:md_spraysound = INVALID_HANDLE; 57 | 58 | // Misc 59 | new Handle:hAdminMenu = INVALID_HANDLE; 60 | 61 | new Handle:adt_decal_names = INVALID_HANDLE; 62 | new Handle:adt_decal_paths = INVALID_HANDLE; 63 | new Handle:adt_decal_precache = INVALID_HANDLE; 64 | 65 | new Handle:adt_decal_id = INVALID_HANDLE; 66 | new Handle:adt_decal_position = INVALID_HANDLE; 67 | 68 | new String:mapName[64]; 69 | new String:path_decals[PLATFORM_MAX_PATH]; 70 | new String:path_mapdecals[PLATFORM_MAX_PATH]; 71 | 72 | 73 | 74 | /***************************************************************** 75 | 76 | 77 | F O R W A R D P U B L I C S 78 | 79 | 80 | *****************************************************************/ 81 | 82 | public OnPluginStart() { 83 | 84 | // Commands 85 | RegAdminCmd("sm_paintdecal", Command_PaintDecal, ADMIN_LEVEL_SPRAY, "Sprays a Decal by (names specified in config)"); 86 | RegAdminCmd("sm_removedecal", Command_RemoveDecal, ADMIN_LEVEL_SPRAY, "Removes a Decal whilst aiming at it, [all] removes all Decals (on current Map), [id] removes a Decal by id, [last] removes last painted Decal, [name] removes all Decals by decalname (on current Map)"); 87 | RegAdminCmd("sm_listdecal", Command_ListDecal, ADMIN_LEVEL_SPRAY, "Shows the name of a Decal whilst aiming at it, [all] lists all Decal names available, [id] lists a Decal by id, [last] lists the last painted Decal (on current Map), [map] lists all Decals painted (on current Map), [name] lists all Decals by that Name painted (on current Map), [saved] lists all Decals saved in config File"); 88 | RegAdminCmd("sm_savedecal", Command_SaveDecal, ADMIN_LEVEL_SAVE, "Saves a Decal to the config whilst aiming at it, [all] saves all Decals (on current Map), [id] saves a Decal by id, [last] saves last painted Decal, [name] saves all Decals by decalname (on current Map)"); 89 | RegAdminCmd("sm_aimpos", Command_GetAimPos, ADMIN_LEVEL_SAVE, "Shows the position you are currently aiming at"); 90 | RegAdminCmd("sm_decalmenu", Command_DecalMenu, ADMIN_LEVEL_SPRAY, "Shows the Map Decals Menu"); 91 | 92 | // ConVars 93 | md_version = CreateConVar("md_version", PLUGIN_VERSION, "Map Decals plugin version", FCVAR_DONTRECORD|FCVAR_PLUGIN|FCVAR_NOTIFY); 94 | // Set it to the correct version, in case the plugin gets updated... 95 | SetConVarString(md_version, PLUGIN_VERSION); 96 | 97 | md_maxdis = CreateConVar("md_decal_dista", "50.0", "How far away from the Decals position it will be traced to and check distance to prevent painting a Decal over another"); 98 | md_pos = CreateConVar("md_decal_printpos", "1", "Turns on/off printing out of decal positions"); 99 | md_spraysound = CreateConVar("md_decal_spraysound", "player/sprayer.wav", "Path to the spray sound used by map-decals plugin"); 100 | 101 | // Create our dynamic arrays we need for the keyvalues/decal data 102 | adt_decal_names = CreateArray(64); 103 | adt_decal_paths = CreateArray(PLATFORM_MAX_PATH); 104 | adt_decal_precache = CreateArray(); 105 | adt_decal_id = CreateArray(); 106 | adt_decal_position = CreateArray(3); 107 | 108 | LoadTranslations("map-decals.phrases"); 109 | 110 | /* See if the menu plugin is already ready */ 111 | new Handle:topmenu; 112 | if (LibraryExists("adminmenu") && ((topmenu = GetAdminTopMenu()) != INVALID_HANDLE)) { 113 | /* If so, manually fire the callback */ 114 | OnAdminMenuReady(topmenu); 115 | } 116 | } 117 | 118 | public OnLibraryRemoved(const String:name[]) { 119 | 120 | if (StrEqual(name, "adminmenu")) { 121 | hAdminMenu = INVALID_HANDLE; 122 | } 123 | } 124 | 125 | public OnMapStart() { 126 | 127 | GetCurrentMap(mapName, sizeof(mapName)); 128 | 129 | BuildPath(Path_SM, path_decals, sizeof(path_decals), "configs/map-decals/decals.cfg"); 130 | BuildPath(Path_SM, path_mapdecals, sizeof(path_mapdecals), "configs/map-decals/maps/%s.cfg", mapName); 131 | 132 | ReadDecals(-1, READ); 133 | 134 | decl String:spraySound[PLATFORM_MAX_PATH]; 135 | GetConVarString(md_spraysound, spraySound, sizeof(spraySound)); 136 | Format(spraySound, sizeof(spraySound), "sound/%s", spraySound); 137 | AddFileToDownloadsTable(spraySound); 138 | 139 | // Precache Spray Sound 140 | if (!IsSoundPrecached(spraySound)) { 141 | if (!PrecacheSound(spraySound, false)) { 142 | LogMessage("PrecacheSound failed: %s", spraySound); 143 | } 144 | } 145 | } 146 | 147 | public OnMapEnd() { 148 | 149 | ClearArray(adt_decal_names); 150 | ClearArray(adt_decal_paths); 151 | ClearArray(adt_decal_precache); 152 | 153 | ClearArray(adt_decal_id); 154 | ClearArray(adt_decal_position); 155 | } 156 | 157 | public OnClientPostAdminCheck(client) { 158 | 159 | // Show him what we have 160 | decl Float:position[3]; 161 | decl id, precache; 162 | 163 | new size = GetArraySize(adt_decal_id); 164 | for (new i=0; i GetArraySize(adt_decal_names)) { 221 | id = FindStringInArrayCase(adt_decal_names, decalName, false); 222 | } 223 | else{ 224 | id--; 225 | GetArrayString(adt_decal_names, id, decalName, sizeof(decalName)); 226 | } 227 | 228 | if (id == -1) { 229 | ReplyToCommand(client, "%t", "error_decal_not_found", COLOR_DEFAULT, COLOR_GREEN, COLOR_DEFAULT, COLOR_GREEN, decalName, COLOR_DEFAULT); 230 | return Plugin_Handled; 231 | } 232 | 233 | new precache = GetArrayCell(adt_decal_precache, id); 234 | new Float:MaxDis = GetConVarFloat(md_maxdis); 235 | 236 | decl Float:pos[3]; 237 | decl Float:position[3]; 238 | 239 | if (GetClientAimTargetEx(client, pos) >= 0) { 240 | new size = GetArraySize(adt_decal_id); 241 | for (new i=0; i= 0) { 292 | new Float:MaxDis = GetConVarFloat(md_maxdis); 293 | for (new i=0; i 1) 369 | ReplyToCommand(client, "%t", "removedecal_names",COLOR_DEFAULT, COLOR_GREEN, size, COLOR_DEFAULT, COLOR_GREEN, mapName, COLOR_DEFAULT); 370 | if (cursize > 1) 371 | ReplyToCommand(client, "%t", "removedecal_names",COLOR_DEFAULT, COLOR_GREEN, size-cursize, COLOR_DEFAULT, COLOR_GREEN, mapName, COLOR_DEFAULT); 372 | return Plugin_Handled; 373 | } 374 | ReplyToCommand(client, "%t", "decals_named", COLOR_DEFAULT, COLOR_GREEN, action, COLOR_DEFAULT); 375 | return Plugin_Handled; 376 | } 377 | 378 | // Remove by ID 379 | index = StringToInt(action); 380 | if (index != 0 && index <= size) { 381 | index--; 382 | new decal = GetArrayCell(adt_decal_id, index); 383 | GetArrayString(adt_decal_names, decal, decalName, sizeof(decalName)); 384 | GetArrayArray(adt_decal_position, index, _:position); 385 | RemoveFromArray(adt_decal_id, index); 386 | RemoveFromArray(adt_decal_position, index); 387 | ReplyToCommand(client, "%t", "removedecal", COLOR_DEFAULT, COLOR_GREEN, index+1, COLOR_DEFAULT, COLOR_GREEN, decalName, COLOR_DEFAULT, COLOR_GREEN, mapName, COLOR_DEFAULT); 388 | LogAction(client, -1, "\"%L\" removed Decal \"%s\" from Map \"%s\" (Position: %f, %f, %f)", client, decalName, mapName, position[0], position[1], position[2]); 389 | new DecalPos = GetConVarInt(md_pos); 390 | if (DecalPos) 391 | ReplyToCommand(client, "%t", "decal_position",COLOR_DEFAULT, COLOR_GREEN, position[0], position[1], position[2]); 392 | return Plugin_Handled; 393 | } 394 | ReplyToCommand(client, "%t", "usage_removedecal", COLOR_DEFAULT, COLOR_GREEN, COLOR_DEFAULT); 395 | return Plugin_Handled; 396 | } 397 | 398 | public Action:Command_ListDecal(client, args) { 399 | 400 | new size = GetArraySize(adt_decal_id); 401 | // List by aim position 402 | decl Float:position[3]; 403 | decl String:decalName[64]; 404 | if (GetCmdArgs() == 0) { 405 | decl Float:pos[3]; 406 | if (GetClientAimTargetEx(client, pos) >= 0) { 407 | new Float:MaxDis = GetConVarFloat(md_maxdis); 408 | for (new i=0; i0) 431 | ReplyToCommand(client, "%t", "available_decals", COLOR_DEFAULT, COLOR_GREEN); 432 | 433 | else 434 | ReplyToCommand(client, "%t", "no_decals_available", COLOR_DEFAULT, COLOR_GREEN); 435 | for (new i=0; i -1) { 470 | new status = 0; 471 | ReplyToCommand(client, "%t", "decals_name_on_map", COLOR_DEFAULT, COLOR_GREEN, action, COLOR_DEFAULT, COLOR_GREEN, mapName, COLOR_DEFAULT); 472 | for (new i=0; i= 0) { 541 | new Float:MaxDis = GetConVarFloat(md_maxdis); 542 | for (new i=0; i -1) { 670 | GetArrayString(adt_decal_names,found, action, sizeof(action)); 671 | new count = 0; 672 | ReplyToCommand(client, "%t", "savedecals_file", COLOR_DEFAULT, COLOR_GREEN, file, COLOR_DEFAULT); 673 | FileToKeyValues(kv, file); 674 | for (new i=0; i= 0) { 773 | ReplyToCommand(client, "%t", "aimpos",COLOR_DEFAULT, COLOR_GREEN, pos[0], pos[1], pos[2]); 774 | } 775 | else { 776 | ReplyToCommand(client, "%t", "error_entity", COLOR_DEFAULT, COLOR_GREEN, COLOR_DEFAULT); 777 | } 778 | return Plugin_Handled; 779 | } 780 | 781 | public Action:Command_DecalMenu(client, args) { 782 | 783 | decl String:action[64]; 784 | decl String:buffer[128]; 785 | 786 | new Handle:menu = CreateMenu(DecalMenuHandler); 787 | Format(buffer, sizeof(buffer), "%T", "decal_menu_title", client); 788 | SetMenuTitle(menu, buffer); 789 | if (GetCmdArgs() != 0) { 790 | GetCmdArg(1, action, sizeof(action)); 791 | } 792 | 793 | if (strcmp(action, "admin", false) == 0) { 794 | SetMenuExitBackButton(menu, true); 795 | Format(buffer, sizeof(buffer), "%T", "paint_decal", client); 796 | AddMenuItem(menu, "paintdecal_admin", buffer); 797 | Format(buffer, sizeof(buffer), "%T", "remove_decal", client); 798 | AddMenuItem(menu, "removedecal_admin", buffer); 799 | Format(buffer, sizeof(buffer), "%T", "list_decal_menu", client); 800 | AddMenuItem(menu, "listdecal_admin", buffer); 801 | if (CheckCommandAccess(client, "sm_savedecal_admin", ADMIN_LEVEL_SAVE, false)) { 802 | Format(buffer, sizeof(buffer), "%T", "save_decal", client); 803 | AddMenuItem(menu, "savedecal_admin", buffer); 804 | Format(buffer, sizeof(buffer), "%T", "aim_position_menu", client); 805 | AddMenuItem(menu, "aimpos_admin", buffer); 806 | } 807 | } 808 | else { 809 | Format(buffer, sizeof(buffer), "%T", "paint_decal", client); 810 | AddMenuItem(menu, "paintdecal", buffer); 811 | Format(buffer, sizeof(buffer), "%T", "remove_decal", client); 812 | AddMenuItem(menu, "removedecal", buffer); 813 | Format(buffer, sizeof(buffer), "%T", "list_decal_menu", client); 814 | AddMenuItem(menu, "listdecal", buffer); 815 | if (CheckCommandAccess(client, "sm_savedecal", ADMIN_LEVEL_SAVE, false)) { 816 | Format(buffer, sizeof(buffer), "%T", "save_decal", client); 817 | AddMenuItem(menu, "savedecal", buffer); 818 | Format(buffer, sizeof(buffer), "%T", "aim_position_menu", client); 819 | AddMenuItem(menu, "aimpos", buffer); 820 | } 821 | } 822 | SetMenuExitButton(menu, true); 823 | DisplayMenu(menu, client, MENU_TIME_FOREVER); 824 | return Plugin_Handled; 825 | } 826 | 827 | public DecalMenuHandler(Handle:menu, MenuAction:action, param1, param2) { 828 | 829 | /* If an option was selected, tell the client about the item. */ 830 | if (action == MenuAction_Select) { 831 | decl String:info[64]; 832 | new bool:found = GetMenuItem(menu, param2, info, sizeof(info)); 833 | if (found) { 834 | if (StrContains(info, "aimpos", false) > -1) { 835 | FakeClientCommand(param1, "say /aimpos"); 836 | if (StrContains(info, "admin", false) > -1) 837 | FakeClientCommand(param1, "sm_decalmenu admin"); 838 | else 839 | Command_DecalMenu(param1, -1); 840 | } 841 | else if (StrContains(info, "paintdecal", false) > -1) 842 | Command_OptionsMenu(param1, info); 843 | else 844 | Command_SubMenu(param1, info); 845 | } 846 | } 847 | /* If the menu was cancelled, check for param and redisplay AdminMenu. */ 848 | else if (action == MenuAction_Cancel) { 849 | 850 | if (param2 == MenuCancel_ExitBack) { 851 | RedisplayAdminMenu(hAdminMenu, param1); 852 | } 853 | } 854 | /* If the menu has ended, destroy it */ 855 | else if (action == MenuAction_End) { 856 | 857 | CloseHandle(menu); 858 | } 859 | } 860 | 861 | public bool:TraceEntityFilterPlayer(entity, contentsMask) { 862 | 863 | return entity > MAXPLAYERS; 864 | } 865 | 866 | // Menu Option 867 | public AdminMenu_MapDecals(Handle:topmenu, TopMenuAction:action, TopMenuObject:object_id, param, String:buffer[], maxlength) { 868 | 869 | if (action == TopMenuAction_DisplayOption) { 870 | 871 | Format(buffer, maxlength, "%T", "admin_menu_title", param); 872 | } 873 | else if (action == TopMenuAction_SelectOption) { 874 | 875 | FakeClientCommand(param, "sm_decalmenu admin"); 876 | } 877 | } 878 | 879 | public SubMenuHandler(Handle:submenu, MenuAction:action, param1, param2) { 880 | 881 | decl String:info[64]; 882 | /* If an option was selected, tell the client about the item. */ 883 | if (action == MenuAction_Select) { 884 | 885 | new bool:found = GetMenuItem(submenu, param2, info, sizeof(info)); 886 | if (found) { 887 | if (StrContains(info, "savedecal_all", false) > -1) { 888 | FakeClientCommand(param1, "say /savedecal all"); 889 | if (StrContains(info, "admin", false) > -1) 890 | Command_SubMenu(param1, "savedecal_admin"); 891 | else 892 | Command_SubMenu(param1, "savedecal"); 893 | } 894 | else if (StrContains(info, "savedecal_aim", false) > -1) { 895 | FakeClientCommand(param1, "say /savedecal"); 896 | if (StrContains(info, "admin", false) > -1) 897 | Command_SubMenu(param1, "savedecal_admin"); 898 | else 899 | Command_SubMenu(param1, "savedecal"); 900 | } 901 | else if (StrContains(info, "savedecal_last", false) > -1) { 902 | FakeClientCommand(param1, "say /savedecal last"); 903 | if (StrContains(info, "admin", false) > -1) 904 | Command_SubMenu(param1, "savedecal_admin"); 905 | else 906 | Command_SubMenu(param1, "savedecal"); 907 | } 908 | else if (StrContains(info, "removedecal_all", false) > -1) { 909 | FakeClientCommand(param1, "say /removedecal all"); 910 | if (StrContains(info, "admin", false) > -1) 911 | Command_SubMenu(param1, "removedecal_admin"); 912 | else 913 | Command_SubMenu(param1, "removedecal"); 914 | } 915 | else if (StrContains(info, "removedecal_aim", false) > -1) { 916 | FakeClientCommand(param1, "say /removedecal"); 917 | if (StrContains(info, "admin", false) > -1) 918 | Command_SubMenu(param1, "removedecal_admin"); 919 | else 920 | Command_SubMenu(param1, "removedecal"); 921 | } 922 | else if (StrContains(info, "removedecal_last", false) > -1) { 923 | FakeClientCommand(param1, "say /removedecal last"); 924 | if (StrContains(info, "admin", false) > -1) 925 | Command_SubMenu(param1, "removedecal_admin"); 926 | else 927 | Command_SubMenu(param1, "removedecal"); 928 | } 929 | else if (StrContains(info, "listdecal_all", false) > -1) { 930 | FakeClientCommand(param1, "say /listdecal all"); 931 | if (StrContains(info, "admin", false) > -1) 932 | Command_SubMenu(param1, "listdecal_admin"); 933 | else 934 | Command_SubMenu(param1, "listdecal"); 935 | } 936 | else if (StrContains(info, "listdecal_aim", false) > -1) { 937 | FakeClientCommand(param1, "say /listdecal"); 938 | if (StrContains(info, "admin", false) > -1) 939 | Command_SubMenu(param1, "listdecal_admin"); 940 | else 941 | Command_SubMenu(param1, "listdecal"); 942 | } 943 | else if (StrContains(info, "listdecal_last", false) > -1) { 944 | FakeClientCommand(param1, "say /listdecal last"); 945 | if (StrContains(info, "admin", false) > -1) 946 | Command_SubMenu(param1, "listdecal_admin"); 947 | else 948 | Command_SubMenu(param1, "listdecal"); 949 | } 950 | else if (StrContains(info, "listdecal_map", false) > -1) { 951 | FakeClientCommand(param1, "say /listdecal map"); 952 | if (StrContains(info, "admin", false) > -1) 953 | Command_SubMenu(param1, "listdecal_admin"); 954 | else 955 | Command_SubMenu(param1, "listdecal"); 956 | } 957 | else if (StrContains(info, "listdecal_saved", false) > -1) { 958 | FakeClientCommand(param1, "say /listdecal saved"); 959 | if (StrContains(info, "admin", false) > -1) 960 | Command_SubMenu(param1, "listdecal_admin"); 961 | else 962 | Command_SubMenu(param1, "listdecal"); 963 | } 964 | else 965 | Command_OptionsMenu(param1, info); 966 | } 967 | } 968 | 969 | /* If the menu was cancelled, check for info and redisplay previous menu. */ 970 | else if (action == MenuAction_Cancel) { 971 | 972 | if (param2 == MenuCancel_ExitBack) { 973 | 974 | GetMenuItem(submenu, 0, info, sizeof(info)); 975 | if (StrContains(info, "admin", false) > -1) { 976 | FakeClientCommand(param1, "sm_decalmenu admin"); 977 | } 978 | else { 979 | Command_DecalMenu(param1, -1); 980 | } 981 | } 982 | } 983 | /* If the menu has ended, destroy it */ 984 | else if (action == MenuAction_End) { 985 | 986 | CloseHandle(submenu); 987 | } 988 | } 989 | 990 | 991 | 992 | /***************************************************************** 993 | 994 | 995 | P L U G I N F U N C T I O N S 996 | 997 | 998 | *****************************************************************/ 999 | 1000 | public NextPosFromTrie(Handle:trie, String:key[]) { 1001 | 1002 | new pos = 1; 1003 | if (GetTrieValue(trie, key, pos)) { 1004 | pos++; 1005 | } 1006 | SetTrieValue(trie, key, pos); 1007 | return pos; 1008 | } 1009 | 1010 | Command_SubMenu(client, String:info[]) { 1011 | 1012 | new Handle:submenu = CreateMenu(SubMenuHandler); 1013 | new DecalPos = GetConVarInt(md_pos); 1014 | decl String:buffer[128]; 1015 | 1016 | if (strcmp(info, "savedecal") == 0) { 1017 | 1018 | Format(buffer, sizeof(buffer), "%T", "save_decal_title", client); 1019 | SetMenuTitle(submenu, buffer); 1020 | Format(buffer, sizeof(buffer), "%T", "all", client); 1021 | AddMenuItem(submenu, "savedecal_all", buffer); 1022 | Format(buffer, sizeof(buffer), "%T", "by_aim", client); 1023 | AddMenuItem(submenu, "savedecal_aim", buffer); 1024 | Format(buffer, sizeof(buffer), "%T", "by_id", client); 1025 | AddMenuItem(submenu, "savedecal_id", buffer); 1026 | Format(buffer, sizeof(buffer), "%T", "by_name", client); 1027 | AddMenuItem(submenu, "savedecal_name", buffer); 1028 | Format(buffer, sizeof(buffer), "%T", "last_painted", client); 1029 | AddMenuItem(submenu, "savedecal_last", buffer); 1030 | } 1031 | else if (strcmp(info, "savedecal_admin") == 0) { 1032 | 1033 | Format(buffer, sizeof(buffer), "%T", "save_decal_title", client); 1034 | SetMenuTitle(submenu, buffer); 1035 | Format(buffer, sizeof(buffer), "%T", "all", client); 1036 | AddMenuItem(submenu, "savedecal_all_admin", buffer); 1037 | Format(buffer, sizeof(buffer), "%T", "by_aim", client); 1038 | AddMenuItem(submenu, "savedecal_aim_admin", buffer); 1039 | Format(buffer, sizeof(buffer), "%T", "by_id", client); 1040 | AddMenuItem(submenu, "savedecal_id_admin", buffer); 1041 | Format(buffer, sizeof(buffer), "%T", "by_name", client); 1042 | AddMenuItem(submenu, "savedecal_name_admin", buffer); 1043 | Format(buffer, sizeof(buffer), "%T", "last_painted", client); 1044 | AddMenuItem(submenu, "savedecal_last_admin", buffer); 1045 | } 1046 | else if (strcmp(info, "removedecal") == 0) { 1047 | 1048 | Format(buffer, sizeof(buffer), "%T", "remove_decal_title", client); 1049 | SetMenuTitle(submenu, buffer); 1050 | Format(buffer, sizeof(buffer), "%T", "all", client); 1051 | AddMenuItem(submenu, "removedecal_all", buffer); 1052 | Format(buffer, sizeof(buffer), "%T", "by_aim", client); 1053 | AddMenuItem(submenu, "removedecal_aim", buffer); 1054 | Format(buffer, sizeof(buffer), "%T", "by_id", client); 1055 | AddMenuItem(submenu, "removedecal_id", buffer); 1056 | Format(buffer, sizeof(buffer), "%T", "by_name", client); 1057 | AddMenuItem(submenu, "removedecal_name", buffer); 1058 | Format(buffer, sizeof(buffer), "%T", "last_painted", client); 1059 | AddMenuItem(submenu, "removedecal_last", buffer); 1060 | } 1061 | else if (strcmp(info, "removedecal_admin") == 0) { 1062 | 1063 | Format(buffer, sizeof(buffer), "%T", "remove_decal_title", client); 1064 | SetMenuTitle(submenu, buffer); 1065 | Format(buffer, sizeof(buffer), "%T", "all", client); 1066 | AddMenuItem(submenu, "removedecal_all_admin", buffer); 1067 | Format(buffer, sizeof(buffer), "%T", "by_aim", client); 1068 | AddMenuItem(submenu, "removedecal_aim_admin", buffer); 1069 | Format(buffer, sizeof(buffer), "%T", "by_id", client); 1070 | AddMenuItem(submenu, "removedecal_id_admin", buffer); 1071 | Format(buffer, sizeof(buffer), "%T", "by_name", client); 1072 | AddMenuItem(submenu, "removedecal_name_admin", buffer); 1073 | Format(buffer, sizeof(buffer), "%T", "last_painted", client); 1074 | AddMenuItem(submenu, "removedecal_last_admin", buffer); 1075 | } 1076 | else if (strcmp(info, "listdecal") == 0) { 1077 | 1078 | Format(buffer, sizeof(buffer), "%T", "list_decal_title", client); 1079 | SetMenuTitle(submenu, buffer); 1080 | Format(buffer, sizeof(buffer), "%T", "all_list", client); 1081 | AddMenuItem(submenu, "listdecal_all", buffer); 1082 | Format(buffer, sizeof(buffer), "%T", "by_aim", client); 1083 | AddMenuItem(submenu, "listdecal_aim", buffer); 1084 | if (DecalPos) { 1085 | Format(buffer, sizeof(buffer), "%T", "by_id", client); 1086 | AddMenuItem(submenu, "listdecal_id", buffer); 1087 | } 1088 | Format(buffer, sizeof(buffer), "%T", "by_name", client); 1089 | AddMenuItem(submenu, "listdecal_name", buffer); 1090 | Format(buffer, sizeof(buffer), "%T", "last_painted", client); 1091 | AddMenuItem(submenu, "listdecal_last", buffer); 1092 | Format(buffer, sizeof(buffer), "%T", "map", client); 1093 | AddMenuItem(submenu, "listdecal_map", buffer); 1094 | Format(buffer, sizeof(buffer), "%T", "saved", client); 1095 | AddMenuItem(submenu, "listdecal_saved", buffer); 1096 | } 1097 | else if (strcmp(info, "listdecal_admin") == 0) { 1098 | 1099 | Format(buffer, sizeof(buffer), "%T", "list_decal_title", client); 1100 | SetMenuTitle(submenu, buffer); 1101 | Format(buffer, sizeof(buffer), "%T", "all_list", client); 1102 | AddMenuItem(submenu, "listdecal_all_admin", buffer); 1103 | Format(buffer, sizeof(buffer), "%T", "by_aim", client); 1104 | AddMenuItem(submenu, "listdecal_aim_admin", buffer); 1105 | if (DecalPos) { 1106 | Format(buffer, sizeof(buffer), "%T", "by_id", client); 1107 | AddMenuItem(submenu, "listdecal_id_admin", buffer); 1108 | } 1109 | Format(buffer, sizeof(buffer), "%T", "by_name", client); 1110 | AddMenuItem(submenu, "listdecal_name_admin", buffer); 1111 | Format(buffer, sizeof(buffer), "%T", "last_painted", client); 1112 | AddMenuItem(submenu, "listdecal_last_admin", buffer); 1113 | Format(buffer, sizeof(buffer), "%T", "map", client); 1114 | AddMenuItem(submenu, "listdecal_map_admin", buffer); 1115 | Format(buffer, sizeof(buffer), "%T", "saved", client); 1116 | AddMenuItem(submenu, "listdecal_saved_admin", buffer); 1117 | } 1118 | 1119 | SetMenuExitBackButton(submenu, true); 1120 | SetMenuExitButton(submenu, true); 1121 | DisplayMenu(submenu, client, MENU_TIME_FOREVER); 1122 | } 1123 | 1124 | public Command_OptionsMenu(client, String:info[]) { 1125 | 1126 | new Handle:optionsmenu = CreateMenu(OptionsMenuHandler); 1127 | decl String:id[64]; 1128 | decl String:buffer[128]; 1129 | decl String:decalName[128]; 1130 | decl size; 1131 | Format(buffer, sizeof(buffer), "%T", "options_menu_title", client); 1132 | SetMenuTitle(optionsmenu, buffer); 1133 | if (StrContains(info, "id", false) > -1) { 1134 | size = GetArraySize(adt_decal_id); 1135 | for (new i=0; i7) { 1139 | IntToString(i+1, id, sizeof(id)); 1140 | StrCat(decalName, sizeof(decalName), " ("); 1141 | StrCat(decalName, sizeof(decalName), id); 1142 | StrCat(decalName, sizeof(decalName), ")"); 1143 | } 1144 | AddMenuItem(optionsmenu, info, decalName); 1145 | } 1146 | } 1147 | else { 1148 | size = GetArraySize(adt_decal_names); 1149 | for (new i=0; i7) { 1152 | IntToString(i+1, id, sizeof(id)); 1153 | StrCat(decalName, sizeof(decalName), " ("); 1154 | StrCat(decalName, sizeof(decalName), id); 1155 | StrCat(decalName, sizeof(decalName), ")"); 1156 | } 1157 | AddMenuItem(optionsmenu, info, decalName); 1158 | } 1159 | } 1160 | if (size == 0) { 1161 | PrintToChat(client, "%t", "no_decals_in_file", COLOR_DEFAULT, COLOR_GREEN, mapName, COLOR_DEFAULT); 1162 | if (StrContains(info, "admin", false) > -1) 1163 | FakeClientCommand(client, "sm_decalmenu admin"); 1164 | else 1165 | Command_DecalMenu(client, -1); 1166 | } 1167 | else { 1168 | SetMenuExitBackButton(optionsmenu, true); 1169 | SetMenuExitButton(optionsmenu, true); 1170 | DisplayMenu(optionsmenu, client, MENU_TIME_FOREVER); 1171 | } 1172 | } 1173 | 1174 | public OptionsMenuHandler(Handle:optionsmenu, MenuAction:action, param1, param2) { 1175 | 1176 | decl String:info[64]; 1177 | decl String:name[64]; 1178 | decl flag; 1179 | 1180 | /* If an option was selected, tell the client about the item. */ 1181 | if (action == MenuAction_Select) { 1182 | 1183 | new bool:found = GetMenuItem(optionsmenu, param2, info, sizeof(info), flag, name, sizeof(name)); 1184 | if (found) { 1185 | if (StrContains(info, "paintdecal") > -1) { 1186 | FakeClientCommand(param1, "say /paintdecal %s", name); 1187 | if (StrContains(info, "admin", false) > -1) 1188 | Command_OptionsMenu(param1, "paintdecal_admin"); 1189 | else 1190 | Command_OptionsMenu(param1, "paintdecal"); 1191 | } 1192 | else if (StrContains(info, "savedecal_id") > -1) { 1193 | FakeClientCommand(param1, "say /savedecal %d", param2+1); 1194 | if (StrContains(info, "admin", false) > -1) 1195 | Command_OptionsMenu(param1, "savedecal_id_admin"); 1196 | else 1197 | Command_OptionsMenu(param1, "savedecal_id"); 1198 | } 1199 | else if (StrContains(info, "savedecal_name") > -1) { 1200 | FakeClientCommand(param1, "say /savedecal %s", name); 1201 | if (StrContains(info, "admin", false) > -1) 1202 | Command_OptionsMenu(param1, "savedecal_name_admin"); 1203 | else 1204 | Command_OptionsMenu(param1, "savedecal_name"); 1205 | } 1206 | else if (StrContains(info, "removedecal_id") > -1) { 1207 | FakeClientCommand(param1, "say /removedecal %d", param2+1); 1208 | if (StrContains(info, "admin", false) > -1) 1209 | Command_OptionsMenu(param1, "removedecal_id_admin"); 1210 | else 1211 | Command_OptionsMenu(param1, "removedecal_id"); 1212 | } 1213 | else if (StrContains(info, "removedecal_name") > -1) { 1214 | FakeClientCommand(param1, "say /removedecal %s", name); 1215 | if (StrContains(info, "admin", false) > -1) 1216 | Command_OptionsMenu(param1, "removedecal_name_admin"); 1217 | else 1218 | Command_OptionsMenu(param1, "removedecal_name"); 1219 | } 1220 | else if (StrContains(info, "listdecal_id") > -1) { 1221 | FakeClientCommand(param1, "say /listdecal %d", param2+1); 1222 | if (StrContains(info, "admin", false) > -1) 1223 | Command_OptionsMenu(param1, "listdecal_id_admin"); 1224 | else 1225 | Command_OptionsMenu(param1, "listdecal_id"); 1226 | } 1227 | else if (StrContains(info, "listdecal_name") > -1) { 1228 | FakeClientCommand(param1, "say /listdecal %s", name); 1229 | if (StrContains(info, "admin", false) > -1) 1230 | Command_OptionsMenu(param1, "listdecal_name_admin"); 1231 | else 1232 | Command_OptionsMenu(param1, "listdecal_name"); 1233 | } 1234 | } 1235 | } 1236 | 1237 | /* If the menu was cancelled, check for info and redisplay previous menu. */ 1238 | else if (action == MenuAction_Cancel) { 1239 | 1240 | if (param2 == MenuCancel_ExitBack) { 1241 | 1242 | GetMenuItem(optionsmenu, 0, info, sizeof(info)); 1243 | if (StrContains(info, "paintdecal", false) > -1 && StrContains(info, "admin", false) > -1) { 1244 | FakeClientCommand(param1, "sm_decalmenu admin"); 1245 | } 1246 | else if (StrContains(info, "paintdecal", false) > -1) { 1247 | Command_DecalMenu(param1, -1); 1248 | } 1249 | 1250 | if (StrContains(info, "savedecal", false) > -1 && StrContains(info, "admin", false) > -1) { 1251 | Command_SubMenu(param1, "savedecal_admin"); 1252 | } 1253 | else if (StrContains(info, "savedecal", false) > -1) { 1254 | Command_SubMenu(param1, "savedecal"); 1255 | } 1256 | 1257 | if (StrContains(info, "removedecal", false) > -1 && StrContains(info, "admin", false) > -1) { 1258 | Command_SubMenu(param1, "removedecal_admin"); 1259 | } 1260 | else if (StrContains(info, "removedecal", false) > -1) { 1261 | Command_SubMenu(param1, "removedecal"); 1262 | } 1263 | 1264 | if (StrContains(info, "listdecal", false) > -1 && StrContains(info, "admin", false) > -1) { 1265 | Command_SubMenu(param1, "listdecal_admin"); 1266 | } 1267 | else if (StrContains(info, "listdecal", false) > -1) { 1268 | Command_SubMenu(param1, "listdecal"); 1269 | } 1270 | } 1271 | } 1272 | /* If the menu has ended, destroy it */ 1273 | else if (action == MenuAction_End) 1274 | { 1275 | CloseHandle(optionsmenu); 1276 | } 1277 | } 1278 | 1279 | public bool:ReadDecals(client, mode) { 1280 | 1281 | decl String:buffer[PLATFORM_MAX_PATH]; 1282 | decl String:file[PLATFORM_MAX_PATH]; 1283 | decl String:download[PLATFORM_MAX_PATH]; 1284 | decl Handle:kv; 1285 | decl Handle:vtf; 1286 | 1287 | // Read Decal config File 1288 | if (mode == READ) { 1289 | 1290 | kv = CreateKeyValues("Decals"); 1291 | FileToKeyValues(kv, path_decals); 1292 | 1293 | if (!KvGotoFirstSubKey(kv)) { 1294 | 1295 | LogMessage("CFG File not found: %s", file); 1296 | CloseHandle(kv); 1297 | return false; 1298 | } 1299 | do { 1300 | 1301 | KvGetSectionName(kv, buffer, sizeof(buffer)); 1302 | PushArrayString(adt_decal_names, buffer); 1303 | KvGetString(kv, "path", buffer, sizeof(buffer)); 1304 | PushArrayString(adt_decal_paths, buffer); 1305 | new precacheId = PrecacheDecal(buffer, true); 1306 | PushArrayCell(adt_decal_precache, precacheId); 1307 | decl String:decalpath[PLATFORM_MAX_PATH]; 1308 | Format(decalpath, sizeof(decalpath), buffer); 1309 | Format(download, sizeof(download), "materials/%s.vmt", buffer); 1310 | AddFileToDownloadsTable(download); 1311 | vtf = CreateKeyValues("LightmappedGeneric"); 1312 | FileToKeyValues(vtf, download); 1313 | KvGetString(vtf, "$basetexture", buffer, sizeof(buffer), buffer); 1314 | CloseHandle(vtf); 1315 | Format(download, sizeof(download), "materials/%s.vtf", buffer); 1316 | AddFileToDownloadsTable(download); 1317 | } while (KvGotoNextKey(kv)); 1318 | CloseHandle(kv); 1319 | } 1320 | // Read Map config File 1321 | kv = CreateKeyValues("Positions"); 1322 | FileToKeyValues(kv, path_mapdecals); 1323 | 1324 | if (!KvGotoFirstSubKey(kv)) { 1325 | 1326 | if (mode == READ) { 1327 | LogMessage("CFG File for Map %s not found", mapName); 1328 | } 1329 | else { 1330 | ReplyToCommand(client, "%t", "cfg_file_not_found", COLOR_DEFAULT, COLOR_GREEN, COLOR_DEFAULT, COLOR_GREEN, mapName, COLOR_DEFAULT); 1331 | } 1332 | 1333 | CloseHandle(kv); 1334 | return false; 1335 | } 1336 | do { 1337 | KvGetSectionName(kv, buffer, sizeof(buffer)); 1338 | new id = FindStringInArray(adt_decal_names, buffer); 1339 | if (id != -1) { 1340 | 1341 | if (mode == LIST) { 1342 | ReplyToCommand(client, "%t", "list_decal", COLOR_DEFAULT, COLOR_GREEN, buffer); 1343 | } 1344 | 1345 | new Float:position[3]; 1346 | decl String:strpos[8]; 1347 | new n=1; 1348 | Format(strpos, sizeof(strpos), "pos%d", n); 1349 | KvGetVector(kv, strpos, position); 1350 | while (position[0] != 0 && position[1] != 0 && position[2] != 0) { 1351 | 1352 | if (mode == READ) { 1353 | PushArrayCell(adt_decal_id, id); 1354 | PushArrayArray(adt_decal_position, _:position); 1355 | } 1356 | else { 1357 | ReplyToCommand(client, "%t", "list_decal_id", COLOR_DEFAULT, COLOR_GREEN, n); 1358 | new DecalPos = GetConVarInt(md_pos); 1359 | if (DecalPos) 1360 | ReplyToCommand(client, "%t", "decal_position",COLOR_DEFAULT, COLOR_GREEN, position[0], position[1], position[2]); 1361 | } 1362 | n++; 1363 | Format(strpos, sizeof(strpos), "pos%d", n); 1364 | KvGetVector(kv, strpos, position); 1365 | } 1366 | } 1367 | } while (KvGotoNextKey(kv)); 1368 | CloseHandle(kv); 1369 | return true; 1370 | } 1371 | 1372 | TE_SetupBSPDecal(const Float:vecOrigin[3], entity, index) { 1373 | 1374 | TE_Start("BSP Decal"); 1375 | TE_WriteVector("m_vecOrigin",vecOrigin); 1376 | TE_WriteNum("m_nEntity",entity); 1377 | TE_WriteNum("m_nIndex",index); 1378 | } 1379 | 1380 | FindStringInArrayCase(Handle:array, const String:item[], bool:caseSensitive=true) { 1381 | 1382 | decl String:str[256]; 1383 | new size = GetArraySize(array); 1384 | for (new i=0; i