mmorpg2d/Assets/Script/playerNetwork.cs
2025-06-23 17:06:59 +05:30

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
}
}