public override BattleAction Construct(BattleAgent agent, Dictionary <string, object> selections) { Skill skill; if (m_IsID) { object skillObject; selections.TryGetValue(m_Skill, out skillObject); skill = skillObject as Skill; } else { AssetHolder.Skills.TryGetValue(m_Skill, out skill); } BattleManhattanDistanceZone target; if (selections.ContainsKey(m_Target)) { target = selections[m_Target] as BattleManhattanDistanceZone; } else { BattleManhattanDistanceZone range = Skill.GetRange(m_Range, agent); target = Skill.GetTarget(m_Target, agent, range); } return(new BattleSkillAction(agent, skill, target, 0.01f * (m_Power.Equals("") ? agent["Power:" + skill.Element] : agent[m_Power]), m_SPCost, m_HPCost)); }
protected BattleAction MoveWithinRangeOfTarget(Vector2Int target, BattleManhattanDistanceZone range) { BattleManhattanPathZone moveRange = new BattleManhattanPathZone(m_Agent.Coordinates, 1, m_Agent["Move"], m_Agent["Jump"]); List <Vector2Int> options = new List <Vector2Int>(); Vector2Int destination = new Vector2Int(); foreach (Vector2Int point in moveRange) { range.Center = point; if (range[target]) { options.Add(point); } } if (options.Count == 1) { destination = options[0]; } else if (options.Count == 0) { float minDistance = float.PositiveInfinity; foreach (Vector2Int point in moveRange) { float dist = (point - target).magnitude; if (dist < minDistance) { destination = point; minDistance = dist; } } if (float.IsPositiveInfinity(minDistance)) { return(null); } } else { float maxDistance = float.NegativeInfinity; float minWalk = float.PositiveInfinity; foreach (Vector2Int point in options) { float dist = (point - target).magnitude; float walk = (point - m_Agent.Coordinates).magnitude; if (dist >= maxDistance && walk <= minWalk) { destination = point; maxDistance = dist; minWalk = walk; } } } return(new BattleMoveAction(m_Agent, destination)); }
public BattleSkillAction(BattleAgent agent, Skill skill, BattleManhattanDistanceZone target, float power, float spcost, float hpcost) { Agent = agent; Skill = skill; Target = target; Power = power; SPCost = spcost; HPCost = hpcost; }
public override BattleMenu Construct(BattleAgent agent, Dictionary <string, object> selections) { string rangeType, targetType; GetRangeAndTarget(agent, selections, out rangeType, out targetType); BattleManhattanDistanceZone range = Skill.GetRange(rangeType, agent); BattleManhattanDistanceZone target = Skill.GetTarget(targetType, agent, range); return(new BattleTargetSelectMenu(id, range, target)); }
public BattleTargetSelectMenu(string id, BattleManhattanDistanceZone range, BattleManhattanDistanceZone targets) { m_ID = id; m_Range = range; m_Targets = targets; if (m_Range == m_Targets) { m_Targets.Center = m_Range.Center; m_Next = new BattleTargetConfirmMenu(m_ID, m_Targets); } }
public override List <object> Options(BattleAgent agent, Dictionary <string, object> selections) { string rangeType, targetType; GetRangeAndTarget(agent, selections, out rangeType, out targetType); BattleManhattanDistanceZone range = Skill.GetRange(rangeType, agent); BattleManhattanDistanceZone target = Skill.GetTarget(targetType, agent, range); List <object> points = new List <object>(); foreach (Vector2Int point in range) { // check within boundaries points.Add(point); } return(points); }
public override BattleAction Update() { Dictionary <string, object> selections; BattleCommand command = m_Agent.Behaviour.Decide(m_Manager, m_Agent, out selections); if (command != null) { int t = int.MinValue; foreach (BattleCommandSelection selection in command.Selections) { BattleCommandTargetSelection targetSelection = selection as BattleCommandTargetSelection; if (targetSelection != null) { string rangeType, targetType; targetSelection.GetRangeAndTarget(m_Agent, selections, out rangeType, out targetType); BattleManhattanDistanceZone range = Skill.GetRange(rangeType, m_Agent); BattleManhattanDistanceZone target = selections[targetSelection.id] as BattleManhattanDistanceZone; m_Manager.Add(new BattleTargetSelect(new BattleQueueTime(t, ++t), range)); m_Manager.Add(new BattleTargetConfirm(new BattleQueueTime(t, ++t), range, target)); } } // TODO if (command.Expends != BattleCommand.Type.None) { --m_Agent["Turn:" + command.Expends]; } return(command.Construct(m_Agent, selections)); } return(new BattleEndTurnAction(m_Agent)); }
public BattleTargetConfirm(BattleQueueTime time, BattleZone range, BattleManhattanDistanceZone target) : base(time) { m_Range = range; m_Target = target; }
public override BattleAction Update() { m_Manager.grid.Selector.SelectedTile = m_Agent.Coordinates; if (m_Agent["Turn:Action"] <= 0) { return(new BattleEndTurnAction(m_Agent)); } // Find most powerful skill WeaponSkillFilter filter = new WeaponSkillFilter(m_Agent.BaseCharacter); Skill bestSkill = null; float bestPower = float.NegativeInfinity; foreach (Skill skill in filter) { float power = 0f; foreach (SkillEffect effect in skill.Effects) { power += CalculatePower(effect); } if (power > bestPower) { bestSkill = skill; bestPower = power; } } if (bestSkill == null) { return(new BattleEndTurnAction(m_Agent)); } // Select a target BattleManhattanDistanceZone range = Skill.GetRange(bestSkill.Range, m_Agent); List <Vector2Int> options = new List <Vector2Int>(); Vector2Int target; foreach (Vector2Int point in range) { BattleTile tile = m_Manager.grid[point]; if (tile != null && tile.Actor != null) { options.Add(point); } } if (options.Count == 0) { if (m_Agent["Turn:Move"] <= 0) { return(new BattleEndTurnAction(m_Agent)); } // Try to move closer target = TargetNearest(); BattleAction moveAction = MoveWithinRangeOfTarget(target, range); return(moveAction != null ? moveAction : new BattleEndTurnAction(m_Agent)); } else if (options.Count == 1) { target = options[0]; } else { System.Random rand = new System.Random(); target = options[rand.Next() % options.Count]; } BattleManhattanDistanceZone targets = Skill.GetTarget(bestSkill.Target, m_Agent, range); targets.Center = target; return(new BattleSkillAction(m_Agent, bestSkill, targets, 0.01f * m_Agent["Power: " + bestSkill.Element], 1f, 0f)); }
public override BattleAction Construct(BattleAgent agent, Dictionary <string, object> selections) { BattleManhattanDistanceZone destination = selections[m_Target] as BattleManhattanDistanceZone; return(new BattleMoveAction(agent, destination.Center)); }
public static BattleManhattanDistanceZone GetTarget(string target, BattleAgent agent, BattleManhattanDistanceZone range) { if (target.Equals("Single")) { return(new BattleManhattanDistanceZone(new Vector2Int(), 0, 0)); } if (target.StartsWith("All")) { return(new BattleManhattanDistanceZone(range.Center, range.MinRadius, range.MaxRadius + agent["AoE:" + target.Substring(4)])); } return(new BattleManhattanDistanceZone(new Vector2Int(), 0, agent[target])); }
public override BattleCommand Decide(BattleManager manager, BattleAgent agent, out Dictionary <string, object> selections) { if (agent["Turn:Action"] > 0) { // Randomly select an offensive command System.Random rand = new System.Random(); List <Decision> options = new List <Decision>(); foreach (BattleCommand command in agent.BaseCharacter.Commands) { if (command.Enabled(agent)) { Decision decision = new Decision(command); foreach (BattleCommandSelection selection in command.Selections) { List <object> opts = selection.Select(manager, agent, decision.Selections, true); if (opts.Count == 0) { decision = null; break; } else { decision.Selections[selection.id] = opts[rand.Next() % opts.Count]; } } if (decision != null) { options.Add(decision); } } } if (options.Count > 0) { Decision final = options[rand.Next() % options.Count]; selections = final.Selections; return(final.Command); } if (agent["Turn:Move"] > 0) { // Move within range int nearestDist = int.MaxValue; BattleAgent nearest = null; foreach (BattleAgent other in manager.agents) { int dist = PathFinder.ManhattanDistance(agent.Coordinates, other.Coordinates); if (agent.Unit.Opposes(other.Unit) && dist < nearestDist) { nearestDist = dist; nearest = other; } } int optDist; // TODO this section but better if (agent["Attack"] > agent["Magic"]) { optDist = 1; } else { optDist = agent["Range:Magic [Offense]"] + agent["AoE:Magic [Offense]"]; } List <Vector2Int> points = new List <Vector2Int>(); BattleManhattanDistanceZone moveRange = Skill.GetRange("Move", agent); int closestDiff = int.MaxValue; foreach (Vector2Int point in moveRange) { int dist = PathFinder.ManhattanDistance(nearest.Coordinates, point); int diff = dist > optDist ? dist - optDist : optDist - dist; if (diff <= closestDiff) { if (diff < closestDiff) { closestDiff = diff; points = new List <Vector2Int>(); } points.Add(point); } } if (points.Count > 0) { // TODO pick point that closest target is facing furthest away from selections = new Dictionary <string, object>(); selections["destination"] = new BattleManhattanDistanceZone(points[rand.Next() % points.Count], 0, 0); return(AssetHolder.Commands["Move"]); } } } else if (agent["Turn:Move"] > 0) { // Move out of danger } // End turn selections = new Dictionary <string, object>(); return(AssetHolder.Commands["End Turn"]); }
public BattleTargetConfirmMenu(string id, BattleManhattanDistanceZone targets) { m_ID = id; m_Targets = targets; }
public override List <object> Select(BattleManager manager, BattleAgent agent, Dictionary <string, object> selections, bool offense) { string rangeType, targetType; GetRangeAndTarget(agent, selections, out rangeType, out targetType); BattleManhattanDistanceZone range = Skill.GetRange(rangeType, agent); List <object> targets = new List <object>(); if (targetType.StartsWith("All")) { BattleManhattanDistanceZone target = Skill.GetTarget(targetType, agent, range); foreach (Vector2Int point in target) { // count if enemy or ally in space BattleTile tile = manager.grid[point]; if (tile != null && tile.Actor != null) { BattleUnit other = tile.Actor.Agent.Unit; if ((offense && agent.Unit.Opposes(other)) || (!offense && !agent.Unit.Opposes(other))) { targets.Add(target); break; } } } } else { int badMin = int.MaxValue; int goodMax = 0; int bestHealth = offense ? int.MaxValue : 0; foreach (Vector2Int center in range) { BattleManhattanDistanceZone target = Skill.GetTarget(targetType, agent, range); target.Center = center; int badCount = 0; int goodCount = 0; int health = 0; foreach (Vector2Int point in target) { // count if enemy or ally in space BattleTile tile = manager.grid[point]; if (tile != null && tile.Actor != null) { BattleAgent other = tile.Actor.Agent; if (offense) { if (agent.Unit.Opposes(other.Unit)) // is an enemy (good target) { ++goodCount; health += agent.HP; } else // is an ally or neutral (bad target) { ++badCount; } } else { if (agent.Unit.Opposes(other.Unit)) // is an enemy (bad target) { ++badCount; } else // is an ally or neutral (good target) { ++goodCount; health += agent.HP; } } } } if (badCount < badMin || (badCount == badMin && goodCount >= goodMax)) { if (badCount < badMin || goodCount > goodMax) { targets = new List <object>(); badMin = badCount; goodMax = goodCount; bestHealth = health; } else if (health < bestHealth) { targets = new List <object>(); bestHealth = health; } targets.Add(target); } } if (goodMax == 0) { return(new List <object>()); } } return(targets); }