Networking optimization/bugfixes (hull water volumes & wall damage are synced, more reliable inventory updates, AICharacter sync changes), proper particle collisions with walls

This commit is contained in:
Regalis
2015-09-25 18:56:39 +03:00
parent 3587b4a4bb
commit 53e729ea11
27 changed files with 50344 additions and 273 deletions

View File

@@ -223,6 +223,8 @@ namespace FarseerPhysics.Collision
public static float Evaluate(int indexA, int indexB, float t)
{
if (float.IsNaN(t)) return 0.0f;
Transform xfA, xfB;
_sweepA.GetTransform(out xfA, t);
_sweepB.GetTransform(out xfB, t);

View File

@@ -29,7 +29,6 @@
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(LauncherMain));
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.launchButton = new System.Windows.Forms.Button();
this.resolutionBox = new System.Windows.Forms.ComboBox();
this.label1 = new System.Windows.Forms.Label();
@@ -37,26 +36,16 @@
this.contentPackageBox = new System.Windows.Forms.ComboBox();
this.label2 = new System.Windows.Forms.Label();
this.packageManagerButton = new System.Windows.Forms.Button();
this.label3 = new System.Windows.Forms.Label();
this.installedVersionLabel = new System.Windows.Forms.Label();
this.autoUpdateCheckBox = new System.Windows.Forms.CheckBox();
this.progressBar = new System.Windows.Forms.ProgressBar();
this.patchNoteBox = new System.Windows.Forms.TextBox();
this.updateLabel = new System.Windows.Forms.Label();
this.downloadButton = new System.Windows.Forms.Button();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
//
// pictureBox1
//
this.pictureBox1.BackColor = System.Drawing.Color.OrangeRed;
this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image")));
this.pictureBox1.Location = new System.Drawing.Point(-11, 33);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(650, 42);
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
//
// launchButton
//
this.launchButton.BackColor = System.Drawing.Color.OrangeRed;
@@ -137,16 +126,16 @@
this.packageManagerButton.UseVisualStyleBackColor = false;
this.packageManagerButton.Click += new System.EventHandler(this.packageManagerButton_Click);
//
// label3
// installedVersionLabel
//
this.label3.AutoSize = true;
this.label3.BackColor = System.Drawing.Color.Transparent;
this.label3.ForeColor = System.Drawing.SystemColors.ControlLightLight;
this.label3.Location = new System.Drawing.Point(266, 78);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(86, 13);
this.label3.TabIndex = 8;
this.label3.Text = "Installed version:";
this.installedVersionLabel.BackColor = System.Drawing.Color.Transparent;
this.installedVersionLabel.ForeColor = System.Drawing.SystemColors.ControlLightLight;
this.installedVersionLabel.Location = new System.Drawing.Point(-8, 78);
this.installedVersionLabel.Name = "installedVersionLabel";
this.installedVersionLabel.Size = new System.Drawing.Size(644, 23);
this.installedVersionLabel.TabIndex = 8;
this.installedVersionLabel.Text = "Installed version:";
this.installedVersionLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// autoUpdateCheckBox
//
@@ -202,20 +191,32 @@
this.downloadButton.UseVisualStyleBackColor = false;
this.downloadButton.Click += new System.EventHandler(this.downloadButton_Click);
//
// pictureBox1
//
this.pictureBox1.BackColor = System.Drawing.Color.Transparent;
this.pictureBox1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image")));
this.pictureBox1.Location = new System.Drawing.Point(-8, 12);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(644, 63);
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
//
// LauncherMain
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.SystemColors.ButtonHighlight;
this.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("$this.BackgroundImage")));
this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
this.ClientSize = new System.Drawing.Size(628, 453);
this.Controls.Add(this.downloadButton);
this.Controls.Add(this.updateLabel);
this.Controls.Add(this.patchNoteBox);
this.Controls.Add(this.progressBar);
this.Controls.Add(this.autoUpdateCheckBox);
this.Controls.Add(this.label3);
this.Controls.Add(this.installedVersionLabel);
this.Controls.Add(this.packageManagerButton);
this.Controls.Add(this.label2);
this.Controls.Add(this.contentPackageBox);
@@ -227,6 +228,7 @@
this.DoubleBuffered = true;
this.Name = "LauncherMain";
this.Text = "Form1";
this.Load += new System.EventHandler(this.LauncherMain_Load);
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
@@ -235,7 +237,6 @@
#endregion
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.Button launchButton;
private System.Windows.Forms.ComboBox resolutionBox;
private System.Windows.Forms.Label label1;
@@ -243,12 +244,13 @@
private System.Windows.Forms.ComboBox contentPackageBox;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Button packageManagerButton;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label installedVersionLabel;
private System.Windows.Forms.CheckBox autoUpdateCheckBox;
private System.Windows.Forms.ProgressBar progressBar;
private System.Windows.Forms.TextBox patchNoteBox;
private System.Windows.Forms.Label updateLabel;
private System.Windows.Forms.Button downloadButton;
private System.Windows.Forms.PictureBox pictureBox1;
}
}

View File

