Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
M
MDPro2
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
kiggy
MDPro2
Commits
41919acf
Commit
41919acf
authored
Jun 12, 2023
by
赤子奈落
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add voice function: summon line
parent
69f098fd
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
167 additions
and
48 deletions
+167
-48
Assets/MD/Scripts/CardAnimation.cs
Assets/MD/Scripts/CardAnimation.cs
+9
-9
Assets/MD/Scripts/LoadSFX.cs
Assets/MD/Scripts/LoadSFX.cs
+8
-7
Assets/MD/Scripts/VoiceHandler.cs
Assets/MD/Scripts/VoiceHandler.cs
+58
-5
Assets/MD/Scripts/VoiceMap.cs
Assets/MD/Scripts/VoiceMap.cs
+43
-0
Assets/SibylSystem/Ocgcore/OCGobjects/gameCard.cs
Assets/SibylSystem/Ocgcore/OCGobjects/gameCard.cs
+49
-27
No files found.
Assets/MD/Scripts/CardAnimation.cs
View file @
41919acf
...
...
@@ -117,7 +117,7 @@ public class CardAnimation : MonoBehaviour
int
cutinFrames
=
96
;
int
landingFrames
=
50
;
//50帧动画 10帧落地 在movetime的后50帧播放
public
void
CardLanding
(
int
level
)
public
void
CardLanding
(
int
level
,
float
extraDelay
=
0f
)
{
if
(
LoadSFX
.
spType
==
"RITUAL"
)
{
...
...
@@ -156,23 +156,23 @@ public class CardAnimation : MonoBehaviour
StopAllCoroutines
();
if
(
bigLanding
&&
cutin
&&
summon
)
{
StartCoroutine
(
DelayCardLandingAnimation
((
showUnlitCardFrames
+
summonFrames1
+
cutinFrames
-
landingFrames
)/
60f
+
landTime
));
StartCoroutine
(
DelayActivateQuad
((
showUnlitCardFrames
+
summonFrames1
+
cutinFrames
)
/
60f
+
landTime
));
StartCoroutine
(
DelayCardLandingAnimation
((
showUnlitCardFrames
+
summonFrames1
+
cutinFrames
-
landingFrames
)/
60f
+
landTime
+
extraDelay
));
StartCoroutine
(
DelayActivateQuad
((
showUnlitCardFrames
+
summonFrames1
+
cutinFrames
)
/
60f
+
landTime
+
extraDelay
));
}
else
if
(
bigLanding
&&
cutin
)
{
StartCoroutine
(
DelayCardLandingAnimation
(
VoiceHandler
.
voiceTime
+
(
cutinFrames
-
landingFrames
)/
60f
+
landTime
));
StartCoroutine
(
DelayActivateQuad
(
VoiceHandler
.
voiceTime
+
cutinFrames
/
60f
+
landTime
));
StartCoroutine
(
DelayCardLandingAnimation
(
VoiceHandler
.
voiceTime
+
(
cutinFrames
-
landingFrames
)/
60f
+
landTime
+
extraDelay
));
StartCoroutine
(
DelayActivateQuad
(
VoiceHandler
.
voiceTime
+
cutinFrames
/
60f
+
landTime
+
extraDelay
));
}
else
if
(
bigLanding
&&
summon
)
{
StartCoroutine
(
DelayCardLandingAnimation
((
showUnlitCardFrames
+
summonFrames2
-
landingFrames
)/
60f
+
landTime
));
StartCoroutine
(
DelayActivateQuad
((
showUnlitCardFrames
+
summonFrames2
)
/
60f
+
landTime
));
StartCoroutine
(
DelayCardLandingAnimation
((
showUnlitCardFrames
+
summonFrames2
-
landingFrames
)/
60f
+
landTime
+
extraDelay
));
StartCoroutine
(
DelayActivateQuad
((
showUnlitCardFrames
+
summonFrames2
)
/
60f
+
landTime
+
extraDelay
));
}
else
if
(
bigLanding
)
{
StartCoroutine
(
DelayCardLandingAnimation
(
VoiceHandler
.
voiceTime
+
landTime
-
landingFrames
/
60f
));
StartCoroutine
(
DelayActivateQuad
(
VoiceHandler
.
voiceTime
+
landTime
));
StartCoroutine
(
DelayCardLandingAnimation
(
VoiceHandler
.
voiceTime
+
landTime
-
landingFrames
/
60f
+
extraDelay
));
StartCoroutine
(
DelayActivateQuad
(
VoiceHandler
.
voiceTime
+
landTime
+
extraDelay
));
}
bigLanding
=
false
;
cutin
=
false
;
...
...
Assets/MD/Scripts/LoadSFX.cs
View file @
41919acf
...
...
@@ -571,9 +571,6 @@ public class LoadSFX : MonoBehaviour
{
string
type
=
spType
;
if
(
type
==
"FUSION"
)
BlackBehaviour
.
FadeIn
(
0.25f
);
GameObject
ms
;
switch
(
type
)
{
...
...
@@ -668,10 +665,7 @@ public class LoadSFX : MonoBehaviour
break
;
cards
.
GetChild
(
i
).
GetChild
(
0
).
GetChild
(
0
).
GetChild
(
1
).
GetChild
(
1
).
GetComponent
<
Renderer
>().
material
.
mainTexture
=
GameTextureManager
.
GetCardPictureNow
(
materials
[
i
].
Id
);
}
if
(
materials
.
Count
>
2
)
SEHandler
.
Play
(
"SE_DUEL/SE_SMN_CMN_CARD_02"
);
else
SEHandler
.
Play
(
"SE_DUEL/SE_SMN_CMN_CARD_01"
);
if
(
type
==
"SYNCHRO"
)
{
List
<
ParticleSystem
>
ps
=
new
List
<
ParticleSystem
>();
...
...
@@ -701,6 +695,13 @@ public class LoadSFX : MonoBehaviour
yield
return
new
WaitForSeconds
(
time
);
if
(
type
==
"FUSION"
)
BlackBehaviour
.
FadeIn
(
0.25f
);
if
(
materials
.
Count
>
2
)
SEHandler
.
Play
(
"SE_DUEL/SE_SMN_CMN_CARD_02"
);
else
SEHandler
.
Play
(
"SE_DUEL/SE_SMN_CMN_CARD_01"
);
ms
.
SetActive
(
true
);
ms
.
transform
.
GetChild
(
0
).
GetComponent
<
PlayableDirector
>().
Play
();
Destroy
(
ms
,
2f
);
...
...
Assets/MD/Scripts/VoiceHandler.cs
View file @
41919acf
...
...
@@ -53,7 +53,7 @@ public class VoiceHandler : MonoBehaviour
}
}
public
static
bool
PlayCardLine
(
uint
controller
,
string
type
,
int
card
,
bool
sleep
,
bool
firstOnField
=
true
,
uint
location
=
(
uint
)
CardLocation
.
Onfield
,
int
chain
=
1
)
public
static
bool
PlayCardLine
(
uint
controller
,
string
type
,
int
card
,
bool
sleep
,
bool
firstOnField
=
true
,
uint
location
=
(
uint
)
CardLocation
.
Onfield
,
int
chain
=
1
,
bool
summonline
=
false
)
{
if
(!
Program
.
I
().
setting
.
setting
.
Vxyz
.
value
)
{
...
...
@@ -103,7 +103,12 @@ public class VoiceHandler : MonoBehaviour
if
(
clip
!=
null
)
{
if
(
type
==
"summon"
)
{
if
(
summonline
)
PlayGroup
(
controller
,
clip
,
sleep
,
onlyPlayOne
,
hand
,
true
,
card
);
else
PlayGroup
(
controller
,
clip
,
sleep
,
onlyPlayOne
,
hand
,
true
);
}
else
PlayGroup
(
controller
,
clip
,
sleep
,
onlyPlayOne
,
hand
,
false
);
return
true
;
...
...
@@ -112,15 +117,35 @@ public class VoiceHandler : MonoBehaviour
return
false
;
}
static
void
PlayGroup
(
uint
controller
,
AudioClip
clip0
,
bool
sleep
,
bool
onlyPlayOne
=
false
,
bool
hand
=
false
,
bool
summon
=
false
)
static
void
PlayGroup
(
uint
controller
,
AudioClip
clip0
,
bool
sleep
,
bool
onlyPlayOne
=
false
,
bool
hand
=
false
,
bool
summon
=
false
,
int
card
=
0
)
{
AudioClip
clip
=
clip0
;
List
<
AudioClip
>
audioClips
=
new
List
<
AudioClip
>();
if
(
hand
)
{
var
clipFromHand
=
GetClipFromAB
(
controller
,
clip0
.
name
.
Substring
(
0
,
6
)
+
"07_00_00_0"
);
audioClips
.
Add
(
clipFromHand
);
}
AudioClip
clip
=
clip0
;
if
(
card
!=
0
)
{
int
voiceId
=
VoiceMap
.
Map
(
clip0
.
name
.
Substring
(
0
,
5
),
"summonline"
,
card
,
true
,
(
uint
)
CardLocation
.
Onfield
,
1
);
if
(
voiceId
>=
0
)
{
string
sl
=
""
;
if
(
voiceId
>
9
)
sl
=
clip0
.
name
.
Substring
(
0
,
5
)
+
"_37_00_"
+
voiceId
+
"_0"
;
if
(
voiceId
<=
9
)
sl
=
clip0
.
name
.
Substring
(
0
,
5
)
+
"_37_00_0"
+
voiceId
+
"_0"
;
AudioClip
clipSL
=
GetClipFromAB
(
controller
,
sl
);
int
k
=
0
;
while
(
clipSL
!=
null
)
{
audioClips
.
Add
(
clipSL
);
k
++;
clipSL
=
GetClipFromAB
(
controller
,
clipSL
.
name
.
Substring
(
0
,
15
)
+
k
);
}
}
}
audioClips
.
Add
(
clip
);
if
(!
onlyPlayOne
)
{
...
...
@@ -520,6 +545,10 @@ public class VoiceHandler : MonoBehaviour
return
"_07_13_00_0"
;
case
"ActivatePendulum"
:
return
"_07_14_00_0"
;
case
"ActivateEffects"
:
return
"_08_00_00_0"
;
case
"ActivateMonsterEffects"
:
return
"_09_00_00_0"
;
case
"PreSummon"
:
return
"_10_00_00_0"
;
case
"Summon"
:
...
...
@@ -544,6 +573,8 @@ public class VoiceHandler : MonoBehaviour
return
"_11_09_00_0"
;
case
"LinkSummon"
:
return
"_11_10_00_0"
;
case
"SummonMonsters"
:
return
"_13_10_00_0"
;
case
"BattlePhase"
:
return
"_14_00_00_0"
;
case
"PreAttack"
:
...
...
@@ -554,6 +585,8 @@ public class VoiceHandler : MonoBehaviour
return
"_17_00_00_0"
;
case
"DirectAttack"
:
return
"_18_00_00_0"
;
case
"MonstersAttack"
:
return
"_19_00_00_0"
;
case
"SetCard"
:
return
"_20_00_00_0"
;
case
"SetMonster"
:
...
...
@@ -590,8 +623,28 @@ public class VoiceHandler : MonoBehaviour
return
"_35_00_00_0"
;
case
"Tag"
:
return
"_36_00_00_0"
;
case
"SummonLine"
:
case
"SummonLine
s
"
:
return
"_37_00_00_0"
;
case
"RidingDuel"
:
return
"_38_00_00_0"
;
case
"CoinEffect"
:
return
"_39_00_00_0"
;
case
"CoinEffect2"
:
return
"_40_00_00_0"
;
case
"PreDimensionDuel"
:
return
"_41_00_00_0"
;
case
"DimensionDuel"
:
return
"_42_00_00_0"
;
case
"HenShinn"
:
return
"_43_00_00_0"
;
case
"ActionDuel"
:
return
"_44_00_00_0"
;
case
"ActionCard"
:
return
"_45_00_00_0"
;
case
"Reincarnation"
:
return
"_46_00_00_0"
;
case
"AfterReincarnation"
:
return
"_47_00_00_0"
;
}
}
...
...
Assets/MD/Scripts/VoiceMap.cs
View file @
41919acf
...
...
@@ -147,6 +147,49 @@ public class VoiceMap : MonoBehaviour
return
Random
.
Range
(
0
,
2
);
}
return
V0501
(
"summon"
,
card
)
+
1
;
case
"summonline"
:
switch
(
card
)
{
case
16178681
:
return
0
;
case
53025096
:
return
1
;
case
19221310
:
return
2
;
case
21770839
:
return
3
;
case
83347294
:
return
4
;
case
72378329
:
return
5
;
case
88305705
:
return
6
;
case
1516510
:
return
7
;
case
82044279
:
return
8
;
case
41209827
:
return
9
;
case
16195942
:
return
10
;
case
1621413
:
return
11
;
case
86238081
:
return
12
;
case
45627618
:
return
13
;
case
45014450
:
return
14
;
case
58074177
:
return
15
;
case
16306932
:
return
16
;
case
59123194
:
return
17
;
case
80896940
:
return
18
;
}
break
;
case
"activate"
:
switch
(
card
)
{
...
...
Assets/SibylSystem/Ocgcore/OCGobjects/gameCard.cs
View file @
41919acf
...
...
@@ -905,7 +905,7 @@ public class gameCard : OCGobject
((
p_moveBefore
.
location
&
(
uint
)
CardLocation
.
Extra
)
>
0
||
LoadSFX
.
spType
==
"RITUAL"
)
)
{
if
(!
VoiceHandler
.
PlayCardLine
(
p
.
controller
,
"summon"
,
data
.
Alias
==
0
?
data
.
Id
:
data
.
Alias
,
false
))
if
(!
VoiceHandler
.
PlayCardLine
(
p
.
controller
,
"summon"
,
data
.
Alias
==
0
?
data
.
Id
:
data
.
Alias
,
false
,
true
,
12
,
1
,
true
))
{
if
(
LoadSFX
.
spType
==
"RITUAL"
)
VoiceHandler
.
PlayFixedLine
(
p
.
controller
,
"RitualSummon"
,
false
);
...
...
@@ -918,28 +918,37 @@ public class gameCard : OCGobject
else
if
(
LoadSFX
.
spType
==
"LINK"
)
VoiceHandler
.
PlayFixedLine
(
p
.
controller
,
"LinkSummon"
,
false
);
}
//主程序暂停
Program
.
I
().
ocgcore
.
Sleep
(
showUnlitCardFrames
+
summonFrames1
+
cutinFrames
+
(
int
)(
landTime
*
60
)
-
12
);
//卡片延时移动
TweenTo
(
gived_position
,
gived_rotation
,
(
showUnlitCardFrames
+
summonFrames1
+
cutinFrames
)/
60f
,
landTime
);
//卡片延时动画
gameObject
.
GetComponent
<
CardAnimation
>().
position
=
p
.
position
;
gameObject
.
GetComponent
<
CardAnimation
>().
bigLanding
=
true
;
gameObject
.
GetComponent
<
CardAnimation
>().
cutin
=
true
;
gameObject
.
GetComponent
<
CardAnimation
>().
summon
=
true
;
gameObject
.
GetComponent
<
CardAnimation
>().
landTime
=
landTime
;
gameObject
.
GetComponent
<
CardAnimation
>().
type
=
LoadSFX
.
spType
;
gameObject
.
GetComponent
<
CardAnimation
>().
CardLanding
(
get_data
().
Level
);
//加载素材动画
if
(
VoiceHandler
.
voiceTime
<=
(
showUnlitCardFrames
+
summonFrames1
+
cutinFrames
+
(
int
)(
landTime
*
60
)
-
12
)
/
60f
)
{
Program
.
I
().
ocgcore
.
Sleep
(
showUnlitCardFrames
+
summonFrames1
+
cutinFrames
+
(
int
)(
landTime
*
60
)
-
12
);
TweenTo
(
gived_position
,
gived_rotation
,
(
showUnlitCardFrames
+
summonFrames1
+
cutinFrames
)
/
60f
,
landTime
);
ls
.
MaterialShow
(
0
,
true
,
landTime
,
this
);
//加载summon动画
ls
.
SummonAnimation
(
showUnlitCardFrames
/
60f
,
this
);
ls
.
SummonAnimation
(
showUnlitCardFrames
/
60f
,
this
);
gameObject
.
GetComponent
<
CardAnimation
>().
CardLanding
(
get_data
().
Level
);
}
else
{
float
extraDelay
=
VoiceHandler
.
voiceTime
-
(
showUnlitCardFrames
+
summonFrames1
+
cutinFrames
+
(
int
)(
landTime
*
60
)
-
12
)
/
60f
;
Program
.
I
().
ocgcore
.
Sleep
((
int
)(
extraDelay
*
60
)
+
showUnlitCardFrames
+
summonFrames1
+
cutinFrames
+
(
int
)(
landTime
*
60
)
-
12
);
TweenTo
(
gived_position
,
gived_rotation
,
extraDelay
+
(
showUnlitCardFrames
+
summonFrames1
+
cutinFrames
)
/
60f
,
landTime
);
ls
.
MaterialShow
(
extraDelay
,
true
,
landTime
,
this
);
ls
.
SummonAnimation
(
extraDelay
+
showUnlitCardFrames
/
60f
,
this
);
gameObject
.
GetComponent
<
CardAnimation
>().
CardLanding
(
get_data
().
Level
,
extraDelay
);
}
}
else
//仅有Cutin动画
{
if
(!
VoiceHandler
.
PlayCardLine
(
p
.
controller
,
"summon"
,
data
.
Alias
==
0
?
data
.
Id
:
data
.
Alias
,
false
))
bool
summonline
=
true
;
if
(
IsExtraCard
())
summonline
=
false
;
if
(!
VoiceHandler
.
PlayCardLine
(
p
.
controller
,
"summon"
,
data
.
Alias
==
0
?
data
.
Id
:
data
.
Alias
,
false
,
true
,
12
,
1
,
summonline
))
{
if
((
p
.
reason
&
(
uint
)
CardReason
.
SPSUMMON
)
>
0
)
VoiceHandler
.
PlayFixedLine
(
p
.
controller
,
"SpecialSummon"
,
false
);
...
...
@@ -983,7 +992,7 @@ public class gameCard : OCGobject
(
p
.
position
&
(
uint
)
CardPosition
.
FaceUp
)
>
0
)
{
if
(!
VoiceHandler
.
PlayCardLine
(
p
.
controller
,
"summon"
,
data
.
Alias
==
0
?
data
.
Id
:
data
.
Alias
,
false
))
if
(!
VoiceHandler
.
PlayCardLine
(
p
.
controller
,
"summon"
,
data
.
Alias
==
0
?
data
.
Id
:
data
.
Alias
,
false
,
true
,
12
,
1
,
true
))
{
if
(
LoadSFX
.
spType
==
"RITUAL"
)
VoiceHandler
.
PlayFixedLine
(
p
.
controller
,
"RitualSummon"
,
false
);
...
...
@@ -996,23 +1005,30 @@ public class gameCard : OCGobject
else
if
(
LoadSFX
.
spType
==
"LINK"
)
VoiceHandler
.
PlayFixedLine
(
p
.
controller
,
"LinkSummon"
,
false
);
}
//主程序暂停
Program
.
I
().
ocgcore
.
Sleep
(
showUnlitCardFrames
+
summonFrames2
+
(
int
)(
landTime
*
60
)
-
12
);
//卡片延时移动
TweenTo
(
gived_position
,
gived_rotation
,
(
showUnlitCardFrames
+
summonFrames2
)
/
60f
,
landTime
);
//卡片延时动画
gameObject
.
GetComponent
<
CardAnimation
>().
position
=
p
.
position
;
gameObject
.
GetComponent
<
CardAnimation
>().
bigLanding
=
true
;
gameObject
.
GetComponent
<
CardAnimation
>().
summon
=
true
;
gameObject
.
GetComponent
<
CardAnimation
>().
landTime
=
landTime
;
gameObject
.
GetComponent
<
CardAnimation
>().
type
=
LoadSFX
.
spType
;
if
(
VoiceHandler
.
voiceTime
<=
(
showUnlitCardFrames
+
summonFrames2
+
(
int
)(
landTime
*
60
)
-
12
)
/
60f
)
{
Program
.
I
().
ocgcore
.
Sleep
(
showUnlitCardFrames
+
summonFrames2
+
(
int
)(
landTime
*
60
)
-
12
);
TweenTo
(
gived_position
,
gived_rotation
,
(
showUnlitCardFrames
+
summonFrames2
)
/
60f
,
landTime
);
ls
.
MaterialShow
(
0
,
true
,
landTime
,
this
);
ls
.
SummonAnimation
(
showUnlitCardFrames
/
60f
,
this
);
gameObject
.
GetComponent
<
CardAnimation
>().
CardLanding
(
get_data
().
Level
);
}
else
{
float
extraDelay
=
VoiceHandler
.
voiceTime
-
(
showUnlitCardFrames
+
summonFrames2
+
(
int
)(
landTime
*
60
)
-
12
)
/
60f
;
Program
.
I
().
ocgcore
.
Sleep
((
int
)(
extraDelay
*
60
)
+
showUnlitCardFrames
+
summonFrames2
+
(
int
)(
landTime
*
60
)
-
12
);
TweenTo
(
gived_position
,
gived_rotation
,
extraDelay
+
(
showUnlitCardFrames
+
summonFrames2
)
/
60f
,
landTime
);
ls
.
MaterialShow
(
extraDelay
,
true
,
landTime
,
this
);
ls
.
SummonAnimation
(
extraDelay
+
showUnlitCardFrames
/
60f
,
this
);
gameObject
.
GetComponent
<
CardAnimation
>().
CardLanding
(
get_data
().
Level
,
extraDelay
);
}
//加载素材动画
ls
.
MaterialShow
(
0
,
false
,
landTime
,
this
);
//加载summon动画
ls
.
SummonAnimation
(
showUnlitCardFrames
/
60f
,
this
);
}
//是否需要BigLanding
else
if
(
...
...
@@ -1030,7 +1046,10 @@ public class gameCard : OCGobject
&&
!
Ocgcore
.
inSkiping
)
{
if
(!
VoiceHandler
.
PlayCardLine
(
p
.
controller
,
"summon"
,
data
.
Alias
==
0
?
data
.
Id
:
data
.
Alias
,
false
))
bool
summonline
=
true
;
if
(
IsExtraCard
())
summonline
=
false
;
if
(!
VoiceHandler
.
PlayCardLine
(
p
.
controller
,
"summon"
,
data
.
Alias
==
0
?
data
.
Id
:
data
.
Alias
,
false
,
true
,
12
,
1
,
summonline
))
{
if
((
p
.
reason
&
(
uint
)
CardReason
.
SPSUMMON
)
>
0
)
VoiceHandler
.
PlayFixedLine
(
p
.
controller
,
"SpecialSummon"
,
false
);
...
...
@@ -1060,7 +1079,10 @@ public class gameCard : OCGobject
&&
!
Ocgcore
.
inSkiping
)
{
if
(!
VoiceHandler
.
PlayCardLine
(
p
.
controller
,
"summon"
,
data
.
Alias
==
0
?
data
.
Id
:
data
.
Alias
,
false
))
bool
summonline
=
true
;
if
(
IsExtraCard
())
summonline
=
false
;
if
(!
VoiceHandler
.
PlayCardLine
(
p
.
controller
,
"summon"
,
data
.
Alias
==
0
?
data
.
Id
:
data
.
Alias
,
false
,
true
,
12
,
1
,
summonline
))
{
if
((
p
.
reason
&
(
uint
)
CardReason
.
SPSUMMON
)
>
0
)
VoiceHandler
.
PlayFixedLine
(
p
.
controller
,
"SpecialSummon"
,
false
);
...
...
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