Рейтинг темы:
  • 0 Голос(ов) - 0 в среднем
  • 1
  • 2
  • 3
  • 4
  • 5
Помогите с компилом
#1
Помогите скомпилить файл .java в .class! Заранее очень благодарен!
[spoiler=Creature.java]/* */ package devworld.gameserver.model;
/* */
/* */ import devworld.commons.lang.reference.HardReference;
/* */ import devworld.commons.listener.Listener;
/* */ import devworld.commons.threading.RunnableImpl;
/* */ import devworld.commons.util.concurrent.atomic.AtomicState;
/* */ import devworld.gameserver.ai.CharacterAI;
/* */ import devworld.gameserver.ai.CtrlEvent;
/* */ import devworld.gameserver.model.actor.listener.CharListenerList;
/* */ import devworld.gameserver.model.actor.recorder.CharStatsChangeRecorder;
/* */ import devworld.gameserver.model.base.InvisibleType;
/* */ import devworld.gameserver.model.base.TeamType;
/* */ import devworld.gameserver.model.entity.Reflection;
/* */ import devworld.gameserver.model.instances.MonsterInstance;
/* */ import devworld.gameserver.model.instances.NpcInstance;
/* */ import devworld.gameserver.model.items.ItemInstance;
/* */ import devworld.gameserver.model.pledge.Clan;
/* */ import devworld.gameserver.serverpackets.AbnormalStatusUpdate;
/* */ import devworld.gameserver.serverpackets.Attack;
/* */ import devworld.gameserver.serverpackets.ExAbnormalStatusUpdateFromTargetPacket;
/* */ import devworld.gameserver.serverpackets.FlyToLocation.FlyType;
/* */ import devworld.gameserver.serverpackets.L2GameServerPacket;
/* */ import devworld.gameserver.serverpackets.StatusUpdate;
/* */ import devworld.gameserver.serverpackets.components.CustomMessage;
/* */ import devworld.gameserver.serverpackets.components.IStaticPacket;
/* */ import devworld.gameserver.skills.AbnormalEffect;
/* */ import devworld.gameserver.skills.TimeStamp;
/* */ import devworld.gameserver.stats.Calculator;
/* */ import devworld.gameserver.stats.Env;
/* */ import devworld.gameserver.stats.Formulas.AttackInfo;
/* */ import devworld.gameserver.stats.StatTemplate;
/* */ import devworld.gameserver.stats.Stats;
/* */ import devworld.gameserver.stats.funcs.Func;
/* */ import devworld.gameserver.stats.triggers.TriggerInfo;
/* */ import devworld.gameserver.stats.triggers.TriggerType;
/* */ import devworld.gameserver.templates.CharTemplate;
/* */ import devworld.gameserver.templates.item.WeaponTemplate;
/* */ import devworld.gameserver.templates.item.WeaponTemplate.WeaponType;
/* */ import devworld.gameserver.templates.spawn.WalkerRouteTemplate;
/* */ import devworld.gameserver.utils.Location;
/* */ import gnu.trove.set.hash.TIntHashSet;
/* */ import java.util.Collection;
/* */ import java.util.Iterator;
/* */ import java.util.List;
/* */ import java.util.Map;
/* */ import java.util.Set;
/* */ import java.util.concurrent.Future;
/* */ import java.util.concurrent.atomic.AtomicBoolean;
/* */ import java.util.concurrent.locks.Lock;
/* */ import java.util.concurrent.locks.ReadWriteLock;
/* */ import org.napile.primitive.maps.IntObjectMap;
/* */ import org.slf4j.Logger;
/* */ import org.slf4j.LoggerFactory;
/* */
public abstract class Creature extends GameObject {
public class MoveNextTask extends RunnableImpl {
private double alldist, donedist;

public MoveNextTask setDist(double dist) {
alldist = dist;
donedist = 0.;
return this;
}

@Override
public void runImpl() throws Exception {
if (!isMoving)
return;

moveLock.lock();
try {
if (!isMoving)
return;

if (isMovementDisabled()) {
stopMove();
return;
}

Creature follow = null;
int speed = getMoveSpeed();
if (speed <= 0) {
stopMove();
return;
}
long now = System.currentTimeMillis();

if (isFollow) {
follow = getFollowTarget();
if (follow == null) {
stopMove();
return;
}
if (isInRangeZ(follow, _offset) && GeoEngine.canSeeTarget(Creature.this, follow, false)) {
stopMove();
ThreadPoolManager.getInstance().execute(new NotifyAITask(Creature.this, CtrlEvent.EVT_ARRIVED_TARGET));
return;
}
}

if (alldist <= 0) {
moveNext(false);
return;
}

donedist += (now - _startMoveTime) * _previousSpeed / 1000.;
double done = donedist / alldist;

if (done < 0)
done = 0;
if (done >= 1) {
moveNext(false);
return;
}

if (isMovementDisabled()) {
stopMove();
return;
}

Location loc = null;

int index = (int) (moveList.size() * done);
if (index >= moveList.size())
index = moveList.size() - 1;
if (index < 0)
index = 0;

loc = moveList.get(index).clone().geo2world();

if (!isFlying() && !isInBoat() && !isInWater() && !isBoat())
if (loc.z - getZ() > 256) {
String bug_text = "geo bug 1 at: " + getLoc() + " => " + loc.x + "," + loc.y + "," + loc.z + "\tAll path: " + moveList.get(0) + " => " + moveList.get(moveList.size() - 1);
Log.add(bug_text, "geo");
stopMove();
return;
}

// Проверяем, на всякий случай
if (loc == null || isMovementDisabled()) {
stopMove();
return;
}

setLoc(loc, true);

// В процессе изменения координат, мы остановились
if (isMovementDisabled()) {
stopMove();
return;
}

if (isFollow && now - _followTimestamp > (_forestalling ? 500 : 1000) && follow != null && !follow.isInRange(movingDestTempPos, Math.max(100, _offset))) {
if (Math.abs(getZ() - loc.z) > 1000 && !isFlying()) {
sendPacket(SystemMsg.CANNOT_SEE_TARGET);
stopMove();
return;
}
if (buildPathTo(follow.getX(), follow.getY(), follow.getZ(), _offset, follow, true, true))
movingDestTempPos.set(follow.getX(), follow.getY(), follow.getZ());
else {
stopMove();
return;
}
moveNext(true);
return;
}

_previousSpeed = speed;
_startMoveTime = now;
_moveTask = ThreadPoolManager.getInstance().schedule(this, getMoveTickInterval());

} catch (Exception e) {
_log.error("", e);
} finally {
moveLock.unlock();
}
}
}

private static final Logger _log = LoggerFactory.getLogger(Creature.class);

public static final double HEADINGS_IN_PI = 10430.378350470452724949566316381;
public static final int INTERACTION_DISTANCE = 200;

private Skill _castingSkill;

private long _castInterruptTime;
private long _animationEndTime;

public int _scheduledCastCount;
public int _scheduledCastInterval;

public Future<?> _skillTask;
public Future<?> _skillLaunchedTask;

public Future<?> _skillDoubleTask;
public Future<?> _skillDoubleLaunchedTask;

private Future<?> _stanceTask;
private Runnable _stanceTaskRunnable;
private long _stanceEndTime;

public final static int CLIENT_BAR_SIZE = 352; // 352 - размер полоски CP/HP/MP в клиенте, в пикселях

private int _lastCpBarUpdate = -1;
private int _lastHpBarUpdate = -1;
private int _lastMpBarUpdate = -1;

protected double _currentCp = 0;
protected double _currentHp = 1;
protected double _currentMp = 1;

private int _abnormalEffects;
private int _abnormalEffects2;
private int _abnormalEffects3;

protected boolean _isAttackAborted;
protected long _attackEndTime;
protected long _attackReuseEndTime;
private int _poleAttackCount = 0;
private static final double[] POLE_VAMPIRIC_MOD = {1, 0.9, 0, 7, 0.2, 0.01};

/**
* HashMap(Integer, L2Skill) containing all skills of the L2Character
*/
protected final Map<Integer, Skill> _skills = new ConcurrentSkipListMap<Integer, Skill>();
protected Map<TriggerType, Set<TriggerInfo>> _triggers;

protected final IntObjectMap<TimeStamp> _skillReuses = new CHashIntObjectMap<TimeStamp>();

protected volatile EffectList _effectList;

protected volatile CharStatsChangeRecorder<? extends Creature> _statsRecorder;

private List<Stats> _blockedStats;

protected AtomicBoolean isDead = new AtomicBoolean();
protected AtomicBoolean isTeleporting = new AtomicBoolean();

private Map<Integer, Integer> _skillMastery;

protected boolean _isInvul;

private boolean _fakeDeath;
private boolean _isBlessedByNoblesse; // Восстанавливает все бафы после смерти
private boolean _isSalvation; // Восстанавливает все бафы после смерти и полностью CP, MP, HP

private boolean _meditated;
private boolean _lockedTarget;

private boolean _blocked;

private AtomicState _afraid = new AtomicState();
private AtomicState _muted = new AtomicState();
private AtomicState _pmuted = new AtomicState();
private AtomicState _amuted = new AtomicState();
private AtomicState _paralyzed = new AtomicState();
private AtomicState _rooted = new AtomicState();
private AtomicState _sleeping = new AtomicState();
private AtomicState _stunned = new AtomicState();
private AtomicState _immobilized = new AtomicState();
private AtomicState _confused = new AtomicState();
private AtomicState _frozen = new AtomicState();

private AtomicState _healBlocked = new AtomicState();
private AtomicState _damageBlocked = new AtomicState();
private AtomicState _buffImmunity = new AtomicState(); // Иммунитет к бафам
private AtomicState _debuffImmunity = new AtomicState(); // Иммунитет к дебафам
private AtomicState _effectImmunity = new AtomicState(); // Иммунитет ко всем эффектам

private AtomicState _weaponEquipBlocked = new AtomicState();

private boolean _flying;

private boolean _running;

public boolean isMoving;
public boolean isFollow;
private final Lock moveLock = new ReentrantLock();
private Future<?> _moveTask;
private MoveNextTask _moveTaskRunnable;
private List<Location> moveList;
private Location destination;
/**
* при moveToLocation используется для хранения геокоординат в которые мы двигаемся для того что бы избежать повторного построения одного и того же пути
* при followToCharacter используется для хранения мировых координат в которых находилась последний раз преследуемая цель для отслеживания необходимости перестраивания пути
*/
private final Location movingDestTempPos = new Location();
private int _offset;

private boolean _forestalling;

private volatile HardReference<? extends GameObject> target = HardReferences.emptyRef();
private volatile HardReference<? extends Creature> castingTarget = HardReferences.emptyRef();
private volatile HardReference<? extends Creature> followTarget = HardReferences.emptyRef();
private volatile HardReference<? extends Creature> _aggressionTarget = HardReferences.emptyRef();

private final List<List<Location>> _targetRecorder = new ArrayList<List<Location>>();
private long _followTimestamp, _startMoveTime;
private int _previousSpeed = 0;

private int _heading;

private final Calculator[] _calculators;

protected CharTemplate _template;

protected volatile CharacterAI _ai;

protected String _name;
protected String _title;
protected TeamType _team = TeamType.NONE;

private boolean _isRegenerating;
private final Lock regenLock = new ReentrantLock();
private Future<?> _regenTask;
private Runnable _regenTaskRunnable;


public boolean _isEnabledDoubleCast = false;


private List<Zone> _zones = new LazyArrayList<Zone>();
/**
* Блокировка для чтения/записи объектов из региона
*/
private final ReadWriteLock zonesLock = new ReentrantReadWriteLock();
private final Lock zonesRead = zonesLock.readLock();
private final Lock zonesWrite = zonesLock.writeLock();

protected volatile CharListenerList listeners;

/**
* If true, creature cannot dye - his HP is always will be under 1.
*/
protected boolean _deathImmune = false;

/**
* Список игроков, которым необходимо отсылать информацию об изменении состояния персонажа
*/
private List<Player> _statusListeners;
private final Lock statusListenersLock = new ReentrantLock();
protected WalkerRouteTemplate _walkerRoutesTemplate = null;

protected Long _storedId;

public final Long getStoredId() {
return _storedId;
}

protected HardReference<? extends Creature> reference;

/**
* Трансформ теперь можно наложить на все креатуры
*/
private int _transformationId;
private int _transformationTemplate;
private String _transformationName;
public Creature(int objectId, CharTemplate template) {
super(objectId);

_template = template;

_calculators = new Calculator[Stats.NUM_STATS];

StatFunctions.addPredefinedFuncs(this);

reference = new L2Reference<Creature>(this);

_storedId = GameObjectsStorage.put(this);
}

@Override
public HardReference<? extends Creature> getRef() {
return reference;
}

public boolean isAttackAborted() {
return _isAttackAborted;
}

public final void abortAttack(boolean force, boolean message) {
if (isAttackingNow()) {
_attackEndTime = 0;
if (force)
_isAttackAborted = true;

getAI().setIntention(AI_INTENTION_ACTIVE);

if (isPlayer() && message) {
sendActionFailed();
sendPacket(new SystemMessage(SystemMessage.C1S_ATTACK_FAILED).addName(this));
}
}
}

public final void abortCast(boolean force, boolean message) {
if (isCastingNow() && (force || canAbortCast())) {
final Skill castingSkill = _castingSkill;
final Future<?> skillTask = _skillTask;
final Future<?> skillLaunchedTask = _skillLaunchedTask;
final Future<?> skillDoubleTask = _skillDoubleTask;
final Future<?> skillDoubleLaunchedTask = _skillDoubleLaunchedTask;

finishFly(); // Броадкаст пакета FlyToLoc уже выполнен, устанавливаем координаты чтобы не было визуальных глюков
clearCastVars();

if (skillTask != null)
skillTask.cancel(false); // cancels the skill hit scheduled task

if (skillLaunchedTask != null)
skillLaunchedTask.cancel(false); // cancels the skill hit scheduled task

if (skillDoubleTask != null)
skillDoubleTask.cancel(false); // cancels the skill hit scheduled task

if (skillDoubleLaunchedTask != null)
skillDoubleLaunchedTask.cancel(false); // cancels the skill hit scheduled task

if (castingSkill != null) {
if (castingSkill.isUsingWhileCasting()) {
Creature target = getAI().getAttackTarget();
if (target != null)
target.getEffectList().stopEffect(castingSkill.getId());
}

removeSkillMastery(castingSkill.getId());
}

broadcastPacket(new MagicSkillCanceled(getObjectId())); // broadcast packet to stop animations client-side

getAI().setIntention(AI_INTENTION_ACTIVE);

if (isPlayer() && message)
sendPacket(Msg.CASTING_HAS_BEEN_INTERRUPTED);
}
}

public final boolean canAbortCast() {
return _castInterruptTime > System.currentTimeMillis();
}

public boolean absorbAndReflect(Creature target, Skill skill, double damage) {
if (target.isDead())
return false;

boolean bow = getActiveWeaponItem() != null && (getActiveWeaponItem().getItemType() == WeaponType.BOW || getActiveWeaponItem().getItemType() == WeaponType.CROSSBOW);

double value = 0;

if (skill != null && skill.isMagic())
value = target.calcStat(Stats.REFLECT_AND_BLOCK_MSKILL_DAMAGE_CHANCE, 0, this, skill);
else if (skill != null && skill.getCastRange() <= 200)
value = target.calcStat(Stats.REFLECT_AND_BLOCK_PSKILL_DAMAGE_CHANCE, 0, this, skill);
else if (skill == null && !bow)
value = target.calcStat(Stats.REFLECT_AND_BLOCK_DAMAGE_CHANCE, 0, this, null);

//Цель отразила весь урон
if (value > 0 && Rnd.chance(value)) {
reduceCurrentHp(damage, 0, target, null, true, true, false, false, false, false, true);
return true;
}

if (skill != null && skill.isMagic())
value = target.calcStat(Stats.REFLECT_MSKILL_DAMAGE_PERCENT, 0, this, skill);
else if (skill != null && skill.getCastRange() <= 200)
value = target.calcStat(Stats.REFLECT_PSKILL_DAMAGE_PERCENT, 0, this, skill);
else if (skill == null && !bow)
value = target.calcStat(Stats.REFLECT_DAMAGE_PERCENT, 0, this, null);

if (value > 0) {
//Цель в состоянии отразить часть урона
if (target.getCurrentHp() + target.getCurrentCp() > damage)
reduceCurrentHp(value / 100. * damage, 0, target, null, true, true, false, false, false, false, true);
}

if (skill != null || bow)
return false;

// вампирик
damage = (int) (damage - target.getCurrentCp());

if (damage <= 0)
return false;

final double poleMod = _poleAttackCount < POLE_VAMPIRIC_MOD.length ? POLE_VAMPIRIC_MOD[_poleAttackCount] : 0;
double absorb = poleMod * calcStat(Stats.ABSORB_DAMAGE_PERCENT, 0, target, null);
double limit;
if (absorb > 0 && !target.isDamageBlocked()) {
limit = calcStat(Stats.HP_LIMIT, null, null) * getMaxHp() / 100.;
if (getCurrentHp() < limit)
setCurrentHp(Math.min(_currentHp + damage * absorb * Config.ALT_ABSORB_DAMAGE_MODIFIER / 100., limit), false);
}

absorb = poleMod * calcStat(Stats.ABSORB_DAMAGEMP_PERCENT, 0, target, null);
if (absorb > 0 && !target.isDamageBlocked()) {
limit = calcStat(Stats.MP_LIMIT, null, null) * getMaxMp() / 100.;
if (getCurrentMp() < limit)
setCurrentMp(Math.min(_currentMp + damage * absorb * Config.ALT_ABSORB_DAMAGE_MODIFIER / 100., limit));
}

return false;
}

public double absorbToEffector(Creature attacker, double damage) {
double transferToEffectorDam = calcStat(Stats.TRANSFER_TO_EFFECTOR_DAMAGE_PERCENT, 0.);
if (transferToEffectorDam > 0) {
Effect effect = getEffectList().getEffectByType(EffectType.AbsorbDamageToEffector);
if (effect == null)
return damage;

Creature effector = effect.getEffector();
// на мертвого чара, не онлайн игрока - не даем абсорб, и не на самого себя
if (effector == this || effector.isDead() || !isInRange(effector, 1200))
return damage;

Player thisPlayer = getPlayer();
Player effectorPlayer = effector.getPlayer();
if (thisPlayer != null && effectorPlayer != null) {
if (thisPlayer != effectorPlayer && (!thisPlayer.isOnline() || !thisPlayer.isInParty() || thisPlayer.getParty() != effectorPlayer.getParty()))
return damage;
} else
return damage;

double transferDamage = (damage * transferToEffectorDam) * .01;
damage -= transferDamage;

effector.reduceCurrentHp(transferDamage, 0, effector, null, false, false, !attacker.isPlayable(), false, true, false, true);
}
return damage;
}

public double absorbToMp(Creature attacker, double damage) {
double transferToMpDamPercent = calcStat(Stats.TRANSFER_TO_MP_DAMAGE_PERCENT, 0.);
if (transferToMpDamPercent > 0) {
double transferDamage = (damage * transferToMpDamPercent) * .01;

double currentMp = getCurrentMp();
if (currentMp > transferDamage) {
setCurrentMp(getCurrentMp() - transferDamage);
return 0;
} else {
if (currentMp > 0) {
damage -= currentMp;
setCurrentMp(0);
sendPacket(SystemMsg.MP_BECAME_0_AND_THE_ARCANE_SHIELD_IS_DISAPPEARING);
}
getEffectList().stopEffects(EffectType.AbsorbDamageToMp);
}

return damage;
}
return damage;
}

public double absorbToSummon(Creature attacker, double damage) {
if (!isPlayer())
return damage;
double transferToSummonDam = calcStat(Stats.TRANSFER_TO_SUMMON_DAMAGE_PERCENT, 0.);
if (transferToSummonDam > 0) {
List<Summon> servitors = ((Player) this).getSummonList().getServitors();
double transferDamage = (damage * transferToSummonDam) * .01;
for (Iterator<Summon> it = servitors.iterator(); it.hasNext(); ) {
Summon summon = it.next();
if (summon == null || summon.isDead() || summon.getCurrentHp() < transferDamage / servitors.size()) {
it.remove();
}
}
if (servitors.size() > 0) {
for (Summon summon : servitors) {
if (summon.isInRangeZ(this, 1200)) {
damage -= transferDamage;
summon.reduceCurrentHp(transferDamage, 0, summon, null, false, false, false, false, true, false, true);
}
}
} else {
getEffectList().stopEffects(EffectType.AbsorbDamageToSummon);
return damage;
}
}
return damage;
}

public void addBlockStats(List<Stats> stats) {
if (_blockedStats == null)
_blockedStats = new ArrayList<Stats>();
_blockedStats.addAll(stats);
}

public Skill addSkill(Skill newSkill) {
if (newSkill == null)
return null;

Skill oldSkill = _skills.get(newSkill.getId());

if (oldSkill != null && oldSkill.getLevel() == newSkill.getLevel())
return newSkill;

// Replace oldSkill by newSkill or Add the newSkill
_skills.put(newSkill.getId(), newSkill);

if (oldSkill != null) {
removeStatsOwner(oldSkill);
removeTriggers(oldSkill);
}

addTriggers(newSkill);

// Add Func objects of newSkill to the calculator set of the L2Character
addStatFuncs(newSkill.getStatFuncs());

return oldSkill;
}

public Calculator[] getCalculators() {
return _calculators;
}

public final void addStatFunc(Func f) {
if (f == null)
return;
int stat = f.stat.ordinal();
synchronized (_calculators) {
if (_calculators[stat] == null)
_calculators[stat] = new Calculator(f.stat, this);
_calculators[stat].addFunc(f);
}
}

public final void addStatFuncs(Func[] funcs) {
for (Func f : funcs)
addStatFunc(f);
}

public final void removeStatFunc(Func f) {
if (f == null)
return;
int stat = f.stat.ordinal();
synchronized (_calculators) {
if (_calculators[stat] != null)
_calculators[stat].removeFunc(f);
}
}

public final void removeStatFuncs(Func[] funcs) {
for (Func f : funcs)
removeStatFunc(f);
}

public final void removeStatsOwner(Object owner) {
synchronized (_calculators) {
for (int i = 0; i < _calculators.length; i++)
if (_calculators[i] != null)
_calculators[i].removeOwner(owner);
}
}

public void altOnMagicUseTimer(Creature aimingTarget, Skill skill) {
if (isAlikeDead())
return;
int magicId = skill.getDisplayId();
int level = Math.max(1, getSkillDisplayLevel(skill.getId()));
List<Creature> targets = skill.getTargets(this, aimingTarget, true);
broadcastPacket(new MagicSkillLaunched(getObjectId(), magicId, level, targets));
double mpConsume2 = skill.getMpConsume2();
if (mpConsume2 > 0) {
if (_currentMp < mpConsume2) {
sendPacket(Msg.NOT_ENOUGH_MP);
return;
}
if (skill.isMagic())
reduceCurrentMp(calcStat(Stats.MP_MAGIC_SKILL_CONSUME, mpConsume2, aimingTarget, skill), null);
else
reduceCurrentMp(calcStat(Stats.MP_PHYSICAL_SKILL_CONSUME, mpConsume2, aimingTarget, skill), null);
}
callSkill(skill, targets, false);
}

public void altUseSkill(Skill skill, Creature target) {
if (skill == null)
return;
int magicId = skill.getId();
if (isUnActiveSkill(magicId))
return;
if (isSkillDisabled(skill)) {
sendReuseMessage(skill);
return;
}
if (target == null) {
target = skill.getAimingTarget(this, getTarget());
if (target == null)
return;
}

getListeners().onMagicUse(skill, target, true);

int itemConsume[] = skill.getItemConsume();

if (itemConsume[0] > 0)
for (int i = 0; i < itemConsume.length; i++)
if (!consumeItem(skill.getItemConsumeId()[i], itemConsume[i])) {
sendPacket(skill.isHandler() ? SystemMsg.INCORRECT_ITEM_COUNT : SystemMsg.THERE_ARE_NOT_ENOUGH_NECESSARY_ITEMS_TO_USE_THE_SKILL);
return;
}

if (skill.getReferenceItemId() > 0)
if (!consumeItemMp(skill.getReferenceItemId(), skill.getReferenceItemMpConsume()))
return;

if (skill.getSoulsConsume() > getConsumedSouls()) {
sendPacket(Msg.THERE_IS_NOT_ENOUGHT_SOUL);
return;
}

if (skill.getEnergyConsume() > getAgathionEnergy()) {
sendPacket(SystemMsg.THE_SKILL_HAS_BEEN_CANCELED_BECAUSE_YOU_HAVE_INSUFFICIENT_ENERGY);
return;
}

if (skill.getSoulsConsume() > 0)
setConsumedSouls(getConsumedSouls() - skill.getSoulsConsume(), null);
if (skill.getEnergyConsume() > 0)
setAgathionEnergy(getAgathionEnergy() - skill.getEnergyConsume());

int level = Math.max(1, getSkillDisplayLevel(magicId));
Formulas.calcSkillMastery(skill, this);
long reuseDelay = Formulas.calcSkillReuseDelay(this, skill);
if (!skill.isToggle())
broadcastPacket(new MagicSkillUse(this, target, skill.getDisplayId(), level, skill.getHitTime(), reuseDelay));
// Не показывать сообщение для хербов и кубиков
if (!skill.isHideUseMessage())
if (skill.getSkillType() == SkillType.PET_SUMMON)
sendPacket(new SystemMessage(SystemMessage.SUMMON_A_PET));
else if (!skill.isHandler())
sendPacket(new SystemMessage(SystemMessage.YOU_USE_S1).addSkillName(magicId, level));
else
sendPacket(new SystemMessage(SystemMessage.YOU_USE_S1).addItemName(skill.getItemConsumeId()[0]));

if (!skill.isHandler())
disableSkill(skill, reuseDelay);

ThreadPoolManager.getInstance().schedule(new AltMagicUseTask(this, target, skill), skill.getHitTime());
}

public void sendReuseMessage(Skill skill) {
}

public void broadcastPacket(L2GameServerPacket... packets) {
sendPacket(packets);
broadcastPacketToOthers(packets);
}

public void broadcastPacket(List<L2GameServerPacket> packets) {
sendPacket(packets);
broadcastPacketToOthers(packets);
}

public void broadcastPacketToOthers(L2GameServerPacket... packets) {
if (!isVisible() || packets.length == 0)
return;

List<Player> players = World.getAroundPlayers(this);
Player target;
for (int i = 0; i < players.size(); i++) {
target = players.get(i);
target.sendPacket(packets);
}
}

public void broadcastPacketToOthers(List<L2GameServerPacket> packets) {
if (!isVisible() || packets.isEmpty())
return;

List<Player> players = World.getAroundPlayers(this);
Player target;
for (int i = 0; i < players.size(); i++) {
target = players.get(i);
target.sendPacket(packets);
}
}

public void broadcastToStatusListeners(L2GameServerPacket... packets) {
if (!isVisible() || packets.length == 0)
return;

statusListenersLock.lock();
try {
if (_statusListeners == null || _statusListeners.isEmpty())
return;

Player player;
for (int i = 0; i < _statusListeners.size(); i++) {
player = _statusListeners.get(i);
player.sendPacket(packets);
}
} finally {
statusListenersLock.unlock();
}
}

public void addStatusListener(Player cha) {
if (cha == this)
return;

statusListenersLock.lock();
try {
if (_statusListeners == null)
_statusListeners = new LazyArrayList<Player>();
if (!_statusListeners.contains(cha))
_statusListeners.add(cha);
} finally {
statusListenersLock.unlock();
}
}

public void removeStatusListener(Creature cha) {
statusListenersLock.lock();
try {
if (_statusListeners == null)
return;
_statusListeners.remove(cha);
} finally {
statusListenersLock.unlock();
}
}

public void clearStatusListeners() {
statusListenersLock.lock();
try {
if (_statusListeners == null)
return;
_statusListeners.clear();
} finally {
statusListenersLock.unlock();
}
}

public StatusUpdate makeStatusUpdate(int... fields) {
StatusUpdate su = new StatusUpdate(getObjectId());
for (int field : fields)
switch (field) {
case StatusUpdate.CUR_HP:
su.addAttribute(field, (int) getCurrentHp());
break;
case StatusUpdate.MAX_HP:
su.addAttribute(field, getMaxHp());
break;
case StatusUpdate.CUR_MP:
su.addAttribute(field, (int) getCurrentMp());
break;
case StatusUpdate.MAX_MP:
su.addAttribute(field, getMaxMp());
break;
case StatusUpdate.KARMA:
su.addAttribute(field, getKarma());
break;
case StatusUpdate.CUR_CP:
su.addAttribute(field, (int) getCurrentCp());
break;
case StatusUpdate.MAX_CP:
su.addAttribute(field, getMaxCp());
break;
case StatusUpdate.PVP_FLAG:
su.addAttribute(field, getPvpFlag());
break;
}
return su;
}

public StatusUpdate makeHPStatusUpdate(int _attakerId) {
StatusUpdate su = new StatusUpdate(getObjectId(), _attakerId);
su.addAttribute(StatusUpdate.CUR_HP, (int) getCurrentHp());
su.addAttribute(StatusUpdate.CUR_CP, (int) getCurrentCp());
su.addAttribute(StatusUpdate.MAX_HP, getMaxHp());
return su;
}

public void broadcastStatusUpdate() {
if (!needStatusUpdate())
return;

StatusUpdate su = makeStatusUpdate(StatusUpdate.MAX_HP, StatusUpdate.MAX_MP, StatusUpdate.CUR_HP, StatusUpdate.CUR_MP);
broadcastToStatusListeners(su);
}

public void broadcastHPStatusUpdate(int _id) {
if (!needStatusUpdate())
return;

StatusUpdate su = makeHPStatusUpdate(_id);
broadcastToStatusListeners(su);
}

public int calcHeading(int x_dest, int y_dest) {
return (int) (Math.atan2(getY() - y_dest, getX() - x_dest) * HEADINGS_IN_PI) + 32768;
}

public final double calcStat(Stats stat, double init) {
return calcStat(stat, init, null, null);
}

public final double calcStat(Stats stat, double init, Creature target, Skill skill) {
int id = stat.ordinal();
Calculator c = _calculators[id];
if (c == null)
return init;
Env env = new Env();
env.character = this;
env.target = target;
env.skill = skill;
env.value = init;
c.calc(env);
return env.value;
}

public final double calcStat(Stats stat, Creature target, Skill skill) {
Env env = new Env(this, target, skill);
env.value = stat.getInit();
int id = stat.ordinal();
Calculator c = _calculators[id];
if (c != null)
c.calc(env);
return env.value;
}

/**
* Return the Attack Speed of the L2Character (delay (in milliseconds) before next attack).
*/
public int calculateAttackDelay() {
return Formulas.calcPAtkSpd(getPAtkSpd());
}

public void callSkill(Skill skill, List<Creature> targets, boolean useActionSkills) {
try {
if (useActionSkills && !skill.isUsingWhileCasting() && _triggers != null)
if (skill.isOffensive()) {
if (skill.isMagic())
useTriggers(getTarget(), TriggerType.OFFENSIVE_MAGICAL_SKILL_USE, null, skill, 0);
else
useTriggers(getTarget(), TriggerType.OFFENSIVE_PHYSICAL_SKILL_USE, null, skill, 0);
} else if (skill.isMagic()) // для АоЕ, пати/клан бафов и селфов триггер накладывается на кастера
{
final boolean targetSelf = skill.isAoE() || skill.isNotTargetAoE() || skill.getTargetType() == Skill.SkillTargetType.TARGET_SELF;
useTriggers(targetSelf ? this : getTarget(), TriggerType.SUPPORT_MAGICAL_SKILL_USE, null, skill, 0);
}

Player pl = getPlayer();
Creature target;
Iterator<Creature> itr = targets.iterator();
while (itr.hasNext()) {
target = itr.next();

//Фильтруем неуязвимые цели
if (skill.isOffensive() && target.isInvul()) {
Player pcTarget = target.getPlayer();
if ((!skill.isIgnoreInvul() || pcTarget != null && pcTarget.isGM()) && !target.isArtefact()) {
itr.remove();
continue;
}
}
//Рассчитываем игрорируемые скилы из спец.эффекта
Effect ie = target.getEffectList().getEffectByType(EffectType.IgnoreSkill);
if (ie != null)
if (ArrayUtils.contains(ie.getTemplate().getParam().getIntegerArray("skillId"), skill.getId())) {
itr.remove();
continue;
}

target.getListeners().onMagicHit(skill, this);

if (pl != null)
if (target != null && target.isNpc()) {
NpcInstance npc = (NpcInstance) target;
List<QuestState> ql = pl.getQuestsForEvent(npc, QuestEventType.MOB_TARGETED_BY_SKILL, false);
if (ql != null)
for (QuestState qs : ql)
qs.getQuest().notifySkillUse(npc, skill, qs);
}

if (skill.getNegateSkill() > 0)
for (Effect e : target.getEffectList().getAllEffects()) {
Skill efs = e.getSkill();
if (efs.getId() == skill.getNegateSkill() && e.isCancelable() && (skill.getNegatePower() <= 0 || efs.getPower() <= skill.getNegatePower()))
e.exit();
}

if (skill.getCancelTarget() > 0)
if (Rnd.chance(skill.getCancelTarget()))
if ((target.getCastingSkill() == null || !(target.getCastingSkill().getSkillType() == SkillType.TAKECASTLE || target.getCastingSkill().getSkillType() == SkillType.TAKEFORTRESS || target.getCastingSkill().getSkillType() == SkillType.TAKEFLAG)) && !target.isRaid()) {
target.abortAttack(true, true);
target.abortCast(true, true);
target.setTarget(null);
}
}

if (skill.isOffensive())
startAttackStanceTask();

// Применяем селфэффекты на кастера
// Особое условие для атакующих аура-скиллов (Vengeance 368):
// если ни одна цель не задета то селфэффекты не накладываются
if (!(skill.isNotTargetAoE() && skill.isOffensive() && targets.size() == 0))
skill.getEffects(this, this, false, true);

skill.useSkill(this, targets);
} catch (Exception e) {
_log.error("", e);
}
}

public void useTriggers(GameObject target, TriggerType type, Skill ex, Skill owner, double damage) {
if (_triggers == null)
return;

Set<TriggerInfo> SkillsOnSkillAttack = _triggers.get(type);
if (SkillsOnSkillAttack != null)
for (TriggerInfo t : SkillsOnSkillAttack)
if (t.getSkill() != ex)
useTriggerSkill(target == null ? getTarget() : target, null, t, owner, damage);
}

public void useTriggerSkill(GameObject target, List<Creature> targets, TriggerInfo trigger, Skill owner, double damage) {
Skill skill = trigger.getSkill();
if (skill.getReuseDelay() > 0 && isSkillDisabled(skill))
return;

Creature aimTarget = skill.getAimingTarget(this, target);
// DS: Для шансовых скиллов с TARGET_SELF и условием "пвп" сам кастер будет являться aimTarget,
// поэтому в условиях для триггера проверяем реальную цель.
Creature realTarget = target != null && target.isCreature() ? (Creature) target : null;
if (Rnd.chance(trigger.getChance()) && trigger.checkCondition(this, realTarget, aimTarget, owner, damage) && skill.checkCondition(this, aimTarget, false, true, true)) {
if (targets == null)
targets = skill.getTargets(this, aimTarget, false);

int displayId = 0, displayLevel = 0;

if (skill.hasEffects()) {
displayId = skill.getEffectTemplates()[0]._displayId;
displayLevel = skill.getEffectTemplates()[0]._displayLevel;
}

if (displayId == 0)
displayId = skill.getDisplayId();
if (displayLevel == 0)
displayLevel = skill.getDisplayLevel();

if (trigger.getType() != TriggerType.SUPPORT_MAGICAL_SKILL_USE)
for (Creature cha : targets)
broadcastPacket(new MagicSkillUse(this, cha, displayId, displayLevel, 0, 0));

Formulas.calcSkillMastery(skill, this);
callSkill(skill, targets, false);
disableSkill(skill, skill.getReuseDelay());
}
}

public boolean checkBlockedStat(Stats stat) {
return _blockedStats != null && _blockedStats.contains(stat);
}

public boolean checkReflectSkill(Creature attacker, Skill skill) {
if (!skill.isReflectable())
return false;
// Не отражаем, если есть неуязвимость, иначе она может отмениться
if (isInvul() || attacker.isInvul() || !skill.isOffensive())
return false;
// Из магических скилов отражаются только скилы наносящие урон по ХП.
if (skill.isMagic() && skill.getSkillType() != SkillType.MDAM)
return false;
if (Rnd.chance(calcStat(skill.isMagic() ? Stats.REFLECT_MAGIC_SKILL : Stats.REFLECT_PHYSIC_SKILL, 0, attacker, skill))) {
sendPacket(new SystemMessage(SystemMessage.YOU_COUNTERED_C1S_ATTACK).addName(attacker));
attacker.sendPacket(new SystemMessage(SystemMessage.C1_DODGES_THE_ATTACK).addName(this));
return true;
}
return false;
}

public void doCounterAttack(Skill skill, Creature attacker, boolean blow) {
if (isDead()) // если персонаж уже мертв, контратаки быть не должно
return;
if (isDamageBlocked() || attacker.isDamageBlocked()) // Не контратакуем, если есть неуязвимость, иначе она может отмениться
return;
if (skill == null || skill.hasEffects() || skill.isMagic() || !skill.isOffensive() || skill.getCastRange() > 200)
return;
if (Rnd.chance(calcStat(Stats.COUNTER_ATTACK, 0, attacker, skill))) {
double damage = 1189 * getPAtk(attacker) / Math.max(attacker.getPDef(this), 1);
attacker.sendPacket(new SystemMessage(SystemMessage.C1S_IS_PERFORMING_A_COUNTERATTACK).addName(this));
if (blow) // урон х2 для отражения blow скиллов
{
sendPacket(new SystemMessage(SystemMessage.C1S_IS_PERFORMING_A_COUNTERATTACK).addName(this));
sendPacket(new SystemMessage(SystemMessage.C1_HAS_GIVEN_C2_DAMAGE_OF_S3).addName(this).addName(attacker).addNumber((long) damage));
attacker.reduceCurrentHp(damage, damage, this, skill, true, true, false, false, false, false, true);
} else
sendPacket(new SystemMessage(SystemMessage.C1S_IS_PERFORMING_A_COUNTERATTACK).addName(this));
sendPacket(new SystemMessage(SystemMessage.C1_HAS_GIVEN_C2_DAMAGE_OF_S3).addName(this).addName(attacker).addNumber((long) damage));
attacker.reduceCurrentHp(damage, damage, this, skill, true, true, false, false, false, false, true);
}
}

/**
* Disable this skill id for the duration of the delay in milliseconds.
*
* @param skill
* @param delay (seconds * 1000)
*/
public void disableSkill(Skill skill, long delay) {
_skillReuses.put(skill.hashCode(), new TimeStamp(skill, delay));
}

public abstract boolean isAutoAttackable(Creature attacker);

public void doAttack(Creature target) {
if (target == null || isAMuted() || isAttackingNow() || isAlikeDead() || target.isAlikeDead() || !isInRange(target, 2000) || isPlayer() && getPlayer().isInMountTransform())
return;

getListeners().onAttack(target);

// Get the Attack Speed of the L2Character (delay (in milliseconds) before next attack)
int sAtk = Math.max(calculateAttackDelay(), 333);
int ssGrade = 0;

WeaponTemplate weaponItem = getActiveWeaponItem();
if (weaponItem != null) {
if (isPlayer() && weaponItem.getAttackReuseDelay() > 0) {
int reuse = (int) (weaponItem.getAttackReuseDelay() * getReuseModifier(target) * 666 * calcStat(Stats.ATK_BASE, 0, target, null) / 293. / getPAtkSpd());
if (reuse > 0) {
sendPacket(new SetupGauge(this, SetupGauge.RED_MINI, reuse));
_attackReuseEndTime = reuse + System.currentTimeMillis() - 75;
if (reuse > sAtk)
ThreadPoolManager.getInstance().schedule(new NotifyAITask(this, CtrlEvent.EVT_READY_TO_ACT, null, null), reuse);
}
}

ssGrade = weaponItem.getCrystalType().externalOrdinal;
}

// DS: скорректировано на 1/100 секунды поскольку AI task вызывается с небольшой погрешностью
// особенно на слабых машинах и происходит обрыв автоатаки по isAttackingNow() == true
_attackEndTime = sAtk + System.currentTimeMillis() - 10;
_isAttackAborted = false;

Attack attack = new Attack(this, target, getChargedSoulShot(), ssGrade);

setHeading(PositionUtils.calculateHeadingFrom(this, target));

// Select the type of attack to
if (weaponItem == null)
doAttackHitSimple(attack, target, 1., !isPlayer(), sAtk, true);
else
switch (weaponItem.getItemType()) {
case BOW:
case CROSSBOW:
doAttackHitByBow(attack, target, sAtk);
break;
case POLE:
doAttackHitByPole(attack, target, sAtk);
break;
case DUAL:
case DUALFIST:
case DUALDAGGER:
doAttackHitByDual(attack, target, sAtk);
break;
default:
doAttackHitSimple(attack, target, 1., true, sAtk, true);
}

if (attack.hasHits())
broadcastPacket(attack);
}

private void doAttackHitSimple(Attack attack, Creature target, double multiplier, boolean unchargeSS, int sAtk, boolean notify) {
int damage1 = 0, reflectableDamage1 = 0;
boolean shld1 = false;
boolean crit1 = false;
boolean miss1 = Formulas.calcHitMiss(this, target);

if (!miss1) {
AttackInfo info = Formulas.calcPhysDam(this, target, null, false, false, attack._soulshot, false);
damage1 = (int) (info.damage * multiplier);
reflectableDamage1 = (int) (info.reflectableDamage * multiplier);
shld1 = info.shld;
crit1 = info.crit;
}

ThreadPoolManager.getInstance().schedule(new HitTask(this, target, damage1, reflectableDamage1, crit1, miss1, attack._soulshot, shld1, unchargeSS, notify), sAtk);

attack.addHit(target, damage1, miss1, crit1, shld1);
}

private void doAttackHitByBow(Attack attack, Creature target, int sAtk) {
WeaponTemplate activeWeapon = getActiveWeaponItem();
if (activeWeapon == null)
return;

int damage1 = 0, damage2 = 0;
boolean shld1 = false;
boolean crit1 = false;

// Calculate if hit is missed or not
boolean miss1 = Formulas.calcHitMiss(this, target);

reduceArrowCount();

if (!miss1) {
AttackInfo info = Formulas.calcPhysDam(this, target, null, false, false, attack._soulshot, false);
damage1 = (int) info.damage;
damage2 = (int) info.reflectableDamage;
shld1 = info.shld;
crit1 = info.crit;

int range = activeWeapon.getAttackRange();
damage1 *= Math.min(range, getDistance(target)) / range * .4 + 0.8; // разброс 20% в обе стороны
}

ThreadPoolManager.getInstance().schedule(new HitTask(this, target, damage1, damage2, crit1, miss1, attack._soulshot, shld1, true, true), sAtk);

attack.addHit(target, damage2, miss1, crit1, shld1);
}

private void doAttackHitByDual(Attack attack, Creature target, int sAtk) {
int damage1 = 0;
int damage2 = 0;
int reflectableDamage1 = 0, reflectableDamage2 = 0;
boolean shld1 = false;
boolean shld2 = false;
boolean crit1 = false;
boolean crit2 = false;

boolean miss1 = Formulas.calcHitMiss(this, target);
boolean miss2 = Formulas.calcHitMiss(this, target);

if (!miss1) {
AttackInfo info = Formulas.calcPhysDam(this, target, null, true, false, attack._soulshot, false);
damage1 = (int) info.damage;
reflectableDamage1 = (int) info.reflectableDamage;
shld1 = info.shld;
crit1 = info.crit;
}

if (!miss2) {
AttackInfo info = Formulas.calcPhysDam(this, target, null, true, false, attack._soulshot, false);
damage2 = (int) info.damage;
reflectableDamage2 = (int) info.reflectableDamage;
shld2 = info.shld;
crit2 = info.crit;
}

// Create a new hit task with Medium priority for hit 1 and for hit 2 with a higher delay
ThreadPoolManager.getInstance().schedule(new HitTask(this, target, damage1, reflectableDamage1, crit1, miss1, attack._soulshot, shld1, true, false), sAtk / 2);
ThreadPoolManager.getInstance().schedule(new HitTask(this, target, damage2, reflectableDamage2, crit2, miss2, attack._soulshot, shld2, false, true), sAtk);

attack.addHit(target, damage1, miss1, crit1, shld1);
attack.addHit(target, damage2, miss2, crit2, shld2);
}

private void doAttackHitByPole(Attack attack, Creature target, int sAtk) {
int angle = (int) calcStat(Stats.POLE_ATTACK_ANGLE, 90, target, null);
int range = (int) calcStat(Stats.POWER_ATTACK_RANGE, getTemplate().getBaseAtkRange(), target, null);

// Используем Math.round т.к. обычный кастинг обрезает к меньшему
// double d = 2.95. int i = (int)d, выйдет что i = 2
// если 1% угла или 1 дистанции не играет огромной роли, то для
// количества целей это критично
int attackcountmax = (int) Math.round(calcStat(Stats.POLE_TARGET_COUNT, 0, target, null));

if (isBoss())
attackcountmax += 27;
else if (isRaid())
attackcountmax += 12;
else if (isMonster() && getLevel() > 0)
attackcountmax += getLevel() / 7.5;

double mult = 1.;
_poleAttackCount = 1;

if (!isInZonePeace())// Гварды с пикой, будут атаковать только одиночные цели в городе
for (Creature t : getAroundCharacters(range, 200))
if (_poleAttackCount <= attackcountmax) {
if (t == target || t.isDead() || !PositionUtils.isFacing(this, t, angle))
continue;

if (t.isAutoAttackable(this)) {
doAttackHitSimple(attack, t, mult, false, sAtk, false);
mult *= Config.ALT_POLE_DAMAGE_MODIFIER;
_poleAttackCount++;
}
} else
break;

_poleAttackCount = 0;
doAttackHitSimple(attack, target, 1., true, sAtk, true);
}

public long getAnimationEndTime() {
return _animationEndTime;
}

public void doCast(Skill skill, Creature target, boolean forceUse) {
if (skill == null)
return;

int itemConsume[] = skill.getItemConsume();

if (itemConsume[0] > 0)
for (int i = 0; i < itemConsume.length; i++)
if (!consumeItem(skill.getItemConsumeId()[i], itemConsume[i])) {
sendPacket(skill.isHandler() ? SystemMsg.INCORRECT_ITEM_COUNT : SystemMsg.THERE_ARE_NOT_ENOUGH_NECESSARY_ITEMS_TO_USE_THE_SKILL);
return;
}

if (skill.getReferenceItemId() > 0)
if (!consumeItemMp(skill.getReferenceItemId(), skill.getReferenceItemMpConsume()))
return;

int magicId = skill.getId();

if (target == null)
target = skill.getAimingTarget(this, getTarget());
if (target == null)
return;

getListeners().onMagicUse(skill, target, false);

if (this != target)
setHeading(PositionUtils.calculateHeadingFrom(this, target));

int level = Math.max(1, getSkillDisplayLevel(magicId));

int skillTime = skill.isSkillTimePermanent() ? skill.getHitTime() : Formulas.calcMAtkSpd(this, skill, skill.getHitTime());
int skillInterruptTime = skill.isMagic() ? Formulas.calcMAtkSpd(this, skill, skill.getSkillInterruptTime()) : 0;

int minCastTime = Math.min(Config.SKILLS_CAST_TIME_MIN, skill.getHitTime());
if (skillTime < minCastTime) {
skillTime = minCastTime;
skillInterruptTime = 0;
}

_animationEndTime = System.currentTimeMillis() + skillTime;

if (skill.isMagic() && !skill.isSkillTimePermanent() && getChargedSpiritShot() > 0) {
skillTime = (int) (0.70 * skillTime);
skillInterruptTime = (int) (0.70 * skillInterruptTime);
}

Formulas.calcSkillMastery(skill, this); // Calculate skill mastery for current cast
long reuseDelay = Math.max(0, Formulas.calcSkillReuseDelay(this, skill));

broadcastPacket(new MagicSkillUse(this, target, skill.getDisplayId(), level, skillTime, reuseDelay, isDoubleCastingNow()));

if (!skill.isHandler())
disableSkill(skill, reuseDelay);

if (isPlayer())
if (skill.getSkillType() == SkillType.PET_SUMMON)
sendPacket(Msg.SUMMON_A_PET);
else if (!skill.isHandler())
sendPacket(new SystemMessage(SystemMessage.YOU_USE_S1).addSkillName(magicId, level));
else
sendPacket(new SystemMessage(SystemMessage.YOU_USE_S1).addItemName(skill.getItemConsumeId()[0]));

if (skill.getTargetType() == SkillTargetType.TARGET_HOLY)
target.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, this, 1);

double mpConsume1 = skill.isUsingWhileCasting() ? skill.getMpConsume() : skill.getMpConsume1();
if (mpConsume1 > 0) {
if (_currentMp < mpConsume1) {
sendPacket(Msg.NOT_ENOUGH_MP);
onCastEndTime(false);
return;
}
reduceCurrentMp(mpConsume1, null);
}

_flyLoc = null;
switch (skill.getFlyType()) {
case DUMMY:
case CHARGE:
Location flyLoc = getFlyLocation(target, skill);
if (flyLoc != null) {
_flyLoc = flyLoc;
broadcastPacket(new FlyToLocation(this, flyLoc, skill.getFlyType(), 0));
} else {
sendPacket(SystemMsg.CANNOT_SEE_TARGET);
return;
}
}

_castingSkill = skill;
_castInterruptTime = System.currentTimeMillis() + skillInterruptTime;
setCastingTarget(target);

if (skill.isUsingWhileCasting())
callSkill(skill, skill.getTargets(this, target, forceUse), true);

if (isPlayer())
sendPacket(new SetupGauge(this, SetupGauge.BLUE_DUAL, skillTime));

_scheduledCastCount = skill.getCastCount();
_scheduledCastInterval = skill.getCastCount() > 0 ? skillTime / _scheduledCastCount : skillTime;

// Create a task MagicUseTask with Medium priority to launch the MagicSkill at the end of the casting time
if (!isDoubleCastingNow() && IsEnabledDoubleCast())
{
_skillDoubleLaunchedTask = ThreadPoolManager.getInstance().schedule(new MagicLaunchedTask(this, forceUse), skillInterruptTime);
_skillDoubleTask = ThreadPoolManager.getInstance().schedule(new MagicUseTask(this, forceUse), skill.getCastCount() > 0 ? skillTime / skill.getCastCount() : skillTime);

}
else
{
_skillLaunchedTask = ThreadPoolManager.getInstance().schedule(new MagicLaunchedTask(this, forceUse), skillInterruptTime);
_skillTask = ThreadPoolManager.getInstance().schedule(new MagicUseTask(this, forceUse), skill.getCastCount() > 0 ? skillTime / skill.getCastCount() : skillTime);
}

}

