0.1500.3.0 (🗿 edition)

This commit is contained in:
Markus Isberg
2021-09-17 22:47:21 +09:00
parent 1231170fce
commit 5a6bbcc79e
75 changed files with 1145 additions and 441 deletions
@@ -60,7 +60,6 @@ namespace Barotrauma.Items.Components
}
}
public GeneticMaterial(Item item, XElement element)
: base(item, element)
{
@@ -85,7 +84,7 @@ namespace Barotrauma.Items.Components
public bool CanBeCombinedWith(GeneticMaterial otherGeneticMaterial)
{
return !tainted && otherGeneticMaterial != null && !otherGeneticMaterial.tainted;
return !tainted && otherGeneticMaterial != null && !otherGeneticMaterial.tainted && item.AllowDeconstruct && otherGeneticMaterial.item.AllowDeconstruct;
}
public override void Equip(Character character)
@@ -147,9 +146,12 @@ namespace Barotrauma.Items.Components
public bool Combine(GeneticMaterial otherGeneticMaterial, Character user)
{
if (!CanBeCombinedWith(otherGeneticMaterial)) { return false; }
float conditionIncrease = Rand.Range(ConditionIncreaseOnCombineMin, ConditionIncreaseOnCombineMax);
conditionIncrease *= 1.0f + user.GetStatValue(StatTypes.GeneticMaterialRefineBonus);
if (item.Prefab == otherGeneticMaterial.item.Prefab)
{
item.Condition = Math.Max(item.Condition, otherGeneticMaterial.item.Condition) + Rand.Range(ConditionIncreaseOnCombineMin, ConditionIncreaseOnCombineMax);
item.Condition = Math.Max(item.Condition, otherGeneticMaterial.item.Condition) + conditionIncrease;
float taintedProbability = GetTaintedProbabilityOnRefine(user);
if (taintedProbability >= Rand.Range(0.0f, 1.0f))
{
@@ -160,9 +162,14 @@ namespace Barotrauma.Items.Components
else
{
item.Condition = otherGeneticMaterial.Item.Condition =
(item.Condition + otherGeneticMaterial.Item.Condition) / 2.0f + Rand.Range(ConditionIncreaseOnCombineMin, ConditionIncreaseOnCombineMax);
(item.Condition + otherGeneticMaterial.Item.Condition) / 2.0f + conditionIncrease;
item.OwnInventory?.TryPutItem(otherGeneticMaterial.Item, user: null);
MakeTainted();
item.AllowDeconstruct = false;
otherGeneticMaterial.Item.AllowDeconstruct = false;
if (GetTaintedProbabilityOnCombine(user) >= Rand.Range(0.0f, 1.0f))
{
MakeTainted();
}
return false;
}
}
@@ -172,7 +179,14 @@ namespace Barotrauma.Items.Components
if (user == null) { return 1.0f; }
float probability = MathHelper.Lerp(0.0f, 0.99f, item.Condition / 100.0f);
probability *= MathHelper.Lerp(1.0f, 0.25f, DegreeOfSuccess(user));
return probability;
return MathHelper.Clamp(probability, 0.0f, 1.0f);
}
private float GetTaintedProbabilityOnCombine(Character user)
{
if (user == null) { return 1.0f; }
float probability = 1.0f - user.GetStatValue(StatTypes.GeneticMaterialTaintedProbabilityReductionOnCombine);
return MathHelper.Clamp(probability, 0.0f, 1.0f);
}
private void MakeTainted()
@@ -1,4 +1,5 @@
using Barotrauma.Networking;
using Barotrauma.Abilities;
using Barotrauma.Networking;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
@@ -73,12 +74,15 @@ namespace Barotrauma.Items.Components
if (PickingTime > 0.0f)
{
var abilityPickingTime = new AbilityValueItem(PickingTime, item.Prefab);
picker.CheckTalents(AbilityEffectType.OnItemPicked, abilityPickingTime);
if ((picker.PickingItem == null || picker.PickingItem == item) && PickingTime <= float.MaxValue)
{
#if SERVER
item.CreateServerEvent(this);
#endif
pickingCoroutine = CoroutineManager.StartCoroutine(WaitForPick(picker, PickingTime));
pickingCoroutine = CoroutineManager.StartCoroutine(WaitForPick(picker, abilityPickingTime.Value));
}
return false;
}
@@ -523,7 +523,20 @@ namespace Barotrauma.Items.Components
ApplyStatusEffectsOnTarget(user, deltaTime, ActionType.OnUse, new ISerializableEntity[] { targetStructure });
FixStructureProjSpecific(user, deltaTime, targetStructure, sectionIndex);
targetStructure.AddDamage(sectionIndex, -StructureFixAmount * degreeOfSuccess, user);
float structureFixAmount = StructureFixAmount;
if (structureFixAmount >= 0f)
{
structureFixAmount *= 1 + user.GetStatValue(StatTypes.RepairToolStructureRepairMultiplier);
structureFixAmount *= 1 + item.GetQualityModifier(Quality.StatType.RepairToolStructureRepairMultiplier);
}
else
{
structureFixAmount *= 1 + user.GetStatValue(StatTypes.RepairToolStructureDamageMultiplier);
structureFixAmount *= 1 + item.GetQualityModifier(Quality.StatType.RepairToolStructureDamageMultiplier);
}
targetStructure.AddDamage(sectionIndex, -structureFixAmount * degreeOfSuccess, user);
//if the next section is small enough, apply the effect to it as well
//(to make it easier to fix a small "left-over" section)
@@ -535,7 +548,7 @@ namespace Barotrauma.Items.Components
(nextSectionLength > 0 && nextSectionLength < Structure.WallSectionSize * 0.3f))
{
//targetStructure.HighLightSection(sectionIndex + i);
targetStructure.AddDamage(sectionIndex + i, -StructureFixAmount * degreeOfSuccess);
targetStructure.AddDamage(sectionIndex + i, -structureFixAmount * degreeOfSuccess);
}
}
return true;
@@ -606,7 +619,8 @@ namespace Barotrauma.Items.Components
levelResource.requiredItems.Any() &&
levelResource.HasRequiredItems(user, addMessage: false))
{
levelResource.DeattachTimer += deltaTime;
float addedDetachTime = deltaTime * (1f + user.GetStatValue(StatTypes.RepairToolDeattachTimeMultiplier)) * item.GetQualityModifier(Quality.StatType.RepairToolDeattachTimeMultiplier);
levelResource.DeattachTimer += addedDetachTime;
#if CLIENT
Character.Controlled?.UpdateHUDProgressBar(
this,
@@ -61,7 +61,7 @@ namespace Barotrauma.Items.Components
public int Capacity
{
get { return capacity; }
set { capacity = Math.Max(value, 1); }
set { capacity = Math.Max(value, 0); }
}
//how many items can be contained
@@ -86,15 +86,9 @@ namespace Barotrauma.Items.Components
}
}
#if DEBUG
[Editable]
#endif
[Serialize("0.0,0.0", false, description: "The position where the contained items get drawn at (offset from the upper left corner of the sprite in pixels).")]
public Vector2 ItemPos { get; set; }
#if DEBUG
[Editable]
#endif
[Serialize("0.0,0.0", false, description: "The interval at which the contained items are spaced apart from each other (in pixels).")]
public Vector2 ItemInterval { get; set; }
@@ -329,11 +323,24 @@ namespace Barotrauma.Items.Components
{
return slotRestrictions.Any(s => s.MatchesItem(item));
}
public bool CanBeContained(Item item, int index)
{
if (index < 0 || index >= capacity) { return false; }
return slotRestrictions[index].MatchesItem(item);
}
public bool CanBeContained(ItemPrefab itemPrefab)
{
return slotRestrictions.Any(s => s.MatchesItem(itemPrefab));
}
public bool CanBeContained(ItemPrefab itemPrefab, int index)
{
if (index < 0 || index >= capacity) { return false; }
return slotRestrictions[index].MatchesItem(itemPrefab);
}
readonly List<ISerializableEntity> targets = new List<ISerializableEntity>();
public override void Update(float deltaTime, Camera cam)
@@ -256,6 +256,17 @@ namespace Barotrauma.Items.Components
}
}
if (user != null && !user.Removed)
{
var deconstructItemRetainProbability = new AbilityValueItem(0f, targetItem.Prefab);
user.CheckTalents(AbilityEffectType.OnItemDeconstructedRetainProbability, deconstructItemRetainProbability);
if (deconstructItemRetainProbability.Value > Rand.Range(0f, 1f, Rand.RandSync.Unsynced))
{
allowRemove = false;
}
}
if (targetItem.AllowDeconstruct && allowRemove)
{
//drop all items that are inside the deconstructed item
@@ -24,12 +24,6 @@ namespace Barotrauma.Items.Components
private Character user;
public float FabricationSpeedMultiplier
{
get;
set;
}
private ItemContainer inputContainer, outputContainer;
[Serialize(1.0f, true)]
@@ -249,7 +243,6 @@ namespace Barotrauma.Items.Components
var availableIngredients = GetAvailableIngredients();
if (fabricatedItem == null || !CanBeFabricated(fabricatedItem, availableIngredients, user))
{
FabricationSpeedMultiplier = 1f;
CancelFabricating();
return;
}
@@ -286,8 +279,7 @@ namespace Barotrauma.Items.Components
if (powerConsumption <= 0) { Voltage = 1.0f; }
timeUntilReady -= deltaTime * Math.Min(Voltage, 1.0f) * FabricationSpeedMultiplier;
FabricationSpeedMultiplier = 1f;
timeUntilReady -= deltaTime * Math.Min(Voltage, 1.0f);
UpdateRequiredTimeProjSpecific();
@@ -328,13 +320,21 @@ namespace Barotrauma.Items.Components
var fabricationValueItem = new AbilityValueItem(fabricatedItem.Amount, fabricatedItem.TargetItem);
if (user != null)
int quality = 0;
if (user?.Info != null)
{
foreach (Character character in Character.CharacterList.Where(c => c.TeamID == user.TeamID))
{
character.CheckTalents(AbilityEffectType.OnAllyItemFabricatedAmount, fabricationValueItem);
}
user.CheckTalents(AbilityEffectType.OnItemFabricatedAmount, fabricationValueItem);
float floatQuality = 0.0f;
foreach (string tag in fabricatedItem.TargetItem.Tags)
{
floatQuality += user.Info.GetSavedStatValue(StatTypes.IncreaseFabricationQuality, tag);
}
quality = (int)floatQuality;
}
var tempUser = user;
@@ -343,12 +343,20 @@ namespace Barotrauma.Items.Components
if (i < amountFittingContainer)
{
Entity.Spawner.AddToSpawnQueue(fabricatedItem.TargetItem, outputContainer.Inventory, fabricatedItem.TargetItem.Health * fabricatedItem.OutCondition,
onSpawned: (Item spawnedItem) => { onItemSpawned(spawnedItem, tempUser); });
onSpawned: (Item spawnedItem) =>
{
onItemSpawned(spawnedItem, tempUser);
spawnedItem.Quality = quality;
});
}
else
{
Entity.Spawner.AddToSpawnQueue(fabricatedItem.TargetItem, item.Position, item.Submarine, fabricatedItem.TargetItem.Health * fabricatedItem.OutCondition,
onSpawned: (Item spawnedItem) => { onItemSpawned(spawnedItem, tempUser); });
onSpawned: (Item spawnedItem) =>
{
onItemSpawned(spawnedItem, tempUser);
spawnedItem.Quality = quality;
});
}
}
@@ -116,6 +116,8 @@ namespace Barotrauma.Items.Components
item.CurrentHull.WaterVolume += currFlow;
if (item.CurrentHull.WaterVolume > item.CurrentHull.Volume) { item.CurrentHull.Pressure += 0.5f; }
Voltage -= deltaTime;
}
public void InfectBallast(string identifier, bool allowMultiplePerShip = false)
@@ -0,0 +1,72 @@
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Xml.Linq;
namespace Barotrauma.Items.Components
{
partial class Quality : ItemComponent
{
public const int MaxQuality = 3;
public enum StatType
{
Condition,
ExplosionRadius,
ExplosionDamage,
RepairSpeed,
RepairToolStructureRepairMultiplier,
RepairToolStructureDamageMultiplier,
RepairToolDeattachTimeMultiplier,
// unused as of now
AttackMultiplier,
AttackSpeedMultiplier,
ForceDoorsOpenSpeedMultiplier,
RangedSpreadReduction,
ChargeSpeedMultiplier,
MovementSpeedMultiplier,
// generic stats to be used for various needs, declared just in case (localization)
EffectivenessMultiplier,
PowerOutputMultiplier,
ConsumptionReductionMultiplier,
}
private readonly Dictionary<StatType, float> statValues = new Dictionary<StatType, float>();
private int qualityLevel;
[Serialize(0, false)]
public int QualityLevel
{
get { return qualityLevel; }
set { qualityLevel = MathHelper.Clamp(value, 0, MaxQuality); }
}
public Quality(Item item, XElement element) : base(item, element)
{
foreach (XElement subElement in element.Elements())
{
switch (subElement.Name.ToString().ToLower())
{
case "stattype":
case "statvalue":
case "qualitystat":
string statTypeString = subElement.GetAttributeString("stattype", "");
if (!Enum.TryParse(statTypeString, true, out StatType statType))
{
DebugConsole.ThrowError("Invalid stat type type \"" + statTypeString + "\" in item (" + item.prefab.Identifier + ")");
}
float statValue = subElement.GetAttributeFloat("value", 0f);
statValues.TryAdd(statType, statValue);
break;
}
}
}
public float GetValue(StatType statType)
{
if (!statValues.ContainsKey(statType)) { return 0.0f; }
return statValues[statType] * qualityLevel;
}
}
}
@@ -35,6 +35,7 @@ namespace Barotrauma.Items.Components
public RemoteController(Item item, XElement element)
: base(item, element)
{
DrawHudWhenEquipped = false;
}
public override bool Select(Character character)
@@ -11,7 +11,7 @@ namespace Barotrauma.Items.Components
{
partial class Repairable : ItemComponent, IServerSerializable, IClientSerializable
{
private string header;
private readonly string header;
private float deteriorationTimer;
private float deteriorateAlwaysResetTimer;
@@ -182,6 +182,10 @@ namespace Barotrauma.Items.Components
if (Rand.Range(0.0f, 0.5f) < RepairDegreeOfSuccess(character, requiredSkills)) { return true; }
ApplyStatusEffects(ActionType.OnFailure, 1.0f, character);
if (bestRepairItem != null && bestRepairItem.GetComponent<Holdable>() is Holdable h)
{
h.ApplyStatusEffects(ActionType.OnFailure, 1.0f, character);
}
return false;
}
@@ -217,6 +221,11 @@ namespace Barotrauma.Items.Components
{
GameServer.Log($"{GameServer.CharacterLogName(character)} failed to {(action == FixActions.Sabotage ? "sabotage" : "repair")} {item.Name}", ServerLog.MessageType.ItemInteraction);
GameMain.Server?.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.ApplyStatusEffect, ActionType.OnFailure, this, character.ID });
if (bestRepairItem != null && bestRepairItem.GetComponent<Holdable>() is Holdable h)
{
GameMain.Server?.CreateEntityEvent(bestRepairItem, new object[] { NetEntityEvent.Type.ApplyStatusEffect, ActionType.OnFailure, h, character.ID });
}
return false;
}
@@ -243,7 +252,7 @@ namespace Barotrauma.Items.Components
}
return true;
Item GetBestRepairItem(Character character)
static Item GetBestRepairItem(Character character)
{
return character.HeldItems.OrderByDescending(i => i.Prefab.AddedRepairSpeedMultiplier).FirstOrDefault();
}
@@ -386,6 +395,9 @@ namespace Barotrauma.Items.Components
float fixDuration = MathHelper.Lerp(FixDurationLowSkill, FixDurationHighSkill, successFactor);
fixDuration /= 1 + CurrentFixer.GetStatValue(StatTypes.RepairSpeed) + currentRepairItem?.Prefab.AddedRepairSpeedMultiplier ?? 0f;
fixDuration /= 1 + item.GetQualityModifier(Quality.StatType.RepairSpeed);
item.MaxRepairConditionMultiplier = 1 + CurrentFixer.GetStatValue(StatTypes.MaxRepairConditionMultiplier);
if (currentFixerAction == FixActions.Repair)
{
@@ -383,6 +383,10 @@ namespace Barotrauma.Items.Components
else
{
float chargeDeltaTime = tryingToCharge ? deltaTime : -deltaTime;
if (chargeDeltaTime > 0f && user != null)
{
chargeDeltaTime *= 1f + user.GetStatValue(StatTypes.TurretChargeSpeed);
}
currentChargeTime = Math.Clamp(currentChargeTime + chargeDeltaTime, 0f, MaxChargeTime);
}
tryingToCharge = false;
@@ -285,7 +285,7 @@ namespace Barotrauma.Items.Components
int i = 0;
foreach (XElement subElement in element.Elements())
{
switch (subElement.Name.ToString().ToLower())
switch (subElement.Name.ToString().ToLowerInvariant())
{
case "sprite":
if (subElement.Attribute("texture") == null)