From 0b580d1c850c58aaf460a99b45b196a4348a5fd5 Mon Sep 17 00:00:00 2001 From: DarkPenguin <96709220+DarkPenguin24@users.noreply.github.com> Date: Thu, 27 Jan 2022 15:32:04 +0100 Subject: [PATCH] #266: Introduce role assignment as Lobby Host (#288) * #266: Introduce role assignment as Lobby Host * #266: Check max Imposter Amount --- appdata/il2cpp-types.h | 254 +++++++++++++++++++++++++++++++++++++- gui/tabs/host_tab.cpp | 100 ++++++++------- gui/tabs/host_tab.h | 7 +- hooks/GameOptionsData.cpp | 2 + hooks/RoleManager.cpp | 15 +++ hooks/_hooks.h | 1 + used_types.txt | 25 ++++ user/state.hpp | 7 +- user/utility.cpp | 17 +++ user/utility.h | 13 +- 10 files changed, 389 insertions(+), 52 deletions(-) diff --git a/appdata/il2cpp-types.h b/appdata/il2cpp-types.h index db364fd5..b5858f2f 100644 --- a/appdata/il2cpp-types.h +++ b/appdata/il2cpp-types.h @@ -10508,7 +10508,7 @@ namespace app #else int32_t TaskBarMode; #endif - void* RoleOptions; + struct RoleOptionsData* RoleOptions; bool isDefaults; void* settings; }; @@ -10633,7 +10633,7 @@ namespace app float ProtectionDurationSeconds; float EngineerCooldown; float EngineerInVentMaxTime; - void* roleRates; + struct Dictionary_2_RoleTypes_RoleOptionsData_RoleRate_* roleRates; }; struct RoleOptionsData @@ -10651,10 +10651,260 @@ namespace app VirtualInvokeData ToString; }; + struct IEqualityComparer_1_RoleTypes_ + { + struct IEqualityComparer_1_RoleTypes___Class* klass; + MonitorData* monitor; + }; + + struct IEqualityComparer_1_RoleTypes___StaticFields + { + }; + + struct IEqualityComparer_1_RoleTypes___VTable + { + VirtualInvokeData Equals; + VirtualInvokeData GetHashCode; + }; + + struct IEqualityComparer_1_RoleTypes___Class + { + Il2CppClass_0 _0; + Il2CppRuntimeInterfaceOffsetPair* interfaceOffsets; + struct IEqualityComparer_1_RoleTypes___StaticFields* static_fields; + const Il2CppRGCTXData* rgctx_data; + Il2CppClass_1 _1; + struct IEqualityComparer_1_RoleTypes___VTable vtable; + }; + + struct __declspec(align(4)) Dictionary_2_RoleTypes_RoleOptionsData_RoleRate___Fields + { + struct Int32__Array* buckets; + struct Dictionary_2_TKey_TValue_Entry_RoleTypes_RoleOptionsData_RoleRate___Array* entries; + int32_t count; + int32_t version; + int32_t freeList; + int32_t freeCount; + struct IEqualityComparer_1_RoleTypes_* comparer; + struct Dictionary_2_TKey_TValue_KeyCollection_RoleTypes_RoleOptionsData_RoleRate_* keys; + struct Dictionary_2_TKey_TValue_ValueCollection_RoleTypes_RoleOptionsData_RoleRate_* values; + struct Object* _syncRoot; + }; + + struct __declspec(align(4)) Dictionary_2_TKey_TValue_ValueCollection_RoleTypes_RoleOptionsData_RoleRate___Fields + { + struct Dictionary_2_RoleTypes_RoleOptionsData_RoleRate_* dictionary; + }; + + struct Dictionary_2_TKey_TValue_ValueCollection_RoleTypes_RoleOptionsData_RoleRate_ + { + struct Dictionary_2_TKey_TValue_ValueCollection_RoleTypes_RoleOptionsData_RoleRate___Class* klass; + MonitorData* monitor; + struct Dictionary_2_TKey_TValue_ValueCollection_RoleTypes_RoleOptionsData_RoleRate___Fields fields; + }; + + struct Dictionary_2_TKey_TValue_ValueCollection_RoleTypes_RoleOptionsData_RoleRate___VTable + { + VirtualInvokeData Equals; + VirtualInvokeData Finalize; + VirtualInvokeData GetHashCode; + VirtualInvokeData ToString; + VirtualInvokeData get_Count; + VirtualInvokeData System_Collections_Generic_ICollection_TValue__get_IsReadOnly; + VirtualInvokeData System_Collections_Generic_ICollection_TValue__Add; + VirtualInvokeData System_Collections_Generic_ICollection_TValue__Clear; + VirtualInvokeData System_Collections_Generic_ICollection_TValue__Contains; + VirtualInvokeData CopyTo; + VirtualInvokeData System_Collections_Generic_ICollection_TValue__Remove; + VirtualInvokeData System_Collections_Generic_IEnumerable_TValue__GetEnumerator; + VirtualInvokeData System_Collections_IEnumerable_GetEnumerator; + VirtualInvokeData System_Collections_ICollection_CopyTo; + VirtualInvokeData get_Count_1; + VirtualInvokeData System_Collections_ICollection_get_SyncRoot; + VirtualInvokeData System_Collections_ICollection_get_IsSynchronized; + VirtualInvokeData get_Count_2; + }; + + struct Dictionary_2_TKey_TValue_ValueCollection_RoleTypes_RoleOptionsData_RoleRate___StaticFields + { + }; + + struct Dictionary_2_TKey_TValue_ValueCollection_RoleTypes_RoleOptionsData_RoleRate___Class + { + Il2CppClass_0 _0; + Il2CppRuntimeInterfaceOffsetPair* interfaceOffsets; + struct Dictionary_2_TKey_TValue_ValueCollection_RoleTypes_RoleOptionsData_RoleRate___StaticFields* static_fields; + const Il2CppRGCTXData* rgctx_data; + Il2CppClass_1 _1; + struct Dictionary_2_TKey_TValue_ValueCollection_RoleTypes_RoleOptionsData_RoleRate___VTable vtable; + }; + + struct __declspec(align(4)) Dictionary_2_TKey_TValue_KeyCollection_RoleTypes_RoleOptionsData_RoleRate___Fields + { + struct Dictionary_2_RoleTypes_RoleOptionsData_RoleRate_* dictionary; + }; + + struct Dictionary_2_TKey_TValue_KeyCollection_RoleTypes_RoleOptionsData_RoleRate_ + { + struct Dictionary_2_TKey_TValue_KeyCollection_RoleTypes_RoleOptionsData_RoleRate___Class* klass; + MonitorData* monitor; + struct Dictionary_2_TKey_TValue_KeyCollection_RoleTypes_RoleOptionsData_RoleRate___Fields fields; + }; + + struct Dictionary_2_TKey_TValue_KeyCollection_RoleTypes_RoleOptionsData_RoleRate___VTable + { + VirtualInvokeData Equals; + VirtualInvokeData Finalize; + VirtualInvokeData GetHashCode; + VirtualInvokeData ToString; + VirtualInvokeData get_Count; + VirtualInvokeData System_Collections_Generic_ICollection_TKey__get_IsReadOnly; + VirtualInvokeData System_Collections_Generic_ICollection_TKey__Add; + VirtualInvokeData System_Collections_Generic_ICollection_TKey__Clear; + VirtualInvokeData System_Collections_Generic_ICollection_TKey__Contains; + VirtualInvokeData CopyTo; + VirtualInvokeData System_Collections_Generic_ICollection_TKey__Remove; + VirtualInvokeData System_Collections_Generic_IEnumerable_TKey__GetEnumerator; + VirtualInvokeData System_Collections_IEnumerable_GetEnumerator; + VirtualInvokeData System_Collections_ICollection_CopyTo; + VirtualInvokeData get_Count_1; + VirtualInvokeData System_Collections_ICollection_get_SyncRoot; + VirtualInvokeData System_Collections_ICollection_get_IsSynchronized; + VirtualInvokeData get_Count_2; + }; + + struct Dictionary_2_TKey_TValue_KeyCollection_RoleTypes_RoleOptionsData_RoleRate___StaticFields + { + }; + + struct Dictionary_2_TKey_TValue_KeyCollection_RoleTypes_RoleOptionsData_RoleRate___Class + { + Il2CppClass_0 _0; + Il2CppRuntimeInterfaceOffsetPair* interfaceOffsets; + struct Dictionary_2_TKey_TValue_KeyCollection_RoleTypes_RoleOptionsData_RoleRate___StaticFields* static_fields; + const Il2CppRGCTXData* rgctx_data; + Il2CppClass_1 _1; + struct Dictionary_2_TKey_TValue_KeyCollection_RoleTypes_RoleOptionsData_RoleRate___VTable vtable; + }; + + struct Dictionary_2_RoleTypes_RoleOptionsData_RoleRate_ + { + struct Dictionary_2_RoleTypes_RoleOptionsData_RoleRate___Class* klass; + MonitorData* monitor; + struct Dictionary_2_RoleTypes_RoleOptionsData_RoleRate___Fields fields; + }; + + struct Dictionary_2_RoleTypes_RoleOptionsData_RoleRate___VTable + { + VirtualInvokeData Equals; + VirtualInvokeData Finalize; + VirtualInvokeData GetHashCode; + VirtualInvokeData ToString; + VirtualInvokeData get_Item; + VirtualInvokeData set_Item; + VirtualInvokeData System_Collections_Generic_IDictionary_TKey_TValue__get_Keys; + VirtualInvokeData System_Collections_Generic_IDictionary_TKey_TValue__get_Values; + VirtualInvokeData ContainsKey; + VirtualInvokeData Add; + VirtualInvokeData Remove; + VirtualInvokeData TryGetValue; + VirtualInvokeData get_Count; + VirtualInvokeData System_Collections_Generic_ICollection_System_Collections_Generic_KeyValuePair_TKey_TValue___get_IsReadOnly; + VirtualInvokeData System_Collections_Generic_ICollection_System_Collections_Generic_KeyValuePair_TKey_TValue___Add; + VirtualInvokeData Clear; + VirtualInvokeData System_Collections_Generic_ICollection_System_Collections_Generic_KeyValuePair_TKey_TValue___Contains; + VirtualInvokeData System_Collections_Generic_ICollection_System_Collections_Generic_KeyValuePair_TKey_TValue___CopyTo; + VirtualInvokeData System_Collections_Generic_ICollection_System_Collections_Generic_KeyValuePair_TKey_TValue___Remove; + VirtualInvokeData System_Collections_Generic_IEnumerable_System_Collections_Generic_KeyValuePair_TKey_TValue___GetEnumerator; + VirtualInvokeData System_Collections_IEnumerable_GetEnumerator; + VirtualInvokeData System_Collections_IDictionary_get_Item; + VirtualInvokeData System_Collections_IDictionary_set_Item; + VirtualInvokeData System_Collections_IDictionary_get_Keys; + VirtualInvokeData System_Collections_IDictionary_get_Values; + VirtualInvokeData System_Collections_IDictionary_Contains; + VirtualInvokeData System_Collections_IDictionary_Add; + VirtualInvokeData Clear_1; + VirtualInvokeData System_Collections_IDictionary_get_IsReadOnly; + VirtualInvokeData System_Collections_IDictionary_get_IsFixedSize; + VirtualInvokeData System_Collections_IDictionary_GetEnumerator; + VirtualInvokeData System_Collections_IDictionary_Remove; + VirtualInvokeData System_Collections_ICollection_CopyTo; + VirtualInvokeData get_Count_1; + VirtualInvokeData System_Collections_ICollection_get_SyncRoot; + VirtualInvokeData System_Collections_ICollection_get_IsSynchronized; + VirtualInvokeData TryGetValue_1; + VirtualInvokeData System_Collections_Generic_IReadOnlyDictionary_TKey_TValue__get_Keys; + VirtualInvokeData System_Collections_Generic_IReadOnlyDictionary_TKey_TValue__get_Values; + VirtualInvokeData get_Count_2; + VirtualInvokeData GetObjectData; + VirtualInvokeData OnDeserialization; + VirtualInvokeData GetObjectData_1; + VirtualInvokeData OnDeserialization_1; + }; + + struct Dictionary_2_RoleTypes_RoleOptionsData_RoleRate___Class + { + Il2CppClass_0 _0; + Il2CppRuntimeInterfaceOffsetPair* interfaceOffsets; + struct Dictionary_2_RoleTypes_RoleOptionsData_RoleRate___StaticFields* static_fields; + const Il2CppRGCTXData* rgctx_data; + Il2CppClass_1 _1; + struct Dictionary_2_RoleTypes_RoleOptionsData_RoleRate___VTable vtable; + }; + + struct Dictionary_2_RoleTypes_RoleOptionsData_RoleRate___StaticFields + { + }; + + struct RoleOptionsData_RoleRate + { + int32_t MaxCount; + int32_t Chance; + }; + + struct Dictionary_2_TKey_TValue_Entry_RoleTypes_RoleOptionsData_RoleRate_ + { + int32_t hashCode; + int32_t next; +#if defined(_CPLUSPLUS_) + RoleTypes__Enum key; +#else + uint16_t key; +#endif + struct RoleOptionsData_RoleRate value; + }; + + struct Dictionary_2_TKey_TValue_Entry_RoleTypes_RoleOptionsData_RoleRate___Array + { + struct Dictionary_2_TKey_TValue_Entry_RoleTypes_RoleOptionsData_RoleRate___Array__Class* klass; + MonitorData* monitor; + Il2CppArrayBounds* bounds; + il2cpp_array_size_t max_length; + struct Dictionary_2_TKey_TValue_Entry_RoleTypes_RoleOptionsData_RoleRate_ vector[32]; + }; + + struct Dictionary_2_TKey_TValue_Entry_RoleTypes_RoleOptionsData_RoleRate___Array__VTable + { + }; + + struct Dictionary_2_TKey_TValue_Entry_RoleTypes_RoleOptionsData_RoleRate___Array__Class + { + Il2CppClass_0 _0; + Il2CppRuntimeInterfaceOffsetPair* interfaceOffsets; + struct Dictionary_2_TKey_TValue_Entry_RoleTypes_RoleOptionsData_RoleRate___Array__StaticFields* static_fields; + const Il2CppRGCTXData* rgctx_data; + Il2CppClass_1 _1; + struct Dictionary_2_TKey_TValue_Entry_RoleTypes_RoleOptionsData_RoleRate___Array__VTable vtable; + }; + struct RoleOptionsData__StaticFields { }; + struct Dictionary_2_TKey_TValue_Entry_RoleTypes_RoleOptionsData_RoleRate___Array__StaticFields + { + }; + struct RoleOptionsData__Class { Il2CppClass_0 _0; diff --git a/gui/tabs/host_tab.cpp b/gui/tabs/host_tab.cpp index c533f8f9..7d79e4b3 100644 --- a/gui/tabs/host_tab.cpp +++ b/gui/tabs/host_tab.cpp @@ -9,66 +9,61 @@ namespace HostTab { void Render() { if (IsHost() && IsInLobby()) { if (ImGui::BeginTabItem("Host")) { - ImGui::Text("Select Impostors:"); + ImGui::Text("Select Roles:"); ImGui::BeginChild("host#list", ImVec2(200, 0), true); - ImGui::ListBoxHeader("Choose Impostors", ImVec2(200, 150)); - for (auto playerData : GetAllPlayerData()) { - if (playerData->fields.Disconnected) continue; - - std::string playerName = convert_from_string(GetPlayerOutfit(playerData)->fields._playerName); - + ImGui::ListBoxHeader("Choose Roles", ImVec2(200, 150)); + auto allPlayers = GetAllPlayerData(); + auto playerAmount = allPlayers.size(); + auto maxImposterAmount = GetMaxImposterAmount(playerAmount); + for (int index = 0; index < playerAmount; index++) { + auto playerData = allPlayers[index]; PlayerControl* playerCtrl = GetPlayerControlById(playerData->fields.PlayerId); - bool impostor = std::find(State.impostors.begin(), State.impostors.end(), playerCtrl) != State.impostors.end(); - ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.13f, 0.14f, 0.17f, 1.00f)); - if (ImGui::Checkbox(std::string("##" + playerName + "_CheckBox").c_str(), &impostor)) { - if (!(std::find(State.impostors.begin(), State.impostors.end(), playerCtrl) != State.impostors.end())) { - bool set = false; - - for (int i = 0; i < (*Game::pGameOptionsData)->fields.NumImpostors; i++) { - if (State.impostors[i] == nullptr) { - State.impostors[i] = playerCtrl; - set = true; - break; - } - } + State.assignedRolesPlayer[index] = playerCtrl; + if (State.assignedRolesPlayer[index] == nullptr) + continue; - if (!set) { - if ((*Game::pGameOptionsData)->fields.NumImpostors > 2) { - State.impostors[2] = State.impostors[1]; - } - if ((*Game::pGameOptionsData)->fields.NumImpostors > 1) { - State.impostors[1] = State.impostors[0]; - } - State.impostors[0] = playerCtrl; - } + std::string playerName = convert_from_string(GetPlayerOutfit(playerData)->fields._playerName); + if (CustomListBoxInt(playerName.c_str(), &State.assignedRoles[index], ROLE_NAMES, 80)) + { + State.engineers_amount = GetRoleCount((int)RoleType::Engineer); + State.scientists_amount = GetRoleCount((int)RoleType::Scientist); + State.shapeshifters_amount = GetRoleCount((int)RoleType::Shapeshifter); + State.impostors_amount = GetRoleCount((int)RoleType::Impostor); + if (State.impostors_amount + State.shapeshifters_amount > maxImposterAmount) + { + State.assignedRoles[index] = (int)RoleType::Crewmate; + State.impostors_amount--; } - else { - for (int i = 0; i < (*Game::pGameOptionsData)->fields.NumImpostors; i++) { - if (State.impostors[i] == playerCtrl) { - State.impostors[i] = nullptr; - break; - } - } + else if (State.shapeshifters_amount + State.impostors_amount > maxImposterAmount) + { + State.assignedRoles[index] = (int)RoleType::Engineer; + State.shapeshifters_amount--; } + if (!IsInGame()) + { + auto vectors = (*Game::pGameOptionsData)->fields.RoleOptions->fields.roleRates->fields.entries[0].vector; + for (auto iVector = 0; iVector < 32; iVector++) + { + if (vectors[iVector].key == RoleTypes__Enum::Engineer && State.engineers_amount > vectors[iVector].value.MaxCount) + vectors[iVector].value.MaxCount = State.engineers_amount; + else if (vectors[iVector].key == RoleTypes__Enum::Scientist && State.scientists_amount > vectors[iVector].value.MaxCount) + vectors[iVector].value.MaxCount = State.scientists_amount; + else if (vectors[iVector].key == RoleTypes__Enum::Shapeshifter && State.shapeshifters_amount > vectors[iVector].value.MaxCount) + vectors[iVector].value.MaxCount = State.shapeshifters_amount; + } + if((*Game::pGameOptionsData)->fields.NumImpostors <= State.impostors_amount + State.shapeshifters_amount) + (*Game::pGameOptionsData)->fields.NumImpostors = State.impostors_amount + State.shapeshifters_amount; + } } - ImGui::PopStyleColor(); - ImGui::SameLine(); - ImGui::Dummy(ImVec2(0, 0)); - ImGui::SameLine(); - - ImGui::TextColored(AmongUsColorToImVec4(GetPlayerColor(GetPlayerOutfit(playerData)->fields.ColorId)),playerName.c_str()); } ImGui::ListBoxFooter(); ImGui::EndChild(); ImGui::SameLine(); ImGui::BeginChild("host#actions", ImVec2(200, 0), true); - State.impostors_amount = std::clamp(State.impostors_amount, 0, 2); + State.mapHostChoice = std::clamp(State.mapHostChoice, 0, 4); - if (CustomListBoxInt("Impostors", &State.impostors_amount, IMPOSTOR_AMOUNTS, 75)) { - if (!IsInGame()) (*Game::pGameOptionsData)->fields.NumImpostors = (State.impostors_amount + 1); - } if (CustomListBoxInt("Map", &State.mapHostChoice, MAP_NAMES, 75)) { if (!IsInGame()) { if (State.mapHostChoice == 3) { @@ -91,4 +86,17 @@ namespace HostTab { } } } + const ptrdiff_t& GetRoleCount(int role) + { + return std::count_if(State.assignedRoles.cbegin(), State.assignedRoles.cend(), [role](int i) {return i == role; }); + } + + int GetMaxImposterAmount(size_t playerAmount) + { + if(playerAmount >= 9) + return 3; + if(playerAmount >= 7) + return 2; + return 1; + } } \ No newline at end of file diff --git a/gui/tabs/host_tab.h b/gui/tabs/host_tab.h index 56632b43..9d59b0fc 100644 --- a/gui/tabs/host_tab.h +++ b/gui/tabs/host_tab.h @@ -2,7 +2,10 @@ #include namespace HostTab { - const std::vector MAP_NAMES = { "The Skeld", "Mira HQ", "Polus", "Dleks", "Airship"}; - const std::vector IMPOSTOR_AMOUNTS = { "One", "Two", "Three" }; + const std::vector MAP_NAMES = { "The Skeld", "Mira HQ", "Polus", "Dleks", "Airship" }; + const std::vector IMPOSTOR_AMOUNTS = { "1", "2", "3" }; + const std::vector ROLE_NAMES = { "Random", "Crewmate", "Scientist", "Engineer", "Imposter", "Shapeshifter" }; void Render(); + const ptrdiff_t& GetRoleCount(int role); + int GetMaxImposterAmount(size_t playerAmount); } \ No newline at end of file diff --git a/hooks/GameOptionsData.cpp b/hooks/GameOptionsData.cpp index 0877a3ed..c83e639f 100644 --- a/hooks/GameOptionsData.cpp +++ b/hooks/GameOptionsData.cpp @@ -13,6 +13,7 @@ GameOptionsData* dGameOptionsData_Deserialize(BinaryReader* reader, MethodInfo* State.TaskBarUpdates = (int)gameOptions->fields.TaskBarMode; State.mapHostChoice = gameOptions->fields.MapId; State.impostors_amount = gameOptions->fields.NumImpostors; + State.RoleOptions = gameOptions->fields.RoleOptions; return gameOptions; } @@ -28,6 +29,7 @@ GameOptionsData* dGameOptionsData_Deserialize_1(MessageReader* reader, MethodInf State.TaskBarUpdates = (int)gameOptions->fields.TaskBarMode; State.mapHostChoice = gameOptions->fields.MapId; State.impostors_amount = gameOptions->fields.NumImpostors; + State.RoleOptions = gameOptions->fields.RoleOptions; return gameOptions; } \ No newline at end of file diff --git a/hooks/RoleManager.cpp b/hooks/RoleManager.cpp index 7e609b9b..e1bd1915 100644 --- a/hooks/RoleManager.cpp +++ b/hooks/RoleManager.cpp @@ -12,5 +12,20 @@ void dRoleManager_AssignRolesForTeam(List_1_GameData_PlayerInfo_* players, RoleO } void dRoleManager_AssignRolesFromList(List_1_GameData_PlayerInfo_* players, int32_t teamMax, List_1_RoleTypes_* roleList, int32_t* rolesAssigned, MethodInfo* method) { + dRoleManager_AssignPreChosenRoles(rolesAssigned); return RoleManager_AssignRolesFromList(players, teamMax, roleList, rolesAssigned, method); } + +void dRoleManager_AssignPreChosenRoles(int32_t*& rolesAssigned) +{ + for (int i = 0; i < State.assignedRolesPlayer.size(); i++) { + auto role = State.assignedRoles[i]; + auto player = State.assignedRolesPlayer[i]; + if (role == (int)RoleType::Random) + continue; + + auto trueRole = GetRoleTypesEnum((RoleType)role); + PlayerControl_RpcSetRole(player, trueRole, NULL); + (*rolesAssigned)++; + } +} diff --git a/hooks/_hooks.h b/hooks/_hooks.h index 6187cc25..0519c543 100644 --- a/hooks/_hooks.h +++ b/hooks/_hooks.h @@ -69,6 +69,7 @@ bool dEOSManager_IsFreechatAllowed(EOSManager* __this, MethodInfo* method); void dChatController_Update(ChatController* __this, MethodInfo* method); void dInnerNetClient_EnqueueDisconnect(InnerNetClient* __this, DisconnectReasons__Enum reason, String* stringReason, MethodInfo* method); void dRoleManager_AssignRolesFromList(List_1_GameData_PlayerInfo_* players, int32_t teamMax, List_1_RoleTypes_* roleList, int32_t* rolesAssigned, MethodInfo* method); +void dRoleManager_AssignPreChosenRoles(int32_t*& rolesAssigned); void dPlayerPhysics_FixedUpdate (PlayerPhysics* __this, MethodInfo* method); // 55 8B EC 80 3D ? ? ? ? ? 75 14 68 ? ? ? ? E8 ? ? ? ? 83 C4 04 C6 05 ? ? ? ? ? 8B 45 0C 85 C0 74 3F 80 78 50 00 diff --git a/used_types.txt b/used_types.txt index 65a568af..45bb7a14 100644 --- a/used_types.txt +++ b/used_types.txt @@ -158,6 +158,31 @@ TaskBarMode__Enum GameOptionsData List_1_GameData_PlayerInfo_ RoleOptionsData +RoleOptionsData_RoleRate +Dictionary_2_RoleTypes_RoleOptionsData_RoleRate_ +IEqualityComparer_1_RoleTypes_ +IEqualityComparer_1_RoleTypes___StaticFields +IEqualityComparer_1_RoleTypes___VTable +IEqualityComparer_1_RoleTypes___Class +Dictionary_2_RoleTypes_RoleOptionsData_RoleRate___Class +Dictionary_2_RoleTypes_RoleOptionsData_RoleRate___Fields +Dictionary_2_RoleTypes_RoleOptionsData_RoleRate___VTable +Dictionary_2_RoleTypes_RoleOptionsData_RoleRate___StaticFields +Dictionary_2_TKey_TValue_Entry_RoleTypes_RoleOptionsData_RoleRate_ +Dictionary_2_TKey_TValue_Entry_RoleTypes_RoleOptionsData_RoleRate___Array +Dictionary_2_TKey_TValue_Entry_RoleTypes_RoleOptionsData_RoleRate___Array__Class +Dictionary_2_TKey_TValue_KeyCollection_RoleTypes_RoleOptionsData_RoleRate_ +Dictionary_2_TKey_TValue_ValueCollection_RoleTypes_RoleOptionsData_RoleRate_ +Dictionary_2_TKey_TValue_ValueCollection_RoleTypes_RoleOptionsData_RoleRate___Fields +Dictionary_2_TKey_TValue_ValueCollection_RoleTypes_RoleOptionsData_RoleRate___Class +Dictionary_2_TKey_TValue_ValueCollection_RoleTypes_RoleOptionsData_RoleRate___VTable +Dictionary_2_TKey_TValue_ValueCollection_RoleTypes_RoleOptionsData_RoleRate___StaticFields +Dictionary_2_TKey_TValue_KeyCollection_RoleTypes_RoleOptionsData_RoleRate___Fields +Dictionary_2_TKey_TValue_KeyCollection_RoleTypes_RoleOptionsData_RoleRate___Class +Dictionary_2_TKey_TValue_KeyCollection_RoleTypes_RoleOptionsData_RoleRate___VTable +Dictionary_2_TKey_TValue_KeyCollection_RoleTypes_RoleOptionsData_RoleRate___StaticFields +Dictionary_2_TKey_TValue_Entry_RoleTypes_RoleOptionsData_RoleRate___Array__VTable +Dictionary_2_TKey_TValue_Entry_RoleTypes_RoleOptionsData_RoleRate___Array__StaticFields Nullable_1_RoleTypes_ RoleTypes__Enum__Array List_1_RoleTypes_ diff --git a/user/state.hpp b/user/state.hpp index 5b9ccece..17f52b4a 100644 --- a/user/state.hpp +++ b/user/state.hpp @@ -90,9 +90,14 @@ class Settings { int32_t rpcCooldown = 15; int32_t playerKilledId = 0; - std::vector impostors = { nullptr, nullptr, nullptr }; + std::vector assignedRolesPlayer = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; + std::vector assignedRoles = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int mapHostChoice = -1; int impostors_amount = 0; + int shapeshifters_amount = 0; + int engineers_amount = 0; + int scientists_amount = 0; + RoleOptionsData* RoleOptions = nullptr; bool Wallhack = false; bool FreeCam = false; diff --git a/user/utility.cpp b/user/utility.cpp index 00e4e369..83bd60c0 100644 --- a/user/utility.cpp +++ b/user/utility.cpp @@ -665,4 +665,21 @@ std::string GetRoleName(RoleBehaviour* roleBehaviour, bool abbreviated /* = fals default: return (abbreviated ? "Unk" : "Unknown"); } +} + +RoleTypes__Enum GetRoleTypesEnum(RoleType role) +{ + if (role == RoleType::Shapeshifter) { + return RoleTypes__Enum::Shapeshifter; + } + else if (role == RoleType::Impostor) { + return RoleTypes__Enum::Impostor; + } + else if (role == RoleType::Engineer) { + return RoleTypes__Enum::Engineer; + } + else if (role == RoleType::Scientist) { + return RoleTypes__Enum::Scientist; + } + return RoleTypes__Enum::Crewmate; } \ No newline at end of file diff --git a/user/utility.h b/user/utility.h index 7298fe23..c4a48fb2 100644 --- a/user/utility.h +++ b/user/utility.h @@ -18,6 +18,16 @@ enum MapType { MAP_AIRSHIP = 3 }; +enum RoleType +{ + Random = 0, + Crewmate = 1, + Scientist = 2, + Engineer = 3, + Impostor = 4, + Shapeshifter = 5, +}; + class PlayerSelection { bool hasValue; int32_t clientId; @@ -124,4 +134,5 @@ void ResetOriginalAppearance(); bool PlayerIsImpostor(GameData_PlayerInfo* player); GameData_PlayerOutfit* GetPlayerOutfit(GameData_PlayerInfo* player, bool includeShapeshifted = false); Color GetRoleColor(RoleBehaviour* roleBehaviour); -std::string GetRoleName(RoleBehaviour* roleBehaviour, bool abbreviated = false); \ No newline at end of file +std::string GetRoleName(RoleBehaviour* roleBehaviour, bool abbreviated = false); +RoleTypes__Enum GetRoleTypesEnum(RoleType role); \ No newline at end of file