예제 #1
0
    private static void AddMobSpawn(SpawnMetadata mobSpawnDataBox, MapEntityMetadata metadata, IMS2RegionBoxSpawn boxSpawn)
    {
        int mobNpcCountBox    = mobSpawnDataBox?.Population ?? 6;
        int mobSpawnRadiusBox = 150;
        // TODO: This previously relied in "NpcList" to be set. NpcList is impossible to be set on
        // MS2RegionSpawn, it's only set for SpawnPointNPC.
        List <int> mobNpcListBox = new()
        {
            21000025 // Placeholder
        };

        metadata.MobSpawns.Add(new(boxSpawn.SpawnPointID, CoordS.FromVector3(boxSpawn.Position),
                                   mobNpcCountBox, mobNpcListBox, mobSpawnRadiusBox, mobSpawnDataBox));
        // "QR_10000264_" is Quest Reward Chest? This is tied to a MS2TriggerAgent making this object appear.
    }
예제 #2
0
        public static List <MapEntityMetadata> Parse(MemoryMappedFile m2dFile, IEnumerable <PackFileEntry> entries)
        {
            List <MapEntityMetadata>    entities = new List <MapEntityMetadata>();
            Dictionary <string, string> maps     = new Dictionary <string, string>();

            foreach (PackFileEntry entry in entries)
            {
                if (!entry.Name.StartsWith("xblock/"))
                {
                    continue;
                }

                string mapIdStr = Regex.Match(entry.Name, @"\d{8}").Value;
                if (string.IsNullOrEmpty(mapIdStr))
                {
                    continue;
                }
                int mapId = int.Parse(mapIdStr);
                if (maps.ContainsKey(mapIdStr))
                {
                    Console.WriteLine($"Duplicate {entry.Name} was already added as {maps[mapIdStr]}");
                    continue;
                }
                maps.Add(mapIdStr, entry.Name);

                MapEntityMetadata metadata    = new MapEntityMetadata(mapId);
                XmlDocument       document    = m2dFile.GetDocument(entry.FileHeader);
                XmlNodeList       mapEntities = document.SelectNodes("/game/entitySet/entity");

                foreach (XmlNode node in mapEntities)
                {
                    if (node.Attributes["name"].Value.Contains("SpawnPointPC"))
                    {
                        XmlNode playerCoord    = node.SelectSingleNode("property[@name='Position']");
                        XmlNode playerRotation = node.SelectSingleNode("property[@name='Rotation']");

                        string playerPositionValue = playerCoord?.FirstChild.Attributes["value"].Value ?? "0, 0, 0";
                        string playerRotationValue = playerRotation?.FirstChild.Attributes["value"].Value ?? "0, 0, 0";

                        metadata.PlayerSpawns.Add(new MapPlayerSpawn(ParseCoord(playerPositionValue), ParseCoord(playerRotationValue)));
                    }
                }

                //XmlNodeList nodes = document.SelectNodes("/game/entitySet/entity/property[@name='NpcList']");
                XmlNodeList nodes = document.SelectNodes("/game/entitySet/entity/property");
                foreach (XmlNode node in nodes)
                {
                    if (node.Attributes["name"].Value == "NpcList")
                    {
                        if (node.FirstChild != null)
                        {
                            XmlNode parent = node.ParentNode;
                            try
                            {
                                XmlNode coordNode    = parent.SelectSingleNode("property[@name='Position']");
                                XmlNode rotationNode = parent.SelectSingleNode("property[@name='Rotation']");

                                int    npcId         = int.Parse(node.FirstChild.Attributes["index"].Value);
                                string positionValue = coordNode?.FirstChild.Attributes["value"].Value ?? "0, 0, 0";
                                string rotationValue = rotationNode?.FirstChild.Attributes["value"].Value ?? "0, 0, 0";

                                CoordS position = ParseCoord(positionValue);
                                CoordS rotation = ParseCoord(rotationValue);
                                metadata.Npcs.Add(new MapNpc(npcId, position, rotation));
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine(ex);
                                Console.WriteLine(mapId);
                                Console.WriteLine("Failed NPC " + parent.InnerXml);
                            }
                        }
                    }
                    else if (node.Attributes["name"].Value == "PortalID")
                    {
                        XmlNode parent = node.ParentNode;
                        try
                        {
                            XmlNode visibleNode        = parent.SelectSingleNode("property[@name='IsVisible']");
                            XmlNode enabledNode        = parent.SelectSingleNode("property[@name='PortalEnable']");
                            XmlNode minimapVisibleNode = parent.SelectSingleNode("property[@name='MinimapIconVisible']");
                            XmlNode targetNode         = parent.SelectSingleNode("property[@name='TargetFieldSN']");
                            XmlNode coordNode          = parent.SelectSingleNode("property[@name='Position']");
                            XmlNode rotationNode       = parent.SelectSingleNode("property[@name='Rotation']");
                            if (targetNode == null)
                            {
                                continue;
                            }

                            if (!bool.TryParse(visibleNode?.FirstChild.Attributes["value"].Value,
                                               out bool visibleValue))
                            {
                                visibleValue = true;
                            }
                            if (!bool.TryParse(enabledNode?.FirstChild.Attributes["value"].Value,
                                               out bool enabledValue))
                            {
                                enabledValue = true;
                            }
                            if (!bool.TryParse(minimapVisibleNode?.FirstChild.Attributes["value"].Value,
                                               out bool minimapVisibleValue))
                            {
                                minimapVisibleValue = true;
                            }

                            int    target        = int.Parse(targetNode.FirstChild.Attributes["value"].Value);
                            int    portalId      = int.Parse(node.FirstChild.Attributes["value"].Value);
                            string positionValue = coordNode?.FirstChild.Attributes["value"].Value ?? "0, 0, 0";
                            string rotationValue = rotationNode?.FirstChild.Attributes["value"].Value ?? "0, 0, 0";


                            MapPortalFlag flags = visibleValue ? MapPortalFlag.Visible : MapPortalFlag.None;
                            flags |= enabledValue ? MapPortalFlag.Enabled : MapPortalFlag.None;
                            flags |= minimapVisibleValue ? MapPortalFlag.MinimapVisible : MapPortalFlag.None;

                            CoordS position = ParseCoord(positionValue);
                            CoordS rotation = ParseCoord(rotationValue);
                            metadata.Portals.Add(new MapPortal(portalId, flags, target, position, rotation));
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex);
                            Console.WriteLine(mapId);
                            Console.WriteLine("Failed NPC " + parent.InnerXml);
                        }
                    }
                }

                // No data on this map
                if (metadata.Npcs.Count == 0 && metadata.Portals.Count == 0 && metadata.PlayerSpawns.Count == 0)
                {
                    continue;
                }

                entities.Add(metadata);
            }

            return(entities);
        }
