/// <inheritdoc />
        public override IEntity CreateEntityUninitialized(string?prototypeName, EntityCoordinates coordinates)
        {
            var newEntity = CreateEntity(prototypeName, GenerateEntityUid());
            var gridId    = coordinates.GetGridId(this);

            if (coordinates.GetGridId(this) != GridId.Invalid)
            {
                var gridEntityId = _mapManager.GetGrid(gridId).GridEntityId;
                newEntity.Transform.AttachParent(GetEntity(gridEntityId));
                newEntity.Transform.LocalPosition = coordinates.Position;
            }

            return(newEntity);
        }
Exemplo n.º 2
0
        public bool IsWeightless(EntityCoordinates coordinates)
        {
            var gridId = coordinates.GetGridId(_entityManager);
            var tile   = _mapManager.GetGrid(gridId).GetTileRef(coordinates).Tile;

            return(!_mapManager.GetGrid(gridId).HasGravity || tile.IsEmpty);
        }
Exemplo n.º 3
0
        public IEntity TakeBullet(EntityCoordinates spawnAtGrid, MapCoordinates spawnAtMap)
        {
            if (_ammoIsProjectile)
            {
                return(Owner);
            }

            if (_spent)
            {
                return(null);
            }

            _spent = true;
            if (Owner.TryGetComponent(out AppearanceComponent appearanceComponent))
            {
                appearanceComponent.SetData(AmmoVisuals.Spent, true);
            }

            var entity = spawnAtGrid.GetGridId(_entityManager) != GridId.Invalid
                ? Owner.EntityManager.SpawnEntity(_projectileId, spawnAtGrid)
                : Owner.EntityManager.SpawnEntity(_projectileId, spawnAtMap);

            DebugTools.AssertNotNull(entity);
            return(entity);
        }
Exemplo n.º 4
0
        private bool HandleWideAttack(ICommonSession session, EntityCoordinates coords, EntityUid uid)
        {
            // client sanitization
            if (!_mapManager.GridExists(coords.GetGridId(_entityManager)))
            {
                Logger.InfoS("system.interaction", $"Invalid Coordinates: client={session}, coords={coords}");
                return(true);
            }

            if (uid.IsClientSide())
            {
                Logger.WarningS("system.interaction",
                                $"Client sent attack with client-side entity. Session={session}, Uid={uid}");
                return(true);
            }

            var userEntity = ((IPlayerSession)session).AttachedEntity;

            if (userEntity == null || !userEntity.IsValid())
            {
                return(true);
            }

            if (userEntity.TryGetComponent(out CombatModeComponent combatMode) && combatMode.IsInCombatMode)
            {
                DoAttack(userEntity, coords, true);
            }

            return(true);
        }
        public async void TryPryTile(EntityUid user, EntityCoordinates clickLocation)
        {
            if (!_entMan.TryGetComponent <ToolComponent?>(Owner, out var tool) && _toolComponentNeeded)
            {
                return;
            }

            if (!_mapManager.TryGetGrid(clickLocation.GetGridId(_entMan), out var mapGrid))
            {
                return;
            }

            var tile = mapGrid.GetTileRef(clickLocation);

            var coordinates = mapGrid.GridTileToLocal(tile.GridIndices);

            if (!user.InRangeUnobstructed(coordinates, popup: false))
            {
                return;
            }

            var tileDef = (ContentTileDefinition)_tileDefinitionManager[tile.Tile.TypeId];

            if (!tileDef.CanCrowbar)
            {
                return;
            }

            if (_toolComponentNeeded && !await EntitySystem.Get <ToolSystem>().UseTool(Owner, user, null, 0f, 0f, _qualityNeeded, toolComponent: tool))
            {
                return;
            }

            coordinates.PryTile(_entMan, _mapManager);
        }