@@ -109,6 +109,8 @@ namespace Launcher
updateLabel.Visible = false;
downloadButton.Visible = false;
installedVersionLabel.Text = "Installed version: " + version;
if (settings.AutoCheckUpdates)
{
CheckForUpdates();
@@ -313,6 +315,11 @@ namespace Launcher
}
private void LauncherMain_Load(object sender, EventArgs e)
{
}
}
public class GraphicsMode

File diff suppressed because it is too large Load Diff

View File

@@ -256,11 +256,11 @@
//
// pictureBox1
//
this.pictureBox1.BackColor = System.Drawing.Color.OrangeRed;
this.pictureBox1.BackColor = System.Drawing.Color.Transparent;
this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image")));
this.pictureBox1.Location = new System.Drawing.Point(0, 26);
this.pictureBox1.Location = new System.Drawing.Point(-8, 12);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(784, 42);
this.pictureBox1.Size = new System.Drawing.Size(802, 56);
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
this.pictureBox1.TabIndex = 17;
this.pictureBox1.TabStop = false;
@@ -299,7 +299,7 @@
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("$this.BackgroundImage")));
this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
this.ClientSize = new System.Drawing.Size(784, 562);
this.Controls.Add(this.exeButton);
this.Controls.Add(this.exeBox);

File diff suppressed because it is too large Load Diff

View File

@@ -51,6 +51,7 @@
<HintPath>..\packages\RestSharp.105.2.3\lib\net4\RestSharp.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.XML" />
<Reference Include="System.Xml.Linq" />
</ItemGroup>

View File

@@ -5,10 +5,10 @@
sizechangemin="0.9,0.9" sizechangemax="1.2,1.2"
startrotationmin ="0.0" startrotationmax="360"
startcolor="1.0, 1.0, 1.0" startalpha="0.8"
colorchange="0.0, 0.0, 0.0, -0.25"
lifetime="3"
colorchange="0.0, 0.0, 0.0, -0.8"
lifetime="2"
growtime ="0.2"
deleteoncollision="true"
collideswithwalls="true"
velocitychange="0.0, -9.8">
<sprite texture="Content/Particles/spatter.png"/>
</watersplash>
@@ -111,7 +111,7 @@
lifetime="5.0"
growtime ="0.05"
drawtarget="air"
deleteoncollision="true"
collideswithwalls="true"
velocitychange="0.0, 0.5">
<sprite texture="Content/Particles/explosion.png" sourcerect="0,0,128,128"/>
</explosionfire>

View File

@@ -487,10 +487,17 @@ namespace Subsurface
message.Write(wallAttackPos.Y);
}
//message.Write(Velocity.X);
//message.Write(Velocity.Y);
//message.Write(Character.AnimController.RefLimb.SimPosition.X);
//message.Write(Character.AnimController.RefLimb.SimPosition.Y);
message.Write(MathUtils.AngleToByte(steeringManager.WanderAngle));
message.WriteRangedSingle(MathHelper.Clamp(updateTargetsTimer,0.0f, UpdateTargetsInterval), 0.0f, UpdateTargetsInterval, 8);
message.WriteRangedSingle(MathHelper.Clamp(raycastTimer, 0.0f, RaycastInterval), 0.0f, RaycastInterval, 8);
message.WriteRangedSingle(MathHelper.Clamp(coolDownTimer, 0.0f, attackCoolDown * 2.0f), 0.0f, attackCoolDown * 2.0f, 8);
//message.WriteRangedSingle(MathHelper.Clamp(updateTargetsTimer,0.0f, UpdateTargetsInterval), 0.0f, UpdateTargetsInterval, 8);
//message.WriteRangedSingle(MathHelper.Clamp(raycastTimer, 0.0f, RaycastInterval), 0.0f, RaycastInterval, 8);
//message.WriteRangedSingle(MathHelper.Clamp(coolDownTimer, 0.0f, attackCoolDown * 2.0f), 0.0f, attackCoolDown * 2.0f, 8);
message.Write(targetEntity==null ? -1 : (targetEntity as Entity).ID);
}
@@ -502,6 +509,10 @@ namespace Subsurface
float wanderAngle;
float updateTargetsTimer, raycastTimer, coolDownTimer;
Vector2 newVelocity = Vector2.Zero;
Vector2 targetPosition = Vector2.Zero;
int targetID;
try
@@ -516,10 +527,14 @@ namespace Subsurface
newWallAttackPos = new Vector2(message.ReadFloat(), message.ReadFloat());
}
//newVelocity = new Vector2(message.ReadFloat(), message.ReadFloat());
//targetPosition = new Vector2(message.ReadFloat(), message.ReadFloat());
wanderAngle = MathUtils.ByteToAngle(message.ReadByte());
updateTargetsTimer = message.ReadRangedSingle(0.0f, UpdateTargetsInterval, 8);
raycastTimer = message.ReadRangedSingle(0.0f, RaycastInterval, 8);
coolDownTimer = message.ReadRangedSingle(0.0f, attackCoolDown*2.0f, 8);
//updateTargetsTimer = message.ReadRangedSingle(0.0f, UpdateTargetsInterval, 8);
//raycastTimer = message.ReadRangedSingle(0.0f, RaycastInterval, 8);
//coolDownTimer = message.ReadRangedSingle(0.0f, attackCoolDown*2.0f, 8);
targetID = message.ReadInt32();
}
@@ -529,9 +544,9 @@ namespace Subsurface
wallAttackPos = newWallAttackPos;
steeringManager.WanderAngle = wanderAngle;
this.updateTargetsTimer = updateTargetsTimer;
this.raycastTimer = raycastTimer;
this.coolDownTimer = coolDownTimer;
//this.updateTargetsTimer = updateTargetsTimer;
//this.raycastTimer = raycastTimer;
//this.coolDownTimer = coolDownTimer;
if (targetID > -1)
targetEntity = Entity.FindEntityByID(targetID) as IDamageable;

