Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
M
MDPro3
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
6
Issues
6
List
Boards
Labels
Service Desk
Milestones
Merge Requests
4
Merge Requests
4
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
赤子奈落
MDPro3
Commits
d20b6d9e
Commit
d20b6d9e
authored
Mar 13, 2026
by
Senator John
💬
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'patch' into 'master'
Patch See merge request
!32
parents
b3287b74
eea6cdcb
Changes
14
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
2896 additions
and
246 deletions
+2896
-246
Assets/Prefabs/ScriptableObjects/Items.asset
Assets/Prefabs/ScriptableObjects/Items.asset
+9
-2
Assets/Scripts/MDPro3/Duel/BG/DuelBGManager.cs
Assets/Scripts/MDPro3/Duel/BG/DuelBGManager.cs
+1434
-182
Assets/Scripts/MDPro3/Duel/BG/PremiumMateRules.cs
Assets/Scripts/MDPro3/Duel/BG/PremiumMateRules.cs
+109
-0
Assets/Scripts/MDPro3/Duel/BG/PremiumMateRules.cs.meta
Assets/Scripts/MDPro3/Duel/BG/PremiumMateRules.cs.meta
+2
-0
Assets/Scripts/MDPro3/Duel/BG/PremiumMateSwapEffects.cs
Assets/Scripts/MDPro3/Duel/BG/PremiumMateSwapEffects.cs
+240
-0
Assets/Scripts/MDPro3/Duel/BG/PremiumMateSwapEffects.cs.meta
Assets/Scripts/MDPro3/Duel/BG/PremiumMateSwapEffects.cs.meta
+2
-0
Assets/Scripts/MDPro3/Duel/Message/DuelMessage.cs
Assets/Scripts/MDPro3/Duel/Message/DuelMessage.cs
+26
-0
Assets/Scripts/MDPro3/Game/Mate.cs
Assets/Scripts/MDPro3/Game/Mate.cs
+782
-31
Assets/Scripts/MDPro3/Game/Tools.cs
Assets/Scripts/MDPro3/Game/Tools.cs
+19
-3
Assets/Scripts/MDPro3/Helper/ABLoader.cs
Assets/Scripts/MDPro3/Helper/ABLoader.cs
+24
-11
Assets/Scripts/MDPro3/ScriptableObjects/Items.cs
Assets/Scripts/MDPro3/ScriptableObjects/Items.cs
+25
-4
Assets/Scripts/MDPro3/UI/Function/EventSEPlayer.cs
Assets/Scripts/MDPro3/UI/Function/EventSEPlayer.cs
+23
-0
Assets/Scripts/MDPro3/UI/SelectionButton/SelectionToggle_AppearanceItem.cs
...Pro3/UI/SelectionButton/SelectionToggle_AppearanceItem.cs
+163
-2
Assets/Scripts/MDPro3/UI/ServantUI/AppearanceUI.cs
Assets/Scripts/MDPro3/UI/ServantUI/AppearanceUI.cs
+38
-11
No files found.
Assets/Prefabs/ScriptableObjects/Items.asset
View file @
d20b6d9e
...
@@ -954,7 +954,7 @@ MonoBehaviour:
...
@@ -954,7 +954,7 @@ MonoBehaviour:
-
id
:
1003003
-
id
:
1003003
m_name
:
m_name
:
m_description
:
m_description
:
path
:
Mate/M1367
0
_Model
path
:
Mate/M1367
1
_Model
secondFace
:
1
secondFace
:
1
diy
:
0
diy
:
0
notReady
:
0
notReady
:
0
...
@@ -965,6 +965,13 @@ MonoBehaviour:
...
@@ -965,6 +965,13 @@ MonoBehaviour:
secondFace
:
1
secondFace
:
1
diy
:
0
diy
:
0
notReady
:
0
notReady
:
0
-
id
:
1003203
m_name
:
m_description
:
path
:
Mate/M13670_Model
secondFace
:
1
diy
:
0
notReady
:
0
-
id
:
1003004
-
id
:
1003004
m_name
:
m_name
:
m_description
:
m_description
:
...
...
Assets/Scripts/MDPro3/Duel/BG/DuelBGManager.cs
View file @
d20b6d9e
This diff is collapsed.
Click to expand it.
Assets/Scripts/MDPro3/Duel/BG/PremiumMateRules.cs
0 → 100644
View file @
d20b6d9e
using
System.Collections.Generic
;
using
System.Linq
;
namespace
MDPro3.Duel
{
public
enum
PremiumMateBehavior
{
LaundryBattlePhaseRoundTrip
,
GaiaExtraDeckPermanent
,
ShuraigLpThreshold
,
RayeBattlePhaseAndDirectAttack
,
FiendsmithExtraDeckOrEquipPermanent
,
IpSpTurnParity
}
public
sealed
class
PremiumMateRule
{
public
int
BaseId
{
get
;
}
public
int
SubId
{
get
;
}
public
IReadOnlyList
<
int
>
VariantIds
{
get
;
}
public
PremiumMateBehavior
Behavior
{
get
;
}
public
int
LpThreshold
{
get
;
}
public
PremiumMateRule
(
int
baseId
,
int
subId
,
PremiumMateBehavior
behavior
,
int
lpThreshold
=
0
,
IReadOnlyList
<
int
>
extraVariantIds
=
null
)
{
BaseId
=
baseId
;
SubId
=
subId
;
Behavior
=
behavior
;
LpThreshold
=
lpThreshold
;
var
variants
=
new
List
<
int
>
{
subId
};
if
(
extraVariantIds
!=
null
)
foreach
(
var
variantId
in
extraVariantIds
)
if
(
variantId
>
0
&&
variantId
!=
baseId
&&
!
variants
.
Contains
(
variantId
))
variants
.
Add
(
variantId
);
VariantIds
=
variants
;
}
}
public
static
class
PremiumMateRules
{
private
static
readonly
List
<
PremiumMateRule
>
_rules
=
new
()
{
new
PremiumMateRule
(
1000020
,
1000021
,
PremiumMateBehavior
.
LaundryBattlePhaseRoundTrip
),
new
PremiumMateRule
(
1003001
,
1003101
,
PremiumMateBehavior
.
GaiaExtraDeckPermanent
),
new
PremiumMateRule
(
1003002
,
1003102
,
PremiumMateBehavior
.
ShuraigLpThreshold
,
3000
),
new
PremiumMateRule
(
1003003
,
1003203
,
PremiumMateBehavior
.
RayeBattlePhaseAndDirectAttack
,
0
,
new
[]
{
1003103
}),
new
PremiumMateRule
(
1003004
,
1003104
,
PremiumMateBehavior
.
FiendsmithExtraDeckOrEquipPermanent
),
new
PremiumMateRule
(
1003005
,
1003105
,
PremiumMateBehavior
.
IpSpTurnParity
),
};
private
static
readonly
Dictionary
<
int
,
PremiumMateRule
>
_ruleByAnyId
=
_rules
.
SelectMany
(
rule
=>
rule
.
VariantIds
.
Select
(
id
=>
new
KeyValuePair
<
int
,
PremiumMateRule
>(
id
,
rule
))
.
Prepend
(
new
KeyValuePair
<
int
,
PremiumMateRule
>(
rule
.
BaseId
,
rule
)))
.
ToDictionary
(
pair
=>
pair
.
Key
,
pair
=>
pair
.
Value
);
private
static
readonly
Dictionary
<
int
,
PremiumMateRule
>
_ruleByBaseId
=
_rules
.
ToDictionary
(
rule
=>
rule
.
BaseId
,
rule
=>
rule
);
public
static
IReadOnlyList
<
PremiumMateRule
>
All
=>
_rules
;
public
static
bool
TryGetRule
(
int
mateId
,
out
PremiumMateRule
rule
)
{
return
_ruleByAnyId
.
TryGetValue
(
mateId
,
out
rule
);
}
public
static
bool
TryGetRuleByBaseId
(
int
mateId
,
out
PremiumMateRule
rule
)
{
return
_ruleByBaseId
.
TryGetValue
(
mateId
,
out
rule
);
}
public
static
bool
IsPremiumMateId
(
int
mateId
)
{
return
_ruleByAnyId
.
ContainsKey
(
mateId
);
}
public
static
bool
IsPremiumBaseId
(
int
mateId
)
{
return
_ruleByBaseId
.
ContainsKey
(
mateId
);
}
public
static
bool
IsPremiumVariantId
(
int
mateId
)
{
return
TryGetRule
(
mateId
,
out
var
rule
)
&&
rule
.
VariantIds
.
Contains
(
mateId
);
}
public
static
int
GetBaseMateId
(
int
mateId
)
{
return
TryGetRule
(
mateId
,
out
var
rule
)
?
rule
.
BaseId
:
mateId
;
}
public
static
int
GetSubMateId
(
int
mateId
)
{
return
TryGetRule
(
mateId
,
out
var
rule
)
?
rule
.
SubId
:
mateId
;
}
public
static
List
<
Items
.
Item
>
FilterAppearanceMateItems
(
IEnumerable
<
Items
.
Item
>
source
)
{
return
source
.
Where
(
item
=>
!
IsPremiumVariantId
(
item
.
id
)).
ToList
();
}
}
}
Assets/Scripts/MDPro3/Duel/BG/PremiumMateRules.cs.meta
0 → 100644
View file @
d20b6d9e
fileFormatVersion: 2
guid: 555a55c03fd6e3d45bc341e9808a721c
\ No newline at end of file
Assets/Scripts/MDPro3/Duel/BG/PremiumMateSwapEffects.cs
0 → 100644
View file @
d20b6d9e
This diff is collapsed.
Click to expand it.
Assets/Scripts/MDPro3/Duel/BG/PremiumMateSwapEffects.cs.meta
0 → 100644
View file @
d20b6d9e
fileFormatVersion: 2
guid: fd603fb2afd594547a10c88eda27f8dd
\ No newline at end of file
Assets/Scripts/MDPro3/Duel/Message/DuelMessage.cs
View file @
d20b6d9e
...
@@ -920,6 +920,13 @@ namespace MDPro3.Duel
...
@@ -920,6 +920,13 @@ namespace MDPro3.Duel
card
.
AnimationPositon
();
card
.
AnimationPositon
();
ES_hint
=
InterString
.
Get
(
"「[?]」特殊召唤宣言时"
,
card
.
GetData
().
Name
);
ES_hint
=
InterString
.
Get
(
"「[?]」特殊召唤宣言时"
,
card
.
GetData
().
Name
);
var
isExtraDeckMonster
=
card
.
GetData
().
HasType
(
CardType
.
Fusion
)
||
card
.
GetData
().
HasType
(
CardType
.
Synchro
)
||
card
.
GetData
().
HasType
(
CardType
.
Xyz
)
||
card
.
GetData
().
HasType
(
CardType
.
Link
);
if
(
isExtraDeckMonster
)
duelBGManager
.
OnSpecialSummonFromExtra
(
gps
.
InMyControl
()
?
0
:
1
);
if
(
materialCards
.
Count
>
0
)
if
(
materialCards
.
Count
>
0
)
{
{
if
(
card
.
GetData
().
HasType
(
CardType
.
Link
))
if
(
card
.
GetData
().
HasType
(
CardType
.
Link
))
...
@@ -1315,6 +1322,9 @@ namespace MDPro3.Duel
...
@@ -1315,6 +1322,9 @@ namespace MDPro3.Duel
else
else
attackedPosition
=
attackedCard
.
model
.
transform
.
position
;
attackedPosition
=
attackedCard
.
model
.
transform
.
position
;
if
(
directAttack
!=
0
)
duelBGManager
.
OnDirectAttack
(
from
.
InMyControl
()
?
0
:
1
);
var
isFinalAttack
=
duelBGManager
.
IsFinalBlow
();
var
isFinalAttack
=
duelBGManager
.
IsFinalBlow
();
duelBGManager
.
HideAttackLine
();
duelBGManager
.
HideAttackLine
();
duelBGManager
.
HideDuelFinalBlowText
();
duelBGManager
.
HideDuelFinalBlowText
();
...
@@ -1516,7 +1526,12 @@ namespace MDPro3.Duel
...
@@ -1516,7 +1526,12 @@ namespace MDPro3.Duel
if
(
life0
<=
0
||
life1
<=
0
)
if
(
life0
<=
0
||
life1
<=
0
)
duelBGManager
.
FinishDamageEffect
();
duelBGManager
.
FinishDamageEffect
();
if
(
currentMessage
==
GameMessage
.
Damage
)
duelBGManager
.
OnPlayerDamaged
(
player
,
Mathf
.
Max
(
value
,
0
));
duelBGManager
.
UpdateBgEffects
(
player
);
duelBGManager
.
UpdateBgEffects
(
player
);
duelBGManager
.
OnLifePointsChanged
(
0
,
life0
);
duelBGManager
.
OnLifePointsChanged
(
1
,
life1
);
AudioManager
.
PlaySE
(
"SE_COST_DAMAGE"
);
AudioManager
.
PlaySE
(
"SE_COST_DAMAGE"
);
Core
.
SetLP
(
player
,
-
value
);
Core
.
SetLP
(
player
,
-
value
);
await
UniTask
.
WaitForSeconds
(
0.5f
);
await
UniTask
.
WaitForSeconds
(
0.5f
);
...
@@ -1543,6 +1558,8 @@ namespace MDPro3.Duel
...
@@ -1543,6 +1558,8 @@ namespace MDPro3.Duel
ES_hint
=
InterString
.
Get
(
"对方生命值回复时"
);
ES_hint
=
InterString
.
Get
(
"对方生命值回复时"
);
}
}
duelBGManager
.
OnLifePointsChanged
(
0
,
life0
);
duelBGManager
.
OnLifePointsChanged
(
1
,
life1
);
Core
.
SetLP
(
player
,
value
);
Core
.
SetLP
(
player
,
value
);
await
UniTask
.
WaitForSeconds
(
0.5f
);
await
UniTask
.
WaitForSeconds
(
0.5f
);
}
}
...
@@ -1568,6 +1585,10 @@ namespace MDPro3.Duel
...
@@ -1568,6 +1585,10 @@ namespace MDPro3.Duel
duelBGManager
.
FinishDamageEffect
();
duelBGManager
.
FinishDamageEffect
();
duelBGManager
.
UpdateBgEffects
(
player
);
duelBGManager
.
UpdateBgEffects
(
player
);
if
(
diff
<
0
)
duelBGManager
.
OnPlayerDamaged
(
player
,
-
diff
);
duelBGManager
.
OnLifePointsChanged
(
0
,
life0
);
duelBGManager
.
OnLifePointsChanged
(
1
,
life1
);
if
(
diff
<
0
)
if
(
diff
<
0
)
AudioManager
.
PlaySE
(
"SE_COST_DAMAGE"
);
AudioManager
.
PlaySE
(
"SE_COST_DAMAGE"
);
Core
.
SetLP
(
player
,
diff
);
Core
.
SetLP
(
player
,
diff
);
...
@@ -1947,6 +1968,7 @@ namespace MDPro3.Duel
...
@@ -1947,6 +1968,7 @@ namespace MDPro3.Duel
opSpSummonCount
=
0
;
opSpSummonCount
=
0
;
turns
++;
turns
++;
myTurn
=
isFirst
?
(
turns
%
2
!=
0
)
:
(
turns
%
2
==
0
);
myTurn
=
isFirst
?
(
turns
%
2
!=
0
)
:
(
turns
%
2
==
0
);
duelBGManager
.
OnNewTurn
(
myTurn
,
turns
);
PhaseButtonHandler
.
TurnChange
(
myTurn
,
turns
);
PhaseButtonHandler
.
TurnChange
(
myTurn
,
turns
);
PhaseButtonHandler
.
SetTextMain
(
string
.
Empty
);
PhaseButtonHandler
.
SetTextMain
(
string
.
Empty
);
...
@@ -1997,6 +2019,7 @@ namespace MDPro3.Duel
...
@@ -1997,6 +2019,7 @@ namespace MDPro3.Duel
else
if
(
duelPhase
==
DuelPhase
.
End
)
else
if
(
duelPhase
==
DuelPhase
.
End
)
PhaseButtonHandler
.
SetTextMain
(
"End"
);
PhaseButtonHandler
.
SetTextMain
(
"End"
);
duelBGManager
.
OnNewPhase
(
player
,
duelPhase
);
await
duelBGManager
.
ShowPhaseBanner
(
player
,
duelPhase
);
await
duelBGManager
.
ShowPhaseBanner
(
player
,
duelPhase
);
}
}
...
@@ -2296,7 +2319,10 @@ namespace MDPro3.Duel
...
@@ -2296,7 +2319,10 @@ namespace MDPro3.Duel
if
(
currentMessage
==
GameMessage
.
CardTarget
)
if
(
currentMessage
==
GameMessage
.
CardTarget
)
cardFrom
.
AddTarget
(
cardTo
);
cardFrom
.
AddTarget
(
cardTo
);
else
if
(
currentMessage
==
GameMessage
.
Equip
)
else
if
(
currentMessage
==
GameMessage
.
Equip
)
{
cardFrom
.
equipedCard
=
cardTo
;
cardFrom
.
equipedCard
=
cardTo
;
duelBGManager
.
OnEquipApplied
(
from
.
InMyControl
()
?
0
:
1
);
}
return
UniTask
.
CompletedTask
;
return
UniTask
.
CompletedTask
;
}
}
...
...
Assets/Scripts/MDPro3/Game/Mate.cs
View file @
d20b6d9e
This diff is collapsed.
Click to expand it.
Assets/Scripts/MDPro3/Game/Tools.cs
View file @
d20b6d9e
...
@@ -55,6 +55,22 @@ namespace MDPro3
...
@@ -55,6 +55,22 @@ namespace MDPro3
Animator
[]
animators
=
animationContainer
.
GetComponentsInChildren
<
Animator
>();
Animator
[]
animators
=
animationContainer
.
GetComponentsInChildren
<
Animator
>();
foreach
(
Animator
animator
in
animators
)
foreach
(
Animator
animator
in
animators
)
{
{
if
(
animator
==
null
||
string
.
IsNullOrEmpty
(
animationName
))
continue
;
var
hasTrigger
=
false
;
var
parameters
=
animator
.
parameters
;
for
(
var
i
=
0
;
i
<
parameters
.
Length
;
i
++)
{
var
param
=
parameters
[
i
];
if
(
param
.
type
==
AnimatorControllerParameterType
.
Trigger
&&
param
.
name
==
animationName
)
{
hasTrigger
=
true
;
break
;
}
}
if
(
hasTrigger
)
animator
.
SetTrigger
(
animationName
);
animator
.
SetTrigger
(
animationName
);
}
}
}
}
...
@@ -224,7 +240,7 @@ namespace MDPro3
...
@@ -224,7 +240,7 @@ namespace MDPro3
}
}
else
else
{
{
UnityEngine
.
Debug
.
LogErrorFormat
(
$
"Image [
{
0
}
]:
{
1
}
"
,
url
,
request
.
error
);
UnityEngine
.
Debug
.
LogErrorFormat
(
"Image [{0}]: {1}"
,
url
,
request
.
error
);
return
null
;
return
null
;
}
}
}
}
...
...
Assets/Scripts/MDPro3/Helper/ABLoader.cs
View file @
d20b6d9e
...
@@ -69,23 +69,36 @@ namespace MDPro3
...
@@ -69,23 +69,36 @@ namespace MDPro3
}
}
AssetBundle
ab
=
await
AssetBundle
.
LoadFromFileAsync
(
Program
.
root
+
path
);
AssetBundle
ab
=
await
AssetBundle
.
LoadFromFileAsync
(
Program
.
root
+
path
);
var
assets
=
ab
.
LoadAllAssets
();
var
expectedName
=
Path
.
GetFileName
(
path
);
if
(!
string
.
IsNullOrEmpty
(
expectedName
))
foreach
(
UnityEngine
.
Object
asset
in
assets
)
{
{
if
(
typeof
(
GameObject
).
IsInstanceOfType
(
asset
))
var
assetRequest
=
ab
.
LoadAssetAsync
<
GameObject
>(
expectedName
);
await
assetRequest
;
returnValue
=
assetRequest
.
asset
as
GameObject
;
}
if
(
returnValue
==
null
)
{
{
if
(
cache
)
var
assets
=
ab
.
LoadAllAssets
();
foreach
(
UnityEngine
.
Object
asset
in
assets
)
{
{
if
(!
cachedAB
.
TryAdd
(
path
,
asset
as
GameObject
))
if
(!
typeof
(
GameObject
).
IsInstanceOfType
(
asset
))
Debug
.
LogWarning
(
$"Failed to cache
{
path
}
"
);
continue
;
}
returnValue
=
asset
as
GameObject
;
var
candidate
=
asset
as
GameObject
;
//break;
returnValue
=
candidate
;
if
(
candidate
!=
null
&&
candidate
.
name
==
expectedName
)
break
;
}
}
}
}
ab
.
Unload
(
false
);
ab
.
Unload
(
false
);
if
(
cache
&&
returnValue
!=
null
)
{
if
(!
cachedAB
.
TryAdd
(
path
,
returnValue
))
Debug
.
LogWarning
(
$"Failed to cache
{
path
}
"
);
}
if
(
instantiate
&&
returnValue
!=
null
)
if
(
instantiate
&&
returnValue
!=
null
)
return
UnityEngine
.
Object
.
Instantiate
(
returnValue
);
return
UnityEngine
.
Object
.
Instantiate
(
returnValue
);
else
else
...
...
Assets/Scripts/MDPro3/ScriptableObjects/Items.cs
View file @
d20b6d9e
...
@@ -100,7 +100,8 @@ namespace MDPro3
...
@@ -100,7 +100,8 @@ namespace MDPro3
public
List
<
Item
>
wallpapers
;
// 113
public
List
<
Item
>
wallpapers
;
// 113
public
List
<
List
<
Item
>>
kinds
;
public
List
<
List
<
Item
>>
kinds
;
private
const
string
ADDRESS_DEFAULT_DECK_CASE
=
"DeckCase0001_L"
;
private
const
int
CODE_DEFAULT_DECK_CASE
=
1080001
;
private
const
string
ADDRESS_DEFAULT_DECK_CASE_LEGACY
=
"DeckCase0001_L"
;
public
const
string
STRING_NULL
=
"coming soon"
;
public
const
string
STRING_NULL
=
"coming soon"
;
public
const
int
CODE_NONE
=
0
;
public
const
int
CODE_NONE
=
0
;
...
@@ -627,15 +628,35 @@ namespace MDPro3
...
@@ -627,15 +628,35 @@ namespace MDPro3
}
}
public
async
UniTask
<
Sprite
>
LoadDeckCaseIconAsync
(
int
code
,
string
suffix
)
public
async
UniTask
<
Sprite
>
LoadDeckCaseIconAsync
(
int
code
,
string
suffix
)
{
var
sprite
=
await
TryLoadAddressableSprite
(
GetDeckCaseAddress
(
code
,
suffix
));
if
(
sprite
!=
null
)
return
sprite
;
sprite
=
await
TryLoadAddressableSprite
(
GetDeckCaseAddress
(
CODE_DEFAULT_DECK_CASE
,
suffix
));
if
(
sprite
!=
null
)
return
sprite
;
return
await
TryLoadAddressableSprite
(
ADDRESS_DEFAULT_DECK_CASE_LEGACY
);
}
private
static
string
GetDeckCaseAddress
(
int
code
,
string
suffix
)
{
if
(
code
<
1080000
||
code
>
1089999
)
code
=
CODE_DEFAULT_DECK_CASE
;
return
$"DeckCase
{
code
.
ToString
()[
3.
.]}{
suffix
??
string
.
Empty
}
"
;
}
private
async
UniTask
<
Sprite
>
TryLoadAddressableSprite
(
string
address
)
{
{
try
try
{
{
return
await
LoadAddressableSprite
(
$"DeckCase
{
code
.
ToString
()[
3.
.]}{
suffix
}
"
);
return
await
LoadAddressableSprite
(
address
);
}
}
catch
catch
{
{
Debug
.
LogError
(
"Addressables Not Found: "
+
$"DeckCase
{
code
}
_
{
suffix
}
"
);
return
null
;
return
await
LoadAddressableSprite
(
ADDRESS_DEFAULT_DECK_CASE
);
}
}
}
}
...
...
Assets/Scripts/MDPro3/UI/Function/EventSEPlayer.cs
View file @
d20b6d9e
using
UnityEngine
;
using
UnityEngine
;
using
System
;
namespace
MDPro3.UI
namespace
MDPro3.UI
{
{
public
class
EventSEPlayer
:
MonoBehaviour
public
class
EventSEPlayer
:
MonoBehaviour
{
{
public
static
float
LastEventTime
{
get
;
private
set
;
}
=
float
.
NegativeInfinity
;
public
static
string
LastEventLabel
{
get
;
private
set
;
}
=
string
.
Empty
;
void
PlayAnimationEventSe
(
string
se
)
void
PlayAnimationEventSe
(
string
se
)
{
{
RegisterEvent
(
se
);
AudioManager
.
PlaySE
(
se
,
0.4f
);
AudioManager
.
PlaySE
(
se
,
0.4f
);
}
}
void
NewEvent
(
string
se
)
void
NewEvent
(
string
se
)
{
{
RegisterEvent
(
se
);
AudioManager
.
PlaySE
(
se
,
0.4f
);
AudioManager
.
PlaySE
(
se
,
0.4f
);
}
}
public
static
bool
HasRecentEvent
(
string
expectedPrefix
,
float
sinceTime
)
{
if
(
LastEventTime
<
sinceTime
)
return
false
;
if
(
string
.
IsNullOrEmpty
(
expectedPrefix
))
return
true
;
return
!
string
.
IsNullOrEmpty
(
LastEventLabel
)
&&
LastEventLabel
.
StartsWith
(
expectedPrefix
,
StringComparison
.
OrdinalIgnoreCase
);
}
private
static
void
RegisterEvent
(
string
se
)
{
LastEventTime
=
Time
.
unscaledTime
;
LastEventLabel
=
se
??
string
.
Empty
;
}
}
}
}
}
Assets/Scripts/MDPro3/UI/SelectionButton/SelectionToggle_AppearanceItem.cs
View file @
d20b6d9e
...
@@ -10,6 +10,7 @@ using MDPro3.Servant;
...
@@ -10,6 +10,7 @@ using MDPro3.Servant;
using
MDPro3.UI.ServantUI
;
using
MDPro3.UI.ServantUI
;
using
MDPro3.Utility
;
using
MDPro3.Utility
;
using
Cysharp.Threading.Tasks
;
using
Cysharp.Threading.Tasks
;
using
MDPro3.Duel
;
namespace
MDPro3.UI
namespace
MDPro3.UI
{
{
...
@@ -28,6 +29,7 @@ namespace MDPro3.UI
...
@@ -28,6 +29,7 @@ namespace MDPro3.UI
m_Protector
=
m_Protector
!=
null
?
m_Protector
m_Protector
=
m_Protector
!=
null
?
m_Protector
:
Manager
.
GetElement
<
RawImage
>(
LABEL_RIMG_PROTECTOR
);
:
Manager
.
GetElement
<
RawImage
>(
LABEL_RIMG_PROTECTOR
);
private
const
string
LABEL_IMG_WALLPAPER_BG
=
"WallpaperBG"
;
private
const
string
LABEL_IMG_WALLPAPER_BG
=
"WallpaperBG"
;
private
Image
m_WallpaperBG
;
private
Image
m_WallpaperBG
;
private
Image
WallpaperBG
=>
private
Image
WallpaperBG
=>
...
@@ -52,6 +54,11 @@ namespace MDPro3.UI
...
@@ -52,6 +54,11 @@ namespace MDPro3.UI
private
Coroutine
refreshCoroutine
;
private
Coroutine
refreshCoroutine
;
private
Coroutine
hideCoroutine
;
private
Coroutine
hideCoroutine
;
private
Image
premiumOverlayIcon
;
private
Coroutine
premiumCrossfadeCoroutine
;
private
const
float
CrossfadeHoldSeconds
=
2.0f
;
private
const
float
CrossfadeFadeSeconds
=
0.6f
;
protected
override
void
Awake
()
protected
override
void
Awake
()
{
{
base
.
Awake
();
base
.
Awake
();
...
@@ -131,6 +138,7 @@ namespace MDPro3.UI
...
@@ -131,6 +138,7 @@ namespace MDPro3.UI
Icon
.
material
=
Appearance
.
matForFace
;
Icon
.
material
=
Appearance
.
matForFace
;
loaded
=
true
;
loaded
=
true
;
StartPremiumCrossfade
();
}
}
catch
(
OperationCanceledException
)
catch
(
OperationCanceledException
)
{
{
...
@@ -208,9 +216,10 @@ namespace MDPro3.UI
...
@@ -208,9 +216,10 @@ namespace MDPro3.UI
}
}
else
else
{
{
if
(
DeckEditor
.
Deck
.
Mate
!=
itemID
)
var
normalizedMateId
=
PremiumMateRules
.
GetBaseMateId
(
itemID
);
if
(
DeckEditor
.
Deck
.
Mate
!=
normalizedMateId
)
{
{
DeckEditor
.
Deck
.
Mate
=
itemID
;
DeckEditor
.
Deck
.
Mate
=
normalizedMateId
;
Program
.
instance
.
deckEditor
.
GetUI
<
DeckEditorUI
>().
DeckView
.
SetDirty
(
true
);
Program
.
instance
.
deckEditor
.
GetUI
<
DeckEditorUI
>().
DeckView
.
SetDirty
(
true
);
Program
.
instance
.
deckEditor
.
GetUI
<
DeckEditorUI
>().
IconMate
.
sprite
=
Icon
.
sprite
;
Program
.
instance
.
deckEditor
.
GetUI
<
DeckEditorUI
>().
IconMate
.
sprite
=
Icon
.
sprite
;
}
}
...
@@ -220,6 +229,9 @@ namespace MDPro3.UI
...
@@ -220,6 +229,9 @@ namespace MDPro3.UI
{
{
if
(
AppearanceUI
.
currentContent
==
"Wallpaper"
)
if
(
AppearanceUI
.
currentContent
==
"Wallpaper"
)
Config
.
Set
(
"Wallpaper"
,
itemID
.
ToString
());
Config
.
Set
(
"Wallpaper"
,
itemID
.
ToString
());
else
if
(
AppearanceUI
.
currentContent
==
"Mate"
)
Config
.
Set
(
Appearance
.
condition
.
ToString
()
+
AppearanceUI
.
currentContent
+
Appearance
.
player
,
PremiumMateRules
.
GetBaseMateId
(
itemID
).
ToString
());
else
else
Config
.
Set
(
Appearance
.
condition
.
ToString
()
+
AppearanceUI
.
currentContent
+
Appearance
.
player
,
itemID
.
ToString
());
Config
.
Set
(
Appearance
.
condition
.
ToString
()
+
AppearanceUI
.
currentContent
+
Appearance
.
player
,
itemID
.
ToString
());
...
@@ -384,6 +396,7 @@ namespace MDPro3.UI
...
@@ -384,6 +396,7 @@ namespace MDPro3.UI
if
(
hideCoroutine
!=
null
||
!
gameObject
.
activeSelf
)
if
(
hideCoroutine
!=
null
||
!
gameObject
.
activeSelf
)
return
;
return
;
hideCoroutine
=
StartCoroutine
(
HideAsync
());
hideCoroutine
=
StartCoroutine
(
HideAsync
());
StopPremiumCrossfade
();
GetComponent
<
LayoutElement
>().
ignoreLayout
=
true
;
GetComponent
<
LayoutElement
>().
ignoreLayout
=
true
;
GetComponent
<
RectTransform
>().
anchoredPosition
=
Vector2
.
zero
;
GetComponent
<
RectTransform
>().
anchoredPosition
=
Vector2
.
zero
;
...
@@ -412,10 +425,13 @@ namespace MDPro3.UI
...
@@ -412,10 +425,13 @@ namespace MDPro3.UI
GetComponent
<
LayoutElement
>().
ignoreLayout
=
false
;
GetComponent
<
LayoutElement
>().
ignoreLayout
=
false
;
transform
.
SetSiblingIndex
(
index
);
transform
.
SetSiblingIndex
(
index
);
StartPremiumCrossfade
();
}
}
public
void
Dispose
()
public
void
Dispose
()
{
{
StopPremiumCrossfade
();
if
(
refreshCoroutine
!=
null
)
if
(
refreshCoroutine
!=
null
)
StopCoroutine
(
refreshCoroutine
);
StopCoroutine
(
refreshCoroutine
);
...
@@ -424,5 +440,150 @@ namespace MDPro3.UI
...
@@ -424,5 +440,150 @@ namespace MDPro3.UI
Destroy
(
gameObject
);
Destroy
(
gameObject
);
}
}
#
region
Premium
Mate
Crossfade
private
void
StartPremiumCrossfade
()
{
StopPremiumCrossfade
();
if
(!
loaded
)
return
;
if
(
AppearanceUI
.
currentContent
!=
"Mate"
)
return
;
if
(!
PremiumMateRules
.
IsPremiumBaseId
(
itemID
))
return
;
if
(
Icon
==
null
||
!
Icon
.
gameObject
.
activeSelf
)
return
;
premiumCrossfadeCoroutine
=
StartCoroutine
(
PremiumCrossfadeAsync
());
}
private
void
StopPremiumCrossfade
()
{
if
(
premiumCrossfadeCoroutine
!=
null
)
{
StopCoroutine
(
premiumCrossfadeCoroutine
);
premiumCrossfadeCoroutine
=
null
;
}
if
(
premiumOverlayIcon
!=
null
)
{
Destroy
(
premiumOverlayIcon
.
gameObject
);
premiumOverlayIcon
=
null
;
}
if
(
Icon
!=
null
)
{
var
c
=
Icon
.
color
;
c
.
a
=
1f
;
Icon
.
color
=
c
;
}
}
private
Image
CreateOverlayIcon
()
{
var
overlayGo
=
new
GameObject
(
"PremiumOverlay"
);
overlayGo
.
transform
.
SetParent
(
Icon
.
transform
.
parent
,
false
);
overlayGo
.
transform
.
SetSiblingIndex
(
Icon
.
transform
.
GetSiblingIndex
()
+
1
);
var
overlayImg
=
overlayGo
.
AddComponent
<
Image
>();
overlayImg
.
raycastTarget
=
false
;
overlayImg
.
preserveAspect
=
Icon
.
preserveAspect
;
overlayImg
.
type
=
Icon
.
type
;
overlayImg
.
maskable
=
Icon
.
maskable
;
var
overlayRt
=
overlayImg
.
rectTransform
;
var
iconRt
=
Icon
.
rectTransform
;
overlayRt
.
anchorMin
=
iconRt
.
anchorMin
;
overlayRt
.
anchorMax
=
iconRt
.
anchorMax
;
overlayRt
.
pivot
=
iconRt
.
pivot
;
overlayRt
.
anchoredPosition
=
iconRt
.
anchoredPosition
;
overlayRt
.
sizeDelta
=
iconRt
.
sizeDelta
;
overlayRt
.
localScale
=
iconRt
.
localScale
;
overlayRt
.
localRotation
=
iconRt
.
localRotation
;
var
c
=
Color
.
white
;
c
.
a
=
0f
;
overlayImg
.
color
=
c
;
return
overlayImg
;
}
private
IEnumerator
PremiumCrossfadeAsync
()
{
if
(!
PremiumMateRules
.
TryGetRuleByBaseId
(
itemID
,
out
var
rule
))
yield
break
;
Sprite
subSprite
=
null
;
foreach
(
var
variantId
in
rule
.
VariantIds
)
{
var
task
=
Program
.
items
.
LoadItemIconAsync
(
variantId
.
ToString
(),
Items
.
ItemType
.
Mate
);
while
(
task
.
Status
==
UniTaskStatus
.
Pending
)
yield
return
null
;
try
{
subSprite
=
task
.
GetAwaiter
().
GetResult
();
if
(
subSprite
!=
null
)
break
;
}
catch
{
// Icon not available for this variant, try next
}
}
if
(
subSprite
==
null
||
this
==
null
||
Icon
==
null
)
yield
break
;
premiumOverlayIcon
=
CreateOverlayIcon
();
premiumOverlayIcon
.
sprite
=
subSprite
;
// Icon shows base (alpha=1), overlay shows sub (alpha=0) initially.
// Crossfade loop: hold → fade overlay in → hold → fade overlay out → repeat.
while
(
true
)
{
// Hold on base icon
yield
return
new
WaitForSecondsRealtime
(
CrossfadeHoldSeconds
);
// Fade in overlay (base → sub)
yield
return
FadeOverlay
(
0f
,
1f
,
CrossfadeFadeSeconds
);
// Hold on sub icon
yield
return
new
WaitForSecondsRealtime
(
CrossfadeHoldSeconds
);
// Fade out overlay (sub → base)
yield
return
FadeOverlay
(
1f
,
0f
,
CrossfadeFadeSeconds
);
}
}
private
IEnumerator
FadeOverlay
(
float
fromAlpha
,
float
toAlpha
,
float
duration
)
{
if
(
premiumOverlayIcon
==
null
)
yield
break
;
var
elapsed
=
0f
;
while
(
elapsed
<
duration
)
{
elapsed
+=
Time
.
unscaledDeltaTime
;
var
t
=
Mathf
.
Clamp01
(
elapsed
/
duration
);
t
=
t
*
t
*
(
3f
-
2f
*
t
);
// smoothstep
var
alpha
=
Mathf
.
Lerp
(
fromAlpha
,
toAlpha
,
t
);
if
(
premiumOverlayIcon
!=
null
)
{
var
c
=
premiumOverlayIcon
.
color
;
c
.
a
=
alpha
;
premiumOverlayIcon
.
color
=
c
;
}
yield
return
null
;
}
if
(
premiumOverlayIcon
!=
null
)
{
var
c
=
premiumOverlayIcon
.
color
;
c
.
a
=
toAlpha
;
premiumOverlayIcon
.
color
=
c
;
}
}
#
endregion
}
}
}
}
Assets/Scripts/MDPro3/UI/ServantUI/AppearanceUI.cs
View file @
d20b6d9e
...
@@ -8,6 +8,7 @@ using UnityEngine.EventSystems;
...
@@ -8,6 +8,7 @@ using UnityEngine.EventSystems;
using
UnityEngine.UI
;
using
UnityEngine.UI
;
using
static
MDPro3
.
Servant
.
Appearance
;
using
static
MDPro3
.
Servant
.
Appearance
;
using
static
YgomGame
.
Duel
.
BattleAimingEffect
;
using
static
YgomGame
.
Duel
.
BattleAimingEffect
;
using
MDPro3.Duel
;
namespace
MDPro3.UI.ServantUI
namespace
MDPro3.UI.ServantUI
{
{
...
@@ -390,6 +391,8 @@ namespace MDPro3.UI.ServantUI
...
@@ -390,6 +391,8 @@ namespace MDPro3.UI.ServantUI
int
itemCount
=
0
;
int
itemCount
=
0
;
foreach
(
var
itemInfo
in
targetItems
)
foreach
(
var
itemInfo
in
targetItems
)
{
{
if
(
currentContent
==
"Mate"
&&
PremiumMateRules
.
IsPremiumVariantId
(
itemInfo
.
id
))
continue
;
if
(
itemInfo
.
notReady
)
continue
;
if
(
itemInfo
.
notReady
)
continue
;
GameObject
item
=
Instantiate
(
Template
);
GameObject
item
=
Instantiate
(
Template
);
...
@@ -520,44 +523,68 @@ namespace MDPro3.UI.ServantUI
...
@@ -520,44 +523,68 @@ namespace MDPro3.UI.ServantUI
foreach
(
var
item
in
currentList
)
foreach
(
var
item
in
currentList
)
{
{
var
itemMono
=
item
.
GetComponent
<
SelectionToggle_AppearanceItem
>();
if
(
currentContent
==
"Mate"
&&
PremiumMateRules
.
IsPremiumVariantId
(
itemMono
.
itemID
))
{
itemMono
.
Hide
();
continue
;
}
if
(
player
.
Contains
(
"0"
)
&&
onlyOpSideShowItems
.
Contains
(
item
))
if
(
player
.
Contains
(
"0"
)
&&
onlyOpSideShowItems
.
Contains
(
item
))
item
.
GetComponent
<
SelectionToggle_AppearanceItem
>()
.
Hide
();
item
Mono
.
Hide
();
else
else
item
.
GetComponent
<
SelectionToggle_AppearanceItem
>()
.
Show
();
item
Mono
.
Show
();
}
}
foreach
(
var
item
in
currentList
)
foreach
(
var
item
in
currentList
)
{
{
var
itemMono
=
item
.
GetComponent
<
SelectionToggle_AppearanceItem
>();
if
(
currentContent
==
"Wallpaper"
)
if
(
currentContent
==
"Wallpaper"
)
{
{
if
(
item
.
GetComponent
<
SelectionToggle_AppearanceItem
>()
.
itemID
.
ToString
()
==
Config
.
Get
(
"Wallpaper"
,
targetItems
[
0
].
id
.
ToString
()))
if
(
item
Mono
.
itemID
.
ToString
()
==
Config
.
Get
(
"Wallpaper"
,
targetItems
[
0
].
id
.
ToString
()))
{
{
item
.
GetComponent
<
SelectionToggle_AppearanceItem
>()
.
SetToggleOn
();
item
Mono
.
SetToggleOn
();
break
;
break
;
}
}
}
}
else
else
{
{
var
itemID
=
item
.
GetComponent
<
SelectionToggle_AppearanceItem
>().
itemID
;
var
itemID
=
itemMono
.
itemID
;
if
(
currentContent
==
"Mate"
&&
PremiumMateRules
.
IsPremiumVariantId
(
itemID
))
continue
;
if
(
condition
==
Condition
.
DeckEditor
)
if
(
condition
==
Condition
.
DeckEditor
)
{
{
if
(
itemID
==
DeckEditor
.
Deck
.
Case
if
(
currentContent
==
"Mate"
)
{
var
selectedMate
=
PremiumMateRules
.
GetBaseMateId
(
DeckEditor
.
Deck
.
Mate
);
if
(
itemID
==
selectedMate
)
{
itemMono
.
SetToggleOn
();
break
;
}
}
else
if
(
itemID
==
DeckEditor
.
Deck
.
Case
||
itemID
==
DeckEditor
.
Deck
.
Protector
||
itemID
==
DeckEditor
.
Deck
.
Protector
||
itemID
==
DeckEditor
.
Deck
.
Field
||
itemID
==
DeckEditor
.
Deck
.
Field
||
itemID
==
DeckEditor
.
Deck
.
Grave
||
itemID
==
DeckEditor
.
Deck
.
Grave
||
itemID
==
DeckEditor
.
Deck
.
Stand
||
itemID
==
DeckEditor
.
Deck
.
Stand
||
itemID
==
DeckEditor
.
Deck
.
Mate
)
||
itemID
==
DeckEditor
.
Deck
.
Mate
)
{
{
item
.
GetComponent
<
SelectionToggle_AppearanceItem
>()
.
SetToggleOn
();
itemMono
.
SetToggleOn
();
break
;
break
;
}
}
}
}
else
else
{
{
if
(
itemID
.
ToString
()
==
Config
.
Get
(
condition
.
ToString
()
+
currentContent
+
player
,
targetItems
[
0
].
id
.
ToString
()))
var
selectedCode
=
Config
.
Get
(
condition
.
ToString
()
+
currentContent
+
player
,
targetItems
[
0
].
id
.
ToString
());
if
(
currentContent
==
"Mate"
&&
int
.
TryParse
(
selectedCode
,
out
var
selectedMateCode
))
selectedCode
=
PremiumMateRules
.
GetBaseMateId
(
selectedMateCode
).
ToString
();
if
(
itemID
.
ToString
()
==
selectedCode
)
{
{
item
.
GetComponent
<
SelectionToggle_AppearanceItem
>()
.
SetToggleOn
();
item
Mono
.
SetToggleOn
();
break
;
break
;
}
}
}
}
...
...
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