private static void PerformCustomPing(PingCatalog.PingType pingType, PingCatalog.PingData pingData)
        {
            if (!pingData.owner)
            {
                RadialPingsPlugin.logger.LogError("Received PerformCustomPing for nonexistent owner");
                return;
            }

            var pingHelper = pingData.owner.GetComponent <PingMenuHelper>();

            if (!pingHelper)
            {
                pingHelper       = pingData.owner.gameObject.AddComponent <PingMenuHelper>();
                pingHelper.owner = pingData.owner;
            }

            var           ownerText = Util.GetBestMasterName(pingData.owner.master);
            List <string> args      = new List <string> {
                ownerText
            };

            if (!pingType.tryApply(pingData, args))
            {
                RadialPingsPlugin.logger.LogWarning($"PerformCustomPing failed to apply CustomPingType {nameof(pingType)} (likely missing networkidentity on target object)");
                return;
            }
            var skin = pingType.pingSkins[pingType.modifyAndSelectSkin?.Invoke(ref pingData, pingType.catalogIndex, args) ?? 0];

            var chatText = string.Format(Language.GetString(skin.chatToken), args.ToArray());

            pingHelper.ManualBuildPing(pingData.targets.Count > 0 ? pingData.targets[0] : null, pingData.origin, pingData.normal,
                                       ownerText, chatText,
                                       skin.pingColor, skin.textColor, skin.spriteColor, skin.sprite, skin.duration, skin.basePingType,
                                       skin.doHighlight, skin.highlightColor, skin.highlightStrength);
        }
        public void AuthorityPerformCustomPing(GameObject[] extraTargets, params PingCatalog.PingType[] orderedPingTypesToTry)
        {
            if (!TryUpdatePingInfo())
            {
                return;
            }

            var ownerText = Util.GetBestMasterName(owner.master);

            List <string> args = new List <string> {
                ownerText
            };

            PingCatalog.PingType selectedType = null;

            var allTargets = new List <GameObject> {
                lastPingInfo.targetGameObject
            };

            if (extraTargets != null)
            {
                allTargets.AddRange(extraTargets);
            }

            var pingData = new PingCatalog.PingData {
                origin  = lastPingInfo.origin,
                normal  = lastPingInfo.normal,
                targets = allTargets,
                owner   = this.owner
            };

            foreach (var pingType in orderedPingTypesToTry)
            {
                if (pingType.catalogIndex == -1)
                {
                    continue;
                }
                if (pingType.tryApply(pingData, args))
                {
                    selectedType = pingType;
                    break;
                }
            }

            if (selectedType == null)
            {
                return;
            }

            if (owner.pingerController.hasAuthority && (pingData.origin != null || pingData.targets.Count > 0) && TryDeductPingStock())
            {
                new MsgCustomPing(selectedType, pingData).Send(R2API.Networking.NetworkDestination.Clients);
            }
        }
        public string GetFormattedContext(GameObject[] extraTargets, params PingCatalog.PingType[] pingTypes)
        {
            PingCatalog.PingType selectedType = null;

            var allTargets = new List <GameObject> {
                lastPingInfo.targetGameObject
            };

            if (extraTargets != null)
            {
                allTargets.AddRange(extraTargets);
            }

            List <string> args     = new List <string>();
            var           pingData = new PingCatalog.PingData {
                origin  = lastPingInfo.origin,
                normal  = lastPingInfo.normal,
                targets = allTargets,
                owner   = this.owner
            };

            foreach (var pingType in pingTypes)
            {
                if (pingType.tryApply(pingData, args))
                {
                    selectedType = pingType;
                    break;
                }
            }

            if (selectedType == null || selectedType.previewToken == null)
            {
                return(null);
            }

            return(string.Format(Language.GetString(selectedType.previewToken), args.ToArray()));
        }
 public MsgCustomPing(PingCatalog.PingType pingType, PingCatalog.PingData pingData)
 {
     _pingType = pingType;
     _pingData = pingData;
 }
 public void Deserialize(NetworkReader reader)
 {
     _pingType = PingCatalog.Get(reader.ReadInt32());
     _pingData = reader.Read <PingCatalog.PingData>();
 }