GUIStyle improvements & some simple UI graphics, networking bugfixes, separate Random class, some StyleCop cleanup
This commit is contained in:
@@ -9,7 +9,7 @@ namespace Subsurface
|
||||
public enum AiState { None, Attack, GoTo, Escape }
|
||||
public enum SteeringState { Wander, Seek, Escape }
|
||||
|
||||
public Character character;
|
||||
public Character Character;
|
||||
|
||||
protected AiState state;
|
||||
|
||||
@@ -17,18 +17,18 @@ namespace Subsurface
|
||||
|
||||
public Vector2 Steering
|
||||
{
|
||||
get { return character.animController.TargetMovement; }
|
||||
set { character.animController.TargetMovement = value; }
|
||||
get { return Character.AnimController.TargetMovement; }
|
||||
set { Character.AnimController.TargetMovement = value; }
|
||||
}
|
||||
|
||||
public Vector2 Position
|
||||
{
|
||||
get { return character.animController.limbs[0].SimPosition; }
|
||||
get { return Character.AnimController.limbs[0].SimPosition; }
|
||||
}
|
||||
|
||||
public Vector2 Velocity
|
||||
{
|
||||
get { return character.animController.limbs[0].LinearVelocity; }
|
||||
get { return Character.AnimController.limbs[0].LinearVelocity; }
|
||||
}
|
||||
|
||||
public AiState State
|
||||
@@ -38,7 +38,7 @@ namespace Subsurface
|
||||
|
||||
public AIController (Character c)
|
||||
{
|
||||
character = c;
|
||||
Character = c;
|
||||
|
||||
steeringManager = new SteeringManager(this);
|
||||
}
|
||||
|
||||
@@ -5,14 +5,13 @@ namespace Subsurface
|
||||
{
|
||||
class AITarget
|
||||
{
|
||||
public static List<AITarget> list = new List<AITarget>();
|
||||
public static List<AITarget> List = new List<AITarget>();
|
||||
|
||||
public Entity Entity;
|
||||
|
||||
protected float soundRange;
|
||||
protected float sightRange;
|
||||
|
||||
public Entity entity;
|
||||
|
||||
|
||||
public float SoundRange
|
||||
{
|
||||
get
|
||||
@@ -30,18 +29,18 @@ namespace Subsurface
|
||||
|
||||
public Vector2 Position
|
||||
{
|
||||
get { return entity.SimPosition; }
|
||||
get { return Entity.SimPosition; }
|
||||
}
|
||||
|
||||
public AITarget(Entity e)
|
||||
{
|
||||
entity = e;
|
||||
list.Add(this);
|
||||
Entity = e;
|
||||
List.Add(this);
|
||||
}
|
||||
|
||||
public void Remove()
|
||||
{
|
||||
list.Remove(this);
|
||||
List.Remove(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,12 @@ namespace Subsurface
|
||||
{
|
||||
|
||||
class EnemyAIController : AIController
|
||||
{ //the preference to attack a specific type of target (-1.0 - 1.0)
|
||||
{
|
||||
private const float UpdateTargetsInterval = 5.0f;
|
||||
|
||||
private const float RaycastInterval = 1.0f;
|
||||
|
||||
//the preference to attack a specific type of target (-1.0 - 1.0)
|
||||
//0.0 = doesn't attack targets of the type
|
||||
//positive values = attacks targets of this type
|
||||
//negative values = escapes targets of this type
|
||||
@@ -20,13 +25,9 @@ namespace Subsurface
|
||||
private float attackWeaker;
|
||||
private float attackStronger;
|
||||
|
||||
|
||||
|
||||
private float updateTargetsTimer;
|
||||
private const float UpdateTargetsInterval = 5.0f;
|
||||
|
||||
private float raycastTimer;
|
||||
private const float RaycastInterval = 1.0f;
|
||||
|
||||
private Vector2 prevPosition;
|
||||
private float distanceAccumulator;
|
||||
@@ -85,7 +86,7 @@ namespace Subsurface
|
||||
{
|
||||
UpdateDistanceAccumulator();
|
||||
|
||||
character.animController.IgnorePlatforms = (-character.animController.TargetMovement.Y > Math.Abs(character.animController.TargetMovement.X));
|
||||
Character.AnimController.IgnorePlatforms = (-Character.AnimController.TargetMovement.Y > Math.Abs(Character.AnimController.TargetMovement.X));
|
||||
|
||||
if (updateTargetsTimer > 0.0)
|
||||
{
|
||||
@@ -94,7 +95,7 @@ namespace Subsurface
|
||||
else
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("updatetargets");
|
||||
UpdateTargets(character);
|
||||
UpdateTargets(Character);
|
||||
updateTargetsTimer = UpdateTargetsInterval;
|
||||
|
||||
if (selectedTarget == null)
|
||||
@@ -136,7 +137,7 @@ namespace Subsurface
|
||||
|
||||
private void UpdateDistanceAccumulator()
|
||||
{
|
||||
Limb limb = character.animController.limbs[0];
|
||||
Limb limb = Character.AnimController.limbs[0];
|
||||
distanceAccumulator += (limb.SimPosition - prevPosition).Length();
|
||||
|
||||
prevPosition = limb.body.Position;
|
||||
@@ -178,10 +179,10 @@ namespace Subsurface
|
||||
//check if any of the limbs is close enough to attack the target
|
||||
if (attackingLimb == null)
|
||||
{
|
||||
foreach (Limb limb in character.animController.limbs)
|
||||
foreach (Limb limb in Character.AnimController.limbs)
|
||||
{
|
||||
if (limb.attack==null || limb.attack.type == Attack.Type.None) continue;
|
||||
if (Vector2.Distance(limb.SimPosition, attackPosition) > limb.attack.range) continue;
|
||||
if (limb.attack==null || limb.attack.Type == AttackType.None) continue;
|
||||
if (Vector2.Distance(limb.SimPosition, attackPosition) > limb.attack.Range) continue;
|
||||
|
||||
attackingLimb = limb;
|
||||
break;
|
||||
@@ -200,8 +201,8 @@ namespace Subsurface
|
||||
|
||||
//System.Diagnostics.Debug.WriteLine("cooldown");
|
||||
|
||||
if (selectedTarget.entity is Hull ||
|
||||
Vector2.Distance(attackPosition, character.animController.limbs[0].SimPosition) < ConvertUnits.ToSimUnits(500.0f))
|
||||
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);
|
||||
@@ -217,7 +218,7 @@ namespace Subsurface
|
||||
{
|
||||
targetEntity = null;
|
||||
//check if there's a wall between the target and the character
|
||||
Vector2 rayStart = character.animController.limbs[0].SimPosition;
|
||||
Vector2 rayStart = Character.AnimController.limbs[0].SimPosition;
|
||||
Vector2 rayEnd = selectedTarget.Position;
|
||||
Body closestBody = Submarine.CheckVisibility(rayStart, rayEnd);
|
||||
|
||||
@@ -257,12 +258,12 @@ namespace Subsurface
|
||||
{
|
||||
IDamageable damageTarget = null;
|
||||
|
||||
switch (limb.attack.type)
|
||||
switch (limb.attack.Type)
|
||||
{
|
||||
case Attack.Type.PinchCW:
|
||||
case Attack.Type.PinchCCW:
|
||||
case AttackType.PinchCW:
|
||||
case AttackType.PinchCCW:
|
||||
|
||||
float dir = (limb.attack.type == Attack.Type.PinchCW) ? 1.0f : -1.0f;
|
||||
float dir = (limb.attack.Type == AttackType.PinchCW) ? 1.0f : -1.0f;
|
||||
float dist = Vector2.Distance(limb.SimPosition, attackPosition);
|
||||
|
||||
if (wallAttackPos != Vector2.Zero && targetEntity != null)
|
||||
@@ -271,21 +272,21 @@ namespace Subsurface
|
||||
}
|
||||
else
|
||||
{
|
||||
damageTarget = selectedTarget.entity as IDamageable;
|
||||
damageTarget = selectedTarget.Entity as IDamageable;
|
||||
}
|
||||
|
||||
attackTimer += deltaTime*0.05f;
|
||||
|
||||
if (damageTarget == null)
|
||||
{
|
||||
attackTimer = limb.attack.duration;
|
||||
attackTimer = limb.attack.Duration;
|
||||
break;
|
||||
}
|
||||
|
||||
if (dist < limb.attack.range * 0.5f)
|
||||
if (dist < limb.attack.Range * 0.5f)
|
||||
{
|
||||
attackTimer += deltaTime;
|
||||
limb.body.ApplyTorque(limb.Mass * 50.0f * character.animController.Dir * dir);
|
||||
limb.body.ApplyTorque(limb.Mass * 50.0f * Character.AnimController.Dir * dir);
|
||||
|
||||
limb.attack.DoDamage(damageTarget, limb.SimPosition, deltaTime, (limb.soundTimer <= 0.0f));
|
||||
|
||||
@@ -303,11 +304,11 @@ namespace Subsurface
|
||||
|
||||
break;
|
||||
default:
|
||||
attackTimer = limb.attack.duration;
|
||||
attackTimer = limb.attack.Duration;
|
||||
break;
|
||||
}
|
||||
|
||||
if (attackTimer >= limb.attack.duration)
|
||||
if (attackTimer >= limb.attack.Duration)
|
||||
{
|
||||
attackTimer = 0.0f;
|
||||
if (Vector2.Distance(limb.SimPosition, attackPosition)<5.0) coolDownTimer = attackCoolDown;
|
||||
@@ -320,10 +321,10 @@ namespace Subsurface
|
||||
//sight/hearing range
|
||||
public void UpdateTargets(Character character)
|
||||
{
|
||||
if (distanceAccumulator<5.0f && Game1.random.Next(1,3)==1)
|
||||
if (distanceAccumulator<5.0f && Rand.Range(1,3, false)==1)
|
||||
{
|
||||
selectedTarget = null;
|
||||
character.animController.TargetMovement = -character.animController.TargetMovement;
|
||||
character.AnimController.TargetMovement = -character.AnimController.TargetMovement;
|
||||
state = AiState.None;
|
||||
return;
|
||||
}
|
||||
@@ -335,35 +336,35 @@ namespace Subsurface
|
||||
|
||||
UpdateTargetMemories();
|
||||
|
||||
foreach (AITarget target in AITarget.list)
|
||||
foreach (AITarget target in AITarget.List)
|
||||
{
|
||||
float valueModifier = 0.0f;
|
||||
float dist = 0.0f;
|
||||
|
||||
IDamageable targetDamageable = target.entity as IDamageable;
|
||||
IDamageable targetDamageable = target.Entity as IDamageable;
|
||||
if (targetDamageable!=null && targetDamageable.Health <= 0.0f) continue;
|
||||
|
||||
Character targetCharacter = target.entity as Character;
|
||||
Character targetCharacter = target.Entity as Character;
|
||||
|
||||
//ignore the aitarget if it is the character itself
|
||||
if (targetCharacter == character) continue;
|
||||
|
||||
if (targetCharacter!=null)
|
||||
{
|
||||
if (attackHumans == 0.0f || targetCharacter.speciesName != "human") continue;
|
||||
if (attackHumans == 0.0f || targetCharacter.SpeciesName != "human") continue;
|
||||
|
||||
valueModifier = attackHumans;
|
||||
}
|
||||
else if (target.entity!=null && attackRooms!=0.0f)
|
||||
else if (target.Entity!=null && attackRooms!=0.0f)
|
||||
{
|
||||
//skip the target if it's the room the character is inside of
|
||||
if (character.animController.CurrentHull != null && character.animController.CurrentHull == target.entity as Hull) continue;
|
||||
if (character.AnimController.CurrentHull != null && character.AnimController.CurrentHull == target.Entity as Hull) continue;
|
||||
|
||||
valueModifier = attackRooms;
|
||||
}
|
||||
|
||||
dist = Vector2.Distance(
|
||||
character.animController.limbs[0].SimPosition,
|
||||
character.AnimController.limbs[0].SimPosition,
|
||||
target.Position);
|
||||
dist = ConvertUnits.ToDisplayUnits(dist);
|
||||
|
||||
@@ -374,7 +375,7 @@ namespace Subsurface
|
||||
|
||||
if (Math.Abs(valueModifier) > Math.Abs(targetValue) && (dist < target.SightRange * sight || dist < target.SoundRange * hearing))
|
||||
{
|
||||
Vector2 rayStart = character.animController.limbs[0].SimPosition;
|
||||
Vector2 rayStart = character.AnimController.limbs[0].SimPosition;
|
||||
Vector2 rayEnd = target.Position;
|
||||
|
||||
Body closestBody = Submarine.CheckVisibility(rayStart, rayEnd);
|
||||
@@ -414,7 +415,7 @@ namespace Subsurface
|
||||
selectedTargetMemory = targetMemory;
|
||||
|
||||
targetValue = valueModifier;
|
||||
Debug.WriteLine(selectedTarget.entity+": "+targetValue);
|
||||
Debug.WriteLine(selectedTarget.Entity+": "+targetValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -448,7 +449,7 @@ namespace Subsurface
|
||||
foreach(KeyValuePair<AITarget, AITargetMemory> memory in targetMemories)
|
||||
{
|
||||
memory.Value.Priority += 0.5f;
|
||||
if (memory.Value.Priority == 0.0f || !AITarget.list.Contains(memory.Key)) toBeRemoved.Add(memory.Key);
|
||||
if (memory.Value.Priority == 0.0f || !AITarget.List.Contains(memory.Key)) toBeRemoved.Add(memory.Key);
|
||||
}
|
||||
|
||||
foreach (AITarget target in toBeRemoved)
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Subsurface
|
||||
{
|
||||
this.host = host;
|
||||
|
||||
wanderAngle = MathUtils.RandomFloatLocal(0.0f, MathHelper.TwoPi);
|
||||
wanderAngle = Rand.Range(0.0f, MathHelper.TwoPi);
|
||||
}
|
||||
|
||||
public void SteeringSeek(Vector2 target, float speed = 1.0f)
|
||||
@@ -90,7 +90,7 @@ namespace Subsurface
|
||||
|
||||
float angleChange = 1.5f;
|
||||
|
||||
wanderAngle += MathUtils.RandomFloatLocal(0.0f, 1.0f) * angleChange - angleChange * 0.5f;
|
||||
wanderAngle += Rand.Range(0.0f, 1.0f) * angleChange - angleChange * 0.5f;
|
||||
|
||||
Vector2 newSteering = circleCenter + displacement;
|
||||
float steeringSpeed = (newSteering + host.Steering).Length();
|
||||
@@ -106,9 +106,9 @@ namespace Subsurface
|
||||
{
|
||||
if (steering == Vector2.Zero || host.Steering == Vector2.Zero) return Vector2.Zero;
|
||||
|
||||
float MaxDistance = 2.0f;
|
||||
float maxDistance = 2.0f;
|
||||
|
||||
Vector2 ahead = host.Position + Vector2.Normalize(host.Steering)*MaxDistance;
|
||||
Vector2 ahead = host.Position + Vector2.Normalize(host.Steering)*maxDistance;
|
||||
|
||||
if (rayCastTimer <= 0.0f)
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Subsurface
|
||||
{
|
||||
private Queue<Vector2> nodes;
|
||||
|
||||
const float minDistance = 0.1f;
|
||||
const float MinDistance = 0.1f;
|
||||
|
||||
Vector2 currentNode;
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace Subsurface
|
||||
public Vector2 GetNode(Vector2 pos)
|
||||
{
|
||||
if (nodes.Count == 0) return Vector2.Zero;
|
||||
if (currentNode==Vector2.Zero || Vector2.Distance(pos, currentNode)<minDistance) currentNode = nodes.Dequeue();
|
||||
if (currentNode == Vector2.Zero || Vector2.Distance(pos, currentNode) < MinDistance) currentNode = nodes.Dequeue();
|
||||
|
||||
return currentNode;
|
||||
}
|
||||
|
||||
@@ -6,16 +6,16 @@ namespace Subsurface
|
||||
{
|
||||
class AnimController : Ragdoll
|
||||
{
|
||||
protected Character character;
|
||||
|
||||
public bool isStanding;
|
||||
public bool IsStanding;
|
||||
|
||||
public enum Animation { None, Climbing, UsingConstruction, Struggle };
|
||||
public Animation anim;
|
||||
public Animation Anim;
|
||||
|
||||
protected float walkSpeed, swimSpeed;
|
||||
|
||||
public Direction targetDir;
|
||||
public Direction TargetDir;
|
||||
|
||||
protected Character character;
|
||||
|
||||
protected float walkSpeed, swimSpeed;
|
||||
|
||||
//how large impacts the character can take before being stunned
|
||||
//protected float impactTolerance;
|
||||
|
||||
@@ -1,48 +1,48 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
|
||||
public enum DamageType { None, Blunt, Slash };
|
||||
public enum DamageType { None, Blunt, Slash }
|
||||
|
||||
public enum AttackType
|
||||
{
|
||||
None, PinchCW, PinchCCW
|
||||
}
|
||||
|
||||
struct AttackResult
|
||||
{
|
||||
public readonly float damage;
|
||||
public readonly float bleeding;
|
||||
public readonly float Damage;
|
||||
public readonly float Bleeding;
|
||||
|
||||
public readonly bool hitArmor;
|
||||
public readonly bool HitArmor;
|
||||
|
||||
public AttackResult(float damage, float bleeding, bool hitArmor=false)
|
||||
{
|
||||
this.damage = damage;
|
||||
this.bleeding = bleeding;
|
||||
this.Damage = damage;
|
||||
this.Bleeding = bleeding;
|
||||
|
||||
this.hitArmor = hitArmor;
|
||||
this.HitArmor = hitArmor;
|
||||
}
|
||||
}
|
||||
|
||||
class Attack
|
||||
{
|
||||
public enum Type
|
||||
{
|
||||
None, PinchCW, PinchCCW
|
||||
};
|
||||
public readonly Type type;
|
||||
public readonly float range;
|
||||
public readonly float duration;
|
||||
|
||||
public readonly DamageType damageType;
|
||||
public readonly AttackType Type;
|
||||
public readonly float Range;
|
||||
public readonly float Duration;
|
||||
|
||||
public readonly float structureDamage;
|
||||
public readonly float damage;
|
||||
public readonly float bleedingDamage;
|
||||
public readonly DamageType DamageType;
|
||||
|
||||
public readonly float stun;
|
||||
public readonly float StructureDamage;
|
||||
public readonly float Damage;
|
||||
public readonly float BleedingDamage;
|
||||
|
||||
public readonly float Stun;
|
||||
|
||||
private float priority;
|
||||
|
||||
@@ -50,62 +50,62 @@ namespace Subsurface
|
||||
{
|
||||
try
|
||||
{
|
||||
type = (Type)Enum.Parse(typeof(Type), element.Attribute("type").Value, true);
|
||||
Type = (AttackType)Enum.Parse(typeof(AttackType), element.Attribute("type").Value, true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
type = Type.None;
|
||||
Type = AttackType.None;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
damageType = (DamageType)Enum.Parse(typeof(DamageType), ToolBox.GetAttributeString(element, "damagetype", "None"), true);
|
||||
DamageType = (DamageType)Enum.Parse(typeof(DamageType), ToolBox.GetAttributeString(element, "damagetype", "None"), true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
damageType = DamageType.None;
|
||||
DamageType = DamageType.None;
|
||||
}
|
||||
|
||||
|
||||
damage = ToolBox.GetAttributeFloat(element, "damage", 0.0f);
|
||||
structureDamage = ToolBox.GetAttributeFloat(element, "structuredamage", 0.0f);
|
||||
bleedingDamage = ToolBox.GetAttributeFloat(element, "bleedingdamage", 0.0f);
|
||||
Damage = ToolBox.GetAttributeFloat(element, "damage", 0.0f);
|
||||
StructureDamage = ToolBox.GetAttributeFloat(element, "structuredamage", 0.0f);
|
||||
BleedingDamage = ToolBox.GetAttributeFloat(element, "bleedingdamage", 0.0f);
|
||||
|
||||
stun = ToolBox.GetAttributeFloat(element, "stun", 0.0f);
|
||||
Stun = ToolBox.GetAttributeFloat(element, "stun", 0.0f);
|
||||
|
||||
|
||||
range = FarseerPhysics.ConvertUnits.ToSimUnits(ToolBox.GetAttributeFloat(element, "range", 0.0f));
|
||||
Range = FarseerPhysics.ConvertUnits.ToSimUnits(ToolBox.GetAttributeFloat(element, "range", 0.0f));
|
||||
|
||||
duration = ToolBox.GetAttributeFloat(element, "duration", 0.0f);
|
||||
Duration = ToolBox.GetAttributeFloat(element, "duration", 0.0f);
|
||||
|
||||
priority = ToolBox.GetAttributeFloat(element, "priority", 1.0f);
|
||||
}
|
||||
|
||||
public AttackResult DoDamage(IDamageable target, Vector2 position, float deltaTime, bool playSound=true)
|
||||
public AttackResult DoDamage(IDamageable target, Vector2 position, float deltaTime, bool playSound = true)
|
||||
{
|
||||
float damageAmount = 0.0f;
|
||||
//DamageSoundType damageSoundType = DamageSoundType.None;
|
||||
|
||||
if (target as Character == null)
|
||||
{
|
||||
damageAmount = structureDamage;
|
||||
damageAmount = StructureDamage;
|
||||
//damageSoundType = (damageType == DamageType.Blunt) ? DamageSoundType.StructureBlunt: DamageSoundType.StructureSlash;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
damageAmount = damage;
|
||||
damageAmount = Damage;
|
||||
//damageSoundType = (damageType == DamageType.Blunt) ? DamageSoundType.LimbBlunt : DamageSoundType.LimbSlash;
|
||||
}
|
||||
//damageSoundType = (damageType == DamageType.Blunt) ? DamageSoundType.StructureBlunt : DamageSoundType.StructureSlash;
|
||||
//if (playSound) AmbientSoundManager.PlayDamageSound(damageSoundType, damageAmount, position);
|
||||
|
||||
if (duration > 0.0f) damageAmount *= deltaTime;
|
||||
float bleedingAmount = (duration == 0.0f) ? bleedingDamage : bleedingDamage * deltaTime;
|
||||
if (Duration > 0.0f) damageAmount *= deltaTime;
|
||||
float bleedingAmount = (Duration == 0.0f) ? BleedingDamage : BleedingDamage * deltaTime;
|
||||
|
||||
if (damageAmount > 0.0f)
|
||||
{
|
||||
return target.AddDamage(position, damageType, damageAmount, bleedingAmount, stun, playSound);
|
||||
return target.AddDamage(position, DamageType, damageAmount, bleedingAmount, Stun, playSound);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+154
-140
@@ -16,11 +16,11 @@ namespace Subsurface
|
||||
{
|
||||
class Character : Entity, IDamageable, IPropertyObject
|
||||
{
|
||||
public static List<Character> characterList = new List<Character>();
|
||||
public static List<Character> CharacterList = new List<Character>();
|
||||
|
||||
public static Queue<CharacterInfo> newCharacterQueue = new Queue<CharacterInfo>();
|
||||
public static Queue<CharacterInfo> NewCharacterQueue = new Queue<CharacterInfo>();
|
||||
|
||||
public static bool disableControls;
|
||||
public static bool DisableControls;
|
||||
|
||||
//the character that the player is currently controlling
|
||||
private static Character controlled;
|
||||
@@ -35,14 +35,14 @@ namespace Subsurface
|
||||
|
||||
private Inventory inventory;
|
||||
|
||||
public double lastNetworkUpdate;
|
||||
public double LastNetworkUpdate;
|
||||
|
||||
public byte largeUpdateTimer;
|
||||
public byte LargeUpdateTimer;
|
||||
|
||||
public readonly Dictionary<string, ObjectProperty> properties;
|
||||
public readonly Dictionary<string, ObjectProperty> Properties;
|
||||
public Dictionary<string, ObjectProperty> ObjectProperties
|
||||
{
|
||||
get { return properties; }
|
||||
get { return Properties; }
|
||||
}
|
||||
|
||||
protected Key selectKeyHit;
|
||||
@@ -52,7 +52,7 @@ namespace Subsurface
|
||||
private Item selectedConstruction;
|
||||
private Item[] selectedItems;
|
||||
|
||||
public AnimController animController;
|
||||
public AnimController AnimController;
|
||||
private AIController aiController;
|
||||
|
||||
private Vector2 cursorPosition;
|
||||
@@ -71,9 +71,9 @@ namespace Subsurface
|
||||
bool isHumanoid;
|
||||
|
||||
//the name of the species (e.q. human)
|
||||
public readonly string speciesName;
|
||||
public readonly string SpeciesName;
|
||||
|
||||
public CharacterInfo info;
|
||||
public CharacterInfo Info;
|
||||
|
||||
protected float soundTimer;
|
||||
protected float soundInterval;
|
||||
@@ -89,7 +89,7 @@ namespace Subsurface
|
||||
{
|
||||
get
|
||||
{
|
||||
return speciesName;
|
||||
return SpeciesName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,12 +251,12 @@ namespace Subsurface
|
||||
|
||||
public override Vector2 SimPosition
|
||||
{
|
||||
get { return animController.limbs[0].SimPosition; }
|
||||
get { return AnimController.limbs[0].SimPosition; }
|
||||
}
|
||||
|
||||
public Vector2 Position
|
||||
{
|
||||
get { return ConvertUnits.ToDisplayUnits(animController.limbs[0].SimPosition); }
|
||||
get { return ConvertUnits.ToDisplayUnits(AnimController.limbs[0].SimPosition); }
|
||||
}
|
||||
|
||||
public Character(string file) : this(file, Vector2.Zero, null)
|
||||
@@ -269,7 +269,7 @@ namespace Subsurface
|
||||
}
|
||||
|
||||
public Character(CharacterInfo characterInfo, Vector2 position, bool isNetworkPlayer = false)
|
||||
: this(characterInfo.file, position, characterInfo, isNetworkPlayer)
|
||||
: this(characterInfo.File, position, characterInfo, isNetworkPlayer)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -289,33 +289,33 @@ namespace Subsurface
|
||||
//blood = 100.0f;
|
||||
aiTarget = new AITarget(this);
|
||||
|
||||
properties = ObjectProperty.GetProperties(this);
|
||||
Properties = ObjectProperty.GetProperties(this);
|
||||
|
||||
info = characterInfo==null ? new CharacterInfo(file) : characterInfo;
|
||||
Info = characterInfo==null ? new CharacterInfo(file) : characterInfo;
|
||||
|
||||
XDocument doc = ToolBox.TryLoadXml(file);
|
||||
if (doc == null) return;
|
||||
|
||||
speciesName = ToolBox.GetAttributeString(doc.Root, "name", "Unknown");
|
||||
SpeciesName = ToolBox.GetAttributeString(doc.Root, "name", "Unknown");
|
||||
|
||||
isHumanoid = ToolBox.GetAttributeBool(doc.Root, "humanoid", false);
|
||||
|
||||
if (isHumanoid)
|
||||
{
|
||||
animController = new HumanoidAnimController(this, doc.Root.Element("ragdoll"));
|
||||
animController.targetDir = Direction.Right;
|
||||
AnimController = new HumanoidAnimController(this, doc.Root.Element("ragdoll"));
|
||||
AnimController.TargetDir = Direction.Right;
|
||||
inventory = new CharacterInventory(10, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
animController = new FishAnimController(this, doc.Root.Element("ragdoll"));
|
||||
AnimController = new FishAnimController(this, doc.Root.Element("ragdoll"));
|
||||
PressureProtection = 100.0f;
|
||||
//FishAnimController fishAnim = (FishAnimController)animController;
|
||||
|
||||
aiController = new EnemyAIController(this, file);
|
||||
}
|
||||
|
||||
foreach (Limb limb in animController.limbs)
|
||||
foreach (Limb limb in AnimController.limbs)
|
||||
{
|
||||
limb.body.SetTransform(position+limb.SimPosition, 0.0f);
|
||||
//limb.prevPosition = ConvertUnits.ToDisplayUnits(position);
|
||||
@@ -329,44 +329,40 @@ namespace Subsurface
|
||||
|
||||
soundInterval = ToolBox.GetAttributeFloat(doc.Root, "soundinterval", 10.0f);
|
||||
|
||||
var xSounds = doc.Root.Elements("sound").ToList();
|
||||
if (xSounds.Any())
|
||||
var soundElements = doc.Root.Elements("sound").ToList();
|
||||
if (soundElements.Any())
|
||||
{
|
||||
sounds = new Sound[xSounds.Count()];
|
||||
soundStates = new AIController.AiState[xSounds.Count()];
|
||||
sounds = new Sound[soundElements.Count()];
|
||||
soundStates = new AIController.AiState[soundElements.Count()];
|
||||
int i = 0;
|
||||
foreach (XElement xSound in xSounds)
|
||||
foreach (XElement soundElement in soundElements)
|
||||
{
|
||||
sounds[i] = Sound.Load(xSound.Attribute("file").Value);
|
||||
if (xSound.Attribute("state") == null)
|
||||
sounds[i] = Sound.Load(soundElement.Attribute("file").Value);
|
||||
if (soundElement.Attribute("state") == null)
|
||||
{
|
||||
soundStates[i] = AIController.AiState.None;
|
||||
}
|
||||
else
|
||||
{
|
||||
soundStates[i] = (AIController.AiState)Enum.Parse(
|
||||
typeof(AIController.AiState), xSound.Attribute("state").Value, true);
|
||||
typeof(AIController.AiState), soundElement.Attribute("state").Value, true);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
animController.FindHull();
|
||||
AnimController.FindHull();
|
||||
|
||||
//if (info.ID >= 0)
|
||||
//{
|
||||
// ID = info.ID;
|
||||
//}
|
||||
|
||||
characterList.Add(this);
|
||||
CharacterList.Add(this);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Control the characte
|
||||
/// </summary>
|
||||
public void Control(float deltaTime, Camera cam, bool forcePick=false)
|
||||
public void Control(float deltaTime, Camera cam, bool forcePick = false)
|
||||
{
|
||||
if (isDead) return;
|
||||
|
||||
@@ -416,7 +412,7 @@ namespace Subsurface
|
||||
|
||||
private Item FindClosestItem(Vector2 mouseSimPos)
|
||||
{
|
||||
Limb torso = animController.GetLimb(LimbType.Torso);
|
||||
Limb torso = AnimController.GetLimb(LimbType.Torso);
|
||||
Vector2 pos = (torso.body.TargetPosition != Vector2.Zero) ? torso.body.TargetPosition : torso.SimPosition;
|
||||
|
||||
return Item.FindPickable(pos, selectedConstruction == null ? mouseSimPos : selectedConstruction.SimPosition, null, selectedItems);
|
||||
@@ -433,13 +429,13 @@ namespace Subsurface
|
||||
// return;
|
||||
//}
|
||||
|
||||
Limb head = animController.GetLimb(LimbType.Head);
|
||||
Limb head = AnimController.GetLimb(LimbType.Head);
|
||||
|
||||
Lights.LightManager.viewPos = ConvertUnits.ToDisplayUnits(head.SimPosition);
|
||||
Lights.LightManager.ViewPos = ConvertUnits.ToDisplayUnits(head.SimPosition);
|
||||
|
||||
Vector2 targetMovement = Vector2.Zero;
|
||||
|
||||
if (!disableControls)
|
||||
if (!DisableControls)
|
||||
{
|
||||
if (PlayerInput.KeyDown(Keys.W)) targetMovement.Y += 1.0f;
|
||||
if (PlayerInput.KeyDown(Keys.S)) targetMovement.Y -= 1.0f;
|
||||
@@ -448,13 +444,13 @@ namespace Subsurface
|
||||
|
||||
//the vertical component is only used for falling through platforms and climbing ladders when not in water,
|
||||
//so the movement can't be normalized or the character would walk slower when pressing down/up
|
||||
if (animController.InWater)
|
||||
if (AnimController.InWater)
|
||||
{
|
||||
float length = targetMovement.Length();
|
||||
if (length > 0.0f) targetMovement = targetMovement / length;
|
||||
}
|
||||
|
||||
if (Keyboard.GetState().IsKeyDown(Keys.LeftShift) && Math.Sign(targetMovement.X) == Math.Sign(animController.Dir))
|
||||
if (Keyboard.GetState().IsKeyDown(Keys.LeftShift) && Math.Sign(targetMovement.X) == Math.Sign(AnimController.Dir))
|
||||
targetMovement *= 3.0f;
|
||||
|
||||
selectKeyHit.SetState(PlayerInput.KeyHit(Keys.E));
|
||||
@@ -472,53 +468,53 @@ namespace Subsurface
|
||||
secondaryKeyDown.SetState(false);
|
||||
}
|
||||
|
||||
animController.TargetMovement = targetMovement;
|
||||
animController.isStanding = true;
|
||||
AnimController.TargetMovement = targetMovement;
|
||||
AnimController.IsStanding = true;
|
||||
|
||||
if (moveCam)
|
||||
{
|
||||
cam.TargetPos = ConvertUnits.ToDisplayUnits(animController.limbs[0].SimPosition);
|
||||
cam.TargetPos = ConvertUnits.ToDisplayUnits(AnimController.limbs[0].SimPosition);
|
||||
cam.OffsetAmount = 250.0f;
|
||||
}
|
||||
|
||||
cursorPosition = cam.ScreenToWorld(PlayerInput.MousePosition);
|
||||
Vector2 mouseSimPos = ConvertUnits.ToSimUnits(cursorPosition);
|
||||
|
||||
if (animController.onGround &&
|
||||
!animController.InWater &&
|
||||
animController.anim != AnimController.Animation.UsingConstruction)
|
||||
if (AnimController.onGround &&
|
||||
!AnimController.InWater &&
|
||||
AnimController.Anim != AnimController.Animation.UsingConstruction)
|
||||
{
|
||||
if (mouseSimPos.X < head.SimPosition.X-1.0f)
|
||||
{
|
||||
animController.targetDir = Direction.Left;
|
||||
AnimController.TargetDir = Direction.Left;
|
||||
}
|
||||
else if (mouseSimPos.X > head.SimPosition.X + 1.0f)
|
||||
{
|
||||
animController.targetDir = Direction.Right;
|
||||
AnimController.TargetDir = Direction.Right;
|
||||
}
|
||||
}
|
||||
|
||||
disableControls = false;
|
||||
DisableControls = false;
|
||||
}
|
||||
|
||||
|
||||
public static void UpdateAnimAll(float deltaTime)
|
||||
{
|
||||
foreach (Character c in characterList)
|
||||
foreach (Character c in CharacterList)
|
||||
{
|
||||
if (c.isDead) continue;
|
||||
c.animController.UpdateAnim(deltaTime);
|
||||
c.AnimController.UpdateAnim(deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
public static void UpdateAll(Camera cam, float deltaTime)
|
||||
{
|
||||
if (newCharacterQueue.Count>0)
|
||||
if (NewCharacterQueue.Count>0)
|
||||
{
|
||||
new Character(newCharacterQueue.Dequeue(), Vector2.Zero);
|
||||
new Character(NewCharacterQueue.Dequeue(), Vector2.Zero);
|
||||
}
|
||||
|
||||
foreach (Character c in characterList)
|
||||
foreach (Character c in CharacterList)
|
||||
{
|
||||
c.Update(cam, deltaTime);
|
||||
}
|
||||
@@ -531,14 +527,14 @@ namespace Subsurface
|
||||
if (controlled == this)
|
||||
{
|
||||
cam.Zoom = MathHelper.Lerp(cam.Zoom, 1.5f, 0.1f);
|
||||
cam.TargetPos = ConvertUnits.ToDisplayUnits(animController.limbs[0].SimPosition);
|
||||
cam.TargetPos = ConvertUnits.ToDisplayUnits(AnimController.limbs[0].SimPosition);
|
||||
cam.OffsetAmount = 0.0f;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (PressureProtection==0.0f &&
|
||||
(animController.CurrentHull == null || animController.CurrentHull.LethalPressure >= 100.0f))
|
||||
(AnimController.CurrentHull == null || AnimController.CurrentHull.LethalPressure >= 100.0f))
|
||||
{
|
||||
Implode();
|
||||
return;
|
||||
@@ -553,18 +549,18 @@ namespace Subsurface
|
||||
|
||||
if (needsAir)
|
||||
{
|
||||
if (animController.HeadInWater)
|
||||
if (AnimController.HeadInWater)
|
||||
{
|
||||
Oxygen -= deltaTime*100.0f / drowningTime;
|
||||
}
|
||||
else if (animController.CurrentHull != null)
|
||||
else if (AnimController.CurrentHull != null)
|
||||
{
|
||||
float hullOxygen = animController.CurrentHull.OxygenPercentage;
|
||||
float hullOxygen = AnimController.CurrentHull.OxygenPercentage;
|
||||
hullOxygen -= 30.0f;
|
||||
|
||||
Oxygen += deltaTime * 100.0f * (hullOxygen / 500.0f);
|
||||
|
||||
animController.CurrentHull.Oxygen -= Hull.OxygenConsumptionSpeed * deltaTime;
|
||||
AnimController.CurrentHull.Oxygen -= Hull.OxygenConsumptionSpeed * deltaTime;
|
||||
}
|
||||
PressureProtection -= deltaTime*100.0f;
|
||||
}
|
||||
@@ -593,12 +589,12 @@ namespace Subsurface
|
||||
|
||||
//distance is approximated based on the mass of the character
|
||||
//(which corresponds to size because all the characters have the same limb density)
|
||||
foreach (Limb limb in animController.limbs)
|
||||
foreach (Limb limb in AnimController.limbs)
|
||||
{
|
||||
aiTarget.SightRange += limb.Mass * 1000.0f;
|
||||
}
|
||||
//the faster the character is moving, the easier it is to see it
|
||||
Limb torso = animController.GetLimb(LimbType.Torso);
|
||||
Limb torso = AnimController.GetLimb(LimbType.Torso);
|
||||
if (torso !=null)
|
||||
{
|
||||
aiTarget.SightRange += torso.LinearVelocity.Length() * 500.0f;
|
||||
@@ -607,13 +603,13 @@ namespace Subsurface
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
animController.Draw(spriteBatch);
|
||||
AnimController.Draw(spriteBatch);
|
||||
|
||||
if (IsNetworkPlayer)
|
||||
{
|
||||
Vector2 namePos = new Vector2(Position.X, -Position.Y - 80.0f) - GUI.font.MeasureString(info.name) * 0.5f;
|
||||
spriteBatch.DrawString(GUI.font, info.name, namePos - new Vector2(1.0f, 1.0f), Color.Black);
|
||||
spriteBatch.DrawString(GUI.font, info.name, namePos, Color.White);
|
||||
Vector2 namePos = new Vector2(Position.X, -Position.Y - 80.0f) - GUI.font.MeasureString(Info.Name) * 0.5f;
|
||||
spriteBatch.DrawString(GUI.font, Info.Name, namePos - new Vector2(1.0f, 1.0f), Color.Black);
|
||||
spriteBatch.DrawString(GUI.font, Info.Name, namePos, Color.White);
|
||||
}
|
||||
|
||||
if (this == Character.controlled) return;
|
||||
@@ -622,7 +618,9 @@ namespace Subsurface
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)healthBarPos.X-2, (int)healthBarPos.Y-2, 100+4, 15+4), Color.Black, false);
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)healthBarPos.X, (int)healthBarPos.Y, (int)(100.0f*(health/maxHealth)), 15), Color.Red, true);
|
||||
|
||||
//spriteBatch.DrawString(GUI.font, ID.ToString(), ConvertUnits.ToDisplayUnits(animController.limbs[0].Position), Color.White);
|
||||
Vector2 pos = ConvertUnits.ToDisplayUnits(AnimController.limbs[0].SimPosition);
|
||||
pos.Y = -pos.Y;
|
||||
spriteBatch.DrawString(GUI.font, ID.ToString(), pos, Color.White);
|
||||
//GUI.DrawLine(spriteBatch, ConvertUnits.ToDisplayUnits(animController.limbs[0].SimPosition.X, animController.limbs[0].SimPosition.Y),
|
||||
// ConvertUnits.ToDisplayUnits(animController.limbs[0].SimPosition.X, animController.limbs[0].SimPosition.Y) +
|
||||
// ConvertUnits.ToDisplayUnits(animController.targetMovement.X, animController.targetMovement.Y), Color.Green);
|
||||
@@ -681,7 +679,7 @@ namespace Subsurface
|
||||
if (sounds == null || !sounds.Any()) return;
|
||||
var matchingSoundStates = soundStates.Where(x => x == state).ToList();
|
||||
|
||||
int selectedSound = Game1.localRandom.Next(matchingSoundStates.Count());
|
||||
int selectedSound = Rand.Int(matchingSoundStates.Count());
|
||||
|
||||
int n = 0;
|
||||
for (int i = 0; i < sounds.Count(); i++)
|
||||
@@ -690,7 +688,7 @@ namespace Subsurface
|
||||
if (n == selectedSound)
|
||||
{
|
||||
sounds[i].Play(1.0f, 2000.0f,
|
||||
animController.limbs[0].body.FarseerBody);
|
||||
AnimController.limbs[0].body.FarseerBody);
|
||||
Debug.WriteLine("playing: " + sounds[i]);
|
||||
return;
|
||||
}
|
||||
@@ -700,11 +698,11 @@ namespace Subsurface
|
||||
|
||||
public AttackResult AddDamage(Vector2 position, DamageType damageType, float amount, float bleedingAmount, float stun, bool playSound = false)
|
||||
{
|
||||
animController.StunTimer = Math.Max(animController.StunTimer, stun);
|
||||
AnimController.StunTimer = Math.Max(AnimController.StunTimer, stun);
|
||||
|
||||
Limb closestLimb = null;
|
||||
float closestDistance = 0.0f;
|
||||
foreach (Limb limb in animController.limbs)
|
||||
foreach (Limb limb in AnimController.limbs)
|
||||
{
|
||||
float distance = Vector2.Distance(position, limb.SimPosition);
|
||||
if (closestLimb == null || distance < closestDistance)
|
||||
@@ -720,8 +718,8 @@ namespace Subsurface
|
||||
|
||||
|
||||
AttackResult attackResult = closestLimb.AddDamage(position, damageType, amount, bleedingAmount, playSound);
|
||||
health -= attackResult.damage;
|
||||
bleeding += attackResult.bleeding;
|
||||
health -= attackResult.Damage;
|
||||
bleeding += attackResult.Bleeding;
|
||||
|
||||
return attackResult;
|
||||
|
||||
@@ -741,12 +739,12 @@ namespace Subsurface
|
||||
|
||||
private void Implode()
|
||||
{
|
||||
Limb torso= animController.GetLimb(LimbType.Torso);
|
||||
if (torso == null) torso = animController.GetLimb(LimbType.Head);
|
||||
Limb torso= AnimController.GetLimb(LimbType.Torso);
|
||||
if (torso == null) torso = AnimController.GetLimb(LimbType.Head);
|
||||
|
||||
Vector2 centerOfMass = Vector2.Zero;
|
||||
float totalMass = 0.0f;
|
||||
foreach (Limb limb in animController.limbs)
|
||||
foreach (Limb limb in AnimController.limbs)
|
||||
{
|
||||
centerOfMass += limb.Mass * limb.SimPosition;
|
||||
totalMass += limb.Mass;
|
||||
@@ -756,7 +754,7 @@ namespace Subsurface
|
||||
|
||||
health = 0.0f;
|
||||
|
||||
foreach (Limb limb in animController.limbs)
|
||||
foreach (Limb limb in AnimController.limbs)
|
||||
{
|
||||
Vector2 diff = centerOfMass - limb.SimPosition;
|
||||
if (diff == Vector2.Zero) continue;
|
||||
@@ -769,16 +767,16 @@ namespace Subsurface
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
Particle p = Game1.particleManager.CreateParticle("waterblood",
|
||||
torso.SimPosition + new Vector2(MathUtils.RandomFloatLocal(-0.5f, 0.5f), MathUtils.RandomFloatLocal(-0.5f, 0.5f)),
|
||||
torso.SimPosition + new Vector2(Rand.Range(-0.5f, 0.5f), Rand.Range(-0.5f, 0.5f)),
|
||||
Vector2.Zero);
|
||||
if (p!=null) p.Size *= 2.0f;
|
||||
|
||||
Game1.particleManager.CreateParticle("bubbles",
|
||||
torso.SimPosition,
|
||||
new Vector2(MathUtils.RandomFloatLocal(-0.5f, 0.5f), MathUtils.RandomFloatLocal(-1.0f,0.5f)));
|
||||
new Vector2(Rand.Range(-0.5f, 0.5f), Rand.Range(-1.0f,0.5f)));
|
||||
}
|
||||
|
||||
foreach (var joint in animController.limbJoints)
|
||||
foreach (var joint in AnimController.limbJoints)
|
||||
{
|
||||
joint.LimitEnabled = false;
|
||||
}
|
||||
@@ -790,8 +788,8 @@ namespace Subsurface
|
||||
if (isDead) return;
|
||||
|
||||
isDead = true;
|
||||
animController.movement = Vector2.Zero;
|
||||
animController.TargetMovement = Vector2.Zero;
|
||||
AnimController.movement = Vector2.Zero;
|
||||
AnimController.TargetMovement = Vector2.Zero;
|
||||
|
||||
for (int i = 0; i < selectedItems.Length; i++ )
|
||||
{
|
||||
@@ -802,13 +800,13 @@ namespace Subsurface
|
||||
aiTarget.Remove();
|
||||
aiTarget = null;
|
||||
|
||||
foreach (Limb limb in animController.limbs)
|
||||
foreach (Limb limb in AnimController.limbs)
|
||||
{
|
||||
if (limb.pullJoint == null) continue;
|
||||
limb.pullJoint.Enabled = false;
|
||||
}
|
||||
|
||||
foreach (RevoluteJoint joint in animController.limbJoints)
|
||||
foreach (RevoluteJoint joint in AnimController.limbJoints)
|
||||
{
|
||||
joint.MotorEnabled = false;
|
||||
joint.MaxMotorTorque = 0.0f;
|
||||
@@ -863,20 +861,25 @@ namespace Subsurface
|
||||
message.Write(NetTime.Now);
|
||||
|
||||
// Write byte = move direction
|
||||
message.Write(animController.TargetMovement.X);
|
||||
message.Write(animController.TargetMovement.Y);
|
||||
message.Write(AnimController.TargetMovement.X);
|
||||
message.Write(AnimController.TargetMovement.Y);
|
||||
|
||||
message.Write(animController.targetDir==Direction.Right);
|
||||
message.Write(AnimController.TargetDir==Direction.Right);
|
||||
|
||||
message.Write(cursorPosition.X);
|
||||
message.Write(cursorPosition.Y);
|
||||
|
||||
message.Write(largeUpdateTimer <= 0);
|
||||
message.Write(AnimController.limbs.Count());
|
||||
|
||||
if (largeUpdateTimer<=0)
|
||||
|
||||
message.Write(LargeUpdateTimer <= 0);
|
||||
|
||||
if (LargeUpdateTimer<=0)
|
||||
{
|
||||
foreach (Limb limb in animController.limbs)
|
||||
int i = 0;
|
||||
foreach (Limb limb in AnimController.limbs)
|
||||
{
|
||||
message.Write(42.0f+i);
|
||||
message.Write(limb.body.Position.X);
|
||||
message.Write(limb.body.Position.Y);
|
||||
|
||||
@@ -885,19 +888,20 @@ namespace Subsurface
|
||||
|
||||
message.Write(limb.body.Rotation);
|
||||
message.Write(limb.body.AngularVelocity);
|
||||
i++;
|
||||
}
|
||||
|
||||
message.Write(animController.StunTimer);
|
||||
message.Write(AnimController.StunTimer);
|
||||
|
||||
largeUpdateTimer = 5;
|
||||
LargeUpdateTimer = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
Limb torso = animController.GetLimb(LimbType.Torso);
|
||||
Limb torso = AnimController.GetLimb(LimbType.Torso);
|
||||
message.Write(torso.body.Position.X);
|
||||
message.Write(torso.body.Position.Y);
|
||||
|
||||
largeUpdateTimer = (byte)Math.Max(0, largeUpdateTimer-1);
|
||||
LargeUpdateTimer = (byte)Math.Max(0, LargeUpdateTimer-1);
|
||||
}
|
||||
|
||||
|
||||
@@ -950,7 +954,7 @@ namespace Subsurface
|
||||
targetMovement.X = message.ReadFloat();
|
||||
targetMovement.Y = message.ReadFloat();
|
||||
|
||||
animController.isStanding = true;
|
||||
AnimController.IsStanding = true;
|
||||
|
||||
bool targetDir = message.ReadBoolean();
|
||||
|
||||
@@ -958,67 +962,77 @@ namespace Subsurface
|
||||
cursorPos.X = message.ReadFloat();
|
||||
cursorPos.Y = message.ReadFloat();
|
||||
|
||||
if (sendingTime > lastNetworkUpdate)
|
||||
{
|
||||
cursorPosition = cursorPos;
|
||||
int num1 = message.ReadInt32();
|
||||
System.Diagnostics.Debug.WriteLine(num1);
|
||||
|
||||
animController.TargetMovement= targetMovement;
|
||||
animController.targetDir = (targetDir) ? Direction.Right : Direction.Left;
|
||||
if (sendingTime <= LastNetworkUpdate) return;
|
||||
|
||||
cursorPosition = cursorPos;
|
||||
|
||||
|
||||
AnimController.TargetMovement= targetMovement;
|
||||
AnimController.TargetDir = (targetDir) ? Direction.Right : Direction.Left;
|
||||
|
||||
if (message.ReadBoolean())
|
||||
if (message.ReadBoolean())
|
||||
{
|
||||
foreach (Limb limb in AnimController.limbs)
|
||||
{
|
||||
foreach (Limb limb in animController.limbs)
|
||||
float num = message.ReadFloat();
|
||||
System.Diagnostics.Debug.WriteLine(num);
|
||||
Vector2 pos = Vector2.Zero;
|
||||
pos.X = message.ReadFloat();
|
||||
pos.Y = message.ReadFloat();
|
||||
|
||||
Vector2 vel = Vector2.Zero;
|
||||
vel.X = message.ReadFloat();
|
||||
vel.Y = message.ReadFloat();
|
||||
|
||||
float rotation = message.ReadFloat();
|
||||
float angularVel = message.ReadFloat();
|
||||
|
||||
|
||||
|
||||
if (vel != Vector2.Zero && vel.Length() > 100.0f) { }
|
||||
|
||||
if (pos != Vector2.Zero && pos.Length() > 100.0f) { }
|
||||
|
||||
if (limb.body != null)
|
||||
{
|
||||
Vector2 pos = Vector2.Zero;
|
||||
pos.X = message.ReadFloat();
|
||||
pos.Y = message.ReadFloat();
|
||||
|
||||
Vector2 vel = Vector2.Zero;
|
||||
vel.X = message.ReadFloat();
|
||||
vel.Y = message.ReadFloat();
|
||||
|
||||
float rotation = message.ReadFloat();
|
||||
float angularVel = message.ReadFloat();
|
||||
|
||||
if (limb.body == null) continue;
|
||||
|
||||
if (vel != Vector2.Zero && vel.Length() > 100.0f) { }
|
||||
|
||||
if (pos != Vector2.Zero && pos.Length() > 100.0f) { }
|
||||
|
||||
limb.body.TargetVelocity = vel;
|
||||
limb.body.TargetPosition = pos;// +vel * (float)(deltaTime / 60.0);
|
||||
limb.body.TargetRotation = rotation;// +angularVel * (float)(deltaTime / 60.0);
|
||||
limb.body.TargetAngularVelocity = angularVel;
|
||||
}
|
||||
|
||||
animController.StunTimer = message.ReadFloat();
|
||||
|
||||
largeUpdateTimer = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector2 pos = Vector2.Zero;
|
||||
pos.X = message.ReadFloat();
|
||||
pos.Y = message.ReadFloat();
|
||||
|
||||
Limb torso = animController.GetLimb(LimbType.Torso);
|
||||
torso.body.TargetPosition = pos;
|
||||
|
||||
largeUpdateTimer = 0;
|
||||
}
|
||||
|
||||
if (aiController != null) aiController.ReadNetworkData(message);
|
||||
AnimController.StunTimer = message.ReadFloat();
|
||||
|
||||
lastNetworkUpdate = sendingTime;
|
||||
LargeUpdateTimer = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector2 pos = Vector2.Zero;
|
||||
pos.X = message.ReadFloat();
|
||||
pos.Y = message.ReadFloat();
|
||||
|
||||
Limb torso = AnimController.GetLimb(LimbType.Torso);
|
||||
torso.body.TargetPosition = pos;
|
||||
|
||||
LargeUpdateTimer = 0;
|
||||
}
|
||||
|
||||
if (aiController != null) aiController.ReadNetworkData(message);
|
||||
|
||||
LastNetworkUpdate = sendingTime;
|
||||
|
||||
}
|
||||
|
||||
public override void Remove()
|
||||
{
|
||||
base.Remove();
|
||||
|
||||
characterList.Remove(this);
|
||||
CharacterList.Remove(this);
|
||||
|
||||
if (controlled == this) controlled = null;
|
||||
|
||||
@@ -1027,8 +1041,8 @@ namespace Subsurface
|
||||
if (aiTarget != null)
|
||||
aiTarget.Remove();
|
||||
|
||||
if (animController!=null)
|
||||
animController.Remove();
|
||||
if (AnimController!=null)
|
||||
AnimController.Remove();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,17 +7,17 @@ namespace Subsurface
|
||||
|
||||
class CharacterInfo
|
||||
{
|
||||
public string name;
|
||||
public string Name;
|
||||
|
||||
public readonly string file;
|
||||
public readonly string File;
|
||||
|
||||
public readonly int headSpriteId;
|
||||
public int HeadSpriteId;
|
||||
|
||||
//public int ID;
|
||||
|
||||
public Gender gender;
|
||||
public Gender Gender;
|
||||
|
||||
public int salary;
|
||||
public int Salary;
|
||||
|
||||
//public string GenderString()
|
||||
//{
|
||||
@@ -26,25 +26,25 @@ namespace Subsurface
|
||||
|
||||
public CharacterInfo(string file, string name = "", Gender gender = Gender.None)
|
||||
{
|
||||
this.file = file;
|
||||
this.File = file;
|
||||
|
||||
//ID = -1;
|
||||
|
||||
XDocument doc = ToolBox.TryLoadXml(file);
|
||||
if (doc == null) return;
|
||||
|
||||
salary = 500;
|
||||
Salary = 500;
|
||||
|
||||
if (ToolBox.GetAttributeBool(doc.Root, "genders", false))
|
||||
{
|
||||
if (gender == Gender.None)
|
||||
{
|
||||
float femaleRatio = ToolBox.GetAttributeFloat(doc.Root, "femaleratio", 0.5f);
|
||||
this.gender = (Game1.random.NextDouble() < femaleRatio) ? Gender.Female : Gender.Male;
|
||||
this.Gender = (Rand.Range(0.0f, 1.0f, false) < femaleRatio) ? Gender.Female : Gender.Male;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.gender = gender;
|
||||
this.Gender = gender;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,18 +53,18 @@ namespace Subsurface
|
||||
{
|
||||
headSpriteRange = ToolBox.GetAttributeVector2(
|
||||
doc.Root,
|
||||
this.gender == Gender.Female ? "femaleheadid" : "maleheadid",
|
||||
this.Gender == Gender.Female ? "femaleheadid" : "maleheadid",
|
||||
Vector2.Zero);
|
||||
}
|
||||
|
||||
if (headSpriteRange != Vector2.Zero)
|
||||
{
|
||||
headSpriteId = Game1.localRandom.Next((int)headSpriteRange.X, (int)headSpriteRange.Y + 1);
|
||||
HeadSpriteId = Rand.Range((int)headSpriteRange.X, (int)headSpriteRange.Y + 1);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(name))
|
||||
{
|
||||
this.name = name;
|
||||
this.Name = name;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -73,32 +73,32 @@ namespace Subsurface
|
||||
string firstNamePath = (ToolBox.GetAttributeString(doc.Root.Element("name"), "firstname", ""));
|
||||
if (firstNamePath != "")
|
||||
{
|
||||
firstNamePath = firstNamePath.Replace("[GENDER]", (this.gender == Gender.Female) ? "f" : "");
|
||||
this.name = ToolBox.GetRandomLine(firstNamePath);
|
||||
firstNamePath = firstNamePath.Replace("[GENDER]", (this.Gender == Gender.Female) ? "f" : "");
|
||||
this.Name = ToolBox.GetRandomLine(firstNamePath);
|
||||
}
|
||||
|
||||
string lastNamePath = (ToolBox.GetAttributeString(doc.Root.Element("name"), "lastname", ""));
|
||||
if (lastNamePath != "")
|
||||
{
|
||||
lastNamePath = lastNamePath.Replace("[GENDER]", (this.gender == Gender.Female) ? "f" : "");
|
||||
if (this.name != "") this.name += " ";
|
||||
this.name += ToolBox.GetRandomLine(lastNamePath);
|
||||
lastNamePath = lastNamePath.Replace("[GENDER]", (this.Gender == Gender.Female) ? "f" : "");
|
||||
if (this.Name != "") this.Name += " ";
|
||||
this.Name += ToolBox.GetRandomLine(lastNamePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CharacterInfo(XElement element)
|
||||
{
|
||||
name = ToolBox.GetAttributeString(element, "name", "unnamed");
|
||||
Name = ToolBox.GetAttributeString(element, "name", "unnamed");
|
||||
|
||||
string genderStr = ToolBox.GetAttributeString(element, "gender", "male").ToLower();
|
||||
gender = (genderStr == "male") ? Gender.Male : Gender.Female;
|
||||
Gender = (genderStr == "male") ? Gender.Male : Gender.Female;
|
||||
|
||||
file = ToolBox.GetAttributeString(element, "file", "");
|
||||
File = ToolBox.GetAttributeString(element, "file", "");
|
||||
|
||||
salary = ToolBox.GetAttributeInt(element, "salary", 1000);
|
||||
Salary = ToolBox.GetAttributeInt(element, "salary", 1000);
|
||||
|
||||
headSpriteId = ToolBox.GetAttributeInt(element, "headspriteid", 1);
|
||||
HeadSpriteId = ToolBox.GetAttributeInt(element, "headspriteid", 1);
|
||||
}
|
||||
|
||||
public virtual XElement Save(XElement parentElement)
|
||||
@@ -106,11 +106,11 @@ namespace Subsurface
|
||||
XElement componentElement = new XElement("character");
|
||||
|
||||
componentElement.Add(
|
||||
new XAttribute("name", name),
|
||||
new XAttribute("file", file),
|
||||
new XAttribute("gender", gender == Gender.Male ? "male" : "female"),
|
||||
new XAttribute("salary", salary),
|
||||
new XAttribute("headspriteid", headSpriteId));
|
||||
new XAttribute("name", Name),
|
||||
new XAttribute("file", File),
|
||||
new XAttribute("gender", Gender == Gender.Male ? "male" : "female"),
|
||||
new XAttribute("salary", Salary),
|
||||
new XAttribute("headspriteid", HeadSpriteId));
|
||||
|
||||
parentElement.Add(componentElement);
|
||||
return componentElement;
|
||||
|
||||
@@ -6,15 +6,15 @@ namespace Subsurface
|
||||
{
|
||||
class DelayedEffect : StatusEffect
|
||||
{
|
||||
public static List<DelayedEffect> list = new List<DelayedEffect>();
|
||||
public static List<DelayedEffect> List = new List<DelayedEffect>();
|
||||
|
||||
float delay;
|
||||
private float delay;
|
||||
|
||||
float timer;
|
||||
|
||||
Vector2 position;
|
||||
private float timer;
|
||||
|
||||
List<IPropertyObject> targets;
|
||||
private Vector2 position;
|
||||
|
||||
private List<IPropertyObject> targets;
|
||||
|
||||
public float Timer
|
||||
{
|
||||
@@ -36,7 +36,7 @@ namespace Subsurface
|
||||
|
||||
this.targets = targets;
|
||||
|
||||
list.Add(this);
|
||||
List.Add(this);
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
@@ -46,7 +46,7 @@ namespace Subsurface
|
||||
if (timer > 0.0f) return;
|
||||
|
||||
base.Apply(1.0f, position, targets);
|
||||
list.Remove(this);
|
||||
List.Remove(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -62,11 +62,11 @@ namespace Subsurface
|
||||
//targetDir = (movement.X > 0.0f) ? Direction.Right : Direction.Left;
|
||||
if (movement.X > 0.1f && movement.X > Math.Abs(movement.Y))
|
||||
{
|
||||
targetDir = Direction.Right;
|
||||
TargetDir = Direction.Right;
|
||||
}
|
||||
else if (movement.X < -0.1f && movement.X < -Math.Abs(movement.Y))
|
||||
{
|
||||
targetDir = Direction.Left;
|
||||
TargetDir = Direction.Left;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -79,17 +79,17 @@ namespace Subsurface
|
||||
|
||||
if (rotation > 20 && rotation < 160)
|
||||
{
|
||||
targetDir = Direction.Left;
|
||||
TargetDir = Direction.Left;
|
||||
}
|
||||
else if (rotation > 200 && rotation < 340)
|
||||
{
|
||||
targetDir = Direction.Right;
|
||||
TargetDir = Direction.Right;
|
||||
}
|
||||
}
|
||||
|
||||
//if (stunTimer > gameTime.TotalGameTime.TotalMilliseconds) return;
|
||||
|
||||
if (targetDir != dir)
|
||||
if (TargetDir != dir)
|
||||
{
|
||||
Flip();
|
||||
if (flip) Mirror();
|
||||
@@ -213,7 +213,7 @@ namespace Subsurface
|
||||
//out whether the ragdoll is standing on ground
|
||||
float closestFraction = 1;
|
||||
//Structure closestStructure = null;
|
||||
Game1.world.RayCast((fixture, point, normal, fraction) =>
|
||||
Game1.World.RayCast((fixture, point, normal, fraction) =>
|
||||
{
|
||||
//other limbs and bodies with no collision detection are ignored
|
||||
if (fixture == null ||
|
||||
|
||||
@@ -20,13 +20,13 @@ namespace Subsurface
|
||||
Vector2 rayStart = colliderPos; // at the bottom of the player sprite
|
||||
Vector2 rayEnd = rayStart - new Vector2(0.0f, TorsoPosition);
|
||||
if (stairs != null) rayEnd.Y -= 0.5f;
|
||||
if (anim != Animation.UsingConstruction) ResetPullJoints();
|
||||
if (Anim != Animation.UsingConstruction) ResetPullJoints();
|
||||
|
||||
//do a raytrace straight down from the torso to figure
|
||||
//out whether the ragdoll is standing on ground
|
||||
float closestFraction = 1;
|
||||
Structure closestStructure = null;
|
||||
Game1.world.RayCast((fixture, point, normal, fraction) =>
|
||||
Game1.World.RayCast((fixture, point, normal, fraction) =>
|
||||
{
|
||||
switch (fixture.CollisionCategories)
|
||||
{
|
||||
@@ -119,7 +119,7 @@ namespace Subsurface
|
||||
return;
|
||||
}
|
||||
|
||||
switch (anim)
|
||||
switch (Anim)
|
||||
{
|
||||
case Animation.Climbing:
|
||||
UpdateClimbing();
|
||||
@@ -129,13 +129,13 @@ namespace Subsurface
|
||||
default:
|
||||
if (inWater)
|
||||
UpdateSwimming();
|
||||
else if (isStanding)
|
||||
else if (IsStanding)
|
||||
UpdateStanding();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (targetDir != dir) Flip();
|
||||
if (TargetDir != dir) Flip();
|
||||
|
||||
foreach (Limb limb in limbs)
|
||||
{
|
||||
@@ -376,9 +376,9 @@ namespace Subsurface
|
||||
if (!character.IsNetworkPlayer)
|
||||
{
|
||||
if (rotation > 20 && rotation < 170)
|
||||
targetDir = Direction.Left;
|
||||
TargetDir = Direction.Left;
|
||||
else if (rotation > 190 && rotation < 340)
|
||||
targetDir = Direction.Right;
|
||||
TargetDir = Direction.Right;
|
||||
}
|
||||
|
||||
if (TargetMovement == Vector2.Zero) return;
|
||||
@@ -520,7 +520,7 @@ namespace Subsurface
|
||||
{
|
||||
if (character.SelectedConstruction == null)
|
||||
{
|
||||
anim = Animation.None;
|
||||
Anim = Animation.None;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -597,7 +597,7 @@ namespace Subsurface
|
||||
torso.body.ApplyForce(climbForce * 65.0f * torso.Mass);
|
||||
head.body.SmoothRotate(0.0f);
|
||||
|
||||
Rectangle trigger = character.SelectedConstruction.Prefab.triggers.First();
|
||||
Rectangle trigger = character.SelectedConstruction.Prefab.Triggers.First();
|
||||
trigger = character.SelectedConstruction.TransformTrigger(trigger);
|
||||
|
||||
//stop climbing if:
|
||||
@@ -609,7 +609,7 @@ namespace Subsurface
|
||||
(TargetMovement.Y < 0.0f && ConvertUnits.ToSimUnits(trigger.Height) + handPos.Y < HeadPosition*2.0f) ||
|
||||
(TargetMovement.Y > 0.0f && -handPos.Y < ConvertUnits.ToSimUnits(10.0f)))
|
||||
{
|
||||
anim = Animation.None;
|
||||
Anim = Animation.None;
|
||||
character.SelectedConstruction = null;
|
||||
IgnorePlatforms = false;
|
||||
}
|
||||
|
||||
@@ -208,7 +208,7 @@ namespace Subsurface
|
||||
pullJoint.Enabled = false;
|
||||
pullJoint.MaxForce = 150.0f * body.Mass;
|
||||
|
||||
Game1.world.AddJoint(pullJoint);
|
||||
Game1.World.AddJoint(pullJoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -235,10 +235,10 @@ namespace Subsurface
|
||||
case "sprite":
|
||||
string spritePath = subElement.Attribute("texture").Value;
|
||||
|
||||
if (character.info!=null)
|
||||
if (character.Info!=null)
|
||||
{
|
||||
spritePath = spritePath.Replace("[GENDER]", (character.info.gender == Gender.Female) ? "f" : "");
|
||||
spritePath = spritePath.Replace("[HEADID]", character.info.headSpriteId.ToString());
|
||||
spritePath = spritePath.Replace("[GENDER]", (character.Info.Gender == Gender.Female) ? "f" : "");
|
||||
spritePath = spritePath.Replace("[HEADID]", character.Info.HeadSpriteId.ToString());
|
||||
}
|
||||
|
||||
|
||||
@@ -323,7 +323,7 @@ namespace Subsurface
|
||||
|
||||
Game1.particleManager.CreateParticle("blood",
|
||||
SimPosition,
|
||||
particleVel * MathUtils.RandomFloatLocal(1.0f, 3.0f));
|
||||
particleVel * Rand.Range(1.0f, 3.0f));
|
||||
}
|
||||
|
||||
for (int i = 0; i < bloodAmount / 2; i++)
|
||||
@@ -339,7 +339,7 @@ namespace Subsurface
|
||||
if (LinearVelocity.X>100.0f)
|
||||
{
|
||||
DebugConsole.ThrowError("CHARACTER EXPLODED");
|
||||
foreach (Limb limb in character.animController.limbs)
|
||||
foreach (Limb limb in character.AnimController.limbs)
|
||||
{
|
||||
limb.body.ResetDynamics();
|
||||
limb.body.SetTransform(body.Position, 0.0f);
|
||||
|
||||
@@ -197,7 +197,7 @@ namespace Subsurface
|
||||
joint.MotorEnabled = true;
|
||||
joint.MaxMotorTorque = 0.25f;
|
||||
|
||||
Game1.world.AddJoint(joint);
|
||||
Game1.World.AddJoint(joint);
|
||||
|
||||
for (int i = 0; i < limbJoints.Length; i++ )
|
||||
{
|
||||
@@ -223,7 +223,7 @@ namespace Subsurface
|
||||
float startDepth = 0.1f;
|
||||
float increment = 0.0001f;
|
||||
|
||||
foreach (Character otherCharacter in Character.characterList)
|
||||
foreach (Character otherCharacter in Character.CharacterList)
|
||||
{
|
||||
if (otherCharacter==character) continue;
|
||||
startDepth+=increment;
|
||||
@@ -541,7 +541,7 @@ namespace Subsurface
|
||||
float allowedDistance = 0.1f;
|
||||
|
||||
float dist = Vector2.Distance(limbs[0].body.Position, refLimb.body.TargetPosition);
|
||||
bool resetAll = (dist > resetDistance && character.largeUpdateTimer == 1);
|
||||
bool resetAll = (dist > resetDistance && character.LargeUpdateTimer == 1);
|
||||
|
||||
Vector2 newMovement = (refLimb.body.TargetPosition - refLimb.body.Position);
|
||||
|
||||
@@ -632,7 +632,7 @@ namespace Subsurface
|
||||
foreach (Limb l in limbs) l.Remove();
|
||||
foreach (RevoluteJoint joint in limbJoints)
|
||||
{
|
||||
Game1.world.RemoveJoint(joint);
|
||||
Game1.World.RemoveJoint(joint);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -237,9 +237,9 @@ namespace Subsurface
|
||||
|
||||
public static void UpdateAll(float deltaTime)
|
||||
{
|
||||
for (int i = DelayedEffect.list.Count-1; i>= 0; i--)
|
||||
for (int i = DelayedEffect.List.Count-1; i>= 0; i--)
|
||||
{
|
||||
DelayedEffect.list[i].Update(deltaTime);
|
||||
DelayedEffect.List[i].Update(deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user