low pass filter to sounds playing at distance, "armored" limbs, moved playing damagesounds from attack to IDamageable

This commit is contained in:
Regalis
2015-06-01 22:20:17 +03:00
parent 95c0d41023
commit 1f42e4a4db
32 changed files with 331 additions and 175 deletions

View File

@@ -654,10 +654,8 @@ namespace Subsurface
}
}
public void AddDamage(Vector2 position, float amount, float bleedingAmount, float stun)
public void AddDamage(Vector2 position, DamageType damageType, float amount, float bleedingAmount, float stun, bool playSound = false)
{
int bloodAmount = 0;
animController.StunTimer = Math.Max(animController.StunTimer, stun);
Limb closestLimb = null;
@@ -676,35 +674,9 @@ namespace Subsurface
if (pull != Vector2.Zero) pull = Vector2.Normalize(pull);
closestLimb.body.ApplyForce(pull*Math.Min(amount*100.0f, 100.0f));
closestLimb.Bleeding += bleedingAmount;
closestLimb.Damage += amount;
bloodAmount = (int)Math.Min((int)(amount*2.0f),20);
//if (closestLimb.Damage>=100.0f)
//{
// bloodAmount *= 2;
// foreach (var joint in animController.limbJoints)
// {
// if (!(joint.BodyA == closestLimb.body.FarseerBody) && !(joint.BodyB == closestLimb.body.FarseerBody)) continue;
// joint.Enabled = false;
// break;
// }
//}
for (int i = 0; i < bloodAmount; i++)
{
Vector2 particleVel = closestLimb.SimPosition-position;
if (particleVel != Vector2.Zero) particleVel = Vector2.Normalize(particleVel);
closestLimb.AddDamage(position, damageType, amount, bleedingAmount, playSound);
Game1.particleManager.CreateParticle("blood",
closestLimb.SimPosition,
particleVel * ToolBox.RandomFloat(1.0f,3.0f));
}
for (int i = 0; i < bloodAmount / 2; i++)
{
Game1.particleManager.CreateParticle("waterblood",closestLimb.SimPosition,Vector2.Zero);
}
}
public void Stun()

View File

