Renamed project folders from Subsurface to Barotrauma

This commit is contained in:
Regalis
2017-06-04 15:00:53 +03:00
parent ad03c8bf0d
commit 94c6a8ea1b
697 changed files with 157 additions and 211 deletions
@@ -0,0 +1,292 @@
using System.Xml.Linq;
using FarseerPhysics;
using Microsoft.Xna.Framework;
using System.Collections.Generic;
namespace Barotrauma.Items.Components
{
class Holdable : Pickable
{
//the position(s) in the item that the Character grabs
protected Vector2[] handlePos;
private List<RelatedItem> prevRequiredItems;
string prevMsg;
//the distance from the holding characters elbow to center of the physics body of the item
protected Vector2 holdPos;
protected Vector2 aimPos;
//protected bool aimable;
private bool attachable, attached, attachedByDefault;
private PhysicsBody body;
//the angle in which the Character holds the item
protected float holdAngle;
[HasDefaultValue(false, true)]
public bool Attached
{
get { return attached && item.ParentInventory == null; }
set { attached = value; }
}
[HasDefaultValue(false, false)]
public bool ControlPose
{
get;
set;
}
[HasDefaultValue(false, false)]
public bool Attachable
{
get { return attachable; }
set { attachable = value; }
}
[HasDefaultValue(false, false)]
public bool AttachedByDefault
{
get { return attachedByDefault; }
set { attachedByDefault = value; }
}
[HasDefaultValue("0.0,0.0", false)]
public string HoldPos
{
get { return ToolBox.Vector2ToString(ConvertUnits.ToDisplayUnits(holdPos)); }
set { holdPos = ConvertUnits.ToSimUnits(ToolBox.ParseToVector2(value)); }
}
[HasDefaultValue("0.0,0.0", false)]
public string AimPos
{
get { return ToolBox.Vector2ToString(ConvertUnits.ToDisplayUnits(aimPos)); }
set { aimPos = ConvertUnits.ToSimUnits(ToolBox.ParseToVector2(value)); }
}
[HasDefaultValue(0.0f, false)]
public float HoldAngle
{
get { return MathHelper.ToDegrees(holdAngle); }
set { holdAngle = MathHelper.ToRadians(value); }
}
public Holdable(Item item, XElement element)
: base(item, element)
{
body = item.body;
handlePos = new Vector2[2];
for (int i = 1; i < 3; i++)
{
handlePos[i - 1] = ToolBox.GetAttributeVector2(element, "handle" + i, Vector2.Zero);
handlePos[i - 1] = ConvertUnits.ToSimUnits(handlePos[i - 1]);
}
canBePicked = true;
if (attachable)
{
prevRequiredItems = new List<RelatedItem>(requiredItems);
prevMsg = Msg;
requiredItems.Clear();
Msg = "";
}
if (attachedByDefault || (Screen.Selected == GameMain.EditMapScreen)) Use(1.0f);
//holdAngle = ToolBox.GetAttributeFloat(element, "holdangle", 0.0f);
//holdAngle = MathHelper.ToRadians(holdAngle);
}
public override void Drop(Character dropper)
{
DropConnectedWires(dropper);
if (body != null) item.body = body;
if (item.body != null) item.body.Enabled = true;
IsActive = false;
if (picker == null)
{
if (dropper == null) return;
picker = dropper;
}
if (picker.Inventory == null) return;
item.Submarine = picker.Submarine;
if (item.body != null)
{
item.body.ResetDynamics();
item.SetTransform(picker.SimPosition, 0.0f);
}
picker.DeselectItem(item);
picker.Inventory.RemoveItem(item);
picker = null;
}
public override void Equip(Character character)
{
picker = character;
if (character != null) item.Submarine = character.Submarine;
if (item.body == null)
{
if (body != null)
{
item.body = body;
}
else
{
return;
}
}
if (!item.body.Enabled)
{
Limb rightHand = picker.AnimController.GetLimb(LimbType.RightHand);
item.SetTransform(rightHand.SimPosition, 0.0f);
}
bool alreadySelected = character.HasSelectedItem(item);
if (picker.TrySelectItem(item))
{
item.body.Enabled = true;
IsActive = true;
if (!alreadySelected) Networking.GameServer.Log(character.Name + " equipped " + item.Name, Networking.ServerLog.MessageType.ItemInteraction);
}
}
public override void Unequip(Character character)
{
if (picker == null) return;
picker.DeselectItem(item);
Networking.GameServer.Log(character.Name + " unequipped " + item.Name, Networking.ServerLog.MessageType.ItemInteraction);
item.body.Enabled = false;
IsActive = false;
}
public override bool Pick(Character picker)
{
if (!attachable)
{
return base.Pick(picker);
}
if (!base.Pick(picker))
{
return false;
}
else
{
requiredItems.Clear();
Msg = "";
}
attached = false;
if (body != null) item.body = body;
//item.body.Enabled = true;
return true;
}
public override bool Use(float deltaTime, Character character = null)
{
if (!attachable || item.body == null) return true;
if (character != null && !character.IsKeyDown(InputType.Aim)) return false;
item.Drop();
var containedItems = item.ContainedItems;
if (containedItems != null)
{
foreach (Item contained in containedItems)
{
if (contained.body == null) continue;
contained.SetTransform(item.SimPosition, contained.body.Rotation);
}
}
item.body.Enabled = false;
item.body = null;
requiredItems = new List<RelatedItem>(prevRequiredItems);
Msg = prevMsg;
attached = true;
return true;
}
public override void UpdateBroken(float deltaTime, Camera cam)
{
Update(deltaTime, cam);
}
public override void Update(float deltaTime, Camera cam)
{
if (item.body == null || !item.body.Enabled) return;
if (!picker.HasSelectedItem(item)) IsActive = false;
ApplyStatusEffects(ActionType.OnActive, deltaTime, picker);
if (item.body.Dir != picker.AnimController.Dir) Flip(item);
item.Submarine = picker.Submarine;
picker.AnimController.HoldItem(deltaTime, item, handlePos, holdPos, aimPos, picker.IsKeyDown(InputType.Aim), holdAngle);
}
protected void Flip(Item item)
{
handlePos[0].X = -handlePos[0].X;
handlePos[1].X = -handlePos[1].X;
item.body.Dir = -item.body.Dir;
}
public override void OnMapLoaded()
{
//prevRequiredItems = new List<RelatedItem>(requiredItems);
if (!attachable) return;
if (Attached)
{
Use(1.0f);
}
else
{
if (item.ParentInventory != null)
{
if (body != null)
{
item.body = body;
body.Enabled = false;
}
attached = false;
}
requiredItems.Clear();
Msg = "";
}
}
}
}
@@ -0,0 +1,261 @@
using FarseerPhysics;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Dynamics.Contacts;
using Microsoft.Xna.Framework;
using System;
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma.Items.Components
{
class MeleeWeapon : Holdable
{
private float hitPos;
private bool hitting;
private Attack attack;
private float range;
private Character user;
private float reload;
private float reloadTimer;
[HasDefaultValue(0.0f, false)]
public float Range
{
get { return ConvertUnits.ToDisplayUnits(range); }
set { range = ConvertUnits.ToSimUnits(value); }
}
[HasDefaultValue(0.5f, false)]
public float Reload
{
get { return reload; }
set { reload = Math.Max(0.0f, value); }
}
public MeleeWeapon(Item item, XElement element)
: base(item, element)
{
//throwForce = ToolBox.GetAttributeFloat(element, "throwforce", 1.0f);
foreach (XElement subElement in element.Elements())
{
if (subElement.Name.ToString().ToLowerInvariant() != "attack") continue;
attack = new Attack(subElement);
}
}
public override bool Use(float deltaTime, Character character = null)
{
if (character == null || reloadTimer>0.0f) return false;
if (!character.IsKeyDown(InputType.Aim) || hitting) return false;
//don't allow hitting if the character is already hitting with another weapon
for (int i = 0; i < 2; i++ )
{
if (character.SelectedItems[i] == null || character.SelectedItems[i] == Item) continue;
var otherWeapon = character.SelectedItems[i].GetComponent<MeleeWeapon>();
if (otherWeapon == null) continue;
if (otherWeapon.hitting) return false;
}
SetUser(character);
if (hitPos < MathHelper.Pi * 0.69f) return false;
reloadTimer = reload;
item.body.FarseerBody.CollisionCategories = Physics.CollisionProjectile;
item.body.FarseerBody.CollidesWith = Physics.CollisionCharacter | Physics.CollisionWall;
item.body.FarseerBody.OnCollision += OnCollision;
foreach (Limb l in character.AnimController.Limbs)
{
//item.body.FarseerBody.IgnoreCollisionWith(l.body.FarseerBody);
if (character.AnimController.InWater) continue;
if (l.type == LimbType.LeftFoot || l.type == LimbType.LeftThigh || l.type == LimbType.LeftLeg) continue;
if (l.type == LimbType.Head || l.type == LimbType.Torso)
{
l.body.ApplyLinearImpulse(new Vector2(character.AnimController.Dir * 7.0f, -4.0f));
}
else
{
l.body.ApplyLinearImpulse(new Vector2(character.AnimController.Dir * 5.0f, -2.0f));
}
}
hitting = true;
IsActive = true;
return false;
}
public override void Drop(Character dropper)
{
base.Drop(dropper);
hitting = false;
hitPos = 0.0f;
}
public override void UpdateBroken(float deltaTime, Camera cam)
{
Update(deltaTime, cam);
}
public override void Update(float deltaTime, Camera cam)
{
if (!item.body.Enabled) return;
if (!picker.HasSelectedItem(item)) IsActive = false;
reloadTimer -= deltaTime;
if (!picker.IsKeyDown(InputType.Aim) && !hitting) hitPos = 0.0f;
ApplyStatusEffects(ActionType.OnActive, deltaTime, picker);
if (item.body.Dir != picker.AnimController.Dir) Flip(item);
AnimController ac = picker.AnimController;
if (!hitting)
{
if (picker.IsKeyDown(InputType.Aim))
{
hitPos = Math.Min(hitPos+deltaTime*5.0f, MathHelper.Pi*0.7f);
ac.HoldItem(deltaTime, item, handlePos, new Vector2(0.6f, -0.1f), new Vector2(-0.3f, 0.2f), false, hitPos);
}
else
{
ac.HoldItem(deltaTime, item, handlePos, new Vector2(hitPos, 0.0f), aimPos, false, holdAngle);
}
}
else
{
//Vector2 diff = Vector2.Normalize(picker.CursorPosition - ac.RefLimb.Position);
//diff.X = diff.X * ac.Dir;
hitPos -= deltaTime*15.0f;
//angl = -hitPos * 2.0f;
// System.Diagnostics.Debug.WriteLine("<1.0f "+hitPos);
ac.HoldItem(deltaTime, item, handlePos, new Vector2(0.6f, -0.1f), new Vector2(-0.3f, 0.2f), false, hitPos);
//}
//else
//{
// System.Diagnostics.Debug.WriteLine(">1.0f " + hitPos);
// ac.HoldItem(deltaTime, item, handlePos, new Vector2(0.5f, 0.2f), new Vector2(1.0f, 0.2f), false, 0.0f);
//}
if (hitPos < -MathHelper.PiOver4*1.2f)
{
RestoreCollision();
hitting = false;
}
}
}
private void SetUser(Character character)
{
if (user == character) return;
if (user != null)
{
foreach (Limb limb in user.AnimController.Limbs)
{
try
{
item.body.FarseerBody.RestoreCollisionWith(limb.body.FarseerBody);
}
catch
{
continue;
}
}
}
foreach (Limb limb in character.AnimController.Limbs)
{
item.body.FarseerBody.IgnoreCollisionWith(limb.body.FarseerBody);
}
user = character;
}
private void RestoreCollision()
{
item.body.FarseerBody.OnCollision -= OnCollision;
item.body.CollisionCategories = Physics.CollisionItem;
item.body.CollidesWith = Physics.CollisionWall;
//foreach (Limb l in picker.AnimController.Limbs)
//{
// item.body.FarseerBody.RestoreCollisionWith(l.body.FarseerBody);
//}
}
private bool OnCollision(Fixture f1, Fixture f2, Contact contact)
{
Character target = null;
Limb limb = f2.Body.UserData as Limb;
if (limb != null)
{
if (limb.character == picker) return false;
target = limb.character;
}
else
{
return false;
}
if (target == null)
{
target = f2.Body.UserData as Character;
}
if (target == null) return false;
if (attack != null) attack.DoDamage(user, target, item.WorldPosition, 1.0f);
RestoreCollision();
hitting = false;
if (GameMain.Client != null) return true;
if (GameMain.Server != null)
{
GameMain.Server.CreateEntityEvent(item, new object[] { Networking.NetEntityEvent.Type.ApplyStatusEffect, ActionType.OnUse, target.ID });
string logStr = picker?.Name + " used " + item.Name;
if (item.ContainedItems != null && item.ContainedItems.Length > 0)
{
logStr += "(" + string.Join(", ", item.ContainedItems.Select(i => i?.Name)) + ")";
}
logStr += " on " + target + ".";
Networking.GameServer.Log(logStr, Networking.ServerLog.MessageType.Attack);
}
ApplyStatusEffects(ActionType.OnUse, 1.0f, limb.character);
return true;
}
}
}
@@ -0,0 +1,209 @@
using Barotrauma.Networking;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Xml.Linq;
namespace Barotrauma.Items.Components
{
class Pickable : ItemComponent
{
protected Character picker;
protected List<InvSlotType> allowedSlots;
private float pickTimer;
public List<InvSlotType> AllowedSlots
{
get { return allowedSlots; }
}
public Character Picker
{
get { return picker; }
}
public Pickable(Item item, XElement element)
: base(item, element)
{
allowedSlots = new List<InvSlotType>();
string slotString = ToolBox.GetAttributeString(element, "slots", "Any");
string[] slotCombinations = slotString.Split(',');
foreach (string slotCombination in slotCombinations)
{
string[] slots = slotCombination.Split('+');
InvSlotType allowedSlot = InvSlotType.None;
foreach (string slot in slots)
{
if (slot.ToLowerInvariant() == "bothhands")
{
allowedSlot = InvSlotType.LeftHand | InvSlotType.RightHand;
}
else
{
allowedSlot = allowedSlot | (InvSlotType)Enum.Parse(typeof(InvSlotType), slot.Trim());
}
}
allowedSlots.Add(allowedSlot);
}
canBePicked = true;
}
public override bool Pick(Character picker)
{
//return if someone is already trying to pick the item
if (pickTimer>0.0f) return false;
if (picker == null || picker.Inventory == null) return false;
if (PickingTime>0.0f)
{
CoroutineManager.StartCoroutine(WaitForPick(picker, PickingTime));
return false;
}
else
{
return OnPicked(picker);
}
}
private bool OnPicked(Character picker)
{
if (picker.Inventory.TryPutItem(item, allowedSlots))
{
if (!picker.HasSelectedItem(item) && item.body != null) item.body.Enabled = false;
this.picker = picker;
for (int i = item.linkedTo.Count - 1; i >= 0; i--)
{
item.linkedTo[i].RemoveLinked(item);
}
item.linkedTo.Clear();
DropConnectedWires(picker);
ApplyStatusEffects(ActionType.OnPicked, 1.0f, picker);
return true;
}
return false;
}
private IEnumerable<object> WaitForPick(Character picker, float requiredTime)
{
var leftHand = picker.AnimController.GetLimb(LimbType.LeftHand);
var rightHand = picker.AnimController.GetLimb(LimbType.RightHand);
pickTimer = 0.0f;
while (pickTimer < requiredTime && Screen.Selected != GameMain.EditMapScreen)
{
if (picker.IsKeyDown(InputType.Aim) ||
!item.IsInPickRange(picker.WorldPosition) ||
picker.Stun > 0.0f || picker.IsDead)
{
StopPicking(picker);
yield return CoroutineStatus.Success;
}
picker.UpdateHUDProgressBar(
this,
item.WorldPosition,
pickTimer / requiredTime,
Color.Red, Color.Green);
picker.AnimController.Anim = AnimController.Animation.UsingConstruction;
picker.AnimController.TargetMovement = Vector2.Zero;
leftHand.Disabled = true;
leftHand.pullJoint.Enabled = true;
leftHand.pullJoint.WorldAnchorB = item.SimPosition + Vector2.UnitY * ((pickTimer / 10.0f) % 0.1f);
rightHand.Disabled = true;
rightHand.pullJoint.Enabled = true;
rightHand.pullJoint.WorldAnchorB = item.SimPosition + Vector2.UnitY * ((pickTimer / 10.0f) % 0.1f);
pickTimer += CoroutineManager.DeltaTime;
yield return CoroutineStatus.Running;
}
StopPicking(picker);
if (!picker.IsRemotePlayer) OnPicked(picker);
yield return CoroutineStatus.Success;
}
private void StopPicking(Character picker)
{
picker.AnimController.Anim = AnimController.Animation.None;
pickTimer = 0.0f;
}
protected void DropConnectedWires(Character character)
{
Vector2 pos = character == null ? item.SimPosition : character.SimPosition;
var connectionPanel = item.GetComponent<ConnectionPanel>();
if (connectionPanel == null) return;
foreach (Connection c in connectionPanel.Connections)
{
foreach (Wire w in c.Wires)
{
if (w == null) continue;
w.Item.Drop(character);
w.Item.SetTransform(pos, 0.0f);
}
}
}
public override void Drop(Character dropper)
{
if (picker == null)
{
picker = dropper;
}
Vector2 bodyDropPos = Vector2.Zero;
if (picker == null || picker.Inventory == null)
{
if (item.ParentInventory != null && item.ParentInventory.Owner != null)
{
bodyDropPos = item.ParentInventory.Owner.SimPosition;
if (item.body != null) item.body.ResetDynamics();
}
}
else
{
DropConnectedWires(picker);
item.Submarine = picker.Submarine;
bodyDropPos = picker.SimPosition;
picker.Inventory.RemoveItem(item);
picker = null;
}
if (item.body != null && !item.body.Enabled)
{
item.body.ResetDynamics();
item.SetTransform(bodyDropPos, 0.0f);
item.body.Enabled = true;
}
}
}
}
@@ -0,0 +1,104 @@
using System.Xml.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Barotrauma.Particles;
namespace Barotrauma.Items.Components
{
class Propulsion : ItemComponent
{
private float force;
private string particles;
private float useState;
private ParticlePrefab.DrawTargetType usableIn;
[HasDefaultValue(0.0f, false)]
public float Force
{
get { return force; }
set { force = value; }
}
[HasDefaultValue("", false)]
public string Particles
{
get { return particles; }
set { particles = value; }
}
public Propulsion(Item item, XElement element)
: base(item,element)
{
switch (ToolBox.GetAttributeString(element, "usablein", "both").ToLowerInvariant())
{
case "air":
usableIn = ParticlePrefab.DrawTargetType.Air;
break;
case "water":
usableIn = ParticlePrefab.DrawTargetType.Water;
break;
case "both":
default:
usableIn = ParticlePrefab.DrawTargetType.Both;
break;
}
}
public override bool Use(float deltaTime, Character character = null)
{
if (character == null) return false;
if (!character.IsKeyDown(InputType.Aim) || character.Stun>0.0f) return false;
IsActive = true;
useState = 0.1f;
if (character.AnimController.InWater)
{
if (usableIn == ParticlePrefab.DrawTargetType.Air) return true;
}
else
{
if (usableIn == ParticlePrefab.DrawTargetType.Water) return true;
}
Vector2 dir = Vector2.Normalize(character.CursorPosition - character.Position);
Vector2 propulsion = dir * force;
if (character.AnimController.InWater) character.AnimController.TargetMovement = dir;
foreach (Limb limb in character.AnimController.Limbs)
{
if (limb.WearingItems.Find(w => w.WearableComponent.Item == this.item)==null) continue;
limb.body.ApplyForce(propulsion);
}
character.AnimController.Collider.ApplyForce(propulsion);
if (character.SelectedItems[0] == item) character.AnimController.GetLimb(LimbType.RightHand).body.ApplyForce(propulsion);
if (character.SelectedItems[1] == item) character.AnimController.GetLimb(LimbType.LeftHand).body.ApplyForce(propulsion);
if (!string.IsNullOrWhiteSpace(particles))
{
GameMain.ParticleManager.CreateParticle(particles, item.WorldPosition,
item.body.Rotation + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi), 0.0f, item.CurrentHull);
}
return true;
}
public override void Update(float deltaTime, Camera cam)
{
useState -= deltaTime;
if (useState <= 0.0f) IsActive = false;
}
}
}
@@ -0,0 +1,126 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using FarseerPhysics;
using FarseerPhysics.Dynamics;
using Microsoft.Xna.Framework;
namespace Barotrauma.Items.Components
{
class RangedWeapon : ItemComponent
{
private float reload, reloadTimer;
private Vector2 barrelPos;
[HasDefaultValue("0.0,0.0", false)]
public string BarrelPos
{
get { return ToolBox.Vector2ToString(ConvertUnits.ToDisplayUnits(barrelPos)); }
set { barrelPos = ConvertUnits.ToSimUnits(ToolBox.ParseToVector2(value)); }
}
[HasDefaultValue(1.0f, false)]
public float Reload
{
get { return reload; }
set { reload = Math.Max(value, 0.0f); }
}
public Vector2 TransformedBarrelPos
{
get
{
Matrix bodyTransform = Matrix.CreateRotationZ(item.body.Rotation);
Vector2 flippedPos = barrelPos;
if (item.body.Dir < 0.0f) flippedPos.X = -flippedPos.X;
return (Vector2.Transform(flippedPos, bodyTransform) + item.body.SimPosition);
}
}
public RangedWeapon(Item item, XElement element)
: base(item, element)
{
//barrelPos = ToolBox.GetAttributeVector2(element, "barrelpos", Vector2.Zero);
//barrelPos = ConvertUnits.ToSimUnits(barrelPos);
}
public override void Update(float deltaTime, Camera cam)
{
reloadTimer -= deltaTime;
if (reloadTimer < 0.0f)
{
reloadTimer = 0.0f;
IsActive = false;
}
}
public override bool Use(float deltaTime, Character character = null)
{
if (character == null) return false;
if (!character.IsKeyDown(InputType.Aim) || reloadTimer > 0.0f) return false;
IsActive = true;
reloadTimer = reload;
List<Body> limbBodies = new List<Body>();
foreach (Limb l in character.AnimController.Limbs)
{
limbBodies.Add(l.body.FarseerBody);
}
float degreeOfFailure = (100.0f - DegreeOfSuccess(character))/100.0f;
degreeOfFailure *= degreeOfFailure;
if (degreeOfFailure > Rand.Range(0.0f, 1.0f))
{
ApplyStatusEffects(ActionType.OnFailure, 1.0f, character);
}
Item[] containedItems = item.ContainedItems;
if (containedItems != null)
{
foreach (Item projectile in containedItems)
{
if (projectile == null) continue;
//find the projectile-itemcomponent of the projectile,
//and add the limbs of the shooter to the list of bodies to be ignored
//so that the player can't shoot himself
Projectile projectileComponent= projectile.GetComponent<Projectile>();
if (projectileComponent == null) continue;
projectile.body.ResetDynamics();
projectile.SetTransform(TransformedBarrelPos,
((item.body.Dir == 1.0f) ? item.body.Rotation : item.body.Rotation - MathHelper.Pi)
+ Rand.Range(-degreeOfFailure, degreeOfFailure));
projectile.Use(deltaTime);
projectileComponent.User = character;
projectile.body.ApplyTorque(projectile.body.Mass * degreeOfFailure * Rand.Range(-10.0f, 10.0f));
//recoil
item.body.ApplyLinearImpulse(
new Vector2((float)Math.Cos(projectile.body.Rotation), (float)Math.Sin(projectile.body.Rotation)) * item.body.Mass * -50.0f);
projectileComponent.IgnoredBodies = limbBodies;
item.RemoveContained(projectile);
Rope rope = item.GetComponent<Rope>();
if (rope != null) rope.Attach(projectile);
return true;
}
}
return true;
}
}
}
@@ -0,0 +1,271 @@
using System;
using System.Collections.Generic;
using System.Xml.Linq;
using FarseerPhysics;
using FarseerPhysics.Dynamics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Barotrauma.Items.Components
{
class RepairTool : ItemComponent
{
private readonly List<string> fixableEntities;
private float range;
private Vector2 pickedPosition;
private Vector2 barrelPos;
private string particles;
private float activeTimer;
[HasDefaultValue(0.0f, false)]
public float Range
{
get { return range; }
set { range = value; }
}
[HasDefaultValue(0.0f, false)]
public float StructureFixAmount
{
get; set;
}
[HasDefaultValue(0.0f, false)]
public float LimbFixAmount
{
get; set;
}
[HasDefaultValue(0.0f, false)]
public float ExtinquishAmount
{
get; set;
}
[HasDefaultValue("", false)]
public string Particles
{
get { return particles; }
set { particles = value; }
}
[HasDefaultValue(0.0f, false)]
public float ParticleSpeed
{
get; set;
}
[HasDefaultValue("0.0,0.0", false)]
public string BarrelPos
{
get { return ToolBox.Vector2ToString(barrelPos); }
set { barrelPos = ToolBox.ParseToVector2(value); }
}
public Vector2 TransformedBarrelPos
{
get
{
Matrix bodyTransform = Matrix.CreateRotationZ(item.body.Rotation);
Vector2 flippedPos = barrelPos;
if (item.body.Dir < 0.0f) flippedPos.X = -flippedPos.X;
return (Vector2.Transform(flippedPos, bodyTransform));
}
}
public RepairTool(Item item, XElement element)
: base(item, element)
{
this.item = item;
fixableEntities = new List<string>();
foreach (XElement subElement in element.Elements())
{
switch (subElement.Name.ToString().ToLowerInvariant())
{
case "fixable":
fixableEntities.Add(subElement.Attribute("name").Value);
break;
}
}
}
public override void Update(float deltaTime, Camera cam)
{
activeTimer -= deltaTime;
if (activeTimer <= 0.0f) IsActive = false;
}
public override bool Use(float deltaTime, Character character = null)
{
if (character == null) return false;
if (!character.IsKeyDown(InputType.Aim)) return false;
//if (DoesUseFail(Character)) return false;
//targetPosition = targetPosition.X, -targetPosition.Y);
float degreeOfSuccess = DegreeOfSuccess(character)/100.0f;
if (Rand.Range(0.0f, 0.5f) > degreeOfSuccess)
{
ApplyStatusEffects(ActionType.OnFailure, deltaTime, character);
return false;
}
Vector2 targetPosition = item.WorldPosition;
targetPosition += new Vector2(
(float)Math.Cos(item.body.Rotation),
(float)Math.Sin(item.body.Rotation)) * range * item.body.Dir;
List<Body> ignoredBodies = new List<Body>();
foreach (Limb limb in character.AnimController.Limbs)
{
if (Rand.Range(0.0f, 0.5f) > degreeOfSuccess) continue;
ignoredBodies.Add(limb.body.FarseerBody);
}
IsActive = true;
activeTimer = 0.1f;
Vector2 rayStart = ConvertUnits.ToSimUnits(item.WorldPosition);
Vector2 rayEnd = ConvertUnits.ToSimUnits(targetPosition);
if (character.Submarine == null)
{
foreach (Submarine sub in Submarine.Loaded)
{
Repair(rayStart - sub.SimPosition, rayEnd - sub.SimPosition, deltaTime, character, degreeOfSuccess, ignoredBodies);
}
Repair(rayStart, rayEnd, deltaTime, character, degreeOfSuccess, ignoredBodies);
}
else
{
Repair(rayStart - character.Submarine.SimPosition, rayEnd - character.Submarine.SimPosition, deltaTime, character, degreeOfSuccess, ignoredBodies);
}
GameMain.ParticleManager.CreateParticle(particles, item.WorldPosition + TransformedBarrelPos,
-item.body.Rotation + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi), ParticleSpeed);
return true;
}
private void Repair(Vector2 rayStart, Vector2 rayEnd, float deltaTime, Character user, float degreeOfSuccess, List<Body> ignoredBodies)
{
if (ExtinquishAmount > 0.0f && item.CurrentHull != null)
{
Vector2 displayPos = ConvertUnits.ToDisplayUnits(rayStart + (rayEnd - rayStart) * Submarine.LastPickedFraction * 0.9f);
displayPos += item.CurrentHull.Submarine.Position;
Hull hull = Hull.FindHull(displayPos, item.CurrentHull);
if (hull != null)
{
hull.Extinquish(deltaTime, ExtinquishAmount, displayPos);
if (hull != item.CurrentHull)
{
item.CurrentHull.Extinquish(deltaTime, ExtinquishAmount, displayPos);
}
}
}
Body targetBody = Submarine.PickBody(rayStart, rayEnd, ignoredBodies);
if (targetBody == null || targetBody.UserData == null) return;
pickedPosition = Submarine.LastPickedPosition;
Structure targetStructure;
Limb targetLimb;
Item targetItem;
if ((targetStructure = (targetBody.UserData as Structure)) != null)
{
if (!fixableEntities.Contains("structure") && !fixableEntities.Contains(targetStructure.Name)) return;
if (targetStructure.IsPlatform) return;
int sectionIndex = targetStructure.FindSectionIndex(ConvertUnits.ToDisplayUnits(pickedPosition));
if (sectionIndex < 0) return;
Vector2 progressBarPos = targetStructure.SectionPosition(sectionIndex);
if (targetStructure.Submarine != null)
{
progressBarPos += targetStructure.Submarine.DrawPosition;
}
var progressBar = user.UpdateHUDProgressBar(
targetStructure,
progressBarPos,
1.0f - targetStructure.SectionDamage(sectionIndex) / targetStructure.Health,
Color.Red, Color.Green);
if (progressBar != null) progressBar.Size = new Vector2(60.0f, 20.0f);
targetStructure.AddDamage(sectionIndex, -StructureFixAmount * degreeOfSuccess);
//if the next section is small enough, apply the effect to it as well
//(to make it easier to fix a small "left-over" section)
for (int i = -1; i < 2; i += 2)
{
int nextSectionLength = targetStructure.SectionLength(sectionIndex + i);
if ((sectionIndex == 1 && i == -1) ||
(sectionIndex == targetStructure.SectionCount - 2 && i == 1) ||
(nextSectionLength > 0 && nextSectionLength < Structure.wallSectionSize * 0.3f))
{
//targetStructure.HighLightSection(sectionIndex + i);
targetStructure.AddDamage(sectionIndex + i, -StructureFixAmount * degreeOfSuccess);
}
}
}
else if ((targetLimb = (targetBody.UserData as Limb)) != null)
{
targetLimb.character.AddDamage(CauseOfDeath.Damage, -LimbFixAmount * degreeOfSuccess, user);
}
else if ((targetItem = (targetBody.UserData as Item)) != null)
{
targetItem.IsHighlighted = true;
ApplyStatusEffects(ActionType.OnUse, targetItem.AllPropertyObjects, deltaTime);
}
}
public override bool AIOperate(float deltaTime, Character character, AIObjectiveOperateItem objective)
{
Gap leak = objective.OperateTarget as Gap;
if (leak == null) return true;
float dist = Vector2.Distance(leak.WorldPosition, item.WorldPosition);
//too far away -> consider this done and hope the AI is smart enough to move closer
if (dist > range * 5.0f) return true;
//steer closer if almost in range
if (dist > range)
{
Vector2 standPos = leak.isHorizontal ?
new Vector2(Math.Sign(item.WorldPosition.X - leak.WorldPosition.X), 0.0f)
: new Vector2(0.0f, Math.Sign(item.WorldPosition.Y - leak.WorldPosition.Y));
standPos = leak.WorldPosition + standPos * range;
character.AIController.SteeringManager.SteeringManual(deltaTime, (standPos - character.WorldPosition) / 1000.0f);
}
else
{
//close enough -> stop moving
character.AIController.SteeringManager.Reset();
}
character.CursorPosition = leak.Position;
character.SetInput(InputType.Aim, false, true);
Use(deltaTime, character);
return leak.Open <= 0.0f;
}
}
}
@@ -0,0 +1,143 @@
using Microsoft.Xna.Framework;
using System.Xml.Linq;
namespace Barotrauma.Items.Components
{
class Throwable : Holdable
{
float throwForce;
float throwPos;
bool throwing;
[HasDefaultValue(1.0f, false)]
public float ThrowForce
{
get { return throwForce; }
set { throwForce = value; }
}
public Throwable(Item item, XElement element)
: base(item, element)
{
//throwForce = ToolBox.GetAttributeFloat(element, "throwforce", 1.0f);
}
public override bool Use(float deltaTime, Character character = null)
{
if (character == null) return false;
if (!character.IsKeyDown(InputType.Aim) || throwing) return false;
//Vector2 diff = Vector2.Normalize(Character.CursorPosition - Character.AnimController.RefLimb.Position);
//if (Character.SelectedItems[1]==item)
//{
// Limb leftHand = Character.AnimController.GetLimb(LimbType.LeftHand);
// leftHand.body.ApplyLinearImpulse(diff * 20.0f);
// leftHand.Disabled = true;
//}
//if (Character.SelectedItems[0] == item)
//{
// Limb rightHand = Character.AnimController.GetLimb(LimbType.RightHand);
// rightHand.body.ApplyLinearImpulse(diff * 20.0f);
// rightHand.Disabled = true;
//}
throwing = true;
IsActive = true;
return true;
}
public override void SecondaryUse(float deltaTime, Character character = null)
{
if (throwing) return;
}
public override void Drop(Character dropper)
{
base.Drop(dropper);
throwing = false;
throwPos = 0.0f;
}
public override void UpdateBroken(float deltaTime, Camera cam)
{
Update(deltaTime, cam);
}
public override void Update(float deltaTime, Camera cam)
{
if (!item.body.Enabled) return;
if (!picker.HasSelectedItem(item)) IsActive = false;
if (!picker.IsKeyDown(InputType.Aim) && !throwing) throwPos = 0.0f;
ApplyStatusEffects(ActionType.OnActive, deltaTime, picker);
if (item.body.Dir != picker.AnimController.Dir) Flip(item);
AnimController ac = picker.AnimController;
item.Submarine = picker.Submarine;
if (!throwing)
{
if (picker.IsKeyDown(InputType.Aim))
{
throwPos = (float)System.Math.Min(throwPos+deltaTime*5.0f, MathHelper.Pi*0.7f);
ac.HoldItem(deltaTime, item, handlePos, new Vector2(0.6f, -0.0f), new Vector2(-0.3f, 0.2f), false, throwPos);
}
else
{
ac.HoldItem(deltaTime, item, handlePos, new Vector2(throwPos, 0.0f), aimPos, false, 0.0f);
}
}
else
{
//Vector2 diff = Vector2.Normalize(picker.CursorPosition - ac.RefLimb.Position);
//diff.X = diff.X * ac.Dir;
throwPos -= deltaTime*15.0f;
//angl = -hitPos * 2.0f;
// System.Diagnostics.Debug.WriteLine("<1.0f "+hitPos);
ac.HoldItem(deltaTime, item, handlePos, new Vector2(0.6f, 0.0f), new Vector2(-0.3f, 0.2f), false, throwPos);
//}
//else
//{
// System.Diagnostics.Debug.WriteLine(">1.0f " + hitPos);
// ac.HoldItem(deltaTime, item, handlePos, new Vector2(0.5f, 0.2f), new Vector2(1.0f, 0.2f), false, 0.0f);
//}
if (throwPos < -0.0)
{
Vector2 throwVector = picker.CursorWorldPosition - picker.WorldPosition;
throwVector = Vector2.Normalize(throwVector);
item.Drop();
item.body.ApplyLinearImpulse(throwVector * throwForce * item.body.Mass * 3.0f);
ac.GetLimb(LimbType.Head).body.ApplyLinearImpulse(throwVector*10.0f);
ac.GetLimb(LimbType.Torso).body.ApplyLinearImpulse(throwVector * 10.0f);
Limb rightHand = ac.GetLimb(LimbType.RightHand);
item.body.AngularVelocity = rightHand.body.AngularVelocity;
throwing = false;
}
}
}
}
}