Last active
October 17, 2020 22:44
-
-
Save maneco2/bb823b8c4a01dc7ae77015e8707fd61f to your computer and use it in GitHub Desktop.
New Queen Ant AI
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
### Eclipse Workspace Patch 1.0 | |
#P l2j-server-datapack | |
diff --git src/main/java/com/l2jserver/datapack/ai/individual/QueenAnt.java src/main/java/com/l2jserver/datapack/ai/individual/QueenAnt.java | |
index 5d57d77..d637155 100644 | |
--- src/main/java/com/l2jserver/datapack/ai/individual/QueenAnt.java | |
+++ src/main/java/com/l2jserver/datapack/ai/individual/QueenAnt.java | |
@@ -19,34 +19,38 @@ | |
package com.l2jserver.datapack.ai.individual; | |
import static com.l2jserver.gameserver.config.Configuration.grandBoss; | |
-import static com.l2jserver.gameserver.config.Configuration.npc; | |
import java.util.List; | |
import java.util.concurrent.CopyOnWriteArrayList; | |
import com.l2jserver.datapack.ai.npc.AbstractNpcAI; | |
import com.l2jserver.gameserver.ai.CtrlIntention; | |
+import com.l2jserver.gameserver.enums.MountType; | |
import com.l2jserver.gameserver.enums.audio.Music; | |
import com.l2jserver.gameserver.instancemanager.GrandBossManager; | |
+import com.l2jserver.gameserver.model.L2Object; | |
import com.l2jserver.gameserver.model.Location; | |
import com.l2jserver.gameserver.model.StatsSet; | |
import com.l2jserver.gameserver.model.actor.L2Attackable; | |
+import com.l2jserver.gameserver.model.actor.L2Character; | |
import com.l2jserver.gameserver.model.actor.L2Npc; | |
-import com.l2jserver.gameserver.model.actor.L2Playable; | |
import com.l2jserver.gameserver.model.actor.instance.L2GrandBossInstance; | |
import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance; | |
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance; | |
import com.l2jserver.gameserver.model.holders.SkillHolder; | |
-import com.l2jserver.gameserver.model.skills.CommonSkill; | |
+import com.l2jserver.gameserver.model.skills.AttributeType; | |
import com.l2jserver.gameserver.model.skills.Skill; | |
+import com.l2jserver.gameserver.model.zone.L2ZoneType; | |
import com.l2jserver.gameserver.model.zone.type.L2BossZone; | |
import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse; | |
/** | |
- * Queen Ant's AI | |
+ * Queen Ant AI | |
* @author Emperorc | |
+ * @author Maneco2 | |
*/ | |
public final class QueenAnt extends AbstractNpcAI { | |
+ // NPCs | |
private static final int QUEEN = 29001; | |
private static final int LARVA = 29002; | |
private static final int NURSE = 29003; | |
@@ -61,57 +65,62 @@ | |
ROYAL | |
}; | |
- private static final Location OUST_LOC_1 = new Location(-19480, 187344, -5600); | |
- private static final Location OUST_LOC_2 = new Location(-17928, 180912, -5520); | |
- private static final Location OUST_LOC_3 = new Location(-23808, 182368, -5600); | |
- | |
+ // Queen Ant Location | |
private static final int QUEEN_X = -21610; | |
private static final int QUEEN_Y = 181594; | |
private static final int QUEEN_Z = -5734; | |
- | |
- // QUEEN Status Tracking : | |
- private static final byte ALIVE = 0; // Queen Ant is spawned. | |
- private static final byte DEAD = 1; // Queen Ant has been killed. | |
- | |
+ // Larva Location | |
+ private static final Location LARVA_LOCATION = new Location(-21600, 179482, -5846, getRandom(360)); | |
+ // Zones | |
+ private static final int ZONE = 12012; | |
+ private static final Location TELE_LOCATION_1 = new Location(-19480, 187344, -5600); | |
+ private static final Location TELE_LOCATION_2 = new Location(-17928, 180912, -5520); | |
+ private static final Location TELE_LOCATION_3 = new Location(-23808, 182368, -5600); | |
+ // Skills | |
+ private static final SkillHolder RAID_CURSE = new SkillHolder(4215); // Raid Curse - Silence | |
+ private static final SkillHolder RAID_CURSE_2 = new SkillHolder(4515); // Raid Curse - Stone | |
+ private static final SkillHolder QUEEN_ANT_BRANDISH = new SkillHolder(4017); // Queen Ant Brandish | |
+ private static final SkillHolder DECREASE_SPEED_1 = new SkillHolder(4018); // Decrease Speed | |
+ private static final SkillHolder DECREASE_SPEED_2 = new SkillHolder(4019); // Decrease Speed | |
+ private static final SkillHolder HEAL_QUEEN_ANT_1 = new SkillHolder(4020); // Heal Queen Ant1 | |
+ private static final SkillHolder HEAL_QUEEN_ANT_2 = new SkillHolder(4024); // Heal Queen Ant2 | |
+ private static final SkillHolder ANTI_STRIDER = new SkillHolder(4258); // Hinder Strider | |
+ // Variables | |
private static L2BossZone _zone; | |
- | |
- private static SkillHolder HEAL1 = new SkillHolder(4020, 1); | |
- private static SkillHolder HEAL2 = new SkillHolder(4024, 1); | |
- | |
+ private static final String ATTACK_FLAG = "ATTACK_FLAG"; | |
private L2MonsterInstance _queen = null; | |
private L2MonsterInstance _larva = null; | |
private final List<L2MonsterInstance> _nurses = new CopyOnWriteArrayList<>(); | |
+ // Status | |
+ private static final int ALIVE = 0; | |
+ private static final int DEAD = 1; | |
public QueenAnt() { | |
super(QueenAnt.class.getSimpleName(), "ai/individual"); | |
- addSpawnId(MOBS); | |
addKillId(MOBS); | |
- addAggroRangeEnterId(MOBS); | |
- addFactionCallId(NURSE); | |
+ addSpawnId(MOBS); | |
+ addExitZoneId(ZONE); | |
+ addEnterZoneId(ZONE); | |
+ addSkillSeeId(QUEEN); | |
+ addMoveFinishedId(QUEEN); | |
+ addAttackId(QUEEN, NURSE, GUARD, ROYAL); | |
_zone = GrandBossManager.getInstance().getZone(QUEEN_X, QUEEN_Y, QUEEN_Z); | |
- StatsSet info = GrandBossManager.getInstance().getStatsSet(QUEEN); | |
- int status = GrandBossManager.getInstance().getBossStatus(QUEEN); | |
- if (status == DEAD) { | |
- // load the unlock date and time for queen ant from DB | |
- long temp = info.getLong("respawn_time") - System.currentTimeMillis(); | |
- // if queen ant is locked until a certain time, mark it so and start the unlock timer | |
- // the unlock time has not yet expired. | |
- if (temp > 0) { | |
- startQuestTimer("queen_unlock", temp, null, null); | |
+ final StatsSet info = GrandBossManager.getInstance().getStatsSet(QUEEN); | |
+ if (GrandBossManager.getInstance().getBossStatus(QUEEN) == DEAD) { | |
+ final long remain = info.getLong("respawn_time") - System.currentTimeMillis(); | |
+ if (remain > 0) { | |
+ startQuestTimer("QUEEN_UNLOCK", remain, null, null); | |
} else { | |
- // the time has already expired while the server was offline. Immediately spawn queen ant. | |
- L2GrandBossInstance queen = (L2GrandBossInstance) addSpawn(QUEEN, QUEEN_X, QUEEN_Y, QUEEN_Z, 0, false, 0); | |
- GrandBossManager.getInstance().setBossStatus(QUEEN, ALIVE); | |
- spawnBoss(queen); | |
+ notifyEvent("QUEEN_UNLOCK", null, null); | |
} | |
} else { | |
+ int hp = info.getInt("currentHP"); | |
+ int mp = info.getInt("currentMP"); | |
int loc_x = info.getInt("loc_x"); | |
int loc_y = info.getInt("loc_y"); | |
int loc_z = info.getInt("loc_z"); | |
int heading = info.getInt("heading"); | |
- int hp = info.getInt("currentHP"); | |
- int mp = info.getInt("currentMP"); | |
if (!_zone.isInsideZone(loc_x, loc_y, loc_z)) { | |
loc_x = QUEEN_X; | |
loc_y = QUEEN_Y; | |
@@ -123,183 +132,246 @@ | |
} | |
} | |
- private void spawnBoss(L2GrandBossInstance npc) { | |
- GrandBossManager.getInstance().addBoss(npc); | |
- if (getRandom(100) < 33) { | |
- _zone.movePlayersTo(OUST_LOC_1); | |
- } else if (getRandom(100) < 50) { | |
- _zone.movePlayersTo(OUST_LOC_2); | |
- } else { | |
- _zone.movePlayersTo(OUST_LOC_3); | |
+ @Override | |
+ public String onAdvEvent(String event, L2Npc npc, L2PcInstance player) { | |
+ switch (event) { | |
+ case "CHECK_ZONE": { | |
+ if (npc != null) { | |
+ addMoveToDesire(npc, new Location(-21610, 181594, -5734, 0), 0); | |
+ if (_zone.isInsideZone(npc)) { | |
+ cancelQuestTimers("CHECK_ZONE"); | |
+ } | |
+ } | |
+ break; | |
+ } | |
+ case "CORE_AI": { | |
+ if ((npc != null) && (npc.isCoreAIDisabled()) && (_zone.isInsideZone(npc))) { | |
+ ((L2Attackable) npc).clearAggroList(); | |
+ npc.disableCoreAI(false); | |
+ npc.setIsImmobilized(false); | |
+ npc.getVariables().set(ATTACK_FLAG, false); | |
+ } | |
+ break; | |
+ } | |
+ case "CORE_MOVEMENT": { | |
+ if (npc != null) { | |
+ final L2Object obj = npc.getTarget(); | |
+ if ((obj != null) && (obj.isPlayer()) && (_zone.isInsideZone(obj))) { | |
+ _queen.setIsImmobilized(false); | |
+ } | |
+ npc.getVariables().set(ATTACK_FLAG, false); | |
+ } | |
+ break; | |
+ } | |
+ case "HEAL": { | |
+ if ((npc != null) && (!npc.isCastingNow())) { | |
+ if ((_larva != null) && (_queen != null)) { | |
+ if (_larva.getCurrentHp() < _larva.getMaxHp()) { | |
+ if (npc.calculateDistance(_larva, false, false) < 2500) { | |
+ addSkillCastDesire(npc, _larva, getRandomBoolean() ? HEAL_QUEEN_ANT_1 : HEAL_QUEEN_ANT_2, 100L); | |
+ } else { | |
+ addMoveToDesire(npc, LARVA_LOCATION, 0); | |
+ } | |
+ } else if (_queen.getCurrentHp() < _queen.getMaxHp()) { | |
+ addSkillCastDesire(npc, _queen, HEAL_QUEEN_ANT_1, 1000000L); | |
+ } | |
+ } | |
+ if ((!npc.isMoving()) && (npc.getAI().getIntention() == CtrlIntention.AI_INTENTION_ATTACK)) { | |
+ ((L2Attackable) npc).clearAggroList(); | |
+ npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE); | |
+ } | |
+ } | |
+ break; | |
+ } | |
+ case "ACTION": { | |
+ if ((getRandom(100) < 30) && (npc != null) && (!npc.isInCombat())) { | |
+ if (getRandom(100) < 50) { | |
+ npc.broadcastSocialAction(3); | |
+ } else { | |
+ npc.broadcastSocialAction(4); | |
+ } | |
+ } | |
+ break; | |
+ } | |
+ case "QUEEN_UNLOCK": { | |
+ L2GrandBossInstance queen = (L2GrandBossInstance) addSpawn(QUEEN, QUEEN_X, QUEEN_Y, QUEEN_Z, 0, false, 0); | |
+ GrandBossManager.getInstance().setBossStatus(QUEEN, ALIVE); | |
+ spawnBoss(queen); | |
+ break; | |
+ } | |
+ case "RAID_CURSE": { | |
+ if ((player != null) && (!_zone.isInsideZone(player))) { | |
+ cancelQuestTimers("RAID_CURSE"); | |
+ } else if ((player != null) && (!player.isDead()) && (_zone.isInsideZone(player)) && (_queen != null) && (!_queen.isDead())) { | |
+ if ((player.getLevel() - _queen.getLevel()) > 8) { | |
+ if (player.isMageClass()) { | |
+ if (!player.isAffectedBySkill(RAID_CURSE.getSkillId())) { | |
+ _queen.broadcastPacket(new MagicSkillUse(_queen, player, RAID_CURSE.getSkillId(), 1, 300, 0)); | |
+ RAID_CURSE.getSkill().applyEffects(_queen, player); | |
+ } | |
+ } else { | |
+ if (!player.isAffectedBySkill(RAID_CURSE_2.getSkillId())) { | |
+ _queen.broadcastPacket(new MagicSkillUse(_queen, player, RAID_CURSE_2.getSkillId(), 1, 300, 0)); | |
+ RAID_CURSE_2.getSkill().applyEffects(_queen, player); | |
+ } | |
+ } | |
+ } | |
+ } | |
+ break; | |
+ } | |
+ case "RESPAWN_QUEEN": { | |
+ if (GrandBossManager.getInstance().getBossStatus(QUEEN) == DEAD) { | |
+ GrandBossManager.getInstance().getStatsSet(QUEEN).set("respawn_time", 0); | |
+ cancelQuestTimers("QUEEN_UNLOCK"); | |
+ notifyEvent("QUEEN_UNLOCK", null, null); | |
+ } else { | |
+ player.sendMessage(getClass().getSimpleName() + ": You cant respawn Queen Ant while Queen Ant is alive!"); | |
+ } | |
+ break; | |
+ } | |
} | |
- GrandBossManager.getInstance().addBoss(npc); | |
- startQuestTimer("action", 10000, npc, null, true); | |
- startQuestTimer("heal", 1000, null, null, true); | |
- npc.broadcastPacket(Music.BS01_A_10000.getPacket()); | |
- _queen = npc; | |
- _larva = (L2MonsterInstance) addSpawn(LARVA, -21600, 179482, -5846, getRandom(360), false, 0); | |
+ return super.onAdvEvent(event, npc, player); | |
} | |
@Override | |
- public String onAdvEvent(String event, L2Npc npc, L2PcInstance player) { | |
- if (event.equalsIgnoreCase("heal")) { | |
- boolean notCasting; | |
- final boolean larvaNeedHeal = (_larva != null) && (_larva.getCurrentHp() < _larva.getMaxHp()); | |
- final boolean queenNeedHeal = (_queen != null) && (_queen.getCurrentHp() < _queen.getMaxHp()); | |
- for (L2MonsterInstance nurse : _nurses) { | |
- if ((nurse == null) || nurse.isDead() || nurse.isCastingNow()) { | |
- continue; | |
- } | |
- | |
- notCasting = nurse.getAI().getIntention() != CtrlIntention.AI_INTENTION_CAST; | |
- if (larvaNeedHeal) { | |
- if ((nurse.getTarget() != _larva) || notCasting) { | |
- nurse.setTarget(_larva); | |
- nurse.useMagic(getRandomBoolean() ? HEAL1.getSkill() : HEAL2.getSkill()); | |
+ public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon, Skill skill) { | |
+ if ((_zone.isInsideZone(npc)) && (npc != null) && (_queen != null) && (!npc.isCastingNow()) && (!npc.isCoreAIDisabled())) { | |
+ switch (npc.getId()) { | |
+ case QUEEN: { | |
+ if ((attacker.getMountType() == MountType.STRIDER) && !attacker.isAffectedBySkill(ANTI_STRIDER.getSkillId())) { | |
+ if (npc.checkDoCastConditions(ANTI_STRIDER.getSkill())) { | |
+ addSkillCastDesire(npc, attacker, ANTI_STRIDER, 1000000L); | |
+ } | |
+ } else if ((skill != null) && (skill.getAttributeType() == AttributeType.FIRE) && (getRandom(100) < 70)) { | |
+ addSkillCastDesire(npc, attacker, DECREASE_SPEED_1, 1000000L); | |
+ } else if ((npc.calculateDistance(attacker, false, false) > 500) && (getRandom(100) < 10)) { | |
+ addSkillCastDesire(npc, attacker, DECREASE_SPEED_2, 1000000L); | |
+ } else if ((npc.calculateDistance(attacker, false, false) > 150) && (getRandom(100) < 10)) { | |
+ if ((npc.calculateDistance(attacker, false, false) < 500) && (getRandom(100) < 80)) { | |
+ addSkillCastDesire(npc, attacker, DECREASE_SPEED_1, 1000000L); | |
+ } else { | |
+ addSkillCastDesire(npc, attacker, DECREASE_SPEED_2, 1000000L); | |
+ } | |
+ } else if ((npc.calculateDistance(attacker, false, false) < 250) && (getRandom(100) < 5)) { | |
+ addSkillCastDesire(npc, attacker, QUEEN_ANT_BRANDISH, 1000000L); | |
} | |
- continue; | |
+ break; | |
} | |
- if (queenNeedHeal) { | |
- if (nurse.getLeader() == _larva) { | |
- continue; | |
+ case NURSE: | |
+ case ROYAL: { | |
+ if ((_queen.calculateDistance(attacker, false, false) > 500) && (getRandom(100) < 5)) { | |
+ addSkillCastDesire(_queen, attacker, DECREASE_SPEED_2, 1000000L); | |
+ } else if ((_queen.calculateDistance(attacker, false, false) > 150) && (getRandom(100) < 5)) { | |
+ if (getRandom(100) < 80) { | |
+ addSkillCastDesire(_queen, attacker, DECREASE_SPEED_1, 1000000L); | |
+ } else { | |
+ addSkillCastDesire(_queen, attacker, DECREASE_SPEED_2, 1000000L); | |
+ } | |
+ } else if ((_queen.calculateDistance(attacker, false, false) < 250) && (getRandom(100) < 2)) { | |
+ addSkillCastDesire(_queen, attacker, QUEEN_ANT_BRANDISH, 1000000L); | |
} | |
- | |
- if ((nurse.getTarget() != _queen) || notCasting) { | |
- nurse.setTarget(_queen); | |
- nurse.useMagic(HEAL1.getSkill()); | |
- } | |
- continue; | |
+ break; | |
} | |
- // if nurse not casting - remove target | |
- if (notCasting && (nurse.getTarget() != null)) { | |
- nurse.setTarget(null); | |
+ case GUARD: { | |
+ if (attacker.isPlayer()) { | |
+ if ((_queen.calculateDistance(attacker, false, false) > 500) && (getRandom(100) < 3)) { | |
+ addSkillCastDesire(_queen, attacker, DECREASE_SPEED_2, 1000000L); | |
+ } else if ((_queen.calculateDistance(attacker, false, false) > 150) && (getRandom(100) < 3)) { | |
+ if (getRandom(100) < 80) { | |
+ addSkillCastDesire(_queen, attacker, DECREASE_SPEED_1, 1000000L); | |
+ } else { | |
+ addSkillCastDesire(_queen, attacker, DECREASE_SPEED_2, 1000000L); | |
+ } | |
+ } else if ((_queen.calculateDistance(attacker, false, false) < 250) && (getRandom(100) < 2)) { | |
+ addSkillCastDesire(_queen, attacker, QUEEN_ANT_BRANDISH, 1000000L); | |
+ } | |
+ } | |
+ break; | |
} | |
} | |
- } else if (event.equalsIgnoreCase("action") && (npc != null)) { | |
- if (getRandom(3) == 0) { | |
- if (getRandom(2) == 0) { | |
- npc.broadcastSocialAction(3); | |
- } else { | |
- npc.broadcastSocialAction(4); | |
- } | |
- } | |
- } else if (event.equalsIgnoreCase("queen_unlock")) { | |
- L2GrandBossInstance queen = (L2GrandBossInstance) addSpawn(QUEEN, QUEEN_X, QUEEN_Y, QUEEN_Z, 0, false, 0); | |
- GrandBossManager.getInstance().setBossStatus(QUEEN, ALIVE); | |
- spawnBoss(queen); | |
} | |
- return super.onAdvEvent(event, npc, player); | |
+ if ((!npc.getVariables().getBoolean(ATTACK_FLAG, false)) && !npc.isCoreAIDisabled()) { | |
+ if (npc.calculateDistance(attacker, false, false) > 150) { | |
+ _queen.setIsImmobilized(true); | |
+ } | |
+ npc.getVariables().set(ATTACK_FLAG, true); | |
+ startQuestTimer("CORE_MOVEMENT", 5000, npc, null); | |
+ } | |
+ return super.onAttack(npc, attacker, damage, isSummon, skill); | |
+ } | |
+ | |
+ @Override | |
+ public String onSkillSee(L2Npc npc, L2PcInstance player, Skill skill, L2Object[] targets, boolean isSummon) { | |
+ if ((skill.getEffectPoint() > 0) && (getRandom(100) < 15)) { | |
+ if ((_zone.isInsideZone(npc)) && (npc != null) && (!npc.isCastingNow()) && (!npc.isCoreAIDisabled())) { | |
+ addSkillCastDesire(npc, player, DECREASE_SPEED_1, 1000000L); | |
+ } | |
+ } | |
+ return super.onSkillSee(npc, player, skill, targets, isSummon); | |
} | |
@Override | |
public String onSpawn(L2Npc npc) { | |
final L2MonsterInstance mob = (L2MonsterInstance) npc; | |
switch (npc.getId()) { | |
- case LARVA: | |
- mob.setIsImmobilized(true); | |
+ case QUEEN: { | |
+ startQuestTimer("ACTION", 10000, npc, null, true); | |
+ break; | |
+ } | |
+ case LARVA: { | |
mob.setIsMortal(false); | |
mob.setIsRaidMinion(true); | |
+ mob.setIsImmobilized(true); | |
break; | |
- case NURSE: | |
+ } | |
+ case NURSE: { | |
+ _nurses.add(mob); | |
mob.disableCoreAI(true); | |
mob.setIsRaidMinion(true); | |
- _nurses.add(mob); | |
+ startQuestTimer("HEAL", 2000, mob, null, true); | |
break; | |
+ } | |
case ROYAL: | |
- case GUARD: | |
+ case GUARD: { | |
mob.setIsRaidMinion(true); | |
break; | |
+ } | |
} | |
return super.onSpawn(npc); | |
} | |
@Override | |
- public String onFactionCall(L2Npc npc, L2Npc caller, L2PcInstance attacker, boolean isSummon) { | |
- if ((caller == null) || (npc == null)) { | |
- return super.onFactionCall(npc, caller, attacker, isSummon); | |
- } | |
- | |
- if (!npc.isCastingNow() && (npc.getAI().getIntention() != CtrlIntention.AI_INTENTION_CAST)) { | |
- if (caller.getCurrentHp() < caller.getMaxHp()) { | |
- npc.setTarget(caller); | |
- ((L2Attackable) npc).useMagic(HEAL1.getSkill()); | |
- } | |
- } | |
- return null; | |
- } | |
- | |
- @Override | |
- public String onAggroRangeEnter(L2Npc npc, L2PcInstance player, boolean isSummon) { | |
- if ((npc == null) || (player.isGM() && player.isInvisible())) { | |
- return null; | |
- } | |
- | |
- final boolean isMage; | |
- final L2Playable character; | |
- if (isSummon) { | |
- isMage = false; | |
- character = player.getSummon(); | |
- } else { | |
- isMage = player.isMageClass(); | |
- character = player; | |
- } | |
- | |
- if (character == null) { | |
- return null; | |
- } | |
- | |
- if (npc().raidCurse() && ((character.getLevel() - npc.getLevel()) > 8)) { | |
- Skill curse = null; | |
- if (isMage) { | |
- if (!character.isMuted() && (getRandom(4) == 0)) { | |
- curse = CommonSkill.RAID_CURSE.getSkill(); | |
- } | |
- } else { | |
- if (!character.isParalyzed() && (getRandom(4) == 0)) { | |
- curse = CommonSkill.RAID_CURSE2.getSkill(); | |
- } | |
- } | |
- | |
- if (curse != null) { | |
- npc.broadcastPacket(new MagicSkillUse(npc, character, curse.getId(), curse.getLevel(), 300, 0)); | |
- curse.applyEffects(npc, character); | |
- } | |
- | |
- ((L2Attackable) npc).stopHating(character); // for calling again | |
- return null; | |
- } | |
- | |
- return super.onAggroRangeEnter(npc, player, isSummon); | |
+ public String onEnterZone(L2Character character, L2ZoneType zone) { | |
+ final L2PcInstance player = character.getActingPlayer(); | |
+ notifyEvent("RAID_CURSE", _queen, player); | |
+ startQuestTimer("RAID_CURSE", 3000, _queen, player, true); | |
+ return super.onEnterZone(character, zone); | |
} | |
@Override | |
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon) { | |
- int npcId = npc.getId(); | |
- if (npcId == QUEEN) { | |
+ if (npc.getId() == QUEEN) { | |
+ cancelQuestTimers("HEAL"); | |
+ cancelQuestTimers("ACTION"); | |
npc.broadcastPacket(Music.BS02_D_10000.getPacket()); | |
GrandBossManager.getInstance().setBossStatus(QUEEN, DEAD); | |
- // Calculate Min and Max respawn times randomly. | |
- long respawnTime = grandBoss().getIntervalOfQueenAntSpawn() + getRandom(-grandBoss().getRandomOfQueenAntSpawn(), grandBoss().getRandomOfQueenAntSpawn()); | |
- respawnTime *= 3600000; | |
- startQuestTimer("queen_unlock", respawnTime, null, null); | |
- cancelQuestTimer("action", npc, null); | |
- cancelQuestTimer("heal", null, null); | |
- // also save the respawn time so that the info is maintained past reboots | |
- StatsSet info = GrandBossManager.getInstance().getStatsSet(QUEEN); | |
- info.set("respawn_time", System.currentTimeMillis() + respawnTime); | |
- GrandBossManager.getInstance().setStatsSet(QUEEN, info); | |
+ final long respawnTime = (grandBoss().getIntervalOfQueenAntSpawn() + getRandom(-grandBoss().getRandomOfQueenAntSpawn(), grandBoss().getRandomOfQueenAntSpawn())) * 3600000; | |
+ GrandBossManager.getInstance().getStatsSet(QUEEN).set("respawn_time", (System.currentTimeMillis() + respawnTime)); | |
+ startQuestTimer("QUEEN_UNLOCK", respawnTime, null, null); | |
_nurses.clear(); | |
- _larva.deleteMe(); | |
- _larva = null; | |
_queen = null; | |
+ if (_larva != null) { | |
+ _larva.deleteMe(); | |
+ _larva = null; | |
+ } | |
} else if ((_queen != null) && !_queen.isAlikeDead()) { | |
- if (npcId == ROYAL) { | |
+ if (npc.getId() == ROYAL) { | |
L2MonsterInstance mob = (L2MonsterInstance) npc; | |
if (mob.getLeader() != null) { | |
mob.getLeader().getMinionList().onMinionDie(mob, (280 + getRandom(40)) * 1000); | |
} | |
- } else if (npcId == NURSE) { | |
+ } else if (npc.getId() == NURSE) { | |
L2MonsterInstance mob = (L2MonsterInstance) npc; | |
_nurses.remove(mob); | |
if (mob.getLeader() != null) { | |
@@ -307,6 +379,36 @@ | |
} | |
} | |
} | |
+ | |
return super.onKill(npc, killer, isSummon); | |
} | |
+ | |
+ @Override | |
+ public String onExitZone(L2Character character, L2ZoneType zone) { | |
+ if ((character.isAttackable()) && (character.isRaid()) && (!_zone.isInsideZone(_queen)) && (_queen != null)) { | |
+ _queen.disableCoreAI(true); | |
+ _queen.setIsImmobilized(false); | |
+ startQuestTimer("CHECK_ZONE", 1000, _queen, null, true); | |
+ } | |
+ return super.onExitZone(character, zone); | |
+ } | |
+ | |
+ @Override | |
+ public void onMoveFinished(L2Npc npc) { | |
+ startQuestTimer("CORE_AI", 100, npc, null); | |
+ } | |
+ | |
+ private void spawnBoss(L2GrandBossInstance npc) { | |
+ if (getRandom(100) < 33) { | |
+ _zone.movePlayersTo(TELE_LOCATION_1); | |
+ } else if (getRandom(100) < 50) { | |
+ _zone.movePlayersTo(TELE_LOCATION_2); | |
+ } else { | |
+ _zone.movePlayersTo(TELE_LOCATION_3); | |
+ } | |
+ GrandBossManager.getInstance().addBoss(npc); | |
+ npc.broadcastPacket(Music.BS01_A_10000.getPacket()); | |
+ _queen = npc; | |
+ _larva = (L2MonsterInstance) addSpawn(LARVA, LARVA_LOCATION, false, 0); | |
+ } | |
} | |
diff --git src/main/java/com/l2jserver/datapack/handlers/admincommandhandlers/AdminGrandBoss.java src/main/java/com/l2jserver/datapack/handlers/admincommandhandlers/AdminGrandBoss.java | |
index ea68d6d..8bcb95a 100644 | |
--- src/main/java/com/l2jserver/datapack/handlers/admincommandhandlers/AdminGrandBoss.java | |
+++ src/main/java/com/l2jserver/datapack/handlers/admincommandhandlers/AdminGrandBoss.java | |
@@ -22,6 +22,7 @@ | |
import java.util.Arrays; | |
import java.util.StringTokenizer; | |
+import com.l2jserver.datapack.ai.individual.QueenAnt; | |
import com.l2jserver.datapack.ai.individual.Antharas.Antharas; | |
import com.l2jserver.datapack.ai.individual.Baium.Baium; | |
import com.l2jserver.gameserver.cache.HtmCache; | |
@@ -78,7 +79,7 @@ | |
final int grandBossId = Integer.parseInt(st.nextToken()); | |
if (grandBossId == ANTHARAS) { | |
- antharasAi().notifyEvent("SKIP_WAITING", null, activeChar); | |
+ getAntharasAI().notifyEvent("SKIP_WAITING", null, activeChar); | |
manageHtml(activeChar, grandBossId); | |
} else { | |
activeChar.sendMessage("Wrong ID!"); | |
@@ -94,12 +95,17 @@ | |
switch (grandBossId) { | |
case ANTHARAS: { | |
- antharasAi().notifyEvent("RESPAWN_ANTHARAS", null, activeChar); | |
+ getAntharasAI().notifyEvent("RESPAWN_ANTHARAS", null, activeChar); | |
manageHtml(activeChar, grandBossId); | |
break; | |
} | |
case BAIUM: { | |
- baiumAi().notifyEvent("RESPAWN_BAIUM", null, activeChar); | |
+ getBaiumAI().notifyEvent("RESPAWN_BAIUM", null, activeChar); | |
+ manageHtml(activeChar, grandBossId); | |
+ break; | |
+ } | |
+ case QUEENANT: { | |
+ getQueenAntAI().notifyEvent("RESPAWN_QUEEN", null, activeChar); | |
manageHtml(activeChar, grandBossId); | |
break; | |
} | |
@@ -118,11 +124,11 @@ | |
switch (grandBossId) { | |
case ANTHARAS: { | |
- antharasAi().notifyEvent("DESPAWN_MINIONS", null, activeChar); | |
+ getAntharasAI().notifyEvent("DESPAWN_MINIONS", null, activeChar); | |
break; | |
} | |
case BAIUM: { | |
- baiumAi().notifyEvent("DESPAWN_MINIONS", null, activeChar); | |
+ getBaiumAI().notifyEvent("DESPAWN_MINIONS", null, activeChar); | |
break; | |
} | |
default: { | |
@@ -140,12 +146,12 @@ | |
switch (grandBossId) { | |
case ANTHARAS: { | |
- antharasAi().notifyEvent("ABORT_FIGHT", null, activeChar); | |
+ getAntharasAI().notifyEvent("ABORT_FIGHT", null, activeChar); | |
manageHtml(activeChar, grandBossId); | |
break; | |
} | |
case BAIUM: { | |
- baiumAi().notifyEvent("ABORT_FIGHT", null, activeChar); | |
+ getBaiumAI().notifyEvent("ABORT_FIGHT", null, activeChar); | |
manageHtml(activeChar, grandBossId); | |
break; | |
} | |
@@ -255,14 +261,18 @@ | |
} | |
} | |
- private Quest antharasAi() { | |
+ private Quest getAntharasAI() { | |
return QuestManager.getInstance().getQuest(Antharas.class.getSimpleName()); | |
} | |
- private Quest baiumAi() { | |
+ private Quest getBaiumAI() { | |
return QuestManager.getInstance().getQuest(Baium.class.getSimpleName()); | |
} | |
+ private Quest getQueenAntAI() { | |
+ return QuestManager.getInstance().getQuest(QueenAnt.class.getSimpleName()); | |
+ } | |
+ | |
@Override | |
public String[] getAdminCommandList() { | |
return ADMIN_COMMANDS; | |
diff --git src/main/resources/data/html/admin/grandboss_queenant.htm src/main/resources/data/html/admin/grandboss_queenant.htm | |
index d12f2ee..ecc4b96 100644 | |
--- src/main/resources/data/html/admin/grandboss_queenant.htm | |
+++ src/main/resources/data/html/admin/grandboss_queenant.htm | |
@@ -9,7 +9,7 @@ | |
</table> | |
<br> | |
<br> | |
-<font color="LEVEL">Queen ant<font><br> | |
+<font color="LEVEL">Queen Ant<font><br> | |
<table width="270" border="0" bgcolor="444444"> | |
<tr> | |
<td>Status:</td> | |
@@ -22,6 +22,7 @@ | |
</table> | |
<br> | |
<br> | |
+<button value="Respawn Queen Ant" action="bypass -h admin_grandboss_respawn 29001" width=200 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td><br1> | |
<button value="Teleport to Queen Ant" action="bypass -h admin_move_to -21568 181764 -5722" width=200 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td><br1> | |
<button value="Teleport to Queen Ant Larva" action="bypass -h admin_move_to -21598 179595 -5834" width=200 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td><br1> | |
</center> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment