/*
* 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 .
*/
package com.l2jserver.gameserver.datatables;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jserver.Config;
import com.l2jserver.L2DatabaseFactory;
import com.l2jserver.gameserver.instancemanager.DayNightSpawnManager;
import com.l2jserver.gameserver.model.L2Spawn;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.templates.chars.L2NpcTemplate;
import javolution.util.FastMap;
/**
* This class ...
*
* @author Nightmare
* @version $Revision: 1.5.2.6.2.7 $ $Date: 2005/03/27 15:29:18 $
*/
public class SpawnTable
{
private static Logger _log = Logger.getLogger(SpawnTable.class.getName());
private Map _spawntable = new FastMap().shared();
private int _npcSpawnCount;
private int _customSpawnCount;
private int _highestId;
public static SpawnTable getInstance()
{
return SingletonHolder._instance;
}
private SpawnTable()
{
if (!Config.ALT_DEV_NO_SPAWNS)
fillSpawnTable();
}
public Map getSpawnTable()
{
return _spawntable;
}
private void fillSpawnTable()
{
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement;
if (Config.DELETE_GMSPAWN_ON_CUSTOM)
{
statement = con.prepareStatement("SELECT id, count, npc_templateid, locx, locy, locz, heading, respawn_delay, loc_id, periodOfDay FROM spawnlist where id NOT in ( select id from custom_notspawned where isCustom = false ) ORDER BY id");
}
else
{
statement = con.prepareStatement("SELECT id, count, npc_templateid, locx, locy, locz, heading, respawn_delay, loc_id, periodOfDay FROM spawnlist ORDER BY id");
}
ResultSet rset = statement.executeQuery();
L2Spawn spawnDat;
L2NpcTemplate template1;
while (rset.next())
{
template1 = NpcTable.getInstance().getTemplate(rset.getInt("npc_templateid"));
if (template1 != null)
{
if (template1.type.equalsIgnoreCase("L2SiegeGuard"))
{
// Don't spawn
}
else if (template1.type.equalsIgnoreCase("L2RaidBoss"))
{
// Don't spawn raidboss
}
else if (!Config.ALLOW_CLASS_MASTERS && template1.type.equals("L2ClassMaster"))
{
// Dont' spawn class masters
}
else
{
spawnDat = new L2Spawn(template1);
spawnDat.setId(rset.getInt("id"));
spawnDat.setAmount(rset.getInt("count"));
spawnDat.setLocx(rset.getInt("locx"));
spawnDat.setLocy(rset.getInt("locy"));
spawnDat.setLocz(rset.getInt("locz"));
spawnDat.setHeading(rset.getInt("heading"));
spawnDat.setRespawnDelay(rset.getInt("respawn_delay"));
int loc_id = rset.getInt("loc_id");
spawnDat.setLocation(loc_id);
switch (rset.getInt("periodOfDay"))
{
case 0: // default
_npcSpawnCount += spawnDat.init();
break;
case 1: // Day
DayNightSpawnManager.getInstance().addDayCreature(spawnDat);
_npcSpawnCount++;
break;
case 2: // Night
DayNightSpawnManager.getInstance().addNightCreature(spawnDat);
_npcSpawnCount++;
break;
}
_spawntable.put(spawnDat.getId(), spawnDat);
if (spawnDat.getId() > _highestId)
_highestId = spawnDat.getId();
}
}
else
{
_log.warning("SpawnTable: Data missing in NPC table for ID: " + rset.getInt("npc_templateid") + ".");
}
}
rset.close();
statement.close();
}
catch (Exception e)
{
// problem with initializing spawn, go to next one
_log.log(Level.WARNING, "SpawnTable: Spawn could not be initialized: " + e.getMessage(), e);
}
finally
{
L2DatabaseFactory.close(con);
}
_log.info("SpawnTable: Loaded " + _spawntable.size() + " Npc Spawn Locations.");
if (Config.CUSTOM_SPAWNLIST_TABLE)
{
try
{
con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement;
if (Config.DELETE_GMSPAWN_ON_CUSTOM)
{
statement = con.prepareStatement("SELECT id, count, npc_templateid, locx, locy, locz, heading, respawn_delay, loc_id, periodOfDay FROM custom_spawnlist where id NOT in ( select id from custom_notspawned where isCustom = true ) ORDER BY id");
}
else
{
statement = con.prepareStatement("SELECT id, count, npc_templateid, locx, locy, locz, heading, respawn_delay, loc_id, periodOfDay FROM custom_spawnlist ORDER BY id");
}
ResultSet rset = statement.executeQuery();
L2Spawn spawnDat;
L2NpcTemplate template1;
while (rset.next())
{
template1 = NpcTable.getInstance().getTemplate(rset.getInt("npc_templateid"));
if (template1 != null)
{
if (template1.type.equalsIgnoreCase("L2SiegeGuard"))
{
// Don't spawn
}
else if (template1.type.equalsIgnoreCase("L2RaidBoss"))
{
// Don't spawn raidboss
}
else if (!Config.ALLOW_CLASS_MASTERS && template1.type.equals("L2ClassMaster"))
{
// Dont' spawn class masters
}
else
{
spawnDat = new L2Spawn(template1);
spawnDat.setId(rset.getInt("id"));
spawnDat.setAmount(rset.getInt("count"));
spawnDat.setLocx(rset.getInt("locx"));
spawnDat.setLocy(rset.getInt("locy"));
spawnDat.setLocz(rset.getInt("locz"));
spawnDat.setHeading(rset.getInt("heading"));
spawnDat.setRespawnDelay(rset.getInt("respawn_delay"));
spawnDat.setCustom(true);
int loc_id = rset.getInt("loc_id");
spawnDat.setLocation(loc_id);
switch (rset.getInt("periodOfDay"))
{
case 0: // default
_customSpawnCount += spawnDat.init();
break;
case 1: // Day
DayNightSpawnManager.getInstance().addDayCreature(spawnDat);
_customSpawnCount++;
break;
case 2: // Night
DayNightSpawnManager.getInstance().addNightCreature(spawnDat);
_customSpawnCount++;
break;
}
_spawntable.put(spawnDat.getId(), spawnDat);
if (spawnDat.getId() > _highestId)
_highestId = spawnDat.getId();
}
}
else
{
_log.warning("CustomSpawnTable: Data missing in NPC table for ID: " + rset.getInt("npc_templateid") + ".");
}
}
rset.close();
statement.close();
}
catch (Exception e)
{
// problem with initializing spawn, go to next one
_log.log(Level.WARNING, "CustomSpawnTable: Spawn could not be initialized: " + e.getMessage(), e);
}
finally
{
L2DatabaseFactory.close(con);
}
_log.info("CustomSpawnTable: Loaded " + _customSpawnCount + " Npc Spawn Locations.");
}
if (Config.DEBUG)
_log.fine("SpawnTable: Spawning completed, total number of NPCs in the world: " + (_npcSpawnCount + _customSpawnCount));
}
public L2Spawn getTemplate(int id)
{
return _spawntable.get(id);
}
public void addNewSpawn(L2Spawn spawn, boolean storeInDb)
{
_highestId++;
spawn.setId(_highestId);
_spawntable.put(_highestId, spawn);
if (storeInDb)
{
Connection con = null;
String spawnTable;
if (spawn.isCustom() && Config.CUSTOM_SPAWNLIST_TABLE)
spawnTable = "custom_spawnlist";
else
spawnTable = "spawnlist";
try
{
con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("INSERT INTO " + spawnTable
+ "(id,count,npc_templateid,locx,locy,locz,heading,respawn_delay,loc_id) values(?,?,?,?,?,?,?,?,?)");
statement.setInt(1, spawn.getId());
statement.setInt(2, spawn.getAmount());
statement.setInt(3, spawn.getNpcid());
statement.setInt(4, spawn.getLocx());
statement.setInt(5, spawn.getLocy());
statement.setInt(6, spawn.getLocz());
statement.setInt(7, spawn.getHeading());
statement.setInt(8, spawn.getRespawnDelay() / 1000);
statement.setInt(9, spawn.getLocation());
statement.execute();
statement.close();
}
catch (Exception e)
{
// problem with storing spawn
_log.log(Level.WARNING, "SpawnTable: Could not store spawn in the DB:" + e.getMessage(), e);
}
finally
{
L2DatabaseFactory.close(con);
}
}
}
public void deleteSpawn(L2Spawn spawn, boolean updateDb)
{
if (_spawntable.remove(spawn.getId()) == null)
return;
if (updateDb)
{
Connection con = null;
if (Config.DELETE_GMSPAWN_ON_CUSTOM)
{
try
{
con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("Replace into custom_notspawned VALUES (?,?)");
statement.setInt(1, spawn.getId());
statement.setBoolean(2, spawn.isCustom());
statement.execute();
statement.close();
}
catch (Exception e)
{
// problem with inserting nospawn
_log.log(Level.WARNING, "SpawnTable: Spawn " + spawn.getId() + " could not be insert into DB: " + e.getMessage(), e);
}
finally
{
L2DatabaseFactory.close(con);
}
}
else
{
try
{
con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("DELETE FROM "
+ (spawn.isCustom() ? "custom_spawnlist" : "spawnlist") + " WHERE id=?");
statement.setInt(1, spawn.getId());
statement.execute();
statement.close();
}
catch (Exception e)
{
// problem with deleting spawn
_log.log(Level.WARNING, "SpawnTable: Spawn " + spawn.getId() + " could not be removed from DB: " + e.getMessage(), e);
}
finally
{
L2DatabaseFactory.close(con);
}
}
}
}
//just wrapper
public void reloadAll()
{
fillSpawnTable();
}
/**
* Get all the spawn of a NPC
*
* @param npcId : ID of the NPC to find.
* @return
*/
public void findNPCInstances(L2PcInstance activeChar, int npcId, int teleportIndex)
{
int index = 0;
for (L2Spawn spawn : _spawntable.values())
{
if (npcId == spawn.getNpcid())
{
index++;
if (teleportIndex > -1)
{
if (teleportIndex == index)
activeChar.teleToLocation(spawn.getLocx(), spawn.getLocy(), spawn.getLocz(), true);
}
else
{
activeChar.sendMessage(index + " - " + spawn.getTemplate().name + " (" + spawn.getId() + "): " + spawn.getLocx() + " "
+ spawn.getLocy() + " " + spawn.getLocz());
}
}
}
if (index == 0)
activeChar.sendMessage("No current spawns found.");
}
@SuppressWarnings("synthetic-access")
private static class SingletonHolder
{
protected static final SpawnTable _instance = new SpawnTable();
}
}