Update slots to support assigning to specific items

This commit is contained in:
Michal Pikulski
2025-12-08 13:34:06 +01:00
parent c15b7e9d92
commit fff50990f1
13 changed files with 446 additions and 2152 deletions

View File

@@ -172,6 +172,7 @@ SkinnedMeshRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_MaskInteraction: 0
serializedVersion: 2
m_Quality: 0
m_UpdateWhenOffscreen: 0
@@ -456,6 +457,7 @@ MeshRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_MaskInteraction: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!114 &1477914804333655978
MonoBehaviour:
@@ -558,6 +560,7 @@ MeshRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_MaskInteraction: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!114 &6279009652162230510
MonoBehaviour:
@@ -660,6 +663,7 @@ MeshRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_MaskInteraction: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!114 &7522599432703993887
MonoBehaviour:
@@ -796,6 +800,7 @@ SkinnedMeshRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_MaskInteraction: 0
serializedVersion: 2
m_Quality: 0
m_UpdateWhenOffscreen: 0
@@ -912,6 +917,7 @@ MeshRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_MaskInteraction: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!114 &4521180984547725349
MonoBehaviour:

View File

@@ -34,6 +34,7 @@ Transform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &4110666412151536905
SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
@@ -79,6 +80,7 @@ SpriteRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 1
m_MaskInteraction: 0
m_Sprite: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
@@ -88,7 +90,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 0
m_MaskInteraction: 0
m_SpriteSortPoint: 0
--- !u!1 &7249528695393012044
GameObject:
@@ -131,6 +132,7 @@ Transform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &6258593095132504700
SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
@@ -176,6 +178,7 @@ SpriteRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_MaskInteraction: 0
m_Sprite: {fileID: -8438005379329254897, guid: fe735eb4f8856904caec179520dcb92f, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
@@ -185,7 +188,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0
--- !u!61 &5475802662781903683
BoxCollider2D:

View File

@@ -121,6 +121,7 @@ MeshRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_MaskInteraction: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!114 &1799170203493421407
MonoBehaviour:
@@ -169,6 +170,7 @@ Transform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &2343214996212089369
SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
@@ -214,6 +216,7 @@ SpriteRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 1
m_MaskInteraction: 0
m_Sprite: {fileID: -1125559343802010594, guid: 46b2fe6896b27cc4c8bd9f0da3f0de50, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
@@ -223,7 +226,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 1
--- !u!61 &7660380594239590698
BoxCollider2D:
@@ -360,6 +362,7 @@ MeshRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_MaskInteraction: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!114 &6348852419369233976
MonoBehaviour:
@@ -407,6 +410,7 @@ Transform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &7990414055343410434
SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
@@ -452,6 +456,7 @@ SpriteRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 1
m_MaskInteraction: 0
m_Sprite: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
@@ -461,7 +466,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 0
m_MaskInteraction: 0
m_SpriteSortPoint: 0
--- !u!1 &2265449145943364229
GameObject:
@@ -552,6 +556,7 @@ MeshRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_MaskInteraction: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!114 &220335373367130193
MonoBehaviour:
@@ -685,6 +690,7 @@ MeshRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_MaskInteraction: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!114 &972451099498184359
MonoBehaviour:
@@ -790,6 +796,7 @@ SkinnedMeshRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_MaskInteraction: 0
serializedVersion: 2
m_Quality: 0
m_UpdateWhenOffscreen: 0
@@ -909,6 +916,7 @@ SkinnedMeshRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_MaskInteraction: 0
serializedVersion: 2
m_Quality: 0
m_UpdateWhenOffscreen: 0
@@ -1393,6 +1401,7 @@ Transform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &5292193662800385283
SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
@@ -1438,6 +1447,7 @@ SpriteRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 2
m_MaskInteraction: 0
m_Sprite: {fileID: 779209807, guid: b215bf5a0a0f5db4da48c686489d8cab, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
@@ -1447,7 +1457,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0
--- !u!95 &2858293142053250427
Animator:

View File

@@ -86,6 +86,7 @@ PolygonCollider2D:
m_UseDelaunayMesh: 0
--- !u!212 &2825253017896168654
SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
@@ -131,6 +132,7 @@ SpriteRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 1
m_MaskInteraction: 0
m_Sprite: {fileID: -642587728066523507, guid: 95d6dbee5cb1f694c971791ee60cad14, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
@@ -140,7 +142,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 1
--- !u!1 &4316370833098727305
GameObject:
@@ -176,6 +177,7 @@ Transform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &3806274462998212361
SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
@@ -221,6 +223,7 @@ SpriteRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 1
m_MaskInteraction: 0
m_Sprite: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
@@ -230,7 +233,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 0
m_MaskInteraction: 0
m_SpriteSortPoint: 1
--- !u!1 &7145022056631397938
GameObject:

View File

@@ -57,6 +57,7 @@ BoxCollider:
m_Center: {x: 0, y: 0, z: 0}
--- !u!212 &4055726361761331703
SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
@@ -102,6 +103,7 @@ SpriteRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 1
m_MaskInteraction: 0
m_Sprite: {fileID: -3019416885370694485, guid: ed57eef56cafff0428d08bce28798f58, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
@@ -111,7 +113,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 1
--- !u!114 &1226703179564388091
MonoBehaviour:

View File

@@ -57,6 +57,7 @@ BoxCollider:
m_Center: {x: 0, y: 0, z: 0}
--- !u!212 &4774534086162962138
SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
@@ -102,6 +103,7 @@ SpriteRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 1
m_MaskInteraction: 0
m_Sprite: {fileID: 4799961156935096247, guid: 74289c1614ce2b2439a5d3ff60a90d66, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
@@ -111,7 +113,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 1
--- !u!114 &5483561632297398438
MonoBehaviour:

View File

@@ -57,6 +57,7 @@ BoxCollider:
m_Center: {x: 0, y: 0, z: 0}
--- !u!212 &4986096986936361008
SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
@@ -102,6 +103,7 @@ SpriteRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 1
m_MaskInteraction: 0
m_Sprite: {fileID: -2082989857396687135, guid: f106ad45f67e9e74895c64edbc1e4614, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
@@ -111,7 +113,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 1
--- !u!114 &2753389442270867527
MonoBehaviour:

View File

@@ -57,6 +57,7 @@ BoxCollider:
m_Center: {x: 0, y: 0, z: 0}
--- !u!212 &4266110216568578813
SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
@@ -102,6 +103,7 @@ SpriteRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 1
m_MaskInteraction: 0
m_Sprite: {fileID: -4183208330383030991, guid: 26abd62d79d435f438c281aa83ee274a, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
@@ -111,7 +113,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 1
--- !u!114 &1707774147108908574
MonoBehaviour:

View File

@@ -69,10 +69,14 @@ MonoBehaviour:
itemData: {fileID: 11400000, guid: ea20e322caf6eb441b580775bf1bf2c8, type: 2}
iconRenderer: {fileID: 1311388821310946158}
slottedItemRenderers:
- {fileID: 4363732810493563330}
- {fileID: 4765283125670404640}
- {fileID: 6453868228671073978}
- {fileID: 5502334101811892095}
- renderer: {fileID: 4363732810493563330}
assignedItem: {fileID: 11400000, guid: f5a6df00a3840924a8e5b5052a8c9b05, type: 2}
- renderer: {fileID: 4765283125670404640}
assignedItem: {fileID: 11400000, guid: 0f94d1cbd3735424ea37b6125154ed37, type: 2}
- renderer: {fileID: 6453868228671073978}
assignedItem: {fileID: 11400000, guid: d0e8554a0463a924e803732e9209c92a, type: 2}
- renderer: {fileID: 5502334101811892095}
assignedItem: {fileID: 11400000, guid: 45c190ffad50b994ba53f64a9838751d, type: 2}
onItemSlotted:
m_PersistentCalls:
m_Calls: []

View File

@@ -34,6 +34,7 @@ Transform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &3593498626556091915
SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
@@ -79,6 +80,7 @@ SpriteRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 1
m_MaskInteraction: 0
m_Sprite: {fileID: 277634131431117102, guid: 2cf4a5af200e48347b7dcd0dbd84d9ca, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
@@ -88,7 +90,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0
--- !u!1 &563765657355903966
GameObject:
@@ -454,6 +455,7 @@ Transform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &4677446939953396014
SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
@@ -499,6 +501,7 @@ SpriteRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 1
m_MaskInteraction: 0
m_Sprite: {fileID: -2418630947029704618, guid: fbbc627f5a8f06e47a23369fd19f3998, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
@@ -508,7 +511,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0
--- !u!1 &2312511629901843318
GameObject:
@@ -544,6 +546,7 @@ Transform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &5126475362876787783
SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
@@ -589,6 +592,7 @@ SpriteRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 1
m_MaskInteraction: 0
m_Sprite: {fileID: 277634131431117102, guid: 2cf4a5af200e48347b7dcd0dbd84d9ca, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
@@ -598,7 +602,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0
--- !u!1 &2391935521422290070
GameObject:
@@ -637,6 +640,7 @@ Transform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &6338084184716153992
SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
@@ -682,6 +686,7 @@ SpriteRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 1
m_MaskInteraction: 0
m_Sprite: {fileID: -3811075571101519331, guid: cf5af87e6a25e9442b89f069b894a5fd, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
@@ -691,7 +696,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0
--- !u!61 &253472492358066383
BoxCollider2D:
@@ -813,6 +817,7 @@ Transform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &1081162597868568544
SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
@@ -858,6 +863,7 @@ SpriteRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_MaskInteraction: 0
m_Sprite: {fileID: 9105513792776133627, guid: 140f82f54aeb07e409575fe55dc6df14, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
@@ -867,7 +873,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0
--- !u!60 &4857176284453307382
PolygonCollider2D:
@@ -955,6 +960,7 @@ Transform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &7072755111968586092
SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
@@ -1000,6 +1006,7 @@ SpriteRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_MaskInteraction: 0
m_Sprite: {fileID: 9105513792776133627, guid: 140f82f54aeb07e409575fe55dc6df14, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
@@ -1009,7 +1016,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0
--- !u!1 &8095936409589519396
GameObject:
@@ -1045,6 +1051,7 @@ Transform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &7713018619525726688
SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
@@ -1090,6 +1097,7 @@ SpriteRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 1
m_MaskInteraction: 0
m_Sprite: {fileID: -2418630947029704618, guid: fbbc627f5a8f06e47a23369fd19f3998, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
@@ -1099,7 +1107,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0
--- !u!1 &8607415572972099566
GameObject:

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -17,6 +17,17 @@ namespace Interactions
Forbidden
}
/// <summary>
/// Maps a sprite renderer to an optional item assignment
/// </summary>
[Serializable]
public class SlotRendererMapping
{
public SpriteRenderer renderer;
[Tooltip("Optional: If set, this renderer slot is dedicated to this specific item. Leave null for flexible slots.")]
public PickupItemData assignedItem;
}
/// <summary>
/// Saveable data for ItemSlot state
/// </summary>
@@ -41,7 +52,7 @@ namespace Interactions
// Multi-slot item tracking
private List<PickupItemData> slottedItemsData = new List<PickupItemData>();
public SpriteRenderer[] slottedItemRenderers; // Array of renderers for multiple items
public SlotRendererMapping[] slottedItemRenderers; // Array of renderers with optional item assignments
private List<GameObject> slottedItemObjects = new List<GameObject>();
private List<bool> slottedItemCorrectness = new List<bool>(); // Track which items are correct
@@ -63,12 +74,24 @@ namespace Interactions
/// <summary>
/// Number of items currently slotted (correct or incorrect)
/// </summary>
public int CurrentSlottedCount => slottedItemObjects.Count;
public int CurrentSlottedCount => slottedItemObjects.Count(obj => obj != null);
/// <summary>
/// Number of CORRECT items currently slotted
/// </summary>
public int CurrentCorrectCount => slottedItemCorrectness.Count(correct => correct);
public int CurrentCorrectCount
{
get
{
int count = 0;
for (int i = 0; i < slottedItemCorrectness.Count; i++)
{
if (i < slottedItemObjects.Count && slottedItemObjects[i] != null && slottedItemCorrectness[i])
count++;
}
return count;
}
}
/// <summary>
/// Number of items required to complete this slot
@@ -288,16 +311,44 @@ namespace Interactions
// For multi-slots: only allow swap if not complete yet (allows fixing mistakes)
if (!IsMultiSlot || !IsComplete)
{
// LIFO swap - swap with the last item
int lastIndex = CurrentSlottedCount - 1;
var itemToReturn = slottedItemObjects[lastIndex];
var itemDataToReturn = slottedItemsData[lastIndex];
// Determine target index for the new item
int targetIndex = GetTargetSlotIndexForItem(heldItemData);
int indexToSwap;
if (targetIndex >= 0 && targetIndex < slottedItemObjects.Count && slottedItemObjects[targetIndex] != null)
{
// Swap with the item in the assigned slot
indexToSwap = targetIndex;
}
else
{
// LIFO swap - swap with the last non-null item
indexToSwap = -1;
for (int i = slottedItemObjects.Count - 1; i >= 0; i--)
{
if (slottedItemObjects[i] != null)
{
indexToSwap = i;
break;
}
}
if (indexToSwap < 0)
{
// No items to swap (shouldn't happen, but fallback)
SlotItem(heldItemObj, heldItemData);
return false;
}
}
var itemToReturn = slottedItemObjects[indexToSwap];
var itemDataToReturn = slottedItemsData[indexToSwap];
// Step 1: Give old item to follower
FollowerController.TryPickupItem(itemToReturn, itemDataToReturn, dropItem: false);
// Step 2: Remove old item from slot
RemoveItemAtIndex(lastIndex);
RemoveItemAtIndex(indexToSwap);
// Step 3: Slot the new item
SlotItem(heldItemObj, heldItemData);
@@ -317,7 +368,19 @@ namespace Interactions
// Pickup from slot (empty hands) - LIFO removal
if (heldItemData == null)
{
int lastIndex = CurrentSlottedCount - 1;
// Find last non-null item
int lastIndex = -1;
for (int i = slottedItemObjects.Count - 1; i >= 0; i--)
{
if (slottedItemObjects[i] != null)
{
lastIndex = i;
break;
}
}
if (lastIndex >= 0)
{
var itemToPickup = slottedItemObjects[lastIndex];
var itemDataToPickup = slottedItemsData[lastIndex];
@@ -326,6 +389,7 @@ namespace Interactions
// Remove from slot
RemoveItemAtIndex(lastIndex);
}
// Just picked up from slot - not a success
return false;
@@ -343,7 +407,16 @@ namespace Interactions
/// </summary>
private void ClearSlot()
{
var previousData = slottedItemsData.Count > 0 ? slottedItemsData[0] : null;
// Find first non-null data for event
PickupItemData previousData = null;
foreach (var data in slottedItemsData)
{
if (data != null)
{
previousData = data;
break;
}
}
// Clear all pickup's OwningSlot references
foreach (var itemObj in slottedItemObjects)
@@ -375,7 +448,7 @@ namespace Interactions
/// </summary>
private void RemoveItemAtIndex(int index)
{
if (index < 0 || index >= CurrentSlottedCount)
if (index < 0 || index >= slottedItemObjects.Count)
return;
var itemObj = slottedItemObjects[index];
@@ -391,9 +464,10 @@ namespace Interactions
}
}
slottedItemObjects.RemoveAt(index);
slottedItemsData.RemoveAt(index);
slottedItemCorrectness.RemoveAt(index); // Also remove correctness tracking
// Set to null instead of removing to maintain sparse storage
slottedItemObjects[index] = null;
slottedItemsData[index] = null;
slottedItemCorrectness[index] = false;
if (CurrentSlottedCount == 0)
{
@@ -412,6 +486,74 @@ namespace Interactions
#region Visual Updates
/// <summary>
/// Determines the best slot index for an item based on assignments and availability.
/// Returns -1 if no mappings are configured (uses append behavior).
/// </summary>
private int GetTargetSlotIndexForItem(PickupItemData itemData)
{
if (slottedItemRenderers == null || slottedItemRenderers.Length == 0)
return -1;
// Check if any renderer has assignments configured
bool hasAnyAssignments = false;
for (int i = 0; i < slottedItemRenderers.Length; i++)
{
if (slottedItemRenderers[i]?.assignedItem != null)
{
hasAnyAssignments = true;
break;
}
}
// If no assignments configured, use append behavior (backward compatible)
if (!hasAnyAssignments)
return -1;
// Step 1: Check if this item has a dedicated assigned slot
for (int i = 0; i < slottedItemRenderers.Length; i++)
{
var mapping = slottedItemRenderers[i];
if (mapping?.assignedItem != null && PickupItemData.AreEquivalent(mapping.assignedItem, itemData))
{
// This is the assigned slot for this item
return i;
}
}
// Step 2: Item is not assigned to a specific slot - find best available slot
// Ensure lists are large enough to check
while (slottedItemObjects.Count < slottedItemRenderers.Length)
{
slottedItemObjects.Add(null);
slottedItemsData.Add(null);
slottedItemCorrectness.Add(false);
}
// Prefer unassigned empty slots first
for (int i = 0; i < slottedItemRenderers.Length; i++)
{
var mapping = slottedItemRenderers[i];
if (mapping?.assignedItem == null && slottedItemObjects[i] == null)
{
return i; // Empty unassigned slot
}
}
// Then try assigned but empty slots
for (int i = 0; i < slottedItemRenderers.Length; i++)
{
var mapping = slottedItemRenderers[i];
if (mapping?.assignedItem != null && slottedItemObjects[i] == null)
{
return i; // Empty assigned slot
}
}
// All slots full - return -1 to trigger swap logic
return -1;
}
/// <summary>
/// Updates the sprite and scale for all slotted items.
/// </summary>
@@ -423,10 +565,12 @@ namespace Interactions
// Update each renderer based on slotted items
for (int i = 0; i < slottedItemRenderers.Length; i++)
{
var slotRenderer = slottedItemRenderers[i];
if (slotRenderer == null)
var mapping = slottedItemRenderers[i];
if (mapping == null || mapping.renderer == null)
continue;
var slotRenderer = mapping.renderer;
// If we have an item at this index, show it
if (i < slottedItemsData.Count && slottedItemsData[i] != null)
{
@@ -645,7 +789,7 @@ namespace Interactions
/// <summary>
/// Public API for slotting items during gameplay.
/// Adds item to the slot (multi-slot support).
/// Adds item to the slot (multi-slot support with positional awareness).
/// Caller is responsible for managing follower's held item state.
/// </summary>
public void SlotItem(GameObject itemToSlot, PickupItemData itemToSlotData)
@@ -661,10 +805,31 @@ namespace Interactions
var allowed = config?.allowedItems ?? new List<PickupItemData>();
bool isCorrectItem = PickupItemData.ListContainsEquivalent(allowed, itemToSlotData);
// Add to lists
// Determine target slot index
int targetIndex = GetTargetSlotIndexForItem(itemToSlotData);
if (targetIndex >= 0)
{
// Positional slotting - ensure lists are large enough
while (slottedItemObjects.Count <= targetIndex)
{
slottedItemObjects.Add(null);
slottedItemsData.Add(null);
slottedItemCorrectness.Add(false);
}
// Place at specific index
slottedItemObjects[targetIndex] = itemToSlot;
slottedItemsData[targetIndex] = itemToSlotData;
slottedItemCorrectness[targetIndex] = isCorrectItem;
}
else
{
// Append behavior (backward compatible or when all slots full)
slottedItemObjects.Add(itemToSlot);
slottedItemsData.Add(itemToSlotData);
slottedItemCorrectness.Add(isCorrectItem); // Track correctness
slottedItemCorrectness.Add(isCorrectItem);
}
// Deactivate item and set pickup state
itemToSlot.SetActive(false);