public IEntity GetEntityUnderPosition(GridLocalCoordinates coordinates) { // Find all the entities intersecting our click var entities = _entityManager.GetEntitiesIntersecting(coordinates.MapID, coordinates.Position); // Check the entities against whether or not we can click them var foundEntities = new List <(IEntity clicked, int drawDepth)>(); foreach (IEntity entity in entities) { if (entity.TryGetComponent <IClientClickableComponent>(out var component) && entity.GetComponent <ITransformComponent>().IsMapTransform && component.CheckClick(coordinates, out int drawdepthofclicked)) { foundEntities.Add((entity, drawdepthofclicked)); } } if (foundEntities.Count != 0) { foundEntities.Sort(new ClickableEntityComparer()); return(foundEntities[foundEntities.Count - 1].clicked); } return(null); }
/// <summary> /// Creates an instance of <see cref="FullInputCmdMessage"/> with an optional Entity reference. /// </summary> /// <param name="tick">Client tick this was created.</param> /// <param name="inputFunctionId">Function this command is changing.</param> /// <param name="state">New state of the Input Function.</param> /// <param name="coordinates">Local Coordinates of the pointer when the command was created.</param> /// <param name="uid">Entity that was under the pointer when the command was created.</param> public FullInputCmdMessage(uint tick, KeyFunctionId inputFunctionId, BoundKeyState state, GridLocalCoordinates coordinates, EntityUid uid) : base(tick, inputFunctionId) { State = state; Coordinates = coordinates; Uid = uid; }
void IAfterAttack.Afterattack(IEntity user, GridLocalCoordinates clicklocation, IEntity attacked) { if (UserCanFire(user) && WeaponCanFire()) { Fire(user, clicklocation); } }
private void HandleUseItemInWorld(ICommonSession session, GridLocalCoordinates coords, EntityUid uid) { if (!EntityManager.TryGetEntity(uid, out var used)) { return; } if (!used.TryGetComponent(out IActivate activateComp)) { return; } var playerEnt = ((IPlayerSession)session).AttachedEntity; if (playerEnt == null || !playerEnt.IsValid()) { return; } if (!playerEnt.Transform.LocalPosition.InRange(used.Transform.LocalPosition, INTERACTION_RANGE)) { return; } activateComp.Activate(playerEnt); }
private static void HandleThrowItem(ICommonSession session, GridLocalCoordinates coords, EntityUid uid) { var plyEnt = ((IPlayerSession)session).AttachedEntity; if (plyEnt == null || !plyEnt.IsValid()) { return; } if (!plyEnt.TryGetComponent(out HandsComponent handsComp)) { return; } if (!handsComp.CanDrop(handsComp.ActiveIndex)) { return; } var throwEnt = handsComp.GetHand(handsComp.ActiveIndex).Owner; // pop off an item, or throw the single item in hand. if (!throwEnt.TryGetComponent(out StackComponent stackComp) || stackComp.Count < 2) { handsComp.Drop(handsComp.ActiveIndex); }
private void _tryFire(IEntity user, GridLocalCoordinates coordinates, int attemptCount) { if (!user.TryGetComponent(out HandsComponent hands) || hands.GetActiveHand.Owner != Owner) { return; } if (!UserCanFire(user) || !WeaponCanFire()) { return; } // Firing delays are quite complicated. // Sometimes the client's fire messages come in just too early. // Generally this is a frame or two of being early. // In that case we try them a few times the next frames to avoid having to drop them. var curTime = IoCManager.Resolve <IGameTiming>().CurTime; var span = curTime - _lastFireTime; if (span.TotalSeconds < 1 / FireRate) { if (attemptCount >= MaxFireDelayAttempts) { return; } Timer.Spawn(TimeSpan.FromSeconds(1 / FireRate) - span, () => _tryFire(user, coordinates, attemptCount + 1)); return; } Fire(user, coordinates); }
public override void AlignPlacementMode(ScreenCoordinates mouseScreen) { MouseCoords = ScreenToPlayerGrid(mouseScreen); CurrentTile = MouseCoords.Grid.GetTile(MouseCoords); if (pManager.CurrentPermission.IsTile) { return; } var nodes = new List <Vector2>(); if (pManager.CurrentPrototype.MountingPoints != null) { nodes.AddRange( pManager.CurrentPrototype.MountingPoints.Select( current => new Vector2(MouseCoords.X, CurrentTile.Y + current))); } else { nodes.Add(new Vector2(MouseCoords.X, CurrentTile.Y + 0.5f)); nodes.Add(new Vector2(MouseCoords.X, CurrentTile.Y + 1.0f)); nodes.Add(new Vector2(MouseCoords.X, CurrentTile.Y + 1.5f)); } Vector2 closestNode = (from Vector2 node in nodes orderby(node - MouseCoords.Position).LengthSquared ascending select node).First(); MouseCoords = new GridLocalCoordinates(closestNode + new Vector2(pManager.CurrentPrototype.PlacementOffset.X, pManager.CurrentPrototype.PlacementOffset.Y), MouseCoords.Grid); }
public bool CheckClick(GridLocalCoordinates worldPos, out int drawdepth) { var component = Owner.GetComponent <IClickTargetComponent>(); drawdepth = (int)component.DrawDepth; return(true); }
private static void HandleDrop(ICommonSession session, GridLocalCoordinates coords, EntityUid uid) { var ent = ((IPlayerSession)session).AttachedEntity; if (ent == null || !ent.IsValid()) { return; } if (!ent.TryGetComponent(out HandsComponent handsComp)) { return; } var transform = ent.Transform; GridLocalCoordinates?dropPos = null; if (transform.LocalPosition.InRange(coords, InteractionSystem.INTERACTION_RANGE)) { dropPos = coords; } handsComp.Drop(handsComp.ActiveIndex, dropPos); }
private void HandleRunLevelChanged(object sender, RunLevelChangedEventArgs args) { switch (args.NewLevel) { case ServerRunLevel.PreGame: var timing = IoCManager.Resolve <IGameTiming>(); var mapLoader = IoCManager.Resolve <IMapLoader>(); var mapMan = IoCManager.Resolve <IMapManager>(); var newMap = mapMan.CreateMap(); var grid = mapLoader.LoadBlueprint(newMap, "Maps/stationstation.yml"); SpawnPoint = new GridLocalCoordinates(Vector2.Zero, grid); var startTime = timing.RealTime; var timeSpan = timing.RealTime - startTime; Logger.Info($"Loaded map in {timeSpan.TotalMilliseconds:N2}ms."); chatManager.DispatchMessage(ChatChannel.Server, "Gamemode: Round loaded!"); break; case ServerRunLevel.Game: _players.SendJoinGameToAll(); chatManager.DispatchMessage(ChatChannel.Server, "Gamemode: Round started!"); break; case ServerRunLevel.PostGame: chatManager.DispatchMessage(ChatChannel.Server, "Gamemode: Round over!"); break; } }
private static IList <IEntity> GetEntitiesUnderPosition(IClientEntityManager entityMan, GridLocalCoordinates coordinates) { // Find all the entities intersecting our click var entities = entityMan.GetEntitiesIntersecting(coordinates.MapID, coordinates.Position); // Check the entities against whether or not we can click them var foundEntities = new List <(IEntity clicked, int drawDepth)>(); foreach (var entity in entities) { if (entity.TryGetComponent <IClientClickableComponent>(out var component) && entity.Transform.IsMapTransform && component.CheckClick(coordinates, out var drawDepthClicked)) { foundEntities.Add((entity, drawDepthClicked)); } } if (foundEntities.Count == 0) { return(new List <IEntity>()); } foundEntities.Sort(new ClickableEntityComparer()); // 0 is the top element. foundEntities.Reverse(); return(foundEntities.Select(a => a.clicked).ToList()); }
public TryStartStructureConstructionMessage(GridLocalCoordinates loc, string prototypeName, Angle angle, int ack) { Directed = true; Location = loc; PrototypeName = prototypeName; Angle = angle; Ack = ack; }
public PointerInputCmdArgs(ICommonSession session, GridLocalCoordinates coordinates, ScreenCoordinates screenCoordinates, EntityUid entityUid) { Session = session; Coordinates = coordinates; ScreenCoordinates = screenCoordinates; EntityUid = entityUid; }
/// <summary> /// Gets all players inside of a circle. /// </summary> /// <param name="worldPos">Position of the circle in world-space.</param> /// <param name="range">Radius of the circle in world units.</param> /// <returns></returns> public List <IPlayerSession> GetPlayersInRange(GridLocalCoordinates worldPos, int range) { //TODO: This needs to be moved to the PVS system. return (_sessions.Values.Where(x => x.AttachedEntity != null && worldPos.InRange(x.AttachedEntity.GetComponent <ITransformComponent>().LocalPosition, range)) .Cast <IPlayerSession>() .ToList()); }
public override bool HijackPlacementRequest(GridLocalCoordinates coords) { if (Prototype != null) { var dir = Manager.Direction; Owner.SpawnGhost(Prototype, coords, dir); } return(true); }
public override bool IsValidPosition(GridLocalCoordinates position) { if (!RangeCheck(position)) { return(false); } return(true); }
/// <summary> /// We didn't click on any entity, try doing an afterattack on the click location /// </summary> /// <param name="user"></param> /// <param name="weapon"></param> /// <param name="clicklocation"></param> public static void InteractAfterattack(IEntity user, IEntity weapon, GridLocalCoordinates clicklocation) { List <IAfterAttack> afterattacks = weapon.GetAllComponents <IAfterAttack>().ToList(); for (var i = 0; i < afterattacks.Count; i++) { afterattacks[i].Afterattack(user, clicklocation, null); } }
public override void PopupMessage(GridLocalCoordinates coordinates, IEntity viewer, string message) { if (viewer != _playerManager.LocalPlayer.ControlledEntity) { return; } PopupMessage(_eyeManager.WorldToScreen(coordinates), message); }
public override void AlignPlacementMode(ScreenCoordinates mouseScreen) { MouseCoords = ScreenToPlayerGrid(mouseScreen); CurrentTile = MouseCoords.Grid.GetTile(MouseCoords); if (pManager.CurrentPermission.IsTile) { return; } if (!RangeCheck(MouseCoords)) { return; } var manager = IoCManager.Resolve <IClientEntityManager>(); var snapToEntities = manager.GetEntitiesInRange(MouseCoords, SnapToRange) .Where(entity => entity.Prototype == pManager.CurrentPrototype && entity.Transform.MapID == MouseCoords.MapID) .OrderBy(entity => (entity.Transform.WorldPosition - MouseCoords.ToWorld().Position).LengthSquared) .ToList(); if (snapToEntities.Count == 0) { return; } var closestEntity = snapToEntities[0]; if (!closestEntity.TryGetComponent <ISpriteComponent>(out var component)) { return; } var closestBounds = component.BaseRSI.Size; var closestRect = Box2.FromDimensions( closestEntity.Transform.WorldPosition.X - closestBounds.X / 2f, closestEntity.Transform.WorldPosition.Y - closestBounds.Y / 2f, closestBounds.X, closestBounds.Y); var sides = new[] { new Vector2(closestRect.Left + closestRect.Width / 2f, closestRect.Top - closestBounds.Y / 2f), new Vector2(closestRect.Left + closestRect.Width / 2f, closestRect.Bottom + closestBounds.Y / 2f), new Vector2(closestRect.Left - closestBounds.X / 2f, closestRect.Top + closestRect.Height / 2f), new Vector2(closestRect.Right + closestBounds.X / 2f, closestRect.Top + closestRect.Height / 2f) }; var closestSide = (from Vector2 side in sides orderby(side - MouseCoords.Position).LengthSquared select side).First(); MouseCoords = new GridLocalCoordinates(closestSide, MouseCoords.Grid); }
protected override void Fire(IEntity user, GridLocalCoordinates clicklocation) { var userposition = user.GetComponent <TransformComponent>().WorldPosition; //Remember world positions are ephemeral and can only be used instantaneously var angle = new Angle(clicklocation.Position - userposition); var ray = new Ray(userposition, angle.ToVec()); var raycastresults = IoCManager.Resolve <ICollisionManager>().IntersectRay(ray, 20, Owner.GetComponent <TransformComponent>().GetMapTransform().Owner); Hit(raycastresults); AfterEffects(user, raycastresults, angle); }
/// <summary> /// Play an audio file at a static position. /// </summary> /// <param name="filename">The resource path to the OGG Vorbis file to play.</param> /// <param name="coordinates">The coordinates at which to play the audio.</param> public void Play(string filename, GridLocalCoordinates coordinates, AudioParams?audioParams = null) { var msg = new PlayAudioPositionalMessage { FileName = filename, Coordinates = coordinates, AudioParams = audioParams ?? AudioParams.Default }; RaiseNetworkEvent(msg); }
private void Fire(IEntity user, GridLocalCoordinates clickLocation) { var userPosition = user.Transform.WorldPosition; //Remember world positions are ephemeral and can only be used instantaneously var angle = new Angle(clickLocation.Position - userPosition); var ray = new Ray(userPosition, angle.ToVec()); var rayCastResults = IoCManager.Resolve <IPhysicsManager>().IntersectRay(ray, MaxLength, Owner.Transform.GetMapTransform().Owner); Hit(rayCastResults); AfterEffects(user, rayCastResults, angle); }
public override bool IsValidPosition(GridLocalCoordinates position) { if (!RangeCheck(position)) { return(false); } var entitymanager = IoCManager.Resolve <IClientEntityManager>(); return(!(entitymanager.AnyEntitiesIntersecting(MouseCoords.MapID, new Box2(new Vector2(CurrentTile.X, CurrentTile.Y), new Vector2(CurrentTile.X + 0.99f, CurrentTile.Y + 0.99f))))); }
public override IEntity ForceSpawnEntityAt(string entityType, GridLocalCoordinates coordinates) { Entity entity = SpawnEntity(entityType); entity.GetComponent <ITransformComponent>().LocalPosition = coordinates; if (EntitiesInitialized) { InitializeEntity(entity); } return(entity); }
private void HandleExamine(ICommonSession session, GridLocalCoordinates coords, EntityUid uid) { if (!(session is IPlayerSession svSession)) { return; } var playerEnt = svSession.AttachedEntity; if (!EntityManager.TryGetEntity(uid, out var examined)) { return; } //Verify player has a transform component if (!playerEnt.TryGetComponent <ITransformComponent>(out var playerTransform)) { return; } //Verify player is on the same map as the entity he clicked on if (coords.MapID != playerTransform.MapID) { Logger.WarningS("sys.examine", $"Player named {session.Name} clicked on a map he isn't located on"); return; } //Start a StringBuilder since we have no idea how many times this could be appended to var fullExamineText = new StringBuilder("This is " + examined.Name); //Add an entity description if one is declared if (!string.IsNullOrEmpty(examined.Description)) { fullExamineText.Append(Environment.NewLine + examined.Description); } //Add component statuses from components that report one foreach (var examineComponents in examined.GetAllComponents <IExamine>()) { var componentDescription = examineComponents.Examine(); if (string.IsNullOrEmpty(componentDescription)) { continue; } fullExamineText.Append(Environment.NewLine); fullExamineText.Append(componentDescription); } //Send to client chat channel IoCManager.Resolve <IChatManager>().DispatchMessage(SS14.Shared.Console.ChatChannel.Visual, fullExamineText.ToString(), session.SessionId); }
public override bool IsValidPosition(GridLocalCoordinates position) { if (!RangeCheck(position)) { return(false); } if (!pManager.CurrentPermission.IsTile && !IsColliding(position)) { return(false); } return(true); }
public override void PopupMessage(GridLocalCoordinates coordinates, IEntity viewer, string message) { if (!viewer.TryGetComponent(out IActorComponent actor)) { return; } var netMessage = _netManager.CreateNetMessage <MsgDoNotify>(); netMessage.Coordinates = coordinates; netMessage.Message = message; _netManager.ServerSendMessage(netMessage, actor.playerSession.ConnectedClient); }
private static void HandleThrowItem(ICommonSession session, GridLocalCoordinates coords, EntityUid uid) { var plyEnt = ((IPlayerSession)session).AttachedEntity; if (plyEnt == null || !plyEnt.IsValid()) { return; } if (!plyEnt.TryGetComponent(out HandsComponent handsComp)) { return; } if (handsComp.CanDrop(handsComp.ActiveIndex)) { var throwEnt = handsComp.GetHand(handsComp.ActiveIndex).Owner; handsComp.Drop(handsComp.ActiveIndex, null); if (!throwEnt.TryGetComponent(out ProjectileComponent projComp)) { projComp = throwEnt.AddComponent <ProjectileComponent>(); } projComp.IgnoreEntity(plyEnt); var transform = plyEnt.Transform; var dirVec = (coords.ToWorld().Position - transform.WorldPosition).Normalized; if (!throwEnt.TryGetComponent(out PhysicsComponent physComp)) { physComp = throwEnt.AddComponent <PhysicsComponent>(); } physComp.LinearVelocity = dirVec * ThrowSpeed; var wHomoDir = Vector3.UnitX; transform.InvWorldMatrix.Transform(ref wHomoDir, out var lHomoDir); lHomoDir.Normalize(); var angle = new Angle(lHomoDir.Xy); transform.LocalRotation = angle; } else { return; } }
/// <summary> /// Checks if the player is spawning within a certain range of his character if range is required on this mode /// </summary> /// <returns></returns> public bool RangeCheck(GridLocalCoordinates coordinates) { if (!RangeRequired) { return(true); } var range = pManager.CurrentPermission.Range; if (range > 0 && !pManager.PlayerManager.LocalPlayer.ControlledEntity.Transform.LocalPosition.InRange(coordinates, range)) { return(false); } return(true); }
public void TryFire(GridLocalCoordinates worldPos) { var curTime = IoCManager.Resolve <IGameTiming>().CurTime; var span = curTime - _lastFireTime; if (span.TotalSeconds < 1 / FireRate) { return; } Logger.Debug("Delay: {0}", span.TotalSeconds); _lastFireTime = curTime; SendNetworkMessage(new FireMessage(worldPos, _tick++)); }