View File

@@ -59,9 +59,9 @@ namespace Subsurface
aiController.Update(deltaTime);
}
public override AttackResult AddDamage(IDamageable attacker, Vector2 position, Attack attack, bool playSound = false)
public override AttackResult AddDamage(IDamageable attacker, Vector2 position, Attack attack, float deltaTime, bool playSound = false)
{
AttackResult result = base.AddDamage(attacker, position, attack, playSound);
AttackResult result = base.AddDamage(attacker, position, attack, deltaTime, playSound);
aiController.OnAttacked(attacker, (result.Damage + result.Bleeding)/Math.Max(health,1.0f));
@@ -107,6 +107,9 @@ namespace Subsurface
message.Write(AnimController.RefLimb.SimPosition.X);
message.Write(AnimController.RefLimb.SimPosition.Y);
message.Write(AnimController.RefLimb.LinearVelocity.X);
message.Write(AnimController.RefLimb.LinearVelocity.Y);
LargeUpdateTimer = Math.Max(0, LargeUpdateTimer - 1);
}
}
@@ -201,19 +204,21 @@ namespace Subsurface
}
else
{
Vector2 pos = Vector2.Zero;
Vector2 pos = Vector2.Zero, vel = Vector2.Zero;
try
{
pos.X = message.ReadFloat();
pos.Y = message.ReadFloat();
vel.X = message.ReadFloat();
vel.Y = message.ReadFloat();
}
catch { return; }
Limb torso = AnimController.GetLimb(LimbType.Torso);
if (torso == null) torso = AnimController.GetLimb(LimbType.Head);
torso.body.TargetPosition = pos;
AnimController.RefLimb.body.TargetPosition = pos;
AnimController.RefLimb.body.TargetVelocity = vel;
LargeUpdateTimer = 0;
}

View File

@@ -39,9 +39,9 @@ namespace Subsurface
public readonly DamageType DamageType;
public readonly float StructureDamage;
public readonly float Damage;
public readonly float BleedingDamage;
private readonly float structureDamage;
private readonly float damage;
private readonly float bleedingDamage;
private Sound sound;
@@ -51,6 +51,21 @@ namespace Subsurface
private float priority;
public float GetDamage(float deltaTime)
{
return (Duration == 0.0f) ? damage : damage * deltaTime;
}
public float GetBleedingDamage(float deltaTime)
{
return (Duration == 0.0f) ? bleedingDamage : bleedingDamage * deltaTime;
}
public float GetStructureDamage(float deltaTime)
{
return (Duration == 0.0f) ? structureDamage : structureDamage * deltaTime;
}
//public Attack(AttackType type, float range,)
//{
@@ -78,9 +93,9 @@ namespace Subsurface
}
Damage = ToolBox.GetAttributeFloat(element, "damage", 0.0f);
StructureDamage = ToolBox.GetAttributeFloat(element, "structuredamage", 0.0f);
BleedingDamage = ToolBox.GetAttributeFloat(element, "bleedingdamage", 0.0f);
damage = ToolBox.GetAttributeFloat(element, "damage", 0.0f);
structureDamage = ToolBox.GetAttributeFloat(element, "structuredamage", 0.0f);
bleedingDamage = ToolBox.GetAttributeFloat(element, "bleedingdamage", 0.0f);
Stun = ToolBox.GetAttributeFloat(element, "stun", 0.0f);
@@ -110,28 +125,25 @@ namespace Subsurface
if (target as Character == null)
{
damageAmount = StructureDamage;
damageAmount = structureDamage;
}
else
{
damageAmount = Damage;
damageAmount = damage;
}
if (Duration > 0.0f) damageAmount *= deltaTime;
float bleedingAmount = (Duration == 0.0f) ? BleedingDamage : BleedingDamage * deltaTime;
if (particleEmitterPrefab != null)
{
particleEmitterPrefab.Emit(position);
}
if (sound!=null)
if (sound != null)
{
sound.Play(1.0f, 500.0f, position);
}
return target.AddDamage(attacker, position, this, playSound);
return target.AddDamage(attacker, position, this, deltaTime, playSound);
}
}

View File

