(4f4395b00) Reduced the size of the disallowed item interface area around the chatbox

This commit is contained in:
Joonas Rikkonen
2019-04-04 11:07:45 +03:00
parent 860e5204ab
commit 79ea41e6c9
54 changed files with 571 additions and 540 deletions
@@ -530,7 +530,8 @@ namespace Barotrauma
}
}
if (Math.Abs(Character.AnimController.movement.X) > 0.1f && !Character.AnimController.InWater)
if (Math.Abs(Character.AnimController.movement.X) > 0.1f && !Character.AnimController.InWater &&
(GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer || Character.Controlled == Character))
{
Character.AnimController.TargetDir = Character.WorldPosition.X < attackWorldPos.X ? Direction.Right : Direction.Left;
}
@@ -204,10 +204,7 @@ namespace Barotrauma
private void Attack(float deltaTime)
{
character.CursorPosition = Enemy.Position;
if (Weapon.RequireAimToUse)
{
character.SetInput(InputType.Aim, false, true);
}
character.SetInput(InputType.Aim, false, true);
if (WeaponComponent is MeleeWeapon meleeWeapon)
{
if (Vector2.DistanceSquared(character.Position, Enemy.Position) <= meleeWeapon.Range * meleeWeapon.Range)
@@ -161,10 +161,7 @@ namespace Barotrauma
private void OperateRepairTool(float deltaTime)
{
character.CursorPosition = Item.Position;
if (Item.RequireAimToUse)
{
character.SetInput(InputType.Aim, false, true);
}
character.SetInput(InputType.Aim, false, true);
Vector2 fromToolToTarget = Item.Position - repairTool.Item.Position;
if (fromToolToTarget.LengthSquared() < MathUtils.Pow(repairTool.Range / 2, 2))
{
@@ -696,7 +696,7 @@ namespace Barotrauma
return;
}
limb.body.ApplyForce(diff * (float)(Math.Sin(WalkPos) * Math.Sqrt(limb.Mass)) * 30.0f * animStrength);
limb.body.ApplyForce(diff * (float)(Math.Sin(WalkPos) * Math.Sqrt(limb.Mass)) * 30.0f * animStrength, maxVelocity: 10.0f);
}
}
@@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using Barotrauma.Extensions;
using Barotrauma.Networking;
namespace Barotrauma
{
@@ -1122,6 +1123,7 @@ namespace Barotrauma
//prevent the hands from going above the top of the ladders
handPos.Y = Math.Min(-0.5f, handPos.Y);
// TODO: lock only one hand when aiming?
if (!PlayerInput.KeyDown(InputType.Aim) || Math.Abs(movement.Y) > 0.01f)
{
MoveLimb(leftHand,
@@ -892,8 +892,6 @@ namespace Barotrauma
return !(dequeuedInput.HasFlag(InputNetFlags.Crouch)) && (prevDequeuedInput.HasFlag(InputNetFlags.Crouch));
case InputType.Select:
return dequeuedInput.HasFlag(InputNetFlags.Select); //TODO: clean up the way this input is registered
case InputType.Deselect:
return dequeuedInput.HasFlag(InputNetFlags.Deselect);
case InputType.Health:
return dequeuedInput.HasFlag(InputNetFlags.Health);
case InputType.Grab:
@@ -1272,51 +1270,18 @@ namespace Barotrauma
{
for (int i = 0; i < selectedItems.Length; i++ )
{
if (selectedItems[i] == null) { continue; }
if (i == 1 && selectedItems[0] == selectedItems[1]) { continue; }
var item = selectedItems[i];
if (item == null) { continue; }
if (IsKeyDown(InputType.Aim) || !item.RequireAimToSecondaryUse)
{
item.SecondaryUse(deltaTime, this);
}
if (IsKeyDown(InputType.Use) && !item.IsShootable)
{
if (!item.RequireAimToUse || IsKeyDown(InputType.Aim))
{
item.Use(deltaTime, this);
}
}
if (IsKeyDown(InputType.Shoot) && item.IsShootable)
{
if (!item.RequireAimToUse || IsKeyDown(InputType.Aim))
{
item.Use(deltaTime, this);
}
}
if (selectedItems[i] == null) continue;
if (i == 1 && selectedItems[0] == selectedItems[1]) continue;
if (IsKeyDown(InputType.Use)) selectedItems[i].Use(deltaTime, this);
if (IsKeyDown(InputType.Aim) && selectedItems[i] != null) selectedItems[i].SecondaryUse(deltaTime, this);
}
}
if (SelectedConstruction != null)
{
if (IsKeyDown(InputType.Aim) || !SelectedConstruction.RequireAimToSecondaryUse)
{
SelectedConstruction.SecondaryUse(deltaTime, this);
}
if (IsKeyDown(InputType.Use) && !SelectedConstruction.IsShootable)
{
if (!SelectedConstruction.RequireAimToUse || IsKeyDown(InputType.Aim))
{
SelectedConstruction.Use(deltaTime, this);
}
}
if (IsKeyDown(InputType.Shoot) && SelectedConstruction.IsShootable)
{
if (!SelectedConstruction.RequireAimToUse || IsKeyDown(InputType.Aim))
{
SelectedConstruction.Use(deltaTime, this);
}
}
if (IsKeyDown(InputType.Use)) SelectedConstruction.Use(deltaTime, this);
if (SelectedConstruction != null && IsKeyDown(InputType.Aim)) SelectedConstruction.SecondaryUse(deltaTime, this);
}
if (SelectedCharacter != null)
@@ -1794,7 +1759,7 @@ namespace Barotrauma
}
#endif
}
else if (IsKeyHit(InputType.Deselect) && SelectedConstruction != null)
else if (IsKeyHit(InputType.Select) && SelectedConstruction != null)
{
SelectedConstruction = null;
#if CLIENT
@@ -1939,7 +1904,7 @@ namespace Barotrauma
//cannot be protected from pressure when below crush depth
protectedFromPressure = protectedFromPressure && WorldPosition.Y > CharacterHealth.CrushDepth;
//implode if not protected from pressure, and either outside or in a high-pressure hull
if (!protectedFromPressure &&
if (!protectedFromPressure &&
(AnimController.CurrentHull == null || AnimController.CurrentHull.LethalPressure >= 80.0f))
{
if (CharacterHealth.PressureKillDelay <= 0.0f)
@@ -1954,7 +1919,7 @@ namespace Barotrauma
if (PressureTimer >= 100.0f)
{
if (Controlled == this) cam.Zoom = 5.0f;
if (Controlled == this) { cam.Zoom = 5.0f; }
if (GameMain.NetworkMember == null || !GameMain.NetworkMember.IsClient)
{
Implode();
@@ -2235,7 +2200,7 @@ namespace Barotrauma
if (limbHit == null) return new AttackResult();
limbHit.body?.ApplyLinearImpulse(attack.TargetImpulseWorld + attack.TargetForceWorld * deltaTime);
limbHit.body?.ApplyLinearImpulse(attack.TargetImpulseWorld + attack.TargetForceWorld * deltaTime, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
#if SERVER
if (attacker is Character attackingCharacter && attackingCharacter.AIController == null)
{
@@ -2321,7 +2286,8 @@ namespace Barotrauma
{
Vector2 diff = dir;
if (diff == Vector2.Zero) diff = Rand.Vector(1.0f);
hitLimb.body.ApplyLinearImpulse(Vector2.Normalize(diff) * attackImpulse, hitLimb.SimPosition + ConvertUnits.ToSimUnits(diff));
hitLimb.body.ApplyLinearImpulse(Vector2.Normalize(diff) * attackImpulse, hitLimb.SimPosition + ConvertUnits.ToSimUnits(diff),
maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
}
Vector2 simPos = hitLimb.SimPosition + ConvertUnits.ToSimUnits(dir);
AttackResult attackResult = hitLimb.AddDamage(simPos, afflictions, playSound);
@@ -55,12 +55,8 @@ namespace Barotrauma
Ragdoll = 0x800,
Health = 0x1000,
Grab = 0x2000,
Deselect = 0x4000, // 16384
Shoot = 0x8000, // 32768
MaxVal = 0xFFFF // 65535
//MaxVal = 0x7FFF // 32767
//MaxVal = 0x3FFF // 16383
MaxVal = 0x3FFF
}
private InputNetFlags dequeuedInput = 0;
private InputNetFlags prevDequeuedInput = 0;
@@ -103,6 +103,7 @@ namespace Barotrauma
}
public float CrushDepth { get; private set; }
public float PressureKillDelay { get; private set; } = 5.0f;
public float Vitality { get; private set; }
@@ -626,13 +626,17 @@ namespace Barotrauma
Limb limb = character.AnimController.Limbs[limbIndex];
Vector2 forcePos = limb.pullJoint == null ? limb.body.SimPosition : limb.pullJoint.WorldAnchorA;
limb.body.ApplyLinearImpulse(limb.Mass * attack.Force * Vector2.Normalize(attackSimPos - SimPosition), forcePos);
limb.body.ApplyLinearImpulse(limb.Mass * attack.Force * Vector2.Normalize(attackSimPos - SimPosition), forcePos,
maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
}
}
else
{
Vector2 forcePos = pullJoint == null ? body.SimPosition : pullJoint.WorldAnchorA;
body.ApplyLinearImpulse(Mass * attack.Force * Vector2.Normalize(attackSimPos - SimPosition), forcePos);
body.ApplyLinearImpulse(
Mass * attack.Force * Vector2.Normalize(attackSimPos - SimPosition),
forcePos,
maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
}
}
return wasHit;
@@ -396,11 +396,12 @@ namespace Barotrauma
keyMapping[(int)InputType.Voice] = new KeyOrMouse(Keys.V);
keyMapping[(int)InputType.Use] = new KeyOrMouse(Keys.E);
keyMapping[(int)InputType.SelectNextCharacter] = new KeyOrMouse(Keys.Tab);
keyMapping[(int)InputType.SelectPreviousCharacter] = new KeyOrMouse(Keys.Q);
keyMapping[(int)InputType.Select] = new KeyOrMouse(0);
keyMapping[(int)InputType.Deselect] = new KeyOrMouse(1);
keyMapping[(int)InputType.Shoot] = new KeyOrMouse(0);
keyMapping[(int)InputType.Voice] = new KeyOrMouse(Keys.V);
keyMapping[(int)InputType.Use] = new KeyOrMouse(0);
keyMapping[(int)InputType.Aim] = new KeyOrMouse(1);
foreach (XElement subElement in doc.Root.Elements())
@@ -741,6 +742,7 @@ namespace Barotrauma
EnableSplashScreen = doc.Root.GetAttributeBool("enablesplashscreen", EnableSplashScreen);
AimAssistAmount = doc.Root.GetAttributeFloat("aimassistamount", AimAssistAmount);
EnableMouseLook = doc.Root.GetAttributeBool("enablemouselook", EnableMouseLook);
foreach (XElement subElement in doc.Root.Elements())
{
@@ -924,7 +926,8 @@ namespace Barotrauma
new XAttribute("quickstartsub", QuickStartSubmarineName),
new XAttribute("requiresteamauthentication", requireSteamAuthentication),
new XAttribute("autoupdateworkshopitems", AutoUpdateWorkshopItems),
new XAttribute("aimassistamount", aimAssistAmount));
new XAttribute("aimassistamount", aimAssistAmount),
new XAttribute("enablemouselook", EnableMouseLook));
if (!ShowUserStatisticsPrompt)
{
@@ -396,63 +396,75 @@ namespace Barotrauma.Items.Components
}
int dir = IsHorizontal ? Math.Sign(c.SimPosition.Y - item.SimPosition.Y) : Math.Sign(c.SimPosition.X - item.SimPosition.X);
List<PhysicsBody> bodies = c.AnimController.Limbs.Select(l => l.body).ToList();
bodies.Add(c.AnimController.Collider);
bool soundPlayed = false;
foreach (Limb limb in c.AnimController.Limbs)
{
float diff = 0.0f;
if (!MathUtils.IsValid(body.SimPosition))
{
DebugConsole.ThrowError("Failed to push a limb out of a doorway - position of the body (character \"" + c.Name + "\") is not valid (" + body.SimPosition + ")");
GameAnalyticsManager.AddErrorEventOnce("PushCharactersAway:LimbPosInvalid", GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
"Failed to push a character out of a doorway - position of the character \"" + c.Name + "\" is not valid (" + body.SimPosition + ")." +
" Removed: " + c.Removed +
" Remoteplayer: " + c.IsRemotePlayer);
continue;
}
if (IsHorizontal)
{
if (body.SimPosition.X < simPos.X || body.SimPosition.X > simPos.X + simSize.X) continue;
diff = body.SimPosition.Y - item.SimPosition.Y;
}
else
{
if (body.SimPosition.Y > simPos.Y || body.SimPosition.Y < simPos.Y - simSize.Y) continue;
diff = body.SimPosition.X - item.SimPosition.X;
}
if (Math.Sign(diff) != dir)
if (PushBodyOutOfDoorway(c, limb.body, dir, simPos, simSize) && !soundPlayed)
{
#if CLIENT
SoundPlayer.PlayDamageSound("LimbBlunt", 1.0f, limb.body);
#endif
if (IsHorizontal)
{
body.SetTransform(new Vector2(body.SimPosition.X, item.SimPosition.Y + dir * simSize.Y * 2.0f), body.Rotation);
body.ApplyLinearImpulse(new Vector2(isOpen ? 0.0f : 1.0f, dir * 2.0f));
}
else
{
body.SetTransform(new Vector2(item.SimPosition.X + dir * simSize.X * 1.2f, body.SimPosition.Y), body.Rotation);
body.ApplyLinearImpulse(new Vector2(dir * 0.5f, isOpen ? 0.0f : -1.0f));
}
}
if (IsHorizontal)
{
if (Math.Abs(body.SimPosition.Y - item.SimPosition.Y) > simSize.Y * 0.5f) continue;
body.ApplyLinearImpulse(new Vector2(isOpen ? 0.0f : 1.0f, dir * 0.5f));
soundPlayed = true;
}
}
PushBodyOutOfDoorway(c, c.AnimController.Collider, dir, simPos, simSize);
}
}
private bool PushBodyOutOfDoorway(Character c, PhysicsBody body, int dir, Vector2 doorRectSimPos, Vector2 doorRectSimSize)
{
float diff = 0.0f;
if (!MathUtils.IsValid(body.SimPosition))
{
DebugConsole.ThrowError("Failed to push a limb out of a doorway - position of the body (character \"" + c.Name + "\") is not valid (" + body.SimPosition + ")");
GameAnalyticsManager.AddErrorEventOnce("PushCharactersAway:LimbPosInvalid", GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
"Failed to push a character out of a doorway - position of the character \"" + c.Name + "\" is not valid (" + body.SimPosition + ")." +
" Removed: " + c.Removed +
" Remoteplayer: " + c.IsRemotePlayer);
return false;
}
if (IsHorizontal)
{
if (body.SimPosition.X < doorRectSimPos.X || body.SimPosition.X > doorRectSimPos.X + doorRectSimSize.X) { return false; }
diff = body.SimPosition.Y - item.SimPosition.Y;
}
else
{
if (body.SimPosition.Y > doorRectSimPos.Y || body.SimPosition.Y < doorRectSimPos.Y - doorRectSimSize.Y) { return false; }
diff = body.SimPosition.X - item.SimPosition.X;
}
//if the limb is at a different side of the door than the character (collider),
//immediately teleport it to the correct side
if (Math.Sign(diff) != dir)
{
if (IsHorizontal)
{
body.SetTransform(new Vector2(body.SimPosition.X, item.SimPosition.Y + dir * doorRectSimSize.Y * 2.0f), body.Rotation);
}
else
{
body.SetTransform(new Vector2(item.SimPosition.X + dir * doorRectSimSize.X * 1.2f, body.SimPosition.Y), body.Rotation);
}
}
//apply an impulse to push the limb further from the door
if (IsHorizontal)
{
if (Math.Abs(body.SimPosition.Y - item.SimPosition.Y) > doorRectSimSize.Y * 0.5f) { return false; }
body.ApplyLinearImpulse(new Vector2(isOpen ? 0.0f : 1.0f, dir * 2.0f), maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
}
else
{
if (Math.Abs(body.SimPosition.X - item.SimPosition.X) > doorRectSimSize.X * 0.5f) { return false; }
body.ApplyLinearImpulse(new Vector2(dir * 2.0f, isOpen ? 0.0f : -1.0f), maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
}
c.SetStun(0.2f);
return true;
}
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
{
if (isStuck) return;
@@ -461,12 +473,7 @@ namespace Barotrauma.Items.Components
if (connection.Name == "toggle")
{
DebugConsole.ThrowError("Failed to push a limb out of a doorway - position of the body (character \"" + c.Name + "\") is not valid (" + body.SimPosition + ")");
GameAnalyticsManager.AddErrorEventOnce("PushCharactersAway:LimbPosInvalid", GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
"Failed to push a character out of a doorway - position of the character \"" + c.Name + "\" is not valid (" + body.SimPosition + ")." +
" Removed: " + c.Removed +
" Remoteplayer: " + c.IsRemotePlayer);
return false;
SetState(!wasOpen, false, true);
}
else if (connection.Name == "set_state")
{
@@ -471,7 +471,7 @@ namespace Barotrauma.Items.Components
swingState %= 1.0f;
if (SwingWhenHolding ||
(SwingWhenAiming && picker.IsKeyDown(InputType.Aim)) ||
(SwingWhenUsing && picker.IsKeyDown(InputType.Aim) && picker.IsKeyDown(InputType.Shoot)))
(SwingWhenUsing && picker.IsKeyDown(InputType.Aim) && picker.IsKeyDown(InputType.Use)))
{
swing = swingAmount * new Vector2(
PerlinNoise.GetPerlin(swingState * SwingSpeed * 0.1f, swingState * SwingSpeed * 0.1f) - 0.5f,
@@ -489,8 +489,7 @@ namespace Barotrauma.Items.Components
{
scaledHandlePos[0] = handlePos[0] * item.Scale;
scaledHandlePos[1] = handlePos[1] * item.Scale;
bool aim = picker.IsKeyDown(InputType.Aim) && aimPos != Vector2.Zero && (picker.SelectedConstruction == null || picker.SelectedConstruction.GetComponent<Ladder>() != null);
picker.AnimController.HoldItem(deltaTime, item, scaledHandlePos, holdPos + swing, aimPos + swing, aim, holdAngle);
picker.AnimController.HoldItem(deltaTime, item, scaledHandlePos, holdPos + swing, aimPos + swing, picker.IsKeyDown(InputType.Aim) && aimPos != Vector2.Zero, holdAngle);
}
else
{
@@ -149,8 +149,7 @@ namespace Barotrauma.Items.Components
//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.IsKeyDown(InputType.Aim) && reloadTimer <= 0 && (picker.SelectedConstruction == null || picker.SelectedConstruction.GetComponent<Ladder>() != null);
if (aim)
if (picker.IsKeyDown(InputType.Aim) && reloadTimer <= 0)
{
hitPos = MathUtils.WrapAnglePi(Math.Min(hitPos + deltaTime * 5f, MathHelper.PiOver4));
ac.HoldItem(deltaTime, item, handlePos, aimPos, Vector2.Zero, false, hitPos, holdAngle + hitPos);
@@ -1,4 +1,5 @@
using FarseerPhysics;
using Barotrauma.Networking;
using FarseerPhysics;
using FarseerPhysics.Collision;
using FarseerPhysics.Dynamics;
using Microsoft.Xna.Framework;
@@ -166,11 +167,12 @@ namespace Barotrauma.Items.Components
//set the rotation of the projectile again because dropping the projectile resets the rotation
projectile.Item.SetTransform(projectilePos,
rotation + ((item.body.Dir == 1.0f) ? projectile.LaunchRotationRadians : projectile.LaunchRotationRadians - MathHelper.Pi));
rotation + (projectile.Item.body.Dir * projectile.LaunchRotationRadians));
//recoil
item.body.ApplyLinearImpulse(
new Vector2((float)Math.Cos(projectile.Item.body.Rotation), (float)Math.Sin(projectile.Item.body.Rotation)) * item.body.Mass * -50.0f);
new Vector2((float)Math.Cos(projectile.Item.body.Rotation), (float)Math.Sin(projectile.Item.body.Rotation)) * item.body.Mass * -50.0f,
maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
item.RemoveContained(projectile.Item);
@@ -79,8 +79,7 @@ namespace Barotrauma.Items.Components
break;
}
}
item.IsShootable = true;
item.RequireAimToUse = true;
InitProjSpecific(element);
}
@@ -312,10 +311,7 @@ namespace Barotrauma.Items.Components
sinTime += deltaTime;
character.CursorPosition = leak.Position + VectorExtensions.Forward(Item.body.TransformedRotation + (float)Math.Sin(sinTime), dist);
if (item.RequireAimToUse)
{
character.SetInput(InputType.Aim, false, true);
}
character.SetInput(InputType.Aim, false, true);
// Press the trigger only when the tool is approximately facing the target.
// If the character is climbing, ignore the check, because we cannot aim while climbing.
@@ -107,10 +107,10 @@ namespace Barotrauma.Items.Components
#endif
Character thrower = picker;
item.Drop(thrower, createNetworkEvent: GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer);
item.body.ApplyLinearImpulse(throwVector * throwForce * item.body.Mass * 3.0f);
item.body.ApplyLinearImpulse(throwVector * throwForce * item.body.Mass * 3.0f, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
ac.GetLimb(LimbType.Head).body.ApplyLinearImpulse(throwVector*10.0f);
ac.GetLimb(LimbType.Torso).body.ApplyLinearImpulse(throwVector * 10.0f);
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;
@@ -210,13 +210,8 @@ namespace Barotrauma.Items.Components
{
Entity.Spawner.AddToSpawnQueue(fabricatedItem.TargetItem, outputContainer.Inventory, fabricatedItem.TargetItem.Health * fabricatedItem.OutCondition);
}
bool isNotClient = true;
#if CLIENT
isNotClient = GameMain.Client == null;
#endif
if (isNotClient && user != null)
if ((GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer) && user != null && !user.Removed)
{
foreach (Skill skill in fabricatedItem.RequiredSkills)
{
@@ -377,23 +377,14 @@ namespace Barotrauma.Items.Components
target.Body.ApplyLinearImpulse(item.body.LinearVelocity * item.body.Mass);
return true;
}
else if (target.Body.UserData is Limb limb)
{
//severed limbs don't deactivate the projectile (but may still slow it down enough to make it inactive)
if (limb.IsSevered)
{
target.Body.ApplyLinearImpulse(item.body.LinearVelocity * item.body.Mass);
return true;
}
limb.character.LastDamageSource = item;
attackResult = attack.DoDamageToLimb(User, limb, item.WorldPosition, 1.0f);
if (limb.character != null) character = limb.character;
}
else if (target.Body.UserData is Structure structure)
{
attackResult = attack.DoDamage(User, structure, item.WorldPosition, 1.0f);
}
limb.character.LastDamageSource = item;
if (attack != null) { attackResult = attack.DoDamageToLimb(User, limb, item.WorldPosition, 1.0f); }
if (limb.character != null) { character = limb.character; }
}
else if (target.Body.UserData is Structure structure)
{
if (attack != null) { attackResult = attack.DoDamage(User, structure, item.WorldPosition, 1.0f); }
}
if (character != null) character.LastDamageSource = item;
@@ -22,6 +22,10 @@ namespace Barotrauma.Items.Components
private float blinkTimer;
private bool itemLoaded;
private float blinkTimer;
public PhysicsBody ParentBody;
[Editable(MinValueFloat = 0.0f, MaxValueFloat = 2048.0f), Serialize(100.0f, true)]
@@ -77,7 +81,7 @@ namespace Barotrauma.Items.Components
IsActive = value;
#if SERVER
if (GameMain.Server != null && GameMain.Server.GameStarted) { item.CreateServerEvent(this); }
if (GameMain.Server != null && itemLoaded) { item.CreateServerEvent(this); }
#endif
}
}
@@ -315,7 +315,7 @@ namespace Barotrauma.Items.Components
Vector2 diff = nodes[nodes.Count - 1] - newNodePos;
Vector2 pullBackDir = diff == Vector2.Zero ? Vector2.Zero : Vector2.Normalize(diff);
user.AnimController.Collider.ApplyForce(pullBackDir * user.Mass * 50.0f);
user.AnimController.Collider.ApplyForce(pullBackDir * user.Mass * 50.0f, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
user.AnimController.UpdateUseItem(true, user.WorldPosition + pullBackDir * 200.0f);
if (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer)
@@ -163,8 +163,7 @@ namespace Barotrauma.Items.Components
break;
}
}
item.IsShootable = true;
item.RequireAimToUse = false;
InitProjSpecific(element);
}
@@ -489,10 +488,7 @@ namespace Barotrauma.Items.Components
character.CursorPosition = closestEnemy.WorldPosition;
if (item.Submarine != null) character.CursorPosition -= item.Submarine.Position;
if (item.RequireAimToUse)
{
character.SetInput(InputType.Aim, false, true);
}
character.SetInput(InputType.Aim, false, true);
float enemyAngle = MathUtils.VectorToAngle(closestEnemy.WorldPosition - item.WorldPosition);
float turretAngle = -rotation;
@@ -505,7 +501,7 @@ namespace Barotrauma.Items.Components
if (objective.Option.ToLowerInvariant() == "fireatwill")
{
character?.Speak(TextManager.Get("DialogFireTurret").Replace("[itemname]", item.Name), null, 0.0f, "fireturret", 5.0f);
character.SetInput(InputType.Shoot, true, true);
character.SetInput(InputType.Use, true, true);
}
return false;
@@ -235,30 +235,6 @@ namespace Barotrauma
set { /*do nothing*/ }
}
/// <summary>
/// Should the item's Use method be called with the "Use" or with the "Shoot" key?
/// </summary>
[Serialize(false, false)]
public bool IsShootable { get; set; }
/// <summary>
/// If true, the user has to hold the "aim" key before use is registered. False by default.
/// </summary>
[Serialize(false, false)]
public bool RequireAimToUse
{
get; set;
}
/// <summary>
/// If true, the user has to hold the "aim" key before secondary use is registered. True by default.
/// </summary>
[Serialize(true, false)]
public bool RequireAimToSecondaryUse
{
get; set;
}
public Color Color
{
get { return spriteColor; }
@@ -1145,6 +1121,12 @@ namespace Barotrauma
return;
}
float forceFactor = 1.0f;
if (CurrentHull != null)
{
return;
}
float forceFactor = 1.0f;
if (CurrentHull != null)
{
@@ -1389,27 +1371,20 @@ namespace Barotrauma
}
else
{
if (picker.IsKeyDown(InputType.Aim))
if (forceSelectKey)
{
pickHit = false;
selectHit = false;
if (ic.PickKey == InputType.Select) pickHit = true;
if (ic.SelectKey == InputType.Select) selectHit = true;
}
else if (forceActionKey)
{
if (ic.PickKey == InputType.Use) pickHit = true;
if (ic.SelectKey == InputType.Use) selectHit = true;
}
else
{
if (forceSelectKey)
{
if (ic.PickKey == InputType.Select) pickHit = true;
if (ic.SelectKey == InputType.Select) selectHit = true;
}
else if (forceActionKey)
{
if (ic.PickKey == InputType.Use) pickHit = true;
if (ic.SelectKey == InputType.Use) selectHit = true;
}
else
{
pickHit = picker.IsKeyHit(ic.PickKey);
selectHit = picker.IsKeyHit(ic.SelectKey);
pickHit = picker.IsKeyHit(ic.PickKey);
selectHit = picker.IsKeyHit(ic.SelectKey);
#if CLIENT
//if the cursor is on a UI component, disable interaction with the left mouse button
@@ -1420,10 +1395,10 @@ namespace Barotrauma
if (GameMain.Config.KeyBind(ic.SelectKey).MouseButton == 0) selectHit = false;
}
#endif
}
}
}
if (!pickHit && !selectHit) continue;
if (!ic.HasRequiredSkills(picker, out Skill tempRequiredSkill)) hasRequiredSkills = false;
@@ -1475,6 +1450,7 @@ namespace Barotrauma
return true;
}
public void Use(float deltaTime, Character character = null, Limb targetLimb = null)
{
if (RequireAimToUse && !character.IsKeyDown(InputType.Aim))
@@ -1625,6 +1601,8 @@ namespace Barotrauma
GameMain.NetworkMember != null && (GameMain.NetworkMember.IsServer || Character.Controlled == dropper))
{
parentInventory.CreateNetworkEvent();
//send frequent updates after the item has been dropped
PositionUpdateInterval = 0.0f;
}
}
@@ -568,7 +568,7 @@ namespace Barotrauma
public void Extinguish(float deltaTime, float amount, Vector2 position)
{
for (int i = FireSources.Count - 1; i >= 0; i-- )
for (int i = FireSources.Count - 1; i >= 0; i--)
{
FireSources[i].Extinguish(deltaTime, amount, position);
}
@@ -331,13 +331,13 @@ namespace Barotrauma
switch (subElement.Name.ToString().ToLowerInvariant())
{
case "sprite":
Sprite = new Sprite(subElement);
Sprite = new Sprite(subElement, lazyLoad: true);
break;
case "specularsprite":
SpecularSprite = new Sprite(subElement);
SpecularSprite = new Sprite(subElement, lazyLoad: true);
break;
case "deformablesprite":
DeformableSprite = new DeformableSprite(subElement);
DeformableSprite = new DeformableSprite(subElement, lazyLoad: true);
break;
case "overridecommonness":
string levelType = subElement.GetAttributeString("leveltype", "");
@@ -543,19 +543,19 @@ namespace Barotrauma
if (ForceVelocityLimit < 1000.0f)
body.ApplyForce(Force * currentForceFluctuation * distFactor, ForceVelocityLimit);
else
body.ApplyForce(Force * currentForceFluctuation * distFactor);
body.ApplyForce(Force * currentForceFluctuation * distFactor, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
break;
case TriggerForceMode.Acceleration:
if (ForceVelocityLimit < 1000.0f)
body.ApplyForce(Force * body.Mass * currentForceFluctuation * distFactor, ForceVelocityLimit);
else
body.ApplyForce(Force * body.Mass * currentForceFluctuation * distFactor);
body.ApplyForce(Force * body.Mass * currentForceFluctuation * distFactor, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
break;
case TriggerForceMode.Impulse:
if (ForceVelocityLimit < 1000.0f)
body.ApplyLinearImpulse(Force * currentForceFluctuation * distFactor, ForceVelocityLimit);
body.ApplyLinearImpulse(Force * currentForceFluctuation * distFactor, maxVelocity: ForceVelocityLimit);
else
body.ApplyLinearImpulse(Force * currentForceFluctuation * distFactor);
body.ApplyLinearImpulse(Force * currentForceFluctuation * distFactor, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
break;
case TriggerForceMode.LimitVelocity:
float maxVel = ForceVelocityLimit * currentForceFluctuation * distFactor;
@@ -563,7 +563,8 @@ namespace Barotrauma
{
body.ApplyForce(
Vector2.Normalize(-body.LinearVelocity) *
Force.Length() * body.Mass * currentForceFluctuation * distFactor);
Force.Length() * body.Mass * currentForceFluctuation * distFactor,
maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
}
break;
}
@@ -126,7 +126,7 @@ namespace Barotrauma
CanChangeTo.Add(new LocationTypeChange(Identifier, subElement));
break;
case "portrait":
var portrait = new Sprite(subElement);
var portrait = new Sprite(subElement, lazyLoad: true);
if (portrait != null)
{
portraits.Add(portrait);
@@ -605,7 +605,7 @@ namespace Barotrauma
{
if (!IsValidValue(impulse, "impulse", -1e10f, 1e10f)) return;
if (!IsValidValue(point, "point")) return;
if (!IsValidValue(impulse / body.Mass, "new velocity")) return;
if (!IsValidValue(impulse / body.Mass, "new velocity", -1000.0f, 1000.0f)) return;
body.ApplyLinearImpulse(impulse, point);
}
@@ -646,15 +646,20 @@ namespace Barotrauma
/// </summary>
public void ApplyForce(Vector2 force, float maxVelocity)
{
if (!IsValidValue(force, "force", -1e10f, 1e10f)) return;
if (!IsValidValue(maxVelocity, "max velocity")) return;
float currSpeed = body.LinearVelocity.Length();
Vector2 velocityAddition = force / Mass * (float)Timing.Step;
Vector2 newVelocity = body.LinearVelocity + velocityAddition;
newVelocity = newVelocity.ClampLength(Math.Max(currSpeed, maxVelocity));
float newSpeedSqr = newVelocity.LengthSquared();
if (newSpeedSqr > maxVelocity * maxVelocity)
{
newVelocity = newVelocity.ClampLength(maxVelocity);
}
body.ApplyForce((newVelocity - body.LinearVelocity) * Mass / (float)Timing.Step);
Vector2 clampedForce = (newVelocity - body.LinearVelocity) * Mass / (float)Timing.Step;
if (!IsValidValue(force, "clamped force", -1e10f, 1e10f)) return;
body.ApplyForce(force);
}
public void ApplyForce(Vector2 force, Vector2 point)
@@ -15,9 +15,7 @@ namespace Barotrauma
Ragdoll, Health, Grab,
SelectNextCharacter,
SelectPreviousCharacter,
Voice,
Deselect,
Shoot
Voice
}
public class KeyOrMouse
@@ -5,30 +5,25 @@ namespace Barotrauma
{
partial class DeformableSprite
{
private Sprite sprite;
public Vector2 Size
{
get { return sprite.size; }
get { return Sprite.size; }
}
public Vector2 Origin
{
get { return sprite.Origin; }
set { sprite.Origin = value; }
get { return Sprite.Origin; }
set { Sprite.Origin = value; }
}
public Sprite Sprite
public Sprite Sprite { get; private set; }
public DeformableSprite(XElement element, int? subdivisionsX = null, int? subdivisionsY = null, string filePath = "", bool lazyLoad = false)
{
get { return sprite; }
Sprite = new Sprite(element, file: filePath, lazyLoad: lazyLoad);
InitProjSpecific(element, subdivisionsX, subdivisionsY, lazyLoad);
}
public DeformableSprite(XElement element, int? subdivisionsX = null, int? subdivisionsY = null, string filePath = "")
{
sprite = new Sprite(element, file: filePath);
InitProjSpecific(element, subdivisionsX, subdivisionsY);
}
partial void InitProjSpecific(XElement element, int? subdivisionsX, int? subdivisionsY);
partial void InitProjSpecific(XElement element, int? subdivisionsX, int? subdivisionsY, bool lazyLoad = false);
}
}
@@ -103,8 +103,9 @@ namespace Barotrauma
partial void LoadTexture(ref Vector4 sourceVector, ref bool shouldReturn, bool premultiplyAlpha = true);
partial void CalculateSourceRect();
public Sprite(XElement element, string path = "", string file = "")
public Sprite(XElement element, string path = "", string file = "", bool? preMultiplyAlpha = null, bool lazyLoad = false)
{
this.lazyLoad = lazyLoad;
SourceElement = element;
if (file == "")
{
@@ -127,8 +128,12 @@ namespace Barotrauma
Name = SourceElement.GetAttributeString("name", null);
Vector4 sourceVector = SourceElement.GetAttributeVector4("sourcerect", Vector4.Zero);
preMultipliedAlpha = preMultiplyAlpha ?? SourceElement.GetAttributeBool("premultiplyalpha", true);
bool shouldReturn = false;
LoadTexture(ref sourceVector, ref shouldReturn, SourceElement.GetAttributeBool("premultiplyalpha", true));
if (!lazyLoad)
{
LoadTexture(ref sourceVector, ref shouldReturn, preMultipliedAlpha);
}
if (shouldReturn) return;
sourceRect = new Rectangle((int)sourceVector.X, (int)sourceVector.Y, (int)sourceVector.Z, (int)sourceVector.W);
size = SourceElement.GetAttributeVector2("size", Vector2.One);
@@ -31,6 +31,8 @@ namespace Barotrauma
public readonly HashSet<Character> ReactorMeltdown = new HashSet<Character>();
public readonly HashSet<Character> Casualties = new HashSet<Character>();
public bool SubWasDamaged;
}
private static RoundData roundData;
@@ -110,7 +112,47 @@ namespace Barotrauma
UnlockAchievement("subdeep", true, c => c != null && c.Submarine == sub && !c.IsDead && !c.IsUnconscious);
}
}
}
if (!roundData.SubWasDamaged)
{
roundData.SubWasDamaged = SubWallsDamaged(Submarine.MainSub);
}
}
if (GameMain.GameSession != null && Character.Controlled != null)
{
if (Character.Controlled.HasEquippedItem("clownmask") &&
Character.Controlled.HasEquippedItem("clowncostume"))
{
UnlockAchievement(Character.Controlled, "clowncostume");
}
if (Submarine.MainSub != null && Character.Controlled.Submarine == null)
{
float dist = 500 / Physics.DisplayToRealWorldRatio;
if (Vector2.DistanceSquared(Character.Controlled.WorldPosition, Submarine.MainSub.WorldPosition) >
dist * dist)
{
UnlockAchievement(Character.Controlled, "crewaway");
}
}
}
}
private static bool SubWallsDamaged(Submarine sub)
{
foreach (Structure structure in Structure.WallList)
{
if (structure.Submarine != sub || structure.HasBody) { continue; }
for (int i = 0; i < structure.SectionCount; i++)
{
if (structure.SectionIsLeaking(i))
{
return true;
}
}
}
return false;
}
public static void OnBiomeDiscovered(Biome biome)
@@ -274,14 +316,21 @@ namespace Barotrauma
//made it to the destination
if (gameSession.Submarine.AtEndPosition)
{
bool noDamageRun = !roundData.SubWasDamaged && !roundData.Casualties.Any(c => !(c.AIController is EnemyAIController));
#if SERVER
if (GameMain.Server != null)
{
//in MP all characters that were inside the sub during reactor meltdown and still alive at the end of the round get an achievement
UnlockAchievement("survivereactormeltdown", true, c => c != null && !c.IsDead && roundData.ReactorMeltdown.Contains(c));
if (noDamageRun)
{
UnlockAchievement("nodamagerun", true, c => c != null && !c.IsDead);
}
}
#endif
#if CLIENT
if (noDamageRun) { UnlockAchievement("nodamagerun"); }
if (roundData.ReactorMeltdown.Any()) //in SP getting to the destination after a meltdown is enough
{
UnlockAchievement("survivereactormeltdown");
@@ -302,6 +351,11 @@ namespace Barotrauma
UnlockAchievement(charactersInSub[0], "lonesailor");
}
}
foreach (Character character in charactersInSub)
{
if (character.Info.Job == null) { continue; }
UnlockAchievement(character, character.Info.Job.Prefab.Identifier + "round");
}
}
}