/// <summary> /// Gets a new location within the crab's move radius. /// </summary> /// <returns>The location</returns> Vector2Int GetNewLocationInMoveRadius() { int moveRadius = TraitsUtil.GetMoveRadius(crab); HashSet <Vector2Int> cellsInsideRadius = GridUtil.GetCellsInsideRadius(crab.Map.Size, crab.Location, moveRadius, true); cellsInsideRadius.Remove(crab.Location); List <Vector2Int> locations = new List <Vector2Int>(cellsInsideRadius); Vector2Int location = Vector2Int.zero; bool isLocationFound = false; int tryCount = 0; int maxTryCount = 100; // Find a random location inside the crab's move radius. while (isLocationFound == false && locations.Count > 0) { if (++tryCount >= maxTryCount) { break; } int locationIndex = Random.Range(0, locations.Count); location = locations[locationIndex]; isLocationFound = GetIsFootprintInBounds(location); // If the selected location isn't valid, then remove it from the collection pool. if (isLocationFound == false) { locations.RemoveAt(locationIndex); continue; } } // If the max number of tries was reached, then stay in the current location. if (tryCount >= maxTryCount) { return(crab.Location); } // If there were no locations left in the pool, then edge case occured and just // set the location to the center of the map since valid locations cant be found // in the current location. if (locations.Count <= 0) { return(Vector2Int.zero); } return(location); }
/// <summary> /// Creates a clone of the agent at a bigger size and destroys the original. /// </summary> void IMoltable.Molt() { ITrait sizeTrait = (Agent as IStatsCollection).GetStat(TraitsUtil.sizeTraitId); int size = sizeTrait != null ? sizeTrait.Quantity : 0; // If the size is less than one, then simply destroy the agent without molting. if (size < 1) { GameObject.Destroy(AgentGameObject); return; } int newSize = (int)(size * moltPercentage); newSize = Mathf.Max(newSize, size + 1); sizeTrait.Quantity = newSize; Vector3 scale = AgentTransform.localScale; scale *= moltPercentage; Vector3 position = Agent.Position; int health = TraitsUtil.GetHealth(Agent) + 1; Agent.RemoveFromMap(); GameObject instance = spawnable.Spawn(position, scale); IAgent instanceAgent = instance.GetComponentInChildren <IAgent>(); if (instanceAgent != null) { instanceAgent.Data = Agent.Data.Copy(); instanceAgent.DisplayName = Agent.DisplayName; instanceAgent.Description = ""; instanceAgent.GroupId = Agent.GroupId; TraitsUtil.SetHealth(instanceAgent, health); } Tweener tweener = instance.GetComponentInChildren <Tweener>(); if (tweener != null) { tweener.TweenOnStart = TweenerMethod.None; } GameObject.Destroy(AgentGameObject); }
/// <summary> /// Removes the target from map and explodes it if it's size is not too small. /// </summary> protected override void OnStart() { int size = TraitsUtil.GetSize(agent); if (size <= 1) { agent.RemoveFromMap(); Complete(); return; } AddEventHandlers(); agent.RemoveFromMap(); explodable.Explode(); }
/// <summary> /// Attack the target attack receiever and then call the relevant transition. /// </summary> void AttackTarget() { if (agent.TargetMapElement == null) { CallTargetKilledTransition(); return; } IAttackReceiver attackReceiver = agent.TargetMapElement as IAttackReceiver; if (attackReceiver == null) { CallTargetKilledTransition(); return; } int targetHealth = TraitsUtil.GetHealth(agent.TargetMapElement); if (targetHealth <= 0) { int targetSize = TraitsUtil.GetSize(agent.TargetMapElement); if (targetSize > 1) { CallTargetKilledTransition(); } else { float hunger = 1.0f; bool isEating = Random.value <= hunger; if (isEating) { agent.Description = "Ate " + agent.TargetMapElement.DisplayName; agent.TargetMapElement.Description = "Eaten by " + agent.DisplayName; CallTargetEatenTransition(); } else { CallTargetKilledTransition(); } } } else { attackReceiver.ReceiveAttack(agent); } }