/* * Copyright (C) 2004-2015 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 . */ package ai.npc.NpcBuffers.impl; import java.util.Collection; import ai.npc.AbstractNpcAI; import com.l2jserver.gameserver.SevenSigns; import com.l2jserver.gameserver.ThreadPoolManager; import com.l2jserver.gameserver.datatables.SkillData; import com.l2jserver.gameserver.model.actor.L2Npc; import com.l2jserver.gameserver.model.actor.instance.L2PcInstance; import com.l2jserver.gameserver.model.skills.BuffInfo; import com.l2jserver.gameserver.model.skills.Skill; import com.l2jserver.gameserver.network.NpcStringId; import com.l2jserver.gameserver.network.clientpackets.Say2; /** * Preacher of Doom and Orator of Revelations AI * @author UnAfraid, malyelfik */ public final class CabaleBuffer extends AbstractNpcAI { private static final int DISTANCE_TO_WATCH_OBJECT = 900; // Messages public static final NpcStringId[] ORATOR_MSG = { NpcStringId.THE_DAY_OF_JUDGMENT_IS_NEAR, NpcStringId.THE_PROPHECY_OF_DARKNESS_HAS_BEEN_FULFILLED, NpcStringId.AS_FORETOLD_IN_THE_PROPHECY_OF_DARKNESS_THE_ERA_OF_CHAOS_HAS_BEGUN, NpcStringId.THE_PROPHECY_OF_DARKNESS_HAS_COME_TO_PASS }; public static final NpcStringId[] PREACHER_MSG = { NpcStringId.THIS_WORLD_WILL_SOON_BE_ANNIHILATED, NpcStringId.ALL_IS_LOST_PREPARE_TO_MEET_THE_GODDESS_OF_DEATH, NpcStringId.ALL_IS_LOST_THE_PROPHECY_OF_DESTRUCTION_HAS_BEEN_FULFILLED, NpcStringId.THE_END_OF_TIME_HAS_COME_THE_PROPHECY_OF_DESTRUCTION_HAS_BEEN_FULFILLED }; // Skills private static final int ORATOR_FIGTER = 4364; private static final int ORATOR_MAGE = 4365; private static final int PREACHER_FIGTER = 4361; private static final int PREACHER_MAGE = 4362; private CabaleBuffer() { super(CabaleBuffer.class.getSimpleName(), "ai/npc"); addFirstTalkId(SevenSigns.ORATOR_NPC_ID, SevenSigns.PREACHER_NPC_ID); addSpawnId(SevenSigns.ORATOR_NPC_ID, SevenSigns.PREACHER_NPC_ID); } @Override public String onFirstTalk(L2Npc npc, L2PcInstance player) { return null; } @Override public String onSpawn(L2Npc npc) { ThreadPoolManager.getInstance().scheduleGeneral(new CabaleAI(npc), 3000); ThreadPoolManager.getInstance().scheduleGeneral(new Talk(npc), 60000); return super.onSpawn(npc); } protected class Talk implements Runnable { private final L2Npc _npc; protected Talk(L2Npc npc) { _npc = npc; } @Override public void run() { if ((_npc != null) && !_npc.isDecayed()) { NpcStringId[] messages = ORATOR_MSG; if (_npc.getId() == SevenSigns.PREACHER_NPC_ID) { messages = PREACHER_MSG; } broadcastSay(_npc, messages[getRandom(messages.length)], null, -1); ThreadPoolManager.getInstance().scheduleGeneral(this, 60000); } } } protected class CabaleAI implements Runnable { private final L2Npc _npc; protected CabaleAI(L2Npc npc) { _npc = npc; } @Override public void run() { if ((_npc == null) || !_npc.isVisible()) { return; } boolean isBuffAWinner = false; boolean isBuffALoser = false; final int winningCabal = SevenSigns.getInstance().getCabalHighestScore(); int losingCabal = SevenSigns.CABAL_NULL; if (winningCabal == SevenSigns.CABAL_DAWN) { losingCabal = SevenSigns.CABAL_DUSK; } else if (winningCabal == SevenSigns.CABAL_DUSK) { losingCabal = SevenSigns.CABAL_DAWN; } Collection plrs = _npc.getKnownList().getKnownPlayers().values(); for (L2PcInstance player : plrs) { if ((player == null) || player.isInvul()) { continue; } final int playerCabal = SevenSigns.getInstance().getPlayerCabal(player.getObjectId()); if ((playerCabal == winningCabal) && (playerCabal != SevenSigns.CABAL_NULL) && (_npc.getId() == SevenSigns.ORATOR_NPC_ID)) { if (!player.isMageClass()) { if (handleCast(player, ORATOR_FIGTER)) { if (getAbnormalLvl(player, ORATOR_FIGTER) == 2) { broadcastSay(_npc, NpcStringId.S1_I_GIVE_YOU_THE_BLESSING_OF_PROPHECY, player.getName(), 500); } else { broadcastSay(_npc, NpcStringId.I_BESTOW_UPON_YOU_A_BLESSING, null, 1); } isBuffAWinner = true; continue; } } else { if (handleCast(player, ORATOR_MAGE)) { if (getAbnormalLvl(player, ORATOR_MAGE) == 2) { broadcastSay(_npc, NpcStringId.S1_I_BESTOW_UPON_YOU_THE_AUTHORITY_OF_THE_ABYSS, player.getName(), 500); } else { broadcastSay(_npc, NpcStringId.HERALD_OF_THE_NEW_ERA_OPEN_YOUR_EYES, null, 1); } isBuffAWinner = true; continue; } } } else if ((playerCabal == losingCabal) && (playerCabal != SevenSigns.CABAL_NULL) && (_npc.getId() == SevenSigns.PREACHER_NPC_ID)) { if (!player.isMageClass()) { if (handleCast(player, PREACHER_FIGTER)) { if (getAbnormalLvl(player, PREACHER_FIGTER) == 2) { broadcastSay(_npc, NpcStringId.A_CURSE_UPON_YOU, player.getName(), 500); } else { broadcastSay(_npc, NpcStringId.YOU_DONT_HAVE_ANY_HOPE_YOUR_END_HAS_COME, null, 1); } isBuffALoser = true; continue; } } else { if (handleCast(player, PREACHER_MAGE)) { if (getAbnormalLvl(player, PREACHER_MAGE) == 2) { broadcastSay(_npc, NpcStringId.S1_YOU_MIGHT_AS_WELL_GIVE_UP, player.getName(), 500); } else { broadcastSay(_npc, NpcStringId.S1_YOU_BRING_AN_ILL_WIND, player.getName(), 1); } isBuffALoser = true; continue; } } } if (isBuffAWinner && isBuffALoser) { break; } } ThreadPoolManager.getInstance().scheduleGeneral(this, 3000); } /** * For each known player in range, cast either the positive or negative buff.
* The stats affected depend on the player type, either a fighter or a mystic.
*
* Curse of Destruction (Loser)
* - Fighters: -25% Accuracy, -25% Effect Resistance
* - Mystics: -25% Casting Speed, -25% Effect Resistance
*
*
* Blessing of Prophecy (Winner)
* - Fighters: +25% Max Load, +25% Effect Resistance
* - Mystics: +25% Magic Cancel Resist, +25% Effect Resistance
* @param player * @param skillId * @return */ private boolean handleCast(L2PcInstance player, int skillId) { if (player.isDead() || !player.isVisible() || !_npc.isInsideRadius(player, DISTANCE_TO_WATCH_OBJECT, false, false)) { return false; } boolean doCast = false; int skillLevel = 1; final int level = getAbnormalLvl(player, skillId); if (level == 0) { doCast = true; } else if ((level == 1) && (getRandom(100) < 5)) { doCast = true; skillLevel = 2; } if (doCast) { final Skill skill = SkillData.getInstance().getSkill(skillId, skillLevel); _npc.setTarget(player); _npc.doCast(skill); return true; } return false; } } public void broadcastSay(L2Npc npc, NpcStringId message, String param, int chance) { if (chance == -1) { broadcastNpcSay(npc, Say2.NPC_ALL, message); } else if (getRandom(10000) < chance) { broadcastNpcSay(npc, Say2.NPC_ALL, message, param); } } public int getAbnormalLvl(L2PcInstance player, int skillId) { final BuffInfo info = player.getEffectList().getBuffInfoBySkillId(skillId); return (info != null) ? info.getSkill().getAbnormalLvl() : 0; } public static void main(String[] args) { new CabaleBuffer(); } }