Faction Test 100.4.0.0
This commit is contained in:
+78
-29
@@ -32,6 +32,20 @@ namespace Barotrauma.Items.Components
|
||||
set { reload = Math.Max(value, 0.0f); }
|
||||
}
|
||||
|
||||
[Serialize(0f, IsPropertySaveable.No, description: "Weapons skill requirement to reload at normal speed.")]
|
||||
public float ReloadSkillRequirement
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(1.0f, IsPropertySaveable.No, description: "Reload time at 0 skill level. Reload time scales with skill level up to the Weapons skill requirement.")]
|
||||
public float ReloadNoSkill
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(false, IsPropertySaveable.No, description: "Tells the AI to hold the trigger down when it uses this weapon")]
|
||||
public bool HoldTrigger
|
||||
{
|
||||
@@ -39,7 +53,7 @@ namespace Barotrauma.Items.Components
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(1, IsPropertySaveable.No, description: "How projectiles the weapon launches when fired once.")]
|
||||
[Serialize(1, IsPropertySaveable.No, description: "How many projectiles the weapon launches when fired once.")]
|
||||
public int ProjectileCount
|
||||
{
|
||||
get;
|
||||
@@ -60,6 +74,23 @@ namespace Barotrauma.Items.Components
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(0.0f, IsPropertySaveable.No, description: "The impulse applied to the physics body of the projectile (the higher the impulse, the faster the projectiles are launched). Sum of weapon + projectile.")]
|
||||
public float LaunchImpulse
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(0.0f, IsPropertySaveable.Yes, description: "Percentage of damage mitigation ignored when hitting armored body parts (deflecting limbs). Sum of weapon + projectile."), Editable(MinValueFloat = 0.0f, MaxValueFloat = 1f)]
|
||||
public float Penetration { get; private set; }
|
||||
|
||||
[Serialize(1f, IsPropertySaveable.Yes, description: "Weapon's damage modifier")]
|
||||
public float WeaponDamageModifier
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
[Serialize(0f, IsPropertySaveable.Yes, description: "The time required for a charge-type turret to charge up before able to fire.")]
|
||||
public float MaxChargeTime
|
||||
{
|
||||
@@ -67,6 +98,9 @@ namespace Barotrauma.Items.Components
|
||||
private set;
|
||||
}
|
||||
|
||||
private readonly IReadOnlySet<Identifier> suitableProjectiles;
|
||||
|
||||
|
||||
private enum ChargingState
|
||||
{
|
||||
Inactive,
|
||||
@@ -99,6 +133,11 @@ namespace Barotrauma.Items.Components
|
||||
// TODO: should define this in xml if we have ranged weapons that don't require aim to use
|
||||
item.RequireAimToUse = true;
|
||||
characterUsable = true;
|
||||
suitableProjectiles = element.GetAttributeIdentifierArray(nameof(suitableProjectiles), Array.Empty<Identifier>()).ToHashSet();
|
||||
if (ReloadSkillRequirement > 0 && ReloadNoSkill <= reload)
|
||||
{
|
||||
DebugConsole.AddWarning($"Invalid XML at {item.Name}: ReloadNoSkill is lower or equal than it's reload skill, despite having ReloadSkillRequirement.");
|
||||
}
|
||||
InitProjSpecific(element);
|
||||
}
|
||||
|
||||
@@ -167,7 +206,15 @@ namespace Barotrauma.Items.Components
|
||||
if (currentChargeTime < MaxChargeTime) { return false; }
|
||||
|
||||
IsActive = true;
|
||||
ReloadTimer = reload / (1 + character?.GetStatValue(StatTypes.RangedAttackSpeed) ?? 0f);
|
||||
float baseReloadTime = reload;
|
||||
float weaponSkill = character.GetSkillLevel("weapons");
|
||||
if (ReloadSkillRequirement > 0 && ReloadNoSkill > reload && weaponSkill < ReloadSkillRequirement)
|
||||
{
|
||||
//Examples, assuming 40 weapon skill required: 1 - 40/40 = 0 ... 1 - 0/40 = 1 ... 1 - 20 / 40 = 0.5
|
||||
float reloadFailure = MathHelper.Clamp(1 - (weaponSkill / ReloadSkillRequirement), 0, 1);
|
||||
baseReloadTime = MathHelper.Lerp(reload, ReloadNoSkill, reloadFailure);
|
||||
}
|
||||
ReloadTimer = baseReloadTime / (1 + character?.GetStatValue(StatTypes.RangedAttackSpeed) ?? 0f);
|
||||
currentChargeTime = 0f;
|
||||
|
||||
if (character != null)
|
||||
@@ -218,9 +265,9 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
lastProjectile?.Item.GetComponent<Rope>()?.Snap();
|
||||
}
|
||||
float damageMultiplier = 1f + item.GetQualityModifier(Quality.StatType.FirepowerMultiplier);
|
||||
float damageMultiplier = (1f + item.GetQualityModifier(Quality.StatType.FirepowerMultiplier)) * WeaponDamageModifier;
|
||||
projectile.Launcher = item;
|
||||
projectile.Shoot(character, character.AnimController.AimSourceSimPos, barrelPos, rotation + spread, ignoredBodies: ignoredBodies.ToList(), createNetworkEvent: false, damageMultiplier);
|
||||
projectile.Shoot(character, character.AnimController.AimSourceSimPos, barrelPos, rotation + spread, ignoredBodies: ignoredBodies.ToList(), createNetworkEvent: false, damageMultiplier, LaunchImpulse);
|
||||
projectile.Item.GetComponent<Rope>()?.Attach(Item, projectile.Item);
|
||||
if (i == 0)
|
||||
{
|
||||
@@ -244,39 +291,41 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public Projectile FindProjectile(bool triggerOnUseOnContainers = false)
|
||||
{
|
||||
var containedItems = item.OwnInventory?.AllItemsMod;
|
||||
if (containedItems == null) { return null; }
|
||||
|
||||
foreach (Item item in containedItems)
|
||||
foreach (ItemContainer container in item.GetComponents<ItemContainer>())
|
||||
{
|
||||
if (item == null) { continue; }
|
||||
Projectile projectile = item.GetComponent<Projectile>();
|
||||
if (projectile != null) { return projectile; }
|
||||
}
|
||||
|
||||
//projectile not found, see if one of the contained items contains projectiles
|
||||
foreach (Item it in containedItems)
|
||||
{
|
||||
if (it == null) { continue; }
|
||||
var containedSubItems = it.OwnInventory?.AllItemsMod;
|
||||
if (containedSubItems == null) { continue; }
|
||||
foreach (Item subItem in containedSubItems)
|
||||
foreach (Item containedItem in container.Inventory.AllItemsMod)
|
||||
{
|
||||
if (subItem == null) { continue; }
|
||||
Projectile 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...)
|
||||
if (triggerOnUseOnContainers && subItem.Condition > 0.0f)
|
||||
if (containedItem == null) { continue; }
|
||||
Projectile projectile = containedItem.GetComponent<Projectile>();
|
||||
if (IsSuitableProjectile(projectile)) { return projectile; }
|
||||
|
||||
//projectile not found, see if the contained item contains projectiles
|
||||
var containedSubItems = containedItem.OwnInventory?.AllItemsMod;
|
||||
if (containedSubItems == null) { continue; }
|
||||
foreach (Item subItem in containedSubItems)
|
||||
{
|
||||
subItem.GetComponent<ItemContainer>()?.Item.ApplyStatusEffects(ActionType.OnUse, 1.0f);
|
||||
}
|
||||
if (projectile != null) { return projectile; }
|
||||
if (subItem == null) { continue; }
|
||||
Projectile subProjectile = 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...)
|
||||
if (triggerOnUseOnContainers && subItem.Condition > 0.0f)
|
||||
{
|
||||
subItem.GetComponent<ItemContainer>()?.Item.ApplyStatusEffects(ActionType.OnUse, 1.0f);
|
||||
}
|
||||
if (IsSuitableProjectile(subProjectile)) { return subProjectile; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool IsSuitableProjectile(Projectile projectile)
|
||||
{
|
||||
if (projectile?.Item == null) { return false; }
|
||||
if (!suitableProjectiles.Any()) { return true; }
|
||||
return suitableProjectiles.Any(s => projectile.Item.Prefab.Identifier == s || projectile.Item.HasTag(s));
|
||||
}
|
||||
|
||||
partial void LaunchProjSpecific();
|
||||
}
|
||||
class AbilityRangedWeapon : AbilityObject, IAbilityItem
|
||||
|
||||
Reference in New Issue
Block a user