Build 0.20.8.0
This commit is contained in:
@@ -77,11 +77,11 @@ namespace Barotrauma
|
||||
{
|
||||
if (Level.Loaded.Type == LevelData.LevelType.LocationConnection)
|
||||
{
|
||||
if (Timing.TotalTime < GameMain.GameSession.RoundStartTime + 30.0f) { currentFlags.Add("Initial".ToIdentifier()); }
|
||||
if (GameMain.GameSession.RoundDuration > 30.0f) { currentFlags.Add("Initial".ToIdentifier()); }
|
||||
}
|
||||
else if (Level.Loaded.Type == LevelData.LevelType.Outpost)
|
||||
{
|
||||
if (Timing.TotalTime < GameMain.GameSession.RoundStartTime + 120.0f &&
|
||||
if (GameMain.GameSession.RoundDuration > 120.0f &&
|
||||
speaker?.CurrentHull != null &&
|
||||
(speaker.TeamID == CharacterTeamType.FriendlyNPC || speaker.TeamID == CharacterTeamType.None) &&
|
||||
Character.CharacterList.Any(c => c.TeamID != speaker.TeamID && c.CurrentHull == speaker.CurrentHull))
|
||||
|
||||
@@ -206,7 +206,7 @@ namespace Barotrauma
|
||||
public float Stun { get; private set; }
|
||||
|
||||
[Serialize(false, IsPropertySaveable.Yes, description: "Can damage only Humans."), Editable]
|
||||
public bool OnlyHumans { get; private set; }
|
||||
public bool OnlyHumans { get; set; }
|
||||
|
||||
[Serialize("", IsPropertySaveable.Yes), Editable]
|
||||
public string ApplyForceOnLimbs
|
||||
@@ -322,7 +322,7 @@ namespace Barotrauma
|
||||
List<Affliction> multipliedAfflictions = new List<Affliction>();
|
||||
foreach (Affliction affliction in Afflictions.Keys)
|
||||
{
|
||||
multipliedAfflictions.Add(affliction.CreateMultiplied(multiplier, affliction.Probability));
|
||||
multipliedAfflictions.Add(affliction.CreateMultiplied(multiplier, affliction));
|
||||
}
|
||||
return multipliedAfflictions;
|
||||
}
|
||||
|
||||
@@ -529,7 +529,7 @@ namespace Barotrauma
|
||||
private Color speechBubbleColor;
|
||||
private float speechBubbleTimer;
|
||||
|
||||
public bool ResetInteract;
|
||||
public bool DisableInteract { get; set; }
|
||||
|
||||
//text displayed when the character is highlighted if custom interact is set
|
||||
public LocalizedString CustomInteractHUDText { get; private set; }
|
||||
@@ -798,6 +798,7 @@ namespace Barotrauma
|
||||
public float MaxHealth => MaxVitality;
|
||||
public AIState AIState => AIController is EnemyAIController enemyAI ? enemyAI.State : AIState.Idle;
|
||||
public bool IsLatched => AIController is EnemyAIController enemyAI && enemyAI.LatchOntoAI != null && enemyAI.LatchOntoAI.IsAttached;
|
||||
public float EmpVulnerability => Params.Health.EmpVulnerability;
|
||||
|
||||
public float Bloodloss
|
||||
{
|
||||
@@ -845,6 +846,12 @@ namespace Barotrauma
|
||||
set;
|
||||
}
|
||||
|
||||
public bool IgnoreMeleeWeapons
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Current speed of the character's collider. Can be used by status effects to check if the character is moving.
|
||||
/// </summary>
|
||||
@@ -895,6 +902,10 @@ namespace Barotrauma
|
||||
{
|
||||
itemSelectedTime = Timing.TotalTime;
|
||||
}
|
||||
if (prevSelectedItem != _selectedItem && prevSelectedItem?.OnDeselect != null)
|
||||
{
|
||||
prevSelectedItem.OnDeselect(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
@@ -2687,9 +2698,9 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
|
||||
if (ResetInteract)
|
||||
if (DisableInteract)
|
||||
{
|
||||
ResetInteract = false;
|
||||
DisableInteract = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2710,25 +2721,31 @@ namespace Barotrauma
|
||||
{
|
||||
if (!IsMouseOnUI && (ViewTarget == null || ViewTarget == this))
|
||||
{
|
||||
if ((findFocusedTimer <= 0.0f || Screen.Selected == GameMain.SubEditorScreen) && (!PlayerInput.PrimaryMouseButtonHeld() || Barotrauma.Inventory.DraggingItemToWorld))
|
||||
if (findFocusedTimer <= 0.0f || Screen.Selected == GameMain.SubEditorScreen)
|
||||
{
|
||||
FocusedCharacter = CanInteract || CanEat ? FindCharacterAtPosition(mouseSimPos) : null;
|
||||
if (FocusedCharacter != null && !CanSeeCharacter(FocusedCharacter)) { FocusedCharacter = null; }
|
||||
float aimAssist = GameSettings.CurrentConfig.AimAssistAmount * (AnimController.InWater ? 1.5f : 1.0f);
|
||||
if (HeldItems.Any(it => it?.GetComponent<Wire>()?.IsActive ?? false))
|
||||
if (!PlayerInput.PrimaryMouseButtonHeld() || Barotrauma.Inventory.DraggingItemToWorld)
|
||||
{
|
||||
//disable aim assist when rewiring to make it harder to accidentally select items when adding wire nodes
|
||||
aimAssist = 0.0f;
|
||||
}
|
||||
FocusedCharacter = CanInteract || CanEat ? FindCharacterAtPosition(mouseSimPos) : null;
|
||||
if (FocusedCharacter != null && !CanSeeCharacter(FocusedCharacter)) { FocusedCharacter = null; }
|
||||
float aimAssist = GameSettings.CurrentConfig.AimAssistAmount * (AnimController.InWater ? 1.5f : 1.0f);
|
||||
if (HeldItems.Any(it => it?.GetComponent<Wire>()?.IsActive ?? false))
|
||||
{
|
||||
//disable aim assist when rewiring to make it harder to accidentally select items when adding wire nodes
|
||||
aimAssist = 0.0f;
|
||||
}
|
||||
|
||||
var item = FindItemAtPosition(mouseSimPos, aimAssist);
|
||||
|
||||
focusedItem = CanInteract ? item : null;
|
||||
if (focusedItem != null && focusedItem.CampaignInteractionType != CampaignMode.InteractionType.None)
|
||||
{
|
||||
FocusedCharacter = null;
|
||||
focusedItem = CanInteract ? FindItemAtPosition(mouseSimPos, aimAssist) : null;
|
||||
if (focusedItem != null && focusedItem.CampaignInteractionType != CampaignMode.InteractionType.None)
|
||||
{
|
||||
FocusedCharacter = null;
|
||||
}
|
||||
findFocusedTimer = 0.05f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (focusedItem != null && !CanInteractWith(focusedItem)) { focusedItem = null; }
|
||||
if (FocusedCharacter != null && !CanInteractWith(FocusedCharacter)) { FocusedCharacter = null; }
|
||||
}
|
||||
findFocusedTimer = 0.05f;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -2957,6 +2974,15 @@ namespace Barotrauma
|
||||
{
|
||||
UpdateProjSpecific(deltaTime, cam);
|
||||
|
||||
if (InvisibleTimer > 0.0f)
|
||||
{
|
||||
if (Controlled == null || Controlled == this || (Controlled.CharacterHealth.GetAffliction("psychosis")?.Strength ?? 0.0f) <= 0.0f)
|
||||
{
|
||||
InvisibleTimer = Math.Min(InvisibleTimer, 1.0f);
|
||||
}
|
||||
InvisibleTimer -= deltaTime;
|
||||
}
|
||||
|
||||
KnockbackCooldownTimer -= deltaTime;
|
||||
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient && this == Controlled && !isSynced) { return; }
|
||||
@@ -2996,6 +3022,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
HideFace = false;
|
||||
IgnoreMeleeWeapons = false;
|
||||
|
||||
UpdateSightRange(deltaTime);
|
||||
UpdateSoundRange(deltaTime);
|
||||
@@ -4102,7 +4129,13 @@ namespace Barotrauma
|
||||
{
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient && !isNetworkMessage) { return; }
|
||||
if (Screen.Selected != GameMain.GameScreen) { return; }
|
||||
if (newStun > 0 && Params.Health.StunImmunity) { return; }
|
||||
if (newStun > 0 && Params.Health.StunImmunity)
|
||||
{
|
||||
if (EmpVulnerability <= 0 || CharacterHealth.GetAfflictionStrength("emp", allowLimbAfflictions: false) <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ((newStun <= Stun && !allowStunDecrease) || !MathUtils.IsValid(newStun)) { return; }
|
||||
if (Math.Sign(newStun) != Math.Sign(Stun))
|
||||
{
|
||||
|
||||
@@ -1238,7 +1238,7 @@ namespace Barotrauma
|
||||
|
||||
partial void OnSkillChanged(Identifier skillIdentifier, float prevLevel, float newLevel);
|
||||
|
||||
public void GiveExperience(int amount, bool isMissionExperience = false)
|
||||
public void GiveExperience(int amount)
|
||||
{
|
||||
int prevAmount = ExperiencePoints;
|
||||
|
||||
@@ -1292,6 +1292,18 @@ namespace Barotrauma
|
||||
return experienceRequired + ExperienceRequiredPerLevel(level);
|
||||
}
|
||||
|
||||
public int GetExperienceRequiredForLevel(int level)
|
||||
{
|
||||
int currentLevel = GetCurrentLevel(out int experienceRequired);
|
||||
if (currentLevel >= level) { return 0; }
|
||||
int required = experienceRequired;
|
||||
for (int i = currentLevel + 1; i <= level; i++)
|
||||
{
|
||||
required += ExperienceRequiredPerLevel(i);
|
||||
}
|
||||
return required;
|
||||
}
|
||||
|
||||
public int GetCurrentLevel()
|
||||
{
|
||||
return GetCurrentLevel(out _);
|
||||
@@ -1309,7 +1321,7 @@ namespace Barotrauma
|
||||
return level;
|
||||
}
|
||||
|
||||
private int ExperienceRequiredPerLevel(int level)
|
||||
private static int ExperienceRequiredPerLevel(int level)
|
||||
{
|
||||
return BaseExperienceRequired + AddedExperienceRequiredPerLevel * level;
|
||||
}
|
||||
|
||||
+14
-2
@@ -61,6 +61,9 @@ namespace Barotrauma
|
||||
[Serialize(true, IsPropertySaveable.Yes, description: "Explosion damage is applied per each affected limb. Should this affliction damage be divided by the count of affected limbs (1-15) or applied in full? Default: true. Only affects explosions."), Editable]
|
||||
public bool DivideByLimbCount { get; set; }
|
||||
|
||||
[Serialize(false, IsPropertySaveable.Yes, description: "Is the damage relative to the max vitality (percentage) or absolute (normal)"), Editable]
|
||||
public bool MultiplyByMaxVitality { get; private set; }
|
||||
|
||||
public float DamagePerSecond;
|
||||
public float DamagePerSecondTimer;
|
||||
public float PreviousVitalityDecrease;
|
||||
@@ -104,6 +107,15 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy properties here instead of using SerializableProperties (with reflection).
|
||||
/// </summary>
|
||||
public void CopyProperties(Affliction source)
|
||||
{
|
||||
Probability = source.Probability;
|
||||
DivideByLimbCount = source.DivideByLimbCount;
|
||||
MultiplyByMaxVitality = source.MultiplyByMaxVitality;
|
||||
}
|
||||
|
||||
public void Serialize(XElement element)
|
||||
{
|
||||
@@ -115,10 +127,10 @@ namespace Barotrauma
|
||||
SerializableProperties = SerializableProperty.DeserializeProperties(this, element);
|
||||
}
|
||||
|
||||
public Affliction CreateMultiplied(float multiplier, float probability)
|
||||
public Affliction CreateMultiplied(float multiplier, Affliction affliction)
|
||||
{
|
||||
var instance = Prefab.Instantiate(NonClampedStrength * multiplier, Source);
|
||||
instance.Probability = probability;
|
||||
instance.CopyProperties(affliction);
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
@@ -693,8 +693,15 @@ namespace Barotrauma
|
||||
if (Character.Params.IsMachine && !newAffliction.Prefab.AffectMachines) { return; }
|
||||
if (!DoesBleed && newAffliction is AfflictionBleeding) { return; }
|
||||
if (!Character.NeedsOxygen && newAffliction.Prefab == AfflictionPrefab.OxygenLow) { return; }
|
||||
if (Character.Params.Health.StunImmunity && newAffliction.Prefab.AfflictionType == "stun") { return; }
|
||||
if (Character.Params.Health.StunImmunity && newAffliction.Prefab.AfflictionType == "stun")
|
||||
{
|
||||
if (Character.EmpVulnerability <= 0 || GetAfflictionStrength("emp", allowLimbAfflictions: false) <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (Character.Params.Health.PoisonImmunity && newAffliction.Prefab.AfflictionType == "poison") { return; }
|
||||
if (Character.EmpVulnerability <= 0 && newAffliction.Prefab.AfflictionType == "emp") { return; }
|
||||
if (newAffliction.Prefab is AfflictionPrefabHusk huskPrefab)
|
||||
{
|
||||
if (huskPrefab.TargetSpecies.None(s => s == Character.SpeciesName))
|
||||
|
||||
@@ -757,6 +757,10 @@ namespace Barotrauma
|
||||
}
|
||||
if (!foundMatchingModifier && random > affliction.Probability) { continue; }
|
||||
float finalDamageModifier = damageMultiplier;
|
||||
if (affliction.Prefab.AfflictionType == "emp" && character.EmpVulnerability > 0)
|
||||
{
|
||||
finalDamageModifier *= character.EmpVulnerability;
|
||||
}
|
||||
foreach (DamageModifier damageModifier in tempModifiers)
|
||||
{
|
||||
float damageModifierValue = damageModifier.DamageMultiplier;
|
||||
@@ -766,9 +770,13 @@ namespace Barotrauma
|
||||
}
|
||||
finalDamageModifier *= damageModifierValue;
|
||||
}
|
||||
if (affliction.MultiplyByMaxVitality)
|
||||
{
|
||||
finalDamageModifier *= character.MaxVitality / 100f;
|
||||
}
|
||||
if (!MathUtils.NearlyEqual(finalDamageModifier, 1.0f))
|
||||
{
|
||||
newAffliction = affliction.CreateMultiplied(finalDamageModifier, affliction.Probability);
|
||||
newAffliction = affliction.CreateMultiplied(finalDamageModifier, affliction);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -501,6 +501,9 @@ namespace Barotrauma
|
||||
[Serialize(false, IsPropertySaveable.Yes), Editable]
|
||||
public bool PoisonImmunity { get; set; }
|
||||
|
||||
[Serialize(0f, IsPropertySaveable.Yes), Editable]
|
||||
public float EmpVulnerability { get; set; }
|
||||
|
||||
[Serialize(false, IsPropertySaveable.Yes, description: "Can afflictions affect the face/body tint of the character."), Editable]
|
||||
public bool ApplyAfflictionColors { get; private set; }
|
||||
|
||||
|
||||
+9
-4
@@ -37,14 +37,19 @@ namespace Barotrauma.Abilities
|
||||
{
|
||||
if (GameMain.GameSession?.Campaign?.Factions is not { } factions) { return false; }
|
||||
|
||||
// FIXME there's probably a better way to check the faction affiliated with the mission later
|
||||
foreach (Identifier factionIdentifier in mission.ReputationRewards.Keys)
|
||||
foreach (var (factionIdentifier, amount) in mission.ReputationRewards)
|
||||
{
|
||||
if (factions.Where(faction => factionIdentifier == faction.Prefab.Identifier).Any(static faction => faction.GetPlayerAffiliationStatus() != FactionAffiliation.Affiliated))
|
||||
if (amount <= 0) { continue; }
|
||||
|
||||
Faction faction = factions.FirstOrDefault(faction => factionIdentifier == faction.Prefab.Identifier);
|
||||
|
||||
if (faction?.GetPlayerAffiliationStatus() is FactionAffiliation.Affiliated)
|
||||
{
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return missionType.Contains(mission.Prefab.Type);
|
||||
|
||||
+19
-1
@@ -5,15 +5,33 @@ internal sealed class CharacterAbilityGiveExperience : CharacterAbility
|
||||
public override bool AppliesEffectOnIntervalUpdate => true;
|
||||
|
||||
private readonly int amount;
|
||||
private readonly int level;
|
||||
|
||||
public CharacterAbilityGiveExperience(CharacterAbilityGroup characterAbilityGroup, ContentXElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
{
|
||||
amount = abilityElement.GetAttributeInt("amount", 0);
|
||||
level = abilityElement.GetAttributeInt("level", 0);
|
||||
|
||||
if (amount == 0 && level == 0)
|
||||
{
|
||||
DebugConsole.ThrowError($"Error in talent {CharacterTalent.DebugIdentifier} - no exp amount or level defined in {nameof(CharacterAbilityGiveExperience)}.");
|
||||
}
|
||||
if (amount > 0 && level > 0)
|
||||
{
|
||||
DebugConsole.ThrowError($"Error in talent {CharacterTalent.DebugIdentifier} - {nameof(CharacterAbilityGiveExperience)} defines both an exp amount and a level.");
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyEffectSpecific(Character targetCharacter)
|
||||
{
|
||||
targetCharacter.Info?.GiveExperience(amount);
|
||||
if (amount != 0)
|
||||
{
|
||||
targetCharacter.Info?.GiveExperience(amount);
|
||||
}
|
||||
if (level > 0)
|
||||
{
|
||||
targetCharacter.Info?.GiveExperience(targetCharacter.Info.GetExperienceRequiredForLevel(level));
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ApplyEffect(AbilityObject abilityObject)
|
||||
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
namespace Barotrauma.Abilities
|
||||
{
|
||||
class CharacterAbilityRevive : CharacterAbility
|
||||
{
|
||||
public override bool AppliesEffectOnIntervalUpdate => true;
|
||||
|
||||
public CharacterAbilityRevive(CharacterAbilityGroup characterAbilityGroup, ContentXElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
{
|
||||
}
|
||||
|
||||
private void ApplyEffectSpecific()
|
||||
{
|
||||
Character.Revive(removeAllAfflictions: false);
|
||||
}
|
||||
|
||||
protected override void ApplyEffect()
|
||||
{
|
||||
ApplyEffectSpecific();
|
||||
}
|
||||
|
||||
protected override void ApplyEffect(AbilityObject abilityObject)
|
||||
{
|
||||
ApplyEffectSpecific();
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-4
@@ -35,10 +35,8 @@ namespace Barotrauma.Abilities
|
||||
foreach (Identifier identifier in selectedTalentTree)
|
||||
{
|
||||
if (Character.HasTalent(identifier)) { continue; }
|
||||
if (Character.GiveTalent(identifier))
|
||||
{
|
||||
Character.Info.AdditionalTalentPoints++;
|
||||
}
|
||||
|
||||
Character.GiveTalent(identifier);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -139,23 +139,13 @@ namespace Barotrauma
|
||||
{
|
||||
if (talentOptionStage.TalentIdentifiers.Contains(talentIdentifier))
|
||||
{
|
||||
return TalentTreeMeetsRequirements(talentTree, subTree, selectedTalents);
|
||||
return !talentOptionStage.HasMaxTalents(selectedTalents) && TalentTreeMeetsRequirements(talentTree, subTree, selectedTalents);
|
||||
}
|
||||
bool optionStageCompleted = talentOptionStage.HasEnoughTalents(selectedTalents);
|
||||
if (!optionStageCompleted)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/*bool hasTalentInThisTier = talentOptionStage.HasMaxTalents(selectedTalents);
|
||||
if (!hasTalentInThisTier)
|
||||
{
|
||||
if (talentOptionStage.TalentIdentifiers.Contains(talentIdentifier))
|
||||
{
|
||||
return TalentTreeMeetsRequirements(talentTree, subTree, selectedTalents);
|
||||
}
|
||||
break;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user