@@ -41,12 +41,15 @@ namespace Subsurface
public readonly bool ignoreCollisions;
private float maxHealth;
private readonly float maxHealth;
private float damage;
private float bleeding;
public readonly float impactTolerance;
private readonly Vector2 armorSector;
private readonly float armorValue;
Sound hitSound;
//a timer for delaying when a hitsound/attacksound can be played again
public float soundTimer;
@@ -206,6 +209,12 @@ namespace Subsurface
steerForce = ToolBox.GetAttributeFloat(element, "steerforce", 0.0f);
maxHealth = Math.Max(ToolBox.GetAttributeFloat(element, "health", 100.0f),1.0f);
armorSector = ToolBox.GetAttributeVector2(element, "armorsector", Vector2.Zero);
armorSector.X = MathHelper.ToRadians(armorSector.X);
armorSector.Y = MathHelper.ToRadians(armorSector.Y);
armorValue = Math.Max(ToolBox.GetAttributeFloat(element, "armor", 1.0f), 1.0f);
body.BodyType = BodyType.Dynamic;
body.FarseerBody.AngularDamping = LimbAngularDamping;
@@ -248,6 +257,62 @@ namespace Subsurface
body.ApplyLinearImpulse((deltaPos - vel * 0.5f) * body.Mass, pullPos);
}
public void AddDamage(Vector2 position, DamageType damageType, float amount, float bleedingAmount, bool playSound)
{
DamageSoundType damageSoundType = (damageType == DamageType.Blunt) ? DamageSoundType.LimbBlunt : DamageSoundType.LimbSlash;
if (armorSector != Vector2.Zero)
{
float rot = body.Rotation;
if (Dir == -1) rot -= MathHelper.Pi;
Vector2 armorLimits = new Vector2(rot-armorSector.X*Dir, rot-armorSector.Y*Dir);
float mid = (armorLimits.X + armorLimits.Y) / 2.0f;
float angleDiff = ToolBox.GetShortestAngle(ToolBox.VectorToAngle(position - SimPosition), mid);
if (Math.Abs(angleDiff) < (armorSector.Y-armorSector.X) / 2.0f) return;
}
if (playSound)
{
AmbientSoundManager.PlayDamageSound(damageSoundType, amount, position);
}
Bleeding += bleedingAmount;
Damage += amount;
float bloodAmount = (int)Math.Min((int)(amount * 2.0f), 20);
//if (closestLimb.Damage>=100.0f)
//{
// bloodAmount *= 2;
// foreach (var joint in animController.limbJoints)
// {
// if (!(joint.BodyA == closestLimb.body.FarseerBody) && !(joint.BodyB == closestLimb.body.FarseerBody)) continue;
// joint.Enabled = false;
// break;
// }
//}
for (int i = 0; i < bloodAmount; i++)
{
Vector2 particleVel = SimPosition - position;
if (particleVel != Vector2.Zero) particleVel = Vector2.Normalize(particleVel);
Game1.particleManager.CreateParticle("blood",
SimPosition,
particleVel * ToolBox.RandomFloat(1.0f, 3.0f));
}
for (int i = 0; i < bloodAmount / 2; i++)
{
Game1.particleManager.CreateParticle("waterblood", SimPosition, Vector2.Zero);
}
}
public void Update(float deltaTime)
{
if (LinearVelocity.X>100.0f)

View File

@@ -8,11 +8,11 @@ using System.Xml.Linq;
namespace Subsurface
{
public enum DamageType { None, Blunt, Slash };
class Attack
{
public enum DamageType { None, Blunt, Slash };
public enum Type
{
@@ -70,26 +70,26 @@ namespace Subsurface
public void DoDamage(IDamageable target, Vector2 position, float deltaTime, bool playSound=true)
{
float damageAmount = 0.0f;
DamageSoundType damageSoundType = DamageSoundType.None;
//DamageSoundType damageSoundType = DamageSoundType.None;
if (target as Character == null)
{
damageAmount = structureDamage;
damageSoundType = (damageType == DamageType.Blunt) ? DamageSoundType.StructureBlunt: DamageSoundType.StructureSlash;
//damageSoundType = (damageType == DamageType.Blunt) ? DamageSoundType.StructureBlunt: DamageSoundType.StructureSlash;
}
else
{
damageAmount = damage;
damageSoundType = (damageType == DamageType.Blunt) ? DamageSoundType.LimbBlunt : DamageSoundType.LimbSlash;
//damageSoundType = (damageType == DamageType.Blunt) ? DamageSoundType.LimbBlunt : DamageSoundType.LimbSlash;
}
if (playSound) AmbientSoundManager.PlayDamageSound(damageSoundType, damageAmount, position);
//damageSoundType = (damageType == DamageType.Blunt) ? DamageSoundType.StructureBlunt : DamageSoundType.StructureSlash;
//if (playSound) AmbientSoundManager.PlayDamageSound(damageSoundType, damageAmount, position);
if (duration > 0.0f) damageAmount *= deltaTime;
float bleedingAmount = (duration == 0.0f) ? bleedingDamage : bleedingDamage * deltaTime;
if (damageAmount>0.0f) target.AddDamage(position, damageAmount, bleedingAmount, stun);
if (damageAmount>0.0f) target.AddDamage(position, damageType, damageAmount, bleedingAmount, stun, playSound);
}
}
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Xml.Linq;
@@ -9,6 +10,7 @@ namespace Subsurface
class StatusEffect
{
[Flags]
public enum Target
{
@@ -20,6 +22,8 @@ namespace Subsurface
public string[] propertyNames;
private object[] propertyEffects;
private bool disableDeltaTime;
private string[] onContainingNames;
@@ -60,7 +64,9 @@ namespace Subsurface
{
IEnumerable<XAttribute> attributes = element.Attributes();
List<XAttribute> propertyAttributes = new List<XAttribute>();
disableDeltaTime = ToolBox.GetAttributeBool(element, "disabledeltatime", false);
foreach (XAttribute attribute in attributes)
{
switch (attribute.Name.ToString())
@@ -179,13 +185,14 @@ namespace Subsurface
protected void ApplyToProperty(ObjectProperty property, object value, float deltaTime)
{
if (disableDeltaTime) deltaTime = 1.0f;
Type type = value.GetType();
if (type == typeof(float))
{
property.TrySetValue((float)property.GetValue() + (float)value * deltaTime);
}
if (type == typeof(int))
else if (type == typeof(int))
{
property.TrySetValue((int)property.GetValue() + (int)value * deltaTime);
}

View File

@@ -10,7 +10,7 @@
flip="true">
<!-- head -->
<limb id = "0" radius="22" height="45" mass = "6" type="Head" flip="true" steerforce="1.0">
<limb id = "0" radius="22" height="45" mass = "6" type="Head" flip="true" steerforce="1.0" armorsector="0.0,180.0">
<sprite texture="Content/Characters/Crawler/crawler.png" sourcerect="0,0,51,121" depth="0.02" origin="0.45,0.63"/>
</limb>

View File

@@ -11,7 +11,7 @@
<Wearable limbtype="Head" slots="Any,Head">
<sprite texture="DivingMask.png" limb="Head" sourcerect="1,1,37,38"/>
<StatusEffect type="OnWearing" target="Contained,Character" targetnames="Oxygen Tank" Condition="-0.25" Oxygen="20.0"/>
<StatusEffect type="OnWearing" target="Contained,Character" targetnames="Oxygen Tank" Condition="-0.7" Oxygen="20.0"/>
</Wearable>
<ItemContainer capacity="1" hideitems="true">
@@ -38,7 +38,7 @@
<sprite texture="DivingSuit.png" limb="RightArm" sourcerect="0,0,18,40" origin="0.5,0.4" depth="0.005"/>
<sprite texture="DivingSuit.png" limb="LeftArm" sourcerect="0,0,18,40" origin="0.5,0.4" depth="0.005"/>
<StatusEffect type="OnWearing" target="Contained,Character" targetnames="Oxygen Tank" Condition="-0.25" Oxygen="20.0"/>
<StatusEffect type="OnWearing" target="Contained,Character" targetnames="Oxygen Tank" Condition="-0.7" Oxygen="20.0"/>
<StatusEffect type="OnWearing" target="Character" PressureProtection="100.0"/>
</Wearable>

View File

@@ -6,7 +6,7 @@
<Sprite texture ="battery.png" depth="0.8"/>
<OxygenGenerator powerconsumption="2000.0" minvoltage="0.5" canbeselected = "true">
<StatusEffect type="OnActive" target="Contained" targetnames="Oxygen Tank" Condition="1.0"/>
<StatusEffect type="OnActive" target="Contained" targetnames="Oxygen Tank" Condition="2.0"/>
</OxygenGenerator>
<trigger/>

View File

Before

Width:  |  Height:  |  Size: 577 B

After

Width:  |  Height:  |  Size: 577 B

View File

Before

Width:  |  Height:  |  Size: 922 B

After

Width:  |  Height:  |  Size: 922 B

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB

View File

@@ -11,7 +11,7 @@
<Reactor canbeselected = "true">
<requireditem name="Fuel Rod" type="Contained"/>
<StatusEffect type="OnActive" target="Contained" targetnames="Fuel Rod, Heat Absorber, Temperature Control Circuit" Condition="-0.1" />
<StatusEffect type="OnContaining=Heat Absorber" target="This" ExtraCooling="500.0" />
<sound file="reactor.ogg" type="OnActive" range="1000.0"/>
</Reactor>
<ConnectionPanel canbeselected = "true">
@@ -20,7 +20,9 @@
</ConnectionPanel>
<ItemContainer capacity="5">
<Containable name="Fuel Rod"/>
<Containable name="Fuel Rod">
<StatusEffect type="OnContaining" target="This" AvailableFuel="2000.0" disabledeltatime="true"/>
</Containable>
<Containable name="Heat Absorber"/>
<Containable name="Temperature Control Circuit"/>
</ItemContainer>

View File

@@ -28,8 +28,8 @@
<Pickable slots="Any,BothHands"/>
<RangedWeapon barrelpos="49,10">
<Sound path="Content/Items/Weapons/harpoon1.ogg" type="OnUse"/>
<Sound path="Content/Items/Weapons/harpoon2.ogg" type="OnUse"/>
<Sound file="harpoon1.ogg" type="OnUse"/>
<Sound file="harpoon2.ogg" type="OnUse"/>
<RequiredItems name="Spear" type="Contained"/>
</RangedWeapon>

View File

@@ -10,7 +10,7 @@
<Turret barrelsprite="railgunbarrel.png" canbeselected = "true" linkable="true" origin="0.5, 0.85" barrelpos="117, 57"
rotationlimits="180,360"
powerconsumption="500.0">
<Sound path="Content/Items/railgun.ogg" type="OnUse"/>
<Sound file="railgun.ogg" type="OnUse"/>
</Turret>
</Item>

View File

@@ -110,7 +110,7 @@ namespace Subsurface.Items.Components
if (contained.body!=null) contained.body.Enabled = false;
RelatedItem ri = containableItems.Find(x => x.MatchesItem(item));
RelatedItem ri = containableItems.Find(x => x.MatchesItem(contained));
if (ri == null) continue;
foreach (StatusEffect effect in ri.statusEffects)

View File

@@ -9,19 +9,20 @@ using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Subsurface.Networking;
using Subsurface.Items.Components;
using System.IO;
namespace Subsurface
{
struct ItemSound
class ItemSound
{
public readonly byte index;
public readonly Sound sound;
public readonly ActionType type;
public readonly float range;
public ItemSound(int index, ActionType type, float range)
public ItemSound(Sound sound, ActionType type, float range)
{
this.index = (byte)index;
this.sound = sound;
this.type = type;
this.range = range;
}
@@ -150,10 +151,12 @@ namespace Subsurface
statusEffects.Add(StatusEffect.Load(subElement));
break;
case "sound":
string filePath = ToolBox.GetAttributeString(subElement, "path", "");
string filePath = ToolBox.GetAttributeString(subElement, "file", "");
if (filePath=="") continue;
if (!filePath.Contains("\\")) filePath = Path.GetDirectoryName(item.Prefab.ConfigFile)+"\\"+filePath;
//int index = item.Prefab.sounds.FindIndex(x => x.FilePath == filePath);
int index = item.Prefab.sounds.FindIndex(x => x.FilePath == filePath);
ActionType type;
@@ -167,34 +170,41 @@ namespace Subsurface
break;
}
Sound sound = Sound.Load(filePath);
float range = ToolBox.GetAttributeFloat(subElement, "range", 800.0f);
sounds.Add(new ItemSound(index, type, range));
sounds.Add(new ItemSound(sound, type, range));
break;
}
}
}
private ItemSound loopingSound;
private int loopingSoundIndex;
public void PlaySound(ActionType type, float volume, Vector2 position, bool loop=false)
{
if (loop && Sounds.SoundManager.IsPlaying(loopingSoundIndex)) return;
ItemSound itemSound = null;
if (!loop || !Sounds.SoundManager.IsPlaying(loopingSoundIndex))
{
List<ItemSound> matchingSounds = sounds.FindAll(x => x.type == type);
if (matchingSounds.Count == 0) return;
int index = Game1.localRandom.Next(matchingSounds.Count);
itemSound = sounds[index];
if (loop) loopingSound = itemSound;
}
List<ItemSound> matchingSounds = sounds.FindAll(x => x.type == type);
if (matchingSounds.Count == 0 || item.Prefab.sounds.Count == 0) return;
int index = Game1.localRandom.Next(Math.Min(matchingSounds.Count, item.Prefab.sounds.Count));
Sound sound = item.Prefab.sounds[matchingSounds[index].index];
if (loop)
{
loopingSoundIndex = sound.Loop(loopingSoundIndex, volume, position, matchingSounds[index].range);
loopingSoundIndex = loopingSound.sound.Loop(loopingSoundIndex, volume, position, loopingSound.range);
}
else
{
sound.Play(volume, matchingSounds[index].range, position);
itemSound.sound.Play(volume, itemSound.range, position);
}
}

View File

@@ -91,6 +91,8 @@ namespace Subsurface.Items.Components
public float ExtraCooling { get; set; }
public float AvailableFuel { get; set; }
public Reactor(Item item, XElement element)
: base(item, element)
{
@@ -109,6 +111,8 @@ namespace Subsurface.Items.Components
{
ApplyStatusEffects(ActionType.OnActive, deltaTime, null);
fissionRate = Math.Min(fissionRate, AvailableFuel);
float heat = 100 * fissionRate;
float heatDissipation = 50 * coolingRate + ExtraCooling;
@@ -157,6 +161,7 @@ namespace Subsurface.Items.Components
//fission rate can't be lowered below a certain amount if the core is too hot
FissionRate = Math.Max(fissionRate, heat / 200.0f);
//the power generated by the reactor is equal to the temperature
currPowerConsumption = -temperature*powerPerTemp;
@@ -169,6 +174,7 @@ namespace Subsurface.Items.Components
UpdateGraph(deltaTime);
ExtraCooling = 0.0f;
AvailableFuel = 0.0f;
}
public override void UpdateBroken(float deltaTime, Camera cam)

View File

@@ -334,16 +334,8 @@ namespace Subsurface.Items.Components
if (!mouseIn) return;
end = PlayerInput.MousePosition;
}
else if (draggingConnected == null)
{
if (Vector2.Distance(end, PlayerInput.MousePosition)<20.0f)
{
item.IsHighlighted = true;
//start dragging the wire
if (PlayerInput.LeftButtonDown()) draggingConnected = wireItem;
}
}
bool mouseOn = false;
int textX = (int)start.X;
float connLength = 10.0f;
@@ -358,9 +350,12 @@ namespace Subsurface.Items.Components
}
else
{
wireVertical.DrawTiled(spriteBatch,
new Vector2(start.X, end.Y + wireCorner.size.Y) - wireVertical.size / 2,
new Vector2(wireVertical.size.X, (float)Math.Abs((end.Y + wireCorner.size.Y) - start.Y)), Color.White);
Vector2 pos = new Vector2(start.X, end.Y + wireCorner.size.Y) - wireVertical.size / 2;
Vector2 size = new Vector2(wireVertical.size.X, (float)Math.Abs((end.Y + wireCorner.size.Y) - start.Y));
wireVertical.DrawTiled(spriteBatch, pos, size, Color.White);
Rectangle rect = new Rectangle((int)pos.X, (int)pos.Y, (int)size.X, (int)size.Y);
if (rect.Contains(PlayerInput.MousePosition)) mouseOn = true;
float dir = (end.X > start.X) ? -1.0f : 1.0f;
@@ -371,16 +366,29 @@ namespace Subsurface.Items.Components
float wireStartX = start.X - wireCorner.size.X / 2 * dir;
float wireEndX = end.X + connLength * dir;
wireHorizontal.DrawTiled(spriteBatch, new Vector2(Math.Min(wireStartX,wireEndX), end.Y - wireVertical.size.Y / 2),
new Vector2(Math.Abs(wireStartX - wireEndX), wireHorizontal.size.Y), Color.White);
pos = new Vector2(Math.Min(wireStartX,wireEndX), end.Y - wireVertical.size.Y / 2);
size = new Vector2(Math.Abs(wireStartX - wireEndX), wireHorizontal.size.Y);
wireHorizontal.DrawTiled(spriteBatch, pos, size, Color.White);
rect = new Rectangle((int)pos.X, (int)pos.Y, (int)size.X, (int)size.Y);
if (rect.Contains(PlayerInput.MousePosition)) mouseOn = true;
connector.Draw(spriteBatch, end, -MathHelper.PiOver2*dir);
}
if (draggingConnected == null)
{
if (mouseOn || Vector2.Distance(end, PlayerInput.MousePosition)<20.0f)
{
item.IsHighlighted = true;
//start dragging the wire
if (PlayerInput.LeftButtonDown()) draggingConnected = wireItem;
}
}
spriteBatch.DrawString(GUI.font, item.Name,
new Vector2(textX, start.Y-30),
Color.White,
mouseOn ? Color.Gold : Color.White,
MathHelper.PiOver2,
GUI.font.MeasureString(item.Name)*0.5f,
1.0f, SpriteEffects.None, 0.0f);

View File

@@ -17,8 +17,9 @@ namespace Subsurface.Items.Components
bool throwing;
[HasDefaultValue(1.0f, false)]
private float ThrowForce
public float ThrowForce
{
get { return throwForce; }
set { throwForce = value; }
}

View File

@@ -370,7 +370,7 @@ namespace Subsurface
}
public void AddDamage(Vector2 position, float amount, float bleedingAmount, float stun)
public void AddDamage(Vector2 position, DamageType damageType, float amount, float bleedingAmount, float stun, bool playSound = true)
{
Condition -= amount;
}
@@ -384,8 +384,7 @@ namespace Subsurface
if (condition > 0.0f)
{
ic.Update(deltaTime, cam);
ic.PlaySound(ActionType.OnActive, 1.0f, Position, true);
ic.ApplyStatusEffects(ActionType.OnActive, 1.0f, null);
}

View File

@@ -26,7 +26,7 @@ namespace Subsurface
float pickDistance;
public List<Sound> sounds;
//public List<Sound> sounds;
//an area next to the construction
//the construction can be Activated() by a character inside the area
@@ -201,16 +201,17 @@ namespace Subsurface
}
}
sounds = new List<Sound>();
var soundElements = element.Descendants("Sound");
foreach (XElement soundElement in soundElements)
{
string soundPath = ToolBox.GetAttributeString(soundElement, "path", "");
if (soundPath == "") continue;
//sounds = new List<Sound>();
//var soundElements = element.Descendants();
//foreach (XElement soundElement in soundElements)
//{
// if (soundElement.Name.ToString().ToLower() != "sound") continue;
// string soundPath = ToolBox.GetAttributeString(soundElement, "path", "");
// if (soundPath == "") continue;
Sound sound = Sound.Load(soundPath);
if (sound != null) sounds.Add(sound);
}
// Sound sound = Sound.Load(soundPath);
// if (sound != null) sounds.Add(sound);
//}
list.Add(this);
}

View File

@@ -97,7 +97,7 @@ namespace Subsurface
{
distFactor = 1.0f - Vector2.Distance(limb.SimPosition, position)/range;
c.AddDamage(limb.SimPosition, damage * distFactor, 0.0f, stun * distFactor);
c.AddDamage(limb.SimPosition, DamageType.None, damage * distFactor, 0.0f, stun * distFactor);
if (force>0.0f)
{

View File

@@ -214,24 +214,13 @@ namespace Subsurface
soundVolume = soundVolume + ((flowForce.Length() < 100.0f) ? -deltaTime * 0.5f : deltaTime * 0.5f);
soundVolume = MathHelper.Clamp(soundVolume, 0.0f, 1.0f);
//if (soundVolume < 0.01f)
//{
// if (soundIndex > -1)
// {
// Sound.Stop(soundIndex);
// soundIndex = -1;
// }
int index = (int)Math.Floor(flowForce.Length() / 100.0f);
index = Math.Min(index,2);
//}
//else
{
int index = (int)Math.Floor(flowForce.Length() / 100.0f);
index = Math.Min(index,2);
soundIndex = AmbientSoundManager.flowSounds[index].Loop(soundIndex, soundVolume, Position, 2000.0f);
//soundVolume = Math.Max(0.0f, soundVolume-deltaTime);
//Sound.UpdatePosition(soundIndex, Position, 2000.0f);
}
soundIndex = AmbientSoundManager.flowSounds[index].Loop(soundIndex, soundVolume, Position, 2000.0f);
//soundVolume = Math.Max(0.0f, soundVolume-deltaTime);
//Sound.UpdatePosition(soundIndex, Position, 2000.0f);
flowForce = Vector2.Zero;
@@ -386,7 +375,7 @@ namespace Subsurface
{
float delta = Math.Min(hull2.Volume - hull2.FullVolume + Hull.MaxCompress / 2.0f, deltaTime * 8000.0f * sizeModifier);
flowForce = new Vector2(0.0f, Math.Min(hull2.Pressure-hull1.Pressure,500.0f));
flowForce = new Vector2(0.0f, Math.Min(hull2.Pressure - hull1.Pressure, 500.0f));
delta = Math.Max(delta, 0.0f);
hull1.Volume += delta;
@@ -444,6 +433,7 @@ namespace Subsurface
//}
}
}
if (open > 0.0f)
{
if (hull1.Volume>hull1.FullVolume && hull2.Volume>hull2.FullVolume)
@@ -458,9 +448,6 @@ namespace Subsurface
hull2.LethalPressure = 0.0f;
}
}
}
void UpdateRoomToOut(float deltaTime)
@@ -526,7 +513,7 @@ namespace Subsurface
}
else
{
flowForce = new Vector2(0.0f,delta);
flowForce = new Vector2(0.0f, delta);
}
}
}
@@ -539,9 +526,9 @@ namespace Subsurface
float totalOxygen = hull1.Oxygen + hull2.Oxygen;
float totalVolume = (hull1.FullVolume + hull2.FullVolume);
hull1.Oxygen += Math.Sign(totalOxygen*hull1.FullVolume/(totalVolume) - hull1.Oxygen) * Hull.OxygenDistributionSpeed;
hull2.Oxygen += Math.Sign(totalOxygen*hull2.FullVolume/(totalVolume) - hull2.Oxygen) * Hull.OxygenDistributionSpeed;
hull1.Oxygen += Math.Sign(totalOxygen * hull1.FullVolume / (totalVolume) - hull1.Oxygen) * Hull.OxygenDistributionSpeed;
hull2.Oxygen += Math.Sign(totalOxygen * hull2.FullVolume / (totalVolume) - hull2.Oxygen) * Hull.OxygenDistributionSpeed;
}
public override void Remove()

