playerNetwork.cs 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using Assets.HeroEditor4D.Common.Scripts.CharacterScripts;
  4. using Assets.HeroEditor4D.Common.Scripts.Enums;
  5. using Mirror;
  6. using TMPro;
  7. using Firebase.Firestore;
  8. using Firebase.Extensions;
  9. using Unity.VisualScripting;
  10. using UnityEngine;
  11. using UnityEngine.SceneManagement;
  12. using GooglePlayGames;
  13. using UnityEngine.SocialPlatforms;
  14. using Firebase.Auth;
  15. using UnityEngine.UI;
  16. using Newtonsoft.Json;
  17. public class playerNetwork : NetworkBehaviour
  18. {
  19. public static playerNetwork localPlayer;
  20. public invitePlayer invitePlayer;
  21. public const float ATTACK_COOLDOWN = 0.6f;
  22. [HideInInspector]
  23. public StatManager statManager;
  24. //public const int XPFORLEVEL = 10;
  25. [SyncVar(hook = nameof(OnHealthChanged))] public int health = 100;
  26. public Character4D character;
  27. public characterManager characterMan;
  28. [SyncVar(hook = nameof(OnDirectionChanged))]
  29. public Vector2 directionNetwork;
  30. [SyncVar(hook = nameof(OnAnimChanged))]
  31. public int animIntNetwork;
  32. [SyncVar(hook = nameof(onKillCountChange))]
  33. public int enemyKillCount;
  34. // public int xp { get{
  35. // int val = 0;
  36. // for(int i =5; i <= enemyKillCount; i+=5){
  37. // val = enemyKillCount;
  38. // }
  39. // return val;
  40. // }}
  41. [SyncVar(hook = nameof(OnXpChanged))]
  42. public int XP;
  43. [SyncVar]
  44. public string myPartyOwner;
  45. public int lvl2
  46. {
  47. get
  48. {
  49. return GetLevelForKills2(enemyKillCount);
  50. }
  51. }
  52. public int GetLevelForKills2(int kills)
  53. {
  54. int val = 0;
  55. for (int i = 10; i <= kills; i += 10)
  56. {
  57. val++;
  58. }
  59. return val;
  60. }
  61. public int lvl
  62. {
  63. get
  64. {
  65. return GetLevelByXp(XP);
  66. }
  67. }
  68. public int GetLevelByXp(int xp)
  69. {
  70. // int level = Mathf.CeilToInt(Mathf.Sqrt(xp/100f));
  71. // if(level <= 0){level = 1;}
  72. // return level;
  73. int level = Mathf.CeilToInt(Mathf.Log(xp / 100f, 2) + 1);
  74. if (level <= 0) { level = 1; }
  75. return level;
  76. // int level = 1;
  77. // int xpNeeded = 100;
  78. // while (xp >= xpNeeded)
  79. // {
  80. // level++;
  81. // xpNeeded = 100 * (int)Mathf.Pow(2, level - 1);
  82. // }
  83. // return level - 1;
  84. }
  85. public int GetXpForLevel(int level)
  86. {
  87. if (level <= 0)
  88. level = 1;
  89. return Mathf.FloorToInt(100 * Mathf.Pow(2, level - 1));
  90. }
  91. public float XpSliderVal
  92. {
  93. get
  94. {
  95. int nextLevelXp = GetXpForLevel(lvl);
  96. int prevLevelXp = GetXpForLevel(lvl - 1);
  97. if (nextLevelXp == prevLevelXp)
  98. {
  99. prevLevelXp = 0;
  100. }
  101. int range = nextLevelXp - prevLevelXp;
  102. // Debug.Log($"{XP-prevLevelXp} / {range}");
  103. //Debug.Log($"next : {nextLevelXp}, prev: {prevLevelXp}, xp:{XP}, xpSince:{XP-prevLevelXp}");
  104. return ((float)(XP - prevLevelXp) / (float)range);
  105. // int nextLevel = lvl+1;
  106. // int curLevelXp = lvl * lvl;
  107. // int nextLevelXp = nextLevel * nextLevel;
  108. // // Debug.Log($"Xp Calc: {XP}-{curLevelXp}/{nextLevelXp} - {curLevelXp}");
  109. // // Debug.Log($"{curLevelXp-XP}/{nextLevelXp - curLevelXp}");
  110. // if(XP == 0){return 0;}
  111. // return 1f - ((float)(curLevelXp - XP) / (float)(nextLevelXp- curLevelXp));
  112. }
  113. }
  114. [SyncVar]
  115. public string playerName;
  116. [SyncVar]
  117. public int playerCoin;
  118. [SyncVar]
  119. public string myCharJson;
  120. public TMP_Text txtEnemyKillCount;
  121. public TMP_Text txtPlayerName;
  122. public TMP_Text questText;
  123. public GameObject questUI;
  124. public TMP_Text coinText;
  125. public TMP_Text xpText;
  126. public TMP_Text lvlText;
  127. public Slider xpSlider;
  128. public GameObject[] xpSliderSlots;
  129. public TMP_Text xpEnableTxt;
  130. //public TMP_Text attackDmgEnableTxt;
  131. public GameObject canvas;
  132. public Slider healthBar;
  133. public Slider armorBar;
  134. public Inventory inventory;
  135. public static Transform localPlayerTransform;
  136. public GameObject healthVfx;
  137. public GameObject damageVfx;
  138. public GameObject levelUpVfx;
  139. public QuestScriptable currentQuest;
  140. public List<QuestAction> questActions;
  141. public List<string> completedQuests;
  142. public GameObject projectile;
  143. public GameObject arrowRange;
  144. public string selectedCharacterJson = CharacterSelection.selectedCharJson;
  145. public void SetActiveQuest(QuestScriptable questData)
  146. {
  147. currentQuest = questData;
  148. questText.text = questData.questTitle;
  149. questUI.SetActive(true);
  150. foreach (QuestAction quest in questActions)
  151. {
  152. if (quest.questData == questData)
  153. {
  154. quest.activate();
  155. }
  156. }
  157. }
  158. public void CompleteQuest(QuestScriptable questData)
  159. {
  160. if (questData != currentQuest)
  161. {
  162. Debug.LogError("Completed a quest that wasnt active");
  163. return;
  164. }
  165. completedQuests.Add(currentQuest.questName);
  166. currentQuest = null;
  167. questText.text = "Quest Completed!";
  168. playerCoin += questData.rewardAmount;
  169. coinText.text = playerCoin.ToString();
  170. //add delay
  171. StartCoroutine(DelayUI());
  172. }
  173. public void CancelledQuest()
  174. {
  175. questText.text = "Quest Cancelled: " + currentQuest.questTitle;
  176. //
  177. currentQuest = null;
  178. StartCoroutine(DelayUI());
  179. }
  180. IEnumerator DelayUI()
  181. {
  182. yield return new WaitForSecondsRealtime(10f);
  183. questUI.SetActive(false);
  184. }
  185. public static void registerQuestAction(QuestAction action)
  186. {
  187. localPlayerTransform.GetComponent<playerNetwork>().questActions.Add(action);
  188. }
  189. void Awake()
  190. {
  191. invitePlayer = GetComponent<invitePlayer>();
  192. rangeEnemyFind = GetComponent<rangeEnemyFinder>();
  193. }
  194. void Start()
  195. {
  196. #if UNITY_EDITOR
  197. if (isServer)
  198. {
  199. playerName = "Player" + Random.Range(0, 100);
  200. }
  201. #endif
  202. if (!isLocalPlayer)
  203. {
  204. canvas.SetActive(false);
  205. if (!isServer)
  206. {
  207. CmdRequestCharJson();
  208. }
  209. }
  210. else
  211. {
  212. localPlayerTransform = transform;
  213. localPlayer = this;
  214. cameraRPG.instance.SetTarget(transform);
  215. #if UNITY_EDITOR
  216. ResetHealthAndArmor();
  217. #else
  218. LoadPlayerData();
  219. #endif
  220. statManager.OnStatsChanged += ConfigArmorHealthSliders;
  221. if (isServer)
  222. {
  223. playerName = gplayAuth.userNameCloud;
  224. myCharJson = CharacterSelection.selectedCharJson;
  225. RpcBroadcastCharJson(CharacterSelection.selectedCharJson);
  226. }
  227. else
  228. {
  229. if (gplayAuth.userNameCloud.Length > 0)
  230. {
  231. CmdSetName(gplayAuth.userNameCloud);
  232. }
  233. else
  234. {
  235. CmdSetName("Player" + Random.Range(0, 100));
  236. }
  237. CmdSetCharJson(CharacterSelection.selectedCharJson);
  238. }
  239. }
  240. }
  241. [Command]
  242. public void CmdInvitePlayer(string otherPlayerName)
  243. {
  244. if (myPartyOwner == null || myPartyOwner.Length == 0)
  245. {
  246. FindPlayerByName(otherPlayerName).ShowInvite(playerName);
  247. }
  248. else
  249. {
  250. FindPlayerByName(otherPlayerName).ShowInvite(myPartyOwner);
  251. }
  252. }
  253. public void ShowInvite(string ownerName)
  254. {
  255. RpcInvitePlayer(ownerName);
  256. }
  257. [ClientRpc]
  258. void RpcInvitePlayer(string playerName)
  259. {
  260. if (!isLocalPlayer) { return; }
  261. invitePlayer.ShowInvite(playerName);
  262. }
  263. [Command]
  264. public void CmdAcceptInvite(string otherPlayerName)
  265. {
  266. myPartyOwner = otherPlayerName;
  267. Debug.Log("Invite accepted: " + myPartyOwner);
  268. }
  269. [Command]
  270. public void CmdLeaveParty()
  271. {
  272. myPartyOwner = null;
  273. }
  274. playerNetwork FindPlayerByName(string playerName)
  275. {
  276. playerNetwork[] players = FindObjectsOfType<playerNetwork>();
  277. foreach (playerNetwork player in players)
  278. {
  279. if (player.playerName == playerName)
  280. {
  281. return player;
  282. }
  283. }
  284. return null;
  285. }
  286. void LoadCharFromJson(string json)
  287. {
  288. if (json.Length <= 0) { return; }
  289. character.FromJson(json, true);
  290. }
  291. public void SavePlayerData()
  292. {
  293. #if UNITY_EDITOR
  294. return;
  295. #endif
  296. Debug.Log("*** Save Method Got Called ! ***");
  297. if (!isLoaded)
  298. {
  299. Debug.Log("*** Save Method Return ***");
  300. return;
  301. }
  302. FirebaseFirestore db = FirebaseFirestore.DefaultInstance;
  303. //int playerCoin = int.Parse(coins.text);
  304. Dictionary<string, object> saveValues = new Dictionary<string, object>{
  305. {"playerInventory" , JsonConvert.SerializeObject(inventory.inventoryManager.GetEntries())},
  306. {"playerHealth" , health},
  307. {"playerCoin", playerCoin},
  308. {"killCount", enemyKillCount},
  309. {"xp", XP},
  310. {"completedQuest", completedQuests},
  311. {"playerStats", statManager.PlayerStats},
  312. {"characterJson", selectedCharacterJson},
  313. };
  314. DocumentReference docRef = db.Collection("PlayerData").Document(gplayAuth.userID);
  315. docRef.SetAsync(saveValues).ContinueWithOnMainThread(task =>
  316. {
  317. if (task.IsCompleted)
  318. {
  319. Debug.Log("**** Save Completed Firestore ****");
  320. }
  321. else
  322. {
  323. Debug.Log("**** Failed to save data to firestore ****");
  324. }
  325. });
  326. }
  327. public bool isLoaded = false;
  328. public void LoadPlayerData()
  329. {
  330. #if UNITY_EDITOR
  331. return;
  332. #endif
  333. Debug.Log("**** Data Load method got called ****");
  334. FirebaseFirestore db = FirebaseFirestore.DefaultInstance;
  335. DocumentReference docRef = db.Collection("PlayerData").Document(gplayAuth.userID);
  336. docRef.GetSnapshotAsync().ContinueWithOnMainThread(task =>
  337. {
  338. DocumentSnapshot snapshot = task.Result;
  339. if (snapshot.Exists)
  340. {
  341. Debug.Log("**** Found previous Data to load ****");
  342. //load data
  343. // Dictionary<string,object> dic = snapshot.ToDictionary(ServerTimestampBehavior.Estimate);
  344. // Debug.Log("Reading data");
  345. // foreach(KeyValuePair<string,object> item in dic){
  346. // Debug.Log(item.Key + " : " +item.Value.ToString());
  347. // }
  348. //saveNameTxt.text = snapshot.GetValue<string>("playerName");
  349. //load kills
  350. int _enemyKillCount = snapshot.GetValue<int>("killCount");
  351. SetEnemyKillCount(_enemyKillCount);
  352. //load XP
  353. XP = snapshot.GetValue<int>("xp");
  354. //Load coin
  355. int _playerCoin = snapshot.GetValue<int>("playerCoin");
  356. SetPlayerCoins(_playerCoin);
  357. // coinText.text = snapshot.GetValue<int>("playerCoin").ToString();
  358. //Load Health
  359. int savedHealth = snapshot.GetValue<int>("playerHealth");
  360. SetHealth(savedHealth);
  361. ResetHealthAndArmor();
  362. healthBar.value = (savedHealth);
  363. armorBar.value = savedHealth;
  364. //load Inventory
  365. Dictionary<int, string> inventoryGetData = JsonConvert.DeserializeObject<Dictionary<int, string>>(snapshot.GetValue<string>("playerInventory"));
  366. inventory.inventoryManager.SetInventory(inventoryGetData);
  367. completedQuests = snapshot.GetValue<List<string>>("completedQuest");
  368. //stats
  369. statManager.loadFromCloudSave(snapshot.GetValue<Dictionary<string, int>>("playerStats"));
  370. isLoaded = true;
  371. }
  372. else
  373. {
  374. //show error previous data doesnt exists to load
  375. Debug.Log("**** No previous data to load ****");
  376. isLoaded = true;
  377. }
  378. });
  379. }
  380. [Command]
  381. void CmdSetName(string nameValue)
  382. {
  383. playerName = nameValue;
  384. }
  385. [Command(requiresAuthority = false)]
  386. void CmdRequestCharJson()
  387. {
  388. RpcBroadcastCharJson(myCharJson);
  389. }
  390. [Command]
  391. void CmdSetCharJson(string newValue)
  392. {
  393. myCharJson = newValue;
  394. RpcBroadcastCharJson(newValue);
  395. LoadCharFromJson(newValue);
  396. }
  397. [ClientRpc]
  398. void RpcBroadcastCharJson(string newValue)
  399. {
  400. LoadCharFromJson(newValue);
  401. }
  402. void OnDirectionChanged(Vector2 oldVal, Vector2 newVal)
  403. {
  404. character.SetDirection(newVal);
  405. }
  406. void OnAnimChanged(int oldVal, int newVal)
  407. {
  408. if (isLocalPlayer) { return; }
  409. character.AnimationManager.SetState((CharacterState)newVal);
  410. }
  411. rangeEnemyFinder rangeEnemyFind;
  412. enemyScript closestEnemy => rangeEnemyFind.targetEnemy;
  413. float attackTimer = 0;
  414. [HideInInspector]
  415. public PlayerAttack playerAttack;
  416. void Update()
  417. {
  418. if (isLocalPlayer)
  419. {
  420. if (attackTimer > 0) { attackTimer -= Time.deltaTime; }
  421. if (isServer)
  422. {
  423. SetAnimationData(character.Direction, character.Animator.GetInteger("State"));
  424. }
  425. else
  426. {
  427. CmdUpdateAnim(character.Direction, character.Animator.GetInteger("State"));
  428. }
  429. healthBar.value = (health);
  430. armorBar.value = health;
  431. txtEnemyKillCount.text = enemyKillCount.ToString();
  432. coinText.text = playerCoin.ToString();
  433. txtPlayerName.text = gplayAuth.userNameCloud;
  434. if (myPartyOwner != null && myPartyOwner.Length > 0)
  435. {
  436. invitePlayer.InParty(myPartyOwner);
  437. }
  438. else
  439. {
  440. invitePlayer.InParty("");
  441. }
  442. }
  443. ShowXP();
  444. ShowLevel();
  445. }
  446. [Command]
  447. void CmdUpdateAnim(Vector2 direction, int animState)
  448. {
  449. SetAnimationData(direction, animState);
  450. }
  451. void SetAnimationData(Vector2 direction, int animState)
  452. {
  453. directionNetwork = direction;
  454. animIntNetwork = animState;
  455. if (!isLocalPlayer)
  456. {
  457. character.AnimationManager.SetState((CharacterState)animState);
  458. character.SetDirection(direction);
  459. }
  460. }
  461. void OnHealthChanged(int oldVal, int newVal)
  462. {
  463. if (!isLocalPlayer) { return; }
  464. //
  465. if (oldVal < newVal)
  466. {
  467. GameObject newObject = Instantiate(healthVfx, character.characterTransform());
  468. newObject.transform.localPosition = Vector3.zero;
  469. newObject.transform.parent = transform;
  470. //StartCoroutine (Couroutine_autoDisableVFX(newObject));
  471. vfxScript vfxSc = newObject.AddComponent<vfxScript>();
  472. }
  473. else if (oldVal > newVal)
  474. {
  475. //damage VFX
  476. GameObject newObject = Instantiate(damageVfx, character.characterTransform());
  477. newObject.transform.localPosition = new Vector3(0, 5f, 0);
  478. newObject.transform.parent = transform;
  479. //StartCoroutine (Couroutine_autoDisableVFX(newObject));
  480. vfxScript vfxSc = newObject.AddComponent<vfxScript>();
  481. // vfxSc.offsetVFX = new Vector3(0, 5f, 0);
  482. // vfxSc.target = character.characterTransform();
  483. }
  484. SavePlayerData();
  485. healthBar.value = (newVal);
  486. armorBar.value = newVal;
  487. }
  488. // IEnumerator Couroutine_autoDisableVFX(GameObject go){
  489. // yield return new WaitForSecondsRealtime(5f);
  490. // Destroy(go);
  491. // }
  492. void onKillCountChange(int oldval, int newval)
  493. {
  494. if (!isLocalPlayer) { return; }
  495. // int prevLevel = GetLevelForKills(oldval);
  496. // int newLevel = GetLevelForKills(newval);
  497. SavePlayerData();
  498. // if(newLevel > prevLevel){
  499. // StartCoroutine(uiTxtDelay(25f));
  500. // }
  501. // if(enemyKillCount == 5 ){
  502. // //SavePlayerData();
  503. // //QuestComplete();
  504. // AddCoin();
  505. // }
  506. }
  507. void OnXpChanged(int oldVal, int newVal)
  508. {
  509. if (!isLocalPlayer) { return; }
  510. int prevLevel = GetLevelByXp(oldVal);
  511. int newLevle = GetLevelByXp(newVal);
  512. if (newLevle > prevLevel)
  513. {
  514. int levelChange = newLevle - prevLevel;
  515. GameObject newObject = Instantiate(levelUpVfx, character.characterTransform());
  516. newObject.transform.localPosition = Vector3.zero;
  517. newObject.transform.parent = transform;
  518. StartCoroutine(uiTxtDelay(25f, levelChange));
  519. }
  520. }
  521. public void SetHealth(int newvalue)
  522. {
  523. if (isServer)
  524. {
  525. health = newvalue;
  526. healthBar.value = (newvalue);
  527. armorBar.value = newvalue;
  528. }
  529. else
  530. {
  531. CmdSetHealth(newvalue);
  532. }
  533. }
  534. public void SetEnemyKillCount(int newValue)
  535. {
  536. if (isServer)
  537. {
  538. enemyKillCount = newValue;
  539. }
  540. else
  541. {
  542. CmdSetEnemyKillCount(newValue);
  543. }
  544. }
  545. public void SetPlayerCoins(int newVal)
  546. {
  547. if (isServer)
  548. {
  549. playerCoin = newVal;
  550. }
  551. else
  552. {
  553. CmdSetPlayerCoin(newVal);
  554. }
  555. }
  556. [Command]
  557. void CmdSetPlayerCoin(int newVal)
  558. {
  559. playerCoin = newVal;
  560. }
  561. [Command]
  562. void CmdSetEnemyKillCount(int newValue)
  563. {
  564. enemyKillCount = newValue;
  565. }
  566. [Command]
  567. void CmdSetHealth(int newValue)
  568. {
  569. health = newValue;
  570. }
  571. public void TakeDamage(int attackDamage)
  572. {
  573. serverTakeDmg(attackDamage);
  574. // if(isLocalPlayer){
  575. // takedmg(attackDamage);
  576. // }else if(isServer){
  577. // RpcTakeDamage(attackDamage);
  578. // }
  579. }
  580. void serverTakeDmg(int damage)
  581. {
  582. health -= damage;
  583. if (health <= 0)
  584. {
  585. RpcDeath();
  586. death();
  587. }
  588. }
  589. float xpTimer = 0;
  590. public void ShowXP()
  591. {
  592. if (xpTimer > 0) { xpTimer -= Time.deltaTime; return; }
  593. xpTimer = 1;
  594. xpText.text = (Mathf.RoundToInt(XP / 100f) * 100f).ToString();
  595. xpSlider.value = XpSliderVal;
  596. for (int i = 0; i < 10; i++)
  597. {
  598. float val = (float)i / 10f;
  599. xpSliderSlots[i].SetActive(xpSlider.value > val);
  600. }
  601. }
  602. public void ShowLevel()
  603. {
  604. lvlText.text = lvl.ToString();
  605. }
  606. public void OnEnemyKilled(int enemyLevel)
  607. {
  608. //disable take damage and disable healthbar going backwards
  609. int prevValue = lvl;
  610. // SavePlayerData();
  611. enemyKillCount++;
  612. //XP += (int)(enemyScript.XP_GAIN * (enemyLevel/2f));
  613. XP += enemyScript.XP_GAIN_Base + Mathf.FloorToInt(enemyScript.XP_GAIN * (enemyLevel - 1));
  614. }
  615. IEnumerator uiTxtDelay(float delayTime, int levelChange)
  616. {
  617. //enable
  618. xpEnableTxt.gameObject.SetActive(true);
  619. //int attackDamageChange= 5 * levelChange;
  620. //attackDmgEnableTxt.gameObject.SetActive(true);
  621. //attackDmgEnableTxt.text = "Attack Damage + " + attackDamageChange;
  622. yield return new WaitForSecondsRealtime(delayTime);
  623. //disable
  624. xpEnableTxt.gameObject.SetActive(false);
  625. //attackDmgEnableTxt.gameObject.SetActive(false);
  626. }
  627. // public void QuestComplete(){
  628. // //task completion logic
  629. // // Strikethrough the text
  630. // //questText.text = "<s>Kill 5 Enemies to claim 100Golds</s> Completed";
  631. // Debug.Log("First quest completed");
  632. // }
  633. public void AddCoin()
  634. {
  635. playerCoin += 100;
  636. coinText.text = playerCoin.ToString();
  637. }
  638. [ClientRpc]
  639. public void RpcDeath()
  640. {
  641. death();
  642. }
  643. public bool isDead = false;
  644. public void death()
  645. {
  646. Debug.Log("Death called");
  647. character.AnimationManager.Die();
  648. isDead = true;
  649. StartCoroutine(CouroutineWaitDeath());
  650. // throw new System.Exception();
  651. }
  652. IEnumerator CouroutineWaitDeath()
  653. {
  654. yield return new WaitForSecondsRealtime(3);
  655. isDead = false;
  656. playerRespawn();
  657. }
  658. public void OnAttack()
  659. {
  660. if (attackTimer > 0)
  661. {
  662. return;
  663. }
  664. //characterMan.SetActiveWeapon(78);
  665. attackTimer = ATTACK_COOLDOWN;
  666. if (isLocalPlayer)
  667. {
  668. PlayAttackAnim();
  669. playerAttack.Attack(false);
  670. if (isServer)
  671. {
  672. RpcPlayAttackAnim();
  673. }
  674. else
  675. {
  676. CmdPlayAttackAnim();
  677. }
  678. }
  679. }
  680. [SerializeField] public float arrowSpeed = 2.0f;
  681. [SerializeField] public float arrowShootOffset = 1;
  682. [SerializeField] public float arrowShootHeightOffset = 1;
  683. public void OnRangeAttack()
  684. {
  685. if (attackTimer > 0)
  686. {
  687. return;
  688. }
  689. if (closestEnemy == null) { return; }
  690. attackTimer = ATTACK_COOLDOWN;
  691. characterMan.EquipBow();
  692. PlayAttackAnim();
  693. StartCoroutine(ArrowShootDelay());
  694. // arrowRange.transform.position = startingPosition;
  695. //TODO: Deal Damage once it hits enemy
  696. }
  697. public float arrowDelay;
  698. IEnumerator ArrowShootDelay()
  699. {
  700. yield return new WaitForSeconds(arrowDelay);
  701. Vector3 startingPosition = transform.position;
  702. Vector3 destination = closestEnemy.transform.position;
  703. //TODO: Move attack projectile from startingPosition to destination
  704. Vector3 direction = (destination - startingPosition).normalized;
  705. startingPosition += (direction * arrowShootOffset);
  706. startingPosition += (Vector3.up * arrowShootHeightOffset);
  707. destination += (Vector3.up * arrowShootHeightOffset);
  708. // Quaternion rotation = Quaternion.LookRotation(direction);
  709. float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
  710. Quaternion rotation = Quaternion.Euler(0, 0, angle - 90f);
  711. GameObject newArrow = Instantiate(arrowRange, transform.position + (direction * arrowShootOffset), rotation);
  712. StartCoroutine(moveArrow(newArrow.transform, startingPosition, destination, closestEnemy));
  713. }
  714. public int RangeDmg = 10;
  715. IEnumerator moveArrow(Transform arrow, Vector3 start, Vector3 destination, enemyScript target)
  716. {
  717. float dist = Vector3.Distance(start, destination);
  718. float duration = dist / arrowSpeed;
  719. float timer = 0f;
  720. while (timer < duration)
  721. {
  722. arrow.position = Vector3.Lerp(start, destination, timer / duration);
  723. timer += Time.deltaTime;
  724. yield return null;
  725. }
  726. target.TakeDamage(RangeDmg, netId);
  727. Destroy(arrow.gameObject);
  728. }
  729. public int MagicAttackWeaponIndex = 52;
  730. public void OnMagicAttack()
  731. {
  732. if (attackTimer > 0)
  733. {
  734. return;
  735. }
  736. attackTimer = ATTACK_COOLDOWN;
  737. //characterMan.SetActiveWeapon(MagicAttackWeaponIndex);
  738. if (isLocalPlayer)
  739. {
  740. PlayAttackAnim();
  741. //?
  742. playerAttack.MagicalAttack();
  743. playerAttack.Attack(true);
  744. if (isServer)
  745. {
  746. RpcPlayAttackAnim();
  747. }
  748. else
  749. {
  750. CmdPlayAttackAnim();
  751. }
  752. }
  753. }
  754. [Command]
  755. void CmdPlayAttackAnim()
  756. {
  757. PlayAttackAnim();
  758. RpcPlayAttackAnim();
  759. }
  760. [ClientRpc]
  761. void RpcPlayAttackAnim()
  762. {
  763. if (isLocalPlayer) { return; }
  764. PlayAttackAnim();
  765. }
  766. void PlayAttackAnim()
  767. {
  768. switch (character.WeaponType)
  769. {
  770. case WeaponType.Melee1H:
  771. case WeaponType.Paired:
  772. character.AnimationManager.Slash(twoHanded: false);
  773. break;
  774. case WeaponType.Melee2H:
  775. character.AnimationManager.Slash(twoHanded: true);
  776. break;
  777. case WeaponType.Bow:
  778. character.AnimationManager.ShotBow();
  779. break;
  780. }
  781. }
  782. public void playerRespawn()
  783. {
  784. Debug.Log("Respawning");
  785. // healthBar.SetMaxHealth(statManager.GetEffectiveValue("health"));
  786. ResetHealthAndArmor();
  787. healthBar.value = health;
  788. character.AnimationManager.SetState(CharacterState.Idle);
  789. Transform newSpawnLocationPlayer = GameManager.instance.spawnPointsPlayer.GetChild(Random.Range(0, GameManager.instance.spawnPointsPlayer.childCount));
  790. transform.position = newSpawnLocationPlayer.position;
  791. }
  792. void ResetHealthAndArmor()
  793. {
  794. healthBar.maxValue = statManager.GetEffectiveValue("health");
  795. health = statManager.GetEffectiveValue("health") + statManager.GetEffectiveValue("defence");
  796. // Debug.Log($"Setting armor bar, maxVal:{health}, minVal:{healthBar.maxValue}, val:{health}");
  797. armorBar.maxValue = health;
  798. armorBar.minValue = healthBar.maxValue;
  799. armorBar.value = health;
  800. }
  801. void ConfigArmorHealthSliders()
  802. {
  803. healthBar.maxValue = statManager.GetEffectiveValue("health");
  804. float maxHealth = statManager.GetEffectiveValue("health") + statManager.GetEffectiveValue("defence");
  805. // Debug.Log($"Setting armor bar, maxVal:{health}, minVal:{healthBar.maxValue}, val:{health}");
  806. armorBar.maxValue = maxHealth;
  807. armorBar.minValue = healthBar.maxValue;
  808. armorBar.value = health;
  809. healthBar.value = health;
  810. }
  811. //Pickup
  812. public void PickupObject(pickup item)
  813. {
  814. if (!isServer) { Debug.LogError("Cant call command on client, 403"); return; }
  815. if (isLocalPlayer)
  816. {
  817. pickupObject(item.lootData.type);
  818. }
  819. else
  820. {
  821. RpcPickupObject(item.lootData.type);
  822. }
  823. }
  824. [ClientRpc]
  825. void RpcPickupObject(string type)
  826. {
  827. if (isLocalPlayer)
  828. {
  829. pickupObject(type);
  830. }
  831. }
  832. void pickupObject(string type)
  833. {
  834. inventory.AddItem(type);
  835. }
  836. public void DropPickup(string type)
  837. {
  838. if (isServer)
  839. {
  840. GameManager.instance.SpawnPickup(type, transform.position + new Vector3(0.85f, 0.6f));
  841. }
  842. else
  843. {
  844. CmdDropPickup(type);
  845. }
  846. }
  847. [Command]
  848. void CmdDropPickup(string type)
  849. {
  850. GameManager.instance.SpawnPickup(type, transform.position + new Vector3(4, 0));
  851. }
  852. int magicalDmg = 0;
  853. public void MagicalAttack(Vector3 direction, float magicalProjectileSpawnOffset, int dmg)
  854. {
  855. if (isServer)
  856. {
  857. magicalAttack(direction, magicalProjectileSpawnOffset, dmg);
  858. }
  859. else
  860. {
  861. CmdMagicalAttack(direction, magicalProjectileSpawnOffset, dmg);
  862. }
  863. }
  864. [Command]
  865. void CmdMagicalAttack(Vector3 direction, float magicalProjectileSpawnOffset, int dmg)
  866. {
  867. magicalAttack(direction, magicalProjectileSpawnOffset, dmg);
  868. }
  869. void magicalAttack(Vector3 direction, float magicalProjectileSpawnOffset, int dmg)
  870. {
  871. magicalDmg = dmg;
  872. GameObject projectileSpawned = Instantiate(projectile, transform.position + (direction * magicalProjectileSpawnOffset), Quaternion.identity);
  873. RangeProjectile _projectile = projectileSpawned.GetComponent<RangeProjectile>();
  874. _projectile.direction = direction;
  875. _projectile.OnHit.AddListener(OnMagicalHit);
  876. _projectile.shooterId = netId;
  877. NetworkServer.Spawn(projectileSpawned);
  878. }
  879. void OnMagicalHit(enemyScript victim)
  880. {
  881. //magical damage with intelligance stat ?
  882. //int damageamount = magicalDmg + (lvl * 5);
  883. int damageamount = magicalDmg + (statManager.GetEffectiveValue("intelligence") * 2);
  884. Debug.Log("magic damage amount " + damageamount);
  885. victim.TakeMagicalDamage(damageamount, netId);
  886. }
  887. public void GoBackMenu()
  888. {
  889. startClient.instance.networkManager.StopClient();
  890. SceneManager.LoadScene("GameLogin");
  891. #if UNITY_EDITOR || UNITY_SERVER || UNITY_STANDALONE_WIN
  892. #else
  893. PlayGamesPlatform.Instance.SignOut();
  894. Firebase.Auth.FirebaseAuth.DefaultInstance.SignOut();
  895. #endif
  896. }
  897. }