Unstable 0.1500.1.0 (BaroDev edition)
This commit is contained in:
+3
-3
@@ -15,7 +15,7 @@ namespace Barotrauma.Abilities
|
||||
|
||||
private readonly string itemIdentifier;
|
||||
private readonly string[] tags;
|
||||
private WeaponType weapontype;
|
||||
private readonly WeaponType weapontype;
|
||||
public AbilityConditionAttackData(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement)
|
||||
{
|
||||
itemIdentifier = conditionElement.GetAttributeString("itemidentifier", "");
|
||||
@@ -33,7 +33,7 @@ namespace Barotrauma.Abilities
|
||||
|
||||
protected override bool MatchesConditionSpecific(object abilityData)
|
||||
{
|
||||
if (abilityData is AttackData attackData)
|
||||
if (abilityData is AbilityAttackData attackData)
|
||||
{
|
||||
Item item = attackData?.SourceAttack?.SourceItem;
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace Barotrauma.Abilities
|
||||
}
|
||||
else
|
||||
{
|
||||
LogAbilityConditionError(abilityData, typeof(AttackData));
|
||||
LogAbilityConditionError(abilityData, typeof(AbilityAttackData));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ namespace Barotrauma.Abilities
|
||||
}
|
||||
else
|
||||
{
|
||||
LogAbilityConditionError(abilityData, typeof(AttackData));
|
||||
LogAbilityConditionError(abilityData, typeof(AbilityAttackData));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-4
@@ -1,7 +1,4 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Abilities
|
||||
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Abilities
|
||||
{
|
||||
class AbilityConditionHandsomeStranger : AbilityConditionData
|
||||
{
|
||||
string skillIdentifier;
|
||||
|
||||
public AbilityConditionHandsomeStranger(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement)
|
||||
{
|
||||
skillIdentifier = conditionElement.GetAttributeString("skillidentifier", "").ToLowerInvariant();
|
||||
}
|
||||
|
||||
protected override bool MatchesConditionSpecific(object abilityData)
|
||||
{
|
||||
if (abilityData is string skillIdentifier)
|
||||
{
|
||||
return this.skillIdentifier == skillIdentifier;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogAbilityConditionError(abilityData, typeof(string));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
using Barotrauma.Items.Components;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Abilities
|
||||
{
|
||||
class AbilityConditionIsAiming : AbilityConditionDataless
|
||||
{
|
||||
private enum WeaponType
|
||||
{
|
||||
Any = 0,
|
||||
Melee = 1,
|
||||
Ranged = 2
|
||||
};
|
||||
|
||||
private WeaponType weapontype;
|
||||
public AbilityConditionIsAiming(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement)
|
||||
{
|
||||
switch (conditionElement.GetAttributeString("weapontype", ""))
|
||||
{
|
||||
case "melee":
|
||||
weapontype = WeaponType.Melee;
|
||||
break;
|
||||
case "ranged":
|
||||
weapontype = WeaponType.Ranged;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool MatchesConditionSpecific()
|
||||
{
|
||||
bool aimingCorrectItem = false;
|
||||
if (character.AnimController is HumanoidAnimController animController)
|
||||
{
|
||||
foreach (Item item in character.HeldItems)
|
||||
{
|
||||
switch (weapontype)
|
||||
{
|
||||
case WeaponType.Melee:
|
||||
aimingCorrectItem |= item.GetComponent<MeleeWeapon>() != null && animController.IsAimingMelee;
|
||||
break;
|
||||
case WeaponType.Ranged:
|
||||
aimingCorrectItem |= item.GetComponent<RangedWeapon>() != null && animController.IsAiming;
|
||||
break;
|
||||
default:
|
||||
aimingCorrectItem |= animController.IsAiming || animController.IsAimingMelee;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return aimingCorrectItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-3
@@ -22,10 +22,9 @@ namespace Barotrauma.Abilities
|
||||
{
|
||||
item = tempItem.Prefab;
|
||||
}
|
||||
// this and other instances of this type of casting will be refactored
|
||||
else if (abilityData is (ItemPrefab itemPrefab, object _))
|
||||
else if (abilityData is IAbilityItemPrefab abilityItemPrefab)
|
||||
{
|
||||
item = itemPrefab;
|
||||
item = abilityItemPrefab.ItemPrefab;
|
||||
}
|
||||
|
||||
if (item != null)
|
||||
|
||||
+4
-4
@@ -15,17 +15,17 @@ namespace Barotrauma.Abilities
|
||||
|
||||
protected override bool MatchesConditionSpecific(object abilityData)
|
||||
{
|
||||
if (abilityData is (Affliction affliction, float reduceAmount))
|
||||
if (abilityData is IAbilityAffliction abilityAffliction)
|
||||
{
|
||||
if (allowedTypes.Find(c => c == affliction.Prefab.AfflictionType) == null) { return false; }
|
||||
if (allowedTypes.Find(c => c == abilityAffliction.Affliction.Prefab.AfflictionType) == null) { return false; }
|
||||
|
||||
if (!string.IsNullOrEmpty(identifier) && affliction.Prefab.Identifier != identifier) { return false; }
|
||||
if (!string.IsNullOrEmpty(identifier) && abilityAffliction.Affliction.Prefab.Identifier != identifier) { return false; }
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogAbilityConditionError(abilityData, typeof((Affliction, float)));
|
||||
LogAbilityConditionError(abilityData, typeof(IAbilityAffliction));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Abilities
|
||||
{
|
||||
class AbilityConditionSkill : AbilityConditionData
|
||||
{
|
||||
private readonly string skillIdentifier;
|
||||
|
||||
public AbilityConditionSkill(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement)
|
||||
{
|
||||
skillIdentifier = conditionElement.GetAttributeString("skillidentifier", "").ToLowerInvariant();
|
||||
}
|
||||
|
||||
private bool MatchesConditionSpecific(string skillIdentifier)
|
||||
{
|
||||
return this.skillIdentifier == skillIdentifier;
|
||||
}
|
||||
|
||||
protected override bool MatchesConditionSpecific(object abilityData)
|
||||
{
|
||||
if ((abilityData as string ?? (abilityData as IAbilityString)?.String) is string skillIdentifier)
|
||||
{
|
||||
return MatchesConditionSpecific(skillIdentifier);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogAbilityConditionError(abilityData, typeof(string));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-3
@@ -1,11 +1,10 @@
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Abilities
|
||||
{
|
||||
class AbilityConditionAboveVitality : AbilityConditionDataless
|
||||
{
|
||||
float vitalityPercentage;
|
||||
private readonly float vitalityPercentage;
|
||||
|
||||
public AbilityConditionAboveVitality(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement)
|
||||
{
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Abilities
|
||||
{
|
||||
class AbilityConditionCoauthor : AbilityConditionDataless
|
||||
{
|
||||
private readonly string jobIdentifier;
|
||||
|
||||
public AbilityConditionCoauthor(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement)
|
||||
{
|
||||
jobIdentifier = conditionElement.GetAttributeString("jobidentifier", string.Empty);
|
||||
}
|
||||
|
||||
protected override bool MatchesConditionSpecific()
|
||||
{
|
||||
if (character.SelectedCharacter is Character otherCharacter)
|
||||
{
|
||||
if (!otherCharacter.HasJob(jobIdentifier)) { return false; }
|
||||
if (!(character.SelectedBy == otherCharacter)) { return false; }
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-5
@@ -1,8 +1,4 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Abilities
|
||||
{
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Abilities
|
||||
{
|
||||
class AbilityConditionHasPermanentStat : AbilityConditionDataless
|
||||
{
|
||||
private readonly StatTypes statType;
|
||||
private readonly float min;
|
||||
|
||||
public AbilityConditionHasPermanentStat(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement)
|
||||
{
|
||||
statType = CharacterAbilityGroup.ParseStatType(conditionElement.GetAttributeString("stattype", ""), characterTalent.DebugIdentifier);
|
||||
min = conditionElement.GetAttributeFloat("min", 0f);
|
||||
}
|
||||
|
||||
protected override bool MatchesConditionSpecific()
|
||||
{
|
||||
// should consider decoupling this from stat values entirely
|
||||
return character.Info.GetSavedStatValue(statType) >= min;
|
||||
}
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Abilities
|
||||
{
|
||||
class AbilityConditionHasStatusTag : AbilityConditionDataless
|
||||
{
|
||||
private readonly string tag;
|
||||
|
||||
|
||||
public AbilityConditionHasStatusTag(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement)
|
||||
{
|
||||
tag = conditionElement.GetAttributeString("tag", "");
|
||||
if (string.IsNullOrEmpty(tag))
|
||||
{
|
||||
DebugConsole.AddWarning($"Error in talent \"{characterTalent.Prefab.OriginalName}\" - tag not defined in AbilityConditionHasStatusTag.");
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool MatchesConditionSpecific()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(tag))
|
||||
{
|
||||
return
|
||||
StatusEffect.DurationList.Any(d => d.Targets.Contains(character) && d.Parent.HasTag(tag)) ||
|
||||
DelayedEffect.DelayList.Any(d => d.Targets.Contains(character) && d.Parent.HasTag(tag));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Abilities
|
||||
{
|
||||
class AbilityConditionInFriendlySubmarine : AbilityConditionDataless
|
||||
{
|
||||
public AbilityConditionInFriendlySubmarine(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement) { }
|
||||
|
||||
protected override bool MatchesConditionSpecific()
|
||||
{
|
||||
return character.Submarine?.TeamID == character.TeamID;
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Abilities
|
||||
{
|
||||
class AbilityConditionInHull : AbilityConditionDataless
|
||||
{
|
||||
public AbilityConditionInHull(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement) { }
|
||||
|
||||
protected override bool MatchesConditionSpecific()
|
||||
{
|
||||
return character.CurrentHull != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Abilities
|
||||
{
|
||||
class AbilityConditionLevelsBehindHighest : AbilityConditionDataless
|
||||
{
|
||||
private readonly int levelsBehind;
|
||||
public AbilityConditionLevelsBehindHighest(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement)
|
||||
{
|
||||
levelsBehind = conditionElement.GetAttributeInt("levelsbehind", 0);
|
||||
}
|
||||
|
||||
protected override bool MatchesConditionSpecific()
|
||||
{
|
||||
return Character.GetFriendlyCrew(character).Where(c => c.Info != null && (c.Info.GetCurrentLevel() - character.Info.GetCurrentLevel() >= levelsBehind)).Any();
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -24,13 +24,13 @@ namespace Barotrauma.Abilities
|
||||
|
||||
protected override bool MatchesConditionSpecific(object abilityData)
|
||||
{
|
||||
if (abilityData is (Mission mission, AbilityValue missionAbilityValue))
|
||||
if (abilityData is IAbilityMission abilityMission)
|
||||
{
|
||||
return mission.Prefab.Type == missionType;
|
||||
return abilityMission.Mission.Prefab.Type == missionType;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogAbilityConditionError(abilityData, typeof((Mission, AbilityValue)));
|
||||
LogAbilityConditionError(abilityData, typeof(IAbilityMission));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-6
@@ -1,14 +1,10 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Abilities
|
||||
{
|
||||
class AbilityConditionServerRandom : AbilityConditionDataless
|
||||
{
|
||||
private float randomChance = 0f;
|
||||
private readonly float randomChance = 0f;
|
||||
public override bool AllowClientSimulation => false;
|
||||
|
||||
public AbilityConditionServerRandom(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement)
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
namespace Barotrauma.Abilities
|
||||
{
|
||||
interface IAbilityItemPrefab
|
||||
{
|
||||
public ItemPrefab ItemPrefab { get; set; }
|
||||
}
|
||||
|
||||
interface IAbilityValue
|
||||
{
|
||||
public float Value { get; set; }
|
||||
}
|
||||
|
||||
interface IAbilityMission
|
||||
{
|
||||
public Mission Mission { get; set; }
|
||||
}
|
||||
|
||||
interface IAbilityCharacter
|
||||
{
|
||||
public Character Character { get; set; }
|
||||
}
|
||||
|
||||
interface IAbilityString
|
||||
{
|
||||
public string String { get; set; }
|
||||
}
|
||||
|
||||
interface IAbilityAffliction
|
||||
{
|
||||
public Affliction Affliction { get; set; }
|
||||
}
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Barotrauma.Abilities
|
||||
{
|
||||
|
||||
class AbilityValue : IAbilityValue
|
||||
{
|
||||
public AbilityValue(float value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
public float Value { get; set; }
|
||||
}
|
||||
|
||||
class AbilityValueItem : IAbilityValue, IAbilityItemPrefab
|
||||
{
|
||||
public AbilityValueItem(float value, ItemPrefab itemPrefab)
|
||||
{
|
||||
Value = value;
|
||||
ItemPrefab = itemPrefab;
|
||||
}
|
||||
public float Value { get; set; }
|
||||
public ItemPrefab ItemPrefab { get; set; }
|
||||
}
|
||||
|
||||
class AbilityValueString : IAbilityValue, IAbilityString
|
||||
{
|
||||
public AbilityValueString(float value, string abilityString)
|
||||
{
|
||||
Value = value;
|
||||
String = abilityString;
|
||||
}
|
||||
public float Value { get; set; }
|
||||
public string String { get; set; }
|
||||
}
|
||||
|
||||
class AbilityStringCharacter : IAbilityCharacter, IAbilityString
|
||||
{
|
||||
public AbilityStringCharacter(string abilityString, Character character)
|
||||
{
|
||||
String = abilityString;
|
||||
Character = character;
|
||||
}
|
||||
public Character Character { get; set; }
|
||||
public string String { get; set; }
|
||||
}
|
||||
|
||||
class AbilityValueAffliction : IAbilityValue, IAbilityAffliction
|
||||
{
|
||||
public AbilityValueAffliction(float value, Affliction affliction)
|
||||
{
|
||||
Value = value;
|
||||
Affliction = affliction;
|
||||
}
|
||||
public float Value { get; set; }
|
||||
public Affliction Affliction { get; set; }
|
||||
}
|
||||
|
||||
class AbilityValueMission : IAbilityValue, IAbilityMission
|
||||
{
|
||||
public AbilityValueMission(float value, Mission mission)
|
||||
{
|
||||
Value = value;
|
||||
Mission = mission;
|
||||
}
|
||||
public float Value { get; set; }
|
||||
public Mission Mission { get; set; }
|
||||
}
|
||||
|
||||
class AbilityAttackData : IAbilityCharacter
|
||||
{
|
||||
public float DamageMultiplier { get; set; } = 1f;
|
||||
public float AddedPenetration { get; set; } = 0f;
|
||||
public List<Affliction> Afflictions { get; set; }
|
||||
public Attack SourceAttack { get; }
|
||||
public Character Character { get; set; }
|
||||
public Character Attacker { get; set; }
|
||||
|
||||
public AbilityAttackData(Attack sourceAttack, Character character)
|
||||
{
|
||||
SourceAttack = sourceAttack;
|
||||
Character = character;
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-7
@@ -12,12 +12,16 @@ namespace Barotrauma.Abilities
|
||||
public CharacterTalent CharacterTalent { get; }
|
||||
public Character Character { get; }
|
||||
|
||||
public virtual bool RequiresAlive => true;
|
||||
public bool RequiresAlive { get; }
|
||||
|
||||
public virtual bool AllowClientSimulation => false;
|
||||
public virtual bool AppliesEffectOnIntervalUpdate => false;
|
||||
|
||||
private const float DefaultEffectTime = 1.0f;
|
||||
|
||||
// currently resets if the character dies. would need to be stored in a dictionary of sorts to maintain through death
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Used primarily for StatusEffects. Default to constant outside interval abilities.
|
||||
/// </summary>
|
||||
@@ -28,6 +32,7 @@ namespace Barotrauma.Abilities
|
||||
CharacterAbilityGroup = characterAbilityGroup;
|
||||
CharacterTalent = characterAbilityGroup.CharacterTalent;
|
||||
Character = CharacterTalent.Character;
|
||||
RequiresAlive = abilityElement.GetAttributeBool("requiresalive", true);
|
||||
}
|
||||
|
||||
public bool IsViable()
|
||||
@@ -132,11 +137,5 @@ namespace Barotrauma.Abilities
|
||||
}
|
||||
return flagType;
|
||||
}
|
||||
|
||||
public static float DistanceToSquaredDistance(float distance)
|
||||
{
|
||||
return distance * distance;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+33
-4
@@ -10,16 +10,41 @@ namespace Barotrauma.Abilities
|
||||
|
||||
protected readonly List<StatusEffect> statusEffects;
|
||||
|
||||
private readonly bool applyToSelected;
|
||||
|
||||
readonly List<ISerializableEntity> targets = new List<ISerializableEntity>();
|
||||
|
||||
public CharacterAbilityApplyStatusEffects(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
{
|
||||
statusEffects = CharacterAbilityGroup.ParseStatusEffects(CharacterTalent, abilityElement.GetChildElement("statuseffects"));
|
||||
applyToSelected = abilityElement.GetAttributeBool("applytoselected", false);
|
||||
}
|
||||
|
||||
protected void ApplyEffectSpecific(Character targetCharacter)
|
||||
{
|
||||
foreach (var statusEffect in statusEffects)
|
||||
{
|
||||
statusEffect.Apply(ActionType.OnAbility, EffectDeltaTime, Character, targetCharacter);
|
||||
if (statusEffect.HasTargetType(StatusEffect.TargetType.UseTarget))
|
||||
{
|
||||
// currently used this to spawn items on the targeted character
|
||||
statusEffect.SetUser(targetCharacter);
|
||||
statusEffect.Apply(ActionType.OnAbility, EffectDeltaTime, targetCharacter, targetCharacter);
|
||||
}
|
||||
else if (statusEffect.HasTargetType(StatusEffect.TargetType.NearbyCharacters))
|
||||
{
|
||||
targets.Clear();
|
||||
targets.AddRange(statusEffect.GetNearbyTargets(targetCharacter.WorldPosition, targets));
|
||||
statusEffect.Apply(ActionType.OnAbility, EffectDeltaTime, targetCharacter, targets);
|
||||
}
|
||||
else if (statusEffect.HasTargetType(StatusEffect.TargetType.This))
|
||||
{
|
||||
statusEffect.SetUser(Character);
|
||||
statusEffect.Apply(ActionType.OnAbility, EffectDeltaTime, Character, Character);
|
||||
}
|
||||
else
|
||||
{
|
||||
statusEffect.Apply(ActionType.OnAbility, EffectDeltaTime, Character, targetCharacter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,13 +55,17 @@ namespace Barotrauma.Abilities
|
||||
|
||||
protected override void ApplyEffect(object abilityData)
|
||||
{
|
||||
if (abilityData is Character targetCharacter)
|
||||
if (applyToSelected && Character.SelectedCharacter is Character selectedCharacter)
|
||||
{
|
||||
ApplyEffectSpecific(selectedCharacter);
|
||||
}
|
||||
else if ((abilityData as Character ?? (abilityData as IAbilityCharacter)?.Character) is Character targetCharacter)
|
||||
{
|
||||
ApplyEffectSpecific(targetCharacter);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
ApplyEffect();
|
||||
ApplyEffect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
using Barotrauma.Extensions;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Abilities
|
||||
{
|
||||
class CharacterAbilityApplyStatusEffectsToAllies : CharacterAbilityApplyStatusEffects
|
||||
{
|
||||
private readonly bool allowSelf;
|
||||
|
||||
public CharacterAbilityApplyStatusEffectsToAllies(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
{
|
||||
allowSelf = abilityElement.GetAttributeBool("allowself", true);
|
||||
}
|
||||
|
||||
|
||||
protected override void ApplyEffect()
|
||||
{
|
||||
IEnumerable<Character> chosenCharacters = Character.GetFriendlyCrew(Character).Where(c => allowSelf || c != Character);
|
||||
|
||||
foreach (Character character in chosenCharacters)
|
||||
{
|
||||
ApplyEffectSpecific(character);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Abilities
|
||||
{
|
||||
class CharacterAbilityApplyStatusEffectsToAttacker : CharacterAbilityApplyStatusEffects
|
||||
{
|
||||
public CharacterAbilityApplyStatusEffectsToAttacker(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void ApplyEffect(object abilityData)
|
||||
{
|
||||
if ((abilityData as AbilityAttackData)?.Attacker is Character attacker)
|
||||
{
|
||||
ApplyEffectSpecific(attacker);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-4
@@ -1,6 +1,5 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Abilities
|
||||
@@ -10,7 +9,7 @@ namespace Barotrauma.Abilities
|
||||
protected float squaredMaxDistance;
|
||||
public CharacterAbilityApplyStatusEffectsToNearestAlly(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
{
|
||||
squaredMaxDistance = DistanceToSquaredDistance(abilityElement.GetAttributeFloat("maxdistance", float.MaxValue));
|
||||
squaredMaxDistance = MathF.Pow(abilityElement.GetAttributeFloat("maxdistance", float.MaxValue), 2);
|
||||
}
|
||||
|
||||
protected override void ApplyEffect()
|
||||
@@ -20,7 +19,7 @@ namespace Barotrauma.Abilities
|
||||
|
||||
foreach (Character crewCharacter in Character.GetFriendlyCrew(Character))
|
||||
{
|
||||
if (crewCharacter != Character && Vector2.DistanceSquared(Character.SimPosition, Character.GetRelativeSimPosition(crewCharacter)) is float tempDistance && tempDistance < closestDistance)
|
||||
if (crewCharacter != Character && Vector2.DistanceSquared(Character.WorldPosition, crewCharacter.WorldPosition) is float tempDistance && tempDistance < closestDistance)
|
||||
{
|
||||
closestCharacter = crewCharacter;
|
||||
closestDistance = tempDistance;
|
||||
|
||||
+4
-3
@@ -1,5 +1,6 @@
|
||||
using Barotrauma.Extensions;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
@@ -16,7 +17,7 @@ namespace Barotrauma.Abilities
|
||||
|
||||
public CharacterAbilityApplyStatusEffectsToRandomAlly(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
{
|
||||
squaredMaxDistance = DistanceToSquaredDistance(abilityElement.GetAttributeFloat("maxdistance", float.MaxValue));
|
||||
squaredMaxDistance = MathF.Pow(abilityElement.GetAttributeFloat("maxdistance", float.MaxValue), 2);
|
||||
allowDifferentSub = abilityElement.GetAttributeBool("mustbeonsamesub", true);
|
||||
allowSelf = abilityElement.GetAttributeBool("allowself", true);
|
||||
}
|
||||
@@ -26,9 +27,9 @@ namespace Barotrauma.Abilities
|
||||
Character chosenCharacter = null;
|
||||
|
||||
chosenCharacter = Character.GetFriendlyCrew(Character).Where(c =>
|
||||
(allowSelf ||c != Character) &&
|
||||
(allowSelf || c != Character) &&
|
||||
(allowDifferentSub || c.Submarine == Character.Submarine) &&
|
||||
Vector2.DistanceSquared(Character.SimPosition, Character.GetRelativeSimPosition(c)) is float tempDistance &&
|
||||
Vector2.DistanceSquared(Character.WorldPosition, c.WorldPosition) is float tempDistance &&
|
||||
tempDistance < squaredMaxDistance).GetRandom();
|
||||
|
||||
if (chosenCharacter == null) { return; }
|
||||
|
||||
+27
-2
@@ -7,16 +7,41 @@ namespace Barotrauma.Abilities
|
||||
{
|
||||
public override bool AppliesEffectOnIntervalUpdate => true;
|
||||
|
||||
private int amount;
|
||||
private readonly int amount;
|
||||
private StatTypes scalingStatType;
|
||||
|
||||
public CharacterAbilityGiveMoney(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
{
|
||||
amount = abilityElement.GetAttributeInt("amount", 0);
|
||||
scalingStatType = CharacterAbilityGroup.ParseStatType(abilityElement.GetAttributeString("scalingstattype", "None"), CharacterTalent.DebugIdentifier);
|
||||
}
|
||||
|
||||
private void ApplyEffectSpecific(Character targetCharacter)
|
||||
{
|
||||
float multiplier = 1f;
|
||||
if (scalingStatType != StatTypes.None)
|
||||
{
|
||||
multiplier = 0 + Character.Info.GetSavedStatValue(scalingStatType);
|
||||
}
|
||||
|
||||
targetCharacter.GiveMoney((int)(multiplier * amount));
|
||||
}
|
||||
|
||||
protected override void ApplyEffect(object abilityData)
|
||||
{
|
||||
if ((abilityData as Character ?? (abilityData as IAbilityCharacter)?.Character) is Character targetCharacter)
|
||||
{
|
||||
ApplyEffectSpecific(targetCharacter);
|
||||
}
|
||||
else
|
||||
{
|
||||
ApplyEffectSpecific(Character);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ApplyEffect()
|
||||
{
|
||||
Character.GiveMoney(amount);
|
||||
ApplyEffectSpecific(Character);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-2
@@ -8,8 +8,10 @@ namespace Barotrauma.Abilities
|
||||
private readonly string statIdentifier;
|
||||
private readonly StatTypes statType;
|
||||
private readonly float value;
|
||||
private readonly float maxValue;
|
||||
private readonly bool targetAllies;
|
||||
private readonly bool removeOnDeath;
|
||||
private readonly bool removeAfterRound;
|
||||
//private readonly float maximumValue;
|
||||
|
||||
public override bool AppliesEffectOnIntervalUpdate => true;
|
||||
@@ -19,8 +21,10 @@ namespace Barotrauma.Abilities
|
||||
statIdentifier = abilityElement.GetAttributeString("statidentifier", "").ToLowerInvariant();
|
||||
statType = CharacterAbilityGroup.ParseStatType(abilityElement.GetAttributeString("stattype", ""), CharacterTalent.DebugIdentifier);
|
||||
value = abilityElement.GetAttributeFloat("value", 0f);
|
||||
maxValue = abilityElement.GetAttributeFloat("maxvalue", float.MaxValue);
|
||||
targetAllies = abilityElement.GetAttributeBool("targetallies", false);
|
||||
removeOnDeath = abilityElement.GetAttributeBool("removeondeath", true);
|
||||
removeAfterRound = abilityElement.GetAttributeBool("removeafterround", false);
|
||||
//maximumValue = abilityElement.GetAttributeFloat("maximumvalue", float.MaxValue);
|
||||
}
|
||||
|
||||
@@ -38,11 +42,11 @@ namespace Barotrauma.Abilities
|
||||
{
|
||||
if (targetAllies)
|
||||
{
|
||||
Character.GetFriendlyCrew(Character).ForEach(c => c?.Info.ChangeSavedStatValue(statType, value, statIdentifier, removeOnDeath));
|
||||
Character.GetFriendlyCrew(Character).ForEach(c => c?.Info.ChangeSavedStatValue(statType, value, statIdentifier, removeOnDeath, removeAfterRound, maxValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
Character?.Info.ChangeSavedStatValue(statType, value, statIdentifier, removeOnDeath);
|
||||
Character?.Info.ChangeSavedStatValue(statType, value, statIdentifier, removeOnDeath, removeAfterRound, maxValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
-4
@@ -4,18 +4,23 @@ namespace Barotrauma.Abilities
|
||||
{
|
||||
class CharacterAbilityGiveResistance : CharacterAbility
|
||||
{
|
||||
private string resistanceId;
|
||||
private float resistance;
|
||||
private readonly string resistanceId;
|
||||
private readonly float multiplier;
|
||||
|
||||
public CharacterAbilityGiveResistance(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
{
|
||||
resistanceId = abilityElement.GetAttributeString("resistanceid", "");
|
||||
resistance = abilityElement.GetAttributeFloat("resistance", 1f);
|
||||
multiplier = abilityElement.GetAttributeFloat("multiplier", 1f);
|
||||
|
||||
if (string.IsNullOrEmpty(resistanceId))
|
||||
{
|
||||
DebugConsole.ThrowError("Error in CharacterAbilityGiveResistance - resistance identifier not set.");
|
||||
}
|
||||
}
|
||||
|
||||
public override void InitializeAbility(bool addingFirstTime)
|
||||
{
|
||||
Character.ChangeAbilityResistance(resistanceId, resistance);
|
||||
Character.ChangeAbilityResistance(resistanceId, multiplier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-3
@@ -4,10 +4,9 @@ namespace Barotrauma.Abilities
|
||||
{
|
||||
class CharacterAbilityGiveStat : CharacterAbility
|
||||
{
|
||||
private StatTypes statType;
|
||||
private float value;
|
||||
private readonly StatTypes statType;
|
||||
private readonly float value;
|
||||
|
||||
// this and resistance giving should probably be moved directly to charactertalent attributes, as they don't need to interact with either ability group types
|
||||
public CharacterAbilityGiveStat(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
{
|
||||
statType = CharacterAbilityGroup.ParseStatType(abilityElement.GetAttributeString("stattype", ""), CharacterTalent.DebugIdentifier);
|
||||
|
||||
+12
-3
@@ -7,8 +7,9 @@ namespace Barotrauma.Abilities
|
||||
{
|
||||
private readonly List<Affliction> afflictions;
|
||||
|
||||
float addedDamageMultiplier;
|
||||
float addedPenetration;
|
||||
private readonly float addedDamageMultiplier;
|
||||
private readonly float addedPenetration;
|
||||
private readonly bool implode;
|
||||
|
||||
public CharacterAbilityModifyAttackData(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
{
|
||||
@@ -18,11 +19,12 @@ namespace Barotrauma.Abilities
|
||||
}
|
||||
addedDamageMultiplier = abilityElement.GetAttributeFloat("addeddamagemultiplier", 0f);
|
||||
addedPenetration = abilityElement.GetAttributeFloat("addedpenetration", 0f);
|
||||
implode = abilityElement.GetAttributeBool("implode", false);
|
||||
}
|
||||
|
||||
protected override void ApplyEffect(object abilityData)
|
||||
{
|
||||
if (abilityData is AttackData attackData)
|
||||
if (abilityData is AbilityAttackData attackData)
|
||||
{
|
||||
if (attackData.Afflictions == null)
|
||||
{
|
||||
@@ -34,6 +36,13 @@ namespace Barotrauma.Abilities
|
||||
}
|
||||
attackData.DamageMultiplier += addedDamageMultiplier;
|
||||
attackData.AddedPenetration += addedPenetration;
|
||||
|
||||
if (implode)
|
||||
{
|
||||
// might have issues, as the method used to be private and only used for pressure death
|
||||
attackData.Character?.Implode();
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+7
-2
@@ -4,8 +4,8 @@ namespace Barotrauma.Abilities
|
||||
{
|
||||
class CharacterAbilityModifyResistance : CharacterAbility
|
||||
{
|
||||
private string resistanceId;
|
||||
private float resistance;
|
||||
private readonly string resistanceId;
|
||||
private readonly float resistance;
|
||||
bool lastState;
|
||||
|
||||
// should probably be split to different classes
|
||||
@@ -13,6 +13,11 @@ namespace Barotrauma.Abilities
|
||||
{
|
||||
resistanceId = abilityElement.GetAttributeString("resistanceid", "");
|
||||
resistance = abilityElement.GetAttributeFloat("resistance", 1f);
|
||||
|
||||
if (string.IsNullOrEmpty(resistanceId))
|
||||
{
|
||||
DebugConsole.ThrowError("Error in CharacterAbilityModifyResistance - resistance identifier not set.");
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateCharacterAbility(bool conditionsMatched, float timeSinceLastUpdate)
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Abilities
|
||||
{
|
||||
class CharacterAbilityModifyStatToSkill : CharacterAbility
|
||||
{
|
||||
private readonly StatTypes statType;
|
||||
private readonly float maxValue;
|
||||
private readonly string skillIdentifier;
|
||||
private readonly bool useAll;
|
||||
private float lastValue = 0f;
|
||||
|
||||
public CharacterAbilityModifyStatToSkill(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
{
|
||||
statType = CharacterAbilityGroup.ParseStatType(abilityElement.GetAttributeString("stattype", ""), CharacterTalent.DebugIdentifier);
|
||||
maxValue = abilityElement.GetAttributeFloat("maxvalue", 0f);
|
||||
skillIdentifier = abilityElement.GetAttributeString("skillidentifier", string.Empty);
|
||||
useAll = skillIdentifier == "all";
|
||||
}
|
||||
|
||||
protected override void VerifyState(bool conditionsMatched, float timeSinceLastUpdate)
|
||||
{
|
||||
Character.ChangeStat(statType, -lastValue);
|
||||
|
||||
if (conditionsMatched)
|
||||
{
|
||||
float skillTotal = 0f;
|
||||
|
||||
if (useAll && Character.Info?.Job != null)
|
||||
{
|
||||
foreach (Skill skill in Character.Info.Job.Skills)
|
||||
{
|
||||
skillTotal += Character.GetSkillLevel(skill.Identifier);
|
||||
}
|
||||
skillTotal /= Character.Info.Job.Skills.Count;
|
||||
}
|
||||
else
|
||||
{
|
||||
skillTotal = Character.GetSkillLevel(skillIdentifier);
|
||||
}
|
||||
|
||||
lastValue = skillTotal / 100f * maxValue;
|
||||
Character.ChangeStat(statType, lastValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
lastValue = 0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-26
@@ -5,42 +5,21 @@ namespace Barotrauma.Abilities
|
||||
class CharacterAbilityModifyValue : CharacterAbility
|
||||
{
|
||||
private float addedValue;
|
||||
private float multiplierValue;
|
||||
private float multiplyValue;
|
||||
|
||||
public CharacterAbilityModifyValue(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
{
|
||||
addedValue = abilityElement.GetAttributeFloat("addedvalue", 0f);
|
||||
multiplierValue = abilityElement.GetAttributeFloat("multipliervalue", 1f);
|
||||
multiplyValue = abilityElement.GetAttributeFloat("multiplyvalue", 1f);
|
||||
}
|
||||
|
||||
protected override void ApplyEffect(object abilityData)
|
||||
{
|
||||
if (abilityData is AbilityValue abilityValue)
|
||||
if (abilityData is IAbilityValue abilityValue)
|
||||
{
|
||||
ApplyEffectSpecific(abilityValue);
|
||||
abilityValue.Value += addedValue;
|
||||
abilityValue.Value *= multiplyValue;
|
||||
}
|
||||
else if (abilityData is (object _, AbilityValue tupleAbilityValue))
|
||||
{
|
||||
ApplyEffectSpecific(tupleAbilityValue);
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyEffectSpecific(AbilityValue abilityValue)
|
||||
{
|
||||
abilityValue.Value += addedValue;
|
||||
abilityValue.Value *= multiplierValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// this seems like a real silly way to have to pass values by reference into these same interfaces
|
||||
// if more of these are required, maybe there should be an additional set of interfaces to easily pass values by reference instead
|
||||
class AbilityValue
|
||||
{
|
||||
public float Value { get; set; }
|
||||
public AbilityValue(float value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ namespace Barotrauma.Abilities
|
||||
class CharacterAbilityResetPermanentStat : CharacterAbility
|
||||
{
|
||||
private readonly string statIdentifier;
|
||||
public override bool RequiresAlive => false;
|
||||
public override bool AppliesEffectOnIntervalUpdate => true;
|
||||
|
||||
public CharacterAbilityResetPermanentStat(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
{
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Abilities
|
||||
{
|
||||
class CharacterAbilityRevive : CharacterAbility
|
||||
{
|
||||
public override bool AppliesEffectOnIntervalUpdate => true;
|
||||
|
||||
public CharacterAbilityRevive(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
{
|
||||
}
|
||||
|
||||
private void ApplyEffectSpecific()
|
||||
{
|
||||
Character.Revive();
|
||||
}
|
||||
|
||||
protected override void ApplyEffect()
|
||||
{
|
||||
ApplyEffectSpecific();
|
||||
}
|
||||
|
||||
protected override void ApplyEffect(object abilityData)
|
||||
{
|
||||
ApplyEffectSpecific();
|
||||
}
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Abilities
|
||||
{
|
||||
class CharacterAbilityAlienHoarder : CharacterAbility
|
||||
{
|
||||
private readonly float addedDamageMultiplierPerItem;
|
||||
private readonly int maxAmount;
|
||||
private readonly string[] tags;
|
||||
|
||||
public CharacterAbilityAlienHoarder(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
{
|
||||
addedDamageMultiplierPerItem = abilityElement.GetAttributeFloat("addeddamagemultiplierperitem", 0f);
|
||||
maxAmount = abilityElement.GetAttributeInt("maxamount", 0);
|
||||
tags = abilityElement.GetAttributeStringArray("tags", Array.Empty<string>(), convertToLowerInvariant: true);
|
||||
}
|
||||
|
||||
protected override void ApplyEffect(object abilityData)
|
||||
{
|
||||
if (abilityData is AbilityAttackData attackData)
|
||||
{
|
||||
float totalAddedDamageMultiplier = 0f;
|
||||
foreach (Item item in Character.Inventory.AllItems)
|
||||
{
|
||||
if (tags.Any(t => item.Prefab.Tags.Any(p => t == p)))
|
||||
{
|
||||
totalAddedDamageMultiplier += addedDamageMultiplierPerItem;
|
||||
}
|
||||
}
|
||||
attackData.DamageMultiplier += addedDamageMultiplierPerItem;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogAbilityDataMismatch();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -12,9 +12,9 @@ namespace Barotrauma.Abilities
|
||||
|
||||
protected override void ApplyEffect(object abilityData)
|
||||
{
|
||||
if (abilityData is (string skillIdentifier, Character character) && character != Character)
|
||||
if (abilityData is AbilityStringCharacter abilityStringCharacter && abilityStringCharacter.Character != Character)
|
||||
{
|
||||
character.Info?.IncreaseSkillLevel(skillIdentifier, 1.0f, character.Position + Vector2.UnitY * 175.0f);
|
||||
Character.Info?.IncreaseSkillLevel(abilityStringCharacter.String, 1.0f, abilityStringCharacter.Character.Position + Vector2.UnitY * 175.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Abilities
|
||||
{
|
||||
class CharacterAbilityByTheBook : CharacterAbility
|
||||
{
|
||||
private int moneyAmount;
|
||||
private int max;
|
||||
|
||||
public CharacterAbilityByTheBook(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
{
|
||||
moneyAmount = abilityElement.GetAttributeInt("moneyamount", 0);
|
||||
max = abilityElement.GetAttributeInt("max", 0);
|
||||
}
|
||||
|
||||
protected override void ApplyEffect()
|
||||
{
|
||||
IEnumerable<Character> enemyCharacters = Character.CharacterList.Where(c => c.TeamID == CharacterTeamType.None);
|
||||
|
||||
int timesGiven = 0;
|
||||
foreach (Character enemyCharacter in enemyCharacters)
|
||||
{
|
||||
if (!enemyCharacter.IsHuman) { continue; }
|
||||
if (enemyCharacter.Submarine == null || enemyCharacter.Submarine != Submarine.MainSub) { continue; }
|
||||
if (enemyCharacter.IsDead) { continue; }
|
||||
if (!enemyCharacter.LockHands) { continue; }
|
||||
if (timesGiven > max) { continue; }
|
||||
Character.GiveMoney(moneyAmount);
|
||||
timesGiven++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-27
@@ -9,45 +9,22 @@ namespace Barotrauma.Abilities
|
||||
class CharacterAbilityInsurancePolicy : CharacterAbility
|
||||
{
|
||||
public override bool AppliesEffectOnIntervalUpdate => true;
|
||||
public override bool RequiresAlive => false;
|
||||
|
||||
private readonly int moneyPerLevel;
|
||||
private bool hasOccurred = false;
|
||||
private readonly int moneyPerMission;
|
||||
|
||||
private static List<Client> clientsAlreadyUsed = new List<Client>();
|
||||
|
||||
public CharacterAbilityInsurancePolicy(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
{
|
||||
moneyPerLevel = abilityElement.GetAttributeInt("moneyperlevel", 0);
|
||||
moneyPerMission = abilityElement.GetAttributeInt("moneypermission", 0);
|
||||
}
|
||||
|
||||
protected override void ApplyEffect()
|
||||
{
|
||||
if (Character?.Info is CharacterInfo info && !hasOccurred)
|
||||
if (Character?.Info is CharacterInfo info)
|
||||
{
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
|
||||
{
|
||||
foreach (Client client in GameMain.NetworkMember.ConnectedClients)
|
||||
{
|
||||
if (client.Character == Character && clientsAlreadyUsed.Contains(client)) { return; }
|
||||
}
|
||||
}
|
||||
|
||||
Character.GiveMoney(moneyPerLevel * info.GetCurrentLevel());
|
||||
hasOccurred = true;
|
||||
|
||||
// this is an ugly way to do this, but this effect should not occur more than once per round for a client
|
||||
// this seemed like the simplest way to do it since characters are instantiated from scratch each time
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
|
||||
{
|
||||
foreach (Client client in GameMain.NetworkMember.ConnectedClients)
|
||||
{
|
||||
if (client.Character == Character)
|
||||
{
|
||||
clientsAlreadyUsed.Add(client);
|
||||
}
|
||||
}
|
||||
}
|
||||
Character.GiveMoney(moneyPerMission * info.MissionsCompletedSinceDeath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -5,14 +5,14 @@ namespace Barotrauma.Abilities
|
||||
class CharacterAbilityPsychoClown : CharacterAbility
|
||||
{
|
||||
private StatTypes statType;
|
||||
private float value;
|
||||
private float maxValue;
|
||||
private string afflictionIdentifier;
|
||||
private float lastValue = 0f;
|
||||
|
||||
public CharacterAbilityPsychoClown(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
{
|
||||
statType = CharacterAbilityGroup.ParseStatType(abilityElement.GetAttributeString("stattype", ""), CharacterTalent.DebugIdentifier);
|
||||
value = abilityElement.GetAttributeFloat("value", 0f);
|
||||
maxValue = abilityElement.GetAttributeFloat("maxvalue", 0f);
|
||||
afflictionIdentifier = abilityElement.GetAttributeString("afflictionidentifier", "");
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Barotrauma.Abilities
|
||||
afflictionStrength = affliction.Strength / affliction.Prefab.MaxStrength;
|
||||
}
|
||||
|
||||
lastValue = afflictionStrength * value;
|
||||
lastValue = afflictionStrength * maxValue;
|
||||
Character.ChangeStat(statType, lastValue);
|
||||
}
|
||||
else
|
||||
|
||||
+2
@@ -8,6 +8,8 @@ namespace Barotrauma.Abilities
|
||||
{
|
||||
class CharacterAbilityRegenerateLoot : CharacterAbility
|
||||
{
|
||||
// not maintained through death, so it's possible for players to respawn and re-loot chests
|
||||
// seems like a minor issue for now
|
||||
List<Item> openedContainers = new List<Item>();
|
||||
|
||||
public CharacterAbilityRegenerateLoot(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
|
||||
+4
-4
@@ -10,20 +10,20 @@ namespace Barotrauma.Abilities
|
||||
{
|
||||
private readonly List<StatusEffect> statusEffects;
|
||||
private readonly List<StatusEffect> statusEffectsReset;
|
||||
private int maxEnemyCount;
|
||||
private float squaredDistance;
|
||||
private readonly int maxEnemyCount;
|
||||
private readonly float squaredDistance;
|
||||
|
||||
public CharacterAbilityStonewall(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
{
|
||||
statusEffects = CharacterAbilityGroup.ParseStatusEffects(CharacterTalent, abilityElement.GetChildElement("statuseffects"));
|
||||
statusEffectsReset = CharacterAbilityGroup.ParseStatusEffects(CharacterTalent, abilityElement.GetChildElement("statuseffectsreset"));
|
||||
maxEnemyCount = abilityElement.GetAttributeInt("maxenemycount", 0);
|
||||
squaredDistance = DistanceToSquaredDistance(abilityElement.GetAttributeFloat("distance", 0));
|
||||
squaredDistance = MathF.Pow(abilityElement.GetAttributeFloat("distance", 0), 2);
|
||||
}
|
||||
|
||||
protected override void VerifyState(bool conditionsMatched, float timeSinceLastUpdate)
|
||||
{
|
||||
int numberOfEnemiesInRange = Character.CharacterList.Where(c => !HumanAIController.IsFriendly(Character, c) && !c.IsDead && Vector2.DistanceSquared(Character.SimPosition, Character.GetRelativeSimPosition(c)) < squaredDistance).Count();
|
||||
int numberOfEnemiesInRange = Character.CharacterList.Count(c => !HumanAIController.IsFriendly(Character, c) && !c.IsDead && Vector2.DistanceSquared(Character.WorldPosition, c.WorldPosition) < squaredDistance);
|
||||
|
||||
foreach (var statusEffect in statusEffectsReset)
|
||||
{
|
||||
|
||||
+1
@@ -8,6 +8,7 @@ namespace Barotrauma.Abilities
|
||||
{
|
||||
class CharacterAbilityTandemFire : CharacterAbilityApplyStatusEffectsToNearestAlly
|
||||
{
|
||||
// this should just be its own class, misleading to inherit here
|
||||
private string tag;
|
||||
public CharacterAbilityTandemFire(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user