This commit is contained in:
Evil Factory
2022-02-24 14:30:39 -03:00
364 changed files with 10838 additions and 3966 deletions
@@ -166,7 +166,7 @@ namespace Barotrauma.Items.Components
Pusher = new PhysicsBody(item.body.width, item.body.height, item.body.radius, item.body.Density)
{
BodyType = BodyType.Dynamic,
CollidesWith = Physics.CollisionCharacter,
CollidesWith = Physics.CollisionCharacter | Physics.CollisionProjectile,
CollisionCategories = Physics.CollisionItemBlocking,
Enabled = false,
UserData = this
@@ -237,10 +237,13 @@ namespace Barotrauma.Items.Components
}
}
private bool loadedFromXml;
public override void Load(XElement componentElement, bool usePrefabValues, IdRemap idRemap)
{
base.Load(componentElement, usePrefabValues, idRemap);
loadedFromXml = true;
if (usePrefabValues)
{
//this needs to be loaded regardless
@@ -536,7 +539,16 @@ namespace Barotrauma.Items.Components
else
{
attachTargetCell = GetAttachTargetCell(150.0f);
if (attachTargetCell != null) { IsActive = true; }
if (attachTargetCell != null && attachTargetCell.IsDestructible)
{
attachTargetCell.OnDestroyed += () =>
{
if (attachTargetCell != null && attachTargetCell.CellType != Voronoi2.CellType.Solid)
{
Drop(dropConnectedWires: true, dropper: null);
}
};
}
}
}
@@ -562,7 +574,7 @@ namespace Barotrauma.Items.Components
public void DeattachFromWall()
{
if (!attachable) return;
if (!attachable) { return; }
Attached = false;
attachTargetCell = null;
@@ -604,7 +616,14 @@ namespace Barotrauma.Items.Components
int maxAttachableCount = (int)character.Info.GetSavedStatValue(StatTypes.MaxAttachableCount, item.Prefab.Identifier);
int currentlyAttachedCount = Item.ItemList.Count(
i => i.Submarine == attachTarget?.Submarine && i.GetComponent<Holdable>() is Holdable holdable && holdable.Attached && i.Prefab.Identifier == item.prefab.Identifier);
if (currentlyAttachedCount >= maxAttachableCount)
if (maxAttachableCount == 0)
{
#if CLIENT
GUI.AddMessage(TextManager.Get("itemmsgrequiretraining"), Color.Red);
#endif
return false;
}
else if (currentlyAttachedCount >= maxAttachableCount)
{
#if CLIENT
GUI.AddMessage($"{TextManager.Get("itemmsgtotalnumberlimited")} ({currentlyAttachedCount}/{maxAttachableCount})", Color.Red);
@@ -726,15 +745,6 @@ namespace Barotrauma.Items.Components
public override void Update(float deltaTime, Camera cam)
{
if (attachTargetCell != null)
{
if (attachTargetCell.CellType != Voronoi2.CellType.Solid)
{
Drop(dropConnectedWires: true, dropper: null);
}
return;
}
if (item.body == null || !item.body.Enabled) { return; }
if (picker == null || !picker.HasEquippedItem(item))
{
@@ -801,7 +811,7 @@ namespace Barotrauma.Items.Components
equipLimb = picker.AnimController.GetLimb(LimbType.Torso);
}
if (equipLimb != null)
if (equipLimb != null && !equipLimb.Removed)
{
float itemAngle = (equipLimb.Rotation + holdAngle * picker.AnimController.Dir);
@@ -814,6 +824,11 @@ namespace Barotrauma.Items.Components
}
}
public override void ReceiveSignal(Signal signal, Connection connection)
{
//do nothing
}
public override void FlipX(bool relativeToSub)
{
handlePos[0].X = -handlePos[0].X;
@@ -826,15 +841,25 @@ namespace Barotrauma.Items.Components
public override void OnItemLoaded()
{
if (item.Submarine != null && item.Submarine.Loading) return;
if (item.Submarine != null && item.Submarine.Loading) { return; }
OnMapLoaded();
item.SetActiveSprite();
}
public override void OnMapLoaded()
{
if (!attachable) return;
if (!attachable) { return; }
//a mod has overridden the item, and the base item didn't have a Holdable component = a mod made the item movable/detachable
if (item.Prefab.IsOverride && !loadedFromXml)
{
if (attachedByDefault)
{
AttachToWall();
return;
}
}
if (Attached)
{
AttachToWall();
@@ -51,7 +51,11 @@ namespace Barotrauma.Items.Components
#else
if (deattachTimer >= DeattachDuration)
{
holdable.DeattachFromWall();
if (holdable.Attached)
{
GameAnalyticsManager.AddDesignEvent("ResourceCollected:" + (GameMain.GameSession?.GameMode?.Preset.Identifier ?? "none") + ":" + item.Prefab.Identifier);
holdable.DeattachFromWall();
}
trigger.Enabled = false;
}
#endif
@@ -115,7 +115,7 @@ namespace Barotrauma.Items.Components
reloadTimer /= (1f + item.GetQualityModifier(Quality.StatType.StrikingSpeedMultiplier));
item.body.FarseerBody.CollisionCategories = Physics.CollisionProjectile;
item.body.FarseerBody.CollidesWith = Physics.CollisionCharacter | Physics.CollisionWall;
item.body.FarseerBody.CollidesWith = Physics.CollisionCharacter | Physics.CollisionWall | Physics.CollisionItemBlocking;
item.body.FarseerBody.OnCollision += OnCollision;
item.body.FarseerBody.IsBullet = true;
item.body.PhysEnabled = true;
@@ -361,6 +361,10 @@ namespace Barotrauma.Items.Components
}
hitTargets.Add(targetItem);
}
else if (f2.Body.UserData is Holdable holdable && holdable.CanPush)
{
hitTargets.Add(holdable.Item);
}
else
{
return false;
@@ -412,6 +416,14 @@ namespace Barotrauma.Items.Components
if (targetItem.Removed) { return; }
Attack.DoDamage(User, targetItem, item.WorldPosition, 1.0f);
}
else if (target.UserData is Holdable holdable && holdable.CanPush)
{
if (holdable.Item.Removed) { return; }
Attack.DoDamage(User, holdable.Item, item.WorldPosition, 1.0f);
RestoreCollision();
hitting = false;
User = null;
}
else
{
return;
@@ -74,7 +74,7 @@ namespace Barotrauma.Items.Components
if (PickingTime > 0.0f)
{
var abilityPickingTime = new AbilityValueItem(PickingTime, item.Prefab);
var abilityPickingTime = new AbilityItemPickingTime(PickingTime, item.Prefab);
picker.CheckTalents(AbilityEffectType.OnItemPicked, abilityPickingTime);
if (requiredItems.ContainsKey(RelatedItem.RelationType.Equipped))
@@ -300,4 +300,15 @@ namespace Barotrauma.Items.Components
}
}
}
class AbilityItemPickingTime : AbilityObject, IAbilityValue, IAbilityItemPrefab
{
public AbilityItemPickingTime(float pickingTime, ItemPrefab itemPrefab)
{
Value = pickingTime;
ItemPrefab = itemPrefab;
}
public float Value { get; set; }
public ItemPrefab ItemPrefab { get; set; }
}
}
@@ -158,7 +158,7 @@ namespace Barotrauma.Items.Components
return MathHelper.ToRadians(spread);
}
private readonly List<Body> limbBodies = new List<Body>();
private readonly List<Body> ignoredBodies = new List<Body>();
public override bool Use(float deltaTime, Character character = null)
{
tryingToCharge = true;
@@ -172,8 +172,8 @@ namespace Barotrauma.Items.Components
if (character != null)
{
var abilityItem = new AbilityItem(item);
character.CheckTalents(AbilityEffectType.OnUseRangedWeapon, abilityItem);
var abilityRangedWeapon = new AbilityRangedWeapon(item);
character.CheckTalents(AbilityEffectType.OnUseRangedWeapon, abilityRangedWeapon);
}
if (item.AiTarget != null)
@@ -182,11 +182,20 @@ namespace Barotrauma.Items.Components
item.AiTarget.SightRange = item.AiTarget.MaxSightRange;
}
limbBodies.Clear();
ignoredBodies.Clear();
foreach (Limb l in character.AnimController.Limbs)
{
if (l.IsSevered) { continue; }
limbBodies.Add(l.body.FarseerBody);
ignoredBodies.Add(l.body.FarseerBody);
}
foreach (Item heldItem in character.HeldItems)
{
var holdable = heldItem.GetComponent<Holdable>();
if (holdable?.Pusher != null)
{
ignoredBodies.Add(holdable.Pusher.FarseerBody);
}
}
float degreeOfFailure = 1.0f - DegreeOfSuccess(character);
@@ -211,7 +220,7 @@ namespace Barotrauma.Items.Components
}
float damageMultiplier = 1f + item.GetQualityModifier(Quality.StatType.FirepowerMultiplier);
projectile.Launcher = item;
projectile.Shoot(character, character.AnimController.AimSourceSimPos, barrelPos, rotation + spread, ignoredBodies: limbBodies.ToList(), createNetworkEvent: false, damageMultiplier);
projectile.Shoot(character, character.AnimController.AimSourceSimPos, barrelPos, rotation + spread, ignoredBodies: ignoredBodies.ToList(), createNetworkEvent: false, damageMultiplier);
projectile.Item.GetComponent<Rope>()?.Attach(Item, projectile.Item);
if (i == 0)
{
@@ -270,4 +279,12 @@ namespace Barotrauma.Items.Components
partial void LaunchProjSpecific();
}
class AbilityRangedWeapon : AbilityObject, IAbilityItem
{
public AbilityRangedWeapon(Item item)
{
Item = item;
}
public Item Item { get; set; }
}
}
@@ -521,7 +521,7 @@ namespace Barotrauma.Items.Components
if (!fixableEntities.Contains("structure") && !fixableEntities.Contains(targetStructure.Prefab.Identifier)) { return true; }
ApplyStatusEffectsOnTarget(user, deltaTime, ActionType.OnUse, new ISerializableEntity[] { targetStructure });
ApplyStatusEffectsOnTarget(user, deltaTime, ActionType.OnUse, structure: targetStructure);
FixStructureProjSpecific(user, deltaTime, targetStructure, sectionIndex);
float structureFixAmount = StructureFixAmount;
@@ -589,8 +589,7 @@ namespace Barotrauma.Items.Components
closestLimb.body.ApplyForce(dir * TargetForce, maxVelocity: 10.0f);
}
ApplyStatusEffectsOnTarget(user, deltaTime, ActionType.OnUse,
closestLimb == null ? new ISerializableEntity[] { targetCharacter } : new ISerializableEntity[] { targetCharacter, closestLimb });
ApplyStatusEffectsOnTarget(user, deltaTime, ActionType.OnUse, character: targetCharacter, limb: closestLimb);
FixCharacterProjSpecific(user, deltaTime, targetCharacter);
return true;
}
@@ -606,7 +605,7 @@ namespace Barotrauma.Items.Components
}
targetLimb.character.LastDamageSource = item;
ApplyStatusEffectsOnTarget(user, deltaTime, ActionType.OnUse, new ISerializableEntity[] { targetLimb.character, targetLimb });
ApplyStatusEffectsOnTarget(user, deltaTime, ActionType.OnUse, character: targetLimb.character, limb: targetLimb);
FixCharacterProjSpecific(user, deltaTime, targetLimb.character);
return true;
}
@@ -645,7 +644,7 @@ namespace Barotrauma.Items.Components
targetItem.IsHighlighted = true;
ApplyStatusEffectsOnTarget(user, deltaTime, ActionType.OnUse, targetItem.AllPropertyObjects);
ApplyStatusEffectsOnTarget(user, deltaTime, ActionType.OnUse, targetItem);
if (targetItem.body != null && !MathUtils.NearlyEqual(TargetForce, 0.0f))
{
@@ -682,7 +681,7 @@ namespace Barotrauma.Items.Components
Reset();
return true;
}
if (leak.Submarine == null)
if (leak.Submarine == null || leak.Submarine != character.Submarine)
{
Reset();
return true;
@@ -836,32 +835,48 @@ namespace Barotrauma.Items.Components
}
}
private void ApplyStatusEffectsOnTarget(Character user, float deltaTime, ActionType actionType, IEnumerable<ISerializableEntity> targets)
private static List<ISerializableEntity> currentTargets = new List<ISerializableEntity>();
private void ApplyStatusEffectsOnTarget(Character user, float deltaTime, ActionType actionType, Item targetItem = null, Character character = null, Limb limb = null, Structure structure = null)
{
if (statusEffectLists == null) { return; }
if (!statusEffectLists.TryGetValue(actionType, out List<StatusEffect> statusEffects)) { return; }
foreach (StatusEffect effect in statusEffects)
{
currentTargets.Clear();
effect.SetUser(user);
if (effect.HasTargetType(StatusEffect.TargetType.UseTarget))
{
effect.Apply(actionType, deltaTime, item, targets);
if (targetItem != null)
{
currentTargets.AddRange(targetItem.AllPropertyObjects);
}
if (structure != null)
{
currentTargets.Add(structure);
}
if (character != null)
{
currentTargets.Add(character);
}
effect.Apply(actionType, deltaTime, item, currentTargets);
}
else if (effect.HasTargetType(StatusEffect.TargetType.Character))
{
effect.Apply(actionType, deltaTime, item, targets.Where(t => t is Character));
currentTargets.Add(character);
effect.Apply(actionType, deltaTime, item, currentTargets);
}
else if (effect.HasTargetType(StatusEffect.TargetType.Limb))
{
effect.Apply(actionType, deltaTime, item, targets.Where(t => t is Limb));
currentTargets.Add(limb);
effect.Apply(actionType, deltaTime, item, currentTargets);
}
#if CLIENT
if (user == null) { return; }
// Hard-coded progress bars for welding doors stuck.
// A general purpose system could be better, but it would most likely require changes in the way we define the status effects in xml.
foreach (ISerializableEntity target in targets)
foreach (ISerializableEntity target in currentTargets)
{
if (!(target is Door door)) { continue; }
if (!door.CanBeWelded || !door.Item.IsInteractable(user)) { continue; }