Перейти к содержанию
Авторизация  
staige2973

Эффекты накладываются не по порядку

Рекомендуемые сообщения

При баффе, эффекты накладываются рандомно, а не по порядку. Еще при удалении эффектов по одному, они перемещаются. Пример: бафф акумен стоял в самом начале, я удалю любой другой бафф, а акумен переместится в конец. Как сделать, что бы баффы не перемещались?

package l2p.gameserver.model;


import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;

import l2p.commons.threading.RunnableImpl;
import l2p.gameserver.Config;
import l2p.gameserver.listener.actor.OnAttackListener;
import l2p.gameserver.listener.actor.OnMagicUseListener;
import l2p.gameserver.masteriopack.bbsbuffer.BBSBuffer;
import l2p.gameserver.masteriopack.bbsbuffer.BBSBufferConfig;
import l2p.gameserver.serverpackets.AbnormalStatusUpdate;
import l2p.gameserver.serverpackets.ExOlympiadSpelledInfo;
import l2p.gameserver.serverpackets.PartySpelled;
import l2p.gameserver.serverpackets.ShortBuffStatusUpdate;
import l2p.gameserver.serverpackets.SystemMessage;
import l2p.gameserver.serverpackets.components.SystemMsg;
import l2p.gameserver.skills.AbnormalEffect;
import l2p.gameserver.skills.EffectType;
import l2p.gameserver.skills.effects.EffectTemplate;
import l2p.gameserver.stats.Env;
import l2p.gameserver.stats.funcs.Func;
import l2p.gameserver.stats.funcs.FuncOwner;
import l2p.gameserver.tables.SkillTable;
import l2p.gameserver.taskmanager.EffectTaskManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class Effect extends RunnableImpl implements Comparable, FuncOwner {

private static final Logger _log = LoggerFactory.getLogger(Effect.class);
public final static Effect[] EMPTY_L2EFFECT_ARRAY = new Effect[0];
// Состояние, при котором работает задача запланированного эффекта
public static int SUSPENDED = -1;
public static int STARTING = 0;
public static int STARTED = 1;
public static int ACTING = 2;
public static int FINISHING = 3;
public static int FINISHED = 4;
/**
* Накладывающий эффект
*/
protected final Creature _effector;
/**
* Тот, на кого накладывают эффект
*/
protected final Creature _effected;
protected final Skill _skill;
protected final int _displayId;
protected final int _displayLevel;
// the value of an update
private final double _value;
// the current state
private final AtomicInteger _state;
// counter
private int _count;
// period, milliseconds
private long _period;
private long _startTimeMillis;
private long _duration;
private boolean _inUse = false;
private Effect _next = null;
private boolean _active = false;
protected final EffectTemplate _template;
private Future_effectTask;

protected Effect(Env env, EffectTemplate template) {
_skill = env.skill;
_effector = env.character;
_effected = env.target;

_template = template;
_value = template._value;
_count = template.getCount();
_period = template.getPeriod();

_duration = _period * _count;

_displayId = template._displayId != 0 ? template._displayId : _skill.getDisplayId();
_displayLevel = template._displayLevel != 0 ? template._displayLevel : _skill.getDisplayLevel();

_state = new AtomicInteger(STARTING);
}

public long getPeriod() {
return _period;
}

public void setPeriod(long time) {
_period = time;
_duration = _period * _count;
}

public int getCount() {
return _count;
}

public void setCount(int count) {
_count = count;
_duration = _period * _count;
}

public boolean isOneTime() {
return _period == 0;
}

/**
* Возвращает время старта эффекта, если время не установлено, возвращается
* текущее
*/
public long getStartTime() {
if (_startTimeMillis == 0L) {
return System.currentTimeMillis();
}
return _startTimeMillis;
}

/**
* Возвращает общее время действия эффекта в миллисекундах.
*/
public long getTime() {
return System.currentTimeMillis() - getStartTime();
}

/**
* Возвращает длительность эффекта в миллисекундах.
*/
public long getDuration() {
return _duration;
}

/**
* Возвращает оставшееся время в секундах.
*/
public int getTimeLeft() {
return (int) ((getDuration() - getTime()) / 1000L);
}

/**
* Возвращает true, если осталось время для действия эффекта
*/
public boolean isTimeLeft() {
return getDuration() - getTime() > 0L;
}

public boolean isInUse() {
return _inUse;
}

public void setInUse(boolean inUse) {
_inUse = inUse;
}

public boolean isActive() {
return _active;
}

/**
* Для неактивных эфектов не вызывается onActionTime.
*/
public void setActive(boolean set) {
_active = set;
}

public EffectTemplate getTemplate() {
return _template;
}

public String getStackType() {
return getTemplate()._stackType;
}

public String getStackType2() {
return getTemplate()._stackType2;
}

public boolean checkStackType(String param) {
return getStackType().equalsIgnoreCase(param) || getStackType2().equalsIgnoreCase(param);
}

public boolean checkStackType(Effect param) {
return checkStackType(param.getStackType()) || checkStackType(param.getStackType2());
}

public int getStackOrder() {
return getTemplate()._stackOrder;
}

public Skill getSkill() {
return _skill;
}

public Creature getEffector() {
return _effector;
}

public Creature getEffected() {
return _effected;
}

public double calc() {
return _value;
}

public boolean isEnded() {
return isFinished() || isFinishing();
}

public boolean isFinishing() {
return getState() == FINISHING;
}

public boolean isFinished() {
return getState() == FINISHED;
}

private int getState() {
return _state.get();
}

private boolean setState(int oldState, int newState) {
return _state.compareAndSet(oldState, newState);
}

private ActionDispelListener _listener;

private class ActionDispelListener implements OnAttackListener, OnMagicUseListener {

@@override
public void onMagicUse(Creature actor, Skill skill, Creature target, boolean alt) {
exit();
}

@@override
public void onAttack(Creature actor, Creature target) {
exit();
}
}

public boolean checkCondition() {
return true;
}

/**
* Notify started
*/
protected void onStart() {
getEffected().addStatFuncs(getStatFuncs());
getEffected().addTriggers(getTemplate());
if (getTemplate()._abnormalEffect != AbnormalEffect.NULL) {
getEffected().startAbnormalEffect(getTemplate()._abnormalEffect);
} else if (getEffectType().getAbnormal() != null) {
getEffected().startAbnormalEffect(getEffectType().getAbnormal());
}
if (getTemplate()._abnormalEffect2 != AbnormalEffect.NULL) {
getEffected().startAbnormalEffect(getTemplate()._abnormalEffect2);
}
if (getTemplate()._abnormalEffect3 != AbnormalEffect.NULL) {
getEffected().startAbnormalEffect(getTemplate()._abnormalEffect3);
}
if (_template._cancelOnAction) {
getEffected().addListener(_listener = new ActionDispelListener());
}
if (getEffected().isPlayer() && !getSkill().canUseTeleport()) {
getEffected().getPlayer().getPlayerAccess().UseTeleport = false;
}
}

/**
* Return true for continuation of this effect
*/
protected abstract boolean onActionTime();

/**
* Cancel the effect in the the abnormal effect map of the effected
* L2Character.

*

*/
protected void onExit() {
getEffected().removeStatsOwner(this);
getEffected().removeTriggers(getTemplate());
if (getTemplate()._abnormalEffect != AbnormalEffect.NULL) {
getEffected().stopAbnormalEffect(getTemplate()._abnormalEffect);
} else if (getEffectType().getAbnormal() != null) {
getEffected().stopAbnormalEffect(getEffectType().getAbnormal());
}
if (getTemplate()._abnormalEffect2 != AbnormalEffect.NULL) {
getEffected().stopAbnormalEffect(getTemplate()._abnormalEffect2);
}
if (getTemplate()._abnormalEffect3 != AbnormalEffect.NULL) {
getEffected().stopAbnormalEffect(getTemplate()._abnormalEffect3);
}
if (_template._cancelOnAction) {
getEffected().removeListener(_listener);
}
if (getEffected().isPlayer() && getStackType().equals(EffectTemplate.HP_RECOVER_CAST)) {
getEffected().sendPacket(new ShortBuffStatusUpdate());
}
if (getEffected().isPlayer() && !getSkill().canUseTeleport()
&& !getEffected().getPlayer().getPlayerAccess().UseTeleport) {
getEffected().getPlayer().getPlayerAccess().UseTeleport = true;
}

// BBS Buffer by Masterio
if (BBSBufferConfig.AUTOREBUFF_ENABLED) {
if (getEffected() instanceof Player) {
BBSBuffer BB = ((Player) getEffected())._bbsbuffer;

if (!BB.isRebuffPlayerTaskExecute() && BB.getRebuffPlayerSchemeId() > 0
&& BB.isSkillInSchemeExists(getSkill().getId(), true)) {
BB.startRebuffPlayerTaskSchedule();
}
} else if (getEffected() instanceof Summon) {
BBSBuffer BB = getEffected().getPlayer()._bbsbuffer;

if (!BB.isRebuffSummonTaskExecute() && BB.getRebuffSummonSchemeId() > 0
&& BB.isSkillInSchemeExists(getSkill().getId(), false)) {
BB.startRebuffSummonTaskSchedule();
}
}
}
}

private void stopEffectTask() {
if (_effectTask != null) {
_effectTask.cancel(false);
}
}

private void startEffectTask() {
if (_effectTask == null) {
_startTimeMillis = System.currentTimeMillis();
_effectTask = EffectTaskManager.getInstance().scheduleAtFixedRate(this, _period, _period);
}
}

/**
* Добавляет эффект в список эффектов, в случае успешности вызывается метод
* start
*/
public final void schedule() {
Creature effected = getEffected();
if (effected == null) {
return;
}

if (!checkCondition()) {
return;
}

getEffected().getEffectList().addEffect(this);
}

/**
* Переводит эффект в "фоновый" режим, эффект может быть запущен методом
* schedule
*/
private void suspend() {
// Эффект создан, запускаем задачу в фоне
if (setState(STARTING, SUSPENDED)) {
startEffectTask();
} else if (setState(STARTED, SUSPENDED) || setState(ACTING, SUSPENDED)) {
synchronized (this) {
if (isInUse()) {
setInUse(false);
setActive(false);
onExit();
}
}
getEffected().getEffectList().removeEffect(this);
}
}

/**
* Запускает задачу эффекта, в случае если эффект успешно добавлен в список
*/
public final void start() {
if (setState(STARTING, STARTED)) {
synchronized (this) {
if (isInUse()) {
setActive(true);
onStart();
startEffectTask();
}
}
}

run();
}

@@override
public final void runImpl() throws Exception {
if (setState(STARTED, ACTING)) {
// Отображать сообщение только для первого эффекта скилла
if (!getSkill().isHideStartMessage()
&& getEffected().getEffectList().getEffectsCountForSkill(getSkill().getId()) == 1) {
getEffected().sendPacket(
new SystemMessage(SystemMsg.S1_EFFECT_CAN_BE_FELT).addSkillName(_displayId, _displayLevel));
}

return;
}

if (getState() == SUSPENDED) {
if (isTimeLeft()) {
_count--;
if (isTimeLeft()) {
return;
}
}

exit();
return;
}

if (getState() == ACTING) {
if (isTimeLeft()) {
_count--;
if ((!isActive() || onActionTime()) && isTimeLeft()) {
return;
}
}
}

if (setState(ACTING, FINISHING)) {
setInUse(false);
}

if (setState(FINISHING, FINISHED)) {
synchronized (this) {
setActive(false);
stopEffectTask();
onExit();
}

// Добавляем следующий запланированный эффект
Effect next = getNext();
if (next != null) {
if (next.setState(SUSPENDED, STARTING)) {
next.schedule();
}
}

if (getSkill().getDelayedEffect() > 0) {
Skill delayErrects = SkillTable.getInstance().getInfo(getSkill().getDelayedEffect(),
getSkill().getDelayedEffectLvl());
if (delayErrects != null) {
delayErrects.getEffects(_effector, _effected, false, false);
}
}

boolean msg = !isHidden() && getEffected().getEffectList().getEffectsCountForSkill(getSkill().getId()) == 1;

getEffected().getEffectList().removeEffect(this);

// Отображать сообщение только для последнего оставшегося эффекта
// скилла
if (msg) {
getEffected().sendPacket(
new SystemMessage(SystemMsg.S1_HAS_WORN_OFF).addSkillName(_displayId, _displayLevel));
}
}
}

/**
* Завершает эффект и все связанные, удаляет эффект из списка эффектов
*/
public final void exit() {
Effect next = getNext();
if (next != null) {
next.exit();
}
removeNext();

// Эффект запланирован на запуск, удаляем
if (setState(STARTING, FINISHED)) {
getEffected().getEffectList().removeEffect(this);
} // Эффект работает в "фоне", останавливаем задачу в планировщике
else if (setState(SUSPENDED, FINISHED)) {
stopEffectTask();
} else if (setState(STARTED, FINISHED) || setState(ACTING, FINISHED)) {
synchronized (this) {
if (isInUse()) {
setInUse(false);
setActive(false);
stopEffectTask();
onExit();
}
}
getEffected().getEffectList().removeEffect(this);
}
}

/**
* Поставить в очередь эффект
*
* @param e
*

* @return true, если эффект поставлен в очередь
*/
private boolean scheduleNext(Effect e) {
if (e == null || e.isEnded()) {
return false;
}

Effect next = getNext();
if (next != null && !next.maybeScheduleNext(e)) {
return false;
}

_next = e;

return true;
}

public Effect getNext() {
return _next;
}

private void removeNext() {
_next = null;
}

/**
* @return false - игнорировать новый эффект, true - использовать новый
* эффект
*/
public boolean maybeScheduleNext(Effect newEffect) {
if (newEffect.getStackOrder() < getStackOrder()) // новый эффект слабее
{
if (newEffect.getTimeLeft() > getTimeLeft()) // новый эффект длинее
{
newEffect.suspend();
scheduleNext(newEffect); // пробуем пристроить новый эффект в
// очередь
}

return false; // более слабый эффект всегда игнорируется, даже если
// не попал в очередь
} else // если старый не дольше, то просто остановить его
if (newEffect.getTimeLeft() >= getTimeLeft()) {
// наследуем зашедуленый старому, если есть смысл
if (getNext() != null && getNext().getTimeLeft() > newEffect.getTimeLeft()) {
newEffect.scheduleNext(getNext());
// отсоединяем зашедуленные от текущего
removeNext();
}
exit();
} else // если новый короче то зашедулить старый
{
suspend();
newEffect.scheduleNext(this);
}

return true;
}

public Func[] getStatFuncs() {
return getTemplate().getStatFuncs(this);
}

public void addIcon(AbnormalStatusUpdate mi) {
if (!isActive() || isHidden()) {
return;
}
int duration = _skill.isToggle() ? AbnormalStatusUpdate.INFINITIVE_EFFECT : getTimeLeft();
mi.addEffect(_displayId, _displayLevel, duration);
}

public void addPartySpelledIcon(PartySpelled ps) {
if (!isActive() || isHidden()) {
return;
}
int duration = _skill.isToggle() ? AbnormalStatusUpdate.INFINITIVE_EFFECT : getTimeLeft();
ps.addPartySpelledEffect(_displayId, _displayLevel, duration);
}

public void addOlympiadSpelledIcon(Player player, ExOlympiadSpelledInfo os) {
if (!isActive() || isHidden()) {
return;
}
int duration = _skill.isToggle() ? AbnormalStatusUpdate.INFINITIVE_EFFECT : getTimeLeft();
os.addSpellRecivedPlayer(player);
os.addEffect(_displayId, _displayLevel, duration);
}

protected int getLevel() {
return _skill.getLevel();
}

public EffectType getEffectType() {
return getTemplate()._effectType;
}

public boolean isHidden() {
return _displayId < 0;
}

@@override
public int compareTo(Effect obj) {
if (obj.equals(this)) {
return 0;
}
return 1;
}

public boolean isSaveable() {
return _template.isSaveable(getSkill().isSaveable()) && getTimeLeft() >= Config.ALT_SAVE_EFFECTS_REMAINING_TIME;
}

public int getDisplayId() {
return _displayId;
}

public int getDisplayLevel() {
return _displayLevel;
}

public boolean isCancelable() {
return _template.isCancelable(getSkill().isCancelable());
}

@@override
public String toString() {
return "Skill: " + _skill + ", state: " + getState() + ", inUse: " + _inUse + ", active : " + _active;
}

@@override
public boolean isFuncEnabled() {
return isInUse();
}

@@override
public boolean overrideLimits() {
return false;
}

public boolean isOffensive() {
return _template.isOffensive(getSkill().isOffensive());
}
}

 

