package l2p.gameserver.scripts;
import javolution.util.FastMap;
import l2p.common.ThreadPoolManager;
import l2p.database.DatabaseUtils;
import l2p.database.FiltredPreparedStatement;
import l2p.database.L2DatabaseFactory;
import l2p.database.ThreadConnection;
import l2p.gameserver.Announcements;
import l2p.gameserver.instancemanager.ClanHallManager;
import l2p.gameserver.model.L2Character;
import l2p.gameserver.model.L2Clan;
import l2p.gameserver.model.L2Player;
import l2p.gameserver.model.L2Summon;
import l2p.gameserver.model.entity.residence.ClanHall;
import l2p.gameserver.model.instances.L2DoorInstance;
import l2p.gameserver.model.instances.L2NpcInstance;
import l2p.gameserver.model.quest.Quest;
import l2p.gameserver.modules.data.DoorTable;
import l2p.gameserver.modules.event.mEvent;
import l2p.gameserver.tables.ClanTable;
import l2p.util.Location;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashSet;
import java.util.concurrent.ScheduledFuture;
/**
* User: voron.dev
* Date: 11.10.11
* Time: 11:13
*/
public class WildBeastReserve extends L2CoreScript
{
private static class Data
{
int clanId = 0;
int flagId = 0;
HashSet<L2Player> members = new HashSet<L2Player>();
}
private static ClanHall clanHall = ClanHallManager.getInstance().getClanHall(63);
private static final int timeSecond = 1000;
private static final int timeMinute = 60 * timeSecond;
private static final int timeHour = timeMinute * 60;
private static final int timeRunBattle = timeHour;
private static final int timeEndBattle = timeHour;
private static ScheduledFuture<?> runReg;
private static ScheduledFuture<?> runEndBattle;
private static boolean enableReg = false;
private static boolean enableBattle = false;
private static FastMap<Integer, Data> datas = new FastMap<Integer, Data>();
private static ArrayList<L2NpcInstance> spawns = new ArrayList<L2NpcInstance>();
private static int[] npcFlag =
{
35423, 35424, 35425, 35426, 35427
};
private static int[] npcCommander =
{
35428, 35429, 35430, 35431, 35432
};
private static final int[][] spawnFlags =
{
{
56324, -94207, -1360
},
{
58834, -94636, -1360
},
{
60059, -92417, -1360
},
{
58306, -90447, -1360
},
{
55885, -91614, -1360
},
};
private static final int[][] spawnCommander =
{
{
56488, -94038, -1360
},
{
58707, -94395, -1360
},
{
59750, -92481, -1360
},
{
58266, -90711, -1360
},
{
56081, -91717, -1360
},
};
private static final int[] doors =
{
21150005, 21150006, 21150007, 21150008, 21150009,
};
private static int countKillFlags = 0;
private static Calendar dateStartReg = Calendar.getInstance();
private static int siegeDayOfWeak = 0;
private static int siegeHourOfDay = 0;
@Override
public void onLoad()
{
L2DoorInstance door = DoorTable.getInstance().getDoor(21150003);
clanHall.getDoors().add(door);
door = DoorTable.getInstance().getDoor(21150004);
clanHall.getDoors().add(door);
startAutoTask();
}
@Override
public void onReload()
{
}
@Override
public void onShutdown()
{
}
public void info()
{
L2Player player = getSelfPlayer();
StringBuilder sb = new StringBuilder();
sb.append("<font color=\"LEVEL\">Текущее время:</font>").append("<br1>");
sb.append(Calendar.getInstance().getTime().toString()).append("<br>");
sb.append("<font color=\"LEVEL\">Начало регистрации:</font>").append("<br1>");
sb.append(dateStartReg.getTime().toString()).append("<br>");
sb.append("<font color=\"LEVEL\">Начало осады:</font>").append("<br1>");
Calendar dateStartBattle = Calendar.getInstance();
dateStartBattle.setTimeInMillis(dateStartReg.getTimeInMillis());
dateStartBattle.add(Calendar.MILLISECOND, timeRunBattle);
sb.append(dateStartBattle.getTime().toString()).append("<br>");
sb.append("<font color=\"LEVEL\">Зарегестрированные кланы:</font>").append("<br1>");
for(Data data : datas.values())
{
String name = ClanTable.getInstance().getClanName(data.clanId);
sb.append(name).append(" - ").append(data.members.size()).append(" человек(а)").append("<br>");
}
show(sb.toString(), player);
}
public void regClan()
{
L2Player player = getSelfPlayer();
if(enableReg)
{
L2Clan clan = player.getClan();
if(clan != null && player.isClanLeader())
{
if(!datas.containsKey(clan.getClanId()))
{
Data data = new Data();
data.clanId = clan.getClanId();
data.members.add(player);
datas.put(clan.getClanId(), data);
show("Регистрация прошла успешно.", player);
}
else
{
show("Ваш клан уже зарегестрирован.", player);
}
}
else
{
show("Регистрация доступна только для главы клана.", player);
}
}
else
{
show("Регистрация в данный момент не доступна.", player);
}
}
public void regClanMember()
{
L2Player player = getSelfPlayer();
if(enableReg)
{
L2Clan clan = player.getClan();
if(clan != null)
{
Data data = datas.get(clan.getClanId());
if(data != null)
{
if(data.members.contains(player))
{
show("Вы уже зарегестрированы.", player);
}
else if(data.members.size() < 18)
{
data.members.add(player);
show("Регистрация прошла успешно.", player);
}
else
{
show("Для вашего клана достигнуто максимальное кол-во участников.", player);
}
}
else
{
show("Ваш клан не зарегестрирован на осаду", player);
}
}
else
{
show("Вы не состоите в клане.", player);
}
}
else
{
show("Регистрация в данный момент не доступна.", player);
}
}
private class runReg implements Runnable
{
@Override
public void run()
{
ThreadPoolManager.getInstance().scheduleGeneral(new runBattle(), timeRunBattle);
L2Clan clan = clanHall.getOwner();
if(clan != null)
{
Data data = new Data();
data.clanId = clan.getClanId();
L2Player player = clan.getLeader().getPlayer();
if(player != null)
{
data.members.add(player);
}
datas.put(clan.getClanId(), data);
}
clanHall.changeOwner(null);
enableReg = true;
Announcements.getInstance().announceToAll("Открыта регистрация на осаду ClanHall Wild Beast Reserve.");
}
}
private class runBattle implements Runnable
{
@Override
public void run()
{
if(datas.size() < 1)
{
Announcements.getInstance().announceToAll("Осада ClanHall Wild Beast Reserve отменена из за отсутствия к ней интереса.");
saveSiege();
return;
}
enableReg = false;
Announcements.getInstance().announceToAll("Закрыта регистрация на осаду ClanHall Wild Beast Reserve.");
enableBattle = true;
runEndBattle = ThreadPoolManager.getInstance().scheduleGeneral(new runEndBattle(), timeEndBattle);
for(int doorId : doors)
{
DoorTable.getInstance().getDoor(doorId).openMe();
}
for(int i = 0; i < 5; i++)
{
Location location = new Location(spawnFlags[i][0], spawnFlags[i][1], spawnFlags[i][2], 0);
L2NpcInstance npc = Quest.addSpawnToInstance(npcFlag[i], location, 0, 0);
spawns.add(npc);
location = new Location(spawnCommander[i][0], spawnCommander[i][1], spawnCommander[i][2], 0);
npc = Quest.addSpawnToInstance(npcCommander[i], location, 0, 0);
spawns.add(npc);
}
int i = 0;
for(Data data : datas.values())
{
data.flagId = npcFlag[i];
for(L2Player player : data.members)
{
Location location = new Location(spawnCommander[i][0], spawnCommander[i][1], spawnCommander[i][2]);
mEvent.teleportToLocation(player, location, true, 0);
}
i++;
}
}
}
private class runEndBattle implements Runnable
{
@Override
public void run()
{
enableBattle = false;
for(int doorId : doors)
{
DoorTable.getInstance().getDoor(doorId).closeMe();
}
for(L2NpcInstance npc : spawns)
{
npc.deleteMe();
}
for(Data data : datas.values())
{
for(L2Player player : data.members)
{
mEvent.unTeleportToLocation(player);
}
}
datas.clear();
saveSiege();
}
}
public void OnDie(L2Character self, L2Character killer)
{
if(enableBattle)
{
if(self instanceof L2NpcInstance)
{
for(int flagId : npcFlag)
{
if(flagId == self.getNpcId())
{
countKillFlags++;
break;
}
}
Data dataDel = null;
for(Data data : datas.values())
{
if(data.flagId == self.getNpcId())
{
dataDel = data;
for(L2Player player : data.members)
{
mEvent.unTeleportToLocation(player);
}
break;
}
}
if(dataDel != null)
{
datas.remove(dataDel.clanId);
}
synchronized(this)
{
if(countKillFlags >= 4 || datas.isEmpty())
{
runEndBattle.cancel(true);
runEndBattle = ThreadPoolManager.getInstance().scheduleGeneral(new runEndBattle(), 5 * timeSecond);
countKillFlags = 0;
}
if(datas.size() == 1)
{
L2Clan clan = null;
if(killer instanceof L2Player)
{
clan = killer.getPlayer().getClan();
}
else if(killer instanceof L2Summon)
{
clan = killer.getPet().getPlayer().getClan();
}
clanHall.changeOwner(clan);
}
}
}
else if(self instanceof L2Player)
{
L2Player player = (L2Player) self;
for(Data data : datas.values())
{
if(data.members.contains(player))
{
mEvent.resurrectAndHeal(player);
int index = data.flagId - 35423;
Location location = new Location(spawnCommander[index][0], spawnCommander[index][1], spawnCommander[index][2]);
mEvent.teleportToLocation(player, location, false, 0);
break;
}
}
}
}
}
private void startAutoTask()
{
if(runReg != null)
{
return;
}
loadData();
correctSiegeDateTime();
runReg = ThreadPoolManager.getInstance().scheduleGeneral(new runReg(), dateStartReg.getTimeInMillis() - System.currentTimeMillis());
}
private void correctSiegeDateTime()
{
dateStartReg.setTimeInMillis(System.currentTimeMillis());
if(dateStartReg.get(Calendar.DAY_OF_WEEK) != siegeDayOfWeak)
{
dateStartReg.set(Calendar.DAY_OF_WEEK, siegeDayOfWeak);
}
if(dateStartReg.get(Calendar.HOUR_OF_DAY) != siegeHourOfDay)
{
dateStartReg.set(Calendar.HOUR_OF_DAY, siegeHourOfDay);
}
dateStartReg.set(Calendar.MINUTE, 0);
dateStartReg.set(Calendar.SECOND, 0);
if(dateStartReg.getTimeInMillis() < System.currentTimeMillis())
{
setNextSiegeDate();
}
}
private void setNextSiegeDate()
{
if(dateStartReg.getTimeInMillis() < System.currentTimeMillis())
{
dateStartReg.add(Calendar.DAY_OF_MONTH, 14);
if(dateStartReg.getTimeInMillis() < System.currentTimeMillis())
{
setNextSiegeDate();
}
}
}
private void saveSiege()
{
runReg = null;
setNextSiegeDate();
saveData();
startAutoTask();
}
private void loadData()
{
ThreadConnection threadConnection = null;
FiltredPreparedStatement filtredPreparedStatement = null;
ResultSet resultSet = null;
try
{
threadConnection = L2DatabaseFactory.getInstance().getConnection();
filtredPreparedStatement = threadConnection.prepareStatement("SELECT siegeDate, siegeDayOfWeek, siegeHourOfDay FROM clanhall WHERE id=? LIMIT 1");
filtredPreparedStatement.setInt(1, 63);
resultSet = filtredPreparedStatement.executeQuery();
while(resultSet.next())
{
dateStartReg.setTimeInMillis(resultSet.getLong("siegeDate"));
siegeDayOfWeak = resultSet.getInt("siegeDayOfWeek");
siegeHourOfDay = resultSet.getInt("siegeHourOfDay");
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
DatabaseUtils.closeDatabaseCSR(threadConnection, filtredPreparedStatement, resultSet);
}
}
private void saveData()
{
ThreadConnection threadConnection = null;
FiltredPreparedStatement filtredPreparedStatement = null;
try
{
threadConnection = L2DatabaseFactory.getInstance().getConnection();
filtredPreparedStatement = threadConnection.prepareStatement("UPDATE `clanhall` SET `siegeDate`='" + dateStartReg.getTimeInMillis() / 1000 + "' WHERE `id`='63'");
filtredPreparedStatement.execute();
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
DatabaseUtils.closeDatabaseCS(threadConnection, filtredPreparedStatement);
}
}
}