Auto play support for different target modes.

This commit is contained in:
MobiusDevelopment
2022-10-23 23:52:42 +00:00
parent 7b739334bf
commit c674348e77
6 changed files with 201 additions and 78 deletions

View File

@@ -27,11 +27,12 @@ import org.l2jmobius.gameserver.geoengine.GeoEngine;
import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.Player; import org.l2jmobius.gameserver.model.actor.Player;
import org.l2jmobius.gameserver.model.actor.Summon; import org.l2jmobius.gameserver.model.actor.Summon;
import org.l2jmobius.gameserver.model.actor.instance.Monster;
import org.l2jmobius.gameserver.model.item.Weapon; import org.l2jmobius.gameserver.model.item.Weapon;
import org.l2jmobius.gameserver.model.item.instance.Item; import org.l2jmobius.gameserver.model.item.instance.Item;
import org.l2jmobius.gameserver.model.zone.ZoneId;
import org.l2jmobius.gameserver.network.serverpackets.autoplay.ExAutoPlayDoMacro; import org.l2jmobius.gameserver.network.serverpackets.autoplay.ExAutoPlayDoMacro;
import org.l2jmobius.gameserver.util.Util; import org.l2jmobius.gameserver.util.Util;
@@ -74,16 +75,19 @@ public class AutoPlayTaskManager
continue PLAY; continue PLAY;
} }
// Next target mode.
final int targetMode = player.getAutoPlaySettings().getNextTargetMode();
// Skip thinking. // Skip thinking.
final WorldObject target = player.getTarget(); final WorldObject target = player.getTarget();
if ((target != null) && target.isMonster()) if ((target != null) && target.isCreature())
{ {
final Monster monster = (Monster) target; final Creature creature = (Creature) target;
if (monster.isAlikeDead()) if (creature.isAlikeDead() || !isTargetModeValid(targetMode, player, creature))
{ {
player.setTarget(null); player.setTarget(null);
} }
else if ((monster.getTarget() == player) || (monster.getTarget() == null)) else if ((creature.getTarget() == player) || (creature.getTarget() == null))
{ {
// We take granted that mage classes do not auto hit. // We take granted that mage classes do not auto hit.
if (isMageCaster(player)) if (isMageCaster(player))
@@ -96,18 +100,21 @@ public class AutoPlayTaskManager
{ {
if (player.getAI().getIntention() != CtrlIntention.AI_INTENTION_ATTACK) if (player.getAI().getIntention() != CtrlIntention.AI_INTENTION_ATTACK)
{ {
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, monster); if (creature.isAutoAttackable(player))
{
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, creature);
} }
else if (monster.hasAI() && !monster.getAI().isAutoAttacking()) }
else if (creature.hasAI() && !creature.getAI().isAutoAttacking())
{ {
final Weapon weapon = player.getActiveWeaponItem(); final Weapon weapon = player.getActiveWeaponItem();
if (weapon != null) if (weapon != null)
{ {
final boolean ranged = weapon.getItemType().isRanged(); final boolean ranged = weapon.getItemType().isRanged();
final double angle = Util.calculateHeadingFrom(player, monster); final double angle = Util.calculateHeadingFrom(player, creature);
final double radian = Math.toRadians(angle); final double radian = Math.toRadians(angle);
final double course = Math.toRadians(180); final double course = Math.toRadians(180);
final double distance = (ranged ? player.getCollisionRadius() : player.getCollisionRadius() + monster.getCollisionRadius()) * 2; final double distance = (ranged ? player.getCollisionRadius() : player.getCollisionRadius() + creature.getCollisionRadius()) * 2;
final int x1 = (int) (Math.cos(Math.PI + radian + course) * distance); final int x1 = (int) (Math.cos(Math.PI + radian + course) * distance);
final int y1 = (int) (Math.sin(Math.PI + radian + course) * distance); final int y1 = (int) (Math.sin(Math.PI + radian + course) * distance);
final Location location; final Location location;
@@ -117,7 +124,7 @@ public class AutoPlayTaskManager
} }
else else
{ {
location = new Location(monster.getX() + x1, monster.getY() + y1, player.getZ()); location = new Location(creature.getX() + x1, creature.getY() + y1, player.getZ());
} }
player.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, location); player.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, location);
} }
@@ -160,38 +167,41 @@ public class AutoPlayTaskManager
} }
// Find target. // Find target.
Monster monster = null; Creature creature = null;
double closestDistance = Double.MAX_VALUE; double closestDistance = Double.MAX_VALUE;
TARGET: for (Monster nearby : World.getInstance().getVisibleObjectsInRange(player, Monster.class, player.getAutoPlaySettings().isShortRange() ? 600 : 1400)) TARGET: for (Creature nearby : World.getInstance().getVisibleObjectsInRange(player, Creature.class, player.getAutoPlaySettings().isShortRange() ? 600 : 1400))
{ {
// Skip unavailable monsters. // Skip unavailable creatures.
if ((nearby == null) || nearby.isAlikeDead()) if ((nearby == null) || nearby.isAlikeDead())
{ {
continue TARGET; continue TARGET;
} }
// Check monster target. // Check creature target.
if (player.getAutoPlaySettings().isRespectfulHunting() && (nearby.getTarget() != null) && (nearby.getTarget() != player) && !player.getServitors().containsKey(nearby.getTarget().getObjectId())) if (player.getAutoPlaySettings().isRespectfulHunting() && !nearby.isPlayable() && (nearby.getTarget() != null) && (nearby.getTarget() != player) && !player.getServitors().containsKey(nearby.getTarget().getObjectId()))
{ {
continue TARGET; continue TARGET;
} }
// Check if monster is reachable. // Check next target mode.
if (nearby.isAutoAttackable(player) // if (!isTargetModeValid(targetMode, player, nearby))
&& GeoEngine.getInstance().canSeeTarget(player, nearby)//
&& GeoEngine.getInstance().canMoveToTarget(player.getX(), player.getY(), player.getZ(), nearby.getX(), nearby.getY(), nearby.getZ(), player.getInstanceWorld()))
{ {
final double monsterDistance = player.calculateDistance2D(nearby); continue TARGET;
if (monsterDistance < closestDistance) }
// Check if creature is reachable.
if (GeoEngine.getInstance().canSeeTarget(player, nearby) && GeoEngine.getInstance().canMoveToTarget(player.getX(), player.getY(), player.getZ(), nearby.getX(), nearby.getY(), nearby.getZ(), player.getInstanceWorld()))
{ {
monster = nearby; final double creatureDistance = player.calculateDistance2D(nearby);
closestDistance = monsterDistance; if (creatureDistance < closestDistance)
{
creature = nearby;
closestDistance = creatureDistance;
} }
} }
} }
// New target was assigned. // New target was assigned.
if (monster != null) if (creature != null)
{ {
player.setTarget(monster); player.setTarget(creature);
// We take granted that mage classes do not auto hit. // We take granted that mage classes do not auto hit.
if (isMageCaster(player)) if (isMageCaster(player))
@@ -215,6 +225,33 @@ public class AutoPlayTaskManager
// Non Essence like. // Non Essence like.
return player.isMageClass() && (player.getRace() != Race.ORC); return player.isMageClass() && (player.getRace() != Race.ORC);
} }
private boolean isTargetModeValid(int mode, Player player, Creature creature)
{
switch (mode)
{
case 1: // Monster
{
return creature.isMonster();
}
case 2: // Characters
{
return creature.isPlayable() && creature.isAutoAttackable(player);
}
case 3: // NPC
{
return creature.isNpc() && !creature.isMonster() && !creature.isInsideZone(ZoneId.PEACE);
}
case 4: // Counterattack
{
return creature.isMonster() || (creature.isPlayable() && creature.isAutoAttackable(player));
}
default: // Any Target
{
return (creature.isNpc() && !creature.isInsideZone(ZoneId.PEACE)) || (creature.isPlayable() && creature.isAutoAttackable(player));
}
}
}
} }
public synchronized void doAutoPlay(Player player) public synchronized void doAutoPlay(Player player)

