public static bool initializeOverlays()
        {
            HudManager hudManager = DestroyableSingleton <HudManager> .Instance;

            if (hudManager == null)
            {
                return(false);
            }

            if (helpButton == null)
            {
                helpButton = Helpers.loadSpriteFromResources("TheOtherRoles.Resources.HelpButton.png", 115f);
            }

            if (colorBG == null)
            {
                colorBG = Helpers.loadSpriteFromResources("TheOtherRoles.Resources.White.png", 100f);
            }

            if (meetingUnderlay == null)
            {
                meetingUnderlay = UnityEngine.Object.Instantiate(hudManager.FullScreen, hudManager.transform);
                meetingUnderlay.transform.localPosition = new Vector3(0f, 0f, 20f);
                meetingUnderlay.gameObject.SetActive(true);
                meetingUnderlay.enabled = false;
            }

            if (infoUnderlay == null)
            {
                infoUnderlay = UnityEngine.Object.Instantiate(meetingUnderlay, hudManager.transform);
                infoUnderlay.transform.localPosition = new Vector3(0f, 0f, -900f);
                infoUnderlay.gameObject.SetActive(true);
                infoUnderlay.enabled = false;
            }

            if (infoOverlayRules == null)
            {
                infoOverlayRules          = UnityEngine.Object.Instantiate(hudManager.TaskText, hudManager.transform);
                infoOverlayRules.fontSize = infoOverlayRules.fontSizeMin = infoOverlayRules.fontSizeMax = 1.15f;
                infoOverlayRules.autoSizeTextContainer   = false;
                infoOverlayRules.enableWordWrapping      = false;
                infoOverlayRules.alignment               = TMPro.TextAlignmentOptions.TopLeft;
                infoOverlayRules.transform.position      = Vector3.zero;
                infoOverlayRules.transform.localPosition = new Vector3(-2.5f, 1.15f, -910f);
                infoOverlayRules.transform.localScale    = Vector3.one;
                infoOverlayRules.color   = Palette.White;
                infoOverlayRules.enabled = false;
            }

            if (infoOverlayRoles == null)
            {
                infoOverlayRoles = UnityEngine.Object.Instantiate(infoOverlayRules, hudManager.transform);
                infoOverlayRoles.maxVisibleLines         = 28;
                infoOverlayRoles.fontSize                = infoOverlayRoles.fontSizeMin = infoOverlayRoles.fontSizeMax = 1.15f;
                infoOverlayRoles.outlineWidth           += 0.02f;
                infoOverlayRoles.autoSizeTextContainer   = false;
                infoOverlayRoles.enableWordWrapping      = false;
                infoOverlayRoles.alignment               = TMPro.TextAlignmentOptions.TopLeft;
                infoOverlayRoles.transform.position      = Vector3.zero;
                infoOverlayRoles.transform.localPosition = infoOverlayRules.transform.localPosition + new Vector3(2.5f, 0.0f, 0.0f);
                infoOverlayRoles.transform.localScale    = Vector3.one;
                infoOverlayRoles.color   = Palette.White;
                infoOverlayRoles.enabled = false;
            }

            if (roleUnderlay == null)
            {
                roleUnderlay = UnityEngine.Object.Instantiate(meetingUnderlay, hudManager.transform);
                roleUnderlay.transform.localPosition = new Vector3(0f, 0f, -900f);
                roleUnderlay.gameObject.SetActive(true);
                roleUnderlay.enabled = false;
            }

            if (roleOverlayList == null)
            {
                roleOverlayList = new TMPro.TextMeshPro[3];
            }

            for (var i = 0; i < roleOverlayList.Length; i++)
            {
                if (roleOverlayList[i] == null)
                {
                    if (i == 0)
                    {
                        roleOverlayList[i] = UnityEngine.Object.Instantiate(hudManager.TaskText, hudManager.transform);

                        initializeRoleOverlay(roleOverlayList[i]);

                        roleOverlayList[i].transform.localPosition = new Vector3(-3.5f, 1.2f, -910f);
                    }
                    else
                    {
                        roleOverlayList[i] = UnityEngine.Object.Instantiate(roleOverlayList[i - 1], hudManager.transform);

                        initializeRoleOverlay(roleOverlayList[i]);

                        roleOverlayList[i].transform.localPosition = roleOverlayList[i - 1].transform.localPosition + new Vector3(3.1f, 0.0f, 0.0f);
                    }
                }
            }

            if (roleDatas == null)
            {
                roleDatas = new List <string>();

                StringBuilder entry   = new StringBuilder();
                List <string> entries = new List <string>();

                // First add the presets and the role counts
                entries.Add(GameOptionsDataPatch.optionToString(CustomOptionHolder.presetSelection));

                var optionName = CustomOptionHolder.cs(new Color(204f / 255f, 204f / 255f, 0, 1f), ModTranslation.getString("crewmateRoles"));
                var min        = CustomOptionHolder.crewmateRolesCountMin.getSelection();
                var max        = CustomOptionHolder.crewmateRolesCountMax.getSelection();
                if (min > max)
                {
                    min = max;
                }
                var optionValue = (min == max) ? $"{max}" : $"{min} - {max}";
                entry.AppendLine($"{optionName}: {optionValue}");

                optionName = CustomOptionHolder.cs(new Color(204f / 255f, 204f / 255f, 0, 1f), ModTranslation.getString("neutralRoles"));
                min        = CustomOptionHolder.neutralRolesCountMin.getSelection();
                max        = CustomOptionHolder.neutralRolesCountMax.getSelection();
                if (min > max)
                {
                    min = max;
                }
                optionValue = (min == max) ? $"{max}" : $"{min} - {max}";
                entry.AppendLine($"{optionName}: {optionValue}");

                optionName = CustomOptionHolder.cs(new Color(204f / 255f, 204f / 255f, 0, 1f), ModTranslation.getString("impostorRoles"));
                min        = CustomOptionHolder.impostorRolesCountMin.getSelection();
                max        = CustomOptionHolder.impostorRolesCountMax.getSelection();
                if (min > max)
                {
                    min = max;
                }
                optionValue = (min == max) ? $"{max}" : $"{min} - {max}";
                entry.AppendLine($"{optionName}: {optionValue}");

                entries.Add(entry.ToString().Trim('\r', '\n'));

                int maxLines = 28;

                foreach (CustomOption option in CustomOption.options)
                {
                    if ((option == CustomOptionHolder.presetSelection) ||
                        (option == CustomOptionHolder.crewmateRolesCountMin) ||
                        (option == CustomOptionHolder.crewmateRolesCountMax) ||
                        (option == CustomOptionHolder.neutralRolesCountMin) ||
                        (option == CustomOptionHolder.neutralRolesCountMax) ||
                        (option == CustomOptionHolder.impostorRolesCountMin) ||
                        (option == CustomOptionHolder.impostorRolesCountMax))
                    {
                        continue;
                    }

                    if (option.parent == null)
                    {
                        if (!option.enabled)
                        {
                            continue;
                        }

                        entry = new StringBuilder();
                        if (!option.isHidden)
                        {
                            entry.AppendLine(GameOptionsDataPatch.optionToString(option));
                        }

                        addChildren(option, ref entry, !option.isHidden);

                        // 1つのオプションが最大行を越えていた場合、最大行までで分割する
                        int lines = entry.ToString().Trim('\r', '\n').Count(c => c == '\n') + 1;
                        while (lines > maxLines)
                        {
                            var line       = 0;
                            var newEntry   = new StringBuilder();
                            var entryLines = entry.ToString().Trim('\r', '\n').Split(new[] { "\r\n", "\n", "\r" }, StringSplitOptions.None);
                            foreach (var entryLine in entryLines)
                            {
                                newEntry.AppendLine(entryLine);
                                entry.Remove(0, entryLine.Length + Environment.NewLine.Length);
                                line++;
                                if (maxLines <= line)
                                {
                                    break;
                                }
                            }
                            entries.Add(newEntry.ToString().Trim('\r', '\n'));
                            lines -= maxLines;
                        }

                        entries.Add(entry.ToString().Trim('\r', '\n'));
                    }
                }

                int    lineCount = 0;
                string page      = "";
                foreach (var e in entries)
                {
                    int lines = e.Count(c => c == '\n') + 1;

                    if (lineCount + lines > maxLines)
                    {
                        roleDatas.Add(page);
                        page      = "";
                        lineCount = 0;
                    }

                    page       = page + e + "\n\n";
                    lineCount += lines + 1;
                }

                page = page.Trim('\r', '\n');
                if (page != "")
                {
                    roleDatas.Add(page);
                }

                maxRolePage = ((roleDatas.Count - 1) / 3) + 1;
            }

            return(true);
        }
