Networking bugfixes, underwater scooter, fixed limbs going through walls when flipping the ragdoll

This commit is contained in:
Regalis
2015-11-13 00:52:42 +02:00
parent 9c2aec4c8e
commit 24ed95cd68
26 changed files with 301 additions and 119 deletions
+6
View File
@@ -60,6 +60,8 @@
<Compile Include="Source\Characters\AICharacter.cs" />
<Compile Include="Source\Characters\AI\AIController.cs" />
<Compile Include="Source\Characters\AI\AITarget.cs" />
<Compile Include="Source\Characters\AI\Objectives\AIObjectiveOperateItem.cs" />
<Compile Include="Source\Characters\AI\Objectives\AIObjective.cs" />
<Compile Include="Source\Characters\AI\PathFinder.cs" />
<Compile Include="Source\Characters\AnimController.cs" />
<Compile Include="Source\Characters\Attack.cs" />
@@ -90,6 +92,7 @@
<Compile Include="Source\GUI\GUIMessage.cs" />
<Compile Include="Source\GUI\TitleScreen.cs" />
<Compile Include="Source\Items\Components\Holdable\MeleeWeapon.cs" />
<Compile Include="Source\Items\Components\Holdable\Propulsion.cs" />
<Compile Include="Source\Items\Components\Label.cs" />
<Compile Include="Source\Items\Components\Signal\WaterDetector.cs" />
<Compile Include="Source\Items\Components\Signal\WifiComponent.cs" />
@@ -868,6 +871,9 @@
<None Include="Content\Items\Diving\divingSuit.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Content\Items\Diving\scooter.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Content\Items\Door\door.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

