Deedlit

one of vector engine ai tasks

Mar 13th, 2017 (edited)
162
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 14.88 KB | None | 0 0
  1. /*
  2.  * This program is free software: you can redistribute it and/or modify it under
  3.  * the terms of the GNU General Public License as published by the Free Software
  4.  * Foundation, either version 3 of the License, or (at your option) any later
  5.  * version.
  6.  *
  7.  * This program is distributed in the hope that it will be useful, but WITHOUT
  8.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  9.  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  10.  * details.
  11.  *
  12.  * You should have received a copy of the GNU General Public License along with
  13.  * this program. If not, see <http://www.gnu.org/licenses/>.
  14.  */
  15. package com.l2jserver.gameserver.ai.ext.tasks;
  16.  
  17. import com.l2jserver.Config;
  18. import com.l2jserver.gameserver.GeoData;
  19. import com.l2jserver.gameserver.ai.ext.AI_TaskQueue;
  20. import com.l2jserver.gameserver.ai.ext.struct.holder.PawnEvaluationHolder;
  21. import com.l2jserver.gameserver.ai.ext.struct.position.BasePositionData;
  22. import com.l2jserver.gameserver.ai.ext.struct.stat_watchers.PawnEvaluationData;
  23. import com.l2jserver.gameserver.ai.ext.struct.task.AITaskSimpleVar;
  24. import com.l2jserver.gameserver.ext.util.ExtUtil;
  25. import com.l2jserver.gameserver.model.actor.L2Character;
  26. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  27. import com.l2jserver.gameserver.util.Point3D;
  28. import com.l2jserver.util.Rnd;
  29.  
  30. import java.util.Collection;
  31.  
  32. /**
  33.  * ==============================================<br>
  34.  * AttackRepositionTask - This tasks is active, when AI is in combat mode. Task probes
  35.  * target surroundings, and repositions character accordingly, to Vector Engine
  36.  * position calculations, taking into consideration other attackers (if exist). This
  37.  * task is also responsible, for remembering valid char->target position vector, when
  38.  * is found. Task additionally scouts possible "move to" positions, if they are
  39.  * better than current. If not, movement is not performed..<br>
  40.  * ==============================================<br>
  41.  * @author Deedlit(deedlit@protonmail.com)
  42.  */
  43. public class AttackRepositionTask extends AbstractAITask
  44. {
  45.     private L2Character _target;
  46.  
  47.     private boolean _forceMove = false;
  48.  
  49.  
  50.     public AttackRepositionTask(L2Character cha, L2Character target)
  51.     {
  52.         super(cha.getTaskQueue(), 0, false, true, 0, cha);
  53.         _target = target;
  54.     }
  55.  
  56.     @Override
  57.     protected void initTaskTypeName()
  58.     {
  59.         _name = "AttackRepositionTask";
  60.     }
  61.  
  62.  
  63.     private BasePositionData _pawnBasePositionData;
  64.  
  65.     public L2Character getTarget()
  66.     {
  67.         L2Character newTarget = getAI().getAttackTarget();
  68.         if (_target != newTarget || _pawnBasePositionData == null)
  69.         {
  70.             _pawnBasePositionData = getActor().getRangesCalc().getPawnRangeInfo(newTarget);
  71.         }
  72.         _target = newTarget;
  73.         return _target;
  74.     }
  75.  
  76.     @Override
  77.     public boolean valid()
  78.     {
  79.         return /*getTarget() != null &&*/ hasAI() && /*getTarget().hasAI() &&*/ getAI().getIntention().isAttackingMode() && !getActor().isDead() && !getActor().isPlayable()
  80.                 && !getActor().getRangesCalc().isLongRangeType();// && getAI().getAttackTarget() == getTarget();
  81.     }
  82.  
  83.     @Override
  84.     public boolean waiting(int taskRunCycle)
  85.     {
  86.         return (getTarget() == null || !hasAI() || !getTarget().hasAI() || getActor().isCastingNow() || (getActor().isAttackingNow() && getActor().hitBroadcasted)
  87.                 || (getActor().getTimeToDestination() > 6000 && getActor().getMyLocation().calculateTimeToMoveTo(getTarget().getMyLocation(), getActor(), getActor().isFloating() || getTarget().isFloating()) > 9000)
  88.         || getTarget().isMoving() || (getAI().isFollowing() && getActor().getRangesCalc().canSee(getTarget())) || getActor().isMovementDisabled()) || !getActor().getRangesCalc().canSee(getTarget());
  89.     }
  90.  
  91.     @Override
  92.     public boolean ready()
  93.     {
  94.         return (getAI().getAtkMovTimestamp() >= 0 && System.currentTimeMillis() - getAI().getAtkMovTimestamp() > 15000 && getTarget().getCombatData().countAttackers() > 5) || shouldReposition()|| (!getActor().getRangesCalc().canSee(getTarget()) && !getActor().isMoving());
  95.     }
  96.  
  97.     private boolean shouldReposition()
  98.     {
  99.         try
  100.         {
  101.             if (_pawnBasePositionData != null)
  102.             {
  103.                 PawnEvaluationData ed = _pawnBasePositionData.getPawnEvaluationData();
  104.  
  105.                 if (ed.isActorAttacking() || !ed.isActorCanMove() || (ed.isPawnFloating() && !ed.isActorCanFloat()) || !ed.isActorCanSeePawn())
  106.                     return false;
  107.  
  108.                 if (ed.isWithinMaxOffsetNoMoveExtent())
  109.                 {
  110.                     // ---
  111.                 }
  112.  
  113.                 // w zasiΔ™gu
  114.                 if (ed.isWithinMaxOffset())
  115.                 {
  116.                     if (ed.isMovingInOppositeDirections())
  117.                     {
  118.                         int whenWeMeet = ed.getActorTimeToMoveToPawn();
  119.                         if (ed.isBothMoving())
  120.                             whenWeMeet = Math.abs(ed.getActorPosition().calculateTimeToMoveTo(ed.getPawnPosition(), getTarget(), ed.isFloatingAny()) - ed.getActorTimeToMoveToPawn())/2;
  121.                     }
  122.                     else if (ed.isMovingInSameDirection())
  123.                     {
  124.  
  125.                     }
  126.                 }
  127.             }
  128.  
  129.             if (getActor().getRangesCalc().isWithinMaxOffset(getTarget()) && !(getTarget().getAI().getAtkMovTimestamp() <= 0
  130.                     || (getTarget().getAI().getAtkMovTimestamp() > 0 && System.currentTimeMillis() - getTarget().getAI().getAtkMovTimestamp() > 500)))
  131.                 return false;
  132.  
  133.             boolean ready = getTarget() != null && hasAI() && getTarget().hasAI() && ((!getActor().getRangesCalc().isWithinMaxOffset(getTarget()) && (getActor().getTimeToDestination() < 1000
  134.                     || getActor().getMyDestinationLocation().calculateDistanceTo(getTarget().getMyLocation(), getActor().isFloating()
  135.                     || getTarget().isFloating()) > getActor().getMyLocation().calculateDistanceTo(getTarget().getMyLocation(), getActor().isFloating() || getTarget().isFloating())
  136.                     || getActor().getRangesCalc().needToCalcNewPositionAroundPawn(getTarget())))
  137.                     || (/*getActor().isMoving() != getTarget().isMoving() ||*/ ((getActor().isMoving() || (getAI().getAtkMovTimestamp() <= 0 || System.currentTimeMillis() - getAI().getAtkMovTimestamp() > 1000)))
  138.                     && (/*!getTarget().isMoving() ||*/ (getTarget().getAI().getAtkMovTimestamp() <= 0 || (System.currentTimeMillis() - getTarget().getAI().getAtkMovTimestamp() > 1000
  139.                     || getTarget().getMyLocation().calculateTimeToMoveTo(getActor().getMyLocation(), getActor(), getActor().isFloating() || getTarget().isFloating()) > 2000)))))
  140.                     && getActor().getRangesCalc().canSee(getTarget());
  141.  
  142.             if (!ready && !getActor().isMoving() && !getTarget().isMoving() && !getActor().getRangesCalc().getPawnRangeInfo(getTarget()).isRegistered())
  143.             {
  144.                 BasePositionData bpd = getActor().getRangesCalc().getPawnRangeInfo(getTarget());
  145.                 if (bpd != null && !bpd.isRegistered())
  146.                     bpd.tryKeepingPositionVector();
  147.             }
  148.             return ready;
  149.         }
  150.         catch (Exception e)
  151.         {
  152.             return false;
  153.         }
  154.     }
  155.  
  156.  
  157.     /**
  158.      * Returning always true, to not forcibly push this task, on the queue top.
  159.      * @return
  160.      */
  161.     @Override
  162.     public boolean run()
  163.     {
  164.         _forceMove = false; // reset if forced exec
  165.  
  166.         final L2Character target = getTarget();
  167.         if (target == null)
  168.             return false;
  169.         final L2Character cha = getActor();
  170.  
  171.         final int collision = (int)cha.getCollisionRadius();
  172.         if (_pawnBasePositionData == null)
  173.             return false;
  174.  
  175.         if (/*!cha.isMoving() && */_pawnBasePositionData.canSee())
  176.         {
  177.             int attackers = target.getAI().getCombatData().countAttackers();
  178.  
  179.             if ((!cha.isMoving() && getAI().getAtkMovTimestamp() > 0 && System.currentTimeMillis() - getAI().getAtkMovTimestamp() > 15000 && attackers > 5
  180.                     && !_pawnBasePositionData.needToCalcNewPositionAroundPawn()) && Rnd.qchance(Math.min(25 + attackers, 45))) /* If not moved for over 25s, try going randomly some. */
  181.             {
  182.                 int x1, y1, z1, x = _pawnBasePositionData.getPawnEvaluationData().getPawnPosition().x, y = _pawnBasePositionData.getPawnEvaluationData().getPawnPosition().y;
  183.                 int drange = /*Rnd.qchance(15) ? 350 : 50*/0;
  184.                 int tries = 3, range = drange + getAI().getRangesCalc().getMaxOffset(target);
  185.                 while (tries > 0)
  186.                 {
  187.                     tries--;
  188.                     x1 = Rnd.qnextInt(range * 2); // x
  189.                     y1 = Rnd.qget(x1, range * 2); // distance
  190.                     y1 = (int) Math.sqrt(y1 * y1 - x1 * x1); // y
  191.                     x1 += x - range;
  192.                     y1 += y - range;
  193.                     z1 = GeoData.getInstance().getSpawnHeight(x1, y1, cha.getZ() - 30, cha.getZ() + 50, null);
  194.  
  195.                     Point3D t = new Point3D(x1, y1, z1);
  196.                     if (t.calculateDistanceTo(cha.getMyLocation(), false) < 32 || GeoData.getInstance().getNSWE(t) != 15 || !GeoData.getInstance().canMoveFromToTarget(cha.getMyLocation(), t))
  197.                         continue;
  198.  
  199.                     if (cha.isAttackingNow() && !cha.isAttackAborted())
  200.                         cha.abortAttack();
  201.                     getAI().moveTo(t);
  202.                     if (cha.isMoving())
  203.                         return true;
  204.                 }
  205.             }
  206.  
  207.             boolean lastResort = false;
  208.             if (!target.isMoving()) /* Main reposition routine, checking nearby area and destination position befor moving. */
  209.             {
  210.                 try
  211.                 {
  212.                     int maxChance = 0; int reposM = 1;
  213.                     boolean targetNear = _pawnBasePositionData.needToCalcNewPositionAroundPawn();
  214.                     boolean playersNear = false;
  215.                     if ((!targetNear || !target.isPlayer()) && !cha.isMoving())
  216.                     {
  217.                         Collection<L2PcInstance> _players = cha.getKnownList().getKnownPlayersInRadius(collision + collision + 10);
  218.                         if (target.isPlayer() && _players.contains(target.getActingPlayer()))
  219.                             _players.remove(target.getActingPlayer());
  220.                         playersNear = !_players.isEmpty();
  221.                     }
  222.                     boolean charsNear = false, chance = false;
  223.                     if ((!targetNear && !playersNear) && !cha.isMoving())
  224.                     {
  225.                         double cmul = cha.getCollisionRadius() / 10.;
  226.                         if (target.getCombatData() != null)
  227.                         {
  228.                             if (attackers < 13 / cmul)
  229.                                 maxChance = 17;
  230.                             else if (attackers < 15 / cmul)
  231.                                 maxChance = 15;
  232.                             else if (attackers < 17 / cmul)
  233.                                 maxChance = 12;
  234.                             else if (attackers < 19 / cmul)
  235.                                 maxChance = 9;
  236.                             else if (attackers < 23 / cmul)
  237.                                 maxChance = 6;
  238.                             else
  239.                                 maxChance = 3;
  240.                         }
  241.                         charsNear = !cha.getKnownList().getKnownCharactersInRadius(collision + collision + 10, false).isEmpty();
  242.                         if (!charsNear)
  243.                         {
  244.                             final int[] _dest = _pawnBasePositionData.calcNewPositionAroundPawn();
  245.                             if (_dest != null && _dest[4] == 1)
  246.                             {
  247.                                 final Point3D d = new Point3D(_dest[0], _dest[1], _dest[2]);
  248.                                 if (!cha.isMoving() && !target.isMoving() && ExtUtil.calculateDistance(d, cha.getMyLocation(), false) <= collision / 4)
  249.                                     _pawnBasePositionData.tryKeepingPositionVector();
  250.                             }
  251.                         }
  252.                         else if (maxChance > 0)
  253.                             chance = Rnd.qchance(maxChance);
  254.                     }
  255.                     if ((charsNear && chance) || targetNear || playersNear)
  256.                     {
  257.                         if (playersNear && System.currentTimeMillis() - getAI().getLastToPawnCoordRecalc() < 2500)
  258.                             playersNear = false;
  259.                         int[] _dest = _pawnBasePositionData.calcNewPositionAroundPawn(playersNear, Config.SL2_MOD_AI_USE_ATK_INDEX_FOR_PAWN_POSITIONING, !cha.isFloating());
  260.                         double _dist = _dest != null ? cha.getMyLocation().calculateDistanceTo(new Point3D(_dest[0], _dest[1], _dest[2]), false) : 0;
  261.                         boolean okToMove = _dist > cha.getCollisionRadius();
  262.                         if (!targetNear && !playersNear && okToMove)
  263.                         {
  264.                             okToMove = cha.getKnownList().getKnownCharactersInRadiusAt(_dest[0], _dest[1], _dest[2], collision + collision + 10, false).isEmpty();
  265.                             if (okToMove)
  266.                                 reposM = 2;
  267.                         }
  268.                         if (!okToMove && (targetNear || playersNear || System.currentTimeMillis() - getAI().getLastToPawnCoordRecalc() > 3000))
  269.                         {
  270.                             _dest = _pawnBasePositionData.calcNewPositionAroundPawn(true, Config.SL2_MOD_AI_USE_ATK_INDEX_FOR_PAWN_POSITIONING, !cha.isFloating());
  271.                             _dist = _dest != null ? cha.getMyLocation().calculateDistanceTo(new Point3D(_dest[0], _dest[1], _dest[2]), false) : 0;
  272.                             okToMove = _dist > cha.getCollisionRadius() && (targetNear || cha.getKnownList().getKnownCharactersInRadiusAt(_dest[0], _dest[1], _dest[2], collision + collision + 10, false).isEmpty());
  273.                             if (okToMove)
  274.                             {
  275.                                 if (!targetNear)
  276.                                     getRangesCalc().keepCurrentPositionVector(target);
  277.                                 reposM = 3;
  278.                             }
  279.                         }
  280.                         if (okToMove)
  281.                         {
  282.                             getAI().moveTo(_dest[0], _dest[1], _dest[2]);
  283.                             if (cha.isMoving())
  284.                             {
  285.                                 getAI().setLastToPawnCoordRecalc(System.currentTimeMillis());
  286.                                 try
  287.                                 {
  288.                                     if (cha.isAIDebug() && Config.AI_log_this(cha, "on_atk_repos"))
  289.                                         cha.debug().debugRegisterActorAI_Warning("thinkAttack: reposition "+reposM);
  290.                                 }
  291.                                 catch (Exception e)
  292.                                 {
  293.                                 }
  294.                                 return true;
  295.                             }
  296.                             lastResort = true;
  297.                         }
  298.                     }
  299.                     else if (!charsNear && !cha.isMoving())
  300.                     {
  301.                         final int[] _dest = _pawnBasePositionData.calcNewPositionAroundPawn();
  302.                         if (_dest != null && _dest[4] == 1)
  303.                         {
  304.                             final Point3D d = new Point3D(_dest[0], _dest[1], _dest[2]);
  305.                             if (!cha.isMoving() && !target.isMoving() && ExtUtil.calculateDistance(d, cha.getMyLocation(), false) <= collision / 4)
  306.                                 _pawnBasePositionData.tryKeepingPositionVector();
  307.                         }
  308.                     }
  309.                 }
  310.                 catch(NullPointerException npe)
  311.                 {
  312.                     // ignore NPE's (can appear, when task is run, after target is decayed).
  313.                 }
  314.             }
  315.  
  316.             /* Last resort movement routine if one above failed or sth */
  317.             if ((lastResort || _pawnBasePositionData.needToCalcNewPositionAroundPawn()) && !cha.isMoving()/*&& (*//*target.isMoving() !=*//* !cha.isMoving())*/)//cha.isInsideRadius(target, getAI().getRangesCalc().isWithinMaxOffset(target), cha.isFloating() || target.isFloating(), false))
  318.             {
  319.                 getAI().moveToPawn(target, getAI().getRangesCalc().getMinOffset(target), true, lastResort);
  320.                 if (cha.isMoving())
  321.                 {
  322.                     getAI().setLastToPawnCoordRecalc(System.currentTimeMillis());
  323.                     return true;
  324.                 }
  325.             }
  326.         }
  327.         return false;
  328.     }
  329.  
  330.     @Override
  331.     public boolean block_think_after_run()
  332.     {
  333.         return false;
  334.     }
  335.  
  336.     @Override
  337.     public int update_weight()
  338.     {
  339.         return -1;
  340.     }
  341.  
  342.     @Override
  343.     public boolean removeable()
  344.     {
  345.         return !valid();
  346.     }
  347.  
  348.     @Override
  349.     public boolean valid_run_delay()
  350.     {
  351.         return !(getActor().isAttackingNow() && !getActor().isAttackAborted()) && (calcTimeSinceTaskLastExec(false) <= 0
  352.                 || calcTimeSinceTaskLastExec(false) > (!getActor().isMoving() || getTarget().isMoving() ? 250 : 350));
  353.     }
  354.  
  355.     @Override
  356.     public int max_task_instances()
  357.     {
  358.         return 1;
  359.     }
  360.  
  361.     @Override
  362.     public void on_variable_listener(AITaskSimpleVar.LISTENER_EVENTS event, AITaskSimpleVar variable)
  363.     {
  364.         if (event == AITaskSimpleVar.LISTENER_EVENTS.VALUE_CHANGE && variable.getVarName().equals("_forceAtkRepos") && variable.getValueBool())
  365.         {
  366.             _forceMove = true;
  367.             run();
  368.         }
  369.     }
  370.  
  371.     @Override
  372.     public void on_added_to_queue(AI_TaskQueue queue)
  373.     {
  374.         queue.getTaskVariable("_forceAtkRepos").registerListener(getTaskId(), AITaskSimpleVar.LISTENER_EVENTS.VALUE_CHANGE);
  375.     }
  376.  
  377.     @Override
  378.     public void on_remove_from_queue(AI_TaskQueue queue)
  379.     {
  380.         queue.getTaskVariable("_forceAtkRepos").unregisterListener(getTaskId(), AITaskSimpleVar.LISTENER_EVENTS.VALUE_CHANGE);
  381.     }
  382.  
  383.     @Override
  384.     public boolean valid_update_weight_delay()
  385.     {
  386.         return false;
  387.     }
  388. }
Add Comment
Please, Sign In to add comment