2f107db...5202af9
This commit is contained in:
@@ -288,7 +288,9 @@ namespace Barotrauma.Items.Components
|
||||
item.body.Enabled = true;
|
||||
IsActive = true;
|
||||
|
||||
#if SERVER
|
||||
if (!alreadySelected) GameServer.Log(character.LogName + " equipped " + item.Name, ServerLog.MessageType.ItemInteraction);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,8 +299,9 @@ namespace Barotrauma.Items.Components
|
||||
if (picker == null) return;
|
||||
|
||||
picker.DeselectItem(item);
|
||||
|
||||
#if SERVER
|
||||
GameServer.Log(character.LogName + " unequipped " + item.Name, ServerLog.MessageType.ItemInteraction);
|
||||
#endif
|
||||
|
||||
item.body.Enabled = false;
|
||||
IsActive = false;
|
||||
@@ -354,6 +357,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
DeattachFromWall();
|
||||
|
||||
#if SERVER
|
||||
if (GameMain.Server != null && attachable)
|
||||
{
|
||||
item.CreateServerEvent(this);
|
||||
@@ -362,6 +366,7 @@ namespace Barotrauma.Items.Components
|
||||
GameServer.Log(picker.LogName + " detached " + item.Name + " from a wall", ServerLog.MessageType.ItemInteraction);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -426,11 +431,13 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (!character.IsKeyDown(InputType.Aim)) return false;
|
||||
if (!CanBeAttached()) return false;
|
||||
#if SERVER
|
||||
if (GameMain.Server != null)
|
||||
{
|
||||
item.CreateServerEvent(this);
|
||||
GameServer.Log(character.LogName + " attached " + item.Name + " to a wall", ServerLog.MessageType.ItemInteraction);
|
||||
}
|
||||
#endif
|
||||
item.Drop();
|
||||
}
|
||||
|
||||
@@ -471,7 +478,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
ApplyStatusEffects(ActionType.OnActive, deltaTime, picker);
|
||||
|
||||
if (item.body.Dir != picker.AnimController.Dir) Flip(item);
|
||||
if (item.body.Dir != picker.AnimController.Dir) Flip();
|
||||
|
||||
item.Submarine = picker.Submarine;
|
||||
|
||||
@@ -507,7 +514,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
protected void Flip(Item item)
|
||||
public void Flip()
|
||||
{
|
||||
handlePos[0].X = -handlePos[0].X;
|
||||
handlePos[1].X = -handlePos[1].X;
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
deattachTimer = Math.Max(0.0f, value);
|
||||
//clients don't deattach the item until the server says so (handled in ClientRead)
|
||||
if (GameMain.Client == null && deattachTimer >= DeattachDuration)
|
||||
if ((GameMain.NetworkMember == null || !GameMain.NetworkMember.IsClient) && deattachTimer >= DeattachDuration)
|
||||
{
|
||||
holdable.DeattachFromWall();
|
||||
}
|
||||
@@ -80,6 +80,7 @@ namespace Barotrauma.Items.Components
|
||||
trigger.FarseerBody.IsSensor = true;
|
||||
trigger.FarseerBody.IsStatic = true;
|
||||
trigger.FarseerBody.CollisionCategories = Physics.CollisionWall;
|
||||
trigger.FarseerBody.CollidesWith = Physics.CollisionNone;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
ApplyStatusEffects(ActionType.OnActive, deltaTime, picker);
|
||||
|
||||
if (item.body.Dir != picker.AnimController.Dir) Flip(item);
|
||||
if (item.body.Dir != picker.AnimController.Dir) Flip();
|
||||
|
||||
AnimController ac = picker.AnimController;
|
||||
|
||||
@@ -294,8 +294,9 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
if (GameMain.Client != null) return true;
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) return true;
|
||||
|
||||
#if SERVER
|
||||
if (GameMain.Server != null && targetCharacter != null) //TODO: Log structure hits
|
||||
{
|
||||
|
||||
@@ -308,13 +309,14 @@ namespace Barotrauma.Items.Components
|
||||
});
|
||||
|
||||
string logStr = picker?.LogName + " used " + item.Name;
|
||||
if (item.ContainedItems != null && item.ContainedItems.Length > 0)
|
||||
if (item.ContainedItems != null && item.ContainedItems.Any())
|
||||
{
|
||||
logStr += "(" + string.Join(", ", item.ContainedItems.Select(i => i?.Name)) + ")";
|
||||
logStr += " (" + string.Join(", ", item.ContainedItems.Select(i => i?.Name)) + ")";
|
||||
}
|
||||
logStr += " on " + targetCharacter.LogName + ".";
|
||||
Networking.GameServer.Log(logStr, Networking.ServerLog.MessageType.Attack);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (targetCharacter != null) //TODO: Allow OnUse to happen on structures too maybe??
|
||||
{
|
||||
|
||||
@@ -66,7 +66,9 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (picker.PickingItem == null && PickingTime <= float.MaxValue)
|
||||
{
|
||||
#if SERVER
|
||||
item.CreateServerEvent(this);
|
||||
#endif
|
||||
CoroutineManager.StartCoroutine(WaitForPick(picker, PickingTime));
|
||||
}
|
||||
return false;
|
||||
@@ -143,7 +145,11 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
StopPicking(picker);
|
||||
|
||||
if (!picker.IsRemotePlayer || GameMain.Server != null) OnPicked(picker);
|
||||
bool isNotRemote = true;
|
||||
#if CLIENT
|
||||
isNotRemote = !picker.IsRemotePlayer;
|
||||
#endif
|
||||
if (isNotRemote) OnPicked(picker);
|
||||
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
Projectile projectile = null;
|
||||
Item[] containedItems = item.ContainedItems;
|
||||
var containedItems = item.ContainedItems;
|
||||
if (containedItems == null) return true;
|
||||
|
||||
foreach (Item item in containedItems)
|
||||
@@ -105,18 +105,29 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
foreach (Item item in containedItems)
|
||||
{
|
||||
Item[] containedSubItems = item.ContainedItems;
|
||||
foreach (Item subItem in containedSubItems)
|
||||
projectile = item.GetComponent<Projectile>();
|
||||
if (projectile != null) break;
|
||||
}
|
||||
//projectile not found, see if one of the contained items contains projectiles
|
||||
if (projectile == null)
|
||||
{
|
||||
foreach (Item item in containedItems)
|
||||
{
|
||||
projectile = subItem.GetComponent<Projectile>();
|
||||
|
||||
//apply OnUse statuseffects to the container in case it has to react to it somehow
|
||||
//(play a sound, spawn more projectiles, reduce condition...)
|
||||
subItem.GetComponent<ItemContainer>()?.Item.ApplyStatusEffects(ActionType.OnUse, deltaTime);
|
||||
if (projectile != null) break;
|
||||
var containedSubItems = item.ContainedItems;
|
||||
if (containedSubItems == null) { continue; }
|
||||
foreach (Item subItem in containedSubItems)
|
||||
{
|
||||
projectile = subItem.GetComponent<Projectile>();
|
||||
|
||||
//apply OnUse statuseffects to the container in case it has to react to it somehow
|
||||
//(play a sound, spawn more projectiles, reduce condition...)
|
||||
subItem.GetComponent<ItemContainer>()?.Item.ApplyStatusEffects(ActionType.OnUse, deltaTime);
|
||||
if (projectile != null) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (projectile == null) return true;
|
||||
|
||||
float spread = MathHelper.ToRadians(MathHelper.Lerp(Spread, UnskilledSpread, degreeOfFailure));
|
||||
|
||||
@@ -14,52 +14,35 @@ namespace Barotrauma.Items.Components
|
||||
partial class RepairTool : ItemComponent
|
||||
{
|
||||
private readonly List<string> fixableEntities;
|
||||
|
||||
private float range;
|
||||
|
||||
private Vector2 pickedPosition;
|
||||
|
||||
private Vector2 barrelPos;
|
||||
|
||||
private float activeTimer;
|
||||
|
||||
|
||||
[Serialize(0.0f, false)]
|
||||
public float Range
|
||||
{
|
||||
get { return range; }
|
||||
set { range = value; }
|
||||
}
|
||||
public float Range { get; set; }
|
||||
|
||||
[Serialize(0.0f, false)]
|
||||
public float StructureFixAmount
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
[Serialize(0.0f, false)]
|
||||
public float LimbFixAmount
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
[Serialize(0.0f, false)]
|
||||
public float ExtinguishAmount
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
|
||||
[Serialize("0.0,0.0", false)]
|
||||
public Vector2 BarrelPos
|
||||
{
|
||||
get { return barrelPos; }
|
||||
set { barrelPos = value; }
|
||||
}
|
||||
public Vector2 BarrelPos { get; set; }
|
||||
|
||||
[Serialize(false, false)]
|
||||
public bool RepairThroughWalls { get; set; }
|
||||
|
||||
public Vector2 TransformedBarrelPos
|
||||
{
|
||||
get
|
||||
{
|
||||
Matrix bodyTransform = Matrix.CreateRotationZ(item.body.Rotation);
|
||||
Vector2 flippedPos = barrelPos;
|
||||
Vector2 flippedPos = BarrelPos;
|
||||
if (item.body.Dir < 0.0f) flippedPos.X = -flippedPos.X;
|
||||
return (Vector2.Transform(flippedPos, bodyTransform));
|
||||
}
|
||||
@@ -70,6 +53,11 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
this.item = item;
|
||||
|
||||
if (element.Attribute("limbfixamount") != null)
|
||||
{
|
||||
DebugConsole.ThrowError("Error in item \"" + item.Name + "\" - RepairTool damage should be configured using a StatusEffect with Afflictions, not the limbfixamount attribute.");
|
||||
}
|
||||
|
||||
fixableEntities = new List<string>();
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
@@ -116,7 +104,7 @@ namespace Barotrauma.Items.Components
|
||||
Vector2 targetPosition = item.WorldPosition;
|
||||
targetPosition += new Vector2(
|
||||
(float)Math.Cos(item.body.Rotation),
|
||||
(float)Math.Sin(item.body.Rotation)) * range * item.body.Dir;
|
||||
(float)Math.Sin(item.body.Rotation)) * Range * item.body.Dir;
|
||||
|
||||
List<Body> ignoredBodies = new List<Body>();
|
||||
foreach (Limb limb in character.AnimController.Limbs)
|
||||
@@ -154,9 +142,20 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private void Repair(Vector2 rayStart, Vector2 rayEnd, float deltaTime, Character user, float degreeOfSuccess, List<Body> ignoredBodies)
|
||||
{
|
||||
Body targetBody = Submarine.PickBody(rayStart, rayEnd, ignoredBodies,
|
||||
Physics.CollisionWall | Physics.CollisionCharacter | Physics.CollisionItem | Physics.CollisionLevel | Physics.CollisionRepair, false);
|
||||
|
||||
var collisionCategories = Physics.CollisionWall | Physics.CollisionCharacter | Physics.CollisionItem | Physics.CollisionLevel | Physics.CollisionRepair;
|
||||
if (RepairThroughWalls)
|
||||
{
|
||||
var bodies = Submarine.PickBodies(rayStart, rayEnd, ignoredBodies, collisionCategories, ignoreSensors: false);
|
||||
foreach (Body body in bodies)
|
||||
{
|
||||
FixBody(user, deltaTime, degreeOfSuccess, body);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FixBody(user, deltaTime, degreeOfSuccess, Submarine.PickBody(rayStart, rayEnd, ignoredBodies, collisionCategories, ignoreSensors: false));
|
||||
}
|
||||
|
||||
if (ExtinguishAmount > 0.0f && item.CurrentHull != null)
|
||||
{
|
||||
List<FireSource> fireSourcesInRange = new List<FireSource>();
|
||||
@@ -164,7 +163,7 @@ namespace Barotrauma.Items.Components
|
||||
for (float x = 0.0f; x <= Submarine.LastPickedFraction; x += 0.1f)
|
||||
{
|
||||
Vector2 displayPos = ConvertUnits.ToDisplayUnits(rayStart + (rayEnd - rayStart) * x);
|
||||
if (item.CurrentHull.Submarine != null) { displayPos += item.CurrentHull.Submarine.Position; }
|
||||
if (item.CurrentHull.Submarine != null) { displayPos += item.CurrentHull.Submarine.Position; }
|
||||
|
||||
Hull hull = Hull.FindHull(displayPos, item.CurrentHull);
|
||||
if (hull == null) continue;
|
||||
@@ -182,11 +181,14 @@ namespace Barotrauma.Items.Components
|
||||
fs.Extinguish(deltaTime, ExtinguishAmount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (targetBody == null || targetBody.UserData == null) return;
|
||||
private void FixBody(Character user, float deltaTime, float degreeOfSuccess, Body targetBody)
|
||||
{
|
||||
if (targetBody?.UserData == null) { return; }
|
||||
|
||||
pickedPosition = Submarine.LastPickedPosition;
|
||||
|
||||
|
||||
if (targetBody.UserData is Structure targetStructure)
|
||||
{
|
||||
if (!fixableEntities.Contains("structure") && !fixableEntities.Contains(targetStructure.Prefab.Identifier)) return;
|
||||
@@ -214,20 +216,14 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
else if (targetBody.UserData is Character targetCharacter)
|
||||
{
|
||||
Vector2 hitPos = ConvertUnits.ToDisplayUnits(pickedPosition);
|
||||
if (targetCharacter.Submarine != null) hitPos += targetCharacter.Submarine.Position;
|
||||
|
||||
targetCharacter.LastDamageSource = item;
|
||||
targetCharacter.AddDamage(hitPos,
|
||||
new List<Affliction>() { AfflictionPrefab.Burn.Instantiate(-LimbFixAmount * degreeOfSuccess, user) }, 0.0f, false, 0.0f, user);
|
||||
ApplyStatusEffectsOnTarget(user, deltaTime, ActionType.OnUse, new List<ISerializableEntity>() { targetCharacter });
|
||||
FixCharacterProjSpecific(user, deltaTime, targetCharacter);
|
||||
}
|
||||
else if (targetBody.UserData is Limb targetLimb)
|
||||
{
|
||||
targetLimb.character.LastDamageSource = item;
|
||||
targetLimb.character.DamageLimb(targetLimb.WorldPosition, targetLimb,
|
||||
new List<Affliction>() { AfflictionPrefab.Burn.Instantiate(-LimbFixAmount * degreeOfSuccess, user) }, 0.0f, false, 0.0f, user);
|
||||
|
||||
ApplyStatusEffectsOnTarget(user, deltaTime, ActionType.OnUse, new List<ISerializableEntity>() { targetLimb.character, targetLimb });
|
||||
FixCharacterProjSpecific(user, deltaTime, targetLimb.character);
|
||||
}
|
||||
else if (targetBody.UserData is Item targetItem)
|
||||
@@ -236,7 +232,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
float prevCondition = targetItem.Condition;
|
||||
|
||||
ApplyStatusEffectsOnTarget(deltaTime, ActionType.OnUse, targetItem.AllPropertyObjects);
|
||||
ApplyStatusEffectsOnTarget(user, deltaTime, ActionType.OnUse, targetItem.AllPropertyObjects);
|
||||
|
||||
var levelResource = targetItem.GetComponent<LevelResource>();
|
||||
if (levelResource != null && levelResource.IsActive &&
|
||||
@@ -254,6 +250,11 @@ namespace Barotrauma.Items.Components
|
||||
FixItemProjSpecific(user, deltaTime, targetItem, prevCondition);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
partial void FixStructureProjSpecific(Character user, float deltaTime, Structure targetStructure, int sectionIndex);
|
||||
partial void FixCharacterProjSpecific(Character user, float deltaTime, Character targetCharacter);
|
||||
partial void FixItemProjSpecific(Character user, float deltaTime, Item targetItem, float prevCondition);
|
||||
|
||||
partial void FixStructureProjSpecific(Character user, float deltaTime, Structure targetStructure, int sectionIndex);
|
||||
partial void FixCharacterProjSpecific(Character user, float deltaTime, Character targetCharacter);
|
||||
@@ -267,7 +268,7 @@ namespace Barotrauma.Items.Components
|
||||
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;
|
||||
if (dist > Range * 5.0f) return true;
|
||||
|
||||
Vector2 gapDiff = leak.WorldPosition - item.WorldPosition;
|
||||
if (!character.AnimController.InWater && character.AnimController is HumanoidAnimController &&
|
||||
@@ -277,13 +278,13 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
//steer closer if almost in range
|
||||
if (dist > range)
|
||||
if (dist > Range)
|
||||
{
|
||||
Vector2 standPos = leak.IsHorizontal ?
|
||||
new Vector2(Math.Sign(-gapDiff.X), 0.0f)
|
||||
: new Vector2(0.0f, Math.Sign(-gapDiff.Y) * 0.5f);
|
||||
|
||||
standPos = leak.WorldPosition + standPos * range;
|
||||
standPos = leak.WorldPosition + standPos * Range;
|
||||
|
||||
character.AIController.SteeringManager.SteeringManual(deltaTime, (standPos - character.WorldPosition) / 1000.0f);
|
||||
}
|
||||
@@ -315,15 +316,14 @@ namespace Barotrauma.Items.Components
|
||||
return leakFixed;
|
||||
}
|
||||
|
||||
private void ApplyStatusEffectsOnTarget(float deltaTime, ActionType actionType, List<ISerializableEntity> targets)
|
||||
private void ApplyStatusEffectsOnTarget(Character user, float deltaTime, ActionType actionType, IEnumerable<ISerializableEntity> targets)
|
||||
{
|
||||
if (statusEffectLists == null) return;
|
||||
|
||||
List<StatusEffect> statusEffects;
|
||||
if (!statusEffectLists.TryGetValue(actionType, out statusEffects)) return;
|
||||
if (statusEffectLists == null) { return; }
|
||||
if (!statusEffectLists.TryGetValue(actionType, out List<StatusEffect> statusEffects)) { return; }
|
||||
|
||||
foreach (StatusEffect effect in statusEffects)
|
||||
{
|
||||
effect.SetUser(user);
|
||||
if (effect.HasTargetType(StatusEffect.TargetType.UseTarget))
|
||||
{
|
||||
effect.Apply(actionType, deltaTime, item, targets);
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
ApplyStatusEffects(ActionType.OnActive, deltaTime, picker);
|
||||
|
||||
if (item.body.Dir != picker.AnimController.Dir) Flip(item);
|
||||
if (item.body.Dir != picker.AnimController.Dir) Flip();
|
||||
|
||||
AnimController ac = picker.AnimController;
|
||||
|
||||
@@ -101,7 +101,9 @@ namespace Barotrauma.Items.Components
|
||||
//throw upwards if cursor is at the position of the character
|
||||
if (!MathUtils.IsValid(throwVector)) throwVector = Vector2.UnitY;
|
||||
|
||||
#if SERVER
|
||||
GameServer.Log(picker.LogName + " threw " + item.Name, ServerLog.MessageType.ItemInteraction);
|
||||
#endif
|
||||
|
||||
item.Drop();
|
||||
item.body.ApplyLinearImpulse(throwVector * throwForce * item.body.Mass * 3.0f);
|
||||
|
||||
Reference in New Issue
Block a user