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
983baaf5
Commit
983baaf5
authored
May 14, 2023
by
timel
Committed by
Chunchi Che
May 28, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: mat bg action
parent
4af2045b
Changes
18
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
237 additions
and
112 deletions
+237
-112
src/main.tsx
src/main.tsx
+5
-7
src/service/duel/selectBattleCmd.ts
src/service/duel/selectBattleCmd.ts
+9
-0
src/service/duel/selectIdleCmd.ts
src/service/duel/selectIdleCmd.ts
+9
-0
src/service/duel/selectPlace.ts
src/service/duel/selectPlace.ts
+17
-1
src/stores/cardStore.ts
src/stores/cardStore.ts
+1
-1
src/stores/index.tsx
src/stores/index.tsx
+3
-0
src/stores/placeStore.ts
src/stores/placeStore.ts
+50
-0
src/ui/Duel/NewPlayMat/Bg/index.scss
src/ui/Duel/NewPlayMat/Bg/index.scss
+7
-0
src/ui/Duel/NewPlayMat/Bg/index.tsx
src/ui/Duel/NewPlayMat/Bg/index.tsx
+46
-12
src/ui/Duel/NewPlayMat/Card/index.scss
src/ui/Duel/NewPlayMat/Card/index.scss
+14
-1
src/ui/Duel/NewPlayMat/Card/index.tsx
src/ui/Duel/NewPlayMat/Card/index.tsx
+27
-11
src/ui/Duel/NewPlayMat/Card/springs/index.ts
src/ui/Duel/NewPlayMat/Card/springs/index.ts
+1
-1
src/ui/Duel/NewPlayMat/Card/springs/toDeck.ts
src/ui/Duel/NewPlayMat/Card/springs/toDeck.ts
+3
-4
src/ui/Duel/NewPlayMat/Card/springs/toGround.ts
src/ui/Duel/NewPlayMat/Card/springs/toGround.ts
+16
-5
src/ui/Duel/NewPlayMat/Card/springs/toHand.ts
src/ui/Duel/NewPlayMat/Card/springs/toHand.ts
+3
-0
src/ui/Duel/NewPlayMat/Card/springs/toOutside.ts
src/ui/Duel/NewPlayMat/Card/springs/toOutside.ts
+3
-8
src/ui/Duel/NewPlayMat/Mat/index.scss
src/ui/Duel/NewPlayMat/Mat/index.scss
+2
-4
src/ui/Duel/NewPlayMat/Menu.tsx
src/ui/Duel/NewPlayMat/Menu.tsx
+21
-57
No files found.
src/main.tsx
View file @
983baaf5
...
@@ -35,11 +35,9 @@ const root = ReactDOM.createRoot(
...
@@ -35,11 +35,9 @@ const root = ReactDOM.createRoot(
document
.
getElementById
(
"
root
"
)
as
HTMLElement
document
.
getElementById
(
"
root
"
)
as
HTMLElement
);
);
root
.
render
(
root
.
render
(
<
React
.
StrictMode
>
<
BrowserRouter
>
<
BrowserRouter
>
<
ConfigProvider
theme=
{
{
algorithm
:
theme
.
darkAlgorithm
}
}
locale=
{
zhCN
}
>
<
ConfigProvider
theme=
{
{
algorithm
:
theme
.
darkAlgorithm
}
}
locale=
{
zhCN
}
>
<
Neos
/>
<
Neos
/>
</
ConfigProvider
>
</
ConfigProvider
>
</
BrowserRouter
>
</
BrowserRouter
>
</
React
.
StrictMode
>
);
);
src/service/duel/selectBattleCmd.ts
View file @
983baaf5
...
@@ -4,6 +4,7 @@ import {
...
@@ -4,6 +4,7 @@ import {
type
Interactivity
,
type
Interactivity
,
InteractType
,
InteractType
,
matStore
,
matStore
,
cardStore
,
}
from
"
@/stores
"
;
}
from
"
@/stores
"
;
import
MsgSelectBattleCmd
=
ygopro
.
StocGameMessage
.
MsgSelectBattleCmd
;
import
MsgSelectBattleCmd
=
ygopro
.
StocGameMessage
.
MsgSelectBattleCmd
;
...
@@ -14,6 +15,9 @@ export default (selectBattleCmd: MsgSelectBattleCmd) => {
...
@@ -14,6 +15,9 @@ export default (selectBattleCmd: MsgSelectBattleCmd) => {
// 先清掉之前的互动性
// 先清掉之前的互动性
clearAllIdleInteractivities
(
player
);
clearAllIdleInteractivities
(
player
);
cardStore
.
inner
.
forEach
((
card
)
=>
{
card
.
idleInteractivities
=
[];
});
cmds
.
forEach
((
cmd
)
=>
{
cmds
.
forEach
((
cmd
)
=>
{
const
interactType
=
battleTypeToInteracType
(
cmd
.
battle_type
);
const
interactType
=
battleTypeToInteracType
(
cmd
.
battle_type
);
...
@@ -38,6 +42,11 @@ export default (selectBattleCmd: MsgSelectBattleCmd) => {
...
@@ -38,6 +42,11 @@ export default (selectBattleCmd: MsgSelectBattleCmd) => {
interactType
,
interactType
,
response
:
data
.
response
,
response
:
data
.
response
,
});
});
cardStore
.
at
(
location
,
player
)[
sequence
].
idleInteractivities
.
push
({
...
tmp
,
interactType
,
response
:
data
.
response
,
});
}
else
{
}
else
{
console
.
warn
(
`Undefined InteractType`
);
console
.
warn
(
`Undefined InteractType`
);
}
}
...
...
src/service/duel/selectIdleCmd.ts
View file @
983baaf5
...
@@ -4,6 +4,7 @@ import {
...
@@ -4,6 +4,7 @@ import {
type
Interactivity
,
type
Interactivity
,
InteractType
,
InteractType
,
matStore
,
matStore
,
cardStore
,
}
from
"
@/stores
"
;
}
from
"
@/stores
"
;
import
MsgSelectIdleCmd
=
ygopro
.
StocGameMessage
.
MsgSelectIdleCmd
;
import
MsgSelectIdleCmd
=
ygopro
.
StocGameMessage
.
MsgSelectIdleCmd
;
...
@@ -14,6 +15,9 @@ export default (selectIdleCmd: MsgSelectIdleCmd) => {
...
@@ -14,6 +15,9 @@ export default (selectIdleCmd: MsgSelectIdleCmd) => {
// 先清掉之前的互动性
// 先清掉之前的互动性
clearAllIdleInteractivities
(
player
);
clearAllIdleInteractivities
(
player
);
cardStore
.
inner
.
forEach
((
card
)
=>
{
card
.
idleInteractivities
=
[];
});
cmds
.
forEach
((
cmd
)
=>
{
cmds
.
forEach
((
cmd
)
=>
{
const
interactType
=
idleTypeToInteractType
(
cmd
.
idle_type
);
const
interactType
=
idleTypeToInteractType
(
cmd
.
idle_type
);
...
@@ -37,6 +41,11 @@ export default (selectIdleCmd: MsgSelectIdleCmd) => {
...
@@ -37,6 +41,11 @@ export default (selectIdleCmd: MsgSelectIdleCmd) => {
interactType
,
interactType
,
response
:
data
.
response
,
response
:
data
.
response
,
});
});
cardStore
.
at
(
location
,
player
)[
sequence
].
idleInteractivities
.
push
({
...
tmp
,
interactType
,
response
:
data
.
response
,
});
}
else
{
}
else
{
console
.
warn
(
`Undefined InteractType`
);
console
.
warn
(
`Undefined InteractType`
);
}
}
...
...
src/service/duel/selectPlace.ts
View file @
983baaf5
import
{
ygopro
}
from
"
@/api
"
;
import
{
ygopro
}
from
"
@/api
"
;
import
{
InteractType
,
matStore
}
from
"
@/stores
"
;
import
{
InteractType
,
matStore
,
placeStore
}
from
"
@/stores
"
;
type
MsgSelectPlace
=
ygopro
.
StocGameMessage
.
MsgSelectPlace
;
type
MsgSelectPlace
=
ygopro
.
StocGameMessage
.
MsgSelectPlace
;
...
@@ -9,6 +9,22 @@ export default (selectPlace: MsgSelectPlace) => {
...
@@ -9,6 +9,22 @@ export default (selectPlace: MsgSelectPlace) => {
return
;
return
;
}
}
for
(
const
place
of
selectPlace
.
places
)
{
switch
(
place
.
zone
)
{
case
ygopro
.
CardZone
.
MZONE
:
case
ygopro
.
CardZone
.
SZONE
:
placeStore
.
set
(
place
.
zone
,
place
.
controler
,
place
.
sequence
,
{
interactType
:
InteractType
.
PLACE_SELECTABLE
,
response
:
{
controler
:
place
.
controler
,
zone
:
place
.
zone
,
sequence
:
place
.
sequence
,
},
});
break
;
}
}
for
(
const
place
of
selectPlace
.
places
)
{
for
(
const
place
of
selectPlace
.
places
)
{
switch
(
place
.
zone
)
{
switch
(
place
.
zone
)
{
case
ygopro
.
CardZone
.
MZONE
:
{
case
ygopro
.
CardZone
.
MZONE
:
{
...
...
src/stores/cardStore.ts
View file @
983baaf5
import
{
CardData
,
CardText
,
fetchCard
,
ygopro
}
from
"
@/api
"
;
import
{
CardData
,
CardText
,
fetchCard
,
ygopro
}
from
"
@/api
"
;
import
{
proxy
}
from
"
valtio
"
;
import
{
proxy
}
from
"
valtio
"
;
import
{
Interactivity
}
from
"
./matStore/types
"
;
import
type
{
Interactivity
}
from
"
./matStore/types
"
;
/**
/**
* 场上某位置的状态,
* 场上某位置的状态,
...
...
src/stores/index.tsx
View file @
983baaf5
...
@@ -5,6 +5,7 @@ export * from "./messageStore";
...
@@ -5,6 +5,7 @@ export * from "./messageStore";
export
*
from
"
./moraStore
"
;
export
*
from
"
./moraStore
"
;
export
*
from
"
./playerStore
"
;
export
*
from
"
./playerStore
"
;
export
*
from
"
./cardStore
"
;
export
*
from
"
./cardStore
"
;
export
*
from
"
./placeStore
"
;
import
{
proxy
}
from
"
valtio
"
;
import
{
proxy
}
from
"
valtio
"
;
import
{
devtools
}
from
"
valtio/utils
"
;
import
{
devtools
}
from
"
valtio/utils
"
;
...
@@ -16,6 +17,7 @@ import { messageStore } from "./messageStore";
...
@@ -16,6 +17,7 @@ import { messageStore } from "./messageStore";
import
{
moraStore
}
from
"
./moraStore
"
;
import
{
moraStore
}
from
"
./moraStore
"
;
import
{
playerStore
}
from
"
./playerStore
"
;
import
{
playerStore
}
from
"
./playerStore
"
;
import
{
cardStore
}
from
"
./cardStore
"
;
import
{
cardStore
}
from
"
./cardStore
"
;
import
{
placeStore
}
from
"
./placeStore
"
;
export
const
store
=
proxy
({
export
const
store
=
proxy
({
playerStore
,
playerStore
,
...
@@ -25,6 +27,7 @@ export const store = proxy({
...
@@ -25,6 +27,7 @@ export const store = proxy({
matStore
,
// 决斗盘
matStore
,
// 决斗盘
messageStore
,
// 决斗的信息,包括模态框
messageStore
,
// 决斗的信息,包括模态框
cardStore
,
cardStore
,
placeStore
,
});
});
devtools
(
store
,
{
name
:
"
valtio store
"
,
enabled
:
true
});
devtools
(
store
,
{
name
:
"
valtio store
"
,
enabled
:
true
});
src/stores/placeStore.ts
0 → 100644
View file @
983baaf5
import
{
ygopro
}
from
"
@/api
"
;
import
{
proxy
}
from
"
valtio
"
;
import
type
{
Interactivity
}
from
"
./matStore/types
"
;
import
{
matStore
}
from
"
@/stores
"
;
export
type
PlaceInteractivity
=
|
Interactivity
<
{
controler
:
number
;
zone
:
ygopro
.
CardZone
;
sequence
:
number
;
}
>
|
undefined
;
const
{
MZONE
,
SZONE
}
=
ygopro
.
CardZone
;
export
const
placeStore
=
proxy
({
inner
:
{
[
MZONE
]:
{
me
:
Array
.
from
({
length
:
7
}).
map
(()
=>
undefined
as
PlaceInteractivity
),
op
:
Array
.
from
({
length
:
7
}).
map
(()
=>
undefined
as
PlaceInteractivity
),
},
[
SZONE
]:
{
me
:
Array
.
from
({
length
:
6
}).
map
(()
=>
undefined
as
PlaceInteractivity
),
op
:
Array
.
from
({
length
:
6
}).
map
(()
=>
undefined
as
PlaceInteractivity
),
},
},
set
(
zone
:
ygopro
.
CardZone
.
MZONE
|
ygopro
.
CardZone
.
SZONE
,
controller
:
number
,
sequence
:
number
,
placeInteractivity
:
PlaceInteractivity
)
{
placeStore
.
inner
[
zone
][
matStore
.
isMe
(
controller
)
?
"
me
"
:
"
op
"
][
sequence
]
=
placeInteractivity
;
},
clearAll
()
{
placeStore
.
inner
[
MZONE
].
me
=
placeStore
.
inner
[
MZONE
].
me
.
map
(
()
=>
undefined
);
placeStore
.
inner
[
MZONE
].
op
=
placeStore
.
inner
[
MZONE
].
op
.
map
(
()
=>
undefined
);
placeStore
.
inner
[
SZONE
].
me
=
placeStore
.
inner
[
SZONE
].
me
.
map
(
()
=>
undefined
);
placeStore
.
inner
[
SZONE
].
op
=
placeStore
.
inner
[
SZONE
].
op
.
map
(
()
=>
undefined
);
},
});
src/ui/Duel/NewPlayMat/Bg/index.scss
View file @
983baaf5
...
@@ -9,6 +9,9 @@ section#mat {
...
@@ -9,6 +9,9 @@ section#mat {
.bg-row
{
.bg-row
{
display
:
flex
;
display
:
flex
;
column-gap
:
var
(
--
col-gap
);
column-gap
:
var
(
--
col-gap
);
&
.opponent
{
flex-direction
:
row-reverse
;
}
}
}
}
}
...
@@ -23,5 +26,9 @@ section#mat {
...
@@ -23,5 +26,9 @@ section#mat {
&
.szone
{
&
.szone
{
height
:
var
(
--
block-height-s
);
height
:
var
(
--
block-height-s
);
}
}
&
.highlight
{
box-shadow
:
0
0
0
1px
#00b0ff
,
0
0
13px
0px
#0077ff
,
0
0
11px
0
skyblue
inset
;
}
}
}
}
}
src/ui/Duel/NewPlayMat/Bg/index.tsx
View file @
983baaf5
import
{
type
FC
}
from
"
react
"
;
import
{
type
FC
}
from
"
react
"
;
import
classnames
from
"
classnames
"
;
import
classnames
from
"
classnames
"
;
import
"
./index.scss
"
;
import
"
./index.scss
"
;
import
{
placeStore
,
type
PlaceInteractivity
,
messageStore
,
CardType
,
cardStore
,
}
from
"
@/stores
"
;
import
{
useSnapshot
,
type
INTERNAL_Snapshot
as
Snapshot
}
from
"
valtio
"
;
import
{
sendSelectPlaceResponse
,
ygopro
}
from
"
@/api
"
;
import
{
interactTypeToString
}
from
"
../../utils
"
;
const
BgRow
:
FC
<
{
isExtra
?:
boolean
;
isSzone
?:
boolean
}
>
=
({
const
BgExtraRow
:
FC
=
()
=>
{
isExtra
=
false
,
return
(
isSzone
=
false
,
})
=>
(
<
div
className=
{
classnames
(
"
bg-row
"
)
}
>
<
div
className=
{
classnames
(
"
bg-row
"
)
}
>
{
Array
.
from
({
length
:
isExtra
?
2
:
5
}).
map
((
_
,
i
)
=>
(
{
Array
.
from
({
length
:
2
}).
map
((
_
,
i
)
=>
(
<
div
key=
{
i
}
className=
{
classnames
(
"
block
"
,
"
extra
"
)
}
></
div
>
))
}
</
div
>
);
};
const
BgRow
:
FC
<
{
isSzone
?:
boolean
;
opponent
?:
boolean
;
snap
:
Snapshot
<
PlaceInteractivity
[]
>
;
}
>
=
({
isSzone
=
false
,
opponent
=
false
,
snap
})
=>
(
<
div
className=
{
classnames
(
"
bg-row
"
,
{
opponent
})
}
>
{
Array
.
from
({
length
:
5
}).
map
((
_
,
i
)
=>
(
<
div
<
div
key=
{
i
}
key=
{
i
}
className=
{
classnames
(
"
block
"
,
{
extra
:
isExtra
},
{
szone
:
isSzone
})
}
className=
{
classnames
(
"
block
"
,
{
szone
:
isSzone
,
highlight
:
!!
snap
[
i
],
})
}
onClick=
{
()
=>
onBlockClick
(
snap
[
i
])
}
></
div
>
></
div
>
))
}
))
}
</
div
>
</
div
>
);
);
export
const
Bg
:
FC
=
()
=>
{
export
const
Bg
:
FC
=
()
=>
{
const
snap
=
useSnapshot
(
placeStore
.
inner
);
return
(
return
(
<
div
className=
"mat-bg"
>
<
div
className=
"mat-bg"
>
<
BgRow
isSzone
/>
<
BgRow
snap=
{
snap
[
ygopro
.
CardZone
.
SZONE
].
op
}
isSzone
opponent
/>
<
BgRow
/>
<
BgRow
snap=
{
snap
[
ygopro
.
CardZone
.
MZONE
].
op
}
opponent
/>
<
Bg
Row
isExtra
/>
<
Bg
ExtraRow
/>
<
BgRow
/>
<
BgRow
snap=
{
snap
[
ygopro
.
CardZone
.
MZONE
].
me
}
/>
<
BgRow
isSzone
/>
<
BgRow
snap=
{
snap
[
ygopro
.
CardZone
.
SZONE
].
me
}
isSzone
/>
</
div
>
</
div
>
);
);
};
};
const
onBlockClick
=
(
placeInteractivity
:
PlaceInteractivity
)
=>
{
if
(
placeInteractivity
)
{
sendSelectPlaceResponse
(
placeInteractivity
.
response
);
cardStore
.
inner
.
forEach
((
card
)
=>
(
card
.
idleInteractivities
=
[]));
placeStore
.
clearAll
();
}
};
src/ui/Duel/NewPlayMat/Card/index.scss
View file @
983baaf5
...
@@ -12,7 +12,7 @@ section#mat {
...
@@ -12,7 +12,7 @@ section#mat {
position
:
relative
;
position
:
relative
;
height
:
100%
;
height
:
100%
;
width
:
100%
;
width
:
100%
;
transform
:
translateZ
(
calc
(
var
(
--
z
)
*
1px
))
transform
:
translateZ
(
calc
(
var
(
--
z
)
*
1px
+
0
.1px
))
rotateY
(
calc
(
var
(
--
ry
)
*
1deg
));
rotateY
(
calc
(
var
(
--
ry
)
*
1deg
));
.card-cover
,
.card-cover
,
.card-back
{
.card-back
{
...
@@ -31,5 +31,18 @@ section#mat {
...
@@ -31,5 +31,18 @@ section#mat {
transform
:
translateZ
(
0px
);
transform
:
translateZ
(
0px
);
}
}
}
}
.card-shadow
{
// position: absolute;
// left: 0;
// top: 0;
// width: 100%;
// height: 100%;
// background-color: #0000005e;
// filter: blur(2px);
}
}
}
}
.highlight
{
box-shadow
:
0
0
10px
2px
#5db7ff
;
}
}
src/ui/Duel/NewPlayMat/Card/index.tsx
View file @
983baaf5
import
React
,
{
useEffect
,
type
CSSProperties
,
type
FC
}
from
"
react
"
;
import
React
,
{
useEffect
,
type
CSSProperties
,
type
FC
,
useState
}
from
"
react
"
;
import
{
cardStore
,
messageStore
,
CardType
}
from
"
@/stores
"
;
import
{
cardStore
,
messageStore
,
CardType
}
from
"
@/stores
"
;
import
"
./index.scss
"
;
import
"
./index.scss
"
;
import
{
useSnapshot
}
from
"
valtio
"
;
import
{
useSnapshot
}
from
"
valtio
"
;
...
@@ -6,9 +6,10 @@ import { watch } from "valtio/utils";
...
@@ -6,9 +6,10 @@ import { watch } from "valtio/utils";
import
{
useSpring
,
animated
,
to
}
from
"
@react-spring/web
"
;
import
{
useSpring
,
animated
,
to
}
from
"
@react-spring/web
"
;
import
{
ygopro
}
from
"
@/api
"
;
import
{
ygopro
}
from
"
@/api
"
;
import
{
useConfig
}
from
"
@/config
"
;
import
{
useConfig
}
from
"
@/config
"
;
import
{
moveToDeck
,
moveTo
Fiel
d
,
moveToHand
,
moveToOutside
}
from
"
./springs
"
;
import
{
moveToDeck
,
moveTo
Groun
d
,
moveToHand
,
moveToOutside
}
from
"
./springs
"
;
import
{
ReportEnum
}
from
"
./springs/types
"
;
import
{
ReportEnum
}
from
"
./springs/types
"
;
import
{
interactTypeToString
}
from
"
../../utils
"
;
import
{
interactTypeToString
}
from
"
../../utils
"
;
import
classnames
from
"
classnames
"
;
const
NeosConfig
=
useConfig
();
const
NeosConfig
=
useConfig
();
...
@@ -35,7 +36,7 @@ export const Card: FC<{ idx: number }> = React.memo(({ idx }) => {
...
@@ -35,7 +36,7 @@ export const Card: FC<{ idx: number }> = React.memo(({ idx }) => {
case
MZONE
:
case
MZONE
:
case
SZONE
:
case
SZONE
:
case
OVERLAY
:
case
OVERLAY
:
moveTo
Fiel
d
({
card
:
state
,
api
,
report
});
moveTo
Groun
d
({
card
:
state
,
api
,
report
});
break
;
break
;
case
HAND
:
case
HAND
:
moveToHand
({
card
:
state
,
api
,
report
});
moveToHand
({
card
:
state
,
api
,
report
});
...
@@ -54,16 +55,28 @@ export const Card: FC<{ idx: number }> = React.memo(({ idx }) => {
...
@@ -54,16 +55,28 @@ export const Card: FC<{ idx: number }> = React.memo(({ idx }) => {
reload
(
state
.
zone
,
false
);
reload
(
state
.
zone
,
false
);
},
[]);
},
[]);
const
[
highlight
,
setHighlight
]
=
useState
(
false
);
const
[
shadowOpacity
,
setShadowOpacity
]
=
useState
(
0
);
watch
((
get
)
=>
{
watch
((
get
)
=>
{
const
{
zone
,
sequence
,
controller
,
xyzMonster
}
=
get
(
state
);
const
{
zone
,
sequence
,
controller
,
xyzMonster
,
idleInteractivities
}
=
get
(
state
);
reload
(
zone
,
true
);
reload
(
zone
,
true
);
});
});
useEffect
(()
=>
{
setHighlight
(
!!
snap
.
idleInteractivities
.
length
);
},
[
snap
.
idleInteractivities
]);
// 在别的手卡更改时候,刷新这张手卡
// 在别的手卡更改时候,刷新这张手卡
eventBus
.
on
(
eventBus
.
on
(
ReportEnum
.
ReloadHand
,
ReportEnum
.
ReloadHand
,
({
sequence
,
controller
}:
{
sequence
:
number
;
controller
:
number
})
=>
{
({
sequence
,
controller
}:
{
sequence
:
number
;
controller
:
number
})
=>
{
if
(
state
.
sequence
!==
sequence
&&
state
.
controller
===
controller
)
{
if
(
state
.
zone
===
HAND
&&
state
.
sequence
!==
sequence
&&
state
.
controller
===
controller
)
{
reload
(
state
.
zone
,
false
);
reload
(
state
.
zone
,
false
);
}
}
}
}
...
@@ -71,7 +84,7 @@ export const Card: FC<{ idx: number }> = React.memo(({ idx }) => {
...
@@ -71,7 +84,7 @@ export const Card: FC<{ idx: number }> = React.memo(({ idx }) => {
return
(
return
(
<
animated
.
div
<
animated
.
div
className=
"mat-card"
className=
{
classnames
(
"
mat-card
"
,
{
highlight
})
}
style=
{
style=
{
{
{
transform
:
to
(
transform
:
to
(
...
@@ -82,17 +95,20 @@ export const Card: FC<{ idx: number }> = React.memo(({ idx }) => {
...
@@ -82,17 +95,20 @@ export const Card: FC<{ idx: number }> = React.memo(({ idx }) => {
"
--z
"
:
styles
.
z
,
"
--z
"
:
styles
.
z
,
"
--ry
"
:
styles
.
ry
,
"
--ry
"
:
styles
.
ry
,
height
:
styles
.
height
,
height
:
styles
.
height
,
zIndex
:
styles
.
zIndex
,
}
as
any
as
CSSProperties
}
as
any
as
CSSProperties
}
}
onClick=
{
()
=>
onClick=
{
()
=>
{
[
MZONE
,
SZONE
,
HAND
].
includes
(
state
.
zone
)
&&
onCardClick
(
state
)
if
([
MZONE
,
SZONE
,
HAND
].
includes
(
state
.
zone
))
{
onCardClick
(
state
);
}
}
}
}
>
>
<
div
className=
"card-shadow"
/>
<
div
className=
"card-img-wrap"
>
<
div
className=
"card-img-wrap"
>
<
img
className=
"card-cover"
src=
{
getCardImgUrl
(
snap
.
code
)
}
alt=
""
/>
<
img
className=
"card-cover"
src=
{
getCardImgUrl
(
snap
.
code
)
}
alt=
""
/>
<
img
className=
"card-back"
src=
{
getCardImgUrl
(
0
,
true
)
}
alt=
""
/>
<
img
className=
"card-back"
src=
{
getCardImgUrl
(
0
,
true
)
}
alt=
""
/>
</
div
>
</
div
>
<
div
className=
"card-shadow"
/>
</
animated
.
div
>
</
animated
.
div
>
);
);
});
});
...
@@ -108,7 +124,7 @@ function getCardImgUrl(code: number, back = false) {
...
@@ -108,7 +124,7 @@ function getCardImgUrl(code: number, back = false) {
return
NeosConfig
.
cardImgUrl
+
"
/
"
+
code
+
"
.jpg
"
;
return
NeosConfig
.
cardImgUrl
+
"
/
"
+
code
+
"
.jpg
"
;
}
}
const
onCardClick
=
(
card
:
CardType
)
=>
()
=>
{
const
onCardClick
=
(
card
:
CardType
)
=>
{
// 中央弹窗展示选中卡牌信息
// 中央弹窗展示选中卡牌信息
messageStore
.
cardModal
.
meta
=
{
messageStore
.
cardModal
.
meta
=
{
id
:
card
.
code
,
id
:
card
.
code
,
...
...
src/ui/Duel/NewPlayMat/Card/springs/index.ts
View file @
983baaf5
export
*
from
"
./to
Fiel
d
"
;
export
*
from
"
./to
Groun
d
"
;
export
*
from
"
./toHand
"
;
export
*
from
"
./toHand
"
;
export
*
from
"
./toDeck
"
;
export
*
from
"
./toDeck
"
;
export
*
from
"
./toOutside
"
;
export
*
from
"
./toOutside
"
;
src/ui/Duel/NewPlayMat/Card/springs/toDeck.ts
View file @
983baaf5
...
@@ -48,16 +48,15 @@ export const moveToDeck = async (props: {
...
@@ -48,16 +48,15 @@ export const moveToDeck = async (props: {
if
(
zone
===
EXTRA
)
{
if
(
zone
===
EXTRA
)
{
x
=
isMe
(
controller
)
?
leftX
:
rightX
;
x
=
isMe
(
controller
)
?
leftX
:
rightX
;
}
}
let
rz
=
isMe
(
controller
)
?
180
-
DECK_ROTATE_Z
.
value
:
-
DECK_ROTATE_Z
.
value
;
let
rz
=
zone
===
EXTRA
?
DECK_ROTATE_Z
.
value
:
-
DECK_ROTATE_Z
.
value
;
if
(
zone
===
EXTRA
)
{
rz
+=
isMe
(
controller
)
?
0
:
180
;
rz
=
isMe
(
controller
)
?
DECK_ROTATE_Z
.
value
:
DECK_ROTATE_Z
.
value
;
}
const
z
=
sequence
;
const
z
=
sequence
;
api
.
start
({
api
.
start
({
x
,
x
,
y
,
y
,
z
,
z
,
rz
,
rz
,
ry
:
isMe
(
controller
)
?
(
zone
===
DECK
?
180
:
0
)
:
180
,
zIndex
:
z
,
zIndex
:
z
,
height
:
DECK_CARD_HEIGHT
.
value
,
height
:
DECK_CARD_HEIGHT
.
value
,
});
});
...
...
src/ui/Duel/NewPlayMat/Card/springs/to
Fiel
d.ts
→
src/ui/Duel/NewPlayMat/Card/springs/to
Groun
d.ts
View file @
983baaf5
...
@@ -24,7 +24,7 @@ const {
...
@@ -24,7 +24,7 @@ const {
const
{
HAND
,
GRAVE
,
REMOVED
,
DECK
,
EXTRA
,
MZONE
,
SZONE
,
TZONE
,
OVERLAY
}
=
const
{
HAND
,
GRAVE
,
REMOVED
,
DECK
,
EXTRA
,
MZONE
,
SZONE
,
TZONE
,
OVERLAY
}
=
ygopro
.
CardZone
;
ygopro
.
CardZone
;
export
const
moveTo
Fiel
d
=
async
(
props
:
{
export
const
moveTo
Groun
d
=
async
(
props
:
{
card
:
CardType
;
card
:
CardType
;
api
:
SpringApi
;
api
:
SpringApi
;
report
:
boolean
;
report
:
boolean
;
...
@@ -40,7 +40,7 @@ export const moveToField = async (props: {
...
@@ -40,7 +40,7 @@ export const moveToField = async (props: {
?
BLOCK_HEIGHT_S
.
value
*
CARD_RATIO
.
value
?
BLOCK_HEIGHT_S
.
value
*
CARD_RATIO
.
value
:
BLOCK_HEIGHT_M
.
value
*
CARD_RATIO
.
value
;
:
BLOCK_HEIGHT_M
.
value
*
CARD_RATIO
.
value
;
cons
t
height
=
zone
===
SZONE
?
BLOCK_HEIGHT_S
.
value
:
BLOCK_HEIGHT_M
.
value
;
le
t
height
=
zone
===
SZONE
?
BLOCK_HEIGHT_S
.
value
:
BLOCK_HEIGHT_M
.
value
;
// 首先计算 x 和 y
// 首先计算 x 和 y
let
x
=
0
,
let
x
=
0
,
...
@@ -94,6 +94,17 @@ export const moveToField = async (props: {
...
@@ -94,6 +94,17 @@ export const moveToField = async (props: {
y
=
-
y
;
y
=
-
y
;
}
}
// 判断是不是防御表示
const
defence
=
[
ygopro
.
CardPosition
.
DEFENSE
,
ygopro
.
CardPosition
.
FACEDOWN_DEFENSE
,
ygopro
.
CardPosition
.
FACEUP_DEFENSE
,
].
includes
(
position
??
5
);
height
=
defence
?
BLOCK_WIDTH
.
value
:
height
;
let
rz
=
isMe
(
controller
)
?
0
:
180
;
rz
+=
defence
?
90
:
0
;
// 动画
await
asyncStart
(
api
)({
await
asyncStart
(
api
)({
x
,
x
,
y
,
y
,
...
@@ -106,17 +117,17 @@ export const moveToField = async (props: {
...
@@ -106,17 +117,17 @@ export const moveToField = async (props: {
].
includes
(
position
??
5
)
].
includes
(
position
??
5
)
?
180
?
180
:
0
,
:
0
,
rz
:
isMe
(
controller
)
?
0
:
180
,
rz
,
config
:
{
config
:
{
// mass: 0.5,
// mass: 0.5,
easing
:
easings
.
ease
Out
Sine
,
easing
:
easings
.
ease
In
Sine
,
},
},
});
});
await
asyncStart
(
api
)({
await
asyncStart
(
api
)({
z
:
0
,
z
:
0
,
zIndex
:
overlayMaterials
.
length
?
3
:
1
,
zIndex
:
overlayMaterials
.
length
?
3
:
1
,
config
:
{
config
:
{
easing
:
easings
.
ease
In
Sine
,
easing
:
easings
.
ease
Out
Sine
,
mass
:
5
,
mass
:
5
,
tension
:
300
,
// 170
tension
:
300
,
// 170
friction
:
12
,
// 26
friction
:
12
,
// 26
...
...
src/ui/Duel/NewPlayMat/Card/springs/toHand.ts
View file @
983baaf5
...
@@ -70,8 +70,11 @@ export const moveToHand = async (props: {
...
@@ -70,8 +70,11 @@ export const moveToHand = async (props: {
api
.
start
({
api
.
start
({
x
:
isMe
(
controller
)
?
x
:
-
x
,
x
:
isMe
(
controller
)
?
x
:
-
x
,
y
:
isMe
(
controller
)
?
y
:
-
y
,
y
:
isMe
(
controller
)
?
y
:
-
y
,
z
:
0
,
rz
:
isMe
(
controller
)
?
_rz
:
180
-
_rz
,
rz
:
isMe
(
controller
)
?
_rz
:
180
-
_rz
,
ry
:
isMe
(
controller
)
?
0
:
180
,
height
:
HAND_CARD_HEIGHT
.
value
,
height
:
HAND_CARD_HEIGHT
.
value
,
zIndex
:
sequence
,
// rx: -PLANE_ROTATE_X.value,
// rx: -PLANE_ROTATE_X.value,
});
});
};
};
src/ui/Duel/NewPlayMat/Card/springs/toOutside.ts
View file @
983baaf5
...
@@ -34,14 +34,8 @@ export const moveToOutside = async (props: {
...
@@ -34,14 +34,8 @@ export const moveToOutside = async (props: {
const
{
zone
,
sequence
,
controller
,
xyzMonster
,
position
,
overlayMaterials
}
=
const
{
zone
,
sequence
,
controller
,
xyzMonster
,
position
,
overlayMaterials
}
=
card
;
card
;
let
x
=
0
,
let
x
=
(
BLOCK_WIDTH
.
value
+
COL_GAP
.
value
)
*
3
,
y
=
0
;
y
=
zone
===
GRAVE
?
BLOCK_HEIGHT_M
.
value
+
ROW_GAP
.
value
:
0
;
if
(
zone
===
GRAVE
)
{
x
=
(
BLOCK_WIDTH
.
value
+
COL_GAP
.
value
)
*
3
;
y
=
BLOCK_HEIGHT_M
.
value
+
ROW_GAP
.
value
;
}
else
if
(
zone
===
REMOVED
)
{
x
=
(
BLOCK_WIDTH
.
value
+
COL_GAP
.
value
)
*
2
;
}
if
(
!
isMe
(
controller
))
{
if
(
!
isMe
(
controller
))
{
x
=
-
x
;
x
=
-
x
;
y
=
-
y
;
y
=
-
y
;
...
@@ -50,6 +44,7 @@ export const moveToOutside = async (props: {
...
@@ -50,6 +44,7 @@ export const moveToOutside = async (props: {
x
,
x
,
y
,
y
,
z
:
0
,
z
:
0
,
height
:
BLOCK_HEIGHT_S
.
value
,
rz
:
isMe
(
controller
)
?
0
:
180
,
rz
:
isMe
(
controller
)
?
0
:
180
,
});
});
};
};
src/ui/Duel/NewPlayMat/Mat/index.scss
View file @
983baaf5
...
@@ -21,10 +21,8 @@ section#mat {
...
@@ -21,10 +21,8 @@ section#mat {
.mat-card-container
{
.mat-card-container
{
position
:
absolute
;
position
:
absolute
;
top
:
0
;
top
:
50%
;
left
:
0
;
left
:
50%
;
width
:
100%
;
height
:
100%
;
display
:
flex
;
display
:
flex
;
justify-content
:
center
;
justify-content
:
center
;
align-items
:
center
;
align-items
:
center
;
...
...
src/ui/Duel/NewPlayMat/Menu.tsx
View file @
983baaf5
import
"
@/styles/mat.css
"
;
import
"
@/styles/mat.css
"
;
import
Icon
from
"
@ant-design/icons
"
;
import
{
Button
,
Modal
}
from
"
antd
"
;
import
{
Button
,
Modal
}
from
"
antd
"
;
import
{
ReactComponent
as
BattleSvg
}
from
"
neos-assets/crossed-swords.svg
"
;
import
{
ReactComponent
as
EpSvg
}
from
"
neos-assets/power-button.svg
"
;
import
{
ReactComponent
as
Main2Svg
}
from
"
neos-assets/sword-in-stone.svg
"
;
import
{
ReactComponent
as
SurrenderSvg
}
from
"
neos-assets/truce.svg
"
;
import
React
,
{
useState
}
from
"
react
"
;
import
React
,
{
useState
}
from
"
react
"
;
import
{
useSnapshot
}
from
"
valtio
"
;
import
{
useSnapshot
}
from
"
valtio
"
;
import
{
import
{
fetchStrings
,
sendSelectBattleCmdResponse
,
sendSelectBattleCmdResponse
,
sendSelectIdleCmdResponse
,
sendSelectIdleCmdResponse
,
sendSurrender
,
sendSurrender
,
ygopro
,
}
from
"
@/api
"
;
}
from
"
@/api
"
;
import
{
import
{
clearAllIdleInteractivities
as
clearAllIdleInteractivities
,
clearAllIdleInteractivities
as
clearAllIdleInteractivities
,
matStore
,
matStore
,
}
from
"
@/stores
"
;
}
from
"
@/stores
"
;
import
PhaseType
=
ygopro
.
StocGameMessage
.
MsgNewPhase
.
PhaseType
;
const
IconSize
=
"
150%
"
;
const
PhaseButton
=
(
props
:
{
text
:
string
;
enable
:
boolean
;
onClick
:
()
=>
void
;
icon
?:
React
.
ReactNode
;
})
=>
{
return
(
<
Button
icon=
{
props
.
icon
}
disabled=
{
!
props
.
enable
}
onClick=
{
props
.
onClick
}
size=
"large"
>
{
props
.
text
}
</
Button
>
);
};
const
{
phase
}
=
matStore
;
const
{
phase
}
=
matStore
;
...
@@ -51,30 +29,30 @@ export const Menu = () => {
...
@@ -51,30 +29,30 @@ export const Menu = () => {
const
[
modalOpen
,
setModalOpen
]
=
useState
(
false
);
const
[
modalOpen
,
setModalOpen
]
=
useState
(
false
);
const
response
=
const
response
=
currentPhase
===
"
BATTLE_START
"
||
currentPhase
===
PhaseType
.
BATTLE_START
||
currentPhase
===
"
BATTLE_STEP
"
||
currentPhase
===
PhaseType
.
BATTLE_STEP
||
currentPhase
===
"
DAMAGE
"
||
currentPhase
===
PhaseType
.
DAMAGE
||
currentPhase
===
"
DAMAGE_GAL
"
||
currentPhase
===
PhaseType
.
DAMAGE_GAL
||
currentPhase
===
"
BATTLE
"
currentPhase
===
PhaseType
.
BATTLE
?
3
?
3
:
7
;
:
7
;
const
onBp
=
()
=>
{
const
onBp
=
()
=>
{
sendSelectIdleCmdResponse
(
6
);
sendSelectIdleCmdResponse
(
6
);
clearAllIdleInteractivities
(
0
);
// 为什么要clear两次?
clearAllIdleInteractivities
(
0
);
clearAllIdleInteractivities
(
0
);
clearAllIdleInteractivities
(
1
);
phase
.
enableBp
=
false
;
phase
.
enableBp
=
false
;
};
};
const
onM2
=
()
=>
{
const
onM2
=
()
=>
{
sendSelectBattleCmdResponse
(
2
);
sendSelectBattleCmdResponse
(
2
);
clearAllIdleInteractivities
(
0
);
clearAllIdleInteractivities
(
0
);
clearAllIdleInteractivities
(
0
);
clearAllIdleInteractivities
(
1
);
phase
.
enableM2
=
false
;
phase
.
enableM2
=
false
;
};
};
const
onEp
=
()
=>
{
const
onEp
=
()
=>
{
sendSelectIdleCmdResponse
(
response
);
sendSelectIdleCmdResponse
(
response
);
clearAllIdleInteractivities
(
0
);
clearAllIdleInteractivities
(
0
);
clearAllIdleInteractivities
(
0
);
clearAllIdleInteractivities
(
1
);
phase
.
enableEp
=
false
;
phase
.
enableEp
=
false
;
};
};
const
onSurrender
=
()
=>
{
const
onSurrender
=
()
=>
{
...
@@ -83,30 +61,16 @@ export const Menu = () => {
...
@@ -83,30 +61,16 @@ export const Menu = () => {
return
(
return
(
<
div
id=
"controller"
>
<
div
id=
"controller"
>
<
PhaseButton
<
button
disabled=
{
!
enableBp
}
onClick=
{
onBp
}
>
icon=
{
<
Icon
component=
{
BattleSvg
}
style=
{
{
fontSize
:
IconSize
}
}
/>
}
{
fetchStrings
(
"
!system
"
,
80
)
}
enable=
{
enableBp
}
</
button
>
text=
"战斗阶段"
<
button
disabled=
{
!
enableM2
}
onClick=
{
onM2
}
>
onClick=
{
onBp
}
进入主要阶段2
/>
</
button
>
<
PhaseButton
<
button
disabled=
{
!
enableEp
}
onClick=
{
onEp
}
>
icon=
{
<
Icon
component=
{
Main2Svg
}
style=
{
{
fontSize
:
IconSize
}
}
/>
}
{
fetchStrings
(
"
!system
"
,
81
)
}
enable=
{
enableM2
}
</
button
>
text=
"主要阶段2"
<
button
onClick=
{
onSurrender
}
>
{
fetchStrings
(
"
!system
"
,
1351
)
}
</
button
>
onClick=
{
onM2
}
/>
<
PhaseButton
icon=
{
<
Icon
component=
{
EpSvg
}
style=
{
{
fontSize
:
IconSize
}
}
/>
}
enable=
{
enableEp
}
text=
"结束回合"
onClick=
{
onEp
}
/>
<
PhaseButton
icon=
{
<
Icon
component=
{
SurrenderSvg
}
style=
{
{
fontSize
:
IconSize
}
}
/>
}
enable=
{
true
}
text=
"投降"
onClick=
{
onSurrender
}
/>
<
Modal
<
Modal
title=
"是否确认要投降?"
title=
"是否确认要投降?"
open=
{
modalOpen
}
open=
{
modalOpen
}
...
...
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