Exemple #2
0
        public static void MakeButtons(HudManager hm)
        {
            // Fox stealth
            foxButton = new CustomButton(
                () =>
            {
                if (foxButton.isEffectActive)
                {
                    foxButton.Timer = 0;
                    return;
                }

                MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.FoxStealth, Hazel.SendOption.Reliable, -1);
                writer.Write(PlayerControl.LocalPlayer.PlayerId);
                writer.Write(true);
                AmongUsClient.Instance.FinishRpcImmediately(writer);
                RPCProcedure.foxStealth(PlayerControl.LocalPlayer.PlayerId, true);
            },
                () => { return(PlayerControl.LocalPlayer.isRole(RoleType.Fox) && !PlayerControl.LocalPlayer.Data.IsDead); },
                () =>
            {
                if (foxButton.isEffectActive)
                {
                    foxButton.buttonText = ModTranslation.getString("FoxUnstealthText");
                }
                else
                {
                    foxButton.buttonText = ModTranslation.getString("FoxStealthText");
                }
                return(PlayerControl.LocalPlayer.CanMove);
            },
                () =>
            {
                foxButton.Timer = foxButton.MaxTimer = Fox.stealthCooldown;
            },
                Fox.getHideButtonSprite(),
                new Vector3(-1.8f, -0.06f, 0),
                hm,
                hm.AbilityButton,
                KeyCode.F,
                true,
                Fox.stealthDuration,
                () =>
            {
                foxButton.Timer      = foxButton.MaxTimer = Fox.stealthCooldown;
                MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.FoxStealth, Hazel.SendOption.Reliable, -1);
                writer.Write(PlayerControl.LocalPlayer.PlayerId);
                writer.Write(false);
                AmongUsClient.Instance.FinishRpcImmediately(writer);
                RPCProcedure.foxStealth(PlayerControl.LocalPlayer.PlayerId, false);
            }
                );
            foxButton.Timer             = foxButton.MaxTimer = Fox.stealthCooldown;
            foxButton.buttonText        = ModTranslation.getString("FoxStealthText");
            foxButton.effectCancellable = true;

            foxRepairButton = new CustomButton(
                () =>
            {
                bool sabotageActive = false;
                foreach (PlayerTask task in PlayerControl.LocalPlayer.myTasks)
                {
                    if (task.TaskType == TaskTypes.FixLights || task.TaskType == TaskTypes.RestoreOxy || task.TaskType == TaskTypes.ResetReactor || task.TaskType == TaskTypes.ResetSeismic || task.TaskType == TaskTypes.FixComms || task.TaskType == TaskTypes.StopCharles)
                    {
                        sabotageActive = true;
                    }
                }
                if (!sabotageActive)
                {
                    return;
                }

                foreach (PlayerTask task in PlayerControl.LocalPlayer.myTasks)
                {
                    if (task.TaskType == TaskTypes.FixLights)
                    {
                        MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.EngineerFixLights, Hazel.SendOption.Reliable, -1);
                        AmongUsClient.Instance.FinishRpcImmediately(writer);
                        RPCProcedure.engineerFixLights();
                    }
                    else if (task.TaskType == TaskTypes.RestoreOxy)
                    {
                        ShipStatus.Instance.RpcRepairSystem(SystemTypes.LifeSupp, 0 | 64);
                        ShipStatus.Instance.RpcRepairSystem(SystemTypes.LifeSupp, 1 | 64);
                    }
                    else if (task.TaskType == TaskTypes.ResetReactor)
                    {
                        ShipStatus.Instance.RpcRepairSystem(SystemTypes.Reactor, 16);
                    }
                    else if (task.TaskType == TaskTypes.ResetSeismic)
                    {
                        ShipStatus.Instance.RpcRepairSystem(SystemTypes.Laboratory, 16);
                    }
                    else if (task.TaskType == TaskTypes.FixComms)
                    {
                        ShipStatus.Instance.RpcRepairSystem(SystemTypes.Comms, 16 | 0);
                        ShipStatus.Instance.RpcRepairSystem(SystemTypes.Comms, 16 | 1);
                    }
                    else if (task.TaskType == TaskTypes.StopCharles)
                    {
                        ShipStatus.Instance.RpcRepairSystem(SystemTypes.Reactor, 0 | 16);
                        ShipStatus.Instance.RpcRepairSystem(SystemTypes.Reactor, 1 | 16);
                    }
                }
                numRepair -= 1;
            },
                () => { return(PlayerControl.LocalPlayer.isRole(RoleType.Fox) && PlayerControl.LocalPlayer.isAlive() && numRepair > 0); },
                () =>
            {
                bool sabotageActive = false;
                foreach (PlayerTask task in PlayerControl.LocalPlayer.myTasks)
                {
                    if (task.TaskType == TaskTypes.FixLights || task.TaskType == TaskTypes.RestoreOxy || task.TaskType == TaskTypes.ResetReactor || task.TaskType == TaskTypes.ResetSeismic || task.TaskType == TaskTypes.FixComms || task.TaskType == TaskTypes.StopCharles)
                    {
                        sabotageActive = true;
                    }
                }
                return(sabotageActive && numRepair > 0 && PlayerControl.LocalPlayer.CanMove);
            },
                () => { foxRepairButton.Timer = foxRepairButton.MaxTimer = 0f; },
                Fox.getRepairButtonSprite(),
                new Vector3(-0.9f, 1f, 0),
                hm,
                hm.AbilityButton,
                KeyCode.G
                );
            foxRepairButton.Timer      = foxRepairButton.MaxTimer = 0f;
            foxRepairButton.buttonText = ModTranslation.getString("FoxRepairText");;

            foxImmoralistButton = new CustomButton(
                () =>
            {
                MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.FoxCreatesImmoralist, Hazel.SendOption.Reliable, -1);
                writer.Write(currentTarget.PlayerId);
                AmongUsClient.Instance.FinishRpcImmediately(writer);
                RPCProcedure.foxCreatesImmoralist(currentTarget.PlayerId);
            },
                () => { return(!Immoralist.exists && canCreateImmoralist && PlayerControl.LocalPlayer.isRole(RoleType.Fox) && PlayerControl.LocalPlayer.isAlive()); },
                () => { return(canCreateImmoralist && Fox.currentTarget != null && PlayerControl.LocalPlayer.CanMove); },
                () => { foxImmoralistButton.Timer = foxImmoralistButton.MaxTimer = 20f; },
                getImmoralistButtonSprite(),
                new Vector3(-1.8f, 1f, 0),
                hm,
                hm.AbilityButton,
                KeyCode.I
                );
            foxImmoralistButton.Timer      = foxImmoralistButton.MaxTimer = 20f;
            foxImmoralistButton.buttonText = ModTranslation.getString("FoxImmoralistText");
        }
        public static void divine(PlayerControl p)
        {
            // FortuneTeller.divine(p, resultIsCrewOrNot);
            string msgBase = "";
            string msgInfo = "";
            Color  color   = Color.white;

            if (divineResult == DivineResults.BlackWhite)
            {
                if (p.isCrew())
                {
                    msgBase = "divineMessageIsCrew";
                    color   = Color.white;
                }
                else
                {
                    msgBase = "divineMessageIsntCrew";
                    color   = Palette.ImpostorRed;
                }
            }

            else if (divineResult == DivineResults.Team)
            {
                msgBase = "divineMessageTeam";
                if (p.isCrew())
                {
                    msgInfo = ModTranslation.getString("divineCrew");
                    color   = Color.white;
                }
                else if (p.isNeutral())
                {
                    msgInfo = ModTranslation.getString("divineNeutral");
                    color   = Color.yellow;
                }
                else
                {
                    msgInfo = ModTranslation.getString("divineImpostor");
                    color   = Palette.ImpostorRed;
                }
            }

            else if (divineResult == DivineResults.Role)
            {
                msgBase = "divineMessageRole";
                msgInfo = String.Join(" ", RoleInfo.getRoleInfoForPlayer(p).Select(x => Helpers.cs(x.color, x.name)).ToArray());
            }

            string msg = string.Format(ModTranslation.getString(msgBase), p.name, msgInfo);

            if (!string.IsNullOrWhiteSpace(msg))
            {
                FortuneTeller.fortuneTellerMessage(msg, 5f, color);
            }

            if (Constants.ShouldPlaySfx())
            {
                SoundManager.Instance.PlaySound(DestroyableSingleton <HudManager> .Instance.TaskCompleteSound, false, 0.8f);
            }
            numUsed += 1;

            // 占いを実行したことで発火される処理を他クライアントに通知
            MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.FortuneTellerUsedDivine, Hazel.SendOption.Reliable, -1);

            writer.Write(PlayerControl.LocalPlayer.PlayerId);
            writer.Write(p.PlayerId);
            AmongUsClient.Instance.FinishRpcImmediately(writer);
            RPCProcedure.fortuneTellerUsedDivine(PlayerControl.LocalPlayer.PlayerId, p.PlayerId);
            numUsed += 1;
        }