예제 #3
0
        public static List <MapEntityMetadata> Parse(MemoryMappedFile m2dFile, IEnumerable <PackFileEntry> entries)
        {
            // Iterate over preset objects to later reference while iterating over exported maps
            Dictionary <string, string> mapObjects = new Dictionary <string, string>();

            foreach (PackFileEntry entry in entries)
            {
                if (!entry.Name.StartsWith("flat/presets/presets object/"))
                {
                    continue;
                }

                // Check if file is valid
                string objStr = entry.Name.ToLower();
                if (string.IsNullOrEmpty(objStr))
                {
                    continue;
                }
                if (mapObjects.ContainsKey(objStr))
                {
                    Console.WriteLine($"Duplicate {entry.Name} was already added as {mapObjects[objStr]}");
                    continue;
                }

                // Parse XML
                XmlDocument document      = m2dFile.GetDocument(entry.FileHeader);
                XmlElement  root          = document.DocumentElement;
                XmlNodeList objProperties = document.SelectNodes("/model/property");

                string objectName = root.Attributes["name"].Value.ToLower();

                foreach (XmlNode node in objProperties)
                {
                    // Storing only weapon item code for now, but there are other uses
                    if (node.Attributes["name"].Value.Contains("ObjectWeaponItemCode"))
                    {
                        string weaponId = node?.FirstChild.Attributes["value"].Value ?? "0";

                        if (!weaponId.Equals("0"))
                        {
                            mapObjects.Add(objectName, weaponId);
                        }
                    }
                }
            }

            // Iterate over map xblocks
            List <MapEntityMetadata>    entities = new List <MapEntityMetadata>();
            Dictionary <string, string> maps     = new Dictionary <string, string>();

            foreach (PackFileEntry entry in entries)
            {
                if (!entry.Name.StartsWith("xblock/"))
                {
                    continue;
                }

                string mapIdStr = Regex.Match(entry.Name, @"\d{8}").Value;
                if (string.IsNullOrEmpty(mapIdStr))
                {
                    continue;
                }
                int mapId = int.Parse(mapIdStr);
                if (maps.ContainsKey(mapIdStr))
                {
                    Console.WriteLine($"Duplicate {entry.Name} was already added as {maps[mapIdStr]}");
                    continue;
                }
                maps.Add(mapIdStr, entry.Name);

                MapEntityMetadata metadata    = new MapEntityMetadata(mapId);
                XmlDocument       document    = m2dFile.GetDocument(entry.FileHeader);
                XmlNodeList       mapEntities = document.SelectNodes("/game/entitySet/entity");

                foreach (XmlNode node in mapEntities)
                {
                    string modelName = node.Attributes["modelName"].Value.ToLower();

                    if (node.Attributes["name"].Value.Contains("SpawnPointPC"))
                    {
                        XmlNode playerCoord    = node.SelectSingleNode("property[@name='Position']");
                        XmlNode playerRotation = node.SelectSingleNode("property[@name='Rotation']");

                        string playerPositionValue = playerCoord?.FirstChild.Attributes["value"].Value ?? "0, 0, 0";
                        string playerRotationValue = playerRotation?.FirstChild.Attributes["value"].Value ?? "0, 0, 0";

                        metadata.PlayerSpawns.Add(new MapPlayerSpawn(ParseCoord(playerPositionValue), ParseCoord(playerRotationValue)));
                    }
                    else if (mapObjects.ContainsKey(modelName))
                    {
                        string nameCoord = node.Attributes["name"].Value.ToLower();

                        Match coordMatch = Regex.Match(nameCoord, @"[\-]?\d+[,]\s[\-]?\d+[,]\s[\-]?\d+");

                        if (!coordMatch.Success)
                        {
                            continue;
                        }

                        CoordB coord = CoordB.Parse(coordMatch.Value, ", ");
                        metadata.Objects.Add(new MapObject(coord, int.Parse(mapObjects[modelName])));
                    }
                }

                //XmlNodeList nodes = document.SelectNodes("/game/entitySet/entity/property[@name='NpcList']");
                XmlNodeList nodes = document.SelectNodes("/game/entitySet/entity/property");
                foreach (XmlNode node in nodes)
                {
                    if (node.Attributes["name"].Value == "NpcList")
                    {
                        if (node.FirstChild != null)
                        {
                            XmlNode parent = node.ParentNode;
                            try
                            {
                                XmlNode coordNode    = parent.SelectSingleNode("property[@name='Position']");
                                XmlNode rotationNode = parent.SelectSingleNode("property[@name='Rotation']");

                                int    npcId         = int.Parse(node.FirstChild.Attributes["index"].Value);
                                string positionValue = coordNode?.FirstChild.Attributes["value"].Value ?? "0, 0, 0";
                                string rotationValue = rotationNode?.FirstChild.Attributes["value"].Value ?? "0, 0, 0";

                                CoordS position = ParseCoord(positionValue);
                                CoordS rotation = ParseCoord(rotationValue);
                                metadata.Npcs.Add(new MapNpc(npcId, position, rotation));
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine(ex);
                                Console.WriteLine(mapId);
                                Console.WriteLine("Failed NPC " + parent.InnerXml);
                            }
                        }
                    }
                    else if (node.Attributes["name"].Value == "PortalID")
                    {
                        XmlNode parent = node.ParentNode;
                        try
                        {
                            XmlNode visibleNode        = parent.SelectSingleNode("property[@name='IsVisible']");
                            XmlNode enabledNode        = parent.SelectSingleNode("property[@name='PortalEnable']");
                            XmlNode minimapVisibleNode = parent.SelectSingleNode("property[@name='MinimapIconVisible']");
                            XmlNode targetNode         = parent.SelectSingleNode("property[@name='TargetFieldSN']");
                            XmlNode coordNode          = parent.SelectSingleNode("property[@name='Position']");
                            XmlNode rotationNode       = parent.SelectSingleNode("property[@name='Rotation']");
                            if (targetNode == null)
                            {
                                continue;
                            }

                            if (!bool.TryParse(visibleNode?.FirstChild.Attributes["value"].Value,
                                               out bool visibleValue))
                            {
                                visibleValue = true;
                            }
                            if (!bool.TryParse(enabledNode?.FirstChild.Attributes["value"].Value,
                                               out bool enabledValue))
                            {
                                enabledValue = true;
                            }
                            if (!bool.TryParse(minimapVisibleNode?.FirstChild.Attributes["value"].Value,
                                               out bool minimapVisibleValue))
                            {
                                minimapVisibleValue = true;
                            }

                            int    target        = int.Parse(targetNode.FirstChild.Attributes["value"].Value);
                            int    portalId      = int.Parse(node.FirstChild.Attributes["value"].Value);
                            string positionValue = coordNode?.FirstChild.Attributes["value"].Value ?? "0, 0, 0";
                            string rotationValue = rotationNode?.FirstChild.Attributes["value"].Value ?? "0, 0, 0";


                            MapPortalFlag flags = visibleValue ? MapPortalFlag.Visible : MapPortalFlag.None;
                            flags |= enabledValue ? MapPortalFlag.Enabled : MapPortalFlag.None;
                            flags |= minimapVisibleValue ? MapPortalFlag.MinimapVisible : MapPortalFlag.None;

                            CoordS position = ParseCoord(positionValue);
                            CoordS rotation = ParseCoord(rotationValue);
                            metadata.Portals.Add(new MapPortal(portalId, flags, target, position, rotation));
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex);
                            Console.WriteLine(mapId);
                            Console.WriteLine("Failed NPC " + parent.InnerXml);
                        }
                    }
                }

                // No data on this map
                if (metadata.Npcs.Count == 0 && metadata.Portals.Count == 0 && metadata.PlayerSpawns.Count == 0)
                {
                    continue;
                }

                entities.Add(metadata);
            }

            return(entities);
        }
