Пример #1
0
        /// <summary>
        ///     Create a <see cref="Portal" /> list from a <see cref="ZPackage" />
        /// </summary>
        /// <param name="zpkg"></param>
        /// <returns></returns>
        public static PortalList FromZPackage(ZPackage zpkg)
        {
            Logger.LogDebug("Deserializing portal list from ZPackage");

            var ret = new PortalList();

            var numConnectedPortals = zpkg.ReadInt();

            while (numConnectedPortals > 0)
            {
                var portalPosition = zpkg.ReadVector3();
                var portalName     = zpkg.ReadString();

                Logger.LogDebug($"{portalName}@{portalPosition}");
                ret.Add(new Portal(portalPosition, portalName, true));

                numConnectedPortals--;
            }

            var numUnconnectedPortals = zpkg.ReadInt();

            while (numUnconnectedPortals > 0)
            {
                var portalPosition = zpkg.ReadVector3();
                var portalName     = zpkg.ReadString();

                Logger.LogDebug($"{portalName}@{portalPosition}");
                ret.Add(new Portal(portalPosition, portalName, false));

                numUnconnectedPortals--;
            }

            return(ret);
        }
Пример #2
0
        /// <summary>
        ///     RPC to handle initial sync to a new peer
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="teleporterZPackage"></param>
        public static void RPC_TeleporterSyncInit(long sender, ZPackage teleporterZPackage)
        {
            // SERVER SIDE
            if (ZNet.instance.IsServerInstance() || ZNet.instance.IsLocalInstance())
            {
                Logger.LogInfo($"Sending portal data to peer #{sender}");

                var portals = PortalList.GetPortals();

                if (ZNet.instance.IsLocalInstance())
                {
                    UpdatePins(portals);
                }

                var package = portals.ToZPackage();
                ZRoutedRpc.instance.InvokeRoutedRPC(sender, nameof(RPC_TeleporterSyncInit), package);
            }

            // CLIENT SIDE
            if (ZNet.instance.IsClientInstance())
            {
                if (teleporterZPackage != null && teleporterZPackage.Size() > 0 && sender == ZRoutedRpc.instance.GetServerPeerID())
                {
                    // Read package and create pins from portal list
                    Logger.LogInfo("Received portal data from server");

                    portalsFromServer = PortalList.FromZPackage(teleporterZPackage);

                    UpdatePins(portalsFromServer);
                }
            }
        }
Пример #3
0
        /// <summary>
        ///     CLIENT SIDE: Initially pull portals after SetMapData on Minimap
        /// </summary>
        private static void UpdatePortalPins(On.Minimap.orig_SetMapData orig, Minimap self, byte[] data)
        {
            orig(self, data);

            if (ZNet.instance.IsServerInstance())
            {
                return;
            }

            if (!ConfigUtil.Get <bool>("Map", "showPortalsOnMap"))
            {
                return;
            }

            if (ZNet.instance.IsLocalInstance())
            {
                Logger.LogMessage("Initializing portals");
                UpdatePins(PortalList.GetPortals());
            }

            if (ZNet.instance.IsClientInstance())
            {
                Logger.LogMessage("Sending portal sync request to server");
                ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), nameof(RPC_Veilheim_TeleporterSyncInit), new ZPackage());
            }
        }
Пример #4
0
        /// <summary>
        ///     Get the current list of <see cref="Portal" /> ZDOs
        /// </summary>
        /// <returns></returns>
        public static PortalList GetPortals()
        {
            Logger.LogDebug("Creating portal list from ZDOMan");

            // Collect all portal locations/names
            var connected   = new List <ZDO>();
            var unconnected = new Dictionary <string, ZDO>();

            foreach (var zdoarray in ZDOMan.instance.m_objectsBySector)
            {
                if (zdoarray != null)
                {
                    foreach (var zdo in zdoarray.Where(x => x.m_prefab == -661882940))
                    {
                        var tag = zdo.GetString("tag");

                        if (!unconnected.ContainsKey(tag))
                        {
                            unconnected.Add(tag, zdo);
                        }
                        else
                        {
                            connected.Add(zdo);
                            connected.Add(unconnected[tag]);
                            unconnected.Remove(tag);
                        }
                    }
                }
            }

            // Make a list of all Portals
            var    ret = new PortalList();
            Portal portal;

            Logger.LogDebug("Connected Portals");
            foreach (var entry in connected.OrderBy(x => x.GetString("tag")))
            {
                portal = new Portal(entry.m_position, entry.GetString("tag"), true);
                Logger.LogDebug(portal);
                ret.Add(portal);
            }

            Logger.LogDebug("Unconnected Portals");
            foreach (var entry in unconnected.OrderBy(x => x.Value.GetString("tag")))
            {
                portal = new Portal(entry.Value.m_position, entry.Value.GetString("tag"), false);
                Logger.LogDebug(portal);
                ret.Add(portal);
            }

            return(ret);
        }
