/*
* 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 hellbound.AI.Zones.TowerOfNaia;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;
import ai.npc.AbstractNpcAI;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.ai.CtrlIntention;
import com.l2jserver.gameserver.data.xml.impl.DoorData;
import com.l2jserver.gameserver.datatables.SkillData;
import com.l2jserver.gameserver.instancemanager.GlobalVariablesManager;
import com.l2jserver.gameserver.instancemanager.ZoneManager;
import com.l2jserver.gameserver.model.L2Party;
import com.l2jserver.gameserver.model.Location;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.skills.Skill;
import com.l2jserver.gameserver.model.zone.L2ZoneType;
import com.l2jserver.gameserver.network.NpcStringId;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.clientpackets.Say2;
import com.l2jserver.gameserver.util.MinionList;
import com.l2jserver.gameserver.util.Util;
/**
* Tower Of Naia.
* @author GKR
*/
public final class TowerOfNaia extends AbstractNpcAI
{
// Challenge states
private static final int STATE_SPORE_CHALLENGE_IN_PROGRESS = 1;
private static final int STATE_SPORE_CHALLENGE_SUCCESSFULL = 2;
private static final int STATE_SPORE_IDLE_TOO_LONG = 3;
// Some constants
private static final int SELF_DESPAWN_LIMIT = 600; // Challenge discontinues after 600 self-despawns by timer
private static final int ELEMENT_INDEX_LIMIT = 120; // Epidos spawns when index reaches 120 points
private static final int LOCK = 18491;
private static final int CONTROLLER = 18492;
private static final int ROOM_MANAGER_FIRST = 18494;
private static final int ROOM_MANAGER_LAST = 18505;
private static final int MUTATED_ELPY = 25604;
private static final int SPORE_BASIC = 25613;
private static final int SPORE_FIRE = 25605;
private static final int SPORE_WATER = 25606;
private static final int SPORE_WIND = 25607;
private static final int SPORE_EARTH = 25608;
private static final int DWARVEN_GHOST = 32370;
private static final int[] EPIDOSES =
{
25610,
25609,
25612,
25611
}; // Order is important!
private static final int[] TOWER_MONSTERS =
{
18490,
22393,
22394,
22395,
22411,
22412,
22413,
22439,
22440,
22441,
22442
};
private static final int[] ELEMENTS =
{
25605,
25606,
25607,
25608
};
private static final int[] OPPOSITE_ELEMENTS =
{
25606,
25605,
25608,
25607
};
private static final String[] ELEMENTS_NAME =
{
"Fire",
"Water",
"Wind",
"Earth"
};
//@formatter:off
private static final int[][] SPORES_MOVE_POINTS =
{
{-46080, 246368, -14183},
{-44816, 246368, -14183},
{-44224, 247440, -14184},
{-44896, 248464, -14183},
{-46064, 248544, -14183},
{-46720, 247424, -14183},
};
private static final int[][] SPORES_MERGE_POSITION =
{
{-45488, 246768, -14183},
{-44767, 247419, -14183},
{-46207, 247417, -14183},
{-45462, 248174, -14183},
};
//@formatter:on
private static final NpcStringId[] SPORES_NPCSTRING_ID =
{
NpcStringId.ITS_S1,
NpcStringId.S1_IS_STRONG,
NpcStringId.ITS_ALWAYS_S1,
NpcStringId.S1_WONT_DO
};
private static Map DOORS = new HashMap<>();
private static Map ZONES = new HashMap<>();
private static Map SPAWNS = new HashMap<>();
private L2MonsterInstance _lock;
private final L2Npc _controller;
private int _counter;
private final AtomicInteger _despawnedSporesCount = new AtomicInteger();
private final int[] _indexCount =
{
0,
0
};
private int _challengeState;
private int _winIndex;
private final Map _activeRooms = new HashMap<>();
private final Map> _spawns = new ConcurrentHashMap<>();
private final Set _sporeSpawn = ConcurrentHashMap.newKeySet();
static
{
// Format: entrance_door, exit_door
DOORS.put(18494, new int[]
{
18250001,
18250002
});
DOORS.put(18495, new int[]
{
18250003,
18250004
});
DOORS.put(18496, new int[]
{
18250005,
18250006
});
DOORS.put(18497, new int[]
{
18250007,
18250008
});
DOORS.put(18498, new int[]
{
18250009,
18250010
});
DOORS.put(18499, new int[]
{
18250011,
18250101
});
DOORS.put(18500, new int[]
{
18250013,
18250014
});
DOORS.put(18501, new int[]
{
18250015,
18250102
});
DOORS.put(18502, new int[]
{
18250017,
18250018
});
DOORS.put(18503, new int[]
{
18250019,
18250103
});
DOORS.put(18504, new int[]
{
18250021,
18250022
});
DOORS.put(18505, new int[]
{
18250023,
18250024
});
ZONES.put(18494, 200020);
ZONES.put(18495, 200021);
ZONES.put(18496, 200022);
ZONES.put(18497, 200023);
ZONES.put(18498, 200024);
ZONES.put(18499, 200025);
ZONES.put(18500, 200026);
ZONES.put(18501, 200027);
ZONES.put(18502, 200028);
ZONES.put(18503, 200029);
ZONES.put(18504, 200030);
ZONES.put(18505, 200031);
//@formatter:off
SPAWNS.put(18494, new int[][]
{
{22393, -46371, 246400, -9120, 0},
{22394, -46435, 245830, -9120, 0},
{22394, -46536, 246275, -9120, 0},
{22393, -46239, 245996, -9120, 0},
{22394, -46229, 246347, -9120, 0},
{22394, -46019, 246198, -9120, 0},
});
SPAWNS.put(18495, new int[][]
{
{22439, -48146, 249597, -9124, -16280},
{22439, -48144, 248711, -9124, 16368},
{22439, -48704, 249597, -9104, -16380},
{22439, -49219, 249596, -9104, -16400},
{22439, -49715, 249601, -9104, -16360},
{22439, -49714, 248696, -9104, 15932},
{22439, -49225, 248710, -9104, 16512},
{22439, -48705, 248708, -9104, 16576},
});
SPAWNS.put(18496, new int[][]
{
{22441, -51176, 246055, -9984, 0},
{22441, -51699, 246190, -9984, 0},
{22442, -52060, 245956, -9984, 0},
{22442, -51565, 246433, -9984, 0},
});
SPAWNS.put(18497, new int[][]
{
{22440, -49754, 243866, -9968, -16328},
{22440, -49754, 242940, -9968, 16336},
{22440, -48733, 243858, -9968, -16208},
{22440, -48745, 242936, -9968, 16320},
{22440, -49264, 242946, -9968, 16312},
{22440, -49268, 243869, -9968, -16448},
{22440, -48186, 242934, -9968, 16576},
{22440, -48185, 243855, -9968, -16448},
});
SPAWNS.put(18498, new int[][]
{
{22411, -46355, 246375, -9984, 0},
{22411, -46167, 246160, -9984, 0},
{22393, -45952, 245748, -9984, 0},
{22394, -46428, 246254, -9984, 0},
{22393, -46490, 245871, -9984, 0},
{22394, -45877, 246309, -9984, 0},
});
SPAWNS.put(18499, new int[][]
{
{22395, -48730, 248067, -9984, 0},
{22395, -49112, 248250, -9984, 0},
});
SPAWNS.put(18500, new int[][]
{
{22393, -51954, 246475, -10848, 0},
{22394, -51421, 246512, -10848, 0},
{22394, -51404, 245951, -10848, 0},
{22393, -51913, 246206, -10848, 0},
{22394, -51663, 245979, -10848, 0},
{22394, -51969, 245809, -10848, 0},
{22412, -51259, 246357, -10848, 0},
});
SPAWNS.put(18501, new int[][]
{
{22395, -48856, 243949, -10848, 0},
{22395, -49144, 244190, -10848, 0},
});
SPAWNS.put(18502, new int[][]
{
{22441, -46471, 246135, -11704, 0},
{22441, -46449, 245997, -11704, 0},
{22441, -46235, 246187, -11704, 0},
{22441, -46513, 246326, -11704, 0},
{22441, -45889, 246313, -11704, 0},
});
SPAWNS.put(18503, new int[][]
{
{22395, -49067, 248050, -11712, 0},
{22395, -48957, 248223, -11712, 0},
});
SPAWNS.put(18504, new int[][]
{
{22413, -51748, 246138, -12568, 0},
{22413, -51279, 246200, -12568, 0},
{22413, -51787, 246594, -12568, 0},
{22413, -51892, 246544, -12568, 0},
{22413, -51500, 245781, -12568, 0},
{22413, -51941, 246045, -12568, 0},
});
SPAWNS.put(18505, new int[][]
{
{18490, -48238, 243347, -13376, 0},
{18490, -48462, 244022, -13376, 0},
{18490, -48050, 244045, -13376, 0},
{18490, -48229, 243823, -13376, 0},
{18490, -47871, 243208, -13376, 0},
{18490, -48255, 243528, -13376, 0},
{18490, -48461, 243780, -13376, 0},
{18490, -47983, 243197, -13376, 0},
{18490, -47841, 243819, -13376, 0},
{18490, -48646, 243764, -13376, 0},
{18490, -47806, 243850, -13376, 0},
{18490, -48456, 243447, -13376, 0},
});
//@formatter:on
}
public TowerOfNaia()
{
super(TowerOfNaia.class.getSimpleName(), "hellbound/AI/Zones");
addFirstTalkId(CONTROLLER);
addStartNpc(CONTROLLER, DWARVEN_GHOST);
addTalkId(CONTROLLER, DWARVEN_GHOST);
addAttackId(LOCK);
addKillId(LOCK, MUTATED_ELPY, SPORE_BASIC);
addSpawnId(MUTATED_ELPY, SPORE_BASIC);
for (int npcId = SPORE_FIRE; npcId <= SPORE_EARTH; npcId++)
{
addKillId(npcId);
addSpawnId(npcId);
}
for (int npcId = ROOM_MANAGER_FIRST; npcId <= ROOM_MANAGER_LAST; npcId++)
{
addFirstTalkId(npcId);
addTalkId(npcId);
addStartNpc(npcId);
initRoom(npcId);
}
for (int npcId : TOWER_MONSTERS)
{
addKillId(npcId);
}
_lock = (L2MonsterInstance) addSpawn(LOCK, 16409, 244438, 11620, -1048, false, 0, false);
_controller = addSpawn(CONTROLLER, 16608, 244420, 11620, 31264, false, 0, false);
_counter = 90;
initSporeChallenge();
spawnElpy();
}
@Override
public final String onFirstTalk(L2Npc npc, L2PcInstance player)
{
final int npcId = npc.getId();
if (npcId == CONTROLLER)
{
if (_lock == null)
{
return "18492-02.htm";
}
return "18492-01.htm";
}
else if ((npcId >= ROOM_MANAGER_FIRST) && (npcId <= ROOM_MANAGER_LAST))
{
if (_activeRooms.containsKey(npcId) && !_activeRooms.get(npcId))
{
if (player.getParty() == null)
{
player.sendPacket(SystemMessageId.CAN_OPERATE_MACHINE_WHEN_IN_PARTY);
return null;
}
return "manager.htm";
}
}
return super.onFirstTalk(npc, player);
}
@Override
public final String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
String htmltext = event;
// Timer. Spawns Naia Lock
if (event.equalsIgnoreCase("spawn_lock"))
{
htmltext = null;
_lock = (L2MonsterInstance) addSpawn(LOCK, 16409, 244438, 11620, -1048, false, 0, false);
_counter = 90;
}
// Timer. Depending of _challengeState despans all spawned spores, or spores, reached assembly point
else if (event.equalsIgnoreCase("despawn_total"))
{
// Spores is not attacked too long - despawn them all, reinit values
if (_challengeState == STATE_SPORE_IDLE_TOO_LONG)
{
removeSpores();
initSporeChallenge();
}
// Spores are moving to assembly point. Despawn all reached, check for reached spores count.
else if ((_challengeState == STATE_SPORE_CHALLENGE_SUCCESSFULL) && (_winIndex >= 0))
{
// Requirements are met, despawn all spores, spawn Epidos
if ((_despawnedSporesCount.get() >= 10) || _sporeSpawn.isEmpty())
{
removeSpores();
_despawnedSporesCount.set(0);
int[] coords = SPORES_MERGE_POSITION[_winIndex];
addSpawn(EPIDOSES[_winIndex], coords[0], coords[1], coords[2], 0, false, 0, false);
initSporeChallenge();
}
// Requirements aren't met, despawn reached spores
else
{
Iterator it = _sporeSpawn.iterator();
while (it.hasNext())
{
L2Npc spore = it.next();
if ((spore != null) && !spore.isDead() && (spore.getX() == spore.getSpawn().getX()) && (spore.getY() == spore.getSpawn().getY()))
{
spore.deleteMe();
it.remove();
_despawnedSporesCount.incrementAndGet();
}
}
startQuestTimer("despawn_total", 3000, null, null);
}
}
}
if (npc == null)
{
return null;
}
final int npcId = npc.getId();
if (event.equalsIgnoreCase("despawn_spore") && !npc.isDead() && (_challengeState == STATE_SPORE_CHALLENGE_IN_PROGRESS))
{
htmltext = null;
_sporeSpawn.remove(npc);
npc.deleteMe();
if (npcId == SPORE_BASIC)
{
spawnRandomSpore();
spawnRandomSpore();
}
else if ((npcId >= SPORE_FIRE) && (npcId <= SPORE_EARTH))
{
_despawnedSporesCount.incrementAndGet();
if (_despawnedSporesCount.get() < SELF_DESPAWN_LIMIT)
{
spawnOppositeSpore(npcId);
}
else
{
_challengeState = STATE_SPORE_IDLE_TOO_LONG;
startQuestTimer("despawn_total", 60000, null, null);
}
}
}
else if (event.equalsIgnoreCase("18492-05.htm"))
{
if ((_lock == null) || (_lock.getCurrentHp() > (_lock.getMaxHp() / 10)))
{
htmltext = null;
if (_lock != null)
{
_lock.deleteMe();
_lock = null;
}
cancelQuestTimers("spawn_lock");
startQuestTimer("spawn_lock", 300000, null, null);
npc.setTarget(player);
npc.doCast(SkillData.getInstance().getSkill(5527, 1));
}
}
else if (event.equalsIgnoreCase("teleport") && (_lock != null))
{
htmltext = null;
L2Party party = player.getParty();
if (party != null)
{
if (Util.checkIfInRange(3000, party.getLeader(), npc, true))
{
for (L2PcInstance partyMember : party.getMembers())
{
if (Util.checkIfInRange(2000, partyMember, npc, true))
{
partyMember.teleToLocation(-47271, 246098, -9120, true);
}
}
_lock.deleteMe();
_lock = null;
cancelQuestTimers("spawn_lock");
startQuestTimer("spawn_lock", 1200000, null, null);
}
else
{
npc.setTarget(player);
npc.doCast(SkillData.getInstance().getSkill(5527, 1));
}
}
else
{
player.teleToLocation(-47271, 246098, -9120);
_lock.deleteMe();
_lock = null;
cancelQuestTimers("spawn_lock");
startQuestTimer("spawn_lock", 1200000, null, null);
}
}
else if (event.equalsIgnoreCase("go") && _activeRooms.containsKey(npcId) && !_activeRooms.get(npcId))
{
htmltext = null;
L2Party party = player.getParty();
if (party != null)
{
removeForeigners(npcId, party);
startRoom(npcId);
ThreadPoolManager.getInstance().scheduleGeneral(new StopRoomTask(npcId), 300000);
}
else
{
player.sendPacket(SystemMessageId.CAN_OPERATE_MACHINE_WHEN_IN_PARTY);
}
}
return htmltext;
}
@Override
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon, Skill skill)
{
if ((_lock != null) && (npc.getObjectId() == _lock.getObjectId()))
{
int remaindedHpPercent = (int) ((npc.getCurrentHp() * 100) / npc.getMaxHp());
if ((remaindedHpPercent <= _counter) && (_controller != null))
{
if (_counter == 50)
{
MinionList.spawnMinion(_lock, 18493);
}
else if (_counter == 10)
{
MinionList.spawnMinion(_lock, 18493);
MinionList.spawnMinion(_lock, 18493);
}
broadcastNpcSay(_controller, Say2.NPC_ALL, NpcStringId.EMERGENCY_EMERGENCY_THE_OUTER_WALL_IS_WEAKENING_RAPIDLY);
_counter -= 10;
}
}
return super.onAttack(npc, attacker, damage, isSummon, skill);
}
@Override
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
{
int npcId = npc.getId();
if (npcId == LOCK)
{
_lock = null;
cancelQuestTimers("spawn_lock");
startQuestTimer("spawn_lock", 300000, null, null);
}
else if (Arrays.binarySearch(TOWER_MONSTERS, npcId) >= 0)
{
int managerId = 0;
for (L2ZoneType zone : ZoneManager.getInstance().getZones(npc.getX(), npc.getY(), npc.getZ()))
{
if (ZONES.containsValue(zone.getId()))
{
for (int i : ZONES.keySet())
{
if (ZONES.get(i) == zone.getId())
{
managerId = i;
break;
}
}
}
}
if ((managerId > 0) && _spawns.containsKey(managerId))
{
List spawned = _spawns.get(managerId);
spawned.remove(npc);
if (spawned.isEmpty() && DOORS.containsKey(managerId))
{
int[] doorList = DOORS.get(managerId);
DoorData.getInstance().getDoor(doorList[1]).openMe();
_spawns.remove(managerId);
}
}
}
else if (npcId == MUTATED_ELPY)
{
_challengeState = STATE_SPORE_CHALLENGE_IN_PROGRESS;
markElpyRespawn();
DoorData.getInstance().getDoor(18250025).closeMe();
ZoneManager.getInstance().getZoneById(200100).setEnabled(true);
for (int i = 0; i < 10; i++)
{
addSpawn(SPORE_BASIC, -45474, 247450, -13994, 49152, false, 0, false);
}
}
else if ((npcId == SPORE_BASIC) && (_challengeState == STATE_SPORE_CHALLENGE_IN_PROGRESS))
{
_sporeSpawn.remove(npc);
spawnRandomSpore();
spawnRandomSpore();
}
else if ((npcId >= SPORE_FIRE) && (npcId <= SPORE_EARTH) && ((_challengeState == STATE_SPORE_CHALLENGE_IN_PROGRESS) || (_challengeState == STATE_SPORE_CHALLENGE_SUCCESSFULL)))
{
_sporeSpawn.remove(npc);
if (_challengeState == STATE_SPORE_CHALLENGE_IN_PROGRESS)
{
_despawnedSporesCount.decrementAndGet();
int sporeGroup = getSporeGroup(npcId);
if (sporeGroup >= 0)
{
if ((npcId == SPORE_FIRE) || (npcId == SPORE_WIND))
{
_indexCount[sporeGroup] += 2;
}
else
{
_indexCount[sporeGroup] -= 2;
}
if (_indexCount[Math.abs(sporeGroup - 1)] > 0)
{
_indexCount[Math.abs(sporeGroup - 1)]--;
}
else if (_indexCount[Math.abs(sporeGroup - 1)] < 0)
{
_indexCount[Math.abs(sporeGroup - 1)]++;
}
if ((Math.abs(_indexCount[sporeGroup]) < ELEMENT_INDEX_LIMIT) && (Math.abs(_indexCount[sporeGroup]) > 0) && ((_indexCount[sporeGroup] % 20) == 0) && (getRandom(100) < 50))
{
String el = ELEMENTS_NAME[Arrays.binarySearch(ELEMENTS, npcId)];
for (L2Npc spore : _sporeSpawn)
{
if ((spore != null) && !spore.isDead() && (spore.getId() == npcId))
{
broadcastNpcSay(spore, Say2.NPC_ALL, SPORES_NPCSTRING_ID[getRandom(4)], el);
}
}
}
if (Math.abs(_indexCount[sporeGroup]) < ELEMENT_INDEX_LIMIT)
{
if ((((_indexCount[sporeGroup] > 0) && ((npcId == SPORE_FIRE) || (npcId == SPORE_WIND))) || ((_indexCount[sporeGroup] <= 0) && ((npcId == SPORE_WATER) || (npcId == SPORE_EARTH)))) && (getRandom(1000) > 200))
{
spawnOppositeSpore(npcId);
}
else
{
spawnRandomSpore();
}
}
else
// index value was reached
{
_challengeState = STATE_SPORE_CHALLENGE_SUCCESSFULL;
_despawnedSporesCount.set(0);
_winIndex = Arrays.binarySearch(ELEMENTS, npcId);
int[] coord = SPORES_MERGE_POSITION[_winIndex];
for (L2Npc spore : _sporeSpawn)
{
if ((spore != null) && !spore.isDead())
{
moveTo(spore, coord);
}
}
startQuestTimer("despawn_total", 3000, null, null);
}
}
}
}
return super.onKill(npc, killer, isSummon);
}
@Override
public final String onSpawn(L2Npc npc)
{
final int npcId = npc.getId();
if (npcId == MUTATED_ELPY)
{
DoorData.getInstance().getDoor(18250025).openMe();
ZoneManager.getInstance().getZoneById(200100).setEnabled(false);
ZoneManager.getInstance().getZoneById(200101).setEnabled(true);
ZoneManager.getInstance().getZoneById(200101).setEnabled(false);
}
else if (((npcId == SPORE_BASIC) || ((npcId >= SPORE_FIRE) && (npcId <= SPORE_EARTH))) && (_challengeState == STATE_SPORE_CHALLENGE_IN_PROGRESS))
{
_sporeSpawn.add(npc);
npc.setIsRunning(false);
int[] coord = SPORES_MOVE_POINTS[getRandom(SPORES_MOVE_POINTS.length)];
npc.getSpawn().setX(coord[0]);
npc.getSpawn().setY(coord[1]);
npc.getSpawn().setZ(coord[2]);
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(coord[0], coord[1], coord[2], 0));
startQuestTimer("despawn_spore", 60000, npc, null);
}
return super.onSpawn(npc);
}
private int getSporeGroup(int sporeId)
{
int ret;
switch (sporeId)
{
case SPORE_FIRE:
case SPORE_WATER:
ret = 0;
break;
case SPORE_WIND:
case SPORE_EARTH:
ret = 1;
break;
default:
ret = -1;
}
return ret;
}
protected void initRoom(int managerId)
{
removeAllPlayers(managerId);
_activeRooms.put(managerId, false);
if (DOORS.containsKey(managerId))
{
int[] doorList = DOORS.get(managerId);
DoorData.getInstance().getDoor(doorList[0]).openMe();
DoorData.getInstance().getDoor(doorList[1]).closeMe();
}
if (_spawns.containsKey(managerId) && (_spawns.get(managerId) != null))
{
for (L2Npc npc : _spawns.get(managerId))
{
if ((npc != null) && !npc.isDead())
{
npc.deleteMe();
}
}
_spawns.get(managerId).clear();
_spawns.remove(managerId);
}
}
private void initSporeChallenge()
{
_despawnedSporesCount.set(0);
_challengeState = 0;
_winIndex = -1;
_indexCount[0] = 0;
_indexCount[1] = 0;
ZoneManager.getInstance().getZoneById(200100).setEnabled(false);
ZoneManager.getInstance().getZoneById(200101).setEnabled(false);
ZoneManager.getInstance().getZoneById(200101).setEnabled(true);
}
private void markElpyRespawn()
{
final long respawnTime = (getRandom(43200, 216000) * 1000) + System.currentTimeMillis();
GlobalVariablesManager.getInstance().set("elpy_respawn_time", respawnTime);
}
private int moveTo(L2Npc npc, int[] coords)
{
int time = 0;
if (npc != null)
{
double distance = npc.calculateDistance(coords[0], coords[1], coords[2], true, false);
int heading = Util.calculateHeadingFrom(npc.getX(), npc.getY(), coords[0], coords[1]);
time = (int) ((distance / npc.getWalkSpeed()) * 1000);
npc.setIsRunning(false);
npc.disableCoreAI(true);
npc.setIsNoRndWalk(true);
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(coords[0], coords[1], coords[2], heading));
npc.getSpawn().setX(coords[0]);
npc.getSpawn().setY(coords[1]);
npc.getSpawn().setZ(coords[2]);
}
return time == 0 ? 100 : time;
}
private void spawnElpy()
{
final long respawnTime = GlobalVariablesManager.getInstance().getLong("elpy_respawn_time", 0);
if (respawnTime <= System.currentTimeMillis())
{
addSpawn(MUTATED_ELPY, -45474, 247450, -13994, 49152, false, 0, false);
}
else
{
ThreadPoolManager.getInstance().scheduleGeneral(() -> addSpawn(MUTATED_ELPY, -45474, 247450, -13994, 49152, false, 0, false), respawnTime - System.currentTimeMillis());
}
}
private L2Npc spawnRandomSpore()
{
return addSpawn(getRandom(SPORE_FIRE, SPORE_EARTH), -45474, 247450, -13994, 49152, false, 0, false);
}
private L2Npc spawnOppositeSpore(int srcSporeId)
{
final int idx = Arrays.binarySearch(ELEMENTS, srcSporeId);
return idx >= 0 ? addSpawn(OPPOSITE_ELEMENTS[idx], -45474, 247450, -13994, 49152, false, 0, false) : null;
}
private void startRoom(int managerId)
{
_activeRooms.put(managerId, true);
if (DOORS.containsKey(managerId))
{
int[] doorList = DOORS.get(managerId);
DoorData.getInstance().getDoor(doorList[0]).closeMe();
}
if (SPAWNS.containsKey(managerId))
{
int[][] spawnList = SPAWNS.get(managerId);
List spawned = new CopyOnWriteArrayList<>();
for (int[] spawn : spawnList)
{
L2Npc spawnedNpc = addSpawn(spawn[0], spawn[1], spawn[2], spawn[3], spawn[4], false, 0, false);
spawned.add(spawnedNpc);
}
if (!spawned.isEmpty())
{
_spawns.put(managerId, spawned);
}
}
}
private void removeForeigners(int managerId, L2Party party)
{
if ((party != null) && ZONES.containsKey(managerId) && (ZoneManager.getInstance().getZoneById(ZONES.get(managerId)) != null))
{
L2ZoneType zone = ZoneManager.getInstance().getZoneById(ZONES.get(managerId));
for (L2PcInstance player : zone.getPlayersInside())
{
if (player != null)
{
L2Party charParty = player.getParty();
if ((charParty == null) || (charParty.getLeaderObjectId() != party.getLeaderObjectId()))
{
player.teleToLocation(16110, 243841, 11616);
}
}
}
}
}
private void removeAllPlayers(int managerId)
{
if (ZONES.containsKey(managerId) && (ZoneManager.getInstance().getZoneById(ZONES.get(managerId)) != null))
{
L2ZoneType zone = ZoneManager.getInstance().getZoneById(ZONES.get(managerId));
for (L2PcInstance player : zone.getPlayersInside())
{
if (player != null)
{
player.teleToLocation(16110, 243841, 11616);
}
}
}
}
private void removeSpores()
{
for (L2Npc spore : _sporeSpawn)
{
if ((spore != null) && !spore.isDead())
{
spore.deleteMe();
}
}
_sporeSpawn.clear();
cancelQuestTimers("despawn_spore");
}
private class StopRoomTask implements Runnable
{
private final int _managerId;
public StopRoomTask(int managerId)
{
_managerId = managerId;
}
@Override
public void run()
{
initRoom(_managerId);
}
}
}