@@ -844,9 +844,9 @@ namespace Subsurface
}
}
public virtual AttackResult AddDamage(IDamageable attacker, Vector2 simPosition, Attack attack, bool playSound = false)
public virtual AttackResult AddDamage(IDamageable attacker, Vector2 simPosition, Attack attack, float deltaTime, bool playSound = false)
{
return AddDamage(simPosition, attack.DamageType, attack.Damage, attack.BleedingDamage, attack.Stun, playSound);
return AddDamage(simPosition, attack.DamageType, attack.GetDamage(deltaTime), attack.GetBleedingDamage(deltaTime), attack.Stun, playSound);
}
public AttackResult AddDamage(Vector2 simPosition, DamageType damageType, float amount, float bleedingAmount, float stun, bool playSound)
@@ -855,7 +855,6 @@ namespace Subsurface
if (controlled == this) CharacterHUD.TakeDamage();
Limb closestLimb = null;
float closestDistance = 0.0f;
foreach (Limb limb in AnimController.Limbs)

View File

@@ -629,12 +629,14 @@ namespace Subsurface
{
if (inWater)
{
foreach (Limb limb in Limbs)
{
if (limb.body.TargetPosition == Vector2.Zero) continue;
//foreach (Limb limb in Limbs)
//{
// if (limb.body.TargetPosition == Vector2.Zero) continue;
limb.body.SetTransform(limb.SimPosition + newMovement * 0.1f, limb.Rotation);
}
// limb.body.SetTransform(limb.SimPosition + newMovement * 0.1f, limb.Rotation);
//}
correctionMovement = Vector2.Normalize(newMovement) * Math.Min(0.1f + dist, 3.0f);
}
else
{

View File

@@ -153,6 +153,7 @@ namespace Subsurface
if (items[i].Combine(item))
{
//PutItem(items[i], i, false, false);
new Networking.NetworkEvent(Networking.NetworkEventType.InventoryUpdate, items[i].ID, true);
combined = true;
}
@@ -186,7 +187,6 @@ namespace Subsurface
{
return false;
}
}
else
{
@@ -276,6 +276,8 @@ namespace Subsurface
else
{
DropItem(draggingItem);
new Networking.NetworkEvent(Subsurface.Networking.NetworkEventType.DropItem, draggingItem.ID, true);
//draggingItem = null;
}
}

View File

@@ -52,8 +52,9 @@ namespace Subsurface.Items.Components
get { return rechargeSpeed; }
set
{
if (float.IsNaN(value)) return;
if (float.IsNaN(value)) return;
rechargeSpeed = MathHelper.Clamp(value, 0.0f, maxRechargeSpeed);
rechargeSpeed = MathUtils.Round(rechargeSpeed, Math.Max(maxRechargeSpeed * 0.1f, 1.0f));
}
}
@@ -194,38 +195,38 @@ namespace Subsurface.Items.Components
new Vector2(x + 30, y + 30), Color.White);
spriteBatch.DrawString(GUI.Font, "Recharge rate: " + (rechargeSpeed / maxRechargeSpeed), new Vector2(x + 30, y + 100), Color.White);
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 50, y + 150, 40, 40), "+", true))
{
rechargeSpeed = Math.Min(rechargeSpeed + 10.0f, maxRechargeSpeed);
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 50, y + 150, 40, 40), "+"))
{
rechargeSpeed = Math.Min(rechargeSpeed + maxRechargeSpeed*0.1f, maxRechargeSpeed);
item.NewComponentEvent(this, true);
}
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 250, y + 150, 40, 40), "-", true))
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 250, y + 150, 40, 40), "-"))
{
rechargeSpeed = Math.Max(rechargeSpeed - 10.0f, 0.0f);
rechargeSpeed = Math.Max(rechargeSpeed - maxRechargeSpeed * 0.1f, 0.0f);
item.NewComponentEvent(this, true);
}
}
public override void FillNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetOutgoingMessage message)
{
message.Write(rechargeSpeed);
message.Write((byte)((int)(rechargeSpeed/maxRechargeSpeed*255.0f)));
message.Write(charge);
}
public override void ReadNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetIncomingMessage message)
{
float newRechargeSpeed = 0.0f;
byte newRechargeSpeed = 0;
float newCharge = 0.0f;
try
{
newRechargeSpeed = message.ReadFloat();
newRechargeSpeed = message.ReadByte();
newCharge = message.ReadFloat();
}
catch { }
RechargeSpeed = newRechargeSpeed;
RechargeSpeed = (newRechargeSpeed/255.0f)*maxRechargeSpeed;
Charge = newCharge;
}

View File