Пример #5
0
        public static void UpdatePortalPins(Minimap instance)
        {
            if (ZNet.instance.IsServerInstance())
            {
                return;
            }

            if (!Configuration.Current.Map.IsEnabled || !Configuration.Current.Map.showPortalsOnMap)
            {
                return;
            }

            if (ZNet.instance.IsLocalInstance())
            {
                Logger.LogInfo("Initializing portals");
                UpdatePins(PortalList.GetPortals());
            }

            if (ZNet.instance.IsClientInstance())
            {
                Logger.LogInfo("Sending portal sync request to server");
                ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), nameof(RPC_TeleporterSyncInit), new ZPackage());
            }
        }
Пример #6
0
        public static void OpenPortalSelection()
        {
            if (TextInput.instance.m_panel.activeSelf)
            {
                Logger.LogInfo("Generating portal selection");

                // set position of textinput (a bit higher)
                TextInput.instance.m_panel.transform.localPosition = new Vector3(0, 270.0f, 0);

                // Create gameobject(s) if not exist
                if (portalRect == null)
                {
                    portalRect = GenerateGUI();
                }

                IEnumerable <Portal> singlePortals;
                // Generate list of unconnected portals from ZDOMan
                if (ZNet.instance.IsLocalInstance())
                {
                    singlePortals = PortalList.GetPortals().Where(x => !x.m_con);
                }
                // or from PortalsOnMap.portalsFromServer, if it is a real client
                else
                {
                    singlePortals = PortalsOnMap.portalsFromServer.Where(x => !x.m_con);
                }

                // remove all buttons from earlier calls
                foreach (var oldbt in teleporterButtons)
                {
                    if (oldbt != null)
                    {
                        Object.Destroy(oldbt);
                    }
                }

                // empty the local list
                teleporterButtons.Clear();

                var idx = 0;

                // calculate number of lines
                var lines = singlePortals.Count() / 3;

                // Get name of portal
                var currentTag = TextInput.instance.m_textField.text;
                if (string.IsNullOrEmpty(currentTag))
                {
                    currentTag = "<unnamed>";
                    TextInput.instance.m_textField.text = currentTag;
                }

                if (TextInput.instance.m_panel.transform.Find("OK") != null)
                {
                    var originalButton = TextInput.instance.m_panel.transform.Find("OK").gameObject;

                    foreach (var portal in singlePortals)
                    {
                        // Skip if it is the selected teleporter
                        if (portal.m_tag == currentTag || currentTag == "<unnamed>" && string.IsNullOrEmpty(portal.m_tag))
                        {
                            continue;
                        }

                        // clone button
                        var newButton = Object.Instantiate(originalButton, buttonList.GetComponent <RectTransform>());
                        newButton.name = "TP" + idx;

                        // set position
                        newButton.transform.localPosition = new Vector3(-600.0f / 3f + idx % 3 * 600.0f / 3f, lines * 25f - idx / 3 * 50f, 0f);

                        // enable
                        newButton.SetActive(true);

                        // set button text
                        newButton.GetComponentInChildren <Text>().text = portal.m_tag;

                        // add event payload
                        newButton.GetComponentInChildren <Button>().onClick.AddListener(() =>
                        {
                            // Set input field text to new name
                            TextInput.instance.m_textField.text = portal.m_tag;

                            // simulate enter key
                            TextInput.instance.OnEnter(portal.m_tag);

                            // hide textinput
                            TextInput.instance.Hide();
                        });

                        // Add to local list
                        teleporterButtons.Add(newButton);
                        idx++;
                    }
                }

                if (singlePortals.Count() > 0)
                {
                    // show buttonlist only if single teleports are available to choose from
                    portalRect.gameObject.SetActive(true);
                }

                // Set anchor
                buttonList.GetComponent <RectTransform>().anchoredPosition = new Vector2(0, -(singlePortals.Count() / 3) * 25.0f);

                // Set size
                buttonList.GetComponent <RectTransform>().SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, singlePortals.Count() / 3 * 50.0f + 50f);

                // release mouselock
                GameCamera.instance.m_mouseCapture = false;
                GameCamera.instance.UpdateMouseCapture();
            }
        }
