Advertisement
Guest User

Untitled

a guest
Sep 2nd, 2020
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 18.86 KB | None | 0 0
  1. this.ai_defend <- this.inherit("scripts/ai/tactical/behavior", {
  2.     m = {
  3.         TargetTile = null,
  4.         TargetInfo = null,
  5.         IsHoldingPosition = false,
  6.         IsWaitingBeforeMove = false,
  7.         IsWaitingAfterMove = false,
  8.         IsDoneThisTurn = false
  9.     },
  10.     function create(){
  11.         this.m.ID = this.Const.AI.Behavior.ID.Defend;
  12.         this.m.Order = this.Const.AI.Behavior.Order.Defend;
  13.         this.m.IsThreaded = true;
  14.         this.behavior.create();
  15.     }
  16.  
  17.     function onEvaluate( _entity ){
  18.         // Function is a generator.
  19.         this.m.TargetTile = null;
  20.         this.m.TargetInfo = null;
  21.         this.m.IsHoldingPosition = false;
  22.         this.m.IsWaitingAfterMove = false;
  23.         this.m.IsWaitingBeforeMove = false;
  24.         local score = this.getProperties().BehaviorMult[this.m.ID];
  25.  
  26.         if (_entity.getActionPoints() < this.Const.Movement.AutoEndTurnBelowAP){
  27.             return this.Const.AI.Behavior.Score.Zero;
  28.         }
  29.  
  30.         if (this.m.IsDoneThisTurn && _entity.getActionPoints() < _entity.getActionPointsMax()){
  31.             return this.Const.AI.Behavior.Score.Zero;
  32.         }
  33.  
  34.         if (_entity.getCurrentProperties().IsRooted){
  35.             return this.Const.AI.Behavior.Score.Zero;
  36.         }
  37.  
  38.         if (_entity.getMoraleState() == this.Const.MoraleState.Fleeing){
  39.             return this.Const.AI.Behavior.Score.Zero;
  40.         }
  41.  
  42.         if (_entity.getFaction() == this.Const.Faction.Player || _entity.getFaction() == this.Const.Faction.PlayerAnimals){
  43.             return this.Const.AI.Behavior.Score.Zero;
  44.         }
  45.  
  46.         if (!this.getStrategy().isDefending()){
  47.             return this.Const.AI.Behavior.Score.Zero;
  48.         }
  49.  
  50.         if (this.getAgent().getBehavior(this.Const.AI.Behavior.ID.EngageRanged) != null && this.getAgent().getBehavior(this.Const.AI.Behavior.ID.EngageRanged).getScore() > 0 || this.getAgent().getBehavior(this.Const.AI.Behavior.ID.EngageRanged) != null && this.getAgent().getBehavior(this.Const.AI.Behavior.ID.EngageRanged).isUsedThisTurn() || this.getAgent().getBehavior(this.Const.AI.Behavior.ID.EngageMelee) != null && this.getAgent().getBehavior(this.Const.AI.Behavior.ID.EngageMelee).getScore() > 0 || this.getAgent().getBehavior(this.Const.AI.Behavior.ID.AttackBow) != null && this.getAgent().getBehavior(this.Const.AI.Behavior.ID.AttackBow).getScore() > 0 || this.getAgent().getBehavior(this.Const.AI.Behavior.ID.AttackHandgonne) != null && this.getAgent().getBehavior(this.Const.AI.Behavior.ID.AttackHandgonne).getScore() > 0 || this.getAgent().getBehavior(this.Const.AI.Behavior.ID.AttackDefault) != null && this.getAgent().getBehavior(this.Const.AI.Behavior.ID.AttackDefault).getScore() > 0 || this.getAgent().getBehavior(this.Const.AI.Behavior.ID.Reload) != null && this.getAgent().getBehavior(this.Const.AI.Behavior.ID.Reload).getScore() > 0 || this.getAgent().getBehavior(this.Const.AI.Behavior.ID.Protect) != null && (this.getAgent().getBehavior(this.Const.AI.Behavior.ID.Protect).getScore() > 0 || this.getAgent().getBehavior(this.Const.AI.Behavior.ID.Protect).isDoneThisTurn())){
  51.             return this.Const.AI.Behavior.Score.Zero;
  52.         }
  53.  
  54.         if (!this.getAgent().hasKnownOpponent()){
  55.             return this.Const.AI.Behavior.Score.Zero;
  56.         }
  57.  
  58.         if (this.queryTargetsInMeleeRange(this.getProperties().EngageRangeMin, this.getProperties().EngageRangeMax).len() != 0){
  59.             return this.Const.AI.Behavior.Score.Zero;
  60.         }
  61.  
  62.         if (!this.getStrategy().getStats().IsEngaged && _entity.getIdealRange() == 2 && !this.getProperties().IgnoreTargetValueOnEngage && _entity.isAbleToWait() && this.Tactical.TurnSequenceBar.isAllyStillToAct(_entity) && !this.isKindOf(_entity.get(), "lindwurm")){
  63.             local allies = this.getAgent().getKnownAllies();
  64.             local someoneStillToMove = false;
  65.  
  66.             foreach( ally in allies ){
  67.                 if (!ally.isTurnDone() && ally.isArmedWithMeleeWeapon() && ally.getIdealRange() == 1 && ally.getActionPoints() >= 4){
  68.                     someoneStillToMove = true;
  69.                     break;
  70.                 }
  71.             }
  72.  
  73.             if (someoneStillToMove){
  74.                 this.m.IsWaitingBeforeMove = true;
  75.                 return this.Const.AI.Behavior.Score.Defend * score;
  76.             }
  77.         }
  78.  
  79.         if (this.getAgent().getIntentions().IsDefendingPosition){
  80.             score = score * this.Const.AI.Behavior.DefendAlreadyDoneMult;
  81.         }
  82.  
  83.         local targetTile = this.getAgent().getIntentions().IntermediateTargetTile;
  84.  
  85.         if (targetTile == null){
  86.             targetTile = this.getAgent().getIntentions().TargetTile;
  87.         }
  88.  
  89.         if (targetTile != null && targetTile.IsBadTerrain){
  90.             score = score * this.Const.AI.Behavior.DefendAvoidBadTerrainMult;
  91.         }
  92.  
  93.         if (targetTile != null && targetTile.Properties.Effect != null && !targetTile.Properties.Effect.IsPositive && targetTile.Properties.Effect.Applicable(_entity)){
  94.             score = score * this.Const.AI.Behavior.DefendAvoidBadTerrainMult;
  95.         }
  96.  
  97.         local potentialDanger = this.getPotentialDanger(false);
  98.         local func = this.selectBestTargetTile(_entity, targetTile, this.Const.AI.Behavior.DefendMaxSearchRange, potentialDanger);
  99.  
  100.         while (resume func == null){
  101.             yield null;
  102.         }
  103.  
  104.         if (this.m.TargetTile == null){
  105.             return this.Const.AI.Behavior.Score.Zero;
  106.         }
  107.  
  108.         this.m.IsHoldingPosition = _entity.getTile().isSameTileAs(this.m.TargetTile);
  109.  
  110.         if (this.m.IsHoldingPosition && this.getAgent().getIntentions().IsRecuperating){
  111.             return this.Const.AI.Behavior.Score.Zero;
  112.         }
  113.         else if (this.m.IsHoldingPosition && _entity.isArmedWithRangedWeapon()){
  114.             local item = _entity.getItems().getItemAtSlot(this.Const.ItemSlot.Mainhand);
  115.  
  116.             if (item.getAmmoMax() == 0 || item.getAmmo() > 0){
  117.                 local targets = this.queryTargetsInMeleeRange(2, this.Math.min(item.getRangeMax(), _entity.getCurrentProperties().Vision));
  118.                 score = score * this.Math.pow(this.Const.AI.Behavior.DefendUseRangedWeaponMult, targets.len());
  119.             }
  120.         }
  121.  
  122.         return this.Const.AI.Behavior.Score.Defend * score;
  123.     }
  124.  
  125.     function onTurnStarted(){
  126.         this.m.IsDoneThisTurn = false;
  127.     }
  128.  
  129.     function onBeforeExecute( _entity ){
  130.         this.getAgent().getOrders().IsEngaging = false;
  131.         this.getAgent().getOrders().IsDefending = true;
  132.         this.getAgent().getIntentions().IsDefendingPosition = true;
  133.         this.getAgent().getIntentions().IsEngaging = false;
  134.  
  135.         if (this.m.IsWaitingAfterMove){
  136.             this.m.IsDoneThisTurn = true;
  137.         }
  138.     }
  139.  
  140.     function onExecute( _entity ){
  141.         if (this.m.IsWaitingBeforeMove && this.Tactical.TurnSequenceBar.entityWaitTurn(_entity)){
  142.             if (this.Const.AI.VerboseMode){
  143.                 this.logInfo("* " + _entity.getName() + ": Waiting until others have moved!");
  144.             }
  145.  
  146.             return true;
  147.         }
  148.  
  149.         if (!this.m.IsHoldingPosition){
  150.             local navigator = this.Tactical.getNavigator();
  151.  
  152.             if (this.m.IsFirstExecuted){
  153.                 local settings = navigator.createSettings();
  154.                 settings.ActionPointCosts = _entity.getActionPointCosts();
  155.                 settings.FatigueCosts = _entity.getFatigueCosts();
  156.                 settings.FatigueCostFactor = 0.0;
  157.                 settings.ActionPointCostPerLevel = _entity.getLevelActionPointCost();
  158.                 settings.FatigueCostPerLevel = _entity.getLevelFatigueCost();
  159.                 settings.AllowZoneOfControlPassing = false;
  160.                 settings.ZoneOfControlCost = this.Const.AI.Behavior.ZoneOfControlAPPenalty;
  161.                 settings.AlliedFactions = _entity.getAlliedFactions();
  162.                 settings.Faction = _entity.getFaction();
  163.                 navigator.findPath(_entity.getTile(), this.m.TargetTile, settings, 0);
  164.  
  165.                 if (this.Const.AI.PathfindingDebugMode){
  166.                     navigator.buildVisualisation(_entity, settings, _entity.getActionPoints(), _entity.getFatigueMax() - _entity.getFatigue());
  167.                 }
  168.  
  169.                 local movement = navigator.getCostForPath(_entity, settings, _entity.getActionPoints(), _entity.getFatigueMax() - _entity.getFatigue());
  170.                 this.m.Agent.adjustCameraToDestination(movement.End);
  171.  
  172.                 if (this.Const.AI.VerboseMode){
  173.                     this.logInfo("* " + _entity.getName() + ": Going for defensive position.");
  174.                 }
  175.  
  176.                 this.m.IsFirstExecuted = false;
  177.                 return;
  178.             }
  179.  
  180.             if (!navigator.travel(_entity, _entity.getActionPoints(), _entity.getFatigueMax() - _entity.getFatigue())){
  181.                 this.m.TargetTile = null;
  182.                 this.m.TargetInfo = null;
  183.                 return true;
  184.             }
  185.         }
  186.         else{
  187.             if (this.Tactical.TurnSequenceBar.hasEnemiesLeftToAct(_entity.getFaction()) && this.Tactical.TurnSequenceBar.entityWaitTurn(_entity)){
  188.                 if (this.Const.AI.VerboseMode){
  189.                     this.logInfo("* " + _entity.getName() + ": Waiting until others have moved!");
  190.                 }
  191.             }
  192.             else{
  193.                 if (this.Const.AI.VerboseMode){
  194.                     this.logInfo("* " + _entity.getName() + ": Holding defensive position.");
  195.                 }
  196.  
  197.                 this.getAgent().getIntentions().IsRecuperating = true;
  198.             }
  199.  
  200.             this.m.TargetTile = null;
  201.             this.m.TargetInfo = null;
  202.             return true;
  203.         }
  204.  
  205.         return false;
  206.     }
  207.  
  208.     function selectBestTargetTile( _entity, _targetTile, _maxRange, _potentialDanger ){
  209.         // Function is a generator.
  210.         local navigator = this.Tactical.getNavigator();
  211.         local settings = navigator.createSettings();
  212.         local myTile = _entity.getTile();
  213.         local myFaction = _entity.getFaction();
  214.         yield null;
  215.         local tiles = {
  216.             Behavior = this,
  217.             Actor = _entity,
  218.             Origin = myTile,
  219.             TargetTile = _targetTile,
  220.             Range = _maxRange,
  221.             Tiles = []
  222.         };
  223.         this.onQueryTargetTile(myTile, tiles);
  224.         this.Tactical.queryTilesInRange(_entity.getTile(), 1, _maxRange, true, this.Const.AI.Behavior.DefendTerrainMinTV, _entity.getAlliedFactions(), this.onQueryTargetTile, tiles);
  225.         yield null;
  226.         local entityIsRangedUnit = this.isRangedUnit(_entity);
  227.         tiles.Tiles.sort(this.onSortByScore);
  228.         local attempts = 0;
  229.         local time = this.Time.getExactTime();
  230.         local bestDestination;
  231.         local bestDestinationInfo;
  232.         local bestScore = 9000;
  233.         local bestIsForNextTurn = false;
  234.         local bestWaitAfterMove = false;
  235.         local myTile = _entity.getTile();
  236.         local targets = [];
  237.         local actors = this.m.Agent.getKnownOpponents();
  238.  
  239.         foreach( a in actors ){
  240.             if (a.Actor.isNull()){
  241.                 continue;
  242.             }
  243.  
  244.             if (this.isRangedUnit(a.Actor) || myTile.getDistanceTo(a.Actor.getTile()) <= 8){
  245.                 targets.push(a.Actor);
  246.             }
  247.         }
  248.  
  249.         if (targets.len() == 0){
  250.             foreach( a in actors ){
  251.                 if (a.Actor.isNull()){
  252.                     continue;
  253.                 }
  254.  
  255.                 targets.push(a.Actor);
  256.             }
  257.         }
  258.  
  259.         local size = this.Tactical.getMapSize();
  260.         local centerTile;
  261.  
  262.         if (this.Tactical.State.getStrategicProperties() != null && this.Tactical.State.getStrategicProperties().LocationTemplate != null){
  263.             centerTile = this.Tactical.getTileSquare(size.X / 2 + this.Tactical.State.getStrategicProperties().LocationTemplate.ShiftX, size.Y / 2 + this.Tactical.State.getStrategicProperties().LocationTemplate.ShiftY);
  264.         }
  265.         else{
  266.             centerTile = this.Tactical.getTileSquare(size.X / 2, size.Y / 2);
  267.         }
  268.  
  269.         foreach( t in tiles.Tiles ){
  270.             if (this.isAllottedTimeReached(time)){
  271.                 yield null;
  272.                 time = this.Time.getExactTime();
  273.             }
  274.  
  275.             local isForNextTurn = false;
  276.             local apCost = 0;
  277.             local finalTile = t.Tile;
  278.             local waitAfterMove = false;
  279.             attempts = ++attempts;
  280.  
  281.             if (attempts > this.Const.AI.Behavior.DefendMaxAttempts){
  282.                 break;
  283.             }
  284.  
  285.             if (this.getStrategy().isDefendingCamp()){
  286.                 local d = t.Tile.getDistanceTo(centerTile);
  287.  
  288.                 for( ; d > this.Const.Tactical.Settings.CampRadius + this.Tactical.State.getStrategicProperties().LocationTemplate.AdditionalRadius + 1;  ){
  289.                 }
  290.             }
  291.  
  292.             local movementCosts;
  293.  
  294.             if (!t.Tile.isSameTileAs(myTile)){
  295.                 settings.ActionPointCosts = _entity.getActionPointCosts();
  296.                 settings.FatigueCosts = _entity.getFatigueCosts();
  297.                 settings.FatigueCostFactor = 0.0;
  298.                 settings.ActionPointCostPerLevel = _entity.getLevelActionPointCost();
  299.                 settings.FatigueCostPerLevel = _entity.getLevelFatigueCost();
  300.                 settings.AllowZoneOfControlPassing = false;
  301.                 settings.ZoneOfControlCost = this.Const.AI.Behavior.ZoneOfControlAPPenalty;
  302.                 settings.AlliedFactions = _entity.getAlliedFactions();
  303.                 settings.Faction = _entity.getFaction();
  304.  
  305.                 if (navigator.findPath(myTile, t.Tile, settings, 0)){
  306.                     movementCosts = navigator.getCostForPath(_entity, settings, _entity.getActionPoints(), _entity.getFatigueMax() - _entity.getFatigue());
  307.                     apCost = apCost + movementCosts.ActionPointsRequired;
  308.                     finalTile = movementCosts.End;
  309.                     isForNextTurn = false;
  310.                     waitAfterMove = false;
  311.  
  312.                     if (!movementCosts.IsComplete){
  313.                         if (movementCosts.Tiles == 0){
  314.                             isForNextTurn = true;
  315.                         }
  316.                         else{
  317.                             waitAfterMove = true;
  318.                         }
  319.                     }
  320.  
  321.                     if (!movementCosts.IsComplete){
  322.                         local inDanger = false;
  323.  
  324.                         foreach( d in _potentialDanger ){
  325.                             if (this.isAllottedTimeReached(time)){
  326.                                 yield null;
  327.                                 time = this.Time.getExactTime();
  328.                             }
  329.  
  330.                             if (this.queryActorTurnsNearTarget(d, finalTile, _entity).Turns <= 1.0){
  331.                                 inDanger = true;
  332.                                 break;
  333.                             }
  334.                         }
  335.  
  336.                         if (inDanger){
  337.                             local dist = finalTile.getDistanceTo(myTile);
  338.                             local scoreBonus = finalTile.TVTotal * this.Const.AI.Behavior.DefendTerrainValueMult;
  339.                             t.ScoreBonus = scoreBonus;
  340.                         }
  341.                     }
  342.                 }
  343.                 else{
  344.                     continue;
  345.                 }
  346.             }
  347.  
  348.             if (entityIsRangedUnit){
  349.                 foreach( d in _potentialDanger ){
  350.                     if (this.queryActorTurnsNearTarget(d, finalTile, _entity).Turns <= 1.0){
  351.                         t.ScoreBonus -= this.Const.AI.Behavior.DefendRangedWeaponDanger;
  352.                         break;
  353.                     }
  354.                 }
  355.             }
  356.  
  357.             local dirs = [
  358.                 0,
  359.                 0,
  360.                 0,
  361.                 0,
  362.                 0,
  363.                 0
  364.             ];
  365.  
  366.             foreach( opponent in targets ){
  367.                 local dir = t.Tile.getDirection8To(opponent.getTile());
  368.                 local mult = this.isRangedUnit(opponent) ? 2 : 1;
  369.                 mult = mult * (7.0 / t.Tile.getDistanceTo(opponent.getTile()));
  370.  
  371.                 switch(dir){
  372.                 case this.Const.Direction8.W:
  373.                     dirs[this.Const.Direction.NW] += 4 * mult;
  374.                     dirs[this.Const.Direction.SW] += 4 * mult;
  375.                     break;
  376.  
  377.                 case this.Const.Direction8.E:
  378.                     dirs[this.Const.Direction.NE] += 4 * mult;
  379.                     dirs[this.Const.Direction.SE] += 4 * mult;
  380.                     break;
  381.  
  382.                 default:
  383.                     local dir = t.Tile.getDirectionTo(opponent.getTile());
  384.                     local dir_left = dir - 1 >= 0 ? dir - 1 : 6 - 1;
  385.                     local dir_right = dir + 1 < 6 ? dir + 1 : 0;
  386.                     dirs[dir] += 4 * mult;
  387.                     dirs[dir_left] += 3 * mult;
  388.                     dirs[dir_right] += 3 * mult;
  389.                     break;
  390.                 }
  391.             }
  392.  
  393.             local coverBonus = 0.0;
  394.  
  395.             if (entityIsRangedUnit || _entity.isArmedWithMeleeWeapon() && !_entity.isArmedWithShield()){
  396.                 for( local i = 0; i < 6; i = ++i ){
  397.                     if (!t.Tile.hasNextTile(i)){
  398.                     }
  399.                     else{
  400.                         local adjacentTile = t.Tile.getNextTile(i);
  401.  
  402.                         if (dirs[i] >= 8 && !adjacentTile.IsEmpty && adjacentTile.getEntity().getID() != _entity.getID() && (!adjacentTile.IsOccupiedByActor || !this.isRangedUnit(adjacentTile.getEntity()))){
  403.                             coverBonus = coverBonus + dirs[i] / targets.len() * this.Const.AI.Behavior.DefendSeekCoverMult;
  404.                         }
  405.                     }
  406.                 }
  407.             }
  408.  
  409.             local allyDefendBonus = 0.0;
  410.  
  411.             if (!entityIsRangedUnit && _entity.getCurrentProperties().TargetAttractionMult <= 1.0){
  412.                 local importantAllies = [];
  413.                 local secondaryAllies = [];
  414.  
  415.                 for( local i = 0; i < 6; i = ++i ){
  416.                     if (!t.Tile.hasNextTile(i)){
  417.                     }
  418.                     else{
  419.                         local adjacentTile = t.Tile.getNextTile(i);
  420.  
  421.                         if (!adjacentTile.IsOccupiedByActor){
  422.                         }
  423.                         else{
  424.                             local entity = adjacentTile.getEntity();
  425.  
  426.                             if (entity.getFaction() == _entity.getFaction()){
  427.                                 if (entity.getCurrentProperties().TargetAttractionMult > 1.0 || this.isRangedUnit(entity)){
  428.                                     importantAllies.push(entity);
  429.                                 }
  430.                                 else if (_entity.isArmedWithShield() && !entity.isArmedWithShield()){
  431.                                     secondaryAllies.push(entity);
  432.                                 }
  433.                             }
  434.                         }
  435.                     }
  436.                 }
  437.  
  438.                 if (importantAllies.len() == 0){
  439.                     importantAllies = secondaryAllies;
  440.                 }
  441.  
  442.                 foreach( a in importantAllies ){
  443.                     local tile = a.getTile();
  444.                     local checkDirs = [];
  445.                     checkDirs.push(tile.getDirectionTo(t.Tile));
  446.                     checkDirs.push(checkDirs[0] - 1 >= 0 ? checkDirs[0] - 1 : this.Const.Direction.COUNT - 1);
  447.                     checkDirs.push(checkDirs[0] + 1 < this.Const.Direction.COUNT ? checkDirs[0] + 1 : 0);
  448.                     local hasCover = false;
  449.  
  450.                     foreach( d in checkDirs ){
  451.                         if (!tile.hasNextTile(d)){
  452.                             continue;
  453.                         }
  454.  
  455.                         local next = tile.getNextTile(d);
  456.  
  457.                         if (next.IsEmpty || myTile.isSameTileAs(next)){
  458.                             continue;
  459.                         }
  460.  
  461.                         if (next.IsOccupiedByActor){
  462.                             local occupant = next.getEntity();
  463.  
  464.                             if (occupant.isAlliedWith(_entity) && (occupant.getCurrentProperties().TargetAttractionMult > 1.0 || this.isRangedUnit(occupant))){
  465.                                 continue;
  466.                             }
  467.                         }
  468.  
  469.                         hasCover = true;
  470.                         break;
  471.                     }
  472.  
  473.                     allyDefendBonus = allyDefendBonus + dirs[checkDirs[0]] / targets.len() * this.Const.AI.Behavior.DefendImportantAllyPosMult * (!hasCover ? this.Const.AI.Behavior.DefendImportantAllyPosMult : 1.0) * a.getCurrentProperties().TargetAttractionMult;
  474.                 }
  475.             }
  476.  
  477.             if (this.getStrategy().isDefendingCamp()){
  478.                 if (movementCosts != null && !movementCosts.IsComplete){
  479.                     local d = movementCosts.End.getDistanceTo(centerTile);
  480.  
  481.                     if (d > this.Const.Tactical.Settings.CampRadius + this.Tactical.State.getStrategicProperties().LocationTemplate.AdditionalRadius + 1){
  482.                         t.ScoreBonus -= this.Const.AI.Behavior.DefendAtPalisadeBonus;
  483.                     }
  484.                 }
  485.  
  486.                 local d = t.Tile.getDistanceTo(centerTile);
  487.  
  488.                 if (d == this.Const.Tactical.Settings.CampRadius + this.Tactical.State.getStrategicProperties().LocationTemplate.AdditionalRadius || d == this.Const.Tactical.Settings.CampRadius + this.Tactical.State.getStrategicProperties().LocationTemplate.AdditionalRadius - 1){
  489.                     t.ScoreBonus += this.Const.AI.Behavior.DefendAtPalisadeBonus;
  490.                 }
  491.             }
  492.  
  493.             local score = apCost - t.ScoreBonus - allyDefendBonus - coverBonus;
  494.  
  495.             if (score < bestScore){
  496.                 bestDestination = t.Tile;
  497.                 bestDestinationInfo = t;
  498.                 bestIsForNextTurn = isForNextTurn;
  499.                 bestWaitAfterMove = waitAfterMove;
  500.                 bestScore = score;
  501.             }
  502.         }
  503.  
  504.         if (bestDestination != null && bestIsForNextTurn == false){
  505.             this.m.TargetInfo = bestDestinationInfo;
  506.             this.m.TargetTile = bestDestination;
  507.             this.m.IsWaitingAfterMove = bestWaitAfterMove;
  508.             return true;
  509.         }
  510.  
  511.         return false;
  512.     }
  513.  
  514.     function onQueryTargetTile( _tile, _tag ){
  515.         local dist = _tile.getDistanceTo(_tag.Origin);
  516.         local score = _tile.Level * 2.0 + _tile.TVTotal - dist * 2.0;
  517.         local scoreBonus = _tile.Level + _tile.TVTotal * this.Const.AI.Behavior.DefendTerrainValueMult;
  518.  
  519.         if (_tile.Properties.Effect != null && !_tile.Properties.Effect.IsPositive && _tile.Properties.Effect.Applicable(_tag.Actor)){
  520.             score = score - this.Const.AI.Behavior.DefendAvoidTileEffectPenalty;
  521.             scoreBonus = scoreBonus - this.Const.AI.Behavior.DefendAvoidTileEffectPenalty;
  522.         }
  523.  
  524.         for( local i = 0; i < 6; i = ++i ){
  525.             if (!_tile.hasNextTile(i)){
  526.             }
  527.             else if (!_tile.getNextTile(i).IsEmpty){
  528.                 score = score + 1;
  529.             }
  530.         }
  531.  
  532.         _tag.Tiles.push({
  533.             Tile = _tile,
  534.             Score = score,
  535.             ScoreBonus = scoreBonus,
  536.             Allies = 0.0,
  537.             Opponents = 0.0
  538.         });
  539.     }
  540.  
  541.     function onSortByScore( _a, _b ){
  542.         if (_a.Score > _b.Score){
  543.             return -1;
  544.         }
  545.         else if (_a.Score < _b.Score){
  546.             return 1;
  547.         }
  548.  
  549.         return 0;
  550.     }
  551.  
  552.     function onSortByLowestScore( _d1, _d2 ){
  553.         if (_d1.Score > _d2.Score){
  554.             return 1;
  555.         }
  556.         else if (_d1.Score < _d2.Score){
  557.             return -1;
  558.         }
  559.  
  560.         return 0;
  561.     }
  562.  
  563. });
  564.  
  565.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement