Runnable implementations for task manager classes.

This commit is contained in:
MobiusDevelopment
2021-10-02 22:51:05 +00:00
parent e15d1719be
commit 0c4cbf4e18
372 changed files with 11957 additions and 10677 deletions

View File

@@ -33,7 +33,7 @@ import org.l2jmobius.gameserver.network.serverpackets.AutoAttackStop;
* Attack stance task manager.
* @author Luca Baldi
*/
public class AttackStanceTaskManager
public class AttackStanceTaskManager implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(AttackStanceTaskManager.class.getName());
@@ -42,58 +42,58 @@ public class AttackStanceTaskManager
private static final Map<Creature, Long> _attackStanceTasks = new ConcurrentHashMap<>();
private static boolean _working = false;
/**
* Instantiates a new attack stance task manager.
*/
protected AttackStanceTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
ThreadPool.scheduleAtFixedRate(this, 0, 1000);
}
@Override
public void run()
{
if (_working)
{
if (_working)
return;
}
_working = true;
final long current = Chronos.currentTimeMillis();
try
{
final Iterator<Entry<Creature, Long>> iterator = _attackStanceTasks.entrySet().iterator();
Entry<Creature, Long> entry;
Creature creature;
while (iterator.hasNext())
{
return;
}
_working = true;
final long current = Chronos.currentTimeMillis();
try
{
final Iterator<Entry<Creature, Long>> iterator = _attackStanceTasks.entrySet().iterator();
Entry<Creature, Long> entry;
Creature creature;
while (iterator.hasNext())
entry = iterator.next();
if ((current - entry.getValue().longValue()) > COMBAT_TIME)
{
entry = iterator.next();
if ((current - entry.getValue().longValue()) > COMBAT_TIME)
creature = entry.getKey();
if (creature != null)
{
creature = entry.getKey();
if (creature != null)
creature.broadcastPacket(new AutoAttackStop(creature.getObjectId()));
creature.getAI().setAutoAttacking(false);
if (creature.isPlayer() && creature.hasSummon())
{
creature.broadcastPacket(new AutoAttackStop(creature.getObjectId()));
creature.getAI().setAutoAttacking(false);
if (creature.isPlayer() && creature.hasSummon())
creature.getActingPlayer().clearDamageTaken();
final Summon pet = creature.getPet();
if (pet != null)
{
creature.getActingPlayer().clearDamageTaken();
final Summon pet = creature.getPet();
if (pet != null)
{
pet.broadcastPacket(new AutoAttackStop(pet.getObjectId()));
}
creature.getServitors().values().forEach(s -> s.broadcastPacket(new AutoAttackStop(s.getObjectId())));
pet.broadcastPacket(new AutoAttackStop(pet.getObjectId()));
}
creature.getServitors().values().forEach(s -> s.broadcastPacket(new AutoAttackStop(s.getObjectId())));
}
iterator.remove();
}
iterator.remove();
}
}
catch (Exception e)
{
// Unless caught here, players remain in attack positions.
LOGGER.log(Level.WARNING, "Error in AttackStanceTaskManager: " + e.getMessage(), e);
}
_working = false;
}, 0, 1000);
}
catch (Exception e)
{
// Unless caught here, players remain in attack positions.
LOGGER.log(Level.WARNING, "Error in AttackStanceTaskManager: " + e.getMessage(), e);
}
_working = false;
}
/**

View File

@@ -26,44 +26,47 @@ import org.l2jmobius.gameserver.model.actor.Attackable;
/**
* @author Mobius
*/
public class AttackableThinkTaskManager
public class AttackableThinkTaskManager implements Runnable
{
private static final Set<Attackable> ATTACKABLES = ConcurrentHashMap.newKeySet();
private static boolean _working = false;
public AttackableThinkTaskManager()
protected AttackableThinkTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
ThreadPool.scheduleAtFixedRate(this, 1000, 1000);
}
@Override
public void run()
{
if (_working)
{
if (_working)
return;
}
_working = true;
CreatureAI ai;
for (Attackable attackable : ATTACKABLES)
{
if (attackable.hasAI())
{
return;
}
_working = true;
CreatureAI ai;
for (Attackable attackable : ATTACKABLES)
{
if (attackable.hasAI())
ai = attackable.getAI();
if (ai != null)
{
ai = attackable.getAI();
if (ai != null)
{
ai.onEvtThink();
}
else
{
remove(attackable);
}
ai.onEvtThink();
}
else
{
remove(attackable);
}
}
_working = false;
}, 1000, 1000);
else
{
remove(attackable);
}
}
_working = false;
}
public void add(Attackable attackable)

View File

