Build 0.18.4.0
This commit is contained in:
@@ -144,9 +144,16 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
public bool Combine(GeneticMaterial otherGeneticMaterial, Character user)
|
||||
public enum CombineResult
|
||||
{
|
||||
if (!CanBeCombinedWith(otherGeneticMaterial)) { return false; }
|
||||
None,
|
||||
Refined,
|
||||
Combined
|
||||
}
|
||||
|
||||
public CombineResult Combine(GeneticMaterial otherGeneticMaterial, Character user)
|
||||
{
|
||||
if (!CanBeCombinedWith(otherGeneticMaterial)) { return CombineResult.None; }
|
||||
|
||||
float conditionIncrease = Rand.Range(ConditionIncreaseOnCombineMin, ConditionIncreaseOnCombineMax);
|
||||
conditionIncrease += user?.GetStatValue(StatTypes.GeneticMaterialRefineBonus) ?? 0.0f;
|
||||
@@ -158,7 +165,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
MakeTainted();
|
||||
}
|
||||
return true;
|
||||
return CombineResult.Refined;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -171,7 +178,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
MakeTainted();
|
||||
}
|
||||
return false;
|
||||
return CombineResult.Combined;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -697,14 +697,17 @@ namespace Barotrauma.Items.Components
|
||||
Vector2 fromCharacterToLeak = leak.WorldPosition - character.AnimController.AimSourceWorldPos;
|
||||
float dist = fromCharacterToLeak.Length();
|
||||
float reach = AIObjectiveFixLeak.CalculateReach(this, character);
|
||||
|
||||
if (dist > reach * 3)
|
||||
if (dist > reach * 2)
|
||||
{
|
||||
// Too far away -> consider this done and hope the AI is smart enough to move closer
|
||||
Reset();
|
||||
return true;
|
||||
}
|
||||
character.AIController.SteeringManager.Reset();
|
||||
if (character.AIController.SteeringManager is IndoorsSteeringManager pathSteering)
|
||||
{
|
||||
pathSteering.ResetPath();
|
||||
}
|
||||
if (!character.AnimController.InWater)
|
||||
{
|
||||
// TODO: use the collider size?
|
||||
@@ -714,34 +717,25 @@ namespace Barotrauma.Items.Components
|
||||
humanAnim.Crouching = true;
|
||||
}
|
||||
}
|
||||
if (dist > reach * 0.8f || dist > reach * 0.5f && character.AnimController.Limbs.Any(l => l.InWater))
|
||||
if (!character.IsClimbing)
|
||||
{
|
||||
// Steer closer
|
||||
if (character.AIController.SteeringManager is IndoorsSteeringManager indoorSteering)
|
||||
if (dist > reach * 0.8f || dist > reach * 0.5f && character.AnimController.Limbs.Any(l => l.InWater))
|
||||
{
|
||||
// Swimming inside the sub
|
||||
if (indoorSteering.CurrentPath != null && !indoorSteering.IsPathDirty && (indoorSteering.CurrentPath.Unreachable || indoorSteering.CurrentPath.Finished))
|
||||
// Steer closer
|
||||
Vector2 dir = Vector2.Normalize(fromCharacterToLeak);
|
||||
if (!character.InWater)
|
||||
{
|
||||
Vector2 dir = Vector2.Normalize(fromCharacterToLeak);
|
||||
character.AIController.SteeringManager.SteeringManual(deltaTime, dir);
|
||||
}
|
||||
else
|
||||
{
|
||||
character.AIController.SteeringManager.SteeringSeek(character.GetRelativeSimPosition(leak));
|
||||
dir.Y = 0;
|
||||
}
|
||||
character.AIController.SteeringManager.SteeringManual(deltaTime, dir);
|
||||
}
|
||||
else
|
||||
else if (dist < reach * 0.25f && !character.IsClimbing)
|
||||
{
|
||||
// Swimming outside the sub
|
||||
character.AIController.SteeringManager.SteeringSeek(character.GetRelativeSimPosition(leak));
|
||||
// Too close -> steer away
|
||||
character.AIController.SteeringManager.SteeringManual(deltaTime, Vector2.Normalize(character.SimPosition - leak.SimPosition));
|
||||
}
|
||||
}
|
||||
else if (dist < reach * 0.25f)
|
||||
{
|
||||
// Too close -> steer away
|
||||
character.AIController.SteeringManager.SteeringManual(deltaTime, Vector2.Normalize(character.SimPosition - leak.SimPosition));
|
||||
}
|
||||
if (dist <= reach)
|
||||
if (dist <= reach || character.IsClimbing)
|
||||
{
|
||||
// In range
|
||||
character.CursorPosition = leak.WorldPosition;
|
||||
@@ -815,7 +809,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
bool leakFixed = (leak.Open <= 0.0f || leak.Removed) &&
|
||||
(leak.ConnectedWall == null || leak.ConnectedWall.Sections.Average(s => s.damage) < 1);
|
||||
(leak.ConnectedWall == null || leak.ConnectedWall.Sections.Max(s => s.damage) < 0.1f);
|
||||
|
||||
if (leakFixed && leak.FlowTargetHull?.DisplayName != null && character.IsOnPlayerTeam)
|
||||
{
|
||||
|
||||
@@ -187,7 +187,12 @@ namespace Barotrauma.Items.Components
|
||||
[Serialize(false, IsPropertySaveable.No)]
|
||||
public bool RemoveContainedItemsOnDeconstruct { get; set; }
|
||||
|
||||
private SlotRestrictions[] slotRestrictions;
|
||||
private readonly ImmutableArray<SlotRestrictions> slotRestrictions;
|
||||
|
||||
readonly List<ISerializableEntity> targets = new List<ISerializableEntity>();
|
||||
|
||||
private Vector2 prevContainedItemPositions;
|
||||
|
||||
|
||||
public bool ShouldBeContained(string[] identifiersOrTags, out bool isRestrictionsDefined)
|
||||
{
|
||||
@@ -237,10 +242,11 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
Inventory = new ItemInventory(item, this, totalCapacity, SlotsPerRow);
|
||||
slotRestrictions = new SlotRestrictions[totalCapacity];
|
||||
|
||||
List<SlotRestrictions> newSlotRestrictions = new List<SlotRestrictions>(totalCapacity);
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
slotRestrictions[i] = new SlotRestrictions(maxStackSize, ContainableItems);
|
||||
newSlotRestrictions.Add(new SlotRestrictions(maxStackSize, ContainableItems));
|
||||
}
|
||||
|
||||
int subContainerIndex = capacity;
|
||||
@@ -268,11 +274,13 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
for (int i = subContainerIndex; i < subContainerIndex + subCapacity; i++)
|
||||
{
|
||||
slotRestrictions[i] = new SlotRestrictions(subMaxStackSize, subContainableItems);
|
||||
newSlotRestrictions.Add(new SlotRestrictions(subMaxStackSize, subContainableItems));
|
||||
}
|
||||
subContainerIndex += subCapacity;
|
||||
}
|
||||
capacity = totalCapacity;
|
||||
slotRestrictions = newSlotRestrictions.ToImmutableArray();
|
||||
System.Diagnostics.Debug.Assert(totalCapacity == slotRestrictions.Length);
|
||||
InitProjSpecific(element);
|
||||
}
|
||||
|
||||
@@ -365,18 +373,21 @@ namespace Barotrauma.Items.Components
|
||||
return false;
|
||||
}
|
||||
|
||||
readonly List<ISerializableEntity> targets = new List<ISerializableEntity>();
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(SpawnWithId) && !alwaysContainedItemsSpawned)
|
||||
{
|
||||
SpawnAlwaysContainedItems();
|
||||
alwaysContainedItemsSpawned = true;
|
||||
}
|
||||
|
||||
if (item.ParentInventory is CharacterInventory ownerInventory)
|
||||
{
|
||||
item.SetContainedItemPositions();
|
||||
if (Vector2.DistanceSquared(prevContainedItemPositions, item.Position) > 10.0f)
|
||||
{
|
||||
SetContainedItemPositions();
|
||||
prevContainedItemPositions = item.Position;
|
||||
}
|
||||
|
||||
if (AutoInject)
|
||||
{
|
||||
@@ -397,7 +408,7 @@ namespace Barotrauma.Items.Components
|
||||
item.body.Enabled &&
|
||||
item.body.FarseerBody.Awake)
|
||||
{
|
||||
item.SetContainedItemPositions();
|
||||
SetContainedItemPositions();
|
||||
}
|
||||
else if (activeContainedItems.Count == 0)
|
||||
{
|
||||
|
||||
@@ -147,7 +147,7 @@ namespace Barotrauma.Items.Components
|
||||
CancelUsing(user);
|
||||
user = null;
|
||||
}
|
||||
if (!IsToggle) { IsActive = false; }
|
||||
if (!IsToggle || item.Connections == null) { IsActive = false; }
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+22
-10
@@ -231,28 +231,40 @@ namespace Barotrauma.Items.Components
|
||||
if (targetItem == otherItem) { continue; }
|
||||
if (deconstructProduct.RequiredOtherItem.Any(r => otherItem.HasTag(r) || r == otherItem.Prefab.Identifier))
|
||||
{
|
||||
user?.CheckTalents(AbilityEffectType.OnGeneticMaterialCombinedOrRefined);
|
||||
foreach (Character character in Character.GetFriendlyCrew(user))
|
||||
{
|
||||
character.CheckTalents(AbilityEffectType.OnCrewGeneticMaterialCombinedOrRefined);
|
||||
}
|
||||
|
||||
var geneticMaterial1 = targetItem.GetComponent<GeneticMaterial>();
|
||||
var geneticMaterial2 = otherItem.GetComponent<GeneticMaterial>();
|
||||
if (geneticMaterial1 != null && geneticMaterial2 != null)
|
||||
{
|
||||
if (geneticMaterial1.Combine(geneticMaterial2, user))
|
||||
var result = geneticMaterial1.Combine(geneticMaterial2, user);
|
||||
if (result == GeneticMaterial.CombineResult.Refined)
|
||||
{
|
||||
inputContainer.Inventory.RemoveItem(otherItem);
|
||||
OutputContainer.Inventory.RemoveItem(otherItem);
|
||||
Entity.Spawner.AddItemToRemoveQueue(otherItem);
|
||||
}
|
||||
if (result != GeneticMaterial.CombineResult.None)
|
||||
{
|
||||
OnCombinedOrRefined();
|
||||
}
|
||||
allowRemove = false;
|
||||
return;
|
||||
}
|
||||
inputContainer.Inventory.RemoveItem(otherItem);
|
||||
OutputContainer.Inventory.RemoveItem(otherItem);
|
||||
Entity.Spawner.AddItemToRemoveQueue(otherItem);
|
||||
else
|
||||
{
|
||||
inputContainer.Inventory.RemoveItem(otherItem);
|
||||
OutputContainer.Inventory.RemoveItem(otherItem);
|
||||
Entity.Spawner.AddItemToRemoveQueue(otherItem);
|
||||
OnCombinedOrRefined();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnCombinedOrRefined()
|
||||
{
|
||||
user?.CheckTalents(AbilityEffectType.OnGeneticMaterialCombinedOrRefined);
|
||||
foreach (Character character in Character.GetFriendlyCrew(user))
|
||||
{
|
||||
character.CheckTalents(AbilityEffectType.OnCrewGeneticMaterialCombinedOrRefined);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -400,8 +400,8 @@ namespace Barotrauma.Items.Components
|
||||
private void IncreaseSkillLevel(Character user, float deltaTime)
|
||||
{
|
||||
if (user?.Info == null) { return; }
|
||||
// Do not increase the helm skill when "steering" the sub in an outpost level
|
||||
if (GameMain.GameSession?.Campaign != null && Level.IsLoadedOutpost) { return; }
|
||||
// Do not increase the helm skill when "steering" the sub while docked into something static (e.g. outpost or wreck)
|
||||
if (GameMain.GameSession?.Campaign != null && controlledSub != null && controlledSub.DockedTo.Any(d => d.PhysicsBody.BodyType == BodyType.Static)) { return; }
|
||||
|
||||
float userSkill = Math.Max(user.GetSkillLevel("helm"), 1.0f) / 100.0f;
|
||||
user.Info.IncreaseSkillLevel(
|
||||
|
||||
@@ -3,7 +3,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
@@ -81,6 +80,8 @@ namespace Barotrauma.Items.Components
|
||||
private ItemContainer? container;
|
||||
private float growthTickTimer;
|
||||
|
||||
private List<LightComponent>? lightComponents;
|
||||
|
||||
public Planter(Item item, ContentXElement element) : base(item, element)
|
||||
{
|
||||
canBePicked = true;
|
||||
@@ -107,10 +108,14 @@ namespace Barotrauma.Items.Components
|
||||
base.OnItemLoaded();
|
||||
IsActive = true;
|
||||
#if CLIENT
|
||||
lightComponent = item.GetComponent<LightComponent>();
|
||||
if (lightComponent != null)
|
||||
var lights = item.GetComponents<LightComponent>();
|
||||
if (lights.Any())
|
||||
{
|
||||
lightComponent.Light.Enabled = false;
|
||||
lightComponents = lights.ToList();
|
||||
foreach (var light in lightComponents)
|
||||
{
|
||||
light.Light.Enabled = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
container = item.GetComponent<ItemContainer>();
|
||||
@@ -227,12 +232,17 @@ namespace Barotrauma.Items.Components
|
||||
base.Update(deltaTime, cam);
|
||||
|
||||
#if CLIENT
|
||||
if (lightComponent != null)
|
||||
if (lightComponents != null && lightComponents.Count > 0)
|
||||
{
|
||||
bool hasSeed = false;
|
||||
foreach (Growable? seed in GrowableSeeds) { hasSeed |= seed != null; }
|
||||
|
||||
lightComponent.Light.Enabled = hasSeed;
|
||||
foreach (Growable? seed in GrowableSeeds)
|
||||
{
|
||||
hasSeed |= seed != null;
|
||||
}
|
||||
foreach (var light in lightComponents)
|
||||
{
|
||||
light.Light.Enabled = hasSeed;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -602,7 +602,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private bool ShouldDeteriorate()
|
||||
{
|
||||
if (Level.IsLoadedOutpost) { return false; }
|
||||
if (Level.IsLoadedFriendlyOutpost) { return false; }
|
||||
|
||||
if (LastActiveTime > Timing.TotalTime) { return true; }
|
||||
foreach (ItemComponent ic in item.Components)
|
||||
|
||||
@@ -13,12 +13,13 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private float updateTimer;
|
||||
|
||||
[Flags]
|
||||
public enum TargetType
|
||||
{
|
||||
Any,
|
||||
Human,
|
||||
Monster,
|
||||
Wall
|
||||
Human = 1,
|
||||
Monster = 2,
|
||||
Wall = 4,
|
||||
Any = Human | Monster | Wall,
|
||||
}
|
||||
|
||||
[Serialize(false, IsPropertySaveable.No, description: "Has the item currently detected movement. Intended to be used by StatusEffect conditionals (setting this value in XML has no effect).")]
|
||||
@@ -179,6 +180,11 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (!string.IsNullOrEmpty(signalOut)) { item.SendSignal(new Signal(signalOut, 1), "state_out"); }
|
||||
|
||||
if (MotionDetected)
|
||||
{
|
||||
ApplyStatusEffects(ActionType.OnUse, deltaTime);
|
||||
}
|
||||
|
||||
updateTimer -= deltaTime;
|
||||
if (updateTimer > 0.0f) { return; }
|
||||
|
||||
@@ -199,8 +205,7 @@ namespace Barotrauma.Items.Components
|
||||
float broadRangeX = Math.Max(rangeX * 2, 500);
|
||||
float broadRangeY = Math.Max(rangeY * 2, 500);
|
||||
|
||||
if (item.CurrentHull == null && item.Submarine != null &&
|
||||
(Target == TargetType.Wall || Target == TargetType.Any))
|
||||
if (item.CurrentHull == null && item.Submarine != null && Target.HasFlag(TargetType.Wall))
|
||||
{
|
||||
if (Level.Loaded != null && (Math.Abs(item.Submarine.Velocity.X) > MinimumVelocity || Math.Abs(item.Submarine.Velocity.Y) > MinimumVelocity))
|
||||
{
|
||||
@@ -248,7 +253,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
if (Target != TargetType.Wall)
|
||||
if (Target.HasFlag(TargetType.Human) || Target.HasFlag(TargetType.Monster))
|
||||
{
|
||||
foreach (Character c in Character.CharacterList)
|
||||
{
|
||||
@@ -258,14 +263,13 @@ namespace Barotrauma.Items.Components
|
||||
//makes it possible to detect when a spawned character moves without triggering the detector immediately as the ragdoll spawns and drops to the ground
|
||||
if (c.SpawnTime > Timing.TotalTime - 1.0) { continue; }
|
||||
|
||||
switch (Target)
|
||||
if (c.IsHuman)
|
||||
{
|
||||
case TargetType.Human:
|
||||
if (!c.IsHuman) { continue; }
|
||||
break;
|
||||
case TargetType.Monster:
|
||||
if (c.IsHuman || c.IsPet) { continue; }
|
||||
break;
|
||||
if (!Target.HasFlag(TargetType.Human)) { continue; }
|
||||
}
|
||||
else if (!c.IsPet)
|
||||
{
|
||||
if (!Target.HasFlag(TargetType.Monster)) { continue; }
|
||||
}
|
||||
|
||||
//do a rough check based on the position of the character's collider first
|
||||
|
||||
@@ -4,6 +4,7 @@ using FarseerPhysics.Dynamics.Contacts;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
@@ -12,6 +13,46 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
[Editable, Serialize(0.0f, IsPropertySaveable.Yes, description: "The maximum amount of force applied to the triggering entitites.", alwaysUseInstanceValues: true)]
|
||||
public float Force { get; set; }
|
||||
[Editable, Serialize(false, IsPropertySaveable.Yes, description: "Determines if the force gets higher the closer the triggerer is to the center of the trigger.", alwaysUseInstanceValues: true)]
|
||||
public bool DistanceBasedForce { get; set; }
|
||||
[Editable, Serialize(false, IsPropertySaveable.Yes, description: "Determines if the force fluctuates over time or if it stays constant.", alwaysUseInstanceValues: true)]
|
||||
public bool ForceFluctuation { get; set; }
|
||||
[Serialize(1.0f, IsPropertySaveable.Yes, description: "How much the fluctuation affects the force. 1 is the maximum fluctuation, 0 is no fluctuation.", alwaysUseInstanceValues: true)]
|
||||
private float ForceFluctuationStrength
|
||||
{
|
||||
get
|
||||
{
|
||||
return forceFluctuationStrength;
|
||||
}
|
||||
set
|
||||
{
|
||||
forceFluctuationStrength = Math.Clamp(value, 0.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
[Serialize(1.0f, IsPropertySaveable.Yes, description: "How fast (cycles per second) the force fluctuates.", alwaysUseInstanceValues: true)]
|
||||
private float ForceFluctuationFrequency
|
||||
{
|
||||
get
|
||||
{
|
||||
return forceFluctuationFrequency;
|
||||
}
|
||||
set
|
||||
{
|
||||
forceFluctuationFrequency = Math.Max(value, 0.01f);
|
||||
}
|
||||
}
|
||||
[Serialize(0.01f, IsPropertySaveable.Yes, description: "How often (in seconds) the force fluctuation is calculated.", alwaysUseInstanceValues: true)]
|
||||
private float ForceFluctuationInterval
|
||||
{
|
||||
get
|
||||
{
|
||||
return forceFluctuationInterval;
|
||||
}
|
||||
set
|
||||
{
|
||||
forceFluctuationInterval = Math.Max(value, 0.01f);
|
||||
}
|
||||
}
|
||||
|
||||
public PhysicsBody PhysicsBody { get; private set; }
|
||||
private float Radius { get; set; }
|
||||
@@ -38,11 +79,6 @@ namespace Barotrauma.Items.Components
|
||||
private readonly LevelTrigger.TriggererType triggeredBy;
|
||||
private readonly HashSet<Entity> triggerers = new HashSet<Entity>();
|
||||
private readonly bool triggerOnce;
|
||||
private readonly bool distanceBasedForce;
|
||||
private readonly bool forceFluctuation;
|
||||
private readonly float forceFluctuationStrength;
|
||||
private readonly float forceFluctuationFrequency;
|
||||
private readonly float forceFluctuationInterval;
|
||||
private readonly List<ISerializableEntity> statusEffectTargets = new List<ISerializableEntity>();
|
||||
/// <summary>
|
||||
/// Effects applied to entities inside the trigger
|
||||
@@ -53,6 +89,10 @@ namespace Barotrauma.Items.Components
|
||||
/// </summary>
|
||||
private readonly List<Attack> attacks = new List<Attack>();
|
||||
|
||||
private float forceFluctuationStrength;
|
||||
private float forceFluctuationFrequency;
|
||||
private float forceFluctuationInterval;
|
||||
|
||||
public TriggerComponent(Item item, ContentXElement element) : base(item, element)
|
||||
{
|
||||
string triggeredByAttribute = element.GetAttributeString("triggeredby", "Character");
|
||||
@@ -61,15 +101,6 @@ namespace Barotrauma.Items.Components
|
||||
DebugConsole.ThrowError($"Error in ForceComponent config: \"{triggeredByAttribute}\" is not a valid triggerer type.");
|
||||
}
|
||||
triggerOnce = element.GetAttributeBool("triggeronce", false);
|
||||
distanceBasedForce = element.GetAttributeBool("distancebasedforce", false);
|
||||
forceFluctuation = element.GetAttributeBool("forcefluctuation", false);
|
||||
forceFluctuationStrength = element.GetAttributeFloat("forcefluctuationstrength", 1.0f);
|
||||
forceFluctuationStrength = Math.Clamp(forceFluctuationStrength, 0.0f, 1.0f);
|
||||
forceFluctuationFrequency = element.GetAttributeFloat("fluctuationfrequency", 1.0f);
|
||||
forceFluctuationFrequency = Math.Max(forceFluctuationFrequency, 0.01f);
|
||||
forceFluctuationInterval = element.GetAttributeFloat("fluctuationinterval", 0.01f);
|
||||
forceFluctuationInterval = Math.Max(forceFluctuationInterval, 0.01f);
|
||||
|
||||
string parentDebugName = $"TriggerComponent in {item.Name}";
|
||||
foreach (var subElement in element.Elements())
|
||||
{
|
||||
@@ -153,14 +184,14 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
TriggerActive = triggerers.Any();
|
||||
|
||||
if (forceFluctuation && TriggerActive && (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer))
|
||||
if (ForceFluctuation && TriggerActive && (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer))
|
||||
{
|
||||
ForceFluctuationTimer += deltaTime;
|
||||
if (ForceFluctuationTimer >= forceFluctuationInterval)
|
||||
if (ForceFluctuationTimer >= ForceFluctuationInterval)
|
||||
{
|
||||
float v = MathF.Sin(2 * MathF.PI * forceFluctuationFrequency * TimeInLevel);
|
||||
float v = MathF.Sin(2 * MathF.PI * ForceFluctuationFrequency * TimeInLevel);
|
||||
float amount = MathUtils.InverseLerp(-1.0f, 1.0f, v);
|
||||
CurrentForceFluctuation = MathHelper.Lerp(1.0f - forceFluctuationStrength, 1.0f, amount);
|
||||
CurrentForceFluctuation = MathHelper.Lerp(1.0f - ForceFluctuationStrength, 1.0f, amount);
|
||||
ForceFluctuationTimer = 0.0f;
|
||||
GameMain.NetworkMember?.CreateEntityEvent(this);
|
||||
}
|
||||
@@ -179,7 +210,7 @@ namespace Barotrauma.Items.Components
|
||||
LevelTrigger.ApplyAttacks(attacks, item.WorldPosition, deltaTime);
|
||||
}
|
||||
|
||||
if (Force < 0.01f)
|
||||
if (Math.Abs(Force) < 0.01f)
|
||||
{
|
||||
// Just ignore very minimal forces
|
||||
continue;
|
||||
@@ -205,7 +236,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
Vector2 diff = ConvertUnits.ToDisplayUnits(PhysicsBody.SimPosition - body.SimPosition);
|
||||
if (diff.LengthSquared() < 0.0001f) { return; }
|
||||
float distanceFactor = distanceBasedForce ? LevelTrigger.GetDistanceFactor(body, PhysicsBody, RadiusInDisplayUnits) : 1.0f;
|
||||
float distanceFactor = DistanceBasedForce ? LevelTrigger.GetDistanceFactor(body, PhysicsBody, RadiusInDisplayUnits) : 1.0f;
|
||||
if (distanceFactor <= 0.0f) { return; }
|
||||
Vector2 force = distanceFactor * (CurrentForceFluctuation * Force) * Vector2.Normalize(diff);
|
||||
if (force.LengthSquared() < 0.01f) { return; }
|
||||
@@ -227,5 +258,43 @@ namespace Barotrauma.Items.Components
|
||||
PhysicsBody.Submarine = item.Submarine;
|
||||
}
|
||||
}
|
||||
|
||||
public override void ReceiveSignal(Signal signal, Connection connection)
|
||||
{
|
||||
base.ReceiveSignal(signal, connection);
|
||||
switch (connection.Name)
|
||||
{
|
||||
case "set_force":
|
||||
if (!FloatTryParse(signal, out float force)) { break; }
|
||||
Force = force;
|
||||
break;
|
||||
case "set_distancebasedforce":
|
||||
if (!bool.TryParse(signal.value, out bool distanceBasedForce)) { break; }
|
||||
DistanceBasedForce = distanceBasedForce;
|
||||
break;
|
||||
case "set_forcefluctuation":
|
||||
if (!bool.TryParse(signal.value, out bool forceFluctuation)) { break; }
|
||||
ForceFluctuation = forceFluctuation;
|
||||
break;
|
||||
case "set_forcefluctuationstrength":
|
||||
if (!FloatTryParse(signal, out float forceFluctuationStrength)) { break; }
|
||||
ForceFluctuationStrength = forceFluctuationStrength;
|
||||
break;
|
||||
case "set_forcefluctuationfrequency":
|
||||
if (!FloatTryParse(signal, out float forceFluctuationFrequency)) { break; }
|
||||
ForceFluctuationFrequency = forceFluctuationFrequency;
|
||||
break;
|
||||
case "set_forcefluctuationinterval":
|
||||
if (!FloatTryParse(signal, out float forceFluctuationInterval)) { break; }
|
||||
ForceFluctuationInterval = forceFluctuationInterval;
|
||||
break;
|
||||
}
|
||||
|
||||
static bool FloatTryParse(Signal signal, out float value)
|
||||
{
|
||||
return float.TryParse(signal.value, NumberStyles.Any, CultureInfo.InvariantCulture, out value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,7 @@ using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Barotrauma.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
using FarseerPhysics.Dynamics;
|
||||
|
||||
@@ -20,8 +18,6 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private Vector2 barrelPos;
|
||||
private Vector2 transformedBarrelPos;
|
||||
|
||||
private LightComponent lightComponent;
|
||||
|
||||
private float rotation, targetRotation;
|
||||
|
||||
@@ -71,6 +67,8 @@ namespace Barotrauma.Items.Components
|
||||
public Character ActiveUser;
|
||||
private float resetActiveUserTimer;
|
||||
|
||||
private List<LightComponent> lightComponents;
|
||||
|
||||
public float Rotation
|
||||
{
|
||||
get { return rotation; }
|
||||
@@ -168,10 +166,13 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
rotation = (minRotation + maxRotation) / 2;
|
||||
#if CLIENT
|
||||
if (lightComponent != null)
|
||||
if (lightComponents != null)
|
||||
{
|
||||
lightComponent.Rotation = rotation;
|
||||
lightComponent.Light.Rotation = -rotation;
|
||||
foreach (var light in lightComponents)
|
||||
{
|
||||
light.Rotation = rotation;
|
||||
light.Light.Rotation = -rotation;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -331,27 +332,39 @@ namespace Barotrauma.Items.Components
|
||||
if (loadedRotationLimits.HasValue) { RotationLimits = loadedRotationLimits.Value; }
|
||||
if (loadedBaseRotation.HasValue) { BaseRotation = loadedBaseRotation.Value; }
|
||||
targetRotation = rotation;
|
||||
FindLightComponent();
|
||||
UpdateTransformedBarrelPos();
|
||||
}
|
||||
|
||||
private void FindLightComponent()
|
||||
private void FindLightComponents()
|
||||
{
|
||||
if (lightComponents != null)
|
||||
{
|
||||
// Can't run again, because of reparenting.
|
||||
return;
|
||||
}
|
||||
foreach (LightComponent lc in item.GetComponents<LightComponent>())
|
||||
{
|
||||
// Only make the Turret control the LightComponents that are it's children. So it'd be possible to for example have some extra lights on the turret that don't rotate with it.
|
||||
if (lc?.Parent == this)
|
||||
{
|
||||
lightComponent = lc;
|
||||
break;
|
||||
if (lightComponents == null)
|
||||
{
|
||||
lightComponents = new List<LightComponent>();
|
||||
}
|
||||
lightComponents.Add(lc);
|
||||
}
|
||||
}
|
||||
|
||||
#if CLIENT
|
||||
if (lightComponent != null)
|
||||
if (lightComponents != null)
|
||||
{
|
||||
lightComponent.Parent = null;
|
||||
lightComponent.Rotation = Rotation - item.RotationRad;
|
||||
lightComponent.Light.Rotation = -rotation;
|
||||
foreach (var light in lightComponents)
|
||||
{
|
||||
// We want the turret to control the state of the LightComponent, not tie it's state to the state of the Turret (the light can be inactive even if the turret is active)
|
||||
light.Parent = null;
|
||||
light.Rotation = Rotation - item.RotationRad;
|
||||
light.Light.Rotation = -rotation;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -428,7 +441,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (MathUtils.NearlyEqual(minRotation, maxRotation))
|
||||
{
|
||||
UpdateLightComponent();
|
||||
UpdateLightComponents();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -452,7 +465,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
// Do not increase the weapons skill when operating a turret in an outpost level
|
||||
if (user?.Info != null && (GameMain.GameSession?.Campaign == null || !Level.IsLoadedOutpost))
|
||||
if (user?.Info != null && (GameMain.GameSession?.Campaign == null || !Level.IsLoadedFriendlyOutpost))
|
||||
{
|
||||
user.Info.IncreaseSkillLevel("weapons".ToIdentifier(),
|
||||
SkillSettings.Current.SkillIncreasePerSecondWhenOperatingTurret * deltaTime / Math.Max(user.GetSkillLevel("weapons"), 1.0f));
|
||||
@@ -509,14 +522,17 @@ namespace Barotrauma.Items.Components
|
||||
aiFindTargetTimer -= deltaTime;
|
||||
}
|
||||
|
||||
UpdateLightComponent();
|
||||
UpdateLightComponents();
|
||||
}
|
||||
|
||||
private void UpdateLightComponent()
|
||||
private void UpdateLightComponents()
|
||||
{
|
||||
if (lightComponent != null)
|
||||
if (lightComponents != null)
|
||||
{
|
||||
lightComponent.Rotation = Rotation - item.RotationRad;
|
||||
foreach (var light in lightComponents)
|
||||
{
|
||||
light.Rotation = Rotation - item.RotationRad;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1601,21 +1617,24 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
break;
|
||||
case "toggle_light":
|
||||
if (lightComponent != null && signal.value != "0")
|
||||
if (lightComponents != null && signal.value != "0")
|
||||
{
|
||||
lightComponent.IsOn = !lightComponent.IsOn;
|
||||
UpdateLightComponent();
|
||||
foreach (var light in lightComponents)
|
||||
{
|
||||
light.IsOn = !light.IsOn;
|
||||
}
|
||||
UpdateLightComponents();
|
||||
}
|
||||
break;
|
||||
case "set_light":
|
||||
if (lightComponent != null)
|
||||
if (lightComponents != null)
|
||||
{
|
||||
bool shouldBeOn = signal.value != "0";
|
||||
if (shouldBeOn != lightComponent.IsOn)
|
||||
foreach (var light in lightComponents)
|
||||
{
|
||||
lightComponent.IsOn = shouldBeOn;
|
||||
UpdateLightComponent();
|
||||
light.IsOn = shouldBeOn;
|
||||
}
|
||||
UpdateLightComponents();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1633,7 +1652,7 @@ namespace Barotrauma.Items.Components
|
||||
public override void OnItemLoaded()
|
||||
{
|
||||
base.OnItemLoaded();
|
||||
FindLightComponent();
|
||||
FindLightComponents();
|
||||
targetRotation = rotation;
|
||||
if (!loadedBaseRotation.HasValue)
|
||||
{
|
||||
|
||||
@@ -6,7 +6,6 @@ using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.Items.Components;
|
||||
using Barotrauma.Networking;
|
||||
using System.Collections.Immutable;
|
||||
using Barotrauma.Abilities;
|
||||
|
||||
namespace Barotrauma
|
||||
@@ -82,7 +81,20 @@ namespace Barotrauma
|
||||
public string Sound { get; private set; }
|
||||
public Point? SheetIndex { get; private set; }
|
||||
|
||||
public LightComponent LightComponent { get; set; }
|
||||
public LightComponent LightComponent => LightComponents?.FirstOrDefault();
|
||||
|
||||
public List<LightComponent> LightComponents
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_lightComponents == null)
|
||||
{
|
||||
_lightComponents = new List<LightComponent>();
|
||||
}
|
||||
return _lightComponents;
|
||||
}
|
||||
}
|
||||
private List<LightComponent> _lightComponents;
|
||||
|
||||
public int Variant { get; set; }
|
||||
|
||||
@@ -338,11 +350,14 @@ namespace Barotrauma.Items.Components
|
||||
foreach (var lightElement in subElement.Elements())
|
||||
{
|
||||
if (!lightElement.Name.ToString().Equals("lightcomponent", StringComparison.OrdinalIgnoreCase)) { continue; }
|
||||
wearableSprites[i].LightComponent = new LightComponent(item, lightElement)
|
||||
wearableSprites[i].LightComponents.Add(new LightComponent(item, lightElement)
|
||||
{
|
||||
Parent = this
|
||||
};
|
||||
item.AddComponent(wearableSprites[i].LightComponent);
|
||||
});
|
||||
foreach (var light in wearableSprites[i].LightComponents)
|
||||
{
|
||||
item.AddComponent(light);
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
@@ -413,7 +428,10 @@ namespace Barotrauma.Items.Components
|
||||
IsActive = true;
|
||||
if (wearableSprite.LightComponent != null)
|
||||
{
|
||||
wearableSprite.LightComponent.ParentBody = equipLimb.body;
|
||||
foreach (var light in wearableSprite.LightComponents)
|
||||
{
|
||||
light.ParentBody = equipLimb.body;
|
||||
}
|
||||
}
|
||||
|
||||
limb[i] = equipLimb;
|
||||
@@ -467,7 +485,10 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (wearableSprites[i].LightComponent != null)
|
||||
{
|
||||
wearableSprites[i].LightComponent.ParentBody = null;
|
||||
foreach (var light in wearableSprites[i].LightComponents)
|
||||
{
|
||||
light.ParentBody = null;
|
||||
}
|
||||
}
|
||||
|
||||
equipLimb.WearingItems.RemoveAll(w => w != null && w == wearableSprites[i]);
|
||||
@@ -494,7 +515,6 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
item.SetTransform(picker.SimPosition, 0.0f);
|
||||
item.SetContainedItemPositions();
|
||||
|
||||
item.ApplyStatusEffects(ActionType.OnWearing, deltaTime, picker);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user