More accurate and reliable submarine-level collisions, looping OnUse sounds bugfix, new music clips, item sprites removed from limbs when someone else loots the item, Camera.WorldView fix, checking vector.LengthSquared before normalizing to avoid creating a NaN vector

This commit is contained in:
Regalis
2015-10-04 23:50:46 +03:00
parent 0be4ad4f84
commit f13a48ef52
33 changed files with 342 additions and 217 deletions

View File

@@ -779,6 +779,8 @@ namespace FarseerPhysics.Dynamics
/// <param name="rotation">The world rotation in radians.</param>
public void SetTransform(Vector2 position, float rotation)
{
Debug.Assert(position.IsValid());
SetTransform(ref position, rotation);
}
@@ -823,6 +825,8 @@ namespace FarseerPhysics.Dynamics
/// <param name="point">The world position of the point of application.</param>
public void ApplyForce(Vector2 force, Vector2 point)
{
Debug.Assert(force.IsValid());
ApplyForce(ref force, ref point);
}
@@ -841,6 +845,8 @@ namespace FarseerPhysics.Dynamics
/// <param name="force">The force.</param>
public void ApplyForce(Vector2 force)
{
Debug.Assert(force.IsValid());
ApplyForce(ref force, ref _xf.p);
}
@@ -898,6 +904,8 @@ namespace FarseerPhysics.Dynamics
/// <param name="impulse">The world impulse vector, usually in N-seconds or kg-m/s.</param>
public void ApplyLinearImpulse(Vector2 impulse)
{
Debug.Assert(impulse.IsValid());
ApplyLinearImpulse(ref impulse);
}
@@ -911,6 +919,8 @@ namespace FarseerPhysics.Dynamics
/// <param name="point">The world position of the point of application.</param>
public void ApplyLinearImpulse(Vector2 impulse, Vector2 point)
{
Debug.Assert(impulse.IsValid());
ApplyLinearImpulse(ref impulse, ref point);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

View File

@@ -32,6 +32,8 @@
<music file="Content/Sounds/Music/Simplex.ogg" type="default"/>
<music file="Content/Sounds/Music/Enter the Maze.ogg" type="repair" priorityrange="40,100"/>
<music file="Content/Sounds/Music/Tenebrous Brothers Carnival - Prelude.ogg" type="default"/>
<music file="Content/Sounds/Music/Enter the Maze.ogg" type="repair" priorityrange="30,60"/>
<music file="Content/Sounds/Music/Static Motion.ogg" type="repair" priorityrange="50,80"/>
<music file="Content/Sounds/Music/Unseen Horrors.ogg" type="monster" priorityrange="40,100"/>
</sounds>

View File

@@ -48,7 +48,7 @@ namespace Subsurface
worldView = new Rectangle(
(int)(center.X - newWidth / 2.0f),
(int)(center.Y - newHeight / 2.0f),
(int)(center.Y + newHeight / 2.0f),
(int)newWidth,
(int)newHeight);

View File

@@ -312,8 +312,12 @@ namespace Subsurface
//limb.body.ApplyTorque(limb.Mass * -20.0f * character.animController.Dir * dir);
}
limb.body.ApplyLinearImpulse(limb.Mass * 10.0f *
Vector2.Normalize(attackPosition - limb.SimPosition));
Vector2 diff = attackPosition - limb.SimPosition;
if (diff.LengthSquared() > 0.00001f)
{
limb.body.ApplyLinearImpulse(limb.Mass * 10.0f *
Vector2.Normalize(attackPosition - limb.SimPosition));
}
steeringManager.SteeringSeek(attackPosition + (limb.SimPosition-Position), 5.0f);

View File

@@ -64,6 +64,9 @@ namespace Subsurface
private Vector2 DoSteeringSeek(Vector2 target, float speed = 1.0f)
{
Vector2 targetVel = target - host.Position;
if (targetVel.LengthSquared() < 0.00001f) return Vector2.Zero;
targetVel = Vector2.Normalize(targetVel) * speed;
Vector2 newSteering = targetVel - host.Steering;

View File

@@ -862,7 +862,6 @@ namespace Subsurface
{
sounds[i].Play(1.0f, 2000.0f,
AnimController.Limbs[0].body.FarseerBody);
Debug.WriteLine("playing: " + sounds[i]);
return;
}
n++;
@@ -944,7 +943,7 @@ namespace Subsurface
{
joint.LimitEnabled = false;
}
Kill(true);
Kill();
}
private IEnumerable<object> DeathAnim(Camera cam)
@@ -955,6 +954,7 @@ namespace Subsurface
float timer = 0.0f;
Color prevAmbientLight = GameMain.LightManager.AmbientLight;
Color darkLight = new Color(0.2f,0.2f,0.2f, 1.0f);
while (timer < dimDuration)
{
@@ -968,7 +968,7 @@ namespace Subsurface
cam.OffsetAmount = 0.0f;
}
GameMain.LightManager.AmbientLight = Color.Lerp(prevAmbientLight, Color.DarkGray, timer / dimDuration);
GameMain.LightManager.AmbientLight = Color.Lerp(prevAmbientLight, darkLight, timer / dimDuration);
}
yield return CoroutineStatus.Running;
@@ -984,7 +984,7 @@ namespace Subsurface
{
lerpLightBack = Math.Min(lerpLightBack + 0.05f, 1.0f);
GameMain.LightManager.AmbientLight = Color.Lerp(Color.DarkGray, prevAmbientLight, lerpLightBack);
GameMain.LightManager.AmbientLight = Color.Lerp(darkLight, prevAmbientLight, lerpLightBack);
yield return CoroutineStatus.Running;
}
@@ -996,17 +996,7 @@ namespace Subsurface
if (isDead) return;
//if the game is run by a client, characters are only killed when the server says so
if (GameMain.Client != null)
{
if (networkMessage)
{
new NetworkEvent(NetworkEventType.KillCharacter, ID, true);
}
else
{
return;
}
}
if (GameMain.Client != null && GameMain.Server==null && !networkMessage) return;
CoroutineManager.StartCoroutine(DeathAnim(GameMain.GameScreen.Cam));
@@ -1052,7 +1042,6 @@ namespace Subsurface
if (type == NetworkEventType.PickItem)
{
message.Write((int)data);
Debug.WriteLine("pickitem");
return;
}
else if (type == NetworkEventType.KillCharacter)
@@ -1140,7 +1129,6 @@ namespace Subsurface
Item item = FindEntityByID(itemId) as Item;
if (item != null)
{
Debug.WriteLine("pickitem "+itemId );
item.Pick(this);
}
@@ -1151,7 +1139,7 @@ namespace Subsurface
Kill(true);
if (GameMain.NetworkMember != null && controlled == this)
{
GameMain.Client.AddChatMessage("YOU HAVE DIED. Your chat messages will only be visible to other dead players.", ChatMessageType.Dead);
GameMain.NetworkMember.AddChatMessage("YOU HAVE DIED. Your chat messages will only be visible to other dead players.", ChatMessageType.Dead);
GameMain.LightManager.LosEnabled = false;
}
return;

View File