@@ -34,138 +34,141 @@ import org.l2jmobius.gameserver.network.serverpackets.autoplay.ExAutoPlayDoMacro
/**
* @author Mobius
*/
public class AutoPlayTaskManager
public class AutoPlayTaskManager implements Runnable
{
private static final Set<PlayerInstance> PLAYERS = ConcurrentHashMap.newKeySet();
private static boolean _working = false;
public AutoPlayTaskManager()
protected AutoPlayTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
ThreadPool.scheduleAtFixedRate(this, 1000, 1000);
}
@Override
public void run()
{
if (_working)
{
if (_working)
return;
}
_working = true;
PLAY: for (PlayerInstance player : PLAYERS)
{
if (!player.isOnline() || player.isInOfflineMode() || !Config.ENABLE_AUTO_PLAY)
{
return;
stopAutoPlay(player);
continue PLAY;
}
_working = true;
PLAY: for (PlayerInstance player : PLAYERS)
if (player.isCastingNow() || (player.getQueuedSkill() != null))
{
if (!player.isOnline() || player.isInOfflineMode() || !Config.ENABLE_AUTO_PLAY)
continue PLAY;
}
// Skip thinking.
final WorldObject target = player.getTarget();
if ((target != null) && target.isMonster())
{
final MonsterInstance monster = (MonsterInstance) target;
if (monster.isAlikeDead())
{
stopAutoPlay(player);
continue PLAY;
player.setTarget(null);
}
if (player.isCastingNow() || (player.getQueuedSkill() != null))
else if (monster.getTarget() == player)
{
continue PLAY;
}
// Skip thinking.
final WorldObject target = player.getTarget();
if ((target != null) && target.isMonster())
{
final MonsterInstance monster = (MonsterInstance) target;
if (monster.isAlikeDead())
{
player.setTarget(null);
}
else if (monster.getTarget() == player)
{
// We take granted that mage classes do not auto hit.
if (isMageCaster(player))
{
continue PLAY;
}
// Check if actually attacking.
if (player.hasAI() && player.getAI().isAutoAttacking() && !player.isAttackingNow() && !player.isCastingNow() && !player.isMoving())
{
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, monster);
}
continue PLAY;
}
}
// Pickup.
if (player.getAutoPlaySettings().doPickup())
{
PICKUP: for (ItemInstance droppedItem : World.getInstance().getVisibleObjectsInRange(player, ItemInstance.class, 200))
{
// Check if item is reachable.
if ((droppedItem == null) //
|| (!droppedItem.isSpawned()) //
|| !GeoEngine.getInstance().canMoveToTarget(player.getX(), player.getY(), player.getZ(), droppedItem.getX(), droppedItem.getY(), droppedItem.getZ(), player.getInstanceWorld()))
{
continue PICKUP;
}
// Move to item.
if (player.calculateDistance2D(droppedItem) > 70)
{
if (!player.isMoving())
{
player.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, droppedItem);
}
continue PLAY;
}
// Try to pick it up.
if (!droppedItem.isProtected() || (droppedItem.getOwnerId() == player.getObjectId()))
{
player.doPickupItem(droppedItem);
continue PLAY; // Avoid pickup being skipped.
}
}
}
// Find target.
MonsterInstance monster = null;
double closestDistance = Double.MAX_VALUE;
TARGET: for (MonsterInstance nearby : World.getInstance().getVisibleObjectsInRange(player, MonsterInstance.class, player.getAutoPlaySettings().isShortRange() ? 600 : 1400))
{
// Skip unavailable monsters.
if ((nearby == null) || nearby.isAlikeDead())
{
continue TARGET;
}
// Check monster target.
if (player.getAutoPlaySettings().isRespectfulHunting() && (nearby.getTarget() != null) && (nearby.getTarget() != player) && !player.getServitors().containsKey(nearby.getTarget().getObjectId()))
{
continue TARGET;
}
// Check if monster is reachable.
if (nearby.isAutoAttackable(player) //
&& GeoEngine.getInstance().canSeeTarget(player, nearby)//
&& GeoEngine.getInstance().canMoveToTarget(player.getX(), player.getY(), player.getZ(), nearby.getX(), nearby.getY(), nearby.getZ(), player.getInstanceWorld()))
{
final double monsterDistance = player.calculateDistance2D(nearby);
if (monsterDistance < closestDistance)
{
monster = nearby;
closestDistance = monsterDistance;
}
}
}
// New target was assigned.
if (monster != null)
{
player.setTarget(monster);
// We take granted that mage classes do not auto hit.
if (isMageCaster(player))
{
continue PLAY;
}
player.sendPacket(ExAutoPlayDoMacro.STATIC_PACKET);
// Check if actually attacking.
if (player.hasAI() && player.getAI().isAutoAttacking() && !player.isAttackingNow() && !player.isCastingNow() && !player.isMoving())
{
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, monster);
}
continue PLAY;
}
}
_working = false;
}, 1000, 1000);
// Pickup.
if (player.getAutoPlaySettings().doPickup())
{
PICKUP: for (ItemInstance droppedItem : World.getInstance().getVisibleObjectsInRange(player, ItemInstance.class, 200))
{
// Check if item is reachable.
if ((droppedItem == null) //
|| (!droppedItem.isSpawned()) //
|| !GeoEngine.getInstance().canMoveToTarget(player.getX(), player.getY(), player.getZ(), droppedItem.getX(), droppedItem.getY(), droppedItem.getZ(), player.getInstanceWorld()))
{
continue PICKUP;
}
// Move to item.
if (player.calculateDistance2D(droppedItem) > 70)
{
if (!player.isMoving())
{
player.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, droppedItem);
}
continue PLAY;
}
// Try to pick it up.
if (!droppedItem.isProtected() || (droppedItem.getOwnerId() == player.getObjectId()))
{
player.doPickupItem(droppedItem);
continue PLAY; // Avoid pickup being skipped.
}
}
}
// Find target.
MonsterInstance monster = null;
double closestDistance = Double.MAX_VALUE;
TARGET: for (MonsterInstance nearby : World.getInstance().getVisibleObjectsInRange(player, MonsterInstance.class, player.getAutoPlaySettings().isShortRange() ? 600 : 1400))
{
// Skip unavailable monsters.
if ((nearby == null) || nearby.isAlikeDead())
{
continue TARGET;
}
// Check monster target.
if (player.getAutoPlaySettings().isRespectfulHunting() && (nearby.getTarget() != null) && (nearby.getTarget() != player) && !player.getServitors().containsKey(nearby.getTarget().getObjectId()))
{
continue TARGET;
}
// Check if monster is reachable.
if (nearby.isAutoAttackable(player) //
&& GeoEngine.getInstance().canSeeTarget(player, nearby)//
&& GeoEngine.getInstance().canMoveToTarget(player.getX(), player.getY(), player.getZ(), nearby.getX(), nearby.getY(), nearby.getZ(), player.getInstanceWorld()))
{
final double monsterDistance = player.calculateDistance2D(nearby);
if (monsterDistance < closestDistance)
{
monster = nearby;
closestDistance = monsterDistance;
}
}
}
// New target was assigned.
if (monster != null)
{
player.setTarget(monster);
// We take granted that mage classes do not auto hit.
if (isMageCaster(player))
{
continue PLAY;
}
player.sendPacket(ExAutoPlayDoMacro.STATIC_PACKET);
}
}
_working = false;
}
public void doAutoPlay(PlayerInstance player)

View File

