示例#1
0
        public void GetByID_OneItem_ReturnsAreaWalkmesh()
        {
            // Arrange
            var          id     = Guid.NewGuid();
            AreaWalkmesh entity = new AreaWalkmesh {
                ID = id
            };

            // Act
            MessageHub.Instance.Publish(new OnCacheObjectSet <AreaWalkmesh>(entity));

            // Assert
            Assert.AreNotSame(entity, _cache.GetByID(id));
        }
示例#2
0
        // Area baking process
        // Run through and look for valid locations for later use by the spawn system.
        // Each tile is 10x10 meters. The "step" value in the config table determines how many meters we progress before checking for a valid location.
        private static void BakeArea(NWArea area)
        {
            _walkmeshesByArea[area] = new List <AreaWalkmesh>();

            const float MinDistance = 6.0f;
            var         dbArea      = DataService.Area.GetByResref(area.Resref);

            int arraySizeX = dbArea.Width * (10 / AreaBakeStep);
            int arraySizeY = dbArea.Height * (10 / AreaBakeStep);

            for (int x = 0; x < arraySizeX; x++)
            {
                for (int y = 0; y < arraySizeY; y++)
                {
                    Location checkLocation = _.Location(area.Object, _.Vector3(x * AreaBakeStep, y * AreaBakeStep), 0.0f);
                    int      material      = _.GetSurfaceMaterial(checkLocation);
                    bool     isWalkable    = Convert.ToInt32(_.Get2DAString("surfacemat", "Walk", material)) == 1;

                    // Location is not walkable if another object exists nearby.
                    NWObject nearest  = (_.GetNearestObjectToLocation(checkLocation, ObjectType.Creature | ObjectType.Door | ObjectType.Placeable | ObjectType.Trigger));
                    float    distance = _.GetDistanceBetweenLocations(checkLocation, nearest.Location);
                    if (nearest.IsValid && distance <= MinDistance)
                    {
                        isWalkable = false;
                    }

                    if (isWalkable)
                    {
                        AreaWalkmesh mesh = new AreaWalkmesh()
                        {
                            AreaID    = dbArea.ID,
                            LocationX = x * AreaBakeStep,
                            LocationY = y * AreaBakeStep,
                            LocationZ = _.GetGroundHeight(checkLocation)
                        };

                        _walkmeshesByArea[area].Add(mesh);
                    }
                }
            }

            Console.WriteLine("Area walkmesh up to date: " + area.Name);
        }
示例#3
0
        public void GetByID_TwoItems_ReturnsCorrectObject()
        {
            // Arrange
            var          id1     = Guid.NewGuid();
            var          id2     = Guid.NewGuid();
            AreaWalkmesh entity1 = new AreaWalkmesh {
                ID = id1
            };
            AreaWalkmesh entity2 = new AreaWalkmesh {
                ID = id2
            };

            // Act
            MessageHub.Instance.Publish(new OnCacheObjectSet <AreaWalkmesh>(entity1));
            MessageHub.Instance.Publish(new OnCacheObjectSet <AreaWalkmesh>(entity2));

            // Assert
            Assert.AreNotSame(entity1, _cache.GetByID(id1));
            Assert.AreNotSame(entity2, _cache.GetByID(id2));
        }
示例#4
0
        public void GetByID_RemovedItem_ReturnsCorrectObject()
        {
            // Arrange
            var          id1     = Guid.NewGuid();
            var          id2     = Guid.NewGuid();
            AreaWalkmesh entity1 = new AreaWalkmesh {
                ID = id1
            };
            AreaWalkmesh entity2 = new AreaWalkmesh {
                ID = id2
            };

            // Act
            MessageHub.Instance.Publish(new OnCacheObjectSet <AreaWalkmesh>(entity1));
            MessageHub.Instance.Publish(new OnCacheObjectSet <AreaWalkmesh>(entity2));
            MessageHub.Instance.Publish(new OnCacheObjectDeleted <AreaWalkmesh>(entity1));

            // Assert
            Assert.Throws <KeyNotFoundException>(() => { _cache.GetByID(id1); });
            Assert.AreNotSame(entity2, _cache.GetByID(id2));
        }
