/// <summary> /// Set's the mob standing state to down. /// </summary> /// <param name="entity">The mob in question</param> /// <param name="playSound">Whether to play a sound when falling down or not</param> /// <param name="dropItems">Whether to make the mob drop all the items on his hands</param> /// <param name="force">Whether or not to check if the entity can fall.</param> /// <returns>False if the mob was already downed or couldn't set the state</returns> public static bool Down(IEntity entity, bool playSound = true, bool dropItems = true, bool force = false) { if (!force && !EffectBlockerSystem.CanFall(entity)) { return(false); } if (!entity.TryGetComponent(out AppearanceComponent appearance)) { return(false); } var newState = SharedSpeciesComponent.MobState.Down; appearance.TryGetData <SharedSpeciesComponent.MobState>(SharedSpeciesComponent.MobVisuals.RotationState, out var oldState); if (newState != oldState) { appearance.SetData(SharedSpeciesComponent.MobVisuals.RotationState, newState); } if (playSound) { IoCManager.Resolve <IEntitySystemManager>().GetEntitySystem <AudioSystem>() .PlayFromEntity(AudioHelpers.GetRandomFileFromSoundCollection("bodyfall"), entity, AudioHelpers.WithVariation(0.25f)); } if (dropItems) { DropAllItemsInHands(entity, false); } return(true); }
bool IEffectBlocker.CanSlip() { if (Owner.TryGetComponent(out InventoryComponent inventoryComponent) && inventoryComponent.TryGetSlotItem(EquipmentSlotDefines.Slots.SHOES, out ItemComponent shoes) ) { return(EffectBlockerSystem.CanSlip(shoes.Owner)); } return(true); }
public bool Down(IEntity entity, bool playSound = true, bool dropItems = true, bool force = false) { if (dropItems) { DropAllItemsInHands(entity, false); } if (!force && !EffectBlockerSystem.CanFall(entity)) { return(false); } return(OnDown(entity, playSound, dropItems, force)); }
private bool TrySlip(IEntity entity) { if (!Slippery || ContainerHelpers.IsInContainer(Owner) || _slipped.Contains(entity.Uid) || !entity.TryGetComponent(out SharedStunnableComponent stun) || !entity.TryGetComponent(out ICollidableComponent otherBody) || !Owner.TryGetComponent(out ICollidableComponent body)) { return(false); } if (otherBody.LinearVelocity.Length < RequiredSlipSpeed || stun.KnockedDown) { return(false); } var percentage = otherBody.WorldAABB.IntersectPercentage(body.WorldAABB); if (percentage < IntersectPercentage) { return(false); } if (!EffectBlockerSystem.CanSlip(entity)) { return(false); } if (entity.TryGetComponent(out ICollidableComponent collidable)) { var controller = collidable.EnsureController <SlipController>(); controller.LinearVelocity = collidable.LinearVelocity * LaunchForwardsMultiplier; } stun.Paralyze(5); _slipped.Add(entity.Uid); OnSlip(); return(true); }
public void CollideWith(IEntity collidedWith) { if (ContainerHelpers.IsInContainer(Owner) || _slipped.Contains(collidedWith.Uid) || !collidedWith.TryGetComponent(out StunnableComponent stun) || !collidedWith.TryGetComponent(out ICollidableComponent otherBody) || !collidedWith.TryGetComponent(out IPhysicsComponent otherPhysics) || !Owner.TryGetComponent(out ICollidableComponent body)) { return; } if (otherPhysics.LinearVelocity.Length < RequiredSlipSpeed || stun.KnockedDown) { return; } var percentage = otherBody.WorldAABB.IntersectPercentage(body.WorldAABB); if (percentage < IntersectPercentage) { return; } if (!EffectBlockerSystem.CanSlip(collidedWith)) { return; } stun.Paralyze(5f); _slipped.Add(collidedWith.Uid); if (!string.IsNullOrEmpty(SlipSound)) { EntitySystem.Get <AudioSystem>().PlayFromEntity(SlipSound, Owner, AudioHelpers.WithVariation(0.2f)); } }
private bool TrySlip(SlipperyComponent component, IPhysBody ourBody, IPhysBody otherBody) { if (!component.Slippery || component.Owner.IsInContainer() || component.Slipped.Contains(otherBody.Owner.Uid) || !otherBody.Owner.TryGetComponent(out SharedStunnableComponent? stun)) { return(false); } if (otherBody.LinearVelocity.Length < component.RequiredSlipSpeed || stun.KnockedDown) { return(false); } var percentage = otherBody.GetWorldAABB().IntersectPercentage(ourBody.GetWorldAABB()); if (percentage < component.IntersectPercentage) { return(false); } if (!EffectBlockerSystem.CanSlip(otherBody.Owner)) { return(false); } otherBody.LinearVelocity *= component.LaunchForwardsMultiplier; stun.Paralyze(5); component.Slipped.Add(otherBody.Owner.Uid); component.Dirty(); PlaySound(component); return(true); }
private bool TrySlip(IEntity entity) { if (ContainerHelpers.IsInContainer(Owner) || _slipped.Contains(entity.Uid) || !entity.TryGetComponent(out SharedStunnableComponent stun) || !entity.TryGetComponent(out ICollidableComponent otherBody) || !entity.TryGetComponent(out IPhysicsComponent otherPhysics) || !Owner.TryGetComponent(out ICollidableComponent body)) { return(false); } if (otherPhysics.LinearVelocity.Length < RequiredSlipSpeed || stun.KnockedDown) { return(false); } var percentage = otherBody.WorldAABB.IntersectPercentage(body.WorldAABB); if (percentage < IntersectPercentage) { return(false); } if (!EffectBlockerSystem.CanSlip(entity)) { return(false); } stun.Paralyze(5); _slipped.Add(entity.Uid); OnSlip(); return(true); }
public async Task BuckleUnbuckleCooldownRangeTest() { var cOptions = new ClientIntegrationOptions { ExtraPrototypes = Prototypes }; var sOptions = new ServerIntegrationOptions { ExtraPrototypes = Prototypes }; var(_, server) = await StartConnectedServerClientPair(cOptions, sOptions); IEntity human = null; IEntity chair = null; BuckleComponent buckle = null; StrapComponent strap = null; await server.WaitAssertion(() => { var mapManager = IoCManager.Resolve <IMapManager>(); var entityManager = IoCManager.Resolve <IEntityManager>(); var actionBlocker = EntitySystem.Get <ActionBlockerSystem>(); var gridId = new GridId(1); var grid = mapManager.GetGrid(gridId); var coordinates = grid.GridEntityId.ToCoordinates(); human = entityManager.SpawnEntity(BuckleDummyId, coordinates); chair = entityManager.SpawnEntity(StrapDummyId, coordinates); // Default state, unbuckled Assert.True(human.TryGetComponent(out buckle)); Assert.NotNull(buckle); Assert.Null(buckle.BuckledTo); Assert.False(buckle.Buckled); Assert.True(actionBlocker.CanMove(human)); Assert.True(actionBlocker.CanChangeDirection(human)); Assert.True(EffectBlockerSystem.CanFall(human)); // Default state, no buckled entities, strap Assert.True(chair.TryGetComponent(out strap)); Assert.NotNull(strap); Assert.IsEmpty(strap.BuckledEntities); Assert.Zero(strap.OccupiedSize); // Side effects of buckling Assert.True(buckle.TryBuckle(human, chair)); Assert.NotNull(buckle.BuckledTo); Assert.True(buckle.Buckled); var player = IoCManager.Resolve <IPlayerManager>().GetAllPlayers().Single(); Assert.True(((BuckleComponentState)buckle.GetComponentState(player)).Buckled); Assert.False(actionBlocker.CanMove(human)); Assert.False(actionBlocker.CanChangeDirection(human)); Assert.False(EffectBlockerSystem.CanFall(human)); Assert.That(human.Transform.WorldPosition, Is.EqualTo(chair.Transform.WorldPosition)); // Side effects of buckling for the strap Assert.That(strap.BuckledEntities, Does.Contain(human)); Assert.That(strap.OccupiedSize, Is.EqualTo(buckle.Size)); Assert.Positive(strap.OccupiedSize); // Trying to buckle while already buckled fails Assert.False(buckle.TryBuckle(human, chair)); // Trying to unbuckle too quickly fails Assert.False(buckle.TryUnbuckle(human)); Assert.False(buckle.ToggleBuckle(human, chair)); Assert.True(buckle.Buckled); }); // Wait enough ticks for the unbuckling cooldown to run out await server.WaitRunTicks(60); await server.WaitAssertion(() => { var actionBlocker = EntitySystem.Get <ActionBlockerSystem>(); // Still buckled Assert.True(buckle.Buckled); // Unbuckle Assert.True(buckle.TryUnbuckle(human)); Assert.Null(buckle.BuckledTo); Assert.False(buckle.Buckled); Assert.True(actionBlocker.CanMove(human)); Assert.True(actionBlocker.CanChangeDirection(human)); Assert.True(EffectBlockerSystem.CanFall(human)); // Unbuckle, strap Assert.IsEmpty(strap.BuckledEntities); Assert.Zero(strap.OccupiedSize); // Re-buckling has no cooldown Assert.True(buckle.TryBuckle(human, chair)); Assert.True(buckle.Buckled); // On cooldown Assert.False(buckle.TryUnbuckle(human)); Assert.True(buckle.Buckled); Assert.False(buckle.ToggleBuckle(human, chair)); Assert.True(buckle.Buckled); Assert.False(buckle.ToggleBuckle(human, chair)); Assert.True(buckle.Buckled); }); // Wait enough ticks for the unbuckling cooldown to run out await server.WaitRunTicks(60); await server.WaitAssertion(() => { var actionBlocker = EntitySystem.Get <ActionBlockerSystem>(); // Still buckled Assert.True(buckle.Buckled); // Unbuckle Assert.True(buckle.TryUnbuckle(human)); Assert.False(buckle.Buckled); // Move away from the chair human.Transform.WorldPosition += (1000, 1000); // Out of range Assert.False(buckle.TryBuckle(human, chair)); Assert.False(buckle.TryUnbuckle(human)); Assert.False(buckle.ToggleBuckle(human, chair)); // Move near the chair human.Transform.WorldPosition = chair.Transform.WorldPosition + (0.5f, 0); // In range Assert.True(buckle.TryBuckle(human, chair)); Assert.True(buckle.Buckled); Assert.False(buckle.TryUnbuckle(human)); Assert.True(buckle.Buckled); Assert.False(buckle.ToggleBuckle(human, chair)); Assert.True(buckle.Buckled); // Force unbuckle Assert.True(buckle.TryUnbuckle(human, true)); Assert.False(buckle.Buckled); Assert.True(actionBlocker.CanMove(human)); Assert.True(actionBlocker.CanChangeDirection(human)); Assert.True(EffectBlockerSystem.CanFall(human)); // Re-buckle Assert.True(buckle.TryBuckle(human, chair)); // Move away from the chair human.Transform.WorldPosition += (1, 0); }); await server.WaitRunTicks(1); await server.WaitAssertion(() => { // No longer buckled Assert.False(buckle.Buckled); Assert.Null(buckle.BuckledTo); Assert.IsEmpty(strap.BuckledEntities); }); }
public async Task BuckleUnbuckleCooldownRangeTest() { var server = StartServerDummyTicker(); IEntity human = null; IEntity chair = null; BuckleComponent buckle = null; StrapComponent strap = null; await server.WaitAssertion(() => { var mapManager = IoCManager.Resolve <IMapManager>(); mapManager.CreateNewMapEntity(MapId.Nullspace); var entityManager = IoCManager.Resolve <IEntityManager>(); human = entityManager.SpawnEntity("HumanMob_Content", MapCoordinates.Nullspace); chair = entityManager.SpawnEntity("ChairWood", MapCoordinates.Nullspace); // Default state, unbuckled Assert.True(human.TryGetComponent(out buckle)); Assert.NotNull(buckle); Assert.Null(buckle.BuckledTo); Assert.False(buckle.Buckled); Assert.True(ActionBlockerSystem.CanMove(human)); Assert.True(ActionBlockerSystem.CanChangeDirection(human)); Assert.True(EffectBlockerSystem.CanFall(human)); // Default state, no buckled entities, strap Assert.True(chair.TryGetComponent(out strap)); Assert.NotNull(strap); Assert.IsEmpty(strap.BuckledEntities); Assert.Zero(strap.OccupiedSize); // Side effects of buckling Assert.True(buckle.TryBuckle(human, chair)); Assert.NotNull(buckle.BuckledTo); Assert.True(buckle.Buckled); Assert.True(((BuckleComponentState)buckle.GetComponentState()).Buckled); Assert.False(ActionBlockerSystem.CanMove(human)); Assert.False(ActionBlockerSystem.CanChangeDirection(human)); Assert.False(EffectBlockerSystem.CanFall(human)); Assert.That(human.Transform.WorldPosition, Is.EqualTo(chair.Transform.WorldPosition)); // Side effects of buckling for the strap Assert.That(strap.BuckledEntities, Does.Contain(human)); Assert.That(strap.OccupiedSize, Is.EqualTo(buckle.Size)); Assert.Positive(strap.OccupiedSize); // Trying to buckle while already buckled fails Assert.False(buckle.TryBuckle(human, chair)); // Trying to unbuckle too quickly fails Assert.False(buckle.TryUnbuckle(human)); Assert.False(buckle.ToggleBuckle(human, chair)); Assert.True(buckle.Buckled); }); // Wait enough ticks for the unbuckling cooldown to run out await server.WaitRunTicks(60); await server.WaitAssertion(() => { // Still buckled Assert.True(buckle.Buckled); // Unbuckle Assert.True(buckle.TryUnbuckle(human)); Assert.Null(buckle.BuckledTo); Assert.False(buckle.Buckled); Assert.True(ActionBlockerSystem.CanMove(human)); Assert.True(ActionBlockerSystem.CanChangeDirection(human)); Assert.True(EffectBlockerSystem.CanFall(human)); // Unbuckle, strap Assert.IsEmpty(strap.BuckledEntities); Assert.Zero(strap.OccupiedSize); // Re-buckling has no cooldown Assert.True(buckle.TryBuckle(human, chair)); Assert.True(buckle.Buckled); // On cooldown Assert.False(buckle.TryUnbuckle(human)); Assert.True(buckle.Buckled); Assert.False(buckle.ToggleBuckle(human, chair)); Assert.True(buckle.Buckled); Assert.False(buckle.ToggleBuckle(human, chair)); Assert.True(buckle.Buckled); }); // Wait enough ticks for the unbuckling cooldown to run out await server.WaitRunTicks(60); await server.WaitAssertion(() => { // Still buckled Assert.True(buckle.Buckled); // Unbuckle Assert.True(buckle.TryUnbuckle(human)); Assert.False(buckle.Buckled); // Move away from the chair human.Transform.WorldPosition += (1000, 1000); // Out of range Assert.False(buckle.TryBuckle(human, chair)); Assert.False(buckle.TryUnbuckle(human)); Assert.False(buckle.ToggleBuckle(human, chair)); // Move near the chair human.Transform.WorldPosition = chair.Transform.WorldPosition + (0.5f, 0); // In range Assert.True(buckle.TryBuckle(human, chair)); Assert.True(buckle.Buckled); Assert.False(buckle.TryUnbuckle(human)); Assert.True(buckle.Buckled); Assert.False(buckle.ToggleBuckle(human, chair)); Assert.True(buckle.Buckled); // Force unbuckle Assert.True(buckle.TryUnbuckle(human, true)); Assert.False(buckle.Buckled); Assert.True(ActionBlockerSystem.CanMove(human)); Assert.True(ActionBlockerSystem.CanChangeDirection(human)); Assert.True(EffectBlockerSystem.CanFall(human)); // Re-buckle Assert.True(buckle.TryBuckle(human, chair)); // Move away from the chair human.Transform.WorldPosition += (1, 0); }); await server.WaitRunTicks(1); await server.WaitAssertion(() => { // No longer buckled Assert.False(buckle.Buckled); Assert.Null(buckle.BuckledTo); Assert.IsEmpty(strap.BuckledEntities); }); }