@@ -132,7 +132,7 @@ namespace Subsurface
void UpdateSineAnim(float deltaTime)
{
movement = MathUtils.SmoothStep(movement, TargetMovement*swimSpeed, 1.0f);
if (movement == Vector2.Zero) return;
if (movement.LengthSquared() < 0.00001f) return;
if (!inWater) movement.Y = Math.Min(0.0f, movement.Y);

View File

@@ -401,14 +401,14 @@ namespace Subsurface
}
}
for (int i = 0; i < 2; i++)
{
Limb leg = (i == 0) ? rightFoot : leftFoot;
//for (int i = 0; i < 2; i++)
//{
// Limb leg = (i == 0) ? rightLeg : leftLeg;
if (leg.SimPosition.Y < torso.SimPosition.Y) continue;
// if (leg.SimPosition.Y < waist.SimPosition.Y) continue;
leg.body.ApplyTorque(-Dir * leg.Mass * 20.0f);
}
// //leg.body.ApplyTorque(Dir * leg.Mass * 50.0f);
//}
}
@@ -416,27 +416,17 @@ namespace Subsurface
{
movement = MathUtils.SmoothStep(movement, TargetMovement, movementLerp);
if (inWater && movement != Vector2.Zero)
if (inWater && movement.LengthSquared()>0.00001f)
{
movement = Vector2.Normalize(movement);
}
if (!MathUtils.IsValid(movement))
{
int a = 1;
}
RefLimb.pullJoint.Enabled = true;
RefLimb.pullJoint.WorldAnchorB =
RefLimb.SimPosition + movement*0.15f;
RefLimb.body.SmoothRotate(0.0f);
if (!MathUtils.IsValid(RefLimb.body.SimPosition))
{
int a = 1;
}
foreach (Limb l in Limbs)
{
if (l==RefLimb) continue;

View File

@@ -240,7 +240,7 @@ namespace Subsurface.Items.Components
{
if (!isStuck)
{
OpenState += deltaTime * ((isOpen) ? 2.0f : -1.0f);
OpenState += deltaTime * ((isOpen) ? 2.0f : -2.0f);
LinkedGap.Open = openState;
}

View File

@@ -221,7 +221,7 @@ namespace Subsurface.Items.Components
AnimController ac = picker.AnimController;
//item.sprite.Depth = picker.AnimController.GetLimb(LimbType.RightHand).sprite.Depth + 0.01f;
//item.sprite.Depth = picker.AnimController.GetLimb(LimbType.RightHand).sprite.Depth + 0.01f;
ac.HoldItem(deltaTime, item, handlePos, holdPos, aimPos, picker.GetInputState(InputType.SecondaryHeld), holdAngle);
}

View File

@@ -111,11 +111,11 @@ namespace Subsurface.Items.Components
Vector2 targetPosition = item.body.SimPosition;
//targetPosition = targetPosition.X, -targetPosition.Y);
float degreeOfSuccess = DegreeOfSuccess(character);
float degreeOfSuccess = DegreeOfSuccess(character)/100.0f;
if (Rand.Range(0.0f, 1.0f) > degreeOfSuccess * degreeOfSuccess)
if (Rand.Range(0.0f, 0.5f) > degreeOfSuccess)
{
ApplyStatusEffects(ActionType.OnFailure, 1.0f, character);
ApplyStatusEffects(ActionType.OnFailure, deltaTime, character);
return false;
}
@@ -147,7 +147,7 @@ namespace Subsurface.Items.Components
targetStructure.HighLightSection(sectionIndex);
targetStructure.AddDamage(sectionIndex, -structureFixAmount);
targetStructure.AddDamage(sectionIndex, -structureFixAmount*degreeOfSuccess);
//if the next section is small enough, apply the effect to it as well
//(to make it easier to fix a small "left-over" section)
@@ -155,7 +155,7 @@ namespace Subsurface.Items.Components
if (nextSectionLength > 0 && nextSectionLength < Structure.wallSectionSize * 0.3f)
{
targetStructure.HighLightSection(sectionIndex + 1);
targetStructure.AddDamage(sectionIndex + 1, -structureFixAmount);
targetStructure.AddDamage(sectionIndex + 1, -structureFixAmount * degreeOfSuccess);
}
}
@@ -163,7 +163,7 @@ namespace Subsurface.Items.Components
{
if (character.GetInputState(InputType.SecondaryHeld))
{
targetLimb.character.Health += limbFixAmount;
targetLimb.character.Health += limbFixAmount * degreeOfSuccess;
//isActive = true;
}
}

View File

@@ -277,12 +277,12 @@ namespace Subsurface.Items.Components
private int loopingSoundIndex;
public void PlaySound(ActionType type, Vector2 position)
{
List<ItemSound> matchingSounds = sounds.FindAll(x => x.Type == type);
if (matchingSounds.Count == 0) return;
ItemSound itemSound = null;
if (!Sounds.SoundManager.IsPlaying(loopingSoundIndex))
{
List<ItemSound> matchingSounds = sounds.FindAll(x => x.Type == type);
if (matchingSounds.Count == 0) return;
int index = Rand.Int(matchingSounds.Count);
itemSound = matchingSounds[index];
}

View File

@@ -151,7 +151,6 @@ namespace Subsurface.Items.Components
}
}
item.body.FarseerBody.OnCollision -= OnProjectileCollision;
item.body.FarseerBody.IsBullet = false;
@@ -181,17 +180,21 @@ namespace Subsurface.Items.Components
}
var containedItems = item.ContainedItems;
if (containedItems == null) return true;
foreach (Item contained in containedItems)
if (containedItems != null)
{
if (contained.body != null)
foreach (Item contained in containedItems)
{
contained.SetTransform(item.SimPosition, contained.body.Rotation);
if (contained.body != null)
{
contained.SetTransform(item.SimPosition, contained.body.Rotation);
}
contained.Condition = 0.0f;
}
contained.Condition = 0.0f;
}
return false;
return (f2.CollisionCategories != Physics.CollisionCharacter);
//return false;
}
private bool StickToTarget(Body targetBody, Vector2 axis)

View File

