Unstable 0.1400.7.0 (Coronavirus edition)
This commit is contained in:
@@ -10,8 +10,8 @@ namespace Barotrauma
|
||||
[Serialize("", true)]
|
||||
public string NPCTag { get; set; }
|
||||
|
||||
[Serialize(0, true)]
|
||||
public int TeamTag { get; set; }
|
||||
[Serialize(CharacterTeamType.None, true)]
|
||||
public CharacterTeamType TeamTag { get; set; }
|
||||
|
||||
[Serialize(false, true)]
|
||||
public bool AddToCrew { get; set; }
|
||||
@@ -29,11 +29,10 @@ namespace Barotrauma
|
||||
affectedNpcs = ParentEvent.GetTargets(NPCTag).Where(c => c is Character).Select(c => c as Character).ToList();
|
||||
foreach (var npc in affectedNpcs)
|
||||
{
|
||||
CharacterTeamType newTeam = (CharacterTeamType)TeamTag;
|
||||
// characters will still remain on friendlyNPC team for rest of the tick
|
||||
npc.SetOriginalTeam(newTeam);
|
||||
npc.SetOriginalTeam(TeamTag);
|
||||
|
||||
if (AddToCrew && (newTeam == CharacterTeamType.Team1 || newTeam == CharacterTeamType.Team2))
|
||||
if (AddToCrew && (TeamTag == CharacterTeamType.Team1 || TeamTag == CharacterTeamType.Team2))
|
||||
{
|
||||
npc.Info.StartItemsGiven = true;
|
||||
|
||||
@@ -44,11 +43,11 @@ namespace Barotrauma
|
||||
var wifiComponent = item.GetComponent<Items.Components.WifiComponent>();
|
||||
if (wifiComponent != null)
|
||||
{
|
||||
wifiComponent.TeamID = newTeam;
|
||||
wifiComponent.TeamID = TeamTag;
|
||||
}
|
||||
}
|
||||
#if SERVER
|
||||
GameMain.NetworkMember.CreateEntityEvent(npc, new object[] { NetEntityEvent.Type.AddToCrew, newTeam, npc.Inventory.AllItems.Select(it => it.ID).ToArray() });
|
||||
GameMain.NetworkMember.CreateEntityEvent(npc, new object[] { NetEntityEvent.Type.AddToCrew, TeamTag, npc.Inventory.AllItems.Select(it => it.ID).ToArray() });
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,13 +124,24 @@ namespace Barotrauma
|
||||
}
|
||||
MTRandom rand = new MTRandom(seed);
|
||||
|
||||
var initialEventSet = SelectRandomEvents(EventSet.List, rand);
|
||||
EventSet initialEventSet = SelectRandomEvents(EventSet.List, rand);
|
||||
EventSet additiveSet = null;
|
||||
if (initialEventSet != null && initialEventSet.Additive)
|
||||
{
|
||||
additiveSet = initialEventSet;
|
||||
initialEventSet = SelectRandomEvents(EventSet.List.FindAll(e => !e.Additive), rand);
|
||||
}
|
||||
if (initialEventSet != null)
|
||||
{
|
||||
pendingEventSets.Add(initialEventSet);
|
||||
CreateEvents(initialEventSet, rand);
|
||||
}
|
||||
|
||||
if (additiveSet != null)
|
||||
{
|
||||
pendingEventSets.Add(additiveSet);
|
||||
CreateEvents(additiveSet, rand);
|
||||
}
|
||||
|
||||
if (level?.LevelData?.Type == LevelData.LevelType.Outpost)
|
||||
{
|
||||
//if the outpost is connected to a locked connection, create an event to unlock it
|
||||
|
||||
@@ -94,6 +94,8 @@ namespace Barotrauma
|
||||
|
||||
public readonly bool TriggerEventCooldown;
|
||||
|
||||
public readonly bool Additive;
|
||||
|
||||
public readonly Dictionary<string, float> Commonness;
|
||||
|
||||
public readonly List<(EventPrefab prefab, float commonness, float probability)> EventPrefabs;
|
||||
@@ -117,6 +119,8 @@ namespace Barotrauma
|
||||
MinLevelDifficulty = element.GetAttributeFloat("minleveldifficulty", 0);
|
||||
MaxLevelDifficulty = Math.Max(element.GetAttributeFloat("maxleveldifficulty", 100), MinLevelDifficulty);
|
||||
|
||||
Additive = element.GetAttributeBool("additive", false);
|
||||
|
||||
string levelTypeStr = element.GetAttributeString("leveltype", "LocationConnection");
|
||||
if (!Enum.TryParse(levelTypeStr, true, out LevelType))
|
||||
{
|
||||
|
||||
@@ -24,6 +24,8 @@ namespace Barotrauma
|
||||
|
||||
private Submarine sub;
|
||||
|
||||
private readonly List<CargoMission> previouslySelectedMissions = new List<CargoMission>();
|
||||
|
||||
public override string Description
|
||||
{
|
||||
get
|
||||
@@ -42,7 +44,13 @@ namespace Barotrauma
|
||||
{
|
||||
this.sub = sub;
|
||||
itemConfig = prefab.ConfigElement.Element("Items");
|
||||
requiredDeliveryAmount = Math.Min(prefab.ConfigElement.GetAttributeFloat("requireddeliveryamount", 0.98f), 1.0f);
|
||||
requiredDeliveryAmount = Math.Min(prefab.ConfigElement.GetAttributeFloat("requireddeliveryamount", 0.98f), 1.0f);
|
||||
//this can get called between rounds when the client receives a campaign save
|
||||
//don't attempt to determine cargo if the sub hasn't been fully loaded
|
||||
if (sub == null || sub.Loading || sub.Removed || Submarine.Unloading)
|
||||
{
|
||||
return;
|
||||
}
|
||||
DetermineCargo();
|
||||
}
|
||||
|
||||
@@ -58,6 +66,30 @@ namespace Barotrauma
|
||||
List<(ItemContainer container, int freeSlots)> containers = sub.GetCargoContainers();
|
||||
containers.Sort((c1, c2) => { return c2.container.Capacity.CompareTo(c1.container.Capacity); });
|
||||
|
||||
previouslySelectedMissions.Clear();
|
||||
if (GameMain.GameSession?.StartLocation?.SelectedMissions != null)
|
||||
{
|
||||
bool isPriorMission = true;
|
||||
foreach (Mission mission in GameMain.GameSession.StartLocation.SelectedMissions)
|
||||
{
|
||||
if (!(mission is CargoMission otherMission)) { continue; }
|
||||
if (mission == this) { isPriorMission = false; }
|
||||
previouslySelectedMissions.Add(otherMission);
|
||||
if (!isPriorMission) { continue; }
|
||||
foreach (var (element, container) in otherMission.itemsToSpawn)
|
||||
{
|
||||
for (int i = 0; i < containers.Count; i++)
|
||||
{
|
||||
if (containers[i].container == container)
|
||||
{
|
||||
containers[i] = (containers[i].container, containers[i].freeSlots - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
maxItemCount = 0;
|
||||
foreach (XElement subElement in itemConfig.Elements())
|
||||
{
|
||||
@@ -87,9 +119,9 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
calculatedReward = 0;
|
||||
foreach (var itemToSpawn in itemsToSpawn)
|
||||
foreach (var (element, container) in itemsToSpawn)
|
||||
{
|
||||
int price = itemToSpawn.element.GetAttributeInt("reward", Prefab.Reward / itemsToSpawn.Count);
|
||||
int price = element.GetAttributeInt("reward", Prefab.Reward / itemsToSpawn.Count);
|
||||
if (rewardPerCrate.HasValue)
|
||||
{
|
||||
if (price != rewardPerCrate.Value) { rewardPerCrate = -1; }
|
||||
@@ -108,7 +140,28 @@ namespace Barotrauma
|
||||
|
||||
public override int GetReward(Submarine sub)
|
||||
{
|
||||
if (sub != this.sub)
|
||||
bool missionsChanged = false;
|
||||
if (GameMain.GameSession?.StartLocation?.SelectedMissions != null)
|
||||
{
|
||||
List<Mission> currentMissions = GameMain.GameSession.StartLocation.SelectedMissions.Where(m => m is CargoMission).ToList();
|
||||
if (currentMissions.Count != previouslySelectedMissions.Count)
|
||||
{
|
||||
missionsChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < previouslySelectedMissions.Count; i++)
|
||||
{
|
||||
if (previouslySelectedMissions[i] != currentMissions[i])
|
||||
{
|
||||
missionsChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sub != this.sub || missionsChanged)
|
||||
{
|
||||
this.sub = sub;
|
||||
DetermineCargo();
|
||||
|
||||
@@ -183,7 +183,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void SetDifficulty(float difficulty) { }
|
||||
public virtual void SetLevel(LevelData level) { }
|
||||
|
||||
public static Mission LoadRandom(Location[] locations, string seed, bool requireCorrectLocationType, MissionType missionType, bool isSinglePlayer = false)
|
||||
{
|
||||
@@ -423,13 +423,16 @@ namespace Barotrauma
|
||||
|
||||
protected Character CreateHuman(HumanPrefab humanPrefab, List<Character> characters, Dictionary<Character, List<Item>> characterItems, Submarine submarine, CharacterTeamType teamType, ISpatialEntity positionToStayIn = null, Rand.RandSync humanPrefabRandSync = Rand.RandSync.Server, bool giveTags = true)
|
||||
{
|
||||
if (positionToStayIn == null)
|
||||
{
|
||||
positionToStayIn = WayPoint.GetRandom(SpawnType.Human, null, submarine);
|
||||
}
|
||||
|
||||
var characterInfo = humanPrefab.GetCharacterInfo(Rand.RandSync.Server) ?? new CharacterInfo(CharacterPrefab.HumanSpeciesName, npcIdentifier: humanPrefab.Identifier, jobPrefab: humanPrefab.GetJobPrefab(humanPrefabRandSync), randSync: humanPrefabRandSync);
|
||||
characterInfo.TeamID = teamType;
|
||||
|
||||
if (positionToStayIn == null)
|
||||
{
|
||||
positionToStayIn =
|
||||
WayPoint.GetRandom(SpawnType.Human, characterInfo.Job?.Prefab, submarine) ??
|
||||
WayPoint.GetRandom(SpawnType.Human, null, submarine);
|
||||
}
|
||||
|
||||
Character spawnedCharacter = Character.Create(characterInfo.SpeciesName, positionToStayIn.WorldPosition, ToolBox.RandomSeed(8), characterInfo, createNetworkEvent: false);
|
||||
spawnedCharacter.Prefab = humanPrefab;
|
||||
humanPrefab.InitializeCharacter(spawnedCharacter, positionToStayIn);
|
||||
|
||||
@@ -107,7 +107,7 @@ namespace Barotrauma
|
||||
//ruin/cave/wreck items are allowed to spawn close to the sub
|
||||
float minDistance = spawnPositionType == Level.PositionType.Ruin || spawnPositionType == Level.PositionType.Cave || spawnPositionType == Level.PositionType.Wreck ?
|
||||
0.0f : Level.Loaded.Size.X * 0.3f;
|
||||
nestPosition = Level.Loaded.GetRandomItemPos(spawnPositionType, 100.0f, minDistance, 30.0f);
|
||||
Level.Loaded.TryGetInterestingPosition(true, spawnPositionType, 0.0f, out Vector2 nestPosition);
|
||||
List<GraphEdge> spawnEdges = new List<GraphEdge>();
|
||||
if (spawnPositionType == Level.PositionType.Cave)
|
||||
{
|
||||
|
||||
@@ -28,6 +28,8 @@ namespace Barotrauma
|
||||
private float pirateSightingUpdateTimer;
|
||||
private Vector2? lastSighting;
|
||||
|
||||
private LevelData levelData;
|
||||
|
||||
public override int TeamCount => 2;
|
||||
|
||||
private bool outsideOfSonarRange;
|
||||
@@ -83,21 +85,24 @@ namespace Barotrauma
|
||||
characterTypeConfig = prefab.ConfigElement.Element("CharacterTypes");
|
||||
addedMissionDifficultyPerPlayer = prefab.ConfigElement.GetAttributeFloat("addedmissiondifficultyperplayer", 0);
|
||||
|
||||
// for campaign missions, set difficulty at construction
|
||||
// for campaign missions, set level at construction
|
||||
LevelData levelData = locations[0].Connections.Where(c => c.Locations.Contains(locations[1])).FirstOrDefault()?.LevelData ?? locations[0]?.LevelData;
|
||||
|
||||
SetDifficulty(levelData?.Difficulty ?? Level.Loaded?.Difficulty ?? 0f);
|
||||
if (levelData != null)
|
||||
{
|
||||
SetLevel(levelData);
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetDifficulty(float difficulty)
|
||||
public override void SetLevel(LevelData level)
|
||||
{
|
||||
if (missionDifficulty > 0f)
|
||||
if (levelData != null)
|
||||
{
|
||||
// difficulty already set
|
||||
//level already set
|
||||
return;
|
||||
}
|
||||
|
||||
missionDifficulty = difficulty;
|
||||
levelData = level;
|
||||
missionDifficulty = level?.Difficulty ?? 0;
|
||||
|
||||
XElement submarineConfig = GetRandomDifficultyModifiedElement(submarineTypeConfig, missionDifficulty, ShipRandomnessModifier);
|
||||
|
||||
@@ -123,23 +128,24 @@ namespace Barotrauma
|
||||
submarineInfo = new SubmarineInfo(contentFile.Path);
|
||||
}
|
||||
|
||||
private float GetDifficultyModifiedValue(float preferredDifficulty, float levelDifficulty, float randomnessModifier)
|
||||
private float GetDifficultyModifiedValue(float preferredDifficulty, float levelDifficulty, float randomnessModifier, Random rand)
|
||||
{
|
||||
return Math.Abs(levelDifficulty - preferredDifficulty + (Rand.Range(-randomnessModifier, randomnessModifier, Rand.RandSync.Server)));
|
||||
return Math.Abs(levelDifficulty - preferredDifficulty + MathHelper.Lerp(-randomnessModifier, randomnessModifier, (float)rand.NextDouble()));
|
||||
}
|
||||
private int GetDifficultyModifiedAmount(int minAmount, int maxAmount, float levelDifficulty)
|
||||
private int GetDifficultyModifiedAmount(int minAmount, int maxAmount, float levelDifficulty, Random rand)
|
||||
{
|
||||
return Math.Max((int)Math.Round(minAmount + (maxAmount - minAmount) * ((levelDifficulty + Rand.Range(-RandomnessModifier, RandomnessModifier, Rand.RandSync.Server)) / MaxDifficulty)), minAmount);
|
||||
return Math.Max((int)Math.Round(minAmount + (maxAmount - minAmount) * (levelDifficulty + MathHelper.Lerp(-RandomnessModifier, RandomnessModifier, (float)rand.NextDouble())) / MaxDifficulty), minAmount);
|
||||
}
|
||||
|
||||
private XElement GetRandomDifficultyModifiedElement(XElement parentElement, float levelDifficulty, float randomnessModifier)
|
||||
{
|
||||
Random rand = new MTRandom(ToolBox.StringToInt(levelData.Seed));
|
||||
// look for the element that is closest to our difficulty, with some randomness
|
||||
XElement bestElement = null;
|
||||
float bestValue = float.MaxValue;
|
||||
foreach (XElement element in parentElement.Elements())
|
||||
{
|
||||
float applicabilityValue = GetDifficultyModifiedValue(element.GetAttributeFloat(0f, "preferreddifficulty"), levelDifficulty, randomnessModifier);
|
||||
float applicabilityValue = GetDifficultyModifiedValue(element.GetAttributeFloat(0f, "preferreddifficulty"), levelDifficulty, randomnessModifier, rand);
|
||||
if (applicabilityValue < bestValue)
|
||||
{
|
||||
bestElement = element;
|
||||
@@ -154,11 +160,11 @@ namespace Barotrauma
|
||||
Vector2 patrolPos = enemySub.WorldPosition;
|
||||
Point subSize = enemySub.GetDockedBorders().Size;
|
||||
|
||||
if (!Level.Loaded.TryGetInterestingPosition(true, Level.PositionType.MainPath | Level.PositionType.SidePath, Level.Loaded.Size.X * 0.3f, out preferredSpawnPos))
|
||||
if (!Level.Loaded.TryGetInterestingPosition(true, Level.PositionType.MainPath, Level.Loaded.Size.X * 0.3f, out preferredSpawnPos))
|
||||
{
|
||||
DebugConsole.ThrowError("Could not spawn pirate submarine in an interesting location! " + this);
|
||||
}
|
||||
if (!Level.Loaded.TryGetInterestingPositionAwayFromPoint(true, Level.PositionType.MainPath | Level.PositionType.SidePath, Level.Loaded.Size.X * 0.3f, out patrolPos, preferredSpawnPos, minDistFromPoint: 10000f))
|
||||
if (!Level.Loaded.TryGetInterestingPositionAwayFromPoint(true, Level.PositionType.MainPath, Level.Loaded.Size.X * 0.3f, out patrolPos, preferredSpawnPos, minDistFromPoint: 10000f))
|
||||
{
|
||||
DebugConsole.ThrowError("Could not give pirate submarine an interesting location to patrol to! " + this);
|
||||
}
|
||||
@@ -182,7 +188,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private void InitPirateShip(Vector2 spawnPos)
|
||||
private void InitPirateShip()
|
||||
{
|
||||
enemySub.NeutralizeBallast();
|
||||
if (enemySub.GetItems(alsoFromConnectedSubs: false).Find(i => i.HasTag("reactor") && !i.NonInteractable)?.GetComponent<Reactor>() is Reactor reactor)
|
||||
@@ -193,6 +199,7 @@ namespace Barotrauma
|
||||
enemySub.TeamID = CharacterTeamType.None;
|
||||
//make the enemy sub withstand atleast the same depth as the player sub
|
||||
enemySub.RealWorldCrushDepth = Math.Max(enemySub.RealWorldCrushDepth, Submarine.MainSub.RealWorldCrushDepth);
|
||||
enemySub.ImmuneToBallastFlora = true;
|
||||
}
|
||||
|
||||
private void InitPirates()
|
||||
@@ -214,12 +221,14 @@ namespace Barotrauma
|
||||
|
||||
float enemyCreationDifficulty = missionDifficulty + playerCount * addedMissionDifficultyPerPlayer;
|
||||
|
||||
Random rand = new MTRandom(ToolBox.StringToInt(levelData.Seed));
|
||||
|
||||
bool commanderAssigned = false;
|
||||
foreach (XElement element in characterConfig.Elements())
|
||||
{
|
||||
// it is possible to get more than the "max" amount of characters if the modified difficulty is high enough; this is intentional
|
||||
// if necessary, another "hard max" value could be used to clamp the value for performance/gameplay concerns
|
||||
int amountCreated = GetDifficultyModifiedAmount(element.GetAttributeInt("minamount", 0), element.GetAttributeInt("maxamount", 0), enemyCreationDifficulty);
|
||||
int amountCreated = GetDifficultyModifiedAmount(element.GetAttributeInt("minamount", 0), element.GetAttributeInt("maxamount", 0), enemyCreationDifficulty, rand);
|
||||
for (int i = 0; i < amountCreated; i++)
|
||||
{
|
||||
XElement characterType = characterTypeConfig.Elements().Where(e => e.GetAttributeString("typeidentifier", string.Empty) == element.GetAttributeString("typeidentifier", string.Empty)).FirstOrDefault();
|
||||
@@ -307,7 +316,7 @@ namespace Barotrauma
|
||||
#endif
|
||||
if (!IsClient)
|
||||
{
|
||||
InitPirateShip(spawnPos);
|
||||
InitPirateShip();
|
||||
}
|
||||
enemySub.SetPosition(spawnPos);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user