@@ -28,93 +28,96 @@ import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius, Gigi
*/
public class AutoPotionTaskManager
public class AutoPotionTaskManager implements Runnable
{
private static final Set<PlayerInstance> PLAYERS = ConcurrentHashMap.newKeySet();
private static boolean _working = false;
public AutoPotionTaskManager()
protected AutoPotionTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
ThreadPool.scheduleAtFixedRate(this, 0, 1000);
}
@Override
public void run()
{
if (_working)
{
if (_working)
return;
}
_working = true;
PLAYER: for (PlayerInstance player : PLAYERS)
{
if ((player == null) || player.isAlikeDead() || (player.isOnlineInt() != 1) || (!Config.AUTO_POTIONS_IN_OLYMPIAD && player.isInOlympiadMode()))
{
return;
remove(player);
continue PLAYER;
}
_working = true;
PLAYER: for (PlayerInstance player : PLAYERS)
boolean success = false;
if (Config.AUTO_HP_ENABLED)
{
if ((player == null) || player.isAlikeDead() || (player.isOnlineInt() != 1) || (!Config.AUTO_POTIONS_IN_OLYMPIAD && player.isInOlympiadMode()))
final boolean restoreHP = ((player.getStatus().getCurrentHp() / player.getMaxHp()) * 100) < Config.AUTO_HP_PERCENTAGE;
HP: for (int itemId : Config.AUTO_HP_ITEM_IDS)
{
remove(player);
continue PLAYER;
}
boolean success = false;
if (Config.AUTO_HP_ENABLED)
{
final boolean restoreHP = ((player.getStatus().getCurrentHp() / player.getMaxHp()) * 100) < Config.AUTO_HP_PERCENTAGE;
HP: for (int itemId : Config.AUTO_HP_ITEM_IDS)
final ItemInstance hpPotion = player.getInventory().getItemByItemId(itemId);
if ((hpPotion != null) && (hpPotion.getCount() > 0))
{
final ItemInstance hpPotion = player.getInventory().getItemByItemId(itemId);
if ((hpPotion != null) && (hpPotion.getCount() > 0))
success = true;
if (restoreHP)
{
success = true;
if (restoreHP)
{
ItemHandler.getInstance().getHandler(hpPotion.getEtcItem()).useItem(player, hpPotion, false);
player.sendMessage("Auto potion: Restored HP.");
break HP;
}
ItemHandler.getInstance().getHandler(hpPotion.getEtcItem()).useItem(player, hpPotion, false);
player.sendMessage("Auto potion: Restored HP.");
break HP;
}
}
}
if (Config.AUTO_CP_ENABLED)
}
if (Config.AUTO_CP_ENABLED)
{
final boolean restoreCP = ((player.getStatus().getCurrentCp() / player.getMaxCp()) * 100) < Config.AUTO_CP_PERCENTAGE;
CP: for (int itemId : Config.AUTO_CP_ITEM_IDS)
{
final boolean restoreCP = ((player.getStatus().getCurrentCp() / player.getMaxCp()) * 100) < Config.AUTO_CP_PERCENTAGE;
CP: for (int itemId : Config.AUTO_CP_ITEM_IDS)
final ItemInstance cpPotion = player.getInventory().getItemByItemId(itemId);
if ((cpPotion != null) && (cpPotion.getCount() > 0))
{
final ItemInstance cpPotion = player.getInventory().getItemByItemId(itemId);
if ((cpPotion != null) && (cpPotion.getCount() > 0))
success = true;
if (restoreCP)
{
success = true;
if (restoreCP)
{
ItemHandler.getInstance().getHandler(cpPotion.getEtcItem()).useItem(player, cpPotion, false);
player.sendMessage("Auto potion: Restored CP.");
break CP;
}
ItemHandler.getInstance().getHandler(cpPotion.getEtcItem()).useItem(player, cpPotion, false);
player.sendMessage("Auto potion: Restored CP.");
break CP;
}
}
}
if (Config.AUTO_MP_ENABLED)
}
if (Config.AUTO_MP_ENABLED)
{
final boolean restoreMP = ((player.getStatus().getCurrentMp() / player.getMaxMp()) * 100) < Config.AUTO_MP_PERCENTAGE;
MP: for (int itemId : Config.AUTO_MP_ITEM_IDS)
{
final boolean restoreMP = ((player.getStatus().getCurrentMp() / player.getMaxMp()) * 100) < Config.AUTO_MP_PERCENTAGE;
MP: for (int itemId : Config.AUTO_MP_ITEM_IDS)
final ItemInstance mpPotion = player.getInventory().getItemByItemId(itemId);
if ((mpPotion != null) && (mpPotion.getCount() > 0))
{
final ItemInstance mpPotion = player.getInventory().getItemByItemId(itemId);
if ((mpPotion != null) && (mpPotion.getCount() > 0))
success = true;
if (restoreMP)
{
success = true;
if (restoreMP)
{
ItemHandler.getInstance().getHandler(mpPotion.getEtcItem()).useItem(player, mpPotion, false);
player.sendMessage("Auto potion: Restored MP.");
break MP;
}
ItemHandler.getInstance().getHandler(mpPotion.getEtcItem()).useItem(player, mpPotion, false);
player.sendMessage("Auto potion: Restored MP.");
break MP;
}
}
}
if (!success)
{
player.sendMessage("Auto potion: You are out of potions!");
}
}
_working = false;
}, 0, 1000);
if (!success)
{
player.sendMessage("Auto potion: You are out of potions!");
}
}
_working = false;
}
public void add(PlayerInstance player)

View File