@@ -108,7 +108,12 @@ namespace Subsurface
protected void PutItem(Item item, int i, bool createNetworkEvent, bool removeItem = true)
{
if (item.inventory != null && removeItem) item.inventory.RemoveItem(item);
if (item.inventory != null && removeItem)
{
item.Drop();
item.inventory.RemoveItem(item);
}
items[i] = item;
item.inventory = this;
if (item.body!=null)

View File

@@ -482,7 +482,11 @@ namespace Subsurface
{
if (ic.Parent != null) ic.IsActive = ic.Parent.IsActive;
if (ic.WasUsed) ic.StopSounds(ActionType.OnUse);
if (!ic.WasUsed)
{
ic.StopSounds(ActionType.OnUse);
}
ic.WasUsed = false;
if (!ic.IsActive) continue;
@@ -861,8 +865,8 @@ namespace Subsurface
{
ic.WasUsed = true;
ic.PlaySound(ActionType.OnUse, Position);
ic.PlaySound(ActionType.OnUse, body==null ? Position : ConvertUnits.ToDisplayUnits(body.SimPosition));
ic.ApplyStatusEffects(ActionType.OnUse, deltaTime, character);
if (ic.DeleteOnUse) remove = true;

View File

@@ -85,30 +85,7 @@ namespace Subsurface
if (attack.GetStructureDamage(1.0f) > 0.0f)
{
List<Structure> structureList = new List<Structure>();
float dist = 600.0f;
foreach (MapEntity entity in MapEntity.mapEntityList)
{
Structure structure = entity as Structure;
if (structure == null) continue;
if (structure.HasBody &&
!structure.IsPlatform &&
Vector2.Distance(structure.Position, displayPosition) < dist*3.0f)
{
structureList.Add(structure);
}
}
foreach (Structure structure in structureList)
{
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, attack.GetStructureDamage(1.0f)*distFactor);
}
}
RangedStructureDamage(displayPosition, displayRange, attack.GetStructureDamage(1.0f));
}
if (force == 0.0f && attack.Stun == 0.0f && attack.GetDamage(1.0f) == 0.0f) return;
@@ -154,5 +131,34 @@ namespace Subsurface
yield return CoroutineStatus.Success;
}
public static void RangedStructureDamage(Vector2 displayPosition, float displayRange, float damage)
{
List<Structure> structureList = new List<Structure>();
float dist = 600.0f;
foreach (MapEntity entity in MapEntity.mapEntityList)
{
Structure structure = entity as Structure;
if (structure == null) continue;
if (structure.HasBody &&
!structure.IsPlatform &&
Vector2.Distance(structure.Position, displayPosition) < dist * 3.0f)
{
structureList.Add(structure);
}
}
foreach (Structure structure in structureList)
{
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, damage * distFactor);
}
}
}
}
}

View File

