diff --git a/Subsurface/Barotrauma.csproj b/Subsurface/Barotrauma.csproj
index 6b0ea2803..dd85d1914 100644
--- a/Subsurface/Barotrauma.csproj
+++ b/Subsurface/Barotrauma.csproj
@@ -60,6 +60,7 @@
+
@@ -598,6 +599,9 @@
PreserveNewest
+
+ PreserveNewest
+
PreserveNewest
diff --git a/Subsurface/Content/Map/beaconbackground.jpg b/Subsurface/Content/Map/beaconbackground.jpg
index 179b69a7b..abe7ff4ee 100644
Binary files a/Subsurface/Content/Map/beaconbackground.jpg and b/Subsurface/Content/Map/beaconbackground.jpg differ
diff --git a/Subsurface/Content/Map/locationTypes.xml b/Subsurface/Content/Map/locationTypes.xml
index d51b53400..530832341 100644
--- a/Subsurface/Content/Map/locationTypes.xml
+++ b/Subsurface/Content/Map/locationTypes.xml
@@ -12,9 +12,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ background="Content/Map/researchbackground.jpg">
+
+
+
+
+
+
+
i.components.Find(ic => ic.GetType() == order.ItemComponentType) != null);
+ int y2 = y;
+ foreach (Item it in matchingItems)
+ {
+ var newOrder = new Order(order, it.components.Find(ic => ic.GetType() == order.ItemComponentType));
+
+ var button = new GUIButton(new Rectangle(x, y2, 150, 20), order.Name, GUI.Style, frame);
+ button.UserData = newOrder;
+ button.OnClicked = SetOrder;
+ y2 += 25;
+ }
+ }
+ else
+ {
+ var button = new GUIButton(new Rectangle(x, y, 150, 20), order.Name, GUI.Style, frame);
+ button.UserData = order;
+ button.OnClicked = SetOrder;
+ }
+
+
+
+ x += 160;
+ }
+ }
+
+ public void UpdateCharacters()
+ {
+ if (frame == null) CreateGUIFrame();
+
+ List prevCharacterFrames = new List();
+ foreach (GUIComponent child in frame.children)
+ {
+ if (child.UserData as Character == null) continue;
+
+ prevCharacterFrames.Add(child);
+ }
+
+ foreach (GUIComponent child in prevCharacterFrames)
+ {
+ frame.RemoveChild(child);
+ }
+
int x = 0, y = 0;
foreach (Character character in crewManager.characters)
{
- GUIButton characterButton = new GUIButton(new Rectangle(x,y, 150, 40), "", Color.Transparent, null, frame);
+ if (character.IsDead) continue;
+
+ GUIButton characterButton = new GUIButton(new Rectangle(x, y, 150, 40), "", Color.Transparent, null, frame);
characterButton.UserData = character;
characterButton.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f);
-
-
+
if (character == Character.Controlled)
{
characterButton.CanBeSelected = false;
@@ -75,18 +130,7 @@ namespace Barotrauma
new GUIImage(new Rectangle(-10, -5, 0, 0), character.AnimController.Limbs[0].sprite, Alignment.Left, characterButton);
- x += 160;
- }
-
- x = 0;
- y = 150;
- foreach (Order command in Order.List)
- {
- var button = new GUIButton(new Rectangle(x, y, 150, 20), command.Name, GUI.Style, frame);
- button.UserData = command;
- button.OnClicked = SetOrder;
-
- x += button.Rect.Width + 10;
+ x += 160;
}
}
diff --git a/Subsurface/Source/Characters/AI/HumanAIController.cs b/Subsurface/Source/Characters/AI/HumanAIController.cs
index 961025d0e..7032a4502 100644
--- a/Subsurface/Source/Characters/AI/HumanAIController.cs
+++ b/Subsurface/Source/Characters/AI/HumanAIController.cs
@@ -50,7 +50,7 @@ namespace Barotrauma
//{
// steeringManager.SteeringSeek(Character.Controlled.Position);
//}
-
+
Character.AnimController.IgnorePlatforms = (-Character.AnimController.TargetMovement.Y > Math.Abs(Character.AnimController.TargetMovement.X));
if (Math.Abs(Character.AnimController.TargetMovement.X) > 0.1f && !Character.AnimController.InWater)
diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjective.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjective.cs
index 5da96ddf8..48d815f6c 100644
--- a/Subsurface/Source/Characters/AI/Objectives/AIObjective.cs
+++ b/Subsurface/Source/Characters/AI/Objectives/AIObjective.cs
@@ -13,6 +13,8 @@ namespace Barotrauma
protected Character character;
+ protected string option;
+
public virtual bool IsCompleted()
{
return false;
@@ -23,11 +25,23 @@ namespace Barotrauma
get { return false; }
}
- public AIObjective(Character character)
+ public string Option
+ {
+ get { return option; }
+ }
+
+
+ public AIObjective(Character character, string option)
{
subObjectives = new List();
this.character = character;
+
+ this.option = option;
+
+#if DEBUG
+ IsDuplicate(null);
+#endif
}
///
@@ -37,10 +51,10 @@ namespace Barotrauma
/// the character who's trying to achieve the objective
public void TryComplete(float deltaTime)
{
+ subObjectives.RemoveAll(s => s.IsCompleted());
+
foreach (AIObjective objective in subObjectives)
{
- if (objective.IsCompleted()) continue;
-
objective.TryComplete(deltaTime);
return;
}
@@ -50,6 +64,13 @@ namespace Barotrauma
protected virtual void Act(float deltaTime) { }
+ public void AddSubObjective(AIObjective objective)
+ {
+ if (subObjectives.Find(o => o.IsDuplicate(objective)) != null) return;
+
+ subObjectives.Add(objective);
+ }
+
public virtual float GetPriority(Character character)
{
return 0.0f;
@@ -57,7 +78,12 @@ namespace Barotrauma
public virtual bool IsDuplicate(AIObjective otherObjective)
{
+#if DEBUG
throw new NotImplementedException();
+#else
+ return (this.GetType() == otherObjective.GetType());
+#endif
+
}
}
}
diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveContainItem.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveContainItem.cs
new file mode 100644
index 000000000..a6f65822a
--- /dev/null
+++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveContainItem.cs
@@ -0,0 +1,73 @@
+using Barotrauma.Items.Components;
+using Microsoft.Xna.Framework;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Barotrauma
+{
+ class AIObjectiveContainItem: AIObjective
+ {
+ private string itemName;
+
+ private ItemContainer container;
+
+ bool canBeCompleted;
+
+ bool isCompleted;
+
+
+ public AIObjectiveContainItem(Character character, string itemName, ItemContainer container)
+ : base (character, "")
+ {
+ this.itemName = itemName;
+ this.container = container;
+
+ //check if the container has room for more items
+ canBeCompleted = false;
+ foreach (Item contained in container.inventory.Items)
+ {
+ if (contained != null) continue;
+ canBeCompleted = true;
+ break;
+ }
+ }
+
+ public override bool IsCompleted()
+ {
+ return isCompleted;
+ }
+
+ protected override void Act(float deltaTime)
+ {
+ if (isCompleted) return;
+
+ //get the item that should be contained
+ var itemToContain = character.Inventory.FindItem(itemName);
+ if (itemToContain == null)
+ {
+ AddSubObjective(new AIObjectiveGetItem(character, itemName));
+ return;
+ }
+
+ if (Vector2.Distance(character.SimPosition, container.Item.SimPosition) > container.Item.PickDistance
+ || !container.Item.IsInsideTrigger(character.Position))
+ {
+ AddSubObjective(new AIObjectiveGoTo(container.Item.SimPosition, character));
+ return;
+ }
+
+ container.Combine(itemToContain);
+ isCompleted = true;
+ }
+
+ public override bool IsDuplicate(AIObjective otherObjective)
+ {
+ AIObjectiveContainItem objective = otherObjective as AIObjectiveContainItem;
+ return (objective != null);
+ }
+
+
+ }
+}
diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveFindSafety.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveFindSafety.cs
index 2fec74906..b796169b5 100644
--- a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveFindSafety.cs
+++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveFindSafety.cs
@@ -8,21 +8,21 @@ namespace Barotrauma
{
class AIObjectiveFindSafety : AIObjective
{
- const float SearchHullInterval = 1.0f;
+ const float SearchHullInterval = 3.0f;
const float MinSafety = 50.0f;
AIObjectiveGoTo gotoObjective;
- private List unreachable;
+ private List unreachable;
float currenthullSafety;
float searchHullTimer;
public AIObjectiveFindSafety(Character character)
- : base(character)
+ : base(character, "")
{
- unreachable = new List();
+ unreachable = new List();
}
protected override void Act(float deltaTime)
@@ -44,6 +44,7 @@ namespace Barotrauma
}
else
{
+ var pathSteering = character.AIController.SteeringManager as IndoorsSteeringManager;
Hull bestHull = null;
float bestValue = currenthullSafety;
@@ -51,7 +52,7 @@ namespace Barotrauma
foreach (Hull hull in Hull.hullList)
{
if (hull == character.AnimController.CurrentHull) continue;
- if (unreachable.Contains(hull.AiTarget)) continue;
+ if (unreachable.Contains(hull)) continue;
float hullValue = GetHullSafety(hull);
hullValue -= (float)Math.Sqrt(Math.Abs(character.Position.X- hull.Position.X));
@@ -66,7 +67,17 @@ namespace Barotrauma
if (bestHull != null)
{
- gotoObjective = new AIObjectiveGoTo(bestHull.AiTarget, character);
+ var path = pathSteering.PathFinder.FindPath(character.SimPosition, bestHull.SimPosition);
+ if (pathSteering.CurrentPath != null && pathSteering.CurrentPath.Cost < path.Cost && !pathSteering.CurrentPath.Unreachable && gotoObjective!=null)
+ {
+ return;
+ }
+ else
+ {
+ pathSteering.SetPath(path);
+ }
+
+ gotoObjective = new AIObjectiveGoTo(bestHull, character);
//character.AIController.SelectTarget(bestHull.AiTarget);
}
@@ -80,7 +91,7 @@ namespace Barotrauma
if (pathSteering!=null && pathSteering.CurrentPath!= null &&
pathSteering.CurrentPath.Unreachable && !unreachable.Contains(gotoObjective.Target))
{
- unreachable.Add(gotoObjective.Target);
+ unreachable.Add(gotoObjective.Target as Hull);
}
}
diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs
index 0d23d7de4..0d4011b9e 100644
--- a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs
+++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs
@@ -11,7 +11,7 @@ namespace Barotrauma
Gap leak;
public AIObjectiveFixLeak(Gap leak, Character character)
- :base (character)
+ :base (character, "")
{
this.leak = leak;
}
diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveGetItem.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveGetItem.cs
index f2e1dc6ba..1b0c36abe 100644
--- a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveGetItem.cs
+++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveGetItem.cs
@@ -22,7 +22,7 @@ namespace Barotrauma
}
public AIObjectiveGetItem(Character character, string itemName)
- : base (character)
+ : base (character, "")
{
canBeCompleted = true;
@@ -72,7 +72,7 @@ namespace Barotrauma
public override bool IsCompleted()
{
- return character.Inventory.Items.FirstOrDefault(i => i != null && (i.HasTag(itemName) || i.Name == itemName)) != null;
+ return character.Inventory.FindItem(itemName) != null;
}
}
}
diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveGoTo.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveGoTo.cs
index 48621d21b..60fcc020a 100644
--- a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveGoTo.cs
+++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveGoTo.cs
@@ -10,7 +10,7 @@ namespace Barotrauma
{
class AIObjectiveGoTo : AIObjective
{
- AITarget target;
+ Entity target;
Vector2 targetPos;
@@ -26,13 +26,13 @@ namespace Barotrauma
}
}
- public AITarget Target
+ public Entity Target
{
get { return target; }
}
- public AIObjectiveGoTo(AITarget target, Character character, bool repeat = false)
- : base (character)
+ public AIObjectiveGoTo(Entity target, Character character, bool repeat = false)
+ : base (character, "")
{
this.target = target;
this.repeat = false;
@@ -40,14 +40,19 @@ namespace Barotrauma
public AIObjectiveGoTo(Vector2 targetPos, Character character)
- : base(character)
+ : base(character, "")
{
this.targetPos = targetPos;
}
protected override void Act(float deltaTime)
{
- character.AIController.SelectTarget(target);
+ if (character.SelectedConstruction!=null)
+ {
+ character.SelectedConstruction = null;
+ }
+
+ if (target!=null) character.AIController.SelectTarget(target.AiTarget);
character.AIController.SteeringManager.SteeringSeek(
target != null ? target.SimPosition : targetPos);
@@ -56,7 +61,22 @@ namespace Barotrauma
public override bool IsCompleted()
{
if (repeat) return false;
- return Vector2.Distance(target != null ? target.SimPosition : ConvertUnits.ToDisplayUnits(targetPos), character.SimPosition) < 0.5f;
+
+ float allowedDistance = 0.5f;
+ var item = target as Item;
+ if (item != null) allowedDistance = Math.Max(item.PickDistance,allowedDistance);
+
+ return Vector2.Distance(target != null ? target.SimPosition : targetPos, character.SimPosition) < allowedDistance;
+ }
+
+ public override bool IsDuplicate(AIObjective otherObjective)
+ {
+ AIObjectiveGoTo objective = otherObjective as AIObjectiveGoTo;
+ if (objective == null) return false;
+
+ if (objective.target == target) return true;
+
+ return (objective.targetPos == targetPos);
}
}
}
diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveIdle.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveIdle.cs
index 1d24d7f78..42f55569a 100644
--- a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveIdle.cs
+++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveIdle.cs
@@ -13,7 +13,7 @@ namespace Barotrauma
- public AIObjectiveIdle(Character character) : base(character)
+ public AIObjectiveIdle(Character character) : base(character, "")
{
}
@@ -26,10 +26,27 @@ namespace Barotrauma
protected override void Act(float deltaTime)
{
+
+ var pathSteering = character.AIController.SteeringManager as IndoorsSteeringManager;
+
if (newTargetTimer <= 0.0f)
{
currentTarget = FindRandomTarget();
+ if (currentTarget!=null)
+ {
+ var path = pathSteering.PathFinder.FindPath(character.SimPosition, currentTarget.SimPosition);
+ if (path.Cost > 200.0f)
+ {
+ return;
+ }
+ else
+ {
+ pathSteering.SetPath(path);
+ }
+ }
+
+
newTargetTimer = currentTarget == null ? 5.0f : 10.0f;
}
else
@@ -39,17 +56,27 @@ namespace Barotrauma
if (currentTarget == null) return;
-
+
+
+ //wander randomly if reached the end of the path or the target is unreachable
+ if (pathSteering!=null && pathSteering.CurrentPath != null &&
+ (pathSteering.CurrentPath.NextNode == null || pathSteering.CurrentPath.Unreachable))
+ {
+ if (character.Position.X < character.AnimController.CurrentHull.Rect.X + 200.0f)
+ {
+ pathSteering.SteeringManual(deltaTime, Vector2.UnitX);
+ }
+ else if (character.Position.X > character.AnimController.CurrentHull.Rect.Right - 200.0f)
+ {
+ pathSteering.SteeringManual(deltaTime, -Vector2.UnitX);
+ }
+
+ character.AIController.SteeringManager.SteeringWander(1.0f);
+ return;
+ }
+
character.AIController.SteeringManager.SteeringSeek(currentTarget.SimPosition);
- var pathSteering = character.AIController.SteeringManager as IndoorsSteeringManager;
- if (pathSteering!=null && pathSteering.CurrentPath != null)
- {
- if (pathSteering.CurrentPath.NextNode==null || pathSteering.CurrentPath.Unreachable)
- {
- character.AIController.SteeringManager.SteeringWander(1.0f);
- }
- }
}
private AITarget FindRandomTarget()
diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveManager.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveManager.cs
index d46b9f26b..01fd407b6 100644
--- a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveManager.cs
+++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveManager.cs
@@ -47,7 +47,7 @@ namespace Barotrauma
public void UpdateObjectives()
{
- if (currentOrder != null || !objectives.Any()) return;
+ if (!objectives.Any()) return;
//remove completed objectives
objectives = objectives.FindAll(o => !o.IsCompleted());
@@ -69,7 +69,7 @@ namespace Barotrauma
public void DoCurrentObjective(float deltaTime)
{
- if (currentOrder != null)
+ if (currentOrder != null && (!objectives.Any() || objectives[0].GetPriority(character) i.GetComponent() != null);
- if (reactorItem == null) return;
-
- currentOrder = new AIObjectiveOperateItem(reactorItem.GetComponent(), character);
+ currentOrder = new AIObjectiveGoTo(Character.Controlled, character, true);
break;
default:
- currentOrder = null;
+ if (order.TargetItem == null) return;
+
+ currentOrder = new AIObjectiveOperateItem(order.TargetItem, character, option);
+
break;
}
}
diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs
index 681189155..2421a5040 100644
--- a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs
+++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs
@@ -10,22 +10,43 @@ namespace Barotrauma
class AIObjectiveOperateItem : AIObjective
{
private ItemComponent targetItem;
+ private ItemComponent itemController;
- public AIObjectiveOperateItem(ItemComponent item, Character character)
- :base (character)
+ private bool isCompleted;
+
+
+
+ public AIObjectiveOperateItem(ItemComponent item, Character character, string option)
+ :base (character, option)
{
targetItem = item;
+
+ var controllers = item.Item.GetConnectedComponents();
+ if (controllers.Any()) itemController = controllers[0];
}
protected override void Act(float deltaTime)
{
- if (Vector2.Distance(character.SimPosition, targetItem.Item.SimPosition) < targetItem.Item.PickDistance)
+ ItemComponent target = itemController == null ? targetItem: itemController;
+
+ if (Vector2.Distance(character.SimPosition, target.Item.SimPosition) < target.Item.PickDistance
+ || target.Item.IsInsideTrigger(character.Position))
{
- //targetItem.Pick(character, false, true);
+ if (character.SelectedConstruction != target.Item && target.CanBeSelected)
+ {
+ target.Item.Pick(character, false, true);
+ }
+
+ if (targetItem.AIOperate(deltaTime, character, this)) isCompleted = true;
return;
}
- subObjectives.Add(new AIObjectiveGoTo(targetItem.Item.SimPosition, character));
+ subObjectives.Add(new AIObjectiveGoTo(target.Item, character));
+ }
+
+ public override bool IsCompleted()
+ {
+ return isCompleted;
}
public override bool IsDuplicate(AIObjective otherObjective)
diff --git a/Subsurface/Source/Characters/AI/Order.cs b/Subsurface/Source/Characters/AI/Order.cs
index 5f5532566..1f8ccc527 100644
--- a/Subsurface/Source/Characters/AI/Order.cs
+++ b/Subsurface/Source/Characters/AI/Order.cs
@@ -1,4 +1,5 @@
-using System;
+using Barotrauma.Items.Components;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -7,32 +8,53 @@ namespace Barotrauma
{
class Order
{
- public static List List;
+ public static List PrefabList;
public readonly string Name;
public readonly string DoingText;
- Sprite buttonSprite;
+ //Sprite buttonSprite;
+
+ public readonly Type ItemComponentType;
+
+ public ItemComponent TargetItem;
public readonly string[] Options;
static Order()
{
- List = new List();
+ PrefabList = new List();
- new Order("Follow", "Following");
- new Order("Operate Reactor", "Operating reactor", new string[] {"Power Up", "Shutdown"});
+ PrefabList.Add(new Order("Follow", "Following"));
- new Order("Dismiss", "Dismissed");
+ PrefabList.Add(new Order("Operate Reactor", "Operating reactor", typeof(Reactor), new string[] {"Power up", "Shutdown"}));
+ PrefabList.Add(new Order("Operate Railgun", "Operating railgun", typeof(Turret), new string[] { "Fire at will", "Hold fire" }));
+
+
+ PrefabList.Add(new Order("Dismiss", "Dismissed"));
+ }
+
+ private Order(string name, string doingText, Type itemComponentType, string[] parameters = null)
+ {
+ Name = name;
+ DoingText = doingText;
+ ItemComponentType = itemComponentType;
+ Options = parameters == null ? new string[0] : parameters;
+ }
+
+ public Order(Order prefab, ItemComponent targetItem)
+ {
+ Name = prefab.Name;
+ DoingText = prefab.DoingText;
+ ItemComponentType = prefab.ItemComponentType;
+ Options = prefab.Options;
+
+ TargetItem = targetItem;
}
private Order(string name, string doingText, string[] parameters = null)
+ :this (name,doingText, null, parameters)
{
- this.Name = name;
- this.DoingText = doingText;
- this.Options = parameters == null ? new string[0] : parameters;
-
- List.Add(this);
}
}
diff --git a/Subsurface/Source/Characters/AI/PathFinder.cs b/Subsurface/Source/Characters/AI/PathFinder.cs
index 5af610785..9f8b8cb5d 100644
--- a/Subsurface/Source/Characters/AI/PathFinder.cs
+++ b/Subsurface/Source/Characters/AI/PathFinder.cs
@@ -266,6 +266,7 @@ namespace Barotrauma
{
finalPath.Add(pathNode.Waypoint);
+ path.Cost += pathNode.F;
pathNode = pathNode.Parent;
}
@@ -275,6 +276,7 @@ namespace Barotrauma
{
path.AddNode(wayPoint);
}
+
return path;
}
diff --git a/Subsurface/Source/Characters/AI/PathSteeringManager.cs b/Subsurface/Source/Characters/AI/PathSteeringManager.cs
index fe3098496..2bdedfea9 100644
--- a/Subsurface/Source/Characters/AI/PathSteeringManager.cs
+++ b/Subsurface/Source/Characters/AI/PathSteeringManager.cs
@@ -49,6 +49,13 @@ namespace Barotrauma
findPathTimer -= 1.0f / 60.0f;
}
+ public void SetPath(SteeringPath path)
+ {
+ currentPath = path;
+ if (path.Nodes.Any()) currentTarget = path.Nodes[path.Nodes.Count - 1].SimPosition;
+ findPathTimer = 1.0f;
+ }
+
protected override Vector2 DoSteeringSeek(Vector2 target, float speed = 1)
{
@@ -101,7 +108,7 @@ namespace Barotrauma
//toggle the door if it's the previous node and open, or if it's current node and closed
if (door.IsOpen != open)
{
- var buttons = door.GetButtons();
+ var buttons = door.Item.GetConnectedComponents();
foreach (Controller controller in buttons)
{
if (Vector2.Distance(controller.Item.SimPosition, character.SimPosition) > controller.Item.PickDistance * 2.0f) continue;
@@ -123,7 +130,7 @@ namespace Barotrauma
if (!canOpenDoors) return null;
- var doorButtons = nextNode.Waypoint.ConnectedGap.ConnectedDoor.GetButtons();
+ var doorButtons = nextNode.Waypoint.ConnectedGap.ConnectedDoor.Item.GetConnectedComponents();
foreach (Controller button in doorButtons)
{
if (Math.Sign(button.Item.Position.X - nextNode.Waypoint.Position.X) !=
diff --git a/Subsurface/Source/Characters/AI/SteeringManager.cs b/Subsurface/Source/Characters/AI/SteeringManager.cs
index a25896691..c931edc79 100644
--- a/Subsurface/Source/Characters/AI/SteeringManager.cs
+++ b/Subsurface/Source/Characters/AI/SteeringManager.cs
@@ -50,6 +50,11 @@ namespace Barotrauma
steering += DoSteeringAvoid(deltaTime, speed);
}
+ public void SteeringManual(float deltaTime, Vector2 velocity)
+ {
+ steering += velocity * deltaTime;
+ }
+
public virtual void Update(float speed = 1.0f)
{
float steeringSpeed = steering.Length();
@@ -111,7 +116,7 @@ namespace Barotrauma
float maxDistance = 2.0f;
- Vector2 ahead = host.SimPosition + Vector2.Normalize(host.Steering)*maxDistance;
+ Vector2 ahead = host.SimPosition + Vector2.Normalize(host.Steering) * maxDistance;
if (rayCastTimer <= 0.0f)
{
@@ -120,12 +125,12 @@ namespace Barotrauma
if (closestBody == null)
{
avoidSteering = Vector2.Zero;
- return Vector2.Zero;
+ return Vector2.Zero;
}
else
{
Structure closestStructure = closestBody.UserData as Structure;
- if (closestStructure!=null)
+ if (closestStructure != null)
{
Vector2 obstaclePosition = Submarine.LastPickedPosition;
if (closestStructure.IsHorizontal)
@@ -139,8 +144,14 @@ namespace Barotrauma
avoidSteering = Vector2.Normalize(Submarine.LastPickedPosition - obstaclePosition);
}
+ else
+ {
+ Item item = closestBody.UserData as Item;
+ if (item != null) avoidSteering = Vector2.Normalize(Submarine.LastPickedPosition - item.SimPosition);
+
+ }
}
-
+
}
else
{
@@ -148,7 +159,7 @@ namespace Barotrauma
}
return avoidSteering * speed;
-
}
+
}
}
diff --git a/Subsurface/Source/Characters/AI/SteeringPath.cs b/Subsurface/Source/Characters/AI/SteeringPath.cs
index d508da2d8..428ba2af0 100644
--- a/Subsurface/Source/Characters/AI/SteeringPath.cs
+++ b/Subsurface/Source/Characters/AI/SteeringPath.cs
@@ -32,6 +32,12 @@ namespace Barotrauma
get { return currentIndex; }
}
+ public float Cost
+ {
+ get;
+ set;
+ }
+
public WayPoint PrevNode
{
get
diff --git a/Subsurface/Source/Characters/Character.cs b/Subsurface/Source/Characters/Character.cs
index 127d9c9d1..4b427422f 100644
--- a/Subsurface/Source/Characters/Character.cs
+++ b/Subsurface/Source/Characters/Character.cs
@@ -131,6 +131,11 @@ namespace Barotrauma
public Vector2 CursorPosition
{
get { return cursorPosition; }
+ set
+ {
+ if (!MathUtils.IsValid(value)) return;
+ cursorPosition = value;
+ }
}
public Character ClosestCharacter
diff --git a/Subsurface/Source/Characters/CharacterInfo.cs b/Subsurface/Source/Characters/CharacterInfo.cs
index cc6b805d0..2845daf1d 100644
--- a/Subsurface/Source/Characters/CharacterInfo.cs
+++ b/Subsurface/Source/Characters/CharacterInfo.cs
@@ -216,6 +216,30 @@ namespace Barotrauma
return frame;
}
+ public GUIFrame CreateCharacterFrame(GUIComponent parent, string text, object userData)
+ {
+ GUIFrame frame = new GUIFrame(new Rectangle(0, 0, 0, 40), Color.Transparent, null, parent);
+ frame.UserData = userData;
+ frame.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f);
+ frame.HoverColor = Color.LightGray * 0.5f;
+ frame.SelectedColor = Color.Gold * 0.5f;
+
+ // string name = character.Info.Name.Replace(' ', '\n');
+
+ GUITextBlock textBlock = new GUITextBlock(
+ new Rectangle(40, 0, 0, 25),
+ text,
+ Color.Transparent, Color.White,
+ Alignment.Left, Alignment.Left,
+ null, frame, false);
+ textBlock.Font = GUI.SmallFont;
+ textBlock.Padding = new Vector4(5.0f, 0.0f, 5.0f, 0.0f);
+
+ new GUIImage(new Rectangle(-10, -5, 0, 0), HeadSprite, Alignment.Left, frame);
+
+ return frame;
+ }
+
public void UpdateCharacterItems()
{
pickedItems.Clear();
diff --git a/Subsurface/Source/Characters/Jobs/Job.cs b/Subsurface/Source/Characters/Jobs/Job.cs
index 24aad1fd9..6908e1223 100644
--- a/Subsurface/Source/Characters/Jobs/Job.cs
+++ b/Subsurface/Source/Characters/Jobs/Job.cs
@@ -44,11 +44,6 @@ namespace Barotrauma
get { return skills.Values.ToList(); }
}
- //public List SkillLevels
- //{
- // get { return skills.Values.ToList(); }
- //}
-
public Job(JobPrefab jobPrefab)
{
prefab = jobPrefab;
diff --git a/Subsurface/Source/Characters/Jobs/JobPrefab.cs b/Subsurface/Source/Characters/Jobs/JobPrefab.cs
index 677635c36..aee18aac6 100644
--- a/Subsurface/Source/Characters/Jobs/JobPrefab.cs
+++ b/Subsurface/Source/Characters/Jobs/JobPrefab.cs
@@ -9,26 +9,7 @@ namespace Barotrauma
class JobPrefab
{
public static List List;
-
- string name;
- string description;
-
- //how many crew members can have the job (only one captain etc)
- private int maxNumber;
-
- //how many crew members are REQUIRED to have a job
- //(i.e. if one captain is required, one captain is chosen even if all the players have set captain to lowest preference)
- private int minNumber;
-
- private float commonness;
-
- //if set to true, a client that has chosen this as their preferred job will get it no matter what
- public bool AllowAlways
- {
- get;
- private set;
- }
-
+
//names of the items the Character spawns with
public List ItemNames;
public List EquipItem;
@@ -37,39 +18,55 @@ namespace Barotrauma
public string Name
{
- get { return name; }
+ get;
+ private set;
}
public string Description
{
- get { return description; }
+ get;
+ private set;
}
+
+ //if set to true, a client that has chosen this as their preferred job will get it no matter what
+ public bool AllowAlways
+ {
+ get;
+ private set;
+ }
+
+ //how many crew members can have the job (only one captain etc)
public int MaxNumber
{
- get { return maxNumber; }
+ get;
+ private set;
}
+ //how many crew members are REQUIRED to have the job
+ //(i.e. if one captain is required, one captain is chosen even if all the players have set captain to lowest preference)
public int MinNumber
{
- get { return minNumber; }
+ get;
+ private set;
}
public float Commonness
{
- get { return commonness; }
+ get;
+ private set;
}
public JobPrefab(XElement element)
{
- name = ToolBox.GetAttributeString(element, "name", "name not found");
+ Name = ToolBox.GetAttributeString(element, "name", "name not found");
- description = ToolBox.GetAttributeString(element, "description", "");
+ Description = ToolBox.GetAttributeString(element, "description", "");
- minNumber = ToolBox.GetAttributeInt(element, "minnumber", 0);
- maxNumber = ToolBox.GetAttributeInt(element, "maxnumber", 10);
+ MinNumber = ToolBox.GetAttributeInt(element, "minnumber", 0);
+ MaxNumber = ToolBox.GetAttributeInt(element, "maxnumber", 10);
- commonness = ToolBox.GetAttributeInt(element, "commonness", 10);
+ Commonness = ToolBox.GetAttributeInt(element, "commonness", 10);
AllowAlways = ToolBox.GetAttributeBool(element, "allowalways", false);
@@ -117,9 +114,9 @@ namespace Barotrauma
GUIFrame frame = new GUIFrame(new Rectangle(GameMain.GraphicsWidth / 2 - width / 2, GameMain.GraphicsHeight / 2 - height / 2, width, height), GUI.Style, backFrame);
frame.Padding = new Vector4(30.0f, 30.0f, 30.0f, 30.0f);
- new GUITextBlock(new Rectangle(0,0,100,20), name, GUI.Style, Alignment.TopLeft, Alignment.TopLeft, frame, false, GUI.LargeFont);
+ new GUITextBlock(new Rectangle(0,0,100,20), Name, GUI.Style, Alignment.TopLeft, Alignment.TopLeft, frame, false, GUI.LargeFont);
- var descriptionBlock = new GUITextBlock(new Rectangle(0, 40, 0, 0), description, GUI.Style, Alignment.TopLeft, Alignment.TopLeft, frame, true, GUI.SmallFont);
+ var descriptionBlock = new GUITextBlock(new Rectangle(0, 40, 0, 0), Description, GUI.Style, Alignment.TopLeft, Alignment.TopLeft, frame, true, GUI.SmallFont);
new GUITextBlock(new Rectangle(0, 40 + descriptionBlock.Rect.Height + 20, 100, 20), "Skills: ", GUI.Style, Alignment.TopLeft, Alignment.TopLeft, frame, false, GUI.LargeFont);
diff --git a/Subsurface/Source/DebugConsole.cs b/Subsurface/Source/DebugConsole.cs
index 8226cec06..54e6a579d 100644
--- a/Subsurface/Source/DebugConsole.cs
+++ b/Subsurface/Source/DebugConsole.cs
@@ -41,7 +41,10 @@ namespace Barotrauma
public static bool IsOpen
{
- get { return isOpen; }
+ get
+ {
+ return isOpen;
+ }
}
public static void Init(GameWindow window)
@@ -72,6 +75,7 @@ namespace Barotrauma
}
else
{
+ GUIComponent.MouseOn = null;
textBox.Deselect();
}
@@ -80,10 +84,8 @@ namespace Barotrauma
if (isOpen)
{
-
frame.Update(deltaTime);
-
Character.DisableControls = true;
if (PlayerInput.KeyHit(Keys.Up))
diff --git a/Subsurface/Source/GameSession/CrewManager.cs b/Subsurface/Source/GameSession/CrewManager.cs
index b1b5650e8..3c0c51a56 100644
--- a/Subsurface/Source/GameSession/CrewManager.cs
+++ b/Subsurface/Source/GameSession/CrewManager.cs
@@ -85,24 +85,28 @@ namespace Barotrauma
characterInfos.Add(character.Info);
}
- GUIFrame frame = new GUIFrame(new Rectangle(0, 0, 0, 40), Color.Transparent, null, listBox);
- frame.UserData = character;
- frame.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f);
- frame.HoverColor = Color.LightGray * 0.5f;
- frame.SelectedColor = Color.Gold * 0.5f;
+ commander.UpdateCharacters();
- string name = character.Info.Name.Replace(' ', '\n');
+ character.Info.CreateCharacterFrame(listBox, character.Info.Name.Replace(' ', '\n'), character);
- GUITextBlock textBlock = new GUITextBlock(
- new Rectangle(40, 0, 0, 25),
- name,
- Color.Transparent, Color.White,
- Alignment.Left, Alignment.Left,
- null, frame, false);
- textBlock.Font = GUI.SmallFont;
- textBlock.Padding = new Vector4(5.0f, 0.0f, 5.0f, 0.0f);
+ //GUIFrame frame = new GUIFrame(new Rectangle(0, 0, 0, 40), Color.Transparent, null, listBox);
+ //frame.UserData = character;
+ //frame.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f);
+ //frame.HoverColor = Color.LightGray * 0.5f;
+ //frame.SelectedColor = Color.Gold * 0.5f;
- new GUIImage(new Rectangle(-10, -5, 0, 0), character.AnimController.Limbs[0].sprite, Alignment.Left, frame);
+ //string name = character.Info.Name.Replace(' ', '\n');
+
+ //GUITextBlock textBlock = new GUITextBlock(
+ // new Rectangle(40, 0, 0, 25),
+ // name,
+ // Color.Transparent, Color.White,
+ // Alignment.Left, Alignment.Left,
+ // null, frame, false);
+ //textBlock.Font = GUI.SmallFont;
+ //textBlock.Padding = new Vector4(5.0f, 0.0f, 5.0f, 0.0f);
+
+ //new GUIImage(new Rectangle(-10, -5, 0, 0), character.AnimController.Limbs[0].sprite, Alignment.Left, frame);
}
public void Update(float deltaTime)
@@ -123,6 +127,9 @@ namespace Barotrauma
GUIComponent characterBlock = listBox.GetChild(killedCharacter) as GUIComponent;
if (characterBlock != null) characterBlock.Color = Color.DarkRed * 0.5f;
+
+ commander.UpdateCharacters();
+
//if (characters.Find(c => !c.IsDead)==null)
//{
// Game1.GameSession.EndShift(null, null);
diff --git a/Subsurface/Source/GameSession/HireManager.cs b/Subsurface/Source/GameSession/HireManager.cs
index ce3aa1608..60043908b 100644
--- a/Subsurface/Source/GameSession/HireManager.cs
+++ b/Subsurface/Source/GameSession/HireManager.cs
@@ -12,13 +12,15 @@ namespace Barotrauma
{
availableCharacters = new List();
}
-
- public void GenerateCharacters(string file, int amount)
- {
-
+
+ public void GenerateCharacters(Location location, int amount)
+ {
for (int i = 0 ; i GetButtons()
- {
- ConnectionPanel connectionPanel = Item.GetComponent();
- if (connectionPanel == null) return new List();
-
- List buttons = new List();
-
- foreach (Connection c in connectionPanel.Connections)
- {
- foreach (Wire w in c.Wires)
- {
- if (w == null) continue;
- var otherConnection = w.OtherConnection(c);
-
- if (otherConnection.Item == Item || otherConnection == null) continue;
-
- var controller = otherConnection.Item.GetComponent();
- if (controller != null) buttons.Add(controller);
- }
- }
-
- return buttons;
- }
-
+
public override void Draw(SpriteBatch spriteBatch, bool editing)
{
Color color = (item.IsSelected) ? Color.Green : Color.White;
diff --git a/Subsurface/Source/Items/Components/ItemComponent.cs b/Subsurface/Source/Items/Components/ItemComponent.cs
index 7f4f750f8..7476bc20c 100644
--- a/Subsurface/Source/Items/Components/ItemComponent.cs
+++ b/Subsurface/Source/Items/Components/ItemComponent.cs
@@ -38,8 +38,7 @@ namespace Barotrauma.Items.Components
///
/// The base class for components holding the different functionalities of the item
///
- class
- ItemComponent : IPropertyObject
+ class ItemComponent : IPropertyObject
{
protected Item item;
@@ -400,6 +399,13 @@ namespace Barotrauma.Items.Components
/// A vector that can be used to pass additional information to the components
public virtual void ItemActivate(Item item, Vector2 modifier) { }
+
+ /// true if the operation was completed
+ public virtual bool AIOperate(float deltaTime, Character character, AIObjective objective)
+ {
+ return false;
+ }
+
//called when isActive is true and condition > 0.0f
public virtual void Update(float deltaTime, Camera cam) { }
diff --git a/Subsurface/Source/Items/Components/ItemContainer.cs b/Subsurface/Source/Items/Components/ItemContainer.cs
index 0babebb28..8021ae386 100644
--- a/Subsurface/Source/Items/Components/ItemContainer.cs
+++ b/Subsurface/Source/Items/Components/ItemContainer.cs
@@ -86,6 +86,11 @@ namespace Barotrauma.Items.Components
}
private int slotsPerRow;
+ public List ContainableItems
+ {
+ get { return containableItems; }
+ }
+
public ItemContainer(Item item, XElement element)
: base (item, element)
{
diff --git a/Subsurface/Source/Items/Components/Machines/Reactor.cs b/Subsurface/Source/Items/Components/Machines/Reactor.cs
index 5a4acda62..1f3ee98fa 100644
--- a/Subsurface/Source/Items/Components/Machines/Reactor.cs
+++ b/Subsurface/Source/Items/Components/Machines/Reactor.cs
@@ -311,12 +311,44 @@ namespace Barotrauma.Items.Components
new Vector2(10, 40 * (temperature / 10000.0f)), new Color(temperature / 10000.0f, 1.0f - (temperature / 10000.0f), 0.0f, 1.0f), true);
}
+ public override bool AIOperate(float deltaTime, Character character, AIObjective objective)
+ {
+ switch (objective.Option.ToLower())
+ {
+ case "power up":
+ float tempDiff = load - temperature;
- bool valueChanged = false;
+ shutDownTemp = Math.Min(load + 1000.0f, 7500.0f);
+
+ //temperature too high/low
+ if (Math.Abs(tempDiff)>500.0f)
+ {
+ autoTemp = false;
+ FissionRate += deltaTime * 100.0f * Math.Sign(tempDiff);
+ CoolingRate -= deltaTime * 100.0f * Math.Sign(tempDiff);
+ }
+ //temperature OK
+ else
+ {
+ autoTemp = true;
+ }
+
+ break;
+ case "shutdown":
+
+ shutDownTemp = 0.0f;
+
+ break;
+ }
+
+ return false;
+ }
+
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
{
IsActive = true;
+ bool valueChanged = false;
int width = GuiFrame.Rect.Width, height = GuiFrame.Rect.Height;
int x = GuiFrame.Rect.X;
@@ -398,7 +430,6 @@ namespace Barotrauma.Items.Components
if (valueChanged)
{
item.NewComponentEvent(this, true, false);
- valueChanged = false;
}
}
diff --git a/Subsurface/Source/Items/Components/Power/PowerContainer.cs b/Subsurface/Source/Items/Components/Power/PowerContainer.cs
index 43f78eefc..47612f831 100644
--- a/Subsurface/Source/Items/Components/Power/PowerContainer.cs
+++ b/Subsurface/Source/Items/Components/Power/PowerContainer.cs
@@ -156,6 +156,13 @@ namespace Barotrauma.Items.Components
voltage = 0.0f;
}
+ public override bool AIOperate(float deltaTime, Character character, AIObjective objective)
+ {
+ RechargeSpeed = maxRechargeSpeed * 0.5f;
+
+ return true;
+ }
+
public override void Draw(SpriteBatch spriteBatch, bool editing)
{
base.Draw(spriteBatch);
diff --git a/Subsurface/Source/Items/Components/Turret.cs b/Subsurface/Source/Items/Components/Turret.cs
index 142ce006c..b0a9404cc 100644
--- a/Subsurface/Source/Items/Components/Turret.cs
+++ b/Subsurface/Source/Items/Components/Turret.cs
@@ -127,67 +127,161 @@ namespace Barotrauma.Items.Components
{
if (reload > 0.0f) return false;
- Projectile projectileComponent = null;
- //search for a projectile from linked containers
- Item projectile = null;
- Item projectileContainer = null;
- foreach (MapEntity e in item.linkedTo)
- {
- projectileContainer = e as Item;
- if (projectileContainer == null) continue;
-
- ItemContainer containerComponent = projectileContainer.GetComponent();
- if (containerComponent == null) continue;
-
- for (int i = 0; i < containerComponent.inventory.Items.Length; i++)
- {
- if (containerComponent.inventory.Items[i] == null) continue;
- if ((projectileComponent = containerComponent.inventory.Items[i].GetComponent()) != null)
- {
- projectile = containerComponent.inventory.Items[i];
- break;
- }
- }
-
- if (projectileComponent != null) break;
- }
-
- if (projectile == null || projectileComponent == null) return false;
+ var projectiles = GetLoadedProjectiles(true);
+ if (projectiles.Count == 0) return false;
+ if (GetAvailablePower() < currPowerConsumption) return false;
+
+ var batteries = item.GetConnectedComponents();
float availablePower = 0.0f;
- //List batteries = new List();
- foreach (Connection c in item.Connections)
+ foreach (PowerContainer battery in batteries)
{
- foreach (Connection c2 in c.Recipients)
- {
- if (c2 == null || c2.Item == null) continue;
+ float batteryPower = Math.Min(battery.Charge, battery.MaxOutPut);
+ float takePower = Math.Min(currPowerConsumption - availablePower, batteryPower);
- PowerContainer batteryComponent = c2.Item.GetComponent();
- if (batteryComponent == null) continue;
-
- float batteryPower = Math.Min(batteryComponent.Charge, batteryComponent.MaxOutPut);
- float takePower = Math.Min(currPowerConsumption - availablePower, batteryPower);
-
- batteryComponent.Charge -= takePower;
- availablePower += takePower;
- }
+ battery.Charge -= takePower;
}
- reload = reloadTime;
-
- if (availablePower < currPowerConsumption) return false;
-
+ reload = reloadTime;
+
+ Item projectile = projectiles[0].Item;
+
projectile.body.ResetDynamics();
projectile.body.Enabled = true;
projectile.SetTransform(ConvertUnits.ToSimUnits(new Vector2(item.Rect.X + barrelPos.X, item.Rect.Y - barrelPos.Y)), -rotation);
- projectileComponent.Use(deltaTime);
- projectileContainer.RemoveContained(projectile);
+ projectiles[0].Use(deltaTime);
+ if (projectile.container != null) projectile.container.RemoveContained(projectile);
return true;
}
+ public override bool AIOperate(float deltaTime, Character character, AIObjective objective)
+ {
+ var projectiles = GetLoadedProjectiles();
+
+ if (projectiles.Count==0 || (projectiles.Count==1 && objective.Option.ToLower()=="hold fire"))
+ {
+ ItemContainer container = null;
+ foreach (MapEntity e in item.linkedTo)
+ {
+ var containerItem = e as Item;
+ if (containerItem == null) continue;
+
+ container = containerItem.GetComponent();
+ if (container != null) break;
+ }
+
+ if (container == null || container.ContainableItems.Count==0) return true;
+
+ objective.AddSubObjective(new AIObjectiveContainItem(character, container.ContainableItems[0].Names[0], container));
+ return false;
+ }
+ else if (GetAvailablePower() < powerConsumption)
+ {
+ var batteries = item.GetConnectedComponents();
+
+ float lowestCharge = 0.0f;
+ PowerContainer batteryToLoad = null;
+ foreach (PowerContainer battery in batteries)
+ {
+ if (batteryToLoad==null || battery.Charge < lowestCharge)
+ {
+ batteryToLoad = battery;
+ lowestCharge = battery.Charge;
+ }
+ }
+
+ if (batteryToLoad == null) return true;
+
+ if (batteryToLoad.RechargeSpeed < batteryToLoad.MaxRechargeSpeed*0.4f)
+ {
+ objective.AddSubObjective(new AIObjectiveOperateItem(batteryToLoad, character, ""));
+ return false;
+ }
+
+
+ }
+
+ //enough shells and power
+
+ Character closestEnemy = null;
+ float closestDist = 3000.0f;
+ foreach (Character enemy in Character.CharacterList)
+ {
+ //ignore humans and characters that are inside the sub
+ if (enemy.IsDead || enemy.SpeciesName == "human" || enemy.AnimController.CurrentHull != null) continue;
+
+ float dist = Vector2.Distance(enemy.Position, item.Position);
+ if (dist < closestDist)
+ {
+ closestEnemy = enemy;
+ closestDist = dist;
+ }
+ }
+
+ if (closestEnemy == null) return false;
+
+ character.CursorPosition = closestEnemy.Position;
+ SecondaryUse(deltaTime, character);
+
+ float enemyAngle = MathUtils.VectorToAngle(closestEnemy.Position-item.Position);
+ float turretAngle = -(rotation - MathHelper.TwoPi);
+
+ if (Math.Abs(enemyAngle - turretAngle) > 0.01f) return false;
+
+ var pickedBody = Submarine.PickBody(item.SimPosition, closestEnemy.SimPosition, null);
+ if (pickedBody != null && pickedBody.UserData as Limb == null) return false;
+
+ Use(deltaTime, character);
+
+
+ return false;
+
+ }
+
+ private float GetAvailablePower()
+ {
+ var batteries = item.GetConnectedComponents();
+
+ float availablePower = 0.0f;
+ foreach (PowerContainer battery in batteries)
+ {
+ float batteryPower = Math.Min(battery.Charge, battery.MaxOutPut);
+
+ availablePower += batteryPower;
+ }
+
+ return availablePower;
+ }
+
+ private List GetLoadedProjectiles(bool returnFirst = false)
+ {
+ List projectiles = new List();
+
+ foreach (MapEntity e in item.linkedTo)
+ {
+ var projectileContainer = e as Item;
+ if (projectileContainer == null) continue;
+
+ var containedItems = projectileContainer.ContainedItems;
+ if (containedItems == null) continue;
+
+ for (int i = 0; i < containedItems.Length; i++)
+ {
+ var projectileComponent = containedItems[i].GetComponent();
+ if (projectileComponent != null)
+ {
+ projectiles.Add(projectileComponent);
+ if (returnFirst) return projectiles;
+ }
+ }
+ }
+
+ return projectiles;
+ }
+
public override void ReceiveSignal(string signal, Connection connection, Item sender, float power)
{
switch (connection.Name)
diff --git a/Subsurface/Source/Items/Item.cs b/Subsurface/Source/Items/Item.cs
index 7609969bc..8f4177483 100644
--- a/Subsurface/Source/Items/Item.cs
+++ b/Subsurface/Source/Items/Item.cs
@@ -681,7 +681,7 @@ namespace Barotrauma
private GUIComponent CreateEditingHUD(bool inGame=false)
{
- int width = 500;
+ int width = 400;
int x = GameMain.GraphicsWidth/2-width/2, y = 10;
List editableProperties = inGame ? GetProperties() : GetProperties();
@@ -786,6 +786,26 @@ namespace Barotrauma
}
}
+ public List GetConnectedComponents()
+ {
+ ConnectionPanel connectionPanel = GetComponent();
+ if (connectionPanel == null) return new List();
+
+ List connectedComponents = new List();
+
+ foreach (Connection c in connectionPanel.Connections)
+ {
+ var recipients = c.Recipients;
+ foreach (Connection recipient in recipients)
+ {
+ var component = recipient.Item.GetComponent();
+ if (component != null) connectedComponents.Add(component);
+ }
+ }
+
+ return connectedComponents;
+ }
+
public void SendSignal(string signal, string connectionName, float power = 0.0f)
{
ConnectionPanel panel = GetComponent();
@@ -862,6 +882,18 @@ namespace Barotrauma
return closest;
}
+ public bool IsInsideTrigger(Vector2 position)
+ {
+ foreach (Rectangle trigger in prefab.Triggers)
+ {
+ Rectangle transformedTrigger = TransformTrigger(trigger);
+
+ if (Submarine.RectContains(transformedTrigger, position)) return true;
+ }
+
+ return false;
+ }
+
public bool Pick(Character picker, bool ignoreRequiredItems=false, bool forceSelectKey=false, bool forceActionKey=false)
{
diff --git a/Subsurface/Source/Map/FireSource.cs b/Subsurface/Source/Map/FireSource.cs
index 8785da854..41dfc3d87 100644
--- a/Subsurface/Source/Map/FireSource.cs
+++ b/Subsurface/Source/Map/FireSource.cs
@@ -151,13 +151,17 @@ namespace Barotrauma
if (size.X < 100.0f) continue;
- var smokeParticle = GameMain.ParticleManager.CreateParticle("smoke",
+ if (Rand.Int(5) == 1)
+ {
+ var smokeParticle = GameMain.ParticleManager.CreateParticle("smoke",
spawnPos, speed, 0.0f, hull);
- if (smokeParticle != null)
- {
- smokeParticle.Size *= MathHelper.Clamp(size.X / 100.0f * Math.Max(hull.Oxygen / hull.FullVolume, 0.4f), 0.5f, 4.0f);
+ if (smokeParticle != null)
+ {
+ smokeParticle.Size *= MathHelper.Clamp(size.X / 100.0f * Math.Max(hull.Oxygen / hull.FullVolume, 0.4f), 0.5f, 4.0f);
+ }
}
+
}
DamageCharacters(deltaTime);
@@ -166,7 +170,7 @@ namespace Barotrauma
if (hull.Volume > 0.0f) HullWaterExtinquish(deltaTime);
lightSource.Range = Math.Max(size.X, size.Y) * Rand.Range(8.0f, 10.0f)/2.0f;
- lightSource.Color = new Color(1.0f, 0.9f, 0.6f) * Rand.Range(0.8f, 1.0f);
+ lightSource.Color = new Color(1.0f, 0.45f, 0.3f) * Rand.Range(0.8f, 1.0f);
hull.Oxygen -= size.X*deltaTime*OxygenConsumption;
diff --git a/Subsurface/Source/Map/Location.cs b/Subsurface/Source/Map/Location.cs
index 7e5e067b6..f12e51c4f 100644
--- a/Subsurface/Source/Map/Location.cs
+++ b/Subsurface/Source/Map/Location.cs
@@ -52,7 +52,7 @@ namespace Barotrauma
if (type.HasHireableCharacters)
{
hireManager = new HireManager();
- hireManager.GenerateCharacters(Character.HumanConfigFile, 10);
+ hireManager.GenerateCharacters(this, 10);
}
Connections = new List();
diff --git a/Subsurface/Source/Map/LocationType.cs b/Subsurface/Source/Map/LocationType.cs
index 64f94b397..a75c36dc0 100644
--- a/Subsurface/Source/Map/LocationType.cs
+++ b/Subsurface/Source/Map/LocationType.cs
@@ -24,11 +24,9 @@ namespace Barotrauma
private Sprite backGround;
- public bool HasHireableCharacters
- {
- get;
- private set;
- }
+ //
+ private List> hireableJobs;
+ private float totalHireableWeight;
public string Name
{
@@ -40,6 +38,11 @@ namespace Barotrauma
get { return nameFormats; }
}
+ public bool HasHireableCharacters
+ {
+ get { return hireableJobs.Any(); }
+ }
+
public Sprite Sprite
{
get { return symbolSprite; }
@@ -57,21 +60,51 @@ namespace Barotrauma
commonness = ToolBox.GetAttributeInt(element, "commonness", 1);
totalWeight += commonness;
- HasHireableCharacters = ToolBox.GetAttributeBool(element, "hireablecharacters", false);
-
nameFormats = new List();
foreach (XAttribute nameFormat in element.Element("nameformats").Attributes())
{
nameFormats.Add(nameFormat.Value);
}
+ hireableJobs = new List>();
+ foreach (XElement subElement in element.Elements())
+ {
+ if (subElement.Name.ToString().ToLower() != "hireable") continue;
+
+ string jobName = ToolBox.GetAttributeString(subElement, "name", "");
+
+ JobPrefab jobPrefab = JobPrefab.List.Find(jp => jp.Name.ToLower() == jobName.ToLower());
+ if (jobPrefab==null)
+ {
+ DebugConsole.ThrowError("Invalid job name ("+jobName+") in location type "+name);
+ }
+
+ float jobCommonness = ToolBox.GetAttributeFloat(subElement, "commonness", 1.0f);
+ totalHireableWeight += jobCommonness;
+
+ Tuple hireableJob = new Tuple(jobPrefab, jobCommonness);
+
+ hireableJobs.Add(hireableJob);
+ }
+
string spritePath = ToolBox.GetAttributeString(element, "symbol", "Content/Map/beaconSymbol.png");
symbolSprite = new Sprite(spritePath, new Vector2(0.5f, 0.5f));
string backgroundPath = ToolBox.GetAttributeString(element, "background", "");
backGround = new Sprite(backgroundPath, Vector2.Zero);
- //sprite.Origin = ;
+ }
+ public JobPrefab GetRandomHireable()
+ {
+ float randFloat = Rand.Range(0.0f, totalHireableWeight);
+
+ foreach (Tuple hireable in hireableJobs)
+ {
+ if (randFloat < hireable.Item2) return hireable.Item1;
+ randFloat -= hireable.Item2;
+ }
+
+ return null;
}
public static LocationType Random()
diff --git a/Subsurface/Source/Networking/GameServerSettings.cs b/Subsurface/Source/Networking/GameServerSettings.cs
index 7c5b05e3b..ee30ec613 100644
--- a/Subsurface/Source/Networking/GameServerSettings.cs
+++ b/Subsurface/Source/Networking/GameServerSettings.cs
@@ -85,7 +85,7 @@ namespace Barotrauma.Networking
var selectionFrame = new GUIFrame(new Rectangle(0, 60, 300, 20), null, innerFrame);
for (int i = 0; i<3; i++)
{
- var selectionTick = new GUITickBox(new Rectangle(i * 100, 00, 20, 20), ((SelectionMode)i).ToString(), Alignment.Left, selectionFrame);
+ var selectionTick = new GUITickBox(new Rectangle(i * 100, 0, 20, 20), ((SelectionMode)i).ToString(), Alignment.Left, selectionFrame);
selectionTick.Selected = i == (int)subSelectionMode;
selectionTick.OnSelected = SwitchSubSelection;
selectionTick.UserData = (SelectionMode)i;
@@ -100,14 +100,11 @@ namespace Barotrauma.Networking
selectionTick.OnSelected = SwitchModeSelection;
selectionTick.UserData = (SelectionMode)i;
}
-
-
- var allowSpecBox = new GUITickBox(new Rectangle(0, 0, 20, 20), "Allow spectating", Alignment.Left, innerFrame);
- allowSpecBox.Selected = true;
- allowSpecBox.OnSelected = ToggleAllowSpectating;
-
-
+ var allowSpecBox = new GUITickBox(new Rectangle(0, 150, 20, 20), "Allow spectating", Alignment.Left, innerFrame);
+ allowSpecBox.Selected = true;
+ allowSpecBox.OnSelected = ToggleAllowSpectating;
+
var closeButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Close", Alignment.BottomRight, GUI.Style, innerFrame);
closeButton.OnClicked = ToggleSettingsFrame;
}
diff --git a/Subsurface/Source/Screens/LobbyScreen.cs b/Subsurface/Source/Screens/LobbyScreen.cs
index efe223844..d1f02bf5d 100644
--- a/Subsurface/Source/Screens/LobbyScreen.cs
+++ b/Subsurface/Source/Screens/LobbyScreen.cs
@@ -144,12 +144,12 @@ namespace Barotrauma
itemList = new GUIListBox(new Rectangle(0, 0, sellColumnWidth, 400), Color.White * 0.7f, Alignment.TopRight, GUI.Style, bottomPanel[(int)PanelTab.Store]);
itemList.OnSelected = SelectItem;
- foreach (MapEntityPrefab ep in MapEntityPrefab.list)
- {
- if (ep.Price == 0) continue;
+ foreach (MapEntityPrefab ep in MapEntityPrefab.list)
+ {
+ if (ep.Price == 0) continue;
- CreateItemFrame(ep, itemList);
- }
+ CreateItemFrame(ep, itemList);
+ }
}
public override void Select()
@@ -158,7 +158,16 @@ namespace Barotrauma
gameMode = GameMain.GameSession.gameMode as SinglePlayerMode;
- //Map.Unload();
+ foreach (GUIComponent component in topPanel.children)
+ {
+ var button = component as GUIButton;
+ if (button == null || button.Text != "Hire") continue;
+
+ button.Enabled = GameMain.GameSession.Map.CurrentLocation.Type.HasHireableCharacters;
+ break;
+ }
+ //hireButton.Enabled = location.Type.HasHireableCharacters;
+
UpdateCharacterLists();
}
@@ -173,6 +182,7 @@ namespace Barotrauma
locationTitle.Font = GUI.LargeFont;
bottomPanel[(int)PanelTab.CurrentLocation].ClearChildren();
+ bottomPanel[(int)PanelTab.CurrentLocation].UserData = location;
//rightPanel[(int)PanelTab.Hire].Padding = GUI.style.smallPadding;
//for (int i = 0; i < Enum.GetNames(typeof(PanelTab)).Length; i++ )
@@ -208,16 +218,18 @@ namespace Barotrauma
hireList.ClearChildren();
foreach (CharacterInfo c in location.HireManager.availableCharacters)
{
- GUITextBlock textBlock = new GUITextBlock(
- new Rectangle(0, 0, 0, 25),
- c.Name + " (" + c.Job.Name + ")", GUI.Style, hireList);
- textBlock.UserData = c;
+ var frame = c.CreateCharacterFrame(hireList, c.Name + " (" + c.Job.Name + ")", c);
- textBlock = new GUITextBlock(
+ //GUITextBlock textBlock = new GUITextBlock(
+ // new Rectangle(0, 0, 0, 25),
+ // c.Name + " (" + c.Job.Name + ")", GUI.Style, hireList);
+ //textBlock.UserData = c;
+
+ var textBlock = new GUITextBlock(
new Rectangle(0, 0, 0, 25),
c.Salary.ToString(),
null, null,
- Alignment.TopRight, GUI.Style, textBlock);
+ Alignment.TopRight, GUI.Style, frame);
}
}
else
@@ -240,22 +252,22 @@ namespace Barotrauma
if (locationPanel != null) bottomPanel[(int)PanelTab.Map].RemoveChild(locationPanel);
- locationPanel = new GUIFrame(new Rectangle(0, 0, 200, 190), Color.Transparent, Alignment.TopRight, null, bottomPanel[(int)PanelTab.Map]);
+ locationPanel = new GUIFrame(new Rectangle(0, 0, 250, 190), Color.Transparent, Alignment.TopRight, null, bottomPanel[(int)PanelTab.Map]);
locationPanel.UserData = "selectedlocation";
if (location == null) return;
- new GUITextBlock(new Rectangle(0,0,0,0), location.Name, Color.Transparent, Color.White, Alignment.TopLeft, null, locationPanel);
+ new GUITextBlock(new Rectangle(0, 0, 0, 0), location.Name, Color.Black * 0.8f, Color.White, Alignment.TopLeft, null, locationPanel).Font = GUI.LargeFont;
if (GameMain.GameSession.Map.SelectedConnection != null && GameMain.GameSession.Map.SelectedConnection.Quest != null)
{
var quest = GameMain.GameSession.Map.SelectedConnection.Quest;
- new GUITextBlock(new Rectangle(0, 40, 0, 20), "Quest: "+quest.Name, Color.Transparent, Color.White, Alignment.TopLeft, null, locationPanel);
-
- new GUITextBlock(new Rectangle(0, 60, 0, 20), "Reward: " + quest.Reward, Color.Transparent, Color.White, Alignment.TopLeft, null, locationPanel);
-
- new GUITextBlock(new Rectangle(0, 80, 0, 0), quest.Description, Color.Transparent, Color.White, Alignment.TopLeft, null, locationPanel, true);
+ new GUITextBlock(new Rectangle(0, 40, 0, 20), "Quest: "+quest.Name, Color.Black*0.8f, Color.White, Alignment.TopLeft, null, locationPanel);
+
+ new GUITextBlock(new Rectangle(0, 60, 0, 20), "Reward: " + quest.Reward, Color.Black * 0.8f, Color.White, Alignment.TopLeft, null, locationPanel);
+
+ new GUITextBlock(new Rectangle(0, 80, 0, 0), quest.Description, Color.Black * 0.8f, Color.White, Alignment.TopLeft, null, locationPanel, true);
}
@@ -269,14 +281,16 @@ namespace Barotrauma
characterList.ClearChildren();
foreach (CharacterInfo c in CrewManager.characterInfos)
{
- GUITextBlock textBlock = new GUITextBlock(
- new Rectangle(0, 0, 0, 25),
- c.Name + " (" + c.Job.Name + ")", GUI.Style,
- Alignment.Left,
- Alignment.Left,
- characterList, false, GameMain.GraphicsWidth<1000 ? GUI.SmallFont : GUI.Font);
- textBlock.Padding = new Vector4(10.0f, 0.0f, 0.0f, 0.0f);
- textBlock.UserData = c;
+ c.CreateCharacterFrame(characterList, c.Name + " ("+c.Job.Name+") ", c);
+
+ //GUITextBlock textBlock = new GUITextBlock(
+ // new Rectangle(0, 0, 0, 25),
+ // c.Name + " (" + c.Job.Name + ")", GUI.Style,
+ // Alignment.Left,
+ // Alignment.Left,
+ // characterList, false, GameMain.GraphicsWidth<1000 ? GUI.SmallFont : GUI.Font);
+ //textBlock.Padding = new Vector4(10.0f, 0.0f, 0.0f, 0.0f);
+ //textBlock.UserData = c;
}
}
@@ -403,7 +417,7 @@ namespace Barotrauma
GameMain.GameSession.Map.Draw(spriteBatch, new Rectangle(
bottomPanel[selectedRightPanel].Rect.X + 20,
bottomPanel[selectedRightPanel].Rect.Y + 20,
- bottomPanel[selectedRightPanel].Rect.Width - 280,
+ bottomPanel[selectedRightPanel].Rect.Width - 310,
bottomPanel[selectedRightPanel].Rect.Height - 40), mapZoom);
}
@@ -449,6 +463,16 @@ namespace Barotrauma
private bool SelectCharacter(GUIComponent component, object selection)
{
+ GUIComponent prevInfoFrame = null;
+ foreach (GUIComponent child in bottomPanel[selectedRightPanel].children)
+ {
+ if (child.UserData as CharacterInfo == null) continue;
+
+ prevInfoFrame = child;
+ }
+
+ if (prevInfoFrame != null) bottomPanel[selectedRightPanel].RemoveChild(prevInfoFrame);
+
CharacterInfo characterInfo = selection as CharacterInfo;
if (characterInfo == null) return false;
diff --git a/Subsurface_Solution.v12.suo b/Subsurface_Solution.v12.suo
index 30a66e032..2a5250160 100644
Binary files a/Subsurface_Solution.v12.suo and b/Subsurface_Solution.v12.suo differ