Unstable 1.1.14.0
This commit is contained in:
+2
-2
@@ -22,13 +22,13 @@ namespace Barotrauma.Abilities
|
||||
private static readonly List<WeaponType> WeaponTypeValues = Enum.GetValues(typeof(WeaponType)).Cast<WeaponType>().ToList();
|
||||
|
||||
private readonly string itemIdentifier;
|
||||
private readonly string[] tags;
|
||||
private readonly Identifier[] tags;
|
||||
private readonly WeaponType weapontype;
|
||||
private readonly bool ignoreNonHarmfulAttacks;
|
||||
public AbilityConditionAttackData(CharacterTalent characterTalent, ContentXElement conditionElement) : base(characterTalent, conditionElement)
|
||||
{
|
||||
itemIdentifier = conditionElement.GetAttributeString("itemidentifier", string.Empty);
|
||||
tags = conditionElement.GetAttributeStringArray("tags", Array.Empty<string>(), convertToLowerInvariant: true);
|
||||
tags = conditionElement.GetAttributeIdentifierArray("tags", Array.Empty<Identifier>());
|
||||
ignoreNonHarmfulAttacks = conditionElement.GetAttributeBool("ignorenonharmfulattacks", false);
|
||||
|
||||
string weaponTypeStr = conditionElement.GetAttributeString("weapontype", "Any");
|
||||
|
||||
+3
-3
@@ -41,10 +41,10 @@ namespace Barotrauma.Abilities
|
||||
|
||||
if (GameMain.GameSession?.Campaign?.Factions is not { } factions) { return false; }
|
||||
|
||||
foreach (var (factionIdentifier, amount) in mission.ReputationRewards)
|
||||
foreach (var reputationReward in mission.ReputationRewards)
|
||||
{
|
||||
if (amount <= 0) { continue; }
|
||||
if (GetMatchingFaction(factionIdentifier) is { } faction &&
|
||||
if (reputationReward.Amount <= 0) { continue; }
|
||||
if (GetMatchingFaction(reputationReward.FactionIdentifier) is { } faction &&
|
||||
Faction.GetPlayerAffiliationStatus(faction) is FactionAffiliation.Positive)
|
||||
{
|
||||
return CheckMissionType();
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
|
||||
namespace Barotrauma.Abilities
|
||||
{
|
||||
class AbilityConditionAllyHasTalent : AbilityConditionDataless
|
||||
{
|
||||
private readonly Identifier talentIdentifier;
|
||||
|
||||
public AbilityConditionAllyHasTalent(CharacterTalent characterTalent, ContentXElement conditionElement) : base(characterTalent, conditionElement)
|
||||
{
|
||||
talentIdentifier = conditionElement.GetAttributeIdentifier("identifier", Identifier.Empty);
|
||||
}
|
||||
|
||||
protected override bool MatchesConditionSpecific()
|
||||
{
|
||||
foreach (Character crewCharacter in Character.GetFriendlyCrew(characterTalent.Character))
|
||||
{
|
||||
if (crewCharacter.HasTalent(talentIdentifier)) { return true; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -5,12 +5,12 @@ namespace Barotrauma.Abilities
|
||||
{
|
||||
class AbilityConditionHasItem : AbilityConditionDataless
|
||||
{
|
||||
private readonly string[] tags;
|
||||
private readonly Identifier[] tags;
|
||||
readonly bool requireAll;
|
||||
|
||||
public AbilityConditionHasItem(CharacterTalent characterTalent, ContentXElement conditionElement) : base(characterTalent, conditionElement)
|
||||
{
|
||||
tags = conditionElement.GetAttributeStringArray("tags", Array.Empty<string>());
|
||||
tags = conditionElement.GetAttributeIdentifierArray("tags", Array.Empty<Identifier>());
|
||||
requireAll = conditionElement.GetAttributeBool("requireall", false);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Barotrauma.Abilities
|
||||
|
||||
if (requireAll)
|
||||
{
|
||||
foreach (string tag in tags)
|
||||
foreach (Identifier tag in tags)
|
||||
{
|
||||
if (character.GetEquippedItem(tag) == null) { return false; }
|
||||
}
|
||||
@@ -31,7 +31,7 @@ namespace Barotrauma.Abilities
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (string tag in tags)
|
||||
foreach (Identifier tag in tags)
|
||||
{
|
||||
if (character.GetEquippedItem(tag) != null) { return true; }
|
||||
}
|
||||
|
||||
+4
-4
@@ -5,13 +5,13 @@ namespace Barotrauma.Abilities
|
||||
{
|
||||
class AbilityConditionHasStatusTag : AbilityConditionDataless
|
||||
{
|
||||
private readonly string tag;
|
||||
private readonly Identifier tag;
|
||||
|
||||
|
||||
public AbilityConditionHasStatusTag(CharacterTalent characterTalent, ContentXElement conditionElement) : base(characterTalent, conditionElement)
|
||||
{
|
||||
tag = conditionElement.GetAttributeString("tag", "");
|
||||
if (string.IsNullOrEmpty(tag))
|
||||
tag = conditionElement.GetAttributeIdentifier("tag", Identifier.Empty);
|
||||
if (tag.IsEmpty)
|
||||
{
|
||||
DebugConsole.AddWarning($"Error in talent \"{characterTalent.Prefab.OriginalName}\" - tag not defined in AbilityConditionHasStatusTag.");
|
||||
}
|
||||
@@ -19,7 +19,7 @@ namespace Barotrauma.Abilities
|
||||
|
||||
protected override bool MatchesConditionSpecific()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(tag))
|
||||
if (!tag.IsEmpty)
|
||||
{
|
||||
return
|
||||
StatusEffect.DurationList.Any(d => d.Targets.Contains(character) && d.Parent.HasTag(tag)) ||
|
||||
|
||||
+1
-2
@@ -12,8 +12,7 @@ namespace Barotrauma.Abilities
|
||||
|
||||
protected override bool MatchesConditionSpecific()
|
||||
{
|
||||
bool result = character.HasTalent(talentIdentifier);
|
||||
return result;
|
||||
return character.HasTalent(talentIdentifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -27,8 +27,8 @@ internal sealed class AbilityConditionHoldingItem : AbilityConditionDataless
|
||||
return false;
|
||||
|
||||
static bool HasItemInHand(Character character, Identifier? tagOrIdentifier) =>
|
||||
character.GetEquippedItem(tagOrIdentifier?.Value, InvSlotType.RightHand) is not null ||
|
||||
character.GetEquippedItem(tagOrIdentifier?.Value, InvSlotType.LeftHand) is not null;
|
||||
character.GetEquippedItem(tagOrIdentifier, InvSlotType.RightHand) is not null ||
|
||||
character.GetEquippedItem(tagOrIdentifier, InvSlotType.LeftHand) is not null;
|
||||
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -37,10 +37,11 @@ namespace Barotrauma.Abilities
|
||||
|
||||
protected override void ApplyEffect()
|
||||
{
|
||||
if (Character?.Submarine is null) { return; }
|
||||
if (Character is null) { return; }
|
||||
|
||||
foreach (Item item in Character.Submarine.GetItems(true))
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
if (item.Submarine?.TeamID != Character.TeamID) { continue; }
|
||||
if (item.HasTag(tags) || tags.Contains(item.Prefab.Identifier))
|
||||
{
|
||||
item.StatManager.ApplyStat(stat, stackable, value, CharacterTalent);
|
||||
|
||||
+2
-2
@@ -66,12 +66,12 @@
|
||||
{
|
||||
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
|
||||
{
|
||||
Character?.Info.ChangeSavedStatValue(statType, value, identifier, removeOnDeath, maxValue: maxValue, setValue: setValue);
|
||||
Character?.Info?.ChangeSavedStatValue(statType, value, identifier, removeOnDeath, maxValue: maxValue, setValue: setValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -18,7 +18,7 @@ namespace Barotrauma.Abilities
|
||||
|
||||
protected override void ApplyEffect()
|
||||
{
|
||||
IEnumerable<Character> enemyCharacters = Character.CharacterList.Where(c => c.TeamID == CharacterTeamType.None);
|
||||
IEnumerable<Character> enemyCharacters = Character.CharacterList.Where(c => !Character.IsFriendly(c));
|
||||
|
||||
int timesGiven = 0;
|
||||
foreach (Character enemyCharacter in enemyCharacters)
|
||||
@@ -27,7 +27,6 @@ namespace Barotrauma.Abilities
|
||||
if (enemyCharacter.Submarine == null || enemyCharacter.Submarine != Submarine.MainSub) { continue; }
|
||||
if (enemyCharacter.IsDead) { continue; }
|
||||
if (!enemyCharacter.LockHands) { continue; }
|
||||
if (timesGiven > max) { continue; }
|
||||
Character.GiveMoney(moneyAmount);
|
||||
GameAnalyticsManager.AddMoneyGainedEvent(moneyAmount, GameAnalyticsManager.MoneySource.Ability, CharacterTalent.Prefab.Identifier.Value);
|
||||
foreach (Character character in Character.GetFriendlyCrew(Character))
|
||||
@@ -35,6 +34,7 @@ namespace Barotrauma.Abilities
|
||||
character.Info?.GiveExperience(experienceAmount);
|
||||
}
|
||||
timesGiven++;
|
||||
if (max > 0 && timesGiven >= max) { break; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+23
-12
@@ -5,32 +5,43 @@ namespace Barotrauma.Abilities
|
||||
{
|
||||
class CharacterAbilityRegenerateLoot : CharacterAbility
|
||||
{
|
||||
/// <summary>
|
||||
/// Chance for the loot to be regenerated. We can't use <see cref="AbilityConditionServerRandom"/> for this,
|
||||
/// because it'd allow the player to reopen the container until the ability is executed successfully
|
||||
/// </summary>
|
||||
private readonly float randomChance;
|
||||
|
||||
// separate random chance used for the ability itself to prevent the player
|
||||
// from opening/reopening a container until it spawns loot
|
||||
private readonly float randomChance;
|
||||
|
||||
/// <summary>
|
||||
/// Chance for an individual loot item to be generated.
|
||||
/// </summary>
|
||||
private readonly float randomChancePerItem = 1.0f;
|
||||
|
||||
// not maintained through death, so it's possible for players to respawn and re-loot chests
|
||||
// seems like a minor issue for now
|
||||
private readonly List<Item> openedContainers = new List<Item>();
|
||||
private readonly HashSet<Item> openedContainers = new HashSet<Item>();
|
||||
|
||||
public CharacterAbilityRegenerateLoot(CharacterAbilityGroup characterAbilityGroup, ContentXElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
{
|
||||
randomChance = abilityElement.GetAttributeFloat("randomchance", 1f);
|
||||
randomChance = abilityElement.GetAttributeFloat(nameof(randomChance), 1f);
|
||||
randomChancePerItem = abilityElement.GetAttributeFloat(nameof(randomChancePerItem), 1f);
|
||||
}
|
||||
|
||||
protected override void ApplyEffect(AbilityObject abilityObject)
|
||||
{
|
||||
if ((abilityObject as IAbilityItem)?.Item is Item item)
|
||||
{
|
||||
if (openedContainers.Contains(item)) { return; }
|
||||
openedContainers.Add(item);
|
||||
if (randomChance < Rand.Range(0f, 1f, Rand.RandSync.Unsynced)) { return; }
|
||||
if ((abilityObject as IAbilityItem)?.Item is not Item item) { return; }
|
||||
if (openedContainers.Contains(item)) { return; }
|
||||
|
||||
if (item.GetComponent<ItemContainer>() is ItemContainer itemContainer)
|
||||
{
|
||||
AutoItemPlacer.RegenerateLoot(item.Submarine, itemContainer);
|
||||
}
|
||||
openedContainers.Add(item);
|
||||
if (randomChance < Rand.Range(0f, 1f, Rand.RandSync.Unsynced)) { return; }
|
||||
|
||||
if (item.GetComponent<ItemContainer>() is ItemContainer itemContainer)
|
||||
{
|
||||
AutoItemPlacer.RegenerateLoot(item.Submarine, itemContainer, skipItemProbability: 1.0f - randomChancePerItem);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -5,10 +5,10 @@ namespace Barotrauma.Abilities
|
||||
class CharacterAbilityTandemFire : CharacterAbilityApplyStatusEffectsToNearestAlly
|
||||
{
|
||||
// this should just be its own class, misleading to inherit here
|
||||
private readonly string tag;
|
||||
private readonly Identifier tag;
|
||||
public CharacterAbilityTandemFire(CharacterAbilityGroup characterAbilityGroup, ContentXElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
{
|
||||
tag = abilityElement.GetAttributeString("tag", "");
|
||||
tag = abilityElement.GetAttributeIdentifier("tag", Identifier.Empty);
|
||||
}
|
||||
|
||||
protected override void ApplyEffect()
|
||||
@@ -37,7 +37,7 @@ namespace Barotrauma.Abilities
|
||||
ApplyEffectSpecific(closestCharacter);
|
||||
}
|
||||
|
||||
static bool SelectedItemHasTag(Character character, string tag) =>
|
||||
static bool SelectedItemHasTag(Character character, Identifier tag) =>
|
||||
(character.SelectedItem != null && character.SelectedItem.HasTag(tag)) ||
|
||||
(character.SelectedSecondaryItem != null && character.SelectedSecondaryItem.HasTag(tag));
|
||||
}
|
||||
|
||||
@@ -133,6 +133,14 @@ namespace Barotrauma
|
||||
|
||||
if (IsTalentLocked(talentIdentifier)) { return false; }
|
||||
|
||||
if (character.Info.GetUnlockedTalentsInTree().Contains(talentIdentifier))
|
||||
{
|
||||
//if the character already has the talent, it must be viable?
|
||||
//needed for backwards compatibility, otherwise if we remove e.g. a tier 1 or tier 2 talent,
|
||||
//all the already-unlocked higher-tier talents will be considered invalid which'll break the talent selection
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach (var subTree in talentTree!.TalentSubTrees)
|
||||
{
|
||||
if (subTree.AllTalentIdentifiers.Contains(talentIdentifier) && subTree.HasMaxTalents(selectedTalents)) { return false; }
|
||||
@@ -143,11 +151,12 @@ namespace Barotrauma
|
||||
{
|
||||
return !talentOptionStage.HasMaxTalents(selectedTalents) && TalentTreeMeetsRequirements(talentTree, subTree, selectedTalents);
|
||||
}
|
||||
//if a previous stage hasn't been completed, this talent can't be selected yet
|
||||
bool optionStageCompleted = talentOptionStage.HasEnoughTalents(selectedTalents);
|
||||
if (!optionStageCompleted)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user