+24 -1
View File
@@ -40,7 +40,6 @@
<Containable name="Oxygen Tank"/>
<Containable name="Welding Fuel Tank"/>
</ItemContainer>
</Item>
<Item
@@ -73,6 +72,30 @@
<ItemContainer capacity="1" hideitems="true">
<Containable name="Oxygen Tank"/>
</ItemContainer>
</Item>
<Item
name="Underwater Scooter"
Tags="smallitem"
pickdistance="200"
price="50">
<Sprite texture ="DivingSuit.png" depth="0.5" sourcerect="29,109,45,19"/>
<Body radius="10" height="20" density="5"/>
<Holdable slots="Any,LeftHand,RightHand" aimpos="100,0" handle1="-12,4"/>
<Propulsion force="80" usablein="water" particles="bubbles">
<RequiredItems name="Battery Cell" type="Contained" msg="Battery Cell required"/>
<StatusEffect type="OnUse" target="Contained" targetnames="Battery Cell" Condition="-0.7"/>
<sound file="scooter.ogg" type="OnUse" range="500.0" loop="true"/>
</Propulsion>
<ItemContainer capacity="1" hideitems="true">
<Containable name="Battery Cell"/>
</ItemContainer>
</Item>
</Items>
Binary file not shown.
+2 -2
View File
@@ -12,7 +12,7 @@
<Body width="39" height="18" density="5"/>
<!-- the character will hold the item 50 pixels in front of him, with his hands at the handle1 and handle2 positions -->
<Holdable slots="Any,BothHands"
<Holdable slots="Any,BothHands" controlpose="true"
aimpos="50,0" handle1="-17,0" handle2="8,0"/>
<RepairTool structurefixamount="5.0" limbfixamount="-0.5" range="100" barrelpos="19,8" particles="weld">
@@ -56,7 +56,7 @@
<Body width="39" height="18" density="5"/>
<Holdable slots="Any,BothHands"
<Holdable slots="Any,BothHands" controlpose="true"
aimpos="50,0" handle1="-12,4"/>
<RepairTool structurefixamount="-2.0" limbfixamount="-0.5" range="100" barrelpos="19,8" particles="plasma">
+2 -1
View File
@@ -26,7 +26,8 @@
<Body width="90" height="30" density="10"/>
<Holdable slots="Any,BothHands" holdpos="35,-10" aimpos="35,-10" handle1="-15,-6" handle2="26,7"/>
<Holdable slots="Any,BothHands" controlpose="true"
holdpos="35,-10" aimpos="35,-10" handle1="-15,-6" handle2="26,7"/>
<RangedWeapon barrelpos="49,10">
<Sound file="harpoon1.ogg" type="OnUse"/>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Barotrauma
{
class AIObjective
{
protected List<AIObjective> subObjectives;
public virtual bool IsCompleted()
{
return true;
}
public AIObjective()
{
subObjectives = new List<AIObjective>();
}
/// <summary>
/// makes the character act according to the objective, or according to any subobjectives that
/// need to be completed before this one (starting from the one with the highest priority)
/// </summary>
/// <param name="character">the character who's trying to achieve the objective</param>
public void TryComplete(float deltaTime, Character character)
{
foreach (AIObjective objective in subObjectives)
{
if (objective.IsCompleted()) continue;
objective.TryComplete(deltaTime, character);
return;
}
Act(deltaTime, character);
}
protected virtual void Act(float deltaTime, Character character) { }
}
}
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Barotrauma
{
class AIObjectiveOperateItem : AIObjective
{
private Item targetItem;
public AIObjectiveOperateItem(Item item)
{
targetItem = item;
}
protected override void Act(float deltaTime, Character character)
{
//item.AIOperate(float deltaTime, Character character) or something
}
}
}
@@ -787,6 +787,8 @@ namespace Barotrauma
public override void HoldItem(float deltaTime, Item item, Vector2[] handlePos, Vector2 holdPos, Vector2 aimPos, bool aim, float holdAngle)
{
Holdable holdable = item.GetComponent<Holdable>();
//calculate the handle positions
Matrix itemTransfrom = Matrix.CreateRotationZ(item.body.Rotation);
Vector2[] transformedHandlePos = new Vector2[2];
@@ -808,19 +810,23 @@ namespace Barotrauma
Vector2 diff = (mousePos - torso.SimPosition) * Dir;
holdAngle = MathUtils.VectorToAngle(new Vector2(diff.X, diff.Y * Dir)) - torso.body.Rotation * Dir;
holdAngle = MathHelper.Clamp(MathUtils.WrapAnglePi(holdAngle), -1.3f, 1.0f);
//holdAngle = MathHelper.Clamp(MathUtils.WrapAnglePi(holdAngle), -1.3f, 1.0f);
itemAngle = (torso.body.Rotation + holdAngle * Dir);
head.body.SmoothRotate(itemAngle);
if (TargetMovement == Vector2.Zero && inWater)
if (holdable.ControlPose)
{
torso.body.AngularVelocity -= torso.body.AngularVelocity * 0.1f;
torso.body.ApplyForce(torso.body.LinearVelocity * -0.5f);
head.body.SmoothRotate(itemAngle);
if (TargetMovement == Vector2.Zero && inWater)
{
torso.body.AngularVelocity -= torso.body.AngularVelocity * 0.1f;
torso.body.ApplyForce(torso.body.LinearVelocity * -0.5f);
}
aiming = true;
}
aiming = true;
}
else
{
@@ -945,23 +951,25 @@ namespace Barotrauma
}
}
foreach (Limb l in Limbs)
foreach (Limb limb in Limbs)
{
switch (l.type)
switch (limb.type)
{
case LimbType.LeftHand:
case LimbType.LeftArm:
case LimbType.RightHand:
case LimbType.RightArm:
difference = l.body.SimPosition - torso.SimPosition;
difference = limb.body.SimPosition - torso.SimPosition;
difference = Vector2.Transform(difference, torsoTransform);
difference.Y = -difference.Y;
l.body.SetTransform(torso.SimPosition + Vector2.Transform(difference, -torsoTransform), -l.body.Rotation);
TrySetLimbPosition(limb, limb.SimPosition, torso.SimPosition + Vector2.Transform(difference, -torsoTransform));
limb.body.SetTransform(limb.body.SimPosition, -limb.body.Rotation);
break;
default:
if (!inWater) l.body.SetTransform(l.body.SimPosition,
MathUtils.WrapAnglePi(l.body.Rotation * (l.DoesFlip ? -1.0f : 1.0f)));
if (!inWater) limb.body.SetTransform(limb.body.SimPosition,
MathUtils.WrapAnglePi(limb.body.Rotation * (limb.DoesFlip ? -1.0f : 1.0f)));
break;
}
}
+1 -1
View File
@@ -671,7 +671,7 @@ namespace Barotrauma
}
}
private void TrySetLimbPosition(Limb limb, Vector2 original, Vector2 simPosition)
protected void TrySetLimbPosition(Limb limb, Vector2 original, Vector2 simPosition)
{
if (original == simPosition) return;
+1
View File
@@ -305,6 +305,7 @@ namespace Barotrauma
case "loadsub":
case "load":
if (commands.Length < 2) break;
Submarine.Load(string.Join(" ", commands.Skip(1)));
break;
case "cleansub":
+4 -33
View File
@@ -357,17 +357,11 @@ namespace Barotrauma
public override bool FillNetworkData(NetworkEventType type, NetBuffer message, object data)
{
for (int i = 0; i < 5; i++ )
for (int i = 0; i < capacity; i++)
{
message.Write(items[i]==null ? (ushort)0 : (ushort)items[i].ID);
}
for (int i = 5; i < capacity; i++)
{
if (items[i] == null) continue;
message.Write((ushort)items[i].ID);
}
return true;
}
@@ -375,7 +369,7 @@ namespace Barotrauma
{
character.ClearInput(InputType.Use);
for (int i = 0; i<5; i++)
for (int i = 0; i<capacity; i++)
{
ushort itemId = message.ReadUInt16();
if (itemId==0)
@@ -387,34 +381,11 @@ namespace Barotrauma
Item item = Entity.FindEntityByID(itemId) as Item;
if (item == null) continue;
if (items[i] != item) items[i].Drop(character, false);
TryPutItem(item, i, false);
}
}
List<ushort> newItemIDs = new List<ushort>();
for (int i = 5; i < capacity; i++)
{
newItemIDs.Add(message.ReadUInt16());
}
for (int i = 5; i < capacity; i++)
{
if (items[i] == null) continue;
if (!newItemIDs.Contains(items[i].ID))
{
items[i].Drop(null, false);
continue;
}
}
foreach (ushort itemId in newItemIDs)
{
Item item = Entity.FindEntityByID(itemId) as Item;
if (item == null) continue;
TryPutItem(item, LimbSlot.Any, false);
}
}
}
@@ -19,7 +19,7 @@ namespace Barotrauma.Items.Components
protected Vector2 aimPos;
protected bool aimable;
//protected bool aimable;
private bool attachable, attached, attachedByDefault;
private PhysicsBody body;
@@ -35,10 +35,10 @@ namespace Barotrauma.Items.Components
}
[HasDefaultValue(false, false)]
public bool Aimable
public bool ControlPose
{
get { return aimable; }
set { aimable = value; }
get;
set;
}
[HasDefaultValue(false, false)]
@@ -0,0 +1,120 @@
using System;
using System.Collections.Generic;
using System.Xml.Linq;
using FarseerPhysics;
using FarseerPhysics.Dynamics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Barotrauma.Particles;
namespace Barotrauma.Items.Components
{
class Propulsion : ItemComponent
{
private float force;
private string particles;
private ParticlePrefab.DrawTargetType usableIn;
[HasDefaultValue(0.0f, false)]
public float Force
{
get { return force; }
set { force = value; }
}
[HasDefaultValue("", false)]
public string Particles
{
get { return particles; }
set { particles = value; }
}
public Propulsion(Item item, XElement element)
: base(item,element)
{
switch (ToolBox.GetAttributeString(element, "usablein", "air").ToLower())
{
case "air":
usableIn = ParticlePrefab.DrawTargetType.Air;
break;
case "water":
usableIn = ParticlePrefab.DrawTargetType.Water;
break;
default:
usableIn = ParticlePrefab.DrawTargetType.Both;
break;
}
}
public override bool Use(float deltaTime, Character character = null)
{
if (character == null) return false;
if (!character.IsKeyDown(InputType.Aim)) return false;
if (item.InWater)
{
if (usableIn == ParticlePrefab.DrawTargetType.Air) return true;
}
else
{
if (usableIn == ParticlePrefab.DrawTargetType.Water) return true;
}
Vector2 dir = Vector2.Normalize(character.CursorPosition - character.Position);
Vector2 propulsion = dir * force;
if (character.AnimController.InWater) character.AnimController.TargetMovement = dir;
if (item.body.Enabled && false)
{
item.body.ApplyForce(propulsion);
}
else
{
foreach (Limb limb in character.AnimController.Limbs)
{
if (limb.WearingItem==null || limb.WearingItem.Item != item) continue;
limb.body.ApplyForce(propulsion);
}
if (character.SelectedItems[0] == item) character.AnimController.GetLimb(LimbType.RightHand).body.ApplyForce(propulsion);
if (character.SelectedItems[1] == item) character.AnimController.GetLimb(LimbType.LeftHand).body.ApplyForce(propulsion);
}
if (!string.IsNullOrWhiteSpace(particles))
{
GameMain.ParticleManager.CreateParticle(particles, item.Position,
item.body.Rotation + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi), 0.0f);
}
return true;
}
public override void Draw(SpriteBatch spriteBatch, bool editing)
{
if (!IsActive) return;
//Vector2 particleSpeed = new Vector2(
// (float)Math.Cos(item.body.Rotation),
// (float)Math.Sin(item.body.Rotation)) *item.body.Dir * 0.1f;
//Vector2 startPos = ConvertUnits.ToDisplayUnits(item.body.Position);
//Vector2 endPos = ConvertUnits.ToDisplayUnits(pickedPosition);
//endPos = new Vector2(endPos.X + Game1.localRandom.Next(-2, 2), endPos.Y + Game1.localRandom.Next(-2, 2));
//GUI.DrawLine(spriteBatch, startPos, endPos, Color.Orange, 0.0f);
IsActive = false;
}
}
}
@@ -4,35 +4,15 @@ namespace Barotrauma.Items.Components
{
class WaterDetector : ItemComponent
{
private Hull hull;
public WaterDetector(Item item, XElement element)
: base (item, element)
{
hull = Hull.FindHull(item.Position);
IsActive = true;
}
public override void OnMapLoaded()
{
hull = Hull.FindHull(item.Position);
}
public override void Move(Microsoft.Xna.Framework.Vector2 amount)
{
hull = Hull.FindHull(item.Position);
}
public override void Update(float deltaTime, Camera cam)
{
if (hull == null) return;
float waterDepth = hull.Volume / hull.Size.X;
bool underWater = (hull.Rect.Y-hull.Rect.Height + waterDepth)>item.Position.Y;
item.SendSignal(underWater ? "1" : "0", "signal_out");
item.SendSignal(item.InWater ? "1" : "0", "signal_out");
}
}
}
+24 -24
View File
@@ -58,6 +58,8 @@ namespace Barotrauma
private float condition;
private bool inWater;
//the inventory in which the item is contained in
public Inventory inventory;
@@ -153,6 +155,18 @@ namespace Barotrauma
get { return prefab.FireProof; }
}
public bool InWater
{
get
{
//if the item has an active physics body, inWater is updated in the Update method
if (body != null && body.Enabled) return inWater;
//if not, we'll just have to check
return IsInWater();
}
}
public bool Updated
{
set
@@ -501,6 +515,15 @@ namespace Barotrauma
return new AttackResult(damageAmount, 0.0f, false);
}
private bool IsInWater()
{
if (CurrentHull == null) return true;
float surfaceY = CurrentHull.Surface;
return Position.Y < surfaceY;
}
public override void Update(Camera cam, float deltaTime)
{
@@ -545,30 +568,7 @@ namespace Barotrauma
body.SetToTargetPosition();
bool inWater = true;
if (CurrentHull != null)
{
float surfaceY = ConvertUnits.ToSimUnits(CurrentHull.Surface);
if (body.SimPosition.Y < surfaceY )
{
inWater = true;
//the item has gone through the surface of the water -> apply an impulse which serves as surface tension
//if (body.SimPosition.Y - (body.LinearVelocity.Y / 60.0f) < surfaceY)
//{
// Vector2 impulse = -body.LinearVelocity * (body.Mass / body.Density);
// body.ApplyLinearImpulse(impulse);
// int n = (int)((ConvertUnits.ToDisplayUnits(body.SimPosition.X) - CurrentHull.Rect.X) / Hull.WaveWidth);
// CurrentHull.WaveVel[n] = impulse.Y * 10.0f;
//}
}
else
{
inWater = false;
}
}
inWater = IsInWater();
if (!inWater) return;
+1 -1
View File
@@ -169,7 +169,7 @@ namespace Barotrauma.Lights
Vector2 scale = new Vector2(MathHelper.Clamp(diff.Length()/256.0f, 2.0f, 5.0f), 2.0f);
spriteBatch.Draw(LightSource.LightTexture, new Vector2(ViewPos.X, -ViewPos.Y), null, Color.White, rotation,
spriteBatch.Draw(visionCircle, new Vector2(ViewPos.X, -ViewPos.Y), null, Color.White, rotation,
new Vector2(LightSource.LightTexture.Width*0.2f, LightSource.LightTexture.Height/2), scale, SpriteEffects.None, 0.0f);
spriteBatch.End();
+1 -1
View File
@@ -682,7 +682,7 @@ namespace Barotrauma.Networking
public bool SpectateClicked(GUIButton button, object userData)
{
NetOutgoingMessage msg = client.CreateMessage();
msg.Write((byte)PacketTypes.Spectate);
msg.Write((byte)PacketTypes.SpectateRequest);
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
+11 -5
View File
@@ -460,11 +460,13 @@ namespace Barotrauma.Networking
case (byte)PacketTypes.Vote:
Voting.RegisterVote(inc, ConnectedClients);
break;
case (byte)PacketTypes.Spectate:
case (byte)PacketTypes.SpectateRequest:
if (gameStarted)
{
var startMessage = CreateStartMessage(roundStartSeed, Submarine.Loaded, GameMain.GameSession.gameMode.Preset);
server.SendMessage(startMessage, inc.SenderConnection, NetDeliveryMethod.ReliableUnordered);
dataSender.Spectating = true;
}
break;
}
@@ -674,9 +676,6 @@ namespace Barotrauma.Networking
GameMain.GameSession = new GameSession(selectedSub, "", selectedMode);
GameMain.GameSession.StartShift(GameMain.NetLobbyScreen.LevelSeed);
var startMessage = CreateStartMessage(roundStartSeed, Submarine.Loaded, GameMain.GameSession.gameMode.Preset);
SendMessage(startMessage, NetDeliveryMethod.ReliableUnordered);
yield return CoroutineStatus.Running;
List<CharacterInfo> characterInfos = new List<CharacterInfo>();
@@ -717,6 +716,10 @@ namespace Barotrauma.Networking
myCharacter.GiveJobItems(assignedWayPoints[assignedWayPoints.Length - 1]);
}
var startMessage = CreateStartMessage(roundStartSeed, Submarine.Loaded, GameMain.GameSession.gameMode.Preset);
SendMessage(startMessage, NetDeliveryMethod.ReliableUnordered);
yield return CoroutineStatus.Running;
UpdateCrewFrame();
@@ -761,7 +764,7 @@ namespace Barotrauma.Networking
if (myCharacter != null)
{
msg.Write(-1);
WriteCharacterData(msg, myCharacter.Info.Name, Character.Controlled);
WriteCharacterData(msg, myCharacter.Info.Name, myCharacter);
}
return msg;
@@ -799,6 +802,7 @@ namespace Barotrauma.Networking
foreach (Client client in ConnectedClients)
{
client.Spectating = false;
client.Character = null;
client.inGame = false;
}
@@ -1328,6 +1332,8 @@ namespace Barotrauma.Networking
public List<JobPrefab> jobPreferences;
public JobPrefab assignedJob;
public bool Spectating;
public ReliableChannel ReliableChannel;
public float deleteDisconnectedTimer;
+3 -1
View File
@@ -192,7 +192,6 @@ namespace Barotrauma.Networking
}
Entity e = Entity.FindEntityByID(id);
System.Diagnostics.Debug.WriteLine(e.ToString());
if (e == null)
{
#if DEBUG
@@ -201,6 +200,9 @@ namespace Barotrauma.Networking
return false;
}
System.Diagnostics.Debug.WriteLine(e.ToString());
object data;
try
@@ -29,7 +29,7 @@ namespace Barotrauma.Networking
ResendRequest, ReliableMessage, LatestMessageID,
Spectate
SpectateRequest
}
enum VoteType
+1 -9
View File
@@ -160,15 +160,7 @@ namespace Barotrauma.Particles
if ((prefab.DeleteOnCollision || prefab.CollidesWithWalls) && currentHull!=null)
{
Vector2 edgePos = position + prefab.Sprites[spriteIndex].SourceRect.Width * Vector2.Normalize(velocity) * size.X;
//bool insideHull = false;
//foreach (Hull hull in hullLimits)
//{
// if (!Submarine.RectContains(hull.Rect, edgePos)) continue;
// insideHull = true;
// break;
//}
Vector2 edgePos = position + prefab.CollisionRadius * Vector2.Normalize(velocity) * size.X;
if (!Submarine.RectContains(currentHull.Rect, edgePos))
{
@@ -29,6 +29,7 @@ namespace Barotrauma.Particles
public readonly float GrowTime;
public readonly float CollisionRadius;
public readonly bool DeleteOnCollision;
public readonly bool CollidesWithWalls;
@@ -122,7 +123,9 @@ namespace Barotrauma.Particles
StartAlpha = ToolBox.GetAttributeFloat(element, "startalpha", 1.0f);
DeleteOnCollision = ToolBox.GetAttributeBool(element, "deleteoncollision", false);
CollidesWithWalls = ToolBox.GetAttributeBool(element, "collideswithwalls", false);
CollidesWithWalls = ToolBox.GetAttributeBool(element, "collideswithwalls", false);
CollisionRadius = ToolBox.GetAttributeFloat(element, "collisionradius", Sprites[0].SourceRect.Width/2.0f);
ColorChange = ToolBox.GetAttributeVector4(element, "colorchange", Vector4.Zero);
@@ -221,6 +221,11 @@ namespace Barotrauma
if (characterMode)
{
if (Entity.FindEntityByID(dummyCharacter.ID)!=dummyCharacter)
{
ToggleCharacterMode(null, null);
}
foreach (MapEntity me in MapEntity.mapEntityList)
{
me.IsHighlighted = false;
Binary file not shown.