Unstable 1.1.14.0
This commit is contained in:
@@ -16,7 +16,7 @@ namespace Barotrauma
|
||||
protected readonly HashSet<Character> requireKill = new HashSet<Character>();
|
||||
protected readonly HashSet<Character> requireRescue = new HashSet<Character>();
|
||||
|
||||
private readonly string itemTag;
|
||||
private readonly Identifier itemTag;
|
||||
private readonly XElement itemConfig;
|
||||
private readonly List<Item> items = new List<Item>();
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace Barotrauma
|
||||
hostagesKilledMessage = TextManager.Get(msgTag).Fallback(msgTag);
|
||||
|
||||
itemConfig = prefab.ConfigElement.GetChildElement("Items");
|
||||
itemTag = prefab.ConfigElement.GetAttributeString("targetitem", "");
|
||||
itemTag = prefab.ConfigElement.GetAttributeIdentifier("targetitem", Identifier.Empty);
|
||||
}
|
||||
|
||||
protected override void StartMissionSpecific(Level level)
|
||||
@@ -118,7 +118,7 @@ namespace Barotrauma
|
||||
|
||||
private void InitItems(Submarine submarine)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(itemTag))
|
||||
if (!itemTag.IsEmpty)
|
||||
{
|
||||
var itemsToDestroy = Item.ItemList.FindAll(it => it.Submarine?.Info.Type != SubmarineType.Player && it.HasTag(itemTag));
|
||||
if (!itemsToDestroy.Any())
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace Barotrauma
|
||||
{
|
||||
get
|
||||
{
|
||||
if (level.BeaconStation == null)
|
||||
if (level.BeaconStation == null || state > 0)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
@@ -95,9 +95,10 @@ namespace Barotrauma
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
if (!connectedSubs.Contains(item.Submarine) || item.Submarine?.Info is { IsPlayer: true }) { continue; }
|
||||
if (item.GetComponent<PowerTransfer>() != null ||
|
||||
bool isReactor = item.GetComponent<Reactor>() != null;
|
||||
if ((isReactor && GameMain.GameSession is not { TraitorsEnabled: true }) ||
|
||||
item.GetComponent<PowerTransfer>() != null ||
|
||||
item.GetComponent<PowerContainer>() != null ||
|
||||
item.GetComponent<Reactor>() != null ||
|
||||
item.GetComponent<Sonar>() != null)
|
||||
{
|
||||
item.InvulnerableToDamage = true;
|
||||
|
||||
@@ -262,6 +262,12 @@ namespace Barotrauma
|
||||
SpawnedInCurrentOutpost = true,
|
||||
AllowStealing = false
|
||||
};
|
||||
item.AddTag("cargomission");
|
||||
item.AddTag(Prefab.Identifier);
|
||||
foreach (var tag in Prefab.Tags)
|
||||
{
|
||||
item.AddTag(tag);
|
||||
}
|
||||
item.FindHull();
|
||||
items.Add(item);
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace Barotrauma
|
||||
private readonly CharacterPrefab minionPrefab;
|
||||
|
||||
private readonly Identifier spawnPointTag;
|
||||
private WayPoint bossSpawnPoint;
|
||||
private readonly Identifier destructibleItemTag;
|
||||
|
||||
private readonly string endCinematicSound;
|
||||
@@ -68,7 +69,13 @@ namespace Barotrauma
|
||||
{
|
||||
if (boss != null && !boss.Removed)
|
||||
{
|
||||
Vector2 prevPos = boss.AnimController.Collider.SimPosition;
|
||||
boss.AnimController.ColliderIndex = 1;
|
||||
if (bossSpawnPoint != null)
|
||||
{
|
||||
//ensure the new collider stays in the same position (the 2nd one has a different shape than the 1st one)
|
||||
boss.AnimController.Collider.SetTransform(prevPos, 0.0f);
|
||||
}
|
||||
}
|
||||
}, delay: wakeUpCinematicDelay + bossWakeUpDelay + 2);
|
||||
}
|
||||
@@ -142,21 +149,21 @@ namespace Barotrauma
|
||||
|
||||
protected override void StartMissionSpecific(Level level)
|
||||
{
|
||||
var spawnPoint = WayPoint.WayPointList.FirstOrDefault(wp => wp.Tags.Contains(spawnPointTag));
|
||||
if (spawnPoint == null)
|
||||
bossSpawnPoint = WayPoint.WayPointList.FirstOrDefault(wp => wp.Tags.Contains(spawnPointTag));
|
||||
if (bossSpawnPoint == null)
|
||||
{
|
||||
DebugConsole.ThrowError($"Error in end mission \"{Prefab.Identifier}\". Could not find a spawn point \"{spawnPointTag}\".");
|
||||
return;
|
||||
}
|
||||
if (!IsClient)
|
||||
{
|
||||
boss = Character.Create(bossPrefab.Identifier, spawnPoint.WorldPosition, ToolBox.RandomSeed(8), createNetworkEvent: false);
|
||||
boss = Character.Create(bossPrefab.Identifier, bossSpawnPoint.WorldPosition, ToolBox.RandomSeed(8), createNetworkEvent: false);
|
||||
var minionList = new List<Character>();
|
||||
float angle = 0;
|
||||
float angleStep = MathHelper.TwoPi / Math.Max(minionCount, 1);
|
||||
for (int i = 0; i < minionCount; i++)
|
||||
{
|
||||
minionList.Add(Character.Create(minionPrefab.Identifier, MathUtils.GetPointOnCircumference(spawnPoint.WorldPosition, minionScatter, angle), ToolBox.RandomSeed(8), createNetworkEvent: false));
|
||||
minionList.Add(Character.Create(minionPrefab.Identifier, MathUtils.GetPointOnCircumference(bossSpawnPoint.WorldPosition, minionScatter, angle), ToolBox.RandomSeed(8), createNetworkEvent: false));
|
||||
angle += angleStep;
|
||||
}
|
||||
SwarmBehavior.CreateSwarm(minionList.Cast<AICharacter>());
|
||||
|
||||
@@ -315,27 +315,21 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private bool Survived(Character character)
|
||||
private static bool Survived(Character character)
|
||||
{
|
||||
return IsAlive(character) && character.CurrentHull?.Submarine != null &&
|
||||
(character.CurrentHull.Submarine == Submarine.MainSub || Submarine.MainSub.DockedTo.Contains(character.CurrentHull.Submarine));
|
||||
}
|
||||
|
||||
private bool IsAlive(Character character)
|
||||
private static bool IsAlive(Character character)
|
||||
{
|
||||
return character != null && !character.Removed && !character.IsDead;
|
||||
}
|
||||
|
||||
private bool IsCaptured(Character character)
|
||||
{
|
||||
return character.LockHands && character.HasTeamChange(TerroristTeamChangeIdentifier);
|
||||
}
|
||||
|
||||
protected override bool DetermineCompleted()
|
||||
{
|
||||
if (Submarine.MainSub != null && Submarine.MainSub.AtEndExit)
|
||||
{
|
||||
bool terroristsSurvived = terroristCharacters.Any(c => Survived(c) && !IsCaptured(c));
|
||||
bool friendliesSurvived = characters.Except(terroristCharacters).All(c => Survived(c));
|
||||
bool vipDied = false;
|
||||
|
||||
@@ -345,7 +339,7 @@ namespace Barotrauma
|
||||
vipDied = !Survived(vipCharacter);
|
||||
}
|
||||
|
||||
if (friendliesSurvived && !terroristsSurvived && !vipDied)
|
||||
if (friendliesSurvived && !vipDied)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (cave.Area.Contains(spawnedResource.WorldPosition))
|
||||
{
|
||||
cave.DisplayOnSonar = true;
|
||||
cave.MissionsToDisplayOnSonar.Add(this);
|
||||
caves.Add(cave);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public Dictionary<Identifier, float> ReputationRewards
|
||||
public ImmutableList<MissionPrefab.ReputationReward> ReputationRewards
|
||||
{
|
||||
get { return Prefab.ReputationRewards; }
|
||||
}
|
||||
@@ -268,7 +268,7 @@ namespace Barotrauma
|
||||
delayedTriggerEvents.Clear();
|
||||
foreach (string categoryToShow in Prefab.UnhideEntitySubCategories)
|
||||
{
|
||||
foreach (MapEntity entityToShow in MapEntity.mapEntityList.Where(me => me.Prefab?.HasSubCategory(categoryToShow) ?? false))
|
||||
foreach (MapEntity entityToShow in MapEntity.MapEntityList.Where(me => me.Prefab?.HasSubCategory(categoryToShow) ?? false))
|
||||
{
|
||||
entityToShow.HiddenInGame = false;
|
||||
}
|
||||
@@ -353,8 +353,7 @@ namespace Barotrauma
|
||||
if (GameMain.GameSession?.EventManager != null)
|
||||
{
|
||||
var newEvent = eventPrefab.CreateInstance();
|
||||
GameMain.GameSession.EventManager.ActiveEvents.Add(newEvent);
|
||||
newEvent.Init();
|
||||
GameMain.GameSession.EventManager.ActivateEvent(newEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -372,7 +371,19 @@ namespace Barotrauma
|
||||
{
|
||||
ChangeLocationType(Prefab.LocationTypeChangeOnCompleted);
|
||||
}
|
||||
GiveReward();
|
||||
try
|
||||
{
|
||||
GiveReward();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
string errorMsg = "Unknown error while giving mission rewards.";
|
||||
DebugConsole.ThrowError(errorMsg, e);
|
||||
GameAnalyticsManager.AddErrorEventOnce("Mission.End:GiveReward", GameAnalyticsManager.ErrorSeverity.Error, errorMsg + "\n" + e.StackTrace);
|
||||
#if SERVER
|
||||
GameMain.Server?.SendChatMessage(errorMsg + "\n" + e.StackTrace, Networking.ChatMessageType.Error);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
TimesAttempted++;
|
||||
@@ -423,30 +434,7 @@ namespace Barotrauma
|
||||
crewCharacters.ForEach(c => c.CheckTalents(AbilityEffectType.OnAllyGainMissionExperience, experienceGainMultiplier));
|
||||
crewCharacters.ForEach(c => experienceGainMultiplier.Value += c.GetStatValue(StatTypes.MissionExperienceGainMultiplier));
|
||||
|
||||
int experienceGain = (int)(baseExperienceGain * experienceGainMultiplier.Value);
|
||||
#if CLIENT
|
||||
foreach (Character character in crewCharacters)
|
||||
{
|
||||
GiveMissionExperience(character.Info);
|
||||
}
|
||||
#else
|
||||
foreach (Barotrauma.Networking.Client c in GameMain.Server.ConnectedClients)
|
||||
{
|
||||
//give the experience to the stored characterinfo if the client isn't currently controlling a character
|
||||
GiveMissionExperience(c.Character?.Info ?? c.CharacterInfo);
|
||||
}
|
||||
foreach (Character bot in GameSession.GetSessionCrewCharacters(CharacterType.Bot))
|
||||
{
|
||||
GiveMissionExperience(bot.Info);
|
||||
}
|
||||
#endif
|
||||
|
||||
void GiveMissionExperience(CharacterInfo info)
|
||||
{
|
||||
var experienceGainMultiplierIndividual = new AbilityMissionExperienceGainMultiplier(this, 1f);
|
||||
info?.Character?.CheckTalents(AbilityEffectType.OnGainMissionExperience, experienceGainMultiplierIndividual);
|
||||
info?.GiveExperience((int)((experienceGain * experienceGainMultiplier.Value) * experienceGainMultiplierIndividual.Value));
|
||||
}
|
||||
DistributeExperienceToCrew(crewCharacters, (int)(baseExperienceGain * experienceGainMultiplier.Value));
|
||||
|
||||
CalculateFinalReward(Submarine.MainSub);
|
||||
#if SERVER
|
||||
@@ -465,17 +453,32 @@ namespace Barotrauma
|
||||
character.Info.MissionsCompletedSinceDeath++;
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<Identifier, float> reputationReward in ReputationRewards)
|
||||
foreach (var reputationReward in ReputationRewards)
|
||||
{
|
||||
if (reputationReward.Key == "location")
|
||||
if (reputationReward.FactionIdentifier == "location")
|
||||
{
|
||||
OriginLocation.Reputation?.AddReputation(reputationReward.Value);
|
||||
OriginLocation.Reputation?.AddReputation(reputationReward.Amount);
|
||||
TryGiveReputationForOpposingFaction(OriginLocation.Faction, reputationReward.AmountForOpposingFaction);
|
||||
}
|
||||
else
|
||||
{
|
||||
Faction faction = campaign.Factions.Find(faction1 => faction1.Prefab.Identifier == reputationReward.Key);
|
||||
float prevValue = faction.Reputation.Value;
|
||||
faction?.Reputation.AddReputation(reputationReward.Value);
|
||||
Faction faction = campaign.Factions.Find(faction1 => faction1.Prefab.Identifier == reputationReward.FactionIdentifier);
|
||||
if (faction != null)
|
||||
{
|
||||
faction.Reputation.AddReputation(reputationReward.Amount);
|
||||
TryGiveReputationForOpposingFaction(faction, reputationReward.AmountForOpposingFaction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TryGiveReputationForOpposingFaction(Faction thisFaction, float amount)
|
||||
{
|
||||
if (MathUtils.NearlyEqual(amount, 0.0f)) { return; }
|
||||
if (thisFaction?.Prefab != null &&
|
||||
!thisFaction.Prefab.OpposingFaction.IsEmpty)
|
||||
{
|
||||
Faction faction = campaign.Factions.Find(faction1 => faction1.Prefab.Identifier == thisFaction.Prefab.OpposingFaction);
|
||||
faction?.Reputation.AddReputation(amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -489,30 +492,10 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
#if SERVER
|
||||
public static int DistributeRewardsToCrew(IEnumerable<Character> crew, int totalReward)
|
||||
{
|
||||
int remainingRewards = totalReward;
|
||||
float sum = GetRewardDistibutionSum(crew);
|
||||
if (MathUtils.NearlyEqual(sum, 0)) { return remainingRewards; }
|
||||
foreach (Character character in crew)
|
||||
{
|
||||
int rewardDistribution = character.Wallet.RewardDistribution;
|
||||
float rewardWeight = sum > 100 ? rewardDistribution / sum : rewardDistribution / 100f;
|
||||
int reward = (int)(totalReward * rewardWeight);
|
||||
reward = Math.Min(remainingRewards, reward);
|
||||
character.Wallet.Give(reward);
|
||||
remainingRewards -= reward;
|
||||
if (remainingRewards <= 0) { break; }
|
||||
}
|
||||
|
||||
return remainingRewards;
|
||||
}
|
||||
#endif
|
||||
partial void DistributeExperienceToCrew(IEnumerable<Character> crew, int experienceGain);
|
||||
|
||||
public static int GetRewardDistibutionSum(IEnumerable<Character> crew, int rewardDistribution = 0) => crew.Sum(c => c.Wallet.RewardDistribution) + rewardDistribution;
|
||||
|
||||
|
||||
public static (int Amount, int Percentage, float Sum) GetRewardShare(int rewardDistribution, IEnumerable<Character> crew, Option<int> reward)
|
||||
{
|
||||
float sum = GetRewardDistibutionSum(crew, rewardDistribution);
|
||||
|
||||
@@ -4,7 +4,6 @@ using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -54,6 +53,20 @@ namespace Barotrauma
|
||||
{ MissionType.Combat, typeof(CombatMission) }
|
||||
};
|
||||
|
||||
public class ReputationReward
|
||||
{
|
||||
public readonly Identifier FactionIdentifier;
|
||||
public readonly float Amount;
|
||||
public readonly float AmountForOpposingFaction;
|
||||
|
||||
public ReputationReward(XElement element)
|
||||
{
|
||||
FactionIdentifier = element.GetAttributeIdentifier("identifier", Identifier.Empty);
|
||||
Amount = element.GetAttributeFloat(nameof(Amount), 0.0f);
|
||||
AmountForOpposingFaction = element.GetAttributeFloat(nameof(AmountForOpposingFaction), 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
public static readonly HashSet<MissionType> HiddenMissionClasses = new HashSet<MissionType>() { MissionType.GoTo, MissionType.End };
|
||||
|
||||
private readonly ConstructorInfo constructor;
|
||||
@@ -75,7 +88,7 @@ namespace Barotrauma
|
||||
|
||||
public readonly Identifier AchievementIdentifier;
|
||||
|
||||
public readonly Dictionary<Identifier, float> ReputationRewards = new Dictionary<Identifier, float>();
|
||||
public readonly ImmutableList<ReputationReward> ReputationRewards;
|
||||
|
||||
public readonly List<(Identifier Identifier, object Value, SetDataAction.OperationType OperationType)>
|
||||
DataRewards = new List<(Identifier Identifier, object Value, SetDataAction.OperationType OperationType)>();
|
||||
@@ -252,7 +265,8 @@ namespace Barotrauma
|
||||
messages.Add(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
List<ReputationReward> reputationRewards = new List<ReputationReward>();
|
||||
int messageIndex = 0;
|
||||
foreach (var subElement in element.Elements())
|
||||
{
|
||||
@@ -292,14 +306,7 @@ namespace Barotrauma
|
||||
break;
|
||||
case "reputation":
|
||||
case "reputationreward":
|
||||
Identifier factionIdentifier = subElement.GetAttributeIdentifier("identifier", Identifier.Empty);
|
||||
float amount = subElement.GetAttributeFloat("amount", 0.0f);
|
||||
if (ReputationRewards.ContainsKey(factionIdentifier))
|
||||
{
|
||||
DebugConsole.ThrowError($"Error in mission prefab \"{Identifier}\". Multiple reputation changes defined for the identifier \"{factionIdentifier}\".");
|
||||
continue;
|
||||
}
|
||||
ReputationRewards.Add(factionIdentifier, amount);
|
||||
reputationRewards.Add(new ReputationReward(subElement));
|
||||
break;
|
||||
case "metadata":
|
||||
Identifier identifier = subElement.GetAttributeIdentifier("identifier", Identifier.Empty);
|
||||
@@ -325,6 +332,7 @@ namespace Barotrauma
|
||||
}
|
||||
Headers = headers.ToImmutableArray();
|
||||
Messages = messages.ToImmutableArray();
|
||||
ReputationRewards = reputationRewards.ToImmutableList();
|
||||
|
||||
Identifier missionTypeName = element.GetAttributeIdentifier("type", Identifier.Empty);
|
||||
//backwards compatibility
|
||||
@@ -399,7 +407,7 @@ namespace Barotrauma
|
||||
else if (Type == MissionType.ScanAlienRuins || Type == MissionType.ClearAlienRuins)
|
||||
{
|
||||
var connection = from.Connections.Find(c => c.Locations.Contains(from) && c.Locations.Contains(to));
|
||||
if (connection?.LevelData == null || connection.LevelData.GenerationParams.RuinCount < 1) { return false; }
|
||||
if (connection?.LevelData == null || connection.LevelData.GenerationParams.GetMaxRuinCount() < 1) { return false; }
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -147,7 +147,7 @@ namespace Barotrauma
|
||||
monster.Params.AI.FleeHealthThreshold = 0;
|
||||
foreach (var targetParam in monster.Params.AI.Targets)
|
||||
{
|
||||
if (targetParam.Tag.Equals("engine", StringComparison.OrdinalIgnoreCase)) { continue; }
|
||||
if (targetParam.Tag == "engine") { continue; }
|
||||
switch (targetParam.State)
|
||||
{
|
||||
case AIState.Avoid:
|
||||
|
||||
@@ -4,7 +4,6 @@ using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Voronoi2;
|
||||
|
||||
namespace Barotrauma
|
||||
@@ -30,6 +29,8 @@ namespace Barotrauma
|
||||
|
||||
private Vector2 nestPosition;
|
||||
|
||||
private Level.Cave selectedCave;
|
||||
|
||||
|
||||
public override IEnumerable<(LocalizedString Label, Vector2 Position)> SonarLabels
|
||||
{
|
||||
@@ -125,11 +126,9 @@ namespace Barotrauma
|
||||
}
|
||||
if (closestCave != null)
|
||||
{
|
||||
closestCave.DisplayOnSonar = true;
|
||||
SpawnNestObjects(level, closestCave);
|
||||
#if SERVER
|
||||
selectedCave = closestCave;
|
||||
#endif
|
||||
selectedCave.MissionsToDisplayOnSonar.Add(this);
|
||||
SpawnNestObjects(level, closestCave);
|
||||
}
|
||||
var nearbyCells = Level.Loaded.GetCells(nestPosition, searchDepth: 3);
|
||||
if (nearbyCells.Any())
|
||||
@@ -172,8 +171,8 @@ namespace Barotrauma
|
||||
|
||||
foreach (var subElement in itemConfig.Elements())
|
||||
{
|
||||
string itemIdentifier = subElement.GetAttributeString("identifier", "");
|
||||
if (!(MapEntityPrefab.Find(null, itemIdentifier) is ItemPrefab itemPrefab))
|
||||
var itemIdentifier = subElement.GetAttributeIdentifier("identifier", Identifier.Empty);
|
||||
if (MapEntityPrefab.FindByIdentifier(itemIdentifier) is not ItemPrefab itemPrefab)
|
||||
{
|
||||
DebugConsole.ThrowError("Couldn't spawn item for nest mission: item prefab \"" + itemIdentifier + "\" not found");
|
||||
continue;
|
||||
@@ -183,25 +182,34 @@ namespace Barotrauma
|
||||
float rotation = 0.0f;
|
||||
if (spawnEdges.Any())
|
||||
{
|
||||
var edge = spawnEdges.GetRandom(Rand.RandSync.ServerAndClient);
|
||||
spawnPos = Vector2.Lerp(edge.Point1, edge.Point2, Rand.Range(0.1f, 0.9f, Rand.RandSync.ServerAndClient));
|
||||
Vector2 normal = Vector2.UnitY;
|
||||
if (edge.Cell1 != null && edge.Cell1.CellType == CellType.Solid)
|
||||
const float MinDistanceFromOtherItems = 30.0f;
|
||||
const int MaxTries = 10;
|
||||
for (int i = 0; i < MaxTries; i++)
|
||||
{
|
||||
normal = edge.GetNormal(edge.Cell1);
|
||||
var edge = spawnEdges.GetRandom(Rand.RandSync.ServerAndClient);
|
||||
spawnPos = Vector2.Lerp(edge.Point1, edge.Point2, Rand.Range(0.1f, 0.9f, Rand.RandSync.ServerAndClient));
|
||||
Vector2 normal = Vector2.UnitY;
|
||||
if (edge.Cell1 != null && edge.Cell1.CellType == CellType.Solid)
|
||||
{
|
||||
normal = edge.GetNormal(edge.Cell1);
|
||||
}
|
||||
else if (edge.Cell2 != null && edge.Cell2.CellType == CellType.Solid)
|
||||
{
|
||||
normal = edge.GetNormal(edge.Cell2);
|
||||
}
|
||||
spawnPos += normal * 10.0f;
|
||||
rotation = MathUtils.VectorToAngle(normal) - MathHelper.PiOver2;
|
||||
|
||||
if (items.All(it => Vector2.DistanceSquared(it.WorldPosition, spawnPos) > MinDistanceFromOtherItems)) { break; }
|
||||
}
|
||||
else if (edge.Cell2 != null && edge.Cell2.CellType == CellType.Solid)
|
||||
{
|
||||
normal = edge.GetNormal(edge.Cell2);
|
||||
}
|
||||
spawnPos += normal * 10.0f;
|
||||
rotation = MathUtils.VectorToAngle(normal) - MathHelper.PiOver2;
|
||||
}
|
||||
|
||||
var item = new Item(itemPrefab, spawnPos, null);
|
||||
item.body.FarseerBody.BodyType = BodyType.Kinematic;
|
||||
item.body.SetTransformIgnoreContacts(item.body.SimPosition, rotation);
|
||||
item.FindHull();
|
||||
item.AddTag("nestmission");
|
||||
item.AddTag(Prefab.Identifier);
|
||||
items.Add(item);
|
||||
|
||||
var statusEffectElement =
|
||||
@@ -286,7 +294,10 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
//continue when all items are in the sub or destroyed
|
||||
if (AllItemsDestroyedOrRetrieved()) { State = 1; }
|
||||
if (AllItemsDestroyedOrRetrieved())
|
||||
{
|
||||
State = 1;
|
||||
}
|
||||
|
||||
break;
|
||||
case 1:
|
||||
|
||||
@@ -239,7 +239,7 @@ namespace Barotrauma
|
||||
private void InitPirateShip()
|
||||
{
|
||||
enemySub.NeutralizeBallast();
|
||||
if (enemySub.GetItems(alsoFromConnectedSubs: false).Find(i => i.HasTag("reactor") && !i.NonInteractable)?.GetComponent<Reactor>() is Reactor reactor)
|
||||
if (enemySub.GetItems(alsoFromConnectedSubs: false).Find(i => i.HasTag(Tags.Reactor) && !i.NonInteractable)?.GetComponent<Reactor>() is Reactor reactor)
|
||||
{
|
||||
reactor.PowerUpImmediately();
|
||||
}
|
||||
|
||||
@@ -30,8 +30,8 @@ namespace Barotrauma
|
||||
|
||||
public readonly ItemPrefab ItemPrefab;
|
||||
public readonly Level.PositionType SpawnPositionType;
|
||||
public readonly string ContainerTag;
|
||||
public readonly string ExistingItemTag;
|
||||
public readonly Identifier ContainerTag;
|
||||
public readonly Identifier ExistingItemTag;
|
||||
|
||||
public readonly bool RemoveItem;
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace Barotrauma
|
||||
public Target(ContentXElement element, SalvageMission mission)
|
||||
{
|
||||
this.mission = mission;
|
||||
ContainerTag = element.GetAttributeString("containertag", "");
|
||||
ContainerTag = element.GetAttributeIdentifier("containertag", Identifier.Empty);
|
||||
RequiredRetrievalState = element.GetAttributeEnum("requireretrieval", RetrievalState.RetrievedToSub);
|
||||
AllowContinueBeforeRetrieved = element.GetAttributeBool("allowcontinuebeforeretrieved", false);
|
||||
HideLabelAfterRetrieved = element.GetAttributeBool("hidelabelafterretrieved", false);
|
||||
@@ -100,7 +100,7 @@ namespace Barotrauma
|
||||
.Fallback(TextManager.Get(sonarLabelTag))
|
||||
.Fallback(element.GetAttributeString("sonarlabel", ""));
|
||||
}
|
||||
ExistingItemTag = element.GetAttributeString("existingitemtag", "");
|
||||
ExistingItemTag = element.GetAttributeIdentifier("existingitemtag", Identifier.Empty);
|
||||
|
||||
RemoveItem = element.GetAttributeBool("removeitem", true);
|
||||
|
||||
@@ -109,7 +109,7 @@ namespace Barotrauma
|
||||
DebugConsole.ThrowError("Error in SalvageMission - use item identifier instead of the name of the item.");
|
||||
string itemName = element.GetAttributeString("itemname", "");
|
||||
ItemPrefab = MapEntityPrefab.Find(itemName) as ItemPrefab;
|
||||
if (ItemPrefab == null && ExistingItemTag.IsNullOrEmpty())
|
||||
if (ItemPrefab == null && ExistingItemTag.IsEmpty)
|
||||
{
|
||||
DebugConsole.ThrowError($"Error in SalvageMission: couldn't find an item prefab with the name \"{itemName}\"");
|
||||
}
|
||||
@@ -126,7 +126,7 @@ namespace Barotrauma
|
||||
string itemTag = element.GetAttributeString("itemtag", "");
|
||||
ItemPrefab = MapEntityPrefab.GetRandom(p => p.Tags.Contains(itemTag), Rand.RandSync.Unsynced) as ItemPrefab;
|
||||
}
|
||||
if (ItemPrefab == null && ExistingItemTag.IsNullOrEmpty())
|
||||
if (ItemPrefab == null && ExistingItemTag.IsEmpty)
|
||||
{
|
||||
DebugConsole.ThrowError($"Error in SalvageMission - couldn't find an item prefab with the identifier \"{itemIdentifier}\"");
|
||||
}
|
||||
@@ -233,7 +233,7 @@ namespace Barotrauma
|
||||
Vector2.Zero :
|
||||
Level.Loaded.GetRandomItemPos(target.SpawnPositionType, 100.0f, minDistance, 30.0f);
|
||||
|
||||
if (!string.IsNullOrEmpty(target.ExistingItemTag))
|
||||
if (!target.ExistingItemTag.IsEmpty)
|
||||
{
|
||||
var suitableItems = Item.ItemList.Where(it => it.HasTag(target.ExistingItemTag));
|
||||
if (GameMain.GameSession?.Missions != null)
|
||||
@@ -284,9 +284,9 @@ namespace Barotrauma
|
||||
|
||||
if (target.Item == null)
|
||||
{
|
||||
if (target.ItemPrefab == null && string.IsNullOrEmpty(target.ContainerTag))
|
||||
if (target.ItemPrefab == null && target.ContainerTag.IsEmpty)
|
||||
{
|
||||
DebugConsole.ThrowError($"Failed to find a target item for the mission \"{Prefab.Identifier}\". Item tag: {target.ExistingItemTag ?? "null"}");
|
||||
DebugConsole.ThrowError($"Failed to find a target item for the mission \"{Prefab.Identifier}\". Item tag: {target.ExistingItemTag}");
|
||||
continue;
|
||||
}
|
||||
target.Item = new Item(target.ItemPrefab, position, null);
|
||||
@@ -312,8 +312,10 @@ namespace Barotrauma
|
||||
#endif
|
||||
}
|
||||
|
||||
target.Item.IsSalvageMissionItem = true;
|
||||
|
||||
//try to find a container and place the item inside it
|
||||
if (!string.IsNullOrEmpty(target.ContainerTag) && target.Item.ParentInventory == null)
|
||||
if (!target.ContainerTag.IsEmpty && target.Item.ParentInventory == null)
|
||||
{
|
||||
List<ItemContainer> validContainers = new List<ItemContainer>();
|
||||
foreach (Item it in Item.ItemList)
|
||||
|
||||
@@ -218,7 +218,7 @@ namespace Barotrauma
|
||||
#endif
|
||||
}
|
||||
|
||||
private bool IsValidScanPosition(Scanner scanner, KeyValuePair<WayPoint, bool> scanStatus, float scanRadiusSquared)
|
||||
private static bool IsValidScanPosition(Scanner scanner, KeyValuePair<WayPoint, bool> scanStatus, float scanRadiusSquared)
|
||||
{
|
||||
if (scanStatus.Value) { return false; }
|
||||
if (scanStatus.Key.Submarine != scanner.Item.Submarine) { return false; }
|
||||
@@ -232,39 +232,15 @@ namespace Barotrauma
|
||||
switch (State)
|
||||
{
|
||||
case 0:
|
||||
if (!AllTargetsScanned) { return; }
|
||||
State = 1;
|
||||
break;
|
||||
case 1:
|
||||
if (!Submarine.MainSub.AtEndExit && !Submarine.MainSub.AtStartExit) { return; }
|
||||
State = 2;
|
||||
if (AllTargetsScanned)
|
||||
{
|
||||
State = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool DetermineCompleted()
|
||||
{
|
||||
return State == 2 && AllScannersReturned();
|
||||
|
||||
bool AllScannersReturned()
|
||||
{
|
||||
foreach (var scanner in scanners)
|
||||
{
|
||||
if (scanner?.Item == null || scanner.Item.Removed) { return false; }
|
||||
var owner = scanner.Item.GetRootInventoryOwner();
|
||||
if (owner.Submarine != null && owner.Submarine.Info.Type == SubmarineType.Player)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (owner is Character c && c.Info != null && GameMain.GameSession.CrewManager.CharacterInfos.Contains(c.Info))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
protected override bool DetermineCompleted() => State > 0;
|
||||
|
||||
protected override void EndMissionSpecific(bool completed)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user