using System.Collections; using System.Collections.Generic; using Assets.HeroEditor4D.Common.Scripts.CharacterScripts; using Assets.HeroEditor4D.Common.Scripts.Enums; using Mirror; using TMPro; using Firebase.Firestore; using Firebase.Extensions; using Unity.VisualScripting; using UnityEngine; public class playerNetwork : NetworkBehaviour { [SyncVar(hook =nameof(OnHealthChanged))] public int health = 100; public Character4D character; [SyncVar(hook =nameof(OnDirectionChanged))] public Vector2 directionNetwork; [SyncVar(hook =nameof(OnAnimChanged))] public int animIntNetwork; [SyncVar] public int enemyKillCount; public int xp { get{ int val = 0; for(int i =5; i <= enemyKillCount; i+=5){ val = enemyKillCount; } return val; }} public int lvl { get{ int val = 0; for(int i =5; i <= enemyKillCount; i+=5){ val ++; } return val; }} [SyncVar] public string playerName; [SyncVar] public int playerCoin; public TMP_Text txtEnemyKillCount; public TMP_Text txtPlayerName; public TMP_Text questText; public TMP_Text coinText; public TMP_Text xpText; public TMP_Text lvlText; public TMP_Text xpEnableTxt; public TMP_Text attackDmgEnableTxt; public GameObject canvas; public healthBar healthBar; public Inventory inventory; void Start(){ if(!isLocalPlayer){ LoadPlayerData(); if(isServer){ playerName = gplayAuth.userNameCloud; } else{ CmdSetName(gplayAuth.userNameCloud); } canvas.SetActive(false); } } public void SavePlayerData(){ FirebaseFirestore db = FirebaseFirestore.DefaultInstance; //int playerCoin = int.Parse(coins.text); Dictionary saveValues = new Dictionary{ {"playerInventory" , inventory.getInventoryDictionary()}, {"playerHealth" , health}, {"playerCoin", playerCoin}, {"killCount", enemyKillCount}, }; DocumentReference docRef = db.Collection("PlayerData").Document(gplayAuth.userID); docRef.SetAsync(saveValues).ContinueWithOnMainThread(task => { if(task.IsCompleted){ Debug.Log("Save Completed Firestore"); } else{ Debug.Log("Failed to save data to firestore"); } }); } public void LoadPlayerData(){ FirebaseFirestore db = FirebaseFirestore.DefaultInstance; DocumentReference docRef = db.Collection("PlayerData").Document(gplayAuth.userID); docRef.GetSnapshotAsync().ContinueWithOnMainThread(task => { DocumentSnapshot snapshot = task.Result; if(snapshot.Exists){ //load data // Dictionary dic = snapshot.ToDictionary(ServerTimestampBehavior.Estimate); // Debug.Log("Reading data"); // foreach(KeyValuePair item in dic){ // Debug.Log(item.Key + " : " +item.Value.ToString()); // } //saveNameTxt.text = snapshot.GetValue("playerName"); enemyKillCount = snapshot.GetValue("killCount"); //Load coin playerCoin = snapshot.GetValue("playerCoin"); coinText.text = snapshot.GetValue("playerCoin").ToString(); //Load Health int savedHealth = snapshot.GetValue("playerHealth"); SetHealth(savedHealth); healthBar.SetHealth(savedHealth); //load Inventory Dictionary inventoryGetData = snapshot.GetValue>("playerInventory"); inventory.setInventoryData(inventoryGetData); }else{ //show error previous data doesnt exists to load Debug.Log("No previous data to load"); } }); } void CmdSetName(string nameValue){ playerName = nameValue; } void OnDirectionChanged(Vector2 oldVal, Vector2 newVal){ character.SetDirection(newVal); } void OnAnimChanged(int oldVal, int newVal){ character.AnimationManager.SetState((CharacterState)newVal); } void Update(){ if(isLocalPlayer){ if(isServer){ SetAnimationData(character.Direction, character.Animator.GetInteger("State")); }else{ CmdUpdateAnim(character.Direction, character.Animator.GetInteger("State")); } healthBar.SetHealth(health); txtEnemyKillCount.text = enemyKillCount.ToString(); txtPlayerName.text = playerName; } ShowXP(); ShowLevel(); } [Command] void CmdUpdateAnim(Vector2 direction, int animState){ SetAnimationData(direction, animState); } void SetAnimationData(Vector2 direction, int animState){ directionNetwork = direction; animIntNetwork = animState; if(!isLocalPlayer){ character.AnimationManager.SetState((CharacterState)animState); character.SetDirection(direction); } } void OnHealthChanged(int oldVal, int newVal){ SavePlayerData(); if(!isLocalPlayer){return;} healthBar.SetHealth(newVal); } public void SetHealth(int newvalue){ if(isServer){ health = newvalue; healthBar.SetHealth(newvalue); }else{ CmdSetHealth(newvalue); } } [Command] void CmdSetHealth(int newValue){ health = newValue; } public void TakeDamage(int attackDamage){ serverTakeDmg(attackDamage); // if(isLocalPlayer){ // takedmg(attackDamage); // }else if(isServer){ // RpcTakeDamage(attackDamage); // } } void serverTakeDmg(int damage){ health -= damage; if(health <=0){ RpcDeath(); death(); } } public void ShowXP(){ xpText.text = xp.ToString(); } public void ShowLevel(){ lvlText.text = lvl.ToString(); } public void OnEnemyKilled(){ int prevValue = lvl; SavePlayerData(); enemyKillCount++; if(lvl > prevValue){ StartCoroutine(uiTxtDelay(25f)); } if(enemyKillCount == 5 ){ SavePlayerData(); QuestComplete(); AddCoin(); } } IEnumerator uiTxtDelay (float delayTime){ //enable xpEnableTxt.gameObject.SetActive(true); attackDmgEnableTxt.gameObject.SetActive(true); yield return new WaitForSecondsRealtime(delayTime); //disable xpEnableTxt.gameObject.SetActive(false); attackDmgEnableTxt.gameObject.SetActive(false); } public void QuestComplete(){ //task completion logic // Strikethrough the text questText.text = "Kill 5 Enemies to claim 100Golds Completed"; Debug.Log("First quest completed"); } public void AddCoin(){ playerCoin += 100; coinText.text = playerCoin.ToString(); } [ClientRpc] public void RpcDeath(){ death(); } public void death(){ Debug.Log("Death called"); character.AnimationManager.Die(); StartCoroutine(CouroutineWaitDeath()); // throw new System.Exception(); } IEnumerator CouroutineWaitDeath (){ yield return new WaitForSecondsRealtime(3); playerRespawn(); } public void OnAttack(){ if(isLocalPlayer){ PlayAttackAnim(); if(isServer){ RpcPlayAttackAnim(); }else{ CmdPlayAttackAnim(); } } } [Command] void CmdPlayAttackAnim(){ PlayAttackAnim(); RpcPlayAttackAnim(); } [ClientRpc] void RpcPlayAttackAnim(){ if(isLocalPlayer){return;} PlayAttackAnim(); } void PlayAttackAnim(){ switch (character.WeaponType) { case WeaponType.Melee1H: case WeaponType.Paired: character.AnimationManager.Slash(twoHanded: false); break; case WeaponType.Melee2H: character.AnimationManager.Slash(twoHanded: true); break; case WeaponType.Bow: character.AnimationManager.ShotBow(); break; } } public void playerRespawn(){ Debug.Log("Respawning"); health=100; healthBar.SetHealth(health); character.AnimationManager.SetState(CharacterState.Idle); Transform newSpawnLocationPlayer = GameManager.instance.spawnPointsPlayer.GetChild(Random.Range(0,GameManager.instance.spawnPointsPlayer.childCount)); transform.position = newSpawnLocationPlayer.position; } //Pickup public void PickupObject(pickup item){ if(!isServer){ Debug.LogError("Cant call command on client, 403"); return; } if(isLocalPlayer){ pickupObject(item.lootType); }else{ RpcPickupObject(item.lootType); } } [ClientRpc] void RpcPickupObject(string type){ if(isLocalPlayer){ pickupObject(type); } } void pickupObject(string type){ inventory.AddItem(type); } public void DropPickup(string type){ if(isServer){ GameManager.instance.SpawnPickup(type,transform.position + new Vector3(1.5f,1f)); }else{ CmdDropPickup(type); } } [Command] void CmdDropPickup(string type){ GameManager.instance.SpawnPickup(type,transform.position + new Vector3(4,0)); } }