(f0d812055) v0.9.9.0
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user