@@ -51,257 +51,260 @@ import org.l2jmobius.gameserver.network.serverpackets.ExBasicActionList;
/**
* @author Mobius
*/
public class AutoUseTaskManager
public class AutoUseTaskManager implements Runnable
{
private static final Set<PlayerInstance> PLAYERS = ConcurrentHashMap.newKeySet();
private static boolean _working = false;
public AutoUseTaskManager()
protected AutoUseTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
ThreadPool.scheduleAtFixedRate(this, 1000, 1000);
}
@Override
public void run()
{
if (_working)
{
if (_working)
return;
}
_working = true;
for (PlayerInstance player : PLAYERS)
{
if (!player.isOnline() || player.isInOfflineMode())
{
return;
stopAutoUseTask(player);
continue;
}
_working = true;
for (PlayerInstance player : PLAYERS)
if (player.hasBlockActions() || player.isControlBlocked() || player.isAlikeDead())
{
if (!player.isOnline() || player.isInOfflineMode())
continue;
}
final boolean isInPeaceZone = player.isInsideZone(ZoneId.PEACE);
if (Config.ENABLE_AUTO_ITEM && !isInPeaceZone)
{
ITEMS: for (Integer itemId : player.getAutoUseSettings().getAutoSupplyItems())
{
stopAutoUseTask(player);
continue;
}
if (player.hasBlockActions() || player.isControlBlocked() || player.isAlikeDead())
{
continue;
}
final boolean isInPeaceZone = player.isInsideZone(ZoneId.PEACE);
if (Config.ENABLE_AUTO_ITEM && !isInPeaceZone)
{
ITEMS: for (Integer itemId : player.getAutoUseSettings().getAutoSupplyItems())
final ItemInstance item = player.getInventory().getItemByItemId(itemId.intValue());
if (item == null)
{
final ItemInstance item = player.getInventory().getItemByItemId(itemId.intValue());
if (item == null)
player.getAutoUseSettings().getAutoSupplyItems().remove(itemId);
continue ITEMS;
}
final Item it = item.getItem();
if (it != null)
{
if (!it.checkCondition(player, player, false))
{
player.getAutoUseSettings().getAutoSupplyItems().remove(itemId);
continue ITEMS;
}
final Item it = item.getItem();
if (it != null)
final List<ItemSkillHolder> skills = it.getAllSkills();
if (skills != null)
{
if (!it.checkCondition(player, player, false))
for (ItemSkillHolder itemSkillHolder : skills)
{
continue ITEMS;
}
final List<ItemSkillHolder> skills = it.getAllSkills();
if (skills != null)
{
for (ItemSkillHolder itemSkillHolder : skills)
final Skill skill = itemSkillHolder.getSkill();
if (player.isAffectedBySkill(skill.getId()) || player.hasSkillReuse(skill.getReuseHashCode()) || !skill.checkCondition(player, player, false))
{
final Skill skill = itemSkillHolder.getSkill();
if (player.isAffectedBySkill(skill.getId()) || player.hasSkillReuse(skill.getReuseHashCode()) || !skill.checkCondition(player, player, false))
{
continue ITEMS;
}
continue ITEMS;
}
}
}
final int reuseDelay = item.getReuseDelay();
if ((reuseDelay <= 0) || (player.getItemRemainingReuseTime(item.getObjectId()) <= 0))
{
final EtcItem etcItem = item.getEtcItem();
final IItemHandler handler = ItemHandler.getInstance().getHandler(etcItem);
if ((handler != null) && handler.useItem(player, item, false) && (reuseDelay > 0))
{
player.addTimeStampItem(item, reuseDelay);
}
}
}
}
if (Config.ENABLE_AUTO_POTION && !isInPeaceZone && (player.getCurrentHpPercent() <= player.getAutoPlaySettings().getAutoPotionPercent()))
{
POTIONS: for (Integer itemId : player.getAutoUseSettings().getAutoPotionItems())
{
final ItemInstance item = player.getInventory().getItemByItemId(itemId.intValue());
if (item == null)
{
player.getAutoUseSettings().getAutoPotionItems().remove(itemId);
continue POTIONS;
}
final int reuseDelay = item.getReuseDelay();
if ((reuseDelay <= 0) || (player.getItemRemainingReuseTime(item.getObjectId()) <= 0))
{
final EtcItem etcItem = item.getEtcItem();
final IItemHandler handler = ItemHandler.getInstance().getHandler(etcItem);
if ((handler != null) && handler.useItem(player, item, false) && (reuseDelay > 0))
{
player.addTimeStampItem(item, reuseDelay);
}
}
}
}
if (Config.ENABLE_AUTO_SKILL)
{
BUFFS: for (Integer skillId : player.getAutoUseSettings().getAutoSkills())
{
// Fixes start area issue.
if (isInPeaceZone)
{
break BUFFS;
}
// Already casting.
if (player.isCastingNow())
{
break BUFFS;
}
// Player is teleporting.
if (player.isTeleporting())
{
break BUFFS;
}
final Skill skill = player.getKnownSkill(skillId.intValue());
if (skill == null)
{
player.getAutoUseSettings().getAutoSkills().remove(skillId);
continue BUFFS;
}
// Not a buff.
if (skill.isBad())
{
continue BUFFS;
}
final WorldObject target = player.getTarget();
if (canCastBuff(player, target, skill))
{
// Playable target cast.
if ((target != null) && target.isPlayable())
{
player.doCast(skill);
}
else // Target self, cast and re-target.
{
final WorldObject savedTarget = target;
player.setTarget(player);
player.doCast(skill);
player.setTarget(savedTarget);
}
}
}
// Continue when auto play is not enabled.
if (!AutoPlayTaskManager.getInstance().isAutoPlay(player))
final int reuseDelay = item.getReuseDelay();
if ((reuseDelay <= 0) || (player.getItemRemainingReuseTime(item.getObjectId()) <= 0))
{
continue;
}
SKILLS: for (Integer skillId : player.getAutoUseSettings().getAutoSkills())
{
// Already casting.
if (player.isCastingNow())
final EtcItem etcItem = item.getEtcItem();
final IItemHandler handler = ItemHandler.getInstance().getHandler(etcItem);
if ((handler != null) && handler.useItem(player, item, false) && (reuseDelay > 0))
{
break SKILLS;
}
// Player is teleporting.
if (player.isTeleporting())
{
break SKILLS;
}
final Skill skill = player.getKnownSkill(skillId.intValue());
if (skill == null)
{
player.getAutoUseSettings().getAutoSkills().remove(skillId);
continue SKILLS;
}
// Not an offensive skill.
if (!skill.isBad())
{
continue SKILLS;
}
// Casting on self stops movement.
final WorldObject target = player.getTarget();
if (target == player)
{
continue SKILLS;
}
// Check bad skill target.
if ((target == null) || !target.isAttackable())
{
continue SKILLS;
}
// Do not attack guards.
if (target instanceof GuardInstance)
{
continue SKILLS;
}
if (canUseMagic(player, target, skill))
{
player.useMagic(skill, null, true, false);
}
}
ACTIONS: for (Integer actionId : player.getAutoUseSettings().getAutoActions())
{
final BuffInfo info = player.getEffectList().getFirstBuffInfoByAbnormalType(AbnormalType.BOT_PENALTY);
if (info != null)
{
for (AbstractEffect effect : info.getEffects())
{
if (!effect.checkCondition(actionId))
{
player.sendPacket(SystemMessageId.YOU_HAVE_BEEN_REPORTED_AS_AN_ILLEGAL_PROGRAM_USER_SO_YOUR_ACTIONS_HAVE_BEEN_RESTRICTED);
break ACTIONS;
}
}
}
// Do not allow to do some action if player is transformed.
if (player.isTransformed())
{
final int[] allowedActions = player.isTransformed() ? ExBasicActionList.ACTIONS_ON_TRANSFORM : ExBasicActionList.DEFAULT_ACTION_LIST;
if (Arrays.binarySearch(allowedActions, actionId) < 0)
{
continue ACTIONS;
}
}
final ActionDataHolder actionHolder = ActionData.getInstance().getActionData(actionId);
if (actionHolder != null)
{
final IPlayerActionHandler actionHandler = PlayerActionHandler.getInstance().getHandler(actionHolder.getHandler());
if (actionHandler != null)
{
actionHandler.useAction(player, actionHolder, false, false);
}
player.addTimeStampItem(item, reuseDelay);
}
}
}
}
_working = false;
}, 1000, 1000);
if (Config.ENABLE_AUTO_POTION && !isInPeaceZone && (player.getCurrentHpPercent() <= player.getAutoPlaySettings().getAutoPotionPercent()))
{
POTIONS: for (Integer itemId : player.getAutoUseSettings().getAutoPotionItems())
{
final ItemInstance item = player.getInventory().getItemByItemId(itemId.intValue());
if (item == null)
{
player.getAutoUseSettings().getAutoPotionItems().remove(itemId);
continue POTIONS;
}
final int reuseDelay = item.getReuseDelay();
if ((reuseDelay <= 0) || (player.getItemRemainingReuseTime(item.getObjectId()) <= 0))
{
final EtcItem etcItem = item.getEtcItem();
final IItemHandler handler = ItemHandler.getInstance().getHandler(etcItem);
if ((handler != null) && handler.useItem(player, item, false) && (reuseDelay > 0))
{
player.addTimeStampItem(item, reuseDelay);
}
}
}
}
if (Config.ENABLE_AUTO_SKILL)
{
BUFFS: for (Integer skillId : player.getAutoUseSettings().getAutoSkills())
{
// Fixes start area issue.
if (isInPeaceZone)
{
break BUFFS;
}
// Already casting.
if (player.isCastingNow())
{
break BUFFS;
}
// Player is teleporting.
if (player.isTeleporting())
{
break BUFFS;
}
final Skill skill = player.getKnownSkill(skillId.intValue());
if (skill == null)
{
player.getAutoUseSettings().getAutoSkills().remove(skillId);
continue BUFFS;
}
// Not a buff.
if (skill.isBad())
{
continue BUFFS;
}
final WorldObject target = player.getTarget();
if (canCastBuff(player, target, skill))
{
// Playable target cast.
if ((target != null) && target.isPlayable())
{
player.doCast(skill);
}
else // Target self, cast and re-target.
{
final WorldObject savedTarget = target;
player.setTarget(player);
player.doCast(skill);
player.setTarget(savedTarget);
}
}
}
// Continue when auto play is not enabled.
if (!AutoPlayTaskManager.getInstance().isAutoPlay(player))
{
continue;
}
SKILLS: for (Integer skillId : player.getAutoUseSettings().getAutoSkills())
{
// Already casting.
if (player.isCastingNow())
{
break SKILLS;
}
// Player is teleporting.
if (player.isTeleporting())
{
break SKILLS;
}
final Skill skill = player.getKnownSkill(skillId.intValue());
if (skill == null)
{
player.getAutoUseSettings().getAutoSkills().remove(skillId);
continue SKILLS;
}
// Not an offensive skill.
if (!skill.isBad())
{
continue SKILLS;
}
// Casting on self stops movement.
final WorldObject target = player.getTarget();
if (target == player)
{
continue SKILLS;
}
// Check bad skill target.
if ((target == null) || !target.isAttackable())
{
continue SKILLS;
}
// Do not attack guards.
if (target instanceof GuardInstance)
{
continue SKILLS;
}
if (canUseMagic(player, target, skill))
{
player.useMagic(skill, null, true, false);
}
}
ACTIONS: for (Integer actionId : player.getAutoUseSettings().getAutoActions())
{
final BuffInfo info = player.getEffectList().getFirstBuffInfoByAbnormalType(AbnormalType.BOT_PENALTY);
if (info != null)
{
for (AbstractEffect effect : info.getEffects())
{
if (!effect.checkCondition(actionId))
{
player.sendPacket(SystemMessageId.YOU_HAVE_BEEN_REPORTED_AS_AN_ILLEGAL_PROGRAM_USER_SO_YOUR_ACTIONS_HAVE_BEEN_RESTRICTED);
break ACTIONS;
}
}
}
// Do not allow to do some action if player is transformed.
if (player.isTransformed())
{
final int[] allowedActions = player.isTransformed() ? ExBasicActionList.ACTIONS_ON_TRANSFORM : ExBasicActionList.DEFAULT_ACTION_LIST;
if (Arrays.binarySearch(allowedActions, actionId) < 0)
{
continue ACTIONS;
}
}
final ActionDataHolder actionHolder = ActionData.getInstance().getActionData(actionId);
if (actionHolder != null)
{
final IPlayerActionHandler actionHandler = PlayerActionHandler.getInstance().getHandler(actionHolder.getHandler());
if (actionHandler != null)
{
actionHandler.useAction(player, actionHolder, false, false);
}
}
}
}
}
_working = false;
}
private boolean canCastBuff(PlayerInstance player, WorldObject target, Skill skill)

