Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_CharacterInventoryStorageComponent.c
Go to the documentation of this file.
2{
3 IT_NONE = 16385
4}
5
6[ComponentEditorProps(category: "GameScripted/Inventory", description: "Inventory 2.0", icon: HYBRID_COMPONENT_ICON)]
7class SCR_CharacterInventoryStorageComponentClass: CharacterInventoryStorageComponentClass
8{
9}
10
12{
13 CharacterControllerComponent m_Controller;
14
15 //------------------------------------------------------------------------------------------------
16 protected override void OnComplete()
17 {
18 m_Controller.TryEquipRightHandItem(m_pItem, EEquipItemType.EEquipTypeWeapon, false);
19 m_pItem = null;
20 }
21
22 //------------------------------------------------------------------------------------------------
23 protected override void OnFailed()
24 {
25 m_pItem = null;
26 }
27}
28
29class SCR_EquipNextGrenadeCB : SCR_InvCallBack
30{
31 SCR_InventoryStorageManagerComponent m_InvMan;
32
33 //------------------------------------------------------------------------------------------------
34 protected override void OnComplete()
35 {
36 if (m_pItem)
37 m_InvMan.EquipWeapon(m_pItem, null, false);
38
39 m_pItem = null;
40 }
41
42 //------------------------------------------------------------------------------------------------
43 protected override void OnFailed()
44 {
45 m_pItem = null;
46 }
47}
48
50{
51 protected override void OnComplete()
52 {
53 if (m_pMenu)
54 {
55 m_pMenu.ShowStoragesList();
56 m_pMenu.ShowAllStoragesInList();
57 }
58 }
59}
60
61class SCR_InvEquipAnyItemCB : SCR_InvCallBack
62{
64
65 //------------------------------------------------------------------------------------------------
66 protected override void OnComplete()
67 {
69 if (!characterStorage || !m_pItem)
70 return;
71
72 if (m_iSlotToFocus > -1)
73 {
74 characterStorage.RemoveItemFromQuickSlotAtIndex(m_iSlotToFocus);
75 characterStorage.StoreItemToQuickSlot(m_pItem, m_iSlotToFocus);
77 }
78
79 if (m_bShouldEquip)
80 // This must be delayed because inventory... Otherwise its possible that item will be permanently system locked, as host might still not know that item transfer was finished
81 GetGame().GetCallqueue().CallLater(characterStorage.UseItem, 250, false, m_pItem, ESlotFunction.TYPE_GENERIC, SCR_EUseContext.FROM_INVENTORY);
82
83 super.OnComplete();
84 m_pItem = null;
85 m_pStorageToPickUp = null;
86 }
87}
88
89class SCR_CharacterInventoryStorageComponent : CharacterInventoryStorageComponent
90{
91 //TODO: define this on loadout level. This is temporary and will be removed!
92 [Attribute( "0", UIWidgets.EditBox, "How much weight the character can carry")]
93 protected float m_fMaxWeight;
94
95 //TODO: define this on loadout level. This is temporary and will be removed!
96 [Attribute( "0", UIWidgets.EditBox, "How much volume the character can carry")]
97 protected float m_fMaxVolume;
98
99 #ifndef DISABLE_INVENTORY
100
101 private BaseInventoryStorageComponent m_LootStorage;
102 protected ref array<ref SCR_QuickslotBaseContainer> m_aQuickSlots = { null, null, null, null, null, null, null, null, null, null };
104 protected ref array<IEntity> m_aWeaponQuickSlotsStorage = {}; //Is used to store first four quickslots of turrets.
105 protected ref array<int> m_aQuickSlotsHistory = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //here we'll be remembering the items stored
106 protected ref set<int> m_aQuickSlotsInitalized = new set<int>();
107// protected ref array<EntityComponentPrefabData> m_aPrefabsData = { null, null, null, null, null, null, null, null, null, null }; // todo: figure out the intentions
108 protected static const int GADGET_OFFSET = 9999; //EWeaponType && EGadgetType might be have the same number, offset it ( not nice (i agree) )
109 protected static const int TURRET_WEAPON_SWITCH_SLOTS = 4; //How many slots can player cycle between using SelectNextWeapon method by default when in turret
110 protected static const int INFANTRY_WEAPON_SWITCH_SLOTS = 2; //How many slots can player cycle between using SelectNextWeapon method by default when not in turret
111
112// protected ref array<ref array<int>> m_aDefaultRiflemanQuickSlots = { { EWeaponType.WT_RIFLE, EWeaponType.WT_SNIPERRIFLE, EWeaponType.WT_MACHINEGUN },
113// { EWeaponType.WT_HANDGUN, EWeaponType.WT_ROCKETLAUNCHER, EWeaponType.WT_GRENADELAUNCHER, ( EGadgetType.BINOCULARS ) + GADGET_OFFSET },
114// { ( EGadgetType.FLASHLIGHT ) + GADGET_OFFSET },
115// { EWeaponType.WT_FRAGGRENADE, EWeaponType.WT_SMOKEGRENADE },
116// { ( EGadgetType.MAP ) + GADGET_OFFSET },
117// { ( EGadgetType.COMPASS ) + GADGET_OFFSET }
118// };
119
120
121 //---- REFACTOR NOTE START: Not the best way to do this, should be more configurable by players ----
122
123 protected static const ref array<ref array<int>> DEFAULT_QUICK_SLOTS = { { EWeaponType.WT_RIFLE, EWeaponType.WT_SNIPERRIFLE, EWeaponType.WT_MACHINEGUN },
124 { EWeaponType.WT_RIFLE, EWeaponType.WT_ROCKETLAUNCHER, EWeaponType.WT_GRENADELAUNCHER, EWeaponType.WT_SNIPERRIFLE, EWeaponType.WT_MACHINEGUN },
125 { EWeaponType.WT_HANDGUN },
126 { EWeaponType.WT_FRAGGRENADE },
127 { EWeaponType.WT_SMOKEGRENADE },
128 { EGadgetType.CONSUMABLE + GADGET_OFFSET + SCR_EConsumableType.BANDAGE },
129 { EGadgetType.CONSUMABLE + GADGET_OFFSET + SCR_EConsumableType.TOURNIQUET },
130 { EGadgetType.CONSUMABLE + GADGET_OFFSET + SCR_EConsumableType.MORPHINE, EGadgetType.CONSUMABLE + GADGET_OFFSET + SCR_EConsumableType.SALINE },
131 { EGadgetType.RADIO + GADGET_OFFSET }, // Preferably as GadgetRadio action, then it can be saline
132 { EGadgetType.BUILDING_TOOL + GADGET_OFFSET } // To be replaced with engineering tool
133 };
134
135 //---- REFACTOR NOTE END ----
136
137 protected ref array<typename> m_aBlockedSlots = {};
138 protected ref array<BaseInventoryStorageComponent> m_aStoragesInStorageList = {}; //here we remember the opened storages in the Inventory menu ( in the Storages list area )
140 protected BaseInventoryStorageComponent m_WeaponStorage;
141 protected SCR_CharacterFactionAffiliationComponent m_CharacterAffiliationComponent;
142
144
145 protected static const ref array<EWeaponType> WEAPON_TYPES_THROWABLE = { EWeaponType.WT_FRAGGRENADE, EWeaponType.WT_SMOKEGRENADE };
146
147 //------------------------------------------------------------------------ USER METHODS ------------------------------------------------------------------------
148
149 //------------------------------------------------------------------------------------------------
151 //TODO: define this on loadout level. This is temporary and will be removed!
153 {
154 return m_fMaxWeight;
155 }
156
157 //------------------------------------------------------------------------------------------------
159 BaseInventoryStorageComponent GetWeaponStorage()
160 {
161 if (!m_WeaponStorage)
162 m_WeaponStorage = BaseInventoryStorageComponent.Cast(GetOwner().FindComponent(EquipedWeaponStorageComponent));
163
164 return m_WeaponStorage;
165 }
166
167 //------------------------------------------------------------------------------------------------
171 {
172 // Not all attached Entities to slots are storages.
173 // For instance boots - even though attached to character storage slot by themselves represent item, not storage
174 // However if entity attached to slot it is guaranteed to have InventoryItemComponent
175 InventoryStorageSlot slot = GetSlotFromArea(eSlot.Type());
176 if (!slot)
177 return null;
178
179 IEntity entity = slot.GetAttachedEntity();
180 if (!entity)
181 return null;
182
184 }
185
186 //------------------------------------------------------------------------------------------------
189 BaseInventoryStorageComponent GetStorageFromLoadoutSlot( LoadoutAreaType eSlot )
190 {
191 return BaseInventoryStorageComponent.Cast( GetItemFromLoadoutSlot(eSlot) );
192 }
193
194 //------------------------------------------------------------------------------------------------
195 protected bool HasStorageComponent( IEntity pEntity )
196 {
197 return GetStorageComponentFromEntity( pEntity ) != null;
198 }
199
200 //------------------------------------------------------------------------------------------------
203 void GetStorages( out notnull array<SCR_UniversalInventoryStorageComponent> storagesInInventory )
204 {
205 array<IEntity> pEntities = {};
206 int iNrOfStorages = GetAll( pEntities );
207
209 foreach ( IEntity pEntity: pEntities )
210 {
211 pUniComp = GetStorageComponentFromEntity(pEntity);
212 if( pUniComp )
213 storagesInInventory.Insert( pUniComp );
214 }
215 }
216
217 //------------------------------------------------------------------------------------------------
219 void GetBlockedSlots(out notnull array<typename> blockedSlots)
220 {
221 blockedSlots.Copy(m_aBlockedSlots);
222 }
223
224 //------------------------------------------------------------------------------------------------
234
235 //------------------------------------------------------------------------------------------------
237 void SetLootStorage( IEntity pOwner )
238 {
239 if( !pOwner )
240 {
241 m_LootStorage = null;
242 return;
243 }
244
245 m_LootStorage = BaseInventoryStorageComponent.Cast(pOwner.FindComponent(BaseInventoryStorageComponent));
246 }
247
248 //------------------------------------------------------------------------------------------------
250 BaseInventoryStorageComponent GetLootStorage()
251 {
252 return m_LootStorage;
253 }
254
255 //------------------------------------------------------------------------------------------------
258 bool GetIsStorageShown( notnull BaseInventoryStorageComponent pStorage )
259 {
260 return m_aStoragesInStorageList.Find( pStorage ) != -1;
261 }
262
263 //------------------------------------------------------------------------------------------------
265 void SetStorageAsShown( notnull BaseInventoryStorageComponent pStorage )
266 {
267 if ( !GetIsStorageShown( pStorage ) )
268 m_aStoragesInStorageList.Insert( pStorage );
269 }
270
271 //------------------------------------------------------------------------------------------------
273 void SetStorageAsHidden( notnull BaseInventoryStorageComponent pStorage )
274 {
275 m_aStoragesInStorageList.RemoveItem( pStorage );
276 }
277
278 //---- REFACTOR NOTE START: Ideally should be linked to components and rather should work based on item config instead ----
279
280 //------------------------------------------------------------------------------------------------
283 static int GetItemType(notnull IEntity pItem)
284 {
285 int iItemType = -1;
286 //Weapons:
287 BaseWeaponComponent weaponComponent = BaseWeaponComponent.Cast( pItem.FindComponent( BaseWeaponComponent ) );
288 if ( weaponComponent )
289 {
290 iItemType = weaponComponent.GetWeaponType();
291 }
292 else
293 {
294 //Gadgets:
295 SCR_GadgetComponent gadgetComponent = SCR_GadgetComponent.Cast( pItem.FindComponent( SCR_GadgetComponent ) );
296 if ( gadgetComponent )
297 {
298 EGadgetType gadgetType = gadgetComponent.GetType();
299 int consumableOffset = 0;
300 if (gadgetType == EGadgetType.CONSUMABLE)
301 {
302 SCR_ConsumableItemComponent consumable = SCR_ConsumableItemComponent.Cast(gadgetComponent);
303 if (consumable)
304 consumableOffset = consumable.GetConsumableType();
305 }
306 iItemType = gadgetComponent.GetType() + GADGET_OFFSET + consumableOffset;
307 }
308 }
309
310 return iItemType;
311 }
312
313 //---- REFACTOR NOTE END ----
314
315 //------------------------------------------------------------------------------------------------
320 bool ItemBelongsToSlot( int iItemType, int iSlotIndex )
321 {
322 return DEFAULT_QUICK_SLOTS[iSlotIndex].Contains(iItemType);
323 }
324
325 //------------------------------------------------------------------------------------------------
326 bool SetQuickSlotInitialized(int iSlotIndex)
327 {
328 return m_aQuickSlotsInitalized.Insert(iSlotIndex);
329 }
330
331 //------------------------------------------------------------------------------------------------
335 {
336 int result = m_mSlotHistory.Get(ent);
337 m_mSlotHistory.Remove(ent);
338 return result;
339 }
340
341 //------------------------------------------------------------------------------------------------
344 static int GetDefaultQuickSlot(notnull IEntity item)
345 {
346 int itemType = GetItemType(item);
347 foreach (int i, ref array<int> allowedTypes : DEFAULT_QUICK_SLOTS)
348 {
349 if (allowedTypes.Contains(itemType))
350 return i;
351 }
352
353 return -1;
354 }
355
356 //------------------------------------------------------------------------------------------------
359 bool IsInDefaultQuickSlot(notnull IEntity item)
360 {
361 int itemType = GetItemType(item);
362 if (itemType < 0)
363 return false;
364
365 int slotId = GetDefaultQuickSlot(item);
366 if (slotId < 0)
367 return false;
368
369 return GetEntityIndexInQuickslots(item) == slotId;
370 }
371
372 //------------------------------------------------------------------------------------------------
378 int StoreItemToQuickSlot(notnull IEntity pItem, int iSlotIndex = -1, bool isForced = false)
379 {
380 int iItemType = GetItemType( pItem );
381 if ( iSlotIndex == -1 ) //we don't know what slot we put the item into. Check first if we remember the type of the item
382 {
383 InventoryItemComponent itemComp = InventoryItemComponent.Cast(pItem.FindComponent(InventoryItemComponent));
384 InventoryStorageSlot parentSlot;
385 if (itemComp)
386 parentSlot = itemComp.GetParentSlot();
387
388 if (parentSlot && EquipedWeaponStorageComponent.Cast(parentSlot.GetStorage()))
389 {
390 iSlotIndex = parentSlot.GetID();
391 }
392 else
393 {
394 foreach (int i, SCR_QuickslotBaseContainer quickSlot : m_aQuickSlots)
395 {
396 if (quickSlot)
397 continue;//do it only for the empty slots
398
399 if (m_aQuickSlotsHistory.IsIndexValid(i) && iItemType == m_aQuickSlotsHistory[i])
400 {
401 iSlotIndex = i;
402 break;
403 }
404
405 if (ItemBelongsToSlot(iItemType, i))
406 {
407 iSlotIndex = i;
408 break;
409 }
410 }
411 }
412 }
413
414 if ( iSlotIndex == -1 ) //any suitable slot not found, do not insert into quick slot
415 return -1;
416
417 if (!isForced)
418 {
420 if (turretCompartment)
421 {
423 return -1;
424
425 array<IEntity> turretWeapons = {};
426 GetTurretWeaponsList(turretCompartment, turretWeapons);
427 if (turretWeapons.Contains(pItem))
428 return -1;
429 }
430 }
431
433 if ( entityContainer && pItem == entityContainer.GetEntity() )
434 return iSlotIndex;
435
436 int iOldIndex = RemoveItemFromQuickSlot( pItem );
437 if ( 0 <= iOldIndex && iOldIndex < m_aQuickSlotsHistory.Count() )
438 m_aQuickSlotsHistory[ iOldIndex ] = 0; //in case the item is already in slot and we shift the item into a different slot
439
440 SCR_QuickslotEntityContainer inventoryContainer = new SCR_QuickslotEntityContainer(pItem);
441 InsertContainerIntoQuickslot(inventoryContainer, iSlotIndex);
442
443 m_aQuickSlotsHistory[ iSlotIndex ] = iItemType; // remember it
444 return iSlotIndex;
445 }
446
447 //------------------------------------------------------------------------------------------------
450 {
451 //clear the array in case something reacts to it
452 m_aQuickSlots.Set(slotIndex, null);
453 m_aQuickSlots.Set(slotIndex, container);
454 }
455
456 //------------------------------------------------------------------------------------------------
461 {
463
465
466 return index;
467 }
468
469 //------------------------------------------------------------------------------------------------
473 {
474 if (m_aQuickSlots.IsIndexValid(index))
475 m_aQuickSlots.Set(index, null);
476 }
477
478 //------------------------------------------------------------------------------------------------
480 array<ref SCR_QuickslotBaseContainer> GetQuickSlotItems()
481 {
482 return m_aQuickSlots;
483 }
484
485 //------------------------------------------------------------------------------------------------
488 {
489 array<IEntity> entities = {};
490
491 SCR_QuickslotEntityContainer entityContainer;
492 foreach(SCR_QuickslotBaseContainer container : m_aQuickSlots)
493 {
494 entityContainer = SCR_QuickslotEntityContainer.Cast(container);
495 if (!entityContainer)
496 {
497 entities.Insert(null);
498 continue;
499 }
500
501 entities.Insert(entityContainer.GetEntity());
502 }
503
504 return entities;
505 }
506
507 //------------------------------------------------------------------------------------------------
511 {
512 if (!m_aQuickSlots.IsIndexValid(index))
513 return null;
514
516 if (!entityContainer)
517 return null;
518
519 return entityContainer.GetEntity();
520 }
521
522 //------------------------------------------------------------------------------------------------
526 {
527 if (!m_aQuickSlots.IsIndexValid(index))
528 return null;
529
530 return m_aQuickSlots[index];
531 }
532
533 //------------------------------------------------------------------------------------------------
536 {
537 ChimeraCharacter character = ChimeraCharacter.Cast(GetOwner());
538 if (!character)
539 return null;
540
541 CharacterControllerComponent controller = character.GetCharacterController();
542 if (!controller)
543 return null;
544
545 IEntity gadget = controller.GetAttachedGadgetAtLeftHandSlot();
546 if (gadget)
547 return gadget;
548
550 if (weapon)
551 return weapon.GetOwner();
552
553 return null;
554 }
555
556 //------------------------------------------------------------------------------------------------
559 {
560 // Selection is in progress
561 if (m_Callback.m_pItem)
562 return m_Callback.m_pItem;
563
564 return GetCurrentItem();
565 }
566
567 //------------------------------------------------------------------------------------------------
570 {
571 ChimeraCharacter character = ChimeraCharacter.Cast(GetOwner());
572 if (!character)
573 return;
574
575 CharacterControllerComponent controller = character.GetCharacterController();
576 if (!controller)
577 return;
578
579 if (controller.IsChangingItem())
580 return;
581
582 if (controller.IsGadgetInHands())
583 controller.RemoveGadgetFromHand();
584 else
585 controller.SelectWeapon(null);
586 }
587
588 //------------------------------------------------------------------------------------------------
591 {
592 ChimeraCharacter character = ChimeraCharacter.Cast(GetOwner());
593 if (!character)
594 return;
595
596 CharacterControllerComponent controller = character.GetCharacterController();
597 if (!controller)
598 return;
599
600 if (controller.IsChangingItem())
601 return;
602
603 SCR_InventoryStorageManagerComponent storageManager = SCR_InventoryStorageManagerComponent.Cast(controller.GetInventoryStorageManager());
604 if (!storageManager)
605 return;
606
607 IEntity itemEnt;
608
609 // TODO: Also drop hidden sticky gadget
610 if (controller.IsGadgetInHands())
611 {
612 // TODO: Equip another gadget or consumable of same type
613 itemEnt = controller.GetAttachedGadgetAtLeftHandSlot();
614 storageManager.TryRemoveItemFromInventory(itemEnt);
615 return;
616 }
617
618 BaseWeaponManagerComponent weaponManager = controller.GetWeaponManagerComponent();
619 if (!weaponManager)
620 return;
621
622 WeaponSlotComponent currentSlot = weaponManager.GetCurrentSlot();
623 if (!currentSlot)
624 return;
625
626 SCR_EquipNextGrenadeCB callback = new SCR_EquipNextGrenadeCB();
627
628 EWeaponType type = currentSlot.GetWeaponType();
629 itemEnt = currentSlot.GetWeaponEntity();
630
631 if (!storageManager.CanMoveItem(itemEnt))
632 return;
633
634 callback.m_InvMan = storageManager;
635
636 if (WEAPON_TYPES_THROWABLE.Contains(type))
637 callback.m_pItem = storageManager.FindNextWeaponOfType(type, itemEnt, true);
638
639 storageManager.SetInventoryLocked(true);
640 controller.DropWeapon(currentSlot);
641 storageManager.SetInventoryLocked(false);
642 }
643
644 //------------------------------------------------------------------------------------------------
648 protected override void OnAddedToSlot(IEntity item, int slotID)
649 {
650 super.OnAddedToSlot(item, slotID);
651
652 UpdateBlockedSlots(item, slotID, true);
653
654 EditArmoredAttributes(item, slotID);
655
656 //~ Update perceived faction
657 UpdatePerceivedFaction(true, item);
658
659 #ifdef DEBUG_INVENTORY20
660 // Loadout manager is taking care of this since there are some items that shouldn't be visible when attached to slot, some have different meshes for different states.
661 // Consider glasses in first person view - they deffinitely should be disabled
662 // it is slightly more complex then this
663
665 if (!itemComponent)
666 return;
667
669 if (!storageComponent)
670 return;
671
672 SCR_ItemAttributeCollection attr = SCR_ItemAttributeCollection.Cast(storageComponent.GetAttributes());
673 if( !attr )
674 return;
675
676 UIInfo UIinfoItem = attr.GetUIInfo();
677 if( !UIinfoItem )
678 return;
679
680 Print(string.Format("INV: item %1 was added. It's weight is: %2, and total weight of item/storage is: %3", UIinfoItem.GetName(), attr.GetWeight(), storageComponent.GetTotalWeight()), LogLevel.NORMAL);
681 #endif
682 }
683
684 //------------------------------------------------------------------------------------------------
685 protected override void OnRemovedFromSlot(IEntity item, int slotID)
686 {
687 super.OnRemovedFromSlot(item, slotID);
688
689 UpdateBlockedSlots(item, slotID, false);
690
691 EditArmoredAttributes(item, slotID, true);
692
693 //~ Update perceived faction
694 UpdatePerceivedFaction(false, item);
695 }
696
697 //------------------------------------------------------------------------------------------------
698 protected void UpdateBlockedSlots(IEntity item, int slotID, bool added)
699 {
701 if (!loadoutComp)
702 return;
703
704 array<typename> blockedSlots = {};
705
706 loadoutComp.GetBlockedSlots(blockedSlots);
707
708 if (blockedSlots.IsEmpty())
709 return;
710
711 if (added)
712 {
713 foreach (typename blockedSlot: blockedSlots)
714 {
715 m_aBlockedSlots.Insert(blockedSlot);
716 }
717 }
718 else
719 {
720 foreach (typename blockedSlot: blockedSlots)
721 {
722 m_aBlockedSlots.RemoveItem(blockedSlot);
723 }
724 }
725 }
726
727 //------------------------------------------------------------------------------------------------
730 bool IsAreaBlocked(typename areaType)
731 {
732 return m_aBlockedSlots.Contains(areaType);
733 }
734
735 //------------------------------------------------------------------------------------------------
737 protected void EditArmoredAttributes(IEntity item, int slotID, bool remove = false)
738 {
740 if (!itemComponent)
741 return;
742
743 SCR_ItemAttributeCollection attributes = SCR_ItemAttributeCollection.Cast(itemComponent.GetAttributes());
744 if (!attributes)
745 return;
746
747 SCR_ArmoredClothItemData armorAttr = SCR_ArmoredClothItemData.Cast(attributes.FindAttribute(SCR_ArmoredClothItemData));
749 if (armorAttr && damageMgr)
750 damageMgr.UpdateArmorDataMap(armorAttr, remove);
751 }
752
753 //------------------------------------------------------------------------------------------------
757 void HandleOnItemAddedToInventory( IEntity item, BaseInventoryStorageComponent storageOwner )
758 {
759 int targetQuickSlot = StoreItemToQuickSlot(item);
760 if (targetQuickSlot > -1 && SCR_WeaponSwitchingBaseUI.s_bOpened)
762 }
763
764 //------------------------------------------------------------------------------------------------
768 void HandleOnItemRemovedFromInventory( IEntity item, BaseInventoryStorageComponent storageOwner )
769 {
770 int itemIndex = GetEntityIndexInQuickslots(item);
771 m_mSlotHistory.Set(item, itemIndex);
773 }
774
775 //------------------------------------------------------------------------------------------------
779 {
780 ChimeraCharacter character = ChimeraCharacter.Cast(GetOwner());
781 if (!character)
782 return false;
783
784 CharacterControllerComponent charCtrl = character.GetCharacterController();
785 if (!charCtrl)
786 return false;
787
788 if (charCtrl.GetCurrentItemInHands() == item || charCtrl.GetInputContext().GetLeftHandGadgetEntity() == item)
789 return false;
790
791 GenericComponent component = GenericComponent.Cast(item.FindComponent(SCR_GadgetComponent));
792 if (SCR_GadgetComponent.Cast(component))
793 return CanUseItem(item, ESlotFunction.TYPE_GADGET);
794
795 component = GenericComponent.Cast(item.FindComponent(MagazineComponent));
796 if (MagazineComponent.Cast(component))
797 return false;
798
799 component = GenericComponent.Cast(item.FindComponent(BaseLoadoutClothComponent));
800 if (BaseLoadoutClothComponent.Cast(component))
801 {
802 BaseLoadoutClothComponent clothComp = BaseLoadoutClothComponent.Cast(component);
803 LoadoutAreaType loadoutArea = clothComp.GetAreaType();
804 return loadoutArea && item != GetClothFromArea(loadoutArea.Type());//prevent reequipping of an item
805 }
806
807 component = GenericComponent.Cast(item.FindComponent(BaseWeaponComponent));
808 if (component)
809 {
810 if (charCtrl.IsChangingItem())
811 return false;
812
813 BaseWeaponComponent weapon = BaseWeaponComponent.Cast(component);
814 return weapon && weapon.CanBeEquipped(charCtrl) == ECanBeEquippedResult.OK;//f.e. mines cannot be equipped while prone
815 }
816
817 return CanUseItem(item);
818 }
819
820 //---- REFACTOR NOTE START: Ideally should be linked to components and rather should work based on item config instead ----
821
822 // For use from inventory menu
823 bool CanUseItem_Inventory(notnull IEntity item, ESlotFunction slotFunction = ESlotFunction.TYPE_GENERIC)
824 {
825 ChimeraCharacter character = ChimeraCharacter.Cast(GetOwner());
826 if (!character)
827 return false;
828
829 CharacterControllerComponent controller = character.GetCharacterController();
830 if (!controller)
831 return false;
832
833 if (slotFunction == ESlotFunction.TYPE_GENERIC)
834 {
835 if (item.FindComponent(BaseLoadoutClothComponent))
836 slotFunction = ESlotFunction.TYPE_CLOTHES;
837 else if (item.FindComponent(SCR_GadgetComponent))
838 slotFunction = ESlotFunction.TYPE_GADGET;
839 else if (item.FindComponent(MagazineComponent))
840 slotFunction = ESlotFunction.TYPE_MAGAZINE;
841 else if (item.FindComponent(BaseWeaponComponent))
842 slotFunction = ESlotFunction.TYPE_WEAPON;
843 }
844
845 switch (slotFunction)
846 {
847 case ESlotFunction.TYPE_CLOTHES:
848 {
849 return false;
850 } break;
851
852 case ESlotFunction.TYPE_MAGAZINE:
853 {
854 if (!character.IsInVehicle())
855 return CanReloadCurrentWeapon(item);
856
857 return false;
858 } break;
859
860 case ESlotFunction.TYPE_WEAPON:
861 {
862 return false;
863 } break;
864
865 case ESlotFunction.TYPE_GADGET:
866 {
867 SCR_ConsumableItemComponent consumableComp = SCR_ConsumableItemComponent.Cast(item.FindComponent(SCR_ConsumableItemComponent));
868 if (consumableComp)
869 {
870 return (consumableComp
871 && consumableComp.GetConsumableEffect()
872 && consumableComp.GetConsumableEffect().CanApplyEffect(character, character));
873 }
874 else
875 {
876 SCR_GadgetComponent gadgetComp = SCR_GadgetComponent.Cast(item.FindComponent(SCR_GadgetComponent));
877 return (gadgetComp.GetMode() == EGadgetMode.IN_HAND && gadgetComp.GetUseMask() & SCR_EUseContext.FROM_INVENTORY);
878 }
879 } break;
880 }
881
882 return false;
883 }
884
885 //------------------------------------------------------------------------------------------------
890 bool CanUseItem(notnull IEntity item, ESlotFunction slotFunction = ESlotFunction.TYPE_GENERIC)
891 {
892 ChimeraCharacter character = ChimeraCharacter.Cast(GetOwner());
893 if (!character)
894 return false;
895
896 CharacterControllerComponent controller = character.GetCharacterController();
897 if (!controller)
898 return false;
899
900 // Autodetect slot function if not provided
901 if (slotFunction == ESlotFunction.TYPE_GENERIC)
902 {
903 if (item.FindComponent(SCR_GadgetComponent))
904 slotFunction = ESlotFunction.TYPE_GADGET;
905 else if (item.FindComponent(MagazineComponent))
906 slotFunction = ESlotFunction.TYPE_MAGAZINE;
907 else if (item.FindComponent(BaseWeaponComponent))
908 slotFunction = ESlotFunction.TYPE_WEAPON;
909 }
910
911 switch (slotFunction)
912 {
913 case ESlotFunction.TYPE_MAGAZINE:
914 {
915 if (!character.IsInVehicle())
916 return CanReloadCurrentWeapon(item);
917
918 return false;
919 }
920
921 case ESlotFunction.TYPE_WEAPON:
922 {
924 {
926 return currentWeapon && currentWeapon.GetOwner(); // TODO: != item
927 }
928 else
929 {
930 return controller.GetCanFireWeapon(); // TODO: Has multiple muzzles or has next grenade type
931 }
932
933 return false;
934 }
935
936 case ESlotFunction.TYPE_GADGET:
937 {
938 return controller.CanEquipGadget(item);
939 }
940 }
941
942 return false;
943 }
944
945 //------------------------------------------------------------------------------------------------
950 bool UseItem(notnull IEntity item, ESlotFunction slotFunction = ESlotFunction.TYPE_GENERIC, SCR_EUseContext context = SCR_EUseContext.FROM_QUICKSLOT)
951 {
952 ChimeraCharacter character = ChimeraCharacter.Cast(GetOwner());
953 if (!character)
954 return false;
955
956 // Autodetect slot function
957 if (slotFunction == ESlotFunction.TYPE_GENERIC)
958 {
959 if (item.FindComponent(SCR_GadgetComponent))
960 slotFunction = ESlotFunction.TYPE_GADGET;
961 else if (item.FindComponent(BaseLoadoutClothComponent))
962 slotFunction = ESlotFunction.TYPE_CLOTHES;
963 else if (item.FindComponent(MagazineComponent))
964 slotFunction = ESlotFunction.TYPE_MAGAZINE;
965 else if (item.FindComponent(BaseWeaponComponent))
966 slotFunction = ESlotFunction.TYPE_WEAPON;
967 }
968
969 SCR_UISoundEntity.SoundEvent(SCR_SoundEvent.SOUND_INV_VICINITY_EQUIP_CLICK);
970
971 switch (slotFunction)
972 {
973 case ESlotFunction.TYPE_MAGAZINE:
974 {
976
977 SCR_MagazinePredicate predicate = new SCR_MagazinePredicate();
978 predicate.magWellType = MagazineComponent.Cast(item.FindComponent(MagazineComponent)).GetMagazineWell().Type();
979 array<IEntity> magazines = {};
980
982 if (invMan)
983 invMan.FindItems(magazines, predicate);
984
985 foreach (IEntity nextMag : magazines)
986 {
987 if (nextMag != item)
988 {
989 StoreItemToQuickSlot(nextMag);
990 break;
991 }
992 }
993
994 return ReloadCurrentWeapon(item);
995 }
996
997 case ESlotFunction.TYPE_WEAPON:
998 {
999 CharacterControllerComponent controller = character.GetCharacterController();
1000 if (!controller)
1001 return false;
1002
1003 m_Callback.m_pItem = item;
1004 m_Callback.m_Controller = controller;
1005
1007 if (gadgetMgr)
1008 gadgetMgr.RemoveHeldGadget();
1009
1011 if (turretCompartment)
1012 {
1013 TurretControllerComponent turretController = TurretControllerComponent.Cast(turretCompartment.GetController());
1014 if (!turretController)
1015 return false;
1016
1017 array<WeaponSlotComponent> turretWeaponSlots = {};
1018 GetTurretWeaponSlots(turretCompartment, turretWeaponSlots);
1019 foreach (WeaponSlotComponent weaponSlot: turretWeaponSlots)
1020 {
1021 if (weaponSlot.GetWeaponEntity() == item)
1022 return turretController.SelectWeapon(character, weaponSlot);
1023 }
1024 }
1025 else
1026 {
1027 SCR_InventoryStorageManagerComponent inventoryManager = SCR_InventoryStorageManagerComponent.Cast(controller.GetInventoryStorageManager());
1028 if (!inventoryManager)
1029 return false;
1030
1031 BaseWeaponComponent currentWeapon;
1032 BaseWeaponManagerComponent manager = controller.GetWeaponManagerComponent();
1033 if (manager)
1034 currentWeapon = manager.GetCurrentWeapon();
1035
1036 // Swap grenade type only if reselecting the same grenade slot
1037 BaseWeaponComponent itemWeapon = BaseWeaponComponent.Cast(item.FindComponent(BaseWeaponComponent));
1038 if (itemWeapon && itemWeapon.CanBeEquipped(controller) != ECanBeEquippedResult.OK)
1039 {
1040 return false;
1041 }
1042 else if (currentWeapon && itemWeapon && currentWeapon.GetWeaponType() == itemWeapon.GetWeaponType() && WEAPON_TYPES_THROWABLE.Contains(itemWeapon.GetWeaponType()))
1043 {
1044 // Equip different type of grenade
1045 IEntity nextGrenade = inventoryManager.FindNextWeaponOfType(itemWeapon.GetWeaponType(), currentWeapon.GetOwner());
1046 if (nextGrenade)
1047 m_Callback.m_pItem = nextGrenade;
1048 }
1049 // Currently selected weapon can have alternative muzzle
1050 else if (currentWeapon && currentWeapon.GetOwner() == item && !controller.IsGadgetInHands())
1051 {
1052 // Select next muzzle of a selected weapon
1053 int nextMuzzleID = SCR_WeaponLib.GetNextMuzzleID(currentWeapon);
1054 if (nextMuzzleID != -1)
1055 return controller.SetMuzzle(nextMuzzleID);
1056
1057 return false;
1058 }
1059
1060 // TODO: Interrupt current equipping process now
1062 {
1063 bool result = controller.TryEquipRightHandItem(m_Callback.m_pItem, EEquipItemType.EEquipTypeWeapon, false);
1064 m_Callback.m_pItem = null;
1065 return result;
1066 }
1067
1068 return inventoryManager.EquipWeapon(m_Callback.m_pItem, m_Callback, false);
1069 }
1070 break;
1071 }
1072
1073 case ESlotFunction.TYPE_GADGET:
1074 {
1075 // need to run through manager
1076 // TODO kamil: this doesnt call setmode when switching to other item from gadget (no direct call to scripted togglefocused for example, possibly other issues?)
1078 if (gadgetMgr)
1079 {
1080 SCR_GadgetComponent gadgetComp = SCR_GadgetComponent.Cast(item.FindComponent(SCR_GadgetComponent));
1081 if (gadgetComp.GetMode() == EGadgetMode.IN_HAND && gadgetComp.GetUseMask() != SCR_EUseContext.NONE)
1082 {
1083 gadgetComp.ToggleActive(!gadgetComp.IsToggledOn(), context);
1084 }
1085 else
1086 {
1087 if (gadgetMgr.GetHeldGadget() && gadgetMgr.GetHeldGadget() != item)
1088 gadgetMgr.RemoveHeldGadget();
1089
1090 gadgetMgr.SetGadgetMode(item, EGadgetMode.IN_HAND);
1091 }
1092 }
1093 else
1094 {
1095 return false;
1096 }
1097
1098 return true;
1099 }
1100
1101 case ESlotFunction.TYPE_CLOTHES:
1102 {
1105
1106 SCR_InventoryStorageManagerComponent storageMgr = SCR_InventoryStorageManagerComponent.Cast(character.GetCharacterController().GetInventoryStorageManager());
1107 if (storageMgr)
1108 storageMgr.EquipAny(this, item, -1, cb);
1109 } break;
1110
1111 case ESlotFunction.TYPE_STORAGE:
1112 {
1115
1116 SCR_InventoryStorageManagerComponent storageMgr = SCR_InventoryStorageManagerComponent.Cast(character.GetCharacterController().GetInventoryStorageManager());
1117 if (storageMgr)
1118 storageMgr.EquipAny(this, item, -1, cb);
1119 } break;
1120 }
1121 return false;
1122 }
1123
1124 //---- REFACTOR NOTE END ----
1125
1126 //------------------------------------------------------------------------------------------------
1127 protected bool CanReloadCurrentWeapon(notnull IEntity item)
1128 {
1129 BaseWeaponComponent currentWeapon = GetCurrentWeapon();
1130 if (!currentWeapon)
1131 return false;
1132
1133 if (!currentWeapon.IsReloadPossible())
1134 return false;
1135
1136 BaseMuzzleComponent currentMuzzle = currentWeapon.GetCurrentMuzzle();
1137 if (!currentMuzzle)
1138 return false;
1139
1140 BaseMagazineWell currentMagWell = currentMuzzle.GetMagazineWell();
1141 if (!currentMagWell)
1142 return false;
1143
1144 MagazineComponent magazine = MagazineComponent.Cast(item.FindComponent(MagazineComponent));
1145 if (!magazine)
1146 return false;
1147
1148 BaseMagazineWell magazineWell = magazine.GetMagazineWell();
1149 if (!magazineWell)
1150 return false;
1151
1152 if (magazineWell.Type() == currentMagWell.Type())
1153 return true;
1154
1155 return false;
1156 }
1157
1158 //------------------------------------------------------------------------------------------------
1159 protected bool ReloadCurrentWeapon(IEntity item)
1160 {
1161 if (!item)
1162 return false;
1163
1164 ChimeraCharacter character = ChimeraCharacter.Cast(GetOwner());
1165 if (!character)
1166 return false;
1167
1168 CharacterControllerComponent controller = character.GetCharacterController();
1169 if (!controller)
1170 return false;
1171
1172 return controller.ReloadWeaponWith(item);
1173 }
1174
1175 //------------------------------------------------------------------------------------------------
1176 protected void GetPlayersWeapons( notnull inout array<IEntity> outWeapons )
1177 {
1178 ChimeraCharacter character = ChimeraCharacter.Cast(GetOwner());
1179 if (!character)
1180 return;
1181
1182 CharacterControllerComponent controller = character.GetCharacterController();
1183 if (!controller)
1184 return;
1185
1186 BaseWeaponManagerComponent weaponManager = controller.GetWeaponManagerComponent();
1187 if (weaponManager)
1188 weaponManager.GetWeaponsList(outWeapons);
1189 }
1190
1191 //------------------------------------------------------------------------------------------------
1193 {
1194 ChimeraCharacter character = ChimeraCharacter.Cast(GetOwner());
1195 if (!character)
1196 return null;
1197
1198 CompartmentAccessComponent compAccess = character.GetCompartmentAccessComponent();
1199 if (!compAccess || !compAccess.IsInCompartment())
1200 return null;
1201
1202 return compAccess.GetCompartment();
1203 }
1204
1205 //------------------------------------------------------------------------------------------------
1207 {
1209 if (!compartment)
1210 return null;
1211
1212 TurretControllerComponent controller = TurretControllerComponent.Cast(compartment.GetController());
1213 if (!controller)
1214 return null;
1215
1216 BaseWeaponManagerComponent weaponManager = controller.GetWeaponManager();
1217 if (!weaponManager)
1218 return null;
1219
1220 return weaponManager.GetCurrentWeapon();
1221 }
1222
1223 //------------------------------------------------------------------------------------------------
1225 {
1227 if (turretWeapon)
1228 return turretWeapon;
1229
1230 ChimeraCharacter character = ChimeraCharacter.Cast(GetOwner());
1231 if (!character)
1232 return null;
1233
1234 CharacterControllerComponent controller = character.GetCharacterController();
1235 if (!controller)
1236 return null;
1237
1238 BaseWeaponManagerComponent weaponManager = controller.GetWeaponManagerComponent();
1239 if (!weaponManager)
1240 return null;
1241
1242 return weaponManager.GetCurrentWeapon();
1243 }
1244
1245 //------------------------------------------------------------------------------------------------
1247 {
1249 if (compartment)
1250 return GetCurrentTurretWeapon();
1251 else
1253 }
1254
1255 //------------------------------------------------------------------------------------------------
1257 IEntity SelectNextWeapon(int maxSlot = -1)
1258 {
1259 IEntity nextWeapon = GetNextWeapon(maxSlot);
1260 if (!nextWeapon)
1261 return null;
1262
1263 if (CanUseItem(nextWeapon))
1264 {
1265 UseItem(nextWeapon);
1266
1267 int id = GetEntityIndexInQuickslots(nextWeapon);
1269 }
1270
1271 return nextWeapon;
1272 }
1273
1274 //------------------------------------------------------------------------------------------------
1276 IEntity GetNextWeapon(int maxSlots = -1)
1277 {
1278 if (maxSlots < 0)
1279 {
1281 maxSlots = TURRET_WEAPON_SWITCH_SLOTS;
1282 else
1284 }
1285
1286 maxSlots = Math.Min(maxSlots, m_aQuickSlots.Count());
1287
1288 IEntity currentWeapon;
1289 BaseWeaponComponent currentWeaponComponent = GetCurrentWeapon();
1290 if (currentWeaponComponent)
1291 currentWeapon = currentWeaponComponent.GetOwner();
1292
1293 // If not currently equipped, select weapon again
1294 if (currentWeapon && currentWeapon == GetCurrentItem())
1295 {
1296 // Find current slot
1297 int currentSlot = -1;
1298 for (int i; i < maxSlots; i++)
1299 {
1300 if (GetItemFromQuickSlot(i) != currentWeapon)
1301 continue;
1302
1303 currentSlot = i;
1304 break;
1305 }
1306
1307 // Find next weapon within limit
1308 IEntity item;
1309 int nextSlot = -1;
1310 for (int i; i < maxSlots; i++)
1311 {
1312 nextSlot = (currentSlot + i + 1) % maxSlots;
1313
1314 if (nextSlot == currentSlot)
1315 continue;
1316
1317 item = GetItemFromQuickSlot(nextSlot);
1318 if (item)
1319 return item;
1320 }
1321 }
1322 else
1323 {
1324 // Get first valid item
1325 IEntity item;
1326 for (int i; i < maxSlots; i++)
1327 {
1328 item = GetItemFromQuickSlot(i);
1329 if (item)
1330 return item;
1331 }
1332 }
1333
1334 return null;
1335 }
1336
1337 //------------------------------------------------------------------------------------------------
1341 void InitAsPlayer(IEntity pOwner, bool pControlled)
1342 {
1343 ChimeraCharacter character = ChimeraCharacter.Cast(pOwner);
1344 if (!character)
1345 return;
1346
1347 CharacterControllerComponent controller = character.GetCharacterController();
1348 if (!controller)
1349 return;
1350
1351 SCR_InventoryStorageManagerComponent pInventoryManager = SCR_InventoryStorageManagerComponent.Cast(controller.GetInventoryStorageManager());
1352 if ( !pInventoryManager )
1353 return;
1354
1355 if (pControlled)
1356 {
1357 array<IEntity> initSlotItems = {};
1358 pInventoryManager.GetItems(initSlotItems);
1359 foreach (IEntity item : initSlotItems)
1360 {
1361 if (!item)
1362 continue;
1363
1364 const int slotId = GetDefaultQuickSlot(item);
1365 if (!SetQuickSlotInitialized(slotId))
1366 continue; // Already inited by external logic (e.g. save-game)
1367
1368 if (GetEntityIndexInQuickslots(item) == slotId)
1369 continue; // Already in default quick slot
1370
1372 }
1373
1374 pInventoryManager.m_OnItemAddedInvoker.Insert( HandleOnItemAddedToInventory );
1375 pInventoryManager.m_OnItemRemovedInvoker.Insert( HandleOnItemRemovedFromInventory );
1376
1378 if (charController)
1379 charController.m_OnItemUseEndedInvoker.Insert(OnItemUsed);
1380
1381 m_CompartmentAccessComp = SCR_CompartmentAccessComponent.Cast(character.GetCompartmentAccessComponent());
1383 return;
1384
1385 m_CompartmentAccessComp.GetOnCompartmentEntered().Insert(OnCompartmentEntered);
1386 m_CompartmentAccessComp.GetOnCompartmentLeft().Insert(OnCompartmentLeft);
1387
1388 BaseCompartmentSlot compartmentSlot = m_CompartmentAccessComp.GetCompartment();
1389 if (compartmentSlot)
1390 {
1391 // If the character was already in a compartment slot before the character was initialized as a player, we need to handle it.
1392 OnCompartmentSlotEntered(compartmentSlot);
1393 }
1394 }
1395 else
1396 {
1397 pInventoryManager.m_OnItemAddedInvoker.Remove( HandleOnItemAddedToInventory );
1398 pInventoryManager.m_OnItemRemovedInvoker.Remove( HandleOnItemRemovedFromInventory );
1399
1401 {
1402 m_CompartmentAccessComp.GetOnCompartmentEntered().Remove(OnCompartmentEntered);
1403 m_CompartmentAccessComp.GetOnCompartmentLeft().Remove(OnCompartmentLeft);
1404 }
1405 }
1406 }
1407
1408 //------------------------------------------------------------------------------------------------
1409 // Called when item is used by the player
1410 protected void OnItemUsed(IEntity item, bool successful, ItemUseParameters animParams)
1411 {
1412 if (!item)
1413 return;
1414
1415 // If the item isn't consumable, return
1416 if (!SCR_ConsumableItemComponent.Cast(item.FindComponent(SCR_ConsumableItemComponent)))
1417 return;
1418
1419 // restock used medical item back to its quick slot
1420 int quickSlot = GetEntityIndexInQuickslots(item);
1421 if (quickSlot == -1)
1422 return;
1423
1425 int itemType = GetItemType(item);
1426
1427 typename t = BaseWeaponComponent;
1428 if (itemType > GADGET_OFFSET)
1429 t = SCR_GadgetComponent;
1430
1431 SCR_ItemTypeSearchPredicate itemSearch = new SCR_ItemTypeSearchPredicate(t, itemType, item);
1432 array<IEntity> items = {};
1433
1435 if (!invMan)
1436 return;
1437
1438 invMan.FindItems(items, itemSearch);
1439
1440 if (!items.IsEmpty())
1441 {
1442 foreach (IEntity itm : items)
1443 {
1444 if (itm == item)
1445 continue;
1446 StoreItemToQuickSlot(itm, quickSlot);
1447 break;
1448 }
1449 }
1450 }
1451
1452 //------------------------------------------------------------------------------------------------
1453 private void OnCompartmentSlotEntered(BaseCompartmentSlot compartment)
1454 {
1456 {
1458 IEntity entity;
1459 SCR_QuickslotEntityContainer entityContainer;
1460 for (int i, count = m_aQuickSlots.Count(); i < SCR_InventoryMenuUI.WEAPON_SLOTS_COUNT && i < count; i++)
1461 {
1462 entityContainer = SCR_QuickslotEntityContainer.Cast(m_aQuickSlots[i]);
1463 if (!entityContainer)
1464 {
1465 m_aWeaponQuickSlotsStorage.Insert(null);
1466 continue;
1467 }
1468
1469 m_aWeaponQuickSlotsStorage.Insert(entityContainer.GetEntity());
1470 }
1471 }
1472
1473 if (!TurretCompartmentSlot.Cast(compartment) && !m_aWeaponQuickSlotsStorage.IsEmpty())
1474 {
1476
1477 IEntity quickSlotEntity;
1478 SCR_InventoryStorageManagerComponent pInventoryManager = SCR_InventoryStorageManagerComponent.Cast(GetOwner().FindComponent( SCR_InventoryStorageManagerComponent));
1479
1480 for (int i; i < m_aWeaponQuickSlotsStorage.Count(); i++)
1481 {
1482 quickSlotEntity = m_aWeaponQuickSlotsStorage[i];
1483
1484 if (!quickSlotEntity)
1485 continue;
1486
1487 if (!pInventoryManager.Contains(quickSlotEntity))
1488 continue;
1489
1490 StoreItemToQuickSlot(quickSlotEntity, i, true);
1491 }
1492
1493 SCR_WeaponSwitchingBaseUI.RefreshQuickSlots();
1494
1495 return;
1496 }
1497
1498 array<WeaponSlotComponent> turretWeaponSlots = {};
1499 if (GetTurretWeaponSlots(compartment, turretWeaponSlots) > 0)
1500 {
1502
1503 foreach (int i, WeaponSlotComponent weaponSlot: turretWeaponSlots)
1504 {
1505 IEntity weaponSlotEntity = weaponSlot.GetWeaponEntity();
1506 if (!weaponSlotEntity)
1507 continue;
1508
1509 StoreItemToQuickSlot(weaponSlotEntity, i, true);
1510 }
1511 }
1512
1513 SCR_WeaponSwitchingBaseUI.RefreshQuickSlots();
1514 }
1515
1516 //------------------------------------------------------------------------------------------------
1523 protected void OnCompartmentEntered(IEntity targetEntity, BaseCompartmentManagerComponent manager, int mgrID, int slotID, bool move)
1524 {
1525 BaseCompartmentSlot compartment = manager.FindCompartment(slotID, mgrID);
1526
1527 OnCompartmentSlotEntered(compartment);
1528 }
1529
1530 //------------------------------------------------------------------------------------------------
1537 protected void OnCompartmentLeft(IEntity targetEntity, BaseCompartmentManagerComponent manager, int mgrID, int slotID, bool move)
1538 {
1539 BaseCompartmentSlot compartment = manager.FindCompartment(slotID, mgrID);
1540
1541 if (!TurretCompartmentSlot.Cast(compartment))
1542 {
1544 IEntity entity;
1545 SCR_QuickslotEntityContainer entityContainer;
1546 for (int i, count = m_aQuickSlots.Count(); i < SCR_InventoryMenuUI.WEAPON_SLOTS_COUNT && i < count; i++)
1547 {
1548 entityContainer = SCR_QuickslotEntityContainer.Cast(m_aQuickSlots[i]);
1549 if (!entityContainer)
1550 {
1551 m_aWeaponQuickSlotsStorage.Insert(null);
1552 continue;
1553 }
1554
1555 m_aWeaponQuickSlotsStorage.Insert(entityContainer.GetEntity());
1556 }
1557 }
1558
1560 {
1562
1563 IEntity quickSlotEntity;
1564 SCR_InventoryStorageManagerComponent pInventoryManager = SCR_InventoryStorageManagerComponent.Cast(GetOwner().FindComponent( SCR_InventoryStorageManagerComponent));
1565
1566 for (int i; i < m_aWeaponQuickSlotsStorage.Count(); i++)
1567 {
1568 quickSlotEntity = m_aWeaponQuickSlotsStorage[i];
1569
1570 if (!quickSlotEntity)
1571 continue;
1572
1573 if (!pInventoryManager.Contains(quickSlotEntity))
1574 continue;
1575
1576 StoreItemToQuickSlot(quickSlotEntity, i, true);
1577 }
1578
1580 }
1581
1583 }
1584
1585 //------------------------------------------------------------------------------------------------
1587 {
1588 for (int i = 0; i < SCR_InventoryMenuUI.WEAPON_SLOTS_COUNT; i++)
1589 {
1591 }
1592 }
1593
1594 //------------------------------------------------------------------------------------------------
1595 protected int GetTurretWeaponsList(BaseCompartmentSlot compartment, out array<IEntity> weaponsList)
1596 {
1597 TurretControllerComponent turretController = TurretControllerComponent.Cast(compartment.GetController());
1598 if (!turretController)
1599 return -1;
1600
1601 BaseWeaponManagerComponent weaponManager = turretController.GetWeaponManager();
1602 if (weaponManager)
1603 return weaponManager.GetWeaponsList(weaponsList);
1604
1605 return -1;
1606 }
1607
1608 //------------------------------------------------------------------------------------------------
1609 protected int GetTurretWeaponSlots(BaseCompartmentSlot compartment, out array<WeaponSlotComponent> weaponSlots)
1610 {
1611 TurretControllerComponent turretController = TurretControllerComponent.Cast(compartment.GetController());
1612 if (!turretController)
1613 return -1;
1614
1615 BaseWeaponManagerComponent weaponManager = turretController.GetWeaponManager();
1616 if (weaponManager)
1617 return weaponManager.GetWeaponsSlots(weaponSlots);
1618
1619 return -1;
1620 }
1621
1622 //------------------------------------------------------------------------------------------------
1625 {
1626 int index = -1;
1627 SCR_QuickslotEntityContainer entityContainer;
1628 foreach (int i, SCR_QuickslotBaseContainer container : m_aQuickSlots)
1629 {
1630 entityContainer = SCR_QuickslotEntityContainer.Cast(container);
1631 if (entityContainer && entityContainer.GetEntity() == entity)
1632 index = i;
1633 }
1634
1635 return index;
1636 }
1637
1638 //------------------------------------------------------------------------------------------------
1641 {
1642 int index = -1;
1643 SCR_QuickslotEntityContainer entityContainer;
1644 IEntity testedEntity;
1645 InventoryItemComponent itemComponent;
1646 foreach (int i, SCR_QuickslotBaseContainer container : m_aQuickSlots)
1647 {
1648 entityContainer = SCR_QuickslotEntityContainer.Cast(container);
1649 if (entityContainer && entityContainer.GetEntity())
1650 {
1651 testedEntity = entityContainer.GetEntity();
1652 itemComponent = InventoryItemComponent.Cast(testedEntity.FindComponent(InventoryItemComponent));
1653 if (!itemComponent)
1654 continue;;
1655
1656 if (itemComponent.GetAttributes().GetCommonType() != type)
1657 continue;
1658
1659 index = i;
1660 }
1661 }
1662
1663 return index;
1664 }
1665
1666 //------------------------------------------------------------------------ PERCEIVED FACTION ----------------------------------------------------------------------
1667 //------------------------------------------------------------------------------------------------
1670 void InitCharacterPerceivedOutfitData(notnull SCR_CharacterFactionAffiliationComponent characterAffiliationComponent)
1671 {
1672 m_CharacterAffiliationComponent = characterAffiliationComponent;
1673
1674 array<IEntity> allItems = {};
1675 GetAll(allItems);
1676
1677 SCR_ItemOutfitFactionComponent outfitComponent;
1678
1679 //~ Update the perceived faction. Does not replicate as that is called when the init is done by the SCR_CharacterFactionAffiliationComponent
1680 foreach (IEntity item : allItems)
1681 {
1682 //~ Only check items that are in slots
1683 if (!FindItemSlot(item))
1684 continue;
1685
1686 UpdatePerceivedFaction(true, item, false);
1687 }
1688 }
1689
1690 //------------------------------------------------------------------------------------------------
1691 //~ Called on init and when an item is added or removed from the character
1692 protected void UpdatePerceivedFaction(bool addedToSlot, IEntity item, bool updateFaction = true)
1693 {
1695 return;
1696
1697 //~ Send update to character affiliation comp that a piece of clothing was added/removed even if it has no faction
1698 SCR_ItemOutfitFactionComponent outfitComponent = SCR_ItemOutfitFactionComponent.Cast(item.FindComponent(SCR_ItemOutfitFactionComponent));
1699 if (!outfitComponent)
1700 {
1701 m_CharacterAffiliationComponent.OnNoFactionSlottedItemChanged(addedToSlot, item, updateFaction);
1702 return;
1703 }
1704
1705 if (addedToSlot)
1706 outfitComponent.OnAddedToSlot(m_CharacterAffiliationComponent, updateFaction);
1707 else
1708 outfitComponent.OnRemovedFromSlot(m_CharacterAffiliationComponent, updateFaction);
1709 }
1710
1711 //------------------------------------------------------------------------ COMMON METHODS ----------------------------------------------------------------------
1712
1713 #else
1714
1715 //------------------------------------------------------------------------------------------------
1717 float GetMaxLoad();
1718
1719 //------------------------------------------------------------------------------------------------
1721 BaseInventoryStorageComponent GetWeaponStorage();
1722
1723 //------------------------------------------------------------------------------------------------
1726 InventoryItemComponent GetItemFromLoadoutSlot( ELoadoutArea eSlot );
1727
1728 //------------------------------------------------------------------------------------------------
1731 BaseInventoryStorageComponent GetStorageFromLoadoutSlot( ELoadoutArea eSlot );
1732 protected bool HasStorageComponent( IEntity pEntity );
1733
1734 //------------------------------------------------------------------------------------------------
1736 void GetStorages( out notnull array<SCR_UniversalInventoryStorageComponent> storagesInInventory );
1737
1738 //------------------------------------------------------------------------------------------------
1742
1743 //------------------------------------------------------------------------------------------------
1745 void SetLootStorage( IEntity pOwner );
1746
1747 //------------------------------------------------------------------------------------------------
1749 BaseInventoryStorageComponent GetLootStorage();
1750 //override bool CanStoreItem(IEntity item, int slotID);
1751 //override bool CanRemoveItem(IEntity item);
1752 //protected override void OnRemovedFromSlot(IEntity item, int slotID);
1753 //override InventoryStorageSlot GetEmptySlotForItem( IEntity item );
1754 //protected override void OnAddedToSlot(IEntity item, int slotID);
1755 #endif
1756}
ArmaReforgerScripted GetGame()
Definition game.c:1398
ECommonItemType
SCR_EArsenalItemType GetItemType()
SCR_EquipGearCB m_CharacterStorage
SCR_InvEquipCB m_InvMan
enum EItemType ComponentEditorProps(category:"GameScripted/Inventory", description:"Inventory 2.0", icon:HYBRID_COMPONENT_ICON)
SCR_EConsumableType
Type of consumable gadget.
EDamageType type
SCR_DestructionSynchronizationComponentClass ScriptComponentClass int index
SCR_EUseContext
void SCR_QuickslotEntityContainer(IEntity entity)
array< ref SCR_TaskFinishEntry > GetAll()
SCR_InventoryStorageManagerComponent pInventoryManager
void SCR_UniversalInventoryStorageComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
enum EVehicleType IEntity
proto external Managed FindComponent(typename typeName)
Definition Math.c:13
void UpdateArmorDataMap(notnull SCR_ArmoredClothItemData armorAttr, bool remove)
If !remove, take data from prefab and insert to map as class. If remove, remove this hitZone's stored...
static const ref array< EWeaponType > WEAPON_TYPES_THROWABLE
void UpdateBlockedSlots(IEntity item, int slotID, bool added)
void SetStorageAsShown(notnull BaseInventoryStorageComponent pStorage)
bool UseItem(notnull IEntity item, ESlotFunction slotFunction=ESlotFunction.TYPE_GENERIC, SCR_EUseContext context=SCR_EUseContext.FROM_QUICKSLOT)
void HandleOnItemAddedToInventory(IEntity item, BaseInventoryStorageComponent storageOwner)
int StoreItemToQuickSlot(notnull IEntity pItem, int iSlotIndex=-1, bool isForced=false)
void OnItemUsed(IEntity item, bool successful, ItemUseParameters animParams)
array< IEntity > GetQuickSlotEntitiesOnly()
gets all entities in quickslots, and nulls in arrays for non-entity or empty slots
IEntity SelectNextWeapon(int maxSlot=-1)
Select next weapon.
void EditArmoredAttributes(IEntity item, int slotID, bool remove=false)
Take the data from the armor attribute, and store them in map on damagemanager.
void GetBlockedSlots(out notnull array< typename > blockedSlots)
int GetTurretWeaponSlots(BaseCompartmentSlot compartment, out array< WeaponSlotComponent > weaponSlots)
bool GetIsStorageShown(notnull BaseInventoryStorageComponent pStorage)
bool CanUseItem_Inventory(notnull IEntity item, ESlotFunction slotFunction=ESlotFunction.TYPE_GENERIC)
SCR_CharacterFactionAffiliationComponent m_CharacterAffiliationComponent
void InsertContainerIntoQuickslot(SCR_QuickslotBaseContainer container, int slotIndex)
void GetPlayersWeapons(notnull inout array< IEntity > outWeapons)
void OnCompartmentEntered(IEntity targetEntity, BaseCompartmentManagerComponent manager, int mgrID, int slotID, bool move)
void HandleOnItemRemovedFromInventory(IEntity item, BaseInventoryStorageComponent storageOwner)
void UpdatePerceivedFaction(bool addedToSlot, IEntity item, bool updateFaction=true)
override void OnRemovedFromSlot(IEntity item, int slotID)
ref array< BaseInventoryStorageComponent > m_aStoragesInStorageList
static const ref array< ref array< int > > DEFAULT_QUICK_SLOTS
void InitCharacterPerceivedOutfitData(notnull SCR_CharacterFactionAffiliationComponent characterAffiliationComponent)
array< ref SCR_QuickslotBaseContainer > GetQuickSlotItems()
void OnCompartmentLeft(IEntity targetEntity, BaseCompartmentManagerComponent manager, int mgrID, int slotID, bool move)
void UnequipCurrentItem()
Unequip currently held item. Not allowed while switching to another item.
ref array< ref SCR_QuickslotBaseContainer > m_aQuickSlots
IEntity GetNextWeapon(int maxSlots=-1)
Get next weapon up to specified maximum.
InventoryItemComponent GetItemFromLoadoutSlot(LoadoutAreaType eSlot)
void DropCurrentItem()
Drop currently held item. Not allowed while switching to another item.
int GetTurretWeaponsList(BaseCompartmentSlot compartment, out array< IEntity > weaponsList)
void SetStorageAsHidden(notnull BaseInventoryStorageComponent pStorage)
void GetStorages(out notnull array< SCR_UniversalInventoryStorageComponent > storagesInInventory)
SCR_UniversalInventoryStorageComponent GetStorageComponentFromEntity(IEntity pEntity)
SCR_QuickslotBaseContainer GetContainerFromQuickslot(int index)
BaseInventoryStorageComponent GetStorageFromLoadoutSlot(LoadoutAreaType eSlot)
bool CanUseItem(notnull IEntity item, ESlotFunction slotFunction=ESlotFunction.TYPE_GENERIC)
void SetGadgetMode(IEntity gadget, EGadgetMode targetMode, bool doFocus=false)
static SCR_GadgetManagerComponent GetGadgetManager(IEntity entity)
void RemoveHeldGadget()
Remove gadget held in hand.
override void OnFailed()
override void OnComplete()
static SCR_InventoryMenuUI GetInventoryMenu()
SCR_QuickslotBaseContainer is intended to be used for quickslots, to allow quickslotting of non-item ...
static void HighlightQuickSlot(int id, bool highlight=true)
static void RefreshQuickSlots(int id=-1)
UIInfo - allows to define UI elements.
Definition UIInfo.c:14
Definition Types.c:486
IEntity GetOwner()
Owner entity of the fuel tank.
HYBRID_COMPONENT_ICON
Default icon for all components written in script that don't inherit ScriptComponent.
EEquipItemType
proto external bool CanUseItem()
Returns true if the character can use an item.
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
LogLevel
Enum with severity of the logging message.
Definition LogLevel.c:14
SCR_FieldOfViewSettings Attribute
EquipedLoadoutStorageComponentClass ScriptedBaseInventoryStorageComponentClass GetSlotFromArea(typename pAreaType)
Get the first slot that satisfies the condition : "slot area type is inherited by pAreaType".
proto external IEntity GetClothFromArea(typename pAreaType)
Get the first cloth entity that satisfies the condition : "slot area type is inherited by pAreaType A...
proto external sealed InventoryStorageSlot FindItemSlot(IEntity item)
proto bool Contains(T value)
EWeaponType
Definition EWeaponType.c:13
ECanBeEquippedResult