Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
ColdShot
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
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
15박보승
ColdShot
Commits
18049a31
Commit
18049a31
authored
Feb 01, 2020
by
15박보승
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implementing weapon system.
parent
d7bdc6ba
Changes
18
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
22077 additions
and
17273 deletions
+22077
-17273
BloodParticleMaterial.mat
Assets/Materials/BloodParticleMaterial.mat
+44
-0
BloodParticleMaterial.mat.meta
Assets/Materials/BloodParticleMaterial.mat.meta
+8
-0
DummyAssaultRifle.asset
Assets/Resources/DummyAssaultRifle.asset
+20
-0
DummyAssaultRifle.asset.meta
Assets/Resources/DummyAssaultRifle.asset.meta
+8
-0
Ingame.unity
Assets/Scenes/Ingame.unity
+21735
-17226
Actor.cs
Assets/Scripts/Actors/Actor.cs
+9
-0
PlayableCharacter.cs
Assets/Scripts/Actors/PlayableCharacter.cs
+56
-33
NodalPathfinding2DAgent.cs
Assets/Scripts/NodalPathfinding/NodalPathfinding2DAgent.cs
+7
-0
PlayerController.cs
Assets/Scripts/PlayerController.cs
+17
-2
Weapon.cs
Assets/Scripts/Weapon.cs
+0
-9
AssaultRifle.cs
Assets/Scripts/Weapons/AssaultRifle.cs
+28
-0
AssaultRifle.cs.meta
Assets/Scripts/Weapons/AssaultRifle.cs.meta
+11
-0
Weapon.cs
Assets/Scripts/Weapons/Weapon.cs
+28
-0
Weapon.cs.meta
Assets/Scripts/Weapons/Weapon.cs.meta
+0
-0
WeaponBehaviour.cs
Assets/Scripts/Weapons/WeaponBehaviour.cs
+92
-0
WeaponBehaviour.cs.meta
Assets/Scripts/Weapons/WeaponBehaviour.cs.meta
+11
-0
Physics2DSettings.asset
ProjectSettings/Physics2DSettings.asset
+1
-1
TagManager.asset
ProjectSettings/TagManager.asset
+2
-2
No files found.
Assets/Materials/BloodParticleMaterial.mat
0 → 100644
View file @
18049a31
%YAML
1.1
%TAG
!u!
tag:unity3d.com,2011:
---
!u!21
&2100000
Material
:
serializedVersion
:
6
m_ObjectHideFlags
:
0
m_CorrespondingSourceObject
:
{
fileID
:
0
}
m_PrefabInstance
:
{
fileID
:
0
}
m_PrefabAsset
:
{
fileID
:
0
}
m_Name
:
BloodParticleMaterial
m_Shader
:
{
fileID
:
10753
,
guid
:
0000000000000000f000000000000000
,
type
:
0
}
m_ShaderKeywords
:
m_LightmapFlags
:
4
m_EnableInstancingVariants
:
0
m_DoubleSidedGI
:
0
m_CustomRenderQueue
:
-1
stringTagMap
:
{}
disabledShaderPasses
:
[]
m_SavedProperties
:
serializedVersion
:
3
m_TexEnvs
:
-
_AlphaTex
:
m_Texture
:
{
fileID
:
0
}
m_Scale
:
{
x
:
1
,
y
:
1
}
m_Offset
:
{
x
:
0
,
y
:
0
}
-
_MainTex
:
m_Texture
:
{
fileID
:
0
}
m_Scale
:
{
x
:
1
,
y
:
1
}
m_Offset
:
{
x
:
0
,
y
:
0
}
-
_MaskTex
:
m_Texture
:
{
fileID
:
0
}
m_Scale
:
{
x
:
1
,
y
:
1
}
m_Offset
:
{
x
:
0
,
y
:
0
}
-
_NormalMap
:
m_Texture
:
{
fileID
:
0
}
m_Scale
:
{
x
:
1
,
y
:
1
}
m_Offset
:
{
x
:
0
,
y
:
0
}
m_Floats
:
-
PixelSnap
:
0
-
_EnableExternalAlpha
:
0
m_Colors
:
-
_Color
:
{
r
:
1
,
g
:
0
,
b
:
0
,
a
:
1
}
-
_Flip
:
{
r
:
1
,
g
:
1
,
b
:
1
,
a
:
1
}
-
_RendererColor
:
{
r
:
1
,
g
:
1
,
b
:
1
,
a
:
1
}
Assets/Materials/BloodParticleMaterial.mat.meta
0 → 100644
View file @
18049a31
fileFormatVersion: 2
guid: a537af3ab109b2b4891f4033f51de915
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
userData:
assetBundleName:
assetBundleVariant:
Assets/Resources/DummyAssaultRifle.asset
0 → 100644
View file @
18049a31
%YAML
1.1
%TAG
!u!
tag:unity3d.com,2011:
---
!u!114
&11400000
MonoBehaviour
:
m_ObjectHideFlags
:
0
m_CorrespondingSourceObject
:
{
fileID
:
0
}
m_PrefabInstance
:
{
fileID
:
0
}
m_PrefabAsset
:
{
fileID
:
0
}
m_GameObject
:
{
fileID
:
0
}
m_Enabled
:
1
m_EditorHideFlags
:
0
m_Script
:
{
fileID
:
11500000
,
guid
:
27849484d6b326e4abb8591c36ef24b4
,
type
:
3
}
m_Name
:
DummyAssaultRifle
m_EditorClassIdentifier
:
shotRange
:
5
shotInterval
:
1
damage
:
10
damageRandomRange
:
1
bulletsPerShot
:
3
bulletInterval
:
0.1
Assets/Resources/DummyAssaultRifle.asset.meta
0 → 100644
View file @
18049a31
fileFormatVersion: 2
guid: 73594f3ebba70a94d92c2cdbf0384f9f
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
userData:
assetBundleName:
assetBundleVariant:
Assets/Scenes/Ingame.unity
View file @
18049a31
This diff is collapsed.
Click to expand it.
Assets/Scripts/Actors/Actor.cs
View file @
18049a31
...
@@ -36,12 +36,21 @@ public abstract class Actor : MonoBehaviour
...
@@ -36,12 +36,21 @@ public abstract class Actor : MonoBehaviour
}
}
set
set
{
{
if
(
_health
>
value
)
hitParticle
.
Play
();
_health
=
value
;
_health
=
value
;
if
(
_health
<=
0
)
gameObject
.
SetActive
(
false
);
}
}
}
}
[
SerializeField
]
protected
ParticleSystem
hitParticle
;
protected
virtual
void
Start
()
protected
virtual
void
Start
()
{
{
agent
=
GetComponent
<
NodalPathfinding2DAgent
>();
agent
=
GetComponent
<
NodalPathfinding2DAgent
>();
Health
=
MaxHealth
;
}
}
public
virtual
void
MoveTo
(
Vector2
destination
)
public
virtual
void
MoveTo
(
Vector2
destination
)
...
...
Assets/Scripts/Actors/PlayableCharacter.cs
View file @
18049a31
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
using
System.Collections.Generic
;
using
System.Collections.Generic
;
using
UnityEngine
;
using
UnityEngine
;
using
BS
;
using
BS
;
using
System.Linq
;
enum
CharacterControlMode
enum
CharacterControlMode
{
{
...
@@ -13,26 +14,19 @@ enum CharacterControlMode
...
@@ -13,26 +14,19 @@ enum CharacterControlMode
[
RequireComponent
(
typeof
(
LineRenderer
))]
[
RequireComponent
(
typeof
(
LineRenderer
))]
public
abstract
class
PlayableCharacter
:
Actor
public
abstract
class
PlayableCharacter
:
Actor
{
{
public
float
shotRange
=
5.0f
;
public
LayerMask
shotBlockMask
;
protected
LineRenderer
shotRangeRenderer
;
[
SerializeField
]
[
SerializeField
]
protected
LineRenderer
pathRenderer
;
private
WeaponBehaviour
weaponBehaviour
=
null
;
private
float
r
=
0.0f
;
public
bool
isSelected
=
false
;
public
bool
isSelected
=
false
;
private
Transform
target
;
public
Enemy
Target
{
private
get
;
set
;
}
public
bool
isAutoTargeting
=
false
;
public
LayerMask
enemyMask
;
protected
override
void
Start
()
protected
override
void
Start
()
{
{
base
.
Start
();
base
.
Start
();
if
(
shotRangeRenderer
==
null
)
if
(
weaponBehaviour
==
null
)
shotRangeRenderer
=
GetComponent
<
LineRenderer
>();
weaponBehaviour
=
GetComponent
<
WeaponBehaviour
>();
if
(
pathRenderer
==
null
)
pathRenderer
=
GetComponentInChildren
<
LineRenderer
>();
if
(
selectRing
==
null
)
if
(
selectRing
==
null
)
selectRing
=
transform
.
Find
(
"SelectRing"
).
gameObject
;
selectRing
=
transform
.
Find
(
"SelectRing"
).
gameObject
;
}
}
...
@@ -41,38 +35,32 @@ public abstract class PlayableCharacter : Actor
...
@@ -41,38 +35,32 @@ public abstract class PlayableCharacter : Actor
{
{
if
(
isSelected
)
if
(
isSelected
)
{
{
r
=
Mathf
.
Min
(
shotRange
,
r
+
shotRange
*
Time
.
deltaTime
);
weaponBehaviour
.
DrawWeaponRange
(
);
Vector3
[]
vertices
=
new
Vector3
[
361
];
}
for
(
int
i
=
0
;
i
<
360
;
i
++
)
if
(
isAutoTargeting
&&
Target
==
null
)
{
{
Vector2
direction
=
(
Quaternion
.
Euler
(
0
,
0
,
i
)
*
Vector2
.
right
).
normalized
;
AutoTargeting
();
RaycastHit2D
hit
=
Physics2D
.
Raycast
(
transform
.
position
,
direction
,
r
,
shotBlockMask
);
if
(
hit
.
collider
!=
null
)
vertices
[
i
]
=
hit
.
point
;
else
vertices
[
i
]
=
transform
.
position
+
new
Vector3
(
direction
.
x
,
direction
.
y
)
*
r
;
}
}
vertices
[
360
]
=
vertices
[
0
];
if
(
Target
!=
null
)
{
shotRangeRenderer
.
SetPositions
(
vertices
);
AttackTarget
();
}
}
}
}
public
override
void
OnSelected
()
public
override
void
OnSelected
()
{
{
if
(
isSelected
)
return
;
isSelected
=
true
;
isSelected
=
true
;
shotRangeRenderer
.
enabled
=
true
;
selectRing
?.
SetActive
(
true
);
selectRing
?.
SetActive
(
true
);
r
=
0
;
weaponBehaviour
.
OnSelected
()
;
}
}
public
override
void
OnUnselected
()
public
override
void
OnUnselected
()
{
{
isSelected
=
false
;
isSelected
=
false
;
shotRangeRenderer
.
enabled
=
false
;
selectRing
?.
SetActive
(
false
);
selectRing
?.
SetActive
(
false
);
weaponBehaviour
.
OnDeselected
();
}
}
public
override
void
MoveTo
(
Vector2
destination
)
public
override
void
MoveTo
(
Vector2
destination
)
...
@@ -81,9 +69,44 @@ public abstract class PlayableCharacter : Actor
...
@@ -81,9 +69,44 @@ public abstract class PlayableCharacter : Actor
agent
.
MoveTo
(
destination
);
agent
.
MoveTo
(
destination
);
}
}
public
void
DrawPath
()
public
void
AutoTargeting
()
{
{
Collider2D
[]
result
=
Physics2D
.
OverlapCircleAll
(
transform
.
position
,
weaponBehaviour
.
weapon
.
shotRange
,
enemyMask
);
List
<
Collider2D
>
sorted
=
result
.
ToList
();
sorted
.
Sort
((
a
,
b
)
=>
Vector2
.
Distance
(
transform
.
position
,
a
.
transform
.
position
)
>
Vector2
.
Distance
(
transform
.
position
,
b
.
transform
.
position
)
?
1
:
-
1
);
foreach
(
var
enemy
in
sorted
)
{
}
}
public
void
SetTarget
(
Enemy
enemy
)
{
if
(
isSelected
)
Target
=
enemy
;
}
public
void
AttackTarget
()
{
if
(
weaponBehaviour
.
IsAttackable
(
Target
))
{
agent
.
Stop
();
LookAt
(
Target
.
transform
);
weaponBehaviour
.
OnAttack
(
Target
);
}
else
{
agent
.
MoveTo
(
Target
.
transform
.
position
);
}
}
protected
void
LookAt
(
Transform
target
)
{
transform
.
rotation
=
Quaternion
.
Euler
(
0
,
0
,
Vector2
.
SignedAngle
(
Vector2
.
up
,
target
.
position
-
transform
.
position
));
}
}
protected
abstract
void
DefaultControl
();
protected
abstract
void
DefaultControl
();
...
...
Assets/Scripts/NodalPathfinding/NodalPathfinding2DAgent.cs
View file @
18049a31
...
@@ -90,6 +90,13 @@ namespace BS {
...
@@ -90,6 +90,13 @@ namespace BS {
}
}
}
}
public
void
Stop
()
{
rb
.
velocity
=
Vector2
.
zero
;
destination
=
transform
.
position
;
path
.
Clear
();
}
private
void
FixedUpdate
()
private
void
FixedUpdate
()
{
{
if
(
path
.
Count
>
0
)
if
(
path
.
Count
>
0
)
...
...
Assets/Scripts/PlayerController.cs
View file @
18049a31
using
System.Collections
;
using
System.Collections
;
using
System.Collections.Generic
;
using
System.Collections.Generic
;
using
System.Linq
;
using
UnityEngine
;
using
UnityEngine
;
public
class
PlayerController
:
SingletonBehaviour
<
PlayerController
>
public
class
PlayerController
:
SingletonBehaviour
<
PlayerController
>
...
@@ -23,6 +24,7 @@ public class PlayerController : SingletonBehaviour<PlayerController>
...
@@ -23,6 +24,7 @@ public class PlayerController : SingletonBehaviour<PlayerController>
private
void
Awake
()
private
void
Awake
()
{
{
characters
=
FindObjectsOfType
<
PlayableCharacter
>().
ToList
();
}
}
private
void
Update
()
private
void
Update
()
...
@@ -118,10 +120,23 @@ public class PlayerController : SingletonBehaviour<PlayerController>
...
@@ -118,10 +120,23 @@ public class PlayerController : SingletonBehaviour<PlayerController>
}
}
}
}
if
(
Input
.
GetMouseButton
(
1
))
if
(
Input
.
GetMouseButton
(
1
))
{
Vector3
mouseWorldPostion
=
Camera
.
main
.
ScreenToWorldPoint
(
Input
.
mousePosition
);
Enemy
target
=
Physics2D
.
OverlapPoint
(
mouseWorldPostion
).
GetComponent
<
Enemy
>();
if
(
target
!=
null
)
{
foreach
(
var
character
in
characters
)
{
character
.
SetTarget
(
target
);
}
}
else
{
{
foreach
(
var
character
in
characters
)
foreach
(
var
character
in
characters
)
{
{
character
.
MoveTo
(
Camera
.
main
.
ScreenToWorldPoint
(
Input
.
mousePosition
));
character
.
MoveTo
(
Camera
.
main
.
ScreenToWorldPoint
(
Input
.
mousePosition
));
character
.
SetTarget
(
null
);
}
}
}
}
}
}
}
...
...
Assets/Scripts/Weapon.cs
deleted
100644 → 0
View file @
d7bdc6ba
using
System.Collections
;
using
System.Collections.Generic
;
using
UnityEngine
;
public
class
Weapon
:
ScriptableObject
{
public
float
shotRange
;
public
float
damage
;
}
Assets/Scripts/Weapons/AssaultRifle.cs
0 → 100644
View file @
18049a31
using
System.Collections
;
using
System.Collections.Generic
;
using
UnityEngine
;
public
class
AssaultRifle
:
Weapon
{
public
int
bulletsPerShot
;
public
float
bulletInterval
;
public
override
void
OnAttack
(
Enemy
enemy
)
{
if
(
IsReady
)
{
behaviour
.
StartCoroutine
(
ShotBullet
(
enemy
));
shotTimer
=
shotInterval
;
}
}
private
IEnumerator
ShotBullet
(
Enemy
enemy
)
{
for
(
int
i
=
0
;
i
<
bulletsPerShot
;
i
++)
{
enemy
.
Health
-=
damage
+
Random
.
Range
(-
damageRandomRange
,
damageRandomRange
+
1
);
behaviour
.
EmitBulletParticle
();
yield
return
new
WaitForSeconds
(
bulletInterval
);
}
}
}
Assets/Scripts/Weapons/AssaultRifle.cs.meta
0 → 100644
View file @
18049a31
fileFormatVersion: 2
guid: 27849484d6b326e4abb8591c36ef24b4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
Assets/Scripts/Weapons/Weapon.cs
0 → 100644
View file @
18049a31
using
System.Collections
;
using
System.Collections.Generic
;
using
UnityEngine
;
public
abstract
class
Weapon
:
ScriptableObject
{
protected
WeaponBehaviour
behaviour
;
public
float
shotRange
;
public
float
shotInterval
;
protected
float
shotTimer
;
public
int
damage
;
public
int
damageRandomRange
;
public
bool
IsReady
{
get
{
return
shotTimer
<=
0
;
}
}
public
virtual
void
Init
(
WeaponBehaviour
behaviour
)
{
this
.
behaviour
=
behaviour
;
shotTimer
=
shotInterval
;
}
public
virtual
void
UpdateWeapon
(
float
deltaTime
)
{
shotTimer
=
Mathf
.
Max
(
0
,
shotTimer
-
deltaTime
);
}
public
abstract
void
OnAttack
(
Enemy
enemy
);
}
Assets/Scripts/Weapon.cs.meta
→
Assets/Scripts/Weapon
s/Weapon
.cs.meta
View file @
18049a31
File moved
Assets/Scripts/Weapons/WeaponBehaviour.cs
0 → 100644
View file @
18049a31
using
System
;
using
System.Collections
;
using
System.Collections.Generic
;
using
UnityEngine
;
public
sealed
class
WeaponBehaviour
:
MonoBehaviour
{
[
SerializeField
]
private
List
<
Weapon
>
weapons
=
new
List
<
Weapon
>();
[
SerializeField
]
private
int
weaponIndex
=
0
;
[
SerializeField
]
private
LineRenderer
shotRangeRenderer
;
public
LayerMask
shotBlockMask
;
[
SerializeField
]
private
ParticleSystem
bulletParticle
;
public
Action
<
Enemy
>
OnAttack
{
get
;
private
set
;
}
public
Action
OnReload
{
get
;
private
set
;
}
public
Weapon
weapon
{
get
{
return
weapons
[
weaponIndex
];
}
}
private
float
shotRadius
=
0
;
private
void
Start
()
{
ChangeWeapon
(
weaponIndex
);
}
private
void
Update
()
{
weapon
.
UpdateWeapon
(
Time
.
deltaTime
);
}
public
void
Init
(
Weapon
weapon
)
{
weapon
.
Init
(
this
);
OnAttack
=
weapon
.
OnAttack
;
}
public
void
ChangeWeapon
(
int
index
)
{
if
(
index
>=
weapons
.
Count
)
{
Debug
.
LogError
(
"Index out of bounds"
);
return
;
}
Init
(
weapons
[
index
]);
}
public
void
EmitBulletParticle
()
{
bulletParticle
.
Emit
(
1
);
}
public
void
DrawWeaponRange
()
{
shotRadius
=
Mathf
.
Min
(
weapon
.
shotRange
,
shotRadius
+
weapon
.
shotRange
*
Time
.
deltaTime
);
Vector3
[]
vertices
=
new
Vector3
[
361
];
for
(
int
i
=
0
;
i
<
360
;
i
++)
{
Vector2
direction
=
(
Quaternion
.
Euler
(
0
,
0
,
i
)
*
Vector2
.
right
).
normalized
;
RaycastHit2D
hit
=
Physics2D
.
Raycast
(
transform
.
position
,
direction
,
shotRadius
,
shotBlockMask
);
if
(
hit
.
collider
!=
null
)
vertices
[
i
]
=
hit
.
point
;
else
vertices
[
i
]
=
transform
.
position
+
new
Vector3
(
direction
.
x
,
direction
.
y
)
*
shotRadius
;
}
vertices
[
360
]
=
vertices
[
0
];
shotRangeRenderer
.
SetPositions
(
vertices
);
}
public
void
OnSelected
()
{
shotRadius
=
0
;
shotRangeRenderer
.
enabled
=
true
;
}
public
void
OnDeselected
()
{
shotRangeRenderer
.
enabled
=
false
;
}
public
bool
IsAttackable
(
Enemy
enemy
)
{
return
!(
Vector2
.
Distance
(
transform
.
position
,
enemy
.
transform
.
position
)
>
weapon
.
shotRange
)
&&
!
Physics2D
.
Linecast
(
transform
.
position
,
enemy
.
transform
.
position
,
shotBlockMask
);
}
}
Assets/Scripts/Weapons/WeaponBehaviour.cs.meta
0 → 100644
View file @
18049a31
fileFormatVersion: 2
guid: 4ecc7f8bb7cb0ba4abf7b037c9a61411
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
ProjectSettings/Physics2DSettings.asset
View file @
18049a31
...
@@ -53,4 +53,4 @@ Physics2DSettings:
...
@@ -53,4 +53,4 @@ Physics2DSettings:
m_ColliderAsleepColor
:
{
r
:
0.5686275
,
g
:
0.95686275
,
b
:
0.54509807
,
a
:
0.36078432
}
m_ColliderAsleepColor
:
{
r
:
0.5686275
,
g
:
0.95686275
,
b
:
0.54509807
,
a
:
0.36078432
}
m_ColliderContactColor
:
{
r
:
1
,
g
:
0
,
b
:
1
,
a
:
0.6862745
}
m_ColliderContactColor
:
{
r
:
1
,
g
:
0
,
b
:
1
,
a
:
0.6862745
}
m_ColliderAABBColor
:
{
r
:
1
,
g
:
1
,
b
:
0
,
a
:
0.2509804
}
m_ColliderAABBColor
:
{
r
:
1
,
g
:
1
,
b
:
0
,
a
:
0.2509804
}
m_LayerCollisionMatrix
:
fffdfffffffdfffffffdfffffffffffffffdfffffffdfffffffffffffffffffffffdffffc8f
cffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
m_LayerCollisionMatrix
:
fffdfffffffdfffffffdfffffffffffffffdfffffffdfffffffffffffffffffffffdffffc8f
0fffffffdfffffffd
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ProjectSettings/TagManager.asset
View file @
18049a31
...
@@ -15,8 +15,8 @@ TagManager:
...
@@ -15,8 +15,8 @@ TagManager:
-
-
-
Wall
-
Wall
-
Floor
-
Floor
-
-
Enemy
-
-
Player
-
-
-
-
-
-
...
...
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