Progress on tutorial, misc bugfixes
This commit is contained in:
@@ -43,7 +43,7 @@ namespace Subsurface
|
||||
steeringManager = new SteeringManager(this);
|
||||
}
|
||||
|
||||
public virtual void SelectTarget(IDamageable target) { }
|
||||
public virtual void SelectTarget(AITarget target) { }
|
||||
|
||||
public virtual void Update(float deltaTime) { }
|
||||
|
||||
|
||||
@@ -82,11 +82,10 @@ namespace Subsurface
|
||||
state = AiState.None;
|
||||
}
|
||||
|
||||
public override void SelectTarget(IDamageable target)
|
||||
public override void SelectTarget(AITarget target)
|
||||
{
|
||||
targetEntity = target;
|
||||
selectedAiTarget = target.AiTarget;
|
||||
selectedTargetMemory = FindTargetMemory(target.AiTarget);
|
||||
selectedAiTarget = target;
|
||||
selectedTargetMemory = FindTargetMemory(target);
|
||||
|
||||
targetValue = 100.0f;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,11 @@ namespace Subsurface
|
||||
public float StunTimer
|
||||
{
|
||||
get { return stunTimer; }
|
||||
set { stunTimer = value; }
|
||||
set
|
||||
{
|
||||
if (float.IsNaN(value) || float.IsInfinity(value)) return;
|
||||
stunTimer = value;
|
||||
}
|
||||
}
|
||||
|
||||
public AnimController(Character character, XElement element)
|
||||
|
||||
@@ -1024,6 +1024,10 @@ namespace Subsurface
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (type== NetworkEventType.NotMoving)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//if (type == Networking.NetworkEventType.KeyHit)
|
||||
@@ -1057,11 +1061,11 @@ namespace Subsurface
|
||||
message.Write(limb.body.Position.X);
|
||||
message.Write(limb.body.Position.Y);
|
||||
|
||||
message.Write(limb.body.LinearVelocity.X);
|
||||
message.Write(limb.body.LinearVelocity.Y);
|
||||
//message.Write(limb.body.LinearVelocity.X);
|
||||
//message.Write(limb.body.LinearVelocity.Y);
|
||||
|
||||
message.Write(limb.body.Rotation);
|
||||
message.Write(limb.body.AngularVelocity);
|
||||
//message.WriteRangedSingle(MathHelper.Clamp(limb.body.AngularVelocity, -10.0f, 10.0f), -10.0f, 10.0f, 8);
|
||||
i++;
|
||||
}
|
||||
|
||||
@@ -1118,6 +1122,13 @@ namespace Subsurface
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (type == NetworkEventType.NotMoving)
|
||||
{
|
||||
AnimController.TargetMovement = Vector2.Zero;
|
||||
actionKeyDown.State = false;
|
||||
secondaryKeyDown.State = false;
|
||||
return;
|
||||
}
|
||||
|
||||
bool actionKeyState = false;
|
||||
bool secondaryKeyState = false;
|
||||
@@ -1176,11 +1187,11 @@ namespace Subsurface
|
||||
pos.X = message.ReadFloat();
|
||||
pos.Y = message.ReadFloat();
|
||||
|
||||
vel.X = message.ReadFloat();
|
||||
vel.Y = message.ReadFloat();
|
||||
//vel.X = message.ReadFloat();
|
||||
//vel.Y = message.ReadFloat();
|
||||
|
||||
rotation = message.ReadFloat();
|
||||
angularVel = message.ReadFloat();
|
||||
//angularVel = message.ReadFloat();
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -1189,10 +1200,10 @@ namespace Subsurface
|
||||
|
||||
if (limb.body != null)
|
||||
{
|
||||
limb.body.TargetVelocity = vel;
|
||||
limb.body.TargetVelocity = limb.body.LinearVelocity;
|
||||
limb.body.TargetPosition = pos;// +vel * (float)(deltaTime / 60.0);
|
||||
limb.body.TargetRotation = rotation;// +angularVel * (float)(deltaTime / 60.0);
|
||||
limb.body.TargetAngularVelocity = angularVel;
|
||||
limb.body.TargetAngularVelocity = limb.body.AngularVelocity;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using FarseerPhysics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Subsurface.Items.Components;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
@@ -542,7 +543,7 @@ namespace Subsurface
|
||||
|
||||
void UpdateClimbing()
|
||||
{
|
||||
if (character.SelectedConstruction == null)
|
||||
if (character.SelectedConstruction == null || character.SelectedConstruction.GetComponent<Ladder>()==null)
|
||||
{
|
||||
Anim = Animation.None;
|
||||
return;
|
||||
@@ -623,7 +624,12 @@ namespace Subsurface
|
||||
torso.body.ApplyForce(climbForce * 40.0f * torso.Mass);
|
||||
head.body.SmoothRotate(0.0f);
|
||||
|
||||
Rectangle trigger = character.SelectedConstruction.Prefab.Triggers.First();
|
||||
Rectangle trigger = character.SelectedConstruction.Prefab.Triggers.FirstOrDefault();
|
||||
if (trigger == null)
|
||||
{
|
||||
character.SelectedConstruction = null;
|
||||
return;
|
||||
}
|
||||
trigger = character.SelectedConstruction.TransformTrigger(trigger);
|
||||
|
||||
//stop climbing if:
|
||||
|
||||
@@ -472,7 +472,7 @@ namespace Subsurface
|
||||
inWater = false;
|
||||
headInWater = false;
|
||||
|
||||
if (currentHull.Volume>currentHull.FullVolume*0.95f || ConvertUnits.ToSimUnits(currentHull.Surface)-floorY> HeadPosition*0.95f)
|
||||
if (currentHull.Volume > currentHull.FullVolume * 0.95f || ConvertUnits.ToSimUnits(currentHull.Surface) - floorY > HeadPosition * 0.95f)
|
||||
inWater = true;
|
||||
|
||||
}
|
||||
@@ -562,7 +562,7 @@ namespace Subsurface
|
||||
private void UpdateNetplayerPosition()
|
||||
{
|
||||
Limb refLimb = GetLimb(LimbType.Torso);
|
||||
if (refLimb== null) refLimb = GetLimb(LimbType.Head);
|
||||
if (refLimb == null) refLimb = GetLimb(LimbType.Head);
|
||||
|
||||
if (refLimb.body.TargetPosition == Vector2.Zero) return;
|
||||
|
||||
@@ -603,7 +603,7 @@ namespace Subsurface
|
||||
|
||||
if (resetAll)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("resetall");
|
||||
System.Diagnostics.Debug.WriteLine("reset ragdoll limb positions");
|
||||
|
||||
foreach (Limb limb in limbs)
|
||||
{
|
||||
|
||||
@@ -22,6 +22,8 @@ namespace Subsurface
|
||||
|
||||
Game1.GameSession.StartShift(TimeSpan.Zero, "tutorial");
|
||||
|
||||
Game1.GameSession.taskManager.Tasks.Clear();
|
||||
|
||||
Game1.GameScreen.Select();
|
||||
}
|
||||
|
||||
@@ -184,7 +186,7 @@ namespace Subsurface
|
||||
+ " going into the to the power connection - that's why the monitor isn't working."
|
||||
+ " You should find a piece of wire to connect it. Try searching some of the cabinets scattered around the sub.");
|
||||
|
||||
while (Character.Controlled.Inventory.items.FirstOrDefault(i => i!=null && i.GetComponent<Wire>()!=null)==null)
|
||||
while (!HasItem("Wire"))
|
||||
{
|
||||
yield return Status.Running;
|
||||
}
|
||||
@@ -280,32 +282,159 @@ namespace Subsurface
|
||||
var moloch = new Character("Content/Characters/Moloch/moloch.xml", steering.Item.SimPosition + Vector2.UnitX * 15.0f);
|
||||
moloch.PlaySound(AIController.AiState.Attack);
|
||||
|
||||
//moloch.AIController.
|
||||
|
||||
infoBox = CreateInfoFrame("Uh-oh... Something enormous just appeared on the radar.");
|
||||
|
||||
Structure window = null;
|
||||
List<Structure> windows = new List<Structure>();
|
||||
foreach (Structure s in Structure.wallList)
|
||||
{
|
||||
if (s.CastShadow) continue;
|
||||
if (s.CastShadow || !s.HasBody) continue;
|
||||
|
||||
if (window == null || s.Rect.Right > window.Rect.Right) window = s;
|
||||
if (s.Rect.Right > steering.Item.Position.X) windows.Add(s);
|
||||
}
|
||||
|
||||
bool broken = false;
|
||||
do
|
||||
{
|
||||
moloch.AIController.SelectTarget(steering.Item);
|
||||
for (int i = 0; i < window.SectionCount; i++)
|
||||
moloch.AIController.SelectTarget(steering.Item.CurrentHull.AiTarget);
|
||||
Vector2 steeringDir = windows[0].Position - moloch.Position;
|
||||
if (steeringDir != Vector2.Zero) steeringDir = Vector2.Normalize(steeringDir);
|
||||
|
||||
foreach (Limb limb in moloch.AnimController.limbs)
|
||||
{
|
||||
if (!window.SectionHasHole(i)) continue;
|
||||
broken = true;
|
||||
break;
|
||||
limb.body.LinearVelocity = new Vector2(limb.LinearVelocity.X, limb.LinearVelocity.Y + steeringDir.Y*0.01f);
|
||||
}
|
||||
|
||||
moloch.AIController.Steering = steeringDir;
|
||||
|
||||
foreach (Structure window in windows)
|
||||
{
|
||||
for (int i = 0; i < window.SectionCount; i++)
|
||||
{
|
||||
if (!window.SectionHasHole(i)) continue;
|
||||
broken = true;
|
||||
break;
|
||||
}
|
||||
if (broken) break;
|
||||
}
|
||||
|
||||
|
||||
yield return new WaitForSeconds(1.0f);
|
||||
} while (!broken);
|
||||
|
||||
yield return new WaitForSeconds(1.0f);
|
||||
|
||||
|
||||
var capacitor1 = Item.itemList.Find(i => i.HasTag("capacitor1")).GetComponent<PowerContainer>();
|
||||
var capacitor2 = Item.itemList.Find(i => i.HasTag("capacitor1")).GetComponent<PowerContainer>();
|
||||
CoroutineManager.StartCoroutine(KeepEnemyAway(moloch, new PowerContainer[] { capacitor1, capacitor2 }));
|
||||
|
||||
|
||||
infoBox = CreateInfoFrame("The hull has been breached! Close all the doors to the command room to stop the water from flooding the entire sub!");
|
||||
|
||||
|
||||
Door commandDoor1 = Item.itemList.Find(i => i.HasTag("commanddoor1")).GetComponent<Door>();
|
||||
Door commandDoor2 = Item.itemList.Find(i => i.HasTag("commanddoor2")).GetComponent<Door>();
|
||||
Door commandDoor3 = Item.itemList.Find(i => i.HasTag("commanddoor3")).GetComponent<Door>();
|
||||
|
||||
while (commandDoor1.IsOpen && (commandDoor2.IsOpen || commandDoor3.IsOpen))
|
||||
{
|
||||
yield return Status.Running;
|
||||
}
|
||||
|
||||
infoBox = CreateInfoFrame("Great! You should find yourself an diving mask or a diving suit, in case the creature causes more damage. "+
|
||||
"There are some in the room next to the airlock.");
|
||||
|
||||
while (!HasItem("Diving Mask") && !HasItem("Diving Suit"))
|
||||
{
|
||||
yield return Status.Running;
|
||||
}
|
||||
|
||||
if (HasItem("Diving Mask"))
|
||||
{
|
||||
infoBox = CreateInfoFrame("The diving mask will let you breathe underwater, but it won't protect from the water pressure outside the sub. "+
|
||||
"It should be fine for the situation at hand, but you still need to find an oxygen tank and drag it into the same slot as the mask." +
|
||||
"You should grab one or two.");
|
||||
}
|
||||
else if (HasItem("Diving Suit"))
|
||||
{
|
||||
infoBox = CreateInfoFrame("In addition to letting you breathe underwater, the suit will protect you from the water pressure outside the sub " +
|
||||
"(unlike the diving mask). However, you still need to drag an oxygen tank into the same slot as the suit to supply oxygen. "+
|
||||
"You should grab one or two.");
|
||||
}
|
||||
|
||||
while (!HasItem("Oxygen Tank"))
|
||||
{
|
||||
yield return Status.Running;
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(5.0f);
|
||||
|
||||
infoBox = CreateInfoFrame("Now it's time to stop the creature attacking the submarine. Head to the railgun room at the upper right corner of the sub.");
|
||||
|
||||
var railGun = Item.itemList.Find(i => i.GetComponent<Turret>()!=null);
|
||||
|
||||
while (Vector2.Distance(Character.Controlled.Position, railGun.Position)>500)
|
||||
{
|
||||
yield return new WaitForSeconds(1.0f);
|
||||
}
|
||||
|
||||
infoBox = CreateInfoFrame("The railgun requires a large power surge to fire. The reactor can't provide a surge large enough, so we need to use the "
|
||||
+" supercapacitors in the railgun room. The capacitors need to be charged first; select them and crank up the recharge rate.");
|
||||
|
||||
while (capacitor1.RechargeSpeed<0.5f && capacitor2.RechargeSpeed<0.5f)
|
||||
{
|
||||
yield return new WaitForSeconds(1.0f);
|
||||
}
|
||||
|
||||
infoBox = CreateInfoFrame("The capacitors consume large amounts of power when they're being charged at a high rate. "+
|
||||
"Be cautious to overload the electrical grid or the reactor. They also take some time to recharge, so now is a good "+
|
||||
"time to head to the room below to load some shells into the railgun.");
|
||||
|
||||
|
||||
var loader = Item.itemList.Find(i => i.Name == "Railgun Loader").GetComponent<ItemContainer>();
|
||||
|
||||
while (Math.Abs(Character.Controlled.Position.Y - loader.Item.Position.Y)>50)
|
||||
{
|
||||
yield return Status.Running;
|
||||
}
|
||||
|
||||
infoBox = CreateInfoFrame("Grab one of the shells. You can load it by selecting the railgun loader and dragging the shell to. "
|
||||
+"one of the free slots.");
|
||||
|
||||
while (loader.Item.ContainedItems.FirstOrDefault(i => i != null) != null)
|
||||
{
|
||||
capacitor1.Charge += 1.0f;
|
||||
capacitor2.Charge += 1.0f;
|
||||
yield return Status.Running;
|
||||
}
|
||||
|
||||
|
||||
yield return Status.Success;
|
||||
}
|
||||
|
||||
private bool HasItem(string itemName)
|
||||
{
|
||||
if (Character.Controlled == null) return false;
|
||||
return Character.Controlled.Inventory.items.FirstOrDefault(i => i != null && i.Name == itemName)!=null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// keeps the enemy away from the sub until the capacitors are loaded
|
||||
/// </summary>
|
||||
private IEnumerable<object> KeepEnemyAway(Character enemy, PowerContainer[] capacitors)
|
||||
{
|
||||
do
|
||||
{
|
||||
Vector2 targetPos = Character.Controlled.Position + new Vector2(0.0f, 3000.0f);
|
||||
|
||||
Vector2 steering = targetPos - enemy.Position;
|
||||
if (steering != Vector2.Zero) steering = Vector2.Normalize(steering);
|
||||
|
||||
enemy.AIController.Steering = steering*2.0f;
|
||||
|
||||
yield return Status.Running;
|
||||
} while (capacitors.FirstOrDefault(c => c.Charge > 0.4f) == null);
|
||||
|
||||
yield return Status.Success;
|
||||
}
|
||||
|
||||
|
||||
@@ -92,8 +92,11 @@ namespace Subsurface.Items.Components
|
||||
newText = message.ReadString();
|
||||
}
|
||||
|
||||
catch
|
||||
catch (Exception e)
|
||||
{
|
||||
#if DEBUG
|
||||
DebugConsole.ThrowError("invalid network message", e);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,8 +22,9 @@ namespace Subsurface.Items.Components
|
||||
get { return flowPercentage; }
|
||||
set
|
||||
{
|
||||
if (float.IsNaN(flowPercentage)) return;
|
||||
flowPercentage = MathHelper.Clamp(value,-100.0f,100.0f);
|
||||
if (!MathUtils.IsValid(flowPercentage)) return;
|
||||
flowPercentage = MathHelper.Clamp(value,-100.0f,100.0f);
|
||||
flowPercentage = MathUtils.Round(flowPercentage, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,14 +118,14 @@ namespace Subsurface.Items.Components
|
||||
|
||||
spriteBatch.DrawString(GUI.Font, "Flow percentage: " + (int)flowPercentage + " %", new Vector2(x + 20, y + 80), Color.White);
|
||||
|
||||
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 200, y + 70, 40, 40), "+", true))
|
||||
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 200, y + 70, 40, 40), "+", false))
|
||||
{
|
||||
FlowPercentage += 1.0f;
|
||||
FlowPercentage += 10.0f;
|
||||
item.NewComponentEvent(this, true);
|
||||
}
|
||||
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 250, y + 70, 40, 40), "-", true))
|
||||
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 250, y + 70, 40, 40), "-", false))
|
||||
{
|
||||
FlowPercentage -= 1.0f;
|
||||
FlowPercentage -= 10.0f;
|
||||
item.NewComponentEvent(this, true);
|
||||
}
|
||||
|
||||
@@ -166,7 +167,7 @@ namespace Subsurface.Items.Components
|
||||
|
||||
public override void FillNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetOutgoingMessage message)
|
||||
{
|
||||
message.Write(flowPercentage);
|
||||
message.Write(Convert.ToByte(flowPercentage+100));
|
||||
message.Write(isActive);
|
||||
}
|
||||
|
||||
@@ -177,11 +178,17 @@ namespace Subsurface.Items.Components
|
||||
|
||||
try
|
||||
{
|
||||
newFlow = message.ReadFloat();
|
||||
newFlow = (float)(message.ReadByte()-100);
|
||||
newActive = message.ReadBoolean();
|
||||
}
|
||||
|
||||
catch { return; }
|
||||
catch (Exception e)
|
||||
{
|
||||
#if DEBUG
|
||||
DebugConsole.ThrowError("invalid network message", e);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
FlowPercentage = newFlow;
|
||||
isActive = newActive;
|
||||
|
||||
@@ -68,19 +68,31 @@ namespace Subsurface.Items.Components
|
||||
public float FissionRate
|
||||
{
|
||||
get { return fissionRate; }
|
||||
set { fissionRate = MathHelper.Clamp(value, 0.0f, 100.0f); }
|
||||
set
|
||||
{
|
||||
if (!MathUtils.IsValid(value)) return;
|
||||
fissionRate = MathHelper.Clamp(value, 0.0f, 100.0f);
|
||||
}
|
||||
}
|
||||
|
||||
public float CoolingRate
|
||||
{
|
||||
get { return coolingRate; }
|
||||
set { coolingRate = MathHelper.Clamp(value, 0.0f, 100.0f); }
|
||||
set
|
||||
{
|
||||
if (!MathUtils.IsValid(value)) return;
|
||||
coolingRate = MathHelper.Clamp(value, 0.0f, 100.0f);
|
||||
}
|
||||
}
|
||||
|
||||
public float Temperature
|
||||
{
|
||||
get { return temperature; }
|
||||
set { temperature = MathHelper.Clamp(value, 0.0f, 10000.0f); }
|
||||
set
|
||||
{
|
||||
if (!MathUtils.IsValid(value)) return;
|
||||
temperature = MathHelper.Clamp(value, 0.0f, 10000.0f);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsRunning()
|
||||
@@ -100,6 +112,7 @@ namespace Subsurface.Items.Components
|
||||
public float ShutDownTemp
|
||||
{
|
||||
get { return shutDownTemp; }
|
||||
private set { shutDownTemp = MathHelper.Clamp(value, 0.0f, 10000.0f); }
|
||||
}
|
||||
|
||||
public Reactor(Item item, XElement element)
|
||||
@@ -334,12 +347,12 @@ namespace Subsurface.Items.Components
|
||||
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 400, y + 180, 40, 40), "+", true))
|
||||
{
|
||||
valueChanged = true;
|
||||
shutDownTemp += 100.0f;
|
||||
ShutDownTemp += 100.0f;
|
||||
}
|
||||
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 450, y + 180, 40, 40), "-", true))
|
||||
{
|
||||
valueChanged = true;
|
||||
shutDownTemp -= 100.0f;
|
||||
ShutDownTemp -= 100.0f;
|
||||
}
|
||||
|
||||
if (valueChanged)
|
||||
@@ -392,11 +405,11 @@ namespace Subsurface.Items.Components
|
||||
public override void FillNetworkData(NetworkEventType type, NetOutgoingMessage message)
|
||||
{
|
||||
message.Write(autoTemp);
|
||||
message.Write(temperature);
|
||||
message.Write(shutDownTemp);
|
||||
message.WriteRangedSingle(temperature, 0.0f, 10000.0f, 16);
|
||||
message.WriteRangedSingle(shutDownTemp, 0.0f, 10000.0f, 16);
|
||||
|
||||
message.Write(coolingRate);
|
||||
message.Write(fissionRate);
|
||||
message.WriteRangedSingle(coolingRate, 0.0f, 100.0f, 8);
|
||||
message.WriteRangedSingle(fissionRate, 0.0f, 100.0f, 8);
|
||||
}
|
||||
|
||||
public override void ReadNetworkData(NetworkEventType type, NetIncomingMessage message)
|
||||
@@ -408,18 +421,24 @@ namespace Subsurface.Items.Components
|
||||
try
|
||||
{
|
||||
newAutoTemp = message.ReadBoolean();
|
||||
newTemperature = message.ReadFloat();
|
||||
newShutDownTemp = message.ReadFloat();
|
||||
newTemperature = message.ReadRangedSingle(0.0f, 10000.0f, 16);
|
||||
newShutDownTemp = message.ReadRangedSingle(0.0f, 10000.0f, 16);
|
||||
|
||||
newCoolingRate = message.ReadFloat();
|
||||
newFissionRate = message.ReadFloat();
|
||||
newCoolingRate = message.ReadRangedSingle(0.0f, 100.0f, 8);
|
||||
newFissionRate = message.ReadRangedSingle(0.0f, 100.0f, 8);
|
||||
}
|
||||
|
||||
catch { return; }
|
||||
catch (Exception e)
|
||||
{
|
||||
#if DEBUG
|
||||
DebugConsole.ThrowError("invalid network message", e);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
autoTemp = newAutoTemp;
|
||||
Temperature = newTemperature;
|
||||
shutDownTemp = newShutDownTemp;
|
||||
ShutDownTemp = newShutDownTemp;
|
||||
|
||||
CoolingRate = newCoolingRate;
|
||||
FissionRate = newFissionRate;
|
||||
|
||||
@@ -48,10 +48,7 @@ namespace Subsurface.Items.Components
|
||||
get { return targetVelocity;}
|
||||
set
|
||||
{
|
||||
if (float.IsNaN(value.X) || float.IsNaN(value.Y))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!MathUtils.IsValid(value)) return;
|
||||
targetVelocity.X = MathHelper.Clamp(value.X, -100.0f, 100.0f);
|
||||
targetVelocity.Y = MathHelper.Clamp(value.Y, -100.0f, 100.0f);
|
||||
}
|
||||
|
||||
@@ -45,6 +45,11 @@ namespace Subsurface
|
||||
get { return Vector2.Zero; }
|
||||
}
|
||||
|
||||
public AITarget AiTarget
|
||||
{
|
||||
get { return aiTarget; }
|
||||
}
|
||||
|
||||
public Entity()
|
||||
{
|
||||
//give an unique ID
|
||||
|
||||
@@ -505,7 +505,7 @@ namespace Subsurface
|
||||
|
||||
private void Translate(Vector2 amount)
|
||||
{
|
||||
if (amount == Vector2.Zero || ! amount.IsValid()) return;
|
||||
if (amount == Vector2.Zero || !amount.IsValid()) return;
|
||||
|
||||
Level.Loaded.Move(-amount);
|
||||
}
|
||||
@@ -587,8 +587,11 @@ namespace Subsurface
|
||||
newSpeed = new Vector2(message.ReadFloat(), message.ReadFloat());
|
||||
}
|
||||
|
||||
catch
|
||||
catch (Exception e)
|
||||
{
|
||||
#if DEBUG
|
||||
DebugConsole.ThrowError("invalid network message", e);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -72,13 +72,18 @@ namespace Subsurface.Networking
|
||||
myCharacter = Character.Controlled;
|
||||
|
||||
// Create new instance of configs. Parameter is "application Id". It has to be same on client and server.
|
||||
NetPeerConfiguration Config = new NetPeerConfiguration("subsurface");
|
||||
|
||||
//Config.SimulatedLoss = 0.2f;
|
||||
//Config.SimulatedMinimumLatency = 0.5f;
|
||||
NetPeerConfiguration config = new NetPeerConfiguration("subsurface");
|
||||
|
||||
#if DEBUG
|
||||
config.SimulatedLoss = 0.2f;
|
||||
config.SimulatedMinimumLatency = 0.3f;
|
||||
#endif
|
||||
|
||||
config.DisableMessageType(NetIncomingMessageType.DebugMessage | NetIncomingMessageType.WarningMessage | NetIncomingMessageType.Receipt
|
||||
| NetIncomingMessageType.ErrorMessage | NetIncomingMessageType.Error);
|
||||
|
||||
// Create new client, with previously created configs
|
||||
client = new NetClient(Config);
|
||||
client = new NetClient(config);
|
||||
|
||||
NetOutgoingMessage outmsg = client.CreateMessage();
|
||||
client.Start();
|
||||
@@ -267,9 +272,19 @@ namespace Subsurface.Networking
|
||||
Character.Controlled = null;
|
||||
Game1.GameScreen.Cam.TargetPos = Vector2.Zero;
|
||||
}
|
||||
else
|
||||
else if (gameStarted)
|
||||
{
|
||||
if (gameStarted) new NetworkEvent(myCharacter.ID, true);
|
||||
Vector2 charMovement = myCharacter.AnimController.TargetMovement;
|
||||
if ((charMovement==Vector2.Zero || charMovement.Length()<0.001f) &&
|
||||
!myCharacter.ActionKeyDown.State && !myCharacter.SecondaryKeyDown.State)
|
||||
{
|
||||
new NetworkEvent(NetworkEventType.NotMoving, myCharacter.ID, true);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
new NetworkEvent(myCharacter.ID, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace Subsurface.Networking
|
||||
|
||||
private Client myClient;
|
||||
|
||||
public GameServer(string name, int port, bool isPublic = false, string password="", bool attemptUPnP = false, int maxPlayers = 10)
|
||||
public GameServer(string name, int port, bool isPublic = false, string password = "", bool attemptUPnP = false, int maxPlayers = 10)
|
||||
{
|
||||
var endRoundButton = new GUIButton(new Rectangle(Game1.GraphicsWidth - 290, 20, 150, 25), "End round", Alignment.TopLeft, GUI.style, inGameHUD);
|
||||
endRoundButton.OnClicked = EndButtonHit;
|
||||
@@ -41,8 +41,10 @@ namespace Subsurface.Networking
|
||||
|
||||
config = new NetPeerConfiguration("subsurface");
|
||||
|
||||
//config.SimulatedLoss = 0.2f;
|
||||
//config.SimulatedMinimumLatency = 0.5f;
|
||||
#if DEBUG
|
||||
config.SimulatedLoss = 0.2f;
|
||||
config.SimulatedMinimumLatency = 0.3f;
|
||||
#endif
|
||||
|
||||
config.Port = port;
|
||||
Port = port;
|
||||
@@ -53,6 +55,9 @@ namespace Subsurface.Networking
|
||||
}
|
||||
|
||||
config.MaximumConnections = maxPlayers;
|
||||
|
||||
config.DisableMessageType(NetIncomingMessageType.DebugMessage | NetIncomingMessageType.WarningMessage | NetIncomingMessageType.Receipt
|
||||
| NetIncomingMessageType.ErrorMessage | NetIncomingMessageType.Error);
|
||||
|
||||
config.EnableMessageType(NetIncomingMessageType.ConnectionApproval);
|
||||
|
||||
@@ -457,6 +462,31 @@ namespace Subsurface.Networking
|
||||
{
|
||||
//System.Diagnostics.Debug.WriteLine("networkevent "+networkEvent.ID);
|
||||
|
||||
List<NetConnection> recipients = new List<NetConnection>();
|
||||
|
||||
if (!networkEvent.IsImportant)
|
||||
{
|
||||
Entity e = Entity.FindEntityByID(networkEvent.ID);
|
||||
foreach (Client c in connectedClients)
|
||||
{
|
||||
if (c.character==null) continue;
|
||||
if (Vector2.Distance(e.SimPosition, c.character.SimPosition) > 2000.0f) continue;
|
||||
|
||||
recipients.Add(c.Connection);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (Client c in connectedClients)
|
||||
{
|
||||
if (c.character == null) continue;
|
||||
|
||||
recipients.Add(c.Connection);
|
||||
}
|
||||
}
|
||||
|
||||
if (recipients.Count == 0) return;
|
||||
|
||||
NetOutgoingMessage message = server.CreateMessage();
|
||||
message.Write((byte)PacketTypes.NetworkEvent);
|
||||
//if (!networkEvent.IsClient) continue;
|
||||
@@ -467,7 +497,7 @@ namespace Subsurface.Networking
|
||||
|
||||
if (server.ConnectionsCount>0)
|
||||
{
|
||||
server.SendMessage(message, server.Connections,
|
||||
server.SendMessage(message, recipients,
|
||||
(networkEvent.IsImportant) ? NetDeliveryMethod.Unreliable : NetDeliveryMethod.ReliableUnordered, 0);
|
||||
}
|
||||
|
||||
@@ -703,8 +733,7 @@ namespace Subsurface.Networking
|
||||
|
||||
spriteBatch.DrawString(GUI.SmallFont, "Sent bytes: " + server.Statistics.SentBytes, new Vector2(x + 10, y + 75), Color.White);
|
||||
spriteBatch.DrawString(GUI.SmallFont, "Sent packets: " + server.Statistics.SentPackets, new Vector2(x + 10, y + 90), Color.White);
|
||||
|
||||
|
||||
|
||||
y += 110;
|
||||
foreach (Client c in connectedClients)
|
||||
{
|
||||
|
||||
@@ -11,14 +11,15 @@ namespace Subsurface.Networking
|
||||
DropItem = 3,
|
||||
InventoryUpdate = 4,
|
||||
PickItem = 5,
|
||||
UpdateProperty = 6
|
||||
UpdateProperty = 6,
|
||||
NotMoving = 7
|
||||
}
|
||||
|
||||
class NetworkEvent
|
||||
{
|
||||
public static List<NetworkEvent> events = new List<NetworkEvent>();
|
||||
|
||||
private static bool[] isImportant = { false, true, false, true, true, true };
|
||||
private static bool[] isImportant = { false, true, false, true, true, true, true, false };
|
||||
|
||||
private int id;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Subsurface.Networking;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
@@ -48,6 +49,7 @@ namespace Subsurface
|
||||
get { return targetPosition; }
|
||||
set
|
||||
{
|
||||
if (float.IsNaN(value.X) || float.IsNaN(value.Y)) return;
|
||||
targetPosition.X = MathHelper.Clamp(value.X, -10000.0f, 10000.0f);
|
||||
targetPosition.Y = MathHelper.Clamp(value.Y, -10000.0f, 10000.0f);
|
||||
}
|
||||
@@ -57,7 +59,8 @@ namespace Subsurface
|
||||
{
|
||||
get { return targetVelocity; }
|
||||
set
|
||||
{
|
||||
{
|
||||
if (float.IsNaN(value.X) || float.IsNaN(value.Y)) return;
|
||||
targetVelocity.X = MathHelper.Clamp(value.X, -100.0f, 100.0f);
|
||||
targetVelocity.Y = MathHelper.Clamp(value.Y, -100.0f, 100.0f);
|
||||
}
|
||||
@@ -68,7 +71,7 @@ namespace Subsurface
|
||||
get { return targetRotation; }
|
||||
set
|
||||
{
|
||||
if (float.IsNaN(value) || float.IsInfinity(value) || float.IsNegativeInfinity(value)) return;
|
||||
if (float.IsNaN(value) || float.IsInfinity(value)) return;
|
||||
targetRotation = value;
|
||||
}
|
||||
}
|
||||
@@ -76,7 +79,11 @@ namespace Subsurface
|
||||
public float TargetAngularVelocity
|
||||
{
|
||||
get { return targetAngularVelocity; }
|
||||
set { targetAngularVelocity = value; }
|
||||
set
|
||||
{
|
||||
if (float.IsNaN(value) || float.IsInfinity(value)) return;
|
||||
targetAngularVelocity = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 DrawPosition
|
||||
@@ -356,13 +363,37 @@ namespace Subsurface
|
||||
|
||||
public void ReadNetworkData(NetworkEventType type, NetIncomingMessage message)
|
||||
{
|
||||
targetPosition.X = message.ReadFloat();
|
||||
targetPosition.Y = message.ReadFloat();
|
||||
targetVelocity.X = message.ReadFloat();
|
||||
targetVelocity.Y = message.ReadFloat();
|
||||
Vector2 newTargetPos = Vector2.Zero;
|
||||
Vector2 newTargetVel = Vector2.Zero;
|
||||
|
||||
float newTargetRotation = 0.0f, newTargetAngularVel = 0.0f;
|
||||
try
|
||||
{
|
||||
newTargetPos = new Vector2(message.ReadFloat(),message.ReadFloat());
|
||||
newTargetVel = new Vector2(message.ReadFloat(),message.ReadFloat());
|
||||
|
||||
newTargetRotation = message.ReadFloat();
|
||||
newTargetAngularVel = message.ReadFloat();
|
||||
}
|
||||
|
||||
catch (Exception e)
|
||||
{
|
||||
#if DEBUG
|
||||
DebugConsole.ThrowError("invalid network message", e);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (!MathUtils.IsValid(newTargetPos) || !MathUtils.IsValid(newTargetVel) ||
|
||||
!MathUtils.IsValid(newTargetRotation) || !MathUtils.IsValid(newTargetAngularVel)) return;
|
||||
|
||||
targetPosition = newTargetPos;
|
||||
targetVelocity = newTargetVel;
|
||||
|
||||
targetRotation = newTargetRotation;
|
||||
targetAngularVelocity = newTargetAngularVel;
|
||||
|
||||
|
||||
targetRotation = message.ReadFloat();
|
||||
targetAngularVelocity = message.ReadFloat();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,18 @@ namespace Subsurface
|
||||
return (float)Math.Atan2(vector.Y, vector.X);
|
||||
}
|
||||
|
||||
public static bool IsValid(float value)
|
||||
{
|
||||
return (!float.IsInfinity(value) && !float.IsInfinity(value));
|
||||
}
|
||||
|
||||
public static bool IsValid(Vector2 vector)
|
||||
{
|
||||
return (!float.IsInfinity(vector.X) && !float.IsInfinity(vector.Y) && !float.IsNaN(vector.X) && !float.IsNaN(vector.Y));
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static float CurveAngle(float from, float to, float step)
|
||||
{
|
||||
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user