A* pathfinding, autopilot, WIP radar rendering, proper location names, character skills shown in menus, got rid of PreviewCharacter, mantis

This commit is contained in:
Regalis
2015-07-14 21:09:00 +03:00
parent a2636133ca
commit 44b9a63c94
51 changed files with 1971 additions and 940 deletions

View File

@@ -196,6 +196,11 @@ namespace FarseerPhysics.Collision.Shapes
I += (0.25f * k_inv3 * D) * (intx2 + inty2);
}
if (area <= Settings.Epsilon)
{
int alsmfkldsmfdkasf = 1;
}
//The area is too small for the engine to handle.
Debug.Assert(area > Settings.Epsilon);

View File

@@ -0,0 +1,240 @@
using Microsoft.Xna.Framework;
using System.Collections.Generic;
using System.Linq;
namespace Subsurface
{
class PathNode
{
private WayPoint wayPoint;
private int wayPointID;
public int state;
public PathNode Parent;
private Vector2 position;
public float F,G,H;
public List<PathNode> connections;
public float[] distances;
public WayPoint Waypoint
{
get { return wayPoint; }
}
public Vector2 Position
{
get {return position;}
}
public PathNode(WayPoint wayPoint)
{
this.wayPoint = wayPoint;
this.position = wayPoint.SimPosition;
wayPointID = wayPoint.ID;
connections = new List<PathNode>();
}
public static List<PathNode> GenerateNodes(List<WayPoint> wayPoints)
{
var nodes = new Dictionary<int, PathNode>();
foreach (WayPoint wayPoint in wayPoints)
{
nodes.Add(wayPoint.ID, new PathNode(wayPoint));
}
foreach (KeyValuePair<int,PathNode> node in nodes)
{
foreach (MapEntity linked in node.Value.wayPoint.linkedTo)
{
PathNode connectedNode = null;
nodes.TryGetValue(linked.ID, out connectedNode);
if (connectedNode == null) continue;
node.Value.connections.Add(connectedNode);
}
}
var nodeList = nodes.Values.ToList();
foreach (PathNode node in nodeList)
{
node.distances = new float[node.connections.Count];
for (int i = 0; i< node.distances.Length; i++)
{
node.distances[i] = Vector2.Distance(node.position, node.connections[i].position);
}
}
return nodeList;
}
}
class PathFinder
{
List<PathNode> nodes;
private bool insideSubmarine;
public PathFinder(List<WayPoint> wayPoints, bool insideSubmarine = false)
{
nodes = PathNode.GenerateNodes(wayPoints.FindAll(w => w.MoveWithLevel != insideSubmarine));
this.insideSubmarine = insideSubmarine;
}
public SteeringPath FindPath(Vector2 start, Vector2 end)
{
float closestDist = 0.0f;
PathNode startNode = null;
foreach (PathNode node in nodes)
{
float dist = Vector2.Distance(start,node.Position);
if (dist<closestDist || startNode==null)
{
closestDist = dist;
startNode = node;
}
}
closestDist = 0.0f;
PathNode endNode = null;
foreach (PathNode node in nodes)
{
float dist = Vector2.Distance(end, node.Position);
if (dist < closestDist || endNode == null)
{
closestDist = dist;
endNode = node;
}
}
if (startNode == null || endNode == null)
{
DebugConsole.ThrowError("Pathfinding error, couldn't find pathnodes");
return null;
}
return FindPath(startNode,endNode);
}
public SteeringPath FindPath(WayPoint start, WayPoint end)
{
PathNode startNode=null, endNode=null;
foreach (PathNode node in nodes)
{
if (node.Waypoint == start)
{
startNode = node;
if (endNode != null) break;
}
if (node.Waypoint == end)
{
endNode = node;
if (startNode != null) break;
}
if (startNode==null || endNode==null)
{
DebugConsole.ThrowError("Pathfinding error, couldn't find matching pathnodes to waypoints");
return null;
}
}
return FindPath(startNode, endNode);
}
private SteeringPath FindPath(PathNode start, PathNode end)
{
foreach (PathNode node in nodes)
{
node.state = 0;
node.F = 0.0f;
node.G = 0.0f;
node.H = 0.0f;
}
start.state = 1;
while (true)
{
PathNode currNode = null;
float dist = 10000.0f;
foreach (PathNode node in nodes)
{
if (node.state != 1) continue;
if (node.F < dist)
{
dist = node.F;
currNode = node;
}
}
if (currNode == null || currNode == end) break;
currNode.state = 2;
for (int i = 0; i < currNode.connections.Count; i++)
{
PathNode nextNode = currNode.connections[i];
//a node that hasn't been searched yet
if (nextNode.state==0)
{
nextNode.H = Vector2.Distance(nextNode.Position,end.Position);
nextNode.G = currNode.G + currNode.distances[i];
nextNode.F = nextNode.G + nextNode.H;
nextNode.Parent = currNode;
nextNode.state = 1;
}
//node that has been searched
else if (nextNode.state==1)
{
float tempG = currNode.G + currNode.distances[i];
//only use if this new route is better than the
//route the node was a part of
if (tempG < nextNode.G)
{
nextNode.G = tempG;
nextNode.F = nextNode.G + nextNode.H;
nextNode.Parent = currNode;
}
}
}
}
if (end.state==0)
{
//path not found
return new SteeringPath();
}
SteeringPath path = new SteeringPath();
List<WayPoint> finalPath = new List<WayPoint>();
PathNode pathNode = end;
while (pathNode != start && pathNode != null)
{
finalPath.Add(pathNode.Waypoint);
pathNode = pathNode.Parent;
}
finalPath.Reverse();
foreach (WayPoint wayPoint in finalPath)
{
path.AddNode(wayPoint);
}
return path;
}
}
}

View File

@@ -5,32 +5,30 @@ namespace Subsurface
{
class SteeringPath
{
private Queue<Vector2> nodes;
const float MinDistance = 0.1f;
Vector2 currentNode;
private Queue<WayPoint> nodes;
WayPoint currentNode;
public SteeringPath()
{
nodes = new Queue<Vector2>();
nodes = new Queue<WayPoint>();
}
public void AddNode(Vector2 node)
public void AddNode(WayPoint node)
{
if (node == Vector2.Zero) return;
if (node == null) return;
nodes.Enqueue(node);
}
public Vector2 CurrentNode
public WayPoint CurrentNode
{
get { return currentNode; }
}
public Vector2 GetNode(Vector2 pos)
public WayPoint GetNode(Vector2 pos, float minDistance = 0.1f)
{
if (nodes.Count == 0) return Vector2.Zero;
if (currentNode == Vector2.Zero || Vector2.Distance(pos, currentNode) < MinDistance) currentNode = nodes.Dequeue();
if (nodes.Count == 0) return null;
if (currentNode == null || Vector2.Distance(pos, currentNode.SimPosition) < minDistance) currentNode = nodes.Dequeue();
return currentNode;
}

View File

@@ -1,4 +1,5 @@
using FarseerPhysics;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Dynamics.Joints;
using Lidgren.Network;
using Microsoft.Xna.Framework;
@@ -94,6 +95,11 @@ namespace Subsurface
}
}
public float Mass
{
get { return AnimController.Mass; }
}
public Inventory Inventory
{
get { return inventory; }
@@ -397,6 +403,11 @@ namespace Subsurface
}
}
public int GetSkillLevel(string skillName)
{
return Info.Job.GetSkillLevel(skillName);
}
public void Control(float deltaTime, Camera cam, bool forcePick = false)
{
if (isDead) return;
@@ -509,12 +520,23 @@ namespace Subsurface
if (moveCam)
{
cam.TargetPos = ConvertUnits.ToDisplayUnits(AnimController.limbs[0].SimPosition);
cam.OffsetAmount = 250.0f;
cam.OffsetAmount = MathHelper.Lerp(cam.OffsetAmount, 250.0f, 0.05f);
}
cursorPosition = cam.ScreenToWorld(PlayerInput.MousePosition);
Vector2 mouseSimPos = ConvertUnits.ToSimUnits(cursorPosition);
Body body = Submarine.PickBody(AnimController.limbs[0].SimPosition, mouseSimPos);
Structure structure = null;
if (body != null) structure = body.UserData as Structure;
if (structure!=null)
{
if (!structure.CastShadow && moveCam)
{
cam.OffsetAmount = MathHelper.Lerp(cam.OffsetAmount, 500.0f, 0.05f);
}
}
if (AnimController.onGround &&
!AnimController.InWater &&
AnimController.Anim != AnimController.Animation.UsingConstruction)
@@ -780,14 +802,12 @@ namespace Subsurface
if (torso == null) torso = AnimController.GetLimb(LimbType.Head);
Vector2 centerOfMass = Vector2.Zero;
float totalMass = 0.0f;
foreach (Limb limb in AnimController.limbs)
{
centerOfMass += limb.Mass * limb.SimPosition;
totalMass += limb.Mass;
}
centerOfMass /= totalMass;
centerOfMass /= AnimController.Mass;
health = 0.0f;

View File

@@ -15,7 +15,17 @@ namespace Subsurface
public Job Job;
public Gender Gender;
private Gender gender;
public Gender Gender
{
get { return gender; }
set
{
if (gender == value) return;
gender = value;
LoadHeadSprite();
}
}
public int Salary;
@@ -26,6 +36,16 @@ namespace Subsurface
// return gender.ToString();
//}
private Sprite headSprite;
public Sprite HeadSprite
{
get
{
if (headSprite == null) LoadHeadSprite();
return headSprite;
}
}
public CharacterInfo(string file, string name = "", Gender gender = Gender.None, JobPrefab jobPrefab = null)
{
this.File = file;
@@ -42,11 +62,11 @@ namespace Subsurface
if (gender == Gender.None)
{
float femaleRatio = ToolBox.GetAttributeFloat(doc.Root, "femaleratio", 0.5f);
this.Gender = (Rand.Range(0.0f, 1.0f, false) < 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;
}
}
@@ -55,7 +75,7 @@ namespace Subsurface
{
headSpriteRange = ToolBox.GetAttributeVector2(
doc.Root,
this.Gender == Gender.Female ? "femaleheadid" : "maleheadid",
this.gender == Gender.Female ? "femaleheadid" : "maleheadid",
Vector2.Zero);
}
@@ -77,26 +97,82 @@ namespace Subsurface
string firstNamePath = ToolBox.GetAttributeString(doc.Root.Element("name"), "firstname", "");
if (firstNamePath != "")
{
firstNamePath = firstNamePath.Replace("[GENDER]", (this.Gender == Gender.Female) ? "f" : "");
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" : "");
lastNamePath = lastNamePath.Replace("[GENDER]", (this.gender == Gender.Female) ? "f" : "");
if (this.Name != "") this.Name += " ";
this.Name += ToolBox.GetRandomLine(lastNamePath);
}
}
}
private void LoadHeadSprite()
{
XDocument doc = ToolBox.TryLoadXml(File);
if (doc == null) return;
XElement ragdollElement = doc.Root.Element("ragdoll");
foreach (XElement limbElement in ragdollElement.Elements())
{
if (ToolBox.GetAttributeString(limbElement, "type", "").ToLower() != "head") continue;
XElement spriteElement = limbElement.Element("sprite");
string spritePath = spriteElement.Attribute("texture").Value;
spritePath = spritePath.Replace("[GENDER]", (this.gender == Gender.Female) ? "f" : "");
spritePath = spritePath.Replace("[HEADID]", HeadSpriteId.ToString());
headSprite = new Sprite(spriteElement, "", spritePath);
break;
}
}
public GUIFrame CreateInfoFrame(Rectangle rect)
{
GUIFrame frame = new GUIFrame(rect, Color.Transparent);
frame.Padding = new Vector4(10.0f,10.0f,10.0f,10.0f);
return CreateInfoFrame(frame);
}
public GUIFrame CreateInfoFrame(GUIFrame frame)
{
GUIImage image = new GUIImage(new Rectangle(0,0,30,30), HeadSprite, Alignment.TopLeft, frame);
int x = 0, y = 0;
new GUITextBlock(new Rectangle(x+80, y, 200, 20), Name, GUI.style, frame);
y += 20;
new GUITextBlock(new Rectangle(x+80, y, 200, 20), Job.Name, GUI.style, frame);
y += 30;
var skills = Job.Skills;
skills.Sort((s1, s2) => -s1.Level.CompareTo(s2.Level));
new GUITextBlock(new Rectangle(x, y, 200, 20), "Skills:", GUI.style, frame);
y += 20;
foreach (Skill skill in skills)
{
Color textColor = Color.White * (0.5f + skill.Level/200.0f);
new GUITextBlock(new Rectangle(x+20, y, 200, 20), skill.Name, Color.Transparent, textColor, Alignment.Left, GUI.style, frame);
new GUITextBlock(new Rectangle(x + 20, y, 200, 20), skill.Level.ToString(), Color.Transparent, textColor, Alignment.Right, GUI.style, frame);
y += 20;
}
return frame;
}
public CharacterInfo(XElement element)
{
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", "");
Salary = ToolBox.GetAttributeInt(element, "salary", 1000);
@@ -119,7 +195,7 @@ namespace Subsurface
charElement.Add(
new XAttribute("name", Name),
new XAttribute("file", File),
new XAttribute("gender", Gender == Gender.Male ? "male" : "female"),
new XAttribute("gender", gender == Gender.Male ? "male" : "female"),
new XAttribute("salary", Salary),
new XAttribute("headspriteid", HeadSpriteId),
new XAttribute("startitemsgiven", StartItemsGiven));

View File

@@ -20,6 +20,8 @@ namespace Subsurface
private float flipTimer;
private float? footRotation;
public FishAnimController(Character character, XElement element)
: base(character, element)
{
@@ -31,6 +33,12 @@ namespace Subsurface
walkSpeed = ToolBox.GetAttributeFloat(element, "walkspeed", 1.0f);
swimSpeed = ToolBox.GetAttributeFloat(element, "swimspeed", 1.0f);
float footRot = ToolBox.GetAttributeFloat(element,"footrotation", float.NaN);
if (!float.IsNaN(footRot))
{
footRotation = MathHelper.ToRadians(footRot);
}
rotateTowardsMovement = ToolBox.GetAttributeBool(element, "rotatetowardsmovement", true);
}
@@ -202,19 +210,20 @@ namespace Subsurface
Limb torso = GetLimb(LimbType.Torso);
Limb head = GetLimb(LimbType.Head);
if (torso!=null)
{
colliderLimb = torso;
colliderHeight = TorsoPosition;
colliderLimb.body.SmoothRotate(TorsoAngle*Dir, 5.0f);
colliderLimb.body.SmoothRotate(TorsoAngle*Dir, 10.0f);
}
else
{
colliderLimb = head;
colliderHeight = HeadPosition;
colliderLimb.body.SmoothRotate(HeadAngle*Dir, 10.0f);
colliderLimb.body.SmoothRotate(HeadAngle*Dir, 100.0f);
}
Vector2 colliderPos = colliderLimb.SimPosition;
@@ -270,7 +279,9 @@ namespace Subsurface
colliderLimb.Move(new Vector2(colliderPos.X + movement.X * 0.2f, floorY + colliderHeight), 5.0f);
}
float walkCycleSpeed = head.LinearVelocity.X * 0.08f;
//colliderLimb.body.SetTransform(Vector2.Zero, colliderLimb.Rotation);
float walkCycleSpeed = head.LinearVelocity.X * 0.05f;
walkPos -= walkCycleSpeed;
@@ -308,6 +319,9 @@ namespace Subsurface
(-transformedStepSize.Y > 0.0f) ? -transformedStepSize.Y : 0.0f),
8.0f);
}
if (footRotation!=null) limb.body.SmoothRotate((float)footRotation*Dir, 50.0f);
break;
case LimbType.LeftLeg:
case LimbType.RightLeg:

