Unstable 0.1400.2.0 (a mimir edition)
This commit is contained in:
@@ -538,16 +538,18 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (hull.Submarine != subs[i]) continue;
|
||||
if (hull.WorldRect.Y < hullRects[i].Y - hullRects[i].Height) continue;
|
||||
if (hull.WorldRect.Y - hull.WorldRect.Height > hullRects[i].Y) continue;
|
||||
if (hull.Submarine != subs[i]) { continue; }
|
||||
if (hull.WorldRect.Y - 5 < hullRects[i].Y - hullRects[i].Height) { continue; }
|
||||
if (hull.WorldRect.Y - hull.WorldRect.Height + 5 > hullRects[i].Y) { continue; }
|
||||
|
||||
if (i == 0) //left hull
|
||||
{
|
||||
if (hull.WorldPosition.X > hullRects[0].Center.X) { continue; }
|
||||
leftSubRightSide = Math.Max(hull.WorldRect.Right, leftSubRightSide);
|
||||
}
|
||||
else //upper hull
|
||||
{
|
||||
if (hull.WorldPosition.X < hullRects[1].Center.X) { continue; }
|
||||
rightSubLeftSide = Math.Min(hull.WorldRect.X, rightSubLeftSide);
|
||||
}
|
||||
}
|
||||
@@ -591,8 +593,11 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
int expand = 5;
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
hullRects[i].X -= expand;
|
||||
hullRects[i].Width += expand * 2;
|
||||
hullRects[i].Location -= MathUtils.ToPoint((subs[i].WorldPosition - subs[i].HiddenSubPosition));
|
||||
hulls[i] = new Hull(MapEntityPrefab.Find(null, "hull"), hullRects[i], subs[i]);
|
||||
hulls[i].AddToGrid(subs[i]);
|
||||
@@ -636,16 +641,18 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (hull.Submarine != subs[i]) continue;
|
||||
if (hull.WorldRect.Right < hullRects[i].X) continue;
|
||||
if (hull.WorldRect.X > hullRects[i].Right) continue;
|
||||
if (hull.Submarine != subs[i]) { continue; }
|
||||
if (hull.WorldRect.Right - 5 < hullRects[i].X) { continue; }
|
||||
if (hull.WorldRect.X + 5 > hullRects[i].Right) { continue; }
|
||||
|
||||
if (i == 0) //lower hull
|
||||
{
|
||||
if (hull.WorldPosition.Y > hullRects[i].Y - hullRects[i].Height / 2) { continue; }
|
||||
lowerSubTop = Math.Max(hull.WorldRect.Y, lowerSubTop);
|
||||
}
|
||||
else //upper hull
|
||||
{
|
||||
if (hull.WorldPosition.Y < hullRects[i].Y - hullRects[i].Height / 2) { continue; }
|
||||
upperSubBottom = Math.Min(hull.WorldRect.Y - hull.WorldRect.Height, upperSubBottom);
|
||||
}
|
||||
}
|
||||
@@ -705,8 +712,11 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
|
||||
int expand = 5;
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
hullRects[i].Y += expand;
|
||||
hullRects[i].Height += expand * 2;
|
||||
hullRects[i].Location -= MathUtils.ToPoint((subs[i].WorldPosition - subs[i].HiddenSubPosition));
|
||||
hulls[i] = new Hull(MapEntityPrefab.Find(null, "hull"), hullRects[i], subs[i]);
|
||||
hulls[i].AddToGrid(subs[i]);
|
||||
|
||||
@@ -663,7 +663,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
else
|
||||
{
|
||||
return Item.GetConnectedComponents<Controller>(true).Any(b => b.HasAccess(character));
|
||||
return base.HasAccess(character) && Item.GetConnectedComponents<Controller>(true).Any(b => b.HasAccess(character));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,6 +69,7 @@ namespace Barotrauma.Items.Components
|
||||
item.IsShootable = true;
|
||||
// TODO: should define this in xml if we have ranged weapons that don't require aim to use
|
||||
item.RequireAimToUse = true;
|
||||
characterUsable = true;
|
||||
InitProjSpecific(element);
|
||||
}
|
||||
|
||||
|
||||
@@ -660,7 +660,7 @@ namespace Barotrauma.Items.Components
|
||||
/// </summary>
|
||||
public virtual bool HasAccess(Character character)
|
||||
{
|
||||
if (item.IgnoreByAI) { return false; }
|
||||
if (character.IsBot && item.IgnoreByAI(character)) { return false; }
|
||||
if (!item.IsInteractable(character)) { return false; }
|
||||
if (requiredItems.None()) { return true; }
|
||||
if (character.Inventory != null)
|
||||
|
||||
@@ -22,6 +22,8 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
private bool alwaysContainedItemsSpawned;
|
||||
|
||||
public ItemInventory Inventory;
|
||||
|
||||
private readonly List<ActiveContainedItem> activeContainedItems = new List<ActiveContainedItem>();
|
||||
@@ -208,6 +210,11 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(SpawnWithId) && !alwaysContainedItemsSpawned)
|
||||
{
|
||||
SpawnAlwaysContainedItems();
|
||||
}
|
||||
|
||||
if (item.ParentInventory is CharacterInventory)
|
||||
{
|
||||
item.SetContainedItemPositions();
|
||||
@@ -418,11 +425,13 @@ namespace Barotrauma.Items.Components
|
||||
if (!isEditor && (Entity.Spawner == null || Entity.Spawner.Removed) && GameMain.NetworkMember == null)
|
||||
{
|
||||
var spawnedItem = new Item(prefab, Vector2.Zero, null);
|
||||
Inventory.TryPutItem(spawnedItem, null, spawnedItem.AllowedSlots, createNetworkEvent: false);
|
||||
Inventory.TryPutItem(spawnedItem, null, spawnedItem.AllowedSlots, createNetworkEvent: false);
|
||||
alwaysContainedItemsSpawned = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Entity.Spawner?.AddToSpawnQueue(prefab, Inventory, spawnIfInventoryFull: false);
|
||||
IsActive = true;
|
||||
Entity.Spawner?.AddToSpawnQueue(prefab, Inventory, spawnIfInventoryFull: false, onSpawned: (Item item) => { alwaysContainedItemsSpawned = true; });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,19 +326,24 @@ namespace Barotrauma.Items.Components
|
||||
tolerance = MathHelper.Lerp(5.0f, 20.0f, degreeOfSuccess);
|
||||
allowedTurbineOutput = new Vector2(correctTurbineOutput - tolerance, correctTurbineOutput + tolerance);
|
||||
|
||||
DebugConsole.Log($"Degree of success: {degreeOfSuccess}");
|
||||
DebugConsole.Log($"Current load: {currentLoad}");
|
||||
DebugConsole.Log($"Max power output: {MaxPowerOutput}");
|
||||
DebugConsole.Log($"Available fuel: {AvailableFuel}");
|
||||
|
||||
float desiredTurbineOutput = MathHelper.Clamp(correctTurbineOutput, 0.0f, 100.0f);
|
||||
DebugConsole.Log($"Turbine output reset: {targetTurbineOutput}, {turbineOutput} -> {desiredTurbineOutput}");
|
||||
targetTurbineOutput = desiredTurbineOutput;
|
||||
turbineOutput = desiredTurbineOutput;
|
||||
|
||||
float desiredFissionRate = (optimalFissionRate.X + optimalFissionRate.Y) / 2.0f;
|
||||
DebugConsole.Log($"Fission rate reset: {targetFissionRate}, {fissionRate} -> {desiredFissionRate}");
|
||||
targetFissionRate = desiredFissionRate;
|
||||
fissionRate = desiredFissionRate;
|
||||
|
||||
float desiredTemperature = (optimalTemperature.X + optimalTemperature.Y) / 2.0f;
|
||||
DebugConsole.Log($"Temperature reset: {temperature} -> {desiredTemperature}");
|
||||
temperature = desiredTemperature;
|
||||
|
||||
float desiredFissionRate = GetFissionRateForTargetTemperatureAndTurbineOutput(desiredTemperature, desiredTurbineOutput);
|
||||
DebugConsole.Log($"Fission rate reset: {targetFissionRate}, {fissionRate} -> {desiredFissionRate}");
|
||||
targetFissionRate = desiredFissionRate;
|
||||
fissionRate = desiredFissionRate;
|
||||
}
|
||||
|
||||
loadQueue.Enqueue(currentLoad);
|
||||
@@ -420,6 +425,12 @@ namespace Barotrauma.Items.Components
|
||||
return fissionRate * (prevAvailableFuel / 100.0f) * 2.0f;
|
||||
}
|
||||
|
||||
private float GetFissionRateForTargetTemperatureAndTurbineOutput(float temperature, float turbineOutput)
|
||||
{
|
||||
if (MathUtils.NearlyEqual(AvailableFuel, 0f)) { return 0f; }
|
||||
return (temperature + turbineOutput) / (AvailableFuel / 100f) / 2f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Do we need more fuel to generate enough power to match the current load.
|
||||
/// </summary>
|
||||
|
||||
@@ -44,6 +44,8 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private readonly Queue<Impact> impactQueue = new Queue<Impact>();
|
||||
|
||||
private bool removePending;
|
||||
|
||||
//continuous collision detection is used while the projectile is moving faster than this
|
||||
const float ContinuousCollisionThreshold = 5.0f;
|
||||
|
||||
@@ -274,10 +276,9 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (character != null && !characterUsable) { return false; }
|
||||
|
||||
|
||||
for (int i = 0; i < HitScanCount; i++)
|
||||
{
|
||||
float launchAngle = 0f;
|
||||
float launchAngle;
|
||||
|
||||
if (StaticSpread)
|
||||
{
|
||||
@@ -305,6 +306,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
else
|
||||
{
|
||||
item.body.SetTransform(item.body.SimPosition, launchAngle);
|
||||
float modifiedLaunchImpulse = LaunchImpulse * (1 + Rand.Range(-ImpulseSpread, ImpulseSpread));
|
||||
DoLaunch(launchDir * modifiedLaunchImpulse * item.body.Mass);
|
||||
}
|
||||
@@ -562,14 +564,17 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
ApplyStatusEffects(ActionType.OnActive, deltaTime, null);
|
||||
|
||||
while (impactQueue.Count > 0)
|
||||
{
|
||||
var impact = impactQueue.Dequeue();
|
||||
HandleProjectileCollision(impact.Fixture, impact.Normal, impact.LinearVelocity);
|
||||
}
|
||||
|
||||
if (!removePending)
|
||||
{
|
||||
ApplyStatusEffects(ActionType.OnActive, deltaTime, null);
|
||||
}
|
||||
|
||||
if (item.body != null && item.body.FarseerBody.IsBullet)
|
||||
{
|
||||
if (item.body.LinearVelocity.LengthSquared() < ContinuousCollisionThreshold * ContinuousCollisionThreshold)
|
||||
@@ -668,6 +673,10 @@ namespace Barotrauma.Items.Components
|
||||
hits.Add(target.Body);
|
||||
impactQueue.Enqueue(new Impact(target, contact.Manifold.LocalNormal, item.body.LinearVelocity));
|
||||
IsActive = true;
|
||||
if (RemoveOnHit)
|
||||
{
|
||||
item.body.FarseerBody.ResetDynamics();
|
||||
}
|
||||
if (hits.Count() >= MaxTargetsToHit || target.Body.UserData is VoronoiCell)
|
||||
{
|
||||
Deactivate();
|
||||
@@ -867,15 +876,10 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (RemoveOnHit)
|
||||
{
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient)
|
||||
{
|
||||
//clients aren't allowed to remove items by themselves, so lets hide the projectile until the server tells us to remove it
|
||||
item.HiddenInGame = Hitscan;
|
||||
}
|
||||
else
|
||||
{
|
||||
Entity.Spawner?.AddToRemoveQueue(item);
|
||||
}
|
||||
removePending = true;
|
||||
item.HiddenInGame = true;
|
||||
item.body.FarseerBody.Enabled = false;
|
||||
Entity.Spawner?.AddToRemoveQueue(item);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
private string[] labels;
|
||||
[Serialize("", true, description: "The texts displayed on the buttons/tickboxes, separated by commas.")]
|
||||
[Serialize("", true, description: "The texts displayed on the buttons/tickboxes, separated by commas.", alwaysUseInstanceValues: true)]
|
||||
public string Labels
|
||||
{
|
||||
get { return string.Join(",", labels); }
|
||||
@@ -111,7 +111,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
private string[] signals;
|
||||
[Serialize("", true, description: "The signals sent when the buttons are pressed or the tickboxes checked, separated by commas.")]
|
||||
[Serialize("", true, description: "The signals sent when the buttons are pressed or the tickboxes checked, separated by commas.", alwaysUseInstanceValues: true)]
|
||||
public string Signals
|
||||
{
|
||||
//use semicolon as a separator because comma may be needed in the signals (for color or vector values for example)
|
||||
|
||||
@@ -20,9 +20,10 @@ namespace Barotrauma.Items.Components
|
||||
private bool castShadows;
|
||||
private bool drawBehindSubs;
|
||||
|
||||
|
||||
private double lastToggleSignalTime;
|
||||
|
||||
private string prevColorSignal;
|
||||
|
||||
public PhysicsBody ParentBody;
|
||||
|
||||
private Turret turret;
|
||||
@@ -326,7 +327,11 @@ namespace Barotrauma.Items.Components
|
||||
IsOn = signal.value != "0";
|
||||
break;
|
||||
case "set_color":
|
||||
LightColor = XMLExtensions.ParseColor(signal.value, false);
|
||||
if (signal.value != prevColorSignal)
|
||||
{
|
||||
LightColor = XMLExtensions.ParseColor(signal.value, false);
|
||||
prevColorSignal = signal.value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,6 +164,7 @@ namespace Barotrauma.Items.Components
|
||||
if (Math.Abs(item.body.LinearVelocity.X) > MinimumVelocity || Math.Abs(item.body.LinearVelocity.Y) > MinimumVelocity)
|
||||
{
|
||||
MotionDetected = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,67 +174,93 @@ namespace Barotrauma.Items.Components
|
||||
float broadRangeY = Math.Max(rangeY * 2, 500);
|
||||
|
||||
if (item.CurrentHull == null && item.Submarine != null && Level.Loaded != null &&
|
||||
(Target == TargetType.Wall || Target == TargetType.Any) &&
|
||||
(Math.Abs(item.Submarine.Velocity.X) > MinimumVelocity || Math.Abs(item.Submarine.Velocity.Y) > MinimumVelocity))
|
||||
(Target == TargetType.Wall || Target == TargetType.Any))
|
||||
{
|
||||
var cells = Level.Loaded.GetCells(item.WorldPosition, 1);
|
||||
foreach (var cell in cells)
|
||||
if (Math.Abs(item.Submarine.Velocity.X) > MinimumVelocity || Math.Abs(item.Submarine.Velocity.Y) > MinimumVelocity)
|
||||
{
|
||||
if (cell.IsPointInside(item.WorldPosition))
|
||||
var cells = Level.Loaded.GetCells(item.WorldPosition, 1);
|
||||
foreach (var cell in cells)
|
||||
{
|
||||
MotionDetected = true;
|
||||
return;
|
||||
}
|
||||
foreach (var edge in cell.Edges)
|
||||
{
|
||||
var closestPoint = MathUtils.GetClosestPointOnLineSegment(edge.Point1 + cell.Translation, edge.Point2 + cell.Translation, item.WorldPosition);
|
||||
if (Math.Abs(closestPoint.X - item.WorldPosition.X) < rangeX && Math.Abs(closestPoint.Y - item.WorldPosition.Y) < rangeY)
|
||||
if (cell.IsPointInside(item.WorldPosition))
|
||||
{
|
||||
MotionDetected = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
foreach (var edge in cell.Edges)
|
||||
{
|
||||
Vector2 e1 = edge.Point1 + cell.Translation;
|
||||
Vector2 e2 = edge.Point2 + cell.Translation;
|
||||
if (MathUtils.LinesIntersect(e1, e2, new Vector2(detectRect.X, detectRect.Y), new Vector2(detectRect.Right, detectRect.Y)) ||
|
||||
MathUtils.LinesIntersect(e1, e2, new Vector2(detectRect.X, detectRect.Bottom), new Vector2(detectRect.Right, detectRect.Bottom)) ||
|
||||
MathUtils.LinesIntersect(e1, e2, new Vector2(detectRect.X, detectRect.Y), new Vector2(detectRect.X, detectRect.Bottom)) ||
|
||||
MathUtils.LinesIntersect(e1, e2, new Vector2(detectRect.Right, detectRect.Y), new Vector2(detectRect.Right, detectRect.Bottom)))
|
||||
{
|
||||
MotionDetected = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Character c in Character.CharacterList)
|
||||
{
|
||||
if (IgnoreDead && c.IsDead) { continue; }
|
||||
|
||||
//ignore characters that have spawned a second or less ago
|
||||
//makes it possible to detect when a spawned character moves without triggering the detector immediately as the ragdoll spawns and drops to the ground
|
||||
if (c.SpawnTime > Timing.TotalTime - 1.0) { continue; }
|
||||
|
||||
switch (Target)
|
||||
foreach (Submarine sub in Submarine.Loaded)
|
||||
{
|
||||
case TargetType.Human:
|
||||
if (!c.IsHuman) { continue; }
|
||||
break;
|
||||
case TargetType.Monster:
|
||||
if (c.IsHuman || c.IsPet) { continue; }
|
||||
break;
|
||||
case TargetType.Wall:
|
||||
break;
|
||||
}
|
||||
if (sub == item.Submarine) { continue; }
|
||||
|
||||
//do a rough check based on the position of the character's collider first
|
||||
//before the more accurate limb-based check
|
||||
if (Math.Abs(c.WorldPosition.X - detectPos.X) > broadRangeX || Math.Abs(c.WorldPosition.Y - detectPos.Y) > broadRangeY)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Vector2 relativeVelocity = item.Submarine.Velocity - sub.Velocity;
|
||||
if (Math.Abs(relativeVelocity.X) < MinimumVelocity && Math.Abs(relativeVelocity.Y) < MinimumVelocity) { continue; }
|
||||
|
||||
foreach (Limb limb in c.AnimController.Limbs)
|
||||
{
|
||||
if (limb.IsSevered) { continue; }
|
||||
if (limb.LinearVelocity.LengthSquared() <= MinimumVelocity * MinimumVelocity) { continue; }
|
||||
if (MathUtils.CircleIntersectsRectangle(limb.WorldPosition, ConvertUnits.ToDisplayUnits(limb.body.GetMaxExtent()), detectRect))
|
||||
Rectangle worldBorders = new Rectangle(
|
||||
sub.Borders.X + (int)sub.WorldPosition.X,
|
||||
sub.Borders.Y + (int)sub.WorldPosition.Y - sub.Borders.Height,
|
||||
sub.Borders.Width,
|
||||
sub.Borders.Height);
|
||||
|
||||
if (worldBorders.Intersects(detectRect))
|
||||
{
|
||||
MotionDetected = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Target != TargetType.Wall)
|
||||
{
|
||||
foreach (Character c in Character.CharacterList)
|
||||
{
|
||||
if (IgnoreDead && c.IsDead) { continue; }
|
||||
|
||||
//ignore characters that have spawned a second or less ago
|
||||
//makes it possible to detect when a spawned character moves without triggering the detector immediately as the ragdoll spawns and drops to the ground
|
||||
if (c.SpawnTime > Timing.TotalTime - 1.0) { continue; }
|
||||
|
||||
switch (Target)
|
||||
{
|
||||
case TargetType.Human:
|
||||
if (!c.IsHuman) { continue; }
|
||||
break;
|
||||
case TargetType.Monster:
|
||||
if (c.IsHuman || c.IsPet) { continue; }
|
||||
break;
|
||||
}
|
||||
|
||||
//do a rough check based on the position of the character's collider first
|
||||
//before the more accurate limb-based check
|
||||
if (Math.Abs(c.WorldPosition.X - detectPos.X) > broadRangeX || Math.Abs(c.WorldPosition.Y - detectPos.Y) > broadRangeY)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (Limb limb in c.AnimController.Limbs)
|
||||
{
|
||||
if (limb.IsSevered) { continue; }
|
||||
if (limb.LinearVelocity.LengthSquared() <= MinimumVelocity * MinimumVelocity) { continue; }
|
||||
if (MathUtils.CircleIntersectsRectangle(limb.WorldPosition, ConvertUnits.ToDisplayUnits(limb.body.GetMaxExtent()), detectRect))
|
||||
{
|
||||
MotionDetected = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void FlipX(bool relativeToSub)
|
||||
|
||||
@@ -15,8 +15,8 @@ namespace Barotrauma.Items.Components
|
||||
partial class Turret : Powered, IDrawableComponent, IServerSerializable
|
||||
{
|
||||
private Sprite barrelSprite, railSprite;
|
||||
private List<Tuple<Sprite, Vector2>> chargeSprites = new List<Tuple<Sprite, Vector2>>();
|
||||
private List<Sprite> spinningBarrelSprites = new List<Sprite>();
|
||||
private readonly List<(Sprite sprite, Vector2 position)> chargeSprites = new List<(Sprite sprite, Vector2 position)>();
|
||||
private readonly List<Sprite> spinningBarrelSprites = new List<Sprite>();
|
||||
|
||||
private Vector2 barrelPos;
|
||||
private Vector2 transformedBarrelPos;
|
||||
@@ -290,7 +290,7 @@ namespace Barotrauma.Items.Components
|
||||
railSprite = new Sprite(subElement);
|
||||
break;
|
||||
case "chargesprite":
|
||||
chargeSprites.Add(new Tuple<Sprite, Vector2>(new Sprite(subElement), subElement.GetAttributeVector2("chargetarget", Vector2.Zero)));
|
||||
chargeSprites.Add((new Sprite(subElement), subElement.GetAttributeVector2("chargetarget", Vector2.Zero)));
|
||||
break;
|
||||
case "spinningbarrelsprite":
|
||||
int spriteCount = subElement.GetAttributeInt("spriteamount", 1);
|
||||
@@ -1283,7 +1283,6 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private Vector2 GetRelativeFiringPosition(bool useOffset = true)
|
||||
{
|
||||
// i don't feel great about this method, should be evaluated again
|
||||
Vector2 transformedFiringOffset = Vector2.Zero;
|
||||
if (useOffset)
|
||||
{
|
||||
|
||||
@@ -202,7 +202,7 @@ namespace Barotrauma
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
class Wearable : Pickable, IServerSerializable
|
||||
partial class Wearable : Pickable, IServerSerializable
|
||||
{
|
||||
private readonly XElement[] wearableElements;
|
||||
private readonly WearableSprite[] wearableSprites;
|
||||
@@ -210,6 +210,7 @@ namespace Barotrauma.Items.Components
|
||||
private readonly Limb[] limb;
|
||||
|
||||
private readonly List<DamageModifier> damageModifiers;
|
||||
public readonly Dictionary<string, float> SkillModifiers;
|
||||
|
||||
public IEnumerable<DamageModifier> DamageModifiers
|
||||
{
|
||||
@@ -265,7 +266,8 @@ namespace Barotrauma.Items.Components
|
||||
this.item = item;
|
||||
|
||||
damageModifiers = new List<DamageModifier>();
|
||||
|
||||
SkillModifiers = new Dictionary<string, float>();
|
||||
|
||||
int spriteCount = element.Elements().Count(x => x.Name.ToString() == "sprite");
|
||||
Variants = element.GetAttributeInt("variants", 0);
|
||||
variant = Rand.Range(1, Variants + 1, Rand.RandSync.Server);
|
||||
@@ -308,6 +310,18 @@ namespace Barotrauma.Items.Components
|
||||
case "damagemodifier":
|
||||
damageModifiers.Add(new DamageModifier(subElement, item.Name + ", Wearable"));
|
||||
break;
|
||||
case "skillmodifier":
|
||||
string skillIdentifier = subElement.GetAttributeString("skillidentifier", string.Empty);
|
||||
float skillValue = subElement.GetAttributeFloat("skillvalue", 0f);
|
||||
if (SkillModifiers.ContainsKey(skillIdentifier))
|
||||
{
|
||||
SkillModifiers[skillIdentifier] += skillValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
SkillModifiers.TryAdd(skillIdentifier, skillValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -324,7 +338,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
var wearableSprite = wearableSprites[i];
|
||||
if (!wearableSprite.IsInitialized) { wearableSprite.Init(picker.Info?.Gender ?? Gender.None); }
|
||||
if (picker.Info?.Gender != Gender.None && (wearableSprite.Gender != Gender.None))
|
||||
if (picker.Info != null && picker.Info?.Gender != Gender.None && (wearableSprite.Gender != Gender.None))
|
||||
{
|
||||
// If the item is gender specific (it has a different textures for male and female), we have to change the gender here so that the texture is updated.
|
||||
wearableSprite.Gender = picker.Info.Gender;
|
||||
@@ -386,6 +400,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (character == null || character.Removed) { return; }
|
||||
if (picker == null) { return; }
|
||||
|
||||
for (int i = 0; i < wearableSprites.Length; i++)
|
||||
{
|
||||
Limb equipLimb = character.AnimController.GetLimb(limbType[i]);
|
||||
|
||||
Reference in New Issue
Block a user