- AI equips a diving suit before going out

- placing a firesource outside any hull won't crash the game
- scrollbars aren't gray
- fixed client crashing if in the lobby when a round ends
- fixed password box crashing
This commit is contained in:
Regalis
2016-01-25 18:47:19 +02:00
parent 89405d786b
commit 08daab9d87
12 changed files with 177 additions and 48 deletions

View File

@@ -63,6 +63,7 @@
<Compile Include="Source\Characters\AI\IndoorsSteeringManager.cs" />
<Compile Include="Source\Characters\AI\Objectives\AIObjectiveCombat.cs" />
<Compile Include="Source\Characters\AI\Objectives\AIObjectiveContainItem.cs" />
<Compile Include="Source\Characters\AI\Objectives\AIObjectiveFindDivingGear.cs" />
<Compile Include="Source\Characters\AI\Objectives\AIObjectiveFixLeaks.cs" />
<Compile Include="Source\Characters\AI\Order.cs" />
<Compile Include="Source\Characters\AI\CrewCommander.cs" />

View File

@@ -39,7 +39,7 @@
</GUIListBox>
<GUIScrollBar
color="0.3, 0.3, 0.3, 1.0"
color="0.88, 0.25, 0.15, 0.8"
textcolor="1.0, 1.0, 1.0, 1.0"
outlinecolor="0.5, 0.57, 0.6, 1.0">

View File

@@ -36,6 +36,12 @@ namespace Barotrauma
get { return currentTarget; }
}
public bool HasOutdoorsNodes
{
get;
private set;
}
public IndoorsSteeringManager(ISteerable host, bool canOpenDoors)
: base(host)
{
@@ -79,6 +85,8 @@ namespace Barotrauma
}
currentPath = pathFinder.FindPath(pos, target);
HasOutdoorsNodes = currentPath.Nodes.Find(n => n.CurrentHull == null) != null;
findPathTimer = Rand.Range(1.0f,1.2f);
@@ -151,6 +159,22 @@ namespace Barotrauma
bool open = currentPath.CurrentNode != null &&
Math.Sign(door.Item.SimPosition.X - host.SimPosition.X) == Math.Sign(currentPath.CurrentNode.SimPosition.X - host.SimPosition.X);
if (currentPath.CurrentNode==null)
{
open = false;
}
else
{
if (door.LinkedGap.isHorizontal)
{
open = Math.Sign(door.Item.SimPosition.X - character.SimPosition.X) == Math.Sign(currentPath.CurrentNode.SimPosition.X - character.SimPosition.X);
}
else
{
open = Math.Sign(door.Item.SimPosition.Y - character.SimPosition.Y) == Math.Sign(currentPath.CurrentNode.SimPosition.Y - character.SimPosition.Y);
}
}
//toggle the door if it's the previous node and open, or if it's current node and closed
if (door.IsOpen != open)
{

View File

@@ -0,0 +1,76 @@
using Barotrauma.Items.Components;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Barotrauma
{
class AIObjectiveFindDivingGear : AIObjective
{
private AIObjective subObjective;
private string gearName;
public override bool IsCompleted()
{
var item = character.Inventory.FindItem(gearName);
if (item == null) return false;
var containedItems = item.ContainedItems;
var oxygenTank = Array.Find(containedItems, i => i.Name == "Oxygen Tank" && i.Condition > 0.0f);
return oxygenTank != null;
}
public AIObjectiveFindDivingGear(Character character, bool needDivingSuit)
: base(character, "")
{
gearName = needDivingSuit ? "Diving Suit" : "diving";
}
protected override void Act(float deltaTime)
{
var item = character.Inventory.FindItem(gearName);
if (item == null)
{
//get a diving mask/suit first
if (!(subObjective is AIObjectiveGetItem))
{
subObjective = new AIObjectiveGetItem(character, gearName, true);
}
}
else
{
var containedItems = item.ContainedItems;
if (containedItems == null) return;
//check if there's an oxygen tank in the mask
var oxygenTank = Array.Find(containedItems, i => i.Name == "Oxygen Tank" && i.Condition > 0.0f);
if (oxygenTank != null)
{
//isCompleted = true;
return;
}
if (!(subObjective is AIObjectiveContainItem))
{
subObjective = new AIObjectiveContainItem(character, "Oxygen Tank", item.GetComponent<ItemContainer>());
}
}
if (subObjective != null)
{
subObjective.TryComplete(deltaTime);
//isCompleted = subObjective.IsCompleted();
}
}
public override bool IsDuplicate(AIObjective otherObjective)
{
return otherObjective is AIObjectiveFindDivingGear;
}
}
}

View File

@@ -117,45 +117,50 @@ namespace Barotrauma
private bool FindDivingGear(float deltaTime)
{
var item = character.Inventory.FindItem("diving");
if (item == null)
if (divingGearObjective==null)
{
//get a diving mask/suit first
if (!(divingGearObjective is AIObjectiveGetItem))
{
divingGearObjective = new AIObjectiveGetItem(character, "diving", true);
}
}
else
{
var containedItems = item.ContainedItems;
if (containedItems == null) return true;
//check if there's an oxygen tank in the mask
var oxygenTank = Array.Find(containedItems, i => i.Name == "Oxygen Tank" && i.Condition > 0.0f);
if (oxygenTank != null) return true;
if (!(divingGearObjective is AIObjectiveContainItem))
{
divingGearObjective = new AIObjectiveContainItem(character, "Oxygen Tank", item.GetComponent<ItemContainer>());
}
divingGearObjective = new AIObjectiveFindDivingGear(character, false);
}
if (divingGearObjective != null)
{
divingGearObjective.TryComplete(deltaTime);
divingGearObjective.TryComplete(deltaTime);
return divingGearObjective.IsCompleted();
bool isCompleted = divingGearObjective.IsCompleted();
if (isCompleted) divingGearObjective = null;
return isCompleted;
}
//var item = character.Inventory.FindItem("diving");
//if (item == null)
//{
// //get a diving mask/suit first
// if (!(divingGearObjective is AIObjectiveGetItem))
// {
// divingGearObjective = new AIObjectiveGetItem(character, "diving", true);
// }
//}
//else
//{
// var containedItems = item.ContainedItems;
// if (containedItems == null) return true;
return false;
// //check if there's an oxygen tank in the mask
// var oxygenTank = Array.Find(containedItems, i => i.Name == "Oxygen Tank" && i.Condition > 0.0f);
// if (oxygenTank != null) return true;
// if (!(divingGearObjective is AIObjectiveContainItem))
// {
// divingGearObjective = new AIObjectiveContainItem(character, "Oxygen Tank", item.GetComponent<ItemContainer>());
// }
//}
//if (divingGearObjective != null)
//{
// divingGearObjective.TryComplete(deltaTime);
// bool isCompleted = divingGearObjective.IsCompleted();
// if (isCompleted) divingGearObjective = null;
// return isCompleted;
//}
//return false;
}
public override bool IsDuplicate(AIObjective otherObjective)

View File

@@ -10,11 +10,11 @@ namespace Barotrauma
{
class AIObjectiveGoTo : AIObjective
{
Entity target;
private Entity target;
Vector2 targetPos;
private Vector2 targetPos;
bool repeat;
private bool repeat;
//how long until the path to the target is declared unreachable
private float waitUntilPathUnreachable;
@@ -90,7 +90,7 @@ namespace Barotrauma
{
//currTargetPos += target.Submarine.SimPosition;
}
else if (target.Submarine==null)
else if (target.Submarine == null)
{
currTargetPos -= Submarine.Loaded.SimPosition;
}
@@ -103,9 +103,15 @@ namespace Barotrauma
}
else
{
character.AIController.SteeringManager.SteeringSeek(currTargetPos);
character.AIController.SteeringManager.SteeringSeek(currTargetPos);
var indoorsSteering = character.AIController.SteeringManager as IndoorsSteeringManager;
if (indoorsSteering.CurrentPath != null && indoorsSteering.HasOutdoorsNodes)
{
AddSubObjective(new AIObjectiveGetItem(character, "Diving Suit", true));
}
}
}

View File

@@ -135,14 +135,14 @@ namespace Barotrauma
if (isHorizontal)
{
scrollBar = new GUIScrollBar(
new Rectangle(this.rect.X, this.rect.Bottom - 20, this.rect.Width, 20), color, 1.0f, GUI.Style);
new Rectangle(this.rect.X, this.rect.Bottom - 20, this.rect.Width, 20), null, 1.0f, GUI.Style);
}
else
{
scrollBar = new GUIScrollBar(
new Rectangle(this.rect.Right - 20, this.rect.Y, 20, this.rect.Height), color, 1.0f, GUI.Style);
new Rectangle(this.rect.Right - 20, this.rect.Y, 20, this.rect.Height), null, 1.0f, GUI.Style);
}
frame = new GUIFrame(Rectangle.Empty, style, this);
if (style != null) style.Apply(frame, this);

