Faction Test 100.4.0.0

This commit is contained in:
Markus Isberg
2022-11-14 18:28:28 +02:00
parent 87426b68b2
commit c772b61fc1
412 changed files with 16984 additions and 5530 deletions
@@ -138,7 +138,7 @@ namespace Barotrauma
private ConcurrentQueue<float> impactQueue;
//a dictionary containing lists of the status effects in all the components of the item
private readonly bool[] hasStatusEffectsOfType;
private readonly bool[] hasStatusEffectsOfType = new bool[Enum.GetValues(typeof(ActionType)).Length];
private readonly Dictionary<ActionType, List<StatusEffect>> statusEffectLists;
public Dictionary<Identifier, SerializableProperty> SerializableProperties { get; protected set; }
@@ -422,8 +422,41 @@ namespace Barotrauma
}
}
public Color? HighlightColor;
/// <summary>
/// Can be used by status effects or conditionals to check whether the item is contained inside something
/// </summary>
public bool IsContained
{
get
{
return parentInventory != null;
}
}
/// <summary>
/// Can be used by status effects or conditionals to the speed of the item
/// </summary>
public float Speed
{
get
{
if (body != null && body.PhysEnabled)
{
return body.LinearVelocity.Length();
}
else if (ParentInventory?.Owner is Character character)
{
return character.AnimController.MainLimb.LinearVelocity.Length();
}
else if (container != null)
{
return container.Speed;
}
return 0.0f;
}
}
public Color? HighlightColor;
[Serialize("", IsPropertySaveable.Yes)]
@@ -437,7 +470,8 @@ namespace Barotrauma
{
if (AiTarget != null)
{
AiTarget.SonarLabel = !string.IsNullOrEmpty(value) && value.Length > 200 ? value.Substring(200) : value;
string trimmedStr = !string.IsNullOrEmpty(value) && value.Length > 250 ? value.Substring(250) : value;
AiTarget.SonarLabel = TextManager.Get(trimmedStr).Fallback(trimmedStr);
}
}
}
@@ -597,7 +631,7 @@ namespace Barotrauma
{
if (!spawnedInCurrentOutpost && value)
{
OriginalOutpost = GameMain.GameSession?.StartLocation?.BaseName ?? "";
OriginalOutpost = GameMain.GameSession?.LevelData?.Seed;
}
spawnedInCurrentOutpost = value;
}
@@ -618,7 +652,9 @@ namespace Barotrauma
set
{
originalOutpost = value;
if (!string.IsNullOrEmpty(value) && GameMain.GameSession?.LevelData?.Type == LevelData.LevelType.Outpost && GameMain.GameSession?.StartLocation?.BaseName == value)
if (!string.IsNullOrEmpty(value) &&
GameMain.GameSession?.LevelData?.Type == LevelData.LevelType.Outpost &&
GameMain.GameSession?.LevelData?.Seed == value)
{
spawnedInCurrentOutpost = true;
}
@@ -821,6 +857,16 @@ namespace Barotrauma
public bool IsSecondaryItem { get; }
private ItemStatManager statManager;
public ItemStatManager StatManager
{
get
{
statManager ??= new ItemStatManager(this);
return statManager;
}
}
public Item(ItemPrefab itemPrefab, Vector2 position, Submarine submarine, ushort id = Entity.NullEntityID, bool callOnItemLoaded = true)
: this(new Rectangle(
(int)(position.X - itemPrefab.Sprite.size.X / 2 * itemPrefab.Scale),
@@ -900,7 +946,7 @@ namespace Barotrauma
{
if (!Physics.TryParseCollisionCategory(collisionCategoryStr, out Category cat))
{
DebugConsole.ThrowError("Invalid collision category in item \"" + Name+"\" (" + collisionCategoryStr + ")");
DebugConsole.ThrowError("Invalid collision category in item \"" + Name + "\" (" + collisionCategoryStr + ")");
}
else
{
@@ -962,7 +1008,6 @@ namespace Barotrauma
}
}
hasStatusEffectsOfType = new bool[Enum.GetValues(typeof(ActionType)).Length];
foreach (ItemComponent ic in components)
{
if (ic is Pickable pickable)
@@ -1611,7 +1656,7 @@ namespace Barotrauma
if (effect.HasTargetType(StatusEffect.TargetType.NearbyCharacters) || effect.HasTargetType(StatusEffect.TargetType.NearbyItems))
{
targets.AddRange(effect.GetNearbyTargets(WorldPosition, targets));
effect.AddNearbyTargets(WorldPosition, targets);
if (targets.Count > 0)
{
hasTargets = true;
@@ -1656,8 +1701,15 @@ namespace Barotrauma
{
targets.AddRange(character.AnimController.Limbs.ToList());
}
if (effect.HasTargetType(StatusEffect.TargetType.Limb) && limb == null && effect.targetLimbs != null)
{
foreach (var characterLimb in character.AnimController.Limbs)
{
if (effect.targetLimbs.Contains(characterLimb.type)) { targets.Add(characterLimb); }
}
}
}
if (effect.HasTargetType(StatusEffect.TargetType.Limb))
if (effect.HasTargetType(StatusEffect.TargetType.Limb) && limb != null)
{
targets.Add(limb);
}
@@ -1837,16 +1889,32 @@ namespace Barotrauma
if (ic.IsActiveConditionals != null)
{
bool shouldBeActive = true;
foreach (var conditional in ic.IsActiveConditionals)
if (ic.IsActiveConditionalComparison == PropertyConditional.Comparison.And)
{
if (!ConditionalMatches(conditional))
bool shouldBeActive = true;
foreach (var conditional in ic.IsActiveConditionals)
{
shouldBeActive = false;
break;
if (!ConditionalMatches(conditional))
{
shouldBeActive = false;
break;
}
}
ic.IsActive = shouldBeActive;
}
else
{
bool shouldBeActive = false;
foreach (var conditional in ic.IsActiveConditionals)
{
if (ConditionalMatches(conditional))
{
shouldBeActive = true;
break;
}
}
ic.IsActive = shouldBeActive;
}
ic.IsActive = shouldBeActive;
}
#if CLIENT
if (ic.HasSounds)
@@ -1892,7 +1960,10 @@ namespace Barotrauma
if (Math.Abs(body.LinearVelocity.X) > 0.01f || Math.Abs(body.LinearVelocity.Y) > 0.01f || transformDirty)
{
UpdateTransform();
if (body.CollisionCategories != Category.None)
{
UpdateTransform();
}
if (CurrentHull == null && Level.Loaded != null && body.SimPosition.Y < ConvertUnits.ToSimUnits(Level.MaxEntityDepth))
{
Spawner?.AddItemToRemoveQueue(this);
@@ -2072,7 +2143,7 @@ namespace Barotrauma
}
//no need to apply buoyancy if the item is still and not light enough to float
if (moving || body.Density < 10.0f)
if (moving || body.Density <= 10.0f)
{
Vector2 buoyancy = -GameMain.World.Gravity * forceFactor * volume * Physics.NeutralDensity;
body.ApplyForce(buoyancy);
@@ -2699,38 +2770,26 @@ namespace Barotrauma
}
#endif
float applyOnSelfFraction = user?.GetStatValue(StatTypes.ApplyTreatmentsOnSelfFraction) ?? 0.0f;
bool remove = false;
foreach (ItemComponent ic in components)
{
if (!ic.HasRequiredContainedItems(user, addMessage: user == Character.Controlled)) { continue; }
bool success = Rand.Range(0.0f, 0.5f) < ic.DegreeOfSuccess(user);
ActionType actionType = success ? ActionType.OnUse : ActionType.OnFailure;
ActionType conditionalActionType = success ? ActionType.OnSuccess : ActionType.OnFailure;
#if CLIENT
ic.PlaySound(actionType, user);
ic.PlaySound(conditionalActionType, user);
ic.PlaySound(ActionType.OnUse, user);
#endif
ic.WasUsed = true;
ic.ApplyStatusEffects(actionType, 1.0f, character, targetLimb, user: user, applyOnUserFraction: applyOnSelfFraction);
if (applyOnSelfFraction > 0.0f)
{
//hacky af
ic.statusEffectLists.TryGetValue(actionType, out var effectList);
if (effectList != null)
{
effectList.ForEach(e => e.AfflictionMultiplier = applyOnSelfFraction);
ic.ApplyStatusEffects(actionType, 1.0f, user, targetLimb == null ? null : user.AnimController.GetLimb(targetLimb.type), user: user);
effectList.ForEach(e => e.AfflictionMultiplier = 1.0f);
}
}
ic.ApplyStatusEffects(conditionalActionType, 1.0f, character, targetLimb, user: user);
ic.ApplyStatusEffects(ActionType.OnUse, 1.0f, character, targetLimb, user: user);
if (GameMain.NetworkMember is { IsServer: true })
{
GameMain.NetworkMember.CreateEntityEvent(this, new ApplyStatusEffectEventData(
actionType, ic, character, targetLimb));
GameMain.NetworkMember.CreateEntityEvent(this, new ApplyStatusEffectEventData(conditionalActionType, ic, character, targetLimb));
}
if (ic.DeleteOnUse) { remove = true; }
@@ -2866,15 +2925,20 @@ namespace Barotrauma
//to ensure client/server doesn't get any properties mixed up if there's some conditions that can vary between the server and the clients
var allProperties = inGameEditableOnly ? GetInGameEditableProperties(ignoreConditions: true) : GetProperties<Editable>();
SerializableProperty property = extraData.SerializableProperty;
ISerializableEntity entity = extraData.Entity;
if (property != null)
{
var propertyOwner = allProperties.Find(p => p.property == property);
if (allProperties.Count > 1)
{
msg.WriteByte((byte)allProperties.FindIndex(p => p.property == property));
int propertyIndex = allProperties.FindIndex(p => p.property == property && p.obj == entity);
if (propertyIndex < -1)
{
throw new Exception($"Could not find the property \"{property.Name}\" in \"{entity.Name ?? "null"}\"");
}
msg.WriteVariableUInt32((uint)propertyIndex);
}
object value = property.GetValue(propertyOwner.obj);
object value = property.GetValue(entity);
if (value is string stringVal)
{
msg.WriteString(stringVal);
@@ -2979,7 +3043,7 @@ namespace Barotrauma
int propertyIndex = 0;
if (allProperties.Count > 1)
{
propertyIndex = msg.ReadByte();
propertyIndex = (int)msg.ReadVariableUInt32();
}
bool allowEditing = true;
@@ -3119,14 +3183,14 @@ namespace Barotrauma
}
logPropertyChangeCoroutine = CoroutineManager.Invoke(() =>
{
GameServer.Log($"{sender.Character.Name} set the value \"{property.Name}\" of the item \"{Name}\" to \"{logValue}\".", ServerLog.MessageType.ItemInteraction);
GameServer.Log($"{sender.Character?.Name ?? sender.Name} set the value \"{property.Name}\" of the item \"{Name}\" to \"{logValue}\".", ServerLog.MessageType.ItemInteraction);
}, delay: 1.0f);
}
#endif
if (GameMain.NetworkMember is { IsServer: true })
if (GameMain.NetworkMember is { IsServer: true } && parentObject is ISerializableEntity entity)
{
GameMain.NetworkMember.CreateEntityEvent(this, new ChangePropertyEventData(property));
GameMain.NetworkMember.CreateEntityEvent(this, new ChangePropertyEventData(property, entity));
}
}
@@ -3230,7 +3294,7 @@ namespace Barotrauma
{
if (!(property.GetValue(item)?.Equals(prevValue) ?? true))
{
GameMain.NetworkMember.CreateEntityEvent(item, new ChangePropertyEventData(property));
GameMain.NetworkMember.CreateEntityEvent(item, new ChangePropertyEventData(property, item));
}
}
}
@@ -3349,12 +3413,6 @@ namespace Barotrauma
item.PurchasedNewSwap = false;
}
item.condition = element.GetAttributeFloat("condition", item.condition);
item.condition = MathHelper.Clamp(item.condition, 0, item.MaxCondition);
item.lastSentCondition = item.condition;
item.RecalculateConditionValues();
item.SetActiveSprite();
Version savedVersion = submarine?.Info.GameVersion;
if (element.Document?.Root != null && element.Document.Root.Name.ToString().Equals("gamesession", StringComparison.OrdinalIgnoreCase))
{
@@ -3362,14 +3420,38 @@ namespace Barotrauma
//(the sub may have already been saved and up-to-date, even though the character inventories aren't)
savedVersion = new Version(element.Document.Root.GetAttributeString("version", "0.0.0.0"));
}
float prevCondition = item.condition;
if (savedVersion != null)
{
SerializableProperty.UpgradeGameVersion(item, item.Prefab.ConfigElement, savedVersion);
}
if (element.GetAttribute("conditionpercentage") != null)
{
item.condition = element.GetAttributeFloat("conditionpercentage", 100.0f) / 100.0f * item.MaxCondition;
}
else
{
//backwards compatibility
item.condition = element.GetAttributeFloat("condition", item.condition);
//if the item was in full condition considering the unmodified health
//(not taking possible HealthMultipliers added by mods into account),
//make sure it stays in full condition
bool wasFullCondition = prevCondition >= item.Prefab.Health;
if (wasFullCondition)
{
item.condition = item.MaxCondition;
}
item.condition = MathHelper.Clamp(item.condition, 0, item.MaxCondition);
}
item.lastSentCondition = item.condition;
item.RecalculateConditionValues();
item.SetActiveSprite();
foreach (ItemComponent component in item.components)
{
if (component.Parent != null) { component.IsActive = component.Parent.IsActive; }
component.OnItemLoaded();
}
@@ -3401,11 +3483,6 @@ namespace Barotrauma
element.Add(new XAttribute("availableswaps", string.Join(',', AvailableSwaps.Select(s => s.Identifier))));
}
if (condition < MaxCondition)
{
element.Add(new XAttribute("condition", condition.ToString("G", CultureInfo.InvariantCulture)));
}
if (!MathUtils.NearlyEqual(healthMultiplier, 1.0f))
{
element.Add(new XAttribute("healthmultiplier", HealthMultiplier.ToString("G", CultureInfo.InvariantCulture)));
@@ -3442,6 +3519,16 @@ namespace Barotrauma
upgrade.Save(element);
}
if (condition < MaxCondition)
{
element.Add(new XAttribute("conditionpercentage", ConditionPercentage.ToString("G", CultureInfo.InvariantCulture)));
}
else
{
var conditionAttribute = element.GetAttribute("condition");
if (conditionAttribute != null) { conditionAttribute.Remove(); }
}
parentElement.Add(element);
return element;