View File

@@ -36,9 +36,16 @@ public class BuyListTaskManager
private static boolean _workingProducts = false;
private static boolean _workingSaves = false;
public BuyListTaskManager()
protected BuyListTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
ThreadPool.scheduleAtFixedRate(new BuyListProductTask(), 1000, 60000);
ThreadPool.scheduleAtFixedRate(new BuyListSaveTask(), 50, 50);
}
protected class BuyListProductTask implements Runnable
{
@Override
public void run()
{
if (_workingProducts)
{
@@ -64,9 +71,13 @@ public class BuyListTaskManager
}
_workingProducts = false;
}, 1000, 60000);
ThreadPool.scheduleAtFixedRate(() ->
}
}
protected class BuyListSaveTask implements Runnable
{
@Override
public void run()
{
if (_workingSaves)
{
@@ -86,7 +97,7 @@ public class BuyListTaskManager
}
_workingSaves = false;
}, 50, 50);
}
}
public void add(Product product, long endTime)

View File

@@ -40,9 +40,16 @@ public class CreatureFollowTaskManager
private static boolean _workingNormal = false;
private static boolean _workingAttack = false;
public CreatureFollowTaskManager()
protected CreatureFollowTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
ThreadPool.scheduleAtFixedRate(new CreatureFollowNormalTask(), 1000, 1000);
ThreadPool.scheduleAtFixedRate(new CreatureFollowAttackTask(), 500, 500);
}
protected class CreatureFollowNormalTask implements Runnable
{
@Override
public void run()
{
if (_workingNormal)
{
@@ -56,9 +63,13 @@ public class CreatureFollowTaskManager
}
_workingNormal = false;
}, 1000, 1000);
ThreadPool.scheduleAtFixedRate(() ->
}
}
protected class CreatureFollowAttackTask implements Runnable
{
@Override
public void run()
{
if (_workingAttack)
{
@@ -72,7 +83,7 @@ public class CreatureFollowTaskManager
}
_workingAttack = false;
}, 500, 500);
}
}
private void follow(Creature creature, int range)

