electricity bugfixes, destructable doors, ai improvements, removed rope, container changes

This commit is contained in:
Regalis
2015-05-27 01:02:30 +03:00
parent a1196d1876
commit 80648ffd46
51 changed files with 701 additions and 509 deletions
+104 -87
View File
@@ -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;
}
}
+16 -11
View File
@@ -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);
}
}
}
+27 -20
View File
@@ -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)
+1 -1
View File
@@ -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)
+8 -3
View File
@@ -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);
}
}
+7 -6
View File
@@ -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);
+14 -14
View File
@@ -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);