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
49c04e7c
Commit
49c04e7c
authored
Mar 30, 2023
by
Chunchi Che
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'feat/ui/select_counter' into 'main'
Feat/ui/select counter See merge request
mycard/Neos!159
parents
2984f1c7
e8dcd004
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
192 additions
and
27 deletions
+192
-27
rust-src/src/buffer.rs
rust-src/src/buffer.rs
+8
-0
src/api/ocgcore/ocgAdapter/ctos/ctosGameMsgResponse/mod.ts
src/api/ocgcore/ocgAdapter/ctos/ctosGameMsgResponse/mod.ts
+8
-0
src/api/ocgcore/ocgAdapter/ctos/ctosGameMsgResponse/selectCounter.ts
...core/ocgAdapter/ctos/ctosGameMsgResponse/selectCounter.ts
+13
-0
src/api/ocgcore/ocgHelper.ts
src/api/ocgcore/ocgHelper.ts
+14
-0
src/reducers/duel/mod.ts
src/reducers/duel/mod.ts
+10
-4
src/reducers/duel/modal/checkCardModalV3Slice.ts
src/reducers/duel/modal/checkCardModalV3Slice.ts
+1
-13
src/reducers/duel/modal/checkCounterModalSlice.ts
src/reducers/duel/modal/checkCounterModalSlice.ts
+41
-0
src/reducers/duel/modal/mod.ts
src/reducers/duel/modal/mod.ts
+10
-6
src/reducers/duel/util.ts
src/reducers/duel/util.ts
+4
-2
src/service/duel/selectCounter.ts
src/service/duel/selectCounter.ts
+2
-1
src/ui/Duel/checkCardModalV3.tsx
src/ui/Duel/checkCardModalV3.tsx
+1
-1
src/ui/Duel/checkCounterModal.tsx
src/ui/Duel/checkCounterModal.tsx
+78
-0
src/ui/Duel/main.tsx
src/ui/Duel/main.tsx
+2
-0
No files found.
rust-src/src/buffer.rs
View file @
49c04e7c
...
...
@@ -102,6 +102,14 @@ impl BufferWriter {
self
.array
.extend
(
value
.to_le_bytes
());
}
pub
fn
writeUint16
(
&
mut
self
,
value
:
u16
)
{
self
.array
.extend
(
value
.to_le_bytes
());
}
pub
fn
writeInt16
(
&
mut
self
,
value
:
i16
)
{
self
.array
.extend
(
value
.to_le_bytes
());
}
pub
fn
writeUint32
(
&
mut
self
,
value
:
u32
)
{
self
.array
.extend
(
value
.to_le_bytes
());
}
...
...
src/api/ocgcore/ocgAdapter/ctos/ctosGameMsgResponse/mod.ts
View file @
49c04e7c
...
...
@@ -10,6 +10,7 @@ import adaptSelectPositionResponse from "./selectPosition";
import
adaptSelectOptionResponse
from
"
./selectOption
"
;
import
adaptSelectBattleCmdResponse
from
"
./selectBattleCmd
"
;
import
adaptSelectUnselectCardResponse
from
"
./selectUnselectCard
"
;
import
adaptSelectCounterResponse
from
"
./selectCounter
"
;
/*
* CTOS CTOS_RESPONSE
...
...
@@ -72,6 +73,13 @@ export default class CtosResponsePacket extends YgoProPacket {
break
;
}
case
"
select_counter_response
"
:
{
extraData
=
adaptSelectCounterResponse
(
response
.
select_counter_response
);
break
;
}
default
:
{
break
;
}
...
...
src/api/ocgcore/ocgAdapter/ctos/ctosGameMsgResponse/selectCounter.ts
0 → 100644
View file @
49c04e7c
import
{
ygopro
}
from
"
../../../idl/ocgcore
"
;
// @ts-ignore
import
{
BufferWriter
}
from
"
rust-src
"
;
export
default
(
response
:
ygopro
.
CtosGameMsgResponse
.
SelectCounterResponse
)
=>
{
const
writer
=
new
BufferWriter
();
for
(
const
count
of
response
.
selected_count
)
{
writer
.
writeInt16
(
count
);
}
return
writer
.
toArray
();
};
src/api/ocgcore/ocgHelper.ts
View file @
49c04e7c
...
...
@@ -268,3 +268,17 @@ export function sendSelectUnselectCardResponse(value: {
socketMiddleWare
({
cmd
:
socketCmd
.
SEND
,
payload
});
}
export
function
sendSelectCounterResponse
(
counts
:
number
[])
{
const
response
=
new
ygopro
.
YgoCtosMsg
({
ctos_response
:
new
ygopro
.
CtosGameMsgResponse
({
select_counter_response
:
new
ygopro
.
CtosGameMsgResponse
.
SelectCounterResponse
({
selected_count
:
counts
,
}),
}),
});
const
payload
=
new
GameMsgResponse
(
response
).
serialize
();
socketMiddleWare
({
cmd
:
socketCmd
.
SEND
,
payload
});
}
src/reducers/duel/mod.ts
View file @
49c04e7c
...
...
@@ -59,9 +59,10 @@ import {
setCheckCardModalV3OverFlowImpl
,
setCheckCardModalV3ResponseAbleImpl
,
resetCheckCardModalV3Impl
,
setCheckCardModalV3SelectedImpl
,
checkCardModalV3Case
,
setCardModalCountersImpl
,
setCheckCounterImpl
,
clearCheckCounterImpl
,
}
from
"
./modal/mod
"
;
import
{
MonsterState
,
...
...
@@ -184,7 +185,10 @@ const initialState: DuelState = {
allLevel
:
0
,
mustSelectList
:
[],
selectAbleList
:
[],
selectedList
:
[],
},
checkCounterModal
:
{
isOpen
:
false
,
options
:
[],
},
},
};
...
...
@@ -279,8 +283,9 @@ const duelSlice = createSlice({
setCheckCardModalV3OverFlow
:
setCheckCardModalV3OverFlowImpl
,
setCheckCardModalV3ResponseAble
:
setCheckCardModalV3ResponseAbleImpl
,
resetCheckCardModalV3
:
resetCheckCardModalV3Impl
,
setCheckCardModalV3Selected
:
setCheckCardModalV3SelectedImpl
,
setCardModalCounters
:
setCardModalCountersImpl
,
setCheckCounter
:
setCheckCounterImpl
,
clearCheckCounter
:
clearCheckCounterImpl
,
// 通用的`Reducer`
clearAllIdleInteractivities
:
clearAllIdleInteractivitiesImpl
,
...
...
@@ -393,8 +398,9 @@ export const {
setCheckCardModalV3OverFlow
,
setCheckCardModalV3ResponseAble
,
resetCheckCardModalV3
,
setCheckCardModalV3Selected
,
setCardModalCounters
,
setCheckCounter
,
clearCheckCounter
,
}
=
duelSlice
.
actions
;
export
const
selectDuelHsStart
=
(
state
:
RootState
)
=>
{
return
state
.
duel
.
meInitInfo
!=
null
;
...
...
src/reducers/duel/modal/checkCardModalV3Slice.ts
View file @
49c04e7c
...
...
@@ -5,7 +5,7 @@ import {
CaseReducer
,
createAsyncThunk
,
}
from
"
@reduxjs/toolkit
"
;
import
{
CardMeta
,
fetchCard
}
from
"
../../../api/cards
"
;
import
{
fetchCard
}
from
"
../../../api/cards
"
;
import
{
RootState
}
from
"
../../../store
"
;
import
{
ygopro
}
from
"
../../../api/ocgcore/idl/ocgcore
"
;
import
{
findCardByLocation
}
from
"
../util
"
;
...
...
@@ -48,17 +48,6 @@ export const setCheckCardModalV3ResponseAbleImpl: DuelReducer<boolean> = (
state
.
modalState
.
checkCardModalV3
.
responseable
=
action
.
payload
;
};
export
const
setCheckCardModalV3SelectedImpl
:
DuelReducer
<
{
meta
:
CardMeta
;
level1
:
number
;
level2
:
number
;
response
:
number
;
}[]
>
=
(
state
,
action
)
=>
{
state
.
modalState
.
checkCardModalV3
.
selectedList
=
action
.
payload
;
};
// 增加卡牌选项
export
const
fetchCheckCardMetasV3
=
createAsyncThunk
(
"
duel/fetchCheckCardMetaV3
"
,
...
...
@@ -137,7 +126,6 @@ export const resetCheckCardModalV3Impl: CaseReducer<DuelState> = (state) => {
modalState
.
responseable
=
undefined
;
modalState
.
mustSelectList
=
[];
modalState
.
selectAbleList
=
[];
modalState
.
selectedList
=
[];
};
export
const
selectCheckCardModalV3
=
(
state
:
RootState
)
=>
...
...
src/reducers/duel/modal/checkCounterModalSlice.ts
0 → 100644
View file @
49c04e7c
// 后续对于`MSG_SELECT_XXX`的处理UI都尽量用`Babylon.js`实现而不会通过`Antd`的`Modal`实现,因此这里不追求工程质量,暂时简单实现下。
import
{
PayloadAction
,
CaseReducer
}
from
"
@reduxjs/toolkit
"
;
import
{
RootState
}
from
"
../../../store
"
;
import
{
DuelState
}
from
"
../mod
"
;
import
{
findCardByLocation
}
from
"
../util
"
;
import
{
ygopro
}
from
"
../../../api/ocgcore/idl/ocgcore
"
;
type
SelectCounter
=
ReturnType
<
typeof
ygopro
.
StocGameMessage
.
MsgSelectCounter
.
prototype
.
toObject
>
;
export
const
setCheckCounterImpl
:
CaseReducer
<
DuelState
,
PayloadAction
<
SelectCounter
>
>
=
(
state
,
action
)
=>
{
const
modal
=
state
.
modalState
.
checkCounterModal
;
const
payload
=
action
.
payload
;
modal
.
counterType
=
payload
.
counter_type
;
modal
.
min
=
payload
.
min
;
modal
.
options
=
payload
.
options
!
.
map
((
option
)
=>
{
const
code
=
option
.
code
?
option
.
code
:
findCardByLocation
(
state
,
option
.
location
!
)?.
occupant
?.
id
||
0
;
return
{
code
,
max
:
option
.
counter_count
!
,
};
});
modal
.
isOpen
=
true
;
};
export
const
clearCheckCounterImpl
:
CaseReducer
<
DuelState
>
=
(
state
)
=>
{
state
.
modalState
.
checkCounterModal
.
isOpen
=
false
;
state
.
modalState
.
checkCounterModal
.
min
=
undefined
;
state
.
modalState
.
checkCounterModal
.
counterType
=
undefined
;
state
.
modalState
.
checkCounterModal
.
options
=
[];
};
export
const
selectCheckCounterModal
=
(
state
:
RootState
)
=>
state
.
duel
.
modalState
.
checkCounterModal
;
src/reducers/duel/modal/mod.ts
View file @
49c04e7c
...
...
@@ -92,12 +92,15 @@ export interface ModalState {
level2
:
number
;
response
:
number
;
}[];
// TODO: remove this prop
selectedList
:
{
meta
:
CardMeta
;
level1
:
number
;
level2
:
number
;
response
:
number
;
};
// 指示器选择弹窗
checkCounterModal
:
{
isOpen
:
boolean
;
counterType
?:
number
;
min
?:
number
;
options
:
{
code
:
number
;
max
:
number
;
}[];
};
}
...
...
@@ -110,3 +113,4 @@ export * from "./positionModalSlice";
export
*
from
"
./optionModalSlice
"
;
export
*
from
"
./checkCardModalV2Slice
"
;
export
*
from
"
./checkCardModalV3Slice
"
;
export
*
from
"
./checkCounterModalSlice
"
;
src/reducers/duel/util.ts
View file @
49c04e7c
...
...
@@ -29,9 +29,11 @@ export function judgeSelf(player: number, state: Draft<DuelState>): boolean {
* 通过`controler`,`zone`和`sequence`获取卡牌状态*/
export
function
findCardByLocation
(
state
:
Draft
<
DuelState
>
,
location
:
ygopro
.
CardLocation
location
:
|
ygopro
.
CardLocation
|
ReturnType
<
typeof
ygopro
.
CardLocation
.
prototype
.
toObject
>
):
CardState
|
undefined
{
const
controler
=
location
.
controler
;
const
controler
=
location
.
controler
!
;
const
zone
=
location
.
location
;
const
sequence
=
location
.
sequence
;
...
...
src/service/duel/selectCounter.ts
View file @
49c04e7c
import
{
ygopro
}
from
"
../../api/ocgcore/idl/ocgcore
"
;
import
{
setCheckCounter
}
from
"
../../reducers/duel/mod
"
;
import
{
AppDispatch
}
from
"
../../store
"
;
import
MsgSelectCounter
=
ygopro
.
StocGameMessage
.
MsgSelectCounter
;
export
default
(
selectCounter
:
MsgSelectCounter
,
dispatch
:
AppDispatch
)
=>
{
console
.
log
(
selectCounter
);
dispatch
(
setCheckCounter
(
selectCounter
.
toObject
())
);
};
src/ui/Duel/checkCardModalV3.tsx
View file @
49c04e7c
...
...
@@ -21,7 +21,7 @@ const CheckCardModalV3 = () => {
const
max
=
state
.
selectMax
||
0
;
const
mustSelectOptions
=
state
.
mustSelectList
;
const
selectAbleOptions
=
state
.
selectAbleList
;
const
[
selectedOptions
,
setSelectedOptions
]
=
useState
(
state
.
selectedList
);
const
[
selectedOptions
,
setSelectedOptions
]
=
useState
(
[]
);
const
overflow
=
state
.
overflow
;
const
LevelSum
=
state
.
allLevel
;
const
Level1Sum
=
mustSelectOptions
...
...
src/ui/Duel/checkCounterModal.tsx
0 → 100644
View file @
49c04e7c
import
{
Button
,
Row
,
Col
,
Card
,
InputNumber
}
from
"
antd
"
;
import
React
,
{
useRef
,
useState
}
from
"
react
"
;
import
{
sendSelectCounterResponse
}
from
"
../../api/ocgcore/ocgHelper
"
;
import
{
fetchStrings
}
from
"
../../api/strings
"
;
import
{
useAppSelector
}
from
"
../../hook
"
;
import
{
clearCheckCounter
}
from
"
../../reducers/duel/mod
"
;
import
{
selectCheckCounterModal
}
from
"
../../reducers/duel/modal/checkCounterModalSlice
"
;
import
{
store
}
from
"
../../store
"
;
import
DragModal
from
"
./dragModal
"
;
import
NeosConfig
from
"
../../../neos.config.json
"
;
const
CheckCounterModal
=
()
=>
{
const
dispatch
=
store
.
dispatch
;
const
state
=
useAppSelector
(
selectCheckCounterModal
);
const
isOpen
=
state
.
isOpen
;
const
counterName
=
fetchStrings
(
"
!counter
"
,
`0x
${
state
.
counterType
!
}
`
);
const
min
=
state
.
min
||
0
;
const
options
=
state
.
options
;
const
[
selected
,
setSelected
]
=
useState
(
new
Array
(
options
.
length
));
const
sum
=
selected
.
reduce
((
sum
,
current
)
=>
sum
+
current
,
0
);
const
finishable
=
sum
==
min
;
const
draggleRef
=
useRef
<
HTMLDivElement
>
(
null
);
const
onFinish
=
()
=>
{
sendSelectCounterResponse
(
selected
);
dispatch
(
clearCheckCounter
());
};
return
(
<
DragModal
modalProps=
{
{
title
:
`请移除${min}个${counterName}`
,
open
:
isOpen
,
closable
:
false
,
footer
:
(
<
Button
disabled=
{
!
finishable
}
onClick=
{
onFinish
}
>
finish
</
Button
>
),
}
}
dragRef=
{
draggleRef
}
draggable=
{
true
}
>
<
Row
>
{
options
.
map
((
option
,
idx
)
=>
{
return
(
<
Col
span=
{
4
}
key=
{
idx
}
>
<
Card
hoverable
style=
{
{
width
:
120
}
}
cover=
{
<
img
alt=
{
option
.
code
.
toString
()
}
src=
{
`${NeosConfig.cardImgUrl}/${option.code}.jpg`
}
/>
}
>
<
InputNumber
min=
{
0
}
max=
{
option
.
max
}
defaultValue=
{
0
}
onChange=
{
(
value
)
=>
{
let
newSelected
=
[...
selected
];
newSelected
[
idx
]
=
value
||
0
;
setSelected
(
newSelected
);
}
}
/>
</
Card
>
</
Col
>
);
})
}
</
Row
>
</
DragModal
>
);
};
export
default
CheckCounterModal
;
src/ui/Duel/main.tsx
View file @
49c04e7c
...
...
@@ -27,6 +27,7 @@ import SendBox from "./sendBox";
import
PlayerStatus
from
"
./status
"
;
import
Alert
from
"
./alert
"
;
import
CheckCardModalV3
from
"
./checkCardModalV3
"
;
import
CheckCounterModal
from
"
./checkCounterModal
"
;
// Ref: https://github.com/brianzinn/react-babylonjs/issues/126
const
NeosDuel
=
()
=>
{
...
...
@@ -48,6 +49,7 @@ const NeosDuel = () => {
<
OptionModal
/>
<
CheckCardModalV2
/>
<
CheckCardModalV3
/>
<
CheckCounterModal
/>
</>
);
};
...
...
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