View File

@@ -85,6 +85,8 @@ namespace Barotrauma
private void LimitSize()
{
if (hull == null) return;
position.X = Math.Max(hull.Rect.X, position.X);
position.Y = Math.Min(hull.Rect.Y, position.Y);

View File

@@ -595,12 +595,12 @@ namespace Barotrauma.Networking
public IEnumerable<object> EndGame(string endMessage)
{
GameMain.GameSession.gameMode.End(endMessage);
if (!gameStarted) yield return CoroutineStatus.Success;
GameMain.GameSession.gameMode.End(endMessage);
//var messageBox = new GUIMessageBox("The round has ended", endMessage, 400, 300);
if (!gameStarted) yield return CoroutineStatus.Success;
gameStarted = false;
Character.Controlled = null;

View File

@@ -494,6 +494,8 @@ namespace Barotrauma
SetTraitorsEnabled((YesNoMaybe)index);
if (GameMain.Server != null) GameMain.Server.UpdateNetLobby(null);
return true;
}

View File

@@ -302,15 +302,28 @@ namespace Barotrauma
if (serverList.Selected!=null && (serverList.Selected.GetChild("password") as GUITickBox).Selected)
{
var msgBox = new GUIMessageBox("Password required:", "");
var passwordBox = new GUITextBox(new Rectangle(0,40,150,25), Alignment.TopLeft, GUI.Style, msgBox);
var msgBox = new GUIMessageBox("Password required:", "", new string[] { "OK", "Cancel" });
var passwordBox = new GUITextBox(new Rectangle(0,40,150,25), Alignment.TopLeft, GUI.Style, msgBox.children[0]);
passwordBox.UserData = "password";
var okButton = msgBox.GetChild<GUIButton>();
var okButton = msgBox.Buttons[0];
var cancelButton = msgBox.Buttons[1];
while (GUIMessageBox.MessageBoxes.Contains(msgBox))
{
okButton.Enabled = !string.IsNullOrWhiteSpace(passwordBox.Text);
if (okButton.Selected)
{
msgBox.Close(null,null);
break;
}
else if (cancelButton.Selected)
{
msgBox.Close(null, null);
yield return CoroutineStatus.Success;
}
yield return CoroutineStatus.Running;
}

Binary file not shown.