protected void attachFunc(Node n, Object template, String functionName, Condition attachCond) { Stats stat = Stats.valueOfXml(n.getAttributes().getNamedItem("stat").getNodeValue()); int order = -1; final Node orderNode = n.getAttributes().getNamedItem("order"); if (orderNode != null) { order = Integer.parseInt(orderNode.getNodeValue()); } String valueString = n.getAttributes().getNamedItem("val").getNodeValue(); double value; if (valueString.charAt(0) == '#') { value = Double.parseDouble(getTableValue(valueString)); } else { value = Double.parseDouble(valueString); } final Condition applayCond = parseCondition(n.getFirstChild(), template); final FuncTemplate ft = new FuncTemplate(attachCond, applayCond, functionName, order, stat, value); if (template instanceof L2Item) { ((L2Item) template).attach(ft); } else if (template instanceof AbstractEffect) { ((AbstractEffect) template).attach(ft); } else { throw new RuntimeException("Attaching stat to a non-effect template!!!"); } }
/** * Calculate the new value of the state with modifiers that will be applied on the targeted * L2Character.<br> * <B><U> Concept</U> :</B><BR * A L2Character owns a table of Calculators called <B> * _calculators</B>. Each Calculator (a calculator per state) own a table of Func object. A Func * object is a mathematic function that permit to calculate the modifier of a state (ex : * REGENERATE_HP_RATE...) : <br> * FuncAtkAccuracy -> Math.sqrt(_player.getDEX())*6+_player.getLevel()<br> * When the calc method of a calculator is launched, each mathematical function is called * according to its priority <B>_order</B>.<br> * Indeed, Func with lowest priority order is executed firsta and Funcs with the same order are * executed in unspecified order.<br> * The result of the calculation is stored in the value property of an Env class instance.<br> * * @param stat The stat to calculate the new value with modifiers * @param initVal The initial value of the stat before applying modifiers * @param target The L2Charcater whose properties will be used in the calculation (ex : CON, * INT...) * @param skill The L2Skill whose properties will be used in the calculation (ex : Level...) * @return */ public final double calcStat(Stats stat, double initVal, L2Character target, Skill skill) { double value = initVal; if (stat == null) { return value; } final int id = stat.ordinal(); final Calculator c = _activeChar.getCalculators()[id]; // If no Func object found, no modifier is applied if ((c == null) || (c.size() == 0)) { return value; } // Apply transformation stats. if (getActiveChar().isPlayer() && getActiveChar().isTransformed()) { double val = getActiveChar().getTransformation().getStat(getActiveChar().getActingPlayer(), stat); if (val > 0) { value = val; } } // Launch the calculation value = c.calc(_activeChar, target, skill, value); // avoid some troubles with negative stats (some stats should never be negative) if (value <= 0) { switch (stat) { case MAX_HP: case MAX_MP: case MAX_CP: case MAGIC_DEFENCE: case POWER_DEFENCE: case POWER_ATTACK: case MAGIC_ATTACK: case POWER_ATTACK_SPEED: case MAGIC_ATTACK_SPEED: case SHIELD_DEFENCE: case STAT_CON: case STAT_DEX: case STAT_INT: case STAT_MEN: case STAT_STR: case STAT_WIT: case STAT_LUC: case STAT_CHA: { value = 1.0; break; } } } return value; }