Chronicle 4 branch.
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* 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 com.l2jmobius.gameserver.instancemanager;
|
||||
|
||||
import com.l2jmobius.gameserver.model.L2Character;
|
||||
import com.l2jmobius.gameserver.model.zone.type.L2ArenaZone;
|
||||
|
||||
import javolution.util.FastList;
|
||||
|
||||
public class ArenaManager
|
||||
{
|
||||
|
||||
// =========================================================
|
||||
private static ArenaManager _Instance;
|
||||
|
||||
public static final ArenaManager getInstance()
|
||||
{
|
||||
if (_Instance == null)
|
||||
{
|
||||
System.out.println("Initializing ArenaManager");
|
||||
_Instance = new ArenaManager();
|
||||
|
||||
}
|
||||
return _Instance;
|
||||
}
|
||||
// =========================================================
|
||||
|
||||
// =========================================================
|
||||
// Data Field
|
||||
private FastList<L2ArenaZone> _Arenas;
|
||||
|
||||
// =========================================================
|
||||
// Constructor
|
||||
public ArenaManager()
|
||||
{
|
||||
}
|
||||
|
||||
// Property - Public
|
||||
public void addArena(L2ArenaZone arena)
|
||||
{
|
||||
if (_Arenas == null)
|
||||
{
|
||||
_Arenas = new FastList<>();
|
||||
}
|
||||
|
||||
_Arenas.add(arena);
|
||||
}
|
||||
|
||||
public final L2ArenaZone getArena(L2Character character)
|
||||
{
|
||||
for (final L2ArenaZone temp : _Arenas)
|
||||
{
|
||||
if (temp.isCharacterInZone(character))
|
||||
{
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public final L2ArenaZone getArena(int arenaId)
|
||||
{
|
||||
for (final L2ArenaZone temp : _Arenas)
|
||||
{
|
||||
if (temp.getId() == arenaId)
|
||||
{
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* 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 com.l2jmobius.gameserver.instancemanager;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.L2DatabaseFactory;
|
||||
import com.l2jmobius.gameserver.model.entity.Auction;
|
||||
|
||||
import javolution.util.FastList;
|
||||
|
||||
public class AuctionManager
|
||||
{
|
||||
protected static Logger _log = Logger.getLogger(AuctionManager.class.getName());
|
||||
|
||||
// =========================================================
|
||||
private static AuctionManager _Instance;
|
||||
|
||||
public static final AuctionManager getInstance()
|
||||
{
|
||||
if (_Instance == null)
|
||||
{
|
||||
System.out.println("Initializing AuctionManager");
|
||||
_Instance = new AuctionManager();
|
||||
|
||||
}
|
||||
return _Instance;
|
||||
}
|
||||
// =========================================================
|
||||
|
||||
// =========================================================
|
||||
// Data Field
|
||||
private List<Auction> _Auctions;
|
||||
|
||||
private static final String[] ITEM_INIT_DATA =
|
||||
{
|
||||
"(22, 0, 'NPC', 'NPC Clan', 'ClanHall', 22, 0, 'Moonstone Hall', 1, 20000000, 0, 1164841200000)",
|
||||
"(23, 0, 'NPC', 'NPC Clan', 'ClanHall', 23, 0, 'Onyx Hall', 1, 20000000, 0, 1164841200000)",
|
||||
"(24, 0, 'NPC', 'NPC Clan', 'ClanHall', 24, 0, 'Topaz Hall', 1, 20000000, 0, 1164841200000)",
|
||||
"(25, 0, 'NPC', 'NPC Clan', 'ClanHall', 25, 0, 'Ruby Hall', 1, 20000000, 0, 1164841200000)",
|
||||
"(26, 0, 'NPC', 'NPC Clan', 'ClanHall', 26, 0, 'Crystal Hall', 1, 20000000, 0, 1164841200000)",
|
||||
"(27, 0, 'NPC', 'NPC Clan', 'ClanHall', 27, 0, 'Onyx Hall', 1, 20000000, 0, 1164841200000)",
|
||||
"(28, 0, 'NPC', 'NPC Clan', 'ClanHall', 28, 0, 'Sapphire Hall', 1, 20000000, 0, 1164841200000)",
|
||||
"(29, 0, 'NPC', 'NPC Clan', 'ClanHall', 29, 0, 'Moonstone Hall', 1, 20000000, 0, 1164841200000)",
|
||||
"(30, 0, 'NPC', 'NPC Clan', 'ClanHall', 30, 0, 'Emerald Hall', 1, 20000000, 0, 1164841200000)",
|
||||
"(31, 0, 'NPC', 'NPC Clan', 'ClanHall', 31, 0, 'The Atramental Barracks', 1, 8000000, 0, 1164841200000)",
|
||||
"(32, 0, 'NPC', 'NPC Clan', 'ClanHall', 32, 0, 'The Scarlet Barracks', 1, 8000000, 0, 1164841200000)",
|
||||
"(33, 0, 'NPC', 'NPC Clan', 'ClanHall', 33, 0, 'The Viridian Barracks', 1, 8000000, 0, 1164841200000)",
|
||||
"(36, 0, 'NPC', 'NPC Clan', 'ClanHall', 36, 0, 'The Golden Chamber', 1, 50000000, 0, 1164841200000)",
|
||||
"(37, 0, 'NPC', 'NPC Clan', 'ClanHall', 37, 0, 'The Silver Chamber', 1, 50000000, 0, 1164841200000)",
|
||||
"(38, 0, 'NPC', 'NPC Clan', 'ClanHall', 38, 0, 'The Mithril Chamber', 1, 50000000, 0, 1164841200000)",
|
||||
"(39, 0, 'NPC', 'NPC Clan', 'ClanHall', 39, 0, 'Silver Manor', 1, 50000000, 0, 1164841200000)",
|
||||
"(40, 0, 'NPC', 'NPC Clan', 'ClanHall', 40, 0, 'Gold Manor', 1, 50000000, 0, 1164841200000)",
|
||||
"(41, 0, 'NPC', 'NPC Clan', 'ClanHall', 41, 0, 'The Bronze Chamber', 1, 50000000, 0, 1164841200000)",
|
||||
"(42, 0, 'NPC', 'NPC Clan', 'ClanHall', 42, 0, 'The Golden Chamber', 1, 50000000, 0, 1164841200000)",
|
||||
"(43, 0, 'NPC', 'NPC Clan', 'ClanHall', 43, 0, 'The Silver Chamber', 1, 50000000, 0, 1164841200000)",
|
||||
"(44, 0, 'NPC', 'NPC Clan', 'ClanHall', 44, 0, 'The Mithril Chamber', 1, 50000000, 0, 1164841200000)",
|
||||
"(45, 0, 'NPC', 'NPC Clan', 'ClanHall', 45, 0, 'The Bronze Chamber', 1, 50000000, 0, 1164841200000)",
|
||||
"(46, 0, 'NPC', 'NPC Clan', 'ClanHall', 46, 0, 'Silver Manor', 1, 50000000, 0, 1164841200000)",
|
||||
"(47, 0, 'NPC', 'NPC Clan', 'ClanHall', 47, 0, 'Moonstone Hall', 1, 50000000, 0, 1164841200000)",
|
||||
"(48, 0, 'NPC', 'NPC Clan', 'ClanHall', 48, 0, 'Onyx Hall', 1, 50000000, 0, 1164841200000)",
|
||||
"(49, 0, 'NPC', 'NPC Clan', 'ClanHall', 49, 0, 'Emerald Hall', 1, 50000000, 0, 1164841200000)",
|
||||
"(50, 0, 'NPC', 'NPC Clan', 'ClanHall', 50, 0, 'Sapphire Hall', 1, 50000000, 0, 1164841200000)"
|
||||
};
|
||||
|
||||
private static final Integer[] ItemInitDataId =
|
||||
{
|
||||
22,
|
||||
23,
|
||||
24,
|
||||
25,
|
||||
26,
|
||||
27,
|
||||
28,
|
||||
29,
|
||||
30,
|
||||
31,
|
||||
32,
|
||||
33,
|
||||
36,
|
||||
37,
|
||||
38,
|
||||
39,
|
||||
40,
|
||||
41,
|
||||
42,
|
||||
43,
|
||||
44,
|
||||
45,
|
||||
46,
|
||||
47,
|
||||
48,
|
||||
49,
|
||||
50
|
||||
};
|
||||
|
||||
// =========================================================
|
||||
// Constructor
|
||||
public AuctionManager()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Method - Public
|
||||
public void reload()
|
||||
{
|
||||
getAuctions().clear();
|
||||
load();
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Method - Private
|
||||
private final void load()
|
||||
{
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("Select id from auction order by id");
|
||||
ResultSet rs = statement.executeQuery())
|
||||
{
|
||||
while (rs.next())
|
||||
{
|
||||
getAuctions().add(new Auction(rs.getInt("id")));
|
||||
}
|
||||
|
||||
System.out.println("Loaded: " + getAuctions().size() + " auction(s)");
|
||||
}
|
||||
catch (final Exception e)
|
||||
{
|
||||
System.out.println("Exception: AuctionManager.load(): " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Property - Public
|
||||
public final Auction getAuction(int auctionId)
|
||||
{
|
||||
final int index = getAuctionIndex(auctionId);
|
||||
if (index >= 0)
|
||||
{
|
||||
return getAuctions().get(index);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public final int getAuctionIndex(int auctionId)
|
||||
{
|
||||
Auction auction;
|
||||
for (int i = 0; i < getAuctions().size(); i++)
|
||||
{
|
||||
auction = getAuctions().get(i);
|
||||
if ((auction != null) && (auction.getId() == auctionId))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public final List<Auction> getAuctions()
|
||||
{
|
||||
if (_Auctions == null)
|
||||
{
|
||||
_Auctions = new FastList<>();
|
||||
}
|
||||
return _Auctions;
|
||||
}
|
||||
|
||||
public static boolean initNPC(int id)
|
||||
{
|
||||
int i = 0;
|
||||
for (i = 0; i < ItemInitDataId.length; i++)
|
||||
{
|
||||
if (ItemInitDataId[i] == id)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= ItemInitDataId.length)
|
||||
{
|
||||
_log.warning("Clan Hall auction not found for Id :" + id);
|
||||
return false;
|
||||
}
|
||||
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("INSERT INTO `auction` VALUES " + ITEM_INIT_DATA[i]))
|
||||
{
|
||||
statement.execute();
|
||||
}
|
||||
catch (final Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Exception: Auction.initNPC(): " + e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* 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 com.l2jmobius.gameserver.instancemanager;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.LineNumberReader;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.idfactory.IdFactory;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2BoatInstance;
|
||||
import com.l2jmobius.gameserver.templates.L2CharTemplate;
|
||||
import com.l2jmobius.gameserver.templates.StatsSet;
|
||||
|
||||
import javolution.util.FastMap;
|
||||
|
||||
public class BoatManager
|
||||
{
|
||||
private static final Logger _log = Logger.getLogger(BoatManager.class.getName());
|
||||
|
||||
// =========================================================
|
||||
// Data Field
|
||||
private Map<Integer, L2BoatInstance> _staticItems = new FastMap<>();
|
||||
protected boolean _initialized;
|
||||
|
||||
private static BoatManager _Instance;
|
||||
|
||||
public static final BoatManager getInstance()
|
||||
{
|
||||
if (_Instance == null)
|
||||
{
|
||||
_Instance = new BoatManager();
|
||||
}
|
||||
return _Instance;
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Constructor
|
||||
private BoatManager()
|
||||
{
|
||||
if (Config.ALLOW_BOAT)
|
||||
{
|
||||
System.out.println("Initializing BoatManager");
|
||||
load();
|
||||
}
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Method - Private
|
||||
private final void load()
|
||||
{
|
||||
_initialized = true;
|
||||
|
||||
final File boatData = new File(Config.DATAPACK_ROOT, "data/boat.csv");
|
||||
try (FileReader fr = new FileReader(boatData);
|
||||
BufferedReader br = new BufferedReader(fr);
|
||||
LineNumberReader lnr = new LineNumberReader(br))
|
||||
{
|
||||
String line = null;
|
||||
while ((line = lnr.readLine()) != null)
|
||||
{
|
||||
if ((line.trim().length() == 0) || line.startsWith("#"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final L2BoatInstance boat = parseLine(line);
|
||||
boat.beginCycle();
|
||||
|
||||
_staticItems.put(boat.getObjectId(), boat);
|
||||
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
System.out.println("Boat ID : " + boat.getObjectId());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (final FileNotFoundException e)
|
||||
{
|
||||
_initialized = false;
|
||||
_log.warning("boat.csv is missing in data folder");
|
||||
}
|
||||
catch (final Exception e)
|
||||
{
|
||||
_initialized = false;
|
||||
_log.warning("error while creating boat table " + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param line
|
||||
* @return
|
||||
*/
|
||||
private L2BoatInstance parseLine(String line)
|
||||
{
|
||||
L2BoatInstance boat;
|
||||
final StringTokenizer st = new StringTokenizer(line, ";");
|
||||
|
||||
final String name = st.nextToken();
|
||||
final int id = Integer.parseInt(st.nextToken());
|
||||
final int xspawn = Integer.parseInt(st.nextToken());
|
||||
final int yspawn = Integer.parseInt(st.nextToken());
|
||||
final int zspawn = Integer.parseInt(st.nextToken());
|
||||
final int heading = Integer.parseInt(st.nextToken());
|
||||
|
||||
final StatsSet npcDat = new StatsSet();
|
||||
npcDat.set("npcId", id);
|
||||
npcDat.set("level", 0);
|
||||
npcDat.set("jClass", "boat");
|
||||
|
||||
npcDat.set("baseSTR", 0);
|
||||
npcDat.set("baseCON", 0);
|
||||
npcDat.set("baseDEX", 0);
|
||||
npcDat.set("baseINT", 0);
|
||||
npcDat.set("baseWIT", 0);
|
||||
npcDat.set("baseMEN", 0);
|
||||
|
||||
npcDat.set("baseShldDef", 0);
|
||||
npcDat.set("baseShldRate", 0);
|
||||
npcDat.set("baseAccCombat", 38);
|
||||
npcDat.set("baseEvasRate", 38);
|
||||
npcDat.set("baseCritRate", 38);
|
||||
|
||||
npcDat.set("collision_radius", 0);
|
||||
npcDat.set("collision_height", 0);
|
||||
npcDat.set("sex", "male");
|
||||
npcDat.set("type", "");
|
||||
npcDat.set("baseAtkRange", 0);
|
||||
npcDat.set("baseMpMax", 0);
|
||||
npcDat.set("baseCpMax", 0);
|
||||
npcDat.set("rewardExp", 0);
|
||||
npcDat.set("rewardSp", 0);
|
||||
npcDat.set("basePAtk", 0);
|
||||
npcDat.set("baseMAtk", 0);
|
||||
npcDat.set("basePAtkSpd", 0);
|
||||
npcDat.set("aggroRange", 0);
|
||||
npcDat.set("baseMAtkSpd", 0);
|
||||
npcDat.set("rhand", 0);
|
||||
npcDat.set("lhand", 0);
|
||||
npcDat.set("armor", 0);
|
||||
npcDat.set("baseWalkSpd", 0);
|
||||
npcDat.set("baseRunSpd", 0);
|
||||
npcDat.set("name", name);
|
||||
npcDat.set("baseHpMax", 50000);
|
||||
npcDat.set("baseHpReg", 3.e-3f);
|
||||
npcDat.set("baseMpReg", 3.e-3f);
|
||||
npcDat.set("basePDef", 100);
|
||||
npcDat.set("baseMDef", 100);
|
||||
final L2CharTemplate template = new L2CharTemplate(npcDat);
|
||||
boat = new L2BoatInstance(IdFactory.getInstance().getNextId(), template);
|
||||
boat.setName(name);
|
||||
boat.setHeading(heading);
|
||||
boat.setXYZ(xspawn, yspawn, zspawn);
|
||||
|
||||
int IdWaypoint1 = Integer.parseInt(st.nextToken());
|
||||
int IdWTicket1 = Integer.parseInt(st.nextToken());
|
||||
int ntx1 = Integer.parseInt(st.nextToken());
|
||||
int nty1 = Integer.parseInt(st.nextToken());
|
||||
int ntz1 = Integer.parseInt(st.nextToken());
|
||||
String npc1 = st.nextToken();
|
||||
String mess10_1 = st.nextToken();
|
||||
String mess5_1 = st.nextToken();
|
||||
String mess1_1 = st.nextToken();
|
||||
String mess0_1 = st.nextToken();
|
||||
String messb_1 = st.nextToken();
|
||||
boat.SetTrajet1(IdWaypoint1, IdWTicket1, ntx1, nty1, ntz1, npc1, mess10_1, mess5_1, mess1_1, mess0_1, messb_1);
|
||||
IdWaypoint1 = Integer.parseInt(st.nextToken());
|
||||
IdWTicket1 = Integer.parseInt(st.nextToken());
|
||||
ntx1 = Integer.parseInt(st.nextToken());
|
||||
nty1 = Integer.parseInt(st.nextToken());
|
||||
ntz1 = Integer.parseInt(st.nextToken());
|
||||
npc1 = st.nextToken();
|
||||
mess10_1 = st.nextToken();
|
||||
mess5_1 = st.nextToken();
|
||||
mess1_1 = st.nextToken();
|
||||
mess0_1 = st.nextToken();
|
||||
messb_1 = st.nextToken();
|
||||
boat.SetTrajet2(IdWaypoint1, IdWTicket1, ntx1, nty1, ntz1, npc1, mess10_1, mess5_1, mess1_1, mess0_1, messb_1);
|
||||
return boat;
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Property - Public
|
||||
|
||||
/**
|
||||
* @param boatId
|
||||
* @return
|
||||
*/
|
||||
public L2BoatInstance getBoat(int boatId)
|
||||
{
|
||||
if (_staticItems == null)
|
||||
{
|
||||
_staticItems = new FastMap<>();
|
||||
}
|
||||
return _staticItems.get(boatId);
|
||||
}
|
||||
}
|
@@ -0,0 +1,329 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* 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 com.l2jmobius.gameserver.instancemanager;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.List;
|
||||
|
||||
import com.l2jmobius.L2DatabaseFactory;
|
||||
import com.l2jmobius.gameserver.SevenSigns;
|
||||
import com.l2jmobius.gameserver.model.L2Clan;
|
||||
import com.l2jmobius.gameserver.model.L2ClanMember;
|
||||
import com.l2jmobius.gameserver.model.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.entity.Castle;
|
||||
|
||||
import javolution.util.FastList;
|
||||
|
||||
public class CastleManager
|
||||
{
|
||||
// =========================================================
|
||||
private static CastleManager _Instance;
|
||||
|
||||
public static final CastleManager getInstance()
|
||||
{
|
||||
if (_Instance == null)
|
||||
{
|
||||
System.out.println("Initializing CastleManager");
|
||||
_Instance = new CastleManager();
|
||||
_Instance.load();
|
||||
}
|
||||
return _Instance;
|
||||
}
|
||||
// =========================================================
|
||||
|
||||
// =========================================================
|
||||
// Data Field
|
||||
private List<Castle> _Castles;
|
||||
private static final int _castleCirclets[] =
|
||||
{
|
||||
0,
|
||||
6838,
|
||||
6835,
|
||||
6839,
|
||||
6837,
|
||||
6840,
|
||||
6834,
|
||||
6836
|
||||
};
|
||||
|
||||
// =========================================================
|
||||
// Constructor
|
||||
public CastleManager()
|
||||
{
|
||||
}
|
||||
|
||||
public final int findNearestCastleIndex(L2Object obj)
|
||||
{
|
||||
int index = getCastleIndex(obj);
|
||||
if (index < 0)
|
||||
{
|
||||
double closestDistance = 99999999;
|
||||
double distance;
|
||||
Castle castle;
|
||||
for (int i = 0; i < getCastles().size(); i++)
|
||||
{
|
||||
castle = getCastles().get(i);
|
||||
if (castle == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
distance = castle.getDistance(obj);
|
||||
if (closestDistance > distance)
|
||||
{
|
||||
closestDistance = distance;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Method - Private
|
||||
private final void load()
|
||||
{
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("Select id from castle order by id");
|
||||
ResultSet rs = statement.executeQuery())
|
||||
{
|
||||
while (rs.next())
|
||||
{
|
||||
getCastles().add(new Castle(rs.getInt("id")));
|
||||
}
|
||||
|
||||
System.out.println("Loaded: " + getCastles().size() + " castles");
|
||||
}
|
||||
catch (final Exception e)
|
||||
{
|
||||
System.out.println("Exception: loadCastleData(): " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Property - Public
|
||||
public final Castle getCastleById(int castleId)
|
||||
{
|
||||
for (final Castle temp : getCastles())
|
||||
{
|
||||
if (temp.getCastleId() == castleId)
|
||||
{
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public final Castle getCastleByOwner(L2Clan clan)
|
||||
{
|
||||
for (final Castle temp : getCastles())
|
||||
{
|
||||
if (temp.getOwnerId() == clan.getClanId())
|
||||
{
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public final Castle getCastle(String name)
|
||||
{
|
||||
for (final Castle temp : getCastles())
|
||||
{
|
||||
if (temp.getName().equalsIgnoreCase(name.trim()))
|
||||
{
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public final Castle getCastle(int x, int y, int z)
|
||||
{
|
||||
for (final Castle temp : getCastles())
|
||||
{
|
||||
if (temp.checkIfInZone(x, y, z))
|
||||
{
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public final Castle getCastle(L2Object activeObject)
|
||||
{
|
||||
return getCastle(activeObject.getX(), activeObject.getY(), activeObject.getZ());
|
||||
}
|
||||
|
||||
public final int getCastleIndex(int castleId)
|
||||
{
|
||||
Castle castle;
|
||||
for (int i = 0; i < getCastles().size(); i++)
|
||||
{
|
||||
castle = getCastles().get(i);
|
||||
if ((castle != null) && (castle.getCastleId() == castleId))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public final int getCastleIndex(L2Object activeObject)
|
||||
{
|
||||
return getCastleIndex(activeObject.getX(), activeObject.getY(), activeObject.getZ());
|
||||
}
|
||||
|
||||
public final int getCastleIndex(int x, int y, int z)
|
||||
{
|
||||
Castle castle;
|
||||
for (int i = 0; i < getCastles().size(); i++)
|
||||
{
|
||||
castle = getCastles().get(i);
|
||||
if ((castle != null) && castle.checkIfInZone(x, y, z))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public final List<Castle> getCastles()
|
||||
{
|
||||
if (_Castles == null)
|
||||
{
|
||||
_Castles = new FastList<>();
|
||||
}
|
||||
return _Castles;
|
||||
}
|
||||
|
||||
public final void validateTaxes(int sealStrifeOwner)
|
||||
{
|
||||
int maxTax;
|
||||
switch (sealStrifeOwner)
|
||||
{
|
||||
case SevenSigns.CABAL_DUSK:
|
||||
maxTax = 5;
|
||||
break;
|
||||
case SevenSigns.CABAL_DAWN:
|
||||
maxTax = 25;
|
||||
break;
|
||||
default: // no owner
|
||||
maxTax = 15;
|
||||
break;
|
||||
}
|
||||
|
||||
for (final Castle castle : _Castles)
|
||||
{
|
||||
if (castle.getTaxPercent() > maxTax)
|
||||
{
|
||||
castle.setTaxPercent(maxTax);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getCircletByCastleId(int castleId)
|
||||
{
|
||||
if ((castleId > 0) && (castleId < 8))
|
||||
{
|
||||
return _castleCirclets[castleId];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// remove this castle's circlets from the clan
|
||||
public void removeCirclet(L2Clan clan, int castleId)
|
||||
{
|
||||
for (final L2ClanMember member : clan.getMembers())
|
||||
{
|
||||
if (member == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final L2PcInstance player = member.getPlayerInstance();
|
||||
final int circletId = getCircletByCastleId(castleId);
|
||||
|
||||
if (circletId != 0)
|
||||
{
|
||||
// online-player circlet removal
|
||||
if (player != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
final L2ItemInstance circlet = player.getInventory().getItemByItemId(circletId);
|
||||
if (circlet != null)
|
||||
{
|
||||
if (circlet.isEquipped())
|
||||
{
|
||||
player.getInventory().unEquipItemInSlotAndRecord(circlet.getEquipSlot());
|
||||
}
|
||||
player.destroyItemByItemId("CastleCircletRemoval", circletId, 1, player, true);
|
||||
}
|
||||
|
||||
if (player.isClanLeader())
|
||||
{
|
||||
final L2ItemInstance crown = player.getInventory().getItemByItemId(6841);
|
||||
if (crown != null)
|
||||
{
|
||||
if (crown.isEquipped())
|
||||
{
|
||||
player.getInventory().unEquipItemInSlotAndRecord(crown.getEquipSlot());
|
||||
}
|
||||
player.destroyItemByItemId("CastleCircletRemoval", 6841, 1, player, true);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
catch (final NullPointerException e)
|
||||
{
|
||||
// continue removing offline
|
||||
}
|
||||
}
|
||||
|
||||
// else offline-player circlet removal
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("DELETE FROM items WHERE owner_id = ? and item_id = ?"))
|
||||
{
|
||||
statement.setInt(1, member.getObjectId());
|
||||
statement.setInt(2, circletId);
|
||||
statement.execute();
|
||||
|
||||
if (member.getObjectId() == clan.getLeaderId())
|
||||
{
|
||||
final PreparedStatement statement2 = con.prepareStatement("DELETE FROM items WHERE owner_id = ? and item_id = ?");
|
||||
statement2.setInt(1, member.getObjectId());
|
||||
statement2.setInt(2, 6841);
|
||||
statement2.execute();
|
||||
}
|
||||
}
|
||||
catch (final Exception e)
|
||||
{
|
||||
System.out.println("Failed to remove castle circlets offline for player " + member.getName());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,623 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* 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 com.l2jmobius.gameserver.instancemanager;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.Calendar;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.L2DatabaseFactory;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.datatables.ClanTable;
|
||||
import com.l2jmobius.gameserver.model.ClanWarehouse;
|
||||
import com.l2jmobius.gameserver.model.ItemContainer;
|
||||
import com.l2jmobius.gameserver.model.L2Clan;
|
||||
import com.l2jmobius.gameserver.model.L2Manor;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.entity.Castle;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jmobius.util.Rnd;
|
||||
|
||||
import javolution.util.FastList;
|
||||
|
||||
/**
|
||||
* Class For Castle Manor Manager Load manor data from DB Update/Reload/Delete Handles all schedule for manor
|
||||
* @author l3x
|
||||
*/
|
||||
public class CastleManorManager
|
||||
{
|
||||
protected static Logger _log = Logger.getLogger(CastleManorManager.class.getName());
|
||||
|
||||
private static CastleManorManager _instance;
|
||||
|
||||
public static final int PERIOD_CURRENT = 0;
|
||||
public static final int PERIOD_NEXT = 1;
|
||||
|
||||
private static final String CASTLE_MANOR_LOAD_PROCURE = "SELECT * FROM castle_manor_procure WHERE castle_id=?";
|
||||
private static final String CASTLE_MANOR_LOAD_PRODUCTION = "SELECT * FROM castle_manor_production WHERE castle_id=?";
|
||||
|
||||
private static final int NEXT_PERIOD_APPROVE = Config.ALT_MANOR_APPROVE_TIME; // 6:00
|
||||
private static final int NEXT_PERIOD_APPROVE_MIN = Config.ALT_MANOR_APPROVE_MIN; //
|
||||
private static final int MANOR_REFRESH = Config.ALT_MANOR_REFRESH_TIME; // 20:00
|
||||
private static final int MANOR_REFRESH_MIN = Config.ALT_MANOR_REFRESH_MIN; //
|
||||
protected static final long MAINTENANCE_PERIOD = Config.ALT_MANOR_MAINTENANCE_PERIOD; // 6 mins
|
||||
|
||||
private Calendar _manorRefresh;
|
||||
private Calendar _periodApprove;
|
||||
|
||||
private boolean _underMaintenance;
|
||||
private boolean _disabled;
|
||||
|
||||
protected ScheduledFuture<?> _scheduledManorRefresh;
|
||||
protected ScheduledFuture<?> _scheduledMaintenanceEnd;
|
||||
protected ScheduledFuture<?> _scheduledNextPeriodapprove;
|
||||
|
||||
public static final CastleManorManager getInstance()
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
_log.info("Initializing CastleManorManager");
|
||||
_instance = new CastleManorManager();
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
|
||||
public class CropProcure
|
||||
{
|
||||
int _cropId;
|
||||
int _buyResidual;
|
||||
int _rewardType;
|
||||
int _buy;
|
||||
int _price;
|
||||
|
||||
public CropProcure(int id)
|
||||
{
|
||||
_cropId = id;
|
||||
_buyResidual = 0;
|
||||
_rewardType = 0;
|
||||
_buy = 0;
|
||||
_price = 0;
|
||||
}
|
||||
|
||||
public CropProcure(int id, int amount, int type, int buy, int price)
|
||||
{
|
||||
_cropId = id;
|
||||
_buyResidual = amount;
|
||||
_rewardType = type;
|
||||
_buy = buy;
|
||||
_price = price;
|
||||
}
|
||||
|
||||
public int getReward()
|
||||
{
|
||||
return _rewardType;
|
||||
}
|
||||
|
||||
public int getId()
|
||||
{
|
||||
return _cropId;
|
||||
}
|
||||
|
||||
public int getAmount()
|
||||
{
|
||||
return _buyResidual;
|
||||
}
|
||||
|
||||
public int getStartAmount()
|
||||
{
|
||||
return _buy;
|
||||
}
|
||||
|
||||
public int getPrice()
|
||||
{
|
||||
return _price;
|
||||
}
|
||||
|
||||
public void setAmount(int amount)
|
||||
{
|
||||
_buyResidual = amount;
|
||||
}
|
||||
}
|
||||
|
||||
public class SeedProduction
|
||||
{
|
||||
int _seedId;
|
||||
int _residual;
|
||||
int _price;
|
||||
int _sales;
|
||||
|
||||
public SeedProduction(int id)
|
||||
{
|
||||
_seedId = id;
|
||||
_sales = 0;
|
||||
_price = 0;
|
||||
_sales = 0;
|
||||
}
|
||||
|
||||
public SeedProduction(int id, int amount, int price, int sales)
|
||||
{
|
||||
_seedId = id;
|
||||
_residual = amount;
|
||||
_price = price;
|
||||
_sales = sales;
|
||||
}
|
||||
|
||||
public int getId()
|
||||
{
|
||||
return _seedId;
|
||||
}
|
||||
|
||||
public int getCanProduce()
|
||||
{
|
||||
return _residual;
|
||||
}
|
||||
|
||||
public int getPrice()
|
||||
{
|
||||
return _price;
|
||||
}
|
||||
|
||||
public int getStartProduce()
|
||||
{
|
||||
return _sales;
|
||||
}
|
||||
|
||||
public void setCanProduce(int amount)
|
||||
{
|
||||
_residual = amount;
|
||||
}
|
||||
}
|
||||
|
||||
private CastleManorManager()
|
||||
{
|
||||
load(); // load data from database
|
||||
init(); // schedule all manor related events
|
||||
_underMaintenance = false;
|
||||
_disabled = !Config.ALLOW_MANOR;
|
||||
|
||||
boolean isApproved;
|
||||
if (_periodApprove.getTimeInMillis() > _manorRefresh.getTimeInMillis())
|
||||
{
|
||||
// Next approve period already scheduled
|
||||
isApproved = (_manorRefresh.getTimeInMillis() > Calendar.getInstance().getTimeInMillis());
|
||||
}
|
||||
else
|
||||
{
|
||||
isApproved = ((_periodApprove.getTimeInMillis() < Calendar.getInstance().getTimeInMillis()) && (_manorRefresh.getTimeInMillis() > Calendar.getInstance().getTimeInMillis()));
|
||||
}
|
||||
|
||||
for (final Castle c : CastleManager.getInstance().getCastles())
|
||||
{
|
||||
c.setNextPeriodApproved(isApproved);
|
||||
}
|
||||
}
|
||||
|
||||
private void load()
|
||||
{
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection())
|
||||
{
|
||||
for (final Castle castle : CastleManager.getInstance().getCastles())
|
||||
{
|
||||
final FastList<SeedProduction> production = new FastList<>();
|
||||
final FastList<SeedProduction> productionNext = new FastList<>();
|
||||
final FastList<CropProcure> procure = new FastList<>();
|
||||
final FastList<CropProcure> procureNext = new FastList<>();
|
||||
|
||||
// restore seed production info
|
||||
try (PreparedStatement statement = con.prepareStatement(CASTLE_MANOR_LOAD_PRODUCTION))
|
||||
{
|
||||
statement.setInt(1, castle.getCastleId());
|
||||
try (ResultSet rs = statement.executeQuery())
|
||||
{
|
||||
while (rs.next())
|
||||
{
|
||||
final int seedId = rs.getInt("seed_id");
|
||||
final int canProduce = rs.getInt("can_produce");
|
||||
final int startProduce = rs.getInt("start_produce");
|
||||
final int price = rs.getInt("seed_price");
|
||||
final int period = rs.getInt("period");
|
||||
if (period == PERIOD_CURRENT)
|
||||
{
|
||||
production.add(new SeedProduction(seedId, canProduce, price, startProduce));
|
||||
}
|
||||
else
|
||||
{
|
||||
productionNext.add(new SeedProduction(seedId, canProduce, price, startProduce));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
castle.setSeedProduction(production, PERIOD_CURRENT);
|
||||
castle.setSeedProduction(productionNext, PERIOD_NEXT);
|
||||
|
||||
// restore procure info
|
||||
try (PreparedStatement statement = con.prepareStatement(CASTLE_MANOR_LOAD_PROCURE))
|
||||
{
|
||||
statement.setInt(1, castle.getCastleId());
|
||||
try (ResultSet rs = statement.executeQuery())
|
||||
{
|
||||
while (rs.next())
|
||||
{
|
||||
final int cropId = rs.getInt("crop_id");
|
||||
final int canBuy = rs.getInt("can_buy");
|
||||
final int startBuy = rs.getInt("start_buy");
|
||||
final int rewardType = rs.getInt("reward_type");
|
||||
final int price = rs.getInt("price");
|
||||
final int period = rs.getInt("period");
|
||||
if (period == PERIOD_CURRENT)
|
||||
{
|
||||
procure.add(new CropProcure(cropId, canBuy, rewardType, startBuy, price));
|
||||
}
|
||||
else
|
||||
{
|
||||
procureNext.add(new CropProcure(cropId, canBuy, rewardType, startBuy, price));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
castle.setCropProcure(procure, PERIOD_CURRENT);
|
||||
castle.setCropProcure(procureNext, PERIOD_NEXT);
|
||||
|
||||
if (!procure.isEmpty() || !procureNext.isEmpty() || !production.isEmpty() || !productionNext.isEmpty())
|
||||
{
|
||||
_log.info(castle.getName() + ": Data loaded");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (final Exception e)
|
||||
{
|
||||
_log.info("Error restoring manor data: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
protected void init()
|
||||
{
|
||||
_manorRefresh = Calendar.getInstance();
|
||||
_manorRefresh.set(Calendar.HOUR_OF_DAY, MANOR_REFRESH);
|
||||
_manorRefresh.set(Calendar.MINUTE, MANOR_REFRESH_MIN);
|
||||
|
||||
_periodApprove = Calendar.getInstance();
|
||||
_periodApprove.set(Calendar.HOUR_OF_DAY, NEXT_PERIOD_APPROVE);
|
||||
_periodApprove.set(Calendar.MINUTE, NEXT_PERIOD_APPROVE_MIN);
|
||||
|
||||
updateManorRefresh();
|
||||
updatePeriodApprove();
|
||||
}
|
||||
|
||||
public void updateManorRefresh()
|
||||
{
|
||||
_log.info("Manor System: Manor refresh updated");
|
||||
_scheduledManorRefresh = ThreadPoolManager.getInstance().scheduleGeneral(() ->
|
||||
{
|
||||
if (!isDisabled())
|
||||
{
|
||||
setUnderMaintenance(true);
|
||||
_log.info("Manor System: Under maintenance mode started");
|
||||
|
||||
_scheduledMaintenanceEnd = ThreadPoolManager.getInstance().scheduleGeneral(() ->
|
||||
{
|
||||
_log.info("Manor System: Next period started");
|
||||
setNextPeriod();
|
||||
try
|
||||
{
|
||||
save();
|
||||
}
|
||||
catch (final Exception e)
|
||||
{
|
||||
_log.info("Manor System: Failed to save manor data: " + e);
|
||||
}
|
||||
setUnderMaintenance(false);
|
||||
}, MAINTENANCE_PERIOD);
|
||||
}
|
||||
updateManorRefresh();
|
||||
}, getMillisToManorRefresh());
|
||||
}
|
||||
|
||||
public void updatePeriodApprove()
|
||||
{
|
||||
_log.info("Manor System: Manor period approve updated");
|
||||
_scheduledNextPeriodapprove = ThreadPoolManager.getInstance().scheduleGeneral(() ->
|
||||
{
|
||||
if (!isDisabled())
|
||||
{
|
||||
approveNextPeriod();
|
||||
_log.info("Manor System: Next period approved");
|
||||
}
|
||||
updatePeriodApprove();
|
||||
}, getMillisToNextPeriodApprove());
|
||||
}
|
||||
|
||||
public long getMillisToManorRefresh()
|
||||
{
|
||||
// use safe interval 120s to prevent double run
|
||||
if ((_manorRefresh.getTimeInMillis() - Calendar.getInstance().getTimeInMillis()) < 120000)
|
||||
{
|
||||
setNewManorRefresh();
|
||||
}
|
||||
|
||||
_log.info("Manor System: New Schedule for manor refresh @ " + _manorRefresh.getTime());
|
||||
|
||||
return (_manorRefresh.getTimeInMillis() - Calendar.getInstance().getTimeInMillis());
|
||||
}
|
||||
|
||||
public void setNewManorRefresh()
|
||||
{
|
||||
_manorRefresh = Calendar.getInstance();
|
||||
_manorRefresh.set(Calendar.HOUR_OF_DAY, MANOR_REFRESH);
|
||||
_manorRefresh.set(Calendar.MINUTE, MANOR_REFRESH_MIN);
|
||||
_manorRefresh.set(Calendar.SECOND, 0);
|
||||
_manorRefresh.add(Calendar.HOUR_OF_DAY, 24);
|
||||
}
|
||||
|
||||
public long getMillisToNextPeriodApprove()
|
||||
{
|
||||
// use safe interval 120s to prevent double run
|
||||
if ((_periodApprove.getTimeInMillis() - Calendar.getInstance().getTimeInMillis()) < 120000)
|
||||
{
|
||||
setNewPeriodApprove();
|
||||
}
|
||||
|
||||
_log.info("Manor System: New Schedule for period approve @ " + _periodApprove.getTime());
|
||||
|
||||
return (_periodApprove.getTimeInMillis() - Calendar.getInstance().getTimeInMillis());
|
||||
}
|
||||
|
||||
public void setNewPeriodApprove()
|
||||
{
|
||||
_periodApprove = Calendar.getInstance();
|
||||
_periodApprove.set(Calendar.HOUR_OF_DAY, NEXT_PERIOD_APPROVE);
|
||||
_periodApprove.set(Calendar.MINUTE, NEXT_PERIOD_APPROVE_MIN);
|
||||
_periodApprove.set(Calendar.SECOND, 0);
|
||||
_periodApprove.add(Calendar.HOUR_OF_DAY, 24);
|
||||
}
|
||||
|
||||
public void setNextPeriod()
|
||||
{
|
||||
for (final Castle c : CastleManager.getInstance().getCastles())
|
||||
{
|
||||
if (c.getOwnerId() <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final L2Clan clan = ClanTable.getInstance().getClan(c.getOwnerId());
|
||||
if (clan == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final ItemContainer cwh = clan.getWarehouse();
|
||||
if (!(cwh instanceof ClanWarehouse))
|
||||
{
|
||||
_log.info("Can't get clan warehouse for clan " + ClanTable.getInstance().getClan(c.getOwnerId()));
|
||||
return;
|
||||
}
|
||||
|
||||
for (final CropProcure crop : c.getCropProcure(PERIOD_CURRENT))
|
||||
{
|
||||
if (crop.getStartAmount() == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// adding bought crops to clan warehouse
|
||||
if ((crop.getStartAmount() - crop.getAmount()) > 0)
|
||||
{
|
||||
int count = crop.getStartAmount() - crop.getAmount();
|
||||
count = (count * 90) / 100;
|
||||
if (count < 1)
|
||||
{
|
||||
if (Rnd.nextInt(99) < 90)
|
||||
{
|
||||
count = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
cwh.addItem("Manor", L2Manor.getInstance().getMatureCrop(crop.getId()), count, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
// reserved and not used money giving back to treasury
|
||||
if (crop.getAmount() > 0)
|
||||
{
|
||||
c.addToTreasuryNoTax(crop.getAmount() * crop.getPrice());
|
||||
}
|
||||
}
|
||||
|
||||
c.setSeedProduction(c.getSeedProduction(PERIOD_NEXT), PERIOD_CURRENT);
|
||||
c.setCropProcure(c.getCropProcure(PERIOD_NEXT), PERIOD_CURRENT);
|
||||
|
||||
if (c.getTreasury() < c.getManorCost(PERIOD_CURRENT))
|
||||
{
|
||||
c.setSeedProduction(getNewSeedsList(c.getCastleId()), PERIOD_NEXT);
|
||||
c.setCropProcure(getNewCropsList(c.getCastleId()), PERIOD_NEXT);
|
||||
}
|
||||
else
|
||||
{
|
||||
final FastList<SeedProduction> production = new FastList<>();
|
||||
for (final SeedProduction s : c.getSeedProduction(PERIOD_CURRENT))
|
||||
{
|
||||
s.setCanProduce(s.getStartProduce());
|
||||
production.add(s);
|
||||
}
|
||||
c.setSeedProduction(production, PERIOD_NEXT);
|
||||
|
||||
final FastList<CropProcure> procure = new FastList<>();
|
||||
for (final CropProcure cr : c.getCropProcure(PERIOD_CURRENT))
|
||||
{
|
||||
cr.setAmount(cr.getStartAmount());
|
||||
procure.add(cr);
|
||||
}
|
||||
|
||||
c.setCropProcure(procure, PERIOD_NEXT);
|
||||
}
|
||||
|
||||
if (Config.ALT_MANOR_SAVE_ALL_ACTIONS)
|
||||
{
|
||||
c.saveCropData();
|
||||
c.saveSeedData();
|
||||
}
|
||||
|
||||
// Sending notification to a clan leader
|
||||
L2PcInstance clanLeader = L2World.getInstance().getPlayer(clan.getLeader().getName());
|
||||
if (clanLeader != null)
|
||||
{
|
||||
clanLeader.sendPacket(new SystemMessage(SystemMessage.THE_MANOR_INFORMATION_HAS_BEEN_UPDATED));
|
||||
}
|
||||
|
||||
c.setNextPeriodApproved(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void approveNextPeriod()
|
||||
{
|
||||
for (final Castle c : CastleManager.getInstance().getCastles())
|
||||
{
|
||||
boolean notFunc = false;
|
||||
|
||||
// Castle has no owner
|
||||
if (c.getOwnerId() <= 0)
|
||||
{
|
||||
c.setCropProcure(new FastList<CropProcure>(), PERIOD_NEXT);
|
||||
c.setSeedProduction(new FastList<SeedProduction>(), PERIOD_NEXT);
|
||||
}
|
||||
else if (c.getTreasury() < c.getManorCost(PERIOD_NEXT))
|
||||
{
|
||||
notFunc = true;
|
||||
c.setSeedProduction(getNewSeedsList(c.getCastleId()), PERIOD_NEXT);
|
||||
c.setCropProcure(getNewCropsList(c.getCastleId()), PERIOD_NEXT);
|
||||
}
|
||||
else
|
||||
{
|
||||
final ItemContainer cwh = ClanTable.getInstance().getClan(c.getOwnerId()).getWarehouse();
|
||||
if (!(cwh instanceof ClanWarehouse))
|
||||
{
|
||||
_log.info("Can't get clan warehouse for clan " + ClanTable.getInstance().getClan(c.getOwnerId()));
|
||||
return;
|
||||
}
|
||||
|
||||
int slots = 0;
|
||||
for (final CropProcure crop : c.getCropProcure(PERIOD_NEXT))
|
||||
{
|
||||
if (crop.getStartAmount() > 0)
|
||||
{
|
||||
if (cwh.getItemByItemId(L2Manor.getInstance().getMatureCrop(crop.getId())) == null)
|
||||
{
|
||||
slots++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!cwh.validateCapacity(slots))
|
||||
{
|
||||
notFunc = true;
|
||||
c.setSeedProduction(getNewSeedsList(c.getCastleId()), PERIOD_NEXT);
|
||||
c.setCropProcure(getNewCropsList(c.getCastleId()), PERIOD_NEXT);
|
||||
}
|
||||
}
|
||||
|
||||
c.setNextPeriodApproved(true);
|
||||
c.addToTreasuryNoTax((-1) * c.getManorCost(PERIOD_NEXT));
|
||||
|
||||
if (notFunc)
|
||||
{
|
||||
final L2Clan clan = ClanTable.getInstance().getClan(c.getOwnerId());
|
||||
L2PcInstance clanLeader = null;
|
||||
if (clan != null)
|
||||
{
|
||||
clanLeader = L2World.getInstance().getPlayer(clan.getLeader().getName());
|
||||
}
|
||||
if (clanLeader != null)
|
||||
{
|
||||
clanLeader.sendPacket(new SystemMessage(SystemMessage.THE_AMOUNT_IS_NOT_SUFFICIENT_AND_SO_THE_MANOR_IS_NOT_IN_OPERATION));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private FastList<SeedProduction> getNewSeedsList(int castleId)
|
||||
{
|
||||
final FastList<SeedProduction> seeds = new FastList<>();
|
||||
final FastList<Integer> seedsIds = L2Manor.getInstance().getSeedsForCastle(castleId);
|
||||
for (final int sd : seedsIds)
|
||||
{
|
||||
seeds.add(new SeedProduction(sd));
|
||||
}
|
||||
|
||||
return seeds;
|
||||
}
|
||||
|
||||
private FastList<CropProcure> getNewCropsList(int castleId)
|
||||
{
|
||||
final FastList<CropProcure> crops = new FastList<>();
|
||||
final FastList<Integer> cropsIds = L2Manor.getInstance().getCropsForCastle(castleId);
|
||||
for (final int cr : cropsIds)
|
||||
{
|
||||
crops.add(new CropProcure(cr));
|
||||
}
|
||||
|
||||
return crops;
|
||||
}
|
||||
|
||||
public boolean isUnderMaintenance()
|
||||
{
|
||||
return _underMaintenance;
|
||||
}
|
||||
|
||||
public void setUnderMaintenance(boolean mode)
|
||||
{
|
||||
_underMaintenance = mode;
|
||||
}
|
||||
|
||||
public boolean isDisabled()
|
||||
{
|
||||
return _disabled;
|
||||
}
|
||||
|
||||
public void setDisabled(boolean mode)
|
||||
{
|
||||
_disabled = mode;
|
||||
}
|
||||
|
||||
public SeedProduction getNewSeedProduction(int id, int amount, int price, int sales)
|
||||
{
|
||||
return new SeedProduction(id, amount, price, sales);
|
||||
}
|
||||
|
||||
public CropProcure getNewCropProcure(int id, int amount, int type, int price, int buy)
|
||||
{
|
||||
return new CropProcure(id, amount, type, buy, price);
|
||||
}
|
||||
|
||||
public void save()
|
||||
{
|
||||
for (final Castle c : CastleManager.getInstance().getCastles())
|
||||
{
|
||||
c.saveSeedData();
|
||||
c.saveCropData();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* 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 com.l2jmobius.gameserver.instancemanager;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.List;
|
||||
|
||||
import com.l2jmobius.L2DatabaseFactory;
|
||||
import com.l2jmobius.gameserver.datatables.ClanTable;
|
||||
import com.l2jmobius.gameserver.model.L2Clan;
|
||||
import com.l2jmobius.gameserver.model.entity.ClanHall;
|
||||
|
||||
import javolution.util.FastList;
|
||||
|
||||
public class ClanHallManager
|
||||
{
|
||||
|
||||
// =========================================================
|
||||
private static ClanHallManager _Instance;
|
||||
|
||||
public static final ClanHallManager getInstance()
|
||||
{
|
||||
if (_Instance == null)
|
||||
{
|
||||
System.out.println("Initializing ClanHallManager");
|
||||
_Instance = new ClanHallManager();
|
||||
|
||||
}
|
||||
return _Instance;
|
||||
}
|
||||
// =========================================================
|
||||
|
||||
// =========================================================
|
||||
// Data Field
|
||||
private List<ClanHall> _ClanHalls;
|
||||
|
||||
// =========================================================
|
||||
// Constructor
|
||||
public ClanHallManager()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Method - Private
|
||||
private final void load()
|
||||
{
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("SELECT * FROM clanhall ORDER BY id");
|
||||
ResultSet rs = statement.executeQuery())
|
||||
{
|
||||
while (rs.next())
|
||||
{
|
||||
if (rs.getInt("ownerId") != 0)
|
||||
{
|
||||
// just in case clan is deleted manually from db
|
||||
if (ClanTable.getInstance().getClan(rs.getInt("ownerId")) == null)
|
||||
{
|
||||
AuctionManager.initNPC(rs.getInt("id"));
|
||||
}
|
||||
}
|
||||
getClanHalls().add(new ClanHall(rs.getInt("id"), rs.getString("name"), rs.getInt("ownerId"), rs.getInt("lease"), rs.getString("desc"), rs.getString("location"), rs.getLong("paidUntil"), rs.getInt("Grade"), rs.getBoolean("paid")));
|
||||
}
|
||||
|
||||
System.out.println("Loaded: " + getClanHalls().size() + " clan halls");
|
||||
}
|
||||
catch (final Exception e)
|
||||
{
|
||||
System.out.println("Exception: ClanHallManager.load(): " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Property - Public
|
||||
public final ClanHall getClanHallById(int clanHallId)
|
||||
{
|
||||
for (final ClanHall clanHall : getClanHalls())
|
||||
{
|
||||
if (clanHall.getId() == clanHallId)
|
||||
{
|
||||
return clanHall;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public final ClanHall getNearbyClanHall(int x, int y, int maxDist)
|
||||
{
|
||||
for (final ClanHall ch : getClanHalls())
|
||||
{
|
||||
if ((ch.getZone() != null) && (ch.getZone().getDistanceToZone(x, y) < maxDist))
|
||||
{
|
||||
return ch;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public final ClanHall getClanHallByOwner(L2Clan clan)
|
||||
{
|
||||
for (final ClanHall clanHall : getClanHalls())
|
||||
{
|
||||
if (clan.getClanId() == clanHall.getOwnerId())
|
||||
{
|
||||
return clanHall;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public final List<ClanHall> getClanHalls()
|
||||
{
|
||||
if (_ClanHalls == null)
|
||||
{
|
||||
_ClanHalls = new FastList<>();
|
||||
}
|
||||
return _ClanHalls;
|
||||
}
|
||||
}
|
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* 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 com.l2jmobius.gameserver.instancemanager;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.gameserver.GameTimeController;
|
||||
import com.l2jmobius.gameserver.model.L2Spawn;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2NpcInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2RaidBossInstance;
|
||||
|
||||
import javolution.util.FastMap;
|
||||
|
||||
/**
|
||||
* This class ...
|
||||
* @version $Revision: $ $Date: $
|
||||
* @author godson
|
||||
*/
|
||||
|
||||
public class DayNightSpawnManager
|
||||
{
|
||||
private static Logger _log = Logger.getLogger(DayNightSpawnManager.class.getName());
|
||||
|
||||
private static DayNightSpawnManager _instance;
|
||||
private static Map<L2Spawn, L2NpcInstance> _dayCreatures;
|
||||
private static Map<L2Spawn, L2NpcInstance> _nightCreatures;
|
||||
private static Map<L2Spawn, L2RaidBossInstance> _bosses;
|
||||
|
||||
// private static int _currentState; // 0 = Day, 1 = Night
|
||||
|
||||
public static DayNightSpawnManager getInstance()
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
_instance = new DayNightSpawnManager();
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
|
||||
private DayNightSpawnManager()
|
||||
{
|
||||
_dayCreatures = new FastMap<>();
|
||||
_nightCreatures = new FastMap<>();
|
||||
_bosses = new FastMap<>();
|
||||
|
||||
_log.info("DayNightSpawnManager: Day/Night handler initialized");
|
||||
}
|
||||
|
||||
public void addDayCreature(L2Spawn spawnDat)
|
||||
{
|
||||
if (_dayCreatures.containsKey(spawnDat))
|
||||
{
|
||||
_log.warning("DayNightSpawnManager: Spawn already added into day map");
|
||||
return;
|
||||
}
|
||||
_dayCreatures.put(spawnDat, null);
|
||||
}
|
||||
|
||||
public void addNightCreature(L2Spawn spawnDat)
|
||||
{
|
||||
if (_nightCreatures.containsKey(spawnDat))
|
||||
{
|
||||
_log.warning("DayNightSpawnManager: Spawn already added into night map");
|
||||
return;
|
||||
}
|
||||
_nightCreatures.put(spawnDat, null);
|
||||
}
|
||||
|
||||
public void spawnDayCreatures()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_nightCreatures.size() != 0)
|
||||
{
|
||||
int i = 0;
|
||||
for (final L2NpcInstance nightCreature : _nightCreatures.values())
|
||||
{
|
||||
if (nightCreature == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nightCreature.getSpawn() != null)
|
||||
{
|
||||
nightCreature.getSpawn().stopRespawn();
|
||||
}
|
||||
|
||||
nightCreature.deleteMe();
|
||||
i++;
|
||||
}
|
||||
|
||||
_log.info("DayNightSpawnManager: Deleted " + i + " night creatures");
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
|
||||
L2NpcInstance creature = null;
|
||||
for (final L2Spawn spawnDat : _dayCreatures.keySet())
|
||||
{
|
||||
|
||||
if (_dayCreatures.get(spawnDat) == null)
|
||||
{
|
||||
creature = spawnDat.doSpawn();
|
||||
if (creature == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
creature.setCurrentHp(creature.getMaxHp());
|
||||
creature.setCurrentMp(creature.getMaxMp());
|
||||
|
||||
_dayCreatures.remove(spawnDat);
|
||||
_dayCreatures.put(spawnDat, creature);
|
||||
|
||||
creature = _dayCreatures.get(spawnDat);
|
||||
creature.getSpawn().startRespawn();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
creature = _dayCreatures.get(spawnDat);
|
||||
if (creature == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
creature.getSpawn().startRespawn();
|
||||
creature.setCurrentHp(creature.getMaxHp());
|
||||
creature.setCurrentMp(creature.getMaxMp());
|
||||
creature.spawnMe();
|
||||
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
_log.info("DayNightSpawnManager: Spawning " + i + " day creatures");
|
||||
}
|
||||
catch (final Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void spawnNightCreatures()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_dayCreatures.size() != 0)
|
||||
{
|
||||
int i = 0;
|
||||
for (final L2NpcInstance dayCreature : _dayCreatures.values())
|
||||
{
|
||||
if (dayCreature == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dayCreature.getSpawn() != null)
|
||||
{
|
||||
dayCreature.getSpawn().stopRespawn();
|
||||
}
|
||||
|
||||
dayCreature.deleteMe();
|
||||
i++;
|
||||
}
|
||||
_log.info("DayNightSpawnManager: Deleted " + i + " day creatures");
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
|
||||
L2NpcInstance creature = null;
|
||||
for (final L2Spawn spawnDat : _nightCreatures.keySet())
|
||||
{
|
||||
|
||||
if (_nightCreatures.get(spawnDat) == null)
|
||||
{
|
||||
creature = spawnDat.doSpawn();
|
||||
if (creature == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
_nightCreatures.remove(spawnDat);
|
||||
_nightCreatures.put(spawnDat, creature);
|
||||
creature.setCurrentHp(creature.getMaxHp());
|
||||
creature.setCurrentMp(creature.getMaxMp());
|
||||
|
||||
creature = _nightCreatures.get(spawnDat);
|
||||
creature.getSpawn().startRespawn();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
creature = _nightCreatures.get(spawnDat);
|
||||
if (creature == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
creature.getSpawn().startRespawn();
|
||||
creature.setCurrentHp(creature.getMaxHp());
|
||||
creature.setCurrentMp(creature.getMaxMp());
|
||||
creature.spawnMe();
|
||||
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
_log.info("DayNightSpawnManager: Spawning " + i + " night creatures");
|
||||
}
|
||||
catch (final Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void changeMode(int mode)
|
||||
{
|
||||
if ((_nightCreatures.size() == 0) && (_dayCreatures.size() == 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case 0:
|
||||
spawnDayCreatures();
|
||||
specialNightBoss(0);
|
||||
break;
|
||||
case 1:
|
||||
spawnNightCreatures();
|
||||
specialNightBoss(1);
|
||||
break;
|
||||
default:
|
||||
_log.warning("DayNightSpawnManager: Wrong mode sent");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyChangeMode()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (GameTimeController.getInstance().isNowNight())
|
||||
{
|
||||
changeMode(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
changeMode(0);
|
||||
}
|
||||
}
|
||||
catch (final Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void cleanUp()
|
||||
{
|
||||
_nightCreatures.clear();
|
||||
_dayCreatures.clear();
|
||||
_bosses.clear();
|
||||
}
|
||||
|
||||
public void specialNightBoss(int mode)
|
||||
{
|
||||
try
|
||||
{
|
||||
for (final L2Spawn spawn : _bosses.keySet())
|
||||
{
|
||||
L2RaidBossInstance boss = _bosses.get(spawn);
|
||||
|
||||
if (boss == null)
|
||||
{
|
||||
if (mode == 1)
|
||||
{
|
||||
boss = (L2RaidBossInstance) spawn.doSpawn();
|
||||
RaidBossSpawnManager.getInstance().notifySpawnNightBoss(boss);
|
||||
_bosses.remove(spawn);
|
||||
_bosses.put(spawn, boss);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((boss.getNpcId() == 10328) && boss.getRaidStatus().equals(RaidBossSpawnManager.StatusEnum.ALIVE))
|
||||
{
|
||||
handleHellmans(boss, mode);
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
catch (final Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void handleHellmans(L2RaidBossInstance boss, int mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case 0:
|
||||
boss.deleteMe();
|
||||
_log.info("DayNightSpawnManager: Deleting Hellman raidboss");
|
||||
break;
|
||||
case 1:
|
||||
boss.spawnMe();
|
||||
_log.info("DayNightSpawnManager: Spawning Hellman raidboss");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public L2RaidBossInstance handleBoss(L2Spawn spawnDat)
|
||||
{
|
||||
if (_bosses.containsKey(spawnDat))
|
||||
{
|
||||
return _bosses.get(spawnDat);
|
||||
}
|
||||
|
||||
if (GameTimeController.getInstance().isNowNight())
|
||||
{
|
||||
final L2RaidBossInstance raidboss = (L2RaidBossInstance) spawnDat.doSpawn();
|
||||
_bosses.put(spawnDat, raidboss);
|
||||
return raidboss;
|
||||
}
|
||||
_bosses.put(spawnDat, null);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -0,0 +1,627 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* 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 com.l2jmobius.gameserver.instancemanager;
|
||||
|
||||
import java.awt.Polygon;
|
||||
import java.awt.Shape;
|
||||
import java.io.File;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.L2DatabaseFactory;
|
||||
import com.l2jmobius.gameserver.Olympiad;
|
||||
import com.l2jmobius.gameserver.datatables.NpcTable;
|
||||
import com.l2jmobius.gameserver.datatables.SpawnTable;
|
||||
import com.l2jmobius.gameserver.model.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.model.L2Spawn;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2NpcInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.entity.DimensionalRift;
|
||||
import com.l2jmobius.gameserver.model.entity.TvTEvent;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
import com.l2jmobius.gameserver.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.util.Util;
|
||||
import com.l2jmobius.util.Rnd;
|
||||
|
||||
import javolution.util.FastList;
|
||||
|
||||
/**
|
||||
* Thanks to L2Fortress and balancer.ru - kombat
|
||||
*/
|
||||
public class DimensionalRiftManager
|
||||
{
|
||||
private static Logger _log = Logger.getLogger(DimensionalRiftManager.class.getName());
|
||||
private static DimensionalRiftManager _instance;
|
||||
private final Map<Byte, Map<Byte, DimensionalRiftRoom>> _rooms = new HashMap<>(7);
|
||||
private final int DIMENSIONAL_FRAGMENT_ITEM_ID = 7079;
|
||||
|
||||
public static DimensionalRiftManager getInstance()
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
_instance = new DimensionalRiftManager();
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
|
||||
private DimensionalRiftManager()
|
||||
{
|
||||
loadRooms();
|
||||
loadSpawns();
|
||||
}
|
||||
|
||||
public DimensionalRiftRoom getRoom(byte type, byte room)
|
||||
{
|
||||
return _rooms.get(type) == null ? null : _rooms.get(type).get(room);
|
||||
}
|
||||
|
||||
private void loadRooms()
|
||||
{
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement s = con.prepareStatement("SELECT * FROM dimensional_rift");
|
||||
ResultSet rs = s.executeQuery())
|
||||
{
|
||||
while (rs.next())
|
||||
{
|
||||
// 0 waiting room, 1 recruit, 2 soldier, 3 officer, 4 captain , 5 commander, 6 hero
|
||||
final byte type = rs.getByte("type");
|
||||
final byte room_id = rs.getByte("room_id");
|
||||
|
||||
// coords related
|
||||
final int xMin = rs.getInt("xMin");
|
||||
final int xMax = rs.getInt("xMax");
|
||||
final int yMin = rs.getInt("yMin");
|
||||
final int yMax = rs.getInt("yMax");
|
||||
final int z1 = rs.getInt("zMin");
|
||||
final int z2 = rs.getInt("zMax");
|
||||
final int xT = rs.getInt("xT");
|
||||
final int yT = rs.getInt("yT");
|
||||
final int zT = rs.getInt("zT");
|
||||
final boolean isBossRoom = rs.getByte("boss") > 0;
|
||||
|
||||
if (!_rooms.containsKey(type))
|
||||
{
|
||||
_rooms.put(type, new HashMap<Byte, DimensionalRiftRoom>(9));
|
||||
}
|
||||
|
||||
_rooms.get(type).put(room_id, new DimensionalRiftRoom(type, room_id, xMin, xMax, yMin, yMax, z1, z2, xT, yT, zT, isBossRoom));
|
||||
}
|
||||
}
|
||||
catch (final Exception e)
|
||||
{
|
||||
_log.log(Level.WARNING, "Can't load Dimension Rift zones. " + e.getMessage(), e);
|
||||
}
|
||||
|
||||
final int typeSize = _rooms.keySet().size();
|
||||
int roomSize = 0;
|
||||
|
||||
for (final byte b : _rooms.keySet())
|
||||
{
|
||||
roomSize += _rooms.get(b).keySet().size();
|
||||
}
|
||||
|
||||
_log.info(getClass().getSimpleName() + ": Loaded " + typeSize + " room types with " + roomSize + " rooms.");
|
||||
}
|
||||
|
||||
public void loadSpawns()
|
||||
{
|
||||
int countGood = 0, countBad = 0;
|
||||
try
|
||||
{
|
||||
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setValidating(false);
|
||||
factory.setIgnoringComments(true);
|
||||
|
||||
final File file = new File(Config.DATAPACK_ROOT + "/data/dimensionalRift.xml");
|
||||
if (!file.exists())
|
||||
{
|
||||
_log.log(Level.WARNING, getClass().getSimpleName() + ": Couldn't find data/" + file.getName());
|
||||
return;
|
||||
}
|
||||
|
||||
final Document doc = factory.newDocumentBuilder().parse(file);
|
||||
NamedNodeMap attrs;
|
||||
byte type, roomId;
|
||||
int mobId, x, y, z, delay, count;
|
||||
L2Spawn spawnDat;
|
||||
L2NpcTemplate template;
|
||||
|
||||
for (Node rift = doc.getFirstChild(); rift != null; rift = rift.getNextSibling())
|
||||
{
|
||||
if ("rift".equalsIgnoreCase(rift.getNodeName()))
|
||||
{
|
||||
for (Node area = rift.getFirstChild(); area != null; area = area.getNextSibling())
|
||||
{
|
||||
if ("area".equalsIgnoreCase(area.getNodeName()))
|
||||
{
|
||||
attrs = area.getAttributes();
|
||||
type = Byte.parseByte(attrs.getNamedItem("type").getNodeValue());
|
||||
|
||||
for (Node room = area.getFirstChild(); room != null; room = room.getNextSibling())
|
||||
{
|
||||
if ("room".equalsIgnoreCase(room.getNodeName()))
|
||||
{
|
||||
attrs = room.getAttributes();
|
||||
roomId = Byte.parseByte(attrs.getNamedItem("id").getNodeValue());
|
||||
|
||||
for (Node spawn = room.getFirstChild(); spawn != null; spawn = spawn.getNextSibling())
|
||||
{
|
||||
if ("spawn".equalsIgnoreCase(spawn.getNodeName()))
|
||||
{
|
||||
attrs = spawn.getAttributes();
|
||||
mobId = Integer.parseInt(attrs.getNamedItem("mobId").getNodeValue());
|
||||
delay = Integer.parseInt(attrs.getNamedItem("delay").getNodeValue());
|
||||
count = Integer.parseInt(attrs.getNamedItem("count").getNodeValue());
|
||||
|
||||
template = NpcTable.getInstance().getTemplate(mobId);
|
||||
if (template == null)
|
||||
{
|
||||
_log.warning("Template " + mobId + " not found!");
|
||||
}
|
||||
|
||||
if (!_rooms.containsKey(type))
|
||||
{
|
||||
_log.warning("Type " + type + " not found!");
|
||||
}
|
||||
else if (!_rooms.get(type).containsKey(roomId))
|
||||
{
|
||||
_log.warning("Room " + roomId + " in Type " + type + " not found!");
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
final DimensionalRiftRoom riftRoom = _rooms.get(type).get(roomId);
|
||||
x = riftRoom.getRandomX();
|
||||
y = riftRoom.getRandomY();
|
||||
z = riftRoom.getTeleportCoords()[2];
|
||||
|
||||
if ((template != null) && _rooms.containsKey(type) && _rooms.get(type).containsKey(roomId))
|
||||
{
|
||||
spawnDat = new L2Spawn(template);
|
||||
spawnDat.setAmount(1);
|
||||
spawnDat.setLocx(x);
|
||||
spawnDat.setLocy(y);
|
||||
spawnDat.setLocz(z);
|
||||
spawnDat.setHeading(-1);
|
||||
spawnDat.setRespawnDelay(delay);
|
||||
|
||||
SpawnTable.getInstance().addNewSpawn(spawnDat, false);
|
||||
_rooms.get(type).get(roomId).getSpawns().add(spawnDat);
|
||||
countGood++;
|
||||
}
|
||||
else
|
||||
{
|
||||
countBad++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (final Exception e)
|
||||
{
|
||||
_log.log(Level.WARNING, "Error on loading dimensional rift spawns: " + e.getMessage(), e);
|
||||
}
|
||||
_log.info(getClass().getSimpleName() + ": Loaded " + countGood + " dimensional rift spawns, " + countBad + " errors.");
|
||||
}
|
||||
|
||||
public void reload()
|
||||
{
|
||||
for (final byte b : _rooms.keySet())
|
||||
{
|
||||
for (final byte i : _rooms.get(b).keySet())
|
||||
{
|
||||
_rooms.get(b).get(i).getSpawns().clear();
|
||||
}
|
||||
_rooms.get(b).clear();
|
||||
}
|
||||
_rooms.clear();
|
||||
loadRooms();
|
||||
loadSpawns();
|
||||
}
|
||||
|
||||
public boolean checkIfInRiftZone(int x, int y, int z, boolean ignorePeaceZone)
|
||||
{
|
||||
if (ignorePeaceZone)
|
||||
{
|
||||
return _rooms.get((byte) 0).get((byte) 1).checkIfInZone(x, y, z);
|
||||
}
|
||||
return _rooms.get((byte) 0).get((byte) 1).checkIfInZone(x, y, z) && !_rooms.get((byte) 0).get((byte) 0).checkIfInZone(x, y, z);
|
||||
}
|
||||
|
||||
public boolean checkIfInPeaceZone(int x, int y, int z)
|
||||
{
|
||||
return _rooms.get((byte) 0).get((byte) 0).checkIfInZone(x, y, z);
|
||||
}
|
||||
|
||||
public void teleportToWaitingRoom(L2PcInstance player)
|
||||
{
|
||||
final int[] coords = getRoom((byte) 0, (byte) 0).getTeleportCoords();
|
||||
|
||||
// just to avoid critical errors during restart
|
||||
if (player.isOnline() == 1)
|
||||
{
|
||||
player.teleToLocation(coords[0], coords[1], coords[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.setXYZInvisible(coords[0], coords[1], coords[2]);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void start(L2PcInstance player, byte type, L2NpcInstance npc)
|
||||
{
|
||||
boolean canPass = true;
|
||||
if (!player.isInParty())
|
||||
{
|
||||
showHtmlFile(player, "data/html/seven_signs/rift/NoParty.htm", npc);
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.getParty().getPartyLeaderOID() != player.getObjectId())
|
||||
{
|
||||
showHtmlFile(player, "data/html/seven_signs/rift/NotPartyLeader.htm", npc);
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.getParty().isInDimensionalRift())
|
||||
{
|
||||
handleCheat(player, npc);
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.getParty().getMemberCount() < Config.RIFT_MIN_PARTY_SIZE)
|
||||
{
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(npc.getObjectId());
|
||||
html.setFile("data/html/seven_signs/rift/SmallParty.htm");
|
||||
html.replace("%npc_name%", npc.getName());
|
||||
html.replace("%count%", Integer.toString(Config.RIFT_MIN_PARTY_SIZE));
|
||||
player.sendPacket(html);
|
||||
return;
|
||||
}
|
||||
|
||||
// max parties inside is rooms count - 1
|
||||
if (!isAllowedEnter(type))
|
||||
{
|
||||
player.sendMessage("Rift is full. Try later.");
|
||||
return;
|
||||
}
|
||||
|
||||
for (final L2PcInstance p : player.getParty().getPartyMembers())
|
||||
{
|
||||
if (!checkIfInPeaceZone(p.getX(), p.getY(), p.getZ()))
|
||||
{
|
||||
canPass = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!canPass)
|
||||
{
|
||||
showHtmlFile(player, "data/html/seven_signs/rift/NotInWaitingRoom.htm", npc);
|
||||
return;
|
||||
}
|
||||
|
||||
L2ItemInstance i;
|
||||
final int count = getNeededItems(type);
|
||||
for (final L2PcInstance p : player.getParty().getPartyMembers())
|
||||
{
|
||||
if (p.isFestivalParticipant())
|
||||
{
|
||||
player.sendMessage("Somebody among the party members has registered to participate in the Festival of Darkness.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Olympiad.getInstance().isRegisteredInComp(p))
|
||||
{
|
||||
player.sendMessage("Somebody among the party members has registered to participate in the Grand Olympiad games.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (TvTEvent.isRegistered(p))
|
||||
{
|
||||
player.sendMessage("Somebody among the party members has registered to participate in the TvT Event.");
|
||||
return;
|
||||
}
|
||||
|
||||
i = p.getInventory().getItemByItemId(DIMENSIONAL_FRAGMENT_ITEM_ID);
|
||||
if (i == null)
|
||||
{
|
||||
canPass = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (i.getCount() > 0)
|
||||
{
|
||||
if (i.getCount() < getNeededItems(type))
|
||||
{
|
||||
canPass = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
canPass = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!canPass)
|
||||
{
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(npc.getObjectId());
|
||||
html.setFile("data/html/seven_signs/rift/NoFragments.htm");
|
||||
html.replace("%npc_name%", npc.getName());
|
||||
html.replace("%count%", Integer.toString(count));
|
||||
player.sendPacket(html);
|
||||
return;
|
||||
}
|
||||
|
||||
for (final L2PcInstance p : player.getParty().getPartyMembers())
|
||||
{
|
||||
i = p.getInventory().getItemByItemId(DIMENSIONAL_FRAGMENT_ITEM_ID);
|
||||
if (!p.destroyItem("RiftEntrance", i, count, null, false))
|
||||
{
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(npc.getObjectId());
|
||||
html.setFile("data/html/seven_signs/rift/NoFragments.htm");
|
||||
html.replace("%npc_name%", npc.getName());
|
||||
html.replace("%count%", Integer.toString(count));
|
||||
player.sendPacket(html);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
byte room;
|
||||
FastList<Byte> emptyRooms;
|
||||
do
|
||||
{
|
||||
emptyRooms = getFreeRooms(type);
|
||||
room = emptyRooms.get(Rnd.get(1, emptyRooms.size()) - 1);
|
||||
}
|
||||
// find empty room
|
||||
while (_rooms.get(type).get(room).ispartyInside());
|
||||
new DimensionalRift(player.getParty(), type, room);
|
||||
}
|
||||
|
||||
public void killRift(DimensionalRift d)
|
||||
{
|
||||
if (d.getTeleportTimerTask() != null)
|
||||
{
|
||||
d.getTeleportTimerTask().cancel();
|
||||
d.setTeleportTimerTask(null);
|
||||
}
|
||||
|
||||
if (d.getTeleportTimer() != null)
|
||||
{
|
||||
d.getTeleportTimer().cancel();
|
||||
d.setTeleportTimer(null);
|
||||
}
|
||||
|
||||
if (d.getSpawnTimerTask() != null)
|
||||
{
|
||||
d.getSpawnTimerTask().cancel();
|
||||
d.setSpawnTimerTask(null);
|
||||
}
|
||||
|
||||
if (d.getSpawnTimer() != null)
|
||||
{
|
||||
d.getSpawnTimer().cancel();
|
||||
d.setSpawnTimer(null);
|
||||
}
|
||||
}
|
||||
|
||||
public class DimensionalRiftRoom
|
||||
{
|
||||
@SuppressWarnings("unused")
|
||||
private final byte _type;
|
||||
final byte _room;
|
||||
private final int _xMin;
|
||||
private final int _xMax;
|
||||
private final int _yMin;
|
||||
private final int _yMax;
|
||||
private final int _zMin;
|
||||
private final int _zMax;
|
||||
private final int[] _teleportCoords;
|
||||
private final Shape _s;
|
||||
private final boolean _isBossRoom;
|
||||
private final FastList<L2Spawn> _roomSpawns;
|
||||
@SuppressWarnings("unused")
|
||||
private final FastList<L2NpcInstance> _roomMobs;
|
||||
private boolean _partyInside = false;
|
||||
|
||||
public DimensionalRiftRoom(byte type, byte room, int xMin, int xMax, int yMin, int yMax, int zMin, int zMax, int xT, int yT, int zT, boolean isBossRoom)
|
||||
{
|
||||
_type = type;
|
||||
_room = room;
|
||||
_xMin = (xMin + 128);
|
||||
_xMax = (xMax - 128);
|
||||
_yMin = (yMin + 128);
|
||||
_yMax = (yMax - 128);
|
||||
_zMin = zMin;
|
||||
_zMax = zMax;
|
||||
_teleportCoords = new int[]
|
||||
{
|
||||
xT,
|
||||
yT,
|
||||
zT
|
||||
};
|
||||
_isBossRoom = isBossRoom;
|
||||
_roomSpawns = new FastList<>();
|
||||
_roomMobs = new FastList<>();
|
||||
_s = new Polygon(new int[]
|
||||
{
|
||||
xMin,
|
||||
xMax,
|
||||
xMax,
|
||||
xMin
|
||||
}, new int[]
|
||||
{
|
||||
yMin,
|
||||
yMin,
|
||||
yMax,
|
||||
yMax
|
||||
}, 4);
|
||||
}
|
||||
|
||||
public int getRandomX()
|
||||
{
|
||||
return Rnd.get(_xMin, _xMax);
|
||||
}
|
||||
|
||||
public int getRandomY()
|
||||
{
|
||||
return Rnd.get(_yMin, _yMax);
|
||||
}
|
||||
|
||||
public int[] getTeleportCoords()
|
||||
{
|
||||
return _teleportCoords;
|
||||
}
|
||||
|
||||
public boolean checkIfInZone(int x, int y, int z)
|
||||
{
|
||||
return _s.contains(x, y) && (z >= _zMin) && (z <= _zMax);
|
||||
}
|
||||
|
||||
public boolean isBossRoom()
|
||||
{
|
||||
return _isBossRoom;
|
||||
}
|
||||
|
||||
public FastList<L2Spawn> getSpawns()
|
||||
{
|
||||
return _roomSpawns;
|
||||
}
|
||||
|
||||
public void spawn()
|
||||
{
|
||||
for (final L2Spawn spawn : _roomSpawns)
|
||||
{
|
||||
spawn.doSpawn();
|
||||
spawn.startRespawn();
|
||||
}
|
||||
}
|
||||
|
||||
public DimensionalRiftRoom unspawn()
|
||||
{
|
||||
for (final L2Spawn spawn : _roomSpawns)
|
||||
{
|
||||
spawn.stopRespawn();
|
||||
if (spawn.getLastSpawn() != null)
|
||||
{
|
||||
spawn.getLastSpawn().deleteMe();
|
||||
}
|
||||
spawn.decreaseCount(null);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the _partyInside
|
||||
*/
|
||||
public boolean ispartyInside()
|
||||
{
|
||||
return _partyInside;
|
||||
}
|
||||
|
||||
public void setpartyInside(boolean partyInside)
|
||||
{
|
||||
_partyInside = partyInside;
|
||||
}
|
||||
}
|
||||
|
||||
private int getNeededItems(byte type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case 1:
|
||||
return Config.RIFT_ENTER_COST_RECRUIT;
|
||||
case 2:
|
||||
return Config.RIFT_ENTER_COST_SOLDIER;
|
||||
case 3:
|
||||
return Config.RIFT_ENTER_COST_OFFICER;
|
||||
case 4:
|
||||
return Config.RIFT_ENTER_COST_CAPTAIN;
|
||||
case 5:
|
||||
return Config.RIFT_ENTER_COST_COMMANDER;
|
||||
case 6:
|
||||
return Config.RIFT_ENTER_COST_HERO;
|
||||
default:
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
}
|
||||
|
||||
public void showHtmlFile(L2PcInstance player, String file, L2NpcInstance npc)
|
||||
{
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(npc.getObjectId());
|
||||
html.setFile(file);
|
||||
html.replace("%npc_name%", npc.getName());
|
||||
player.sendPacket(html);
|
||||
}
|
||||
|
||||
public void handleCheat(L2PcInstance player, L2NpcInstance npc)
|
||||
{
|
||||
showHtmlFile(player, "data/html/seven_signs/rift/Cheater.htm", npc);
|
||||
if (!player.isGM())
|
||||
{
|
||||
_log.warning("Player " + player.getName() + "(" + player.getObjectId() + ") was cheating in dimension rift area!");
|
||||
Util.handleIllegalPlayerAction(player, "Warning!! Character " + player.getName() + " tried to cheat in dimensional rift.", Config.DEFAULT_PUNISH);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isAllowedEnter(byte type)
|
||||
{
|
||||
int count = 0;
|
||||
for (final Object room : _rooms.get(type).values())
|
||||
{
|
||||
if (((DimensionalRiftRoom) room).ispartyInside())
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return (count < (_rooms.get(type).size() - 1));
|
||||
}
|
||||
|
||||
public FastList<Byte> getFreeRooms(byte type)
|
||||
{
|
||||
final FastList<Byte> list = new FastList<>();
|
||||
for (final Object room : _rooms.get(type).values())
|
||||
{
|
||||
if (!((DimensionalRiftRoom) room).ispartyInside())
|
||||
{
|
||||
list.add(((DimensionalRiftRoom) room)._room);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,368 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* 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 com.l2jmobius.gameserver.instancemanager;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.L2DatabaseFactory;
|
||||
import com.l2jmobius.gameserver.model.L2Character;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2GrandBossInstance;
|
||||
import com.l2jmobius.gameserver.model.zone.type.L2BossZone;
|
||||
import com.l2jmobius.gameserver.templates.StatsSet;
|
||||
|
||||
import javolution.util.FastList;
|
||||
import javolution.util.FastMap;
|
||||
|
||||
/**
|
||||
* @author DaRkRaGe Revised by Emperorc
|
||||
*/
|
||||
public class GrandBossManager
|
||||
{
|
||||
/*
|
||||
* ========================================================= This class handles all Grand Bosses: <ul> <li>12001 Queen Ant</li> <li>12052 Core</li> <li>12169 Orfen</li> <li>12211 Antharas</li> <li>12372 Baium</li> <li>12374 Zaken</li> <li>12899 Valakas</li> </ul> It handles the saving of hp, mp,
|
||||
* location, and status of all Grand Bosses. It also manages the zones associated with the Grand Bosses. NOTE: The current version does NOT spawn the Grand Bosses, it just stores and retrieves the values on reboot/startup, for AI scripts to utilize as needed.
|
||||
*/
|
||||
|
||||
public static Logger _log = Logger.getLogger(GrandBossManager.class.getName());
|
||||
|
||||
private static GrandBossManager _instance;
|
||||
protected static Map<Integer, L2GrandBossInstance> _bosses;
|
||||
protected static Map<Integer, StatsSet> _storedInfo;
|
||||
private Map<Integer, Integer> _bossStatus;
|
||||
|
||||
private FastList<L2BossZone> _zones;
|
||||
|
||||
public static GrandBossManager getInstance()
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
_log.info("Initializing GrandBossManager");
|
||||
_instance = new GrandBossManager();
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
|
||||
public GrandBossManager()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
_zones = new FastList<>();
|
||||
|
||||
_bosses = new FastMap<>();
|
||||
_storedInfo = new FastMap<>();
|
||||
_bossStatus = new FastMap<>();
|
||||
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("SELECT * from grandboss_data ORDER BY boss_id");
|
||||
ResultSet rset = statement.executeQuery())
|
||||
{
|
||||
while (rset.next())
|
||||
{
|
||||
// Read all info from DB, and store it for AI to read and decide what to do
|
||||
// faster than accessing DB in real time
|
||||
StatsSet info = new StatsSet();
|
||||
final int bossId = rset.getInt("boss_id");
|
||||
info.set("loc_x", rset.getInt("loc_x"));
|
||||
info.set("loc_y", rset.getInt("loc_y"));
|
||||
info.set("loc_z", rset.getInt("loc_z"));
|
||||
info.set("heading", rset.getInt("heading"));
|
||||
info.set("respawn_time", rset.getLong("respawn_time"));
|
||||
final double HP = rset.getDouble("currentHP"); // jython doesn't recognize doubles
|
||||
final int true_HP = (int) HP; // so use java's ability to type cast
|
||||
info.set("currentHP", true_HP); // to convert double to int
|
||||
final double MP = rset.getDouble("currentMP");
|
||||
final int true_MP = (int) MP;
|
||||
info.set("currentMP", true_MP);
|
||||
_bossStatus.put(bossId, rset.getInt("status"));
|
||||
|
||||
_storedInfo.put(bossId, info);
|
||||
info = null;
|
||||
}
|
||||
|
||||
_log.info("GrandBossManager: Loaded " + _storedInfo.size() + " Instance(s)");
|
||||
}
|
||||
catch (final SQLException e)
|
||||
{
|
||||
_log.warning("GrandBossManager: Could not load grandboss_data table");
|
||||
}
|
||||
catch (final Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Zone Functions
|
||||
*/
|
||||
|
||||
public void initZones()
|
||||
{
|
||||
final FastMap<Integer, L2BossZone> zones = new FastMap<>();
|
||||
|
||||
if (_zones == null)
|
||||
{
|
||||
_log.warning("GrandBossManager: Could not read Grand Boss zone data");
|
||||
return;
|
||||
}
|
||||
|
||||
for (final L2BossZone zone : _zones)
|
||||
{
|
||||
if (zone == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
zones.put(zone.getId(), zone);
|
||||
}
|
||||
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("SELECT * from grandboss_list ORDER BY player_id");
|
||||
ResultSet rset = statement.executeQuery())
|
||||
{
|
||||
while (rset.next())
|
||||
{
|
||||
final int id = rset.getInt("player_id");
|
||||
final int zone_id = rset.getInt("zone");
|
||||
|
||||
final L2BossZone zone = zones.get(zone_id);
|
||||
if (zone != null)
|
||||
{
|
||||
zone.allowPlayerEntry(id, zone.getTimeInvade());
|
||||
}
|
||||
}
|
||||
|
||||
_log.info("GrandBossManager: Initialized " + _zones.size() + " Grand Boss Zone(s)");
|
||||
}
|
||||
catch (final SQLException e)
|
||||
{
|
||||
_log.warning("GrandBossManager: Could not load grandboss_list table");
|
||||
}
|
||||
catch (final Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
zones.clear();
|
||||
}
|
||||
|
||||
public void addZone(L2BossZone zone)
|
||||
{
|
||||
if (_zones != null)
|
||||
{
|
||||
_zones.add(zone);
|
||||
}
|
||||
}
|
||||
|
||||
public final L2BossZone getZone(L2Character character)
|
||||
{
|
||||
if (_zones != null)
|
||||
{
|
||||
for (final L2BossZone temp : _zones)
|
||||
{
|
||||
if (temp.isCharacterInZone(character))
|
||||
{
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public final L2BossZone getZone(int x, int y, int z)
|
||||
{
|
||||
if (_zones != null)
|
||||
{
|
||||
for (final L2BossZone temp : _zones)
|
||||
{
|
||||
if (temp.isInsideZone(x, y, z))
|
||||
{
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean checkIfInZone(String zoneType, L2Object obj)
|
||||
{
|
||||
final L2BossZone temp = getZone(obj.getX(), obj.getY(), obj.getZ());
|
||||
if (temp == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return temp.getZoneName().equalsIgnoreCase(zoneType);
|
||||
}
|
||||
|
||||
/*
|
||||
* The rest
|
||||
*/
|
||||
|
||||
public int getBossStatus(int bossId)
|
||||
{
|
||||
return _bossStatus.get(bossId);
|
||||
}
|
||||
|
||||
public void setBossStatus(int bossId, int status)
|
||||
{
|
||||
_bossStatus.remove(bossId);
|
||||
_bossStatus.put(bossId, status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds a L2GrandBossInstance to the list of bosses.
|
||||
*/
|
||||
public void addBoss(L2GrandBossInstance boss)
|
||||
{
|
||||
if (boss != null)
|
||||
{
|
||||
if (_bosses.containsKey(boss.getNpcId()))
|
||||
{
|
||||
_bosses.remove(boss.getNpcId());
|
||||
}
|
||||
_bosses.put(boss.getNpcId(), boss);
|
||||
}
|
||||
}
|
||||
|
||||
public L2GrandBossInstance getBoss(int bossId)
|
||||
{
|
||||
return _bosses.get(bossId);
|
||||
}
|
||||
|
||||
public StatsSet getStatsSet(int bossId)
|
||||
{
|
||||
return _storedInfo.get(bossId);
|
||||
}
|
||||
|
||||
public void setStatsSet(int bossId, StatsSet info)
|
||||
{
|
||||
if (_storedInfo.containsKey(bossId))
|
||||
{
|
||||
_storedInfo.remove(bossId);
|
||||
}
|
||||
_storedInfo.put(bossId, info);
|
||||
storeToDb();
|
||||
}
|
||||
|
||||
private void storeToDb()
|
||||
{
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection())
|
||||
{
|
||||
try (PreparedStatement statement = con.prepareStatement("DELETE FROM grandboss_list"))
|
||||
{
|
||||
statement.executeUpdate();
|
||||
}
|
||||
|
||||
for (final L2BossZone zone : _zones)
|
||||
{
|
||||
if (zone == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final Integer id = zone.getId();
|
||||
final FastList<Integer> list = zone.getAllowedPlayers();
|
||||
if (list == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (list.isEmpty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (final Integer player : list)
|
||||
{
|
||||
try (PreparedStatement statement = con.prepareStatement("INSERT INTO grandboss_list (player_id,zone) VALUES (?,?)"))
|
||||
{
|
||||
statement.setInt(1, player);
|
||||
statement.setInt(2, id);
|
||||
statement.executeUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (final Integer bossId : _storedInfo.keySet())
|
||||
{
|
||||
final L2GrandBossInstance boss = _bosses.get(bossId);
|
||||
final StatsSet info = _storedInfo.get(bossId);
|
||||
|
||||
if ((boss == null) || (info == null))
|
||||
{
|
||||
try (PreparedStatement statement = con.prepareStatement("UPDATE grandboss_data set status = ? where boss_id = ?"))
|
||||
{
|
||||
statement.setInt(1, _bossStatus.get(bossId));
|
||||
statement.setInt(2, bossId);
|
||||
statement.executeUpdate();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try (PreparedStatement statement = con.prepareStatement("UPDATE grandboss_data set loc_x = ?, loc_y = ?, loc_z = ?, heading = ?, respawn_time = ?, currentHP = ?, currentMP = ?, status = ? where boss_id = ?"))
|
||||
{
|
||||
statement.setInt(1, boss.getX());
|
||||
statement.setInt(2, boss.getY());
|
||||
statement.setInt(3, boss.getZ());
|
||||
statement.setInt(4, boss.getHeading());
|
||||
statement.setLong(5, info.getLong("respawn_time"));
|
||||
|
||||
double hp = boss.getCurrentHp();
|
||||
double mp = boss.getCurrentMp();
|
||||
if (boss.isDead())
|
||||
{
|
||||
hp = boss.getMaxHp();
|
||||
mp = boss.getMaxMp();
|
||||
}
|
||||
|
||||
statement.setDouble(6, hp);
|
||||
statement.setDouble(7, mp);
|
||||
statement.setInt(8, _bossStatus.get(bossId));
|
||||
statement.setInt(9, bossId);
|
||||
statement.executeUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (final SQLException e)
|
||||
{
|
||||
_log.warning("GrandBossManager: Could not store Grand Bosses to database:" + e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves all Grand Boss info and then clears all info from memory, including all schedules.
|
||||
*/
|
||||
public void cleanUp()
|
||||
{
|
||||
storeToDb();
|
||||
|
||||
_bosses.clear();
|
||||
_storedInfo.clear();
|
||||
_bossStatus.clear();
|
||||
_zones.clear();
|
||||
}
|
||||
}
|
@@ -0,0 +1,295 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* 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 com.l2jmobius.gameserver.instancemanager;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.Statement;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.L2DatabaseFactory;
|
||||
import com.l2jmobius.gameserver.ItemsAutoDestroy;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.model.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
|
||||
import javolution.util.FastList;
|
||||
|
||||
/**
|
||||
* This class manage all items on ground
|
||||
* @version $Revision: $ $Date: $
|
||||
* @author DiezelMax - original ideea
|
||||
* @author Enforcer - actual build
|
||||
*/
|
||||
public class ItemsOnGroundManager
|
||||
{
|
||||
static final Logger _log = Logger.getLogger(ItemsOnGroundManager.class.getName());
|
||||
private static ItemsOnGroundManager _Instance;
|
||||
protected List<L2ItemInstance> _items = null;
|
||||
|
||||
private ItemsOnGroundManager()
|
||||
{
|
||||
if (!Config.SAVE_DROPPED_ITEM)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_items = new FastList<>();
|
||||
if (Config.SAVE_DROPPED_ITEM_INTERVAL > 0)
|
||||
{
|
||||
ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new storeInDb(), Config.SAVE_DROPPED_ITEM_INTERVAL, Config.SAVE_DROPPED_ITEM_INTERVAL);
|
||||
}
|
||||
}
|
||||
|
||||
public static final ItemsOnGroundManager getInstance()
|
||||
{
|
||||
if (_Instance == null)
|
||||
{
|
||||
_Instance = new ItemsOnGroundManager();
|
||||
_Instance.load();
|
||||
}
|
||||
return _Instance;
|
||||
}
|
||||
|
||||
private void load()
|
||||
{
|
||||
// If SaveDroppedItem is false, may want to delete all items previously stored to avoid add old items on reactivate
|
||||
if (!Config.SAVE_DROPPED_ITEM && Config.CLEAR_DROPPED_ITEM_TABLE)
|
||||
{
|
||||
emptyTable();
|
||||
}
|
||||
|
||||
if (!Config.SAVE_DROPPED_ITEM)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// if DestroyPlayerDroppedItem was previously false, items curently protected will be added to ItemsAutoDestroy
|
||||
if (Config.DESTROY_DROPPED_PLAYER_ITEM)
|
||||
{
|
||||
String str = null;
|
||||
if (!Config.DESTROY_EQUIPABLE_PLAYER_ITEM)
|
||||
{
|
||||
str = "update Itemsonground set drop_time=? where drop_time=-1 and equipable=0";
|
||||
}
|
||||
else if (Config.DESTROY_EQUIPABLE_PLAYER_ITEM)
|
||||
{
|
||||
str = "update Itemsonground set drop_time=? where drop_time=-1";
|
||||
}
|
||||
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement(str))
|
||||
{
|
||||
statement.setLong(1, System.currentTimeMillis());
|
||||
statement.execute();
|
||||
}
|
||||
catch (final Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "error while updating table ItemsOnGround " + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Add items to world
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
||||
Statement s = con.createStatement();
|
||||
ResultSet result = s.executeQuery("select object_id,item_id,count,enchant_level,x,y,z,drop_time,equipable from Itemsonground"))
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
while (result.next())
|
||||
{
|
||||
final L2ItemInstance item = new L2ItemInstance(result.getInt(1), result.getInt(2));
|
||||
L2World.getInstance().storeObject(item);
|
||||
if (item.isStackable() && (result.getInt(3) > 1))
|
||||
{
|
||||
item.setCount(result.getInt(3));
|
||||
}
|
||||
if (result.getInt(4) > 0)
|
||||
{
|
||||
item.setEnchantLevel(result.getInt(4));
|
||||
}
|
||||
item.getPosition().setWorldPosition(result.getInt(5), result.getInt(6), result.getInt(7));
|
||||
item.getPosition().setWorldRegion(L2World.getInstance().getRegion(item.getPosition().getWorldPosition()));
|
||||
item.getPosition().getWorldRegion().addVisibleObject(item);
|
||||
item.setDropTime(result.getLong(8));
|
||||
if (result.getLong(8) == -1)
|
||||
{
|
||||
item.setProtected(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
item.setProtected(false);
|
||||
}
|
||||
item.setIsVisible(true);
|
||||
|
||||
L2World.getInstance().addVisibleObject(item, item.getPosition().getWorldRegion(), null);
|
||||
_items.add(item);
|
||||
count++;
|
||||
|
||||
// add to ItemsAutoDestroy only items not protected
|
||||
if (!Config.LIST_PROTECTED_ITEMS.contains(item.getItemId()))
|
||||
{
|
||||
|
||||
if (result.getLong(8) > -1)
|
||||
{
|
||||
if (Config.AUTODESTROY_ITEM_AFTER > 0)
|
||||
{
|
||||
ItemsAutoDestroy.getInstance().addItem(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
System.out.println("ItemsOnGroundManager: restored " + count + " items.");
|
||||
}
|
||||
else
|
||||
{
|
||||
System.out.println("Initializing ItemsOnGroundManager.");
|
||||
}
|
||||
}
|
||||
catch (final Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "error while loading ItemsOnGround " + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (Config.EMPTY_DROPPED_ITEM_TABLE_AFTER_LOAD)
|
||||
{
|
||||
emptyTable();
|
||||
}
|
||||
}
|
||||
|
||||
public void Save(L2ItemInstance item)
|
||||
{
|
||||
if (!Config.SAVE_DROPPED_ITEM)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_items.add(item);
|
||||
}
|
||||
|
||||
public void removeObject(L2Object item)
|
||||
{
|
||||
if (!Config.SAVE_DROPPED_ITEM)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_items.remove(item);
|
||||
}
|
||||
|
||||
public void saveInDb()
|
||||
{
|
||||
new storeInDb().run();
|
||||
}
|
||||
|
||||
public void cleanUp()
|
||||
{
|
||||
_items.clear();
|
||||
}
|
||||
|
||||
public void emptyTable()
|
||||
{
|
||||
try (Connection conn = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement del = conn.prepareStatement("delete from Itemsonground"))
|
||||
{
|
||||
del.execute();
|
||||
}
|
||||
catch (final Exception e1)
|
||||
{
|
||||
_log.log(Level.SEVERE, "error while cleaning table ItemsOnGround " + e1);
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
protected class storeInDb extends Thread
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if (!Config.SAVE_DROPPED_ITEM)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
emptyTable();
|
||||
|
||||
if (_items.isEmpty())
|
||||
{
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.warning("ItemsOnGroundManager: nothing to save...");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (final L2ItemInstance item : _items)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("insert into Itemsonground(object_id,item_id,count,enchant_level,x,y,z,drop_time,equipable) values(?,?,?,?,?,?,?,?,?)"))
|
||||
{
|
||||
statement.setInt(1, item.getObjectId());
|
||||
statement.setInt(2, item.getItemId());
|
||||
statement.setInt(3, item.getCount());
|
||||
statement.setInt(4, item.getEnchantLevel());
|
||||
statement.setInt(5, item.getX());
|
||||
statement.setInt(6, item.getY());
|
||||
statement.setInt(7, item.getZ());
|
||||
if (item.isProtected())
|
||||
{
|
||||
statement.setLong(8, -1); // item will be protected
|
||||
}
|
||||
else
|
||||
{
|
||||
statement.setLong(8, item.getDropTime()); // item will be added to ItemsAutoDestroy
|
||||
}
|
||||
if (item.isEquipable())
|
||||
{
|
||||
statement.setLong(9, 1); // set equipable
|
||||
}
|
||||
else
|
||||
{
|
||||
statement.setLong(9, 0);
|
||||
}
|
||||
statement.execute();
|
||||
}
|
||||
catch (final Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "error while inserting into table ItemsOnGround " + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.warning("ItemsOnGroundManager: " + _items.size() + " items on ground saved");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* 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 com.l2jmobius.gameserver.instancemanager;
|
||||
|
||||
public class Manager
|
||||
{
|
||||
|
||||
public static void reloadAll()
|
||||
{
|
||||
|
||||
AuctionManager.getInstance().reload();
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,653 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* 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 com.l2jmobius.gameserver.instancemanager;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.L2DatabaseFactory;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.datatables.NpcTable;
|
||||
import com.l2jmobius.gameserver.idfactory.IdFactory;
|
||||
import com.l2jmobius.gameserver.model.AutoChatHandler;
|
||||
import com.l2jmobius.gameserver.model.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2SiegeGuardInstance;
|
||||
import com.l2jmobius.gameserver.model.entity.Castle;
|
||||
import com.l2jmobius.gameserver.templates.L2NpcTemplate;
|
||||
|
||||
import javolution.util.FastList;
|
||||
|
||||
/**
|
||||
* @author yellowperil & Fulminus This class is similar to the SiegeGuardManager, except it handles the loading of the mercenary tickets that are dropped on castle floors by the castle lords. These tickets (aka badges) need to be readded after each server reboot except when the server crashed in the
|
||||
* middle of an ongoig siege. In addition, this class keeps track of the added tickets, in order to properly limit the number of mercenaries in each castle and the number of mercenaries from each mercenary type. Finally, we provide auxilary functions to identify the castle in which each item
|
||||
* (and its corresponding NPC) belong to, in order to help avoid mixing them up.
|
||||
*/
|
||||
public class MercTicketManager
|
||||
{
|
||||
protected static Logger _log = Logger.getLogger(CastleManager.class.getName());
|
||||
|
||||
// =========================================================
|
||||
private static MercTicketManager _Instance;
|
||||
|
||||
public static final MercTicketManager getInstance()
|
||||
{
|
||||
// CastleManager.getInstance();
|
||||
if (_Instance == null)
|
||||
{
|
||||
System.out.println("Initializing MercTicketManager");
|
||||
_Instance = new MercTicketManager();
|
||||
_Instance.load();
|
||||
}
|
||||
return _Instance;
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Data Field
|
||||
private List<L2ItemInstance> _DroppedTickets; // to keep track of items on the ground
|
||||
|
||||
// TODO move all these values into siege.properties
|
||||
// max tickets per merc type = 10 + (castleid * 2)?
|
||||
// max ticker per castle = 40 + (castleid * 20)?
|
||||
private final int[] maxmercpertype =
|
||||
{
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10, // Gludio
|
||||
15,
|
||||
15,
|
||||
15,
|
||||
15,
|
||||
15,
|
||||
15,
|
||||
15,
|
||||
15,
|
||||
15,
|
||||
15, // Dion
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10, // Giran
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10, // Oren
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20, // Aden
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20, // Heine
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20 // Goddard
|
||||
};
|
||||
|
||||
private final int[] mercsmaxpercastle =
|
||||
{
|
||||
50, // Gludio
|
||||
75, // Dion
|
||||
100, // Giran
|
||||
150, // Oren
|
||||
200, // Aden
|
||||
200, // Heine
|
||||
200 // Goddard
|
||||
};
|
||||
|
||||
private final int[] _ItemIds =
|
||||
{
|
||||
3960,
|
||||
3961,
|
||||
3962,
|
||||
3963,
|
||||
3964,
|
||||
3965,
|
||||
3966,
|
||||
3967,
|
||||
3968,
|
||||
3969, // Gludio
|
||||
3973,
|
||||
3974,
|
||||
3975,
|
||||
3976,
|
||||
3977,
|
||||
3978,
|
||||
3979,
|
||||
3980,
|
||||
3981,
|
||||
3982, // Dion
|
||||
3986,
|
||||
3987,
|
||||
3988,
|
||||
3989,
|
||||
3990,
|
||||
3991,
|
||||
3992,
|
||||
3993,
|
||||
3994,
|
||||
3995, // Giran
|
||||
3999,
|
||||
4000,
|
||||
4001,
|
||||
4002,
|
||||
4003,
|
||||
4004,
|
||||
4005,
|
||||
4006,
|
||||
4007,
|
||||
4008, // Oren
|
||||
4012,
|
||||
4013,
|
||||
4014,
|
||||
4015,
|
||||
4016,
|
||||
4017,
|
||||
4018,
|
||||
4019,
|
||||
4020,
|
||||
4021, // Aden
|
||||
5205,
|
||||
5206,
|
||||
5207,
|
||||
5208,
|
||||
5209,
|
||||
5210,
|
||||
5211,
|
||||
5212,
|
||||
5213,
|
||||
5214, // Heine
|
||||
6779,
|
||||
6780,
|
||||
6781,
|
||||
6782,
|
||||
6783,
|
||||
6784,
|
||||
6785,
|
||||
6786,
|
||||
6787,
|
||||
6788 // Goddard
|
||||
};
|
||||
|
||||
private final int[] _NpcIds =
|
||||
{
|
||||
12301,
|
||||
12302,
|
||||
12303,
|
||||
12304,
|
||||
12305,
|
||||
12306,
|
||||
12307,
|
||||
12308,
|
||||
12309,
|
||||
12310, // Gludio
|
||||
12301,
|
||||
12302,
|
||||
12303,
|
||||
12304,
|
||||
12305,
|
||||
12306,
|
||||
12307,
|
||||
12308,
|
||||
12309,
|
||||
12310, // Dion
|
||||
12301,
|
||||
12302,
|
||||
12303,
|
||||
12304,
|
||||
12305,
|
||||
12306,
|
||||
12307,
|
||||
12308,
|
||||
12309,
|
||||
12310, // Giran
|
||||
12301,
|
||||
12302,
|
||||
12303,
|
||||
12304,
|
||||
12305,
|
||||
12306,
|
||||
12307,
|
||||
12308,
|
||||
12309,
|
||||
12310, // Oren
|
||||
12301,
|
||||
12302,
|
||||
12303,
|
||||
12304,
|
||||
12305,
|
||||
12306,
|
||||
12307,
|
||||
12308,
|
||||
12309,
|
||||
12310, // Aden
|
||||
12301,
|
||||
12302,
|
||||
12303,
|
||||
12304,
|
||||
12305,
|
||||
12306,
|
||||
12307,
|
||||
12308,
|
||||
12309,
|
||||
12310, // Heine
|
||||
12301,
|
||||
12302,
|
||||
12303,
|
||||
12304,
|
||||
12305,
|
||||
12306,
|
||||
12307,
|
||||
12308,
|
||||
12309,
|
||||
12310 // Goddard
|
||||
};
|
||||
|
||||
// =========================================================
|
||||
// Constructor
|
||||
public MercTicketManager()
|
||||
{
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Method - Public
|
||||
// returns the castleId for the passed ticket item id
|
||||
public int getTicketCastleId(int itemId)
|
||||
{
|
||||
if ((itemId >= _ItemIds[0]) && (itemId <= _ItemIds[9]))
|
||||
{
|
||||
return 1; // Gludio
|
||||
}
|
||||
if ((itemId >= _ItemIds[10]) && (itemId <= _ItemIds[19]))
|
||||
{
|
||||
return 2; // Dion
|
||||
}
|
||||
if ((itemId >= _ItemIds[20]) && (itemId <= _ItemIds[29]))
|
||||
{
|
||||
return 3; // Giran
|
||||
}
|
||||
if ((itemId >= _ItemIds[30]) && (itemId <= _ItemIds[39]))
|
||||
{
|
||||
return 4; // Oren
|
||||
}
|
||||
if ((itemId >= _ItemIds[40]) && (itemId <= _ItemIds[49]))
|
||||
{
|
||||
return 5; // Aden
|
||||
}
|
||||
if ((itemId >= _ItemIds[50]) && (itemId <= _ItemIds[59]))
|
||||
{
|
||||
return 6; // Heine
|
||||
}
|
||||
if ((itemId >= _ItemIds[60]) && (itemId <= _ItemIds[69]))
|
||||
{
|
||||
return 7; // Goddard
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void reload()
|
||||
{
|
||||
getDroppedTickets().clear();
|
||||
load();
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Method - Private
|
||||
private final void load()
|
||||
{
|
||||
// load merc tickets into the world
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("SELECT * FROM castle_siege_guards Where isHired = 1");
|
||||
ResultSet rs = statement.executeQuery())
|
||||
{
|
||||
int npcId;
|
||||
int itemId;
|
||||
int x, y, z;
|
||||
final int mercPlaced[] = new int[10];
|
||||
// start index to begin the search for the itemId corresponding to this NPC
|
||||
// this will help with:
|
||||
// a) skip unnecessary iterations in the search loop
|
||||
// b) avoid finding the wrong itemId whenever tickets of different spawn the same npc!
|
||||
int startindex = 0;
|
||||
|
||||
while (rs.next())
|
||||
{
|
||||
npcId = rs.getInt("npcId");
|
||||
x = rs.getInt("x");
|
||||
y = rs.getInt("y");
|
||||
|
||||
z = rs.getInt("z");
|
||||
|
||||
final Castle castle = CastleManager.getInstance().getCastle(x, y, z);
|
||||
if (castle != null)
|
||||
{
|
||||
if (mercPlaced[castle.getCastleId() - 1] >= mercsmaxpercastle[castle.getCastleId() - 1])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
startindex = 10 * (castle.getCastleId() - 1);
|
||||
mercPlaced[castle.getCastleId() - 1] += 1;
|
||||
|
||||
}
|
||||
|
||||
// find the FIRST ticket itemId with spawns the saved NPC in the saved location
|
||||
for (int i = startindex; i < _NpcIds.length; i++)
|
||||
{
|
||||
if (_NpcIds[i] == npcId) // Find the index of the item used
|
||||
{
|
||||
// only handle tickets if a siege is not ongoing in this npc's castle
|
||||
|
||||
if ((castle != null) && !(castle.getSiege().getIsInProgress()))
|
||||
{
|
||||
itemId = _ItemIds[i];
|
||||
// create the ticket in the gameworld
|
||||
final L2ItemInstance dropticket = new L2ItemInstance(IdFactory.getInstance().getNextId(), itemId);
|
||||
dropticket.dropMe(null, x, y, z);
|
||||
dropticket.setDropTime(0); // avoids it from beeing removed by the auto item destroyer
|
||||
L2World.getInstance().storeObject(dropticket);
|
||||
getDroppedTickets().add(dropticket);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("Loaded: " + getDroppedTickets().size() + " Mercenary Tickets");
|
||||
}
|
||||
catch (final Exception e)
|
||||
{
|
||||
System.out.println("Exception: loadMercenaryData(): " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Property - Public
|
||||
/**
|
||||
* Checks if the passed item has reached the limit of number of dropped tickets that this SPECIFIC item may have in its castle
|
||||
* @param itemId
|
||||
* @return
|
||||
*/
|
||||
public boolean isAtTypeLimit(int itemId)
|
||||
{
|
||||
int limit = -1;
|
||||
// find the max value for this item
|
||||
for (int i = 0; i < _ItemIds.length; i++)
|
||||
{
|
||||
if (_ItemIds[i] == itemId) // Find the index of the item used
|
||||
{
|
||||
limit = maxmercpertype[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (limit <= 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
L2ItemInstance ticket;
|
||||
for (int i = 0; i < getDroppedTickets().size(); i++)
|
||||
{
|
||||
ticket = getDroppedTickets().get(i);
|
||||
if ((ticket != null) && (ticket.getItemId() == itemId))
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count >= limit)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the passed item belongs to a castle which has reached its limit of number of dropped tickets.
|
||||
* @param itemId
|
||||
* @return
|
||||
*/
|
||||
public boolean isAtCastleLimit(int itemId)
|
||||
{
|
||||
final int castleId = getTicketCastleId(itemId);
|
||||
if (castleId <= 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
final int limit = mercsmaxpercastle[castleId - 1];
|
||||
if (limit <= 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
L2ItemInstance ticket;
|
||||
for (int i = 0; i < getDroppedTickets().size(); i++)
|
||||
{
|
||||
ticket = getDroppedTickets().get(i);
|
||||
if ((ticket != null) && (getTicketCastleId(ticket.getItemId()) == castleId))
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count >= limit)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isTooCloseToAnotherTicket(int x, int y, int z)
|
||||
{
|
||||
for (final L2ItemInstance item : getDroppedTickets())
|
||||
{
|
||||
final double dx = x - item.getX();
|
||||
final double dy = y - item.getY();
|
||||
final double dz = z - item.getZ();
|
||||
|
||||
if (((dx * dx) + (dy * dy) + (dz * dz)) < (25 * 25))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* addTicket actions 1) find the npc that needs to be saved in the mercenary spawns, given this item 2) Use the passed character's location info to add the spawn 3) create a copy of the item to drop in the world returns the id of the mercenary npc that was added to the spawn returns -1 if this
|
||||
* fails.
|
||||
* @param itemId
|
||||
* @param activeChar
|
||||
* @param messages
|
||||
* @return
|
||||
*/
|
||||
public int addTicket(int itemId, L2PcInstance activeChar, String[] messages)
|
||||
{
|
||||
final int x = activeChar.getX();
|
||||
final int y = activeChar.getY();
|
||||
final int z = activeChar.getZ();
|
||||
final int heading = activeChar.getHeading();
|
||||
|
||||
final Castle castle = CastleManager.getInstance().getCastle(activeChar);
|
||||
if (castle == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// check if this item can be added here
|
||||
for (int i = 0; i < _ItemIds.length; i++)
|
||||
{
|
||||
if (_ItemIds[i] == itemId) // Find the index of the item used
|
||||
{
|
||||
spawnMercenary(_NpcIds[i], x, y, z, 3000, messages, 0);
|
||||
|
||||
// Hire merc for this castle. NpcId is at the same index as the item used.
|
||||
castle.getSiege().getSiegeGuardManager().hireMerc(x, y, z, heading, _NpcIds[i]);
|
||||
|
||||
// create the ticket in the gameworld
|
||||
final L2ItemInstance dropticket = new L2ItemInstance(IdFactory.getInstance().getNextId(), itemId);
|
||||
dropticket.dropMe(null, x, y, z);
|
||||
dropticket.setDropTime(0); // avoids it from beeing removed by the auto item destroyer
|
||||
L2World.getInstance().storeObject(dropticket); // add to the world
|
||||
// and keep track of this ticket in the list
|
||||
_DroppedTickets.add(dropticket);
|
||||
|
||||
return _NpcIds[i];
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private void spawnMercenary(int npcId, int x, int y, int z, int despawnDelay, String[] messages, int chatDelay)
|
||||
{
|
||||
final L2NpcTemplate template = NpcTable.getInstance().getTemplate(npcId);
|
||||
if (template != null)
|
||||
{
|
||||
final L2SiegeGuardInstance npc = new L2SiegeGuardInstance(IdFactory.getInstance().getNextId(), template);
|
||||
npc.setCurrentHpMp(npc.getMaxHp(), npc.getMaxMp());
|
||||
npc.setDecayed(false);
|
||||
npc.spawnMe(x, y, (z + 20));
|
||||
|
||||
if ((messages != null) && (messages.length > 0))
|
||||
{
|
||||
AutoChatHandler.getInstance().registerChat(npc, messages, chatDelay);
|
||||
}
|
||||
|
||||
if (despawnDelay > 0)
|
||||
{
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(() -> npc.deleteMe(), despawnDelay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all tickets from a castle; remove the items from the world and remove references to them from this class
|
||||
* @param castleId
|
||||
*/
|
||||
public void deleteTickets(int castleId)
|
||||
{
|
||||
int i = 0;
|
||||
while (i < getDroppedTickets().size())
|
||||
{
|
||||
final L2ItemInstance item = getDroppedTickets().get(i);
|
||||
if ((item != null) && (getTicketCastleId(item.getItemId()) == castleId))
|
||||
{
|
||||
item.decayMe();
|
||||
L2World.getInstance().removeObject(item);
|
||||
|
||||
// remove from the list
|
||||
getDroppedTickets().remove(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* remove a single ticket and its associated spawn from the world (used when the castle lord picks up a ticket, for example)
|
||||
* @param item
|
||||
*/
|
||||
public void removeTicket(L2ItemInstance item)
|
||||
{
|
||||
final int itemId = item.getItemId();
|
||||
int npcId = -1;
|
||||
|
||||
// find the FIRST ticket itemId with spawns the saved NPC in the saved location
|
||||
for (int i = 0; i < _ItemIds.length; i++)
|
||||
{
|
||||
if (_ItemIds[i] == itemId) // Find the index of the item used
|
||||
{
|
||||
npcId = _NpcIds[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// find the castle where this item is
|
||||
final Castle castle = CastleManager.getInstance().getCastleById(getTicketCastleId(itemId));
|
||||
if ((npcId > 0) && (castle != null))
|
||||
{
|
||||
(new SiegeGuardManager(castle)).removeMerc(npcId, item.getX(), item.getY(), item.getZ());
|
||||
}
|
||||
|
||||
getDroppedTickets().remove(item);
|
||||
}
|
||||
|
||||
public int[] getItemIds()
|
||||
{
|
||||
return _ItemIds;
|
||||
}
|
||||
|
||||
public final List<L2ItemInstance> getDroppedTickets()
|
||||
{
|
||||
if (_DroppedTickets == null)
|
||||
{
|
||||
_DroppedTickets = new FastList<>();
|
||||
}
|
||||
return _DroppedTickets;
|
||||
}
|
||||
}
|
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* 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 com.l2jmobius.gameserver.instancemanager;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.gameserver.model.L2Character;
|
||||
import com.l2jmobius.gameserver.model.zone.type.L2OlympiadStadiumZone;
|
||||
|
||||
import javolution.util.FastList;
|
||||
|
||||
public class OlympiadStadiumManager
|
||||
{
|
||||
protected static Logger _log = Logger.getLogger(OlympiadStadiumManager.class.getName());
|
||||
|
||||
// =========================================================
|
||||
private static OlympiadStadiumManager _instance;
|
||||
|
||||
public static final OlympiadStadiumManager getInstance()
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
System.out.println("Initializing OlympiadStadiumManager");
|
||||
_instance = new OlympiadStadiumManager();
|
||||
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Data Field
|
||||
private FastList<L2OlympiadStadiumZone> _olympiadStadiums;
|
||||
|
||||
// =========================================================
|
||||
// Constructor
|
||||
public OlympiadStadiumManager()
|
||||
{
|
||||
}
|
||||
|
||||
// Property - Public
|
||||
public void addStadium(L2OlympiadStadiumZone arena)
|
||||
{
|
||||
if (_olympiadStadiums == null)
|
||||
{
|
||||
_olympiadStadiums = new FastList<>();
|
||||
}
|
||||
|
||||
_olympiadStadiums.add(arena);
|
||||
}
|
||||
|
||||
public final L2OlympiadStadiumZone getStadium(L2Character character)
|
||||
{
|
||||
for (final L2OlympiadStadiumZone temp : _olympiadStadiums)
|
||||
{
|
||||
if (temp.isCharacterInZone(character))
|
||||
{
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public final L2OlympiadStadiumZone getOlympiadStadiumById(int olympiadStadiumId)
|
||||
{
|
||||
for (final L2OlympiadStadiumZone temp : _olympiadStadiums)
|
||||
{
|
||||
if (temp.getStadiumId() == olympiadStadiumId)
|
||||
{
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -0,0 +1,647 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* 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 com.l2jmobius.gameserver.instancemanager;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.datatables.GmListTable;
|
||||
import com.l2jmobius.gameserver.idfactory.IdFactory;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.clientpackets.Say2;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.CreatureSay;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.L2GameServerPacket;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
|
||||
import javolution.text.TextBuilder;
|
||||
import javolution.util.FastList;
|
||||
import javolution.util.FastMap;
|
||||
|
||||
/**
|
||||
* Petition Manager
|
||||
* @author Tempy
|
||||
*/
|
||||
public final class PetitionManager
|
||||
{
|
||||
protected static Logger _log = Logger.getLogger(PetitionManager.class.getName());
|
||||
private static PetitionManager _instance;
|
||||
|
||||
private final Map<Integer, Petition> _pendingPetitions;
|
||||
private final Map<Integer, Petition> _completedPetitions;
|
||||
|
||||
private static enum PetitionState
|
||||
{
|
||||
Pending,
|
||||
Responder_Cancel,
|
||||
Responder_Missing,
|
||||
Responder_Reject,
|
||||
Responder_Complete,
|
||||
Petitioner_Cancel,
|
||||
Petitioner_Missing,
|
||||
In_Process,
|
||||
Completed
|
||||
}
|
||||
|
||||
private static enum PetitionType
|
||||
{
|
||||
Immobility,
|
||||
Recovery_Related,
|
||||
Bug_Report,
|
||||
Quest_Related,
|
||||
Bad_User,
|
||||
Suggestions,
|
||||
Game_Tip,
|
||||
Operation_Related,
|
||||
Other
|
||||
}
|
||||
|
||||
public static PetitionManager getInstance()
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
System.out.println("Initializing PetitionManager");
|
||||
_instance = new PetitionManager();
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
|
||||
private class Petition
|
||||
{
|
||||
private final long _submitTime = System.currentTimeMillis();
|
||||
private long _endTime = -1;
|
||||
|
||||
private final int _id;
|
||||
private final PetitionType _type;
|
||||
private PetitionState _state = PetitionState.Pending;
|
||||
private final String _content;
|
||||
|
||||
private final List<CreatureSay> _messageLog = new FastList<>();
|
||||
|
||||
private final L2PcInstance _petitioner;
|
||||
private L2PcInstance _responder;
|
||||
|
||||
public Petition(L2PcInstance petitioner, String petitionText, int petitionType)
|
||||
{
|
||||
petitionType--;
|
||||
_id = IdFactory.getInstance().getNextId();
|
||||
if (petitionType >= PetitionType.values().length)
|
||||
{
|
||||
_log.warning("PetitionManager:Petition : invalid petition type (received type was +1) : " + petitionType);
|
||||
}
|
||||
_type = PetitionType.values()[petitionType];
|
||||
_content = petitionText;
|
||||
|
||||
_petitioner = petitioner;
|
||||
}
|
||||
|
||||
protected boolean addLogMessage(CreatureSay cs)
|
||||
{
|
||||
return _messageLog.add(cs);
|
||||
}
|
||||
|
||||
protected List<CreatureSay> getLogMessages()
|
||||
{
|
||||
return _messageLog;
|
||||
}
|
||||
|
||||
public boolean endPetitionConsultation(PetitionState endState)
|
||||
{
|
||||
setState(endState);
|
||||
_endTime = System.currentTimeMillis();
|
||||
|
||||
if ((getResponder() != null) && (getResponder().isOnline() == 1))
|
||||
{
|
||||
if (endState == PetitionState.Responder_Reject)
|
||||
{
|
||||
getPetitioner().sendMessage("Your petition was rejected. Please try again later.");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ending petition consultation with <Player>.
|
||||
SystemMessage sm = new SystemMessage(395);
|
||||
sm.addString(getPetitioner().getName());
|
||||
getResponder().sendPacket(sm);
|
||||
|
||||
if (endState == PetitionState.Petitioner_Cancel)
|
||||
{
|
||||
// Receipt No. <ID> petition cancelled.
|
||||
sm = new SystemMessage(391);
|
||||
sm.addNumber(getId());
|
||||
getResponder().sendPacket(sm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// End petition consultation and inform them, if they are still online.
|
||||
if ((getPetitioner() != null) && (getPetitioner().isOnline() == 1))
|
||||
{
|
||||
getPetitioner().sendPacket(new SystemMessage(387));
|
||||
}
|
||||
|
||||
getCompletedPetitions().put(getId(), this);
|
||||
return (getPendingPetitions().remove(getId()) != null);
|
||||
}
|
||||
|
||||
public String getContent()
|
||||
{
|
||||
return _content;
|
||||
}
|
||||
|
||||
public int getId()
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
|
||||
public L2PcInstance getPetitioner()
|
||||
{
|
||||
return _petitioner;
|
||||
}
|
||||
|
||||
public L2PcInstance getResponder()
|
||||
{
|
||||
return _responder;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public long getEndTime()
|
||||
{
|
||||
return _endTime;
|
||||
}
|
||||
|
||||
public long getSubmitTime()
|
||||
{
|
||||
return _submitTime;
|
||||
}
|
||||
|
||||
public PetitionState getState()
|
||||
{
|
||||
return _state;
|
||||
}
|
||||
|
||||
public String getTypeAsString()
|
||||
{
|
||||
return _type.toString().replace("_", " ");
|
||||
}
|
||||
|
||||
public void sendPetitionerPacket(L2GameServerPacket responsePacket)
|
||||
{
|
||||
if ((getPetitioner() == null) || (getPetitioner().isOnline() == 0))
|
||||
{
|
||||
// Allows petitioners to see the results of their petition when
|
||||
// they log back into the game.
|
||||
|
||||
// endPetitionConsultation(PetitionState.Petitioner_Missing);
|
||||
return;
|
||||
}
|
||||
|
||||
getPetitioner().sendPacket(responsePacket);
|
||||
}
|
||||
|
||||
public void sendResponderPacket(L2GameServerPacket responsePacket)
|
||||
{
|
||||
if ((getResponder() == null) || (getResponder().isOnline() == 0))
|
||||
{
|
||||
endPetitionConsultation(PetitionState.Responder_Missing);
|
||||
return;
|
||||
}
|
||||
|
||||
getResponder().sendPacket(responsePacket);
|
||||
}
|
||||
|
||||
public void setState(PetitionState state)
|
||||
{
|
||||
_state = state;
|
||||
}
|
||||
|
||||
public void setResponder(L2PcInstance respondingAdmin)
|
||||
{
|
||||
if (getResponder() != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_responder = respondingAdmin;
|
||||
}
|
||||
}
|
||||
|
||||
private PetitionManager()
|
||||
{
|
||||
_pendingPetitions = new FastMap<>();
|
||||
_completedPetitions = new FastMap<>();
|
||||
}
|
||||
|
||||
public void clearCompletedPetitions()
|
||||
{
|
||||
final int numPetitions = getPendingPetitionCount();
|
||||
|
||||
getCompletedPetitions().clear();
|
||||
_log.info("PetitionManager: Completed petition data cleared. " + numPetitions + " petition(s) removed.");
|
||||
}
|
||||
|
||||
public void clearPendingPetitions()
|
||||
{
|
||||
final int numPetitions = getPendingPetitionCount();
|
||||
|
||||
getPendingPetitions().clear();
|
||||
_log.info("PetitionManager: Pending petition queue cleared. " + numPetitions + " petition(s) removed.");
|
||||
}
|
||||
|
||||
public boolean acceptPetition(L2PcInstance respondingAdmin, int petitionId)
|
||||
{
|
||||
if (!isValidPetition(petitionId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final Petition currPetition = getPendingPetitions().get(petitionId);
|
||||
|
||||
if (currPetition.getResponder() != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
currPetition.setResponder(respondingAdmin);
|
||||
currPetition.setState(PetitionState.In_Process);
|
||||
|
||||
// Petition application accepted. (Send to Petitioner)
|
||||
currPetition.sendPetitionerPacket(new SystemMessage(406));
|
||||
|
||||
// Petition application accepted. Reciept No. is <ID>
|
||||
SystemMessage sm = new SystemMessage(389);
|
||||
sm.addNumber(currPetition.getId());
|
||||
currPetition.sendResponderPacket(sm);
|
||||
|
||||
// Petition consultation with <Player> underway.
|
||||
sm = new SystemMessage(394);
|
||||
sm.addString(currPetition.getPetitioner().getName());
|
||||
currPetition.sendResponderPacket(sm);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cancelActivePetition(L2PcInstance player)
|
||||
{
|
||||
for (final Petition currPetition : getPendingPetitions().values())
|
||||
{
|
||||
if ((currPetition.getPetitioner() != null) && (currPetition.getPetitioner().getObjectId() == player.getObjectId()))
|
||||
{
|
||||
return (currPetition.endPetitionConsultation(PetitionState.Petitioner_Cancel));
|
||||
}
|
||||
|
||||
if ((currPetition.getResponder() != null) && (currPetition.getResponder().getObjectId() == player.getObjectId()))
|
||||
{
|
||||
return (currPetition.endPetitionConsultation(PetitionState.Responder_Cancel));
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void checkPetitionMessages(L2PcInstance petitioner)
|
||||
{
|
||||
if (petitioner != null)
|
||||
{
|
||||
for (final Petition currPetition : getPendingPetitions().values())
|
||||
{
|
||||
if (currPetition == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((currPetition.getPetitioner() != null) && (currPetition.getPetitioner().getObjectId() == petitioner.getObjectId()))
|
||||
{
|
||||
for (final CreatureSay logMessage : currPetition.getLogMessages())
|
||||
{
|
||||
petitioner.sendPacket(logMessage);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean endActivePetition(L2PcInstance player)
|
||||
{
|
||||
if (!player.isGM())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (final Petition currPetition : getPendingPetitions().values())
|
||||
{
|
||||
if (currPetition == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((currPetition.getResponder() != null) && (currPetition.getResponder().getObjectId() == player.getObjectId()))
|
||||
{
|
||||
return (currPetition.endPetitionConsultation(PetitionState.Completed));
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected Map<Integer, Petition> getCompletedPetitions()
|
||||
{
|
||||
return _completedPetitions;
|
||||
}
|
||||
|
||||
protected Map<Integer, Petition> getPendingPetitions()
|
||||
{
|
||||
return _pendingPetitions;
|
||||
}
|
||||
|
||||
public int getPendingPetitionCount()
|
||||
{
|
||||
return getPendingPetitions().size();
|
||||
}
|
||||
|
||||
public int getPlayerTotalPetitionCount(L2PcInstance player)
|
||||
{
|
||||
if (player == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int petitionCount = 0;
|
||||
|
||||
for (final Petition currPetition : getPendingPetitions().values())
|
||||
{
|
||||
if (currPetition == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((currPetition.getPetitioner() != null) && (currPetition.getPetitioner().getObjectId() == player.getObjectId()))
|
||||
{
|
||||
petitionCount++;
|
||||
}
|
||||
}
|
||||
|
||||
for (final Petition currPetition : getCompletedPetitions().values())
|
||||
{
|
||||
if (currPetition == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((currPetition.getPetitioner() != null) && (currPetition.getPetitioner().getObjectId() == player.getObjectId()))
|
||||
{
|
||||
petitionCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return petitionCount;
|
||||
}
|
||||
|
||||
public boolean isPetitionInProcess()
|
||||
{
|
||||
for (final Petition currPetition : getPendingPetitions().values())
|
||||
{
|
||||
if (currPetition == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (currPetition.getState() == PetitionState.In_Process)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPetitionInProcess(int petitionId)
|
||||
{
|
||||
if (!isValidPetition(petitionId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final Petition currPetition = getPendingPetitions().get(petitionId);
|
||||
return (currPetition.getState() == PetitionState.In_Process);
|
||||
}
|
||||
|
||||
public boolean isPlayerInConsultation(L2PcInstance player)
|
||||
{
|
||||
if (player != null)
|
||||
{
|
||||
for (final Petition currPetition : getPendingPetitions().values())
|
||||
{
|
||||
if (currPetition == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (currPetition.getState() != PetitionState.In_Process)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (((currPetition.getPetitioner() != null) && (currPetition.getPetitioner().getObjectId() == player.getObjectId())) || ((currPetition.getResponder() != null) && (currPetition.getResponder().getObjectId() == player.getObjectId())))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPetitioningAllowed()
|
||||
{
|
||||
return Config.PETITIONING_ALLOWED;
|
||||
}
|
||||
|
||||
public boolean isPlayerPetitionPending(L2PcInstance petitioner)
|
||||
{
|
||||
if (petitioner != null)
|
||||
{
|
||||
for (final Petition currPetition : getPendingPetitions().values())
|
||||
{
|
||||
if (currPetition == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((currPetition.getPetitioner() != null) && (currPetition.getPetitioner().getObjectId() == petitioner.getObjectId()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isValidPetition(int petitionId)
|
||||
{
|
||||
return getPendingPetitions().containsKey(petitionId);
|
||||
}
|
||||
|
||||
public boolean rejectPetition(L2PcInstance respondingAdmin, int petitionId)
|
||||
{
|
||||
if (!isValidPetition(petitionId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final Petition currPetition = getPendingPetitions().get(petitionId);
|
||||
|
||||
if (currPetition.getResponder() != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
currPetition.setResponder(respondingAdmin);
|
||||
return (currPetition.endPetitionConsultation(PetitionState.Responder_Reject));
|
||||
}
|
||||
|
||||
public boolean sendActivePetitionMessage(L2PcInstance player, String messageText)
|
||||
{
|
||||
// if (!isPlayerInConsultation(player))
|
||||
// return false;
|
||||
|
||||
CreatureSay cs;
|
||||
|
||||
for (final Petition currPetition : getPendingPetitions().values())
|
||||
{
|
||||
if (currPetition == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((currPetition.getPetitioner() != null) && (currPetition.getPetitioner().getObjectId() == player.getObjectId()))
|
||||
{
|
||||
cs = new CreatureSay(player.getObjectId(), Say2.PETITION_PLAYER, player.getName(), messageText);
|
||||
currPetition.addLogMessage(cs);
|
||||
|
||||
currPetition.sendResponderPacket(cs);
|
||||
currPetition.sendPetitionerPacket(cs);
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((currPetition.getResponder() != null) && (currPetition.getResponder().getObjectId() == player.getObjectId()))
|
||||
{
|
||||
cs = new CreatureSay(player.getObjectId(), Say2.PETITION_GM, player.getName(), messageText);
|
||||
currPetition.addLogMessage(cs);
|
||||
|
||||
currPetition.sendResponderPacket(cs);
|
||||
currPetition.sendPetitionerPacket(cs);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void sendPendingPetitionList(L2PcInstance activeChar)
|
||||
{
|
||||
final TextBuilder htmlContent = new TextBuilder("<html><body>" + "<center><font color=\"LEVEL\">Current Petitions</font><br><table width=\"300\">");
|
||||
final SimpleDateFormat dateFormat = new SimpleDateFormat("dd MMM HH:mm z");
|
||||
|
||||
if (getPendingPetitionCount() == 0)
|
||||
{
|
||||
htmlContent.append("<tr><td colspan=\"4\">There are no currently pending petitions.</td></tr>");
|
||||
}
|
||||
else
|
||||
{
|
||||
htmlContent.append("<tr><td></td><td><font color=\"999999\">Petitioner</font></td>" + "<td><font color=\"999999\">Petition Type</font></td><td><font color=\"999999\">Submitted</font></td></tr>");
|
||||
}
|
||||
|
||||
for (final Petition currPetition : getPendingPetitions().values())
|
||||
{
|
||||
if (currPetition == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
htmlContent.append("<tr><td>");
|
||||
|
||||
if (currPetition.getState() != PetitionState.In_Process)
|
||||
{
|
||||
htmlContent.append("<button value=\"View\" action=\"bypass -h admin_view_petition " + currPetition.getId() + "\" " + "width=\"40\" height=\"15\" back=\"sek.cbui94\" fore=\"sek.cbui92\">");
|
||||
}
|
||||
else
|
||||
{
|
||||
htmlContent.append("<font color=\"999999\">In Process</font>");
|
||||
}
|
||||
|
||||
htmlContent.append("</td><td>" + currPetition.getPetitioner().getName() + "</td><td>" + currPetition.getTypeAsString() + "</td><td>" + dateFormat.format(new Date(currPetition.getSubmitTime())) + "</td></tr>");
|
||||
}
|
||||
|
||||
htmlContent.append("</table><br><button value=\"Refresh\" action=\"bypass -h admin_view_petitions\" width=\"50\" " + "height=\"15\" back=\"sek.cbui94\" fore=\"sek.cbui92\"><br><button value=\"Back\" action=\"bypass -h admin_admin\" " + "width=\"40\" height=\"15\" back=\"sek.cbui94\" fore=\"sek.cbui92\"></center></body></html>");
|
||||
|
||||
final NpcHtmlMessage htmlMsg = new NpcHtmlMessage(0);
|
||||
htmlMsg.setHtml(htmlContent.toString());
|
||||
activeChar.sendPacket(htmlMsg);
|
||||
}
|
||||
|
||||
public int submitPetition(L2PcInstance petitioner, String petitionText, int petitionType)
|
||||
{
|
||||
// Create a new petition instance and add it to the list of pending petitions.
|
||||
final Petition newPetition = new Petition(petitioner, petitionText, petitionType);
|
||||
final int newPetitionId = newPetition.getId();
|
||||
getPendingPetitions().put(newPetitionId, newPetition);
|
||||
|
||||
// Notify all GMs that a new petition has been submitted.
|
||||
final String msgContent = petitioner.getName() + " has submitted a new petition."; // (ID: " + newPetitionId + ").";
|
||||
GmListTable.broadcastToGMs(new CreatureSay(petitioner.getObjectId(), 17, "Petition System", msgContent));
|
||||
|
||||
return newPetitionId;
|
||||
}
|
||||
|
||||
public void viewPetition(L2PcInstance activeChar, int petitionId)
|
||||
{
|
||||
if (!activeChar.isGM())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isValidPetition(petitionId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Petition currPetition = getPendingPetitions().get(petitionId);
|
||||
final TextBuilder htmlContent = new TextBuilder("<html><body>");
|
||||
final SimpleDateFormat dateFormat = new SimpleDateFormat("EEE dd MMM HH:mm z");
|
||||
|
||||
htmlContent.append("<center><br><font color=\"LEVEL\">Petition #" + currPetition.getId() + "</font><br1>");
|
||||
htmlContent.append("<img src=\"L2UI.SquareGray\" width=\"200\" height=\"1\"></center><br>");
|
||||
htmlContent.append("Submit Time: " + dateFormat.format(new Date(currPetition.getSubmitTime())) + "<br1>");
|
||||
htmlContent.append("Petitioner: " + currPetition.getPetitioner().getName() + "<br1>");
|
||||
htmlContent.append("Petition Type: " + currPetition.getTypeAsString() + "<br>" + currPetition.getContent() + "<br>");
|
||||
htmlContent.append("<center><button value=\"Accept\" action=\"bypass -h admin_accept_petition " + currPetition.getId() + "\"" + "width=\"50\" height=\"15\" back=\"sek.cbui94\" fore=\"sek.cbui92\"><br1>");
|
||||
htmlContent.append("<button value=\"Reject\" action=\"bypass -h admin_reject_petition " + currPetition.getId() + "\" " + "width=\"50\" height=\"15\" back=\"sek.cbui94\" fore=\"sek.cbui92\"><br>");
|
||||
htmlContent.append("<button value=\"Back\" action=\"bypass -h admin_view_petitions\" width=\"40\" height=\"15\" back=\"sek.cbui94\" " + "fore=\"sek.cbui92\"></center>");
|
||||
htmlContent.append("</body></html>");
|
||||
|
||||
final NpcHtmlMessage htmlMsg = new NpcHtmlMessage(0);
|
||||
htmlMsg.setHtml(htmlContent.toString());
|
||||
activeChar.sendPacket(htmlMsg);
|
||||
}
|
||||
}
|
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* 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 com.l2jmobius.gameserver.instancemanager;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.model.quest.Quest;
|
||||
import com.l2jmobius.gameserver.scripting.L2ScriptEngineManager;
|
||||
import com.l2jmobius.gameserver.scripting.ScriptManager;
|
||||
|
||||
import javolution.util.FastMap;
|
||||
|
||||
public class QuestManager extends ScriptManager<Quest>
|
||||
{
|
||||
protected static Logger _log = Logger.getLogger(QuestManager.class.getName());
|
||||
|
||||
// =========================================================
|
||||
private static QuestManager _Instance;
|
||||
|
||||
public static final QuestManager getInstance()
|
||||
{
|
||||
if (_Instance == null)
|
||||
{
|
||||
System.out.println("Initializing QuestManager");
|
||||
_Instance = new QuestManager();
|
||||
}
|
||||
return _Instance;
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
|
||||
// =========================================================
|
||||
// Data Field
|
||||
private final Map<String, Quest> _quests = new FastMap<>();
|
||||
|
||||
// =========================================================
|
||||
// Constructor
|
||||
public QuestManager()
|
||||
{
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Method - Public
|
||||
public final boolean reload(String questFolder)
|
||||
{
|
||||
final Quest q = getQuest(questFolder);
|
||||
if (q == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return q.reload();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads the quest given by questId.<BR>
|
||||
* <B>NOTICE: Will only work if the quest name is equal to the quest folder name</B>
|
||||
* @param questId The id of the quest to be reloaded
|
||||
* @return true if reload was successful, false otherwise
|
||||
*/
|
||||
public final boolean reload(int questId)
|
||||
{
|
||||
final Quest q = getQuest(questId);
|
||||
if (q == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return q.reload();
|
||||
}
|
||||
|
||||
public final void reloadAllQuests()
|
||||
{
|
||||
_log.info("Reloading Server Scripts");
|
||||
try
|
||||
{
|
||||
// unload all scripts
|
||||
for (final Quest quest : _quests.values())
|
||||
{
|
||||
if (quest != null)
|
||||
{
|
||||
quest.unload();
|
||||
}
|
||||
}
|
||||
|
||||
// Firstly, preconfigure jython path
|
||||
L2ScriptEngineManager.getInstance().preConfigure();
|
||||
|
||||
// now load all scripts
|
||||
final File scripts = new File(Config.DATAPACK_ROOT + "/data/scripts.cfg");
|
||||
L2ScriptEngineManager.getInstance().executeScriptList(scripts);
|
||||
|
||||
QuestManager.getInstance().report();
|
||||
}
|
||||
catch (final Exception ioe)
|
||||
{
|
||||
_log.severe("Failed loading scripts.cfg, no script is going to be loaded");
|
||||
}
|
||||
}
|
||||
|
||||
public final void report()
|
||||
{
|
||||
System.out.println("Loaded: " + _quests.size() + " quests");
|
||||
}
|
||||
|
||||
public final void save()
|
||||
{
|
||||
for (final Quest q : _quests.values())
|
||||
{
|
||||
q.saveGlobalData();
|
||||
}
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Property - Public
|
||||
public final Quest getQuest(String name)
|
||||
{
|
||||
return _quests.get(name);
|
||||
}
|
||||
|
||||
public final Quest getQuest(int questId)
|
||||
{
|
||||
for (final Quest q : _quests.values())
|
||||
{
|
||||
if (q.getQuestIntId() == questId)
|
||||
{
|
||||
return q;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public final void addQuest(Quest newQuest)
|
||||
{
|
||||
if (newQuest == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Quest argument cannot be null");
|
||||
}
|
||||
|
||||
final Quest old = _quests.get(newQuest.getName());
|
||||
|
||||
// FIXME: unloading the old quest at this point is a tad too late.
|
||||
// the new quest has already initialized itself and read the data, starting
|
||||
// an unpredictable number of tasks with that data. The old quest will now
|
||||
// save data which will never be read.
|
||||
// However, requesting the newQuest to re-read the data is not necessarily a
|
||||
// good option, since the newQuest may have already started timers, spawned NPCs
|
||||
// or taken any other action which it might re-take by re-reading the data.
|
||||
// the current solution properly closes the running tasks of the old quest but
|
||||
// ignores the data; perhaps the least of all evils...
|
||||
if (old != null)
|
||||
{
|
||||
old.unload();
|
||||
_log.info("Replaced: (" + old.getName() + ") with a new version (" + newQuest.getName() + ")");
|
||||
}
|
||||
_quests.put(newQuest.getName(), newQuest);
|
||||
}
|
||||
|
||||
public final boolean removeQuest(Quest q)
|
||||
{
|
||||
return _quests.remove(q.getName()) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.l2jmobius.gameserver.scripting.ScriptManager#getAllManagedScripts()
|
||||
*/
|
||||
@Override
|
||||
public Iterable<Quest> getAllManagedScripts()
|
||||
{
|
||||
return _quests.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.l2jmobius.gameserver.scripting.ScriptManager#unload(com.l2jmobius.gameserver.scripting.ManagedScript)
|
||||
*/
|
||||
@Override
|
||||
public boolean unload(Quest ms)
|
||||
{
|
||||
ms.saveGlobalData();
|
||||
return removeQuest(ms);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.l2jmobius.gameserver.scripting.ScriptManager#getScriptManagerName()
|
||||
*/
|
||||
@Override
|
||||
public String getScriptManagerName()
|
||||
{
|
||||
return "QuestManager";
|
||||
}
|
||||
}
|
@@ -0,0 +1,520 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* 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 com.l2jmobius.gameserver.instancemanager;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.L2DatabaseFactory;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.datatables.GmListTable;
|
||||
import com.l2jmobius.gameserver.datatables.NpcTable;
|
||||
import com.l2jmobius.gameserver.datatables.SpawnTable;
|
||||
import com.l2jmobius.gameserver.model.L2Spawn;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2RaidBossInstance;
|
||||
import com.l2jmobius.gameserver.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.templates.StatsSet;
|
||||
import com.l2jmobius.util.Rnd;
|
||||
|
||||
import javolution.util.FastMap;
|
||||
|
||||
/**
|
||||
* @author godson
|
||||
*/
|
||||
public class RaidBossSpawnManager
|
||||
{
|
||||
|
||||
private static Logger _log = Logger.getLogger(RaidBossSpawnManager.class.getName());
|
||||
|
||||
private static RaidBossSpawnManager _instance;
|
||||
protected static Map<Integer, L2RaidBossInstance> _bosses;
|
||||
protected static Map<Integer, L2Spawn> _spawns;
|
||||
protected static Map<Integer, StatsSet> _storedInfo;
|
||||
protected static Map<Integer, ScheduledFuture<?>> _schedules;
|
||||
|
||||
public static enum StatusEnum
|
||||
{
|
||||
ALIVE,
|
||||
DEAD,
|
||||
UNDEFINED
|
||||
}
|
||||
|
||||
public RaidBossSpawnManager()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
public static RaidBossSpawnManager getInstance()
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
_instance = new RaidBossSpawnManager();
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
_bosses = new FastMap<>();
|
||||
_schedules = new FastMap<>();
|
||||
_storedInfo = new FastMap<>();
|
||||
_spawns = new FastMap<>();
|
||||
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("SELECT * from raidboss_spawnlist ORDER BY boss_id");
|
||||
ResultSet rset = statement.executeQuery())
|
||||
{
|
||||
L2Spawn spawnDat;
|
||||
L2NpcTemplate template;
|
||||
long respawnTime;
|
||||
|
||||
while (rset.next())
|
||||
{
|
||||
template = getValidTemplate(rset.getInt("boss_id"));
|
||||
if (template != null)
|
||||
{
|
||||
spawnDat = new L2Spawn(template);
|
||||
spawnDat.setLocx(rset.getInt("loc_x"));
|
||||
spawnDat.setLocy(rset.getInt("loc_y"));
|
||||
spawnDat.setLocz(rset.getInt("loc_z"));
|
||||
spawnDat.setAmount(rset.getInt("amount"));
|
||||
spawnDat.setHeading(rset.getInt("heading"));
|
||||
spawnDat.setRespawnMinDelay(rset.getInt("respawn_min_delay"));
|
||||
spawnDat.setRespawnMaxDelay(rset.getInt("respawn_max_delay"));
|
||||
|
||||
respawnTime = rset.getLong("respawn_time");
|
||||
|
||||
addNewSpawn(spawnDat, respawnTime, rset.getDouble("currentHP"), rset.getDouble("currentMP"), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
_log.warning("RaidBossSpawnManager: Could not load raidboss #" + rset.getInt("boss_id") + " from DB");
|
||||
}
|
||||
}
|
||||
|
||||
_log.info("RaidBossSpawnManager: Loaded " + _bosses.size() + " Instances");
|
||||
_log.info("RaidBossSpawnManager: Scheduled " + _schedules.size() + " Instances");
|
||||
}
|
||||
catch (final SQLException e)
|
||||
{
|
||||
_log.warning("RaidBossSpawnManager: Couldnt load raidboss_spawnlist table");
|
||||
}
|
||||
catch (final Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private class spawnSchedule implements Runnable
|
||||
{
|
||||
private final int bossId;
|
||||
|
||||
public spawnSchedule(int npcId)
|
||||
{
|
||||
bossId = npcId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
L2RaidBossInstance raidboss = null;
|
||||
|
||||
if (bossId == 10328)
|
||||
{
|
||||
raidboss = DayNightSpawnManager.getInstance().handleBoss(_spawns.get(bossId));
|
||||
}
|
||||
else
|
||||
{
|
||||
raidboss = (L2RaidBossInstance) _spawns.get(bossId).doSpawn();
|
||||
}
|
||||
|
||||
if (raidboss != null)
|
||||
{
|
||||
raidboss.setRaidStatus(StatusEnum.ALIVE);
|
||||
|
||||
final StatsSet info = new StatsSet();
|
||||
info.set("currentHP", raidboss.getCurrentHp());
|
||||
info.set("currentMP", raidboss.getCurrentMp());
|
||||
info.set("respawnTime", 0L);
|
||||
|
||||
_storedInfo.put(bossId, info);
|
||||
|
||||
GmListTable.broadcastMessageToGMs("Spawning Raid Boss " + raidboss.getName());
|
||||
|
||||
_bosses.put(bossId, raidboss);
|
||||
}
|
||||
|
||||
_schedules.remove(bossId);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateStatus(L2RaidBossInstance boss, boolean isBossDead)
|
||||
{
|
||||
if (!_storedInfo.containsKey(boss.getNpcId()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final StatsSet info = _storedInfo.get(boss.getNpcId());
|
||||
|
||||
if (isBossDead)
|
||||
{
|
||||
boss.setRaidStatus(StatusEnum.DEAD);
|
||||
|
||||
long respawnTime;
|
||||
final int RespawnMinDelay = boss.getSpawn().getRespawnMinDelay();
|
||||
final int RespawnMaxDelay = boss.getSpawn().getRespawnMaxDelay();
|
||||
final long respawn_delay = Rnd.get((int) (RespawnMinDelay * 1000 * Config.RAID_MIN_RESPAWN_MULTIPLIER), (int) (RespawnMaxDelay * 1000 * Config.RAID_MAX_RESPAWN_MULTIPLIER));
|
||||
respawnTime = Calendar.getInstance().getTimeInMillis() + respawn_delay;
|
||||
|
||||
info.set("currentHP", boss.getMaxHp());
|
||||
info.set("currentMP", boss.getMaxMp());
|
||||
info.set("respawnTime", respawnTime);
|
||||
|
||||
_log.info("RaidBossSpawnManager: Updated " + boss.getName() + " respawn time to " + respawnTime);
|
||||
|
||||
if (!_schedules.containsKey(boss.getNpcId()))
|
||||
{
|
||||
ScheduledFuture<?> futureSpawn;
|
||||
futureSpawn = ThreadPoolManager.getInstance().scheduleGeneral(new spawnSchedule(boss.getNpcId()), respawn_delay);
|
||||
|
||||
_schedules.put(boss.getNpcId(), futureSpawn);
|
||||
// To update immediately Database uncomment on the following line, to post the hour of respawn raid boss on your site for example or to envisage a crash landing of the waiter.
|
||||
updateDb();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
boss.setRaidStatus(StatusEnum.ALIVE);
|
||||
|
||||
info.set("currentHP", boss.getCurrentHp());
|
||||
info.set("currentMP", boss.getCurrentMp());
|
||||
info.set("respawnTime", 0L);
|
||||
}
|
||||
|
||||
_storedInfo.remove(boss.getNpcId());
|
||||
_storedInfo.put(boss.getNpcId(), info);
|
||||
}
|
||||
|
||||
public void addNewSpawn(L2Spawn spawnDat, long respawnTime, double currentHP, double currentMP, boolean storeInDb)
|
||||
{
|
||||
if (spawnDat == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (_spawns.containsKey(spawnDat.getNpcid()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final int bossId = spawnDat.getNpcid();
|
||||
final long time = Calendar.getInstance().getTimeInMillis();
|
||||
|
||||
SpawnTable.getInstance().addNewSpawn(spawnDat, false);
|
||||
|
||||
if ((respawnTime == 0L) || (time > respawnTime))
|
||||
{
|
||||
L2RaidBossInstance raidboss = null;
|
||||
|
||||
if (bossId == 10328)
|
||||
{
|
||||
raidboss = DayNightSpawnManager.getInstance().handleBoss(spawnDat);
|
||||
}
|
||||
else
|
||||
{
|
||||
raidboss = (L2RaidBossInstance) spawnDat.doSpawn();
|
||||
}
|
||||
|
||||
if (raidboss != null)
|
||||
{
|
||||
raidboss.setCurrentHp(currentHP);
|
||||
raidboss.setCurrentMp(currentMP);
|
||||
raidboss.setRaidStatus(StatusEnum.ALIVE);
|
||||
|
||||
_bosses.put(bossId, raidboss);
|
||||
|
||||
final StatsSet info = new StatsSet();
|
||||
info.set("currentHP", currentHP);
|
||||
info.set("currentMP", currentMP);
|
||||
info.set("respawnTime", 0L);
|
||||
|
||||
_storedInfo.put(bossId, info);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ScheduledFuture<?> futureSpawn;
|
||||
final long spawnTime = respawnTime - Calendar.getInstance().getTimeInMillis();
|
||||
|
||||
futureSpawn = ThreadPoolManager.getInstance().scheduleGeneral(new spawnSchedule(bossId), spawnTime);
|
||||
|
||||
_schedules.put(bossId, futureSpawn);
|
||||
}
|
||||
|
||||
_spawns.put(bossId, spawnDat);
|
||||
|
||||
if (storeInDb)
|
||||
{
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("INSERT INTO raidboss_spawnlist (boss_id,amount,loc_x,loc_y,loc_z,heading,respawn_time,currentHp,currentMp) values(?,?,?,?,?,?,?,?,?)"))
|
||||
{
|
||||
statement.setInt(1, spawnDat.getNpcid());
|
||||
statement.setInt(2, spawnDat.getAmount());
|
||||
statement.setInt(3, spawnDat.getLocx());
|
||||
statement.setInt(4, spawnDat.getLocy());
|
||||
statement.setInt(5, spawnDat.getLocz());
|
||||
statement.setInt(6, spawnDat.getHeading());
|
||||
|
||||
statement.setLong(7, respawnTime);
|
||||
statement.setDouble(8, currentHP);
|
||||
statement.setDouble(9, currentMP);
|
||||
statement.execute();
|
||||
}
|
||||
catch (final Exception e)
|
||||
{
|
||||
// problem with storing spawn
|
||||
_log.warning("RaidBossSpawnManager: Could not store raidboss #" + bossId + " in the DB:" + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteSpawn(L2Spawn spawnDat, boolean updateDb)
|
||||
{
|
||||
if (spawnDat == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!_spawns.containsKey(spawnDat.getNpcid()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final int bossId = spawnDat.getNpcid();
|
||||
|
||||
SpawnTable.getInstance().deleteSpawn(spawnDat, false);
|
||||
_spawns.remove(bossId);
|
||||
|
||||
if (_bosses.containsKey(bossId))
|
||||
{
|
||||
_bosses.remove(bossId);
|
||||
}
|
||||
|
||||
if (_schedules.containsKey(bossId))
|
||||
{
|
||||
final ScheduledFuture<?> f = _schedules.get(bossId);
|
||||
f.cancel(true);
|
||||
_schedules.remove(bossId);
|
||||
}
|
||||
|
||||
if (_storedInfo.containsKey(bossId))
|
||||
{
|
||||
_storedInfo.remove(bossId);
|
||||
}
|
||||
|
||||
if (updateDb)
|
||||
{
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("DELETE FROM raidboss_spawnlist WHERE boss_id=?"))
|
||||
{
|
||||
statement.setInt(1, bossId);
|
||||
statement.execute();
|
||||
}
|
||||
catch (final Exception e)
|
||||
{
|
||||
// problem with deleting spawn
|
||||
_log.warning("RaidBossSpawnManager: Could not remove raidboss #" + bossId + " from DB: " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateDb()
|
||||
{
|
||||
for (final Integer bossId : _storedInfo.keySet())
|
||||
{
|
||||
final L2RaidBossInstance boss = _bosses.get(bossId);
|
||||
if (boss == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (boss.getRaidStatus().equals(StatusEnum.ALIVE))
|
||||
{
|
||||
updateStatus(boss, false);
|
||||
}
|
||||
|
||||
final StatsSet info = _storedInfo.get(bossId);
|
||||
if (info == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("UPDATE raidboss_spawnlist set respawn_time = ?, currentHP = ?, currentMP = ? where boss_id = ?"))
|
||||
{
|
||||
statement.setLong(1, info.getLong("respawnTime"));
|
||||
statement.setDouble(2, info.getDouble("currentHP"));
|
||||
statement.setDouble(3, info.getDouble("currentMP"));
|
||||
statement.setInt(4, bossId);
|
||||
statement.execute();
|
||||
}
|
||||
catch (final SQLException e)
|
||||
{
|
||||
_log.warning("RaidBossSpawnManager: Couldnt update raidboss_spawnlist table");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String[] getAllRaidBossStatus()
|
||||
{
|
||||
final String[] msg = new String[_bosses == null ? 0 : _bosses.size()];
|
||||
|
||||
if (_bosses == null)
|
||||
{
|
||||
msg[0] = "None";
|
||||
return msg;
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
|
||||
for (final int i : _bosses.keySet())
|
||||
{
|
||||
final L2RaidBossInstance boss = _bosses.get(i);
|
||||
|
||||
msg[index] = boss.getName() + ": " + boss.getRaidStatus().name();
|
||||
index++;
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
public String getRaidBossStatus(int bossId)
|
||||
{
|
||||
String msg = "RaidBoss Status....\n";
|
||||
|
||||
if (_bosses == null)
|
||||
{
|
||||
msg += "None";
|
||||
return msg;
|
||||
}
|
||||
|
||||
if (_bosses.containsKey(bossId))
|
||||
{
|
||||
final L2RaidBossInstance boss = _bosses.get(bossId);
|
||||
|
||||
msg += boss.getName() + ": " + boss.getRaidStatus().name();
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
public StatusEnum getRaidBossStatusId(int bossId)
|
||||
{
|
||||
if (_bosses.containsKey(bossId))
|
||||
{
|
||||
return _bosses.get(bossId).getRaidStatus();
|
||||
}
|
||||
|
||||
if (_schedules.containsKey(bossId))
|
||||
{
|
||||
return StatusEnum.DEAD;
|
||||
}
|
||||
|
||||
return StatusEnum.UNDEFINED;
|
||||
}
|
||||
|
||||
public L2NpcTemplate getValidTemplate(int bossId)
|
||||
{
|
||||
final L2NpcTemplate template = NpcTable.getInstance().getTemplate(bossId);
|
||||
if (template == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (!template.type.equalsIgnoreCase("L2RaidBoss"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return template;
|
||||
}
|
||||
|
||||
public void notifySpawnNightBoss(L2RaidBossInstance raidboss)
|
||||
{
|
||||
final StatsSet info = new StatsSet();
|
||||
info.set("currentHP", raidboss.getCurrentHp());
|
||||
info.set("currentMP", raidboss.getCurrentMp());
|
||||
info.set("respawnTime", 0L);
|
||||
|
||||
raidboss.setRaidStatus(StatusEnum.ALIVE);
|
||||
|
||||
_storedInfo.put(raidboss.getNpcId(), info);
|
||||
|
||||
GmListTable.broadcastMessageToGMs("Spawning Raid Boss " + raidboss.getName());
|
||||
|
||||
_bosses.put(raidboss.getNpcId(), raidboss);
|
||||
}
|
||||
|
||||
public boolean isDefined(int bossId)
|
||||
{
|
||||
return _spawns.containsKey(bossId);
|
||||
}
|
||||
|
||||
public Map<Integer, L2RaidBossInstance> getBosses()
|
||||
{
|
||||
return _bosses;
|
||||
}
|
||||
|
||||
public Map<Integer, L2Spawn> getSpawns()
|
||||
{
|
||||
return _spawns;
|
||||
}
|
||||
|
||||
public void reloadBosses()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves all raidboss status and then clears all info from memory, including all schedules.
|
||||
*/
|
||||
|
||||
public void cleanUp()
|
||||
{
|
||||
updateDb();
|
||||
|
||||
_bosses.clear();
|
||||
|
||||
if (_schedules != null)
|
||||
{
|
||||
for (final Integer bossId : _schedules.keySet())
|
||||
{
|
||||
final ScheduledFuture<?> f = _schedules.get(bossId);
|
||||
f.cancel(true);
|
||||
}
|
||||
}
|
||||
|
||||
_schedules.clear();
|
||||
_storedInfo.clear();
|
||||
_spawns.clear();
|
||||
}
|
||||
}
|
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* 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 com.l2jmobius.gameserver.instancemanager;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.L2DatabaseFactory;
|
||||
import com.l2jmobius.gameserver.datatables.NpcTable;
|
||||
import com.l2jmobius.gameserver.model.L2Spawn;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.entity.Castle;
|
||||
import com.l2jmobius.gameserver.templates.L2NpcTemplate;
|
||||
|
||||
import javolution.util.FastList;
|
||||
|
||||
public class SiegeGuardManager
|
||||
{
|
||||
private static Logger _log = Logger.getLogger(SiegeGuardManager.class.getName());
|
||||
|
||||
// =========================================================
|
||||
// Data Field
|
||||
private final Castle _Castle;
|
||||
private final List<L2Spawn> _SiegeGuardSpawn = new FastList<>();
|
||||
|
||||
// =========================================================
|
||||
// Constructor
|
||||
public SiegeGuardManager(Castle castle)
|
||||
{
|
||||
_Castle = castle;
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Method - Public
|
||||
/**
|
||||
* Add guard.<BR>
|
||||
* <BR>
|
||||
* @param activeChar
|
||||
* @param npcId
|
||||
*/
|
||||
public void addSiegeGuard(L2PcInstance activeChar, int npcId)
|
||||
{
|
||||
if (activeChar == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
addSiegeGuard(activeChar.getX(), activeChar.getY(), activeChar.getZ(), activeChar.getHeading(), npcId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add guard.<BR>
|
||||
* <BR>
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param heading
|
||||
* @param npcId
|
||||
*/
|
||||
public void addSiegeGuard(int x, int y, int z, int heading, int npcId)
|
||||
{
|
||||
saveSiegeGuard(x, y, z, heading, npcId, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hire merc.<BR>
|
||||
* <BR>
|
||||
* @param activeChar
|
||||
* @param npcId
|
||||
*/
|
||||
public void hireMerc(L2PcInstance activeChar, int npcId)
|
||||
{
|
||||
if (activeChar == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
hireMerc(activeChar.getX(), activeChar.getY(), activeChar.getZ(), activeChar.getHeading(), npcId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hire merc.<BR>
|
||||
* <BR>
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param heading
|
||||
* @param npcId
|
||||
*/
|
||||
public void hireMerc(int x, int y, int z, int heading, int npcId)
|
||||
{
|
||||
saveSiegeGuard(x, y, z, heading, npcId, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a single mercenary, identified by the npcId and location. Presumably, this is used when a castle lord picks up a previously dropped ticket
|
||||
* @param npcId
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
*/
|
||||
public void removeMerc(int npcId, int x, int y, int z)
|
||||
{
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("Delete From castle_siege_guards Where npcId = ? And x = ? AND y = ? AND z = ? AND isHired = 1"))
|
||||
{
|
||||
statement.setInt(1, npcId);
|
||||
statement.setInt(2, x);
|
||||
statement.setInt(3, y);
|
||||
statement.setInt(4, z);
|
||||
statement.execute();
|
||||
}
|
||||
catch (final Exception e1)
|
||||
{
|
||||
_log.warning("Error deleting hired siege guard at " + x + ',' + y + ',' + z + ":" + e1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove mercs.<BR>
|
||||
* <BR>
|
||||
*/
|
||||
public void removeMercs()
|
||||
{
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("Delete From castle_siege_guards Where castleId = ? And isHired = 1"))
|
||||
{
|
||||
statement.setInt(1, getCastle().getCastleId());
|
||||
statement.execute();
|
||||
}
|
||||
catch (final Exception e1)
|
||||
{
|
||||
_log.warning("Error deleting hired siege guard for castle " + getCastle().getName() + ":" + e1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawn guards.<BR>
|
||||
* <BR>
|
||||
*/
|
||||
public void spawnSiegeGuard()
|
||||
{
|
||||
loadSiegeGuard();
|
||||
for (final L2Spawn spawn : getSiegeGuardSpawn())
|
||||
{
|
||||
if (spawn != null)
|
||||
{
|
||||
spawn.init();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unspawn guards.<BR>
|
||||
* <BR>
|
||||
*/
|
||||
public void unspawnSiegeGuard()
|
||||
{
|
||||
for (final L2Spawn spawn : getSiegeGuardSpawn())
|
||||
{
|
||||
if (spawn == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
spawn.stopRespawn();
|
||||
spawn.getLastSpawn().doDie(spawn.getLastSpawn());
|
||||
}
|
||||
|
||||
getSiegeGuardSpawn().clear();
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Method - Private
|
||||
/**
|
||||
* Load guards.<BR>
|
||||
* <BR>
|
||||
*/
|
||||
private void loadSiegeGuard()
|
||||
{
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("SELECT * FROM castle_siege_guards Where castleId = ? And isHired = ?"))
|
||||
{
|
||||
statement.setInt(1, getCastle().getCastleId());
|
||||
if (getCastle().getOwnerId() > 0)
|
||||
{
|
||||
statement.setInt(2, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
statement.setInt(2, 0);
|
||||
}
|
||||
try (ResultSet rs = statement.executeQuery())
|
||||
{
|
||||
L2Spawn spawn1;
|
||||
L2NpcTemplate template1;
|
||||
|
||||
while (rs.next())
|
||||
{
|
||||
template1 = NpcTable.getInstance().getTemplate(rs.getInt("npcId"));
|
||||
if (template1 != null)
|
||||
{
|
||||
spawn1 = new L2Spawn(template1);
|
||||
spawn1.setId(rs.getInt("id"));
|
||||
spawn1.setAmount(1);
|
||||
spawn1.setLocx(rs.getInt("x"));
|
||||
spawn1.setLocy(rs.getInt("y"));
|
||||
spawn1.setLocz(rs.getInt("z"));
|
||||
spawn1.setHeading(rs.getInt("heading"));
|
||||
spawn1.setRespawnDelay(rs.getInt("respawnDelay"));
|
||||
spawn1.setLocation(0);
|
||||
|
||||
_SiegeGuardSpawn.add(spawn1);
|
||||
}
|
||||
else
|
||||
{
|
||||
_log.warning("Missing npc data in npc table for id: " + rs.getInt("npcId"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (final Exception e1)
|
||||
{
|
||||
_log.warning("Error loading siege guard for castle " + getCastle().getName() + ":" + e1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save guards.<BR>
|
||||
* <BR>
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param heading
|
||||
* @param npcId
|
||||
* @param isHire
|
||||
*/
|
||||
private void saveSiegeGuard(int x, int y, int z, int heading, int npcId, int isHire)
|
||||
{
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("Insert Into castle_siege_guards (castleId, npcId, x, y, z, heading, respawnDelay, isHired) Values (?, ?, ?, ?, ?, ?, ?, ?)"))
|
||||
{
|
||||
statement.setInt(1, getCastle().getCastleId());
|
||||
statement.setInt(2, npcId);
|
||||
statement.setInt(3, x);
|
||||
statement.setInt(4, y);
|
||||
statement.setInt(5, z);
|
||||
statement.setInt(6, heading);
|
||||
if (isHire == 1)
|
||||
{
|
||||
statement.setInt(7, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
statement.setInt(7, 600);
|
||||
}
|
||||
statement.setInt(8, isHire);
|
||||
statement.execute();
|
||||
}
|
||||
catch (final Exception e1)
|
||||
{
|
||||
_log.warning("Error adding siege guard for castle " + getCastle().getName() + ":" + e1);
|
||||
}
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Proeprty
|
||||
|
||||
public final Castle getCastle()
|
||||
{
|
||||
return _Castle;
|
||||
}
|
||||
|
||||
public final List<L2Spawn> getSiegeGuardSpawn()
|
||||
{
|
||||
return _SiegeGuardSpawn;
|
||||
}
|
||||
}
|
@@ -0,0 +1,400 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* 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 com.l2jmobius.gameserver.instancemanager;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.L2DatabaseFactory;
|
||||
import com.l2jmobius.gameserver.datatables.SkillTable;
|
||||
import com.l2jmobius.gameserver.model.L2Character;
|
||||
import com.l2jmobius.gameserver.model.L2Clan;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.entity.Castle;
|
||||
import com.l2jmobius.gameserver.model.entity.Siege;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
|
||||
import javolution.util.FastList;
|
||||
import javolution.util.FastMap;
|
||||
|
||||
public class SiegeManager
|
||||
{
|
||||
private static Logger _log = Logger.getLogger(SiegeManager.class.getName());
|
||||
|
||||
// =========================================================
|
||||
private static SiegeManager _Instance;
|
||||
|
||||
public static final SiegeManager getInstance()
|
||||
{
|
||||
if (_Instance == null)
|
||||
{
|
||||
System.out.println("Initializing SiegeManager");
|
||||
_Instance = new SiegeManager();
|
||||
_Instance.load();
|
||||
}
|
||||
return _Instance;
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Data Field
|
||||
private int _Attacker_Max_Clans = 500; // Max number of clans
|
||||
private int _Attacker_RespawnDelay = 0; // Time in ms. Changeable in siege.config
|
||||
private int _Defender_Max_Clans = 500; // Max number of clans
|
||||
|
||||
// Siege settings
|
||||
private FastMap<Integer, FastList<SiegeSpawn>> _artefactSpawnList;
|
||||
private FastMap<Integer, FastList<SiegeSpawn>> _controlTowerSpawnList;
|
||||
|
||||
private int _Flag_MaxCount = 1; // Changeable in siege.config
|
||||
private int _Siege_Clan_MinLevel = 4; // Changeable in siege.config
|
||||
private int _Siege_Length = 120; // Time in minute. Changeable in siege.config
|
||||
|
||||
// =========================================================
|
||||
// Constructor
|
||||
public SiegeManager()
|
||||
{
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Method - Public
|
||||
public final void addSiegeSkills(L2PcInstance character)
|
||||
{
|
||||
character.addSkill(SkillTable.getInstance().getInfo(246, 1), false);
|
||||
character.addSkill(SkillTable.getInstance().getInfo(247, 1), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if character summon<BR>
|
||||
* <BR>
|
||||
* @param activeChar The L2Character of the character can summon
|
||||
* @param isCheckOnly
|
||||
* @return
|
||||
*/
|
||||
public final boolean checkIfOkToSummon(L2Character activeChar, boolean isCheckOnly)
|
||||
{
|
||||
if ((activeChar == null) || !(activeChar instanceof L2PcInstance))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final SystemMessage sm = new SystemMessage(614);
|
||||
final L2PcInstance player = (L2PcInstance) activeChar;
|
||||
|
||||
if (getSiege(activeChar) == null)
|
||||
{
|
||||
sm.addString("You may only summon this in a siege battlefield.");
|
||||
}
|
||||
else if ((player.getClanId() != 0) && (getSiege(activeChar).getAttackerClan(player.getClanId()) == null))
|
||||
{
|
||||
sm.addString("Only attackers have the right to use this skill.");
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!isCheckOnly)
|
||||
{
|
||||
player.sendPacket(sm);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the clan is registered or owner of a castle<BR>
|
||||
* <BR>
|
||||
* @param clan The L2Clan of the player
|
||||
* @param castleId
|
||||
* @return
|
||||
*/
|
||||
public final boolean checkIsRegistered(L2Clan clan, int castleId)
|
||||
{
|
||||
if (clan == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (clan.getHasCastle() > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean register = false;
|
||||
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("SELECT clan_id FROM siege_clans where clan_id=? and castle_id=?"))
|
||||
{
|
||||
statement.setInt(1, clan.getClanId());
|
||||
statement.setInt(2, castleId);
|
||||
try (ResultSet rs = statement.executeQuery())
|
||||
{
|
||||
while (rs.next())
|
||||
{
|
||||
register = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (final Exception e)
|
||||
{
|
||||
System.out.println("Exception: checkIsRegistered(): " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
return register;
|
||||
}
|
||||
|
||||
public final void removeSiegeSkills(L2PcInstance character)
|
||||
{
|
||||
character.removeSkill(SkillTable.getInstance().getInfo(246, 1));
|
||||
character.removeSkill(SkillTable.getInstance().getInfo(247, 1));
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Method - Private
|
||||
private final void load()
|
||||
{
|
||||
final Properties siegeSettings = new Properties();
|
||||
try (InputStream is = new FileInputStream(new File(Config.SIEGE_CONFIGURATION_FILE)))
|
||||
{
|
||||
siegeSettings.load(is);
|
||||
}
|
||||
catch (final Exception e)
|
||||
{
|
||||
System.err.println("Error while loading siege data.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// Siege setting
|
||||
_Attacker_Max_Clans = Integer.decode(siegeSettings.getProperty("AttackerMaxClans", "500"));
|
||||
_Attacker_RespawnDelay = Integer.decode(siegeSettings.getProperty("AttackerRespawn", "0"));
|
||||
|
||||
_Defender_Max_Clans = Integer.decode(siegeSettings.getProperty("DefenderMaxClans", "500"));
|
||||
|
||||
_Flag_MaxCount = Integer.decode(siegeSettings.getProperty("MaxFlags", "1"));
|
||||
_Siege_Clan_MinLevel = Integer.decode(siegeSettings.getProperty("SiegeClanMinLevel", "4"));
|
||||
_Siege_Length = Integer.decode(siegeSettings.getProperty("SiegeLength", "120"));
|
||||
|
||||
// Siege spawns settings
|
||||
_controlTowerSpawnList = new FastMap<>();
|
||||
_artefactSpawnList = new FastMap<>();
|
||||
|
||||
for (final Castle castle : CastleManager.getInstance().getCastles())
|
||||
{
|
||||
final FastList<SiegeSpawn> _controlTowersSpawns = new FastList<>();
|
||||
|
||||
for (int i = 1; i < 0xFF; i++)
|
||||
{
|
||||
final String _spawnParams = siegeSettings.getProperty(castle.getName() + "ControlTower" + Integer.toString(i), "");
|
||||
|
||||
if (_spawnParams.length() == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
final StringTokenizer st = new StringTokenizer(_spawnParams.trim(), ",");
|
||||
|
||||
try
|
||||
{
|
||||
final int x = Integer.parseInt(st.nextToken());
|
||||
final int y = Integer.parseInt(st.nextToken());
|
||||
final int z = Integer.parseInt(st.nextToken());
|
||||
final int npc_id = Integer.parseInt(st.nextToken());
|
||||
final int hp = Integer.parseInt(st.nextToken());
|
||||
|
||||
_controlTowersSpawns.add(new SiegeSpawn(castle.getCastleId(), x, y, z, 0, npc_id, hp));
|
||||
}
|
||||
catch (final Exception e)
|
||||
{
|
||||
_log.warning("Error while loading control tower(s) for " + castle.getName() + " castle.");
|
||||
}
|
||||
}
|
||||
|
||||
final FastList<SiegeSpawn> _artefactSpawns = new FastList<>();
|
||||
|
||||
for (int i = 1; i < 0xFF; i++)
|
||||
{
|
||||
final String _spawnParams = siegeSettings.getProperty(castle.getName() + "Artefact" + Integer.toString(i), "");
|
||||
|
||||
if (_spawnParams.length() == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
final StringTokenizer st = new StringTokenizer(_spawnParams.trim(), ",");
|
||||
|
||||
try
|
||||
{
|
||||
final int x = Integer.parseInt(st.nextToken());
|
||||
final int y = Integer.parseInt(st.nextToken());
|
||||
final int z = Integer.parseInt(st.nextToken());
|
||||
final int heading = Integer.parseInt(st.nextToken());
|
||||
final int npc_id = Integer.parseInt(st.nextToken());
|
||||
|
||||
_artefactSpawns.add(new SiegeSpawn(castle.getCastleId(), x, y, z, heading, npc_id));
|
||||
}
|
||||
catch (final Exception e)
|
||||
{
|
||||
_log.warning("Error while loading artefact(s) for " + castle.getName() + " castle.");
|
||||
}
|
||||
}
|
||||
|
||||
_controlTowerSpawnList.put(castle.getCastleId(), _controlTowersSpawns);
|
||||
_artefactSpawnList.put(castle.getCastleId(), _artefactSpawns);
|
||||
}
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Property - Public
|
||||
|
||||
public final FastList<SiegeSpawn> getArtefactSpawnList(int _castleId)
|
||||
{
|
||||
if (_artefactSpawnList.containsKey(_castleId))
|
||||
{
|
||||
return _artefactSpawnList.get(_castleId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public final FastList<SiegeSpawn> getControlTowerSpawnList(int _castleId)
|
||||
{
|
||||
if (_controlTowerSpawnList.containsKey(_castleId))
|
||||
{
|
||||
return _controlTowerSpawnList.get(_castleId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public final int getAttackerMaxClans()
|
||||
{
|
||||
return _Attacker_Max_Clans;
|
||||
}
|
||||
|
||||
public final int getAttackerRespawnDelay()
|
||||
{
|
||||
return _Attacker_RespawnDelay;
|
||||
}
|
||||
|
||||
public final int getDefenderMaxClans()
|
||||
{
|
||||
return _Defender_Max_Clans;
|
||||
}
|
||||
|
||||
public final int getFlagMaxCount()
|
||||
{
|
||||
return _Flag_MaxCount;
|
||||
}
|
||||
|
||||
public final Siege getSiege(L2Object activeObject)
|
||||
{
|
||||
return getSiege(activeObject.getX(), activeObject.getY(), activeObject.getZ());
|
||||
}
|
||||
|
||||
public final Siege getSiege(int x, int y, int z)
|
||||
{
|
||||
for (final Castle castle : CastleManager.getInstance().getCastles())
|
||||
{
|
||||
if (castle.getSiege().checkIfInZone(x, y, z))
|
||||
{
|
||||
return castle.getSiege();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public final int getSiegeClanMinLevel()
|
||||
{
|
||||
return _Siege_Clan_MinLevel;
|
||||
}
|
||||
|
||||
public final int getSiegeLength()
|
||||
{
|
||||
return _Siege_Length;
|
||||
}
|
||||
|
||||
public final List<Siege> getSieges()
|
||||
{
|
||||
final FastList<Siege> sieges = new FastList<>();
|
||||
for (final Castle castle : CastleManager.getInstance().getCastles())
|
||||
{
|
||||
sieges.add(castle.getSiege());
|
||||
}
|
||||
return sieges;
|
||||
}
|
||||
|
||||
public class SiegeSpawn
|
||||
{
|
||||
Location _location;
|
||||
private final int _npc_id;
|
||||
private final int _heading;
|
||||
private final int _castle_id;
|
||||
private int _hp;
|
||||
|
||||
public SiegeSpawn(int castle_id, int x, int y, int z, int heading, int npc_id)
|
||||
{
|
||||
_castle_id = castle_id;
|
||||
_location = new Location(x, y, z, heading);
|
||||
_heading = heading;
|
||||
_npc_id = npc_id;
|
||||
}
|
||||
|
||||
public SiegeSpawn(int castle_id, int x, int y, int z, int heading, int npc_id, int hp)
|
||||
{
|
||||
_castle_id = castle_id;
|
||||
_location = new Location(x, y, z, heading);
|
||||
_heading = heading;
|
||||
_npc_id = npc_id;
|
||||
_hp = hp;
|
||||
}
|
||||
|
||||
public int getCastleId()
|
||||
{
|
||||
return _castle_id;
|
||||
}
|
||||
|
||||
public int getNpcId()
|
||||
{
|
||||
return _npc_id;
|
||||
}
|
||||
|
||||
public int getHeading()
|
||||
{
|
||||
return _heading;
|
||||
}
|
||||
|
||||
public int getHp()
|
||||
{
|
||||
return _hp;
|
||||
}
|
||||
|
||||
public Location getLocation()
|
||||
{
|
||||
return _location;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* 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 com.l2jmobius.gameserver.instancemanager;
|
||||
|
||||
import com.l2jmobius.gameserver.datatables.MapRegionTable;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.entity.Castle;
|
||||
import com.l2jmobius.gameserver.model.zone.type.L2TownZone;
|
||||
|
||||
import javolution.util.FastList;
|
||||
|
||||
public class TownManager
|
||||
{
|
||||
// private static Logger _log = Logger.getLogger(TownManager.class.getName());
|
||||
|
||||
// =========================================================
|
||||
private static TownManager _Instance;
|
||||
|
||||
public static final TownManager getInstance()
|
||||
{
|
||||
if (_Instance == null)
|
||||
{
|
||||
System.out.println("Initializing TownManager");
|
||||
_Instance = new TownManager();
|
||||
|
||||
}
|
||||
return _Instance;
|
||||
}
|
||||
// =========================================================
|
||||
|
||||
// =========================================================
|
||||
// Data Field
|
||||
private FastList<L2TownZone> _Towns;
|
||||
|
||||
// =========================================================
|
||||
// Constructor
|
||||
public TownManager()
|
||||
{
|
||||
}
|
||||
|
||||
// Property - Public
|
||||
public void addTown(L2TownZone town)
|
||||
{
|
||||
if (_Towns == null)
|
||||
{
|
||||
_Towns = new FastList<>();
|
||||
}
|
||||
|
||||
_Towns.add(town);
|
||||
}
|
||||
|
||||
public final L2TownZone getClosestTown(L2Object activeObject)
|
||||
{
|
||||
switch (MapRegionTable.getInstance().getMapRegion(activeObject.getPosition().getX(), activeObject.getPosition().getY()))
|
||||
{
|
||||
case 0:
|
||||
return getTown(2); // TI
|
||||
case 1:
|
||||
return getTown(3); // Elven
|
||||
case 2:
|
||||
return getTown(1); // DE
|
||||
case 3:
|
||||
return getTown(4); // Orc
|
||||
case 4:
|
||||
return getTown(6); // Dwarven
|
||||
case 5:
|
||||
return getTown(7); // Gludio
|
||||
case 6:
|
||||
return getTown(5); // Gludin
|
||||
case 7:
|
||||
return getTown(8); // Dion
|
||||
case 8:
|
||||
return getTown(9); // Giran
|
||||
case 9:
|
||||
return getTown(10); // Oren
|
||||
case 10:
|
||||
return getTown(12); // Aden
|
||||
case 11:
|
||||
return getTown(11); // HV
|
||||
case 12:
|
||||
return getTown(9); // Giran
|
||||
case 13:
|
||||
return getTown(15); // Heine
|
||||
case 14:
|
||||
return getTown(14); // Rune
|
||||
case 15:
|
||||
return getTown(13); // Goddard
|
||||
case 16:
|
||||
return getTown(8); // Dion
|
||||
}
|
||||
|
||||
return getTown(12); // Default to Aden
|
||||
}
|
||||
|
||||
public final boolean townHasCastleInSiege(int x, int y)
|
||||
{
|
||||
final int curtown = (MapRegionTable.getInstance().getMapRegion(x, y));
|
||||
final int[] castleidarray =
|
||||
{
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
0,
|
||||
0,
|
||||
6,
|
||||
0,
|
||||
7,
|
||||
2
|
||||
};
|
||||
// find an instance of the castle for this town.
|
||||
final int castleIndex = castleidarray[curtown];
|
||||
if (castleIndex > 0)
|
||||
{
|
||||
final Castle castle = CastleManager.getInstance().getCastles().get(CastleManager.getInstance().getCastleIndex(castleIndex));
|
||||
if (castle != null)
|
||||
{
|
||||
return castle.getSiege().getIsInProgress();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public final L2TownZone getTown(int townId)
|
||||
{
|
||||
for (final L2TownZone temp : _Towns)
|
||||
{
|
||||
if (temp.getTownId() == townId)
|
||||
{
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public final L2TownZone getTown(int x, int y, int z)
|
||||
{
|
||||
for (final L2TownZone temp : _Towns)
|
||||
{
|
||||
if (temp.isInsideZone(x, y, z))
|
||||
{
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -0,0 +1,571 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* 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 com.l2jmobius.gameserver.instancemanager.games;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Calendar;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.L2DatabaseFactory;
|
||||
import com.l2jmobius.gameserver.Announcements;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.model.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jmobius.util.Rnd;
|
||||
|
||||
public class Lottery
|
||||
{
|
||||
public static long SECOND = 1000;
|
||||
public static long MINUTE = 60000;
|
||||
|
||||
private static Lottery _instance;
|
||||
protected static Logger _log = Logger.getLogger(Lottery.class.getName());
|
||||
|
||||
private static final String INSERT_LOTTERY = "INSERT INTO games(id, idnr, enddate, prize, newprize) VALUES (?, ?, ?, ?, ?)";
|
||||
private static final String UPDATE_PRICE = "UPDATE games SET prize=?, newprize=? WHERE id = 1 AND idnr = ?";
|
||||
private static final String UPDATE_LOTTERY = "UPDATE games SET finished=1, prize=?, newprize=?, number1=?, number2=?, prize1=?, prize2=?, prize3=? WHERE id=1 AND idnr=?";
|
||||
private static final String SELECT_LAST_LOTTERY = "SELECT idnr, prize, newprize, enddate, finished FROM games WHERE id = 1 ORDER BY idnr DESC LIMIT 1";
|
||||
private static final String SELECT_LOTTERY_ITEM = "SELECT enchant_level, custom_type2 FROM items WHERE item_id = 4442 AND custom_type1 = ?";
|
||||
private static final String SELECT_LOTTERY_TICKET = "SELECT number1, number2, prize1, prize2, prize3 FROM games WHERE id = 1 and idnr = ?";
|
||||
|
||||
protected int _number;
|
||||
protected int _prize;
|
||||
protected boolean _isSellingTickets;
|
||||
protected boolean _isStarted;
|
||||
protected long _enddate;
|
||||
|
||||
private Lottery()
|
||||
{
|
||||
_number = 1;
|
||||
_prize = Config.ALT_LOTTERY_PRIZE;
|
||||
_isSellingTickets = false;
|
||||
_isStarted = false;
|
||||
_enddate = System.currentTimeMillis();
|
||||
|
||||
if (Config.ALLOW_LOTTERY)
|
||||
{
|
||||
(new startLottery()).run();
|
||||
}
|
||||
}
|
||||
|
||||
public static Lottery getInstance()
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
_instance = new Lottery();
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
|
||||
public int getId()
|
||||
{
|
||||
return _number;
|
||||
}
|
||||
|
||||
public int getPrize()
|
||||
{
|
||||
return _prize;
|
||||
}
|
||||
|
||||
public long getEndDate()
|
||||
{
|
||||
return _enddate;
|
||||
}
|
||||
|
||||
public void increasePrize(int count)
|
||||
{
|
||||
_prize += count;
|
||||
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement(UPDATE_PRICE))
|
||||
{
|
||||
statement.setInt(1, getPrize());
|
||||
statement.setInt(2, getPrize());
|
||||
statement.setInt(3, getId());
|
||||
statement.execute();
|
||||
}
|
||||
catch (final SQLException e)
|
||||
{
|
||||
_log.warning("Lottery: Could not increase current lottery prize: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isSellableTickets()
|
||||
{
|
||||
return _isSellingTickets;
|
||||
}
|
||||
|
||||
public boolean isStarted()
|
||||
{
|
||||
return _isStarted;
|
||||
}
|
||||
|
||||
private class startLottery implements Runnable
|
||||
{
|
||||
protected startLottery()
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement(SELECT_LAST_LOTTERY))
|
||||
{
|
||||
try (ResultSet rset = statement.executeQuery())
|
||||
{
|
||||
if (rset.next())
|
||||
{
|
||||
_number = rset.getInt("idnr");
|
||||
|
||||
if (rset.getInt("finished") == 1)
|
||||
{
|
||||
_number++;
|
||||
_prize = rset.getInt("newprize");
|
||||
}
|
||||
else
|
||||
{
|
||||
_prize = rset.getInt("prize");
|
||||
_enddate = rset.getLong("enddate");
|
||||
|
||||
if (_enddate <= (System.currentTimeMillis() + (2 * MINUTE)))
|
||||
{
|
||||
(new finishLottery()).run();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_enddate > System.currentTimeMillis())
|
||||
{
|
||||
_isStarted = true;
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new finishLottery(), _enddate - System.currentTimeMillis());
|
||||
|
||||
if (_enddate > (System.currentTimeMillis() + (12 * MINUTE)))
|
||||
{
|
||||
_isSellingTickets = true;
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new stopSellingTickets(), _enddate - System.currentTimeMillis() - (10 * MINUTE));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (final SQLException e)
|
||||
{
|
||||
_log.warning("Lottery: Could not restore lottery data: " + e);
|
||||
}
|
||||
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.info("Lottery: Starting ticket sell for lottery #" + getId() + ".");
|
||||
}
|
||||
|
||||
_isSellingTickets = true;
|
||||
_isStarted = true;
|
||||
|
||||
Announcements.getInstance().announceToAll("Lottery tickets are now available for Lucky Lottery #" + getId() + ".");
|
||||
final Calendar finishtime = Calendar.getInstance();
|
||||
finishtime.setTimeInMillis(_enddate);
|
||||
finishtime.set(Calendar.MINUTE, 0);
|
||||
finishtime.set(Calendar.SECOND, 0);
|
||||
|
||||
if (finishtime.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY)
|
||||
{
|
||||
finishtime.set(Calendar.HOUR_OF_DAY, 19);
|
||||
_enddate = finishtime.getTimeInMillis();
|
||||
_enddate += 604800000;
|
||||
}
|
||||
else
|
||||
{
|
||||
finishtime.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
|
||||
finishtime.set(Calendar.HOUR_OF_DAY, 19);
|
||||
_enddate = finishtime.getTimeInMillis();
|
||||
}
|
||||
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new stopSellingTickets(), _enddate - System.currentTimeMillis() - (10 * MINUTE));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new finishLottery(), _enddate - System.currentTimeMillis());
|
||||
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement(INSERT_LOTTERY))
|
||||
{
|
||||
statement.setInt(1, 1);
|
||||
statement.setInt(2, getId());
|
||||
statement.setLong(3, getEndDate());
|
||||
statement.setInt(4, getPrize());
|
||||
statement.setInt(5, getPrize());
|
||||
statement.execute();
|
||||
}
|
||||
catch (final SQLException e)
|
||||
{
|
||||
_log.warning("Lottery: Could not store new lottery data: " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class stopSellingTickets implements Runnable
|
||||
{
|
||||
protected stopSellingTickets()
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.info("Lottery: Stopping ticket sell for lottery #" + getId() + ".");
|
||||
}
|
||||
_isSellingTickets = false;
|
||||
|
||||
Announcements.getInstance().announceToAll(new SystemMessage(783));
|
||||
}
|
||||
}
|
||||
|
||||
private class finishLottery implements Runnable
|
||||
{
|
||||
protected finishLottery()
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.info("Lottery: Ending lottery #" + getId() + ".");
|
||||
}
|
||||
|
||||
final int[] luckynums = new int[5];
|
||||
int luckynum = 0;
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
boolean found = true;
|
||||
|
||||
while (found)
|
||||
{
|
||||
luckynum = Rnd.get(20) + 1;
|
||||
found = false;
|
||||
|
||||
for (int j = 0; j < i; j++)
|
||||
{
|
||||
if (luckynums[j] == luckynum)
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
luckynums[i] = luckynum;
|
||||
}
|
||||
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.info("Lottery: The lucky numbers are " + luckynums[0] + ", " + luckynums[1] + ", " + luckynums[2] + ", " + luckynums[3] + ", " + luckynums[4] + ".");
|
||||
}
|
||||
|
||||
int enchant = 0;
|
||||
int type2 = 0;
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
if (luckynums[i] < 17)
|
||||
{
|
||||
enchant += Math.pow(2, luckynums[i] - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
type2 += Math.pow(2, luckynums[i] - 17);
|
||||
}
|
||||
}
|
||||
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.info("Lottery: Encoded lucky numbers are " + enchant + ", " + type2);
|
||||
}
|
||||
|
||||
int count1 = 0;
|
||||
int count2 = 0;
|
||||
int count3 = 0;
|
||||
int count4 = 0;
|
||||
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement(SELECT_LOTTERY_ITEM))
|
||||
{
|
||||
statement.setInt(1, getId());
|
||||
try (ResultSet rset = statement.executeQuery())
|
||||
{
|
||||
while (rset.next())
|
||||
{
|
||||
int curenchant = rset.getInt("enchant_level") & enchant;
|
||||
int curtype2 = rset.getInt("custom_type2") & type2;
|
||||
|
||||
if ((curenchant == 0) && (curtype2 == 0))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
|
||||
for (int i = 1; i <= 16; i++)
|
||||
{
|
||||
final int val = curenchant / 2;
|
||||
|
||||
if (val != ((double) curenchant / 2))
|
||||
{
|
||||
count++;
|
||||
}
|
||||
|
||||
final int val2 = curtype2 / 2;
|
||||
|
||||
if (val2 != ((double) curtype2 / 2))
|
||||
{
|
||||
count++;
|
||||
}
|
||||
|
||||
curenchant = val;
|
||||
curtype2 = val2;
|
||||
}
|
||||
|
||||
if (count == 5)
|
||||
{
|
||||
count1++;
|
||||
}
|
||||
else if (count == 4)
|
||||
{
|
||||
count2++;
|
||||
}
|
||||
else if (count == 3)
|
||||
{
|
||||
count3++;
|
||||
}
|
||||
else if (count > 0)
|
||||
{
|
||||
count4++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (final SQLException e)
|
||||
{
|
||||
_log.warning("Lottery: Could restore lottery data: " + e);
|
||||
}
|
||||
|
||||
final int prize4 = count4 * Config.ALT_LOTTERY_2_AND_1_NUMBER_PRIZE;
|
||||
int prize1 = 0;
|
||||
int prize2 = 0;
|
||||
int prize3 = 0;
|
||||
|
||||
if (count1 > 0)
|
||||
{
|
||||
prize1 = (int) (((getPrize() - prize4) * Config.ALT_LOTTERY_5_NUMBER_RATE) / count1);
|
||||
}
|
||||
|
||||
if (count2 > 0)
|
||||
{
|
||||
prize2 = (int) (((getPrize() - prize4) * Config.ALT_LOTTERY_4_NUMBER_RATE) / count2);
|
||||
}
|
||||
|
||||
if (count3 > 0)
|
||||
{
|
||||
prize3 = (int) (((getPrize() - prize4) * Config.ALT_LOTTERY_3_NUMBER_RATE) / count3);
|
||||
}
|
||||
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.info("Lottery: " + count1 + " players with all FIVE numbers each win " + prize1 + ".");
|
||||
_log.info("Lottery: " + count2 + " players with FOUR numbers each win " + prize2 + ".");
|
||||
_log.info("Lottery: " + count3 + " players with THREE numbers each win " + prize3 + ".");
|
||||
_log.info("Lottery: " + count4 + " players with ONE or TWO numbers each win " + prize4 + ".");
|
||||
}
|
||||
|
||||
final int newprize = getPrize() - (prize1 + prize2 + prize3 + prize4);
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.info("Lottery: Jackpot for next lottery is " + newprize + ".");
|
||||
}
|
||||
|
||||
SystemMessage sm;
|
||||
if (count1 > 0)
|
||||
{
|
||||
// There are winners.
|
||||
sm = new SystemMessage(1112);
|
||||
sm.addNumber(getId());
|
||||
sm.addNumber(getPrize());
|
||||
sm.addNumber(count1);
|
||||
Announcements.getInstance().announceToAll(sm);
|
||||
}
|
||||
else
|
||||
{
|
||||
// There are no winners.
|
||||
sm = new SystemMessage(1113);
|
||||
sm.addNumber(getId());
|
||||
sm.addNumber(getPrize());
|
||||
Announcements.getInstance().announceToAll(sm);
|
||||
}
|
||||
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement(UPDATE_LOTTERY))
|
||||
{
|
||||
statement.setInt(1, getPrize());
|
||||
statement.setInt(2, newprize);
|
||||
statement.setInt(3, enchant);
|
||||
statement.setInt(4, type2);
|
||||
statement.setInt(5, prize1);
|
||||
statement.setInt(6, prize2);
|
||||
statement.setInt(7, prize3);
|
||||
statement.setInt(8, getId());
|
||||
statement.execute();
|
||||
}
|
||||
catch (final SQLException e)
|
||||
{
|
||||
_log.warning("Lottery: Could not store finished lottery data: " + e);
|
||||
}
|
||||
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new startLottery(), MINUTE);
|
||||
_number++;
|
||||
|
||||
_isStarted = false;
|
||||
}
|
||||
}
|
||||
|
||||
public int[] decodeNumbers(int enchant, int type2)
|
||||
{
|
||||
final int res[] = new int[5];
|
||||
int id = 0;
|
||||
int nr = 1;
|
||||
|
||||
while (enchant > 0)
|
||||
{
|
||||
final int val = enchant / 2;
|
||||
if (val != ((double) enchant / 2))
|
||||
{
|
||||
res[id] = nr;
|
||||
id++;
|
||||
}
|
||||
enchant /= 2;
|
||||
nr++;
|
||||
}
|
||||
|
||||
nr = 17;
|
||||
|
||||
while (type2 > 0)
|
||||
{
|
||||
final int val = type2 / 2;
|
||||
if (val != ((double) type2 / 2))
|
||||
{
|
||||
res[id] = nr;
|
||||
id++;
|
||||
}
|
||||
type2 /= 2;
|
||||
nr++;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public int[] checkTicket(L2ItemInstance item)
|
||||
{
|
||||
return checkTicket(item.getCustomType1(), item.getEnchantLevel(), item.getCustomType2());
|
||||
}
|
||||
|
||||
public int[] checkTicket(int id, int enchant, int type2)
|
||||
{
|
||||
final int res[] =
|
||||
{
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement(SELECT_LOTTERY_TICKET))
|
||||
{
|
||||
statement.setInt(1, id);
|
||||
try (ResultSet rset = statement.executeQuery())
|
||||
{
|
||||
if (rset.next())
|
||||
{
|
||||
int curenchant = rset.getInt("number1") & enchant;
|
||||
int curtype2 = rset.getInt("number2") & type2;
|
||||
|
||||
if ((curenchant == 0) && (curtype2 == 0))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
|
||||
for (int i = 1; i <= 16; i++)
|
||||
{
|
||||
final int val = curenchant / 2;
|
||||
if (val != ((double) curenchant / 2))
|
||||
{
|
||||
count++;
|
||||
}
|
||||
final int val2 = curtype2 / 2;
|
||||
if (val2 != ((double) curtype2 / 2))
|
||||
{
|
||||
count++;
|
||||
}
|
||||
curenchant = val;
|
||||
curtype2 = val2;
|
||||
}
|
||||
|
||||
switch (count)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 5:
|
||||
res[0] = 1;
|
||||
res[1] = rset.getInt("prize1");
|
||||
break;
|
||||
case 4:
|
||||
res[0] = 2;
|
||||
res[1] = rset.getInt("prize2");
|
||||
break;
|
||||
case 3:
|
||||
res[0] = 3;
|
||||
res[1] = rset.getInt("prize3");
|
||||
break;
|
||||
default:
|
||||
res[0] = 4;
|
||||
res[1] = 200;
|
||||
}
|
||||
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.warning("count: " + count + ", id: " + id + ", enchant: " + enchant + ", type2: " + type2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (final SQLException e)
|
||||
{
|
||||
_log.warning("Lottery: Could not check lottery ticket #" + id + ": " + e);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user