Unstable 0.17.3.0
This commit is contained in:
@@ -520,8 +520,9 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
if (branch.Health > branch.MaxHealth * 0.9f || branch.DisconnectedFromRoot) { continue; }
|
||||
float branchHealAmount = (float)(MaxBranchHealthRegenDistance - branch.BranchDepth) / MaxBranchHealthRegenDistance * healAmount;
|
||||
if (branchHealAmount <= 0.0f) { continue; }
|
||||
float prevHealth = branch.Health;
|
||||
branch.Health += branchHealAmount;
|
||||
branch.AccumulatedDamage -= branchHealAmount;
|
||||
branch.AccumulatedDamage += (prevHealth - branch.Health);
|
||||
}
|
||||
}
|
||||
StateMachine.Update(deltaTime);
|
||||
@@ -633,7 +634,8 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
{
|
||||
if (branch.ParentBranch != null && (branch.ParentBranch.DisconnectedFromRoot || branch.ParentBranch.Health <= 0.0f))
|
||||
{
|
||||
DamageBranch(branch, deltaTime * MathHelper.Lerp(10.0f, 0.01f, branch.ParentBranch.Health / branch.ParentBranch.MaxHealth), AttackType.CutFromRoot);
|
||||
float speed = MathHelper.Lerp(5.0f, 0.1f, branch.ParentBranch.Health / branch.ParentBranch.MaxHealth);
|
||||
DamageBranch(branch, speed * speed * deltaTime, AttackType.CutFromRoot);
|
||||
}
|
||||
if (branch.Health <= 0.0f)
|
||||
{
|
||||
@@ -836,7 +838,7 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
}
|
||||
|
||||
#if SERVER
|
||||
SendNetworkMessage(new BranchCreateEventData(newBranch, parent));
|
||||
CreateNetworkMessage(new BranchCreateEventData(newBranch, parent));
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
@@ -878,7 +880,7 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
#if SERVER
|
||||
if (!load)
|
||||
{
|
||||
SendNetworkMessage(new InfectEventData(target, InfectEventData.InfectState.Yes, branch));
|
||||
CreateNetworkMessage(new InfectEventData(target, InfectEventData.InfectState.Yes, branch));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -955,8 +957,6 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
/// <param name="branch"></param>
|
||||
private void CreateBody(BallastFloraBranch branch)
|
||||
{
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; }
|
||||
|
||||
Rectangle rect = branch.Rect;
|
||||
Vector2 pos = Parent.Position + Offset + branch.Position;
|
||||
|
||||
@@ -975,6 +975,14 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
public void DamageBranch(BallastFloraBranch branch, float amount, AttackType type, Character? attacker = null)
|
||||
{
|
||||
float damage = amount;
|
||||
if (damage > 0)
|
||||
{
|
||||
damage = Math.Min(damage, branch.Health);
|
||||
}
|
||||
else
|
||||
{
|
||||
damage = Math.Max(damage, branch.Health - branch.MaxHealth);
|
||||
}
|
||||
|
||||
if (type != AttackType.Other && type != AttackType.CutFromRoot)
|
||||
{
|
||||
@@ -983,8 +991,28 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
|
||||
if (branch.IsRootGrowth && root != null && root.Health > 0.0f) { return; }
|
||||
|
||||
// damage is handled server side currently
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; }
|
||||
if (type != AttackType.Other && type != AttackType.CutFromRoot)
|
||||
{
|
||||
branch.AccumulatedDamage += damage;
|
||||
Anger += damage * 0.001f;
|
||||
}
|
||||
|
||||
if (GameMain.NetworkMember != null)
|
||||
{
|
||||
// damage is handled server side
|
||||
if (GameMain.NetworkMember.IsClient)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
//accumulate damage on the server's side to ensure clients get notified
|
||||
if (type == AttackType.Other || type == AttackType.CutFromRoot)
|
||||
{
|
||||
branch.AccumulatedDamage += damage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (attacker != null && toxinsCooldown <= 0)
|
||||
{
|
||||
@@ -1014,11 +1042,6 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
}
|
||||
|
||||
branch.Health -= damage;
|
||||
if (type != AttackType.Other && type != AttackType.CutFromRoot)
|
||||
{
|
||||
branch.AccumulatedDamage += damage;
|
||||
Anger += damage * 0.001f;
|
||||
}
|
||||
|
||||
#if SERVER
|
||||
GameMain.Server?.KarmaManager?.OnBallastFloraDamaged(attacker, damage);
|
||||
@@ -1110,7 +1133,7 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
#if SERVER
|
||||
if (!wasRemoved)
|
||||
{
|
||||
SendNetworkMessage(new BranchRemoveEventData(branch));
|
||||
CreateNetworkMessage(new BranchRemoveEventData(branch));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1141,7 +1164,7 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
}
|
||||
});
|
||||
#if SERVER
|
||||
SendNetworkMessage(new InfectEventData(item, InfectEventData.InfectState.No, null));
|
||||
CreateNetworkMessage(new InfectEventData(item, InfectEventData.InfectState.No, null));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1159,7 +1182,7 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
|
||||
StateMachine?.State?.Exit();
|
||||
#if SERVER
|
||||
SendNetworkMessage(new KillEventData());
|
||||
CreateNetworkMessage(new KillEventData());
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1181,7 +1204,7 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
|
||||
_entityList.Remove(this);
|
||||
#if SERVER
|
||||
SendNetworkMessage(new KillEventData());
|
||||
CreateNetworkMessage(new KillEventData());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -160,17 +160,20 @@ namespace Barotrauma
|
||||
public void Delete()
|
||||
{
|
||||
Dispose();
|
||||
if (File.Exists(ContentFile.Path))
|
||||
try
|
||||
{
|
||||
try
|
||||
if (ContentPackage is { Files: { Length: 1 } }
|
||||
&& ContentPackageManager.LocalPackages.Contains(ContentPackage))
|
||||
{
|
||||
File.Delete(ContentFile.Path);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Deleting item assembly \"" + Name + "\" failed.", e);
|
||||
Directory.Delete(ContentPackage.Dir, recursive: true);
|
||||
ContentPackageManager.LocalPackages.Refresh();
|
||||
ContentPackageManager.EnabledPackages.DisableRemovedMods();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Deleting item assembly \"" + Name + "\" failed.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Dispose() { }
|
||||
|
||||
@@ -3826,12 +3826,12 @@ namespace Barotrauma
|
||||
if (location != null)
|
||||
{
|
||||
DebugConsole.NewMessage($"Generating an outpost for the {(isStart ? "start" : "end")} of the level... (Location: {location.Name}, level type: {LevelData.Type})");
|
||||
outpost = OutpostGenerator.Generate(outpostGenerationParams, location, onlyEntrance: LevelData.Type != LevelData.LevelType.Outpost);
|
||||
outpost = OutpostGenerator.Generate(outpostGenerationParams, location, onlyEntrance: LevelData.Type != LevelData.LevelType.Outpost, LevelData.AllowInvalidOutpost);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.NewMessage($"Generating an outpost for the {(isStart ? "start" : "end")} of the level... (Location type: {locationType}, level type: {LevelData.Type})");
|
||||
outpost = OutpostGenerator.Generate(outpostGenerationParams, locationType, onlyEntrance: LevelData.Type != LevelData.LevelType.Outpost);
|
||||
outpost = OutpostGenerator.Generate(outpostGenerationParams, locationType, onlyEntrance: LevelData.Type != LevelData.LevelType.Outpost, LevelData.AllowInvalidOutpost);
|
||||
}
|
||||
|
||||
foreach (string categoryToHide in locationType.HideEntitySubcategories)
|
||||
|
||||
@@ -31,8 +31,16 @@ namespace Barotrauma
|
||||
|
||||
public bool HasHuntingGrounds, OriginallyHadHuntingGrounds;
|
||||
|
||||
//minimum difficulty of the level before hunting grounds can appear
|
||||
public const float HuntingGroundsDifficultyThreshold = 25;
|
||||
|
||||
//probability of hunting grounds appearing in 100% difficulty levels
|
||||
public const float MaxHuntingGroundsProbability = 0.3f;
|
||||
|
||||
public OutpostGenerationParams ForceOutpostGenerationParams;
|
||||
|
||||
public bool AllowInvalidOutpost;
|
||||
|
||||
public readonly Point Size;
|
||||
|
||||
public readonly int InitialDepth;
|
||||
@@ -150,11 +158,7 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
//minimum difficulty of the level before hunting grounds can appear
|
||||
float huntingGroundsDifficultyThreshold = 25;
|
||||
//probability of hunting grounds appearing in 100% difficulty levels
|
||||
float maxHuntingGroundsProbability = 0.3f;
|
||||
HasHuntingGrounds = OriginallyHadHuntingGrounds = rand.NextDouble() < MathUtils.InverseLerp(huntingGroundsDifficultyThreshold, 100.0f, Difficulty) * maxHuntingGroundsProbability;
|
||||
HasHuntingGrounds = OriginallyHadHuntingGrounds = rand.NextDouble() < MathUtils.InverseLerp(HuntingGroundsDifficultyThreshold, 100.0f, Difficulty) * MaxHuntingGroundsProbability;
|
||||
HasBeaconStation = !HasHuntingGrounds && rand.NextDouble() < locationConnection.Locations.Select(l => l.Type.BeaconStationChance).Max();
|
||||
}
|
||||
IsBeaconActive = false;
|
||||
|
||||
@@ -182,8 +182,7 @@ namespace Barotrauma
|
||||
{
|
||||
for (int i = 0; i < Connections.Count; i++)
|
||||
{
|
||||
float maxHuntingGroundsProbability = 0.3f;
|
||||
Connections[i].LevelData.HasHuntingGrounds = Rand.Range(0.0f, 1.0f) < Connections[i].Difficulty / 100.0f * maxHuntingGroundsProbability;
|
||||
Connections[i].LevelData.HasHuntingGrounds = Rand.Range(0.0f, 1.0f) < Connections[i].Difficulty / 100.0f * LevelData.MaxHuntingGroundsProbability;
|
||||
connectionElements[i].SetAttributeValue("hashuntinggrounds", true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,17 +57,17 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public static Submarine Generate(OutpostGenerationParams generationParams, LocationType locationType, bool onlyEntrance = false)
|
||||
public static Submarine Generate(OutpostGenerationParams generationParams, LocationType locationType, bool onlyEntrance = false, bool allowInvalidOutpost = false)
|
||||
{
|
||||
return Generate(generationParams, locationType, location: null, onlyEntrance);
|
||||
return Generate(generationParams, locationType, location: null, onlyEntrance, allowInvalidOutpost);
|
||||
}
|
||||
|
||||
public static Submarine Generate(OutpostGenerationParams generationParams, Location location, bool onlyEntrance = false)
|
||||
public static Submarine Generate(OutpostGenerationParams generationParams, Location location, bool onlyEntrance = false, bool allowInvalidOutpost = false)
|
||||
{
|
||||
return Generate(generationParams, location.Type, location, onlyEntrance);
|
||||
return Generate(generationParams, location.Type, location, onlyEntrance, allowInvalidOutpost);
|
||||
}
|
||||
|
||||
private static Submarine Generate(OutpostGenerationParams generationParams, LocationType locationType, Location location, bool onlyEntrance = false)
|
||||
private static Submarine Generate(OutpostGenerationParams generationParams, LocationType locationType, Location location, bool onlyEntrance = false, bool allowInvalidOutpost = false)
|
||||
{
|
||||
var outpostModuleFiles = ContentPackageManager.EnabledPackages.All
|
||||
.SelectMany(p => p.GetFiles<OutpostModuleFile>())
|
||||
@@ -197,12 +197,19 @@ namespace Barotrauma
|
||||
AppendToModule(selectedModules.Last(), outpostModules.ToList(), pendingModuleFlags, selectedModules, locationType, allowExtendBelowInitialModule: generationParams is RuinGeneration.RuinGenerationParams);
|
||||
if (pendingModuleFlags.Any(flag => flag != "none"))
|
||||
{
|
||||
remainingTries--;
|
||||
if (remainingTries <= 0)
|
||||
if (!allowInvalidOutpost)
|
||||
{
|
||||
DebugConsole.ThrowError("Could not generate an outpost with all of the required modules. Some modules may not have enough doors at the edges to generate a valid layout. Pending modules: " + string.Join(", ", pendingModuleFlags));
|
||||
remainingTries--;
|
||||
if (remainingTries <= 0)
|
||||
{
|
||||
DebugConsole.ThrowError("Could not generate an outpost with all of the required modules. Some modules may not have enough connections at the edges to generate a valid layout. Pending modules: " + string.Join(", ", pendingModuleFlags));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.ThrowError("Could not generate an outpost with all of the required modules. Some modules may not have enough connections at the edges to generate a valid layout. Pending modules: " + string.Join(", ", pendingModuleFlags) + ". Won't retry because invalid outposts are allowed.");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
var outpostInfo = new SubmarineInfo()
|
||||
@@ -328,7 +335,10 @@ namespace Barotrauma
|
||||
selectedModule.Offset =
|
||||
(selectedModule.PreviousGap.WorldPosition + selectedModule.PreviousModule.Offset) -
|
||||
selectedModule.ThisGap.WorldPosition;
|
||||
selectedModule.Offset += moveDir * generationParams.MinHallwayLength;
|
||||
if (selectedModule.PreviousGap.ConnectedDoor != null || selectedModule.ThisGap.ConnectedDoor != null)
|
||||
{
|
||||
selectedModule.Offset += moveDir * generationParams.MinHallwayLength;
|
||||
}
|
||||
}
|
||||
entities[selectedModule] = moduleEntities;
|
||||
}
|
||||
@@ -464,6 +474,16 @@ namespace Barotrauma
|
||||
pendingModuleFlags.Remove(initialModuleFlag);
|
||||
pendingModuleFlags.Insert(0, initialModuleFlag);
|
||||
|
||||
if (pendingModuleFlags.Count > totalModuleCount)
|
||||
{
|
||||
DebugConsole.ThrowError($"Error during outpost generation. {pendingModuleFlags.Count} modules set to be used the outpost, but total module count is only {totalModuleCount}. Leaving out some of the modules...");
|
||||
int removeCount = pendingModuleFlags.Count - totalModuleCount;
|
||||
for (int i = 0; i < removeCount; i++)
|
||||
{
|
||||
pendingModuleFlags.Remove(pendingModuleFlags.Last());
|
||||
}
|
||||
}
|
||||
|
||||
return pendingModuleFlags;
|
||||
}
|
||||
|
||||
@@ -486,46 +506,71 @@ namespace Barotrauma
|
||||
if (pendingModuleFlags.Count == 0) { return true; }
|
||||
|
||||
List<PlacedModule> placedModules = new List<PlacedModule>();
|
||||
foreach (OutpostModuleInfo.GapPosition gapPosition in GapPositions.Randomize(Rand.RandSync.ServerAndClient))
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (currentModule.UsedGapPositions.HasFlag(gapPosition)) { continue; }
|
||||
if (!allowExtendBelowInitialModule)
|
||||
//try placing a module meant for this location type first, and if that fails, try choosing whatever fits
|
||||
bool allowDifferentLocationType = i > 0;
|
||||
foreach (OutpostModuleInfo.GapPosition gapPosition in GapPositions.Randomize(Rand.RandSync.ServerAndClient))
|
||||
{
|
||||
//don't continue downwards if it'd extend below the airlock
|
||||
if (gapPosition == OutpostModuleInfo.GapPosition.Bottom && currentModule.Offset.Y <= 1) { continue; }
|
||||
}
|
||||
if (currentModule.Info.OutpostModuleInfo.GapPositions.HasFlag(gapPosition))
|
||||
{
|
||||
var newModule = AppendModule(currentModule, GetOpposingGapPosition(gapPosition), availableModules, pendingModuleFlags, selectedModules, locationType);
|
||||
if (newModule != null) { placedModules.Add(newModule); }
|
||||
if (pendingModuleFlags.Count == 0) { return true; }
|
||||
if (currentModule.UsedGapPositions.HasFlag(gapPosition)) { continue; }
|
||||
if (!allowExtendBelowInitialModule)
|
||||
{
|
||||
//don't continue downwards if it'd extend below the airlock
|
||||
if (gapPosition == OutpostModuleInfo.GapPosition.Bottom && currentModule.Offset.Y <= 1) { continue; }
|
||||
}
|
||||
|
||||
PlacedModule newModule = null;
|
||||
//try appending to the current module if possible
|
||||
if (currentModule.Info.OutpostModuleInfo.GapPositions.HasFlag(gapPosition))
|
||||
{
|
||||
newModule = AppendModule(currentModule, GetOpposingGapPosition(gapPosition), availableModules, pendingModuleFlags, selectedModules, locationType, allowDifferentLocationType);
|
||||
}
|
||||
|
||||
if (newModule != null)
|
||||
{
|
||||
placedModules.Add(newModule);
|
||||
}
|
||||
else
|
||||
{
|
||||
//couldn't append to current module, try one of the other placed modules
|
||||
foreach (PlacedModule otherModule in selectedModules)
|
||||
{
|
||||
if (otherModule == currentModule) { continue; }
|
||||
foreach (OutpostModuleInfo.GapPosition otherGapPosition in
|
||||
GapPositions.Where(g => !otherModule.UsedGapPositions.HasFlag(g) && otherModule.Info.OutpostModuleInfo.GapPositions.HasFlag(g)))
|
||||
{
|
||||
newModule = AppendModule(otherModule, GetOpposingGapPosition(otherGapPosition), availableModules, pendingModuleFlags, selectedModules, locationType, allowDifferentLocationType);
|
||||
if (newModule != null)
|
||||
{
|
||||
placedModules.Add(newModule);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (newModule != null) { break; }
|
||||
}
|
||||
}
|
||||
if (pendingModuleFlags.Count == 0) { return true; }
|
||||
}
|
||||
}
|
||||
|
||||
//couldn't place anything, retry
|
||||
if (placedModules.Count == 0 && retry && !selectedModules.Any(m => m != currentModule && m.PreviousModule == currentModule.PreviousModule))
|
||||
//couldn't place a module anywhere, we're probably fucked!
|
||||
if (placedModules.Count == 0 && retry && currentModule.PreviousModule != null && !selectedModules.Any(m => m != currentModule && m.PreviousModule == currentModule))
|
||||
{
|
||||
//try to append to some other module first
|
||||
foreach (PlacedModule otherModule in selectedModules)
|
||||
{
|
||||
if (AppendToModule(otherModule, availableModules, pendingModuleFlags, selectedModules, locationType, retry: false, allowExtendBelowInitialModule: allowExtendBelowInitialModule))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
//try to replace the previously placed module with something else that we can append to
|
||||
var failedModule = currentModule;
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
selectedModules.Remove(currentModule);
|
||||
assertAllPreviousModulesPresent();
|
||||
//readd the module types that the previous module was supposed to fulfill to the pending module types
|
||||
pendingModuleFlags.AddRange(currentModule.FulfilledModuleTypes);
|
||||
if (!availableModules.Contains(currentModule.Info)) { availableModules.Add(currentModule.Info); }
|
||||
//retry
|
||||
currentModule = AppendModule(currentModule.PreviousModule, currentModule.ThisGapPosition, availableModules, pendingModuleFlags, selectedModules, locationType);
|
||||
currentModule = AppendModule(currentModule.PreviousModule, currentModule.ThisGapPosition, availableModules, pendingModuleFlags, selectedModules, locationType, allowDifferentLocationType: true);
|
||||
assertAllPreviousModulesPresent();
|
||||
if (currentModule == null) { break; }
|
||||
if (AppendToModule(currentModule, availableModules, pendingModuleFlags, selectedModules, locationType, retry: false, allowExtendBelowInitialModule: allowExtendBelowInitialModule))
|
||||
{
|
||||
assertAllPreviousModulesPresent();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -534,9 +579,14 @@ namespace Barotrauma
|
||||
|
||||
foreach (PlacedModule placedModule in placedModules)
|
||||
{
|
||||
AppendToModule(placedModule, availableModules, pendingModuleFlags, selectedModules, locationType);
|
||||
AppendToModule(placedModule, availableModules, pendingModuleFlags, selectedModules, locationType, allowExtendBelowInitialModule: allowExtendBelowInitialModule);
|
||||
}
|
||||
return placedModules.Count > 0;
|
||||
|
||||
void assertAllPreviousModulesPresent()
|
||||
{
|
||||
System.Diagnostics.Debug.Assert(selectedModules.All(m => m.PreviousModule == null || selectedModules.Contains(m.PreviousModule)));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -553,7 +603,8 @@ namespace Barotrauma
|
||||
List<SubmarineInfo> availableModules,
|
||||
List<Identifier> pendingModuleFlags,
|
||||
List<PlacedModule> selectedModules,
|
||||
LocationType locationType)
|
||||
LocationType locationType,
|
||||
bool allowDifferentLocationType)
|
||||
{
|
||||
if (pendingModuleFlags.Count == 0) { return null; }
|
||||
|
||||
@@ -562,7 +613,7 @@ namespace Barotrauma
|
||||
foreach (Identifier moduleFlag in pendingModuleFlags)
|
||||
{
|
||||
flagToPlace = moduleFlag;
|
||||
nextModule = GetRandomModule(currentModule?.Info?.OutpostModuleInfo, availableModules, flagToPlace, gapPosition, locationType);
|
||||
nextModule = GetRandomModule(currentModule?.Info?.OutpostModuleInfo, availableModules, flagToPlace, gapPosition, locationType, allowDifferentLocationType);
|
||||
if (nextModule != null) { break; }
|
||||
}
|
||||
|
||||
@@ -603,6 +654,7 @@ namespace Barotrauma
|
||||
foreach (PlacedModule otherModule in modules2)
|
||||
{
|
||||
if (module == otherModule) { continue; }
|
||||
if (module.PreviousModule == otherModule && module.PreviousGap.ConnectedDoor == null && module.ThisGap.ConnectedDoor == null) { continue; }
|
||||
if (ModulesOverlap(module, otherModule))
|
||||
{
|
||||
module1 = module;
|
||||
@@ -775,22 +827,25 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private static SubmarineInfo GetRandomModule(OutpostModuleInfo prevModule, IEnumerable<SubmarineInfo> modules, Identifier moduleFlag, OutpostModuleInfo.GapPosition gapPosition, LocationType locationType)
|
||||
private static SubmarineInfo GetRandomModule(OutpostModuleInfo prevModule, IEnumerable<SubmarineInfo> modules, Identifier moduleFlag, OutpostModuleInfo.GapPosition gapPosition, LocationType locationType, bool allowDifferentLocationType)
|
||||
{
|
||||
IEnumerable<SubmarineInfo> availableModules = null;
|
||||
if (moduleFlag.IsEmpty || moduleFlag.Equals("none"))
|
||||
{
|
||||
availableModules = modules
|
||||
.Where(m => !m.OutpostModuleInfo.ModuleFlags.Any() || (m.OutpostModuleInfo.ModuleFlags.Count() == 1 && m.OutpostModuleInfo.ModuleFlags.Contains("none".ToIdentifier())) && m.OutpostModuleInfo.GapPositions.HasFlag(gapPosition));
|
||||
.Where(m => !m.OutpostModuleInfo.ModuleFlags.Any() || (m.OutpostModuleInfo.ModuleFlags.Count() == 1 && m.OutpostModuleInfo.ModuleFlags.Contains("none".ToIdentifier())));
|
||||
}
|
||||
else
|
||||
{
|
||||
availableModules = modules
|
||||
.Where(m => m.OutpostModuleInfo.ModuleFlags.Contains(moduleFlag) && m.OutpostModuleInfo.GapPositions.HasFlag(gapPosition));
|
||||
.Where(m => m.OutpostModuleInfo.ModuleFlags.Contains(moduleFlag));
|
||||
}
|
||||
|
||||
availableModules = availableModules.Where(m => m.OutpostModuleInfo.GapPositions.HasFlag(gapPosition) && m.OutpostModuleInfo.CanAttachToPrevious.HasFlag(gapPosition));
|
||||
|
||||
if (prevModule != null)
|
||||
{
|
||||
availableModules = availableModules.Where(m => CanAttachTo(m.OutpostModuleInfo, prevModule) && CanAttachTo(prevModule, m.OutpostModuleInfo));
|
||||
availableModules = availableModules.Where(m => CanAttachTo(m.OutpostModuleInfo, prevModule));// && CanAttachTo(prevModule, m.OutpostModuleInfo));
|
||||
}
|
||||
|
||||
if (availableModules.Count() == 0) { return null; }
|
||||
@@ -800,15 +855,22 @@ namespace Barotrauma
|
||||
availableModules.Where(m => m.OutpostModuleInfo.AllowedLocationTypes.Contains(locationType.Identifier));
|
||||
|
||||
//if not found, search for modules suitable for any location type
|
||||
if (!modulesSuitableForLocationType.Any())
|
||||
if (allowDifferentLocationType && !modulesSuitableForLocationType.Any())
|
||||
{
|
||||
modulesSuitableForLocationType = availableModules.Where(m => !m.OutpostModuleInfo.AllowedLocationTypes.Any());
|
||||
}
|
||||
|
||||
if (!modulesSuitableForLocationType.Any())
|
||||
{
|
||||
DebugConsole.NewMessage($"Could not find a suitable module for the location type {locationType}. Module flag: {moduleFlag}.", Color.Orange);
|
||||
return ToolBox.SelectWeightedRandom(availableModules.ToList(), availableModules.Select(m => m.OutpostModuleInfo.Commonness).ToList(), Rand.RandSync.ServerAndClient);
|
||||
if (allowDifferentLocationType)
|
||||
{
|
||||
DebugConsole.NewMessage($"Could not find a suitable module for the location type {locationType}. Module flag: {moduleFlag}.", Color.Orange);
|
||||
return ToolBox.SelectWeightedRandom(availableModules.ToList(), availableModules.Select(m => m.OutpostModuleInfo.Commonness).ToList(), Rand.RandSync.ServerAndClient);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1039,16 +1101,20 @@ namespace Barotrauma
|
||||
|
||||
if (hallwayLength <= 1.0f) { continue; }
|
||||
|
||||
var suitableModules = availableModules.Where(m =>
|
||||
m.OutpostModuleInfo.AllowAttachToModules.Any(s => module.Info.OutpostModuleInfo.ModuleFlags.Contains(s)) &&
|
||||
m.OutpostModuleInfo.AllowAttachToModules.Any(s => module.PreviousModule.Info.OutpostModuleInfo.ModuleFlags.Contains(s)));
|
||||
if (suitableModules.Count() == 0)
|
||||
Identifier moduleFlag = (isHorizontal ? "hallwayhorizontal" : "hallwayvertical").ToIdentifier();
|
||||
var hallwayModules = availableModules.Where(m => m.OutpostModuleInfo.ModuleFlags.Contains(moduleFlag));
|
||||
|
||||
var suitableHallwayModules = hallwayModules.Where(m =>
|
||||
m.OutpostModuleInfo.AllowAttachToModules.Any(s => module.Info.OutpostModuleInfo.ModuleFlags.Contains(s)) &&
|
||||
m.OutpostModuleInfo.AllowAttachToModules.Any(s => module.PreviousModule.Info.OutpostModuleInfo.ModuleFlags.Contains(s)));
|
||||
if (suitableHallwayModules.Count() == 0)
|
||||
{
|
||||
suitableModules = availableModules.Where(m =>
|
||||
suitableHallwayModules = hallwayModules.Where(m =>
|
||||
!m.OutpostModuleInfo.AllowAttachToModules.Any() ||
|
||||
m.OutpostModuleInfo.AllowAttachToModules.All(s => s == "any"));
|
||||
}
|
||||
var hallwayInfo = GetRandomModule(suitableModules, (isHorizontal ? "hallwayhorizontal" : "hallwayvertical").ToIdentifier(), locationType);
|
||||
|
||||
var hallwayInfo = GetRandomModule(suitableHallwayModules, moduleFlag, locationType);
|
||||
if (hallwayInfo == null)
|
||||
{
|
||||
DebugConsole.ThrowError($"Generating hallways between outpost modules failed. No {(isHorizontal ? "horizontal" : "vertical")} hallway modules suitable for use between the modules \"{module.Info.DisplayName}\" and \"{module.PreviousModule.Info.DisplayName}\".");
|
||||
@@ -1170,7 +1236,7 @@ namespace Barotrauma
|
||||
var startWaypoint = WayPoint.WayPointList.Find(wp => wp.ConnectedGap == module.ThisGap);
|
||||
if (startWaypoint == null)
|
||||
{
|
||||
DebugConsole.ThrowError($"Failed to connect waypoints between outpost modules. No waypoint in the {GetOpposingGapPosition(module.ThisGapPosition).ToString().ToLower()} gap of the module \"{module.Info.Name}\".");
|
||||
DebugConsole.ThrowError($"Failed to connect waypoints between outpost modules. No waypoint in the {module.ThisGapPosition.ToString().ToLower()} gap of the module \"{module.Info.Name}\".");
|
||||
continue;
|
||||
}
|
||||
var endWaypoint = WayPoint.WayPointList.Find(wp => wp.ConnectedGap == module.PreviousGap);
|
||||
|
||||
@@ -45,6 +45,9 @@ namespace Barotrauma
|
||||
[Serialize(GapPosition.None, IsPropertySaveable.Yes, description: "Which sides of the module have gaps on them (i.e. from which sides the module can be attached to other modules). Center = no gaps available.")]
|
||||
public GapPosition GapPositions { get; set; }
|
||||
|
||||
[Serialize(GapPosition.Right | GapPosition.Left | GapPosition.Bottom | GapPosition.Top, IsPropertySaveable.Yes, description: "Which sides of this module are allowed to attach to the previously placed module. E.g. if you want a module to always attach to the left side of the docking module, you could set this to Right.")]
|
||||
public GapPosition CanAttachToPrevious { get; set; }
|
||||
|
||||
public string Name { get; private set; }
|
||||
|
||||
public Dictionary<Identifier, SerializableProperty> SerializableProperties { get; private set; }
|
||||
|
||||
@@ -48,11 +48,11 @@ namespace Barotrauma
|
||||
{
|
||||
if (!subs.Any()) yield return CoroutineStatus.Success;
|
||||
|
||||
Character.Controlled = null;
|
||||
cam.TargetPos = Vector2.Zero;
|
||||
#if CLIENT
|
||||
Character.Controlled = null;
|
||||
GameMain.LightManager.LosEnabled = false;
|
||||
#endif
|
||||
cam.TargetPos = Vector2.Zero;
|
||||
|
||||
Level.Loaded.TopBarrier.Enabled = false;
|
||||
|
||||
|
||||
@@ -322,7 +322,7 @@ namespace Barotrauma
|
||||
#endif
|
||||
|
||||
Tags = tags.ToImmutableHashSet();
|
||||
AllowedLinks = Enumerable.Empty<Identifier>().ToImmutableHashSet();
|
||||
AllowedLinks = ImmutableHashSet<Identifier>.Empty;
|
||||
}
|
||||
|
||||
protected override void CreateInstance(Rectangle rect)
|
||||
|
||||
Reference in New Issue
Block a user