@@ -116,12 +116,7 @@ namespace Subsurface
item.body.Enabled = false;
}
if (createNetworkEvent)
{
int[] data = { item.ID, i };
new NetworkEvent(NetworkEventType.InventoryUpdate, ID, true, data);
}
if (createNetworkEvent) new NetworkEvent(NetworkEventType.InventoryUpdate, ID, true);
}
public void RemoveItem(Item item)
@@ -273,49 +268,58 @@ namespace Subsurface
public override void FillNetworkData(NetworkEventType type, NetOutgoingMessage message, object data)
{
int[] dataArray = data as int[];
if (dataArray == null || dataArray.Length<2)
for (int i = 0; i<capacity; i++)
{
message.Write(-1);
return;
message.Write((items[i] == null) ? -1 : items[i].ID);
}
//item id
message.Write(dataArray[0]);
//index of the slot which the item was moved to
message.Write(dataArray[1]);
}
public override void ReadNetworkData(NetworkEventType type, NetIncomingMessage message)
{
int itemId=-1, slotIndex = -1;
int[] newItemIDs = new int[capacity];
try
{
itemId = message.ReadInt32();
slotIndex = message.ReadInt32();
for (int i = 0; i<capacity; i++)
{
newItemIDs[i] = message.ReadInt32();
}
}
catch
{
return;
}
if (itemId == -1) return;
Item item = FindEntityByID(itemId) as Item;
if (item == null) return;
System.Diagnostics.Debug.WriteLine("Inventory update: "+itemId+" - "+slotIndex);
if (slotIndex==-1)
for (int i = 0; i < capacity; i++)
{
if (item.inventory == this) item.Drop();
}
else
{
TryPutItem(item, slotIndex, false);
if (newItemIDs[i] == -1)
{
if (items[i] == null) continue;
items[i].Drop(null, false);
continue;
}
Item item = FindEntityByID(newItemIDs[i]) as Item;
if (item == null) continue;
TryPutItem(item, i, false);
}
//System.Diagnostics.Debug.WriteLine("Inventory update: "+itemId+" - "+slotIndex);
//if (slotIndex==-1)
//{
// if (item.inventory == this) item.Drop();
//}
//else
//{
// TryPutItem(item, slotIndex, false);
//}
}
}
}

View File