예제 #4
0
    private void BuildMetadata(string xblock, IEnumerable <IMapEntity> mapEntities)
    {
        if (xblock.EndsWith("_cn") || xblock.EndsWith("_jp") || xblock.EndsWith("_kr"))
        {
            return;
        }

        MapMetadata mapMetadata = MapMetadatas.FirstOrDefault(x => x.XBlockName == xblock);

        if (mapMetadata is null)
        {
            return;
        }

        MapEntityMetadata mapEntity = mapMetadata.Entities;

        List <IMS2WayPoint>   tempWaypoints  = new();
        List <IMS2PatrolData> tempPatrolData = new();

        foreach (IMapEntity entity in mapEntities)
        {
            if (entity is IMS2CubeProp cube)
            {
                MapBlock mapBlock = new()
                {
                    Coord         = CoordS.FromVector3(cube.Position),
                    Type          = cube.CubeType,
                    SaleableGroup = cube.CubeSalableGroup,
                    Attribute     = cube.MapAttribute
                };

                mapMetadata.Blocks.TryAdd(mapBlock.Coord, mapBlock);
            }

            switch (entity)
            {
            case IMS2Bounding bounding:
                if (bounding.EntityName.EndsWith("0") && mapEntity.BoundingBox0.Equals(CoordS.From(0, 0, 0)))
                {
                    mapEntity.BoundingBox0 = CoordS.FromVector3(bounding.Position);
                }
                else if (bounding.EntityName.EndsWith("1") && mapEntity.BoundingBox1.Equals(CoordS.From(0, 0, 0)))
                {
                    mapEntity.BoundingBox1 = CoordS.FromVector3(bounding.Position);
                }

                break;

            case IMS2PatrolData patrolData:
                tempPatrolData.Add(patrolData);
                break;

            case IMS2WayPoint wayPoint:
                tempWaypoints.Add(wayPoint);
                break;

            // TODO: This can probably be more generally handled as IMS2RegionSkill
            case IMS2HealingRegionSkillSound healingRegion:
                if (healingRegion.Position == default)
                {
                    continue;
                }

                mapEntity.HealingSpot.Add(CoordS.FromVector3(healingRegion.Position));
                break;

            case IMS2InteractObject interact:
                InteractObjectType type = GetInteractObjectType(interact.interactID);
                if (type == InteractObjectType.None)
                {
                    continue;
                }

                switch (interact)
                {
                case IMS2SimpleUiObject uiObject:
                    mapEntity.InteractObjects.Add(new(uiObject.EntityId, uiObject.interactID, uiObject.Enabled, type,
                                                      CoordF.FromVector3(uiObject.Position),
                                                      CoordF.FromVector3(uiObject.Rotation)));
                    break;

                case IMS2InteractMesh interactMesh:
                    mapEntity.InteractObjects.Add(new(interactMesh.EntityId, interactMesh.interactID, interactMesh.IsVisible, type,
                                                      CoordF.FromVector3(interactMesh.Position),
                                                      CoordF.FromVector3(interactMesh.Rotation)));
                    break;

                case IMS2Telescope telescope:
                    mapEntity.InteractObjects.Add(new(telescope.EntityId, telescope.interactID, telescope.Enabled, type,
                                                      CoordF.FromVector3(telescope.Position),
                                                      CoordF.FromVector3(telescope.Rotation)));
                    break;

                case IMS2InteractActor interactActor:
                    mapEntity.InteractObjects.Add(new(interactActor.EntityId, interactActor.interactID, interactActor.IsVisible, type
                                                      , CoordF.FromVector3(interactActor.Position),
                                                      CoordF.FromVector3(interactActor.Rotation)));
                    break;

                case IMS2InteractDisplay interactDisplay:
                    mapEntity.InteractObjects.Add(new(interactDisplay.EntityId, interactDisplay.interactID, interactDisplay.IsVisible, type,
                                                      CoordF.FromVector3(interactDisplay.Position),
                                                      CoordF.FromVector3(interactDisplay.Rotation)));
                    break;
                }

                break;

            case ISpawnPoint spawn:
                switch (spawn)
                {
                // TODO: Parse "value" from NPCList.
                case IEventSpawnPointNPC eventSpawnNpc:         // trigger mob/npc spawns
                    List <string> npcIds = new();
                    npcIds.AddRange(eventSpawnNpc.NpcList.Keys);

                    mapEntity.EventNpcSpawnPoints.Add(new(eventSpawnNpc.SpawnPointID, eventSpawnNpc.NpcCount, npcIds, eventSpawnNpc.SpawnAnimation,
                                                          eventSpawnNpc.SpawnRadius,
                                                          CoordF.FromVector3(eventSpawnNpc.Position), CoordF.FromVector3(eventSpawnNpc.Rotation)));
                    break;

                case ISpawnPointPC pcSpawn:
                    mapEntity.PlayerSpawns.Add(new(CoordS.FromVector3(pcSpawn.Position), CoordS.FromVector3(pcSpawn.Rotation)));
                    break;

                case ISpawnPointNPC npcSpawn:
                    // These tend to be vendors, shops, etc.
                    // If the name tag begins with SpawnPointNPC, I think these are mob spawn locations. Skipping these.
                    string npcIdStr = npcSpawn.NpcList.FirstOrDefault().Key ?? "0";
                    if (npcIdStr == "0" || !int.TryParse(npcIdStr, out int npcId))
                    {
                        continue;
                    }

                    MapNpc npc = new(npcId, npcSpawn.ModelName, npcSpawn.EntityName, CoordS.FromVector3(npcSpawn.Position),
                                     CoordS.FromVector3(npcSpawn.Rotation), npcSpawn.IsSpawnOnFieldCreate, npcSpawn.dayDie, npcSpawn.nightDie, npcSpawn.PatrolData);
                    // Parse some additional flat supplemented data about this NPC.

                    mapEntity.Npcs.Add(npc);
                    break;
                }

                break;

            case IMS2RegionSpawnBase spawnBase:
                SpawnMetadata spawnData = SpawnTagMap.ContainsKey(mapMetadata.Id) && SpawnTagMap[mapMetadata.Id].ContainsKey(spawnBase.SpawnPointID)
                        ? SpawnTagMap[mapMetadata.Id][spawnBase.SpawnPointID]
                        : null;
                switch (spawnBase)
                {
                case IMS2RegionBoxSpawn boxSpawn:
                    if (boxSpawn.ModelName.Contains("chest", StringComparison.CurrentCultureIgnoreCase))
                    {
                        mapEntity.MapChests.Add(new()
                        {
                            IsGolden = boxSpawn.ModelName.Contains("rare", StringComparison.CurrentCultureIgnoreCase),
                            Position = CoordF.FromVector3(boxSpawn.Position),
                            Rotation = CoordF.FromVector3(boxSpawn.Rotation)
                        });
                        continue;
                    }

                    AddMobSpawn(spawnData, mapEntity, boxSpawn);
                    break;

                case IMS2RegionSpawn regionSpawn:
                    int mobNpcCount = spawnData?.Population ?? 6;

                    // TODO: This previously relied in "NpcList" to be set. NpcList is impossible to be set on
                    // MS2RegionSpawn, it's only set for SpawnPointNPC.
                    List <int> mobNpcList = new()
                    {
                        21000025         // Placeholder
                    };
                    mapEntity.MobSpawns.Add(new(regionSpawn.SpawnPointID, CoordS.FromVector3(regionSpawn.Position),
                                                mobNpcCount, mobNpcList, (int)regionSpawn.SpawnRadius, spawnData));
                    break;
                }

                break;

            case IPortal portal:
                mapEntity.Portals.Add(new(portal.PortalID, portal.ModelName, portal.PortalEnable, portal.IsVisible, portal.MinimapIconVisible,
                                          portal.TargetFieldSN,
                                          CoordS.FromVector3(portal.Position), CoordS.FromVector3(portal.Rotation), portal.TargetPortalID, (PortalTypes)portal.PortalType));
                break;

            case IMS2Breakable breakable:
                switch (breakable)
                {
                case IMS2BreakableActor actor:
                    mapEntity.BreakableActors.Add(new(actor.EntityId, actor.Enabled, actor.hideTimer, actor.resetTimer));
                    break;

                case IMS2BreakableNIF nif:
                    mapEntity.BreakableNifs.Add(new(nif.EntityId, nif.Enabled, (int)nif.TriggerBreakableID, nif.hideTimer, nif.resetTimer));
                    break;
                }

                break;

            case IMS2TriggerObject triggerObject:
                switch (triggerObject)
                {
                case IMS2TriggerMesh triggerMesh:
                    mapEntity.TriggerMeshes.Add(new(triggerMesh.TriggerObjectID, triggerMesh.IsVisible));
                    break;

                case IMS2TriggerEffect triggerEffect:
                    mapEntity.TriggerEffects.Add(new(triggerEffect.TriggerObjectID, triggerEffect.IsVisible));
                    break;

                case IMS2TriggerCamera triggerCamera:
                    mapEntity.TriggerCameras.Add(new(triggerCamera.TriggerObjectID, triggerCamera.Enabled));
                    break;

                case IMS2TriggerBox triggerBox:
                    mapEntity.TriggerBoxes.Add(new(triggerBox.TriggerObjectID, CoordF.FromVector3(triggerBox.Position),
                                                   CoordF.FromVector3(triggerBox.ShapeDimensions)));
                    break;

                case IMS2TriggerLadder triggerLadder:         // TODO: Find which parameters correspond to animationeffect (bool) and animation delay (int?)
                    mapEntity.TriggerLadders.Add(new(triggerLadder.TriggerObjectID, triggerLadder.IsVisible));
                    break;

                case IMS2TriggerRope triggerRope:         // TODO: Find which parameters correspond to animationeffect (bool) and animation delay (int?)
                    mapEntity.TriggerRopes.Add(new(triggerRope.TriggerObjectID, triggerRope.IsVisible));
                    break;

                case IMS2TriggerPortal triggerPortal:
                    mapEntity.Portals.Add(new(triggerPortal.PortalID, triggerPortal.ModelName, triggerPortal.PortalEnable, triggerPortal.IsVisible,
                                              triggerPortal.MinimapIconVisible,
                                              triggerPortal.TargetFieldSN, CoordS.FromVector3(triggerPortal.Position), CoordS.FromVector3(triggerPortal.Rotation),
                                              triggerPortal.TargetPortalID, (PortalTypes)triggerPortal.PortalType, triggerPortal.TriggerObjectID));
                    break;

                case IMS2TriggerActor triggerActor:
                    mapEntity.TriggerActors.Add(new(triggerActor.TriggerObjectID, triggerActor.IsVisible, triggerActor.InitialSequence));
                    break;

                case IMS2TriggerCube triggerCube:
                    mapEntity.TriggerCubes.Add(new(triggerCube.TriggerObjectID, triggerCube.IsVisible));
                    break;

                case IMS2TriggerSound triggerSound:
                    mapEntity.TriggerSounds.Add(new(triggerSound.TriggerObjectID, triggerSound.Enabled));
                    break;

                case IMS2TriggerSkill triggerSkill:
                    mapEntity.TriggerSkills.Add(new(triggerSkill.TriggerObjectID, triggerSkill.skillID,
                                                    (short)triggerSkill.skillLevel, (byte)triggerSkill.count, CoordF.FromVector3(triggerSkill.Position)));
                    break;
                }

                break;

            case IMS2LiftableTargetBox liftableTargetBox:
                mapEntity.LiftableTargets.Add(new(liftableTargetBox.liftableTarget, CoordF.FromVector3(liftableTargetBox.Position),
                                                  CoordF.FromVector3(liftableTargetBox.ShapeDimensions)));
                break;

            case IMS2PhysXProp physXProp:
                switch (physXProp)
                {
                case IMS2CubeProp prop:
                    if (!prop.IsObjectWeapon)
                    {
                        break;
                    }

                    List <int> weaponIds = prop.ObjectWeaponItemCode.SplitAndParseToInt(',').ToList();
                    mapEntity.WeaponObjects.Add(new(CoordB.FromVector3(prop.Position), weaponIds));
                    break;

                case IMS2Liftable liftable:
                    mapEntity.LiftableObjects.Add(new(liftable.EntityId, (int)liftable.ItemID, liftable.ItemStackCount, liftable.MaskQuestID,
                                                      liftable.MaskQuestState, liftable.EffectQuestID, liftable.EffectQuestState, liftable.ItemLifeTime,
                                                      liftable.LiftableRegenCheckTime, liftable.LiftableFinishTime, CoordF.FromVector3(liftable.Position),
                                                      CoordF.FromVector3(liftable.Rotation)));
                    break;

                case IMS2Vibrate vibrate:
                    mapEntity.VibrateObjects.Add(new(vibrate.EntityId, CoordF.FromVector3(physXProp.Position)));
                    break;
                }

                break;
            }
        }

        BuildWaypoints(tempPatrolData, tempWaypoints, mapEntity);
    }
