v1.7.7.0 (Winter Update 2024)

This commit is contained in:
Regalis11
2024-12-11 13:26:13 +02:00
parent 7d5b7a310a
commit f6349b2175
256 changed files with 4794 additions and 1653 deletions
@@ -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))