View File

@@ -14,6 +14,6 @@ namespace Subsurface
get;
}
void AddDamage(Vector2 position, float amount, float bleedingAmount, float stun);
void AddDamage(Vector2 position, DamageType damageType, float amount, float bleedingAmount, float stun, bool playSound=true);
}
}

View File

@@ -378,7 +378,7 @@ namespace Subsurface
sections[sectionIndex].rect.Y - sections[sectionIndex].rect.Height / 2.0f);
}
public void AddDamage(Vector2 position, float amount, float bleedingAmount, float stun)
public void AddDamage(Vector2 position, DamageType damageType, float amount, float bleedingAmount, float stun, bool playSound = false)
{
if (!prefab.HasBody || prefab.IsPlatform) return;
@@ -387,6 +387,11 @@ namespace Subsurface
Game1.particleManager.CreateParticle("dustcloud", ConvertUnits.ToSimUnits(SectionPosition(i)), 0.0f, 0.0f);
if (playSound)
{
DamageSoundType damageSoundType = (damageType == DamageType.Blunt) ? DamageSoundType.StructureBlunt : DamageSoundType.StructureSlash;
AmbientSoundManager.PlayDamageSound(damageSoundType, amount, position);
}
AddDamage(i, amount);
}

View File

@@ -72,58 +72,74 @@ namespace Subsurface
return SoundManager.Play(this, volume);
}
public int Play(float volume, float range, Vector2 position)
public int Play(float baseVolume, float range, Vector2 position)
{
//position = new Vector2(position.X - CameraPos.X, position.Y - CameraPos.Y);
//volume = (range == 0.0f) ? 0.0f : MathHelper.Clamp(volume * (range - position.Length())/range, 0.0f, 1.0f);
int newIndex = SoundManager.Play(this, volume);
Vector2 relativePos = GetRelativePosition(position);
float volume = GetVolume(relativePos, range, baseVolume);
if (newIndex == -1) return -1;
return SoundManager.Play(this, relativePos, volume, volume);
return UpdatePosition(newIndex, position, range, volume);
//if (newIndex == -1) return -1;
//return UpdatePosition(newIndex, position, range, volume);
}
public int Play(float volume, float range, Body body)
{
Vector2 bodyPosition = ConvertUnits.ToDisplayUnits(body.Position);
//Vector2 bodyPosition = ConvertUnits.ToDisplayUnits(body.Position);
//bodyPosition.Y = -bodyPosition.Y;
return Play(volume, range, bodyPosition);
return Play(volume, range, ConvertUnits.ToDisplayUnits(body.Position));
}
public static int UpdatePosition(int sourceIndex, Vector2 position, float range, float baseVolume = 1.0f)
private float GetVolume(Vector2 relativePosition, float range, float baseVolume)
{
position = new Vector2(position.X - CameraPos.X, position.Y - CameraPos.Y);
float volume = (range == 0.0f) ? 0.0f : MathHelper.Clamp(baseVolume * (range - position.Length())/range, 0.0f, 1.0f);
float volume = (range == 0.0f) ? 0.0f : MathHelper.Clamp(baseVolume * (range - relativePosition.Length()) / range, 0.0f, 1.0f);
if (volume <= 0.0f)
{
if (sourceIndex > 0)
{
SoundManager.Stop(sourceIndex);
sourceIndex = -1;
}
return sourceIndex;
}
SoundManager.UpdateSoundPosition(sourceIndex, position, volume);
return sourceIndex;
return volume;
}
public int UpdatePosition(int sourceIndex, Body body, float range, float baseVolume = 1.0f)
private Vector2 GetRelativePosition(Vector2 position)
{
Vector2 bodyPosition = ConvertUnits.ToDisplayUnits(body.Position);
bodyPosition.Y = -bodyPosition.Y;
return UpdatePosition(sourceIndex, bodyPosition, range, baseVolume);
return new Vector2(position.X - CameraPos.X, position.Y - CameraPos.Y);
}
//public static int UpdatePosition(int sourceIndex, Vector2 position, float range, float baseVolume = 1.0f)
//{
// position = new Vector2(position.X - CameraPos.X, position.Y - CameraPos.Y);
// float volume = (range == 0.0f) ? 0.0f : MathHelper.Clamp(baseVolume * (range - position.Length())/range, 0.0f, 1.0f);
// if (volume <= 0.0f)
// {
// if (sourceIndex > 0)
// {
// SoundManager.Stop(sourceIndex);
// sourceIndex = -1;
// }
// return sourceIndex;
// }
// SoundManager.UpdateSoundPosition(sourceIndex, position, volume, volume);
// return sourceIndex;
//}
//public int UpdatePosition(int sourceIndex, Body body, float range, float baseVolume = 1.0f)
//{
// Vector2 bodyPosition = ConvertUnits.ToDisplayUnits(body.Position);
// bodyPosition.Y = -bodyPosition.Y;
// return UpdatePosition(sourceIndex, bodyPosition, range, baseVolume);
//}
public int Loop(int sourceIndex, float volume)
{
if (volume == 0.0f)
if (volume <= 0.0f)
{
if (sourceIndex > 0)
{
@@ -139,8 +155,12 @@ namespace Subsurface
return newIndex;
}
public int Loop(int sourceIndex, float volume, Vector2 position, float range)
public int Loop(int sourceIndex, float baseVolume, Vector2 position, float range)
{
Vector2 relativePos = GetRelativePosition(position);
float volume = GetVolume(relativePos, range, baseVolume);
if (volume <= 0.0f)
{
if (sourceIndex > 0)
@@ -152,9 +172,11 @@ namespace Subsurface
return sourceIndex;
}
int newIndex = SoundManager.Loop(this, sourceIndex, volume);
return UpdatePosition(newIndex, position, range, volume);
return SoundManager.Loop(this, sourceIndex, position, volume, volume);
//return UpdatePosition(newIndex, position, range, volume);
}

View File

@@ -3,6 +3,7 @@ using System.Diagnostics;
using Microsoft.Xna.Framework;
using OpenTK.Audio;
using OpenTK.Audio.OpenAL;
using System;
namespace Subsurface.Sounds
{
@@ -13,8 +14,15 @@ namespace Subsurface.Sounds
private static List<int> alSources = new List<int>();
private static int[] alBuffers = new int[DefaultSourceCount];
private static int lowpassFilterId;
private static float overrideLowPassGain;
public static float OverrideLowPassGain
{
get { return overrideLowPassGain; }
set { overrideLowPassGain = MathHelper.Clamp(overrideLowPassGain, 0.0f, 1.0f); }
}
static AudioContext AC;
public static OggStreamer oggStreamer;
@@ -34,7 +42,7 @@ namespace Subsurface.Sounds
lowpassFilterId = ALHelper.Efx.GenFilter();
//alFilters.Add(alFilterId);
ALHelper.Efx.Filter(lowpassFilterId, EfxFilteri.FilterType, (int)EfxFilterType.Lowpass);
//LowPassHFGain = 1;
}
@@ -72,6 +80,7 @@ namespace Subsurface.Sounds
public static int Play(Sound sound, float volume = 1.0f)
{
return Play(sound, Vector2.Zero, volume, 0.0f);
//for (int i = 2; i < DefaultSourceCount; i++)
//{
// AL.SourceStop(alSources[i]);
@@ -80,6 +89,43 @@ namespace Subsurface.Sounds
// System.Diagnostics.Debug.WriteLine(AL.GetSourceType(alSources[i]));
//}
//for (int i = 1; i < DefaultSourceCount; i++)
//{
// //find a source that's free to use (not playing or paused)
// if (AL.GetSourceState(alSources[i]) == ALSourceState.Playing
// || AL.GetSourceState(alSources[i]) == ALSourceState.Paused) continue;
// //if (position!=Vector2.Zero)
// // position /= 1000.0f;
// alBuffers[i]=sound.AlBufferId;
// AL.Source(alSources[i], ALSourceb.Looping, false);
// AL.Source(alSources[i], ALSource3f.Position, 0.0f, 0.0f, 0.0f);
// AL.Source(alSources[i], ALSourcei.Buffer, sound.AlBufferId);
// AL.Source(alSources[i], ALSourcef.Gain, volume);
// //AL.Source(alSources[i], ALSource3f.Position, position.X, position.Y, 0.0f);
// AL.SourcePlay(alSources[i]);
// //sound.sourceIndex = i;
// return i;
//}
//return -1;
}
public static int Play(Sound sound, Vector2 position, float volume = 1.0f, float lowPassGain = 0.0f)
{
//for (int i = 2; i < DefaultSourceCount; i++)
//{
// AL.SourceStop(alSources[i]);
// AL.Source(alSources[i], ALSourceb.Looping, false);
// System.Diagnostics.Debug.WriteLine(i + ": " + AL.GetSourceState(alSources[i]));
// System.Diagnostics.Debug.WriteLine(AL.GetSourceType(alSources[i]));
//}
for (int i = 1; i < DefaultSourceCount; i++)
{
//find a source that's free to use (not playing or paused)
@@ -89,11 +135,21 @@ namespace Subsurface.Sounds
//if (position!=Vector2.Zero)
// position /= 1000.0f;
alBuffers[i]=sound.AlBufferId;
alBuffers[i] = sound.AlBufferId;
AL.Source(alSources[i], ALSourceb.Looping, false);
AL.Source(alSources[i], ALSource3f.Position, 0.0f, 0.0f, 0.0f);
AL.Source(alSources[i], ALSourcei.Buffer, sound.AlBufferId);
position /= 1000.0f;
//System.Diagnostics.Debug.WriteLine("updatesoundpos: "+offset);
AL.Source(alSources[i], ALSourcef.Gain, volume);
AL.Source(alSources[i], ALSource3f.Position, position.X, position.Y, 0.0f);
AL.Source(alSources[i], ALSourcei.Buffer, sound.AlBufferId);
ALHelper.Efx.Filter(lowpassFilterId, EfxFilterf.LowpassGainHF, lowPassHfGain = Math.Min(lowPassGain, overrideLowPassGain));
ALHelper.Efx.BindFilterToSource(alSources[i], lowpassFilterId);
ALHelper.Check();
//AL.Source(alSources[i], ALSource3f.Position, position.X, position.Y, 0.0f);
AL.SourcePlay(alSources[i]);
@@ -105,22 +161,28 @@ namespace Subsurface.Sounds
return -1;
}
public static int Loop(Sound sound, int sourceIndex, float volume)
public static int Loop(Sound sound, int sourceIndex, float volume = 1.0f)
{
return Loop(sound,sourceIndex, Vector2.Zero, volume, 0.0f);
}
public static int Loop(Sound sound, int sourceIndex, Vector2 position, float volume = 1.0f, float lowPassGain = 0.0f)
{
if (sourceIndex<1)
{
sourceIndex = Play(sound, volume);
sourceIndex = Play(sound, position, volume, lowPassGain);
if (sourceIndex>0)
{
AL.Source(alSources[sourceIndex], ALSourceb.Looping, true);
AL.Source(alSources[sourceIndex], ALSourcef.Gain, volume);
}
ALHelper.Check();
return sourceIndex;
}
else
{
AL.Source(alSources[sourceIndex], ALSourceb.Looping, true);
AL.Source(alSources[sourceIndex], ALSourcef.Gain, volume);
ALHelper.Check();
return sourceIndex;
}
}
@@ -195,6 +257,7 @@ namespace Subsurface.Sounds
{
if (ALHelper.Efx.IsInitialized)
{
overrideLowPassGain = value;
for (int i = 0; i < DefaultSourceCount; i++)
{
//find a source that's free to use (not playing or paused)
@@ -221,17 +284,21 @@ namespace Subsurface.Sounds
// }
//}
public static void UpdateSoundPosition(int sourceIndex, Vector2 position, float baseVolume = 1.0f)
public static void UpdateSoundPosition(int sourceIndex, Vector2 position, float baseVolume = 1.0f, float lowPassGain = 0.0f)
{
if (sourceIndex < 1) return;
//Resume(sourceIndex);
position/= 1000.0f;
//System.Diagnostics.Debug.WriteLine("updatesoundpos: "+offset);
AL.Source(alSources[sourceIndex], ALSourcef.Gain, baseVolume);
AL.Source(alSources[sourceIndex], ALSource3f.Position, position.X, position.Y, 0.0f);
ALHelper.Efx.Filter(lowpassFilterId, EfxFilterf.LowpassGainHF, lowPassHfGain = Math.Min(lowPassGain, overrideLowPassGain));
ALHelper.Efx.BindFilterToSource(alSources[sourceIndex], lowpassFilterId);
ALHelper.Check();
}
public static OggStream StartStream(string file, float volume = 1.0f)

View File

@@ -350,7 +350,7 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<SubType>Designer</SubType>
</Content>
<Content Include="Content\Items\fuelrod.png">
<Content Include="Content\Items\Reactor\fuelrod.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Items\idcard.xml">
@@ -368,7 +368,7 @@
<Content Include="Content\Items\Weapons\harpoongun.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Items\heatabsorber.png">
<Content Include="Content\Items\Reactor\heatabsorber.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Items\Diving\divinggear.xml">
@@ -426,10 +426,10 @@
<Content Include="Content\Items\railgunshell.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Items\reactor.png">
<Content Include="Content\Items\Reactor\reactor.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Items\reactor.xml">
<Content Include="Content\Items\Reactor\reactor.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<SubType>Designer</SubType>
</Content>
@@ -549,6 +549,9 @@
<None Include="Content\effects.mgfx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Content\Items\Reactor\reactor.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Content\Items\Weapons\harpoon1.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>

View File

@@ -9,6 +9,6 @@
<ErrorReportUrlHistory />
<FallbackCulture>en-US</FallbackCulture>
<VerifyUploadedFiles>false</VerifyUploadedFiles>
<ProjectView>ShowAllFiles</ProjectView>
<ProjectView>ProjectFiles</ProjectView>
</PropertyGroup>
</Project>

View File

@@ -200,8 +200,12 @@ namespace Subsurface
public static object GetAttributeObject(XAttribute attribute)
{
if (attribute == null) return null;
string value = attribute.Value.ToString();
return ParseToObject(attribute.Value.ToString());
}
public static object ParseToObject(string value)
{
float floatVal;
int intVal;
if (value.ToString().Contains(".") && float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out floatVal))

View File

@@ -166,7 +166,4 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(Performance) = preSolution
HasPerformanceSessions = true
EndGlobalSection
EndGlobal

Binary file not shown.