private void UpgradeBot(GatherBot bot) { //bot.Upgrade(); resourceCount -= botUpgradeCost; toBeSpent -= botUpgradeCost; inventory.RemoveItem(Item.Type.PureCorvorite, botUpgradeCost); }
protected virtual void Signalling() { signalTimer -= Time.deltaTime; if (signalTimer <= 0f) { for (int i = 0; i < hive.childBots.Count; i++) { GatherBot sibling = hive.childBots[i]; sibling.enemies = enemies; if (IsInCombat) { sibling.SetState(AIState.Escaping); } else { sibling.SetState(AIState.Attacking); } for (int j = 0; j < enemies.Count; j++) { ICombat enemy = enemies[j]; enemy.EngageInCombat(sibling); } } } }
private void SpendResources(GatherBot b = null) { int usable = resourceCount - minLeftoverResources - toBeSpent; int creationCount = usable / botCreationCost; int tooMuch = Math.Max(0, creationCount + childBots.Count - maxBotCount); creationCount -= tooMuch; usable -= creationCount * botCreationCost; int upgradeCount = childBots.Count + creationCount < maxBotCount ? 0 : usable / botUpgradeCost; tooMuch = Math.Max(0, upgradeCount - (creationCount * maxInitialUpgrades + (b == null ? 0 : 1))); upgradeCount -= tooMuch; usable -= upgradeCount * botUpgradeCost; bool startCreationProcess = needToCreate == 0; //update vars Debug.Log(string.Format("Current resource count: {0}", resourceCount)); Debug.Log(string.Format("Creating {0} bots at {1} each: (-{2})", creationCount, botCreationCost, creationCount * botCreationCost)); needToCreate += creationCount; Debug.Log(string.Format("Upgrading {0} bots at {1} each: (-{2})", upgradeCount, botUpgradeCost, upgradeCount * botUpgradeCost)); needToUpgrade += upgradeCount; toBeSpent += needToCreate * botCreationCost + needToUpgrade * botUpgradeCost; Debug.Log(string.Format("New resource count: {0}", resourceCount - toBeSpent)); if (startCreationProcess) { CreationProcess(b); } }
private GatherBot CreateBot(int dockID, bool ignoreCost = false) { if (!ignoreCost) { if (resourceCount < botCreationCost + minLeftoverResources) { return(null); } resourceCount -= botCreationCost; toBeSpent -= botCreationCost; inventory.RemoveItem(Item.Type.PureCorvorite, botCreationCost); } GatherBot bot = Instantiate(botPrefab); bot.Create(this, botBaseHP, dockID); bot.Activate(false); occupiedDocks[dockID] = true; bot.transform.position = docks[dockID].position; bot.transform.rotation = docks[dockID].rotation; bot.transform.parent = transform.parent; childBots.Add(bot); AssignUnoccupiedCoords(bot); BuildBot(dockID); return(bot); }
public void Store(List <ItemStack> items, GatherBot b) { b.Activate(false); dockAnims[b.dockID].SetTrigger("Dismantle1"); inventory.Store(items); resourceCount = inventory.Count(Item.Type.PureCorvorite); SpendResources(b); }
protected virtual void AlertAll(ICombat threat) { for (int i = 0; i < hive?.childBots.Count; i++) { GatherBot sibling = hive.childBots[i]; sibling.AddThreat(threat); sibling.SetState(AIState.Attacking); } }
public void AssignUnoccupiedCoords(GatherBot b) { if (b == null) { return; } CheckEmptyMarkedCoords(); botOccupiedCoords.Clear(); botOccupiedCoords.AddRange(emptyCoords); for (int i = 0; i < childBots.Count; i++) { EntityNetwork.IterateCoordsInRange( childBots[i].GetIntendedCoords(), 1, cc => { botOccupiedCoords.Add(cc); return(false); }, false); } //find a random nearby coordinate that is not already occupied int searchRange = 1; ChunkCoords location = ChunkCoords.Invalid; while (location == ChunkCoords.Invalid) { EntityNetwork.IterateCoordsOnRangeBorder( coords, searchRange, cc => { if (botOccupiedCoords.Contains(cc)) { return(false); } if (Random.value < 0.1f) { location = cc; return(true); } return(false); }, false); searchRange++; } Vector2 pos = ChunkCoords.GetCenterCell(location, EntityNetwork.CHUNK_SIZE); b.HiveOrders(pos); }
private bool SiblingsInRangeOfTarget(Vector2 enemyPos) { for (int i = 0; i < hive?.childBots.Count; i++) { GatherBot bot = hive.childBots[i]; float dist = Vector2.Distance(bot.transform.position, enemyPos); if (dist < chaseRange) { return(true); } } return(Vector2.Distance(transform.position, enemyPos) < chaseRange); }
public void ActivateBot(int ID, Vector2 position) { for (int i = 0; i < childBots.Count; i++) { GatherBot bot = childBots[i]; if (bot.dockID == ID) { bot.transform.position = position; bot.Activate(true); return; } } }
public bool SplitUpGatheringUnits(GatherBot b) { for (int i = 0; i < childBots.Count; i++) { GatherBot bot = childBots[i]; //don't check self if (b == bot) { continue; } //two bots should gather in different locations to avoid overcrowding if (b.GetIntendedCoords() == bot.GetIntendedCoords()) { return(true); } } return(false); }
public bool VerifyGatheringTarget(GatherBot b, Entity e = null) { e = e == null ? b.targetEntity : e; for (int i = 0; i < childBots.Count; i++) { GatherBot bot = childBots[i]; //don't check self if (b == bot) { continue; } //two bots shouldn't gather from the same target if (e == bot.targetEntity) { return(false); } } return(true); }
public override void DestroyedAnEntity(Entity target) { for (int i = 0; i < enemies.Count; i++) { if ((Entity)enemies[i] == target) { enemies[i].DisengageInCombat(this); enemies.RemoveAt(i); if (enemies.Count == 0) { for (int j = 0; j < hive?.childBots.Count; j++) { GatherBot bot = hive.childBots[j]; bot?.SetState(AIState.Collecting); } } return; } } }
private void CreationProcess(GatherBot b = null) { if (b != null && needToUpgrade > 0) { UpgradeBot(b); needToUpgrade--; } while (needToCreate > 0) { int dockID = GetAvailableDockID(); GatherBot newBot = CreateBot(dockID); needToCreate--; for (int i = 0; i < maxInitialUpgrades && needToUpgrade > 0; i++) { UpgradeBot(newBot); needToUpgrade--; } } }
public Transform GetDock(GatherBot bot) => docks[bot.dockID];
protected virtual void Attacking() { if (enemies.Count == 0) { SetState(AIState.Collecting); } Vector2 currentPos = transform.position; //if sibling bots are nearby, get them to join the fight for (int i = 0; i < hive?.childBots.Count; i++) { GatherBot sibling = hive.childBots[i]; if (sibling.state == AIState.Attacking || sibling.state == AIState.Dying) { continue; } if (Vector2.Distance(currentPos, sibling.transform.position) < Constants.CHUNK_SIZE) { float scanAngle = -Vector2.SignedAngle(Vector2.up, (Vector2)sibling.transform.position - currentPos); StartCoroutine(ScanRings(scanAngle, 30f, false, 0.3f)); sibling.enemies = enemies; sibling.SetState(AIState.Attacking); } } //check if the target is too far away from this bot and its siblings targetEntity = (Entity)enemies[0]; Vector2 enemyPos = targetEntity.transform.position; bool found = SiblingsInRangeOfTarget(enemyPos); //if the target is out of range for too long then disengage from combat if (IncrementOutOfRangeCounter(found)) { return; } //bots attack by circling its target and firing float orbitAngle = Mathf.PI * 2f / (hive?.childBots.Count ?? 1) * dockID + Pause.timeSinceOpen * orbitSpeed; Vector2 orbitPos = new Vector2(Mathf.Sin(orbitAngle), Mathf.Cos(orbitAngle)) * orbitRange; float distanceFromTarget = Vector2.Distance(currentPos, enemyPos); Vector2 direction = enemyPos - currentPos; int count = Physics2D.RaycastNonAlloc(currentPos, direction, lineOfSight, distanceFromTarget); GoToLocation(enemyPos + orbitPos, count > 1, 0.2f, true, distanceFromTarget > firingRange ? null : (Vector2?)targetEntity.transform.position - transform.right); //fire will in range readyToFire = distanceFromTarget <= firingRange; if (readyToFire) { straightWeapon.aim = targetEntity.transform.position; } //run away if hp drops below 50% while also having lower health than the target if (!IsSwarmInCombat) { float hpRatio = healthComponent.CurrentRatio; if (hpRatio < 0.5f && hpRatio < targetEntity.HealthRatio) { scaryEntities.Add(targetEntity); SetState(AIState.Signalling); } } }
protected virtual void SetState(AIState newState) { if (state == AIState.Dying || state == newState) { return; } bool wasIdle = isIdle; isIdle = true; bool couldDrill = canDrill; canDrill = false; switch (newState) { case AIState.Suspicious: suspicionMeter = suspicionMeter ?? Instantiate(radialMeterPrefab); suspicionMeter.transform.parent = ParticleGenerator.holder; suspicionMeter.material.SetFloat("_ArcAngle", 0); break; case AIState.Gathering: canDrill = true; isIdle = false; break; case AIState.Spawning: transform.position = hive.GetDock(this).position; hive.Store(DefaultInventory.ItemStacks, this); itemsCollected = 0; disassembling = false; unsuspiciousEntities.Clear(); break; case AIState.Signalling: for (int i = 0; i < hive.childBots.Count; i++) { GatherBot sibling = hive.childBots[i]; if (sibling == null) { hive.childBots.Remove(sibling); } if (sibling == this) { continue; } float scanAngle = -Vector2.SignedAngle(Vector2.up, sibling.transform.position - transform.position); StartCoroutine(ScanRings(scanAngle, 30f, false, 0.3f)); } signalTimer = scanDuration; break; case AIState.Attacking: anim.SetTrigger("GunOut"); isIdle = false; break; case AIState.Exploring: hive.AssignUnoccupiedCoords(this); break; case AIState.Escaping: outOfRangeTimer = 0f; break; case AIState.Dying: dyingTimer = 0f; anim.enabled = false; sprRend.sprite = dyingSprite; burningEffectsObj?.SetActive(true); ActivateAllColliders(false); EjectFromAllDrillers(true); break; } if (isIdle && isIdle != wasIdle) { anim.SetTrigger("Idle"); } if (canDrill && canDrill != couldDrill) { anim.SetTrigger("DrillOut"); } if (newState != AIState.Gathering) { drill.StopDrilling(false); anim.SetBool("Drilling", false); } if (newState != AIState.Suspicious) { nearbySuspects.Clear(); intenseScanner.Stop(); suspicionMeter?.gameObject.SetActive(false); suspicionMeter?.material.SetFloat("_ArcAngle", 0); } state = newState; }
public void BotDestroyed(GatherBot bot) { occupiedDocks[bot.dockID] = false; childBots.Remove(bot); }