(6eeea9b7c) v0.9.10.0.0

This commit is contained in:
Joonas Rikkonen
2020-06-04 16:41:07 +03:00
parent ce4ccd99ac
commit eeac247a8e
366 changed files with 7772 additions and 3692 deletions
@@ -3,6 +3,7 @@ using FarseerPhysics;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Dynamics.Contacts;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Xml.Linq;
@@ -309,8 +310,13 @@ namespace Barotrauma.Items.Components
{
picker = character;
if (character != null) item.Submarine = character.Submarine;
if (item.Removed)
{
DebugConsole.ThrowError($"Attempted to equip a removed item ({item.Name})\n" + Environment.StackTrace);
return;
}
if (character != null) { item.Submarine = character.Submarine; }
if (item.body == null)
{
if (body != null)
@@ -325,8 +331,8 @@ namespace Barotrauma.Items.Components
if (!item.body.Enabled)
{
Limb rightHand = picker.AnimController.GetLimb(LimbType.RightHand);
item.SetTransform(rightHand.SimPosition, 0.0f);
Limb hand = picker.AnimController.GetLimb(LimbType.RightHand) ?? picker.AnimController.GetLimb(LimbType.LeftHand);
item.SetTransform(hand != null ? hand.SimPosition : character.SimPosition, 0.0f);
}
bool alreadyEquipped = character.HasEquippedItem(item);
@@ -363,38 +369,61 @@ namespace Barotrauma.Items.Components
IsActive = false;
}
public bool CanBeAttached()
public bool CanBeAttached(Character user)
{
if (!attachable || !Reattachable) return false;
if (!attachable || !Reattachable) { return false; }
//can be attached anywhere in sub editor
if (Screen.Selected == GameMain.SubEditorScreen) return true;
if (Screen.Selected == GameMain.SubEditorScreen) { return true; }
Vector2 attachPos = user == null ? item.WorldPosition : GetAttachPosition(user, useWorldCoordinates: true);
//can be attached anywhere inside hulls
if (item.CurrentHull != null) return true;
if (item.CurrentHull != null && Submarine.RectContains(item.CurrentHull.WorldRect, attachPos)) { return true; }
return Structure.GetAttachTarget(item.WorldPosition) != null;
return Structure.GetAttachTarget(attachPos) != null;
}
public bool CanBeDeattached()
{
if (!attachable || !attached) return true;
if (!attachable || !attached) { return true; }
//allow deattaching everywhere in sub editor
if (Screen.Selected == GameMain.SubEditorScreen) return true;
if (Screen.Selected == GameMain.SubEditorScreen) { return true; }
//don't allow deattaching if part of a sub and outside hulls
return item.Submarine == null || item.CurrentHull != null;
if (item.GetComponent<LevelResource>() != null) { return true; }
//if the item has a connection panel and rewiring is disabled, don't allow deattaching
var connectionPanel = item.GetComponent<ConnectionPanel>();
if (connectionPanel != null && (connectionPanel.Locked || !(GameMain.NetworkMember?.ServerSettings?.AllowRewiring ?? true)))
{
return false;
}
if (item.CurrentHull == null)
{
return Structure.GetAttachTarget(item.WorldPosition) != null;
}
else
{
return true;
}
}
public override bool Pick(Character picker)
{
if (item.Removed)
{
DebugConsole.ThrowError($"Attempted to pick up a removed item ({item.Name})\n" + Environment.StackTrace);
return false;
}
if (!attachable)
{
return base.Pick(picker);
}
if (!CanBeDeattached()) return false;
if (!CanBeDeattached()) { return false; }
if (Attached)
{
@@ -486,7 +515,7 @@ namespace Barotrauma.Items.Components
if (character != null)
{
if (!character.IsKeyDown(InputType.Aim)) { return false; }
if (!CanBeAttached()) { return false; }
if (!CanBeAttached(character)) { return false; }
if (GameMain.NetworkMember != null)
{
@@ -515,7 +544,7 @@ namespace Barotrauma.Items.Components
else
{
item.Drop(character);
item.SetTransform(ConvertUnits.ToSimUnits(GetAttachPosition(character)), 0.0f);
item.SetTransform(ConvertUnits.ToSimUnits(GetAttachPosition(character)), 0.0f, findNewHull: false);
}
}
@@ -524,16 +553,18 @@ namespace Barotrauma.Items.Components
return true;
}
private Vector2 GetAttachPosition(Character user)
private Vector2 GetAttachPosition(Character user, bool useWorldCoordinates = false)
{
if (user == null) { return item.Position; }
if (user == null) { return useWorldCoordinates ? item.WorldPosition : item.Position; }
Vector2 mouseDiff = user.CursorWorldPosition - user.WorldPosition;
mouseDiff = mouseDiff.ClampLength(MaxAttachDistance);
Vector2 userPos = useWorldCoordinates ? user.WorldPosition : user.Position;
return new Vector2(
MathUtils.RoundTowardsClosest(user.Position.X + mouseDiff.X, Submarine.GridSize.X),
MathUtils.RoundTowardsClosest(user.Position.Y + mouseDiff.Y, Submarine.GridSize.Y));
MathUtils.RoundTowardsClosest(userPos.X + mouseDiff.X, Submarine.GridSize.X),
MathUtils.RoundTowardsClosest(userPos.Y + mouseDiff.Y, Submarine.GridSize.Y));
}
public override void UpdateBroken(float deltaTime, Camera cam)
@@ -95,6 +95,7 @@ namespace Barotrauma.Items.Components
{
foreach (Limb l in character.AnimController.Limbs)
{
if (l.IsSevered) { continue; }
if (l.type == LimbType.LeftFoot || l.type == LimbType.LeftThigh || l.type == LimbType.LeftLeg) { continue; }
if (l.type == LimbType.Head || l.type == LimbType.Torso)
{
@@ -65,7 +65,7 @@ namespace Barotrauma.Items.Components
if (PickingTime > 0.0f)
{
if (picker.PickingItem == null && PickingTime <= float.MaxValue)
if ((picker.PickingItem == null || picker.PickingItem == item) && PickingTime <= float.MaxValue)
{
#if SERVER
item.CreateServerEvent(this);
@@ -114,10 +114,6 @@ namespace Barotrauma.Items.Components
{
activePicker = picker;
picker.PickingItem = item;
var leftHand = picker.AnimController.GetLimb(LimbType.LeftHand);
var rightHand = picker.AnimController.GetLimb(LimbType.RightHand);
pickTimer = 0.0f;
while (pickTimer < requiredTime && Screen.Selected != GameMain.SubEditorScreen)
{
@@ -65,7 +65,7 @@ namespace Barotrauma.Items.Components
foreach (Limb limb in character.AnimController.Limbs)
{
if (limb.WearingItems.Find(w => w.WearableComponent.Item == this.item) == null) continue;
if (limb.WearingItems.Find(w => w.WearableComponent.Item == item) == null) { continue; }
limb.body.ApplyForce(propulsion, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
}
@@ -90,6 +90,7 @@ namespace Barotrauma.Items.Components
return MathHelper.ToRadians(MathHelper.Lerp(Spread, UnskilledSpread, degreeOfFailure));
}
private readonly List<Body> limbBodies = new List<Body>();
public override bool Use(float deltaTime, Character character = null)
{
if (character == null || character.Removed) { return false; }
@@ -104,9 +105,10 @@ namespace Barotrauma.Items.Components
item.AiTarget.SightRange = item.AiTarget.MaxSightRange;
}
List<Body> limbBodies = new List<Body>();
limbBodies.Clear();
foreach (Limb l in character.AnimController.Limbs)
{
if (l.IsSevered) { continue; }
limbBodies.Add(l.body.FarseerBody);
}
@@ -22,6 +22,8 @@ namespace Barotrauma.Items.Components
private Vector2 debugRayStartPos, debugRayEndPos;
private readonly List<Body> ignoredBodies = new List<Body>();
[Serialize("Both", false, description: "Can the item be used in air, water or both.")]
public UseEnvironment UsableIn
{
@@ -68,6 +70,12 @@ namespace Barotrauma.Items.Components
[Serialize(false, false, description: "Can the item repair things through holes in walls.")]
public bool RepairThroughHoles { get; set; }
[Serialize(true, false, description: "Can the item hit broken doors.")]
public bool HitItems { get; set; }
[Serialize(false, false, description: "Can the item hit broken doors.")]
public bool HitBrokenDoors { get; set; }
[Serialize(0.0f, false, description: "The probability of starting a fire somewhere along the ray fired from the barrel (for example, 0.1 = 10% chance to start a fire during a second of use).")]
public float FireProbability { get; set; }
@@ -114,8 +122,7 @@ namespace Barotrauma.Items.Components
}
}
item.IsShootable = true;
// TODO: should define this in xml if we have repair tools that don't require aim to use
item.RequireAimToUse = true;
item.RequireAimToUse = element.Parent.GetAttributeBool("requireaimtouse", true);
InitProjSpecific(element);
}
@@ -124,16 +131,17 @@ namespace Barotrauma.Items.Components
public override void Update(float deltaTime, Camera cam)
{
activeTimer -= deltaTime;
if (activeTimer <= 0.0f) IsActive = false;
if (activeTimer <= 0.0f) { IsActive = false; }
}
private List<Body> ignoredBodies = new List<Body>();
public override bool Use(float deltaTime, Character character = null)
{
if (character == null || character.Removed) return false;
if (item.RequireAimToUse && !character.IsKeyDown(InputType.Aim)) return false;
if (character != null)
{
if (item.RequireAimToUse && !character.IsKeyDown(InputType.Aim)) { return false; }
}
float degreeOfSuccess = DegreeOfSuccess(character);
float degreeOfSuccess = character == null ? 0.5f : DegreeOfSuccess(character);
if (Rand.Range(0.0f, 0.5f) > degreeOfSuccess)
{
@@ -187,12 +195,15 @@ namespace Barotrauma.Items.Components
(float)Math.Sin(angle)) * Range * item.body.Dir);
ignoredBodies.Clear();
foreach (Limb limb in character.AnimController.Limbs)
if (character != null)
{
if (Rand.Range(0.0f, 0.5f) > degreeOfSuccess) continue;
ignoredBodies.Add(limb.body.FarseerBody);
foreach (Limb limb in character.AnimController.Limbs)
{
if (Rand.Range(0.0f, 0.5f) > degreeOfSuccess) continue;
ignoredBodies.Add(limb.body.FarseerBody);
}
ignoredBodies.Add(character.AnimController.Collider.FarseerBody);
}
ignoredBodies.Add(character.AnimController.Collider.FarseerBody);
IsActive = true;
activeTimer = 0.1f;
@@ -200,7 +211,8 @@ namespace Barotrauma.Items.Components
debugRayStartPos = ConvertUnits.ToDisplayUnits(rayStart);
debugRayEndPos = ConvertUnits.ToDisplayUnits(rayEnd);
if (character.Submarine == null)
Submarine parentSub = character?.Submarine ?? item.Submarine;
if (parentSub == null)
{
foreach (Submarine sub in Submarine.Loaded)
{
@@ -216,7 +228,7 @@ namespace Barotrauma.Items.Components
}
else
{
Repair(rayStart - character.Submarine.SimPosition, rayEnd - character.Submarine.SimPosition, deltaTime, character, degreeOfSuccess, ignoredBodies);
Repair(rayStart - parentSub.SimPosition, rayEnd - parentSub.SimPosition, deltaTime, character, degreeOfSuccess, ignoredBodies);
}
UseProjSpecific(deltaTime, rayStart);
@@ -314,6 +326,18 @@ namespace Barotrauma.Items.Components
{
if (RepairThroughHoles && f.IsSensor && f.Body?.UserData is Structure) { return false; }
if (f.Body?.UserData as string == "ruinroom") { return false; }
if (f.Body?.UserData is Item targetItem)
{
if (!HitItems) { return false; }
if (HitBrokenDoors)
{
if (targetItem.GetComponent<Door>() == null && targetItem.Condition <= 0) { return false; }
}
else
{
if (targetItem.Condition <= 0) { return false; }
}
}
return f.Body?.UserData != null;
},
allowInsideFixture: true));
@@ -440,7 +464,8 @@ namespace Barotrauma.Items.Components
}
else if (targetBody.UserData is Item targetItem)
{
if (!HitItems) { return false; }
var levelResource = targetItem.GetComponent<LevelResource>();
if (levelResource != null && levelResource.Attached &&
levelResource.requiredItems.Any() &&
@@ -459,6 +484,15 @@ namespace Barotrauma.Items.Components
if (!targetItem.Prefab.DamagedByRepairTools) { return false; }
if (HitBrokenDoors)
{
if (targetItem.GetComponent<Door>() == null && targetItem.Condition <= 0) { return false; }
}
else
{
if (targetItem.Condition <= 0) { return false; }
}
targetItem.IsHighlighted = true;
ApplyStatusEffectsOnTarget(user, deltaTime, ActionType.OnUse, targetItem.AllPropertyObjects);
@@ -647,26 +681,26 @@ namespace Barotrauma.Items.Components
}
#if CLIENT
if (user == null) { return; }
// Hard-coded progress bars for welding doors stuck.
// A general purpose system could be better, but it would most likely require changes in the way we define the status effects in xml.
foreach (ISerializableEntity target in targets)
{
if (target is Door door)
if (!(target is Door door)) { continue; }
if (!door.CanBeWelded) { continue; }
for (int i = 0; i < effect.propertyNames.Length; i++)
{
if (!door.CanBeWelded) continue;
for (int i = 0; i < effect.propertyNames.Length; i++)
string propertyName = effect.propertyNames[i];
if (propertyName != "stuck") { continue; }
if (door.SerializableProperties == null || !door.SerializableProperties.TryGetValue(propertyName, out SerializableProperty property)) { continue; }
object value = property.GetValue(target);
if (door.Stuck > 0)
{
string propertyName = effect.propertyNames[i];
if (propertyName != "stuck") { continue; }
if (door.SerializableProperties == null || !door.SerializableProperties.TryGetValue(propertyName, out SerializableProperty property)) { continue; }
object value = property.GetValue(target);
if (door.Stuck > 0)
{
var progressBar = user.UpdateHUDProgressBar(door, door.Item.WorldPosition, door.Stuck / 100, Color.DarkGray * 0.5f, Color.White);
if (progressBar != null) { progressBar.Size = new Vector2(60.0f, 20.0f); }
}
var progressBar = user.UpdateHUDProgressBar(door, door.Item.WorldPosition, door.Stuck / 100, Color.DarkGray * 0.5f, Color.White);
if (progressBar != null) { progressBar.Size = new Vector2(60.0f, 20.0f); }
}
}
}
}
#endif
}