Drag and Drop + Zoooooooom

Refactored inventory drag & drop to use new global drag & drop management
Enabled Drag & Drop from inventory panel to action bar
Enabled gear and consumable item binding
Fixed stat modifier behavior to allow it to be toggled
Fixed Switch behavior to make it bindable
Added lambda multiplier to aether drive so that stat mod can target it
This commit is contained in:
Reinier Vens 2021-04-21 01:49:07 +01:00
commit 7cfc5cd04f
21 changed files with 352 additions and 323 deletions

View file

@ -109,8 +109,8 @@
<Compile Include="Assets\Scripts\ServerShared\NIH\LiteNetLib\NetPacket.cs" />
<Compile Include="Assets\Scripts\ServerShared\Zone.cs" />
<Compile Include="Assets\Scripts\ServerShared\Agents\Minion.cs" />
<Compile Include="Assets\Scripts\ServerShared\Behaviors\ChargedWeapon.cs" />
<Compile Include="Assets\Scripts\ServerShared\NIH\LiteNetLib\NetUtils.cs" />
<Compile Include="Assets\Scripts\ServerShared\Behaviors\ChargedWeapon.cs" />
<Compile Include="Assets\Scripts\ServerShared\NIH\MIConvexHull\ConvexHull\DataModel.cs" />
<Compile Include="Assets\Scripts\ServerShared\NIH\MIConvexHull\IVertex.cs" />
<Compile Include="Assets\Scripts\ServerShared\NIH\LiteNetLib\BaseChannel.cs" />

View file