示例#5
0
        // Area baking process
        // Check if walkmesh matches what's in the database.
        // If it doesn't, run through and look for valid locations for later use by the spawn system.
        // Each tile is 10x10 meters. The "step" value in the config table determines how many meters we progress before checking for a valid location.
        // If you adjust this to get finer precision your database may explode with a ton of records. I chose a value that got me the
        // accuracy I wanted, without too much overhead. Your mileage may vary.
        private void BakeAreas()
        {
            var         config      = _data.GetAll <ServerConfiguration>().First();
            int         Step        = config.AreaBakeStep;
            const float MinDistance = 6.0f;

            foreach (var area in NWModule.Get().Areas)
            {
                var dbArea = _data.Single <Area>(x => x.Resref == area.Resref);

                int arraySizeX = dbArea.Width * (10 / Step);
                int arraySizeY = dbArea.Height * (10 / Step);
                Tuple <bool, float>[,] locations = new Tuple <bool, float> [arraySizeX, arraySizeY];
                string walkmesh = string.Empty;

                for (int x = 0; x < arraySizeX; x++)
                {
                    for (int y = 0; y < arraySizeY; y++)
                    {
                        Location checkLocation = _.Location(area.Object, _.Vector(x * Step, y * Step), 0.0f);
                        int      material      = _.GetSurfaceMaterial(checkLocation);
                        bool     isWalkable    = Convert.ToInt32(_.Get2DAString("surfacemat", "Walk", material)) == 1;

                        // Location is not walkable if another object exists nearby.
                        NWObject nearest  = (_.GetNearestObjectToLocation(OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE | OBJECT_TYPE_TRIGGER, checkLocation));
                        float    distance = _.GetDistanceBetweenLocations(checkLocation, nearest.Location);
                        if (nearest.IsValid && distance <= MinDistance)
                        {
                            isWalkable = false;
                        }


                        locations[x, y] = new Tuple <bool, float>(isWalkable, _.GetGroundHeight(checkLocation));

                        walkmesh += isWalkable ? "1" : "0";
                    }
                }

                if (dbArea.Walkmesh != walkmesh)
                {
                    dbArea.Walkmesh      = walkmesh;
                    dbArea.DateLastBaked = DateTime.UtcNow;
                    _data.SubmitDataChange(dbArea, DatabaseActionType.Update);

                    Console.WriteLine("Baking area because its walkmesh has changed since last run: " + area.Name);

                    var walkmeshes = _data.Where <AreaWalkmesh>(x => x.AreaID == dbArea.ID).ToList();
                    for (int x = walkmeshes.Count - 1; x >= 0; x--)
                    {
                        var mesh = walkmeshes.ElementAt(x);
                        _data.SubmitDataChange(mesh, DatabaseActionType.Delete);
                    }

                    Console.WriteLine("Cleared old walkmesh. Adding new one now.");

                    int records = 0;
                    for (int x = 0; x < arraySizeX; x++)
                    {
                        for (int y = 0; y < arraySizeY; y++)
                        {
                            // Ignore any points in the area that aren't walkable.
                            bool isWalkable = locations[x, y].Item1;
                            if (!isWalkable)
                            {
                                continue;
                            }

                            float z = locations[x, y].Item2;

                            AreaWalkmesh mesh = new AreaWalkmesh()
                            {
                                AreaID    = dbArea.ID,
                                LocationX = x * Step,
                                LocationY = y * Step,
                                LocationZ = z
                            };

                            _data.SubmitDataChange(mesh, DatabaseActionType.Insert);

                            records++;
                        }
                    }

                    Console.WriteLine("Saved " + records + " records.");
                }
                Console.WriteLine("Area walkmesh up to date: " + area.Name);
            }
        }