@@ -222,7 +222,7 @@ namespace Subsurface
for (int i = 0; i < waveY.Length; i++)
{
float maxDelta = Math.Max(Math.Abs(rightDelta[i]), Math.Abs(leftDelta[i]));
if (maxDelta > Rand.Range(0.2f,10.0f))
if (maxDelta > Rand.Range(1.0f,10.0f))
{
GameMain.ParticleManager.CreateParticle("mist",
new Vector2(rect.X + WaveWidth * i,surface + waveY[i]),

View File

@@ -388,7 +388,9 @@ namespace Subsurface
{
if (!prefab.HasBody || prefab.IsPlatform) return;
if (GameMain.Client==null)
if (sectionIndex < 0 || sectionIndex > sections.Length - 1) return;
if (GameMain.Client == null)
SetDamage(sectionIndex, sections[sectionIndex].damage + damage);
}

View File

@@ -314,21 +314,21 @@ namespace Subsurface
return closestBody;
}
public static Body PickBody(Vector2 point)
{
Body foundBody = null;
AABB aabb = new AABB(point, point);
//public static Body PickBody(Vector2 point)
//{
// Body foundBody = null;
// AABB aabb = new AABB(point, point);
GameMain.World.QueryAABB(p =>
{
foundBody = p.Body;
// GameMain.World.QueryAABB(p =>
// {
// foundBody = p.Body;
return true;
// return true;
}, ref aabb);
// }, ref aabb);
return foundBody;
}
// return foundBody;
//}
//public static bool InsideWall(Vector2 point)
//{
@@ -348,7 +348,7 @@ namespace Subsurface
{
if (Level.Loaded == null) return;
subBody.Update(deltaTime);
if (subBody!=null) subBody.Update(deltaTime);
}
public void ApplyForce(Vector2 force)

View File

@@ -16,7 +16,11 @@ namespace Subsurface
{
class SubmarineBody
{
//structure damage = impact * damageMultiplier
const float DamageMultiplier = 50.0f;
const float Friction = 0.2f, Restitution = 0.0f;
public List<Vector2> HullVertices
{
get;
@@ -30,6 +34,11 @@ namespace Subsurface
private Vector2 speed;
private Vector2 targetPosition;
float mass = 10000.0f;
private Vector2? lastContactPoint;
private VoronoiCell lastContactCell;
public Rectangle Borders
{
@@ -103,7 +112,7 @@ namespace Subsurface
body.SleepingAllowed = false;
body.IgnoreGravity = true;
body.OnCollision += OnCollision;
//body.OnSeparation += OnSeparation;
body.OnSeparation += OnSeparation;
body.UserData = this;
}
@@ -163,7 +172,12 @@ namespace Subsurface
public void Update(float deltaTime)
{
Vector2 translateAmount = speed * deltaTime;
if (body.Position!=Vector2.Zero)
{
UpdateColliding();
}
Vector2 translateAmount = speed * deltaTime;
translateAmount += ConvertUnits.ToDisplayUnits(body.Position) * collisionRigidness;
if (targetPosition != Vector2.Zero && Vector2.Distance(targetPosition, sub.Position) > 50.0f)
@@ -181,14 +195,14 @@ namespace Subsurface
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)
if (speed.LengthSquared() > 0.000001f)
{
totalForce += -Vector2.Normalize(speed) * drag;
float dragCoefficient = 0.00001f;
float speedLength = (speed == Vector2.Zero) ? 0.0f : speed.Length();
float drag = speedLength * speedLength * dragCoefficient * mass;
totalForce += -Vector2.Normalize(speed) * drag;
}
ApplyForce(totalForce);
@@ -215,35 +229,39 @@ namespace Subsurface
float neutralPercentage = 0.07f;
float buoyancy = neutralPercentage - waterPercentage;
float buoyancy = Math.Max(neutralPercentage - waterPercentage, -neutralPercentage*2.0f);
buoyancy *= mass * 30.0f;
return new Vector2(0.0f, buoyancy);
}
float mass = 10000.0f;
public void ApplyForce(Vector2 force)
{
speed += force / mass;
Speed += force / mass;
}
public bool OnCollision(Fixture f1, Fixture f2, Contact contact)
private void UpdateColliding()
{
VoronoiCell cell = f2.Body.UserData as VoronoiCell;
if (cell == null)
{
speed = new Vector2(speed.X * 0.9f, speed.Y * 0.2f);
return true;
}
if (body.Position.LengthSquared()<0.00001f) return;
Vector2 normal = contact.Manifold.LocalNormal;
Vector2 simSpeed = ConvertUnits.ToSimUnits(speed) + body.LinearVelocity;
float impact = Vector2.Dot(simSpeed, normal);
Vector2 normal = Vector2.Normalize(body.Position);
Vector2 simSpeed = ConvertUnits.ToSimUnits(speed);
Vector2 u = Vector2.Dot(simSpeed, -normal) * -normal;
Vector2 w = simSpeed - u;
float impact = Vector2.Dot(simSpeed, -normal);
Vector2 limbForce = normal * impact;
if (impact < 0.0f) return;
Vector2 u = Vector2.Dot(simSpeed, -normal) * normal;
Vector2 w = (simSpeed + u);
speed = ConvertUnits.ToDisplayUnits(w * (1.0f - Friction) + u * Restitution);
if (lastContactPoint == null || lastContactCell==null || impact < 3.0f) return;
AmbientSoundManager.PlayDamageSound(DamageSoundType.StructureBlunt, impact * 10.0f, ConvertUnits.ToDisplayUnits((Vector2)lastContactPoint));
GameMain.GameScreen.Cam.Shake = impact * 2.0f;
Vector2 limbForce = -normal * impact*0.5f;
float length = limbForce.Length();
if (length > 10.0f) limbForce = (limbForce / length) * 10.0f;
@@ -261,66 +279,125 @@ namespace Subsurface
}
}
if (impact >= 1.0f)
{
AmbientSoundManager.PlayDamageSound(DamageSoundType.StructureBlunt, impact * 10.0f, cell.body);
Explosion.RangedStructureDamage(ConvertUnits.ToDisplayUnits((Vector2)lastContactPoint), impact*50.0f, impact*DamageMultiplier);
FarseerPhysics.Common.FixedArray2<Vector2> worldPoints;
contact.GetWorldManifold(out normal, out worldPoints);
//Body wallBody = Submarine.PickBody(
// (Vector2)lastContactPoint - body.Position,
// (Vector2)lastContactPoint + body.Position * 10.0f,
// new List<Body>() { lastContactCell.body });
AmbientSoundManager.PlayDamageSound(DamageSoundType.StructureBlunt, impact * 10.0f, ConvertUnits.ToDisplayUnits(worldPoints[0]));
//if (wallBody == null || wallBody.UserData == null) return;
//var damageable = wallBody.UserData as IDamageable;
//Structure structure = wallBody.UserData as Structure;
GameMain.GameScreen.Cam.Shake = impact * 2.0f;
}
//if (structure == null) return;
//int sectionIndex = structure.FindSectionIndex(ConvertUnits.ToDisplayUnits(Submarine.LastPickedPosition));
System.Diagnostics.Debug.WriteLine("IMPACT: " + impact + " normal: " + normal + " simspeed: " + simSpeed + " u: " + u + " w: " + w);
if (impact < 3.0f)
{
speed = ConvertUnits.ToDisplayUnits(w * 0.45f - u * 0.25f);
return true;
}
else
{
speed = ConvertUnits.ToDisplayUnits(w * 0.9f + u * 0.5f);
//FixedArray2<Vector2> worldPoints;
//contact.GetWorldManifold(out normal, out worldPoints);
//if (contact.Manifold.PointCount >= 1)
//{
// Vector2 contactPoint = worldPoints[0];
// Body wallBody = Submarine.PickBody(contactPoint, contactPoint + normal, new List<Body>() { cell.body });
// if (wallBody!=null && wallBody.UserData!=null)
// {
// Structure s = wallBody.UserData as Structure;
// }
//}
foreach (GraphEdge ge in cell.edges)
{
Body wallBody = Submarine.PickBody(
ConvertUnits.ToSimUnits(ge.point1 + GameMain.GameSession.Level.Position + normal),
ConvertUnits.ToSimUnits(ge.point2 + GameMain.GameSession.Level.Position + normal), new List<Body>() { cell.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)), impact*50.0f);
}
}
collisionRigidness = 0.8f;
return true;
//for (int i = sectionIndex - (int)(impact / 5.0f); i < sectionIndex + (int)(impact / 5.0f); i++)
//{
// structure.AddDamage(i, impact * DamageMultiplier);
//}
}
//public void OnSeparation(Fixture f1, Fixture f2)
//{
// collidingCell = null;
//}
public bool OnCollision(Fixture f1, Fixture f2, Contact contact)
{
VoronoiCell cell = f2.Body.UserData as VoronoiCell;
if (cell == null)
{
lastContactCell = null;
lastContactPoint = null;
return true;
}
lastContactCell = cell;
Vector2 normal;
FarseerPhysics.Common.FixedArray2<Vector2> worldPoints;
contact.GetWorldManifold(out normal, out worldPoints);
lastContactPoint = worldPoints[0];
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);
//// }
////}
//System.Diagnostics.Debug.WriteLine("IMPACT: " + impact + " normal: " + normal + " simspeed: " + simSpeed);
//if (impact > 1.0f)
//{
// contact.GetWorldManifold(out normal, out worldPoints);
// lastContactPoint = worldPoints[0];
// AmbientSoundManager.PlayDamageSound(DamageSoundType.StructureBlunt, impact * 10.0f, ConvertUnits.ToDisplayUnits(worldPoints[0]));
// GameMain.GameScreen.Cam.Shake = impact * 2.0f;
// //speed = ConvertUnits.ToDisplayUnits(w * 0.9f + u * 0.5f);
// //FixedArray2<Vector2> worldPoints;
// //contact.GetWorldManifold(out normal, out worldPoints);
// //if (contact.Manifold.PointCount >= 1)
// //{
// // Vector2 contactPoint = worldPoints[0];
// // Body wallBody = Submarine.PickBody(contactPoint, contactPoint + normal, new List<Body>() { cell.body });
// // if (wallBody!=null && wallBody.UserData!=null)
// // {
// // Structure s = wallBody.UserData as Structure;
// // }
// //}
// //foreach (GraphEdge ge in cell.edges)
// //{
// // Body wallBody = Submarine.PickBody(
// // ConvertUnits.ToSimUnits(ge.point1 + GameMain.GameSession.Level.Position + normal),
// // ConvertUnits.ToSimUnits(ge.point2 + GameMain.GameSession.Level.Position + normal), new List<Body>() { cell.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)), impact*50.0f);
// //}
//}
//collisionRigidness = 0.8f;
//return true;
}
public void OnSeparation(Fixture f1, Fixture f2)
{
lastContactPoint = null;
}
}
}

