Updated and refactored how items and characters are chosen for interactions in the world. The new system has more precision, with items under the cursor taking priority (this helps with small items which are in front of large items). A new method CanInteractWith(Item) has been added to the Character class which does all validation of interaction with items, including new distance calculations based on bounding boxes. This gives more consistency in selecting and interacting with all sizes and shapes of items. Because of this pickdistance (not interactdistance) has been removed from all item configurations (in their XML config files) and the default InteractDistance for all items is now 120.
This commit is contained in:
@@ -141,7 +141,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (character.SelectedConstruction != currentPath.CurrentNode.Ladders.Item && currentPath.CurrentNode.Ladders.Item.IsInsideTrigger(character.WorldPosition))
|
||||
{
|
||||
currentPath.CurrentNode.Ladders.Item.Pick(character, false, true);
|
||||
currentPath.CurrentNode.Ladders.Item.TryInteract(character, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ namespace Barotrauma
|
||||
foreach (Controller controller in buttons)
|
||||
{
|
||||
float dist = Vector2.Distance(controller.Item.WorldPosition, character.WorldPosition);
|
||||
if (dist > controller.Item.PickDistance * 2.0f) continue;
|
||||
if (dist > controller.Item.InteractDistance * 2.0f) continue;
|
||||
|
||||
if (dist < closestDist || closestButton == null)
|
||||
{
|
||||
@@ -256,7 +256,7 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
|
||||
closestButton.Item.Pick(character, false, true);
|
||||
closestButton.Item.TryInteract(character, false, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Vector2.Distance(character.Position, container.Item.Position) > container.Item.PickDistance
|
||||
if (Vector2.Distance(character.Position, container.Item.Position) > container.Item.InteractDistance
|
||||
&& !container.Item.IsInsideTrigger(character.Position))
|
||||
{
|
||||
AddSubObjective(new AIObjectiveGoTo(container.Item, character));
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace Barotrauma
|
||||
FindTargetItem();
|
||||
if (targetItem == null || moveToTarget == null) return;
|
||||
|
||||
if (Vector2.Distance(character.Position, moveToTarget.Position) < targetItem.PickDistance*2.0f)
|
||||
if (Vector2.Distance(character.Position, moveToTarget.Position) < targetItem.InteractDistance*2.0f)
|
||||
{
|
||||
int targetSlot = -1;
|
||||
if (equip)
|
||||
@@ -93,7 +93,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
targetItem.Pick(character, false, true);
|
||||
targetItem.TryInteract(character, false, true);
|
||||
|
||||
if (targetSlot > -1 && character.Inventory.IsInLimbSlot(targetItem, InvSlotType.Any))
|
||||
{
|
||||
|
||||
@@ -126,7 +126,7 @@ namespace Barotrauma
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
allowedDistance = Math.Max(ConvertUnits.ToSimUnits(item.PickDistance), allowedDistance);
|
||||
allowedDistance = Math.Max(ConvertUnits.ToSimUnits(item.InteractDistance), allowedDistance);
|
||||
if (item.IsInsideTrigger(character.WorldPosition)) completed = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -53,12 +53,12 @@ namespace Barotrauma
|
||||
|
||||
if (target.CanBeSelected)
|
||||
{
|
||||
if (Vector2.Distance(character.Position, target.Item.Position) < target.Item.PickDistance
|
||||
if (Vector2.Distance(character.Position, target.Item.Position) < target.Item.InteractDistance
|
||||
|| target.Item.IsInsideTrigger(character.WorldPosition))
|
||||
{
|
||||
if (character.SelectedConstruction != target.Item && target.CanBeSelected)
|
||||
{
|
||||
target.Item.Pick(character, false, true);
|
||||
target.Item.TryInteract(character, false, true);
|
||||
}
|
||||
|
||||
if (component.AIOperate(deltaTime, character, this)) isCompleted = true;
|
||||
|
||||
@@ -1270,7 +1270,7 @@ namespace Barotrauma
|
||||
var newSelectedConstruction = (Item)character.MemState[0].Interact;
|
||||
if (newSelectedConstruction != null && character.SelectedConstruction != newSelectedConstruction)
|
||||
{
|
||||
newSelectedConstruction.Pick(character, true, true);
|
||||
newSelectedConstruction.TryInteract(character, true, true);
|
||||
}
|
||||
character.SelectedConstruction = newSelectedConstruction;
|
||||
}
|
||||
@@ -1362,7 +1362,7 @@ namespace Barotrauma
|
||||
var newSelectedConstruction = (Item)serverPos.Interact;
|
||||
if (newSelectedConstruction != null && character.SelectedConstruction != newSelectedConstruction)
|
||||
{
|
||||
newSelectedConstruction.Pick(character, true, true);
|
||||
newSelectedConstruction.TryInteract(character, true, true);
|
||||
}
|
||||
character.SelectedConstruction = newSelectedConstruction;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.Items.Components;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -94,8 +95,8 @@ namespace Barotrauma
|
||||
private float health, lastSentHealth;
|
||||
protected float minHealth, maxHealth;
|
||||
|
||||
protected Item closestItem;
|
||||
private Character closestCharacter, selectedCharacter;
|
||||
protected Item focusedItem;
|
||||
private Character focusedCharacter, selectedCharacter;
|
||||
|
||||
private Dictionary<object, HUDProgressBar> hudProgressBars;
|
||||
|
||||
@@ -184,6 +185,11 @@ namespace Barotrauma
|
||||
get { return !IsUnconscious && Stun <= 0.0f && !isDead; }
|
||||
}
|
||||
|
||||
public bool CanInteract
|
||||
{
|
||||
get { return AllowInput && !LockHands; }
|
||||
}
|
||||
|
||||
public Vector2 CursorPosition
|
||||
{
|
||||
get { return cursorPosition; }
|
||||
@@ -199,9 +205,9 @@ namespace Barotrauma
|
||||
get { return Submarine == null ? cursorPosition : cursorPosition + Submarine.Position; }
|
||||
}
|
||||
|
||||
public Character ClosestCharacter
|
||||
public Character FocusedCharacter
|
||||
{
|
||||
get { return closestCharacter; }
|
||||
get { return focusedCharacter; }
|
||||
}
|
||||
|
||||
public Character SelectedCharacter
|
||||
@@ -421,9 +427,9 @@ namespace Barotrauma
|
||||
set { selectedConstruction = value; }
|
||||
}
|
||||
|
||||
public Item ClosestItem
|
||||
public Item FocusedItem
|
||||
{
|
||||
get { return closestItem; }
|
||||
get { return focusedItem; }
|
||||
}
|
||||
|
||||
public virtual AIController AIController
|
||||
@@ -622,7 +628,7 @@ namespace Barotrauma
|
||||
System.Diagnostics.Debug.Assert(item != null);
|
||||
if (item == null) continue;
|
||||
|
||||
item.Pick(this, true, true, true);
|
||||
item.TryInteract(this, true, true, true);
|
||||
inventory.TryPutItem(item, i, false, false);
|
||||
}
|
||||
}
|
||||
@@ -764,7 +770,7 @@ namespace Barotrauma
|
||||
return (Info==null || Info.Job==null) ? 0 : Info.Job.GetSkillLevel(skillName);
|
||||
}
|
||||
|
||||
float findClosestTimer;
|
||||
float findFocusedTimer;
|
||||
|
||||
public Vector2 GetTargetMovement()
|
||||
{
|
||||
@@ -1003,7 +1009,7 @@ namespace Barotrauma
|
||||
|
||||
public bool CanAccessInventory(Inventory inventory)
|
||||
{
|
||||
if (!AllowInput || LockHands) return false;
|
||||
if (!CanInteract) return false;
|
||||
|
||||
//the inventory belongs to some other character
|
||||
if (inventory.Owner is Character && inventory.Owner != this)
|
||||
@@ -1011,14 +1017,13 @@ namespace Barotrauma
|
||||
var owner = (Character)inventory.Owner;
|
||||
|
||||
//can only be accessed if the character is incapacitated and has been selected
|
||||
return selectedCharacter == owner &&
|
||||
(owner.isDead || owner.IsUnconscious || owner.Stun > 0.0f || owner.LockHands);
|
||||
return selectedCharacter == owner && (!owner.CanInteract);
|
||||
}
|
||||
|
||||
if (inventory.Owner is Item)
|
||||
{
|
||||
var owner = (Item)inventory.Owner;
|
||||
if (!CanAccessItem(owner))
|
||||
if (!CanInteractWith(owner))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -1026,53 +1031,162 @@ namespace Barotrauma
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool CanAccessItem(Item item)
|
||||
public bool CanInteractWith(Item item)
|
||||
{
|
||||
if (!AllowInput || LockHands) return false;
|
||||
float distanceToItem;
|
||||
return CanInteractWith(item, out distanceToItem);
|
||||
}
|
||||
|
||||
public bool CanInteractWith(Item item, out float distanceToItem)
|
||||
{
|
||||
distanceToItem = -1.0f;
|
||||
|
||||
if (!CanInteract) return false;
|
||||
|
||||
if (item.ParentInventory != null)
|
||||
{
|
||||
return CanAccessInventory(item.ParentInventory);
|
||||
}
|
||||
|
||||
float maxDist = item.PickDistance * 1.2f;
|
||||
if (maxDist <= 0.01f)
|
||||
{
|
||||
maxDist = 150.0f;
|
||||
}
|
||||
if (item.InteractDistance == 0.0f && !item.Prefab.Triggers.Any()) return false;
|
||||
|
||||
if (Vector2.DistanceSquared(WorldPosition, item.WorldPosition) < maxDist*maxDist ||
|
||||
item.IsInsideTrigger(WorldPosition))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
Pickable pickableComponent = item.GetComponent<Pickable>();
|
||||
if (pickableComponent != null && (pickableComponent.Picker != null && !pickableComponent.Picker.IsDead)) return false;
|
||||
|
||||
Vector2 characterDirection = Vector2.Transform(Vector2.UnitY, Quaternion.CreateFromAxisAngle(Vector3.UnitZ, AnimController.Collider.Rotation));
|
||||
|
||||
return item.GetComponent<Items.Components.Ladder>() != null;
|
||||
}
|
||||
|
||||
private Item FindClosestItem(Vector2 mouseSimPos, out float distance)
|
||||
{
|
||||
distance = 0.0f;
|
||||
|
||||
Limb torso = AnimController.GetLimb(LimbType.Torso);
|
||||
|
||||
if (torso == null) return null;
|
||||
|
||||
Vector2 pos = (torso.body.TargetPosition != null) ? (Vector2)torso.body.TargetPosition : torso.SimPosition;
|
||||
Vector2 pickPos = mouseSimPos;
|
||||
Vector2 upperBodyPosition = Position + (characterDirection * 20.0f);
|
||||
Vector2 lowerBodyPosition = Position - (characterDirection * 60.0f);
|
||||
|
||||
if (Submarine != null)
|
||||
{
|
||||
pos += Submarine.SimPosition;
|
||||
pickPos += Submarine.SimPosition;
|
||||
upperBodyPosition += Submarine.Position;
|
||||
lowerBodyPosition += Submarine.Position;
|
||||
}
|
||||
|
||||
if (selectedConstruction != null) pickPos = ConvertUnits.ToSimUnits(selectedConstruction.WorldPosition);
|
||||
Vector2 playerDistanceCheckPosition;
|
||||
Rectangle itemDisplayRect;
|
||||
|
||||
return Item.FindPickable(pos, pickPos, AnimController.CurrentHull, selectedItems, out distance);
|
||||
bool insideTrigger = false;
|
||||
if (item.Prefab.Triggers.Any())
|
||||
{
|
||||
foreach (Rectangle trigger in item.Prefab.Triggers)
|
||||
{
|
||||
Rectangle transformedTrigger = new Rectangle(
|
||||
item.WorldRect.X + trigger.X,
|
||||
(item.WorldRect.Y + trigger.Y) - ((trigger.Height == 0) ? item.Rect.Height : trigger.Height),
|
||||
(trigger.Width == 0) ? item.Rect.Width : trigger.Width,
|
||||
(trigger.Height == 0) ? item.Rect.Height : trigger.Height);
|
||||
|
||||
// Get the point along the line between lowerBodyPosition and upperBodyPosition which is closest to the center of itemDisplayRect
|
||||
playerDistanceCheckPosition = Vector2.Clamp(transformedTrigger.Center.ToVector2(), lowerBodyPosition, upperBodyPosition);
|
||||
|
||||
if (!transformedTrigger.Contains(upperBodyPosition)) return false;
|
||||
|
||||
insideTrigger = true;
|
||||
}
|
||||
if (!insideTrigger) return false;
|
||||
}
|
||||
itemDisplayRect = new Rectangle(item.InteractionRect.X, item.InteractionRect.Y - item.InteractionRect.Height, item.InteractionRect.Width, item.InteractionRect.Height);
|
||||
|
||||
// Get the point along the line between lowerBodyPosition and upperBodyPosition which is closest to the center of itemDisplayRect
|
||||
playerDistanceCheckPosition = Vector2.Clamp(itemDisplayRect.Center.ToVector2(), lowerBodyPosition, upperBodyPosition);
|
||||
|
||||
// Here we get the point on the itemDisplayRect which is closest to playerDistanceCheckPosition
|
||||
Vector2 rectIntersectionPoint = new Vector2(Math.Max(itemDisplayRect.X, Math.Min(itemDisplayRect.X + itemDisplayRect.Width, playerDistanceCheckPosition.X)), Math.Max(itemDisplayRect.Y, Math.Min(itemDisplayRect.Y + itemDisplayRect.Height, playerDistanceCheckPosition.Y)));
|
||||
|
||||
// If playerDistanceCheckPosition is inside the itemDisplayRect then we consider the character to within 0 distance of the item
|
||||
if (!itemDisplayRect.Contains(playerDistanceCheckPosition))
|
||||
{
|
||||
distanceToItem = Vector2.Distance(rectIntersectionPoint, playerDistanceCheckPosition);
|
||||
}
|
||||
|
||||
if (distanceToItem > item.InteractDistance && item.InteractDistance > 0.0f) return false;
|
||||
|
||||
if (!item.Prefab.InteractThroughWalls && Screen.Selected != GameMain.EditMapScreen && !insideTrigger)
|
||||
{
|
||||
Vector2 itemPosition = item.SimPosition;
|
||||
if (Submarine == null && item.Submarine != null)
|
||||
{
|
||||
//character is outside, item inside
|
||||
itemPosition += item.Submarine.SimPosition;
|
||||
}
|
||||
else if (Submarine != null && item.Submarine == null)
|
||||
{
|
||||
//character is inside, item outside
|
||||
itemPosition -= Submarine.SimPosition;
|
||||
}
|
||||
else if (Submarine != item.Submarine)
|
||||
{
|
||||
//character and the item are inside different subs
|
||||
itemPosition += item.Submarine.SimPosition;
|
||||
itemPosition -= Submarine.SimPosition;
|
||||
}
|
||||
Body body = Submarine.CheckVisibility(SimPosition, itemPosition, true);
|
||||
if (body != null && body.UserData as Item != item) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private Character FindClosestCharacter(Vector2 mouseSimPos, float maxDist = 150.0f)
|
||||
/// <summary>
|
||||
/// Finds the front (lowest depth) interactable item at a position. "Interactable" in this case means that the character can "reach" the item.
|
||||
/// </summary>
|
||||
/// <param name="character">The Character who is looking for the interactable item, only items that are close enough to this character are returned</param>
|
||||
/// <param name="simPosition">The item at the simPosition, with the lowest depth, is returned</param>
|
||||
/// <param name="allowFindingNearestItem">If this is true and an item cannot be found at simPosition then a nearest item will be returned if possible</param>
|
||||
/// <param name="hull">If a hull is specified, only items within that hull are returned</param>
|
||||
public Item FindItemAtPosition(Vector2 simPosition, float aimAssistModifier = 0.0f, Hull hull = null, Item[] ignoredItems = null)
|
||||
{
|
||||
if (Submarine != null)
|
||||
{
|
||||
simPosition += Submarine.SimPosition;
|
||||
}
|
||||
|
||||
Vector2 displayPosition = ConvertUnits.ToDisplayUnits(simPosition);
|
||||
|
||||
Item highestPriorityItemAtPosition = null;
|
||||
Item closestItem = null;
|
||||
float closestItemDistance = 0.0f;
|
||||
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
if (ignoredItems != null && ignoredItems.Contains(item)) continue;
|
||||
if (item.body != null && !item.body.Enabled) continue;
|
||||
|
||||
if (CanInteractWith(item))
|
||||
{
|
||||
if (item.IsMouseOn(displayPosition))
|
||||
{
|
||||
Console.WriteLine("Name: " + item.Name + " Priority:" + item.InteractPriority);
|
||||
}
|
||||
if (item.IsMouseOn(displayPosition) && (highestPriorityItemAtPosition == null ||
|
||||
((highestPriorityItemAtPosition.InteractPriority < item.InteractPriority) ||
|
||||
(highestPriorityItemAtPosition.InteractPriority == item.InteractPriority && highestPriorityItemAtPosition.GetDrawDepth() > item.GetDrawDepth()))))
|
||||
{
|
||||
highestPriorityItemAtPosition = item;
|
||||
}
|
||||
else if (aimAssistModifier > 0.0f)
|
||||
{
|
||||
float distanceToItem = Vector2.Distance(item.WorldPosition, displayPosition);
|
||||
if (distanceToItem < (100.0f * aimAssistModifier) && (closestItem == null || distanceToItem < closestItemDistance))
|
||||
{
|
||||
closestItem = item;
|
||||
closestItemDistance = distanceToItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (highestPriorityItemAtPosition == null)
|
||||
{
|
||||
return closestItem;
|
||||
}
|
||||
|
||||
return highestPriorityItemAtPosition;
|
||||
}
|
||||
|
||||
private Character FindCharacterAtPosition(Vector2 mouseSimPos, float maxDist = 150.0f)
|
||||
{
|
||||
Character closestCharacter = null;
|
||||
float closestDist = 0.0f;
|
||||
@@ -1081,17 +1195,25 @@ namespace Barotrauma
|
||||
|
||||
foreach (Character c in CharacterList)
|
||||
{
|
||||
if (c == this || !c.enabled) continue;
|
||||
|
||||
if (Vector2.DistanceSquared(SimPosition, c.SimPosition) > maxDist*maxDist) continue;
|
||||
if (c == this || !c.enabled || c.info == null || !c.IsHumanoid || !c.CanBeSelected) continue;
|
||||
|
||||
float dist = Vector2.DistanceSquared(mouseSimPos, c.SimPosition);
|
||||
if (dist < maxDist*maxDist && (closestCharacter==null || dist<closestDist))
|
||||
if (dist < maxDist*maxDist && (closestCharacter == null || dist < closestDist))
|
||||
{
|
||||
closestCharacter = c;
|
||||
closestDist = dist;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*FarseerPhysics.Common.Transform transform;
|
||||
c.AnimController.Collider.FarseerBody.GetTransform(out transform);
|
||||
for (int i = 0; i < c.AnimController.Collider.FarseerBody.FixtureList.Count; i++)
|
||||
{
|
||||
if (c.AnimController.Collider.FarseerBody.FixtureList[i].Shape.TestPoint(ref transform, ref mouseSimPos))
|
||||
{
|
||||
Console.WriteLine("Hit: " + i);
|
||||
closestCharacter = c;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
return closestCharacter;
|
||||
@@ -1140,6 +1262,65 @@ namespace Barotrauma
|
||||
selectedCharacter = null;
|
||||
}
|
||||
|
||||
public void DoInteractionUpdate(float deltaTime, Vector2 mouseSimPos)
|
||||
{
|
||||
bool isLocalPlayer = (controlled == this);
|
||||
if (!isLocalPlayer && (this is AICharacter || !IsRemotePlayer))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!AllowInput || LockHands)
|
||||
{
|
||||
if (selectedCharacter != null)
|
||||
{
|
||||
DeselectCharacter();
|
||||
}
|
||||
selectedConstruction = null;
|
||||
focusedItem = null;
|
||||
focusedCharacter = null;
|
||||
return;
|
||||
}
|
||||
if ((!isLocalPlayer && IsKeyHit(InputType.Select) && GameMain.Server == null) || (isLocalPlayer && (findFocusedTimer <= 0.0f || Screen.Selected == GameMain.EditMapScreen)))
|
||||
{
|
||||
focusedCharacter = FindCharacterAtPosition(mouseSimPos);
|
||||
if (focusedCharacter != null)
|
||||
{
|
||||
focusedItem = null; // We can only focus one thing at a time
|
||||
}
|
||||
else
|
||||
{
|
||||
focusedItem = FindItemAtPosition(mouseSimPos, AnimController.InWater ? 0.5f : 0.25f);
|
||||
}
|
||||
findFocusedTimer = 0.05f;
|
||||
}
|
||||
else
|
||||
{
|
||||
findFocusedTimer -= deltaTime;
|
||||
}
|
||||
|
||||
if (focusedCharacter != null && IsKeyHit(InputType.Select))
|
||||
{
|
||||
if (selectedCharacter != null)
|
||||
{
|
||||
DeselectCharacter();
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectCharacter(focusedCharacter);
|
||||
}
|
||||
}
|
||||
else if (focusedItem != null)
|
||||
{
|
||||
focusedItem.IsHighlighted = true;
|
||||
focusedItem.TryInteract(this);
|
||||
}
|
||||
else if (IsKeyHit(InputType.Select) && selectedConstruction != null)
|
||||
{
|
||||
selectedConstruction = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Control the Character according to player input
|
||||
/// </summary>
|
||||
@@ -1147,7 +1328,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (!DisableControls)
|
||||
{
|
||||
for (int i = 0; i < keys.Length; i++ )
|
||||
for (int i = 0; i < keys.Length; i++)
|
||||
{
|
||||
keys[i].SetState();
|
||||
}
|
||||
@@ -1163,7 +1344,7 @@ namespace Barotrauma
|
||||
|
||||
if (moveCam && needsAir)
|
||||
{
|
||||
if (pressureProtection < 80.0f &&
|
||||
if (pressureProtection < 80.0f &&
|
||||
(AnimController.CurrentHull == null || AnimController.CurrentHull.LethalPressure > 50.0f))
|
||||
{
|
||||
float pressure = AnimController.CurrentHull == null ? 100.0f : AnimController.CurrentHull.LethalPressure;
|
||||
@@ -1197,69 +1378,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
if (!LockHands)
|
||||
{
|
||||
//find the closest item if selectkey has been hit, or if the Character is being
|
||||
//controlled by the player (in order to highlight it)
|
||||
|
||||
if (findClosestTimer <= 0.0f || Screen.Selected == GameMain.EditMapScreen)
|
||||
{
|
||||
closestCharacter = FindClosestCharacter(mouseSimPos);
|
||||
if (closestCharacter != null && closestCharacter.info==null)
|
||||
{
|
||||
closestCharacter = null;
|
||||
}
|
||||
|
||||
float closestItemDist = 0.0f;
|
||||
closestItem = FindClosestItem(mouseSimPos, out closestItemDist);
|
||||
|
||||
if (closestCharacter != null && closestItem != null)
|
||||
{
|
||||
if (Vector2.DistanceSquared(closestCharacter.SimPosition, mouseSimPos) < ConvertUnits.ToSimUnits(closestItemDist)*ConvertUnits.ToSimUnits(closestItemDist))
|
||||
{
|
||||
if (selectedConstruction != closestItem) closestItem = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
closestCharacter = null;
|
||||
}
|
||||
}
|
||||
|
||||
findClosestTimer = 0.1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
findClosestTimer -= deltaTime;
|
||||
}
|
||||
|
||||
if (selectedCharacter == null && closestItem != null)
|
||||
{
|
||||
closestItem.IsHighlighted = true;
|
||||
if (!LockHands && closestItem.Pick(this))
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (IsKeyHit(InputType.Select))
|
||||
{
|
||||
if (selectedCharacter != null)
|
||||
{
|
||||
DeselectCharacter();
|
||||
}
|
||||
else if (closestCharacter != null && closestCharacter.IsHumanoid && closestCharacter.CanBeSelected)
|
||||
{
|
||||
SelectCharacter(closestCharacter);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (selectedCharacter != null) DeselectCharacter();
|
||||
selectedConstruction = null;
|
||||
closestItem = null;
|
||||
closestCharacter = null;
|
||||
}
|
||||
DoInteractionUpdate(deltaTime, mouseSimPos);
|
||||
|
||||
DisableControls = false;
|
||||
}
|
||||
@@ -1424,78 +1543,18 @@ namespace Barotrauma
|
||||
{
|
||||
ControlLocalPlayer(deltaTime, cam);
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector2 mouseSimPos = ConvertUnits.ToSimUnits(cursorPosition);
|
||||
DoInteractionUpdate(deltaTime, mouseSimPos);
|
||||
}
|
||||
|
||||
Control(deltaTime, cam);
|
||||
|
||||
if (selectedConstruction != null && !selectedConstruction.IsInPickRange(WorldPosition))
|
||||
if (selectedConstruction != null && !CanInteractWith(selectedConstruction))
|
||||
{
|
||||
selectedConstruction = null;
|
||||
}
|
||||
|
||||
if (controlled != this && (!(this is AICharacter) || IsRemotePlayer))
|
||||
{
|
||||
if (!LockHands)
|
||||
{
|
||||
Vector2 mouseSimPos = ConvertUnits.ToSimUnits(cursorPosition);
|
||||
|
||||
if (IsKeyHit(InputType.Select) && GameMain.Server==null)
|
||||
{
|
||||
closestCharacter = FindClosestCharacter(mouseSimPos);
|
||||
if (closestCharacter != null && closestCharacter.info == null)
|
||||
{
|
||||
closestCharacter = null;
|
||||
}
|
||||
|
||||
float closestItemDist = 0.0f;
|
||||
closestItem = FindClosestItem(mouseSimPos, out closestItemDist);
|
||||
|
||||
if (closestCharacter != null && closestItem != null)
|
||||
{
|
||||
if (closestItem != null) closestItemDist = (closestItem.Position - AnimController.Collider.Position).Length();
|
||||
if (Vector2.Distance(closestCharacter.SimPosition, mouseSimPos) < ConvertUnits.ToSimUnits(closestItemDist))
|
||||
{
|
||||
if (selectedConstruction != closestItem) closestItem = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
closestCharacter = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedCharacter == null && closestItem != null)
|
||||
{
|
||||
//DebugConsole.NewMessage(closestItem.ToString(), Color.Yellow);
|
||||
//closestItem.IsHighlighted = true;
|
||||
if (!LockHands && closestItem.Pick(this))
|
||||
{
|
||||
if (AnimController.Anim == AnimController.Animation.Climbing)
|
||||
{
|
||||
//DebugConsole.NewMessage("ladder woo",Color.Lime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IsKeyHit(InputType.Select))
|
||||
{
|
||||
if (selectedCharacter != null)
|
||||
{
|
||||
DeselectCharacter();
|
||||
}
|
||||
else if (closestCharacter != null && closestCharacter.IsHumanoid && closestCharacter.CanBeSelected)
|
||||
{
|
||||
SelectCharacter(closestCharacter);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (selectedCharacter != null) DeselectCharacter();
|
||||
selectedConstruction = null;
|
||||
closestItem = null;
|
||||
closestCharacter = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedCharacter != null && AnimController.Anim == AnimController.Animation.CPR)
|
||||
{
|
||||
@@ -1574,6 +1633,21 @@ namespace Barotrauma
|
||||
if (!Enabled) return;
|
||||
|
||||
AnimController.Draw(spriteBatch);
|
||||
|
||||
/*Console.WriteLine("Rotation: " + AnimController.Collider.Rotation);
|
||||
|
||||
Vector2 dir = Vector2.Transform(Vector2.UnitY, Quaternion.CreateFromAxisAngle(Vector3.UnitZ, AnimController.Collider.Rotation));
|
||||
|
||||
Vector2 pos1 = Position + (dir * 20.0f);
|
||||
Vector2 pos2 = Position - (dir * 60.0f);
|
||||
|
||||
if (Submarine != null)
|
||||
{
|
||||
pos1 += Submarine.Position;
|
||||
pos2 += Submarine.Position;
|
||||
}
|
||||
|
||||
GUI.DrawLine(spriteBatch, new Vector2(pos1.X, -pos1.Y), new Vector2(pos2.X, -(pos2.Y)), Color.Green);*/
|
||||
}
|
||||
|
||||
public void DrawHUD(SpriteBatch spriteBatch, Camera cam)
|
||||
@@ -1956,7 +2030,7 @@ namespace Barotrauma
|
||||
|
||||
foreach (Character c in CharacterList)
|
||||
{
|
||||
if (c.closestCharacter == this) c.closestCharacter = null;
|
||||
if (c.focusedCharacter == this) c.focusedCharacter = null;
|
||||
if (c.selectedCharacter == this) c.selectedCharacter = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,27 +182,27 @@ namespace Barotrauma
|
||||
if (cprButton.Visible) cprButton.Draw(spriteBatch);
|
||||
}
|
||||
|
||||
if (character.ClosestCharacter != null && character.ClosestCharacter.CanBeSelected)
|
||||
if (character.FocusedCharacter != null && character.FocusedCharacter.CanBeSelected)
|
||||
{
|
||||
Vector2 startPos = character.DrawPosition + (character.ClosestCharacter.DrawPosition - character.DrawPosition) * 0.7f;
|
||||
Vector2 startPos = character.DrawPosition + (character.FocusedCharacter.DrawPosition - character.DrawPosition) * 0.7f;
|
||||
startPos = cam.WorldToScreen(startPos);
|
||||
|
||||
Vector2 textPos = startPos;
|
||||
textPos -= new Vector2(GUI.Font.MeasureString(character.ClosestCharacter.Info.Name).X / 2, 20);
|
||||
textPos -= new Vector2(GUI.Font.MeasureString(character.FocusedCharacter.Info.Name).X / 2, 20);
|
||||
|
||||
GUI.DrawString(spriteBatch, textPos, character.ClosestCharacter.Info.Name, Color.White, Color.Black, 2);
|
||||
GUI.DrawString(spriteBatch, textPos, character.FocusedCharacter.Info.Name, Color.White, Color.Black, 2);
|
||||
}
|
||||
else if (character.SelectedCharacter == null && character.ClosestItem != null && character.SelectedConstruction == null)
|
||||
else if (character.SelectedCharacter == null && character.FocusedItem != null && character.SelectedConstruction == null)
|
||||
{
|
||||
var hudTexts = character.ClosestItem.GetHUDTexts(character);
|
||||
var hudTexts = character.FocusedItem.GetHUDTexts(character);
|
||||
|
||||
Vector2 startPos = new Vector2((int)(GameMain.GraphicsWidth / 2.0f), GameMain.GraphicsHeight);
|
||||
startPos.Y -= 50 + hudTexts.Count * 25;
|
||||
|
||||
Vector2 textPos = startPos;
|
||||
textPos -= new Vector2((int)GUI.Font.MeasureString(character.ClosestItem.Name).X / 2, 20);
|
||||
textPos -= new Vector2((int)GUI.Font.MeasureString(character.FocusedItem.Name).X / 2, 20);
|
||||
|
||||
GUI.DrawString(spriteBatch, textPos, character.ClosestItem.Name, Color.White, Color.Black * 0.7f, 2);
|
||||
GUI.DrawString(spriteBatch, textPos, character.FocusedItem.Name, Color.White, Color.Black * 0.7f, 2);
|
||||
|
||||
textPos.Y += 30.0f;
|
||||
foreach (ColoredText coloredText in hudTexts)
|
||||
|
||||
@@ -147,13 +147,13 @@ namespace Barotrauma
|
||||
var closestEntity = Entity.FindEntityByID(memInput[memInput.Count - 1].interact);
|
||||
if (closestEntity is Item)
|
||||
{
|
||||
closestItem = (Item)closestEntity;
|
||||
closestCharacter = null;
|
||||
focusedItem = (Item)closestEntity;
|
||||
focusedCharacter = null;
|
||||
}
|
||||
else if (closestEntity is Character)
|
||||
{
|
||||
closestCharacter = (Character)closestEntity;
|
||||
closestItem = null;
|
||||
focusedCharacter = (Character)closestEntity;
|
||||
focusedItem = null;
|
||||
}
|
||||
|
||||
memInput.RemoveAt(memInput.Count - 1);
|
||||
@@ -205,13 +205,13 @@ namespace Barotrauma
|
||||
NetInputMem newMem = new NetInputMem();
|
||||
newMem.states = newInput;
|
||||
newMem.intAim = intAngle;
|
||||
if (closestItem != null)
|
||||
if (focusedItem != null)
|
||||
{
|
||||
newMem.interact = closestItem.ID;
|
||||
newMem.interact = focusedItem.ID;
|
||||
}
|
||||
else if (closestCharacter != null)
|
||||
else if (focusedCharacter != null)
|
||||
{
|
||||
newMem.interact = closestCharacter.ID;
|
||||
newMem.interact = focusedCharacter.ID;
|
||||
}
|
||||
|
||||
memInput.Insert(0, newMem);
|
||||
|
||||
Reference in New Issue
Block a user