AI movement rework for return to spawn and long range paths.
This commit is contained in:
@@ -137,9 +137,6 @@ AggroDistanceCheckRestoreLife = True
|
||||
# Default: False
|
||||
GuardAttackAggroMob = False
|
||||
|
||||
# True - Allows guards to use return skill after combat.
|
||||
# Default: False
|
||||
EnableGuardReturn = True
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Pets
|
||||
|
||||
@@ -746,7 +746,6 @@ public class Config
|
||||
public static boolean AGGRO_DISTANCE_CHECK_INSTANCES;
|
||||
public static boolean AGGRO_DISTANCE_CHECK_RESTORE_LIFE;
|
||||
public static boolean GUARD_ATTACK_AGGRO_MOB;
|
||||
public static boolean ENABLE_GUARD_RETURN;
|
||||
public static boolean ALLOW_WYVERN_UPGRADER;
|
||||
public static List<Integer> LIST_PET_RENT_NPC;
|
||||
public static double RAID_HP_REGEN_MULTIPLIER;
|
||||
@@ -2239,7 +2238,6 @@ public class Config
|
||||
AGGRO_DISTANCE_CHECK_INSTANCES = npcConfig.getBoolean("AggroDistanceCheckInstances", false);
|
||||
AGGRO_DISTANCE_CHECK_RESTORE_LIFE = npcConfig.getBoolean("AggroDistanceCheckRestoreLife", true);
|
||||
GUARD_ATTACK_AGGRO_MOB = npcConfig.getBoolean("GuardAttackAggroMob", false);
|
||||
ENABLE_GUARD_RETURN = npcConfig.getBoolean("EnableGuardReturn", false);
|
||||
ALLOW_WYVERN_UPGRADER = npcConfig.getBoolean("AllowWyvernUpgrader", false);
|
||||
final String[] listPetRentNpc = npcConfig.getString("ListPetRentNpc", "30827").split(",");
|
||||
LIST_PET_RENT_NPC = new ArrayList<>(listPetRentNpc.length);
|
||||
|
||||
@@ -27,7 +27,6 @@ import java.util.concurrent.Future;
|
||||
import org.l2jmobius.Config;
|
||||
import org.l2jmobius.commons.threads.ThreadPool;
|
||||
import org.l2jmobius.commons.util.Rnd;
|
||||
import org.l2jmobius.gameserver.data.xml.SkillData;
|
||||
import org.l2jmobius.gameserver.enums.AISkillScope;
|
||||
import org.l2jmobius.gameserver.enums.AIType;
|
||||
import org.l2jmobius.gameserver.geoengine.GeoEngine;
|
||||
@@ -602,30 +601,29 @@ public class AttackableAI extends CreatureAI
|
||||
npc.getAttackByList().clear();
|
||||
}
|
||||
|
||||
// If this is a festival monster, then it remains in the same location.
|
||||
// if (npc instanceof FestivalMonster)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// Check if the mob should not return to spawn point
|
||||
if (!npc.canReturnToSpawnPoint())
|
||||
if (!npc.canReturnToSpawnPoint()
|
||||
/* || npc.isReturningToSpawnPoint() */ ) // Commented because sometimes it stops movement.
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the actor is a GuardInstance
|
||||
if ((npc instanceof Guard) && !npc.isWalker())
|
||||
// Order this attackable to return to its spawn because there's no target to attack
|
||||
if (!npc.isWalker() && ((getTarget() == null) || getTarget().isInvisible() || (getTarget().isPlayer() && !getTarget().getActingPlayer().isAlikeDead())))
|
||||
{
|
||||
if (Config.ENABLE_GUARD_RETURN && (npc.getSpawn() != null) && (Util.calculateDistance(npc, npc.getSpawn(), false, false) > 50) && /* !npc.isInsideZone(ZoneId.SIEGE) && */!npc.isCastingNow())
|
||||
{
|
||||
// Custom guard teleport to spawn.
|
||||
npc.clearAggroList();
|
||||
npc.doCast(SkillData.getInstance().getSkill(1050, 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Order to the GuardInstance to return to its home location because there's no target to attack
|
||||
npc.returnHome();
|
||||
}
|
||||
npc.setWalking();
|
||||
npc.returnHome();
|
||||
return;
|
||||
}
|
||||
|
||||
// If this is a festival monster, then it remains in the same location.
|
||||
if (npc instanceof FestivalMonster)
|
||||
// Do not leave dead player
|
||||
if ((getTarget() != null) && getTarget().isPlayer() && getTarget().getActingPlayer().isAlikeDead())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -681,7 +679,6 @@ public class AttackableAI extends CreatureAI
|
||||
// Order to the Monster to random walk (1/100)
|
||||
else if ((npc.getSpawn() != null) && (Rnd.get(RANDOM_WALK_RATE) == 0) && npc.isRandomWalkingEnabled())
|
||||
{
|
||||
|
||||
for (Skill sk : npc.getTemplate().getAISkills(AISkillScope.BUFF))
|
||||
{
|
||||
if (cast(sk))
|
||||
|
||||
@@ -1688,6 +1688,7 @@ public class Attackable extends Npc
|
||||
|
||||
if (hasAI() && (getSpawn() != null))
|
||||
{
|
||||
setReturningToSpawnPoint(true);
|
||||
getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, getSpawn().getLocation());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4433,10 +4433,10 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
// Movement checks.
|
||||
if ((Config.PATHFINDING > 0) && !(this instanceof QuestGuard))
|
||||
{
|
||||
final double originalDistance = distance;
|
||||
final int originalX = x;
|
||||
final int originalY = y;
|
||||
int originalX = x;
|
||||
int originalY = y;
|
||||
final int originalZ = z;
|
||||
final double originalDistance = distance;
|
||||
final int gtx = (originalX - World.WORLD_X_MIN) >> 4;
|
||||
final int gty = (originalY - World.WORLD_Y_MIN) >> 4;
|
||||
if (isOnGeodataPath())
|
||||
@@ -4476,31 +4476,55 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
{
|
||||
// Path calculation -- overrides previous movement check
|
||||
m.geoPath = PathFinding.getInstance().findPath(curX, curY, curZ, originalX, originalY, originalZ, getInstanceId(), isPlayer());
|
||||
if ((m.geoPath == null) || (m.geoPath.size() < 2)) // No path found
|
||||
boolean found = (m.geoPath != null) && (m.geoPath.size() > 1);
|
||||
|
||||
// If not found and it is an Attackable, attempt to find closest path to move location.
|
||||
if (!found && isAttackable())
|
||||
{
|
||||
if (isPlayer() && !_isFlying && !isInWater)
|
||||
int xMin = Math.min(curX, originalX);
|
||||
int xMax = Math.max(curX, originalX);
|
||||
int yMin = Math.min(curY, originalY);
|
||||
int yMax = Math.max(curY, originalY);
|
||||
final int maxDiff = Math.min(Math.max(xMax - xMin, yMax - yMin), 500);
|
||||
xMin -= maxDiff;
|
||||
xMax += maxDiff;
|
||||
yMin -= maxDiff;
|
||||
yMax += maxDiff;
|
||||
int destinationX = 0;
|
||||
int destinationY = 0;
|
||||
double shortDistance = Double.MAX_VALUE;
|
||||
double tempDistance;
|
||||
List<AbstractNodeLoc> tempPath;
|
||||
for (int sX = xMin; sX < xMax; sX += 500)
|
||||
{
|
||||
return;
|
||||
for (int sY = yMin; sY < yMax; sY += 500)
|
||||
{
|
||||
tempDistance = Math.sqrt(Math.pow(sX - originalX, 2) + Math.pow(sY - originalY, 2));
|
||||
if (tempDistance < shortDistance)
|
||||
{
|
||||
tempPath = PathFinding.getInstance().findPath(curX, curY, curZ, sX, sY, originalZ, getInstanceId(), false);
|
||||
found = (tempPath != null) && (tempPath.size() > 1);
|
||||
if (found)
|
||||
{
|
||||
shortDistance = tempDistance;
|
||||
m.geoPath = tempPath;
|
||||
destinationX = sX;
|
||||
destinationY = sY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
found = (m.geoPath != null) && (m.geoPath.size() > 1);
|
||||
if (found)
|
||||
{
|
||||
originalX = destinationX;
|
||||
originalY = destinationY;
|
||||
}
|
||||
// if (!isPlayable() && !isMinion() && (Math.abs(z - curZ) > 140))
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// if (isSummon() && !((Summon) this).getFollowStatus())
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
||||
m.disregardingGeodata = true;
|
||||
|
||||
x = originalX;
|
||||
y = originalY;
|
||||
z = originalZ;
|
||||
distance = originalDistance;
|
||||
}
|
||||
else
|
||||
|
||||
if (found)
|
||||
{
|
||||
m.onGeodataPathIndex = 0; // on first segment
|
||||
m.onGeodataPathIndex = 0; // On first segment.
|
||||
m.geoPathGtx = gtx;
|
||||
m.geoPathGty = gty;
|
||||
m.geoPathAccurateTx = originalX;
|
||||
@@ -4515,6 +4539,20 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
sin = dy / distance;
|
||||
cos = dx / distance;
|
||||
}
|
||||
else // No path found.
|
||||
{
|
||||
if (isPlayer() && !_isFlying && !isInWater)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m.disregardingGeodata = true;
|
||||
|
||||
x = originalX;
|
||||
y = originalY;
|
||||
z = originalZ;
|
||||
distance = originalDistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ public class QuestGuard extends Guard
|
||||
{
|
||||
super(template);
|
||||
setInstanceType(InstanceType.QuestGuard);
|
||||
setCanReturnToSpawnPoint(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user