(5a377a8ee) Unstable v0.9.1000.0
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using FarseerPhysics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -9,6 +10,8 @@ namespace Barotrauma
|
||||
{
|
||||
const float IntensityUpdateInterval = 5.0f;
|
||||
|
||||
const float CalculateDistanceTraveledInterval = 5.0f;
|
||||
|
||||
private Level level;
|
||||
|
||||
private readonly List<Sprite> preloadedSprites = new List<Sprite>();
|
||||
@@ -30,6 +33,11 @@ namespace Barotrauma
|
||||
|
||||
private float intensityUpdateTimer;
|
||||
|
||||
private PathFinder pathFinder;
|
||||
private float totalPathLength;
|
||||
private float calculateDistanceTraveledTimer;
|
||||
private float distanceTraveled;
|
||||
|
||||
private float avgCrewHealth, avgHullIntegrity, floodingAmount, fireAmount, enemyDanger;
|
||||
|
||||
private float roundDuration;
|
||||
@@ -72,6 +80,10 @@ namespace Barotrauma
|
||||
pendingEventSets.Clear();
|
||||
selectedEvents.Clear();
|
||||
|
||||
pathFinder = new PathFinder(WayPoint.WayPointList, indoorsSteering: false);
|
||||
var steeringPath = pathFinder.FindPath(ConvertUnits.ToSimUnits(Level.Loaded.StartPosition), ConvertUnits.ToSimUnits(Level.Loaded.EndPosition));
|
||||
totalPathLength = steeringPath.TotalLength;
|
||||
|
||||
this.level = level;
|
||||
SelectSettings();
|
||||
|
||||
@@ -137,7 +149,44 @@ namespace Barotrauma
|
||||
|
||||
public void PreloadContent(IEnumerable<ContentFile> contentFiles)
|
||||
{
|
||||
foreach (ContentFile file in contentFiles)
|
||||
var filesToPreload = new List<ContentFile>(contentFiles);
|
||||
foreach (Submarine sub in Submarine.Loaded)
|
||||
{
|
||||
if (sub.WreckAI == null) { continue; }
|
||||
|
||||
if (!string.IsNullOrEmpty(sub.WreckAI.Config.DefensiveAgent))
|
||||
{
|
||||
var prefab = CharacterPrefab.FindBySpeciesName(sub.WreckAI.Config.DefensiveAgent);
|
||||
if (prefab != null && !filesToPreload.Any(f => f.Path == prefab.FilePath))
|
||||
{
|
||||
filesToPreload.Add(new ContentFile(prefab.FilePath, ContentType.Character));
|
||||
}
|
||||
}
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
if (item.Submarine != sub) { continue; }
|
||||
foreach (Items.Components.ItemComponent component in item.Components)
|
||||
{
|
||||
if (component.statusEffectLists == null) { continue; }
|
||||
foreach (var statusEffectList in component.statusEffectLists.Values)
|
||||
{
|
||||
foreach (StatusEffect statusEffect in statusEffectList)
|
||||
{
|
||||
foreach (var spawnInfo in statusEffect.SpawnCharacters)
|
||||
{
|
||||
var prefab = CharacterPrefab.FindBySpeciesName(spawnInfo.SpeciesName);
|
||||
if (prefab != null && !filesToPreload.Any(f => f.Path == prefab.FilePath))
|
||||
{
|
||||
filesToPreload.Add(new ContentFile(prefab.FilePath, ContentType.Character));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (ContentFile file in filesToPreload)
|
||||
{
|
||||
switch (file.Type)
|
||||
{
|
||||
@@ -225,7 +274,7 @@ namespace Barotrauma
|
||||
}
|
||||
else if (eventSet.PerWreck)
|
||||
{
|
||||
applyCount = Submarine.Loaded.Count(s => s.Info.IsWreck && (s.ThalamusAI == null || !s.ThalamusAI.IsAlive));
|
||||
applyCount = Submarine.Loaded.Count(s => s.Info.IsWreck && (s.WreckAI == null || !s.WreckAI.IsAlive));
|
||||
}
|
||||
for (int i = 0; i < applyCount; i++)
|
||||
{
|
||||
@@ -299,12 +348,9 @@ namespace Barotrauma
|
||||
|
||||
private bool CanStartEventSet(ScriptedEventSet eventSet)
|
||||
{
|
||||
float distFromStart = Vector2.Distance(Submarine.MainSub.WorldPosition, level.StartPosition);
|
||||
float distFromEnd = Vector2.Distance(Submarine.MainSub.WorldPosition, level.EndPosition);
|
||||
|
||||
float distanceTraveled = MathHelper.Clamp(
|
||||
(Submarine.MainSub.WorldPosition.X - level.StartPosition.X) / (level.EndPosition.X - level.StartPosition.X),
|
||||
0.0f, 1.0f);
|
||||
ISpatialEntity refEntity = GetRefEntity();
|
||||
float distFromStart = Vector2.Distance(refEntity.WorldPosition, level.StartPosition);
|
||||
float distFromEnd = Vector2.Distance(refEntity.WorldPosition, level.EndPosition);
|
||||
|
||||
//don't create new events if within 50 meters of the start/end of the level
|
||||
if (!eventSet.AllowAtStart)
|
||||
@@ -367,6 +413,13 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
calculateDistanceTraveledTimer -= deltaTime;
|
||||
if (calculateDistanceTraveledTimer <= 0.0f)
|
||||
{
|
||||
distanceTraveled = CalculateDistanceTraveled();
|
||||
calculateDistanceTraveledTimer = CalculateDistanceTraveledInterval;
|
||||
}
|
||||
|
||||
eventThreshold += settings.EventThresholdIncrease * deltaTime;
|
||||
if (eventCoolDown > 0.0f)
|
||||
{
|
||||
@@ -514,5 +567,62 @@ namespace Barotrauma
|
||||
currentIntensity = MathHelper.Max(0.0025f * IntensityUpdateInterval, targetIntensity);
|
||||
}
|
||||
}
|
||||
|
||||
private float CalculateDistanceTraveled()
|
||||
{
|
||||
var refEntity = GetRefEntity();
|
||||
Vector2 target = ConvertUnits.ToSimUnits(Level.Loaded.EndPosition);
|
||||
var steeringPath = pathFinder.FindPath(ConvertUnits.ToSimUnits(refEntity.WorldPosition), target);
|
||||
if (steeringPath.Unreachable || float.IsPositiveInfinity(totalPathLength))
|
||||
{
|
||||
//use horizontal position in the level as a fallback if a path can't be found
|
||||
return MathHelper.Clamp((refEntity.WorldPosition.X - level.StartPosition.X) / (level.EndPosition.X - level.StartPosition.X), 0.0f, 1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
return MathHelper.Clamp(1.0f - steeringPath.TotalLength / totalPathLength, 0.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get the entity that should be used in determining how far the player has progressed in the level.
|
||||
/// = The submarine or player character that has progressed the furthest.
|
||||
/// </summary>
|
||||
private ISpatialEntity GetRefEntity()
|
||||
{
|
||||
ISpatialEntity refEntity = Submarine.MainSub;
|
||||
#if CLIENT
|
||||
if (Character.Controlled != null)
|
||||
{
|
||||
if (Character.Controlled.Submarine != null &&
|
||||
Character.Controlled.Submarine.Info.Type == SubmarineInfo.SubmarineType.Player)
|
||||
{
|
||||
refEntity = Character.Controlled.Submarine;
|
||||
}
|
||||
else
|
||||
{
|
||||
refEntity = Character.Controlled;
|
||||
}
|
||||
}
|
||||
#else
|
||||
foreach (Barotrauma.Networking.Client client in GameMain.Server.ConnectedClients)
|
||||
{
|
||||
if (client.Character == null) { continue; }
|
||||
//only take the players inside a player sub into account.
|
||||
//Otherwise the system could be abused by for example making a respawned player wait
|
||||
//close to the destination outpost
|
||||
if (client.Character.Submarine != null &&
|
||||
client.Character.Submarine.Info.Type == SubmarineInfo.SubmarineType.Player)
|
||||
{
|
||||
if (client.Character.Submarine.WorldPosition.X > refEntity.WorldPosition.X)
|
||||
{
|
||||
refEntity = client.Character.Submarine;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return refEntity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,8 +24,9 @@ namespace Barotrauma
|
||||
public readonly float MinLevelDifficulty = 0.0f;
|
||||
public readonly float MaxLevelDifficulty = 100.0f;
|
||||
|
||||
static EventManagerSettings()
|
||||
public static void Init()
|
||||
{
|
||||
List.Clear();
|
||||
foreach (ContentFile file in GameMain.Instance.GetFilesOfType(ContentType.EventManagerSettings))
|
||||
{
|
||||
Load(file);
|
||||
|
||||
@@ -108,23 +108,6 @@ namespace Barotrauma
|
||||
subs[1].SetPosition(subs[1].FindSpawnPos(Level.Loaded.EndPosition));
|
||||
subs[1].FlipX();
|
||||
|
||||
//prevent wifi components from communicating between subs
|
||||
List<WifiComponent> wifiComponents = new List<WifiComponent>();
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
wifiComponents.AddRange(item.GetComponents<WifiComponent>());
|
||||
}
|
||||
foreach (WifiComponent wifiComponent in wifiComponents)
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (wifiComponent.Item.Submarine == subs[i] || subs[i].ConnectedDockingPorts.ContainsKey(wifiComponent.Item.Submarine))
|
||||
{
|
||||
wifiComponent.TeamID = subs[i].TeamID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
crews = new List<Character>[] { new List<Character>(), new List<Character>() };
|
||||
|
||||
foreach (Submarine submarine in Submarine.Loaded)
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace Barotrauma
|
||||
monsterFiles.Add(new Tuple<string, Point>(monster, new Point(min, max)));
|
||||
}
|
||||
description = description.Replace("[monster]",
|
||||
TextManager.Get("character." + System.IO.Path.GetFileNameWithoutExtension(monsterFileName)));
|
||||
TextManager.Get("character." + Barotrauma.IO.Path.GetFileNameWithoutExtension(monsterFileName)));
|
||||
}
|
||||
|
||||
public override void Start(Level level)
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
using FarseerPhysics;
|
||||
using Barotrauma.Extensions;
|
||||
using FarseerPhysics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -17,11 +19,14 @@ namespace Barotrauma
|
||||
private readonly string containerTag;
|
||||
|
||||
private readonly string existingItemTag;
|
||||
|
||||
private bool usedExistingItem;
|
||||
|
||||
|
||||
private readonly bool showMessageWhenPickedUp;
|
||||
|
||||
/// <summary>
|
||||
/// Status effects executed on the target item when the mission starts. A random effect is chosen from each child list.
|
||||
/// </summary>
|
||||
private readonly List<List<StatusEffect>> statusEffects = new List<List<StatusEffect>>();
|
||||
|
||||
public override IEnumerable<Vector2> SonarPositions
|
||||
{
|
||||
get
|
||||
@@ -71,6 +76,29 @@ namespace Barotrauma
|
||||
{
|
||||
spawnPositionType = Level.PositionType.Cave | Level.PositionType.Ruin;
|
||||
}
|
||||
|
||||
foreach (XElement element in prefab.ConfigElement.Elements())
|
||||
{
|
||||
switch (element.Name.ToString().ToLowerInvariant())
|
||||
{
|
||||
case "statuseffect":
|
||||
{
|
||||
var newEffect = StatusEffect.Load(element, parentDebugName: prefab.Name);
|
||||
if (newEffect == null) { continue; }
|
||||
statusEffects.Add(new List<StatusEffect> { newEffect });
|
||||
break;
|
||||
}
|
||||
case "chooserandom":
|
||||
statusEffects.Add(new List<StatusEffect>());
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
var newEffect = StatusEffect.Load(subElement, parentDebugName: prefab.Name);
|
||||
if (newEffect == null) { continue; }
|
||||
statusEffects.Last().Add(newEffect);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Start(Level level)
|
||||
@@ -103,7 +131,9 @@ namespace Barotrauma
|
||||
if (Submarine.RectContains(worldBorders, it.WorldPosition))
|
||||
{
|
||||
item = it;
|
||||
#if SERVER
|
||||
usedExistingItem = true;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -118,6 +148,18 @@ namespace Barotrauma
|
||||
item.FindHull();
|
||||
}
|
||||
|
||||
for (int i = 0; i < statusEffects.Count; i++)
|
||||
{
|
||||
List<StatusEffect> effectList = statusEffects[i];
|
||||
if (effectList.Count == 0) { continue; }
|
||||
int effectIndex = Rand.Int(effectList.Count);
|
||||
var selectedEffect = effectList[effectIndex];
|
||||
item.ApplyStatusEffect(selectedEffect, selectedEffect.type, deltaTime: 1.0f, worldPosition: item.Position);
|
||||
#if SERVER
|
||||
executedEffectIndices.Add(new Pair<int, int>(i, effectIndex));
|
||||
#endif
|
||||
}
|
||||
|
||||
//try to find a container and place the item inside it
|
||||
if (!string.IsNullOrEmpty(containerTag) && item.ParentInventory == null)
|
||||
{
|
||||
@@ -147,15 +189,23 @@ namespace Barotrauma
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
#if DEBUG
|
||||
DebugConsole.ThrowError("Error in salvage mission " + Prefab.Identifier + " (item was null)");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsClient)
|
||||
{
|
||||
if (item.ParentInventory != null) { item.body.FarseerBody.BodyType = BodyType.Dynamic; }
|
||||
if (item.ParentInventory != null && item.body != null) { item.body.FarseerBody.BodyType = BodyType.Dynamic; }
|
||||
return;
|
||||
}
|
||||
switch (State)
|
||||
{
|
||||
case 0:
|
||||
if (item.ParentInventory != null) { item.body.FarseerBody.BodyType = BodyType.Dynamic; }
|
||||
if (item.ParentInventory != null && item.body != null) { item.body.FarseerBody.BodyType = BodyType.Dynamic; }
|
||||
if (showMessageWhenPickedUp)
|
||||
{
|
||||
if (!(item.ParentInventory?.Owner is Character)) { return; }
|
||||
@@ -175,7 +225,10 @@ namespace Barotrauma
|
||||
|
||||
public override void End()
|
||||
{
|
||||
if (item.CurrentHull?.Submarine == null || !item.CurrentHull.Submarine.AtEndPosition || item.Removed) { return; }
|
||||
if (item.CurrentHull?.Submarine == null || (!item.CurrentHull.Submarine.AtEndPosition && !item.CurrentHull.Submarine.AtStartPosition) || item.Removed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
item?.Remove();
|
||||
item = null;
|
||||
|
||||
@@ -118,13 +118,13 @@ namespace Barotrauma
|
||||
|
||||
private List<Level.InterestingPosition> GetAvailableSpawnPositions()
|
||||
{
|
||||
var availablePositions = Level.Loaded.PositionsOfInterest.FindAll(p => spawnPosType.HasFlag(p.PositionType) && !Level.Loaded.UsedPositions.Contains(p));
|
||||
var availablePositions = Level.Loaded.PositionsOfInterest.FindAll(p => spawnPosType.HasFlag(p.PositionType));
|
||||
var removals = new List<Level.InterestingPosition>();
|
||||
foreach (var position in availablePositions)
|
||||
{
|
||||
if (position.Submarine != null)
|
||||
{
|
||||
if (position.Submarine.ThalamusAI != null && position.Submarine.ThalamusAI.IsAlive)
|
||||
if (position.Submarine.WreckAI != null && position.Submarine.WreckAI.IsAlive)
|
||||
{
|
||||
removals.Add(position);
|
||||
}
|
||||
@@ -169,10 +169,6 @@ namespace Barotrauma
|
||||
if (Rand.Value(Rand.RandSync.Server) > prefab.SpawnProbability)
|
||||
{
|
||||
removedPositions.Add(position);
|
||||
if (prefab.AllowOnlyOnce)
|
||||
{
|
||||
Level.Loaded.UsedPositions.Add(position);
|
||||
}
|
||||
}
|
||||
}
|
||||
removedPositions.ForEach(p => availablePositions.Remove(p));
|
||||
@@ -237,17 +233,15 @@ namespace Barotrauma
|
||||
spawnPos = chosenPosition.Position.ToVector2();
|
||||
if (chosenPosition.Submarine != null || chosenPosition.Ruin != null)
|
||||
{
|
||||
var spawnPoint = WayPoint.GetRandom(SpawnType.Enemy, sub: chosenPosition.Submarine, useSyncedRand: false);
|
||||
if (spawnPoint != null)
|
||||
var spawnPoint = WayPoint.GetRandom(SpawnType.Enemy, sub: chosenPosition.Submarine, ruin: chosenPosition.Ruin, useSyncedRand: false);
|
||||
if (spawnPoint != null)
|
||||
{
|
||||
spawnPos = spawnPoint.WorldPosition;
|
||||
System.Diagnostics.Debug.Assert(spawnPoint.Submarine == chosenPosition.Submarine);
|
||||
System.Diagnostics.Debug.Assert(spawnPoint.ParentRuin == chosenPosition.Ruin);
|
||||
spawnPos = spawnPoint.WorldPosition;
|
||||
}
|
||||
}
|
||||
spawnPending = true;
|
||||
if (prefab.AllowOnlyOnce)
|
||||
{
|
||||
Level.Loaded.UsedPositions.Add(chosenPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -276,11 +270,14 @@ namespace Barotrauma
|
||||
if (spawnPending)
|
||||
{
|
||||
//wait until there are no submarines at the spawnpos
|
||||
foreach (Submarine submarine in Submarine.Loaded)
|
||||
if (spawnPosType == Level.PositionType.MainPath)
|
||||
{
|
||||
if (submarine.Info.Type != SubmarineInfo.SubmarineType.Player) { continue; }
|
||||
float minDist = GetMinDistanceToSub(submarine);
|
||||
if (Vector2.DistanceSquared(submarine.WorldPosition, spawnPos.Value) < minDist * minDist) { return; }
|
||||
foreach (Submarine submarine in Submarine.Loaded)
|
||||
{
|
||||
if (submarine.Info.Type != SubmarineInfo.SubmarineType.Player) { continue; }
|
||||
float minDist = GetMinDistanceToSub(submarine);
|
||||
if (Vector2.DistanceSquared(submarine.WorldPosition, spawnPos.Value) < minDist * minDist) { return; }
|
||||
}
|
||||
}
|
||||
|
||||
//if spawning in a ruin/cave, wait for someone to be close to it to spawning
|
||||
|
||||
@@ -11,7 +11,6 @@ namespace Barotrauma
|
||||
public readonly Type EventType;
|
||||
public readonly string MusicType;
|
||||
public readonly float SpawnProbability;
|
||||
public readonly bool AllowOnlyOnce;
|
||||
public float Commonness;
|
||||
|
||||
public ScriptedEventPrefab(XElement element)
|
||||
@@ -34,7 +33,6 @@ namespace Barotrauma
|
||||
}
|
||||
Commonness = element.GetAttributeFloat("commonness", 1.0f);
|
||||
SpawnProbability = Math.Clamp(element.GetAttributeFloat("spawnprobability", 1.0f), 0, 1);
|
||||
AllowOnlyOnce = element.GetAttributeBool("allowonlyonce", false);
|
||||
}
|
||||
|
||||
public ScriptedEvent CreateInstance()
|
||||
|
||||
Reference in New Issue
Block a user