v0.11.0.9
This commit is contained in:
@@ -318,16 +318,12 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (!character.IsRemotePlayer || character.ViewTarget == focusTarget)
|
||||
{
|
||||
Vector2 centerPos = new Vector2(item.WorldRect.Center.X, item.WorldRect.Center.Y);
|
||||
Vector2 centerPos = new Vector2(focusTarget.WorldRect.Center.X, focusTarget.WorldRect.Center.Y);
|
||||
|
||||
Item targetItem = focusTarget as Item;
|
||||
if (targetItem != null)
|
||||
Turret turret = focusTarget.GetComponent<Turret>();
|
||||
if (turret != null)
|
||||
{
|
||||
Turret turret = targetItem.GetComponent<Turret>();
|
||||
if (turret != null)
|
||||
{
|
||||
centerPos = new Vector2(targetItem.WorldRect.X + turret.TransformedBarrelPos.X, targetItem.WorldRect.Y - turret.TransformedBarrelPos.Y);
|
||||
}
|
||||
centerPos = new Vector2(focusTarget.WorldRect.X + turret.TransformedBarrelPos.X, focusTarget.WorldRect.Y - turret.TransformedBarrelPos.Y);
|
||||
}
|
||||
|
||||
Vector2 offset = character.CursorWorldPosition - centerPos;
|
||||
@@ -356,6 +352,9 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public override bool Pick(Character picker)
|
||||
{
|
||||
#if CLIENT
|
||||
if (Screen.Selected == GameMain.SubEditorScreen) { return false; }
|
||||
#endif
|
||||
if (IsToggle)
|
||||
{
|
||||
if (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer)
|
||||
|
||||
@@ -123,7 +123,7 @@ namespace Barotrauma.Items.Components
|
||||
//drop all items that are inside the deconstructed item
|
||||
foreach (ItemContainer ic in targetItem.GetComponents<ItemContainer>())
|
||||
{
|
||||
if (ic?.Inventory?.Items == null) { continue; }
|
||||
if (ic?.Inventory?.Items == null || ic.RemoveContainedItemsOnDeconstruct) { continue; }
|
||||
foreach (Item containedItem in ic.Inventory.Items)
|
||||
{
|
||||
containedItem?.Drop(dropper: null, createNetworkEvent: true);
|
||||
|
||||
@@ -113,7 +113,7 @@ namespace Barotrauma.Items.Components
|
||||
forceMultiplier *= MathHelper.Lerp(0.5f, 2.0f, (float)Math.Sqrt(User.GetSkillLevel("helm") / 100));
|
||||
}
|
||||
|
||||
float voltageFactor = MinVoltage <= 0.0f ? 1.0f : Math.Min(Voltage / MinVoltage, 1.0f);
|
||||
float voltageFactor = MinVoltage <= 0.0f ? 1.0f : Math.Min(Voltage, 1.0f);
|
||||
Vector2 currForce = new Vector2(force * maxForce * forceMultiplier * voltageFactor, 0.0f);
|
||||
//less effective when in a bad condition
|
||||
currForce *= MathHelper.Lerp(0.5f, 2.0f, item.Condition / item.MaxCondition);
|
||||
@@ -121,7 +121,7 @@ namespace Barotrauma.Items.Components
|
||||
UpdatePropellerDamage(deltaTime);
|
||||
float maxChangeSpeed = 0.5f;
|
||||
float modifier = 2;
|
||||
float noise = currForce.Length() * forceMultiplier * modifier / maxForce;
|
||||
float noise = MathUtils.NearlyEqual(0.0f, maxForce) ? 0.0f : currForce.Length() * forceMultiplier * modifier / maxForce;
|
||||
float min = Math.Max(1 - maxChangeSpeed, 0);
|
||||
float max = 1 + maxChangeSpeed;
|
||||
UpdateAITargets(Math.Clamp(noise, min, max), deltaTime);
|
||||
|
||||
@@ -482,9 +482,9 @@ namespace Barotrauma.Items.Components
|
||||
return componentElement;
|
||||
}
|
||||
|
||||
public override void Load(XElement componentElement, bool usePrefabValues)
|
||||
public override void Load(XElement componentElement, bool usePrefabValues, IdRemap idRemap)
|
||||
{
|
||||
base.Load(componentElement, usePrefabValues);
|
||||
base.Load(componentElement, usePrefabValues, idRemap);
|
||||
savedFabricatedItem = componentElement.GetAttributeString("fabricateditemidentifier", "");
|
||||
savedTimeUntilReady = componentElement.GetAttributeFloat("savedtimeuntilready", 0.0f);
|
||||
savedRequiredTime = componentElement.GetAttributeFloat("savedrequiredtime", 0.0f);
|
||||
|
||||
+17
-23
@@ -8,11 +8,10 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
class OxygenGenerator : Powered
|
||||
{
|
||||
private float powerDownTimer;
|
||||
|
||||
private float generatedAmount;
|
||||
|
||||
private List<Vent> ventList;
|
||||
//key = vent, float = total volume of the hull the vent is in and the hulls connected to it
|
||||
private Dictionary<Vent, float> ventList;
|
||||
|
||||
private float totalHullVolume;
|
||||
|
||||
@@ -49,17 +48,12 @@ namespace Barotrauma.Items.Components
|
||||
Voltage = 1.0f;
|
||||
}
|
||||
|
||||
if (item.CurrentHull == null) return;
|
||||
if (item.CurrentHull == null) { return; }
|
||||
|
||||
if (Voltage < MinVoltage)
|
||||
{
|
||||
powerDownTimer += deltaTime;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
powerDownTimer = 0.0f;
|
||||
}
|
||||
|
||||
CurrFlow = Math.Min(Voltage, 1.0f) * generatedAmount * 100.0f;
|
||||
|
||||
@@ -76,24 +70,25 @@ namespace Barotrauma.Items.Components
|
||||
public override void UpdateBroken(float deltaTime, Camera cam)
|
||||
{
|
||||
base.UpdateBroken(deltaTime, cam);
|
||||
powerDownTimer += deltaTime;
|
||||
CurrFlow = 0.0f;
|
||||
}
|
||||
|
||||
private void GetVents()
|
||||
{
|
||||
ventList.Clear();
|
||||
|
||||
ventList = new Dictionary<Vent, float>();
|
||||
foreach (MapEntity entity in item.linkedTo)
|
||||
{
|
||||
Item linkedItem = entity as Item;
|
||||
if (linkedItem == null) continue;
|
||||
if (!(entity is Item linkedItem)) { continue; }
|
||||
|
||||
Vent vent = linkedItem.GetComponent<Vent>();
|
||||
if (vent == null) continue;
|
||||
if (vent?.Item.CurrentHull == null) { continue; }
|
||||
|
||||
ventList.Add(vent);
|
||||
if (linkedItem.CurrentHull != null) totalHullVolume += linkedItem.CurrentHull.Volume;
|
||||
ventList.Add(vent, 0.0f);
|
||||
foreach (Hull connectedHull in vent.Item.CurrentHull.GetConnectedHulls(includingThis: true, searchDepth: 10, ignoreClosedGaps: true))
|
||||
{
|
||||
totalHullVolume += connectedHull.Volume;
|
||||
ventList[vent] += connectedHull.Volume;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,18 +96,17 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (ventList == null)
|
||||
{
|
||||
ventList = new List<Vent>();
|
||||
GetVents();
|
||||
}
|
||||
|
||||
if (!ventList.Any() || totalHullVolume <= 0.0f) return;
|
||||
if (!ventList.Any() || totalHullVolume <= 0.0f) { return; }
|
||||
|
||||
foreach (Vent v in ventList)
|
||||
foreach (KeyValuePair<Vent, float> v in ventList)
|
||||
{
|
||||
if (v.Item.CurrentHull == null) continue;
|
||||
if (v.Key?.Item.CurrentHull == null) { continue; }
|
||||
|
||||
v.OxygenFlow = deltaOxygen * (v.Item.CurrentHull.Volume / totalHullVolume);
|
||||
v.IsActive = true;
|
||||
v.Key.OxygenFlow = deltaOxygen * (v.Value / totalHullVolume);
|
||||
v.Key.IsActive = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.MapCreatures.Behavior;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
@@ -11,10 +13,38 @@ namespace Barotrauma.Items.Components
|
||||
private float flowPercentage;
|
||||
private float maxFlow;
|
||||
|
||||
private float? targetLevel;
|
||||
public float? TargetLevel;
|
||||
|
||||
private bool hijacked;
|
||||
public bool Hijacked
|
||||
{
|
||||
get { return hijacked; }
|
||||
set
|
||||
{
|
||||
if (value == hijacked) { return; }
|
||||
hijacked = value;
|
||||
#if SERVER
|
||||
item.CreateServerEvent(this);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
private float pumpSpeedLockTimer, isActiveLockTimer;
|
||||
|
||||
private bool infected;
|
||||
|
||||
[Serialize(false, true, description: "Whether or not the pump is infected with ballast flora spores.")]
|
||||
public bool Infected
|
||||
{
|
||||
get => infected;
|
||||
set
|
||||
{
|
||||
infected = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string InfectIdentifier;
|
||||
|
||||
[Serialize(0.0f, true, description: "How fast the item is currently pumping water (-100 = full speed out, 100 = full speed in). Intended to be used by StatusEffect conditionals (setting this value in XML has no effect).")]
|
||||
public float FlowPercentage
|
||||
{
|
||||
@@ -66,12 +96,12 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
currFlow = 0.0f;
|
||||
|
||||
if (targetLevel != null)
|
||||
if (TargetLevel != null)
|
||||
{
|
||||
pumpSpeedLockTimer -= deltaTime;
|
||||
float hullPercentage = 0.0f;
|
||||
if (item.CurrentHull != null) { hullPercentage = (item.CurrentHull.WaterVolume / item.CurrentHull.Volume) * 100.0f; }
|
||||
FlowPercentage = ((float)targetLevel - hullPercentage) * 10.0f;
|
||||
FlowPercentage = ((float)TargetLevel - hullPercentage) * 10.0f;
|
||||
}
|
||||
|
||||
currPowerConsumption = powerConsumption * Math.Abs(flowPercentage / 100.0f);
|
||||
@@ -92,14 +122,41 @@ namespace Barotrauma.Items.Components
|
||||
//less effective when in a bad condition
|
||||
currFlow *= MathHelper.Lerp(0.5f, 1.0f, item.Condition / item.MaxCondition);
|
||||
|
||||
|
||||
if (currFlow < 0 && Infected)
|
||||
{
|
||||
InfectBallast(InfectIdentifier);
|
||||
}
|
||||
Infected = false;
|
||||
|
||||
item.CurrentHull.WaterVolume += currFlow;
|
||||
if (item.CurrentHull.WaterVolume > item.CurrentHull.Volume) { item.CurrentHull.Pressure += 0.5f; }
|
||||
}
|
||||
|
||||
public void InfectBallast(string identifier)
|
||||
{
|
||||
Hull hull = item.CurrentHull;
|
||||
if (hull == null) { return; }
|
||||
|
||||
// if the ship is already infected then do nothing
|
||||
if (Hull.hullList.Where(h => h.Submarine == hull.Submarine).Any(h => h.BallastFlora != null)) { return; }
|
||||
|
||||
if (hull.BallastFlora != null) { return; }
|
||||
|
||||
Vector2 offset = item.WorldPosition - hull.WorldPosition;
|
||||
hull.BallastFlora = new BallastFloraBehavior(hull, BallastFloraPrefab.Find(identifier), offset, firstGrowth: true);
|
||||
|
||||
#if SERVER
|
||||
hull.BallastFlora.SendNetworkMessage(hull.BallastFlora, BallastFloraBehavior.NetworkHeader.Spawn);
|
||||
#endif
|
||||
}
|
||||
|
||||
partial void UpdateProjSpecific(float deltaTime);
|
||||
|
||||
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
|
||||
{
|
||||
if (Hijacked) { return; }
|
||||
|
||||
if (connection.Name == "toggle")
|
||||
{
|
||||
IsActive = !IsActive;
|
||||
@@ -115,7 +172,7 @@ namespace Barotrauma.Items.Components
|
||||
if (float.TryParse(signal, NumberStyles.Any, CultureInfo.InvariantCulture, out float tempSpeed))
|
||||
{
|
||||
flowPercentage = MathHelper.Clamp(tempSpeed, -100.0f, 100.0f);
|
||||
targetLevel = null;
|
||||
TargetLevel = null;
|
||||
pumpSpeedLockTimer = 0.1f;
|
||||
}
|
||||
}
|
||||
@@ -123,7 +180,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (float.TryParse(signal, NumberStyles.Any, CultureInfo.InvariantCulture, out float tempTarget))
|
||||
{
|
||||
targetLevel = MathHelper.Clamp(tempTarget + 50.0f, 0.0f, 100.0f);
|
||||
TargetLevel = MathHelper.Clamp(tempTarget + 50.0f, 0.0f, 100.0f);
|
||||
pumpSpeedLockTimer = 0.1f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
[Serialize(0.2f, true, description: "How fast the condition of the contained fuel rods deteriorates per second."), Editable(0.0f, 1000.0f)]
|
||||
[Serialize(0.2f, true, description: "How fast the condition of the contained fuel rods deteriorates per second."), Editable(0.0f, 1000.0f, decimals: 3)]
|
||||
public float FuelConsumptionRate
|
||||
{
|
||||
get { return fuelConsumptionRate; }
|
||||
@@ -399,6 +399,8 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
//fission rate is clamped to the amount of available fuel
|
||||
float maxFissionRate = Math.Min(prevAvailableFuel, 100.0f);
|
||||
if (maxFissionRate >= 100.0f) { return false; }
|
||||
|
||||
float maxTurbineOutput = 100.0f;
|
||||
|
||||
//calculate the maximum output if the fission rate is cranked as high as it goes and turbine output is at max
|
||||
@@ -589,7 +591,7 @@ namespace Barotrauma.Items.Components
|
||||
if (objective.SubObjectives.None())
|
||||
{
|
||||
int itemCount = item.ContainedItems.Count(i => i != null && container.ContainableItems.Any(ri => ri.MatchesItem(i))) + 1;
|
||||
AIContainItems<Reactor>(container, character, objective, itemCount, equip: false, removeEmpty: true, spawnItemIfNotFound: character.TeamID == Character.TeamType.FriendlyNPC);
|
||||
AIContainItems<Reactor>(container, character, objective, itemCount, equip: false, removeEmpty: true, spawnItemIfNotFound: character.TeamID == Character.TeamType.FriendlyNPC, dropItemOnDeselected: true);
|
||||
character.Speak(TextManager.Get("DialogReactorFuel"), null, 0.0f, "reactorfuel", 30.0f);
|
||||
}
|
||||
return false;
|
||||
@@ -604,10 +606,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (item != null && container.ContainableItems.Any(ri => ri.MatchesItem(item)))
|
||||
{
|
||||
if (!character.Inventory.TryPutItem(item, character, allowedSlots: item.AllowedSlots))
|
||||
{
|
||||
item.Drop(character);
|
||||
}
|
||||
item.Drop(character);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private bool useDirectionalPing = false;
|
||||
private Vector2 pingDirection = new Vector2(1.0f, 0.0f);
|
||||
private bool useMineralScanner;
|
||||
|
||||
private bool aiPingCheckPending;
|
||||
|
||||
@@ -103,6 +104,10 @@ namespace Barotrauma.Items.Components
|
||||
set;
|
||||
}
|
||||
|
||||
[Editable, Serialize(false, false, description: "Does the sonar have mineral scanning mode. " +
|
||||
"Only available in-game when the Item has no Steering component.")]
|
||||
public bool HasMineralScanner { get; set; }
|
||||
|
||||
public float Zoom
|
||||
{
|
||||
get { return zoom; }
|
||||
@@ -343,6 +348,7 @@ namespace Barotrauma.Items.Components
|
||||
bool isActive = msg.ReadBoolean();
|
||||
bool directionalPing = useDirectionalPing;
|
||||
float zoomT = zoom, pingDirectionT = 0.0f;
|
||||
bool mineralScanner = useMineralScanner;
|
||||
if (isActive)
|
||||
{
|
||||
zoomT = msg.ReadRangedSingle(0.0f, 1.0f, 8);
|
||||
@@ -351,6 +357,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
pingDirectionT = msg.ReadRangedSingle(0.0f, 1.0f, 8);
|
||||
}
|
||||
mineralScanner = msg.ReadBoolean();
|
||||
}
|
||||
|
||||
if (!item.CanClientAccess(c)) { return; }
|
||||
@@ -366,9 +373,14 @@ namespace Barotrauma.Items.Components
|
||||
float pingAngle = MathHelper.Lerp(0.0f, MathHelper.TwoPi, pingDirectionT);
|
||||
pingDirection = new Vector2((float)Math.Cos(pingAngle), (float)Math.Sin(pingAngle));
|
||||
}
|
||||
useMineralScanner = mineralScanner;
|
||||
#if CLIENT
|
||||
zoomSlider.BarScroll = zoomT;
|
||||
directionalModeSwitch.Selected = useDirectionalPing;
|
||||
if (mineralScannerSwitch != null)
|
||||
{
|
||||
mineralScannerSwitch.Selected = useMineralScanner;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if SERVER
|
||||
@@ -388,6 +400,7 @@ namespace Barotrauma.Items.Components
|
||||
float pingAngle = MathUtils.WrapAngleTwoPi(MathUtils.VectorToAngle(pingDirection));
|
||||
msg.WriteRangedSingle(MathUtils.InverseLerp(0.0f, MathHelper.TwoPi, pingAngle), 0.0f, 1.0f, 8);
|
||||
}
|
||||
msg.Write(useMineralScanner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,10 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (pathFinder == null)
|
||||
{
|
||||
pathFinder = new PathFinder(WayPoint.WayPointList, false);
|
||||
pathFinder = new PathFinder(WayPoint.WayPointList, false)
|
||||
{
|
||||
GetNodePenalty = GetNodePenalty
|
||||
};
|
||||
}
|
||||
MaintainPos = true;
|
||||
if (posToMaintain == null)
|
||||
@@ -87,7 +90,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
[Editable(0.0f, 1.0f, decimals: 3),
|
||||
[Editable(0.0f, 1.0f, decimals: 4),
|
||||
Serialize(0.5f, true, description: "How full the ballast tanks should be when the submarine is not being steered upwards/downwards."
|
||||
+ " Can be used to compensate if the ballast tanks are too large/small relative to the size of the submarine.")]
|
||||
public float NeutralBallastLevel
|
||||
@@ -417,6 +420,7 @@ namespace Barotrauma.Items.Components
|
||||
Math.Max(1000.0f * Math.Abs(controlledSub.Velocity.Y), controlledSub.Borders.Height * 0.75f));
|
||||
|
||||
float avoidRadius = avoidDist.Length();
|
||||
float damagingWallAvoidRadius = avoidRadius * 1.5f;
|
||||
|
||||
Vector2 newAvoidStrength = Vector2.Zero;
|
||||
|
||||
@@ -426,12 +430,26 @@ namespace Barotrauma.Items.Components
|
||||
var closeCells = Level.Loaded.GetCells(controlledSub.WorldPosition, 4);
|
||||
foreach (VoronoiCell cell in closeCells)
|
||||
{
|
||||
if (cell.DoesDamage)
|
||||
{
|
||||
foreach (GraphEdge edge in cell.Edges)
|
||||
{
|
||||
Vector2 closestPoint = MathUtils.GetClosestPointOnLineSegment(edge.Point1 + cell.Translation, edge.Point2 + cell.Translation, controlledSub.WorldPosition);
|
||||
float dist = Vector2.Distance(closestPoint, controlledSub.WorldPosition);
|
||||
if (dist > damagingWallAvoidRadius) { continue; }
|
||||
Vector2 diff = controlledSub.WorldPosition - cell.Center;
|
||||
Vector2 avoid = Vector2.Normalize(diff) * (damagingWallAvoidRadius - dist) / damagingWallAvoidRadius;
|
||||
newAvoidStrength += avoid;
|
||||
debugDrawObstacles.Add(new ObstacleDebugInfo(edge, edge.Center, 1.0f, avoid, cell.Translation));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (GraphEdge edge in cell.Edges)
|
||||
{
|
||||
if (MathUtils.GetLineIntersection(edge.Point1 + cell.Translation, edge.Point2 + cell.Translation, controlledSub.WorldPosition, cell.Center, out Vector2 intersection))
|
||||
{
|
||||
Vector2 diff = controlledSub.WorldPosition - intersection;
|
||||
|
||||
//far enough -> ignore
|
||||
if (Math.Abs(diff.X) > avoidDist.X && Math.Abs(diff.Y) > avoidDist.Y)
|
||||
{
|
||||
@@ -497,6 +515,15 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
private float? GetNodePenalty(PathNode node, PathNode nextNode)
|
||||
{
|
||||
if (node.Waypoint?.Tunnel == null || controlledSub == null || node.Waypoint.Tunnel.Type == Level.TunnelType.MainPath) { return 0.0f; }
|
||||
//never navigate from the main path to another type of path
|
||||
if (node.Waypoint.Tunnel.Type == Level.TunnelType.MainPath && nextNode.Waypoint?.Tunnel?.Type != Level.TunnelType.MainPath) { return null; }
|
||||
//higher cost for side paths (= autopilot prefers the main path, but can still navigate side paths if it ends up on one)
|
||||
return 1000.0f;
|
||||
}
|
||||
|
||||
private void UpdatePath()
|
||||
{
|
||||
if (Level.Loaded == null) { return; }
|
||||
|
||||
@@ -13,11 +13,7 @@ namespace Barotrauma.Items.Components
|
||||
set { oxygenFlow = Math.Max(value, 0.0f); }
|
||||
}
|
||||
|
||||
public Vent (Item item, XElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
|
||||
}
|
||||
public Vent (Item item, XElement element) : base(item, element) { }
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user