@rpg-engine/long-bow 0.1.70 → 0.1.71

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/dist/components/Abstractions/SlotsContainer.d.ts +11 -0
  2. package/dist/components/DraggableContainer.d.ts +1 -0
  3. package/dist/components/Equipment/EquipmentSet.d.ts +13 -0
  4. package/dist/components/Item/Inventory/ItemSlot.d.ts +10 -2
  5. package/dist/components/Item/Inventory/itemContainerHelper.d.ts +6 -2
  6. package/dist/components/store/UI.store.d.ts +34 -0
  7. package/dist/index.d.ts +1 -0
  8. package/dist/long-bow.cjs.development.js +1700 -365
  9. package/dist/long-bow.cjs.development.js.map +1 -1
  10. package/dist/long-bow.cjs.production.min.js +1 -1
  11. package/dist/long-bow.cjs.production.min.js.map +1 -1
  12. package/dist/long-bow.esm.js +1703 -367
  13. package/dist/long-bow.esm.js.map +1 -1
  14. package/dist/mocks/equipmentSet.mocks.d.ts +3 -0
  15. package/package.json +4 -2
  16. package/src/components/Abstractions/SlotsContainer.tsx +42 -0
  17. package/src/components/DraggableContainer.tsx +62 -37
  18. package/src/components/Equipment/EquipmentSet.tsx +179 -0
  19. package/src/components/Item/Inventory/ItemContainer.tsx +70 -178
  20. package/src/components/Item/Inventory/ItemSlot.tsx +92 -24
  21. package/src/components/Item/Inventory/itemContainerHelper.ts +48 -11
  22. package/src/components/Item/SpriteFromAtlas.tsx +8 -1
  23. package/src/components/ListMenu.tsx +3 -3
  24. package/src/components/store/UI.store.ts +192 -0
  25. package/src/index.tsx +1 -0
  26. package/src/mocks/atlas/items/items.json +1209 -181
  27. package/src/mocks/atlas/items/items.png +0 -0
  28. package/src/mocks/equipmentSet.mocks.ts +347 -0
  29. package/src/mocks/itemContainer.mocks.ts +33 -33
@@ -1,12 +1,34 @@
1
- import { IItem } from '@rpg-engine/shared';
1
+ import { IItem, IItemContainer, ItemSlotType } from '@rpg-engine/shared';
2
2
  import React from 'react';
3
3
  import styled from 'styled-components';
4
4
  import atlasJSON from '../../../mocks/atlas/items/items.json';
5
5
  import atlasIMG from '../../../mocks/atlas/items/items.png';
6
6
  import { SpriteFromAtlas } from '../SpriteFromAtlas';