Exemplo n.º 6
0
        public async void TryPryTile(IEntity user, EntityCoordinates clickLocation)
        {
            if (!Owner.TryGetComponent <ToolComponent>(out var tool) && _toolComponentNeeded)
            {
                return;
            }

            if (!_mapManager.TryGetGrid(clickLocation.GetGridId(Owner.EntityManager), out var mapGrid))
            {
                return;
            }

            var tile = mapGrid.GetTileRef(clickLocation);

            var coordinates = mapGrid.GridTileToLocal(tile.GridIndices);

            if (!user.InRangeUnobstructed(coordinates, popup: false))
            {
                return;
            }

            var tileDef = (ContentTileDefinition)_tileDefinitionManager[tile.Tile.TypeId];

            if (!tileDef.CanCrowbar)
            {
                return;
            }

            if (_toolComponentNeeded && !await tool !.UseTool(user, null, 0f, ToolQuality.Prying))
            {
                return;
            }

            coordinates.PryTile(Owner.EntityManager, _mapManager);
        }
Exemplo n.º 7
0
        public static PuddleComponent?SpillAt(this Solution solution, EntityCoordinates coordinates, string prototype, bool sound = true)
        {
            if (solution.TotalVolume == 0)
            {
                return(null);
            }

            var mapManager          = IoCManager.Resolve <IMapManager>();
            var entityManager       = IoCManager.Resolve <IEntityManager>();
            var serverEntityManager = IoCManager.Resolve <IServerEntityManager>();

            var gridId  = coordinates.GetGridId(entityManager);
            var mapGrid = mapManager.GetGrid(gridId);

            // If space return early, let that spill go out into the void
            var tileRef = mapGrid.GetTileRef(coordinates);

            if (tileRef.Tile.IsEmpty)
            {
                return(null);
            }

            // Get normalized co-ordinate for spill location and spill it in the centre
            // TODO: Does SnapGrid or something else already do this?
            var spillTileMapGrid = mapManager.GetGrid(gridId);
            var spillTileRef     = spillTileMapGrid.GetTileRef(coordinates).GridIndices;
            var spillGridCoords  = spillTileMapGrid.GridTileToLocal(spillTileRef);

            var spilt = false;

            foreach (var spillEntity in entityManager.GetEntitiesAt(spillTileMapGrid.ParentMapId, spillGridCoords.Position))
            {
                if (!spillEntity.TryGetComponent(out PuddleComponent? puddleComponent))
                {
                    continue;
                }

                if (!puddleComponent.TryAddSolution(solution, sound))
                {
                    continue;
                }

                spilt = true;
                break;
            }

            // Did we add to an existing puddle
            if (spilt)
            {
                return(null);
            }

            var puddle             = serverEntityManager.SpawnEntity(prototype, spillGridCoords);
            var newPuddleComponent = puddle.GetComponent <PuddleComponent>();

            newPuddleComponent.TryAddSolution(solution, sound);

            return(newPuddleComponent);
        }
Exemplo n.º 8
0
        /// <inheritdoc />
        public IEnumerable <IEntity> GetEntitiesInRange(EntityCoordinates position, float range, bool approximate = false)
        {
            var mapPosition = position.ToMapPos(this);
            var aabb        = new Box2(mapPosition - new Vector2(range / 2, range / 2),
                                       mapPosition + new Vector2(range / 2, range / 2));

            return(GetEntitiesIntersecting(_mapManager.GetGrid(position.GetGridId(this)).ParentMapId, aabb, approximate));
        }
        // TODO: Need to rethink the pathfinder utils (traversable etc.). Maybe just chuck them all in PathfindingSystem
        // Otherwise you get the steerer using this and the pathfinders using a different traversable.
        // Also look at increasing tile cost the more physics entities are on it
        public bool CanTraverse(IEntity entity, EntityCoordinates coordinates)
        {
            var gridId = coordinates.GetGridId(_entityManager);
            var tile   = _mapManager.GetGrid(gridId).GetTileRef(coordinates);
            var node   = GetNode(tile);

            return(CanTraverse(entity, node));
        }
Exemplo n.º 10
0
        public static TileAtmosphere GetTileAtmosphere(this EntityCoordinates coordinates, IEntityManager?entityManager = null)
        {
            entityManager ??= IoCManager.Resolve <IEntityManager>();

            var gridAtmos = EntitySystem.Get <AtmosphereSystem>().GetGridAtmosphere(coordinates.GetGridId(entityManager));

            return(gridAtmos.GetTile(coordinates));
        }
