1074 lines
29 KiB
C#
1074 lines
29 KiB
C#
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 static playerNetwork localPlayer;
|
|
public invitePlayer invitePlayer;
|
|
|
|
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;
|
|
|
|
[SyncVar]
|
|
public string myPartyOwner;
|
|
|
|
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;
|
|
|
|
[SyncVar]
|
|
public string myCharJson;
|
|
|
|
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 GameObject projectile;
|
|
public GameObject arrowRange;
|
|
|
|
public string selectedCharacterJson = CharacterSelection.selectedCharJson;
|
|
|
|
public void SetActiveQuest(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 active");
|
|
return;
|
|
}
|
|
completedQuests.Add(currentQuest.questName);
|
|
currentQuest = null;
|
|
|
|
questText.text = "Quest Completed!";
|
|
playerCoin += questData.rewardAmount;
|
|
coinText.text = playerCoin.ToString();
|
|
//add delay
|
|
StartCoroutine(DelayUI());
|
|
|
|
|
|
}
|
|
public void CancelledQuest()
|
|
{
|
|
|
|
questText.text = "Quest Cancelled: " + currentQuest.questTitle;
|
|
//
|
|
currentQuest = null;
|
|
|
|
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 Awake()
|
|
{
|
|
invitePlayer = GetComponent<invitePlayer>();
|
|
rangeEnemyFind = GetComponent<rangeEnemyFinder>();
|
|
}
|
|
void Start()
|
|
{
|
|
|
|
#if UNITY_EDITOR
|
|
if (isServer)
|
|
{
|
|
playerName = "Player" + Random.Range(0, 100);
|
|
}
|
|
#endif
|
|
|
|
if (!isLocalPlayer)
|
|
{
|
|
canvas.SetActive(false);
|
|
if (!isServer)
|
|
{
|
|
CmdRequestCharJson();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
localPlayerTransform = transform;
|
|
localPlayer = this;
|
|
cameraRPG.instance.SetTarget(transform);
|
|
#if UNITY_EDITOR
|
|
ResetHealthAndArmor();
|
|
#else
|
|
LoadPlayerData();
|
|
#endif
|
|
|
|
statManager.OnStatsChanged += ConfigArmorHealthSliders;
|
|
|
|
if (isServer)
|
|
{
|
|
playerName = gplayAuth.userNameCloud;
|
|
myCharJson = CharacterSelection.selectedCharJson;
|
|
RpcBroadcastCharJson(CharacterSelection.selectedCharJson);
|
|
}
|
|
else
|
|
{
|
|
if (gplayAuth.userNameCloud.Length > 0)
|
|
{
|
|
CmdSetName(gplayAuth.userNameCloud);
|
|
}
|
|
else
|
|
{
|
|
CmdSetName("Player" + Random.Range(0, 100));
|
|
}
|
|
CmdSetCharJson(CharacterSelection.selectedCharJson);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
[Command]
|
|
public void CmdInvitePlayer(string otherPlayerName)
|
|
{
|
|
if (myPartyOwner == null || myPartyOwner.Length == 0)
|
|
{
|
|
FindPlayerByName(otherPlayerName).ShowInvite(playerName);
|
|
}
|
|
else
|
|
{
|
|
FindPlayerByName(otherPlayerName).ShowInvite(myPartyOwner);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
public void ShowInvite(string ownerName)
|
|
{
|
|
RpcInvitePlayer(ownerName);
|
|
}
|
|
|
|
[ClientRpc]
|
|
void RpcInvitePlayer(string playerName)
|
|
{
|
|
if (!isLocalPlayer) { return; }
|
|
|
|
invitePlayer.ShowInvite(playerName);
|
|
}
|
|
|
|
[Command]
|
|
public void CmdAcceptInvite(string otherPlayerName)
|
|
{
|
|
myPartyOwner = otherPlayerName;
|
|
Debug.Log("Invite accepted: " + myPartyOwner);
|
|
}
|
|
|
|
[Command]
|
|
public void CmdLeaveParty()
|
|
{
|
|
myPartyOwner = null;
|
|
}
|
|
|
|
playerNetwork FindPlayerByName(string playerName)
|
|
{
|
|
playerNetwork[] players = FindObjectsOfType<playerNetwork>();
|
|
foreach (playerNetwork player in players)
|
|
{
|
|
if (player.playerName == playerName)
|
|
{
|
|
return player;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
void LoadCharFromJson(string json)
|
|
{
|
|
if (json.Length <= 0) { return; }
|
|
character.FromJson(json, true);
|
|
}
|
|
|
|
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},
|
|
{"characterJson", selectedCharacterJson},
|
|
|
|
};
|
|
|
|
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");
|
|
//stats
|
|
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;
|
|
|
|
}
|
|
});
|
|
}
|
|
[Command]
|
|
void CmdSetName(string nameValue)
|
|
{
|
|
playerName = nameValue;
|
|
}
|
|
|
|
[Command(requiresAuthority = false)]
|
|
void CmdRequestCharJson()
|
|
{
|
|
RpcBroadcastCharJson(myCharJson);
|
|
}
|
|
|
|
[Command]
|
|
void CmdSetCharJson(string newValue)
|
|
{
|
|
myCharJson = newValue;
|
|
RpcBroadcastCharJson(newValue);
|
|
LoadCharFromJson(newValue);
|
|
}
|
|
[ClientRpc]
|
|
void RpcBroadcastCharJson(string newValue)
|
|
{
|
|
LoadCharFromJson(newValue);
|
|
}
|
|
|
|
void OnDirectionChanged(Vector2 oldVal, Vector2 newVal)
|
|
{
|
|
character.SetDirection(newVal);
|
|
}
|
|
|
|
void OnAnimChanged(int oldVal, int newVal)
|
|
{
|
|
if (isLocalPlayer) { return; }
|
|
character.AnimationManager.SetState((CharacterState)newVal);
|
|
}
|
|
|
|
rangeEnemyFinder rangeEnemyFind;
|
|
|
|
enemyScript closestEnemy => rangeEnemyFind.targetEnemy;
|
|
|
|
|
|
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;
|
|
|
|
if (myPartyOwner != null && myPartyOwner.Length > 0)
|
|
{
|
|
invitePlayer.InParty(myPartyOwner);
|
|
}
|
|
else
|
|
{
|
|
invitePlayer.InParty("");
|
|
|
|
}
|
|
}
|
|
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();
|
|
}
|
|
}
|
|
}
|
|
|
|
[SerializeField] public float arrowSpeed = 2.0f;
|
|
[SerializeField] public float arrowShootOffset = 1;
|
|
[SerializeField] public float arrowShootHeightOffset = 1;
|
|
|
|
public void OnRangeAttack()
|
|
{
|
|
if (attackTimer > 0)
|
|
{
|
|
return;
|
|
}
|
|
if (closestEnemy == null) { return; }
|
|
|
|
attackTimer = ATTACK_COOLDOWN;
|
|
|
|
characterMan.EquipBow();
|
|
PlayAttackAnim();
|
|
|
|
StartCoroutine(ArrowShootDelay());
|
|
// arrowRange.transform.position = startingPosition;
|
|
|
|
//TODO: Deal Damage once it hits enemy
|
|
|
|
}
|
|
public float arrowDelay;
|
|
IEnumerator ArrowShootDelay()
|
|
{
|
|
|
|
yield return new WaitForSeconds(arrowDelay);
|
|
|
|
Vector3 startingPosition = transform.position;
|
|
Vector3 destination = closestEnemy.transform.position;
|
|
|
|
//TODO: Move attack projectile from startingPosition to destination
|
|
Vector3 direction = (destination - startingPosition).normalized;
|
|
startingPosition += (direction * arrowShootOffset);
|
|
startingPosition += (Vector3.up * arrowShootHeightOffset);
|
|
destination += (Vector3.up * arrowShootHeightOffset);
|
|
// Quaternion rotation = Quaternion.LookRotation(direction);
|
|
float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
|
|
Quaternion rotation = Quaternion.Euler(0, 0, angle - 90f);
|
|
|
|
GameObject newArrow = Instantiate(arrowRange, transform.position + (direction * arrowShootOffset), rotation);
|
|
|
|
StartCoroutine(moveArrow(newArrow.transform, startingPosition, destination, closestEnemy));
|
|
|
|
}
|
|
public int RangeDmg = 10;
|
|
|
|
IEnumerator moveArrow(Transform arrow, Vector3 start, Vector3 destination, enemyScript target)
|
|
{
|
|
|
|
float dist = Vector3.Distance(start, destination);
|
|
|
|
float duration = dist / arrowSpeed;
|
|
|
|
float timer = 0f;
|
|
|
|
while (timer < duration)
|
|
{
|
|
|
|
arrow.position = Vector3.Lerp(start, destination, timer / duration);
|
|
|
|
timer += Time.deltaTime;
|
|
yield return null;
|
|
}
|
|
|
|
target.TakeDamage(RangeDmg, netId);
|
|
|
|
Destroy(arrow.gameObject);
|
|
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
int magicalDmg = 0;
|
|
|
|
public void MagicalAttack(Vector3 direction, float magicalProjectileSpawnOffset, int dmg)
|
|
{
|
|
if (isServer)
|
|
{
|
|
magicalAttack(direction, magicalProjectileSpawnOffset, dmg);
|
|
}
|
|
else
|
|
{
|
|
CmdMagicalAttack(direction, magicalProjectileSpawnOffset, dmg);
|
|
}
|
|
}
|
|
|
|
[Command]
|
|
void CmdMagicalAttack(Vector3 direction, float magicalProjectileSpawnOffset, int dmg)
|
|
{
|
|
magicalAttack(direction, magicalProjectileSpawnOffset, dmg);
|
|
}
|
|
|
|
void magicalAttack(Vector3 direction, float magicalProjectileSpawnOffset, int dmg)
|
|
{
|
|
magicalDmg = dmg;
|
|
GameObject projectileSpawned = Instantiate(projectile, transform.position + (direction * magicalProjectileSpawnOffset), Quaternion.identity);
|
|
RangeProjectile _projectile = projectileSpawned.GetComponent<RangeProjectile>();
|
|
_projectile.direction = direction;
|
|
_projectile.OnHit.AddListener(OnMagicalHit);
|
|
_projectile.shooterId = netId;
|
|
|
|
NetworkServer.Spawn(projectileSpawned);
|
|
}
|
|
|
|
void OnMagicalHit(enemyScript victim)
|
|
{
|
|
//magical damage with intelligance stat ?
|
|
//int damageamount = magicalDmg + (lvl * 5);
|
|
int damageamount = magicalDmg + (statManager.GetEffectiveValue("intelligence") * 2);
|
|
Debug.Log("magic damage amount " + damageamount);
|
|
victim.TakeMagicalDamage(damageamount, netId);
|
|
}
|
|
|
|
|
|
|
|
public void GoBackMenu()
|
|
{
|
|
startClient.instance.networkManager.StopClient();
|
|
SceneManager.LoadScene("GameLogin");
|
|
|
|
#if UNITY_EDITOR || UNITY_SERVER || UNITY_STANDALONE_WIN
|
|
#else
|
|
PlayGamesPlatform.Instance.SignOut();
|
|
Firebase.Auth.FirebaseAuth.DefaultInstance.SignOut();
|
|
#endif
|
|
|
|
}
|
|
}
|