(ded4a3e0a) v0.9.0.7
This commit is contained in:
+1
-1
@@ -196,7 +196,7 @@ namespace Barotrauma
|
||||
if (ignoredHulls != null && ignoredHulls.Contains(hull)) { continue; }
|
||||
if (unreachable.Contains(hull)) { continue; }
|
||||
float hullSafety = 0;
|
||||
if (character.CurrentHull != null)
|
||||
if (character.CurrentHull != null && character.Submarine != null)
|
||||
{
|
||||
// Inside
|
||||
if (!character.Submarine.IsConnectedTo(hull.Submarine)) { continue; }
|
||||
|
||||
@@ -1101,7 +1101,7 @@ namespace Barotrauma
|
||||
//prevent the hands from going above the top of the ladders
|
||||
handPos.Y = Math.Min(-0.5f, handPos.Y);
|
||||
|
||||
if (!PlayerInput.KeyDown(InputType.Aim) || Math.Abs(movement.Y) > 0.01f)
|
||||
if (!character.IsKeyDown(InputType.Aim) || Math.Abs(movement.Y) > 0.01f)
|
||||
{
|
||||
MoveLimb(leftHand,
|
||||
new Vector2(handPos.X,
|
||||
|
||||
@@ -836,13 +836,21 @@ namespace Barotrauma
|
||||
private static string humanConfigFile;
|
||||
public static string HumanConfigFile
|
||||
{
|
||||
get
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(humanConfigFile))
|
||||
{
|
||||
humanConfigFile = GetConfigFile("Human");
|
||||
humanConfigFile = GameMain.Instance.GetFilesOfType(ContentType.Character)?
|
||||
.FirstOrDefault(c => Path.GetFileName(c).ToLowerInvariant() == "human.xml");
|
||||
|
||||
if (humanConfigFile == null)
|
||||
{
|
||||
DebugConsole.ThrowError($"Couldn't find a human config file from the selected content packages!");
|
||||
DebugConsole.ThrowError($"(The config file must end with \"human.xml\")");
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
return humanConfigFile;
|
||||
return humanConfigFile;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -859,12 +867,16 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches for a character config file from all currently selected content packages,
|
||||
/// or from a specific package if the contentPackage parameter is given.
|
||||
/// </summary>
|
||||
public static string GetConfigFile(string speciesName, ContentPackage contentPackage = null)
|
||||
{
|
||||
string configFile = null;
|
||||
if (contentPackage == null)
|
||||
{
|
||||
configFile = GameMain.Instance.GetFilesOfType(ContentType.Character, searchAllContentPackages: true)
|
||||
configFile = GameMain.Instance.GetFilesOfType(ContentType.Character)
|
||||
.FirstOrDefault(c => Path.GetFileName(c).ToLowerInvariant() == $"{speciesName.ToLowerInvariant()}.xml");
|
||||
}
|
||||
else
|
||||
@@ -1519,10 +1531,9 @@ namespace Barotrauma
|
||||
if (inventory.Owner is Item)
|
||||
{
|
||||
var owner = (Item)inventory.Owner;
|
||||
if (!CanInteractWith(owner))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!CanInteractWith(owner)) { return false; }
|
||||
ItemContainer container = owner.GetComponents<ItemContainer>().FirstOrDefault(ic => ic.Inventory == inventory);
|
||||
if (container != null && !container.HasRequiredItems(this, addMessage: false)) { return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -747,7 +747,7 @@ namespace Barotrauma
|
||||
|
||||
public void IncreaseSkillLevel(string skillIdentifier, float increase, Vector2 worldPos)
|
||||
{
|
||||
if (Job == null || (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient)) return;
|
||||
if (Job == null || (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) || Character == null) { return; }
|
||||
|
||||
float prevLevel = Job.GetSkillLevel(skillIdentifier);
|
||||
Job.IncreaseSkillLevel(skillIdentifier, increase);
|
||||
|
||||
@@ -444,6 +444,8 @@ namespace Barotrauma
|
||||
public bool SectorHit(Vector2 armorSector, Vector2 simPosition)
|
||||
{
|
||||
if (armorSector == Vector2.Zero) { return false; }
|
||||
//sector 360 degrees or more -> always hits
|
||||
if (Math.Abs(armorSector.Y - armorSector.X) >= MathHelper.TwoPi) { return true; }
|
||||
float rotation = body.TransformedRotation;
|
||||
float offset = (MathHelper.PiOver2 - GetArmorSectorRotationOffset(armorSector)) * Dir;
|
||||
float hitAngle = VectorExtensions.Angle(VectorExtensions.Forward(rotation + offset), SimPosition - simPosition);
|
||||
@@ -460,9 +462,7 @@ namespace Barotrauma
|
||||
|
||||
protected float GetArmorSectorSize(Vector2 armorSector)
|
||||
{
|
||||
float min = Math.Min(armorSector.X, armorSector.Y);
|
||||
float max = Math.Max(armorSector.X, armorSector.Y);
|
||||
return max - min;
|
||||
return Math.Abs(armorSector.X - armorSector.Y);
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
|
||||
@@ -498,7 +498,7 @@ namespace Barotrauma
|
||||
{
|
||||
Path = path;
|
||||
|
||||
#if OSX
|
||||
#if OSX || LINUX
|
||||
Path = Path.Replace("\\", "/");
|
||||
#endif
|
||||
|
||||
|
||||
@@ -328,7 +328,7 @@ namespace Barotrauma
|
||||
};
|
||||
}));
|
||||
|
||||
commands.Add(new Command("kickid", "kickid [id]: Kick the player with the specified client ID out of the server.", (string[] args) =>
|
||||
commands.Add(new Command("kickid", "kickid [id]: Kick the player with the specified client ID out of the server. You can see the IDs of the clients using the command \"clientlist\".", (string[] args) =>
|
||||
{
|
||||
if (GameMain.NetworkMember == null || args.Length == 0) return;
|
||||
|
||||
@@ -380,7 +380,7 @@ namespace Barotrauma
|
||||
};
|
||||
}));
|
||||
|
||||
commands.Add(new Command("banid", "banid [id]: Kick and ban the player with the specified client ID from the server.", (string[] args) =>
|
||||
commands.Add(new Command("banid", "banid [id]: Kick and ban the player with the specified client ID from the server. You can see the IDs of the clients using the command \"clientlist\".", (string[] args) =>
|
||||
{
|
||||
if (GameMain.NetworkMember == null || args.Length == 0) return;
|
||||
|
||||
|
||||
@@ -66,12 +66,13 @@ namespace Barotrauma
|
||||
|
||||
if (GameMain.Config?.SelectedContentPackages.Count > 0)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder("ContentPackage:");
|
||||
StringBuilder sb = new StringBuilder("ContentPackage: ");
|
||||
int i = 0;
|
||||
foreach (ContentPackage cp in GameMain.Config.SelectedContentPackages)
|
||||
{
|
||||
sb.Append(cp.Name.Replace(":", "").Substring(0, Math.Min(32, cp.Name.Length)));
|
||||
if (i < GameMain.Config.SelectedContentPackages.Count - 1) sb.Append(",");
|
||||
string trimmedName = cp.Name.Replace(":", "").Replace(" ", "");
|
||||
sb.Append(trimmedName.Substring(0, Math.Min(32, trimmedName.Length)));
|
||||
if (i < GameMain.Config.SelectedContentPackages.Count - 1) { sb.Append(" "); }
|
||||
}
|
||||
GameAnalytics.AddDesignEvent(sb.ToString());
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using System.Xml;
|
||||
using System.IO;
|
||||
#if CLIENT
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Barotrauma.Tutorials;
|
||||
@@ -142,6 +143,8 @@ namespace Barotrauma
|
||||
public bool CrewMenuOpen { get; set; } = true;
|
||||
public bool ChatOpen { get; set; } = true;
|
||||
|
||||
private string overrideSaveFolder, overrideMultiplayerSaveFolder;
|
||||
|
||||
private bool unsavedSettings;
|
||||
public bool UnsavedSettings
|
||||
{
|
||||
@@ -277,7 +280,6 @@ namespace Barotrauma
|
||||
|
||||
public GameSettings()
|
||||
{
|
||||
SelectedContentPackages = new HashSet<ContentPackage>();
|
||||
ContentPackage.LoadAll(ContentPackage.Folder);
|
||||
CompletedTutorialNames = new List<string>();
|
||||
|
||||
@@ -605,6 +607,17 @@ namespace Barotrauma
|
||||
LoadControls(doc);
|
||||
LoadContentPackages(doc);
|
||||
|
||||
//allow overriding the save paths in the config file
|
||||
if (doc.Root.Attribute("overridesavefolder") != null)
|
||||
{
|
||||
overrideSaveFolder = SaveUtil.SaveFolder = doc.Root.GetAttributeString("overridesavefolder", "");
|
||||
overrideMultiplayerSaveFolder = SaveUtil.MultiplayerSaveFolder = Path.Combine(overrideSaveFolder, "Multiplayer");
|
||||
}
|
||||
if (doc.Root.Attribute("overridemultiplayersavefolder") != null)
|
||||
{
|
||||
overrideMultiplayerSaveFolder = SaveUtil.MultiplayerSaveFolder = doc.Root.GetAttributeString("overridemultiplayersavefolder", "");
|
||||
}
|
||||
|
||||
XElement tutorialsElement = doc.Root.Element("tutorials");
|
||||
if (tutorialsElement != null)
|
||||
{
|
||||
@@ -732,6 +745,15 @@ namespace Barotrauma
|
||||
new XAttribute("campaigndisclaimershown", CampaignDisclaimerShown),
|
||||
new XAttribute("editordisclaimershown", EditorDisclaimerShown));
|
||||
|
||||
if (!string.IsNullOrEmpty(overrideSaveFolder))
|
||||
{
|
||||
doc.Root.Add(new XAttribute("overridesavefolder", overrideSaveFolder));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(overrideMultiplayerSaveFolder))
|
||||
{
|
||||
doc.Root.Add(new XAttribute("overridemultiplayersavefolder", overrideMultiplayerSaveFolder));
|
||||
}
|
||||
|
||||
if (!ShowUserStatisticsPrompt)
|
||||
{
|
||||
doc.Root.Add(new XAttribute("senduserstatistics", sendUserStatistics));
|
||||
|
||||
@@ -22,7 +22,6 @@ namespace Barotrauma.Items.Components
|
||||
private float openState;
|
||||
private Sprite doorSprite, weldedSprite, brokenSprite;
|
||||
private bool scaleBrokenSprite, fadeBrokenSprite;
|
||||
private bool createdNewGap;
|
||||
private bool autoOrientGap;
|
||||
|
||||
private bool isStuck;
|
||||
@@ -87,17 +86,19 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
get
|
||||
{
|
||||
if (linkedGap != null) return linkedGap;
|
||||
|
||||
foreach (MapEntity e in item.linkedTo)
|
||||
if (linkedGap == null)
|
||||
{
|
||||
linkedGap = e as Gap;
|
||||
if (linkedGap != null)
|
||||
{
|
||||
linkedGap.PassAmbientLight = Window != Rectangle.Empty;
|
||||
return linkedGap;
|
||||
}
|
||||
GetLinkedGap();
|
||||
}
|
||||
return linkedGap;
|
||||
}
|
||||
}
|
||||
|
||||
private void GetLinkedGap()
|
||||
{
|
||||
linkedGap = item.linkedTo.FirstOrDefault(e => e is Gap) as Gap;
|
||||
if (linkedGap == null)
|
||||
{
|
||||
Rectangle rect = item.Rect;
|
||||
if (IsHorizontal)
|
||||
{
|
||||
@@ -109,17 +110,13 @@ namespace Barotrauma.Items.Components
|
||||
rect.X -= 5;
|
||||
rect.Width += 10;
|
||||
}
|
||||
|
||||
linkedGap = new Gap(rect, !IsHorizontal, Item.Submarine)
|
||||
{
|
||||
Submarine = item.Submarine,
|
||||
PassAmbientLight = Window != Rectangle.Empty,
|
||||
Open = openState
|
||||
Submarine = item.Submarine
|
||||
};
|
||||
item.linkedTo.Add(linkedGap);
|
||||
createdNewGap = true;
|
||||
return linkedGap;
|
||||
}
|
||||
RefreshLinkedGap();
|
||||
}
|
||||
|
||||
public bool IsHorizontal { get; private set; }
|
||||
@@ -162,14 +159,14 @@ namespace Barotrauma.Items.Components
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
|
||||
public Door(Item item, XElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
IsHorizontal = element.GetAttributeBool("horizontal", false);
|
||||
canBePicked = element.GetAttributeBool("canbepicked", false);
|
||||
autoOrientGap = element.GetAttributeBool("autoorientgap", false);
|
||||
|
||||
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
string texturePath = subElement.GetAttributeString("texture", "");
|
||||
@@ -370,12 +367,20 @@ namespace Barotrauma.Items.Components
|
||||
#endif
|
||||
}
|
||||
|
||||
public override void OnMapLoaded()
|
||||
public void RefreshLinkedGap()
|
||||
{
|
||||
LinkedGap.ConnectedDoor = this;
|
||||
if (autoOrientGap)
|
||||
{
|
||||
LinkedGap.AutoOrient();
|
||||
}
|
||||
LinkedGap.Open = openState;
|
||||
if (createdNewGap && autoOrientGap) linkedGap.AutoOrient();
|
||||
LinkedGap.PassAmbientLight = Window != Rectangle.Empty;
|
||||
}
|
||||
|
||||
public override void OnMapLoaded()
|
||||
{
|
||||
RefreshLinkedGap();
|
||||
#if CLIENT
|
||||
Vector2[] corners = GetConvexHullCorners(Rectangle.Empty);
|
||||
|
||||
@@ -386,6 +391,18 @@ namespace Barotrauma.Items.Components
|
||||
#endif
|
||||
}
|
||||
|
||||
public override void OnScaleChanged()
|
||||
{
|
||||
#if CLIENT
|
||||
UpdateConvexHulls();
|
||||
#endif
|
||||
if (linkedGap != null)
|
||||
{
|
||||
RefreshLinkedGap();
|
||||
linkedGap.Rect = item.Rect;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void RemoveComponentSpecific()
|
||||
{
|
||||
base.RemoveComponentSpecific();
|
||||
|
||||
@@ -53,12 +53,6 @@ namespace Barotrauma.Items.Components
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// How useful the weapon is in combat? Used by AI to sort the used weapon. For the sake of clarity, use a value between 0 and 100 (not enforced).
|
||||
/// </summary>
|
||||
[Serialize(0f, false)]
|
||||
public float CombatPriority { get; private set; }
|
||||
|
||||
public MeleeWeapon(Item item, XElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
|
||||
@@ -43,12 +43,6 @@ namespace Barotrauma.Items.Components
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// How useful the weapon is in combat? Used by AI to sort the used weapon. For the sake of clarity, use a value between 0 and 100 (not enforced).
|
||||
/// </summary>
|
||||
[Serialize(0f, false)]
|
||||
public float CombatPriority { get; private set; }
|
||||
|
||||
public Vector2 TransformedBarrelPos
|
||||
{
|
||||
get
|
||||
@@ -170,6 +164,7 @@ namespace Barotrauma.Items.Components
|
||||
projectile.Item.SetTransform(projectilePos, rotation);
|
||||
|
||||
projectile.Use(deltaTime);
|
||||
if (projectile.Item.Removed) { return true; }
|
||||
projectile.User = character;
|
||||
|
||||
projectile.Item.body.ApplyTorque(projectile.Item.body.Mass * degreeOfFailure * Rand.Range(-10.0f, 10.0f));
|
||||
|
||||
@@ -157,7 +157,8 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
partial void UseProjSpecific(float deltaTime);
|
||||
|
||||
private List<FireSource> fireSourcesInRange = new List<FireSource>();
|
||||
private readonly HashSet<Character> hitCharacters = new HashSet<Character>();
|
||||
private readonly List<FireSource> fireSourcesInRange = new List<FireSource>();
|
||||
private void Repair(Vector2 rayStart, Vector2 rayEnd, float deltaTime, Character user, float degreeOfSuccess, List<Body> ignoredBodies)
|
||||
{
|
||||
var collisionCategories = Physics.CollisionWall | Physics.CollisionCharacter | Physics.CollisionItem | Physics.CollisionLevel | Physics.CollisionRepair;
|
||||
@@ -165,6 +166,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
var bodies = Submarine.PickBodies(rayStart, rayEnd, ignoredBodies, collisionCategories, ignoreSensors: false, allowInsideFixture: true);
|
||||
Type lastHitType = null;
|
||||
hitCharacters.Clear();
|
||||
foreach (Body body in bodies)
|
||||
{
|
||||
Type bodyType = body.UserData?.GetType();
|
||||
@@ -173,6 +175,23 @@ namespace Barotrauma.Items.Components
|
||||
//stop the ray if it already hit a door/wall and is now about to hit some other type of entity
|
||||
if (lastHitType == typeof(Item) || lastHitType == typeof(Structure)) { break; }
|
||||
}
|
||||
|
||||
Character hitCharacter = null;
|
||||
if (body.UserData is Limb limb)
|
||||
{
|
||||
hitCharacter = limb.character;
|
||||
}
|
||||
else if (body.UserData is Character character)
|
||||
{
|
||||
hitCharacter = character;
|
||||
}
|
||||
//only do damage once to each character even if they ray hit multiple limbs
|
||||
if (hitCharacter != null)
|
||||
{
|
||||
if (hitCharacters.Contains(hitCharacter)) { continue; }
|
||||
hitCharacters.Add(hitCharacter);
|
||||
}
|
||||
|
||||
if (FixBody(user, deltaTime, degreeOfSuccess, body))
|
||||
{
|
||||
if (bodyType != null) { lastHitType = bodyType; }
|
||||
|
||||
@@ -545,7 +545,6 @@ namespace Barotrauma.Items.Components
|
||||
GameAnalyticsManager.AddErrorEventOnce("ItemComponent.DegreeOfSuccess:CharacterNull", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||
return 0.0f;
|
||||
}
|
||||
float average = skillSuccessSum / requiredSkills.Count;
|
||||
|
||||
float skillSuccessSum = 0.0f;
|
||||
for (int i = 0; i < requiredSkills.Count; i++)
|
||||
@@ -693,6 +692,8 @@ namespace Barotrauma.Items.Components
|
||||
/// </summary>
|
||||
public virtual void OnItemLoaded() { }
|
||||
|
||||
public virtual void OnScaleChanged() { }
|
||||
|
||||
// TODO: Consider using generics, interfaces, or inheritance instead of reflection -> would be easier to debug when something changes/goes wrong.
|
||||
// For example, currently we can edit the constructors but they will fail in runtime because the parameters are not changed here.
|
||||
// It's also painful to find where the constructors are used, because the references exist only at runtime.
|
||||
|
||||
@@ -97,6 +97,7 @@ namespace Barotrauma.Items.Components
|
||||
RelatedItem ri = containableItems.Find(x => x.MatchesItem(containedItem));
|
||||
if (ri != null)
|
||||
{
|
||||
itemsWithStatusEffects.RemoveAll(i => i.First == containedItem);
|
||||
foreach (StatusEffect effect in ri.statusEffects)
|
||||
{
|
||||
itemsWithStatusEffects.Add(new Pair<Item, StatusEffect>(containedItem, effect));
|
||||
@@ -107,12 +108,12 @@ namespace Barotrauma.Items.Components
|
||||
IsActive = itemsWithStatusEffects.Count > 0 || containedItem.body != null;
|
||||
}
|
||||
|
||||
public void OnItemRemoved(Item item)
|
||||
public void OnItemRemoved(Item containedItem)
|
||||
{
|
||||
itemsWithStatusEffects.RemoveAll(i => i.First == item);
|
||||
itemsWithStatusEffects.RemoveAll(i => i.First == containedItem);
|
||||
|
||||
//deactivate if the inventory is empty
|
||||
IsActive = itemsWithStatusEffects.Count > 0 || item.body != null;
|
||||
IsActive = itemsWithStatusEffects.Count > 0 || containedItem.body != null;
|
||||
}
|
||||
|
||||
public bool CanBeContained(Item item)
|
||||
|
||||
@@ -37,6 +37,8 @@ namespace Barotrauma.Items.Components
|
||||
private Item focusTarget;
|
||||
private float targetRotation;
|
||||
|
||||
private bool state;
|
||||
|
||||
public Vector2 UserPos
|
||||
{
|
||||
get { return userPos; }
|
||||
@@ -48,6 +50,13 @@ namespace Barotrauma.Items.Components
|
||||
get { return user; }
|
||||
}
|
||||
|
||||
[Serialize(false, false), Editable(ToolTip = "When enabled, the item will continuously send out a 0/1 signal and interacting with it will flip the signal (making the item behave like a switch). When disabled, the item will simply send out 1 when interacted with.")]
|
||||
public bool IsToggle
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public Controller(Item item, XElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
@@ -55,7 +64,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
userPos = element.GetAttributeVector2("UserPos", Vector2.Zero);
|
||||
|
||||
Enum.TryParse<Direction>(element.GetAttributeString("direction", "None"), out dir);
|
||||
Enum.TryParse(element.GetAttributeString("direction", "None"), out dir);
|
||||
|
||||
foreach (XElement el in element.Elements())
|
||||
{
|
||||
@@ -83,7 +92,12 @@ namespace Barotrauma.Items.Components
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
this.cam = cam;
|
||||
|
||||
|
||||
if (IsToggle)
|
||||
{
|
||||
item.SendSignal(0, state ? "1" : "0", "signal_out", sender: null);
|
||||
}
|
||||
|
||||
if (user == null
|
||||
|| user.Removed
|
||||
|| user.SelectedConstruction != item
|
||||
@@ -94,7 +108,7 @@ namespace Barotrauma.Items.Components
|
||||
CancelUsing(user);
|
||||
user = null;
|
||||
}
|
||||
IsActive = false;
|
||||
if (!IsToggle) { IsActive = false; }
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -169,7 +183,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
item.SendSignal(0, "1", "trigger_out", user);
|
||||
|
||||
|
||||
ApplyStatusEffects(ActionType.OnUse, 1.0f, activator);
|
||||
|
||||
return true;
|
||||
@@ -254,7 +268,14 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public override bool Pick(Character picker)
|
||||
{
|
||||
item.SendSignal(0, "1", "signal_out", picker);
|
||||
if (IsToggle)
|
||||
{
|
||||
state = !state;
|
||||
}
|
||||
else
|
||||
{
|
||||
item.SendSignal(0, "1", "signal_out", picker);
|
||||
}
|
||||
|
||||
#if CLIENT
|
||||
PlaySound(ActionType.OnUse, item.WorldPosition, picker);
|
||||
|
||||
@@ -137,10 +137,10 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public Vector2 AvoidStrength;
|
||||
|
||||
public ObstacleDebugInfo(GraphEdge edge, Vector2? intersection, float dot, Vector2 avoidStrength)
|
||||
public ObstacleDebugInfo(GraphEdge edge, Vector2? intersection, float dot, Vector2 avoidStrength, Vector2 translation)
|
||||
{
|
||||
Point1 = edge.Point1;
|
||||
Point2 = edge.Point2;
|
||||
Point1 = edge.Point1 + translation;
|
||||
Point2 = edge.Point2 + translation;
|
||||
Intersection = intersection;
|
||||
Dot = dot;
|
||||
AvoidStrength = avoidStrength;
|
||||
@@ -210,6 +210,11 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (voltage < minVoltage && currPowerConsumption > 0.0f) { return; }
|
||||
|
||||
if (user != null && user.Removed)
|
||||
{
|
||||
user = null;
|
||||
}
|
||||
|
||||
ApplyStatusEffects(ActionType.OnActive, deltaTime, null);
|
||||
|
||||
if (autoPilot)
|
||||
@@ -333,14 +338,14 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
foreach (GraphEdge edge in cell.Edges)
|
||||
{
|
||||
if (MathUtils.GetLineIntersection(edge.Point1, edge.Point2, controlledSub.WorldPosition, cell.Center, out Vector2 intersection))
|
||||
if (MathUtils.GetLineIntersection(edge.Point1 + cell.Translation, edge.Point2 + cell.Translation, controlledSub.WorldPosition, cell.Center, out Vector2 intersection))
|
||||
{
|
||||
Vector2 diff = controlledSub.WorldPosition - intersection;
|
||||
|
||||
//far enough -> ignore
|
||||
if (Math.Abs(diff.X) > avoidDist.X && Math.Abs(diff.Y) > avoidDist.Y)
|
||||
{
|
||||
debugDrawObstacles.Add(new ObstacleDebugInfo(edge, intersection, 0.0f, Vector2.Zero));
|
||||
debugDrawObstacles.Add(new ObstacleDebugInfo(edge, intersection, 0.0f, Vector2.Zero, Vector2.Zero));
|
||||
continue;
|
||||
}
|
||||
if (diff.LengthSquared() < 1.0f) diff = Vector2.UnitY;
|
||||
@@ -352,13 +357,13 @@ namespace Barotrauma.Items.Components
|
||||
//not heading towards the wall -> ignore
|
||||
if (dot < 0.5)
|
||||
{
|
||||
debugDrawObstacles.Add(new ObstacleDebugInfo(edge, intersection, dot, Vector2.Zero));
|
||||
debugDrawObstacles.Add(new ObstacleDebugInfo(edge, intersection, dot, Vector2.Zero, cell.Translation));
|
||||
continue;
|
||||
}
|
||||
|
||||
Vector2 change = (normalizedDiff * Math.Max((avoidRadius - diff.Length()), 0.0f)) / avoidRadius;
|
||||
newAvoidStrength += change * dot;
|
||||
debugDrawObstacles.Add(new ObstacleDebugInfo(edge, intersection, dot, change * dot));
|
||||
debugDrawObstacles.Add(new ObstacleDebugInfo(edge, intersection, dot, change * dot, cell.Translation));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,7 +275,14 @@ namespace Barotrauma.Items.Components
|
||||
//the raycast didn't hit anything -> the projectile flew somewhere outside the level and is permanently lost
|
||||
if (!hitSomething)
|
||||
{
|
||||
Entity.Spawner.AddToRemoveQueue(item);
|
||||
if (Entity.Spawner == null)
|
||||
{
|
||||
item.Remove();
|
||||
}
|
||||
else
|
||||
{
|
||||
Entity.Spawner.AddToRemoveQueue(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,12 +9,14 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class Repairable : ItemComponent, IServerSerializable, IClientSerializable
|
||||
{
|
||||
public static float SkillIncreaseMultiplier = 0.4f;
|
||||
public static float SkillIncreasePerRepair = 5.0f;
|
||||
|
||||
private string header;
|
||||
|
||||
private float deteriorationTimer;
|
||||
|
||||
bool wasBroken;
|
||||
|
||||
public float LastActiveTime;
|
||||
|
||||
[Serialize(0.0f, true), Editable(MinValueFloat = 0.0f, MaxValueFloat = 100.0f, DecimalCount = 2, ToolTip = "How fast the condition of the item deteriorates per second.")]
|
||||
@@ -173,16 +175,13 @@ namespace Barotrauma.Items.Components
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; }
|
||||
|
||||
float successFactor = requiredSkills.Count == 0 ? 1.0f : 0.0f;
|
||||
foreach (Skill skill in requiredSkills)
|
||||
|
||||
//item must have been below 50% condition for the player to get an achievement or XP for repairing it
|
||||
if (item.Condition < ShowRepairUIThreshold)
|
||||
{
|
||||
float characterSkillLevel = CurrentFixer.GetSkillLevel(skill.Identifier);
|
||||
if (characterSkillLevel >= skill.Level) successFactor += 1.0f / requiredSkills.Count;
|
||||
CurrentFixer.Info.IncreaseSkillLevel(skill.Identifier,
|
||||
SkillIncreaseMultiplier * deltaTime / Math.Max(characterSkillLevel, 1.0f),
|
||||
CurrentFixer.WorldPosition + Vector2.UnitY * 100.0f);
|
||||
wasBroken = true;
|
||||
}
|
||||
|
||||
bool wasBroken = !item.IsFullCondition;
|
||||
float fixDuration = MathHelper.Lerp(FixDurationLowSkill, FixDurationHighSkill, successFactor);
|
||||
if (fixDuration <= 0.0f)
|
||||
{
|
||||
@@ -195,8 +194,16 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (wasBroken && item.IsFullCondition)
|
||||
{
|
||||
foreach (Skill skill in requiredSkills)
|
||||
{
|
||||
float characterSkillLevel = CurrentFixer.GetSkillLevel(skill.Identifier);
|
||||
CurrentFixer.Info.IncreaseSkillLevel(skill.Identifier,
|
||||
SkillIncreasePerRepair / Math.Max(characterSkillLevel, 1.0f),
|
||||
CurrentFixer.WorldPosition + Vector2.UnitY * 100.0f);
|
||||
}
|
||||
SteamAchievementManager.OnItemRepaired(item, currentFixer);
|
||||
deteriorationTimer = Rand.Range(MinDeteriorationDelay, MaxDeteriorationDelay);
|
||||
wasBroken = false;
|
||||
#if SERVER
|
||||
item.CreateServerEvent(this);
|
||||
#endif
|
||||
|
||||
@@ -19,7 +19,8 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private string prevSignal;
|
||||
|
||||
public Character.TeamType TeamID;
|
||||
[Serialize(Character.TeamType.None, false)]
|
||||
public Character.TeamType TeamID { get; set; }
|
||||
|
||||
[Serialize(20000.0f, false)]
|
||||
public float Range
|
||||
@@ -82,8 +83,11 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public bool CanReceive(WifiComponent sender)
|
||||
{
|
||||
if (sender == null || sender.channel != channel || sender.TeamID != TeamID) return false;
|
||||
if (Vector2.DistanceSquared(item.WorldPosition, sender.item.WorldPosition) > sender.range * sender.range) return false;
|
||||
if (sender == null || sender.channel != channel) { return false; }
|
||||
if (sender.TeamID == Character.TeamType.Team1 && TeamID == Character.TeamType.Team2) { return false; }
|
||||
if (sender.TeamID == Character.TeamType.Team2 && TeamID == Character.TeamType.Team1) { return false; }
|
||||
|
||||
if (Vector2.DistanceSquared(item.WorldPosition, sender.item.WorldPosition) > sender.range * sender.range) { return false; }
|
||||
|
||||
return HasRequiredContainedItems(false);
|
||||
}
|
||||
|
||||
@@ -70,7 +70,9 @@ namespace Barotrauma
|
||||
|
||||
private Inventory parentInventory;
|
||||
private Inventory ownInventory;
|
||||
|
||||
|
||||
private Rectangle defaultRect;
|
||||
|
||||
private Dictionary<string, Connection> connections;
|
||||
|
||||
private List<Repairable> repairables;
|
||||
@@ -198,6 +200,34 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private float scale = 1.0f;
|
||||
public override float Scale
|
||||
{
|
||||
get { return scale; }
|
||||
set
|
||||
{
|
||||
if (scale == value) { return; }
|
||||
scale = MathHelper.Clamp(value, 0.1f, 10.0f);
|
||||
|
||||
float relativeScale = scale / prefab.Scale;
|
||||
|
||||
if (!ResizeHorizontal || !ResizeVertical)
|
||||
{
|
||||
int newWidth = ResizeHorizontal ? rect.Width : (int)(defaultRect.Width * relativeScale);
|
||||
int newHeight = ResizeVertical ? rect.Height : (int)(defaultRect.Height * relativeScale);
|
||||
Rect = new Rectangle(rect.X, rect.Y, newWidth, newHeight);
|
||||
}
|
||||
|
||||
if (components != null)
|
||||
{
|
||||
foreach (ItemComponent component in components)
|
||||
{
|
||||
component.OnScaleChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float PositionUpdateInterval
|
||||
{
|
||||
get;
|
||||
@@ -499,9 +529,10 @@ namespace Barotrauma
|
||||
drawableComponents = new List<IDrawableComponent>();
|
||||
tags = new HashSet<string>();
|
||||
repairables = new List<Repairable>();
|
||||
|
||||
|
||||
defaultRect = newRect;
|
||||
rect = newRect;
|
||||
|
||||
|
||||
condition = itemPrefab.Health;
|
||||
lastSentCondition = condition;
|
||||
|
||||
@@ -626,13 +657,18 @@ namespace Barotrauma
|
||||
ic.OnItemLoaded();
|
||||
}
|
||||
}
|
||||
|
||||
DebugConsole.Log("Created " + Name + " (" + ID + ")");
|
||||
}
|
||||
|
||||
partial void InitProjSpecific();
|
||||
|
||||
public override MapEntity Clone()
|
||||
{
|
||||
Item clone = new Item(rect, Prefab, Submarine, callOnItemLoaded: false);
|
||||
Item clone = new Item(rect, Prefab, Submarine, callOnItemLoaded: false)
|
||||
{
|
||||
defaultRect = defaultRect
|
||||
};
|
||||
foreach (KeyValuePair<string, SerializableProperty> property in SerializableProperties)
|
||||
{
|
||||
if (!property.Value.Attributes.OfType<Editable>().Any()) continue;
|
||||
@@ -1552,7 +1588,7 @@ namespace Barotrauma
|
||||
|
||||
public void Use(float deltaTime, Character character = null, Limb targetLimb = null)
|
||||
{
|
||||
if (RequireAimToUse && !character.IsKeyDown(InputType.Aim))
|
||||
if (RequireAimToUse && (character == null || !character.IsKeyDown(InputType.Aim)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -2050,11 +2086,11 @@ namespace Barotrauma
|
||||
System.Diagnostics.Debug.Assert(Submarine != null || rootContainer.ParentInventory?.Owner is Character);
|
||||
|
||||
Vector2 subPosition = Submarine == null ? Vector2.Zero : Submarine.HiddenSubPosition;
|
||||
|
||||
|
||||
element.Add(new XAttribute("rect",
|
||||
(int)(rect.X - subPosition.X) + "," +
|
||||
(int)(rect.Y - subPosition.Y) + "," +
|
||||
rect.Width + "," + rect.Height));
|
||||
defaultRect.Width + "," + defaultRect.Height));
|
||||
|
||||
if (linkedTo != null && linkedTo.Count > 0)
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace Barotrauma
|
||||
class Entity : ISpatialEntity
|
||||
{
|
||||
public const ushort NullEntityID = 0;
|
||||
public const ushort EntitySpawnerID = ushort.MaxValue;
|
||||
|
||||
private static Dictionary<ushort, Entity> dictionary = new Dictionary<ushort, Entity>();
|
||||
public static List<Entity> GetEntityList()
|
||||
@@ -43,12 +44,19 @@ namespace Barotrauma
|
||||
}
|
||||
set
|
||||
{
|
||||
if (this is EntitySpawner) { return; }
|
||||
if (value == NullEntityID)
|
||||
{
|
||||
DebugConsole.ThrowError("Cannot set the ID of an entity to " + NullEntityID +
|
||||
"! The value is reserved for entity events referring to a non-existent (e.g. removed) entity.\n" + Environment.StackTrace);
|
||||
return;
|
||||
}
|
||||
if (value == EntitySpawnerID)
|
||||
{
|
||||
DebugConsole.ThrowError("Cannot set the ID of an entity to " + EntitySpawnerID +
|
||||
"! The value is reserved for EntitySpawner.\n" + Environment.StackTrace);
|
||||
return;
|
||||
}
|
||||
|
||||
if (dictionary.TryGetValue(id, out Entity thisEntity) && thisEntity == this)
|
||||
{
|
||||
@@ -107,15 +115,17 @@ namespace Barotrauma
|
||||
this.Submarine = submarine;
|
||||
|
||||
//give a unique ID
|
||||
id = FindFreeID(submarine == null ? (ushort)1 : submarine.IdOffset);
|
||||
|
||||
id = this is EntitySpawner ?
|
||||
EntitySpawnerID :
|
||||
FindFreeID(submarine == null ? (ushort)1 : submarine.IdOffset);
|
||||
|
||||
dictionary.Add(id, this);
|
||||
}
|
||||
|
||||
public static ushort FindFreeID(ushort idOffset = 0)
|
||||
{
|
||||
//ushort.MaxValue - 1 because 0 is a reserved value
|
||||
if (dictionary.Count >= ushort.MaxValue - 1)
|
||||
//ushort.MaxValue - 2 because 0 and ushort.MaxValue are reserved values
|
||||
if (dictionary.Count >= ushort.MaxValue - 2)
|
||||
{
|
||||
throw new Exception("Maximum amount of entities (" + (ushort.MaxValue - 1) + ") reached!");
|
||||
}
|
||||
|
||||
@@ -228,7 +228,11 @@ namespace Barotrauma
|
||||
attacker = item.GetComponent<Projectile>()?.User;
|
||||
if (attacker == null) attacker = item.GetComponent<MeleeWeapon>()?.User;
|
||||
}
|
||||
c.AddDamage(limb.WorldPosition, modifiedAfflictions, attack.Stun * distFactor, false, attacker: attacker);
|
||||
|
||||
//use a position slightly from the limb's position towards the explosion
|
||||
//ensures that the attack hits the correct limb and that the direction of the hit can be determined correctly in the AddDamage methods
|
||||
Vector2 hitPos = limb.WorldPosition + (worldPosition - limb.WorldPosition) / dist * 0.01f;
|
||||
c.AddDamage(hitPos, modifiedAfflictions, attack.Stun * distFactor, false, attacker: attacker);
|
||||
|
||||
if (attack.StatusEffects != null && attack.StatusEffects.Any())
|
||||
{
|
||||
|
||||
@@ -122,6 +122,8 @@ namespace Barotrauma
|
||||
|
||||
GapList.Add(this);
|
||||
InsertToList();
|
||||
|
||||
DebugConsole.Log("Created gap (" + ID + ")");
|
||||
}
|
||||
|
||||
public override MapEntity Clone()
|
||||
|
||||
@@ -242,6 +242,8 @@ namespace Barotrauma
|
||||
WaterVolume = 0.0f;
|
||||
|
||||
InsertToList();
|
||||
|
||||
DebugConsole.Log("Created hull (" + ID + ")");
|
||||
}
|
||||
|
||||
public static Rectangle GetBorders()
|
||||
|
||||
@@ -107,7 +107,7 @@ namespace Barotrauma
|
||||
if (Screen.Selected == GameMain.SubEditorScreen)
|
||||
{
|
||||
MapEntity.SelectedList.Clear();
|
||||
MapEntity.SelectedList.AddRange(entities);
|
||||
entities.ForEach(e => MapEntity.AddSelection(e));
|
||||
}
|
||||
#endif
|
||||
return entities;
|
||||
|
||||
@@ -1274,6 +1274,8 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
DebugConsole.Log("Generating level resources...");
|
||||
|
||||
for (int i = 0; i < generationParams.ItemCount; i++)
|
||||
{
|
||||
var selectedPrefab = ToolBox.SelectWeightedRandom(
|
||||
@@ -1286,6 +1288,7 @@ namespace Barotrauma
|
||||
var selectedEdge = selectedCell.Edges.GetRandom(e => e.IsSolid && !e.OutsideLevel, Rand.RandSync.Server);
|
||||
if (selectedEdge == null) continue;
|
||||
|
||||
|
||||
float edgePos = Rand.Range(0.0f, 1.0f, Rand.RandSync.Server);
|
||||
Vector2 selectedPos = Vector2.Lerp(selectedEdge.Point1, selectedEdge.Point2, edgePos);
|
||||
Vector2 edgeNormal = selectedEdge.GetNormal(selectedCell);
|
||||
@@ -1306,6 +1309,8 @@ namespace Barotrauma
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
DebugConsole.Log("Level resources generated");
|
||||
}
|
||||
|
||||
public Vector2 GetRandomItemPos(PositionType spawnPosType, float randomSpread, float minDistFromSubs, float offsetFromWall = 10.0f)
|
||||
|
||||
@@ -1022,12 +1022,12 @@ namespace Barotrauma.RuinGeneration
|
||||
{
|
||||
targetEntity = ruinEntities.GetRandom(e =>
|
||||
e.Room == targetRoom &&
|
||||
e.Entity.prefab?.Identifier == connection.TargetEntityIdentifier)?.Entity;
|
||||
e.Entity.prefab?.Identifier == connection.TargetEntityIdentifier, Rand.RandSync.Server)?.Entity;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
targetEntity = ruinEntities.GetRandom(e => e.Entity.prefab?.Identifier == connection.TargetEntityIdentifier)?.Entity;
|
||||
targetEntity = ruinEntities.GetRandom(e => e.Entity.prefab?.Identifier == connection.TargetEntityIdentifier, Rand.RandSync.Server)?.Entity;
|
||||
}
|
||||
|
||||
if (targetEntity == null) continue;
|
||||
|
||||
@@ -57,6 +57,8 @@ namespace Barotrauma
|
||||
linkedToID = new List<ushort>();
|
||||
|
||||
InsertToList();
|
||||
|
||||
DebugConsole.Log("Created linked submarine (" + ID + ")");
|
||||
}
|
||||
|
||||
public static LinkedSubmarine CreateDummy(Submarine mainSub, Submarine linkedSub)
|
||||
|
||||
@@ -207,20 +207,22 @@ namespace Barotrauma
|
||||
//clone links between the entities
|
||||
for (int i = 0; i < clones.Count; i++)
|
||||
{
|
||||
if (entitiesToClone[i].linkedTo == null) continue;
|
||||
if (entitiesToClone[i].linkedTo == null) { continue; }
|
||||
foreach (MapEntity linked in entitiesToClone[i].linkedTo)
|
||||
{
|
||||
if (!entitiesToClone.Contains(linked)) continue;
|
||||
|
||||
if (!entitiesToClone.Contains(linked)) { continue; }
|
||||
clones[i].linkedTo.Add(clones[entitiesToClone.IndexOf(linked)]);
|
||||
}
|
||||
}
|
||||
|
||||
//connect clone wires to the clone items
|
||||
//connect clone wires to the clone items and refresh links between doors and gaps
|
||||
for (int i = 0; i < clones.Count; i++)
|
||||
{
|
||||
var cloneItem = clones[i] as Item;
|
||||
if (cloneItem == null) continue;
|
||||
if (cloneItem == null) { continue; }
|
||||
|
||||
var door = cloneItem.GetComponent<Door>();
|
||||
if (door != null) { door.RefreshLinkedGap(); }
|
||||
|
||||
var cloneWire = cloneItem.GetComponent<Wire>();
|
||||
if (cloneWire == null) continue;
|
||||
@@ -231,7 +233,7 @@ namespace Barotrauma
|
||||
|
||||
for (int n = 0; n < 2; n++)
|
||||
{
|
||||
if (originalWire.Connections[n] == null) continue;
|
||||
if (originalWire.Connections[n] == null) { continue; }
|
||||
|
||||
var connectedItem = originalWire.Connections[n].Item;
|
||||
if (connectedItem == null) continue;
|
||||
@@ -555,7 +557,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
[Serialize(1f, false), Editable(0.1f, 10f, DecimalCount = 3, ValueStep = 0.1f)]
|
||||
[Serialize(1f, true), Editable(0.1f, 10f, DecimalCount = 3, ValueStep = 0.1f)]
|
||||
public virtual float Scale { get; set; } = 1;
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -183,6 +183,29 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected Vector2 textureScale = Vector2.One;
|
||||
|
||||
[Editable(DecimalCount = 3, MinValueFloat = 0.01f, MaxValueFloat = 10f, ValueStep = 0.1f), Serialize("1.0, 1.0", false)]
|
||||
public Vector2 TextureScale
|
||||
{
|
||||
get { return textureScale; }
|
||||
set
|
||||
{
|
||||
textureScale = new Vector2(
|
||||
MathHelper.Clamp(value.X, 0.01f, 10),
|
||||
MathHelper.Clamp(value.Y, 0.01f, 10));
|
||||
}
|
||||
}
|
||||
|
||||
protected Vector2 textureOffset = Vector2.Zero;
|
||||
[Editable(MinValueFloat = -1000f, MaxValueFloat = 1000f, ValueStep = 10f), Serialize("0.0, 0.0", true)]
|
||||
public Vector2 TextureOffset
|
||||
{
|
||||
get { return textureOffset; }
|
||||
set { textureOffset = value; }
|
||||
}
|
||||
|
||||
private Rectangle defaultRect;
|
||||
|
||||
public override Rectangle Rect
|
||||
@@ -296,9 +319,8 @@ namespace Barotrauma
|
||||
defaultRect = rectangle;
|
||||
|
||||
rect = rectangle;
|
||||
#if CLIENT
|
||||
TextureScale = sp.TextureScale;
|
||||
#endif
|
||||
|
||||
spriteColor = prefab.SpriteColor;
|
||||
if (sp.IsHorizontal.HasValue)
|
||||
{
|
||||
@@ -355,6 +377,8 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
InsertToList();
|
||||
|
||||
DebugConsole.Log("Created " + Name + " (" + ID + ")");
|
||||
}
|
||||
|
||||
partial void InitProjSpecific();
|
||||
|
||||
@@ -365,7 +365,9 @@ namespace Barotrauma
|
||||
{
|
||||
using (MemoryStream mem = new MemoryStream(Convert.FromBase64String(previewImageData)))
|
||||
{
|
||||
PreviewImage = new Sprite(TextureLoader.FromStream(mem, preMultiplyAlpha: false), null, null);
|
||||
var texture = TextureLoader.FromStream(mem, preMultiplyAlpha: false, path: filePath);
|
||||
if (texture == null) { throw new Exception("PreviewImage texture returned null"); }
|
||||
PreviewImage = new Sprite(texture, null, null);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -382,7 +384,6 @@ namespace Barotrauma
|
||||
|
||||
DockedTo = new List<Submarine>();
|
||||
|
||||
ID = ushort.MaxValue;
|
||||
FreeID();
|
||||
}
|
||||
|
||||
@@ -1405,7 +1406,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
|
||||
ID = (ushort)(ushort.MaxValue - Submarine.loaded.IndexOf(this));
|
||||
ID = (ushort)(ushort.MaxValue - 1 - Submarine.loaded.IndexOf(this));
|
||||
}
|
||||
|
||||
public static Submarine Load(XElement element, bool unloadPrevious)
|
||||
@@ -1553,7 +1554,7 @@ namespace Barotrauma
|
||||
if (MainSub == this) MainSub = null;
|
||||
if (MainSubs[1] == this) MainSubs[1] = null;
|
||||
|
||||
DockedTo.Clear();
|
||||
DockedTo?.Clear();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
||||
@@ -125,6 +125,8 @@ namespace Barotrauma
|
||||
InsertToList();
|
||||
WayPointList.Add(this);
|
||||
|
||||
DebugConsole.Log("Created waypoint (" + ID + ")");
|
||||
|
||||
currentHull = Hull.FindHull(WorldPosition);
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,11 @@ namespace Barotrauma.Networking
|
||||
get { return "ServerSettings"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Have some of the properties listed in the server list changed
|
||||
/// </summary>
|
||||
public bool ServerDetailsChanged;
|
||||
|
||||
public class SavedClientPermission
|
||||
{
|
||||
public readonly string IP;
|
||||
@@ -277,7 +282,17 @@ namespace Barotrauma.Networking
|
||||
|
||||
public string ServerName;
|
||||
|
||||
public string ServerMessageText;
|
||||
private string serverMessageText;
|
||||
public string ServerMessageText
|
||||
{
|
||||
get { return serverMessageText; }
|
||||
set
|
||||
{
|
||||
if (serverMessageText == value) { return; }
|
||||
serverMessageText = value;
|
||||
ServerDetailsChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
public int Port;
|
||||
|
||||
@@ -370,19 +385,19 @@ namespace Barotrauma.Networking
|
||||
private set;
|
||||
}
|
||||
|
||||
private bool allowSpectating;
|
||||
[Serialize(true, true)]
|
||||
public bool AllowSpectating
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
get { return allowSpectating; }
|
||||
private set
|
||||
{
|
||||
if (allowSpectating == value) { return; }
|
||||
allowSpectating = value;
|
||||
ServerDetailsChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
[Serialize(true, true)]
|
||||
public bool VoipEnabled {
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
|
||||
[Serialize(true, true)]
|
||||
public bool EndRoundAtLevelEnd
|
||||
{
|
||||
@@ -411,11 +426,17 @@ namespace Barotrauma.Networking
|
||||
private set;
|
||||
}
|
||||
|
||||
private bool voiceChatEnabled;
|
||||
[Serialize(true, true)]
|
||||
public bool VoiceChatEnabled
|
||||
{
|
||||
get;
|
||||
set;
|
||||
get { return voiceChatEnabled; }
|
||||
set
|
||||
{
|
||||
if (voiceChatEnabled == value) { return; }
|
||||
voiceChatEnabled = value;
|
||||
ServerDetailsChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
[Serialize(800, true)]
|
||||
@@ -473,11 +494,17 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
private bool allowRespawn;
|
||||
[Serialize(true, true)]
|
||||
public bool AllowRespawn
|
||||
{
|
||||
get;
|
||||
set;
|
||||
get { return allowRespawn; ; }
|
||||
set
|
||||
{
|
||||
if (allowRespawn == value) { return; }
|
||||
allowRespawn = value;
|
||||
ServerDetailsChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
[Serialize(0, true)]
|
||||
@@ -513,10 +540,16 @@ namespace Barotrauma.Networking
|
||||
set;
|
||||
}
|
||||
|
||||
private YesNoMaybe traitorsEnabled;
|
||||
public YesNoMaybe TraitorsEnabled
|
||||
{
|
||||
get;
|
||||
set;
|
||||
get { return traitorsEnabled; }
|
||||
set
|
||||
{
|
||||
if (traitorsEnabled == value) { return; }
|
||||
traitorsEnabled = value;
|
||||
ServerDetailsChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
private SelectionMode subSelectionMode;
|
||||
@@ -528,6 +561,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
subSelectionMode = value;
|
||||
Voting.AllowSubVoting = subSelectionMode == SelectionMode.Vote;
|
||||
ServerDetailsChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -540,6 +574,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
modeSelectionMode = value;
|
||||
Voting.AllowModeVoting = modeSelectionMode == SelectionMode.Vote;
|
||||
ServerDetailsChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -611,6 +646,7 @@ namespace Barotrauma.Networking
|
||||
public int MaxPlayers
|
||||
{
|
||||
get { return maxPlayers; }
|
||||
set { maxPlayers = MathHelper.Clamp(value, 1, NetConfig.MaxPlayers); }
|
||||
}
|
||||
|
||||
public List<MissionType> AllowedRandomMissionTypes
|
||||
@@ -635,7 +671,14 @@ namespace Barotrauma.Networking
|
||||
|
||||
public void SetPassword(string password)
|
||||
{
|
||||
this.password = Encoding.UTF8.GetString(NetUtility.ComputeSHAHash(Encoding.UTF8.GetBytes(password)));
|
||||
if (string.IsNullOrEmpty(password))
|
||||
{
|
||||
this.password = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
this.password = Encoding.UTF8.GetString(NetUtility.ComputeSHAHash(Encoding.UTF8.GetBytes(password)));
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsPasswordCorrect(string input, int nonce)
|
||||
|
||||
@@ -198,7 +198,7 @@ namespace Voronoi2
|
||||
{
|
||||
foreach (GraphEdge edge in Edges)
|
||||
{
|
||||
if (MathUtils.LinesIntersect(point, Center, edge.Point1, edge.Point2)) return false;
|
||||
if (MathUtils.LinesIntersect(point, Center, edge.Point1 + Translation, edge.Point2 + Translation)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -102,6 +102,14 @@ namespace Barotrauma
|
||||
partial void LoadTexture(ref Vector4 sourceVector, ref bool shouldReturn, bool premultiplyAlpha = true);
|
||||
partial void CalculateSourceRect();
|
||||
|
||||
private static void AddToList(Sprite elem)
|
||||
{
|
||||
lock (list)
|
||||
{
|
||||
list.Add(elem);
|
||||
}
|
||||
}
|
||||
|
||||
public Sprite(XElement element, string path = "", string file = "", bool? preMultiplyAlpha = null, bool lazyLoad = false)
|
||||
{
|
||||
this.lazyLoad = lazyLoad;
|
||||
@@ -128,7 +136,7 @@ namespace Barotrauma
|
||||
RelativeOrigin = SourceElement.GetAttributeVector2("origin", new Vector2(0.5f, 0.5f));
|
||||
Depth = SourceElement.GetAttributeFloat("depth", 0.001f);
|
||||
ID = GetID(SourceElement);
|
||||
list.Add(this);
|
||||
AddToList(this);
|
||||
}
|
||||
|
||||
internal void LoadParams(SpriteParams spriteParams, bool isFlipped)
|
||||
@@ -147,13 +155,13 @@ namespace Barotrauma
|
||||
public Sprite(string newFile, Vector2 newOrigin, bool preMultiplyAlpha = true)
|
||||
{
|
||||
Init(newFile, newOrigin: newOrigin, preMultiplyAlpha: preMultiplyAlpha);
|
||||
list.Add(this);
|
||||
AddToList(this);
|
||||
}
|
||||
|
||||
public Sprite(string newFile, Rectangle? sourceRectangle, Vector2? origin = null, float rotation = 0, bool preMultiplyAlpha = true)
|
||||
{
|
||||
Init(newFile, sourceRectangle: sourceRectangle, newOrigin: origin, newRotation: rotation, preMultiplyAlpha: preMultiplyAlpha);
|
||||
list.Add(this);
|
||||
AddToList(this);
|
||||
}
|
||||
|
||||
private void Init(string newFile, Rectangle? sourceRectangle = null, Vector2? newOrigin = null, Vector2? newOffset = null, float newRotation = 0,
|
||||
@@ -198,7 +206,10 @@ namespace Barotrauma
|
||||
|
||||
public void Remove()
|
||||
{
|
||||
list.Remove(this);
|
||||
lock (list)
|
||||
{
|
||||
list.Remove(this);
|
||||
}
|
||||
|
||||
DisposeTexture();
|
||||
}
|
||||
|
||||
@@ -640,14 +640,14 @@ namespace Barotrauma
|
||||
character.LastDamageSource = entity;
|
||||
foreach (Limb limb in character.AnimController.Limbs)
|
||||
{
|
||||
limb.character.DamageLimb(entity.WorldPosition, limb, new List<Affliction>() { multipliedAffliction }, stun: 0.0f, playSound: false, attackImpulse: 0.0f);
|
||||
limb.character.DamageLimb(entity.WorldPosition, limb, new List<Affliction>() { multipliedAffliction }, stun: 0.0f, playSound: false, attackImpulse: 0.0f, attacker: affliction.Source);
|
||||
//only apply non-limb-specific afflictions to the first limb
|
||||
if (!affliction.Prefab.LimbSpecific) { break; }
|
||||
}
|
||||
}
|
||||
else if (target is Limb limb)
|
||||
{
|
||||
limb.character.DamageLimb(entity.WorldPosition, limb, new List<Affliction>() { multipliedAffliction }, stun: 0.0f, playSound: false, attackImpulse: 0.0f);
|
||||
limb.character.DamageLimb(entity.WorldPosition, limb, new List<Affliction>() { multipliedAffliction }, stun: 0.0f, playSound: false, attackImpulse: 0.0f, attacker: affliction.Source);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -311,11 +311,9 @@ namespace Barotrauma
|
||||
{
|
||||
if (gameSession.Mission is CombatMission combatMission)
|
||||
{
|
||||
#if CLIENT
|
||||
//all characters that are alive and in the winning team get an achievement
|
||||
UnlockAchievement(gameSession.Mission.Prefab.AchievementIdentifier + (int)GameMain.GameSession.WinningTeam, true,
|
||||
c => c != null && !c.IsDead && !c.IsUnconscious && combatMission.IsInWinningTeam(c));
|
||||
#endif
|
||||
}
|
||||
else if (gameSession.Mission.Completed)
|
||||
{
|
||||
|
||||
@@ -210,8 +210,8 @@ namespace Barotrauma
|
||||
/// </summary>
|
||||
public static float GetMidAngle(float from, float to)
|
||||
{
|
||||
float max = MathHelper.Max(from, to);
|
||||
float min = MathHelper.Min(from, to);
|
||||
float max = Math.Max(from, to);
|
||||
float min = Math.Min(from, to);
|
||||
float diff = max - min;
|
||||
if (from < to)
|
||||
{
|
||||
|
||||
@@ -378,8 +378,6 @@ namespace Barotrauma
|
||||
Thread.Sleep(250);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -470,7 +468,20 @@ namespace Barotrauma
|
||||
foreach (DirectoryInfo di in dir.GetDirectories())
|
||||
{
|
||||
ClearFolder(di.FullName, ignoredFileNames);
|
||||
di.Delete();
|
||||
int maxRetries = 4;
|
||||
for (int i = 0; i <= maxRetries; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
di.Delete();
|
||||
break;
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
if (i >= maxRetries) { throw; }
|
||||
Thread.Sleep(250);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user