@ -65,7 +65,7 @@ MonoBehaviour:
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_text: Stat Name
m_text: Weapon Groups
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 53555f7a2d5e745428813f1b1118734f, type: 2}
m_sharedMaterial: {fileID: -2804126062856497447, guid: 53555f7a2d5e745428813f1b1118734f,

View file

@ -5592,6 +5592,7 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
Dialog: {fileID: 0}
DragParent: {fileID: 0}
Flip: 1
Settings: {fileID: 11400000, guid: cd2344e2001a37544aab0960c164d4ff, type: 2}
GameManager: {fileID: 1009503729}
@ -9907,6 +9908,11 @@ PrefabInstance:
value:
objectReference: {fileID: 11400000, guid: cd2344e2001a37544aab0960c164d4ff,
type: 2}
- target: {fileID: 2279630453886260054, guid: aac073da6df367d499834c926930dd84,
type: 3}
propertyPath: DragParent
value:
objectReference: {fileID: 245842385}
- target: {fileID: 2279630453886260054, guid: aac073da6df367d499834c926930dd84,
type: 3}
propertyPath: ContextMenu
@ -31053,6 +31059,11 @@ PrefabInstance:
value:
objectReference: {fileID: 11400000, guid: cd2344e2001a37544aab0960c164d4ff,
type: 2}
- target: {fileID: 2279630453886260054, guid: aac073da6df367d499834c926930dd84,
type: 3}
propertyPath: DragParent
value:
objectReference: {fileID: 245842385}
- target: {fileID: 2279630453886260054, guid: aac073da6df367d499834c926930dd84,
type: 3}
propertyPath: ContextMenu
@ -36242,6 +36253,7 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
Dialog: {fileID: 0}
DragParent: {fileID: 0}
Flip: 0
Settings: {fileID: 11400000, guid: cd2344e2001a37544aab0960c164d4ff, type: 2}
GameManager: {fileID: 1009503729}

View file

@ -147,15 +147,16 @@ public class ActionBarGearBinding : ActionBarBinding
public ActionBarGearBinding(Entity entity, ActionBarSlot slot, EquippedItem item, IActivatedBehavior behavior) : base(entity, slot)
{
Item = item;
var data = item.EquippableItem.Data.Value as EquippableItemData;
Behavior = behavior;
Slot.QuantityRemaining.gameObject.SetActive(false);
if(!string.IsNullOrEmpty(Item.Data.ActionBarIcon))
{
Slot.Label.gameObject.SetActive(false);
Slot.Icon.gameObject.SetActive(true);
Slot.Icon.gameObject.SetActive(true);
Slot.Label.gameObject.SetActive(false);
if (!string.IsNullOrEmpty(Item.Data.ActionBarIcon))
Slot.Icon.texture = Resources.Load<Texture2D>(Item.Data.ActionBarIcon.Substring("Assets/Resources/".Length).Split('.').First());
}
else Slot.Icon.gameObject.SetActive(false);
else if (data is WeaponItemData weaponItemData)
Slot.Icon.texture = ActionGameManager.Instance.Settings.GetIcon(weaponItemData.WeaponType).texture;
else Slot.Icon.texture = ActionGameManager.Instance.Settings.GetIcon(data.HardpointType).texture;
}
public override void Activate()

View file

@ -166,8 +166,8 @@ public class ActionGameManager : MonoBehaviour
(float2(0, -1), "Rear")
};
private DragAction _dragAction;
private Action<DragAction> _endDragCallback;
public DragObject DragObject { get; private set; }
private Func<DragObject, bool> _endDragCallback;
private List<Story> _stories = new List<Story>();
@ -242,7 +242,7 @@ public class ActionGameManager : MonoBehaviour
Input.Global.Dock.performed += context =>
{
if (EventSystem.current.currentSelectedGameObject?.GetComponent<TMP_InputField>() != null) return;
if (EventSystem.current.currentSelectedGameObject != null && EventSystem.current.currentSelectedGameObject.GetComponent<TMP_InputField>() != null) return;
if (MainMenu.gameObject.activeSelf) return;
if (CurrentEntity == null)
{
@ -356,13 +356,18 @@ public class ActionGameManager : MonoBehaviour
//Debug.Log("Registering binding!");
switch (dragAction)
{
case EquippedItemDragAction equippedItemDragAction:
break;
case ItemInstanceDragAction itemInstanceDragAction:
break;
case WeaponGroupDragAction weaponGroupDragAction:
case EquippedItemDragObject equippedItemDragAction:
var trigger = equippedItemDragAction.EquippedItem.GetBehavior<IActivatedBehavior>();
if (trigger == null) return false;
slot.Binding = new ActionBarGearBinding(CurrentEntity, slot, equippedItemDragAction.EquippedItem, trigger);
return true;
case ItemInstanceDragObject itemInstanceDragAction:
if (!(itemInstanceDragAction.Item.Data.Value is ConsumableItemData consumable)) return false;
slot.Binding = new ActionBarConsumableBinding(CurrentEntity, slot, consumable);
return true;
case WeaponGroupDragObject weaponGroupDragAction:
slot.Binding = new ActionBarWeaponGroupBinding(CurrentEntity, slot, weaponGroupDragAction.Group);
break;
return true;
default:
throw new ArgumentOutOfRangeException(nameof(dragAction));
}
@ -511,12 +516,12 @@ public class ActionGameManager : MonoBehaviour
});
}
public void BeginDrag(DragAction dragAction)
public void BeginDrag(DragObject dragObject)
{
_dragAction = dragAction;
this.DragObject = dragObject;
}
public void RegisterDragTarget(Action<DragAction> onEndDrag)
public void RegisterDragTarget(Func<DragObject, bool> onEndDrag)
{
_endDragCallback = onEndDrag;
}
@ -526,10 +531,11 @@ public class ActionGameManager : MonoBehaviour
_endDragCallback = null;
}
public void EndDrag()
public bool EndDrag()
{
_endDragCallback?.Invoke(_dragAction);
_dragAction = null;
var success = _endDragCallback?.Invoke(DragObject);
DragObject = null;
return success ?? false;
}
public void EnablePlayerInput()
@ -606,7 +612,7 @@ public class ActionGameManager : MonoBehaviour
private void ToggleMainMenu()
{
if (EventSystem.current.currentSelectedGameObject?.GetComponent<TMP_InputField>() != null) return;
if (EventSystem.current.currentSelectedGameObject != null && EventSystem.current.currentSelectedGameObject.GetComponent<TMP_InputField>() != null) return;
if (CurrentEntity == null) return;
if (MainMenu.gameObject.activeSelf)
{
@ -645,7 +651,7 @@ public class ActionGameManager : MonoBehaviour
private void ToggleMenuTab(MenuTab tab)
{
if (EventSystem.current.currentSelectedGameObject?.GetComponent<TMP_InputField>() != null) return;
if (EventSystem.current.currentSelectedGameObject != null && EventSystem.current.currentSelectedGameObject.GetComponent<TMP_InputField>() != null) return;
if (MainMenu.gameObject.activeSelf) return;
if (Menu.gameObject.activeSelf && Menu.CurrentTab == tab)
{
@ -1082,11 +1088,11 @@ public class ActionGameManager : MonoBehaviour
}
}
public abstract class DragAction{}
public abstract class DragObject{}
public class WeaponGroupDragAction : DragAction
public class WeaponGroupDragObject : DragObject
{
public WeaponGroupDragAction(int group)
public WeaponGroupDragObject(int group)
{
Group = group;
}
@ -1094,22 +1100,36 @@ public class WeaponGroupDragAction : DragAction
public int Group { get; }
}
public class ItemInstanceDragAction : DragAction
public abstract class ItemDragObject : DragObject
{
public ItemInstanceDragAction(ItemInstance item)
protected ItemDragObject(int2 originCellOffset, ItemInstance item)
{
OriginCellOffset = originCellOffset;
Item = item;
}
public ItemInstance Item { get; }
public int2 OriginCellOffset { get; }
}
public class EquippedItemDragAction : DragAction
public class ItemInstanceDragObject : ItemDragObject
{
public EquippedItemDragAction(EquippedItem item)
public ItemInstanceDragObject(ItemInstance item, EquippedCargoBay originInventory, int2 originCellOffset) : base(originCellOffset, item)
{
Item = item;
OriginInventory = originInventory;
}
public EquippedItem Item { get; }
public EquippedCargoBay OriginInventory { get; }
}
public class EquippedItemDragObject : ItemDragObject
{
public EquippedItemDragObject(EquippedItem item, Entity originEntity, int2 originCellOffset) : base(originCellOffset, item.EquippableItem)
{
EquippedItem = item;
OriginEntity = originEntity;
}
public EquippedItem EquippedItem { get; }
public Entity OriginEntity { get; }
}

View file

@ -43,6 +43,7 @@ public class GameSettings : ScriptableObject
[HideInInspector] public Sprite[] WeaponFireTypeIcons;
[HideInInspector] public Sprite[] WeaponModifierIcons;
public Sprite GetIcon(HardpointType type) => ItemIcons[(int) type];
public Sprite GetIcon(WeaponType type) => WeaponTypeIcons[(int) type];
public Sprite GetIcon(WeaponRange range) => WeaponRangeIcons[(int) range];
public Sprite GetIcon(WeaponCaliber caliber) => WeaponCaliberIcons[(int) caliber];

View file

@ -22,19 +22,22 @@ public class AetherDriveData : BehaviorData
[Inspectable, JsonProperty("couplingLambdas"), Key(4)]
public float3 CouplingLambda;
[Inspectable, JsonProperty("couplingEfficiency"), Key(5), RuntimeInspectable]
[Inspectable, JsonProperty("lambdaMultiplier"), Key(5)]
public PerformanceStat LambdaMultiplier;
[Inspectable, JsonProperty("couplingEfficiency"), Key(6), RuntimeInspectable]
public PerformanceStat CouplingEfficiency;
[Inspectable, JsonProperty("torque"), Key(6), RuntimeInspectable]
[Inspectable, JsonProperty("torque"), Key(7), RuntimeInspectable]
public PerformanceStat Torque;
[Inspectable, JsonProperty("torqueProfile"), Key(7), RuntimeInspectable]
[Inspectable, JsonProperty("torqueProfile"), Key(8), RuntimeInspectable]
public BezierCurve TorqueProfile;
[Inspectable, JsonProperty("draw"), Key(8), RuntimeInspectable]
[Inspectable, JsonProperty("draw"), Key(9), RuntimeInspectable]
public PerformanceStat EnergyDraw;
[Inspectable, JsonProperty("passiveCoupling"), Key(9), RuntimeInspectable]
[Inspectable, JsonProperty("passiveCoupling"), Key(10), RuntimeInspectable]
public PerformanceStat PassiveCoupling;
public override Behavior CreateInstance(EquippedItem item)
@ -88,7 +91,7 @@ public class AetherDrive : Behavior
Thrust = (Rpm - AetheriaMath.Decay(Rpm, _data.CouplingLambda, dt)) * _data.RotorMass * efficiency;
var couplingLambda = _data.CouplingLambda * max(abs(_axis), Evaluate(_data.PassiveCoupling));
var couplingLambda = _data.CouplingLambda * Item.Evaluate(_data.LambdaMultiplier) * max(abs(_axis), Evaluate(_data.PassiveCoupling));
var previousRpm = Rpm;
Rpm = AetheriaMath.Decay(Rpm, couplingLambda, dt);
var rpmLoss = previousRpm - Rpm;

View file

@ -34,7 +34,7 @@ public class StatModifierData : BehaviorData
}
[Order(-4)]
public class StatModifier : Behavior, IInitializableBehavior, IDisposable
public class StatModifier : Behavior, IInitializableBehavior, IDisposable, IAlwaysUpdatedBehavior
{
private StatModifierData _data;
@ -42,6 +42,9 @@ public class StatModifier : Behavior, IInitializableBehavior, IDisposable
private static Type[] _statObjects;
private bool _applied;
private bool _executed;
private static Type[] StatObjects => _statObjects = _statObjects ?? typeof(BehaviorData).GetAllChildClasses()
.Concat(typeof(EquippableItemData).GetAllChildClasses()).ToArray();
@ -83,19 +86,41 @@ public class StatModifier : Behavior, IInitializableBehavior, IDisposable
}
}
public override bool Execute(float dt)
private void ApplyModifier()
{
_applied = true;
foreach (var stat in _stats)
(_data.Type == StatModifierType.Constant
? stat.GetConstantModifiers(Entity)
: stat.GetScaleModifiers(Entity))[this] = Evaluate(_data.Modifier);
}
private void RemoveModifier()
{
_applied = false;
foreach (var stat in _stats)
(_data.Type == StatModifierType.Constant ? stat.GetConstantModifiers(Entity) : stat.GetScaleModifiers(Entity)).Remove(this);
}
public override bool Execute(float dt)
{
_executed = true;
return true;
}
public void Dispose()
{
foreach (var stat in _stats)
(_data.Type == StatModifierType.Constant ? stat.GetConstantModifiers(Entity) : stat.GetScaleModifiers(Entity)).Remove(this);
if(_applied)
RemoveModifier();
}
public void Update(float delta)
{
if(_executed && !_applied)
ApplyModifier();
if(!_executed && _applied)
RemoveModifier();
_executed = false;
}
}