Exemple #4
0
        public static void MakeButtons(HudManager hm)
        {
            // Bomber button
            bomberButton = new CustomButton(
                // OnClick
                () =>
            {
                if (currentTarget != null)
                {
                    tmpTarget = currentTarget;
                    bomberButton.HasEffect = true;
                }
            },
                // HasButton
                () => { return(PlayerControl.LocalPlayer.isRole(RoleType.BomberB) && PlayerControl.LocalPlayer.isAlive() && BomberA.isAlive()); },
                // CouldUse
                () =>
            {
                if (bomberButton.isEffectActive && tmpTarget != currentTarget)
                {
                    tmpTarget                   = null;
                    bomberButton.Timer          = 0f;
                    bomberButton.isEffectActive = false;
                }

                return(PlayerControl.LocalPlayer.CanMove && currentTarget != null);
            },
                // OnMeetingEnds
                () =>
            {
                bomberButton.Timer          = bomberButton.MaxTimer;
                bomberButton.isEffectActive = false;
                tmpTarget = null;
            },
                getBomberButtonSprite(),
                new Vector3(-1.8f, -0.06f, 0),
                hm,
                hm.KillButton,
                KeyCode.F,
                true,
                duration,
                // OnEffectsEnd
                () =>
            {
                if (tmpTarget != null)
                {
                    MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.PlantBomb, Hazel.SendOption.Reliable, -1);
                    writer.Write(tmpTarget.PlayerId);
                    AmongUsClient.Instance.FinishRpcImmediately(writer);
                    BomberB.bombTarget = tmpTarget;
                }

                tmpTarget          = null;
                bomberButton.Timer = bomberButton.MaxTimer;
            }
                );
            bomberButton.buttonText = ModTranslation.getString("bomberPlantBomb");
            // Bomber button
            releaseButton = new CustomButton(
                // OnClick
                () =>
            {
                var bomberA    = BomberA.allPlayers.FirstOrDefault();
                float distance = Vector2.Distance(PlayerControl.LocalPlayer.transform.localPosition, bomberA.transform.localPosition);

                if (PlayerControl.LocalPlayer.CanMove && BomberA.bombTarget != null && BomberB.bombTarget != null && bomberA.isAlive() && distance < 1)
                {
                    var target           = BomberB.bombTarget;
                    MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.ReleaseBomb, Hazel.SendOption.Reliable, -1);
                    writer.Write(PlayerControl.LocalPlayer.PlayerId);
                    writer.Write(target.PlayerId);
                    AmongUsClient.Instance.FinishRpcImmediately(writer);
                    RPCProcedure.releaseBomb(PlayerControl.LocalPlayer.PlayerId, target.PlayerId);
                }
            },
                // HasButton
                () => { return(PlayerControl.LocalPlayer.isRole(RoleType.BomberB) && PlayerControl.LocalPlayer.isAlive() && BomberA.isAlive()); },
                // CouldUse
                () =>
            {
                var bomberA    = BomberA.allPlayers.FirstOrDefault();
                float distance = Vector2.Distance(PlayerControl.LocalPlayer.transform.localPosition, bomberA.transform.localPosition);

                return(PlayerControl.LocalPlayer.CanMove && BomberA.bombTarget != null && BomberB.bombTarget != null && bomberA.isAlive() && distance < 1);
            },
                // OnMeetingEnds
                () =>
            {
                releaseButton.Timer = releaseButton.MaxTimer;
            },
                getReleaseButtonSprite(),
                new Vector3(-2.7f, -0.06f, 0),
                hm,
                hm.KillButton,
                KeyCode.F,
                false
                );
            releaseButton.buttonText = ModTranslation.getString("bomberDetonate");
        }
