From deca18bc3da9013d2eef0affa24b88e4022ab63f Mon Sep 17 00:00:00 2001 From: Rushaway Date: Fri, 22 May 2026 11:42:25 +0200 Subject: [PATCH] feat(ci): Initial GA workflow support --- .github/dependabot.yml | 6 + .github/workflows/ci.yml | 90 ++ .gitignore | 10 + .../sourcemod/scripting/entwatch_maker.sp | 822 +++++++++--------- entwatch_maker.smx | Bin 8903 -> 0 bytes sourceknight.yaml | 18 + 6 files changed, 535 insertions(+), 411 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .gitignore rename entwatch_maker.sp => addons/sourcemod/scripting/entwatch_maker.sp (97%) delete mode 100644 entwatch_maker.smx create mode 100644 sourceknight.yaml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..120c689 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..106d720 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,90 @@ +name: CI + +on: [push, pull_request, workflow_dispatch] + +jobs: + build: + name: "Build" + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-24.04] + include: + - os: ubuntu-24.04 + steps: + - uses: actions/checkout@v6 + - name: Build sourcemod plugin + uses: maxime1907/action-sourceknight@v1 + with: + cmd: build + + - name: Create package + run: | + mkdir -p /tmp/package + cp -R .sourceknight/package/* /tmp/package + + - name: Upload build archive for test runners + uses: actions/upload-artifact@v7 + with: + name: ${{ runner.os }} + path: /tmp/package + + tag: + name: Tag + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' + + - uses: dev-drprasad/delete-tag-and-release@v1.1 + if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' + with: + delete_release: true + tag_name: latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - uses: rickstaa/action-create-tag@v1 + if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' + with: + tag: "latest" + github_token: ${{ secrets.GITHUB_TOKEN }} + + release: + name: Release + if: startsWith(github.ref, 'refs/tags/') || github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' + needs: [build, tag] + runs-on: ubuntu-latest + steps: + - name: Download artifacts + uses: actions/download-artifact@v8 + with: + name: ${{ runner.os }} + path: artifacts + + - name: Versioning + run: | + version="latest" + if [[ "${{ github.ref_type }}" == 'tag' ]]; then + version=`echo $GITHUB_REF | sed "s/refs\/tags\///"`; + fi + echo "RELEASE_VERSION=$version" >> $GITHUB_ENV + + - name: Package + run: | + cd artifacts + ls -Rall + tar -czf ../${{ github.event.repository.name }}-${{ env.RELEASE_VERSION }}.tar.gz . + cd .. + ls -la *.tar.gz + + - name: Release + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: '*.tar.gz' + tag: ${{ env.RELEASE_VERSION }} + file_glob: true + overwrite: true \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2a04272 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +build/ +release/ + +.DS_Store +.vscode + +*.smx +plugins/ +.sourceknight +.venv \ No newline at end of file diff --git a/entwatch_maker.sp b/addons/sourcemod/scripting/entwatch_maker.sp similarity index 97% rename from entwatch_maker.sp rename to addons/sourcemod/scripting/entwatch_maker.sp index 13f47ec..8b60340 100644 --- a/entwatch_maker.sp +++ b/addons/sourcemod/scripting/entwatch_maker.sp @@ -1,411 +1,411 @@ -#pragma newdecls required -#pragma semicolon 1 - -#include - -public Plugin myinfo = -{ - name = "EntWatch Config Maker", - author = "tilgep", - description = "Makes a basic EntWatch config for the current map.", - version = "1.3.1", - url = "https://github.com/tilgep/EntWatch-Maker" -}; - -enum Mode -{ - GFL = 0, - DarkerZ, - Mapea, -} - -#define MODE_INFO "0-none, 1-spam, 2-cd, 3-uses, 4-use w/ cd, 5-cd after uses, 6-counter stop@min, 7-counter stop@max" -#define DEFAULT_DIR_PERMS FPERM_O_READ|FPERM_O_EXEC|FPERM_G_READ|FPERM_G_EXEC|FPERM_U_READ|FPERM_U_WRITE|FPERM_U_EXEC -Mode mode; -char path[PLATFORM_MAX_PATH]; -char g_currentmap[128]; - -ArrayList weps; -ArrayList buts; -ArrayList filt; -ArrayList temp; -ArrayList math; - -ConVar dire; -ConVar style; - -public void OnPluginStart() -{ - weps = new ArrayList(); - buts = new ArrayList(); - filt = new ArrayList(); - temp = new ArrayList(); - math = new ArrayList(); - - dire = CreateConVar("ewmaker_path", "addons/sourcemod/configs/entwatch_maker", "Path to store generated configs in. Relative to csgo/", _, true, 0.0, true, 1.0); - dire.AddChangeHook(Cvar_Changed); - - style = CreateConVar("ewmaker_style", "1", "Options to include (0=GFL style, 1=DarkerZ Style, 2=Mapea MapTrack style)", _, true, 0.0, true, 2.0); - style.AddChangeHook(Cvar_Changed); - - RegConsoleCmd("sm_ewmake", Command_Make); - AutoExecConfig(); -} - -public void Cvar_Changed(ConVar cvar, const char[] oldVal, const char[] newVal) -{ - if(cvar == dire) - { - dire.GetString(path, PLATFORM_MAX_PATH); - if(!DirExists(path)) - { - if(!CreateDirectory(path, DEFAULT_DIR_PERMS)) - { - LogError("Failed to create directory %s", path); - } - else - { - LogMessage("Created directory %s", path); - } - } - Format(path, PLATFORM_MAX_PATH, "%s/%s.cfg", path, g_currentmap); - } - else if(cvar == style) - { - mode = view_as(style.IntValue); - } -} - -public void OnConfigsExecuted() -{ - mode = view_as(style.IntValue); - dire.GetString(path, PLATFORM_MAX_PATH); - if(!DirExists(path)) - { - if(!CreateDirectory(path, DEFAULT_DIR_PERMS)) - { - LogError("Failed to create directory %s", path); - } - else - { - LogMessage("Created directory %s", path); - } - } - char mapName[PLATFORM_MAX_PATH]; - GetCurrentMap(mapName, sizeof(mapName)); - Format(path, PLATFORM_MAX_PATH, "%s/%s.cfg", path, mapName); - strcopy(g_currentmap, sizeof(g_currentmap), mapName); -} - -public Action Command_Make(int client, int args) -{ - switch(LoadConfig()) - { - case 0: ReplyToCommand(client, "Failed to create config file %s", path); - case 1: ReplyToCommand(client, "No items found in the map!"); - case 2: ReplyToCommand(client, "Config created at %s", path); - } - return Plugin_Handled; -} - -/** - * Creates the basic entwatch config for the current map - * - * @return 0 = file failed to open - * 1 = No items found - * 2 = Items found and config made - */ -public int LoadConfig() -{ - weps.Clear(); - buts.Clear(); - filt.Clear(); - temp.Clear(); - math.Clear(); - - File file = OpenFile(path, "w"); - if(file==null) - { - LogError("Failed to create file %s", path); - return 0; - } - - EntityLumpEntry ent; - char class[64]; - char paren[64]; - char hammer[16]; - - // Find entities we might be interested in - for(int i = 0; i < EntityLump.Length(); i++) - { - ent = EntityLump.Get(i); - int cl = ent.GetNextKey("classname", class, 64); - if(cl == -1) continue; - - if(strncmp(class, "weapon_", 7) == 0) - { - ent.GetNextKey("hammerid", hammer, sizeof(hammer)); - if(hammer[0]!='\0') weps.Push(i); - } - else if(strncmp(class, "func_button", 11) == 0) - { - int parent = ent.GetNextKey("parentname", paren, sizeof(paren)); - if(parent != -1 && paren[0]!='\0') buts.Push(i); - } - else if(strncmp(class, "filter_activator_name", 21) == 0) - { - filt.Push(i); - } - else if(strncmp(class, "point_template", 14) == 0) - { - temp.Push(i); - } - - delete ent; - } - - if(weps.Length == 0) - { - delete file; - return 1; - } - - if(mode == Mapea) - { - file.WriteLine("\"%s\"\n{", g_currentmap); - } - else - { - file.WriteLine("\"entities\"\n{", g_currentmap); - } - - char key[64]; - char val[128]; - char targe[64]; - char bhammer[16]; - char filter[64]; - char filterid[16]; - char templatename[64]; - char output[5][32]; - bool knife; - bool gameui; - - EntityLumpEntry button, template; - int index = 0; - // Go through weapons - for(int i = 0; i < weps.Length; i++) - { - targe[0] = '\0'; - hammer[0] = '\0'; - bhammer[0] = '\0'; - filter[0] = '\0'; - filterid[0] = '\0'; - templatename[0] = '\0'; - knife = false; - gameui = false; - ent = EntityLump.Get(weps.Get(i)); - bool mapweapon = false; - - //Store properties we might want - for(int w = 0; w < ent.Length; w++) - { - ent.Get(w, key, 64, val, 128); - if(StrEqual(key, "classname")) knife = StrEqual(val, "weapon_knife"); - else if(StrEqual(key, "targetname"))strcopy(targe, sizeof(targe), val); - else if(StrEqual(key, "hammerid")) - { - strcopy(hammer, sizeof(hammer), val); - mapweapon = true; - } - else if(StrEqual(key, "OnPlayerPickup", false)) - { - ExplodeString(val, "", output, 5, 32, true); - if(StrEqual(output[1], "Activate")) gameui = true; - } - } - - if(!mapweapon) - { - delete ent; - continue; - } - - for(int b = gameui ? buts.Length : 0; b < buts.Length; b++) - { - button = EntityLump.Get(buts.Get(b)); - button.GetNextKey("parentname", paren, 64); - if(!StrEqual(paren, targe)) - { - delete button; - continue; - } - - button.GetNextKey("hammerid", bhammer, sizeof(bhammer)); - button.GetNextKey("filtername", filter, sizeof(filter)); - int fi = button.GetNextKey("OnPressed", val, sizeof(val)); - while(fi != -1) - { - ExplodeString(val, "", output, 5, 32, true); - if(StrEqual(output[1], "TestActivator")) break; - fi = button.GetNextKey("OnPressed", val, sizeof(val), fi); - } - - if(fi != -1) - { - EntityLumpEntry filterr; - char ftargetname[64]; - for(int f = 0; f < filt.Length; f++) - { - filterr = EntityLump.Get(filt.Get(f)); - filterr.GetNextKey("targetname", ftargetname, sizeof(ftargetname)); - if(!StrEqual(ftargetname, output[0])) continue; - - filterr.GetNextKey("filtername", filter, sizeof(filter)); - filterr.GetNextKey("hammerid", filterid, sizeof(filterid)); - break; - } - delete filterr; - } - - delete button; - } - - // find pt_spawner - if(mode == DarkerZ) - { - bool found; - for(int t = 0; t < temp.Length; t++) - { - if(found) break; - template = EntityLump.Get(temp.Get(t)); - for(int u = 0; u < template.Length; u++) - { - template.Get(u, key, 64, val, 128); - if(StrEqual(key, "targetname")) strcopy(templatename, sizeof(templatename), val); - else if(!found && strncmp(key, "Template", 8) == 0) - { - if(StrEqual(val, targe)) - { - found = true; - } - else //check wildcarding - { - int len = strlen(val); - if(val[len-1] == '*') - { - if(strncmp(val, targe, len-1) == 0) // matched wildcard - { - found = true; - } - } - } - } - } - - delete template; - } - if(!found) templatename[0] = '\0'; - } - - file.WriteLine("\t\"%d\"", index); - file.WriteLine("\t{"); - - switch(mode) - { - case GFL: - { - file.WriteLine("\t\t\"name\" \"%s\" //currently weapon targetname (change me)", targe); - file.WriteLine("\t\t\"shortname\" \"%s\" //currently weapon targetname (change me)", targe); - file.WriteLine("\t\t\"color\" \"{default}\" // Change me"); - file.WriteLine("\t\t"); - file.WriteLine("\t\t\"buttonclass\" \"%s\"", gameui ? "game_ui" : "func_button"); - file.WriteLine("\t\t"); - file.WriteLine("\t\t\"filtername\" \"%s\"", filter); - file.WriteLine("\t\t\"blockpickup\" \"false\""); - file.WriteLine("\t\t\"allowtransfer\" \"%s\"", knife ? "false" : "true"); - file.WriteLine("\t\t\"forcedrop\" \"%s\"", knife ? "false" : "true"); - file.WriteLine("\t\t\"chat\" \"true\""); - file.WriteLine("\t\t\"hud\" \"true\""); - file.WriteLine("\t\t\"hammerid\" \"%s\"", hammer); - file.WriteLine("\t\t"); - file.WriteLine("\t\t// [EntWatchMaker] Settings below may need changing."); - file.WriteLine("\t\t\"mode\" \"0\" // %s", MODE_INFO); - file.WriteLine("\t\t"); - file.WriteLine("\t\t\"cooldown\" \"0\" //mode = 2/4/5"); - file.WriteLine("\t\t\"maxuses\" \"0\" //mode = 3/4/5"); - file.WriteLine("\t\t\"mathid\" \"0\" //mode 6/7"); - file.WriteLine("\t\t"); - file.WriteLine("\t\t//\"buttonid\" \"%s\" //hammerid of a detected button", bhammer); - file.WriteLine("\t\t\"trigger\" \"0\""); - file.WriteLine("\t\t\"physbox\" \"false\""); - file.WriteLine("\t\t\"maxamount\" \"1\""); - } - case DarkerZ: - { - file.WriteLine("\t\t\"name\" \"%s\" //currently weapon targetname (change me)", targe); - file.WriteLine("\t\t\"shortname\" \"%s\" //currently weapon targetname (change me)", targe); - file.WriteLine("\t\t\"color\" \"{default}\" // Change me"); - file.WriteLine("\t\t"); - file.WriteLine("\t\t\"buttonclass\" \"%s\"", gameui ? "game_ui" : "func_button"); - file.WriteLine("\t\t\"buttonclass2\" \"\""); - file.WriteLine("\t\t"); - file.WriteLine("\t\t\"filtername\" \"%s\"", filter); - file.WriteLine("\t\t\"blockpickup\" \"false\""); - file.WriteLine("\t\t\"allowtransfer\" \"%s\"", knife ? "false" : "true"); - file.WriteLine("\t\t\"forcedrop\" \"%s\"", knife ? "false" : "true"); - file.WriteLine("\t\t"); - file.WriteLine("\t\t\"chat\" \"true\""); - file.WriteLine("\t\t\"chat_uses\" \"true\""); - file.WriteLine("\t\t\"hud\" \"true\""); - file.WriteLine("\t\t\"hammerid\" \"%s\"", hammer); - file.WriteLine("\t\t"); - file.WriteLine("\t\t// [EntWatchMaker] Settings below may need changing."); - file.WriteLine("\t\t\"mode\" \"0\" // %s", MODE_INFO); - file.WriteLine("\t\t\"mode2\" \"0\""); - file.WriteLine("\t\t"); - file.WriteLine("\t\t\"cooldown\" \"0\" //mode = 2/4/5"); - file.WriteLine("\t\t\"cooldown2\" \"0\" //mode2 = 2/4/5"); - file.WriteLine("\t\t\"maxuses\" \"0\" //mode = 3/4/5"); - file.WriteLine("\t\t\"maxuses2\" \"0\" //mode2 = 3/4/5"); - file.WriteLine("\t\t\"energyid\" \"0\" //mode = 6/7"); - file.WriteLine("\t\t\"energyid2\" \"0\" //mode2 = 6/7"); - file.WriteLine("\t\t"); - file.WriteLine("\t\t//\"buttonid\" \"%s\" //hammerid of a detected button", bhammer); - file.WriteLine("\t\t//\"buttonid2\" \"\""); - file.WriteLine("\t\t\"trigger\" \"0\""); - file.WriteLine("\t\t\"physbox\" \"false\""); - file.WriteLine("\t\t"); - file.WriteLine("\t\t\"pt_spawner\" \"%s\"", templatename); - file.WriteLine("\t\t\"use_priority\" \"true\""); - } - case Mapea: - { - file.WriteLine("\t\t\"hammerid\" \"%s\"", hammer); - file.WriteLine("\t\t\"name\" \"%s\" //currently weapon targetname (change me)", targe); - file.WriteLine("\t\t\"shortname\" \"%s\" //currently weapon targetname (change me)", targe); - file.WriteLine("\t\t\"color\" \"{WHITE}\" // Change me"); - file.WriteLine("\t\t\"glowcolor\" \"255 255 255 255\" // Change me"); - file.WriteLine("\t\t\"maxamount\" \"\""); - file.WriteLine("\t\t"); - file.WriteLine("\t\t\"buttonclass\" \"%s\"", gameui ? "game_ui" : "func_button"); - file.WriteLine("\t\t\"filterid\" \"%s\"", filterid); - file.WriteLine("\t\t\"passive\" \"\""); - file.WriteLine("\t\t\"blockpickup\" \"\""); - file.WriteLine("\t\t\"forcedrop\" \"true\""); - file.WriteLine("\t\t\"maxuses\" \"-1\""); - file.WriteLine("\t\t\"cooldown\" \"\""); - file.WriteLine("\t\t\"ignoredactions\" \"\""); - file.WriteLine("\t\t"); - file.WriteLine("\t\t\"chat\" \"true\""); - file.WriteLine("\t\t\"hud\" \"true\""); - } - } - - file.WriteLine("\t}"); - index++; - } - file.WriteLine("}"); - delete ent; - delete file; - return 2; -} +#pragma newdecls required +#pragma semicolon 1 + +#include + +public Plugin myinfo = +{ + name = "EntWatch Config Maker", + author = "tilgep", + description = "Makes a basic EntWatch config for the current map.", + version = "1.3.1", + url = "https://github.com/tilgep/EntWatch-Maker" +}; + +enum Mode +{ + GFL = 0, + DarkerZ, + Mapea, +} + +#define MODE_INFO "0-none, 1-spam, 2-cd, 3-uses, 4-use w/ cd, 5-cd after uses, 6-counter stop@min, 7-counter stop@max" +#define DEFAULT_DIR_PERMS FPERM_O_READ|FPERM_O_EXEC|FPERM_G_READ|FPERM_G_EXEC|FPERM_U_READ|FPERM_U_WRITE|FPERM_U_EXEC +Mode mode; +char path[PLATFORM_MAX_PATH]; +char g_currentmap[128]; + +ArrayList weps; +ArrayList buts; +ArrayList filt; +ArrayList temp; +ArrayList math; + +ConVar dire; +ConVar style; + +public void OnPluginStart() +{ + weps = new ArrayList(); + buts = new ArrayList(); + filt = new ArrayList(); + temp = new ArrayList(); + math = new ArrayList(); + + dire = CreateConVar("ewmaker_path", "addons/sourcemod/configs/entwatch_maker", "Path to store generated configs in. Relative to csgo/", _, true, 0.0, true, 1.0); + dire.AddChangeHook(Cvar_Changed); + + style = CreateConVar("ewmaker_style", "1", "Options to include (0=GFL style, 1=DarkerZ Style, 2=Mapea MapTrack style)", _, true, 0.0, true, 2.0); + style.AddChangeHook(Cvar_Changed); + + RegConsoleCmd("sm_ewmake", Command_Make); + AutoExecConfig(); +} + +public void Cvar_Changed(ConVar cvar, const char[] oldVal, const char[] newVal) +{ + if(cvar == dire) + { + dire.GetString(path, PLATFORM_MAX_PATH); + if(!DirExists(path)) + { + if(!CreateDirectory(path, DEFAULT_DIR_PERMS)) + { + LogError("Failed to create directory %s", path); + } + else + { + LogMessage("Created directory %s", path); + } + } + Format(path, PLATFORM_MAX_PATH, "%s/%s.cfg", path, g_currentmap); + } + else if(cvar == style) + { + mode = view_as(style.IntValue); + } +} + +public void OnConfigsExecuted() +{ + mode = view_as(style.IntValue); + dire.GetString(path, PLATFORM_MAX_PATH); + if(!DirExists(path)) + { + if(!CreateDirectory(path, DEFAULT_DIR_PERMS)) + { + LogError("Failed to create directory %s", path); + } + else + { + LogMessage("Created directory %s", path); + } + } + char mapName[PLATFORM_MAX_PATH]; + GetCurrentMap(mapName, sizeof(mapName)); + Format(path, PLATFORM_MAX_PATH, "%s/%s.cfg", path, mapName); + strcopy(g_currentmap, sizeof(g_currentmap), mapName); +} + +public Action Command_Make(int client, int args) +{ + switch(LoadConfig()) + { + case 0: ReplyToCommand(client, "Failed to create config file %s", path); + case 1: ReplyToCommand(client, "No items found in the map!"); + case 2: ReplyToCommand(client, "Config created at %s", path); + } + return Plugin_Handled; +} + +/** + * Creates the basic entwatch config for the current map + * + * @return 0 = file failed to open + * 1 = No items found + * 2 = Items found and config made + */ +public int LoadConfig() +{ + weps.Clear(); + buts.Clear(); + filt.Clear(); + temp.Clear(); + math.Clear(); + + File file = OpenFile(path, "w"); + if(file==null) + { + LogError("Failed to create file %s", path); + return 0; + } + + EntityLumpEntry ent; + char class[64]; + char paren[64]; + char hammer[16]; + + // Find entities we might be interested in + for(int i = 0; i < EntityLump.Length(); i++) + { + ent = EntityLump.Get(i); + int cl = ent.GetNextKey("classname", class, 64); + if(cl == -1) continue; + + if(strncmp(class, "weapon_", 7) == 0) + { + ent.GetNextKey("hammerid", hammer, sizeof(hammer)); + if(hammer[0]!='\0') weps.Push(i); + } + else if(strncmp(class, "func_button", 11) == 0) + { + int parent = ent.GetNextKey("parentname", paren, sizeof(paren)); + if(parent != -1 && paren[0]!='\0') buts.Push(i); + } + else if(strncmp(class, "filter_activator_name", 21) == 0) + { + filt.Push(i); + } + else if(strncmp(class, "point_template", 14) == 0) + { + temp.Push(i); + } + + delete ent; + } + + if(weps.Length == 0) + { + delete file; + return 1; + } + + if(mode == Mapea) + { + file.WriteLine("\"%s\"\n{", g_currentmap); + } + else + { + file.WriteLine("\"entities\"\n{", g_currentmap); + } + + char key[64]; + char val[128]; + char targe[64]; + char bhammer[16]; + char filter[64]; + char filterid[16]; + char templatename[64]; + char output[5][32]; + bool knife; + bool gameui; + + EntityLumpEntry button, template; + int index = 0; + // Go through weapons + for(int i = 0; i < weps.Length; i++) + { + targe[0] = '\0'; + hammer[0] = '\0'; + bhammer[0] = '\0'; + filter[0] = '\0'; + filterid[0] = '\0'; + templatename[0] = '\0'; + knife = false; + gameui = false; + ent = EntityLump.Get(weps.Get(i)); + bool mapweapon = false; + + //Store properties we might want + for(int w = 0; w < ent.Length; w++) + { + ent.Get(w, key, 64, val, 128); + if(StrEqual(key, "classname")) knife = StrEqual(val, "weapon_knife"); + else if(StrEqual(key, "targetname"))strcopy(targe, sizeof(targe), val); + else if(StrEqual(key, "hammerid")) + { + strcopy(hammer, sizeof(hammer), val); + mapweapon = true; + } + else if(StrEqual(key, "OnPlayerPickup", false)) + { + ExplodeString(val, "", output, 5, 32, true); + if(StrEqual(output[1], "Activate")) gameui = true; + } + } + + if(!mapweapon) + { + delete ent; + continue; + } + + for(int b = gameui ? buts.Length : 0; b < buts.Length; b++) + { + button = EntityLump.Get(buts.Get(b)); + button.GetNextKey("parentname", paren, 64); + if(!StrEqual(paren, targe)) + { + delete button; + continue; + } + + button.GetNextKey("hammerid", bhammer, sizeof(bhammer)); + button.GetNextKey("filtername", filter, sizeof(filter)); + int fi = button.GetNextKey("OnPressed", val, sizeof(val)); + while(fi != -1) + { + ExplodeString(val, "", output, 5, 32, true); + if(StrEqual(output[1], "TestActivator")) break; + fi = button.GetNextKey("OnPressed", val, sizeof(val), fi); + } + + if(fi != -1) + { + EntityLumpEntry filterr; + char ftargetname[64]; + for(int f = 0; f < filt.Length; f++) + { + filterr = EntityLump.Get(filt.Get(f)); + filterr.GetNextKey("targetname", ftargetname, sizeof(ftargetname)); + if(!StrEqual(ftargetname, output[0])) continue; + + filterr.GetNextKey("filtername", filter, sizeof(filter)); + filterr.GetNextKey("hammerid", filterid, sizeof(filterid)); + break; + } + delete filterr; + } + + delete button; + } + + // find pt_spawner + if(mode == DarkerZ) + { + bool found; + for(int t = 0; t < temp.Length; t++) + { + if(found) break; + template = EntityLump.Get(temp.Get(t)); + for(int u = 0; u < template.Length; u++) + { + template.Get(u, key, 64, val, 128); + if(StrEqual(key, "targetname")) strcopy(templatename, sizeof(templatename), val); + else if(!found && strncmp(key, "Template", 8) == 0) + { + if(StrEqual(val, targe)) + { + found = true; + } + else //check wildcarding + { + int len = strlen(val); + if(val[len-1] == '*') + { + if(strncmp(val, targe, len-1) == 0) // matched wildcard + { + found = true; + } + } + } + } + } + + delete template; + } + if(!found) templatename[0] = '\0'; + } + + file.WriteLine("\t\"%d\"", index); + file.WriteLine("\t{"); + + switch(mode) + { + case GFL: + { + file.WriteLine("\t\t\"name\" \"%s\" //currently weapon targetname (change me)", targe); + file.WriteLine("\t\t\"shortname\" \"%s\" //currently weapon targetname (change me)", targe); + file.WriteLine("\t\t\"color\" \"{default}\" // Change me"); + file.WriteLine("\t\t"); + file.WriteLine("\t\t\"buttonclass\" \"%s\"", gameui ? "game_ui" : "func_button"); + file.WriteLine("\t\t"); + file.WriteLine("\t\t\"filtername\" \"%s\"", filter); + file.WriteLine("\t\t\"blockpickup\" \"false\""); + file.WriteLine("\t\t\"allowtransfer\" \"%s\"", knife ? "false" : "true"); + file.WriteLine("\t\t\"forcedrop\" \"%s\"", knife ? "false" : "true"); + file.WriteLine("\t\t\"chat\" \"true\""); + file.WriteLine("\t\t\"hud\" \"true\""); + file.WriteLine("\t\t\"hammerid\" \"%s\"", hammer); + file.WriteLine("\t\t"); + file.WriteLine("\t\t// [EntWatchMaker] Settings below may need changing."); + file.WriteLine("\t\t\"mode\" \"0\" // %s", MODE_INFO); + file.WriteLine("\t\t"); + file.WriteLine("\t\t\"cooldown\" \"0\" //mode = 2/4/5"); + file.WriteLine("\t\t\"maxuses\" \"0\" //mode = 3/4/5"); + file.WriteLine("\t\t\"mathid\" \"0\" //mode 6/7"); + file.WriteLine("\t\t"); + file.WriteLine("\t\t//\"buttonid\" \"%s\" //hammerid of a detected button", bhammer); + file.WriteLine("\t\t\"trigger\" \"0\""); + file.WriteLine("\t\t\"physbox\" \"false\""); + file.WriteLine("\t\t\"maxamount\" \"1\""); + } + case DarkerZ: + { + file.WriteLine("\t\t\"name\" \"%s\" //currently weapon targetname (change me)", targe); + file.WriteLine("\t\t\"shortname\" \"%s\" //currently weapon targetname (change me)", targe); + file.WriteLine("\t\t\"color\" \"{default}\" // Change me"); + file.WriteLine("\t\t"); + file.WriteLine("\t\t\"buttonclass\" \"%s\"", gameui ? "game_ui" : "func_button"); + file.WriteLine("\t\t\"buttonclass2\" \"\""); + file.WriteLine("\t\t"); + file.WriteLine("\t\t\"filtername\" \"%s\"", filter); + file.WriteLine("\t\t\"blockpickup\" \"false\""); + file.WriteLine("\t\t\"allowtransfer\" \"%s\"", knife ? "false" : "true"); + file.WriteLine("\t\t\"forcedrop\" \"%s\"", knife ? "false" : "true"); + file.WriteLine("\t\t"); + file.WriteLine("\t\t\"chat\" \"true\""); + file.WriteLine("\t\t\"chat_uses\" \"true\""); + file.WriteLine("\t\t\"hud\" \"true\""); + file.WriteLine("\t\t\"hammerid\" \"%s\"", hammer); + file.WriteLine("\t\t"); + file.WriteLine("\t\t// [EntWatchMaker] Settings below may need changing."); + file.WriteLine("\t\t\"mode\" \"0\" // %s", MODE_INFO); + file.WriteLine("\t\t\"mode2\" \"0\""); + file.WriteLine("\t\t"); + file.WriteLine("\t\t\"cooldown\" \"0\" //mode = 2/4/5"); + file.WriteLine("\t\t\"cooldown2\" \"0\" //mode2 = 2/4/5"); + file.WriteLine("\t\t\"maxuses\" \"0\" //mode = 3/4/5"); + file.WriteLine("\t\t\"maxuses2\" \"0\" //mode2 = 3/4/5"); + file.WriteLine("\t\t\"energyid\" \"0\" //mode = 6/7"); + file.WriteLine("\t\t\"energyid2\" \"0\" //mode2 = 6/7"); + file.WriteLine("\t\t"); + file.WriteLine("\t\t//\"buttonid\" \"%s\" //hammerid of a detected button", bhammer); + file.WriteLine("\t\t//\"buttonid2\" \"\""); + file.WriteLine("\t\t\"trigger\" \"0\""); + file.WriteLine("\t\t\"physbox\" \"false\""); + file.WriteLine("\t\t"); + file.WriteLine("\t\t\"pt_spawner\" \"%s\"", templatename); + file.WriteLine("\t\t\"use_priority\" \"true\""); + } + case Mapea: + { + file.WriteLine("\t\t\"hammerid\" \"%s\"", hammer); + file.WriteLine("\t\t\"name\" \"%s\" //currently weapon targetname (change me)", targe); + file.WriteLine("\t\t\"shortname\" \"%s\" //currently weapon targetname (change me)", targe); + file.WriteLine("\t\t\"color\" \"{WHITE}\" // Change me"); + file.WriteLine("\t\t\"glowcolor\" \"255 255 255 255\" // Change me"); + file.WriteLine("\t\t\"maxamount\" \"\""); + file.WriteLine("\t\t"); + file.WriteLine("\t\t\"buttonclass\" \"%s\"", gameui ? "game_ui" : "func_button"); + file.WriteLine("\t\t\"filterid\" \"%s\"", filterid); + file.WriteLine("\t\t\"passive\" \"\""); + file.WriteLine("\t\t\"blockpickup\" \"\""); + file.WriteLine("\t\t\"forcedrop\" \"true\""); + file.WriteLine("\t\t\"maxuses\" \"-1\""); + file.WriteLine("\t\t\"cooldown\" \"\""); + file.WriteLine("\t\t\"ignoredactions\" \"\""); + file.WriteLine("\t\t"); + file.WriteLine("\t\t\"chat\" \"true\""); + file.WriteLine("\t\t\"hud\" \"true\""); + } + } + + file.WriteLine("\t}"); + index++; + } + file.WriteLine("}"); + delete ent; + delete file; + return 2; +} diff --git a/entwatch_maker.smx b/entwatch_maker.smx deleted file mode 100644 index 671938aff2288e3396c36b26c17a59a1db9427b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8903 zcmYM3by$;c`~No)P#OhkMv62j9h-o33JB5-L%K$XfS`i3bSb4Y3~9yyC8WE%o6#f2 zZ=cWeJiqU8-0%DSy3Xs``#g6a_pyJbprEC54+!jH0RVRW0D#9g005vHh`s&ShhzW% zJS?Zm0RXNv000q|AD93DN?51FN(;*&SZBm)2+QGE=fFzW6adh{1pxT4Tx10Rh+#9u zu)Jsu0Ayla9xHzv0DuBp*T!H%alFjyQio9f6o3(PBxxU7wi9)|9AA?9UEsa zr~lSHeO+y=ZEXL$vU0TW@c6%_t-XySHh|CC(vHv8-tnJK|DdD2^Z(G^+1BMh#s78t z_k^9Ji=~C*|Bky@{lh*p`zEA56kT39UrCsk*ff}4hB(H^g&;?^*?xm0%~c;%WgWx9%&1t?Tn=NVcSxr-X;YG5KFZGG_ zX^itiF`=%~q?7dZ-(APs&ge&lK8Y0PGUyDMY7Y%?LsKYfxCv&2arcRF_X|TKME^j+ zxcwEmA1G=>aLbHjcJ+sdaQAcHFWzGP}A%ev~yy zp)g$;$)CAdZ~pmO6Hm#(|2?vQ7@BaNj=la5~W=gJlpHMX3~ z^&Cq(+)Q@Ak~FK1==oyVTk*=TmuBwi>lb9*Id05`ocI)&oa6E7C~^6hv1yif^@}bB zco2~-8T46k8p8{Ja71u0Y{Qf#p0QuZ>skck;PIncrb+7=dspDSAKZD;x*d9oEoqP0 z>ofIyv;4NL8pachAzkVNzg9EXy*Flw^}k7|7qm+J>?i1n_qw9rE!2HSm&9B*Eis4l zgU9rsi8rsH>leflow@pb;!k~Qo0}I)-F{Z!sx{>>gcUVT@ndo|`it>`=IT|ovGrXk zs<~Myqt}Leb(d!sBl`xE8k{*>tB@|rlSXWeSL9s!{O>BwNk-4fZ)2V=`io|S{gIw# zSe-3x^Dhs!JAHcJ?jAFx2zq@;7s-X{vX#f)&0lo;&5d@D9%x)_VI}9!I=q*CrqHN7 zQQN>-X<77hQc1Z|!_Ma<)q&k)w%|ev2xmc7e;`-W`T0!1_(J=>kRol}AIH?mZ*smE zdb7CJ$%y4uIKl2b_qtuVZ!_BO*9c26?nz#Y1n2rXf80Tnp#{y?QmUl*1naj_g^-nB z=uLOJQjayxlMAIAu%ej+ShAJAkpJ1Q_s_H^xUw$<4%G<>>twR>hGRC|$=qS%w(o2f8gNtm?E~a-M=(YKiSVF0GRXc!E?n z0+b8YJd#)Egs#+>4HT_g1_$aUiFxYYE>;Hg*`D%0Aw+@I;PsUQe13$psCO}Pf!?b2 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