electricity bugfixes, destructable doors, ai improvements, removed rope, container changes
This commit is contained in:
@@ -5,6 +5,7 @@ using System.Xml.Linq;
|
||||
using FarseerPhysics;
|
||||
using Lidgren.Network;
|
||||
using Microsoft.Xna.Framework;
|
||||
using FarseerPhysics.Dynamics;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
@@ -41,7 +42,7 @@ namespace Subsurface
|
||||
//a point in a wall which the character is currently targeting
|
||||
private Vector2 wallAttackPos;
|
||||
//the entity (a wall) which the character is targeting
|
||||
private MapEntity targetEntity;
|
||||
private IDamageable targetEntity;
|
||||
|
||||
//the limb selected for the current attack
|
||||
private Limb attackingLimb;
|
||||
@@ -157,23 +158,7 @@ namespace Subsurface
|
||||
|
||||
if (coolDownTimer>0.0f)
|
||||
{
|
||||
coolDownTimer -= deltaTime;
|
||||
|
||||
//System.Diagnostics.Debug.WriteLine("cooldown");
|
||||
|
||||
if (selectedTarget.entity is Hull ||
|
||||
Vector2.Distance(attackPosition, character.animController.limbs[0].SimPosition)<ConvertUnits.ToSimUnits(500.0f))
|
||||
{
|
||||
steeringManager.SteeringSeek(attackPosition, -0.8f);
|
||||
steeringManager.SteeringAvoid(deltaTime, 1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
steeringManager.SteeringSeek(attackPosition, -0.5f);
|
||||
steeringManager.SteeringAvoid(deltaTime, 1.0f);
|
||||
|
||||
}
|
||||
|
||||
UpdateCoolDown(attackPosition, deltaTime);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -183,45 +168,7 @@ namespace Subsurface
|
||||
}
|
||||
else
|
||||
{
|
||||
targetEntity = null;
|
||||
//check if there's a wall between the target and the character
|
||||
Vector2 rayStart = character.animController.limbs[0].SimPosition;
|
||||
Vector2 rayEnd = selectedTarget.Position;
|
||||
Structure closestStructure = Map.CheckVisibility(rayStart, rayEnd);
|
||||
if (Map.LastPickedFraction == 1.0f || closestStructure == null)
|
||||
{
|
||||
wallAttackPos = Vector2.Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
Structure wall = closestStructure as Structure;
|
||||
if (wall==null)
|
||||
{
|
||||
wallAttackPos = Map.LastPickedPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
int sectionIndex = wall.FindSectionIndex(ConvertUnits.ToDisplayUnits(Map.LastPickedPosition));
|
||||
|
||||
float sectionDamage = wall.SectionDamage(sectionIndex);
|
||||
for (int i = sectionIndex-2; i<=sectionIndex+2; i++)
|
||||
{
|
||||
if (wall.SectionHasHole(i))
|
||||
{
|
||||
sectionIndex = i;
|
||||
break;
|
||||
}
|
||||
if (wall.SectionDamage(i) > sectionDamage) sectionIndex = i;
|
||||
}
|
||||
wallAttackPos = wall.SectionPosition(sectionIndex);
|
||||
wallAttackPos = ConvertUnits.ToSimUnits(wallAttackPos);
|
||||
}
|
||||
|
||||
|
||||
targetEntity = closestStructure;
|
||||
}
|
||||
GetTargetEntity();
|
||||
|
||||
raycastTimer = RaycastInterval;
|
||||
}
|
||||
@@ -246,13 +193,68 @@ namespace Subsurface
|
||||
|
||||
}
|
||||
|
||||
private void UpdateCoolDown(Vector2 attackPosition, float deltaTime)
|
||||
{
|
||||
coolDownTimer -= deltaTime;
|
||||
attackingLimb = null;
|
||||
|
||||
//System.Diagnostics.Debug.WriteLine("cooldown");
|
||||
|
||||
if (selectedTarget.entity is Hull ||
|
||||
Vector2.Distance(attackPosition, character.animController.limbs[0].SimPosition) < ConvertUnits.ToSimUnits(500.0f))
|
||||
{
|
||||
steeringManager.SteeringSeek(attackPosition, -0.8f);
|
||||
steeringManager.SteeringAvoid(deltaTime, 1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
steeringManager.SteeringSeek(attackPosition, -0.5f);
|
||||
steeringManager.SteeringAvoid(deltaTime, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
private void GetTargetEntity()
|
||||
{
|
||||
targetEntity = null;
|
||||
//check if there's a wall between the target and the character
|
||||
Vector2 rayStart = character.animController.limbs[0].SimPosition;
|
||||
Vector2 rayEnd = selectedTarget.Position;
|
||||
Body closestBody = Map.CheckVisibility(rayStart, rayEnd);
|
||||
|
||||
if (Map.LastPickedFraction == 1.0f || closestBody == null)
|
||||
{
|
||||
wallAttackPos = Vector2.Zero;
|
||||
return;
|
||||
}
|
||||
|
||||
Structure wall = closestBody.UserData as Structure;
|
||||
if (wall == null)
|
||||
{
|
||||
wallAttackPos = Map.LastPickedPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
int sectionIndex = wall.FindSectionIndex(ConvertUnits.ToDisplayUnits(Map.LastPickedPosition));
|
||||
|
||||
float sectionDamage = wall.SectionDamage(sectionIndex);
|
||||
for (int i = sectionIndex - 2; i <= sectionIndex + 2; i++)
|
||||
{
|
||||
if (wall.SectionHasHole(i))
|
||||
{
|
||||
sectionIndex = i;
|
||||
break;
|
||||
}
|
||||
if (wall.SectionDamage(i) > sectionDamage) sectionIndex = i;
|
||||
}
|
||||
wallAttackPos = wall.SectionPosition(sectionIndex);
|
||||
wallAttackPos = ConvertUnits.ToSimUnits(wallAttackPos);
|
||||
}
|
||||
|
||||
targetEntity = closestBody.UserData as IDamageable;
|
||||
}
|
||||
|
||||
private void UpdateLimbAttack(float deltaTime, Limb limb, Vector2 attackPosition)
|
||||
{
|
||||
//DamageType damageType = DamageType.None;
|
||||
// float damage = 0.0f;
|
||||
|
||||
//bool hasAttacked = false;
|
||||
|
||||
IDamageable damageTarget = null;
|
||||
|
||||
switch (limb.attack.type)
|
||||
@@ -310,21 +312,14 @@ namespace Subsurface
|
||||
attackTimer = 0.0f;
|
||||
if (Vector2.Distance(limb.SimPosition, attackPosition)<5.0) coolDownTimer = attackCoolDown;
|
||||
|
||||
System.Diagnostics.Debug.WriteLine("cooldown: " + coolDownTimer);
|
||||
}
|
||||
}
|
||||
|
||||
//private float GetAttackDamage(Limb limb, float deltaTime)
|
||||
//{
|
||||
// return (limb.attack.duration == 0.0f) ? limb.attack.damage : limb.attack.damage * deltaTime;
|
||||
//}
|
||||
|
||||
|
||||
//goes through all the AItargets, evaluates how preferable it is to attack the target,
|
||||
//whether the character can see/hear the target and chooses the most preferable target within
|
||||
//sight/hearing range
|
||||
public void UpdateTargets(Character character)
|
||||
{
|
||||
|
||||
if (distanceAccumulator<5.0f && Game1.random.Next(1,3)==1)
|
||||
{
|
||||
selectedTarget = null;
|
||||
@@ -344,6 +339,9 @@ namespace Subsurface
|
||||
{
|
||||
float valueModifier = 0.0f;
|
||||
float dist = 0.0f;
|
||||
|
||||
IDamageable targetDamageable = target.entity as IDamageable;
|
||||
if (targetDamageable!=null && targetDamageable.Health <= 0.0f) continue;
|
||||
|
||||
Character targetCharacter = target.entity as Character;
|
||||
|
||||
@@ -371,30 +369,49 @@ namespace Subsurface
|
||||
|
||||
AITargetMemory targetMemory = FindTargetMemory(target);
|
||||
|
||||
valueModifier *= targetMemory.Priority;
|
||||
valueModifier = valueModifier * targetMemory.Priority / dist;
|
||||
//dist -= targetMemory.Priority;
|
||||
|
||||
if (valueModifier != 0.0f && (dist < target.SightRange * sight || dist < target.SoundRange * hearing))
|
||||
{
|
||||
//if the target is a character, check if it is visible
|
||||
if (Math.Abs(valueModifier) > Math.Abs(this.targetValue) && (dist < target.SightRange * sight || dist < target.SoundRange * hearing))
|
||||
{
|
||||
Vector2 rayStart = character.animController.limbs[0].SimPosition;
|
||||
Vector2 rayEnd = target.Position;
|
||||
|
||||
Body closestBody = Map.CheckVisibility(rayStart, rayEnd);
|
||||
Structure closestStructure = (closestBody == null) ? null : closestBody.UserData as Structure;
|
||||
|
||||
if (targetCharacter != null)
|
||||
{
|
||||
Vector2 rayStart = character.animController.limbs[0].SimPosition;
|
||||
Vector2 rayEnd = target.Position;
|
||||
|
||||
Structure closestStructure = Map.CheckVisibility(rayStart, rayEnd);
|
||||
//System.Diagnostics.Debug.WriteLine("closestfraction: " + closestFraction);
|
||||
//if not visible, ignore this AItarget
|
||||
//if target is a character that isn't visible, ignore
|
||||
if (closestStructure != null) continue;
|
||||
}
|
||||
|
||||
float newTargetValue = valueModifier/dist;
|
||||
if (selectedTarget == null || Math.Abs(newTargetValue) > Math.Abs(this.targetValue))
|
||||
//prefer targets with low health
|
||||
valueModifier = valueModifier / targetCharacter.Health;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (targetDamageable != null)
|
||||
{
|
||||
valueModifier = valueModifier / targetDamageable.Health;
|
||||
|
||||
}
|
||||
else if (closestStructure!=null)
|
||||
{
|
||||
valueModifier = valueModifier / (closestStructure as IDamageable).Health;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//float newTargetValue = valueModifier/dist;
|
||||
if (selectedTarget == null || Math.Abs(valueModifier) > Math.Abs(this.targetValue))
|
||||
{
|
||||
selectedTarget = target;
|
||||
selectedTargetMemory = targetMemory;
|
||||
targetValue = newTargetValue;
|
||||
Debug.WriteLine(selectedTarget);
|
||||
|
||||
this.targetValue = valueModifier;
|
||||
Debug.WriteLine(selectedTarget.entity+": "+targetValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -449,7 +466,7 @@ namespace Subsurface
|
||||
message.Write(raycastTimer);
|
||||
message.Write(coolDownTimer);
|
||||
|
||||
message.Write(targetEntity==null ? -1 : targetEntity.ID);
|
||||
message.Write(targetEntity==null ? -1 : (targetEntity as Entity).ID);
|
||||
}
|
||||
|
||||
public override void ReadNetworkData(NetIncomingMessage message)
|
||||
@@ -472,7 +489,7 @@ namespace Subsurface
|
||||
this.coolDownTimer = coolDownTimer;
|
||||
|
||||
if (targetID>-1)
|
||||
targetEntity = Entity.FindEntityByID(targetID) as MapEntity;
|
||||
targetEntity = Entity.FindEntityByID(targetID) as IDamageable;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using Microsoft.Xna.Framework;
|
||||
using FarseerPhysics.Dynamics;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
@@ -112,25 +113,29 @@ namespace Subsurface
|
||||
if (rayCastTimer <= 0.0f)
|
||||
{
|
||||
rayCastTimer = RayCastInterval;
|
||||
Structure closestStructure = Map.CheckVisibility(host.Position, ahead);
|
||||
if (closestStructure == null)
|
||||
Body closestBody = Map.CheckVisibility(host.Position, ahead);
|
||||
if (closestBody == null)
|
||||
{
|
||||
avoidSteering = Vector2.Zero;
|
||||
return Vector2.Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector2 obstaclePosition = Map.LastPickedPosition;
|
||||
if (closestStructure.IsHorizontal)
|
||||
Structure closestStructure = closestBody.UserData as Structure;
|
||||
if (closestStructure!=null)
|
||||
{
|
||||
obstaclePosition.Y = closestStructure.SimPosition.Y;
|
||||
}
|
||||
else
|
||||
{
|
||||
obstaclePosition.X = closestStructure.SimPosition.X;
|
||||
}
|
||||
Vector2 obstaclePosition = Map.LastPickedPosition;
|
||||
if (closestStructure.IsHorizontal)
|
||||
{
|
||||
obstaclePosition.Y = closestStructure.SimPosition.Y;
|
||||
}
|
||||
else
|
||||
{
|
||||
obstaclePosition.X = closestStructure.SimPosition.X;
|
||||
}
|
||||
|
||||
avoidSteering = Vector2.Normalize(Map.LastPickedPosition - obstaclePosition);
|
||||
avoidSteering = Vector2.Normalize(Map.LastPickedPosition - obstaclePosition);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -119,6 +119,20 @@ namespace Subsurface
|
||||
}
|
||||
}
|
||||
|
||||
public float Health
|
||||
{
|
||||
get
|
||||
{
|
||||
float totalHealth = 0.0f;
|
||||
foreach (Limb l in animController.limbs)
|
||||
{
|
||||
totalHealth += (l.MaxHealth - l.Damage);
|
||||
|
||||
}
|
||||
return totalHealth/animController.limbs.Count();
|
||||
}
|
||||
}
|
||||
|
||||
public float Blood
|
||||
{
|
||||
get { return blood; }
|
||||
@@ -637,29 +651,25 @@ namespace Subsurface
|
||||
Vector2 particleVel = closestLimb.SimPosition-position;
|
||||
if (particleVel != Vector2.Zero) particleVel = Vector2.Normalize(particleVel);
|
||||
|
||||
Game1.particleManager.CreateParticle(
|
||||
Game1.particleManager.CreateParticle("blood",
|
||||
closestLimb.SimPosition,
|
||||
ToolBox.RandomFloat(0.0f, 3.1f),
|
||||
particleVel * ToolBox.RandomFloat(1.0f,3.0f),
|
||||
"blood");
|
||||
particleVel * ToolBox.RandomFloat(1.0f,3.0f));
|
||||
}
|
||||
|
||||
for (int i = 0; i < bloodAmount / 2; i++)
|
||||
{
|
||||
Game1.particleManager.CreateParticle(closestLimb.SimPosition,
|
||||
0.0f,
|
||||
Vector2.Zero, "waterblood");
|
||||
Game1.particleManager.CreateParticle("waterblood",closestLimb.SimPosition,Vector2.Zero);
|
||||
}
|
||||
}
|
||||
|
||||
public void Stun()
|
||||
{
|
||||
for (int i = 0; i < selectedItems.Length; i++ )
|
||||
{
|
||||
if (selectedItems[i] == null) continue;
|
||||
selectedItems[i].Drop();
|
||||
selectedItems[i] = null;
|
||||
}
|
||||
//for (int i = 0; i < selectedItems.Length; i++ )
|
||||
//{
|
||||
// if (selectedItems[i] == null) continue;
|
||||
// selectedItems[i].Drop();
|
||||
// selectedItems[i] = null;
|
||||
//}
|
||||
|
||||
selectedConstruction = null;
|
||||
}
|
||||
@@ -691,17 +701,14 @@ namespace Subsurface
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
Particle p = Game1.particleManager.CreateParticle(
|
||||
Particle p = Game1.particleManager.CreateParticle("waterblood",
|
||||
torso.SimPosition + new Vector2(ToolBox.RandomFloat(-0.5f, 0.5f), ToolBox.RandomFloat(-0.5f, 0.5f)),
|
||||
0.0f,
|
||||
Vector2.Zero, "waterblood");
|
||||
Vector2.Zero);
|
||||
if (p!=null) p.Size *= 2.0f;
|
||||
|
||||
Game1.particleManager.CreateParticle(
|
||||
Game1.particleManager.CreateParticle("bubbles",
|
||||
torso.SimPosition,
|
||||
0.0f,
|
||||
new Vector2(ToolBox.RandomFloat(-0.5f, 0.5f), ToolBox.RandomFloat(-1.0f,0.5f)),
|
||||
"bubbles");
|
||||
new Vector2(ToolBox.RandomFloat(-0.5f, 0.5f), ToolBox.RandomFloat(-1.0f,0.5f)));
|
||||
}
|
||||
|
||||
foreach (var joint in animController.limbJoints)
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace Subsurface
|
||||
|
||||
if (!inWater) movement.Y = Math.Min(0.0f, movement.Y);
|
||||
|
||||
float movementAngle = ToolBox.VectorToAngle(movement)+MathHelper.PiOver2;
|
||||
float movementAngle = ToolBox.VectorToAngle(movement) - MathHelper.PiOver2;
|
||||
|
||||
Limb tail = GetLimb(LimbType.Tail);
|
||||
if (tail != null && waveAmplitude>0.0f)
|
||||
|
||||
@@ -129,6 +129,11 @@ namespace Subsurface
|
||||
}
|
||||
}
|
||||
|
||||
public float MaxHealth
|
||||
{
|
||||
get { return maxHealth; }
|
||||
}
|
||||
|
||||
public float Bleeding
|
||||
{
|
||||
get { return bleeding; }
|
||||
@@ -290,9 +295,9 @@ namespace Subsurface
|
||||
|
||||
if (ToolBox.RandomFloat(0.0f, 1000.0f) < Bleeding)
|
||||
{
|
||||
Game1.particleManager.CreateParticle(SimPosition,
|
||||
MathHelper.Pi,
|
||||
ToolBox.RandomFloat(0.0f, 0.0f), !inWater ? "blood" : "waterblood");
|
||||
Game1.particleManager.CreateParticle(
|
||||
!inWater ? "blood" : "waterblood",
|
||||
SimPosition, Vector2.Zero);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,15 +72,16 @@ namespace Subsurface
|
||||
float damageAmount = 0.0f;
|
||||
DamageSoundType damageSoundType = DamageSoundType.None;
|
||||
|
||||
if (target as Structure == null)
|
||||
{
|
||||
damageAmount = damage;
|
||||
damageSoundType = (damageType == DamageType.Blunt) ? DamageSoundType.LimbBlunt : DamageSoundType.LimbSlash;
|
||||
}
|
||||
else
|
||||
if (target as Character == null)
|
||||
{
|
||||
damageAmount = structureDamage;
|
||||
damageSoundType = (damageType == DamageType.Blunt) ? DamageSoundType.StructureBlunt: DamageSoundType.StructureSlash;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
damageAmount = damage;
|
||||
damageSoundType = (damageType == DamageType.Blunt) ? DamageSoundType.LimbBlunt : DamageSoundType.LimbSlash;
|
||||
}
|
||||
|
||||
if (playSound) AmbientSoundManager.PlayDamageSound(damageSoundType, damageAmount, position);
|
||||
|
||||
@@ -296,7 +296,7 @@ namespace Subsurface
|
||||
|
||||
Limb l = (Limb)f1.Body.UserData;
|
||||
|
||||
if (impact > 1.0f && l.HitSound != null && l.soundTimer<=0.0f) l.HitSound.Play(Math.Min(impact / 5.0f, 1.0f));
|
||||
if (impact > 1.0f && l.HitSound != null && l.soundTimer<=0.0f) l.HitSound.Play(Math.Min(impact / 5.0f, 1.0f), impact*100.0f, l.body.FarseerBody);
|
||||
|
||||
if (impact > l.impactTolerance)
|
||||
{
|
||||
@@ -308,9 +308,7 @@ namespace Subsurface
|
||||
|
||||
public virtual void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
foreach (Limb limb in limbs)
|
||||
{
|
||||
limb.Draw(spriteBatch, DebugDraw);
|
||||
@@ -340,11 +338,9 @@ namespace Subsurface
|
||||
foreach (RevoluteJoint joint in limbJoints)
|
||||
{
|
||||
Vector2 pos = ConvertUnits.ToDisplayUnits(joint.WorldAnchorA);
|
||||
pos.Y = -pos.Y;
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X, (int)-pos.Y, 5, 5), Color.White, true);
|
||||
|
||||
pos = ConvertUnits.ToDisplayUnits(joint.WorldAnchorB);
|
||||
pos.Y = -pos.Y;
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X, (int)-pos.Y, 5, 5), Color.White, true);
|
||||
}
|
||||
|
||||
@@ -494,16 +490,20 @@ namespace Subsurface
|
||||
{
|
||||
|
||||
//create a splash particle
|
||||
Game1.particleManager.CreateParticle(
|
||||
Subsurface.Particles.Particle splash = Game1.particleManager.CreateParticle("watersplash",
|
||||
new Vector2(limb.SimPosition.X, ConvertUnits.ToSimUnits(limbHull.Surface)),
|
||||
0.0f,
|
||||
new Vector2(0.0f, Math.Abs(limb.LinearVelocity.Y*0.1f)),
|
||||
"watersplash");
|
||||
Game1.particleManager.CreateParticle(
|
||||
new Vector2(limb.SimPosition.X, ConvertUnits.ToSimUnits(limbHull.Surface)),
|
||||
0.0f,
|
||||
new Vector2(0.0f, Math.Abs(-limb.LinearVelocity.Y * 0.1f)),
|
||||
0.0f);
|
||||
|
||||
if (splash != null) splash.yLimits = ConvertUnits.ToSimUnits(
|
||||
new Vector2(
|
||||
limbHull.Rect.Y,
|
||||
limbHull.Rect.Y - limbHull.Rect.Height));
|
||||
|
||||
Game1.particleManager.CreateParticle("bubbles",
|
||||
new Vector2(limb.SimPosition.X, ConvertUnits.ToSimUnits(limbHull.Surface)),
|
||||
limb.LinearVelocity*0.001f,
|
||||
"bubbles");
|
||||
0.0f);
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user