コード例 #1
0
        public static LandblockInstance CreateLandblockInstance(WorldObject wo, bool isLinkChild = false)
        {
            var instance = new LandblockInstance();

            instance.Guid = wo.Guid.Full;

            instance.Landblock = (int)wo.Location.Landblock;

            instance.WeenieClassId = wo.WeenieClassId;

            instance.ObjCellId = wo.Location.Cell;

            instance.OriginX = wo.Location.PositionX;
            instance.OriginY = wo.Location.PositionY;
            instance.OriginZ = wo.Location.PositionZ;

            instance.AnglesW = wo.Location.RotationW;
            instance.AnglesX = wo.Location.RotationX;
            instance.AnglesY = wo.Location.RotationY;
            instance.AnglesZ = wo.Location.RotationZ;

            instance.IsLinkChild = isLinkChild;

            instance.LastModified = DateTime.Now;

            return(instance);
        }
コード例 #2
0
        public HouseListResults(Weenie weenie, LandblockInstance landblockInstance)
        {
            Weenie            = weenie;
            LandblockInstance = landblockInstance;

            HouseType = GetHouseType(Weenie.ClassName);
        }
コード例 #3
0
        /// <summary>
        /// Default is formed from: (input.ObjCellId >> 16).ToString("X4")
        /// </summary>
        public string GetDefaultFileName(LandblockInstance input)
        {
            string fileName = (input.ObjCellId >> 16).ToString("X4");

            fileName  = IllegalInFileName.Replace(fileName, "_");
            fileName += ".sql";

            return(fileName);
        }
コード例 #4
0
ファイル: GDLEConverter.cs プロジェクト: jacobtipp/trACE
        /// <summary>
        /// Converts GDLE spawn map -> ACE landblock instances
        ///
        /// This will not alter the Guid. To sanitize the Guid for ACE usage, you should use GDLELoader.TryLoadWorldSpawnsConverted() instead.
        /// </summary>
        public static bool TryConvert(Models.Landblock input, out List <LandblockInstance> results, out List <LandblockInstanceLink> links)
        {
            try
            {
                results = new List <LandblockInstance>();
                links   = new List <LandblockInstanceLink>();

                foreach (var value in input.value.weenies)
                {
                    var result = new LandblockInstance();

                    result.Guid = value.id; // Collisions and other errors can be caused by invalid input. Data should be sanitized by the running ACE server.
                    //result.Landblock = input.key; ACE uses a virtual column here of (result.ObjCellId >> 16)
                    result.WeenieClassId = value.wcid;

                    result.ObjCellId = value.pos.objcell_id;
                    result.OriginX   = value.pos.frame.origin.x;
                    result.OriginY   = value.pos.frame.origin.y;
                    result.OriginZ   = value.pos.frame.origin.z;
                    result.AnglesW   = value.pos.frame.angles.w;
                    result.AnglesX   = value.pos.frame.angles.x;
                    result.AnglesY   = value.pos.frame.angles.y;
                    result.AnglesZ   = value.pos.frame.angles.z;

                    results.Add(result);
                }

                if (input.value.links != null)
                {
                    foreach (var value in input.value.links)
                    {
                        var result = new LandblockInstanceLink();

                        result.ParentGuid = value.target;
                        result.ChildGuid  = value.source;

                        links.Add(result);
                    }
                }

                // reguid if needed
                var landblockId = (ushort)(input.key >> 16);
                ReGuidAndConvertLandblocks(results, links, landblockId);

                return(true);
            }
            catch
            {
                results = null;
                links   = null;
                return(false);
            }
        }