View file

@ -20,7 +20,7 @@ public class SwitchData : BehaviorData
}
}
public class Switch : Behavior
public class Switch : Behavior, IActivatedBehavior
{
private SwitchData _data;
@ -39,4 +39,14 @@ public class Switch : Behavior
{
return Activated;
}
public void Activate()
{
Activated = true;
}
public void Deactivate()
{
Activated = false;
}
}

View file

@ -14,17 +14,18 @@ public class TypeFormatter : MessagePack.Formatters.IMessagePackFormatter<Type>
public void Serialize(ref MessagePackWriter writer, Type value, MessagePackSerializerOptions options)
{
writer.Write(value.AssemblyQualifiedName);
writer.Write(value == null ? "" : value.AssemblyQualifiedName);
}
public Type Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
{
if (reader.IsNil)
{
throw new InvalidOperationException("typecode is null, struct not supported");
return null; //throw new InvalidOperationException("typecode is null, struct not supported");
}
var assemblyQualifiedName = reader.ReadString();
if (string.IsNullOrEmpty(assemblyQualifiedName)) return null;
return Type.GetType(assemblyQualifiedName);
}

View file

@ -992,7 +992,7 @@ public class ConsumableItemEffect
Data = (ConsumableItemData) item.Data.Value;
RemainingDuration = Data.Duration;
Behaviors = Data.StatModifiers
Behaviors = Data.Behaviors
.Select(bd => bd.CreateInstance(this))
.ToArray();
}
@ -1117,7 +1117,8 @@ public class EquippedItem
var quality = pow(EquippableItem.Quality, stat.QualityExponent);
var scaleModifier = 1.0f;
foreach (var value in stat.GetScaleModifiers(Entity).Values) scaleModifier = scaleModifier * value;
var scaleModifiers = stat.GetScaleModifiers(Entity).Values;
foreach (var value in scaleModifiers) scaleModifier *= value;
float constantModifier = 0;
foreach (var value in stat.GetConstantModifiers(Entity).Values) constantModifier += value;
@ -1150,9 +1151,6 @@ public class EquippedItem
public void Update(float delta)
{
foreach (var behavior in Behaviors)
if(behavior is IAlwaysUpdatedBehavior alwaysUpdatedBehavior) alwaysUpdatedBehavior.Update(delta);
if (Active.Value)
{
foreach (var group in BehaviorGroups.Values)
@ -1164,9 +1162,12 @@ public class EquippedItem
}
}
}
foreach (var behavior in Behaviors)
if(behavior is IAlwaysUpdatedBehavior alwaysUpdatedBehavior) alwaysUpdatedBehavior.Update(delta);
}
public T GetBehavior<T>() where T : Behavior
public T GetBehavior<T>() where T : class
{
foreach (var behavior in Behaviors)
if (behavior is T b)

View file

@ -302,7 +302,7 @@ public class CompoundCommodityData : CraftedItemData
public class ConsumableItemData : CraftedItemData
{
[Inspectable, JsonProperty("behaviors"), Key(10)]
public List<StatModifierData> StatModifiers = new List<StatModifierData>();
public List<BehaviorData> Behaviors = new List<BehaviorData>();
[Inspectable, JsonProperty("stackable"), Key(11)]
public bool Stackable;

View file

@ -281,7 +281,7 @@ public class Ship : Entity
deltaRot = 0;
Direction = lerp(Direction, look, min(delta, 1));
}
deltaRot = pow(abs(deltaRot), .75f) * sign(deltaRot);
deltaRot = pow(abs(deltaRot), .5f) * sign(deltaRot);
foreach (var thruster in _clockwiseThrusters) thruster.Axis += deltaRot;
foreach (var thruster in _counterClockwiseThrusters) thruster.Axis += -deltaRot;

View file

@ -79,213 +79,6 @@ public class InventoryMenu : MonoBehaviour
PropertiesPanel.GameManager = GameManager;
foreach (var panel in InventoryPanels)
{
panel.OnBeginDragAsObservable().Subscribe(data =>
{
//Debug.Log($"Begin drag on panel {panel.name}");
if (data is InventoryCargoEventData cargoEvent)
{
var item = cargoEvent.CargoBay.Occupancy[cargoEvent.Position.x, cargoEvent.Position.y];
if (item != null)
{
var itemData = item.Data.Value;
var itemPosition = cargoEvent.CargoBay.Cargo[item];
_originalOccupancy = cargoEvent.CargoBay.Data.InteriorShape.Inset(itemData.Shape, itemPosition, item.Rotation);
_originalRotation = item.Rotation;
_originalPanel = panel;
_dragItem = item;
_dragCellOffset = itemPosition - cargoEvent.Position;
_dragCells = _originalOccupancy.Coordinates
.Select(v => Instantiate(panel.CellInstances[v], DragParent, true).transform).ToArray();
foreach(var cell in _dragCells)
{
foreach (var component in cell.GetComponentsInChildren<ObservableTriggerBase>())
component.enabled = false;
cell.GetComponentInChildren<Image>().raycastTarget = false;
}
_dragOffsets = _dragCells.Select(x => (Vector2) x.position - data.PointerEventData.position).ToArray();
panel.IgnoreOccupancy = _originalOccupancy;
panel.RefreshCells(_originalOccupancy.Expand().Coordinates);
AkSoundEngine.PostEvent("Pickup", gameObject);
}
}
else if (data is InventoryEntityEventData entityEvent)
{
if(!entityEvent.Entity.Active)
{
var item = entityEvent.Entity.GearOccupancy[entityEvent.Position.x, entityEvent.Position.y];
if (item != null)
{
var itemData = GameManager.ItemManager.GetData(item.EquippableItem);
var hullData = GameManager.ItemManager.GetData(entityEvent.Entity.Hull);
_originalRotation = item.EquippableItem.Rotation;
_originalEquippedItem = entityEvent.Entity.GearOccupancy[data.Position.x, data.Position.y];
_originalOccupancy = hullData.Shape.Inset(itemData.Shape, item.Position, item.EquippableItem.Rotation);
_originalPanel = panel;
_dragItem = item.EquippableItem;
_dragCellOffset = item.Position - entityEvent.Position;
_dragCells = _originalOccupancy.Coordinates
.Select(v => Instantiate(panel.CellInstances[v], DragParent, true).transform).ToArray();
foreach (var cell in _dragCells)
{
foreach (var component in cell.GetComponentsInChildren<ObservableTriggerBase>())
component.enabled = false;
cell.GetComponentInChildren<Image>().raycastTarget = false;
}
_dragOffsets = _dragCells.Select(x => (Vector2) x.position - data.PointerEventData.position).ToArray();
panel.IgnoreOccupancy = _originalOccupancy;
panel.RefreshCells(_originalOccupancy.Expand().Coordinates);
AkSoundEngine.PostEvent("Pickup", gameObject);
}
}
}
});
panel.OnDragAsObservable().Subscribe(data =>
{
if (_dragItem == null) return;
for (var i = 0; i < _dragCells.Length; i++)
_dragCells[i].position = new Vector3(
data.PointerEventData.position.x + _dragOffsets[i].x,
data.PointerEventData.position.y + _dragOffsets[i].y,
_dragCells[i].position.z);
});
panel.OnEndDragAsObservable().Subscribe(data =>
{
if (_dragItem == null) return;
if (_dragTargetValid)
{
if (data is InventoryCargoEventData cargoEvent)
{
cargoEvent.CargoBay.Remove(_dragItem);
_dragTargetPanel.DropItem(_dragItem, _dragTargetPosition);
if(_dragTargetPanel.Target == InventoryPanelTarget.Cargo)
AkSoundEngine.PostEvent("Drop", gameObject);
else
AkSoundEngine.PostEvent("Equip", gameObject);
}
else if (data is InventoryEntityEventData entityEvent)
{
if (entityEvent.Entity.TryUnequip(_originalEquippedItem) != null)
{
_dragTargetPanel.DropItem(_dragItem, _dragTargetPosition);
AkSoundEngine.PostEvent("Unequip", gameObject);
}
else
{
AkSoundEngine.PostEvent("UI_Fail", gameObject);
Dialog.Clear();
Dialog.Title.text = "Unable to move item!";
Dialog.AddProperty("Verify that cargo bays are empty before un-equipping them.");
Dialog.Show();
Dialog.MoveToCursor();
}
}
_dragTargetPanel.FakeOccupancy = null;
}
else
{
_dragItem.Rotation = _originalRotation;
}
if (_destroyItem)
{
if (data is InventoryCargoEventData cargoEvent)
{
cargoEvent.CargoBay.Remove(_dragItem);
}
else if (data is InventoryEntityEventData entityEvent)
{
if (entityEvent.Entity.TryUnequip(_originalEquippedItem) == null)
{
Dialog.Clear();
Dialog.Title.text = "Unable to destroy item!";
Dialog.AddProperty("Verify that cargo bays are empty before un-equipping them.");
Dialog.Show();
Dialog.MoveToCursor();
}
}
}
panel.IgnoreOccupancy = null;
panel.RefreshCells();
if(_dragTargetPanel!=panel && _dragTargetPanel != null)
_dragTargetPanel.RefreshCells();
_dragItem = null;
foreach (var cell in _dragCells) Destroy(cell.gameObject);
});
Action floatCells = () =>
{
foreach (var cell in _dragCells) cell.gameObject.SetActive(true);
_dragTargetValid = false;
};
panel.OnPointerEnterAsObservable().Subscribe(data =>
{
if (_dragItem == null) return;
// Debug.Log($"Pointer entered {data.Position}");
// if(panel != _originalPanel)
// _originalPanel.RefreshCells();
_dragTargetPanel = panel;
_lastDragPosition = data.Position;
_dragTargetPosition = data.Position + _dragCellOffset;
if (data is InventoryCargoEventData cargoEvent)
{
if (cargoEvent.CargoBay.ItemFits(_dragItem, _dragTargetPosition))
{
foreach (var cell in _dragCells) cell.gameObject.SetActive(false);
var itemData = _dragItem.Data.Value;
panel.FakeItem = _dragItem;
panel.FakeOccupancy = cargoEvent.CargoBay.Data.InteriorShape.Inset(itemData.Shape, _dragTargetPosition, _dragItem.Rotation);
_dragTargetValid = true;
panel.RefreshCells();
}
}
else if (data is InventoryEntityEventData entityEvent)
{
var eqItem = _dragItem as EquippableItem;
var hullData = GameManager.ItemManager.GetData(entityEvent.Entity.Hull);
if (eqItem != null && entityEvent.Entity.ItemFits(eqItem, _dragTargetPosition))
{
foreach (var cell in _dragCells) cell.gameObject.SetActive(false);
var itemData = _dragItem.Data.Value;
panel.FakeEquipment = _originalEquippedItem;
panel.FakeOccupancy = hullData.Shape.Inset(itemData.Shape, _dragTargetPosition, _dragItem.Rotation);
_dragTargetValid = true;
panel.RefreshCells();
}
}
});
panel.OnPointerExitAsObservable().Subscribe(data =>
{
if (_dragItem == null) return;
if (data.Position.Equals(_lastDragPosition) || !_dragTargetValid)
{
panel.FakeItem = null;
panel.FakeOccupancy = null;
panel.RefreshCells();
// if (_originalPanel != panel)
// {
// _originalPanel.FakeItem = null;
// _originalPanel.FakeOccupancy = null;
// _originalPanel.RefreshCells();
// }
floatCells();
}
});
panel.OnClickAsObservable().Subscribe(e =>
{
if (e.data is InventoryCargoEventData cargoEvent)

View file

@ -21,6 +21,7 @@ using int2 = Unity.Mathematics.int2;
public class InventoryPanel : MonoBehaviour, IPointerClickHandler
{
public ConfirmationDialog Dialog;
public RectTransform DragParent;
public bool Flip;
public GameSettings Settings;
public ActionGameManager GameManager;
@ -52,19 +53,18 @@ public class InventoryPanel : MonoBehaviour, IPointerClickHandler
public float DoubleClickTime = .5f;
public float HitDamageThreshold = 1;
Subject<InventoryEventData> _onBeginDrag;
Subject<InventoryEventData> _onDrag;
Subject<InventoryEventData> _onEndDrag;
// Subject<InventoryEventData> _onBeginDrag;
// Subject<InventoryEventData> _onDrag;
// Subject<InventoryEventData> _onEndDrag;
Subject<(InventoryEventData data, int clickCount)> _onClick;
Subject<InventoryEventData> _onPointerEnter;
Subject<InventoryEventData> _onPointerExit;
// Subject<InventoryEventData> _onPointerEnter;
// Subject<InventoryEventData> _onPointerExit;
private Entity _displayedEntity;
private EquippedCargoBay _displayedCargo;
private Texture2D _temperatureTexture;
private RectTransform _firstRect;
public EquippedItem FakeEquipment;
public ItemInstance FakeItem;
public Shape FakeOccupancy;
public Shape IgnoreOccupancy;
@ -268,6 +268,10 @@ public class InventoryPanel : MonoBehaviour, IPointerClickHandler
public void Display(Entity entity, bool hud = false, bool thermal = false)
{
Clear();
_subscriptions.Add(entity.Equipment.ObserveAdd().Subscribe(_ => RefreshCells()));
_subscriptions.Add(entity.Equipment.ObserveRemove().Subscribe(_ => RefreshCells()));
_thermal = thermal;
_hud = hud;
@ -352,15 +356,105 @@ public class InventoryPanel : MonoBehaviour, IPointerClickHandler
_onClick?.OnNext((new InventoryEntityEventData(data, v, entity), _clickCount));
});
cell.BeginDragTrigger.OnBeginDragAsObservable()
.Subscribe(data => _onBeginDrag?.OnNext(new InventoryEntityEventData(data, v, entity)));
.Subscribe(data =>
{
//Debug.Log("Entity Drag Start");
var item = entity.GearOccupancy[v.x, v.y];
if (item != null)
{
var originalOccupancy = hullData.Shape.Inset(item.Data.Shape, item.Position, item.EquippableItem.Rotation);
_dragCells = originalOccupancy.Coordinates
.Select(v1 => Instantiate(CellInstances[v1], DragParent, true).transform).ToArray();
foreach(var dragCell in _dragCells)
{
DestroyImmediate(dragCell.GetComponent<Prototype>());
foreach (var component in dragCell.GetComponentsInChildren<ObservableTriggerBase>())
component.enabled = false;
foreach (var img in dragCell.GetComponentsInChildren<Image>())
img.color = new Color(img.color.r, img.color.g, img.color.b, img.color.a * .5f);
dragCell.GetComponentInChildren<Image>().raycastTarget = false;
}
_dragOffsets = _dragCells.Select(x => (Vector2) x.position - data.position).ToArray();
IgnoreOccupancy = originalOccupancy;
RefreshCells();
_originalRotation = item.EquippableItem.Rotation;
GameManager.BeginDrag(new EquippedItemDragObject(item, entity, item.Position - v));
AkSoundEngine.PostEvent("Pickup", gameObject);
}
});
cell.DragTrigger.OnDragAsObservable()
.Subscribe(data => _onDrag?.OnNext(new InventoryEntityEventData(data, v, entity)));
.Subscribe(data =>
{
for (var i = 0; i < _dragCells.Length; i++)
_dragCells[i].position = new Vector3(
data.position.x + _dragOffsets[i].x,
data.position.y + _dragOffsets[i].y,
_dragCells[i].position.z);
});
cell.EndDragTrigger.OnEndDragAsObservable()
.Subscribe(data => _onEndDrag?.OnNext(new InventoryEntityEventData(data, v, entity)));
.Subscribe(data =>
{
//Debug.Log("Entity Drag End");
IgnoreOccupancy = null;
if (!GameManager.EndDrag())
entity.GearOccupancy[v.x, v.y].EquippableItem.Rotation = _originalRotation;
foreach(var dragObject in _dragCells)
Destroy(dragObject.gameObject);
_dragCells = null;
RefreshCells();
});
cell.PointerEnterTrigger.OnPointerEnterAsObservable()
.Subscribe(data => _onPointerEnter?.OnNext(new InventoryEntityEventData(data, v, entity)));
.Subscribe(data =>
{
//Debug.Log("Entity Pointer Enter");
if (!(GameManager.DragObject is ItemDragObject itemDragObject)) return;
var item = itemDragObject.Item;
var itemData = item.Data.Value;
if (!(item is EquippableItem equippableItem)) return;
var placementPosition = v + itemDragObject.OriginCellOffset;
if (entity.ItemFits(equippableItem, placementPosition))
{
//foreach (var cell in _dragCells) cell.gameObject.SetActive(false);
FakeItem = item;
FakeOccupancy = hullData.Shape.Inset(itemData.Shape, placementPosition, item.Rotation);
RefreshCells();
GameManager.RegisterDragTarget(drag =>
{
//Debug.Log("Entity Drag Callback");
if (GameManager.DragObject is EquippedItemDragObject equippedItemDragObject)
{
if(equippedItemDragObject.OriginEntity.TryUnequip(equippedItemDragObject.EquippedItem) == null)
{
AkSoundEngine.PostEvent("UI_Fail", gameObject);
Dialog.Clear();
Dialog.Title.text = "Unable to move item!";
Dialog.AddProperty("Verify that cargo bays are empty before un-equipping them.");
Dialog.Show();
Dialog.MoveToCursor();
}
else
AkSoundEngine.PostEvent("Unequip", gameObject);
}
else if (GameManager.DragObject is ItemInstanceDragObject itemInstanceDragObject)
itemInstanceDragObject.OriginInventory.Remove(itemInstanceDragObject.Item);
FakeOccupancy = null;
entity.TryEquip(equippableItem, placementPosition);
RefreshCells();
AkSoundEngine.PostEvent("Equip", gameObject);
return false;
});
}
});
cell.PointerExitTrigger.OnPointerExitAsObservable()
.Subscribe(data => _onPointerExit?.OnNext(new InventoryEntityEventData(data, v, entity)));
.Subscribe(data =>
{
if (!(GameManager.DragObject is ItemDragObject)) return;
FakeItem = null;
FakeOccupancy = null;
RefreshCells();
GameManager.UnregisterDragTarget();
});
}
}
else
@ -448,6 +542,9 @@ public class InventoryPanel : MonoBehaviour, IPointerClickHandler
{
Clear();
_subscriptions.Add(cargo.Cargo.ObserveAdd().Subscribe(_ => RefreshCells()));
_subscriptions.Add(cargo.Cargo.ObserveRemove().Subscribe(_ => RefreshCells()));
_displayedCargo = cargo;
_displayedEntity = null;
@ -479,15 +576,103 @@ public class InventoryPanel : MonoBehaviour, IPointerClickHandler
_onClick?.OnNext((new InventoryCargoEventData(data, v, cargo), _clickCount));
});
cell.BeginDragTrigger.OnBeginDragAsObservable()
.Subscribe(data => _onBeginDrag?.OnNext(new InventoryCargoEventData(data, v, cargo)));
.Subscribe(data =>
{
//Debug.Log("Inventory Drag Start");
var item = cargo.Occupancy[v.x, v.y];
if (item != null)
{
var itemPosition = cargo.Cargo[item];
var itemData = item.Data.Value;
var originalOccupancy = cargo.Data.InteriorShape.Inset(itemData.Shape, itemPosition, item.Rotation);
_dragCells = originalOccupancy.Coordinates
.Select(v1 => Instantiate(CellInstances[v1], DragParent, true).transform).ToArray();
foreach(var dragCell in _dragCells)
{
DestroyImmediate(dragCell.GetComponent<Prototype>());
foreach (var component in dragCell.GetComponentsInChildren<ObservableTriggerBase>())
component.enabled = false;
foreach (var img in dragCell.GetComponentsInChildren<Image>())
img.color = new Color(img.color.r, img.color.g, img.color.b, img.color.a * .5f);
dragCell.GetComponentInChildren<Image>().raycastTarget = false;
}
_dragOffsets = _dragCells.Select(x => (Vector2) x.position - data.position).ToArray();
IgnoreOccupancy = originalOccupancy;
RefreshCells();
_originalRotation = item.Rotation;
GameManager.BeginDrag(new ItemInstanceDragObject(item, cargo, cargo.Cargo[item] - v));
AkSoundEngine.PostEvent("Pickup", gameObject);
}
});
cell.DragTrigger.OnDragAsObservable()
.Subscribe(data => _onDrag?.OnNext(new InventoryCargoEventData(data, v, cargo)));
.Subscribe(data =>
{
for (var i = 0; i < _dragCells.Length; i++)
_dragCells[i].position = new Vector3(
data.position.x + _dragOffsets[i].x,
data.position.y + _dragOffsets[i].y,
_dragCells[i].position.z);
});
cell.EndDragTrigger.OnEndDragAsObservable()
.Subscribe(data => _onEndDrag?.OnNext(new InventoryCargoEventData(data, v, cargo)));
.Subscribe(data =>
{
//Debug.Log("Inventory Drag End");
IgnoreOccupancy = null;
GameManager.EndDrag();
foreach(var dragObject in _dragCells)
Destroy(dragObject.gameObject);
_dragCells = null;
});
cell.PointerEnterTrigger.OnPointerEnterAsObservable()
.Subscribe(data => _onPointerEnter?.OnNext(new InventoryCargoEventData(data, v, cargo)));
.Subscribe(data =>
{
//Debug.Log("Inventory Pointer Enter");
if (!(GameManager.DragObject is ItemDragObject itemDragObject)) return;
var item = itemDragObject.Item;
var itemData = item.Data.Value;
var placementPosition = v + itemDragObject.OriginCellOffset;
if (cargo.ItemFits(item, placementPosition))
{
//foreach (var cell in _dragCells) cell.gameObject.SetActive(false);
FakeItem = item;
FakeOccupancy = cargo.Data.InteriorShape.Inset(itemData.Shape, placementPosition, item.Rotation);
RefreshCells();
GameManager.RegisterDragTarget(drag =>
{
//Debug.Log("Inventory Drag Callback");
if (GameManager.DragObject is EquippedItemDragObject equippedItemDragObject)
{
if(equippedItemDragObject.OriginEntity.TryUnequip(equippedItemDragObject.EquippedItem) == null)
{
AkSoundEngine.PostEvent("UI_Fail", gameObject);
Dialog.Clear();
Dialog.Title.text = "Unable to move item!";
Dialog.AddProperty("Verify that cargo bays are empty before un-equipping them.");
Dialog.Show();
Dialog.MoveToCursor();
}
else
AkSoundEngine.PostEvent("Unequip", gameObject);
}
else if (GameManager.DragObject is ItemInstanceDragObject itemInstanceDragObject)
itemInstanceDragObject.OriginInventory.Remove(itemInstanceDragObject.Item);
cargo.TryStore(item, placementPosition);
FakeOccupancy = null;
AkSoundEngine.PostEvent("Drop", gameObject);
return true;
});
}
});
cell.PointerExitTrigger.OnPointerExitAsObservable()
.Subscribe(data => _onPointerExit?.OnNext(new InventoryCargoEventData(data, v, cargo)));
.Subscribe(data =>
{
if (!(GameManager.DragObject is ItemDragObject)) return;
FakeItem = null;
FakeOccupancy = null;
RefreshCells();
GameManager.UnregisterDragTarget();
});
CellInstances.Add(v, cell);
}
}
@ -511,7 +696,7 @@ public class InventoryPanel : MonoBehaviour, IPointerClickHandler
var spriteIndex = 0;
var interior = hullData.InteriorCells[v];
var item = FakeOccupancy?[v]??false ? FakeEquipment : IgnoreOccupancy?[v]??false ? null : _displayedEntity.GearOccupancy[v.x, v.y];
var item = FakeOccupancy?[v]??false ? FakeItem : IgnoreOccupancy?[v]??false ? null : _displayedEntity.GearOccupancy[v.x, v.y]?.EquippableItem;
var hardpoint = _displayedEntity.Hardpoints[v.x, v.y];
bool HardpointMatch(int2 offset)
@ -520,7 +705,7 @@ public class InventoryPanel : MonoBehaviour, IPointerClickHandler
return !(
hullData.Shape[v2] &&
_displayedEntity.Hardpoints[v2.x, v2.y] == hardpoint &&
(FakeOccupancy?[v2]??false ? FakeEquipment : IgnoreOccupancy?[v2]??false ? null : _displayedEntity.GearOccupancy[v2.x, v2.y]) == item
(FakeOccupancy?[v2]??false ? FakeItem : IgnoreOccupancy?[v2]??false ? null : _displayedEntity.GearOccupancy[v2.x, v2.y]?.EquippableItem) == item
);
}
@ -531,7 +716,7 @@ public class InventoryPanel : MonoBehaviour, IPointerClickHandler
hullData.Shape[v2] && (
!interior && !hullData.InteriorCells[v2] && _displayedEntity.Hardpoints[v2.x, v2.y] == null ||
interior && item != null &&
(FakeOccupancy?[v2]??false ? FakeEquipment : IgnoreOccupancy?[v2]??false ? null : _displayedEntity.GearOccupancy[v2.x, v2.y]) == item
(FakeOccupancy?[v2]??false ? FakeItem : IgnoreOccupancy?[v2]??false ? null : _displayedEntity.GearOccupancy[v2.x, v2.y]?.EquippableItem) == item
)
);
}
@ -619,14 +804,15 @@ public class InventoryPanel : MonoBehaviour, IPointerClickHandler
var hullData = GameManager.ItemManager.GetData(_displayedEntity.Hull) as HullData;
var interior = hullData.InteriorCells[position];
var hardpoint = _displayedEntity.Hardpoints[position.x, position.y];
var item = FakeOccupancy?[position] ?? false ? FakeEquipment : IgnoreOccupancy?[position] ?? false ? null : _displayedEntity.GearOccupancy[position.x, position.y];
var item = (FakeOccupancy?[position] ?? false ? FakeItem :
IgnoreOccupancy?[position] ?? false ? null : _displayedEntity.GearOccupancy[position.x, position.y]?.EquippableItem) as EquippableItem;
if (_hud)
{
if (_displayedEntity.Armor[position.x, position.y] > .01f)
return Settings.ArmorGradient.Evaluate(_displayedEntity.Armor[position.x, position.y] / _displayedEntity.MaxArmor[position.x, position.y]);
if (item != null) return Settings.DurabilityGradient.Evaluate(item.EquippableItem.Durability / _displayedEntity.ItemManager.GetData(item.EquippableItem).Durability);
if (item != null) return Settings.DurabilityGradient.Evaluate(item.Durability / _displayedEntity.ItemManager.GetData(item).Durability);
return float3(.25f).ToColor();
}
@ -671,21 +857,6 @@ public class InventoryPanel : MonoBehaviour, IPointerClickHandler
}
}
public bool DropItem(ItemInstance item, int2 position)
{
if (_displayedEntity != null && item is EquippableItem equippableItem)
{
return _displayedEntity.TryEquip(equippableItem, position);
}
if(_displayedCargo != null)
{
return _displayedCargo.TryStore(item, position);
}
return false;
}
public bool CanDropItem(ItemInstance item)
{
if (_displayedEntity != null && item is EquippableItem equippableItem)
@ -717,12 +888,16 @@ public class InventoryPanel : MonoBehaviour, IPointerClickHandler
}
public Subject<PointerEventData> OnBackgroundClick = new Subject<PointerEventData>();
private Transform[] _dragCells;
private Vector2[] _dragOffsets;
private ItemRotation _originalRotation;
public Subject<(InventoryEventData data, int clickCount)> OnClickAsObservable() => _onClick ?? (_onClick = new Subject<(InventoryEventData data, int clickCount)>());
public UniRx.IObservable<InventoryEventData> OnBeginDragAsObservable() => _onBeginDrag ?? (_onBeginDrag = new Subject<InventoryEventData>());
public UniRx.IObservable<InventoryEventData> OnDragAsObservable() => _onDrag ?? (_onDrag = new Subject<InventoryEventData>());
public UniRx.IObservable<InventoryEventData> OnEndDragAsObservable() => _onEndDrag ?? (_onEndDrag = new Subject<InventoryEventData>());
public UniRx.IObservable<InventoryEventData> OnPointerEnterAsObservable() => _onPointerEnter ?? (_onPointerEnter = new Subject<InventoryEventData>());
public UniRx.IObservable<InventoryEventData> OnPointerExitAsObservable() => _onPointerExit ?? (_onPointerExit = new Subject<InventoryEventData>());
// public UniRx.IObservable<InventoryEventData> OnBeginDragAsObservable() => _onBeginDrag ?? (_onBeginDrag = new Subject<InventoryEventData>());
// public UniRx.IObservable<InventoryEventData> OnDragAsObservable() => _onDrag ?? (_onDrag = new Subject<InventoryEventData>());
// public UniRx.IObservable<InventoryEventData> OnEndDragAsObservable() => _onEndDrag ?? (_onEndDrag = new Subject<InventoryEventData>());
// public UniRx.IObservable<InventoryEventData> OnPointerEnterAsObservable() => _onPointerEnter ?? (_onPointerEnter = new Subject<InventoryEventData>());
// public UniRx.IObservable<InventoryEventData> OnPointerExitAsObservable() => _onPointerExit ?? (_onPointerExit = new Subject<InventoryEventData>());
public void OnPointerClick(PointerEventData eventData)
{

View file

@ -478,7 +478,7 @@ public class PropertiesPanel : MonoBehaviour
weaponGroups.OnBeginDragAsObservable().Subscribe(x =>
{
//Debug.Log($"Began dragging weapon group {x.group}");
GameManager.BeginDrag(new WeaponGroupDragAction(x.group));
GameManager.BeginDrag(new WeaponGroupDragObject(x.group));
dragObject = Instantiate(weaponGroups.Groups[x.group], DragParent, true).transform;
dragOffset = (Vector2)dragObject.position - x.pointerEventData.position;
});

View file

@ -1,10 +0,0 @@
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class SchematicTriggerGroupElement : MonoBehaviour
{
public TextMeshProUGUI[] GroupLabel;
public Image[] GroupBackgrounds;
}

View file

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 8f090c2738224f698bdfa545978f4d5a
timeCreated: 1609423819

BIN
GameData/AetherDB.msgpack (Stored with Git LFS)

Binary file not shown.

BIN
GameData/PlayerSettings.msgpack (Stored with Git LFS)

Binary file not shown.

View file

@ -241,8 +241,8 @@
<Compile Include="Assets\Scripts\ServerShared\NIH\RethinkDb\RethinkDb.Driver\Generated\Ast\Reconfigure.cs" />
<Compile Include="Assets\Scripts\ServerShared\NIH\RethinkDb\RethinkDb.Driver\Generated\Ast\July.cs" />
<Compile Include="Assets\Scripts\ServerShared\NIH\RethinkDb\RethinkDb.Driver\Generated\Ast\Slice.cs" />
<Compile Include="Assets\Scripts\ServerShared\NIH\RethinkDb\RethinkDb.Driver\Generated\Ast\Info.cs" />
<Compile Include="Assets\Scripts\ServerShared\NIH\RethinkDb\RethinkDb.Driver.Linq\WhereClauseParsers\DefaultParser.cs" />
<Compile Include="Assets\Scripts\ServerShared\NIH\RethinkDb\RethinkDb.Driver\Generated\Ast\Info.cs" />
<Compile Include="Assets\Scripts\ServerShared\NIH\RethinkDb\RethinkDb.Driver.Linq\WhereClauseParsers\SubQueryVisitor\BaseFilterableSubQueryVisitor.cs" />
<Compile Include="Assets\Scripts\ServerShared\NIH\RethinkDb\RethinkDb.Driver\Net\JsonConverters\ExtensionsForJsonConverters.cs" />
<Compile Include="Assets\Scripts\ServerShared\NIH\RethinkDb\RethinkDb.Driver\Net\Handshake.cs" />
@ -295,8 +295,8 @@
<Compile Include="Assets\Scripts\ServerShared\NIH\RethinkDb\RethinkDb.Driver\Generated\Ast\Table.cs" />
<Compile Include="Assets\Scripts\ServerShared\NIH\RethinkDb\RethinkDb.Driver\Generated\Ast\Day.cs" />
<Compile Include="Assets\Scripts\ServerShared\NIH\RethinkDb\RethinkDb.Driver\Generated\Ast\OrderBy.cs" />
<Compile Include="Assets\Scripts\ServerShared\NIH\RethinkDb\RethinkDb.Driver\Generated\Ast\MakeArray.cs" />
<Compile Include="Assets\Scripts\ServerShared\NIH\RethinkDb\RethinkDb.Driver\Generated\Ast\Circle.cs" />
<Compile Include="Assets\Scripts\ServerShared\NIH\RethinkDb\RethinkDb.Driver\Generated\Ast\MakeArray.cs" />
<Compile Include="Assets\Scripts\ServerShared\NIH\RethinkDb\RethinkDb.Driver.Linq\RethinkDbGroup.cs" />
<Compile Include="Assets\Scripts\ServerShared\NIH\RethinkDb\RethinkDb.Driver\Generated\Ast\ReqlObject.cs" />
<Compile Include="Assets\Scripts\ServerShared\NIH\RethinkDb\RethinkDb.Driver\Generated\ReqlAuthError.cs" />