This commit is contained in:
+2
-2
@@ -186,8 +186,8 @@ namespace Barotrauma
|
||||
{
|
||||
if (character.SelectedItem != Item)
|
||||
{
|
||||
if (Item.TryInteract(character, ignoreRequiredItems: true, forceSelectKey: true) ||
|
||||
Item.TryInteract(character, ignoreRequiredItems: true, forceUseKey: true))
|
||||
if (Item.TryInteract(character, ignoreRequiredItems: true, forceUseKey: true) ||
|
||||
Item.TryInteract(character, ignoreRequiredItems: true, forceSelectKey: true))
|
||||
{
|
||||
character.SelectedItem = Item;
|
||||
}
|
||||
|
||||
@@ -1345,7 +1345,7 @@ namespace Barotrauma
|
||||
bool limbsValid = true;
|
||||
foreach (Limb limb in limbs)
|
||||
{
|
||||
if (limb.body == null || !limb.body.Enabled) { continue; }
|
||||
if (limb?.body == null || !limb.body.Enabled) { continue; }
|
||||
if (!CheckValidity(limb.body))
|
||||
{
|
||||
limbsValid = false;
|
||||
@@ -1967,7 +1967,7 @@ namespace Barotrauma
|
||||
{
|
||||
foreach (Limb l in Limbs)
|
||||
{
|
||||
l.Remove();
|
||||
l?.Remove();
|
||||
}
|
||||
limbs = null;
|
||||
}
|
||||
@@ -1976,7 +1976,7 @@ namespace Barotrauma
|
||||
{
|
||||
foreach (PhysicsBody b in collider)
|
||||
{
|
||||
b.Remove();
|
||||
b?.Remove();
|
||||
}
|
||||
collider = null;
|
||||
}
|
||||
@@ -1985,7 +1985,7 @@ namespace Barotrauma
|
||||
{
|
||||
foreach (var joint in LimbJoints)
|
||||
{
|
||||
var j = joint.Joint;
|
||||
var j = joint?.Joint;
|
||||
if (GameMain.World.JointList.Contains(j))
|
||||
{
|
||||
GameMain.World.Remove(j);
|
||||
|
||||
@@ -2728,6 +2728,11 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
bool selectInputSameAsDeselect = false;
|
||||
#if CLIENT
|
||||
selectInputSameAsDeselect = GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Select] == GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Deselect];
|
||||
#endif
|
||||
|
||||
if (SelectedCharacter != null && (IsKeyHit(InputType.Grab) || IsKeyHit(InputType.Health))) //Let people use ladders and buttons and stuff when dragging chars
|
||||
{
|
||||
DeselectCharacter();
|
||||
@@ -2767,14 +2772,16 @@ namespace Barotrauma
|
||||
{
|
||||
FocusedCharacter.onCustomInteract(FocusedCharacter, this);
|
||||
}
|
||||
else if (IsKeyHit(InputType.Deselect) && SelectedItem != null)
|
||||
else if (IsKeyHit(InputType.Deselect) && SelectedItem != null &&
|
||||
(focusedItem == null || focusedItem == SelectedItem || !selectInputSameAsDeselect))
|
||||
{
|
||||
SelectedItem = null;
|
||||
#if CLIENT
|
||||
CharacterHealth.OpenHealthWindow = null;
|
||||
#endif
|
||||
}
|
||||
else if (IsKeyHit(InputType.Deselect) && SelectedSecondaryItem != null)
|
||||
else if (IsKeyHit(InputType.Deselect) && SelectedSecondaryItem != null && SelectedSecondaryItem.GetComponent<Ladder>() == null &&
|
||||
(focusedItem == null || focusedItem == SelectedSecondaryItem || !selectInputSameAsDeselect))
|
||||
{
|
||||
SelectedSecondaryItem = null;
|
||||
#if CLIENT
|
||||
@@ -2789,6 +2796,10 @@ namespace Barotrauma
|
||||
{
|
||||
#if CLIENT
|
||||
if (CharacterInventory.DraggingItemToWorld) { return; }
|
||||
if (selectInputSameAsDeselect)
|
||||
{
|
||||
keys[(int)InputType.Deselect].Reset();
|
||||
}
|
||||
#endif
|
||||
bool canInteract = focusedItem.TryInteract(this);
|
||||
#if CLIENT
|
||||
|
||||
@@ -543,7 +543,7 @@ namespace Barotrauma
|
||||
|
||||
private void GetName(Rand.RandSync randSync, out string name)
|
||||
{
|
||||
var nameElement = CharacterConfigElement.GetChildElement("names") ?? CharacterConfigElement.GetChildElement("name");
|
||||
ContentXElement nameElement = CharacterConfigElement.GetChildElement("names") ?? CharacterConfigElement.GetChildElement("name");
|
||||
ContentPath namesXmlFile = nameElement?.GetAttributeContentPath("path") ?? ContentPath.Empty;
|
||||
XElement namesXml = null;
|
||||
if (!namesXmlFile.IsNullOrEmpty()) //names.xml is defined
|
||||
@@ -554,8 +554,8 @@ namespace Barotrauma
|
||||
else //the legacy firstnames.txt/lastnames.txt shit is defined
|
||||
{
|
||||
namesXml = new XElement("names", new XAttribute("format", "[firstname] [lastname]"));
|
||||
var firstNamesPath = ReplaceVars(nameElement.GetAttributeContentPath("firstname")?.Value ?? "");
|
||||
var lastNamesPath = ReplaceVars(nameElement.GetAttributeContentPath("lastname")?.Value ?? "");
|
||||
string firstNamesPath = nameElement == null ? string.Empty : ReplaceVars(nameElement.GetAttributeContentPath("firstname")?.Value ?? "");
|
||||
string lastNamesPath = nameElement == null ? string.Empty : ReplaceVars(nameElement.GetAttributeContentPath("lastname")?.Value ?? "");
|
||||
if (File.Exists(firstNamesPath) && File.Exists(lastNamesPath))
|
||||
{
|
||||
var firstNames = File.ReadAllLines(firstNamesPath);
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
{
|
||||
var affliction = character.CharacterHealth.GetAffliction(afflictionIdentifier);
|
||||
if (affliction == null) { return false; }
|
||||
return minimumPercentage <= affliction.Strength / affliction.Prefab.MaxStrength;
|
||||
return affliction.Strength >= affliction.Prefab.ActivationThreshold && minimumPercentage <= affliction.Strength / affliction.Prefab.MaxStrength;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
+6
-4
@@ -13,21 +13,23 @@ namespace Barotrauma.Abilities
|
||||
|
||||
protected override void ApplyEffect()
|
||||
{
|
||||
if (!SelectedItemHasTag(Character)) { return; }
|
||||
if (!SelectedItemHasTag(Character, tag)) { return; }
|
||||
|
||||
Character closestCharacter = null;
|
||||
float closestDistance = squaredMaxDistance;
|
||||
|
||||
foreach (Character crewCharacter in Character.GetFriendlyCrew(Character))
|
||||
{
|
||||
if (crewCharacter != Character && Vector2.DistanceSquared(Character.SimPosition, Character.GetRelativeSimPosition(crewCharacter)) is float tempDistance && tempDistance < closestDistance)
|
||||
if (crewCharacter != Character &&
|
||||
Vector2.DistanceSquared(Character.WorldPosition, crewCharacter.WorldPosition) is float tempDistance && tempDistance < closestDistance &&
|
||||
SelectedItemHasTag(crewCharacter, tag))
|
||||
{
|
||||
closestCharacter = crewCharacter;
|
||||
closestDistance = tempDistance;
|
||||
}
|
||||
}
|
||||
|
||||
if (closestCharacter == null || !SelectedItemHasTag(closestCharacter)) { return; }
|
||||
if (closestCharacter == null) { return; }
|
||||
|
||||
if (closestDistance < squaredMaxDistance)
|
||||
{
|
||||
@@ -35,7 +37,7 @@ namespace Barotrauma.Abilities
|
||||
ApplyEffectSpecific(closestCharacter);
|
||||
}
|
||||
|
||||
bool SelectedItemHasTag(Character character) =>
|
||||
static bool SelectedItemHasTag(Character character, string tag) =>
|
||||
(character.SelectedItem != null && character.SelectedItem.HasTag(tag)) ||
|
||||
(character.SelectedSecondaryItem != null && character.SelectedSecondaryItem.HasTag(tag));
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace Barotrauma
|
||||
{
|
||||
Option<ContentPackageId> ugcId = ContentPackageId.Parse(otherModName.Value);
|
||||
ContentPackage? otherMod =
|
||||
allPackages.FirstOrDefault(p => ugcId == p.UgcId)
|
||||
allPackages.FirstOrDefault(p => ugcId.IsSome() && ugcId == p.UgcId)
|
||||
?? allPackages.FirstOrDefault(p => p.Name == otherModName)
|
||||
?? allPackages.FirstOrDefault(p => p.NameMatches(otherModName))
|
||||
?? throw new MissingContentPackageException(ContentPackage, otherModName.Value);
|
||||
|
||||
@@ -1335,7 +1335,7 @@ namespace Barotrauma
|
||||
if (!prefab.UpgradeCategories.Contains(category)) { continue; }
|
||||
if (!string.IsNullOrWhiteSpace(prefabIdentifier) && prefab.Identifier != prefabIdentifier) { continue; }
|
||||
|
||||
int targetLevel = prefab.MaxLevel - upgradeManager.GetRealUpgradeLevel(prefab, category);
|
||||
int targetLevel = prefab.GetMaxLevelForCurrentSub() - upgradeManager.GetRealUpgradeLevel(prefab, category);
|
||||
for (int i = 0; i < targetLevel; i++)
|
||||
{
|
||||
upgradeManager.PurchaseUpgrade(prefab, category, force: true);
|
||||
|
||||
@@ -139,7 +139,7 @@ namespace Barotrauma
|
||||
humanPrefab.GiveItems(newCharacter, newCharacter.Submarine);
|
||||
if (LootingIsStealing)
|
||||
{
|
||||
foreach (Item item in newCharacter.Inventory.AllItems)
|
||||
foreach (Item item in newCharacter.Inventory.FindAllItems(recursive: true))
|
||||
{
|
||||
item.SpawnedInCurrentOutpost = true;
|
||||
item.AllowStealing = false;
|
||||
|
||||
@@ -273,13 +273,13 @@ namespace Barotrauma
|
||||
IsCampaignSet = element.GetAttributeBool("campaign", LevelType == LevelData.LevelType.Outpost || (parentSet?.IsCampaignSet ?? false));
|
||||
ResetTime = element.GetAttributeFloat("resettime", 0);
|
||||
|
||||
DefaultCommonness = 1.0f;
|
||||
DefaultCommonness = element.GetAttributeFloat("commonness", 1.0f);
|
||||
foreach (var subElement in element.Elements())
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||
{
|
||||
case "commonness":
|
||||
DefaultCommonness = subElement.GetAttributeFloat("commonness", 0.0f);
|
||||
DefaultCommonness = subElement.GetAttributeFloat("commonness", DefaultCommonness);
|
||||
foreach (XElement overrideElement in subElement.Elements())
|
||||
{
|
||||
if (overrideElement.NameAsIdentifier() == "override")
|
||||
|
||||
@@ -156,7 +156,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (!(e.ChangedData.BalanceChanged is Some<int> { Value: var changed })) { return; }
|
||||
|
||||
if (changed != 0) { return; }
|
||||
if (changed == 0) { return; }
|
||||
|
||||
bool isGain = changed > 0;
|
||||
Color clr = isGain ? GUIStyle.Yellow : GUIStyle.Red;
|
||||
|
||||
@@ -177,12 +177,13 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
|
||||
int price = prefab.Price.GetBuyprice(GetUpgradeLevel(prefab, category), Campaign.Map?.CurrentLocation);
|
||||
int price = prefab.Price.GetBuyPrice(GetUpgradeLevel(prefab, category), Campaign.Map?.CurrentLocation);
|
||||
int currentLevel = GetUpgradeLevel(prefab, category);
|
||||
|
||||
if (currentLevel + 1 > prefab.MaxLevel)
|
||||
int maxLevel = prefab.GetMaxLevelForCurrentSub();
|
||||
if (currentLevel + 1 > maxLevel)
|
||||
{
|
||||
DebugConsole.ThrowError($"Tried to purchase \"{prefab.Name}\" over the max level! ({currentLevel + 1} > {prefab.MaxLevel}). The transaction has been cancelled.");
|
||||
DebugConsole.ThrowError($"Tried to purchase \"{prefab.Name}\" over the max level! ({currentLevel + 1} > {maxLevel}). The transaction has been cancelled.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -472,7 +473,7 @@ namespace Barotrauma
|
||||
{
|
||||
int newLevel = BuyUpgrade(prefab, category, Submarine.MainSub, level);
|
||||
DebugConsole.Log($" - {category.Identifier}.{prefab.Identifier} lvl. {level}, new: ({newLevel})");
|
||||
SetUpgradeLevel(prefab, category, Math.Clamp(GetRealUpgradeLevel(prefab, category) + level, 0, prefab.MaxLevel));
|
||||
SetUpgradeLevel(prefab, category, GetRealUpgradeLevel(prefab, category) + level);
|
||||
}
|
||||
|
||||
PendingUpgrades.Clear();
|
||||
@@ -652,16 +653,13 @@ namespace Barotrauma
|
||||
|
||||
/// <summary>
|
||||
/// Gets the progress that is shown on the store interface.
|
||||
/// Includes values stored in the metadata and <see cref="PendingUpgrades"/>
|
||||
/// Includes values stored in the metadata and <see cref="PendingUpgrades"/>, and takes submarine tier and class restrictions into account
|
||||
/// </summary>
|
||||
/// <param name="prefab"></param>
|
||||
/// <param name="category"></param>
|
||||
/// <returns></returns>
|
||||
public int GetUpgradeLevel(UpgradePrefab prefab, UpgradeCategory category)
|
||||
{
|
||||
if (!Metadata.HasKey(FormatIdentifier(prefab, category))) { return GetPendingLevel(); }
|
||||
|
||||
return GetRealUpgradeLevel(prefab, category) + GetPendingLevel();
|
||||
return Math.Min(GetRealUpgradeLevel(prefab, category) + GetPendingLevel(), prefab.GetMaxLevelForCurrentSub());
|
||||
|
||||
int GetPendingLevel()
|
||||
{
|
||||
@@ -671,11 +669,8 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the level of the upgrade that is stored in the metadata.
|
||||
/// Gets the level of the upgrade that is stored in the metadata. May be higher than the apparent level on the current sub if the player has switched to a lower-tier sub
|
||||
/// </summary>
|
||||
/// <param name="prefab"></param>
|
||||
/// <param name="category"></param>
|
||||
/// <returns></returns>
|
||||
public int GetRealUpgradeLevel(UpgradePrefab prefab, UpgradeCategory category)
|
||||
{
|
||||
return !Metadata.HasKey(FormatIdentifier(prefab, category)) ? 0 : Metadata.GetInt(FormatIdentifier(prefab, category), 0);
|
||||
@@ -684,9 +679,6 @@ namespace Barotrauma
|
||||
/// <summary>
|
||||
/// Stores the target upgrade level in the campaign metadata.
|
||||
/// </summary>
|
||||
/// <param name="prefab"></param>
|
||||
/// <param name="category"></param>
|
||||
/// <param name="level"></param>
|
||||
private void SetUpgradeLevel(UpgradePrefab prefab, UpgradeCategory category, int level)
|
||||
{
|
||||
Metadata.SetValue(FormatIdentifier(prefab, category), level);
|
||||
|
||||
@@ -1164,11 +1164,14 @@ namespace Barotrauma.Items.Components
|
||||
public override void ReceiveSignal(Signal signal, Connection connection)
|
||||
{
|
||||
#if CLIENT
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient &&
|
||||
!(GameMain.GameSession?.Campaign?.AllowedToManageCampaign(ClientPermissions.ManageMap) ?? false))
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (GameMain.GameSession?.Campaign != null && !CampaignMode.AllowedToManageCampaign(ClientPermissions.ManageMap))
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (dockingCooldown > 0.0f) { return; }
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
const float MaxAttachDistance = 150.0f;
|
||||
private const float MaxAttachDistance = ItemPrefab.DefaultInteractDistance * 0.95f;
|
||||
|
||||
//the position(s) in the item that the Character grabs
|
||||
protected Vector2[] handlePos;
|
||||
@@ -731,10 +731,24 @@ namespace Barotrauma.Items.Components
|
||||
mouseDiff = mouseDiff.ClampLength(MaxAttachDistance);
|
||||
|
||||
Vector2 userPos = useWorldCoordinates ? user.WorldPosition : user.Position;
|
||||
|
||||
Vector2 attachPos = userPos + mouseDiff;
|
||||
|
||||
if (user.Submarine == null && Level.Loaded != null)
|
||||
if (user.Submarine != null)
|
||||
{
|
||||
if (Submarine.PickBody(
|
||||
ConvertUnits.ToSimUnits(user.Position),
|
||||
ConvertUnits.ToSimUnits(user.Position + mouseDiff), collisionCategory: Physics.CollisionWall) != null)
|
||||
{
|
||||
attachPos = userPos + mouseDiff * Submarine.LastPickedFraction;
|
||||
|
||||
//round down if we're placing on the right side and vice versa: ensures we don't round the position inside a wall
|
||||
return
|
||||
new Vector2(
|
||||
mouseDiff.X > 0 ? (float)Math.Floor(attachPos.X / Submarine.GridSize.X) * Submarine.GridSize.X : (float)Math.Ceiling(attachPos.X / Submarine.GridSize.X) * Submarine.GridSize.X,
|
||||
mouseDiff.Y > 0 ? (float)Math.Floor(attachPos.Y / Submarine.GridSize.Y) * Submarine.GridSize.X : (float)Math.Ceiling(attachPos.Y / Submarine.GridSize.Y) * Submarine.GridSize.Y);
|
||||
}
|
||||
}
|
||||
else if (Level.Loaded != null)
|
||||
{
|
||||
bool edgeFound = false;
|
||||
foreach (var cell in Level.Loaded.GetCells(attachPos))
|
||||
|
||||
@@ -112,7 +112,7 @@ namespace Barotrauma.Items.Components
|
||||
reloadTimer = reload;
|
||||
reloadTimer /= 1f + character.GetStatValue(StatTypes.MeleeAttackSpeed);
|
||||
reloadTimer /= 1f + item.GetQualityModifier(Quality.StatType.StrikingSpeedMultiplier);
|
||||
character.AnimController.LockFlippingUntil = (float)Timing.TotalTime + reloadTimer;
|
||||
character.AnimController.LockFlippingUntil = (float)Timing.TotalTime + reloadTimer * 0.9f;
|
||||
|
||||
item.body.FarseerBody.CollisionCategories = Physics.CollisionProjectile;
|
||||
item.body.FarseerBody.CollidesWith = Physics.CollisionCharacter | Physics.CollisionWall | Physics.CollisionItemBlocking;
|
||||
|
||||
@@ -514,7 +514,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer)
|
||||
{
|
||||
if (Rand.Range(0.0f, 1.0f) < FireProbability * deltaTime)
|
||||
if (Rand.Range(0.0f, 1.0f) < FireProbability * deltaTime && item.CurrentHull != null)
|
||||
{
|
||||
Vector2 displayPos = ConvertUnits.ToDisplayUnits(rayStart + (rayEnd - rayStart) * lastPickedFraction * 0.9f);
|
||||
if (item.CurrentHull.Submarine != null) { displayPos += item.CurrentHull.Submarine.Position; }
|
||||
|
||||
@@ -284,9 +284,10 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
Entity.Spawner.AddItemToSpawnQueue(itemPrefab, outputContainer.Inventory, condition, onSpawned: (Item spawnedItem) =>
|
||||
{
|
||||
spawnedItem.SpawnedInCurrentOutpost = item.SpawnedInCurrentOutpost;
|
||||
spawnedItem.StolenDuringRound = targetItem.StolenDuringRound;
|
||||
spawnedItem.AllowStealing = targetItem.AllowStealing;
|
||||
spawnedItem.OriginalOutpost = targetItem.OriginalOutpost;
|
||||
spawnedItem.SpawnedInCurrentOutpost = targetItem.SpawnedInCurrentOutpost;
|
||||
for (int i = 0; i < outputContainer.Capacity; i++)
|
||||
{
|
||||
var containedItem = outputContainer.Inventory.GetItemAt(i);
|
||||
|
||||
@@ -83,8 +83,16 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (lastUser == value) { return; }
|
||||
lastUser = value;
|
||||
degreeOfSuccess = lastUser == null ? 0.0f : Math.Min(DegreeOfSuccess(lastUser), 1.0f);
|
||||
LastUserWasPlayer = lastUser.IsPlayer;
|
||||
if (lastUser == null)
|
||||
{
|
||||
degreeOfSuccess = 0.0f;
|
||||
LastUserWasPlayer = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
degreeOfSuccess = Math.Min(DegreeOfSuccess(lastUser), 1.0f);
|
||||
LastUserWasPlayer = lastUser.IsPlayer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -390,6 +390,8 @@ namespace Barotrauma
|
||||
{
|
||||
public static readonly PrefabCollection<ItemPrefab> Prefabs = new PrefabCollection<ItemPrefab>();
|
||||
|
||||
public const float DefaultInteractDistance = 120.0f;
|
||||
|
||||
//default size
|
||||
public Vector2 Size { get; private set; }
|
||||
|
||||
@@ -590,7 +592,7 @@ namespace Barotrauma
|
||||
public override ImmutableHashSet<string> Aliases => aliases;
|
||||
|
||||
//how close the Character has to be to the item to pick it up
|
||||
[Serialize(120.0f, IsPropertySaveable.No)]
|
||||
[Serialize(DefaultInteractDistance, IsPropertySaveable.No)]
|
||||
public float InteractDistance { get; private set; }
|
||||
|
||||
// this can be used to allow items which are behind other items tp
|
||||
|
||||
@@ -3015,6 +3015,7 @@ namespace Barotrauma
|
||||
var selectedLocation = allValidLocations.FirstOrDefault(l =>
|
||||
Vector2.Distance(l.Edge.Point1, l.Edge.Point2) is float edgeLength &&
|
||||
!l.Edge.OutsideLevel &&
|
||||
((l.Edge.Cell1?.IsDestructible ?? false) || (l.Edge.Cell2?.IsDestructible ?? false)) &&
|
||||
requiredAmount <= (int)Math.Floor(edgeLength / ((1.0f - maxResourceOverlap) * prefab.Size.X)));
|
||||
|
||||
|
||||
@@ -3905,7 +3906,7 @@ namespace Barotrauma
|
||||
|
||||
private bool HasEndOutpost()
|
||||
{
|
||||
if (preSelectedStartOutpost != null) { return true; }
|
||||
if (preSelectedEndOutpost != null) { return true; }
|
||||
//don't create an end outpost for locations
|
||||
if (LevelData.Type == LevelData.LevelType.Outpost) { return false; }
|
||||
if (EndLocation != null && !EndLocation.Type.HasOutpost) { return false; }
|
||||
|
||||
@@ -906,11 +906,17 @@ namespace Barotrauma
|
||||
|
||||
public LocationType GetLocationType()
|
||||
{
|
||||
if (IsCriticallyRadiated() && LocationType.Prefabs[Type.ReplaceInRadiation] is { } newLocationType)
|
||||
if (IsCriticallyRadiated() && !Type.ReplaceInRadiation.IsEmpty)
|
||||
{
|
||||
return newLocationType;
|
||||
if (LocationType.Prefabs.TryGet(Type.ReplaceInRadiation, out LocationType newLocationType))
|
||||
{
|
||||
return newLocationType;
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.ThrowError($"Error when trying to get a new location type for an irradiated location - location type \"{newLocationType}\" not found.");
|
||||
}
|
||||
}
|
||||
|
||||
return Type;
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace Barotrauma
|
||||
private set;
|
||||
}
|
||||
|
||||
public string ReplaceInRadiation { get; }
|
||||
public Identifier ReplaceInRadiation { get; }
|
||||
|
||||
public Sprite Sprite { get; private set; }
|
||||
public Sprite RadiationSprite { get; }
|
||||
@@ -108,7 +108,7 @@ namespace Barotrauma
|
||||
|
||||
HideEntitySubcategories = element.GetAttributeStringArray("hideentitysubcategories", Array.Empty<string>()).ToList();
|
||||
|
||||
ReplaceInRadiation = element.GetAttributeString(nameof(ReplaceInRadiation).ToLower(), "");
|
||||
ReplaceInRadiation = element.GetAttributeIdentifier(nameof(ReplaceInRadiation), Identifier.Empty);
|
||||
|
||||
string teamStr = element.GetAttributeString("outpostteam", "FriendlyNPC");
|
||||
Enum.TryParse(teamStr, out OutpostTeam);
|
||||
|
||||
@@ -560,6 +560,42 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
//make sure the location at the right side of the gate between biomes isn't a dead-end
|
||||
//those may sometimes generate if all the connections of the right-side location lead to the previous biome
|
||||
//(i.e. a situation where the adjacent locations happen to be at the left side of the border of the biomes, see see Regalis11/Barotrauma#10047)
|
||||
for (int i = 0; i < Connections.Count; i++)
|
||||
{
|
||||
var connection = Connections[i];
|
||||
if (!connection.Locked) { continue; }
|
||||
var rightMostLocation =
|
||||
connection.Locations[0].MapPosition.X > connection.Locations[1].MapPosition.X ?
|
||||
connection.Locations[0] :
|
||||
connection.Locations[1];
|
||||
|
||||
//if there's only one connection (= the connection between biomes), create a new connection to the closest location to the right
|
||||
if (rightMostLocation.Connections.Count == 1)
|
||||
{
|
||||
Location closestLocation = null;
|
||||
float closestDist = float.PositiveInfinity;
|
||||
foreach (Location otherLocation in Locations)
|
||||
{
|
||||
if (otherLocation == rightMostLocation || otherLocation.MapPosition.X < rightMostLocation.MapPosition.X) { continue; }
|
||||
float dist = Vector2.DistanceSquared(rightMostLocation.MapPosition, otherLocation.MapPosition);
|
||||
if (dist < closestDist || closestLocation == null)
|
||||
{
|
||||
closestLocation = otherLocation;
|
||||
closestDist = dist;
|
||||
}
|
||||
}
|
||||
|
||||
var newConnection = new LocationConnection(rightMostLocation, closestLocation);
|
||||
rightMostLocation.Connections.Add(newConnection);
|
||||
closestLocation.Connections.Add(newConnection);
|
||||
Connections.Add(newConnection);
|
||||
GenerateLocationConnectionVisuals(newConnection);
|
||||
}
|
||||
}
|
||||
|
||||
//remove orphans
|
||||
Locations.RemoveAll(l => !Connections.Any(c => c.Locations.Contains(l)));
|
||||
|
||||
@@ -606,7 +642,9 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
partial void GenerateLocationConnectionVisuals();
|
||||
partial void GenerateAllLocationConnectionVisuals();
|
||||
|
||||
partial void GenerateLocationConnectionVisuals(LocationConnection connection);
|
||||
|
||||
private int GetZoneIndex(float xPos)
|
||||
{
|
||||
|
||||
@@ -8,23 +8,7 @@ using Lidgren.Network;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
interface IWritableBitField
|
||||
{
|
||||
public void WriteBoolean(bool b);
|
||||
public void WriteInteger(int value, int min, int max);
|
||||
public void WriteFloat(float value, float min, float max, int numberOfBits);
|
||||
|
||||
public void WriteToMessage(IWriteMessage msg);
|
||||
}
|
||||
|
||||
interface IReadableBitField
|
||||
{
|
||||
public bool ReadBoolean();
|
||||
public int ReadInteger(int min, int max);
|
||||
public float ReadFloat(float min, float max, int numberOfBits);
|
||||
}
|
||||
|
||||
sealed class WriteOnlyBitField : IWritableBitField, IDisposable
|
||||
sealed class WriteOnlyBitField : IDisposable
|
||||
{
|
||||
private const int AmountOfBoolsInByte = 7; // Reserve last bit for end marker
|
||||
private readonly List<byte> Buffer = new List<byte>();
|
||||
@@ -100,7 +84,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
sealed class ReadOnlyBitField : IReadableBitField
|
||||
sealed class ReadOnlyBitField
|
||||
{
|
||||
private const int AmountOfBoolsInByte = 7; // Reserve last bit for end marker
|
||||
private readonly ImmutableArray<byte> buffer;
|
||||
@@ -110,17 +94,14 @@ namespace Barotrauma
|
||||
{
|
||||
List<byte> bytes = new List<byte>();
|
||||
byte currentByte;
|
||||
int reads = 0;
|
||||
do
|
||||
{
|
||||
if (inc.BitPosition >= inc.LengthBits)
|
||||
{
|
||||
throw new Exception("Failed to find the end of the bit field: end of the message reached.");
|
||||
}
|
||||
currentByte = inc.ReadByte();
|
||||
bytes.Add(currentByte);
|
||||
|
||||
reads++;
|
||||
if (reads > 100)
|
||||
{
|
||||
throw new Exception($"Failed to find the end of the bit field after 100 reads. Terminating to prevent the game from freezing.");
|
||||
}
|
||||
}
|
||||
while (!IsBitSet(currentByte, AmountOfBoolsInByte));
|
||||
|
||||
|
||||
@@ -113,6 +113,11 @@ namespace Barotrauma.Networking
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (AggregateException aggregateException)
|
||||
{
|
||||
if (aggregateException.InnerException is OperationCanceledException) { return -1; }
|
||||
throw;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
return -1;
|
||||
|
||||
@@ -61,9 +61,9 @@ namespace Barotrauma
|
||||
{
|
||||
public interface IReadWriteBehavior
|
||||
{
|
||||
public delegate object? ReadDelegate(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField);
|
||||
public delegate object? ReadDelegate(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField);
|
||||
|
||||
public delegate void WriteDelegate(object? obj, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField);
|
||||
public delegate void WriteDelegate(object? obj, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField);
|
||||
|
||||
public ReadDelegate ReadAction { get; }
|
||||
public WriteDelegate WriteAction { get; }
|
||||
@@ -71,9 +71,9 @@ namespace Barotrauma
|
||||
|
||||
public readonly struct ReadWriteBehavior<T> : IReadWriteBehavior
|
||||
{
|
||||
public delegate T ReadDelegate(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField);
|
||||
public delegate T ReadDelegate(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField);
|
||||
|
||||
public delegate void WriteDelegate(T obj, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField);
|
||||
public delegate void WriteDelegate(T obj, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField);
|
||||
|
||||
public IReadWriteBehavior.ReadDelegate ReadAction { get; }
|
||||
public IReadWriteBehavior.WriteDelegate WriteAction { get; }
|
||||
@@ -256,18 +256,18 @@ namespace Barotrauma
|
||||
ReadImmutableArray<object>,
|
||||
WriteImmutableArray<object>);
|
||||
|
||||
private static ImmutableArray<T> ReadImmutableArray<T>(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) where T : notnull
|
||||
private static ImmutableArray<T> ReadImmutableArray<T>(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) where T : notnull
|
||||
{
|
||||
return ReadArray<T>(inc, attribute, bitField).ToImmutableArray();
|
||||
}
|
||||
|
||||
private static void WriteImmutableArray<T>(ImmutableArray<T> array, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) where T : notnull
|
||||
private static void WriteImmutableArray<T>(ImmutableArray<T> array, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) where T : notnull
|
||||
{
|
||||
ToolBox.ThrowIfNull(array);
|
||||
WriteIReadOnlyCollection<T>(array, attribute, msg, bitField);
|
||||
}
|
||||
|
||||
private static T[] ReadArray<T>(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) where T : notnull
|
||||
private static T[] ReadArray<T>(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) where T : notnull
|
||||
{
|
||||
int length = bitField.ReadInteger(0, attribute.ArrayMaxSize);
|
||||
|
||||
@@ -286,13 +286,13 @@ namespace Barotrauma
|
||||
return array;
|
||||
}
|
||||
|
||||
private static void WriteArray<T>(T[] array, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) where T : notnull
|
||||
private static void WriteArray<T>(T[] array, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) where T : notnull
|
||||
{
|
||||
ToolBox.ThrowIfNull(array);
|
||||
WriteIReadOnlyCollection(array, attribute, msg, bitField);
|
||||
}
|
||||
|
||||
private static void WriteIReadOnlyCollection<T>(IReadOnlyCollection<T> array, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) where T : notnull
|
||||
private static void WriteIReadOnlyCollection<T>(IReadOnlyCollection<T> array, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) where T : notnull
|
||||
{
|
||||
bitField.WriteInteger(array.Count, 0, attribute.ArrayMaxSize);
|
||||
|
||||
@@ -307,18 +307,18 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private static T ReadINetSerializableStruct<T>(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) where T : INetSerializableStruct
|
||||
private static T ReadINetSerializableStruct<T>(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) where T : INetSerializableStruct
|
||||
{
|
||||
return INetSerializableStruct.ReadInternal<T>(inc, bitField);
|
||||
}
|
||||
|
||||
private static void WriteINetSerializableStruct<T>(T serializableStruct, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) where T : INetSerializableStruct
|
||||
private static void WriteINetSerializableStruct<T>(T serializableStruct, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) where T : INetSerializableStruct
|
||||
{
|
||||
ToolBox.ThrowIfNull(serializableStruct);
|
||||
serializableStruct.WriteInternal(msg, bitField);
|
||||
}
|
||||
|
||||
private static T ReadEnum<T>(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) where T : Enum
|
||||
private static T ReadEnum<T>(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) where T : Enum
|
||||
{
|
||||
var type = typeof(T);
|
||||
|
||||
@@ -338,7 +338,7 @@ namespace Barotrauma
|
||||
throw new InvalidOperationException($"An enum {type} with value {enumIndex} could not be found in {nameof(ReadEnum)}");
|
||||
}
|
||||
|
||||
private static void WriteEnum<T>(T value, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) where T : Enum
|
||||
private static void WriteEnum<T>(T value, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) where T : Enum
|
||||
{
|
||||
ToolBox.ThrowIfNull(value);
|
||||
|
||||
@@ -346,7 +346,7 @@ namespace Barotrauma
|
||||
bitField.WriteInteger((int)Convert.ChangeType(value, value.GetTypeCode()), range.Start, range.End);
|
||||
}
|
||||
|
||||
private static T? ReadNullable<T>(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) where T : struct =>
|
||||
private static T? ReadNullable<T>(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) where T : struct =>
|
||||
ReadOption<T>(inc, attribute, bitField) switch
|
||||
{
|
||||
Some<T> { Value: var value } => value,
|
||||
@@ -354,10 +354,10 @@ namespace Barotrauma
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
|
||||
private static void WriteNullable<T>(T? value, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) where T : struct =>
|
||||
private static void WriteNullable<T>(T? value, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) where T : struct =>
|
||||
WriteOption<T>(value.HasValue ? Option<T>.Some(value.Value) : Option<T>.None(), attribute, msg, bitField);
|
||||
|
||||
private static Option<T> ReadOption<T>(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) where T : notnull
|
||||
private static Option<T> ReadOption<T>(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) where T : notnull
|
||||
{
|
||||
bool hasValue = bitField.ReadBoolean();
|
||||
if (!hasValue)
|
||||
@@ -373,7 +373,7 @@ namespace Barotrauma
|
||||
throw new InvalidOperationException($"Could not find suitable behavior for type {typeof(T)} in {nameof(ReadOption)}");
|
||||
}
|
||||
|
||||
private static void WriteOption<T>(Option<T> option, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) where T : notnull
|
||||
private static void WriteOption<T>(Option<T> option, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) where T : notnull
|
||||
{
|
||||
ToolBox.ThrowIfNull(option);
|
||||
|
||||
@@ -391,22 +391,22 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private static bool ReadBoolean(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => bitField.ReadBoolean();
|
||||
private static void WriteBoolean(bool b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { bitField.WriteBoolean(b); }
|
||||
private static bool ReadBoolean(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) => bitField.ReadBoolean();
|
||||
private static void WriteBoolean(bool b, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) { bitField.WriteBoolean(b); }
|
||||
|
||||
private static byte ReadByte(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => inc.ReadByte();
|
||||
private static void WriteByte(byte b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.WriteByte(b); }
|
||||
private static byte ReadByte(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) => inc.ReadByte();
|
||||
private static void WriteByte(byte b, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) { msg.WriteByte(b); }
|
||||
|
||||
private static ushort ReadUInt16(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => inc.ReadUInt16();
|
||||
private static void WriteUInt16(ushort b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.WriteUInt16(b); }
|
||||
private static ushort ReadUInt16(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) => inc.ReadUInt16();
|
||||
private static void WriteUInt16(ushort b, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) { msg.WriteUInt16(b); }
|
||||
|
||||
private static short ReadInt16(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => inc.ReadInt16();
|
||||
private static void WriteInt16(short b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.WriteInt16(b); }
|
||||
private static short ReadInt16(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) => inc.ReadInt16();
|
||||
private static void WriteInt16(short b, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) { msg.WriteInt16(b); }
|
||||
|
||||
private static uint ReadUInt32(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => inc.ReadUInt32();
|
||||
private static void WriteUInt32(uint b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.WriteUInt32(b); }
|
||||
private static uint ReadUInt32(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) => inc.ReadUInt32();
|
||||
private static void WriteUInt32(uint b, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) { msg.WriteUInt32(b); }
|
||||
|
||||
private static int ReadInt32(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField)
|
||||
private static int ReadInt32(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField)
|
||||
{
|
||||
if (IsRanged(attribute.MinValueInt, attribute.MaxValueInt))
|
||||
{
|
||||
@@ -416,7 +416,7 @@ namespace Barotrauma
|
||||
return inc.ReadInt32();
|
||||
}
|
||||
|
||||
private static void WriteInt32(int i, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField)
|
||||
private static void WriteInt32(int i, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField)
|
||||
{
|
||||
ToolBox.ThrowIfNull(i);
|
||||
|
||||
@@ -429,13 +429,13 @@ namespace Barotrauma
|
||||
msg.WriteInt32(i);
|
||||
}
|
||||
|
||||
private static ulong ReadUInt64(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => inc.ReadUInt64();
|
||||
private static void WriteUInt64(ulong b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.WriteUInt64(b); }
|
||||
private static ulong ReadUInt64(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) => inc.ReadUInt64();
|
||||
private static void WriteUInt64(ulong b, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) { msg.WriteUInt64(b); }
|
||||
|
||||
private static long ReadInt64(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => inc.ReadInt64();
|
||||
private static void WriteInt64(long b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.WriteInt64(b); }
|
||||
private static long ReadInt64(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) => inc.ReadInt64();
|
||||
private static void WriteInt64(long b, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) { msg.WriteInt64(b); }
|
||||
|
||||
private static float ReadSingle(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField)
|
||||
private static float ReadSingle(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField)
|
||||
{
|
||||
if (IsRanged(attribute.MinValueFloat, attribute.MaxValueFloat))
|
||||
{
|
||||
@@ -445,7 +445,7 @@ namespace Barotrauma
|
||||
return inc.ReadSingle();
|
||||
}
|
||||
|
||||
private static void WriteSingle(float f, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField)
|
||||
private static void WriteSingle(float f, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField)
|
||||
{
|
||||
ToolBox.ThrowIfNull(f);
|
||||
|
||||
@@ -458,16 +458,16 @@ namespace Barotrauma
|
||||
msg.WriteSingle(f);
|
||||
}
|
||||
|
||||
private static double ReadDouble(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => inc.ReadDouble();
|
||||
private static void WriteDouble(double b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.WriteDouble(b); }
|
||||
private static double ReadDouble(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) => inc.ReadDouble();
|
||||
private static void WriteDouble(double b, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) { msg.WriteDouble(b); }
|
||||
|
||||
private static string ReadString(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => inc.ReadString();
|
||||
private static void WriteString(string b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.WriteString(b); }
|
||||
private static string ReadString(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) => inc.ReadString();
|
||||
private static void WriteString(string b, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) { msg.WriteString(b); }
|
||||
|
||||
private static Identifier ReadIdentifier(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => inc.ReadIdentifier();
|
||||
private static void WriteIdentifier(Identifier b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.WriteIdentifier(b); }
|
||||
private static Identifier ReadIdentifier(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) => inc.ReadIdentifier();
|
||||
private static void WriteIdentifier(Identifier b, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) { msg.WriteIdentifier(b); }
|
||||
|
||||
private static AccountId ReadAccountId(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField)
|
||||
private static AccountId ReadAccountId(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField)
|
||||
{
|
||||
string str = inc.ReadString();
|
||||
return AccountId.Parse(str).TryUnwrap(out var accountId)
|
||||
@@ -475,14 +475,14 @@ namespace Barotrauma
|
||||
: throw new InvalidCastException($"Could not parse \"{str}\" as an {nameof(AccountId)}");
|
||||
}
|
||||
|
||||
private static void WriteAccountId(AccountId accountId, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField)
|
||||
private static void WriteAccountId(AccountId accountId, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField)
|
||||
{
|
||||
msg.WriteString(accountId.StringRepresentation);
|
||||
}
|
||||
|
||||
private static Color ReadColor(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => attribute.IncludeColorAlpha ? inc.ReadColorR8G8B8A8() : inc.ReadColorR8G8B8();
|
||||
private static Color ReadColor(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) => attribute.IncludeColorAlpha ? inc.ReadColorR8G8B8A8() : inc.ReadColorR8G8B8();
|
||||
|
||||
private static void WriteColor(Color color, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField)
|
||||
private static void WriteColor(Color color, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField)
|
||||
{
|
||||
ToolBox.ThrowIfNull(color);
|
||||
|
||||
@@ -495,7 +495,7 @@ namespace Barotrauma
|
||||
msg.WriteColorR8G8B8(color);
|
||||
}
|
||||
|
||||
private static Vector2 ReadVector2(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField)
|
||||
private static Vector2 ReadVector2(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField)
|
||||
{
|
||||
float x = ReadSingle(inc, attribute, bitField);
|
||||
float y = ReadSingle(inc, attribute, bitField);
|
||||
@@ -503,7 +503,7 @@ namespace Barotrauma
|
||||
return new Vector2(x, y);
|
||||
}
|
||||
|
||||
private static void WriteVector2(Vector2 vector2, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField)
|
||||
private static void WriteVector2(Vector2 vector2, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField)
|
||||
{
|
||||
ToolBox.ThrowIfNull(vector2);
|
||||
|
||||
@@ -690,11 +690,11 @@ namespace Barotrauma
|
||||
/// <returns>A new struct of type T with fields and properties deserialized</returns>
|
||||
public static T Read<T>(IReadMessage inc) where T : INetSerializableStruct
|
||||
{
|
||||
IReadableBitField bitField = new ReadOnlyBitField(inc);
|
||||
ReadOnlyBitField bitField = new ReadOnlyBitField(inc);
|
||||
return ReadInternal<T>(inc, bitField);
|
||||
}
|
||||
|
||||
public static T ReadInternal<T>(IReadMessage inc, IReadableBitField bitField) where T : INetSerializableStruct
|
||||
public static T ReadInternal<T>(IReadMessage inc, ReadOnlyBitField bitField) where T : INetSerializableStruct
|
||||
{
|
||||
object? newObject = Activator.CreateInstance(typeof(T));
|
||||
if (newObject is null) { return default!; }
|
||||
@@ -744,14 +744,14 @@ namespace Barotrauma
|
||||
/// <param name="msg">Outgoing network message</param>
|
||||
public void Write(IWriteMessage msg)
|
||||
{
|
||||
IWritableBitField bitField = new WriteOnlyBitField();
|
||||
WriteOnlyBitField bitField = new WriteOnlyBitField();
|
||||
IWriteMessage structWriteMsg = new WriteOnlyMessage();
|
||||
WriteInternal(structWriteMsg, bitField);
|
||||
bitField.WriteToMessage(msg);
|
||||
msg.WriteBytes(structWriteMsg.Buffer, 0, structWriteMsg.LengthBytes);
|
||||
}
|
||||
|
||||
public void WriteInternal(IWriteMessage msg, IWritableBitField bitField)
|
||||
public void WriteInternal(IWriteMessage msg, WriteOnlyBitField bitField)
|
||||
{
|
||||
var properties = NetSerializableProperties.GetPropertiesAndFields(GetType());
|
||||
|
||||
|
||||
+19
@@ -40,6 +40,25 @@ namespace Barotrauma.Networking
|
||||
return Option<LidgrenAddress>.None();
|
||||
}
|
||||
|
||||
public static Option<LidgrenAddress> ParseHostName(string endpointStr)
|
||||
{
|
||||
try
|
||||
{
|
||||
var resolvedAddresses = Dns.GetHostAddresses(endpointStr);
|
||||
return resolvedAddresses.Any()
|
||||
? Option<LidgrenAddress>.Some(new LidgrenAddress(resolvedAddresses.First()))
|
||||
: Option<LidgrenAddress>.None();
|
||||
}
|
||||
catch (SocketException)
|
||||
{
|
||||
return Option<LidgrenAddress>.None();
|
||||
}
|
||||
catch (ArgumentOutOfRangeException)
|
||||
{
|
||||
return Option<LidgrenAddress>.None();
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
=> obj switch
|
||||
{
|
||||
|
||||
+7
-1
@@ -23,6 +23,11 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
public new static Option<LidgrenEndpoint> Parse(string endpointStr)
|
||||
{
|
||||
return ParseFromWithHostNameCheck(endpointStr, tryParseHostName: false);
|
||||
}
|
||||
|
||||
public static Option<LidgrenEndpoint> ParseFromWithHostNameCheck(string endpointStr, bool tryParseHostName)
|
||||
{
|
||||
string hostName = endpointStr;
|
||||
int port = NetConfig.DefaultPort;
|
||||
@@ -33,7 +38,8 @@ namespace Barotrauma.Networking
|
||||
port = int.TryParse(split[1], out var tmpPort) ? tmpPort : port;
|
||||
}
|
||||
|
||||
if (LidgrenAddress.Parse(hostName).TryUnwrap(out var adr))
|
||||
if (LidgrenAddress.Parse(hostName).TryUnwrap(out var adr) ||
|
||||
(tryParseHostName && LidgrenAddress.ParseHostName(hostName).TryUnwrap(out adr)))
|
||||
{
|
||||
return Option<LidgrenEndpoint>.Some(new LidgrenEndpoint(adr.NetAddress, port));
|
||||
}
|
||||
|
||||
@@ -37,7 +37,12 @@ namespace Barotrauma.Networking
|
||||
|
||||
internal static class MsgWriter
|
||||
{
|
||||
internal static void Write(ref byte[] buf, ref int bitPos, bool val)
|
||||
internal static void UpdateBitLength(ref int bitLength, int bitPos)
|
||||
{
|
||||
bitLength = Math.Max(bitLength, bitPos);
|
||||
}
|
||||
|
||||
internal static void WriteBoolean(ref byte[] buf, ref int bitPos, ref int bitLength, bool val)
|
||||
{
|
||||
#if DEBUG
|
||||
int resetPos = bitPos;
|
||||
@@ -52,7 +57,7 @@ namespace Barotrauma.Networking
|
||||
buf[bytePos] &= bitMask;
|
||||
if (val) buf[bytePos] |= bitFlag;
|
||||
bitPos++;
|
||||
|
||||
UpdateBitLength(ref bitLength, bitPos);
|
||||
#if DEBUG
|
||||
bool testVal = MsgReader.ReadBoolean(buf, ref resetPos);
|
||||
if (testVal != val || resetPos != bitPos)
|
||||
@@ -62,63 +67,71 @@ namespace Barotrauma.Networking
|
||||
#endif
|
||||
}
|
||||
|
||||
internal static void WritePadBits(ref byte[] buf, ref int bitPos)
|
||||
internal static void WritePadBits(ref byte[] buf, ref int bitPos, ref int bitLength)
|
||||
{
|
||||
int bitOffset = bitPos % 8;
|
||||
bitPos += ((8 - bitOffset) % 8);
|
||||
UpdateBitLength(ref bitLength, bitPos);
|
||||
EnsureBufferSize(ref buf, bitPos);
|
||||
}
|
||||
|
||||
internal static void Write(ref byte[] buf, ref int bitPos, byte val)
|
||||
internal static void WriteByte(ref byte[] buf, ref int bitPos, ref int bitLength, byte val)
|
||||
{
|
||||
EnsureBufferSize(ref buf, bitPos + 8);
|
||||
NetBitWriter.WriteByte(val, 8, buf, bitPos);
|
||||
bitPos += 8;
|
||||
UpdateBitLength(ref bitLength, bitPos);
|
||||
}
|
||||
|
||||
internal static void Write(ref byte[] buf, ref int bitPos, UInt16 val)
|
||||
internal static void WriteUInt16(ref byte[] buf, ref int bitPos, ref int bitLength, UInt16 val)
|
||||
{
|
||||
EnsureBufferSize(ref buf, bitPos + 16);
|
||||
NetBitWriter.WriteUInt16(val, 16, buf, bitPos);
|
||||
bitPos += 16;
|
||||
UpdateBitLength(ref bitLength, bitPos);
|
||||
}
|
||||
|
||||
internal static void Write(ref byte[] buf, ref int bitPos, Int16 val)
|
||||
internal static void WriteInt16(ref byte[] buf, ref int bitPos, ref int bitLength, Int16 val)
|
||||
{
|
||||
EnsureBufferSize(ref buf, bitPos + 16);
|
||||
NetBitWriter.WriteUInt16((UInt16)val, 16, buf, bitPos);
|
||||
bitPos += 16;
|
||||
UpdateBitLength(ref bitLength, bitPos);
|
||||
}
|
||||
|
||||
internal static void Write(ref byte[] buf, ref int bitPos, UInt32 val)
|
||||
internal static void WriteUInt32(ref byte[] buf, ref int bitPos, ref int bitLength, UInt32 val)
|
||||
{
|
||||
EnsureBufferSize(ref buf, bitPos + 32);
|
||||
NetBitWriter.WriteUInt32(val, 32, buf, bitPos);
|
||||
bitPos += 32;
|
||||
UpdateBitLength(ref bitLength, bitPos);
|
||||
}
|
||||
|
||||
internal static void Write(ref byte[] buf, ref int bitPos, Int32 val)
|
||||
internal static void WriteInt32(ref byte[] buf, ref int bitPos, ref int bitLength, Int32 val)
|
||||
{
|
||||
EnsureBufferSize(ref buf, bitPos + 32);
|
||||
NetBitWriter.WriteUInt32((UInt32)val, 32, buf, bitPos);
|
||||
bitPos += 32;
|
||||
UpdateBitLength(ref bitLength, bitPos);
|
||||
}
|
||||
|
||||
internal static void Write(ref byte[] buf, ref int bitPos, UInt64 val)
|
||||
internal static void WriteUInt64(ref byte[] buf, ref int bitPos, ref int bitLength, UInt64 val)
|
||||
{
|
||||
EnsureBufferSize(ref buf, bitPos + 64);
|
||||
NetBitWriter.WriteUInt64(val, 64, buf, bitPos);
|
||||
bitPos += 64;
|
||||
UpdateBitLength(ref bitLength, bitPos);
|
||||
}
|
||||
|
||||
internal static void Write(ref byte[] buf, ref int bitPos, Int64 val)
|
||||
internal static void WriteInt64(ref byte[] buf, ref int bitPos, ref int bitLength, Int64 val)
|
||||
{
|
||||
EnsureBufferSize(ref buf, bitPos + 64);
|
||||
NetBitWriter.WriteUInt64((UInt64)val, 64, buf, bitPos);
|
||||
bitPos += 64;
|
||||
UpdateBitLength(ref bitLength, bitPos);
|
||||
}
|
||||
|
||||
internal static void Write(ref byte[] buf, ref int bitPos, Single val)
|
||||
internal static void WriteSingle(ref byte[] buf, ref int bitPos, ref int bitLength, Single val)
|
||||
{
|
||||
// Use union to avoid BitConverter.GetBytes() which allocates memory on the heap
|
||||
SingleUIntUnion su;
|
||||
@@ -129,61 +142,62 @@ namespace Barotrauma.Networking
|
||||
|
||||
NetBitWriter.WriteUInt32(su.UIntValue, 32, buf, bitPos);
|
||||
bitPos += 32;
|
||||
UpdateBitLength(ref bitLength, bitPos);
|
||||
}
|
||||
|
||||
internal static void Write(ref byte[] buf, ref int bitPos, Double val)
|
||||
internal static void WriteDouble(ref byte[] buf, ref int bitPos, ref int bitLength, Double val)
|
||||
{
|
||||
EnsureBufferSize(ref buf, bitPos + 64);
|
||||
|
||||
byte[] bytes = BitConverter.GetBytes(val);
|
||||
WriteBytes(ref buf, ref bitPos, bytes, 0, 8);
|
||||
WriteBytes(ref buf, ref bitPos, ref bitLength, bytes, 0, 8);
|
||||
}
|
||||
|
||||
internal static void WriteColorR8G8B8(ref byte[] buf, ref int bitPos, Color val)
|
||||
internal static void WriteColorR8G8B8(ref byte[] buf, ref int bitPos, ref int bitLength, Color val)
|
||||
{
|
||||
EnsureBufferSize(ref buf, bitPos + 24);
|
||||
|
||||
Write(ref buf, ref bitPos, val.R);
|
||||
Write(ref buf, ref bitPos, val.G);
|
||||
Write(ref buf, ref bitPos, val.B);
|
||||
WriteByte(ref buf, ref bitPos, ref bitLength, val.R);
|
||||
WriteByte(ref buf, ref bitPos, ref bitLength, val.G);
|
||||
WriteByte(ref buf, ref bitPos, ref bitLength, val.B);
|
||||
}
|
||||
|
||||
internal static void WriteColorR8G8B8A8(ref byte[] buf, ref int bitPos, Color val)
|
||||
internal static void WriteColorR8G8B8A8(ref byte[] buf, ref int bitPos, ref int bitLength, Color val)
|
||||
{
|
||||
EnsureBufferSize(ref buf, bitPos + 32);
|
||||
|
||||
Write(ref buf, ref bitPos, val.R);
|
||||
Write(ref buf, ref bitPos, val.G);
|
||||
Write(ref buf, ref bitPos, val.B);
|
||||
Write(ref buf, ref bitPos, val.A);
|
||||
WriteByte(ref buf, ref bitPos, ref bitLength, val.R);
|
||||
WriteByte(ref buf, ref bitPos, ref bitLength, val.G);
|
||||
WriteByte(ref buf, ref bitPos, ref bitLength, val.B);
|
||||
WriteByte(ref buf, ref bitPos, ref bitLength, val.A);
|
||||
}
|
||||
|
||||
internal static void Write(ref byte[] buf, ref int bitPos, string val)
|
||||
internal static void WriteString(ref byte[] buf, ref int bitPos, ref int bitLength, string val)
|
||||
{
|
||||
if (string.IsNullOrEmpty(val))
|
||||
{
|
||||
WriteVariableUInt32(ref buf, ref bitPos, 0u);
|
||||
WriteVariableUInt32(ref buf, ref bitPos, ref bitLength, 0u);
|
||||
return;
|
||||
}
|
||||
|
||||
byte[] bytes = Encoding.UTF8.GetBytes(val);
|
||||
WriteVariableUInt32(ref buf, ref bitPos, (uint)bytes.Length);
|
||||
WriteBytes(ref buf, ref bitPos, bytes, 0, bytes.Length);
|
||||
WriteVariableUInt32(ref buf, ref bitPos, ref bitLength, (uint)bytes.Length);
|
||||
WriteBytes(ref buf, ref bitPos, ref bitLength, bytes, 0, bytes.Length);
|
||||
}
|
||||
|
||||
internal static void WriteVariableUInt32(ref byte[] buf, ref int bitPos, uint value)
|
||||
internal static void WriteVariableUInt32(ref byte[] buf, ref int bitPos, ref int bitLength, uint value)
|
||||
{
|
||||
uint remainingValue = value;
|
||||
while (remainingValue >= 0x80)
|
||||
{
|
||||
Write(ref buf, ref bitPos, (byte)(remainingValue | 0x80));
|
||||
WriteByte(ref buf, ref bitPos, ref bitLength, (byte)(remainingValue | 0x80));
|
||||
remainingValue >>= 7;
|
||||
}
|
||||
|
||||
Write(ref buf, ref bitPos, (byte)remainingValue);
|
||||
WriteByte(ref buf, ref bitPos, ref bitLength, (byte)remainingValue);
|
||||
}
|
||||
|
||||
internal static void WriteRangedInteger(ref byte[] buf, ref int bitPos, int val, int min, int max)
|
||||
internal static void WriteRangedInteger(ref byte[] buf, ref int bitPos, ref int bitLength, int val, int min, int max)
|
||||
{
|
||||
uint range = (uint)(max - min);
|
||||
int numberOfBits = NetUtility.BitsToHoldUInt(range);
|
||||
@@ -193,9 +207,10 @@ namespace Barotrauma.Networking
|
||||
uint rvalue = (uint)(val - min);
|
||||
NetBitWriter.WriteUInt32(rvalue, numberOfBits, buf, bitPos);
|
||||
bitPos += numberOfBits;
|
||||
UpdateBitLength(ref bitLength, bitPos);
|
||||
}
|
||||
|
||||
internal static void WriteRangedSingle(ref byte[] buf, ref int bitPos, Single val, Single min, Single max, int numberOfBits)
|
||||
internal static void WriteRangedSingle(ref byte[] buf, ref int bitPos, ref int bitLength, Single val, Single min, Single max, int numberOfBits)
|
||||
{
|
||||
float range = max - min;
|
||||
float unit = ((val - min) / range);
|
||||
@@ -205,13 +220,15 @@ namespace Barotrauma.Networking
|
||||
|
||||
NetBitWriter.WriteUInt32((UInt32)(maxVal * unit), numberOfBits, buf, bitPos);
|
||||
bitPos += numberOfBits;
|
||||
UpdateBitLength(ref bitLength, bitPos);
|
||||
}
|
||||
|
||||
internal static void WriteBytes(ref byte[] buf, ref int bitPos, byte[] val, int pos, int length)
|
||||
internal static void WriteBytes(ref byte[] buf, ref int bitPos, ref int bitLength, byte[] val, int pos, int length)
|
||||
{
|
||||
EnsureBufferSize(ref buf, bitPos + length * 8);
|
||||
NetBitWriter.WriteBytes(val, pos, length, buf, bitPos);
|
||||
bitPos += length * 8;
|
||||
UpdateBitLength(ref bitLength, bitPos);
|
||||
}
|
||||
|
||||
internal static void EnsureBufferSize(ref byte[] buf, int numberOfBits)
|
||||
@@ -447,77 +464,77 @@ namespace Barotrauma.Networking
|
||||
|
||||
public void WriteBoolean(bool val)
|
||||
{
|
||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
||||
MsgWriter.WriteBoolean(ref buf, ref seekPos, ref lengthBits, val);
|
||||
}
|
||||
|
||||
public void WritePadBits()
|
||||
{
|
||||
MsgWriter.WritePadBits(ref buf, ref seekPos);
|
||||
MsgWriter.WritePadBits(ref buf, ref seekPos, ref lengthBits);
|
||||
}
|
||||
|
||||
public void WriteByte(byte val)
|
||||
{
|
||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
||||
MsgWriter.WriteByte(ref buf, ref seekPos, ref lengthBits, val);
|
||||
}
|
||||
|
||||
public void WriteUInt16(UInt16 val)
|
||||
{
|
||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
||||
MsgWriter.WriteUInt16(ref buf, ref seekPos, ref lengthBits, val);
|
||||
}
|
||||
|
||||
public void WriteInt16(Int16 val)
|
||||
{
|
||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
||||
MsgWriter.WriteInt16(ref buf, ref seekPos, ref lengthBits, val);
|
||||
}
|
||||
|
||||
public void WriteUInt32(UInt32 val)
|
||||
{
|
||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
||||
MsgWriter.WriteUInt32(ref buf, ref seekPos, ref lengthBits, val);
|
||||
}
|
||||
|
||||
public void WriteInt32(Int32 val)
|
||||
{
|
||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
||||
MsgWriter.WriteInt32(ref buf, ref seekPos, ref lengthBits, val);
|
||||
}
|
||||
|
||||
public void WriteUInt64(UInt64 val)
|
||||
{
|
||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
||||
MsgWriter.WriteUInt64(ref buf, ref seekPos, ref lengthBits, val);
|
||||
}
|
||||
|
||||
public void WriteInt64(Int64 val)
|
||||
{
|
||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
||||
MsgWriter.WriteInt64(ref buf, ref seekPos, ref lengthBits, val);
|
||||
}
|
||||
|
||||
public void WriteSingle(Single val)
|
||||
{
|
||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
||||
MsgWriter.WriteSingle(ref buf, ref seekPos, ref lengthBits, val);
|
||||
}
|
||||
|
||||
public void WriteDouble(Double val)
|
||||
{
|
||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
||||
MsgWriter.WriteDouble(ref buf, ref seekPos, ref lengthBits, val);
|
||||
}
|
||||
|
||||
public void WriteColorR8G8B8(Color val)
|
||||
{
|
||||
MsgWriter.WriteColorR8G8B8(ref buf, ref seekPos, val);
|
||||
MsgWriter.WriteColorR8G8B8(ref buf, ref seekPos, ref lengthBits, val);
|
||||
}
|
||||
|
||||
public void WriteColorR8G8B8A8(Color val)
|
||||
{
|
||||
MsgWriter.WriteColorR8G8B8A8(ref buf, ref seekPos, val);
|
||||
MsgWriter.WriteColorR8G8B8A8(ref buf, ref seekPos, ref lengthBits, val);
|
||||
}
|
||||
|
||||
public void WriteVariableUInt32(UInt32 val)
|
||||
{
|
||||
MsgWriter.WriteVariableUInt32(ref buf, ref seekPos, val);
|
||||
MsgWriter.WriteVariableUInt32(ref buf, ref seekPos, ref lengthBits, val);
|
||||
}
|
||||
|
||||
public void WriteString(String val)
|
||||
{
|
||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
||||
MsgWriter.WriteString(ref buf, ref seekPos, ref lengthBits, val);
|
||||
}
|
||||
|
||||
public void WriteIdentifier(Identifier val)
|
||||
@@ -527,17 +544,17 @@ namespace Barotrauma.Networking
|
||||
|
||||
public void WriteRangedInteger(int val, int min, int max)
|
||||
{
|
||||
MsgWriter.WriteRangedInteger(ref buf, ref seekPos, val, min, max);
|
||||
MsgWriter.WriteRangedInteger(ref buf, ref seekPos, ref lengthBits, val, min, max);
|
||||
}
|
||||
|
||||
public void WriteRangedSingle(Single val, Single min, Single max, int bitCount)
|
||||
{
|
||||
MsgWriter.WriteRangedSingle(ref buf, ref seekPos, val, min, max, bitCount);
|
||||
MsgWriter.WriteRangedSingle(ref buf, ref seekPos, ref lengthBits, val, min, max, bitCount);
|
||||
}
|
||||
|
||||
public void WriteBytes(byte[] val, int startPos, int length)
|
||||
{
|
||||
MsgWriter.WriteBytes(ref buf, ref seekPos, val, startPos, length);
|
||||
MsgWriter.WriteBytes(ref buf, ref seekPos, ref lengthBits, val, startPos, length);
|
||||
}
|
||||
|
||||
public byte[] PrepareForSending(bool compressPastThreshold, out bool isCompressed, out int length)
|
||||
@@ -814,77 +831,77 @@ namespace Barotrauma.Networking
|
||||
|
||||
public void WriteBoolean(bool val)
|
||||
{
|
||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
||||
MsgWriter.WriteBoolean(ref buf, ref seekPos, ref lengthBits, val);
|
||||
}
|
||||
|
||||
public void WritePadBits()
|
||||
{
|
||||
MsgWriter.WritePadBits(ref buf, ref seekPos);
|
||||
MsgWriter.WritePadBits(ref buf, ref seekPos, ref lengthBits);
|
||||
}
|
||||
|
||||
public void WriteByte(byte val)
|
||||
{
|
||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
||||
MsgWriter.WriteByte(ref buf, ref seekPos, ref lengthBits, val);
|
||||
}
|
||||
|
||||
public void WriteUInt16(UInt16 val)
|
||||
{
|
||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
||||
MsgWriter.WriteUInt16(ref buf, ref seekPos, ref lengthBits, val);
|
||||
}
|
||||
|
||||
public void WriteInt16(Int16 val)
|
||||
{
|
||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
||||
MsgWriter.WriteInt16(ref buf, ref seekPos, ref lengthBits, val);
|
||||
}
|
||||
|
||||
public void WriteUInt32(UInt32 val)
|
||||
{
|
||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
||||
MsgWriter.WriteUInt32(ref buf, ref seekPos, ref lengthBits, val);
|
||||
}
|
||||
|
||||
public void WriteInt32(Int32 val)
|
||||
{
|
||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
||||
MsgWriter.WriteInt32(ref buf, ref seekPos, ref lengthBits, val);
|
||||
}
|
||||
|
||||
public void WriteUInt64(UInt64 val)
|
||||
{
|
||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
||||
MsgWriter.WriteUInt64(ref buf, ref seekPos, ref lengthBits, val);
|
||||
}
|
||||
|
||||
public void WriteInt64(Int64 val)
|
||||
{
|
||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
||||
MsgWriter.WriteInt64(ref buf, ref seekPos, ref lengthBits, val);
|
||||
}
|
||||
|
||||
public void WriteSingle(Single val)
|
||||
{
|
||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
||||
MsgWriter.WriteSingle(ref buf, ref seekPos, ref lengthBits, val);
|
||||
}
|
||||
|
||||
public void WriteDouble(Double val)
|
||||
{
|
||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
||||
MsgWriter.WriteDouble(ref buf, ref seekPos, ref lengthBits, val);
|
||||
}
|
||||
|
||||
public void WriteColorR8G8B8(Color val)
|
||||
{
|
||||
MsgWriter.WriteColorR8G8B8(ref buf, ref seekPos, val);
|
||||
MsgWriter.WriteColorR8G8B8(ref buf, ref seekPos, ref lengthBits, val);
|
||||
}
|
||||
|
||||
public void WriteColorR8G8B8A8(Color val)
|
||||
{
|
||||
MsgWriter.WriteColorR8G8B8A8(ref buf, ref seekPos, val);
|
||||
MsgWriter.WriteColorR8G8B8A8(ref buf, ref seekPos, ref lengthBits, val);
|
||||
}
|
||||
|
||||
public void WriteVariableUInt32(UInt32 val)
|
||||
{
|
||||
MsgWriter.WriteVariableUInt32(ref buf, ref seekPos, val);
|
||||
MsgWriter.WriteVariableUInt32(ref buf, ref seekPos, ref lengthBits, val);
|
||||
}
|
||||
|
||||
public void WriteString(String val)
|
||||
{
|
||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
||||
MsgWriter.WriteString(ref buf, ref seekPos, ref lengthBits, val);
|
||||
}
|
||||
|
||||
public void WriteIdentifier(Identifier val)
|
||||
@@ -894,17 +911,17 @@ namespace Barotrauma.Networking
|
||||
|
||||
public void WriteRangedInteger(int val, int min, int max)
|
||||
{
|
||||
MsgWriter.WriteRangedInteger(ref buf, ref seekPos, val, min, max);
|
||||
MsgWriter.WriteRangedInteger(ref buf, ref seekPos, ref lengthBits, val, min, max);
|
||||
}
|
||||
|
||||
public void WriteRangedSingle(Single val, Single min, Single max, int bitCount)
|
||||
{
|
||||
MsgWriter.WriteRangedSingle(ref buf, ref seekPos, val, min, max, bitCount);
|
||||
MsgWriter.WriteRangedSingle(ref buf, ref seekPos, ref lengthBits, val, min, max, bitCount);
|
||||
}
|
||||
|
||||
public void WriteBytes(byte[] val, int startPos, int length)
|
||||
{
|
||||
MsgWriter.WriteBytes(ref buf, ref seekPos, val, startPos, length);
|
||||
MsgWriter.WriteBytes(ref buf, ref seekPos, ref lengthBits, val, startPos, length);
|
||||
}
|
||||
|
||||
public bool ReadBoolean()
|
||||
|
||||
+7
-2
@@ -286,8 +286,13 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
public DateTime InstallTime => cachedDateTime ??= DateTime.UtcNow + TimeSpan.FromSeconds(InstallTimeDiffInSeconds);
|
||||
public RegularPackage? RegularPackage => ContentPackageManager.RegularPackages.FirstOrDefault(p => p.Hash.Equals(Hash));
|
||||
public CorePackage? CorePackage => ContentPackageManager.CorePackages.FirstOrDefault(p => p.Hash.Equals(Hash));
|
||||
public RegularPackage? RegularPackage =>
|
||||
ContentPackageManager.RegularPackages.FirstOrDefault(p => p.Name.Equals(Name) && p.Hash.Equals(Hash)) ??
|
||||
ContentPackageManager.RegularPackages.FirstOrDefault(p => p.Hash.Equals(Hash));
|
||||
|
||||
public CorePackage? CorePackage =>
|
||||
ContentPackageManager.CorePackages.FirstOrDefault(p => p.Name.Equals(Name) && p.Hash.Equals(Hash)) ??
|
||||
ContentPackageManager.CorePackages.FirstOrDefault(p => p.Hash.Equals(Hash));
|
||||
public ContentPackage? ContentPackage => (ContentPackage?)RegularPackage ?? CorePackage;
|
||||
|
||||
public ServerContentPackage() { }
|
||||
|
||||
@@ -1750,19 +1750,7 @@ namespace Barotrauma
|
||||
}
|
||||
float spread = Rand.Range(-chosenItemSpawnInfo.AimSpreadRad, chosenItemSpawnInfo.AimSpreadRad);
|
||||
float rotation = chosenItemSpawnInfo.RotationRad;
|
||||
Vector2 worldPos;
|
||||
if (sourceBody != null)
|
||||
{
|
||||
worldPos = sourceBody.Position;
|
||||
if (user?.Submarine != null)
|
||||
{
|
||||
worldPos += user.Submarine.Position;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
worldPos = entity.WorldPosition;
|
||||
}
|
||||
Vector2 spawnPos = sourceBody != null ? sourceBody.SimPosition : entity.SimPosition;
|
||||
switch (chosenItemSpawnInfo.RotationType)
|
||||
{
|
||||
case ItemSpawnInfo.SpawnRotationType.Fixed:
|
||||
@@ -1776,7 +1764,7 @@ namespace Barotrauma
|
||||
}
|
||||
break;
|
||||
case ItemSpawnInfo.SpawnRotationType.Target:
|
||||
rotation = MathUtils.VectorToAngle(entity.WorldPosition - worldPos);
|
||||
rotation = MathUtils.VectorToAngle(entity.SimPosition - spawnPos);
|
||||
break;
|
||||
case ItemSpawnInfo.SpawnRotationType.Limb:
|
||||
if (sourceBody != null)
|
||||
@@ -1820,10 +1808,7 @@ namespace Barotrauma
|
||||
rotation += spread;
|
||||
if (projectile != null)
|
||||
{
|
||||
projectile.Shoot(user,
|
||||
ConvertUnits.ToSimUnits(worldPos),
|
||||
ConvertUnits.ToSimUnits(worldPos),
|
||||
rotation,
|
||||
projectile.Shoot(user, spawnPos, spawnPos, rotation,
|
||||
ignoredBodies: user?.AnimController.Limbs.Where(l => !l.IsSevered).Select(l => l.body.FarseerBody).ToList(), createNetworkEvent: true);
|
||||
}
|
||||
else if (newItem.body != null)
|
||||
|
||||
@@ -43,9 +43,9 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public int GetBuyprice(int level, Location? location = null)
|
||||
public int GetBuyPrice(int level, Location? location = null)
|
||||
{
|
||||
int maxLevel = Prefab.MaxLevel;
|
||||
int maxLevel = Prefab.GetMaxLevelForCurrentSub();
|
||||
|
||||
if (level > maxLevel) { maxLevel = level; }
|
||||
|
||||
@@ -292,16 +292,10 @@ namespace Barotrauma
|
||||
onRemoveOverrideFile: null
|
||||
);
|
||||
|
||||
private readonly int maxLevel;
|
||||
|
||||
public int MaxLevel
|
||||
{
|
||||
get
|
||||
{
|
||||
Submarine? sub = GameMain.GameSession?.Submarine ?? Submarine.MainSub;
|
||||
return sub is { Info: var info } ? GetMaxLevel(info) : maxLevel;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Maximum upgrade level without taking submarine tier or class restrictions into account
|
||||
/// </summary>
|
||||
public readonly int MaxLevel;
|
||||
|
||||
public LocalizedString Name { get; }
|
||||
|
||||
@@ -343,7 +337,7 @@ namespace Barotrauma
|
||||
{
|
||||
Name = element.GetAttributeString("name", string.Empty)!;
|
||||
Description = element.GetAttributeString("description", string.Empty)!;
|
||||
maxLevel = element.GetAttributeInt("maxlevel", 1);
|
||||
MaxLevel = element.GetAttributeInt("maxlevel", 1);
|
||||
SuppressWarnings = element.GetAttributeBool("supresswarnings", false);
|
||||
HideInMenus = element.GetAttributeBool("hideinmenus", false);
|
||||
SourceElement = element;
|
||||
@@ -428,9 +422,21 @@ namespace Barotrauma
|
||||
.ToImmutableHashSet() ?? ImmutableHashSet<Identifier>.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the maximum upgrade level for the current sub, taking tier and class restrictions into account
|
||||
/// </summary>
|
||||
public int GetMaxLevelForCurrentSub()
|
||||
{
|
||||
Submarine? sub = GameMain.GameSession?.Submarine ?? Submarine.MainSub;
|
||||
return sub is { Info: var info } ? GetMaxLevel(info) : MaxLevel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the maximum upgrade level for the specified sub, taking tier and class restrictions into account
|
||||
/// </summary>
|
||||
public int GetMaxLevel(SubmarineInfo info)
|
||||
{
|
||||
int level = maxLevel;
|
||||
int level = MaxLevel;
|
||||
|
||||
foreach (UpgradeMaxLevelMod mod in MaxLevelsMods)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user