From 330b24bcf62f78385410112410c438b0532a4f08 Mon Sep 17 00:00:00 2001 From: juanjp600 Date: Sun, 25 Jun 2017 22:09:41 -0300 Subject: [PATCH] Some more cleanup + event desync debug messages --- BarotraumaClient/BarotraumaClient.csproj | 2 + .../Source/Characters/AI/HumanAIController.cs | 15 ++ .../Source/Characters/AICharacter.cs | 26 +++ .../Source/Characters/Animation/Ragdoll.cs | 52 +++++ BarotraumaClient/Source/Characters/Attack.cs | 50 ++++ .../Source/Characters/Character.cs | 214 ++++++++++++++++-- .../Source/Characters/HuskInfection.cs | 36 +++ BarotraumaClient/Source/Characters/Limb.cs | 31 ++- .../Source/Characters/Character.cs | 2 +- .../Source/Characters/AI/HumanAIController.cs | 15 +- .../Source/Characters/AICharacter.cs | 26 +-- .../Source/Characters/Animation/Ragdoll.cs | 56 ++--- BarotraumaShared/Source/Characters/Attack.cs | 50 +--- .../Source/Characters/Character.cs | 193 ++-------------- .../Source/Characters/HuskInfection.cs | 27 +-- BarotraumaShared/Source/Characters/Limb.cs | 23 +- .../ServerEntityEventManager.cs | 17 +- 17 files changed, 477 insertions(+), 358 deletions(-) create mode 100644 BarotraumaClient/Source/Characters/Attack.cs create mode 100644 BarotraumaClient/Source/Characters/HuskInfection.cs diff --git a/BarotraumaClient/BarotraumaClient.csproj b/BarotraumaClient/BarotraumaClient.csproj index e7ab3ca74..5986851b1 100644 --- a/BarotraumaClient/BarotraumaClient.csproj +++ b/BarotraumaClient/BarotraumaClient.csproj @@ -69,6 +69,7 @@ + @@ -80,6 +81,7 @@ + diff --git a/BarotraumaClient/Source/Characters/AI/HumanAIController.cs b/BarotraumaClient/Source/Characters/AI/HumanAIController.cs index 4daacaff6..0e9e56964 100644 --- a/BarotraumaClient/Source/Characters/AI/HumanAIController.cs +++ b/BarotraumaClient/Source/Characters/AI/HumanAIController.cs @@ -5,6 +5,21 @@ namespace Barotrauma { partial class HumanAIController : AIController { + partial void InitProjSpecific() + { + if (GameMain.GameSession != null && GameMain.GameSession.CrewManager != null) + { + CurrentOrder = Order.PrefabList.Find(o => o.Name.ToLowerInvariant() == "dismissed"); + objectiveManager.SetOrder(CurrentOrder, ""); + GameMain.GameSession.CrewManager.SetCharacterOrder(Character, CurrentOrder); + } + } + + partial void SetOrderProjSpecific(Order order) + { + GameMain.GameSession.CrewManager.SetCharacterOrder(Character, order); + } + public override void DebugDraw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch) { if (selectedAiTarget != null) diff --git a/BarotraumaClient/Source/Characters/AICharacter.cs b/BarotraumaClient/Source/Characters/AICharacter.cs index 9758b9833..65574e299 100644 --- a/BarotraumaClient/Source/Characters/AICharacter.cs +++ b/BarotraumaClient/Source/Characters/AICharacter.cs @@ -5,6 +5,32 @@ namespace Barotrauma { partial class AICharacter : Character { + partial void InitProjSpecific() + { + soundTimer = Rand.Range(0.0f, soundInterval); + } + + partial void SoundUpdate(float deltaTime) + { + if (soundTimer > 0) + { + soundTimer -= deltaTime; + } + else + { + switch (aiController.State) + { + case AIController.AiState.Attack: + PlaySound(CharacterSound.SoundType.Attack); + break; + default: + PlaySound(CharacterSound.SoundType.Idle); + break; + } + soundTimer = soundInterval; + } + } + public override void DrawFront(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch, Camera cam) { base.DrawFront(spriteBatch, cam); diff --git a/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs b/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs index a5e45a18f..a9af76732 100644 --- a/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs +++ b/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs @@ -13,6 +13,58 @@ namespace Barotrauma { partial class Ragdoll { + partial void ImpactProjSpecific(float impact, Body body) + { + float volume = Math.Min(impact - 3.0f, 1.0f); + + if (body.UserData is Limb) + { + Limb limb = (Limb)body.UserData; + + if (impact > 3.0f && limb.HitSound != null && limb.soundTimer <= 0.0f) + { + limb.soundTimer = Limb.SoundInterval; + limb.HitSound.Play(volume, impact * 100.0f, limb.WorldPosition); + } + } + else if (body == Collider.FarseerBody) + { + if (!character.IsRemotePlayer || GameMain.Server != null) + { + if (impact > ImpactTolerance) + { + SoundPlayer.PlayDamageSound(DamageSoundType.LimbBlunt, strongestImpact, Collider); + } + } + + if (Character.Controlled == character) GameMain.GameScreen.Cam.Shake = strongestImpact; + } + } + + partial void Splash(Limb limb, Hull limbHull) + { + //create a splash particle + GameMain.ParticleManager.CreateParticle("watersplash", + new Vector2(limb.Position.X, limbHull.Surface) + limbHull.Submarine.Position, + new Vector2(0.0f, Math.Abs(-limb.LinearVelocity.Y * 20.0f)), + 0.0f, limbHull); + + GameMain.ParticleManager.CreateParticle("bubbles", + new Vector2(limb.Position.X, limbHull.Surface) + limbHull.Submarine.Position, + limb.LinearVelocity * 0.001f, + 0.0f, limbHull); + + //if the Character dropped into water, create a wave + if (limb.LinearVelocity.Y < 0.0f) + { + if (splashSoundTimer <= 0.0f) + { + SoundPlayer.PlaySplashSound(limb.WorldPosition, Math.Abs(limb.LinearVelocity.Y) + Rand.Range(-5.0f, 0.0f)); + splashSoundTimer = 0.5f; + } + } + } + public virtual void Draw(SpriteBatch spriteBatch) { if (simplePhysicsEnabled) return; diff --git a/BarotraumaClient/Source/Characters/Attack.cs b/BarotraumaClient/Source/Characters/Attack.cs new file mode 100644 index 000000000..033bbab9c --- /dev/null +++ b/BarotraumaClient/Source/Characters/Attack.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml.Linq; +using Microsoft.Xna.Framework; +using Barotrauma.Particles; + +namespace Barotrauma +{ + partial class Attack + { + private Sound sound; + + private ParticleEmitterPrefab particleEmitterPrefab; + + partial void InitProjSpecific(XElement element) + { + string soundPath = ToolBox.GetAttributeString(element, "sound", ""); + if (!string.IsNullOrWhiteSpace(soundPath)) + { + sound = Sound.Load(soundPath); + } + + foreach (XElement subElement in element.Elements()) + { + switch (subElement.Name.ToString().ToLowerInvariant()) + { + case "particleemitter": + particleEmitterPrefab = new ParticleEmitterPrefab(subElement); + break; + } + + } + } + + partial void DamageParticles(Vector2 worldPosition) + { + if (particleEmitterPrefab != null) + { + particleEmitterPrefab.Emit(worldPosition); + } + + if (sound != null) + { + sound.Play(1.0f, 500.0f, worldPosition); + } + } + } +} diff --git a/BarotraumaClient/Source/Characters/Character.cs b/BarotraumaClient/Source/Characters/Character.cs index f2b9e99e0..02435ed85 100644 --- a/BarotraumaClient/Source/Characters/Character.cs +++ b/BarotraumaClient/Source/Characters/Character.cs @@ -45,8 +45,10 @@ namespace Barotrauma get { return hudProgressBars; } } - private void InitProjSpecific(XDocument doc) + partial void InitProjSpecific(XDocument doc) { + soundInterval = ToolBox.GetAttributeFloat(doc.Root, "soundinterval", 10.0f); + keys = new Key[Enum.GetNames(typeof(InputType)).Length]; for (int i = 0; i < Enum.GetNames(typeof(InputType)).Length; i++) @@ -65,6 +67,195 @@ namespace Barotrauma hudProgressBars = new Dictionary(); } + + /// + /// Control the Character according to player input + /// + public void ControlLocalPlayer(float deltaTime, Camera cam, bool moveCam = true) + { + if (!DisableControls) + { + for (int i = 0; i < keys.Length; i++) + { + keys[i].SetState(); + } + } + else + { + foreach (Key key in keys) + { + if (key == null) continue; + key.Reset(); + } + } + + if (moveCam && needsAir) + { + if (pressureProtection < 80.0f && + (AnimController.CurrentHull == null || AnimController.CurrentHull.LethalPressure > 50.0f)) + { + float pressure = AnimController.CurrentHull == null ? 100.0f : AnimController.CurrentHull.LethalPressure; + + cam.Zoom = MathHelper.Lerp(cam.Zoom, + (pressure / 50.0f) * Rand.Range(1.0f, 1.05f), + (pressure - 50.0f) / 50.0f); + } + cam.OffsetAmount = MathHelper.Lerp(cam.OffsetAmount, 250.0f, 0.05f); + } + + cursorPosition = cam.ScreenToWorld(PlayerInput.MousePosition); + if (AnimController.CurrentHull != null && AnimController.CurrentHull.Submarine != null) + { + cursorPosition -= AnimController.CurrentHull.Submarine.Position; + } + + Vector2 mouseSimPos = ConvertUnits.ToSimUnits(cursorPosition); + + if (Lights.LightManager.ViewTarget == this && Vector2.DistanceSquared(AnimController.Limbs[0].SimPosition, mouseSimPos) > 1.0f) + { + 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 (!LockHands) + { + //find the closest item if selectkey has been hit, or if the Character is being + //controlled by the player (in order to highlight it) + + if (findClosestTimer <= 0.0f || Screen.Selected == GameMain.EditMapScreen) + { + closestCharacter = FindClosestCharacter(mouseSimPos); + if (closestCharacter != null && closestCharacter.info == null) + { + closestCharacter = null; + } + + float closestItemDist = 0.0f; + closestItem = FindClosestItem(mouseSimPos, out closestItemDist); + + if (closestCharacter != null && closestItem != null) + { + if (Vector2.DistanceSquared(closestCharacter.SimPosition, mouseSimPos) < ConvertUnits.ToSimUnits(closestItemDist) * ConvertUnits.ToSimUnits(closestItemDist)) + { + if (selectedConstruction != closestItem) closestItem = null; + } + else + { + closestCharacter = null; + } + } + + findClosestTimer = 0.1f; + } + else + { + findClosestTimer -= deltaTime; + } + + if (selectedCharacter == null && closestItem != null) + { + closestItem.IsHighlighted = true; + if (!LockHands && closestItem.Pick(this)) + { + + } + } + + if (IsKeyHit(InputType.Select)) + { + if (selectedCharacter != null) + { + DeselectCharacter(); + } + else if (closestCharacter != null && closestCharacter.IsHumanoid && closestCharacter.CanBeSelected) + { + SelectCharacter(closestCharacter); + } + } + } + else + { + if (selectedCharacter != null) DeselectCharacter(); + selectedConstruction = null; + closestItem = null; + closestCharacter = null; + } + + DisableControls = false; + } + + partial void UpdateControlled(float deltaTime,Camera cam) + { + if (controlled == this) + { + ControlLocalPlayer(deltaTime, cam); + } + + Lights.LightManager.ViewTarget = this; + CharacterHUD.Update(deltaTime, this); + + foreach (HUDProgressBar progressBar in hudProgressBars.Values) + { + progressBar.Update(deltaTime); + } + + foreach (var pb in hudProgressBars.Where(pb => pb.Value.FadeTimer <= 0.0f).ToList()) + { + hudProgressBars.Remove(pb.Key); + } + } + + partial void DamageHUD(float amount) + { + if (controlled == this) CharacterHUD.TakeDamage(amount); + } + + partial void UpdateOxygenProjSpecific(float prevOxygen) + { + if (prevOxygen > 0.0f && Oxygen <= 0.0f && controlled == this) + { + SoundPlayer.PlaySound("drown"); + } + } + + partial void KillProjSpecific() + { + if (GameMain.NetworkMember != null && Character.controlled == this) + { + string chatMessage = InfoTextManager.GetInfoText("Self_CauseOfDeath." + causeOfDeath.ToString()); + if (GameMain.Client != null) chatMessage += " Your chat messages will only be visible to other dead players."; + + GameMain.NetworkMember.AddChatMessage(chatMessage, ChatMessageType.Dead); + GameMain.LightManager.LosEnabled = false; + controlled = null; + } + + PlaySound(CharacterSound.SoundType.Die); + } + + partial void DisposeProjSpecific() + { + if (controlled == this) controlled = null; + + if (GameMain.GameSession?.CrewManager != null && + GameMain.GameSession.CrewManager.characters.Contains(this)) + { + GameMain.GameSession.CrewManager.characters.Remove(this); + } + + if (GameMain.Client != null && GameMain.Client.Character == this) GameMain.Client.Character = null; + + if (Lights.LightManager.ViewTarget == this) Lights.LightManager.ViewTarget = null; + } + public static void AddAllToGUIUpdateList() { for (int i = 0; i < CharacterList.Count; i++) @@ -80,26 +271,7 @@ namespace Barotrauma CharacterHUD.AddToGUIUpdateList(this); } } - - partial void UpdateControlled(float deltaTime) - { - if (controlled == this) - { - Lights.LightManager.ViewTarget = this; - CharacterHUD.Update(deltaTime, this); - - foreach (HUDProgressBar progressBar in hudProgressBars.Values) - { - progressBar.Update(deltaTime); - } - - foreach (var pb in hudProgressBars.Where(pb => pb.Value.FadeTimer <= 0.0f).ToList()) - { - hudProgressBars.Remove(pb.Key); - } - } - } - + public void Draw(SpriteBatch spriteBatch) { if (!Enabled) return; diff --git a/BarotraumaClient/Source/Characters/HuskInfection.cs b/BarotraumaClient/Source/Characters/HuskInfection.cs new file mode 100644 index 000000000..72350aebb --- /dev/null +++ b/BarotraumaClient/Source/Characters/HuskInfection.cs @@ -0,0 +1,36 @@ +using Microsoft.Xna.Framework; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace Barotrauma +{ + partial class HuskInfection + { + partial void UpdateProjSpecific(float prevTimer, Character character) + { + if (IncubationTimer < 0.5f) + { + if (prevTimer % 0.1f > 0.05f && IncubationTimer % 0.1f < 0.05f) + { + GUI.AddMessage(InfoTextManager.GetInfoText("HuskDormant"), Color.Red, 4.0f); + } + } + else if (IncubationTimer < 1.0f) + { + if (state == InfectionState.Dormant && Character.Controlled == character) + { + new GUIMessageBox("", InfoTextManager.GetInfoText("HuskCantSpeak")); + } + } + else + { + if (Character.Controlled == character) new GUIMessageBox("", InfoTextManager.GetInfoText("HuskActivate")); + } + } + } +} diff --git a/BarotraumaClient/Source/Characters/Limb.cs b/BarotraumaClient/Source/Characters/Limb.cs index c8b86b7bd..5fb3bd09a 100644 --- a/BarotraumaClient/Source/Characters/Limb.cs +++ b/BarotraumaClient/Source/Characters/Limb.cs @@ -15,7 +15,11 @@ namespace Barotrauma { partial class Limb { - public readonly LightSource LightSource; + public LightSource LightSource + { + get; + private set; + } Sound hitSound; @@ -24,6 +28,31 @@ namespace Barotrauma get { return hitSound; } } + partial void InitProjSpecific(XElement element) + { + foreach (XElement subElement in element.Elements()) + { + switch (subElement.Name.ToString().ToLowerInvariant()) + { + case "lightsource": + LightSource = new LightSource(subElement); + break; + case "sound": + hitSound = Sound.Load(ToolBox.GetAttributeString(subElement, "file", "")); + break; + } + } + } + + partial void UpdateProjSpecific() + { + if (LightSource != null) + { + LightSource.Rotation = dir == Direction.Right ? body.DrawRotation : body.DrawRotation - MathHelper.Pi; + LightSource.ParentSub = body.Submarine; + } + } + public void Draw(SpriteBatch spriteBatch) { float brightness = 1.0f - (burnt / 100.0f) * 0.5f; diff --git a/BarotraumaServer/Source/Characters/Character.cs b/BarotraumaServer/Source/Characters/Character.cs index 57ee761ee..58d517c7d 100644 --- a/BarotraumaServer/Source/Characters/Character.cs +++ b/BarotraumaServer/Source/Characters/Character.cs @@ -24,7 +24,7 @@ namespace Barotrauma } } - private void InitProjSpecific(XDocument doc) + partial void InitProjSpecific(XDocument doc) { keys = null; } diff --git a/BarotraumaShared/Source/Characters/AI/HumanAIController.cs b/BarotraumaShared/Source/Characters/AI/HumanAIController.cs index aca4b0f93..416e96c99 100644 --- a/BarotraumaShared/Source/Characters/AI/HumanAIController.cs +++ b/BarotraumaShared/Source/Characters/AI/HumanAIController.cs @@ -37,15 +37,9 @@ namespace Barotrauma updateObjectiveTimer = Rand.Range(0.0f, UpdateObjectiveInterval); -#if CLIENT - if (GameMain.GameSession!=null && GameMain.GameSession.CrewManager!=null) - { - CurrentOrder = Order.PrefabList.Find(o => o.Name.ToLowerInvariant() == "dismissed"); - objectiveManager.SetOrder(CurrentOrder, ""); - GameMain.GameSession.CrewManager.SetCharacterOrder(Character, CurrentOrder); - } -#endif + InitProjSpecific(); } + partial void InitProjSpecific(); public override void Update(float deltaTime) { @@ -154,10 +148,9 @@ namespace Barotrauma CurrentOrder = order; objectiveManager.SetOrder(order, option); -#if CLIENT - GameMain.GameSession.CrewManager.SetCharacterOrder(Character, order); -#endif + SetOrderProjSpecific(order); } + partial void SetOrderProjSpecific(Order order); public override void SelectTarget(AITarget target) { diff --git a/BarotraumaShared/Source/Characters/AICharacter.cs b/BarotraumaShared/Source/Characters/AICharacter.cs index a37196b79..c43a0c70f 100644 --- a/BarotraumaShared/Source/Characters/AICharacter.cs +++ b/BarotraumaShared/Source/Characters/AICharacter.cs @@ -15,10 +15,9 @@ namespace Barotrauma public AICharacter(string file, Vector2 position, CharacterInfo characterInfo = null, bool isNetworkPlayer = false) : base(file, position, characterInfo, isNetworkPlayer) { -#if CLIENT - soundTimer = Rand.Range(0.0f, soundInterval); -#endif + } + partial void InitProjSpecific(); public void SetAI(AIController aiController) { @@ -45,28 +44,11 @@ namespace Barotrauma if (Controlled == this || !aiController.Enabled) return; -#if CLIENT - if (soundTimer > 0) - { - soundTimer -= deltaTime; - } - else - { - switch (aiController.State) - { - case AIController.AiState.Attack: - PlaySound(CharacterSound.SoundType.Attack); - break; - default: - PlaySound(CharacterSound.SoundType.Idle); - break; - } - soundTimer = soundInterval; - } -#endif + SoundUpdate(deltaTime); aiController.Update(deltaTime); } + partial void SoundUpdate(float deltaTime); public override void AddDamage(CauseOfDeath causeOfDeath, float amount, IDamageable attacker) { diff --git a/BarotraumaShared/Source/Characters/Animation/Ragdoll.cs b/BarotraumaShared/Source/Characters/Animation/Ragdoll.cs index 73a508b8d..8ebea7f3c 100644 --- a/BarotraumaShared/Source/Characters/Animation/Ragdoll.cs +++ b/BarotraumaShared/Source/Characters/Animation/Ragdoll.cs @@ -163,6 +163,11 @@ namespace Barotrauma foreach (Limb limb in Limbs) { + if (limb.body == null) + { + DebugConsole.ThrowError("Limb has no body! (" + (character != null ? character.Name : "Unknown character") + ", " + limb.type.ToString()); + continue; + } limb.body.Enabled = !simplePhysicsEnabled; } @@ -503,19 +508,12 @@ namespace Barotrauma if (character.Submarine == null && f2.Body.UserData is Submarine) velocity -= ((Submarine)f2.Body.UserData).Velocity; float impact = Vector2.Dot(velocity, -normal); - - float volume = Math.Min(impact-3.0f, 1.0f); + + ImpactProjSpecific(impact,f1.Body); + if (f1.Body.UserData is Limb) { - Limb limb = (Limb)f1.Body.UserData; -#if CLIENT - if (impact > 3.0f && limb.HitSound != null && limb.soundTimer <= 0.0f) - { - limb.soundTimer = Limb.SoundInterval; - limb.HitSound.Play(volume, impact * 100.0f, limb.WorldPosition); - } -#endif } else if (f1.Body == Collider.FarseerBody) { @@ -524,16 +522,13 @@ namespace Barotrauma if (impact > ImpactTolerance) { character.AddDamage(CauseOfDeath.Damage, impact - ImpactTolerance, null); -#if CLIENT - SoundPlayer.PlayDamageSound(DamageSoundType.LimbBlunt, strongestImpact, Collider); -#endif + strongestImpact = Math.Max(strongestImpact, impact - ImpactTolerance); } - } - - if (Character.Controlled == character) GameMain.GameScreen.Cam.Shake = strongestImpact; + } } } + partial void ImpactProjSpecific(float impact, Body body); public virtual void Flip() { @@ -829,30 +824,11 @@ namespace Barotrauma //the limb has gone through the surface of the water if (Math.Abs(limb.LinearVelocity.Y) > 5.0f && limb.inWater != prevInWater) { -#if CLIENT - //create a splash particle - GameMain.ParticleManager.CreateParticle("watersplash", - new Vector2(limb.Position.X, limbHull.Surface) + limbHull.Submarine.Position, - new Vector2(0.0f, Math.Abs(-limb.LinearVelocity.Y * 20.0f)), - 0.0f, limbHull); - - GameMain.ParticleManager.CreateParticle("bubbles", - new Vector2(limb.Position.X, limbHull.Surface) + limbHull.Submarine.Position, - limb.LinearVelocity * 0.001f, - 0.0f, limbHull); -#endif + Splash(limb, limbHull); //if the Character dropped into water, create a wave if (limb.LinearVelocity.Y < 0.0f) { - if (splashSoundTimer <= 0.0f) - { -#if CLIENT - SoundPlayer.PlaySplashSound(limb.WorldPosition, Math.Abs(limb.LinearVelocity.Y) + Rand.Range(-5.0f, 0.0f)); -#endif - splashSoundTimer = 0.5f; - } - //1.0 when the limb is parallel to the surface of the water // = big splash and a large impact float parallel = (float)Math.Abs(Math.Sin(limb.Rotation)); @@ -864,12 +840,6 @@ namespace Barotrauma } } -#if CLIENT - if (limb.LightSource != null) - { - limb.LightSource.Rotation = dir == Direction.Right ? limb.body.DrawRotation : limb.body.DrawRotation - MathHelper.Pi; - } -#endif limb.Update(deltaTime); } @@ -1010,6 +980,8 @@ namespace Barotrauma } } + partial void Splash(Limb limb, Hull limbHull); + protected float GetFloorY(Limb refLimb = null) { PhysicsBody refBody = refLimb == null ? Collider : refLimb.body; diff --git a/BarotraumaShared/Source/Characters/Attack.cs b/BarotraumaShared/Source/Characters/Attack.cs index 7a1af2956..d9f5c8176 100644 --- a/BarotraumaShared/Source/Characters/Attack.cs +++ b/BarotraumaShared/Source/Characters/Attack.cs @@ -2,9 +2,7 @@ using System; using System.Xml.Linq; using System.Collections.Generic; -#if CLIENT -using Barotrauma.Particles; -#endif + namespace Barotrauma { @@ -31,7 +29,7 @@ namespace Barotrauma } } - class Attack + partial class Attack { public readonly float Range; public readonly float Duration; @@ -49,13 +47,7 @@ namespace Barotrauma public readonly float Torque; public readonly float TargetForce; - -#if CLIENT - private Sound sound; - - private ParticleEmitterPrefab particleEmitterPrefab; -#endif - + public readonly float Stun; private float priority; @@ -105,30 +97,19 @@ namespace Barotrauma Torque = ToolBox.GetAttributeFloat(element, "torque", 0.0f); Stun = ToolBox.GetAttributeFloat(element, "stun", 0.0f); - -#if CLIENT - string soundPath = ToolBox.GetAttributeString(element, "sound", ""); - if (!string.IsNullOrWhiteSpace(soundPath)) - { - sound = Sound.Load(soundPath); - } -#endif - + Range = ToolBox.GetAttributeFloat(element, "range", 0.0f); Duration = ToolBox.GetAttributeFloat(element, "duration", 0.0f); priority = ToolBox.GetAttributeFloat(element, "priority", 1.0f); - + + InitProjSpecific(element); + foreach (XElement subElement in element.Elements()) { switch (subElement.Name.ToString().ToLowerInvariant()) { -#if CLIENT - case "particleemitter": - particleEmitterPrefab = new ParticleEmitterPrefab(subElement); - break; -#endif case "statuseffect": if (statusEffects == null) { @@ -140,22 +121,12 @@ namespace Barotrauma } } - - + partial void InitProjSpecific(XElement element); + public AttackResult DoDamage(IDamageable attacker, IDamageable target, Vector2 worldPosition, float deltaTime, bool playSound = true) { -#if CLIENT - if (particleEmitterPrefab != null) - { - particleEmitterPrefab.Emit(worldPosition); - } + DamageParticles(worldPosition); - if (sound != null) - { - sound.Play(1.0f, 500.0f, worldPosition); - } -#endif - var attackResult = target.AddDamage(attacker, worldPosition, this, deltaTime, playSound); var effectType = attackResult.Damage > 0.0f ? ActionType.OnUse : ActionType.OnFailure; @@ -179,5 +150,6 @@ namespace Barotrauma return attackResult; } + partial void DamageParticles(Vector2 worldPosition); } } diff --git a/BarotraumaShared/Source/Characters/Character.cs b/BarotraumaShared/Source/Characters/Character.cs index 33843c646..c49db62c3 100644 --- a/BarotraumaShared/Source/Characters/Character.cs +++ b/BarotraumaShared/Source/Characters/Character.cs @@ -440,7 +440,7 @@ namespace Barotrauma public static Character Create(string file, Vector2 position, CharacterInfo characterInfo = null, bool isRemotePlayer = false, bool hasAi=true) { -#if LINUX +#if LINUX if (!System.IO.File.Exists(file)) { @@ -556,10 +556,6 @@ namespace Barotrauma needsAir = ToolBox.GetAttributeBool(doc.Root, "needsair", false); drowningTime = ToolBox.GetAttributeFloat(doc.Root, "drowningtime", 10.0f); - -#if CLIENT - soundInterval = ToolBox.GetAttributeFloat(doc.Root, "soundinterval", 10.0f); -#endif if (file == humanConfigFile) { @@ -593,6 +589,7 @@ namespace Barotrauma // - if an AICharacter, the server enables it when close enough to any of the players Enabled = GameMain.NetworkMember == null; } + partial void InitProjSpecific(XDocument doc); private static string humanConfigFile; public static string HumanConfigFile @@ -1092,134 +1089,7 @@ namespace Barotrauma selectedCharacter = null; } - - /// - /// Control the Character according to player input - /// - public void ControlLocalPlayer(float deltaTime, Camera cam, bool moveCam = true) - { - if (!DisableControls) - { - for (int i = 0; i < keys.Length; i++ ) - { - keys[i].SetState(); - } - } - else - { - foreach (Key key in keys) - { - if (key == null) continue; - key.Reset(); - } - } - - if (moveCam && needsAir) - { - if (pressureProtection < 80.0f && - (AnimController.CurrentHull == null || AnimController.CurrentHull.LethalPressure > 50.0f)) - { - float pressure = AnimController.CurrentHull == null ? 100.0f : AnimController.CurrentHull.LethalPressure; - - cam.Zoom = MathHelper.Lerp(cam.Zoom, - (pressure / 50.0f) * Rand.Range(1.0f, 1.05f), - (pressure - 50.0f) / 50.0f); - } - cam.OffsetAmount = MathHelper.Lerp(cam.OffsetAmount, 250.0f, 0.05f); - } - - cursorPosition = cam.ScreenToWorld(PlayerInput.MousePosition); - if (AnimController.CurrentHull != null && AnimController.CurrentHull.Submarine != null) - { - cursorPosition -= AnimController.CurrentHull.Submarine.Position; - } - - Vector2 mouseSimPos = ConvertUnits.ToSimUnits(cursorPosition); - -#if CLIENT - if (Lights.LightManager.ViewTarget == this && Vector2.DistanceSquared(AnimController.Limbs[0].SimPosition, mouseSimPos) > 1.0f) - { - 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); - } - } - } -#endif - - if (!LockHands) - { - //find the closest item if selectkey has been hit, or if the Character is being - //controlled by the player (in order to highlight it) - - if (findClosestTimer <= 0.0f || Screen.Selected == GameMain.EditMapScreen) - { - closestCharacter = FindClosestCharacter(mouseSimPos); - if (closestCharacter != null && closestCharacter.info==null) - { - closestCharacter = null; - } - - float closestItemDist = 0.0f; - closestItem = FindClosestItem(mouseSimPos, out closestItemDist); - - if (closestCharacter != null && closestItem != null) - { - if (Vector2.DistanceSquared(closestCharacter.SimPosition, mouseSimPos) < ConvertUnits.ToSimUnits(closestItemDist)*ConvertUnits.ToSimUnits(closestItemDist)) - { - if (selectedConstruction != closestItem) closestItem = null; - } - else - { - closestCharacter = null; - } - } - - findClosestTimer = 0.1f; - } - else - { - findClosestTimer -= deltaTime; - } - - if (selectedCharacter == null && closestItem != null) - { - closestItem.IsHighlighted = true; - if (!LockHands && closestItem.Pick(this)) - { - - } - } - - if (IsKeyHit(InputType.Select)) - { - if (selectedCharacter != null) - { - DeselectCharacter(); - } - else if (closestCharacter != null && closestCharacter.IsHumanoid && closestCharacter.CanBeSelected) - { - SelectCharacter(closestCharacter); - } - } - } - else - { - if (selectedCharacter != null) DeselectCharacter(); - selectedConstruction = null; - closestItem = null; - closestCharacter = null; - } - - DisableControls = false; - } - public static void UpdateAnimAll(float deltaTime) { foreach (Character c in CharacterList) @@ -1327,7 +1197,7 @@ namespace Barotrauma } } - UpdateControlled(deltaTime); + UpdateControlled(deltaTime,cam); if (Stun > 0.0f) { @@ -1345,11 +1215,6 @@ namespace Barotrauma return; } - if (controlled == this) - { - ControlLocalPlayer(deltaTime, cam); - } - Control(deltaTime, cam); if (selectedConstruction != null && !selectedConstruction.IsInPickRange(WorldPosition)) @@ -1442,19 +1307,14 @@ namespace Barotrauma if (!IsDead) LockHands = false; } - partial void UpdateControlled(float deltaTime); + partial void UpdateControlled(float deltaTime,Camera cam); private void UpdateOxygen(float deltaTime) { float prevOxygen = oxygen; Oxygen += deltaTime * (oxygenAvailable < 30.0f ? -5.0f : 10.0f); -#if CLIENT - if (prevOxygen > 0.0f && Oxygen <= 0.0f && controlled == this) - { - SoundPlayer.PlaySound("drown"); - } -#endif + UpdateOxygenProjSpecific(prevOxygen); PressureProtection -= deltaTime * 100.0f; @@ -1469,6 +1329,7 @@ namespace Barotrauma OxygenAvailable += Math.Sign(hullAvailableOxygen - oxygenAvailable) * deltaTime * 50.0f; } + partial void UpdateOxygenProjSpecific(float prevOxygen); private void UpdateUnconscious(float deltaTime) { @@ -1504,12 +1365,12 @@ namespace Barotrauma if (amount > 0.0f) { lastAttackCauseOfDeath = causeOfDeath; -#if CLIENT - if (controlled == this) CharacterHUD.TakeDamage(amount); -#endif + + DamageHUD(amount); } if (health <= minHealth) Kill(causeOfDeath); } + partial void DamageHUD(float amount); public virtual AttackResult AddDamage(IDamageable attacker, Vector2 worldPosition, Attack attack, float deltaTime, bool playSound = false) { @@ -1634,18 +1495,6 @@ namespace Barotrauma if (GameMain.NetworkMember != null) { -#if CLIENT - if (Character.controlled == this) - { - string chatMessage = InfoTextManager.GetInfoText("Self_CauseOfDeath." + causeOfDeath.ToString()); - if (GameMain.Client!=null) chatMessage += " Your chat messages will only be visible to other dead players."; - - GameMain.NetworkMember.AddChatMessage(chatMessage, ChatMessageType.Dead); - GameMain.LightManager.LosEnabled = false; - controlled = null; - } -#endif - if (GameMain.Server != null) GameMain.Server.CreateEntityEvent(this, new object[] { NetEntityEvent.Type.Status }); } @@ -1656,10 +1505,8 @@ namespace Barotrauma if (OnDeath != null) OnDeath(this, causeOfDeath); -#if CLIENT - PlaySound(CharacterSound.SoundType.Die); -#endif - + KillProjSpecific(); + isDead = true; this.causeOfDeath = causeOfDeath; @@ -1693,6 +1540,7 @@ namespace Barotrauma GameMain.GameSession.KillCharacter(this); } } + partial void KillProjSpecific(); public void Revive(bool isNetworkMessage) { @@ -1721,26 +1569,12 @@ namespace Barotrauma CharacterList.Remove(this); -#if CLIENT - if (controlled == this) controlled = null; - - if (GameMain.GameSession?.CrewManager != null && - GameMain.GameSession.CrewManager.characters.Contains(this)) - { - GameMain.GameSession.CrewManager.characters.Remove(this); - } - - if (GameMain.Client != null && GameMain.Client.Character == this) GameMain.Client.Character = null; -#endif + DisposeProjSpecific(); if (aiTarget != null) aiTarget.Remove(); if (AnimController != null) AnimController.Remove(); -#if CLIENT - if (Lights.LightManager.ViewTarget == this) Lights.LightManager.ViewTarget = null; -#endif - if (selectedItems[0] != null) selectedItems[0].Drop(this); if (selectedItems[1] != null) selectedItems[1].Drop(this); @@ -1750,5 +1584,6 @@ namespace Barotrauma if (c.selectedCharacter == this) c.selectedCharacter = null; } } + partial void DisposeProjSpecific(); } } diff --git a/BarotraumaShared/Source/Characters/HuskInfection.cs b/BarotraumaShared/Source/Characters/HuskInfection.cs index 7ffabb243..859f9f97c 100644 --- a/BarotraumaShared/Source/Characters/HuskInfection.cs +++ b/BarotraumaShared/Source/Characters/HuskInfection.cs @@ -9,7 +9,7 @@ using System.Xml.Linq; namespace Barotrauma { - class HuskInfection + partial class HuskInfection { public enum InfectionState { @@ -47,9 +47,11 @@ namespace Barotrauma public void Update(float deltaTime, Character character) { + float prevTimer = IncubationTimer; + if (IncubationTimer < 0.5f) { - UpdateDormantState(deltaTime, character); + UpdateDormantState(deltaTime, character); } else if (IncubationTimer < 1.0f) { @@ -59,7 +61,9 @@ namespace Barotrauma { UpdateActiveState(deltaTime, character); } + UpdateProjSpecific(prevTimer,character); } + partial void UpdateProjSpecific(float prevTimer, Character character); private void UpdateDormantState(float deltaTime, Character character) { @@ -70,26 +74,12 @@ namespace Barotrauma IncubationTimer += deltaTime / IncubationDuration; if (Character.Controlled != character) return; - -#if CLIENT - if (prevTimer % 0.1f > 0.05f && IncubationTimer % 0.1f < 0.05f) - { - GUI.AddMessage(InfoTextManager.GetInfoText("HuskDormant"), Color.Red, 4.0f); - } -#endif } private void UpdateTransitionState(float deltaTime, Character character) { IncubationTimer += deltaTime / IncubationDuration; - -#if CLIENT - if (state == InfectionState.Dormant && Character.Controlled == character) - { - new GUIMessageBox("", InfoTextManager.GetInfoText("HuskCantSpeak")); - } -#endif - + state = InfectionState.Transition; } @@ -97,9 +87,6 @@ namespace Barotrauma { if (state != InfectionState.Active) { -#if CLIENT - if (Character.Controlled==character) new GUIMessageBox("", InfoTextManager.GetInfoText("HuskActivate")); -#endif ActivateHusk(character); state = InfectionState.Active; } diff --git a/BarotraumaShared/Source/Characters/Limb.cs b/BarotraumaShared/Source/Characters/Limb.cs index 81e61f87a..75cad1472 100644 --- a/BarotraumaShared/Source/Characters/Limb.cs +++ b/BarotraumaShared/Source/Characters/Limb.cs @@ -9,9 +9,6 @@ using Barotrauma.Items.Components; using System.Collections.Generic; using System.Linq; using System.IO; -#if CLIENT -using Barotrauma.Lights; -#endif namespace Barotrauma { @@ -303,18 +300,12 @@ namespace Barotrauma case "attack": attack = new Attack(subElement); break; -#if CLIENT - case "lightsource": - LightSource = new LightSource(subElement); - - break; - case "sound": - hitSound = Sound.Load(ToolBox.GetAttributeString(subElement, "file", "")); - break; -#endif } } + + InitProjSpecific(element); } + partial void InitProjSpecific(XElement element); public void MoveToPos(Vector2 pos, float force, bool pullFromCenter=false) { @@ -411,12 +402,7 @@ namespace Barotrauma public void Update(float deltaTime) { -#if CLIENT - if (LightSource != null) - { - LightSource.ParentSub = body.Submarine; - } -#endif + UpdateProjSpecific(); if (!character.IsDead) damage = Math.Max(0.0f, damage-deltaTime*0.1f); @@ -445,6 +431,7 @@ namespace Barotrauma // SimPosition, Vector2.Zero); //} } + partial void UpdateProjSpecific(); public void ActivateDamagedSprite() { diff --git a/BarotraumaShared/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs b/BarotraumaShared/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs index 08e771c43..06187974f 100644 --- a/BarotraumaShared/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs +++ b/BarotraumaShared/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs @@ -156,16 +156,25 @@ namespace Barotrauma.Networking //it's been 10 seconds since this event was created //kick everyone that hasn't received it yet, this is way too old List toKick = inGameClients.FindAll(c => NetIdUtils.IdMoreRecent((UInt16)(lastSentToAll + 1), c.lastRecvEntityEventID)); - - toKick.ForEach(c => server.DisconnectClient(c, "", "You have been disconnected because of excessive desync")); + toKick.ForEach(c => + { + DebugConsole.NewMessage(c.name + " was kicked due to excessive desync (expected old event " + c.lastRecvEntityEventID.ToString() + ")", Microsoft.Xna.Framework.Color.Red); + server.DisconnectClient(c, "", "You have been disconnected because of excessive desync"); + } + ); } if (events.Count > 0) { //the client is waiting for an event that we don't have anymore //(the ID they're expecting is smaller than the ID of the first event in our list) - List toKick = inGameClients.FindAll(c => NetIdUtils.IdMoreRecent(events[0].ID, (UInt16)(c.lastRecvEntityEventID+1))); - toKick.ForEach(c => server.DisconnectClient(c, "", "You have been disconnected because of excessive desync")); + List toKick = inGameClients.FindAll(c => NetIdUtils.IdMoreRecent(events[0].ID, (UInt16)(c.lastRecvEntityEventID + 1))); + toKick.ForEach(c => + { + DebugConsole.NewMessage(c.name + " was kicked due to excessive desync (expected " + c.lastRecvEntityEventID.ToString() + ", last available is " + events[0].ID.ToString() + ")", Microsoft.Xna.Framework.Color.Red); + server.DisconnectClient(c, "", "You have been disconnected because of excessive desync"); + } + ); } }