View File

@@ -25,28 +25,31 @@ import org.l2jmobius.gameserver.model.actor.Creature;
/**
* @author Mobius
*/
public class CreatureSeeTaskManager
public class CreatureSeeTaskManager implements Runnable
{
private static final Set<Creature> CREATURES = ConcurrentHashMap.newKeySet();
private static boolean _working = false;
public CreatureSeeTaskManager()
protected CreatureSeeTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
ThreadPool.scheduleAtFixedRate(this, 1000, 1000);
}
@Override
public void run()
{
if (_working)
{
if (_working)
{
return;
}
_working = true;
for (Creature creature : CREATURES)
{
creature.updateSeenCreatures();
}
_working = false;
}, 1000, 1000);
return;
}
_working = true;
for (Creature creature : CREATURES)
{
creature.updateSeenCreatures();
}
_working = false;
}
public void add(Creature creature)

View File

@@ -30,34 +30,37 @@ import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate;
/**
* @author Mobius
*/
public class DecayTaskManager
public class DecayTaskManager implements Runnable
{
private static final Map<Creature, Long> DECAY_SCHEDULES = new ConcurrentHashMap<>();
private static boolean _working = false;
public DecayTaskManager()
protected DecayTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
ThreadPool.scheduleAtFixedRate(this, 0, 1000);
}
@Override
public void run()
{
if (_working)
{
if (_working)
return;
}
_working = true;
final long time = Chronos.currentTimeMillis();
for (Entry<Creature, Long> entry : DECAY_SCHEDULES.entrySet())
{
if (time > entry.getValue().longValue())
{
return;
final Creature creature = entry.getKey();
DECAY_SCHEDULES.remove(creature);
creature.onDecay();
}
_working = true;
final long time = Chronos.currentTimeMillis();
for (Entry<Creature, Long> entry : DECAY_SCHEDULES.entrySet())
{
if (time > entry.getValue().longValue())
{
final Creature creature = entry.getKey();
DECAY_SCHEDULES.remove(creature);
creature.onDecay();
}
}
_working = false;
}, 0, 1000);
}
_working = false;
}
/**

View File

@@ -27,34 +27,37 @@ import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemAppearanceTaskManager
public class ItemAppearanceTaskManager implements Runnable
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemAppearanceTaskManager()
protected ItemAppearanceTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
ThreadPool.scheduleAtFixedRate(this, 1000, 1000);
}
@Override
public void run()
{
if (_working)
{
if (_working)
return;
}
_working = true;
final long currentTime = Chronos.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
return;
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.onVisualLifeTimeEnd();
}
_working = true;
final long currentTime = Chronos.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.onVisualLifeTimeEnd();
}
}
_working = false;
}, 1000, 1000);
}
_working = false;
}
public void add(ItemInstance item, long endTime)

View File

@@ -27,34 +27,37 @@ import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemLifeTimeTaskManager
public class ItemLifeTimeTaskManager implements Runnable
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemLifeTimeTaskManager()
protected ItemLifeTimeTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
ThreadPool.scheduleAtFixedRate(this, 1000, 1000);
}
@Override
public void run()
{
if (_working)
{
if (_working)
return;
}
_working = true;
final long currentTime = Chronos.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
return;
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.endOfLife();
}
_working = true;
final long currentTime = Chronos.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.endOfLife();
}
}
_working = false;
}, 1000, 1000);
}
_working = false;
}
public void add(ItemInstance item, long endTime)

View File

@@ -27,35 +27,38 @@ import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemManaTaskManager
public class ItemManaTaskManager implements Runnable
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static final int MANA_CONSUMPTION_RATE = 60000;
private static boolean _working = false;
public ItemManaTaskManager()
protected ItemManaTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
ThreadPool.scheduleAtFixedRate(this, 1000, 1000);
}
@Override
public void run()
{
if (_working)
{
if (_working)
return;
}
_working = true;
final long currentTime = Chronos.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
return;
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.decreaseMana(true);
}
_working = true;
final long currentTime = Chronos.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.decreaseMana(true);
}
}
_working = false;
}, 1000, 1000);
}
_working = false;
}
public void add(ItemInstance item)

View File

@@ -16,9 +16,8 @@
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
@@ -27,22 +26,17 @@ import org.l2jmobius.gameserver.enums.ItemLocation;
import org.l2jmobius.gameserver.instancemanager.ItemsOnGroundManager;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
public class ItemsAutoDestroyTaskManager
public class ItemsAutoDestroyTaskManager implements Runnable
{
private final List<ItemInstance> _items = new LinkedList<>();
private final Set<ItemInstance> _items = ConcurrentHashMap.newKeySet();
protected ItemsAutoDestroyTaskManager()
{
ThreadPool.scheduleAtFixedRate(this::removeItems, 5000, 5000);
ThreadPool.scheduleAtFixedRate(this, 5000, 5000);
}
public synchronized void addItem(ItemInstance item)
{
item.setDropTime(Chronos.currentTimeMillis());
_items.add(item);
}
private synchronized void removeItems()
@Override
public void run()
{
if (_items.isEmpty())
{
@@ -50,13 +44,11 @@ public class ItemsAutoDestroyTaskManager
}
final long curtime = Chronos.currentTimeMillis();
final Iterator<ItemInstance> itemIterator = _items.iterator();
while (itemIterator.hasNext())
for (ItemInstance item : _items)
{
final ItemInstance item = itemIterator.next();
if ((item.getDropTime() == 0) || (item.getItemLocation() != ItemLocation.VOID))
{
itemIterator.remove();
_items.remove(item);
}
else
{
@@ -77,7 +69,7 @@ public class ItemsAutoDestroyTaskManager
if ((curtime - item.getDropTime()) > autoDestroyTime)
{
item.decayMe();
itemIterator.remove();
_items.remove(item);
if (Config.SAVE_DROPPED_ITEM)
{
ItemsOnGroundManager.getInstance().removeObject(item);
@@ -87,6 +79,12 @@ public class ItemsAutoDestroyTaskManager
}
}
public void addItem(ItemInstance item)
{
item.setDropTime(Chronos.currentTimeMillis());
_items.add(item);
}
public static ItemsAutoDestroyTaskManager getInstance()
{
return SingletonHolder.INSTANCE;

View File

@@ -32,65 +32,68 @@ import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
/**
* @author Mobius
*/
public class MessageDeletionTaskManager
public class MessageDeletionTaskManager implements Runnable
{
private static final Map<Integer, Long> PENDING_MESSAGES = new ConcurrentHashMap<>();
private static boolean _working = false;
public MessageDeletionTaskManager()
protected MessageDeletionTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
ThreadPool.scheduleAtFixedRate(this, 10000, 10000);
}
@Override
public void run()
{
if (_working)
{
if (_working)
return;
}
_working = true;
Integer msgId;
Message msg;
final long time = Chronos.currentTimeMillis();
for (Entry<Integer, Long> entry : PENDING_MESSAGES.entrySet())
{
if (time > entry.getValue().longValue())
{
return;
}
_working = true;
Integer msgId;
Message msg;
final long time = Chronos.currentTimeMillis();
for (Entry<Integer, Long> entry : PENDING_MESSAGES.entrySet())
{
if (time > entry.getValue().longValue())
msgId = entry.getKey();
msg = MailManager.getInstance().getMessage(msgId.intValue());
if (msg == null)
{
msgId = entry.getKey();
msg = MailManager.getInstance().getMessage(msgId.intValue());
if (msg == null)
{
PENDING_MESSAGES.remove(msgId);
return;
}
if (msg.hasAttachments())
{
final PlayerInstance sender = World.getInstance().getPlayer(msg.getSenderId());
if (sender != null)
{
msg.getAttachments().returnToWh(sender.getWarehouse());
sender.sendPacket(SystemMessageId.THE_MAIL_WAS_RETURNED_DUE_TO_THE_EXCEEDED_WAITING_TIME);
}
else
{
msg.getAttachments().returnToWh(null);
}
msg.getAttachments().deleteMe();
msg.removeAttachments();
final PlayerInstance receiver = World.getInstance().getPlayer(msg.getReceiverId());
if (receiver != null)
{
receiver.sendPacket(new SystemMessage(SystemMessageId.THE_MAIL_WAS_RETURNED_DUE_TO_THE_EXCEEDED_WAITING_TIME));
}
}
MailManager.getInstance().deleteMessageInDb(msgId.intValue());
PENDING_MESSAGES.remove(msgId);
return;
}
if (msg.hasAttachments())
{
final PlayerInstance sender = World.getInstance().getPlayer(msg.getSenderId());
if (sender != null)
{
msg.getAttachments().returnToWh(sender.getWarehouse());
sender.sendPacket(SystemMessageId.THE_MAIL_WAS_RETURNED_DUE_TO_THE_EXCEEDED_WAITING_TIME);
}
else
{
msg.getAttachments().returnToWh(null);
}
msg.getAttachments().deleteMe();
msg.removeAttachments();
final PlayerInstance receiver = World.getInstance().getPlayer(msg.getReceiverId());
if (receiver != null)
{
receiver.sendPacket(new SystemMessage(SystemMessageId.THE_MAIL_WAS_RETURNED_DUE_TO_THE_EXCEEDED_WAITING_TIME));
}
}
MailManager.getInstance().deleteMessageInDb(msgId.intValue());
PENDING_MESSAGES.remove(msgId);
}
_working = false;
}, 10000, 10000);
}
_working = false;
}
public void add(int msgId, long deletionTime)