Exemple #5
0
        public override void FixedUpdate()
        {
            // 処理に自信がないので念の為tryで囲っておく
            try{
                if (PlayerControl.LocalPlayer.isRole(RoleType.Trapper) && Trap.traps.Count != 0 && !Trap.hasTrappedPlayer() && !meetingFlag)
                {
                    // トラップを踏んだプレイヤーを動けなくする
                    foreach (var p in PlayerControl.AllPlayerControls)
                    {
                        foreach (var trap in Trap.traps)
                        {
                            if (DateTime.UtcNow.Subtract(trap.Value.placedTime).TotalSeconds < extensionTime)
                            {
                                continue;
                            }
                            if (trap.Value.isActive || p.isDead() || p.inVent || meetingFlag)
                            {
                                continue;
                            }
                            var p1 = p.transform.localPosition;
                            Dictionary <GameObject, byte> listActivate = new Dictionary <GameObject, byte>();
                            var p2       = trap.Value.trap.transform.localPosition;
                            var distance = Vector3.Distance(p1, p2);
                            if (distance < trapRange)
                            {
                                TMPro.TMP_Text text;
                                RoomTracker    roomTracker = HudManager.Instance?.roomTracker;
                                GameObject     gameObject  = UnityEngine.Object.Instantiate(roomTracker.gameObject);
                                UnityEngine.Object.DestroyImmediate(gameObject.GetComponent <RoomTracker>());
                                gameObject.transform.SetParent(HudManager.Instance.transform);
                                gameObject.transform.localPosition = new Vector3(0, -1.8f, gameObject.transform.localPosition.z);
                                gameObject.transform.localScale    = Vector3.one * 2f;
                                text      = gameObject.GetComponent <TMPro.TMP_Text>();
                                text.text = String.Format(ModTranslation.getString("trapperGetTrapped"), p.name);
                                HudManager.Instance.StartCoroutine(Effects.Lerp(3f, new Action <float>((p) => {
                                    if (p == 1f && text != null && text.gameObject != null)
                                    {
                                        UnityEngine.Object.Destroy(text.gameObject);
                                    }
                                })));
                                MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.ActivateTrap, Hazel.SendOption.Reliable, -1);
                                writer.Write(trap.Key);
                                writer.Write(PlayerControl.LocalPlayer.PlayerId);
                                writer.Write(p.PlayerId);
                                AmongUsClient.Instance.FinishRpcImmediately(writer);
                                RPCProcedure.activateTrap(trap.Key, PlayerControl.LocalPlayer.PlayerId, p.PlayerId);
                                break;
                            }
                        }
                    }
                }

                if (PlayerControl.LocalPlayer.isRole(RoleType.Trapper) && Trap.hasTrappedPlayer() && !meetingFlag)
                {
                    // トラップにかかっているプレイヤーを救出する
                    foreach (var trap in Trap.traps)
                    {
                        if (trap.Value.trap == null || !trap.Value.isActive)
                        {
                            return;
                        }
                        Vector3 p1 = trap.Value.trap.transform.position;
                        foreach (var player in PlayerControl.AllPlayerControls)
                        {
                            if (player.PlayerId == trap.Value.target.PlayerId || player.isDead() || player.inVent || player.isRole(RoleType.Trapper))
                            {
                                continue;
                            }
                            Vector3 p2       = player.transform.position;
                            float   distance = Vector3.Distance(p1, p2);
                            if (distance < 0.5)
                            {
                                MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.DisableTrap, Hazel.SendOption.Reliable, -1);
                                writer.Write(trap.Key);
                                AmongUsClient.Instance.FinishRpcImmediately(writer);
                                RPCProcedure.disableTrap(trap.Key);
                            }
                        }
                    }
                }
            }
            catch (NullReferenceException e) {
                Helpers.log(e.Message);
            }
        }
