Unstable 0.1500.5.0 (almost forgor edition 💀)

This commit is contained in:
Markus Isberg
2021-10-01 23:56:14 +09:00
parent 3043a9a7bc
commit 08bdfc6cea
150 changed files with 5669 additions and 4403 deletions
@@ -79,6 +79,13 @@ namespace Barotrauma.Items.Components
set;
}
[Serialize(false, false, description: "Use the hand rotation instead of torso rotation for the item hold angle. Enable this if you want the item just to follow with the arm when not aiming instead of forcing the arm to a hold pose.")]
public bool UseHandRotationForHoldAngle
{
get;
set;
}
[Serialize(false, false, description: "Can the item be attached to walls.")]
public bool Attachable
{
@@ -93,6 +100,13 @@ namespace Barotrauma.Items.Components
set;
}
[Serialize(false, false, description: "Can the item only be attached in limited amount? Uses permanent stat values to check for legibility.")]
public bool LimitedAttachable
{
get;
set;
}
[Serialize(false, false, description: "Should the item be attached to a wall by default when it's placed in the submarine editor.")]
public bool AttachedByDefault
{
@@ -154,7 +168,8 @@ namespace Barotrauma.Items.Components
BodyType = BodyType.Dynamic,
CollidesWith = Physics.CollisionCharacter,
CollisionCategories = Physics.CollisionItemBlocking,
Enabled = false
Enabled = false,
UserData = "Holdable.Pusher"
};
Pusher.FarseerBody.OnCollision += OnPusherCollision;
Pusher.FarseerBody.FixedRotation = false;
@@ -205,7 +220,6 @@ namespace Barotrauma.Items.Components
}
}
}
characterUsable = element.GetAttributeBool("characterusable", true);
}
@@ -247,6 +261,7 @@ namespace Barotrauma.Items.Components
private void Drop(bool dropConnectedWires, Character dropper)
{
GetRope()?.Snap();
if (dropConnectedWires)
{
DropConnectedWires(dropper);
@@ -558,6 +573,15 @@ namespace Barotrauma.Items.Components
PickKey = InputType.Select;
}
public override void ParseMsg()
{
base.ParseMsg();
if (Attachable)
{
prevMsg = DisplayMsg;
}
}
public override bool Use(float deltaTime, Character character = null)
{
if (!attachable || item.body == null) { return character == null || (character.IsKeyDown(InputType.Aim) && characterUsable); }
@@ -567,6 +591,25 @@ namespace Barotrauma.Items.Components
if (!character.IsKeyDown(InputType.Aim)) { return false; }
if (!CanBeAttached(character)) { return false; }
if (LimitedAttachable)
{
if (character?.Info == null)
{
DebugConsole.AddWarning("Character without CharacterInfo attempting to attach a limited attachable item!");
return false;
}
int maxAttachableCount = (int)character.Info.GetSavedStatValue(StatTypes.MaxAttachableCount, item.Prefab.Identifier);
int currentlyAttachedCount = Item.ItemList.Count(
i => i.Submarine == item.Submarine && i.GetComponent<Holdable>() is Holdable holdable && holdable.Attached && i.Prefab.Identifier == item.prefab.Identifier);
if (currentlyAttachedCount >= maxAttachableCount)
{
#if CLIENT
GUI.AddMessage($"{TextManager.Get("itemmsgtotalnumberlimited")} ({currentlyAttachedCount}/{maxAttachableCount})", Color.Red);
#endif
return false;
}
}
if (GameMain.NetworkMember != null)
{
if (character != Character.Controlled)
@@ -666,6 +709,20 @@ namespace Barotrauma.Items.Components
Update(deltaTime, cam);
}
public Rope GetRope()
{
var rangedWeapon = Item.GetComponent<RangedWeapon>();
if (rangedWeapon != null)
{
var lastProjectile = rangedWeapon.LastProjectile;
if (lastProjectile != null)
{
return lastProjectile.Item.GetComponent<Rope>();
}
}
return null;
}
public override void Update(float deltaTime, Camera cam)
{
if (attachTargetCell != null)
@@ -720,9 +777,18 @@ namespace Barotrauma.Items.Components
scaledHandlePos[1] = handlePos[1] * item.Scale;
bool aim = picker.IsKeyDown(InputType.Aim) && aimPos != Vector2.Zero && picker.CanAim;
picker.AnimController.HoldItem(deltaTime, item, scaledHandlePos, holdPos + swing, aimPos + swing, aim, holdAngle);
if (!aim)
{
var rope = GetRope();
if (rope != null && rope.SnapWhenNotAimed)
{
rope.Snap();
}
}
}
else
{
GetRope()?.Snap();
Limb equipLimb = null;
if (picker.Inventory.IsInLimbSlot(item, InvSlotType.Headset) || picker.Inventory.IsInLimbSlot(item, InvSlotType.Head))
{
@@ -792,7 +858,7 @@ namespace Barotrauma.Items.Components
attachTargetCell = null;
if (Pusher != null)
{
GameMain.World.Remove(Pusher.FarseerBody);
Pusher.Remove();
Pusher = null;
}
body = null;
@@ -31,7 +31,7 @@ namespace Barotrauma.Items.Components
public void Initialize(CharacterInfo info)
{
if (info == null) return;
if (info == null) { return; }
if (info.Job?.Prefab != null)
{
@@ -42,20 +42,22 @@ namespace Barotrauma.Items.Components
var head = info.Head;
if (info != null && head != null)
{
item.AddTag("gender:" + head.gender.ToString().ToLowerInvariant());
item.AddTag("race:" + head.race.ToString());
item.AddTag("headspriteid:" + info.HeadSpriteId.ToString());
item.AddTag("hairindex:" + head.HairIndex);
item.AddTag("beardindex:" + head.BeardIndex);
item.AddTag("moustacheindex:" + head.MoustacheIndex);
item.AddTag("faceattachmentindex:" + head.FaceAttachmentIndex);
if (head == null) { return; }
if (info.HasGenders) { item.AddTag($"gender:{head.gender.ToString().ToLowerInvariant()}"); }
if (info.HasRaces) { item.AddTag($"race:{head.race}"); }
item.AddTag($"headspriteid:{info.HeadSpriteId}");
item.AddTag($"hairindex:{head.HairIndex}");
item.AddTag($"beardindex:{head.BeardIndex}");
item.AddTag($"moustacheindex:{head.MoustacheIndex}");
item.AddTag($"faceattachmentindex:{head.FaceAttachmentIndex}");
item.AddTag($"haircolor:{head.HairColor.ToStringHex()}");
item.AddTag($"facialhaircolor:{head.FacialHairColor.ToStringHex()}");
item.AddTag($"skincolor:{head.SkinColor.ToStringHex()}");
if (head.SheetIndex != null)
{
item.AddTag("sheetindex:" + head.SheetIndex.Value.X + ";" + head.SheetIndex.Value.Y);
}
if (head.SheetIndex != null)
{
item.AddTag($"sheetindex:{head.SheetIndex.Value.X};{head.SheetIndex.Value.Y}");
}
}
@@ -50,6 +50,16 @@ namespace Barotrauma.Items.Components
set;
}
[Editable, Serialize(true, false)]
public bool Swing { get; set; }
[Editable, Serialize("2.0, 0.0", false)]
public Vector2 SwingPos { get; set; }
[Editable, Serialize("3.0, -1.0", false)]
public Vector2 SwingForce { get; set; }
/// <summary>
/// Defines items that boost the weapon functionality, like battery cell for stun batons.
/// </summary>
@@ -67,8 +77,6 @@ namespace Barotrauma.Items.Components
};
}
item.IsShootable = true;
// TODO: should define this in xml if we have melee weapons that don't require aim to use
item.RequireAimToUse = true;
PreferredContainedItems = element.GetAttributeStringArray("preferredcontaineditems", new string[0], convertToLowerInvariant: true);
}
@@ -82,6 +90,9 @@ namespace Barotrauma.Items.Components
public override bool Use(float deltaTime, Character character = null)
{
if (character == null || reloadTimer > 0.0f) { return false; }
#if CLIENT
if (!Item.RequireAimToUse && character.IsPlayer && (GUI.MouseOn != null || character.Inventory.visualSlots.Any(s => s.MouseOn()) || Inventory.DraggingItems.Any())) { return false; }
#endif
if (Item.RequireAimToUse && !character.IsKeyDown(InputType.Aim) || hitting) { return false; }
//don't allow hitting if the character is already hitting with another weapon
@@ -94,7 +105,7 @@ namespace Barotrauma.Items.Components
SetUser(character);
if (hitPos < MathHelper.PiOver4) { return false; }
if (Item.RequireAimToUse && hitPos < MathHelper.PiOver4) { return false; }
ActivateNearbySleepingCharacters();
reloadTimer = reload / (1 + character.GetStatValue(StatTypes.MeleeAttackSpeed));
@@ -105,20 +116,28 @@ namespace Barotrauma.Items.Components
item.body.FarseerBody.IsBullet = true;
item.body.PhysEnabled = true;
if (!character.AnimController.InWater)
if (Swing && !character.AnimController.InWater)
{
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)
Vector2 force = new Vector2(character.AnimController.Dir * SwingForce.X, SwingForce.Y) * l.Mass;
switch (l.type)
{
l.body.ApplyLinearImpulse(new Vector2(character.AnimController.Dir * 7.0f, -4.0f));
case LimbType.Torso:
force *= 2;
break;
case LimbType.Legs:
case LimbType.LeftFoot:
case LimbType.LeftThigh:
case LimbType.LeftLeg:
case LimbType.RightFoot:
case LimbType.RightThigh:
case LimbType.RightLeg:
force = Vector2.Zero;
break;
}
else
{
l.body.ApplyLinearImpulse(new Vector2(character.AnimController.Dir * 5.0f, -2.0f));
}
l.body.ApplyLinearImpulse(force);
}
}
@@ -154,9 +173,16 @@ namespace Barotrauma.Items.Components
public override void Update(float deltaTime, Camera cam)
{
if (!item.body.Enabled) { impactQueue.Clear(); return; }
if (picker == null && !picker.HeldItems.Contains(item)) { impactQueue.Clear(); IsActive = false; }
if (!item.body.Enabled)
{
impactQueue.Clear();
return;
}
if (picker == null && !picker.HeldItems.Contains(item))
{
impactQueue.Clear();
IsActive = false;
}
while (impactQueue.Count > 0)
{
var impact = impactQueue.Dequeue();
@@ -164,37 +190,47 @@ namespace Barotrauma.Items.Components
}
//in case handling the impact does something to the picker
if (picker == null) { return; }
reloadTimer -= deltaTime;
if (reloadTimer < 0) { reloadTimer = 0; }
if (!picker.IsKeyDown(InputType.Aim) && !hitting) { hitPos = 0.0f; }
if (reloadTimer < 0)
{
reloadTimer = 0;
}
if (!picker.IsKeyDown(InputType.Aim) && !hitting)
{
hitPos = 0.0f;
}
ApplyStatusEffects(ActionType.OnActive, deltaTime, picker);
if (item.body.Dir != picker.AnimController.Dir) { item.FlipX(relativeToSub: false); }
if (item.body.Dir != picker.AnimController.Dir)
{
item.FlipX(relativeToSub: false);
}
AnimController ac = picker.AnimController;
//TODO: refactor the hitting logic (get rid of the magic numbers, make it possible to use different kinds of animations for different items)
if (!hitting)
{
bool aim = picker.AllowInput && picker.IsKeyDown(InputType.Aim) && reloadTimer <= 0 && picker.CanAim;
bool aim = item.RequireAimToUse && picker.AllowInput && picker.IsKeyDown(InputType.Aim) && reloadTimer <= 0 && picker.CanAim;
if (aim)
{
hitPos = MathUtils.WrapAnglePi(Math.Min(hitPos + deltaTime * 5f, MathHelper.PiOver4));
ac.HoldItem(deltaTime, item, handlePos, aimPos, Vector2.Zero, false, hitPos, holdAngle + hitPos, aimingMelee: true);
ac.HoldItem(deltaTime, item, handlePos, aimPos, Vector2.Zero, aim: false, hitPos, holdAngle + hitPos, aimMelee: true);
}
else
{
hitPos = 0;
ac.HoldItem(deltaTime, item, handlePos, holdPos, Vector2.Zero, false, holdAngle);
ac.HoldItem(deltaTime, item, handlePos, holdPos, Vector2.Zero, aim: false, holdAngle);
}
}
else
{
// TODO: We might want to make this configurable
hitPos = MathUtils.WrapAnglePi(hitPos - deltaTime * 15f);
ac.HoldItem(deltaTime, item, handlePos, new Vector2(2, 0), Vector2.Zero, false, hitPos, holdAngle + hitPos); // aimPos not used -> zero (new Vector2(-0.3f, 0.2f)), holdPos new Vector2(0.6f, -0.1f)
if (Swing)
{
ac.HoldItem(deltaTime, item, handlePos, SwingPos, Vector2.Zero, aim: false, hitPos, holdAngle + hitPos);
}
else
{
ac.HoldItem(deltaTime, item, handlePos, holdPos, Vector2.Zero, aim: false, holdAngle);
}
if (hitPos < -MathHelper.PiOver2)
{
RestoreCollision();
@@ -1,7 +1,6 @@
using Barotrauma.Abilities;
using Barotrauma.Networking;
using FarseerPhysics;
using FarseerPhysics.Collision;
using FarseerPhysics.Dynamics;
using Microsoft.Xna.Framework;
using System;
@@ -80,6 +79,9 @@ namespace Barotrauma.Items.Components
}
}
public Projectile LastProjectile { get; private set; }
private float currentChargeTime;
private bool tryingToCharge;
@@ -196,6 +198,7 @@ namespace Barotrauma.Items.Components
Vector2 barrelPos = TransformedBarrelPos + item.body.SimPosition;
float rotation = (Item.body.Dir == 1.0f) ? Item.body.Rotation : Item.body.Rotation - MathHelper.Pi;
float spread = GetSpread(character) * Rand.Range(-0.5f, 0.5f);
LastProjectile?.Item.GetComponent<Rope>()?.Snap();
float damageMultiplier = 1f + item.GetQualityModifier(Quality.StatType.AttackMultiplier);
projectile.Shoot(character, character.AnimController.AimSourceSimPos, barrelPos, rotation + spread, ignoredBodies: limbBodies.ToList(), createNetworkEvent: false, damageMultiplier);
projectile.Item.GetComponent<Rope>()?.Attach(Item, projectile.Item);
@@ -206,6 +209,7 @@ namespace Barotrauma.Items.Components
projectile.Item.body.ApplyTorque(projectile.Item.body.Mass * degreeOfFailure * Rand.Range(-10.0f, 10.0f));
Item.RemoveContained(projectile.Item);
}
LastProjectile = projectile;
}
LaunchProjSpecific();
@@ -123,18 +123,18 @@ namespace Barotrauma.Items.Components
if (aim)
{
throwPos = MathUtils.WrapAnglePi(System.Math.Min(throwPos + deltaTime * 5.0f, MathHelper.PiOver2));
ac.HoldItem(deltaTime, item, handlePos, aimPos, Vector2.Zero, false, throwPos);
ac.HoldItem(deltaTime, item, handlePos, aimPos, Vector2.Zero, aim: false, throwPos);
}
else
{
throwPos = 0;
ac.HoldItem(deltaTime, item, handlePos, holdPos, Vector2.Zero, false, holdAngle);
ac.HoldItem(deltaTime, item, handlePos, holdPos, Vector2.Zero, aim: false, holdAngle);
}
}
else
{
throwPos = MathUtils.WrapAnglePi(throwPos - deltaTime * 15.0f);
ac.HoldItem(deltaTime, item, handlePos, aimPos, Vector2.Zero, false, throwPos);
ac.HoldItem(deltaTime, item, handlePos, aimPos, Vector2.Zero, aim: false, throwPos);
if (throwPos < 0)
{
@@ -169,8 +169,8 @@ namespace Barotrauma.Items.Components
item.body.FarseerBody.IsBullet = true;
midAir = true;
ac.GetLimb(LimbType.Head).body.ApplyLinearImpulse(throwVector * 10.0f, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
ac.GetLimb(LimbType.Torso).body.ApplyLinearImpulse(throwVector * 10.0f, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
ac.GetLimb(LimbType.Head)?.body.ApplyLinearImpulse(throwVector * 10.0f, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
ac.GetLimb(LimbType.Torso)?.body.ApplyLinearImpulse(throwVector * 10.0f, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
Limb rightHand = ac.GetLimb(LimbType.RightHand);
item.body.AngularVelocity = rightHand.body.AngularVelocity;