コード例 #5
0
ファイル: GDLEConverter.cs プロジェクト: tuita520/ACE
        /// <summary>
        /// This will not alter the Guid. To sanitize the Guid for ACE usage, you should use GDLELoader.TryLoadWorldSpawnsConverted() instead.
        /// </summary>
        public static bool TryConvert(Models.Landblock input, out List <Database.Models.World.LandblockInstance> results, out List <Database.Models.World.LandblockInstanceLink> links)
        {
            try
            {
                results = new List <LandblockInstance>();
                links   = new List <LandblockInstanceLink>();

                foreach (var value in input.Value.Weenies)
                {
                    var result = new LandblockInstance();

                    result.Guid = value.Id; // Collisions and other errors can be caused by invalid input. Data should be sanitized by the running ACE server.
                    //result.Landblock = input.key; ACE uses a virtual column here of (result.ObjCellId >> 16)
                    result.WeenieClassId = value.WCID;

                    result.ObjCellId = value.Position.ObjCellId;
                    result.OriginX   = (float)value.Position.Frame.Origin.X;
                    result.OriginY   = (float)value.Position.Frame.Origin.Y;
                    result.OriginZ   = (float)value.Position.Frame.Origin.Z;
                    result.AnglesW   = (float)value.Position.Frame.Angles.W;
                    result.AnglesX   = (float)value.Position.Frame.Angles.X;
                    result.AnglesY   = (float)value.Position.Frame.Angles.Y;
                    result.AnglesZ   = (float)value.Position.Frame.Angles.Z;

                    results.Add(result);
                }

                if (input.Value.Links != null)
                {
                    foreach (var value in input.Value.Links)
                    {
                        var result = new LandblockInstanceLink();

                        result.ParentGuid = value.Target;
                        result.ChildGuid  = value.Source;

                        links.Add(result);
                    }
                }

                return(true);
            }
            catch
            {
                results = null;
                links   = null;
                return(false);
            }
        }
コード例 #6
0
ファイル: LandblockSQLReader.cs プロジェクト: Mad-Hatz/ACData
 private void AddRecord(List <string> fields)
 {
     if (CurrentTable == Table.LandblockInstance)
     {
         var record = new LandblockInstance();
         PopulateFields(record, fields);
         LandblockInstances.Add(record);
     }
     else if (CurrentTable == Table.LandblockInstanceLink)
     {
         var record = new LandblockInstanceLink();
         PopulateFields(record, fields);
         LandblockInstanceLinks.Add(record);
     }
 }