Exemple #6
0
        public static void MakeButtons(HudManager hm)
        {
            fortuneTellerButtons = new List <CustomButton>();

            Vector3 fortuneTellerCalcPos(byte index)
            {
                int adjIndex = index < PlayerControl.LocalPlayer.PlayerId ? index : index - 1;

                return(new Vector3(-0.25f, -0.15f, 0) + Vector3.right * adjIndex * 0.55f);
            }

            Action fortuneTellerButtonOnClick(byte index)
            {
                return(() =>
                {
                    if (PlayerControl.LocalPlayer.CanMove && local.numUsed < 1 && local.canDivine(index))
                    {
                        PlayerControl p = Helpers.playerById(index);
                        local.divine(p);
                    }
                });
            };

            Func <bool> fortuneTellerHasButton(byte index)
            {
                return(() =>
                {
                    return PlayerControl.LocalPlayer.isRole(RoleType.FortuneTeller);
                    //var p = PlayerControl.LocalPlayer;
                    //if (!p.isRole(RoleType.FortuneTeller)) return false;
                });
            }

            void setButtonPos(byte index)
            {
                Vector3 pos   = fortuneTellerCalcPos(index);
                Vector3 scale = new Vector3(0.4f, 0.5f, 1.0f);

                Vector3 iconBase = hm.UseButton.transform.localPosition;

                iconBase.x *= -1;
                if (fortuneTellerButtons[index].PositionOffset != pos)
                {
                    fortuneTellerButtons[index].PositionOffset            = pos;
                    fortuneTellerButtons[index].LocalScale                = scale;
                    MapOptions.playerIcons[index].transform.localPosition = iconBase + pos;
                }
            }

            void setIconPos(byte index, bool transparent)
            {
                MapOptions.playerIcons[index].transform.localScale = Vector3.one * 0.25f;
                MapOptions.playerIcons[index].gameObject.SetActive(PlayerControl.LocalPlayer.CanMove);
                MapOptions.playerIcons[index].setSemiTransparent(transparent);
            }

            Func <bool> fortuneTellerCouldUse(byte index)
            {
                return(() =>
                {
                    // 占い師以外の場合、リソースがない場合はボタンを表示しない
                    if (!MapOptions.playerIcons.ContainsKey(index) ||
                        !PlayerControl.LocalPlayer.isRole(RoleType.FortuneTeller) ||
                        PlayerControl.LocalPlayer.isDead() ||
                        PlayerControl.LocalPlayer.PlayerId == index ||
                        !isCompletedNumTasks(PlayerControl.LocalPlayer) ||
                        local.numUsed >= 1)
                    {
                        if (MapOptions.playerIcons.ContainsKey(index))
                        {
                            MapOptions.playerIcons[index].gameObject.SetActive(false);
                        }
                        if (fortuneTellerButtons.Count > index)
                        {
                            fortuneTellerButtons[index].setActive(false);
                        }

                        return false;
                    }

                    // ボタンの位置を変更
                    setButtonPos(index);

                    // ボタンにテキストを設定
                    bool status = true;
                    if (local.playerStatus.ContainsKey(index))
                    {
                        status = local.playerStatus[index];
                    }

                    if (status)
                    {
                        var progress = local.progress.ContainsKey(index) ? local.progress[index] : 0f;
                        fortuneTellerButtons[index].buttonText = $"{progress:0.0}/{duration:0.0}";
                    }
                    else
                    {
                        fortuneTellerButtons[index].buttonText = ModTranslation.getString("fortuneTellerDead");
                    }

                    // アイコンの位置と透明度を変更
                    setIconPos(index, !local.canDivine(index));

                    MapOptions.playerIcons[index].gameObject.SetActive(Helpers.ShowButtons && PlayerControl.LocalPlayer.CanMove);
                    fortuneTellerButtons[index].setActive(Helpers.ShowButtons && PlayerControl.LocalPlayer.CanMove);

                    return PlayerControl.LocalPlayer.CanMove && local.numUsed < 1 && local.canDivine(index);
                });
            }

            for (byte i = 0; i < 15; i++)
            {
                CustomButton fortuneTellerButton = new CustomButton(
                    // Action OnClick
                    fortuneTellerButtonOnClick(i),
                    // bool HasButton
                    fortuneTellerHasButton(i),
                    // bool CouldUse
                    fortuneTellerCouldUse(i),
                    // Action OnMeetingEnds
                    () => { },
                    // sprite
                    null,
                    // position
                    Vector3.zero,
                    // hudmanager
                    hm,
                    hm.AbilityButton,
                    // keyboard shortcut
                    KeyCode.None,
                    true
                    );
                fortuneTellerButton.Timer    = 0.0f;
                fortuneTellerButton.MaxTimer = 0.0f;

                fortuneTellerButtons.Add(fortuneTellerButton);
            }
        }
        public void UpdateStatusText()
        {
            // ロード画面でstatusTextを生成すると上手く表示されないのでゲームが開始してから最初に感染させた時点から表示する
            if (!hasInfected())
            {
                return;
            }
            if (MeetingHud.Instance != null)
            {
                if (statusText != null)
                {
                    statusText.gameObject.SetActive(false);
                }
                return;
            }

            if ((player != null && PlayerControl.LocalPlayer == player) || PlayerControl.LocalPlayer.isDead())
            {
                if (statusText == null)
                {
                    GameObject gameObject = UnityEngine.Object.Instantiate(HudManager.Instance?.roomTracker.gameObject);
                    gameObject.transform.SetParent(HudManager.Instance.transform);
                    gameObject.SetActive(true);
                    UnityEngine.Object.DestroyImmediate(gameObject.GetComponent <RoomTracker>());
                    statusText = gameObject.GetComponent <TMPro.TMP_Text>();
                    gameObject.transform.localPosition = new Vector3(-2.7f, -0.1f, gameObject.transform.localPosition.z);

                    statusText.transform.localScale = new Vector3(1f, 1f, 1f);
                    statusText.fontSize             = 1.5f;
                    statusText.fontSizeMin          = 1.5f;
                    statusText.fontSizeMax          = 1.5f;
                    statusText.alignment            = TMPro.TextAlignmentOptions.BottomLeft;
                }

                statusText.gameObject.SetActive(true);
                string text = $"[{ModTranslation.getString("plagueDoctorProgress")}]\n";
                foreach (PlayerControl p in PlayerControl.AllPlayerControls)
                {
                    if (p == player)
                    {
                        continue;
                    }
                    if (dead.ContainsKey(p.PlayerId) && dead[p.PlayerId])
                    {
                        continue;
                    }
                    text += $"{p.name}: ";
                    if (infected.ContainsKey(p.PlayerId))
                    {
                        text += Helpers.cs(Color.red, ModTranslation.getString("plagueDoctorInfectedText"));
                    }
                    else
                    {
                        // データが無い場合は作成する
                        if (!progress.ContainsKey(p.PlayerId))
                        {
                            progress[p.PlayerId] = 0f;
                        }
                        text += getProgressString(progress[p.PlayerId]);
                    }
                    text += "\n";
                }

                statusText.text = text;
            }
        }
