Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
D
dap-hu
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vũ Gia Vương
dap-hu
Commits
b13dc8a7
Commit
b13dc8a7
authored
Apr 29, 2025
by
Vũ Gia Vương
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update shake behind fragment
parent
de9d9ed7
Changes
7
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
426 additions
and
364 deletions
+426
-364
main.fire
assets/main.fire
+352
-338
Events.ts
assets/scripts/Events.ts
+2
-1
BehindFragment.ts
assets/scripts/GamePlay/BehindFragment.ts
+15
-1
BreakingBottleController.ts
assets/scripts/GamePlay/BreakingBottleController.ts
+2
-2
BreakingJarController.ts
assets/scripts/GamePlay/BreakingJarController.ts
+22
-10
FragmentController.ts
assets/scripts/GamePlay/FragmentController.ts
+2
-2
FragmentJarController.ts
assets/scripts/GamePlay/FragmentJarController.ts
+31
-10
No files found.
assets/main.fire
View file @
b13dc8a7
This diff is collapsed.
Click to expand it.
assets/scripts/Events.ts
View file @
b13dc8a7
...
@@ -26,6 +26,7 @@ export const CHECK_FRAGMENT = 'CHECK_FRAGMENT';
...
@@ -26,6 +26,7 @@ export const CHECK_FRAGMENT = 'CHECK_FRAGMENT';
export
const
HAMMER
=
'HAMMER'
;
export
const
HAMMER
=
'HAMMER'
;
export
const
RESET_BOTTLE
=
'RESET_BOTTLE'
;
export
const
RESET_BOTTLE
=
'RESET_BOTTLE'
;
export
const
RESET_FRAGMENT
=
'RESET_FRAGMENT'
;
export
const
RESET_FRAGMENT
=
'RESET_FRAGMENT'
;
export
const
DROP_FRAGMENT
=
'DROP_FRAGMENT'
;
export
const
DROP_ALL_FRAGMENT
=
'DROP_ALL_FRAGMENT'
;
export
const
DROP_TOP_FRAGMENT
=
'DROP_TOP_FRAGMENT'
;
export
const
DROP_BEHIND_FRAGMENT
=
'DROP_BEHIND_FRAGMENT'
;
export
const
DROP_BEHIND_FRAGMENT
=
'DROP_BEHIND_FRAGMENT'
;
export
const
SHAKE_FRAGMENT
=
'SHAKE_FRAGMENT'
;
export
const
SHAKE_FRAGMENT
=
'SHAKE_FRAGMENT'
;
\ No newline at end of file
assets/scripts/GamePlay/BehindFragment.ts
View file @
b13dc8a7
import
{
eventTarget
,
RESET_FRAGMENT
}
from
"../Events"
;
import
{
eventTarget
,
RESET_FRAGMENT
,
SHAKE_FRAGMENT
}
from
"../Events"
;
const
{
ccclass
,
property
}
=
cc
.
_decorator
;
const
{
ccclass
,
property
}
=
cc
.
_decorator
;
...
@@ -7,6 +7,7 @@ const { ccclass, property } = cc._decorator;
...
@@ -7,6 +7,7 @@ const { ccclass, property } = cc._decorator;
export
default
class
BehindFragment
extends
cc
.
Component
{
export
default
class
BehindFragment
extends
cc
.
Component
{
private
_rg
:
cc
.
RigidBody
=
null
;
private
_rg
:
cc
.
RigidBody
=
null
;
private
_physicsCollider
:
cc
.
PhysicsCollider
=
null
;
private
_physicsCollider
:
cc
.
PhysicsCollider
=
null
;
private
_isDropped
:
boolean
=
false
;
onLoad
()
{
onLoad
()
{
this
.
_rg
=
this
.
node
.
getComponent
(
cc
.
RigidBody
);
this
.
_rg
=
this
.
node
.
getComponent
(
cc
.
RigidBody
);
...
@@ -15,9 +16,22 @@ export default class BehindFragment extends cc.Component {
...
@@ -15,9 +16,22 @@ export default class BehindFragment extends cc.Component {
this
.
_physicsCollider
.
enabled
=
false
;
this
.
_physicsCollider
.
enabled
=
false
;
eventTarget
.
on
(
RESET_FRAGMENT
,
this
.
reset
,
this
);
eventTarget
.
on
(
RESET_FRAGMENT
,
this
.
reset
,
this
);
eventTarget
.
on
(
SHAKE_FRAGMENT
,
this
.
shakeFragment
,
this
);
}
public
shakeFragment
()
{
if
(
this
.
_isDropped
)
{
return
;
}
}
cc
.
tween
(
this
.
node
)
.
repeat
(
2
,
cc
.
tween
(
this
.
node
)
.
by
(
0.05
,
{
position
:
cc
.
v3
(
-
10
,
-
10
)
})
.
by
(
0.05
,
{
position
:
cc
.
v3
(
10
,
10
)
})
)
.
start
();
}
public
onDrop
()
{
public
onDrop
()
{
this
.
_isDropped
=
true
;
this
.
scheduleOnce
(()
=>
{
this
.
scheduleOnce
(()
=>
{
this
.
_rg
.
type
=
cc
.
RigidBodyType
.
Dynamic
;
this
.
_rg
.
type
=
cc
.
RigidBodyType
.
Dynamic
;
this
.
_rg
.
gravityScale
=
10
;
this
.
_rg
.
gravityScale
=
10
;
...
...
assets/scripts/GamePlay/BreakingBottleController.ts
View file @
b13dc8a7
import
{
BEAT_GUILD
,
CHECK_FRAGMENT
,
CHECK_TOUCH
,
DROP_FRAGMENT
,
eventTarget
,
HAMMER
,
RESET_BOTTLE
,
RESET_FRAGMENT
,
SHOW_CARD_POPUP
,
STOP_GUILD_TAP
}
from
"../Events"
;
import
{
BEAT_GUILD
,
CHECK_FRAGMENT
,
CHECK_TOUCH
,
DROP_
ALL_
FRAGMENT
,
eventTarget
,
HAMMER
,
RESET_BOTTLE
,
RESET_FRAGMENT
,
SHOW_CARD_POPUP
,
STOP_GUILD_TAP
}
from
"../Events"
;
import
{
Global
}
from
"../Global"
;
import
{
Global
}
from
"../Global"
;
import
FragmentController
from
"./FragmentController"
;
import
FragmentController
from
"./FragmentController"
;
...
@@ -87,7 +87,7 @@ export default class BreakingBottleController extends cc.Component {
...
@@ -87,7 +87,7 @@ export default class BreakingBottleController extends cc.Component {
this
.
_isEnd
=
true
;
this
.
_isEnd
=
true
;
}
}
if
(
this
.
_bodyFragments
.
length
==
6
)
{
if
(
this
.
_bodyFragments
.
length
==
6
)
{
eventTarget
.
emit
(
DROP_FRAGMENT
);
eventTarget
.
emit
(
DROP_
ALL_
FRAGMENT
);
}
}
}
}
...
...
assets/scripts/GamePlay/BreakingJarController.ts
View file @
b13dc8a7
import
{
BEAT_GUILD
,
CHECK_FRAGMENT
,
CHECK_TOUCH
,
eventTarget
,
HAMMER
,
RESET_BOTTLE
,
RESET_FRAGMENT
,
SHAKE_FRAGMENT
,
SHOW_CARD_POPUP
,
STOP_GUILD_TAP
}
from
"../Events"
;
import
{
BEAT_GUILD
,
CHECK_FRAGMENT
,
CHECK_TOUCH
,
DROP_TOP_FRAGMENT
,
eventTarget
,
HAMMER
,
RESET_BOTTLE
,
RESET_FRAGMENT
,
SHAKE_FRAGMENT
,
SHOW_CARD_POPUP
,
STOP_GUILD_TAP
}
from
"../Events"
;
import
{
Global
}
from
"../Global"
;
import
{
Global
}
from
"../Global"
;
import
BehindFragment
from
"./BehindFragment"
;
import
BehindFragment
from
"./BehindFragment"
;
import
FragmentJarController
from
"./FragmentJarController"
;
import
FragmentJarController
from
"./FragmentJarController"
;
...
@@ -7,7 +7,8 @@ const { ccclass, property } = cc._decorator;
...
@@ -7,7 +7,8 @@ const { ccclass, property } = cc._decorator;
@
ccclass
@
ccclass
export
default
class
BreakingJarController
extends
cc
.
Component
{
export
default
class
BreakingJarController
extends
cc
.
Component
{
@
property
([
cc
.
Node
])
private
fragmentSpecialNodes
:
cc
.
Node
[]
=
[];
@
property
(
cc
.
Node
)
@
property
(
cc
.
Node
)
private
hammerNode
:
cc
.
Node
=
null
;
private
hammerNode
:
cc
.
Node
=
null
;
@
property
(
cc
.
Node
)
@
property
(
cc
.
Node
)
...
@@ -18,7 +19,7 @@ export default class BreakingJarController extends cc.Component {
...
@@ -18,7 +19,7 @@ export default class BreakingJarController extends cc.Component {
private
_countFragment
=
0
;
private
_countFragment
=
0
;
private
_fragmentsPosition
:
cc
.
Vec3
[]
=
[];
private
_fragmentsPosition
:
cc
.
Vec3
[]
=
[];
private
_f
ragmentsNode
:
cc
.
Node
[]
=
[];
private
_f
ontFragments
:
cc
.
Node
[]
=
[];
private
_bodyFragments
:
string
[]
=
[];
private
_bodyFragments
:
string
[]
=
[];
private
_isEnd
=
false
;
private
_isEnd
=
false
;
private
_behindJarChild
:
BehindFragment
[]
=
[];
private
_behindJarChild
:
BehindFragment
[]
=
[];
...
@@ -41,8 +42,8 @@ export default class BreakingJarController extends cc.Component {
...
@@ -41,8 +42,8 @@ export default class BreakingJarController extends cc.Component {
eventTarget
.
on
(
RESET_BOTTLE
,
this
.
resetBottle
,
this
);
eventTarget
.
on
(
RESET_BOTTLE
,
this
.
resetBottle
,
this
);
eventTarget
.
on
(
BEAT_GUILD
,
this
.
beatGuild
,
this
);
eventTarget
.
on
(
BEAT_GUILD
,
this
.
beatGuild
,
this
);
this
.
_f
ragmentsNode
=
this
.
getComponentsInChildren
(
FragmentJarController
).
map
(
item
=>
item
.
node
);
this
.
_f
ontFragments
=
this
.
getComponentsInChildren
(
FragmentJarController
).
map
(
item
=>
item
.
node
);
this
.
_fragmentsPosition
=
this
.
_f
ragmentsNode
.
map
(
item
=>
item
.
position
.
clone
());
this
.
_fragmentsPosition
=
this
.
_f
ontFragments
.
map
(
item
=>
item
.
position
.
clone
());
this
.
_behindJarChild
=
this
.
behindJar
.
children
.
map
(
item
=>
item
.
getComponent
(
BehindFragment
));
this
.
_behindJarChild
=
this
.
behindJar
.
children
.
map
(
item
=>
item
.
getComponent
(
BehindFragment
));
this
.
_behindJarChildPosition
=
this
.
behindJar
.
children
.
map
(
item
=>
item
.
position
.
clone
());
this
.
_behindJarChildPosition
=
this
.
behindJar
.
children
.
map
(
item
=>
item
.
position
.
clone
());
}
}
...
@@ -60,7 +61,7 @@ export default class BreakingJarController extends cc.Component {
...
@@ -60,7 +61,7 @@ export default class BreakingJarController extends cc.Component {
this
.
_bodyFragments
=
[];
this
.
_bodyFragments
=
[];
this
.
_spine
.
setSkin
(
this
.
_skins
[
Global
.
tool
%
this
.
_skins
.
length
]);
this
.
_spine
.
setSkin
(
this
.
_skins
[
Global
.
tool
%
this
.
_skins
.
length
]);
this
.
_f
ragmentsNode
.
forEach
((
node
,
index
)
=>
{
this
.
_f
ontFragments
.
forEach
((
node
,
index
)
=>
{
node
.
position
=
this
.
_fragmentsPosition
[
index
];
node
.
position
=
this
.
_fragmentsPosition
[
index
];
})
})
...
@@ -89,7 +90,7 @@ export default class BreakingJarController extends cc.Component {
...
@@ -89,7 +90,7 @@ export default class BreakingJarController extends cc.Component {
private
shakeNode
()
{
private
shakeNode
()
{
cc
.
director
.
getPhysicsManager
().
enabled
=
false
;
cc
.
director
.
getPhysicsManager
().
enabled
=
false
;
eventTarget
.
emit
(
SHAKE_FRAGMENT
)
eventTarget
.
emit
(
SHAKE_FRAGMENT
)
;
cc
.
tween
(
this
.
node
)
cc
.
tween
(
this
.
node
)
.
delay
(
0.15
)
.
delay
(
0.15
)
.
call
(()
=>
cc
.
director
.
getPhysicsManager
().
enabled
=
true
)
.
call
(()
=>
cc
.
director
.
getPhysicsManager
().
enabled
=
true
)
...
@@ -97,8 +98,8 @@ export default class BreakingJarController extends cc.Component {
...
@@ -97,8 +98,8 @@ export default class BreakingJarController extends cc.Component {
}
}
private
checkFragment
(
fragmentNode
:
cc
.
Node
)
{
private
checkFragment
(
fragmentNode
:
cc
.
Node
)
{
const
f
ragmentIndex
=
this
.
_fragmentsNode
.
findIndex
(
item
=>
item
===
fragmentNode
);
const
f
ontFragment
=
this
.
_fontFragments
.
findIndex
(
item
=>
item
===
fragmentNode
);
const
behindFragment
=
this
.
_behindJarChild
[
f
ragmentIndex
];
const
behindFragment
=
this
.
_behindJarChild
[
f
ontFragment
];
behindFragment
.
onDrop
();
behindFragment
.
onDrop
();
if
(
this
.
_isEnd
)
{
if
(
this
.
_isEnd
)
{
...
@@ -107,9 +108,20 @@ export default class BreakingJarController extends cc.Component {
...
@@ -107,9 +108,20 @@ export default class BreakingJarController extends cc.Component {
this
.
_bodyFragments
.
push
(
fragmentNode
.
name
);
this
.
_bodyFragments
.
push
(
fragmentNode
.
name
);
this
.
_countFragment
++
;
this
.
_countFragment
++
;
if
(
this
.
_countFragment
==
8
)
{
if
(
this
.
_countFragment
==
9
)
{
console
.
log
(
'this._countFragment'
,
this
.
_countFragment
)
this
.
scheduleOnce
(()
=>
eventTarget
.
emit
(
SHOW_CARD_POPUP
),
1.5
);
this
.
scheduleOnce
(()
=>
eventTarget
.
emit
(
SHOW_CARD_POPUP
),
1.5
);
this
.
_isEnd
=
true
;
this
.
_isEnd
=
true
;
return
;
}
const
isSpecial
=
this
.
fragmentSpecialNodes
.
some
(
item
=>
item
===
fragmentNode
);
const
isDropTop
=
this
.
fragmentSpecialNodes
.
every
(
item
=>
item
.
getComponent
(
FragmentJarController
).
isDropped
);
if
(
isSpecial
&&
isDropTop
)
{
console
.
log
(
'this._countFragment'
,
this
.
_countFragment
)
eventTarget
.
emit
(
DROP_TOP_FRAGMENT
);
}
}
}
}
...
...
assets/scripts/GamePlay/FragmentController.ts
View file @
b13dc8a7
import
{
eventTarget
,
CHECK_TOUCH
,
CHECK_FRAGMENT
,
HAMMER
,
RESET_FRAGMENT
,
PLAY_DROP_SOUND
,
DROP_FRAGMENT
}
from
"../Events"
;
import
{
eventTarget
,
CHECK_TOUCH
,
CHECK_FRAGMENT
,
HAMMER
,
RESET_FRAGMENT
,
PLAY_DROP_SOUND
,
DROP_
ALL_
FRAGMENT
}
from
"../Events"
;
const
{
ccclass
,
property
}
=
cc
.
_decorator
;
const
{
ccclass
,
property
}
=
cc
.
_decorator
;
...
@@ -22,7 +22,7 @@ export default class FragmentController extends cc.Component {
...
@@ -22,7 +22,7 @@ export default class FragmentController extends cc.Component {
eventTarget
.
on
(
CHECK_TOUCH
,
this
.
checkTouch
,
this
);
eventTarget
.
on
(
CHECK_TOUCH
,
this
.
checkTouch
,
this
);
eventTarget
.
on
(
RESET_FRAGMENT
,
this
.
reset
,
this
);
eventTarget
.
on
(
RESET_FRAGMENT
,
this
.
reset
,
this
);
eventTarget
.
on
(
DROP_FRAGMENT
,
()
=>
this
.
node
.
name
.
includes
(
'nap'
)
&&
this
.
dropFragment
(),
this
);
eventTarget
.
on
(
DROP_
ALL_
FRAGMENT
,
()
=>
this
.
node
.
name
.
includes
(
'nap'
)
&&
this
.
dropFragment
(),
this
);
}
}
public
reset
()
{
public
reset
()
{
...
...
assets/scripts/GamePlay/FragmentJarController.ts
View file @
b13dc8a7
import
{
CHECK_FRAGMENT
,
CHECK_TOUCH
,
DROP_FRAGMENT
,
eventTarget
,
HAMMER
,
PLAY_DROP_SOUND
,
RESET_FRAGMENT
,
SHAKE_FRAGMENT
}
from
"../Events"
;
import
{
CHECK_FRAGMENT
,
CHECK_TOUCH
,
DROP_
ALL_FRAGMENT
,
DROP_TOP_
FRAGMENT
,
eventTarget
,
HAMMER
,
PLAY_DROP_SOUND
,
RESET_FRAGMENT
,
SHAKE_FRAGMENT
}
from
"../Events"
;
const
{
ccclass
,
property
}
=
cc
.
_decorator
;
const
{
ccclass
,
property
}
=
cc
.
_decorator
;
...
@@ -9,11 +9,12 @@ export default class FragmentJarController extends cc.Component {
...
@@ -9,11 +9,12 @@ export default class FragmentJarController extends cc.Component {
@
property
@
property
private
isBottom
:
boolean
=
false
;
private
isBottom
:
boolean
=
false
;
public
isDropped
:
boolean
=
false
;
private
_physicsCollider
:
cc
.
PhysicsPolygonCollider
=
null
;
private
_physicsCollider
:
cc
.
PhysicsPolygonCollider
=
null
;
private
_physicsColliderFragmentLink
:
cc
.
PhysicsPolygonCollider
=
null
;
private
_physicsColliderFragmentLink
:
cc
.
PhysicsPolygonCollider
=
null
;
private
_rg
:
cc
.
RigidBody
=
null
;
private
_rg
:
cc
.
RigidBody
=
null
;
private
_siblingIndex
:
number
=
0
;
private
_siblingIndex
:
number
=
0
;
private
_isDropped
:
boolean
=
false
;
private
_numberOfBeats
=
3
;
private
_numberOfBeats
=
3
;
private
_slots
:
cc
.
Node
[]
=
[];
private
_slots
:
cc
.
Node
[]
=
[];
...
@@ -29,7 +30,8 @@ export default class FragmentJarController extends cc.Component {
...
@@ -29,7 +30,8 @@ export default class FragmentJarController extends cc.Component {
eventTarget
.
on
(
CHECK_TOUCH
,
this
.
checkTouch
,
this
);
eventTarget
.
on
(
CHECK_TOUCH
,
this
.
checkTouch
,
this
);
eventTarget
.
on
(
RESET_FRAGMENT
,
this
.
reset
,
this
);
eventTarget
.
on
(
RESET_FRAGMENT
,
this
.
reset
,
this
);
eventTarget
.
on
(
DROP_FRAGMENT
,
()
=>
this
.
node
.
name
.
includes
(
'nap'
)
&&
this
.
dropFragment
(),
this
);
eventTarget
.
on
(
DROP_ALL_FRAGMENT
,
this
.
dropFragment
,
this
);
eventTarget
.
on
(
DROP_TOP_FRAGMENT
,
this
.
dropFragmentTop
,
this
);
eventTarget
.
on
(
SHAKE_FRAGMENT
,
this
.
shakeFragment
,
this
);
eventTarget
.
on
(
SHAKE_FRAGMENT
,
this
.
shakeFragment
,
this
);
}
}
...
@@ -38,15 +40,16 @@ export default class FragmentJarController extends cc.Component {
...
@@ -38,15 +40,16 @@ export default class FragmentJarController extends cc.Component {
this
.
_rg
.
type
=
cc
.
RigidBodyType
.
Static
;
this
.
_rg
.
type
=
cc
.
RigidBodyType
.
Static
;
this
.
node
.
angle
=
0
;
this
.
node
.
angle
=
0
;
this
.
node
.
setSiblingIndex
(
this
.
_siblingIndex
);
this
.
node
.
setSiblingIndex
(
this
.
_siblingIndex
);
this
.
_
isDropped
=
false
;
this
.
isDropped
=
false
;
this
.
_numberOfBeats
=
3
;
this
.
_numberOfBeats
=
3
;
this
.
node
.
children
.
forEach
(
slot
=>
slot
.
active
=
false
);
this
.
node
.
children
.
forEach
(
slot
=>
slot
.
active
=
false
);
}
}
public
shakeFragment
()
{
public
shakeFragment
()
{
if
(
this
.
_
isDropped
)
{
if
(
this
.
isDropped
)
{
return
;
return
;
}
}
cc
.
tween
(
this
.
node
)
cc
.
tween
(
this
.
node
)
.
repeat
(
2
,
cc
.
tween
(
this
.
node
)
.
repeat
(
2
,
cc
.
tween
(
this
.
node
)
.
by
(
0.05
,
{
position
:
cc
.
v3
(
-
10
,
-
10
)
})
.
by
(
0.05
,
{
position
:
cc
.
v3
(
-
10
,
-
10
)
})
...
@@ -56,7 +59,7 @@ export default class FragmentJarController extends cc.Component {
...
@@ -56,7 +59,7 @@ export default class FragmentJarController extends cc.Component {
}
}
private
checkTouch
(
point
:
cc
.
Vec2
)
{
private
checkTouch
(
point
:
cc
.
Vec2
)
{
if
(
this
.
_isDropped
||
this
.
isBottom
)
{
if
(
this
.
isDropped
)
{
return
;
return
;
}
}
const
pos
=
point
.
clone
().
subtract
(
cc
.
v2
(
this
.
node
.
position
.
x
,
this
.
node
.
position
.
y
));
const
pos
=
point
.
clone
().
subtract
(
cc
.
v2
(
this
.
node
.
position
.
x
,
this
.
node
.
position
.
y
));
...
@@ -84,13 +87,31 @@ export default class FragmentJarController extends cc.Component {
...
@@ -84,13 +87,31 @@ export default class FragmentJarController extends cc.Component {
}
}
eventTarget
.
emit
(
HAMMER
,
point
);
eventTarget
.
emit
(
HAMMER
,
point
);
if
(
this
.
_numberOfBeats
<=
0
)
{
if
(
this
.
_numberOfBeats
>
0
)
{
return
;
}
if
(
this
.
isBottom
)
{
eventTarget
.
emit
(
DROP_ALL_FRAGMENT
)
return
;
}
this
.
dropFragment
();
this
.
dropFragment
();
}
}
private
dropFragmentTop
()
{
if
(
this
.
isBottom
)
{
return
;
}
this
.
dropFragment
();
}
}
private
dropFragment
()
{
private
dropFragment
()
{
this
.
_isDropped
=
true
;
if
(
this
.
isDropped
)
{
return
;
}
this
.
isDropped
=
true
;
const
pos
=
this
.
node
.
position
;
const
pos
=
this
.
node
.
position
;
eventTarget
.
emit
(
CHECK_FRAGMENT
,
this
.
node
);
eventTarget
.
emit
(
CHECK_FRAGMENT
,
this
.
node
);
...
...
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