v1.5.7.0 (Summer Update)
This commit is contained in:
@@ -785,7 +785,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (item.Container == null || character.Inventory.FindIndex(item.Container) == -1) // Not a subinventory in the character's inventory
|
||||
{
|
||||
if (character.HeldItems.Any(i => i.OwnInventory != null && i.OwnInventory.CanBePut(item)))
|
||||
if (character.HeldItems.Any(i => i.OwnInventory != null && i.OwnInventory.CanBePut(item) && character.CanAccessInventory(i.OwnInventory)))
|
||||
{
|
||||
return QuickUseAction.PutToEquippedItem;
|
||||
}
|
||||
@@ -843,13 +843,14 @@ namespace Barotrauma
|
||||
else if (character.HeldItems.FirstOrDefault(i =>
|
||||
i.OwnInventory != null &&
|
||||
i.OwnInventory.Container.DrawInventory &&
|
||||
character.CanAccessInventory(i.OwnInventory) &&
|
||||
(i.OwnInventory.CanBePut(item) || ((i.OwnInventory.Capacity == 1 || i.OwnInventory.Container.HasSubContainers) && i.OwnInventory.AllowSwappingContainedItems && i.OwnInventory.Container.CanBeContained(item)))) is { } equippedContainer)
|
||||
{
|
||||
if (allowEquip)
|
||||
{
|
||||
if (!character.HasEquippedItem(item))
|
||||
{
|
||||
if (equippedContainer.GetComponent<ItemContainer>() is { QuickUseMovesItemsInside: false})
|
||||
if (equippedContainer.GetComponent<ItemContainer>() is { QuickUseMovesItemsInside: false })
|
||||
{
|
||||
//put the item in a hand slot if that hand is free
|
||||
if ((item.AllowedSlots.Contains(InvSlotType.RightHand) && character.Inventory.GetItemInLimbSlot(InvSlotType.RightHand) == null) ||
|
||||
|
||||
@@ -79,7 +79,8 @@ namespace Barotrauma.Items.Components
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(false, IsPropertySaveable.No, description: "If true, the contained state indicator calculates how full the item is based on the total amount of items that can be stacked inside it, as opposed to how many of the inventory slots are occupied.")]
|
||||
[Serialize(false, IsPropertySaveable.No, description: "If true, the contained state indicator calculates how full the item is based on the total amount of items that can be stacked inside it, as opposed to how many of the inventory slots are occupied." +
|
||||
" Note that only items in the main container or in the subcontainer are counted, depending on which container the first containable item match is found in. The item determining this can be defined with ContainedStateIndicatorSlot")]
|
||||
public bool ShowTotalStackCapacityInContainedStateIndicator { get; set; }
|
||||
|
||||
[Serialize(false, IsPropertySaveable.No, description: "Should the inventory of this item be kept open when the item is equipped by a character.")]
|
||||
@@ -274,8 +275,14 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
itemsPerSlot.Sort((i1, i2) => i1.First().Name.CompareTo(i2.First().Name));
|
||||
foreach (var items in itemsPerSlot)
|
||||
var sortedItems = itemsPerSlot
|
||||
.OrderBy(i => i.First().Name)
|
||||
//if there's multiple items with the same name, sort largest stacks first
|
||||
.ThenByDescending(i => i.Count)
|
||||
//same name and stack size, sort items with most items inside first
|
||||
.ThenByDescending(i => i.First().ContainedItems.Count());
|
||||
|
||||
foreach (var items in sortedItems)
|
||||
{
|
||||
int firstFreeSlot = -1;
|
||||
for (int i = 0; i < Inventory.Capacity; i++)
|
||||
@@ -591,7 +598,8 @@ namespace Barotrauma.Items.Components
|
||||
contained.Item.Scale,
|
||||
spriteEffects,
|
||||
depth: containedSpriteDepth);
|
||||
contained.Item.DrawDecorativeSprites(spriteBatch, itemPos, flipX,flipY, (contained.Item.body == null ? 0.0f : contained.Item.body.DrawRotation), containedSpriteDepth);
|
||||
contained.Item.DrawDecorativeSprites(spriteBatch, itemPos, flipX,flipY, (contained.Item.body == null ? 0.0f : contained.Item.body.DrawRotation),
|
||||
containedSpriteDepth, overrideColor);
|
||||
|
||||
foreach (ItemContainer ic in contained.Item.GetComponents<ItemContainer>())
|
||||
{
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace Barotrauma.Items.Components
|
||||
partial void SetLightSourceState(bool enabled, float brightness)
|
||||
{
|
||||
if (Light == null) { return; }
|
||||
if (item.HiddenInGame) { enabled = false; }
|
||||
if (item.IsHidden) { enabled = false; }
|
||||
Light.Enabled = enabled;
|
||||
lightColorMultiplier = brightness;
|
||||
if (enabled)
|
||||
|
||||
@@ -429,7 +429,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (it?.Submarine == null) { return false; }
|
||||
if (item.Submarine == null || !item.Submarine.IsEntityFoundOnThisSub(it, includingConnectedSubs: true)) { return false; }
|
||||
if (it.NonInteractable || it.HiddenInGame) { return false; }
|
||||
if (it.NonInteractable || it.IsHidden) { return false; }
|
||||
if (it.GetComponent<Pickable>() == null) { return false; }
|
||||
|
||||
var holdable = it.GetComponent<Holdable>();
|
||||
@@ -470,10 +470,10 @@ namespace Barotrauma.Items.Components
|
||||
scissorComponent = new GUIScissorComponent(new RectTransform(Vector2.One, submarineContainer.RectTransform, Anchor.Center));
|
||||
miniMapContainer = new GUIFrame(new RectTransform(Vector2.One, scissorComponent.Content.RectTransform, Anchor.Center), style: null) { CanBeFocused = false };
|
||||
|
||||
ImmutableHashSet<Item> hullPointsOfInterest = Item.ItemList.Where(it => item.Submarine.IsEntityFoundOnThisSub(it, includingConnectedSubs: true) && !it.HiddenInGame && !it.NonInteractable && it.Prefab.ShowInStatusMonitor && (it.GetComponent<Door>() != null || it.GetComponent<Turret>() != null)).ToImmutableHashSet();
|
||||
ImmutableHashSet<Item> hullPointsOfInterest = Item.ItemList.Where(it => item.Submarine.IsEntityFoundOnThisSub(it, includingConnectedSubs: true) && !it.IsHidden && !it.NonInteractable && it.Prefab.ShowInStatusMonitor && (it.GetComponent<Door>() != null || it.GetComponent<Turret>() != null)).ToImmutableHashSet();
|
||||
miniMapFrame = CreateMiniMap(item.Submarine, submarineContainer, MiniMapSettings.Default, hullPointsOfInterest, out hullStatusComponents);
|
||||
|
||||
IEnumerable<Item> electricalPointsOfInterest = Item.ItemList.Where(it => item.Submarine.IsEntityFoundOnThisSub(it, includingConnectedSubs: true) && !it.HiddenInGame && !it.NonInteractable && it.GetComponent<Repairable>() != null);
|
||||
IEnumerable<Item> electricalPointsOfInterest = Item.ItemList.Where(it => item.Submarine.IsEntityFoundOnThisSub(it, includingConnectedSubs: true) && !it.IsHidden && !it.NonInteractable && it.GetComponent<Repairable>() != null);
|
||||
electricalFrame = CreateMiniMap(item.Submarine, miniMapContainer, new MiniMapSettings(createHullElements: false), electricalPointsOfInterest, out electricalMapComponents);
|
||||
|
||||
Dictionary<MiniMapGUIComponent, GUIComponent> electricChildren = new Dictionary<MiniMapGUIComponent, GUIComponent>();
|
||||
@@ -566,7 +566,7 @@ namespace Barotrauma.Items.Components
|
||||
displayedSubs.Add(item.Submarine);
|
||||
displayedSubs.AddRange(item.Submarine.DockedTo.Where(s => s.TeamID == item.Submarine.TeamID));
|
||||
|
||||
subEntities = MapEntity.MapEntityList.Where(me => (item.Submarine is { } sub && sub.IsEntityFoundOnThisSub(me, includingConnectedSubs: true, allowDifferentType: false)) && !me.HiddenInGame).OrderByDescending(w => w.SpriteDepth).ToList();
|
||||
subEntities = MapEntity.MapEntityList.Where(me => (item.Submarine is { } sub && sub.IsEntityFoundOnThisSub(me, includingConnectedSubs: true, allowDifferentType: false)) && !me.IsHidden).OrderByDescending(w => w.SpriteDepth).ToList();
|
||||
|
||||
BakeSubmarine(item.Submarine, parentRect);
|
||||
elementSize = GuiFrame.Rect.Size;
|
||||
@@ -763,7 +763,7 @@ namespace Barotrauma.Items.Components
|
||||
worldBorders.Location += item.Submarine.WorldPosition.ToPoint();
|
||||
foreach (Gap gap in Gap.GapList)
|
||||
{
|
||||
if (gap.IsRoomToRoom || gap.linkedTo.Count == 0 || gap.Submarine != item.Submarine || gap.ConnectedDoor != null || gap.HiddenInGame) { continue; }
|
||||
if (gap.IsRoomToRoom || gap.linkedTo.Count == 0 || gap.Submarine != item.Submarine || gap.ConnectedDoor != null || gap.IsHidden) { continue; }
|
||||
RectangleF entityRect = ScaleRectToUI(gap, miniMapFrame.Rect, worldBorders);
|
||||
|
||||
Vector2 scale = new Vector2(entityRect.Size.X / spriteSize.X, entityRect.Size.Y / spriteSize.Y) * 2.0f;
|
||||
@@ -930,7 +930,7 @@ namespace Barotrauma.Items.Components
|
||||
if (DisplayAsSameItem(it.Prefab, searchedPrefab))
|
||||
{
|
||||
// ignore items on players and hidden inventories
|
||||
if (it.FindParentInventory(inv => inv is CharacterInventory || inv is ItemInventory { Owner: Item { HiddenInGame: true }}) is { }) { continue; }
|
||||
if (it.FindParentInventory(inv => inv is CharacterInventory || inv is ItemInventory { Owner: Item { IsHidden: true }}) is { }) { continue; }
|
||||
|
||||
if (it.FindParentInventory(inventory => inventory is ItemInventory { Owner: Item { ParentInventory: null } }) is ItemInventory parent)
|
||||
{
|
||||
@@ -1112,7 +1112,7 @@ namespace Barotrauma.Items.Components
|
||||
if (ShowHullIntegrity)
|
||||
{
|
||||
float amount = 1f + hullData.LinkedHulls.Count;
|
||||
gapOpenSum = hull.ConnectedGaps.Concat(hullData.LinkedHulls.SelectMany(h => h.ConnectedGaps)).Where(g => g.linkedTo.Count == 1 && !g.HiddenInGame).Sum(g => g.Open) / amount;
|
||||
gapOpenSum = hull.ConnectedGaps.Concat(hullData.LinkedHulls.SelectMany(h => h.ConnectedGaps)).Where(g => g.linkedTo.Count == 1 && !g.IsHidden).Sum(g => g.Open) / amount;
|
||||
borderColor = Color.Lerp(neutralColor, GUIStyle.Red, Math.Min(gapOpenSum, 1.0f));
|
||||
}
|
||||
|
||||
@@ -1557,7 +1557,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (linkedEntity is Hull linkedHull)
|
||||
{
|
||||
if (linkedHulls.Contains(linkedHull) || linkedHull.HiddenInGame) { continue; }
|
||||
if (linkedHulls.Contains(linkedHull) || linkedHull.IsHidden) { continue; }
|
||||
linkedHulls.Add(linkedHull);
|
||||
GetLinkedHulls(linkedHull, linkedHulls);
|
||||
}
|
||||
@@ -1737,7 +1737,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
bool IsPartofSub(MapEntity entity)
|
||||
{
|
||||
if (entity.Submarine != sub && !connectedSubs.Contains(entity.Submarine) || entity.HiddenInGame) { return false; }
|
||||
if (entity.Submarine != sub && !connectedSubs.Contains(entity.Submarine) || entity.IsHidden) { return false; }
|
||||
return sub.IsEntityFoundOnThisSub(entity, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -1186,7 +1186,7 @@ namespace Barotrauma.Items.Components
|
||||
foreach (DockingPort dockingPort in DockingPort.List)
|
||||
{
|
||||
if (Level.Loaded != null && dockingPort.Item.Submarine.WorldPosition.Y > Level.Loaded.Size.Y) { continue; }
|
||||
if (dockingPort.Item.HiddenInGame) { continue; }
|
||||
if (dockingPort.Item.IsHidden) { continue; }
|
||||
if (dockingPort.Item.Submarine == null) { continue; }
|
||||
if (dockingPort.Item.Submarine.Info.IsWreck) { continue; }
|
||||
// docking ports should be shown even if defined as not, if the submarine is the same as the sonar's
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public override bool ShouldDrawHUD(Character character)
|
||||
{
|
||||
if (item.HiddenInGame) { return false; }
|
||||
if (item.IsHidden) { return false; }
|
||||
if (!HasRequiredItems(character, false) || character.SelectedItem != item) { return false; }
|
||||
if (character.IsTraitor && item.ConditionPercentage > MinSabotageCondition) { return true; }
|
||||
if (item.ConditionPercentageRelativeToDefaultMaxCondition < RepairThreshold) { return true; }
|
||||
@@ -224,7 +224,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
partial void UpdateProjSpecific(float deltaTime)
|
||||
{
|
||||
if (item.HiddenInGame) { return; }
|
||||
if (item.IsHidden) { return; }
|
||||
if (FakeBrokenTimer > 0.0f)
|
||||
{
|
||||
item.FakeBroken = true;
|
||||
@@ -397,6 +397,12 @@ namespace Barotrauma.Items.Components
|
||||
GUI.DrawString(spriteBatch,
|
||||
new Vector2(item.DrawPosition.X, -item.DrawPosition.Y + 20), "Condition: " + (int)item.Condition + "/" + (int)item.MaxCondition,
|
||||
GUIStyle.Orange);
|
||||
if (MaxStressDeteriorationMultiplier > 1.0f)
|
||||
{
|
||||
GUI.DrawString(spriteBatch,
|
||||
new Vector2(item.DrawPosition.X, -item.DrawPosition.Y + 40), "Stress multiplier: " + StressDeteriorationMultiplier.ToString("0.00"),
|
||||
GUIStyle.Red);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -303,6 +303,17 @@ namespace Barotrauma.Items.Components
|
||||
CreateClientEvent(new CircuitBoxRenameLabelEvent(label.ID, color, header, body));
|
||||
}
|
||||
|
||||
public void SetConnectionLabelOverrides(CircuitBoxInputOutputNode node, Dictionary<string, string> newOverrides)
|
||||
{
|
||||
if (GameMain.NetworkMember is null)
|
||||
{
|
||||
node.ReplaceAllConnectionLabelOverrides(newOverrides);
|
||||
return;
|
||||
}
|
||||
|
||||
CreateClientEvent(new CircuitBoxRenameConnectionLabelsEvent(node.NodeType, newOverrides.ToNetDictionary()));
|
||||
}
|
||||
|
||||
public void ResizeNode(CircuitBoxNode node, CircuitBoxResizeDirection dir, Vector2 amount)
|
||||
{
|
||||
if (Locked) { return; }
|
||||
@@ -528,6 +539,12 @@ namespace Barotrauma.Items.Components
|
||||
_ => node.Position
|
||||
};
|
||||
}
|
||||
|
||||
foreach (var labelOverride in data.LabelOverrides)
|
||||
{
|
||||
RenameConnectionLabelsInternal(labelOverride.Type, labelOverride.Override.ToDictionary());
|
||||
}
|
||||
|
||||
wasInitializedByServer = true;
|
||||
break;
|
||||
}
|
||||
@@ -556,6 +573,12 @@ namespace Barotrauma.Items.Components
|
||||
ResizeLabelInternal(data.ID, data.Position, data.Size);
|
||||
break;
|
||||
}
|
||||
case CircuitBoxOpcode.RenameConnections:
|
||||
{
|
||||
var data = INetSerializableStruct.Read<CircuitBoxRenameConnectionLabelsEvent>(msg);
|
||||
RenameConnectionLabelsInternal(data.Type, data.Override.ToDictionary());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(header), header, "This opcode cannot be handled using entity events");
|
||||
}
|
||||
|
||||
@@ -292,8 +292,17 @@ namespace Barotrauma.Items.Components
|
||||
if (wire.HiddenInGame && Screen.Selected == GameMain.GameScreen) { continue; }
|
||||
|
||||
Connection recipient = wire.OtherConnection(this);
|
||||
LocalizedString label = recipient == null ? "" : recipient.item.Name + $" ({recipient.DisplayName})";
|
||||
if (wire.Locked) { label += "\n" + TextManager.Get("ConnectionLocked"); }
|
||||
LocalizedString label;
|
||||
if (wire.Item.IsLayerHidden)
|
||||
{
|
||||
label = TextManager.Get("ConnectionLocked");
|
||||
}
|
||||
else
|
||||
{
|
||||
label = recipient == null ? "" : recipient.item.Name + $" ({recipient.DisplayName})";
|
||||
if (wire.Locked) { label += "\n" + TextManager.Get("ConnectionLocked"); }
|
||||
}
|
||||
|
||||
DrawWire(spriteBatch, wire, position, wirePosition, equippedWire, panel, label);
|
||||
|
||||
wirePosition.Y += wireInterval;
|
||||
@@ -494,7 +503,7 @@ namespace Barotrauma.Items.Components
|
||||
ConnectionPanel.HighlightedWire = wire;
|
||||
|
||||
bool allowRewiring = GameMain.NetworkMember?.ServerSettings == null || GameMain.NetworkMember.ServerSettings.AllowRewiring || panel.AlwaysAllowRewiring;
|
||||
if (allowRewiring && (!wire.Locked && !panel.Locked && !panel.TemporarilyLocked || Screen.Selected == GameMain.SubEditorScreen))
|
||||
if (allowRewiring && (!wire.Locked && !wire.Item.IsLayerHidden && !panel.Locked && !panel.TemporarilyLocked || Screen.Selected == GameMain.SubEditorScreen))
|
||||
{
|
||||
//start dragging the wire
|
||||
if (PlayerInput.PrimaryMouseButtonHeld()) { DraggingConnected = wire; }
|
||||
|
||||
@@ -283,12 +283,12 @@ namespace Barotrauma.Items.Components
|
||||
texts.Add(CharacterHUD.GetCachedHudText("PlayHint", InputType.Use));
|
||||
textColors.Add(GUIStyle.Green);
|
||||
}
|
||||
if (target.CharacterHealth.UseHealthWindow && !target.DisableHealthWindow && equipper?.FocusedCharacter == target && equipper.CanInteractWith(target, 160f, false))
|
||||
if (equipper?.FocusedCharacter == target && target.CanBeHealedBy(equipper, checkFriendlyTeam: false))
|
||||
{
|
||||
texts.Add(CharacterHUD.GetCachedHudText("HealHint", InputType.Health));
|
||||
textColors.Add(GUIStyle.Green);
|
||||
}
|
||||
if (target.CanBeDragged)
|
||||
if (target.CanBeDraggedBy(Character.Controlled))
|
||||
{
|
||||
texts.Add(CharacterHUD.GetCachedHudText("GrabHint", InputType.Grab));
|
||||
textColors.Add(GUIStyle.Green);
|
||||
|
||||
@@ -196,7 +196,7 @@ namespace Barotrauma.Items.Components
|
||||
Vector2 particlePos = GetRelativeFiringPosition();
|
||||
foreach (ParticleEmitter emitter in particleEmitters)
|
||||
{
|
||||
emitter.Emit(1.0f, particlePos, hullGuess: null, angle: -rotation, particleRotation: rotation);
|
||||
emitter.Emit(1.0f, particlePos, hullGuess: null, angle: -Rotation, particleRotation: Rotation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,7 +213,7 @@ namespace Barotrauma.Items.Components
|
||||
if (crosshairSprite != null)
|
||||
{
|
||||
Vector2 itemPos = cam.WorldToScreen(new Vector2(item.WorldRect.X + transformedBarrelPos.X, item.WorldRect.Y - transformedBarrelPos.Y));
|
||||
Vector2 turretDir = new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation));
|
||||
Vector2 turretDir = new Vector2((float)Math.Cos(Rotation), (float)Math.Sin(Rotation));
|
||||
|
||||
Vector2 mouseDiff = itemPos - PlayerInput.MousePosition;
|
||||
crosshairPos = new Vector2(
|
||||
@@ -268,7 +268,7 @@ namespace Barotrauma.Items.Components
|
||||
foreach (ParticleEmitter emitter in particleEmitterCharges)
|
||||
{
|
||||
// color is currently not connected to ammo type, should be updated when ammo is changed
|
||||
emitter.Emit(deltaTime, particlePos, hullGuess: null, angle: -rotation, particleRotation: rotation, sizeMultiplier: sizeMultiplier, colorMultiplier: emitter.Prefab.Properties.ColorMultiplier);
|
||||
emitter.Emit(deltaTime, particlePos, hullGuess: null, angle: -Rotation, particleRotation: Rotation, sizeMultiplier: sizeMultiplier, colorMultiplier: emitter.Prefab.Properties.ColorMultiplier);
|
||||
}
|
||||
|
||||
if (chargeSoundChannel == null || !chargeSoundChannel.IsPlaying)
|
||||
@@ -339,7 +339,7 @@ namespace Barotrauma.Items.Components
|
||||
if (crosshairSprite != null)
|
||||
{
|
||||
Vector2 itemPos = cam.WorldToScreen(item.WorldPosition);
|
||||
Vector2 turretDir = new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation));
|
||||
Vector2 turretDir = new Vector2((float)Math.Cos(Rotation), (float)Math.Sin(Rotation));
|
||||
|
||||
Vector2 mouseDiff = itemPos - PlayerInput.MousePosition;
|
||||
crosshairPos = new Vector2(
|
||||
@@ -372,7 +372,7 @@ namespace Barotrauma.Items.Components
|
||||
recoilOffset = RecoilDistance;
|
||||
}
|
||||
}
|
||||
return new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation)) * recoilOffset;
|
||||
return new Vector2((float)Math.Cos(Rotation), (float)Math.Sin(Rotation)) * recoilOffset;
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, bool editing = false, float itemDepth = -1, Color? overrideColor = null)
|
||||
@@ -388,13 +388,13 @@ namespace Barotrauma.Items.Components
|
||||
railSprite?.Draw(spriteBatch,
|
||||
drawPos,
|
||||
overrideColor ?? item.SpriteColor,
|
||||
rotation + MathHelper.PiOver2, item.Scale,
|
||||
Rotation + MathHelper.PiOver2, item.Scale,
|
||||
SpriteEffects.None, item.SpriteDepth + (railSprite.Depth - item.Sprite.Depth));
|
||||
|
||||
barrelSprite?.Draw(spriteBatch,
|
||||
drawPos - GetRecoilOffset() * item.Scale,
|
||||
overrideColor ?? item.SpriteColor,
|
||||
rotation + MathHelper.PiOver2, item.Scale,
|
||||
Rotation + MathHelper.PiOver2, item.Scale,
|
||||
SpriteEffects.None, item.SpriteDepth + (barrelSprite.Depth - item.Sprite.Depth));
|
||||
|
||||
float chargeRatio = currentChargeTime / MaxChargeTime;
|
||||
@@ -402,9 +402,9 @@ namespace Barotrauma.Items.Components
|
||||
foreach ((Sprite chargeSprite, Vector2 position) in chargeSprites)
|
||||
{
|
||||
chargeSprite?.Draw(spriteBatch,
|
||||
drawPos - MathUtils.RotatePoint(new Vector2(position.X * chargeRatio, position.Y * chargeRatio) * item.Scale, rotation + MathHelper.PiOver2),
|
||||
drawPos - MathUtils.RotatePoint(new Vector2(position.X * chargeRatio, position.Y * chargeRatio) * item.Scale, Rotation + MathHelper.PiOver2),
|
||||
item.SpriteColor,
|
||||
rotation + MathHelper.PiOver2, item.Scale,
|
||||
Rotation + MathHelper.PiOver2, item.Scale,
|
||||
SpriteEffects.None, item.SpriteDepth + (chargeSprite.Depth - item.Sprite.Depth));
|
||||
}
|
||||
|
||||
@@ -427,9 +427,9 @@ namespace Barotrauma.Items.Components
|
||||
float newPositionOffset = barrelPositionModifier * SpinningBarrelDistance;
|
||||
|
||||
spinningBarrel.Draw(spriteBatch,
|
||||
drawPos - MathUtils.RotatePoint(new Vector2(newPositionOffset, 0f) * item.Scale, rotation + MathHelper.PiOver2),
|
||||
drawPos - MathUtils.RotatePoint(new Vector2(newPositionOffset, 0f) * item.Scale, Rotation + MathHelper.PiOver2),
|
||||
Color.Lerp(overrideColor ?? item.SpriteColor, newColorModifier, 0.8f),
|
||||
rotation + MathHelper.PiOver2, item.Scale,
|
||||
Rotation + MathHelper.PiOver2, item.Scale,
|
||||
SpriteEffects.None, newDepth);
|
||||
}
|
||||
}
|
||||
@@ -475,9 +475,9 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
spriteBatch.DrawLine(drawPos, drawPos + center * circleRadius, GUIStyle.Green, thickness: lineThickness);
|
||||
}
|
||||
else if (radians > Math.PI * 2)
|
||||
else if (radians >= MathHelper.TwoPi)
|
||||
{
|
||||
spriteBatch.DrawCircle(drawPos, circleRadius, 180, GUIStyle.Red, thickness: lineThickness);
|
||||
spriteBatch.DrawCircle(drawPos, circleRadius, 180, GUIStyle.Green, thickness: lineThickness);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -510,7 +510,12 @@ namespace Barotrauma.Items.Components
|
||||
};
|
||||
widget.MouseHeld += (deltaTime) =>
|
||||
{
|
||||
minRotation = GetRotationAngle(GetDrawPos());
|
||||
float newMinRotation = GetRotationAngle(GetDrawPos());
|
||||
AngleWrapAdjustment(minRotation, newMinRotation, ref maxRotation);
|
||||
|
||||
// clamp value here to keep widget movement within max range
|
||||
minRotation = MathHelper.Clamp(newMinRotation, maxRotation - MathHelper.TwoPi, maxRotation);
|
||||
|
||||
UpdateBarrel();
|
||||
MapEntity.DisableSelect = true;
|
||||
};
|
||||
@@ -554,7 +559,12 @@ namespace Barotrauma.Items.Components
|
||||
};
|
||||
widget.MouseHeld += (deltaTime) =>
|
||||
{
|
||||
maxRotation = GetRotationAngle(GetDrawPos());
|
||||
float newMaxRotation = GetRotationAngle(GetDrawPos());
|
||||
AngleWrapAdjustment(maxRotation, newMaxRotation, ref minRotation);
|
||||
|
||||
// clamp value here to keep widget movement within max range
|
||||
maxRotation = MathHelper.Clamp(newMaxRotation, minRotation, minRotation + MathHelper.TwoPi);
|
||||
|
||||
UpdateBarrel();
|
||||
MapEntity.DisableSelect = true;
|
||||
};
|
||||
@@ -580,10 +590,44 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
void UpdateBarrel()
|
||||
{
|
||||
rotation = (minRotation + maxRotation) / 2;
|
||||
Rotation = (minRotation + maxRotation) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void AngleWrapAdjustment(float currentRotation, float newRotation, ref float rangeLockedRotation)
|
||||
{
|
||||
if (DetectAngleWrapAround(currentRotation, newRotation))
|
||||
{
|
||||
// if there's a wrap-around, also wrap the other rotation limit to keep range
|
||||
if (newRotation < currentRotation)
|
||||
{
|
||||
rangeLockedRotation -= MathHelper.TwoPi;
|
||||
}
|
||||
else
|
||||
{
|
||||
rangeLockedRotation += MathHelper.TwoPi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool DetectAngleWrapAround(float rotation, float newRotation)
|
||||
{
|
||||
float deltaRotation = MathF.Abs(rotation - newRotation);
|
||||
|
||||
// turret angle wraps around to 0 from -2Pi and 2Pi.
|
||||
// Detect wrap-around when dragging the widgets, where usual rotation delta is small,
|
||||
// so a large jump in rotation (here, an arbitrary big value in the range of 0 to 2Pi)
|
||||
// is considered a wrap-around for this purpose.
|
||||
// NOTE: this is not a reliable way to detect angle wrap-around in general, and is only intended for
|
||||
// the angle widgets!
|
||||
if (deltaRotation > MathHelper.TwoPi * 0.8f)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public Vector2 GetDrawPos()
|
||||
{
|
||||
Vector2 drawPos = new Vector2(item.Rect.X + transformedBarrelPos.X, item.Rect.Y - transformedBarrelPos.Y);
|
||||
@@ -764,7 +808,7 @@ namespace Barotrauma.Items.Components
|
||||
if (projectileID == 0) { return; }
|
||||
|
||||
//ID ushort.MaxValue = launched without a projectile
|
||||
if (projectileID == ushort.MaxValue)
|
||||
if (projectileID == LaunchWithoutProjectileId)
|
||||
{
|
||||
Launch(null, user);
|
||||
}
|
||||
|
||||
@@ -319,7 +319,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
string colorStr = (item.SpawnedInCurrentOutpost && !item.AllowStealing ? GUIStyle.Red : Color.White).ToStringHex();
|
||||
string colorStr = (item.Illegitimate ? GUIStyle.Red : Color.White).ToStringHex();
|
||||
|
||||
toolTip = $"‖color:{colorStr}‖{name}‖color:end‖";
|
||||
if (item.GetComponent<Quality>() != null)
|
||||
@@ -478,10 +478,11 @@ namespace Barotrauma
|
||||
{
|
||||
int row = (int)Math.Floor((double)i / slotsPerRow);
|
||||
int slotsPerThisRow = Math.Min(slotsPerRow, capacity - row * slotsPerRow);
|
||||
int slotNumberOnThisRow = i - row * slotsPerRow;
|
||||
|
||||
int rowWidth = (int)(rectSize.X * slotsPerThisRow + spacing.X * (slotsPerThisRow - 1));
|
||||
slotRect.X = (int)(center.X) - rowWidth / 2;
|
||||
slotRect.X += (int)((rectSize.X + spacing.X) * (i % slotsPerThisRow));
|
||||
slotRect.X += (int)((rectSize.X + spacing.X) * (slotNumberOnThisRow % slotsPerThisRow));
|
||||
|
||||
slotRect.Y = (int)(topLeft.Y + (rectSize.Y + spacing.Y) * row);
|
||||
visualSlots[i] = new VisualSlot(slotRect);
|
||||
@@ -1185,6 +1186,7 @@ namespace Barotrauma
|
||||
{
|
||||
DraggingItems.RemoveAll(it => !Character.Controlled.CanInteractWith(it));
|
||||
}
|
||||
|
||||
if (DraggingItems.Any() && PlayerInput.PrimaryMouseButtonReleased())
|
||||
{
|
||||
Character.Controlled.ClearInputs();
|
||||
@@ -1193,198 +1195,234 @@ namespace Barotrauma
|
||||
if (!DetermineMouseOnInventory(ignoreDraggedItem: true) &&
|
||||
(CharacterHealth.OpenHealthWindow != null || mouseOnPortrait))
|
||||
{
|
||||
bool dropSuccessful = false;
|
||||
foreach (Item item in DraggingItems)
|
||||
if (TryPortraitAndHealthDrop(mouseOnPortrait))
|
||||
{
|
||||
var inventory = item.ParentInventory;
|
||||
var indices = inventory?.FindIndices(item);
|
||||
dropSuccessful |= (CharacterHealth.OpenHealthWindow ?? Character.Controlled.CharacterHealth).OnItemDropped(item, ignoreMousePos: mouseOnPortrait);
|
||||
if (dropSuccessful)
|
||||
{
|
||||
if (indices != null && inventory.visualSlots != null)
|
||||
{
|
||||
foreach (int i in indices)
|
||||
{
|
||||
inventory.visualSlots[i]?.ShowBorderHighlight(GUIStyle.Green, 0.1f, 0.4f);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dropSuccessful)
|
||||
{
|
||||
DraggingItems.Clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedSlot == null)
|
||||
{
|
||||
if (DraggingItemToWorld &&
|
||||
Character.Controlled.FocusedItem is { OwnInventory: { } inventory } item && item.GetComponent<ItemContainer>() is { } container &&
|
||||
container.HasRequiredItems(Character.Controlled, addMessage: false) &&
|
||||
container.AllowDragAndDrop &&
|
||||
inventory.CanBePut(DraggingItems.FirstOrDefault()))
|
||||
HandleOutsideInventoryDrop();
|
||||
}
|
||||
else if (!DraggingItems.Any(it => selectedSlot.ParentInventory.slots[selectedSlot.SlotIndex].Contains(it)))
|
||||
{
|
||||
HandleInventorySlotDrop();
|
||||
}
|
||||
|
||||
DraggingItems.Clear();
|
||||
}
|
||||
|
||||
if (selectedSlot != null && !CanSelectSlot(selectedSlot))
|
||||
{
|
||||
selectedSlot = null;
|
||||
}
|
||||
|
||||
bool TryPortraitAndHealthDrop(bool mouseOnPortrait)
|
||||
{
|
||||
bool dropSuccessful = false;
|
||||
foreach (Item item in DraggingItems)
|
||||
{
|
||||
var inventory = item.ParentInventory;
|
||||
var indices = inventory?.FindIndices(item);
|
||||
dropSuccessful |= (CharacterHealth.OpenHealthWindow ?? Character.Controlled.CharacterHealth).OnItemDropped(item, ignoreMousePos: mouseOnPortrait);
|
||||
if (dropSuccessful)
|
||||
{
|
||||
bool anySuccess = false;
|
||||
foreach (Item it in DraggingItems)
|
||||
if (indices != null && inventory.visualSlots != null)
|
||||
{
|
||||
bool success = Character.Controlled.FocusedItem.OwnInventory.TryPutItem(it, Character.Controlled);
|
||||
if (!success) { break; }
|
||||
anySuccess |= success;
|
||||
}
|
||||
if (anySuccess) { SoundPlayer.PlayUISound(GUISoundType.PickItem); }
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Screen.Selected is SubEditorScreen)
|
||||
{
|
||||
if (DraggingItems.First()?.ParentInventory != null)
|
||||
foreach (int i in indices)
|
||||
{
|
||||
SubEditorScreen.StoreCommand(new InventoryPlaceCommand(DraggingItems.First().ParentInventory, new List<Item>(DraggingItems), true));
|
||||
inventory.visualSlots[i]?.ShowBorderHighlight(GUIStyle.Green, 0.1f, 0.4f);
|
||||
}
|
||||
}
|
||||
|
||||
SoundPlayer.PlayUISound(GUISoundType.DropItem);
|
||||
bool removed = false;
|
||||
if (Screen.Selected is SubEditorScreen editor)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dropSuccessful)
|
||||
{
|
||||
DraggingItems.Clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void HandleOutsideInventoryDrop()
|
||||
{
|
||||
bool isTargetingValidContainer = Character.Controlled.FocusedItem is { OwnInventory: { } inventory } item &&
|
||||
item.GetComponent<ItemContainer>() is { } container &&
|
||||
container.HasRequiredItems(Character.Controlled, addMessage: false) &&
|
||||
container.AllowDragAndDrop &&
|
||||
inventory.CanBePut(DraggingItems.FirstOrDefault());
|
||||
|
||||
bool isTargetingValidCharacter = IsValidTargetForDragDropGive(Character.Controlled, Character.Controlled.FocusedCharacter);
|
||||
|
||||
if (DraggingItemToWorld && (isTargetingValidContainer || isTargetingValidCharacter))
|
||||
{
|
||||
bool anySuccess = false;
|
||||
foreach (Item it in DraggingItems)
|
||||
{
|
||||
bool success = false;
|
||||
if (isTargetingValidContainer)
|
||||
{
|
||||
if (editor.EntityMenu.Rect.Contains(PlayerInput.MousePosition))
|
||||
success = Character.Controlled.FocusedItem.OwnInventory.TryPutItem(it, Character.Controlled);
|
||||
}
|
||||
if (!success && isTargetingValidCharacter)
|
||||
{
|
||||
success = Character.Controlled.FocusedCharacter.Inventory.TryPutItem(it, Character.Controlled, CharacterInventory.AnySlot);
|
||||
}
|
||||
|
||||
if (!success) { break; }
|
||||
anySuccess = true;
|
||||
}
|
||||
|
||||
if (anySuccess) { SoundPlayer.PlayUISound(GUISoundType.PickItem); }
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Screen.Selected is SubEditorScreen)
|
||||
{
|
||||
if (DraggingItems.First()?.ParentInventory != null)
|
||||
{
|
||||
SubEditorScreen.StoreCommand(new InventoryPlaceCommand(DraggingItems.First().ParentInventory, new List<Item>(DraggingItems), true));
|
||||
}
|
||||
}
|
||||
|
||||
SoundPlayer.PlayUISound(GUISoundType.DropItem);
|
||||
bool removed = false;
|
||||
if (Screen.Selected is SubEditorScreen editor)
|
||||
{
|
||||
if (editor.EntityMenu.Rect.Contains(PlayerInput.MousePosition))
|
||||
{
|
||||
DraggingItems.ForEachMod(it => it.Remove());
|
||||
removed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (editor.WiringMode)
|
||||
{
|
||||
DraggingItems.ForEachMod(it => it.Remove());
|
||||
removed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (editor.WiringMode)
|
||||
{
|
||||
DraggingItems.ForEachMod(it => it.Remove());
|
||||
removed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
DraggingItems.ForEachMod(it => it.Drop(Character.Controlled));
|
||||
}
|
||||
DraggingItems.ForEachMod(it => it.Drop(Character.Controlled));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DraggingItems.ForEachMod(it => it.Drop(Character.Controlled));
|
||||
DraggingItems.First().CreateDroppedStack(DraggingItems, allowClientExecute: false);
|
||||
}
|
||||
SoundPlayer.PlayUISound(removed ? GUISoundType.PickItem : GUISoundType.DropItem);
|
||||
}
|
||||
}
|
||||
else if (!DraggingItems.Any(it => selectedSlot.ParentInventory.slots[selectedSlot.SlotIndex].Contains(it)))
|
||||
{
|
||||
Inventory oldInventory = DraggingItems.First().ParentInventory;
|
||||
Inventory selectedInventory = selectedSlot.ParentInventory;
|
||||
int slotIndex = selectedSlot.SlotIndex;
|
||||
int oldSlot = oldInventory == null ? 0 : Array.IndexOf(oldInventory.slots, DraggingItems);
|
||||
|
||||
//if attempting to drop into an invalid slot in the same inventory, try to move to the correct slot
|
||||
if (selectedInventory.slots[slotIndex].Empty() &&
|
||||
selectedInventory == Character.Controlled.Inventory &&
|
||||
!DraggingItems.First().AllowedSlots.Any(a => a.HasFlag(Character.Controlled.Inventory.SlotTypes[slotIndex])) &&
|
||||
DraggingItems.Any(it => selectedInventory.TryPutItem(it, Character.Controlled, it.AllowedSlots)))
|
||||
else
|
||||
{
|
||||
if (selectedInventory.visualSlots != null)
|
||||
DraggingItems.ForEachMod(it => it.Drop(Character.Controlled));
|
||||
DraggingItems.First().CreateDroppedStack(DraggingItems, allowClientExecute: false);
|
||||
}
|
||||
SoundPlayer.PlayUISound(removed ? GUISoundType.PickItem : GUISoundType.DropItem);
|
||||
}
|
||||
}
|
||||
|
||||
void HandleInventorySlotDrop()
|
||||
{
|
||||
Inventory oldInventory = DraggingItems.First().ParentInventory;
|
||||
Inventory selectedInventory = selectedSlot.ParentInventory;
|
||||
int slotIndex = selectedSlot.SlotIndex;
|
||||
int oldSlot = oldInventory == null ? 0 : Array.IndexOf(oldInventory.slots, DraggingItems);
|
||||
|
||||
//if attempting to drop into an invalid slot in the same inventory, try to move to the correct slot
|
||||
if (selectedInventory.slots[slotIndex].Empty() &&
|
||||
selectedInventory == Character.Controlled.Inventory &&
|
||||
!DraggingItems.First().AllowedSlots.Any(a => a.HasFlag(Character.Controlled.Inventory.SlotTypes[slotIndex])) &&
|
||||
DraggingItems.Any(it => selectedInventory.TryPutItem(it, Character.Controlled, it.AllowedSlots)))
|
||||
{
|
||||
if (selectedInventory.visualSlots != null)
|
||||
{
|
||||
for (int i = 0; i < selectedInventory.visualSlots.Length; i++)
|
||||
{
|
||||
for (int i = 0; i < selectedInventory.visualSlots.Length; i++)
|
||||
if (DraggingItems.Any(it => selectedInventory.slots[i].Contains(it)))
|
||||
{
|
||||
if (DraggingItems.Any(it => selectedInventory.slots[i].Contains(it)))
|
||||
selectedInventory.visualSlots[slotIndex].ShowBorderHighlight(Color.White, 0.1f, 0.4f);
|
||||
}
|
||||
}
|
||||
selectedInventory.visualSlots[slotIndex].ShowBorderHighlight(GUIStyle.Red, 0.1f, 0.9f);
|
||||
}
|
||||
SoundPlayer.PlayUISound(GUISoundType.PickItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool anySuccess = false;
|
||||
//if we're dragging a stack of partial items or trying to drag to a stack of partial items
|
||||
//(which should not normally exist, but can happen when e.g. fire damages a stack of items)
|
||||
//don't allow combining because it leads to weird behavior (stack of items of mixed quality)
|
||||
bool allowCombine = !(DraggingItems.Count(it => !it.IsFullCondition && it.Condition > 0.0f) > 1 ||
|
||||
selectedInventory.GetItemsAt(slotIndex).Count(it => !it.IsFullCondition && it.Condition > 0.0f) > 1);
|
||||
int itemCount = 0;
|
||||
foreach (Item item in DraggingItems)
|
||||
{
|
||||
if (selectedInventory.GetItemAt(slotIndex)?.OwnInventory?.Container is { } container &&
|
||||
container.Inventory.CanBePut(item))
|
||||
{
|
||||
if (!container.AllowDragAndDrop || !container.AllowAccess)
|
||||
{
|
||||
allowCombine = false;
|
||||
}
|
||||
}
|
||||
bool success = selectedInventory.TryPutItem(item, slotIndex, allowSwapping: !anySuccess, allowCombine, Character.Controlled);
|
||||
if (success)
|
||||
{
|
||||
anySuccess = true;
|
||||
itemCount++;
|
||||
}
|
||||
if (!success || itemCount >= item.Prefab.GetMaxStackSize(selectedInventory))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (anySuccess)
|
||||
{
|
||||
highlightedSubInventorySlots.RemoveWhere(s => s.ParentInventory == oldInventory || s.ParentInventory == selectedInventory);
|
||||
if (SubEditorScreen.IsSubEditor())
|
||||
{
|
||||
foreach (Item draggingItem in DraggingItems)
|
||||
{
|
||||
if (selectedInventory.slots[slotIndex].Contains(draggingItem))
|
||||
{
|
||||
selectedInventory.visualSlots[slotIndex].ShowBorderHighlight(Color.White, 0.1f, 0.4f);
|
||||
SubEditorScreen.StoreCommand(new InventoryMoveCommand(oldInventory, selectedInventory, draggingItem, oldSlot, slotIndex));
|
||||
}
|
||||
}
|
||||
selectedInventory.visualSlots[slotIndex].ShowBorderHighlight(GUIStyle.Red, 0.1f, 0.9f);
|
||||
}
|
||||
if (selectedInventory.visualSlots != null) { selectedInventory.visualSlots[slotIndex].ShowBorderHighlight(Color.White, 0.1f, 0.4f); }
|
||||
SoundPlayer.PlayUISound(GUISoundType.PickItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool anySuccess = false;
|
||||
bool allowCombine = true;
|
||||
//if we're dragging a stack of partial items or trying to drag to a stack of partial items
|
||||
//(which should not normally exist, but can happen when e.g. fire damages a stack of items)
|
||||
//don't allow combining because it leads to weird behavior (stack of items of mixed quality)
|
||||
if (DraggingItems.Count(it => !it.IsFullCondition && it.Condition > 0.0f) > 1 ||
|
||||
selectedInventory.GetItemsAt(slotIndex).Count(it => !it.IsFullCondition && it.Condition > 0.0f) > 1)
|
||||
{
|
||||
allowCombine = false;
|
||||
}
|
||||
int itemCount = 0;
|
||||
foreach (Item item in DraggingItems)
|
||||
{
|
||||
if (selectedInventory.GetItemAt(slotIndex)?.OwnInventory?.Container is { } container &&
|
||||
container.Inventory.CanBePut(item))
|
||||
{
|
||||
if (!container.AllowDragAndDrop || !container.AllowAccess)
|
||||
{
|
||||
allowCombine = false;
|
||||
}
|
||||
}
|
||||
bool success = selectedInventory.TryPutItem(item, slotIndex, allowSwapping: !anySuccess, allowCombine, Character.Controlled);
|
||||
if (success)
|
||||
{
|
||||
anySuccess = true;
|
||||
itemCount++;
|
||||
}
|
||||
if (!success || itemCount >= item.Prefab.GetMaxStackSize(selectedInventory))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (anySuccess)
|
||||
{
|
||||
highlightedSubInventorySlots.RemoveWhere(s => s.ParentInventory == oldInventory || s.ParentInventory == selectedInventory);
|
||||
if (SubEditorScreen.IsSubEditor())
|
||||
{
|
||||
foreach (Item draggingItem in DraggingItems)
|
||||
{
|
||||
if (selectedInventory.slots[slotIndex].Contains(draggingItem))
|
||||
{
|
||||
SubEditorScreen.StoreCommand(new InventoryMoveCommand(oldInventory, selectedInventory, draggingItem, oldSlot, slotIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (selectedInventory.visualSlots != null) { selectedInventory.visualSlots[slotIndex].ShowBorderHighlight(Color.White, 0.1f, 0.4f); }
|
||||
SoundPlayer.PlayUISound(GUISoundType.PickItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (selectedInventory.visualSlots != null){ selectedInventory.visualSlots[slotIndex].ShowBorderHighlight(GUIStyle.Red, 0.1f, 0.9f); }
|
||||
SoundPlayer.PlayUISound(GUISoundType.PickItemFail);
|
||||
}
|
||||
if (selectedInventory.visualSlots != null){ selectedInventory.visualSlots[slotIndex].ShowBorderHighlight(GUIStyle.Red, 0.1f, 0.9f); }
|
||||
SoundPlayer.PlayUISound(GUISoundType.PickItemFail);
|
||||
}
|
||||
|
||||
selectedInventory.HideTimer = 2.0f;
|
||||
if (selectedSlot.ParentInventory?.Owner is Item parentItem && parentItem.ParentInventory != null)
|
||||
{
|
||||
for (int i = 0; i < parentItem.ParentInventory.capacity; i++)
|
||||
{
|
||||
if (parentItem.ParentInventory.HideSlot(i)) { continue; }
|
||||
if (parentItem.ParentInventory.slots[i].FirstOrDefault() != parentItem) { continue; }
|
||||
|
||||
highlightedSubInventorySlots.Add(new SlotReference(
|
||||
parentItem.ParentInventory, parentItem.ParentInventory.visualSlots[i],
|
||||
i, false, selectedSlot.ParentInventory));
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
DraggingItems.Clear();
|
||||
DraggingSlot = null;
|
||||
}
|
||||
|
||||
DraggingItems.Clear();
|
||||
}
|
||||
selectedInventory.HideTimer = 2.0f;
|
||||
if (selectedSlot.ParentInventory?.Owner is Item parentItem && parentItem.ParentInventory != null)
|
||||
{
|
||||
for (int i = 0; i < parentItem.ParentInventory.capacity; i++)
|
||||
{
|
||||
if (parentItem.ParentInventory.HideSlot(i)) { continue; }
|
||||
if (parentItem.ParentInventory.slots[i].FirstOrDefault() != parentItem) { continue; }
|
||||
|
||||
if (selectedSlot != null && !CanSelectSlot(selectedSlot))
|
||||
{
|
||||
selectedSlot = null;
|
||||
}
|
||||
highlightedSubInventorySlots.Add(new SlotReference(
|
||||
parentItem.ParentInventory, parentItem.ParentInventory.visualSlots[i],
|
||||
i, false, selectedSlot.ParentInventory));
|
||||
break;
|
||||
}
|
||||
}
|
||||
DraggingItems.Clear();
|
||||
DraggingSlot = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsValidTargetForDragDropGive(Character giver, Character receiver)
|
||||
{
|
||||
if (giver == null || receiver == null) { return false; }
|
||||
if (receiver == giver) { return false; }
|
||||
return receiver.IsInventoryAccessibleTo(giver, IsDragAndDropGiveAllowed ? CharacterInventory.AccessLevel.Allowed : CharacterInventory.AccessLevel.Limited);
|
||||
}
|
||||
|
||||
private static bool CanSelectSlot(SlotReference selectedSlot)
|
||||
@@ -1504,6 +1542,31 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
if (DraggingItems.Any())
|
||||
{
|
||||
DrawDragRelated();
|
||||
}
|
||||
|
||||
if (selectedSlot != null && selectedSlot.Item != null)
|
||||
{
|
||||
Rectangle slotRect = selectedSlot.Slot.Rect;
|
||||
slotRect.Location += selectedSlot.Slot.DrawOffset.ToPoint();
|
||||
if (selectedSlot.TooltipNeedsRefresh())
|
||||
{
|
||||
selectedSlot.RefreshTooltip();
|
||||
}
|
||||
|
||||
if (!slotIconTooltip.IsNullOrEmpty())
|
||||
{
|
||||
DrawToolTip(spriteBatch, slotIconTooltip, slotRect);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawToolTip(spriteBatch, selectedSlot.Tooltip, slotRect);
|
||||
}
|
||||
slotIconTooltip = string.Empty;
|
||||
}
|
||||
|
||||
void DrawDragRelated()
|
||||
{
|
||||
if (DraggingSlot == null || (!DraggingSlot.MouseOn()))
|
||||
{
|
||||
@@ -1521,10 +1584,8 @@ namespace Barotrauma
|
||||
if ((GUI.MouseOn == null || mouseOnHealthInterface) && selectedSlot == null)
|
||||
{
|
||||
var shadowSprite = GUIStyle.GetComponentStyle("OuterGlow").Sprites[GUIComponent.ComponentState.None][0];
|
||||
LocalizedString toolTip = mouseOnHealthInterface ? TextManager.Get("QuickUseAction.UseTreatment") :
|
||||
Character.Controlled.FocusedItem != null ?
|
||||
TextManager.GetWithVariable("PutItemIn", "[itemname]", Character.Controlled.FocusedItem.Name, FormatCapitals.Yes) :
|
||||
TextManager.Get(Screen.Selected is SubEditorScreen editor && editor.EntityMenu.Rect.Contains(PlayerInput.MousePosition) ? "Delete" : "DropItem");
|
||||
|
||||
(LocalizedString toolTip, Color toolTipColor) = GetDragLabelTextAndColor(mouseOnHealthInterface);
|
||||
|
||||
Vector2 nameSize = GUIStyle.Font.MeasureString(DraggingItems.First().Name);
|
||||
Vector2 toolTipSize = GUIStyle.SmallFont.MeasureString(toolTip);
|
||||
@@ -1544,7 +1605,7 @@ namespace Barotrauma
|
||||
|
||||
GUI.DrawString(spriteBatch, textPos + new Vector2(nameSize.X * textOffset, -iconSize / 2), DraggingItems.First().Name, Color.White);
|
||||
GUI.DrawString(spriteBatch, textPos + new Vector2(toolTipSize.X * textOffset, 0), toolTip,
|
||||
color: Character.Controlled.FocusedItem == null && !mouseOnHealthInterface ? GUIStyle.Red : Color.LightGreen,
|
||||
color: toolTipColor,
|
||||
font: GUIStyle.SmallFont);
|
||||
}
|
||||
|
||||
@@ -1587,24 +1648,31 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedSlot != null && selectedSlot.Item != null)
|
||||
(LocalizedString, Color) GetDragLabelTextAndColor(bool mouseOnHealthInterface)
|
||||
{
|
||||
Rectangle slotRect = selectedSlot.Slot.Rect;
|
||||
slotRect.Location += selectedSlot.Slot.DrawOffset.ToPoint();
|
||||
if (selectedSlot.TooltipNeedsRefresh())
|
||||
bool useDragDropGive = IsValidTargetForDragDropGive(Character.Controlled, Character.Controlled.FocusedCharacter);
|
||||
|
||||
Color toolTipColor = Color.LightGreen;
|
||||
|
||||
LocalizedString toolTip;
|
||||
if (mouseOnHealthInterface)
|
||||
{
|
||||
selectedSlot.RefreshTooltip();
|
||||
toolTip = TextManager.Get("QuickUseAction.UseTreatment");
|
||||
}
|
||||
|
||||
if (!slotIconTooltip.IsNullOrEmpty())
|
||||
else if (Character.Controlled.FocusedItem != null)
|
||||
{
|
||||
DrawToolTip(spriteBatch, slotIconTooltip, slotRect);
|
||||
toolTip = TextManager.GetWithVariable("PutItemIn", "[itemname]", Character.Controlled.FocusedItem.Name, FormatCapitals.Yes);
|
||||
}
|
||||
else if (useDragDropGive)
|
||||
{
|
||||
toolTip = TextManager.GetWithVariable("GiveItemTo", "[character]", Character.Controlled.FocusedCharacter.Name, FormatCapitals.Yes);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawToolTip(spriteBatch, selectedSlot.Tooltip, slotRect);
|
||||
toolTipColor = GUIStyle.Red;
|
||||
toolTip = TextManager.Get(Screen.Selected is SubEditorScreen editor && editor.EntityMenu.Rect.Contains(PlayerInput.MousePosition) ? "Delete" : "DropItem");
|
||||
}
|
||||
slotIconTooltip = string.Empty;
|
||||
return (toolTip, toolTipColor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1801,7 +1869,7 @@ namespace Barotrauma
|
||||
DrawSideIcon(deconstructOrder.SymbolSprite, Direction.Right, TextManager.Get("tooltip.markedfordeconstruction"), GUIStyle.Red, out bool mouseOn);
|
||||
if (mouseOn) { availableContextualOrder = (item, Tags.DontDeconstructThis); }
|
||||
}
|
||||
else if (((item.SpawnedInCurrentOutpost && !item.AllowStealing) || (inventory != null && inventory.slots[slotIndex].Items.Any(it => it.SpawnedInCurrentOutpost && !it.AllowStealing))) && CharacterInventory.LimbSlotIcons.ContainsKey(InvSlotType.LeftHand))
|
||||
else if ((item.Illegitimate || (inventory != null && inventory.slots[slotIndex].Items.Any(it => it.Illegitimate))) && CharacterInventory.LimbSlotIcons.ContainsKey(InvSlotType.LeftHand))
|
||||
{
|
||||
DrawSideIcon(CharacterInventory.LimbSlotIcons[InvSlotType.LeftHand], Direction.Left, TextManager.Get("tooltip.stolenitem"), GUIStyle.Red, out _);
|
||||
}
|
||||
|
||||
@@ -326,7 +326,7 @@ namespace Barotrauma
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, bool editing, bool back = true, Color? overrideColor = null)
|
||||
{
|
||||
if (!Visible || (!editing && HiddenInGame) || !SubEditorScreen.IsLayerVisible(this)) { return; }
|
||||
if (!Visible || (!editing && IsHidden) || !SubEditorScreen.IsLayerVisible(this)) { return; }
|
||||
|
||||
if (editing)
|
||||
{
|
||||
@@ -424,7 +424,7 @@ namespace Barotrauma
|
||||
textureScale: Vector2.One * Scale,
|
||||
depth: d);
|
||||
}
|
||||
DrawDecorativeSprites(spriteBatch, DrawPosition, flippedX && Prefab.CanSpriteFlipX, flippedY && Prefab.CanSpriteFlipY, rotation: 0, depth);
|
||||
DrawDecorativeSprites(spriteBatch, DrawPosition, flippedX && Prefab.CanSpriteFlipX, flippedY && Prefab.CanSpriteFlipY, rotation: 0, depth, overrideColor);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -445,7 +445,7 @@ namespace Barotrauma
|
||||
Prefab.DamagedInfectedSprite?.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y) + drawOffset, Infector.HealthColor, Prefab.DamagedInfectedSprite.Origin, RotationRad, Scale, activeSprite.effects, depth - 0.002f);
|
||||
}
|
||||
|
||||
DrawDecorativeSprites(spriteBatch, DrawPosition, flippedX && Prefab.CanSpriteFlipX, flippedY && Prefab.CanSpriteFlipY, -RotationRad, depth);
|
||||
DrawDecorativeSprites(spriteBatch, DrawPosition, flippedX && Prefab.CanSpriteFlipX, flippedY && Prefab.CanSpriteFlipY, -RotationRad, depth, overrideColor);
|
||||
}
|
||||
}
|
||||
else if (body.Enabled)
|
||||
@@ -456,30 +456,49 @@ namespace Barotrauma
|
||||
//don't draw the item on hands if it's also being worn
|
||||
if (GetComponent<Wearable>() is { IsActive: true }) { return; }
|
||||
if (!back) { return; }
|
||||
float depthStep = 0.000001f;
|
||||
if (holdable.Picker.Inventory?.GetItemInLimbSlot(InvSlotType.RightHand) == this)
|
||||
{
|
||||
Limb holdLimb = holdable.Picker.AnimController.GetLimb(LimbType.RightArm);
|
||||
if (holdLimb?.ActiveSprite != null)
|
||||
{
|
||||
depth = holdLimb.ActiveSprite.Depth + holdable.Picker.AnimController.GetDepthOffset() + depthStep * 2;
|
||||
foreach (WearableSprite wearableSprite in holdLimb.WearingItems)
|
||||
{
|
||||
if (!wearableSprite.InheritLimbDepth && wearableSprite.Sprite != null) { depth = Math.Max(wearableSprite.Sprite.Depth + depthStep, depth); }
|
||||
}
|
||||
}
|
||||
depth = GetHeldItemDepth(LimbType.RightHand, depth);
|
||||
}
|
||||
else if (holdable.Picker.Inventory?.GetItemInLimbSlot(InvSlotType.LeftHand) == this)
|
||||
{
|
||||
Limb holdLimb = holdable.Picker.AnimController.GetLimb(LimbType.LeftArm);
|
||||
depth = GetHeldItemDepth(LimbType.LeftHand, depth);
|
||||
}
|
||||
|
||||
float GetHeldItemDepth(LimbType limb, float depth)
|
||||
{
|
||||
//offset used to make sure the item draws just slightly behind the right hand, or slightly in front of the left hand
|
||||
float limbDepthOffset = 0.000001f;
|
||||
float depthOffset = holdable.Picker.AnimController.GetDepthOffset();
|
||||
//use the upper arm as a reference, to ensure the item gets drawn behind / in front of the whole arm (not just the forearm)
|
||||
Limb holdLimb = holdable.Picker.AnimController.GetLimb(limb == LimbType.RightHand ? LimbType.RightArm : LimbType.LeftArm);
|
||||
if (holdLimb?.ActiveSprite != null)
|
||||
{
|
||||
depth = holdLimb.ActiveSprite.Depth + holdable.Picker.AnimController.GetDepthOffset() - depthStep * 2;
|
||||
depth =
|
||||
holdLimb.ActiveSprite.Depth
|
||||
+ depthOffset
|
||||
+ limbDepthOffset * 2 * (limb == LimbType.RightHand ? 1 : -1);
|
||||
foreach (WearableSprite wearableSprite in holdLimb.WearingItems)
|
||||
{
|
||||
if (!wearableSprite.InheritLimbDepth && wearableSprite.Sprite != null) { depth = Math.Min(wearableSprite.Sprite.Depth - depthStep, depth); }
|
||||
if (!wearableSprite.InheritLimbDepth && wearableSprite.Sprite != null)
|
||||
{
|
||||
depth =
|
||||
limb == LimbType.RightHand ?
|
||||
Math.Max(wearableSprite.Sprite.Depth + limbDepthOffset, depth) :
|
||||
Math.Min(wearableSprite.Sprite.Depth - limbDepthOffset, depth);
|
||||
}
|
||||
}
|
||||
var head = holdable.Picker.AnimController.GetLimb(LimbType.Head);
|
||||
if (head != null)
|
||||
{
|
||||
//ensure the holdable item is always drawn in front of the head no matter what the wearables or whatnot do with the sprite depths
|
||||
depth =
|
||||
limb == LimbType.RightHand ?
|
||||
Math.Min(head.Sprite.Depth + depthOffset - limbDepthOffset, depth) :
|
||||
Math.Max(head.Sprite.Depth + depthOffset + limbDepthOffset, depth);
|
||||
}
|
||||
}
|
||||
return depth;
|
||||
}
|
||||
}
|
||||
Vector2 origin = GetSpriteOrigin(activeSprite);
|
||||
@@ -489,7 +508,7 @@ namespace Barotrauma
|
||||
float d = Math.Min(depth + (fadeInBrokenSprite.Sprite.Depth - activeSprite.Depth - 0.000001f), 0.999f);
|
||||
body.Draw(spriteBatch, fadeInBrokenSprite.Sprite, color * fadeInBrokenSpriteAlpha, d, Scale);
|
||||
}
|
||||
DrawDecorativeSprites(spriteBatch, body.DrawPosition, flipX: body.Dir < 0, flipY: false, rotation: body.Rotation, depth: depth);
|
||||
DrawDecorativeSprites(spriteBatch, body.DrawPosition, flipX: body.Dir < 0, flipY: false, rotation: body.Rotation, depth, overrideColor);
|
||||
}
|
||||
|
||||
foreach (var upgrade in Upgrades)
|
||||
@@ -617,11 +636,11 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawDecorativeSprites(SpriteBatch spriteBatch, Vector2 drawPos, bool flipX, bool flipY, float rotation, float depth)
|
||||
public void DrawDecorativeSprites(SpriteBatch spriteBatch, Vector2 drawPos, bool flipX, bool flipY, float rotation, float depth, Color? overrideColor = null)
|
||||
{
|
||||
foreach (var decorativeSprite in Prefab.DecorativeSprites)
|
||||
{
|
||||
Color decorativeSpriteColor = GetSpriteColor(decorativeSprite.Color).Multiply(GetSpriteColor(spriteColor));
|
||||
Color decorativeSpriteColor = overrideColor ?? GetSpriteColor(decorativeSprite.Color).Multiply(GetSpriteColor(spriteColor));
|
||||
if (!spriteAnimState[decorativeSprite].IsActive) { continue; }
|
||||
|
||||
Vector2 offset = decorativeSprite.GetOffset(ref spriteAnimState[decorativeSprite].OffsetState, spriteAnimState[decorativeSprite].RandomOffsetMultiplier,
|
||||
|
||||
Reference in New Issue
Block a user