private Location _flyLoc;

public Location getFlyLocation(GameObject target, Skill skill) {
if (target != null && target != this) {
Location loc;

double radian = PositionUtils.convertHeadingToRadian(target.getHeading());
if (skill.isFlyToBack())
loc = new Location(target.getX() + (int) (Math.sin(radian) * 40), target.getY() - (int) (Math.cos(radian) * 40), target.getZ());
else
loc = new Location(target.getX() - (int) (Math.sin(radian) * 40), target.getY() + (int) (Math.cos(radian) * 40), target.getZ());

if (isFlying()) {
if (isPlayer() && ((Player) this).isInFlyingTransform() && (loc.z <= 0 || loc.z >= 6000))
return null;
if (GeoEngine.moveCheckInAir(getX(), getY(), getZ(), loc.x, loc.y, loc.z, getColRadius(), getGeoIndex()) == null)
return null;
} else {
loc.correctGeoZ();

if (!GeoEngine.canMoveToCoord(getX(), getY(), getZ(), loc.x, loc.y, loc.z, getGeoIndex())) {
loc = target.getLoc(); // Если не получается встать рядом с объектом, пробуем встать прямо в него
if (!GeoEngine.canMoveToCoord(getX(), getY(), getZ(), loc.x, loc.y, loc.z, getGeoIndex()))
return null;
}
}

return loc;
}

double radian = PositionUtils.convertHeadingToRadian(getHeading());
int x1 = -(int) (Math.sin(radian) * skill.getFlyRadius());
int y1 = (int) (Math.cos(radian) * skill.getFlyRadius());

if (isFlying())
return GeoEngine.moveCheckInAir(getX(), getY(), getZ(), getX() + x1, getY() + y1, getZ(), getColRadius(), getGeoIndex());
return GeoEngine.moveCheck(getX(), getY(), getZ(), getX() + x1, getY() + y1, getGeoIndex());
}

