556 lines
15 KiB
C#
556 lines
15 KiB
C#
using UnityEngine;
|
|
using Mirror;
|
|
using UnityEngine.EventSystems;
|
|
using System.Collections;
|
|
using LegacyTouchPhase = UnityEngine.TouchPhase;
|
|
#if ENABLE_INPUT_SYSTEM
|
|
using UnityEngine.InputSystem;
|
|
#endif
|
|
public class NetPlayer : NetworkBehaviour
|
|
{
|
|
|
|
[SyncVar]
|
|
public int userId;
|
|
|
|
[SyncVar]
|
|
public Team myTeam;
|
|
// set the team to red if there are no other players, if not set blue
|
|
public override void OnStartLocalPlayer()
|
|
{
|
|
base.OnStartLocalPlayer();
|
|
|
|
#if UNITY_EDITOR
|
|
// Count current NetPlayers in the scene
|
|
if(Cupid.RoomPort == -1){
|
|
//Without cupid, set the team to red
|
|
bool cloneWorkspace = LoginManager.EditorWorkspaceLooksLikeClone();
|
|
SetMyTeam(cloneWorkspace ? Team.Red : Team.Blue);
|
|
SetMyData(cloneWorkspace ? 0: 1 );
|
|
|
|
}else{
|
|
SetMyTeam(GameManager.MyTeam);
|
|
SetMyData(GameManager.MyTeam == Team.Red ? GameManager.RedPlayer.UserId : GameManager.BluePlayer.UserId);
|
|
}
|
|
#else
|
|
SetMyTeam(GameManager.MyTeam);
|
|
SetMyData(GameManager.MyTeam == Team.Red ? GameManager.RedPlayer.UserId : GameManager.BluePlayer.UserId);
|
|
#endif
|
|
TeamSpecificEffects.instance.SetTeamSpecificEffects(myTeam);
|
|
}
|
|
|
|
void SetMyData(int uid){
|
|
if(isServer){
|
|
setMyData(uid);
|
|
}else{
|
|
CmdSetMyData(uid);
|
|
setMyData(uid);
|
|
}
|
|
}
|
|
|
|
void setMyData(int uid){
|
|
userId= uid;
|
|
}
|
|
|
|
[Command]
|
|
void CmdSetMyData(int uid){
|
|
userId=uid;
|
|
}
|
|
|
|
void SetMyTeam(Team team){
|
|
if(isServer){
|
|
setMyTeam(team);
|
|
}else{
|
|
CmdSetTeam(team);
|
|
setMyTeam(team);
|
|
}
|
|
}
|
|
|
|
void setMyTeam(Team team){
|
|
myTeam = team;
|
|
if (GameManager.instance != null)
|
|
GameManager.instance.OnMatchPlayerTeamAssigned(team);
|
|
}
|
|
|
|
[Command]
|
|
void CmdSetTeam(Team team){
|
|
setMyTeam(team);
|
|
|
|
Logger.Log($"Client {netId} set team to {team}");
|
|
if(team == Team.Red){
|
|
RedPlayer = this;
|
|
}else{
|
|
BluePlayer = this;
|
|
}
|
|
}
|
|
|
|
|
|
public static NetPlayer localPlayer;
|
|
|
|
public static NetPlayer RedPlayer;
|
|
public static NetPlayer BluePlayer;
|
|
public static Vector2 curPosition;
|
|
public Vector2 startPosition;
|
|
public float curPuckPullForce;
|
|
|
|
// Single drag at a time; extra fingers are ignored while isDragging.
|
|
bool isDragging;
|
|
Vector2 lastDragScreenPosition;
|
|
bool serverDragActive;
|
|
|
|
#region EMOTES
|
|
public void SendTextEmote(string txtName){
|
|
if(isServer){
|
|
RpcSendTextEmote(txtName);
|
|
ShowTextEmote(txtName);
|
|
}else{
|
|
CmdSendTextEmote(txtName);
|
|
}
|
|
}
|
|
|
|
[Command]
|
|
void CmdSendTextEmote(string txtName){
|
|
RpcSendTextEmote(txtName);
|
|
ShowTextEmote(txtName);
|
|
Logger.Log($"Client {netId} sent text emote {txtName}");
|
|
}
|
|
|
|
[ClientRpc]
|
|
void RpcSendTextEmote(string txtName){
|
|
ShowTextEmote(txtName);
|
|
}
|
|
|
|
void ShowTextEmote(string txtName){
|
|
GameCanvas.instance.ShowTextEmote(txtName, myTeam);
|
|
}
|
|
|
|
|
|
public void SendEmojiEmote(int id){
|
|
if(isServer){
|
|
RpcSendEmojiEmote(id);
|
|
ShowEmojiEmote(id);
|
|
}else{
|
|
CmdSendEmojiEmote(id);
|
|
}
|
|
}
|
|
|
|
[Command]
|
|
void CmdSendEmojiEmote(int id){
|
|
RpcSendEmojiEmote(id);
|
|
ShowEmojiEmote(id);
|
|
|
|
Logger.Log($"Client {netId} sent emoji emote {id}");
|
|
}
|
|
|
|
[ClientRpc]
|
|
void RpcSendEmojiEmote(int id){
|
|
ShowEmojiEmote(id);
|
|
}
|
|
|
|
void ShowEmojiEmote(int id){
|
|
GameCanvas.instance.ShowEmojiEmote(id, myTeam);
|
|
}
|
|
#endregion
|
|
|
|
void Start(){
|
|
if(isLocalPlayer){
|
|
localPlayer = this;
|
|
SetupInputPanel();
|
|
}
|
|
}
|
|
|
|
void OnDestroy(){
|
|
if(localPlayer == this){
|
|
localPlayer = null;
|
|
}
|
|
}
|
|
|
|
void SetupInputPanel(){
|
|
EventTrigger.Entry entry = new EventTrigger.Entry();
|
|
entry.eventID = EventTriggerType.PointerDown;
|
|
entry.callback.AddListener(OnPointerDown);
|
|
GameCanvas.instance.gameInputPanel.triggers.Add(entry);
|
|
|
|
entry = new EventTrigger.Entry();
|
|
entry.eventID = EventTriggerType.PointerUp;
|
|
entry.callback.AddListener(OnPointerUp);
|
|
GameCanvas.instance.gameInputPanel.triggers.Add(entry);
|
|
|
|
entry = new EventTrigger.Entry();
|
|
entry.eventID = EventTriggerType.Drag;
|
|
entry.callback.AddListener(OnDrag);
|
|
GameCanvas.instance.gameInputPanel.triggers.Add(entry);
|
|
}
|
|
|
|
bool TryGetPointerEvent(BaseEventData eventData, out PointerEventData pointerEventData)
|
|
{
|
|
pointerEventData = eventData as PointerEventData;
|
|
return pointerEventData != null;
|
|
}
|
|
|
|
static int CountPressedTouches()
|
|
{
|
|
#if ENABLE_INPUT_SYSTEM
|
|
if (Touchscreen.current != null)
|
|
{
|
|
int count = 0;
|
|
var touches = Touchscreen.current.touches;
|
|
for (int i = 0; i < touches.Count; i++)
|
|
{
|
|
if (touches[i].press.isPressed)
|
|
count++;
|
|
}
|
|
return count;
|
|
}
|
|
#endif
|
|
return Input.touchCount;
|
|
}
|
|
|
|
void UpdateDragScreenPosition(Vector2 screenPosition)
|
|
{
|
|
lastDragScreenPosition = screenPosition;
|
|
curPosition = screenPosition;
|
|
if (GameManager.SelectedPuck != null)
|
|
curPuckPullForce = GameManager.SelectedPuck.lineEnd.magnitude;
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (!isLocalPlayer || !isDragging)
|
|
return;
|
|
|
|
if (!TryReadPointerHeld(out Vector2 screenPosition, out bool isPressed))
|
|
{
|
|
curPosition = lastDragScreenPosition;
|
|
return;
|
|
}
|
|
|
|
UpdateDragScreenPosition(screenPosition);
|
|
if (!isPressed && CountPressedTouches() == 0)
|
|
CompleteActivePointerDrag();
|
|
}
|
|
|
|
bool TryReadPointerHeld(out Vector2 screenPosition, out bool isPressed)
|
|
{
|
|
screenPosition = lastDragScreenPosition;
|
|
isPressed = false;
|
|
|
|
#if ENABLE_INPUT_SYSTEM
|
|
if (Touchscreen.current != null)
|
|
{
|
|
var primary = Touchscreen.current.primaryTouch;
|
|
if (primary.press.isPressed)
|
|
{
|
|
screenPosition = primary.position.ReadValue();
|
|
isPressed = true;
|
|
return true;
|
|
}
|
|
|
|
if (primary.press.wasReleasedThisFrame)
|
|
{
|
|
screenPosition = primary.position.ReadValue();
|
|
return true;
|
|
}
|
|
|
|
var touches = Touchscreen.current.touches;
|
|
for (int i = 0; i < touches.Count; i++)
|
|
{
|
|
var touch = touches[i];
|
|
if (!touch.press.isPressed)
|
|
continue;
|
|
screenPosition = touch.position.ReadValue();
|
|
isPressed = true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if (Mouse.current != null)
|
|
{
|
|
if (Mouse.current.leftButton.isPressed)
|
|
{
|
|
screenPosition = Mouse.current.position.ReadValue();
|
|
isPressed = true;
|
|
return true;
|
|
}
|
|
|
|
if (Mouse.current.leftButton.wasReleasedThisFrame)
|
|
{
|
|
screenPosition = Mouse.current.position.ReadValue();
|
|
return true;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if (Input.touchCount > 0)
|
|
{
|
|
UnityEngine.Touch touch = Input.GetTouch(0);
|
|
screenPosition = touch.position;
|
|
isPressed = touch.phase != LegacyTouchPhase.Ended && touch.phase != LegacyTouchPhase.Canceled;
|
|
return true;
|
|
}
|
|
|
|
if (Input.GetMouseButton(0))
|
|
{
|
|
screenPosition = Input.mousePosition;
|
|
isPressed = true;
|
|
return true;
|
|
}
|
|
|
|
if (Input.GetMouseButtonUp(0))
|
|
{
|
|
screenPosition = Input.mousePosition;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void CompleteActivePointerDrag()
|
|
{
|
|
if (!isDragging)
|
|
return;
|
|
|
|
if (CountPressedTouches() > 0)
|
|
return;
|
|
|
|
isDragging = false;
|
|
|
|
if (GameManager.SelectedPuck == null)
|
|
return;
|
|
if (GameManager.instance == null)
|
|
return;
|
|
if (GameManager.instance.SelectedTeam != myTeam)
|
|
return;
|
|
|
|
Vector2 direction = GameManager.SelectedPuck.lineEnd;
|
|
CmdOnPointerUp(direction);
|
|
if (CameraEffects.instance != null)
|
|
CameraEffects.instance.ReleaseStretchFactor();
|
|
}
|
|
|
|
void OnPointerDown(BaseEventData eventData){
|
|
if(GameManager.instance == null){return;}
|
|
if(GameManager.instance.SelectedTeam != myTeam){return;}
|
|
if(GameManager.instance.m_isMoving){return;}
|
|
if(isDragging){return;}
|
|
if(CountPressedTouches() > 1){return;}
|
|
if(!TryGetPointerEvent(eventData, out PointerEventData pointerEventData)){return;}
|
|
|
|
Vector2 position = pointerEventData.position;
|
|
Vector3 worldPosition = Camera.main.ScreenToWorldPoint(new Vector3(position.x, position.y, Camera.main.nearClipPlane));
|
|
Puck closestPuck = GameManager.instance.GetClosestPuck(worldPosition);
|
|
if (closestPuck == null)
|
|
return;
|
|
|
|
isDragging = true;
|
|
UpdateDragScreenPosition(position);
|
|
GameManager.SelectedPuck = closestPuck;
|
|
CmdOnPointerDown(worldPosition);
|
|
}
|
|
|
|
|
|
[Command]
|
|
void CmdOnPointerDown(Vector2 position){
|
|
if (GameManager.instance == null)
|
|
return;
|
|
if (serverDragActive)
|
|
return;
|
|
if (GameManager.instance.SelectedTeam != myTeam)
|
|
return;
|
|
|
|
Puck closestPuck = GameManager.instance.GetClosestPuck(position);
|
|
if (closestPuck == null || closestPuck.gameObject == null)
|
|
return;
|
|
|
|
serverDragActive = true;
|
|
GameManager.SelectedPuck = closestPuck;
|
|
RpcOnPointerDown(closestPuck.gameObject);
|
|
}
|
|
|
|
[ClientRpc]
|
|
void RpcOnPointerDown(GameObject puckGo){
|
|
if(puckGo == null){return;}
|
|
if(!isLocalPlayer){return;}
|
|
|
|
Puck puck = puckGo.GetComponent<Puck>();
|
|
if(puck!=GameManager.SelectedPuck){
|
|
Debug.LogError("Selected puck changed on client, This cant happen. Resetting to servers choice", gameObject);
|
|
}
|
|
GameManager.SelectedPuck = puck;
|
|
}
|
|
|
|
|
|
void OnDrag(BaseEventData eventData){
|
|
if(!isDragging){return;}
|
|
if(!TryGetPointerEvent(eventData, out PointerEventData pointerEventData)){return;}
|
|
UpdateDragScreenPosition(pointerEventData.position);
|
|
}
|
|
|
|
void OnPointerUp(BaseEventData eventData){
|
|
if(!isDragging){return;}
|
|
if(TryGetPointerEvent(eventData, out PointerEventData pointerEventData))
|
|
UpdateDragScreenPosition(pointerEventData.position);
|
|
if (CountPressedTouches() > 0)
|
|
return;
|
|
CompleteActivePointerDrag();
|
|
}
|
|
|
|
[Command]
|
|
void CmdOnPointerUp(Vector2 direction){
|
|
serverDragActive = false;
|
|
if (GameManager.instance == null)
|
|
return;
|
|
if (GameManager.instance.SelectedTeam != myTeam)
|
|
return;
|
|
|
|
Debug.Log("Pointer up");
|
|
|
|
GameManager.instance.OnPointerUp(direction);
|
|
|
|
RpcOnPointerUp();
|
|
}
|
|
|
|
[ClientRpc]
|
|
void RpcOnPointerUp(){
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Request a rematch with the opponent.
|
|
/// </summary>
|
|
public void RequestRematch(){
|
|
if(isServer){
|
|
GameOverCanvas.instance.OnRematchRequested();
|
|
RpcRequestRematch();
|
|
}else{
|
|
CmdRequestRematch();
|
|
}
|
|
}
|
|
|
|
[Command]
|
|
void CmdRequestRematch(){
|
|
Logger.Log("Rematch requested");
|
|
|
|
if(isServerOnly){
|
|
//server
|
|
}else{
|
|
GameOverCanvas.instance.OnRematchRequested();
|
|
}
|
|
RpcRequestRematch();
|
|
}
|
|
|
|
[ClientRpc]
|
|
void RpcRequestRematch(){
|
|
GameOverCanvas.instance.OnRematchRequested();
|
|
}
|
|
|
|
|
|
public void AcceptRematch( int betRcCoins){
|
|
if(isServer){
|
|
OnRematchAcceptedServer(betRcCoins);
|
|
}else{
|
|
CmdAcceptRematch(betRcCoins);
|
|
}
|
|
}
|
|
|
|
[Command]
|
|
void CmdAcceptRematch(int betRcCoins){
|
|
OnRematchAcceptedServer(betRcCoins);
|
|
}
|
|
|
|
void OnRematchAcceptedServer(int betRcCoins ){
|
|
if(!isServer){ return; }
|
|
|
|
if(betRcCoins <= 0){
|
|
OnRematchCancelledServer();
|
|
return;
|
|
}
|
|
|
|
GameManager.DedicatedRematchResult resp = GameManager.RequestDedicatedRematch(RedPlayer.userId, BluePlayer.userId, betRcCoins);
|
|
if(resp.Success && resp.Response != null){
|
|
string matchmadeResponseString = JsonUtility.ToJson(resp.Response);
|
|
RpcRematchConfirmed(matchmadeResponseString);
|
|
Logger.Log("Rematch was confirmed, closing in 5 secs. new room :");
|
|
Logger.Log(matchmadeResponseString);
|
|
StartCoroutine(CoroutineOnRematchConfirmedServer());
|
|
}
|
|
}
|
|
|
|
IEnumerator CoroutineOnRematchConfirmedServer(){
|
|
yield return new WaitForSeconds(5f);
|
|
Logger.Log("Exiting for rematch.");
|
|
GameManager.ReportDedicatedMatchRoomClosed();
|
|
Application.Quit();
|
|
}
|
|
|
|
[ClientRpc]
|
|
void RpcRematchConfirmed(string matchmadeResponseString){
|
|
if (string.IsNullOrEmpty(matchmadeResponseString))
|
|
return;
|
|
|
|
MatchmadeResponse env = JsonUtility.FromJson<MatchmadeResponse>(matchmadeResponseString);
|
|
if (env == null || !env.ok)
|
|
return;
|
|
|
|
Team? teamHint = LoginManager.MatchYourTeam;
|
|
if (!teamHint.HasValue)
|
|
teamHint = GameManager.MyTeam;
|
|
|
|
int userId = localPlayer != null ? localPlayer.userId : (LoginManager.CurrentUser != null ? LoginManager.CurrentUser.id : 0);
|
|
|
|
MatchmadeTeamPayload branch = MatchmadeResponse.SelectTeamPayload(env, userId, teamHint);
|
|
if (branch == null || !MatchmadeResponse.TryResolveMyAndOpponent(env, branch, userId, out MatchmadePlayer myPlayer, out MatchmadePlayer opponentPlayer))
|
|
{
|
|
Debug.LogWarning("RpcRematchConfirmed: could not resolve roster for rematch UI");
|
|
return;
|
|
}
|
|
|
|
string yt = (branch.your_team ?? "").Trim().ToLowerInvariant();
|
|
Team myTeam = yt == "blue" ? Team.Blue : Team.Red;
|
|
|
|
if (myTeam == Team.Red)
|
|
{
|
|
GameManager.RedPlayer = myPlayer;
|
|
GameManager.BluePlayer = opponentPlayer;
|
|
}
|
|
else
|
|
{
|
|
GameManager.BluePlayer = myPlayer;
|
|
GameManager.RedPlayer = opponentPlayer;
|
|
}
|
|
GameManager.MyTeam = myTeam;
|
|
|
|
int rcPrizeCoins = env.rc_prize > 0 ? env.rc_prize : branch.rc_prize;
|
|
GameManager.MatchRcPrizeCoins = rcPrizeCoins;
|
|
|
|
if (LevelLoadManager.instance != null)
|
|
LevelLoadManager.instance.SetupMatchMade(myTeam, myPlayer, opponentPlayer, CoinHelper.FormatString(rcPrizeCoins) + " RC");
|
|
|
|
GameManager.ConfigureDedicatedMatchReporting(branch.match_id);
|
|
Cupid.RoomPort = branch.Port;
|
|
LoginManager.SetMatchYourTeam(branch.your_team);
|
|
|
|
GameManager.instance.StopClient();
|
|
LevelLoadManager.LoadLevel("Game");
|
|
}
|
|
|
|
void OnRematchCancelledServer(){
|
|
if(!isServer){ return; }
|
|
|
|
RpcCancelRematch();
|
|
if(!isServerOnly){
|
|
CancelRematch();
|
|
}
|
|
}
|
|
|
|
[ClientRpc]
|
|
void RpcCancelRematch(){
|
|
CancelRematch();
|
|
}
|
|
|
|
void CancelRematch(){
|
|
GameOverCanvas.instance.OnRematchCancelled();
|
|
}
|
|
|
|
}
|