View File

@@ -343,9 +343,13 @@ public class AutoUseTaskManager
// Do not attack guards. // Do not attack guards.
if (target instanceof Guard) if (target instanceof Guard)
{
final int targetMode = player.getAutoPlaySettings().getNextTargetMode();
if (((targetMode != 3 /* NPC */) && (targetMode != 0 /* Any Target */)) || target.isInsideZone(ZoneId.PEACE) || !target.isAutoAttackable(player))
{ {
break SKILLS; break SKILLS;
} }
}
if (!canUseMagic(player, target, skill) || (pet != null ? pet : player).useMagic(skill, null, true, false)) if (!canUseMagic(player, target, skill) || (pet != null ? pet : player).useMagic(skill, null, true, false))
{ {

View File

@@ -27,11 +27,12 @@ import org.l2jmobius.gameserver.geoengine.GeoEngine;
import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.Player; import org.l2jmobius.gameserver.model.actor.Player;
import org.l2jmobius.gameserver.model.actor.Summon; import org.l2jmobius.gameserver.model.actor.Summon;
import org.l2jmobius.gameserver.model.actor.instance.Monster;
import org.l2jmobius.gameserver.model.item.Weapon; import org.l2jmobius.gameserver.model.item.Weapon;
import org.l2jmobius.gameserver.model.item.instance.Item; import org.l2jmobius.gameserver.model.item.instance.Item;
import org.l2jmobius.gameserver.model.zone.ZoneId;
import org.l2jmobius.gameserver.network.serverpackets.autoplay.ExAutoPlayDoMacro; import org.l2jmobius.gameserver.network.serverpackets.autoplay.ExAutoPlayDoMacro;
import org.l2jmobius.gameserver.util.Util; import org.l2jmobius.gameserver.util.Util;
@@ -74,16 +75,19 @@ public class AutoPlayTaskManager
continue PLAY; continue PLAY;
} }
// Next target mode.
final int targetMode = player.getAutoPlaySettings().getNextTargetMode();
// Skip thinking. // Skip thinking.
final WorldObject target = player.getTarget(); final WorldObject target = player.getTarget();
if ((target != null) && target.isMonster()) if ((target != null) && target.isCreature())
{ {
final Monster monster = (Monster) target; final Creature creature = (Creature) target;
if (monster.isAlikeDead()) if (creature.isAlikeDead() || !isTargetModeValid(targetMode, player, creature))
{ {
player.setTarget(null); player.setTarget(null);
} }
else if ((monster.getTarget() == player) || (monster.getTarget() == null)) else if ((creature.getTarget() == player) || (creature.getTarget() == null))
{ {
// We take granted that mage classes do not auto hit. // We take granted that mage classes do not auto hit.
if (isMageCaster(player)) if (isMageCaster(player))
@@ -96,18 +100,21 @@ public class AutoPlayTaskManager
{ {
if (player.getAI().getIntention() != CtrlIntention.AI_INTENTION_ATTACK) if (player.getAI().getIntention() != CtrlIntention.AI_INTENTION_ATTACK)
{ {
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, monster); if (creature.isAutoAttackable(player))
{
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, creature);
} }
else if (monster.hasAI() && !monster.getAI().isAutoAttacking()) }
else if (creature.hasAI() && !creature.getAI().isAutoAttacking())
{ {
final Weapon weapon = player.getActiveWeaponItem(); final Weapon weapon = player.getActiveWeaponItem();
if (weapon != null) if (weapon != null)
{ {
final boolean ranged = weapon.getItemType().isRanged(); final boolean ranged = weapon.getItemType().isRanged();
final double angle = Util.calculateHeadingFrom(player, monster); final double angle = Util.calculateHeadingFrom(player, creature);
final double radian = Math.toRadians(angle); final double radian = Math.toRadians(angle);
final double course = Math.toRadians(180); final double course = Math.toRadians(180);
final double distance = (ranged ? player.getCollisionRadius() : player.getCollisionRadius() + monster.getCollisionRadius()) * 2; final double distance = (ranged ? player.getCollisionRadius() : player.getCollisionRadius() + creature.getCollisionRadius()) * 2;
final int x1 = (int) (Math.cos(Math.PI + radian + course) * distance); final int x1 = (int) (Math.cos(Math.PI + radian + course) * distance);
final int y1 = (int) (Math.sin(Math.PI + radian + course) * distance); final int y1 = (int) (Math.sin(Math.PI + radian + course) * distance);
final Location location; final Location location;
@@ -117,7 +124,7 @@ public class AutoPlayTaskManager
} }
else else
{ {
location = new Location(monster.getX() + x1, monster.getY() + y1, player.getZ()); location = new Location(creature.getX() + x1, creature.getY() + y1, player.getZ());
} }
player.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, location); player.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, location);
} }
@@ -160,38 +167,41 @@ public class AutoPlayTaskManager
} }
// Find target. // Find target.
Monster monster = null; Creature creature = null;
double closestDistance = Double.MAX_VALUE; double closestDistance = Double.MAX_VALUE;
TARGET: for (Monster nearby : World.getInstance().getVisibleObjectsInRange(player, Monster.class, player.getAutoPlaySettings().isShortRange() ? 600 : 1400)) TARGET: for (Creature nearby : World.getInstance().getVisibleObjectsInRange(player, Creature.class, player.getAutoPlaySettings().isShortRange() ? 600 : 1400))
{ {
// Skip unavailable monsters. // Skip unavailable creatures.
if ((nearby == null) || nearby.isAlikeDead()) if ((nearby == null) || nearby.isAlikeDead())
{ {
continue TARGET; continue TARGET;
} }
// Check monster target. // Check creature target.
if (player.getAutoPlaySettings().isRespectfulHunting() && (nearby.getTarget() != null) && (nearby.getTarget() != player) && !player.getServitors().containsKey(nearby.getTarget().getObjectId())) if (player.getAutoPlaySettings().isRespectfulHunting() && !nearby.isPlayable() && (nearby.getTarget() != null) && (nearby.getTarget() != player) && !player.getServitors().containsKey(nearby.getTarget().getObjectId()))
{ {
continue TARGET; continue TARGET;
} }
// Check if monster is reachable. // Check next target mode.
if (nearby.isAutoAttackable(player) // if (!isTargetModeValid(targetMode, player, nearby))
&& GeoEngine.getInstance().canSeeTarget(player, nearby)//
&& GeoEngine.getInstance().canMoveToTarget(player.getX(), player.getY(), player.getZ(), nearby.getX(), nearby.getY(), nearby.getZ(), player.getInstanceWorld()))
{ {
final double monsterDistance = player.calculateDistance2D(nearby); continue TARGET;
if (monsterDistance < closestDistance) }
// Check if creature is reachable.
if (GeoEngine.getInstance().canSeeTarget(player, nearby) && GeoEngine.getInstance().canMoveToTarget(player.getX(), player.getY(), player.getZ(), nearby.getX(), nearby.getY(), nearby.getZ(), player.getInstanceWorld()))
{ {
monster = nearby; final double creatureDistance = player.calculateDistance2D(nearby);
closestDistance = monsterDistance; if (creatureDistance < closestDistance)
{
creature = nearby;
closestDistance = creatureDistance;
} }
} }
} }
// New target was assigned. // New target was assigned.
if (monster != null) if (creature != null)
{ {
player.setTarget(monster); player.setTarget(creature);
// We take granted that mage classes do not auto hit. // We take granted that mage classes do not auto hit.
if (isMageCaster(player)) if (isMageCaster(player))
@@ -215,6 +225,33 @@ public class AutoPlayTaskManager
// Non Essence like. // Non Essence like.
return player.isMageClass() && (player.getRace() != Race.ORC); return player.isMageClass() && (player.getRace() != Race.ORC);
} }
private boolean isTargetModeValid(int mode, Player player, Creature creature)
{
switch (mode)
{
case 1: // Monster
{
return creature.isMonster();
}
case 2: // Characters
{
return creature.isPlayable() && creature.isAutoAttackable(player);
}
case 3: // NPC
{
return creature.isNpc() && !creature.isMonster() && !creature.isInsideZone(ZoneId.PEACE);
}
case 4: // Counterattack
{
return creature.isMonster() || (creature.isPlayable() && creature.isAutoAttackable(player));
}
default: // Any Target
{
return (creature.isNpc() && !creature.isInsideZone(ZoneId.PEACE)) || (creature.isPlayable() && creature.isAutoAttackable(player));
}
}
}
} }
public synchronized void doAutoPlay(Player player) public synchronized void doAutoPlay(Player player)