@@ -459,11 +459,12 @@ namespace Subsurface
}
public AttackResult AddDamage(IDamageable attacker, Vector2 position, Attack attack, bool playSound = true)
public AttackResult AddDamage(IDamageable attacker, Vector2 position, Attack attack, float deltaTime, bool playSound = true)
{
Condition -= attack.Damage;
float damageAmount = attack.GetDamage(deltaTime);
Condition -= damageAmount;
return new AttackResult(attack.Damage, 0.0f, false);
return new AttackResult(damageAmount, 0.0f, false);
}
@@ -921,8 +922,8 @@ namespace Subsurface
public void Drop(Character dropper = null, bool createNetworkEvent = true)
{
if (dropper == Character.Controlled)
new NetworkEvent(NetworkEventType.DropItem, ID, true);
//if (dropper == Character.Controlled)
// new NetworkEvent(NetworkEventType.DropItem, ID, true);
foreach (ItemComponent ic in components) ic.Drop(dropper);

View File

@@ -68,7 +68,7 @@ namespace Subsurface
float cameraDist = Vector2.Distance(GameMain.GameScreen.Cam.Position, displayPosition)/2.0f;
GameMain.GameScreen.Cam.Shake = CameraShake * Math.Max((displayRange - cameraDist)/displayRange, 0.0f);
if (attack.StructureDamage > 0.0f)
if (attack.GetStructureDamage(1.0f) > 0.0f)
{
List<Structure> structureList = new List<Structure>();
@@ -91,11 +91,13 @@ namespace Subsurface
for (int i = 0; i < structure.SectionCount; i++)
{
float distFactor = 1.0f - (Vector2.Distance(structure.SectionPosition(i), displayPosition) / displayRange);
if (distFactor > 0.0f) structure.AddDamage(i, attack.StructureDamage*distFactor);
if (distFactor > 0.0f) structure.AddDamage(i, attack.GetStructureDamage(1.0f)*distFactor);
}
}
}
if (force == 0.0f && attack.Stun == 0.0f && attack.GetDamage(1.0f) == 0.0f) return;
foreach (Character c in Character.CharacterList)
{
float dist = Vector2.Distance(c.SimPosition, simPosition);
@@ -109,7 +111,7 @@ namespace Subsurface
distFactor = 1.0f - Vector2.Distance(limb.SimPosition, simPosition)/attack.Range;
c.AddDamage(limb.SimPosition, DamageType.None,
attack.Damage / c.AnimController.Limbs.Length * distFactor, 0.0f, attack.Stun * distFactor, true);
attack.GetDamage(1.0f) / c.AnimController.Limbs.Length * distFactor, 0.0f, attack.Stun * distFactor, true);
if (force>0.0f)
{
limb.body.ApplyLinearImpulse(Vector2.Normalize(limb.SimPosition - simPosition) * distFactor * force);

View File

@@ -10,6 +10,8 @@ namespace Subsurface
{
class Gap : MapEntity
{
public static List<Gap> GapList = new List<Gap>();
public bool isHorizontal;
//private Sound waterSound;
@@ -53,21 +55,8 @@ namespace Subsurface
}
public Gap(Rectangle newRect)
: this(newRect, (newRect.Width < newRect.Height))
{
rect = newRect;
linkedTo = new ObservableCollection<MapEntity>();
//waterSound = new Sound("waterstream", 0.0f);
flowForce = Vector2.Zero;
isHorizontal = (rect.Width < rect.Height);
open = 1.0f;
FindHulls();
mapEntityList.Add(this);
}
public Gap(Rectangle newRect, bool isHorizontal)
@@ -83,15 +72,15 @@ namespace Subsurface
FindHulls();
GapList.Add(this);
mapEntityList.Add(this);
}
public static void UpdateHulls()
{
foreach (MapEntity entity in mapEntityList)
foreach (Gap g in Gap.GapList)
{
Gap g = entity as Gap;
if (g != null) g.FindHulls();
g.FindHulls();
}
}
@@ -273,17 +262,19 @@ namespace Subsurface
Vector2 pos = Position;
if (isHorizontal)
{
pos.Y = MathHelper.Clamp(lowerSurface, rect.Y - rect.Height, rect.Y);
pos.X += Math.Sign(flowForce.X);
pos.Y = MathHelper.Clamp((higherSurface+lowerSurface)/2.0f, rect.Y - rect.Height, rect.Y);
Vector2 velocity = new Vector2(
MathHelper.Clamp(flowForce.X, -5000.0f, 5000.0f) * Rand.Range(0.5f, 0.7f),
flowForce.Y * Rand.Range(0.5f, 0.7f));
var particle = GameMain.ParticleManager.CreateParticle("watersplash",
new Vector2(pos.X, pos.Y - Rand.Range(0.0f, 10.0f)),
new Vector2(
MathHelper.Clamp(flowForce.X, -5000.0f, 5000.0f) * Rand.Range(0.5f, 0.7f),
flowForce.Y * Rand.Range(0.5f, 0.7f)));
new Vector2(pos.X, pos.Y - Rand.Range(0.0f, 10.0f)), velocity);
if (particle != null)
{
particle.Size = particle.Size * Math.Abs(flowForce.X / 1000.0f);
}
pos.Y = Rand.Range(lowerSurface, rect.Y - rect.Height);
@@ -296,8 +287,13 @@ namespace Subsurface
for (int i = 0; i < rect.Width; i += (int)Rand.Range(80, 100))
{
pos.X = Rand.Range(rect.X, rect.X + rect.Width);
Subsurface.Particles.Particle splash = GameMain.ParticleManager.CreateParticle("watersplash", pos,
new Vector2(0, Math.Max(flowForce.Y * Rand.Range(0.5f, 0.8f), 0.0f)));
Vector2 velocity = new Vector2(
flowForce.X * Rand.Range(0.5f, 0.7f),
Math.Max(flowForce.Y,-100.0f) * Rand.Range(0.5f, 0.7f));
var splash = GameMain.ParticleManager.CreateParticle("watersplash", pos,
velocity);
if (splash != null) splash.Size = splash.Size * MathHelper.Clamp(rect.Width / 50.0f, 0.8f, 4.0f);
@@ -327,7 +323,7 @@ namespace Subsurface
//horizontal gap (such as a regular door)
if (isHorizontal)
{
//higherSurface = Math.Min(hull1.Surface,hull2.Surface);
higherSurface = Math.Max(hull1.Surface,hull2.Surface);
float delta=0.0f;
//water level is above the lower boundary of the gap
if (Math.Max(hull1.Surface+hull1.WaveY[hull1.WaveY.Length - 1], hull2.Surface+hull2.WaveY[0]) > rect.Y - size)
@@ -453,6 +449,8 @@ namespace Subsurface
flowForce = new Vector2(0.0f,-delta);
flowForce.X = hull1.WaveY[hull1.GetWaveIndex(rect.X)] - hull1.WaveY[hull1.GetWaveIndex(rect.Right)] * 10.0f;
//if (water2.Volume < water2.FullVolume - Hull.MaxCompress)
//{
// int posX = (int)((rect.X + size / 2.0f - water1.Rect.X) / Hull.WaveWidth);
@@ -569,6 +567,8 @@ namespace Subsurface
{
base.Remove();
GapList.Remove(this);
if (soundIndex > -1) Sounds.SoundManager.Stop(soundIndex);
}

View File

@@ -48,6 +48,8 @@ namespace Subsurface
float[] leftDelta;
float[] rightDelta;
float lastSentVolume;
public override bool IsLinkable
{
get { return true; }
@@ -73,7 +75,8 @@ namespace Subsurface
{
get { return volume; }
set
{
{
if (!MathUtils.IsValid(value)) return;
volume = MathHelper.Clamp(value, 0.0f, FullVolume + MaxCompress);
if (volume < FullVolume) Pressure = rect.Y - rect.Height + volume / rect.Width;
if (volume > 0.0f) update = true;
@@ -155,8 +158,13 @@ namespace Subsurface
public int GetWaveIndex(Vector2 position)
{
int index = (int)(position.X - rect.X) / WaveWidth;
index = (int)MathHelper.Clamp(index, 0, waveY.Length-1);
return GetWaveIndex(position.X);
}
public int GetWaveIndex(float xPos)
{
int index = (int)(xPos - rect.X) / WaveWidth;
index = (int)MathHelper.Clamp(index, 0, waveY.Length - 1);
return index;
}
@@ -202,6 +210,12 @@ namespace Subsurface
}
}
//update client hulls if the amount of water has changed by >10%
if (Math.Abs(lastSentVolume-volume)>FullVolume*0.1f)
{
new Networking.NetworkEvent(ID, false);
lastSentVolume = volume;
}
if (!update) return;
@@ -254,9 +268,9 @@ namespace Subsurface
}
}
if (volume<FullVolume)
if (volume < FullVolume)
{
LethalPressure -= 0.5f;
LethalPressure -= 10.0f * deltaTime;
if (Volume == 0.0f)
{
for (int i = 1; i < waveY.Length - 1; i++)
@@ -268,7 +282,7 @@ namespace Subsurface
}
else
{
LethalPressure += 1.0f;
LethalPressure += 10.0f * deltaTime;
}
@@ -402,12 +416,17 @@ namespace Subsurface
//returns the water block which contains the point (or null if it isn't inside any)
public static Hull FindHull(Vector2 position, Hull guess = null)
{
if (guess != null && hullList.Contains(guess))
return FindHull(position, hullList, guess);
}
public static Hull FindHull(Vector2 position, List<Hull> hulls, Hull guess = null)
{
if (guess != null && hulls.Contains(guess))
{
if (Submarine.RectContains(guess.rect, position)) return guess;
}
foreach (Hull w in hullList)
foreach (Hull w in hulls)
{
if (Submarine.RectContains(w.rect, position)) return w;
}
@@ -445,6 +464,28 @@ namespace Subsurface
h.ID = int.Parse(element.Attribute("ID").Value);
}
public override void FillNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetOutgoingMessage message, object data)
{
message.Write(volume);
}
public override void ReadNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetIncomingMessage message)
{
float newVolume = this.volume;
try
{
newVolume = message.ReadFloat();
}
catch
{
return;
}
Volume = newVolume;
}
}

View File

@@ -19,6 +19,6 @@ namespace Subsurface
get;
}
AttackResult AddDamage(IDamageable attacker, Vector2 position, Attack attack, bool playSound=true);
AttackResult AddDamage(IDamageable attacker, Vector2 position, Attack attack, float deltaTime, bool playSound=true);
}
}

