Unstable 1.8.4.0
This commit is contained in:
+3
-4
@@ -69,21 +69,20 @@ namespace Barotrauma.Abilities
|
||||
switch (targetType)
|
||||
{
|
||||
case TargetType.Enemy:
|
||||
return !HumanAIController.IsFriendly(character, targetCharacter);
|
||||
return !HumanAIController.IsFriendly(character, targetCharacter, onlySameTeam: false);
|
||||
case TargetType.Ally:
|
||||
return HumanAIController.IsFriendly(character, targetCharacter);
|
||||
return HumanAIController.IsFriendly(character, targetCharacter, onlySameTeam: true);
|
||||
case TargetType.NotSelf:
|
||||
return targetCharacter != character;
|
||||
case TargetType.Alive:
|
||||
return !targetCharacter.IsDead;
|
||||
case TargetType.Monster:
|
||||
return !targetCharacter.IsHuman;
|
||||
return !targetCharacter.IsHuman && !targetCharacter.IsPet;
|
||||
case TargetType.InFriendlySubmarine:
|
||||
return targetCharacter.Submarine != null && targetCharacter.Submarine.TeamID == character.TeamID;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+2
-21
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
|
||||
@@ -7,31 +6,13 @@ namespace Barotrauma.Abilities
|
||||
{
|
||||
class AbilityConditionMission : AbilityConditionData
|
||||
{
|
||||
private readonly ImmutableHashSet<MissionType> missionType;
|
||||
private readonly ImmutableHashSet<Identifier> missionType;
|
||||
private readonly bool isAffiliated;
|
||||
|
||||
public AbilityConditionMission(CharacterTalent characterTalent, ContentXElement conditionElement) : base(characterTalent, conditionElement)
|
||||
{
|
||||
string[] missionTypeStrings = conditionElement.GetAttributeStringArray("missiontype", new []{ "None" })!;
|
||||
HashSet<MissionType> missionTypes = new HashSet<MissionType>();
|
||||
missionType = conditionElement.GetAttributeIdentifierImmutableHashSet("missiontype", ImmutableHashSet<Identifier>.Empty)!;
|
||||
isAffiliated = conditionElement.GetAttributeBool("isaffiliated", false);
|
||||
|
||||
foreach (string missionTypeString in missionTypeStrings)
|
||||
{
|
||||
if (!Enum.TryParse(missionTypeString, out MissionType parsedMission) || parsedMission is MissionType.None)
|
||||
{
|
||||
if (!isAffiliated)
|
||||
{
|
||||
DebugConsole.ThrowError($"Error in AbilityConditionMission \"{characterTalent.DebugIdentifier}\" - \"{missionTypeString}\" is not a valid mission type.",
|
||||
contentPackage: conditionElement.ContentPackage);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
missionTypes.Add(parsedMission);
|
||||
}
|
||||
|
||||
missionType = missionTypes.ToImmutableHashSet();
|
||||
}
|
||||
|
||||
protected override bool MatchesConditionSpecific(AbilityObject abilityObject)
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ namespace Barotrauma.Abilities
|
||||
|
||||
protected override bool MatchesConditionSpecific()
|
||||
{
|
||||
foreach (Character c in GameSession.GetSessionCrewCharacters(CharacterType.Both))
|
||||
foreach (Character c in Character.GetFriendlyCrew(character))
|
||||
{
|
||||
if (!c.IsDead && c.IsUnconscious)
|
||||
{
|
||||
|
||||
+2
-3
@@ -1,6 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Abilities
|
||||
{
|
||||
@@ -14,8 +13,8 @@ namespace Barotrauma.Abilities
|
||||
|
||||
protected override bool MatchesConditionSpecific()
|
||||
{
|
||||
IEnumerable<Character> crewmembers = Character.GetFriendlyCrew(character);
|
||||
int differentCrewAmount = crewmembers.Select(c => c.Info?.Job?.Prefab.Identifier).Distinct().Count();
|
||||
IEnumerable<Character> crewMembers = Character.GetFriendlyCrew(character);
|
||||
int differentCrewAmount = crewMembers.Select(c => c.Info.Job?.Prefab.Identifier).Distinct().Count();
|
||||
return differentCrewAmount >= amount;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-8
@@ -1,18 +1,13 @@
|
||||
using Barotrauma.Items.Components;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Abilities
|
||||
namespace Barotrauma.Abilities
|
||||
{
|
||||
class AbilityConditionHasSkill : AbilityConditionDataless
|
||||
{
|
||||
private readonly string skillIdentifier;
|
||||
private readonly Identifier skillIdentifier;
|
||||
private readonly float minValue;
|
||||
|
||||
public AbilityConditionHasSkill(CharacterTalent characterTalent, ContentXElement conditionElement) : base(characterTalent, conditionElement)
|
||||
{
|
||||
skillIdentifier = conditionElement.GetAttributeString("skillidentifier", string.Empty);
|
||||
skillIdentifier = conditionElement.GetAttributeIdentifier("skillidentifier", Identifier.Empty);
|
||||
minValue = conditionElement.GetAttributeFloat("minvalue", 0f);
|
||||
}
|
||||
|
||||
|
||||
+2
-4
@@ -1,6 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma.Abilities
|
||||
{
|
||||
@@ -14,7 +12,7 @@ namespace Barotrauma.Abilities
|
||||
|
||||
protected override bool MatchesConditionSpecific()
|
||||
{
|
||||
return Character.GetFriendlyCrew(character).Where(c => c.Info != null && (c.Info.GetCurrentLevel() - character.Info.GetCurrentLevel() >= levelsBehind)).Any();
|
||||
return Character.GetFriendlyCrew(character).Any(c => c.Info.GetCurrentLevel() - character.Info.GetCurrentLevel() >= levelsBehind);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ namespace Barotrauma.Abilities
|
||||
protected override bool MatchesCharacter(Character character)
|
||||
{
|
||||
int ownLevel = character.Info.GetCurrentLevel();
|
||||
foreach (Character otherCharacter in GameSession.GetSessionCrewCharacters(CharacterType.Both))
|
||||
foreach (Character otherCharacter in Character.GetFriendlyCrew(character))
|
||||
{
|
||||
if (otherCharacter == character) { continue; }
|
||||
if (otherCharacter.Info.GetCurrentLevel() < ownLevel) { return false; }
|
||||
|
||||
+5
-3
@@ -13,13 +13,15 @@
|
||||
{
|
||||
if (GameMain.GameSession == null) { return false; }
|
||||
|
||||
foreach (Character character in GameMain.GameSession.Casualties)
|
||||
foreach (Character deadCharacter in GameMain.GameSession.Casualties)
|
||||
{
|
||||
if (assistantsDontCount && character.Info?.Job?.Prefab.Identifier == "assistant")
|
||||
if (deadCharacter.TeamID != character.TeamID) { continue; }
|
||||
|
||||
if (assistantsDontCount && deadCharacter.Info?.Job?.Prefab.Identifier == "assistant")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (character.CauseOfDeath != null && character.CauseOfDeath.Type != CauseOfDeathType.Disconnected)
|
||||
if (deadCharacter.CauseOfDeath != null && deadCharacter.CauseOfDeath.Type != CauseOfDeathType.Disconnected)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
+2
-1
@@ -14,7 +14,8 @@
|
||||
float waterVolume = 0.0f, totalVolume = 0.0f;
|
||||
foreach (Hull hull in Hull.HullList)
|
||||
{
|
||||
if (hull.Submarine != character.Submarine) { continue; }
|
||||
if (hull.Submarine is not { } hullSubmarine) { continue; }
|
||||
if (hullSubmarine != character.Submarine || hullSubmarine.TeamID != character.TeamID) { continue; }
|
||||
waterVolume += hull.WaterVolume;
|
||||
totalVolume += hull.Volume;
|
||||
}
|
||||
|
||||
+1
-1
@@ -100,7 +100,7 @@ namespace Barotrauma.Abilities
|
||||
string type = abilityElement.Name.ToString().ToLowerInvariant();
|
||||
try
|
||||
{
|
||||
abilityType = ReflectionUtils.GetTypeWithBackwardsCompatibility("Barotrauma.Abilities", type, false, true);
|
||||
abilityType = ReflectionUtils.GetTypeWithBackwardsCompatibility(ToolBox.BarotraumaAssembly, "Barotrauma.Abilities", type, false, true);
|
||||
if (abilityType == null)
|
||||
{
|
||||
if (errorMessages) DebugConsole.ThrowError("Could not find the CharacterAbility \"" + type + "\" (" + characterAbilityGroup.CharacterTalent.DebugIdentifier + ")",
|
||||
|
||||
+14
-6
@@ -19,6 +19,13 @@ namespace Barotrauma.Abilities
|
||||
|
||||
private bool effectBeingApplied;
|
||||
|
||||
/// <summary>
|
||||
/// Should the character who has the ability be marked as the "user" of the status effect?
|
||||
/// Means that e.g. enemies will consider damage from the effect to be coming from the character with the ability, and that the character will gain skills if the effect e.g. heals someone.
|
||||
/// </summary>
|
||||
|
||||
private readonly bool setUser;
|
||||
|
||||
public CharacterAbilityApplyStatusEffects(CharacterAbilityGroup characterAbilityGroup, ContentXElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
{
|
||||
statusEffects = CharacterAbilityGroup.ParseStatusEffects(CharacterTalent, abilityElement.GetChildElement("statuseffects"));
|
||||
@@ -27,6 +34,7 @@ namespace Barotrauma.Abilities
|
||||
nearbyCharactersAppliesToSelf = abilityElement.GetAttributeBool("nearbycharactersappliestoself", true);
|
||||
nearbyCharactersAppliesToAllies = abilityElement.GetAttributeBool("nearbycharactersappliestoallies", true);
|
||||
nearbyCharactersAppliesToEnemies = abilityElement.GetAttributeBool("nearbycharactersappliestoenemies", true);
|
||||
setUser = abilityElement.GetAttributeBool("setuser", true);
|
||||
}
|
||||
|
||||
protected void ApplyEffectSpecific(Character targetCharacter, Limb targetLimb = null)
|
||||
@@ -44,7 +52,7 @@ namespace Barotrauma.Abilities
|
||||
if (statusEffect.HasTargetType(StatusEffect.TargetType.UseTarget))
|
||||
{
|
||||
// currently used to spawn items on the targeted character
|
||||
statusEffect.SetUser(targetCharacter);
|
||||
if (setUser) { statusEffect.SetUser(targetCharacter); }
|
||||
statusEffect.Apply(ActionType.OnAbility, EffectDeltaTime, targetCharacter, targetCharacter);
|
||||
}
|
||||
else if (statusEffect.HasTargetType(StatusEffect.TargetType.NearbyCharacters))
|
||||
@@ -57,28 +65,28 @@ namespace Barotrauma.Abilities
|
||||
}
|
||||
if (!nearbyCharactersAppliesToAllies)
|
||||
{
|
||||
targets.RemoveAll(c => c is Character otherCharacter && HumanAIController.IsFriendly(otherCharacter, Character));
|
||||
targets.RemoveAll(c => c is Character otherCharacter && HumanAIController.IsFriendly(otherCharacter, Character, onlySameTeam: true));
|
||||
}
|
||||
if (!nearbyCharactersAppliesToEnemies)
|
||||
{
|
||||
targets.RemoveAll(c => c is Character otherCharacter && !HumanAIController.IsFriendly(otherCharacter, Character));
|
||||
}
|
||||
statusEffect.SetUser(Character);
|
||||
if (setUser) { statusEffect.SetUser(Character); }
|
||||
statusEffect.Apply(ActionType.OnAbility, EffectDeltaTime, targetCharacter, targets);
|
||||
}
|
||||
else if (statusEffect.HasTargetType(StatusEffect.TargetType.Limb) && targetLimb != null)
|
||||
{
|
||||
statusEffect.SetUser(Character);
|
||||
if (setUser) { statusEffect.SetUser(Character); }
|
||||
statusEffect.Apply(ActionType.OnAbility, EffectDeltaTime, Character, targetLimb);
|
||||
}
|
||||
else if (statusEffect.HasTargetType(StatusEffect.TargetType.Character))
|
||||
{
|
||||
statusEffect.SetUser(Character);
|
||||
if (setUser) { statusEffect.SetUser(Character); }
|
||||
statusEffect.Apply(ActionType.OnAbility, EffectDeltaTime, Character, targetCharacter);
|
||||
}
|
||||
else
|
||||
{
|
||||
statusEffect.SetUser(Character);
|
||||
if (setUser) { statusEffect.SetUser(Character); }
|
||||
statusEffect.Apply(ActionType.OnAbility, EffectDeltaTime, Character, Character);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -26,9 +26,9 @@ namespace Barotrauma.Abilities
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (Character character in GameSession.GetSessionCrewCharacters(CharacterType.Both))
|
||||
foreach (Character character in Character.GetFriendlyCrew(Character))
|
||||
{
|
||||
JobPrefab? characterJob = character.Info?.Job?.Prefab;
|
||||
JobPrefab? characterJob = character.Info.Job?.Prefab;
|
||||
if (characterJob is null) { continue; }
|
||||
|
||||
switch (characterJob.Identifier == apprenticeJob.Identifier)
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@
|
||||
foreach (Character otherCharacter in Character.GetFriendlyCrew(Character))
|
||||
{
|
||||
if (otherCharacter == Character) { continue; }
|
||||
otherCharacter.Info?.IncreaseSkillLevel(identifier, abilitySkillGain.Value, gainedFromAbility: true);
|
||||
otherCharacter.Info.IncreaseSkillLevel(identifier, abilitySkillGain.Value, gainedFromAbility: true);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
+3
-3
@@ -4,14 +4,14 @@
|
||||
{
|
||||
private readonly Identifier afflictionId;
|
||||
private readonly float strength;
|
||||
private readonly string multiplyStrengthBySkill;
|
||||
private readonly Identifier multiplyStrengthBySkill;
|
||||
private readonly bool setValue;
|
||||
|
||||
public CharacterAbilityGiveAffliction(CharacterAbilityGroup characterAbilityGroup, ContentXElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
{
|
||||
afflictionId = abilityElement.GetAttributeIdentifier("afflictionid", abilityElement.GetAttributeIdentifier("affliction", Identifier.Empty));
|
||||
strength = abilityElement.GetAttributeFloat("strength", 0f);
|
||||
multiplyStrengthBySkill = abilityElement.GetAttributeString("multiplystrengthbyskill", string.Empty);
|
||||
multiplyStrengthBySkill = abilityElement.GetAttributeIdentifier("multiplystrengthbyskill", Identifier.Empty);
|
||||
setValue = abilityElement.GetAttributeBool("setvalue", false);
|
||||
|
||||
if (afflictionId.IsEmpty)
|
||||
@@ -52,7 +52,7 @@
|
||||
return;
|
||||
}
|
||||
float strength = this.strength;
|
||||
if (!string.IsNullOrEmpty(multiplyStrengthBySkill))
|
||||
if (!multiplyStrengthBySkill.IsEmpty)
|
||||
{
|
||||
strength *= Character.GetSkillLevel(multiplyStrengthBySkill);
|
||||
}
|
||||
|
||||
+1
-1
@@ -75,7 +75,7 @@ namespace Barotrauma.Abilities
|
||||
{
|
||||
foreach (Character c in Character.GetFriendlyCrew(Character))
|
||||
{
|
||||
c?.Info?.ChangeSavedStatValue(statType, value, identifier, removeOnDeath, maxValue: maxValue, setValue: setValue);
|
||||
c.Info.ChangeSavedStatValue(statType, value, identifier, removeOnDeath, maxValue: maxValue, setValue: setValue);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
+1
-2
@@ -20,9 +20,8 @@ namespace Barotrauma.Abilities
|
||||
{
|
||||
if (!addingFirstTime) { return; }
|
||||
|
||||
foreach (Character character in GameSession.GetSessionCrewCharacters(CharacterType.Both))
|
||||
foreach (Character character in Character.GetFriendlyCrew(Character))
|
||||
{
|
||||
if (character.Info is null) { return; }
|
||||
character.Info.AdditionalTalentPoints += amount;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@ namespace Barotrauma.Abilities
|
||||
{
|
||||
private readonly StatTypes statType;
|
||||
private readonly float maxValue;
|
||||
private readonly string skillIdentifier;
|
||||
private readonly Identifier skillIdentifier;
|
||||
private readonly bool useAll;
|
||||
private float lastValue = 0f;
|
||||
public override bool AllowClientSimulation => true;
|
||||
@@ -15,7 +15,7 @@ namespace Barotrauma.Abilities
|
||||
{
|
||||
statType = CharacterAbilityGroup.ParseStatType(abilityElement.GetAttributeString("stattype", ""), CharacterTalent.DebugIdentifier);
|
||||
maxValue = abilityElement.GetAttributeFloat("maxvalue", 0f);
|
||||
skillIdentifier = abilityElement.GetAttributeString("skillidentifier", string.Empty);
|
||||
skillIdentifier = abilityElement.GetAttributeIdentifier("skillidentifier", Identifier.Empty);
|
||||
useAll = skillIdentifier == "all";
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -5,6 +5,8 @@
|
||||
private readonly float addedValue;
|
||||
private readonly float multiplyValue;
|
||||
|
||||
public override bool AllowClientSimulation => true;
|
||||
|
||||
public CharacterAbilityModifyValue(CharacterAbilityGroup characterAbilityGroup, ContentXElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
{
|
||||
addedValue = abilityElement.GetAttributeFloat("addedvalue", 0f);
|
||||
|
||||
+23
-3
@@ -1,4 +1,4 @@
|
||||
#nullable enable
|
||||
#nullable enable
|
||||
|
||||
namespace Barotrauma.Abilities
|
||||
{
|
||||
@@ -19,10 +19,30 @@ namespace Barotrauma.Abilities
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ApplyEffect()
|
||||
{
|
||||
ApplyEffectToCharacter(Character);
|
||||
}
|
||||
|
||||
protected override void ApplyEffect(AbilityObject abilityObject)
|
||||
{
|
||||
if (abilityObject is not IAbilityCharacter character) { return; }
|
||||
character.Character.CharacterHealth.ReduceAfflictionOnAllLimbs(afflictionId, amount, attacker: Character);
|
||||
if (abilityObject is IAbilityCharacter characterData)
|
||||
{
|
||||
ApplyEffectToCharacter(characterData.Character);
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyEffectToCharacter(Character character)
|
||||
{
|
||||
character?.CharacterHealth.ReduceAfflictionOnAllLimbs(afflictionId, amount, attacker: Character);
|
||||
}
|
||||
|
||||
protected override void VerifyState(bool conditionsMatched, float timeSinceLastUpdate)
|
||||
{
|
||||
if (conditionsMatched)
|
||||
{
|
||||
ApplyEffect();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
-1
@@ -6,6 +6,7 @@ internal class CharacterAbilityUpgradeSubmarine : CharacterAbility
|
||||
private readonly UpgradePrefab? upgradePrefab;
|
||||
private readonly UpgradeCategory? upgradeCategory;
|
||||
public readonly int level;
|
||||
private readonly bool giveOnAddingFirstTime;
|
||||
|
||||
public override bool AllowClientSimulation => true;
|
||||
|
||||
@@ -13,7 +14,8 @@ internal class CharacterAbilityUpgradeSubmarine : CharacterAbility
|
||||
{
|
||||
var prefabIdentifier = abilityElement.GetAttributeIdentifier(nameof(upgradePrefab), Identifier.Empty);
|
||||
var categoryIdentifier = abilityElement.GetAttributeIdentifier(nameof(upgradeCategory), Identifier.Empty);
|
||||
|
||||
giveOnAddingFirstTime = abilityElement.GetAttributeBool("giveonaddingfirsttime", characterAbilityGroup.AbilityEffectType == AbilityEffectType.None);
|
||||
|
||||
if (UpgradePrefab.Find(prefabIdentifier) is not { } foundUpgradePrefab)
|
||||
{
|
||||
DebugConsole.ThrowError($"Error in talent {CharacterTalent.DebugIdentifier}, {nameof(CharacterAbilityUpgradeSubmarine)} - {nameof(upgradePrefab)} not found.",
|
||||
@@ -47,6 +49,14 @@ internal class CharacterAbilityUpgradeSubmarine : CharacterAbility
|
||||
ApplyEffectSpecific();
|
||||
}
|
||||
|
||||
public override void InitializeAbility(bool addingFirstTime)
|
||||
{
|
||||
if (addingFirstTime && giveOnAddingFirstTime)
|
||||
{
|
||||
ApplyEffectSpecific();
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyEffectSpecific()
|
||||
{
|
||||
if (upgradePrefab == null || upgradeCategory == null) { return; }
|
||||
|
||||
+6
-2
@@ -24,14 +24,18 @@ namespace Barotrauma.Abilities
|
||||
foreach (Character enemyCharacter in enemyCharacters)
|
||||
{
|
||||
if (!enemyCharacter.IsHuman) { continue; }
|
||||
if (enemyCharacter.Submarine == null || enemyCharacter.Submarine != Submarine.MainSub) { continue; }
|
||||
if (enemyCharacter.Submarine == null ||
|
||||
(Submarine.MainSub != null && enemyCharacter.Submarine != Submarine.MainSub))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (enemyCharacter.IsDead) { continue; }
|
||||
if (!enemyCharacter.LockHands) { continue; }
|
||||
Character.GiveMoney(moneyAmount);
|
||||
GameAnalyticsManager.AddMoneyGainedEvent(moneyAmount, GameAnalyticsManager.MoneySource.Ability, CharacterTalent.Prefab.Identifier.Value);
|
||||
foreach (Character character in Character.GetFriendlyCrew(Character))
|
||||
{
|
||||
character.Info?.GiveExperience(experienceAmount);
|
||||
character.Info.GiveExperience(experienceAmount);
|
||||
}
|
||||
timesGiven++;
|
||||
if (max > 0 && timesGiven >= max) { break; }
|
||||
|
||||
+9
-8
@@ -1,4 +1,4 @@
|
||||
#nullable enable
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using Barotrauma.Extensions;
|
||||
@@ -31,7 +31,7 @@ namespace Barotrauma.Abilities
|
||||
|
||||
if (!TalentTree.JobTalentTrees.TryGet(apprentice.Identifier, out TalentTree? talentTree)) { return; }
|
||||
|
||||
ImmutableHashSet<Character> characters = GameSession.GetSessionCrewCharacters(CharacterType.Both);
|
||||
var characters = Character.GetFriendlyCrew(Character);
|
||||
|
||||
HashSet<ImmutableHashSet<Identifier>> talentsTrees = new HashSet<ImmutableHashSet<Identifier>>();
|
||||
foreach (TalentSubTree subTree in talentTree.TalentSubTrees)
|
||||
@@ -60,13 +60,14 @@ namespace Barotrauma.Abilities
|
||||
talentsTrees.Add(identifiers.ToImmutableHashSet());
|
||||
}
|
||||
|
||||
ImmutableHashSet<Identifier> selectedTalentTree = talentsTrees.GetRandomUnsynced();
|
||||
|
||||
foreach (Identifier identifier in selectedTalentTree)
|
||||
ImmutableHashSet<Identifier>? selectedTalentTree = talentsTrees.GetRandomUnsynced();
|
||||
if (selectedTalentTree != null)
|
||||
{
|
||||
if (Character.HasTalent(identifier)) { continue; }
|
||||
|
||||
Character.GiveTalent(identifier);
|
||||
foreach (Identifier identifier in selectedTalentTree)
|
||||
{
|
||||
if (Character.HasTalent(identifier)) { continue; }
|
||||
Character.GiveTalent(identifier);
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsShowCaseTalent(Identifier identifier, TalentOption option)
|
||||
|
||||
+19
-8
@@ -12,14 +12,20 @@
|
||||
internal class CharacterAbilityWarStories : CharacterAbility
|
||||
{
|
||||
private readonly Identifier targetStat;
|
||||
private readonly float minCondition;
|
||||
private readonly float normalQualityThreshold;
|
||||
private readonly float goodQualityThreshold;
|
||||
private readonly float excellentQualityThreshold;
|
||||
private readonly float masterworkQualityThreshold;
|
||||
|
||||
private readonly ItemPrefab prefab;
|
||||
|
||||
public CharacterAbilityWarStories(CharacterAbilityGroup characterAbilityGroup, ContentXElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
{
|
||||
targetStat = abilityElement.GetAttributeIdentifier("target", Identifier.Empty);
|
||||
minCondition = abilityElement.GetAttributeFloat("mincondition", 1);
|
||||
normalQualityThreshold = abilityElement.GetAttributeFloat("normalqualitythreshold", 4);
|
||||
goodQualityThreshold = abilityElement.GetAttributeFloat("goodqualitythreshold", 10);
|
||||
excellentQualityThreshold = abilityElement.GetAttributeFloat("excellentqualitythreshold", 20);
|
||||
masterworkQualityThreshold = abilityElement.GetAttributeFloat("masterworkqualitythreshold", 30);
|
||||
|
||||
if (targetStat.IsEmpty)
|
||||
{
|
||||
@@ -37,23 +43,28 @@ internal class CharacterAbilityWarStories : CharacterAbility
|
||||
{
|
||||
if (prefab is null || Character is null) { return; }
|
||||
|
||||
float condition = Character.Info?.GetSavedStatValue(StatTypes.None, targetStat) ?? 0;
|
||||
if (condition < minCondition) { return; }
|
||||
float statValue = Character.Info?.GetSavedStatValue(StatTypes.None, targetStat) ?? 0;
|
||||
|
||||
if (statValue < normalQualityThreshold) { return; }
|
||||
|
||||
int quality = 0;
|
||||
if (statValue >= masterworkQualityThreshold) { quality = 3; }
|
||||
else if (statValue >= excellentQualityThreshold) { quality = 2; }
|
||||
else if (statValue >= goodQualityThreshold) { quality = 1; }
|
||||
|
||||
if (GameMain.GameSession?.RoundEnding ?? true)
|
||||
{
|
||||
Item item = new(prefab, Character.WorldPosition, Character.Submarine)
|
||||
{
|
||||
Condition = condition,
|
||||
HealthMultiplier = condition
|
||||
Quality = quality,
|
||||
};
|
||||
Character.Inventory.TryPutItem(item, Character, item.AllowedSlots);
|
||||
}
|
||||
else
|
||||
{
|
||||
Entity.Spawner?.AddItemToSpawnQueue(prefab, Character.Inventory, condition: condition, onSpawned: item =>
|
||||
Entity.Spawner?.AddItemToSpawnQueue(prefab, Character.Inventory, quality: quality, onSpawned: item =>
|
||||
{
|
||||
item.HealthMultiplier = condition;
|
||||
item.Quality = quality;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -140,7 +140,7 @@ namespace Barotrauma.Abilities
|
||||
string type = conditionElement.Name.ToString().ToLowerInvariant();
|
||||
try
|
||||
{
|
||||
conditionType = ReflectionUtils.GetTypeWithBackwardsCompatibility("Barotrauma.Abilities", type, false, true);
|
||||
conditionType = ReflectionUtils.GetTypeWithBackwardsCompatibility(ToolBox.BarotraumaAssembly, "Barotrauma.Abilities", type, false, true);
|
||||
if (conditionType == null)
|
||||
{
|
||||
if (errorMessages)
|
||||
|
||||
@@ -22,6 +22,11 @@ namespace Barotrauma
|
||||
|
||||
public readonly Sprite Icon;
|
||||
|
||||
/// <summary>
|
||||
/// When set to true, this talent will not be visible in the "Extra Talents" panel if it is not part of the character's job talent tree.
|
||||
/// </summary>
|
||||
public readonly bool IsHiddenExtraTalent;
|
||||
|
||||
/// <summary>
|
||||
/// When set to a value the talent tooltip will display a text showing the current value of the stat and the max value.
|
||||
/// For example "Progress: 37/100".
|
||||
@@ -62,6 +67,8 @@ namespace Barotrauma
|
||||
DisplayName = TextManager.Get(nameIdentifier).Fallback(Identifier.Value);
|
||||
}
|
||||
|
||||
IsHiddenExtraTalent = element.GetAttributeBool("ishiddenextratalent", false);
|
||||
|
||||
Description = string.Empty;
|
||||
|
||||
#if CLIENT
|
||||
|
||||
@@ -131,7 +131,7 @@ namespace Barotrauma
|
||||
if (character.Info.GetTotalTalentPoints() - selectedTalents.Count <= 0) { return false; }
|
||||
if (!JobTalentTrees.TryGet(character.Info.Job.Prefab.Identifier, out TalentTree talentTree)) { return false; }
|
||||
|
||||
if (IsTalentLocked(talentIdentifier)) { return false; }
|
||||
if (IsTalentLocked(talentIdentifier, Character.GetFriendlyCrew(character))) { return false; }
|
||||
|
||||
if (character.Info.GetUnlockedTalentsInTree().Contains(talentIdentifier))
|
||||
{
|
||||
@@ -163,10 +163,8 @@ namespace Barotrauma
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool IsTalentLocked(Identifier talentIdentifier, ImmutableHashSet<Character> characterList = null)
|
||||
public static bool IsTalentLocked(Identifier talentIdentifier, IEnumerable<Character> characterList)
|
||||
{
|
||||
characterList ??= GameSession.GetSessionCrewCharacters(CharacterType.Both);
|
||||
|
||||
foreach (Character c in characterList)
|
||||
{
|
||||
if (c.Info.GetSavedStatValue(StatTypes.LockedTalents, talentIdentifier) >= 1) { return true; }
|
||||
|
||||
Reference in New Issue
Block a user