v1.7.7.0 (Winter Update 2024)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using Barotrauma.Extensions;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
@@ -21,6 +21,8 @@ namespace Barotrauma
|
||||
public float ActualMaxDifficulty => maxDifficulty;
|
||||
public float AdjustedMaxDifficulty => maxDifficulty - 0.1f;
|
||||
|
||||
public readonly float ExperienceFromMissionRewards;
|
||||
|
||||
|
||||
public readonly ImmutableHashSet<int> AllowedZones;
|
||||
|
||||
@@ -50,6 +52,10 @@ namespace Barotrauma
|
||||
AllowedZones = element.GetAttributeIntArray("AllowedZones", new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }).ToImmutableHashSet();
|
||||
MinDifficulty = element.GetAttributeFloat("MinDifficulty", 0);
|
||||
maxDifficulty = element.GetAttributeFloat("MaxDifficulty", 100);
|
||||
float baseExperience = 0.09f;
|
||||
float difficultyRewardMultiplier = 0.25f;
|
||||
float calculateDefaultExperience = baseExperience + MinDifficulty * difficultyRewardMultiplier / 100;
|
||||
ExperienceFromMissionRewards = element.GetAttributeFloat("ExperienceFromMissionRewards", calculateDefaultExperience);
|
||||
|
||||
var submarineAvailabilityOverrides = new HashSet<SubmarineAvailability>();
|
||||
if (element.GetChildElement("submarines") is ContentXElement availabilityElement)
|
||||
|
||||
@@ -217,8 +217,13 @@ namespace Barotrauma
|
||||
/// Makes the cell rounder by subdividing the edges and offsetting them at the middle
|
||||
/// </summary>
|
||||
/// <param name="minEdgeLength">How small the individual subdivided edges can be (smaller values produce rounder shapes, but require more geometry)</param>
|
||||
public static void RoundCell(VoronoiCell cell, float minEdgeLength = 500.0f, float roundingAmount = 0.5f, float irregularity = 0.1f)
|
||||
/// <param name="minThickness">How "thin" irregularity is allowed to make parts of the cell. Very high irregularity values can lead to thin "spikes" or even parts where the "spike's" thickness becomes negative and wall segments intersect each other.</param>
|
||||
public static void RoundCell(VoronoiCell cell, float minEdgeLength = 500.0f, float roundingAmount = 0.5f, float irregularity = 0.1f, float minThickness = 0.0f)
|
||||
{
|
||||
//we need to make sure the vertices of the wall are still ordered counter-clockwise -
|
||||
//if we deform some vertices so much the cell becomes concave, rendering the triangles will break (parts of the inside of the wall will render outside the edges)
|
||||
var compareCCW = new CompareCCW(cell.Center);
|
||||
|
||||
List<GraphEdge> tempEdges = new List<GraphEdge>();
|
||||
foreach (GraphEdge edge in cell.Edges)
|
||||
{
|
||||
@@ -231,8 +236,10 @@ namespace Barotrauma
|
||||
Vector2 edgeDiff = edge.Point2 - edge.Point1;
|
||||
Vector2 edgeDir = Vector2.Normalize(edgeDiff);
|
||||
|
||||
float maxExtrusion = float.PositiveInfinity;
|
||||
const float minPassageWidth = 200.0f;
|
||||
//If the edge is next to an empty cell and there's another solid cell at the other side of the empty one,
|
||||
//don't touch this edge. Otherwise we may end up closing off small passages between cells.
|
||||
//we need to calculate how far we can extrude the edge so it doesn't end up closing off small passages between cells.
|
||||
var adjacentEmptyCell = edge.AdjacentCell(cell);
|
||||
if (adjacentEmptyCell?.CellType == CellType.Solid) { adjacentEmptyCell = null; }
|
||||
if (adjacentEmptyCell != null)
|
||||
@@ -252,8 +259,15 @@ namespace Barotrauma
|
||||
}
|
||||
if (adjacentEdge != null)
|
||||
{
|
||||
tempEdges.Add(edge);
|
||||
continue;
|
||||
maxExtrusion =
|
||||
new[]
|
||||
{
|
||||
Vector2.Distance(edge.Point1, adjacentEdge.Point1),
|
||||
Vector2.Distance(edge.Point1, adjacentEdge.Point2),
|
||||
Vector2.Distance(edge.Point1, adjacentEdge.Point2),
|
||||
Vector2.Distance(edge.Point2, adjacentEdge.Point1),
|
||||
}.Min();
|
||||
maxExtrusion = Math.Max(0, maxExtrusion - minPassageWidth);
|
||||
}
|
||||
}
|
||||
List<Vector2> edgePoints = new List<Vector2>();
|
||||
@@ -274,12 +288,53 @@ namespace Barotrauma
|
||||
else
|
||||
{
|
||||
|
||||
//value that's 0 at edges, 0.5 at center
|
||||
float centerF = 0.5f - Math.Abs(0.5f - (i / (float)pointCount));
|
||||
float randomVariance = Rand.Range(0, irregularity, Rand.RandSync.ServerAndClient);
|
||||
Vector2 extrudedPoint =
|
||||
//make the value "curve" from 0 to 1 at the center, instead of going linearly from 0 to 1
|
||||
centerF = MathF.Sin(centerF * MathHelper.Pi);
|
||||
|
||||
//magic number intended to make old rounding values behave roughly the same with the new formula
|
||||
//previously the extrusion increased linearly towards the center, forming a "spike" like "/\"
|
||||
//now it follows a sine curve, which makes lower values produce rounder results
|
||||
const float RoundingScale = 0.25f;
|
||||
|
||||
//magic number intended to make old variance values behave roughly the same with the new formula
|
||||
//previously a value of 1 would allow a maximum extrusion of 50% of the edge's length at the center,
|
||||
//now we extrude by the variance at any point on the edge (not more in the center)
|
||||
const float RandomVarianceScale = 0.25f;
|
||||
float randomVariance = irregularity * Rand.Range(-0.5f, 0.5f, Rand.RandSync.ServerAndClient);
|
||||
|
||||
float extrusionAmount = edgeLength * ((roundingAmount * RoundingScale * centerF) + randomVariance * RandomVarianceScale);
|
||||
extrusionAmount = Math.Min(extrusionAmount, maxExtrusion);
|
||||
|
||||
Vector2 nonExtrudedPoint =
|
||||
edge.Point1 +
|
||||
edgeDiff * (i / (float)pointCount) +
|
||||
edgeNormal * edgeLength * (roundingAmount + randomVariance) * centerF;
|
||||
edgeDiff * (i / (float)pointCount);
|
||||
|
||||
Vector2 nextPoint =
|
||||
edge.Point1 +
|
||||
edgeDiff * ((i + 1) / (float)pointCount);
|
||||
|
||||
//"extruding" inwards, need to make sure we don't make the edge poke through the cell from the other side
|
||||
if (extrusionAmount < 0 && minThickness > 0.0f)
|
||||
{
|
||||
foreach (GraphEdge otherEdge in cell.Edges)
|
||||
{
|
||||
if (otherEdge == edge) { continue; }
|
||||
float margin = minThickness * Math.Sign(extrusionAmount);
|
||||
if (MathUtils.GetLineIntersection(
|
||||
nonExtrudedPoint, nonExtrudedPoint + edgeNormal * (extrusionAmount + margin),
|
||||
otherEdge.Point1, otherEdge.Point2, areLinesInfinite: false, out Vector2 intersection))
|
||||
{
|
||||
extrusionAmount = Math.Min(extrusionAmount, Vector2.Distance(edge.Point1, intersection)) - margin;
|
||||
//make sure we don't "overshoot", fix the inwards extrusion by instead extruding too much outwards
|
||||
//(can happen on small cells in caves for example)
|
||||
extrusionAmount = Math.Min(extrusionAmount, edge.Length / 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 extrudedPoint = nonExtrudedPoint + edgeNormal * extrusionAmount;
|
||||
|
||||
var nearbyCells = Level.Loaded.GetCells(extrudedPoint, searchDepth: 2);
|
||||
bool isInside = false;
|
||||
@@ -306,14 +361,29 @@ namespace Barotrauma
|
||||
}
|
||||
if (isInside) { break; }
|
||||
}
|
||||
if (isInside) { continue; }
|
||||
|
||||
if (!isInside)
|
||||
{
|
||||
edgePoints.Add(extrudedPoint);
|
||||
}
|
||||
//if adding the point would deform the edge so much that the normal of the new edge would point
|
||||
//in the opposite direction from the undeformed edge's normal, don't allow adding the point
|
||||
//(that would lead to the edge being "inside out", the wall texture and objects on the wall pointing inwards)
|
||||
bool isNormalInverted =
|
||||
Vector2.Dot(edgeNormal, GraphEdge.GetNormal(cell, edgePoints.Last(), extrudedPoint)) < 0 ||
|
||||
//check that the edge at the other side of the new point doesn't get inverted either
|
||||
Vector2.Dot(edgeNormal, GraphEdge.GetNormal(cell, extrudedPoint, edge.Point2)) < 0;
|
||||
if (isNormalInverted) { continue; }
|
||||
|
||||
//make sure extruding the point doesn't change the vertex order
|
||||
//(they're assumed to be sorted counter-clockwise, and if they're not, the triangles will generate incorrectly)
|
||||
bool vertexOrderChanged =
|
||||
compareCCW.Compare(edgePoints.Last(), nonExtrudedPoint) != compareCCW.Compare(edgePoints.Last(), extrudedPoint) ||
|
||||
compareCCW.Compare(nonExtrudedPoint, nextPoint) != compareCCW.Compare(extrudedPoint, nextPoint);
|
||||
if (vertexOrderChanged) { continue; }
|
||||
|
||||
edgePoints.Add(extrudedPoint);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < edgePoints.Count - 1; i++)
|
||||
{
|
||||
tempEdges.Add(new GraphEdge(edgePoints[i], edgePoints[i + 1])
|
||||
@@ -376,19 +446,7 @@ namespace Barotrauma
|
||||
continue;
|
||||
}
|
||||
|
||||
Vector2 minVert = tempVertices[0];
|
||||
Vector2 maxVert = tempVertices[0];
|
||||
foreach (var vert in tempVertices)
|
||||
{
|
||||
minVert = new Vector2(
|
||||
Math.Min(minVert.X, vert.X),
|
||||
Math.Min(minVert.Y, vert.Y));
|
||||
maxVert = new Vector2(
|
||||
Math.Max(maxVert.X, vert.X),
|
||||
Math.Max(maxVert.Y, vert.Y));
|
||||
}
|
||||
Vector2 center = (minVert + maxVert) / 2;
|
||||
renderTriangles.AddRange(MathUtils.TriangulateConvexHull(tempVertices, center));
|
||||
renderTriangles.AddRange(MathUtils.TriangulateConvexHull(tempVertices, cell.Center));
|
||||
|
||||
if (bodyPoints.Count < 2) { continue; }
|
||||
|
||||
@@ -411,7 +469,7 @@ namespace Barotrauma
|
||||
if (cell.CellType == CellType.Empty) { continue; }
|
||||
|
||||
cellBody.UserData = cell;
|
||||
var triangles = MathUtils.TriangulateConvexHull(bodyPoints, ConvertUnits.ToSimUnits(center));
|
||||
var triangles = MathUtils.TriangulateConvexHull(bodyPoints, ConvertUnits.ToSimUnits(cell.Center));
|
||||
|
||||
for (int i = 0; i < triangles.Count; i++)
|
||||
{
|
||||
|
||||
@@ -1205,7 +1205,8 @@ namespace Barotrauma
|
||||
CaveGenerator.RoundCell(cell,
|
||||
minEdgeLength: GenerationParams.CellSubdivisionLength,
|
||||
roundingAmount: GenerationParams.CellRoundingAmount,
|
||||
irregularity: GenerationParams.CellIrregularity);
|
||||
irregularity: GenerationParams.CellIrregularity,
|
||||
minThickness: GenerationParams.WallTextureExpandInwardsAmount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1278,12 +1279,22 @@ namespace Barotrauma
|
||||
Debug.Assert(triangleLists.Count == cellBatches.Count);
|
||||
for (int i = 0; i < triangleLists.Count; i++)
|
||||
{
|
||||
//the solid black inner part of the wall
|
||||
var wallVerts = CaveGenerator.GenerateWallEdgeVertices(cellBatches[i].cells,
|
||||
expandOutwards: 0.0f, expandInwards: GenerationParams.WallTextureExpandInwardsAmount,
|
||||
outerColor: GenerationParams.WallColor, innerColor: Color.Black,
|
||||
this, zCoord: 0.9f, preventExpandThroughCell: true).ToArray();
|
||||
CaveGenerator.GenerateTextureCoordinates(wallVerts, GenerationParams.WallTextureSize);
|
||||
renderer.SetVertices(
|
||||
CaveGenerator.GenerateWallVertices(triangleLists[i], GenerationParams, zCoord: 0.9f).ToArray(),
|
||||
CaveGenerator.GenerateWallEdgeVertices(cellBatches[i].cells, this, zCoord: 0.9f).ToArray(),
|
||||
wallVerts,
|
||||
CaveGenerator.GenerateWallEdgeVertices(
|
||||
cellBatches[i].cells,
|
||||
GenerationParams.WallEdgeExpandOutwardsAmount, GenerationParams.WallEdgeExpandInwardsAmount,
|
||||
outerColor: GenerationParams.WallColor, innerColor: GenerationParams.WallColor,
|
||||
this, zCoord: 0.9f).ToArray(),
|
||||
CaveGenerator.GenerateWallVertices(triangleLists[i], Color.Black, zCoord: 0.9f).ToArray(),
|
||||
cellBatches[i].parentCave?.CaveGenerationParams?.WallSprite == null ? GenerationParams.WallSprite.Texture : cellBatches[i].parentCave.CaveGenerationParams.WallSprite.Texture,
|
||||
cellBatches[i].parentCave?.CaveGenerationParams?.WallEdgeSprite == null ? GenerationParams.WallEdgeSprite.Texture : cellBatches[i].parentCave.CaveGenerationParams.WallEdgeSprite.Texture,
|
||||
GenerationParams.WallColor);
|
||||
cellBatches[i].parentCave?.CaveGenerationParams?.WallEdgeSprite == null ? GenerationParams.WallEdgeSprite.Texture : cellBatches[i].parentCave.CaveGenerationParams.WallEdgeSprite.Texture);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2808,6 +2819,7 @@ namespace Barotrauma
|
||||
if (l.Cell == null || l.Edge == null) { return false; }
|
||||
if (resourceInfo.IsIslandSpecific && !l.Cell.Island) { return false; }
|
||||
if (!resourceInfo.AllowAtStart && l.EdgeCenter.Y > startPosition.Y && l.EdgeCenter.X < Size.X * 0.25f) { return false; }
|
||||
if (l.Edge.Length < itemPrefab.Size.X) { return false; }
|
||||
if (l.EdgeCenter.Y < AbyssArea.Bottom) { return false; }
|
||||
return resourceInfo.ClusterSize <= GetMaxResourcesOnEdge(itemPrefab, l, out _);
|
||||
|
||||
@@ -2839,6 +2851,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (l.Cell == null || l.Edge == null) { return false; }
|
||||
if (l.EdgeCenter.Y > AbyssArea.Bottom) { return false; }
|
||||
if (l.Edge.Length < selectedPrefab.Size.X) { return false; }
|
||||
l.InitializeResources();
|
||||
return l.Resources.Count <= GetMaxResourcesOnEdge(selectedPrefab, l, out _);
|
||||
}, randSync: Rand.RandSync.ServerAndClient);
|
||||
@@ -3375,37 +3388,41 @@ namespace Barotrauma
|
||||
private void PlaceResources(ItemPrefab resourcePrefab, int resourceCount, ClusterLocation location, out List<Item> placedResources,
|
||||
float? edgeLength = null, float maxResourceOverlap = 0.4f)
|
||||
{
|
||||
edgeLength ??= Vector2.Distance(location.Edge.Point1, location.Edge.Point2);
|
||||
edgeLength ??= location.Edge.Length;
|
||||
Vector2 edgeDir = (location.Edge.Point2 - location.Edge.Point1) / edgeLength.Value;
|
||||
if (!MathUtils.IsValid(edgeDir))
|
||||
{
|
||||
edgeDir = Vector2.Zero;
|
||||
}
|
||||
var minResourceOverlap = -((edgeLength.Value - (resourceCount * resourcePrefab.Size.X)) / (resourceCount * resourcePrefab.Size.X));
|
||||
float minResourceOverlap = -((edgeLength.Value - (resourceCount * resourcePrefab.Size.X)) / (resourceCount * resourcePrefab.Size.X));
|
||||
minResourceOverlap = Math.Clamp(minResourceOverlap, 0, maxResourceOverlap);
|
||||
var lerpAmounts = new float[resourceCount];
|
||||
float[] lerpAmounts = new float[resourceCount];
|
||||
lerpAmounts[0] = 0.0f;
|
||||
var lerpAmount = 0.0f;
|
||||
float lerpAmount = 0.0f;
|
||||
for (int i = 1; i < resourceCount; i++)
|
||||
{
|
||||
var overlap = Rand.Range(minResourceOverlap, maxResourceOverlap, sync: Rand.RandSync.ServerAndClient);
|
||||
lerpAmount += (1.0f - overlap) * resourcePrefab.Size.X / edgeLength.Value;
|
||||
lerpAmounts[i] = Math.Clamp(lerpAmount, 0.0f, 1.0f);
|
||||
float overlap = Rand.Range(minResourceOverlap, maxResourceOverlap, sync: Rand.RandSync.ServerAndClient);
|
||||
lerpAmount = Math.Clamp(lerpAmount + (1.0f - overlap) * resourcePrefab.Size.X / edgeLength.Value, 0.0f, 1.0f);
|
||||
lerpAmounts[i] = lerpAmount;
|
||||
}
|
||||
|
||||
var startOffset = Rand.Range(0.0f, 1.0f - lerpAmount, sync: Rand.RandSync.ServerAndClient);
|
||||
placedResources = new List<Item>();
|
||||
for (int i = 0; i < resourceCount; i++)
|
||||
{
|
||||
Vector2 selectedPos = Vector2.Lerp(location.Edge.Point1 + edgeDir * resourcePrefab.Size.X / 2, location.Edge.Point2 - edgeDir * resourcePrefab.Size.X / 2, startOffset + lerpAmounts[i]);
|
||||
Vector2 selectedPos =
|
||||
location.Edge.Length < resourcePrefab.Size.X ?
|
||||
location.Edge.Center :
|
||||
Vector2.Lerp(location.Edge.Point1 + edgeDir * resourcePrefab.Size.X / 2, location.Edge.Point2 - edgeDir * resourcePrefab.Size.X / 2, startOffset + lerpAmounts[i]);
|
||||
var item = new Item(resourcePrefab, selectedPos, submarine: null);
|
||||
Vector2 edgeNormal = location.Edge.GetNormal(location.Cell);
|
||||
float moveAmount = (item.body == null ? item.Rect.Height / 2 : ConvertUnits.ToDisplayUnits(item.body.GetMaxExtent() * 0.7f));
|
||||
moveAmount += (item.GetComponent<LevelResource>()?.RandomOffsetFromWall ?? 0.0f) * Rand.Range(-0.5f, 0.5f, Rand.RandSync.ServerAndClient);
|
||||
item.Move(edgeNormal * moveAmount);
|
||||
item.Rotation = MathHelper.ToDegrees(-MathUtils.VectorToAngle(edgeNormal) + MathHelper.PiOver2);
|
||||
if (item.GetComponent<Holdable>() is Holdable h)
|
||||
{
|
||||
h.AttachToWall();
|
||||
item.Rotation = MathHelper.ToDegrees(-MathUtils.VectorToAngle(edgeNormal) + MathHelper.PiOver2);
|
||||
}
|
||||
else if (item.body != null)
|
||||
{
|
||||
@@ -3914,7 +3931,7 @@ namespace Barotrauma
|
||||
attempt++;
|
||||
spawnPoint = wayPoint.WorldPosition;
|
||||
success = TryPositionSub(subBorders, subName, placement, ref spawnPoint);
|
||||
positionHistory.Add($"{info.Name}: {attempt}", positions.ToList());
|
||||
positionHistory.TryAdd($"{info.Name}: {attempt}", positions.ToList());
|
||||
positions.Clear();
|
||||
if (success)
|
||||
{
|
||||
@@ -3940,6 +3957,11 @@ namespace Barotrauma
|
||||
PositionsOfInterest.Add(new InterestingPosition(spawnPoint.ToPoint(), PositionType.Wreck, submarine: sub));
|
||||
foreach (Hull hull in sub.GetHulls(false))
|
||||
{
|
||||
if (hull.WaterPercentage > 0)
|
||||
{
|
||||
// Don't override the water level set by the sub designer
|
||||
continue;
|
||||
}
|
||||
if (Rand.Value(Rand.RandSync.ServerAndClient) <= Loaded.GenerationParams.WreckHullFloodingChance)
|
||||
{
|
||||
hull.WaterVolume =
|
||||
@@ -4296,7 +4318,7 @@ namespace Barotrauma
|
||||
if (LevelData.ForceWreck != null)
|
||||
{
|
||||
//force the desired wreck to be chosen first
|
||||
var matchingFile = placeableWrecks.FirstOrDefault(wreck => wreck.WreckFile.Path == LevelData.ForceWreck.FilePath);
|
||||
PlaceableWreck matchingFile = placeableWrecks.FirstOrDefault(wreck => wreck.WreckFile.Path == LevelData.ForceWreck.FilePath);
|
||||
if (matchingFile.WreckFile != null)
|
||||
{
|
||||
placeableWrecks.Remove(matchingFile);
|
||||
@@ -4337,7 +4359,12 @@ namespace Barotrauma
|
||||
{
|
||||
var placeableWreck = placeableWrecks.First();
|
||||
var wreckFile = placeableWreck.WreckFile;
|
||||
placeableWrecks.RemoveAt(0);
|
||||
if (LevelData.ForceWreck == null)
|
||||
{
|
||||
// If a wreck is forced, don't remove it -> only spawns those wrecks (makes testing them in the editor easier).
|
||||
// Normally we don't want two instances of the same wreck to spawn in the same level, but when we test or debug certain wrecks, we want only them.
|
||||
placeableWrecks.RemoveAt(0);
|
||||
}
|
||||
LevelData.ThalamusSpawn thalamusSpawn = requireThalamus ? LevelData.ThalamusSpawn.Forced : LevelData.ThalamusSpawn.Random;
|
||||
if (LevelData.ForceWreck != null) { thalamusSpawn = LevelData.ForceThalamus; }
|
||||
|
||||
@@ -4783,40 +4810,13 @@ namespace Barotrauma
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if (GameMain.NetworkMember is not { IsClient: true })
|
||||
{
|
||||
bool allowDisconnectedWires = true;
|
||||
bool allowDamagedDevices = true;
|
||||
bool allowDamagedWalls = true;
|
||||
if (BeaconStation?.Info?.BeaconStationInfo is BeaconStationInfo info)
|
||||
{
|
||||
allowDisconnectedWires = info.AllowDisconnectedWires;
|
||||
allowDamagedWalls = info.AllowDamagedWalls;
|
||||
allowDamagedDevices = info.AllowDamagedDevices;
|
||||
}
|
||||
|
||||
//remove wires
|
||||
float disconnectWireMinDifficulty = 20.0f;
|
||||
float disconnectWireProbability = MathUtils.InverseLerp(disconnectWireMinDifficulty, 100.0f, LevelData.Difficulty) * 0.5f;
|
||||
if (disconnectWireProbability > 0.0f && allowDisconnectedWires)
|
||||
{
|
||||
DisconnectBeaconStationWires(disconnectWireProbability);
|
||||
}
|
||||
|
||||
if (allowDamagedDevices)
|
||||
{
|
||||
DamageBeaconStationDevices(breakDeviceProbability: 0.5f);
|
||||
}
|
||||
if (allowDamagedWalls)
|
||||
{
|
||||
DamageBeaconStationWalls(damageWallProbability: 0.25f);
|
||||
}
|
||||
}
|
||||
SetLinkedSubCrushDepth(BeaconStation);
|
||||
}
|
||||
|
||||
public void DisconnectBeaconStationWires(float disconnectWireProbability)
|
||||
{
|
||||
if (BeaconStation?.Info?.BeaconStationInfo is { AllowDisconnectedWires: false }) { return; }
|
||||
|
||||
if (disconnectWireProbability <= 0.0f) { return; }
|
||||
List<Item> beaconItems = Item.ItemList.FindAll(it => it.Submarine == BeaconStation);
|
||||
foreach (Item item in beaconItems.Where(it => it.GetComponent<Wire>() != null).ToList())
|
||||
@@ -4852,6 +4852,8 @@ namespace Barotrauma
|
||||
|
||||
public void DamageBeaconStationDevices(float breakDeviceProbability)
|
||||
{
|
||||
if (BeaconStation?.Info?.BeaconStationInfo is { AllowDamagedDevices: false }) { return; }
|
||||
|
||||
if (breakDeviceProbability <= 0.0f) { return; }
|
||||
//break powered items
|
||||
List<Item> beaconItems = Item.ItemList.FindAll(it => it.Submarine == BeaconStation);
|
||||
@@ -4867,6 +4869,8 @@ namespace Barotrauma
|
||||
|
||||
public void DamageBeaconStationWalls(float damageWallProbability)
|
||||
{
|
||||
if (BeaconStation?.Info?.BeaconStationInfo is { AllowDamagedWalls: false }) { return; }
|
||||
|
||||
if (damageWallProbability <= 0.0f) { return; }
|
||||
//poke holes in the walls
|
||||
foreach (Structure structure in Structure.WallList.Where(s => s.Submarine == BeaconStation))
|
||||
|
||||
@@ -236,7 +236,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
|
||||
[Editable(MinValueFloat = 0.0f, MaxValueFloat = 1.0f), Serialize(0.5f, IsPropertySaveable.Yes, description: "How much the individual wall cells are rounded. "
|
||||
[Editable(MinValueFloat = 0.0f, MaxValueFloat = 1.0f, DecimalCount = 2), Serialize(0.5f, IsPropertySaveable.Yes, description: "How much the individual wall cells are rounded. "
|
||||
+ "Note that the final shape of the cells is also affected by the CellSubdivisionLength parameter.")]
|
||||
public float CellRoundingAmount
|
||||
{
|
||||
@@ -247,7 +247,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
[Editable(MinValueFloat = 0.0f, MaxValueFloat = 1.0f), Serialize(0.1f, IsPropertySaveable.Yes, description: "How much random variance is applied to the edges of the cells. "
|
||||
[Editable(MinValueFloat = 0.0f, MaxValueFloat = 1.0f, DecimalCount = 2), Serialize(0.1f, IsPropertySaveable.Yes, description: "How much random variance is applied to the edges of the cells. "
|
||||
+ "Note that the final shape of the cells is also affected by the CellSubdivisionLength parameter.")]
|
||||
public float CellIrregularity
|
||||
{
|
||||
@@ -525,19 +525,19 @@ namespace Barotrauma
|
||||
[Serialize(5, IsPropertySaveable.Yes, description: "The maximum number of corpses per wreck."), Editable(MinValueInt = 0, MaxValueInt = 20)]
|
||||
public int MaxCorpseCount { get; set; }
|
||||
|
||||
[Serialize(0.0f, IsPropertySaveable.Yes, description: "How likely is it that a character set to be spawned as a corpse spawns as a human husk instead? Percentage from 0 to 1 per character."), Editable(MinValueFloat = 0, MaxValueFloat = 1)]
|
||||
[Serialize(0.0f, IsPropertySaveable.Yes, description: "How likely is it that a character set to be spawned as a corpse spawns as a human husk instead? Percentage from 0 to 1 per character."), Editable(MinValueFloat = 0, MaxValueFloat = 1, DecimalCount = 2)]
|
||||
public float HuskProbability { get; set; }
|
||||
|
||||
[Serialize(0.0f, IsPropertySaveable.Yes, description: "How likely is it that a Thalamus inhabits a wreck. Percentage from 0 to 1 per wreck."), Editable(MinValueFloat = 0, MaxValueFloat = 1)]
|
||||
[Serialize(0.0f, IsPropertySaveable.Yes, description: "How likely is it that a Thalamus inhabits a wreck. Percentage from 0 to 1 per wreck."), Editable(MinValueFloat = 0, MaxValueFloat = 1, DecimalCount = 2)]
|
||||
public float ThalamusProbability { get; set; }
|
||||
|
||||
[Serialize(0.5f, IsPropertySaveable.Yes, description: "How likely the water level of a hull inside a wreck is randomly set."), Editable(MinValueFloat = 0, MaxValueFloat = 1)]
|
||||
[Serialize(0.5f, IsPropertySaveable.Yes, description: "How likely the water level of a hull inside a wreck is randomly set."), Editable(MinValueFloat = 0, MaxValueFloat = 1, DecimalCount = 2)]
|
||||
public float WreckHullFloodingChance { get; set; }
|
||||
|
||||
[Serialize(0.1f, IsPropertySaveable.Yes, description: "The min water percentage of randomly flooding hulls in wrecks."), Editable(MinValueFloat = 0, MaxValueFloat = 1)]
|
||||
[Serialize(0.1f, IsPropertySaveable.Yes, description: "The min water percentage of randomly flooding hulls in wrecks."), Editable(MinValueFloat = 0, MaxValueFloat = 1, DecimalCount = 2)]
|
||||
public float WreckFloodingHullMinWaterPercentage { get; set; }
|
||||
|
||||
[Serialize(1.0f, IsPropertySaveable.Yes, description: "The min water percentage of randomly flooding hulls in wrecks."), Editable(MinValueFloat = 0, MaxValueFloat = 1)]
|
||||
[Serialize(1.0f, IsPropertySaveable.Yes, description: "The min water percentage of randomly flooding hulls in wrecks."), Editable(MinValueFloat = 0, MaxValueFloat = 1, DecimalCount = 2)]
|
||||
public float WreckFloodingHullMaxWaterPercentage { get; set; }
|
||||
#endregion
|
||||
|
||||
@@ -602,6 +602,13 @@ namespace Barotrauma
|
||||
private set;
|
||||
}
|
||||
|
||||
[Serialize(1000.0f, IsPropertySaveable.Yes, description: "How deep inside the walls the wall texture extends to before fading to black."), Editable(minValue: 0.0f, maxValue: 10000.0f)]
|
||||
public float WallTextureExpandInwardsAmount
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
[Header("Colors")]
|
||||
[Serialize("27,30,36", IsPropertySaveable.Yes), Editable]
|
||||
public Color AmbientLightColor
|
||||
|
||||
+4
-4
@@ -339,11 +339,11 @@ namespace Barotrauma
|
||||
InitProjSpecific(element);
|
||||
}
|
||||
|
||||
//use the maximum width of the sprite as the minimum surface width if no value is given
|
||||
if (element != null && !element.Attributes("minsurfacewidth").Any())
|
||||
//use (a bit less than) the maximum width of the sprite as the minimum surface width if no value is given
|
||||
if (element != null && element.GetAttribute("minsurfacewidth") == null)
|
||||
{
|
||||
if (Sprites.Any()) MinSurfaceWidth = Sprites[0].size.X * MaxSize;
|
||||
if (DeformableSprite != null) MinSurfaceWidth = Math.Max(MinSurfaceWidth, DeformableSprite.Size.X * MaxSize);
|
||||
if (Sprites.Any()) { MinSurfaceWidth = Sprites[0].size.X * MaxSize * 0.8f; }
|
||||
if (DeformableSprite != null) { MinSurfaceWidth = Math.Max(MinSurfaceWidth, DeformableSprite.Size.X * MaxSize * 0.8f); }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -609,6 +609,21 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
|
||||
if (PhysicsBody != null)
|
||||
{
|
||||
if (currentForceFluctuation <= 0.0f && statusEffects.None() && attacks.None())
|
||||
{
|
||||
//no force atm, and no status effects or attacks the trigger could apply
|
||||
// -> we can disable the collider and get a minor physics performance improvement
|
||||
PhysicsBody.Enabled = false;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
PhysicsBody.Enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Entity triggerer in triggerers)
|
||||
{
|
||||
if (triggerer.Removed) { continue; }
|
||||
|
||||
Reference in New Issue
Block a user