using System; using System.Collections; using System.Collections.Generic; using Mirror; using UnityEngine; using UnityEngine.UI; using Random = UnityEngine.Random; public class SpaceshipNetworkBot : NetworkBehaviour { public string[] Names; [SyncVar (hook = nameof(OnPnameChanged))] public string pname; public Text nameTxt; public float movingSpeed; public float minSpeed; public float maxSpeed; public Transform curTarget; public TrailMgrBot trailMgr; public GameObject DeathEffect; public LayerMask pickupsLayer; [SyncVar] public int Scores = 0; [SyncVar(hook = nameof(OnSetupIndexChanged))] public int SelectedSetupIndex; void OnSetupIndexChanged(int old, int value){ GetComponent().sprite = botSetups[value].skins[SelectedSkinIndex]; } [SyncVar(hook = nameof(OnSkinIndexChanged))] public int SelectedSkinIndex; void OnSkinIndexChanged(int old, int value){ GetComponent().sprite = botSetups[SelectedSetupIndex].skins[value]; } public float up; public BotSetup[] botSetups; void OnPnameChanged(string oldName, string newName){ nameTxt.text = newName; } public void InitRandomBot(){ pname = BotsHiveMind.LeaseName(pname.Length > 0 ? pname : null); nameTxt.text = pname; int luck = Random.Range(0,100); BotSetup selectedSetup = botSetups[0]; for(int i=0; i < botSetups.Length; i++){ BotSetup setup = botSetups[i]; if(setup.rarity < luck && setup.rarity > selectedSetup.rarity){ selectedSetup = setup; SelectedSetupIndex = i; } } SelectedSkinIndex = Random.Range(0, selectedSetup.skins.Length); GetComponent().sprite = selectedSetup.skins[SelectedSkinIndex]; movingSpeed = Random.Range(selectedSetup.minSpeed, selectedSetup.maxSpeed); // movingSpeed = Random.Range(minSpeed, maxSpeed); } // Update is called once per frame void FixedUpdate() { if(!isServer){return;} HandleMovement(); CheckForPickups(); // ChangeName(); } void CheckForPickups(){ Collider2D[] hits = Physics2D.OverlapCircleAll(transform.position, 3, pickupsLayer); foreach(Collider2D hit in hits){ if(hit!=null ){ // Debug.Log(hit.name); PickupItem pickupItem = hit.GetComponent(); if(pickupItem !=null && pickupItem.active){ pickupItem.active=false; pickupItem.Deactivate(transform); CollectPickup(pickupItem.type); } } } } void Update(){ nameTxt.rectTransform.rotation = Quaternion.Euler(Vector3.zero); } float swayTimer = 0; void HandleMovement(){ CheckAndUpdateTarget(); Vector3 targ = curTarget.position; if(isHunting){ targ+=(curTarget.up * 8); if(swayTimer < 10){ targ+=(curTarget.right * 8); }else{ targ-=(curTarget.right * 8); } swayTimer += Time.deltaTime; if(swayTimer > 20){ swayTimer=0; } } targ.z = 0f; Vector3 objectPos = transform.position; targ.x = targ.x - objectPos.x; targ.y = targ.y - objectPos.y; float angle = Mathf.Atan2(targ.y, targ.x) * Mathf.Rad2Deg + up; transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.Euler(new Vector3(0, 0, angle)), 0.05f); transform.position += transform.up * movingSpeed; } float t2 =0; bool isHunting=false; void CheckAndUpdateTarget(){ bool skip = false; if(curTarget != null){ if(curTarget.gameObject.activeSelf){ if(t2 < 5){ t2+=Time.deltaTime; }else{ if(Vector3.Distance(transform.position, curTarget.position) < 7){ skip = true; } t2=0; } if(!skip){return;} } } SpaceshipController[] players = FindObjectsOfType(); foreach(SpaceshipController player in players){ if(BotsHiveMind.LeasePlayer(player, this)){ curTarget = player.transform; isHunting=true; return; break; } } bool foundItem = false; while(!foundItem){ List randomSet= MinigameManager.instance.pickupItems[Random.Range(1,MinigameManager.instance.pickupItems.Length)].Active; PickupItem randomPickup = randomSet[Random.Range(0,randomSet.Count)]; if(Vector3.Distance(Vector3.zero, randomPickup.transform.position) < MinigameManager.instance.mapRadius){ curTarget = randomPickup.transform; foundItem=true; isHunting=false; } } } public void TrailCollided(Collider2D hit){ if(!isServer){return;} SpaceshipController deadPlayer = hit.GetComponent(); // Debug.Log("got hit by player? : " + (deadPlayer != null)); if (deadPlayer != null && !deadPlayer.dead && (NetworkTime.time - deadPlayer.startedTime) > 5) { // <-- okay we killed someone | KILLCODE // deadPlayer.RpcShowDeathEffect(deadPlayer.transform.position); deadPlayer.Die(pname); if(BotsHiveMind.Leased.ContainsKey(deadPlayer)){ if(BotsHiveMind.Leased[deadPlayer] == this){ curTarget=null; isHunting=false; } } Debug.Log($"{pname} killed {deadPlayer.pname}"); return; } SpaceshipNetworkBot deadBot = hit.GetComponent(); // Debug.Log("got hit by bot? : " + (deadPlayer != deadBot)); if(deadBot != null){ deadBot.Die(); return; } } [SyncVar (hook = nameof(OnTrailTimeChanged))] private float m_trailTime; public float maxTrailTime; public float minTrailTime; public float trailIncrementRate = 0.1f; public float trailTime{get{return m_trailTime;} set{ m_trailTime = Mathf.Clamp(value, minTrailTime,maxTrailTime); trailMgr.trail.time = m_trailTime; }} void OnTrailTimeChanged(float oldTime, float newTime){ trailMgr.trail.time = newTime; } public void CollectPickup(PickupItem.PickupType type){ trailTime += trailIncrementRate; if(type.ToString().ToLower().Contains("moon")){ Scores+=2; }else{ Scores++; } } public void Die(){ int leftoverAmount = (int)((float)Scores/4f); Debug.Log("Bot " + pname + " Left " + leftoverAmount + " Stars"); MinigameManager.instance.SpawnLeftoverPickups(transform.position, leftoverAmount); MinigameManager.instance.DestroyBot(this); return; RpcDie(transform.position); Scores = 0; trailTime = 0; trailMgr.trail.time=0; transform.position = MinigameManager.getRandomPointInCirlce(Vector3.zero, 150); StartCoroutine(die()); } [ClientRpc] void RpcDie(Vector3 position){ EffectPool.Spawn(DeathEffect, position); trailMgr.trail.time=0; trailMgr.trail.enabled=false; StartCoroutine(die()); } IEnumerator die(){ yield return new WaitForSeconds(0.5f); trailTime = 0; trailMgr.trail.enabled =true; } } public static class BotsHiveMind{ private static string[] Names= {"Andrew Joe", "Dragon Fire", "Doom Killer", "Ice Killer", "Drake Ronin", "Turbo Skull", "Decay", "Fester Flack", "El Diablo", "Rubble r", "Hank 95", "Zer0", "War-lord", "Wraith", "Knuckles U", "iKill U", "iSteal", "Bull3t", "Tito 97", "Jurgen", "Tobias 37", "Mia M", "Luca 43", "Aditya 101", "Abu B", "Ahmad Cipta", "Harta Ismaya", "Yuda_333"}; private static List ActiveNames; private static List PooledNames; public static string LeaseName(string borrowedName = null){ if(ActiveNames == null) { ActiveNames = new List();} if(PooledNames == null){ PooledNames = new List(Names);} //Return borrowed name to the list if(borrowedName!=null){ ActiveNames.Remove(borrowedName); PooledNames.Add(borrowedName); } //Borrow a new name string chosenName = PooledNames[Random.Range(0,PooledNames.Count)]; PooledNames.Remove(chosenName); ActiveNames.Add(chosenName); return chosenName; } public static void ReturnName(string name){ PooledNames.Add(name); ActiveNames.Remove(name); } private static Dictionary leased = new Dictionary(); public static Dictionary Leased { get{ if(leased == null){ leased = new Dictionary();} return leased; } } public static bool LeasePlayer(SpaceshipController player, SpaceshipNetworkBot bot){ if(leased.ContainsKey(player)){//Player's already leased if(leased[player].curTarget == player.transform){ return false; }else{ leased.Remove(player); } } leased.Add(player,bot); return true; } public static void RetrunPlayer(SpaceshipController player){ if(leased.ContainsKey(player)){ leased.Remove(player); } Debug.Log("Trying to return a player to hive mind pool. But no one was borrowing them"); } } [Serializable] public class BotSetup{ public float minSpeed; public float maxSpeed; public Sprite[] skins; [Range(0,100)] public int rarity; }