コード例 #7
0
        public static void HandleCreateInst(Session session, params string[] parameters)
        {
            var loc = new Position(session.Player.Location);

            var param = parameters[0];

            Weenie weenie = null;

            uint?parentGuid = null;

            var landblock = session.Player.CurrentLandblock.Id.Landblock;

            var firstStaticGuid = 0x70000000 | (uint)landblock << 12;

            if (parameters.Length > 1)
            {
                var allParams = string.Join(" ", parameters);

                var match = Regex.Match(allParams, @"-p ([\S]+) -c ([\S]+)", RegexOptions.IgnoreCase);

                if (match.Success)
                {
                    var parentGuidStr = match.Groups[1].Value;
                    param = match.Groups[2].Value;

                    if (parentGuidStr.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
                    {
                        parentGuidStr = parentGuidStr.Substring(2);
                    }

                    if (!uint.TryParse(parentGuidStr, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var _parentGuid))
                    {
                        session.Network.EnqueueSend(new GameMessageSystemChat($"Couldn't parse parent guid {match.Groups[1].Value}", ChatMessageType.Broadcast));
                        return;
                    }

                    parentGuid = _parentGuid;

                    if (parentGuid <= 0xFFF)
                    {
                        parentGuid = firstStaticGuid | parentGuid;
                    }
                }

                else if (parameters[1].StartsWith("-c", StringComparison.OrdinalIgnoreCase))
                {
                    // get parent from last appraised object
                    var parent = CommandHandlerHelper.GetLastAppraisedObject(session);

                    if (parent == null)
                    {
                        session.Network.EnqueueSend(new GameMessageSystemChat($"Couldn't find parent object", ChatMessageType.Broadcast));
                        return;
                    }

                    parentGuid = parent.Guid.Full;
                }
            }

            if (uint.TryParse(param, out var wcid))
            {
                weenie = DatabaseManager.World.GetCachedWeenie(wcid);   // wcid
            }
            else
            {
                weenie = DatabaseManager.World.GetCachedWeenie(param);  // classname
            }
            if (weenie == null)
            {
                session.Network.EnqueueSend(new GameMessageSystemChat($"Couldn't find weenie {param}", ChatMessageType.Broadcast));
                return;
            }

            // clear any cached instances for this landblock
            DatabaseManager.World.ClearCachedInstancesByLandblock(landblock);

            var instances = DatabaseManager.World.GetCachedInstancesByLandblock(landblock);

            // for link mode, ensure parent guid instance exists
            WorldObject       parentObj      = null;
            LandblockInstance parentInstance = null;

            if (parentGuid != null)
            {
                parentInstance = instances.FirstOrDefault(i => i.Guid == parentGuid);

                if (parentInstance == null)
                {
                    session.Network.EnqueueSend(new GameMessageSystemChat($"Couldn't find landblock instance for parent guid 0x{parentGuid:X8}", ChatMessageType.Broadcast));
                    return;
                }

                parentObj = session.Player.CurrentLandblock.GetObject(parentGuid.Value);

                if (parentObj == null)
                {
                    session.Network.EnqueueSend(new GameMessageSystemChat($"Couldn't find parent object 0x{parentGuid:X8}", ChatMessageType.Broadcast));
                    return;
                }
            }

            var nextStaticGuid = GetNextStaticGuid(landblock, instances);

            var maxStaticGuid = firstStaticGuid | 0xFFF;

            // manually specify a start guid?
            if (parameters.Length == 2)
            {
                if (uint.TryParse(parameters[1].Replace("0x", ""), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var startGuid))
                {
                    if (startGuid <= 0xFFF)
                    {
                        startGuid = firstStaticGuid | startGuid;
                    }

                    if (startGuid < firstStaticGuid || startGuid > maxStaticGuid)
                    {
                        session.Network.EnqueueSend(new GameMessageSystemChat($"Landblock instance guid {startGuid:X8} must be between {firstStaticGuid:X8} and {maxStaticGuid:X8}", ChatMessageType.Broadcast));
                        return;
                    }

                    var existing = instances.FirstOrDefault(i => i.Guid == startGuid);

                    if (existing != null)
                    {
                        session.Network.EnqueueSend(new GameMessageSystemChat($"Landblock instance guid {startGuid:X8} already exists", ChatMessageType.Broadcast));
                        return;
                    }
                    nextStaticGuid = startGuid;
                }
            }


            if (nextStaticGuid >= maxStaticGuid)
            {
                session.Network.EnqueueSend(new GameMessageSystemChat($"Landblock {landblock:X4} has reached the maximum # of static guids", ChatMessageType.Broadcast));
                return;
            }

            // create and spawn object
            var wo = WorldObjectFactory.CreateWorldObject(weenie, new ObjectGuid(nextStaticGuid));

            if (wo == null)
            {
                session.Network.EnqueueSend(new GameMessageSystemChat($"Failed to create new object for {weenie.ClassId} - {weenie.ClassName}", ChatMessageType.Broadcast));
                return;
            }

            if (!wo.Stuck)
            {
                session.Network.EnqueueSend(new GameMessageSystemChat($"{weenie.ClassId} - {weenie.ClassName} is missing PropertyBool.Stuck, cannot spawn as landblock instance", ChatMessageType.Broadcast));
                return;
            }

            // spawn as ethereal temporarily, to spawn directly on player position
            wo.Ethereal = true;
            wo.Location = new Position(loc);

            // even on flat ground, objects can sometimes fail to spawn at the player's current Z
            // Position.Z has some weird thresholds when moving around, but i guess the same logic doesn't apply when trying to spawn in...
            wo.Location.PositionZ += 0.05f;

            var isLinkChild = parentInstance != null;

            session.Network.EnqueueSend(new GameMessageSystemChat($"Creating new landblock instance {(isLinkChild ? "child object " : "")}@ {loc.ToLOCString()}\n{wo.WeenieClassId} - {wo.Name} ({nextStaticGuid:X8})", ChatMessageType.Broadcast));

            if (!wo.EnterWorld())
            {
                session.Network.EnqueueSend(new GameMessageSystemChat("Failed to spawn new object at this location", ChatMessageType.Broadcast));
                return;
            }

            // create new landblock instance
            var instance = CreateLandblockInstance(wo, isLinkChild);

            instances.Add(instance);

            if (isLinkChild)
            {
                var link = new LandblockInstanceLink();

                link.ParentGuid   = parentGuid.Value;
                link.ChildGuid    = wo.Guid.Full;
                link.LastModified = DateTime.Now;

                parentInstance.LandblockInstanceLink.Add(link);

                parentObj.LinkedInstances.Add(instance);

                // ActivateLinks?
                parentObj.SetLinkProperties(wo);
                parentObj.ChildLinks.Add(wo);
                wo.ParentLink = parentObj;
            }

            SyncInstances(session, landblock, instances);
        }
コード例 #8
0
        public static List <LandblockInstance> ConvertToACE(this List <Seg6_LandBlockExtendedData.Landblock> input)
        {
            var results = new List <LandblockInstance>();

            foreach (var value in input)
            {
                if (value.Weenies != null)
                {
                    foreach (var weenie in value.Weenies)
                    {
                        var result = new LandblockInstance
                        {
                            Guid = weenie.ID,

                            WeenieClassId = weenie.WCID,

                            ObjCellId = weenie.Position.ObjCellID,

                            OriginX = weenie.Position.Origin.X,
                            OriginY = weenie.Position.Origin.Y,
                            OriginZ = weenie.Position.Origin.Z,

                            AnglesW = weenie.Position.Angles.W,
                            AnglesX = weenie.Position.Angles.X,
                            AnglesY = weenie.Position.Angles.Y,
                            AnglesZ = weenie.Position.Angles.Z,
                        };

                        // Somebody goofed and a guid was used in two places... I'm not sure that it ultimately was a problem on retail worlds but this fixes it for ACE
                        if (result.Guid == 1975799995)
                        {
                            if (result.WeenieClassId == 22775)
                            {
                                result.Guid = 1975799994; // Unused guid.
                            }
                        }

                        if (value.Links != null)
                        {
                            foreach (var link in value.Links)
                            {
                                if (result.Guid == link.Source)
                                {
                                    result.IsLinkChild = true;
                                }

                                if (result.Guid == link.Target)
                                {
                                    // This code prevents duplicates. There are a few duplicate entries in the cache.bin
                                    bool found = false;

                                    foreach (var record in result.LandblockInstanceLink)
                                    {
                                        if (record.ChildGuid == link.Source)
                                        {
                                            found = true;
                                            break;
                                        }
                                    }

                                    if (!found)
                                    {
                                        result.LandblockInstanceLink.Add(new LandblockInstanceLink
                                        {
                                            ParentGuid = result.Guid,
                                            ChildGuid  = link.Source
                                        });
                                    }
                                }
                            }
                        }

                        results.Add(result);
                    }
                }
            }

            return(results);
        }
コード例 #9
0
ファイル: Server.cs プロジェクト: OptimShi/ACViewer
        public static WorldObject ProcessInstance(uint lbid, LandblockInstance instance, Dictionary <uint, LandblockInstance> lookupTable)
        {
            var wo = WorldObjectFactory.CreateNewWorldObject(instance.WeenieClassId);

            if (wo == null)
            {
                return(null);
            }

            wo.InitPhysicsObj();

            var objCellId = instance.ObjCellId;

            if ((objCellId & 0xFFFF) == 0)
            {
                // get the outdoor landcell for this position
                var cellX = (uint)(instance.OriginX / 24);
                var cellY = (uint)(instance.OriginY / 24);

                var cellID = cellX * 8 + cellY + 1;

                objCellId |= cellID;
            }

            var location = new Position();

            location.ObjCellID         = objCellId;
            location.Frame.Origin      = new Vector3(instance.OriginX, instance.OriginY, instance.OriginZ);
            location.Frame.Orientation = new Quaternion(instance.AnglesX, instance.AnglesY, instance.AnglesZ, instance.AnglesW);

            var success = wo.AddPhysicsObj(location);

            if (!success)
            {
                Console.WriteLine($"LoadInstances({lbid:X8}).AddPhysicsObj({wo.Name}, {location}) - failed to spawn");
                return(null);
            }

            Console.WriteLine($"Spawned {instance.WeenieClassId} - {wo.Name} @ {location}");

            AddInstance(wo);

            foreach (var link in instance.LandblockInstanceLink)
            {
                if (!lookupTable.TryGetValue(link.ChildGuid, out var childInstance))
                {
                    Console.WriteLine($"Server.ProcessInstance({lbid:X8}, {instance.Guid:X8}, {link.ChildGuid:X8}) - couldn't find child guid!");
                    continue;
                }

                var child = ProcessInstance(lbid, childInstance, lookupTable);

                if (child == null)
                {
                    continue;
                }

                child.ParentLink = wo;
                wo.ChildLinks.Add(child);
            }

            return(wo);
        }