/*
* This program 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. This program 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 silentium.scripts.ai;
import javolution.util.FastList;
import silentium.commons.utils.Rnd;
import silentium.gameserver.ai.DefaultMonsterAI;
import silentium.gameserver.configs.NPCConfig;
import silentium.gameserver.instancemanager.GrandBossManager;
import silentium.gameserver.model.actor.L2Attackable;
import silentium.gameserver.model.actor.L2Npc;
import silentium.gameserver.model.actor.instance.L2GrandBossInstance;
import silentium.gameserver.model.actor.instance.L2PcInstance;
import silentium.gameserver.network.serverpackets.PlaySound;
import silentium.gameserver.scripting.ScriptFile;
import silentium.gameserver.templates.StatsSet;
import java.util.List;
/**
* Core AI
*
* @author DrLecter Revised By Emperorc
*/
public class Core extends DefaultMonsterAI implements ScriptFile {
private static final int CORE = 29006;
private static final int DEATH_KNIGHT = 29007;
private static final int DOOM_WRAITH = 29008;
// private static final int DICOR = 29009;
// private static final int VALIDUS = 29010;
private static final int SUSCEPTOR = 29011;
// private static final int PERUM = 29012;
// private static final int PREMO = 29013;
// Status Tracking
private static final byte ALIVE = 0; // Core is spawned.
private static final byte DEAD = 1; // Core has been killed.
private static boolean _FirstAttacked;
final List<L2Attackable> Minions = new FastList<>();
public static void onLoad() {
new Core(-1, "Core", "Core", "ai");
}
public Core(final int scriptId, final String name, final String dname, final String path) {
super(scriptId, name, dname, path);
final int[] mobs = { CORE, DEATH_KNIGHT, DOOM_WRAITH, SUSCEPTOR };
registerMobs(mobs);
_FirstAttacked = false;
final StatsSet info = GrandBossManager.getInstance().getStatsSet(CORE);
final int status = GrandBossManager.getInstance().getBossStatus(CORE);
if (status == DEAD) {
// load the unlock date and time for Core from DB
final long temp = info.getLong("respawn_time") - System.currentTimeMillis();
// if Core 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("core_unlock", temp, null, null);
else {
// the time has already expired while the server was offline. Immediately spawn Core.
final L2GrandBossInstance core = (L2GrandBossInstance) addSpawn(CORE, 17726, 108915, -6480, 0, false, 0);
GrandBossManager.getInstance().setBossStatus(CORE, ALIVE);
spawnBoss(core);
}
} else {
final String test = loadGlobalQuestVar("Core_Attacked");
if ("true".equalsIgnoreCase(test))
_FirstAttacked = true;
final int loc_x = info.getInteger("loc_x");
final int loc_y = info.getInteger("loc_y");
final int loc_z = info.getInteger("loc_z");
final int heading = info.getInteger("heading");
final int hp = info.getInteger("currentHP");
final int mp = info.getInteger("currentMP");
final L2GrandBossInstance core = (L2GrandBossInstance) addSpawn(CORE, loc_x, loc_y, loc_z, heading, false, 0);
core.setCurrentHpMp(hp, mp);
spawnBoss(core);
}
}
@Override
public void saveGlobalData() {
final String val = String.valueOf(_FirstAttacked);
saveGlobalQuestVar("Core_Attacked", val);
}
public void spawnBoss(final L2GrandBossInstance npc) {
GrandBossManager.getInstance().addBoss(npc);
npc.broadcastPacket(new PlaySound(1, "BS01_A", 1, npc.getObjectId(), npc.getX(), npc.getY(), npc.getZ()));
// Spawn minions
L2Attackable mob;
for (int i = 0; i < 5; i++) {
final int x = 16800 + i * 360;
mob = (L2Attackable) addSpawn(DEATH_KNIGHT, x, 110000, npc.getZ(), 280 + Rnd.get(40), false, 0);
mob.setIsRaidMinion(true);
Minions.add(mob);
mob = (L2Attackable) addSpawn(DEATH_KNIGHT, x, 109000, npc.getZ(), 280 + Rnd.get(40), false, 0);
mob.setIsRaidMinion(true);
Minions.add(mob);
final int x2 = 16800 + i * 600;
mob = (L2Attackable) addSpawn(DOOM_WRAITH, x2, 109300, npc.getZ(), 280 + Rnd.get(40), false, 0);
mob.setIsRaidMinion(true);
Minions.add(mob);
}
for (int i = 0; i < 4; i++) {
final int x = 16800 + i * 450;
mob = (L2Attackable) addSpawn(SUSCEPTOR, x, 110300, npc.getZ(), 280 + Rnd.get(40), false, 0);
mob.setIsRaidMinion(true);
Minions.add(mob);
}
}
@Override
public String onAdvEvent(final String event, final L2Npc npc, final L2PcInstance player) {
if ("core_unlock".equalsIgnoreCase(event)) {
final L2GrandBossInstance core = (L2GrandBossInstance) addSpawn(CORE, 17726, 108915, -6480, 0, false, 0);
GrandBossManager.getInstance().setBossStatus(CORE, ALIVE);
spawnBoss(core);
} else if ("spawn_minion".equalsIgnoreCase(event)) {
final L2Attackable mob = (L2Attackable) addSpawn(npc.getNpcId(), npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), false, 0);
mob.setIsRaidMinion(true);
Minions.add(mob);
} else if ("despawn_minions".equalsIgnoreCase(event)) {
for (final L2Attackable mob : Minions) {
if (mob != null)
mob.decayMe();
}
Minions.clear();
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onAttack(final L2Npc npc, final L2PcInstance attacker, final int damage, final boolean isPet) {
if (npc.getNpcId() == CORE) {
if (_FirstAttacked) {
if (Rnd.get(100) == 0)
npc.broadcastNpcSay("Removing intruders.");
} else {
_FirstAttacked = true;
npc.broadcastNpcSay("A non-permitted target has been discovered.");
npc.broadcastNpcSay("Starting intruder removal system.");
}
}
return super.onAttack(npc, attacker, damage, isPet);
}
@Override
public String onKill(final L2Npc npc, final L2PcInstance killer, final boolean isPet) {
final int npcId = npc.getNpcId();
if (npcId == CORE) {
npc.broadcastPacket(new PlaySound(1, "BS02_D", 1, npc.getObjectId(), npc.getX(), npc.getY(), npc.getZ()));
npc.broadcastNpcSay("A fatal error has occurred.");
npc.broadcastNpcSay("System is being shut down...");
npc.broadcastNpcSay("......");
_FirstAttacked = false;
addSpawn(31842, 16502, 110165, -6394, 0, false, 900000);
addSpawn(31842, 18948, 110166, -6397, 0, false, 900000);
GrandBossManager.getInstance().setBossStatus(CORE, DEAD);
// time is 60hour +/- 23hour
final long respawnTime = (long) NPCConfig.SPAWN_INTERVAL_CORE + Rnd.get(NPCConfig.RANDOM_SPAWN_TIME_CORE);
startQuestTimer("core_unlock", respawnTime, null, null);
// also save the respawn time so that the info is maintained past reboots
final StatsSet info = GrandBossManager.getInstance().getStatsSet(CORE);
info.set("respawn_time", System.currentTimeMillis() + respawnTime);
GrandBossManager.getInstance().setStatsSet(CORE, info);
startQuestTimer("despawn_minions", 20000, null, null);
cancelQuestTimers("spawn_minion");
} else if (GrandBossManager.getInstance().getBossStatus(CORE) == ALIVE && Minions != null && Minions.contains(npc)) {
Minions.remove(npc);
startQuestTimer("spawn_minion", 60000, npc, null);
}
return super.onKill(npc, killer, isPet);
}
}