AI operating reactors & railguns, misc AI improvements
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Barotrauma.Items.Components;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -35,7 +36,11 @@ namespace Barotrauma
|
||||
{
|
||||
IsOpen = !IsOpen;
|
||||
|
||||
if (IsOpen && frame == null) CreateGUIFrame();
|
||||
if (IsOpen)
|
||||
{
|
||||
CreateGUIFrame();
|
||||
UpdateCharacters();
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateGUIFrame()
|
||||
@@ -43,14 +48,64 @@ namespace Barotrauma
|
||||
frame = new GUIFrame(Rectangle.Empty, Color.Black * 0.3f);
|
||||
frame.Padding = new Vector4(200.0f, 100.0f, 200.0f, 100.0f);
|
||||
|
||||
UpdateCharacters();
|
||||
|
||||
int x = 0, y = 150;
|
||||
foreach (Order order in Order.PrefabList)
|
||||
{
|
||||
if (order.ItemComponentType!=null)
|
||||
{
|
||||
var matchingItems = Item.ItemList.FindAll(i => 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<GUIComponent> prevCharacterFrames = new List<GUIComponent>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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<AIObjective>();
|
||||
|
||||
this.character = character;
|
||||
|
||||
this.option = option;
|
||||
|
||||
#if DEBUG
|
||||
IsDuplicate(null);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -37,10 +51,10 @@ namespace Barotrauma
|
||||
/// <param name="character">the character who's trying to achieve the objective</param>
|
||||
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
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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<AITarget> unreachable;
|
||||
private List<Hull> unreachable;
|
||||
|
||||
float currenthullSafety;
|
||||
|
||||
float searchHullTimer;
|
||||
|
||||
public AIObjectiveFindSafety(Character character)
|
||||
: base(character)
|
||||
: base(character, "")
|
||||
{
|
||||
unreachable = new List<AITarget>();
|
||||
unreachable = new List<Hull>();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Barotrauma
|
||||
Gap leak;
|
||||
|
||||
public AIObjectiveFixLeak(Gap leak, Character character)
|
||||
:base (character)
|
||||
:base (character, "")
|
||||
{
|
||||
this.leak = leak;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)<OrderPriority))
|
||||
{
|
||||
currentOrder.TryComplete(deltaTime);
|
||||
return;
|
||||
@@ -81,19 +81,18 @@ namespace Barotrauma
|
||||
|
||||
public void SetOrder(Order order, string option)
|
||||
{
|
||||
currentOrder = null;
|
||||
|
||||
switch (order.Name.ToLower())
|
||||
{
|
||||
case "follow":
|
||||
currentOrder = new AIObjectiveGoTo(Character.Controlled.AiTarget, character, true);
|
||||
break;
|
||||
case "operate reactor":
|
||||
var reactorItem = Item.ItemList.Find(i => i.GetComponent<Reactor>() != null);
|
||||
if (reactorItem == null) return;
|
||||
|
||||
currentOrder = new AIObjectiveOperateItem(reactorItem.GetComponent<Reactor>(), 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Controller>();
|
||||
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)
|
||||
|
||||
@@ -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<Order> List;
|
||||
public static List<Order> 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<Order>();
|
||||
PrefabList = new List<Order>();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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<Controller>();
|
||||
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<Controller>();
|
||||
foreach (Controller button in doorButtons)
|
||||
{
|
||||
if (Math.Sign(button.Item.Position.X - nextNode.Waypoint.Position.X) !=
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,12 @@ namespace Barotrauma
|
||||
get { return currentIndex; }
|
||||
}
|
||||
|
||||
public float Cost
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public WayPoint PrevNode
|
||||
{
|
||||
get
|
||||
|
||||
@@ -131,6 +131,11 @@ namespace Barotrauma
|
||||
public Vector2 CursorPosition
|
||||
{
|
||||
get { return cursorPosition; }
|
||||
set
|
||||
{
|
||||
if (!MathUtils.IsValid(value)) return;
|
||||
cursorPosition = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Character ClosestCharacter
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -44,11 +44,6 @@ namespace Barotrauma
|
||||
get { return skills.Values.ToList(); }
|
||||
}
|
||||
|
||||
//public List<float> SkillLevels
|
||||
//{
|
||||
// get { return skills.Values.ToList(); }
|
||||
//}
|
||||
|
||||
public Job(JobPrefab jobPrefab)
|
||||
{
|
||||
prefab = jobPrefab;
|
||||
|
||||
@@ -9,26 +9,7 @@ namespace Barotrauma
|
||||
class JobPrefab
|
||||
{
|
||||
public static List<JobPrefab> 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<string> ItemNames;
|
||||
public List<bool> 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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user