(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
@@ -48,6 +48,7 @@ namespace Barotrauma.Items.Components
partial class ItemComponent : ISerializableEntity partial class ItemComponent : ISerializableEntity
{ {
private bool[] hasSoundsOfType;
private Dictionary<ActionType, List<ItemSound>> sounds; private Dictionary<ActionType, List<ItemSound>> sounds;
private Dictionary<ActionType, SoundSelectionMode> soundSelectionModes; private Dictionary<ActionType, SoundSelectionMode> soundSelectionModes;
@@ -183,6 +184,8 @@ namespace Barotrauma.Items.Components
private SoundChannel loopingSoundChannel; private SoundChannel loopingSoundChannel;
public void PlaySound(ActionType type, Vector2 position, Character user = null) public void PlaySound(ActionType type, Vector2 position, Character user = null)
{ {
if (!hasSoundsOfType[(int)type]) { return; }
if (loopingSound != null) if (loopingSound != null)
{ {
if (Vector3.DistanceSquared(GameMain.SoundManager.ListenerPosition, new Vector3(position.X, position.Y, 0.0f)) > loopingSound.Range * loopingSound.Range) if (Vector3.DistanceSquared(GameMain.SoundManager.ListenerPosition, new Vector3(position.X, position.Y, 0.0f)) > loopingSound.Range * loopingSound.Range)
@@ -225,9 +228,8 @@ namespace Barotrauma.Items.Components
return; return;
} }
if (!sounds.TryGetValue(type, out List<ItemSound> matchingSounds)) return;
ItemSound itemSound = null; ItemSound itemSound = null;
var matchingSounds = sounds[type];
if (loopingSoundChannel == null || !loopingSoundChannel.IsPlaying) if (loopingSoundChannel == null || !loopingSoundChannel.IsPlaying)
{ {
SoundSelectionMode soundSelectionMode = soundSelectionModes[type]; SoundSelectionMode soundSelectionMode = soundSelectionModes[type];
@@ -262,7 +264,7 @@ namespace Barotrauma.Items.Components
private void PlaySound(ItemSound itemSound, Vector2 position, Character user = null) 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; return;
} }
@@ -451,6 +453,7 @@ namespace Barotrauma.Items.Components
{ {
soundList = new List<ItemSound>(); soundList = new List<ItemSound>();
sounds.Add(itemSound.Type, soundList); sounds.Add(itemSound.Type, soundList);
hasSoundsOfType[(int)itemSound.Type] = true;
} }
soundList.Add(itemSound); soundList.Add(itemSound);
@@ -122,10 +122,12 @@ namespace Barotrauma.Items.Components
foreach (Item subItem in containedSubItems) foreach (Item subItem in containedSubItems)
{ {
projectile = subItem.GetComponent<Projectile>(); projectile = subItem.GetComponent<Projectile>();
//apply OnUse statuseffects to the container in case it has to react to it somehow //apply OnUse statuseffects to the container in case it has to react to it somehow
//(play a sound, spawn more projectiles, reduce condition...) //(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; if (projectile != null) break;
} }
} }
@@ -219,6 +219,7 @@ namespace Barotrauma.Items.Components
requiredSkills = new List<Skill>(); requiredSkills = new List<Skill>();
#if CLIENT #if CLIENT
hasSoundsOfType = new bool[Enum.GetValues(typeof(ActionType)).Length];
sounds = new Dictionary<ActionType, List<ItemSound>>(); sounds = new Dictionary<ActionType, List<ItemSound>>();
#endif #endif
@@ -133,6 +133,7 @@ namespace Barotrauma.Items.Components
set set
{ {
if (base.IsActive == value) { return; }
base.IsActive = value; base.IsActive = value;
#if CLIENT #if CLIENT
if (light == null) return; if (light == null) return;
@@ -76,6 +76,7 @@ namespace Barotrauma
private List<Repairable> repairables; private List<Repairable> repairables;
//a dictionary containing lists of the status effects in all the components of the item //a dictionary containing lists of the status effects in all the components of the item
private bool[] hasStatusEffectsOfType;
private Dictionary<ActionType, List<StatusEffect>> statusEffectLists; private Dictionary<ActionType, List<StatusEffect>> statusEffectLists;
public Dictionary<string, SerializableProperty> SerializableProperties { get; protected set; } 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) foreach (ItemComponent ic in components)
{ {
if (ic.statusEffectLists == null) continue; if (ic.statusEffectLists == null) continue;
if (statusEffectLists == null) if (statusEffectLists == null)
{
statusEffectLists = new Dictionary<ActionType, List<StatusEffect>>(); statusEffectLists = new Dictionary<ActionType, List<StatusEffect>>();
}
//go through all the status effects of the component //go through all the status effects of the component
//and add them to the corresponding statuseffect list //and add them to the corresponding statuseffect list
@@ -573,6 +577,7 @@ namespace Barotrauma
{ {
statusEffectList = new List<StatusEffect>(); statusEffectList = new List<StatusEffect>();
statusEffectLists.Add(actionType, statusEffectList); statusEffectLists.Add(actionType, statusEffectList);
hasStatusEffectsOfType[(int)actionType] = true;
} }
foreach (StatusEffect effect in componentEffectList) 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) public void ApplyStatusEffects(ActionType type, float deltaTime, Character character = null, Limb limb = null, bool isNetworkEvent = false)
{ {
if (statusEffectLists == null) return; if (!hasStatusEffectsOfType[(int)type]) { return; }
foreach (StatusEffect effect in statusEffectLists[type])
if (!statusEffectLists.TryGetValue(type, out List<StatusEffect> statusEffects)) return;
bool broken = condition <= 0.0f;
foreach (StatusEffect effect in statusEffects)
{ {
if (broken && effect.type != ActionType.OnBroken) continue;
ApplyStatusEffect(effect, type, deltaTime, character, limb, isNetworkEvent, false); ApplyStatusEffect(effect, type, deltaTime, character, limb, isNetworkEvent, false);
} }
} }
@@ -1047,6 +1047,8 @@ namespace Barotrauma
aiTarget.SoundRange -= deltaTime * 1000.0f; aiTarget.SoundRange -= deltaTime * 1000.0f;
} }
bool broken = condition <= 0.0f;
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer) if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
{ {
sendConditionUpdateTimer -= deltaTime; sendConditionUpdateTimer -= deltaTime;
@@ -1081,17 +1083,16 @@ namespace Barotrauma
if (!ic.IsActive) continue; if (!ic.IsActive) continue;
if (condition > 0.0f) if (broken)
{ {
ic.Update(deltaTime, cam); ic.UpdateBroken(deltaTime, cam);
#if CLIENT
if (ic.IsActive) ic.PlaySound(ActionType.OnActive, WorldPosition);
#endif
} }
else 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; container = container.Container;
} }
} }
if (!broken)
{
ApplyStatusEffects(!waterProof && inWater ? ActionType.InWater : ActionType.NotInWater, deltaTime);
}
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; } 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> /// <summary>
/// Applies buoyancy, drag and angular drag caused by water /// Applies buoyancy, drag and angular drag caused by water
/// </summary> /// </summary>
@@ -1202,7 +1231,7 @@ namespace Barotrauma
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return true; } 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); ApplyStatusEffects(ActionType.OnImpact, 1.0f);
#if SERVER #if SERVER