View File

@@ -216,6 +216,12 @@ namespace Subsurface.Networking
inGameHUD.Update(deltaTime);
if (crewFrameOpen) crewFrame.Update(deltaTime);
if (Character.Controlled != null && Character.Controlled.IsDead)
{
GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
GameMain.LightManager.LosEnabled = false;
}
}
if (PlayerInput.KeyHit(Keys.Tab))

View File

@@ -54,8 +54,8 @@ namespace Subsurface.Particles
public Particle CreateParticle(ParticlePrefab prefab, Vector2 position, Vector2 speed, float rotation=0.0f)
{
//if (!Submarine.RectContains(cam.WorldView, position)) return null;
if (!cam.WorldView.Contains(position)) return null;
if (!Submarine.RectContains(cam.WorldView, position)) return null;
//if (!cam.WorldView.Contains(position)) return null;
if (particleCount >= MaxParticles) return null;

View File

@@ -47,6 +47,13 @@ namespace Subsurface
entity.IsHighlighted = false;
}
public override void Deselect()
{
base.Deselect();
Sounds.SoundManager.LowPassHFGain = 1.0f;
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
@@ -60,16 +67,16 @@ namespace Subsurface
AmbientSoundManager.Update();
//if (Game1.GameSession != null && Game1.GameSession.Level != null)
//{
// Vector2 targetMovement = Vector2.Zero;
// if (PlayerInput.KeyDown(Keys.I)) targetMovement.Y += 1.0f;
// if (PlayerInput.KeyDown(Keys.K)) targetMovement.Y -= 1.0f;
// if (PlayerInput.KeyDown(Keys.J)) targetMovement.X -= 1.0f;
// if (PlayerInput.KeyDown(Keys.L)) targetMovement.X += 1.0f;
if (GameMain.GameSession != null && GameMain.GameSession.Level != null)
{
Vector2 targetMovement = Vector2.Zero;
if (PlayerInput.KeyDown(Keys.I)) targetMovement.Y += 1.0f;
if (PlayerInput.KeyDown(Keys.K)) targetMovement.Y -= 1.0f;
if (PlayerInput.KeyDown(Keys.J)) targetMovement.X -= 1.0f;
if (PlayerInput.KeyDown(Keys.L)) targetMovement.X += 1.0f;
// Game1.GameSession.Submarine.ApplyForce(targetMovement * 100000.0f);
//}
GameMain.GameSession.Submarine.ApplyForce(targetMovement * 100000.0f);
}
if (GameMain.GameSession!=null) GameMain.GameSession.Update((float)deltaTime);
//EventManager.Update(gameTime);
@@ -99,7 +106,7 @@ namespace Subsurface
Ragdoll.UpdateAll(cam, (float)Physics.step);
if (GameMain.GameSession != null && GameMain.GameSession.Level != null)
if (GameMain.GameSession != null && GameMain.GameSession.Level != null && GameMain.GameSession.Submarine!=null)
{
GameMain.GameSession.Submarine.Update((float)Physics.step);
}

View File

@@ -47,10 +47,14 @@ namespace Subsurface.Sounds
public static void Check()
{
#if !DEBUG
return;
#endif
ALError error;
if ((error = AL.GetError()) != ALError.NoError)
{
DebugConsole.ThrowError(AL.GetErrorString(error));
DebugConsole.ThrowError("OpenAL error: "+AL.GetErrorString(error));
}
}
}

