Unstable 0.1400.2.0 (a mimir edition)
This commit is contained in:
@@ -179,7 +179,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (speaker == null) { return; }
|
||||
speaker.CampaignInteractionType = CampaignMode.InteractionType.None;
|
||||
speaker.ActiveConversation = this;
|
||||
speaker.ActiveConversation = null;
|
||||
speaker.SetCustomInteract(null, null);
|
||||
#if SERVER
|
||||
GameMain.NetworkMember.CreateEntityEvent(speaker, new object[] { NetEntityEvent.Type.AssignCampaignInteraction });
|
||||
|
||||
@@ -48,9 +48,9 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var goToObjective in humanAiController.ObjectiveManager.GetActiveObjectives<AIObjectiveGoTo>())
|
||||
foreach (var objective in humanAiController.ObjectiveManager.Objectives)
|
||||
{
|
||||
if (goToObjective.Target == target)
|
||||
if (objective is AIObjectiveGoTo goToObjective && goToObjective.Target == target)
|
||||
{
|
||||
goToObjective.Abandon = true;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace Barotrauma
|
||||
bool hasValidTargets = false;
|
||||
foreach (Entity target in targets)
|
||||
{
|
||||
if (target is Character character && character.Inventory != null)
|
||||
if (target is Character character && character.Inventory != null || target is Item)
|
||||
{
|
||||
hasValidTargets = true;
|
||||
break;
|
||||
@@ -55,20 +55,31 @@ namespace Barotrauma
|
||||
}
|
||||
if (!hasValidTargets) { return; }
|
||||
|
||||
List<Item> usedItems = new List<Item>();
|
||||
HashSet<Item> removedItems = new HashSet<Item>();
|
||||
foreach (Entity target in targets)
|
||||
{
|
||||
Inventory inventory = (target as Character)?.Inventory;
|
||||
if (inventory == null) { continue; }
|
||||
while (usedItems.Count < Amount)
|
||||
if (inventory != null)
|
||||
{
|
||||
var item = inventory.FindItem(it =>
|
||||
it != null &&
|
||||
!usedItems.Contains(it) &&
|
||||
it.Prefab.Identifier.Equals(ItemIdentifier, StringComparison.InvariantCultureIgnoreCase), recursive: true);
|
||||
if (item == null) { break; }
|
||||
Entity.Spawner.AddToRemoveQueue(item);
|
||||
usedItems.Add(item);
|
||||
while (removedItems.Count < Amount)
|
||||
{
|
||||
var item = inventory.FindItem(it =>
|
||||
it != null &&
|
||||
!removedItems.Contains(it) &&
|
||||
it.Prefab.Identifier.Equals(ItemIdentifier, StringComparison.InvariantCultureIgnoreCase), recursive: true);
|
||||
if (item == null) { break; }
|
||||
Entity.Spawner.AddToRemoveQueue(item);
|
||||
removedItems.Add(item);
|
||||
}
|
||||
}
|
||||
else if (target is Item item)
|
||||
{
|
||||
if (item.Prefab.Identifier.Equals(ItemIdentifier, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
Entity.Spawner.AddToRemoveQueue(item);
|
||||
removedItems.Add(item);
|
||||
if (removedItems.Count >= Amount) { break; }
|
||||
}
|
||||
}
|
||||
}
|
||||
isFinished = true;
|
||||
|
||||
@@ -107,27 +107,32 @@ namespace Barotrauma
|
||||
if (!string.IsNullOrEmpty(NPCSetIdentifier) && !string.IsNullOrEmpty(NPCIdentifier))
|
||||
{
|
||||
HumanPrefab humanPrefab = NPCSet.Get(NPCSetIdentifier, NPCIdentifier);
|
||||
ISpatialEntity spawnPos = GetSpawnPos();
|
||||
Entity.Spawner.AddToSpawnQueue(CharacterPrefab.HumanSpeciesName, OffsetSpawnPos(spawnPos?.WorldPosition ?? Vector2.Zero, 100.0f), humanPrefab.GetCharacterInfo(), onSpawn: newCharacter =>
|
||||
if (humanPrefab != null)
|
||||
{
|
||||
newCharacter.TeamID = CharacterTeamType.FriendlyNPC;
|
||||
newCharacter.EnableDespawn = false;
|
||||
humanPrefab.GiveItems(newCharacter, newCharacter.Submarine);
|
||||
if (LootingIsStealing)
|
||||
ISpatialEntity spawnPos = GetSpawnPos();
|
||||
Entity.Spawner.AddToSpawnQueue(CharacterPrefab.HumanSpeciesName, OffsetSpawnPos(spawnPos?.WorldPosition ?? Vector2.Zero, 100.0f), humanPrefab.GetCharacterInfo(), onSpawn: newCharacter =>
|
||||
{
|
||||
foreach (Item item in newCharacter.Inventory.AllItems)
|
||||
if (newCharacter == null) { return; }
|
||||
newCharacter.Prefab = humanPrefab;
|
||||
newCharacter.TeamID = CharacterTeamType.FriendlyNPC;
|
||||
newCharacter.EnableDespawn = false;
|
||||
humanPrefab.GiveItems(newCharacter, newCharacter.Submarine);
|
||||
if (LootingIsStealing)
|
||||
{
|
||||
item.SpawnedInOutpost = true;
|
||||
item.AllowStealing = false;
|
||||
foreach (Item item in newCharacter.Inventory.AllItems)
|
||||
{
|
||||
item.SpawnedInOutpost = true;
|
||||
item.AllowStealing = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
humanPrefab.InitializeCharacter(newCharacter, spawnPos);
|
||||
if (!string.IsNullOrEmpty(TargetTag) && newCharacter != null)
|
||||
{
|
||||
ParentEvent.AddTarget(TargetTag, newCharacter);
|
||||
}
|
||||
spawnedEntity = newCharacter;
|
||||
});
|
||||
humanPrefab.InitializeCharacter(newCharacter, spawnPos);
|
||||
if (!string.IsNullOrEmpty(TargetTag) && newCharacter != null)
|
||||
{
|
||||
ParentEvent.AddTarget(TargetTag, newCharacter);
|
||||
}
|
||||
spawnedEntity = newCharacter;
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(SpeciesName))
|
||||
{
|
||||
@@ -197,8 +202,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
spawned = true;
|
||||
|
||||
spawned = true;
|
||||
}
|
||||
|
||||
public static Vector2 OffsetSpawnPos(Vector2 pos, float offsetAmount)
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Barotrauma
|
||||
{
|
||||
class TagAction : EventAction
|
||||
{
|
||||
public enum SubType { Any= 0, Player = 1, Outpost = 2, Wreck = 4, BeaconStation = 8 }
|
||||
public enum SubType { Any = 0, Player = 1, Outpost = 2, Wreck = 4, BeaconStation = 8 }
|
||||
|
||||
[Serialize("", true)]
|
||||
public string Criteria { get; set; }
|
||||
@@ -67,6 +67,16 @@ namespace Barotrauma
|
||||
#endif
|
||||
}
|
||||
|
||||
private void TagHumansByIdentifier(string identifier)
|
||||
{
|
||||
foreach (Character c in Character.CharacterList)
|
||||
{
|
||||
if (c.Prefab?.Identifier.Equals(identifier, StringComparison.OrdinalIgnoreCase) ?? false)
|
||||
{
|
||||
ParentEvent.AddTarget(Tag, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
private void TagStructuresByIdentifier(string identifier)
|
||||
{
|
||||
ParentEvent.AddTargetPredicate(Tag, e => e is Structure s && SubmarineTypeMatches(s.Submarine) && s.Prefab.Identifier.Equals(identifier, StringComparison.InvariantCultureIgnoreCase));
|
||||
@@ -122,6 +132,9 @@ namespace Barotrauma
|
||||
case "crew":
|
||||
TagCrew();
|
||||
break;
|
||||
case "humanprefabidentifier":
|
||||
if (kvp.Length > 1) { TagHumansByIdentifier(kvp[1].Trim()); }
|
||||
break;
|
||||
case "structureidentifier":
|
||||
if (kvp.Length > 1) { TagStructuresByIdentifier(kvp[1].Trim()); }
|
||||
break;
|
||||
|
||||
@@ -122,6 +122,7 @@ namespace Barotrauma
|
||||
{
|
||||
npcOrItem = npc;
|
||||
npc.CampaignInteractionType = CampaignMode.InteractionType.Examine;
|
||||
npc.RequireConsciousnessForCustomInteract = false;
|
||||
#if CLIENT
|
||||
npc.SetCustomInteract(
|
||||
(speaker, player) => { if (e1 == speaker) { Trigger(speaker, player); } else { Trigger(player, speaker); } },
|
||||
@@ -132,7 +133,6 @@ namespace Barotrauma
|
||||
TextManager.Get("CampaignInteraction.Talk"));
|
||||
GameMain.NetworkMember.CreateEntityEvent(npc, new object[] { NetEntityEvent.Type.AssignCampaignInteraction });
|
||||
#endif
|
||||
npc.RequireConsciousnessForCustomInteract = false;
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -176,6 +176,9 @@ namespace Barotrauma
|
||||
npc.CampaignInteractionType = CampaignMode.InteractionType.None;
|
||||
npc.SetCustomInteract(null, null);
|
||||
npc.RequireConsciousnessForCustomInteract = true;
|
||||
#if SERVER
|
||||
GameMain.NetworkMember.CreateEntityEvent(npc, new object[] { NetEntityEvent.Type.AssignCampaignInteraction });
|
||||
#endif
|
||||
}
|
||||
else if (npcOrItem.TryGet(out Item item))
|
||||
{
|
||||
|
||||
@@ -168,7 +168,7 @@ namespace Barotrauma
|
||||
if (eventSet == null) { return; }
|
||||
if (eventSet.OncePerOutpost)
|
||||
{
|
||||
foreach (EventPrefab ep in eventSet.EventPrefabs.Select(e => e.First))
|
||||
foreach (EventPrefab ep in eventSet.EventPrefabs.Select(e => e.prefab))
|
||||
{
|
||||
if (!level.LevelData.NonRepeatableEvents.Contains(ep))
|
||||
{
|
||||
@@ -374,11 +374,11 @@ namespace Barotrauma
|
||||
preloadedSprites.Clear();
|
||||
}
|
||||
|
||||
private float CalculateCommonness(Pair<EventPrefab, float> eventPrefab)
|
||||
private float CalculateCommonness(EventPrefab eventPrefab, float baseCommonness)
|
||||
{
|
||||
if (level.LevelData.NonRepeatableEvents.Contains(eventPrefab.First)) { return 0.0f; }
|
||||
float retVal = eventPrefab.Second;
|
||||
if (level.LevelData.EventHistory.Contains(eventPrefab.First)) { retVal *= 0.1f; }
|
||||
if (level.LevelData.NonRepeatableEvents.Contains(eventPrefab)) { return 0.0f; }
|
||||
float retVal = baseCommonness;
|
||||
if (level.LevelData.EventHistory.Contains(eventPrefab)) { retVal *= 0.1f; }
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@@ -420,8 +420,8 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
var suitablePrefabs = eventSet.EventPrefabs.FindAll(e =>
|
||||
string.IsNullOrEmpty(e.First.BiomeIdentifier) ||
|
||||
e.First.BiomeIdentifier.Equals(level.LevelData?.Biome?.Identifier, StringComparison.OrdinalIgnoreCase));
|
||||
string.IsNullOrEmpty(e.prefab.BiomeIdentifier) ||
|
||||
e.prefab.BiomeIdentifier.Equals(level.LevelData?.Biome?.Identifier, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
for (int i = 0; i < applyCount; i++)
|
||||
{
|
||||
@@ -429,14 +429,14 @@ namespace Barotrauma
|
||||
{
|
||||
if (suitablePrefabs.Count > 0)
|
||||
{
|
||||
List<Pair<EventPrefab, float>> unusedEvents = new List<Pair<EventPrefab, float>>(suitablePrefabs);
|
||||
var unusedEvents = new List<(EventPrefab prefab, float commonness, float probability)>(suitablePrefabs);
|
||||
for (int j = 0; j < eventSet.EventCount; j++)
|
||||
{
|
||||
if (unusedEvents.All(e => CalculateCommonness(e) <= 0.0f)) { break; }
|
||||
var eventPrefab = ToolBox.SelectWeightedRandom(unusedEvents, unusedEvents.Select(e => CalculateCommonness(e)).ToList(), rand);
|
||||
if (eventPrefab != null)
|
||||
if (unusedEvents.All(e => CalculateCommonness(e.prefab, e.commonness) <= 0.0f)) { break; }
|
||||
(EventPrefab eventPrefab, float commonness, float probability) = ToolBox.SelectWeightedRandom(unusedEvents, unusedEvents.Select(e => CalculateCommonness(e.prefab, e.commonness)).ToList(), rand);
|
||||
if (eventPrefab != null && rand.NextDouble() <= probability)
|
||||
{
|
||||
var newEvent = eventPrefab.First.CreateInstance();
|
||||
var newEvent = eventPrefab.CreateInstance();
|
||||
if (newEvent == null) { continue; }
|
||||
newEvent.Init(true);
|
||||
if (i < spawnPosFilter.Count) { newEvent.SpawnPosFilter = spawnPosFilter[i]; }
|
||||
@@ -450,7 +450,7 @@ namespace Barotrauma
|
||||
selectedEvents.Add(eventSet, new List<Event>());
|
||||
}
|
||||
selectedEvents[eventSet].Add(newEvent);
|
||||
unusedEvents.Remove(eventPrefab);
|
||||
unusedEvents.Remove((eventPrefab, commonness, probability));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -465,9 +465,10 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (Pair<EventPrefab, float> eventPrefab in suitablePrefabs)
|
||||
foreach ((EventPrefab eventPrefab, float commonness, float probability) in suitablePrefabs)
|
||||
{
|
||||
var newEvent = eventPrefab.First.CreateInstance();
|
||||
if (rand.NextDouble() > probability) { continue; }
|
||||
var newEvent = eventPrefab.CreateInstance();
|
||||
if (newEvent == null) { continue; }
|
||||
newEvent.Init(true);
|
||||
#if DEBUG
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Barotrauma
|
||||
{
|
||||
public readonly XElement ConfigElement;
|
||||
public readonly Type EventType;
|
||||
public readonly float SpawnProbability;
|
||||
public readonly float Probability;
|
||||
public readonly bool TriggerEventCooldown;
|
||||
public float Commonness;
|
||||
public string Identifier;
|
||||
@@ -39,7 +39,7 @@ namespace Barotrauma
|
||||
Identifier = ConfigElement.GetAttributeString("identifier", string.Empty);
|
||||
BiomeIdentifier = ConfigElement.GetAttributeString("biome", string.Empty);
|
||||
Commonness = element.GetAttributeFloat("commonness", 1.0f);
|
||||
SpawnProbability = Math.Clamp(element.GetAttributeFloat("spawnprobability", 1.0f), 0, 1);
|
||||
Probability = Math.Clamp(element.GetAttributeFloat(1.0f, "probability", "spawnprobability"), 0, 1);
|
||||
TriggerEventCooldown = element.GetAttributeBool("triggereventcooldown", true);
|
||||
|
||||
UnlockPathEvent = element.GetAttributeBool("unlockpathevent", false);
|
||||
|
||||
@@ -48,10 +48,10 @@ namespace Barotrauma
|
||||
List<EventPrefab> eventPrefabs = new List<EventPrefab>(PrefabList);
|
||||
foreach (var eventSet in List)
|
||||
{
|
||||
eventPrefabs.AddRange(eventSet.EventPrefabs.Select(ep => ep.First));
|
||||
eventPrefabs.AddRange(eventSet.EventPrefabs.Select(ep => ep.prefab));
|
||||
foreach (var childSet in eventSet.ChildSets)
|
||||
{
|
||||
eventPrefabs.AddRange(childSet.EventPrefabs.Select(ep => ep.First));
|
||||
eventPrefabs.AddRange(childSet.EventPrefabs.Select(ep => ep.prefab));
|
||||
}
|
||||
}
|
||||
return eventPrefabs;
|
||||
@@ -96,8 +96,7 @@ namespace Barotrauma
|
||||
|
||||
public readonly Dictionary<string, float> Commonness;
|
||||
|
||||
//Pair.First: event prefab, Pair.Second: commonness
|
||||
public readonly List<Pair<EventPrefab, float>> EventPrefabs;
|
||||
public readonly List<(EventPrefab prefab, float commonness, float probability)> EventPrefabs;
|
||||
|
||||
public readonly List<EventSet> ChildSets;
|
||||
|
||||
@@ -111,7 +110,7 @@ namespace Barotrauma
|
||||
{
|
||||
DebugIdentifier = element.GetAttributeString("identifier", null) ?? debugIdentifier;
|
||||
Commonness = new Dictionary<string, float>();
|
||||
EventPrefabs = new List<Pair<EventPrefab, float>>();
|
||||
EventPrefabs = new List<(EventPrefab prefab, float commonness, float probability)>();
|
||||
ChildSets = new List<EventSet>();
|
||||
|
||||
BiomeIdentifier = element.GetAttributeString("biome", string.Empty);
|
||||
@@ -184,13 +183,14 @@ namespace Barotrauma
|
||||
else
|
||||
{
|
||||
float commonness = subElement.GetAttributeFloat("commonness", prefab.Commonness);
|
||||
EventPrefabs.Add(new Pair<EventPrefab, float>( prefab, commonness));
|
||||
float probability = subElement.GetAttributeFloat("probability", prefab.Probability);
|
||||
EventPrefabs.Add((prefab, commonness, probability));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var prefab = new EventPrefab(subElement);
|
||||
EventPrefabs.Add(new Pair<EventPrefab, float>(prefab, prefab.Commonness));
|
||||
EventPrefabs.Add((prefab, prefab.Commonness, prefab.Probability));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -342,13 +342,13 @@ namespace Barotrauma
|
||||
{
|
||||
if (thisSet.ChooseRandom)
|
||||
{
|
||||
List<Pair<EventPrefab, float>> unusedEvents = new List<Pair<EventPrefab, float>>(thisSet.EventPrefabs);
|
||||
var unusedEvents = new List<(EventPrefab prefab, float commonness, float probability)>(thisSet.EventPrefabs);
|
||||
for (int i = 0; i < thisSet.EventCount; i++)
|
||||
{
|
||||
var eventPrefab = ToolBox.SelectWeightedRandom(unusedEvents, unusedEvents.Select(e => e.Second).ToList(), Rand.RandSync.Unsynced);
|
||||
if (eventPrefab != null)
|
||||
var eventPrefab = ToolBox.SelectWeightedRandom(unusedEvents, unusedEvents.Select(e => e.commonness).ToList(), Rand.RandSync.Unsynced);
|
||||
if (eventPrefab.prefab != null)
|
||||
{
|
||||
AddEvent(stats, eventPrefab.First);
|
||||
AddEvent(stats, eventPrefab.prefab);
|
||||
unusedEvents.Remove(eventPrefab);
|
||||
}
|
||||
}
|
||||
@@ -357,7 +357,7 @@ namespace Barotrauma
|
||||
{
|
||||
foreach (var eventPrefab in thisSet.EventPrefabs)
|
||||
{
|
||||
AddEvent(stats, eventPrefab.First);
|
||||
AddEvent(stats, eventPrefab.prefab);
|
||||
}
|
||||
}
|
||||
foreach (var childSet in thisSet.ChildSets)
|
||||
|
||||
@@ -24,6 +24,19 @@ namespace Barotrauma
|
||||
|
||||
private Submarine sub;
|
||||
|
||||
public override string Description
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Submarine.MainSub != sub)
|
||||
{
|
||||
string rewardText = $"‖color:gui.orange‖{string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0:N0}", GetReward(Submarine.MainSub))}‖end‖";
|
||||
if (descriptionWithoutReward != null) { description = descriptionWithoutReward.Replace("[reward]", rewardText); }
|
||||
}
|
||||
return description;
|
||||
}
|
||||
}
|
||||
|
||||
public CargoMission(MissionPrefab prefab, Location[] locations, Submarine sub)
|
||||
: base(prefab, locations, sub)
|
||||
{
|
||||
|
||||
@@ -14,12 +14,15 @@ namespace Barotrauma
|
||||
private readonly XElement itemConfig;
|
||||
|
||||
private readonly List<Character> characters = new List<Character>();
|
||||
private readonly Dictionary<Character, List<Item>> characterDictionary = new Dictionary<Character, List<Item>>();
|
||||
private readonly Dictionary<Character, List<Item>> characterItems = new Dictionary<Character, List<Item>>();
|
||||
|
||||
private readonly int baseEscortedCharacters;
|
||||
private readonly float scalingEscortedCharacters;
|
||||
private readonly float terroristChance;
|
||||
|
||||
private int calculatedReward;
|
||||
private Submarine missionSub;
|
||||
|
||||
private Character vipCharacter;
|
||||
|
||||
private readonly List<Character> terroristCharacters = new List<Character>();
|
||||
@@ -30,24 +33,43 @@ namespace Barotrauma
|
||||
public EscortMission(MissionPrefab prefab, Location[] locations, Submarine sub)
|
||||
: base(prefab, locations, sub)
|
||||
{
|
||||
missionSub = sub;
|
||||
characterConfig = prefab.ConfigElement.Element("Characters");
|
||||
// Should reflect different escortables, prisoners, VIPs, passengers (where does this comment refer to?)
|
||||
|
||||
baseEscortedCharacters = prefab.ConfigElement.GetAttributeInt("baseescortedcharacters", 1);
|
||||
scalingEscortedCharacters = prefab.ConfigElement.GetAttributeFloat("scalingescortedcharacters", 0);
|
||||
terroristChance = prefab.ConfigElement.GetAttributeFloat("terroristchance", 0);
|
||||
itemConfig = prefab.ConfigElement.Element("TerroristItems");
|
||||
CalculateReward();
|
||||
}
|
||||
|
||||
private void CalculateReward()
|
||||
{
|
||||
if (missionSub == null)
|
||||
{
|
||||
calculatedReward = Prefab.Reward;
|
||||
return;
|
||||
}
|
||||
|
||||
int multiplier = CalculateScalingEscortedCharacterCount();
|
||||
calculatedReward = Prefab.Reward * multiplier;
|
||||
|
||||
string rewardText = $"‖color:gui.orange‖{string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0:N0}", GetReward(missionSub))}‖end‖";
|
||||
if (descriptionWithoutReward != null) { description = descriptionWithoutReward.Replace("[reward]", rewardText); }
|
||||
}
|
||||
|
||||
public override int GetReward(Submarine sub)
|
||||
{
|
||||
int multiplier = CalculateScalingEscortedCharacterCount();
|
||||
return Prefab.Reward * multiplier;
|
||||
if (sub != missionSub)
|
||||
{
|
||||
missionSub = sub;
|
||||
CalculateReward();
|
||||
}
|
||||
return calculatedReward;
|
||||
}
|
||||
|
||||
int CalculateScalingEscortedCharacterCount(bool inMission = false)
|
||||
{
|
||||
if (Submarine.MainSub == null || Submarine.MainSub.Info == null) // UI logic failing to get the correct value is not important, but the mission logic must succeed
|
||||
if (missionSub == null || missionSub.Info == null) // UI logic failing to get the correct value is not important, but the mission logic must succeed
|
||||
{
|
||||
if (inMission)
|
||||
{
|
||||
@@ -55,13 +77,13 @@ namespace Barotrauma
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return (int)Math.Round(baseEscortedCharacters + scalingEscortedCharacters * (Submarine.MainSub.Info.RecommendedCrewSizeMin + Submarine.MainSub.Info.RecommendedCrewSizeMax) / 2);
|
||||
return (int)Math.Round(baseEscortedCharacters + scalingEscortedCharacters * (missionSub.Info.RecommendedCrewSizeMin + missionSub.Info.RecommendedCrewSizeMax) / 2);
|
||||
}
|
||||
|
||||
private void InitEscort()
|
||||
{
|
||||
characters.Clear();
|
||||
characterDictionary.Clear();
|
||||
characterItems.Clear();
|
||||
// VIP transport mission characters stay in the same location; other characters roam at will
|
||||
// could be replaced with a designated waypoint for VIPs, such as cargo or crew
|
||||
WayPoint explicitStayInHullPos = WayPoint.GetRandom(SpawnType.Human, null, Submarine.MainSub);
|
||||
@@ -78,7 +100,7 @@ namespace Barotrauma
|
||||
int count = CalculateScalingEscortedCharacterCount(inMission: true);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Character spawnedCharacter = CreateHuman(CreateHumanPrefabFromElement(element), characters, characterDictionary, Submarine.MainSub, CharacterTeamType.FriendlyNPC, explicitStayInHullPos, humanPrefabRandSync: randSync);
|
||||
Character spawnedCharacter = CreateHuman(CreateHumanPrefabFromElement(element), characters, characterItems, Submarine.MainSub, CharacterTeamType.FriendlyNPC, explicitStayInHullPos, humanPrefabRandSync: randSync);
|
||||
if (spawnedCharacter.AIController is HumanAIController humanAI)
|
||||
{
|
||||
humanAI.InitMentalStateManager();
|
||||
@@ -156,6 +178,13 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
|
||||
// to ensure single missions run without issues, default to mainsub
|
||||
if (missionSub == null)
|
||||
{
|
||||
missionSub = Submarine.MainSub;
|
||||
CalculateReward();
|
||||
}
|
||||
|
||||
if (!IsClient)
|
||||
{
|
||||
InitEscort();
|
||||
@@ -276,7 +305,7 @@ namespace Barotrauma
|
||||
// characters that survived will take their items with them, in case players tried to be crafty and steal them
|
||||
// this needs to run here in case players abort the mission by going back home
|
||||
// TODO: I think this might feel like a bug.
|
||||
foreach (var characterItem in characterDictionary)
|
||||
foreach (var characterItem in characterItems)
|
||||
{
|
||||
if (Survived(characterItem.Key) || !completed)
|
||||
{
|
||||
@@ -291,7 +320,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
characters.Clear();
|
||||
characterDictionary.Clear();
|
||||
characterItems.Clear();
|
||||
failed = !completed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -400,8 +400,6 @@ namespace Barotrauma
|
||||
// putting these here since both escort and pirate missions need them. could be tucked away into another class that they can inherit from (or use composition)
|
||||
protected HumanPrefab CreateHumanPrefabFromElement(XElement element)
|
||||
{
|
||||
HumanPrefab humanPrefab = null;
|
||||
|
||||
if (element.Attribute("name") != null)
|
||||
{
|
||||
DebugConsole.ThrowError("Error in mission \"" + Name + "\" - use character identifiers instead of names to configure the characters.");
|
||||
@@ -411,8 +409,7 @@ namespace Barotrauma
|
||||
|
||||
string characterIdentifier = element.GetAttributeString("identifier", "");
|
||||
string characterFrom = element.GetAttributeString("from", "");
|
||||
humanPrefab = NPCSet.Get(characterFrom, characterIdentifier);
|
||||
|
||||
HumanPrefab humanPrefab = NPCSet.Get(characterFrom, characterIdentifier);
|
||||
if (humanPrefab == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Couldn't spawn character for mission: character prefab \"" + characterIdentifier + "\" not found");
|
||||
@@ -428,9 +425,11 @@ namespace Barotrauma
|
||||
{
|
||||
positionToStayIn = WayPoint.GetRandom(SpawnType.Human, null, submarine);
|
||||
}
|
||||
var characterInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, npcIdentifier: humanPrefab.Identifier, jobPrefab: humanPrefab.GetJobPrefab(humanPrefabRandSync), randSync: humanPrefabRandSync);
|
||||
|
||||
var characterInfo = humanPrefab.GetCharacterInfo(Rand.RandSync.Server) ?? new CharacterInfo(CharacterPrefab.HumanSpeciesName, npcIdentifier: humanPrefab.Identifier, jobPrefab: humanPrefab.GetJobPrefab(humanPrefabRandSync), randSync: humanPrefabRandSync);
|
||||
characterInfo.TeamID = teamType;
|
||||
Character spawnedCharacter = Character.Create(characterInfo.SpeciesName, positionToStayIn.WorldPosition, ToolBox.RandomSeed(8), characterInfo, createNetworkEvent: false);
|
||||
spawnedCharacter.Prefab = humanPrefab;
|
||||
humanPrefab.InitializeCharacter(spawnedCharacter, positionToStayIn);
|
||||
humanPrefab.GiveItems(spawnedCharacter, submarine, Rand.RandSync.Server, createNetworkEvents: false);
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Barotrauma
|
||||
|
||||
private Submarine enemySub;
|
||||
private readonly List<Character> characters = new List<Character>();
|
||||
private readonly Dictionary<Character, List<Item>> characterDictionary = new Dictionary<Character, List<Item>>();
|
||||
private readonly Dictionary<Character, List<Item>> characterItems = new Dictionary<Character, List<Item>>();
|
||||
|
||||
// Update the last sighting periodically so that the players can find the pirate sub even if they have lost the track of it.
|
||||
private readonly float pirateSightingUpdateFrequency = 30;
|
||||
@@ -103,17 +103,20 @@ namespace Barotrauma
|
||||
|
||||
alternateReward = submarineConfig.GetAttributeInt("alternatereward", Reward);
|
||||
|
||||
string submarineIdentifier = submarineConfig.GetAttributeString("identifier", string.Empty);
|
||||
if (submarineIdentifier == string.Empty)
|
||||
string rewardText = $"‖color:gui.orange‖{string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0:N0}", alternateReward)}‖end‖";
|
||||
if (descriptionWithoutReward != null) { description = descriptionWithoutReward.Replace("[reward]", rewardText); }
|
||||
|
||||
string submarinePath = submarineConfig.GetAttributeString("path", string.Empty);
|
||||
if (submarinePath == string.Empty)
|
||||
{
|
||||
DebugConsole.ThrowError("No identifier used for submarine for pirate mission!");
|
||||
DebugConsole.ThrowError($"No path used for submarine for the pirate mission \"{Prefab.Identifier}\"!");
|
||||
return;
|
||||
}
|
||||
// maybe a little redundant
|
||||
var contentFile = ContentPackage.GetFilesOfType(GameMain.Config.AllEnabledPackages, ContentType.EnemySubmarine).FirstOrDefault(x => x.Path == submarineIdentifier);
|
||||
var contentFile = ContentPackage.GetFilesOfType(GameMain.Config.AllEnabledPackages, ContentType.EnemySubmarine).FirstOrDefault(x => x.Path == submarinePath);
|
||||
if (contentFile == null)
|
||||
{
|
||||
DebugConsole.ThrowError("No submarine file found with the identifier!");
|
||||
DebugConsole.ThrowError($"No submarine file found from the path {submarinePath}!");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -187,14 +190,13 @@ namespace Barotrauma
|
||||
reactor.PowerUpImmediately();
|
||||
}
|
||||
enemySub.EnableMaintainPosition();
|
||||
enemySub.SetPosition(spawnPos);
|
||||
enemySub.TeamID = CharacterTeamType.None;
|
||||
}
|
||||
|
||||
private void InitPirates()
|
||||
{
|
||||
characters.Clear();
|
||||
characterDictionary.Clear();
|
||||
characterItems.Clear();
|
||||
|
||||
if (characterConfig == null)
|
||||
{
|
||||
@@ -222,13 +224,13 @@ namespace Barotrauma
|
||||
|
||||
if (characterType == null)
|
||||
{
|
||||
DebugConsole.ThrowError("No character types defined in CharacterTypes for a declared type identifier in mission file " + this);
|
||||
DebugConsole.ThrowError($"No character types defined in CharacterTypes for a declared type identifier in mission \"{Prefab.Identifier}\".");
|
||||
return;
|
||||
}
|
||||
|
||||
XElement variantElement = GetRandomDifficultyModifiedElement(characterType, enemyCreationDifficulty, RandomnessModifier);
|
||||
|
||||
Character spawnedCharacter = CreateHuman(CreateHumanPrefabFromElement(variantElement), characters, characterDictionary, enemySub, CharacterTeamType.None, null);
|
||||
Character spawnedCharacter = CreateHuman(CreateHumanPrefabFromElement(variantElement), characters, characterItems, enemySub, CharacterTeamType.None, null);
|
||||
if (!commanderAssigned)
|
||||
{
|
||||
bool isCommander = variantElement.GetAttributeBool("iscommander", false);
|
||||
@@ -242,6 +244,14 @@ namespace Barotrauma
|
||||
commanderAssigned = true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Item item in spawnedCharacter.Inventory.AllItems)
|
||||
{
|
||||
if (item?.Prefab.Identifier == "idcard")
|
||||
{
|
||||
item.AddTag("id_pirate");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -297,9 +307,10 @@ namespace Barotrauma
|
||||
{
|
||||
InitPirateShip(spawnPos);
|
||||
}
|
||||
enemySub.SetPosition(spawnPos);
|
||||
|
||||
// flipping the sub on the frame it is moved into place must be done after it's been moved, or it breaks item connections to the submarine
|
||||
// creating the pirates have to be done after the sub has been flipped, or it seems to break the AI pathing
|
||||
// flipping the sub on the frame it is moved into place must be done after it's been moved, or it breaks item connections in the submarine
|
||||
// creating the pirates has to be done after the sub has been flipped, or it seems to break the AI pathing
|
||||
enemySub.FlipX();
|
||||
enemySub.ShowSonarMarker = false;
|
||||
|
||||
@@ -375,7 +386,7 @@ namespace Barotrauma
|
||||
completed = true;
|
||||
}
|
||||
characters.Clear();
|
||||
characterDictionary.Clear();
|
||||
characterItems.Clear();
|
||||
failed = !completed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,13 +182,6 @@ namespace Barotrauma
|
||||
{
|
||||
if (disallowed) { return; }
|
||||
|
||||
if (Rand.Value(Rand.RandSync.Server) > prefab.SpawnProbability)
|
||||
{
|
||||
spawnPos = null;
|
||||
Finished();
|
||||
return;
|
||||
}
|
||||
|
||||
spawnPos = Vector2.Zero;
|
||||
var availablePositions = GetAvailableSpawnPositions();
|
||||
var chosenPosition = new Level.InterestingPosition(Point.Zero, Level.PositionType.MainPath, isValid: false);
|
||||
|
||||
Reference in New Issue
Block a user