diff --git a/Subsurface/Content/Characters/Charybdis/charybdis.xml b/Subsurface/Content/Characters/Charybdis/charybdis.xml index fa5caf861..86ef15d62 100644 --- a/Subsurface/Content/Characters/Charybdis/charybdis.xml +++ b/Subsurface/Content/Characters/Charybdis/charybdis.xml @@ -13,7 +13,7 @@ - + diff --git a/Subsurface/Content/Characters/Coelanth/coelanth.xml b/Subsurface/Content/Characters/Coelanth/coelanth.xml index d32181c38..ce223ad49 100644 --- a/Subsurface/Content/Characters/Coelanth/coelanth.xml +++ b/Subsurface/Content/Characters/Coelanth/coelanth.xml @@ -10,12 +10,12 @@ - + - + diff --git a/Subsurface/Content/Characters/Crawler/crawler.xml b/Subsurface/Content/Characters/Crawler/crawler.xml index d2a2dbab5..de3270ce2 100644 --- a/Subsurface/Content/Characters/Crawler/crawler.xml +++ b/Subsurface/Content/Characters/Crawler/crawler.xml @@ -16,7 +16,7 @@ - + @@ -30,7 +30,7 @@ - + @@ -38,7 +38,7 @@ - + @@ -46,7 +46,7 @@ - + @@ -54,7 +54,7 @@ - + diff --git a/Subsurface/Content/Characters/Endworm/endworm.xml b/Subsurface/Content/Characters/Endworm/endworm.xml index 8090dd20d..1ed66da24 100644 --- a/Subsurface/Content/Characters/Endworm/endworm.xml +++ b/Subsurface/Content/Characters/Endworm/endworm.xml @@ -44,12 +44,12 @@ - + - + diff --git a/Subsurface/Content/Characters/Fractalguardian/fractalguardian.xml b/Subsurface/Content/Characters/Fractalguardian/fractalguardian.xml index ee99fe1d0..86c561a70 100644 --- a/Subsurface/Content/Characters/Fractalguardian/fractalguardian.xml +++ b/Subsurface/Content/Characters/Fractalguardian/fractalguardian.xml @@ -8,31 +8,31 @@ - + - + - + - + - + - + diff --git a/Subsurface/Content/Characters/Fractalguardian2/fractalguardian2.xml b/Subsurface/Content/Characters/Fractalguardian2/fractalguardian2.xml index c772e9b69..e1d743557 100644 --- a/Subsurface/Content/Characters/Fractalguardian2/fractalguardian2.xml +++ b/Subsurface/Content/Characters/Fractalguardian2/fractalguardian2.xml @@ -9,25 +9,25 @@ - + - + - + - + - + diff --git a/Subsurface/Content/Characters/Human/human.xml b/Subsurface/Content/Characters/Human/human.xml index 3731b78be..6b70f9857 100644 --- a/Subsurface/Content/Characters/Human/human.xml +++ b/Subsurface/Content/Characters/Human/human.xml @@ -10,21 +10,22 @@ legtorque="15.0" thightorque="-5.0" walkspeed="1.5" - swimspeed="2.0"> + swimspeed="2.0" + impacttolerance="7.5"> - + - + - + diff --git a/Subsurface/Content/Characters/Human/humanhusk.xml b/Subsurface/Content/Characters/Human/humanhusk.xml index 6e8779705..fc593f3ad 100644 --- a/Subsurface/Content/Characters/Human/humanhusk.xml +++ b/Subsurface/Content/Characters/Human/humanhusk.xml @@ -13,16 +13,16 @@ swimspeed="2.0"> - + - + - + @@ -78,7 +78,7 @@ - + diff --git a/Subsurface/Content/Characters/Human/huskappendage.xml b/Subsurface/Content/Characters/Human/huskappendage.xml index 4a8a23841..f388a1ba8 100644 --- a/Subsurface/Content/Characters/Human/huskappendage.xml +++ b/Subsurface/Content/Characters/Human/huskappendage.xml @@ -1,7 +1,7 @@  - + diff --git a/Subsurface/Content/Characters/Husk/husk.xml b/Subsurface/Content/Characters/Husk/husk.xml index d7ba207a7..177bd1407 100644 --- a/Subsurface/Content/Characters/Husk/husk.xml +++ b/Subsurface/Content/Characters/Husk/husk.xml @@ -17,13 +17,13 @@ - + - + @@ -32,10 +32,10 @@ - + - + diff --git a/Subsurface/Content/Characters/Moloch/moloch.xml b/Subsurface/Content/Characters/Moloch/moloch.xml index 9a9b66030..12c85dc13 100644 --- a/Subsurface/Content/Characters/Moloch/moloch.xml +++ b/Subsurface/Content/Characters/Moloch/moloch.xml @@ -11,7 +11,7 @@ - + diff --git a/Subsurface/Content/Characters/TigerThresher/tigerthresher.xml b/Subsurface/Content/Characters/TigerThresher/tigerthresher.xml index 0284b6405..30083658c 100644 --- a/Subsurface/Content/Characters/TigerThresher/tigerthresher.xml +++ b/Subsurface/Content/Characters/TigerThresher/tigerthresher.xml @@ -10,13 +10,13 @@ - + - + diff --git a/Subsurface/Content/Items/Artifacts/artifacts.xml b/Subsurface/Content/Items/Artifacts/artifacts.xml index 0d863f62f..3f11229ed 100644 --- a/Subsurface/Content/Items/Artifacts/artifacts.xml +++ b/Subsurface/Content/Items/Artifacts/artifacts.xml @@ -118,7 +118,7 @@ - + diff --git a/Subsurface/Content/Items/Diving/divinggear.xml b/Subsurface/Content/Items/Diving/divinggear.xml index 8280ae83c..cd1daebd3 100644 --- a/Subsurface/Content/Items/Diving/divinggear.xml +++ b/Subsurface/Content/Items/Diving/divinggear.xml @@ -11,7 +11,7 @@ - + @@ -34,7 +34,7 @@ - + @@ -123,7 +123,7 @@ - + diff --git a/Subsurface/Content/Items/Fabricators/fabricators.xml b/Subsurface/Content/Items/Fabricators/fabricators.xml index 35644e088..a1917ba3d 100644 --- a/Subsurface/Content/Items/Fabricators/fabricators.xml +++ b/Subsurface/Content/Items/Fabricators/fabricators.xml @@ -102,6 +102,10 @@ + + + + @@ -134,7 +138,11 @@ - + + + + + diff --git a/Subsurface/Content/Items/Medical/medical.xml b/Subsurface/Content/Items/Medical/medical.xml index 92edcca1d..8b1585312 100644 --- a/Subsurface/Content/Items/Medical/medical.xml +++ b/Subsurface/Content/Items/Medical/medical.xml @@ -437,7 +437,26 @@ - + + + + + + + + + + + + + diff --git a/Subsurface/Content/Items/Tools/tools.xml b/Subsurface/Content/Items/Tools/tools.xml index e51dfcc6d..ff6953708 100644 --- a/Subsurface/Content/Items/Tools/tools.xml +++ b/Subsurface/Content/Items/Tools/tools.xml @@ -8,7 +8,7 @@ price="100" description="One of the most crucial tools on board the submarine. Also works underwater."> - + @@ -70,7 +70,7 @@ - + @@ -112,7 +112,7 @@ - + @@ -136,7 +136,7 @@ - + @@ -159,7 +159,7 @@ pickdistance="200" price="10"> - + @@ -174,7 +174,7 @@ pickdistance="200" price="10"> - + @@ -191,7 +191,7 @@ pickdistance="200" price="10"> - + @@ -225,7 +225,7 @@ - + @@ -259,7 +259,7 @@ - + diff --git a/Subsurface/Content/Items/Weapons/depthcharge.xml b/Subsurface/Content/Items/Weapons/depthcharge.xml index 31f240caf..31e9a2016 100644 --- a/Subsurface/Content/Items/Weapons/depthcharge.xml +++ b/Subsurface/Content/Items/Weapons/depthcharge.xml @@ -74,7 +74,7 @@ - + diff --git a/Subsurface/Content/Items/Weapons/weapons.xml b/Subsurface/Content/Items/Weapons/weapons.xml index 72e39f49b..5b80c984d 100644 --- a/Subsurface/Content/Items/Weapons/weapons.xml +++ b/Subsurface/Content/Items/Weapons/weapons.xml @@ -35,7 +35,7 @@ - + @@ -61,7 +61,7 @@ price="200" tags="smallitem,weapon"> - + @@ -78,7 +78,7 @@ pickdistance="200" tags="smallitem,weapon"> - + @@ -103,7 +103,7 @@ - + @@ -174,7 +174,7 @@ tags="weapon,smallitem" description="HONK"> - + diff --git a/Subsurface/Source/Characters/AI/HumanAIController.cs b/Subsurface/Source/Characters/AI/HumanAIController.cs index 68b2e0102..fe25a7bb6 100644 --- a/Subsurface/Source/Characters/AI/HumanAIController.cs +++ b/Subsurface/Source/Characters/AI/HumanAIController.cs @@ -185,6 +185,11 @@ namespace Barotrauma new Vector2(pathSteering.CurrentPath.Nodes[i].DrawPosition.X, -pathSteering.CurrentPath.Nodes[i].DrawPosition.Y), new Vector2(pathSteering.CurrentPath.Nodes[i - 1].DrawPosition.X, -pathSteering.CurrentPath.Nodes[i - 1].DrawPosition.Y), Color.LightGreen); + + spriteBatch.DrawString(GUI.SmallFont, + pathSteering.CurrentPath.Nodes[i].ID.ToString(), + new Vector2(pathSteering.CurrentPath.Nodes[i].DrawPosition.X, -pathSteering.CurrentPath.Nodes[i].DrawPosition.Y - 10), + Color.LightGreen); } } } diff --git a/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs b/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs index a377b7ca9..a1aa98d75 100644 --- a/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs +++ b/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs @@ -97,7 +97,7 @@ namespace Barotrauma diff.Y = 0.0f; } - if (diff == Vector2.Zero) return -host.Steering; + if (diff.Length() < 0.01) return -host.Steering; return Vector2.Normalize(diff) * speed; } @@ -258,6 +258,12 @@ namespace Barotrauma if (closestButton != null) { + if (!closestButton.HasRequiredItems(character, false) && shouldBeOpen) + { + currentPath.Unreachable = true; + return; + } + closestButton.Item.Pick(character, false, true); break; } diff --git a/Subsurface/Source/Characters/AI/PathFinder.cs b/Subsurface/Source/Characters/AI/PathFinder.cs index 45dd9a4c5..7ddef2f11 100644 --- a/Subsurface/Source/Characters/AI/PathFinder.cs +++ b/Subsurface/Source/Characters/AI/PathFinder.cs @@ -172,7 +172,12 @@ namespace Barotrauma start, node.Waypoint.SimPosition, null, Physics.CollisionWall | Physics.CollisionLevel | Physics.CollisionStairs | Physics.CollisionPlatform); - if (body != null && body.UserData is Structure && !((Structure)body.UserData).IsPlatform) continue; + if (body != null) + { + if (body.UserData is Structure && !((Structure)body.UserData).IsPlatform) continue; + if (body.UserData is Item && body.FixtureList[0].CollisionCategories.HasFlag(Physics.CollisionWall)) continue; + + } } closestDist = dist; diff --git a/Subsurface/Source/Characters/Animation/AnimController.cs b/Subsurface/Source/Characters/Animation/AnimController.cs index 5b9ebc1cc..f49af7369 100644 --- a/Subsurface/Source/Characters/Animation/AnimController.cs +++ b/Subsurface/Source/Characters/Animation/AnimController.cs @@ -13,10 +13,7 @@ namespace Barotrauma protected Character character; protected float walkSpeed, swimSpeed; - - //how large impacts the Character can take before being stunned - //protected float impactTolerance; - + protected float stunTimer; protected float walkPos; @@ -47,14 +44,7 @@ namespace Barotrauma walkSpeed = ToolBox.GetAttributeFloat(element, "walkspeed", 1.0f); swimSpeed = ToolBox.GetAttributeFloat(element, "swimspeed", 1.0f); - //stepOffset = ToolBox.GetAttributeVector2(element, "stepoffset", Vector2.One); - //stepOffset = ConvertUnits.ToSimUnits(stepOffset); - - //impactTolerance = ToolBox.GetAttributeFloat(element, "impacttolerance", 10.0f); - legTorque = ToolBox.GetAttributeFloat(element, "legtorque", 0.0f); - - } public virtual void UpdateAnim(float deltaTime) { } diff --git a/Subsurface/Source/Characters/Animation/Ragdoll.cs b/Subsurface/Source/Characters/Animation/Ragdoll.cs index 16a436c75..3f802293c 100644 --- a/Subsurface/Source/Characters/Animation/Ragdoll.cs +++ b/Subsurface/Source/Characters/Animation/Ragdoll.cs @@ -224,6 +224,12 @@ namespace Barotrauma } } + public float ImpactTolerance + { + get; + private set; + } + public float StrongestImpact { get { return strongestImpact; } @@ -257,6 +263,8 @@ namespace Barotrauma torsoPosition = ConvertUnits.ToSimUnits(torsoPosition); torsoAngle = MathHelper.ToRadians(ToolBox.GetAttributeFloat(element, "torsoangle", 0.0f)); + ImpactTolerance = ToolBox.GetAttributeFloat(element, "impacttolerance", 50.0f); + CanEnterSubmarine = ToolBox.GetAttributeBool(element, "canentersubmarine", true); foreach (XElement subElement in element.Elements()) @@ -471,11 +479,11 @@ namespace Barotrauma { if (!character.IsRemotePlayer || GameMain.Server != null) { - if (impact > 8.0f) + if (impact > ImpactTolerance) { - character.AddDamage(CauseOfDeath.Damage, impact - 8.0f, null); + character.AddDamage(CauseOfDeath.Damage, impact - ImpactTolerance, null); SoundPlayer.PlayDamageSound(DamageSoundType.LimbBlunt, strongestImpact, collider); - strongestImpact = Math.Max(strongestImpact, impact - 8.0f); + strongestImpact = Math.Max(strongestImpact, impact - ImpactTolerance); } } @@ -852,7 +860,6 @@ namespace Barotrauma //limb.body.ApplyLinearImpulse(impulse); int n = (int)((limb.Position.X - limbHull.Rect.X) / Hull.WaveWidth); limbHull.WaveVel[n] = Math.Min(impulse.Y * 1.0f, 5.0f); - StrongestImpact = ((impulse.Length() * 0.5f) - limb.impactTolerance); } } } diff --git a/Subsurface/Source/Characters/Limb.cs b/Subsurface/Source/Characters/Limb.cs index 05e254bb6..4532a846a 100644 --- a/Subsurface/Source/Characters/Limb.cs +++ b/Subsurface/Source/Characters/Limb.cs @@ -212,9 +212,7 @@ namespace Barotrauma body.CollisionCategories = Physics.CollisionCharacter; body.CollidesWith = Physics.CollisionAll & ~Physics.CollisionCharacter & ~Physics.CollisionItem; } - - impactTolerance = ToolBox.GetAttributeFloat(element, "impacttolerance", 10.0f); - + body.UserData = this; refJointIndex = -1; diff --git a/Subsurface/Source/Events/Missions/CombatMission.cs b/Subsurface/Source/Events/Missions/CombatMission.cs index 02b9ff903..87809baf0 100644 --- a/Subsurface/Source/Events/Missions/CombatMission.cs +++ b/Subsurface/Source/Events/Missions/CombatMission.cs @@ -43,7 +43,7 @@ namespace Barotrauma return successMessage .Replace("[loser]", teamNames[1 - winner]) - .Replace("[winner]", teamNames[winner]); + .Replace("[winner]", teamNames[winner]); } } @@ -57,11 +57,11 @@ namespace Barotrauma ToolBox.GetAttributeString(element, "description2", "") }; - for (int i = 0; i < descriptions.Length; i++ ) + for (int i = 0; i < descriptions.Length; i++) { - for (int n = 0; n < 2;n++ ) + for (int n = 0; n < 2; n++) { - descriptions[i] = descriptions[i].Replace("[location" + (n + 1) + "]", Locations[n]); + descriptions[i] = descriptions[i].Replace("[location" + (n + 1) + "]", locations[n].Name); } } @@ -69,7 +69,7 @@ namespace Barotrauma { ToolBox.GetAttributeString(element, "teamname1", "Team A"), ToolBox.GetAttributeString(element, "teamname2", "Team B") - }; + }; } public static string GetTeamName(int teamID) @@ -136,10 +136,7 @@ namespace Barotrauma DebugConsole.ThrowError("Combat missions cannot be played in the single player mode."); return; } - - Items.Components.Radar.StartMarker = Locations[0]; - Items.Components.Radar.EndMarker = Locations[1]; - + subs = new Submarine[] { Submarine.MainSubs[0], Submarine.MainSubs[1] }; subs[1].SetPosition(Level.Loaded.EndPosition - new Vector2(0.0f, 2000.0f)); subs[1].FlipX(); diff --git a/Subsurface/Source/Events/Missions/Mission.cs b/Subsurface/Source/Events/Missions/Mission.cs index 8263dfc87..1dd37f692 100644 --- a/Subsurface/Source/Events/Missions/Mission.cs +++ b/Subsurface/Source/Events/Missions/Mission.cs @@ -26,9 +26,7 @@ namespace Barotrauma protected List messages; private int reward; - - protected string[] Locations = new string[2]; - + public string Name { get { return name; } @@ -47,6 +45,7 @@ namespace Barotrauma public bool Completed { get { return completed; } + set { completed = value; } } public virtual string RadarLabel @@ -111,11 +110,9 @@ namespace Barotrauma headers.Add(ToolBox.GetAttributeString(subElement, "header", "")); messages.Add(ToolBox.GetAttributeString(subElement, "text", "")); } - - + for (int n = 0; n < 2; n++) { - Locations[n] = locations[n].Name; description = description.Replace("[location" + (n + 1) + "]", locations[n].Name); successMessage = successMessage.Replace("[location" + (n + 1) + "]", locations[n].Name); @@ -227,7 +224,12 @@ namespace Barotrauma public virtual void Update(float deltaTime) { } - public virtual bool AssignTeamIDs(List clients,out int hostTeam) { clients.ForEach(client => { client.TeamID = 1; }); hostTeam = 1; return false; } + public virtual bool AssignTeamIDs(List clients, out int hostTeam) + { + clients.ForEach(c => c.TeamID = 1); + hostTeam = 1; + return false; + } public void ShowMessage(int index) { diff --git a/Subsurface/Source/GameSession/GameModes/MissionMode.cs b/Subsurface/Source/GameSession/GameModes/MissionMode.cs index e84fc9769..24bf6e751 100644 --- a/Subsurface/Source/GameSession/GameModes/MissionMode.cs +++ b/Subsurface/Source/GameSession/GameModes/MissionMode.cs @@ -17,15 +17,9 @@ namespace Barotrauma public MissionMode(GameModePreset preset, object param) : base(preset, param) { - Location[] locations = new Location[2]; + Location[] locations = { GameMain.GameSession.StartLocation, GameMain.GameSession.EndLocation }; MTRandom rand = new MTRandom(ToolBox.StringToInt(GameMain.NetLobbyScreen.LevelSeed)); - - for (int i = 0; i < 2; i++) - { - locations[i] = Location.CreateRandom(new Vector2((float)rand.NextDouble() * 10000.0f, (float)rand.NextDouble() * 10000.0f)); - } - mission = Mission.LoadRandom(locations, rand, param as string); } diff --git a/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs b/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs index ce1b6ea64..8d6ede417 100644 --- a/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs +++ b/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs @@ -197,13 +197,13 @@ namespace Barotrauma } else if (leavingSub.AtEndPosition) { - endShiftButton.Text = "Enter " + Map.SelectedLocation.Name; + endShiftButton.Text = ToolBox.LimitString("Enter " + Map.SelectedLocation.Name, endShiftButton.Font, endShiftButton.Rect.Width - 5); endShiftButton.UserData = leavingSub; endShiftButton.Visible = true; } else if (leavingSub.AtStartPosition) { - endShiftButton.Text = "Enter " + Map.CurrentLocation.Name; + endShiftButton.Text = ToolBox.LimitString("Enter " + Map.CurrentLocation.Name, endShiftButton.Font, endShiftButton.Rect.Width - 5); endShiftButton.UserData = leavingSub; endShiftButton.Visible = true; } diff --git a/Subsurface/Source/GameSession/GameSession.cs b/Subsurface/Source/GameSession/GameSession.cs index ca273bcfa..34127c357 100644 --- a/Subsurface/Source/GameSession/GameSession.cs +++ b/Subsurface/Source/GameSession/GameSession.cs @@ -13,6 +13,9 @@ namespace Barotrauma public readonly GameMode gameMode; + //two locations used as the start and end in the MP mode + private Location[] dummyLocations; + private InfoFrameTab selectedTab; private GUIButton infoButton; private GUIFrame infoFrame; @@ -50,7 +53,37 @@ namespace Barotrauma return (mode == null) ? null : mode.Map; } } - + + public Location StartLocation + { + get + { + if (Map != null) return Map.CurrentLocation; + + if (dummyLocations==null) + { + CreateDummyLocations(); + } + + return dummyLocations[0]; + } + } + + public Location EndLocation + { + get + { + if (Map != null) return Map.SelectedLocation; + + if (dummyLocations == null) + { + CreateDummyLocations(); + } + + return dummyLocations[1]; + } + } + public Submarine Submarine { get { return submarine; } @@ -81,12 +114,10 @@ namespace Barotrauma this.saveFile = saveFile; - //guiRoot = new GUIFrame(new Rectangle(0,0,GameMain.GraphicsWidth,GameMain.GraphicsWidth), Color.Transparent); - infoButton = new GUIButton(new Rectangle(10, 10, 100, 20), "Info", GUI.Style, null); infoButton.OnClicked = ToggleInfoFrame; - if (gameModePreset!=null) gameMode = gameModePreset.Instantiate(missionType); + if (gameModePreset != null) gameMode = gameModePreset.Instantiate(missionType); this.submarine = submarine; } @@ -109,6 +140,17 @@ namespace Barotrauma } } + private void CreateDummyLocations() + { + dummyLocations = new Location[2]; + + MTRandom rand = new MTRandom(ToolBox.StringToInt(GameMain.NetLobbyScreen.LevelSeed)); + for (int i = 0; i < 2; i++) + { + dummyLocations[i] = Location.CreateRandom(new Vector2((float)rand.NextDouble() * 10000.0f, (float)rand.NextDouble() * 10000.0f)); + } + } + public void StartShift(string levelSeed, bool loadSecondSub = true) { Level level = Level.CreateRandom(levelSeed); @@ -166,8 +208,6 @@ namespace Barotrauma if (gameMode!=null) gameMode.Start(); - Items.Components.Radar.StartMarker = "Start"; - Items.Components.Radar.EndMarker = "End"; if (gameMode.Mission != null) Mission.Start(Level.Loaded); TaskManager.StartShift(level); diff --git a/Subsurface/Source/GameSession/InfoTextManager.cs b/Subsurface/Source/GameSession/InfoTextManager.cs index 14e5d4566..e72f1eef3 100644 --- a/Subsurface/Source/GameSession/InfoTextManager.cs +++ b/Subsurface/Source/GameSession/InfoTextManager.cs @@ -58,10 +58,9 @@ namespace Barotrauma } if (Submarine.MainSub != null) text = text.Replace("[sub]", Submarine.MainSub.Name); - if (GameMain.GameSession != null && GameMain.GameSession.Map != null) + if (GameMain.GameSession != null && GameMain.GameSession.StartLocation != null) { - if (GameMain.GameSession.Map.CurrentLocation!=null) - text = text.Replace("[location]", GameMain.GameSession.Map.CurrentLocation.Name); + text = text.Replace("[location]", GameMain.GameSession.StartLocation.Name); } return text; diff --git a/Subsurface/Source/GameSession/ShiftSummary.cs b/Subsurface/Source/GameSession/ShiftSummary.cs index 1816d5554..a9b9e2a48 100644 --- a/Subsurface/Source/GameSession/ShiftSummary.cs +++ b/Subsurface/Source/GameSession/ShiftSummary.cs @@ -15,8 +15,8 @@ namespace Barotrauma { this.gameSession = gameSession; - startLocation = gameSession.Map==null ? null : gameSession.Map.CurrentLocation; - endLocation = gameSession.Map==null ? null : gameSession.Map.SelectedLocation; + startLocation = gameSession.StartLocation; + endLocation = gameSession.EndLocation; selectedMission = gameSession.Mission; } diff --git a/Subsurface/Source/Items/Components/Machines/Deconstructor.cs b/Subsurface/Source/Items/Components/Machines/Deconstructor.cs index e208013c3..44ac51a75 100644 --- a/Subsurface/Source/Items/Components/Machines/Deconstructor.cs +++ b/Subsurface/Source/Items/Components/Machines/Deconstructor.cs @@ -22,7 +22,7 @@ namespace Barotrauma.Items.Components public Deconstructor(Item item, XElement element) : base(item, element) { - progressBar = new GUIProgressBar(new Rectangle(0,0,200,20), Color.Green, 0.0f, Alignment.BottomCenter, GuiFrame); + progressBar = new GUIProgressBar(new Rectangle(0,0,200,20), Color.Green, GUI.Style, 0.0f, Alignment.BottomCenter, GuiFrame); activateButton = new GUIButton(new Rectangle(0, 0, 200, 20), "Deconstruct", Alignment.TopCenter, GUI.Style, GuiFrame); activateButton.OnClicked = ToggleActive; diff --git a/Subsurface/Source/Items/Components/Machines/Fabricator.cs b/Subsurface/Source/Items/Components/Machines/Fabricator.cs index 83b530633..4059b28ef 100644 --- a/Subsurface/Source/Items/Components/Machines/Fabricator.cs +++ b/Subsurface/Source/Items/Components/Machines/Fabricator.cs @@ -91,6 +91,10 @@ namespace Barotrauma.Items.Components private FabricableItem fabricatedItem; private float timeUntilReady; + //used for checking if contained items have changed + //(in which case we need to recheck which items can be fabricated) + private Item[] prevContainedItems; + private float lastNetworkUpdate; public Fabricator(Item item, XElement element) @@ -110,7 +114,6 @@ namespace Barotrauma.Items.Components itemList = new GUIListBox(new Rectangle(0,0,GuiFrame.Rect.Width/2-20,0), GUI.Style, GuiFrame); itemList.OnSelected = SelectItem; - //structureList.CheckSelected = MapEntityPrefab.GetSelected; foreach (FabricableItem fi in fabricableItems) { @@ -131,6 +134,7 @@ namespace Barotrauma.Items.Components Color.Transparent, Color.White, Alignment.Left, Alignment.Left, null, frame); + textBlock.ToolTip = fi.TargetItem.Description; textBlock.Padding = new Vector4(5.0f, 0.0f, 5.0f, 0.0f); if (fi.TargetItem.sprite != null) @@ -138,6 +142,7 @@ namespace Barotrauma.Items.Components GUIImage img = new GUIImage(new Rectangle(0, 0, 40, 40), fi.TargetItem.sprite, Alignment.Left, frame); img.Scale = Math.Min(Math.Min(40.0f / img.SourceRect.Width, 40.0f / img.SourceRect.Height), 1.0f); img.Color = fi.TargetItem.SpriteColor; + img.ToolTip = fi.TargetItem.Description; } } @@ -151,7 +156,7 @@ namespace Barotrauma.Items.Components if (selectedItemFrame != null) GuiFrame.RemoveChild(selectedItemFrame); //int width = 200, height = 150; - selectedItemFrame = new GUIFrame(new Rectangle(0, 0, (int)(GuiFrame.Rect.Width * 0.4f), 250), Color.Black * 0.8f, Alignment.CenterY | Alignment.Right, null, GuiFrame); + selectedItemFrame = new GUIFrame(new Rectangle(0, 0, (int)(GuiFrame.Rect.Width * 0.4f), 300), Color.Black * 0.8f, Alignment.CenterY | Alignment.Right, null, GuiFrame); selectedItemFrame.Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f); @@ -160,6 +165,8 @@ namespace Barotrauma.Items.Components if (targetItem.TargetItem.sprite != null) { + int y = 0; + GUIImage img = new GUIImage(new Rectangle(10, 0, 40, 40), targetItem.TargetItem.sprite, Alignment.TopLeft, selectedItemFrame); img.Scale = Math.Min(Math.Min(40.0f / img.SourceRect.Width, 40.0f / img.SourceRect.Height), 1.0f); img.Color = targetItem.TargetItem.SpriteColor; @@ -172,12 +179,24 @@ namespace Barotrauma.Items.Components Alignment.TopLeft, null, selectedItemFrame, true); + y += 40; + + if (!string.IsNullOrWhiteSpace(targetItem.TargetItem.Description)) + { + var description = new GUITextBlock( + new Rectangle(0, y, 0, 0), + targetItem.TargetItem.Description, + GUI.Style, Alignment.TopLeft, Alignment.TopLeft, + selectedItemFrame, true, GUI.SmallFont); + + y += description.Rect.Height + 10; + } + List inadequateSkills = new List(); if (Character.Controlled != null) { - inadequateSkills = targetItem.RequiredSkills.FindAll(skill => Character.Controlled.GetSkillLevel(skill.Name) < skill.Level); } @@ -204,7 +223,7 @@ namespace Barotrauma.Items.Components } new GUITextBlock( - new Rectangle(0, 50, 0, 25), + new Rectangle(0, y, 0, 25), text, Color.Transparent, textColor, Alignment.TopLeft, @@ -222,11 +241,13 @@ namespace Barotrauma.Items.Components public override bool Select(Character character) { + CheckFabricableItems(character); if (itemList.Selected != null) { - SelectItem(itemList.Selected, itemList.Selected.UserData); + SelectItem(itemList.Selected, itemList.Selected.UserData); } + return base.Select(character); } @@ -235,6 +256,30 @@ namespace Barotrauma.Items.Components return (picker != null); } + /// + /// check which of the items can be fabricated by the character + /// and update the text colors of the item list accordingly + /// + private void CheckFabricableItems(Character character) + { + foreach (GUIComponent child in itemList.children) + { + var itemPrefab = child.UserData as FabricableItem; + if (itemPrefab == null) continue; + + bool canBeFabricated = CanBeFabricated(itemPrefab, character); + + + child.GetChild().TextColor = Color.White * (canBeFabricated ? 1.0f : 0.5f); + child.GetChild().Color = itemPrefab.TargetItem.SpriteColor * (canBeFabricated ? 1.0f : 0.5f); + + } + + var itemContainer = item.GetComponent(); + prevContainedItems = new Item[itemContainer.Inventory.Items.Length]; + itemContainer.Inventory.Items.CopyTo(prevContainedItems, 0); + } + private bool StartButtonClicked(GUIButton button, object obj) { if (fabricatedItem == null) @@ -344,6 +389,30 @@ namespace Barotrauma.Items.Components activateButton.Enabled = CanBeFabricated(targetItem, character); } + if (character != null) + { + bool itemsChanged = false; + if (prevContainedItems == null) + { + itemsChanged = true; + } + else + { + var itemContainer = item.GetComponent(); + for (int i = 0; i < itemContainer.Inventory.Items.Length; i++) + { + if (prevContainedItems[i] != itemContainer.Inventory.Items[i]) + { + itemsChanged = true; + break; + } + } + } + + if (itemsChanged) CheckFabricableItems(character); + } + + GuiFrame.Update((float)Timing.Step); } diff --git a/Subsurface/Source/Items/Components/Machines/Radar.cs b/Subsurface/Source/Items/Components/Machines/Radar.cs index 52661476c..82702c46a 100644 --- a/Subsurface/Source/Items/Components/Machines/Radar.cs +++ b/Subsurface/Source/Items/Components/Machines/Radar.cs @@ -20,10 +20,7 @@ namespace Barotrauma.Items.Components private List radarBlips; private float prevPingRadius; - - public static string StartMarker = "Start"; - public static string EndMarker = "End"; - + [HasDefaultValue(10000.0f, false)] public float Range { @@ -265,11 +262,11 @@ namespace Barotrauma.Items.Components DrawMarker(spriteBatch, - (GameMain.GameSession.Map == null) ? StartMarker : GameMain.GameSession.Map.CurrentLocation.Name, + GameMain.GameSession.StartLocation.Name, (Level.Loaded.StartPosition - item.WorldPosition), displayScale, center, (rect.Width * 0.5f)); DrawMarker(spriteBatch, - (GameMain.GameSession.Map == null) ? EndMarker : GameMain.GameSession.Map.SelectedLocation.Name, + GameMain.GameSession.EndLocation.Name, (Level.Loaded.EndPosition - item.WorldPosition), displayScale, center, (rect.Width * 0.5f)); if (GameMain.GameSession.Mission != null) @@ -397,12 +394,15 @@ namespace Barotrauma.Items.Components if (dir.X < 0.0f) markerPos.X -= GUI.SmallFont.MeasureString(label).X+10; - GUI.DrawString(spriteBatch, new Vector2(markerPos.X + 10, markerPos.Y), label, Color.LightGreen * textAlpha, Color.Black * textAlpha*0.5f, 2, GUI.SmallFont); + string wrappedLabel = ToolBox.WrapText(label, 150, GUI.SmallFont); - GUI.DrawString(spriteBatch, new Vector2(markerPos.X + 10, markerPos.Y + 15), (int)(dist * Physics.DisplayToRealWorldRatio) + " m", - Color.LightGreen * textAlpha, - Color.Black * textAlpha, 2, GUI.SmallFont); - + wrappedLabel += "\n"+((int)(dist * Physics.DisplayToRealWorldRatio) + " m"); + + GUI.DrawString(spriteBatch, + new Vector2(markerPos.X + 10, markerPos.Y), + wrappedLabel, + Color.LightGreen * textAlpha, Color.Black * textAlpha * 0.5f, + 2, GUI.SmallFont); } protected override void RemoveComponentSpecific() diff --git a/Subsurface/Source/Items/Components/Machines/Steering.cs b/Subsurface/Source/Items/Components/Machines/Steering.cs index 48a5bf06f..a1ae055db 100644 --- a/Subsurface/Source/Items/Components/Machines/Steering.cs +++ b/Subsurface/Source/Items/Components/Machines/Steering.cs @@ -19,7 +19,8 @@ namespace Barotrauma.Items.Components private Vector2 targetVelocity; private GUITickBox autopilotTickBox, maintainPosTickBox; - + private GUITickBox levelEndTickBox, levelStartTickBox; + private bool autoPilot; private Vector2? posToMaintain; @@ -47,21 +48,23 @@ namespace Barotrauma.Items.Components if (value == autoPilot) return; autoPilot = value; - autopilotTickBox.Selected = value; maintainPosTickBox.Enabled = autoPilot; - + levelEndTickBox.Enabled = autoPilot; + levelStartTickBox.Enabled = autoPilot; + if (autoPilot) { - if (pathFinder==null) pathFinder = new PathFinder(WayPoint.WayPointList, false); - steeringPath = pathFinder.FindPath( - ConvertUnits.ToSimUnits(item.WorldPosition), - TargetPosition == null ? ConvertUnits.ToSimUnits(Level.Loaded.EndPosition) : (Vector2)TargetPosition); + if (pathFinder == null) pathFinder = new PathFinder(WayPoint.WayPointList, false); + ToggleMaintainPosition(maintainPosTickBox); } else { maintainPosTickBox.Selected = false; + levelEndTickBox.Selected = false; + levelStartTickBox.Selected = false; + posToMaintain = null; } } @@ -114,15 +117,28 @@ namespace Barotrauma.Items.Components return true; }; - maintainPosTickBox = new GUITickBox(new Rectangle(0, 50, 20, 20), "Maintain position", Alignment.TopLeft, GuiFrame); + maintainPosTickBox = new GUITickBox(new Rectangle(5, 50, 15, 15), "Maintain position", Alignment.TopLeft, GUI.SmallFont, GuiFrame); maintainPosTickBox.Enabled = false; maintainPosTickBox.OnSelected = ToggleMaintainPosition; + + levelStartTickBox = new GUITickBox( + new Rectangle(5, 70, 15, 15), + GameMain.GameSession == null ? "" : ToolBox.LimitString(GameMain.GameSession.StartLocation.Name, 20), + Alignment.TopLeft, GUI.SmallFont, GuiFrame); + levelStartTickBox.Enabled = false; + levelStartTickBox.OnSelected = SelectDestination; + + levelEndTickBox = new GUITickBox( + new Rectangle(5, 90, 15, 15), + GameMain.GameSession == null ? "" : ToolBox.LimitString(GameMain.GameSession.StartLocation.Name, 20), + Alignment.TopLeft, GUI.SmallFont, GuiFrame); + levelEndTickBox.Enabled = false; + levelEndTickBox.OnSelected = SelectDestination; + } public override void Update(float deltaTime, Camera cam) { - //base.Update(deltaTime, cam); - if (valueChanged) { networkUpdateTimer -= deltaTime; @@ -331,6 +347,28 @@ namespace Barotrauma.Items.Components } + private void UpdatePath() + { + Vector2 target; + if (TargetPosition != null) + { + target = (Vector2)TargetPosition; + } + else + { + if (levelEndTickBox.Selected) + { + target = ConvertUnits.ToSimUnits(Level.Loaded.EndPosition); + } + else + { + target = ConvertUnits.ToSimUnits(Level.Loaded.StartPosition); + } + } + + steeringPath = pathFinder.FindPath(ConvertUnits.ToSimUnits(item.WorldPosition), target); + } + private void SteerTowardsPosition(Vector2 worldPosition) { float prediction = 10.0f; @@ -345,7 +383,7 @@ namespace Barotrauma.Items.Components } else { - TargetVelocity = targetSpeed/5.0f; + TargetVelocity = targetSpeed / 5.0f; } } @@ -353,21 +391,42 @@ namespace Barotrauma.Items.Components { valueChanged = true; - if (tickBox.Selected) - { - if (item.Submarine == null) - { - posToMaintain = null; - } - else - { - posToMaintain = item.Submarine.WorldPosition; - } - } - else + levelStartTickBox.Selected = false; + levelEndTickBox.Selected = false; + + if (item.Submarine == null) { posToMaintain = null; } + else + { + posToMaintain = item.Submarine.WorldPosition; + } + + tickBox.Selected = true; + + return true; + } + + private bool SelectDestination(GUITickBox tickBox) + { + valueChanged = true; + + if (tickBox == levelStartTickBox) + { + levelEndTickBox.Selected = false; + } + else + { + levelStartTickBox.Selected = false; + } + + maintainPosTickBox.Selected = false; + posToMaintain = null; + + UpdatePath(); + + tickBox.Selected = true; return true; } @@ -397,6 +456,16 @@ namespace Barotrauma.Items.Components else { msg.Write(posToMaintain != null); + message.Write(posToMaintain != null); + if (posToMaintain != null) + { + message.Write(((Vector2)posToMaintain).X); + message.Write(((Vector2)posToMaintain).Y); + } + else + { + message.Write(levelStartTickBox.Selected); + } } } @@ -420,6 +489,17 @@ namespace Barotrauma.Items.Components { posToMaintain = null; maintainPosTickBox.Selected = false; + bool maintainPos = message.ReadBoolean(); + if (maintainPos) + { + newPosToMaintain = new Vector2( + message.ReadFloat(), + message.ReadFloat()); + } + else + { + headingToStart = message.ReadBoolean(); + } } } } @@ -467,6 +547,22 @@ namespace Barotrauma.Items.Components maintainPosTickBox.Selected = false; } } + maintainPosTickBox.Selected = newPosToMaintain != null; + posToMaintain = newPosToMaintain; + + if (posToMaintain == null && autoPilot) + { + levelStartTickBox.Selected = headingToStart; + levelEndTickBox.Selected = !headingToStart; + + UpdatePath(); + } + else + { + levelStartTickBox.Selected = false; + levelEndTickBox.Selected = false; + } + } } } diff --git a/Subsurface/Source/Map/Levels/LevelRenderer.cs b/Subsurface/Source/Map/Levels/LevelRenderer.cs index 2eb4e5c96..8e786ab1e 100644 --- a/Subsurface/Source/Map/Levels/LevelRenderer.cs +++ b/Subsurface/Source/Map/Levels/LevelRenderer.cs @@ -126,21 +126,32 @@ namespace Barotrauma spriteBatch.End(); - spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.Additive, SamplerState.LinearWrap, DepthStencilState.Default, null, null, cam.Transform); - for (int i = 1; i < 2; i++) + for (int i = 1; i < 4; i++) { - Vector2 offset = new Vector2(cam.WorldView.X, cam.WorldView.Y); + float scale = 1.0f - i * 0.2f; - dustParticles.SourceRect = new Rectangle((int)(offset.X), (int)(-offset.Y), (int)(1024), (int)(1024)); + //alpha goes from 1.0 to 0.0 when scale is in the range of 0.2-0.1 + float alpha = (cam.Zoom * scale) < 0.2f ? (cam.Zoom * scale - 0.1f) * 10.0f : 1.0f; + if (alpha <= 0.0f) continue; + + Vector2 offset = (new Vector2(cam.WorldViewCenter.X, cam.WorldViewCenter.Y) + dustOffset) * scale; + Vector3 origin = new Vector3(cam.WorldView.Width, cam.WorldView.Height, 0.0f) * 0.5f; - dustParticles.DrawTiled(spriteBatch, new Vector2(cam.WorldView.X, -cam.WorldView.Y), - new Vector2(cam.WorldView.Width, cam.WorldView.Height), - Vector2.Zero, Color.White); + dustParticles.SourceRect = new Rectangle( + (int)((offset.X - origin.X + (i * 256)) / scale), + (int)((-offset.Y - origin.Y + (i * 256)) / scale), + (int)((cam.WorldView.Width) / scale), + (int)((cam.WorldView.Height) / scale)); + + spriteBatch.Draw(dustParticles.Texture, + new Vector2(cam.WorldViewCenter.X, -cam.WorldViewCenter.Y), + dustParticles.SourceRect, Color.White * alpha, 0.0f, + new Vector2(cam.WorldView.Width, cam.WorldView.Height) * 0.5f / scale, scale, SpriteEffects.None, 0); } spriteBatch.End(); diff --git a/Subsurface/Source/Map/WayPoint.cs b/Subsurface/Source/Map/WayPoint.cs index 7b6809526..efb67f350 100644 --- a/Subsurface/Source/Map/WayPoint.cs +++ b/Subsurface/Source/Map/WayPoint.cs @@ -437,11 +437,11 @@ namespace Barotrauma WayPoint[] stairPoints = new WayPoint[2]; stairPoints[0] = new WayPoint( - new Vector2(stairs.Rect.X - 75.0f, + new Vector2(stairs.Rect.X - 32.0f, stairs.Rect.Y - (stairs.StairDirection == Direction.Left ? 80 : stairs.Rect.Height) + heightFromFloor), SpawnType.Path, submarine); stairPoints[1] = new WayPoint( - new Vector2(stairs.Rect.Right + 75.0f, + new Vector2(stairs.Rect.Right + 32.0f, stairs.Rect.Y - (stairs.StairDirection == Direction.Left ? stairs.Rect.Height : 80) + heightFromFloor), SpawnType.Path, submarine); for (int i = 0; i < 2; i++ ) @@ -536,11 +536,11 @@ namespace Barotrauma //ladderPoints[0].ConnectTo(ladderPoints[1]); } - + foreach (Gap gap in Gap.GapList) { if (!gap.isHorizontal) continue; - + //too small to walk through if (gap.Rect.Height < 150.0f) continue; @@ -550,9 +550,15 @@ namespace Barotrauma for (int dir = -1; dir <= 1; dir += 2) { float tolerance = gap.IsRoomToRoom ? 50.0f : outSideWaypointInterval / 2.0f; - WayPoint closest = wayPoint.FindClosest(dir, true, new Vector2(-tolerance, tolerance)); - if (closest == null) continue; - wayPoint.ConnectTo(closest); + + WayPoint closest = wayPoint.FindClosest( + dir, true, new Vector2(-tolerance, tolerance), + gap.ConnectedDoor == null ? null : gap.ConnectedDoor.Body.FarseerBody); + + if (closest != null) + { + wayPoint.ConnectTo(closest); + } } } @@ -582,7 +588,7 @@ namespace Barotrauma } } - private WayPoint FindClosest(int dir, bool horizontalSearch, Vector2 tolerance) + private WayPoint FindClosest(int dir, bool horizontalSearch, Vector2 tolerance, Body ignoredBody = null) { if (dir != -1 && dir != 1) return null; @@ -614,9 +620,9 @@ namespace Barotrauma if (closest == null || dist < closestDist) { var body = Submarine.CheckVisibility(SimPosition, wp.SimPosition, true); - if (body != null) + if (body != null && body != ignoredBody && !(body.UserData is Submarine)) { - if (body.UserData is Structure) continue; + if (body.UserData is Structure || body.FixtureList[0].CollisionCategories.HasFlag(Physics.CollisionWall)) continue; } closestDist = dist; diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs index 7c7f65627..7759e4811 100644 --- a/Subsurface/Source/Networking/GameServer.cs +++ b/Subsurface/Source/Networking/GameServer.cs @@ -975,6 +975,7 @@ namespace Barotrauma.Networking endMessage += TraitorManager.GetEndMessage(); } + Mission mission = GameMain.GameSession.Mission; GameMain.GameSession.gameMode.End(endMessage); if (autoRestart) AutoRestartTimer = AutoRestartInterval; diff --git a/Subsurface/Source/Physics/PhysicsBody.cs b/Subsurface/Source/Physics/PhysicsBody.cs index 4b03ab976..6c739d1eb 100644 --- a/Subsurface/Source/Physics/PhysicsBody.cs +++ b/Subsurface/Source/Physics/PhysicsBody.cs @@ -233,7 +233,7 @@ namespace Barotrauma public PhysicsBody(Body farseerBody) { body = farseerBody; - body.UserData = this; + if (body.UserData == null) body.UserData = this; LastSentPosition = body.Position; diff --git a/Subsurface/Source/Screens/GameScreen.cs b/Subsurface/Source/Screens/GameScreen.cs index d26649c34..e4e244135 100644 --- a/Subsurface/Source/Screens/GameScreen.cs +++ b/Subsurface/Source/Screens/GameScreen.cs @@ -12,6 +12,8 @@ namespace Barotrauma { Camera cam; + Color waterColor = new Color(0.75f, 0.8f, 0.9f, 1.0f); + readonly RenderTarget2D renderTargetBackground; readonly RenderTarget2D renderTarget; readonly RenderTarget2D renderTargetWater; @@ -270,7 +272,7 @@ namespace Barotrauma spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque); - spriteBatch.Draw(renderTarget, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), new Color(0.75f, 0.8f, 0.9f, 1.0f)); + spriteBatch.Draw(renderTarget, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), waterColor); spriteBatch.End(); #if LINUX @@ -406,7 +408,7 @@ namespace Barotrauma float r = Math.Min(CharacterHUD.damageOverlayTimer * 0.5f, 0.5f); spriteBatch.Draw(renderTarget, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), - Color.Lerp(new Color(0.1f, 0.1f, 0.1f), Color.Red, r)); + Color.Lerp(GameMain.LightManager.AmbientLight*0.5f, Color.Red, r)); spriteBatch.End(); } diff --git a/Subsurface/Source/Utils/ToolBox.cs b/Subsurface/Source/Utils/ToolBox.cs index 31e0d166b..f07ceba87 100644 --- a/Subsurface/Source/Utils/ToolBox.cs +++ b/Subsurface/Source/Utils/ToolBox.cs @@ -343,8 +343,6 @@ namespace Barotrauma { if (maxWidth <= 0 || string.IsNullOrWhiteSpace(str)) return ""; - StringBuilder sb = new StringBuilder(); - float currWidth = font.MeasureString("...").X; for (int i = 0; i < str.Length; i++ ) { @@ -352,7 +350,7 @@ namespace Barotrauma if (currWidth > maxWidth) { - return str.Substring(0, i + 1) + "..."; + return str.Substring(0, Math.Max(i - 2, 1)) + "..."; } }