mmorpg/Assets/Script/playerNetwork.cs
2024-07-21 21:52:51 +05:30

705 lines
22 KiB
C#
Executable File

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;
using UnityEngine.SceneManagement;
using GooglePlayGames;
using UnityEngine.SocialPlatforms;
using Firebase.Auth;
using UnityEngine.UI;
using Newtonsoft.Json;
public class playerNetwork : NetworkBehaviour
{
public const float ATTACK_COOLDOWN = 0.6f;
[HideInInspector]
public StatManager statManager;
//public const int XPFORLEVEL = 10;
[SyncVar(hook =nameof(OnHealthChanged))] public int health = 100;
public Character4D character;
public characterManager characterMan;
[SyncVar(hook =nameof(OnDirectionChanged))]
public Vector2 directionNetwork;
[SyncVar(hook =nameof(OnAnimChanged))]
public int animIntNetwork;
[SyncVar(hook = nameof(onKillCountChange))]
public int enemyKillCount;
// public int xp { get{
// int val = 0;
// for(int i =5; i <= enemyKillCount; i+=5){
// val = enemyKillCount;
// }
// return val;
// }}
[SyncVar(hook = nameof(OnXpChanged))]
public int XP;
public int lvl2 { get{
return GetLevelForKills2(enemyKillCount);
}}
public int GetLevelForKills2(int kills){
int val = 0;
for(int i =10; i <= kills; i+=10){
val ++;
}
return val;
}
public int lvl{
get{
return GetLevelByXp(XP);
}
}
public int GetLevelByXp(int xp){
// int level = Mathf.CeilToInt(Mathf.Sqrt(xp/100f));
// if(level <= 0){level = 1;}
// return level;
int level = Mathf.CeilToInt(Mathf.Log(xp / 100f,2) + 1);
if(level <=0){level = 1;}
return level;
// int level = 1;
// int xpNeeded = 100;
// while (xp >= xpNeeded)
// {
// level++;
// xpNeeded = 100 * (int)Mathf.Pow(2, level - 1);
// }
// return level - 1;
}
public int GetXpForLevel(int level){
if (level <= 0)
level = 1;
return Mathf.FloorToInt(100 * Mathf.Pow(2, level - 1));
}
public float XpSliderVal{
get{
int nextLevelXp = GetXpForLevel(lvl);
int prevLevelXp = GetXpForLevel(lvl-1);
if(nextLevelXp == prevLevelXp){
prevLevelXp = 0;
}
int range = nextLevelXp - prevLevelXp;
// Debug.Log($"{XP-prevLevelXp} / {range}");
//Debug.Log($"next : {nextLevelXp}, prev: {prevLevelXp}, xp:{XP}, xpSince:{XP-prevLevelXp}");
return ((float)(XP-prevLevelXp) / (float)range);
// int nextLevel = lvl+1;
// int curLevelXp = lvl * lvl;
// int nextLevelXp = nextLevel * nextLevel;
// // Debug.Log($"Xp Calc: {XP}-{curLevelXp}/{nextLevelXp} - {curLevelXp}");
// // Debug.Log($"{curLevelXp-XP}/{nextLevelXp - curLevelXp}");
// if(XP == 0){return 0;}
// return 1f - ((float)(curLevelXp - XP) / (float)(nextLevelXp- curLevelXp));
}
}
[SyncVar]
public string playerName;
[SyncVar]
public int playerCoin;
public TMP_Text txtEnemyKillCount;
public TMP_Text txtPlayerName;
public TMP_Text questText;
public GameObject questUI;
public TMP_Text coinText;
public TMP_Text xpText;
public TMP_Text lvlText;
public Slider xpSlider;
public GameObject[] xpSliderSlots;
public TMP_Text xpEnableTxt;
//public TMP_Text attackDmgEnableTxt;
public GameObject canvas;
public Slider healthBar;
public Slider armorBar;
public Inventory inventory;
public static Transform localPlayerTransform;
public GameObject healthVfx;
public GameObject damageVfx;
public GameObject levelUpVfx;
public QuestScriptable currentQuest;
public List<QuestAction> questActions;
public List<string> completedQuests;
public void QuestFunction(QuestScriptable questData){
currentQuest = questData;
questText.text = questData.questTitle;
questUI.SetActive(true);
foreach(QuestAction quest in questActions){
if(quest.questData == questData){
quest.activate();
}
}
}
public void CompleteQuest(QuestScriptable questData){
if(questData != currentQuest){
Debug.LogError("Completed a quest that wasnt even active");
return;
}
completedQuests.Add(currentQuest.name);
currentQuest = null;
questText.text = "Quest Completed! Found 1000 coins from Cave-Chest";
playerCoin += questData.rewardAmount;
coinText.text = playerCoin.ToString();
//add delay
StartCoroutine(DelayUI());
}
IEnumerator DelayUI(){
yield return new WaitForSecondsRealtime(10f);
questUI.SetActive(false);
}
public static void registerQuestAction(QuestAction action){
localPlayerTransform.GetComponent<playerNetwork>().questActions.Add(action);
}
void Start(){
// for(int i =0; i < 2000; i+=10){
// int level = GetLevelByXp(i);
// int xp = GetXpForLevel(level);
// Debug.Log($"{i} : {level} : {xp}");
// }
if(!isLocalPlayer){
canvas.SetActive(false);
}else{
localPlayerTransform = transform;
cameraRPG.instance.SetTarget(transform);
#if UNITY_EDITOR
ResetHealthAndArmor();
#else
LoadPlayerData();
#endif
statManager.OnStatsChanged += ConfigArmorHealthSliders;
if(isServer){
playerName = gplayAuth.userNameCloud;
}
else{
CmdSetName(gplayAuth.userNameCloud);
}
}
}
public void SavePlayerData(){
#if UNITY_EDITOR
return;
#endif
Debug.Log("*** Save Method Got Called ! ***");
if(!isLoaded){
Debug.Log("*** Save Method Return ***");
return;
}
FirebaseFirestore db = FirebaseFirestore.DefaultInstance;
//int playerCoin = int.Parse(coins.text);
Dictionary<string, object> saveValues = new Dictionary<string, object>{
{"playerInventory" , JsonConvert.SerializeObject(inventory.inventoryManager.GetEntries())},
{"playerHealth" , health},
{"playerCoin", playerCoin},
{"killCount", enemyKillCount},
{"xp", XP},
{"completedQuest", completedQuests},
{"playerStats", statManager.PlayerStats},
};
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 bool isLoaded = false;
public void LoadPlayerData(){
#if UNITY_EDITOR
return;
#endif
Debug.Log("**** Data Load method got called ****");
FirebaseFirestore db = FirebaseFirestore.DefaultInstance;
DocumentReference docRef = db.Collection("PlayerData").Document(gplayAuth.userID);
docRef.GetSnapshotAsync().ContinueWithOnMainThread(task => {
DocumentSnapshot snapshot = task.Result;
if(snapshot.Exists){
Debug.Log("**** Found previous Data to load ****");
//load data
// Dictionary<string,object> dic = snapshot.ToDictionary(ServerTimestampBehavior.Estimate);
// Debug.Log("Reading data");
// foreach(KeyValuePair<string,object> item in dic){
// Debug.Log(item.Key + " : " +item.Value.ToString());
// }
//saveNameTxt.text = snapshot.GetValue<string>("playerName");
//load kills
int _enemyKillCount = snapshot.GetValue<int>("killCount");
SetEnemyKillCount(_enemyKillCount);
//load XP
XP = snapshot.GetValue<int>("xp");
//Load coin
int _playerCoin = snapshot.GetValue<int>("playerCoin");
SetPlayerCoins(_playerCoin);
// coinText.text = snapshot.GetValue<int>("playerCoin").ToString();
//Load Health
int savedHealth = snapshot.GetValue<int>("playerHealth");
SetHealth(savedHealth);
ResetHealthAndArmor();
healthBar.value =(savedHealth);
armorBar.value = savedHealth;
//load Inventory
Dictionary<int, string> inventoryGetData = JsonConvert.DeserializeObject<Dictionary<int, string>>(snapshot.GetValue<string>("playerInventory"));
inventory.inventoryManager.SetInventory(inventoryGetData);
completedQuests = snapshot.GetValue<List<string>>("completedQuest");
statManager.loadFromCloudSave(snapshot.GetValue<Dictionary<string, int>>("playerStats"));
isLoaded = true;
}else{
//show error previous data doesnt exists to load
Debug.Log("**** No previous data to load ****");
isLoaded = true;
}
});
}
void CmdSetName(string nameValue){
playerName = nameValue;
}
void OnDirectionChanged(Vector2 oldVal, Vector2 newVal){
character.SetDirection(newVal);
}
void OnAnimChanged(int oldVal, int newVal){
if(isLocalPlayer){return;}
character.AnimationManager.SetState((CharacterState)newVal);
}
float attackTimer = 0;
[HideInInspector]
public PlayerAttack playerAttack;
void Update(){
if(isLocalPlayer){
if(attackTimer >0){attackTimer-=Time.deltaTime;}
if(isServer){
SetAnimationData(character.Direction, character.Animator.GetInteger("State"));
}else{
CmdUpdateAnim(character.Direction, character.Animator.GetInteger("State"));
}
healthBar.value =(health);
armorBar.value = health;
txtEnemyKillCount.text = enemyKillCount.ToString();
coinText.text = playerCoin.ToString();
txtPlayerName.text = gplayAuth.userNameCloud;
}
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){
if(!isLocalPlayer){return;}
//
if(oldVal < newVal){
GameObject newObject = Instantiate(healthVfx , character.characterTransform());
newObject.transform.localPosition = Vector3.zero;
newObject.transform.parent = transform;
//StartCoroutine (Couroutine_autoDisableVFX(newObject));
vfxScript vfxSc = newObject.AddComponent<vfxScript>();
}else if (oldVal > newVal ){
//damage VFX
GameObject newObject = Instantiate(damageVfx , character.characterTransform());
newObject.transform.localPosition = new Vector3(0, 5f, 0);
newObject.transform.parent = transform;
//StartCoroutine (Couroutine_autoDisableVFX(newObject));
vfxScript vfxSc = newObject.AddComponent<vfxScript>();
// vfxSc.offsetVFX = new Vector3(0, 5f, 0);
// vfxSc.target = character.characterTransform();
}
SavePlayerData();
healthBar.value =(newVal);
armorBar.value = newVal;
}
// IEnumerator Couroutine_autoDisableVFX(GameObject go){
// yield return new WaitForSecondsRealtime(5f);
// Destroy(go);
// }
void onKillCountChange(int oldval, int newval){
if(!isLocalPlayer){return;}
// int prevLevel = GetLevelForKills(oldval);
// int newLevel = GetLevelForKills(newval);
SavePlayerData();
// if(newLevel > prevLevel){
// StartCoroutine(uiTxtDelay(25f));
// }
// if(enemyKillCount == 5 ){
// //SavePlayerData();
// //QuestComplete();
// AddCoin();
// }
}
void OnXpChanged(int oldVal, int newVal){
if(!isLocalPlayer){return;}
int prevLevel = GetLevelByXp(oldVal);
int newLevle = GetLevelByXp(newVal);
if(newLevle > prevLevel){
int levelChange = newLevle - prevLevel;
GameObject newObject = Instantiate(levelUpVfx , character.characterTransform());
newObject.transform.localPosition = Vector3.zero;
newObject.transform.parent = transform;
StartCoroutine(uiTxtDelay(25f, levelChange));
}
}
public void SetHealth(int newvalue){
if(isServer){
health = newvalue;
healthBar.value =(newvalue);
armorBar.value = newvalue;
}else{
CmdSetHealth(newvalue);
}
}
public void SetEnemyKillCount(int newValue){
if(isServer){
enemyKillCount = newValue;
}else{
CmdSetEnemyKillCount(newValue);
}
}
public void SetPlayerCoins(int newVal){
if(isServer){
playerCoin = newVal;
}else{
CmdSetPlayerCoin(newVal);
}
}
[Command]
void CmdSetPlayerCoin(int newVal){
playerCoin = newVal;
}
[Command]
void CmdSetEnemyKillCount(int newValue){
enemyKillCount = 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();
}
}
float xpTimer = 0;
public void ShowXP(){
if(xpTimer >0){xpTimer -= Time.deltaTime;return;}
xpTimer = 1;
xpText.text = (Mathf.RoundToInt(XP/100f) * 100f).ToString();
xpSlider.value = XpSliderVal;
for(int i=0; i < 10; i++){
float val = (float)i /10f;
xpSliderSlots[i].SetActive(xpSlider.value > val);
}
}
public void ShowLevel(){
lvlText.text = lvl.ToString();
}
public void OnEnemyKilled(int enemyLevel){
//disable take damage and disable healthbar going backwards
int prevValue = lvl;
// SavePlayerData();
enemyKillCount++;
//XP += (int)(enemyScript.XP_GAIN * (enemyLevel/2f));
XP += enemyScript.XP_GAIN_Base + Mathf.FloorToInt(enemyScript.XP_GAIN * (enemyLevel-1));
}
IEnumerator uiTxtDelay (float delayTime, int levelChange){
//enable
xpEnableTxt.gameObject.SetActive(true);
//int attackDamageChange= 5 * levelChange;
//attackDmgEnableTxt.gameObject.SetActive(true);
//attackDmgEnableTxt.text = "Attack Damage + " + attackDamageChange;
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 = "<s>Kill 5 Enemies to claim 100Golds</s> Completed";
// Debug.Log("First quest completed");
// }
public void AddCoin(){
playerCoin += 100;
coinText.text = playerCoin.ToString();
}
[ClientRpc]
public void RpcDeath(){
death();
}
public bool isDead = false;
public void death(){
Debug.Log("Death called");
character.AnimationManager.Die();
isDead = true;
StartCoroutine(CouroutineWaitDeath());
// throw new System.Exception();
}
IEnumerator CouroutineWaitDeath (){
yield return new WaitForSecondsRealtime(3);
isDead = false;
playerRespawn();
}
public void OnAttack(){
if(attackTimer > 0){
return;
}
characterMan.SetActiveWeapon(78);
attackTimer = ATTACK_COOLDOWN;
if(isLocalPlayer){
PlayAttackAnim();
playerAttack.Attack(false);
if(isServer){
RpcPlayAttackAnim();
}else{
CmdPlayAttackAnim();
}
}
}
public int MagicAttackWeaponIndex = 52;
public void OnMagicAttack(){
if(attackTimer > 0){
return;
}
attackTimer = ATTACK_COOLDOWN;
characterMan.SetActiveWeapon(MagicAttackWeaponIndex);
if(isLocalPlayer){
PlayAttackAnim();
//?
playerAttack.MagicalAttack();
playerAttack.Attack(true);
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");
// healthBar.SetMaxHealth(statManager.GetEffectiveValue("health"));
ResetHealthAndArmor();
healthBar.value = health;
character.AnimationManager.SetState(CharacterState.Idle);
Transform newSpawnLocationPlayer = GameManager.instance.spawnPointsPlayer.GetChild(Random.Range(0,GameManager.instance.spawnPointsPlayer.childCount));
transform.position = newSpawnLocationPlayer.position;
}
void ResetHealthAndArmor(){
healthBar.maxValue = statManager.GetEffectiveValue("health");
health = statManager.GetEffectiveValue("health") + statManager.GetEffectiveValue("defence");
// Debug.Log($"Setting armor bar, maxVal:{health}, minVal:{healthBar.maxValue}, val:{health}");
armorBar.maxValue = health;
armorBar.minValue = healthBar.maxValue;
armorBar.value = health;
}
void ConfigArmorHealthSliders(){
healthBar.maxValue = statManager.GetEffectiveValue("health");
float maxHealth = statManager.GetEffectiveValue("health") + statManager.GetEffectiveValue("defence");
// Debug.Log($"Setting armor bar, maxVal:{health}, minVal:{healthBar.maxValue}, val:{health}");
armorBar.maxValue = maxHealth;
armorBar.minValue = healthBar.maxValue;
armorBar.value = health;
healthBar.value = health;
}
//Pickup
public void PickupObject(pickup item){
if(!isServer){ Debug.LogError("Cant call command on client, 403"); return; }
if(isLocalPlayer){
pickupObject(item.lootData.type);
}else{
RpcPickupObject(item.lootData.type);
}
}
[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(0.85f,0.6f));
}else{
CmdDropPickup(type);
}
}
[Command]
void CmdDropPickup(string type){
GameManager.instance.SpawnPickup(type,transform.position + new Vector3(4,0));
}
public void GoBackMenu(){
startClient.instance.networkManager.StopClient();
SceneManager.LoadScene("GameLogin");
#if UNITY_EDITOR
#else
PlayGamesPlatform.Instance.SignOut();
Firebase.Auth.FirebaseAuth.DefaultInstance.SignOut();
#endif
}
}