/// <summary> /// Devuelve el nodo más adecuado de la lista de nodos accesibles /// </summary> /// <param name="_selectedNodes">Lista de nodos aceccesibles</param> private GridNode BestNodeSelection(Unit chip) { // mutate return float seed = 0.15f; if (chip.role == StrategicRole.Defense) { seed = 0.3f; } else if (chip.role == StrategicRole.Center) { seed = 0.2f; } else if (chip.role == StrategicRole.Forward) { seed = 0.1f; } if (Random.value < seed) { return(Mutate(chip)); } // comportamientos GridNode best = null; GridNode objective = flagEnemy; List <GridNode> menances = new List <GridNode>(); UpgradeArea nearestBoost = NearestBoostArea(chip); // saca el upgrade area compatible más cercana int len = int.MaxValue; bool priority = false; foreach (GridNode g in _selectedNodes) // buscar elementos con prioridad { if (IsNodeOnArea(g) && g.isOccupied != null) { if (g == flagEnemy) // si es la bandera enemiga { return(g); } else if (g.isOccupied.tag == "Unit") // si es una ficha { Unit anotherUnit = (Unit)g.isOccupied; if (!_team.IsUnitInTeam(anotherUnit)) // si la unidad no es amiga { float power = chip.GetUnitPower(anotherUnit); float powerEnemy = anotherUnit.GetUnitPower(chip); if (power < powerEnemy) // si la enemiga es más fuerte { menances.Add(g); priority = true; } else if (power > powerEnemy) // si la enemiga es más debil { best = g; } } } else if (nearestBoost != null && g == nearestBoost.GetGridNode()) { best = g; } } } if (priority) // se activa el return prioritario cuando hay amenazas { // returnea el nodo accesible más lejano al enemigo y más proximo al objetivo return(path.GetOptimalFurtherNode(_selectedNodes, menances, flagEnemy)); } else if (best != null) { return(best); } else // si no se han encontrado elementos con prioridad { switch (chip.role) // modificar objetivo según rol estratégico { case StrategicRole.Forward: // modo ataque if (nearestBoost != null) { if (path.GetDistance(chip.GetGridNode(), nearestBoost.GetGridNode()) < totalDistance / 6) { objective = nearestBoost.GetGridNode(); } else { objective = flagEnemy; } } else { objective = flagEnemy; } break; case StrategicRole.Defense: // modo defensa if (nearestBoost != null) { if (path.GetDistance(chip.GetGridNode(), nearestBoost.GetGridNode()) < totalDistance / 10) { objective = nearestBoost.GetGridNode(); } else { objective = flagAlly; } } else { objective = flagAlly; } break; default: // modo cobertura if (nearestBoost != null) { if (path.GetDistance(chip.GetGridNode(), nearestBoost.GetGridNode()) < totalDistance / 3) { objective = nearestBoost.GetGridNode(); } else { objective = flagEnemy; } } else { objective = flagEnemy; } break; } foreach (GridNode g in _selectedNodes) // recorrer la lista de nodos accesibles y elegir el camino más corto { if (IsNodeOnArea(g)) // si el nodo es accesible { if (g.isOccupied == null) // si el nodo está vacio { int newLen = path.BestPathLength(g, objective); if (newLen < len) // si el camino actual es mas corto que el mejor registrado { len = newLen; // actualizar camino mas corto encontrado best = g; // actualizar mejor nodo } } } } } return(best); }