785 lines
24 KiB
C#
785 lines
24 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using Mirror;
|
|
using System.Linq;
|
|
using UnityEngine.UI;
|
|
using System.Collections;
|
|
|
|
public class SpaceshipController : NetworkBehaviour
|
|
{
|
|
[SyncVar]
|
|
public bool ready;
|
|
public SpriteRenderer playerImg;
|
|
public SkinsData skins;
|
|
[SyncVar(hook = nameof(OnSkinChanged))]
|
|
public string skinName = null;
|
|
[SyncVar(hook = nameof(OnPnameChanged))]
|
|
public string pname;
|
|
[SyncVar(hook = nameof(OnScoresChanged))]
|
|
public int Scores;
|
|
[SyncVar(hook = nameof(OnKillsChanged))]
|
|
public int Kills;
|
|
[SyncVar(hook = nameof(OnTrailTimeChanged))]
|
|
public float trailTime;
|
|
[SyncVar]
|
|
public int moonsCollected;
|
|
public float trailIncrementRate = 0.5f;
|
|
[SyncVar]
|
|
public bool dead;
|
|
[SyncVar]
|
|
public float speed;
|
|
public float _scaleMultiplier = 1;
|
|
public Text pnameTxt;
|
|
public Transform body;
|
|
public TrailMgr trailMgr;
|
|
public float movingSpeed = 0.1f;
|
|
public float turningSmoothFactor = 0.1f;
|
|
public Joystick joystick;
|
|
public Vector2 joyInput;
|
|
[SyncVar]
|
|
public bool boosting;
|
|
|
|
[Header("Client Prediction")]
|
|
public SortedDictionary<int, StatePayload> serverStateBuffer = new SortedDictionary<int, StatePayload>();
|
|
public Vector3 DetourError = new Vector3(0, 0.2f, 0);
|
|
public Vector3 Detour = Vector3.zero;
|
|
public Quaternion RotationDetour = Quaternion.identity;
|
|
public float DetourCorrectionFactor = 0.5f;
|
|
public float timeDelayErrorFix = 1f;
|
|
public bool showDebugHUD = false;
|
|
|
|
public float distanceFromCenter = 0;
|
|
|
|
public void SetReady(bool value){
|
|
if(isServer){
|
|
ready =value;
|
|
}else{
|
|
CmdSetReady(value);
|
|
}
|
|
}
|
|
|
|
[Command]
|
|
void CmdSetReady(bool value){
|
|
ready= value;
|
|
}
|
|
|
|
[Command]
|
|
void CmdSetPname(string value)
|
|
{
|
|
pname = value;
|
|
}
|
|
void OnPnameChanged(string oldName, string newName)
|
|
{
|
|
pnameTxt.text = newName;
|
|
Debug.Log(pname + " Joined the game");
|
|
}
|
|
|
|
[Command]
|
|
void CmdSetSkin(string newSkin)
|
|
{
|
|
skinName = newSkin;
|
|
}
|
|
|
|
void OnSkinChanged(string oldSkin, string newSkin)
|
|
{
|
|
ChangeSkin(newSkin);
|
|
}
|
|
|
|
void ChangeSkin(string name)
|
|
{
|
|
Sprite newSprite = SkinManagerHelper.getSkinSprite(name, skins);
|
|
playerImg.sprite = newSprite;
|
|
}
|
|
|
|
|
|
void OnScoresChanged(int oldScores, int newScores)
|
|
{
|
|
Debug.Log($"Add scores {newScores - oldScores}, (total: {newScores})");
|
|
}
|
|
|
|
void OnTrailTimeChanged(float oldValue, float newValue)
|
|
{
|
|
trailMgr.trail.time = newValue;
|
|
if (isLocalPlayer)
|
|
{
|
|
SceneData.holder.boostBtn.gameObject.SetActive(scale > 1);
|
|
if(scale <=1 && boosting){
|
|
CmdSetBoosting(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
void OnBoostDown()
|
|
{
|
|
if (isLocalPlayer)
|
|
{
|
|
if (isServer)
|
|
{
|
|
boosting = true;
|
|
}
|
|
else
|
|
{
|
|
CmdSetBoosting(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
void OnBoostUp()
|
|
{
|
|
if (isLocalPlayer)
|
|
{
|
|
if (isServer)
|
|
{
|
|
boosting = false;
|
|
}
|
|
else
|
|
{
|
|
CmdSetBoosting(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
[Command]
|
|
void CmdSetBoosting(bool value)
|
|
{
|
|
boosting = value;
|
|
}
|
|
[SyncVar]
|
|
double startedTime = 0;
|
|
|
|
void ResetStats()
|
|
{
|
|
startedXp = DBmanager.Xp;
|
|
startedMetal = DBmanager.Metal;
|
|
}
|
|
|
|
void Start()
|
|
{
|
|
if (isLocalPlayer)
|
|
{
|
|
ResetStats();
|
|
if (joystick == null) { joystick = FindObjectOfType<Joystick>(); }
|
|
FindObjectOfType<CameraFollower>().SetTarget(transform);
|
|
string myName = PlayerPrefs.GetString("username");
|
|
SceneData.localPlayer = gameObject;
|
|
SceneData.OnBoostDown.AddListener(OnBoostDown);
|
|
SceneData.OnBoostUp.AddListener(OnBoostUp);
|
|
//Set username
|
|
if (isServer) { pname = myName; }
|
|
else
|
|
{
|
|
CmdSetPname(myName);
|
|
}
|
|
|
|
//Set Skin
|
|
if (!DBmanager.SkinsPurchased.Contains(SkinShopManager.GetEquipedSkin()))
|
|
{
|
|
//False skin purchase
|
|
}
|
|
else
|
|
{
|
|
if (isServer)
|
|
{
|
|
skinName = SkinShopManager.GetEquipedSkin();
|
|
}
|
|
else
|
|
{
|
|
CmdSetSkin(SkinShopManager.GetEquipedSkin());
|
|
}
|
|
}
|
|
|
|
pnameTxt.text = myName;
|
|
pnameTxt.gameObject.SetActive(false);
|
|
|
|
}
|
|
if (isServer)
|
|
{
|
|
startedTime = NetworkTime.time;
|
|
}
|
|
}
|
|
|
|
// Update is called once per frame
|
|
int timeInMillis => (int)(NetworkTime.time * 1000);
|
|
int roundedTime => Mathf.FloorToInt((float)timeInMillis / 100f) * 100;
|
|
|
|
int lastClientUpdateTime = 0;
|
|
float scale => Mathf.Clamp(1+(trailTime * _scaleMultiplier),1,10);
|
|
void FixedUpdate()
|
|
{
|
|
if (MinigameManager.instance.isRanked && !MinigameManager.instance.RankedGameStarted) { return; }
|
|
distanceFromCenter = Vector3.Distance(transform.position, Vector3.zero);
|
|
pnameTxt.rectTransform.rotation = Quaternion.Euler(Vector3.zero);
|
|
|
|
//Update size of trail and spaceship
|
|
transform.localScale = Vector3.Lerp(transform.localScale, new Vector3(scale, scale, scale), 0.1f);
|
|
trailMgr.trail.startWidth = Mathf.Lerp(trailMgr.trail.startWidth, scale, 0.1f);
|
|
|
|
if (dead) { return; }
|
|
|
|
if (isLocalPlayer)
|
|
{
|
|
joyInput = joystick.input;
|
|
|
|
//Cheats => TODO: Remove this
|
|
if (Input.GetKeyDown(KeyCode.F))
|
|
{
|
|
CmdCheatKills();
|
|
}
|
|
// Debug.Log(startedTime-NetworkTime.time);
|
|
double survivalTime = (startedTime == 0) ? 0 : NetworkTime.time - ((MinigameManager.instance.isRanked)? MinigameManager.instance.startedTime :startedTime);
|
|
if (DBmanager.MostTime < (int)survivalTime)
|
|
{
|
|
DBmanager.SetMostTime((int)survivalTime);
|
|
}
|
|
SceneData.SetTimerTxt(survivalTime);
|
|
}
|
|
//Simulate on both client and server
|
|
if (isLocalPlayer || isServer)
|
|
{
|
|
body.Translate(new Vector3(0, speed), body);
|
|
if (joyInput != Vector2.zero)
|
|
{
|
|
Turn(joyInput);
|
|
}
|
|
}
|
|
|
|
if (isServer)
|
|
{
|
|
//boost check
|
|
if (boosting && scale > 1)
|
|
{
|
|
speed = movingSpeed * 2;
|
|
DecreaseTrail(Time.deltaTime * 3);
|
|
// scaleMultiplier -= Time.deltaTime;
|
|
// if (scaleMultiplier < 1) { scaleMultiplier = 1; } //Clamp in case gets lower
|
|
}
|
|
else
|
|
{
|
|
speed = movingSpeed;
|
|
}
|
|
}
|
|
///Diff = rot1 . rot2
|
|
///1 = rot1 . rot2 / Diff
|
|
///1 * Diff * Diff = rot1.rot2. Diff
|
|
|
|
if (isLocalPlayer)
|
|
{
|
|
CmdUpdateJoyInput(joyInput);
|
|
|
|
//Fix Detours
|
|
if (Mathf.Abs(Detour.magnitude) > 0.1f || true)
|
|
{
|
|
Vector3 newPosition = body.position + Detour;
|
|
Quaternion newRotation = body.rotation * RotationDetour;
|
|
if (Detour.magnitude > 0.5f)
|
|
{
|
|
trailMgr.trail.emitting = false;
|
|
}
|
|
body.position = Vector3.Lerp(body.position, newPosition, (Mathf.Abs(Detour.magnitude) > 0.2f) ? DetourCorrectionFactor * 2 * Detour.magnitude : DetourCorrectionFactor);
|
|
Detour = newPosition - body.position;
|
|
body.rotation = Quaternion.Lerp(body.rotation, newRotation, DetourCorrectionFactor * ((joystick.touchDown) ? 0.1f : 1));
|
|
RotationDetour = Quaternion.Inverse(transform.rotation) * newRotation;
|
|
|
|
trailMgr.trail.emitting = true;
|
|
}
|
|
}
|
|
|
|
//Fill input and position buffer for client predictions
|
|
|
|
StatePayload currentState = new StatePayload(timeInMillis, transform.position, transform.rotation, joyInput);
|
|
|
|
if (isLocalPlayer)
|
|
{
|
|
if (lastClientUpdateTime < roundedTime)
|
|
{
|
|
CmdValidateMovement(roundedTime, currentState.Position, currentState.Rotation, currentState.Input);
|
|
lastClientUpdateTime = roundedTime;
|
|
}
|
|
}
|
|
else if (isServer)
|
|
{
|
|
int lastUpdatedTime = serverStateBuffer.Count > 0 ? serverStateBuffer.Keys.Last() : 0;
|
|
if (timeInMillis >= lastUpdatedTime + 100)
|
|
{
|
|
serverStateBuffer.Add(roundedTime, currentState);
|
|
if (serverStateBuffer.Count > 1024)
|
|
{
|
|
serverStateBuffer.Remove(serverStateBuffer.Keys.First());
|
|
}
|
|
}
|
|
RpcUpdatePosition(joyInput, transform.position, transform.rotation, timeInMillis);
|
|
RpcUpdateTrail(trailMgr.positions);
|
|
}
|
|
else
|
|
{
|
|
transform.position = Vector3.Lerp(transform.position, targetPosition, 0.1f);
|
|
transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, 0.1f);
|
|
}
|
|
}
|
|
|
|
Vector3 targetPosition;
|
|
Quaternion targetRotation;
|
|
|
|
|
|
void Turn(Vector2 input)
|
|
{
|
|
body.rotation = Quaternion.Lerp(body.rotation, getTurnAngle(input), turningSmoothFactor * input.magnitude);
|
|
}
|
|
|
|
Quaternion getTurnAngle(Vector2 input)
|
|
{
|
|
var angle1 = Mathf.Atan2(-input.y, -input.x) * Mathf.Rad2Deg;
|
|
return Quaternion.AngleAxis(angle1 + 90, Vector3.forward);
|
|
}
|
|
|
|
[Command]
|
|
void CmdUpdateJoyInput(Vector2 input)
|
|
{
|
|
joyInput = input;
|
|
}
|
|
|
|
[Command]
|
|
void CmdValidateMovement(int time, Vector3 position, Quaternion rotation, Vector2 input)
|
|
{
|
|
StatePayload payload = new StatePayload(time, position, rotation, input);
|
|
StatePayload lastServerState = serverStateBuffer.Values.Last();
|
|
StatePayload payloadToCompare;
|
|
if (serverStateBuffer.Count < 1) { Debug.Log("still Initiating server buffer"); return; }
|
|
joyInput = payload.Input;
|
|
if (!serverStateBuffer.ContainsKey(time))
|
|
{
|
|
payloadToCompare = lastServerState;
|
|
if (lastServerState.Time < time)
|
|
{
|
|
// Debug.Log("Server doesn't have that data yet\nYou asked for " + time + " best I can do is " + lastServerState.Time);
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < 50; i++)
|
|
{
|
|
if (serverStateBuffer.ContainsKey(time - i))
|
|
{
|
|
payloadToCompare = serverStateBuffer[time - i];
|
|
Debug.Log($"Found closest state at {payloadToCompare.Time}, requested {time}");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
payloadToCompare = serverStateBuffer[time];
|
|
}
|
|
Vector3 positionDiff = payloadToCompare.Position - payload.Position;
|
|
int timeDiff = lastServerState.Time - time;
|
|
|
|
if (Mathf.Abs(positionDiff.magnitude) < 0.2f && lastServerState.Time - time < 500)
|
|
{
|
|
//Validated, move on
|
|
}
|
|
else
|
|
{
|
|
// Debug.Log($"RB : {positionDiff.magnitude} [{timeDiff}ms]");
|
|
RpcRubberBand(joyInput, serverStateBuffer.Values.Last().Position, serverStateBuffer.Values.Last().Rotation, trailMgr.positions, timeInMillis);
|
|
}
|
|
|
|
|
|
}
|
|
[ClientRpc]
|
|
void RpcUpdatePosition(Vector2 input, Vector3 position, Quaternion rotation, double sentTime)
|
|
{
|
|
if (isLocalPlayer || isServer) { return; }
|
|
double delay = (timeInMillis - sentTime) * timeDelayErrorFix;
|
|
int numberOfFrames = (int)((float)(delay / 1000f) * 50f);
|
|
|
|
Quaternion newRotation = rotation;
|
|
Vector3 direction = (rotation * Vector3.forward).normalized;
|
|
Vector3 newPosition = position + ((direction * speed) * numberOfFrames);
|
|
|
|
for (int i = 0; i < numberOfFrames; i++)
|
|
{
|
|
newRotation = Quaternion.Lerp(newRotation, getTurnAngle(input), turningSmoothFactor * input.magnitude);
|
|
}
|
|
|
|
targetPosition = newPosition - DetourError;
|
|
|
|
targetRotation = newRotation;
|
|
}
|
|
double lastRubberBandTime = 0;
|
|
[ClientRpc]
|
|
void RpcRubberBand(Vector2 input, Vector3 position, Quaternion rotation, Vector3[] trailPositions, double sentTime)
|
|
{
|
|
if (true)
|
|
{
|
|
|
|
if (sentTime < lastRubberBandTime) { Debug.Log("Old rubber band rpc, ignoree..."); return; }
|
|
//Lag comprehension
|
|
double delay = (timeInMillis - sentTime) * timeDelayErrorFix;
|
|
int numberOfFrames = (int)((float)(delay / 1000f) * 50f);
|
|
|
|
Quaternion newRotation = rotation;
|
|
Vector3 direction = (rotation * Vector3.forward).normalized;
|
|
Vector3 newPosition = position + ((direction * speed) * numberOfFrames);
|
|
|
|
for (int i = 0; i < numberOfFrames; i++)
|
|
{
|
|
newRotation = Quaternion.Lerp(newRotation, getTurnAngle(input), turningSmoothFactor * input.magnitude);
|
|
}
|
|
int distanceSinceSent = (int)Vector3.Distance(newPosition, position);
|
|
|
|
#region trailSyncOld
|
|
// Vector3[] newTrailPositions = new Vector3[trailPositions.Length];
|
|
// for(int i=0; i < trailPositions.Length; i++){
|
|
// if(i > trailPositions.Length - distanceSinceSent-1){
|
|
// //fill with current data
|
|
// newTrailPositions[i] = trailMgr.positions[i];
|
|
// }else{
|
|
// Vector3 newTrailPoint = trailPositions[i-distanceSinceSent];
|
|
// if(trailMgr.positions.Length > i){
|
|
// if(Vector3.Distance(newTrailPoint, trailMgr.positions[i]) < 0.4f){
|
|
// newTrailPoint = trailMgr.positions[i];
|
|
// }
|
|
// }
|
|
// newTrailPositions[i] = newTrailPoint;
|
|
// }
|
|
// }
|
|
// trailMgr.trail.SetPositions(newTrailPositions);
|
|
#endregion
|
|
// Vector3 newPosition = position + new Vector3(0, movingSpeed * );
|
|
|
|
// Vector3 newPosition = position;
|
|
Detour = newPosition - transform.position - DetourError;
|
|
|
|
// RotationDetour = rotation;
|
|
RotationDetour = Quaternion.Inverse(transform.rotation) * newRotation;
|
|
lastRubberBandTime = sentTime;
|
|
|
|
// Debug.Log($"Rubber banded (Detour of pos:{Detour}, rotation: {RotationDetour}) you to {transform.position}, @ {sentTime} (delay: {delay}");
|
|
}
|
|
}
|
|
|
|
[ClientRpc]
|
|
void RpcUpdateTrail(Vector3[] positions)
|
|
{
|
|
//trailMgr.trail.SetPositions(positions);
|
|
}
|
|
|
|
void OnGUI()
|
|
{
|
|
if (!isLocalPlayer) { return; }
|
|
if (showDebugHUD)
|
|
{
|
|
GUI.Label(new Rect(Screen.width - 120, 10, 100, 20), transform.position.ToString());
|
|
GUI.Label(new Rect(Screen.width - 120, 30, 100, 20), timeInMillis.ToString());
|
|
GUI.Label(new Rect(Screen.width - 100, Screen.height - 30, 50, 20), (NetworkTime.rtt * 1000).ToString() + " ms");
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public float Angle(Vector2 vector2)
|
|
{
|
|
return 360 - (Mathf.Atan2(vector2.x, vector2.y) * Mathf.Rad2Deg * Mathf.Sign(vector2.x));
|
|
}
|
|
|
|
|
|
//Auto assign default variables [Editor only]
|
|
void OnValidate()
|
|
{
|
|
if (body == null)
|
|
{
|
|
body = transform;
|
|
}
|
|
if (trailMgr == null)
|
|
{
|
|
trailMgr = GetComponent<TrailMgr>();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public void TrailCollided(Collider2D hit)
|
|
{
|
|
if (!isServer)
|
|
{
|
|
Debug.Log("Got hit : " + hit.name);
|
|
// Debug.Log("This cannot run on client, That's illegal!"); // <-- What this log says
|
|
return;
|
|
}
|
|
|
|
SpaceshipController deadPlayer = hit.GetComponent<SpaceshipController>();
|
|
Debug.Log("got hit by player? : " + deadPlayer != null);
|
|
if (deadPlayer != null && !deadPlayer.dead && (NetworkTime.time- deadPlayer.startedTime) > 5)
|
|
{ // <-- okay we killed someone | KILLCODE
|
|
deadPlayer.Die(pname);
|
|
Debug.Log($"{pname} killed {deadPlayer.pname}");
|
|
OnKill();
|
|
}
|
|
}
|
|
|
|
void OnKill()
|
|
{
|
|
Kills++;
|
|
Scores += 10; //TODO: Need to change Scores on kills?
|
|
// scaleMultiplier += 0.05f;
|
|
// OnScaleChanged(scaleMultiplier, scaleMultiplier);
|
|
IncreaseTrail(trailIncrementRate);
|
|
RpcOnKill();
|
|
}
|
|
|
|
[ClientRpc]
|
|
void RpcOnKill()
|
|
{
|
|
|
|
}
|
|
|
|
void OnKillsChanged(int oldVal, int newVal)
|
|
{
|
|
if (isLocalPlayer)
|
|
{
|
|
Debug.Log("Show kills for " + newVal);
|
|
KillText.Show(newVal);
|
|
}
|
|
}
|
|
|
|
void IncreaseTrail(float rate)
|
|
{
|
|
trailTime = trailMgr.trail.time + rate;
|
|
trailMgr.trail.time = trailTime;
|
|
// Debug.Log("Increasing trail of" + pname);
|
|
}
|
|
|
|
public void DecreaseTrail(float rate)
|
|
{
|
|
trailTime = Mathf.Clamp(trailMgr.trail.time - rate,0,float.MaxValue);
|
|
trailMgr.trail.time = trailTime;
|
|
// Debug.Log("Decreasing trail of" + pname);
|
|
}
|
|
|
|
[Command]
|
|
void CmdCheatKills()
|
|
{
|
|
OnKill();
|
|
}
|
|
|
|
public void CollectPickup(PickupItem.PickupType type)
|
|
{
|
|
if (!isServer) { Debug.Log("Server function ran on client. That's illegal!"); } // <-- What this log says
|
|
switch (type)
|
|
{
|
|
case PickupItem.PickupType.Moon:
|
|
IncreaseTrail(trailIncrementRate);
|
|
// scaleMultiplier += 0.05f;
|
|
moonsCollected++;
|
|
break;
|
|
|
|
case PickupItem.PickupType.Star:
|
|
IncreaseTrail(trailIncrementRate / 2f);
|
|
// scaleMultiplier += 0.025f;
|
|
|
|
break;
|
|
}
|
|
|
|
RpcCollectPickup(type);
|
|
}
|
|
|
|
[ClientRpc]
|
|
void RpcCollectPickup(PickupItem.PickupType type)
|
|
{
|
|
if (isLocalPlayer)
|
|
{
|
|
MinigameManager.instance.GainMetals((type == PickupItem.PickupType.Star) ? 2 : 5);
|
|
}
|
|
}
|
|
|
|
public void Die(string killer)
|
|
{
|
|
|
|
MinigameManager.instance.SpawnLeftoverPickups(transform.position, Scores);
|
|
Debug.Log($"Sending death signal to {pname} by {killer}");
|
|
|
|
//Handle Respawning
|
|
// OnScaleChanged(scaleMultiplier, 1);
|
|
// scaleMultiplier = 1;
|
|
dead = true;
|
|
Scores = 0;
|
|
Kills = 0;
|
|
startedTime = NetworkTime.time;
|
|
trailTime = 1;
|
|
trailMgr.trail.time = trailTime;
|
|
RpcDie(killer);
|
|
gameObject.SetActive(false);
|
|
//MinigameManager.instance.SetRespawn(gameObject);
|
|
}
|
|
|
|
private int startedXp;
|
|
private int startedMetal;
|
|
|
|
bool RewardedRankedMetal =false;
|
|
|
|
[ClientRpc]
|
|
public void RpcDie(string killer)
|
|
{
|
|
Debug.Log($"{killer} killed {pname} : isItMe? -> {isLocalPlayer}");
|
|
KillfeedMgr.instance.AddNewEntry($"<b>{pname}</b> was killed by <b>{killer}</b>");
|
|
gameObject.SetActive(false);
|
|
if (isLocalPlayer)
|
|
{
|
|
//TODO: Death message goes here
|
|
SceneData.holder.ShowDeadscreen(DBmanager.Xp - startedXp, DBmanager.Metal - startedMetal, NetworkTime.time - startedTime);
|
|
if (MinigameManager.instance.isRanked)
|
|
{
|
|
// MinigameManager.instance.rankedSummary.ShowLoss();
|
|
// StartCoroutine(ShowRankedResults());
|
|
if(MinigameManager.instance.winnerId<=0){
|
|
Debug.LogError("Winner ID not synced yet");
|
|
}
|
|
if (MinigameManager.instance.winnerId != netId)
|
|
{
|
|
//LOSER!
|
|
MinigameManager.instance.rankedSummary.ShowLoss();
|
|
}
|
|
else
|
|
{
|
|
MinigameManager.instance.rankedSummary.ShowWin();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
IEnumerator ShowRankedResults()
|
|
{
|
|
while (MinigameManager.instance.winnerId <= 0)
|
|
{
|
|
yield return new WaitForFixedUpdate();
|
|
}
|
|
|
|
|
|
}
|
|
|
|
public void Respawn(Vector3 respawnPoint)
|
|
{
|
|
Debug.Log("Respawning " + pname);
|
|
|
|
if (isServer)
|
|
{
|
|
respawn(respawnPoint);
|
|
}
|
|
else
|
|
{
|
|
CmdRespawn(respawnPoint);
|
|
}
|
|
}
|
|
|
|
[Command]
|
|
void CmdRespawn(Vector3 respawnPoint)
|
|
{
|
|
respawn(respawnPoint);
|
|
}
|
|
|
|
public void respawn(Vector3 respawnPoint)
|
|
{
|
|
dead = false;
|
|
trailMgr.trail.emitting = false;
|
|
trailMgr.trail.Clear();
|
|
RpcRespawn(respawnPoint);
|
|
transform.position = respawnPoint;
|
|
trailMgr.trail.emitting = true;
|
|
gameObject.SetActive(true);
|
|
}
|
|
|
|
[ClientRpc]
|
|
public void RpcRespawn(Vector3 respawnPoint)
|
|
{
|
|
|
|
GetComponent<NetworkTrail>().enableValidation = false;
|
|
trailMgr.trail.Clear();
|
|
trailMgr.positions = new Vector3[0];
|
|
trailMgr.trail.emitting = false;
|
|
transform.position = respawnPoint;
|
|
trailMgr.trail.emitting = true;
|
|
GetComponent<NetworkTrail>().enableValidation = true;
|
|
gameObject.SetActive(true);
|
|
|
|
if (isLocalPlayer)
|
|
{
|
|
SceneData.holder.deadScreen.SetActive(false);
|
|
ResetStats();
|
|
}
|
|
}
|
|
[Command]
|
|
public void CmdWonRanked(){
|
|
WonRanked();
|
|
}
|
|
|
|
[Command]
|
|
public void CmdLostRanked(){
|
|
LostRanked();
|
|
}
|
|
public void WonRanked()
|
|
{
|
|
if (!isServer)
|
|
{
|
|
return;
|
|
}
|
|
|
|
RpcWonRanked();
|
|
Die("server");
|
|
}
|
|
|
|
[ClientRpc]
|
|
void RpcWonRanked()
|
|
{
|
|
if (isLocalPlayer)
|
|
{
|
|
DBmanager.SetMetal(DBmanager.Metal+500);
|
|
MinigameManager.instance.rankedSummary.ShowWin();
|
|
//Add trophies
|
|
DBmanager.SetTrophies(DBmanager.Trophies + 30);
|
|
}
|
|
}
|
|
|
|
public void LostRanked()
|
|
{
|
|
if (!isServer)
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
RpcLostRanked();
|
|
Die("server");
|
|
}
|
|
|
|
void RpcLostRanked()
|
|
{
|
|
if (isLocalPlayer)
|
|
{
|
|
DBmanager.SetMetal(DBmanager.Metal+250);
|
|
|
|
MinigameManager.instance.rankedSummary.ShowLoss();
|
|
DBmanager.SetTrophies(Mathf.Clamp(DBmanager.Trophies - 15, 0, int.MaxValue));
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public class StatePayload
|
|
{
|
|
public int Time;
|
|
public Vector3 Position;
|
|
public Quaternion Rotation;
|
|
public Vector2 Input;
|
|
|
|
public StatePayload(int time, Vector3 position, Quaternion rotation, Vector2 input)
|
|
{
|
|
Time = time;
|
|
Position = position;
|
|
Rotation = rotation;
|
|
Input = input;
|
|
}
|
|
} |