diff --git a/Subsurface/Content/Items/Engine/engine.xml b/Subsurface/Content/Items/Engine/engine.xml
index 3ae2f1d81..f71d89bee 100644
--- a/Subsurface/Content/Items/Engine/engine.xml
+++ b/Subsurface/Content/Items/Engine/engine.xml
@@ -1,31 +1,31 @@
- -
+
-
-
+
-
-
-
-
-
-
+
+
+
+
+
+
- -
+
-
-
+
@@ -38,12 +38,12 @@
-
-
+
+
-
-
-
-
-
+
+
+
+
+
\ No newline at end of file
diff --git a/Subsurface/Content/Items/Reactor/reactor.xml b/Subsurface/Content/Items/Reactor/reactor.xml
index 306b9b1f0..761987246 100644
--- a/Subsurface/Content/Items/Reactor/reactor.xml
+++ b/Subsurface/Content/Items/Reactor/reactor.xml
@@ -27,7 +27,7 @@
-
+
diff --git a/Subsurface/Content/Items/Tools/tools.xml b/Subsurface/Content/Items/Tools/tools.xml
index de8247a95..3edec139d 100644
--- a/Subsurface/Content/Items/Tools/tools.xml
+++ b/Subsurface/Content/Items/Tools/tools.xml
@@ -34,7 +34,7 @@
-
+
@@ -74,7 +74,7 @@
-
+
diff --git a/Subsurface/Content/Items/Weapons/explosives.xml b/Subsurface/Content/Items/Weapons/explosives.xml
index bcf007454..f23a12245 100644
--- a/Subsurface/Content/Items/Weapons/explosives.xml
+++ b/Subsurface/Content/Items/Weapons/explosives.xml
@@ -12,7 +12,7 @@
-
+
diff --git a/Subsurface/Content/Items/Weapons/railgun.xml b/Subsurface/Content/Items/Weapons/railgun.xml
index 02b90a194..474b461c4 100644
--- a/Subsurface/Content/Items/Weapons/railgun.xml
+++ b/Subsurface/Content/Items/Weapons/railgun.xml
@@ -12,7 +12,7 @@
rotationlimits="180,360"
powerconsumption="500.0">
-
+
diff --git a/Subsurface/Content/Items/Weapons/weapons.xml b/Subsurface/Content/Items/Weapons/weapons.xml
index a20e0ff6d..22e44c66d 100644
--- a/Subsurface/Content/Items/Weapons/weapons.xml
+++ b/Subsurface/Content/Items/Weapons/weapons.xml
@@ -51,7 +51,7 @@
-
+
diff --git a/Subsurface/Content/Sounds/Water/WaterAmbience.ogg b/Subsurface/Content/Sounds/Water/WaterAmbience1.ogg
similarity index 100%
rename from Subsurface/Content/Sounds/Water/WaterAmbience.ogg
rename to Subsurface/Content/Sounds/Water/WaterAmbience1.ogg
diff --git a/Subsurface/Content/Sounds/Water/WaterAmbience2.ogg b/Subsurface/Content/Sounds/Water/WaterAmbience2.ogg
new file mode 100644
index 000000000..ba4ba86ba
Binary files /dev/null and b/Subsurface/Content/Sounds/Water/WaterAmbience2.ogg differ
diff --git a/Subsurface/Source/Characters/AI/AIController.cs b/Subsurface/Source/Characters/AI/AIController.cs
index 07e36afe7..577f51a56 100644
--- a/Subsurface/Source/Characters/AI/AIController.cs
+++ b/Subsurface/Source/Characters/AI/AIController.cs
@@ -44,6 +44,8 @@ namespace Subsurface
steeringManager = new SteeringManager(this);
}
+ public virtual void OnAttacked(IDamageable attacker, float amount) { }
+
public virtual void SelectTarget(AITarget target) { }
public virtual void Update(float deltaTime) { }
diff --git a/Subsurface/Source/Characters/AI/EnemyAIController.cs b/Subsurface/Source/Characters/AI/EnemyAIController.cs
index 9655c8206..a21591f92 100644
--- a/Subsurface/Source/Characters/AI/EnemyAIController.cs
+++ b/Subsurface/Source/Characters/AI/EnemyAIController.cs
@@ -262,6 +262,13 @@ namespace Subsurface
targetEntity = closestBody.UserData as IDamageable;
}
+ public override void OnAttacked(IDamageable attacker, float amount)
+ {
+ if (attacker==null || attacker.AiTarget==null) return;
+ AITargetMemory targetMemory = FindTargetMemory(attacker.AiTarget);
+ targetMemory.Priority += amount;
+ }
+
private void UpdateLimbAttack(float deltaTime, Limb limb, Vector2 attackPosition)
{
IDamageable damageTarget = null;
@@ -295,8 +302,8 @@ namespace Subsurface
{
attackTimer += deltaTime;
limb.body.ApplyTorque(limb.Mass * 50.0f * Character.AnimController.Dir * dir);
-
- limb.attack.DoDamage(damageTarget, limb.SimPosition, deltaTime, (limb.soundTimer <= 0.0f));
+
+ limb.attack.DoDamage(Character, damageTarget, limb.SimPosition, deltaTime, (limb.soundTimer <= 0.0f));
limb.soundTimer = Limb.SoundInterval;
}
diff --git a/Subsurface/Source/Characters/AICharacter.cs b/Subsurface/Source/Characters/AICharacter.cs
index db2a9ff56..3cb471020 100644
--- a/Subsurface/Source/Characters/AICharacter.cs
+++ b/Subsurface/Source/Characters/AICharacter.cs
@@ -10,6 +10,8 @@ namespace Subsurface
{
class AICharacter : Character
{
+ const float AttackBackPriority = 1.0f;
+
private AIController aiController;
public AICharacter(string file) : this(file, Vector2.Zero, null)
@@ -57,6 +59,15 @@ namespace Subsurface
aiController.Update(deltaTime);
}
+ public override AttackResult AddDamage(IDamageable attacker, Vector2 position, Attack attack, bool playSound = false)
+ {
+ AttackResult result = base.AddDamage(attacker, position, attack, playSound);
+
+ aiController.OnAttacked(attacker, (result.Damage + result.Bleeding)/Math.Max(health,1.0f));
+
+ return result;
+ }
+
public override void FillNetworkData(NetworkEventType type, NetOutgoingMessage message, object data)
{
if (type == NetworkEventType.KillCharacter)
diff --git a/Subsurface/Source/Characters/Attack.cs b/Subsurface/Source/Characters/Attack.cs
index 21724003b..678015716 100644
--- a/Subsurface/Source/Characters/Attack.cs
+++ b/Subsurface/Source/Characters/Attack.cs
@@ -51,6 +51,12 @@ namespace Subsurface
private float priority;
+
+ //public Attack(AttackType type, float range,)
+ //{
+
+ //}
+
public Attack(XElement element)
{
try
@@ -94,10 +100,10 @@ namespace Subsurface
{
if (subElement.Name.ToString().ToLower() == "particleemitter") particleEmitterPrefab = new ParticleEmitterPrefab(subElement);
}
-
}
- public AttackResult DoDamage(IDamageable target, Vector2 position, float deltaTime, bool playSound = true)
+
+ public AttackResult DoDamage(IDamageable attacker, IDamageable target, Vector2 position, float deltaTime, bool playSound = true)
{
float damageAmount = 0.0f;
//DamageSoundType damageSoundType = DamageSoundType.None;
@@ -125,7 +131,7 @@ namespace Subsurface
sound.Play(1.0f, 500.0f, position);
}
- return target.AddDamage(position, DamageType, damageAmount, bleedingAmount, Stun, playSound);
+ return target.AddDamage(attacker, position, this, playSound);
}
}
diff --git a/Subsurface/Source/Characters/Character.cs b/Subsurface/Source/Characters/Character.cs
index bb2709f47..dfbcd2c07 100644
--- a/Subsurface/Source/Characters/Character.cs
+++ b/Subsurface/Source/Characters/Character.cs
@@ -856,7 +856,12 @@ namespace Subsurface
}
}
- public AttackResult AddDamage(Vector2 position, DamageType damageType, float amount, float bleedingAmount, float stun, bool playSound = false)
+ public virtual AttackResult AddDamage(IDamageable attacker, Vector2 position, Attack attack, bool playSound = false)
+ {
+ return AddDamage(position, attack.DamageType, attack.Damage, attack.BleedingDamage, attack.Stun, playSound);
+ }
+
+ public AttackResult AddDamage(Vector2 position, DamageType damageType, float amount, float bleedingAmount, float stun, bool playSound)
{
AnimController.StunTimer = Math.Max(AnimController.StunTimer, stun);
@@ -882,7 +887,6 @@ namespace Subsurface
bleeding += attackResult.Bleeding;
return attackResult;
-
}
public void Stun()
diff --git a/Subsurface/Source/Characters/Ragdoll.cs b/Subsurface/Source/Characters/Ragdoll.cs
index 7749a1ca6..7ab5b1f7d 100644
--- a/Subsurface/Source/Characters/Ragdoll.cs
+++ b/Subsurface/Source/Characters/Ragdoll.cs
@@ -669,13 +669,13 @@ namespace Subsurface
foreach (MapEntity e in MapEntity.mapEntityList)
{
Gap gap = e as Gap;
- if (gap == null || gap.FlowTargetHull != currentHull || gap.FlowForce == Vector2.Zero) continue;
+ if (gap == null || gap.FlowTargetHull != currentHull || gap.LerpedFlowForce == Vector2.Zero) continue;
Vector2 gapPos = gap.SimPosition;
float dist = Vector2.Distance(limbPos, gapPos);
- force += Vector2.Normalize(gap.FlowForce) * (Math.Max(gap.FlowForce.Length() - dist, 0.0f) / 500.0f);
+ force += Vector2.Normalize(gap.LerpedFlowForce) * (Math.Max(gap.LerpedFlowForce.Length() - dist, 0.0f) / 500.0f);
}
if (force.Length() > 20.0f) return force;
diff --git a/Subsurface/Source/Events/MonsterEvent.cs b/Subsurface/Source/Events/MonsterEvent.cs
index f6a6f21b9..cc0aeadfd 100644
--- a/Subsurface/Source/Events/MonsterEvent.cs
+++ b/Subsurface/Source/Events/MonsterEvent.cs
@@ -27,7 +27,7 @@ namespace Subsurface
int amount = Rand.Range(minAmount, maxAmount, false);
- monsters = new Character[amount];
+ monsters = new AICharacter[amount];
for (int i = 0; i < amount; i++)
{
diff --git a/Subsurface/Source/Items/Components/Door.cs b/Subsurface/Source/Items/Components/Door.cs
index b446a7695..a6eed6412 100644
--- a/Subsurface/Source/Items/Components/Door.cs
+++ b/Subsurface/Source/Items/Components/Door.cs
@@ -245,9 +245,9 @@ namespace Subsurface.Items.Components
public override void UpdateBroken(float deltaTime, Camera cam)
{
body.Enabled = false;
- convexHull.Enabled = false;
+ //convexHull.Enabled = false;
linkedGap.Open = 1.0f;
- if (convexHull2 != null) convexHull2.Enabled = false;
+ //if (convexHull2 != null) convexHull2.Enabled = false;
}
public override void Draw(SpriteBatch spriteBatch, bool editing)
diff --git a/Subsurface/Source/Items/Components/Holdable/MeleeWeapon.cs b/Subsurface/Source/Items/Components/Holdable/MeleeWeapon.cs
index 783e416c6..80be13d01 100644
--- a/Subsurface/Source/Items/Components/Holdable/MeleeWeapon.cs
+++ b/Subsurface/Source/Items/Components/Holdable/MeleeWeapon.cs
@@ -16,6 +16,8 @@ namespace Subsurface.Items.Components
private float range;
+ private Character user;
+
[HasDefaultValue(0.0f, false)]
public float Range
{
@@ -45,6 +47,8 @@ namespace Subsurface.Items.Components
if (character == null) return false;
if (!character.GetInputState(InputType.SecondaryHeld) || hitting) return false;
+ user = character;
+
if (hitPos < MathHelper.Pi * 0.69f) return false;
item.body.FarseerBody.CollisionCategories = Physics.CollisionProjectile;
@@ -178,7 +182,7 @@ namespace Subsurface.Items.Components
if (target == null) return false;
- attack.DoDamage(target, item.Position, 1.0f);
+ attack.DoDamage(user, target, item.Position, 1.0f);
RestoreCollision();
hitting = false;
diff --git a/Subsurface/Source/Items/Components/Label.cs b/Subsurface/Source/Items/Components/Label.cs
index b09c58a5c..97e086077 100644
--- a/Subsurface/Source/Items/Components/Label.cs
+++ b/Subsurface/Source/Items/Components/Label.cs
@@ -1,106 +1,106 @@
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Graphics;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Xml.Linq;
+//using Microsoft.Xna.Framework;
+//using Microsoft.Xna.Framework.Graphics;
+//using System;
+//using System.Collections.Generic;
+//using System.Linq;
+//using System.Text;
+//using System.Xml.Linq;
-namespace Subsurface.Items.Components
-{
- class Label : ItemComponent
- {
- GUITextBox textBox;
+//namespace Subsurface.Items.Components
+//{
+// class Label : ItemComponent
+// {
+// GUITextBox textBox;
- private string text;
+// private string text;
- [HasDefaultValue("", true)]
- public string Text
- {
- get { return text; }
- set
- {
- text = value;
- }
- }
+// [HasDefaultValue("", true)]
+// public string Text
+// {
+// get { return text; }
+// set
+// {
+// text = value;
+// }
+// }
- public Label(Item item, XElement element)
- : base(item, element)
- {
+// public Label(Item item, XElement element)
+// : base(item, element)
+// {
- }
+// }
- public override bool Select(Character character)
- {
- if (textBox == null)
- {
- textBox = new GUITextBox(Rectangle.Empty, GUI.Style, GuiFrame);
- textBox.Wrap = true;
- textBox.OnTextChanged = TextChanged;
- textBox.LimitText = true;
+// public override bool Select(Character character)
+// {
+// if (textBox == null)
+// {
+// textBox = new GUITextBox(Rectangle.Empty, GUI.Style, GuiFrame);
+// textBox.Wrap = true;
+// textBox.OnTextChanged = TextChanged;
+// textBox.LimitText = true;
- GUIButton button = new GUIButton(new Rectangle(0,0,100,15), "OK", null, Alignment.BottomRight, GUI.Style, GuiFrame);
- button.OnClicked = Close;
- }
+// GUIButton button = new GUIButton(new Rectangle(0,0,100,15), "OK", null, Alignment.BottomRight, GUI.Style, GuiFrame);
+// button.OnClicked = Close;
+// }
- textBox.Text = text;
+// textBox.Text = text;
- textBox.Select();
+// textBox.Select();
- return base.Select(character);
- }
+// return base.Select(character);
+// }
- public override void DrawHUD(SpriteBatch spriteBatch, Character character)
- {
- //isActive = true;
- GuiFrame.Update((float)Physics.step);
- GuiFrame.Draw(spriteBatch);
+// public override void DrawHUD(SpriteBatch spriteBatch, Character character)
+// {
+// //isActive = true;
+// GuiFrame.Update((float)Physics.step);
+// GuiFrame.Draw(spriteBatch);
- //int width = 300, height = 300;
- //int x = Game1.GraphicsWidth / 2 - width / 2;
- //int y = Game1.GraphicsHeight / 2 - height / 2 - 50;
+// //int width = 300, height = 300;
+// //int x = Game1.GraphicsWidth / 2 - width / 2;
+// //int y = Game1.GraphicsHeight / 2 - height / 2 - 50;
- //GUI.DrawRectangle(spriteBatch, new Rectangle(x, y, width, height), Color.Black, true);
- if (!textBox.Selected) character.SelectedConstruction = null;
- }
+// //GUI.DrawRectangle(spriteBatch, new Rectangle(x, y, width, height), Color.Black, true);
+// if (!textBox.Selected) character.SelectedConstruction = null;
+// }
- private bool TextChanged(GUITextBox textBox, string text)
- {
- this.text = text;
- item.NewComponentEvent(this, true);
+// private bool TextChanged(GUITextBox textBox, string text)
+// {
+// this.text = text;
+// item.NewComponentEvent(this, true);
- return true;
- }
+// return true;
+// }
- private bool Close(GUIButton button, object obj)
- {
- textBox.Deselect();
+// private bool Close(GUIButton button, object obj)
+// {
+// textBox.Deselect();
- return true;
- }
+// return true;
+// }
- public override void FillNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetOutgoingMessage message)
- {
- message.Write(Text);
- }
+// public override void FillNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetOutgoingMessage message)
+// {
+// message.Write(Text);
+// }
- public override void ReadNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetIncomingMessage message)
- {
- string newText = "";
- try
- {
- newText = message.ReadString();
- }
+// public override void ReadNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetIncomingMessage message)
+// {
+// string newText = "";
+// try
+// {
+// newText = message.ReadString();
+// }
- catch (Exception e)
- {
-#if DEBUG
- DebugConsole.ThrowError("invalid network message", e);
-#endif
- return;
- }
+// catch (Exception e)
+// {
+//#if DEBUG
+// DebugConsole.ThrowError("invalid network message", e);
+//#endif
+// return;
+// }
- Text = newText;
- }
- }
-}
+// Text = newText;
+// }
+// }
+//}
diff --git a/Subsurface/Source/Items/Components/Projectile.cs b/Subsurface/Source/Items/Components/Projectile.cs
index 54f38c97c..95a92416f 100644
--- a/Subsurface/Source/Items/Components/Projectile.cs
+++ b/Subsurface/Source/Items/Components/Projectile.cs
@@ -145,11 +145,11 @@ namespace Subsurface.Items.Components
Structure structure;
if ((limb = (f2.Body.UserData as Limb)) != null)
{
- attackResult = attack.DoDamage(limb.character, item.SimPosition, 1.0f);
+ attackResult = attack.DoDamage(null, limb.character, item.SimPosition, 1.0f);
}
else if ((structure = (f2.Body.UserData as Structure)) != null)
{
- attackResult = attack.DoDamage(structure, item.SimPosition, 1.0f);
+ attackResult = attack.DoDamage(null, structure, item.SimPosition, 1.0f);
}
}
diff --git a/Subsurface/Source/Items/Components/Signal/Wire.cs b/Subsurface/Source/Items/Components/Signal/Wire.cs
index d146a3c14..d169f58a4 100644
--- a/Subsurface/Source/Items/Components/Signal/Wire.cs
+++ b/Subsurface/Source/Items/Components/Signal/Wire.cs
@@ -289,37 +289,39 @@ namespace Subsurface.Items.Components
{
GUI.DrawRectangle(spriteBatch, new Rectangle((int)Nodes[i].X - 3, (int)-Nodes[i].Y - 3, 6, 6), Color.Red, true, 0.0f);
- if (GUIComponent.MouseOn == null &&
- Vector2.Distance(GameMain.EditMapScreen.Cam.ScreenToWorld(PlayerInput.MousePosition), Nodes[i]) < 20.0f)
+ if (GUIComponent.MouseOn != null ||
+ Vector2.Distance(GameMain.EditMapScreen.Cam.ScreenToWorld(PlayerInput.MousePosition), Nodes[i]) > 20.0f)
{
- GUI.DrawRectangle(spriteBatch, new Rectangle((int)Nodes[i].X - 10, (int)-Nodes[i].Y - 10, 20, 20), Color.Red, false, 0.0f);
+ continue;
+ }
- if (selectedNodeIndex==null)// && selectedNodeIndex>0 && selectedNodeIndex 0.0f)
+ if (attack.StructureDamage > 0.0f)
{
List structureList = new List();
@@ -98,7 +93,7 @@ namespace Subsurface
for (int i = 0; i < structure.SectionCount; i++)
{
float distFactor = 1.0f - (Vector2.Distance(structure.SectionPosition(i), displayPosition) / displayRange);
- if (distFactor > 0.0f) structure.AddDamage(i, structureDamage*distFactor);
+ if (distFactor > 0.0f) structure.AddDamage(i, attack.StructureDamage*distFactor);
}
}
}
@@ -107,16 +102,16 @@ namespace Subsurface
{
float dist = Vector2.Distance(c.SimPosition, simPosition);
- if (dist > range) continue;
+ if (dist > attack.Range) continue;
- float distFactor = 1.0f - dist / range;
+ float distFactor = 1.0f - dist / attack.Range;
foreach (Limb limb in c.AnimController.Limbs)
{
- distFactor = 1.0f - Vector2.Distance(limb.SimPosition, simPosition)/range;
-
- c.AddDamage(limb.SimPosition, DamageType.None, damage / c.AnimController.Limbs.Length * distFactor, 0.0f, stun * distFactor);
+ distFactor = 1.0f - Vector2.Distance(limb.SimPosition, simPosition)/attack.Range;
+ c.AddDamage(limb.SimPosition, DamageType.None,
+ attack.Damage / c.AnimController.Limbs.Length * distFactor, 0.0f, attack.Stun * distFactor, true);
if (force>0.0f)
{
limb.body.ApplyLinearImpulse(Vector2.Normalize(limb.SimPosition - simPosition) * distFactor * force);
diff --git a/Subsurface/Source/Map/Gap.cs b/Subsurface/Source/Map/Gap.cs
index dee826e67..072e6a328 100644
--- a/Subsurface/Source/Map/Gap.cs
+++ b/Subsurface/Source/Map/Gap.cs
@@ -40,6 +40,13 @@ namespace Subsurface
get { return flowForce*soundVolume; }
}
+ public Vector2 LerpedFlowForce
+ {
+ get { return lerpedFlowForce; }
+ }
+
+ private Vector2 lerpedFlowForce;
+
public Hull FlowTargetHull
{
get { return flowTargetHull; }
@@ -178,6 +185,14 @@ namespace Subsurface
public override void Draw(SpriteBatch sb, bool editing)
{
+ if (GameMain.DebugDraw)
+ {
+ Vector2 center = new Vector2(rect.X + rect.Width / 2.0f, -(rect.Y - rect.Width / 2.0f));
+ GUI.DrawLine(sb, center, center + flowForce/10.0f, Color.Red);
+
+ GUI.DrawLine(sb, center + Vector2.One * 5.0f, center + lerpedFlowForce / 10.0f + Vector2.One * 5.0f, Color.Orange);
+ }
+
if (!editing) return;
Color clr = (open == 0.0f) ? Color.Red : Color.Cyan;
@@ -251,6 +266,8 @@ namespace Subsurface
UpdateRoomToRoom(deltaTime);
}
+ lerpedFlowForce = Vector2.Lerp(lerpedFlowForce, flowForce, 0.1f);
+
if (FlowForce.Length() > 150.0f && flowTargetHull != null && flowTargetHull.Volume < flowTargetHull.FullVolume)
{
//UpdateFlowForce();
diff --git a/Subsurface/Source/Map/IDamageable.cs b/Subsurface/Source/Map/IDamageable.cs
index bfd5ae1b0..f06cea4d7 100644
--- a/Subsurface/Source/Map/IDamageable.cs
+++ b/Subsurface/Source/Map/IDamageable.cs
@@ -19,6 +19,6 @@ namespace Subsurface
get;
}
- AttackResult AddDamage(Vector2 position, DamageType damageType, float amount, float bleedingAmount, float stun, bool playSound=true);
+ AttackResult AddDamage(IDamageable attacker, Vector2 position, Attack attack, bool playSound=true);
}
}
diff --git a/Subsurface/Source/Map/MapEntity.cs b/Subsurface/Source/Map/MapEntity.cs
index 8ff2201a3..bcd902a86 100644
--- a/Subsurface/Source/Map/MapEntity.cs
+++ b/Subsurface/Source/Map/MapEntity.cs
@@ -41,9 +41,10 @@ namespace Subsurface
public static bool DisableSelect
{
get { return disableSelect; }
- set {
+ set
+ {
disableSelect = value;
- if (disableSelect==true)
+ if (disableSelect)
{
startMovingPos = Vector2.Zero;
selectionSize = Vector2.Zero;
@@ -52,6 +53,12 @@ namespace Subsurface
}
}
+
+ public static bool SelectedAny
+ {
+ get { return selectedList.Count > 0; }
+ }
+
public bool MoveWithLevel
{
get;
diff --git a/Subsurface/Source/Map/Structure.cs b/Subsurface/Source/Map/Structure.cs
index fb7e97800..4a67c7cb6 100644
--- a/Subsurface/Source/Map/Structure.cs
+++ b/Subsurface/Source/Map/Structure.cs
@@ -386,11 +386,11 @@ namespace Subsurface
}
- public int FindSectionIndex(Vector2 pos)
+ public int FindSectionIndex(Vector2 displayPos)
{
int index = (isHorizontal) ?
- (int)Math.Floor((pos.X - rect.X) / wallSectionSize) :
- (int)Math.Floor((rect.Y - pos.Y) / wallSectionSize);
+ (int)Math.Floor((displayPos.X - rect.X) / wallSectionSize) :
+ (int)Math.Floor((rect.Y - displayPos.Y) / wallSectionSize);
if (index < 0 || index > sections.Length - 1) return -1;
return index;
@@ -412,7 +412,7 @@ namespace Subsurface
sections[sectionIndex].rect.Y - sections[sectionIndex].rect.Height / 2.0f);
}
- public AttackResult AddDamage(Vector2 position, DamageType damageType, float amount, float bleedingAmount, float stun, bool playSound = false)
+ public AttackResult AddDamage(IDamageable attacker, Vector2 position, Attack attack, bool playSound = false)
{
if (!prefab.HasBody || prefab.IsPlatform) return new AttackResult(0.0f, 0.0f);
@@ -423,13 +423,13 @@ namespace Subsurface
if (playSound && !SectionHasHole(i))
{
- DamageSoundType damageSoundType = (damageType == DamageType.Blunt) ? DamageSoundType.StructureBlunt : DamageSoundType.StructureSlash;
- AmbientSoundManager.PlayDamageSound(damageSoundType, amount, position);
+ DamageSoundType damageSoundType = (attack.DamageType == DamageType.Blunt) ? DamageSoundType.StructureBlunt : DamageSoundType.StructureSlash;
+ AmbientSoundManager.PlayDamageSound(damageSoundType, attack.Damage, position);
}
- AddDamage(i, amount);
+ AddDamage(i, attack.Damage);
- return new AttackResult(amount, 0.0f);
+ return new AttackResult(attack.Damage, 0.0f);
}
private void SetDamage(int sectionIndex, float damage)
diff --git a/Subsurface/Source/Map/Submarine.cs b/Subsurface/Source/Map/Submarine.cs
index 8ac493396..e5abeae62 100644
--- a/Subsurface/Source/Map/Submarine.cs
+++ b/Subsurface/Source/Map/Submarine.cs
@@ -1,10 +1,7 @@
using FarseerPhysics;
using FarseerPhysics.Collision;
using FarseerPhysics.Common;
-using FarseerPhysics.Common.Decomposition;
using FarseerPhysics.Dynamics;
-using FarseerPhysics.Dynamics.Contacts;
-using FarseerPhysics.Factories;
using Lidgren.Network;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
@@ -15,7 +12,6 @@ using System.IO;
using System.Linq;
using System.Reflection;
using System.Xml.Linq;
-using Voronoi2;
namespace Subsurface
{
@@ -32,20 +28,14 @@ namespace Subsurface
private static Submarine loaded;
+ private SubmarineBody subBody;
+
private static Vector2 lastPickedPosition;
private static float lastPickedFraction;
static string SaveFolder;
Md5Hash hash;
- Vector2 speed;
-
- Vector2 targetPosition;
-
- private Rectangle borders;
-
- private Body hullBody;
-
private string filePath;
private string name;
@@ -70,12 +60,6 @@ namespace Subsurface
get { return lastPickedFraction; }
}
- public List HullVertices
- {
- get;
- private set;
- }
-
public Md5Hash MD5Hash
{
get
@@ -98,14 +82,11 @@ namespace Subsurface
{
get
{
- return (loaded==null) ? Rectangle.Empty : loaded.borders;
+ return (loaded==null) ? Rectangle.Empty : Loaded.subBody.Borders;
}
}
- public Vector2 Center
- {
- get { return new Vector2(borders.X+borders.Width/2, borders.Y - borders.Height/2); }
- }
+
public Vector2 Position
{
@@ -114,14 +95,16 @@ namespace Subsurface
public Vector2 Speed
{
- get { return speed; }
- set
- {
- if (!MathUtils.IsValid(value)) return;
- speed = value;
- }
+ get { return subBody.Speed; }
+ set { subBody.Speed = value; }
}
+ public List HullVertices
+ {
+ get { return subBody.HullVertices; }
+ }
+
+
public string FilePath
{
get { return filePath; }
@@ -162,69 +145,6 @@ namespace Subsurface
ID = -1;
}
- private List GenerateConvexHull()
- {
- List points = new List();
-
- Vector2 leftMost = Vector2.Zero;
-
- foreach (Structure wall in Structure.wallList)
- {
- for (int x = -1; x <= 1; x += 2)
- {
- for (int y = -1; y <= 1; y += 2)
- {
- Vector2 corner = new Vector2(wall.Rect.X + wall.Rect.Width / 2.0f, wall.Rect.Y - wall.Rect.Height / 2.0f);
- corner.X += x * wall.Rect.Width / 2.0f;
- corner.Y += y * wall.Rect.Height / 2.0f;
-
- if (points.Contains(corner)) continue;
-
- points.Add(corner);
- if (leftMost == Vector2.Zero || corner.X < leftMost.X) leftMost = corner;
- }
- }
- }
-
- List hullPoints = new List();
-
- Vector2 currPoint = leftMost;
- Vector2 endPoint;
- do
- {
- hullPoints.Add(currPoint);
- endPoint = points[0];
-
- for (int i = 1; i < points.Count; i++)
- {
- if ((currPoint == endPoint)
- || (Orientation(currPoint, endPoint, points[i]) == -1))
- {
- endPoint = points[i];
- }
- }
-
- currPoint = endPoint;
-
- }
- while (endPoint != hullPoints[0]);
-
- return hullPoints;
- }
-
- private static int Orientation(Vector2 p1, Vector2 p2, Vector2 p)
- {
- // Determinant
- float Orin = (p2.X - p1.X) * (p.Y - p1.Y) - (p.X - p1.X) * (p2.Y - p1.Y);
-
- if (Orin > 0)
- return -1; // (* Orientation is to the left-hand side *)
- if (Orin < 0)
- return 1; // (* Orientation is to the right-hand side *)
-
- return 0; // (* Orientation is neutral aka collinear *)
- }
-
//drawing ----------------------------------------------------
public static void Draw(SpriteBatch spriteBatch, bool editing = false)
@@ -419,188 +339,41 @@ namespace Subsurface
//movement ----------------------------------------------------
- float collisionRigidness = 1.0f;
public void Update(float deltaTime)
{
- Vector2 translateAmount = speed * deltaTime;
- translateAmount += ConvertUnits.ToDisplayUnits(hullBody.Position) * collisionRigidness;
-
- if (targetPosition != Vector2.Zero && Vector2.Distance(targetPosition, Position) > 50.0f)
- {
- translateAmount += (targetPosition - Position) * 0.01f;
- }
- else
- {
- targetPosition = Vector2.Zero;
- }
-
- Translate(translateAmount);
-
- //-------------------------
-
- Vector2 totalForce = CalculateBuoyancy();
-
- float dragCoefficient = 0.00001f;
-
- float speedLength = (speed == Vector2.Zero) ? 0.0f : speed.Length();
- float drag = speedLength * speedLength * dragCoefficient * mass;
-
- if (speed != Vector2.Zero)
- {
- totalForce += -Vector2.Normalize(speed) * drag;
- }
-
- ApplyForce(totalForce);
-
- //hullBodies[0].body.LinearVelocity = -hullBodies[0].body.Position;
-
- //hullBody.SetTransform(Vector2.Zero , 0.0f);
- hullBody.LinearVelocity = -hullBody.Position/(float)Physics.step;
-
- if (collidingCell == null)
- {
- collisionRigidness = MathHelper.Lerp(collisionRigidness, 1.0f, 0.1f);
- return;
- }
-
- foreach (GraphEdge ge in collidingCell.edges)
- {
- Body body = PickBody(
- ConvertUnits.ToSimUnits(ge.point1+ GameMain.GameSession.Level.Position),
- ConvertUnits.ToSimUnits(ge.point2 + GameMain.GameSession.Level.Position), new List(){collidingCell.body});
- if (body == null || body.UserData == null) continue;
-
- Structure structure = body.UserData as Structure;
- if (structure == null) continue;
- structure.AddDamage(lastPickedPosition, DamageType.Blunt, 50.0f, 0.0f, 0.0f, true);
- }
-
- collidingCell = null;
-
- //hullBodies[0].body.SetTransform(Vector2.Zero, 0.0f);
-
- //position = hullBodies[0].body.Position;
-
- //Level.Loaded.Move(-ConvertUnits.ToDisplayUnits(position - prevPosition));
-
- //prevPosition = hullBodies[0].body.Position;
+ if (Level.Loaded == null) return;
+ subBody.Update(deltaTime);
}
- private Vector2 CalculateBuoyancy()
+ public void ApplyForce(Vector2 force)
{
- float waterVolume = 0.0f;
- float volume = 0.0f;
- foreach (Hull hull in Hull.hullList)
- {
- waterVolume += hull.Volume;
- volume += hull.FullVolume;
- }
-
- float waterPercentage = waterVolume / volume;
-
- float neutralPercentage = 0.07f;
-
- float buoyancy = neutralPercentage-waterPercentage;
- buoyancy *= mass * 30.0f;
-
- return new Vector2(0.0f, buoyancy);
+ subBody.ApplyForce(force);
}
public void SetPosition(Vector2 position)
{
- //hullBodies[0].body.SetTransform(position, 0.0f);
+ if (!MathUtils.IsValid(position)) return;
Level.Loaded.SetPosition(-position);
//prevPosition = position;
}
- private void Translate(Vector2 amount)
+ public void Translate(Vector2 amount)
{
- if (amount == Vector2.Zero || !amount.IsValid()) return;
+ if (amount == Vector2.Zero || !MathUtils.IsValid(amount)) return;
Level.Loaded.Move(-amount);
}
- float mass = 10000.0f;
- public void ApplyForce(Vector2 force)
- {
- speed += force/mass;
- }
-
- VoronoiCell collidingCell;
- public bool OnCollision(Fixture f1, Fixture f2, Contact contact)
- {
- System.Diagnostics.Debug.WriteLine("colliding");
- VoronoiCell cell = f2.Body.UserData as VoronoiCell;
- if (cell==null) return true;
-
- Vector2 normal = contact.Manifold.LocalNormal;
- Vector2 simSpeed = ConvertUnits.ToSimUnits(speed);
- float impact = Vector2.Dot(simSpeed, normal);
-
- Vector2 u = Vector2.Dot(simSpeed, -normal)*-normal;
- Vector2 w = simSpeed - u;
-
- Vector2 limbForce = normal * impact;
-
- foreach (Character c in Character.CharacterList)
- {
- if (c.AnimController.CurrentHull == null) continue;
-
- if (impact > 2.0f) c.AnimController.StunTimer = (impact - 2.0f) * 0.1f;
-
- foreach (Limb limb in c.AnimController.Limbs)
- {
- limb.body.ApplyLinearImpulse(limb.Mass * limbForce);
- }
- }
-
- if (impact >= 1.0f)
- {
- AmbientSoundManager.PlayDamageSound(DamageSoundType.StructureBlunt, impact * 10.0f, cell.body);
-
- FixedArray2 worldPoints;
- contact.GetWorldManifold(out normal, out worldPoints);
-
-
- AmbientSoundManager.PlayDamageSound(DamageSoundType.StructureBlunt, impact * 10.0f, ConvertUnits.ToDisplayUnits(worldPoints[0]));
-
- GameMain.GameScreen.Cam.Shake = impact*2.0f;
- }
-
- System.Diagnostics.Debug.WriteLine("IMPACT: "+impact + " normal: "+normal+" simspeed: "+simSpeed+" u: "+u+" w: " +w);
- if (impact < 4.0f)
- {
- speed = ConvertUnits.ToDisplayUnits(w * 0.9f - u * 0.2f);
- return true;
- }
- else
- {
- speed = ConvertUnits.ToDisplayUnits(w * 0.9f + u * 0.5f);
- }
-
-
- collisionRigidness = 0.8f;
-
- collidingCell = cell;
-
- return true;
- }
-
- public void OnSeparation(Fixture f1, Fixture f2)
- {
- collidingCell = null;
- }
-
public override void FillNetworkData(Networking.NetworkEventType type, NetOutgoingMessage message, object data)
{
message.Write((float)NetTime.Now);
message.Write(Position.X);
message.Write(Position.Y);
- message.Write(speed.X);
- message.Write(speed.Y);
+ message.Write(Speed.X);
+ message.Write(Speed.Y);
}
@@ -630,13 +403,12 @@ namespace Subsurface
//newTargetPosition = newTargetPosition + newSpeed * (float)(NetTime.Now - sendingTime);
- targetPosition = newTargetPosition;
- speed = newSpeed;
+ subBody.TargetPosition = newTargetPosition;
+ subBody.Speed = newSpeed;
lastNetworkUpdate = sendingTime;
}
-
-
+
//saving/loading ----------------------------------------------------
@@ -829,42 +601,7 @@ namespace Subsurface
}
- List convexHull = GenerateConvexHull();
-
- HullVertices = convexHull;
-
- for (int i = 0; i < convexHull.Count; i++)
- {
- convexHull[i] = ConvertUnits.ToSimUnits(convexHull[i]);
- }
-
- convexHull.Reverse();
-
- //get farseer 'vertices' from vectors
- Vertices shapevertices = new Vertices(convexHull);
-
- AABB hullAABB = shapevertices.GetAABB();
-
- borders = new Rectangle(
- (int)ConvertUnits.ToDisplayUnits(hullAABB.LowerBound.X),
- (int)ConvertUnits.ToDisplayUnits(hullAABB.UpperBound.Y),
- (int)ConvertUnits.ToDisplayUnits(hullAABB.Extents.X * 2.0f),
- (int)ConvertUnits.ToDisplayUnits(hullAABB.Extents.Y * 2.0f));
-
-
- var triangulatedVertices = Triangulate.ConvexPartition(shapevertices, TriangulationAlgorithm.Bayazit);
-
- hullBody = BodyFactory.CreateCompoundPolygon(GameMain.World, triangulatedVertices, 5.0f);
- hullBody.BodyType = BodyType.Dynamic;
-
- hullBody.CollisionCategories = Physics.CollisionMisc;
- hullBody.CollidesWith = Physics.CollisionLevel;
- hullBody.FixedRotation = true;
- hullBody.Awake = true;
- hullBody.SleepingAllowed = false;
- hullBody.GravityScale = 0.0f;
- hullBody.OnCollision += OnCollision;
- hullBody.OnSeparation += OnSeparation;
+ subBody = new SubmarineBody(this);
MapEntity.LinkAll();
@@ -908,6 +645,8 @@ namespace Subsurface
{
if (GameMain.GameScreen.Cam != null) GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
+ subBody = null;
+
Entity.RemoveAll();
PhysicsBody.list.Clear();
diff --git a/Subsurface/Source/Map/SubmarineHull.cs b/Subsurface/Source/Map/SubmarineHull.cs
new file mode 100644
index 000000000..c0fdeded5
--- /dev/null
+++ b/Subsurface/Source/Map/SubmarineHull.cs
@@ -0,0 +1,318 @@
+using FarseerPhysics;
+using FarseerPhysics.Collision;
+using FarseerPhysics.Common;
+using FarseerPhysics.Common.Decomposition;
+using FarseerPhysics.Dynamics;
+using FarseerPhysics.Dynamics.Contacts;
+using FarseerPhysics.Factories;
+using Microsoft.Xna.Framework;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Voronoi2;
+
+namespace Subsurface
+{
+ class SubmarineBody
+ {
+
+ public List HullVertices
+ {
+ get;
+ private set;
+ }
+
+ private Submarine sub;
+
+ private Body body;
+
+ private Vector2 speed;
+
+ private Vector2 targetPosition;
+
+ public Rectangle Borders
+ {
+ get;
+ private set;
+ }
+
+ public Vector2 Speed
+ {
+ get { return speed; }
+ set
+ {
+ if (!MathUtils.IsValid(value)) return;
+ speed = value;
+ }
+ }
+
+ public Vector2 TargetPosition
+ {
+ get { return targetPosition; }
+ set
+ {
+ if (!MathUtils.IsValid(value)) return;
+ targetPosition = value;
+ }
+ }
+
+
+ public Vector2 Center
+ {
+ get { return new Vector2(Borders.X + Borders.Width / 2, Borders.Y - Borders.Height / 2); }
+ }
+
+ public SubmarineBody(Submarine sub)
+ {
+ this.sub = sub;
+
+
+ List convexHull = GenerateConvexHull();
+ HullVertices = convexHull;
+
+ for (int i = 0; i < convexHull.Count; i++)
+ {
+ convexHull[i] = ConvertUnits.ToSimUnits(convexHull[i]);
+ }
+
+ convexHull.Reverse();
+
+ //get farseer 'vertices' from vectors
+ Vertices shapevertices = new Vertices(convexHull);
+
+ AABB hullAABB = shapevertices.GetAABB();
+
+ Borders = new Rectangle(
+ (int)ConvertUnits.ToDisplayUnits(hullAABB.LowerBound.X),
+ (int)ConvertUnits.ToDisplayUnits(hullAABB.UpperBound.Y),
+ (int)ConvertUnits.ToDisplayUnits(hullAABB.Extents.X * 2.0f),
+ (int)ConvertUnits.ToDisplayUnits(hullAABB.Extents.Y * 2.0f));
+
+
+ var triangulatedVertices = Triangulate.ConvexPartition(shapevertices, TriangulationAlgorithm.Bayazit);
+
+ body = BodyFactory.CreateCompoundPolygon(GameMain.World, triangulatedVertices, 5.0f);
+ body.BodyType = BodyType.Dynamic;
+
+ body.CollisionCategories = Physics.CollisionMisc;
+ body.CollidesWith = Physics.CollisionLevel;
+ body.FixedRotation = true;
+ body.Awake = true;
+ body.SleepingAllowed = false;
+ body.GravityScale = 0.0f;
+ body.OnCollision += OnCollision;
+ body.OnSeparation += OnSeparation;
+ }
+
+
+ private List GenerateConvexHull()
+ {
+ List points = new List();
+
+ Vector2 leftMost = Vector2.Zero;
+
+ foreach (Structure wall in Structure.wallList)
+ {
+ for (int x = -1; x <= 1; x += 2)
+ {
+ for (int y = -1; y <= 1; y += 2)
+ {
+ Vector2 corner = new Vector2(wall.Rect.X + wall.Rect.Width / 2.0f, wall.Rect.Y - wall.Rect.Height / 2.0f);
+ corner.X += x * wall.Rect.Width / 2.0f;
+ corner.Y += y * wall.Rect.Height / 2.0f;
+
+ if (points.Contains(corner)) continue;
+
+ points.Add(corner);
+ if (leftMost == Vector2.Zero || corner.X < leftMost.X) leftMost = corner;
+ }
+ }
+ }
+
+ List hullPoints = new List();
+
+ Vector2 currPoint = leftMost;
+ Vector2 endPoint;
+ do
+ {
+ hullPoints.Add(currPoint);
+ endPoint = points[0];
+
+ for (int i = 1; i < points.Count; i++)
+ {
+ if ((currPoint == endPoint)
+ || (MathUtils.VectorOrientation(currPoint, endPoint, points[i]) == -1))
+ {
+ endPoint = points[i];
+ }
+ }
+
+ currPoint = endPoint;
+
+ }
+ while (endPoint != hullPoints[0]);
+
+ return hullPoints;
+ }
+
+
+ float collisionRigidness = 1.0f;
+
+ public void Update(float deltaTime)
+ {
+ Vector2 translateAmount = speed * deltaTime;
+ translateAmount += ConvertUnits.ToDisplayUnits(body.Position) * collisionRigidness;
+
+ if (targetPosition != Vector2.Zero && Vector2.Distance(targetPosition, sub.Position) > 50.0f)
+ {
+ translateAmount += (targetPosition - sub.Position) * 0.01f;
+ }
+ else
+ {
+ targetPosition = Vector2.Zero;
+ }
+
+ sub.Translate(translateAmount);
+
+ //-------------------------
+
+ Vector2 totalForce = CalculateBuoyancy();
+
+ float dragCoefficient = 0.00001f;
+
+ float speedLength = (speed == Vector2.Zero) ? 0.0f : speed.Length();
+ float drag = speedLength * speedLength * dragCoefficient * mass;
+
+ if (speed != Vector2.Zero)
+ {
+ totalForce += -Vector2.Normalize(speed) * drag;
+ }
+
+ ApplyForce(totalForce);
+
+ //hullBodies[0].body.LinearVelocity = -hullBodies[0].body.Position;
+
+ //hullBody.SetTransform(Vector2.Zero , 0.0f);
+ body.LinearVelocity = -body.Position / (float)Physics.step;
+
+ if (collidingCell == null)
+ {
+ collisionRigidness = MathHelper.Lerp(collisionRigidness, 1.0f, 0.1f);
+ return;
+ }
+
+ foreach (GraphEdge ge in collidingCell.edges)
+ {
+ Body wallBody = Submarine.PickBody(
+ ConvertUnits.ToSimUnits(ge.point1 + GameMain.GameSession.Level.Position),
+ ConvertUnits.ToSimUnits(ge.point2 + GameMain.GameSession.Level.Position), new List() { collidingCell.body });
+ if (wallBody == null || wallBody.UserData == null) continue;
+
+ Structure structure = wallBody.UserData as Structure;
+ if (structure == null) continue;
+ structure.AddDamage(
+ structure.FindSectionIndex(ConvertUnits.ToDisplayUnits(Submarine.LastPickedPosition)), 50.0f);
+ }
+
+ collidingCell = null;
+ }
+
+ private Vector2 CalculateBuoyancy()
+ {
+ float waterVolume = 0.0f;
+ float volume = 0.0f;
+ foreach (Hull hull in Hull.hullList)
+ {
+ waterVolume += hull.Volume;
+ volume += hull.FullVolume;
+ }
+
+ float waterPercentage = waterVolume / volume;
+
+ float neutralPercentage = 0.07f;
+
+ float buoyancy = neutralPercentage - waterPercentage;
+ buoyancy *= mass * 30.0f;
+
+ return new Vector2(0.0f, buoyancy);
+ }
+
+ float mass = 10000.0f;
+ public void ApplyForce(Vector2 force)
+ {
+ speed += force / mass;
+ }
+
+ VoronoiCell collidingCell;
+ public bool OnCollision(Fixture f1, Fixture f2, Contact contact)
+ {
+ VoronoiCell cell = f2.Body.UserData as VoronoiCell;
+ if (cell == null)
+ {
+ speed = new Vector2(speed.X * 0.9f, speed.Y * 0.2f);
+ return true;
+ }
+
+ Vector2 normal = contact.Manifold.LocalNormal;
+ Vector2 simSpeed = ConvertUnits.ToSimUnits(speed);
+ float impact = Vector2.Dot(simSpeed, normal);
+
+ Vector2 u = Vector2.Dot(simSpeed, -normal) * -normal;
+ Vector2 w = simSpeed - u;
+
+ Vector2 limbForce = normal * impact;
+
+ float length = limbForce.Length();
+ if (length > 10.0f) limbForce = (limbForce / length) * 10.0f;
+
+ foreach (Character c in Character.CharacterList)
+ {
+ if (c.AnimController.CurrentHull == null) continue;
+
+ if (impact > 2.0f) c.AnimController.StunTimer = (impact - 2.0f) * 0.1f;
+
+ foreach (Limb limb in c.AnimController.Limbs)
+ {
+ if (c.AnimController.LowestLimb == limb) continue;
+ limb.body.ApplyLinearImpulse(limb.Mass * limbForce);
+ }
+ }
+
+ if (impact >= 1.0f)
+ {
+ AmbientSoundManager.PlayDamageSound(DamageSoundType.StructureBlunt, impact * 10.0f, cell.body);
+
+ FarseerPhysics.Common.FixedArray2 worldPoints;
+ contact.GetWorldManifold(out normal, out worldPoints);
+
+ AmbientSoundManager.PlayDamageSound(DamageSoundType.StructureBlunt, impact * 10.0f, ConvertUnits.ToDisplayUnits(worldPoints[0]));
+
+ GameMain.GameScreen.Cam.Shake = impact * 2.0f;
+ }
+
+ System.Diagnostics.Debug.WriteLine("IMPACT: " + impact + " normal: " + normal + " simspeed: " + simSpeed + " u: " + u + " w: " + w);
+ if (impact < 4.0f)
+ {
+ speed = ConvertUnits.ToDisplayUnits(w * 0.9f - u * 0.2f);
+ return true;
+ }
+ else
+ {
+ speed = ConvertUnits.ToDisplayUnits(w * 0.9f + u * 0.5f);
+ }
+
+
+ collisionRigidness = 0.8f;
+
+ collidingCell = cell;
+
+ return true;
+ }
+
+ public void OnSeparation(Fixture f1, Fixture f2)
+ {
+ collidingCell = null;
+ }
+ }
+}
diff --git a/Subsurface/Source/Screens/GameScreen.cs b/Subsurface/Source/Screens/GameScreen.cs
index 5c7d5f1f4..5fde178e5 100644
--- a/Subsurface/Source/Screens/GameScreen.cs
+++ b/Subsurface/Source/Screens/GameScreen.cs
@@ -98,7 +98,10 @@ namespace Subsurface
Ragdoll.UpdateAll((float)Physics.step);
- if (GameMain.GameSession != null && GameMain.GameSession.Level != null) GameMain.GameSession.Submarine.Update((float)Physics.step);
+ if (GameMain.GameSession != null && GameMain.GameSession.Level != null)
+ {
+ GameMain.GameSession.Submarine.Update((float)Physics.step);
+ }
GameMain.World.Step((float)Physics.step);
diff --git a/Subsurface/Source/Sounds/AmbientSoundManager.cs b/Subsurface/Source/Sounds/AmbientSoundManager.cs
index 2d7d719fa..84eb0cc5d 100644
--- a/Subsurface/Source/Sounds/AmbientSoundManager.cs
+++ b/Subsurface/Source/Sounds/AmbientSoundManager.cs
@@ -55,8 +55,8 @@ namespace Subsurface
private const float MusicLerpSpeed = 0.01f;
- private static Sound waterAmbience;
- private static int waterAmbienceIndex;
+ private static Sound[] waterAmbiences = new Sound[2];
+ private static int[] waterAmbienceIndexes = new int[2];
private static DamageSound[] damageSounds;
@@ -78,7 +78,9 @@ namespace Subsurface
yield return CoroutineStatus.Running;
- waterAmbience = Sound.Load("Content/Sounds/Water/WaterAmbience.ogg");
+ waterAmbiences[0] = Sound.Load("Content/Sounds/Water/WaterAmbience1.ogg");
+ yield return CoroutineStatus.Running;
+ waterAmbiences[1] = Sound.Load("Content/Sounds/Water/WaterAmbience2.ogg");
yield return CoroutineStatus.Running;
flowSounds[0] = Sound.Load("Content/Sounds/Water/FlowSmall.ogg");
yield return CoroutineStatus.Running;
@@ -162,22 +164,33 @@ namespace Subsurface
}
}
- float ambienceVolume = 0.5f;
+ float ambienceVolume = 0.6f;
float lowpassHFGain = 1.0f;
if (Character.Controlled != null)
{
AnimController animController = Character.Controlled.AnimController;
if (animController.HeadInWater)
{
- ambienceVolume = 0.5f;
+ ambienceVolume = 0.8f;
ambienceVolume += animController.Limbs[0].LinearVelocity.Length();
lowpassHFGain = 0.2f;
}
}
+ //how fast the sub is moving, scaled to 0.0 -> 1.0
+ float movementFactor = 0.0f;
+ if (Submarine.Loaded!=null)
+ {
+ movementFactor = (Submarine.Loaded.Speed == Vector2.Zero) ? 0.0f : Submarine.Loaded.Speed.Length() / 500.0f;
+
+ movementFactor = MathHelper.Clamp(movementFactor, 0.0f, 1.0f);
+ }
+
SoundManager.LowPassHFGain = lowpassHFGain;
- waterAmbienceIndex = waterAmbience.Loop(waterAmbienceIndex, ambienceVolume);
+ waterAmbienceIndexes[0] = waterAmbiences[0].Loop(waterAmbienceIndexes[0], ambienceVolume * (1.0f-movementFactor));
+ waterAmbienceIndexes[1] = waterAmbiences[1].Loop(waterAmbienceIndexes[1], ambienceVolume * movementFactor);
+
}
private static void UpdateMusic()
diff --git a/Subsurface/Source/Utils/MathUtils.cs b/Subsurface/Source/Utils/MathUtils.cs
index 10b736eee..50c993542 100644
--- a/Subsurface/Source/Utils/MathUtils.cs
+++ b/Subsurface/Source/Utils/MathUtils.cs
@@ -36,6 +36,21 @@ namespace Subsurface
{
return (IsValid(vector.X) && IsValid(vector.Y));
}
+
+
+ public static int VectorOrientation(Vector2 p1, Vector2 p2, Vector2 p)
+ {
+ // Determinant
+ float Orin = (p2.X - p1.X) * (p.Y - p1.Y) - (p.X - p1.X) * (p2.Y - p1.Y);
+
+ if (Orin > 0)
+ return -1; // (* Orientation is to the left-hand side *)
+ if (Orin < 0)
+ return 1; // (* Orientation is to the right-hand side *)
+
+ return 0; // (* Orientation is neutral aka collinear *)
+ }
+
public static float CurveAngle(float from, float to, float step)
{
diff --git a/Subsurface/Subsurface.csproj b/Subsurface/Subsurface.csproj
index 6faae5fab..65735f615 100644
--- a/Subsurface/Subsurface.csproj
+++ b/Subsurface/Subsurface.csproj
@@ -94,6 +94,7 @@
+
@@ -682,7 +683,7 @@
PreserveNewest
- PreserveNewest
+ Always
PreserveNewest
@@ -706,6 +707,7 @@
PreserveNewest
+ Designer
PreserveNewest
@@ -943,13 +945,16 @@
PreserveNewest
+
+ PreserveNewest
+
PreserveNewest
PreserveNewest
-
+
PreserveNewest
diff --git a/Subsurface_Solution.v12.suo b/Subsurface_Solution.v12.suo
index 29bc80cc3..569993ce4 100644
Binary files a/Subsurface_Solution.v12.suo and b/Subsurface_Solution.v12.suo differ