1
0
mirror of https://github.com/Rogiel/l2jserver2 synced 2025-12-09 08:52:51 +00:00

Semi-working attack service

Signed-off-by: Rogiel <rogiel@rogiel.com>
This commit is contained in:
2011-05-30 20:02:19 -03:00
parent 52d4be0bf2
commit ae3007559f
61 changed files with 537 additions and 181 deletions

View File

@@ -78,6 +78,22 @@ public class AttackHit {
}
}
/**
* Creates a new instance
*
* @param attacker
* the actor attacking <tt>target</tt>
* @param target
* the actor being attacked by <tt>attacker</tt>
* @param damage
* the damage issued in this hit
*/
public AttackHit(Actor attacker, Actor target, double damage) {
this.attacker = attacker;
this.target = target;
this.damage = damage;
}
/**
* Creates a new instance
*

View File

@@ -0,0 +1,28 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.model.server.attack;
import com.l2jserver.util.calculator.SimpleCalculator;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class AttackCalculator extends SimpleCalculator<AttackCalculatorContext> {
public AttackCalculator(AttackCalculatorFunction... functions) {
super(functions);
}
}

View File

@@ -0,0 +1,33 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.model.server.attack;
import com.l2jserver.model.world.Actor;
import com.l2jserver.util.calculator.CalculatorContext;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class AttackCalculatorContext extends CalculatorContext {
public final Actor attacker;
public final Actor target;
public AttackCalculatorContext(Actor attacker, Actor target) {
this.attacker = attacker;
this.target = target;
}
}

View File

@@ -0,0 +1,37 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.model.server.attack;
import com.l2jserver.model.world.Actor;
import com.l2jserver.util.calculator.AbstractDoubleFunction;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public abstract class AttackCalculatorFunction extends
AbstractDoubleFunction<AttackCalculatorContext> {
public AttackCalculatorFunction(int order) {
super(order);
}
@Override
public double calculate(AttackCalculatorContext ctx, double value) {
return calculate(ctx.attacker, ctx.target, value);
}
public abstract double calculate(Actor attacker, Actor target, double value);
}

View File

@@ -0,0 +1,45 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.model.server.attack;
import com.l2jserver.model.world.Actor;
/**
* Calculator used to calculate physical damage on each hit.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class PhysicalAttackCalculator extends AttackCalculator {
public PhysicalAttackCalculator() {
super(new AttackCalculatorFunction(0x000) {
@Override
public double calculate(Actor attacker, Actor target, double value) {
// TODO this is certainly not right!!!
// this is just an simple calculator for testing!
return attacker.getStats().getPhysicalAttack()
- target.getStats().getPhysicalDefense();
}
}, new AttackCalculatorFunction(Integer.MAX_VALUE) {
@Override
public double calculate(Actor attacker, Actor target, double value) {
if (value <= 0)
return 1;
return value;
}
});
}
}

View File

@@ -28,6 +28,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.l2jserver.model.id.template.ItemTemplateID;
import com.l2jserver.model.template.calculator.ItemPhysicalDamageActorCalculator;
import com.l2jserver.model.world.Item;
import com.l2jserver.util.jaxb.ItemTemplateIDAdapter;
@@ -58,15 +59,26 @@ public class ItemTemplate extends AbstractTemplate<Item> {
protected int price = 0;
@XmlElement(name = "icon")
protected String icon;
@XmlElement(name = "weight")
@XmlElement(name = "effect")
protected EffectContainer effect;
@XmlType(namespace = "item")
private static class EffectContainer {
@XmlAttribute(name = "type")
protected EffectType effect = null;
protected EffectType effect;
}
@XmlType(namespace = "item")
protected static class StatsContainer {
@XmlElement(name = "physicalDamage")
protected StatAttribute physicalDamage;
@XmlElement(name = "magicalDamage")
protected StatAttribute magicalDamage;
}
@XmlElement(name = "stats")
protected StatsContainer stats;
protected ItemMaterial material;
public enum ItemMaterial {
@@ -77,6 +89,38 @@ public class ItemTemplate extends AbstractTemplate<Item> {
IMMEDIATE;
}
@XmlType(namespace = "item")
public static class StatAttribute {
@XmlElement(name = "set")
protected StatSet set;
public static class StatSet {
protected int order;
protected double value;
/**
* @return the order
*/
public int getOrder() {
return order;
}
/**
* @return the value
*/
public double getValue() {
return value;
}
}
/**
* @return the set
*/
public StatSet getSet() {
return set;
}
}
@Override
public Item create() {
log.debug("Creating a new Item instance with template {}", this);
@@ -125,6 +169,24 @@ public class ItemTemplate extends AbstractTemplate<Item> {
return material;
}
/**
* @return the physical damage
*/
public ItemPhysicalDamageActorCalculator getPhysicalDamage() {
if (stats == null)
return null;
return new ItemPhysicalDamageActorCalculator(stats.physicalDamage.set);
}
/**
* @return the magical damage
*/
public StatAttribute getMagicalDamage() {
if (stats == null)
return null;
return stats.magicalDamage;
}
/*
* (non-Javadoc)
*

View File

@@ -14,30 +14,24 @@
* You should have received a copy of the GNU General Public License
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.model.world.npc.calculator.base;
package com.l2jserver.model.template.calculator;
import com.l2jserver.model.template.NPCTemplate;
import com.l2jserver.model.world.NPC;
import com.l2jserver.model.world.npc.calculator.NPCCalculator;
import com.l2jserver.model.world.npc.calculator.NPCCalculatorFunction;
import com.l2jserver.model.template.ActorTemplate;
import com.l2jserver.model.template.ItemTemplate.StatAttribute.StatSet;
import com.l2jserver.model.world.Actor;
import com.l2jserver.model.world.actor.calculator.ActorCalculator;
import com.l2jserver.model.world.actor.calculator.ActorCalculatorFunction;
/**
* Calculates the character base accuracy.
*
* <pre>
* ctx.result = c.getTemplate().getBaseAccuracy();
* </pre>
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
*/
public class NPCBaseAttackAccuracyCalculator extends NPCCalculator {
public NPCBaseAttackAccuracyCalculator() {
super(new NPCCalculatorFunction(0x000) {
public class ItemPhysicalDamageActorCalculator extends ActorCalculator {
public ItemPhysicalDamageActorCalculator(final StatSet set) {
super(new ActorCalculatorFunction(set.getOrder()) {
@Override
protected double calculate(NPC c, NPCTemplate t, double value) {
// return t.getEvasion()
// TODO
return value;
protected double calculate(Actor a, ActorTemplate<?> t, double value) {
return set.getValue();
}
});
}

View File

@@ -30,8 +30,14 @@ import com.l2jserver.service.game.ai.AIScript;
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class NPC extends Actor {
private NPCStats stats;
/**
* This NPC stats
*/
private final NPCStats stats = new NPCStats(this);
/**
* The npc state
*/
private NPCState state;
public enum NPCState {
@@ -48,9 +54,7 @@ public class NPC extends Actor {
super(templateID);
}
/**
* @return the stats
*/
@Override
public NPCStats getStats() {
return stats;
}
@@ -90,7 +94,8 @@ public class NPC extends Actor {
public void setState(NPCState state) {
this.state = state;
}
// TEMPLATE WRAPPERS
@Override
public ActorSex getSex() {
return this.getTemplate().getSex();

View File

@@ -16,12 +16,12 @@
*/
package com.l2jserver.model.world.actor.calculator;
import com.l2jserver.util.calculator.Calculator;
import com.l2jserver.util.calculator.SimpleCalculator;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class ActorCalculator extends Calculator<ActorCalculatorContext> {
public class ActorCalculator extends SimpleCalculator<ActorCalculatorContext> {
public ActorCalculator(ActorCalculatorFunction... functions) {
super(functions);
}

View File

@@ -18,7 +18,7 @@ package com.l2jserver.model.world.actor.calculator;
import com.l2jserver.model.template.ActorTemplate;
import com.l2jserver.model.world.Actor;
import com.l2jserver.util.calculator.AbstractFunction;
import com.l2jserver.util.calculator.AbstractDoubleFunction;
/**
* An calculator for character formulas.
@@ -26,7 +26,7 @@ import com.l2jserver.util.calculator.AbstractFunction;
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public abstract class ActorCalculatorFunction extends
AbstractFunction<ActorCalculatorContext> {
AbstractDoubleFunction<ActorCalculatorContext> {
public ActorCalculatorFunction(int order) {
super(order);
}

View File

@@ -16,11 +16,9 @@
*/
package com.l2jserver.model.world.actor.calculator;
import com.l2jserver.model.template.CharacterTemplate;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.template.ActorTemplate;
import com.l2jserver.model.world.Actor;
import com.l2jserver.model.world.actor.stat.BaseStats;
import com.l2jserver.model.world.character.calculator.CharacterCalculator;
import com.l2jserver.model.world.character.calculator.CharacterCalculatorFunction;
/**
* Calculates the character base run speed
@@ -31,12 +29,11 @@ import com.l2jserver.model.world.character.calculator.CharacterCalculatorFunctio
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class RunSpeedBonusCalculator extends CharacterCalculator {
public class RunSpeedBonusCalculator extends ActorCalculator {
public RunSpeedBonusCalculator() {
super(new CharacterCalculatorFunction(0x300) {
super(new ActorCalculatorFunction(0x300) {
@Override
protected double calculate(L2Character c, CharacterTemplate t,
double value) {
protected double calculate(Actor c, ActorTemplate<?> t, double value) {
return value
* BaseStats.DEX.calculateBonus(c.getStats()
.getDexterity());

View File

@@ -16,11 +16,9 @@
*/
package com.l2jserver.model.world.actor.calculator;
import com.l2jserver.model.template.CharacterTemplate;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.template.ActorTemplate;
import com.l2jserver.model.world.Actor;
import com.l2jserver.model.world.actor.stat.BaseStats;
import com.l2jserver.model.world.character.calculator.CharacterCalculator;
import com.l2jserver.model.world.character.calculator.CharacterCalculatorFunction;
/**
* Calculates the character base walk speed
@@ -31,12 +29,11 @@ import com.l2jserver.model.world.character.calculator.CharacterCalculatorFunctio
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class WalkSpeedBonusCalculator extends CharacterCalculator {
public class WalkSpeedBonusCalculator extends ActorCalculator {
public WalkSpeedBonusCalculator() {
super(new CharacterCalculatorFunction(0x300) {
super(new ActorCalculatorFunction(0x300) {
@Override
protected double calculate(L2Character c, CharacterTemplate t,
double value) {
protected double calculate(Actor c, ActorTemplate<?> t, double value) {
return value
* BaseStats.DEX.calculateBonus(c.getStats()
.getDexterity());

View File

@@ -0,0 +1,68 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.model.world.actor.event;
import com.l2jserver.model.id.ObjectID;
import com.l2jserver.model.server.AttackHit;
import com.l2jserver.model.world.Actor;
import com.l2jserver.model.world.WorldObject;
/**
* Event dispatcher once an actor has received/dealt an attack hit.
* <p>
* Please note that the same event is dispatched for both attacker and attackee.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class ActorAttackHitEvent implements ActorEvent {
/**
* The spawned player
*/
private final AttackHit hit;
/**
* Creates a new instance
*
* @param hit
* the attack hit
*/
public ActorAttackHitEvent(AttackHit hit) {
this.hit = hit;
}
@Override
public WorldObject getObject() {
return hit.getAttacker();
}
@Override
public Actor getActor() {
return hit.getAttacker();
}
/**
* @return the attack hit
*/
public AttackHit getHit() {
return hit;
}
@Override
public ObjectID<?>[] getDispatchableObjects() {
return new ObjectID<?>[] { hit.getAttacker().getID() };
}
}

View File

@@ -32,7 +32,7 @@ import com.l2jserver.model.world.actor.calculator.PhysicalCriticalRateBonusCalcu
import com.l2jserver.model.world.actor.calculator.PhysicalDefenseBonusCalculator;
import com.l2jserver.model.world.actor.calculator.RunSpeedBonusCalculator;
import com.l2jserver.model.world.actor.calculator.WalkSpeedBonusCalculator;
import com.l2jserver.util.calculator.Calculator;
import com.l2jserver.util.calculator.SimpleCalculator;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
@@ -152,12 +152,12 @@ public abstract class ActorStats<T extends ActorCalculatorContext> {
* speed gain is much higher.
*/
@SuppressWarnings("unchecked")
private final Calculator<T>[] calculators = new Calculator[StatType
private final SimpleCalculator<T>[] calculators = new SimpleCalculator[StatType
.values().length];
public ActorStats() {
for (int i = 0; i < calculators.length; i++) {
calculators[i] = new Calculator<T>();
calculators[i] = new SimpleCalculator<T>();
}
// bonuses
@@ -334,7 +334,7 @@ public abstract class ActorStats<T extends ActorCalculatorContext> {
* calculator {@link StatType}
* @return the calculator object associated with the given <tt>type</tt>
*/
protected Calculator<T> getCalculator(StatType type) {
protected SimpleCalculator<T> getCalculator(StatType type) {
return calculators[type.ordinal()];
}
@@ -350,5 +350,9 @@ public abstract class ActorStats<T extends ActorCalculatorContext> {
return getCalculator(type).calculate(ctx);
}
public void updateCalculators() {
}
protected abstract T createContext();
}

View File

@@ -19,6 +19,7 @@ package com.l2jserver.model.world.character;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.actor.stat.ActorStats;
import com.l2jserver.model.world.actor.stat.StatType;
import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll;
import com.l2jserver.model.world.character.calculator.CharacterCalculator;
import com.l2jserver.model.world.character.calculator.CharacterCalculatorContext;
import com.l2jserver.model.world.character.calculator.MaximumCPAddCalculator;
@@ -46,17 +47,17 @@ import com.l2jserver.model.world.character.calculator.base.CharacterBaseRunSpeed
import com.l2jserver.model.world.character.calculator.base.CharacterBaseStrengthCalculator;
import com.l2jserver.model.world.character.calculator.base.CharacterBaseWalkSpeedCalculator;
import com.l2jserver.model.world.character.calculator.base.CharacterBaseWitnessCalculator;
import com.l2jserver.util.calculator.Calculator;
import com.l2jserver.util.calculator.SimpleCalculator;
/**
* This class is responsible for calculating the real character stats. The real
* stats vary from the values from the templates, also, skills and items
* equipped can change those values. Once an buff is applied, a new calculator
* is {@link Calculator#importFunctions(Calculator) imported} and their
* functions are added to this class calculator. Once the skill effect has past
* away, all the functions that were imported are now
* {@link Calculator#removeFunctions(Calculator) removed} and the calculator
* return to its original state.
* is {@link SimpleCalculator#importFunctions(SimpleCalculator) imported} and
* their functions are added to this class calculator. Once the skill effect has
* past away, all the functions that were imported are now
* {@link SimpleCalculator#removeFunctions(SimpleCalculator) removed} and the
* calculator return to its original state.
* <p>
* Another important note is that calculators should perform calculations as
* fast as possible.
@@ -219,7 +220,7 @@ public class CharacterStats extends ActorStats<CharacterCalculatorContext> {
* shared.</u>
*/
private static final CharacterCalculator BASE_ATTACK_EVASION_CALCULATOR = new CharacterBaseAttackEvasionCalculator();
// BONUS
/**
* The calculator for CP bonus
@@ -228,7 +229,7 @@ public class CharacterStats extends ActorStats<CharacterCalculatorContext> {
* shared.</u>
*/
private static final CharacterCalculator CP_BONUS_CALCULATOR = new MaximumCPBonusCalculator();
// ADD
/**
* The calculator for HP add
@@ -299,10 +300,10 @@ public class CharacterStats extends ActorStats<CharacterCalculatorContext> {
add(StatType.MAX_HP, HP_ADD_CALCULATOR);
add(StatType.MAX_MP, MP_ADD_CALCULATOR);
add(StatType.MAX_CP, CP_ADD_CALCULATOR);
// bonus
add(StatType.MAX_CP, CP_BONUS_CALCULATOR);
// TODO henna stats calculators
}
@@ -320,6 +321,17 @@ public class CharacterStats extends ActorStats<CharacterCalculatorContext> {
return (int) calc(StatType.MAX_LOAD);
}
@Override
public void updateCalculators() {
super.updateCalculators();
if (character.getInventory().has(InventoryPaperdoll.RIGHT_HAND)) {
add(StatType.POWER_ATTACK,
character.getInventory()
.getItem(InventoryPaperdoll.RIGHT_HAND)
.getTemplateID().getTemplate().getPhysicalDamage());
}
}
@Override
protected CharacterCalculatorContext createContext() {
return new CharacterCalculatorContext(character);

View File

@@ -21,7 +21,6 @@ import com.l2jserver.model.world.actor.stat.ActorStats;
import com.l2jserver.model.world.actor.stat.StatType;
import com.l2jserver.model.world.npc.calculator.NPCCalculator;
import com.l2jserver.model.world.npc.calculator.NPCCalculatorContext;
import com.l2jserver.model.world.npc.calculator.base.NPCBaseAttackAccuracyCalculator;
import com.l2jserver.model.world.npc.calculator.base.NPCBaseAttackEvasionCalculator;
import com.l2jserver.model.world.npc.calculator.base.NPCBaseConcentrationCalculator;
import com.l2jserver.model.world.npc.calculator.base.NPCBaseDexterityCalculator;
@@ -41,16 +40,16 @@ import com.l2jserver.model.world.npc.calculator.base.NPCBaseRunSpeedCalculator;
import com.l2jserver.model.world.npc.calculator.base.NPCBaseStrengthCalculator;
import com.l2jserver.model.world.npc.calculator.base.NPCBaseWalkSpeedCalculator;
import com.l2jserver.model.world.npc.calculator.base.NPCBaseWitnessCalculator;
import com.l2jserver.util.calculator.Calculator;
import com.l2jserver.util.calculator.SimpleCalculator;
/**
* This class is responsible for calculating the real NPC stats. The real stats
* vary from the values from the templates, also, skills and items equipped can
* change those values. Once an buff is applied, a new calculator is
* {@link Calculator#importFunctions(Calculator) imported} and their functions
* {@link SimpleCalculator#importFunctions(SimpleCalculator) imported} and their functions
* are added to this class calculator. Once the skill effect has past away, all
* the functions that were imported are now
* {@link Calculator#removeFunctions(Calculator) removed} and the calculator
* {@link SimpleCalculator#removeFunctions(SimpleCalculator) removed} and the calculator
* return to its original state.
* <p>
* Another important note is that calculators should perform calculations as
@@ -192,13 +191,6 @@ public class NPCStats extends ActorStats<NPCCalculatorContext> {
*/
private static final NPCCalculator BASE_MAGICAL_DEFENSE_CALCULATOR = new NPCBaseMagicalDefenseCalculator();
/**
* The calculator base attack accuracy
* <p>
* <u>This calculator does not store any state and thus is safe to be
* shared.</u>
*/
private static final NPCCalculator BASE_ATTACK_ACCURACY_CALCULATOR = new NPCBaseAttackAccuracyCalculator();
/**
* The calculator base evasion
* <p>
@@ -245,7 +237,6 @@ public class NPCStats extends ActorStats<NPCCalculatorContext> {
add(StatType.MCRITICAL_RATE, BASE_MAGICAL_CRITICAL_RATE_CALCULATOR);
add(StatType.MAGIC_DEFENSE, BASE_MAGICAL_DEFENSE_CALCULATOR);
add(StatType.ACCURACY_COMBAT, BASE_ATTACK_ACCURACY_CALCULATOR);
add(StatType.EVASION_RATE, BASE_ATTACK_EVASION_CALCULATOR);
}