Пример #7
0
        private static void CreatePortalGUI(string currentTag)
        {
            if (GUIRoot == null)
            {
                GUIRoot = Object.Instantiate(GUIManager.Instance.GetPrefab("PortalButtonBox"));
                GUIRoot.transform.SetParent(GUIManager.PixelFix.transform, false);
                GUIRoot.GetComponentInChildren <Image>().sprite = GUIManager.Instance.GetSprite("woodpanel_trophys");
            }

            foreach (var button in teleporterButtons)
            {
                Object.Destroy(button);
            }

            teleporterButtons.Clear();

            IEnumerable <Portal> singlePortals;

            // Generate list of unconnected portals from ZDOMan
            if (ZNet.instance.IsLocalInstance())
            {
                singlePortals = PortalList.GetPortals().Where(x => !x.m_con);
            }

            // or from PortalsOnMap.portalsFromServer, if it is a real client
            else
            {
                singlePortals = PortalsOnMap.portalsFromServer.Where(x => !x.m_con);
            }

            var idx = 0;

            var lines = singlePortals.Count() / 3;

            foreach (var portal in singlePortals)
            {
                // Skip if it is the selected teleporter
                if (portal.m_tag == currentTag || currentTag == "<unnamed>" && string.IsNullOrEmpty(portal.m_tag))
                {
                    continue;
                }

                var newButton = GUIManager.Instance.CreateButton(portal.m_tag, GUIRoot.transform.Find("Image/Scroll View/Viewport/Content"), new Vector2(0, 1),
                                                                 new Vector2(0, 1), new Vector2(0, 0));

                newButton.GetComponent <Button>().onClick.AddListener(() =>
                {
                    // Set input field text to new name
                    TextInput.instance.m_textField.text = portal.m_tag;

                    // simulate enter key
                    TextInput.instance.OnEnter(portal.m_tag);

                    // hide textinput
                    TextInput.instance.Hide();

                    // Reset visibility state
                    GUIRoot.SetActive(false);
                });

                newButton.name = "TP" + teleporterButtons.Count;
                newButton.SetActive(true);

                newButton.GetComponent <RectTransform>().anchoredPosition = new Vector2(95f + idx % 3 * (180f + 20f), -(idx / 3) * 50f - 25f);
                teleporterButtons.Add(newButton);
                idx++;
            }

            GUIRoot.transform.Find("Image/Scroll View/Viewport/Content").GetComponent <RectTransform>()
            .SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, lines * 50f + 50f);
            GUIRoot.SetActive(teleporterButtons.Count > 0);
        }
Пример #8
0
        /// <summary>
        ///     Add and remove pins in internal list based on a list of portals
        /// </summary>
        /// <param name="portals"></param>
        public static void UpdatePins(PortalList portals)
        {
            Logger.LogDebug("Updating pins of portals on minimap");

            // prevent MT crashing
            lock (portalPins)
            {
                // Add connected portals (separated connected and unconnected, maybe show another icon?)
                foreach (var portal in portals.FindAll(x => x.m_con))
                {
                    Logger.LogDebug(portal);

                    // Was pin already added?
                    var foundPin = portalPins.FirstOrDefault(x => x.m_pos == portal.m_pos);
                    if (foundPin != null)
                    {
                        // Did the pin's name change?
                        if (foundPin.m_name != portal.m_tag)
                        {
                            // Remove pin at location and readd with new name
                            portalPins.Remove(foundPin);
                            portalPins.Add(CreatePinData(portal.m_pos, Minimap.PinType.Icon4, portal.m_tag, false, false));
                        }
                    }
                    else
                    {
                        // Add new pin
                        portalPins.Add(CreatePinData(portal.m_pos, Minimap.PinType.Icon4, portal.m_tag, false, false));
                    }
                }

                // Add unconnected portals (maybe show another icon / text?)
                foreach (var portal in portals.FindAll(x => !x.m_con))
                {
                    Logger.LogDebug(portal);

                    // Was pin already added?
                    var foundPin = portalPins.FirstOrDefault(x => x.m_pos == portal.m_pos);
                    if (foundPin != null)
                    {
                        // Did the pin's name change?
                        if (foundPin.m_name != portal.m_tag)
                        {
                            // Remove pin at location and readd with new name
                            portalPins.Remove(foundPin);
                            portalPins.Add(CreatePinData(portal.m_pos, Minimap.PinType.Icon4, portal.m_tag, false, false));
                        }
                    }
                    else
                    {
                        // Add new pin
                        portalPins.Add(CreatePinData(portal.m_pos, Minimap.PinType.Icon4, portal.m_tag, false, false));
                    }
                }

                // Remove destroyed portals from map
                // doesn't really react on portal destruction, only works if after a portal was destroyed, someone set the name on another portal
                foreach (var kv in portalPins.ToList())
                {
                    if (portals.All(x => x.m_pos != kv.m_pos))
                    {
                        portalPins.Remove(kv);
                    }
                }
            }

            Logger.LogInfo("Portal pins updated succesfully");
        }