View File

@@ -417,7 +417,7 @@ int currentTargetIndex = 1;
}
if (allowedEdges.Count==0)
{
edgeIndex = 0;
edgeIndex = rand.Next() % currentCell.edges.Count;
}
else
{

View File

@@ -21,6 +21,10 @@ namespace Subsurface
public float damage;
public Gap gap;
public float lastSentDamage;
public float lastUpdate;
public bool isHighLighted;
public WallSection(Rectangle rect)
@@ -412,7 +416,7 @@ namespace Subsurface
sections[sectionIndex].rect.Y - sections[sectionIndex].rect.Height / 2.0f);
}
public AttackResult AddDamage(IDamageable attacker, Vector2 position, Attack attack, bool playSound = false)
public AttackResult AddDamage(IDamageable attacker, Vector2 position, Attack attack, float deltaTime, bool playSound = false)
{
if (!prefab.HasBody || prefab.IsPlatform) return new AttackResult(0.0f, 0.0f);
@@ -421,23 +425,29 @@ namespace Subsurface
GameMain.ParticleManager.CreateParticle("dustcloud", SectionPosition(i), 0.0f, 0.0f);
float damageAmount = attack.GetStructureDamage(deltaTime);
if (playSound && !SectionHasHole(i))
{
DamageSoundType damageSoundType = (attack.DamageType == DamageType.Blunt) ? DamageSoundType.StructureBlunt : DamageSoundType.StructureSlash;
AmbientSoundManager.PlayDamageSound(damageSoundType, attack.Damage, position);
AmbientSoundManager.PlayDamageSound(damageSoundType, damageAmount, position);
}
AddDamage(i, attack.Damage);
AddDamage(i, damageAmount);
return new AttackResult(attack.Damage, 0.0f);
return new AttackResult(damageAmount, 0.0f);
}
private void SetDamage(int sectionIndex, float damage)
{
if (!prefab.HasBody) return;
if (damage != sections[sectionIndex].damage)
if (damage != sections[sectionIndex].damage && Math.Abs(sections[sectionIndex].lastSentDamage - damage)>5.0f)
{
new NetworkEvent(NetworkEventType.UpdateEntity, ID, false, sectionIndex);
sections[sectionIndex].lastSentDamage = damage;
}
if (damage < prefab.MaxHealth*0.5f)
{
@@ -637,6 +647,7 @@ namespace Subsurface
return;
}
message.Write((float)NetTime.Now);
message.Write(byteIndex);
message.Write(sections[sectionIndex].damage);
}
@@ -645,9 +656,11 @@ namespace Subsurface
{
int sectionIndex = 0;
float damage = 0.0f;
float updateTime = 0.0f;
try
{
updateTime = message.ReadFloat();
sectionIndex = message.ReadByte();
damage = message.ReadFloat();
}
@@ -656,6 +669,9 @@ namespace Subsurface
return;
}
if (sections[sectionIndex].lastUpdate != 0.0f && updateTime < sections[sectionIndex].lastUpdate) return;
sections[sectionIndex].lastUpdate = updateTime;
SetDamage(sectionIndex, damage);
}

View File