View File

@@ -17,6 +17,8 @@ namespace Subsurface
{
Vector2 colliderPos = GetLimb(LimbType.Torso).SimPosition;
if (inWater) stairs = null;
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;
@@ -31,10 +33,11 @@ namespace Subsurface
switch (fixture.CollisionCategories)
{
case Physics.CollisionStairs:
if (inWater) return -1;
Structure structure = fixture.Body.UserData as Structure;
if (stairs == null && !inWater && structure!=null)
if (stairs == null && structure!=null)
{
if (LowestLimb.SimPosition.Y<structure.SimPosition.Y)
if (LowestLimb.SimPosition.Y < structure.SimPosition.Y)
{
return -1;
}
@@ -92,8 +95,7 @@ namespace Subsurface
if (closestFraction == 1) //raycast didn't hit anything
{
floorY = (currentHull == null) ? -1000.0f : ConvertUnits.ToSimUnits(currentHull.Rect.Y - currentHull.Rect.Height);
}
}
else
{
floorY = rayStart.Y + (rayEnd.Y - rayStart.Y) * closestFraction;

View File

@@ -7,12 +7,34 @@ using System.Xml.Linq;
namespace Subsurface
{
class Skill
{
string name;
int level;
public string Name
{
get { return name; }
}
public int Level
{
get { return level; }
}
public Skill(string name, int level)
{
this.name = name;
this.level = level;
}
}
class Job
{
private JobPrefab prefab;
private Dictionary<string, float> skills;
private Dictionary<string, Skill> skills;
public string Name
{
@@ -34,15 +56,26 @@ namespace Subsurface
get { return prefab.ItemNames; }
}
public List<Skill> Skills
{
get { return skills.Values.ToList(); }
}
//public List<float> SkillLevels
//{
// get { return skills.Values.ToList(); }
//}
public Job(JobPrefab jobPrefab)
{
prefab = jobPrefab;
skills = new Dictionary<string, float>();
skills = new Dictionary<string, Skill>();
foreach (KeyValuePair<string, Vector2> skill in prefab.Skills)
{
skills.Add(skill.Key, Rand.Range(skill.Value.X, skill.Value.Y, false));
skills.Add(
skill.Key,
new Skill( skill.Key, (int)Rand.Range(skill.Value.X, skill.Value.Y, false)));
}
}
@@ -53,10 +86,12 @@ namespace Subsurface
foreach (XElement subElement in element.Elements())
{
skills.Add(subElement.Name.ToString(), ToolBox.GetAttributeFloat(subElement, "level", 0.0f));
skills.Add(
subElement.Name.ToString(),
new Skill(subElement.Name.ToString(), ToolBox.GetAttributeInt(subElement, "level", 0)));
}
}
public static Job Random()
{
JobPrefab prefab = JobPrefab.List[Rand.Int(JobPrefab.List.Count-1, false)];
@@ -64,12 +99,12 @@ namespace Subsurface
return new Job(prefab);
}
public float GetSkill(string skillName)
public int GetSkillLevel(string skillName)
{
float skillLevel = 0.0f;
skills.TryGetValue(skillName.ToLower(), out skillLevel);
Skill skill = null;
skills.TryGetValue(skillName, out skill);
return skillLevel;
return (skill==null) ? 0 : skill.Level;
}
public virtual XElement Save(XElement parentElement)
@@ -78,9 +113,9 @@ namespace Subsurface
jobElement.Add(new XAttribute("name", Name));
foreach (KeyValuePair<string, float> skill in skills)
foreach (KeyValuePair<string, Skill> skill in skills)
{
jobElement.Add(new XElement(skill.Key, new XAttribute("level", skill.Value)));
jobElement.Add(new XElement(skill.Key, new XAttribute("level", skill.Value.Level)));
}
parentElement.Add(jobElement);

View File

@@ -85,17 +85,18 @@ namespace Subsurface
{
foreach (XElement subElement in element.Elements())
{
string skillName = subElement.Name.ToString();
if (Skills.ContainsKey(skillName)) continue;
string skillName = ToolBox.GetAttributeString(subElement, "name", "");
var levelAttribute = subElement.Attribute("level").ToString();
if (levelAttribute.Contains("'"))
if (string.IsNullOrEmpty(skillName) || Skills.ContainsKey(skillName)) continue;
var levelString = ToolBox.GetAttributeString(subElement, "level", "");
if (levelString.Contains(","))
{
Skills.Add(skillName, ToolBox.ParseToVector2(levelAttribute, false));
Skills.Add(skillName, ToolBox.ParseToVector2(levelString, false));
}
else
{
float skillLevel = float.Parse(levelAttribute, CultureInfo.InvariantCulture);
float skillLevel = float.Parse(levelString, CultureInfo.InvariantCulture);
Skills.Add(skillName, new Vector2(skillLevel, skillLevel));
}

View File

@@ -59,6 +59,12 @@ namespace Subsurface
get { return lowestLimb; }
}
public float Mass
{
get;
private set;
}
public Vector2 TargetMovement
{
get { return (correctionMovement == Vector2.Zero) ? targetMovement : correctionMovement; }
@@ -173,6 +179,7 @@ namespace Subsurface
limb.body.FarseerBody.OnCollision += OnLimbCollision;
limbs[ID] = limb;
Mass += limb.Mass;
if (!limbDictionary.ContainsKey(limb.type)) limbDictionary.Add(limb.type, limb);
break;
case "joint":
@@ -257,7 +264,7 @@ namespace Subsurface
}
else if (structure.StairDirection!=Direction.None)
{
if (inWater || (!(targetMovement.Y>Math.Abs(targetMovement.X/2.0f)) && lowestLimb.body.Position.Y < ConvertUnits.ToSimUnits(structure.Rect.Y - structure.Rect.Height) + 0.5f))
if (inWater || !(targetMovement.Y>Math.Abs(targetMovement.X/2.0f)) && lowestLimb.body.Position.Y < ConvertUnits.ToSimUnits(structure.Rect.Y - structure.Rect.Height) + 0.5f)
{
stairs = null;
return false;

View File

@@ -2,21 +2,41 @@
<Jobs>
<Captain description="The Commanding Officer with authority over the entire crew." minnumber="1" maxnumber="1">
<Item name="ID Card"/>
<Skills>
<Skill name="Weapons" level="50,60"/>
<Skill name="Construction" level="10,20"/>
<Skill name="Electrical Engineering" level="10,20"/>
</Skills>
</Captain>
<Engineer>
<Skills>
<Skill name="Weapons" level="10,30"/>
<Skill name="Construction" level="30,40"/>
<Skill name="Electrical Engineering" level="50,60"/>
</Skills>
<Item name="ID Card"/>
<Item name="Wrench"/>
<Item name="Screwdriver"/>
</Engineer>
<Mechanic>
<Skills>
<Skill name="Weapons" level="10,30"/>
<Skill name="Construction" level="50,60"/>
<Skill name="Electrical Engineering" level="30,40"/>
</Skills>
<Item name="ID Card"/>
<Item name="Wrench"/>
<Item name="Screwdriver"/>
</Mechanic>
<Assistant allowalways="true">
<Skills>
<Skill name="Weapons" level="0,10"/>
<Skill name="Construction" level="0,10"/>
<Skill name="Electrical Engineering" level="0,10"/>
</Skills>
<Item name="ID Card"/>
<Item name="Wrench"/>
<Item name="Screwdriver"/>

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

View File

@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8" ?>
<character name ="mantis" humanoid="false">
<sound file="Content/Characters/Crawler/attack.ogg" state="Attack" range="500"/>
<ragdoll headposition="80" headangle="-70"
waveamplitude="50.0" wavelength="2500"
swimspeed="2.0" walkspeed="0.5"
stepsize ="30.0,10.0"
stepoffset="30.0,0.0"
legtorque="10"
footrotation ="180.0"
flip="true">
<!-- head -->
<limb id = "0" radius="30" height="30" mass = "6" type="Head" flip="true" steerforce="1.0" armorsector="0.0,180.0" armorvalue="5.0f">
<sprite texture="Content/Characters/Mantis/mantis.png" sourcerect="0,0,101,168" depth="0.02" origin="0.4,0.7"/>
</limb>
<!-- middle part -->
<limb id = "1" width="42" height="61" mass = "6" flip="true" armorsector="0.0,180.0" armorvalue="5.0f">
<sprite texture="Content/Characters/Mantis/mantis.png" sourcerect="3,168,59,64" depth="0.021" origin="0.3,0.65"/>
</limb>
<!-- middle part -->
<limb id = "2" width="35" height="52" mass = "6" flip="true" armorsector="0.0,180.0" armorvalue="5.0f">
<sprite texture="Content/Characters/Mantis/mantis.png" sourcerect="66,180,65,70" depth="0.022" origin="0.3,0.65"/>
</limb>
<!-- tail -->
<limb id = "3" radius="20" mass = "6" type="Tail" flip="true" armorsector="0.0,180.0" armorvalue="5.0f">
<sprite texture="Content/Characters/Mantis/mantis.png" sourcerect="130,158,46,93" depth="0.023" origin="0.37,0.3"/>
</limb>
<limb id = "4" width="15" height="63" mass = "4" refjoint="3" flip="true">
<sprite texture="Content/Characters/Mantis/mantis.png" sourcerect="232,153,20,63" depth="0.012" origin="0.5,0.5"/>
</limb>
<limb id = "5" width="15" height="63" mass = "4" refjoint="3" flip="true">
<sprite texture="Content/Characters/Mantis/mantis.png" sourcerect="231,80,23,67" depth="0.011" origin="0.5,0.5"/>
<sound file ="Content/Sounds/stepMetal.ogg"/>
</limb>
<!-- ""claw" -->
<limb id = "6" width="15" height="63" mass = "4" flip="true" pullpos="0.0,30.0">
<sprite texture="Content/Characters/Mantis/mantis.png" sourcerect="228,1,28,76" depth="0.01" origin="0.5,0.5"/>
<attack type="PinchCW" range="120" duration="0.5" damage="30" stun="0.1" bleedingdamage="5" structuredamage="50" damagetype="slash"/>
<sound file ="Content/Sounds/stepMetal.ogg"/>
</limb>
<limb id = "7" width="15" height="63" mass = "4" type="LeftLeg" flip="true">
<sprite texture="Content/Characters/Mantis/mantis.png" sourcerect="205,91,20,63" depth="0.01" origin="0.5,0.5"/>
</limb>
<limb id = "8" width="15" height="63" mass = "4" type="LeftFoot" flip="true" pullpos="0.0,30.0" refjoint="6">
<sprite texture="Content/Characters/Mantis/mantis.png" sourcerect="206,3,20,85" depth="0.011" origin="0.5,0.5"/>
<sound file ="Content/Sounds/stepMetal.ogg"/>
</limb>
<limb id = "9" width="15" height="63" mass = "4" type="RightLeg" flip="true">
<sprite texture="Content/Characters/Mantis/mantis.png" sourcerect="159,3,38,66" depth="0.01" origin="0.5,0.5"/>
</limb>
<limb id = "10" width="15" height="102" mass = "4" type="RightFoot" flip="true" pullpos="0.0,50.0" refjoint="2">
<sprite texture="Content/Characters/Mantis/mantis.png" sourcerect="111,0,32,112" depth="0.011" origin="0.5,0.5"/>
<sound file ="Content/Sounds/stepMetal.ogg"/>
</limb>
<joint limb1="0" limb1anchor="-5,-25" limb2="1" limb2anchor="0,20" lowerlimit="-20" upperlimit="20"/>
<joint limb1="1" limb1anchor="6,-18" limb2="2" limb2anchor="-2,36" lowerlimit="-20" upperlimit="30"/>
<joint limb1="2" limb1anchor="1,7" limb2="3" limb2anchor="6,15" lowerlimit="-20" upperlimit="40"/>
<joint limb1="0" limb1anchor="16,30" limb2="4" limb2anchor="-5,-20" lowerlimit="-90" upperlimit="0"/>
<joint limb1="4" limb1anchor="2,21" limb2="5" limb2anchor="-8,-23" lowerlimit="-350" upperlimit="-280"/>
<joint limb1="5" limb1anchor="-2,27" limb2="6" limb2anchor="0,-30" lowerlimit="-190" upperlimit="-30"/>
<joint limb1="0" limb1anchor="52,-6" limb2="7" limb2anchor="-4,-19" lowerlimit="-90" upperlimit="0"/>
<joint limb1="7" limb1anchor="-2,28" limb2="8" limb2anchor="2,-32" lowerlimit="-190" upperlimit="-30"/>
<joint limb1="0" limb1anchor="43,-39" limb2="9" limb2anchor="0,21" lowerlimit="-180" upperlimit="-10"/>
<joint limb1="9" limb1anchor="0,-28" limb2="10" limb2anchor="-11,-46" lowerlimit="-190" upperlimit="-50"/>
</ragdoll>
<ai attackhumans="500" attackrooms="50.0" attackweaker="50" attackstronger="-30"
sight="0.5" hearing="1.0"
attackcooldown="5.0"/>
</character>

View File

@@ -32,6 +32,8 @@
<Radar canbeselected = "true">
<GuiFrame rect="0,0,0.5,0.5" alignment="Center" color="0.0,0.0,0.0,0.0"/>
<PingCircle texture="Content/Items/Engine/pingCircle.png" origin="0.5,0.5"/>
<ScreenOverlay texture="Content/Items/Engine/radarOverlay.png" origin="0.5,0.5"/>
</Radar>
<ConnectionPanel canbeselected = "true">

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

View File

@@ -31,6 +31,7 @@
<Sound file="harpoon1.ogg" type="OnUse"/>
<Sound file="harpoon2.ogg" type="OnUse"/>
<RequiredItems name="Spear" type="Contained"/>
<RequiredSkill name="Weapons" level="30"/>
</RangedWeapon>
<ItemContainer itempos="27,10" iteminterval="0,-8" hideitems="false">

View File

@@ -18,7 +18,10 @@
width = "64" height ="32" resizehorizontal="true" body="true" health="500"/>
<topwindow sprite="Content/Map/testroom.png" sourcerect="208,352,128,80" depth ="0.05"
width = "128" height ="80" body="true" health="100"/>
width = "128" height ="80" body="true" health="100"/>
<verticalwindow sprite="Content/Map/testroom.png" sourcerect="256,784,128,224" depth ="0.05"
width = "128" height ="224" body="true" health="100"/>
<smallhorizontalback sprite="Content/Map/testroom.png" sourcerect="0,65,896,32" depth ="0.4"
width = "128" height ="32" resizehorizontal="true"/>

View File

@@ -0,0 +1,91 @@
Annwn
Argadnel
Balagtan
Dyfed
Falga
Moytura
Powys
Tara
Arran Chaos
Conamara Chaos
Murias Chaos
Narbeth Chaos
Rathmore Chaos
Thotep Chaos
Cilicia Flexus
Delphi Flexus
Gortyna Flexus
Phocis Flexus
Sidon Flexus
Adonis Linea
Agave Linea
Agenor Linea
Alphesiboea Linea
Androgeos Linea
Argiope Linea
Asterius Linea
Astypalaea Linea
Autonoe Linea
Belus Linea
Butterdon Linea
Cadmus Linea
Chthonius Linea
Corick Linea
Drizzlecomb Linea
Drumskinny Linea
Echion Linea
Euphemus Linea
Glaukos Linea
Harmonia Linea
Hyperenor Linea
Ino Linea
Katreus Linea
Kennet Linea
Libya Linea
Mehen Linea
Merrivale Linea
Minos Linea
Onga Linea
Pelagon Linea
Pelorus Linea
Phineus Linea
Phoenix Linea
Rhadamanthys Linea
Sarpedon Linea
Sharpitor Linea
Sparti Linea
Staldon Linea
Tectamus Linea
Telephassa Linea
Thasus Linea
Thynia Linea
Tormsdale Linea
Udaeus Linea
Yelland Linea
Boeotia Macula
Castalia Macula
Cyclades Macula
Sabbati Macula
Thera Macula
Thrace Macula
Apep
Milda
Ana
Anid
Noctae
Set
Berith
Hyldemoer
Arid Troma
New Iapetus
Alkonost
Skaani
Topol
Sontu
Nome
Attis
Bast
Ashvini II
Oshan
Vorta
Tnaboe

View File

@@ -0,0 +1,37 @@
<locationtypes>
<None
commonness="3">
<nameformats
f0="[name]"
f1="[name]"
f2="[name]"
f3="[name] Outpost"/>
</None>
<City
commonness="3">
<nameformats
f0="The City of [name]"
f1="[name] City"
f2="[name] Outpost"
f3="[name] Station"/>
</City>
<Military
commonness="1">
<nameformats
f0="[name] Outpost"
f1="[name] Facility"
f2="[name] Station"
f3="[name] Fortification"/>
</Military>
<Research
commonness="1">
<nameformats
f0="[name] Research Facility"
f1="[name] Research Center"
f2="[name] Institute of Astrobiology"
f3="[name] Biomedical Research Center"/>
</Research>
</locationtypes>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 636 KiB

After

Width:  |  Height:  |  Size: 673 KiB

View File

@@ -74,7 +74,7 @@ namespace Subsurface
{
get { return NetworkMember as GameClient; }
}
public Game1()
{
Graphics = new GraphicsDeviceManager(this);
@@ -121,6 +121,8 @@ namespace Subsurface
GameMode.Init();
GUIComponent.Init(Window);
DebugConsole.Init(Window);
LocationType.Init("Content/Map/locationTypes.xml");
//Event.Init("Content/randomevents.xml");
}

View File

@@ -49,7 +49,7 @@ namespace Subsurface
}
public GameSession(Submarine selectedMap, GameMode gameMode = null)
public GameSession(Submarine selectedSub, GameMode gameMode = null)
{
taskManager = new TaskManager(this);
@@ -83,7 +83,7 @@ namespace Subsurface
//startTime = DateTime.Now;
//endTime = startTime + gameDuration;
this.submarine = selectedMap;
this.submarine = selectedSub;
//if (!save) return;
@@ -134,6 +134,14 @@ namespace Subsurface
submarine.SetPosition(level.StartPosition - new Vector2(0.0f, 2000.0f));
}
foreach (Item item in Item.itemList)
{
foreach (ItemComponent ic in item.components)
{
ic.OnMapLoaded();
}
}
taskManager.StartShift(level);
}

View File

@@ -57,6 +57,8 @@ namespace Subsurface.Items.Components
isActive = true;
reload = 1.0f;
bool failed = UseFailed(character);
List<Body> limbBodies = new List<Body>();
foreach (Limb l in character.AnimController.limbs)
{
@@ -75,18 +77,44 @@ namespace Subsurface.Items.Components
Projectile projectileComponent= projectile.GetComponent<Projectile>();
if (projectileComponent == null) continue;
projectileComponent.ignoredBodies = limbBodies;
projectile.body.ResetDynamics();
projectile.SetTransform(TransformedBarrelPos,
(item.body.Dir == 1.0f) ? item.body.Rotation : item.body.Rotation - MathHelper.Pi);
projectile.Use(deltaTime);
if (failed)
{
Vector2 modifiedVelocity = projectile.body.LinearVelocity;
modifiedVelocity.X *= Rand.Range(0.0f, 0.5f);
modifiedVelocity.Y *= Rand.Range(0.0f, 0.5f);
projectile.body.LinearVelocity = modifiedVelocity;
projectile.body.ApplyTorque(projectile.body.Mass * Rand.Range(-10.0f, 10.0f));
//recoil
item.body.ApplyLinearImpulse(
new Vector2((float)Math.Cos(projectile.body.Rotation), (float)Math.Sin(projectile.body.Rotation)) * item.body.Mass * -10.0f);
if (Rand.Int(2) == 0)
{
item.Drop(character);
item.body.ApplyTorque(projectile.body.Mass * Rand.Range(-10.0f, 10.0f));
}
}
else
{
projectileComponent.ignoredBodies = limbBodies;
//recoil
item.body.ApplyLinearImpulse(
new Vector2((float)Math.Cos(projectile.body.Rotation), (float)Math.Sin(projectile.body.Rotation)) * -item.body.Mass);
}
item.RemoveContained(projectile);
//recoil
item.body.ApplyLinearImpulse(
new Vector2((float)Math.Cos(projectile.body.Rotation), (float)Math.Sin(projectile.body.Rotation)) * item.body.Mass);
Rope rope = item.GetComponent<Rope>();
if (rope != null) rope.Attach(projectile);

View File

@@ -52,6 +52,8 @@ namespace Subsurface
public List<RelatedItem> requiredItems;
public List<Skill> requiredSkills;
private List<ItemSound> sounds;
private GUIFrame guiFrame;
@@ -133,6 +135,8 @@ namespace Subsurface
requiredItems = new List<RelatedItem>();
requiredSkills = new List<Skill>();
sounds = new List<ItemSound>();
statusEffects = new List<StatusEffect>();
@@ -165,6 +169,12 @@ namespace Subsurface
RelatedItem ri = RelatedItem.Load(subElement);
if (ri != null) requiredItems.Add(ri);
break;
case "requiredskill":
case "requiredskills":
string skillName = ToolBox.GetAttributeString(subElement, "name", "");
requiredSkills.Add(new Skill(skillName, ToolBox.GetAttributeInt(subElement, "level", 0)));
break;
case "statuseffect":
statusEffects.Add(StatusEffect.Load(subElement));
break;
@@ -340,6 +350,30 @@ namespace Subsurface
}
}
public bool HasRequiredSkills(Character character)
{
foreach (Skill skill in requiredSkills)
{
int characterLevel = character.GetSkillLevel(skill.Name);
if (characterLevel < skill.Level) return false;
}
return true;
}
protected bool UseFailed(Character character)
{
foreach (Skill skill in requiredSkills)
{
int characterLevel = character.GetSkillLevel(skill.Name);
if (characterLevel > skill.Level) continue;
if (Rand.Int(characterLevel) - skill.Level < 0) return true;
}
return false;
}
public bool HasRequiredContainedItems(bool addMessage)
{
if (!requiredItems.Any()) return true;
@@ -367,7 +401,7 @@ namespace Subsurface
foreach (RelatedItem ri in requiredItems)
{
if (ri.Type == RelatedItem.RelationType.Equipped)
if (ri.Type.HasFlag(RelatedItem.RelationType.Equipped))
{
for (int i = 0; i < character.SelectedItems.Length; i++ )
{
@@ -381,7 +415,7 @@ namespace Subsurface
//if (addMessage && !String.IsNullOrEmpty(ri.Msg)) GUI.AddMessage(ri.Msg, Color.Red);
return false;
}
else if (ri.Type == RelatedItem.RelationType.Picked)
else if (ri.Type.HasFlag(RelatedItem.RelationType.Picked))
{
Item pickedItem = character.Inventory.items.FirstOrDefault(x => x!=null && x.Condition>0.0f && ri.MatchesItem(x));
if (pickedItem == null)

View File

@@ -30,7 +30,7 @@ namespace Subsurface.Items.Components
}
}
[Editable, HasDefaultValue(500.0f, true)]
[Editable, HasDefaultValue(2000.0f, true)]
public float MaxForce
{
get { return maxForce; }

View File

@@ -163,7 +163,7 @@ namespace Subsurface.Items.Components
else if (connection.Name == "set_speed")
{
float tempSpeed;
if (float.TryParse(signal, NumberStyles.Float, CultureInfo.InvariantCulture, out tempSpeed))
if (float.TryParse(signal, NumberStyles.Any, CultureInfo.InvariantCulture, out tempSpeed))
{
flowPercentage = MathHelper.Clamp(tempSpeed, -100.0f, 100.0f);
}
@@ -171,7 +171,7 @@ namespace Subsurface.Items.Components
else if (connection.Name == "set_targetlevel")
{
float tempTarget;
if (float.TryParse(signal, NumberStyles.Float, CultureInfo.InvariantCulture, out tempTarget))
if (float.TryParse(signal, NumberStyles.Any, CultureInfo.InvariantCulture, out tempTarget))
{
targetLevel = MathHelper.Clamp(tempTarget, 0.0f, 100.0f);
}

View File

@@ -15,8 +15,12 @@ namespace Subsurface.Items.Components
float angle;
float pingState;
//RenderTarget2D renderTarget;
Sprite pingCircle, screenOverlay;
[HasDefaultValue(0.0f, false)]
public float Range
{
@@ -27,6 +31,19 @@ namespace Subsurface.Items.Components
public Radar(Item item, XElement element)
: base(item, element)
{
foreach (XElement subElement in element.Elements())
{
switch (subElement.Name.ToString().ToLower())
{
case "pingcircle":
pingCircle = new Sprite(subElement);
break;
case "screenoverlay":
screenOverlay = new Sprite(subElement);
break;
}
}
//renderTarget = new RenderTarget2D(Game1.CurrGraphicsDevice, GuiFrame.Rect.Width, GuiFrame.Rect.Height);
}
@@ -34,6 +51,9 @@ namespace Subsurface.Items.Components
{
base.Update(deltaTime, cam);
pingState = (pingState + deltaTime * 0.5f) % 1.0f;
angle = (angle + deltaTime) % MathHelper.TwoPi;
}
@@ -42,38 +62,67 @@ namespace Subsurface.Items.Components
int width = GuiFrame.Rect.Width, height = GuiFrame.Rect.Height;
int x = GuiFrame.Rect.X;
int y = GuiFrame.Rect.Y;
GuiFrame.Draw(spriteBatch);
if (GUI.DrawButton(spriteBatch, new Rectangle(x+20, y+20, 200, 30), "Activate Radar")) isActive = !isActive;
Vector2 lineEnd = GuiFrame.Center;
lineEnd += new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle))*Math.Min(width,height)/2.0f;
GUI.DrawLine(spriteBatch, GuiFrame.Center, lineEnd, Color.Green);
int radius = GuiFrame.Rect.Height / 2 - 10;
DrawRadar(spriteBatch, new Rectangle((int)GuiFrame.Center.X - radius, (int)GuiFrame.Center.Y - radius, radius * 2, radius * 2));
}
if (!isActive) return;
private void DrawRadar(SpriteBatch spriteBatch, Rectangle rect)
{
float scale = 0.01f;
Vector2 center = new Vector2(rect.Center.X, rect.Center.Y);
//lineEnd += new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle)) * Math.Min(width, height) / 2.0f;
//GUI.DrawLine(spriteBatch, GuiFrame.Center, lineEnd, Color.Green);
List<Vector2[]> edges = Level.Loaded.GetCellEdges(-Level.Loaded.Position, 5);
if (!isActive || Level.Loaded == null) return;
if (pingCircle!=null)
{
pingCircle.Draw(spriteBatch, center, Color.White * (1.0f-pingState), 0.0f, (rect.Width/pingCircle.size.X)*pingState);
}
float scale = 0.015f;
List<Vector2[]> edges = Level.Loaded.GetCellEdges(-Level.Loaded.Position, 7);
Vector2 offset = Vector2.Zero;
for (int i = 0; i < edges.Count; i++)
{
GUI.DrawLine(spriteBatch,
GuiFrame.Center + (edges[i][0] - offset) * scale,
GuiFrame.Center + (edges[i][1] - offset) * scale, Color.Green);
center + (edges[i][0] - offset) * scale,
center + (edges[i][1] - offset) * scale, Color.White);
}
scale = ConvertUnits.ToDisplayUnits(scale);
for (int i = 0; i< Submarine.Loaded.HullVertices.Count; i++)
for (int i = 0; i < Submarine.Loaded.HullVertices.Count; i++)
{
Vector2 start =Submarine.Loaded.HullVertices[i] * scale;
Vector2 start = Submarine.Loaded.HullVertices[i] * scale;
start.Y = -start.Y;
Vector2 end = Submarine.Loaded.HullVertices[(i+1)%Submarine.Loaded.HullVertices.Count] * scale;
Vector2 end = Submarine.Loaded.HullVertices[(i + 1) % Submarine.Loaded.HullVertices.Count] * scale;
end.Y = -end.Y;
GUI.DrawLine(spriteBatch, GuiFrame.Center + start,GuiFrame.Center + end, Color.Green);
GUI.DrawLine(spriteBatch, center + start, center + end, Color.White);
}
foreach (Character c in Character.CharacterList)
{
if (c.AnimController.CurrentHull != null) continue;
if (c.SimPosition!=Vector2.Zero && c.SimPosition.Length() < 7*Level.GridCellWidth)
{
int width = (int)c.Mass/5;
GUI.DrawRectangle(spriteBatch, new Rectangle((int)c.Position.X - width / 2, (int)c.Position.Y - width / 2, width, width), Color.White);
}
}
if (screenOverlay!=null)
{
screenOverlay.Draw(spriteBatch, center, 0.0f, rect.Width/screenOverlay.size.X);
}
}

View File

@@ -1,7 +1,9 @@
using Microsoft.Xna.Framework;
using FarseerPhysics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Xml.Linq;
@@ -13,18 +15,69 @@ namespace Subsurface.Items.Components
Vector2 currVelocity;
Vector2 targetVelocity;
bool autoPilot;
SteeringPath steeringPath;
private Vector2 TargetVelocity
{
get { return targetVelocity;}
set
{
targetVelocity.X = MathHelper.Clamp(value.X, -100.0f, 100.0f);
targetVelocity.Y = MathHelper.Clamp(value.Y, -100.0f, 100.0f);
}
}
public Steering(Item item, XElement element)
: base(item, element)
{
isActive = true;
}
public override void OnMapLoaded()
{
PathFinder pathFinder = new PathFinder(WayPoint.WayPointList, false);
steeringPath = pathFinder.FindPath(
ConvertUnits.ToSimUnits(Level.Loaded.StartPosition),
ConvertUnits.ToSimUnits(Level.Loaded.EndPosition));
}
public override void Update(float deltaTime, Camera cam)
{
base.Update(deltaTime, cam);
item.SendSignal(targetVelocity.X.ToString(), "velocity_x_out");
item.SendSignal((-targetVelocity.Y).ToString(), "velocity_y_out");
if (autoPilot || true)
{
steeringPath.GetNode(Vector2.Zero, 5.0f);
if (steeringPath.CurrentNode!=null)
{
Vector2 targetSpeed = steeringPath.CurrentNode.Position;
float dist = targetSpeed.Length();
targetSpeed = Vector2.Normalize(targetSpeed);
if (dist<2000.0f)
{
targetSpeed = targetSpeed * Math.Max(dist / 2000.0f, 0.5f);
}
Vector2 currSpeed = (Submarine.Loaded.Speed == Vector2.Zero) ? Vector2.Zero : Vector2.Normalize(Submarine.Loaded.Speed);
//targetSpeed.X = (targetSpeed.X - currSpeed.X);
//targetSpeed.Y = (targetSpeed.Y - currSpeed.Y);
//TargetVelocity += targetSpeed;
TargetVelocity += (targetSpeed-currSpeed);
}
}
item.SendSignal(targetVelocity.X.ToString(CultureInfo.InvariantCulture), "velocity_x_out");
item.SendSignal((-targetVelocity.Y).ToString(CultureInfo.InvariantCulture), "velocity_y_out");
}
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
@@ -52,7 +105,7 @@ namespace Subsurface.Items.Components
GUI.DrawRectangle(spriteBatch, new Rectangle((int)targetVelPos.X - 5, (int)targetVelPos.Y - 5, 10, 10), Color.White);
if (Vector2.Distance(PlayerInput.MousePosition, targetVelPos)<10.0f)
if (Vector2.Distance(PlayerInput.MousePosition, new Vector2(velRect.Center.X, velRect.Center.Y)) < 200.0f)
{
GUI.DrawRectangle(spriteBatch, new Rectangle((int)targetVelPos.X -10, (int)targetVelPos.Y - 10, 20, 20), Color.Red);
@@ -82,8 +135,18 @@ namespace Subsurface.Items.Components
public override void ReadNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetIncomingMessage message)
{
targetVelocity.X = message.ReadFloat();
targetVelocity.Y = message.ReadFloat();
Vector2 newTargetVelocity = Vector2.Zero;
try
{
newTargetVelocity = new Vector2(message.ReadFloat(), message.ReadFloat());
}
catch
{
return;
}
TargetVelocity = newTargetVelocity;
}
}
}

View File

@@ -84,8 +84,8 @@ namespace Subsurface.Items.Components
Debug.WriteLine(item.body.Rotation);
Launch(new Vector2(
(float)Math.Cos(item.body.Rotation),
(float)Math.Sin(item.body.Rotation))*launchImpulse*item.body.Mass);
(float)Math.Cos(item.body.Rotation),
(float)Math.Sin(item.body.Rotation)) * launchImpulse * item.body.Mass);
return true;
}

View File

@@ -727,10 +727,13 @@ namespace Subsurface
public bool Pick(Character picker, bool forcePick=false)
{
bool hasRequiredSkills = true;
bool picked = false, selected = false;
foreach (ItemComponent ic in components)
{
if (!ic.HasRequiredSkills(picker)) hasRequiredSkills = false;
if ((ic.CanBePicked || ic.CanBeSelected)
&& (ic.HasRequiredEquippedItems(picker, picker == Character.Controlled) || forcePick)
&& ic.Pick(picker))
@@ -747,6 +750,11 @@ namespace Subsurface
picker.SelectedConstruction = (picker.SelectedConstruction == this) ? null : this;
}
if (!hasRequiredSkills)
{
GUI.AddMessage("Your skills may be insufficient to use the item!", Color.Red, 5.0f);
}
if (container!=null) container.RemoveContained(this);
return true;

View File

@@ -30,9 +30,11 @@ namespace Subsurface
private int siteInterval;
const int GridCellWidth = 2000;
public const int GridCellWidth = 2000;
private List<VoronoiCell>[,] cellGrid;
private float shaftHeight;
//List<Body> bodies;
private List<VoronoiCell> cells;
@@ -59,6 +61,11 @@ namespace Subsurface
private set;
}
public Vector2 EndPosition
{
get { return endPosition; }
}
public bool AtEndPosition
{
get;
@@ -67,7 +74,7 @@ namespace Subsurface
public Vector2 Position
{
get { return ConvertUnits.ToDisplayUnits(cells[0].body.Position); }
get { return ConvertUnits.ToDisplayUnits(cells[1].body.Position); }
}
public string Seed
@@ -97,7 +104,6 @@ namespace Subsurface
public void Generate(float minWidth, bool mirror=false)
{
mirror = true;
Stopwatch sw = new Stopwatch();
sw.Start();
@@ -112,7 +118,7 @@ namespace Subsurface
List<Vector2> sites = new List<Vector2>();
Random rand = new Random(100);
Random rand = new Random(seed.GetHashCode());
float siteVariance = siteInterval * 0.8f;
for (int x = siteInterval / 2; x < borders.Width; x += siteInterval)
@@ -186,17 +192,23 @@ namespace Subsurface
borders.X + (int)minWidth * 2, borders.Y + (int)minWidth * 2,
borders.Right - (int)minWidth * 4, borders.Y + borders.Height - (int)minWidth * 4);
Vector2 startPath = new Vector2((int)minWidth * 2, rand.Next((int)minWidth * 2, borders.Height - (int)minWidth * 2));
Vector2 endPath = new Vector2(borders.Width - (int)minWidth * 2, rand.Next((int)minWidth * 2, borders.Height - (int)minWidth * 2));
List<Vector2> pathNodes = new List<Vector2>();
startPosition = new Vector2((int)minWidth * 2, rand.Next((int)minWidth * 2, borders.Height - (int)minWidth * 2));
endPosition = new Vector2(borders.Width - (int)minWidth * 2, rand.Next((int)minWidth * 2, borders.Height - (int)minWidth * 2));
pathNodes.Add(new Vector2(startPosition.X, borders.Height));
pathNodes.Add(startPosition);
pathNodes.Add(endPosition);
pathNodes.Add(new Vector2(endPosition.X, borders.Height));
if (mirror)
{
startPath.X = borders.Width - startPath.X;
endPath.X = borders.Width - endPath.X;
pathNodes.Reverse();
}
List<VoronoiCell> pathCells = GeneratePath(rand,
startPath, endPath, cells, pathBorders, minWidth);
pathNodes, cells, pathBorders, minWidth, 0.3f, mirror, true);
//place some enemy spawnpoints at random points in the path
for (int i = 0; i <3 ; i++ )
@@ -228,22 +240,22 @@ namespace Subsurface
pathCells.AddRange
(
GeneratePath(rand, start, end, cells, pathBorders, 0.0f, 0.8f)
GeneratePath(rand, new List<Vector2> { start, end }, cells, pathBorders, 0.0f, 0.8f, mirror)
);
}
Debug.WriteLine("path: " + sw2.ElapsedMilliseconds + " ms");
sw2.Restart();
for (int i = 0; i < 2; i++ )
{
Vector2 tunnelStart = (i == 0) ? startPosition : endPosition;
//for (int i = 0; i < 2; i++ )
//{
// Vector2 tunnelStart = (i == 0) ? startPosition : endPosition;
pathCells.AddRange
(
GeneratePath(rand, tunnelStart, new Vector2(tunnelStart.X, borders.Height), cells, pathBorders, minWidth, 0.1f)
);
}
// pathCells.AddRange
// (
// GeneratePath(rand, tunnelStart, new Vector2(tunnelStart.X, borders.Height), cells, pathBorders, minWidth, 0.1f, mirror)
// );
//}
cells = CleanCells(pathCells);
@@ -276,14 +288,14 @@ namespace Subsurface
int cellIndex = FindCellIndex(new Vector2(tunnelStart.X + minWidth * 0.5f * n, tunnelStart.Y), 3);
foreach (GraphEdge ge in cells[cellIndex].edges)
{
if (ge.point1.Y > cells[cellIndex].Center.Y) ge.point1.Y = borders.Height + 5000.0f;
if (ge.point2.Y > cells[cellIndex].Center.Y) ge.point2.Y = borders.Height + 5000.0f;
if (ge.point1.Y > cells[cellIndex].Center.Y) ge.point1.Y = borders.Height + shaftHeight;
if (ge.point2.Y > cells[cellIndex].Center.Y) ge.point2.Y = borders.Height + shaftHeight;
}
}
}
startPosition.Y += 5000.0f;
endPosition.Y += 5000.0f;
startPosition.Y += shaftHeight;
endPosition.Y += shaftHeight;
GeneratePolygons(cells, pathCells);
@@ -309,10 +321,17 @@ namespace Subsurface
basicEffect = new BasicEffect(Game1.CurrGraphicsDevice);
basicEffect.VertexColorEnabled = true;
if (mirror)
{
Vector2 temp = startPosition;
startPosition = endPosition;
endPosition = temp;
}
Debug.WriteLine("Generated a map with " + sites.Count + " sites in " + sw.ElapsedMilliseconds + " ms");
}
private List<VoronoiCell> GeneratePath(Random rand, Vector2 start, Vector2 end, List<VoronoiCell> cells, Microsoft.Xna.Framework.Rectangle limits, float minWidth, float wanderAmount = 0.3f)
private List<VoronoiCell> GeneratePath(Random rand, List<Vector2> points, List<VoronoiCell> cells, Microsoft.Xna.Framework.Rectangle limits, float minWidth, float wanderAmount = 0.3f, bool mirror=false, bool placeWaypoints=false)
{
Stopwatch sw2 = new Stopwatch();
sw2.Start();
@@ -323,11 +342,18 @@ namespace Subsurface
List<VoronoiCell> pathCells = new List<VoronoiCell>();
VoronoiCell currentCell = cells[FindCellIndex(start)];
VoronoiCell[] targetCells = new VoronoiCell[points.Count];
for (int i = 0; i <targetCells.Length; i++)
{
targetCells[i]= cells[FindCellIndex(points[i])];
}
VoronoiCell currentCell = targetCells[0];
pathCells.Add(currentCell);
VoronoiCell endCell = cells[FindCellIndex(end)];
int currentTargetIndex = 1;
do
{
int edgeIndex = 0;
@@ -337,7 +363,7 @@ namespace Subsurface
{
for (int i = 0; i < currentCell.edges.Count; i++)
{
if (!MathUtils.LinesIntersect(currentCell.Center, end, currentCell.edges[i].point1, currentCell.edges[i].point2)) continue;
if (!MathUtils.LinesIntersect(currentCell.Center, targetCells[currentTargetIndex].Center, currentCell.edges[i].point1, currentCell.edges[i].point2)) continue;
edgeIndex = i;
break;
}
@@ -353,16 +379,57 @@ namespace Subsurface
allowedEdges.Add(edge);
}
edgeIndex = (allowedEdges.Count == 0) ?
0 : currentCell.edges.IndexOf(allowedEdges[rand.Next() % allowedEdges.Count]);
if (allowedEdges.Count==0)
{
edgeIndex = 0;
}
else
{
edgeIndex = rand.Next() % allowedEdges.Count;
if (mirror && edgeIndex > 0) edgeIndex = allowedEdges.Count - edgeIndex;
edgeIndex = currentCell.edges.IndexOf(allowedEdges[edgeIndex]);
}
}
currentCell = currentCell.edges[edgeIndex].AdjacentCell(currentCell);
pathCells.Add(currentCell);
} while (currentCell != endCell);
if (currentCell==targetCells[currentTargetIndex])
{
currentTargetIndex += 1;
if (currentTargetIndex>=targetCells.Length) break;
}
} while (currentCell != targetCells[targetCells.Length-1]);
if (placeWaypoints)
{
WayPoint newWaypoint = new WayPoint(new Rectangle((int)pathCells[0].Center.X, (int)(borders.Height + shaftHeight), 10, 10));
newWaypoint.MoveWithLevel = true;
WayPoint prevWaypoint = newWaypoint;
for (int i = 0; i < pathCells.Count; i++)
{
newWaypoint = new WayPoint(new Rectangle((int)pathCells[i].Center.X, (int)pathCells[i].Center.Y, 10, 10));
newWaypoint.MoveWithLevel = true;
if (prevWaypoint != null)
{
prevWaypoint.linkedTo.Add(newWaypoint);
newWaypoint.linkedTo.Add(prevWaypoint);
}
prevWaypoint = newWaypoint;
}
newWaypoint = new WayPoint(new Rectangle((int)pathCells[pathCells.Count - 1].Center.X, (int)(borders.Height + shaftHeight), 10, 10));
newWaypoint.MoveWithLevel = true;
if (prevWaypoint != null)
{
prevWaypoint.linkedTo.Add(newWaypoint);
newWaypoint.linkedTo.Add(prevWaypoint);
}
}
Debug.WriteLine("genpath: " + sw2.ElapsedMilliseconds + " ms");
sw2.Restart();
@@ -537,8 +604,10 @@ namespace Subsurface
for (int i = 0; i < triangles.Count; i++)
{
Vertices bodyVertices = new Vertices(triangles[i]);
if (triangles[i][0].Y == triangles[i][1].Y && triangles[i][0].Y == triangles[i][2].Y) continue;
if (triangles[i][0].X == triangles[i][1].X && triangles[i][0].X == triangles[i][2].X) continue;
Vertices bodyVertices = new Vertices(triangles[i]);
FixtureFactory.AttachPolygon(bodyVertices, 5.0f, edgeBody);
}

