(f0d812055) v0.9.9.0

This commit is contained in:
Joonas Rikkonen
2020-04-23 19:19:37 +03:00
parent b647059b93
commit ac37a3b0e4
391 changed files with 15054 additions and 5420 deletions
@@ -1,6 +1,4 @@
using Microsoft.Xna.Framework;
using System;
using System.Xml.Linq;
namespace Barotrauma
{
@@ -53,7 +51,7 @@ namespace Barotrauma
public override void Init(bool affectSubImmediately)
{
spawnPos = Level.Loaded.GetRandomItemPos(
(Rand.Range(0.0f, 1.0f, Rand.RandSync.Server) < 0.5f) ? Level.PositionType.MainPath : Level.PositionType.Cave | Level.PositionType.Ruin,
(Rand.Value(Rand.RandSync.Server) < 0.5f) ? Level.PositionType.MainPath : Level.PositionType.Cave | Level.PositionType.Ruin,
500.0f, 10000.0f, 30.0f);
spawnPending = true;
@@ -2,7 +2,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma
{
@@ -219,13 +218,44 @@ namespace Barotrauma
private void CreateEvents(ScriptedEventSet eventSet)
{
if (eventSet.ChooseRandom)
int applyCount = 1;
if (eventSet.PerRuin)
{
if (eventSet.EventPrefabs.Count > 0)
applyCount = Level.Loaded.Ruins.Count();
}
else if (eventSet.PerWreck)
{
applyCount = Submarine.Loaded.Count(s => s.Info.IsWreck && (s.WreckAI == null || !s.WreckAI.IsAlive));
}
for (int i = 0; i < applyCount; i++)
{
if (eventSet.ChooseRandom)
{
MTRandom rand = new MTRandom(ToolBox.StringToInt(level.Seed));
var eventPrefab = ToolBox.SelectWeightedRandom(eventSet.EventPrefabs, eventSet.EventPrefabs.Select(e => e.Commonness).ToList(), rand);
if (eventPrefab != null)
if (eventSet.EventPrefabs.Count > 0)
{
MTRandom rand = new MTRandom(ToolBox.StringToInt(level.Seed));
var eventPrefab = ToolBox.SelectWeightedRandom(eventSet.EventPrefabs, eventSet.EventPrefabs.Select(e => e.Commonness).ToList(), rand);
if (eventPrefab != null)
{
var newEvent = eventPrefab.CreateInstance();
newEvent.Init(true);
DebugConsole.Log("Initialized event " + newEvent.ToString());
if (!selectedEvents.ContainsKey(eventSet))
{
selectedEvents.Add(eventSet, new List<ScriptedEvent>());
}
selectedEvents[eventSet].Add(newEvent);
}
}
if (eventSet.ChildSets.Count > 0)
{
var newEventSet = SelectRandomEvents(eventSet.ChildSets);
if (newEventSet != null) { CreateEvents(newEventSet); }
}
}
else
{
foreach (ScriptedEventPrefab eventPrefab in eventSet.EventPrefabs)
{
var newEvent = eventPrefab.CreateInstance();
newEvent.Init(true);
@@ -236,30 +266,11 @@ namespace Barotrauma
}
selectedEvents[eventSet].Add(newEvent);
}
}
if (eventSet.ChildSets.Count > 0)
{
var newEventSet = SelectRandomEvents(eventSet.ChildSets);
if (newEventSet != null) { CreateEvents(newEventSet); }
}
}
else
{
foreach (ScriptedEventPrefab eventPrefab in eventSet.EventPrefabs)
{
var newEvent = eventPrefab.CreateInstance();
newEvent.Init(true);
DebugConsole.Log("Initialized event " + newEvent.ToString());
if (!selectedEvents.ContainsKey(eventSet))
{
selectedEvents.Add(eventSet, new List<ScriptedEvent>());
}
selectedEvents[eventSet].Add(newEvent);
}
foreach (ScriptedEventSet childEventSet in eventSet.ChildSets)
{
CreateEvents(childEventSet);
foreach (ScriptedEventSet childEventSet in eventSet.ChildSets)
{
CreateEvents(childEventSet);
}
}
}
}
@@ -296,11 +307,14 @@ namespace Barotrauma
0.0f, 1.0f);
//don't create new events if within 50 meters of the start/end of the level
if (distanceTraveled <= 0.0f ||
distFromStart * Physics.DisplayToRealWorldRatio < 50.0f ||
distFromEnd * Physics.DisplayToRealWorldRatio < 50.0f)
if (!eventSet.AllowAtStart)
{
return false;
if (distanceTraveled <= 0.0f ||
distFromStart * Physics.DisplayToRealWorldRatio < 50.0f ||
distFromEnd * Physics.DisplayToRealWorldRatio < 50.0f)
{
return false;
}
}
if ((Submarine.MainSub == null || distanceTraveled < eventSet.MinDistanceTraveled) &&
@@ -368,17 +382,15 @@ namespace Barotrauma
pendingEventSets.RemoveAt(i);
if (!selectedEvents.ContainsKey(eventSet))
if (selectedEvents.ContainsKey(eventSet))
{
//no events selected from this event set
continue;
//start events in this set
foreach (ScriptedEvent scriptedEvent in selectedEvents[eventSet])
{
activeEvents.Add(scriptedEvent);
}
}
//start events in this set
foreach (ScriptedEvent scriptedEvent in selectedEvents[eventSet])
{
activeEvents.Add(scriptedEvent);
}
//add child event sets to pending
foreach (ScriptedEventSet childEventSet in eventSet.ChildSets)
{
@@ -431,7 +443,7 @@ namespace Barotrauma
enemyDanger = 0.0f;
foreach (Character character in Character.CharacterList)
{
if (character.IsDead || character.IsUnconscious || !character.Enabled) continue;
if (character.IsDead || character.IsIncapacitated || !character.Enabled) continue;
EnemyAIController enemyAI = character.AIController as EnemyAIController;
if (enemyAI == null) continue;
@@ -458,7 +470,7 @@ namespace Barotrauma
int hullCount = 0;
foreach (Hull hull in Hull.hullList)
{
if (hull.Submarine == null || hull.Submarine.IsOutpost) { continue; }
if (hull.Submarine == null || hull.Submarine.Info.Type != SubmarineInfo.SubmarineType.Player) { continue; }
hullCount++;
foreach (Gap gap in hull.ConnectedGaps)
{
@@ -69,7 +69,7 @@ namespace Barotrauma
return;
}
WayPoint cargoSpawnPos = WayPoint.GetRandom(SpawnType.Cargo, null, Submarine.MainSub, true);
WayPoint cargoSpawnPos = WayPoint.GetRandom(SpawnType.Cargo, null, Submarine.MainSub, useSyncedRand: true);
if (cargoSpawnPos == null)
{
DebugConsole.ThrowError("Couldn't spawn items for cargo mission, cargo spawnpoint not found");
@@ -176,11 +176,11 @@ namespace Barotrauma
{
foreach (Pair<string, string> allowedLocationType in AllowedLocationTypes)
{
if (allowedLocationType.First.ToLowerInvariant() == "any" ||
allowedLocationType.First.ToLowerInvariant() == from.Type.Identifier.ToLowerInvariant())
if (allowedLocationType.First.Equals("any", StringComparison.OrdinalIgnoreCase) ||
allowedLocationType.First.Equals(from.Type.Identifier, StringComparison.OrdinalIgnoreCase))
{
if (allowedLocationType.Second.ToLowerInvariant() == "any" ||
allowedLocationType.Second.ToLowerInvariant() == to.Type.Identifier.ToLowerInvariant())
if (allowedLocationType.Second.Equals("any", StringComparison.OrdinalIgnoreCase) ||
allowedLocationType.Second.Equals(to.Type.Identifier, StringComparison.OrdinalIgnoreCase))
{
return true;
}
@@ -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
{
@@ -13,6 +15,17 @@ namespace Barotrauma
private Item item;
private readonly Level.PositionType spawnPositionType;
private readonly string containerTag;
private readonly string existingItemTag;
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
{
@@ -24,7 +37,7 @@ namespace Barotrauma
}
else
{
yield return ConvertUnits.ToDisplayUnits(item.SimPosition);
yield return item.WorldPosition;
}
}
}
@@ -32,6 +45,8 @@ namespace Barotrauma
public SalvageMission(MissionPrefab prefab, Location[] locations)
: base(prefab, locations)
{
containerTag = prefab.ConfigElement.GetAttributeString("containertag", "");
if (prefab.ConfigElement.Attribute("itemname") != null)
{
DebugConsole.ThrowError("Error in SalvageMission - use item identifier instead of the name of the item.");
@@ -52,32 +67,118 @@ namespace Barotrauma
}
}
existingItemTag = prefab.ConfigElement.GetAttributeString("existingitemtag", "");
showMessageWhenPickedUp = prefab.ConfigElement.GetAttributeBool("showmessagewhenpickedup", false);
string spawnPositionTypeStr = prefab.ConfigElement.GetAttributeString("spawntype", "");
if (string.IsNullOrWhiteSpace(spawnPositionTypeStr) ||
!Enum.TryParse(spawnPositionTypeStr, true, out spawnPositionType))
{
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)
{
if (!IsClient)
{
//ruin items are allowed to spawn close to the sub
float minDistance = spawnPositionType == Level.PositionType.Ruin ? 0.0f : Level.Loaded.Size.X * 0.3f;
//ruin/wreck items are allowed to spawn close to the sub
float minDistance = spawnPositionType == Level.PositionType.Ruin || spawnPositionType == Level.PositionType.Wreck ?
0.0f : Level.Loaded.Size.X * 0.3f;
Vector2 position = Level.Loaded.GetRandomItemPos(spawnPositionType, 100.0f, minDistance, 30.0f);
item = new Item(itemPrefab, position, null);
item.body.FarseerBody.BodyType = BodyType.Kinematic;
if (item.HasTag("alien"))
if (!string.IsNullOrEmpty(existingItemTag))
{
var suitableItems = Item.ItemList.Where(it => it.HasTag(existingItemTag));
switch (spawnPositionType)
{
case Level.PositionType.Cave:
case Level.PositionType.MainPath:
item = suitableItems.FirstOrDefault(it => Vector2.DistanceSquared(it.WorldPosition, position) < 1000.0f);
break;
case Level.PositionType.Ruin:
item = suitableItems.FirstOrDefault(it => it.ParentRuin != null && it.ParentRuin.Area.Contains(position));
break;
case Level.PositionType.Wreck:
foreach (Item it in suitableItems)
{
if (it.Submarine == null || it.Submarine.Info.Type != SubmarineInfo.SubmarineType.Wreck) { continue; }
Rectangle worldBorders = it.Submarine.Borders;
worldBorders.Location += it.Submarine.WorldPosition.ToPoint();
if (Submarine.RectContains(worldBorders, it.WorldPosition))
{
item = it;
#if SERVER
usedExistingItem = true;
#endif
break;
}
}
break;
}
}
if (item == null)
{
item = new Item(itemPrefab, position, null);
item.body.FarseerBody.BodyType = BodyType.Kinematic;
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)
{
//try to find an artifact holder and place the artifact inside it
foreach (Item it in Item.ItemList)
{
if (it.Submarine != null || !it.HasTag("artifactholder")) continue;
if (!it.HasTag(containerTag)) { continue; }
switch (spawnPositionType)
{
case Level.PositionType.Cave:
case Level.PositionType.MainPath:
if (it.Submarine != null || it.ParentRuin != null) { continue; }
break;
case Level.PositionType.Ruin:
if (it.ParentRuin == null) { continue; }
break;
case Level.PositionType.Wreck:
if (it.Submarine == null || it.Submarine.Info.Type != SubmarineInfo.SubmarineType.Wreck) { continue; }
break;
}
var itemContainer = it.GetComponent<Items.Components.ItemContainer>();
if (itemContainer == null) { continue; }
if (itemContainer.Combine(item, user: null)) { break; } // Placement successful
@@ -88,28 +189,46 @@ 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.CurrentHull?.Submarine == null) { return; }
if (item.ParentInventory != null && item.body != null) { item.body.FarseerBody.BodyType = BodyType.Dynamic; }
if (showMessageWhenPickedUp)
{
if (!(item.ParentInventory?.Owner is Character)) { return; }
}
else
{
if (item.CurrentHull?.Submarine == null || item.CurrentHull.Submarine.Info.Type != SubmarineInfo.SubmarineType.Player) { return; }
}
State = 1;
break;
case 1:
if (!Submarine.MainSub.AtEndPosition && !Submarine.MainSub.AtStartPosition) { return; }
State = 2;
break;
}
}
}
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;
@@ -1,50 +1,46 @@
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using Barotrauma.Extensions;
using Barotrauma.Items.Components;
namespace Barotrauma
{
class MonsterEvent : ScriptedEvent
{
private string speciesName;
private int minAmount, maxAmount;
private readonly string speciesName;
private readonly int minAmount, maxAmount;
private List<Character> monsters;
private bool spawnDeep;
private readonly bool spawnDeep;
private Vector2? spawnPos;
private bool disallowed;
private Level.PositionType spawnPosType;
private readonly bool disallowed;
private readonly Level.PositionType spawnPosType;
private bool spawnPending;
private string characterFileName;
public override Vector2 DebugDrawPos
{
get { return spawnPos.HasValue ? spawnPos.Value : Vector2.Zero; }
get { return spawnPos ?? Vector2.Zero; }
}
public override string ToString()
{
if (maxAmount <= 1)
{
return "MonsterEvent (" + characterFileName + ")";
return "MonsterEvent (" + speciesName + ")";
}
else if (minAmount < maxAmount)
{
return "MonsterEvent (" + characterFileName + " x" + minAmount + "-" + maxAmount + ")";
return "MonsterEvent (" + speciesName + " x" + minAmount + "-" + maxAmount + ")";
}
else
{
return "MonsterEvent (" + characterFileName + " x" + maxAmount + ")";
return "MonsterEvent (" + speciesName + " x" + maxAmount + ")";
}
}
@@ -76,7 +72,6 @@ namespace Barotrauma
}
spawnDeep = prefab.ConfigElement.GetAttributeBool("spawndeep", false);
characterFileName = Path.GetFileName(Path.GetDirectoryName(speciesName)).ToLower();
if (GameMain.NetworkMember != null)
{
@@ -85,7 +80,10 @@ namespace Barotrauma
if (!string.IsNullOrWhiteSpace(tryKey))
{
if (!GameMain.NetworkMember.ServerSettings.MonsterEnabled[tryKey]) disallowed = true; //spawn was disallowed by host
if (!GameMain.NetworkMember.ServerSettings.MonsterEnabled[tryKey])
{
disallowed = true; //spawn was disallowed by host
}
}
}
}
@@ -106,18 +104,8 @@ namespace Barotrauma
public override bool CanAffectSubImmediately(Level level)
{
float maxRange = Items.Components.Sonar.DefaultSonarRange * 0.8f;
List<Vector2> positions = GetAvailableSpawnPositions();
foreach (Vector2 position in positions)
{
if (Vector2.DistanceSquared(position, Submarine.MainSub.WorldPosition) < maxRange * maxRange)
{
return true;
}
}
return false;
float maxRange = Sonar.DefaultSonarRange * 0.8f;
return GetAvailableSpawnPositions().Any(p => Vector2.DistanceSquared(p.Position.ToVector2(), Submarine.MainSub.WorldPosition) < maxRange * maxRange);
}
public override void Init(bool affectSubImmediately)
@@ -128,28 +116,44 @@ namespace Barotrauma
}
}
private List<Vector2> GetAvailableSpawnPositions()
private List<Level.InterestingPosition> GetAvailableSpawnPositions()
{
var availablePositions = Level.Loaded.PositionsOfInterest.FindAll(p => spawnPosType.HasFlag(p.PositionType));
List<Vector2> positions = new List<Vector2>();
foreach (var allowedPosition in availablePositions)
var availablePositions = Level.Loaded.PositionsOfInterest.FindAll(p => spawnPosType.HasFlag(p.PositionType) && !Level.Loaded.UsedPositions.Contains(p));
var removals = new List<Level.InterestingPosition>();
foreach (var position in availablePositions)
{
if (Level.Loaded.ExtraWalls.Any(w => w.Cells.Any(c => c.IsPointInside(allowedPosition.Position.ToVector2())))) { continue; }
positions.Add(allowedPosition.Position.ToVector2());
}
if (spawnDeep)
{
for (int i = 0; i < positions.Count; i++)
if (position.Submarine != null)
{
positions[i] = new Vector2(positions[i].X, positions[i].Y - Level.Loaded.Size.Y);
if (position.Submarine.WreckAI != null && position.Submarine.WreckAI.IsAlive)
{
removals.Add(position);
}
else
{
continue;
}
}
if (position.PositionType != Level.PositionType.MainPath) { continue; }
if (Level.Loaded.ExtraWalls.Any(w => w.Cells.Any(c => c.IsPointInside(position.Position.ToVector2()))))
{
removals.Add(position);
}
if (spawnDeep)
{
for (int i = 0; i < availablePositions.Count; i++)
{
var pos = availablePositions[i].Position;
pos = new Point(pos.X, pos.Y - Level.Loaded.Size.Y);
availablePositions[i] = new Level.InterestingPosition(pos, availablePositions[i].PositionType);
}
}
if (position.Position.Y < Level.Loaded.GetBottomPosition(position.Position.X).Y)
{
removals.Add(position);
}
}
positions.RemoveAll(pos => pos.Y < Level.Loaded.GetBottomPosition(pos.X).Y);
return positions;
removals.ForEach(r => availablePositions.Remove(r));
return availablePositions;
}
private void FindSpawnPosition(bool affectSubImmediately)
@@ -158,67 +162,100 @@ namespace Barotrauma
spawnPos = Vector2.Zero;
var availablePositions = GetAvailableSpawnPositions();
if (affectSubImmediately && spawnPosType != Level.PositionType.Ruin)
var chosenPosition = new Level.InterestingPosition(Point.Zero, Level.PositionType.MainPath, isValid: false);
var removedPositions = new List<Level.InterestingPosition>();
foreach (var position in availablePositions)
{
if (availablePositions.Count == 0)
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));
bool isSubOrWreck = spawnPosType == Level.PositionType.Ruin || spawnPosType == Level.PositionType.Wreck;
if (affectSubImmediately && !isSubOrWreck)
{
if (availablePositions.None())
{
//no suitable position found, disable the event
Finished();
return;
}
float closestDist = float.PositiveInfinity;
//find the closest spawnposition that isn't too close to any of the subs
foreach (Vector2 position in availablePositions)
foreach (var position in availablePositions)
{
float dist = Vector2.DistanceSquared(position, Submarine.MainSub.WorldPosition);
Vector2 pos = position.Position.ToVector2();
float dist = Vector2.DistanceSquared(pos, Submarine.MainSub.WorldPosition);
foreach (Submarine sub in Submarine.Loaded)
{
if (sub.IsOutpost) { continue; }
if (sub.Info.Type != SubmarineInfo.SubmarineType.Player) { continue; }
float minDistToSub = GetMinDistanceToSub(sub);
if (dist > minDistToSub * minDistToSub && dist < closestDist)
{
closestDist = dist;
spawnPos = position;
chosenPosition = position;
}
}
}
//only found a spawnpos that's very far from the sub, pick one that's closer
//and wait for the sub to move further before spawning
if (closestDist > 15000.0f * 15000.0f)
{
foreach (Vector2 position in availablePositions)
foreach (var position in availablePositions)
{
float dist = Vector2.DistanceSquared(position, Submarine.MainSub.WorldPosition);
float dist = Vector2.DistanceSquared(position.Position.ToVector2(), Submarine.MainSub.WorldPosition);
if (dist < closestDist)
{
closestDist = dist;
spawnPos = position;
chosenPosition = position;
}
}
}
}
else
{
float minDist = spawnPosType == Level.PositionType.Ruin ? 0.0f : 20000.0f;
availablePositions.RemoveAll(p => Vector2.Distance(Submarine.MainSub.WorldPosition, p) < minDist);
if (availablePositions.Count == 0)
if (!isSubOrWreck)
{
float minDistance = 20000;
availablePositions.RemoveAll(p => Vector2.DistanceSquared(Submarine.MainSub.WorldPosition, p.Position.ToVector2()) < minDistance * minDistance);
}
if (availablePositions.None())
{
//no suitable position found, disable the event
Finished();
return;
}
spawnPos = availablePositions[Rand.Int(availablePositions.Count, Rand.RandSync.Server)];
chosenPosition = availablePositions.GetRandom();
}
if (chosenPosition.IsValid)
{
spawnPos = chosenPosition.Position.ToVector2();
if (chosenPosition.Submarine != null || chosenPosition.Ruin != null)
{
var spawnPoint = WayPoint.GetRandom(SpawnType.Enemy, sub: chosenPosition.Submarine, ruin: chosenPosition.Ruin, useSyncedRand: false);
if (spawnPoint != null)
{
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);
}
}
spawnPending = true;
}
private float GetMinDistanceToSub(Submarine submarine)
{
//9000 units is slightly less than the default range of the sonar
return Math.Max(Math.Max(submarine.Borders.Width, submarine.Borders.Height), 9000.0f);
return Math.Max(Math.Max(submarine.Borders.Width, submarine.Borders.Height), Sonar.DefaultSonarRange * 0.9f);
}
public override void Update(float deltaTime)
@@ -243,9 +280,38 @@ namespace Barotrauma
//wait until there are no submarines at the spawnpos
foreach (Submarine submarine in Submarine.Loaded)
{
if (submarine.IsOutpost) { continue; }
if (submarine.Info.Type != SubmarineInfo.SubmarineType.Player) { continue; }
float minDist = GetMinDistanceToSub(submarine);
if (Vector2.DistanceSquared(submarine.WorldPosition, spawnPos.Value) < minDist * minDist) return;
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
//unnecessary monsters in places the players might never visit during the round
if (spawnPosType == Level.PositionType.Ruin || spawnPosType == Level.PositionType.Cave || spawnPosType == Level.PositionType.Wreck)
{
bool someoneNearby = false;
float minDist = Sonar.DefaultSonarRange * 0.8f;
foreach (Submarine submarine in Submarine.Loaded)
{
if (submarine.Info.Type != SubmarineInfo.SubmarineType.Player) { continue; }
if (Vector2.DistanceSquared(submarine.WorldPosition, spawnPos.Value) < minDist * minDist)
{
someoneNearby = true;
break;
}
}
foreach (Character c in Character.CharacterList)
{
if (c == Character.Controlled || c.IsRemotePlayer)
{
if (Vector2.DistanceSquared(c.WorldPosition, spawnPos.Value) < minDist * minDist)
{
someoneNearby = true;
break;
}
}
}
if (!someoneNearby) { return; }
}
spawnPending = false;
@@ -280,7 +346,7 @@ namespace Barotrauma
Entity targetEntity = Submarine.FindClosest(GameMain.GameScreen.Cam.WorldViewCenter);
#if CLIENT
if (Character.Controlled != null) targetEntity = (Entity)Character.Controlled;
if (Character.Controlled != null) { targetEntity = Character.Controlled; }
#endif
bool monstersDead = true;
@@ -297,7 +363,7 @@ namespace Barotrauma
}
}
if (monstersDead) Finished();
if (monstersDead) { Finished(); }
}
}
}
@@ -1,6 +1,5 @@
using Microsoft.Xna.Framework;
using System.Collections.Generic;
using System.Linq;
namespace Barotrauma
{
@@ -8,7 +7,7 @@ namespace Barotrauma
{
protected bool isFinished;
private readonly ScriptedEventPrefab prefab;
protected readonly ScriptedEventPrefab prefab;
public bool IsFinished
{
@@ -7,12 +7,11 @@ namespace Barotrauma
{
class ScriptedEventPrefab
{
public readonly XElement ConfigElement;
public readonly Type EventType;
public readonly XElement ConfigElement;
public readonly Type EventType;
public readonly string MusicType;
public readonly float SpawnProbability;
public readonly bool AllowOnlyOnce;
public float Commonness;
public ScriptedEventPrefab(XElement element)
@@ -34,6 +33,8 @@ namespace Barotrauma
DebugConsole.ThrowError("Could not find an event class of the type \"" + ConfigElement.Name + "\".");
}
Commonness = element.GetAttributeFloat("commonness", 1.0f);
SpawnProbability = Math.Clamp(element.GetAttributeFloat("spawnprobability", 1.0f), 0, 1);
AllowOnlyOnce = element.GetAttributeBool("allowonlyonce", false);
}
public ScriptedEvent CreateInstance()
@@ -25,6 +25,11 @@ namespace Barotrauma
//the events in this set are delayed if the current EventManager intensity is not between these values
public readonly float MinIntensity, MaxIntensity;
public readonly bool AllowAtStart;
public readonly bool PerRuin;
public readonly bool PerWreck;
public readonly Dictionary<string, float> Commonness;
public readonly List<ScriptedEventPrefab> EventPrefabs;
@@ -54,6 +59,10 @@ namespace Barotrauma
MinDistanceTraveled = element.GetAttributeFloat("mindistancetraveled", 0.0f);
MinMissionTime = element.GetAttributeFloat("minmissiontime", 0.0f);
AllowAtStart = element.GetAttributeBool("allowatstart", false);
PerRuin = element.GetAttributeBool("perruin", false);
PerWreck = element.GetAttributeBool("perwreck", false);
Commonness[""] = 1.0f;
foreach (XElement subElement in element.Elements())
{
@@ -63,7 +72,7 @@ namespace Barotrauma
Commonness[""] = subElement.GetAttributeFloat("commonness", 0.0f);
foreach (XElement overrideElement in subElement.Elements())
{
if (overrideElement.Name.ToString().ToLowerInvariant() == "override")
if (overrideElement.Name.ToString().Equals("override", StringComparison.OrdinalIgnoreCase))
{
string levelType = overrideElement.GetAttributeString("leveltype", "");
if (!Commonness.ContainsKey(levelType))
@@ -116,7 +125,7 @@ namespace Barotrauma
int i = 0;
foreach (XElement element in doc.Root.Elements())
{
if (element.Name.ToString().ToLowerInvariant() != "eventset") { continue; }
if (!element.Name.ToString().Equals("eventset", StringComparison.OrdinalIgnoreCase)) { continue; }
List.Add(new ScriptedEventSet(element, i.ToString()));
i++;
}