예제 #5
0
    private static void BuildWaypoints(List <IMS2PatrolData> tempPatrolData, List <IMS2WayPoint> tempWaypoints, MapEntityMetadata mapEntity)
    {
        foreach (IMS2PatrolData patrolData in tempPatrolData)
        {
            List <string> wayPointIds = patrolData.WayPoints.Select(entry => entry.Value.Replace("-", string.Empty)).ToList();

            List <string> approachAnimations = patrolData.ApproachAnims.Select(entry => entry.Value).ToList();

            List <string> arriveAnimations = patrolData.ArriveAnims.Select(entry => entry.Value).ToList();

            List <int> arriveAnimationTimes = patrolData.ArriveAnimsTime.Select(entry => (int)entry.Value).ToList();

            List <WayPoint> wayPoints = new();
            for (int i = 0; i < wayPointIds.Count; i++)
            {
                string wayPointId          = wayPointIds.ElementAtOrDefault(i);
                string approachAnimation   = approachAnimations.ElementAtOrDefault(i);
                string arriveAnimation     = arriveAnimations.ElementAtOrDefault(i);
                int    arriveAnimationTime = arriveAnimationTimes.ElementAtOrDefault(i);

                IMS2WayPoint waypoint = tempWaypoints.FirstOrDefault(x => x.EntityId == wayPointId);
                if (waypoint is null)
                {
                    continue;
                }

                wayPoints.Add(new(wayPointId, waypoint.IsVisible,
                                  CoordS.FromVector3(waypoint.Position),
                                  CoordS.FromVector3(waypoint.Rotation),
                                  approachAnimation,
                                  arriveAnimation,
                                  arriveAnimationTime));
            }

            mapEntity.PatrolDatas.Add(new(patrolData.EntityId,
                                          patrolData.EntityName,
                                          patrolData.IsAirWayPoint,
                                          (int)patrolData.PatrolSpeed,
                                          patrolData.IsLoop,
                                          wayPoints));
        }
    }