View File

@@ -6,12 +6,15 @@ using System.Text;
namespace Subsurface
{
class Location
{
string name;
Vector2 mapPosition;
LocationType type;
public string Name
{
get { return name; }
@@ -22,16 +25,23 @@ namespace Subsurface
get { return mapPosition; }
}
public Location(string name, Vector2 mapPosition)
public Location(Vector2 mapPosition)
{
this.name = name;
this.name = RandomName(LocationType.Random());
this.mapPosition = mapPosition;
}
public static Location CreateRandom(Vector2 position)
{
return new Location("Location " + Rand.Int(10000, false), position);
return new Location(position);
}
private string RandomName(LocationType type)
{
string name = ToolBox.GetRandomLine("Content/Map/locationNames.txt");
int nameFormatIndex = Rand.Int(type.NameFormats.Count);
return type.NameFormats[nameFormatIndex].Replace("[name]", name);
}
}
}

View File

@@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace Subsurface
{
class LocationType
{
private static List<LocationType> list = new List<LocationType>();
//sum of the commonness-values of each location type
private static int totalWeight;
string name;
private int commonness;
List<string> nameFormats;
public string Name
{
get { return name; }
}
public List<string> NameFormats
{
get { return nameFormats; }
}
private LocationType(XElement element)
{
name = element.Name.ToString();
commonness = ToolBox.GetAttributeInt(element, "commonness", 1);
totalWeight += commonness;
nameFormats = new List<string>();
foreach (XAttribute nameFormat in element.Element("nameformats").Attributes())
{
nameFormats.Add(nameFormat.Value.ToString());
}
}
public static LocationType Random()
{
Debug.Assert(list.Count > 0, "LocationType.list.Count == 0, you probably need to initialize LocationTypes");
int randInt = Rand.Int(totalWeight);
foreach (LocationType type in list)
{
if (randInt < type.commonness) return type;
randInt -= type.commonness;
}
return null;
}
public static void Init(string file)
{
XDocument doc = ToolBox.TryLoadXml(file);
if (doc==null)
{
return;
}
foreach (XElement element in doc.Root.Elements())
{
LocationType locationType = new LocationType(element);
list.Add(locationType);
}
}
}
}

