Unstable 1.8.4.0
This commit is contained in:
@@ -183,6 +183,13 @@ namespace Barotrauma.Items.Components
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(false, IsPropertySaveable.No, description: "Does the Controller require power to function (= to send signals and move the camera focus to a connected item)?")]
|
||||
public bool RequirePower
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(false, IsPropertySaveable.No, description: "If true, other items can be used simultaneously.")]
|
||||
public bool IsSecondaryItem
|
||||
{
|
||||
@@ -190,6 +197,13 @@ namespace Barotrauma.Items.Components
|
||||
private set;
|
||||
}
|
||||
|
||||
[Serialize(false, IsPropertySaveable.No, description: "If enabled, the user sticks to the position of this item even if the item moves.")]
|
||||
public bool ForceUserToStayAttached
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public Controller(Item item, ContentXElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
@@ -199,25 +213,44 @@ namespace Barotrauma.Items.Components
|
||||
IsActive = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hack for allowing characters to interact with a loader to get inside a boarding pod.
|
||||
/// Doing that simply by autointeracting with the contained pod is difficult, because interacting with the loader selects it
|
||||
/// _after_ the Select method of the pod is called by the autointeract logic, and the character only goes inside the pod if it's the selected item.
|
||||
/// </summary>
|
||||
private bool forceSelectNextFrame;
|
||||
|
||||
private float userCanInteractCheckTimer;
|
||||
|
||||
private const float UserCanInteractCheckInterval = 1.0f;
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
this.cam = cam;
|
||||
UserInCorrectPosition = false;
|
||||
if (!ForceUserToStayAttached) { UserInCorrectPosition = false; }
|
||||
|
||||
string signal = IsToggle && State ? output : falseOutput;
|
||||
if (item.Connections != null && IsToggle && !string.IsNullOrEmpty(signal))
|
||||
if (item.Connections != null && IsToggle && !string.IsNullOrEmpty(signal) && !IsOutOfPower())
|
||||
{
|
||||
item.SendSignal(signal, "signal_out");
|
||||
item.SendSignal(signal, "trigger_out");
|
||||
}
|
||||
|
||||
if (forceSelectNextFrame && user != null)
|
||||
{
|
||||
user.SelectedItem = item;
|
||||
}
|
||||
forceSelectNextFrame = false;
|
||||
|
||||
userCanInteractCheckTimer -= deltaTime;
|
||||
|
||||
if (user == null
|
||||
|| user.Removed
|
||||
|| !user.IsAnySelectedItem(item)
|
||||
|| item.ParentInventory != null
|
||||
|| !user.CanInteractWith(item)
|
||||
|| (item.ParentInventory != null && !IsAttachedUser(user))
|
||||
|| (UsableIn == UseEnvironment.Water && !user.AnimController.InWater)
|
||||
|| (UsableIn == UseEnvironment.Air && user.AnimController.InWater))
|
||||
|| (UsableIn == UseEnvironment.Air && user.AnimController.InWater)
|
||||
|| !CheckUserCanInteract())
|
||||
{
|
||||
if (user != null)
|
||||
{
|
||||
@@ -228,6 +261,17 @@ namespace Barotrauma.Items.Components
|
||||
return;
|
||||
}
|
||||
|
||||
if (ForceUserToStayAttached && Vector2.DistanceSquared(item.WorldPosition, user.WorldPosition) > 0.1f)
|
||||
{
|
||||
user.TeleportTo(item.WorldPosition);
|
||||
user.AnimController.Collider.ResetDynamics();
|
||||
foreach (var limb in user.AnimController.Limbs)
|
||||
{
|
||||
if (limb.Removed || limb.IsSevered) { continue; }
|
||||
limb.body?.ResetDynamics();
|
||||
}
|
||||
}
|
||||
|
||||
user.AnimController.StartUsingItem();
|
||||
|
||||
if (userPos != Vector2.Zero)
|
||||
@@ -330,6 +374,22 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckUserCanInteract()
|
||||
{
|
||||
//optimization: CanInteractWith is relatively heavy (can involve visibility checks for example), let's not do it every frame
|
||||
if (user != null)
|
||||
{
|
||||
if (userCanInteractCheckTimer <= 0.0f)
|
||||
{
|
||||
userCanInteractCheckTimer = UserCanInteractCheckInterval;
|
||||
return user.CanInteractWith(item);
|
||||
}
|
||||
}
|
||||
//we only do the actual check every UserCanInteractCheckInterval seconds
|
||||
//can mean the component can stay selected for <1s after the user no longer has access to it
|
||||
return true;
|
||||
}
|
||||
|
||||
private double lastUsed;
|
||||
|
||||
public override bool Use(float deltaTime, Character activator = null)
|
||||
@@ -344,6 +404,8 @@ namespace Barotrauma.Items.Components
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsOutOfPower()) { return false; }
|
||||
|
||||
if (IsToggle && (activator == null || lastUsed < Timing.TotalTime - 0.1))
|
||||
{
|
||||
if (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer)
|
||||
@@ -380,6 +442,8 @@ namespace Barotrauma.Items.Components
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsOutOfPower()) { return false; }
|
||||
|
||||
focusTarget = GetFocusTarget();
|
||||
|
||||
if (focusTarget == null)
|
||||
@@ -417,11 +481,20 @@ namespace Barotrauma.Items.Components
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsOutOfPower()
|
||||
{
|
||||
if (!RequirePower) { return false; }
|
||||
var powered = item.GetComponent<Powered>();
|
||||
return powered == null || powered.Voltage < powered.MinVoltage;
|
||||
}
|
||||
|
||||
public Item GetFocusTarget()
|
||||
{
|
||||
var positionOut = item.Connections?.Find(c => c.Name == "position_out");
|
||||
if (positionOut == null) { return null; }
|
||||
|
||||
if (IsOutOfPower()) { return null; }
|
||||
|
||||
item.SendSignal(new Signal(MathHelper.ToDegrees(targetRotation).ToString("G", CultureInfo.InvariantCulture), sender: user), positionOut);
|
||||
|
||||
for (int i = item.LastSentSignalRecipients.Count - 1; i >= 0; i--)
|
||||
@@ -447,6 +520,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public override bool Pick(Character picker)
|
||||
{
|
||||
if (IsOutOfPower()) { return false; }
|
||||
#if CLIENT
|
||||
if (Screen.Selected == GameMain.SubEditorScreen) { return false; }
|
||||
#endif
|
||||
@@ -539,7 +613,16 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
user = activator;
|
||||
IsActive = true;
|
||||
if (ForceUserToStayAttached && item.Container != null)
|
||||
{
|
||||
forceSelectNextFrame = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//allow the selection logic above to run when out of power, but allow sending signals
|
||||
if (IsOutOfPower()) { return false; }
|
||||
|
||||
#if SERVER
|
||||
item.CreateServerEvent(this);
|
||||
#endif
|
||||
@@ -550,6 +633,14 @@ namespace Barotrauma.Items.Components
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// "Attached user" sticks to this item. Can be used for things such as clown crates and boarding pods.
|
||||
/// </summary>
|
||||
public bool IsAttachedUser(Character character)
|
||||
{
|
||||
return character != null && character == user && ForceUserToStayAttached;
|
||||
}
|
||||
|
||||
public override void FlipX(bool relativeToSub)
|
||||
{
|
||||
if (dir != Direction.None)
|
||||
|
||||
Reference in New Issue
Block a user