Exemplo n.º 11
0
        public static bool PryTile(this EntityCoordinates coordinates, IEntityManager?entityManager = null,
                                   IMapManager?mapManager = null)
        {
            entityManager ??= IoCManager.Resolve <IEntityManager>();
            mapManager ??= IoCManager.Resolve <IMapManager>();

            return(coordinates.ToMapIndices(entityManager, mapManager).PryTile(coordinates.GetGridId(entityManager)));
        }
Exemplo n.º 12
0
        /// <summary>
        ///     Returns the tile ref for a grid, or a map.
        /// </summary>
        public TileRef GetTileRef(EntityCoordinates coordinates)
        {
            var mapCoords = coordinates.ToMap(pManager.EntityManager);
            var gridId    = coordinates.GetGridId(pManager.EntityManager);

            return(gridId.IsValid() ? pManager.MapManager.GetGrid(gridId).GetTileRef(MouseCoords)
                : new TileRef(mapCoords.MapId, gridId,
                              MouseCoords.ToVector2i(pManager.EntityManager, pManager.MapManager), Tile.Empty));
        }
    private bool TryPryTile(EntityUid user, TilePryingComponent component, EntityCoordinates clickLocation)
    {
        if (component.CancelToken != null)
        {
            component.CancelToken.Cancel();
            component.CancelToken = null;
            return(false);
        }

        if (!TryComp <ToolComponent?>(component.Owner, out var tool) && component.ToolComponentNeeded)
        {
            return(false);
        }

        if (!_mapManager.TryGetGrid(clickLocation.GetGridId(EntityManager), out var mapGrid))
        {
            return(false);
        }

        var tile = mapGrid.GetTileRef(clickLocation);

        var coordinates = mapGrid.GridTileToLocal(tile.GridIndices);

        if (!_interactionSystem.InRangeUnobstructed(user, coordinates, popup: false))
        {
            return(false);
        }

        var tileDef = (ContentTileDefinition)_tileDefinitionManager[tile.Tile.TypeId];

        if (!tileDef.CanCrowbar)
        {
            return(false);
        }

        var token = new CancellationTokenSource();

        component.CancelToken = token;

        UseTool(
            component.Owner,
            user,
            null,
            0f,
            component.Delay,
            new [] { component.QualityNeeded },
            new TilePryingCompleteEvent
        {
            Coordinates = clickLocation,
        },
            toolComponent: tool,
            doAfterEventTarget: component.Owner,
            cancelToken: token.Token);

        return(true);
    }
Exemplo n.º 14
0
    private void ReleaseToFloor(EntityCoordinates clickLocation, AbsorbentComponent absorbent, Solution?absorbedSolution)
    {
        if ((_mapManager.TryGetGrid(clickLocation.GetGridId(EntityManager), out var mapGrid)) && // needs valid grid
            absorbedSolution is not null)    // needs a solution to place on the tile
        {
            TileRef tile = mapGrid.GetTileRef(clickLocation);

            // Drop some of the absorbed liquid onto the ground
            var releaseAmount    = FixedPoint2.Min(absorbent.ResidueAmount, absorbedSolution.CurrentVolume);        // The release amount specified on the absorbent component, or the amount currently absorbed (whichever is less).
            var releasedSolution = _solutionSystem.SplitSolution(absorbent.Owner, absorbedSolution, releaseAmount); // Remove releaseAmount of solution from the absorbent component
            _spillableSystem.SpillAt(tile, releasedSolution, puddlePrototypeId);                                    // And spill it onto the tile.
        }
    }
Exemplo n.º 15
0
        public bool IsWeightless(EntityCoordinates coordinates)
        {
            var gridId = coordinates.GetGridId(_entityManager);

            if (!gridId.IsValid())
            {
                // Not on a grid = no gravity for now.
                // In the future, may want to allow maps to override to always have gravity instead.
                return(true);
            }

            var tile = _mapManager.GetGrid(gridId).GetTileRef(coordinates).Tile;

            return(!_mapManager.GetGrid(gridId).HasGravity || tile.IsEmpty);
        }
