(7e43eae73) Optimized Item.ApplyStatusEffects & ItemComponent.PlaySound: check if the item has effects/sounds of the correct type from a bool array instead of doing a dictionary lookup. A small thing, but the methods are called so frequently that it adds up to a lot.

This commit is contained in:
Joonas Rikkonen
2019-04-18 12:05:11 +03:00
parent 1a3184dbad
commit b0580a9050
5 changed files with 57 additions and 21 deletions

View File

@@ -48,6 +48,7 @@ namespace Barotrauma.Items.Components
partial class ItemComponent : ISerializableEntity
{
private bool[] hasSoundsOfType;
private Dictionary<ActionType, List<ItemSound>> sounds;
private Dictionary<ActionType, SoundSelectionMode> soundSelectionModes;
@@ -183,6 +184,8 @@ namespace Barotrauma.Items.Components
private SoundChannel loopingSoundChannel;
public void PlaySound(ActionType type, Vector2 position, Character user = null)
{
if (!hasSoundsOfType[(int)type]) { return; }
if (loopingSound != null)
{
if (Vector3.DistanceSquared(GameMain.SoundManager.ListenerPosition, new Vector3(position.X, position.Y, 0.0f)) > loopingSound.Range * loopingSound.Range)
@@ -224,10 +227,9 @@ namespace Barotrauma.Items.Components
}
return;
}
if (!sounds.TryGetValue(type, out List<ItemSound> matchingSounds)) return;
ItemSound itemSound = null;
var matchingSounds = sounds[type];
if (loopingSoundChannel == null || !loopingSoundChannel.IsPlaying)
{
SoundSelectionMode soundSelectionMode = soundSelectionModes[type];
@@ -262,7 +264,7 @@ namespace Barotrauma.Items.Components
private void PlaySound(ItemSound itemSound, Vector2 position, Character user = null)
{
if (Vector3.DistanceSquared(GameMain.SoundManager.ListenerPosition, new Vector3(position.X, position.Y, 0.0f)) > itemSound.Range * itemSound.Range)
if (Vector2.DistanceSquared(new Vector2(GameMain.SoundManager.ListenerPosition.X, GameMain.SoundManager.ListenerPosition.Y), position) > itemSound.Range * itemSound.Range)
{
return;
}
@@ -451,6 +453,7 @@ namespace Barotrauma.Items.Components
{
soundList = new List<ItemSound>();
sounds.Add(itemSound.Type, soundList);
hasSoundsOfType[(int)itemSound.Type] = true;
}
soundList.Add(itemSound);

View File

@@ -122,10 +122,12 @@ namespace Barotrauma.Items.Components
foreach (Item subItem in containedSubItems)
{
projectile = subItem.GetComponent<Projectile>();
//apply OnUse statuseffects to the container in case it has to react to it somehow
//(play a sound, spawn more projectiles, reduce condition...)
subItem.GetComponent<ItemContainer>()?.Item.ApplyStatusEffects(ActionType.OnUse, deltaTime);
if (subItem.Condition > 0.0f)
{
subItem.GetComponent<ItemContainer>()?.Item.ApplyStatusEffects(ActionType.OnUse, deltaTime);
}
if (projectile != null) break;
}
}

View File

@@ -219,6 +219,7 @@ namespace Barotrauma.Items.Components
requiredSkills = new List<Skill>();
#if CLIENT
hasSoundsOfType = new bool[Enum.GetValues(typeof(ActionType)).Length];
sounds = new Dictionary<ActionType, List<ItemSound>>();
#endif

View File

@@ -133,6 +133,7 @@ namespace Barotrauma.Items.Components
set
{
if (base.IsActive == value) { return; }
base.IsActive = value;
#if CLIENT
if (light == null) return;

View File

@@ -76,6 +76,7 @@ namespace Barotrauma
private List<Repairable> repairables;
//a dictionary containing lists of the status effects in all the components of the item
private bool[] hasStatusEffectsOfType;
private Dictionary<ActionType, List<StatusEffect>> statusEffectLists;
public Dictionary<string, SerializableProperty> SerializableProperties { get; protected set; }
@@ -557,12 +558,15 @@ namespace Barotrauma
}
}
hasStatusEffectsOfType = new bool[Enum.GetValues(typeof(ActionType)).Length];
foreach (ItemComponent ic in components)
{
if (ic.statusEffectLists == null) continue;
if (statusEffectLists == null)
{
statusEffectLists = new Dictionary<ActionType, List<StatusEffect>>();
}
//go through all the status effects of the component
//and add them to the corresponding statuseffect list
@@ -573,6 +577,7 @@ namespace Barotrauma
{
statusEffectList = new List<StatusEffect>();
statusEffectLists.Add(actionType, statusEffectList);
hasStatusEffectsOfType[(int)actionType] = true;
}
foreach (StatusEffect effect in componentEffectList)
@@ -923,14 +928,9 @@ namespace Barotrauma
public void ApplyStatusEffects(ActionType type, float deltaTime, Character character = null, Limb limb = null, bool isNetworkEvent = false)
{
if (statusEffectLists == null) return;
if (!statusEffectLists.TryGetValue(type, out List<StatusEffect> statusEffects)) return;
bool broken = condition <= 0.0f;
foreach (StatusEffect effect in statusEffects)
if (!hasStatusEffectsOfType[(int)type]) { return; }
foreach (StatusEffect effect in statusEffectLists[type])
{
if (broken && effect.type != ActionType.OnBroken) continue;
ApplyStatusEffect(effect, type, deltaTime, character, limb, isNetworkEvent, false);
}
}
@@ -1047,6 +1047,8 @@ namespace Barotrauma
aiTarget.SoundRange -= deltaTime * 1000.0f;
}
bool broken = condition <= 0.0f;
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
{
sendConditionUpdateTimer -= deltaTime;
@@ -1081,17 +1083,16 @@ namespace Barotrauma
if (!ic.IsActive) continue;
if (condition > 0.0f)
if (broken)
{
ic.Update(deltaTime, cam);
#if CLIENT
if (ic.IsActive) ic.PlaySound(ActionType.OnActive, WorldPosition);
#endif
ic.UpdateBroken(deltaTime, cam);
}
else
{
ic.UpdateBroken(deltaTime, cam);
ic.Update(deltaTime, cam);
#if CLIENT
if (ic.IsActive) ic.PlaySound(ActionType.OnActive, WorldPosition);
#endif
}
}
@@ -1123,6 +1124,10 @@ namespace Barotrauma
container = container.Container;
}
}
if (!broken)
{
ApplyStatusEffects(!waterProof && inWater ? ActionType.InWater : ActionType.NotInWater, deltaTime);
}
ApplyStatusEffects(!waterProof && inWater ? ActionType.InWater : ActionType.NotInWater, deltaTime);
if (body == null || !body.Enabled || !inWater || ParentInventory != null || Removed) { return; }
@@ -1159,6 +1164,30 @@ namespace Barotrauma
}
}
FindHull();
if (Submarine == null && prevSub != null)
{
body.SetTransform(body.SimPosition + prevSub.SimPosition, body.Rotation);
}
else if (Submarine != null && prevSub == null)
{
body.SetTransform(body.SimPosition - Submarine.SimPosition, body.Rotation);
}
Vector2 displayPos = ConvertUnits.ToDisplayUnits(body.SimPosition);
rect.X = (int)(displayPos.X - rect.Width / 2.0f);
rect.Y = (int)(displayPos.Y + rect.Height / 2.0f);
if (Math.Abs(body.LinearVelocity.X) > NetConfig.MaxPhysicsBodyVelocity ||
Math.Abs(body.LinearVelocity.Y) > NetConfig.MaxPhysicsBodyVelocity)
{
body.LinearVelocity = new Vector2(
MathHelper.Clamp(body.LinearVelocity.X, -NetConfig.MaxPhysicsBodyVelocity, NetConfig.MaxPhysicsBodyVelocity),
MathHelper.Clamp(body.LinearVelocity.Y, -NetConfig.MaxPhysicsBodyVelocity, NetConfig.MaxPhysicsBodyVelocity));
}
}
/// <summary>
/// Applies buoyancy, drag and angular drag caused by water
/// </summary>
@@ -1202,7 +1231,7 @@ namespace Barotrauma
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return true; }
if (ImpactTolerance > 0.0f && impact > ImpactTolerance)
if (ImpactTolerance > 0.0f && condition > 0.0f && impact > ImpactTolerance)
{
ApplyStatusEffects(ActionType.OnImpact, 1.0f);
#if SERVER