7
+
8
+ export enum SlotContainerType {
9
+ INVENTORY = 'Inventory',
10
+ EQUIPMENT_SET = 'EquipmentSet',
11
+ }
12
+
13
+ const EquipmentSlotSpriteByType: any = {
14
+ Neck: 'accessories/corruption-necklace.png',
15
+ LeftHand: 'swords/broad-sword.png',
16
+ Ring: 'rings/iron-ring.png',
17
+ Head: 'helmets/viking-helmet.png',
18
+ Torso: 'armors/iron-armor.png',
19
+ Legs: 'crafting-resources/medicinal-leaf.png',
20
+ Feet: 'boots/iron-boots.png',
21
+ Inventory: 'containers/bag.png',
22
+ RightHand: 'shields/plate-shield.png',
23
+ Accessory: 'gloves/plate-gloves.png',
24
+ };
25
+
7
26
  interface IProps {
8
27
  slotIndex: number;
9
28
  item: IItem | null;
29
+ itemContainer?: IItemContainer | null;
30
+ slotContainerType: SlotContainerType | null;
31
+ slotSpriteMask?: ItemSlotType | null;
10
32
  onMouseOver: (
11
33
  event: any,
12
34
  slotIndex: number,
@@ -14,14 +36,23 @@ interface IProps {
14
36
  x: number,
15
37
  y: number
16
38
  ) => void;
17
- onClick: (item: IItem, posX: number, posY: number) => void;
39
+ onMouseOut: () => void;
40
+ onClick: (
41
+ item: IItem,
42
+ posX: number,
43
+ posY: number,
44
+ slotContainerType: SlotContainerType | null
45
+ ) => void;
18
46
  onCancelContextMenu: () => void;
19
47
  }
20
48
 
21
49
  export const ItemSlot: React.FC<IProps> = ({
22
50
  slotIndex,
23
51
  item,
52
+ slotContainerType,
53
+ slotSpriteMask,
24
54
  onMouseOver,
55
+ onMouseOut,
25
56
  onClick,
26
57
  onCancelContextMenu,
27
58
  }) => {
@@ -32,51 +63,88 @@ export const ItemSlot: React.FC<IProps> = ({
32
63
  return '2.5rem';
33
64
  };
34
65
 
66
+ const renderItem = (itemToRender: IItem | null) => {
67
+ const element = [];
68
+ if (itemToRender?.texturePath) {
69
+ element.push(
70
+ <SpriteFromAtlas
71
+ atlasIMG={atlasIMG}
72
+ atlasJSON={atlasJSON}
73
+ spriteKey={itemToRender.texturePath}
74
+ scale={3}
75
+ />
76
+ );
77
+ }
78
+ if (itemToRender?.isStackable && itemToRender?.stackQty) {
79
+ element.push(
80
+ <ItemQty left={getLeftPositionValue(itemToRender.stackQty)}>
81
+ {' '}
82
+ {itemToRender.stackQty}{' '}
83
+ </ItemQty>
84
+ );
85
+ }
86
+ return element;
87
+ };
88
+
89
+ const renderEquipment = (itemToRender: IItem | null) => {
90
+ if (
91
+ itemToRender?.texturePath &&
92
+ itemToRender.allowedEquipSlotType?.includes(slotSpriteMask!)
93
+ ) {
94
+ return (
95
+ <SpriteFromAtlas
96
+ atlasIMG={atlasIMG}
97
+ atlasJSON={atlasJSON}
98
+ spriteKey={itemToRender.texturePath}
99
+ scale={3}
100
+ />
101
+ );
102
+ } else {
103
+ return (
104
+ <SpriteFromAtlas
105
+ atlasIMG={atlasIMG}
106
+ atlasJSON={atlasJSON}
107
+ spriteKey={EquipmentSlotSpriteByType[slotSpriteMask!]}
108
+ scale={3}
109
+ grayScale={true}
110
+ opacity={0.4}
111
+ />
112
+ );
113
+ }
114
+ };
115
+
116
+ const onRenderSlot = (itemToRender: IItem | null) => {
117
+ if (slotContainerType === SlotContainerType.EQUIPMENT_SET)
118
+ return renderEquipment(itemToRender);
119
+ return renderItem(itemToRender);
120
+ };
121
+
35
122
  return (
36
123
  <Container
37
124
  className="rpgui-icon empty-slot"
38
125
  onMouseOver={event =>
39
126
  onMouseOver(event, slotIndex, item, event.clientX, event.clientY)
40
127
  }
128
+ onMouseOut={() => onMouseOut()}
41
129
  onClick={e => {
42
130
  if (item) {
43
- console.log(e);
44
- onClick(item, e.clientX, e.clientY);
131
+ onClick(item, e.clientX, e.clientY, slotContainerType);
45
132
  } else {
46
133
  onCancelContextMenu();
47
134
  }
48
135
  }}
49
136
  >
50
- {item && item.texturePath ? (
51
- <SpriteFromAtlas
52
- atlasIMG={atlasIMG}
53
- atlasJSON={atlasJSON}
54
- spriteKey={item.texturePath}
55
- scale={3}
56
- />
57
- ) : null}
58
- {item && item.isStackable && item?.stackQty ? (
59
- <ItemQty left={getLeftPositionValue(item.stackQty)}>
60
- {' '}
61
- {item.stackQty}{' '}
62
- </ItemQty>
63
- ) : null}
137
+ {onRenderSlot(item)}
64
138
  </Container>
65
139
  );
66
140
  };
67
141
 
68
142
  const Container = styled.div`
69
143
  margin: 0.1rem;
70
- // border: 1px red solid;
71
-
72
144
  .sprite-from-atlas-img {
73
145
  position: relative;
74
146
  top: 1.5rem;
75
147
  left: 1.5rem;
76
-
77
- &:hover {
78
- filter: sepia(100%) saturate(300%) brightness(70%) hue-rotate(180deg);
79
- }
80
148
  }
81
149
  `;
82
150
 
@@ -1,21 +1,32 @@
1
- import { ActionsByItemType, ItemType } from '@rpg-engine/shared';
1
+ import {
2
+ ActionsByItemType,
3
+ ItemSocketEventsDisplayLabels,
4
+ ItemType,
5
+ } from '@rpg-engine/shared';
2
6
 
3
- interface IContextMenuItem {
7
+ export interface IContextMenuItem {
4
8
  id: string;
5
9
  text: string;
6
10
  }
7
11
 
8
- export const handleContextMenuList = (itemType: ItemType) => {
9
- const generateContextList = (actionsByTypeList: any) => {
10
- const contextMenu: IContextMenuItem[] = actionsByTypeList.map(
11
- (action: string) => {
12
- return { id: action, text: action };
13
- }
14
- );
15
- return contextMenu;
16
- };
12
+ export enum ContainerType {
13
+ INVENTORY = 'Inventory',
14
+ EQUIPMENT_SET = 'EquipmentSet',
15
+ }
16
+
17
+ // TODO: Refactor this file
18
+ const generateContextList = (actionsByTypeList: any) => {
19
+ const contextMenu: IContextMenuItem[] = actionsByTypeList.map(
20
+ (action: string) => {
21
+ return { id: action, text: ItemSocketEventsDisplayLabels[action] };
22
+ }
23
+ );
24
+ return contextMenu;
25
+ };
17
26
 
27
+ export const handleContextMenuList = (itemType: ItemType) => {
18
28
  let contextActionMenu: IContextMenuItem[] = [];
29
+
19
30
  switch (itemType) {
20
31
  case ItemType.Weapon:
21
32
  case ItemType.Armor:
@@ -42,3 +53,29 @@ export const handleContextMenuList = (itemType: ItemType) => {
42
53
  }
43
54
  return contextActionMenu;
44
55
  };
56
+
57
+ export const handleEquipmentContextMenuList = (itemType: ItemType) => {
58
+ let contextActionMenu: IContextMenuItem[] = [];
59
+ switch (itemType) {
60
+ case ItemType.Weapon:
61
+ case ItemType.Armor:
62
+ case ItemType.Accessory:
63
+ case ItemType.Jewelry:
64
+ case ItemType.Tool:
65
+ contextActionMenu = generateContextList(
66
+ ActionsByItemType.EquipmenSetItems
67
+ );
68
+ break;
69
+ case ItemType.Container:
70
+ contextActionMenu = generateContextList(
71
+ ActionsByItemType.EquipmenSetContainer
72
+ );
73
+ break;
74
+ default:
75
+ contextActionMenu = generateContextList(
76
+ ActionsByItemType.EquipmenSetItems
77
+ );
78
+ break;
79
+ }
80
+ return contextActionMenu;
81
+ };
@@ -29,7 +29,7 @@ export const SpriteFromAtlas: React.FC<IProps> = ({
29
29
  const spriteData = atlasJSON.frames[spriteKey];
30
30
 
31
31
  return (
32
- <Container width={width} height={height}>
32
+ <Container width={width} height={height} hasHover={grayScale}>
33
33
  <ImgSprite
34
34
  className="sprite-from-atlas-img"
35
35
  atlasIMG={atlasIMG}
@@ -58,11 +58,18 @@ interface IImgSpriteProps {
58
58
  interface IContainerProps {
59
59
  width: number;
60
60
  height: number;
61
+ hasHover: boolean;
61
62
  }
62
63
 
63
64
  const Container = styled.div`
64
65
  width: ${(props: IContainerProps) => props.width}px;
65
66
  height: ${(props: IContainerProps) => props.height}px;
67
+ ${(props: IContainerProps) =>
68
+ !props.hasHover
69
+ ? `&:hover {
70
+ filter: sepia(100%) saturate(300%) brightness(70%) hue-rotate(180deg);
71
+ }`
72
+ : ``}
66
73
  `;
67
74
 
68
75
  const ImgSprite = styled.div<IImgSpriteProps>`
@@ -26,12 +26,12 @@ export const ListMenu: React.FC<IListMenuProps> = ({
26
26
  <ul className="rpgui-list-imp" style={{ overflow: 'hidden' }}>
27
27
  {options.map(params => (
28
28
  <ListElement
29
- key={params.text}
29
+ key={params?.id}
30
30
  onClick={() => {
31
- onSelected(params.id);
31
+ onSelected(params?.id);
32
32
  }}
33
33
  >
34
- {params.text}
34
+ {params?.text || 'No text'}
35
35
  </ListElement>
36
36
  ))}
37
37
  </ul>
@@ -0,0 +1,192 @@
1
+ import {
2
+ IItem,
3
+ IPayloadProps,
4
+ ItemSocketEvents,
5
+ ItemSocketEventsDisplayLabels,
6
+ ItemType,
7
+ } from '@rpg-engine/shared';
8
+ import { makeAutoObservable, toJS } from 'mobx';
9
+ import {
10
+ handleContextMenuList,
11
+ handleEquipmentContextMenuList,
12
+ IContextMenuItem,
13
+ } from '../Item/Inventory/itemContainerHelper';
14
+ import { SlotContainerType } from '../Item/Inventory/ItemSlot';
15
+
16
+ interface IContextMenu {
17
+ visible: boolean;
18
+ posX: number;
19
+ posY: number;
20
+ slotItem: IItem | null;
21
+ slotIndex?: number | null;
22
+ contextActions: IContextMenuItem[];
23
+ }
24
+
25
+ interface IHoverDetail {
26
+ visible: boolean;
27
+ posX: number;
28
+ posY: number;
29
+ item: IItem | null;
30
+ }
31
+
32
+ interface ISetContextMenu extends Omit<IContextMenu, 'contextActions'> {}
33
+
34
+ const initialState = {
35
+ visible: false,
36
+ posX: 0,
37
+ posY: 0,
38
+ contextActions: [],
39
+ slotItem: null,
40
+ };
41
+
42
+ const initialHoverState = {
43
+ visible: false,
44
+ posX: 0,
45
+ posY: 0,
46
+ item: null,
47
+ };
48
+ class UIStore {
49
+ public contextMenu: IContextMenu | null = initialState;
50
+
51
+ public onHoverDetail: IHoverDetail | null = initialHoverState;
52
+
53
+ constructor() {
54
+ makeAutoObservable(this);
55
+ }
56
+
57
+ public setContextMenu(contextMenu: ISetContextMenu, itemType: ItemType) {
58
+ const contextActions = handleContextMenuList(itemType);
59
+
60
+ this.contextMenu = {
61
+ ...contextMenu,
62
+ contextActions,
63
+ };
64
+
65
+ console.log(toJS(this.contextMenu));
66
+ }
67
+
68
+ public setEquipContextMenu(
69
+ contextMenu: ISetContextMenu,
70
+ itemType: ItemType,
71
+ isItemContainer: boolean | undefined
72
+ ) {
73
+ const contextActions = handleEquipmentContextMenuList(itemType);
74
+ if (isItemContainer)
75
+ contextActions.push({
76
+ id: ItemSocketEvents.ContainerOpen,
77
+ text: ItemSocketEventsDisplayLabels[ItemSocketEvents.ContainerOpen],
78
+ });
79
+ this.contextMenu = {
80
+ ...contextMenu,
81
+ contextActions,
82
+ };
83
+
84
+ console.log(toJS(this.contextMenu));
85
+ }
86
+
87
+ public clearContextMenu() {
88
+ this.contextMenu = initialState;
89
+ }
90
+
91
+ public setItemHoverDetail(hoverDetail: IHoverDetail) {
92
+ if (hoverDetail?.item === null) this.clearItemHoverDetail();
93
+
94
+ this.onHoverDetail = {
95
+ ...hoverDetail,
96
+ };
97
+ }
98
+
99
+ public clearItemHoverDetail() {
100
+ this.onHoverDetail = initialHoverState;
101
+ }
102
+
103
+ public handleOnItemClick = (
104
+ item: IItem,
105
+ posX: number,
106
+ posY: number,
107
+ slotContainerType: SlotContainerType | null
108
+ ): void => {
109
+ if (
110
+ !item ||
111
+ JSON.stringify(this.contextMenu?.slotItem) === JSON.stringify(item)
112
+ ) {
113
+ this.clearContextMenu();
114
+ this.clearItemHoverDetail();
115
+ return;
116
+ }
117
+ switch (slotContainerType) {
118
+ case SlotContainerType.EQUIPMENT_SET:
119
+ this.setEquipContextMenu(
120
+ {
121
+ visible: true,
122
+ posX,
123
+ posY,
124
+ slotItem: item,
125
+ },
126
+ item.type,
127
+ item.isItemContainer
128
+ );
129
+ break;
130
+ case SlotContainerType.INVENTORY:
131
+ this.setContextMenu(
132
+ {
133
+ visible: true,
134
+ posX,
135
+ posY,
136
+ slotItem: item,
137
+ },
138
+ item.type
139
+ );
140
+ break;
141
+ default:
142
+ this.setContextMenu(
143
+ {
144
+ visible: true,
145
+ posX,
146
+ posY,
147
+ slotItem: item,
148
+ },
149
+ item.type
150
+ );
151
+ }
152
+
153
+ this.clearItemHoverDetail();
154
+ };
155
+
156
+ public handleOnMouseHover = (
157
+ event: any,
158
+ slotIndex: number,
159
+ item: IItem | null,
160
+ posX: number,
161
+ posY: number,
162
+ onMouseOver: any
163
+ ): void => {
164
+ if (item) {
165
+ this.setItemHoverDetail({
166
+ visible: true,
167
+ posX,
168
+ posY,
169
+ item: item,
170
+ });
171
+ }
172
+ if (onMouseOver) {
173
+ onMouseOver(event, slotIndex, item);
174
+ }
175
+ };
176
+
177
+ public onSelected(
178
+ selectedActionId: ItemSocketEvents | string,
179
+ onActionSelected: any
180
+ ) {
181
+ let payloadData: IPayloadProps = {
182
+ actionType: selectedActionId,
183
+ item: this.contextMenu?.slotItem!,
184
+ };
185
+ if (onActionSelected) {
186
+ onActionSelected(payloadData);
187
+ }
188
+ this.clearContextMenu!();
189
+ }
190
+ }
191
+
192
+ export const uiStore = new UIStore();
package/src/index.tsx CHANGED
@@ -19,4 +19,5 @@ export * from './components/SkillProgressBar';
19
19
  export * from './components/TextArea';
20
20
  export * from './components/Truncate';
21
21
  export * from './components/typography/DynamicText';
22
+ export * from './components/Equipment/EquipmentSet';
22
23
  export { useEventListener } from './hooks/useEventListener';