Exemplo n.º 16
0
    /// <summary>
    ///     Spills solution at the specified grid coordinates.
    /// </summary>
    /// <param name="solution">Initial solution for the prototype.</param>
    /// <param name="coordinates">The coordinates to spill the solution at.</param>
    /// <param name="prototype">The prototype to use.</param>
    /// <param name="overflow">If the puddle overflow will be calculated. Defaults to true.</param>
    /// <param name="sound">Whether or not to play the spill sound.</param>
    /// <param name="combine">Whether to attempt to merge with existing puddles</param>
    /// <returns>The puddle if one was created, null otherwise.</returns>
    public PuddleComponent?SpillAt(Solution solution, EntityCoordinates coordinates, string prototype,
                                   bool overflow = true, bool sound = true, bool combine = true)
    {
        if (solution.TotalVolume == 0)
        {
            return(null);
        }


        if (!_mapManager.TryGetGrid(coordinates.GetGridId(EntityManager), out var mapGrid))
        {
            return(null); // Let's not spill to space.
        }
        return(SpillAt(mapGrid.GetTileRef(coordinates), solution, prototype, overflow, sound,
                       combine: combine));
    }
Exemplo n.º 17
0
        /// <summary>
        ///     Spills solution at the specified grid coordinates.
        /// </summary>
        /// <param name="solution">Initial solution for the prototype.</param>
        /// <param name="coordinates">The coordinates to spill the solution at.</param>
        /// <param name="prototype">The prototype to use.</param>
        /// <param name="sound">Whether or not to play the spill sound.</param>
        /// <returns>The puddle if one was created, null otherwise.</returns>
        public static PuddleComponent?SpillAt(this Solution solution, EntityCoordinates coordinates, string prototype, bool overflow = true, bool sound = true)
        {
            if (solution.TotalVolume == 0)
            {
                return(null);
            }

            var mapManager    = IoCManager.Resolve <IMapManager>();
            var entityManager = IoCManager.Resolve <IEntityManager>();

            if (!mapManager.TryGetGrid(coordinates.GetGridId(entityManager), out var mapGrid))
            {
                return(null);                                                                               // Let's not spill to space.
            }
            return(SpillAt(mapGrid.GetTileRef(coordinates), solution, prototype, overflow, sound));
        }
Exemplo n.º 18
0
        public static IEnumerable <IEntity> GetEntitiesInRange(EntityCoordinates grid, Type component, float range)
        {
            var entityManager = IoCManager.Resolve <IEntityManager>();

            foreach (var entity in entityManager.GetEntities(new TypeEntityQuery(component)))
            {
                if (entity.Transform.Coordinates.GetGridId(entityManager) != grid.GetGridId(entityManager))
                {
                    continue;
                }

                if ((entity.Transform.Coordinates.Position - grid.Position).Length <= range)
                {
                    yield return(entity);
                }
            }
        }
Exemplo n.º 19
0
        public static IEnumerable <EntityUid> GetEntitiesInRange(EntityCoordinates grid, Type component, float range)
        {
            var entityManager = IoCManager.Resolve <IEntityManager>();

            foreach (var entity in entityManager.GetAllComponents(component).Select(c => c.Owner))
            {
                var transform = entityManager.GetComponent <TransformComponent>(entity);

                if (transform.Coordinates.GetGridId(entityManager) != grid.GetGridId(entityManager))
                {
                    continue;
                }

                if ((transform.Coordinates.Position - grid.Position).Length <= range)
                {
                    yield return(entity);
                }
            }
        }
        public static EntityCoordinates SnapToGrid(this EntityCoordinates coordinates, IEntityManager?entMan = null, IMapManager?mapManager = null)
        {
            IoCManager.Resolve(ref entMan, ref mapManager);

            var gridId = coordinates.GetGridId(entMan);

            var tileSize = 1f;

            if (gridId.IsValid())
            {
                var grid = mapManager.GetGrid(gridId);
                tileSize = grid.TileSize;
            }

            var localPos = coordinates.Position;

            var x = (int)Math.Floor(localPos.X / tileSize) + tileSize / 2f;
            var y = (int)Math.Floor(localPos.Y / tileSize) + tileSize / 2f;

            return(new EntityCoordinates(coordinates.EntityId, x, y));
        }