View File

@@ -343,9 +343,13 @@ public class AutoUseTaskManager
// Do not attack guards. // Do not attack guards.
if (target instanceof Guard) if (target instanceof Guard)
{
final int targetMode = player.getAutoPlaySettings().getNextTargetMode();
if (((targetMode != 3 /* NPC */) && (targetMode != 0 /* Any Target */)) || target.isInsideZone(ZoneId.PEACE) || !target.isAutoAttackable(player))
{ {
break SKILLS; break SKILLS;
} }
}
if (!canUseMagic(player, target, skill) || (pet != null ? pet : player).useMagic(skill, null, true, false)) if (!canUseMagic(player, target, skill) || (pet != null ? pet : player).useMagic(skill, null, true, false))
{ {

View File

@@ -27,11 +27,12 @@ import org.l2jmobius.gameserver.geoengine.GeoEngine;
import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.Player; import org.l2jmobius.gameserver.model.actor.Player;
import org.l2jmobius.gameserver.model.actor.Summon; import org.l2jmobius.gameserver.model.actor.Summon;
import org.l2jmobius.gameserver.model.actor.instance.Monster;
import org.l2jmobius.gameserver.model.item.Weapon; import org.l2jmobius.gameserver.model.item.Weapon;
import org.l2jmobius.gameserver.model.item.instance.Item; import org.l2jmobius.gameserver.model.item.instance.Item;
import org.l2jmobius.gameserver.model.zone.ZoneId;
import org.l2jmobius.gameserver.network.serverpackets.autoplay.ExAutoPlayDoMacro; import org.l2jmobius.gameserver.network.serverpackets.autoplay.ExAutoPlayDoMacro;
import org.l2jmobius.gameserver.util.Util; import org.l2jmobius.gameserver.util.Util;
@@ -74,16 +75,19 @@ public class AutoPlayTaskManager
continue PLAY; continue PLAY;
} }
// Next target mode.
final int targetMode = player.getAutoPlaySettings().getNextTargetMode();
// Skip thinking. // Skip thinking.
final WorldObject target = player.getTarget(); final WorldObject target = player.getTarget();
if ((target != null) && target.isMonster()) if ((target != null) && target.isCreature())
{ {
final Monster monster = (Monster) target; final Creature creature = (Creature) target;
if (monster.isAlikeDead()) if (creature.isAlikeDead() || !isTargetModeValid(targetMode, player, creature))
{ {
player.setTarget(null); player.setTarget(null);
} }
else if ((monster.getTarget() == player) || (monster.getTarget() == null)) else if ((creature.getTarget() == player) || (creature.getTarget() == null))
{ {
// We take granted that mage classes do not auto hit. // We take granted that mage classes do not auto hit.
if (isMageCaster(player)) if (isMageCaster(player))
@@ -96,18 +100,21 @@ public class AutoPlayTaskManager
{ {
if (player.getAI().getIntention() != CtrlIntention.AI_INTENTION_ATTACK) if (player.getAI().getIntention() != CtrlIntention.AI_INTENTION_ATTACK)
{ {
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, monster); if (creature.isAutoAttackable(player))
{
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, creature);
} }
else if (monster.hasAI() && !monster.getAI().isAutoAttacking()) }
else if (creature.hasAI() && !creature.getAI().isAutoAttacking())
{ {
final Weapon weapon = player.getActiveWeaponItem(); final Weapon weapon = player.getActiveWeaponItem();
if (weapon != null) if (weapon != null)
{ {
final boolean ranged = weapon.getItemType().isRanged(); final boolean ranged = weapon.getItemType().isRanged();
final double angle = Util.calculateHeadingFrom(player, monster); final double angle = Util.calculateHeadingFrom(player, creature);
final double radian = Math.toRadians(angle); final double radian = Math.toRadians(angle);
final double course = Math.toRadians(180); final double course = Math.toRadians(180);
final double distance = (ranged ? player.getCollisionRadius() : player.getCollisionRadius() + monster.getCollisionRadius()) * 2; final double distance = (ranged ? player.getCollisionRadius() : player.getCollisionRadius() + creature.getCollisionRadius()) * 2;
final int x1 = (int) (Math.cos(Math.PI + radian + course) * distance); final int x1 = (int) (Math.cos(Math.PI + radian + course) * distance);
final int y1 = (int) (Math.sin(Math.PI + radian + course) * distance); final int y1 = (int) (Math.sin(Math.PI + radian + course) * distance);
final Location location; final Location location;
@@ -117,7 +124,7 @@ public class AutoPlayTaskManager
} }
else else
{ {
location = new Location(monster.getX() + x1, monster.getY() + y1, player.getZ()); location = new Location(creature.getX() + x1, creature.getY() + y1, player.getZ());
} }
player.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, location); player.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, location);
} }
@@ -160,38 +167,41 @@ public class AutoPlayTaskManager
} }
// Find target. // Find target.
Monster monster = null; Creature creature = null;
double closestDistance = Double.MAX_VALUE; double closestDistance = Double.MAX_VALUE;
TARGET: for (Monster nearby : World.getInstance().getVisibleObjectsInRange(player, Monster.class, player.getAutoPlaySettings().isShortRange() ? 600 : 1400)) TARGET: for (Creature nearby : World.getInstance().getVisibleObjectsInRange(player, Creature.class, player.getAutoPlaySettings().isShortRange() ? 600 : 1400))
{ {
// Skip unavailable monsters. // Skip unavailable creatures.
if ((nearby == null) || nearby.isAlikeDead()) if ((nearby == null) || nearby.isAlikeDead())
{ {
continue TARGET; continue TARGET;
} }
// Check monster target. // Check creature target.
if (player.getAutoPlaySettings().isRespectfulHunting() && (nearby.getTarget() != null) && (nearby.getTarget() != player) && !player.getServitors().containsKey(nearby.getTarget().getObjectId())) if (player.getAutoPlaySettings().isRespectfulHunting() && !nearby.isPlayable() && (nearby.getTarget() != null) && (nearby.getTarget() != player) && !player.getServitors().containsKey(nearby.getTarget().getObjectId()))
{ {
continue TARGET; continue TARGET;
} }
// Check if monster is reachable. // Check next target mode.
if (nearby.isAutoAttackable(player) // if (!isTargetModeValid(targetMode, player, nearby))
&& GeoEngine.getInstance().canSeeTarget(player, nearby)//
&& GeoEngine.getInstance().canMoveToTarget(player.getX(), player.getY(), player.getZ(), nearby.getX(), nearby.getY(), nearby.getZ(), player.getInstanceWorld()))
{ {
final double monsterDistance = player.calculateDistance2D(nearby); continue TARGET;
if (monsterDistance < closestDistance) }
// Check if creature is reachable.
if (GeoEngine.getInstance().canSeeTarget(player, nearby) && GeoEngine.getInstance().canMoveToTarget(player.getX(), player.getY(), player.getZ(), nearby.getX(), nearby.getY(), nearby.getZ(), player.getInstanceWorld()))
{ {
monster = nearby; final double creatureDistance = player.calculateDistance2D(nearby);
closestDistance = monsterDistance; if (creatureDistance < closestDistance)
{
creature = nearby;
closestDistance = creatureDistance;
} }
} }
} }
// New target was assigned. // New target was assigned.
if (monster != null) if (creature != null)
{ {
player.setTarget(monster); player.setTarget(creature);
// We take granted that mage classes do not auto hit. // We take granted that mage classes do not auto hit.
if (isMageCaster(player)) if (isMageCaster(player))
@@ -215,6 +225,33 @@ public class AutoPlayTaskManager
// Non Essence like. // Non Essence like.
return player.isMageClass() && (player.getRace() != Race.ORC); return player.isMageClass() && (player.getRace() != Race.ORC);
} }
private boolean isTargetModeValid(int mode, Player player, Creature creature)
{
switch (mode)
{
case 1: // Monster
{
return creature.isMonster();
}
case 2: // Characters
{
return creature.isPlayable() && creature.isAutoAttackable(player);
}
case 3: // NPC
{
return creature.isNpc() && !creature.isMonster() && !creature.isInsideZone(ZoneId.PEACE);
}
case 4: // Counterattack
{
return creature.isMonster() || (creature.isPlayable() && creature.isAutoAttackable(player));
}
default: // Any Target
{
return (creature.isNpc() && !creature.isInsideZone(ZoneId.PEACE)) || (creature.isPlayable() && creature.isAutoAttackable(player));
}
}
}
} }
public synchronized void doAutoPlay(Player player) public synchronized void doAutoPlay(Player player)

View File

@@ -343,9 +343,13 @@ public class AutoUseTaskManager
// Do not attack guards. // Do not attack guards.
if (target instanceof Guard) if (target instanceof Guard)
{
final int targetMode = player.getAutoPlaySettings().getNextTargetMode();
if (((targetMode != 3 /* NPC */) && (targetMode != 0 /* Any Target */)) || target.isInsideZone(ZoneId.PEACE) || !target.isAutoAttackable(player))
{ {
break SKILLS; break SKILLS;
} }
}
if (!canUseMagic(player, target, skill) || (pet != null ? pet : player).useMagic(skill, null, true, false)) if (!canUseMagic(player, target, skill) || (pet != null ? pet : player).useMagic(skill, null, true, false))
{ {