123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414 |
- /*
- * Copyright (C) 2004-2014 L2J DataPack
- *
- * This file is part of L2J DataPack.
- *
- * L2J DataPack is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * L2J DataPack is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- package ai.individual.Venom;
- import java.util.ArrayList;
- import java.util.List;
- import ai.npc.AbstractNpcAI;
- import com.l2jserver.gameserver.ai.CtrlIntention;
- import com.l2jserver.gameserver.instancemanager.CastleManager;
- import com.l2jserver.gameserver.instancemanager.GlobalVariablesManager;
- import com.l2jserver.gameserver.model.Location;
- import com.l2jserver.gameserver.model.TeleportWhereType;
- import com.l2jserver.gameserver.model.actor.L2Attackable;
- import com.l2jserver.gameserver.model.actor.L2Npc;
- import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
- import com.l2jserver.gameserver.model.events.impl.sieges.castle.OnCastleSiegeFinish;
- import com.l2jserver.gameserver.model.events.impl.sieges.castle.OnCastleSiegeStart;
- import com.l2jserver.gameserver.model.holders.SkillHolder;
- import com.l2jserver.gameserver.model.skills.Skill;
- import com.l2jserver.gameserver.model.zone.ZoneId;
- import com.l2jserver.gameserver.network.NpcStringId;
- import com.l2jserver.gameserver.network.clientpackets.Say2;
- /**
- * Venom AI on Rune Castle.
- * @author nonom, MELERIX
- */
- public final class Venom extends AbstractNpcAI
- {
- private static final int CASTLE = 8; // Rune
-
- private static final int VENOM = 29054;
- private static final int TELEPORT_CUBE = 29055;
- private static final int DUNGEON_KEEPER = 35506;
-
- private static final byte ALIVE = 0;
- private static final byte DEAD = 1;
-
- private static final int HOURS_BEFORE = 24;
-
- private static final Location[] TARGET_TELEPORTS =
- {
- new Location(12860, -49158, 976),
- new Location(14878, -51339, 1024),
- new Location(15674, -49970, 864),
- new Location(15696, -48326, 864),
- new Location(14873, -46956, 1024),
- new Location(12157, -49135, -1088),
- new Location(12875, -46392, -288),
- new Location(14087, -46706, -288),
- new Location(14086, -51593, -288),
- new Location(12864, -51898, -288),
- new Location(15538, -49153, -1056),
- new Location(17001, -49149, -1064)
- };
-
- private static final Location TRHONE = new Location(11025, -49152, -537);
- private static final Location DUNGEON = new Location(11882, -49216, -3008);
- private static final Location TELEPORT = new Location(12589, -49044, -3008);
- private static final Location CUBE = new Location(12047, -49211, -3009);
-
- private static final SkillHolder VENOM_STRIKE = new SkillHolder(4993, 1);
- private static final SkillHolder SONIC_STORM = new SkillHolder(4994, 1);
- private static final SkillHolder VENOM_TELEPORT = new SkillHolder(4995, 1);
- private static final SkillHolder RANGE_TELEPORT = new SkillHolder(4996, 1);
-
- private L2Npc _venom;
- private L2Npc _massymore;
-
- private Location _loc;
-
- private boolean _aggroMode = false;
- private boolean _prisonIsOpen = false;
-
- // @formatter:off
- private static final int[] TARGET_TELEPORTS_OFFSET =
- {
- 650, 100, 100, 100, 100, 650, 200, 200, 200, 200, 200, 650
- };
- // @formatter:on
-
- private static List<L2PcInstance> _targets = new ArrayList<>();
-
- private Venom()
- {
- super(Venom.class.getSimpleName(), "ai/individual");
- addStartNpc(DUNGEON_KEEPER, TELEPORT_CUBE);
- addFirstTalkId(DUNGEON_KEEPER, TELEPORT_CUBE);
- addTalkId(DUNGEON_KEEPER, TELEPORT_CUBE);
- addSpawnId(VENOM, DUNGEON_KEEPER);
- addSpellFinishedId(VENOM);
- addAttackId(VENOM);
- addKillId(VENOM);
- addAggroRangeEnterId(VENOM);
- setCastleSiegeStartId(this::onSiegeStart, CASTLE);
- setCastleSiegeFinishId(this::onSiegeFinish, CASTLE);
-
- final long currentTime = System.currentTimeMillis();
- final long startSiegeDate = CastleManager.getInstance().getCastleById(CASTLE).getSiegeDate().getTimeInMillis();
- final long openingDungeonDate = startSiegeDate - (HOURS_BEFORE * 360000);
- if ((currentTime > openingDungeonDate) && (currentTime < startSiegeDate))
- {
- _prisonIsOpen = true;
- }
- }
-
- @Override
- public String onTalk(L2Npc npc, L2PcInstance talker)
- {
- switch (npc.getId())
- {
- case TELEPORT_CUBE:
- {
- talker.teleToLocation(TeleportWhereType.TOWN);
- break;
- }
- case DUNGEON_KEEPER:
- {
- if (_prisonIsOpen)
- {
- talker.teleToLocation(TELEPORT);
- }
- else
- {
- return "35506-02.html";
- }
- break;
- }
- }
- return super.onTalk(npc, talker);
- }
-
- @Override
- public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
- {
- switch (event)
- {
- case "tower_check":
- if (CastleManager.getInstance().getCastleById(CASTLE).getSiege().getControlTowerCount() <= 1)
- {
- changeLocation(MoveTo.THRONE);
- broadcastNpcSay(_massymore, Say2.NPC_SHOUT, NpcStringId.OH_NO_THE_DEFENSES_HAVE_FAILED_IT_IS_TOO_DANGEROUS_TO_REMAIN_INSIDE_THE_CASTLE_FLEE_EVERY_MAN_FOR_HIMSELF);
- cancelQuestTimer("tower_check", npc, null);
- startQuestTimer("raid_check", 10000, npc, null, true);
- }
- break;
- case "raid_check":
- if (!npc.isInsideZone(ZoneId.SIEGE) && !npc.isTeleporting())
- {
- npc.teleToLocation(_loc);
- }
- break;
- case "cube_despawn":
- if (npc != null)
- {
- npc.deleteMe();
- }
- break;
- }
- return event;
- }
-
- @Override
- public String onAggroRangeEnter(L2Npc npc, L2PcInstance player, boolean isSummon)
- {
- if (isSummon)
- {
- return super.onAggroRangeEnter(npc, player, isSummon);
- }
-
- if (_aggroMode && (_targets.size() < 10) && (getRandom(3) < 1) && !player.isDead())
- {
- _targets.add(player);
- }
- return super.onAggroRangeEnter(npc, player, isSummon);
- }
-
- public void onSiegeStart(OnCastleSiegeStart event)
- {
- _aggroMode = true;
- _prisonIsOpen = false;
- if ((_venom != null) && !_venom.isDead())
- {
- _venom.setCurrentHp(_venom.getMaxHp());
- _venom.setCurrentMp(_venom.getMaxMp());
- _venom.enableSkill(VENOM_TELEPORT.getSkill());
- _venom.enableSkill(RANGE_TELEPORT.getSkill());
- startQuestTimer("tower_check", 30000, _venom, null, true);
- }
- }
-
- public void onSiegeFinish(OnCastleSiegeFinish event)
- {
- _aggroMode = false;
- if ((_venom != null) && !_venom.isDead())
- {
- changeLocation(MoveTo.PRISON);
- _venom.disableSkill(VENOM_TELEPORT.getSkill(), -1);
- _venom.disableSkill(RANGE_TELEPORT.getSkill(), -1);
- }
- updateStatus(ALIVE);
- cancelQuestTimer("tower_check", _venom, null);
- cancelQuestTimer("raid_check", _venom, null);
- }
-
- @Override
- public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
- {
- switch (skill.getId())
- {
- case 4222:
- npc.teleToLocation(_loc);
- break;
- case 4995:
- teleportTarget(player);
- ((L2Attackable) npc).stopHating(player);
- break;
- case 4996:
- teleportTarget(player);
- ((L2Attackable) npc).stopHating(player);
- if ((_targets != null) && (_targets.size() > 0))
- {
- for (L2PcInstance target : _targets)
- {
- final long x = player.getX() - target.getX();
- final long y = player.getY() - target.getY();
- final long z = player.getZ() - target.getZ();
- final long range = 250;
- if (((x * x) + (y * y) + (z * z)) <= (range * range))
- {
- teleportTarget(target);
- ((L2Attackable) npc).stopHating(target);
- }
- }
- _targets.clear();
- }
- break;
- }
- return super.onSpellFinished(npc, player, skill);
- }
-
- @Override
- public final String onSpawn(L2Npc npc)
- {
- switch (npc.getId())
- {
- case DUNGEON_KEEPER:
- {
- _massymore = npc;
- break;
- }
- case VENOM:
- {
- _venom = npc;
-
- _loc = _venom.getLocation();
- _venom.disableSkill(VENOM_TELEPORT.getSkill(), -1);
- _venom.disableSkill(RANGE_TELEPORT.getSkill(), -1);
- _venom.doRevive();
- broadcastNpcSay(npc, Say2.NPC_SHOUT, NpcStringId.WHO_DARES_TO_COVET_THE_THRONE_OF_OUR_CASTLE_LEAVE_IMMEDIATELY_OR_YOU_WILL_PAY_THE_PRICE_OF_YOUR_AUDACITY_WITH_YOUR_VERY_OWN_BLOOD);
- ((L2Attackable) _venom).setCanReturnToSpawnPoint(false);
- if (checkStatus() == DEAD)
- {
- _venom.deleteMe();
- }
- break;
- }
- }
- if (checkStatus() == DEAD)
- {
- npc.deleteMe();
- }
- else
- {
- npc.doRevive();
-
- }
- return super.onSpawn(npc);
- }
-
- @Override
- public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
- {
- final double distance = npc.calculateDistance(attacker, false, false);
- if (_aggroMode && (getRandom(100) < 25))
- {
- npc.setTarget(attacker);
- npc.doCast(VENOM_TELEPORT.getSkill());
- }
- else if (_aggroMode && (npc.getCurrentHp() < (npc.getMaxHp() / 3)) && (getRandom(100) < 25) && !npc.isCastingNow())
- {
- npc.setTarget(attacker);
- npc.doCast(RANGE_TELEPORT.getSkill());
- }
- else if ((distance > 300) && (getRandom(100) < 10) && !npc.isCastingNow())
- {
- npc.setTarget(attacker);
- npc.doCast(VENOM_STRIKE.getSkill());
- }
- else if ((getRandom(100) < 10) && !npc.isCastingNow())
- {
- npc.setTarget(attacker);
- npc.doCast(SONIC_STORM.getSkill());
- }
- return super.onAttack(npc, attacker, damage, isSummon);
- }
-
- @Override
- public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
- {
- updateStatus(DEAD);
- broadcastNpcSay(npc, Say2.NPC_SHOUT, NpcStringId.ITS_NOT_OVER_YET_IT_WONT_BE_OVER_LIKE_THIS_NEVER);
- if (!CastleManager.getInstance().getCastleById(CASTLE).getSiege().isInProgress())
- {
- L2Npc cube = addSpawn(TELEPORT_CUBE, CUBE, false, 0);
- startQuestTimer("cube_despawn", 120000, cube, null);
- }
- cancelQuestTimer("raid_check", npc, null);
- return super.onKill(npc, killer, isSummon);
- }
-
- /**
- * Alters the Venom location
- * @param loc enum
- */
- private void changeLocation(MoveTo loc)
- {
- switch (loc)
- {
- case THRONE:
- _venom.teleToLocation(TRHONE, false);
- break;
- case PRISON:
- if ((_venom == null) || _venom.isDead() || _venom.isDecayed())
- {
- _venom = addSpawn(VENOM, DUNGEON, false, 0);
- }
- else
- {
- _venom.teleToLocation(DUNGEON, false);
- }
- cancelQuestTimer("raid_check", _venom, null);
- cancelQuestTimer("tower_check", _venom, null);
- break;
- }
- _loc.setLocation(_venom.getLocation());
- }
-
- private void teleportTarget(L2PcInstance player)
- {
- if ((player != null) && !player.isDead())
- {
- final int rnd = getRandom(11);
- player.teleToLocation(TARGET_TELEPORTS[rnd], TARGET_TELEPORTS_OFFSET[rnd]);
- player.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
- }
- }
-
- /**
- * Checks if Venom is Alive or Dead
- * @return status
- */
- private int checkStatus()
- {
- int checkStatus = ALIVE;
- if (GlobalVariablesManager.getInstance().hasVariable("VenomStatus"))
- {
- checkStatus = GlobalVariablesManager.getInstance().getInt("VenomStatus");
- }
- else
- {
- GlobalVariablesManager.getInstance().set("VenomStatus", 0);
- }
- return checkStatus;
- }
-
- /**
- * Update the Venom status
- * @param status the new status. 0 = ALIVE, 1 = DEAD.
- */
- private void updateStatus(int status)
- {
- GlobalVariablesManager.getInstance().set("VenomStatus", Integer.toString(status));
- }
-
- private enum MoveTo
- {
- THRONE,
- PRISON
- }
-
- public static void main(String[] args)
- {
- new Venom();
- }
- }
|