Merge branch 'dev' of https://github.com/Regalis11/Barotrauma into unstable
This commit is contained in:
@@ -36,6 +36,7 @@ namespace Barotrauma.Items.Components
|
||||
private readonly List<LimbPos> limbPositions = new List<LimbPos>();
|
||||
|
||||
private Direction dir;
|
||||
public Direction Direction => dir;
|
||||
|
||||
//the position where the user walks to when using the controller
|
||||
//(relative to the position of the item)
|
||||
@@ -128,6 +129,13 @@ namespace Barotrauma.Items.Components
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(false, IsPropertySaveable.No, description: "If true, other items can be used simultaneously.")]
|
||||
public bool IsSecondaryItem
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public Controller(Item item, ContentXElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
@@ -150,7 +158,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (user == null
|
||||
|| user.Removed
|
||||
|| user.SelectedConstruction != item
|
||||
|| !user.IsAnySelectedItem(item)
|
||||
|| item.ParentInventory != null
|
||||
|| !user.CanInteractWith(item)
|
||||
|| (UsableIn == UseEnvironment.Water && !user.AnimController.InWater)
|
||||
@@ -165,7 +173,7 @@ namespace Barotrauma.Items.Components
|
||||
return;
|
||||
}
|
||||
|
||||
user.AnimController.Anim = AnimController.Animation.UsingConstruction;
|
||||
user.AnimController.StartUsingItem();
|
||||
|
||||
if (userPos != Vector2.Zero)
|
||||
{
|
||||
@@ -186,32 +194,34 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
else
|
||||
{
|
||||
diff.Y = 0.0f;
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient && user != Character.Controlled)
|
||||
// Secondary items (like ladders or chairs) will control the character position over primary items
|
||||
// Only control the character position if the character doesn't have another secondary item already controlling it
|
||||
if (!user.HasSelectedAnotherSecondaryItem(Item))
|
||||
{
|
||||
if (Math.Abs(diff.X) > 20.0f)
|
||||
diff.Y = 0.0f;
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient && user != Character.Controlled)
|
||||
{
|
||||
//wait for the character to walk to the correct position
|
||||
return;
|
||||
if (Math.Abs(diff.X) > 20.0f)
|
||||
{
|
||||
//wait for the character to walk to the correct position
|
||||
return;
|
||||
}
|
||||
else if (Math.Abs(diff.X) > 0.1f)
|
||||
{
|
||||
//aim to keep the collider at the correct position once close enough
|
||||
user.AnimController.Collider.LinearVelocity = new Vector2(
|
||||
diff.X * 0.1f,
|
||||
user.AnimController.Collider.LinearVelocity.Y);
|
||||
}
|
||||
}
|
||||
else if (Math.Abs(diff.X) > 0.1f)
|
||||
{
|
||||
//aim to keep the collider at the correct position once close enough
|
||||
user.AnimController.Collider.LinearVelocity = new Vector2(
|
||||
diff.X * 0.1f,
|
||||
user.AnimController.Collider.LinearVelocity.Y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Math.Abs(diff.X) > 10.0f)
|
||||
else if (Math.Abs(diff.X) > 10.0f)
|
||||
{
|
||||
user.AnimController.TargetMovement = Vector2.Normalize(diff);
|
||||
user.AnimController.TargetDir = diff.X > 0.0f ? Direction.Right : Direction.Left;
|
||||
return;
|
||||
}
|
||||
user.AnimController.TargetMovement = Vector2.Zero;
|
||||
}
|
||||
user.AnimController.TargetMovement = Vector2.Zero;
|
||||
UserInCorrectPosition = true;
|
||||
}
|
||||
}
|
||||
@@ -220,9 +230,16 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (limbPositions.Count == 0) { return; }
|
||||
|
||||
user.AnimController.Anim = AnimController.Animation.UsingConstruction;
|
||||
user.AnimController.StartUsingItem();
|
||||
|
||||
user.AnimController.ResetPullJoints();
|
||||
if (user.SelectedItem != null)
|
||||
{
|
||||
user.AnimController.ResetPullJoints(l => l.IsLowerBody);
|
||||
}
|
||||
else
|
||||
{
|
||||
user.AnimController.ResetPullJoints();
|
||||
}
|
||||
|
||||
if (dir != 0) { user.AnimController.TargetDir = dir; }
|
||||
|
||||
@@ -230,7 +247,10 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
Limb limb = user.AnimController.GetLimb(lb.LimbType);
|
||||
if (limb == null || !limb.body.Enabled) { continue; }
|
||||
|
||||
// Don't move lower body limbs if there's another selected secondary item that should control them
|
||||
if (limb.IsLowerBody && user.HasSelectedAnotherSecondaryItem(Item)) { continue; }
|
||||
// Don't move hands if there's a selected primary item that should control them
|
||||
if (!limb.IsLowerBody && Item == user.SelectedSecondaryItem && user.SelectedItem != null) { continue; }
|
||||
if (lb.AllowUsingLimb)
|
||||
{
|
||||
switch (lb.LimbType)
|
||||
@@ -247,12 +267,9 @@ namespace Barotrauma.Items.Components
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
limb.Disabled = true;
|
||||
|
||||
Vector2 worldPosition = new Vector2(item.WorldRect.X, item.WorldRect.Y) + lb.Position * item.Scale;
|
||||
Vector2 diff = worldPosition - limb.WorldPosition;
|
||||
|
||||
limb.PullJointEnabled = true;
|
||||
limb.PullJointWorldAnchorB = limb.SimPosition + ConvertUnits.ToSimUnits(diff);
|
||||
}
|
||||
@@ -266,9 +283,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (user == null || user.Removed ||
|
||||
user.SelectedConstruction != item || !user.CanInteractWith(item))
|
||||
if (user == null || user.Removed || !user.IsAnySelectedItem(item) || !user.CanInteractWith(item))
|
||||
{
|
||||
user = null;
|
||||
return false;
|
||||
@@ -290,46 +305,44 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
lastUsed = Timing.TotalTime;
|
||||
|
||||
ApplyStatusEffects(ActionType.OnUse, 1.0f, activator);
|
||||
|
||||
ApplyStatusEffects(ActionType.OnUse, 1.0f, activator);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool SecondaryUse(float deltaTime, Character character = null)
|
||||
{
|
||||
if (this.user != character)
|
||||
if (user != character)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.user == null || character.Removed ||
|
||||
this.user.SelectedConstruction != item || !character.CanInteractWith(item))
|
||||
if (user == null || character.Removed || !user.IsAnySelectedItem(item) || !character.CanInteractWith(item))
|
||||
{
|
||||
user = null;
|
||||
return false;
|
||||
}
|
||||
if (character == null)
|
||||
{
|
||||
this.user = null;
|
||||
return false;
|
||||
}
|
||||
if (character == null) return false;
|
||||
|
||||
focusTarget = GetFocusTarget();
|
||||
|
||||
if (focusTarget == null)
|
||||
{
|
||||
Vector2 centerPos = new Vector2(item.WorldRect.Center.X, item.WorldRect.Center.Y);
|
||||
|
||||
Vector2 offset = character.CursorWorldPosition - centerPos;
|
||||
offset.Y = -offset.Y;
|
||||
|
||||
targetRotation = MathUtils.WrapAngleTwoPi(MathUtils.VectorToAngle(offset));
|
||||
return false;
|
||||
}
|
||||
|
||||
character.ViewTarget = focusTarget;
|
||||
|
||||
#if CLIENT
|
||||
if (character == Character.Controlled && cam != null)
|
||||
{
|
||||
Lights.LightManager.ViewTarget = focusTarget;
|
||||
cam.TargetPos = focusTarget.WorldPosition;
|
||||
|
||||
cam.OffsetAmount = MathHelper.Lerp(cam.OffsetAmount, (focusTarget as Item).Prefab.OffsetOnSelected * focusTarget.OffsetOnSelectedMultiplier, deltaTime * 10.0f);
|
||||
HideHUDs(true);
|
||||
}
|
||||
@@ -338,16 +351,12 @@ namespace Barotrauma.Items.Components
|
||||
if (!character.IsRemotePlayer || character.ViewTarget == focusTarget)
|
||||
{
|
||||
Vector2 centerPos = new Vector2(focusTarget.WorldRect.Center.X, focusTarget.WorldRect.Center.Y);
|
||||
|
||||
Turret turret = focusTarget.GetComponent<Turret>();
|
||||
if (turret != null)
|
||||
if (focusTarget.GetComponent<Turret>() is { } turret)
|
||||
{
|
||||
centerPos = new Vector2(focusTarget.WorldRect.X + turret.TransformedBarrelPos.X, focusTarget.WorldRect.Y - turret.TransformedBarrelPos.Y);
|
||||
}
|
||||
|
||||
Vector2 offset = character.CursorWorldPosition - centerPos;
|
||||
offset.Y = -offset.Y;
|
||||
|
||||
targetRotation = MathUtils.WrapAngleTwoPi(MathUtils.VectorToAngle(offset));
|
||||
}
|
||||
return true;
|
||||
@@ -425,9 +434,10 @@ namespace Barotrauma.Items.Components
|
||||
humanoidAnim.LockFlippingUntil = (float)Timing.TotalTime + 0.5f;
|
||||
}
|
||||
|
||||
if (character.SelectedConstruction == this.item) { character.SelectedConstruction = null; }
|
||||
if (character.SelectedItem == item) { character.SelectedItem = null; }
|
||||
if (character.SelectedSecondaryItem == item) { character.SelectedSecondaryItem = null; }
|
||||
|
||||
character.AnimController.Anim = AnimController.Animation.None;
|
||||
character.AnimController.StopUsingItem();
|
||||
if (character == Character.Controlled)
|
||||
{
|
||||
HideHUDs(false);
|
||||
|
||||
+15
-11
@@ -3,6 +3,7 @@ using Barotrauma.Extensions;
|
||||
using Barotrauma.Networking;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
@@ -39,8 +40,6 @@ namespace Barotrauma.Items.Components
|
||||
[Editable, Serialize(1.0f, IsPropertySaveable.Yes)]
|
||||
public float DeconstructionSpeed { get; set; }
|
||||
|
||||
public override bool RecreateGUIOnResolutionChange => true;
|
||||
|
||||
public Deconstructor(Item item, ContentXElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
@@ -62,11 +61,18 @@ namespace Barotrauma.Items.Components
|
||||
inputContainer = containers[0];
|
||||
outputContainer = containers[1];
|
||||
|
||||
#if CLIENT
|
||||
Identifier eventIdentifier = new Identifier(nameof(Deconstructor));
|
||||
inputContainer.OnContainedItemsChanged.RegisterOverwriteExisting(eventIdentifier, OnItemSlotsChanged);
|
||||
#endif
|
||||
|
||||
OnItemLoadedProjSpecific();
|
||||
}
|
||||
|
||||
partial void OnItemLoadedProjSpecific();
|
||||
|
||||
partial void OnItemSlotsChanged(ItemContainer container);
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
MoveInputQueue();
|
||||
@@ -88,7 +94,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
ApplyStatusEffects(ActionType.OnActive, deltaTime, null);
|
||||
|
||||
progressTimer += deltaTime * Math.Min(powerConsumption <= 0.0f ? 1 : Voltage, 1.0f);
|
||||
progressTimer += deltaTime * Math.Min(powerConsumption <= 0.0f ? 1 : Voltage, MaxOverVoltageFactor);
|
||||
|
||||
float tinkeringStrength = 0f;
|
||||
if (repairable.IsTinkering)
|
||||
@@ -114,7 +120,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if ((Entity.Spawner?.IsInRemoveQueue(targetItem) ?? false) || !inputContainer.Inventory.AllItems.Contains(targetItem)) { continue; }
|
||||
var validDeconstructItems = targetItem.Prefab.DeconstructItems.Where(it =>
|
||||
(it.RequiredDeconstructor.Length == 0 || it.RequiredDeconstructor.Any(r => item.HasTag(r) || item.Prefab.Identifier == r)) &&
|
||||
it.IsValidDeconstructor(item) &&
|
||||
(it.RequiredOtherItem.Length == 0 || it.RequiredOtherItem.Any(r => items.Any(it => it != targetItem && (it.HasTag(r) || it.Prefab.Identifier == r))))).ToList();
|
||||
|
||||
ProcessItem(targetItem, items, validDeconstructItems, allowRemove: validDeconstructItems.Any() || !targetItem.Prefab.DeconstructItems.Any());
|
||||
@@ -132,9 +138,7 @@ namespace Barotrauma.Items.Components
|
||||
var targetItem = inputContainer.Inventory.LastOrDefault();
|
||||
if (targetItem == null) { return; }
|
||||
|
||||
var validDeconstructItems = targetItem.Prefab.DeconstructItems.Where(it =>
|
||||
it.RequiredDeconstructor.Length == 0 || it.RequiredDeconstructor.Any(r => item.HasTag(r) || item.Prefab.Identifier == r)).ToList();
|
||||
|
||||
var validDeconstructItems = targetItem.Prefab.DeconstructItems.Where(it => it.IsValidDeconstructor(item)).ToList();
|
||||
float deconstructTime = validDeconstructItems.Any() ? targetItem.Prefab.DeconstructTime / (DeconstructionSpeed * deconstructionSpeedModifier) : 1.0f;
|
||||
|
||||
progressState = Math.Min(progressTimer / deconstructTime, 1.0f);
|
||||
@@ -197,18 +201,18 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
foreach (DeconstructItem deconstructProduct in products)
|
||||
{
|
||||
CreateDeconstructProduct(deconstructProduct, inputItems, amountMultiplier);
|
||||
CreateDeconstructProduct(deconstructProduct, inputItems, (int)(amountMultiplier * deconstructProduct.Amount));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (DeconstructItem deconstructProduct in validDeconstructItems)
|
||||
{
|
||||
CreateDeconstructProduct(deconstructProduct, inputItems, amountMultiplier);
|
||||
CreateDeconstructProduct(deconstructProduct, inputItems, (int)(amountMultiplier * deconstructProduct.Amount));
|
||||
}
|
||||
}
|
||||
|
||||
void CreateDeconstructProduct(DeconstructItem deconstructProduct, IEnumerable<Item> inputItems, float amountMultiplier)
|
||||
void CreateDeconstructProduct(DeconstructItem deconstructProduct, IEnumerable<Item> inputItems, int amount)
|
||||
{
|
||||
float percentageHealth = targetItem.Condition / targetItem.MaxCondition;
|
||||
|
||||
@@ -276,11 +280,11 @@ namespace Barotrauma.Items.Components
|
||||
user.CheckTalents(AbilityEffectType.OnItemDeconstructedInventory, itemDeconstructedInventory);
|
||||
}
|
||||
|
||||
int amount = (int)amountMultiplier;
|
||||
for (int i = 0; i < amount; i++)
|
||||
{
|
||||
Entity.Spawner.AddItemToSpawnQueue(itemPrefab, outputContainer.Inventory, condition, onSpawned: (Item spawnedItem) =>
|
||||
{
|
||||
spawnedItem.SpawnedInCurrentOutpost = item.SpawnedInCurrentOutpost;
|
||||
spawnedItem.StolenDuringRound = targetItem.StolenDuringRound;
|
||||
spawnedItem.AllowStealing = targetItem.AllowStealing;
|
||||
for (int i = 0; i < outputContainer.Capacity; i++)
|
||||
|
||||
@@ -117,7 +117,7 @@ namespace Barotrauma.Items.Components
|
||||
Force = MathHelper.Lerp(force, (Voltage < MinVoltage) ? 0.0f : targetForce, deltaTime * 10.0f);
|
||||
if (Math.Abs(Force) > 1.0f)
|
||||
{
|
||||
float voltageFactor = MinVoltage <= 0.0f ? 1.0f : Math.Min(Voltage, 1.0f);
|
||||
float voltageFactor = MinVoltage <= 0.0f ? 1.0f : Math.Min(Voltage, MaxOverVoltageFactor);
|
||||
float currForce = force * voltageFactor;
|
||||
float condition = item.Condition / item.MaxCondition;
|
||||
// Broken engine makes more noise.
|
||||
|
||||
@@ -76,8 +76,6 @@ namespace Barotrauma.Items.Components
|
||||
get { return outputContainer; }
|
||||
}
|
||||
|
||||
public override bool RecreateGUIOnResolutionChange => true;
|
||||
|
||||
private float progressState;
|
||||
|
||||
private readonly Dictionary<uint, int> fabricationLimits = new Dictionary<uint, int>();
|
||||
@@ -305,7 +303,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
float fabricationSpeedIncrease = 1f + tinkeringStrength * TinkeringSpeedIncrease;
|
||||
|
||||
timeUntilReady -= deltaTime * fabricationSpeedIncrease * Math.Min(powerConsumption <= 0 ? 1 : Voltage, 1.0f);
|
||||
timeUntilReady -= deltaTime * fabricationSpeedIncrease * Math.Min(powerConsumption <= 0 ? 1 : Voltage, MaxOverVoltageFactor);
|
||||
|
||||
UpdateRequiredTimeProjSpecific();
|
||||
|
||||
@@ -371,8 +369,7 @@ namespace Barotrauma.Items.Components
|
||||
var availableItems = availableIngredients[requiredPrefab.Identifier];
|
||||
var availableItem = availableItems.FirstOrDefault(potentialPrefab =>
|
||||
{
|
||||
return potentialPrefab.ConditionPercentage >= requiredItem.MinCondition * 100.0f &&
|
||||
potentialPrefab.ConditionPercentage <= requiredItem.MaxCondition * 100.0f;
|
||||
return requiredItem.IsConditionSuitable(potentialPrefab.ConditionPercentage);
|
||||
});
|
||||
|
||||
if (availableItem == null) { continue; }
|
||||
@@ -556,8 +553,20 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
const int MaxCraftingSkill = 100;
|
||||
|
||||
//having a higher-than-100 skill (e.g. due to talents) gives +1 quality
|
||||
quality += fabricatedItem.RequiredSkills.All(s => user.GetSkillLevel(s.Identifier) >= MaxCraftingSkill) ? 1 : 0;
|
||||
quality += FabricationDegreeOfSuccess(user, fabricatedItem.RequiredSkills) >= 0.5f ? 1 : 0;
|
||||
foreach (var skill in fabricatedItem.RequiredSkills)
|
||||
{
|
||||
//+1 quality if the character's skill level is >20% from the min requirement towards max skill
|
||||
//e.g. if the skill requirement is 10 -> 28
|
||||
//40 -> 52
|
||||
//90 -> 92
|
||||
float skillRequirement = MathHelper.Lerp(skill.Level, MaxCraftingSkill, 0.2f);
|
||||
if (user.GetSkillLevel(skill.Identifier) > skillRequirement)
|
||||
{
|
||||
quality += 1;
|
||||
}
|
||||
}
|
||||
return quality;
|
||||
}
|
||||
|
||||
@@ -604,8 +613,7 @@ namespace Barotrauma.Items.Components
|
||||
var availablePrefabs = availableIngredients[requiredPrefab.Identifier];
|
||||
foreach (Item availablePrefab in availablePrefabs)
|
||||
{
|
||||
if (availablePrefab.ConditionPercentage / 100.0f >= requiredItem.MinCondition &&
|
||||
availablePrefab.ConditionPercentage / 100.0f <= requiredItem.MaxCondition)
|
||||
if (requiredItem.IsConditionSuitable(availablePrefab.ConditionPercentage))
|
||||
{
|
||||
availablePrefabsAmount++;
|
||||
}
|
||||
@@ -637,10 +645,13 @@ namespace Barotrauma.Items.Components
|
||||
if (skills.Length == 0) { return 1.0f; }
|
||||
if (character == null) { return 0.0f; }
|
||||
|
||||
float skillSum = (from t in skills let characterLevel = character.GetSkillLevel(t.Identifier) select (characterLevel - (t.Level * SkillRequirementMultiplier))).Sum();
|
||||
float average = skillSum / skills.Length;
|
||||
|
||||
return (average + 100.0f) / 2.0f / 100.0f;
|
||||
float minDegreeOfSuccess = 1.0f;
|
||||
foreach (var skill in skills)
|
||||
{
|
||||
float characterLevel = character.GetSkillLevel(skill.Identifier);
|
||||
minDegreeOfSuccess = Math.Min(minDegreeOfSuccess, (characterLevel - (skill.Level * SkillRequirementMultiplier) + 100.0f) / 2.0f / 100.0f);
|
||||
}
|
||||
return minDegreeOfSuccess;
|
||||
}
|
||||
|
||||
public override float GetSkillMultiplier()
|
||||
@@ -648,13 +659,16 @@ namespace Barotrauma.Items.Components
|
||||
return SkillRequirementMultiplier;
|
||||
}
|
||||
|
||||
|
||||
private readonly HashSet<Inventory> linkedInventories = new HashSet<Inventory>();
|
||||
|
||||
private void RefreshAvailableIngredients()
|
||||
{
|
||||
Character user = this.user;
|
||||
#if CLIENT
|
||||
user ??= Character.Controlled;
|
||||
#endif
|
||||
|
||||
linkedInventories.Clear();
|
||||
List<Item> itemList = new List<Item>();
|
||||
itemList.AddRange(inputContainer.Inventory.AllItems);
|
||||
foreach (MapEntity linkedTo in item.linkedTo)
|
||||
@@ -674,6 +688,7 @@ namespace Barotrauma.Items.Components
|
||||
itemContainer = deconstructor.OutputContainer;
|
||||
}
|
||||
|
||||
linkedInventories.Add(itemContainer.Inventory);
|
||||
itemList.AddRange(itemContainer.Inventory.AllItems);
|
||||
}
|
||||
}
|
||||
@@ -688,6 +703,7 @@ namespace Barotrauma.Items.Components
|
||||
if (user?.Inventory != null)
|
||||
{
|
||||
itemList.AddRange(user.Inventory.AllItems);
|
||||
linkedInventories.Add(user.Inventory);
|
||||
}
|
||||
availableIngredients.Clear();
|
||||
foreach (Item item in itemList)
|
||||
@@ -720,9 +736,7 @@ namespace Barotrauma.Items.Components
|
||||
var availablePrefabs = availableIngredients[requiredPrefab.Identifier];
|
||||
var availablePrefab = availablePrefabs.FirstOrDefault(potentialPrefab =>
|
||||
{
|
||||
return !usedItems.Contains(potentialPrefab) &&
|
||||
potentialPrefab.ConditionPercentage >= requiredItem.MinCondition * 100.0f &&
|
||||
potentialPrefab.ConditionPercentage <= requiredItem.MaxCondition * 100.0f;
|
||||
return !usedItems.Contains(potentialPrefab) && requiredItem.IsConditionSuitable(potentialPrefab.ConditionPercentage);
|
||||
});
|
||||
if (availablePrefab == null) { continue; }
|
||||
|
||||
|
||||
+1
-2
@@ -2,7 +2,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
@@ -52,7 +51,7 @@ namespace Barotrauma.Items.Components
|
||||
return;
|
||||
}
|
||||
|
||||
CurrFlow = Math.Min(PowerConsumption > 0 ? Voltage : 1.0f, 1.0f) * generatedAmount * 100.0f;
|
||||
CurrFlow = Math.Min(PowerConsumption > 0 ? Voltage : 1.0f, MaxOverVoltageFactor) * generatedAmount * 100.0f;
|
||||
float conditionMult = item.Condition / item.MaxCondition;
|
||||
//100% condition = 100% oxygen
|
||||
//50% condition = 25% oxygen
|
||||
|
||||
@@ -130,7 +130,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (item.CurrentHull == null) { return; }
|
||||
|
||||
float powerFactor = Math.Min(currPowerConsumption <= 0.0f || MinVoltage <= 0.0f ? 1.0f : Voltage, 1.0f);
|
||||
float powerFactor = Math.Min(currPowerConsumption <= 0.0f || MinVoltage <= 0.0f ? 1.0f : Voltage, MaxOverVoltageFactor);
|
||||
|
||||
currFlow = flowPercentage / 100.0f * maxFlow * powerFactor;
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
const float NetworkUpdateIntervalHigh = 0.5f;
|
||||
|
||||
const float TemperatureBoostAmount = 20;
|
||||
|
||||
//the rate at which the reactor is being run on (higher rate -> higher temperature)
|
||||
private float fissionRate;
|
||||
|
||||
@@ -46,6 +48,11 @@ namespace Barotrauma.Items.Components
|
||||
private Vector2 optimalFissionRate, allowedFissionRate;
|
||||
private Vector2 optimalTurbineOutput, allowedTurbineOutput;
|
||||
|
||||
private float? signalControlledTargetFissionRate, signalControlledTargetTurbineOutput;
|
||||
private double lastReceivedFissionRateSignalTime, lastReceivedTurbineOutputSignalTime;
|
||||
|
||||
private float temperatureBoost;
|
||||
|
||||
private bool _powerOn;
|
||||
|
||||
[Serialize(defaultValue: false, isSaveable: IsPropertySaveable.Yes)]
|
||||
@@ -226,7 +233,7 @@ namespace Barotrauma.Items.Components
|
||||
// (= bots turn autotemp back on when leaving the reactor)
|
||||
if (LastAIUser != null)
|
||||
{
|
||||
if (LastAIUser.SelectedConstruction != item && LastAIUser.CanInteractWith(item))
|
||||
if (LastAIUser.SelectedItem != item && LastAIUser.CanInteractWith(item))
|
||||
{
|
||||
AutoTemp = true;
|
||||
if (GameMain.NetworkMember?.IsServer ?? false) { unsentChanges = true; }
|
||||
@@ -241,6 +248,34 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
#endif
|
||||
|
||||
if (signalControlledTargetFissionRate.HasValue && lastReceivedFissionRateSignalTime > Timing.TotalTime - 1)
|
||||
{
|
||||
TargetFissionRate = adjustValueWithoutOverShooting(TargetFissionRate, signalControlledTargetFissionRate.Value, deltaTime * 5.0f);
|
||||
#if CLIENT
|
||||
FissionRateScrollBar.BarScroll = TargetFissionRate / 100.0f;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
signalControlledTargetFissionRate = null;
|
||||
}
|
||||
if (signalControlledTargetTurbineOutput.HasValue && lastReceivedTurbineOutputSignalTime > Timing.TotalTime - 1)
|
||||
{
|
||||
TargetTurbineOutput = adjustValueWithoutOverShooting(TargetTurbineOutput, signalControlledTargetTurbineOutput.Value, deltaTime * 5.0f);
|
||||
#if CLIENT
|
||||
TurbineOutputScrollBar.BarScroll = TargetTurbineOutput / 100.0f;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
signalControlledTargetTurbineOutput = null;
|
||||
}
|
||||
|
||||
static float adjustValueWithoutOverShooting(float current, float target, float speed)
|
||||
{
|
||||
return target < current ? Math.Max(target, current - speed) : Math.Min(target, current + speed);
|
||||
}
|
||||
|
||||
prevAvailableFuel = AvailableFuel;
|
||||
ApplyStatusEffects(ActionType.OnActive, deltaTime, null);
|
||||
|
||||
@@ -270,7 +305,10 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
float temperatureDiff = (heatAmount - turbineOutput) - Temperature;
|
||||
Temperature += MathHelper.Clamp(Math.Sign(temperatureDiff) * 10.0f * deltaTime, -Math.Abs(temperatureDiff), Math.Abs(temperatureDiff));
|
||||
//if (item.InWater && AvailableFuel < 100.0f) Temperature -= 12.0f * deltaTime;
|
||||
temperatureBoost = adjustValueWithoutOverShooting(temperatureBoost, 0.0f, deltaTime);
|
||||
#if CLIENT
|
||||
temperatureBoostUpButton.Enabled = temperatureBoostDownButton.Enabled = Math.Abs(temperatureBoost) < TemperatureBoostAmount * 0.9f;
|
||||
#endif
|
||||
|
||||
FissionRate = MathHelper.Lerp(fissionRate, Math.Min(TargetFissionRate, AvailableFuel), deltaTime);
|
||||
|
||||
@@ -438,7 +476,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private float GetGeneratedHeat(float fissionRate)
|
||||
{
|
||||
return fissionRate * (prevAvailableFuel / 100.0f) * 2.0f;
|
||||
return fissionRate * (prevAvailableFuel / 100.0f) * 2.0f + temperatureBoost;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -486,13 +524,15 @@ namespace Barotrauma.Items.Components
|
||||
if (temperature > allowedTemperature.Y)
|
||||
{
|
||||
item.SendSignal("1", "meltdown_warning");
|
||||
//faster meltdown if the item is in a bad condition
|
||||
meltDownTimer += MathHelper.Lerp(deltaTime * 2.0f, deltaTime, item.Condition / item.MaxCondition);
|
||||
|
||||
if (meltDownTimer > MeltdownDelay)
|
||||
if (!item.InvulnerableToDamage)
|
||||
{
|
||||
MeltDown();
|
||||
return;
|
||||
//faster meltdown if the item is in a bad condition
|
||||
meltDownTimer += MathHelper.Lerp(deltaTime * 2.0f, deltaTime, item.Condition / item.MaxCondition);
|
||||
if (meltDownTimer > MeltdownDelay)
|
||||
{
|
||||
MeltDown();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -505,7 +545,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
fireTimer += MathHelper.Lerp(deltaTime * 2.0f, deltaTime, item.Condition / item.MaxCondition);
|
||||
#if SERVER
|
||||
if (fireTimer > Math.Min(5.0f, FireDelay / 2) && blameOnBroken?.Character?.SelectedConstruction == item)
|
||||
if (fireTimer > Math.Min(5.0f, FireDelay / 2) && blameOnBroken?.Character?.SelectedItem == item)
|
||||
{
|
||||
GameMain.Server.KarmaManager.OnReactorOverHeating(item, blameOnBroken.Character, deltaTime);
|
||||
}
|
||||
@@ -705,7 +745,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (lastUser != null && lastUser != character && lastUser != LastAIUser)
|
||||
{
|
||||
if (lastUser.SelectedConstruction == item && character.IsOnPlayerTeam)
|
||||
if (lastUser.SelectedItem == item && character.IsOnPlayerTeam)
|
||||
{
|
||||
character.Speak(TextManager.Get("DialogReactorTaken").Value, null, 0.0f, "reactortaken".ToIdentifier(), 10.0f);
|
||||
}
|
||||
@@ -797,30 +837,31 @@ namespace Barotrauma.Items.Components
|
||||
AutoTemp = false;
|
||||
TargetFissionRate = 0.0f;
|
||||
TargetTurbineOutput = 0.0f;
|
||||
if (GameMain.NetworkMember?.IsServer ?? false) { unsentChanges = true; }
|
||||
registerUnsentChanges();
|
||||
}
|
||||
break;
|
||||
case "set_fissionrate":
|
||||
if (PowerOn && float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out float newFissionRate))
|
||||
{
|
||||
TargetFissionRate = MathHelper.Clamp(newFissionRate, 0.0f, 100.0f);
|
||||
if (GameMain.NetworkMember?.IsServer ?? false) { unsentChanges = true; }
|
||||
#if CLIENT
|
||||
FissionRateScrollBar.BarScroll = TargetFissionRate / 100.0f;
|
||||
#endif
|
||||
signalControlledTargetFissionRate = MathHelper.Clamp(newFissionRate, 0.0f, 100.0f);
|
||||
lastReceivedFissionRateSignalTime = Timing.TotalTime;
|
||||
registerUnsentChanges();
|
||||
}
|
||||
break;
|
||||
case "set_turbineoutput":
|
||||
if (PowerOn && float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out float newTurbineOutput))
|
||||
{
|
||||
TargetTurbineOutput = MathHelper.Clamp(newTurbineOutput, 0.0f, 100.0f);
|
||||
if (GameMain.NetworkMember?.IsServer ?? false) { unsentChanges = true; }
|
||||
#if CLIENT
|
||||
TurbineOutputScrollBar.BarScroll = TargetTurbineOutput / 100.0f;
|
||||
#endif
|
||||
signalControlledTargetTurbineOutput = MathHelper.Clamp(newTurbineOutput, 0.0f, 100.0f);
|
||||
lastReceivedTurbineOutputSignalTime = Timing.TotalTime;
|
||||
registerUnsentChanges();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
void registerUnsentChanges()
|
||||
{
|
||||
if (GameMain.NetworkMember is { IsServer: true }) { unsentChanges = true; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +64,8 @@ namespace Barotrauma.Items.Components
|
||||
private const float MinZoom = 1.0f, MaxZoom = 4.0f;
|
||||
private float zoom = 1.0f;
|
||||
|
||||
/// <remarks>Accessed through event actions. Do not remove even if there are no references in code.</remarks>
|
||||
public bool UseDirectionalPing => useDirectionalPing;
|
||||
private bool useDirectionalPing = false;
|
||||
private Vector2 pingDirection = new Vector2(1.0f, 0.0f);
|
||||
private bool useMineralScanner;
|
||||
@@ -113,13 +115,34 @@ namespace Barotrauma.Items.Components
|
||||
set;
|
||||
}
|
||||
|
||||
[Editable, Serialize(false, IsPropertySaveable.No, description: "Does the sonar have mineral scanning mode. " +
|
||||
"Only available in-game when the Item has no Steering component.")]
|
||||
public bool HasMineralScanner { get; set; }
|
||||
private bool hasMineralScanner;
|
||||
|
||||
[Editable, Serialize(false, IsPropertySaveable.No, description: "Does the sonar have mineral scanning mode. ")]
|
||||
public bool HasMineralScanner
|
||||
{
|
||||
get => hasMineralScanner;
|
||||
set
|
||||
{
|
||||
#if CLIENT
|
||||
if (controlContainer != null && !hasMineralScanner && value)
|
||||
{
|
||||
AddMineralScannerSwitchToGUI();
|
||||
}
|
||||
#endif
|
||||
hasMineralScanner = value;
|
||||
}
|
||||
}
|
||||
|
||||
public float Zoom
|
||||
{
|
||||
get { return zoom; }
|
||||
set
|
||||
{
|
||||
zoom = MathHelper.Clamp(value, MinZoom, MaxZoom);
|
||||
#if CLIENT
|
||||
zoomSlider.BarScroll = MathUtils.InverseLerp(MinZoom, MaxZoom, zoom);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public Mode CurrentMode
|
||||
@@ -144,8 +167,6 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
public override bool RecreateGUIOnResolutionChange => true;
|
||||
|
||||
public Sonar(Item item, ContentXElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
@@ -396,17 +417,17 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public void ServerEventWrite(IWriteMessage msg, Client c, NetEntityEvent.IData extraData = null)
|
||||
{
|
||||
msg.Write(currentMode == Mode.Active);
|
||||
msg.WriteBoolean(currentMode == Mode.Active);
|
||||
if (currentMode == Mode.Active)
|
||||
{
|
||||
msg.WriteRangedSingle(zoom, MinZoom, MaxZoom, 8);
|
||||
msg.Write(useDirectionalPing);
|
||||
msg.WriteBoolean(useDirectionalPing);
|
||||
if (useDirectionalPing)
|
||||
{
|
||||
float pingAngle = MathUtils.WrapAngleTwoPi(MathUtils.VectorToAngle(pingDirection));
|
||||
msg.WriteRangedSingle(MathUtils.InverseLerp(0.0f, MathHelper.TwoPi, pingAngle), 0.0f, 1.0f, 8);
|
||||
}
|
||||
msg.Write(useMineralScanner);
|
||||
msg.WriteBoolean(useMineralScanner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,8 +166,6 @@ namespace Barotrauma.Items.Components
|
||||
set { posToMaintain = value; }
|
||||
}
|
||||
|
||||
public override bool RecreateGUIOnResolutionChange => true;
|
||||
|
||||
struct ObstacleDebugInfo
|
||||
{
|
||||
public Vector2 Point1;
|
||||
@@ -301,7 +299,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
float userSkill = 0.0f;
|
||||
if (user != null && controlledSub != null &&
|
||||
(user.SelectedConstruction == item || item.linkedTo.Contains(user.SelectedConstruction)))
|
||||
(user.SelectedItem == item || item.linkedTo.Contains(user.SelectedItem)))
|
||||
{
|
||||
userSkill = user.GetSkillLevel("helm") / 100.0f;
|
||||
}
|
||||
@@ -333,7 +331,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
showIceSpireWarning = false;
|
||||
if (user != null && user.Info != null &&
|
||||
user.SelectedConstruction == item &&
|
||||
user.SelectedItem == item &&
|
||||
controlledSub != null && controlledSub.Velocity.LengthSquared() > 0.01f)
|
||||
{
|
||||
IncreaseSkillLevel(user, deltaTime);
|
||||
@@ -389,7 +387,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
// if our tactical AI pilot has left, revert back to maintaining position
|
||||
if (navigateTactically && (user == null || user.SelectedConstruction != item))
|
||||
if (navigateTactically && (user == null || user.SelectedItem != item))
|
||||
{
|
||||
navigateTactically = false;
|
||||
AIRamTimer = 0f;
|
||||
@@ -722,7 +720,7 @@ namespace Barotrauma.Items.Components
|
||||
character.AIController.SteeringManager.Reset();
|
||||
if (objective.Override)
|
||||
{
|
||||
if (user != character && user != null && user.SelectedConstruction == item && character.IsOnPlayerTeam)
|
||||
if (user != character && user != null && user.SelectedItem == item && character.IsOnPlayerTeam)
|
||||
{
|
||||
character.Speak(TextManager.Get("DialogSteeringTaken").Value, null, 0.0f, "steeringtaken".ToIdentifier(), 10.0f);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user