Exemple #8
0
        public static void MakeButtons(HudManager hm)
        {
            // Sheriff Kill
            sheriffKillButton = new CustomButton(
                () =>
            {
                if (local.numShots <= 0)
                {
                    return;
                }

                MurderAttemptResult murderAttemptResult = Helpers.checkMuderAttempt(PlayerControl.LocalPlayer, local.currentTarget);
                if (murderAttemptResult == MurderAttemptResult.SuppressKill)
                {
                    return;
                }

                if (murderAttemptResult == MurderAttemptResult.PerformKill)
                {
                    bool misfire  = false;
                    byte targetId = local.currentTarget.PlayerId;;
                    if ((local.currentTarget.Data.Role.IsImpostor && (!local.currentTarget.hasModifier(ModifierType.Mini) || Mini.isGrownUp(local.currentTarget))) ||
                        (Sheriff.spyCanDieToSheriff && Spy.spy == local.currentTarget) ||
                        (Sheriff.madmateCanDieToSheriff && local.currentTarget.hasModifier(ModifierType.Madmate)) ||
                        (Sheriff.createdMadmateCanDieToSheriff && local.currentTarget.hasModifier(ModifierType.CreatedMadmate)) ||
                        (Sheriff.canKillNeutrals && local.currentTarget.isNeutral()) ||
                        (Jackal.jackal == local.currentTarget || Sidekick.sidekick == local.currentTarget))
                    {
                        //targetId = Sheriff.currentTarget.PlayerId;
                        misfire = false;
                    }
                    else
                    {
                        //targetId = PlayerControl.LocalPlayer.PlayerId;
                        misfire = true;
                    }

                    // Mad sheriff always misfires.
                    if (local.player.hasModifier(ModifierType.Madmate))
                    {
                        misfire = true;
                    }
                    MessageWriter killWriter = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SheriffKill, Hazel.SendOption.Reliable, -1);
                    killWriter.Write(PlayerControl.LocalPlayer.Data.PlayerId);
                    killWriter.Write(targetId);
                    killWriter.Write(misfire);
                    AmongUsClient.Instance.FinishRpcImmediately(killWriter);
                    RPCProcedure.sheriffKill(PlayerControl.LocalPlayer.Data.PlayerId, targetId, misfire);
                }

                sheriffKillButton.Timer = sheriffKillButton.MaxTimer;
                local.currentTarget     = null;
            },
                () => { return(PlayerControl.LocalPlayer.isRole(RoleType.Sheriff) && local.numShots > 0 && !PlayerControl.LocalPlayer.Data.IsDead && local.canKill); },
                () =>
            {
                if (sheriffNumShotsText != null)
                {
                    if (local.numShots > 0)
                    {
                        sheriffNumShotsText.text = String.Format(ModTranslation.getString("sheriffShots"), local.numShots);
                    }
                    else
                    {
                        sheriffNumShotsText.text = "";
                    }
                }
                return(local.currentTarget && PlayerControl.LocalPlayer.CanMove);
            },
                () => { sheriffKillButton.Timer = sheriffKillButton.MaxTimer; },
                hm.KillButton.graphic.sprite,
                new Vector3(0f, 1f, 0),
                hm,
                hm.KillButton,
                KeyCode.Q
                );

            sheriffNumShotsText      = GameObject.Instantiate(sheriffKillButton.actionButton.cooldownTimerText, sheriffKillButton.actionButton.cooldownTimerText.transform.parent);
            sheriffNumShotsText.text = "";
            sheriffNumShotsText.enableWordWrapping       = false;
            sheriffNumShotsText.transform.localScale     = Vector3.one * 0.5f;
            sheriffNumShotsText.transform.localPosition += new Vector3(-0.05f, 0.7f, 0);
        }
Exemple #9
0
 public static string tl(string key)
 {
     return ModTranslation.getString(key);
 }
Exemple #10
0
        public static void UpdateTimerText()
        {
            if (restrictDevices == 0 || (!restrictAdminText && !restrictCamerasText && !restrictVitalsText))
            {
                return;
            }
            if (HudManager.Instance == null)
            {
                return;
            }

            // Admin
            if (restrictAdminText)
            {
                AdminTimerText = UnityEngine.Object.Instantiate(HudManager.Instance.TaskText, HudManager.Instance.transform);
                float y = -4.0f;
                if (restrictCamerasText)
                {
                    y += 0.2f;
                }
                if (restrictVitalsText)
                {
                    y += 0.2f;
                }
                AdminTimerText.transform.localPosition = new Vector3(-3.5f, y, 0);
                if (restrictAdminTime > 0)
                {
                    // AdminTimerText.text = $"Admin: {Mathf.RoundToInt(restrictAdminTime)} sec remaining";
                    AdminTimerText.text = String.Format(ModTranslation.getString("adminText"), restrictAdminTime.ToString("0.00"));
                }
                else
                {
                    // AdminTimerText.text = "Admin: ran out of time";
                    AdminTimerText.text = ModTranslation.getString("adminRanOut");
                }
                AdminTimerText.gameObject.SetActive(true);
            }

            // Cameras
            if (restrictCamerasText)
            {
                CamerasTimerText = UnityEngine.Object.Instantiate(HudManager.Instance.TaskText, HudManager.Instance.transform);
                float y = -4.0f;
                if (restrictVitalsText)
                {
                    y += 0.2f;
                }
                CamerasTimerText.transform.localPosition = new Vector3(-3.5f, y, 0);
                if (restrictCamerasTime > 0)
                {
                    // CamerasTimerText.text = $"Cameras: {Mathf.RoundToInt(restrictCamerasTime)} sec remaining";
                    CamerasTimerText.text = String.Format(ModTranslation.getString("camerasText"), restrictCamerasTime.ToString("0.00"));
                }
                else
                {
                    // CamerasTimerText.text = "Cameras: ran out of time";
                    CamerasTimerText.text = ModTranslation.getString("camerasRanOut");
                }
                CamerasTimerText.gameObject.SetActive(true);
            }

            // Vitals
            if (restrictVitalsText)
            {
                VitalsTimerText = UnityEngine.Object.Instantiate(HudManager.Instance.TaskText, HudManager.Instance.transform);
                VitalsTimerText.transform.localPosition = new Vector3(-3.5f, -4.0f, 0);
                if (restrictVitalsTime > 0)
                {
                    // VitalsTimerText.text = $"Vitals: {Mathf.RoundToInt(restrictVitalsTime)} sec remaining";
                    VitalsTimerText.text = String.Format(ModTranslation.getString("vitalsText"), restrictVitalsTime.ToString("0.00"));
                }
                else
                {
                    // VitalsTimerText.text = "Vitals: ran out of time";
                    VitalsTimerText.text = ModTranslation.getString("vitalsRanOut");
                }
                VitalsTimerText.gameObject.SetActive(true);
            }
        }
