diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..b202c3b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.vscode/* +compiled/* diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index d9e0265c..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "sourcepawn.MainPath": "d:\\tf2server\\tf2\\tf\\addons\\sourcemod\\scripting\\robogithub\\berobot_handler.sp" -} \ No newline at end of file diff --git a/Todo.txt b/Todo.txt index 4a49fbfb..291f2117 100644 --- a/Todo.txt +++ b/Todo.txt @@ -3,4 +3,9 @@ TODO: Track what teams robots are on and move players to the non robot team when they join the server mid round Add menus for volunteers to select from a list of robots, taken robots will be grayed out or not shown in the list. First come first serve -Menu style will be 1 - > 9 with Scout, Soldier, Pyro, Demo, Heavy, Engineer, Medic, Spy, with each having different types to pick from. \ No newline at end of file +Menu style will be 1 - > 9 with Scout, Soldier, Pyro, Demo, Heavy, Engineer, Medic, Spy, with each having different types to pick from. + +storage: + - turn target into targetlist in storage plugin? ... maybe? + needed in command too so it would be duplicate code + unless command gets setup in main-plugin too? diff --git a/beagro.sp b/beagro.sp index 7d8e5691..da8a7390 100644 --- a/beagro.sp +++ b/beagro.sp @@ -2,6 +2,7 @@ #include #include #include +#include #define PLUGIN_VERSION "1.0" @@ -58,6 +59,13 @@ public OnPluginStart() SetFailState("Failed to create call: CBasePlayer::EquipWearable"); delete hTF2; + + AddRobot("Agro", "Pyro", CreateAgro); +} + +public void OnPluginEnd() +{ + RemoveRobot("Agro"); } public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max) @@ -185,45 +193,56 @@ public Action:Command_GiantPyro(client, args) decl String:arg1[32]; if (args < 1) { - arg1 = "@me"; + arg1[0] = '\0'; } else GetCmdArg(1, arg1, sizeof(arg1)); + + CreateAgro(client, arg1); + return Plugin_Handled; +} + +public void CreateAgro(int client, char target[32]) +{ + int targetFilter = 0; + if (target[0] == '\0') + { + target = "@me"; + targetFilter = COMMAND_FILTER_NO_IMMUNITY; + } + new String:target_name[MAX_TARGET_LENGTH]; new target_list[MAXPLAYERS], target_count; new bool:tn_is_ml; if ((target_count = ProcessTargetString( - arg1, + target, client, target_list, MAXPLAYERS, - COMMAND_FILTER_ALIVE|(args < 1 ? COMMAND_FILTER_NO_IMMUNITY : 0), + COMMAND_FILTER_ALIVE|targetFilter, target_name, sizeof(target_name), tn_is_ml)) <= 0) { ReplyToTargetError(client, target_count); - return Plugin_Handled; + return; } for (new i = 0; i < target_count; i++) { - if(!g_IsAgro[target_list[i]]){ - + if(!g_IsAgro[target_list[i]]){ + g_IsAgro[target_list[i]] = true; - MakeGiantPyro(target_list[i]); - - }else + MakeGiantPyro(target_list[i]); + } + else { g_IsAgro[target_list[i]] = false; PrintToChat(target_list[i], "1. You are no longer Giant Agro!"); TF2_RegeneratePlayer(target_list[i]); } - - } if (g_IsAgro[client])EmitSoundToAll(SPAWN); - return Plugin_Handled; } MakeGiantPyro(client) diff --git a/bearray.sp b/bearray.sp index c833271b..6f9307ad 100644 --- a/bearray.sp +++ b/bearray.sp @@ -2,6 +2,7 @@ #include #include #include +#include #define PLUGIN_VERSION "1.0" @@ -50,6 +51,13 @@ public OnPluginStart() SetFailState("Failed to create call: CBasePlayer::EquipWearable"); delete hTF2; + + AddRobot("Array Seven", "Medic", CreateArraySeven); +} + +public void OnPluginEnd() +{ + RemoveRobot("Array Seven"); } public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max) @@ -153,53 +161,63 @@ public Action:RemoveModel(client) AcceptEntityInput(client, "SetCustomModel"); } } - + public Action:Command_GiantMedic(client, args) { decl String:arg1[32]; if (args < 1) { - arg1 = "@me"; + arg1[0] = '\0'; } else GetCmdArg(1, arg1, sizeof(arg1)); + + CreateArraySeven(client, arg1); + return Plugin_Handled; +} + +public void CreateArraySeven(int client, char target[32]) +{ + int targetFilter = 0; + if (target[0] == '\0') + { + target = "@me"; + targetFilter = COMMAND_FILTER_NO_IMMUNITY; + } + new String:target_name[MAX_TARGET_LENGTH]; new target_list[MAXPLAYERS], target_count; new bool:tn_is_ml; if ((target_count = ProcessTargetString( - arg1, + target, client, target_list, MAXPLAYERS, - COMMAND_FILTER_ALIVE|(args < 1 ? COMMAND_FILTER_NO_IMMUNITY : 0), + COMMAND_FILTER_ALIVE|targetFilter, target_name, sizeof(target_name), tn_is_ml)) <= 0) { ReplyToTargetError(client, target_count); - return Plugin_Handled; + return; } for (new i = 0; i < target_count; i++) { + if(!g_IsArraySeven[target_list[i]]){ + + g_IsArraySeven[target_list[i]] = true; + MakeGiantMedic(target_list[i]); - - if(!g_IsArraySeven[target_list[i]]){ - - g_IsArraySeven[target_list[i]] = true; - MakeGiantMedic(target_list[i]); - - }else{ + }else{ - g_IsArraySeven[target_list[i]] = false; - PrintToChat(target_list[i], "1. You are no longer Giant ArraySeven!"); - TF2_RegeneratePlayer(target_list[i]); - } - + g_IsArraySeven[target_list[i]] = false; + PrintToChat(target_list[i], "1. You are no longer Giant ArraySeven!"); + TF2_RegeneratePlayer(target_list[i]); + } } if (g_IsArraySeven[client])EmitSoundToAll(SPAWN); - return Plugin_Handled; } - + MakeGiantMedic(client) { TF2_SetPlayerClass(client, TFClass_Medic); diff --git a/bebearded.sp b/bebearded.sp index 098abf7e..945aba61 100644 --- a/bebearded.sp +++ b/bebearded.sp @@ -2,6 +2,7 @@ #include #include #include +#include #define PLUGIN_VERSION "1.0" @@ -50,6 +51,13 @@ public OnPluginStart() SetFailState("Failed to create call: CBasePlayer::EquipWearable"); delete hTF2; + + AddRobot("Bearded Expense", "Heavy", CreateBearded); +} + +public void OnPluginEnd() +{ + RemoveRobot("Bearded Expense"); } public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max) @@ -157,54 +165,63 @@ public Action:RemoveModel(client) AcceptEntityInput(client, "SetCustomModel"); } } - + public Action:Command_SuperHeavyweightChamp(client, args) { decl String:arg1[32]; if (args < 1) { - arg1 = "@me"; + arg1[0] = '\0'; } else GetCmdArg(1, arg1, sizeof(arg1)); + + CreateBearded(client, arg1); + return Plugin_Handled; +} + +public void CreateBearded(int client, char target[32]) +{ + int targetFilter = 0; + if (target[0] == '\0') + { + target = "@me"; + targetFilter = COMMAND_FILTER_NO_IMMUNITY; + } + new String:target_name[MAX_TARGET_LENGTH]; new target_list[MAXPLAYERS], target_count; new bool:tn_is_ml; if ((target_count = ProcessTargetString( - arg1, + target, client, target_list, MAXPLAYERS, - COMMAND_FILTER_ALIVE|(args < 1 ? COMMAND_FILTER_NO_IMMUNITY : 0), + COMMAND_FILTER_ALIVE|targetFilter, target_name, sizeof(target_name), tn_is_ml)) <= 0) { ReplyToTargetError(client, target_count); - return Plugin_Handled; + return; } for (new i = 0; i < target_count; i++) - { - - - if(!g_IsBearded[target_list[i]]){ - - g_IsBearded[target_list[i]] = true; - MakeBearded(target_list[i]); - - }else - { - - g_IsBearded[target_list[i]] = false; - PrintToChat(target_list[i], "1. You are no longer Giant Bearded Expense!"); - PrintToChat(target_list[i], "2. You will turn back by changing class or dying!"); - TF2_RegeneratePlayer(target_list[i]); - } + { + if(!g_IsBearded[target_list[i]]){ + g_IsBearded[target_list[i]] = true; + MakeBearded(target_list[i]); + + }else + { + g_IsBearded[target_list[i]] = false; + PrintToChat(target_list[i], "1. You are no longer Giant Bearded Expense!"); + PrintToChat(target_list[i], "2. You will turn back by changing class or dying!"); + TF2_RegeneratePlayer(target_list[i]); + } } if (g_IsBearded[client])EmitSoundToAll(SPAWN); - return Plugin_Handled; } MakeBearded(client) diff --git a/bedane.sp b/bedane.sp index 93c3ad3f..b34c6fb9 100644 --- a/bedane.sp +++ b/bedane.sp @@ -3,6 +3,7 @@ #include #include #include +#include #define PLUGIN_VERSION "1.0" @@ -54,6 +55,13 @@ public OnPluginStart() SetFailState("Failed to create call: CBasePlayer::EquipWearable"); delete hTF2; + + AddRobot("Uncle Dane", "Engineer", CreateUncleDane); +} + +public void OnPluginEnd() +{ + RemoveRobot("Uncle Dane"); } public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max) @@ -203,25 +211,39 @@ public Action:Command_SuperHeavyweightChamp(client, args) decl String:arg1[32]; if (args < 1) { - arg1 = "@me"; + arg1[0] = '\0'; } else GetCmdArg(1, arg1, sizeof(arg1)); + + CreateUncleDane(client, arg1); + return Plugin_Handled; +} + +public void CreateUncleDane(int client, char target[32]) +{ + int targetFilter = 0; + if (target[0] == '\0') + { + target = "@me"; + targetFilter = COMMAND_FILTER_NO_IMMUNITY; + } + new String:target_name[MAX_TARGET_LENGTH]; new target_list[MAXPLAYERS], target_count; new bool:tn_is_ml; if ((target_count = ProcessTargetString( - arg1, + target, client, target_list, MAXPLAYERS, - COMMAND_FILTER_ALIVE|(args < 1 ? COMMAND_FILTER_NO_IMMUNITY : 0), + COMMAND_FILTER_ALIVE|targetFilter, target_name, sizeof(target_name), tn_is_ml)) <= 0) { ReplyToTargetError(client, target_count); - return Plugin_Handled; + return; } for (new i = 0; i < target_count; i++) { @@ -234,11 +256,9 @@ public Action:Command_SuperHeavyweightChamp(client, args) PrintToChat(target_list[i], "1. You are no longer Giant Deflector GPS!"); PrintToChat(target_list[i], "2. You will turn back by changing class or dying!"); TF2_RegeneratePlayer(target_list[i]); - } - + } } if (g_IsUncleDane[client])EmitSoundToAll(SPAWN); - return Plugin_Handled; } MakeUncleDane(client) diff --git a/bedeflectorgps.sp b/bedeflectorgps.sp index 0c22e0f0..c174a29c 100644 --- a/bedeflectorgps.sp +++ b/bedeflectorgps.sp @@ -2,6 +2,7 @@ #include #include #include +#include #define PLUGIN_VERSION "1.0" @@ -60,6 +61,13 @@ public OnPluginStart() SetFailState("Failed to create call: CBasePlayer::EquipWearable"); delete hTF2; + + AddRobot("HiGPS", "Heavy", CreateHiGPS); +} + +public void OnPluginEnd() +{ + RemoveRobot("HiGPS"); } public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max) @@ -189,31 +197,45 @@ public Action:RemoveModel(client) AcceptEntityInput(client, "SetCustomModel"); } } - + public Action:Command_GPSDeflector(client, args) { decl String:arg1[32]; if (args < 1) { - arg1 = "@me"; + arg1[0] = '\0'; } else GetCmdArg(1, arg1, sizeof(arg1)); + + CreateHiGPS(client, arg1); + return Plugin_Handled; +} + +public void CreateHiGPS(int client, char target[32]) +{ + int targetFilter = 0; + if (target[0] == '\0') + { + target = "@me"; + targetFilter = COMMAND_FILTER_NO_IMMUNITY; + } + new String:target_name[MAX_TARGET_LENGTH]; new target_list[MAXPLAYERS], target_count; new bool:tn_is_ml; if ((target_count = ProcessTargetString( - arg1, + target, client, target_list, MAXPLAYERS, - COMMAND_FILTER_ALIVE|(args < 1 ? COMMAND_FILTER_NO_IMMUNITY : 0), + COMMAND_FILTER_ALIVE|targetFilter, target_name, sizeof(target_name), tn_is_ml)) <= 0) { ReplyToTargetError(client, target_count); - return Plugin_Handled; + return; } for (new i = 0; i < target_count; i++) { @@ -228,16 +250,10 @@ public Action:Command_GPSDeflector(client, args) g_IsGPS[target_list[i]] = false; PrintToChat(target_list[i], "1. You are no longer Giant Deflector GPS!"); TF2_RegeneratePlayer(target_list[i]); - } - - + } } - - if (g_IsGPS[client])EmitSoundToAll(SPAWN); - - return Plugin_Handled; } MakeGDeflectorH(client) diff --git a/berobot_storage.sp b/berobot_storage.sp new file mode 100644 index 00000000..98318191 --- /dev/null +++ b/berobot_storage.sp @@ -0,0 +1,179 @@ +#include +#include +#include +#include +#include +#pragma newdecls required +#pragma semicolon 1 + + +public Plugin myinfo = +{ + name = "berobot_storage", + author = "icebear", + description = "", + version = "1.0", + url = "https://github.com/eisbaer66/robogithub" +}; + +char LOG_TAGS[][] = {"VERBOSE", "INFO", "ERROR"}; +enum (<<= 1) +{ + SML_VERBOSE = 1, + SML_INFO, + SML_ERROR, +} + +char ROBOT_KEY_NAME[] = "name"; +char ROBOT_KEY_CLASS[] = "class"; +char ROBOT_KEY_CALLBACK[] = "callback"; +bool _init; +StringMap _robots; + +public void OnPluginStart() +{ + Init(); +} + +public void Init() +{ + if (_init) + return; + + //TODO: Release + // SMLoggerInit(LOG_TAGS, sizeof(LOG_TAGS), SML_ERROR, SML_FILE); + SMLoggerInit(LOG_TAGS, sizeof(LOG_TAGS), SML_VERBOSE|SML_INFO|SML_ERROR, SML_ALL); + SMLogTag(SML_INFO, "berobot_store started at %i", GetTime()); + + _robots = new StringMap(); + _init = true; + + RegAdminCmd("sm_dumpRobotStorage", Command_DumpRobotStorage, ADMFLAG_ROOT, "Dumps the current Robot-Storage (for debugging)"); +} + +public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max) +{ + CreateNative("AddRobot", Native_AddRobot); + CreateNative("RemoveRobot", Native_RemoveRobot); + CreateNative("GetRobotNames", Native_GetRobotNames); + CreateNative("GetRobotClass", Native_GetRobotClass); + CreateNative("CreateRobot", Native_CreateRobot); + + return APLRes_Success; +} + +public Action Command_DumpRobotStorage(int client, int numParams) +{ + StringMapSnapshot snapshot = _robots.Snapshot(); + for(int i = 0; i < snapshot.Length; i++) + { + char name[NAMELENGTH]; + snapshot.GetKey(i, name, NAMELENGTH); + + StringMap item; + _robots.GetValue(name, item); + + char class[9]; + item.GetString(ROBOT_KEY_CLASS, class, 9); + PrivateForward privateForward; + item.GetValue(ROBOT_KEY_CALLBACK, privateForward); + + SMLogTag(SML_INFO, "Robot {%s: %s, callback: %x}", name, class, privateForward); + } +} + +public any Native_AddRobot(Handle plugin, int numParams) +{ + Init(); + + char name[NAMELENGTH]; + GetNativeString(1, name, NAMELENGTH); + + char class[9]; + GetNativeString(2, class, 9); + + Function callback = GetNativeFunction(3); + + SMLogTag(SML_VERBOSE, "adding robot %s from plugin-handle %x", name, plugin); + + PrivateForward privateForward = new PrivateForward(ET_Ignore, Param_Cell, Param_String); + privateForward.AddFunction(plugin, callback); + + SMLogTag(SML_VERBOSE, "robot %s uses privateForward %x", name, privateForward); + SMLogTag(SML_VERBOSE, "robot %s is class %s", name, class); + + StringMap item = new StringMap(); + item.SetString(ROBOT_KEY_NAME, name); + item.SetString(ROBOT_KEY_CLASS, class); + item.SetValue(ROBOT_KEY_CALLBACK, privateForward); + _robots.SetValue(name, item); +} + +public any Native_RemoveRobot(Handle plugin, int numParams) +{ + Init(); + + char name[NAMELENGTH]; + GetNativeString(1, name, NAMELENGTH); + + _robots.Remove(name); +} + +public any Native_GetRobotNames(Handle plugin, int numParams) +{ + Init(); + + ArrayList names = new ArrayList(NAMELENGTH); + + StringMapSnapshot snapshot = _robots.Snapshot(); + for(int i = 0; i < snapshot.Length; i++) + { + char name[NAMELENGTH]; + snapshot.GetKey(i, name, NAMELENGTH); + + names.PushString(name); + } + + return names; +} + +public any Native_GetRobotClass(Handle plugin, int numParams) +{ + Init(); + + char name[NAMELENGTH]; + GetNativeString(1, name, NAMELENGTH); + + char class[9]; + + StringMap item; + _robots.GetValue(name, item); + item.GetString(ROBOT_KEY_CLASS, class, 9); + + SetNativeString(2, class, 10, false); +} + +public any Native_CreateRobot(Handle plugin, int numParams) +{ + Init(); + + char name[NAMELENGTH]; + GetNativeString(1, name, NAMELENGTH); + int client = GetNativeCell(2); + char target[32]; + GetNativeString(3, target, 32); + + StringMap item; + _robots.GetValue(name, item); + + PrivateForward privateForward; + item.GetValue(ROBOT_KEY_CALLBACK, privateForward); + + SMLogTag(SML_VERBOSE, "calling privateForward %x for robot %s, with client %i and target %s", privateForward, name, client, target); + Call_StartForward(privateForward); + Call_PushCell(client); + Call_PushString(target); + Call_Finish(); + + return 0; +} \ No newline at end of file diff --git a/besolar.sp b/besolar.sp index 82504290..8a6f5df9 100644 --- a/besolar.sp +++ b/besolar.sp @@ -2,6 +2,7 @@ #include #include #include +#include #define PLUGIN_VERSION "1.0" @@ -59,7 +60,12 @@ public OnPluginStart() g_Resupply[i] = false; } + AddRobot("Solar Light", "Demoman", CreateSolar); +} +public void OnPluginEnd() +{ + RemoveRobot("Solar Light"); } public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max) @@ -191,49 +197,55 @@ public Action:Command_GiantSolar(client, args) decl String:arg1[32]; if (args < 1) { - arg1 = "@me"; + arg1[0] = '\0'; } else GetCmdArg(1, arg1, sizeof(arg1)); + + CreateSolar(client, arg1); + return Plugin_Handled; +} + +public void CreateSolar(int client, char target[32]) +{ + int targetFilter = 0; + if (target[0] == '\0') + { + target = "@me"; + targetFilter = COMMAND_FILTER_NO_IMMUNITY; + } + new String:target_name[MAX_TARGET_LENGTH]; new target_list[MAXPLAYERS], target_count; new bool:tn_is_ml; if ((target_count = ProcessTargetString( - arg1, + target, client, target_list, MAXPLAYERS, - COMMAND_FILTER_ALIVE|(args < 1 ? COMMAND_FILTER_NO_IMMUNITY : 0), + COMMAND_FILTER_ALIVE|targetFilter, target_name, sizeof(target_name), tn_is_ml)) <= 0) { ReplyToTargetError(client, target_count); - return Plugin_Handled; + return; } for (new i = 0; i < target_count; i++) { - if(!g_IsSolar[target_list[i]]){ - + if(!g_IsSolar[target_list[i]]){ + g_IsSolar[target_list[i]] = true; MakeSolar(target_list[i]); }else { - g_IsSolar[target_list[i]] = false; PrintToChat(target_list[i], "1. You are no longer Giant Solarlight!"); TF2_RegeneratePlayer(target_list[i]); } - - - - - - } EmitSoundToAll(SPAWN); - return Plugin_Handled; } MakeSolar(client) diff --git a/includes/berobot.inc b/includes/berobot.inc new file mode 100644 index 00000000..e6673aee --- /dev/null +++ b/includes/berobot.inc @@ -0,0 +1,20 @@ +#if defined _berobot_included + #endinput +#endif +#define _berobot_included "0.1" + +#include +#include +#include + +const int NAMELENGTH = 128; +typedef RobotCallback = function void (int client, char target[32]); + + +native void AddRobot(char name[NAMELENGTH], char class[9], RobotCallback callback); +native void RemoveRobot(char name[NAMELENGTH]); + +native ArrayList GetRobotNames(); +native void GetRobotClass(char name[NAMELENGTH], char class[9]); + +native void CreateRobot(char[] name, int client, char target[32]); \ No newline at end of file diff --git a/tests_berobot.sp b/tests_berobot.sp new file mode 100644 index 00000000..15b49557 --- /dev/null +++ b/tests_berobot.sp @@ -0,0 +1,189 @@ +#include +#include +#include +#include +#include +#pragma newdecls required +#pragma semicolon 1 + + +public Plugin myinfo = +{ + name = "tests_berobot", + author = "icebear", + description = "", + version = "0.1", + url = "https://github.com/eisbaer66/robogithub" +}; + +char LOG_TAGS[][] = {"VERBOSE", "INFO", "ERROR", "FAILED_ASSERT"}; +enum (<<= 1) +{ + SML_VERBOSE = 1, + SML_INFO, + SML_ERROR, + SML_FAILED_ASSERT, +} + +enum struct CreateCall{ + char name[1]; + int client; + char target[32]; +} + +ArrayList _created; + +public void OnPluginStart() +{ + SMLoggerInit(LOG_TAGS, sizeof(LOG_TAGS), SML_VERBOSE|SML_INFO|SML_ERROR|SML_FAILED_ASSERT, SML_ALL); + SMLogTag(SML_INFO, "tests_berobot started at %i", GetTime()); + + _created = new ArrayList(3); + + AddRobot("A", "ClassA", CreateA); + AddRobot("B", "ClassB", CreateB); + + Assert(); +} + +public void OnPluginEnd() +{ + RemoveRobot("A"); + RemoveRobot("B"); +} + +public void CreateA(int client, char target[32]) +{ + SMLogTag(SML_VERBOSE, "CreateA called at %i for client %i and target %s", GetTime(), client, target); + + CreateCall call; + call.name = "A"; + call.client = client; + call.target = target; + + _created.PushArray(call); +} + +public void CreateB(int client, char target[32]) +{ + SMLogTag(SML_VERBOSE, "CreateB called at %i for client %i and target %s", GetTime(), client, target); + + CreateCall call; + call.name = "B"; + call.client = client; + call.target = target; + + _created.PushArray(call); +} + +public void Assert() +{ + if (!AssertNames()) + return; + if (!AssertClasses()) + return; + if (!AssertCalls()) + return; + + SMLogTag(SML_INFO, "Asserts passed"); +} + +public bool AssertNames() +{ + ArrayList names = GetRobotNames(); + if (!AssertEqual(2, names.Length, "GetRobotNames did not return expected number of names")) + return false; + + char actualA[2]; + names.GetString(0, actualA, 2); + if (!AssertEqualString("B", actualA, "GetRobotNames did not have 'B' in first Position")) + return false; + + char actualB[2]; + names.GetString(1, actualB, 2); + if (!AssertEqualString("A", actualB, "GetRobotNames did not have 'A' in second Position")) + return false; + + return true; +} + +public bool AssertClasses() +{ + char classA[9]; + GetRobotClass("A", classA); + if (!AssertEqualString("ClassA", classA, "GetRobotClass did not return expected class")) + return false; + + char classB[9]; + GetRobotClass("B", classB); + if (!AssertEqualString("ClassB", classB, "GetRobotClass did not return expected class")) + return false; + + return true; +} + +public bool AssertCalls() +{ + CreateRobot("A", 1, ""); + CreateRobot("B", 2, ""); + + if (!AssertEqual(2, _created.Length, "Create-functions were not called the expected number of times")) + return false; + + CreateCall call; + + _created.GetArray(0, call, sizeof(call)); + if (!AssertEqualCalls(call, "A", 1, "", "first call")) + return false; + + _created.GetArray(1, call, sizeof(call)); + if (!AssertEqualCalls(call, "B", 2, "", "second call")) + return false; + + return true; +} + +public bool AssertEqualCalls(CreateCall call, char[] expectedName, int expectedClient, char expectedTarget[32], char[] message) +{ + char nameMessage[265]; + strcopy(nameMessage, 265, message); + StrCat(nameMessage, 265, " did not have expected name"); + if (!AssertEqualString(expectedName, call.name, nameMessage)) + return false; + + char clientMessage[265]; + strcopy(clientMessage, 265, message); + StrCat(clientMessage, 265, " did not have expected client"); + if (!AssertEqual(expectedClient, call.client, clientMessage)) + return false; + + char argsMessage[265]; + strcopy(argsMessage, 265, message); + StrCat(argsMessage, 265, " did not have expected args"); + if (!AssertEqualString(expectedTarget, call.target, argsMessage)) + return false; + + return true; +} + +public bool AssertEqual(int expected, int actual, char[] message) +{ + if (actual == expected) + return true; + + StrCat(message, 265, ". Expected: %i Actual: %i"); + SMLogTag(SML_FAILED_ASSERT, message, expected, actual); + + return false; +} + +public bool AssertEqualString(char[] expected, char[] actual, char[] message) +{ + if (strcmp(actual, expected) == 0) + return true; + + StrCat(message, 265, ". Expected: %s Actual: %s"); + SMLogTag(SML_FAILED_ASSERT, message, expected, actual); + + return false; +} \ No newline at end of file diff --git a/tests_berobot2.sp b/tests_berobot2.sp new file mode 100644 index 00000000..df54cfca --- /dev/null +++ b/tests_berobot2.sp @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include +#pragma newdecls required +#pragma semicolon 1 + + +public Plugin myinfo = +{ + name = "tests_berobot2", + author = "icebear", + description = "", + version = "0.1", + url = "https://github.com/eisbaer66/robogithub" +}; + +char LOG_TAGS[][] = {"VERBOSE", "INFO", "ERROR", "FAILED_ASSERT"}; +enum (<<= 1) +{ + SML_VERBOSE = 1, + SML_INFO, + SML_ERROR, + SML_FAILED_ASSERT, +} + +enum struct CreateCall{ + char name[1]; + int client; + int args; +} + +ArrayList _created; + +public void OnPluginStart() +{ + SMLoggerInit(LOG_TAGS, sizeof(LOG_TAGS), SML_VERBOSE|SML_INFO|SML_ERROR|SML_FAILED_ASSERT, SML_ALL); + SMLogTag(SML_INFO, "tests_berobot2 started at %i", GetTime()); + + _created = new ArrayList(3); + + Assert(); +} + +public void Assert() +{ + if (!AssertNames()) + return; + + SMLogTag(SML_INFO, "Asserts passed"); +} + +public bool AssertNames() +{ + ArrayList names = GetRobotNames(); + if (!AssertEqual(2, names.Length, "GetRobotNames did not return expected number of names")) + return false; + + char actualA[2]; + names.GetString(0, actualA, 2); + if (!AssertEqualString("B", actualA, "GetRobotNames did not have 'B' in first Position")) + return false; + + char actualB[2]; + names.GetString(1, actualB, 2); + if (!AssertEqualString("A", actualB, "GetRobotNames did not have 'A' in second Position")) + return false; + + return true; +} + +public bool AssertEqual(int expected, int actual, char[] message) +{ + if (actual == expected) + return true; + + StrCat(message, 265, ". Expected: %i Actual: %i"); + SMLogTag(SML_FAILED_ASSERT, message, expected, actual); + + return false; +} + +public bool AssertEqualString(char[] expected, char[] actual, char[] message) +{ + if (strcmp(actual, expected) == 0) + return true; + + StrCat(message, 265, ". Expected: %s Actual: %s"); + SMLogTag(SML_FAILED_ASSERT, message, expected, actual); + + return false; +} \ No newline at end of file