Advertisement
Deedlit

vector engine ai abstract task

Aug 20th, 2021
1,057
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 23.65 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.gameserver.ai.L2CharacterAI;
  18. import com.l2jserver.gameserver.ai.ext.AI_TaskQueue;
  19. import com.l2jserver.gameserver.ai.ext.struct.task.AITaskSimpleVar;
  20. import com.l2jserver.gameserver.idfactory.IdFactory;
  21. import com.l2jserver.gameserver.model.actor.L2Character;
  22. import com.l2jserver.gameserver.util.DynamicExtension;
  23. import com.l2jserver.util.Rnd;
  24.  
  25. import java.lang.reflect.Constructor;
  26. import java.lang.reflect.InvocationTargetException;
  27. import java.util.concurrent.locks.ReentrantLock;
  28. import java.util.logging.Logger;
  29.  
  30. /**
  31.  * ==============================================<br>
  32.  * AbstractAITask - Abstract constuct of AI Task.<br>
  33.  *
  34.  * AI Tasks, are small routines, that AI can execute when request is made and conditions are
  35.  * met. There are three types of tasks: random (chance of execution depends on task's actual weight score,
  36.  * comparing to other queued random tasks), generic fifo/lifo (always executed one task / AI main thread cycle, and
  37.  * after successfull execution, task is removed from queue) and cyclic random / generic tasks (cyclic tasks are
  38.  * not removed from task queue, until "removable()" condition is true)
  39.  * ==============================================<br>
  40.  * @author Deedlit(deedlit@protonmail.com)
  41.  */
  42. public abstract class AbstractAITask
  43. {
  44.     protected static final Logger _log = Logger.getLogger(AbstractAITask.class.getName());
  45.  
  46.     public static final int MAX_RND_TASK_WEIGHT = 100000;
  47.  
  48.     public enum AI_TaskMaxInstancesExceededAction
  49.     {
  50.         NONE,
  51.         OVERWRITE_LAST,
  52.         OVERWRITE_FIRST,
  53.         OVERWRITE_LAST_EXECUTED(true),
  54.         OVERWRITE_FIRST_EXECUTED(true),
  55.         WAIT,
  56.         WAIT_EXECUTED(true);
  57.  
  58.         private boolean executed;
  59.  
  60.         AI_TaskMaxInstancesExceededAction()
  61.         {
  62.             this(false);
  63.         }
  64.  
  65.         AI_TaskMaxInstancesExceededAction(boolean executed)
  66.         {
  67.             this.executed = executed;
  68.         }
  69.  
  70.         public boolean executed()
  71.         {
  72.             return executed;
  73.         }
  74.     }
  75.  
  76.     /* ====================== FIELDS ================================ */
  77.     private final L2Character _actor;
  78.     private L2Character _Eactor = null;
  79.     private Runnable _task;
  80.     private boolean _result = false;
  81.     private boolean _executed = false;
  82.     private boolean _cyclic = false;
  83.     private boolean _random = false;
  84.     private int _taskId = 0;
  85.     private long _execTs = 0;
  86.     private long _createdTs = 0;
  87.     private volatile long _weightUpdateTs = 0;
  88.     private int _initialWeight = 1;
  89.     private volatile int _currentWeight = 1;
  90.     private int _execCount = 0;
  91.     private long _lastExecTs = 0;
  92.     private volatile boolean _released = true;
  93.     protected int addedOnTaskRunCycle = -1;
  94.     private AI_TaskQueue _queue = null;
  95.     private ReentrantLock _lock = new ReentrantLock(true);
  96.  
  97.     protected String _name;
  98.     /* ====================== FIELDS ================================ */
  99.  
  100.  
  101.     /* ====================== CONSTRUCTORS ========================== */
  102.  
  103.     /**
  104.      * Initializes random task, that can be set to run in cycles, with specified initial weight.
  105.      * @param queue specified task queue, to which this task will be assigned, managed and handled by.
  106.      * @param initialWeight
  107.      * @param cyclic
  108.      * @param actor
  109.      */
  110.     public AbstractAITask(AI_TaskQueue queue, int initialWeight, boolean cyclic, L2Character actor)
  111.     {
  112.         this(queue, 0, true, cyclic, initialWeight, actor);
  113.     }
  114.  
  115.     /**
  116.      * Initializes random task, that can be set to run in cycles, with specified initial weight.
  117.      * @param initialWeight
  118.      * @param cyclic
  119.      * @param actor
  120.      */
  121.     public AbstractAITask(int initialWeight, boolean cyclic, L2Character actor)
  122.     {
  123.         this(actor.getTaskQueue(), 0, true, cyclic, initialWeight, actor);
  124.     }
  125.  
  126.     /**
  127.      * Initializes single run, random task with specified initial weight.
  128.      * @param queue specified task queue, to which this task will be assigned, managed and handled by.
  129.      * @param initialWeight
  130.      * @param actor
  131.      */
  132.     public AbstractAITask(AI_TaskQueue queue, int initialWeight, L2Character actor)
  133.     {
  134.         this(queue, 0, true, false, initialWeight, actor);
  135.     }
  136.  
  137.     /**
  138.      * Initializes single run, random task with specified initial weight.
  139.      * @param initialWeight
  140.      * @param actor
  141.      */
  142.     public AbstractAITask(int initialWeight, L2Character actor)
  143.     {
  144.         this(actor.getTaskQueue(), 0, true, false, initialWeight, actor);
  145.     }
  146.  
  147.     /**
  148.      * Initializes general type task, single or cyclic execution mode.
  149.      * @param queue specified task queue, to which this task will be assigned, managed and handled by.
  150.      * @param cyclic
  151.      * @param actor
  152.      */
  153.     public AbstractAITask(AI_TaskQueue queue, boolean cyclic, L2Character actor)
  154.     {
  155.         this(queue, 0, false, cyclic, 0, actor);
  156.     }
  157.  
  158.     /**
  159.      * Initializes general type task, single or cyclic execution mode.
  160.      * @param cyclic
  161.      * @param actor
  162.      */
  163.     public AbstractAITask(boolean cyclic, L2Character actor)
  164.     {
  165.         this(actor.getTaskQueue(), 0, false, cyclic, 0, actor);
  166.     }
  167.  
  168.     /**
  169.      * Initializes general type task. Single execution mode.
  170.      * @param queue specified task queue, to which this task will be assigned, managed and handled by.
  171.      * @param actor
  172.      */
  173.     public AbstractAITask(AI_TaskQueue queue, L2Character actor)
  174.     {
  175.         this(queue, 0, false, false, 0, actor);
  176.     }
  177.  
  178.     /**
  179.      * Initializes general type task. Single execution mode.
  180.      * @param actor
  181.      */
  182.     public AbstractAITask(L2Character actor)
  183.     {
  184.         this(actor.getTaskQueue(), 0, false, false, 0, actor);
  185.     }
  186.  
  187.     /**
  188.      * Create AI task.
  189.      * @param queue specified task queue, to which this task will be assigned, managed and handled by.
  190.      * @param taskUniqueId    <0 to assign automatically from IdFactory pool. NOTE: TaskQueue for tasks, that do not have assigned ID, will automatically assign one, on addition to TaskQueue. To
  191.      *      reduce CPU utilization, it's preferred, that you create tasks without assigned id, to perform basic validation.
  192.      * @param random    true if this task is "random" task type (AI TaskQueue manager, will randomly execute one random task; chance
  193.      *      depends on task's current "weight"; max. weight = AbstractAI.MAX_RND_TASK_WEIGHT)
  194.      * @param cyclic    true if this is an cyclic task (will be executed on every cycle); false if this task should be executed only once and
  195.      *      then removed from pool (or reinitialized)
  196.      * @param initialWeight    initial task "weight". Used by "random" task type only, to determine initial random chance for task to be
  197.      *      randomly executed. Min. is 1, max is AbstractAI.MAX_RND_TASK_WEIGHT.
  198.      * @param actor    character
  199.      */
  200.     public AbstractAITask(AI_TaskQueue queue, int taskUniqueId, boolean random, boolean cyclic, int initialWeight, L2Character actor)
  201.     {
  202.         _queue = queue;
  203.         _taskId = taskUniqueId;
  204.         if (_taskId < 0)
  205.             getNewId();
  206.         _actor = actor;
  207.         _Eactor = actor;
  208.         _createdTs = System.currentTimeMillis();
  209.         _cyclic = cyclic;
  210.         _random = random;
  211.         if (_random)
  212.         {
  213.             setWeight(initialWeight, true);
  214.             setWeight(initialWeight, false);
  215.         }
  216.  
  217.         initTaskTypeName();
  218.     }
  219.  
  220.     /* ====================== CONSTRUCTORS ========================== */
  221.  
  222.     //----------------------------------- MAIN CLASS ----------------------------------------------//
  223.  
  224.     protected void initTaskTypeName()
  225.     {
  226.         _name = getClass().getSimpleName();
  227.     }
  228.  
  229.     /**
  230.      * Returns task type name (by default task class name).
  231.      * @return
  232.      */
  233.     public String getTaskTypeName()
  234.     {
  235.         return _name;
  236.     }
  237.  
  238.     /**
  239.      * Access task queue object.
  240.      * @return
  241.      */
  242.     public final AI_TaskQueue getTaskQueue()
  243.     {
  244.         return _queue;
  245.     }
  246.  
  247.     /**
  248.      * Set task's Task Queue that will handle execution.
  249.      * @param queue
  250.      */
  251.     public final void setTaskQueue(AI_TaskQueue queue)
  252.     {
  253.         _queue = queue;
  254.     }
  255.  
  256.     /**
  257.      * Check if owner has now active AI.
  258.      * @return
  259.      */
  260.     public boolean hasAI()
  261.     {
  262.         return getActor().hasAI();
  263.     }
  264.  
  265.     /**
  266.      * Access owner's AI.
  267.      * @return
  268.      */
  269.     public L2CharacterAI getAI()
  270.     {
  271.         if (hasAI())
  272.             return getActor().getAI();
  273.         return null;
  274.     }
  275.  
  276.     /**
  277.      * Access actor (owner) of task AI.
  278.      * @return
  279.      */
  280.     public L2Character getActor()
  281.     {
  282.         if (_actor == null)
  283.             return _Eactor;
  284.         return _actor;
  285.     }
  286.  
  287.     /**
  288.      * Executed by AI task manager.
  289.      * @param useThreadPoolManager
  290.      */
  291.     public final boolean runThread()
  292.     {
  293.         if (_lock.tryLock())
  294.         {
  295.             try
  296.             {
  297.                 _executed = true;
  298.                 _execTs = System.currentTimeMillis();
  299.                 _execCount++;
  300.                 getTaskQueue().registerTaskTypeExecCountAndTimestamp(hashCode());
  301.                 _result = run();
  302.                 return true;
  303.             }
  304.             catch (Exception e)
  305.             {
  306.  
  307.             }
  308.             finally
  309.             {
  310.                 _lock.unlock();
  311.             }
  312.         }
  313.         return false;
  314.     }
  315.  
  316.     /**
  317.      * Returns timestamp of task creation.
  318.      * @return
  319.      */
  320.     public final long getTaskCreateTimestamp()
  321.     {
  322.         return _createdTs;
  323.     }
  324.  
  325.     /**
  326.      * Returns timestamp of last execution of task.
  327.      * @param onlyThisTask  true - will return counter of exacly this task; false - will return AI TaskQueue global counter, for all tasks of this type.
  328.      * @return
  329.      */
  330.     public final long getTaskLastExecTimestamp(boolean onlyThisTask)
  331.     {
  332.         if (onlyThisTask)
  333.             return _execTs > 0 ? _execTs : _lastExecTs;
  334.         return getTaskQueue().getTaskTypeLastExecTimestamp(hashCode());
  335.     }
  336.  
  337.     /**
  338.      * Returns timestamp of last succesfull weight_update();
  339.      * @return
  340.      */
  341.     public long getLastWeightUpdateTimestamp()
  342.     {
  343.         return _weightUpdateTs;
  344.     }
  345.  
  346.     /**
  347.      * Returns time (millis), since last execution of task (successfull or not), or -1 if task not yet executed.
  348.      * @param onlyThisTask  true - will return counter of exacly this task; false - will return AI TaskQueue global counter, for all tasks of this type.
  349.      * @return
  350.      */
  351.     public final long calcTimeSinceTaskLastExec(boolean onlyThisTask)
  352.     {
  353.         if (getTaskLastExecTimestamp(onlyThisTask) > 0)
  354.             return System.currentTimeMillis() - getTaskLastExecTimestamp(onlyThisTask);
  355.         return -1;
  356.     }
  357.  
  358.     /**
  359.      * Returns time (millis), since task has been created (constructed)
  360.      * @return
  361.      */
  362.     public final long calcTimeSinceTaskCreate()
  363.     {
  364.         if (getTaskCreateTimestamp() > 0)
  365.             return System.currentTimeMillis() - getTaskCreateTimestamp();
  366.         return -1;
  367.     }
  368.  
  369.     /**
  370.      * Holds counter for task executions.
  371.      * @param onlyThisTask  true - will return counter of exacly this task; false - will return AI TaskQueue global counter, for all tasks of this type.
  372.      * @return
  373.      */
  374.     public final int getTaskExecCounter(boolean onlyThisTask)
  375.     {
  376.         if (onlyThisTask)
  377.             return _execCount;
  378.         return getTaskQueue().getTaskTypeExecCount(hashCode());
  379.     }
  380.  
  381.     /**
  382.      * Determine if task execution was successfull.
  383.      * @return
  384.      */
  385.     public final boolean execSuccess()
  386.     {
  387.         return _result;
  388.     }
  389.  
  390.     /**
  391.      * Determine if task was executed.
  392.      * @return
  393.      */
  394.     public final boolean taskExecuted()
  395.     {
  396.         return _executed;
  397.     }
  398.  
  399.     /**
  400.      * Returns task unique id, or 0 if no id assigned (task id released)
  401.      * @return
  402.      */
  403.     public final int getTaskId()
  404.     {
  405.         return _taskId;
  406.     }
  407.  
  408.     /**
  409.      * Determines if task is cyclic, or removed after one execution.
  410.      * @return
  411.      */
  412.     public boolean cyclic()
  413.     {
  414.         return _cyclic;
  415.     }
  416.  
  417.     /**
  418.      * Determines if task is randomized.
  419.      * @return
  420.      */
  421.     public boolean random()
  422.     {
  423.         return _random;
  424.     }
  425.  
  426.     /**
  427.      * Set random task weight.
  428.      * @param weight
  429.      * @param initial
  430.      */
  431.     public void setWeight(int weight, boolean initial)
  432.     {
  433.         if (initial)
  434.             _initialWeight = getWeightProperLimits(weight);
  435.         else
  436.         {
  437.             _weightUpdateTs = System.currentTimeMillis();
  438.             _currentWeight = getWeightProperLimits(weight);
  439.         }
  440.     }
  441.  
  442.     /**
  443.      * Return current random task weight.
  444.      * @param initial
  445.      * @return
  446.      */
  447.     public int weight(boolean initial)
  448.     {
  449.         if (initial)
  450.             return _initialWeight;
  451.         return _currentWeight;
  452.     }
  453.  
  454.     /**
  455.      * Reset task "executed" and "result" states, to initial. Store latest execution time and reset it..
  456.      */
  457.     public void reset()
  458.     {
  459.         _lastExecTs = _execTs;
  460.         _execTs = 0;
  461.         _executed = false;
  462.         _result = false;
  463.     }
  464.  
  465.     /**
  466.      * Add task to queue.
  467.      * @param topOfQueue
  468.      * @return
  469.      */
  470.     public final boolean addToQueue(boolean topOfQueue)
  471.     {
  472.         return getTaskQueue().addTaskToQueue(this, topOfQueue);
  473.     }
  474.  
  475.     /**
  476.      * Removes task from queue.
  477.      * @return
  478.      */
  479.     public final boolean removeFromQueue(boolean releaseId)
  480.     {
  481.         return getTaskQueue().removeTaskFromQueue(this, releaseId);
  482.     }
  483.  
  484.     /**
  485.      * Check if this task is already queued in AI.
  486.      * @return
  487.      */
  488.     public final boolean isTaskQueued()
  489.     {
  490.         return getTaskQueue().isTaskQueued(this);
  491.     }
  492.  
  493.     /**
  494.      * Release task id and return it to idfactory pool.
  495.      */
  496.     public final void free()
  497.     {
  498.         if (_released)
  499.             return;
  500.         _released = true;
  501.         IdFactory.getInstance().releaseId(_taskId);
  502.         _taskId = 0;
  503.     }
  504.  
  505.     /**
  506.      * Check if task is has been released.
  507.      * @return
  508.      */
  509.     public final boolean released()
  510.     {
  511.         return _released;
  512.     }
  513.  
  514.     /**
  515.      * After releasing task id (free()), use getNewId() to assign new unique id for task, from idfactory.
  516.      * @return
  517.      */
  518.     public final int getNewId()
  519.     {
  520.         if (!_released && _taskId != 0)
  521.             return _taskId;
  522.         _released = false;
  523.         _taskId = IdFactory.getInstance().getNextId();
  524.         return _taskId;
  525.     }
  526.  
  527.     /*  ========================================================================== */
  528.  
  529.     /**
  530.      * Get task class hashCode, used to identify task classes.
  531.      *
  532.      * @return
  533.      */
  534.     @Override
  535.     public int hashCode()
  536.     {
  537.         return _name.hashCode();
  538.     }
  539.  
  540.     @Override
  541.     public boolean equals(Object obj)
  542.     {
  543.         return isSameType(obj) && (!((AbstractAITask)obj).released() && !released() && ((AbstractAITask)obj).getTaskId() == getTaskId());
  544.     }
  545.  
  546.     public boolean isSameType(Object obj)
  547.     {
  548.         return (obj instanceof AbstractAITask && ((AbstractAITask)obj).hashCode() == hashCode());
  549.     }
  550.  
  551.     @Override
  552.     public String toString()
  553.     {
  554.         return toString(false);
  555.     }
  556.  
  557.     public String toString(boolean noActorInfo)
  558.     {
  559.         return getTaskTypeName()+":["+(!released() ? getTaskId() : "id_released")+"] type=("+(cyclic() ? "cyclic" : "single")+","+(random() ? "random{weight:"
  560.                 + weight(false)+"}" : "generic")+") valid="+valid()+" waiting="+waiting(getTaskQueue().getTaskRunCycle())+"(taskcycle="+getTaskQueue().getTaskRunCycle()+") ready="+ready()
  561.                 +" executed="+taskExecuted()+(taskExecuted() ? "{result:"+execSuccess()+"}" : "")+" exec_count="+getTaskExecCounter(true)+"/"+getTaskExecCounter(false)
  562.                 +" removable="+removeable()+" valid_run_delay="+ valid_run_delay()+" max_instances="+max_task_instances()+" hashcode="+hashCode()+(!noActorInfo ? "; actor:"+getActor() : "");
  563.     }
  564.     /*  ========================================================================== */
  565.  
  566.     /**
  567.      * If you wish to put task type int AI debug exception list, override this method and return true, for all task types you wish not to be logged by AI loggers.
  568.      * @return
  569.      */
  570.     public boolean quiet_exec()
  571.     {
  572.         return false;
  573.     }
  574.  
  575.     public void setAddedOnTaskRunCycle(int cycle)
  576.     {
  577.         this.addedOnTaskRunCycle = cycle;
  578.     }
  579.  
  580.     /**
  581.      * Check if task is waiting.
  582.      * @return
  583.      */
  584.     public boolean waiting(int taskRunCycle)
  585.     {
  586.         if (taskRunCycle < 0 || addedOnTaskRunCycle < 0)
  587.             return false;
  588.  
  589.         return taskRunCycle <= addedOnTaskRunCycle;
  590.     }
  591.  
  592.     /* ====================== ABSTRACT METHODS ====================== */
  593.  
  594.     /**
  595.      * Check if task state is valid. Validity is checked before adding task to queue, and before every task run. This method should be able to determine with as low computation, as possible, if
  596.      * AI conditions are right, for task to be added to queue..
  597.      * @return
  598.      */
  599.     public abstract boolean valid();
  600.  
  601.     /**
  602.      * Check if task is ready to execution.
  603.      * @return
  604.      */
  605.     public abstract boolean ready();
  606.  
  607.     /**
  608.      * Abstract task procedute.
  609.      * @return
  610.      */
  611.     public abstract boolean run();
  612.  
  613.     /**
  614.      * Determine if after running sucessfully this task, onEvtThink() should be skipped in this AI thread cycle.
  615.      * @return
  616.      */
  617.     public abstract boolean block_think_after_run();
  618.  
  619.     /**
  620.      * Executed by AI, to check if weight should be updated.
  621.      * @return
  622.      */
  623.     public abstract int update_weight();
  624.  
  625.     /**
  626.      * Check if "random" type task weight can be updated at this time.
  627.      * @return
  628.      */
  629.     public abstract boolean valid_update_weight_delay();
  630.  
  631.     /**
  632.      * Determine if task should be removed from queue, after, even unsucessfull execution.
  633.      * @return  true - task will be auto removed from queue after exec (even unsuccessfull)
  634.      */
  635.     public abstract boolean removeable();
  636.  
  637.     /**
  638.      * Determine if enough time has passed, for task to be run.
  639.      * @return  true if yes
  640.      */
  641.     public abstract boolean valid_run_delay();
  642.  
  643.     /**
  644.      * Determine how many instances of task, can be in AI TaskQueue. Some tasks require max. 1 active instance in queue, some do not need to be limited.
  645.      * @return number of max. instances of this task in AI TaskQueue, 0 if no instance allowed atm, or -1, if no limits.
  646.      */
  647.     public abstract int max_task_instances();
  648.  
  649. //  public abstract AI_TaskMaxInstancesExceededAction max_task_instances_exceeded_action();
  650.  
  651.     /**
  652.      * Triggered by Task Queue, when task registers to listen for certain events of queue variables.
  653.      *
  654.      * @param event event that occured
  655.      * @param variable    variable that triggered event.
  656.      */
  657.     public abstract void on_variable_listener(AITaskSimpleVar.LISTENER_EVENTS event, AITaskSimpleVar variable);
  658.  
  659.     /**
  660.      * Triggered by Task Queue, after sucessfully adding task to queue.
  661.      *
  662.      * @param queue
  663.      */
  664.     public abstract void on_added_to_queue(AI_TaskQueue queue);
  665.  
  666.     /**
  667.      * Triggered by Task Queue, before removing task from queue, allowing performing cleanup (eg. unregistering variable listeners).
  668.      *
  669.      * @param queue
  670.      */
  671.     public abstract void on_remove_from_queue(AI_TaskQueue queue);
  672.  
  673.     /* ====================== ABSTRACT METHODS ====================== */
  674.  
  675.     public synchronized void setEActor(L2Character actor)
  676.     {
  677.         _Eactor = actor;
  678.     }
  679.  
  680.     public boolean isEActor()
  681.     {
  682.         return _Eactor != null;
  683.     }
  684.  
  685.     /* ====================== STATIC HELPER METHODS ================= */
  686.  
  687.     /**
  688.      * Calculates weight score for task, using specified percentage value of max. allowed weight.
  689.      * @param weightPercentageOfMaxWeightAllowed    weight percentage (0.001 to 100.0%)
  690.      * @return  weight score for task, corresponding to provided weight (of max allowed) percentage.
  691.      */
  692.     public static int calculateWeightForPercentage(double weightPercentageOfMaxWeightAllowed)
  693.     {
  694.         if (weightPercentageOfMaxWeightAllowed <= 0)
  695.             weightPercentageOfMaxWeightAllowed = 0.001;
  696.         if (weightPercentageOfMaxWeightAllowed > 100)
  697.             weightPercentageOfMaxWeightAllowed = 100.;
  698.         return (int) Math.round((weightPercentageOfMaxWeightAllowed * (MAX_RND_TASK_WEIGHT / 100.)));
  699.     }
  700.  
  701.     /**
  702.      * Returns proper weight value, for provided weight.
  703.      * @param weight    task weight.
  704.      * @return  proper weight value (1 ... AbstractAI.MAX_RND_TASK_WEIGHT inclusive)
  705.      */
  706.     public static int getWeightProperLimits(int weight)
  707.     {
  708.         if (weight < 1)
  709.             return 1;
  710.         if (weight > MAX_RND_TASK_WEIGHT)
  711.             return MAX_RND_TASK_WEIGHT;
  712.         return weight;
  713.     }
  714.  
  715.     /**
  716.      * Generates random weight value for task, in range between provided min and max (inclusive) value. Returned weight is always
  717.      *  limited to proper weight range (1 ... AbstractAI.MAX_RND_TASK_WEIGHT), if min ... max out of range.
  718.      * @param min
  719.      * @param max
  720.      * @return
  721.      */
  722.     public static int getRandomWeightRange(int min, int max)
  723.     {
  724.         return getWeightProperLimits(Rnd.qget(min, max));
  725.     }
  726.  
  727.     /**
  728.      * Returns chance percentage for specified <u>weight</u>.
  729.      *
  730.      * @param weight    task weight value (0... to {@link #MAX_RND_TASK_WEIGHT})
  731.      * @return  how much of MAX_RND_TASK_WEIGHT specified weight is, in percentage (0 - 100.0)
  732.      */
  733.     public static double getPercentageForWeight(int weight)
  734.     {
  735.         return (double)weight * 100. / (double)MAX_RND_TASK_WEIGHT;
  736.     }
  737.  
  738.     /* ====================== STATIC HELPER METHODS ================= */
  739.  
  740.  
  741.     /* ===================== STATIC TASK CLASS INITIALIZERS ============== */
  742.  
  743.     /**
  744.      * Creates new instance of AI Task.
  745.      *
  746.      * @param className    class name of AI task (loaded with {@link DynamicExtension#getExtensionClass(String)} or available in {@link com.l2jserver.gameserver.ai.ext.tasks.*} package.
  747.      * @param constructor_params    constructor definition
  748.      * @param params    constructor parameters
  749.      * @return  instance of AbstractAITask child, or null when failed.
  750.      *
  751.      * @throws ClassNotFoundException
  752.      * @throws NoSuchMethodException
  753.      * @throws IllegalAccessException
  754.      * @throws java.lang.reflect.InvocationTargetException
  755.      * @throws InstantiationException
  756.      */
  757.     public static AbstractAITask newTaskInstance(AI_TaskQueue queue, String className, final Class<?>[] constructor_params, final Object[] params)
  758.             throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException
  759.     {
  760.         if (className == null)
  761.             throw new ClassNotFoundException((queue != null ? queue.getTaskQueueName() : "newTaskInstance")+": AI Task for class name not registered ["+className+"].");
  762.  
  763.         Class<?> n = DynamicExtension.getInstance().getExtensionClass(className);
  764.         Constructor<?> _constructor = null;
  765.         if (n == null) // Not found. Try within server's core.
  766.             _constructor = Class.forName("com.l2jserver.gameserver.ai.ext.tasks." + className).getConstructor(constructor_params);
  767.         else
  768.             _constructor = Class.forName(n.getCanonicalName(), true, DynamicExtension.getInstance().getClassLoader()).getConstructor(constructor_params);
  769.  
  770.         if (_constructor == null)
  771.             throw new ClassNotFoundException((queue != null ? queue.getTaskQueueName() : "newTaskInstance")+": AI Task for class name not registered ["+className+"].");
  772.  
  773.         Object  tmp = _constructor.newInstance(params);
  774.         if (tmp instanceof AbstractAITask)
  775.             return ((AbstractAITask)tmp);
  776.         else
  777.             throw new UnsupportedClassVersionError((queue != null ? queue.getTaskQueueName() : "newTaskInstance")+": Can't create new AI Task instance, for class name. \""+tmp.getClass().getCanonicalName()+"\" is not an valid instance of [AbstractAITask].");
  778.     }
  779.  
  780.     /**
  781.      * Create new task (see {@link #newTaskInstance(com.l2jserver.gameserver.ai.ext.AI_TaskQueue, String, Class[], Object[])} ).
  782.      *
  783.      * @param className  class name of AI task (loaded with {@link DynamicExtension#getExtensionClass(String)} or available in {@link com.l2jserver.gameserver.ai.ext.tasks.*} package.
  784.      * @param randomTask
  785.      * @param cyclicTask
  786.      * @param initialWeight
  787.      * @param cha
  788.      * @return
  789.      * @throws ClassNotFoundException
  790.      * @throws InvocationTargetException
  791.      * @throws NoSuchMethodException
  792.      * @throws InstantiationException
  793.      * @throws IllegalAccessException
  794.      */
  795.     public static AbstractAITask newTaskInstance(AI_TaskQueue queue, String className, boolean randomTask, boolean cyclicTask, int initialWeight, L2Character cha)
  796.             throws ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException
  797.     {
  798.         return newTaskInstance(queue, className, new Class<?>[]{Class.forName("com.l2jserver.gameserver.ai.ext.AI_TaskQueue"), int.class, boolean.class, boolean.class, int.class, Class.forName("com.l2jserver.gameserver.model.actor.L2Character")},
  799.                 new Object[] {queue, 0, randomTask, cyclicTask, initialWeight, cha});
  800.     }
  801.  
  802.     /* ===================== STATIC TASK CLASS INITIALIZERS ============== */
  803. }
  804.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement