Merge branch 'master' of https://github.com/space-wizards/space-station-14
This commit is contained in:
@@ -302,7 +302,8 @@ namespace Content.Client.Chat
|
||||
case "ALL":
|
||||
chatBox.LocalButton.Pressed ^= true;
|
||||
chatBox.OOCButton.Pressed ^= true;
|
||||
chatBox.AdminButton.Pressed ^= true;
|
||||
if (chatBox.AdminButton != null)
|
||||
chatBox.AdminButton.Pressed ^= true;
|
||||
_allState = !_allState;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace Content.Client.GameObjects.Components.Disposal
|
||||
|
||||
private string _stateAnchored;
|
||||
private string _stateUnAnchored;
|
||||
private string _stateCharging;
|
||||
private string _overlayCharging;
|
||||
private string _overlayReady;
|
||||
private string _overlayFull;
|
||||
@@ -47,6 +48,9 @@ namespace Content.Client.GameObjects.Components.Disposal
|
||||
case VisualState.Anchored:
|
||||
sprite.LayerSetState(DisposalUnitVisualLayers.Base, _stateAnchored);
|
||||
break;
|
||||
case VisualState.Charging:
|
||||
sprite.LayerSetState(DisposalUnitVisualLayers.Base, _stateCharging);
|
||||
break;
|
||||
case VisualState.Flushing:
|
||||
sprite.LayerSetState(DisposalUnitVisualLayers.Base, _stateAnchored);
|
||||
|
||||
@@ -111,6 +115,7 @@ namespace Content.Client.GameObjects.Components.Disposal
|
||||
|
||||
_stateAnchored = node.GetNode("state_anchored").AsString();
|
||||
_stateUnAnchored = node.GetNode("state_unanchored").AsString();
|
||||
_stateCharging = node.GetNode("state_charging").AsString();
|
||||
_overlayCharging = node.GetNode("overlay_charging").AsString();
|
||||
_overlayReady = node.GetNode("overlay_ready").AsString();
|
||||
_overlayFull = node.GetNode("overlay_full").AsString();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Content.Shared.GameObjects.Components.Weapons.Ranged;
|
||||
using Content.Shared.GameObjects.Components.Weapons.Ranged;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Weapons.Ranged
|
||||
{
|
||||
@@ -30,9 +31,9 @@ namespace Content.Client.GameObjects.Components.Weapons.Ranged
|
||||
FireRateSelector = rangedState.FireRateSelector;
|
||||
}
|
||||
|
||||
public void SyncFirePos(GridCoordinates worldPos)
|
||||
public void SyncFirePos(GridId targetGrid, Vector2 targetPosition)
|
||||
{
|
||||
SendNetworkMessage(new FirePosComponentMessage(worldPos));
|
||||
SendNetworkMessage(new FirePosComponentMessage(targetGrid, targetPosition));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ using Robust.Shared.Input;
|
||||
using Robust.Shared.Interfaces.Map;
|
||||
using Robust.Shared.Interfaces.Timing;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Map;
|
||||
|
||||
namespace Content.Client.GameObjects.EntitySystems
|
||||
{
|
||||
@@ -96,9 +97,13 @@ namespace Content.Client.GameObjects.EntitySystems
|
||||
var worldPos = _eyeManager.ScreenToMap(_inputManager.MouseScreenPosition);
|
||||
|
||||
if (!_mapManager.TryFindGridAt(worldPos, out var grid))
|
||||
grid = _mapManager.GetDefaultGrid(worldPos.MapId);
|
||||
|
||||
weapon.SyncFirePos(grid.MapToGrid(worldPos));
|
||||
{
|
||||
weapon.SyncFirePos(GridId.Invalid, worldPos.Position);
|
||||
}
|
||||
else
|
||||
{
|
||||
weapon.SyncFirePos(grid.Index, grid.MapToGrid(worldPos).Position);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,11 +3,9 @@ using System.Collections.Generic;
|
||||
using Content.Server.AI.Operators;
|
||||
using Content.Server.AI.Operators.Inventory;
|
||||
using Content.Server.AI.Utility.Considerations;
|
||||
using Content.Server.AI.Utility.Considerations.Clothing;
|
||||
using Content.Server.AI.Utility.Considerations.Inventory;
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
using Content.Shared.GameObjects.Components.Inventory;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
@@ -44,9 +42,7 @@ namespace Content.Server.AI.Utility.Actions.Clothing.Gloves
|
||||
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<ClothingInSlotCon>().Slot(EquipmentSlotDefines.Slots.GLOVES, context)
|
||||
.InverseBoolCurve(context),
|
||||
considerationsManager.Get<CanPutTargetInHandsCon>()
|
||||
considerationsManager.Get<CanPutTargetInInventoryCon>()
|
||||
.BoolCurve(context),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ using Content.Server.AI.Utility.Considerations;
|
||||
using Content.Server.AI.Utility.Considerations.Clothing;
|
||||
using Content.Server.AI.Utility.Considerations.Containers;
|
||||
using Content.Server.AI.Utility.Considerations.Inventory;
|
||||
using Content.Server.AI.Utility.Considerations.Movement;
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
using Content.Shared.GameObjects.Components.Inventory;
|
||||
@@ -40,13 +41,11 @@ namespace Content.Server.AI.Utility.Actions.Clothing.Gloves
|
||||
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<ClothingInSlotCon>().Slot(EquipmentSlotDefines.Slots.GLOVES, context)
|
||||
.InverseBoolCurve(context),
|
||||
considerationsManager.Get<CanPutTargetInHandsCon>()
|
||||
considerationsManager.Get<CanPutTargetInInventoryCon>()
|
||||
.BoolCurve(context),
|
||||
considerationsManager.Get<ClothingInInventoryCon>().Slot(EquipmentSlotDefines.SlotFlags.GLOVES, context)
|
||||
.InverseBoolCurve(context),
|
||||
considerationsManager.Get<TargetAccessibleCon>()
|
||||
considerationsManager.Get<TargetDistanceCon>()
|
||||
.PresetCurve(context, PresetCurve.Distance),
|
||||
considerationsManager.Get<TargetAccessibleCon>()
|
||||
.BoolCurve(context),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -44,9 +44,7 @@ namespace Content.Server.AI.Utility.Actions.Clothing.Head
|
||||
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<ClothingInSlotCon>().Slot(EquipmentSlotDefines.Slots.HEAD, context)
|
||||
.InverseBoolCurve(context),
|
||||
considerationsManager.Get<CanPutTargetInHandsCon>()
|
||||
considerationsManager.Get<CanPutTargetInInventoryCon>()
|
||||
.BoolCurve(context),
|
||||
};
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ using Content.Server.AI.Utility.Considerations;
|
||||
using Content.Server.AI.Utility.Considerations.Clothing;
|
||||
using Content.Server.AI.Utility.Considerations.Containers;
|
||||
using Content.Server.AI.Utility.Considerations.Inventory;
|
||||
using Content.Server.AI.Utility.Considerations.Movement;
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
using Content.Shared.GameObjects.Components.Inventory;
|
||||
@@ -40,13 +41,11 @@ namespace Content.Server.AI.Utility.Actions.Clothing.Head
|
||||
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<ClothingInSlotCon>().Slot(EquipmentSlotDefines.Slots.HEAD, context)
|
||||
.InverseBoolCurve(context),
|
||||
considerationsManager.Get<CanPutTargetInHandsCon>()
|
||||
considerationsManager.Get<CanPutTargetInInventoryCon>()
|
||||
.BoolCurve(context),
|
||||
considerationsManager.Get<ClothingInInventoryCon>().Slot(EquipmentSlotDefines.SlotFlags.HEAD, context)
|
||||
.InverseBoolCurve(context),
|
||||
considerationsManager.Get<TargetAccessibleCon>()
|
||||
considerationsManager.Get<TargetDistanceCon>()
|
||||
.PresetCurve(context, PresetCurve.Distance),
|
||||
considerationsManager.Get<TargetAccessibleCon>()
|
||||
.BoolCurve(context),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -44,9 +44,7 @@ namespace Content.Server.AI.Utility.Actions.Clothing.OuterClothing
|
||||
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<ClothingInSlotCon>().Slot(EquipmentSlotDefines.Slots.OUTERCLOTHING, context)
|
||||
.InverseBoolCurve(context),
|
||||
considerationsManager.Get<CanPutTargetInHandsCon>()
|
||||
considerationsManager.Get<CanPutTargetInInventoryCon>()
|
||||
.BoolCurve(context),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ using Content.Server.AI.Utility.Considerations;
|
||||
using Content.Server.AI.Utility.Considerations.Clothing;
|
||||
using Content.Server.AI.Utility.Considerations.Containers;
|
||||
using Content.Server.AI.Utility.Considerations.Inventory;
|
||||
using Content.Server.AI.Utility.Considerations.Movement;
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
using Content.Shared.GameObjects.Components.Inventory;
|
||||
@@ -40,12 +41,10 @@ namespace Content.Server.AI.Utility.Actions.Clothing.OuterClothing
|
||||
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<ClothingInSlotCon>().Slot(EquipmentSlotDefines.Slots.OUTERCLOTHING, context)
|
||||
.InverseBoolCurve(context),
|
||||
considerationsManager.Get<CanPutTargetInHandsCon>()
|
||||
considerationsManager.Get<CanPutTargetInInventoryCon>()
|
||||
.BoolCurve(context),
|
||||
considerationsManager.Get<ClothingInInventoryCon>().Slot(EquipmentSlotDefines.SlotFlags.OUTERCLOTHING, context)
|
||||
.InverseBoolCurve(context),
|
||||
considerationsManager.Get<TargetDistanceCon>()
|
||||
.PresetCurve(context, PresetCurve.Distance),
|
||||
considerationsManager.Get<TargetAccessibleCon>()
|
||||
.BoolCurve(context),
|
||||
};
|
||||
|
||||
@@ -44,9 +44,7 @@ namespace Content.Server.AI.Utility.Actions.Clothing.Shoes
|
||||
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<ClothingInSlotCon>().Slot(EquipmentSlotDefines.Slots.SHOES, context)
|
||||
.InverseBoolCurve(context),
|
||||
considerationsManager.Get<CanPutTargetInHandsCon>()
|
||||
considerationsManager.Get<CanPutTargetInInventoryCon>()
|
||||
.BoolCurve(context),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ using Content.Server.AI.Utility.Considerations;
|
||||
using Content.Server.AI.Utility.Considerations.Clothing;
|
||||
using Content.Server.AI.Utility.Considerations.Containers;
|
||||
using Content.Server.AI.Utility.Considerations.Inventory;
|
||||
using Content.Server.AI.Utility.Considerations.Movement;
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
using Content.Shared.GameObjects.Components.Inventory;
|
||||
@@ -40,12 +41,10 @@ namespace Content.Server.AI.Utility.Actions.Clothing.Shoes
|
||||
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<ClothingInSlotCon>().Slot(EquipmentSlotDefines.Slots.SHOES, context)
|
||||
.InverseBoolCurve(context),
|
||||
considerationsManager.Get<CanPutTargetInHandsCon>()
|
||||
considerationsManager.Get<CanPutTargetInInventoryCon>()
|
||||
.BoolCurve(context),
|
||||
considerationsManager.Get<ClothingInInventoryCon>().Slot(EquipmentSlotDefines.SlotFlags.SHOES, context)
|
||||
.InverseBoolCurve(context),
|
||||
considerationsManager.Get<TargetDistanceCon>()
|
||||
.PresetCurve(context, PresetCurve.Distance),
|
||||
considerationsManager.Get<TargetAccessibleCon>()
|
||||
.BoolCurve(context),
|
||||
};
|
||||
|
||||
@@ -44,9 +44,7 @@ namespace Content.Server.AI.Utility.Actions.Combat.Melee
|
||||
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<MeleeWeaponEquippedCon>()
|
||||
.InverseBoolCurve(context),
|
||||
considerationsManager.Get<CanPutTargetInHandsCon>()
|
||||
considerationsManager.Get<CanPutTargetInInventoryCon>()
|
||||
.BoolCurve(context),
|
||||
considerationsManager.Get<MeleeWeaponSpeedCon>()
|
||||
.QuadraticCurve(context, 1.0f, 0.5f, 0.0f, 0.0f),
|
||||
|
||||
@@ -66,16 +66,14 @@ namespace Content.Server.AI.Utility.Actions.Combat.Melee
|
||||
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<MeleeWeaponEquippedCon>()
|
||||
.BoolCurve(context),
|
||||
considerationsManager.Get<TargetIsDeadCon>()
|
||||
.InverseBoolCurve(context),
|
||||
considerationsManager.Get<TargetIsCritCon>()
|
||||
.QuadraticCurve(context, -0.8f, 1.0f, 1.0f, 0.0f),
|
||||
considerationsManager.Get<DistanceCon>()
|
||||
.QuadraticCurve(context, 1.0f, 1.0f, 0.02f, 0.0f),
|
||||
considerationsManager.Get<TargetDistanceCon>()
|
||||
.PresetCurve(context, PresetCurve.Distance),
|
||||
considerationsManager.Get<TargetHealthCon>()
|
||||
.QuadraticCurve(context, 1.0f, 0.4f, 0.0f, -0.02f),
|
||||
.PresetCurve(context, PresetCurve.TargetHealth),
|
||||
considerationsManager.Get<MeleeWeaponSpeedCon>()
|
||||
.QuadraticCurve(context, 1.0f, 0.5f, 0.0f, 0.0f),
|
||||
considerationsManager.Get<MeleeWeaponDamageCon>()
|
||||
|
||||
@@ -42,12 +42,8 @@ namespace Content.Server.AI.Utility.Actions.Combat.Melee
|
||||
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<FreeHandCon>()
|
||||
.BoolCurve(context),
|
||||
considerationsManager.Get<HasMeleeWeaponCon>()
|
||||
.InverseBoolCurve(context),
|
||||
considerationsManager.Get<DistanceCon>()
|
||||
.QuadraticCurve(context, 1.0f, 1.0f, 0.02f, 0.0f),
|
||||
considerationsManager.Get<TargetDistanceCon>()
|
||||
.PresetCurve(context, PresetCurve.Distance),
|
||||
considerationsManager.Get<MeleeWeaponDamageCon>()
|
||||
.QuadraticCurve(context, 1.0f, 0.25f, 0.0f, 0.0f),
|
||||
considerationsManager.Get<MeleeWeaponSpeedCon>()
|
||||
|
||||
@@ -64,16 +64,14 @@ namespace Content.Server.AI.Utility.Actions.Combat.Melee
|
||||
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<CanUnarmedCombatCon>()
|
||||
.BoolCurve(context),
|
||||
considerationsManager.Get<TargetIsDeadCon>()
|
||||
.InverseBoolCurve(context),
|
||||
considerationsManager.Get<TargetIsCritCon>()
|
||||
.QuadraticCurve(context, -0.8f, 1.0f, 1.0f, 0.0f),
|
||||
considerationsManager.Get<DistanceCon>()
|
||||
.QuadraticCurve(context, -1.0f, 1.0f, 1.02f, 0.0f),
|
||||
considerationsManager.Get<TargetDistanceCon>()
|
||||
.PresetCurve(context, PresetCurve.Distance),
|
||||
considerationsManager.Get<TargetHealthCon>()
|
||||
.QuadraticCurve(context, 1.0f, 0.4f, 0.0f, -0.02f),
|
||||
.PresetCurve(context, PresetCurve.TargetHealth),
|
||||
considerationsManager.Get<TargetAccessibleCon>()
|
||||
.BoolCurve(context),
|
||||
// TODO: Consider our Speed and Damage to compare this to using a weapon
|
||||
@@ -81,4 +79,4 @@ namespace Content.Server.AI.Utility.Actions.Combat.Melee
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Content.Server.AI.Utility.Actions.Idle
|
||||
/// </summary>
|
||||
public sealed class CloseLastEntityStorage : UtilityAction
|
||||
{
|
||||
public override float Bonus => 1.5f;
|
||||
public override float Bonus => IdleBonus + 0.01f;
|
||||
|
||||
public CloseLastEntityStorage(IEntity owner) : base(owner) {}
|
||||
|
||||
@@ -50,12 +50,12 @@ namespace Content.Server.AI.Utility.Actions.Idle
|
||||
{
|
||||
considerationsManager.Get<StoredStateEntityIsNullCon>().Set(typeof(LastOpenedStorageState), context)
|
||||
.InverseBoolCurve(context),
|
||||
considerationsManager.Get<DistanceCon>()
|
||||
.QuadraticCurve(context, 1.0f, 1.0f, 0.02f, 0.0f),
|
||||
considerationsManager.Get<TargetAccessibleCon>()
|
||||
considerationsManager.Get<TargetDistanceCon>()
|
||||
.PresetCurve(context, PresetCurve.Distance),
|
||||
considerationsManager.Get<TargetAccessibleCon>()
|
||||
.BoolCurve(context),
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,9 +43,9 @@ namespace Content.Server.AI.Utility.Actions.Nutrition.Drink
|
||||
considerationsManager.Get<FreeHandCon>()
|
||||
.BoolCurve(context),
|
||||
considerationsManager.Get<ThirstCon>()
|
||||
.LogisticCurve(context, 1000f, 1.3f, -1.0f, 0.5f),
|
||||
considerationsManager.Get<DistanceCon>()
|
||||
.QuadraticCurve(context, 1.0f, 1.0f, 0.02f, 0.0f),
|
||||
.PresetCurve(context, PresetCurve.Nutrition),
|
||||
considerationsManager.Get<TargetDistanceCon>()
|
||||
.PresetCurve(context, PresetCurve.Distance),
|
||||
considerationsManager.Get<DrinkValueCon>()
|
||||
.QuadraticCurve(context, 1.0f, 0.4f, 0.0f, 0.0f),
|
||||
considerationsManager.Get<TargetAccessibleCon>()
|
||||
|
||||
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using Content.Server.AI.Operators;
|
||||
using Content.Server.AI.Operators.Inventory;
|
||||
using Content.Server.AI.Utility.Considerations;
|
||||
using Content.Server.AI.Utility.Considerations.Hands;
|
||||
using Content.Server.AI.Utility.Considerations.Inventory;
|
||||
using Content.Server.AI.Utility.Considerations.Nutrition.Drink;
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
@@ -43,10 +43,8 @@ namespace Content.Server.AI.Utility.Actions.Nutrition.Drink
|
||||
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<TargetInOurHandsCon>()
|
||||
considerationsManager.Get<TargetInOurInventoryCon>()
|
||||
.BoolCurve(context),
|
||||
considerationsManager.Get<ThirstCon>()
|
||||
.LogisticCurve(context, 1000f, 1.3f, -0.3f, 0.5f),
|
||||
considerationsManager.Get<DrinkValueCon>()
|
||||
.QuadraticCurve(context, 1.0f, 0.4f, 0.0f, 0.0f),
|
||||
};
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using Content.Server.AI.Operators.Sequences;
|
||||
using Content.Server.AI.Utility.Considerations;
|
||||
using Content.Server.AI.Utility.Considerations.Containers;
|
||||
using Content.Server.AI.Utility.Considerations.Hands;
|
||||
using Content.Server.AI.Utility.Considerations.Movement;
|
||||
using Content.Server.AI.Utility.Considerations.Nutrition.Food;
|
||||
using Content.Server.AI.WorldState;
|
||||
@@ -40,12 +39,8 @@ namespace Content.Server.AI.Utility.Actions.Nutrition.Food
|
||||
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<FreeHandCon>()
|
||||
.BoolCurve(context),
|
||||
considerationsManager.Get<HungerCon>()
|
||||
.LogisticCurve(context, 1000f, 1.3f, -1.0f, 0.5f),
|
||||
considerationsManager.Get<DistanceCon>()
|
||||
.QuadraticCurve(context, 1.0f, 1.0f, 0.02f, 0.0f),
|
||||
considerationsManager.Get<TargetDistanceCon>()
|
||||
.PresetCurve(context, PresetCurve.Distance),
|
||||
considerationsManager.Get<FoodValueCon>()
|
||||
.QuadraticCurve(context, 1.0f, 0.4f, 0.0f, 0.0f),
|
||||
considerationsManager.Get<TargetAccessibleCon>()
|
||||
|
||||
@@ -3,8 +3,7 @@ using System.Collections.Generic;
|
||||
using Content.Server.AI.Operators;
|
||||
using Content.Server.AI.Operators.Inventory;
|
||||
using Content.Server.AI.Utility.Considerations;
|
||||
using Content.Server.AI.Utility.Considerations.Containers;
|
||||
using Content.Server.AI.Utility.Considerations.Hands;
|
||||
using Content.Server.AI.Utility.Considerations.Inventory;
|
||||
using Content.Server.AI.Utility.Considerations.Nutrition.Food;
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
@@ -44,13 +43,10 @@ namespace Content.Server.AI.Utility.Actions.Nutrition.Food
|
||||
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<TargetInOurHandsCon>()
|
||||
considerationsManager.Get<TargetInOurInventoryCon>()
|
||||
.BoolCurve(context),
|
||||
considerationsManager.Get<HungerCon>()
|
||||
.LogisticCurve(context, 1000f, 1.3f, -0.3f, 0.5f),
|
||||
considerationsManager.Get<FoodValueCon>()
|
||||
.QuadraticCurve(context, 1.0f, 0.4f, 0.0f, 0.0f),
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,7 +106,6 @@ namespace Content.Server.AI.Utility.Actions
|
||||
/// This is where the magic happens
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="bonus"></param>
|
||||
/// <param name="min"></param>
|
||||
/// <returns></returns>
|
||||
public float GetScore(Blackboard context, float min)
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Content.Server.AI.Utility.BehaviorSets
|
||||
Actions = new IAiUtility[]
|
||||
{
|
||||
new PickUpNearbyDrinkExp(),
|
||||
new UseDrinkInHandsExp(),
|
||||
new UseDrinkInInventoryExp(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States.Utility;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Content.Server.AI.Utility.Considerations
|
||||
{
|
||||
@@ -18,50 +19,114 @@ namespace Content.Server.AI.Utility.Considerations
|
||||
return Math.Clamp(adjustedScore, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
[Pure]
|
||||
private static float BoolCurve(float x)
|
||||
{
|
||||
// ReSharper disable once CompareOfFloatsByEqualityOperator
|
||||
return x == 1.0f ? 1.0f : 0.0f;
|
||||
}
|
||||
|
||||
public Func<float> BoolCurve(Blackboard context)
|
||||
{
|
||||
float Result()
|
||||
{
|
||||
var adjustedScore = GetAdjustedScore(context);
|
||||
// ReSharper disable once CompareOfFloatsByEqualityOperator
|
||||
return adjustedScore == 1.0f ? 1.0f : 0.0f;
|
||||
return BoolCurve(adjustedScore);
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
[Pure]
|
||||
private static float InverseBoolCurve(float x)
|
||||
{
|
||||
// ReSharper disable once CompareOfFloatsByEqualityOperator
|
||||
return x == 1.0f ? 0.0f : 1.0f;
|
||||
}
|
||||
|
||||
public Func<float> InverseBoolCurve(Blackboard context)
|
||||
{
|
||||
float Result()
|
||||
{
|
||||
var adjustedScore = GetAdjustedScore(context);
|
||||
// ReSharper disable once CompareOfFloatsByEqualityOperator
|
||||
return adjustedScore == 1.0f ? 0.0f : 1.0f;
|
||||
return InverseBoolCurve(adjustedScore);
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
[Pure]
|
||||
private static float LogisticCurve(float x, float slope, float exponent, float yOffset, float xOffset)
|
||||
{
|
||||
return Math.Clamp(
|
||||
exponent * (1 / (1 + (float) Math.Pow(Math.Log(1000) * slope, -1 * x + xOffset))) + yOffset, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
public Func<float> LogisticCurve(Blackboard context, float slope, float exponent, float yOffset, float xOffset)
|
||||
{
|
||||
float Result()
|
||||
{
|
||||
var adjustedScore = GetAdjustedScore(context);
|
||||
return Math.Clamp(exponent * (1 / (1 + (float) Math.Pow(Math.Log(1000) * slope, -1 * adjustedScore + xOffset))) + yOffset, 0.0f, 1.0f);
|
||||
return LogisticCurve(adjustedScore, slope, exponent, yOffset, xOffset);
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
[Pure]
|
||||
private static float QuadraticCurve(float x, float slope, float exponent, float yOffset, float xOffset)
|
||||
{
|
||||
return Math.Clamp(slope * (float) Math.Pow(x - xOffset, exponent) + yOffset, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
public Func<float> QuadraticCurve(Blackboard context, float slope, float exponent, float yOffset, float xOffset)
|
||||
{
|
||||
float Result()
|
||||
{
|
||||
var adjustedScore = GetAdjustedScore(context);
|
||||
return Math.Clamp(slope * (float) Math.Pow(adjustedScore - xOffset, exponent) + yOffset, 0.0f, 1.0f);
|
||||
return QuadraticCurve(adjustedScore, slope, exponent, yOffset, xOffset);
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For any curves that are re-used across actions so you only need to update it once.
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="preset"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
||||
public Func<float> PresetCurve(Blackboard context, PresetCurve preset)
|
||||
{
|
||||
float Result()
|
||||
{
|
||||
var adjustedScore = GetAdjustedScore(context);
|
||||
|
||||
switch (preset)
|
||||
{
|
||||
case Considerations.PresetCurve.Distance:
|
||||
return QuadraticCurve(adjustedScore, -1.0f, 1.0f, 1.0f, 0.02f);
|
||||
case Considerations.PresetCurve.Nutrition:
|
||||
return QuadraticCurve(adjustedScore, 2.0f, 1.0f, -1.0f, -0.2f);
|
||||
case Considerations.PresetCurve.TargetHealth:
|
||||
return QuadraticCurve(adjustedScore, 1.0f, 0.4f, 0.0f, -0.02f);
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(preset), preset, null);
|
||||
}
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Preset response curves for considerations
|
||||
/// </summary>
|
||||
public enum PresetCurve
|
||||
{
|
||||
Distance,
|
||||
Nutrition,
|
||||
TargetHealth,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
using Content.Server.GameObjects.Components;
|
||||
using Content.Server.GameObjects.Components.GUI;
|
||||
|
||||
namespace Content.Server.AI.Utility.Considerations.Hands
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns 1 if in our hands else 0
|
||||
/// </summary>
|
||||
public sealed class TargetInOurHandsCon : Consideration
|
||||
{
|
||||
protected override float GetScore(Blackboard context)
|
||||
{
|
||||
var owner = context.GetState<SelfState>().GetValue();
|
||||
var target = context.GetState<TargetEntityState>().GetValue();
|
||||
|
||||
if (target == null ||
|
||||
!target.HasComponent<ItemComponent>() ||
|
||||
!owner.TryGetComponent(out HandsComponent handsComponent))
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
return handsComponent.IsHolding(target) ? 1.0f : 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ using Content.Server.GameObjects.Components;
|
||||
|
||||
namespace Content.Server.AI.Utility.Considerations.Inventory
|
||||
{
|
||||
public class CanPutTargetInHandsCon : Consideration
|
||||
public class CanPutTargetInInventoryCon : Consideration
|
||||
{
|
||||
protected override float GetScore(Blackboard context)
|
||||
{
|
||||
@@ -1,6 +1,7 @@
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
using Content.Server.AI.WorldState.States.Inventory;
|
||||
using Content.Server.GameObjects;
|
||||
using Content.Server.GameObjects.Components;
|
||||
|
||||
namespace Content.Server.AI.Utility.Considerations.Inventory
|
||||
|
||||
@@ -3,7 +3,7 @@ using Content.Server.AI.WorldState.States;
|
||||
|
||||
namespace Content.Server.AI.Utility.Considerations.Movement
|
||||
{
|
||||
public sealed class DistanceCon : Consideration
|
||||
public sealed class TargetDistanceCon : Consideration
|
||||
{
|
||||
protected override float GetScore(Blackboard context)
|
||||
{
|
||||
@@ -14,8 +14,8 @@ namespace Content.Server.AI.Utility.Considerations.Movement
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
// Kind of just pulled a max distance out of nowhere. Add 0.01 just in case it's reaally far and we have no choice so it'll still be considered at least.
|
||||
return (target.Transform.GridPosition.Position - self.Transform.GridPosition.Position).Length / 100 + 0.01f;
|
||||
// Anything further than 100 tiles gets clamped
|
||||
return (target.Transform.GridPosition.Position - self.Transform.GridPosition.Position).Length / 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,12 +2,14 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.AI.Utility.Actions;
|
||||
using Content.Server.AI.Utility.Actions.Clothing.Gloves;
|
||||
using Content.Server.AI.Utility.Considerations;
|
||||
using Content.Server.AI.Utility.Considerations.Clothing;
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
using Content.Server.AI.WorldState.States.Inventory;
|
||||
using Content.Server.GameObjects;
|
||||
using Content.Server.GameObjects.Components.Movement;
|
||||
using Content.Shared.GameObjects.Components.Inventory;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.Server.AI.Utility.ExpandableActions.Clothing.Gloves
|
||||
{
|
||||
@@ -18,6 +20,17 @@ namespace Content.Server.AI.Utility.ExpandableActions.Clothing.Gloves
|
||||
{
|
||||
public override float Bonus => UtilityAction.NormalBonus;
|
||||
|
||||
protected override IEnumerable<Func<float>> GetCommonConsiderations(Blackboard context)
|
||||
{
|
||||
var considerationsManager = IoCManager.Resolve<ConsiderationsManager>();
|
||||
|
||||
return new []
|
||||
{
|
||||
considerationsManager.Get<ClothingInSlotCon>().Slot(EquipmentSlotDefines.Slots.GLOVES, context)
|
||||
.InverseBoolCurve(context),
|
||||
};
|
||||
}
|
||||
|
||||
public override IEnumerable<UtilityAction> GetActions(Blackboard context)
|
||||
{
|
||||
var owner = context.GetState<SelfState>().GetValue();
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.AI.Utility.Actions;
|
||||
using Content.Server.AI.Utility.Actions.Clothing.Gloves;
|
||||
using Content.Server.AI.Utility.Considerations;
|
||||
using Content.Server.AI.Utility.Considerations.Clothing;
|
||||
using Content.Server.AI.Utility.Considerations.Inventory;
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
using Content.Server.AI.WorldState.States.Clothing;
|
||||
using Content.Server.GameObjects;
|
||||
using Content.Shared.GameObjects.Components.Inventory;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.Server.AI.Utility.ExpandableActions.Clothing.Gloves
|
||||
{
|
||||
@@ -13,9 +18,22 @@ namespace Content.Server.AI.Utility.ExpandableActions.Clothing.Gloves
|
||||
{
|
||||
public override float Bonus => UtilityAction.NormalBonus;
|
||||
|
||||
protected override IEnumerable<Func<float>> GetCommonConsiderations(Blackboard context)
|
||||
{
|
||||
var considerationsManager = IoCManager.Resolve<ConsiderationsManager>();
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<ClothingInSlotCon>().Slot(EquipmentSlotDefines.Slots.GLOVES, context)
|
||||
.InverseBoolCurve(context),
|
||||
considerationsManager.Get<ClothingInInventoryCon>().Slot(EquipmentSlotDefines.SlotFlags.GLOVES, context)
|
||||
.InverseBoolCurve(context),
|
||||
};
|
||||
}
|
||||
|
||||
public override IEnumerable<UtilityAction> GetActions(Blackboard context)
|
||||
{
|
||||
var owner = context.GetState<SelfState>().GetValue();
|
||||
|
||||
foreach (var entity in context.GetState<NearbyClothingState>().GetValue())
|
||||
{
|
||||
if (entity.TryGetComponent(out ClothingComponent clothing) &&
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.AI.Utility.Actions;
|
||||
using Content.Server.AI.Utility.Actions.Clothing.Head;
|
||||
using Content.Server.AI.Utility.Considerations;
|
||||
using Content.Server.AI.Utility.Considerations.Clothing;
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
using Content.Server.AI.WorldState.States.Inventory;
|
||||
using Content.Server.GameObjects;
|
||||
using Content.Shared.GameObjects.Components.Inventory;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.Server.AI.Utility.ExpandableActions.Clothing.Head
|
||||
{
|
||||
@@ -16,6 +20,16 @@ namespace Content.Server.AI.Utility.ExpandableActions.Clothing.Head
|
||||
{
|
||||
public override float Bonus => UtilityAction.NormalBonus;
|
||||
|
||||
protected override IEnumerable<Func<float>> GetCommonConsiderations(Blackboard context)
|
||||
{
|
||||
var considerationsManager = IoCManager.Resolve<ConsiderationsManager>();
|
||||
|
||||
return new[] {
|
||||
considerationsManager.Get<ClothingInSlotCon>().Slot(EquipmentSlotDefines.Slots.HEAD, context)
|
||||
.InverseBoolCurve(context),
|
||||
};
|
||||
}
|
||||
|
||||
public override IEnumerable<UtilityAction> GetActions(Blackboard context)
|
||||
{
|
||||
var owner = context.GetState<SelfState>().GetValue();
|
||||
|
||||
@@ -2,12 +2,15 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.AI.Utility.Actions;
|
||||
using Content.Server.AI.Utility.Actions.Clothing.Head;
|
||||
using Content.Server.AI.Utility.Considerations;
|
||||
using Content.Server.AI.Utility.Considerations.Clothing;
|
||||
using Content.Server.AI.Utility.Considerations.Inventory;
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
using Content.Server.AI.WorldState.States.Clothing;
|
||||
using Content.Server.GameObjects;
|
||||
using Content.Server.GameObjects.Components.Movement;
|
||||
using Content.Shared.GameObjects.Components.Inventory;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.Server.AI.Utility.ExpandableActions.Clothing.Head
|
||||
{
|
||||
@@ -15,6 +18,18 @@ namespace Content.Server.AI.Utility.ExpandableActions.Clothing.Head
|
||||
{
|
||||
public override float Bonus => UtilityAction.NormalBonus;
|
||||
|
||||
protected override IEnumerable<Func<float>> GetCommonConsiderations(Blackboard context)
|
||||
{
|
||||
var considerationsManager = IoCManager.Resolve<ConsiderationsManager>();
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<ClothingInSlotCon>().Slot(EquipmentSlotDefines.Slots.HEAD, context)
|
||||
.InverseBoolCurve(context),
|
||||
considerationsManager.Get<ClothingInInventoryCon>().Slot(EquipmentSlotDefines.SlotFlags.HEAD, context)
|
||||
.InverseBoolCurve(context)
|
||||
};
|
||||
}
|
||||
|
||||
public override IEnumerable<UtilityAction> GetActions(Blackboard context)
|
||||
{
|
||||
var owner = context.GetState<SelfState>().GetValue();
|
||||
|
||||
@@ -2,12 +2,14 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.AI.Utility.Actions;
|
||||
using Content.Server.AI.Utility.Actions.Clothing.OuterClothing;
|
||||
using Content.Server.AI.Utility.Considerations;
|
||||
using Content.Server.AI.Utility.Considerations.Clothing;
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
using Content.Server.AI.WorldState.States.Inventory;
|
||||
using Content.Server.GameObjects;
|
||||
using Content.Server.GameObjects.Components.Movement;
|
||||
using Content.Shared.GameObjects.Components.Inventory;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.Server.AI.Utility.ExpandableActions.Clothing.OuterClothing
|
||||
{
|
||||
@@ -18,6 +20,17 @@ namespace Content.Server.AI.Utility.ExpandableActions.Clothing.OuterClothing
|
||||
{
|
||||
public override float Bonus => UtilityAction.NormalBonus;
|
||||
|
||||
protected override IEnumerable<Func<float>> GetCommonConsiderations(Blackboard context)
|
||||
{
|
||||
var considerationsManager = IoCManager.Resolve<ConsiderationsManager>();
|
||||
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<ClothingInSlotCon>().Slot(EquipmentSlotDefines.Slots.OUTERCLOTHING, context)
|
||||
.InverseBoolCurve(context),
|
||||
};
|
||||
}
|
||||
|
||||
public override IEnumerable<UtilityAction> GetActions(Blackboard context)
|
||||
{
|
||||
var owner = context.GetState<SelfState>().GetValue();
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.AI.Utility.Actions;
|
||||
using Content.Server.AI.Utility.Actions.Clothing.OuterClothing;
|
||||
using Content.Server.AI.Utility.Considerations;
|
||||
using Content.Server.AI.Utility.Considerations.Clothing;
|
||||
using Content.Server.AI.Utility.Considerations.Inventory;
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
using Content.Server.AI.WorldState.States.Clothing;
|
||||
using Content.Server.GameObjects;
|
||||
using Content.Shared.GameObjects.Components.Inventory;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.Server.AI.Utility.ExpandableActions.Clothing.OuterClothing
|
||||
{
|
||||
@@ -13,6 +18,19 @@ namespace Content.Server.AI.Utility.ExpandableActions.Clothing.OuterClothing
|
||||
{
|
||||
public override float Bonus => UtilityAction.NormalBonus;
|
||||
|
||||
protected override IEnumerable<Func<float>> GetCommonConsiderations(Blackboard context)
|
||||
{
|
||||
var considerationsManager = IoCManager.Resolve<ConsiderationsManager>();
|
||||
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<ClothingInSlotCon>().Slot(EquipmentSlotDefines.Slots.OUTERCLOTHING, context)
|
||||
.InverseBoolCurve(context),
|
||||
considerationsManager.Get<ClothingInInventoryCon>().Slot(EquipmentSlotDefines.SlotFlags.OUTERCLOTHING, context)
|
||||
.InverseBoolCurve(context)
|
||||
};
|
||||
}
|
||||
|
||||
public override IEnumerable<UtilityAction> GetActions(Blackboard context)
|
||||
{
|
||||
var owner = context.GetState<SelfState>().GetValue();
|
||||
|
||||
@@ -2,12 +2,14 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.AI.Utility.Actions;
|
||||
using Content.Server.AI.Utility.Actions.Clothing.Shoes;
|
||||
using Content.Server.AI.Utility.Considerations;
|
||||
using Content.Server.AI.Utility.Considerations.Clothing;
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
using Content.Server.AI.WorldState.States.Inventory;
|
||||
using Content.Server.GameObjects;
|
||||
using Content.Server.GameObjects.Components.Movement;
|
||||
using Content.Shared.GameObjects.Components.Inventory;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.Server.AI.Utility.ExpandableActions.Clothing.Shoes
|
||||
{
|
||||
@@ -18,6 +20,17 @@ namespace Content.Server.AI.Utility.ExpandableActions.Clothing.Shoes
|
||||
{
|
||||
public override float Bonus => UtilityAction.NormalBonus;
|
||||
|
||||
protected override IEnumerable<Func<float>> GetCommonConsiderations(Blackboard context)
|
||||
{
|
||||
var considerationsManager = IoCManager.Resolve<ConsiderationsManager>();
|
||||
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<ClothingInSlotCon>().Slot(EquipmentSlotDefines.Slots.SHOES, context)
|
||||
.InverseBoolCurve(context),
|
||||
};
|
||||
}
|
||||
|
||||
public override IEnumerable<UtilityAction> GetActions(Blackboard context)
|
||||
{
|
||||
var owner = context.GetState<SelfState>().GetValue();
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.AI.Utility.Actions;
|
||||
using Content.Server.AI.Utility.Actions.Clothing.Shoes;
|
||||
using Content.Server.AI.Utility.Considerations;
|
||||
using Content.Server.AI.Utility.Considerations.Clothing;
|
||||
using Content.Server.AI.Utility.Considerations.Inventory;
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
using Content.Server.AI.WorldState.States.Clothing;
|
||||
using Content.Server.GameObjects;
|
||||
using Content.Shared.GameObjects.Components.Inventory;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.Server.AI.Utility.ExpandableActions.Clothing.Shoes
|
||||
{
|
||||
@@ -13,6 +18,19 @@ namespace Content.Server.AI.Utility.ExpandableActions.Clothing.Shoes
|
||||
{
|
||||
public override float Bonus => UtilityAction.NormalBonus;
|
||||
|
||||
protected override IEnumerable<Func<float>> GetCommonConsiderations(Blackboard context)
|
||||
{
|
||||
var considerationsManager = IoCManager.Resolve<ConsiderationsManager>();
|
||||
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<ClothingInSlotCon>().Slot(EquipmentSlotDefines.Slots.SHOES, context)
|
||||
.InverseBoolCurve(context),
|
||||
considerationsManager.Get<ClothingInInventoryCon>().Slot(EquipmentSlotDefines.SlotFlags.SHOES, context)
|
||||
.InverseBoolCurve(context)
|
||||
};
|
||||
}
|
||||
|
||||
public override IEnumerable<UtilityAction> GetActions(Blackboard context)
|
||||
{
|
||||
var owner = context.GetState<SelfState>().GetValue();
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.AI.Utility.Actions;
|
||||
using Content.Server.AI.Utility.Actions.Combat.Melee;
|
||||
using Content.Server.AI.Utility.Considerations;
|
||||
using Content.Server.AI.Utility.Considerations.Combat.Melee;
|
||||
using Content.Server.AI.Utility.Considerations.Inventory;
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
using Content.Server.AI.WorldState.States.Inventory;
|
||||
using Content.Server.GameObjects.Components.Weapon.Melee;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.Server.AI.Utility.ExpandableActions.Combat.Melee
|
||||
{
|
||||
@@ -12,6 +17,17 @@ namespace Content.Server.AI.Utility.ExpandableActions.Combat.Melee
|
||||
{
|
||||
public override float Bonus => UtilityAction.CombatPrepBonus;
|
||||
|
||||
protected override IEnumerable<Func<float>> GetCommonConsiderations(Blackboard context)
|
||||
{
|
||||
var considerationsManager = IoCManager.Resolve<ConsiderationsManager>();
|
||||
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<MeleeWeaponEquippedCon>()
|
||||
.InverseBoolCurve(context),
|
||||
};
|
||||
}
|
||||
|
||||
public override IEnumerable<UtilityAction> GetActions(Blackboard context)
|
||||
{
|
||||
var owner = context.GetState<SelfState>().GetValue();
|
||||
|
||||
@@ -2,12 +2,15 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.AI.Utility.Actions;
|
||||
using Content.Server.AI.Utility.Actions.Combat.Melee;
|
||||
using Content.Server.AI.Utility.Considerations;
|
||||
using Content.Server.AI.Utility.Considerations.Combat.Melee;
|
||||
using Content.Server.AI.Utils;
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
using Content.Server.GameObjects;
|
||||
using Content.Server.GameObjects.Components.Movement;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.Server.AI.Utility.ExpandableActions.Combat.Melee
|
||||
{
|
||||
@@ -15,6 +18,17 @@ namespace Content.Server.AI.Utility.ExpandableActions.Combat.Melee
|
||||
{
|
||||
public override float Bonus => UtilityAction.CombatBonus;
|
||||
|
||||
protected override IEnumerable<Func<float>> GetCommonConsiderations(Blackboard context)
|
||||
{
|
||||
var considerationsManager = IoCManager.Resolve<ConsiderationsManager>();
|
||||
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<MeleeWeaponEquippedCon>()
|
||||
.BoolCurve(context),
|
||||
};
|
||||
}
|
||||
|
||||
public override IEnumerable<UtilityAction> GetActions(Blackboard context)
|
||||
{
|
||||
var owner = context.GetState<SelfState>().GetValue();
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.AI.Utility.Actions;
|
||||
using Content.Server.AI.Utility.Actions.Combat.Melee;
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
using Content.Server.AI.WorldState.States.Mobs;
|
||||
using Content.Server.GameObjects.Components.Movement;
|
||||
|
||||
namespace Content.Server.AI.Utility.ExpandableActions.Combat.Melee
|
||||
{
|
||||
@@ -14,6 +16,7 @@ namespace Content.Server.AI.Utility.ExpandableActions.Combat.Melee
|
||||
public override IEnumerable<UtilityAction> GetActions(Blackboard context)
|
||||
{
|
||||
var owner = context.GetState<SelfState>().GetValue();
|
||||
|
||||
foreach (var entity in context.GetState<NearbySpeciesState>().GetValue())
|
||||
{
|
||||
yield return new MeleeWeaponAttackEntity(owner, entity, Bonus);
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.AI.Utility.Actions;
|
||||
using Content.Server.AI.Utility.Actions.Combat.Melee;
|
||||
using Content.Server.AI.Utility.Considerations;
|
||||
using Content.Server.AI.Utility.Considerations.Combat.Melee;
|
||||
using Content.Server.AI.Utility.Considerations.Hands;
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
using Content.Server.AI.WorldState.States.Combat.Nearby;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.Server.AI.Utility.ExpandableActions.Combat.Melee
|
||||
{
|
||||
@@ -11,6 +16,19 @@ namespace Content.Server.AI.Utility.ExpandableActions.Combat.Melee
|
||||
{
|
||||
public override float Bonus => UtilityAction.CombatPrepBonus;
|
||||
|
||||
protected override IEnumerable<Func<float>> GetCommonConsiderations(Blackboard context)
|
||||
{
|
||||
var considerationsManager = IoCManager.Resolve<ConsiderationsManager>();
|
||||
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<FreeHandCon>()
|
||||
.BoolCurve(context),
|
||||
considerationsManager.Get<HasMeleeWeaponCon>()
|
||||
.InverseBoolCurve(context),
|
||||
};
|
||||
}
|
||||
|
||||
public override IEnumerable<UtilityAction> GetActions(Blackboard context)
|
||||
{
|
||||
var owner = context.GetState<SelfState>().GetValue();
|
||||
|
||||
@@ -2,12 +2,15 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.AI.Utility.Actions;
|
||||
using Content.Server.AI.Utility.Actions.Combat.Melee;
|
||||
using Content.Server.AI.Utility.Considerations;
|
||||
using Content.Server.AI.Utility.Considerations.Combat.Melee;
|
||||
using Content.Server.AI.Utils;
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
using Content.Server.GameObjects;
|
||||
using Content.Server.GameObjects.Components.Movement;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.Server.AI.Utility.ExpandableActions.Combat.Melee
|
||||
{
|
||||
@@ -15,6 +18,17 @@ namespace Content.Server.AI.Utility.ExpandableActions.Combat.Melee
|
||||
{
|
||||
public override float Bonus => UtilityAction.CombatBonus;
|
||||
|
||||
protected override IEnumerable<Func<float>> GetCommonConsiderations(Blackboard context)
|
||||
{
|
||||
var considerationsManager = IoCManager.Resolve<ConsiderationsManager>();
|
||||
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<CanUnarmedCombatCon>()
|
||||
.BoolCurve(context),
|
||||
};
|
||||
}
|
||||
|
||||
public override IEnumerable<UtilityAction> GetActions(Blackboard context)
|
||||
{
|
||||
var owner = context.GetState<SelfState>().GetValue();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.AI.Utility.Actions;
|
||||
using Content.Server.AI.WorldState;
|
||||
@@ -12,6 +13,37 @@ namespace Content.Server.AI.Utility.ExpandableActions
|
||||
{
|
||||
public abstract float Bonus { get; }
|
||||
|
||||
/// <summary>
|
||||
/// No point expanding nodes if none of them can ever be valid.
|
||||
/// Fails if any of the common considerations is 0.0f (i.e. invalid)
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <returns></returns>
|
||||
public bool IsValid(Blackboard context)
|
||||
{
|
||||
foreach (var con in GetCommonConsiderations(context))
|
||||
{
|
||||
// ReSharper disable once CompareOfFloatsByEqualityOperator
|
||||
if (con.Invoke() == 0.0f) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called by IsValid to try and early-out the expandable action.
|
||||
/// No point going through all nearby clothes if we can't fit it in a slot.
|
||||
/// </summary>
|
||||
/// Similar to HTN's compound tasks where they can have overall conditions that have to be met before the actions are considered.
|
||||
/// Ideally any binary early-outs that are common to all expanded actions would be checked once, e.g. a boolean free hand check
|
||||
/// Use this if you want to optimise the expandable further.
|
||||
/// <param name="context"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual IEnumerable<Func<float>> GetCommonConsiderations(Blackboard context)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
// e.g. you may have a "PickupFood" action for all nearby food sources if you have the "Hungry" BehaviorSet.
|
||||
public abstract IEnumerable<UtilityAction> GetActions(Blackboard context);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.AI.Utility.Actions;
|
||||
using Content.Server.AI.Utility.Actions.Nutrition.Drink;
|
||||
using Content.Server.AI.Utility.Considerations;
|
||||
using Content.Server.AI.Utility.Considerations.Hands;
|
||||
using Content.Server.AI.Utility.Considerations.Nutrition.Drink;
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
using Content.Server.AI.WorldState.States.Nutrition;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.Server.AI.Utility.ExpandableActions.Nutrition
|
||||
{
|
||||
@@ -11,6 +16,16 @@ namespace Content.Server.AI.Utility.ExpandableActions.Nutrition
|
||||
{
|
||||
public override float Bonus => UtilityAction.NeedsBonus;
|
||||
|
||||
protected override IEnumerable<Func<float>> GetCommonConsiderations(Blackboard context)
|
||||
{
|
||||
var considerationsManager = IoCManager.Resolve<ConsiderationsManager>();
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<ThirstCon>().PresetCurve(context, PresetCurve.Nutrition),
|
||||
considerationsManager.Get<FreeHandCon>().BoolCurve(context),
|
||||
};
|
||||
}
|
||||
|
||||
public override IEnumerable<UtilityAction> GetActions(Blackboard context)
|
||||
{
|
||||
var owner = context.GetState<SelfState>().GetValue();
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.AI.Utility.Actions;
|
||||
using Content.Server.AI.Utility.Actions.Nutrition.Food;
|
||||
using Content.Server.AI.Utility.Considerations;
|
||||
using Content.Server.AI.Utility.Considerations.Hands;
|
||||
using Content.Server.AI.Utility.Considerations.Nutrition.Food;
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
using Content.Server.AI.WorldState.States.Nutrition;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.Server.AI.Utility.ExpandableActions.Nutrition
|
||||
{
|
||||
@@ -11,6 +16,16 @@ namespace Content.Server.AI.Utility.ExpandableActions.Nutrition
|
||||
{
|
||||
public override float Bonus => UtilityAction.NeedsBonus;
|
||||
|
||||
protected override IEnumerable<Func<float>> GetCommonConsiderations(Blackboard context)
|
||||
{
|
||||
var considerationsManager = IoCManager.Resolve<ConsiderationsManager>();
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<HungerCon>().PresetCurve(context, PresetCurve.Nutrition),
|
||||
considerationsManager.Get<FreeHandCon>().BoolCurve(context),
|
||||
};
|
||||
}
|
||||
|
||||
public override IEnumerable<UtilityAction> GetActions(Blackboard context)
|
||||
{
|
||||
var owner = context.GetState<SelfState>().GetValue();
|
||||
|
||||
@@ -1,16 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.AI.Utility.Actions;
|
||||
using Content.Server.AI.Utility.Actions.Nutrition.Drink;
|
||||
using Content.Server.AI.Utility.Considerations;
|
||||
using Content.Server.AI.Utility.Considerations.Nutrition.Drink;
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
using Content.Server.AI.WorldState.States.Inventory;
|
||||
using Content.Server.GameObjects.Components.Nutrition;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.Server.AI.Utility.ExpandableActions.Nutrition
|
||||
{
|
||||
public sealed class UseDrinkInHandsExp : ExpandableUtilityAction
|
||||
public sealed class UseDrinkInInventoryExp : ExpandableUtilityAction
|
||||
{
|
||||
public override float Bonus => UtilityAction.NeedsBonus;
|
||||
|
||||
protected override IEnumerable<Func<float>> GetCommonConsiderations(Blackboard context)
|
||||
{
|
||||
var considerationsManager = IoCManager.Resolve<ConsiderationsManager>();
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<ThirstCon>().PresetCurve(context, PresetCurve.Nutrition)
|
||||
};
|
||||
}
|
||||
|
||||
public override IEnumerable<UtilityAction> GetActions(Blackboard context)
|
||||
{
|
||||
@@ -1,10 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.AI.Utility.Actions;
|
||||
using Content.Server.AI.Utility.Actions.Nutrition.Food;
|
||||
using Content.Server.AI.Utility.Considerations;
|
||||
using Content.Server.AI.Utility.Considerations.Nutrition.Food;
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
using Content.Server.AI.WorldState.States.Inventory;
|
||||
using Content.Server.GameObjects.Components.Nutrition;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.Server.AI.Utility.ExpandableActions.Nutrition
|
||||
{
|
||||
@@ -12,6 +16,15 @@ namespace Content.Server.AI.Utility.ExpandableActions.Nutrition
|
||||
{
|
||||
public override float Bonus => UtilityAction.NeedsBonus;
|
||||
|
||||
protected override IEnumerable<Func<float>> GetCommonConsiderations(Blackboard context)
|
||||
{
|
||||
var considerationsManager = IoCManager.Resolve<ConsiderationsManager>();
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<HungerCon>().PresetCurve(context, PresetCurve.Nutrition)
|
||||
};
|
||||
}
|
||||
|
||||
public override IEnumerable<UtilityAction> GetActions(Blackboard context)
|
||||
{
|
||||
var owner = context.GetState<SelfState>().GetValue();
|
||||
|
||||
25
Content.Server/Atmos/AtmosHelpers.cs
Normal file
25
Content.Server/Atmos/AtmosHelpers.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Robust.Shared.GameObjects.Systems;
|
||||
using Robust.Shared.Map;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Content.Server.Atmos
|
||||
{
|
||||
public static class AtmosHelpers
|
||||
{
|
||||
public static TileAtmosphere? GetTileAtmosphere(this GridCoordinates coordinates)
|
||||
{
|
||||
var gridAtmos = EntitySystem.Get<AtmosphereSystem>().GetGridAtmosphere(coordinates.GridID);
|
||||
|
||||
return gridAtmos?.GetTile(coordinates);
|
||||
}
|
||||
|
||||
public static TileAtmosphere? GetTileAtmosphere(this MapIndices indices, GridId gridId)
|
||||
{
|
||||
var gridAtmos = EntitySystem.Get<AtmosphereSystem>().GetGridAtmosphere(gridId);
|
||||
|
||||
return gridAtmos?.GetTile(indices);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,17 @@
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Access
|
||||
{
|
||||
public sealed class AccessReaderChangeMessage : EntitySystemMessage
|
||||
{
|
||||
public EntityUid Uid { get; }
|
||||
public IEntity Sender { get; }
|
||||
|
||||
public bool Enabled { get; }
|
||||
|
||||
public AccessReaderChangeMessage(EntityUid uid, bool enabled)
|
||||
public AccessReaderChangeMessage(IEntity entity, bool enabled)
|
||||
{
|
||||
Uid = uid;
|
||||
Sender = entity;
|
||||
Enabled = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,6 +356,10 @@ namespace Content.Server.GameObjects.Components.Disposal
|
||||
appearance.SetData(Visuals.Light, LightState.Off);
|
||||
return;
|
||||
}
|
||||
else if (_pressure < 1)
|
||||
{
|
||||
appearance.SetData(Visuals.VisualState, VisualState.Charging);
|
||||
}
|
||||
else
|
||||
{
|
||||
appearance.SetData(Visuals.VisualState, VisualState.Anchored);
|
||||
|
||||
@@ -188,7 +188,7 @@ namespace Content.Server.GameObjects
|
||||
SetAppearance(DoorVisualState.Open);
|
||||
}, _cancellationTokenSource.Token);
|
||||
|
||||
Owner.EntityManager.EventBus.RaiseEvent(EventSource.Local, new AccessReaderChangeMessage(Owner.Uid, false));
|
||||
Owner.EntityManager.EventBus.RaiseEvent(EventSource.Local, new AccessReaderChangeMessage(Owner, false));
|
||||
}
|
||||
|
||||
public virtual bool CanClose()
|
||||
@@ -284,7 +284,7 @@ namespace Content.Server.GameObjects
|
||||
State = DoorState.Closed;
|
||||
SetAppearance(DoorVisualState.Closed);
|
||||
}, _cancellationTokenSource.Token);
|
||||
Owner.EntityManager.EventBus.RaiseEvent(EventSource.Local, new AccessReaderChangeMessage(Owner.Uid, true));
|
||||
Owner.EntityManager.EventBus.RaiseEvent(EventSource.Local, new AccessReaderChangeMessage(Owner, true));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using Content.Server.Atmos;
|
||||
using Content.Server.GameObjects.Components.Chemistry;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.GameObjects.EntitySystems.Click;
|
||||
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
||||
using Content.Server.Interfaces;
|
||||
@@ -19,6 +21,7 @@ using Robust.Shared.Utility;
|
||||
using Robust.Shared.ViewVariables;
|
||||
using Robust.Shared.Serialization;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Robust.Shared.GameObjects.Systems;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Interactable
|
||||
{
|
||||
@@ -179,6 +182,10 @@ namespace Content.Server.GameObjects.Components.Interactable
|
||||
|
||||
PlaySoundCollection("WelderOn", -5);
|
||||
_welderSystem.Subscribe(this);
|
||||
|
||||
Owner.Transform.GridPosition
|
||||
.GetTileAtmosphere()?.HotspotExpose(700f, 50f, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,9 +50,6 @@ namespace Content.Server.GameObjects.Components.Items
|
||||
var desiredTile = _tileDefinitionManager[_outputTile];
|
||||
mapGrid.SetTile(eventArgs.ClickLocation, new Tile(desiredTile.TileId));
|
||||
EntitySystem.Get<AudioSystem>().PlayAtCoords("/Audio/Items/genhit.ogg", eventArgs.ClickLocation);
|
||||
if(_stack.Count < 1){
|
||||
Owner.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -28,15 +28,7 @@ namespace Content.Server.GameObjects.Components.Stack
|
||||
public override int Count
|
||||
{
|
||||
get => base.Count;
|
||||
set
|
||||
{
|
||||
base.Count = value;
|
||||
|
||||
if (Count <= 0)
|
||||
{
|
||||
Owner.Delete();
|
||||
}
|
||||
}
|
||||
set => base.Count = value;
|
||||
}
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
|
||||
@@ -159,10 +159,10 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
|
||||
public override void OnAdd()
|
||||
{
|
||||
base.OnAdd();
|
||||
var rangedWeapon = Owner.GetComponent<ServerRangedWeaponComponent>();
|
||||
rangedWeapon.Barrel = this;
|
||||
rangedWeapon.FireHandler += Fire;
|
||||
rangedWeapon.WeaponCanFireHandler += WeaponCanFire;
|
||||
var rangedWeaponComponent = Owner.GetComponent<ServerRangedWeaponComponent>();
|
||||
rangedWeaponComponent.Barrel = this;
|
||||
rangedWeaponComponent.FireHandler += Fire;
|
||||
rangedWeaponComponent.WeaponCanFireHandler += WeaponCanFire;
|
||||
}
|
||||
|
||||
public override void OnRemove()
|
||||
@@ -208,7 +208,12 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
|
||||
return true;
|
||||
}
|
||||
|
||||
private void Fire(IEntity shooter, GridCoordinates target)
|
||||
/// <summary>
|
||||
/// Fires a round of ammo out of the weapon.
|
||||
/// </summary>
|
||||
/// <param name="shooter">Entity that is operating the weapon, usually the player.</param>
|
||||
/// <param name="targetPos">Target position on the map to shoot at.</param>
|
||||
private void Fire(IEntity shooter, Vector2 targetPos)
|
||||
{
|
||||
var soundSystem = EntitySystem.Get<AudioSystem>();
|
||||
if (ShotsLeft == 0)
|
||||
@@ -229,8 +234,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
|
||||
}
|
||||
|
||||
// At this point firing is confirmed
|
||||
var worldPosition = IoCManager.Resolve<IMapManager>().GetGrid(target.GridID).LocalToWorld(target).Position;
|
||||
var direction = (worldPosition - shooter.Transform.WorldPosition).ToAngle();
|
||||
var direction = (targetPos - shooter.Transform.WorldPosition).ToAngle();
|
||||
var angle = GetRecoilAngle(direction);
|
||||
// This should really be client-side but for now we'll just leave it here
|
||||
if (shooter.TryGetComponent(out CameraRecoilComponent recoilComponent))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using Content.Server.GameObjects.Components.GUI;
|
||||
using Content.Server.GameObjects.Components.Mobs;
|
||||
using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels;
|
||||
@@ -12,6 +12,7 @@ using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Systems;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Interfaces.Map;
|
||||
using Robust.Shared.Interfaces.Network;
|
||||
using Robust.Shared.Interfaces.Random;
|
||||
using Robust.Shared.Interfaces.Timing;
|
||||
@@ -19,6 +20,7 @@ using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Players;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Serialization;
|
||||
@@ -38,7 +40,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged
|
||||
|
||||
public Func<bool> WeaponCanFireHandler;
|
||||
public Func<IEntity, bool> UserCanFireHandler;
|
||||
public Action<IEntity, GridCoordinates> FireHandler;
|
||||
public Action<IEntity, Vector2> FireHandler;
|
||||
|
||||
public ServerRangedBarrelComponent Barrel
|
||||
{
|
||||
@@ -77,6 +79,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged
|
||||
serializer.DataField(this, p => p.ClumsyExplodeChance, "clumsyExplodeChance", 0.5f);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void HandleNetworkMessage(ComponentMessage message, INetChannel channel, ICommonSession session = null)
|
||||
{
|
||||
base.HandleNetworkMessage(message, channel, session);
|
||||
@@ -95,7 +98,24 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged
|
||||
return;
|
||||
}
|
||||
|
||||
_tryFire(user, msg.Target);
|
||||
if (msg.TargetGrid != GridId.Invalid)
|
||||
{
|
||||
// grid pos
|
||||
if (!IoCManager.Resolve<IMapManager>().TryGetGrid(msg.TargetGrid, out var grid))
|
||||
{
|
||||
// Client sent us a message with an invalid grid.
|
||||
break;
|
||||
}
|
||||
|
||||
var targetPos = grid.LocalToWorld(msg.TargetPosition);
|
||||
TryFire(user, targetPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
// map pos
|
||||
TryFire(user, msg.TargetPosition);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -105,7 +125,12 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged
|
||||
return new RangedWeaponComponentState(FireRateSelector);
|
||||
}
|
||||
|
||||
private void _tryFire(IEntity user, GridCoordinates coordinates)
|
||||
/// <summary>
|
||||
/// Tries to fire a round of ammo out of the weapon.
|
||||
/// </summary>
|
||||
/// <param name="user">Entity that is operating the weapon, usually the player.</param>
|
||||
/// <param name="targetPos">Target position on the map to shoot at.</param>
|
||||
private void TryFire(IEntity user, Vector2 targetPos)
|
||||
{
|
||||
if (!user.TryGetComponent(out HandsComponent hands) || hands.GetActiveHand?.Owner != Owner)
|
||||
{
|
||||
@@ -158,7 +183,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged
|
||||
return;
|
||||
}
|
||||
|
||||
FireHandler?.Invoke(user, coordinates);
|
||||
FireHandler?.Invoke(user, targetPos);
|
||||
}
|
||||
|
||||
// Probably a better way to do this.
|
||||
|
||||
@@ -79,6 +79,11 @@ namespace Content.Server.GameObjects.EntitySystems.AI.LoadBalancer
|
||||
switch (action)
|
||||
{
|
||||
case ExpandableUtilityAction expandableUtilityAction:
|
||||
if (!expandableUtilityAction.IsValid(_request.Context))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
foreach (var expanded in expandableUtilityAction.GetActions(_request.Context))
|
||||
{
|
||||
actions.Push(expanded);
|
||||
@@ -86,7 +91,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.LoadBalancer
|
||||
break;
|
||||
case UtilityAction utilityAction:
|
||||
consideredTaskCount++;
|
||||
var bonus = (float) utilityAction.Bonus;
|
||||
var bonus = utilityAction.Bonus;
|
||||
|
||||
if (bonus < cutoff)
|
||||
{
|
||||
|
||||
@@ -25,17 +25,17 @@ namespace Content.Server.GameObjects.EntitySystems.Pathfinding
|
||||
/// Whenever there's a change in the collision layers we update the mask as the graph has more reads than writes
|
||||
/// </summary>
|
||||
public int BlockedCollisionMask { get; private set; }
|
||||
private readonly Dictionary<EntityUid, int> _blockedCollidables = new Dictionary<EntityUid, int>(0);
|
||||
private readonly Dictionary<IEntity, int> _blockedCollidables = new Dictionary<IEntity, int>(0);
|
||||
|
||||
public IReadOnlyDictionary<EntityUid, int> PhysicsLayers => _physicsLayers;
|
||||
private readonly Dictionary<EntityUid, int> _physicsLayers = new Dictionary<EntityUid, int>(0);
|
||||
public IReadOnlyDictionary<IEntity, int> PhysicsLayers => _physicsLayers;
|
||||
private readonly Dictionary<IEntity, int> _physicsLayers = new Dictionary<IEntity, int>(0);
|
||||
|
||||
/// <summary>
|
||||
/// The entities on this tile that require access to traverse
|
||||
/// </summary>
|
||||
/// We don't store the ICollection, at least for now, as we'd need to replicate the access code here
|
||||
public IReadOnlyCollection<AccessReader> AccessReaders => _accessReaders.Values;
|
||||
private readonly Dictionary<EntityUid, AccessReader> _accessReaders = new Dictionary<EntityUid, AccessReader>(0);
|
||||
private readonly Dictionary<IEntity, AccessReader> _accessReaders = new Dictionary<IEntity, AccessReader>(0);
|
||||
|
||||
public PathfindingNode(PathfindingChunk parent, TileRef tileRef)
|
||||
{
|
||||
@@ -44,6 +44,17 @@ namespace Content.Server.GameObjects.EntitySystems.Pathfinding
|
||||
GenerateMask();
|
||||
}
|
||||
|
||||
public static bool IsRelevant(IEntity entity, ICollidableComponent collidableComponent)
|
||||
{
|
||||
if (entity.Transform.GridID == GridId.Invalid ||
|
||||
(PathfindingSystem.TrackedCollisionLayers & collidableComponent.CollisionLayer) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return our neighboring nodes (even across chunks)
|
||||
/// </summary>
|
||||
@@ -249,7 +260,7 @@ namespace Content.Server.GameObjects.EntitySystems.Pathfinding
|
||||
/// <param name="entity"></param>
|
||||
/// TODO: These 2 methods currently don't account for a bunch of changes (e.g. airlock unpowered, wrenching, etc.)
|
||||
/// TODO: Could probably optimise this slightly more.
|
||||
public void AddEntity(IEntity entity)
|
||||
public void AddEntity(IEntity entity, ICollidableComponent collidableComponent)
|
||||
{
|
||||
// If we're a door
|
||||
if (entity.HasComponent<AirlockComponent>() || entity.HasComponent<ServerDoorComponent>())
|
||||
@@ -258,27 +269,25 @@ namespace Content.Server.GameObjects.EntitySystems.Pathfinding
|
||||
// TODO: Check for powered I think (also need an event for when it's depowered
|
||||
// AccessReader calls this whenever opening / closing but it can seem to get called multiple times
|
||||
// Which may or may not be intended?
|
||||
if (entity.TryGetComponent(out AccessReader accessReader) && !_accessReaders.ContainsKey(entity.Uid))
|
||||
if (entity.TryGetComponent(out AccessReader accessReader) && !_accessReaders.ContainsKey(entity))
|
||||
{
|
||||
_accessReaders.Add(entity.Uid, accessReader);
|
||||
_accessReaders.Add(entity, accessReader);
|
||||
ParentChunk.Dirty();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (entity.TryGetComponent(out ICollidableComponent collidableComponent) &&
|
||||
(PathfindingSystem.TrackedCollisionLayers & collidableComponent.CollisionLayer) != 0)
|
||||
DebugTools.Assert((PathfindingSystem.TrackedCollisionLayers & collidableComponent.CollisionLayer) != 0);
|
||||
|
||||
if (!collidableComponent.Anchored)
|
||||
{
|
||||
if (entity.TryGetComponent(out IPhysicsComponent physicsComponent) && !physicsComponent.Anchored)
|
||||
{
|
||||
_physicsLayers.Add(entity.Uid, collidableComponent.CollisionLayer);
|
||||
}
|
||||
else
|
||||
{
|
||||
_blockedCollidables.TryAdd(entity.Uid, collidableComponent.CollisionLayer);
|
||||
GenerateMask();
|
||||
ParentChunk.Dirty();
|
||||
}
|
||||
_physicsLayers.Add(entity, collidableComponent.CollisionLayer);
|
||||
}
|
||||
else
|
||||
{
|
||||
_blockedCollidables.Add(entity, collidableComponent.CollisionLayer);
|
||||
GenerateMask();
|
||||
ParentChunk.Dirty();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,18 +301,18 @@ namespace Content.Server.GameObjects.EntitySystems.Pathfinding
|
||||
// There's no guarantee that the entity isn't deleted
|
||||
// 90% of updates are probably entities moving around
|
||||
// Entity can't be under multiple categories so just checking each once is fine.
|
||||
if (_physicsLayers.ContainsKey(entity.Uid))
|
||||
if (_physicsLayers.ContainsKey(entity))
|
||||
{
|
||||
_physicsLayers.Remove(entity.Uid);
|
||||
_physicsLayers.Remove(entity);
|
||||
}
|
||||
else if (_accessReaders.ContainsKey(entity.Uid))
|
||||
else if (_accessReaders.ContainsKey(entity))
|
||||
{
|
||||
_accessReaders.Remove(entity.Uid);
|
||||
_accessReaders.Remove(entity);
|
||||
ParentChunk.Dirty();
|
||||
}
|
||||
else if (_blockedCollidables.ContainsKey(entity.Uid))
|
||||
else if (_blockedCollidables.ContainsKey(entity))
|
||||
{
|
||||
_blockedCollidables.Remove(entity.Uid);
|
||||
_blockedCollidables.Remove(entity);
|
||||
GenerateMask();
|
||||
ParentChunk.Dirty();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using Content.Server.GameObjects.Components.Access;
|
||||
using Content.Server.GameObjects.Components.GUI;
|
||||
using Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Pathfinders;
|
||||
using Content.Server.GameObjects.EntitySystems.JobQueues;
|
||||
using Content.Server.GameObjects.EntitySystems.JobQueues.Queues;
|
||||
@@ -20,9 +22,10 @@ using Robust.Shared.Utility;
|
||||
namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
|
||||
{
|
||||
/*
|
||||
// TODO: IMO use rectangular symmetry reduction on the nodes with collision at all., or
|
||||
// TODO: IMO use rectangular symmetry reduction on the nodes with collision at all. (currently planned to be implemented via AiReachableSystem and expanded later).
|
||||
alternatively store all rooms and have an alternative graph for humanoid mobs (same collision mask, needs access etc). You could also just path from room to room as needed.
|
||||
// TODO: Longer term -> Handle collision layer changes?
|
||||
TODO: Handle container entities so they're not tracked.
|
||||
*/
|
||||
/// <summary>
|
||||
/// This system handles pathfinding graph updates as well as dispatches to the pathfinder
|
||||
@@ -30,10 +33,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
|
||||
/// </summary>
|
||||
public class PathfindingSystem : EntitySystem
|
||||
{
|
||||
#pragma warning disable 649
|
||||
[Dependency] private readonly IEntityManager _entitymanager;
|
||||
[Dependency] private readonly IMapManager _mapManager;
|
||||
#pragma warning restore 649
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
|
||||
public IReadOnlyDictionary<GridId, Dictionary<MapIndices, PathfindingChunk>> Graph => _graph;
|
||||
private readonly Dictionary<GridId, Dictionary<MapIndices, PathfindingChunk>> _graph = new Dictionary<GridId, Dictionary<MapIndices, PathfindingChunk>>();
|
||||
@@ -47,7 +47,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
|
||||
private readonly Queue<TileRef> _tileUpdateQueue = new Queue<TileRef>();
|
||||
|
||||
// Need to store previously known entity positions for collidables for when they move
|
||||
private readonly Dictionary<EntityUid, PathfindingNode> _lastKnownPositions = new Dictionary<EntityUid, PathfindingNode>();
|
||||
private readonly Dictionary<IEntity, PathfindingNode> _lastKnownPositions = new Dictionary<IEntity, PathfindingNode>();
|
||||
|
||||
public const int TrackedCollisionLayers = (int)
|
||||
(CollisionGroup.Impassable |
|
||||
@@ -86,7 +86,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
|
||||
|
||||
foreach (var update in _collidableUpdateQueue)
|
||||
{
|
||||
var entity = _entitymanager.GetEntity(update.Owner);
|
||||
var entity = EntityManager.GetEntity(update.Owner);
|
||||
if (update.CanCollide)
|
||||
{
|
||||
HandleEntityAdd(entity);
|
||||
@@ -103,14 +103,13 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
|
||||
|
||||
foreach (var update in _accessReaderUpdateQueue)
|
||||
{
|
||||
var entity = _entitymanager.GetEntity(update.Uid);
|
||||
if (update.Enabled)
|
||||
{
|
||||
HandleEntityAdd(entity);
|
||||
HandleEntityAdd(update.Sender);
|
||||
}
|
||||
else
|
||||
{
|
||||
HandleEntityRemove(entity);
|
||||
HandleEntityRemove(update.Sender);
|
||||
}
|
||||
|
||||
totalUpdates++;
|
||||
@@ -138,7 +137,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
|
||||
|
||||
for (var i = 0; i < moveUpdateCount; i++)
|
||||
{
|
||||
HandleCollidableMove(_moveUpdateQueue.Dequeue());
|
||||
HandleEntityMove(_moveUpdateQueue.Dequeue());
|
||||
}
|
||||
|
||||
DebugTools.Assert(_moveUpdateQueue.Count < 1000);
|
||||
@@ -204,9 +203,6 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
// TODO: Remove this once the memory leaks are solved.
|
||||
return;
|
||||
|
||||
SubscribeLocalEvent<CollisionChangeMessage>(QueueCollisionChangeMessage);
|
||||
SubscribeLocalEvent<MoveEvent>(QueueMoveEvent);
|
||||
SubscribeLocalEvent<AccessReaderChangeMessage>(QueueAccessChangeMessage);
|
||||
@@ -279,7 +275,10 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
|
||||
/// <param name="entity"></param>
|
||||
private void HandleEntityAdd(IEntity entity)
|
||||
{
|
||||
if (entity.Deleted || _lastKnownPositions.ContainsKey(entity.Uid))
|
||||
if (entity.Deleted ||
|
||||
_lastKnownPositions.ContainsKey(entity) ||
|
||||
!entity.TryGetComponent(out ICollidableComponent collidableComponent) ||
|
||||
!PathfindingNode.IsRelevant(entity, collidableComponent))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -289,19 +288,19 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
|
||||
|
||||
var chunk = GetChunk(tileRef);
|
||||
var node = chunk.GetNode(tileRef);
|
||||
node.AddEntity(entity);
|
||||
_lastKnownPositions.Add(entity.Uid, node);
|
||||
node.AddEntity(entity, collidableComponent);
|
||||
_lastKnownPositions.Add(entity, node);
|
||||
}
|
||||
|
||||
private void HandleEntityRemove(IEntity entity)
|
||||
{
|
||||
if (!_lastKnownPositions.TryGetValue(entity.Uid, out var node))
|
||||
if (!_lastKnownPositions.TryGetValue(entity, out var node))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
node.RemoveEntity(entity);
|
||||
_lastKnownPositions.Remove(entity.Uid);
|
||||
_lastKnownPositions.Remove(entity);
|
||||
}
|
||||
|
||||
private void QueueMoveEvent(MoveEvent moveEvent)
|
||||
@@ -313,35 +312,47 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
|
||||
/// When an entity moves around we'll remove it from its old node and add it to its new node (if applicable)
|
||||
/// </summary>
|
||||
/// <param name="moveEvent"></param>
|
||||
private void HandleCollidableMove(MoveEvent moveEvent)
|
||||
private void HandleEntityMove(MoveEvent moveEvent)
|
||||
{
|
||||
var entityUid = moveEvent.Sender.Uid;
|
||||
|
||||
if (!_lastKnownPositions.TryGetValue(entityUid, out var oldNode))
|
||||
// If we've moved to space or the likes then remove us.
|
||||
if (moveEvent.Sender.Deleted ||
|
||||
!moveEvent.Sender.TryGetComponent(out ICollidableComponent collidableComponent) ||
|
||||
!PathfindingNode.IsRelevant(moveEvent.Sender, collidableComponent))
|
||||
{
|
||||
HandleEntityRemove(moveEvent.Sender);
|
||||
return;
|
||||
}
|
||||
|
||||
// Memory leak protection until grid parenting confirmed fix / you REALLY need the performance
|
||||
var gridBounds = _mapManager.GetGrid(moveEvent.Sender.Transform.GridID).WorldBounds;
|
||||
|
||||
if (!gridBounds.Contains(moveEvent.Sender.Transform.WorldPosition))
|
||||
{
|
||||
HandleEntityRemove(moveEvent.Sender);
|
||||
return;
|
||||
}
|
||||
|
||||
// If we move from space to a grid we may need to start tracking it.
|
||||
if (!_lastKnownPositions.TryGetValue(moveEvent.Sender, out var oldNode))
|
||||
{
|
||||
HandleEntityAdd(moveEvent.Sender);
|
||||
return;
|
||||
}
|
||||
|
||||
// The pathfinding graph is tile-based so first we'll check if they're on a different tile and if we need to update.
|
||||
// If you get entities bigger than 1 tile wide you'll need some other system so god help you.
|
||||
if (moveEvent.Sender.Deleted)
|
||||
{
|
||||
HandleEntityRemove(moveEvent.Sender);
|
||||
return;
|
||||
}
|
||||
|
||||
var newTile = _mapManager.GetGrid(moveEvent.NewPosition.GridID).GetTileRef(moveEvent.NewPosition);
|
||||
|
||||
|
||||
if (oldNode == null || oldNode.TileRef == newTile)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var newNode = GetNode(newTile);
|
||||
_lastKnownPositions[entityUid] = newNode;
|
||||
_lastKnownPositions[moveEvent.Sender] = newNode;
|
||||
|
||||
oldNode.RemoveEntity(moveEvent.Sender);
|
||||
newNode.AddEntity(moveEvent.Sender);
|
||||
newNode.AddEntity(moveEvent.Sender, collidableComponent);
|
||||
}
|
||||
|
||||
private void QueueCollisionChangeMessage(CollisionChangeMessage collisionMessage)
|
||||
|
||||
@@ -320,7 +320,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Steering
|
||||
return SteeringStatus.Pending;
|
||||
}
|
||||
|
||||
var ignoredCollision = new List<EntityUid>();
|
||||
var ignoredCollision = new List<IEntity>();
|
||||
// Check if the target entity has moved - If so then re-path
|
||||
// TODO: Patch the path from the target's position back towards us, stopping if it ever intersects the current path
|
||||
// Probably need a separate "PatchPath" job
|
||||
@@ -339,7 +339,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Steering
|
||||
RequestPath(entity, steeringRequest);
|
||||
}
|
||||
|
||||
ignoredCollision.Add(entitySteer.Target.Uid);
|
||||
ignoredCollision.Add(entitySteer.Target);
|
||||
}
|
||||
|
||||
HandleStuck(entity);
|
||||
@@ -597,7 +597,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Steering
|
||||
/// <param name="direction">entity's travel direction</param>
|
||||
/// <param name="ignoredTargets"></param>
|
||||
/// <returns></returns>
|
||||
private Vector2 CollisionAvoidance(IEntity entity, Vector2 direction, ICollection<EntityUid> ignoredTargets)
|
||||
private Vector2 CollisionAvoidance(IEntity entity, Vector2 direction, ICollection<IEntity> ignoredTargets)
|
||||
{
|
||||
if (direction == Vector2.Zero || !entity.TryGetComponent(out ICollidableComponent collidableComponent))
|
||||
{
|
||||
@@ -627,26 +627,25 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Steering
|
||||
{
|
||||
var node = _pathfindingSystem.GetNode(tile);
|
||||
// Assume the immovables have already been checked
|
||||
foreach (var (uid, layer) in node.PhysicsLayers)
|
||||
foreach (var (physicsEntity, layer) in node.PhysicsLayers)
|
||||
{
|
||||
// Ignore myself / my target if applicable / if my mask doesn't collide
|
||||
if (uid == entity.Uid || ignoredTargets.Contains(uid) || (entityCollisionMask & layer) == 0) continue;
|
||||
if (physicsEntity == entity || ignoredTargets.Contains(physicsEntity) || (entityCollisionMask & layer) == 0) continue;
|
||||
// God there's so many ways to do this
|
||||
// err for now we'll just assume the first entity is the center and just add a vector for it
|
||||
var collisionEntity = _entityManager.GetEntity(uid);
|
||||
|
||||
//Pathfinding updates are deferred so this may not be done yet.
|
||||
if (collisionEntity.Deleted) continue;
|
||||
if (physicsEntity.Deleted) continue;
|
||||
|
||||
// if we're moving in the same direction then ignore
|
||||
// So if 2 entities are moving towards each other and both detect a collision they'll both move in the same direction
|
||||
// i.e. towards the right
|
||||
if (collisionEntity.TryGetComponent(out IPhysicsComponent physicsComponent) &&
|
||||
if (physicsEntity.TryGetComponent(out IPhysicsComponent physicsComponent) &&
|
||||
Vector2.Dot(physicsComponent.LinearVelocity, direction) > 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var centerGrid = collisionEntity.Transform.GridPosition;
|
||||
var centerGrid = physicsEntity.Transform.GridPosition;
|
||||
// Check how close we are to center of tile and get the inverse; if we're closer this is stronger
|
||||
var additionalVector = (centerGrid.Position - entityGridCoords.Position);
|
||||
var distance = additionalVector.Length;
|
||||
|
||||
@@ -5,7 +5,5 @@ namespace Content.Server.Interfaces
|
||||
public interface IGasMixtureHolder
|
||||
{
|
||||
public GasMixture Air { get; set; }
|
||||
|
||||
bool AssumeAir(GasMixture giver);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,8 @@ namespace Content.Shared.GameObjects.Components.Disposal
|
||||
{
|
||||
UnAnchored,
|
||||
Anchored,
|
||||
Flushing
|
||||
Flushing,
|
||||
Charging
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.Reflection;
|
||||
using Robust.Shared.IoC;
|
||||
@@ -26,6 +27,10 @@ namespace Content.Shared.GameObjects.Components
|
||||
_count = value;
|
||||
if (_count <= 0)
|
||||
{
|
||||
if (ContainerHelpers.TryGetContainerMan(Owner, out var containerManager))
|
||||
{
|
||||
containerManager.Remove(Owner);
|
||||
}
|
||||
Owner.Delete();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.GameObjects.Components.Weapons.Ranged
|
||||
@@ -26,14 +27,33 @@ namespace Content.Shared.GameObjects.Components.Weapons.Ranged
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A component message raised when the weapon is fired at a position on the map.
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class FirePosComponentMessage : ComponentMessage
|
||||
{
|
||||
public GridCoordinates Target { get; }
|
||||
/// <summary>
|
||||
/// If this is not invalid, the target position is relative to the grid.
|
||||
/// Otherwise, it is a map position.
|
||||
/// </summary>
|
||||
public GridId TargetGrid { get; }
|
||||
|
||||
public FirePosComponentMessage(GridCoordinates target)
|
||||
/// <summary>
|
||||
/// If Target Grid is not invalid, this is relative to the grid, otherwise
|
||||
/// it is a map position.
|
||||
/// </summary>
|
||||
public Vector2 TargetPosition { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new instance of <see cref="FirePosComponentMessage"/>.
|
||||
/// </summary>
|
||||
/// <param name="targetGrid">The grid that the target position is on, if any.</param>
|
||||
/// <param name="targetPosition">Target position relative to the grid, or a map position if the grid is invalid.</param>
|
||||
public FirePosComponentMessage(GridId targetGrid, Vector2 targetPosition)
|
||||
{
|
||||
Target = target;
|
||||
TargetGrid = targetGrid;
|
||||
TargetPosition = targetPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
- !type:PhysShapeAabb
|
||||
layer:
|
||||
- SmallImpassable
|
||||
- MobImpassable
|
||||
- type: SnapGrid
|
||||
offset: Center
|
||||
- type: IconSmooth
|
||||
|
||||
@@ -118,6 +118,7 @@
|
||||
- type: DisposalUnitVisualizer
|
||||
state_unanchored: condisposal
|
||||
state_anchored: disposal
|
||||
state_charging: disposal-charging
|
||||
overlay_charging: dispover-charge
|
||||
overlay_ready: dispover-ready
|
||||
overlay_full: dispover-full
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 522 B |
@@ -1 +1 @@
|
||||
{"version": 1, "size": {"x": 32, "y": 32}, "license": "CC-BY-SA-3.0", "copyright": "https://github.com/discordia-space/CEV-Eris/blob/bbe32606902c90f5290b57d905a3f31b84dc6d7d/icons/obj/pipes/disposal.dmi and modified by DrSmugleaf", "states": [{"name": "condisposal", "directions": 1, "delays": [[1.0]]}, {"name": "conpipe-c", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "conpipe-j1", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "conpipe-j1s", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "conpipe-j2", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "conpipe-j2s", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "conpipe-s", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "conpipe-t", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "conpipe-y", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "disposal", "directions": 1, "delays": [[1.0]]}, {"name": "disposal-flush", "directions": 1, "delays": [[0.1, 0.1, 0.1, 0.1, 0.1, 0.5, 0.1, 0.1, 0.1]]}, {"name": "dispover-charge", "directions": 1, "delays": [[0.4, 0.4]]}, {"name": "dispover-full", "directions": 1, "delays": [[0.2, 0.2]]}, {"name": "dispover-handle", "directions": 1, "delays": [[1.0]]}, {"name": "dispover-ready", "directions": 1, "delays": [[1.0]]}, {"name": "intake", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "intake-closing", "directions": 4, "delays": [[0.5, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1], [0.5, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1], [0.5, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1], [0.5, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]]}, {"name": "outlet", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "outlet-open", "directions": 4, "delays": [[0.5, 0.5, 0.5, 0.5, 0.5, 0.1, 1.5, 0.1], [0.5, 0.5, 0.5, 0.5, 0.5, 0.1, 1.5, 0.1], [0.5, 0.5, 0.5, 0.5, 0.5, 0.1, 1.5, 0.1], [0.5, 0.5, 0.5, 0.5, 0.5, 0.1, 1.5, 0.1]]}, {"name": "pipe-b", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-bf", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-c", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-cf", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-d", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-j1", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-j1f", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-j1s", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-j1sf", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-j2", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-j2f", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-j2s", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-j2sf", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-s", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-sf", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-t", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-tagger", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-tagger-partial", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-tf", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-u", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-y", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-yf", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}]}
|
||||
{"version": 1, "size": {"x": 32, "y": 32}, "license": "CC-BY-SA-3.0", "copyright": "https://github.com/discordia-space/CEV-Eris/blob/bbe32606902c90f5290b57d905a3f31b84dc6d7d/icons/obj/pipes/disposal.dmi and modified by DrSmugleaf", "states": [{"name": "condisposal", "directions": 1, "delays": [[1.0]]}, {"name": "conpipe-c", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "conpipe-j1", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "conpipe-j1s", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "conpipe-j2", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "conpipe-j2s", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "conpipe-s", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "conpipe-t", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "conpipe-y", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "disposal", "directions": 1, "delays": [[1.0]]}, {"name": "disposal-charging", "directions": 1, "delays": [[1.0]]}, {"name": "disposal-flush", "directions": 1, "delays": [[0.1, 0.1, 0.1, 0.1, 0.1, 0.5, 0.1, 0.1, 0.1]]}, {"name": "dispover-charge", "directions": 1, "delays": [[0.4, 0.4]]}, {"name": "dispover-full", "directions": 1, "delays": [[0.2, 0.2]]}, {"name": "dispover-handle", "directions": 1, "delays": [[1.0]]}, {"name": "dispover-ready", "directions": 1, "delays": [[1.0]]}, {"name": "intake", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "intake-closing", "directions": 4, "delays": [[0.5, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1], [0.5, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1], [0.5, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1], [0.5, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]]}, {"name": "outlet", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "outlet-open", "directions": 4, "delays": [[0.5, 0.5, 0.5, 0.5, 0.5, 0.1, 1.5, 0.1], [0.5, 0.5, 0.5, 0.5, 0.5, 0.1, 1.5, 0.1], [0.5, 0.5, 0.5, 0.5, 0.5, 0.1, 1.5, 0.1], [0.5, 0.5, 0.5, 0.5, 0.5, 0.1, 1.5, 0.1]]}, {"name": "pipe-b", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-bf", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-c", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-cf", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-d", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-j1", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-j1f", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-j1s", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-j1sf", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-j2", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-j2f", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-j2s", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-j2sf", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-s", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-sf", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-t", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-tagger", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-tagger-partial", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-tf", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-u", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-y", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "pipe-yf", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}]}
|
||||
Reference in New Issue
Block a user