public final void doDie(Creature killer) {
// killing is only possible one time
if (!isDead.compareAndSet(false, true))
return;

onDeath(killer);
}

protected void onDeath(Creature killer) {
if (killer != null) {
Player killerPlayer = killer.getPlayer();
if (killerPlayer != null)
killerPlayer.getListeners().onKillIgnorePetOrSummon(this);

killer.getListeners().onKill(this);

if (isPlayer() && killer.isPlayable())
_currentCp = 0;
}

setTarget(null);
stopMove();
stopAttackStanceTask();
stopRegeneration();

_currentHp = 0;

// Stop all active skills effects in progress on the L2Character
if (isBlessedByNoblesse() || isSalvation()) {
if (isSalvation() && isPlayer() && !getPlayer().isInOlympiadMode())
getPlayer().reviveRequest(getPlayer(), 100, false);
for (Effect e : getEffectList().getAllEffects())
// Noblesse Blessing Buff/debuff effects are retained after
// death. However, Noblesse Blessing and Lucky Charm are lost as normal.
if (e.getEffectType() == EffectType.BlessNoblesse || e.getSkill().getId() == Skill.SKILL_FORTUNE_OF_NOBLESSE || e.getSkill().getId() == Skill.SKILL_RAID_BLESSING)
e.exit();
else if (e.getEffectType() == EffectType.AgathionResurrect) {
if (isPlayer())
getPlayer().setAgathionRes(true);
e.exit();
}
} else
for (Effect e : getEffectList().getAllEffects())
// Некоторые эффекты сохраняются при смерти
if (e.getEffectType() != EffectType.Transformation && !e.getSkill().isPreservedOnDeath())
e.exit();

ThreadPoolManager.getInstance().execute(new NotifyAITask(this, CtrlEvent.EVT_DEAD, killer, null));

getListeners().onDeath(killer);

updateEffectIcons();
updateStats();
broadcastStatusUpdate();...
Ответ
#2
:dd: пожалуйста забудьте что-то такое сервер la2 и java
возвращайтесь к обыденным вещам.

:dd: Компиляция невозможна без остальной части исходников.
Ответ
#3
javac -classpath имя\jar.jar -Xlint:unchecked filename.java

должно помочь
Ответ
#4
Gattsu Написал::dd: пожалуйста забудьте что-то такое сервер la2 и java
возвращайтесь к обыденным вещам.

:dd: Компиляция невозможна без остальной части исходников.
Извини, если чем-то кумарю, конечно, но я пока только начинаю вливаться в мир Java. Только вчера уроки смотрел.
А по теме: есть тогда какой-то класс-редактор? Ну, допустим, я этому файлу просто поменяю импорты, кину в похожие исходники и скомпилирую, а потом то нужно импорты обратно поставить!
Я, конечно, нашел СВН их исходников, но они под логом и пасом:
http://subversion.assembla.com/svn/devworld/
Ответ
#5
Автор несет ахинею, хочешь научиться иди читай книги, а не говно видео уроки смотри.

не зная основ программирования не х.. лесть, один х.. не чего не выйдет.
Пусть в горле ложка застрянет у того кто писал систему вступления в клан. © Mifesto
Ответ
#6
mmorgdev Написал:Автор несет ахинею, хочешь научиться иди читай книги, а не говно видео уроки смотри.

не зная основ программирования не х.. лесть, один х.. не чего не выйдет.
Я же говорю, что только вчера начал язык Java изучать! Или ты думаешь, что за один день можно ему обучиться?!
Ладно, клоз тему, разобрался уже.
Ответ
#7
mmorgdev Написал:Автор несет ахинею, хочешь научиться иди читай книги, а не говно видео уроки смотри.

не зная основ программирования не х.. лесть, один х.. не чего не выйдет.
По основам программирования книги уже не актуальны. Их заменили уйма видеоуроков. В частности от Специалист.

Добавлено через 2 минуты
GooD Написал:Я же говорю, что только вчера начал язык Java изучать! Или ты думаешь, что за один день можно ему обучиться?!
Ладно, клоз тему, разобрался уже.
Если Вы только учитесь и только первые дни, то пока Вам не стоит задумываться о сборке проекта. Для начало Вам стоит понять, что вообще такое код и ООП.
Ответ
#8
Видеоуроки не то.
Ответ
#9
Zubastic Написал:Видеоуроки не то.
Хм, а что Вы скажите о видеокурсов от специалист? Я думаю, книги об основе программирования не сравнятся с ними.
Ответ
#10
Видеоуроки это: скопировал то, что в уроке. Бездумно, не разобравшись зачем и почему.
Ответ


Возможно похожие темы ...
Тема Автор Ответы Просмотры Последний пост
  Ребята помогите с логин и геймом Lackyjack 4 1,884 04-04-2018, 05:46 PM
Последний пост: MasVild
  Помогите переписать скрипт с Python на Java Virrilis3 0 1,478 03-29-2018, 10:55 PM
Последний пост: Virrilis3
  Помогите со сборкой lostworld HF voland3 1 2,137 03-22-2018, 12:54 AM
Последний пост: Kampina
  Проблема с компилом Nez 2 1,735 08-04-2016, 04:08 PM
Последний пост: Nez
  Помогите со скриптом Mazahacka 0 1,134 07-29-2015, 10:26 PM
Последний пост: Mazahacka
  Сервер RusTeam rev1269 Хроники C5 [Помогите найти] s4nders 0 1,038 03-13-2015, 09:21 AM
Последний пост: s4nders
  Помогите скомпилить cool235 1 1,425 01-04-2015, 09:03 PM
Последний пост: Rolfer
  Оверлорд докаст скилов - помогите настроить Munhgauzen 15 3,841 01-11-2014, 08:04 AM
Последний пост: DiagoD
  Оверлорд помогите насторить Hide - офлайк Munhgauzen 3 1,519 12-22-2013, 01:53 AM
Последний пост: Munhgauzen
  Помогите прикрутить код wakepower 22 6,931 12-08-2013, 10:19 AM
Последний пост: alextt1989

Перейти к форуму:


Пользователи, просматривающие эту тему: 3 Гость(ей)