View File

@@ -98,9 +98,9 @@ namespace Subsurface
newLocations[i] = Location.CreateRandom(position);
locations.Add(newLocations[i]);
}
connections.Add(new LocationConnection(newLocations[0], newLocations[1], Level.CreateRandom()));
}
int seed = (newLocations[0].GetHashCode() | newLocations[1].GetHashCode());
connections.Add(new LocationConnection(newLocations[0], newLocations[1], Level.CreateRandom(seed.ToString())));
}
@@ -157,9 +157,9 @@ namespace Subsurface
float offsetAmount = 5.0f;
for (int n = 0; n<generations; n++)
for (int n = 0; n < generations; n++)
{
for (int i = 0; i<segments.Count; i++)
for (int i = 0; i < segments.Count; i++)
{
Vector2 startSegment = segments[i][0];
Vector2 endSegment = segments[i][1];

View File

@@ -78,6 +78,11 @@ namespace Subsurface
get { return prefab.HasBody; }
}
public bool CastShadow
{
get { return prefab.CastShadow; }
}
public bool IsHorizontal
{
get { return isHorizontal; }

View File

@@ -112,6 +112,11 @@ namespace Subsurface
get { return (Level.Loaded == null) ? Vector2.Zero : -Level.Loaded.Position; }
}
public Vector2 Speed
{
get { return speed; }
}
public string FilePath
{
get { return filePath; }
@@ -477,10 +482,10 @@ namespace Subsurface
float waterPercentage = waterVolume / volume;
float neutralPercentage = 0.1f;
float neutralPercentage = 0.07f;
float buoyancy = neutralPercentage-waterPercentage;
buoyancy *= mass * 10.0f;
buoyancy *= mass * 30.0f;
return new Vector2(0.0f, buoyancy);
}
@@ -825,13 +830,7 @@ namespace Subsurface
//hullBodies.Add(hullBody);
MapEntity.LinkAll();
foreach (Item item in Item.itemList)
{
foreach (ItemComponent ic in item.components)
{
ic.OnMapLoaded();
}
}
ID = int.MaxValue-10;

View File

@@ -256,6 +256,7 @@ namespace Subsurface
public override XElement Save(XDocument doc)
{
if (MoveWithLevel) return null;
XElement element = new XElement("WayPoint");
element.Add(new XAttribute("ID", ID),

View File

@@ -36,6 +36,11 @@ namespace Subsurface.Networking
get { return characterInfo; }
}
public int ID
{
get { return myID; }
}
public GameClient(string newName)
{
name = newName;
@@ -189,20 +194,14 @@ namespace Subsurface.Networking
public override void Update()
{
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if (PlayerInput.KeyHit(Microsoft.Xna.Framework.Input.Keys.K))
if (PlayerInput.KeyDown(Microsoft.Xna.Framework.Input.Keys.K))
{
SendRandomData();
}
if (!connected || updateTimer > DateTime.Now) return;
//if (reconnectBox != null)
//{
// ConnectToServer(serverIP);
// return;
//}
if (Client.ConnectionStatus == NetConnectionStatus.Disconnected)
{
reconnectBox = new GUIMessageBox("CONNECTION LOST", "You have been disconnected from the server. Reconnecting...", new string[0]);
@@ -472,7 +471,7 @@ namespace Subsurface.Networking
public void SendRandomData()
{
NetOutgoingMessage msg = Client.CreateMessage();
switch (Rand.Int(4))
switch (Rand.Int(5))
{
case 0:
msg.Write((byte)PacketTypes.NetworkEvent);
@@ -485,6 +484,12 @@ namespace Subsurface.Networking
msg.Write(Rand.Int(MapEntity.mapEntityList.Count));
break;
case 2:
msg.Write((byte)PacketTypes.NetworkEvent);
msg.Write((byte)NetworkEventType.UpdateComponent);
msg.Write((int)Item.itemList[Rand.Int(Item.itemList.Count)].ID);
msg.Write(Rand.Int(8));
break;
case 3:
msg.Write((byte)Enum.GetNames(typeof(PacketTypes)).Length);
break;
}

View File

@@ -58,7 +58,17 @@ namespace Subsurface.Networking
// If "inc" is null -> ReadMessage returned null -> Its null, so dont do this :)
NetIncomingMessage inc = Server.ReadMessage();
if (inc != null) ReadMessage(inc);
if (inc != null)
{
try
{
ReadMessage(inc);
}
catch
{
}
}
// if 30ms has passed
if (updateTimer < DateTime.Now)

View File

@@ -56,7 +56,7 @@ namespace Subsurface
{
Vector2 randomVector = new Vector2(Range(-1.0f, 1.0f, local), Range(-1.0f, 1.0f, local));
if (randomVector == Vector2.Zero) return Vector2.One * length;
if (randomVector == Vector2.Zero) return new Vector2(0.0f, length);
return Vector2.Normalize(randomVector) * length;
}

View File

@@ -200,7 +200,7 @@ namespace Subsurface
if (Vector2.Distance(PlayerInput.MousePosition, limbBodyPos)<5.0f && PlayerInput.LeftButtonDown())
{
limb.sprite.Origin -= PlayerInput.MouseSpeed;
limb.sprite.Origin += PlayerInput.MouseSpeed;
}
}
@@ -259,17 +259,30 @@ namespace Subsurface
if (joint.BodyA == limb.body.FarseerBody)
{
jointPos = limbBodyPos + ConvertUnits.ToDisplayUnits(joint.LocalAnchorA);
jointPos = ConvertUnits.ToDisplayUnits(joint.LocalAnchorA);
}
else if (joint.BodyB == limb.body.FarseerBody)
{
jointPos = limbBodyPos + ConvertUnits.ToDisplayUnits(joint.LocalAnchorB);
jointPos = ConvertUnits.ToDisplayUnits(joint.LocalAnchorB);
}
else
{
continue;
}
jointPos.Y = -jointPos.Y;
jointPos += limbBodyPos;
if (joint.BodyA == limb.body.FarseerBody)
{
float a1 = joint.UpperLimit - MathHelper.PiOver2;
float a2 = joint.LowerLimit - MathHelper.PiOver2;
float a3 =( a1+a2)/2.0f;
GUI.DrawLine(spriteBatch, jointPos, jointPos + new Vector2((float)Math.Cos(a1), -(float)Math.Sin(a1)) * 30.0f, Color.Green);
GUI.DrawLine(spriteBatch, jointPos, jointPos + new Vector2((float)Math.Cos(a2), -(float)Math.Sin(a2)) * 30.0f, Color.DarkGreen);
GUI.DrawLine(spriteBatch, jointPos, jointPos + new Vector2((float)Math.Cos(a3), -(float)Math.Sin(a3)) * 30.0f, Color.LightGray);
}
GUI.DrawRectangle(spriteBatch, jointPos, new Vector2(5.0f, 5.0f), Color.Red, true);
if (Vector2.Distance(PlayerInput.MousePosition, jointPos) < 6.0f)
@@ -277,13 +290,15 @@ namespace Subsurface
GUI.DrawRectangle(spriteBatch, jointPos - new Vector2(3.0f, 3.0f), new Vector2(11.0f, 11.0f), Color.Red, false);
if (PlayerInput.LeftButtonDown())
{
Vector2 speed = ConvertUnits.ToSimUnits(PlayerInput.MouseSpeed);
speed.Y = -speed.Y;
if (joint.BodyA == limb.body.FarseerBody)
{
joint.LocalAnchorA += ConvertUnits.ToSimUnits(PlayerInput.MouseSpeed);
joint.LocalAnchorA += speed;
}
else
{
joint.LocalAnchorB += ConvertUnits.ToSimUnits(PlayerInput.MouseSpeed);
joint.LocalAnchorB += speed;
}
}
}

View File

@@ -23,10 +23,7 @@ namespace Subsurface
SinglePlayerMode gameMode;
Body previewPlatform;
Hull previewHull;
Character previewCharacter;
GUIFrame previewFrame;
Level selectedLevel;
@@ -112,57 +109,57 @@ namespace Subsurface
{
base.Deselect();
if (previewPlatform != null)
{
Game1.World.RemoveBody(previewPlatform);
previewPlatform = null;
}
//if (previewPlatform != null)
//{
// Game1.World.RemoveBody(previewPlatform);
// previewPlatform = null;
//}
if (previewHull != null)
{
previewHull.Remove();
previewHull = null;
}
//if (previewHull != null)
//{
// previewHull.Remove();
// previewHull = null;
//}
if (previewCharacter != null)
{
previewCharacter.Remove();
previewCharacter = null;
}
//if (previewCharacter != null)
//{
// previewCharacter.Remove();
// previewCharacter = null;
//}
}
private void CreatePreviewCharacter()
{
if (previewCharacter != null) previewCharacter.Remove();
//private void CreatePreviewCharacter()
//{
// if (previewCharacter != null) previewCharacter.Remove();
Vector2 pos = new Vector2(1000.0f, 1000.0f);
// Vector2 pos = new Vector2(1000.0f, 1000.0f);
previewCharacter = new Character(characterList.SelectedData as CharacterInfo, pos);
// previewCharacter = new Character(characterList.SelectedData as CharacterInfo, pos);
previewCharacter.AnimController.IsStanding = true;
// previewCharacter.AnimController.IsStanding = true;
if (previewPlatform == null)
{
Body platform = BodyFactory.CreateRectangle(Game1.World, 3.0f, 1.0f, 5.0f);
platform.SetTransform(new Vector2(pos.X, pos.Y - 3.5f), 0.0f);
platform.IsStatic = true;
}
// if (previewPlatform == null)
// {
// Body platform = BodyFactory.CreateRectangle(Game1.World, 3.0f, 1.0f, 5.0f);
// platform.SetTransform(new Vector2(pos.X, pos.Y - 3.5f), 0.0f);
// platform.IsStatic = true;
// }
if (previewHull == null)
{
pos = ConvertUnits.ToDisplayUnits(pos);
previewHull = new Hull(new Rectangle((int)pos.X - 100, (int)pos.Y + 100, 200, 500));
}
// if (previewHull == null)
// {
// pos = ConvertUnits.ToDisplayUnits(pos);
// previewHull = new Hull(new Rectangle((int)pos.X - 100, (int)pos.Y + 100, 200, 500));
// }
Physics.Alpha = 1.0f;
// Physics.Alpha = 1.0f;
for (int i = 0; i < 500; i++)
{
previewCharacter.AnimController.Update((float)Physics.step);
previewCharacter.AnimController.UpdateAnim((float)Physics.step);
Game1.World.Step((float)Physics.step);
}
}
// for (int i = 0; i < 500; i++)
// {
// previewCharacter.AnimController.Update((float)Physics.step);
// previewCharacter.AnimController.UpdateAnim((float)Physics.step);
// Game1.World.Step((float)Physics.step);
// }
//}
public void SelectLocation(Location location, LocationConnection connection)
{
@@ -258,22 +255,34 @@ namespace Subsurface
if (characterList.SelectedData != null && selectedRightPanel == (int)PanelTab.Crew)
{
if (previewCharacter != null)
if (previewFrame==null || previewFrame.UserData != characterList.UserData)
{
Vector2 position = new Vector2(characterList.Rect.Right + 100, characterList.Rect.Y + 25.0f);
CharacterInfo previewCharacter = (characterList.SelectedData as CharacterInfo);
Vector2 pos = previewCharacter.Position;
pos.Y = -pos.Y;
Matrix transform = Matrix.CreateTranslation(new Vector3(-pos + position, 0.0f));
GUIFrame frameRoot = new GUIFrame(new Rectangle(350, 30, 300, 500),
new Color(0.0f, 0.0f, 0.0f, 0.8f),
Alignment.Top, GUI.style, rightPanel[selectedRightPanel]);
frameRoot.Padding = new Vector4(20.0f,20.0f,20.0f,20.0f);
spriteBatch.Begin(SpriteSortMode.BackToFront, null, null, null, null, null, transform);
previewCharacter.Draw(spriteBatch);
spriteBatch.End();
}
else
{
CreatePreviewCharacter();
previewFrame = previewCharacter.CreateInfoFrame(frameRoot);
previewFrame.UserData = previewCharacter;
}
//if (previewCharacter != null)
//{
// Vector2 position = new Vector2(characterList.Rect.Right + 100, characterList.Rect.Y + 25.0f);
// Vector2 pos = previewCharacter.Position;
// pos.Y = -pos.Y;
// Matrix transform = Matrix.CreateTranslation(new Vector3(-pos + position, 0.0f));
// spriteBatch.Begin(SpriteSortMode.BackToFront, null, null, null, null, null, transform);
// previewCharacter.Draw(spriteBatch);
// spriteBatch.End();
//}
//else
//{
// CreatePreviewCharacter();
//}
}
}
@@ -331,7 +340,7 @@ namespace Subsurface
if (Character.Controlled != null && characterInfo == Character.Controlled.Info) return false;
CreatePreviewCharacter();
//CreatePreviewCharacter();
return false;
}

View File

@@ -15,8 +15,7 @@ namespace Subsurface
private GUIListBox saveList;
private GUITextBox nameBox;
private GUITextBox ipBox;
private GUITextBox nameBox, ipBox;
private Game1 game;
@@ -61,8 +60,8 @@ namespace Subsurface
new GUITextBlock(new Rectangle(0, 0, 0, 30), "New Game", null, null, Alignment.CenterX, GUI.style, menuTabs[(int)Tabs.NewGame]);
new GUITextBlock(new Rectangle(0, 30, 0, 30), "Selected map:", null, null, Alignment.Left, GUI.style, menuTabs[(int)Tabs.NewGame]);
mapList = new GUIListBox(new Rectangle(0, 60, 200, 400), GUI.style, menuTabs[(int)Tabs.NewGame]);
new GUITextBlock(new Rectangle(0, 30, 0, 30), "Selected submarine:", null, null, Alignment.Left, GUI.style, menuTabs[(int)Tabs.NewGame]);
mapList = new GUIListBox(new Rectangle(0, 60, 200, 360), GUI.style, menuTabs[(int)Tabs.NewGame]);
foreach (Submarine map in Submarine.SavedSubmarines)
{
@@ -77,7 +76,7 @@ namespace Subsurface
if (Submarine.SavedSubmarines.Count > 0) mapList.Select(Submarine.SavedSubmarines[0]);
button = new GUIButton(new Rectangle(0, 0, 100, 30), "Start",Alignment.Right | Alignment.Bottom, GUI.style, menuTabs[(int)Tabs.NewGame]);
button = new GUIButton(new Rectangle(0, 0, 100, 30), "Start",Alignment.BottomRight, GUI.style, menuTabs[(int)Tabs.NewGame]);
button.OnClicked = StartGame;
//----------------------------------------------------------------------
@@ -137,6 +136,13 @@ namespace Subsurface
GUIButton joinButton = new GUIButton(new Rectangle(0, 0, 200, 30), "Join", Alignment.BottomCenter, GUI.style, menuTabs[(int)Tabs.JoinServer]);
joinButton.OnClicked = JoinServer;
//----------------------------------------------------------------------
for (int i = 1; i < 4; i++ )
{
button = new GUIButton(new Rectangle(0, 0, 100, 30), "Back", Alignment.TopLeft, GUI.style, menuTabs[i]);
button.OnClicked = PreviousTab;
}
this.game = game;
@@ -193,6 +199,13 @@ namespace Subsurface
return true;
}
private bool PreviousTab(GUIButton button, object obj)
{
selectedTab = (int)Tabs.Main;
return true;
}
private bool LoadGame(GUIButton button, object obj)
{

View File

@@ -21,9 +21,9 @@ namespace Subsurface
private GUIListBox jobList;
private GUITextBox textBox;
private GUITextBox textBox, seedBox;
private GUITextBox seedBox;
GUIFrame previewPlayer;
private GUIScrollBar durationBar;
@@ -31,8 +31,8 @@ namespace Subsurface
private float camAngle;
private Body previewPlatform;
private Hull previewHull;
//private Body previewPlatform;
//private Hull previewHull;
public bool IsServer;
@@ -136,17 +136,17 @@ namespace Subsurface
{
textBox.Deselect();
if (previewPlatform!=null)
{
Game1.World.RemoveBody(previewPlatform);
previewPlatform = null;
}
//if (previewPlatform!=null)
//{
// Game1.World.RemoveBody(previewPlatform);
// previewPlatform = null;
//}
if (previewHull!=null)
{
previewHull.Remove();
previewHull = null;
}
//if (previewHull!=null)
//{
// previewHull.Remove();
// previewHull = null;
//}
}
public override void Select()
@@ -159,9 +159,6 @@ namespace Subsurface
textBox.Select();
//int oldMapIndex = 0;
//if (mapList != null && mapList.SelectedData != null) oldMapIndex = mapList.SelectedIndex;
new GUITextBlock(new Rectangle(0, 30, 0, 30), "Selected submarine:", GUI.style, infoFrame);
subList = new GUIListBox(new Rectangle(0, 60, 200, 200), Color.White, GUI.style, infoFrame);
subList.OnSelected = SelectMap;
@@ -238,30 +235,28 @@ namespace Subsurface
{
int x = playerFrame.Rect.Width / 2;
new GUITextBlock(new Rectangle(x, 0, 200, 30), "Name: ", GUI.style, playerFrame);
GUITextBox playerName = new GUITextBox(new Rectangle(x, 30, 0, 20),
Alignment.TopLeft, GUI.style, playerFrame);
playerName.Text = Game1.Client.CharacterInfo.Name;
playerName.OnEnter += ChangeCharacterName;
new GUITextBlock(new Rectangle(x,70,200, 30), "Gender: ", GUI.style, playerFrame);
new GUITextBlock(new Rectangle(x, 70, 200, 30), "Gender: ", GUI.style, playerFrame);
GUIButton maleButton = new GUIButton(new Rectangle(x, 100, 70, 20), "Male",
Alignment.TopLeft, GUI.style,playerFrame);
maleButton.UserData = Gender.Male;
maleButton.OnClicked += SwitchGender;
GUIButton femaleButton = new GUIButton(new Rectangle(x+150, 100, 70, 20), "Female",
GUIButton femaleButton = new GUIButton(new Rectangle(x+90, 100, 70, 20), "Female",
Alignment.TopLeft, GUI.style, playerFrame);
femaleButton.UserData = Gender.Female;
femaleButton.OnClicked += SwitchGender;
new GUITextBlock(new Rectangle(0, 150, 200, 30), "Job preferences:", GUI.style, playerFrame);
new GUITextBlock(new Rectangle(x, 150, 200, 30), "Job preferences:", GUI.style, playerFrame);
jobList = new GUIListBox(new Rectangle(0, 180, 200, 0), GUI.style, playerFrame);
jobList = new GUIListBox(new Rectangle(x, 180, 200, 0), GUI.style, playerFrame);
foreach (JobPrefab job in JobPrefab.List)
{
@@ -279,6 +274,8 @@ namespace Subsurface
UpdateJobPreferences(jobList);
UpdatePreviewPlayer(Game1.Client.CharacterInfo);
}
base.Select();
@@ -358,30 +355,32 @@ namespace Subsurface
menu.Draw(spriteBatch);
if (previewPlayer!=null) previewPlayer.Draw(spriteBatch);
GUI.Draw((float)deltaTime, spriteBatch, null);
spriteBatch.End();
if (Game1.Client != null)
{
if (Game1.Client.Character != null)
{
Vector2 position = new Vector2(playerFrame.Rect.X + playerFrame.Rect.Width * 0.25f, playerFrame.Rect.Y + 25.0f);
//if (Game1.Client != null)
//{
// if (Game1.Client.Character != null)
// {
// Vector2 position = new Vector2(playerFrame.Rect.X + playerFrame.Rect.Width * 0.25f, playerFrame.Rect.Y + 25.0f);
Vector2 pos = Game1.Client.Character.Position;
pos.Y = -pos.Y;
Matrix transform = Matrix.CreateTranslation(new Vector3(-pos + position, 0.0f));
// Vector2 pos = Game1.Client.Character.Position;
// pos.Y = -pos.Y;
// Matrix transform = Matrix.CreateTranslation(new Vector3(-pos + position, 0.0f));
spriteBatch.Begin(SpriteSortMode.BackToFront, null, null, null, null, null, transform);
Game1.Client.Character.Draw(spriteBatch);
spriteBatch.End();
}
else
{
CreatePreviewCharacter();
}
}
// spriteBatch.Begin(SpriteSortMode.BackToFront, null, null, null, null, null, transform);
// Game1.Client.Character.Draw(spriteBatch);
// spriteBatch.End();
// }
// else
// {
// CreatePreviewCharacter();
// }
//}
}
@@ -412,43 +411,15 @@ namespace Subsurface
return true;
}
private void CreatePreviewCharacter()
private void UpdatePreviewPlayer(CharacterInfo characterInfo)
{
if (Game1.Client.Character != null) Game1.Client.Character.Remove();
previewPlayer = new GUIFrame(
new Rectangle(playerFrame.Rect.X + 20, playerFrame.Rect.Y + 20, 230, 300),
new Color(0.0f, 0.0f, 0.0f, 0.8f), GUI.style);
previewPlayer.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f);
characterInfo.CreateInfoFrame(previewPlayer);
Vector2 pos = new Vector2(1000.0f, 1000.0f);
Character character = new Character(Game1.Client.CharacterInfo, pos);
character.ID = int.MaxValue;
Game1.Client.Character = character;
character.AnimController.IsStanding = true;
if (previewPlatform == null)
{
Body platform = BodyFactory.CreateRectangle(Game1.World, 3.0f, 1.0f, 5.0f);
platform.SetTransform(new Vector2(pos.X, pos.Y - 2.5f), 0.0f);
platform.IsStatic = true;
}
if (previewHull == null)
{
pos = ConvertUnits.ToDisplayUnits(pos);
previewHull = new Hull(new Rectangle((int)pos.X - 100, (int)pos.Y + 100, 200, 200));
previewHull.ID = int.MaxValue - 2;
}
Physics.Alpha = 1.0f;
for (int i = 0; i < 500; i++)
{
character.AnimController.Update((float)Physics.step);
character.AnimController.UpdateAnim((float)Physics.step);
Game1.World.Step((float)Physics.step);
}
Game1.Client.SendCharacterData();
previewPlayer.UserData = characterInfo;
}
private bool SwitchGender(GUIButton button, object obj)
@@ -458,7 +429,8 @@ namespace Subsurface
Gender gender = (Gender)obj;
Game1.Client.CharacterInfo.Gender = gender;
Game1.Client.SendCharacterData();
CreatePreviewCharacter();
UpdatePreviewPlayer(Game1.Client.CharacterInfo);
//CreatePreviewCharacter();
}
catch
{
@@ -491,6 +463,7 @@ namespace Subsurface
Game1.Client.SendCharacterData();
textBox.Text = newName;
textBox.Selected = false;
return true;
}
@@ -502,7 +475,7 @@ namespace Subsurface
int index = jobList.children.IndexOf(jobText);
int newIndex = index + (int)obj;
if (newIndex<0 || newIndex>jobList.children.Count-1) return false;
if (newIndex < 0 || newIndex > jobList.children.Count - 1) return false;
GUIComponent temp = jobList.children[newIndex];
jobList.children[newIndex] = jobText;
@@ -516,12 +489,12 @@ namespace Subsurface
private void UpdateJobPreferences(GUIListBox listBox)
{
listBox.Deselect();
for (int i = 1; i<listBox.children.Count; i++)
for (int i = 1; i < listBox.children.Count; i++)
{
float a = (float)(i - 1) / 3.0f;
a = Math.Min(a, 3);
Color color = new Color(1.0f-a, (1.0f - a)*0.6f, 0.0f, 0.3f);
Color color = new Color(1.0f - a, (1.0f - a) * 0.6f, 0.0f, 0.3f);
listBox.children[i].Color = color;
}
@@ -592,8 +565,7 @@ namespace Subsurface
string mapName = msg.ReadString();
string md5Hash = msg.ReadString();
TrySelectMap(mapName, md5Hash);
TrySelectMap(mapName, md5Hash);
//mapList.Select(msg.ReadInt32());
modeList.Select(msg.ReadInt32());
@@ -607,8 +579,7 @@ namespace Subsurface
{
int clientID = msg.ReadInt32();
string jobName = msg.ReadString();
Client client = null;
GUITextBlock textBlock = null;
foreach (GUIComponent child in playerList.children)
@@ -621,10 +592,17 @@ namespace Subsurface
break;
}
if (client == null) continue;
client.assignedJob = JobPrefab.List.Find(jp => jp.Name == jobName);
client.assignedJob = JobPrefab.List.Find(jp => jp.Name == jobName);
textBlock.Text = client.name + ((client.assignedJob==null) ? "" : " (" + client.assignedJob.Name + ")");
if (clientID == Game1.Client.ID)
{
Game1.Client.CharacterInfo.Job = new Job(client.assignedJob);
Game1.Client.CharacterInfo.Name = client.name;
UpdatePreviewPlayer(Game1.Client.CharacterInfo);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -53,6 +53,7 @@
<Compile Include="Camera.cs" />
<Compile Include="Characters\AI\AIController.cs" />
<Compile Include="Characters\AI\AITarget.cs" />
<Compile Include="Characters\AI\PathFinder.cs" />
<Compile Include="Characters\AnimController.cs" />
<Compile Include="Characters\Attack.cs" />
<Compile Include="Characters\Character.cs" />
@@ -64,6 +65,7 @@
<Compile Include="Characters\AI\SteeringManager.cs" />
<Compile Include="Characters\AI\SteeringPath.cs" />
<Compile Include="CoroutineManager.cs" />
<Compile Include="Map\LocationType.cs" />
<Compile Include="Rand.cs" />
<Compile Include="Events\PropertyTask.cs" />
<Compile Include="Events\RepairTask.cs" />
@@ -130,14 +132,14 @@
<Compile Include="Map\Entity.cs" />
<Compile Include="Map\Explosion.cs" />
<Compile Include="Map\IDamageable.cs" />
<Compile Include="Map\Level.cs" />
<Compile Include="Map\Levels\Level.cs" />
<Compile Include="Map\Lights\ConvexHull.cs" />
<Compile Include="Map\Lights\LightManager.cs" />
<Compile Include="Map\Location.cs" />
<Compile Include="Map\Map.cs" />
<Compile Include="Map\Md5Hash.cs" />
<Compile Include="Map\Voronoi.cs" />
<Compile Include="Map\VoronoiElements.cs" />
<Compile Include="Map\Levels\Voronoi.cs" />
<Compile Include="Map\Levels\VoronoiElements.cs" />
<Compile Include="MathUtils.cs" />
<Compile Include="Physics\PhysicsBody.cs" />
<Compile Include="Networking\NetworkEvent.cs" />
@@ -269,6 +271,13 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<SubType>Designer</SubType>
</Content>
<Content Include="Content\Characters\Mantis\mantis.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Characters\Mantis\mantis.xml">
<SubType>Designer</SubType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Characters\Moloch\moloch.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -328,6 +337,12 @@
<Content Include="Content\Items\Engine\fabricator.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Items\Engine\pingCircle.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Items\Engine\radarOverlay.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Items\Fabricators\fabricator.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -379,9 +394,15 @@
<Content Include="Content\Map\iceSurface.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Map\locationNames.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Map\shaft.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Map\locationTypes.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\UI\caret.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

View File

@@ -193,8 +193,8 @@ namespace Subsurface
return vector;
}
float.TryParse(components[0], NumberStyles.Float, CultureInfo.InvariantCulture, out vector.X);
float.TryParse(components[1], NumberStyles.Float, CultureInfo.InvariantCulture, out vector.Y);
float.TryParse(components[0], NumberStyles.Any, CultureInfo.InvariantCulture, out vector.X);
float.TryParse(components[1], NumberStyles.Any, CultureInfo.InvariantCulture, out vector.Y);
return vector;
}

Binary file not shown.