Exemple #11
0
        public static void makeButtons(HudManager hm)
        {
            Ninja.MakeButtons(hm);
            Sheriff.MakeButtons(hm);
            PlagueDoctor.MakeButtons(hm);
            Lighter.MakeButtons(hm);
            SerialKiller.MakeButtons(hm);
            Fox.MakeButtons(hm);
            Immoralist.MakeButtons(hm);
            FortuneTeller.MakeButtons(hm);
            LastImpostor.MakeButtons(hm);
            SoulPlayer.MakeButtons(hm);
            SchrodingersCat.MakeButtons(hm);
            Trapper.MakeButtons(hm);
            BomberA.MakeButtons(hm);
            BomberB.MakeButtons(hm);
            EvilTracker.MakeButtons(hm);
            Puppeteer.MakeButtons(hm);
            MimicK.MakeButtons(hm);
            MimicA.MakeButtons(hm);

            gmButtons     = new List <CustomButton>();
            gmKillButtons = new List <CustomButton>();

            Vector3 gmCalcPos(byte index)
            {
                return(new Vector3(-0.25f, -0.25f, 1.0f) + Vector3.right * index * 0.55f);
            }

            Action gmButtonOnClick(byte index)
            {
                return(() =>
                {
                    PlayerControl target = Helpers.playerById(index);
                    if (!MapOptions.playerIcons.ContainsKey(index) || target.Data.Disconnected)
                    {
                        return;
                    }

                    if (GM.gm.transform.position != target.transform.position)
                    {
                        GM.gm.transform.position = target.transform.position;
                    }
                });
            };

            Action gmKillButtonOnClick(byte index)
            {
                return(() =>
                {
                    PlayerControl target = Helpers.playerById(index);
                    if (!MapOptions.playerIcons.ContainsKey(index) || target.Data.Disconnected)
                    {
                        return;
                    }

                    if (!target.Data.IsDead)
                    {
                        MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.GMKill, Hazel.SendOption.Reliable, -1);
                        writer.Write(index);
                        AmongUsClient.Instance.FinishRpcImmediately(writer);
                        RPCProcedure.GMKill(index);
                    }
                    else
                    {
                        MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.GMRevive, Hazel.SendOption.Reliable, -1);
                        writer.Write(index);
                        AmongUsClient.Instance.FinishRpcImmediately(writer);
                        RPCProcedure.GMRevive(index);
                    }
                });
            };

            Func <bool> gmHasButton(byte index)
            {
                return(() =>
                {
                    if ((GM.gm == null || PlayerControl.LocalPlayer != GM.gm) ||
                        (!MapOptions.playerIcons.ContainsKey(index)) ||
                        (!GM.canWarp) ||
                        (Helpers.playerById(index).Data.Disconnected))
                    {
                        return false;
                    }

                    return true;
                });
            }

            Func <bool> gmHasKillButton(byte index)
            {
                return(() =>
                {
                    if ((GM.gm == null || PlayerControl.LocalPlayer != GM.gm) ||
                        (!MapOptions.playerIcons.ContainsKey(index)) ||
                        (!GM.canKill) ||
                        (Helpers.playerById(index).Data.Disconnected))
                    {
                        return false;
                    }

                    return true;
                });
            }

            Func <bool> gmCouldUse(byte index)
            {
                return(() =>
                {
                    if (!MapOptions.playerIcons.ContainsKey(index) || !GM.canWarp)
                    {
                        return false;
                    }

                    Vector3 pos = gmCalcPos(index);
                    Vector3 scale = new Vector3(0.4f, 0.8f, 1.0f);

                    Vector3 iconBase = hm.UseButton.transform.localPosition;
                    iconBase.x *= -1;
                    if (gmButtons[index].PositionOffset != pos)
                    {
                        gmButtons[index].PositionOffset = pos;
                        gmButtons[index].LocalScale = scale;
                        MapOptions.playerIcons[index].transform.localPosition = iconBase + pos;
                        //TheOtherRolesPlugin.Instance.Log.LogInfo($"Updated {index}: {pos.x}, {pos.y}, {pos.z}");
                    }

                    //MapOptions.playerIcons[index].gameObject.SetActive(PlayerControl.LocalPlayer.CanMove);
                    return PlayerControl.LocalPlayer.CanMove;
                });
            }

            Func <bool> gmCouldKill(byte index)
            {
                return(() =>
                {
                    if (!MapOptions.playerIcons.ContainsKey(index) || !GM.canKill)
                    {
                        return false;
                    }

                    Vector3 pos = gmCalcPos(index) + Vector3.up * 0.55f;
                    Vector3 scale = new Vector3(0.4f, 0.25f, 1.0f);
                    if (gmKillButtons[index].PositionOffset != pos)
                    {
                        gmKillButtons[index].PositionOffset = pos;
                        gmKillButtons[index].LocalScale = scale;
                    }

                    PlayerControl target = Helpers.playerById(index);
                    if (target.Data.IsDead)
                    {
                        gmKillButtons[index].buttonText = ModTranslation.getString("gmRevive");
                    }
                    else
                    {
                        gmKillButtons[index].buttonText = ModTranslation.getString("gmKill");
                    }

                    //MapOptions.playerIcons[index].gameObject.SetActive(PlayerControl.LocalPlayer.CanMove);
                    return true;
                });
            }

            for (byte i = 0; i < 15; i++)
            {
                //TheOtherRolesPlugin.Instance.Log.LogInfo($"Added {i}");

                CustomButton gmButton = new CustomButton(
                    // Action OnClick
                    gmButtonOnClick(i),
                    // bool HasButton
                    gmHasButton(i),
                    // bool CouldUse
                    gmCouldUse(i),
                    // Action OnMeetingEnds
                    () => { },
                    // sprite
                    null,
                    // position
                    Vector3.zero,
                    // hudmanager
                    hm,
                    hm.UseButton,
                    // keyboard shortcut
                    null,
                    true
                    );
                gmButton.Timer          = 0.0f;
                gmButton.MaxTimer       = 0.0f;
                gmButton.showButtonText = false;
                gmButtons.Add(gmButton);

                CustomButton gmKillButton = new CustomButton(
                    // Action OnClick
                    gmKillButtonOnClick(i),
                    // bool HasButton
                    gmHasKillButton(i),
                    // bool CouldUse
                    gmCouldKill(i),
                    // Action OnMeetingEnds
                    () => { },
                    // sprite
                    null,
                    // position
                    Vector3.zero,
                    // hudmanager
                    hm,
                    hm.KillButton,
                    // keyboard shortcut
                    null,
                    true
                    );
                gmKillButton.Timer          = 0.0f;
                gmKillButton.MaxTimer       = 0.0f;
                gmKillButton.showButtonText = true;

                var buttonPos = gmKillButton.actionButton.buttonLabelText.transform.localPosition;
                gmKillButton.actionButton.buttonLabelText.transform.localPosition = new Vector3(buttonPos.x, buttonPos.y + 0.6f, -500f);
                gmKillButton.actionButton.buttonLabelText.transform.localScale    = new Vector3(1.5f, 1.8f, 1.0f);

                gmKillButtons.Add(gmKillButton);
            }

            gmZoomOut = new CustomButton(
                () => {
                if (Camera.main.orthographicSize < 18.0f)
                {
                    Camera.main.orthographicSize *= 1.5f;
                    hm.UICamera.orthographicSize *= 1.5f;
                }

                if (hm.transform.localScale.x < 6.0f)
                {
                    hm.transform.localScale *= 1.5f;
                }

                /*TheOtherRolesPlugin.Instance.Log.LogInfo($"Camera zoom {Camera.main.orthographicSize} / {TaskPanelBehaviour.Instance.transform.localPosition.x}");*/
            },
                () => { return(!(GM.gm == null || PlayerControl.LocalPlayer != GM.gm)); },
                () => { return(true); },
                () => { },
                GM.getZoomOutSprite(),
                // position
                Vector3.zero + Vector3.up * 3.75f + Vector3.right * 0.55f,
                // hudmanager
                hm,
                hm.UseButton,
                // keyboard shortcut
                KeyCode.PageDown,
                false
                );
            gmZoomOut.Timer          = 0.0f;
            gmZoomOut.MaxTimer       = 0.0f;
            gmZoomOut.showButtonText = false;
            gmZoomOut.LocalScale     = Vector3.one * 0.275f;

            gmZoomIn = new CustomButton(
                () => {
                if (Camera.main.orthographicSize > 3.0f)
                {
                    Camera.main.orthographicSize /= 1.5f;
                    hm.UICamera.orthographicSize /= 1.5f;
                }

                if (hm.transform.localScale.x > 1.0f)
                {
                    hm.transform.localScale /= 1.5f;
                }

                /*TheOtherRolesPlugin.Instance.Log.LogInfo($"Camera zoom {Camera.main.orthographicSize} / {TaskPanelBehaviour.Instance.transform.localPosition.x}");*/
            },
                () => { return(!(GM.gm == null || PlayerControl.LocalPlayer != GM.gm)); },
                () => { return(true); },
                () => { },
                GM.getZoomInSprite(),
                // position
                Vector3.zero + Vector3.up * 3.75f + Vector3.right * 0.2f,
                // hudmanager
                hm,
                hm.UseButton,
                // keyboard shortcut
                KeyCode.PageUp,
                false
                );
            gmZoomIn.Timer          = 0.0f;
            gmZoomIn.MaxTimer       = 0.0f;
            gmZoomIn.showButtonText = false;
            gmZoomIn.LocalScale     = Vector3.one * 0.275f;
        }