View File

@@ -77,6 +77,8 @@ namespace Subsurface
public int Play(float volume = 1.0f)
{
if (volume <= 0.0f) return -1;
alSourceId = SoundManager.Play(this, volume);
return alSourceId;
}
@@ -90,7 +92,9 @@ namespace Subsurface
Vector2 relativePos = GetRelativePosition(position);
float volume = GetVolume(relativePos, range, baseVolume);
alSourceId = SoundManager.Play(this, relativePos, volume, volume);
if (volume <= 0.0f) return -1;
alSourceId = SoundManager.Play(this, relativePos, volume);
return alSourceId;

View File

@@ -44,7 +44,7 @@ namespace Subsurface.Sounds
//alFilters.Add(alFilterId);
ALHelper.Efx.Filter(lowpassFilterId, OpenTK.Audio.OpenAL.EfxFilteri.FilterType, (int)OpenTK.Audio.OpenAL.EfxFilterType.Lowpass);
//LowPassHFGain = 1;
LowPassHFGain = 1.0f;
}
@@ -115,7 +115,7 @@ namespace Subsurface.Sounds
//return -1;
}
public static int Play(Sound sound, Vector2 position, float volume = 1.0f, float lowPassGain = 0.0f)
public static int Play(Sound sound, Vector2 position, float volume = 1.0f, float lowPassGain = 0.0f, bool loop=false)
{
//for (int i = 2; i < DefaultSourceCount; i++)
//{
@@ -137,26 +137,19 @@ namespace Subsurface.Sounds
// position /= 1000.0f;
alBuffers[i] = sound.AlBufferId;
OpenTK.Audio.OpenAL.AL.Source(alSources[i], OpenTK.Audio.OpenAL.ALSourceb.Looping, false);
OpenTK.Audio.OpenAL.AL.Source(alSources[i], OpenTK.Audio.OpenAL.ALSourceb.Looping, loop);
OpenTK.Audio.OpenAL.AL.Source(alSources[i], OpenTK.Audio.OpenAL.ALSourcei.Buffer, sound.AlBufferId);
UpdateSoundPosition(i, position, volume);
//position /= 1000.0f;
////System.Diagnostics.Debug.WriteLine("updatesoundpos: "+offset);
//OpenTK.Audio.OpenAL.AL.Source(alSources[i], OpenTK.Audio.OpenAL.ALSourcef.Gain, volume);
//OpenTK.Audio.OpenAL.AL.Source(alSources[i], OpenTK.Audio.OpenAL.ALSource3f.Position, position.X, position.Y, 0.0f);
//ALHelper.Efx.Filter(lowpassFilterId, OpenTK.Audio.OpenAL.EfxFilterf.LowpassGainHF, lowPassHfGain);
//ALHelper.Efx.BindFilterToSource(alSources[i], lowpassFilterId);
//ALHelper.Check();
//AL.Source(alSources[i], ALSource3f.Position, position.X, position.Y, 0.0f);
OpenTK.Audio.OpenAL.AL.SourcePlay(alSources[i]);
//sound.sourceIndex = i;
return i;
@@ -171,14 +164,19 @@ namespace Subsurface.Sounds
}
public static int Loop(Sound sound, int sourceIndex, Vector2 position, float volume = 1.0f)
{
if (!MathUtils.IsValid(volume))
{
volume = 0.0f;
}
if (sourceIndex<1)
{
sourceIndex = Play(sound, position, volume);
if (sourceIndex>0)
{
AL.Source(alSources[sourceIndex], ALSourceb.Looping, true);
AL.Source(alSources[sourceIndex], ALSourcef.Gain, volume);
}
sourceIndex = Play(sound, position, volume, 0.0f, true);
//if (sourceIndex>0)
//{
// AL.Source(alSources[sourceIndex], ALSourceb.Looping, true);
// AL.Source(alSources[sourceIndex], ALSourcef.Gain, volume);
//}
ALHelper.Check();
return sourceIndex;
}
@@ -233,7 +231,7 @@ namespace Subsurface.Sounds
public static void Stop(int sourceIndex)
{
if (sourceIndex < 1) return;
var state = AL.GetSourceState(alSources[sourceIndex]);
if (state == ALSourceState.Playing || state == ALSourceState.Paused)
{
@@ -296,19 +294,25 @@ namespace Subsurface.Sounds
{
if (sourceIndex < 1) return;
if (!MathUtils.IsValid(position))
{
position = Vector2.Zero;
}
//Resume(sourceIndex);
position/= 1000.0f;
//System.Diagnostics.Debug.WriteLine("updatesoundpos: "+offset);
OpenTK.Audio.OpenAL.AL.Source(alSources[sourceIndex], OpenTK.Audio.OpenAL.ALSourcef.Gain, baseVolume);
OpenTK.Audio.OpenAL.AL.Source(alSources[sourceIndex], OpenTK.Audio.OpenAL.ALSource3f.Position, position.X, position.Y, 0.0f);
float lowPassGain = lowPassHfGain / Math.Max(position.Length()*5.0f,1.0f);
float lowPassGain = lowPassHfGain / Math.Max(position.Length() * 5.0f, 1.0f);
ALHelper.Efx.Filter(lowpassFilterId, OpenTK.Audio.OpenAL.EfxFilterf.LowpassGainHF, lowPassGain);
ALHelper.Efx.BindFilterToSource(alSources[sourceIndex], lowpassFilterId);
ALHelper.Check();
}
public static OggStream StartStream(string file, float volume = 1.0f)

View File

@@ -911,6 +911,12 @@
<None Include="Content\Sounds\Music\Enter the Maze.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Content\Sounds\Music\Static Motion.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Content\Sounds\Music\Tenebrous Brothers Carnival - Prelude.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Content\Sounds\Music\Unseen Horrors.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>

Binary file not shown.