Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
N
Neos
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
love_飞影
Neos
Commits
b2ac11db
Commit
b2ac11db
authored
Jun 21, 2023
by
timel
Committed by
Chunchi Che
Jun 22, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: card list modal
parent
e1115001
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
150 additions
and
164 deletions
+150
-164
src/service/duel/move.ts
src/service/duel/move.ts
+8
-10
src/service/utils/fetchCheckCardMeta.ts
src/service/utils/fetchCheckCardMeta.ts
+2
-2
src/stores/cardStore.ts
src/stores/cardStore.ts
+7
-7
src/ui/Duel/Message/CardListModal.tsx
src/ui/Duel/Message/CardListModal.tsx
+62
-43
src/ui/Duel/Message/CardModal/index.tsx
src/ui/Duel/Message/CardModal/index.tsx
+0
-8
src/ui/Duel/Message/EffectButton.tsx
src/ui/Duel/Message/EffectButton.tsx
+0
-64
src/ui/Duel/Message/OptionModal.tsx
src/ui/Duel/Message/OptionModal.tsx
+37
-1
src/ui/Duel/PlayMat/Card/index.tsx
src/ui/Duel/PlayMat/Card/index.tsx
+7
-16
src/ui/Duel/PlayMat/Mat/index.tsx
src/ui/Duel/PlayMat/Mat/index.tsx
+0
-1
src/ui/Duel/PlayMat/utils/cssConfig.ts
src/ui/Duel/PlayMat/utils/cssConfig.ts
+15
-7
src/ui/Shared/YgoCard/index.scss
src/ui/Shared/YgoCard/index.scss
+3
-0
src/ui/Shared/YgoCard/index.tsx
src/ui/Shared/YgoCard/index.tsx
+9
-5
No files found.
src/service/duel/move.ts
View file @
b2ac11db
...
...
@@ -47,16 +47,14 @@ export default async (move: MsgMove) => {
}
}
// log出来看看,后期删掉即可
await
(
async
()
=>
{
console
.
color
(
"
green
"
)(
`
${
meta
.
text
.
name
}
${
ygopro
.
CardZone
[
from
.
zone
]}
:
${
from
.
sequence
}
:
${
from
.
is_overlay
?
from
.
overlay_sequence
:
""
}
→
${
ygopro
.
CardZone
[
to
.
zone
]}
:
${
to
.
sequence
}
:
${
to
.
is_overlay
?
to
.
overlay_sequence
:
""
}
`
);
})();
// log出来看看
console
.
color
(
"
green
"
)(
`
${
meta
.
text
.
name
}
${
ygopro
.
CardZone
[
from
.
zone
]}
:
${
from
.
sequence
}${
from
.
is_overlay
?
"
:
"
+
from
.
overlay_sequence
:
""
}
→
${
ygopro
.
CardZone
[
to
.
zone
]}
:
${
to
.
sequence
}${
to
.
is_overlay
?
"
:
"
+
to
.
overlay_sequence
:
""
}
`
);
let
target
:
CardType
;
...
...
src/service/utils/fetchCheckCardMeta.ts
View file @
b2ac11db
...
...
@@ -35,9 +35,9 @@ const helper = async (
const
effectDesc
=
effectDescCode
?
getCardStr
(
meta
,
effectDescCode
&
0xf
)
:
undefined
;
const
newOption
=
{
const
newOption
:
Option
=
{
meta
,
location
:
location
.
toObject
()
,
location
,
level1
,
level2
,
effectDesc
,
...
...
src/stores/cardStore.ts
View file @
b2ac11db
...
...
@@ -49,8 +49,8 @@ class CardStore {
card
.
location
.
zone
===
zone
&&
card
.
location
.
controller
===
controller
&&
card
.
location
.
sequence
===
sequence
&&
card
.
location
.
is_overlay
==
true
&&
card
.
location
.
overlay_sequence
==
overlay_sequence
card
.
location
.
is_overlay
==
=
true
&&
card
.
location
.
overlay_sequence
==
=
overlay_sequence
)
.
at
(
0
);
}
else
{
...
...
@@ -60,7 +60,7 @@ class CardStore {
card
.
location
.
zone
===
zone
&&
card
.
location
.
controller
===
controller
&&
card
.
location
.
sequence
===
sequence
&&
card
.
location
.
is_overlay
==
false
card
.
location
.
is_overlay
==
=
false
)
.
at
(
0
);
}
...
...
@@ -69,7 +69,7 @@ class CardStore {
(
card
)
=>
card
.
location
.
zone
===
zone
&&
card
.
location
.
controller
===
controller
&&
card
.
location
.
is_overlay
==
false
card
.
location
.
is_overlay
==
=
false
);
}
}
...
...
@@ -84,9 +84,9 @@ class CardStore {
):
CardType
[]
{
return
this
.
inner
.
filter
(
(
card
)
=>
card
.
location
.
zone
==
zone
&&
card
.
location
.
controller
==
controller
&&
card
.
location
.
sequence
==
sequence
&&
card
.
location
.
zone
==
=
zone
&&
card
.
location
.
controller
==
=
controller
&&
card
.
location
.
sequence
==
=
sequence
&&
card
.
location
.
is_overlay
);
}
...
...
src/ui/Duel/Message/CardListModal.tsx
View file @
b2ac11db
import
{
Drawer
,
List
}
from
"
antd
"
;
import
{
Drawer
,
Space
}
from
"
antd
"
;
import
React
from
"
react
"
;
import
{
useSnapshot
}
from
"
valtio
"
;
import
{
proxy
,
useSnapshot
}
from
"
valtio
"
;
import
{
useConfig
}
from
"
@/config
"
;
import
{
messageStore
}
from
"
@/stores
"
;
import
{
EffectButton
}
from
"
./EffectButton
"
;
import
{
CardType
,
messageStore
,
cardStore
}
from
"
@/stores
"
;
import
{
showCardModal
}
from
"
./CardModal
"
;
import
{
ygopro
}
from
"
@/api
"
;
import
{
YgoCard
}
from
"
@/ui/Shared
"
;
const
NeosConfig
=
useConfig
();
...
...
@@ -15,50 +15,69 @@ const CARD_WIDTH = 100;
const
{
cardListModal
}
=
messageStore
;
// TODO: 显示的位置还需要细细斟酌
const
defaultStore
=
{
zone
:
ygopro
.
CardZone
.
HAND
,
controller
:
0
,
monster
:
{}
as
CardType
,
isOpen
:
false
,
isZone
:
true
,
};
const
store
=
proxy
(
defaultStore
);
export
const
CardListModal
=
()
=>
{
const
snap
=
useSnapshot
(
cardListModal
);
const
isOpen
=
snap
.
isOpen
;
const
list
=
snap
.
list
as
typeof
cardListModal
.
list
;
const
{
zone
,
monster
,
isOpen
,
isZone
,
controller
}
=
useSnapshot
(
store
);
let
cardList
:
CardType
[]
=
[];
if
(
isZone
)
{
cardList
=
cardStore
.
at
(
zone
,
controller
);
console
.
log
({
cardList
});
}
else
{
// 看超量素材
cardList
=
cardStore
.
findOverlay
(
monster
.
location
.
zone
,
monster
.
location
.
controller
,
monster
.
location
.
sequence
);
}
const
handleOkOrCancel
=
()
=>
{
cardListModal
.
isOpen
=
false
;
store
.
isOpen
=
false
;
};
return
(
<
Drawer
open=
{
isOpen
}
onClose=
{
handleOkOrCancel
}
>
<
List
itemLayout=
"horizontal"
dataSource=
{
list
}
renderItem=
{
(
item
)
=>
(
<
List
.
Item
actions=
{
[
<
EffectButton
effectInteractivies=
{
item
.
interactivies
}
meta=
{
item
.
meta
}
/>,
]
}
extra=
{
<
img
alt=
{
item
.
meta
?.
text
.
name
}
src=
{
item
.
meta
?.
id
?
`${NeosConfig.cardImgUrl}/${item.meta.id}.jpg`
:
`${NeosConfig.assetsPath}/card_back.jpg`
}
style=
{
{
width
:
CARD_WIDTH
}
}
/>
}
onClick=
{
()
=>
{
showCardModal
(
item
);
}
}
>
<
List
.
Item
.
Meta
title=
{
item
.
meta
?.
text
.
name
}
description=
{
item
.
meta
?.
text
.
desc
}
/>
</
List
.
Item
>
)
}
></
List
>
<
Drawer
open=
{
isOpen
}
onClose=
{
handleOkOrCancel
}
headerStyle=
{
{
display
:
"
none
"
}
}
width=
{
CARD_WIDTH
+
66
}
style=
{
{
maxHeight
:
"
100%
"
}
}
>
<
Space
direction=
"vertical"
>
{
cardList
.
map
((
card
)
=>
(
<
YgoCard
code=
{
card
.
code
}
key=
{
card
.
uuid
}
width=
{
CARD_WIDTH
}
onClick=
{
()
=>
showCardModal
(
card
)
}
/>
))
}
</
Space
>
</
Drawer
>
);
};
export
const
displayCardListModal
=
({
isZone
,
monster
,
zone
,
controller
,
}:
Partial
<
Omit
<
typeof
defaultStore
,
"
isOpen
"
>>
)
=>
{
store
.
isOpen
=
true
;
isZone
&&
(
store
.
isZone
=
isZone
);
monster
&&
(
store
.
monster
=
monster
);
zone
&&
(
store
.
zone
=
zone
);
controller
&&
(
store
.
controller
=
controller
);
};
src/ui/Duel/Message/CardModal/index.tsx
View file @
b2ac11db
...
...
@@ -14,7 +14,6 @@ import {
Race2StringCodeMap
,
Type2StringCodeMap
,
}
from
"
../../../../common
"
;
import
{
EffectButton
}
from
"
../EffectButton
"
;
import
{
Drawer
,
Space
,
Tag
,
Divider
,
Timeline
,
Typography
}
from
"
antd
"
;
import
{
LeftOutlined
}
from
"
@ant-design/icons
"
;
...
...
@@ -61,13 +60,6 @@ export const CardModal = () => {
const
atk
=
meta
?.
data
.
atk
;
const
def
=
meta
?.
data
.
def
;
const
nonEffectInteractivies
=
snap
.
interactivies
.
filter
(
(
item
)
=>
item
.
desc
!=
"
发动效果
"
);
const
effectInteractivies
=
snap
.
interactivies
.
filter
(
(
item
)
=>
item
.
desc
==
"
发动效果
"
);
return
(
// TODO: 宽度要好好设置 根据屏幕宽度
<
Drawer
...
...
src/ui/Duel/Message/EffectButton.tsx
deleted
100644 → 0
View file @
e1115001
import
"
@/styles/card-modal.scss
"
;
import
React
from
"
react
"
;
import
{
CardMeta
,
getCardStr
,
sendSelectIdleCmdResponse
}
from
"
@/api
"
;
import
{
cardStore
,
messageStore
}
from
"
@/stores
"
;
const
{
cardModal
}
=
messageStore
;
export
const
EffectButton
=
(
props
:
{
meta
?:
CardMeta
;
effectInteractivies
:
{
desc
:
string
;
response
:
number
;
effectCode
?:
number
;
}[];
})
=>
(
<>
{
props
.
effectInteractivies
.
length
>
0
?
(
props
.
effectInteractivies
.
length
==
1
?
(
// 如果只有一个效果,点击直接触发
<
button
className=
"card-modal-btn"
onClick=
{
()
=>
{
sendSelectIdleCmdResponse
(
props
.
effectInteractivies
[
0
].
response
);
cardModal
.
isOpen
=
false
;
// 清空互动性
for
(
const
card
of
cardStore
.
inner
)
{
card
.
idleInteractivities
=
[];
}
}
}
>
{
props
.
effectInteractivies
[
0
].
desc
}
</
button
>
)
:
(
// 如果有多个效果,点击后进入`OptionModal`选择
<
button
className=
"card-modal-btn"
onClick=
{
()
=>
{
for
(
const
effect
of
props
.
effectInteractivies
)
{
const
effectMsg
=
props
.
meta
&&
effect
.
effectCode
?
getCardStr
(
props
.
meta
,
effect
.
effectCode
&
0xf
)
??
"
[:?]
"
:
"
[:?]
"
;
messageStore
.
optionModal
.
options
.
push
({
msg
:
effectMsg
,
response
:
effect
.
response
,
});
}
cardModal
.
isOpen
=
false
;
// 清空互动性
for
(
const
card
of
cardStore
.
inner
)
{
card
.
idleInteractivities
=
[];
}
messageStore
.
optionModal
.
isOpen
=
true
;
}
}
>
发动效果
</
button
>
)
)
:
(
<></>
)
}
</>
);
src/ui/Duel/Message/OptionModal.tsx
View file @
b2ac11db
...
...
@@ -3,7 +3,13 @@ import { Button } from "antd";
import
React
,
{
useState
}
from
"
react
"
;
import
{
useSnapshot
,
proxy
}
from
"
valtio
"
;
import
{
sendSelectOptionResponse
}
from
"
@/api
"
;
import
{
type
CardMeta
,
sendSelectOptionResponse
,
ygopro
,
sendSelectIdleCmdResponse
,
getCardStr
,
}
from
"
@/api
"
;
import
{
NeosModal
}
from
"
./NeosModal
"
;
type
Options
=
{
msg
:
string
;
response
:
number
}[];
...
...
@@ -54,3 +60,33 @@ export const displayOptionModal = async (options: Options) => {
await
new
Promise
((
resolve
)
=>
(
rs
=
resolve
));
store
.
isOpen
=
false
;
};
export
const
handleEffectActivation
=
async
(
meta
:
CardMeta
,
effectInteractivies
:
{
desc
:
string
;
response
:
number
;
effectCode
:
number
|
undefined
;
}[]
)
=>
{
if
(
!
effectInteractivies
.
length
)
{
return
;
}
if
(
effectInteractivies
.
length
===
1
)
{
// 如果只有一个效果,点击直接触发
sendSelectIdleCmdResponse
(
effectInteractivies
[
0
].
response
);
}
else
{
// optionsModal
const
options
=
effectInteractivies
.
map
((
effect
)
=>
{
const
effectMsg
=
meta
&&
effect
.
effectCode
?
getCardStr
(
meta
,
effect
.
effectCode
&
0xf
)
??
"
[:?]
"
:
"
[:?]
"
;
return
{
msg
:
effectMsg
,
response
:
effect
.
response
,
};
});
await
displayOptionModal
(
options
);
// 主动发动效果,所以不需要await,但是以后可能要留心
}
};
src/ui/Duel/PlayMat/Card/index.tsx
View file @
b2ac11db
...
...
@@ -31,7 +31,7 @@ import {
UpOutlined
,
}
from
"
@ant-design/icons
"
;
import
{
fetchStrings
,
sendSelectIdleCmdResponse
,
type
CardMeta
}
from
"
@/api
"
;
import
{
displayOptionModal
}
from
"
../../Message
"
;
import
{
display
CardListModal
,
display
OptionModal
}
from
"
../../Message
"
;
const
NeosConfig
=
useConfig
();
const
{
HAND
,
GRAVE
,
REMOVED
,
DECK
,
EXTRA
,
MZONE
,
SZONE
,
TZONE
}
=
...
...
@@ -233,6 +233,7 @@ export const Card: FC<{ idx: number }> = React.memo(({ idx }) => {
overlayClassName=
"card-dropdown"
arrow
trigger=
{
[
"
click
"
]
}
// TODO: 没有交互效果、或者不能点击的卡,不应该显示下拉菜单
>
<
div
className=
{
classnames
(
"
card-img-wrap
"
,
{
focus
:
classFocus
})
}
>
<
YgoCard
...
...
@@ -274,20 +275,10 @@ const onCardClick = (card: CardType) => {
};
const
onFieldClick
=
(
card
:
CardType
)
=>
{
const
displayStates
=
cardStore
.
at
(
card
.
location
.
zone
,
card
.
location
.
controller
);
messageStore
.
cardListModal
.
list
=
displayStates
.
map
((
item
)
=>
({
meta
:
{
id
:
item
.
code
,
text
:
item
.
meta
.
text
,
data
:
item
.
meta
.
data
,
},
interactivies
:
item
.
idleInteractivities
.
map
((
interactivy
)
=>
({
desc
:
interactTypeToString
(
interactivy
.
interactType
),
response
:
interactivy
.
response
,
})),
}));
messageStore
.
cardListModal
.
isOpen
=
true
;
displayCardListModal
({
isZone
:
true
,
zone
:
card
.
location
.
zone
,
controller
:
card
.
location
.
controller
,
});
};
src/ui/Duel/PlayMat/Mat/index.tsx
View file @
b2ac11db
...
...
@@ -17,7 +17,6 @@ export const Mat: FC = () => {
id=
"mat"
style=
{
{
width
:
"
100%
"
,
...
toCssProperties
(
matConfig
),
}
}
>
<
Plane
>
...
...
src/ui/Duel/PlayMat/utils/cssConfig.ts
View file @
b2ac11db
...
...
@@ -5,13 +5,17 @@ export type CSSConfig = Record<string, { value: number; unit: UNIT }>;
/** 转为CSS变量: BOARD_ROTATE_Z -> --board-rotate-z */
export
const
toCssProperties
=
(
config
:
CSSConfig
)
=>
Object
.
entries
(
config
)
.
map
(([
k
,
v
])
=>
({
[
`--
${
k
.
split
(
"
_
"
)
.
map
((
s
)
=>
s
.
toLowerCase
())
.
join
(
"
-
"
)}
`
]:
`
${
v
.
value
}${
v
.
unit
}
`
,
}))
.
reduce
((
acc
,
cur
)
=>
({
...
acc
,
...
cur
}),
{});
.
map
(
([
k
,
v
])
=>
[
`--
${
k
.
split
(
"
_
"
)
.
map
((
s
)
=>
s
.
toLowerCase
())
.
join
(
"
-
"
)}
`
,
`
${
v
.
value
}${
v
.
unit
}
`
,
]
as
[
string
,
string
]
)
.
reduce
((
acc
,
cur
)
=>
[...
acc
,
cur
],
[]
as
[
string
,
string
][]);
enum
UNIT
{
PX
=
"
px
"
,
...
...
@@ -81,3 +85,7 @@ export const matConfig = {
unit
:
UNIT
.
PX
,
},
};
toCssProperties
(
matConfig
).
forEach
(([
k
,
v
])
=>
{
document
.
body
.
style
.
setProperty
(
k
,
v
);
});
src/ui/Shared/YgoCard/index.scss
View file @
b2ac11db
.skeleton-cover
{
background-color
:
gray
;
}
.ygo-card
{
aspect-ratio
:
var
(
--
card-ratio
);
}
src/ui/Shared/YgoCard/index.tsx
View file @
b2ac11db
...
...
@@ -11,34 +11,38 @@ interface Props {
code
?:
number
;
style
?:
CSSProperties
;
width
?:
number
;
onClick
?:
()
=>
void
;
}
export
const
YgoCard
:
FC
<
Props
>
=
(
props
)
=>
{
const
{
className
,
code
:
cardCode
=
0
,
code
=
0
,
isBack
=
false
,
width
=
80
,
style
,
onClick
=
()
=>
{},
}
=
props
;
return
useMemo
(
()
=>
(
<>
{
c
ardC
ode
===
0
&&
!
isBack
?
(
{
code
===
0
&&
!
isBack
?
(
<
div
className=
{
classNames
(
"
ygo-card
"
,
"
skeleton-cover
"
)
}
className=
{
classNames
(
"
ygo-card
"
,
"
skeleton-cover
"
,
className
)
}
style=
{
{
width
,
...
style
}
}
onClick=
{
onClick
}
/>
)
:
(
<
img
className=
{
classNames
(
"
ygo-card
"
,
className
)
}
src=
{
getCardImgUrl
(
c
ardC
ode
,
isBack
)
}
src=
{
getCardImgUrl
(
code
,
isBack
)
}
style=
{
{
width
,
...
style
}
}
onClick=
{
onClick
}
/>
)
}
</>
),
[
c
ardC
ode
]
[
code
]
);
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment