예제 #1
0
        public void GetEntityInRangePointTest()
        {
            // Arrange
            var baseEnt    = EntityManager.SpawnEntity("dummyPoint");
            var inRangeEnt = EntityManager.SpawnEntity("dummyPoint");

            inRangeEnt.GetComponent <IServerTransformComponent>().WorldPosition = new Vector2(-2, -2);

            // Act
            var results = EntityManager.GetEntitiesInRange(baseEnt, 4.00f);

            // Cleanup
            var list = results.ToList();

            EntityManager.FlushEntities();

            // Assert
            Assert.That(list.Count, Is.EqualTo(2), list.Count.ToString);
        }
예제 #2
0
        private IEntity FindBestTarget()
        {
            // "best" target is the closest one with LOS

            var ents        = _entMan.GetEntitiesInRange(SelfEntity, VisionRadius);
            var myTransform = SelfEntity.GetComponent <IServerTransformComponent>();
            var maxRayLen   = VisionRadius * 2.5f; // circle inscribed in square, square diagonal = 2*r*sqrt(2)

            _workList.Clear();
            foreach (var entity in ents)
            {
                // filter to "people" entities (entities with controllers)
                if (!entity.HasComponent <IMoverComponent>())
                {
                    continue;
                }

                // build the ray
                var dir = entity.GetComponent <TransformComponent>().WorldPosition - myTransform.WorldPosition;
                var ray = new Ray(myTransform.WorldPosition, dir.Normalized);

                // cast the ray
                var result = _physMan.IntersectRay(ray, maxRayLen);

                // add to visible list
                if (result.HitEntity == entity)
                {
                    _workList.Add(entity);
                }
            }

            // get closest entity in list
            var closestEnt = GetClosest(myTransform.WorldPosition, _workList);

            // return closest
            return(closestEnt);
        }
        private bool Explosion()
        {
            var maxRange = MathHelper.Max(DevastationRange, HeavyImpactRange, LightImpactRange, 0f);
            //Entity damage calculation
            var entitiesAll = _serverEntityManager.GetEntitiesInRange(Owner.Transform.GridPosition, maxRange).ToList();

            foreach (var entity in entitiesAll)
            {
                Owner.Delete();
                if (entity == Owner)
                {
                    continue;
                }
                if (!entity.Transform.IsMapTransform)
                {
                    continue;
                }
                var distanceFromEntity = (int)entity.Transform.GridPosition.Distance(_mapManager, Owner.Transform.GridPosition);
                var exAct    = _entitySystemManager.GetEntitySystem <ActSystem>();
                var severity = ExplosionSeverity.Destruction;
                if (distanceFromEntity < DevastationRange)
                {
                    severity = ExplosionSeverity.Destruction;
                }
                else if (distanceFromEntity < HeavyImpactRange)
                {
                    severity = ExplosionSeverity.Heavy;
                }
                else if (distanceFromEntity < LightImpactRange)
                {
                    severity = ExplosionSeverity.Light;
                }
                else
                {
                    continue;
                }
                exAct.HandleExplosion(Owner, entity, severity);
            }

            //Tile damage calculation mockup
            //TODO: make it into some sort of actual damage component or whatever the boys think is appropriate
            var mapGrid = _mapManager.GetGrid(Owner.Transform.GridPosition.GridID);
            var circle  = new Circle(Owner.Transform.GridPosition.Position, maxRange);
            var tiles   = mapGrid.GetTilesIntersecting(circle);

            foreach (var tile in tiles)
            {
                var tileLoc          = mapGrid.GridTileToLocal(tile.GridIndices);
                var tileDef          = (ContentTileDefinition)_tileDefinitionManager[tile.Tile.TypeId];
                var distanceFromTile = (int)tileLoc.Distance(_mapManager, Owner.Transform.GridPosition);
                if (!string.IsNullOrWhiteSpace(tileDef.SubFloor))
                {
                    if (distanceFromTile < DevastationRange)
                    {
                        mapGrid.SetTile(tileLoc, new Tile(_tileDefinitionManager["space"].TileId));
                    }
                    if (distanceFromTile < HeavyImpactRange)
                    {
                        if (new Random().Prob(80))
                        {
                            mapGrid.SetTile(tileLoc, new Tile(_tileDefinitionManager[tileDef.SubFloor].TileId));
                        }
                        else
                        {
                            mapGrid.SetTile(tileLoc, new Tile(_tileDefinitionManager["space"].TileId));
                        }
                    }
                    if (distanceFromTile < LightImpactRange)
                    {
                        if (new Random().Prob(50))
                        {
                            mapGrid.SetTile(tileLoc, new Tile(_tileDefinitionManager[tileDef.SubFloor].TileId));
                        }
                    }
                }
            }

            //Effects and sounds
            var time    = IoCManager.Resolve <IGameTiming>().CurTime;
            var message = new EffectSystemMessage
            {
                EffectSprite = "Effects/explosion.rsi",
                RsiState     = "explosionfast",
                Born         = time,
                DeathTime    = time + TimeSpan.FromSeconds(5),
                Size         = new Vector2(FlashRange / 2, FlashRange / 2),
                Coordinates  = Owner.Transform.GridPosition,
                //Rotated from east facing
                Rotation   = 0f,
                ColorDelta = new Vector4(0, 0, 0, -1500f),
                Color      = Vector4.Multiply(new Vector4(255, 255, 255, 750), 0.5f),
                Shaded     = false
            };

            _entitySystemManager.GetEntitySystem <EffectSystem>().CreateParticle(message);
            _entitySystemManager.GetEntitySystem <AudioSystem>().Play("/Audio/effects/explosion.ogg", Owner);

            // Knock back cameras of all players in the area.

            var playerManager = IoCManager.Resolve <IPlayerManager>();
            var selfPos       = Owner.Transform.WorldPosition;

            foreach (var player in playerManager.GetAllPlayers())
            {
                if (player.AttachedEntity == null ||
                    player.AttachedEntity.Transform.MapID != mapGrid.ParentMapId ||
                    !player.AttachedEntity.TryGetComponent(out CameraRecoilComponent recoil))
                {
                    continue;
                }

                var playerPos = player.AttachedEntity.Transform.WorldPosition;
                var delta     = selfPos - playerPos;
                var distance  = delta.LengthSquared;

                var effect = 1 / (1 + 0.2f * distance);
                if (effect > 0.01f)
                {
                    var kick = -delta.Normalized * effect;
                    recoil.Kick(kick);
                }
            }

            return(true);
        }