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
eea6cdcb
Commit
eea6cdcb
authored
Mar 13, 2026
by
ElderLich
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Feature: Implemented Deluxe Mates like in MD
parent
2046e5d8
Changes
13
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
2869 additions
and
240 deletions
+2869
-240
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
+17
-1
Assets/Scripts/MDPro3/Helper/ABLoader.cs
Assets/Scripts/MDPro3/Helper/ABLoader.cs
+24
-11
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 @
eea6cdcb
...
@@ -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 @
eea6cdcb
This diff is collapsed.
Click to expand it.
Assets/Scripts/MDPro3/Duel/BG/PremiumMateRules.cs
0 → 100644
View file @
eea6cdcb
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 @
eea6cdcb
fileFormatVersion: 2
guid: 555a55c03fd6e3d45bc341e9808a721c
\ No newline at end of file
Assets/Scripts/MDPro3/Duel/BG/PremiumMateSwapEffects.cs
0 → 100644
View file @
eea6cdcb
This diff is collapsed.
Click to expand it.
Assets/Scripts/MDPro3/Duel/BG/PremiumMateSwapEffects.cs.meta
0 → 100644
View file @
eea6cdcb
fileFormatVersion: 2
guid: fd603fb2afd594547a10c88eda27f8dd
\ No newline at end of file
Assets/Scripts/MDPro3/Duel/Message/DuelMessage.cs
View file @
eea6cdcb
...
@@ -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 @
eea6cdcb
This diff is collapsed.
Click to expand it.
Assets/Scripts/MDPro3/Game/Tools.cs
View file @
eea6cdcb
...
@@ -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
);
}
}
}
}
...
...
Assets/Scripts/MDPro3/Helper/ABLoader.cs
View file @
eea6cdcb
...
@@ -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/UI/Function/EventSEPlayer.cs
View file @
eea6cdcb
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 @
eea6cdcb
...
@@ -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 @
eea6cdcb
...
@@ -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