@@ -1,6 +1,8 @@
using FarseerPhysics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
namespace Subsurface.Particles
{
@@ -34,6 +36,8 @@ namespace Subsurface.Particles
//private float checkCollisionTimer;
private Hull currentHull;
private List<Hull> hullLimits;
public ParticlePrefab.DrawTargetType DrawTarget
{
@@ -80,9 +84,11 @@ namespace Subsurface.Particles
velocityChange = prefab.VelocityChange;
if (prefab.DeleteOnCollision)
if (prefab.DeleteOnCollision || prefab.CollidesWithWalls)
{
currentHull = Hull.FindHull(position);
//currentHull = Hull.FindHull(position);
hullLimits = new List<Hull>();
hullLimits = FindLimits(position);
}
if (prefab.RotateToDirection)
@@ -93,6 +99,45 @@ namespace Subsurface.Particles
}
}
private List<Hull> FindLimits(Vector2 position)
{
List<Hull> hullList = new List<Hull>();
currentHull = Hull.FindHull(position);
if (currentHull == null) return hullList;
hullList.Add(currentHull);
return FindAdjacentHulls(hullList, currentHull, Math.Abs(velocity.X)>Math.Abs(velocity.Y));
}
private List<Hull> FindAdjacentHulls(List<Hull> adjacentHulls, Hull currentHull, bool isHorizontal)
{
foreach (Gap gap in Gap.GapList)
{
if (gap.isHorizontal != isHorizontal) continue;
if (gap.Open < 0.01f) continue;
if (gap.linkedTo[0]==currentHull && gap.linkedTo[1]!=null)
{
if (!adjacentHulls.Contains(gap.linkedTo[1] as Hull))
{
adjacentHulls.Add(gap.linkedTo[1] as Hull);
FindAdjacentHulls(adjacentHulls, gap.linkedTo[1] as Hull, isHorizontal);
}
}
else if (gap.linkedTo[1] == currentHull && gap.linkedTo[0] != null)
{
if (!adjacentHulls.Contains(gap.linkedTo[0] as Hull))
{
adjacentHulls.Add(gap.linkedTo[0] as Hull);
FindAdjacentHulls(adjacentHulls, gap.linkedTo[0] as Hull, isHorizontal);
}
}
}
return adjacentHulls;
}
public bool Update(float deltaTime)
{
//over 3 times faster than position += velocity * deltatime
@@ -124,9 +169,34 @@ namespace Subsurface.Particles
color.G / 255.0f + prefab.ColorChange.Y * deltaTime,
color.B / 255.0f + prefab.ColorChange.Z * deltaTime);
if (prefab.DeleteOnCollision && currentHull!=null)
if ((prefab.DeleteOnCollision || prefab.CollidesWithWalls) && currentHull!=null)
{
if (!Submarine.RectContains(currentHull.Rect, position)) return false;
bool insideHull = false;
foreach (Hull hull in hullLimits)
{
if (!Submarine.RectContains(hull.Rect, position)) continue;
insideHull = true;
break;
}
if (!insideHull)
{
if (prefab.DeleteOnCollision) return false;
Hull prevHull = Hull.FindHull(prevPosition, hullLimits, currentHull);
if (prevHull == null) return false;
OnWallCollision(prevHull);
}
//if (position.Y < currentHull.Rect.Y-currentHull.Rect.Height)
//{
// position.Y = currentHull.Rect.Y - currentHull.Rect.Height;
// velocity.Y *= -0.2f;
//}
//if (!Submarine.RectContains(currentHull.Rect, position)) return false;
}
lifeTime -= deltaTime;
@@ -135,6 +205,35 @@ namespace Subsurface.Particles
return true;
}
private void OnWallCollision(Hull prevHull)
{
float restitution = 0.05f;
if (position.Y < prevHull.Rect.Y - prevHull.Rect.Height)
{
position.Y = prevHull.Rect.Y - prevHull.Rect.Height + 1.0f;
velocity.Y = -velocity.Y;
}
else if (position.Y > prevHull.Rect.Y)
{
position.Y = prevHull.Rect.Y - 1.0f;
velocity.Y = -velocity.Y;
}
if (position.X < prevHull.Rect.X)
{
position.X = prevHull.Rect.X + 1.0f;
velocity.X = -velocity.X;
}
else if (position.X > prevHull.Rect.X + prevHull.Rect.Width)
{
position.X = prevHull.Rect.X + prevHull.Rect.Width - 1.0f;
velocity.X = -velocity.X;
}
velocity *= restitution;
}
public void Draw(SpriteBatch spriteBatch)
{

View File

@@ -29,6 +29,7 @@ namespace Subsurface.Particles
public readonly float GrowTime;
public readonly bool DeleteOnCollision;
public readonly bool CollidesWithWalls;
public readonly Vector2 VelocityChange;
@@ -100,6 +101,7 @@ namespace Subsurface.Particles
StartAlpha = ToolBox.GetAttributeFloat(element, "startalpha", 1.0f);
DeleteOnCollision = ToolBox.GetAttributeBool(element, "deleteoncollision", false);
CollidesWithWalls = ToolBox.GetAttributeBool(element, "collideswithwalls", false);
ColorChange = ToolBox.GetAttributeVector4(element, "colorchange", Vector4.Zero);

View File

@@ -747,7 +747,7 @@ namespace Subsurface
return;
}
//if (!string.IsNullOrWhiteSpace(mapName)) TrySelectMap(mapName, md5Hash);
if (!string.IsNullOrWhiteSpace(mapName)) TrySelectMap(mapName, md5Hash);
modeList.Select(modeIndex);

Binary file not shown.