AttackEndTime rework and proper MovementTaskManager comments.
This commit is contained in:
parent
739e49bd8e
commit
8c4fff7541
@ -310,9 +310,11 @@ public class CreatureAI extends AbstractAI
|
||||
return;
|
||||
}
|
||||
|
||||
if (_actor.isAttackingNow())
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = _actor.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), _actor.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1176,7 +1176,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
final boolean isTwoHanded = (weaponItem != null) && (weaponItem.getBodyPart() == ItemTemplate.SLOT_LR_HAND);
|
||||
final int timeAtk = Formulas.calculateTimeBetweenAttacks(_stat.getPAtkSpd());
|
||||
final int timeToHit = Formulas.calculateTimeToHit(timeAtk, weaponType, isTwoHanded, false);
|
||||
_attackEndTime = System.nanoTime() + (TimeUnit.MILLISECONDS.toNanos(timeAtk));
|
||||
final long currentTime = System.nanoTime();
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
// Precaution. It has happened in the past. Probably impossible to happen now, but will not risk it.
|
||||
if (_attackEndTime < currentTime)
|
||||
{
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
// Make sure that char is facing selected target
|
||||
// also works: setHeading(Util.convertDegreeToClientHeading(Util.calculateAngleFrom(this, target)));
|
||||
@ -1225,7 +1231,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
}
|
||||
|
||||
// Calculate and set the disable delay of the bow in function of the Attack Speed
|
||||
_disableRangedAttackEndTime = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
// Precaution. It happened in the past for _attackEndTime. Will not risk it.
|
||||
if (_disableRangedAttackEndTime < currentTime)
|
||||
{
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
_hitTask = ThreadPool.schedule(() -> onHitTimeNotDual(weaponItem, attack, timeToHit, timeAtk), timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -3345,13 +3356,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// called from AIAccessor only
|
||||
|
||||
/**
|
||||
* Calculate movement data for a move to location action and add the Creature to movingObjects of GameTimeTaskManager (only called by AI Accessor).<br>
|
||||
* Calculate movement data for a move to location action and add the Creature to MOVING_OBJECTS of MovementTaskManager (only called by AI Accessor).<br>
|
||||
* <br>
|
||||
* <b><u>Concept</u>:</b><br>
|
||||
* <br>
|
||||
* At the beginning of the move action, all properties of the movement are stored in the MoveData object called <b>_move</b> of the Creature.<br>
|
||||
* The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<br>
|
||||
* All Creature in movement are identified in <b>movingObjects</b> of GameTimeTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* All Creature in movement are identified in <b>MOVING_OBJECTS</b> of MovementTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* <br>
|
||||
* <b><u>Actions</u>:</b>
|
||||
* <ul>
|
||||
@ -3359,7 +3370,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
* <li>Calculate distance (dx,dy) between current position and destination including offset</li>
|
||||
* <li>Create and Init a MoveData object</li>
|
||||
* <li>Set the Creature _move object to MoveData object</li>
|
||||
* <li>Add the Creature to movingObjects of the GameTimeTaskManager</li>
|
||||
* <li>Add the Creature to MOVING_OBJECTS of the MovementTaskManager</li>
|
||||
* <li>Create a task to notify the AI that Creature arrives at a check point of the movement</li>
|
||||
* </ul>
|
||||
* <font color=#FF0000><b><u>Caution</u>: This method DOESN'T send Server->Client packet MoveToPawn/MoveToLocation.</b></font><br>
|
||||
@ -3665,7 +3676,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
}
|
||||
|
||||
public boolean moveToNextRoutePoint()
|
||||
@ -3735,7 +3746,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// Set the Creature _move object to MoveData object
|
||||
_move = m;
|
||||
|
||||
// Add the Creature to moving objects of the GameTimeTaskManager.
|
||||
// Add the Creature to moving objects of the MovementTaskManager.
|
||||
// The MovementTaskManager manages object movement.
|
||||
MovementTaskManager.getInstance().registerMovingObject(this);
|
||||
|
||||
@ -3745,8 +3756,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
|
||||
// to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
|
||||
// Send a Server->Client packet MoveToLocation to the actor and all Player in its _knownPlayers
|
||||
broadcastMoveToLocation();
|
||||
|
@ -259,14 +259,18 @@ public class UseItem implements IClientIncomingPacket
|
||||
// Create and Bind the next action to the AI.
|
||||
player.getAI().setNextAction(new NextAction(CtrlEvent.EVT_FINISH_CASTING, CtrlIntention.AI_INTENTION_CAST, () -> player.useEquippableItem(item, true)));
|
||||
}
|
||||
else if (player.isAttackingNow())
|
||||
else // Equip or unEquip.
|
||||
{
|
||||
// Equip or unEquip.
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), player.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = player.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -310,9 +310,11 @@ public class CreatureAI extends AbstractAI
|
||||
return;
|
||||
}
|
||||
|
||||
if (_actor.isAttackingNow())
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = _actor.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), _actor.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1176,7 +1176,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
final boolean isTwoHanded = (weaponItem != null) && (weaponItem.getBodyPart() == ItemTemplate.SLOT_LR_HAND);
|
||||
final int timeAtk = Formulas.calculateTimeBetweenAttacks(_stat.getPAtkSpd());
|
||||
final int timeToHit = Formulas.calculateTimeToHit(timeAtk, weaponType, isTwoHanded, false);
|
||||
_attackEndTime = System.nanoTime() + (TimeUnit.MILLISECONDS.toNanos(timeAtk));
|
||||
final long currentTime = System.nanoTime();
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
// Precaution. It has happened in the past. Probably impossible to happen now, but will not risk it.
|
||||
if (_attackEndTime < currentTime)
|
||||
{
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
// Make sure that char is facing selected target
|
||||
// also works: setHeading(Util.convertDegreeToClientHeading(Util.calculateAngleFrom(this, target)));
|
||||
@ -1225,7 +1231,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
}
|
||||
|
||||
// Calculate and set the disable delay of the bow in function of the Attack Speed
|
||||
_disableRangedAttackEndTime = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
// Precaution. It happened in the past for _attackEndTime. Will not risk it.
|
||||
if (_disableRangedAttackEndTime < currentTime)
|
||||
{
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
_hitTask = ThreadPool.schedule(() -> onHitTimeNotDual(weaponItem, attack, timeToHit, timeAtk), timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -3345,13 +3356,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// called from AIAccessor only
|
||||
|
||||
/**
|
||||
* Calculate movement data for a move to location action and add the Creature to movingObjects of GameTimeTaskManager (only called by AI Accessor).<br>
|
||||
* Calculate movement data for a move to location action and add the Creature to MOVING_OBJECTS of MovementTaskManager (only called by AI Accessor).<br>
|
||||
* <br>
|
||||
* <b><u>Concept</u>:</b><br>
|
||||
* <br>
|
||||
* At the beginning of the move action, all properties of the movement are stored in the MoveData object called <b>_move</b> of the Creature.<br>
|
||||
* The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<br>
|
||||
* All Creature in movement are identified in <b>movingObjects</b> of GameTimeTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* All Creature in movement are identified in <b>MOVING_OBJECTS</b> of MovementTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* <br>
|
||||
* <b><u>Actions</u>:</b>
|
||||
* <ul>
|
||||
@ -3359,7 +3370,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
* <li>Calculate distance (dx,dy) between current position and destination including offset</li>
|
||||
* <li>Create and Init a MoveData object</li>
|
||||
* <li>Set the Creature _move object to MoveData object</li>
|
||||
* <li>Add the Creature to movingObjects of the GameTimeTaskManager</li>
|
||||
* <li>Add the Creature to MOVING_OBJECTS of the MovementTaskManager</li>
|
||||
* <li>Create a task to notify the AI that Creature arrives at a check point of the movement</li>
|
||||
* </ul>
|
||||
* <font color=#FF0000><b><u>Caution</u>: This method DOESN'T send Server->Client packet MoveToPawn/MoveToLocation.</b></font><br>
|
||||
@ -3665,7 +3676,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
}
|
||||
|
||||
public boolean moveToNextRoutePoint()
|
||||
@ -3735,7 +3746,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// Set the Creature _move object to MoveData object
|
||||
_move = m;
|
||||
|
||||
// Add the Creature to moving objects of the GameTimeTaskManager.
|
||||
// Add the Creature to moving objects of the MovementTaskManager.
|
||||
// The MovementTaskManager manages object movement.
|
||||
MovementTaskManager.getInstance().registerMovingObject(this);
|
||||
|
||||
@ -3745,8 +3756,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
|
||||
// to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
|
||||
// Send a Server->Client packet MoveToLocation to the actor and all Player in its _knownPlayers
|
||||
broadcastMoveToLocation();
|
||||
|
@ -259,14 +259,18 @@ public class UseItem implements IClientIncomingPacket
|
||||
// Create and Bind the next action to the AI.
|
||||
player.getAI().setNextAction(new NextAction(CtrlEvent.EVT_FINISH_CASTING, CtrlIntention.AI_INTENTION_CAST, () -> player.useEquippableItem(item, true)));
|
||||
}
|
||||
else if (player.isAttackingNow())
|
||||
else // Equip or unEquip.
|
||||
{
|
||||
// Equip or unEquip.
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), player.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = player.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -310,9 +310,11 @@ public class CreatureAI extends AbstractAI
|
||||
return;
|
||||
}
|
||||
|
||||
if (_actor.isAttackingNow())
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = _actor.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), _actor.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1176,7 +1176,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
final boolean isTwoHanded = (weaponItem != null) && (weaponItem.getBodyPart() == ItemTemplate.SLOT_LR_HAND);
|
||||
final int timeAtk = Formulas.calculateTimeBetweenAttacks(_stat.getPAtkSpd());
|
||||
final int timeToHit = Formulas.calculateTimeToHit(timeAtk, weaponType, isTwoHanded, false);
|
||||
_attackEndTime = System.nanoTime() + (TimeUnit.MILLISECONDS.toNanos(timeAtk));
|
||||
final long currentTime = System.nanoTime();
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
// Precaution. It has happened in the past. Probably impossible to happen now, but will not risk it.
|
||||
if (_attackEndTime < currentTime)
|
||||
{
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
// Make sure that char is facing selected target
|
||||
// also works: setHeading(Util.convertDegreeToClientHeading(Util.calculateAngleFrom(this, target)));
|
||||
@ -1225,7 +1231,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
}
|
||||
|
||||
// Calculate and set the disable delay of the bow in function of the Attack Speed
|
||||
_disableRangedAttackEndTime = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
// Precaution. It happened in the past for _attackEndTime. Will not risk it.
|
||||
if (_disableRangedAttackEndTime < currentTime)
|
||||
{
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
_hitTask = ThreadPool.schedule(() -> onHitTimeNotDual(weaponItem, attack, timeToHit, timeAtk), timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -3345,13 +3356,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// called from AIAccessor only
|
||||
|
||||
/**
|
||||
* Calculate movement data for a move to location action and add the Creature to movingObjects of GameTimeTaskManager (only called by AI Accessor).<br>
|
||||
* Calculate movement data for a move to location action and add the Creature to MOVING_OBJECTS of MovementTaskManager (only called by AI Accessor).<br>
|
||||
* <br>
|
||||
* <b><u>Concept</u>:</b><br>
|
||||
* <br>
|
||||
* At the beginning of the move action, all properties of the movement are stored in the MoveData object called <b>_move</b> of the Creature.<br>
|
||||
* The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<br>
|
||||
* All Creature in movement are identified in <b>movingObjects</b> of GameTimeTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* All Creature in movement are identified in <b>MOVING_OBJECTS</b> of MovementTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* <br>
|
||||
* <b><u>Actions</u>:</b>
|
||||
* <ul>
|
||||
@ -3359,7 +3370,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
* <li>Calculate distance (dx,dy) between current position and destination including offset</li>
|
||||
* <li>Create and Init a MoveData object</li>
|
||||
* <li>Set the Creature _move object to MoveData object</li>
|
||||
* <li>Add the Creature to movingObjects of the GameTimeTaskManager</li>
|
||||
* <li>Add the Creature to MOVING_OBJECTS of the MovementTaskManager</li>
|
||||
* <li>Create a task to notify the AI that Creature arrives at a check point of the movement</li>
|
||||
* </ul>
|
||||
* <font color=#FF0000><b><u>Caution</u>: This method DOESN'T send Server->Client packet MoveToPawn/MoveToLocation.</b></font><br>
|
||||
@ -3665,7 +3676,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
}
|
||||
|
||||
public boolean moveToNextRoutePoint()
|
||||
@ -3735,7 +3746,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// Set the Creature _move object to MoveData object
|
||||
_move = m;
|
||||
|
||||
// Add the Creature to moving objects of the GameTimeTaskManager.
|
||||
// Add the Creature to moving objects of the MovementTaskManager.
|
||||
// The MovementTaskManager manages object movement.
|
||||
MovementTaskManager.getInstance().registerMovingObject(this);
|
||||
|
||||
@ -3745,8 +3756,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
|
||||
// to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
|
||||
// Send a Server->Client packet MoveToLocation to the actor and all Player in its _knownPlayers
|
||||
broadcastMoveToLocation();
|
||||
|
@ -259,14 +259,18 @@ public class UseItem implements IClientIncomingPacket
|
||||
// Create and Bind the next action to the AI.
|
||||
player.getAI().setNextAction(new NextAction(CtrlEvent.EVT_FINISH_CASTING, CtrlIntention.AI_INTENTION_CAST, () -> player.useEquippableItem(item, true)));
|
||||
}
|
||||
else if (player.isAttackingNow())
|
||||
else // Equip or unEquip.
|
||||
{
|
||||
// Equip or unEquip.
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), player.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = player.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -310,9 +310,11 @@ public class CreatureAI extends AbstractAI
|
||||
return;
|
||||
}
|
||||
|
||||
if (_actor.isAttackingNow())
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = _actor.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), _actor.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1176,7 +1176,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
final boolean isTwoHanded = (weaponItem != null) && (weaponItem.getBodyPart() == ItemTemplate.SLOT_LR_HAND);
|
||||
final int timeAtk = Formulas.calculateTimeBetweenAttacks(_stat.getPAtkSpd());
|
||||
final int timeToHit = Formulas.calculateTimeToHit(timeAtk, weaponType, isTwoHanded, false);
|
||||
_attackEndTime = System.nanoTime() + (TimeUnit.MILLISECONDS.toNanos(timeAtk));
|
||||
final long currentTime = System.nanoTime();
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
// Precaution. It has happened in the past. Probably impossible to happen now, but will not risk it.
|
||||
if (_attackEndTime < currentTime)
|
||||
{
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
// Make sure that char is facing selected target
|
||||
// also works: setHeading(Util.convertDegreeToClientHeading(Util.calculateAngleFrom(this, target)));
|
||||
@ -1225,7 +1231,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
}
|
||||
|
||||
// Calculate and set the disable delay of the bow in function of the Attack Speed
|
||||
_disableRangedAttackEndTime = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
// Precaution. It happened in the past for _attackEndTime. Will not risk it.
|
||||
if (_disableRangedAttackEndTime < currentTime)
|
||||
{
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
_hitTask = ThreadPool.schedule(() -> onHitTimeNotDual(weaponItem, attack, timeToHit, timeAtk), timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -3345,13 +3356,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// called from AIAccessor only
|
||||
|
||||
/**
|
||||
* Calculate movement data for a move to location action and add the Creature to movingObjects of GameTimeTaskManager (only called by AI Accessor).<br>
|
||||
* Calculate movement data for a move to location action and add the Creature to MOVING_OBJECTS of MovementTaskManager (only called by AI Accessor).<br>
|
||||
* <br>
|
||||
* <b><u>Concept</u>:</b><br>
|
||||
* <br>
|
||||
* At the beginning of the move action, all properties of the movement are stored in the MoveData object called <b>_move</b> of the Creature.<br>
|
||||
* The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<br>
|
||||
* All Creature in movement are identified in <b>movingObjects</b> of GameTimeTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* All Creature in movement are identified in <b>MOVING_OBJECTS</b> of MovementTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* <br>
|
||||
* <b><u>Actions</u>:</b>
|
||||
* <ul>
|
||||
@ -3359,7 +3370,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
* <li>Calculate distance (dx,dy) between current position and destination including offset</li>
|
||||
* <li>Create and Init a MoveData object</li>
|
||||
* <li>Set the Creature _move object to MoveData object</li>
|
||||
* <li>Add the Creature to movingObjects of the GameTimeTaskManager</li>
|
||||
* <li>Add the Creature to MOVING_OBJECTS of the MovementTaskManager</li>
|
||||
* <li>Create a task to notify the AI that Creature arrives at a check point of the movement</li>
|
||||
* </ul>
|
||||
* <font color=#FF0000><b><u>Caution</u>: This method DOESN'T send Server->Client packet MoveToPawn/MoveToLocation.</b></font><br>
|
||||
@ -3665,7 +3676,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
}
|
||||
|
||||
public boolean moveToNextRoutePoint()
|
||||
@ -3735,7 +3746,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// Set the Creature _move object to MoveData object
|
||||
_move = m;
|
||||
|
||||
// Add the Creature to moving objects of the GameTimeTaskManager.
|
||||
// Add the Creature to moving objects of the MovementTaskManager.
|
||||
// The MovementTaskManager manages object movement.
|
||||
MovementTaskManager.getInstance().registerMovingObject(this);
|
||||
|
||||
@ -3745,8 +3756,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
|
||||
// to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
|
||||
// Send a Server->Client packet MoveToLocation to the actor and all Player in its _knownPlayers
|
||||
broadcastMoveToLocation();
|
||||
|
@ -259,14 +259,18 @@ public class UseItem implements IClientIncomingPacket
|
||||
// Create and Bind the next action to the AI.
|
||||
player.getAI().setNextAction(new NextAction(CtrlEvent.EVT_FINISH_CASTING, CtrlIntention.AI_INTENTION_CAST, () -> player.useEquippableItem(item, true)));
|
||||
}
|
||||
else if (player.isAttackingNow())
|
||||
else // Equip or unEquip.
|
||||
{
|
||||
// Equip or unEquip.
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), player.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = player.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -310,9 +310,11 @@ public class CreatureAI extends AbstractAI
|
||||
return;
|
||||
}
|
||||
|
||||
if (_actor.isAttackingNow())
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = _actor.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), _actor.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1176,7 +1176,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
final boolean isTwoHanded = (weaponItem != null) && (weaponItem.getBodyPart() == ItemTemplate.SLOT_LR_HAND);
|
||||
final int timeAtk = Formulas.calculateTimeBetweenAttacks(_stat.getPAtkSpd());
|
||||
final int timeToHit = Formulas.calculateTimeToHit(timeAtk, weaponType, isTwoHanded, false);
|
||||
_attackEndTime = System.nanoTime() + (TimeUnit.MILLISECONDS.toNanos(timeAtk));
|
||||
final long currentTime = System.nanoTime();
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
// Precaution. It has happened in the past. Probably impossible to happen now, but will not risk it.
|
||||
if (_attackEndTime < currentTime)
|
||||
{
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
// Make sure that char is facing selected target
|
||||
// also works: setHeading(Util.convertDegreeToClientHeading(Util.calculateAngleFrom(this, target)));
|
||||
@ -1225,7 +1231,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
}
|
||||
|
||||
// Calculate and set the disable delay of the bow in function of the Attack Speed
|
||||
_disableRangedAttackEndTime = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
// Precaution. It happened in the past for _attackEndTime. Will not risk it.
|
||||
if (_disableRangedAttackEndTime < currentTime)
|
||||
{
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
_hitTask = ThreadPool.schedule(() -> onHitTimeNotDual(weaponItem, attack, timeToHit, timeAtk), timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -3345,13 +3356,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// called from AIAccessor only
|
||||
|
||||
/**
|
||||
* Calculate movement data for a move to location action and add the Creature to movingObjects of GameTimeTaskManager (only called by AI Accessor).<br>
|
||||
* Calculate movement data for a move to location action and add the Creature to MOVING_OBJECTS of MovementTaskManager (only called by AI Accessor).<br>
|
||||
* <br>
|
||||
* <b><u>Concept</u>:</b><br>
|
||||
* <br>
|
||||
* At the beginning of the move action, all properties of the movement are stored in the MoveData object called <b>_move</b> of the Creature.<br>
|
||||
* The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<br>
|
||||
* All Creature in movement are identified in <b>movingObjects</b> of GameTimeTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* All Creature in movement are identified in <b>MOVING_OBJECTS</b> of MovementTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* <br>
|
||||
* <b><u>Actions</u>:</b>
|
||||
* <ul>
|
||||
@ -3359,7 +3370,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
* <li>Calculate distance (dx,dy) between current position and destination including offset</li>
|
||||
* <li>Create and Init a MoveData object</li>
|
||||
* <li>Set the Creature _move object to MoveData object</li>
|
||||
* <li>Add the Creature to movingObjects of the GameTimeTaskManager</li>
|
||||
* <li>Add the Creature to MOVING_OBJECTS of the MovementTaskManager</li>
|
||||
* <li>Create a task to notify the AI that Creature arrives at a check point of the movement</li>
|
||||
* </ul>
|
||||
* <font color=#FF0000><b><u>Caution</u>: This method DOESN'T send Server->Client packet MoveToPawn/MoveToLocation.</b></font><br>
|
||||
@ -3665,7 +3676,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
}
|
||||
|
||||
public boolean moveToNextRoutePoint()
|
||||
@ -3735,7 +3746,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// Set the Creature _move object to MoveData object
|
||||
_move = m;
|
||||
|
||||
// Add the Creature to moving objects of the GameTimeTaskManager.
|
||||
// Add the Creature to moving objects of the MovementTaskManager.
|
||||
// The MovementTaskManager manages object movement.
|
||||
MovementTaskManager.getInstance().registerMovingObject(this);
|
||||
|
||||
@ -3745,8 +3756,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
|
||||
// to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
|
||||
// Send a Server->Client packet MoveToLocation to the actor and all Player in its _knownPlayers
|
||||
broadcastMoveToLocation();
|
||||
|
@ -256,14 +256,18 @@ public class UseItem implements IClientIncomingPacket
|
||||
// Create and Bind the next action to the AI.
|
||||
player.getAI().setNextAction(new NextAction(CtrlEvent.EVT_FINISH_CASTING, CtrlIntention.AI_INTENTION_CAST, () -> player.useEquippableItem(item, true)));
|
||||
}
|
||||
else if (player.isAttackingNow())
|
||||
else // Equip or unEquip.
|
||||
{
|
||||
// Equip or unEquip.
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), player.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = player.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -310,9 +310,11 @@ public class CreatureAI extends AbstractAI
|
||||
return;
|
||||
}
|
||||
|
||||
if (_actor.isAttackingNow())
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = _actor.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), _actor.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1176,7 +1176,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
final boolean isTwoHanded = (weaponItem != null) && (weaponItem.getBodyPart() == ItemTemplate.SLOT_LR_HAND);
|
||||
final int timeAtk = Formulas.calculateTimeBetweenAttacks(_stat.getPAtkSpd());
|
||||
final int timeToHit = Formulas.calculateTimeToHit(timeAtk, weaponType, isTwoHanded, false);
|
||||
_attackEndTime = System.nanoTime() + (TimeUnit.MILLISECONDS.toNanos(timeAtk));
|
||||
final long currentTime = System.nanoTime();
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
// Precaution. It has happened in the past. Probably impossible to happen now, but will not risk it.
|
||||
if (_attackEndTime < currentTime)
|
||||
{
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
// Make sure that char is facing selected target
|
||||
// also works: setHeading(Util.convertDegreeToClientHeading(Util.calculateAngleFrom(this, target)));
|
||||
@ -1225,7 +1231,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
}
|
||||
|
||||
// Calculate and set the disable delay of the bow in function of the Attack Speed
|
||||
_disableRangedAttackEndTime = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
// Precaution. It happened in the past for _attackEndTime. Will not risk it.
|
||||
if (_disableRangedAttackEndTime < currentTime)
|
||||
{
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
_hitTask = ThreadPool.schedule(() -> onHitTimeNotDual(weaponItem, attack, timeToHit, timeAtk), timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -3345,13 +3356,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// called from AIAccessor only
|
||||
|
||||
/**
|
||||
* Calculate movement data for a move to location action and add the Creature to movingObjects of GameTimeTaskManager (only called by AI Accessor).<br>
|
||||
* Calculate movement data for a move to location action and add the Creature to MOVING_OBJECTS of MovementTaskManager (only called by AI Accessor).<br>
|
||||
* <br>
|
||||
* <b><u>Concept</u>:</b><br>
|
||||
* <br>
|
||||
* At the beginning of the move action, all properties of the movement are stored in the MoveData object called <b>_move</b> of the Creature.<br>
|
||||
* The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<br>
|
||||
* All Creature in movement are identified in <b>movingObjects</b> of GameTimeTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* All Creature in movement are identified in <b>MOVING_OBJECTS</b> of MovementTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* <br>
|
||||
* <b><u>Actions</u>:</b>
|
||||
* <ul>
|
||||
@ -3359,7 +3370,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
* <li>Calculate distance (dx,dy) between current position and destination including offset</li>
|
||||
* <li>Create and Init a MoveData object</li>
|
||||
* <li>Set the Creature _move object to MoveData object</li>
|
||||
* <li>Add the Creature to movingObjects of the GameTimeTaskManager</li>
|
||||
* <li>Add the Creature to MOVING_OBJECTS of the MovementTaskManager</li>
|
||||
* <li>Create a task to notify the AI that Creature arrives at a check point of the movement</li>
|
||||
* </ul>
|
||||
* <font color=#FF0000><b><u>Caution</u>: This method DOESN'T send Server->Client packet MoveToPawn/MoveToLocation.</b></font><br>
|
||||
@ -3665,7 +3676,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
}
|
||||
|
||||
public boolean moveToNextRoutePoint()
|
||||
@ -3735,7 +3746,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// Set the Creature _move object to MoveData object
|
||||
_move = m;
|
||||
|
||||
// Add the Creature to moving objects of the GameTimeTaskManager.
|
||||
// Add the Creature to moving objects of the MovementTaskManager.
|
||||
// The MovementTaskManager manages object movement.
|
||||
MovementTaskManager.getInstance().registerMovingObject(this);
|
||||
|
||||
@ -3745,8 +3756,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
|
||||
// to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
|
||||
// Send a Server->Client packet MoveToLocation to the actor and all Player in its _knownPlayers
|
||||
broadcastMoveToLocation();
|
||||
|
@ -265,14 +265,18 @@ public class UseItem implements IClientIncomingPacket
|
||||
// Create and Bind the next action to the AI
|
||||
player.getAI().setNextAction(new NextAction(CtrlEvent.EVT_FINISH_CASTING, CtrlIntention.AI_INTENTION_CAST, () -> player.useEquippableItem(item, true)));
|
||||
}
|
||||
else if (player.isAttackingNow())
|
||||
else // Equip or unEquip.
|
||||
{
|
||||
// Equip or unEquip.
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), player.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = player.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -310,9 +310,11 @@ public class CreatureAI extends AbstractAI
|
||||
return;
|
||||
}
|
||||
|
||||
if (_actor.isAttackingNow())
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = _actor.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), _actor.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1176,7 +1176,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
final boolean isTwoHanded = (weaponItem != null) && (weaponItem.getBodyPart() == ItemTemplate.SLOT_LR_HAND);
|
||||
final int timeAtk = Formulas.calculateTimeBetweenAttacks(_stat.getPAtkSpd());
|
||||
final int timeToHit = Formulas.calculateTimeToHit(timeAtk, weaponType, isTwoHanded, false);
|
||||
_attackEndTime = System.nanoTime() + (TimeUnit.MILLISECONDS.toNanos(timeAtk));
|
||||
final long currentTime = System.nanoTime();
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
// Precaution. It has happened in the past. Probably impossible to happen now, but will not risk it.
|
||||
if (_attackEndTime < currentTime)
|
||||
{
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
// Make sure that char is facing selected target
|
||||
// also works: setHeading(Util.convertDegreeToClientHeading(Util.calculateAngleFrom(this, target)));
|
||||
@ -1225,7 +1231,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
}
|
||||
|
||||
// Calculate and set the disable delay of the bow in function of the Attack Speed
|
||||
_disableRangedAttackEndTime = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
// Precaution. It happened in the past for _attackEndTime. Will not risk it.
|
||||
if (_disableRangedAttackEndTime < currentTime)
|
||||
{
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
_hitTask = ThreadPool.schedule(() -> onHitTimeNotDual(weaponItem, attack, timeToHit, timeAtk), timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -3345,13 +3356,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// called from AIAccessor only
|
||||
|
||||
/**
|
||||
* Calculate movement data for a move to location action and add the Creature to movingObjects of GameTimeTaskManager (only called by AI Accessor).<br>
|
||||
* Calculate movement data for a move to location action and add the Creature to MOVING_OBJECTS of MovementTaskManager (only called by AI Accessor).<br>
|
||||
* <br>
|
||||
* <b><u>Concept</u>:</b><br>
|
||||
* <br>
|
||||
* At the beginning of the move action, all properties of the movement are stored in the MoveData object called <b>_move</b> of the Creature.<br>
|
||||
* The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<br>
|
||||
* All Creature in movement are identified in <b>movingObjects</b> of GameTimeTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* All Creature in movement are identified in <b>MOVING_OBJECTS</b> of MovementTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* <br>
|
||||
* <b><u>Actions</u>:</b>
|
||||
* <ul>
|
||||
@ -3359,7 +3370,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
* <li>Calculate distance (dx,dy) between current position and destination including offset</li>
|
||||
* <li>Create and Init a MoveData object</li>
|
||||
* <li>Set the Creature _move object to MoveData object</li>
|
||||
* <li>Add the Creature to movingObjects of the GameTimeTaskManager</li>
|
||||
* <li>Add the Creature to MOVING_OBJECTS of the MovementTaskManager</li>
|
||||
* <li>Create a task to notify the AI that Creature arrives at a check point of the movement</li>
|
||||
* </ul>
|
||||
* <font color=#FF0000><b><u>Caution</u>: This method DOESN'T send Server->Client packet MoveToPawn/MoveToLocation.</b></font><br>
|
||||
@ -3665,7 +3676,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
}
|
||||
|
||||
public boolean moveToNextRoutePoint()
|
||||
@ -3735,7 +3746,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// Set the Creature _move object to MoveData object
|
||||
_move = m;
|
||||
|
||||
// Add the Creature to moving objects of the GameTimeTaskManager.
|
||||
// Add the Creature to moving objects of the MovementTaskManager.
|
||||
// The MovementTaskManager manages object movement.
|
||||
MovementTaskManager.getInstance().registerMovingObject(this);
|
||||
|
||||
@ -3745,8 +3756,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
|
||||
// to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
|
||||
// Send a Server->Client packet MoveToLocation to the actor and all Player in its _knownPlayers
|
||||
broadcastMoveToLocation();
|
||||
|
@ -265,14 +265,18 @@ public class UseItem implements IClientIncomingPacket
|
||||
// Create and Bind the next action to the AI
|
||||
player.getAI().setNextAction(new NextAction(CtrlEvent.EVT_FINISH_CASTING, CtrlIntention.AI_INTENTION_CAST, () -> player.useEquippableItem(item, true)));
|
||||
}
|
||||
else if (player.isAttackingNow())
|
||||
else // Equip or unEquip.
|
||||
{
|
||||
// Equip or unEquip.
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), player.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = player.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -310,9 +310,11 @@ public class CreatureAI extends AbstractAI
|
||||
return;
|
||||
}
|
||||
|
||||
if (_actor.isAttackingNow())
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = _actor.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), _actor.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1176,7 +1176,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
final boolean isTwoHanded = (weaponItem != null) && (weaponItem.getBodyPart() == ItemTemplate.SLOT_LR_HAND);
|
||||
final int timeAtk = Formulas.calculateTimeBetweenAttacks(_stat.getPAtkSpd());
|
||||
final int timeToHit = Formulas.calculateTimeToHit(timeAtk, weaponType, isTwoHanded, false);
|
||||
_attackEndTime = System.nanoTime() + (TimeUnit.MILLISECONDS.toNanos(timeAtk));
|
||||
final long currentTime = System.nanoTime();
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
// Precaution. It has happened in the past. Probably impossible to happen now, but will not risk it.
|
||||
if (_attackEndTime < currentTime)
|
||||
{
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
// Make sure that char is facing selected target
|
||||
// also works: setHeading(Util.convertDegreeToClientHeading(Util.calculateAngleFrom(this, target)));
|
||||
@ -1225,7 +1231,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
}
|
||||
|
||||
// Calculate and set the disable delay of the bow in function of the Attack Speed
|
||||
_disableRangedAttackEndTime = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
// Precaution. It happened in the past for _attackEndTime. Will not risk it.
|
||||
if (_disableRangedAttackEndTime < currentTime)
|
||||
{
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
_hitTask = ThreadPool.schedule(() -> onHitTimeNotDual(weaponItem, attack, timeToHit, timeAtk), timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -3344,13 +3355,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// called from AIAccessor only
|
||||
|
||||
/**
|
||||
* Calculate movement data for a move to location action and add the Creature to movingObjects of GameTimeTaskManager (only called by AI Accessor).<br>
|
||||
* Calculate movement data for a move to location action and add the Creature to MOVING_OBJECTS of MovementTaskManager (only called by AI Accessor).<br>
|
||||
* <br>
|
||||
* <b><u>Concept</u>:</b><br>
|
||||
* <br>
|
||||
* At the beginning of the move action, all properties of the movement are stored in the MoveData object called <b>_move</b> of the Creature.<br>
|
||||
* The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<br>
|
||||
* All Creature in movement are identified in <b>movingObjects</b> of GameTimeTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* All Creature in movement are identified in <b>MOVING_OBJECTS</b> of MovementTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* <br>
|
||||
* <b><u>Actions</u>:</b>
|
||||
* <ul>
|
||||
@ -3358,7 +3369,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
* <li>Calculate distance (dx,dy) between current position and destination including offset</li>
|
||||
* <li>Create and Init a MoveData object</li>
|
||||
* <li>Set the Creature _move object to MoveData object</li>
|
||||
* <li>Add the Creature to movingObjects of the GameTimeTaskManager</li>
|
||||
* <li>Add the Creature to MOVING_OBJECTS of the MovementTaskManager</li>
|
||||
* <li>Create a task to notify the AI that Creature arrives at a check point of the movement</li>
|
||||
* </ul>
|
||||
* <font color=#FF0000><b><u>Caution</u>: This method DOESN'T send Server->Client packet MoveToPawn/MoveToLocation.</b></font><br>
|
||||
@ -3664,7 +3675,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
}
|
||||
|
||||
public boolean moveToNextRoutePoint()
|
||||
@ -3734,7 +3745,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// Set the Creature _move object to MoveData object
|
||||
_move = m;
|
||||
|
||||
// Add the Creature to moving objects of the GameTimeTaskManager.
|
||||
// Add the Creature to moving objects of the MovementTaskManager.
|
||||
// The MovementTaskManager manages object movement.
|
||||
MovementTaskManager.getInstance().registerMovingObject(this);
|
||||
|
||||
@ -3744,8 +3755,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
|
||||
// to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
|
||||
// Send a Server->Client packet MoveToLocation to the actor and all Player in its _knownPlayers
|
||||
broadcastMoveToLocation();
|
||||
|
@ -265,14 +265,18 @@ public class UseItem implements IClientIncomingPacket
|
||||
// Create and Bind the next action to the AI
|
||||
player.getAI().setNextAction(new NextAction(CtrlEvent.EVT_FINISH_CASTING, CtrlIntention.AI_INTENTION_CAST, () -> player.useEquippableItem(item, true)));
|
||||
}
|
||||
else if (player.isAttackingNow())
|
||||
else // Equip or unEquip.
|
||||
{
|
||||
// Equip or unEquip.
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), player.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = player.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -310,9 +310,11 @@ public class CreatureAI extends AbstractAI
|
||||
return;
|
||||
}
|
||||
|
||||
if (_actor.isAttackingNow())
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = _actor.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), _actor.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1176,7 +1176,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
final boolean isTwoHanded = (weaponItem != null) && (weaponItem.getBodyPart() == ItemTemplate.SLOT_LR_HAND);
|
||||
final int timeAtk = Formulas.calculateTimeBetweenAttacks(_stat.getPAtkSpd());
|
||||
final int timeToHit = Formulas.calculateTimeToHit(timeAtk, weaponType, isTwoHanded, false);
|
||||
_attackEndTime = System.nanoTime() + (TimeUnit.MILLISECONDS.toNanos(timeAtk));
|
||||
final long currentTime = System.nanoTime();
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
// Precaution. It has happened in the past. Probably impossible to happen now, but will not risk it.
|
||||
if (_attackEndTime < currentTime)
|
||||
{
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
// Make sure that char is facing selected target
|
||||
// also works: setHeading(Util.convertDegreeToClientHeading(Util.calculateAngleFrom(this, target)));
|
||||
@ -1225,7 +1231,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
}
|
||||
|
||||
// Calculate and set the disable delay of the bow in function of the Attack Speed
|
||||
_disableRangedAttackEndTime = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
// Precaution. It happened in the past for _attackEndTime. Will not risk it.
|
||||
if (_disableRangedAttackEndTime < currentTime)
|
||||
{
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
_hitTask = ThreadPool.schedule(() -> onHitTimeNotDual(weaponItem, attack, timeToHit, timeAtk), timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -3344,13 +3355,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// called from AIAccessor only
|
||||
|
||||
/**
|
||||
* Calculate movement data for a move to location action and add the Creature to movingObjects of GameTimeTaskManager (only called by AI Accessor).<br>
|
||||
* Calculate movement data for a move to location action and add the Creature to MOVING_OBJECTS of MovementTaskManager (only called by AI Accessor).<br>
|
||||
* <br>
|
||||
* <b><u>Concept</u>:</b><br>
|
||||
* <br>
|
||||
* At the beginning of the move action, all properties of the movement are stored in the MoveData object called <b>_move</b> of the Creature.<br>
|
||||
* The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<br>
|
||||
* All Creature in movement are identified in <b>movingObjects</b> of GameTimeTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* All Creature in movement are identified in <b>MOVING_OBJECTS</b> of MovementTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* <br>
|
||||
* <b><u>Actions</u>:</b>
|
||||
* <ul>
|
||||
@ -3358,7 +3369,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
* <li>Calculate distance (dx,dy) between current position and destination including offset</li>
|
||||
* <li>Create and Init a MoveData object</li>
|
||||
* <li>Set the Creature _move object to MoveData object</li>
|
||||
* <li>Add the Creature to movingObjects of the GameTimeTaskManager</li>
|
||||
* <li>Add the Creature to MOVING_OBJECTS of the MovementTaskManager</li>
|
||||
* <li>Create a task to notify the AI that Creature arrives at a check point of the movement</li>
|
||||
* </ul>
|
||||
* <font color=#FF0000><b><u>Caution</u>: This method DOESN'T send Server->Client packet MoveToPawn/MoveToLocation.</b></font><br>
|
||||
@ -3664,7 +3675,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
}
|
||||
|
||||
public boolean moveToNextRoutePoint()
|
||||
@ -3734,7 +3745,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// Set the Creature _move object to MoveData object
|
||||
_move = m;
|
||||
|
||||
// Add the Creature to moving objects of the GameTimeTaskManager.
|
||||
// Add the Creature to moving objects of the MovementTaskManager.
|
||||
// The MovementTaskManager manages object movement.
|
||||
MovementTaskManager.getInstance().registerMovingObject(this);
|
||||
|
||||
@ -3744,8 +3755,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
|
||||
// to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
|
||||
// Send a Server->Client packet MoveToLocation to the actor and all Player in its _knownPlayers
|
||||
broadcastMoveToLocation();
|
||||
|
@ -266,14 +266,18 @@ public class UseItem implements IClientIncomingPacket
|
||||
// Create and Bind the next action to the AI
|
||||
player.getAI().setNextAction(new NextAction(CtrlEvent.EVT_FINISH_CASTING, CtrlIntention.AI_INTENTION_CAST, () -> player.useEquippableItem(item, true)));
|
||||
}
|
||||
else if (player.isAttackingNow())
|
||||
else // Equip or unEquip.
|
||||
{
|
||||
// Equip or unEquip.
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), player.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = player.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -310,9 +310,11 @@ public class CreatureAI extends AbstractAI
|
||||
return;
|
||||
}
|
||||
|
||||
if (_actor.isAttackingNow())
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = _actor.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), _actor.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1176,7 +1176,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
final boolean isTwoHanded = (weaponItem != null) && (weaponItem.getBodyPart() == ItemTemplate.SLOT_LR_HAND);
|
||||
final int timeAtk = Formulas.calculateTimeBetweenAttacks(_stat.getPAtkSpd());
|
||||
final int timeToHit = Formulas.calculateTimeToHit(timeAtk, weaponType, isTwoHanded, false);
|
||||
_attackEndTime = System.nanoTime() + (TimeUnit.MILLISECONDS.toNanos(timeAtk));
|
||||
final long currentTime = System.nanoTime();
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
// Precaution. It has happened in the past. Probably impossible to happen now, but will not risk it.
|
||||
if (_attackEndTime < currentTime)
|
||||
{
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
// Make sure that char is facing selected target
|
||||
// also works: setHeading(Util.convertDegreeToClientHeading(Util.calculateAngleFrom(this, target)));
|
||||
@ -1225,7 +1231,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
}
|
||||
|
||||
// Calculate and set the disable delay of the bow in function of the Attack Speed
|
||||
_disableRangedAttackEndTime = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
// Precaution. It happened in the past for _attackEndTime. Will not risk it.
|
||||
if (_disableRangedAttackEndTime < currentTime)
|
||||
{
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
_hitTask = ThreadPool.schedule(() -> onHitTimeNotDual(weaponItem, attack, timeToHit, timeAtk), timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -3344,13 +3355,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// called from AIAccessor only
|
||||
|
||||
/**
|
||||
* Calculate movement data for a move to location action and add the Creature to movingObjects of GameTimeTaskManager (only called by AI Accessor).<br>
|
||||
* Calculate movement data for a move to location action and add the Creature to MOVING_OBJECTS of MovementTaskManager (only called by AI Accessor).<br>
|
||||
* <br>
|
||||
* <b><u>Concept</u>:</b><br>
|
||||
* <br>
|
||||
* At the beginning of the move action, all properties of the movement are stored in the MoveData object called <b>_move</b> of the Creature.<br>
|
||||
* The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<br>
|
||||
* All Creature in movement are identified in <b>movingObjects</b> of GameTimeTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* All Creature in movement are identified in <b>MOVING_OBJECTS</b> of MovementTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* <br>
|
||||
* <b><u>Actions</u>:</b>
|
||||
* <ul>
|
||||
@ -3358,7 +3369,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
* <li>Calculate distance (dx,dy) between current position and destination including offset</li>
|
||||
* <li>Create and Init a MoveData object</li>
|
||||
* <li>Set the Creature _move object to MoveData object</li>
|
||||
* <li>Add the Creature to movingObjects of the GameTimeTaskManager</li>
|
||||
* <li>Add the Creature to MOVING_OBJECTS of the MovementTaskManager</li>
|
||||
* <li>Create a task to notify the AI that Creature arrives at a check point of the movement</li>
|
||||
* </ul>
|
||||
* <font color=#FF0000><b><u>Caution</u>: This method DOESN'T send Server->Client packet MoveToPawn/MoveToLocation.</b></font><br>
|
||||
@ -3664,7 +3675,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
}
|
||||
|
||||
public boolean moveToNextRoutePoint()
|
||||
@ -3734,7 +3745,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// Set the Creature _move object to MoveData object
|
||||
_move = m;
|
||||
|
||||
// Add the Creature to moving objects of the GameTimeTaskManager.
|
||||
// Add the Creature to moving objects of the MovementTaskManager.
|
||||
// The MovementTaskManager manages object movement.
|
||||
MovementTaskManager.getInstance().registerMovingObject(this);
|
||||
|
||||
@ -3744,8 +3755,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
|
||||
// to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
|
||||
// Send a Server->Client packet MoveToLocation to the actor and all Player in its _knownPlayers
|
||||
broadcastMoveToLocation();
|
||||
|
@ -266,14 +266,18 @@ public class UseItem implements IClientIncomingPacket
|
||||
// Create and Bind the next action to the AI
|
||||
player.getAI().setNextAction(new NextAction(CtrlEvent.EVT_FINISH_CASTING, CtrlIntention.AI_INTENTION_CAST, () -> player.useEquippableItem(item, true)));
|
||||
}
|
||||
else if (player.isAttackingNow())
|
||||
else // Equip or unEquip.
|
||||
{
|
||||
// Equip or unEquip.
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), player.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = player.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -310,9 +310,11 @@ public class CreatureAI extends AbstractAI
|
||||
return;
|
||||
}
|
||||
|
||||
if (_actor.isAttackingNow())
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = _actor.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), _actor.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1186,7 +1186,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
final boolean isTwoHanded = (weaponItem != null) && (weaponItem.getBodyPart() == ItemTemplate.SLOT_LR_HAND);
|
||||
final int timeAtk = Formulas.calculateTimeBetweenAttacks(_stat.getPAtkSpd());
|
||||
final int timeToHit = Formulas.calculateTimeToHit(timeAtk, weaponType, isTwoHanded, false);
|
||||
_attackEndTime = System.nanoTime() + (TimeUnit.MILLISECONDS.toNanos(timeAtk));
|
||||
final long currentTime = System.nanoTime();
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
// Precaution. It has happened in the past. Probably impossible to happen now, but will not risk it.
|
||||
if (_attackEndTime < currentTime)
|
||||
{
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
// Make sure that char is facing selected target
|
||||
// also works: setHeading(Util.convertDegreeToClientHeading(Util.calculateAngleFrom(this, target)));
|
||||
@ -1235,7 +1241,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
}
|
||||
|
||||
// Calculate and set the disable delay of the bow in function of the Attack Speed
|
||||
_disableRangedAttackEndTime = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
// Precaution. It happened in the past for _attackEndTime. Will not risk it.
|
||||
if (_disableRangedAttackEndTime < currentTime)
|
||||
{
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
_hitTask = ThreadPool.schedule(() -> onHitTimeNotDual(weaponItem, attack, timeToHit, timeAtk), timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -3354,13 +3365,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// called from AIAccessor only
|
||||
|
||||
/**
|
||||
* Calculate movement data for a move to location action and add the Creature to movingObjects of GameTimeTaskManager (only called by AI Accessor).<br>
|
||||
* Calculate movement data for a move to location action and add the Creature to MOVING_OBJECTS of MovementTaskManager (only called by AI Accessor).<br>
|
||||
* <br>
|
||||
* <b><u>Concept</u>:</b><br>
|
||||
* <br>
|
||||
* At the beginning of the move action, all properties of the movement are stored in the MoveData object called <b>_move</b> of the Creature.<br>
|
||||
* The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<br>
|
||||
* All Creature in movement are identified in <b>movingObjects</b> of GameTimeTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* All Creature in movement are identified in <b>MOVING_OBJECTS</b> of MovementTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* <br>
|
||||
* <b><u>Actions</u>:</b>
|
||||
* <ul>
|
||||
@ -3368,7 +3379,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
* <li>Calculate distance (dx,dy) between current position and destination including offset</li>
|
||||
* <li>Create and Init a MoveData object</li>
|
||||
* <li>Set the Creature _move object to MoveData object</li>
|
||||
* <li>Add the Creature to movingObjects of the GameTimeTaskManager</li>
|
||||
* <li>Add the Creature to MOVING_OBJECTS of the MovementTaskManager</li>
|
||||
* <li>Create a task to notify the AI that Creature arrives at a check point of the movement</li>
|
||||
* </ul>
|
||||
* <font color=#FF0000><b><u>Caution</u>: This method DOESN'T send Server->Client packet MoveToPawn/MoveToLocation.</b></font><br>
|
||||
@ -3674,7 +3685,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
}
|
||||
|
||||
public boolean moveToNextRoutePoint()
|
||||
@ -3744,7 +3755,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// Set the Creature _move object to MoveData object
|
||||
_move = m;
|
||||
|
||||
// Add the Creature to moving objects of the GameTimeTaskManager.
|
||||
// Add the Creature to moving objects of the MovementTaskManager.
|
||||
// The MovementTaskManager manages object movement.
|
||||
MovementTaskManager.getInstance().registerMovingObject(this);
|
||||
|
||||
@ -3754,8 +3765,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
|
||||
// to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
|
||||
// Send a Server->Client packet MoveToLocation to the actor and all Player in its _knownPlayers
|
||||
broadcastMoveToLocation();
|
||||
|
@ -267,14 +267,18 @@ public class UseItem implements IClientIncomingPacket
|
||||
// Create and Bind the next action to the AI
|
||||
player.getAI().setNextAction(new NextAction(CtrlEvent.EVT_FINISH_CASTING, CtrlIntention.AI_INTENTION_CAST, () -> player.useEquippableItem(item, true)));
|
||||
}
|
||||
else if (player.isAttackingNow())
|
||||
else // Equip or unEquip.
|
||||
{
|
||||
// Equip or unEquip.
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), player.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = player.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -5200,19 +5200,19 @@ public abstract class Creature extends WorldObject implements ISkillsHolder
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate movement data for a move to location action and add the Creature to movingObjects of GameTimeTaskManager (only called by AI Accessor).<br>
|
||||
* Calculate movement data for a move to location action and add the Creature to MOVING_OBJECTS of MovementTaskManager (only called by AI Accessor).<br>
|
||||
* <br>
|
||||
* <b><u>Concept</u>:</b><br>
|
||||
* <br>
|
||||
* At the beginning of the move action, all properties of the movement are stored in the MoveData object called <b>_move</b> of the Creature. The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<br>
|
||||
* All Creature in movement are identified in <b>movingObjects</b> of GameTimeTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* All Creature in movement are identified in <b>MOVING_OBJECTS</b> of MovementTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* <br>
|
||||
* <b><u>Actions</u>:</b><br>
|
||||
* <li>Get current position of the Creature</li>
|
||||
* <li>Calculate distance (dx,dy) between current position and destination including offset</li>
|
||||
* <li>Create and Init a MoveData object</li>
|
||||
* <li>Set the Creature _move object to MoveData object</li>
|
||||
* <li>Add the Creature to movingObjects of the GameTimeTaskManager</li>
|
||||
* <li>Add the Creature to MOVING_OBJECTS of the MovementTaskManager</li>
|
||||
* <li>Create a task to notify the AI that Creature arrives at a check point of the movement</li><br>
|
||||
* <font color=#FF0000><b><u>Caution</u>: This method DOESN'T send Server->Client packet MoveToPawn/MoveToLocation </b></font><br>
|
||||
* <br>
|
||||
@ -5613,7 +5613,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder
|
||||
// Set the Creature _move object to MoveData object
|
||||
_move = m;
|
||||
|
||||
// Add the Creature to moving objects of the GameTimeTaskManager.
|
||||
// Add the Creature to moving objects of the MovementTaskManager.
|
||||
// The MovementTaskManager manages object movement.
|
||||
MovementTaskManager.getInstance().registerMovingObject(this);
|
||||
|
||||
@ -5623,7 +5623,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder
|
||||
ThreadPool.schedule(new NotifyAITask(CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
|
||||
// Send a Server->Client packet MoveToLocation to the actor and all Player in its _knownPlayers
|
||||
broadcastMoveToLocation();
|
||||
|
@ -5246,19 +5246,19 @@ public abstract class Creature extends WorldObject implements ISkillsHolder
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate movement data for a move to location action and add the Creature to movingObjects of GameTimeTaskManager (only called by AI Accessor).<br>
|
||||
* Calculate movement data for a move to location action and add the Creature to MOVING_OBJECTS of MovementTaskManager (only called by AI Accessor).<br>
|
||||
* <br>
|
||||
* <b><u>Concept</u>:</b><br>
|
||||
* <br>
|
||||
* At the beginning of the move action, all properties of the movement are stored in the MoveData object called <b>_move</b> of the Creature. The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<br>
|
||||
* All Creature in movement are identified in <b>movingObjects</b> of GameTimeTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* All Creature in movement are identified in <b>MOVING_OBJECTS</b> of MovementTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* <br>
|
||||
* <b><u>Actions</u>:</b><br>
|
||||
* <li>Get current position of the Creature</li>
|
||||
* <li>Calculate distance (dx,dy) between current position and destination including offset</li>
|
||||
* <li>Create and Init a MoveData object</li>
|
||||
* <li>Set the Creature _move object to MoveData object</li>
|
||||
* <li>Add the Creature to movingObjects of the GameTimeTaskManager</li>
|
||||
* <li>Add the Creature to MOVING_OBJECTS of the MovementTaskManager</li>
|
||||
* <li>Create a task to notify the AI that Creature arrives at a check point of the movement</li><br>
|
||||
* <font color=#FF0000><b><u>Caution</u>: This method DOESN'T send Server->Client packet MoveToPawn/MoveToLocation </b></font><br>
|
||||
* <br>
|
||||
@ -5659,7 +5659,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder
|
||||
// Set the Creature _move object to MoveData object
|
||||
_move = m;
|
||||
|
||||
// Add the Creature to moving objects of the GameTimeTaskManager.
|
||||
// Add the Creature to moving objects of the MovementTaskManager.
|
||||
// The MovementTaskManager manages object movement.
|
||||
MovementTaskManager.getInstance().registerMovingObject(this);
|
||||
|
||||
@ -5669,7 +5669,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder
|
||||
ThreadPool.schedule(new NotifyAITask(CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
|
||||
// Send a Server->Client packet MoveToLocation to the actor and all Player in its _knownPlayers
|
||||
broadcastMoveToLocation();
|
||||
|
@ -309,9 +309,11 @@ public class CreatureAI extends AbstractAI
|
||||
return;
|
||||
}
|
||||
|
||||
if (_actor.getBowAttackEndTime() > GameTimeTaskManager.getInstance().getGameTicks())
|
||||
final int gameTime = GameTimeTaskManager.getInstance().getGameTicks();
|
||||
final int bowAttackEndTime = _actor.getBowAttackEndTime();
|
||||
if (bowAttackEndTime > gameTime)
|
||||
{
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target), (_actor.getBowAttackEndTime() - GameTimeTaskManager.getInstance().getGameTicks()) * GameTimeTaskManager.MILLIS_IN_TICK);
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target), (bowAttackEndTime - gameTime) * GameTimeTaskManager.MILLIS_IN_TICK);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1054,6 +1054,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
final Attack attack = new Attack(this, target, isChargedShot(ShotType.SOULSHOTS), (weaponItem != null) ? weaponItem.getCrystalTypePlus().getLevel() : 0);
|
||||
setHeading(Util.calculateHeadingFrom(this, target));
|
||||
final int reuse = calculateReuseTime(weaponItem);
|
||||
final long currentTime = System.nanoTime();
|
||||
boolean hitted = false;
|
||||
switch (getAttackType())
|
||||
{
|
||||
@ -1063,13 +1064,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
return;
|
||||
}
|
||||
_attackEndTime = System.nanoTime() + TimeUnit.NANOSECONDS.convert(timeToHit + (reuse / 2), TimeUnit.MILLISECONDS);
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeToHit + (reuse / 2));
|
||||
hitted = doAttackHitByBow(attack, target, timeAtk, reuse);
|
||||
break;
|
||||
}
|
||||
case POLE:
|
||||
{
|
||||
_attackEndTime = System.nanoTime() + TimeUnit.NANOSECONDS.convert(timeAtk, TimeUnit.MILLISECONDS);
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
hitted = doAttackHitByPole(attack, target, timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -1077,7 +1078,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
if (!isPlayer())
|
||||
{
|
||||
_attackEndTime = System.nanoTime() + TimeUnit.NANOSECONDS.convert(timeAtk, TimeUnit.MILLISECONDS);
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
hitted = doAttackHitSimple(attack, target, timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -1087,18 +1088,24 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
case DUALFIST:
|
||||
case DUALDAGGER:
|
||||
{
|
||||
_attackEndTime = System.nanoTime() + TimeUnit.NANOSECONDS.convert(timeAtk, TimeUnit.MILLISECONDS);
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
hitted = doAttackHitByDual(attack, target, timeToHit);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
_attackEndTime = System.nanoTime() + TimeUnit.NANOSECONDS.convert(timeAtk, TimeUnit.MILLISECONDS);
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
hitted = doAttackHitSimple(attack, target, timeToHit);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Precaution. It has happened in the past. Probably impossible to happen now, but will not risk it.
|
||||
if (_attackEndTime < currentTime)
|
||||
{
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
if (isFakePlayer() && (target.isPlayable() || target.isFakePlayer()))
|
||||
{
|
||||
final Npc npc = ((Npc) this);
|
||||
@ -1226,7 +1233,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new HitTask(this, target, damage1, crit1, miss1, shld1, attack.hasSoulshot(), true), sAtk);
|
||||
|
||||
// Calculate and set the disable delay of the bow in function of the Attack Speed
|
||||
_disableBowAttackEndTime = ((sAtk + reuse) / GameTimeTaskManager.MILLIS_IN_TICK) + GameTimeTaskManager.getInstance().getGameTicks();
|
||||
final int gameTime = GameTimeTaskManager.getInstance().getGameTicks();
|
||||
_disableBowAttackEndTime = gameTime + ((sAtk + reuse) / GameTimeTaskManager.MILLIS_IN_TICK);
|
||||
// Precaution. It happened in the past for _attackEndTime. Will not risk it.
|
||||
if (_disableBowAttackEndTime < gameTime)
|
||||
{
|
||||
_disableBowAttackEndTime = Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
// Add this hit to the Server-Client packet Attack
|
||||
attack.addHit(target, damage1, miss1, crit1, shld1);
|
||||
@ -4124,13 +4137,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate movement data for a move to location action and add the Creature to movingObjects of GameTimeTaskManager (only called by AI Accessor).<br>
|
||||
* Calculate movement data for a move to location action and add the Creature to MOVING_OBJECTS of MovementTaskManager (only called by AI Accessor).<br>
|
||||
* <br>
|
||||
* <b><u>Concept</u>:</b><br>
|
||||
* <br>
|
||||
* At the beginning of the move action, all properties of the movement are stored in the MoveData object called <b>_move</b> of the Creature.<br>
|
||||
* The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<br>
|
||||
* All Creature in movement are identified in <b>movingObjects</b> of GameTimeTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* All Creature in movement are identified in <b>MOVING_OBJECTS</b> of MovementTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* <br>
|
||||
* <b><u>Actions</u>:</b>
|
||||
* <ul>
|
||||
@ -4138,7 +4151,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
* <li>Calculate distance (dx,dy) between current position and destination including offset</li>
|
||||
* <li>Create and Init a MoveData object</li>
|
||||
* <li>Set the Creature _move object to MoveData object</li>
|
||||
* <li>Add the Creature to movingObjects of the GameTimeTaskManager</li>
|
||||
* <li>Add the Creature to MOVING_OBJECTS of the MovementTaskManager</li>
|
||||
* <li>Create a task to notify the AI that Creature arrives at a check point of the movement</li>
|
||||
* </ul>
|
||||
* <font color=#FF0000><b><u>Caution</u>: This method DOESN'T send Server->Client packet MoveToPawn/MoveToLocation.</b></font><br>
|
||||
@ -4435,7 +4448,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// Set the Creature _move object to MoveData object
|
||||
_move = m;
|
||||
|
||||
// Add the Creature to moving objects of the GameTimeTaskManager.
|
||||
// Add the Creature to moving objects of the MovementTaskManager.
|
||||
// The MovementTaskManager manages object movement.
|
||||
MovementTaskManager.getInstance().registerMovingObject(this);
|
||||
|
||||
@ -4444,7 +4457,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
}
|
||||
|
||||
public boolean moveToNextRoutePoint()
|
||||
@ -4524,8 +4537,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
|
||||
// to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
|
||||
// Send a Server->Client packet MoveToLocation to the actor and all Player in its _knownPlayers
|
||||
broadcastMoveToLocation();
|
||||
|
@ -225,14 +225,18 @@ public class UseItem implements IClientIncomingPacket
|
||||
// Binding next action to AI.
|
||||
player.getAI().setNextAction(nextAction);
|
||||
}
|
||||
else if (player.isAttackingNow())
|
||||
else // Equip or unEquip.
|
||||
{
|
||||
// Equip or unEquip.
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.MILLISECONDS.convert(player.getAttackEndTime() - System.nanoTime(), TimeUnit.NANOSECONDS));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = player.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -311,9 +311,11 @@ public class CreatureAI extends AbstractAI
|
||||
return;
|
||||
}
|
||||
|
||||
if (_actor.getBowAttackEndTime() > GameTimeTaskManager.getInstance().getGameTicks())
|
||||
final int gameTime = GameTimeTaskManager.getInstance().getGameTicks();
|
||||
final int bowAttackEndTime = _actor.getBowAttackEndTime();
|
||||
if (bowAttackEndTime > gameTime)
|
||||
{
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target), (_actor.getBowAttackEndTime() - GameTimeTaskManager.getInstance().getGameTicks()) * GameTimeTaskManager.MILLIS_IN_TICK);
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target), (bowAttackEndTime - gameTime) * GameTimeTaskManager.MILLIS_IN_TICK);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1103,6 +1103,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
final Attack attack = new Attack(this, target, isChargedShot(ShotType.SOULSHOTS), (weaponItem != null) ? weaponItem.getCrystalTypePlus().getLevel() : 0);
|
||||
setHeading(Util.calculateHeadingFrom(this, target));
|
||||
final int reuse = calculateReuseTime(weaponItem);
|
||||
final long currentTime = System.nanoTime();
|
||||
boolean hitted = false;
|
||||
switch (getAttackType())
|
||||
{
|
||||
@ -1112,7 +1113,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
return;
|
||||
}
|
||||
_attackEndTime = System.nanoTime() + TimeUnit.NANOSECONDS.convert(timeToHit + (reuse / 2), TimeUnit.MILLISECONDS);
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeToHit + (reuse / 2));
|
||||
hitted = doAttackHitByBow(attack, target, timeAtk, reuse);
|
||||
break;
|
||||
}
|
||||
@ -1122,13 +1123,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
return;
|
||||
}
|
||||
_attackEndTime = System.nanoTime() + TimeUnit.NANOSECONDS.convert(timeToHit + (reuse / 2), TimeUnit.MILLISECONDS);
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeToHit + (reuse / 2));
|
||||
hitted = doAttackHitByCrossBow(attack, target, timeAtk, reuse);
|
||||
break;
|
||||
}
|
||||
case POLE:
|
||||
{
|
||||
_attackEndTime = System.nanoTime() + TimeUnit.NANOSECONDS.convert(timeAtk, TimeUnit.MILLISECONDS);
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
hitted = doAttackHitByPole(attack, target, timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -1136,7 +1137,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
if (!isPlayer())
|
||||
{
|
||||
_attackEndTime = System.nanoTime() + TimeUnit.NANOSECONDS.convert(timeAtk, TimeUnit.MILLISECONDS);
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
hitted = doAttackHitSimple(attack, target, timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -1146,18 +1147,24 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
case DUALFIST:
|
||||
case DUALDAGGER:
|
||||
{
|
||||
_attackEndTime = System.nanoTime() + TimeUnit.NANOSECONDS.convert(timeAtk, TimeUnit.MILLISECONDS);
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
hitted = doAttackHitByDual(attack, target, timeToHit);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
_attackEndTime = System.nanoTime() + TimeUnit.NANOSECONDS.convert(timeAtk, TimeUnit.MILLISECONDS);
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
hitted = doAttackHitSimple(attack, target, timeToHit);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Precaution. It has happened in the past. Probably impossible to happen now, but will not risk it.
|
||||
if (_attackEndTime < currentTime)
|
||||
{
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
if (isFakePlayer() && (target.isPlayable() || target.isFakePlayer()))
|
||||
{
|
||||
final Npc npc = ((Npc) this);
|
||||
@ -1285,7 +1292,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new HitTask(this, target, damage1, crit1, miss1, shld1, attack.hasSoulshot(), true), sAtk);
|
||||
|
||||
// Calculate and set the disable delay of the bow in function of the Attack Speed
|
||||
_disableBowAttackEndTime = ((sAtk + reuse) / GameTimeTaskManager.MILLIS_IN_TICK) + GameTimeTaskManager.getInstance().getGameTicks();
|
||||
final int gameTime = GameTimeTaskManager.getInstance().getGameTicks();
|
||||
_disableBowAttackEndTime = gameTime + ((sAtk + reuse) / GameTimeTaskManager.MILLIS_IN_TICK);
|
||||
// Precaution. It happened in the past for _attackEndTime. Will not risk it.
|
||||
if (_disableBowAttackEndTime < gameTime)
|
||||
{
|
||||
_disableBowAttackEndTime = Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
// Add this hit to the Server-Client packet Attack
|
||||
attack.addHit(target, damage1, miss1, crit1, shld1);
|
||||
@ -1355,7 +1368,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new HitTask(this, target, damage1, crit1, miss1, shld1, attack.hasSoulshot(), true), sAtk);
|
||||
|
||||
// Calculate and set the disable delay of the bow in function of the Attack Speed
|
||||
_disableBowAttackEndTime = ((sAtk + reuse) / GameTimeTaskManager.MILLIS_IN_TICK) + GameTimeTaskManager.getInstance().getGameTicks();
|
||||
final int gameTime = GameTimeTaskManager.getInstance().getGameTicks();
|
||||
_disableBowAttackEndTime = gameTime + ((sAtk + reuse) / GameTimeTaskManager.MILLIS_IN_TICK);
|
||||
// Precaution. It happened in the past for _attackEndTime. Will not risk it.
|
||||
if (_disableBowAttackEndTime < gameTime)
|
||||
{
|
||||
_disableBowAttackEndTime = Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
// Add this hit to the Server-Client packet Attack
|
||||
attack.addHit(target, damage1, miss1, crit1, shld1);
|
||||
@ -4309,13 +4328,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate movement data for a move to location action and add the Creature to movingObjects of GameTimeTaskManager (only called by AI Accessor).<br>
|
||||
* Calculate movement data for a move to location action and add the Creature to MOVING_OBJECTS of MovementTaskManager (only called by AI Accessor).<br>
|
||||
* <br>
|
||||
* <b><u>Concept</u>:</b><br>
|
||||
* <br>
|
||||
* At the beginning of the move action, all properties of the movement are stored in the MoveData object called <b>_move</b> of the Creature.<br>
|
||||
* The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<br>
|
||||
* All Creature in movement are identified in <b>movingObjects</b> of GameTimeTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* All Creature in movement are identified in <b>MOVING_OBJECTS</b> of MovementTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* <br>
|
||||
* <b><u>Actions</u>:</b>
|
||||
* <ul>
|
||||
@ -4323,7 +4342,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
* <li>Calculate distance (dx,dy) between current position and destination including offset</li>
|
||||
* <li>Create and Init a MoveData object</li>
|
||||
* <li>Set the Creature _move object to MoveData object</li>
|
||||
* <li>Add the Creature to movingObjects of the GameTimeTaskManager</li>
|
||||
* <li>Add the Creature to MOVING_OBJECTS of the MovementTaskManager</li>
|
||||
* <li>Create a task to notify the AI that Creature arrives at a check point of the movement</li>
|
||||
* </ul>
|
||||
* <font color=#FF0000><b><u>Caution</u>: This method DOESN'T send Server->Client packet MoveToPawn/MoveToLocation.</b></font><br>
|
||||
@ -4629,7 +4648,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
}
|
||||
|
||||
public boolean moveToNextRoutePoint()
|
||||
@ -4699,7 +4718,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// Set the Creature _move object to MoveData object
|
||||
_move = m;
|
||||
|
||||
// Add the Creature to moving objects of the GameTimeTaskManager.
|
||||
// Add the Creature to moving objects of the MovementTaskManager.
|
||||
// The MovementTaskManager manages object movement.
|
||||
MovementTaskManager.getInstance().registerMovingObject(this);
|
||||
|
||||
@ -4709,8 +4728,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
|
||||
// to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
|
||||
// Send a Server->Client packet MoveToLocation to the actor and all Player in its _knownPlayers
|
||||
broadcastMoveToLocation();
|
||||
|
@ -302,14 +302,18 @@ public class UseItem implements IClientIncomingPacket
|
||||
// Binding next action to AI.
|
||||
player.getAI().setNextAction(nextAction);
|
||||
}
|
||||
else if (player.isAttackingNow())
|
||||
else // Equip or unEquip.
|
||||
{
|
||||
// Equip or unEquip.
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.MILLISECONDS.convert(player.getAttackEndTime() - System.nanoTime(), TimeUnit.NANOSECONDS));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = player.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -311,9 +311,11 @@ public class CreatureAI extends AbstractAI
|
||||
return;
|
||||
}
|
||||
|
||||
if (_actor.getBowAttackEndTime() > GameTimeTaskManager.getInstance().getGameTicks())
|
||||
final int gameTime = GameTimeTaskManager.getInstance().getGameTicks();
|
||||
final int bowAttackEndTime = _actor.getBowAttackEndTime();
|
||||
if (bowAttackEndTime > gameTime)
|
||||
{
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target), (_actor.getBowAttackEndTime() - GameTimeTaskManager.getInstance().getGameTicks()) * GameTimeTaskManager.MILLIS_IN_TICK);
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target), (bowAttackEndTime - gameTime) * GameTimeTaskManager.MILLIS_IN_TICK);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -284,7 +284,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
/** Table of calculators containing all standard NPC calculator (ex : ACCURACY_COMBAT, EVASION_RATE) */
|
||||
private static final Calculator[] NPC_STD_CALCULATOR = Formulas.getStdNPCCalculators();
|
||||
|
||||
private CreatureAI _ai = null;
|
||||
private volatile CreatureAI _ai = null;
|
||||
|
||||
/** Future Skill Cast */
|
||||
protected Future<?> _skillCast;
|
||||
@ -1104,6 +1104,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
final Attack attack = new Attack(this, target, isChargedShot(ShotType.SOULSHOTS), (weaponItem != null) ? weaponItem.getCrystalTypePlus().getLevel() : 0);
|
||||
setHeading(Util.calculateHeadingFrom(this, target));
|
||||
final int reuse = calculateReuseTime(weaponItem);
|
||||
final long currentTime = System.nanoTime();
|
||||
boolean hitted = false;
|
||||
switch (getAttackType())
|
||||
{
|
||||
@ -1113,7 +1114,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
return;
|
||||
}
|
||||
_attackEndTime = System.nanoTime() + TimeUnit.NANOSECONDS.convert(timeToHit + (reuse / 2), TimeUnit.MILLISECONDS);
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeToHit + (reuse / 2));
|
||||
hitted = doAttackHitByBow(attack, target, timeAtk, reuse);
|
||||
break;
|
||||
}
|
||||
@ -1123,13 +1124,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
return;
|
||||
}
|
||||
_attackEndTime = System.nanoTime() + TimeUnit.NANOSECONDS.convert(timeToHit + (reuse / 2), TimeUnit.MILLISECONDS);
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeToHit + (reuse / 2));
|
||||
hitted = doAttackHitByCrossBow(attack, target, timeAtk, reuse);
|
||||
break;
|
||||
}
|
||||
case POLE:
|
||||
{
|
||||
_attackEndTime = System.nanoTime() + TimeUnit.NANOSECONDS.convert(timeAtk, TimeUnit.MILLISECONDS);
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
hitted = doAttackHitByPole(attack, target, timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -1137,7 +1138,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
if (!isPlayer())
|
||||
{
|
||||
_attackEndTime = System.nanoTime() + TimeUnit.NANOSECONDS.convert(timeAtk, TimeUnit.MILLISECONDS);
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
hitted = doAttackHitSimple(attack, target, timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -1147,18 +1148,24 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
case DUALFIST:
|
||||
case DUALDAGGER:
|
||||
{
|
||||
_attackEndTime = System.nanoTime() + TimeUnit.NANOSECONDS.convert(timeAtk, TimeUnit.MILLISECONDS);
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
hitted = doAttackHitByDual(attack, target, timeToHit);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
_attackEndTime = System.nanoTime() + TimeUnit.NANOSECONDS.convert(timeAtk, TimeUnit.MILLISECONDS);
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
hitted = doAttackHitSimple(attack, target, timeToHit);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Precaution. It has happened in the past. Probably impossible to happen now, but will not risk it.
|
||||
if (_attackEndTime < currentTime)
|
||||
{
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
if (isFakePlayer() && (target.isPlayable() || target.isFakePlayer()))
|
||||
{
|
||||
final Npc npc = ((Npc) this);
|
||||
@ -1286,7 +1293,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new HitTask(this, target, damage1, crit1, miss1, shld1, attack.hasSoulshot(), true), sAtk);
|
||||
|
||||
// Calculate and set the disable delay of the bow in function of the Attack Speed
|
||||
_disableBowAttackEndTime = ((sAtk + reuse) / GameTimeTaskManager.MILLIS_IN_TICK) + GameTimeTaskManager.getInstance().getGameTicks();
|
||||
final int gameTime = GameTimeTaskManager.getInstance().getGameTicks();
|
||||
_disableBowAttackEndTime = gameTime + ((sAtk + reuse) / GameTimeTaskManager.MILLIS_IN_TICK);
|
||||
// Precaution. It happened in the past for _attackEndTime. Will not risk it.
|
||||
if (_disableBowAttackEndTime < gameTime)
|
||||
{
|
||||
_disableBowAttackEndTime = Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
// Add this hit to the Server-Client packet Attack
|
||||
attack.addHit(target, damage1, miss1, crit1, shld1);
|
||||
@ -1356,7 +1369,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new HitTask(this, target, damage1, crit1, miss1, shld1, attack.hasSoulshot(), true), sAtk);
|
||||
|
||||
// Calculate and set the disable delay of the bow in function of the Attack Speed
|
||||
_disableBowAttackEndTime = ((sAtk + reuse) / GameTimeTaskManager.MILLIS_IN_TICK) + GameTimeTaskManager.getInstance().getGameTicks();
|
||||
final int gameTime = GameTimeTaskManager.getInstance().getGameTicks();
|
||||
_disableBowAttackEndTime = gameTime + ((sAtk + reuse) / GameTimeTaskManager.MILLIS_IN_TICK);
|
||||
// Precaution. It happened in the past for _attackEndTime. Will not risk it.
|
||||
if (_disableBowAttackEndTime < gameTime)
|
||||
{
|
||||
_disableBowAttackEndTime = Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
// Add this hit to the Server-Client packet Attack
|
||||
attack.addHit(target, damage1, miss1, crit1, shld1);
|
||||
@ -4311,13 +4330,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate movement data for a move to location action and add the Creature to movingObjects of GameTimeTaskManager (only called by AI Accessor).<br>
|
||||
* Calculate movement data for a move to location action and add the Creature to MOVING_OBJECTS of MovementTaskManager (only called by AI Accessor).<br>
|
||||
* <br>
|
||||
* <b><u>Concept</u>:</b><br>
|
||||
* <br>
|
||||
* At the beginning of the move action, all properties of the movement are stored in the MoveData object called <b>_move</b> of the Creature.<br>
|
||||
* The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<br>
|
||||
* All Creature in movement are identified in <b>movingObjects</b> of GameTimeTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* All Creature in movement are identified in <b>MOVING_OBJECTS</b> of MovementTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* <br>
|
||||
* <b><u>Actions</u>:</b>
|
||||
* <ul>
|
||||
@ -4325,7 +4344,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
* <li>Calculate distance (dx,dy) between current position and destination including offset</li>
|
||||
* <li>Create and Init a MoveData object</li>
|
||||
* <li>Set the Creature _move object to MoveData object</li>
|
||||
* <li>Add the Creature to movingObjects of the GameTimeTaskManager</li>
|
||||
* <li>Add the Creature to MOVING_OBJECTS of the MovementTaskManager</li>
|
||||
* <li>Create a task to notify the AI that Creature arrives at a check point of the movement</li>
|
||||
* </ul>
|
||||
* <font color=#FF0000><b><u>Caution</u>: This method DOESN'T send Server->Client packet MoveToPawn/MoveToLocation.</b></font><br>
|
||||
@ -4631,7 +4650,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
}
|
||||
|
||||
public boolean moveToNextRoutePoint()
|
||||
@ -4701,7 +4720,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// Set the Creature _move object to MoveData object
|
||||
_move = m;
|
||||
|
||||
// Add the Creature to moving objects of the GameTimeTaskManager.
|
||||
// Add the Creature to moving objects of the MovementTaskManager.
|
||||
// The MovementTaskManager manages object movement.
|
||||
MovementTaskManager.getInstance().registerMovingObject(this);
|
||||
|
||||
@ -4711,8 +4730,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
|
||||
// to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
|
||||
// Send a Server->Client packet MoveToLocation to the actor and all Player in its _knownPlayers
|
||||
broadcastMoveToLocation();
|
||||
|
@ -302,14 +302,18 @@ public class UseItem implements IClientIncomingPacket
|
||||
// Binding next action to AI.
|
||||
player.getAI().setNextAction(nextAction);
|
||||
}
|
||||
else if (player.isAttackingNow())
|
||||
else // Equip or unEquip.
|
||||
{
|
||||
// Equip or unEquip.
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.MILLISECONDS.convert(player.getAttackEndTime() - System.nanoTime(), TimeUnit.NANOSECONDS));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = player.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -310,9 +310,11 @@ public class CreatureAI extends AbstractAI
|
||||
return;
|
||||
}
|
||||
|
||||
if (_actor.isAttackingNow())
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = _actor.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), _actor.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1176,7 +1176,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
final boolean isTwoHanded = (weaponItem != null) && (weaponItem.getBodyPart() == ItemTemplate.SLOT_LR_HAND);
|
||||
final int timeAtk = Formulas.calculateTimeBetweenAttacks(_stat.getPAtkSpd());
|
||||
final int timeToHit = Formulas.calculateTimeToHit(timeAtk, weaponType, isTwoHanded, false);
|
||||
_attackEndTime = System.nanoTime() + (TimeUnit.MILLISECONDS.toNanos(timeAtk));
|
||||
final long currentTime = System.nanoTime();
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
// Precaution. It has happened in the past. Probably impossible to happen now, but will not risk it.
|
||||
if (_attackEndTime < currentTime)
|
||||
{
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
// Make sure that char is facing selected target
|
||||
// also works: setHeading(Util.convertDegreeToClientHeading(Util.calculateAngleFrom(this, target)));
|
||||
@ -1225,7 +1231,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
}
|
||||
|
||||
// Calculate and set the disable delay of the bow in function of the Attack Speed
|
||||
_disableRangedAttackEndTime = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
// Precaution. It happened in the past for _attackEndTime. Will not risk it.
|
||||
if (_disableRangedAttackEndTime < currentTime)
|
||||
{
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
_hitTask = ThreadPool.schedule(() -> onHitTimeNotDual(weaponItem, attack, timeToHit, timeAtk), timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -3345,13 +3356,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// called from AIAccessor only
|
||||
|
||||
/**
|
||||
* Calculate movement data for a move to location action and add the Creature to movingObjects of GameTimeTaskManager (only called by AI Accessor).<br>
|
||||
* Calculate movement data for a move to location action and add the Creature to MOVING_OBJECTS of MovementTaskManager (only called by AI Accessor).<br>
|
||||
* <br>
|
||||
* <b><u>Concept</u>:</b><br>
|
||||
* <br>
|
||||
* At the beginning of the move action, all properties of the movement are stored in the MoveData object called <b>_move</b> of the Creature.<br>
|
||||
* The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<br>
|
||||
* All Creature in movement are identified in <b>movingObjects</b> of GameTimeTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* All Creature in movement are identified in <b>MOVING_OBJECTS</b> of MovementTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* <br>
|
||||
* <b><u>Actions</u>:</b>
|
||||
* <ul>
|
||||
@ -3359,7 +3370,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
* <li>Calculate distance (dx,dy) between current position and destination including offset</li>
|
||||
* <li>Create and Init a MoveData object</li>
|
||||
* <li>Set the Creature _move object to MoveData object</li>
|
||||
* <li>Add the Creature to movingObjects of the GameTimeTaskManager</li>
|
||||
* <li>Add the Creature to MOVING_OBJECTS of the MovementTaskManager</li>
|
||||
* <li>Create a task to notify the AI that Creature arrives at a check point of the movement</li>
|
||||
* </ul>
|
||||
* <font color=#FF0000><b><u>Caution</u>: This method DOESN'T send Server->Client packet MoveToPawn/MoveToLocation.</b></font><br>
|
||||
@ -3665,7 +3676,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
}
|
||||
|
||||
public boolean moveToNextRoutePoint()
|
||||
@ -3735,7 +3746,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// Set the Creature _move object to MoveData object
|
||||
_move = m;
|
||||
|
||||
// Add the Creature to moving objects of the GameTimeTaskManager.
|
||||
// Add the Creature to moving objects of the MovementTaskManager.
|
||||
// The MovementTaskManager manages object movement.
|
||||
MovementTaskManager.getInstance().registerMovingObject(this);
|
||||
|
||||
@ -3745,8 +3756,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
|
||||
// to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
|
||||
// Send a Server->Client packet MoveToLocation to the actor and all Player in its _knownPlayers
|
||||
broadcastMoveToLocation();
|
||||
|
@ -259,14 +259,18 @@ public class UseItem implements IClientIncomingPacket
|
||||
// Create and Bind the next action to the AI.
|
||||
player.getAI().setNextAction(new NextAction(CtrlEvent.EVT_FINISH_CASTING, CtrlIntention.AI_INTENTION_CAST, () -> player.useEquippableItem(item, true)));
|
||||
}
|
||||
else if (player.isAttackingNow())
|
||||
else // Equip or unEquip.
|
||||
{
|
||||
// Equip or unEquip.
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), player.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = player.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -310,9 +310,11 @@ public class CreatureAI extends AbstractAI
|
||||
return;
|
||||
}
|
||||
|
||||
if (_actor.isAttackingNow())
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = _actor.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), _actor.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1176,7 +1176,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
final boolean isTwoHanded = (weaponItem != null) && (weaponItem.getBodyPart() == ItemTemplate.SLOT_LR_HAND);
|
||||
final int timeAtk = Formulas.calculateTimeBetweenAttacks(_stat.getPAtkSpd());
|
||||
final int timeToHit = Formulas.calculateTimeToHit(timeAtk, weaponType, isTwoHanded, false);
|
||||
_attackEndTime = System.nanoTime() + (TimeUnit.MILLISECONDS.toNanos(timeAtk));
|
||||
final long currentTime = System.nanoTime();
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
// Precaution. It has happened in the past. Probably impossible to happen now, but will not risk it.
|
||||
if (_attackEndTime < currentTime)
|
||||
{
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
// Make sure that char is facing selected target
|
||||
// also works: setHeading(Util.convertDegreeToClientHeading(Util.calculateAngleFrom(this, target)));
|
||||
@ -1225,7 +1231,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
}
|
||||
|
||||
// Calculate and set the disable delay of the bow in function of the Attack Speed
|
||||
_disableRangedAttackEndTime = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
// Precaution. It happened in the past for _attackEndTime. Will not risk it.
|
||||
if (_disableRangedAttackEndTime < currentTime)
|
||||
{
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
_hitTask = ThreadPool.schedule(() -> onHitTimeNotDual(weaponItem, attack, timeToHit, timeAtk), timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -3345,13 +3356,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// called from AIAccessor only
|
||||
|
||||
/**
|
||||
* Calculate movement data for a move to location action and add the Creature to movingObjects of GameTimeTaskManager (only called by AI Accessor).<br>
|
||||
* Calculate movement data for a move to location action and add the Creature to MOVING_OBJECTS of MovementTaskManager (only called by AI Accessor).<br>
|
||||
* <br>
|
||||
* <b><u>Concept</u>:</b><br>
|
||||
* <br>
|
||||
* At the beginning of the move action, all properties of the movement are stored in the MoveData object called <b>_move</b> of the Creature.<br>
|
||||
* The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<br>
|
||||
* All Creature in movement are identified in <b>movingObjects</b> of GameTimeTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* All Creature in movement are identified in <b>MOVING_OBJECTS</b> of MovementTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* <br>
|
||||
* <b><u>Actions</u>:</b>
|
||||
* <ul>
|
||||
@ -3359,7 +3370,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
* <li>Calculate distance (dx,dy) between current position and destination including offset</li>
|
||||
* <li>Create and Init a MoveData object</li>
|
||||
* <li>Set the Creature _move object to MoveData object</li>
|
||||
* <li>Add the Creature to movingObjects of the GameTimeTaskManager</li>
|
||||
* <li>Add the Creature to MOVING_OBJECTS of the MovementTaskManager</li>
|
||||
* <li>Create a task to notify the AI that Creature arrives at a check point of the movement</li>
|
||||
* </ul>
|
||||
* <font color=#FF0000><b><u>Caution</u>: This method DOESN'T send Server->Client packet MoveToPawn/MoveToLocation.</b></font><br>
|
||||
@ -3665,7 +3676,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
}
|
||||
|
||||
public boolean moveToNextRoutePoint()
|
||||
@ -3735,7 +3746,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// Set the Creature _move object to MoveData object
|
||||
_move = m;
|
||||
|
||||
// Add the Creature to moving objects of the GameTimeTaskManager.
|
||||
// Add the Creature to moving objects of the MovementTaskManager.
|
||||
// The MovementTaskManager manages object movement.
|
||||
MovementTaskManager.getInstance().registerMovingObject(this);
|
||||
|
||||
@ -3745,8 +3756,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
|
||||
// to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
|
||||
// Send a Server->Client packet MoveToLocation to the actor and all Player in its _knownPlayers
|
||||
broadcastMoveToLocation();
|
||||
|
@ -259,14 +259,18 @@ public class UseItem implements IClientIncomingPacket
|
||||
// Create and Bind the next action to the AI.
|
||||
player.getAI().setNextAction(new NextAction(CtrlEvent.EVT_FINISH_CASTING, CtrlIntention.AI_INTENTION_CAST, () -> player.useEquippableItem(item, true)));
|
||||
}
|
||||
else if (player.isAttackingNow())
|
||||
else // Equip or unEquip.
|
||||
{
|
||||
// Equip or unEquip.
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), player.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = player.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -310,9 +310,11 @@ public class CreatureAI extends AbstractAI
|
||||
return;
|
||||
}
|
||||
|
||||
if (_actor.isAttackingNow())
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = _actor.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), _actor.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1176,7 +1176,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
final boolean isTwoHanded = (weaponItem != null) && (weaponItem.getBodyPart() == ItemTemplate.SLOT_LR_HAND);
|
||||
final int timeAtk = Formulas.calculateTimeBetweenAttacks(_stat.getPAtkSpd());
|
||||
final int timeToHit = Formulas.calculateTimeToHit(timeAtk, weaponType, isTwoHanded, false);
|
||||
_attackEndTime = System.nanoTime() + (TimeUnit.MILLISECONDS.toNanos(timeAtk));
|
||||
final long currentTime = System.nanoTime();
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
// Precaution. It has happened in the past. Probably impossible to happen now, but will not risk it.
|
||||
if (_attackEndTime < currentTime)
|
||||
{
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
// Make sure that char is facing selected target
|
||||
// also works: setHeading(Util.convertDegreeToClientHeading(Util.calculateAngleFrom(this, target)));
|
||||
@ -1225,7 +1231,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
}
|
||||
|
||||
// Calculate and set the disable delay of the bow in function of the Attack Speed
|
||||
_disableRangedAttackEndTime = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
// Precaution. It happened in the past for _attackEndTime. Will not risk it.
|
||||
if (_disableRangedAttackEndTime < currentTime)
|
||||
{
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
_hitTask = ThreadPool.schedule(() -> onHitTimeNotDual(weaponItem, attack, timeToHit, timeAtk), timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -3345,13 +3356,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// called from AIAccessor only
|
||||
|
||||
/**
|
||||
* Calculate movement data for a move to location action and add the Creature to movingObjects of GameTimeTaskManager (only called by AI Accessor).<br>
|
||||
* Calculate movement data for a move to location action and add the Creature to MOVING_OBJECTS of MovementTaskManager (only called by AI Accessor).<br>
|
||||
* <br>
|
||||
* <b><u>Concept</u>:</b><br>
|
||||
* <br>
|
||||
* At the beginning of the move action, all properties of the movement are stored in the MoveData object called <b>_move</b> of the Creature.<br>
|
||||
* The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<br>
|
||||
* All Creature in movement are identified in <b>movingObjects</b> of GameTimeTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* All Creature in movement are identified in <b>MOVING_OBJECTS</b> of MovementTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* <br>
|
||||
* <b><u>Actions</u>:</b>
|
||||
* <ul>
|
||||
@ -3359,7 +3370,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
* <li>Calculate distance (dx,dy) between current position and destination including offset</li>
|
||||
* <li>Create and Init a MoveData object</li>
|
||||
* <li>Set the Creature _move object to MoveData object</li>
|
||||
* <li>Add the Creature to movingObjects of the GameTimeTaskManager</li>
|
||||
* <li>Add the Creature to MOVING_OBJECTS of the MovementTaskManager</li>
|
||||
* <li>Create a task to notify the AI that Creature arrives at a check point of the movement</li>
|
||||
* </ul>
|
||||
* <font color=#FF0000><b><u>Caution</u>: This method DOESN'T send Server->Client packet MoveToPawn/MoveToLocation.</b></font><br>
|
||||
@ -3665,7 +3676,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
}
|
||||
|
||||
public boolean moveToNextRoutePoint()
|
||||
@ -3735,7 +3746,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// Set the Creature _move object to MoveData object
|
||||
_move = m;
|
||||
|
||||
// Add the Creature to moving objects of the GameTimeTaskManager.
|
||||
// Add the Creature to moving objects of the MovementTaskManager.
|
||||
// The MovementTaskManager manages object movement.
|
||||
MovementTaskManager.getInstance().registerMovingObject(this);
|
||||
|
||||
@ -3745,8 +3756,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
|
||||
// to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
|
||||
// Send a Server->Client packet MoveToLocation to the actor and all Player in its _knownPlayers
|
||||
broadcastMoveToLocation();
|
||||
|
@ -259,14 +259,18 @@ public class UseItem implements IClientIncomingPacket
|
||||
// Create and Bind the next action to the AI.
|
||||
player.getAI().setNextAction(new NextAction(CtrlEvent.EVT_FINISH_CASTING, CtrlIntention.AI_INTENTION_CAST, () -> player.useEquippableItem(item, true)));
|
||||
}
|
||||
else if (player.isAttackingNow())
|
||||
else // Equip or unEquip.
|
||||
{
|
||||
// Equip or unEquip.
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), player.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = player.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -310,9 +310,11 @@ public class CreatureAI extends AbstractAI
|
||||
return;
|
||||
}
|
||||
|
||||
if (_actor.isAttackingNow())
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = _actor.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), _actor.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1176,7 +1176,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
final boolean isTwoHanded = (weaponItem != null) && (weaponItem.getBodyPart() == ItemTemplate.SLOT_LR_HAND);
|
||||
final int timeAtk = Formulas.calculateTimeBetweenAttacks(_stat.getPAtkSpd());
|
||||
final int timeToHit = Formulas.calculateTimeToHit(timeAtk, weaponType, isTwoHanded, false);
|
||||
_attackEndTime = System.nanoTime() + (TimeUnit.MILLISECONDS.toNanos(timeAtk));
|
||||
final long currentTime = System.nanoTime();
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
// Precaution. It has happened in the past. Probably impossible to happen now, but will not risk it.
|
||||
if (_attackEndTime < currentTime)
|
||||
{
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
// Make sure that char is facing selected target
|
||||
// also works: setHeading(Util.convertDegreeToClientHeading(Util.calculateAngleFrom(this, target)));
|
||||
@ -1225,7 +1231,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
}
|
||||
|
||||
// Calculate and set the disable delay of the bow in function of the Attack Speed
|
||||
_disableRangedAttackEndTime = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
// Precaution. It happened in the past for _attackEndTime. Will not risk it.
|
||||
if (_disableRangedAttackEndTime < currentTime)
|
||||
{
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
_hitTask = ThreadPool.schedule(() -> onHitTimeNotDual(weaponItem, attack, timeToHit, timeAtk), timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -3345,13 +3356,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// called from AIAccessor only
|
||||
|
||||
/**
|
||||
* Calculate movement data for a move to location action and add the Creature to movingObjects of GameTimeTaskManager (only called by AI Accessor).<br>
|
||||
* Calculate movement data for a move to location action and add the Creature to MOVING_OBJECTS of MovementTaskManager (only called by AI Accessor).<br>
|
||||
* <br>
|
||||
* <b><u>Concept</u>:</b><br>
|
||||
* <br>
|
||||
* At the beginning of the move action, all properties of the movement are stored in the MoveData object called <b>_move</b> of the Creature.<br>
|
||||
* The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<br>
|
||||
* All Creature in movement are identified in <b>movingObjects</b> of GameTimeTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* All Creature in movement are identified in <b>MOVING_OBJECTS</b> of MovementTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* <br>
|
||||
* <b><u>Actions</u>:</b>
|
||||
* <ul>
|
||||
@ -3359,7 +3370,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
* <li>Calculate distance (dx,dy) between current position and destination including offset</li>
|
||||
* <li>Create and Init a MoveData object</li>
|
||||
* <li>Set the Creature _move object to MoveData object</li>
|
||||
* <li>Add the Creature to movingObjects of the GameTimeTaskManager</li>
|
||||
* <li>Add the Creature to MOVING_OBJECTS of the MovementTaskManager</li>
|
||||
* <li>Create a task to notify the AI that Creature arrives at a check point of the movement</li>
|
||||
* </ul>
|
||||
* <font color=#FF0000><b><u>Caution</u>: This method DOESN'T send Server->Client packet MoveToPawn/MoveToLocation.</b></font><br>
|
||||
@ -3665,7 +3676,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
}
|
||||
|
||||
public boolean moveToNextRoutePoint()
|
||||
@ -3735,7 +3746,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// Set the Creature _move object to MoveData object
|
||||
_move = m;
|
||||
|
||||
// Add the Creature to moving objects of the GameTimeTaskManager.
|
||||
// Add the Creature to moving objects of the MovementTaskManager.
|
||||
// The MovementTaskManager manages object movement.
|
||||
MovementTaskManager.getInstance().registerMovingObject(this);
|
||||
|
||||
@ -3745,8 +3756,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
|
||||
// to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
|
||||
// Send a Server->Client packet MoveToLocation to the actor and all Player in its _knownPlayers
|
||||
broadcastMoveToLocation();
|
||||
|
@ -259,14 +259,18 @@ public class UseItem implements IClientIncomingPacket
|
||||
// Create and Bind the next action to the AI.
|
||||
player.getAI().setNextAction(new NextAction(CtrlEvent.EVT_FINISH_CASTING, CtrlIntention.AI_INTENTION_CAST, () -> player.useEquippableItem(item, true)));
|
||||
}
|
||||
else if (player.isAttackingNow())
|
||||
else // Equip or unEquip.
|
||||
{
|
||||
// Equip or unEquip.
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), player.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = player.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -310,9 +310,11 @@ public class CreatureAI extends AbstractAI
|
||||
return;
|
||||
}
|
||||
|
||||
if (_actor.isAttackingNow())
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = _actor.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), _actor.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1176,7 +1176,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
final boolean isTwoHanded = (weaponItem != null) && (weaponItem.getBodyPart() == ItemTemplate.SLOT_LR_HAND);
|
||||
final int timeAtk = Formulas.calculateTimeBetweenAttacks(_stat.getPAtkSpd());
|
||||
final int timeToHit = Formulas.calculateTimeToHit(timeAtk, weaponType, isTwoHanded, false);
|
||||
_attackEndTime = System.nanoTime() + (TimeUnit.MILLISECONDS.toNanos(timeAtk));
|
||||
final long currentTime = System.nanoTime();
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
// Precaution. It has happened in the past. Probably impossible to happen now, but will not risk it.
|
||||
if (_attackEndTime < currentTime)
|
||||
{
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
// Make sure that char is facing selected target
|
||||
// also works: setHeading(Util.convertDegreeToClientHeading(Util.calculateAngleFrom(this, target)));
|
||||
@ -1225,7 +1231,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
}
|
||||
|
||||
// Calculate and set the disable delay of the bow in function of the Attack Speed
|
||||
_disableRangedAttackEndTime = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
// Precaution. It happened in the past for _attackEndTime. Will not risk it.
|
||||
if (_disableRangedAttackEndTime < currentTime)
|
||||
{
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
_hitTask = ThreadPool.schedule(() -> onHitTimeNotDual(weaponItem, attack, timeToHit, timeAtk), timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -3345,13 +3356,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// called from AIAccessor only
|
||||
|
||||
/**
|
||||
* Calculate movement data for a move to location action and add the Creature to movingObjects of GameTimeTaskManager (only called by AI Accessor).<br>
|
||||
* Calculate movement data for a move to location action and add the Creature to MOVING_OBJECTS of MovementTaskManager (only called by AI Accessor).<br>
|
||||
* <br>
|
||||
* <b><u>Concept</u>:</b><br>
|
||||
* <br>
|
||||
* At the beginning of the move action, all properties of the movement are stored in the MoveData object called <b>_move</b> of the Creature.<br>
|
||||
* The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<br>
|
||||
* All Creature in movement are identified in <b>movingObjects</b> of GameTimeTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* All Creature in movement are identified in <b>MOVING_OBJECTS</b> of MovementTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* <br>
|
||||
* <b><u>Actions</u>:</b>
|
||||
* <ul>
|
||||
@ -3359,7 +3370,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
* <li>Calculate distance (dx,dy) between current position and destination including offset</li>
|
||||
* <li>Create and Init a MoveData object</li>
|
||||
* <li>Set the Creature _move object to MoveData object</li>
|
||||
* <li>Add the Creature to movingObjects of the GameTimeTaskManager</li>
|
||||
* <li>Add the Creature to MOVING_OBJECTS of the MovementTaskManager</li>
|
||||
* <li>Create a task to notify the AI that Creature arrives at a check point of the movement</li>
|
||||
* </ul>
|
||||
* <font color=#FF0000><b><u>Caution</u>: This method DOESN'T send Server->Client packet MoveToPawn/MoveToLocation.</b></font><br>
|
||||
@ -3665,7 +3676,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
}
|
||||
|
||||
public boolean moveToNextRoutePoint()
|
||||
@ -3735,7 +3746,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// Set the Creature _move object to MoveData object
|
||||
_move = m;
|
||||
|
||||
// Add the Creature to moving objects of the GameTimeTaskManager.
|
||||
// Add the Creature to moving objects of the MovementTaskManager.
|
||||
// The MovementTaskManager manages object movement.
|
||||
MovementTaskManager.getInstance().registerMovingObject(this);
|
||||
|
||||
@ -3745,8 +3756,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
|
||||
// to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
|
||||
// Send a Server->Client packet MoveToLocation to the actor and all Player in its _knownPlayers
|
||||
broadcastMoveToLocation();
|
||||
|
@ -256,14 +256,18 @@ public class UseItem implements IClientIncomingPacket
|
||||
// Create and Bind the next action to the AI.
|
||||
player.getAI().setNextAction(new NextAction(CtrlEvent.EVT_FINISH_CASTING, CtrlIntention.AI_INTENTION_CAST, () -> player.useEquippableItem(item, true)));
|
||||
}
|
||||
else if (player.isAttackingNow())
|
||||
else // Equip or unEquip.
|
||||
{
|
||||
// Equip or unEquip.
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), player.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = player.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -310,9 +310,11 @@ public class CreatureAI extends AbstractAI
|
||||
return;
|
||||
}
|
||||
|
||||
if (_actor.isAttackingNow())
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = _actor.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), _actor.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1177,7 +1177,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
final boolean isTwoHanded = (weaponItem != null) && (weaponItem.getBodyPart() == ItemTemplate.SLOT_LR_HAND);
|
||||
final int timeAtk = Formulas.calculateTimeBetweenAttacks(_stat.getPAtkSpd());
|
||||
final int timeToHit = Formulas.calculateTimeToHit(timeAtk, weaponType, isTwoHanded, false);
|
||||
_attackEndTime = System.nanoTime() + (TimeUnit.MILLISECONDS.toNanos(timeAtk));
|
||||
final long currentTime = System.nanoTime();
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
// Precaution. It has happened in the past. Probably impossible to happen now, but will not risk it.
|
||||
if (_attackEndTime < currentTime)
|
||||
{
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
// Make sure that char is facing selected target
|
||||
// also works: setHeading(Util.convertDegreeToClientHeading(Util.calculateAngleFrom(this, target)));
|
||||
@ -1226,7 +1232,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
}
|
||||
|
||||
// Calculate and set the disable delay of the bow in function of the Attack Speed
|
||||
_disableRangedAttackEndTime = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
// Precaution. It happened in the past for _attackEndTime. Will not risk it.
|
||||
if (_disableRangedAttackEndTime < currentTime)
|
||||
{
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
_hitTask = ThreadPool.schedule(() -> onHitTimeNotDual(weaponItem, attack, timeToHit, timeAtk), timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -3358,13 +3369,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// called from AIAccessor only
|
||||
|
||||
/**
|
||||
* Calculate movement data for a move to location action and add the Creature to movingObjects of GameTimeTaskManager (only called by AI Accessor).<br>
|
||||
* Calculate movement data for a move to location action and add the Creature to MOVING_OBJECTS of MovementTaskManager (only called by AI Accessor).<br>
|
||||
* <br>
|
||||
* <b><u>Concept</u>:</b><br>
|
||||
* <br>
|
||||
* At the beginning of the move action, all properties of the movement are stored in the MoveData object called <b>_move</b> of the Creature.<br>
|
||||
* The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<br>
|
||||
* All Creature in movement are identified in <b>movingObjects</b> of GameTimeTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* All Creature in movement are identified in <b>MOVING_OBJECTS</b> of MovementTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* <br>
|
||||
* <b><u>Actions</u>:</b>
|
||||
* <ul>
|
||||
@ -3372,7 +3383,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
* <li>Calculate distance (dx,dy) between current position and destination including offset</li>
|
||||
* <li>Create and Init a MoveData object</li>
|
||||
* <li>Set the Creature _move object to MoveData object</li>
|
||||
* <li>Add the Creature to movingObjects of the GameTimeTaskManager</li>
|
||||
* <li>Add the Creature to MOVING_OBJECTS of the MovementTaskManager</li>
|
||||
* <li>Create a task to notify the AI that Creature arrives at a check point of the movement</li>
|
||||
* </ul>
|
||||
* <font color=#FF0000><b><u>Caution</u>: This method DOESN'T send Server->Client packet MoveToPawn/MoveToLocation.</b></font><br>
|
||||
@ -3678,7 +3689,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
}
|
||||
|
||||
public boolean moveToNextRoutePoint()
|
||||
@ -3748,7 +3759,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// Set the Creature _move object to MoveData object
|
||||
_move = m;
|
||||
|
||||
// Add the Creature to moving objects of the GameTimeTaskManager.
|
||||
// Add the Creature to moving objects of the MovementTaskManager.
|
||||
// The MovementTaskManager manages object movement.
|
||||
MovementTaskManager.getInstance().registerMovingObject(this);
|
||||
|
||||
@ -3758,8 +3769,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
|
||||
// to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
|
||||
// Send a Server->Client packet MoveToLocation to the actor and all Player in its _knownPlayers
|
||||
broadcastMoveToLocation();
|
||||
|
@ -265,14 +265,18 @@ public class UseItem implements IClientIncomingPacket
|
||||
// Create and Bind the next action to the AI
|
||||
player.getAI().setNextAction(new NextAction(CtrlEvent.EVT_FINISH_CASTING, CtrlIntention.AI_INTENTION_CAST, () -> player.useEquippableItem(item, true)));
|
||||
}
|
||||
else if (player.isAttackingNow())
|
||||
else // Equip or unEquip.
|
||||
{
|
||||
// Equip or unEquip.
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), player.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = player.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -310,9 +310,11 @@ public class CreatureAI extends AbstractAI
|
||||
return;
|
||||
}
|
||||
|
||||
if (_actor.isAttackingNow())
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = _actor.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), _actor.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1177,7 +1177,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
final boolean isTwoHanded = (weaponItem != null) && (weaponItem.getBodyPart() == ItemTemplate.SLOT_LR_HAND);
|
||||
final int timeAtk = Formulas.calculateTimeBetweenAttacks(_stat.getPAtkSpd());
|
||||
final int timeToHit = Formulas.calculateTimeToHit(timeAtk, weaponType, isTwoHanded, false);
|
||||
_attackEndTime = System.nanoTime() + (TimeUnit.MILLISECONDS.toNanos(timeAtk));
|
||||
final long currentTime = System.nanoTime();
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
// Precaution. It has happened in the past. Probably impossible to happen now, but will not risk it.
|
||||
if (_attackEndTime < currentTime)
|
||||
{
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
// Make sure that char is facing selected target
|
||||
// also works: setHeading(Util.convertDegreeToClientHeading(Util.calculateAngleFrom(this, target)));
|
||||
@ -1226,7 +1232,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
}
|
||||
|
||||
// Calculate and set the disable delay of the bow in function of the Attack Speed
|
||||
_disableRangedAttackEndTime = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
// Precaution. It happened in the past for _attackEndTime. Will not risk it.
|
||||
if (_disableRangedAttackEndTime < currentTime)
|
||||
{
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
_hitTask = ThreadPool.schedule(() -> onHitTimeNotDual(weaponItem, attack, timeToHit, timeAtk), timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -3358,13 +3369,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// called from AIAccessor only
|
||||
|
||||
/**
|
||||
* Calculate movement data for a move to location action and add the Creature to movingObjects of GameTimeTaskManager (only called by AI Accessor).<br>
|
||||
* Calculate movement data for a move to location action and add the Creature to MOVING_OBJECTS of MovementTaskManager (only called by AI Accessor).<br>
|
||||
* <br>
|
||||
* <b><u>Concept</u>:</b><br>
|
||||
* <br>
|
||||
* At the beginning of the move action, all properties of the movement are stored in the MoveData object called <b>_move</b> of the Creature.<br>
|
||||
* The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<br>
|
||||
* All Creature in movement are identified in <b>movingObjects</b> of GameTimeTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* All Creature in movement are identified in <b>MOVING_OBJECTS</b> of MovementTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* <br>
|
||||
* <b><u>Actions</u>:</b>
|
||||
* <ul>
|
||||
@ -3372,7 +3383,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
* <li>Calculate distance (dx,dy) between current position and destination including offset</li>
|
||||
* <li>Create and Init a MoveData object</li>
|
||||
* <li>Set the Creature _move object to MoveData object</li>
|
||||
* <li>Add the Creature to movingObjects of the GameTimeTaskManager</li>
|
||||
* <li>Add the Creature to MOVING_OBJECTS of the MovementTaskManager</li>
|
||||
* <li>Create a task to notify the AI that Creature arrives at a check point of the movement</li>
|
||||
* </ul>
|
||||
* <font color=#FF0000><b><u>Caution</u>: This method DOESN'T send Server->Client packet MoveToPawn/MoveToLocation.</b></font><br>
|
||||
@ -3678,7 +3689,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
}
|
||||
|
||||
public boolean moveToNextRoutePoint()
|
||||
@ -3748,7 +3759,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// Set the Creature _move object to MoveData object
|
||||
_move = m;
|
||||
|
||||
// Add the Creature to moving objects of the GameTimeTaskManager.
|
||||
// Add the Creature to moving objects of the MovementTaskManager.
|
||||
// The MovementTaskManager manages object movement.
|
||||
MovementTaskManager.getInstance().registerMovingObject(this);
|
||||
|
||||
@ -3758,8 +3769,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
|
||||
// to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
|
||||
// Send a Server->Client packet MoveToLocation to the actor and all Player in its _knownPlayers
|
||||
broadcastMoveToLocation();
|
||||
|
@ -265,14 +265,18 @@ public class UseItem implements IClientIncomingPacket
|
||||
// Create and Bind the next action to the AI
|
||||
player.getAI().setNextAction(new NextAction(CtrlEvent.EVT_FINISH_CASTING, CtrlIntention.AI_INTENTION_CAST, () -> player.useEquippableItem(item, true)));
|
||||
}
|
||||
else if (player.isAttackingNow())
|
||||
else // Equip or unEquip.
|
||||
{
|
||||
// Equip or unEquip.
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), player.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = player.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -310,9 +310,11 @@ public class CreatureAI extends AbstractAI
|
||||
return;
|
||||
}
|
||||
|
||||
if (_actor.isAttackingNow())
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = _actor.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), _actor.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1177,7 +1177,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
final boolean isTwoHanded = (weaponItem != null) && (weaponItem.getBodyPart() == ItemTemplate.SLOT_LR_HAND);
|
||||
final int timeAtk = Formulas.calculateTimeBetweenAttacks(_stat.getPAtkSpd());
|
||||
final int timeToHit = Formulas.calculateTimeToHit(timeAtk, weaponType, isTwoHanded, false);
|
||||
_attackEndTime = System.nanoTime() + (TimeUnit.MILLISECONDS.toNanos(timeAtk));
|
||||
final long currentTime = System.nanoTime();
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
// Precaution. It has happened in the past. Probably impossible to happen now, but will not risk it.
|
||||
if (_attackEndTime < currentTime)
|
||||
{
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
// Make sure that char is facing selected target
|
||||
// also works: setHeading(Util.convertDegreeToClientHeading(Util.calculateAngleFrom(this, target)));
|
||||
@ -1226,7 +1232,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
}
|
||||
|
||||
// Calculate and set the disable delay of the bow in function of the Attack Speed
|
||||
_disableRangedAttackEndTime = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
// Precaution. It happened in the past for _attackEndTime. Will not risk it.
|
||||
if (_disableRangedAttackEndTime < currentTime)
|
||||
{
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
_hitTask = ThreadPool.schedule(() -> onHitTimeNotDual(weaponItem, attack, timeToHit, timeAtk), timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -3358,13 +3369,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// called from AIAccessor only
|
||||
|
||||
/**
|
||||
* Calculate movement data for a move to location action and add the Creature to movingObjects of GameTimeTaskManager (only called by AI Accessor).<br>
|
||||
* Calculate movement data for a move to location action and add the Creature to MOVING_OBJECTS of MovementTaskManager (only called by AI Accessor).<br>
|
||||
* <br>
|
||||
* <b><u>Concept</u>:</b><br>
|
||||
* <br>
|
||||
* At the beginning of the move action, all properties of the movement are stored in the MoveData object called <b>_move</b> of the Creature.<br>
|
||||
* The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<br>
|
||||
* All Creature in movement are identified in <b>movingObjects</b> of GameTimeTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* All Creature in movement are identified in <b>MOVING_OBJECTS</b> of MovementTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* <br>
|
||||
* <b><u>Actions</u>:</b>
|
||||
* <ul>
|
||||
@ -3372,7 +3383,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
* <li>Calculate distance (dx,dy) between current position and destination including offset</li>
|
||||
* <li>Create and Init a MoveData object</li>
|
||||
* <li>Set the Creature _move object to MoveData object</li>
|
||||
* <li>Add the Creature to movingObjects of the GameTimeTaskManager</li>
|
||||
* <li>Add the Creature to MOVING_OBJECTS of the MovementTaskManager</li>
|
||||
* <li>Create a task to notify the AI that Creature arrives at a check point of the movement</li>
|
||||
* </ul>
|
||||
* <font color=#FF0000><b><u>Caution</u>: This method DOESN'T send Server->Client packet MoveToPawn/MoveToLocation.</b></font><br>
|
||||
@ -3678,7 +3689,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
}
|
||||
|
||||
public boolean moveToNextRoutePoint()
|
||||
@ -3748,7 +3759,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// Set the Creature _move object to MoveData object
|
||||
_move = m;
|
||||
|
||||
// Add the Creature to moving objects of the GameTimeTaskManager.
|
||||
// Add the Creature to moving objects of the MovementTaskManager.
|
||||
// The MovementTaskManager manages object movement.
|
||||
MovementTaskManager.getInstance().registerMovingObject(this);
|
||||
|
||||
@ -3758,8 +3769,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
|
||||
// to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
|
||||
// Send a Server->Client packet MoveToLocation to the actor and all Player in its _knownPlayers
|
||||
broadcastMoveToLocation();
|
||||
|
@ -265,14 +265,18 @@ public class UseItem implements IClientIncomingPacket
|
||||
// Create and Bind the next action to the AI
|
||||
player.getAI().setNextAction(new NextAction(CtrlEvent.EVT_FINISH_CASTING, CtrlIntention.AI_INTENTION_CAST, () -> player.useEquippableItem(item, true)));
|
||||
}
|
||||
else if (player.isAttackingNow())
|
||||
else // Equip or unEquip.
|
||||
{
|
||||
// Equip or unEquip.
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), player.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = player.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -310,9 +310,11 @@ public class CreatureAI extends AbstractAI
|
||||
return;
|
||||
}
|
||||
|
||||
if (_actor.isAttackingNow())
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = _actor.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), _actor.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1177,7 +1177,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
final boolean isTwoHanded = (weaponItem != null) && (weaponItem.getBodyPart() == ItemTemplate.SLOT_LR_HAND);
|
||||
final int timeAtk = Formulas.calculateTimeBetweenAttacks(_stat.getPAtkSpd());
|
||||
final int timeToHit = Formulas.calculateTimeToHit(timeAtk, weaponType, isTwoHanded, false);
|
||||
_attackEndTime = System.nanoTime() + (TimeUnit.MILLISECONDS.toNanos(timeAtk));
|
||||
final long currentTime = System.nanoTime();
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
// Precaution. It has happened in the past. Probably impossible to happen now, but will not risk it.
|
||||
if (_attackEndTime < currentTime)
|
||||
{
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
// Make sure that char is facing selected target
|
||||
// also works: setHeading(Util.convertDegreeToClientHeading(Util.calculateAngleFrom(this, target)));
|
||||
@ -1226,7 +1232,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
}
|
||||
|
||||
// Calculate and set the disable delay of the bow in function of the Attack Speed
|
||||
_disableRangedAttackEndTime = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
// Precaution. It happened in the past for _attackEndTime. Will not risk it.
|
||||
if (_disableRangedAttackEndTime < currentTime)
|
||||
{
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
_hitTask = ThreadPool.schedule(() -> onHitTimeNotDual(weaponItem, attack, timeToHit, timeAtk), timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -3357,13 +3368,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// called from AIAccessor only
|
||||
|
||||
/**
|
||||
* Calculate movement data for a move to location action and add the Creature to movingObjects of GameTimeTaskManager (only called by AI Accessor).<br>
|
||||
* Calculate movement data for a move to location action and add the Creature to MOVING_OBJECTS of MovementTaskManager (only called by AI Accessor).<br>
|
||||
* <br>
|
||||
* <b><u>Concept</u>:</b><br>
|
||||
* <br>
|
||||
* At the beginning of the move action, all properties of the movement are stored in the MoveData object called <b>_move</b> of the Creature.<br>
|
||||
* The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<br>
|
||||
* All Creature in movement are identified in <b>movingObjects</b> of GameTimeTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* All Creature in movement are identified in <b>MOVING_OBJECTS</b> of MovementTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* <br>
|
||||
* <b><u>Actions</u>:</b>
|
||||
* <ul>
|
||||
@ -3371,7 +3382,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
* <li>Calculate distance (dx,dy) between current position and destination including offset</li>
|
||||
* <li>Create and Init a MoveData object</li>
|
||||
* <li>Set the Creature _move object to MoveData object</li>
|
||||
* <li>Add the Creature to movingObjects of the GameTimeTaskManager</li>
|
||||
* <li>Add the Creature to MOVING_OBJECTS of the MovementTaskManager</li>
|
||||
* <li>Create a task to notify the AI that Creature arrives at a check point of the movement</li>
|
||||
* </ul>
|
||||
* <font color=#FF0000><b><u>Caution</u>: This method DOESN'T send Server->Client packet MoveToPawn/MoveToLocation.</b></font><br>
|
||||
@ -3677,7 +3688,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
}
|
||||
|
||||
public boolean moveToNextRoutePoint()
|
||||
@ -3747,7 +3758,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// Set the Creature _move object to MoveData object
|
||||
_move = m;
|
||||
|
||||
// Add the Creature to moving objects of the GameTimeTaskManager.
|
||||
// Add the Creature to moving objects of the MovementTaskManager.
|
||||
// The MovementTaskManager manages object movement.
|
||||
MovementTaskManager.getInstance().registerMovingObject(this);
|
||||
|
||||
@ -3757,8 +3768,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
|
||||
// to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
|
||||
// Send a Server->Client packet MoveToLocation to the actor and all Player in its _knownPlayers
|
||||
broadcastMoveToLocation();
|
||||
|
@ -265,14 +265,18 @@ public class UseItem implements IClientIncomingPacket
|
||||
// Create and Bind the next action to the AI
|
||||
player.getAI().setNextAction(new NextAction(CtrlEvent.EVT_FINISH_CASTING, CtrlIntention.AI_INTENTION_CAST, () -> player.useEquippableItem(item, true)));
|
||||
}
|
||||
else if (player.isAttackingNow())
|
||||
else // Equip or unEquip.
|
||||
{
|
||||
// Equip or unEquip.
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), player.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = player.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -310,9 +310,11 @@ public class CreatureAI extends AbstractAI
|
||||
return;
|
||||
}
|
||||
|
||||
if (_actor.isAttackingNow())
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = _actor.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), _actor.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1176,7 +1176,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
final boolean isTwoHanded = (weaponItem != null) && (weaponItem.getBodyPart() == ItemTemplate.SLOT_LR_HAND);
|
||||
final int timeAtk = Formulas.calculateTimeBetweenAttacks(_stat.getPAtkSpd());
|
||||
final int timeToHit = Formulas.calculateTimeToHit(timeAtk, weaponType, isTwoHanded, false);
|
||||
_attackEndTime = System.nanoTime() + (TimeUnit.MILLISECONDS.toNanos(timeAtk));
|
||||
final long currentTime = System.nanoTime();
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
// Precaution. It has happened in the past. Probably impossible to happen now, but will not risk it.
|
||||
if (_attackEndTime < currentTime)
|
||||
{
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
// Make sure that char is facing selected target
|
||||
// also works: setHeading(Util.convertDegreeToClientHeading(Util.calculateAngleFrom(this, target)));
|
||||
@ -1225,7 +1231,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
}
|
||||
|
||||
// Calculate and set the disable delay of the bow in function of the Attack Speed
|
||||
_disableRangedAttackEndTime = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
// Precaution. It happened in the past for _attackEndTime. Will not risk it.
|
||||
if (_disableRangedAttackEndTime < currentTime)
|
||||
{
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
_hitTask = ThreadPool.schedule(() -> onHitTimeNotDual(weaponItem, attack, timeToHit, timeAtk), timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -3345,13 +3356,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// called from AIAccessor only
|
||||
|
||||
/**
|
||||
* Calculate movement data for a move to location action and add the Creature to movingObjects of GameTimeTaskManager (only called by AI Accessor).<br>
|
||||
* Calculate movement data for a move to location action and add the Creature to MOVING_OBJECTS of MovementTaskManager (only called by AI Accessor).<br>
|
||||
* <br>
|
||||
* <b><u>Concept</u>:</b><br>
|
||||
* <br>
|
||||
* At the beginning of the move action, all properties of the movement are stored in the MoveData object called <b>_move</b> of the Creature.<br>
|
||||
* The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<br>
|
||||
* All Creature in movement are identified in <b>movingObjects</b> of GameTimeTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* All Creature in movement are identified in <b>MOVING_OBJECTS</b> of MovementTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* <br>
|
||||
* <b><u>Actions</u>:</b>
|
||||
* <ul>
|
||||
@ -3359,7 +3370,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
* <li>Calculate distance (dx,dy) between current position and destination including offset</li>
|
||||
* <li>Create and Init a MoveData object</li>
|
||||
* <li>Set the Creature _move object to MoveData object</li>
|
||||
* <li>Add the Creature to movingObjects of the GameTimeTaskManager</li>
|
||||
* <li>Add the Creature to MOVING_OBJECTS of the MovementTaskManager</li>
|
||||
* <li>Create a task to notify the AI that Creature arrives at a check point of the movement</li>
|
||||
* </ul>
|
||||
* <font color=#FF0000><b><u>Caution</u>: This method DOESN'T send Server->Client packet MoveToPawn/MoveToLocation.</b></font><br>
|
||||
@ -3665,7 +3676,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
}
|
||||
|
||||
public boolean moveToNextRoutePoint()
|
||||
@ -3735,7 +3746,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// Set the Creature _move object to MoveData object
|
||||
_move = m;
|
||||
|
||||
// Add the Creature to moving objects of the GameTimeTaskManager.
|
||||
// Add the Creature to moving objects of the MovementTaskManager.
|
||||
// The MovementTaskManager manages object movement.
|
||||
MovementTaskManager.getInstance().registerMovingObject(this);
|
||||
|
||||
@ -3745,8 +3756,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
|
||||
// to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
|
||||
// Send a Server->Client packet MoveToLocation to the actor and all Player in its _knownPlayers
|
||||
broadcastMoveToLocation();
|
||||
|
@ -267,14 +267,18 @@ public class UseItem implements IClientIncomingPacket
|
||||
// Create and Bind the next action to the AI.
|
||||
player.getAI().setNextAction(new NextAction(CtrlEvent.EVT_FINISH_CASTING, CtrlIntention.AI_INTENTION_CAST, () -> player.useEquippableItem(item, true)));
|
||||
}
|
||||
else if (player.isAttackingNow())
|
||||
else // Equip or unEquip.
|
||||
{
|
||||
// Equip or unEquip.
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), player.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = player.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -310,9 +310,11 @@ public class CreatureAI extends AbstractAI
|
||||
return;
|
||||
}
|
||||
|
||||
if (_actor.isAttackingNow())
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = _actor.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), _actor.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1180,7 +1180,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
final boolean isTwoHanded = (weaponItem != null) && (weaponItem.getBodyPart() == ItemTemplate.SLOT_LR_HAND);
|
||||
final int timeAtk = Formulas.calculateTimeBetweenAttacks(_stat.getPAtkSpd());
|
||||
final int timeToHit = Formulas.calculateTimeToHit(timeAtk, weaponType, isTwoHanded, false);
|
||||
_attackEndTime = System.nanoTime() + (TimeUnit.MILLISECONDS.toNanos(timeAtk));
|
||||
final long currentTime = System.nanoTime();
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
// Precaution. It has happened in the past. Probably impossible to happen now, but will not risk it.
|
||||
if (_attackEndTime < currentTime)
|
||||
{
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
// Make sure that char is facing selected target
|
||||
// also works: setHeading(Util.convertDegreeToClientHeading(Util.calculateAngleFrom(this, target)));
|
||||
@ -1229,7 +1235,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
}
|
||||
|
||||
// Calculate and set the disable delay of the bow in function of the Attack Speed
|
||||
_disableRangedAttackEndTime = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
// Precaution. It happened in the past for _attackEndTime. Will not risk it.
|
||||
if (_disableRangedAttackEndTime < currentTime)
|
||||
{
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
_hitTask = ThreadPool.schedule(() -> onHitTimeNotDual(weaponItem, attack, timeToHit, timeAtk), timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -3360,13 +3371,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// called from AIAccessor only
|
||||
|
||||
/**
|
||||
* Calculate movement data for a move to location action and add the Creature to movingObjects of GameTimeTaskManager (only called by AI Accessor).<br>
|
||||
* Calculate movement data for a move to location action and add the Creature to MOVING_OBJECTS of MovementTaskManager (only called by AI Accessor).<br>
|
||||
* <br>
|
||||
* <b><u>Concept</u>:</b><br>
|
||||
* <br>
|
||||
* At the beginning of the move action, all properties of the movement are stored in the MoveData object called <b>_move</b> of the Creature.<br>
|
||||
* The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<br>
|
||||
* All Creature in movement are identified in <b>movingObjects</b> of GameTimeTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* All Creature in movement are identified in <b>MOVING_OBJECTS</b> of MovementTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* <br>
|
||||
* <b><u>Actions</u>:</b>
|
||||
* <ul>
|
||||
@ -3374,7 +3385,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
* <li>Calculate distance (dx,dy) between current position and destination including offset</li>
|
||||
* <li>Create and Init a MoveData object</li>
|
||||
* <li>Set the Creature _move object to MoveData object</li>
|
||||
* <li>Add the Creature to movingObjects of the GameTimeTaskManager</li>
|
||||
* <li>Add the Creature to MOVING_OBJECTS of the MovementTaskManager</li>
|
||||
* <li>Create a task to notify the AI that Creature arrives at a check point of the movement</li>
|
||||
* </ul>
|
||||
* <font color=#FF0000><b><u>Caution</u>: This method DOESN'T send Server->Client packet MoveToPawn/MoveToLocation.</b></font><br>
|
||||
@ -3680,7 +3691,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
}
|
||||
|
||||
public boolean moveToNextRoutePoint()
|
||||
@ -3750,7 +3761,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// Set the Creature _move object to MoveData object
|
||||
_move = m;
|
||||
|
||||
// Add the Creature to moving objects of the GameTimeTaskManager.
|
||||
// Add the Creature to moving objects of the MovementTaskManager.
|
||||
// The MovementTaskManager manages object movement.
|
||||
MovementTaskManager.getInstance().registerMovingObject(this);
|
||||
|
||||
@ -3760,8 +3771,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
|
||||
// to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
|
||||
// Send a Server->Client packet MoveToLocation to the actor and all Player in its _knownPlayers
|
||||
broadcastMoveToLocation();
|
||||
|
@ -277,14 +277,18 @@ public class UseItem implements IClientIncomingPacket
|
||||
// Create and Bind the next action to the AI
|
||||
player.getAI().setNextAction(new NextAction(CtrlEvent.EVT_FINISH_CASTING, CtrlIntention.AI_INTENTION_CAST, () -> player.useEquippableItem(item, true)));
|
||||
}
|
||||
else if (player.isAttackingNow())
|
||||
else // Equip or unEquip.
|
||||
{
|
||||
// Equip or unEquip.
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), player.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = player.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -310,9 +310,11 @@ public class CreatureAI extends AbstractAI
|
||||
return;
|
||||
}
|
||||
|
||||
if (_actor.isAttackingNow())
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = _actor.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), _actor.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1187,7 +1187,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
final boolean isTwoHanded = (weaponItem != null) && (weaponItem.getBodyPart() == ItemTemplate.SLOT_LR_HAND);
|
||||
final int timeAtk = Formulas.calculateTimeBetweenAttacks(_stat.getPAtkSpd());
|
||||
final int timeToHit = Formulas.calculateTimeToHit(timeAtk, weaponType, isTwoHanded, false);
|
||||
_attackEndTime = System.nanoTime() + (TimeUnit.MILLISECONDS.toNanos(timeAtk));
|
||||
final long currentTime = System.nanoTime();
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
// Precaution. It has happened in the past. Probably impossible to happen now, but will not risk it.
|
||||
if (_attackEndTime < currentTime)
|
||||
{
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
// Make sure that char is facing selected target
|
||||
// also works: setHeading(Util.convertDegreeToClientHeading(Util.calculateAngleFrom(this, target)));
|
||||
@ -1236,7 +1242,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
}
|
||||
|
||||
// Calculate and set the disable delay of the bow in function of the Attack Speed
|
||||
_disableRangedAttackEndTime = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
// Precaution. It happened in the past for _attackEndTime. Will not risk it.
|
||||
if (_disableRangedAttackEndTime < currentTime)
|
||||
{
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
_hitTask = ThreadPool.schedule(() -> onHitTimeNotDual(weaponItem, attack, timeToHit, timeAtk), timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -3367,13 +3378,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// called from AIAccessor only
|
||||
|
||||
/**
|
||||
* Calculate movement data for a move to location action and add the Creature to movingObjects of GameTimeTaskManager (only called by AI Accessor).<br>
|
||||
* Calculate movement data for a move to location action and add the Creature to MOVING_OBJECTS of MovementTaskManager (only called by AI Accessor).<br>
|
||||
* <br>
|
||||
* <b><u>Concept</u>:</b><br>
|
||||
* <br>
|
||||
* At the beginning of the move action, all properties of the movement are stored in the MoveData object called <b>_move</b> of the Creature.<br>
|
||||
* The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<br>
|
||||
* All Creature in movement are identified in <b>movingObjects</b> of GameTimeTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* All Creature in movement are identified in <b>MOVING_OBJECTS</b> of MovementTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* <br>
|
||||
* <b><u>Actions</u>:</b>
|
||||
* <ul>
|
||||
@ -3381,7 +3392,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
* <li>Calculate distance (dx,dy) between current position and destination including offset</li>
|
||||
* <li>Create and Init a MoveData object</li>
|
||||
* <li>Set the Creature _move object to MoveData object</li>
|
||||
* <li>Add the Creature to movingObjects of the GameTimeTaskManager</li>
|
||||
* <li>Add the Creature to MOVING_OBJECTS of the MovementTaskManager</li>
|
||||
* <li>Create a task to notify the AI that Creature arrives at a check point of the movement</li>
|
||||
* </ul>
|
||||
* <font color=#FF0000><b><u>Caution</u>: This method DOESN'T send Server->Client packet MoveToPawn/MoveToLocation.</b></font><br>
|
||||
@ -3687,7 +3698,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
}
|
||||
|
||||
public boolean moveToNextRoutePoint()
|
||||
@ -3757,7 +3768,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// Set the Creature _move object to MoveData object
|
||||
_move = m;
|
||||
|
||||
// Add the Creature to moving objects of the GameTimeTaskManager.
|
||||
// Add the Creature to moving objects of the MovementTaskManager.
|
||||
// The MovementTaskManager manages object movement.
|
||||
MovementTaskManager.getInstance().registerMovingObject(this);
|
||||
|
||||
@ -3767,8 +3778,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
|
||||
// to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
|
||||
// Send a Server->Client packet MoveToLocation to the actor and all Player in its _knownPlayers
|
||||
broadcastMoveToLocation();
|
||||
|
@ -293,14 +293,18 @@ public class UseItem implements IClientIncomingPacket
|
||||
// Create and Bind the next action to the AI
|
||||
player.getAI().setNextAction(new NextAction(CtrlEvent.EVT_FINISH_CASTING, CtrlIntention.AI_INTENTION_CAST, () -> player.useEquippableItem(item, true)));
|
||||
}
|
||||
else if (player.isAttackingNow())
|
||||
else // Equip or unEquip.
|
||||
{
|
||||
// Equip or unEquip.
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), player.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = player.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -310,9 +310,11 @@ public class CreatureAI extends AbstractAI
|
||||
return;
|
||||
}
|
||||
|
||||
if (_actor.isAttackingNow())
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = _actor.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), _actor.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
ThreadPool.schedule(new CastTask(_actor, skill, target, item, forceUse, dontMove), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1197,7 +1197,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
final boolean isTwoHanded = (weaponItem != null) && (weaponItem.getBodyPart() == ItemTemplate.SLOT_LR_HAND);
|
||||
final int timeAtk = Formulas.calculateTimeBetweenAttacks(_stat.getPAtkSpd());
|
||||
final int timeToHit = Formulas.calculateTimeToHit(timeAtk, weaponType, isTwoHanded, false);
|
||||
_attackEndTime = System.nanoTime() + (TimeUnit.MILLISECONDS.toNanos(timeAtk));
|
||||
final long currentTime = System.nanoTime();
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(timeAtk);
|
||||
// Precaution. It has happened in the past. Probably impossible to happen now, but will not risk it.
|
||||
if (_attackEndTime < currentTime)
|
||||
{
|
||||
_attackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
// Make sure that char is facing selected target
|
||||
// also works: setHeading(Util.convertDegreeToClientHeading(Util.calculateAngleFrom(this, target)));
|
||||
@ -1246,7 +1252,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
}
|
||||
|
||||
// Calculate and set the disable delay of the bow in function of the Attack Speed
|
||||
_disableRangedAttackEndTime = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(reuse);
|
||||
// Precaution. It happened in the past for _attackEndTime. Will not risk it.
|
||||
if (_disableRangedAttackEndTime < currentTime)
|
||||
{
|
||||
_disableRangedAttackEndTime = currentTime + TimeUnit.MILLISECONDS.toNanos(Integer.MAX_VALUE);
|
||||
}
|
||||
_hitTask = ThreadPool.schedule(() -> onHitTimeNotDual(weaponItem, attack, timeToHit, timeAtk), timeToHit);
|
||||
break;
|
||||
}
|
||||
@ -3377,13 +3388,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// called from AIAccessor only
|
||||
|
||||
/**
|
||||
* Calculate movement data for a move to location action and add the Creature to movingObjects of GameTimeTaskManager (only called by AI Accessor).<br>
|
||||
* Calculate movement data for a move to location action and add the Creature to MOVING_OBJECTS of MovementTaskManager (only called by AI Accessor).<br>
|
||||
* <br>
|
||||
* <b><u>Concept</u>:</b><br>
|
||||
* <br>
|
||||
* At the beginning of the move action, all properties of the movement are stored in the MoveData object called <b>_move</b> of the Creature.<br>
|
||||
* The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<br>
|
||||
* All Creature in movement are identified in <b>movingObjects</b> of GameTimeTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* All Creature in movement are identified in <b>MOVING_OBJECTS</b> of MovementTaskManager that will call the updatePosition method of those Creature each 0.1s.<br>
|
||||
* <br>
|
||||
* <b><u>Actions</u>:</b>
|
||||
* <ul>
|
||||
@ -3391,7 +3402,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
* <li>Calculate distance (dx,dy) between current position and destination including offset</li>
|
||||
* <li>Create and Init a MoveData object</li>
|
||||
* <li>Set the Creature _move object to MoveData object</li>
|
||||
* <li>Add the Creature to movingObjects of the GameTimeTaskManager</li>
|
||||
* <li>Add the Creature to MOVING_OBJECTS of the MovementTaskManager</li>
|
||||
* <li>Create a task to notify the AI that Creature arrives at a check point of the movement</li>
|
||||
* </ul>
|
||||
* <font color=#FF0000><b><u>Caution</u>: This method DOESN'T send Server->Client packet MoveToPawn/MoveToLocation.</b></font><br>
|
||||
@ -3697,7 +3708,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
}
|
||||
|
||||
public boolean moveToNextRoutePoint()
|
||||
@ -3767,7 +3778,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// Set the Creature _move object to MoveData object
|
||||
_move = m;
|
||||
|
||||
// Add the Creature to moving objects of the GameTimeTaskManager.
|
||||
// Add the Creature to moving objects of the MovementTaskManager.
|
||||
// The MovementTaskManager manages object movement.
|
||||
MovementTaskManager.getInstance().registerMovingObject(this);
|
||||
|
||||
@ -3777,8 +3788,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
ThreadPool.schedule(new NotifyAITask(this, CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
|
||||
}
|
||||
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
|
||||
// to destination by GameTimeTaskManager
|
||||
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive to destination by MovementTaskManager
|
||||
|
||||
// Send a Server->Client packet MoveToLocation to the actor and all Player in its _knownPlayers
|
||||
broadcastMoveToLocation();
|
||||
|
@ -295,14 +295,18 @@ public class UseItem implements IClientIncomingPacket
|
||||
// Create and Bind the next action to the AI
|
||||
player.getAI().setNextAction(new NextAction(CtrlEvent.EVT_FINISH_CASTING, CtrlIntention.AI_INTENTION_CAST, () -> player.useEquippableItem(item, true)));
|
||||
}
|
||||
else if (player.isAttackingNow())
|
||||
else // Equip or unEquip.
|
||||
{
|
||||
// Equip or unEquip.
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), player.getAttackEndTime() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
final long currentTime = System.nanoTime();
|
||||
final long attackEndTime = player.getAttackEndTime();
|
||||
if (attackEndTime > currentTime)
|
||||
{
|
||||
ThreadPool.schedule(() -> player.useEquippableItem(item, false), TimeUnit.NANOSECONDS.toMillis(attackEndTime - currentTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.useEquippableItem(item, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
Loading…
Reference in New Issue
Block a user