Exemplo n.º 21
0
        public static TileRef?GetTileRef(this EntityCoordinates coordinates, IEntityManager?entityManager = null, IMapManager?mapManager = null)
        {
            entityManager ??= IoCManager.Resolve <IEntityManager>();

            if (!coordinates.IsValid(entityManager))
            {
                return(null);
            }

            mapManager ??= IoCManager.Resolve <IMapManager>();

            if (!mapManager.TryGetGrid(coordinates.GetGridId(entityManager), out var grid))
            {
                return(null);
            }

            if (!grid.TryGetTileRef(coordinates, out var tile))
            {
                return(null);
            }

            return(tile);
        }
Exemplo n.º 22
0
        public static EntityCoordinates SnapToGrid(this EntityCoordinates coordinates,
                                                   SnapGridOffset offset = SnapGridOffset.Center, IEntityManager?entityManager = null, IMapManager?mapManager = null)
        {
            entityManager ??= IoCManager.Resolve <IEntityManager>();
            mapManager ??= IoCManager.Resolve <IMapManager>();

            var gridId = coordinates.GetGridId(entityManager);

            var tileSize = 1f;

            if (gridId.IsValid())
            {
                var grid = mapManager.GetGrid(gridId);
                tileSize = grid.TileSize;
            }

            var localPos = coordinates.Position;

            var x = (int)Math.Floor(localPos.X / tileSize) + tileSize / (offset == SnapGridOffset.Center ? 2f : 0f);
            var y = (int)Math.Floor(localPos.Y / tileSize) + tileSize / (offset == SnapGridOffset.Center ? 2f : 0f);

            return(new EntityCoordinates(coordinates.EntityId, x, y));
        }
        public bool TryPoint(ICommonSession?session, EntityCoordinates coords, EntityUid uid)
        {
            var player = (session as IPlayerSession)?.ContentData()?.Mind?.CurrentEntity;

            if (player == null)
            {
                return(false);
            }

            if (_pointers.TryGetValue(session !, out var lastTime) &&
                _gameTiming.CurTime < lastTime + PointDelay)
            {
                return(false);
            }

            if (EntityManager.TryGetEntity(uid, out var entity) && entity.HasComponent <PointingArrowComponent>())
            {
                // this is a pointing arrow. no pointing here...
                return(false);
            }

            if (!InRange(coords, player.Transform.Coordinates))
            {
                player.PopupMessage(Loc.GetString("You can't reach there!"));
                return(false);
            }

            if (ActionBlockerSystem.CanChangeDirection(player))
            {
                var diff = coords.ToMapPos(EntityManager) - player.Transform.MapPosition.Position;
                if (diff.LengthSquared > 0.01f)
                {
                    player.Transform.LocalRotation = new Angle(diff);
                }
            }

            var arrow = EntityManager.SpawnEntity("pointingarrow", coords);

            var layer = (int)VisibilityFlags.Normal;

            if (player.TryGetComponent(out VisibilityComponent? playerVisibility))
            {
                var arrowVisibility = arrow.EnsureComponent <VisibilityComponent>();
                layer = arrowVisibility.Layer = playerVisibility.Layer;
            }

            // Get players that are in range and whose visibility layer matches the arrow's.
            var viewers = _playerManager.GetPlayersBy((playerSession) =>
            {
                if ((playerSession.VisibilityMask & layer) == 0)
                {
                    return(false);
                }

                var ent = playerSession.ContentData()?.Mind?.CurrentEntity;

                return(ent != null &&
                       ent.Transform.MapPosition.InRange(player.Transform.MapPosition, PointingRange));
            });

            string selfMessage;
            string viewerMessage;
            string?viewerPointedAtMessage = null;

            if (EntityManager.TryGetEntity(uid, out var pointed))
            {
                selfMessage = player == pointed
                    ? Loc.GetString("You point at yourself.")
                    : Loc.GetString("You point at {0:theName}.", pointed);

                viewerMessage = player == pointed
                    ? $"{player.Name} {Loc.GetString("points at {0:themself}.", player)}"
                    : $"{player.Name} {Loc.GetString("points at {0:theName}.", pointed)}";

                viewerPointedAtMessage = $"{player.Name} {Loc.GetString("points at you.")}";
            }
            else
            {
                var tileRef = _mapManager.GetGrid(coords.GetGridId(EntityManager)).GetTileRef(coords);
                var tileDef = _tileDefinitionManager[tileRef.Tile.TypeId];

                selfMessage = Loc.GetString("You point at {0}.", tileDef.DisplayName);

                viewerMessage = $"{player.Name} {Loc.GetString("points at {0}.", tileDef.DisplayName)}";
            }

            _pointers[session !] = _gameTiming.CurTime;
Exemplo n.º 24
0
            public void Update(float frameTime)
            {
                Age += TimeSpan.FromSeconds(frameTime);
                if (Age >= Deathtime)
                {
                    return;
                }

                Velocity           += Acceleration * frameTime;
                RadialVelocity     += RadialAcceleration * frameTime;
                TangentialVelocity += TangentialAcceleration * frameTime;

                var deltaPosition = new Vector2(0f, 0f);

                //If we have an emitter we can do special effects around that emitter position
                if (_mapManager.GridExists(EmitterCoordinates.GetGridId(_entityManager)))
                {
                    //Calculate delta p due to radial velocity
                    var positionRelativeToEmitter =
                        Coordinates.ToMapPos(_entityManager) - EmitterCoordinates.ToMapPos(_entityManager);
                    var deltaRadial = RadialVelocity * frameTime;
                    deltaPosition = positionRelativeToEmitter * (deltaRadial / positionRelativeToEmitter.Length);

                    //Calculate delta p due to tangential velocity
                    var radius = positionRelativeToEmitter.Length;
                    if (radius > 0)
                    {
                        var theta = (float)Math.Atan2(positionRelativeToEmitter.Y, positionRelativeToEmitter.X);
                        theta         += TangentialVelocity * frameTime;
                        deltaPosition += new Vector2(radius * (float)Math.Cos(theta), radius * (float)Math.Sin(theta))
                                         - positionRelativeToEmitter;
                    }
                }

                //Calculate new position from our velocity as well as possible rotation/movement around emitter
                deltaPosition += Velocity * frameTime;
                Coordinates    = Coordinates.Offset(deltaPosition);

                //Finish calculating new rotation, size, color
                Rotation += RotationRate * frameTime;
                Size     += SizeDelta * frameTime;
                Color    += ColorDelta * frameTime;

                if (RsiState == null)
                {
                    return;
                }

                // Calculate RSI animations.
                var delayCount = RsiState.DelayCount;

                if (delayCount > 0 && (AnimationLoops || AnimationIndex < delayCount - 1))
                {
                    AnimationTime += frameTime;
                    while (RsiState.GetDelay(AnimationIndex) < AnimationTime)
                    {
                        var delay = RsiState.GetDelay(AnimationIndex);
                        AnimationIndex += 1;
                        AnimationTime  -= delay;
                        if (AnimationIndex == delayCount)
                        {
                            if (AnimationLoops)
                            {
                                AnimationIndex = 0;
                            }
                            else
                            {
                                break;
                            }
                        }

                        EffectSprite = RsiState.GetFrame(RSI.State.Direction.South, AnimationIndex);
                    }
                }
            }
Exemplo n.º 25
0
        public bool IsColliding(EntityCoordinates coordinates)
        {
            var bounds      = pManager.ColliderAABB;
            var worldcoords = coordinates.ToMapPos(pManager.EntityManager);

            var collisionbox = Box2.FromDimensions(
                bounds.Left + worldcoords.X,
                bounds.Bottom + worldcoords.Y,
                bounds.Width,
                bounds.Height);

            if (pManager.PhysicsManager.TryCollideRect(collisionbox, pManager.MapManager.GetGrid(coordinates.GetGridId(pManager.EntityManager)).ParentMapId))
            {
                return(true);
            }

            return(false);
        }
Exemplo n.º 26
0
        private HashSet <GridTileLookupNode> GetOrCreateNodes(EntityCoordinates coordinates, Box2 box)
        {
            var results = new HashSet <GridTileLookupNode>();

            foreach (var grid in _mapManager.FindGridsIntersecting(_mapManager.GetGrid(coordinates.GetGridId(EntityManager)).ParentMapId, box))
            {
                foreach (var tile in grid.GetTilesIntersecting(box))
                {
                    results.Add(GetOrCreateNode(grid.Index, tile.GridIndices));
                }
            }

            return(results);
        }