Exemple #12
0
        public static void refreshRoleDescription(PlayerControl player)
        {
            if (player == null)
            {
                return;
            }

            List <RoleInfo> infos = RoleInfo.getRoleInfoForPlayer(player);

            var toRemove = new List <PlayerTask>();

            foreach (PlayerTask t in player.myTasks)
            {
                var textTask = t.gameObject.GetComponent <ImportantTextTask>();
                if (textTask != null)
                {
                    var info = infos.FirstOrDefault(x => textTask.Text.StartsWith(x.name));
                    if (info != null)
                    {
                        infos.Remove(info); // TextTask for this RoleInfo does not have to be added, as it already exists
                    }
                    else
                    {
                        toRemove.Add(t); // TextTask does not have a corresponding RoleInfo and will hence be deleted
                    }
                }
            }

            foreach (PlayerTask t in toRemove)
            {
                t.OnRemove();
                player.myTasks.Remove(t);
                UnityEngine.Object.Destroy(t.gameObject);
            }

            // Add TextTask for remaining RoleInfos
            foreach (RoleInfo roleInfo in infos)
            {
                var task = new GameObject("RoleTask").AddComponent <ImportantTextTask>();
                task.transform.SetParent(player.transform, false);

                if (roleInfo.roleType == RoleType.Jackal)
                {
                    if (Jackal.canCreateSidekick)
                    {
                        task.Text = cs(roleInfo.color, $"{roleInfo.name}: " + ModTranslation.getString("jackalWithSidekick"));
                    }
                    else
                    {
                        task.Text = cs(roleInfo.color, $"{roleInfo.name}: " + ModTranslation.getString("jackalShortDesc"));
                    }
                }
                else
                {
                    task.Text = cs(roleInfo.color, $"{roleInfo.name}: {roleInfo.shortDescription}");
                }

                player.myTasks.Insert(0, task);
            }

            if (player.hasModifier(ModifierType.Madmate) || player.hasModifier(ModifierType.CreatedMadmate))
            {
                var task = new GameObject("RoleTask").AddComponent <ImportantTextTask>();
                task.transform.SetParent(player.transform, false);
                task.Text = cs(Madmate.color, $"{Madmate.fullName}: " + ModTranslation.getString("madmateShortDesc"));
                player.myTasks.Insert(0, task);
            }
        }