Unstable 0.14.4.0

This commit is contained in:
Markus Isberg
2021-06-09 17:09:20 +03:00
parent de04525d51
commit 1f3e588fcd
54 changed files with 468 additions and 133 deletions
@@ -479,7 +479,7 @@ namespace Barotrauma
Character.AnimController.InWater ||
Character.AnimController.HeadInWater ||
Character.CurrentHull == null ||
(Character.Submarine.TeamID != Character.TeamID && !Character.IsEscorted) || // these instances should maybe be combined to a method
(Character.Submarine?.TeamID != Character.TeamID && !Character.IsEscorted) || // these instances should maybe be combined to a method
ObjectiveManager.IsCurrentObjective<AIObjectiveFindSafety>() ||
ObjectiveManager.CurrentObjective.GetSubObjectivesRecursive(true).Any(o => o.KeepDivingGearOn);
if (oxygenLow && Character.CurrentHull.Oxygen > 0)
@@ -244,12 +244,12 @@ namespace Barotrauma
availableIssues.Sort((x, y) => y.Importance.CompareTo(x.Importance));
attendedIssues.Sort((x, y) => x.Importance.CompareTo(y.Importance));
ShipIssueWorker mostImportantIssue = availableIssues.First();
ShipIssueWorker mostImportantIssue = availableIssues.FirstOrDefault();
float bestValue = 0f;
Character bestCharacter = null;
if (mostImportantIssue.Importance > MinimumIssueThreshold)
if (mostImportantIssue != null && mostImportantIssue.Importance > MinimumIssueThreshold)
{
IEnumerable<Character> bestCharacters = CrewManager.GetCharactersSortedForOrder(mostImportantIssue.SuggestedOrderPrefab, AlliedCharacters, character, true);
@@ -296,7 +296,7 @@ namespace Barotrauma
}
}
if (bestCharacter != null)
if (bestCharacter != null && mostImportantIssue != null)
{
#if DEBUG
ShipCommandLog("Setting " + mostImportantIssue + " for character " + bestCharacter);
@@ -637,7 +637,7 @@ namespace Barotrauma
impactQueue.Enqueue(new Impact(f1, f2, contact, velocity));
}
}
return !f2.IsSensor;
return true;
}
Vector2 colliderBottom = GetColliderBottom();
@@ -514,7 +514,7 @@ namespace Barotrauma
DamageParticles(deltaTime, worldPosition);
var attackResult = targetLimb.character.ApplyAttack(attacker, worldPosition, this, deltaTime, playSound, targetLimb, penetration:Penetration);
var attackResult = targetLimb.character.ApplyAttack(attacker, worldPosition, this, deltaTime, playSound, targetLimb, penetration: Penetration);
var effectType = attackResult.Damage > 0.0f ? ActionType.OnUse : ActionType.OnFailure;
foreach (StatusEffect effect in statusEffects)
@@ -300,7 +300,6 @@ namespace Barotrauma
}
foreach (XElement element in mainElement.Elements())
{
if (!element.Name.ToString().Equals("job", StringComparison.OrdinalIgnoreCase)) { continue; }
if (element.IsOverride())
{
var job = new JobPrefab(element.FirstElement(), file.Path)
@@ -311,6 +310,7 @@ namespace Barotrauma
}
else
{
if (!element.Name.ToString().Equals("job", StringComparison.OrdinalIgnoreCase)) { continue; }
var job = new JobPrefab(element, file.Path)
{
ContentPackage = file.ContentPackage
@@ -17,25 +17,33 @@ namespace Barotrauma
// Anything that uses this field I wasn't sure if actually needed the proper campaign settings to be passed down
public static CampaignSettings Unsure = Empty;
public bool RadiationEnabled { get; set; }
public int MaxMissionCount { get; set; }
public const int DefaultMaxMissionCount = 2;
public const int MaxMissionCountLimit = 10;
public const int MinMissionCountLimit = 1;
public CampaignSettings(IReadMessage inc)
{
RadiationEnabled = inc.ReadBoolean();
MaxMissionCount = inc.ReadInt32();
}
public CampaignSettings(XElement element)
{
RadiationEnabled = element.GetAttributeBool(nameof(RadiationEnabled).ToLower(), true);
MaxMissionCount = element.GetAttributeInt(nameof(MaxMissionCount).ToLower(), DefaultMaxMissionCount);
}
public void Serialize(IWriteMessage msg)
{
msg.Write(RadiationEnabled);
msg.Write(MaxMissionCount);
}
public XElement Save()
{
return new XElement(nameof(CampaignSettings), new XAttribute(nameof(RadiationEnabled).ToLower(), RadiationEnabled));
return new XElement(nameof(CampaignSettings), new XAttribute(nameof(RadiationEnabled).ToLower(), RadiationEnabled), new XAttribute(nameof(MaxMissionCount).ToLower().ToLower(), MaxMissionCount));
}
}
@@ -874,5 +882,25 @@ namespace Barotrauma
map?.Remove();
map = null;
}
public int NumberOfMissionsAtLocation(Location location)
{
return Map.CurrentLocation.SelectedMissions.Count(m => m.Locations.Contains(location));
}
public void CheckTooManyMissions(Location currentLocation, Client sender)
{
foreach (Location location in currentLocation.Connections.Select(c => c.OtherLocation(currentLocation)))
{
if (NumberOfMissionsAtLocation(location) > Settings.MaxMissionCount)
{
DebugConsole.AddWarning($"Client {sender.Name} had too many missions selected for location {location.Name}! Count was {NumberOfMissionsAtLocation(location)}. Deselecting extra missions.");
foreach (Mission mission in currentLocation.SelectedMissions.Where(m => m.Locations[1] == location).Skip(Settings.MaxMissionCount).ToList())
{
currentLocation.DeselectMission(mission);
}
}
}
}
}
}
@@ -807,22 +807,22 @@ namespace Barotrauma.Items.Components
for (int i = 0; i < 2; i++)
{
Gap doorGap = i == 0 ? Door?.LinkedGap : DockingTarget?.Door?.LinkedGap;
if (doorGap == null) continue;
if (doorGap == null) { continue; }
doorGap.DisableHullRechecks = true;
if (doorGap.linkedTo.Count >= 2) continue;
if (doorGap.linkedTo.Count >= 2) { continue; }
if (IsHorizontal)
{
if (item.WorldPosition.X < DockingTarget.item.WorldPosition.X)
{
if (!doorGap.linkedTo.Contains(hulls[0])) doorGap.linkedTo.Add(hulls[0]);
if (!doorGap.linkedTo.Contains(hulls[0])) { doorGap.linkedTo.Add(hulls[0]); }
}
else
{
if (!doorGap.linkedTo.Contains(hulls[1])) doorGap.linkedTo.Add(hulls[1]);
if (!doorGap.linkedTo.Contains(hulls[1])) { doorGap.linkedTo.Add(hulls[1]); }
}
//make sure the left hull is linked to the gap first (gap logic assumes that the first hull is the one to the left)
if (doorGap.linkedTo.Count > 1 && doorGap.linkedTo[0].Rect.X > doorGap.linkedTo[1].Rect.X)
if (doorGap.linkedTo.Count > 1 && doorGap.linkedTo[0].WorldRect.X > doorGap.linkedTo[1].WorldRect.X)
{
var temp = doorGap.linkedTo[0];
doorGap.linkedTo[0] = doorGap.linkedTo[1];
@@ -831,16 +831,16 @@ namespace Barotrauma.Items.Components
}
else
{
if (item.WorldPosition.Y < DockingTarget.item.WorldPosition.Y)
if (item.WorldPosition.Y > DockingTarget.item.WorldPosition.Y)
{
if (!doorGap.linkedTo.Contains(hulls[0])) doorGap.linkedTo.Add(hulls[0]);
if (!doorGap.linkedTo.Contains(hulls[0])) { doorGap.linkedTo.Add(hulls[0]); }
}
else
{
if (!doorGap.linkedTo.Contains(hulls[1])) doorGap.linkedTo.Add(hulls[1]);
if (!doorGap.linkedTo.Contains(hulls[1])) { doorGap.linkedTo.Add(hulls[1]); }
}
//make sure the upper hull is linked to the gap first (gap logic assumes that the first hull is above the second one)
if (doorGap.linkedTo.Count > 1 && doorGap.linkedTo[0].Rect.Y < doorGap.linkedTo[1].Rect.Y)
if (doorGap.linkedTo.Count > 1 && doorGap.linkedTo[0].WorldRect.Y < doorGap.linkedTo[1].WorldRect.Y)
{
var temp = doorGap.linkedTo[0];
doorGap.linkedTo[0] = doorGap.linkedTo[1];
@@ -172,14 +172,23 @@ namespace Barotrauma.Items.Components
float scaledDamageRange = propellerDamage.DamageRange * item.Scale;
Vector2 propellerWorldPos = item.WorldPosition + PropellerPos * item.Scale;
Vector2 propellerWorldPos = item.WorldPosition + PropellerPos * item.Scale;
float broadRange = Math.Max(scaledDamageRange * 2, 500);
foreach (Character character in Character.CharacterList)
{
if (!character.Enabled || character.Removed) { continue; }
float distSqr = Vector2.DistanceSquared(character.WorldPosition, propellerWorldPos);
if (distSqr > scaledDamageRange * scaledDamageRange) { continue; }
character.LastDamageSource = item;
propellerDamage.DoDamage(null, character, propellerWorldPos, 1.0f, true);
if (Math.Abs(character.WorldPosition.X - propellerWorldPos.X) > broadRange) { continue; }
if (Math.Abs(character.WorldPosition.Y - propellerWorldPos.Y) > broadRange) { continue; }
foreach (Limb limb in character.AnimController.Limbs)
{
if (limb.IsSevered || !limb.body.Enabled) { continue; }
float distSqr = Vector2.DistanceSquared(limb.WorldPosition, propellerWorldPos);
if (distSqr > scaledDamageRange * scaledDamageRange) { continue; }
character.LastDamageSource = item;
propellerDamage.DoDamage(null, character, propellerWorldPos, 1.0f, true);
break;
}
}
}
@@ -72,6 +72,8 @@ namespace Barotrauma.Items.Components
}
}
public Character Attacker { get; set; }
public IEnumerable<Body> Hits
{
get { return hits; }
@@ -723,7 +725,7 @@ namespace Barotrauma.Items.Components
if (limb.IsSevered || limb.character == null || limb.character.Removed) { return false; }
limb.character.LastDamageSource = item;
if (Attack != null) { attackResult = Attack.DoDamageToLimb(User, limb, item.WorldPosition, 1.0f); }
if (Attack != null) { attackResult = Attack.DoDamageToLimb(User ?? Attacker, limb, item.WorldPosition, 1.0f); }
if (limb.character != null) { character = limb.character; }
}
else if (target.Body.UserData is Item targetItem)
@@ -731,18 +733,18 @@ namespace Barotrauma.Items.Components
if (targetItem.Removed) { return false; }
if (Attack != null && targetItem.Prefab.DamagedByProjectiles && targetItem.Condition > 0)
{
attackResult = Attack.DoDamage(User, targetItem, item.WorldPosition, 1.0f);
attackResult = Attack.DoDamage(User ?? Attacker, targetItem, item.WorldPosition, 1.0f);
}
}
else if (target.Body.UserData is IDamageable damageable)
{
if (Attack != null) { attackResult = Attack.DoDamage(User, damageable, item.WorldPosition, 1.0f); }
if (Attack != null) { attackResult = Attack.DoDamage(User ?? Attacker, damageable, item.WorldPosition, 1.0f); }
}
else if (target.Body.UserData is VoronoiCell voronoiCell && voronoiCell.IsDestructible && Attack != null && Math.Abs(Attack.LevelWallDamage) > 0.0f)
{
if (Level.Loaded?.ExtraWalls.Find(w => w.Body == target.Body) is DestructibleLevelWall destructibleWall)
{
attackResult = Attack.DoDamage(User, destructibleWall, item.WorldPosition, 1.0f);
attackResult = Attack.DoDamage(User ?? Attacker, destructibleWall, item.WorldPosition, 1.0f);
}
}
@@ -696,6 +696,7 @@ namespace Barotrauma.Items.Components
Projectile projectileComponent = projectile.GetComponent<Projectile>();
if (projectileComponent != null)
{
projectileComponent.Attacker = user;
projectileComponent.Use();
projectile.GetComponent<Rope>()?.Attach(item, projectile);
projectileComponent.User = user;
@@ -691,6 +691,29 @@ namespace Barotrauma
get { return Prefab.Linkable; }
}
/// <summary>
/// Can be used to move the item from XML (e.g. to correct the positions of items whose sprite origin has been changed)
/// </summary>
public float PositionX
{
get { return Position.X; }
private set
{
Move(new Vector2((value - Position.X) * Scale, 0.0f));
}
}
/// <summary>
/// Can be used to move the item from XML (e.g. to correct the positions of items whose sprite origin has been changed)
/// </summary>
public float PositionY
{
get { return Position.Y; }
private set
{
Move(new Vector2(0.0f, (value - Position.Y) * Scale));
}
}
public BallastFloraBranch Infector { get; set; }
public ItemPrefab PendingItemSwap { get; set; }
@@ -516,7 +516,7 @@ namespace Barotrauma
[Serialize(null, false)]
public string EquipConfirmationText { get; set; }
[Serialize(true, false, description: "Can the item be rotated in the sprite editor.")]
[Serialize(true, false, description: "Can the item be rotated in the submarine editor.")]
public bool AllowRotatingInEditor { get; set; }
[Serialize(false, false)]
@@ -94,7 +94,7 @@ namespace Barotrauma
public FireSource(Vector2 worldPosition, Hull spawningHull = null, bool isNetworkMessage = false)
{
hull = Hull.FindHull(worldPosition, spawningHull);
if (hull == null || worldPosition.Y < hull.WorldSurface) return;
if (hull == null || worldPosition.Y < hull.WorldSurface) { return; }
#if CLIENT
if (!isNetworkMessage && GameMain.Client != null) { return; }
@@ -574,6 +574,9 @@ namespace Barotrauma
Pressure = rect.Y - rect.Height + waterVolume / rect.Width;
BallastFlora?.OnMapLoaded();
#if CLIENT
lastAmbientLightEditTime = 0.0;
#endif
}
public void AddToGrid(Submarine submarine)
@@ -683,6 +686,11 @@ namespace Barotrauma
public void AddFireSource(FireSource fireSource)
{
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient)
{
//clients aren't allowed to create fire sources in hulls whose IDs have been freed (dynamic hulls between docking ports), because they can't be synced
if (IdFreed) { return; }
}
if (fireSource is DummyFireSource dummyFire)
{
FakeFireSources.Add(dummyFire);
@@ -892,6 +892,8 @@ namespace Barotrauma.Networking
get;
set;
}
// we do not serialize this value because it relies on a default setting
public int MaxMissionCount { get; set; } = CampaignSettings.DefaultMaxMissionCount;
public void SetPassword(string password)
{
@@ -53,7 +53,41 @@ namespace Barotrauma
return GameMain.Server.ServerSettings.RadiationEnabled;
#endif
}
public void SetMaxMissionCount(int maxMissionCount)
{
#if SERVER
if (GameMain.Server != null)
{
if (maxMissionCount < CampaignSettings.MinMissionCountLimit) maxMissionCount = CampaignSettings.MaxMissionCountLimit;
if (maxMissionCount > CampaignSettings.MaxMissionCountLimit) maxMissionCount = CampaignSettings.MinMissionCountLimit;
GameMain.Server.ServerSettings.MaxMissionCount = maxMissionCount;
lastUpdateID++;
}
#endif
#if CLIENT
(maxMissionCountText as GUITextBlock).Text = maxMissionCount.ToString();
#endif
}
public int GetMaxMissionCount()
{
#if CLIENT
// this seems rather silly, but it matches the radiation enabled check structurally. is this right?
if (maxMissionCountText != null && Int32.TryParse(maxMissionCountText.Text, out int result))
{
return result;
}
else
{
return 0;
}
#elif SERVER
return GameMain.Server.ServerSettings.MaxMissionCount;
#endif
}
public void ToggleTraitorsEnabled(int dir)
{
#if SERVER
@@ -790,7 +790,7 @@ namespace Barotrauma
}
}
void FixValue(SerializableProperty property, object parentObject, XAttribute attribute)
static void FixValue(SerializableProperty property, object parentObject, XAttribute attribute)
{
if (attribute.Value.Length > 0 && attribute.Value[0] == '*')
{
@@ -813,6 +813,29 @@ namespace Barotrauma
property.TrySetValue(parentObject, ((Point)property.GetValue(parentObject)).Multiply(multiplier));
}
}
else if (attribute.Value.Length > 0 && attribute.Value[0] == '+')
{
if (property.PropertyType == typeof(int))
{
float.TryParse(attribute.Value.Substring(1), NumberStyles.Float, CultureInfo.InvariantCulture, out float addition);
property.TrySetValue(parentObject, (int)(((int)property.GetValue(parentObject)) + addition));
}
else if (property.PropertyType == typeof(float))
{
float.TryParse(attribute.Value.Substring(1), NumberStyles.Float, CultureInfo.InvariantCulture, out float addition);
property.TrySetValue(parentObject, (float)property.GetValue(parentObject) + addition);
}
else if (property.PropertyType == typeof(Vector2))
{
var addition = XMLExtensions.ParseVector2(attribute.Value.Substring(1));
property.TrySetValue(parentObject, (Vector2)property.GetValue(parentObject) + addition);
}
else if (property.PropertyType == typeof(Point))
{
var addition = XMLExtensions.ParsePoint(attribute.Value.Substring(1));
property.TrySetValue(parentObject, ((Point)property.GetValue(parentObject)) + addition);
}
}
else
{
property.TrySetValue(parentObject, attribute.Value);
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+31
View File
@@ -1,3 +1,34 @@
---------------------------------------------------------------------------------------------------------
v0.14.4.0 (unstable)
---------------------------------------------------------------------------------------------------------
Changes:
- Restrict the number of missions you can choose per level to 2.
- Removed Endworm's weak point in the mouth.
- Alien/physicorium shells now break the limbs again, like they used to. Reduced the damage from 1000 to 800.
- Pulse laser doesn't bypass all the damagemodifiers anymore (because it uses burndamage instead of burn). Increased the damage slightly.
Fixes:
- Fixed some incorrect room names in the beacon stations.
- Fixed propeller damage area triggering very inaccurately, particularly on shuttle engines.
- Fixed hull indicators fading in when loading a sub in the editor (they should only get hidden and fade in when editing the ambient light value).
- Fixed inability to override jobs with mods (unstable only).
- Fixed rotated levelobjects emitting particles in a wrong direction (e.g. cave vents).
- Fixed LevelTriggers staying active when the character who activated them leaves them (e.g. gas vents draining oxygen even after you've left their trigger area). Unstable only.
- Removed duplicate front piece from pirate Humpback.
- Fixed boss health bar not showing up when damaging boss monsters with the pulse laser.
- Fixed gaps sometimes getting linked incorrectly to the hulls between docking hatches, preventing water from flowing down from the lower hull in mirrored subs. Happened in mirrored Kastrull for example.
- Fixed fires in hulls between docking ports never going out client-side.
- Fixed Moloch's armor not always breaking when shot with a railgun.
- Fixed Moloch's armor breaking when shot with canister shots or chainguns.
- Fixed the armor penetration of railgun shell not working.
- Fixed a crash related to bots entering dry rooms inside alien ruins. (unstable only)
- Fixed nav terminal's, sonar monitor's and status monitor's selection rectangles being offset from the sprite in the sub editor.
- Fixed mirrored pumps emitting particles from the wrong side of the pump.
- Fixed turret icon not switching back to the previous one in the sub preview when cancelling a pending turret upgrade.
- Fixed occasional "sequence contains no elements" crash when updating pirate AI.
- Fixed occasional "index out of range" console errors when a client receives an update about the pirates' AI state.
---------------------------------------------------------------------------------------------------------
v0.1400.3.0 (unstable)
---------------------------------------------------------------------------------------------------------