protected internal override Steering getSteering(PersonajeBase personaje) { _finishedLinear = _finishedAngular = false; Vector3 newOffset = SimulationManager.DirectionToVector(_target.orientacion + SimulationManager.VectorToDirection(offsetPosition)) * offsetPosition.magnitude; Vector2 destino = SimManagerFinal.positionToGrid(_target.posicion + newOffset); if (destino != lastDestiny) { Vector2 origen = SimManagerFinal.positionToGrid(personaje.posicion); List <Vector3> recorrido = SimManagerFinal.aStarPathV3(origen, destino, personaje.tipo, personaje is PersonajePlayer); lastDestiny = destino; followPath = new PathFollowEndSD(recorrido); } if (followPath.finishedLinear) { personaje.fakeAlign.orientacion = _target.orientacion + offsetOrientation; if (personaje.fakeAlign.orientacion < -System.Math.PI) { personaje.fakeAlign.orientacion += 2 * (float)System.Math.PI; } else if (personaje.fakeAlign.orientacion > System.Math.PI) { personaje.fakeAlign.orientacion -= 2 * (float)System.Math.PI; } personaje.fakeAlign.transform.eulerAngles = new Vector3(0, (_target.orientacion + offsetOrientation) * Bodi.RadianesAGrados, 0); faceSD.target = personaje.fakeAlign; parada.getSteering(personaje); return(faceSD.getSteering(personaje)); } else { return(followPath.getSteering(personaje)); } }
public PathFollowingNOPathOffsetGridSD(List <Vector3> path, StatsInfo.TIPO_TERRENO[][] terrenos) { foreach (Vector3 pos in path) { this.path.Add(SimManagerFinal.positionToGrid(pos)); } }
protected internal void ActualizeBasesHealth() { foreach (PersonajeBase unit in personajesPlayer) { if (unit.isAlive()) { if (TacticalModule.isInBaseRange(unit, SimManagerFinal.positionToGrid(enemyBase.position))) { redBase -= StatsInfo.damagePerClass[(int)unit.tipo] * Time.fixedDeltaTime; } } } foreach (PersonajeBase unit in personajesNPC) { if (unit.isAlive()) { if (TacticalModule.isInBaseRange(unit, SimManagerFinal.positionToGrid(allyBase.position))) { blueBase -= StatsInfo.damagePerClass[(int)unit.tipo] * Time.fixedDeltaTime; } } } baseHPBars.actualizeHP(1, redBase / StatsInfo.MAX_BASE_HEALTH); baseHPBars.actualizeHP(0, blueBase / StatsInfo.MAX_BASE_HEALTH); }
private List <Accion> attackEnemiesClose() { List <Accion> attackActions = new List <Accion>(); List <PersonajeBase> unidadKataka = new List <PersonajeBase>(); foreach (PersonajeBase unit in unitsNotAsigned) { if (!defensiveGroup.Contains(unit)) //si no es alguien que deba defender { foreach (PersonajeBase enemy in enemies) { Vector2 mipos = SimManagerFinal.positionToGrid(unit.posicion); Vector2 supos = SimManagerFinal.positionToGrid(enemy.posicion); if (enemy.isAlive() && (mipos - supos).magnitude <= StatsInfo.detectionRangePerClass[(int)unit.tipo]) //distancia de deteccion { //lo quitamos de grupo de ataque si estaba attackActions.Add(createAttackingAction(unit, enemy)); //añadimos accion de atacar unidadKataka.Add(unit); break; } } } } if (unidadKataka.Count > 0) { foreach (PersonajeBase person in unidadKataka) { unitsNotAsigned.Remove(person); //eliminamos de las unidades a mandar ofensiveGroup.Remove(person); } } return(attackActions); }
protected internal override Steering getSteering(PersonajeBase personaje) { if (currentPoint >= path.Count) { _finishedAngular = _finishedLinear = true; Vector3 cuadrao = SimManagerFinal.gridToPosition(SimManagerFinal.positionToGrid(personaje.posicion)); personaje.fakeAvoid.posicion = cuadrao; personaje.fakeAvoid.moveTo(cuadrao); personaje.fakeMovement.posicion = cuadrao; personaje.fakeMovement.moveTo(cuadrao); return(new Steering()); } personaje.fakeAvoid.posicion = pathEnd; personaje.fakeAvoid.moveTo(pathEnd); personaje.fakeMovement.posicion = path[currentPoint]; personaje.fakeMovement.moveTo(path[currentPoint]); pursueSD.target = personaje.fakeMovement; Steering movActual = pursueSD.getSteering(personaje); if (pursueSD.finishedLinear) { currentPoint++; } return(movActual); }
protected internal Vector2 getUnitPointOnBase(PersonajeBase person, Vector2 basePos) { int index = 0; foreach (PersonajeBase ppl in allies) { if (person == ppl) { break; } index++; } int angle = index * 360 / allies.Count; Vector3 radio = new Vector3((float)System.Math.Cos(angle), 0, (float)System.Math.Sin(angle)) * StatsInfo.baseDistaciaCuracion * 0.75f; Vector3 destino = SimManagerFinal.gridToPosition(basePos) + radio; return(SimManagerFinal.positionToGrid(destino)); /*Vector3 distance = SimManagerFinal.gridToPosition(basePos) - person.posicion; * if (distance.magnitude < StatsInfo.baseDistaciaCuracion) * { * return SimManagerFinal.positionToGrid(person.posicion); * } * else * { * distance = distance.normalized* (distance.magnitude - StatsInfo.baseDistaciaCuracion + 5); * return SimManagerFinal.positionToGrid(person.posicion + distance); * }*/ }
protected internal override bool isInRange() //Comprobacion de rango de ataque { Vector2 mipos = SimManagerFinal.positionToGrid(sujeto.posicion); Vector2 supos = SimManagerFinal.positionToGrid(receptor.posicion); return(((mipos - supos).magnitude <= StatsInfo.attackRangePerClass[(int)sujeto.tipo])); }
protected internal bool alreadyComingToBase(PersonajeBase unit) { Vector3 destino = Vector3.zero; if (unit.currentAction != null && unit.currentAction is ActionGo) { destino = SimManagerFinal.gridToPosition(((ActionGo)unit.currentAction).getDestiny()); } return((destino - SimManagerFinal.gridToPosition(baseCoords)).magnitude <= StatsInfo.baseDistaciaCuracion); }
protected internal bool ourBaseIsUnderAttack() { foreach (PersonajeBase pp in enemies) { if (pp.isAlive() && ((pp.posicion - SimManagerFinal.gridToPosition(baseCoords)).magnitude <= StatsInfo.baseDistaciaCuracion)) { return(true); } } return(false); }
protected internal override void doit() { if (receptor) { destiny = SimManagerFinal.positionToGrid(receptor.posicion); } List <Vector3> camino = SimManagerFinal.aStarPathV3(SimManagerFinal.positionToGrid(sujeto.posicion), destiny, sujeto.tipo, sujeto is PersonajePlayer); recorrer = new PathFollowEndSD(camino); sujeto.newTaskGrid(recorrer); }
protected static internal AccionCompuesta createAttackingAction(PersonajeBase sujeto, PersonajeBase receptor) { ActionGo goToEnemy = new ActionGo(sujeto, SimManagerFinal.positionToGrid(receptor.posicion), receptor); AccionAttack attackEnemy = new AccionAttack(sujeto, receptor); List <Accion> orders = new List <Accion> { goToEnemy, attackEnemy }; AccionCompuesta ac = new AccionCompuesta(sujeto, orders, true); return(ac); }
private List <Accion> sendAlliesToDefend(int defenders, List <PersonajeBase> attackers) //manda los defensores necesarios { //comprobar si hay suficientes unidades que no esten peleando para mandarlas //sino mandar las que esten mas cerca hasta cumplir los requirimientos //o quedarnos sin unidades //añadimos a los elegidos al grupo de defensores List <Accion> defendActions = new List <Accion>(); List <float> priorities = new List <float>(); float distancePriority = 7; float velocityPriotiry = 5; float dmgPriority = 5; for (int i = 0; i < unitsNotAsigned.Count; i++) { float prioridad = 0; prioridad -= (SimManagerFinal.positionToGrid(unitsNotAsigned[i].posicion) - getUnitPointOnBase(unitsNotAsigned[i], baseCoords)).magnitude * distancePriority; //prioridad = -getClosestPointToBase(unitsNotAsigned[i], baseCoords).magnitude * distancePriority; prioridad += unitsNotAsigned[i].maxMovSpeed * velocityPriotiry; float dmgPower = 0; foreach (PersonajeBase person in attackers) { dmgPower += StatsInfo.damageModifiers[(int)unitsNotAsigned[i].tipo][(int)person.tipo]; } prioridad += dmgPower * dmgPriority; priorities.Add(prioridad); } for (int i = 0; i < defenders; i++) { float higherPriority = float.MinValue; int index = 0; for (int j = 0; j < priorities.Count; j++) { if (priorities[j] > higherPriority) { higherPriority = priorities[j]; index = j; } } defendActions.Add(createAttackingAction(unitsNotAsigned[index], getClosestEnemy(unitsNotAsigned[index], attackers))); defensiveGroup.Add(unitsNotAsigned[index]); unitsNotAsigned.Remove(unitsNotAsigned[index]); //si falla algo, mirar aqui priorities.RemoveAt(index); } if (patrullero.isAlive()) { defendActions.Add(createAttackingAction(patrullero, getClosestEnemy(patrullero, attackers))); } return(defendActions); }
protected internal override bool isDone() { bool aRango = false; if (receptor != null) { Vector2 mipos = SimManagerFinal.positionToGrid(sujeto.posicion); Vector2 supos = SimManagerFinal.positionToGrid(receptor.posicion); aRango = (mipos - supos).magnitude <= (StatsInfo.attackRangePerClass[(int)sujeto.tipo]); } return(aRango || (recorrer != null && recorrer.finishedLinear)); }
internal void formacionASusPuestosGrid() { for (int i = 1; i < maximoMiembros; i++) { if (miembros[i] != null) { Vector2 start = SimManagerFinal.positionToGrid(offsetPositions[i - 1]); FormacionGridSD opSD = new FormacionGridSD(offsetPositions[i - 1], offsetRotations[i - 1]); opSD.target = lider; miembros[i].newTask(opSD); } } }
protected internal List <PersonajeBase> enemiesOnBase() //comprobar si hay enemigos en la base atacando { List <PersonajeBase> enemies_attacking = new List <PersonajeBase>(); foreach (PersonajeBase pp in enemies) { if (pp.isAlive() && ((pp.posicion - SimManagerFinal.gridToPosition(baseCoords)).magnitude <= StatsInfo.baseDistaciaCuracion)) { enemies_attacking.Add(pp); } } return(enemies_attacking); }
private bool tooFarAwayFromBase(PersonajeBase unit) { PersonajeBase enemyToAttack = null; if (unit.currentAction != null && (unit.currentAction is AccionCompuesta)) { AccionCompuesta ac = (AccionCompuesta)unit.currentAction; ActionGo ag = (ActionGo)ac.acciones[0]; enemyToAttack = ag.receptor; } if (enemyToAttack != null) { return((enemyToAttack.posicion - SimManagerFinal.gridToPosition(baseCoords)).magnitude > (StatsInfo.baseDistaciaCuracion * 2)); } else { return(false); } }
protected static internal Vector2 getUnitPointOnBaseStatic(PersonajeBase person, Vector2 basePos, List <PersonajeBase> alice) { int index = 0; foreach (PersonajeBase ppl in alice) { if (person == ppl) { break; } index++; } int angle = index * 360 / alice.Count; Vector3 radio = new Vector3((float)System.Math.Cos(angle), 0, (float)System.Math.Sin(angle)) * StatsInfo.baseDistaciaCuracion * 0.75f; Vector3 destino = SimManagerFinal.gridToPosition(basePos) + radio; return(SimManagerFinal.positionToGrid(destino)); }
private bool alreadyInBridge(PersonajeBase npc, int whichBridge) //hay que pasarlo 1 o 2 como valor de entrada { Vector2 pos = SimManagerFinal.positionToGrid(npc.posicion); switch (whichBridge) { case 1: return(pos.x >= StatsInfo.puente_superior[0].x && pos.x <= StatsInfo.puente_superior[2].x && pos.y >= StatsInfo.puente_superior[0].y && pos.y <= StatsInfo.puente_superior[1].y); case 2: return(pos.x >= StatsInfo.puente_inferior[0].x && pos.x <= StatsInfo.puente_inferior[2].x && pos.y >= StatsInfo.puente_inferior[0].y && pos.y <= StatsInfo.puente_inferior[1].y); case 3: return ((pos.x >= StatsInfo.puente_superior[0].x && pos.x <= StatsInfo.puente_superior[2].x && pos.y >= StatsInfo.puente_superior[0].y && pos.y <= StatsInfo.puente_superior[1].y) || (pos.x >= StatsInfo.puente_inferior[0].x && pos.x <= StatsInfo.puente_inferior[2].x && pos.y >= StatsInfo.puente_inferior[0].y && pos.y <= StatsInfo.puente_inferior[1].y)); } return(false); }
private List <Accion> attackEnemiesClose() { List <Accion> attackActions = new List <Accion>(); foreach (PersonajeBase unit in unitsNotAsigned) { foreach (PersonajeBase enemy in enemies) { Vector2 mipos = SimManagerFinal.positionToGrid(unit.posicion); Vector2 supos = SimManagerFinal.positionToGrid(enemy.posicion); if (enemy.isAlive() && (mipos - supos).magnitude <= StatsInfo.detectionRangePerClass[(int)unit.tipo]) { attackActions.Add(createAttackingAction(unit, enemy)); //attackGroup.Remove(unit); break; } } } return(attackActions); }
private List <Accion> setPatrol() { List <Accion> patrolActions = new List <Accion>(); bool notGoingToAttack = true; if (patrullero.isAlive()) { if (!isGoingToAttack(patrullero)) { foreach (PersonajeBase enemy in enemies) { Vector2 mipos = SimManagerFinal.positionToGrid(patrullero.posicion); Vector2 supos = SimManagerFinal.positionToGrid(enemy.posicion); if (enemy.isAlive() && (mipos - supos).magnitude <= StatsInfo.detectionRangePerClass[(int)patrullero.tipo]) { patrolActions.Add(createAttackingAction(patrullero, enemy)); notGoingToAttack = false; break; } } if (notGoingToAttack) { if (!(patrullero.currentAction is AccionPatrullar)) { patrolActions.Add(new AccionPatrullar(patrullero, getPatrolPathing(this.team), SimManagerFinal.terrenos)); } } } else if (tooFarAwayFromBase(patrullero)) { patrolActions.Add(new AccionPatrullar(patrullero, getPatrolPathing(this.team), SimManagerFinal.terrenos)); } } return(patrolActions); }
protected internal override bool hasToRecalculate() { return(receptor && destiny != SimManagerFinal.positionToGrid(receptor.posicion)); }
protected internal void initIAs() { playerIA = new TacticIA(new List <PersonajeBase>(personajesPlayer), new List <PersonajeBase>(personajesNPC), SimManagerFinal.positionToGrid(baseAliada.position), SimManagerFinal.positionToGrid(baseEnemiga.position), true); enemyIA = new TacticIA(new List <PersonajeBase>(personajesNPC), new List <PersonajeBase>(personajesPlayer), SimManagerFinal.positionToGrid(baseEnemiga.position), SimManagerFinal.positionToGrid(baseAliada.position), false); }
protected internal override Steering getSteering(PersonajeBase personaje) { terciaryWhiskersAngle = personaje.outterAngleVision; secondaryWhiskersAngle = personaje.outterAngleVision / 2; //secondaryWhiskersLength = personaje.velocidad.magnitude*1.5f; //primaryWhiskerLenght = personaje.velocidad.magnitude*2.5f; terciaryWhiskersLength = personaje.maxMovSpeed * multiplier * 0.5f; secondaryWhiskersLength = personaje.maxMovSpeed * 0.75f * multiplier; primaryWhiskerLenght = personaje.maxMovSpeed * 1.5f * multiplier; wallOffset = personaje.innerDetector * 1.5f; RaycastHit leftSWHit, leftTWHit, rightSWHit, rightTWHit, midWHit; float leftSecondaryOri = personaje.orientacion - secondaryWhiskersAngle; if (leftSecondaryOri > System.Math.PI) { leftSecondaryOri -= 2 * (float)System.Math.PI; } else if (leftSecondaryOri < -System.Math.PI) { leftSecondaryOri += 2 * (float)System.Math.PI; } float leftTerciaryOri = personaje.orientacion - terciaryWhiskersAngle; if (leftTerciaryOri > System.Math.PI) { leftTerciaryOri -= 2 * (float)System.Math.PI; } else if (leftTerciaryOri < -System.Math.PI) { leftTerciaryOri += 2 * (float)System.Math.PI; } float rightSecondaryOri = personaje.orientacion + secondaryWhiskersAngle; if (rightSecondaryOri > System.Math.PI) { rightSecondaryOri -= 2 * (float)System.Math.PI; } else if (rightSecondaryOri < -System.Math.PI) { rightSecondaryOri += 2 * (float)System.Math.PI; } float rightTerciaryOri = personaje.orientacion + terciaryWhiskersAngle; if (rightTerciaryOri > System.Math.PI) { rightTerciaryOri -= 2 * (float)System.Math.PI; } else if (rightTerciaryOri < -System.Math.PI) { rightTerciaryOri += 2 * (float)System.Math.PI; } bool midWhisker = Physics.Raycast(personaje.posicion, SimulationManager.DirectionToVector(personaje.orientacion), out midWHit, primaryWhiskerLenght, 1 << 9 | 1 << 8 | 1 << 13); bool leftSWhisker = Physics.Raycast(personaje.posicion, SimulationManager.DirectionToVector(leftSecondaryOri), out leftSWHit, secondaryWhiskersLength, 1 << 9 | 1 << 8 | 1 << 13); bool rightSWhisker = Physics.Raycast(personaje.posicion, SimulationManager.DirectionToVector(rightSecondaryOri), out rightSWHit, secondaryWhiskersLength, 1 << 9 | 1 << 8 | 1 << 13); bool leftTWhisker = Physics.Raycast(personaje.posicion, SimulationManager.DirectionToVector(leftTerciaryOri), out leftTWHit, terciaryWhiskersLength, 1 << 9 | 1 << 8 | 1 << 13); bool righTWhisker = Physics.Raycast(personaje.posicion, SimulationManager.DirectionToVector(rightTerciaryOri), out rightTWHit, terciaryWhiskersLength, 1 << 9 | 1 << 8 | 1 << 13); if (midWhisker) { _finishedLinear = _finishedAngular = false; Vector3 newPos = midWHit.point + midWHit.normal.normalized * wallOffset; newPos = new Vector3(newPos.x, 0, newPos.z); Vector2 newPos2d = SimManagerFinal.positionToGrid(newPos); if (SimManagerFinal.terrenos[(int)newPos2d.x][(int)newPos2d.y] == StatsInfo.TIPO_TERRENO.INFRANQUEABLE) { newPos2d = getVecinoFranqueable(newPos2d); } newPos = SimManagerFinal.gridToPosition(newPos2d); personaje.fakeAvoid.posicion = newPos; personaje.fakeAvoid.innerDetector = personaje.innerDetector; personaje.fakeAvoid.moveTo(newPos); pursueSD.target = personaje.fakeAvoid; } else if ((leftSWhisker || leftTWhisker) && !rightSWhisker && !righTWhisker) { _finishedLinear = _finishedAngular = false; float hipotenusa = 0; float transversalDistance = 0; float longitudinalDistance = 0; if (leftSWhisker) { hipotenusa = leftSWHit.distance; transversalDistance = hipotenusa * (float)System.Math.Sin(secondaryWhiskersAngle); longitudinalDistance = hipotenusa * (float)System.Math.Cos(secondaryWhiskersAngle); } else if (leftTWhisker) { hipotenusa = leftTWHit.distance; transversalDistance = hipotenusa * (float)System.Math.Sin(terciaryWhiskersAngle); longitudinalDistance = hipotenusa * (float)System.Math.Cos(terciaryWhiskersAngle); } else { hipotenusa = (leftSWHit.distance + leftTWHit.distance) / 2; transversalDistance = hipotenusa * (float)System.Math.Sin((secondaryWhiskersAngle + terciaryWhiskersAngle) / 2); longitudinalDistance = hipotenusa * (float)System.Math.Cos((secondaryWhiskersAngle + terciaryWhiskersAngle) / 2); } float transversalOri = personaje.orientacion + 90 * Bodi.GradosARadianes; if (transversalOri > (float)System.Math.PI) { transversalOri -= 2 * (float)System.Math.PI; } else if (transversalOri < (float)System.Math.PI) { transversalOri += 2 * (float)System.Math.PI; } //CUSTOM FOR INNER CORNERS Vector3 newPos = personaje.posicion + personaje.velocidad.normalized * longitudinalDistance + SimulationManager.DirectionToVector(transversalOri) * (wallOffset - transversalDistance); newPos = new Vector3(newPos.x, 0, newPos.z); Vector2 newPos2d = SimManagerFinal.positionToGrid(newPos); if (SimManagerFinal.terrenos[(int)newPos2d.x][(int)newPos2d.y] == StatsInfo.TIPO_TERRENO.INFRANQUEABLE) { newPos2d = getVecinoFranqueable(newPos2d); } newPos = SimManagerFinal.gridToPosition(newPos2d); personaje.fakeAvoid.posicion = newPos; personaje.fakeAvoid.innerDetector = personaje.innerDetector; personaje.fakeAvoid.moveTo(newPos); pursueSD.target = personaje.fakeAvoid; } else if ((rightSWhisker || righTWhisker) && !leftSWhisker && !leftTWhisker) { _finishedLinear = _finishedAngular = false; float hipotenusa = 0; float transversalDistance = 0; float longitudinalDistance = 0; if (rightSWhisker) { hipotenusa = leftSWHit.distance; transversalDistance = hipotenusa * (float)System.Math.Sin(secondaryWhiskersAngle); longitudinalDistance = hipotenusa * (float)System.Math.Cos(secondaryWhiskersAngle); } else if (righTWhisker) { hipotenusa = leftTWHit.distance; transversalDistance = hipotenusa * (float)System.Math.Sin(terciaryWhiskersAngle); longitudinalDistance = hipotenusa * (float)System.Math.Cos(terciaryWhiskersAngle); } else { hipotenusa = (leftSWHit.distance + leftTWHit.distance) / 2; transversalDistance = hipotenusa * (float)System.Math.Sin((secondaryWhiskersAngle + terciaryWhiskersAngle) / 2); longitudinalDistance = hipotenusa * (float)System.Math.Cos((secondaryWhiskersAngle + terciaryWhiskersAngle) / 2); } float transversalOri = personaje.orientacion - 90 * Bodi.GradosARadianes; if (transversalOri > (float)System.Math.PI) { transversalOri -= 2 * (float)System.Math.PI; } else if (transversalOri < (float)System.Math.PI) { transversalOri += 2 * (float)System.Math.PI; } //CUSTOM FOR INNER CORNERS Vector3 newPos = personaje.posicion + personaje.velocidad.normalized * longitudinalDistance + SimulationManager.DirectionToVector(transversalOri) * (wallOffset - transversalDistance); newPos = new Vector3(newPos.x, 0, newPos.z); Vector2 newPos2d = SimManagerFinal.positionToGrid(newPos); if (SimManagerFinal.terrenos[(int)newPos2d.x][(int)newPos2d.y] == StatsInfo.TIPO_TERRENO.INFRANQUEABLE) { newPos2d = getVecinoFranqueable(newPos2d); } newPos = SimManagerFinal.gridToPosition(newPos2d); personaje.fakeAvoid.posicion = newPos; personaje.fakeAvoid.innerDetector = personaje.innerDetector; personaje.fakeAvoid.moveTo(newPos); pursueSD.target = personaje.fakeAvoid; } else if (_finishedLinear || (!_finishedLinear && pursueSD.finishedLinear)) { _finishedLinear = _finishedAngular = true; return(new Steering()); } return(pursueSD.getSteering(personaje)); }
protected internal override List <Accion> getStrategyActions() { List <Accion> defensiveActions = new List <Accion>(); foreach (PersonajeBase ally in allies) { if (!ally.isAlive()) { continue; } //1 - COMPROBAR SI HAY UNIDADES QUE NECESITEN CURACION if (!ally.isFullHealth()) { if (!ally.isInCombat()) //Si no esta en combate { if (!isInBaseRange(ally, baseCoords) && !alreadyComingToBase(ally)) { Vector2 closestPoint = getUnitPointOnBase(ally, baseCoords); ActionGo goToBase = new ActionGo(ally, closestPoint, null); defensiveActions.Add(goToBase); } } else { if (ally.betterToRun() && !alreadyComingToBase(ally)) //vida por debajo del 30% { if (!isInBaseRange(ally, baseCoords)) { Vector2 closestPoint = getUnitPointOnBase(ally, baseCoords); ActionGo goToBase = new ActionGo(ally, closestPoint, null); defensiveActions.Add(goToBase); } } } } else { //2 - COMPROBAR SI HAY ENEMIGOS EN EL AREA DE LA BASE INTERRUMPIENDO SPAWN List <PersonajeBase> enemies_attacking = enemiesOnBase(); if (enemies_attacking.Count > 0 && !isGoingToAttack(ally)) { PersonajeBase closestEnemy = getClosestEnemy(ally, enemies_attacking); ActionGo goToEnemy = new ActionGo(ally, SimManagerFinal.positionToGrid(closestEnemy.posicion), closestEnemy); AccionAttack attackEnemy = new AccionAttack(ally, closestEnemy); List <Accion> orders = new List <Accion> { goToEnemy, attackEnemy }; AccionCompuesta defendBase = new AccionCompuesta(ally, orders, true); defensiveActions.Add(defendBase); defended = true; } else { //3 - COMPROBAR UNIDADES FUERA DEL PERIMETRO DE LA BASE if (!isInBaseRange(ally, baseCoords) && !alreadyComingToBase(ally)) { Vector2 closestPoint = getUnitPointOnBase(ally, baseCoords); ActionGo goToBase = new ActionGo(ally, closestPoint, null); defensiveActions.Add(goToBase); } //4 - AGRUPAR UNIDADES DENTRO DEL PERIMETRO DE LA BASE } } } return(defensiveActions); }
protected static internal bool isInBaseRange(PersonajeBase person, Vector2 baseCoord) { return((person.posicion - SimManagerFinal.gridToPosition(baseCoord)).magnitude <= StatsInfo.baseDistaciaCuracion); }
protected internal override Steering getSteering(PersonajeBase personaje) { if (!setup) { Vector3 puntoActual = path[0]; for (int i = 1; i < path.Count; i++) { List <Vector3> recorridoActual = SimManagerFinal.aStarPathV3(puntoActual, path[i], personaje.tipo, personaje is PersonajePlayer); ruta.AddRange(recorridoActual); puntoActual = path[i]; } List <Vector3> recorridoFinal = SimManagerFinal.aStarPathV3(path[path.Count - 1], path[0], personaje.tipo, personaje is PersonajePlayer); ruta.AddRange(recorridoFinal); float minDist = Mathf.Infinity; int nearestPoint = -1; for (int i = 0; i < ruta.Count; i++) { if ((ruta[i] - personaje.posicion).magnitude < minDist) { nearestPoint = i; minDist = (ruta[i] - personaje.posicion).magnitude; } } setup = true; currentStartingPoint = nearestPoint; startingruta = SimManagerFinal.aStarPathV3(SimManagerFinal.positionToGrid(personaje.posicion), SimManagerFinal.positionToGrid(ruta[nearestPoint]), personaje.tipo, personaje is PersonajePlayer); } if (!startingsetup) { if (startingruta.Count > 0) { //preguntar a alex si se acuerda personaje.fakeMovement.innerDetector = personaje.innerDetector; personaje.fakeMovement.posicion = startingruta[currentPoint]; personaje.fakeMovement.moveTo(startingruta[currentPoint]); personaje.fakeAvoid.posicion = startingruta[startingruta.Count - 1]; personaje.fakeAvoid.moveTo(startingruta[startingruta.Count - 1]); if (pursueSD.finishedLinear) { currentPoint = (currentPoint + 1); if (currentPoint >= startingruta.Count) { startingsetup = true; currentPoint = currentStartingPoint; for (int i = currentPoint; i < ruta.Count; i++) { bool found = false; for (int j = 0; j < path.Count; j++) { if (ruta[i] == SimManagerFinal.gridToPosition(path[j])) { personaje.fakeAvoid.posicion = ruta[i]; personaje.fakeAvoid.moveTo(ruta[i]); found = true; break; } } if (found) { break; } } } } } else { startingsetup = true; currentPoint = currentStartingPoint; for (int i = currentPoint; i < ruta.Count; i++) { bool found = false; for (int j = 0; j < path.Count; j++) { if (ruta[i] == SimManagerFinal.gridToPosition(path[j])) { personaje.fakeAvoid.posicion = ruta[i]; personaje.fakeAvoid.moveTo(ruta[i]); found = true; break; } } if (found) { break; } } } } else { if (pursueSD.finishedLinear) { for (int i = 0; i < path.Count; i++) { if (path[i] == SimManagerFinal.positionToGrid(ruta[currentPoint])) { int next = (i + 1) % path.Count; Vector3 nextRoutePoint = SimManagerFinal.gridToPosition(path[next]); personaje.fakeAvoid.posicion = nextRoutePoint; personaje.fakeAvoid.moveTo(nextRoutePoint); } } currentPoint = (currentPoint + 1) % ruta.Count; } personaje.fakeMovement.innerDetector = personaje.innerDetector; personaje.fakeMovement.posicion = ruta[currentPoint]; personaje.fakeMovement.moveTo(ruta[currentPoint]); } pursueSD.target = personaje.fakeMovement; return(pursueSD.getSteering(personaje)); }
protected internal override Steering getSteering(PersonajeBase personaje) { if (!setupAEstrella) { LinkedList <NodoGrafoAStar> closedPositions = new LinkedList <NodoGrafoAStar>(); closedPositions.AddLast(nodoOrigen); LinkedList <NodoGrafoAStar> openPositions = new LinkedList <NodoGrafoAStar>(); NodoGrafoAStar nodoActual = nodoOrigen; while (!setupAEstrella) { LinkedList <NodoGrafoAStar> adyacentes = calcularAdyacentes(nodoActual, personaje.tipo); //LinkedList<NodoGrafoAStar> adyacentesFiltrados foreach (NodoGrafoAStar nodito in adyacentes) { //Observamos lista closed bool estaEnListaClosed = false; foreach (NodoGrafoAStar noditoClosed in closedPositions) { //Si el nodo ya está en la lista closed, no se considera if (noditoClosed.posicionGrid == nodito.posicionGrid) { estaEnListaClosed = true; break; } } if (estaEnListaClosed) { continue; } //Observamos lista open NodoGrafoAStar posibleaASustituir = null; bool estaEnListaOpen = false; foreach (NodoGrafoAStar noditoOpen in openPositions) { if (nodito.posicionGrid == noditoOpen.posicionGrid) { estaEnListaOpen = true; if (noditoOpen.totalCost > nodito.totalCost) { posibleaASustituir = noditoOpen; } break; } } if (posibleaASustituir != null) { openPositions.Remove(posibleaASustituir); openPositions.AddLast(nodito); } else if (!estaEnListaOpen) { openPositions.AddLast(nodito); } } //Calculamos siguiente nodo float minorCost = float.MaxValue; NodoGrafoAStar next = null; foreach (NodoGrafoAStar noditoOpen in openPositions) { if (noditoOpen.totalCost < minorCost) { minorCost = noditoOpen.totalCost; next = noditoOpen; } } nodoActual = next; openPositions.Remove(nodoActual); closedPositions.AddLast(nodoActual); //Comprobacion de parada(llegamos al destina) foreach (NodoGrafoAStar noditoClosed in closedPositions) { if (noditoClosed.posicionGrid == destino) { setupAEstrella = true; } } } //Calculamos el camino a seguir en base a los padres del nodo destino NodoGrafoAStar aux = nodoActual; while (aux.padre != null) { recorrido.AddFirst(aux.posicionGrid); aux = aux.padre; } } if (pursue.finishedLinear || !setupRecorrido) { if (pasoActual >= recorrido.Count - 1) { _finishedLinear = true; _finishedAngular = true; return(new Steering()); } else { pasoActual++; personaje.fakeMovement.posicion = SimManagerFinal.gridToPosition(recorrido.ElementAt(pasoActual)); personaje.fakeMovement.moveTo(SimManagerFinal.gridToPosition(recorrido.ElementAt(pasoActual))); pursue.target = personaje.fakeMovement; setupRecorrido = true; return(pursue.getSteering(personaje)); } } else { return(pursue.getSteering(personaje)); } }