Package l2p.gameserver.skills

Source Code of l2p.gameserver.skills.Calculator

package l2p.gameserver.skills;

import l2p.Config;
import l2p.debug.StatsLimitDebugger;
import l2p.extensions.listeners.MaxHpMpCpListener;
import l2p.extensions.listeners.StatsChangeListener;
import l2p.extensions.listeners.StorageSizeListener;
import l2p.gameserver.model.L2Character;
import l2p.gameserver.skills.funcs.Func;
import l2p.gameserver.skills.funcs.FuncOwner;

/**
* A calculator is created to manage and dynamically calculate the effect of a character property (ex : MAX_HP, REGENERATE_HP_RATE...).
* In fact, each calculator is a table of Func object in which each Func represents a mathematic function : <BR><BR>
* <p/>
* FuncAtkAccuracy -> Math.sqrt(_player.getDEX())*6+_player.getLevel()<BR><BR>
* <p/>
* When the calc method of a calculator is launched, each mathematic function is called according to its priority <B>_order</B>.
* Indeed, Func with lowest priority order is executed firsta and Funcs with the same order are executed in unspecified order.
* The result of the calculation is stored in the value property of an Env class instance.<BR><BR>
* <p/>
* Method addFunc and removeFunc permit to add and remove a Func object from a Calculator.<BR><BR>
*/
public final class Calculator
{
  /**
   * Empty Func table definition
   */
  private static final Func[] emptyFuncs = new Func[0];
  /**
   * Table of Func object
   */
  private Func[] _functions;
  private static final StatsChangeListener[] emptyListeners = new StatsChangeListener[0];
  private StatsChangeListener[] _listeners = emptyListeners;
  private Double _base = null;
  private Double _last = null;
  public final Stats _stat;
  public final L2Character _character;

  /**
   * Constructor<?> of Calculator (Init value : emptyFuncs).<BR><BR>
   */
  public Calculator(Stats stat, L2Character character)
  {
    _stat = stat;
    _character = character;
    _functions = emptyFuncs;
    if(character.isPlayable() || !stat.isLimitOnlyPlayable())
    {
      if(Config.DEBUG_STAT_LIMITS && character.isPlayer())
      {
        addListener(new StatsLimitDebugger(stat));
      }
    }
    if(stat == Stats.MAX_MP || stat == Stats.MAX_HP || stat == Stats.MAX_CP)
    {
      addListener(new MaxHpMpCpListener(stat));
    }
    if(character.isPlayer() && (stat == Stats.INVENTORY_LIMIT || stat == Stats.STORAGE_LIMIT || stat == Stats.TRADE_LIMIT || stat == Stats.COMMON_RECIPE_LIMIT || stat == Stats.DWARVEN_RECIPE_LIMIT))
    {
      addListener(new StorageSizeListener(stat));
    }
  }

  /**
   * Check if 2 calculators are equals.<BR><BR>
   */
  public static boolean equalsCals(Calculator c1, Calculator c2)
  {
    if(c1 == c2)
    {
      return true;
    }
    if(c1 == null || c2 == null)
    {
      return false;
    }
    Func[] funcs1 = c1.getFunctions();
    Func[] funcs2 = c2.getFunctions();
    if(funcs1.length != funcs2.length)
    {
      return false;
    }
    if(funcs1 == funcs2)
    {
      return true;
    }
    if(funcs1.length == 0)
    {
      return true;
    }
    for(int i = 0; i < funcs1.length; i++)
    {
      if(funcs1[i] != funcs2[i])
      {
        return false;
      }
    }
    return true;
  }

  /**
   * Return the number of Funcs in the Calculator.<BR><BR>
   */
  public int size()
  {
    return _functions.length;
  }

  public synchronized void addListener(StatsChangeListener l)
  {
    StatsChangeListener[] tmp_listeners = new StatsChangeListener[_listeners.length + 1];
    if(_listeners.length > 0)
    {
      System.arraycopy(_listeners, 0, tmp_listeners, 0, _listeners.length);
    }
    tmp_listeners[_listeners.length] = l;
    l.setCalculator(this);
    _listeners = tmp_listeners;
  }

  /**
   * Add a Func to the Calculator.<BR><BR>
   */
  public synchronized void addFunc(Func f)
  {
    Func[] funcs = _functions;
    Func[] tmp = new Func[funcs.length + 1];
    final int order = f._order;
    int i;
    for(i = 0; i < funcs.length && order >= funcs[i]._order; i++)
    {
      tmp[i] = funcs[i];
    }
    tmp[i] = f;
    for(; i < funcs.length; i++)
    {
      tmp[i + 1] = funcs[i];
    }
    _functions = tmp;
  }

  /**
   * Remove a Func from the Calculator.<BR><BR>
   */
  public synchronized void removeFunc(Func f)
  {
    Func[] funcs = _functions;
    if(funcs.length == 0)
    {
      return;
    }
    if(funcs.length == 1)
    {
      if(funcs[0] == f)
      {
        _functions = emptyFuncs;
      }
      return;
    }
    int size = funcs.length;
    for(Func func : funcs)
    {
      if(func == f)
      {
        size--;
      }
    }
    if(size == funcs.length)
    {
      return;
    }
    if(size <= 0)
    {
      _functions = emptyFuncs;
      return;
    }
    Func[] tmp = new Func[size];
    int j = 0;
    for(int i = 0; i < funcs.length; i++)
    {
      if(tmp.length > j && f != funcs[i])
      {
        tmp[j++] = funcs[i];
      }
    }
    _functions = tmp;
  }

  /**
   * Remove each Func with the specified owner of the Calculator.<BR><BR>
   */
  public synchronized void removeOwner(Object owner)
  {
    Func[] funcs = _functions;
    for(Func element : funcs)
    {
      if(element._funcOwner == owner)
      {
        removeFunc(element);
      }
    }
  }

  /**
   * Run each Func of the Calculator.<BR><BR>
   */
  public void calc(Env env)
  {
    Func[] funcs = _functions;
    _base = env.value;
    boolean overrideLimits = false;
    for(Func func : funcs)
    {
      if(func._funcOwner instanceof FuncOwner)
      {
        if(!((FuncOwner) func._funcOwner).isFuncEnabled())
        {
          continue;
        }
        if(((FuncOwner) func._funcOwner).overrideLimits())
        {
          overrideLimits = true;
        }
      }
      if(func.getCondition() == null || func.getCondition().test(env))
      {
        func.calc(env);
      }
    }
    if(!overrideLimits)
    {
      if(_stat._min != null && env.value < _stat._min)
      {
        env.value = _stat._min;
      }
      if(_stat._max != null && env.value > _stat._max && (_character.isPlayer() || !_stat.isLimitOnlyPlayable()))
      {
        env.value = _stat._max;
      }
    }
    if(_last == null || _last != env.value)
    {
      Double last = _last;
      _last = env.value;
      for(StatsChangeListener _listener : _listeners)
      {
        _listener.statChanged(last, env.value, _base, env);
      }
    }
  }

  /**
   * Для отладки
   */
  public Func[] getFunctions()
  {
    return _functions;
  }

  public Double getBase()
  {
    return _base;
  }

  public Double getLast()
  {
    return _last;
  }
}
TOP

Related Classes of l2p.gameserver.skills.Calculator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.