View File

@@ -28,38 +28,41 @@ import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
/**
* @author Mobius
*/
public class PlayerAutoSaveTaskManager
public class PlayerAutoSaveTaskManager implements Runnable
{
private static final Map<PlayerInstance, Long> PLAYER_TIMES = new ConcurrentHashMap<>();
private static boolean _working = false;
public PlayerAutoSaveTaskManager()
protected PlayerAutoSaveTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
ThreadPool.scheduleAtFixedRate(this, 1000, 1000);
}
@Override
public void run()
{
if (_working)
{
if (_working)
return;
}
_working = true;
final long time = Chronos.currentTimeMillis();
SEARCH: for (Entry<PlayerInstance, Long> entry : PLAYER_TIMES.entrySet())
{
if (time > entry.getValue().longValue())
{
return;
}
_working = true;
final long time = Chronos.currentTimeMillis();
SEARCH: for (Entry<PlayerInstance, Long> entry : PLAYER_TIMES.entrySet())
{
if (time > entry.getValue().longValue())
final PlayerInstance player = entry.getKey();
if ((player != null) && player.isOnline())
{
final PlayerInstance player = entry.getKey();
if ((player != null) && player.isOnline())
{
player.autoSave();
PLAYER_TIMES.put(entry.getKey(), time + Config.CHAR_DATA_STORE_INTERVAL);
break SEARCH; // Prevent SQL flood.
}
player.autoSave();
PLAYER_TIMES.put(entry.getKey(), time + Config.CHAR_DATA_STORE_INTERVAL);
break SEARCH; // Prevent SQL flood.
}
}
_working = false;
}, 1000, 1000);
}
_working = false;
}
public void add(PlayerInstance player)

View File

@@ -26,43 +26,46 @@ import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
/**
* @author Mobius
*/
public class PvpFlagTaskManager
public class PvpFlagTaskManager implements Runnable
{
private static final Set<PlayerInstance> PLAYERS = ConcurrentHashMap.newKeySet();
private static boolean _working = false;
public PvpFlagTaskManager()
protected PvpFlagTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
ThreadPool.scheduleAtFixedRate(this, 1000, 1000);
}
@Override
public void run()
{
if (_working)
{
if (_working)
return;
}
_working = true;
if (!PLAYERS.isEmpty())
{
final long time = Chronos.currentTimeMillis();
for (PlayerInstance player : PLAYERS)
{
return;
}
_working = true;
if (!PLAYERS.isEmpty())
{
final long time = Chronos.currentTimeMillis();
for (PlayerInstance player : PLAYERS)
if (time > player.getPvpFlagLasts())
{
if (time > player.getPvpFlagLasts())
{
player.stopPvPFlag();
}
else if (time > (player.getPvpFlagLasts() - 20000))
{
player.updatePvPFlag(2);
}
else
{
player.updatePvPFlag(1);
}
player.stopPvPFlag();
}
else if (time > (player.getPvpFlagLasts() - 20000))
{
player.updatePvPFlag(2);
}
else
{
player.updatePvPFlag(1);
}
}
_working = false;
}, 1000, 1000);
}
_working = false;
}
public void add(PlayerInstance player)

View File

@@ -29,37 +29,40 @@ import org.l2jmobius.gameserver.model.actor.Npc;
/**
* @author Mobius
*/
public class RandomAnimationTaskManager
public class RandomAnimationTaskManager implements Runnable
{
private static final Map<Npc, Long> PENDING_ANIMATIONS = new ConcurrentHashMap<>();
private static boolean _working = false;
public RandomAnimationTaskManager()
protected RandomAnimationTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
ThreadPool.scheduleAtFixedRate(this, 0, 1000);
}
@Override
public void run()
{
if (_working)
{
if (_working)
return;
}
_working = true;
final long time = Chronos.currentTimeMillis();
for (Entry<Npc, Long> entry : PENDING_ANIMATIONS.entrySet())
{
if (time > entry.getValue().longValue())
{
return;
}
_working = true;
final long time = Chronos.currentTimeMillis();
for (Entry<Npc, Long> entry : PENDING_ANIMATIONS.entrySet())
{
if (time > entry.getValue().longValue())
final Npc npc = entry.getKey();
if (npc.isInActiveRegion() && !npc.isDead() && !npc.isInCombat() && !npc.isMoving() && !npc.hasBlockActions())
{
final Npc npc = entry.getKey();
if (npc.isInActiveRegion() && !npc.isDead() && !npc.isInCombat() && !npc.isMoving() && !npc.hasBlockActions())
{
npc.onRandomAnimation(Rnd.get(2, 3));
}
PENDING_ANIMATIONS.put(npc, time + (Rnd.get((npc.isAttackable() ? Config.MIN_MONSTER_ANIMATION : Config.MIN_NPC_ANIMATION), (npc.isAttackable() ? Config.MAX_MONSTER_ANIMATION : Config.MAX_NPC_ANIMATION)) * 1000));
npc.onRandomAnimation(Rnd.get(2, 3));
}
PENDING_ANIMATIONS.put(npc, time + (Rnd.get((npc.isAttackable() ? Config.MIN_MONSTER_ANIMATION : Config.MIN_NPC_ANIMATION), (npc.isAttackable() ? Config.MAX_MONSTER_ANIMATION : Config.MAX_NPC_ANIMATION)) * 1000));
}
_working = false;
}, 0, 1000);
}
_working = false;
}
public void add(Npc npc)

View File

@@ -28,39 +28,42 @@ import org.l2jmobius.gameserver.model.actor.Npc;
/**
* @author Mobius
*/
public class RespawnTaskManager
public class RespawnTaskManager implements Runnable
{
private static final Map<Npc, Long> PENDING_RESPAWNS = new ConcurrentHashMap<>();
private static boolean _working = false;
public RespawnTaskManager()
protected RespawnTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
ThreadPool.scheduleAtFixedRate(this, 0, 1000);
}
@Override
public void run()
{
if (_working)
{
if (_working)
return;
}
_working = true;
final long time = Chronos.currentTimeMillis();
for (Entry<Npc, Long> entry : PENDING_RESPAWNS.entrySet())
{
if (time > entry.getValue().longValue())
{
return;
}
_working = true;
final long time = Chronos.currentTimeMillis();
for (Entry<Npc, Long> entry : PENDING_RESPAWNS.entrySet())
{
if (time > entry.getValue().longValue())
final Npc npc = entry.getKey();
PENDING_RESPAWNS.remove(npc);
final Spawn spawn = npc.getSpawn();
if (spawn != null)
{
final Npc npc = entry.getKey();
PENDING_RESPAWNS.remove(npc);
final Spawn spawn = npc.getSpawn();
if (spawn != null)
{
spawn.respawnNpc(npc);
spawn._scheduledCount--;
}
spawn.respawnNpc(npc);
spawn._scheduledCount--;
}
}
_working = false;
}, 0, 1000);
}
_working = false;
}
public void add(Npc npc, long time)