package l2p.gameserver.model;

import gnu.trove.list.array.TIntArrayList;
import gnu.trove.map.hash.TIntObjectHashMap;
import gnu.trove.set.hash.TIntHashSet;
import l2p.gameserver.skills.EffectType;
import l2p.gameserver.skills.effects.EffectTemplate;
import l2p.gameserver.skills.skillclasses.Transformation;
import l2p.gameserver.stats.Stats;
import l2p.gameserver.stats.funcs.FuncTemplate;
import org.apache.commons.lang3.ArrayUtils;
import l2p.gameserver.Config;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class EffectList {

public static final int NONE_SLOT_TYPE = -1;
public static final int BUFF_SLOT_TYPE = 0;
public static final int MUSIC_SLOT_TYPE = 1;
public static final int TRIGGER_SLOT_TYPE = 2;
public static final int DEBUFF_SLOT_TYPE = 3;
private Creature _actor;
private List _effects;
private Lock lock = new ReentrantLock();

public EffectList(Creature owner) {
_actor = owner;
}

/**
* Возвращает число эффектов соответствующее данному скиллу
*/
public int getEffectsCountForSkill(int skill_id) {
if (isEmpty()) {
return 0;
}

int count = 0;

for (Effect e : _effects) {
if (e.getSkill().getId() == skill_id) {
count++;
}
}

return count;
}

public Effect getEffectByType(EffectType et) {
if (isEmpty()) {
return null;
}

for (Effect e : _effects) {
if (e.getEffectType() == et) {
return e;
}
}

return null;
}

public List getEffectsBySkill(Skill skill) {
if (skill == null) {
return null;
}
return getEffectsBySkillId(skill.getId());
}

public List getEffectsBySkillId(int skillId) {
if (isEmpty()) {
return null;
}

List list = new ArrayList(2);
for (Effect e : _effects) {
if (e.getSkill().getId() == skillId) {
list.add(e);
}
}

return list.isEmpty() ? null : list;
}

public Effect getEffectByIndexAndType(int skillId, EffectType type) {
if (isEmpty()) {
return null;
}
for (Effect e : _effects) {
if (e.getSkill().getId() == skillId && e.getEffectType() == type) {
return e;
}
}

return null;
}

public Effect getEffectByStackType(String type) {
if (isEmpty()) {
return null;
}
for (Effect e : _effects) {
if (e.getStackType().equalsIgnoreCase(type)) {
return e;
}
}

return null;
}

public boolean containEffectFromSkills(int[] skillIds) {
if (isEmpty()) {
return false;
}

int skillId;
for (Effect e : _effects) {
skillId = e.getSkill().getId();
if (ArrayUtils.contains(skillIds, skillId)) {
return true;
}
}

return false;
}

public List getAllEffects() {
if (isEmpty()) {
return Collections.emptyList();
}
return new ArrayList(_effects);
}

public boolean isEmpty() {
return _effects == null || _effects.isEmpty();
}

/**
* Возвращает первые эффекты для всех скиллов. Нужно для отображения не
* более чем 1 иконки для каждого скилла.
*/
public Effect[] getAllFirstEffects() {
if (isEmpty()) {
return Effect.EMPTY_L2EFFECT_ARRAY;
}

TIntObjectHashMap map = new TIntObjectHashMap();

for (Effect e : _effects) {
map.put(e.getSkill().getId(), e);
}

return map.values(new Effect[map.size()]);
}

private void checkSlotLimit(Effect newEffect) {
if (_effects == null) {
return;
}

int slotType = getSlotType(newEffect);
if (slotType == NONE_SLOT_TYPE) {
return;
}

int size = 0;
TIntArrayList skillIds = new TIntArrayList();
for (Effect e : _effects) {
if (e.isInUse()) {
if (e.getSkill().equals(newEffect.getSkill())) // мы уже имеем
// эффект от
// этого скилла
{
return;
}

if (!skillIds.contains(e.getSkill().getId())) {
int subType = getSlotType(e);
if (subType == slotType) {
size++;
skillIds.add(e.getSkill().getId());
}
}
}
}

int limit = 0;
switch (slotType) {
case BUFF_SLOT_TYPE:
limit = _actor.getBuffLimit();
break;
case MUSIC_SLOT_TYPE:
limit = Config.ALT_MUSIC_LIMIT;
break;
case DEBUFF_SLOT_TYPE:
limit = Config.ALT_DEBUFF_LIMIT;
break;
case TRIGGER_SLOT_TYPE:
limit = Config.ALT_TRIGGER_LIMIT;
break;
}

if (size < limit) {
return;
}

int skillId = 0;
for (Effect e : _effects) {
if (e.isInUse()) {
if (getSlotType(e) == slotType) {
skillId = e.getSkill().getId();
break;
}
}
}

if (skillId != 0) {
stopEffect(skillId);
}
}

public static int getSlotType(Effect e) {
if (e.getSkill().isPassive() || e.getSkill().isToggle() || e.getSkill() instanceof Transformation
|| e.getStackType().equals(EffectTemplate.HP_RECOVER_CAST) || e.getEffectType() == EffectType.Cubic) {
return NONE_SLOT_TYPE;
} else if (e.getSkill().isOffensive()) {
return DEBUFF_SLOT_TYPE;
} else if (e.getSkill().isMusic()) {
return MUSIC_SLOT_TYPE;
} else if (e.getSkill().isTrigger()) {
return TRIGGER_SLOT_TYPE;
} else {
return BUFF_SLOT_TYPE;
}
}

public static boolean checkStackType(EffectTemplate ef1, EffectTemplate ef2) {
if (!ef1._stackType.equals(EffectTemplate.NO_STACK) && ef1._stackType.equalsIgnoreCase(ef2._stackType)) {
return true;
}
if (!ef1._stackType.equals(EffectTemplate.NO_STACK) && ef1._stackType.equalsIgnoreCase(ef2._stackType2)) {
return true;
}
if (!ef1._stackType2.equals(EffectTemplate.NO_STACK) && ef1._stackType2.equalsIgnoreCase(ef2._stackType)) {
return true;
}
if (!ef1._stackType2.equals(EffectTemplate.NO_STACK) && ef1._stackType2.equalsIgnoreCase(ef2._stackType2)) {
return true;
}
return false;
}

public void addEffect(Effect effect) {
// TODO [G1ta0] затычка на статы повышающие HP/MP/CP
double hp = _actor.getCurrentHp();
double mp = _actor.getCurrentMp();
double cp = _actor.getCurrentCp();

String stackType = effect.getStackType();
boolean add = false;

lock.lock();
try {
if (_effects == null) {
_effects = new CopyOnWriteArrayList();
}

if (stackType.equals(EffectTemplate.NO_STACK)) // Удаляем такие же
// эффекты
{
for (Effect e : _effects) {
if (!e.isInUse()) {
continue;
}

if (e.getStackType().equals(EffectTemplate.NO_STACK)
&& e.getSkill().getId() == effect.getSkill().getId()
&& e.getEffectType() == effect.getEffectType()) // Если
// оставшаяся
// длительность
// старого
// эффекта
// больше
// чем
// длительность
// нового,
// то
// оставляем
// старый.
{
if (effect.getTimeLeft() > e.getTimeLeft()) {
e.exit();
} else {
return;
}
}
}
} else // Проверяем, нужно ли накладывать эффект, при совпадении
// StackType.
// Новый эффект накладывается только в том случае, если у него
// больше StackOrder и больше длительность.
// Если условия подходят - удаляем старый.
{
for (Effect e : _effects) {
if (!e.isInUse()) {
continue;
}

if (!checkStackType(e.getTemplate(), effect.getTemplate())) {
continue;
}

if (e.getSkill().getId() == effect.getSkill().getId()
&& e.getEffectType() != effect.getEffectType()) {
break;
}

// Эффекты со StackOrder == -1 заменить нельзя (например,
// Root).
if (e.getStackOrder() == -1) {
return;
}

if (!e.maybeScheduleNext(effect)) {
return;
}
}
}

// Проверяем на лимиты бафов/дебафов
checkSlotLimit(effect);

// Добавляем новый эффект
if (add = _effects.add(effect)) {
effect.setInUse(true);
}
} finally {
lock.unlock();
}

if (!add) {
return;
}

// Запускаем эффект
effect.start();

// TODO [G1ta0] затычка на статы повышающие HP/MP/CP
for (FuncTemplate ft : effect.getTemplate().getAttachedFuncs()) {
if (ft._stat == Stats.MAX_HP) {
_actor.setCurrentHp(hp, false);
} else if (ft._stat == Stats.MAX_MP) {
_actor.setCurrentMp(mp);
} else if (ft._stat == Stats.MAX_CP) {
_actor.setCurrentCp(cp);
}
}

// Обновляем иконки
_actor.updateStats();
_actor.updateEffectIcons();
}

/**
* Удаление эффекта из списка
*
* @param effect
* эффект для удаления
*/
public void removeEffect(Effect effect) {
if (effect == null) {
return;
}

boolean remove = false;

lock.lock();
try {
if (_effects == null) {
return;
}

if (!(remove = _effects.remove(effect))) {
return;
}
} finally {
lock.unlock();
}

if (!remove) {
return;
}

_actor.updateStats();
_actor.updateEffectIcons();
}

public void stopAllEffects() {
if (isEmpty()) {
return;
}

lock.lock();
try {
for (Effect e : _effects) {
e.exit();
}
} finally {
lock.unlock();
}

_actor.updateStats();
_actor.updateEffectIcons();
}

public void stopEffect(int skillId) {
if (isEmpty()) {
return;
}

for (Effect e : _effects) {
if (e.getSkill().getId() == skillId) {
e.exit();
}
}
}

public void stopEffect(Skill skill) {
if (skill != null) {
stopEffect(skill.getId());
}
}

public void stopEffectByDisplayId(int skillId) {
if (isEmpty()) {
return;
}

for (Effect e : _effects) {
if (e.getSkill().getDisplayId() == skillId) {
e.exit();
}
}
}

public void stopEffects(EffectType type) {
if (isEmpty()) {
return;
}

for (Effect e : _effects) {
if (e.getEffectType() == type) {
e.exit();
}
}
}

/**
* Находит скиллы с указанным эффектом, и останавливает у этих скиллов все
* эффекты (не только указанный).
*/
public void stopAllSkillEffects(EffectType type) {
if (isEmpty()) {
return;
}

TIntHashSet skillIds = new TIntHashSet();

for (Effect e : _effects) {
if (e.getEffectType() == type) {
skillIds.add(e.getSkill().getId());
}
}

for (int skillId : skillIds.toArray()) {
stopEffect(skillId);
}
}
}

 

Изменено пользователем staige2973

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация  

  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...