Chronicle 4 branch.

This commit is contained in:
MobiusDev
2017-07-19 21:24:06 +00:00
parent 9a69bec286
commit 3a0bf3539a
13496 changed files with 641683 additions and 0 deletions

View File

@@ -0,0 +1,846 @@
/*
* 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.model;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.List;
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.SevenSigns;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.model.actor.instance.L2NpcInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2SiegeGuardInstance;
import com.l2jmobius.gameserver.network.serverpackets.CreatureSay;
import com.l2jmobius.util.Rnd;
import javolution.util.FastList;
import javolution.util.FastMap;
/**
* Auto Chat Handler Allows NPCs to automatically send messages to nearby players at a set time interval.
* @author Tempy
*/
public class AutoChatHandler implements SpawnListener
{
protected static Logger _log = Logger.getLogger(AutoChatHandler.class.getName());
private static AutoChatHandler _instance;
private static final long DEFAULT_CHAT_DELAY = 30000; // 30 secs by default
protected Map<Integer, AutoChatInstance> _registeredChats;
protected AutoChatHandler()
{
_registeredChats = new FastMap<>();
restoreChatData();
L2Spawn.addSpawnListener(this);
}
private void restoreChatData()
{
int numLoaded = 0;
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("SELECT * FROM auto_chat ORDER BY groupId ASC");
ResultSet rs = statement.executeQuery())
{
while (rs.next())
{
numLoaded++;
try (PreparedStatement statement2 = con.prepareStatement("SELECT * FROM auto_chat_text WHERE groupId=?"))
{
statement2.setInt(1, rs.getInt("groupId"));
try (ResultSet rs2 = statement2.executeQuery())
{
rs2.last();
final String[] chatTexts = new String[rs2.getRow()];
int i = 0;
rs2.first();
while (rs2.next())
{
chatTexts[i] = rs2.getString("chatText");
i++;
}
registerGlobalChat(rs.getInt("npcId"), chatTexts, rs.getLong("chatDelay"));
}
}
}
if (Config.DEBUG)
{
_log.config("AutoChatHandler: Loaded " + numLoaded + " chat group(s) from the database.");
}
}
catch (final Exception e)
{
_log.warning("AutoSpawnHandler: Could not restore chat data: " + e);
}
}
public static AutoChatHandler getInstance()
{
if (_instance == null)
{
_instance = new AutoChatHandler();
}
return _instance;
}
public int size()
{
return _registeredChats.size();
}
/**
* Registers a globally active auto chat for ALL instances of the given NPC ID. <BR>
* Returns the associated auto chat instance.
* @param npcId
* @param chatTexts
* @param chatDelay (-1 = default delay)
* @return AutoChatInstance chatInst
*/
public AutoChatInstance registerGlobalChat(int npcId, String[] chatTexts, long chatDelay)
{
return registerChat(npcId, null, chatTexts, chatDelay);
}
/**
* Registers a NON globally-active auto chat for the given NPC instance, and adds to the currently assigned chat instance for this NPC ID, otherwise creates a new instance if a previous one is not found. <BR>
* Returns the associated auto chat instance.
* @param npcInst
* @param chatTexts
* @param chatDelay (-1 = default delay)
* @return AutoChatInstance chatInst
*/
public AutoChatInstance registerChat(L2NpcInstance npcInst, String[] chatTexts, long chatDelay)
{
return registerChat(npcInst.getNpcId(), npcInst, chatTexts, chatDelay);
}
private final AutoChatInstance registerChat(int npcId, L2NpcInstance npcInst, String[] chatTexts, long chatDelay)
{
AutoChatInstance chatInst = null;
if (chatDelay < 0)
{
chatDelay = DEFAULT_CHAT_DELAY;
}
if (_registeredChats.containsKey(npcId))
{
chatInst = _registeredChats.get(npcId);
}
else
{
chatInst = new AutoChatInstance(npcId, chatTexts, chatDelay, (npcInst == null));
}
if (npcInst != null)
{
chatInst.addChatDefinition(npcInst);
}
_registeredChats.put(npcId, chatInst);
return chatInst;
}
/**
* Removes and cancels ALL auto chat definition for the given NPC ID, and removes its chat instance if it exists.
* @param npcId
* @return boolean removedSuccessfully
*/
public boolean removeChat(int npcId)
{
final AutoChatInstance chatInst = _registeredChats.get(npcId);
return removeChat(chatInst);
}
/**
* Removes and cancels ALL auto chats for the given chat instance.
* @param chatInst
* @return boolean removedSuccessfully
*/
public boolean removeChat(AutoChatInstance chatInst)
{
if (chatInst == null)
{
return false;
}
_registeredChats.remove(chatInst);
chatInst.setActive(false);
if (Config.DEBUG)
{
_log.config("AutoChatHandler: Removed auto chat for NPC ID " + chatInst.getNPCId());
}
return true;
}
/**
* Returns the associated auto chat instance either by the given NPC ID or object ID.
* @param id
* @param byObjectId
* @return AutoChatInstance chatInst
*/
public AutoChatInstance getAutoChatInstance(int id, boolean byObjectId)
{
if (!byObjectId)
{
return _registeredChats.get(id);
}
for (final AutoChatInstance chatInst : _registeredChats.values())
{
if (chatInst.getChatDefinition(id) != null)
{
return chatInst;
}
}
return null;
}
/**
* Sets the active state of all auto chat instances to that specified, and cancels the scheduled chat task if necessary.
* @param isActive
*/
public void setAutoChatActive(boolean isActive)
{
for (final AutoChatInstance chatInst : _registeredChats.values())
{
chatInst.setActive(isActive);
}
}
/**
* Used in conjunction with a SpawnListener, this method is called every time an NPC is spawned in the world. <BR>
* <BR>
* If an auto chat instance is set to be "global", all instances matching the registered NPC ID will be added to that chat instance.
*/
@Override
public void npcSpawned(L2NpcInstance npc)
{
synchronized (_registeredChats)
{
if (npc == null)
{
return;
}
final int npcId = npc.getNpcId();
if (_registeredChats.containsKey(npcId))
{
final AutoChatInstance chatInst = _registeredChats.get(npcId);
if ((chatInst != null) && chatInst.isGlobal())
{
chatInst.addChatDefinition(npc);
}
}
}
}
/**
* Auto Chat Instance <BR>
* <BR>
* Manages the auto chat instances for a specific registered NPC ID.
* @author Tempy
*/
public class AutoChatInstance
{
protected int _npcId;
private long _defaultDelay = DEFAULT_CHAT_DELAY;
private String[] _defaultTexts;
private boolean _defaultRandom = false;
private boolean _globalChat = false;
private boolean _isActive;
private final Map<Integer, AutoChatDefinition> _chatDefinitions = new FastMap<>();
public ScheduledFuture<?> _chatTask;
protected AutoChatInstance(int npcId, String[] chatTexts, long chatDelay, boolean isGlobal)
{
_defaultTexts = chatTexts;
_npcId = npcId;
_defaultDelay = chatDelay;
_globalChat = isGlobal;
if (Config.DEBUG)
{
_log.config("AutoChatHandler: Registered auto chat for NPC ID " + _npcId + " (Global Chat = " + _globalChat + ").");
}
setActive(true);
}
protected AutoChatDefinition getChatDefinition(int objectId)
{
return _chatDefinitions.get(objectId);
}
protected AutoChatDefinition[] getChatDefinitions()
{
return _chatDefinitions.values().toArray(new AutoChatDefinition[_chatDefinitions.values().size()]);
}
/**
* Defines an auto chat for an instance matching this auto chat instance's registered NPC ID, and launches the scheduled chat task. <BR>
* Returns the object ID for the NPC instance, with which to refer to the created chat definition. <BR>
* <B>Note</B>: Uses pre-defined default values for texts and chat delays from the chat instance.
* @param npcInst
* @return int objectId
*/
public int addChatDefinition(L2NpcInstance npcInst)
{
return addChatDefinition(npcInst, null, 0);
}
/**
* Defines an auto chat for an instance matching this auto chat instance's registered NPC ID, and launches the scheduled chat task. <BR>
* Returns the object ID for the NPC instance, with which to refer to the created chat definition.
* @param npcInst
* @param chatTexts
* @param chatDelay
* @return int objectId
*/
public int addChatDefinition(L2NpcInstance npcInst, String[] chatTexts, long chatDelay)
{
final int objectId = npcInst.getObjectId();
final AutoChatDefinition chatDef = new AutoChatDefinition(this, npcInst, chatTexts, chatDelay);
if (npcInst instanceof L2SiegeGuardInstance)
{
chatDef.setRandomChat(true);
}
_chatDefinitions.put(objectId, chatDef);
return objectId;
}
/**
* Removes a chat definition specified by the given object ID.
* @param objectId
* @return boolean removedSuccessfully
*/
public boolean removeChatDefinition(int objectId)
{
if (!_chatDefinitions.containsKey(objectId))
{
return false;
}
final AutoChatDefinition chatDefinition = _chatDefinitions.get(objectId);
chatDefinition.setActive(false);
_chatDefinitions.remove(objectId);
return true;
}
/**
* Tests if this auto chat instance is active.
* @return boolean isActive
*/
public boolean isActive()
{
return _isActive;
}
/**
* Tests if this auto chat instance applies to ALL currently spawned instances of the registered NPC ID.
* @return boolean isGlobal
*/
public boolean isGlobal()
{
return _globalChat;
}
/**
* Tests if random order is the DEFAULT for new chat definitions.
* @return boolean isRandom
*/
public boolean isDefaultRandom()
{
return _defaultRandom;
}
/**
* Tests if the auto chat definition given by its object ID is set to be random.
* @param objectId
* @return boolean isRandom
*/
public boolean isRandomChat(int objectId)
{
if (!_chatDefinitions.containsKey(objectId))
{
return false;
}
return _chatDefinitions.get(objectId).isRandomChat();
}
/**
* Returns the ID of the NPC type managed by this auto chat instance.
* @return int npcId
*/
public int getNPCId()
{
return _npcId;
}
/**
* Returns the number of auto chat definitions stored for this instance.
* @return int definitionCount
*/
public int getDefinitionCount()
{
return _chatDefinitions.size();
}
/**
* Returns a list of all NPC instances handled by this auto chat instance.
* @return L2NpcInstance[] npcInsts
*/
public L2NpcInstance[] getNPCInstanceList()
{
final List<L2NpcInstance> npcInsts = new FastList<>();
for (final AutoChatDefinition chatDefinition : _chatDefinitions.values())
{
npcInsts.add(chatDefinition._npcInstance);
}
return npcInsts.toArray(new L2NpcInstance[npcInsts.size()]);
}
/**
* A series of methods used to get and set default values for new chat definitions.
* @return
*/
public long getDefaultDelay()
{
return _defaultDelay;
}
public String[] getDefaultTexts()
{
return _defaultTexts;
}
public void setDefaultChatDelay(long delayValue)
{
_defaultDelay = delayValue;
}
public void setDefaultChatTexts(String[] textsValue)
{
_defaultTexts = textsValue;
}
public void setDefaultRandom(boolean randValue)
{
_defaultRandom = randValue;
}
/**
* Sets a specific chat delay for the specified auto chat definition given by its object ID.
* @param objectId
* @param delayValue
*/
public void setChatDelay(int objectId, long delayValue)
{
final AutoChatDefinition chatDef = getChatDefinition(objectId);
if (chatDef != null)
{
chatDef.setChatDelay(delayValue);
}
}
/**
* Sets a specific set of chat texts for the specified auto chat definition given by its object ID.
* @param objectId
* @param textsValue
*/
public void setChatTexts(int objectId, String[] textsValue)
{
final AutoChatDefinition chatDef = getChatDefinition(objectId);
if (chatDef != null)
{
chatDef.setChatTexts(textsValue);
}
}
/**
* Sets specifically to use random chat order for the auto chat definition given by its object ID.
* @param objectId
* @param randValue
*/
public void setRandomChat(int objectId, boolean randValue)
{
final AutoChatDefinition chatDef = getChatDefinition(objectId);
if (chatDef != null)
{
chatDef.setRandomChat(randValue);
}
}
/**
* Sets the activity of ALL auto chat definitions handled by this chat instance.
* @param activeValue
*/
public void setActive(boolean activeValue)
{
if (_isActive == activeValue)
{
return;
}
_isActive = activeValue;
if (!isGlobal())
{
for (final AutoChatDefinition chatDefinition : _chatDefinitions.values())
{
chatDefinition.setActive(activeValue);
}
return;
}
if (isActive())
{
final AutoChatRunner acr = new AutoChatRunner(_npcId, -1);
_chatTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(acr, _defaultDelay, _defaultDelay);
}
else
{
_chatTask.cancel(false);
}
}
/**
* Auto Chat Definition <BR>
* <BR>
* Stores information about specific chat data for an instance of the NPC ID specified by the containing auto chat instance. <BR>
* Each NPC instance of this type should be stored in a subsequent AutoChatDefinition class.
* @author Tempy
*/
private class AutoChatDefinition
{
protected int _chatIndex = 0;
protected L2NpcInstance _npcInstance;
protected AutoChatInstance _chatInstance;
private long _chatDelay = 0;
private String[] _chatTexts = null;
private boolean isActive;
private boolean _randomChat;
protected AutoChatDefinition(AutoChatInstance chatInst, L2NpcInstance npcInst, String[] chatTexts, long chatDelay)
{
_npcInstance = npcInst;
_chatInstance = chatInst;
_randomChat = chatInst.isDefaultRandom();
_chatDelay = chatDelay;
_chatTexts = chatTexts;
if (Config.DEBUG)
{
_log.info("AutoChatHandler: Chat definition added for NPC ID " + _npcInstance.getNpcId() + " (Object ID = " + _npcInstance.getObjectId() + ").");
}
// If global chat isn't enabled for the parent instance,
// then handle the chat task locally.
if (!chatInst.isGlobal())
{
setActive(true);
}
}
protected String[] getChatTexts()
{
if (_chatTexts != null)
{
return _chatTexts;
}
return _chatInstance.getDefaultTexts();
}
private long getChatDelay()
{
if (_chatDelay > 0)
{
return _chatDelay;
}
return _chatInstance.getDefaultDelay();
}
private boolean isActive()
{
return isActive;
}
boolean isRandomChat()
{
return _randomChat;
}
void setRandomChat(boolean randValue)
{
_randomChat = randValue;
}
void setChatDelay(long delayValue)
{
_chatDelay = delayValue;
}
void setChatTexts(String[] textsValue)
{
_chatTexts = textsValue;
}
void setActive(boolean activeValue)
{
if (isActive() == activeValue)
{
return;
}
if (activeValue)
{
final AutoChatRunner acr = new AutoChatRunner(_npcId, _npcInstance.getObjectId());
if (getChatDelay() == 0)
{
_chatTask = ThreadPoolManager.getInstance().scheduleGeneral(acr, 5);
}
else
{
_chatTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(acr, getChatDelay(), getChatDelay());
}
}
else
{
_chatTask.cancel(false);
}
isActive = activeValue;
}
}
/**
* Auto Chat Runner <BR>
* <BR>
* Represents the auto chat scheduled task for each chat instance.
* @author Tempy
*/
private class AutoChatRunner implements Runnable
{
protected int npcId;
private final int objectId;
protected AutoChatRunner(int pNpcId, int pObjectId)
{
npcId = pNpcId;
objectId = pObjectId;
}
@Override
public synchronized void run()
{
final AutoChatInstance chatInst = _registeredChats.get(npcId);
AutoChatDefinition[] chatDefinitions;
if (chatInst.isGlobal())
{
chatDefinitions = chatInst.getChatDefinitions();
}
else
{
final AutoChatDefinition chatDef = chatInst.getChatDefinition(objectId);
if (chatDef == null)
{
_log.warning("AutoChatHandler: Auto chat definition is NULL for NPC ID " + _npcId + ".");
return;
}
chatDefinitions = new AutoChatDefinition[]
{
chatDef
};
}
if (Config.DEBUG)
{
_log.info("AutoChatHandler: Running auto chat for " + chatDefinitions.length + " instances of NPC ID " + _npcId + "." + " (Global Chat = " + chatInst.isGlobal() + ")");
}
for (final AutoChatDefinition chatDef : chatDefinitions)
{
try
{
final L2NpcInstance chatNpc = chatDef._npcInstance;
final List<L2PcInstance> nearbyPlayers = new FastList<>();
final List<L2PcInstance> nearbyGMs = new FastList<>();
for (final L2Character player : chatNpc.getKnownList().getKnownCharactersInRadius(1500))
{
if (!(player instanceof L2PcInstance))
{
continue;
}
if (((L2PcInstance) player).isGM())
{
nearbyGMs.add((L2PcInstance) player);
}
else
{
nearbyPlayers.add((L2PcInstance) player);
}
}
final int maxIndex = chatDef.getChatTexts().length;
int lastIndex = Rnd.nextInt(maxIndex);
final String creatureName = chatNpc.getName();
String text;
if (!chatDef.isRandomChat())
{
lastIndex = chatDef._chatIndex;
lastIndex++;
if (lastIndex == maxIndex)
{
lastIndex = 0;
}
chatDef._chatIndex = lastIndex;
}
text = chatDef.getChatTexts()[lastIndex];
if (text == null)
{
return;
}
if (!nearbyPlayers.isEmpty())
{
final int randomPlayerIndex = Rnd.nextInt(nearbyPlayers.size());
final L2PcInstance randomPlayer = nearbyPlayers.get(randomPlayerIndex);
final int winningCabal = SevenSigns.getInstance().getCabalHighestScore();
int losingCabal = SevenSigns.CABAL_NULL;
if (winningCabal == SevenSigns.CABAL_DAWN)
{
losingCabal = SevenSigns.CABAL_DUSK;
}
else if (winningCabal == SevenSigns.CABAL_DUSK)
{
losingCabal = SevenSigns.CABAL_DAWN;
}
if (text.indexOf("%player_random%") > -1)
{
text = text.replaceAll("%player_random%", randomPlayer.getName());
}
if (text.indexOf("%player_cabal_winner%") > -1)
{
for (final L2PcInstance nearbyPlayer : nearbyPlayers)
{
if (SevenSigns.getInstance().getPlayerCabal(nearbyPlayer) == winningCabal)
{
text = text.replaceAll("%player_cabal_winner%", nearbyPlayer.getName());
break;
}
}
}
if (text.indexOf("%player_cabal_loser%") > -1)
{
for (final L2PcInstance nearbyPlayer : nearbyPlayers)
{
if (SevenSigns.getInstance().getPlayerCabal(nearbyPlayer) == losingCabal)
{
text = text.replaceAll("%player_cabal_loser%", nearbyPlayer.getName());
break;
}
}
}
}
if (text == null)
{
return;
}
if (text.contains("%player_cabal_loser%") || text.contains("%player_cabal_winner%") || text.contains("%player_random%"))
{
return;
}
final CreatureSay cs = new CreatureSay(chatNpc.getObjectId(), 0, creatureName, text);
for (final L2PcInstance nearbyPlayer : nearbyPlayers)
{
nearbyPlayer.sendPacket(cs);
}
for (final L2PcInstance nearbyGM : nearbyGMs)
{
nearbyGM.sendPacket(cs);
}
if (Config.DEBUG)
{
_log.fine("AutoChatHandler: Chat propogation for object ID " + chatNpc.getObjectId() + " (" + creatureName + ") with text '" + text + "' sent to " + nearbyPlayers.size() + " nearby players.");
}
}
catch (final Exception e)
{
e.printStackTrace();
return;
}
}
}
}
}
}

View File

@@ -0,0 +1,740 @@
/*
* 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.model;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
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.datatables.MapRegionTable;
import com.l2jmobius.gameserver.datatables.NpcTable;
import com.l2jmobius.gameserver.datatables.SpawnTable;
import com.l2jmobius.gameserver.idfactory.IdFactory;
import com.l2jmobius.gameserver.model.actor.instance.L2NpcInstance;
import com.l2jmobius.gameserver.templates.L2NpcTemplate;
import com.l2jmobius.util.Rnd;
import javolution.util.FastList;
import javolution.util.FastMap;
/**
* Auto Spawn Handler Allows spawning of a NPC object based on a timer. (From the official idea used for the Merchant and Blacksmith of Mammon) General Usage: - Call registerSpawn() with the parameters listed below. int npcId int[][] spawnPoints or specify NULL to add points later. int initialDelay
* (If < 0 = default value) int respawnDelay (If < 0 = default value) int despawnDelay (If < 0 = default value or if = 0, function disabled) spawnPoints is a standard two-dimensional int array containing X,Y and Z coordinates. The default respawn/despawn delays are currently every hour (as for
* Mammon on official servers). - The resulting AutoSpawnInstance object represents the newly added spawn index. - The interal methods of this object can be used to adjust random spawning, for instance a call to setRandomSpawn(1, true); would set the spawn at index 1 to be randomly rather than
* sequentially-based. - Also they can be used to specify the number of NPC instances to spawn using setSpawnCount(), and broadcast a message to all users using setBroadcast(). Random Spawning = OFF by default Broadcasting = OFF by default
* @author Tempy
*/
public class AutoSpawnHandler
{
protected static Logger _log = Logger.getLogger(AutoSpawnHandler.class.getName());
private static AutoSpawnHandler _instance;
private static final int DEFAULT_INITIAL_SPAWN = 30000; // 30 seconds after registration
private static final int DEFAULT_RESPAWN = 3600000; // 1 hour in millisecs
private static final int DEFAULT_DESPAWN = 3600000; // 1 hour in millisecs
protected Map<Integer, AutoSpawnInstance> _registeredSpawns;
protected Map<Integer, ScheduledFuture<?>> _runningSpawns;
protected boolean _activeState = true;
public AutoSpawnHandler()
{
_registeredSpawns = new FastMap<>();
_runningSpawns = new FastMap<>();
restoreSpawnData();
}
public static AutoSpawnHandler getInstance()
{
if (_instance == null)
{
_instance = new AutoSpawnHandler();
}
return _instance;
}
public final int size()
{
return _registeredSpawns.size();
}
private void restoreSpawnData()
{
int numLoaded = 0;
// Restore spawn group data, then the location data.
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("SELECT * FROM random_spawn ORDER BY groupId ASC");
ResultSet rs = statement.executeQuery())
{
while (rs.next())
{
// Register random spawn group, set various options on the created spawn instance.
final AutoSpawnInstance spawnInst = registerSpawn(rs.getInt("npcId"), rs.getInt("initialDelay"), rs.getInt("respawnDelay"), rs.getInt("despawnDelay"));
spawnInst.setSpawnCount(rs.getInt("count"));
spawnInst.setBroadcast(rs.getBoolean("broadcastSpawn"));
spawnInst.setRandomSpawn(rs.getBoolean("randomSpawn"));
numLoaded++;
// Restore the spawn locations for this spawn group/instance.
try (PreparedStatement statement2 = con.prepareStatement("SELECT * FROM random_spawn_loc WHERE groupId=?"))
{
statement2.setInt(1, rs.getInt("groupId"));
try (ResultSet rs2 = statement2.executeQuery())
{
while (rs2.next())
{
// Add each location to the spawn group/instance.
spawnInst.addSpawnLocation(rs2.getInt("x"), rs2.getInt("y"), rs2.getInt("z"), rs2.getInt("heading"));
}
}
}
}
if (Config.DEBUG)
{
_log.config("AutoSpawnHandler: Loaded " + numLoaded + " spawn group(s) from the database.");
}
}
catch (final Exception e)
{
_log.warning("AutoSpawnHandler: Could not restore spawn data: " + e);
}
}
/**
* Registers a spawn with the given parameters with the spawner, and marks it as active. Returns a AutoSpawnInstance containing info about the spawn.
* @param npcId
* @param spawnPoints
* @param initialDelay (If < 0 = default value)
* @param respawnDelay (If < 0 = default value)
* @param despawnDelay (If < 0 = default value or if = 0, function disabled)
* @return AutoSpawnInstance spawnInst
*/
public AutoSpawnInstance registerSpawn(int npcId, int[][] spawnPoints, int initialDelay, int respawnDelay, int despawnDelay)
{
if (initialDelay < 0)
{
initialDelay = DEFAULT_INITIAL_SPAWN;
}
if (respawnDelay < 0)
{
respawnDelay = DEFAULT_RESPAWN;
}
if (despawnDelay < 0)
{
despawnDelay = DEFAULT_DESPAWN;
}
final AutoSpawnInstance newSpawn = new AutoSpawnInstance(npcId, initialDelay, respawnDelay, despawnDelay);
if (spawnPoints != null)
{
for (final int[] spawnPoint : spawnPoints)
{
newSpawn.addSpawnLocation(spawnPoint);
}
}
final int newId = IdFactory.getInstance().getNextId();
newSpawn._objectId = newId;
_registeredSpawns.put(newId, newSpawn);
setSpawnActive(newSpawn, true);
if (Config.DEBUG)
{
_log.config("AutoSpawnHandler: Registered auto spawn for NPC ID " + npcId + " (Object ID = " + newId + ").");
}
return newSpawn;
}
/**
* Registers a spawn with the given parameters with the spawner, and marks it as active. Returns a AutoSpawnInstance containing info about the spawn. <BR>
* <B>Warning:</B> Spawn locations must be specified separately using addSpawnLocation().
* @param npcId
* @param initialDelay (If < 0 = default value)
* @param respawnDelay (If < 0 = default value)
* @param despawnDelay (If < 0 = default value or if = 0, function disabled)
* @return AutoSpawnInstance spawnInst
*/
public AutoSpawnInstance registerSpawn(int npcId, int initialDelay, int respawnDelay, int despawnDelay)
{
return registerSpawn(npcId, null, initialDelay, respawnDelay, despawnDelay);
}
/**
* Remove a registered spawn from the list, specified by the given spawn instance.
* @param spawnInst
* @return boolean removedSuccessfully
*/
public boolean removeSpawn(AutoSpawnInstance spawnInst)
{
if (!isSpawnRegistered(spawnInst))
{
return false;
}
try
{
// Try to remove from the list of registered spawns if it exists.
_registeredSpawns.remove(spawnInst);
// Cancel the currently associated running scheduled task.
final ScheduledFuture<?> respawnTask = _runningSpawns.remove(spawnInst._objectId);
respawnTask.cancel(false);
if (Config.DEBUG)
{
_log.config("AutoSpawnHandler: Removed auto spawn for NPC ID " + spawnInst._npcId + " (Object ID = " + spawnInst._objectId + ").");
}
}
catch (final Exception e)
{
_log.warning("AutoSpawnHandler: Could not auto spawn for NPC ID " + spawnInst._npcId + " (Object ID = " + spawnInst._objectId + "): " + e);
return false;
}
return true;
}
/**
* Remove a registered spawn from the list, specified by the given spawn object ID.
* @param objectId
*/
public void removeSpawn(int objectId)
{
removeSpawn(_registeredSpawns.get(objectId));
}
/**
* Sets the active state of the specified spawn.
* @param spawnInst
* @param isActive
*/
public void setSpawnActive(AutoSpawnInstance spawnInst, boolean isActive)
{
if (spawnInst == null)
{
return;
}
final int objectId = spawnInst._objectId;
if (isSpawnRegistered(objectId))
{
ScheduledFuture<?> spawnTask = null;
if (isActive)
{
final AutoSpawner rs = new AutoSpawner(objectId);
if (spawnInst._desDelay > 0)
{
spawnTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(rs, spawnInst._initDelay, spawnInst._resDelay);
}
else
{
spawnTask = ThreadPoolManager.getInstance().scheduleEffect(rs, spawnInst._initDelay);
}
_runningSpawns.put(objectId, spawnTask);
}
else
{
final AutoDespawner rd = new AutoDespawner(objectId);
spawnTask = _runningSpawns.remove(objectId);
if (spawnTask != null)
{
spawnTask.cancel(false);
}
ThreadPoolManager.getInstance().scheduleEffect(rd, 0);
}
spawnInst.setSpawnActive(isActive);
}
}
/**
* Sets the active state of all auto spawn instances to that specified, and cancels the scheduled spawn task if necessary.
* @param isActive
*/
public void setAllActive(boolean isActive)
{
if (_activeState == isActive)
{
return;
}
for (final AutoSpawnInstance spawnInst : _registeredSpawns.values())
{
setSpawnActive(spawnInst, isActive);
}
_activeState = isActive;
}
/**
* Returns the number of milliseconds until the next occurrance of the given spawn.
* @param spawnInst
* @return
*/
public final long getTimeToNextSpawn(AutoSpawnInstance spawnInst)
{
final int objectId = spawnInst.getObjectId();
if (!isSpawnRegistered(objectId))
{
return -1;
}
return _runningSpawns.get(objectId).getDelay(TimeUnit.MILLISECONDS);
}
/**
* Attempts to return the AutoSpawnInstance associated with the given NPC or Object ID type. <BR>
* Note: If isObjectId == false, returns first instance for the specified NPC ID.
* @param id
* @param isObjectId
* @return AutoSpawnInstance spawnInst
*/
public final AutoSpawnInstance getAutoSpawnInstance(int id, boolean isObjectId)
{
if (isObjectId)
{
if (isSpawnRegistered(id))
{
return _registeredSpawns.get(id);
}
}
else
{
for (final AutoSpawnInstance spawnInst : _registeredSpawns.values())
{
if (spawnInst.getNpcId() == id)
{
return spawnInst;
}
}
}
return null;
}
public Map<Integer, AutoSpawnInstance> getAutoSpawnInstances(int npcId)
{
final Map<Integer, AutoSpawnInstance> spawnInstList = new FastMap<>();
for (final AutoSpawnInstance spawnInst : _registeredSpawns.values())
{
if (spawnInst.getNpcId() == npcId)
{
spawnInstList.put(spawnInst.getObjectId(), spawnInst);
}
}
return spawnInstList;
}
/**
* Tests if the specified object ID is assigned to an auto spawn.
* @param objectId
* @return boolean isAssigned
*/
public final boolean isSpawnRegistered(int objectId)
{
return _registeredSpawns.containsKey(objectId);
}
/**
* Tests if the specified spawn instance is assigned to an auto spawn.
* @param spawnInst
* @return boolean isAssigned
*/
public final boolean isSpawnRegistered(AutoSpawnInstance spawnInst)
{
return _registeredSpawns.containsValue(spawnInst);
}
/**
* AutoSpawner Class <BR>
* <BR>
* This handles the main spawn task for an auto spawn instance, and initializes a despawner if required.
* @author Tempy
*/
private class AutoSpawner implements Runnable
{
private final int _objectId;
AutoSpawner(int objectId)
{
_objectId = objectId;
}
@Override
public void run()
{
try
{
// Retrieve the required spawn instance for this spawn task.
final AutoSpawnInstance spawnInst = _registeredSpawns.get(_objectId);
// If the spawn is not scheduled to be active, cancel the spawn task.
if (!spawnInst.isSpawnActive())
{
return;
}
final Location[] locationList = spawnInst.getLocationList();
// If there are no set co-ordinates, cancel the spawn task.
if (locationList.length == 0)
{
_log.info("AutoSpawnHandler: No location co-ords specified for spawn instance (Object ID = " + _objectId + ").");
return;
}
final int locationCount = locationList.length;
int locationIndex = Rnd.nextInt(locationCount);
/*
* If random spawning is disabled, the spawn at the next set of co-ordinates after the last. If the index is greater than the number of possible spawns, reset the counter to zero.
*/
if (!spawnInst.isRandomSpawn())
{
locationIndex = spawnInst._lastLocIndex;
locationIndex++;
if (locationIndex == locationCount)
{
locationIndex = 0;
}
spawnInst._lastLocIndex = locationIndex;
}
// Set the X, Y and Z co-ordinates, where this spawn will take place.
final int x = locationList[locationIndex].getX();
final int y = locationList[locationIndex].getY();
final int z = locationList[locationIndex].getZ();
final int heading = locationList[locationIndex].getHeading();
// Fetch the template for this NPC ID and create a new spawn.
final L2NpcTemplate npcTemp = NpcTable.getInstance().getTemplate(spawnInst.getNpcId());
if (npcTemp == null)
{
_log.warning("Couldnt find NPC id" + spawnInst.getNpcId() + " Try to update your DP");
return;
}
final L2Spawn newSpawn = new L2Spawn(npcTemp);
newSpawn.setLocx(x);
newSpawn.setLocy(y);
newSpawn.setLocz(z);
if (heading != -1)
{
newSpawn.setHeading(heading);
}
newSpawn.setAmount(spawnInst.getSpawnCount());
if (spawnInst._desDelay == 0)
{
newSpawn.setRespawnDelay(spawnInst._resDelay);
}
// Add the new spawn information to the spawn table, but do not store it.
SpawnTable.getInstance().addNewSpawn(newSpawn, false);
L2NpcInstance npcInst = null;
if (spawnInst._spawnCount == 1)
{
npcInst = newSpawn.doSpawn();
npcInst.setXYZ(npcInst.getX(), npcInst.getY(), npcInst.getZ());
spawnInst.addNpcInstance(npcInst);
}
else
{
for (int i = 0; i < spawnInst._spawnCount; i++)
{
npcInst = newSpawn.doSpawn();
// To prevent spawning of more than one NPC in the exact same spot,
// move it slightly by a small random offset.
npcInst.setXYZ(npcInst.getX() + Rnd.nextInt(50), npcInst.getY() + Rnd.nextInt(50), npcInst.getZ());
// Add the NPC instance to the list of managed instances.
spawnInst.addNpcInstance(npcInst);
}
}
final String nearestTown = MapRegionTable.getInstance().getClosestTownName(npcInst);
// Announce to all players that the spawn has taken place, with the nearest town location.
if (spawnInst.isBroadcasting() && (npcInst != null))
{
Announcements.getInstance().announceToAll("The " + npcInst.getName() + " has spawned near " + nearestTown + "!");
}
if (Config.DEBUG)
{
_log.info("AutoSpawnHandler: Spawned NPC ID " + spawnInst.getNpcId() + " at " + x + ", " + y + ", " + z + " (Near " + nearestTown + ") for " + (spawnInst.getRespawnDelay() / 60000) + " minute(s).");
}
// If there is no despawn time, do not create a despawn task.
if (spawnInst.getDespawnDelay() > 0)
{
final AutoDespawner rd = new AutoDespawner(_objectId);
ThreadPoolManager.getInstance().scheduleAi(rd, spawnInst.getDespawnDelay() - 1000);
}
}
catch (final Exception e)
{
_log.warning("AutoSpawnHandler: An error occurred while initializing spawn instance (Object ID = " + _objectId + "): " + e);
e.printStackTrace();
}
}
}
/**
* AutoDespawner Class <BR>
* <BR>
* Simply used as a secondary class for despawning an auto spawn instance.
* @author Tempy
*/
private class AutoDespawner implements Runnable
{
private final int _objectId;
AutoDespawner(int objectId)
{
_objectId = objectId;
}
@Override
public void run()
{
try
{
final AutoSpawnInstance spawnInst = _registeredSpawns.get(_objectId);
if (spawnInst == null)
{
_log.info("AutoSpawnHandler: No spawn registered for object ID = " + _objectId + ".");
return;
}
for (final L2NpcInstance npcInst : spawnInst.getNPCInstanceList())
{
if (npcInst == null)
{
continue;
}
npcInst.deleteMe();
spawnInst.removeNpcInstance(npcInst);
if (Config.DEBUG)
{
_log.info("AutoSpawnHandler: Spawns removed for spawn instance (Object ID = " + _objectId + ").");
}
}
}
catch (final Exception e)
{
_log.warning("AutoSpawnHandler: An error occurred while despawning spawn (Object ID = " + _objectId + "): " + e);
}
}
}
/**
* AutoSpawnInstance Class <BR>
* <BR>
* Stores information about a registered auto spawn.
* @author Tempy
*/
public class AutoSpawnInstance
{
protected int _objectId;
protected int _spawnIndex;
protected int _npcId;
protected int _initDelay;
protected int _resDelay;
protected int _desDelay;
protected int _spawnCount = 1;
protected int _lastLocIndex = -1;
private final List<L2NpcInstance> _npcList = new FastList<>();
private final List<Location> _locList = new FastList<>();
private boolean _spawnActive;
private boolean _randomSpawn = false;
private boolean _broadcastAnnouncement = false;
protected AutoSpawnInstance(int npcId, int initDelay, int respawnDelay, int despawnDelay)
{
_npcId = npcId;
_initDelay = initDelay;
_resDelay = respawnDelay;
_desDelay = despawnDelay;
}
protected void setSpawnActive(boolean activeValue)
{
_spawnActive = activeValue;
}
protected boolean addNpcInstance(L2NpcInstance npcInst)
{
return _npcList.add(npcInst);
}
protected boolean removeNpcInstance(L2NpcInstance npcInst)
{
return _npcList.remove(npcInst);
}
public int getObjectId()
{
return _objectId;
}
public int getInitialDelay()
{
return _initDelay;
}
public int getRespawnDelay()
{
return _resDelay;
}
public int getDespawnDelay()
{
return _desDelay;
}
public int getNpcId()
{
return _npcId;
}
public int getSpawnCount()
{
return _spawnCount;
}
public Location[] getLocationList()
{
return _locList.toArray(new Location[_locList.size()]);
}
public L2NpcInstance[] getNPCInstanceList()
{
L2NpcInstance[] ret;
synchronized (_npcList)
{
ret = new L2NpcInstance[_npcList.size()];
_npcList.toArray(ret);
}
return ret;
}
public L2Spawn[] getSpawns()
{
final List<L2Spawn> npcSpawns = new FastList<>();
for (final L2NpcInstance npcInst : _npcList)
{
npcSpawns.add(npcInst.getSpawn());
}
return npcSpawns.toArray(new L2Spawn[npcSpawns.size()]);
}
public void setSpawnCount(int spawnCount)
{
_spawnCount = spawnCount;
}
public void setRandomSpawn(boolean randValue)
{
_randomSpawn = randValue;
}
public void setBroadcast(boolean broadcastValue)
{
_broadcastAnnouncement = broadcastValue;
}
public boolean isSpawnActive()
{
return _spawnActive;
}
public boolean isRandomSpawn()
{
return _randomSpawn;
}
public boolean isBroadcasting()
{
return _broadcastAnnouncement;
}
public boolean addSpawnLocation(int x, int y, int z, int heading)
{
return _locList.add(new Location(x, y, z, heading));
}
public boolean addSpawnLocation(int[] spawnLoc)
{
if (spawnLoc.length != 3)
{
return false;
}
return addSpawnLocation(spawnLoc[0], spawnLoc[1], spawnLoc[2], -1);
}
public Location removeSpawnLocation(int locIndex)
{
try
{
return _locList.remove(locIndex);
}
catch (final IndexOutOfBoundsException e)
{
return null;
}
}
}
}

View File

@@ -0,0 +1,128 @@
/*
* 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.model;
import java.util.Set;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import javolution.util.FastSet;
/**
* This class ...
* @version $Revision: 1.2 $ $Date: 2004/06/27 08:12:59 $
*/
public class BlockList
{
private final Set<String> blockSet;
private boolean blockAll;
public BlockList()
{
blockSet = new FastSet<>();
blockAll = false;
}
private void addToBlockList(L2PcInstance character)
{
if (character != null)
{
blockSet.add(new String(character.getName()));
}
}
private void removeFromBlockList(L2PcInstance character)
{
if (character != null)
{
blockSet.remove(character.getName());
}
}
private boolean isInBlockList(L2PcInstance character)
{
return blockSet.contains(character.getName());
}
private boolean isBlockAll()
{
return blockAll;
}
public static boolean isBlocked(L2PcInstance listOwner, L2PcInstance character)
{
final BlockList blockList = listOwner.getBlockList();
return blockList.isBlockAll() || blockList.isInBlockList(character);
}
private void setBlockAll(boolean state)
{
blockAll = state;
}
private Set<String> getBlockList()
{
return blockSet;
}
public static void addToBlockList(L2PcInstance listOwner, L2PcInstance character)
{
listOwner.getBlockList().addToBlockList(character);
SystemMessage sm = new SystemMessage(SystemMessage.S1_HAS_ADDED_YOU_TO_IGNORE_LIST);
sm.addString(listOwner.getName());
character.sendPacket(sm);
sm = new SystemMessage(SystemMessage.S1_WAS_ADDED_TO_YOUR_IGNORE_LIST);
sm.addString(character.getName());
listOwner.sendPacket(sm);
}
public static void removeFromBlockList(L2PcInstance listOwner, L2PcInstance character)
{
listOwner.getBlockList().removeFromBlockList(character);
final SystemMessage sm = new SystemMessage(SystemMessage.S1_WAS_REMOVED_FROM_YOUR_IGNORE_LIST);
sm.addString(character.getName());
listOwner.sendPacket(sm);
}
public static boolean isInBlockList(L2PcInstance listOwner, L2PcInstance character)
{
return listOwner.getBlockList().isInBlockList(character);
}
public static boolean isBlockAll(L2PcInstance listOwner)
{
return listOwner.getBlockList().isBlockAll();
}
public static void setBlockAll(L2PcInstance listOwner, boolean newValue)
{
listOwner.getBlockList().setBlockAll(newValue);
}
public static void sendListToOwner(L2PcInstance listOwner)
{
for (final String playerName : listOwner.getBlockList().getBlockList())
{
listOwner.sendPacket(new SystemMessage(614).addString(playerName));
}
}
}

View File

@@ -0,0 +1,287 @@
/*
* 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.model;
/**
* Used to Store data sent to Client for Character Selection screen.
* @version $Revision: 1.2.2.2.2.4 $ $Date: 2005/03/27 15:29:33 $
*/
public class CharSelectInfoPackage
{
private String _name;
private int _objectId = 0;
private int _charId = 0x00030b7a;
private long _exp = 0;
private int _sp = 0;
private int _clanId = 0;
private int _race = 0;
private int _classId = 0;
private int _baseClassId = 0;
private long _deleteTimer = 0L;
private long _lastAccess = 0L;
private int _face = 0;
private int _hairStyle = 0;
private int _hairColor = 0;
private int _sex = 0;
private int _level = 1;
private int _maxHp = 0;
private double _currentHp = 0;
private int _maxMp = 0;
private double _currentMp = 0;
private final int[][] _paperdoll;
private int _karma = 0;
/**
* @param objectId
* @param name
*/
public CharSelectInfoPackage(int objectId, String name)
{
setObjectId(objectId);
_name = name;
_paperdoll = PcInventory.restoreVisibleInventory(objectId);
}
public int getObjectId()
{
return _objectId;
}
public void setObjectId(int objectId)
{
_objectId = objectId;
}
public int getCharId()
{
return _charId;
}
public void setCharId(int charId)
{
_charId = charId;
}
public int getClanId()
{
return _clanId;
}
public void setClanId(int clanId)
{
_clanId = clanId;
}
public int getClassId()
{
return _classId;
}
public int getBaseClassId()
{
return _baseClassId;
}
public void setClassId(int classId)
{
_classId = classId;
}
public void setBaseClassId(int baseClassId)
{
_baseClassId = baseClassId;
}
public double getCurrentHp()
{
return _currentHp;
}
public void setCurrentHp(double currentHp)
{
_currentHp = currentHp;
}
public double getCurrentMp()
{
return _currentMp;
}
public void setCurrentMp(double currentMp)
{
_currentMp = currentMp;
}
public long getDeleteTimer()
{
return _deleteTimer;
}
public void setDeleteTimer(long deleteTimer)
{
_deleteTimer = deleteTimer;
}
public long getLastAccess()
{
return _lastAccess;
}
public void setLastAccess(long lastAccess)
{
_lastAccess = lastAccess;
}
public long getExp()
{
return _exp;
}
public void setExp(long exp)
{
_exp = exp;
}
public int getFace()
{
return _face;
}
public void setFace(int face)
{
_face = face;
}
public int getHairColor()
{
return _hairColor;
}
public void setHairColor(int hairColor)
{
_hairColor = hairColor;
}
public int getHairStyle()
{
return _hairStyle;
}
public void setHairStyle(int hairStyle)
{
_hairStyle = hairStyle;
}
public int getPaperdollObjectId(int slot)
{
return _paperdoll[slot][0];
}
public int getPaperdollItemId(int slot)
{
return _paperdoll[slot][1];
}
public int getLevel()
{
return _level;
}
public void setLevel(int level)
{
_level = level;
}
public int getMaxHp()
{
return _maxHp;
}
public void setMaxHp(int maxHp)
{
_maxHp = maxHp;
}
public int getMaxMp()
{
return _maxMp;
}
public void setMaxMp(int maxMp)
{
_maxMp = maxMp;
}
public String getName()
{
return _name;
}
public void setName(String name)
{
_name = name;
}
public int getRace()
{
return _race;
}
public void setRace(int race)
{
_race = race;
}
public int getSex()
{
return _sex;
}
public void setSex(int sex)
{
_sex = sex;
}
public int getSp()
{
return _sp;
}
public void setSp(int sp)
{
_sp = sp;
}
public int getEnchantEffect()
{
if (_paperdoll[Inventory.PAPERDOLL_RHAND][2] > 0)
{
return _paperdoll[Inventory.PAPERDOLL_RHAND][2];
}
return _paperdoll[Inventory.PAPERDOLL_LRHAND][2];
}
public void setKarma(int k)
{
_karma = k;
}
public int getKarma()
{
return _karma;
}
}

View File

@@ -0,0 +1,71 @@
/*
* 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.model;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.model.L2ItemInstance.ItemLocation;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
public final class ClanWarehouse extends Warehouse
{
// private static final Logger _log = Logger.getLogger(PcWarehouse.class.getName());
private final L2Clan _clan;
public ClanWarehouse(L2Clan clan)
{
_clan = clan;
}
@Override
public int getOwnerId()
{
return _clan.getClanId();
}
@Override
public L2PcInstance getOwner()
{
return _clan.getLeader().getPlayerInstance();
}
@Override
public ItemLocation getBaseLocation()
{
return ItemLocation.CLANWH;
}
public String getLocationId()
{
return "0";
}
public int getLocationId(boolean dummy)
{
return 0;
}
public void setLocationId(L2PcInstance dummy)
{
}
@Override
public boolean validateCapacity(int slots)
{
return ((_items.size() + slots) <= Config.WAREHOUSE_SLOTS_CLAN);
}
}

View File

@@ -0,0 +1,192 @@
/*
* 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.model;
import java.util.Map;
import javolution.util.FastMap;
/**
* This class ...
* @version $Revision$ $Date$
*/
public class DesireTable
{
public static final DesireType[] DEFAULT_DESIRES =
{
DesireType.FEAR,
DesireType.DISLIKE,
DesireType.HATE,
DesireType.DAMAGE
};
public enum DesireType
{
FEAR,
DISLIKE,
HATE,
DAMAGE;
}
class DesireValue
{
private float value;
DesireValue()
{
this(0f);
}
DesireValue(Float pValue)
{
value = pValue;
}
public void addValue(float pValue)
{
value += pValue;
}
public float getValue()
{
return value;
}
}
class Desires
{
private final Map<DesireType, DesireValue> desireTable;
public Desires(DesireType... desireList)
{
desireTable = new FastMap<>();
for (final DesireType desire : desireList)
{
desireTable.put(desire, new DesireValue());
}
}
public DesireValue getDesireValue(DesireType type)
{
return desireTable.get(type);
}
public void addValue(DesireType type, float value)
{
final DesireValue temp = getDesireValue(type);
if (temp != null)
{
temp.addValue(value);
}
}
public void createDesire(DesireType type)
{
desireTable.put(type, new DesireValue());
}
public void deleteDesire(DesireType type)
{
desireTable.remove(type);
}
}
private final Map<L2Object, Desires> objectDesireTable;
private final Desires generalDesires;
private final DesireType[] desireTypes;
public DesireTable(DesireType... desireList)
{
desireTypes = desireList;
objectDesireTable = new FastMap<>();
generalDesires = new Desires(desireTypes);
}
public float getDesireValue(DesireType type)
{
return generalDesires.getDesireValue(type).getValue();
}
public float getDesireValue(L2Object object, DesireType type)
{
final Desires desireList = objectDesireTable.get(object);
if (desireList == null)
{
return 0f;
}
return desireList.getDesireValue(type).getValue();
}
public void addDesireValue(DesireType type, float value)
{
generalDesires.addValue(type, value);
}
public void addDesireValue(L2Object object, DesireType type, float value)
{
final Desires desireList = objectDesireTable.get(object);
if (desireList != null)
{
desireList.addValue(type, value);
}
}
public void createDesire(DesireType type)
{
generalDesires.createDesire(type);
}
public void deleteDesire(DesireType type)
{
generalDesires.deleteDesire(type);
}
public void createDesire(L2Object object, DesireType type)
{
final Desires desireList = objectDesireTable.get(object);
if (desireList != null)
{
desireList.createDesire(type);
}
}
public void deleteDesire(L2Object object, DesireType type)
{
final Desires desireList = objectDesireTable.get(object);
if (desireList != null)
{
desireList.deleteDesire(type);
}
}
public void addKnownObject(L2Object object)
{
if (object != null)
{
addKnownObject(object, DesireType.DISLIKE, DesireType.FEAR, DesireType.DAMAGE, DesireType.HATE);
}
}
public void addKnownObject(L2Object object, DesireType... desireList)
{
if (object != null)
{
objectDesireTable.put(object, new Desires(desireList));
}
}
}

View File

@@ -0,0 +1,97 @@
/*
* 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.model;
import java.util.concurrent.ScheduledFuture;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
/**
* @author DrHouse
*/
public class DropProtection implements Runnable
{
private volatile boolean _isProtected = false;
private L2PcInstance _owner = null;
private ScheduledFuture<?> _task = null;
private static final long PROTECTED_MILLIS_TIME = 15000;
@Override
public synchronized void run()
{
_isProtected = false;
_owner = null;
_task = null;
}
public boolean isProtected()
{
return _isProtected;
}
public L2PcInstance getOwner()
{
return _owner;
}
public synchronized boolean tryPickUp(L2PcInstance actor)
{
if (!_isProtected)
{
return true;
}
if (_owner == actor)
{
return true;
}
if ((_owner.getParty() != null) && (_owner.getParty() == actor.getParty()))
{
return true;
}
return false;
}
public synchronized void unprotect()
{
if (_task != null)
{
_task.cancel(false);
}
_isProtected = false;
_owner = null;
_task = null;
}
public synchronized void protect(L2PcInstance player)
{
unprotect();
_isProtected = true;
if ((_owner = player) == null)
{
throw new NullPointerException("Trying to protect dropped item to null owner");
}
_task = ThreadPoolManager.getInstance().scheduleGeneral(this, PROTECTED_MILLIS_TIME);
}
}

View File

@@ -0,0 +1,46 @@
/*
* 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.model;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Properties;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.model.entity.TvTEvent;
public class EventEngine
{
public static void load()
{
// Load all Events and their settings
final Properties eventSettings = new Properties();
try (InputStream is = new FileInputStream(new File(Config.EVENTS_CONFIG_FILE)))
{
eventSettings.load(is);
}
catch (final Exception e)
{
System.err.println("Error while loading Events Settings.");
e.printStackTrace();
}
// TvT Event
TvTEvent.initialize(eventSettings);
}
}

View File

@@ -0,0 +1,111 @@
/*
* 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.model;
public class FishData
{
private final int _id;
private final int _level;
private final String _name;
private final int _hP;
private final int _hpRegen;
private final int _type;
private final int _group;
private final int _fish_guts;
private final int _guts_check_time;
private final int _wait_time;
private final int _combat_time;
public FishData(int id, int lvl, String name, int hP, int hpRegen, int type, int group, int fish_guts, int guts_check_time, int wait_time, int combat_time)
{
_id = id;
_level = lvl;
_name = name.intern();
_hP = hP;
_hpRegen = hpRegen;
_type = type;
_group = group;
_fish_guts = fish_guts;
_guts_check_time = guts_check_time;
_wait_time = wait_time;
_combat_time = combat_time;
}
/**
* @return Returns the id.
*/
public int getId()
{
return _id;
}
/**
* @return Returns the level.
*/
public int getLevel()
{
return _level;
}
/**
* @return Returns the name.
*/
public String getName()
{
return _name;
}
public int getHP()
{
return _hP;
}
public int getHpRegen()
{
return _hpRegen;
}
public int getType()
{
return _type;
}
public int getGroup()
{
return _group;
}
public int getFishGuts()
{
return _fish_guts;
}
public int getGutsCheckTime()
{
return _guts_check_time;
}
public int getWaitTime()
{
return _wait_time;
}
public int getCombatTime()
{
return _combat_time;
}
}

View File

@@ -0,0 +1,42 @@
/*
* 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.model;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jmobius.Config;
public class GMAudit
{
private static final Logger _log = Logger.getLogger("gmaudit");
public static void auditGMAction(String gmName, String action, String target, String params)
{
if (Config.GMAUDIT)
{
String today;
SimpleDateFormat formatter;
formatter = new SimpleDateFormat("dd/MM/yyyy H:mm:ss");
today = formatter.format(new Date());
_log.log(Level.INFO, today + ">" + gmName + ">" + action + ">" + target + ">" + params);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,665 @@
/*
* 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.model;
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.Config;
import com.l2jmobius.L2DatabaseFactory;
import com.l2jmobius.gameserver.GameTimeController;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.model.L2ItemInstance.ItemLocation;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.templates.L2Item;
import javolution.util.FastList;
/**
* @author Advi
*/
public abstract class ItemContainer
{
protected static final Logger _log = Logger.getLogger(ItemContainer.class.getName());
protected final List<L2ItemInstance> _items;
protected ItemContainer()
{
_items = new FastList<>();
}
protected abstract L2Character getOwner();
protected abstract ItemLocation getBaseLocation();
/**
* Returns the ownerID of the inventory
* @return int
*/
public int getOwnerId()
{
return getOwner() == null ? 0 : getOwner().getObjectId();
}
/**
* Returns the quantity of items in the inventory
* @return int
*/
public int getSize()
{
return _items.size();
}
/**
* Returns the list of items in inventory
* @return L2ItemInstance : items in inventory
*/
public L2ItemInstance[] getItems()
{
return _items.toArray(new L2ItemInstance[_items.size()]);
}
public List<L2ItemInstance> getItemList()
{
return _items;
}
/**
* Returns the item from inventory by using its <B>itemId</B><BR>
* <BR>
* @param itemId : int designating the ID of the item
* @return L2ItemInstance designating the item or null if not found in inventory
*/
public L2ItemInstance getItemByItemId(int itemId)
{
for (final L2ItemInstance item : _items)
{
if ((item != null) && (item.getItemId() == itemId))
{
return item;
}
}
return null;
}
/**
* Returns the item from inventory by using its <B>itemId</B><BR>
* <BR>
* @param itemId : int designating the ID of the item
* @param itemToIgnore : used during a loop, to avoid returning the same item
* @return L2ItemInstance designating the item or null if not found in inventory
*/
public L2ItemInstance getItemByItemId(int itemId, L2ItemInstance itemToIgnore)
{
for (final L2ItemInstance item : _items)
{
if ((item != null) && (item.getItemId() == itemId) && !item.equals(itemToIgnore))
{
return item;
}
}
return null;
}
/**
* Returns item from inventory by using its <B>objectId</B>
* @param objectId : int designating the ID of the object
* @return L2ItemInstance designating the item or null if not found in inventory
*/
public L2ItemInstance getItemByObjectId(int objectId)
{
for (final L2ItemInstance item : _items)
{
if (item == null)
{
continue;
}
if (item.getObjectId() == objectId)
{
return item;
}
}
return null;
}
public int getInventoryItemCount(int itemId, int enchantLevel)
{
int count = 0;
for (final L2ItemInstance item : _items)
{
if (item == null)
{
continue;
}
if ((item.getItemId() == itemId) && ((item.getEnchantLevel() == enchantLevel) || (enchantLevel < 0)))
{
if (item.isStackable())
{
count = item.getCount();
}
else
{
count++;
}
}
}
return count;
}
/**
* Adds item to inventory
* @param process : String Identifier of process triggering this action
* @param item : L2ItemInstance to be added
* @param actor : L2PcInstance Player requesting the item add
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
* @return L2ItemInstance corresponding to the new item or the updated item in inventory
*/
public L2ItemInstance addItem(String process, L2ItemInstance item, L2PcInstance actor, L2Object reference)
{
final L2ItemInstance olditem = getItemByItemId(item.getItemId());
// If stackable item is found in inventory just add to current quantity
if ((olditem != null) && olditem.isStackable())
{
olditem.changeCount(process, item.getCount(), actor, reference);
olditem.setLastChange(L2ItemInstance.MODIFIED);
// And destroys the item
ItemTable.getInstance().destroyItem(process, item, actor, reference);
item.updateDatabase();
item = olditem;
// Updates database
if ((item.getItemId() == 57) && (item.getCount() < (10000 * Config.RATE_DROP_ADENA)))
{
// Small adena changes won't be saved to database all the time
if ((GameTimeController.getGameTicks() % 5) == 0)
{
item.updateDatabase();
}
}
else
{
item.updateDatabase();
}
}
// If item hasn't be found in inventory, create new one
else
{
item.setOwnerId(process, getOwnerId(), actor, reference);
item.setLocation(getBaseLocation());
item.setLastChange((L2ItemInstance.ADDED));
// Add item in inventory
addItem(item);
// Updates database
item.updateDatabase();
}
refreshWeight();
return item;
}
/**
* Adds item to inventory
* @param process : String Identifier of process triggering this action
* @param itemId : int Item Identifier of the item to be added
* @param count : int Quantity of items to be added
* @param actor : L2PcInstance Player requesting the item add
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
* @return L2ItemInstance corresponding to the new item or the updated item in inventory
*/
public L2ItemInstance addItem(String process, int itemId, int count, L2PcInstance actor, L2Object reference)
{
L2ItemInstance item = getItemByItemId(itemId);
// If stackable item is found in inventory just add to current quantity
if ((item != null) && item.isStackable())
{
item.changeCount(process, count, actor, reference);
item.setLastChange(L2ItemInstance.MODIFIED);
// Updates database
if ((itemId == 57) && (count < (10000 * Config.RATE_DROP_ADENA)))
{
// Small adena changes won't be saved to database all the time
if ((GameTimeController.getGameTicks() % 5) == 0)
{
item.updateDatabase();
}
}
else
{
item.updateDatabase();
}
}
// If item hasn't be found in inventory, create new one
else
{
for (int i = 0; i < count; i++)
{
final L2Item template = ItemTable.getInstance().getTemplate(itemId);
if (template == null)
{
_log.log(Level.WARNING, (actor != null ? "[" + actor.getName() + "] " : "") + "Invalid ItemId requested: ", itemId);
return null;
}
item = ItemTable.getInstance().createItem(process, itemId, template.isStackable() ? count : 1, actor, reference);
item.setOwnerId(getOwnerId());
item.setLocation(getBaseLocation());
item.setLastChange(L2ItemInstance.ADDED);
// Add item in inventory
addItem(item);
// Updates database
item.updateDatabase();
// If stackable, end loop as entire count is included in 1 instance of item
if (template.isStackable() || !Config.MULTIPLE_ITEM_DROP)
{
break;
}
}
}
refreshWeight();
return item;
}
/**
* Adds Wear/Try On item to inventory<BR>
* <BR>
* @param process : String Identifier of process triggering this action
* @param itemId : int Item Identifier of the item to be added
* @param actor : L2PcInstance Player requesting the item add
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
* @return L2ItemInstance corresponding to the new weared item
*/
public L2ItemInstance addWearItem(String process, int itemId, L2PcInstance actor, L2Object reference)
{
// Surch the item in the inventory of the player
L2ItemInstance item = getItemByItemId(itemId);
// There is such item already in inventory
if (item != null)
{
return item;
}
// Create and Init the L2ItemInstance corresponding to the Item Identifier and quantity
// Add the L2ItemInstance object to _allObjects of L2world
item = ItemTable.getInstance().createItem(process, itemId, 1, actor, reference);
// Set Item Properties
item.setWear(true); // "Try On" Item -> Don't save it in database
item.setOwnerId(getOwnerId());
item.setLocation(getBaseLocation());
item.setLastChange((L2ItemInstance.ADDED));
// Add item in inventory and equip it if necessary (item location defined)
addItem(item);
// Calculate the weight loaded by player
refreshWeight();
return item;
}
/**
* Transfers item to another inventory
* @param process : String Identifier of process triggering this action
* @param objectId
* @param count : int Quantity of items to be transfered
* @param target
* @param actor : L2PcInstance Player requesting the item transfer
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
* @return L2ItemInstance corresponding to the new item or the updated item in inventory
*/
public L2ItemInstance transferItem(String process, int objectId, int count, ItemContainer target, L2PcInstance actor, L2Object reference)
{
if (target == null)
{
return null;
}
final L2ItemInstance sourceitem = getItemByObjectId(objectId);
if (sourceitem == null)
{
return null;
}
L2ItemInstance targetitem = sourceitem.isStackable() ? target.getItemByItemId(sourceitem.getItemId()) : null;
synchronized (sourceitem)
{
if (getItemByObjectId(objectId) != sourceitem)
{
return null;
}
// Check if requested quantity is available
if (count > sourceitem.getCount())
{
count = sourceitem.getCount();
}
// If possible, move entire item object
if ((sourceitem.getCount() == count) && (targetitem == null))
{
removeItem(sourceitem);
target.addItem(process, sourceitem, actor, reference);
targetitem = sourceitem;
}
else
{
if (sourceitem.getCount() > count)
{
sourceitem.changeCount(process, -count, actor, reference);
}
else // Otherwise destroy old item
{
removeItem(sourceitem);
ItemTable.getInstance().destroyItem(process, sourceitem, actor, reference);
}
if (targetitem != null)
{
targetitem.changeCount(process, count, actor, reference);
}
else
{
targetitem = target.addItem(process, sourceitem.getItemId(), count, actor, reference);
}
}
// Updates database
sourceitem.updateDatabase(true);
if ((targetitem != sourceitem) && (targetitem != null))
{
targetitem.updateDatabase();
}
refreshWeight();
}
return targetitem;
}
/**
* Destroy item from inventory and updates database
* @param process : String Identifier of process triggering this action
* @param item : L2ItemInstance to be destroyed
* @param actor : L2PcInstance Player requesting the item destroy
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
* @return L2ItemInstance corresponding to the destroyed item or the updated item in inventory
*/
public L2ItemInstance destroyItem(String process, L2ItemInstance item, L2PcInstance actor, L2Object reference)
{
return destroyItem(process, item, item.getCount(), actor, reference);
}
/**
* Destroy item from inventory and updates database
* @param process : String Identifier of process triggering this action
* @param item : L2ItemInstance to be destroyed
* @param count
* @param actor : L2PcInstance Player requesting the item destroy
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
* @return L2ItemInstance corresponding to the destroyed item or the updated item in inventory
*/
public L2ItemInstance destroyItem(String process, L2ItemInstance item, int count, L2PcInstance actor, L2Object reference)
{
synchronized (item)
{
// Adjust item quantity
if (item.getCount() > count)
{
item.changeCount(process, -count, actor, reference);
item.setLastChange(L2ItemInstance.MODIFIED);
// dont update often for untraced items
if ((process != null) || ((GameTimeController.getGameTicks() % 10) == 0))
{
item.updateDatabase();
}
refreshWeight();
return item;
}
if (item.getCount() < count)
{
return null;
}
final boolean removed = removeItem(item);
if (!removed)
{
return null;
}
ItemTable.getInstance().destroyItem(process, item, actor, reference);
item.updateDatabase();
refreshWeight();
}
return item;
}
/**
* Destroy item from inventory by using its <B>objectID</B> and updates database
* @param process : String Identifier of process triggering this action
* @param objectId : int Item Instance identifier of the item to be destroyed
* @param count : int Quantity of items to be destroyed
* @param actor : L2PcInstance Player requesting the item destroy
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
* @return L2ItemInstance corresponding to the destroyed item or the updated item in inventory
*/
public L2ItemInstance destroyItem(String process, int objectId, int count, L2PcInstance actor, L2Object reference)
{
final L2ItemInstance item = getItemByObjectId(objectId);
if (item == null)
{
return null;
}
return destroyItem(process, item, count, actor, reference);
}
/**
* Destroy item from inventory by using its <B>itemId</B> and updates database
* @param process : String Identifier of process triggering this action
* @param itemId : int Item identifier of the item to be destroyed
* @param count : int Quantity of items to be destroyed
* @param actor : L2PcInstance Player requesting the item destroy
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
* @return L2ItemInstance corresponding to the destroyed item or the updated item in inventory
*/
public L2ItemInstance destroyItemByItemId(String process, int itemId, int count, L2PcInstance actor, L2Object reference)
{
final L2ItemInstance item = getItemByItemId(itemId);
if (item == null)
{
return null;
}
return destroyItem(process, item, count, actor, reference);
}
/**
* Destroy all items from inventory and updates database
* @param process : String Identifier of process triggering this action
* @param actor : L2PcInstance Player requesting the item destroy
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
*/
public synchronized void destroyAllItems(String process, L2PcInstance actor, L2Object reference)
{
for (final L2ItemInstance item : _items)
{
destroyItem(process, item, actor, reference);
}
}
/**
* Get warehouse adena
* @return
*/
public int getAdena()
{
int count = 0;
for (final L2ItemInstance item : _items)
{
if (item.getItemId() == 57)
{
count = item.getCount();
return count;
}
}
return count;
}
/**
* Adds item to inventory for further adjustments.
* @param item : L2ItemInstance to be added from inventory
*/
protected void addItem(L2ItemInstance item)
{
_items.add(item);
}
/**
* Removes item from inventory for further adjustments.
* @param item : L2ItemInstance to be removed from inventory
* @return
*/
protected boolean removeItem(L2ItemInstance item)
{
return _items.remove(item);
}
/**
* Refresh the weight of equipment loaded
*/
protected void refreshWeight()
{
}
/**
* Delete item object from world
*/
public void deleteMe()
{
try
{
updateDatabase();
}
catch (final Throwable t)
{
_log.log(Level.SEVERE, "deletedMe()", t);
}
final List<L2Object> items = new FastList<>(_items);
_items.clear();
L2World.getInstance().removeObjects(items);
}
/**
* Update database with items in inventory
*/
public void updateDatabase()
{
if (getOwner() != null)
{
for (final L2ItemInstance item : _items)
{
if (item != null)
{
item.updateDatabase(true);
}
}
}
}
/**
* Get back items in container from database
*/
public void restore()
{
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("SELECT object_id FROM items WHERE owner_id=? AND (loc=?) ORDER BY object_id DESC"))
{
statement.setInt(1, getOwnerId());
statement.setString(2, getBaseLocation().name());
try (ResultSet inv = statement.executeQuery())
{
L2ItemInstance item;
while (inv.next())
{
final int objectId = inv.getInt(1);
item = L2ItemInstance.restoreFromDb(objectId);
if (item == null)
{
continue;
}
L2World.getInstance().storeObject(item);
// If stackable item is found in inventory just add to current quantity
if (item.isStackable() && (getItemByItemId(item.getItemId()) != null))
{
addItem("Restore", item, null, getOwner());
}
else
{
addItem(item);
}
}
}
refreshWeight();
}
catch (final Exception e)
{
_log.log(Level.WARNING, "could not restore container:", e);
}
}
public boolean validateCapacity(int slots)
{
return true;
}
public boolean validateWeight(int weight)
{
return true;
}
}

View File

@@ -0,0 +1,178 @@
/*
* 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.model;
import com.l2jmobius.gameserver.templates.L2Item;
/**
* Get all information from L2ItemInstance to generate ItemInfo.<BR>
* <BR>
*/
public class ItemInfo
{
/** Identifier of the L2ItemInstance */
private int _objectId;
/** The L2Item template of the L2ItemInstance */
private L2Item _item;
/** The level of enchant on the L2ItemInstance */
private int _enchant;
/** The quantity of L2ItemInstance */
private int _count;
/** The price of the L2ItemInstance */
private int _price;
/** The custom L2ItemInstance types (used loto, race tickets) */
private int _type1;
private int _type2;
/** If True the L2ItemInstance is equipped */
private int _equipped;
/** The action to do client side (1=ADD, 2=MODIFY, 3=REMOVE) */
private int _change;
/**
* Get all information from L2ItemInstance to generate ItemInfo.<BR>
* <BR>
* @param item
*/
public ItemInfo(L2ItemInstance item)
{
if (item == null)
{
return;
}
// Get the Identifier of the L2ItemInstance
_objectId = item.getObjectId();
// Get the L2Item of the L2ItemInstance
_item = item.getItem();
// Get the enchant level of the L2ItemInstance
_enchant = item.getEnchantLevel();
// Get the quantity of the L2ItemInstance
_count = item.getCount();
// Get custom item types (used loto, race tickets)
_type1 = item.getCustomType1();
_type2 = item.getCustomType2();
// Verify if the L2ItemInstance is equipped
_equipped = item.isEquipped() ? 1 : 0;
// Get the action to do client side
switch (item.getLastChange())
{
case (L2ItemInstance.ADDED):
{
_change = 1;
break;
}
case (L2ItemInstance.MODIFIED):
{
_change = 2;
break;
}
case (L2ItemInstance.REMOVED):
{
_change = 3;
break;
}
}
}
public ItemInfo(L2ItemInstance item, int change)
{
if (item == null)
{
return;
}
// Get the Identifier of the L2ItemInstance
_objectId = item.getObjectId();
// Get the L2Item of the L2ItemInstance
_item = item.getItem();
// Get the enchant level of the L2ItemInstance
_enchant = item.getEnchantLevel();
// Get the quantity of the L2ItemInstance
_count = item.getCount();
// Get custom item types (used loto, race tickets)
_type1 = item.getCustomType1();
_type2 = item.getCustomType2();
// Verify if the L2ItemInstance is equipped
_equipped = item.isEquipped() ? 1 : 0;
// Get the action to do client side
_change = change;
}
public int getObjectId()
{
return _objectId;
}
public L2Item getItem()
{
return _item;
}
public int getEnchant()
{
return _enchant;
}
public int getCount()
{
return _count;
}
public int getPrice()
{
return _price;
}
public int getCustomType1()
{
return _type1;
}
public int getCustomType2()
{
return _type2;
}
public int getEquipped()
{
return _equipped;
}
public int getChange()
{
return _change;
}
}

View File

@@ -0,0 +1,105 @@
/*
* 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.model;
/**
*
*/
public class ItemRequest
{
int _objectId;
int _itemId;
int _count;
int _price;
public ItemRequest(int objectId, int count, int price)
{
_objectId = objectId;
_count = count;
_price = price;
}
public ItemRequest(int objectId, int itemId, int count, int price)
{
_objectId = objectId;
_itemId = itemId;
_count = count;
_price = price;
}
public int getObjectId()
{
return _objectId;
}
public int getItemId()
{
return _itemId;
}
public void setCount(int count)
{
_count = count;
}
public int getCount()
{
return _count;
}
public int getPrice()
{
return _price;
}
/*
* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode()
{
return _objectId;
}
/*
* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
final ItemRequest other = (ItemRequest) obj;
if (_objectId != other._objectId)
{
return false;
}
return true;
}
}

View File

@@ -0,0 +1,166 @@
/*
* 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.model;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
/**
* @author Luno
*/
public final class L2ArmorSet
{
private final int _chest;
private final int _legs;
private final int _head;
private final int _gloves;
private final int _feet;
private final int _skill_id;
private final int _shield;
private final int _shield_skill_id;
public L2ArmorSet(int chest, int legs, int head, int gloves, int feet, int skill_id, int shield, int shield_skill_id)
{
_chest = chest;
_legs = legs;
_head = head;
_gloves = gloves;
_feet = feet;
_skill_id = skill_id;
_shield = shield;
_shield_skill_id = shield_skill_id;
}
/**
* Checks if player have equiped all items from set (not checking shield)
* @param player whose inventory is being checked
* @return True if player equips whole set
*/
public boolean containAll(L2PcInstance player)
{
final Inventory inv = player.getInventory();
final L2ItemInstance legsItem = inv.getPaperdollItem(Inventory.PAPERDOLL_LEGS);
final L2ItemInstance headItem = inv.getPaperdollItem(Inventory.PAPERDOLL_HEAD);
final L2ItemInstance glovesItem = inv.getPaperdollItem(Inventory.PAPERDOLL_GLOVES);
final L2ItemInstance feetItem = inv.getPaperdollItem(Inventory.PAPERDOLL_FEET);
int legs = 0;
int head = 0;
int gloves = 0;
int feet = 0;
if (legsItem != null)
{
legs = legsItem.getItemId();
}
if (headItem != null)
{
head = headItem.getItemId();
}
if (glovesItem != null)
{
gloves = glovesItem.getItemId();
}
if (feetItem != null)
{
feet = feetItem.getItemId();
}
return containAll(_chest, legs, head, gloves, feet);
}
public boolean containAll(int chest, int legs, int head, int gloves, int feet)
{
if ((_chest != 0) && (_chest != chest))
{
return false;
}
if ((_legs != 0) && (_legs != legs))
{
return false;
}
if ((_head != 0) && (_head != head))
{
return false;
}
if ((_gloves != 0) && (_gloves != gloves))
{
return false;
}
if ((_feet != 0) && (_feet != feet))
{
return false;
}
return true;
}
public boolean containItem(int slot, int itemId)
{
switch (slot)
{
case Inventory.PAPERDOLL_CHEST:
return _chest == itemId;
case Inventory.PAPERDOLL_LEGS:
return _legs == itemId;
case Inventory.PAPERDOLL_HEAD:
return _head == itemId;
case Inventory.PAPERDOLL_GLOVES:
return _gloves == itemId;
case Inventory.PAPERDOLL_FEET:
return _feet == itemId;
default:
return false;
}
}
public int getSkillId()
{
return _skill_id;
}
public boolean containShield(L2PcInstance player)
{
final Inventory inv = player.getInventory();
final L2ItemInstance shieldItem = inv.getPaperdollItem(Inventory.PAPERDOLL_LHAND);
if ((shieldItem != null) && (shieldItem.getItemId() == _shield))
{
return true;
}
return false;
}
public boolean containShield(int shield_id)
{
if (_shield == 0)
{
return false;
}
return _shield == shield_id;
}
public int getShieldSkillId()
{
return _shield_skill_id;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,42 @@
/*
* 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.model;
/**
* This class permit to pass (x, y, z, heading) position data to method.<BR>
* <BR>
*/
public final class L2CharPosition
{
public final int x, y, z, heading;
/**
* Constructor of L2CharPosition.<BR>
* <BR>
* @param pX
* @param pY
* @param pZ
* @param pHeading
*/
public L2CharPosition(int pX, int pY, int pZ, int pHeading)
{
x = pX;
y = pY;
z = pZ;
heading = pHeading;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,139 @@
/*
* 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.model;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
/**
* This class ...
* @version $Revision: 1.5.4.2 $ $Date: 2005/03/27 15:29:33 $
*/
public class L2ClanMember
{
private int _objectId;
private String _name;
private int _level;
private int _classId;
private L2PcInstance _player;
public L2ClanMember(String name, int level, int classId, int objectId)
{
_name = name;
_level = level;
_classId = classId;
_objectId = objectId;
}
public L2ClanMember(L2PcInstance player)
{
_player = player;
}
public void setPlayerInstance(L2PcInstance player)
{
if ((player == null) && (_player != null))
{
// this is here to keep the data when the player logs off
_name = _player.getName();
_level = _player.getLevel();
_classId = _player.getClassId().getId();
_objectId = _player.getObjectId();
}
_player = player;
}
public L2PcInstance getPlayerInstance()
{
return _player;
}
public boolean isOnline()
{
if (_player == null)
{
return false;
}
if (_player.inOfflineMode())
{
return false;
}
return true;
}
/**
* @return Returns the classId.
*/
public int getClassId()
{
if (_player != null)
{
return _player.getClassId().getId();
}
return _classId;
}
/**
* @return Returns the level.
*/
public int getLevel()
{
if (_player != null)
{
return _player.getLevel();
}
return _level;
}
/**
* @return Returns the name.
*/
public String getName()
{
if (_player != null)
{
return _player.getName();
}
return _name;
}
/**
* @return Returns the objectId.
*/
public int getObjectId()
{
if (_player != null)
{
return _player.getObjectId();
}
return _objectId;
}
public String getTitle()
{
if (_player != null)
{
return _player.getTitle();
}
return " ";
}
}

View File

@@ -0,0 +1,182 @@
/*
* 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.model;
import java.util.List;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.serverpackets.ExCloseMPCC;
import com.l2jmobius.gameserver.network.serverpackets.ExOpenMPCC;
import com.l2jmobius.gameserver.network.serverpackets.L2GameServerPacket;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import javolution.util.FastList;
/**
* @author chris_00
*/
public class L2CommandChannel
{
private List<L2Party> _parties = null;
private L2PcInstance _commandLeader = null;
/**
* Creates a New Command Channel and Add the Leaders party to the CC
* @param leader
*/
public L2CommandChannel(L2PcInstance leader)
{
_commandLeader = leader;
_parties = new FastList<>();
_parties.add(leader.getParty());
leader.getParty().setCommandChannel(this);
leader.getParty().broadcastToPartyMembers(new ExOpenMPCC());
}
/**
* Adds a Party to the Command Channel
* @param party
*/
public void addParty(L2Party party)
{
_parties.add(party);
party.setCommandChannel(this);
if (_parties.size() == Config.ALT_CHANNEL_ACTIVATION_COUNT)
{
broadcastToChannelMembers(new SystemMessage(SystemMessage.CHANNEL_ACTIVATED));
}
party.broadcastToPartyMembers(new ExOpenMPCC());
}
/**
* Removes a Party from the Command Channel
* @param party
*/
public void removeParty(L2Party party)
{
_parties.remove(party);
party.setCommandChannel(null);
party.broadcastToPartyMembers(new ExCloseMPCC());
if (_parties.size() < 2)
{
party.broadcastToPartyMembers(new SystemMessage(SystemMessage.COMMAND_CHANNEL_DISBANDED));
broadcastToChannelMembers(new SystemMessage(SystemMessage.COMMAND_CHANNEL_DISBANDED));
disbandChannel();
}
else if (_parties.size() < Config.ALT_CHANNEL_ACTIVATION_COUNT)
{
broadcastToChannelMembers(new SystemMessage(SystemMessage.CHANNEL_DEACTIVATED));
}
}
/**
* disbands the whole Command Channel
*/
public void disbandChannel()
{
if (_parties != null)
{
for (final L2Party party : _parties)
{
if (party == null)
{
continue;
}
removeParty(party);
}
}
_parties = null;
}
/**
* @return overall membercount of the Command Channel
*/
public int getMemberCount()
{
int count = 0;
for (final L2Party party : _parties)
{
if (party != null)
{
count += party.getMemberCount();
}
}
return count;
}
/**
* Broadcast packet to every channelmember
* @param gsp
*/
public void broadcastToChannelMembers(L2GameServerPacket gsp)
{
if (!_parties.isEmpty())
{
for (final L2Party party : _parties)
{
if (party != null)
{
party.broadcastToPartyMembers(gsp);
}
}
}
}
/**
* @return list of Parties in Command Channel
*/
public List<L2Party> getParties()
{
return _parties;
}
/**
* @return list of all Members in Command Channel
*/
public List<L2PcInstance> getMembers()
{
final List<L2PcInstance> members = new FastList<>();
for (final L2Party party : getParties())
{
members.addAll(party.getPartyMembers());
}
return members;
}
/**
* @param leader the leader of the Command Channel
*/
public void setChannelLeader(L2PcInstance leader)
{
_commandLeader = leader;
}
/**
* @return the leader of the Command Channel
*/
public L2PcInstance getChannelLeader()
{
return _commandLeader;
}
}

View File

@@ -0,0 +1,190 @@
/*
* 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.model;
import com.l2jmobius.Config;
import com.l2jmobius.util.Rnd;
import javolution.util.FastList;
/**
* @author Fulminus
*/
public class L2DropCategory
{
private final FastList<L2DropData> _drops;
private int _categoryChance; // a sum of chances for calculating if an item will be dropped from this category
private int _categoryBalancedChance; // sum for balancing drop selection inside categories in high rate servers
private final int _categoryType;
public L2DropCategory(int categoryType)
{
_categoryType = categoryType;
_drops = new FastList<>(0);
_categoryChance = 0;
_categoryBalancedChance = 0;
}
public void addDropData(L2DropData drop, boolean raid)
{
boolean found = false;
if (!drop.isQuestDrop())
{
if (Config.CUSTOM_DROPLIST_TABLE)
{
// If the drop exists is replaced
for (final L2DropData d : _drops)
{
if (d.getItemId() == drop.getItemId())
{
d.setMinDrop(drop.getMinDrop());
d.setMaxDrop(drop.getMaxDrop());
if (d.getChance() != drop.getChance())
{
// Re-calculate Chance
_categoryChance -= d.getChance();
_categoryBalancedChance -= Math.min((d.getChance() * (raid ? Config.RATE_BOSS_DROP_ITEMS : Config.RATE_DROP_ITEMS)), L2DropData.MAX_CHANCE);
d.setChance(drop.getChance());
_categoryChance += d.getChance();
_categoryBalancedChance += Math.min((d.getChance() * (raid ? Config.RATE_BOSS_DROP_ITEMS : Config.RATE_DROP_ITEMS)), L2DropData.MAX_CHANCE);
}
found = true;
break;
}
}
}
if (!found)
{
_drops.add(drop);
_categoryChance += drop.getChance();
// for drop selection inside a category: max 100 % chance for getting an item, scaling all values to that.
_categoryBalancedChance += Math.min((drop.getChance() * (raid ? Config.RATE_BOSS_DROP_ITEMS : Config.RATE_DROP_ITEMS)), L2DropData.MAX_CHANCE);
}
}
}
public FastList<L2DropData> getAllDrops()
{
return _drops;
}
public void clearAllDrops()
{
_drops.clear();
}
public boolean isSweep()
{
return (getCategoryType() == -1);
}
// this returns the chance for the category to be visited in order to check if
// drops might come from it. Category -1 (spoil) must always be visited
// (but may return 0 or many drops)
public int getCategoryChance()
{
if (getCategoryType() >= 0)
{
return _categoryChance;
}
return L2DropData.MAX_CHANCE;
}
public int getCategoryBalancedChance()
{
if (getCategoryType() >= 0)
{
return _categoryBalancedChance;
}
return L2DropData.MAX_CHANCE;
}
public int getCategoryType()
{
return _categoryType;
}
/**
* Useful for seeded conditions... the category will attempt to drop only among items that are allowed to be dropped when a mob is seeded.<br>
* Previously, this only included Adena. According to sh1ny, seals tones are also acceptable drops.<br>
* If no acceptable drops are in the category, nothing will be dropped.<br>
* therwise, it will check for the item's chance to drop and either drop it or drop nothing.
* @return acceptable drop when mob is seeded, if it exists. Null otherwise.
*/
public synchronized L2DropData dropSeedAllowedDropsOnly()
{
FastList<L2DropData> drops = new FastList<>();
int subCatChance = 0;
for (final L2DropData drop : getAllDrops())
{
if ((drop.getItemId() == 57) || (drop.getItemId() == 6360) || (drop.getItemId() == 6361) || (drop.getItemId() == 6362))
{
drops.add(drop);
subCatChance += drop.getChance();
}
}
// among the results choose one.
final int randomIndex = Rnd.get(subCatChance);
int sum = 0;
for (final L2DropData drop : drops)
{
sum += drop.getChance();
if (sum > randomIndex) // drop this item and exit the function
{
drops.clear();
drops = null;
return drop;
}
}
// since it is still within category, only drop one of the acceptable drops from the results.
return null;
}
/**
* One of the drops in this category is to be dropped now.<br>
* to see which one will be dropped, weight all items' chances such that their sum of chances equals MAX_CHANCE.<br>
* Since the individual drops have their base chance, we also ought to use the base category chance for the weight.<br>
* So weight = MAX_CHANCE/basecategoryDropChance.<br>
* Then get a single random number within this range. The first item (in order of the list) whose contribution to the sum makes the sum greater than the random number, will be dropped.<br>
* Edited: How _categoryBalancedChance works in high rate servers:<br>
* Let's say item1 has a drop chance (when considered alone, without category) of 1 % * RATE_DROP_ITEMS and item2 has 20 % * RATE_DROP_ITEMS, and the server's RATE_DROP_ITEMS is for example 50x.<br>
* Without this balancer, the relative chance inside the category to select item1 to be dropped would be 1/26 and item2 25/26, no matter what rates are used.<br>
* In high rate servers people usually consider the 1 % individual drop chance should become higher than this relative chance (1/26) inside the category, since having the both items for example in their own categories would result in having a drop chance for item1 50 % and item2 1000 %.<br>
* _categoryBalancedChance limits the individual chances to 100 % max, making the chance for item1 to be selected from this category 50/(50+100) = 1/3 and item2 100/150 = 2/3.<br>
* This change doesn't affect calculation when drop_chance * RATE_DROP_ITEMS < 100%, meaning there are no big changes for low rate servers and no changes at all for 1x servers.
* @param raid
* @return selected drop from category, or null if nothing is dropped.
*/
public synchronized L2DropData dropOne(boolean raid)
{
final int randomIndex = Rnd.get(getCategoryBalancedChance());
int sum = 0;
for (final L2DropData drop : getAllDrops())
{
sum += Math.min((drop.getChance() * (raid ? Config.RATE_BOSS_DROP_ITEMS : Config.RATE_DROP_ITEMS)), L2DropData.MAX_CHANCE);
if (sum >= randomIndex)
{
return drop;
}
}
return null;
}
}

View File

@@ -0,0 +1,183 @@
/*
* 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.model;
import java.util.Arrays;
/**
* Special thanks to nuocnam Author: LittleVexy
* @version $Revision: 1.1.4.4 $ $Date: 2005/03/29 23:15:15 $
*/
public class L2DropData
{
public static final int MAX_CHANCE = 1000000;
private int _itemId;
private int _mindrop;
private int _maxdrop;
private int _chance;
private String _questID = null;
private String[] _stateID = null;
/**
* Returns the ID of the item dropped
* @return int
*/
public int getItemId()
{
return _itemId;
}
/**
* Sets the ID of the item dropped
* @param itemId : int designating the ID of the item
*/
public void setItemId(int itemId)
{
_itemId = itemId;
}
/**
* Returns the minimum quantity of items dropped
* @return int
*/
public int getMinDrop()
{
return _mindrop;
}
/**
* Returns the maximum quantity of items dropped
* @return int
*/
public int getMaxDrop()
{
return _maxdrop;
}
/**
* Returns the chance of having a drop
* @return int
*/
public int getChance()
{
return _chance;
}
/**
* Sets the value for minimal quantity of dropped items
* @param mindrop : int designating the quantity
*/
public void setMinDrop(int mindrop)
{
_mindrop = mindrop;
}
/**
* Sets the value for maximal quantity of dopped items
* @param maxdrop : int designating the quantity of dropped items
*/
public void setMaxDrop(int maxdrop)
{
_maxdrop = maxdrop;
}
/**
* Sets the chance of having the item for a drop
* @param chance : int designating the chance
*/
public void setChance(int chance)
{
_chance = chance;
}
/**
* Returns the stateID.
* @return String[]
*/
public String[] getStateIDs()
{
return _stateID;
}
/**
* Adds states of the dropped item
* @param list : String[]
*/
public void addStates(String[] list)
{
_stateID = list;
}
/**
* Returns the questID.
* @return String designating the ID of the quest
*/
public String getQuestID()
{
return _questID;
}
/**
* Sets the questID
* @param questID designating the questID to set.
*/
public void setQuestID(String questID)
{
_questID = questID;
}
/**
* Returns if the dropped item is requested for a quest
* @return boolean
*/
public boolean isQuestDrop()
{
return (_questID != null) && (_stateID != null);
}
/**
* Returns a report of the object
* @return String
*/
@Override
public String toString()
{
String out = "ItemID: " + getItemId() + " Min: " + getMinDrop() + " Max: " + getMaxDrop() + " Chance: " + (getChance() / 10000.0) + "%";
if (isQuestDrop())
{
out += " QuestID: " + getQuestID() + " StateID's: " + Arrays.toString(getStateIDs());
}
return out;
}
/**
* Returns if parameter "o" is a L2DropData and has the same itemID that the current object
* @return boolean
*/
@Override
public boolean equals(Object o)
{
if (o instanceof L2DropData)
{
final L2DropData drop = (L2DropData) o;
return drop.getItemId() == getItemId();
}
return false;
}
}

View File

@@ -0,0 +1,651 @@
/*
* 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.model;
import java.util.List;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.GameTimeController;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.network.serverpackets.ExOlympiadSpelledInfo;
import com.l2jmobius.gameserver.network.serverpackets.MagicEffectIcons;
import com.l2jmobius.gameserver.network.serverpackets.PartySpelled;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.skills.Env;
import com.l2jmobius.gameserver.skills.effects.EffectTemplate;
import com.l2jmobius.gameserver.skills.funcs.Func;
import com.l2jmobius.gameserver.skills.funcs.FuncTemplate;
import com.l2jmobius.gameserver.skills.funcs.Lambda;
import javolution.util.FastList;
/**
* This class ...
* @version $Revision: 1.1.2.1.2.12 $ $Date: 2005/04/11 10:06:07 $
*/
public abstract class L2Effect
{
static final Logger _log = Logger.getLogger(L2Effect.class.getName());
public static enum EffectState
{
CREATED,
ACTING,
FINISHING
}
public static enum EffectType
{
BUFF,
DEBUFF,
DMG_OVER_TIME,
HEAL_OVER_TIME,
COMBAT_POINT_HEAL_OVER_TIME,
MANA_DMG_OVER_TIME,
MANA_HEAL_OVER_TIME,
RELAXING,
STUN,
ROOT,
SLEEP,
HATE,
FAKE_DEATH,
CONFUSION,
CONFUSE_MOB_ONLY,
MUTE,
FEAR,
SILENT_MOVE,
SEED,
PARALYZE,
STUN_SELF,
PHYSICAL_MUTE,
SILENCE_MAGIC_PHYSICAL,
PETRIFICATION,
NOBLESSE_BLESSING,
MP_CONSUME_PER_LEVEL,
BLUFF,
REMOVE_TARGET,
CHARM_OF_LUCK,
THROW_UP
}
private static final Func[] _emptyFunctionSet = new Func[0];
// member _effector is the instance of L2Character that cast/used the spell/skill that is
// causing this effect. Do not confuse with the instance of L2Character that
// is being affected by this effect.
private final L2Character _effector;
// member _effected is the instance of L2Character that was affected
// by this effect. Do not confuse with the instance of L2Character that
// catsed/used this effect.
private final L2Character _effected;
// the skill that was used.
private final L2Skill _skill;
// or the items that was used.
// private final L2Item _item;
// the value of an update
private final Lambda _lambda;
// the current state
private EffectState _state;
// period, seconds
private int _period;
private int _periodStartTicks;
private int _periodfirsttime;
// function templates
private final FuncTemplate[] _funcTemplates;
// initial count
private final int _totalCount;
// counter
private int _count;
// abnormal effect mask
private final short _abnormalEffect;
// show icon
private final boolean _icon;
public boolean preventExitUpdate;
private boolean _isSelfEffect = false;
public final class EffectTask implements Runnable
{
protected final int delay;
protected final int rate;
EffectTask(int pDelay, int pRate)
{
delay = pDelay;
rate = pRate;
}
@Override
public void run()
{
try
{
if (getPeriodfirsttime() == 0)
{
setPeriodStartTicks(GameTimeController.getGameTicks());
}
else
{
setPeriodfirsttime(0);
}
scheduleEffect();
}
catch (final Throwable e)
{
_log.log(Level.SEVERE, "", e);
}
}
}
private ScheduledFuture<?> _currentFuture;
private EffectTask _currentTask;
/** The Identifier of the stack group */
private final String _stackType;
/** The position of the effect in the stack group */
private final float _stackOrder;
private boolean _inUse = false;
protected L2Effect(Env env, EffectTemplate template)
{
_state = EffectState.CREATED;
_skill = env.skill;
_effected = env.target;
_effector = env.player;
_lambda = template._lambda;
_funcTemplates = template._funcTemplates;
_count = template._counter;
_totalCount = _count;
_period = template._period;
if (env.skillMastery)
{
_period *= 2;
}
// Set duration for NPC buffs
if (_effector.isAIOBuffer() && (Config.AIO_BUFF_DURATION > 0))
{
_period = Config.AIO_BUFF_DURATION;
}
_abnormalEffect = template._abnormalEffect;
_stackType = template._stackType;
_stackOrder = template._stackOrder;
_periodStartTicks = GameTimeController.getGameTicks();
_periodfirsttime = 0;
_icon = template._icon;
scheduleEffect();
}
public int getCount()
{
return _count;
}
public int getTotalCount()
{
return _totalCount;
}
public void setCount(int newcount)
{
_count = newcount;
}
public void setFirstTime(int newfirsttime)
{
if (_currentFuture != null)
{
_periodStartTicks = GameTimeController.getGameTicks() - (newfirsttime * GameTimeController.TICKS_PER_SECOND);
_currentFuture.cancel(false);
_currentFuture = null;
_currentTask = null;
_periodfirsttime = newfirsttime;
final int duration = _period - _periodfirsttime;
_currentTask = new EffectTask(duration * 1000, -1);
_currentFuture = ThreadPoolManager.getInstance().scheduleEffect(_currentTask, duration * 1000);
}
}
public boolean getShowIcon()
{
return _icon;
}
public int getPeriod()
{
return _period;
}
public void setPeriod(int period)
{
_period = period;
}
public int getTime()
{
return (GameTimeController.getGameTicks() - _periodStartTicks) / GameTimeController.TICKS_PER_SECOND;
}
public int getTaskTime()
{
if (_count == _totalCount)
{
return 0;
}
return (Math.abs((_count - _totalCount) + 1) * _period) + getTime() + 1;
}
public boolean getInUse()
{
return _inUse;
}
public void setInUse(boolean inUse)
{
_inUse = inUse;
if (_inUse)
{
onStart();
}
else
{
onExit();
}
}
public String getStackType()
{
return _stackType;
}
public float getStackOrder()
{
return _stackOrder;
}
public final L2Skill getSkill()
{
return _skill;
}
public final L2Character getEffector()
{
return _effector;
}
public final L2Character getEffected()
{
return _effected;
}
public boolean isSelfEffect()
{
return _isSelfEffect;
}
public void setSelfEffect()
{
_isSelfEffect = true;
}
public final double calc()
{
final Env env = new Env();
env.player = _effector;
env.target = _effected;
env.skill = _skill;
return _lambda.calc(env);
}
private synchronized void startEffectTask(int duration)
{
stopEffectTask();
_currentTask = new EffectTask(duration, -1);
_currentFuture = ThreadPoolManager.getInstance().scheduleEffect(_currentTask, duration);
if (_state == EffectState.ACTING)
{
_effected.addEffect(this);
}
}
private synchronized void startEffectTaskAtFixedRate(int delay, int rate)
{
stopEffectTask();
_currentTask = new EffectTask(delay, rate);
_currentFuture = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(_currentTask, delay, rate);
if (_state == EffectState.ACTING)
{
_effected.addEffect(this);
}
}
/**
* Stop the L2Effect task and send Server->Client update packet.<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Cancel the effect in the the abnormal effect map of the L2Character</li>
* <li>Stop the task of the L2Effect, remove it and update client magic icone</li><BR>
* <BR>
*/
public final void exit()
{
exit(false);
}
public final void exit(boolean preventUpdate)
{
preventExitUpdate = preventUpdate;
_state = EffectState.FINISHING;
scheduleEffect();
}
/**
* Stop the task of the L2Effect, remove it and update client magic icone.<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Cancel the task</li>
* <li>Stop and remove L2Effect from L2Character and update client magic icone</li><BR>
* <BR>
*/
public void stopEffectTask()
{
if (_currentFuture != null)
{
// Cancel the task
_currentFuture.cancel(false);
ThreadPoolManager.getInstance().removeEffect(_currentTask);
_currentFuture = null;
_currentTask = null;
if (_effected != null)
{
_effected.removeEffect(this);
}
}
}
/**
* returns effect type
* @return
*/
public abstract EffectType getEffectType();
/** Notify started */
public void onStart()
{
if (_abnormalEffect != 0)
{
getEffected().startAbnormalEffect(_abnormalEffect);
}
}
/**
* Cancel the effect in the the abnormal effect map of the effected L2Character.<BR>
* <BR>
*/
public void onExit()
{
if (_abnormalEffect != 0)
{
_effected.stopAbnormalEffect(_abnormalEffect);
}
}
/**
* Return true for continueation of this effect
* @return
*/
public abstract boolean onActionTime();
public final void rescheduleEffect()
{
if (_state != EffectState.ACTING)
{
scheduleEffect();
}
else
{
if (_count > 1)
{
startEffectTaskAtFixedRate(5, _period * 1000);
return;
}
if (_period > 0)
{
startEffectTask(_period * 1000);
return;
}
}
}
public final void scheduleEffect()
{
if (_state == EffectState.CREATED)
{
_state = EffectState.ACTING;
if (_skill.isPvpSkill())
{
final SystemMessage smsg = new SystemMessage(110);
smsg.addString(_skill.getName());
getEffected().sendPacket(smsg);
}
if (_count > 1)
{
startEffectTaskAtFixedRate(5, _period * 1000);
return;
}
if (_period > 0)
{
startEffectTask(_period * 1000);
return;
}
// effects not having count or period should start
onStart();
}
if (_state == EffectState.ACTING)
{
if (_count-- > 0)
{
if (getInUse())
{
if (onActionTime())
{
return;
}
}
else if (_count > 0)
{
return;
}
}
_state = EffectState.FINISHING;
}
if (_state == EffectState.FINISHING)
{
// Cancel the effect in the the abnormal effect map of the L2Character
if (getInUse() || !((_count > 1) || (_period > 0)))
{
onExit();
}
// If the time left is equal to zero, send the message
if (_count == 0)
{
final SystemMessage smsg3 = new SystemMessage(92);
smsg3.addString(_skill.getName());
getEffected().sendPacket(smsg3);
}
if ((_currentFuture == null) && (_effected != null))
{
_effected.removeEffect(this);
}
// Stop the task of the L2Effect, remove it and update client magic icone
stopEffectTask();
}
}
public Func[] getStatFuncs()
{
if (_funcTemplates == null)
{
return _emptyFunctionSet;
}
final List<Func> funcs = new FastList<>();
for (final FuncTemplate t : _funcTemplates)
{
final Env env = new Env();
env.player = getEffector();
env.target = getEffected();
env.skill = getSkill();
final Func f = t.getFunc(env, this); // effect is owner
if (f != null)
{
funcs.add(f);
}
}
if (funcs.size() == 0)
{
return _emptyFunctionSet;
}
return funcs.toArray(new Func[funcs.size()]);
}
public final void addIcon(MagicEffectIcons mi)
{
final EffectTask task = _currentTask;
final ScheduledFuture<?> future = _currentFuture;
if ((task == null) || (future == null))
{
return;
}
if ((_state == EffectState.FINISHING) || (_state == EffectState.CREATED))
{
return;
}
final L2Skill sk = getSkill();
if (task.rate > 0)
{
if (sk.isPotion())
{
mi.addEffect(sk.getId(), getLevel(), sk.getBuffDuration() - (getTaskTime() * 1000));
}
else
{
mi.addEffect(sk.getId(), getLevel(), -1);
}
}
else
{
mi.addEffect(sk.getId(), getLevel(), (int) future.getDelay(TimeUnit.MILLISECONDS));
}
}
public final void addPartySpelledIcon(PartySpelled ps)
{
final EffectTask task = _currentTask;
final ScheduledFuture<?> future = _currentFuture;
if ((task == null) || (future == null))
{
return;
}
if ((_state == EffectState.FINISHING) || (_state == EffectState.CREATED))
{
return;
}
final L2Skill sk = getSkill();
ps.addPartySpelledEffect(sk.getId(), getLevel(), (int) future.getDelay(TimeUnit.MILLISECONDS));
}
public final void addOlympiadSpelledIcon(ExOlympiadSpelledInfo os)
{
final EffectTask task = _currentTask;
final ScheduledFuture<?> future = _currentFuture;
if ((task == null) || (future == null))
{
return;
}
if ((_state == EffectState.FINISHING) || (_state == EffectState.CREATED))
{
return;
}
final L2Skill sk = getSkill();
os.addEffect(sk.getId(), getLevel(), (int) future.getDelay(TimeUnit.MILLISECONDS));
}
public int getLevel()
{
return getSkill().getLevel();
}
public int getPeriodfirsttime()
{
return _periodfirsttime;
}
public void setPeriodfirsttime(int periodfirsttime)
{
_periodfirsttime = periodfirsttime;
}
public int getPeriodStartTicks()
{
return _periodStartTicks;
}
public void setPeriodStartTicks(int periodStartTicks)
{
_periodStartTicks = periodStartTicks;
}
}

View File

@@ -0,0 +1,134 @@
/*
* 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.model;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
/**
* This class ...
* @version $Revision: 1.2.4.2 $ $Date: 2005/03/27 15:29:33 $
*/
public final class L2EnchantSkillLearn
{
// these two build the primary key
private final int _id;
private final int _level;
// not needed, just for easier debug
private final String _name;
private final int _spCost;
private final int _baseLvl;
private final int _minSkillLevel;
private final int _exp;
private final byte _rate76;
private final byte _rate77;
private final byte _rate78;
public L2EnchantSkillLearn(int id, int lvl, int minSkillLvl, int baseLvl, String name, int cost, int exp, byte rate76, byte rate77, byte rate78)
{
_id = id;
_level = lvl;
_baseLvl = baseLvl;
_minSkillLevel = minSkillLvl;
_name = name.intern();
_spCost = cost;
_exp = exp;
_rate76 = rate76;
_rate77 = rate77;
_rate78 = rate78;
}
/**
* @return Returns the id.
*/
public int getId()
{
return _id;
}
/**
* @return Returns the level.
*/
public int getLevel()
{
return _level;
}
/**
* @return Returns the minLevel.
*/
public int getBaseLevel()
{
return _baseLvl;
}
/**
* @return Returns the minSkillLevel.
*/
public int getMinSkillLevel()
{
return _minSkillLevel;
}
/**
* @return Returns the name.
*/
public String getName()
{
return _name;
}
/**
* @return Returns the spCost.
*/
public int getSpCost()
{
return _spCost;
}
/**
* @return Returns the exp.
*/
public int getExp()
{
return _exp;
}
public byte getRate(L2PcInstance ply)
{
byte result;
switch (ply.getLevel())
{
case 76:
result = _rate76;
break;
case 77:
result = _rate77;
break;
case 78:
result = _rate78;
break;
default:
result = _rate78;
break;
}
return result;
}
}

View File

@@ -0,0 +1,45 @@
/*
* 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.model;
import javolution.util.FastList;
/**
* @author -Nemesiss-
*/
public class L2ExtractableItem
{
private final int _itemId;
private final L2ExtractableProductItem[] _products;
public L2ExtractableItem(int itemid, FastList<L2ExtractableProductItem> products)
{
_itemId = itemid;
_products = new L2ExtractableProductItem[products.size()];
products.toArray(_products);
}
public int getItemId()
{
return _itemId;
}
public L2ExtractableProductItem[] getProductItemsArray()
{
return _products;
}
}

View File

@@ -0,0 +1,49 @@
/*
* 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.model;
/**
* @author -Nemesiss-
*/
public class L2ExtractableProductItem
{
private final int _id;
private final int _ammount;
private final int _chance;
public L2ExtractableProductItem(int id, int ammount, int chance)
{
_id = id;
_ammount = ammount;
_chance = chance;
}
public int getId()
{
return _id;
}
public int getAmmount()
{
return _ammount;
}
public int getChance()
{
return _chance;
}
}

View File

@@ -0,0 +1,355 @@
/*
* 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.model;
import java.util.concurrent.Future;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.datatables.NpcTable;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2PenaltyMonsterInstance;
import com.l2jmobius.gameserver.network.serverpackets.ExFishingHpRegen;
import com.l2jmobius.gameserver.network.serverpackets.ExFishingStartCombat;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.templates.L2NpcTemplate;
import com.l2jmobius.util.Rnd;
public class L2Fishing implements Runnable
{
// =========================================================
// Data Field
private L2PcInstance _fisher;
private int _time;
private int _stop = 0;
private int _gooduse = 0;
private int _animation = 0;
private int _mode = 0;
private Future<?> _fishAItask;
private boolean thinking;
// Fish datas
private final int _fishID;
private final int _fishMaxHP;
private int _fishCurHP;
private final double _regenHP;
private final int _lureType;
@Override
public void run()
{
if (_fishCurHP >= (_fishMaxHP * 2))
{
// The fish got away
_fisher.sendPacket(new SystemMessage(SystemMessage.BAIT_STOLEN_BY_FISH));
doDie(false);
}
else if (_time <= 0)
{
// Time is up, so that fish got away
_fisher.sendPacket(new SystemMessage(SystemMessage.FISH_SPIT_THE_HOOK));
doDie(false);
}
else
{
aiTask();
}
}
// =========================================================
public L2Fishing(L2PcInstance fisher, FishData fish, boolean isNoob)
{
_fisher = fisher;
_fishMaxHP = fish.getHP();
_fishCurHP = _fishMaxHP;
_regenHP = fish.getHpRegen();
_fishID = fish.getId();
_time = fish.getCombatTime() / 1000;
_lureType = isNoob ? 0 : 1;
_mode = Rnd.get(100) >= 80 ? 1 : 0;
final ExFishingStartCombat efsc = new ExFishingStartCombat(_fisher, _time, _fishMaxHP, _mode, _lureType);
_fisher.broadcastPacket(efsc);
// Succeeded in getting a bite
_fisher.sendPacket(new SystemMessage(SystemMessage.GOT_A_BITE));
if (_fishAItask == null)
{
_fishAItask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(this, 1000, 1000);
}
}
public void changeHp(int hp, int pen)
{
_fishCurHP -= hp;
if (_fishCurHP < 0)
{
_fishCurHP = 0;
}
final ExFishingHpRegen efhr = new ExFishingHpRegen(_fisher, _time, _fishCurHP, _mode, _gooduse, _animation, pen);
_fisher.broadcastPacket(efhr);
_animation = 0;
if (_fishCurHP > (_fishMaxHP * 2))
{
_fishCurHP = _fishMaxHP * 2;
doDie(false);
return;
}
else if (_fishCurHP == 0)
{
doDie(true);
return;
}
}
public synchronized void doDie(boolean win)
{
if (_fishAItask != null)
{
_fishAItask.cancel(false);
_fishAItask = null;
}
if (_fisher == null)
{
return;
}
if (win)
{
final int check = Rnd.get(100);
if (check <= 5)
{
penaltyMonster();
}
else
{
_fisher.sendPacket(new SystemMessage(SystemMessage.YOU_CAUGHT_SOMETHING));
_fisher.addItem("Fishing", _fishID, 1, null, true);
}
}
_fisher.endFishing(win);
_fisher = null;
}
protected void aiTask()
{
if (thinking)
{
return;
}
thinking = true;
_time--;
try
{
if (_mode == 1)
{
_fishCurHP += (int) _regenHP;
}
if (_stop == 0)
{
_stop = 1;
final int check = Rnd.get(100);
if (check >= 70)
{
_mode = _mode == 0 ? 1 : 0;
}
}
else
{
_stop--;
}
}
finally
{
thinking = false;
final ExFishingHpRegen efhr = new ExFishingHpRegen(_fisher, _time, _fishCurHP, _mode, 0, _animation, 0);
if (_animation != 0)
{
_fisher.broadcastPacket(efhr);
}
else
{
_fisher.sendPacket(efhr);
}
}
}
public void useRealing(int dmg, int pen)
{
_animation = 2;
if (Rnd.get(100) > 90)
{
_fisher.sendPacket(new SystemMessage(SystemMessage.FISH_RESISTED_ATTEMPT_TO_BRING_IT_IN));
_gooduse = 0;
changeHp(0, pen);
return;
}
if (_fisher == null)
{
return;
}
if (_mode == 1)
{
// Reeling is successful, Damage: $s1
SystemMessage sm = new SystemMessage(SystemMessage.REELING_SUCCESFUL_S1_DAMAGE);
sm.addNumber(dmg);
_fisher.sendPacket(sm);
if (pen == 50)
{
sm = new SystemMessage(SystemMessage.REELING_SUCCESSFUL_PENALTY_S1);
sm.addNumber(pen);
_fisher.sendPacket(sm);
}
_gooduse = 1;
changeHp(dmg, pen);
}
else
{
// Reeling failed, Damage: $s1
final SystemMessage sm = new SystemMessage(SystemMessage.FISH_RESISTED_REELING_S1_HP_REGAINED);
sm.addNumber(dmg);
_fisher.sendPacket(sm);
_gooduse = 2;
changeHp(-dmg, pen);
}
}
public void usePumping(int dmg, int pen)
{
_animation = 1;
if (Rnd.get(100) > 90)
{
_fisher.sendPacket(new SystemMessage(SystemMessage.FISH_RESISTED_ATTEMPT_TO_BRING_IT_IN));
_gooduse = 0;
changeHp(0, pen);
return;
}
if (_fisher == null)
{
return;
}
if (_mode == 0)
{
// Pumping is successful. Damage: $s1
SystemMessage sm = new SystemMessage(SystemMessage.PUMPING_SUCCESFUL_S1_DAMAGE);
sm.addNumber(dmg);
_fisher.sendPacket(sm);
if (pen == 50)
{
sm = new SystemMessage(SystemMessage.PUMPING_SUCCESSFUL_PENALTY_S1);
sm.addNumber(pen);
_fisher.sendPacket(sm);
}
_gooduse = 1;
changeHp(dmg, pen);
}
else
{
// Pumping failed, Regained: $s1
final SystemMessage sm = new SystemMessage(SystemMessage.FISH_RESISTED_PUMPING_S1_HP_REGAINED);
sm.addNumber(dmg);
_fisher.sendPacket(sm);
_gooduse = 2;
changeHp(-dmg, pen);
}
}
private void penaltyMonster()
{
final int lvl = (int) Math.round(_fisher.getLevel() * 0.1);
int npcid;
_fisher.sendPacket(new SystemMessage(SystemMessage.YOU_CAUGHT_SOMETHING_SMELLY_THROW_IT_BACK));
switch (lvl)
{
case 0:
case 1:
npcid = 13245;
break;
case 2:
npcid = 13246;
break;
case 3:
npcid = 13247;
break;
case 4:
npcid = 13248;
break;
case 5:
npcid = 13249;
break;
case 6:
npcid = 13250;
break;
case 7:
npcid = 13251;
break;
case 8:
npcid = 13252;
break;
default:
npcid = 13245;
break;
}
L2NpcTemplate temp;
temp = NpcTable.getInstance().getTemplate(npcid);
if (temp != null)
{
try
{
final L2Spawn spawn = new L2Spawn(temp);
spawn.setLocx(_fisher.getFishx());
spawn.setLocy(_fisher.getFishy());
spawn.setLocz(_fisher.getFishz());
spawn.setAmount(1);
spawn.setHeading(_fisher.getHeading());
spawn.stopRespawn();
((L2PenaltyMonsterInstance) spawn.doSpawn()).SetPlayerToKill(_fisher);
}
catch (final Exception e)
{
// Nothing
}
}
}
}

View File

@@ -0,0 +1,102 @@
/*
* 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.model;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.Territory;
import com.l2jmobius.gameserver.idfactory.IdFactory;
import com.l2jmobius.gameserver.model.actor.instance.L2ControllableMobInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2NpcInstance;
import com.l2jmobius.gameserver.templates.L2NpcTemplate;
import com.l2jmobius.util.Rnd;
/**
* @author littlecrow A special spawn implementation to spawn controllable mob
*/
public class L2GroupSpawn extends L2Spawn
{
private final L2NpcTemplate _template;
public L2GroupSpawn(L2NpcTemplate mobTemplate) throws SecurityException, ClassNotFoundException, NoSuchMethodException
{
super(mobTemplate);
_template = mobTemplate;
setAmount(1);
}
public L2NpcInstance doGroupSpawn()
{
try
{
if (_template.type.equalsIgnoreCase("L2Pet") || _template.type.equalsIgnoreCase("L2Minion"))
{
return null;
}
int newlocx, newlocy, newlocz;
if ((getLocx() == 0) && (getLocy() == 0))
{
if (getLocation() == 0)
{
return null;
}
final int p[] = Territory.getInstance().getRandomPoint(getLocation());
newlocx = p[0];
newlocy = p[1];
newlocz = p[2];
}
else
{
newlocx = getLocx();
newlocy = getLocy();
newlocz = getLocz();
}
final L2NpcInstance mob = new L2ControllableMobInstance(IdFactory.getInstance().getNextId(), _template);
mob.setCurrentHpMp(mob.getMaxHp(), mob.getMaxMp());
if (getHeading() == -1)
{
mob.setHeading(Rnd.nextInt(61794));
}
else
{
mob.setHeading(getHeading());
}
mob.setSpawn(this);
mob.spawnMe(newlocx, newlocy, newlocz);
mob.onSpawn();
if (Config.DEBUG)
{
_log.finest("spawned Mob ID: " + _template.npcId + " ,at: " + mob.getX() + " x, " + mob.getY() + " y, " + mob.getZ() + " z");
}
return mob;
}
catch (final Exception e)
{
_log.warning("NPC class not found: " + e);
return null;
}
}
}

View File

@@ -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.model;
import com.l2jmobius.gameserver.templates.L2Henna;
/**
* This class represents a Non-Player-Character in the world. it can be a monster or a friendly character. it also uses a template to fetch some static values. the templates are hardcoded in the client, so we can rely on them.
* @version $Revision$ $Date$
*/
public class L2HennaInstance
{
// private static Logger _log = Logger.getLogger(L2HennaInstance.class.getName());
private final L2Henna _template;
private int _symbolId;
private int _itemIdDye;
private int _price;
private int _statINT;
private int _statSTR;
private int _statCON;
private int _statMEN;
private int _statDEX;
private int _statWIT;
private int _amountDyeRequire;
public L2HennaInstance(L2Henna template)
{
_template = template;
_symbolId = _template.symbol_id;
_itemIdDye = _template.dye;
_amountDyeRequire = _template.amount;
_price = _template.price;
_statINT = _template.stat_INT;
_statSTR = _template.stat_STR;
_statCON = _template.stat_CON;
_statMEN = _template.stat_MEN;
_statDEX = _template.stat_DEX;
_statWIT = _template.stat_WIT;
}
public String getName()
{
String res = "";
if (_statINT > 0)
{
res = res + "INT +" + _statINT;
}
else if (_statSTR > 0)
{
res = res + "STR +" + _statSTR;
}
else if (_statCON > 0)
{
res = res + "CON +" + _statCON;
}
else if (_statMEN > 0)
{
res = res + "MEN +" + _statMEN;
}
else if (_statDEX > 0)
{
res = res + "DEX +" + _statDEX;
}
else if (_statWIT > 0)
{
res = res + "WIT +" + _statWIT;
}
if (_statINT < 0)
{
res = res + ", INT " + _statINT;
}
else if (_statSTR < 0)
{
res = res + ", STR " + _statSTR;
}
else if (_statCON < 0)
{
res = res + ", CON " + _statCON;
}
else if (_statMEN < 0)
{
res = res + ", MEN " + _statMEN;
}
else if (_statDEX < 0)
{
res = res + ", DEX " + _statDEX;
}
else if (_statWIT < 0)
{
res = res + ", WIT " + _statWIT;
}
return res;
}
public L2Henna getTemplate()
{
return _template;
}
public int getSymbolId()
{
return _symbolId;
}
public void setSymbolId(int SymbolId)
{
_symbolId = SymbolId;
}
public int getItemIdDye()
{
return _itemIdDye;
}
public void setItemIdDye(int ItemIdDye)
{
_itemIdDye = ItemIdDye;
}
public int getAmountDyeRequire()
{
return _amountDyeRequire;
}
public void setAmountDyeRequire(int AmountDyeRequire)
{
_amountDyeRequire = AmountDyeRequire;
}
public int getPrice()
{
return _price;
}
public void setPrice(int Price)
{
_price = Price;
}
public int getStatINT()
{
return _statINT;
}
public void setStatINT(int StatINT)
{
_statINT = StatINT;
}
public int getStatSTR()
{
return _statSTR;
}
public void setStatSTR(int StatSTR)
{
_statSTR = StatSTR;
}
public int getStatCON()
{
return _statCON;
}
public void setStatCON(int StatCON)
{
_statCON = StatCON;
}
public int getStatMEN()
{
return _statMEN;
}
public void setStatMEN(int StatMEN)
{
_statMEN = StatMEN;
}
public int getStatDEX()
{
return _statDEX;
}
public void setStatDEX(int StatDEX)
{
_statDEX = StatDEX;
}
public int getStatWIT()
{
return _statWIT;
}
public void setStatWIT(int StatWIT)
{
_statWIT = StatWIT;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,213 @@
/*
* 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.model;
/**
* This class ...
* @author NightMarez
* @version $Revision: 1.2.2.1.2.1 $ $Date: 2005/03/27 15:29:32 $
*/
public class L2LvlupData
{
private int _classid;
private int _classLvl;
private float _classHpAdd;
private float _classHpBase;
private float _classHpModifier;
private float _classCpAdd;
private float _classCpBase;
private float _classCpModifier;
private float _classMpAdd;
private float _classMpBase;
private float _classMpModifier;
/**
* @return Returns the _classHpAdd.
*/
public float get_classHpAdd()
{
return _classHpAdd;
}
/**
* @param hpAdd The _classHpAdd to set.
*/
public void set_classHpAdd(float hpAdd)
{
_classHpAdd = hpAdd;
}
/**
* @return Returns the _classHpBase.
*/
public float get_classHpBase()
{
return _classHpBase;
}
/**
* @param hpBase The _classHpBase to set.
*/
public void set_classHpBase(float hpBase)
{
_classHpBase = hpBase;
}
/**
* @return Returns the _classHpModifier.
*/
public float get_classHpModifier()
{
return _classHpModifier;
}
/**
* @param hpModifier The _classHpModifier to set.
*/
public void set_classHpModifier(float hpModifier)
{
_classHpModifier = hpModifier;
}
/**
* @return Returns the _classCpAdd.
*/
public float get_classCpAdd()
{
return _classCpAdd;
}
/**
* @param cpAdd The _classCpAdd to set.
*/
public void set_classCpAdd(float cpAdd)
{
_classCpAdd = cpAdd;
}
/**
* @return Returns the _classCpBase.
*/
public float get_classCpBase()
{
return _classCpBase;
}
/**
* @param cpBase The _classCpBase to set.
*/
public void set_classCpBase(float cpBase)
{
_classCpBase = cpBase;
}
/**
* @return Returns the _classCpModifier.
*/
public float get_classCpModifier()
{
return _classCpModifier;
}
/**
* @param cpModifier The _classCpModifier to set.
*/
public void set_classCpModifier(float cpModifier)
{
_classCpModifier = cpModifier;
}
/**
* @return Returns the _classid.
*/
public int get_classid()
{
return _classid;
}
/**
* @param pClassid The _classid to set.
*/
public void set_classid(int pClassid)
{
_classid = pClassid;
}
/**
* @return Returns the _classLvl.
*/
public int get_classLvl()
{
return _classLvl;
}
/**
* @param lvl The _classLvl to set.
*/
public void set_classLvl(int lvl)
{
_classLvl = lvl;
}
/**
* @return Returns the _classMpAdd.
*/
public float get_classMpAdd()
{
return _classMpAdd;
}
/**
* @param mpAdd The _classMpAdd to set.
*/
public void set_classMpAdd(float mpAdd)
{
_classMpAdd = mpAdd;
}
/**
* @return Returns the _classMpBase.
*/
public float get_classMpBase()
{
return _classMpBase;
}
/**
* @param mpBase The _classMpBase to set.
*/
public void set_classMpBase(float mpBase)
{
_classMpBase = mpBase;
}
/**
* @return Returns the _classMpModifier.
*/
public float get_classMpModifier()
{
return _classMpModifier;
}
/**
* @param mpModifier The _classMpModifier to set.
*/
public void set_classMpModifier(float mpModifier)
{
_classMpModifier = mpModifier;
}
}

View File

@@ -0,0 +1,72 @@
/*
* 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.model;
/**
* This class ...
* @version $Revision: 1.3 $ $Date: 2004/10/23 22:12:44 $
*/
public class L2Macro
{
public final static int CMD_TYPE_SKILL = 1;
public final static int CMD_TYPE_ACTION = 3;
public final static int CMD_TYPE_SHORTCUT = 4;
public int id;
public final int icon;
public final String name;
public final String descr;
public final String acronym;
public final L2MacroCmd[] commands;
public static class L2MacroCmd
{
public final int entry;
public final int type;
public final int d1; // skill_id or page for shortcuts
public final int d2; // shortcut
public final String cmd;
public L2MacroCmd(int pEntry, int pType, int pD1, int pD2, String pCmd)
{
entry = pEntry;
type = pType;
d1 = pD1;
d2 = pD2;
cmd = pCmd;
}
}
/**
* @param pId
* @param pIcon
* @param pName
* @param pDescr
* @param pAcronym
* @param pCommands
*/
public L2Macro(int pId, int pIcon, String pName, String pDescr, String pAcronym, L2MacroCmd[] pCommands)
{
id = pId;
icon = pIcon;
name = pName;
descr = pDescr;
acronym = pAcronym;
commands = pCommands;
}
}

View File

@@ -0,0 +1,434 @@
/*
* 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.model;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.LineNumberReader;
import java.util.StringTokenizer;
import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.templates.L2Item;
import javolution.util.FastList;
import javolution.util.FastMap;
/**
* Service class for manor
* @author l3x
*/
public class L2Manor
{
private static Logger _log = Logger.getLogger(L2Manor.class.getName());
private static L2Manor _instance;
private static FastMap<Integer, SeedData> _seeds;
public L2Manor()
{
_seeds = new FastMap<Integer, SeedData>().shared();
parseData();
}
public static L2Manor getInstance()
{
if (_instance == null)
{
_instance = new L2Manor();
}
return _instance;
}
public FastList<Integer> getAllCrops()
{
final FastList<Integer> crops = new FastList<>();
for (final SeedData seed : _seeds.values())
{
if (!crops.contains(seed.getCrop()) && (seed.getCrop() != 0) && !crops.contains(seed.getCrop()))
{
crops.add(seed.getCrop());
}
}
return crops;
}
public int getSeedBasicPrice(int seedId)
{
final L2Item seedItem = ItemTable.getInstance().getTemplate(seedId);
if (seedItem == null)
{
return 0;
}
return seedItem.getReferencePrice();
}
public int getSeedBasicPriceByCrop(int cropId)
{
for (final SeedData seed : _seeds.values())
{
if (seed.getCrop() == cropId)
{
return getSeedBasicPrice(seed.getId());
}
}
return 0;
}
public int getCropBasicPrice(int cropId)
{
final L2Item cropItem = ItemTable.getInstance().getTemplate(cropId);
if (cropItem == null)
{
return 0;
}
return cropItem.getReferencePrice();
}
public int getMatureCrop(int cropId)
{
for (final SeedData seed : _seeds.values())
{
if (seed.getCrop() == cropId)
{
return seed.getMature();
}
}
return 0;
}
public int getSeedBuyPrice(int seedId)
{
final int buyPrice = getSeedBasicPrice(seedId) / 10;
return (buyPrice > 0 ? buyPrice : 1);
}
public int getSeedMinLevel(int seedId)
{
final SeedData seed = _seeds.get(seedId);
if (seed == null)
{
return -1;
}
return seed.getLevel() - 5;
}
public int getSeedMaxLevel(int seedId)
{
final SeedData seed = _seeds.get(seedId);
if (seed == null)
{
return -1;
}
return seed.getLevel() + 5;
}
public int getSeedLevelByCrop(int cropId)
{
for (final SeedData seed : _seeds.values())
{
if (seed.getCrop() == cropId)
{
return seed.getLevel();
}
}
return 0;
}
public int getSeedLevel(int seedId)
{
final SeedData seed = _seeds.get(seedId);
if (seed == null)
{
return -1;
}
return seed.getLevel();
}
public boolean isAlternative(int seedId)
{
for (final SeedData seed : _seeds.values())
{
if (seed.getId() == seedId)
{
return seed.isAlternative();
}
}
return false;
}
public int getCropType(int seedId)
{
final SeedData seed = _seeds.get(seedId);
if (seed == null)
{
return -1;
}
return seed.getCrop();
}
public synchronized int getRewardItem(int cropId, int type)
{
for (final SeedData seed : _seeds.values())
{
if (seed.getCrop() == cropId)
{
return seed.getReward(type);
}
}
return -1;
}
public synchronized int getRewardItemBySeed(int seedId, int type)
{
final SeedData seed = _seeds.get(seedId);
if (seed == null)
{
return 0;
}
return seed.getReward(type);
}
/**
* Return all crops which can be purchased by given castle
* @param castleId
* @return
*/
public FastList<Integer> getCropsForCastle(int castleId)
{
final FastList<Integer> crops = new FastList<>();
for (final SeedData seed : _seeds.values())
{
if ((seed.getManorId() == castleId) && !crops.contains(seed.getCrop()))
{
crops.add(seed.getCrop());
}
}
return crops;
}
/**
* Return list of seed ids, which belongs to castle with given id
* @param castleId - id of the castle
* @return seedIds - list of seed ids
*/
public FastList<Integer> getSeedsForCastle(int castleId)
{
final FastList<Integer> seedsID = new FastList<>();
for (final SeedData seed : _seeds.values())
{
if ((seed.getManorId() == castleId) && !seedsID.contains(seed.getId()))
{
seedsID.add(seed.getId());
}
}
return seedsID;
}
public int getCastleIdForSeed(int seedId)
{
final SeedData seed = _seeds.get(seedId);
if (seed == null)
{
return 0;
}
return seed.getManorId();
}
public int getSeedSaleLimit(int seedId)
{
final SeedData seed = _seeds.get(seedId);
if (seed == null)
{
return 0;
}
return seed.getSeedLimit();
}
public int getCropPuchaseLimit(int cropId)
{
for (final SeedData seed : _seeds.values())
{
if (seed.getCrop() == cropId)
{
return seed.getCropLimit();
}
}
return 0;
}
private class SeedData
{
private int _id;
private final int _level; // seed level
private final int _crop; // crop type
private final int _mature; // mature crop type
private int _type1;
private int _type2;
private int _manorId; // id of manor (castle id) where seed can be farmed
private int _isAlternative;
private int _limitSeeds;
private int _limitCrops;
public SeedData(int level, int crop, int mature)
{
_level = level;
_crop = crop;
_mature = mature;
}
public void setData(int id, int t1, int t2, int manorId, int isAlt, int lim1, int lim2)
{
_id = id;
_type1 = t1;
_type2 = t2;
_manorId = manorId;
_isAlternative = isAlt;
_limitSeeds = lim1;
_limitCrops = lim2;
}
public int getManorId()
{
return _manorId;
}
public int getId()
{
return _id;
}
public int getCrop()
{
return _crop;
}
public int getMature()
{
return _mature;
}
public int getReward(int type)
{
return (type == 1 ? _type1 : _type2);
}
public int getLevel()
{
return _level;
}
public boolean isAlternative()
{
return (_isAlternative == 1);
}
public int getSeedLimit()
{
return _limitSeeds * Config.RATE_DROP_MANOR;
}
public int getCropLimit()
{
return _limitCrops * Config.RATE_DROP_MANOR;
}
}
private void parseData()
{
final File seedData = new File(Config.DATAPACK_ROOT, "data/seeds.csv");
try (FileReader fr = new FileReader(seedData);
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 SeedData seed = parseList(line);
_seeds.put(seed.getId(), seed);
}
_log.info("ManorManager: Loaded " + _seeds.size() + " seeds");
}
catch (final FileNotFoundException e)
{
_log.info("seeds.csv is missing in data folder");
}
catch (final Exception e)
{
_log.info("error while loading seeds: " + e.getMessage());
}
}
private SeedData parseList(String line)
{
final StringTokenizer st = new StringTokenizer(line, ";");
final int seedId = Integer.parseInt(st.nextToken()); // seed id
final int level = Integer.parseInt(st.nextToken()); // seed level
final int cropId = Integer.parseInt(st.nextToken()); // crop id
final int matureId = Integer.parseInt(st.nextToken()); // mature crop id
final int type1R = Integer.parseInt(st.nextToken()); // type I reward
final int type2R = Integer.parseInt(st.nextToken()); // type II reward
final int manorId = Integer.parseInt(st.nextToken()); // id of manor, where seed can be farmed
final int isAlt = Integer.parseInt(st.nextToken()); // alternative seed
final int limitSeeds = Integer.parseInt(st.nextToken()); // limit for seeds
final int limitCrops = Integer.parseInt(st.nextToken()); // limit for crops
final SeedData seed = new SeedData(level, cropId, matureId);
seed.setData(seedId, type1R, type2R, manorId, isAlt, limitSeeds, limitCrops);
return seed;
}
}

View File

@@ -0,0 +1,52 @@
/*
* 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.model;
import com.l2jmobius.gameserver.RecipeController;
/**
* This class ...
* @version $Revision: 1.1.2.2.2.1 $ $Date: 2005/03/27 15:29:32 $
*/
public class L2ManufactureItem
{
private final int _recipeId;
private final int _cost;
private final boolean _isDwarven;
public L2ManufactureItem(int recipeId, int cost)
{
_recipeId = recipeId;
_cost = cost;
_isDwarven = RecipeController.getInstance().getRecipeById(_recipeId).isDwarvenRecipe();
}
public int getRecipeId()
{
return _recipeId;
}
public int getCost()
{
return _cost;
}
public boolean isDwarven()
{
return _isDwarven;
}
}

View File

@@ -0,0 +1,84 @@
/*
* 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.model;
import java.util.List;
import javolution.util.FastList;
/**
* This class ...
* @version $Revision: 1.1.2.1.2.2 $ $Date: 2005/03/27 15:29:33 $
*/
public class L2ManufactureList
{
private List<L2ManufactureItem> _list;
private boolean _confirmed;
private String _manufactureStoreName;
public L2ManufactureList()
{
_list = new FastList<>();
_confirmed = false;
}
public int size()
{
return _list.size();
}
public void setConfirmedTrade(boolean x)
{
_confirmed = x;
}
public boolean hasConfirmed()
{
return _confirmed;
}
/**
* @param manufactureStoreName The _manufactureStoreName to set.
*/
public void setStoreName(String manufactureStoreName)
{
_manufactureStoreName = manufactureStoreName;
}
/**
* @return Returns the _manufactureStoreName.
*/
public String getStoreName()
{
return _manufactureStoreName;
}
public void add(L2ManufactureItem item)
{
_list.add(item);
}
public List<L2ManufactureItem> getList()
{
return _list;
}
public void setList(List<L2ManufactureItem> list)
{
_list = list;
}
}

View File

@@ -0,0 +1,102 @@
/*
* 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.model;
import com.l2jmobius.util.Rnd;
/**
* This class defines the spawn data of a Minion type In a group mob, there are one master called RaidBoss and several slaves called Minions. <B><U> Data</U> :</B><BR>
* <BR>
* <li>_minionId : The Identifier of the L2Minion to spawn</li>
* <li>_minionAmount : The number of this Minion Type to spawn</li><BR>
* <BR>
*/
public class L2MinionData
{
/** The Identifier of the L2Minion */
private int _minionId;
/** The number of this Minion Type to spawn */
private int _minionAmount;
private int _minionAmountMin;
private int _minionAmountMax;
/**
* Set the Identifier of the Minion to spawn.<BR>
* <BR>
* @param id The L2Character Identifier to spawn
*/
public void setMinionId(int id)
{
_minionId = id;
}
/**
* Return the Identifier of the Minion to spawn.<BR>
* <BR>
* @return
*/
public int getMinionId()
{
return _minionId;
}
/**
* Set the minimum of minions to amount.<BR>
* <BR>
* @param amountMin The minimum quantity of this Minion type to spawn
*/
public void setAmountMin(int amountMin)
{
_minionAmountMin = amountMin;
}
/**
* Set the maximum of minions to amount.<BR>
* <BR>
* @param amountMax The maximum quantity of this Minion type to spawn
*/
public void setAmountMax(int amountMax)
{
_minionAmountMax = amountMax;
}
/**
* Set the amount of this Minion type to spawn.<BR>
* <BR>
* @param amount The quantity of this Minion type to spawn
*/
public void setAmount(int amount)
{
_minionAmount = amount;
}
/**
* Return the amount of this Minion type to spawn.<BR>
* <BR>
* @return
*/
public int getAmount()
{
if (_minionAmountMax > _minionAmountMin)
{
_minionAmount = Rnd.get(_minionAmountMin, _minionAmountMax);
return _minionAmount;
}
return _minionAmountMin;
}
}

View File

@@ -0,0 +1,628 @@
/*
* 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.model;
import java.io.File;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.model.actor.instance.L2NpcInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.serverpackets.MultiSellList;
import com.l2jmobius.gameserver.templates.L2Armor;
import com.l2jmobius.gameserver.templates.L2Item;
import com.l2jmobius.gameserver.templates.L2Weapon;
import javolution.util.FastList;
/**
* Multisell list manager
*/
public class L2Multisell
{
private static Logger _log = Logger.getLogger(L2Multisell.class.getName());
private final List<MultiSellListContainer> entries = new FastList<>();
private static L2Multisell _instance;
public MultiSellListContainer getList(int id)
{
synchronized (entries)
{
for (final MultiSellListContainer list : entries)
{
if (list.getListId() == id)
{
return list;
}
}
}
_log.warning("[L2Multisell] cant find list with id: " + id);
return null;
}
public L2Multisell()
{
parseData();
}
public void reload()
{
parseData();
}
public static L2Multisell getInstance()
{
if (_instance == null)
{
_instance = new L2Multisell();
}
return _instance;
}
private void parseData()
{
entries.clear();
parse();
_log.config("L2Multisell: Loaded " + entries.size() + " lists.");
}
public class MultiSellEntry
{
private int _entryId;
private final List<MultiSellIngredient> _products = new FastList<>();
private final List<MultiSellIngredient> _ingredients = new FastList<>();
/**
* @param entryId The entryId to set.
*/
public void setEntryId(int entryId)
{
_entryId = entryId;
}
/**
* @return Returns the entryId.
*/
public int getEntryId()
{
return _entryId;
}
/**
* @param product The product to add.
*/
public void addProduct(MultiSellIngredient product)
{
_products.add(product);
}
/**
* @return Returns the products.
*/
public List<MultiSellIngredient> getProducts()
{
return _products;
}
/**
* @param ingredient The ingredients to set.
*/
public void addIngredient(MultiSellIngredient ingredient)
{
_ingredients.add(ingredient);
}
/**
* @return Returns the ingredients.
*/
public List<MultiSellIngredient> getIngredients()
{
return _ingredients;
}
}
public class MultiSellIngredient
{
private int _itemId;
private long _itemCount;
private int _enchantmentLevel;
public MultiSellIngredient(int itemId, int itemCount)
{
this(itemId, itemCount, 0);
}
public MultiSellIngredient(int itemId, long itemCount, int enchantmentLevel)
{
setItemId(itemId);
setItemCount(itemCount);
setEnchantmentLevel(enchantmentLevel);
}
public MultiSellIngredient(MultiSellIngredient e)
{
_itemId = e.getItemId();
_itemCount = e.getItemCount();
_enchantmentLevel = e.getEnchantmentLevel();
}
/**
* @param itemId The itemId to set.
*/
public void setItemId(int itemId)
{
_itemId = itemId;
}
/**
* @return Returns the itemId.
*/
public int getItemId()
{
return _itemId;
}
/**
* @param itemCount The itemCount to set.
*/
public void setItemCount(long itemCount)
{
_itemCount = itemCount;
}
/**
* @return Returns the itemCount.
*/
public long getItemCount()
{
return _itemCount;
}
/**
* @param enchantmentLevel The itemCount to set.
*/
public void setEnchantmentLevel(int enchantmentLevel)
{
_enchantmentLevel = enchantmentLevel;
}
/**
* @return Returns the itemCount.
*/
public int getEnchantmentLevel()
{
return _enchantmentLevel;
}
}
public class MultiSellListContainer
{
private int _listId;
private boolean _applyTaxes = false;
private boolean _maintainEnchantment = false;
private List<Integer> _npcIds;
List<MultiSellEntry> entriesC;
public MultiSellListContainer()
{
entriesC = new FastList<>();
}
/**
* @param listId The listId to set.
*/
public void setListId(int listId)
{
_listId = listId;
}
public void setApplyTaxes(boolean applyTaxes)
{
_applyTaxes = applyTaxes;
}
public void setMaintainEnchantment(boolean maintainEnchantment)
{
_maintainEnchantment = maintainEnchantment;
}
public void addNpcId(int objId)
{
_npcIds.add(objId);
}
/**
* @return Returns the listId.
*/
public int getListId()
{
return _listId;
}
public boolean getApplyTaxes()
{
return _applyTaxes;
}
public boolean getMaintainEnchantment()
{
return _maintainEnchantment;
}
public boolean checkNpcId(int npcId)
{
if (_npcIds == null)
{
synchronized (this)
{
if (_npcIds == null)
{
_npcIds = new FastList<>();
}
}
return false;
}
return _npcIds.contains(npcId);
}
public void addEntry(MultiSellEntry e)
{
entriesC.add(e);
}
public List<MultiSellEntry> getEntries()
{
return entriesC;
}
}
private void hashFiles(String dirname, List<File> hash)
{
final File dir = new File(Config.DATAPACK_ROOT, "data/" + dirname);
if (!dir.exists())
{
_log.config("Dir " + dir.getAbsolutePath() + " not exists");
return;
}
final File[] files = dir.listFiles();
for (final File f : files)
{
if (f.getName().endsWith(".xml"))
{
hash.add(f);
}
}
}
private void parse()
{
Document doc = null;
int id = 0;
final List<File> files = new FastList<>();
hashFiles("multisell", files);
for (final File f : files)
{
id = Integer.parseInt(f.getName().replaceAll(".xml", ""));
try
{
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(false);
factory.setIgnoringComments(true);
doc = factory.newDocumentBuilder().parse(f);
}
catch (final Exception e)
{
_log.log(Level.SEVERE, "Error loading file " + f, e);
}
try
{
final MultiSellListContainer list = parseDocument(doc);
list.setListId(id);
entries.add(list);
}
catch (final Exception e)
{
_log.log(Level.SEVERE, "Error in file " + f, e);
}
}
}
protected MultiSellListContainer parseDocument(Document doc)
{
final MultiSellListContainer list = new MultiSellListContainer();
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
Node attribute;
attribute = n.getAttributes().getNamedItem("applyTaxes");
if (attribute == null)
{
list.setApplyTaxes(false);
}
else
{
list.setApplyTaxes(Boolean.parseBoolean(attribute.getNodeValue()));
}
attribute = n.getAttributes().getNamedItem("maintainEnchantment");
if (attribute == null)
{
list.setMaintainEnchantment(false);
}
else
{
list.setMaintainEnchantment(Boolean.parseBoolean(attribute.getNodeValue()));
}
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("item".equalsIgnoreCase(d.getNodeName()))
{
final MultiSellEntry e = parseEntry(d);
list.addEntry(e);
}
}
}
else if ("item".equalsIgnoreCase(n.getNodeName()))
{
final MultiSellEntry e = parseEntry(n);
list.addEntry(e);
}
}
return list;
}
protected MultiSellEntry parseEntry(Node n)
{
final int entryId = Integer.parseInt(n.getAttributes().getNamedItem("id").getNodeValue());
final Node first = n.getFirstChild();
final MultiSellEntry entry = new MultiSellEntry();
for (n = first; n != null; n = n.getNextSibling())
{
if ("ingredient".equalsIgnoreCase(n.getNodeName()))
{
final int id = Integer.parseInt(n.getAttributes().getNamedItem("id").getNodeValue());
final int count = Integer.parseInt(n.getAttributes().getNamedItem("count").getNodeValue());
final MultiSellIngredient e = new MultiSellIngredient(id, count);
entry.addIngredient(e);
}
else if ("production".equalsIgnoreCase(n.getNodeName()))
{
final int id = Integer.parseInt(n.getAttributes().getNamedItem("id").getNodeValue());
final int count = Integer.parseInt(n.getAttributes().getNamedItem("count").getNodeValue());
final MultiSellIngredient e = new MultiSellIngredient(id, count);
entry.addProduct(e);
}
}
entry.setEntryId(entryId);
return entry;
}
/**
* This will generate the multisell list for the items. There exist various parameters in multisells that affect the way they will appear: 1) inventory only: * if true, only show items of the multisell for which the "primary" ingredients are already in the player's inventory. By "primary"
* ingredients we mean weapon and armor. * if false, show the entire list. 2) maintain enchantment: presumably, only lists with "inventory only" set to true should sometimes have this as true. This makes no sense otherwise... * If true, then the product will match the enchantment level of the
* ingredient. if the player has multiple items that match the ingredient list but the enchantment levels differ, then the entries need to be duplicated to show the products and ingredients for each enchantment level. For example: If the player has a crystal staff +1 and a crystal staff +3 and
* goes to exchange it at the mammon, the list should have all exchange possibilities for the +1 staff, followed by all possibilities for the +3 staff. * If false, then any level ingredient will be considered equal and product will always be at +0 3) apply taxes: affects the amount of adena and
* ancient adena in ingredients.
* @param listId
* @param inventoryOnly
* @param player
* @param merchant
* @return
*/
private MultiSellListContainer generateMultiSell(int listId, boolean inventoryOnly, L2PcInstance player, L2NpcInstance merchant)
{
final MultiSellListContainer listTemplate = L2Multisell.getInstance().getList(listId);
MultiSellListContainer list = new MultiSellListContainer();
if (listTemplate == null)
{
return list;
}
list = L2Multisell.getInstance().new MultiSellListContainer();
list.setListId(listId);
if ((merchant != null) && !listTemplate.checkNpcId(merchant.getNpcId()))
{
listTemplate.addNpcId(merchant.getNpcId());
}
if (inventoryOnly)
{
if (player == null)
{
return list;
}
L2ItemInstance[] items;
if (listTemplate.getMaintainEnchantment())
{
items = player.getInventory().getUniqueItemsByEnchantLevel(false, false);
}
else
{
items = player.getInventory().getUniqueItems(false, false);
}
int enchantLevel;
for (final L2ItemInstance item : items)
{
// only do the matchup on equipable items that are not currently equipped
// so for each appropriate item, produce a set of entries for the multisell list.
if (!item.isWear() && ((item.getItem() instanceof L2Armor) || (item.getItem() instanceof L2Weapon)))
{
enchantLevel = (listTemplate.getMaintainEnchantment() ? item.getEnchantLevel() : 0);
// loop through the entries to see which ones we wish to include
for (final MultiSellEntry ent : listTemplate.getEntries())
{
boolean doInclude = false;
// check ingredients of this entry to see if it's an entry we'd like to include.
for (final MultiSellIngredient ing : ent.getIngredients())
{
if (item.getItemId() == ing.getItemId())
{
doInclude = true;
break;
}
}
// manipulate the ingredients of the template entry for this particular instance shown
// i.e: Assign enchant levels and/or apply taxes as needed.
if (doInclude)
{
list.addEntry(prepareEntry(ent, listTemplate.getApplyTaxes(), listTemplate.getMaintainEnchantment(), enchantLevel, merchant));
}
}
}
} // end for each inventory item.
} // end if "inventory-only"
else // this is a list-all type
{
// if no taxes are applied, no modifications are needed
for (final MultiSellEntry ent : listTemplate.getEntries())
{
list.addEntry(prepareEntry(ent, listTemplate.getApplyTaxes(), false, 0, merchant));
}
}
return list;
}
// Regarding taxation, the following appears to be the case:
// a) The count of aa remains unchanged (taxes do not affect aa directly).
// b) 5/6 of the amount of aa is taxed by the normal tax rate.
// c) the resulting taxes are added as normal adena value.
// d) normal adena are taxed fully.
// e) Items other than adena and ancient adena are not taxed even when the list is taxable.
// example: If the template has an item worth 120aa, and the tax is 10%,
// then from 120aa, take 5/6 so that is 100aa, apply the 10% tax in adena (10a)
// so the final price will be 120aa and 10a!
private MultiSellEntry prepareEntry(MultiSellEntry templateEntry, boolean applyTaxes, boolean maintainEnchantment, int enchantLevel, L2NpcInstance merchant)
{
final MultiSellEntry newEntry = L2Multisell.getInstance().new MultiSellEntry();
newEntry.setEntryId((templateEntry.getEntryId() * 100000) + enchantLevel);
for (final MultiSellIngredient ing : templateEntry.getIngredients())
{
// load the ingredient from the template
MultiSellIngredient newIngredient = L2Multisell.getInstance().new MultiSellIngredient(ing);
// if taxes are to be applied, modify/add the adena count based on the template adena/ancient adena count
if (applyTaxes && ((ing.getItemId() == 57) || (ing.getItemId() == 5575)))
{
double taxRate = 0.0;
if ((merchant != null) && (merchant.getCastle() != null))
{
taxRate = merchant.getCastle().getTaxRate();
}
if (ing.getItemId() == 57)
{
final int taxAmount = (int) Math.round(ing.getItemCount() * taxRate);
newIngredient.setItemCount(ing.getItemCount() + taxAmount);
}
else // ancient adena
{
// add the ancient adena count normally
newEntry.addIngredient(newIngredient);
final double taxableCount = (ing.getItemCount() * 5.0) / 6;
if (taxRate == 0)
{
continue;
}
newIngredient = L2Multisell.getInstance().new MultiSellIngredient(57, (int) Math.round(taxableCount * taxRate));
}
}
// if it is an armor/weapon, modify the enchantment level appropriately, if necessary
else if (maintainEnchantment)
{
final L2Item tempItem = ItemTable.getInstance().createDummyItem(ing.getItemId()).getItem();
if ((tempItem instanceof L2Armor) || (tempItem instanceof L2Weapon))
{
newIngredient.setEnchantmentLevel(enchantLevel);
}
}
// finally, add this ingredient to the entry
newEntry.addIngredient(newIngredient);
}
// Now modify the enchantment level of products, if necessary
for (final MultiSellIngredient ing : templateEntry.getProducts())
{
// load the ingredient from the template
final MultiSellIngredient newIngredient = L2Multisell.getInstance().new MultiSellIngredient(ing);
if (maintainEnchantment)
{
// if it is an armor/weapon, modify the enchantment level appropriately
// (note, if maintain enchantment is "false" this modification will result to a +0)
final L2Item tempItem = ItemTable.getInstance().createDummyItem(ing.getItemId()).getItem();
if ((tempItem instanceof L2Armor) || (tempItem instanceof L2Weapon))
{
newIngredient.setEnchantmentLevel(enchantLevel);
}
}
newEntry.addProduct(newIngredient);
}
return newEntry;
}
public void createMultiSell(int listId, L2PcInstance player, boolean inventoryOnly, L2NpcInstance merchant)
{
final MultiSellListContainer list = generateMultiSell(listId, inventoryOnly, player, merchant);
MultiSellListContainer temp = new MultiSellListContainer();
int page = 1;
temp.setListId(list.getListId());
for (final MultiSellEntry e : list.getEntries())
{
if (temp.getEntries().size() == 40)
{
player.sendPacket(new MultiSellList(temp, page, 0));
page++;
temp = new MultiSellListContainer();
temp.setListId(list.getListId());
}
temp.addEntry(e);
}
player.sendPacket(new MultiSellList(temp, page, 1));
}
}

View File

@@ -0,0 +1,151 @@
/*
* 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.model;
import com.l2jmobius.gameserver.templates.StatsSet;
/**
* @author Rayan RPG
* @since 927
*/
public class L2NpcWalkerNode
{
private int _routeId;
private int _npcId;
private String _movePoint;
private String _chatText;
private int _moveX;
private int _moveY;
private int _moveZ;
private int _delay;
private boolean _running;
/**
* Constructor of L2NpcWalker.<BR>
* <BR>
*/
public L2NpcWalkerNode()
{
}
/**
* Constructor of L2NpcWalker.<BR>
* <BR>
* @param set The StatsSet object to transfert data to the method
*/
public L2NpcWalkerNode(StatsSet set)
{
_npcId = set.getInteger("npc_id");
_movePoint = set.getString("move_point");
_chatText = set.getString("chatText");
_moveX = set.getInteger("move_x");
_moveX = set.getInteger("move_y");
_moveX = set.getInteger("move_z");
_delay = set.getInteger("delay");
}
public void setRunning(boolean val)
{
_running = val;
}
public void setRouteId(int id)
{
_routeId = id;
}
public void setNpcId(int id)
{
_npcId = id;
}
public void setMovePoint(String val)
{
_movePoint = val;
}
public void setChatText(String val)
{
_chatText = val;
}
public void setMoveX(int val)
{
_moveX = val;
}
public void setMoveY(int val)
{
_moveY = val;
}
public void setMoveZ(int val)
{
_moveZ = val;
}
public void setDelay(int val)
{
_delay = val;
}
public int getRouteId()
{
return _routeId;
}
public int getNpcId()
{
return _npcId;
}
public String getMovePoint()
{
return _movePoint;
}
public String getChatText()
{
return _chatText;
}
public int getMoveX()
{
return _moveX;
}
public int getMoveY()
{
return _moveY;
}
public int getMoveZ()
{
return _moveZ;
}
public int getDelay()
{
return _delay;
}
public boolean getRunning()
{
return _running;
}
}

View File

@@ -0,0 +1,390 @@
/*
* 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.model;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.idfactory.IdFactory;
import com.l2jmobius.gameserver.instancemanager.ItemsOnGroundManager;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.actor.knownlist.ObjectKnownList;
import com.l2jmobius.gameserver.model.actor.poly.ObjectPoly;
import com.l2jmobius.gameserver.model.actor.position.ObjectPosition;
import com.l2jmobius.gameserver.network.L2GameClient;
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
/**
* Mother class of all objects in the world which ones is it possible to interact (PC, NPC, Item...)<BR>
* <BR>
* L2Object :<BR>
* <BR>
* <li>L2Character</li>
* <li>L2ItemInstance</li>
* <li>L2Potion</li>
*/
public abstract class L2Object
{
// =========================================================
// Data Field
private ObjectKnownList _KnownList;
private String _Name;
private int _ObjectId; // Object identifier
private ObjectPoly _Poly;
private ObjectPosition _Position;
// =========================================================
// Constructor
public L2Object(int objectId)
{
_ObjectId = objectId;
}
// =========================================================
// Event - Public
public void onAction(L2PcInstance player)
{
player.sendPacket(new ActionFailed());
}
public void onActionShift(L2GameClient client)
{
client.getActiveChar().sendPacket(new ActionFailed());
}
public void onForcedAttack(L2PcInstance player)
{
player.sendPacket(new ActionFailed());
}
/**
* Do Nothing.<BR>
* <BR>
* <B><U> Overriden in </U> :</B><BR>
* <BR>
* <li>L2GuardInstance : Set the home location of its L2GuardInstance</li>
* <li>L2Attackable : Reset the Spoiled flag</li><BR>
* <BR>
*/
public void onSpawn()
{
}
// =========================================================
// Position - Should remove to fully move to L2ObjectPosition
public final void setXYZ(int x, int y, int z)
{
getPosition().setXYZ(x, y, z);
}
public final void setXYZInvisible(int x, int y, int z)
{
getPosition().setXYZInvisible(x, y, z);
}
public final int getX()
{
if (Config.ASSERT)
{
assert getPosition().getWorldRegion() != null;
}
return getPosition().getX();
}
public final int getY()
{
if (Config.ASSERT)
{
assert getPosition().getWorldRegion() != null;
}
return getPosition().getY();
}
public final int getZ()
{
if (Config.ASSERT)
{
assert getPosition().getWorldRegion() != null;
}
return getPosition().getZ();
}
// =========================================================
// Method - Public
/**
* Remove a L2Object from the world.<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Remove the L2Object from the world</li><BR>
* <BR>
* <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T REMOVE the object from _allObjects of L2World </B></FONT><BR>
* <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T SEND Server->Client packets to players</B></FONT><BR>
* <BR>
* <B><U> Assert </U> :</B><BR>
* <BR>
* <li>_worldRegion != null <I>(L2Object is visible at the beginning)</I></li><BR>
* <BR>
* <B><U> Example of use </U> :</B><BR>
* <BR>
* <li>Delete NPC/PC or Unsummon</li><BR>
* <BR>
*/
public final void decayMe()
{
if (Config.ASSERT)
{
assert getPosition().getWorldRegion() != null;
}
final L2WorldRegion reg = getPosition().getWorldRegion();
synchronized (this)
{
getPosition().setWorldRegion(null);
}
// this can synchronize on others instances, so it's out of
// synchronized, to avoid deadlocks
// Remove the L2Object from the world
L2World.getInstance().removeVisibleObject(this, reg);
L2World.getInstance().removeObject(this);
if (Config.SAVE_DROPPED_ITEM)
{
ItemsOnGroundManager.getInstance().removeObject(this);
}
}
public void refreshID()
{
L2World.getInstance().removeObject(this);
IdFactory.getInstance().releaseId(getObjectId());
_ObjectId = IdFactory.getInstance().getNextId();
}
/**
* Init the position of a L2Object spawn and add it in the world as a visible object.<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Set the x,y,z position of the L2Object spawn and update its _worldregion</li>
* <li>Add the L2Object spawn in the _allobjects of L2World</li>
* <li>Add the L2Object spawn to _visibleObjects of its L2WorldRegion</li>
* <li>Add the L2Object spawn in the world as a <B>visible</B> object</li><BR>
* <BR>
* <B><U> Assert </U> :</B><BR>
* <BR>
* <li>_worldRegion == null <I>(L2Object is invisible at the beginning)</I></li><BR>
* <BR>
* <B><U> Example of use </U> :</B><BR>
* <BR>
* <li>Create Door</li>
* <li>Spawn : Monster, Minion, CTs, Summon...</li><BR>
*/
public final void spawnMe()
{
if (Config.ASSERT)
{
assert (getPosition().getWorldRegion() == null) && (getPosition().getWorldPosition().getX() != 0) && (getPosition().getWorldPosition().getY() != 0) && (getPosition().getWorldPosition().getZ() != 0);
}
synchronized (this)
{
// Set the x,y,z position of the L2Object spawn and update its _worldregion
getPosition().setWorldRegion(L2World.getInstance().getRegion(getPosition().getWorldPosition()));
// Add the L2Object spawn in the _allobjects of L2World
L2World.getInstance().storeObject(this);
// Add the L2Object spawn to _visibleObjects and if necessary to _allplayers of its L2WorldRegion
getPosition().getWorldRegion().addVisibleObject(this);
}
// this can synchronize on others instances, so it's out of
// synchronized, to avoid deadlocks
// Add the L2Object spawn in the world as a visible object
L2World.getInstance().addVisibleObject(this, getPosition().getWorldRegion(), null);
onSpawn();
}
public final void spawnMe(int x, int y, int z)
{
if (Config.ASSERT)
{
assert getPosition().getWorldRegion() == null;
}
synchronized (this)
{
// Set the x,y,z position of the L2Object spawn and update its _worldregion
if (x > L2World.MAP_MAX_X)
{
x = L2World.MAP_MAX_X - 5000;
}
if (x < L2World.MAP_MIN_X)
{
x = L2World.MAP_MIN_X + 5000;
}
if (y > L2World.MAP_MAX_Y)
{
y = L2World.MAP_MAX_Y - 5000;
}
if (y < L2World.MAP_MIN_Y)
{
y = L2World.MAP_MIN_Y + 5000;
}
getPosition().setWorldPosition(x, y, z);
getPosition().setWorldRegion(L2World.getInstance().getRegion(getPosition().getWorldPosition()));
}
// Add the L2Object spawn in the _allobjects of L2World
L2World.getInstance().storeObject(this);
// Add the L2Object spawn to _visibleObjects and if necessary to _allplayers of its L2WorldRegion
getPosition().getWorldRegion().addVisibleObject(this);
// this can synchronize on others instances, so it's out of
// synchronized, to avoid deadlocks
// Add the L2Object spawn in the world as a visible object
L2World.getInstance().addVisibleObject(this, getPosition().getWorldRegion(), null);
onSpawn();
}
public void toggleVisible()
{
if (isVisible())
{
decayMe();
}
else
{
spawnMe();
}
}
// =========================================================
// Method - Private
// =========================================================
// Property - Public
public boolean isAttackable()
{
return false;
}
public abstract boolean isAutoAttackable(L2Character attacker);
public boolean isMarker()
{
return false;
}
/**
* Return the visibility state of the L2Object. <BR>
* <BR>
* <B><U> Concept</U> :</B><BR>
* <BR>
* A L2Object is visible if <B>_worldregion</B>!=null <BR>
* <BR>
* @return
*/
public final boolean isVisible()
{
return getPosition().getWorldRegion() != null;
}
public final void setIsVisible(boolean value)
{
if (!value && (getWorldRegion() != null))
{
getWorldRegion().removeVisibleObject(this);
getPosition().setWorldRegion(null);
}
}
public ObjectKnownList getKnownList()
{
if (_KnownList == null)
{
_KnownList = new ObjectKnownList(this);
}
return _KnownList;
}
public final void setKnownList(ObjectKnownList value)
{
_KnownList = value;
}
public final String getName()
{
return _Name;
}
public void setName(String value)
{
_Name = value;
}
public final int getObjectId()
{
return _ObjectId;
}
public final ObjectPoly getPoly()
{
if (_Poly == null)
{
_Poly = new ObjectPoly(this);
}
return _Poly;
}
public final ObjectPosition getPosition()
{
if (_Position == null)
{
_Position = new ObjectPosition(this);
}
return _Position;
}
/**
* returns reference to region this object is in
* @return
*/
public L2WorldRegion getWorldRegion()
{
return getPosition().getWorldRegion();
}
public L2PcInstance getActingPlayer()
{
return null;
}
@Override
public String toString()
{
return "" + getObjectId();
}
}

View File

@@ -0,0 +1,870 @@
/*
* 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.model;
import java.util.List;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.SevenSignsFestival;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2PlayableInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2SummonInstance;
import com.l2jmobius.gameserver.model.entity.DimensionalRift;
import com.l2jmobius.gameserver.network.serverpackets.ExCloseMPCC;
import com.l2jmobius.gameserver.network.serverpackets.ExManagePartyRoomMember;
import com.l2jmobius.gameserver.network.serverpackets.ExOpenMPCC;
import com.l2jmobius.gameserver.network.serverpackets.L2GameServerPacket;
import com.l2jmobius.gameserver.network.serverpackets.PartyMatchDetail;
import com.l2jmobius.gameserver.network.serverpackets.PartyMemberPosition;
import com.l2jmobius.gameserver.network.serverpackets.PartySmallWindowAdd;
import com.l2jmobius.gameserver.network.serverpackets.PartySmallWindowAll;
import com.l2jmobius.gameserver.network.serverpackets.PartySmallWindowDelete;
import com.l2jmobius.gameserver.network.serverpackets.PartySmallWindowDeleteAll;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.skills.Stats;
import com.l2jmobius.gameserver.util.Util;
import com.l2jmobius.util.Rnd;
import javolution.util.FastList;
/**
* This class ...
* @author nuocnam
* @version $Revision: 1.6.2.2.2.6 $ $Date: 2005/04/11 19:12:16 $
*/
public class L2Party
{
static double[] _bonusExpSp =
{
1,
1.30,
1.39,
1.50,
1.54,
1.58,
1.63,
1.67,
1.71
};
// private static Logger _log = Logger.getLogger(L2Party.class.getName());
private List<L2PcInstance> _members = null;
private int _partyLvl = 0;
private int _itemDistribution = 0;
private int _itemLastLoot = 0;
private L2CommandChannel _commandChannel = null;
private DimensionalRift _rift;
public static final int ITEM_LOOTER = 0;
public static final int ITEM_RANDOM = 1;
public static final int ITEM_RANDOM_SPOIL = 2;
public static final int ITEM_ORDER = 3;
public static final int ITEM_ORDER_SPOIL = 4;
/**
* constructor ensures party has always one member - leader
* @param leader
*/
public L2Party(L2PcInstance leader)
{
_itemDistribution = leader.getLootInvitation();
getPartyMembers().add(leader);
_partyLvl = leader.getLevel();
}
/**
* returns number of party members
* @return
*/
public int getMemberCount()
{
return getPartyMembers().size();
}
/**
* returns all party members
* @return
*/
public List<L2PcInstance> getPartyMembers()
{
if (_members == null)
{
_members = new FastList<>();
}
return _members;
}
/**
* get random member from party
* @param ItemId
* @param target
* @return
*/
private L2PcInstance getCheckedRandomMember(int ItemId, L2Character target)
{
final List<L2PcInstance> availableMembers = new FastList<>();
for (final L2PcInstance member : getPartyMembers())
{
if (member.getInventory().validateCapacityByItemId(ItemId) && Util.checkIfInRange(Config.ALT_PARTY_RANGE2, target, member, true))
{
availableMembers.add(member);
}
}
if (availableMembers.size() > 0)
{
return availableMembers.get(Rnd.get(availableMembers.size()));
}
return null;
}
/**
* get next item looter
* @param ItemId
* @param target
* @return
*/
private L2PcInstance getCheckedNextLooter(int ItemId, L2Character target)
{
for (int i = 0; i < getMemberCount(); i++)
{
_itemLastLoot++;
if (_itemLastLoot >= getMemberCount())
{
_itemLastLoot = 0;
}
L2PcInstance member;
try
{
member = getPartyMembers().get(_itemLastLoot);
if (member.getInventory().validateCapacityByItemId(ItemId) && Util.checkIfInRange(Config.ALT_PARTY_RANGE2, target, member, true))
{
return member;
}
}
catch (final Exception e)
{
// continue, take another member if this just logged off
}
}
return null;
}
/**
* get next item looter
* @param player
* @param ItemId
* @param spoil
* @param target
* @return
*/
private L2PcInstance getActualLooter(L2PcInstance player, int ItemId, boolean spoil, L2Character target)
{
L2PcInstance looter = player;
switch (_itemDistribution)
{
case ITEM_RANDOM:
if (!spoil)
{
looter = getCheckedRandomMember(ItemId, target);
}
break;
case ITEM_RANDOM_SPOIL:
looter = getCheckedRandomMember(ItemId, target);
break;
case ITEM_ORDER:
if (!spoil)
{
looter = getCheckedNextLooter(ItemId, target);
}
break;
case ITEM_ORDER_SPOIL:
looter = getCheckedNextLooter(ItemId, target);
break;
}
if (looter == null)
{
looter = player;
}
return looter;
}
/**
* true if player is party leader
* @param player
* @return
*/
public boolean isLeader(L2PcInstance player)
{
return (getPartyMembers().get(0).equals(player));
}
/**
* Returns the Object ID for the party leader to be used as a unique identifier of this party
* @return int
*/
public int getPartyLeaderOID()
{
return getPartyMembers().get(0).getObjectId();
}
/**
* Broadcasts packet to every party member
* @param msg
*/
public void broadcastToPartyMembers(L2GameServerPacket msg)
{
for (final L2PcInstance member : getPartyMembers())
{
member.sendPacket(msg);
}
}
/**
* Send a Server->Client packet to all other L2PcInstance of the Party.<BR>
* <BR>
* @param player
* @param msg
*/
public void broadcastToPartyMembers(L2PcInstance player, L2GameServerPacket msg)
{
for (final L2PcInstance member : getPartyMembers())
{
if ((member != null) && !member.equals(player))
{
member.sendPacket(msg);
}
}
}
public void broadcastToPartyMembersNewLeader()
{
for (final L2PcInstance member : getPartyMembers())
{
if (member != null)
{
member.sendPacket(new PartySmallWindowDeleteAll());
final PartySmallWindowAll window = new PartySmallWindowAll(_itemDistribution);
window.setPartyList(getPartyMembers());
member.sendPacket(window);
member.updateEffectIcons(true);
}
}
}
/**
* adds new member to party
* @param player
*/
public void addPartyMember(L2PcInstance player)
{
// sends new member party window for all members
// we do all actions before adding member to a list, this speeds things up a little
final PartySmallWindowAll window = new PartySmallWindowAll(_itemDistribution);
window.setPartyList(getPartyMembers());
player.sendPacket(window);
SystemMessage msg = new SystemMessage(SystemMessage.YOU_JOINED_S1_PARTY);
msg.addString(getPartyMembers().get(0).getName());
player.sendPacket(msg);
msg = new SystemMessage(SystemMessage.S1_JOINED_PARTY);
msg.addString(player.getName());
broadcastToPartyMembers(msg);
broadcastToPartyMembers(new PartySmallWindowAdd(player));
if (!player.isInBoat())
{
player.sendPacket(new PartyMemberPosition(player));
broadcastToPartyMembers(player, new PartyMemberPosition(player));
}
// add player to party, adjust party level
if (!getPartyMembers().contains(player))
{
getPartyMembers().add(player);
}
if (player.getLevel() > _partyLvl)
{
_partyLvl = player.getLevel();
}
// update partySpelled
for (final L2PcInstance member : getPartyMembers())
{
member.updateEffectIcons(true); // update party icons only
member.broadcastUserInfo();
}
if (isInCommandChannel())
{
player.sendPacket(new ExOpenMPCC());
}
}
/**
* Remove player from party Overloaded method that takes player's name as parameter
* @param name
* @param hasLeft
*/
public void removePartyMember(String name, boolean hasLeft)
{
final L2PcInstance player = getPlayerByName(name);
if (player != null)
{
removePartyMember(player, hasLeft);
}
}
/**
* Remove player from party
* @param player
* @param hasLeft
*/
public void removePartyMember(L2PcInstance player, boolean hasLeft)
{
if (getPartyMembers().contains(player))
{
if (isInDimensionalRift())
{
_rift.partyMemberExited(player, hasLeft);
}
final boolean isLeader = isLeader(player);
getPartyMembers().remove(player);
recalculatePartyLevel();
if (player.isFestivalParticipant())
{
SevenSignsFestival.getInstance().updateParticipants(player, this);
}
SystemMessage msg = new SystemMessage(SystemMessage.YOU_HAVE_BEEN_EXPELLED_FROM_PARTY);
if (hasLeft)
{
msg = new SystemMessage(SystemMessage.YOU_LEFT_PARTY);
}
player.sendPacket(msg);
player.sendPacket(new PartySmallWindowDeleteAll());
player.setParty(null);
if (hasLeft)
{
msg = new SystemMessage(SystemMessage.S1_LEFT_PARTY);
}
else
{
msg = new SystemMessage(SystemMessage.S1_WAS_EXPELLED_FROM_PARTY);
}
msg.addString(player.getName());
broadcastToPartyMembers(msg);
broadcastToPartyMembers(new PartySmallWindowDelete(player));
if (isLeader && (getPartyMembers().size() > 1))
{
msg = new SystemMessage(SystemMessage.S1_HAS_BECOME_A_PARTY_LEADER);
msg.addString(getPartyMembers().get(0).getName());
broadcastToPartyMembers(msg);
broadcastToPartyMembersNewLeader();
}
if (isInCommandChannel())
{
player.sendPacket(new ExCloseMPCC());
}
if (getPartyMembers().size() == 1)
{
if (isInCommandChannel())
{
if (getCommandChannel().getChannelLeader().equals(getPartyMembers().get(0)))
{
getCommandChannel().disbandChannel();
}
else
{
getCommandChannel().removeParty(this);
}
}
if (getPartyMembers().get(0) != null)
{
getPartyMembers().get(0).setParty(null);
}
_members = null;
}
}
if (player.isInPartyMatchRoom())
{
final PartyMatchRoom _room = PartyMatchRoomList.getInstance().getPlayerRoom(player);
if (_room != null)
{
player.sendPacket(new PartyMatchDetail(_room));
for (final L2PcInstance _member : _room.getPartyMembers())
{
if (_member == null)
{
continue;
}
_member.sendPacket(new ExManagePartyRoomMember(player, _room, 1));
}
}
player.broadcastUserInfo();
}
}
/**
* Change party leader (used for string arguments)
* @param name
*/
public void changePartyLeader(String name)
{
final L2PcInstance player = getPlayerByName(name);
if (player != null)
{
if (getPartyMembers().contains(player))
{
if (isLeader(player))
{
player.sendPacket(new SystemMessage(SystemMessage.YOU_CANNOT_TRANSFER_RIGHTS_TO_YOURSELF));
}
else
{
// Swap party members
L2PcInstance temp;
final int p1 = getPartyMembers().indexOf(player);
temp = getPartyMembers().get(0);
getPartyMembers().set(0, getPartyMembers().get(p1));
getPartyMembers().set(p1, temp);
SystemMessage msg = new SystemMessage(SystemMessage.S1_HAS_BECOME_A_PARTY_LEADER);
msg.addString(getPartyMembers().get(0).getName());
broadcastToPartyMembers(msg);
broadcastToPartyMembersNewLeader();
player.updateEffectIcons(true);
if (isInCommandChannel() && temp.equals(_commandChannel.getChannelLeader()))
{
_commandChannel.setChannelLeader(getPartyMembers().get(0));
msg = new SystemMessage(SystemMessage.COMMAND_CHANNEL_LEADER_NOW_S1);
msg.addString(_commandChannel.getChannelLeader().getName());
_commandChannel.broadcastToChannelMembers(msg);
}
if (player.isInPartyMatchRoom())
{
final PartyMatchRoom room = PartyMatchRoomList.getInstance().getPlayerRoom(player);
room.changeLeader(player);
}
}
}
else
{
player.sendPacket(new SystemMessage(SystemMessage.YOU_CAN_TRANSFER_RIGHTS_ONLY_TO_ANOTHER_PARTY_MEMBER));
}
}
}
/**
* finds a player in the party by name
* @param name
* @return
*/
private L2PcInstance getPlayerByName(String name)
{
for (final L2PcInstance member : getPartyMembers())
{
if (member.getName().equals(name))
{
return member;
}
}
return null;
}
/**
* distribute item(s) to party members
* @param player
* @param item
*/
public void distributeItem(L2PcInstance player, L2ItemInstance item)
{
if (item.getItemId() == 57)
{
distributeAdena(player, item.getCount(), player);
ItemTable.getInstance().destroyItem("Party", item, player, null);
return;
}
final L2PcInstance target = getActualLooter(player, item.getItemId(), false, player);
target.addItem("Party", item, player, true);
// Send messages to other party members about reward
if (item.getCount() > 1)
{
final SystemMessage msg = new SystemMessage(SystemMessage.S1_PICKED_UP_S2_S3);
msg.addString(target.getName());
msg.addItemName(item.getItemId());
msg.addNumber(item.getCount());
broadcastToPartyMembers(target, msg);
}
else
{
final SystemMessage msg = new SystemMessage(SystemMessage.S1_PICKED_UP_S2);
msg.addString(target.getName());
msg.addItemName(item.getItemId());
broadcastToPartyMembers(target, msg);
}
}
/**
* distribute item(s) to party members
* @param player
* @param item
* @param spoil
* @param target
*/
public void distributeItem(L2PcInstance player, L2Attackable.RewardItem item, boolean spoil, L2Attackable target)
{
if (item == null)
{
return;
}
if (item.getItemId() == 57)
{
distributeAdena(player, item.getCount(), target);
return;
}
final L2PcInstance looter = getActualLooter(player, item.getItemId(), spoil, target);
looter.addItem(spoil ? "Sweep" : "Party", item.getItemId(), item.getCount(), player, true);
// Send messages to other aprty members about reward
if (item.getCount() > 1)
{
final SystemMessage msg = spoil ? new SystemMessage(SystemMessage.S1_SWEEPED_UP_S2_S3) : new SystemMessage(SystemMessage.S1_PICKED_UP_S2_S3);
msg.addString(looter.getName());
msg.addItemName(item.getItemId());
msg.addNumber(item.getCount());
broadcastToPartyMembers(looter, msg);
}
else
{
final SystemMessage msg = spoil ? new SystemMessage(SystemMessage.S1_SWEEPED_UP_S2) : new SystemMessage(SystemMessage.S1_PICKED_UP_S2);
msg.addString(looter.getName());
msg.addItemName(item.getItemId());
broadcastToPartyMembers(looter, msg);
}
}
/**
* distribute adena to party members
* @param player
* @param adena
* @param target
*/
public void distributeAdena(L2PcInstance player, int adena, L2Character target)
{
// Get all the party members
final List<L2PcInstance> membersList = getPartyMembers();
// Check the number of party members that must be rewarded
// (The party member must be in range to receive its reward)
final List<L2PcInstance> ToReward = new FastList<>();
for (final L2PcInstance member : membersList)
{
if (!Util.checkIfInRange(Config.ALT_PARTY_RANGE2, target, member, true))
{
continue;
}
ToReward.add(member);
}
// Avoid null exceptions, if any
if (ToReward.isEmpty())
{
return;
}
// Now we can actually distribute the adena reward
// (Total adena splitted by the number of party members that are in range and must be rewarded)
final int count = adena / ToReward.size();
for (final L2PcInstance member : ToReward)
{
member.addAdena("Party", count, player, true);
}
}
/**
* Distribute Experience and SP rewards to L2PcInstance Party members in the known area of the last attacker.<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Get the L2PcInstance owner of the L2SummonInstance (if necessary)</li>
* <li>Calculate the Experience and SP reward distribution rate</li>
* <li>Add Experience and SP to the L2PcInstance</li><BR>
* <BR>
* <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T GIVE rewards to L2PetInstance</B></FONT><BR>
* <BR>
* @param xpReward The Experience reward to distribute
* @param spReward The SP reward to distribute
* @param rewardedMembers The list of L2PcInstance to reward
* @param topLvl
*/
public void distributeXpAndSp(long xpReward, int spReward, List<L2PlayableInstance> rewardedMembers, int topLvl)
{
L2SummonInstance summon = null;
final List<L2PlayableInstance> validMembers = getValidMembers(rewardedMembers, topLvl);
float penalty;
double sqLevel;
double preCalculation;
xpReward *= getExpBonus(validMembers.size());
spReward *= getSpBonus(validMembers.size());
double sqLevelSum = 0;
for (final L2PlayableInstance character : validMembers)
{
sqLevelSum += (character.getLevel() * character.getLevel());
}
// Go through the L2PcInstances and L2PetInstances (not L2SummonInstances) that must be rewarded
synchronized (rewardedMembers)
{
for (final L2Character member : rewardedMembers)
{
if (member.isDead())
{
continue;
}
penalty = 0;
// The L2SummonInstance penalty
if ((member.getPet() != null) && (member.getPet() instanceof L2SummonInstance))
{
summon = (L2SummonInstance) member.getPet();
penalty = summon.getExpPenalty();
}
// Pets that leech xp from the owner (like babypets) do not get rewarded directly
if (member instanceof L2PetInstance)
{
if (((L2PetInstance) member).getPetData().getOwnerExpTaken() > 0)
{
continue;
}
penalty = (float) 0.85;
}
// Calculate and add the EXP and SP reward to the member
if (validMembers.contains(member))
{
sqLevel = member.getLevel() * member.getLevel();
preCalculation = (sqLevel / sqLevelSum) * (1 - penalty);
// Add the XP/SP points to the requested party member
if (!member.isDead())
{
member.addExpAndSp(Math.round(member.calcStat(Stats.EXPSP_RATE, xpReward * preCalculation, null, null)), (int) member.calcStat(Stats.EXPSP_RATE, spReward * preCalculation, null, null));
}
}
else
{
member.addExpAndSp(0, 0);
}
}
}
}
/**
* refresh party level
*/
public void recalculatePartyLevel()
{
int newLevel = 0;
for (final L2PcInstance member : getPartyMembers())
{
if (member == null)
{
getPartyMembers().remove(member);
continue;
}
if (member.getLevel() > newLevel)
{
newLevel = member.getLevel();
}
}
_partyLvl = newLevel;
}
private List<L2PlayableInstance> getValidMembers(List<L2PlayableInstance> members, int topLvl)
{
final List<L2PlayableInstance> validMembers = new FastList<>();
// Fixed LevelDiff cutoff point
if (Config.PARTY_XP_CUTOFF_METHOD.equalsIgnoreCase("level"))
{
for (final L2PlayableInstance member : members)
{
if ((topLvl - member.getLevel()) <= Config.PARTY_XP_CUTOFF_LEVEL)
{
validMembers.add(member);
}
}
}
// Fixed MinPercentage cutoff point
else if (Config.PARTY_XP_CUTOFF_METHOD.equalsIgnoreCase("percentage"))
{
int sqLevelSum = 0;
for (final L2PlayableInstance member : members)
{
sqLevelSum += (member.getLevel() * member.getLevel());
}
for (final L2PlayableInstance member : members)
{
final int sqLevel = member.getLevel() * member.getLevel();
if ((sqLevel * 100) >= (sqLevelSum * Config.PARTY_XP_CUTOFF_PERCENT))
{
validMembers.add(member);
}
}
}
// Automatic cutoff method
else if (Config.PARTY_XP_CUTOFF_METHOD.equalsIgnoreCase("auto"))
{
int sqLevelSum = 0;
for (final L2PlayableInstance member : members)
{
sqLevelSum += (member.getLevel() * member.getLevel());
}
int i = members.size() - 1;
if (i < 1)
{
return members;
}
if (i >= _bonusExpSp.length)
{
i = _bonusExpSp.length - 1;
}
for (final L2PlayableInstance member : members)
{
final int sqLevel = member.getLevel() * member.getLevel();
if (sqLevel >= (sqLevelSum * (1 - (1 / ((1 + _bonusExpSp[i]) - _bonusExpSp[i - 1])))))
{
validMembers.add(member);
}
}
}
return validMembers;
}
private double getBaseExpSpBonus(int membersCount)
{
int i = membersCount - 1;
if (i < 1)
{
return 1;
}
if (i >= _bonusExpSp.length)
{
i = _bonusExpSp.length - 1;
}
return _bonusExpSp[i];
}
private double getExpBonus(int membersCount)
{
if (membersCount < 2)
{
// not is a valid party
return getBaseExpSpBonus(membersCount);
}
return getBaseExpSpBonus(membersCount) * Config.RATE_PARTY_XP;
}
private double getSpBonus(int membersCount)
{
if (membersCount < 2)
{
// not is a valid party
return getBaseExpSpBonus(membersCount);
}
return getBaseExpSpBonus(membersCount) * Config.RATE_PARTY_SP;
}
public int getLevel()
{
return _partyLvl;
}
public int getLootDistribution()
{
return _itemDistribution;
}
public boolean isInCommandChannel()
{
return _commandChannel != null;
}
public L2CommandChannel getCommandChannel()
{
return _commandChannel;
}
public void setCommandChannel(L2CommandChannel channel)
{
_commandChannel = channel;
}
public boolean isInDimensionalRift()
{
return _rift != null;
}
public void setDimensionalRift(DimensionalRift dr)
{
_rift = dr;
}
public DimensionalRift getDimensionalRift()
{
return _rift;
}
}

View File

@@ -0,0 +1,420 @@
/*
* 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.model;
public class L2PetData
{
public static final String PET_TYPE = "typeID";
public static final String PET_LEVEL = "level";
// public static final String PET_EXP = "exp";
public static final String PET_MAX_EXP = "expMax";
// public static final String PET_HP = "hp";
public static final String PET_MAX_HP = "hpMax";
// public static final String PET_MP = "mp";
public static final String PET_MAX_MP = "mpMax";
public static final String PET_PATK = "patk";
public static final String PET_PDEF = "pdef";
public static final String PET_MATK = "matk";
public static final String PET_MDEF = "mdef";
public static final String PET_ACCURACY = "acc";
public static final String PET_EVASION = "evasion";
public static final String PET_CRITICAL = "crit";
public static final String PET_SPEED = "speed";
public static final String PET_ATK_SPEED = "atk_speed";
public static final String PET_CAST_SPEED = "cast_speed";
// public static final String PET_FEED = "feed";
public static final String PET_MAX_FEED = "feedMax";
public static final String PET_FEED_BATTLE = "feedbattle";
public static final String PET_FEED_NORMAL = "feednormal";
// public static final String PET_LOAD = "load";
public static final String PET_MAX_LOAD = "loadMax";
public static final String PET_REGEN_HP = "hpregen";
public static final String PET_REGEN_MP = "mpregen";
public static final String OWNER_EXP_TAKEN = "owner_exp_taken";
private int petID;
private int petLevel;
private float owner_exp_taken;
private long petMaxExp;
private int petMaxHP;
private int petMaxMP;
private int petPAtk;
private int petPDef;
private int petMAtk;
private int petMDef;
private int petAccuracy;
private int petEvasion;
private int petCritical;
private int petSpeed;
private int petAtkSpeed;
private int petCastSpeed;
private int petMaxFeed;
private int petFeedBattle;
private int petFeedNormal;
private int petMaxLoad;
private int petRegenHP;
private int petRegenMP;
public void setStat(String stat, int value)
{
if (stat.equalsIgnoreCase(PET_MAX_HP))
{
setPetMaxHP(value);
}
else if (stat.equalsIgnoreCase(PET_MAX_MP))
{
setPetMaxMP(value);
}
else if (stat.equalsIgnoreCase(PET_PATK))
{
setPetPAtk(value);
}
else if (stat.equalsIgnoreCase(PET_PDEF))
{
setPetPDef(value);
}
else if (stat.equalsIgnoreCase(PET_MATK))
{
setPetMAtk(value);
}
else if (stat.equalsIgnoreCase(PET_MDEF))
{
setPetMDef(value);
}
else if (stat.equalsIgnoreCase(PET_ACCURACY))
{
setPetAccuracy(value);
}
else if (stat.equalsIgnoreCase(PET_EVASION))
{
setPetEvasion(value);
}
else if (stat.equalsIgnoreCase(PET_CRITICAL))
{
setPetCritical(value);
}
else if (stat.equalsIgnoreCase(PET_SPEED))
{
setPetSpeed(value);
}
else if (stat.equalsIgnoreCase(PET_ATK_SPEED))
{
setPetAtkSpeed(value);
}
else if (stat.equalsIgnoreCase(PET_CAST_SPEED))
{
setPetCastSpeed(value);
}
else if (stat.equalsIgnoreCase(PET_MAX_FEED))
{
setPetMaxFeed(value);
}
else if (stat.equalsIgnoreCase(PET_FEED_NORMAL))
{
setPetFeedNormal(value);
}
else if (stat.equalsIgnoreCase(PET_FEED_BATTLE))
{
setPetFeedBattle(value);
}
else if (stat.equalsIgnoreCase(PET_MAX_LOAD))
{
setPetMaxLoad(value);
}
else if (stat.equalsIgnoreCase(PET_REGEN_HP))
{
setPetRegenHP(value);
}
else if (stat.equalsIgnoreCase(PET_REGEN_MP))
{
setPetRegenMP(value);
}
}
public void setStat(String stat, long value)
{
if (stat.equalsIgnoreCase(PET_MAX_EXP))
{
setPetMaxExp(value);
}
}
public void setStat(String stat, float value)
{
if (stat.equalsIgnoreCase(OWNER_EXP_TAKEN))
{
setOwnerExpTaken(value);
}
}
// ID
public int getPetID()
{
return petID;
}
public void setPetID(int pPetID)
{
petID = pPetID;
}
// Level
public int getPetLevel()
{
return petLevel;
}
public void setPetLevel(int pPetLevel)
{
petLevel = pPetLevel;
}
// Max Exp
public long getPetMaxExp()
{
return petMaxExp;
}
public void setPetMaxExp(long pPetMaxExp)
{
petMaxExp = pPetMaxExp;
}
public float getOwnerExpTaken()
{
return owner_exp_taken;
}
public void setOwnerExpTaken(float pOwnerExpTaken)
{
owner_exp_taken = pOwnerExpTaken;
}
// Max HP
public int getPetMaxHP()
{
return petMaxHP;
}
public void setPetMaxHP(int pPetMaxHP)
{
petMaxHP = pPetMaxHP;
}
// Max Mp
public int getPetMaxMP()
{
return petMaxMP;
}
public void setPetMaxMP(int pPetMaxMP)
{
petMaxMP = pPetMaxMP;
}
// PAtk
public int getPetPAtk()
{
return petPAtk;
}
public void setPetPAtk(int pPetPAtk)
{
petPAtk = pPetPAtk;
}
// PDef
public int getPetPDef()
{
return petPDef;
}
public void setPetPDef(int pPetPDef)
{
petPDef = pPetPDef;
}
// MAtk
public int getPetMAtk()
{
return petMAtk;
}
public void setPetMAtk(int pPetMAtk)
{
petMAtk = pPetMAtk;
}
// MDef
public int getPetMDef()
{
return petMDef;
}
public void setPetMDef(int pPetMDef)
{
petMDef = pPetMDef;
}
// Accuracy
public int getPetAccuracy()
{
return petAccuracy;
}
public void setPetAccuracy(int pPetAccuracy)
{
petAccuracy = pPetAccuracy;
}
// Evasion
public int getPetEvasion()
{
return petEvasion;
}
public void setPetEvasion(int pPetEvasion)
{
petEvasion = pPetEvasion;
}
// Critical
public int getPetCritical()
{
return petCritical;
}
public void setPetCritical(int pPetCritical)
{
petCritical = pPetCritical;
}
// Speed
public int getPetSpeed()
{
return petSpeed;
}
public void setPetSpeed(int pPetSpeed)
{
petSpeed = pPetSpeed;
}
// Atk Speed
public int getPetAtkSpeed()
{
return petAtkSpeed;
}
public void setPetAtkSpeed(int pPetAtkSpeed)
{
petAtkSpeed = pPetAtkSpeed;
}
// Cast Speed
public int getPetCastSpeed()
{
return petCastSpeed;
}
public void setPetCastSpeed(int pPetCastSpeed)
{
petCastSpeed = pPetCastSpeed;
}
// MaxFeed
public int getPetMaxFeed()
{
return petMaxFeed;
}
public void setPetMaxFeed(int pPetMaxFeed)
{
petMaxFeed = pPetMaxFeed;
}
// Normal Feed
public int getPetFeedNormal()
{
return petFeedNormal;
}
public void setPetFeedNormal(int pPetFeedNormal)
{
petFeedNormal = pPetFeedNormal;
}
// Battle Feed
public int getPetFeedBattle()
{
return petFeedBattle;
}
public void setPetFeedBattle(int pPetFeedBattle)
{
petFeedBattle = pPetFeedBattle;
}
// Max Load
public int getPetMaxLoad()
{
return petMaxLoad;
}
public void setPetMaxLoad(int pPetMaxLoad)
{
petMaxLoad = pPetMaxLoad;
}
// Regen HP
public int getPetRegenHP()
{
return petRegenHP;
}
public void setPetRegenHP(int pPetRegenHP)
{
petRegenHP = pPetRegenHP;
}
// Regen MP
public int getPetRegenMP()
{
return petRegenMP;
}
public void setPetRegenMP(int pPetRegenMP)
{
petRegenMP = pPetRegenMP;
}
@Override
public String toString()
{
return "PetID: " + getPetID() + " \t" + "PetLevel: " + getPetLevel() + " \t" +
// PET_EXP + ": " + getPetExp() + " \t" +
PET_MAX_EXP + ": " + getPetMaxExp() + " \t" +
// PET_HP + ": " + getPetHP() + " \t" +
PET_MAX_HP + ": " + getPetMaxHP() + " \t" +
// PET_MP + ": " + getPetMP() + " \t" +
PET_MAX_MP + ": " + getPetMaxMP() + " \t" + PET_PATK + ": " + getPetPAtk() + " \t" + PET_PDEF + ": " + getPetPDef() + " \t" + PET_MATK + ": " + getPetMAtk() + " \t" + PET_MDEF + ": " + getPetMDef() + " \t" + PET_ACCURACY + ": " + getPetAccuracy() + " \t" + PET_EVASION + ": " + getPetEvasion() + " \t" + PET_CRITICAL + ": " + getPetCritical() + " \t" + PET_SPEED + ": " + getPetSpeed() + " \t" + PET_ATK_SPEED + ": " + getPetAtkSpeed() + " \t" + PET_CAST_SPEED + ": " + getPetCastSpeed() + " \t" +
// PET_FEED + ": " + getPetFeed() + " \t" +
PET_MAX_FEED + ": " + getPetMaxFeed() + " \t" + PET_FEED_BATTLE + ": " + getPetFeedBattle() + " \t" + PET_FEED_NORMAL + ": " + getPetFeedNormal() + " \t" +
// PET_LOAD + ": " + getPetLoad() + " \t" +
PET_MAX_LOAD + ": " + getPetMaxLoad() + " \t" + PET_REGEN_HP + ": " + getPetRegenHP() + " \t" + PET_REGEN_MP + ": " + getPetRegenMP();
}
}

View File

@@ -0,0 +1,402 @@
/*
* 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.model;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Map;
import java.util.logging.Logger;
import com.l2jmobius.L2DatabaseFactory;
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
import javolution.util.FastMap;
public class L2PetDataTable
{
private static Logger _log = Logger.getLogger(L2PetInstance.class.getName());
private static L2PetDataTable _instance;
public static final int[] petList =
{
12077,
12312,
12313,
12311,
12527,
12528,
12526
};
private static Map<Integer, Map<Integer, L2PetData>> petTable;
public static L2PetDataTable getInstance()
{
if (_instance == null)
{
_instance = new L2PetDataTable();
}
return _instance;
}
private L2PetDataTable()
{
petTable = new FastMap<>();
}
public void loadPetsData()
{
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("SELECT typeID, level, expMax, hpMax, mpMax, patk, pdef, matk, mdef, acc, evasion, crit, speed, atk_speed, cast_speed, feedMax, feedbattle, feednormal, loadMax, hpregen, mpregen, owner_exp_taken FROM pets_stats");
ResultSet rset = statement.executeQuery())
{
int petId, petLevel;
while (rset.next())
{
petId = rset.getInt("typeID");
petLevel = rset.getInt("level");
// build the pet data for this level
final L2PetData petData = new L2PetData();
petData.setPetID(petId);
petData.setPetLevel(petLevel);
petData.setPetMaxExp(rset.getLong("expMax"));
petData.setPetMaxHP(rset.getInt("hpMax"));
petData.setPetMaxMP(rset.getInt("mpMax"));
petData.setPetPAtk(rset.getInt("patk"));
petData.setPetPDef(rset.getInt("pdef"));
petData.setPetMAtk(rset.getInt("matk"));
petData.setPetMDef(rset.getInt("mdef"));
petData.setPetAccuracy(rset.getInt("acc"));
petData.setPetEvasion(rset.getInt("evasion"));
petData.setPetCritical(rset.getInt("crit"));
petData.setPetSpeed(rset.getInt("speed"));
petData.setPetAtkSpeed(rset.getInt("atk_speed"));
petData.setPetCastSpeed(rset.getInt("cast_speed"));
petData.setPetMaxFeed(rset.getInt("feedMax"));
petData.setPetFeedNormal(rset.getInt("feednormal"));
petData.setPetFeedBattle(rset.getInt("feedbattle"));
petData.setPetMaxLoad(rset.getInt("loadMax"));
petData.setPetRegenHP(rset.getInt("hpregen"));
petData.setPetRegenMP(rset.getInt("mpregen"));
petData.setOwnerExpTaken(rset.getFloat("owner_exp_taken"));
// if its the first data for this petid, we initialize its level FastMap
if (!petTable.containsKey(petId))
{
petTable.put(petId, new FastMap<Integer, L2PetData>());
}
petTable.get(petId).put(petLevel, petData);
}
}
catch (final Exception e)
{
_log.warning("Could not load pets stats: " + e);
}
}
public void addPetData(L2PetData petData)
{
final Map<Integer, L2PetData> h = petTable.get(petData.getPetID());
if (h == null)
{
final Map<Integer, L2PetData> statTable = new FastMap<>();
statTable.put(petData.getPetLevel(), petData);
petTable.put(petData.getPetID(), statTable);
return;
}
h.put(petData.getPetLevel(), petData);
}
public void addPetData(L2PetData[] petLevelsList)
{
for (final L2PetData element : petLevelsList)
{
addPetData(element);
}
}
public L2PetData getPetData(int petID, int petLevel)
{
// System.out.println("Getting id "+petID+" level "+ petLevel);
return petTable.get(petID).get(petLevel);
}
public static boolean isWolf(int npcId)
{
return npcId == 12077;
}
public static boolean isSinEater(int npcId)
{
return npcId == 12564;
}
public static boolean isHatchling(int npcId)
{
return (npcId > 12310) && (npcId < 12314);
}
public static boolean isStrider(int npcId)
{
return (npcId > 12525) && (npcId < 12529);
}
public static boolean isWyvern(int npcId)
{
return npcId == 12621;
}
public static boolean isBaby(int npcId)
{
return (npcId > 12779) && (npcId < 12783);
}
public static boolean isPetFood(int itemId)
{
return (itemId == 2515) || (itemId == 4038) || (itemId == 5168) || (itemId == 5169) || (itemId == 6316) || (itemId == 7582);
}
public static boolean isWolfFood(int itemId)
{
return itemId == 2515;
}
public static boolean isSinEaterFood(int itemId)
{
return itemId == 2515;
}
public static boolean isHatchlingFood(int itemId)
{
return itemId == 4038;
}
public static boolean isStriderFood(int itemId)
{
return (itemId == 5168) || (itemId == 5169);
}
public static boolean isWyvernFood(int itemId)
{
return itemId == 6316;
}
public static boolean isBabyFood(int itemId)
{
return itemId == 7582;
}
public static int[] getFoodItemId(int npcId)
{
// Wolf and Sin Eater
if ((npcId == 12077) || (npcId == 12564))
{
return new int[]
{
2515
};
}
else if (isHatchling(npcId))
{
return new int[]
{
4038
};
}
else if (isStrider(npcId))
{
return new int[]
{
5168,
5169
};
}
else if (isWyvern(npcId))
{
return new int[]
{
6316
};
}
else if (isBaby(npcId))
{
return new int[]
{
7582
};
}
return new int[]
{
0
};
}
public static int getPetIdByItemId(int itemId)
{
switch (itemId)
{
case 2375: // wolf pet
return 12077;
case 3500: // hatchling of wind
return 12311;
case 3501: // hatchling of star
return 12312;
case 3502: // hatchling of twilight
return 12313;
case 4422: // wind strider
return 12526;
case 4423: // Star strider
return 12527;
case 4424: // Twilight strider
return 12528;
case 4425: // Sin Eater
return 12564;
case 6648: // Baby Buffalo
return 12780;
case 6649: // Baby Cougar
return 12782;
case 6650: // Baby Kookaburra
return 12781;
default: // unknown item id.. should never happen
return 0;
}
}
public static int getHatchlingWindId()
{
return 12311;
}
public static int getHatchlingStarId()
{
return 12312;
}
public static int getHatchlingTwilightId()
{
return 12313;
}
public static int getStriderWindId()
{
return 12526;
}
public static int getStriderStarId()
{
return 12527;
}
public static int getStriderTwilightId()
{
return 12528;
}
public static int getSinEaterItemId()
{
return 4425;
}
public static int getStriderWindItemId()
{
return 4422;
}
public static int getStriderStarItemId()
{
return 4423;
}
public static int getStriderTwilightItemId()
{
return 4424;
}
public static boolean isPetItem(int itemId)
{
return ((itemId == 2375 // wolf
) || (itemId == 3500) || (itemId == 3501) || (itemId == 3502 // hatchlings
) || (itemId == 4422) || (itemId == 4423) || (itemId == 4424 // striders
) || (itemId == 4425 // Sin Eater
) || (itemId == 6648) || (itemId == 6649) || (itemId == 6650)); // Babies
}
public static int[] getPetItemsAsNpc(int npcId)
{
switch (npcId)
{
case 12077: // wolf pet
return new int[]
{
2375
};
case 12311: // hatchling of wind
case 12312: // hatchling of star
case 12313: // hatchling of twilight
return new int[]
{
3500,
3501,
3502
};
case 12526: // wind strider
case 12527: // Star strider
case 12528: // Twilight strider
return new int[]
{
4422,
4423,
4424
};
case 12564: // Sin Eater
return new int[]
{
4425
};
case 12780: // Baby Buffalo
case 12781: // Baby Kookaburra
case 12782: // Baby Cougar
return new int[]
{
6648,
6649,
6650
};
default: // unknown item id.. should never happen
return new int[]
{
0
};
}
}
public static boolean isMountable(int npcId)
{
return (npcId == 12526 // wind strider
) || (npcId == 12527 // star strider
) || (npcId == 12528 // twilight strider
) || (npcId == 12621); // wyvern
}
}

View File

@@ -0,0 +1,230 @@
/*
* 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.model;
import java.util.concurrent.Future;
import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.ThreadPoolManager;
/**
* This class ...
* @version $Revision: 1.2.2.1.2.5 $ $Date: 2005/03/27 15:29:30 $
*/
public class L2Potion extends L2Object
{
protected static final Logger _log = Logger.getLogger(L2Potion.class.getName());
L2Character _target;
private Future<?> _potionhpRegTask;
private Future<?> _potionmpRegTask;
protected int _milliseconds;
protected double _effect;
protected int _duration;
private int _potion;
protected Object _mpLock = new Object();
protected Object _hpLock = new Object();
class PotionHpHealing implements Runnable
{
L2Character _instance;
public PotionHpHealing(L2Character instance)
{
_instance = instance;
}
@Override
public void run()
{
try
{
synchronized (_hpLock)
{
double nowHp = _instance.getCurrentHp();
if (_duration == 0)
{
stopPotionHpRegeneration();
}
if (_duration != 0)
{
nowHp += _effect;
_instance.setCurrentHp(nowHp);
_duration = _duration - (_milliseconds / 1000);
setCurrentHpPotion2();
}
}
}
catch (final Exception e)
{
_log.warning("Error in hp potion task:" + e);
}
}
}
public L2Potion(int objectId)
{
super(objectId);
}
public void stopPotionHpRegeneration()
{
if (_potionhpRegTask != null)
{
_potionhpRegTask.cancel(false);
}
_potionhpRegTask = null;
if (Config.DEBUG)
{
_log.fine("Potion HP regen stop");
}
}
public void setCurrentHpPotion2()
{
if (_duration == 0)
{
stopPotionHpRegeneration();
}
}
public void setCurrentHpPotion1(L2Character activeChar, int item)
{
_potion = item;
_target = activeChar;
switch (_potion)
{
case 1540:
double nowHp = activeChar.getCurrentHp();
nowHp += 435;
if (nowHp >= activeChar.getMaxHp())
{
nowHp = activeChar.getMaxHp();
}
activeChar.setCurrentHp(nowHp);
break;
case 728:
double nowMp = activeChar.getMaxMp();
nowMp += 435;
if (nowMp >= activeChar.getMaxMp())
{
nowMp = activeChar.getMaxMp();
}
activeChar.setCurrentMp(nowMp);
break;
case 726:
_milliseconds = 500;
_duration = 15;
_effect = 1.5;
startPotionMpRegeneration(activeChar);
break;
}
}
class PotionMpHealing implements Runnable
{
L2Character _instance;
public PotionMpHealing(L2Character instance)
{
_instance = instance;
}
@Override
public void run()
{
try
{
synchronized (_mpLock)
{
double nowMp = _instance.getCurrentMp();
if (_duration == 0)
{
stopPotionMpRegeneration();
}
if (_duration != 0)
{
nowMp += _effect;
_instance.setCurrentMp(nowMp);
_duration = (_duration - (_milliseconds / 1000));
setCurrentMpPotion2();
}
}
}
catch (final Exception e)
{
_log.warning("error in mp potion task:" + e);
}
}
}
private void startPotionMpRegeneration(L2Character activeChar)
{
_potionmpRegTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new PotionMpHealing(activeChar), 1000, _milliseconds);
if (Config.DEBUG)
{
_log.fine("Potion MP regen Started");
}
}
public void stopPotionMpRegeneration()
{
if (_potionmpRegTask != null)
{
_potionmpRegTask.cancel(false);
}
_potionmpRegTask = null;
if (Config.DEBUG)
{
_log.fine("Potion MP regen stop");
}
}
public void setCurrentMpPotion2()
{
if (_duration == 0)
{
stopPotionMpRegeneration();
}
}
public void setCurrentMpPotion1(L2Character activeChar, int item)
{
_potion = item;
_target = activeChar;
switch (_potion)
{
}
}
/*
* (non-Javadoc)
* @see com.l2jmobius.gameserver.model.L2Object#isAttackable()
*/
@Override
public boolean isAutoAttackable(L2Character attacker)
{
return false;
}
}

View File

@@ -0,0 +1,117 @@
/*
* 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.model;
import java.util.Vector;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.serverpackets.RadarControl;
/**
* @author dalrond
*/
public final class L2Radar
{
private final L2PcInstance _player;
private final Vector<RadarMarker> _markers;
public L2Radar(L2PcInstance player)
{
_player = player;
_markers = new Vector<>();
}
// Add a marker to player's radar
public void addMarker(int x, int y, int z)
{
final RadarMarker newMarker = new RadarMarker(x, y, z);
_markers.add(newMarker);
_player.sendPacket(new RadarControl(2, 2, x, y, z));
_player.sendPacket(new RadarControl(0, 1, x, y, z));
}
// Remove a marker from player's radar
public void removeMarker(int x, int y, int z)
{
final RadarMarker newMarker = new RadarMarker(x, y, z);
_markers.remove(newMarker);
_player.sendPacket(new RadarControl(1, 1, x, y, z));
}
public void removeAllMarkers()
{
for (final RadarMarker tempMarker : _markers)
{
_player.sendPacket(new RadarControl(2, 2, tempMarker._x, tempMarker._y, tempMarker._z));
}
_markers.removeAllElements();
}
public void loadMarkers()
{
_player.sendPacket(new RadarControl(2, 2, _player.getX(), _player.getY(), _player.getZ()));
for (final RadarMarker tempMarker : _markers)
{
_player.sendPacket(new RadarControl(0, 1, tempMarker._x, tempMarker._y, tempMarker._z));
}
}
public class RadarMarker
{
// Simple class to model radar points.
public int _type, _x, _y, _z;
public RadarMarker(int type, int x, int y, int z)
{
_type = type;
_x = x;
_y = y;
_z = z;
}
public RadarMarker(int x, int y, int z)
{
_type = 1;
_x = x;
_y = y;
_z = z;
}
@Override
public boolean equals(Object obj)
{
try
{
final RadarMarker temp = (RadarMarker) obj;
if ((temp._x == _x) && (temp._y == _y) && (temp._z == _z) && (temp._type == _type))
{
return true;
}
return false;
}
catch (final Exception e)
{
return false;
}
}
}
}

View File

@@ -0,0 +1,62 @@
/*
* 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.model;
/**
* This class describes a RecipeList component (1 line of the recipe : Item-Quantity needed).<BR>
* <BR>
*/
public class L2RecipeInstance
{
/** The Identifier of the item needed in the L2RecipeInstance */
private final int _itemId;
/** The item quantity needed in the L2RecipeInstance */
private final int _quantity;
/**
* Constructor of L2RecipeInstance (create a new line in a RecipeList).<BR>
* <BR>
* @param itemId
* @param quantity
*/
public L2RecipeInstance(int itemId, int quantity)
{
_itemId = itemId;
_quantity = quantity;
}
/**
* Return the Identifier of the L2RecipeInstance Item needed.<BR>
* <BR>
* @return
*/
public int getItemId()
{
return _itemId;
}
/**
* Return the Item quantity needed of the L2RecipeInstance.<BR>
* <BR>
* @return
*/
public int getQuantity()
{
return _quantity;
}
}

View File

@@ -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.model;
/**
* This class describes a Recipe used by Dwarf to craft Item. All L2RecipeList are made of L2RecipeInstance (1 line of the recipe : Item-Quantity needed).<BR>
* <BR>
*/
public class L2RecipeList
{
/** The table containing all L2RecipeInstance (1 line of the recipe : Item-Quantity needed) of the L2RecipeList */
private L2RecipeInstance[] _recipes;
/** The Identifier of the Instance */
private final int _id;
/** The crafting level needed to use this L2RecipeList */
private final int _level;
/** The Identifier of the L2RecipeList */
private final int _recipeId;
/** The name of the L2RecipeList */
private final String _recipeName;
/** The crafting succes rate when using the L2RecipeList */
private final int _successRate;
/** The crafting MP cost of this L2RecipeList */
private final int _mpCost;
/** The Identifier of the Item crafted with this L2RecipeList */
private final int _itemId;
/** The quantity of Item crafted when using this L2RecipeList */
private final int _count;
/** If this a common or a dwarven recipe */
private final boolean _IsDwarvenRecipe;
/**
* Constructor of L2RecipeList (create a new Recipe).<BR>
* <BR>
* @param id
* @param level
* @param recipeId
* @param recipeName
* @param successRate
* @param mpCost
* @param itemId
* @param count
* @param isDwarvenRecipe
*/
public L2RecipeList(int id, int level, int recipeId, String recipeName, int successRate, int mpCost, int itemId, int count, boolean isDwarvenRecipe)
{
_id = id;
_recipes = new L2RecipeInstance[0];
_level = level;
_recipeId = recipeId;
_recipeName = recipeName;
_successRate = successRate;
_mpCost = mpCost;
_itemId = itemId;
_count = count;
_IsDwarvenRecipe = isDwarvenRecipe;
}
/**
* Add a L2RecipeInstance to the L2RecipeList (add a line Item-Quantity needed to the Recipe).<BR>
* <BR>
* @param recipe
*/
public void addRecipe(L2RecipeInstance recipe)
{
final int len = _recipes.length;
final L2RecipeInstance[] tmp = new L2RecipeInstance[len + 1];
System.arraycopy(_recipes, 0, tmp, 0, len);
tmp[len] = recipe;
_recipes = tmp;
}
/**
* Return the Identifier of the Instance.<BR>
* <BR>
* @return
*/
public int getId()
{
return _id;
}
/**
* Return the crafting level needed to use this L2RecipeList.<BR>
* <BR>
* @return
*/
public int getLevel()
{
return _level;
}
/**
* Return the Identifier of the L2RecipeList.<BR>
* <BR>
* @return
*/
public int getRecipeId()
{
return _recipeId;
}
/**
* Return the name of the L2RecipeList.<BR>
* <BR>
* @return
*/
public String getRecipeName()
{
return _recipeName;
}
/**
* Return the crafting succes rate when using the L2RecipeList.<BR>
* <BR>
* @return
*/
public int getSuccessRate()
{
return _successRate;
}
/**
* Return the crafting MP cost of this L2RecipeList.<BR>
* <BR>
* @return
*/
public int getMpCost()
{
return _mpCost;
}
/**
* Return rue if the Item crafted with this L2RecipeList is consubable (shot, arrow,...).<BR>
* <BR>
* @return
*/
public boolean isConsumable()
{
return (((_itemId >= 1463) && (_itemId <= 1467)) // Soulshots
|| ((_itemId >= 2509) && (_itemId <= 2514)) // Spiritshots
|| ((_itemId >= 3947) && (_itemId <= 3952)) // Blessed Spiritshots
|| ((_itemId >= 1341) && (_itemId <= 1345)) // Arrows
);
}
/**
* Return the Identifier of the Item crafted with this L2RecipeList.<BR>
* <BR>
* @return
*/
public int getItemId()
{
return _itemId;
}
/**
* Return the quantity of Item crafted when using this L2RecipeList.<BR>
* <BR>
* @return
*/
public int getCount()
{
return _count;
}
/**
* Return <B>true</B> if this a Dwarven recipe or <B>false</B> if its a Common recipe
* @return
*/
public boolean isDwarvenRecipe()
{
return _IsDwarvenRecipe;
}
/**
* Return the table containing all L2RecipeInstance (1 line of the recipe : Item-Quantity needed) of the L2RecipeList.<BR>
* <BR>
* @return
*/
public L2RecipeInstance[] getRecipes()
{
return _recipes;
}
}

View File

@@ -0,0 +1,160 @@
/*
* 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.model;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.clientpackets.L2GameClientPacket;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
/**
* This class manages requests (transactions) between two L2PcInstance.
* @author kriau
*/
public class L2Request
{
public static final int REQUEST_TIMEOUT = 15; // in seconds
protected L2PcInstance _player;
protected L2PcInstance _partner;
protected boolean _isRequestor;
protected boolean _isAnswerer;
protected L2GameClientPacket _requestPacket;
public L2Request(L2PcInstance player)
{
_player = player;
}
protected void Clear()
{
_partner = null;
_requestPacket = null;
_isRequestor = false;
_isAnswerer = false;
}
/**
* Set the L2PcInstance member of a transaction (ex : FriendInvite, JoinAlly, JoinParty...).<BR>
* <BR>
* @param partner
*/
private synchronized void setPartner(L2PcInstance partner)
{
_partner = partner;
}
/**
* Return the L2PcInstance member of a transaction (ex : FriendInvite, JoinAlly, JoinParty...).<BR>
* <BR>
* @return
*/
public L2PcInstance getPartner()
{
return _partner;
}
/**
* Set the packet incomed from requestor.<BR>
* <BR>
* @param packet
*/
private synchronized void setRequestPacket(L2GameClientPacket packet)
{
_requestPacket = packet;
}
/**
* Return the packet originally incomed from requestor.<BR>
* <BR>
* @return
*/
public L2GameClientPacket getRequestPacket()
{
return _requestPacket;
}
/**
* Checks if request can be made and in success case puts both PC on request state.<BR>
* <BR>
* @param partner
* @param packet
* @return
*/
public synchronized boolean setRequest(L2PcInstance partner, L2GameClientPacket packet)
{
if (partner == null)
{
return false;
}
if (partner.getRequest().isProcessingRequest())
{
SystemMessage sm = new SystemMessage(SystemMessage.S1_IS_BUSY_TRY_LATER);
sm.addString(partner.getName());
_player.sendPacket(sm);
sm = null;
return false;
}
if (isProcessingRequest())
{
// Waiting another reply.
_player.sendPacket(new SystemMessage(164));
return false;
}
_partner = partner;
_requestPacket = packet;
setOnRequestTimer(true);
_partner.getRequest().setPartner(_player);
_partner.getRequest().setRequestPacket(packet);
_partner.getRequest().setOnRequestTimer(false);
return true;
}
private void setOnRequestTimer(boolean isRequestor)
{
_isRequestor = isRequestor ? true : false;
_isAnswerer = isRequestor ? false : true;
ThreadPoolManager.getInstance().scheduleGeneral(() -> Clear(), REQUEST_TIMEOUT * 1000);
}
/**
* Clears PC request state. Should be called after answer packet receive.<BR>
* <BR>
*/
public void onRequestResponse()
{
if (_partner != null)
{
_partner.getRequest().Clear();
}
Clear();
}
/**
* Return True if a transaction is in progress.<BR>
* <BR>
* @return
*/
public boolean isProcessingRequest()
{
return _partner != null;
}
}

View File

@@ -0,0 +1,70 @@
/*
* 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.model;
/**
* This class ...
* @version $Revision: 1.3.4.1 $ $Date: 2005/03/27 15:29:32 $
*/
public class L2ShortCut
{
public final static int TYPE_ITEM = 1;
public final static int TYPE_SKILL = 2;
public final static int TYPE_ACTION = 3;
public final static int TYPE_MACRO = 4;
public final static int TYPE_RECIPE = 5;
private final int _slot;
private final int _page;
private final int _type;
private final int _id;
private final int _level;
public L2ShortCut(int slotId, int pageId, int shortcutType, int shortcutId, int shortcutLevel, int unknown)
{
_slot = slotId;
_page = pageId;
_type = shortcutType;
_id = shortcutId;
_level = shortcutLevel;
}
public int getId()
{
return _id;
}
public int getLevel()
{
return _level;
}
public int getPage()
{
return _page;
}
public int getSlot()
{
return _slot;
}
public int getType()
{
return _type;
}
}

View File

@@ -0,0 +1,122 @@
/*
* 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.model;
import java.util.List;
import com.l2jmobius.gameserver.model.actor.instance.L2NpcInstance;
import javolution.util.FastList;
public class L2SiegeClan
{
// ==========================================================================================
// Instance
// ===============================================================
// Data Field
private int _ClanId = 0;
private List<L2NpcInstance> _Flag = new FastList<>();
private int _numFlagsAdded = 0;
private SiegeClanType _type;
public enum SiegeClanType
{
OWNER,
DEFENDER,
ATTACKER,
DEFENDER_PENDING
}
// =========================================================
// Constructor
public L2SiegeClan(int clanId, SiegeClanType type)
{
_ClanId = clanId;
_type = type;
}
// =========================================================
// Method - Public
public int getNumFlags()
{
return _numFlagsAdded;
}
public void addFlag(L2NpcInstance flag)
{
_numFlagsAdded++;
getFlag().add(flag);
}
public boolean removeFlag(L2NpcInstance flag)
{
if (flag == null)
{
return false;
}
final boolean ret = getFlag().remove(flag);
// flag.deleteMe();
// check if null objects or dups remain in the list.
// for some reason, this might be happenning sometimes...
// delete false dupplicates: if this flag got deleted, delete its copies too.
if (ret)
{
while (getFlag().remove(flag))
{
}
}
flag.deleteMe();
_numFlagsAdded--;
return ret;
}
public void removeFlags()
{
for (final L2NpcInstance flag : getFlag())
{
removeFlag(flag);
}
}
// =========================================================
// Proeprty
public final int getClanId()
{
return _ClanId;
}
public final List<L2NpcInstance> getFlag()
{
if (_Flag == null)
{
_Flag = new FastList<>();
}
return _Flag;
}
public SiegeClanType getType()
{
return _type;
}
public void setType(SiegeClanType setType)
{
_type = setType;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,97 @@
/*
* 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.model;
/**
* This class ...
* @version $Revision: 1.2.4.2 $ $Date: 2005/03/27 15:29:33 $
*/
public final class L2SkillLearn
{
// these two build the primary key
private final int _id;
private final int _level;
// not needed, just for easier debug
private final String _name;
private final int _spCost;
private final int _minLevel;
private final int _costid;
private final int _costcount;
public L2SkillLearn(int id, int lvl, int minLvl, String name, int cost, int costid, int costcount)
{
_id = id;
_level = lvl;
_minLevel = minLvl;
_name = name.intern();
_spCost = cost;
_costid = costid;
_costcount = costcount;
}
/**
* @return Returns the id.
*/
public int getId()
{
return _id;
}
/**
* @return Returns the level.
*/
public int getLevel()
{
return _level;
}
/**
* @return Returns the minLevel.
*/
public int getMinLevel()
{
return _minLevel;
}
/**
* @return Returns the name.
*/
public String getName()
{
return _name;
}
/**
* @return Returns the spCost.
*/
public int getSpCost()
{
return _spCost;
}
public int getIdCost()
{
return _costid;
}
public int getCostCount()
{
return _costcount;
}
}

View File

@@ -0,0 +1,708 @@
/*
* 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.model;
import java.lang.reflect.Constructor;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.GeoData;
import com.l2jmobius.gameserver.Territory;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.idfactory.IdFactory;
import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2NpcInstance;
import com.l2jmobius.gameserver.templates.L2NpcTemplate;
import com.l2jmobius.util.Rnd;
import javolution.util.FastList;
/**
* This class manages the spawn and respawn of a group of L2NpcInstance that are in the same are and have the same type. <B><U> Concept</U> :</B><BR>
* <BR>
* L2NpcInstance can be spawned either in a random position into a location area (if Lox=0 and Locy=0), either at an exact position. The heading of the L2NpcInstance can be a random heading if not defined (value= -1) or an exact heading (ex : merchant...).<BR>
* <BR>
* @author Nightmare
* @version $Revision: 1.9.2.3.2.8 $ $Date: 2005/03/27 15:29:32 $
*/
public class L2Spawn
{
protected static Logger _log = Logger.getLogger(L2Spawn.class.getName());
/** The link on the L2NpcTemplate object containing generic and static properties of this spawn (ex : RewardExp, RewardSP, AggroRange...) */
private L2NpcTemplate _template;
/** The Identifier of this spawn in the spawn table */
private int _id;
// private String _location = DEFAULT_LOCATION;
/** The identifier of the location area where L2NpcInstance can be spwaned */
private int _location;
/** The maximum number of L2NpcInstance that can manage this L2Spawn */
private int _maximumCount;
/** The current number of L2NpcInstance managed by this L2Spawn */
private int _currentCount;
/** The current number of SpawnTask in progress or stand by of this L2Spawn */
protected int _scheduledCount;
/** The X position of the spawn point */
private int _locx;
/** The Y position of the spawn point */
private int _locy;
/** The Z position of the spawn point */
private int _locz;
/** The heading of L2NpcInstance when they are spawned */
private int _heading;
/** The delay between a L2NpcInstance remove and its re-spawn */
private int _respawnDelay;
/** Minimum delay RaidBoss */
private int _respawnMinDelay;
/** Maximum delay RaidBoss */
private int _respawnMaxDelay;
/** The generic constructor of L2NpcInstance managed by this L2Spawn */
private Constructor<?> _constructor;
/** If True a L2NpcInstance is respawned each time that another is killed */
boolean _doRespawn;
/** If true then spawn is custom */
private boolean _customSpawn;
private L2NpcInstance _lastSpawn;
private static List<SpawnListener> _spawnListeners = new FastList<>();
/** The task launching the function doSpawn() */
class SpawnTask implements Runnable
{
L2NpcInstance oldNpc;
public SpawnTask(L2NpcInstance pOldNpc)
{
oldNpc = pOldNpc;
}
@Override
public void run()
{
try
{
if (_doRespawn)
{
respawnNpc(oldNpc);
}
}
catch (final Exception e)
{
_log.log(Level.WARNING, "", e);
}
_scheduledCount--;
}
}
/**
* Constructor of L2Spawn.<BR>
* <BR>
* <B><U> Concept</U> :</B><BR>
* <BR>
* Each L2Spawn owns generic and static properties (ex : RewardExp, RewardSP, AggroRange...). All of those properties are stored in a different L2NpcTemplate for each type of L2Spawn. Each template is loaded once in the server cache memory (reduce memory use). When a new instance of L2Spawn is
* created, server just create a link between the instance and the template. This link is stored in <B>_template</B><BR>
* <BR>
* Each L2NpcInstance is linked to a L2Spawn that manages its spawn and respawn (delay, location...). This link is stored in <B>_spawn</B> of the L2NpcInstance<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Set the _template of the L2Spawn</li>
* <li>Calculate the implementationName used to generate the generic constructor of L2NpcInstance managed by this L2Spawn</li>
* <li>Create the generic constructor of L2NpcInstance managed by this L2Spawn</li><BR>
* <BR>
* @param mobTemplate The L2NpcTemplate to link to this L2Spawn
* @throws SecurityException
* @throws ClassNotFoundException
* @throws NoSuchMethodException
*/
public L2Spawn(L2NpcTemplate mobTemplate) throws SecurityException, ClassNotFoundException, NoSuchMethodException
{
// Set the _template of the L2Spawn
_template = mobTemplate;
if (_template == null)
{
return;
}
// The Name of the L2NpcInstance type managed by this L2Spawn
String implementationName = _template.type; // implementing class name
if (mobTemplate.npcId == 7995)
{
implementationName = "L2RaceManager";
}
// if (mobTemplate.npcId == 8050)
if ((mobTemplate.npcId >= 8046) && (mobTemplate.npcId <= 8053))
{
implementationName = "L2SymbolMaker";
}
// Create the generic constructor of L2NpcInstance managed by this L2Spawn
@SuppressWarnings("rawtypes")
final Class[] parameters =
{
int.class,
Class.forName("com.l2jmobius.gameserver.templates.L2NpcTemplate")
};
_constructor = Class.forName("com.l2jmobius.gameserver.model.actor.instance." + implementationName + "Instance").getConstructor(parameters);
}
/**
* Return the maximum number of L2NpcInstance that this L2Spawn can manage.<BR>
* <BR>
* @return
*/
public int getAmount()
{
return _maximumCount;
}
/**
* Return the Identifier of this L2Spawn (used as key in the SpawnTable).<BR>
* <BR>
* @return
*/
public int getId()
{
return _id;
}
/**
* Return the Identifier of the location area where L2NpcInstance can be spwaned.<BR>
* <BR>
* @return
*/
public int getLocation()
{
return _location;
}
/**
* Return the X position of the spwan point.<BR>
* <BR>
* @return
*/
public int getLocx()
{
return _locx;
}
/**
* Return the Y position of the spwan point.<BR>
* <BR>
* @return
*/
public int getLocy()
{
return _locy;
}
/**
* Return the Z position of the spwan point.<BR>
* <BR>
* @return
*/
public int getLocz()
{
return _locz;
}
/**
* Return the Itdentifier of the L2NpcInstance manage by this L2Spawn contained in the L2NpcTemplate.<BR>
* <BR>
* @return
*/
public int getNpcid()
{
return _template.npcId;
}
/**
* Return the heading of L2NpcInstance when they are spawned.<BR>
* <BR>
* @return
*/
public int getHeading()
{
return _heading;
}
/**
* Return the delay between a L2NpcInstance remove and its re-spawn.<BR>
* <BR>
* @return
*/
public int getRespawnDelay()
{
return _respawnDelay;
}
/*
* Return Min RaidBoss Spawn delay.<BR><BR>
*/
public int getRespawnMinDelay()
{
return _respawnMinDelay;
}
/*
* Return Max RaidBoss Spawn delay.<BR><BR>
*/
public int getRespawnMaxDelay()
{
return _respawnMaxDelay;
}
/**
* Set the maximum number of L2NpcInstance that this L2Spawn can manage.<BR>
* <BR>
* @param amount
*/
public void setAmount(int amount)
{
_maximumCount = amount;
}
/**
* Set the Identifier of this L2Spawn (used as key in the SpawnTable).<BR>
* <BR>
* @param id
*/
public void setId(int id)
{
_id = id;
}
/**
* Set the Identifier of the location area where L2NpcInstance can be spwaned.<BR>
* <BR>
* @param location
*/
public void setLocation(int location)
{
_location = location;
}
/**
* Set Minimum Respawn Delay.<BR>
* <BR>
* @param date
*/
public void setRespawnMinDelay(int date)
{
_respawnMinDelay = date;
}
/**
* Set Maximum Respawn Delay.<BR>
* <BR>
* @param date
*/
public void setRespawnMaxDelay(int date)
{
_respawnMaxDelay = date;
}
/**
* Set the X position of the spwan point.<BR>
* <BR>
* @param locx
*/
public void setLocx(int locx)
{
_locx = locx;
}
/**
* Set the Y position of the spwan point.<BR>
* <BR>
* @param locy
*/
public void setLocy(int locy)
{
_locy = locy;
}
/**
* Set the Z position of the spwan point.<BR>
* <BR>
* @param locz
*/
public void setLocz(int locz)
{
_locz = locz;
}
/**
* Set the heading of L2NpcInstance when they are spawned.<BR>
* <BR>
* @param heading
*/
public void setHeading(int heading)
{
_heading = heading;
}
/**
* Set the spawn as custom.<BR>
* <BR>
* @param custom
*/
public void setCustom(boolean custom)
{
_customSpawn = custom;
}
/**
* Return type of spawn.<BR>
* <BR>
* @return
*/
public boolean isCustom()
{
return _customSpawn;
}
/**
* Decrease the current number of L2NpcInstance of this L2Spawn and if necessary create a SpawnTask to launch after the respawn Delay.<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Decrease the current number of L2NpcInstance of this L2Spawn</li>
* <li>Check if respawn is possible to prevent multiple respawning caused by lag</li>
* <li>Update the current number of SpawnTask in progress or stand by of this L2Spawn</li>
* <li>Create a new SpawnTask to launch after the respawn Delay</li><BR>
* <BR>
* <FONT COLOR=#FF0000><B> <U>Caution</U> : A respawn is possible ONLY if _doRespawn=True and _scheduledCount + _currentCount < _maximumCount</B></FONT><BR>
* <BR>
* @param oldNpc
*/
public void decreaseCount(L2NpcInstance oldNpc)
{
// sanity check
if (_currentCount <= 0)
{
return;
}
// Decrease the current number of L2NpcInstance of this L2Spawn
_currentCount--;
// Check if respawn is possible to prevent multiple respawning caused by lag
if (_doRespawn && ((_scheduledCount + _currentCount) < _maximumCount))
{
// Update the current number of SpawnTask in progress or stand by of this L2Spawn
_scheduledCount++;
// Create a new SpawnTask to launch after the respawn Delay
// ClientScheduler.getInstance().scheduleLow(new SpawnTask(npcId), _respawnDelay);
ThreadPoolManager.getInstance().scheduleGeneral(new SpawnTask(oldNpc), _respawnDelay);
}
}
/**
* Create the initial spawning and set _doRespawn to True.<BR>
* <BR>
* @return The number of L2NpcInstance that were spawned
*/
public int init()
{
while (_currentCount < _maximumCount)
{
doSpawn();
}
_doRespawn = true;
return _currentCount;
}
/**
* Create a L2NpcInstance in this L2Spawn.<BR>
* <BR>
* @return
*/
public L2NpcInstance spawnOne()
{
return doSpawn();
}
/**
* Set _doRespawn to False to stop respawn in thios L2Spawn.<BR>
* <BR>
*/
public void stopRespawn()
{
_doRespawn = false;
}
/**
* Set _doRespawn to True to start or restart respawn in this L2Spawn.<BR>
* <BR>
*/
public void startRespawn()
{
_doRespawn = true;
}
/**
* Create the L2NpcInstance, add it to the world and lauch its onSpawn action.<BR>
* <BR>
* <B><U> Concept</U> :</B><BR>
* <BR>
* L2NpcInstance can be spawned either in a random position into a location area (if Lox=0 and Locy=0), either at an exact position. The heading of the L2NpcInstance can be a random heading if not defined (value= -1) or an exact heading (ex : merchant...).<BR>
* <BR>
* <B><U> Actions for an random spawn into location area</U> : <I>(if Locx=0 and Locy=0)</I></B><BR>
* <BR>
* <li>Get L2NpcInstance Init parameters and its generate an Identifier</li>
* <li>Call the constructor of the L2NpcInstance</li>
* <li>Calculate the random position in the location area (if Locx=0 and Locy=0) or get its exact position from the L2Spawn</li>
* <li>Set the position of the L2NpcInstance</li>
* <li>Set the HP and MP of the L2NpcInstance to the max</li>
* <li>Set the heading of the L2NpcInstance (random heading if not defined : value=-1)</li>
* <li>Link the L2NpcInstance to this L2Spawn</li>
* <li>Init other values of the L2NpcInstance (ex : from its L2CharTemplate for INT, STR, DEX...) and add it in the world</li>
* <li>Lauch the action onSpawn fo the L2NpcInstance</li><BR>
* <BR>
* <li>Increase the current number of L2NpcInstance managed by this L2Spawn</li><BR>
* <BR>
* @return
*/
public L2NpcInstance doSpawn()
{
L2NpcInstance mob = null;
try
{
// Check if the L2Spawn is not a L2Pet, L2BabyPet, L2SiegeSummon or L2Minion spawn
if (_template.type.equalsIgnoreCase("L2Pet") || _template.type.equalsIgnoreCase("L2BabyPet") || _template.type.equalsIgnoreCase("L2SiegeSummon") || _template.type.equalsIgnoreCase("L2Minion"))
{
_currentCount++;
return mob;
}
// Get L2NpcInstance Init parameters and its generate an Identifier
final Object[] parameters =
{
IdFactory.getInstance().getNextId(),
_template
};
// Call the constructor of the L2NpcInstance
// (can be a L2ArtefactInstance, L2FriendlyMobInstance, L2GuardInstance, L2MonsterInstance, L2SiegeGuardInstance, L2BoxInstance or L2FolkInstance)
final Object tmp = _constructor.newInstance(parameters);
// Check if the Instance is a L2NpcInstance
if (!(tmp instanceof L2NpcInstance))
{
return mob;
}
mob = (L2NpcInstance) tmp;
return initializeNpcInstance(mob);
}
catch (final Exception e)
{
_log.log(Level.WARNING, "NPC " + _template.npcId + " class not found", e);
}
return mob;
}
/**
* @param mob
* @return
*/
private L2NpcInstance initializeNpcInstance(L2NpcInstance mob)
{
// declare summon animation
mob.setShowSummonAnimation(true);
int newlocx, newlocy, newlocz;
// If Locx=0 and Locy=0, the L2NpcInstance must be spawned in an area defined by location
if ((getLocx() == 0) && (getLocy() == 0))
{
if (getLocation() == 0)
{
return mob;
}
// Calculate the random position in the location area
final int p[] = Territory.getInstance().getRandomPoint(getLocation());
// Set the calculated position of the L2NpcInstance
newlocx = p[0];
newlocy = p[1];
newlocz = p[3];
}
else
{
// The L2NpcInstance is spawned at the exact position (Lox, Locy, Locz)
newlocx = getLocx();
newlocy = getLocy();
newlocz = getLocz();
}
// don't correct z of flying npc's
if (!mob.isFlying())
{
newlocz = GeoData.getInstance().getSpawnHeight(newlocx, newlocy, newlocz, newlocz);
}
for (final L2Effect f : mob.getAllEffects())
{
if (f != null)
{
mob.removeEffect(f);
}
}
mob.setIsDead(false);
// Reset decay info
mob.setDecayed(false);
// Set the HP and MP of the L2NpcInstance to the max
mob.setCurrentHpMp(mob.getMaxHp(), mob.getMaxMp());
// Set the heading of the L2NpcInstance (random heading if not defined)
if (getHeading() == -1)
{
mob.setHeading(Rnd.nextInt(61794));
}
else
{
mob.setHeading(getHeading());
}
mob.setChampion(false);
if (Config.CHAMPION_ENABLE)
{
// Set champion on next spawn
if ((mob instanceof L2MonsterInstance) && !getTemplate().isQuestMonster && !mob.isRaid() && (Config.CHAMPION_FREQUENCY > 0) && (mob.getLevel() >= Config.CHAMP_MIN_LVL) && (mob.getLevel() <= Config.CHAMP_MAX_LVL))
{
if (Rnd.get(100) < Config.CHAMPION_FREQUENCY)
{
mob.setChampion(true);
}
}
}
// Link the L2NpcInstance to this L2Spawn
mob.setSpawn(this);
// Init other values of the L2NpcInstance (ex : from its L2CharTemplate for INT, STR, DEX...) and add it in the world as a visible object
mob.spawnMe(newlocx, newlocy, newlocz);
L2Spawn.notifyNpcSpawned(mob);
_lastSpawn = mob;
if (Config.DEBUG)
{
_log.finest("spawned Mob ID: " + _template.npcId + " ,at: " + mob.getX() + " x, " + mob.getY() + " y, " + mob.getZ() + " z");
}
// Increase the current number of L2NpcInstance managed by this L2Spawn
_currentCount++;
return mob;
}
public static void addSpawnListener(SpawnListener listener)
{
synchronized (_spawnListeners)
{
_spawnListeners.add(listener);
}
}
public static void removeSpawnListener(SpawnListener listener)
{
synchronized (_spawnListeners)
{
_spawnListeners.remove(listener);
}
}
public static void notifyNpcSpawned(L2NpcInstance npc)
{
synchronized (_spawnListeners)
{
for (final SpawnListener listener : _spawnListeners)
{
listener.npcSpawned(npc);
}
}
}
/**
* @param i delay in seconds
*/
public void setRespawnDelay(int i)
{
if (i < 0)
{
_log.warning("respawn delay is negative for spawnId:" + _id);
}
if (i < 60)
{
i = 60;
}
_respawnDelay = i * 1000;
}
public L2NpcInstance getLastSpawn()
{
return _lastSpawn;
}
/**
* @param oldNpc
*/
public void respawnNpc(L2NpcInstance oldNpc)
{
oldNpc.refreshID();
initializeNpcInstance(oldNpc);
}
public L2NpcTemplate getTemplate()
{
return _template;
}
}

View File

@@ -0,0 +1,912 @@
/*
* 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.model;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.GeoData;
import com.l2jmobius.gameserver.ai.CtrlIntention;
import com.l2jmobius.gameserver.ai.L2CharacterAI;
import com.l2jmobius.gameserver.ai.L2SummonAI;
import com.l2jmobius.gameserver.datatables.SkillTable;
import com.l2jmobius.gameserver.model.L2Attackable.AggroInfo;
import com.l2jmobius.gameserver.model.L2Skill.SkillTargetType;
import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2PlayableInstance;
import com.l2jmobius.gameserver.model.actor.knownlist.SummonKnownList;
import com.l2jmobius.gameserver.model.actor.stat.SummonStat;
import com.l2jmobius.gameserver.model.actor.status.SummonStatus;
import com.l2jmobius.gameserver.model.base.Experience;
import com.l2jmobius.gameserver.network.L2GameClient;
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import com.l2jmobius.gameserver.network.serverpackets.MyTargetSelected;
import com.l2jmobius.gameserver.network.serverpackets.NpcInfo;
import com.l2jmobius.gameserver.network.serverpackets.PartySpelled;
import com.l2jmobius.gameserver.network.serverpackets.PetDelete;
import com.l2jmobius.gameserver.network.serverpackets.PetInfo;
import com.l2jmobius.gameserver.network.serverpackets.PetStatusShow;
import com.l2jmobius.gameserver.network.serverpackets.PetStatusUpdate;
import com.l2jmobius.gameserver.network.serverpackets.RelationChanged;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.network.serverpackets.ValidateLocation;
import com.l2jmobius.gameserver.taskmanager.DecayTaskManager;
import com.l2jmobius.gameserver.templates.L2NpcTemplate;
import com.l2jmobius.gameserver.templates.L2Weapon;
public abstract class L2Summon extends L2PlayableInstance
{
// private static Logger _log = Logger.getLogger(L2Summon.class.getName());
private L2PcInstance _owner;
private int _attackRange = 36; // Melee range
private boolean _follow = true;
private boolean _previousFollowStatus = true;
public boolean _isSiegeGolem = false;
private int _chargedSoulShot;
private int _chargedSpiritShot;
public class AIAccessor extends L2Character.AIAccessor
{
protected AIAccessor()
{
}
public L2Summon getSummon()
{
return L2Summon.this;
}
public boolean isAutoFollow()
{
return getFollowStatus();
}
public void doPickupItem(L2Object object)
{
L2Summon.this.doPickupItem(object);
}
}
public L2Summon(int objectId, L2NpcTemplate template, L2PcInstance owner)
{
super(objectId, template);
getKnownList();
getStat();
getStatus();
_showSummonAnimation = true;
_owner = owner;
_ai = new L2SummonAI(new L2Summon.AIAccessor());
setXYZInvisible(owner.getX() + 50, owner.getY() + 100, owner.getZ() + 100);
}
@Override
public void onSpawn()
{
setFollowStatus(true);
updateAndBroadcastStatus(0);
getOwner().sendPacket(new RelationChanged(this, getOwner().getRelation(getOwner()), false));
for (final L2PcInstance player : getOwner().getKnownList().getKnownPlayersInRadius(800))
{
player.sendPacket(new RelationChanged(this, getOwner().getRelation(player), isAutoAttackable(player)));
}
super.onSpawn();
}
@Override
public final SummonKnownList getKnownList()
{
if ((super.getKnownList() == null) || !(super.getKnownList() instanceof SummonKnownList))
{
setKnownList(new SummonKnownList(this));
}
return (SummonKnownList) super.getKnownList();
}
@Override
public SummonStat getStat()
{
if ((super.getStat() == null) || !(super.getStat() instanceof SummonStat))
{
setStat(new SummonStat(this));
}
return (SummonStat) super.getStat();
}
@Override
public SummonStatus getStatus()
{
if ((super.getStatus() == null) || !(super.getStatus() instanceof SummonStatus))
{
setStatus(new SummonStatus(this));
}
return (SummonStatus) super.getStatus();
}
@Override
public L2CharacterAI getAI()
{
if (_ai == null)
{
synchronized (this)
{
if (_ai == null)
{
_ai = new L2SummonAI(new L2Summon.AIAccessor());
}
}
}
return _ai;
}
@Override
public L2NpcTemplate getTemplate()
{
return (L2NpcTemplate) super.getTemplate();
}
// this defines the action buttons, 1 for Summon, 2 for Pets
public abstract int getSummonType();
@Override
public void updateAbnormalEffect()
{
for (final L2PcInstance player : getKnownList().getKnownPlayers().values())
{
player.sendPacket(new NpcInfo(this, player, 1));
}
}
/**
* @return Returns the mountable.
*/
public boolean isMountable()
{
return false;
}
@Override
public void onAction(L2PcInstance player)
{
if ((player == _owner) && (player.getTarget() == this))
{
player.sendPacket(new PetStatusShow(this));
player.sendPacket(new ActionFailed());
}
else if (player.getTarget() != this)
{
if (Config.DEBUG)
{
_log.fine("new target selected:" + getObjectId());
}
player.setTarget(this);
final MyTargetSelected my = new MyTargetSelected(getObjectId(), player.getLevel() - getLevel());
player.sendPacket(my);
player.sendPacket(new ValidateLocation(this));
}
else if (player.getTarget() == this)
{
player.sendPacket(new ValidateLocation(this));
if (isAutoAttackable(player))
{
if (Config.GEODATA > 0)
{
if (GeoData.getInstance().canSeeTarget(player, this))
{
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, this);
player.onActionRequest();
}
}
else
{
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, this);
player.onActionRequest();
}
}
else
{
// This Action Failed packet avoids player getting stuck when clicking three or more times
player.sendPacket(new ActionFailed());
if (Config.GEODATA > 0)
{
if (GeoData.getInstance().canSeeTarget(player, this))
{
player.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, this);
}
}
else
{
player.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, this);
}
}
}
}
@Override
public void onActionShift(L2GameClient client)
{
// Get the L2PcInstance corresponding to the thread
final L2PcInstance player = client.getActiveChar();
if (player == null)
{
return;
}
if (player.getTarget() != this)
{
player.setTarget(this);
final MyTargetSelected my = new MyTargetSelected(getObjectId(), player.getLevel() - getLevel());
player.sendPacket(my);
}
player.sendPacket(new ValidateLocation(this));
// This Action Failed packet avoids player getting stuck when shift-clicking
player.sendPacket(new ActionFailed());
}
public long getExpForThisLevel()
{
if (getLevel() >= Experience.LEVEL.length)
{
return 0;
}
return Experience.LEVEL[getLevel()];
}
public long getExpForNextLevel()
{
if (getLevel() >= (Experience.LEVEL.length - 1))
{
return 0;
}
return Experience.LEVEL[getLevel() + 1];
}
public final L2PcInstance getOwner()
{
return _owner;
}
public final int getNpcId()
{
return getTemplate().npcId;
}
public void setChargedSoulShot(int shotType)
{
_chargedSoulShot = shotType;
}
public void setChargedSpiritShot(int shotType)
{
_chargedSpiritShot = shotType;
}
public final short getSoulShotsPerHit()
{
if (getTemplate().ss > 1)
{
return getTemplate().ss;
}
return 1;
}
public final short getSpiritShotsPerHit()
{
if (getTemplate().bss > 1)
{
return getTemplate().bss;
}
return 1;
}
public void followOwner()
{
setFollowStatus(true);
}
@Override
public boolean doDie(L2Character killer)
{
if (!super.doDie(killer))
{
return false;
}
if (getOwner() != null)
{
for (final L2Character TgMob : getKnownList().getKnownCharacters())
{
// get the mobs which have aggro on this instance
if (TgMob instanceof L2Attackable)
{
if (((L2Attackable) TgMob).isDead())
{
continue;
}
final AggroInfo info = ((L2Attackable) TgMob).getAggroList().get(this);
if (info != null)
{
((L2Attackable) TgMob).addDamageHate(getOwner(), info.damage, info.hate);
}
}
}
}
DecayTaskManager.getInstance().addDecayTask(this);
return true;
}
public boolean doDie(L2Character killer, boolean decayed)
{
if (!super.doDie(killer))
{
return false;
}
if (!decayed)
{
DecayTaskManager.getInstance().addDecayTask(this);
}
return true;
}
public void stopDecay()
{
DecayTaskManager.getInstance().cancelDecayTask(this);
}
@Override
public void onDecay()
{
deleteMe(_owner);
}
@Override
public void updateEffectIcons(boolean partyOnly)
{
final PartySpelled ps = new PartySpelled(this);
// Go through all effects if any
final L2Effect[] effects = getAllEffects();
if ((effects != null) && (effects.length > 0))
{
for (final L2Effect effect : effects)
{
if ((effect == null) || !effect.getShowIcon())
{
continue;
}
if (effect.getInUse())
{
effect.addPartySpelledIcon(ps);
}
}
}
getOwner().sendPacket(ps);
}
@Override
public void broadcastStatusUpdate()
{
super.broadcastStatusUpdate();
updateAndBroadcastStatus(1);
}
public void updateAndBroadcastStatus(int val)
{
if (getOwner() == null)
{
return;
}
getOwner().sendPacket(new PetInfo(this, val));
getOwner().sendPacket(new PetStatusUpdate(this));
if (isVisible())
{
broadcastNpcInfo(val);
}
updateEffectIcons(true);
}
public void broadcastNpcInfo(int val)
{
for (final L2PcInstance player : getKnownList().getKnownPlayers().values())
{
if ((player == null) || (player == getOwner()))
{
continue;
}
player.sendPacket(new NpcInfo(this, player, val));
}
}
public void deleteMe(L2PcInstance owner)
{
getAI().stopFollow();
owner.sendPacket(new PetDelete(getSummonType(), getObjectId()));
// pet will be deleted along with all its items
if (getInventory() != null)
{
getInventory().destroyAllItems("pet deleted", getOwner(), this);
}
decayMe();
getKnownList().removeAllKnownObjects();
owner.setPet(null);
}
public void unSummon(L2PcInstance owner)
{
if (isVisible() && !isDead())
{
// stop HP and MP regeneration
stopHpMpRegeneration();
getAI().stopFollow();
owner.sendPacket(new PetDelete(getSummonType(), getObjectId()));
store();
giveAllToOwner();
owner.setPet(null);
stopAllEffects();
final L2WorldRegion oldRegion = getWorldRegion();
decayMe();
if (oldRegion != null)
{
oldRegion.removeFromZones(this);
}
getKnownList().removeAllKnownObjects();
setTarget(null);
for (final int itemId : owner.getAutoSoulShot())
{
if ((itemId == 6645) || (itemId == 6646) || (itemId == 6647))
{
owner.disableAutoShot(itemId);
}
}
}
}
public int getAttackRange()
{
return _attackRange;
}
public void setAttackRange(int range)
{
if (range < 36)
{
range = 36;
}
_attackRange = range;
}
public void setFollowStatus(boolean state)
{
_follow = state;
if (_follow)
{
getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, getOwner());
}
else
{
getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE, null);
}
}
public boolean getFollowStatus()
{
return _follow;
}
public boolean isSiegeGolem()
{
return _isSiegeGolem;
}
public boolean isHungry()
{
return false;
}
public int getWeapon()
{
return 0;
}
public int getArmor()
{
return 0;
}
@Override
public boolean isAutoAttackable(L2Character attacker)
{
return _owner.isAutoAttackable(attacker);
}
public int getChargedSoulShot()
{
return _chargedSoulShot;
}
public int getChargedSpiritShot()
{
return _chargedSpiritShot;
}
@Override
public boolean isInCombat()
{
return getOwner().isInCombat();
}
public int getControlItemId()
{
return 0;
}
public int getCurrentFed()
{
return 0;
}
public int getMaxFed()
{
return 0;
}
public int getPetSpeed()
{
return getTemplate().baseRunSpd;
}
public L2Weapon getActiveWeapon()
{
return null;
}
public PetInventory getInventory()
{
return null;
}
protected void doPickupItem(L2Object object)
{
}
public void giveAllToOwner()
{
}
public void store()
{
}
@Override
public L2ItemInstance getActiveWeaponInstance()
{
return null;
}
@Override
public L2Weapon getActiveWeaponItem()
{
return null;
}
@Override
public L2ItemInstance getSecondaryWeaponInstance()
{
return null;
}
@Override
public L2Weapon getSecondaryWeaponItem()
{
return null;
}
/**
* Return the L2Party object of its L2PcInstance owner or null.<BR>
* <BR>
*/
@Override
public L2Party getParty()
{
if (_owner == null)
{
return null;
}
return _owner.getParty();
}
@Override
public boolean isInvul()
{
return _IsInvul || _IsTeleporting || getOwner().isSpawnProtected();
}
/**
* Return True if the L2Character has a Party in progress.<BR>
* <BR>
*/
@Override
public boolean isInParty()
{
if (_owner == null)
{
return false;
}
return _owner.getParty() != null;
}
/**
* Check if the active L2Skill can be casted.<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Check if the target is correct</li>
* <li>Check if the target is in the skill cast range</li>
* <li>Check if the summon owns enough HP and MP to cast the skill</li>
* <li>Check if all skills are enabled and this skill is enabled</li><BR>
* <BR>
* <li>Check if the skill is active</li><BR>
* <BR>
* <li>Notify the AI with AI_INTENTION_CAST and target</li><BR>
* <BR>
* @param skill The L2Skill to use
* @param forceUse used to force ATTACK on players
* @param dontMove used to prevent movement, if not in range
*/
public void useMagic(L2Skill skill, boolean forceUse, boolean dontMove)
{
if ((skill == null) || isDead())
{
return;
}
// Check if the skill is active
if (skill.isPassive())
{
// just ignore the passive skill request. why does the client send it anyway ??
return;
}
// ************************************* Check Casting in Progress *******************************************
// If a skill is currently being used
if (isCastingNow())
{
return;
}
// Set current pet skill
getOwner().setCurrentPetSkill(skill, forceUse, dontMove);
// ************************************* Check Target *******************************************
// Get the target for the skill
L2Object target = null;
switch (skill.getTargetType())
{
// OWNER_PET should be cast even if no target has been found
case TARGET_OWNER_PET:
target = getOwner();
break;
// PARTY, AURA, SELF should be cast even if no target has been found
case TARGET_PARTY:
case TARGET_AURA:
case TARGET_SELF:
target = this;
break;
default:
// Get the first target of the list
target = skill.getFirstOfTargetList(this);
break;
}
// Check the validity of the target
if (target == null)
{
if (getOwner() != null)
{
getOwner().sendPacket(new SystemMessage(SystemMessage.TARGET_CANT_FOUND));
}
return;
}
// ************************************* Check skill availability *******************************************
// Check if this skill is enabled (ex : reuse time)
if (isAllSkillsDisabled() && (getOwner() != null) && (getOwner().getAccessLevel() < Config.GM_PEACEATTACK))
{
return;
}
// ************************************* Check Consumables *******************************************
// Check if the summon has enough MP
if (getCurrentMp() < (getStat().getMpConsume(skill) + getStat().getMpInitialConsume(skill)))
{
// Send a System Message to the caster
if (getOwner() != null)
{
getOwner().sendPacket(new SystemMessage(SystemMessage.NOT_ENOUGH_MP));
}
return;
}
// Check if the summon has enough HP
if (getCurrentHp() <= skill.getHpConsume())
{
// Send a System Message to the caster
if (getOwner() != null)
{
getOwner().sendPacket(new SystemMessage(SystemMessage.NOT_ENOUGH_HP));
}
return;
}
// ************************************* Check Summon State *******************************************
// Check if this is offensive magic skill
if (skill.isOffensive())
{
if (isInsidePeaceZone(this, target) && (getOwner() != null) && (getOwner().getAccessLevel() < Config.GM_PEACEATTACK))
{
// If summon or target is in a peace zone, send a system message TARGET_IN_PEACEZONE
getOwner().sendPacket(new SystemMessage(SystemMessage.TARGET_IN_PEACEZONE));
return;
}
if ((getOwner() != null) && getOwner().isInOlympiadMode() && !getOwner().isOlympiadStart())
{
// if L2PcInstance is in Olympiad and the match isn't already start, send a Server->Client packet ActionFailed
sendPacket(new ActionFailed());
return;
}
// Check if the target is attackable
if (target instanceof L2DoorInstance)
{
if (!((L2DoorInstance) target).isAttackable(getOwner()))
{
return;
}
}
else
{
if (!target.isAttackable() && (getOwner() != null) && (getOwner().getAccessLevel() < Config.GM_PEACEATTACK))
{
return;
}
// Check if a Forced ATTACK is in progress on non-attackable target
if (!target.isAutoAttackable(this) && !forceUse && (skill.getTargetType() != SkillTargetType.TARGET_AURA) && (skill.getTargetType() != SkillTargetType.TARGET_CLAN) && (skill.getTargetType() != SkillTargetType.TARGET_ALLY) && (skill.getTargetType() != SkillTargetType.TARGET_PARTY) && (skill.getTargetType() != SkillTargetType.TARGET_SELF))
{
return;
}
}
}
// Notify the AI with AI_INTENTION_CAST and target
getAI().setIntention(CtrlIntention.AI_INTENTION_CAST, skill, target);
}
@Override
public void setIsImmobilized(boolean value)
{
super.setIsImmobilized(value);
if (value)
{
_previousFollowStatus = getFollowStatus();
// if immobilized temporarily disable follow mode
if (_previousFollowStatus)
{
setFollowStatus(false);
}
}
else
{
// if not more immobilized restore previous follow mode
setFollowStatus(_previousFollowStatus);
}
}
public void setOwner(L2PcInstance newOwner)
{
_owner = newOwner;
}
/**
* Servitors' skills automatically change their level based on the servitor's level. Until level 70, the servitor gets 1 lv of skill per 10 levels. After that, it is 1 skill level per 5 servitor levels. If the resulting skill level doesn't exist use the max that does exist!
* @see com.l2jmobius.gameserver.model.L2Character#doCast(com.l2jmobius.gameserver.model.L2Skill)
*/
@Override
public void doCast(L2Skill skill)
{
if (!getOwner().checkPvpSkill(getTarget(), skill, true) && (getOwner().getAccessLevel() < Config.GM_PEACEATTACK))
{
getOwner().sendPacket(new SystemMessage(SystemMessage.TARGET_IS_INCORRECT));
// Send a Server->Client packet ActionFailed to the L2PcInstance
getOwner().sendPacket(new ActionFailed());
return;
}
final int petLevel = getLevel();
int skillLevel = petLevel / 10;
if (petLevel >= 70)
{
skillLevel += (petLevel - 65) / 10;
}
// adjust the level for servitors less than lv 10
if (skillLevel < 1)
{
skillLevel = 1;
}
final L2Skill skillToCast = SkillTable.getInstance().getInfo(skill.getId(), skillLevel);
if (skillToCast != null)
{
super.doCast(skillToCast);
}
else
{
super.doCast(skill);
}
}
@Override
public L2PcInstance getActingPlayer()
{
return getOwner();
}
}

View File

@@ -0,0 +1,54 @@
/*
* 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.model;
/**
* @author -Nemesiss-
*/
public class L2SummonItem
{
private final int _itemId;
private final int _npcId;
private final byte _type;
public L2SummonItem(int itemId, int npcId, byte type)
{
_itemId = itemId;
_npcId = npcId;
_type = type;
}
public int getItemId()
{
return _itemId;
}
public int getNpcId()
{
return _npcId;
}
public byte getType()
{
return _type;
}
public boolean isPetSummon()
{
return (_type == 1) || (_type == 2);
}
}

View File

@@ -0,0 +1,127 @@
/*
* 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.model;
/**
* This class ...
* @version $Revision: 1.2.4.1 $ $Date: 2005/03/27 15:29:32 $
*/
public class L2TeleportLocation
{
private int _teleId;
private int _locX;
private int _locY;
private int _locZ;
private int _price;
private boolean _fornoble;
/**
* @param id
*/
public void setTeleId(int id)
{
_teleId = id;
}
/**
* @param locX
*/
public void setLocX(int locX)
{
_locX = locX;
}
/**
* @param locY
*/
public void setLocY(int locY)
{
_locY = locY;
}
/**
* @param locZ
*/
public void setLocZ(int locZ)
{
_locZ = locZ;
}
/**
* @param price
*/
public void setPrice(int price)
{
_price = price;
}
/**
* @param val
*/
public void setIsForNoble(boolean val)
{
_fornoble = val;
}
/**
* @return
*/
public int getTeleId()
{
return _teleId;
}
/**
* @return
*/
public int getLocX()
{
return _locX;
}
/**
* @return
*/
public int getLocY()
{
return _locY;
}
/**
* @return
*/
public int getLocZ()
{
return _locZ;
}
/**
* @return
*/
public int getPrice()
{
return _price;
}
/**
* @return
*/
public boolean getIsForNoble()
{
return _fornoble;
}
}

View File

@@ -0,0 +1,205 @@
/*
* 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.model;
import java.util.List;
import java.util.logging.Logger;
import com.l2jmobius.util.Rnd;
import javolution.util.FastList;
public class L2Territory
{
private static Logger _log = Logger.getLogger(L2Territory.class.getName());
protected class Point
{
protected int x, y, zmin, zmax, proc;
Point(int _x, int _y, int _zmin, int _zmax, int _proc)
{
x = _x;
y = _y;
zmin = _zmin;
zmax = _zmax;
proc = _proc;
}
}
private final List<Point> _points;
private final int _terr;
private int _x_min;
private int _x_max;
private int _y_min;
private int _y_max;
private int _z_min;
private int _z_max;
private int _proc_max;
public L2Territory(int terr)
{
_points = new FastList<>();
_terr = terr;
_x_min = 999999;
_x_max = -999999;
_y_min = 999999;
_y_max = -999999;
_z_min = 999999;
_z_max = -999999;
_proc_max = 0;
}
public void add(int x, int y, int zmin, int zmax, int proc)
{
_points.add(new Point(x, y, zmin, zmax, proc));
if (x < _x_min)
{
_x_min = x;
}
if (y < _y_min)
{
_y_min = y;
}
if (x > _x_max)
{
_x_max = x;
}
if (y > _y_max)
{
_y_max = y;
}
if (zmin < _z_min)
{
_z_min = zmin;
}
if (zmax > _z_max)
{
_z_max = zmax;
}
_proc_max += proc;
}
public void print()
{
for (final Point p : _points)
{
System.out.println("(" + p.x + "," + p.y + ")");
}
}
public boolean isIntersect(int x, int y, Point p1, Point p2)
{
final double dy1 = p1.y - y;
final double dy2 = p2.y - y;
if (Math.signum(dy1) == Math.signum(dy2))
{
return false;
}
final double dx1 = p1.x - x;
final double dx2 = p2.x - x;
if ((dx1 >= 0) && (dx2 >= 0))
{
return true;
}
if ((dx1 < 0) && (dx2 < 0))
{
return false;
}
final double dx0 = (dy1 * (p1.x - p2.x)) / (p1.y - p2.y);
return dx0 <= dx1;
}
public boolean isInside(int x, int y)
{
int intersect_count = 0;
for (int i = 0; i < _points.size(); i++)
{
final Point p1 = _points.get(i > 0 ? i - 1 : _points.size() - 1);
final Point p2 = _points.get(i);
if (isIntersect(x, y, p1, p2))
{
intersect_count++;
}
}
return (intersect_count % 2) == 1;
}
public int[] getRandomPoint()
{
int i;
final int[] p = new int[4];
if (_proc_max > 0)
{
int pos = 0;
final int rnd = Rnd.nextInt(_proc_max);
for (i = 0; i < _points.size(); i++)
{
final Point p1 = _points.get(i);
pos += p1.proc;
if (rnd <= pos)
{
p[0] = p1.x;
p[1] = p1.y;
p[2] = p1.zmin;
p[3] = p1.zmax;
return p;
}
}
}
for (i = 0; i < 100; i++)
{
p[0] = Rnd.get(_x_min, _x_max);
p[1] = Rnd.get(_y_min, _y_max);
if (isInside(p[0], p[1]))
{
double curdistance = 0;
p[2] = _z_min + 100;
p[3] = _z_max;
for (i = 0; i < _points.size(); i++)
{
final Point p1 = _points.get(i);
final double dx = p1.x - p[0];
final double dy = p1.y - p[1];
final double distance = Math.sqrt((dx * dx) + (dy * dy));
if ((curdistance == 0) || (distance < curdistance))
{
curdistance = distance;
p[2] = p1.zmin + 100;
}
}
return p;
}
}
_log.warning("Can't make point for territory" + _terr);
return p;
}
public int getProcMax()
{
return _proc_max;
}
}

View File

@@ -0,0 +1,590 @@
/*
* 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.model;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.List;
import java.util.logging.Logger;
import com.l2jmobius.L2DatabaseFactory;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
import com.l2jmobius.gameserver.network.serverpackets.StatusUpdate;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import javolution.util.FastList;
/**
* This class ...
* @version $Revision: 1.4.2.1.2.5 $ $Date: 2005/03/27 15:29:33 $
*/
public class L2TradeList
{
private static Logger _log = Logger.getLogger(L2TradeList.class.getName());
private final List<L2ItemInstance> _items;
private final int _listId;
private boolean _confirmed;
private String _Buystorename, _Sellstorename;
private String _npcId;
public L2TradeList(int listId)
{
_items = new FastList<>();
_listId = listId;
_confirmed = false;
}
public void setNpcId(String id)
{
_npcId = id;
}
public String getNpcId()
{
return _npcId;
}
public void addItem(L2ItemInstance item)
{
_items.add(item);
}
public void replaceItem(int itemID, int price)
{
for (int i = 0; i < _items.size(); i++)
{
final L2ItemInstance item = _items.get(i);
if (item.getItemId() == itemID)
{
item.setPriceToSell(price);
}
}
}
public boolean decreaseCount(int itemID, int count)
{
for (int i = 0; i < _items.size(); i++)
{
final L2ItemInstance item = _items.get(i);
if (item.getItemId() == itemID)
{
if (item.getCount() >= count)
{
item.setCount(item.getCount() - count);
return true;
}
}
}
return false;
}
public void removeItem(int itemID)
{
for (int i = 0; i < _items.size(); i++)
{
final L2ItemInstance item = _items.get(i);
if (item.getItemId() == itemID)
{
_items.remove(i);
}
}
}
/**
* @return Returns the listId.
*/
public int getListId()
{
return _listId;
}
public void setSellStoreName(String name)
{
_Sellstorename = name;
}
public String getSellStoreName()
{
return _Sellstorename;
}
public void setBuyStoreName(String name)
{
_Buystorename = name;
}
public String getBuyStoreName()
{
return _Buystorename;
}
/**
* @return Returns the items.
*/
public List<L2ItemInstance> getItems()
{
return _items;
}
public List<L2ItemInstance> getItems(int start, int end)
{
return _items.subList(start, end);
}
public int getPriceForItemId(int itemId)
{
for (int i = 0; i < _items.size(); i++)
{
final L2ItemInstance item = _items.get(i);
if (item.getItemId() == itemId)
{
return item.getPriceToSell();
}
}
return -1;
}
public boolean countDecrease(int itemId)
{
for (int i = 0; i < _items.size(); i++)
{
final L2ItemInstance item = _items.get(i);
if (item.getItemId() == itemId)
{
return item.getCountDecrease();
}
}
return false;
}
public boolean containsItemId(int itemId)
{
for (final L2ItemInstance item : _items)
{
if (item.getItemId() == itemId)
{
return true;
}
}
return false;
}
public L2ItemInstance getItem(int ObjectId)
{
for (int i = 0; i < _items.size(); i++)
{
final L2ItemInstance item = _items.get(i);
if (item.getObjectId() == ObjectId)
{
return item;
}
}
return null;
}
public synchronized void setConfirmedTrade(boolean x)
{
_confirmed = x;
}
public synchronized boolean hasConfirmed()
{
return _confirmed;
}
public void removeItem(int objId, int count)
{
L2ItemInstance temp;
for (int y = 0; y < _items.size(); y++)
{
temp = _items.get(y);
if (temp.getObjectId() == objId)
{
if (count == temp.getCount())
{
_items.remove(temp);
}
break;
}
}
}
public boolean contains(int objId)
{
boolean bool = false;
L2ItemInstance temp;
for (int y = 0; y < _items.size(); y++)
{
temp = _items.get(y);
if (temp.getObjectId() == objId)
{
bool = true;
break;
}
}
return bool;
}
public boolean validateTrade(L2PcInstance player)
{
final Inventory playersInv = player.getInventory();
L2ItemInstance playerItem, temp;
for (int y = 0; y < _items.size(); y++)
{
temp = _items.get(y);
playerItem = playersInv.getItemByObjectId(temp.getObjectId());
if ((playerItem == null) || (playerItem.getCount() < temp.getCount()))
{
return false;
}
}
return true;
}
// Call validate before this
public void tradeItems(L2PcInstance player, L2PcInstance reciever)
{
final Inventory playersInv = player.getInventory();
final Inventory recieverInv = reciever.getInventory();
L2ItemInstance playerItem, recieverItem, temp, newitem;
InventoryUpdate update = new InventoryUpdate();
final ItemTable itemTable = ItemTable.getInstance();
for (int y = 0; y < _items.size(); y++)
{
temp = _items.get(y);
playerItem = playersInv.getItemByObjectId(temp.getObjectId());
// FIXME: why is this null??
if (playerItem == null)
{
continue;
}
newitem = itemTable.createItem("L2TradeList", playerItem.getItemId(), playerItem.getCount(), player);
newitem.setEnchantLevel(temp.getEnchantLevel());
// DIRTY FIX: Fix for trading pet collar not updating pet with new collar object id
changePetItemObjectId(playerItem.getObjectId(), newitem.getObjectId());
// Remove item from sender and add item to reciever
if (reciever.isGM() || player.isGM())
{
L2PcInstance gm;
L2PcInstance target;
if (reciever.isGM())
{
gm = reciever;
target = player;
}
else
{
gm = player;
target = reciever;
}
GMAudit.auditGMAction(gm.getName(), "trade", target.getName(), newitem.getItem().getName() + " - " + newitem.getItemId());
}
playerItem = playersInv.destroyItem("!L2TradeList!", playerItem.getObjectId(), temp.getCount(), null, null);
recieverItem = recieverInv.addItem("!L2TradeList!", newitem, null, null);
if (playerItem == null)
{
_log.warning("L2TradeList: PlayersInv.destroyItem returned NULL!");
continue;
}
if (playerItem.getLastChange() == L2ItemInstance.MODIFIED)
{
update.addModifiedItem(playerItem);
}
else
{
final L2World world = L2World.getInstance();
world.removeObject(playerItem);
update.addRemovedItem(playerItem);
}
player.sendPacket(update);
update = new InventoryUpdate();
if (recieverItem.getLastChange() == L2ItemInstance.MODIFIED)
{
update.addModifiedItem(recieverItem);
}
else
{
update.addNewItem(recieverItem);
}
reciever.sendPacket(update);
}
// weight status update both player and reciever
StatusUpdate su = new StatusUpdate(player.getObjectId());
su.addAttribute(StatusUpdate.CUR_LOAD, player.getCurrentLoad());
player.sendPacket(su);
su = new StatusUpdate(reciever.getObjectId());
su.addAttribute(StatusUpdate.CUR_LOAD, reciever.getCurrentLoad());
reciever.sendPacket(su);
}
private void changePetItemObjectId(int oldObjectId, int newObjectId)
{
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("UPDATE pets SET item_obj_id = ? WHERE item_obj_id = ?"))
{
statement.setInt(1, newObjectId);
statement.setInt(2, oldObjectId);
statement.executeUpdate();
}
catch (final Exception e)
{
_log.warning("could not change pet item object id: " + e);
}
}
public void updateBuyList(L2PcInstance player, List<TradeItem> list)
{
TradeItem temp;
int count;
final Inventory playersInv = player.getInventory();
L2ItemInstance temp2;
count = 0;
while (count != list.size())
{
temp = list.get(count);
temp2 = playersInv.getItemByItemId(temp.getItemId());
if (temp2 == null)
{
list.remove(count);
count = count - 1;
}
else
{
if (temp.getCount() == 0)
{
list.remove(count);
count = count - 1;
}
}
count++;
}
}
public void updateSellList(L2PcInstance player, List<TradeItem> list)
{
final Inventory playersInv = player.getInventory();
TradeItem temp;
L2ItemInstance temp2;
int count = 0;
while (count != list.size())
{
temp = list.get(count);
temp2 = playersInv.getItemByObjectId(temp.getObjectId());
if (temp2 == null)
{
list.remove(count);
count = count - 1;
}
else
{
if (temp2.getCount() < temp.getCount())
{
temp.setCount(temp2.getCount());
}
}
count++;
}
}
public synchronized void buySellItems(L2PcInstance buyer, List<TradeItem> buyerslist, L2PcInstance seller, List<TradeItem> sellerslist)
{
final Inventory sellerInv = seller.getInventory();
final Inventory buyerInv = buyer.getInventory();
// TradeItem buyerItem = null;
TradeItem temp2 = null;
L2ItemInstance sellerItem = null;
L2ItemInstance temp = null;
L2ItemInstance newitem = null;
L2ItemInstance adena = null;
int enchantLevel = 0;
final InventoryUpdate buyerupdate = new InventoryUpdate();
final InventoryUpdate sellerupdate = new InventoryUpdate();
final ItemTable itemTable = ItemTable.getInstance();
int amount = 0;
int x = 0;
int y = 0;
final List<SystemMessage> sysmsgs = new FastList<>();
SystemMessage msg = null;
for (final TradeItem buyerItem : buyerslist)
{
for (x = 0; x < sellerslist.size(); x++)// find in sellerslist
{
temp2 = sellerslist.get(x);
if (temp2.getItemId() == buyerItem.getItemId())
{
sellerItem = sellerInv.getItemByItemId(buyerItem.getItemId());
break;
}
}
if (sellerItem != null)
{
if ((temp2 != null) && (buyerItem.getCount() > temp2.getCount()))
{
amount = temp2.getCount();
}
if (buyerItem.getCount() > sellerItem.getCount())
{
amount = sellerItem.getCount();
}
else
{
amount = buyerItem.getCount();
}
if (buyerItem.getCount() > (Integer.MAX_VALUE / buyerItem.getOwnersPrice()))
{
_log.warning("Integer Overflow on Cost. Possible Exploit attempt between " + buyer.getName() + " and " + seller.getName() + ".");
return;
}
// int cost = amount * buyerItem.getOwnersPrice();
enchantLevel = sellerItem.getEnchantLevel();
sellerItem = sellerInv.destroyItem("", sellerItem.getObjectId(), amount, null, null);
// buyer.reduceAdena(cost);
// seller.addAdena(cost);
newitem = itemTable.createItem("L2TradeList", sellerItem.getItemId(), amount, buyer, seller);
newitem.setEnchantLevel(enchantLevel);
temp = buyerInv.addItem("", newitem, null, null);
if (amount == 1)// system msg stuff
{
msg = new SystemMessage(SystemMessage.S1_PURCHASED_S2);
msg.addString(buyer.getName());
msg.addItemName(sellerItem.getItemId());
sysmsgs.add(msg);
msg = new SystemMessage(SystemMessage.S1_PURCHASED_S2);
msg.addString("You");
msg.addItemName(sellerItem.getItemId());
sysmsgs.add(msg);
}
else
{
msg = new SystemMessage(SystemMessage.S1_PURCHASED_S3_S2_s);
msg.addString(buyer.getName());
msg.addItemName(sellerItem.getItemId());
msg.addNumber(amount);
sysmsgs.add(msg);
msg = new SystemMessage(SystemMessage.S1_PURCHASED_S3_S2_s);
msg.addString("You");
msg.addItemName(sellerItem.getItemId());
msg.addNumber(amount);
sysmsgs.add(msg);
}
if ((temp2 != null) && (temp2.getCount() == buyerItem.getCount()))
{
sellerslist.remove(temp2);
buyerItem.setCount(0);
}
else if (temp2 != null)
{
if (buyerItem.getCount() < temp2.getCount())
{
temp2.setCount(temp2.getCount() - buyerItem.getCount());
}
else
{
buyerItem.setCount(buyerItem.getCount() - temp2.getCount());
}
}
if (sellerItem.getLastChange() == L2ItemInstance.MODIFIED)
{
sellerupdate.addModifiedItem(sellerItem);
}
else
{
final L2World world = L2World.getInstance();
world.removeObject(sellerItem);
sellerupdate.addRemovedItem(sellerItem);
}
if (temp.getLastChange() == L2ItemInstance.MODIFIED)
{
buyerupdate.addModifiedItem(temp);
}
else
{
buyerupdate.addNewItem(temp);
}
// }
sellerItem = null;
}
}
if (newitem != null)
{
// updateSellList(seller,sellerslist);
adena = seller.getInventory().getAdenaInstance();
adena.setLastChange(L2ItemInstance.MODIFIED);
sellerupdate.addModifiedItem(adena);
adena = buyer.getInventory().getAdenaInstance();
adena.setLastChange(L2ItemInstance.MODIFIED);
buyerupdate.addModifiedItem(adena);
seller.sendPacket(sellerupdate);
buyer.sendPacket(buyerupdate);
y = 0;
for (x = 0; x < sysmsgs.size(); x++)
{
if (y == 0)
{
seller.sendPacket(sysmsgs.get(x));
y = 1;
}
else
{
buyer.sendPacket(sysmsgs.get(x));
y = 0;
}
}
}
}
}

View File

@@ -0,0 +1,862 @@
/*
* 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.model;
import java.util.Collection;
import java.util.Iterator;
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.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2PlayableInstance;
import com.l2jmobius.util.L2ObjectMap;
import com.l2jmobius.util.Point3D;
import javolution.util.FastList;
import javolution.util.FastMap;
/**
* This class ...
* @version $Revision: 1.21.2.5.2.7 $ $Date: 2005/03/27 15:29:32 $
*/
public final class L2World
{
private static Logger _log = Logger.getLogger(L2World.class.getName());
/*
* biteshift, defines number of regions note, shifting by 15 will result in regions corresponding to map tiles shifting by 12 divides one tile to 8x8 regions
*/
public static final int SHIFT_BY = 12;
/** Map dimensions */
public static final int MAP_MIN_X = -131072;
public static final int MAP_MAX_X = 228608;
public static final int MAP_MIN_Y = -262144;
public static final int MAP_MAX_Y = 262144;
/** calculated offset used so top left region is 0,0 */
public static final int OFFSET_X = Math.abs(MAP_MIN_X >> SHIFT_BY);
public static final int OFFSET_Y = Math.abs(MAP_MIN_Y >> SHIFT_BY);
/** number of regions */
private static final int REGIONS_X = (MAP_MAX_X >> SHIFT_BY) + OFFSET_X;
private static final int REGIONS_Y = (MAP_MAX_Y >> SHIFT_BY) + OFFSET_Y;
/** HashMap(String Player name, L2PcInstance) containing all the players in game */
private final Map<String, L2PcInstance> _allPlayers;
/** L2ObjectHashMap(L2Object) containing all visible objects */
private final L2ObjectMap<L2Object> _allObjects;
/** List with the pets instances and their owner id */
private final FastMap<Integer, L2PetInstance> _petsInstance;
private static final L2World _instance = new L2World();
private L2WorldRegion[][] _worldRegions;
/**
* Constructor of L2World.<BR>
* <BR>
*/
private L2World()
{
_allPlayers = new FastMap<String, L2PcInstance>().shared();
_petsInstance = new FastMap<Integer, L2PetInstance>().shared();
_allObjects = L2ObjectMap.createL2ObjectMap();
initRegions();
}
/**
* Return the current instance of L2World.<BR>
* <BR>
* @return
*/
public static L2World getInstance()
{
return _instance;
}
/**
* Add L2Object object in _allObjects.<BR>
* <BR>
* <B><U> Example of use </U> :</B><BR>
* <BR>
* <li>Withdraw an item from the warehouse, create an item</li>
* <li>Spawn a L2Character (PC, NPC, Pet)</li><BR>
* @param object
*/
public void storeObject(L2Object object)
{
if (_allObjects.get(object.getObjectId()) != null)
{
if (Config.DEBUG)
{
_log.warning("[L2World] objectId " + object.getObjectId() + " already exist in OID map!");
}
return;
}
_allObjects.put(object);
}
public long timeStoreObject(L2Object object)
{
long time = System.currentTimeMillis();
_allObjects.put(object);
time -= System.currentTimeMillis();
return time;
}
/**
* Remove L2Object object from _allObjects of L2World.<BR>
* <BR>
* <B><U> Example of use </U> :</B><BR>
* <BR>
* <li>Delete item from inventory, tranfer Item from inventory to warehouse</li>
* <li>Crystallize item</li>
* <li>Remove NPC/PC/Pet from the world</li><BR>
* @param object L2Object to remove from _allObjects of L2World
*/
public void removeObject(L2Object object)
{
_allObjects.remove(object); // suggestion by whatev
}
public void removeObjects(List<L2Object> list)
{
for (final L2Object o : list)
{
_allObjects.remove(o); // suggestion by whatev
}
}
public void removeObjects(L2Object[] objects)
{
for (final L2Object o : objects)
{
if (o != null)
{
_allObjects.remove(o); // suggestion by whatev
}
}
}
public long timeRemoveObject(L2Object object)
{
long time = System.currentTimeMillis();
_allObjects.remove(object);
time -= System.currentTimeMillis();
return time;
}
/**
* Return the L2Object object that belongs to an ID or null if no object found.<BR>
* <BR>
* <B><U> Example of use </U> :</B><BR>
* <BR>
* <li>Client packets : Action, AttackRequest, RequestJoinParty, RequestJoinPledge...</li><BR>
* @param oID Identifier of the L2Object
* @return
*/
public L2Object findObject(int oID)
{
return _allObjects.get(oID);
}
public long timeFindObject(int objectID)
{
long time = System.currentTimeMillis();
_allObjects.get(objectID);
time -= System.currentTimeMillis();
return time;
}
/**
* Added by Tempy - 08 Aug 05 Allows easy retrevial of all visible objects in world. -- do not use that function, its unsafe!
* @return
*/
public final L2ObjectMap<L2Object> getAllVisibleObjects()
{
return _allObjects;
}
/**
* Get the count of all visible objects in world.<br>
* <br>
* @return count off all L2World objects
*/
public final int getAllVisibleObjectsCount()
{
return _allObjects.size();
}
/**
* Return a table containing all GMs.<BR>
* <BR>
* @return
*/
public FastList<L2PcInstance> getAllGMs()
{
return GmListTable.getInstance().getAllGms(true);
}
/**
* Return a collection containing all players in game.<BR>
* <BR>
* <FONT COLOR=#FF0000><B> <U>Caution</U> : Read-only, please! </B></FONT><BR>
* <BR>
* @return
*/
public Collection<L2PcInstance> getAllPlayers()
{
return _allPlayers.values();
}
/**
* Return how many players are online.<BR>
* <BR>
* @return number of online players.
*/
public int getAllPlayersCount()
{
return _allPlayers.size();
}
/**
* Return the player instance corresponding to the given name.<BR>
* <BR>
* @param name Name of the player to get Instance
* @return
*/
public L2PcInstance getPlayer(String name)
{
if (name == null)
{
return null;
}
return _allPlayers.get(name.toLowerCase());
}
/**
* Return a collection containing all pets in game.<BR>
* <BR>
* <FONT COLOR=#FF0000><B> <U>Caution</U> : Read-only, please! </B></FONT><BR>
* <BR>
* @return
*/
public Collection<L2PetInstance> getAllPets()
{
return _petsInstance.values();
}
/**
* Return the pet instance from the given ownerId.<BR>
* <BR>
* @param ownerId ID of the owner
* @return
*/
public L2PetInstance getPet(int ownerId)
{
return _petsInstance.get(new Integer(ownerId));
}
/**
* Add the given pet instance from the given ownerId.<BR>
* <BR>
* @param ownerId ID of the owner
* @param pet L2PetInstance of the pet
* @return
*/
public L2PetInstance addPet(int ownerId, L2PetInstance pet)
{
return _petsInstance.put(new Integer(ownerId), pet);
}
/**
* Remove the given pet instance.<BR>
* <BR>
* @param ownerId ID of the owner
*/
public void removePet(int ownerId)
{
_petsInstance.remove(new Integer(ownerId));
}
/**
* Remove the given pet instance.<BR>
* <BR>
* @param pet the pet to remove
*/
public void removePet(L2PetInstance pet)
{
_petsInstance.values().remove(pet);
}
/**
* Add a L2Object in the world.<BR>
* <BR>
* <B><U> Concept</U> :</B><BR>
* <BR>
* L2Object (including L2PcInstance) are identified in <B>_visibleObjects</B> of his current L2WorldRegion and in <B>_knownObjects</B> of other surrounding L2Characters <BR>
* L2PcInstance are identified in <B>_allPlayers</B> of L2World, in <B>_allPlayers</B> of his current L2WorldRegion and in <B>_knownPlayer</B> of other surrounding L2Characters <BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Add the L2Object object in _allPlayers* of L2World</li>
* <li>Add the L2Object object in _gmList** of GmListTable</li>
* <li>Add object in _knownObjects and _knownPlayer* of all surrounding L2WorldRegion L2Characters</li><BR>
* <li>If object is a L2Character, add all surrounding L2Object in its _knownObjects and all surrounding L2PcInstance in its _knownPlayer</li><BR>
* <I>* only if object is a L2PcInstance</I><BR>
* <I>** only if object is a GM L2PcInstance</I><BR>
* <BR>
* <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T ADD the object in _visibleObjects and _allPlayers* of L2WorldRegion (need synchronisation)</B></FONT><BR>
* <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T ADD the object to _allObjects and _allPlayers* of L2World (need synchronisation)</B></FONT><BR>
* <BR>
* <B><U> Example of use </U> :</B><BR>
* <BR>
* <li>Drop an Item</li>
* <li>Spawn a L2Character</li>
* <li>Apply Death Penalty of a L2PcInstance</li><BR>
* <BR>
* @param object L2object to add in the world
* @param newRegion L2WorldRegion in wich the object will be add (not used)
* @param dropper L2Character who has dropped the object (if necessary)
*/
public void addVisibleObject(L2Object object, L2WorldRegion newRegion, L2Character dropper)
{
// If selected L2Object is a L2PcIntance, add it in L2ObjectHashSet(L2PcInstance) _allPlayers of L2World
// XXX TODO: this code should be obsoleted by protection in putObject func...
if (object instanceof L2PcInstance)
{
final L2PcInstance player = (L2PcInstance) object;
if (!player.isTeleporting())
{
final L2PcInstance tmp = _allPlayers.get(player.getName().toLowerCase());
if (tmp != null)
{
_log.warning("Duplicate character!? Closing both characters (" + player.getName() + ")");
player.logout();
tmp.logout();
return;
}
_allPlayers.put(player.getName().toLowerCase(), player);
}
}
if (!newRegion.isActive())
{
return;
}
// Get all visible objects contained in the _visibleObjects of L2WorldRegions
// in a circular area of 2000 units
final FastList<L2Object> visibles = getVisibleObjects(object, 2000);
if (Config.DEBUG)
{
_log.finest("objects in range:" + visibles.size());
}
// tell the player about the surroundings
// Go through the visible objects contained in the circular area
for (final L2Object visible : visibles)
{
if (visible == null)
{
continue;
}
// Add the object in L2ObjectHashSet(L2Object) _knownObjects of the visible L2Character according to conditions :
// - L2Character is visible
// - object is not already known
// - object is in the watch distance
// If L2Object is a L2PcInstance, add L2Object in L2ObjectHashSet(L2PcInstance) _knownPlayer of the visible L2Character
visible.getKnownList().addKnownObject(object, dropper);
// Add the visible L2Object in L2ObjectHashSet(L2Object) _knownObjects of the object according to conditions
// If visible L2Object is a L2PcInstance, add visible L2Object in L2ObjectHashSet(L2PcInstance) _knownPlayer of the object
object.getKnownList().addKnownObject(visible, dropper);
}
}
/**
* Add the L2PcInstance to _allPlayers of L2World.<BR>
* <BR>
* @param cha
*/
public void addToAllPlayers(L2PcInstance cha)
{
_allPlayers.put(cha.getName().toLowerCase(), cha);
}
/**
* Remove the L2PcInstance from _allPlayers of L2World.<BR>
* <BR>
* <B><U> Example of use </U> :</B><BR>
* <BR>
* <li>Remove a player fom the visible objects</li><BR>
* @param cha
*/
public void removeFromAllPlayers(L2PcInstance cha)
{
_allPlayers.remove(cha.getName().toLowerCase());
}
/**
* Remove a L2Object from the world.<BR>
* <BR>
* <B><U> Concept</U> :</B><BR>
* <BR>
* L2Object (including L2PcInstance) are identified in <B>_visibleObjects</B> of his current L2WorldRegion and in <B>_knownObjects</B> of other surrounding L2Characters <BR>
* L2PcInstance are identified in <B>_allPlayers</B> of L2World, in <B>_allPlayers</B> of his current L2WorldRegion and in <B>_knownPlayer</B> of other surrounding L2Characters <BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Remove the L2Object object from _allPlayers* of L2World</li>
* <li>Remove the L2Object object from _visibleObjects and _allPlayers* of L2WorldRegion</li>
* <li>Remove the L2Object object from _gmList** of GmListTable</li>
* <li>Remove object from _knownObjects and _knownPlayer* of all surrounding L2WorldRegion L2Characters</li><BR>
* <li>If object is a L2Character, remove all L2Object from its _knownObjects and all L2PcInstance from its _knownPlayer</li><BR>
* <BR>
* <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T REMOVE the object from _allObjects of L2World</B></FONT><BR>
* <BR>
* <I>* only if object is a L2PcInstance</I><BR>
* <I>** only if object is a GM L2PcInstance</I><BR>
* <BR>
* <B><U> Example of use </U> :</B><BR>
* <BR>
* <li>Pickup an Item</li>
* <li>Decay a L2Character</li><BR>
* <BR>
* @param object L2object to remove from the world
* @param oldRegion L2WorldRegion in wich the object was before removing
*/
public void removeVisibleObject(L2Object object, L2WorldRegion oldRegion)
{
if (object == null)
{
return;
}
if (oldRegion != null)
{
// Remove the object from the L2ObjectHashSet(L2Object) _visibleObjects of L2WorldRegion
// If object is a L2PcInstance, remove it from the L2ObjectHashSet(L2PcInstance) _allPlayers of this L2WorldRegion
oldRegion.removeVisibleObject(object);
// Go through all surrounding L2WorldRegion L2Characters
for (final L2WorldRegion reg : oldRegion.getSurroundingRegions())
{
for (final L2Object obj : reg.getVisibleObjects())
{
// Remove the L2Object from the L2ObjectHashSet(L2Object) _knownObjects of the surrounding L2WorldRegion L2Characters
// If object is a L2PcInstance, remove the L2Object from the L2ObjectHashSet(L2PcInstance) _knownPlayer of the surrounding L2WorldRegion L2Characters
// If object is targeted by one of the surrounding L2WorldRegion L2Characters, cancel ATTACK and cast
if (obj.getKnownList() != null)
{
obj.getKnownList().removeKnownObject(object);
}
// Remove surrounding L2WorldRegion L2Characters from the L2ObjectHashSet(L2Object) _KnownObjects of object
// If surrounding L2WorldRegion L2Characters is a L2PcInstance, remove it from the L2ObjectHashSet(L2PcInstance) _knownPlayer of object
// TODO Delete this line if all the stuff is done by the next line object.removeAllKnownObjects()
if (object.getKnownList() != null)
{
object.getKnownList().removeKnownObject(obj);
}
}
}
// If object is a L2Character :
// Remove all L2Object from L2ObjectHashSet(L2Object) containing all L2Object detected by the L2Character
// Remove all L2PcInstance from L2ObjectHashSet(L2PcInstance) containing all player ingame detected by the L2Character
object.getKnownList().removeAllKnownObjects();
// If selected L2Object is a L2PcIntance, remove it from L2ObjectHashSet(L2PcInstance) _allPlayers of L2World
if (object instanceof L2PcInstance)
{
if (!((L2PcInstance) object).isTeleporting())
{
removeFromAllPlayers((L2PcInstance) object);
}
}
}
}
/**
* Return all visible objects of the L2WorldRegion object's and of its surrounding L2WorldRegion.<BR>
* <BR>
* <B><U> Concept</U> :</B><BR>
* <BR>
* All visible object are identified in <B>_visibleObjects</B> of their current L2WorldRegion <BR>
* All surrounding L2WorldRegion are identified in <B>_surroundingRegions</B> of the selected L2WorldRegion in order to scan a large area around a L2Object<BR>
* <BR>
* <B><U> Example of use </U> :</B><BR>
* <BR>
* <li>Find Close Objects for L2Character</li><BR>
* @param object L2object that determine the current L2WorldRegion
* @return
*/
public FastList<L2Object> getVisibleObjects(L2Object object)
{
final L2WorldRegion reg = object.getWorldRegion();
if (reg == null)
{
return null;
}
// Create an FastList in order to contain all visible L2Object
final FastList<L2Object> result = new FastList<>();
// Create a FastList containing all regions around the current region
final FastList<L2WorldRegion> _regions = reg.getSurroundingRegions();
// Go through the FastList of region
for (int i = 0; i < _regions.size(); i++)
{
// Go through visible objects of the selected region
for (final L2Object _object : _regions.get(i).getVisibleObjects())
{
if (_object.equals(object))
{
continue; // skip our own character
}
if (!_object.isVisible())
{
continue; // skip dying objects
}
result.add(_object);
}
}
return result;
}
/**
* Return all visible objects of the L2WorldRegions in the circular area (radius) centered on the object.<BR>
* <BR>
* <B><U> Concept</U> :</B><BR>
* <BR>
* All visible object are identified in <B>_visibleObjects</B> of their current L2WorldRegion <BR>
* All surrounding L2WorldRegion are identified in <B>_surroundingRegions</B> of the selected L2WorldRegion in order to scan a large area around a L2Object<BR>
* <BR>
* <B><U> Example of use </U> :</B><BR>
* <BR>
* <li>Define the aggrolist of monster</li>
* <li>Define visible objects of a L2Object</li>
* <li>Skill : Confusion...</li><BR>
* @param object L2object that determine the center of the circular area
* @param radius Radius of the circular area
* @return
*/
public FastList<L2Object> getVisibleObjects(L2Object object, int radius)
{
if ((object == null) || !object.isVisible())
{
return new FastList<>();
}
final int x = object.getX();
final int y = object.getY();
final int sqRadius = radius * radius;
// Create an FastList in order to contain all visible L2Object
final FastList<L2Object> result = new FastList<>();
// Create an FastList containing all regions around the current region
final FastList<L2WorldRegion> _regions = object.getWorldRegion().getSurroundingRegions();
// Go through the FastList of region
for (int i = 0; i < _regions.size(); i++)
{
// Go through visible objects of the selected region
for (final L2Object _object : _regions.get(i).getVisibleObjects())
{
if ((_object == null) || _object.equals(object))
{
continue; // skip null or our own character
}
final int x1 = _object.getX();
final int y1 = _object.getY();
final double dx = x1 - x;
// if (dx > radius || -dx > radius)
// continue;
final double dy = y1 - y;
// if (dy > radius || -dy > radius)
// continue;
// If the visible object is inside the circular area
// add the object to the FastList result
if (((dx * dx) + (dy * dy)) < sqRadius)
{
result.add(_object);
}
}
}
return result;
}
/**
* Return all visible objects of the L2WorldRegions in the spheric area (radius) centered on the object.<BR>
* <BR>
* <B><U> Concept</U> :</B><BR>
* <BR>
* All visible object are identified in <B>_visibleObjects</B> of their current L2WorldRegion <BR>
* All surrounding L2WorldRegion are identified in <B>_surroundingRegions</B> of the selected L2WorldRegion in order to scan a large area around a L2Object<BR>
* <BR>
* <B><U> Example of use </U> :</B><BR>
* <BR>
* <li>Define the target list of a skill</li>
* <li>Define the target list of a polearme attack</li><BR>
* <BR>
* @param object L2object that determine the center of the circular area
* @param radius Radius of the spheric area
* @return
*/
public FastList<L2Object> getVisibleObjects3D(L2Object object, int radius)
{
if ((object == null) || !object.isVisible())
{
return new FastList<>();
}
final int x = object.getX();
final int y = object.getY();
final int z = object.getZ();
final int sqRadius = radius * radius;
// Create an FastList in order to contain all visible L2Object
final FastList<L2Object> result = new FastList<>();
// Create an FastList containing all regions around the current region
final FastList<L2WorldRegion> _regions = object.getWorldRegion().getSurroundingRegions();
// Go through visible object of the selected region
for (int i = 0; i < _regions.size(); i++)
{
for (final L2Object _object : _regions.get(i).getVisibleObjects())
{
if (_object.equals(object))
{
continue; // skip our own character
}
final int x1 = _object.getX();
final int y1 = _object.getY();
final int z1 = _object.getZ();
final long dx = x1 - x;
// if (dx > radius || -dx > radius)
// continue;
final long dy = y1 - y;
// if (dy > radius || -dy > radius)
// continue;
final long dz = z1 - z;
if (((dx * dx) + (dy * dy) + (dz * dz)) < sqRadius)
{
result.add(_object);
}
}
}
return result;
}
/**
* Return all visible players of the L2WorldRegion object's and of its surrounding L2WorldRegion.<BR>
* <BR>
* <B><U> Concept</U> :</B><BR>
* <BR>
* All visible object are identified in <B>_visibleObjects</B> of their current L2WorldRegion <BR>
* All surrounding L2WorldRegion are identified in <B>_surroundingRegions</B> of the selected L2WorldRegion in order to scan a large area around a L2Object<BR>
* <BR>
* <B><U> Example of use </U> :</B><BR>
* <BR>
* <li>Find Close Objects for L2Character</li><BR>
* @param object L2object that determine the current L2WorldRegion
* @return
*/
public FastList<L2PlayableInstance> getVisiblePlayable(L2Object object)
{
final L2WorldRegion reg = object.getWorldRegion();
if (reg == null)
{
return null;
}
// Create an FastList in order to contain all visible L2Object
final FastList<L2PlayableInstance> result = new FastList<>();
// Create a FastList containing all regions around the current region
final FastList<L2WorldRegion> _regions = reg.getSurroundingRegions();
// Go through the FastList of region
for (int i = 0; i < _regions.size(); i++)
{
// Create an Iterator to go through the visible L2Object of the L2WorldRegion
final Iterator<L2PlayableInstance> _playables = _regions.get(i).iterateAllPlayers();
// Go through visible object of the selected region
while (_playables.hasNext())
{
final L2PlayableInstance _object = _playables.next();
if (_object == null)
{
continue;
}
if (_object.equals(object))
{
continue; // skip our own character
}
if (!_object.isVisible())
{
continue; // skip dying objects
}
result.add(_object);
}
}
return result;
}
/**
* Calculate the current L2WorldRegions of the object according to its position (x,y).<BR>
* <BR>
* <B><U> Example of use </U> :</B><BR>
* <BR>
* <li>Set position of a new L2Object (drop, spawn...)</li>
* <li>Update position of a L2Object after a movement</li><BR>
* @param point
* @return
*/
public L2WorldRegion getRegion(Point3D point)
{
return _worldRegions[(point.getX() >> SHIFT_BY) + OFFSET_X][(point.getY() >> SHIFT_BY) + OFFSET_Y];
}
public L2WorldRegion getRegion(int x, int y)
{
return _worldRegions[(x >> SHIFT_BY) + OFFSET_X][(y >> SHIFT_BY) + OFFSET_Y];
}
public L2WorldRegion[][] getAllWorldRegions()
{
return _worldRegions;
}
/**
* Check if the current L2WorldRegions of the object is valid according to its position (x,y).<BR>
* <BR>
* <B><U> Example of use </U> :</B><BR>
* <BR>
* <li>Init L2WorldRegions</li><BR>
* @param x X position of the object
* @param y Y position of the object
* @return True if the L2WorldRegion is valid
*/
private boolean validRegion(int x, int y)
{
return ((x >= 0) && (x <= REGIONS_X) && (y >= 0) && (y <= REGIONS_Y));
}
/**
* Init each L2WorldRegion and their surrounding table.<BR>
* <BR>
* <B><U> Concept</U> :</B><BR>
* <BR>
* All surrounding L2WorldRegion are identified in <B>_surroundingRegions</B> of the selected L2WorldRegion in order to scan a large area around a L2Object<BR>
* <BR>
* <B><U> Example of use </U> :</B><BR>
* <BR>
* <li>Constructor of L2World</li><BR>
*/
private void initRegions()
{
_log.config("L2World: Setting up World Regions");
_worldRegions = new L2WorldRegion[REGIONS_X + 1][REGIONS_Y + 1];
for (int i = 0; i <= REGIONS_X; i++)
{
for (int j = 0; j <= REGIONS_Y; j++)
{
_worldRegions[i][j] = new L2WorldRegion(i, j);
}
}
for (int x = 0; x <= REGIONS_X; x++)
{
for (int y = 0; y <= REGIONS_Y; y++)
{
for (int a = -1; a <= 1; a++)
{
for (int b = -1; b <= 1; b++)
{
if (validRegion(x + a, y + b))
{
_worldRegions[x + a][y + b].addSurroundingRegion(_worldRegions[x][y]);
}
}
}
}
}
_log.config("L2World: (" + REGIONS_X + " by " + REGIONS_Y + ") World Region Grid set up.");
}
/**
* Deleted all spawns in the world.
*/
public synchronized void deleteVisibleNpcSpawns()
{
_log.info("Deleting all visible NPC's.");
for (int i = 0; i <= REGIONS_X; i++)
{
for (int j = 0; j <= REGIONS_Y; j++)
{
_worldRegions[i][j].deleteVisibleNpcSpawns();
}
}
_log.info("All visible NPC's deleted.");
}
}

View File

@@ -0,0 +1,441 @@
/*
* 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.model;
import java.util.Iterator;
import java.util.concurrent.ScheduledFuture;
import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.ai.L2AttackableAI;
import com.l2jmobius.gameserver.datatables.SpawnTable;
import com.l2jmobius.gameserver.model.actor.instance.L2NpcInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2PlayableInstance;
import com.l2jmobius.gameserver.model.zone.L2ZoneType;
import com.l2jmobius.util.L2ObjectSet;
import javolution.util.FastList;
/**
* This class ...
* @version $Revision: 1.3.4.4 $ $Date: 2005/03/27 15:29:33 $
*/
public final class L2WorldRegion
{
private static Logger _log = Logger.getLogger(L2WorldRegion.class.getName());
/** L2ObjectHashSet(L2PlayableInstance) containing L2PlayableInstance of all player & summon in game in this L2WorldRegion */
private final L2ObjectSet<L2PlayableInstance> _allPlayable;
/** L2ObjectHashSet(L2Object) containing L2Object visible in this L2WorldRegion */
private final L2ObjectSet<L2Object> _visibleObjects;
private final FastList<L2WorldRegion> _surroundingRegions;
private final int tileX, tileY;
private Boolean _active = false;
private ScheduledFuture<?> _neighborsTask = null;
private final FastList<L2ZoneType> _zones;
public L2WorldRegion(int pTileX, int pTileY)
{
_allPlayable = L2ObjectSet.createL2PlayerSet(); // new L2ObjectHashSet<L2PlayableInstance>();
_visibleObjects = L2ObjectSet.createL2ObjectSet(); // new L2ObjectHashSet<L2Object>();
_surroundingRegions = new FastList<>();
tileX = pTileX;
tileY = pTileY;
// default a newly initialized region to inactive, unless always on is specified
if (Config.GRIDS_ALWAYS_ON)
{
_active = true;
}
else
{
_active = false;
}
_zones = new FastList<>();
}
public FastList<L2ZoneType> getZones()
{
return _zones;
}
public void addZone(L2ZoneType zone)
{
_zones.add(zone);
}
public void removeZone(L2ZoneType zone)
{
_zones.remove(zone);
}
public void revalidateZones(L2Character character)
{
for (final L2ZoneType z : getZones())
{
if (z != null)
{
z.revalidateInZone(character);
}
}
}
public void removeFromZones(L2Character character)
{
for (final L2ZoneType z : getZones())
{
if (z != null)
{
z.removeCharacter(character);
}
}
}
/** Task of AI notification */
public class NeighborsTask implements Runnable
{
private final boolean _isActivating;
public NeighborsTask(boolean isActivating)
{
_isActivating = isActivating;
}
@Override
public void run()
{
if (_isActivating)
{
// for each neighbor, if it's not active, activate.
for (final L2WorldRegion neighbor : getSurroundingRegions())
{
neighbor.setActive(true);
}
}
else
{
if (areNeighborsEmpty())
{
setActive(false);
}
// check and deactivate
for (final L2WorldRegion neighbor : getSurroundingRegions())
{
if (neighbor.areNeighborsEmpty())
{
neighbor.setActive(false);
}
}
}
}
}
private void switchAI(Boolean isOn)
{
int c = 0;
if (!isOn)
{
for (final L2Object o : _visibleObjects)
{
if (o instanceof L2Attackable)
{
c++;
final L2Attackable mob = (L2Attackable) o;
// Set target to null and cancel Attack or Cast
mob.setTarget(null);
// Stop movement
mob.stopMove(null);
// Stop all active skills effects in progress on the L2Character
mob.stopAllEffects();
mob.clearAggroList();
mob.getAttackByList().clear();
mob.getKnownList().removeAllKnownObjects();
mob.getAI().setIntention(com.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE);
// stop the ai tasks
((L2AttackableAI) mob.getAI()).stopAITask();
// Stop HP/MP/CP Regeneration task
// try this: allow regen, but only until mob is 100% full...then stop
// it until the grid is made active.
// mob.getStatus().stopHpMpRegeneration();
}
}
_log.fine(c + " mobs were turned off");
}
else
{
for (final L2Object o : _visibleObjects)
{
if (o instanceof L2Attackable)
{
c++;
// Start HP/MP/CP Regeneration task
((L2Attackable) o).getStatus().startHpMpRegeneration();
// start the ai
// ((L2AttackableAI) mob.getAI()).startAITask();
}
else if (o instanceof L2NpcInstance)
{
// Create a RandomAnimation Task that will be launched after the calculated delay if the server allow it
// L2Monsterinstance/L2Attackable socials are handled by AI (TODO: check the instances)
((L2NpcInstance) o).startRandomAnimationTimer();
}
}
_log.fine(c + " mobs were turned on");
}
}
public boolean isActive()
{
return _active;
}
// check if all 9 neighbors (including self) are inactive or active but with no players.
// returns true if the above condition is met.
public boolean areNeighborsEmpty()
{
// if this region is occupied, return false.
if (isActive() && (_allPlayable.size() > 0))
{
return false;
}
// if any one of the neighbors is occupied, return false
for (final L2WorldRegion neighbor : _surroundingRegions)
{
if (neighbor.isActive() && (neighbor._allPlayable.size() > 0))
{
return false;
}
}
// in all other cases, return true.
return true;
}
/**
* this function turns this region's AI and geodata on or off
* @param value
*/
public void setActive(boolean value)
{
if (_active == value)
{
return;
}
_active = value;
// turn the AI on or off to match the region's activation.
switchAI(value);
// TODO
// turn the geodata on or off to match the region's activation.
if (value)
{
_log.fine("Starting Grid " + tileX + "," + tileY);
}
else
{
_log.fine("Stoping Grid " + tileX + "," + tileY);
}
}
/**
* Immediately sets self as active and starts a timer to set neighbors as active this timer is to avoid turning on neighbors in the case when a person just teleported into a region and then teleported out immediately...there is no reason to activate all the neighbors in that case.
*/
private void startActivation()
{
// first set self to active and do self-tasks...
setActive(true);
// if the timer to deactivate neighbors is running, cancel it.
synchronized (this)
{
if (_neighborsTask != null)
{
_neighborsTask.cancel(true);
_neighborsTask = null;
}
// then, set a timer to activate the neighbors
_neighborsTask = ThreadPoolManager.getInstance().scheduleGeneral(new NeighborsTask(true), 1000 * Config.GRID_NEIGHBOR_TURNON_TIME);
}
}
/**
* starts a timer to set neighbors (including self) as inactive this timer is to avoid turning off neighbors in the case when a person just moved out of a region that he may very soon return to. There is no reason to turn self & neighbors off in that case.
*/
private void startDeactivation()
{
// if the timer to activate neighbors is running, cancel it.
synchronized (this)
{
if (_neighborsTask != null)
{
_neighborsTask.cancel(true);
_neighborsTask = null;
}
// start a timer to "suggest" a deactivate to self and neighbors.
// suggest means: first check if a neighbor has L2PcInstances in it. If not, deactivate.
_neighborsTask = ThreadPoolManager.getInstance().scheduleGeneral(new NeighborsTask(false), 1000 * Config.GRID_NEIGHBOR_TURNOFF_TIME);
}
}
/**
* Add the L2Object in the L2ObjectHashSet(L2Object) _visibleObjects containing L2Object visible in this L2WorldRegion <BR>
* If L2Object is a L2PcInstance, Add the L2PcInstance in the L2ObjectHashSet(L2PcInstance) _allPlayable containing L2PcInstance of all player in game in this L2WorldRegion <BR>
* Assert : object.getCurrentWorldRegion() == this
* @param object
*/
public void addVisibleObject(L2Object object)
{
if (Config.ASSERT)
{
assert object.getWorldRegion() == this;
}
if (object == null)
{
return;
}
_visibleObjects.put(object);
if (object instanceof L2PlayableInstance)
{
_allPlayable.put((L2PlayableInstance) object);
// if this is the first player to enter the region, activate self & neighbors
if ((_allPlayable.size() == 1) && (!Config.GRIDS_ALWAYS_ON))
{
startActivation();
}
}
}
/**
* Remove the L2Object from the L2ObjectHashSet(L2Object) _visibleObjects in this L2WorldRegion <BR>
* <BR>
* If L2Object is a L2PcInstance, remove it from the L2ObjectHashSet(L2PcInstance) _allPlayable of this L2WorldRegion <BR>
* Assert : object.getCurrentWorldRegion() == this || object.getCurrentWorldRegion() == null
* @param object
*/
public void removeVisibleObject(L2Object object)
{
if (Config.ASSERT)
{
assert (object.getWorldRegion() == this) || (object.getWorldRegion() == null);
}
if (object == null)
{
return;
}
_visibleObjects.remove(object);
if (object instanceof L2PlayableInstance)
{
_allPlayable.remove((L2PlayableInstance) object);
if ((_allPlayable.size() == 0) && (!Config.GRIDS_ALWAYS_ON))
{
startDeactivation();
}
}
}
public void addSurroundingRegion(L2WorldRegion region)
{
_surroundingRegions.add(region);
}
/**
* Return the FastList _surroundingRegions containing all L2WorldRegion around the current L2WorldRegion
* @return
*/
public FastList<L2WorldRegion> getSurroundingRegions()
{
// change to return L2WorldRegion[] ?
// this should not change after initialization, so maybe changes are not necessary
return _surroundingRegions;
}
public Iterator<L2PlayableInstance> iterateAllPlayers()
{
return _allPlayable.iterator();
}
public L2ObjectSet<L2Object> getVisibleObjects()
{
return _visibleObjects;
}
public L2ObjectSet<L2PlayableInstance> getVisiblePlayable()
{
return _allPlayable;
}
public String getName()
{
return "(" + tileX + ", " + tileY + ")";
}
/**
* Deleted all spawns in the world.
*/
public synchronized void deleteVisibleNpcSpawns()
{
_log.fine("Deleting all visible NPC's in Region: " + getName());
for (final L2Object obj : _visibleObjects)
{
if (obj instanceof L2NpcInstance)
{
final L2NpcInstance target = (L2NpcInstance) obj;
target.deleteMe();
final L2Spawn spawn = target.getSpawn();
if (spawn != null)
{
spawn.stopRespawn();
SpawnTable.getInstance().deleteSpawn(spawn, false);
}
_log.finest("Removed NPC " + target.getObjectId());
}
}
_log.info("All visible NPC's deleted in Region: " + getName());
}
}

View File

@@ -0,0 +1,64 @@
/*
* 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.model;
/**
* This class ...
* @version $Revision: 1.1.4.1 $ $Date: 2005/03/27 15:29:33 $
*/
public final class Location
{
private final int _x;
private final int _y;
private final int _z;
private int _heading;
public Location(int x, int y, int z)
{
_x = x;
_y = y;
_z = z;
}
public Location(int x, int y, int z, int heading)
{
_x = x;
_y = y;
_z = z;
_heading = heading;
}
public int getX()
{
return _x;
}
public int getY()
{
return _y;
}
public int getZ()
{
return _z;
}
public int getHeading()
{
return _heading;
}
}

View File

@@ -0,0 +1,236 @@
/*
* 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.model;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jmobius.L2DatabaseFactory;
import com.l2jmobius.gameserver.model.L2Macro.L2MacroCmd;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.serverpackets.SendMacroList;
import javolution.text.TextBuilder;
import javolution.util.FastList;
import javolution.util.FastMap;
/**
* This class ...
* @version $Revision: 1.1.2.1.2.2 $ $Date: 2005/03/02 15:38:41 $
*/
public class MacroList
{
private static Logger _log = Logger.getLogger(MacroList.class.getName());
private final L2PcInstance _owner;
private int _revision;
private int _macroId;
private final Map<Integer, L2Macro> _macroses = new FastMap<>();
public MacroList(L2PcInstance owner)
{
_owner = owner;
_revision = 1;
_macroId = 1000;
}
public int getRevision()
{
return _revision;
}
public L2Macro[] getAllMacroses()
{
return _macroses.values().toArray(new L2Macro[_macroses.size()]);
}
public L2Macro getMacro(int id)
{
return _macroses.get(id - 1);
}
public void registerMacro(L2Macro macro)
{
if (macro.id == 0)
{
macro.id = _macroId++;
while (_macroses.get(macro.id) != null)
{
macro.id = _macroId++;
}
_macroses.put(macro.id, macro);
registerMacroInDb(macro);
}
else
{
final L2Macro old = _macroses.put(macro.id, macro);
if (old != null)
{
deleteMacroFromDb(old);
}
registerMacroInDb(macro);
}
sendUpdate();
}
public void deleteMacro(int id)
{
final L2Macro toRemove = _macroses.get(id);
if (toRemove != null)
{
deleteMacroFromDb(toRemove);
}
_macroses.remove(id);
for (final L2ShortCut sc : _owner.getAllShortCuts())
{
if (sc == null)
{
continue;
}
if ((sc.getId() == id) && (sc.getType() == L2ShortCut.TYPE_MACRO))
{
_owner.deleteShortCut(sc.getSlot(), sc.getPage());
}
}
sendUpdate();
}
public void sendUpdate()
{
_revision++;
final L2Macro[] all = getAllMacroses();
if (all.length == 0)
{
_owner.sendPacket(new SendMacroList(_revision, all.length, null));
}
else
{
for (final L2Macro m : all)
{
_owner.sendPacket(new SendMacroList(_revision, all.length, m));
}
}
}
private void registerMacroInDb(L2Macro macro)
{
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("INSERT INTO character_macroses (char_obj_id,id,icon,name,descr,acronym,commands) values(?,?,?,?,?,?,?)"))
{
statement.setInt(1, _owner.getObjectId());
statement.setInt(2, macro.id);
statement.setInt(3, macro.icon);
statement.setString(4, macro.name);
statement.setString(5, macro.descr);
statement.setString(6, macro.acronym);
final TextBuilder sb = new TextBuilder();
for (final L2MacroCmd cmd : macro.commands)
{
sb.append(cmd.type).append(',');
sb.append(cmd.d1).append(',');
sb.append(cmd.d2);
if ((cmd.cmd != null) && (cmd.cmd.length() > 0))
{
sb.append(',').append(cmd.cmd);
}
sb.append(';');
}
statement.setString(7, sb.toString());
statement.execute();
}
catch (final Exception e)
{
_log.log(Level.WARNING, "could not store macro:", e);
}
}
/**
* @param macro
*/
private void deleteMacroFromDb(L2Macro macro)
{
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("DELETE FROM character_macroses WHERE char_obj_id=? AND id=?"))
{
statement.setInt(1, _owner.getObjectId());
statement.setInt(2, macro.id);
statement.execute();
}
catch (final Exception e)
{
_log.log(Level.WARNING, "could not delete macro:", e);
}
}
public void restore()
{
_macroses.clear();
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("SELECT char_obj_id, id, icon, name, descr, acronym, commands FROM character_macroses WHERE char_obj_id=?"))
{
statement.setInt(1, _owner.getObjectId());
try (ResultSet rset = statement.executeQuery())
{
while (rset.next())
{
final int id = rset.getInt("id");
final int icon = rset.getInt("icon");
final String name = rset.getString("name");
final String descr = rset.getString("descr");
final String acronym = rset.getString("acronym");
final List<L2MacroCmd> commands = new FastList<>();
final StringTokenizer st1 = new StringTokenizer(rset.getString("commands"), ";");
while (st1.hasMoreTokens())
{
final StringTokenizer st = new StringTokenizer(st1.nextToken(), ",");
if (st.countTokens() < 3)
{
continue;
}
final int type = Integer.parseInt(st.nextToken());
final int d1 = Integer.parseInt(st.nextToken());
final int d2 = Integer.parseInt(st.nextToken());
String cmd = "";
if (st.hasMoreTokens())
{
cmd = st.nextToken();
}
final L2MacroCmd mcmd = new L2MacroCmd(commands.size(), type, d1, d2, cmd);
commands.add(mcmd);
}
final L2Macro m = new L2Macro(id, icon, name, descr, acronym, commands.toArray(new L2MacroCmd[commands.size()]));
_macroses.put(m.id, m);
}
}
}
catch (final Exception e)
{
_log.log(Level.WARNING, "could not store shortcuts:", e);
}
}
}

View File

@@ -0,0 +1,413 @@
/*
* 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.model;
import java.util.List;
import com.l2jmobius.gameserver.ai.CtrlIntention;
import com.l2jmobius.gameserver.ai.L2ControllableMobAI;
import com.l2jmobius.gameserver.datatables.SpawnTable;
import com.l2jmobius.gameserver.model.actor.instance.L2ControllableMobInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.templates.L2NpcTemplate;
import com.l2jmobius.util.Rnd;
import javolution.util.FastList;
/**
* @author littlecrow
*/
public final class MobGroup
{
private final L2NpcTemplate _npcTemplate;
private final int _groupId;
private final int _maxMobCount;
private List<L2ControllableMobInstance> _mobs;
public MobGroup(int groupId, L2NpcTemplate npcTemplate, int maxMobCount)
{
_groupId = groupId;
_npcTemplate = npcTemplate;
_maxMobCount = maxMobCount;
}
public int getActiveMobCount()
{
return getMobs().size();
}
public int getGroupId()
{
return _groupId;
}
public int getMaxMobCount()
{
return _maxMobCount;
}
public List<L2ControllableMobInstance> getMobs()
{
if (_mobs == null)
{
_mobs = new FastList<>();
}
return _mobs;
}
public String getStatus()
{
try
{
final L2ControllableMobAI mobGroupAI = (L2ControllableMobAI) getMobs().get(0).getAI();
switch (mobGroupAI.getAlternateAI())
{
case L2ControllableMobAI.AI_NORMAL:
return "Idle";
case L2ControllableMobAI.AI_FORCEATTACK:
return "Force Attacking";
case L2ControllableMobAI.AI_FOLLOW:
return "Following";
case L2ControllableMobAI.AI_CAST:
return "Casting";
case L2ControllableMobAI.AI_ATTACK_GROUP:
return "Attacking Group";
default:
return "Idle";
}
}
catch (final Exception e)
{
return "Unspawned";
}
}
public L2NpcTemplate getTemplate()
{
return _npcTemplate;
}
public boolean isGroupMember(L2ControllableMobInstance mobInst)
{
for (final L2ControllableMobInstance groupMember : getMobs())
{
if (groupMember == null)
{
continue;
}
if (groupMember.getObjectId() == mobInst.getObjectId())
{
return true;
}
}
return false;
}
public void spawnGroup(int x, int y, int z)
{
if (getActiveMobCount() > 0)
{
return;
}
try
{
for (int i = 0; i < getMaxMobCount(); i++)
{
final L2GroupSpawn spawn = new L2GroupSpawn(getTemplate());
final int signX = (Rnd.nextInt(2) == 0) ? -1 : 1;
final int signY = (Rnd.nextInt(2) == 0) ? -1 : 1;
final int randX = Rnd.nextInt(MobGroupTable.RANDOM_RANGE);
final int randY = Rnd.nextInt(MobGroupTable.RANDOM_RANGE);
spawn.setLocx(x + (signX * randX));
spawn.setLocy(y + (signY * randY));
spawn.setLocz(z);
spawn.stopRespawn();
SpawnTable.getInstance().addNewSpawn(spawn, false);
getMobs().add((L2ControllableMobInstance) spawn.doGroupSpawn());
}
}
catch (final ClassNotFoundException e)
{
}
catch (final NoSuchMethodException e2)
{
}
}
public void spawnGroup(L2PcInstance activeChar)
{
spawnGroup(activeChar.getX(), activeChar.getY(), activeChar.getZ());
}
public void teleportGroup(L2PcInstance player)
{
removeDead();
for (final L2ControllableMobInstance mobInst : getMobs())
{
if (mobInst == null)
{
continue;
}
if (!mobInst.isDead())
{
final int x = player.getX() + Rnd.nextInt(50);
final int y = player.getY() + Rnd.nextInt(50);
mobInst.teleToLocation(x, y, player.getZ(), true);
final L2ControllableMobAI ai = (L2ControllableMobAI) mobInst.getAI();
ai.follow(player);
}
}
}
public L2ControllableMobInstance getRandomMob()
{
removeDead();
if (getActiveMobCount() == 0)
{
return null;
}
final int choice = Rnd.nextInt(getActiveMobCount());
return getMobs().get(choice);
}
public void unspawnGroup()
{
removeDead();
if (getActiveMobCount() == 0)
{
return;
}
for (final L2ControllableMobInstance mobInst : getMobs())
{
if (mobInst == null)
{
continue;
}
if (!mobInst.isDead())
{
mobInst.deleteMe();
}
SpawnTable.getInstance().deleteSpawn(mobInst.getSpawn(), false);
}
getMobs().clear();
}
public void killGroup(L2PcInstance activeChar)
{
removeDead();
for (final L2ControllableMobInstance mobInst : getMobs())
{
if (mobInst == null)
{
continue;
}
if (!mobInst.isDead())
{
mobInst.reduceCurrentHp(mobInst.getMaxHp() + 1, activeChar);
}
SpawnTable.getInstance().deleteSpawn(mobInst.getSpawn(), false);
}
getMobs().clear();
}
public void setAttackRandom()
{
removeDead();
for (final L2ControllableMobInstance mobInst : getMobs())
{
if (mobInst == null)
{
continue;
}
final L2ControllableMobAI ai = (L2ControllableMobAI) mobInst.getAI();
ai.setAlternateAI(L2ControllableMobAI.AI_NORMAL);
ai.setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
}
}
public void setAttackTarget(L2Character target)
{
removeDead();
for (final L2ControllableMobInstance mobInst : getMobs())
{
if (mobInst == null)
{
continue;
}
final L2ControllableMobAI ai = (L2ControllableMobAI) mobInst.getAI();
ai.forceAttack(target);
}
}
public void setIdleMode()
{
removeDead();
for (final L2ControllableMobInstance mobInst : getMobs())
{
if (mobInst == null)
{
continue;
}
final L2ControllableMobAI ai = (L2ControllableMobAI) mobInst.getAI();
ai.stop();
}
}
public void returnGroup(L2Character activeChar)
{
setIdleMode();
for (final L2ControllableMobInstance mobInst : getMobs())
{
if (mobInst == null)
{
continue;
}
final int signX = (Rnd.nextInt(2) == 0) ? -1 : 1;
final int signY = (Rnd.nextInt(2) == 0) ? -1 : 1;
final int randX = Rnd.nextInt(MobGroupTable.RANDOM_RANGE);
final int randY = Rnd.nextInt(MobGroupTable.RANDOM_RANGE);
final L2ControllableMobAI ai = (L2ControllableMobAI) mobInst.getAI();
ai.move(activeChar.getX() + (signX * randX), activeChar.getY() + (signY * randY), activeChar.getZ());
}
}
public void setFollowMode(L2Character character)
{
removeDead();
for (final L2ControllableMobInstance mobInst : getMobs())
{
if (mobInst == null)
{
continue;
}
final L2ControllableMobAI ai = (L2ControllableMobAI) mobInst.getAI();
ai.follow(character);
}
}
public void setCastMode()
{
removeDead();
for (final L2ControllableMobInstance mobInst : getMobs())
{
if (mobInst == null)
{
continue;
}
final L2ControllableMobAI ai = (L2ControllableMobAI) mobInst.getAI();
ai.setAlternateAI(L2ControllableMobAI.AI_CAST);
}
}
public void setNoMoveMode(boolean enabled)
{
removeDead();
for (final L2ControllableMobInstance mobInst : getMobs())
{
if (mobInst == null)
{
continue;
}
final L2ControllableMobAI ai = (L2ControllableMobAI) mobInst.getAI();
ai.setNotMoving(enabled);
}
}
protected void removeDead()
{
final List<L2ControllableMobInstance> deadMobs = new FastList<>();
for (final L2ControllableMobInstance mobInst : getMobs())
{
if ((mobInst != null) && mobInst.isDead())
{
deadMobs.add(mobInst);
}
}
getMobs().removeAll(deadMobs);
}
public void setInvul(boolean invulState)
{
removeDead();
for (final L2ControllableMobInstance mobInst : getMobs())
{
if (mobInst != null)
{
mobInst.setInvul(invulState);
}
}
}
public void setAttackGroup(MobGroup otherGrp)
{
removeDead();
for (final L2ControllableMobInstance mobInst : getMobs())
{
if (mobInst == null)
{
continue;
}
final L2ControllableMobAI ai = (L2ControllableMobAI) mobInst.getAI();
ai.forceAttackGroup(otherGrp);
ai.setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
}
}
}

View File

@@ -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.model;
import java.util.Map;
import com.l2jmobius.gameserver.model.actor.instance.L2ControllableMobInstance;
import javolution.util.FastMap;
/**
* @author littlecrow
*/
public class MobGroupTable
{
private static MobGroupTable _instance;
private final Map<Integer, MobGroup> _groupMap;
public static final int FOLLOW_RANGE = 300;
public static final int RANDOM_RANGE = 300;
public MobGroupTable()
{
_groupMap = new FastMap<>();
}
public static MobGroupTable getInstance()
{
if (_instance == null)
{
_instance = new MobGroupTable();
}
return _instance;
}
public void addGroup(int groupKey, MobGroup group)
{
_groupMap.put(groupKey, group);
}
public MobGroup getGroup(int groupKey)
{
return _groupMap.get(groupKey);
}
public int getGroupCount()
{
return _groupMap.size();
}
public MobGroup getGroupForMob(L2ControllableMobInstance mobInst)
{
for (final MobGroup mobGroup : _groupMap.values())
{
if (mobGroup.isGroupMember(mobInst))
{
return mobGroup;
}
}
return null;
}
public MobGroup[] getGroups()
{
return _groupMap.values().toArray(new MobGroup[getGroupCount()]);
}
public boolean removeGroup(int groupKey)
{
return (_groupMap.remove(groupKey) != null);
}
}

View File

@@ -0,0 +1,91 @@
/*
* 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.model;
import java.util.List;
import com.l2jmobius.gameserver.model.L2ItemInstance.ItemLocation;
import com.l2jmobius.gameserver.model.actor.instance.L2NpcInstance;
import javolution.util.FastList;
public class NpcInventory extends Inventory
{
public static final int ADENA_ID = 57;
public static final int ANCIENT_ADENA_ID = 5575;
private final L2NpcInstance _owner;
public boolean sshotInUse = false;
public boolean bshotInUse = false;
public NpcInventory(L2NpcInstance owner)
{
_owner = owner;
}
public void reset()
{
destroyAllItems("Reset", null, null);
if (_owner.getTemplate().ss > 0)
{
addItem("Reset", 1835, _owner.getTemplate().ss, null, null);
}
if (_owner.getTemplate().bss > 0)
{
addItem("Reset", 3947, _owner.getTemplate().bss, null, null);
}
}
@Override
public L2NpcInstance getOwner()
{
return _owner;
}
@Override
protected ItemLocation getBaseLocation()
{
return ItemLocation.NPC;
}
@Override
protected ItemLocation getEquipLocation()
{
return ItemLocation.NPC;
}
/**
* Returns the list of all items in inventory that have a given item id.
* @param itemId
* @return L2ItemInstance[] : matching items from inventory
*/
public L2ItemInstance[] getAllItemsByItemId(int itemId)
{
final List<L2ItemInstance> list = new FastList<>();
for (final L2ItemInstance item : _items)
{
if (item.getItemId() == itemId)
{
list.add(item);
}
}
return list.toArray(new L2ItemInstance[list.size()]);
}
}

View File

@@ -0,0 +1,188 @@
/*
* 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.model;
import java.util.ArrayList;
import java.util.List;
import com.l2jmobius.gameserver.datatables.MapRegionTable;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.serverpackets.ExManagePartyRoomMember;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
/**
* @author Gnacik
*/
public class PartyMatchRoom
{
private final int _id;
private String _title;
private int _loot;
private int _location;
private int _minlvl;
private int _maxlvl;
private int _maxmem;
private final List<L2PcInstance> _members = new ArrayList<>();
public PartyMatchRoom(int id, String title, int loot, int minlvl, int maxlvl, int maxmem, L2PcInstance owner)
{
_id = id;
_title = title;
_loot = loot;
_location = MapRegionTable.getInstance().getClosestTownNumber(owner);
_minlvl = minlvl;
_maxlvl = maxlvl;
_maxmem = maxmem;
_members.add(owner);
}
public List<L2PcInstance> getPartyMembers()
{
return _members;
}
public void addMember(L2PcInstance player)
{
_members.add(player);
}
public void deleteMember(L2PcInstance player)
{
if (player != getOwner())
{
_members.remove(player);
notifyMembersAboutExit(player);
}
else if (_members.size() == 1)
{
PartyMatchRoomList.getInstance().deleteRoom(_id);
}
else
{
changeLeader(_members.get(1));
deleteMember(player);
}
}
public void notifyMembersAboutExit(L2PcInstance player)
{
for (final L2PcInstance _member : _members)
{
final SystemMessage sm = new SystemMessage(SystemMessage.S1_LEFT_PARTY_ROOM);
sm.addString(player.getName());
_member.sendPacket(sm);
_member.sendPacket(new ExManagePartyRoomMember(player, this, 2));
}
}
public void changeLeader(L2PcInstance newLeader)
{
// Get current leader
final L2PcInstance oldLeader = _members.get(0);
// Remove new leader
_members.remove(newLeader);
// Move him to first position
_members.set(0, newLeader);
// Add old leader as normal member
_members.add(oldLeader);
// Broadcast change
for (final L2PcInstance member : _members)
{
member.sendPacket(new ExManagePartyRoomMember(newLeader, this, 1));
member.sendPacket(new ExManagePartyRoomMember(oldLeader, this, 1));
member.sendPacket(new SystemMessage(SystemMessage.PARTY_ROOM_LEADER_CHANGED));
}
}
public int getId()
{
return _id;
}
public int getLootType()
{
return _loot;
}
public int getMinLvl()
{
return _minlvl;
}
public int getMaxLvl()
{
return _maxlvl;
}
public int getLocation()
{
return _location;
}
public int getMembers()
{
return _members.size();
}
public int getMaxMembers()
{
return _maxmem;
}
public String getTitle()
{
return _title;
}
public L2PcInstance getOwner()
{
return _members.get(0);
}
/* SET */
public void setMinLvl(int minlvl)
{
_minlvl = minlvl;
}
public void setMaxLvl(int maxlvl)
{
_maxlvl = maxlvl;
}
public void setLocation(int loc)
{
_location = loc;
}
public void setLootType(int loot)
{
_loot = loot;
}
public void setMaxMembers(int maxmem)
{
_maxmem = maxmem;
}
public void setTitle(String title)
{
_title = title;
}
}

View File

@@ -0,0 +1,131 @@
/*
* 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.model;
import java.util.Map;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.serverpackets.ExClosePartyRoom;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import javolution.util.FastMap;
/**
* @author Gnacik
*/
public class PartyMatchRoomList
{
private int _maxid;
private final Map<Integer, PartyMatchRoom> _rooms;
private static PartyMatchRoomList _instance;
public static PartyMatchRoomList getInstance()
{
if (_instance == null)
{
_instance = new PartyMatchRoomList();
}
return _instance;
}
private PartyMatchRoomList()
{
_rooms = new FastMap<>();
}
public synchronized void addPartyMatchRoom(PartyMatchRoom room)
{
_rooms.put(room.getId(), room);
}
public void deleteRoom(int id)
{
for (final L2PcInstance _member : getRoom(id).getPartyMembers())
{
if (_member == null)
{
continue;
}
_member.sendPacket(new ExClosePartyRoom());
_member.sendPacket(new SystemMessage(SystemMessage.PARTY_ROOM_DISBANDED));
_member.setPartyRoom(0);
_member.broadcastUserInfo();
}
_rooms.remove(id);
}
public PartyMatchRoom getRoom(int id)
{
return _rooms.get(id);
}
public PartyMatchRoom[] getRooms()
{
return _rooms.values().toArray(new PartyMatchRoom[_rooms.size()]);
}
public int getPartyMatchRoomCount()
{
return _rooms.size();
}
public int getAutoIncrementId()
{
// reset all ids as free
// if room list is empty
if (_rooms.size() == 0)
{
_maxid = 0;
}
_maxid++;
return _maxid;
}
public PartyMatchRoom getPlayerRoom(L2PcInstance player)
{
for (final PartyMatchRoom _room : _rooms.values())
{
for (final L2PcInstance member : _room.getPartyMembers())
{
if (member.equals(player))
{
return _room;
}
}
}
return null;
}
public int getPlayerRoomId(L2PcInstance player)
{
for (final PartyMatchRoom _room : _rooms.values())
{
for (final L2PcInstance member : _room.getPartyMembers())
{
if (member.equals(player))
{
return _room.getId();
}
}
}
return -1;
}
}

View File

@@ -0,0 +1,160 @@
/*
* 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.model;
import java.util.List;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.model.L2ItemInstance.ItemLocation;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import javolution.util.FastList;
public class PcFreight extends ItemContainer
{
// private static final Logger _log = Logger.getLogger(PcFreight.class.getName());
private final L2PcInstance _owner; // This is the L2PcInstance that owns this Freight
private int _activeLocationId = 0;
private int _tempOwnerId = 0;
public PcFreight(L2PcInstance owner)
{
_owner = owner;
}
@Override
public L2PcInstance getOwner()
{
return _owner;
}
@Override
public ItemLocation getBaseLocation()
{
return ItemLocation.FREIGHT;
}
public void setActiveLocation(int locationId)
{
_activeLocationId = locationId;
}
/**
* Returns the quantity of items in the inventory
* @return int
*/
public int getAvailablePackages()
{
int size = 0;
for (final L2ItemInstance item : _items)
{
if ((item.getEquipSlot() == 0) || (_activeLocationId == 0) || (item.getEquipSlot() == _activeLocationId))
{
size++;
}
}
return size;
}
/**
* Returns the list of items in inventory
* @return L2ItemInstance : items in inventory
*/
@Override
public L2ItemInstance[] getItems()
{
final List<L2ItemInstance> list = new FastList<>();
for (final L2ItemInstance item : _items)
{
if ((item.getEquipSlot() == 0) || (item.getEquipSlot() == _activeLocationId))
{
list.add(item);
}
}
return list.toArray(new L2ItemInstance[list.size()]);
}
/**
* Returns the item from inventory by using its <B>itemId</B>
* @param itemId : int designating the ID of the item
* @return L2ItemInstance designating the item or null if not found in inventory
*/
@Override
public L2ItemInstance getItemByItemId(int itemId)
{
for (final L2ItemInstance item : _items)
{
if ((item.getItemId() == itemId) && ((item.getEquipSlot() == 0) || (_activeLocationId == 0) || (item.getEquipSlot() == _activeLocationId)))
{
return item;
}
}
return null;
}
/**
* Adds item to PcFreight for further adjustments.
* @param item : L2ItemInstance to be added from inventory
*/
@Override
protected void addItem(L2ItemInstance item)
{
super.addItem(item);
if (_activeLocationId > 0)
{
item.setLocation(item.getLocation(), _activeLocationId);
}
}
/**
* Get back items in PcFreight from database
*/
@Override
public void restore()
{
final int locationId = _activeLocationId;
_activeLocationId = 0;
super.restore();
_activeLocationId = locationId;
}
@Override
public boolean validateCapacity(int slots)
{
final int cap = (_owner == null ? Config.FREIGHT_SLOTS : _owner.getFreightLimit());
return ((getSize() + slots) <= cap);
}
@Override
public int getOwnerId()
{
if (_owner == null)
{
return _tempOwnerId;
}
return super.getOwnerId();
}
public void doQuickRestore(int val)
{
_tempOwnerId = val;
restore();
}
}

View File

@@ -0,0 +1,668 @@
/*
* 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.model;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.List;
import java.util.logging.Level;
import com.l2jmobius.L2DatabaseFactory;
import com.l2jmobius.gameserver.model.L2ItemInstance.ItemLocation;
import com.l2jmobius.gameserver.model.TradeList.TradeItem;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import javolution.util.FastList;
public class PcInventory extends Inventory
{
public static final int ADENA_ID = 57;
public static final int ANCIENT_ADENA_ID = 5575;
private final L2PcInstance _owner;
private L2ItemInstance _adena;
private L2ItemInstance _ancientAdena;
public PcInventory(L2PcInstance owner)
{
_owner = owner;
}
@Override
public L2PcInstance getOwner()
{
return _owner;
}
@Override
protected ItemLocation getBaseLocation()
{
return ItemLocation.INVENTORY;
}
@Override
protected ItemLocation getEquipLocation()
{
return ItemLocation.PAPERDOLL;
}
public L2ItemInstance getAdenaInstance()
{
return _adena;
}
@Override
public int getAdena()
{
return _adena != null ? _adena.getCount() : 0;
}
public L2ItemInstance getAncientAdenaInstance()
{
return _ancientAdena;
}
public int getAncientAdena()
{
return (_ancientAdena != null) ? _ancientAdena.getCount() : 0;
}
/**
* Returns the list of items in inventory available for transaction
* @param allowAdena
* @param allowAncientAdena
* @return L2ItemInstance : items in inventory
*/
public L2ItemInstance[] getUniqueItems(boolean allowAdena, boolean allowAncientAdena)
{
final List<L2ItemInstance> list = new FastList<>();
for (final L2ItemInstance item : _items)
{
if ((!allowAdena && (item.getItemId() == 57)))
{
continue;
}
if ((!allowAncientAdena && (item.getItemId() == 5575)))
{
continue;
}
boolean isDuplicate = false;
for (final L2ItemInstance litem : list)
{
if (litem.getItemId() == item.getItemId())
{
isDuplicate = true;
break;
}
}
if (!isDuplicate && item.getItem().isSellable() && item.isAvailable(getOwner(), false))
{
list.add(item);
}
}
return list.toArray(new L2ItemInstance[list.size()]);
}
/**
* Returns the list of items in inventory available for transaction Allows an item to appear twice if and only if there is a difference in enchantment level.
* @param allowAdena
* @param allowAncientAdena
* @return L2ItemInstance : items in inventory
*/
public L2ItemInstance[] getUniqueItemsByEnchantLevel(boolean allowAdena, boolean allowAncientAdena)
{
final List<L2ItemInstance> list = new FastList<>();
for (final L2ItemInstance item : _items)
{
if ((!allowAdena && (item.getItemId() == 57)))
{
continue;
}
if ((!allowAncientAdena && (item.getItemId() == 5575)))
{
continue;
}
boolean isDuplicate = false;
for (final L2ItemInstance litem : list)
{
if ((litem.getItemId() == item.getItemId()) && (litem.getEnchantLevel() == item.getEnchantLevel()))
{
isDuplicate = true;
break;
}
}
if (!isDuplicate && item.getItem().isSellable() && item.isAvailable(getOwner(), false))
{
list.add(item);
}
}
return list.toArray(new L2ItemInstance[list.size()]);
}
/**
* Returns the list of all items in inventory that have a given item id.
* @param itemId
* @return L2ItemInstance[] : matching items from inventory
*/
public L2ItemInstance[] getAllItemsByItemId(int itemId)
{
final List<L2ItemInstance> list = new FastList<>();
for (final L2ItemInstance item : _items)
{
if (item.getItemId() == itemId)
{
list.add(item);
}
}
return list.toArray(new L2ItemInstance[list.size()]);
}
/**
* Returns the list of all items in inventory that have a given item id AND a given enchantment level.
* @param itemId
* @param enchantment
* @return L2ItemInstance[] : matching items from inventory
*/
public L2ItemInstance[] getAllItemsByItemId(int itemId, int enchantment)
{
final List<L2ItemInstance> list = new FastList<>();
for (final L2ItemInstance item : _items)
{
if ((item.getItemId() == itemId) && (item.getEnchantLevel() == enchantment))
{
list.add(item);
}
}
return list.toArray(new L2ItemInstance[list.size()]);
}
/**
* Returns the list of items in inventory available for transaction
* @param allowAdena
* @return L2ItemInstance : items in inventory
*/
public L2ItemInstance[] getAvailableItems(boolean allowAdena)
{
final List<L2ItemInstance> list = new FastList<>();
for (final L2ItemInstance item : _items)
{
if ((item != null) && item.isAvailable(getOwner(), allowAdena))
{
list.add(item);
}
}
return list.toArray(new L2ItemInstance[list.size()]);
}
/**
* Returns the list of items in inventory available for transaction adjusetd by tradeList
* @param tradeList
* @return L2ItemInstance : items in inventory
*/
public TradeList.TradeItem[] getAvailableItems(TradeList tradeList)
{
final List<TradeList.TradeItem> list = new FastList<>();
for (final L2ItemInstance item : _items)
{
if (item.isAvailable(getOwner(), false))
{
final TradeList.TradeItem adjItem = tradeList.adjustAvailableItem(item);
if (adjItem != null)
{
list.add(adjItem);
}
}
}
return list.toArray(new TradeList.TradeItem[list.size()]);
}
/**
* Adjust TradeItem according his status in inventory
* @param item : L2ItemInstance to be adjusten
*/
public void adjustAvailableItem(TradeItem item)
{
for (final L2ItemInstance adjItem : _items)
{
if (adjItem.getItemId() == item.getItem().getItemId())
{
item.setObjectId(adjItem.getObjectId());
item.setEnchant(adjItem.getEnchantLevel());
if (adjItem.getCount() < item.getCount())
{
item.setCount(adjItem.getCount());
}
return;
}
}
item.setCount(0);
}
/**
* Adds adena to PCInventory
* @param process : String Identifier of process triggering this action
* @param count : int Quantity of adena to be added
* @param actor : L2PcInstance Player requesting the item add
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
*/
public void addAdena(String process, int count, L2PcInstance actor, L2Object reference)
{
if (count > 0)
{
addItem(process, ADENA_ID, count, actor, reference);
}
}
/**
* Removes adena to PCInventory
* @param process : String Identifier of process triggering this action
* @param count : int Quantity of adena to be removed
* @param actor : L2PcInstance Player requesting the item add
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
*/
public void reduceAdena(String process, int count, L2PcInstance actor, L2Object reference)
{
if (count > 0)
{
destroyItemByItemId(process, ADENA_ID, count, actor, reference);
}
}
/**
* Adds specified amount of ancient adena to player inventory.
* @param process : String Identifier of process triggering this action
* @param count : int Quantity of adena to be added
* @param actor : L2PcInstance Player requesting the item add
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
*/
public void addAncientAdena(String process, int count, L2PcInstance actor, L2Object reference)
{
if (count > 0)
{
addItem(process, ANCIENT_ADENA_ID, count, actor, reference);
}
}
/**
* Removes specified amount of ancient adena from player inventory.
* @param process : String Identifier of process triggering this action
* @param count : int Quantity of adena to be removed
* @param actor : L2PcInstance Player requesting the item add
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
*/
public void reduceAncientAdena(String process, int count, L2PcInstance actor, L2Object reference)
{
if (count > 0)
{
destroyItemByItemId(process, ANCIENT_ADENA_ID, count, actor, reference);
}
}
/**
* Adds item in inventory and checks _adena and _ancientAdena
* @param process : String Identifier of process triggering this action
* @param item : L2ItemInstance to be added
* @param actor : L2PcInstance Player requesting the item add
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
* @return L2ItemInstance corresponding to the new item or the updated item in inventory
*/
@Override
public L2ItemInstance addItem(String process, L2ItemInstance item, L2PcInstance actor, L2Object reference)
{
item = super.addItem(process, item, actor, reference);
if ((item != null) && (item.getItemId() == ADENA_ID) && !item.equals(_adena))
{
_adena = item;
}
if ((item != null) && (item.getItemId() == ANCIENT_ADENA_ID) && !item.equals(_ancientAdena))
{
_ancientAdena = item;
}
return item;
}
/**
* Adds item in inventory and checks _adena and _ancientAdena
* @param process : String Identifier of process triggering this action
* @param itemId : int Item Identifier of the item to be added
* @param count : int Quantity of items to be added
* @param actor : L2PcInstance Player requesting the item creation
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
* @return L2ItemInstance corresponding to the new item or the updated item in inventory
*/
@Override
public L2ItemInstance addItem(String process, int itemId, int count, L2PcInstance actor, L2Object reference)
{
final L2ItemInstance item = super.addItem(process, itemId, count, actor, reference);
if ((item != null) && (item.getItemId() == ADENA_ID) && !item.equals(_adena))
{
_adena = item;
}
if ((item != null) && (item.getItemId() == ANCIENT_ADENA_ID) && !item.equals(_ancientAdena))
{
_ancientAdena = item;
}
return item;
}
/**
* Transfers item to another inventory and checks _adena and _ancientAdena
* @param process : String Identifier of process triggering this action
* @param count : int Quantity of items to be transfered
* @param actor : L2PcInstance Player requesting the item transfer
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
* @return L2ItemInstance corresponding to the new item or the updated item in inventory
*/
@Override
public L2ItemInstance transferItem(String process, int objectId, int count, ItemContainer target, L2PcInstance actor, L2Object reference)
{
final L2ItemInstance item = super.transferItem(process, objectId, count, target, actor, reference);
if ((_adena != null) && ((_adena.getCount() <= 0) || (_adena.getOwnerId() != getOwnerId())))
{
_adena = null;
}
if ((_ancientAdena != null) && ((_ancientAdena.getCount() <= 0) || (_ancientAdena.getOwnerId() != getOwnerId())))
{
_ancientAdena = null;
}
return item;
}
/**
* Destroy item from inventory and checks _adena and _ancientAdena
* @param process : String Identifier of process triggering this action
* @param item : L2ItemInstance to be destroyed
* @param actor : L2PcInstance Player requesting the item destroy
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
* @return L2ItemInstance corresponding to the destroyed item or the updated item in inventory
*/
@Override
public L2ItemInstance destroyItem(String process, L2ItemInstance item, L2PcInstance actor, L2Object reference)
{
return this.destroyItem(process, item, item.getCount(), actor, reference);
}
/**
* Destroy item from inventory and checks _adena and _ancientAdena
* @param process : String Identifier of process triggering this action
* @param item : L2ItemInstance to be destroyed
* @param actor : L2PcInstance Player requesting the item destroy
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
* @return L2ItemInstance corresponding to the destroyed item or the updated item in inventory
*/
@Override
public L2ItemInstance destroyItem(String process, L2ItemInstance item, int count, L2PcInstance actor, L2Object reference)
{
item = super.destroyItem(process, item, count, actor, reference);
if ((_adena != null) && (_adena.getCount() <= 0))
{
_adena = null;
}
if ((_ancientAdena != null) && (_ancientAdena.getCount() <= 0))
{
_ancientAdena = null;
}
return item;
}
/**
* Destroys item from inventory and checks _adena and _ancientAdena
* @param process : String Identifier of process triggering this action
* @param objectId : int Item Instance identifier of the item to be destroyed
* @param count : int Quantity of items to be destroyed
* @param actor : L2PcInstance Player requesting the item destroy
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
* @return L2ItemInstance corresponding to the destroyed item or the updated item in inventory
*/
@Override
public L2ItemInstance destroyItem(String process, int objectId, int count, L2PcInstance actor, L2Object reference)
{
final L2ItemInstance item = getItemByObjectId(objectId);
if (item == null)
{
return null;
}
return destroyItem(process, item, count, actor, reference);
}
/**
* Destroy item from inventory by using its <B>itemId</B> and checks _adena and _ancientAdena
* @param process : String Identifier of process triggering this action
* @param itemId : int Item identifier of the item to be destroyed
* @param count : int Quantity of items to be destroyed
* @param actor : L2PcInstance Player requesting the item destroy
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
* @return L2ItemInstance corresponding to the destroyed item or the updated item in inventory
*/
@Override
public L2ItemInstance destroyItemByItemId(String process, int itemId, int count, L2PcInstance actor, L2Object reference)
{
final L2ItemInstance item = getItemByItemId(itemId);
if (item == null)
{
return null;
}
return destroyItem(process, item, count, actor, reference);
}
/**
* Drop item from inventory and checks _adena and _ancientAdena
* @param process : String Identifier of process triggering this action
* @param item : L2ItemInstance to be dropped
* @param actor : L2PcInstance Player requesting the item drop
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
* @return L2ItemInstance corresponding to the destroyed item or the updated item in inventory
*/
@Override
public L2ItemInstance dropItem(String process, L2ItemInstance item, L2PcInstance actor, L2Object reference)
{
item = super.dropItem(process, item, actor, reference);
if ((_adena != null) && ((_adena.getCount() <= 0) || (_adena.getOwnerId() != getOwnerId())))
{
_adena = null;
}
if ((_ancientAdena != null) && ((_ancientAdena.getCount() <= 0) || (_ancientAdena.getOwnerId() != getOwnerId())))
{
_ancientAdena = null;
}
return item;
}
/**
* Drop item from inventory by using its <B>objectID</B> and checks _adena and _ancientAdena
* @param process : String Identifier of process triggering this action
* @param objectId : int Item Instance identifier of the item to be dropped
* @param count : int Quantity of items to be dropped
* @param actor : L2PcInstance Player requesting the item drop
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
* @return L2ItemInstance corresponding to the destroyed item or the updated item in inventory
*/
@Override
public L2ItemInstance dropItem(String process, int objectId, int count, L2PcInstance actor, L2Object reference)
{
final L2ItemInstance item = super.dropItem(process, objectId, count, actor, reference);
if ((_adena != null) && ((_adena.getCount() <= 0) || (_adena.getOwnerId() != getOwnerId())))
{
_adena = null;
}
if ((_ancientAdena != null) && ((_ancientAdena.getCount() <= 0) || (_ancientAdena.getOwnerId() != getOwnerId())))
{
_ancientAdena = null;
}
return item;
}
/**
* <b>Overloaded</b>, when removes item from inventory, remove also owner shortcuts.
* @param item : L2ItemInstance to be removed from inventory
*/
@Override
protected boolean removeItem(L2ItemInstance item)
{
// Removes any reference to the item from Shortcut bar
getOwner().removeItemFromShortCut(item.getObjectId());
// Removes active Enchant Scroll
if (item.equals(getOwner().getActiveEnchantItem()))
{
getOwner().setActiveEnchantItem(null);
}
if (item.getItemId() == ADENA_ID)
{
_adena = null;
}
else if (item.getItemId() == ANCIENT_ADENA_ID)
{
_ancientAdena = null;
}
return super.removeItem(item);
}
/**
* Refresh the weight of equipment loaded
*/
@Override
public void refreshWeight()
{
super.refreshWeight();
getOwner().refreshOverloaded();
}
/**
* Get back items in inventory from database
*/
@Override
public void restore()
{
super.restore();
_adena = getItemByItemId(ADENA_ID);
_ancientAdena = getItemByItemId(ANCIENT_ADENA_ID);
}
public static int[][] restoreVisibleInventory(int objectId)
{
final int[][] paperdoll = new int[0x10][3];
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement2 = con.prepareStatement("SELECT object_id,item_id,loc_data,enchant_level FROM items WHERE owner_id=? AND loc='PAPERDOLL'"))
{
statement2.setInt(1, objectId);
try (ResultSet invdata = statement2.executeQuery())
{
while (invdata.next())
{
final int slot = invdata.getInt("loc_data");
paperdoll[slot][0] = invdata.getInt("object_id");
paperdoll[slot][1] = invdata.getInt("item_id");
paperdoll[slot][2] = invdata.getInt("enchant_level");
}
}
}
catch (final Exception e)
{
_log.log(Level.WARNING, "could not restore inventory:", e);
}
return paperdoll;
}
public boolean validateCapacity(L2ItemInstance item)
{
int slots = 0;
if (!(item.isStackable() && (getItemByItemId(item.getItemId()) != null)))
{
slots++;
}
return validateCapacity(slots);
}
public boolean validateCapacity(List<L2ItemInstance> items)
{
int slots = 0;
for (final L2ItemInstance item : items)
{
if (!(item.isStackable() && (getItemByItemId(item.getItemId()) != null)))
{
slots++;
}
}
return validateCapacity(slots);
}
public boolean validateCapacityByItemId(int ItemId)
{
int slots = 0;
final L2ItemInstance invItem = getItemByItemId(ItemId);
if (!((invItem != null) && invItem.isStackable()))
{
slots++;
}
return validateCapacity(slots);
}
@Override
public boolean validateCapacity(int slots)
{
return ((_items.size() + slots) <= _owner.getInventoryLimit());
}
@Override
public boolean validateWeight(int weight)
{
return ((_totalWeight + weight) <= _owner.getMaxLoad());
}
}

View File

@@ -0,0 +1,65 @@
/*
* 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.model;
import com.l2jmobius.gameserver.model.L2ItemInstance.ItemLocation;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
public class PcWarehouse extends Warehouse
{
// private static final Logger _log = Logger.getLogger(PcWarehouse.class.getName());
private final L2PcInstance _owner;
public PcWarehouse(L2PcInstance owner)
{
_owner = owner;
}
@Override
public L2PcInstance getOwner()
{
return _owner;
}
@Override
public ItemLocation getBaseLocation()
{
return ItemLocation.WAREHOUSE;
}
public String getLocationId()
{
return "0";
}
public int getLocationId(boolean dummy)
{
return 0;
}
public void setLocationId(L2PcInstance dummy)
{
return;
}
@Override
public boolean validateCapacity(int slots)
{
return ((_items.size() + slots) <= _owner.getWareHouseLimit());
}
}

View File

@@ -0,0 +1,112 @@
/*
* 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.model;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.model.L2ItemInstance.ItemLocation;
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
import com.l2jmobius.gameserver.templates.L2Item;
public class PetInventory extends Inventory
{
private final L2PetInstance _owner;
public PetInventory(L2PetInstance owner)
{
_owner = owner;
}
@Override
public L2PetInstance getOwner()
{
return _owner;
}
@Override
public int getOwnerId()
{
// gets the L2PcInstance-owner's ID
int id;
try
{
id = _owner.getOwner().getObjectId();
}
catch (final NullPointerException e)
{
return 0;
}
return id;
}
/**
* Refresh the weight of equipment loaded
*/
@Override
public void refreshWeight()
{
super.refreshWeight();
getOwner().updateAndBroadcastStatus(1);
}
public boolean validateCapacity(L2ItemInstance item)
{
int slots = 0;
if (!(item.isStackable() && (getItemByItemId(item.getItemId()) != null)))
{
slots++;
}
return validateCapacity(slots);
}
@Override
public boolean validateCapacity(int slots)
{
return ((_items.size() + slots) <= _owner.getInventoryLimit());
}
public boolean validateWeight(L2ItemInstance item, int count)
{
int weight = 0;
final L2Item template = ItemTable.getInstance().getTemplate(item.getItemId());
if (template == null)
{
return false;
}
weight += count * template.getWeight();
return validateWeight(weight);
}
@Override
public boolean validateWeight(int weight)
{
return ((_totalWeight + weight) <= _owner.getMaxLoad());
}
@Override
protected ItemLocation getBaseLocation()
{
return ItemLocation.PET;
}
@Override
protected ItemLocation getEquipLocation()
{
return ItemLocation.PET_EQUIP;
}
}

View File

@@ -0,0 +1,221 @@
/*
* 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.model;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Logger;
import com.l2jmobius.L2DatabaseFactory;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.serverpackets.ExAutoSoulShot;
import com.l2jmobius.gameserver.templates.L2EtcItemType;
/**
* This class ...
* @version $Revision: 1.1.2.1.2.3 $ $Date: 2005/03/27 15:29:33 $
*/
public class ShortCuts
{
private static Logger _log = Logger.getLogger(ShortCuts.class.getName());
private final L2PcInstance _owner;
private final Map<Integer, L2ShortCut> _shortCuts = new TreeMap<>();
public ShortCuts(L2PcInstance owner)
{
_owner = owner;
}
public L2ShortCut[] getAllShortCuts()
{
return _shortCuts.values().toArray(new L2ShortCut[_shortCuts.values().size()]);
}
public L2ShortCut getShortCut(int slot, int page)
{
L2ShortCut sc = _shortCuts.get(slot + (page * 12));
// verify shortcut
if ((sc != null) && (sc.getType() == L2ShortCut.TYPE_ITEM))
{
if (_owner.getInventory().getItemByObjectId(sc.getId()) == null)
{
deleteShortCut(sc.getSlot(), sc.getPage());
sc = null;
}
}
return sc;
}
public void registerShortCut(L2ShortCut shortcut)
{
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("REPLACE INTO character_shortcuts (char_obj_id,slot,page,type,shortcut_id,level,class_index) values(?,?,?,?,?,?,?)"))
{
statement.setInt(1, _owner.getObjectId());
statement.setInt(2, shortcut.getSlot());
statement.setInt(3, shortcut.getPage());
statement.setInt(4, shortcut.getType());
statement.setInt(5, shortcut.getId());
statement.setInt(6, shortcut.getLevel());
statement.setInt(7, _owner.getClassIndex());
statement.execute();
}
catch (final Exception e)
{
_log.warning("Could not store character shortcut: " + e);
}
_shortCuts.put(shortcut.getSlot() + (12 * shortcut.getPage()), shortcut);
}
/**
* @param slot
* @param page
*/
public synchronized void deleteShortCut(int slot, int page)
{
final L2ShortCut old = _shortCuts.remove(slot + (page * 12));
if (old == null)
{
return;
}
deleteShortCutFromDb(old);
if (_owner == null)
{
return;
}
if (old.getType() == L2ShortCut.TYPE_ITEM)
{
final L2ItemInstance item = _owner.getInventory().getItemByObjectId(old.getId());
if ((item != null) && (item.getItemType() == L2EtcItemType.SHOT))
{
_owner.removeAutoSoulShot(item.getItemId());
_owner.sendPacket(new ExAutoSoulShot(item.getItemId(), 0));
}
}
for (final int shotId : _owner.getAutoSoulShot())
{
_owner.sendPacket(new ExAutoSoulShot(shotId, 1));
}
}
public synchronized void deleteShortCutByObjectId(int objectId)
{
L2ShortCut toRemove = null;
for (final L2ShortCut shortcut : _shortCuts.values())
{
if ((shortcut.getType() == L2ShortCut.TYPE_ITEM) && (shortcut.getId() == objectId))
{
toRemove = shortcut;
break;
}
}
if (toRemove != null)
{
deleteShortCut(toRemove.getSlot(), toRemove.getPage());
}
}
/**
* @param shortCut
*/
private void deleteShortCutFromDb(L2ShortCut shortCut)
{
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("DELETE FROM character_shortcuts WHERE char_obj_id=? AND slot=? AND page=? AND type=? AND shortcut_id=? AND level=? AND class_index=?"))
{
statement.setInt(1, _owner.getObjectId());
statement.setInt(2, shortCut.getSlot());
statement.setInt(3, shortCut.getPage());
statement.setInt(4, shortCut.getType());
statement.setInt(5, shortCut.getId());
statement.setInt(6, shortCut.getLevel());
statement.setInt(7, _owner.getClassIndex());
statement.execute();
}
catch (final Exception e)
{
_log.warning("Could not delete character shortcut: " + e);
}
}
public void restore()
{
_shortCuts.clear();
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("SELECT char_obj_id, slot, page, type, shortcut_id, level FROM character_shortcuts WHERE char_obj_id=? AND class_index=?"))
{
statement.setInt(1, _owner.getObjectId());
statement.setInt(2, _owner.getClassIndex());
try (ResultSet rset = statement.executeQuery())
{
while (rset.next())
{
final int slot = rset.getInt("slot");
final int page = rset.getInt("page");
final int type = rset.getInt("type");
final int id = rset.getInt("shortcut_id");
int level = rset.getInt("level");
if (level > -1)
{
level = _owner.getSkillLevel(id);
}
final L2ShortCut sc = new L2ShortCut(slot, page, type, id, level, 1);
_shortCuts.put(slot + (page * 12), sc);
}
}
}
catch (final Exception e)
{
_log.warning("Could not restore character shortcuts: " + e);
}
// verify shortcuts
for (final L2ShortCut sc : getAllShortCuts())
{
if (sc == null)
{
continue;
}
if (sc.getType() == L2ShortCut.TYPE_ITEM)
{
if (_owner.getInventory().getItemByObjectId(sc.getId()) == null)
{
deleteShortCut(sc.getSlot(), sc.getPage());
}
}
}
}
}

View File

@@ -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.model;
import com.l2jmobius.gameserver.model.actor.instance.L2NpcInstance;
/**
* This class ...
* @version $Revision: 1.2 $ $Date: 2004/06/27 08:12:59 $
*/
public interface SpawnListener
{
public void npcSpawned(L2NpcInstance npc);
}

View File

@@ -0,0 +1,95 @@
/*
* 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.model;
/**
* This class ...
* @version $Revision: 1.2.4.1 $ $Date: 2005/03/27 15:29:32 $
*/
public final class TradeItem
{
private int _ObjectId;
private int _ItemId;
private int _Price;
private int _storePrice;
private int _count;
private int _enchantLevel;
public TradeItem()
{
}
public void setObjectId(int id)
{
_ObjectId = id;
}
public int getObjectId()
{
return _ObjectId;
}
public void setItemId(int id)
{
_ItemId = id;
}
public int getItemId()
{
return _ItemId;
}
public void setOwnersPrice(int price)
{
_Price = price;
}
public int getOwnersPrice()
{
return _Price;
}
public void setstorePrice(int price)
{
_storePrice = price;
}
public int getStorePrice()
{
return _storePrice;
}
public void setCount(int count)
{
_count = count;
}
public int getCount()
{
return _count;
}
public void setEnchantLevel(int enchant)
{
_enchantLevel = enchant;
}
public int getEnchantLevel()
{
return _enchantLevel;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,25 @@
/*
* 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.model;
/**
* This class ...
* @version $Revision: 1.3.2.1.2.12 $ $Date: 2005/04/06 16:13:42 $
*/
public abstract class Warehouse extends ItemContainer
{
}

View File

@@ -0,0 +1,138 @@
/*
* 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.model.actor.appearance;
public class PcAppearance
{
// =========================================================
// Data Field
private byte _Face;
private byte _HairColor;
private byte _HairStyle;
private boolean _Sex; // Female true(1)
/** true if the player is invisible */
private boolean _invisible = false;
/** The hexadecimal Color of players name (white is 0xFFFFFF) */
private int _nameColor = 0xFFFFFF;
/** The hexadecimal Color of players name (white is 0xFFFFFF) */
private int _titleColor = 0xFFFF77;
// =========================================================
// Constructor
public PcAppearance(byte Face, byte HColor, byte HStyle, boolean Sex)
{
_Face = Face;
_HairColor = HColor;
_HairStyle = HStyle;
_Sex = Sex;
}
// =========================================================
// Property - Public
public final byte getFace()
{
return _Face;
}
public final void setFace(int value)
{
_Face = (byte) value;
}
public final byte getHairColor()
{
return _HairColor;
}
public final void setHairColor(int value)
{
_HairColor = (byte) value;
}
public final byte getHairStyle()
{
return _HairStyle;
}
public final void setHairStyle(int value)
{
_HairStyle = (byte) value;
}
/**
* @return true if char is female
*/
public final boolean getSex()
{
return _Sex;
}
/**
* @param isfemale
*/
public final void setSex(boolean isfemale)
{
_Sex = isfemale;
}
public void setInvisible()
{
_invisible = true;
}
public void setVisible()
{
_invisible = false;
}
public boolean getInvisible()
{
return _invisible;
}
public int getNameColor()
{
return _nameColor;
}
public void setNameColor(int nameColor)
{
_nameColor = nameColor;
}
public void setNameColor(int red, int green, int blue)
{
_nameColor = (red & 0xFF) + ((green & 0xFF) << 8) + ((blue & 0xFF) << 16);
}
public int getTitleColor()
{
return _titleColor;
}
public void setTitleColor(int titleColor)
{
_titleColor = titleColor;
}
public void setTitleColor(int red, int green, int blue)
{
_titleColor = (red & 0xFF) + ((green & 0xFF) << 8) + ((blue & 0xFF) << 16);
}
}

View File

@@ -0,0 +1,106 @@
/*
* 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.model.actor.instance;
import com.l2jmobius.gameserver.instancemanager.RaidBossSpawnManager;
import com.l2jmobius.gameserver.model.L2Spawn;
import com.l2jmobius.gameserver.network.serverpackets.ExQuestInfo;
import com.l2jmobius.gameserver.network.serverpackets.RadarControl;
import com.l2jmobius.gameserver.templates.L2NpcTemplate;
/**
* This class ...
* @version $Revision: $ $Date: $
* @author LBaldi
*/
public class L2AdventurerInstance extends L2FolkInstance
{
// private static Logger _log = Logger.getLogger(L2AdventurerInstance.class.getName());
public L2AdventurerInstance(int objectId, L2NpcTemplate template)
{
super(objectId, template);
}
@Override
public void onBypassFeedback(L2PcInstance player, String command)
{
if (command.startsWith("npcfind_byid"))
{
try
{
final int bossId = Integer.parseInt(command.substring(12).trim());
switch (RaidBossSpawnManager.getInstance().getRaidBossStatusId(bossId))
{
case ALIVE:
case DEAD:
final L2Spawn spawn = RaidBossSpawnManager.getInstance().getSpawns().get(bossId);
player.sendPacket(new RadarControl(2, 2, spawn.getLocx(), spawn.getLocy(), spawn.getLocz()));
player.sendPacket(new RadarControl(0, 1, spawn.getLocx(), spawn.getLocy(), spawn.getLocz()));
break;
case UNDEFINED:
player.sendMessage("This Boss isn't in game - notify L2JMobius Team.");
break;
}
}
catch (final NumberFormatException e)
{
_log.warning("Invalid Bypass to Server command parameter.");
}
}
else if (command.startsWith("raidInfo"))
{
final int bossLevel = Integer.parseInt(command.substring(9).trim());
String filename = "data/html/adventurer_guildsman/raid_info/info.htm";
if (bossLevel != 0)
{
filename = "data/html/adventurer_guildsman/raid_info/level" + bossLevel + ".htm";
}
showChatWindow(player, bossLevel, filename);
}
else if (command.equalsIgnoreCase("questlist"))
{
player.sendPacket(new ExQuestInfo());
}
else
{
super.onBypassFeedback(player, command);
}
}
@Override
public String getHtmlPath(int npcId, int val)
{
String pom = "";
if (val == 0)
{
pom = "" + npcId;
}
else
{
pom = npcId + "-" + val;
}
return "data/html/adventurer_guildsman/" + pom + ".htm";
}
private void showChatWindow(L2PcInstance player, int bossLevel, String filename)
{
showChatWindow(player, filename);
}
}

View File

@@ -0,0 +1,132 @@
/*
* 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.model.actor.instance;
import com.l2jmobius.gameserver.ai.CtrlIntention;
import com.l2jmobius.gameserver.model.L2Character;
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import com.l2jmobius.gameserver.network.serverpackets.MyTargetSelected;
import com.l2jmobius.gameserver.network.serverpackets.ValidateLocation;
import com.l2jmobius.gameserver.templates.L2NpcTemplate;
/**
* This class manages all Castle Siege Artefacts.<BR>
* <BR>
* @version $Revision: 1.11.2.1.2.7 $ $Date: 2005/04/06 16:13:40 $
*/
public final class L2ArtefactInstance extends L2NpcInstance
{
/**
* Constructor of L2ArtefactInstance (use L2Character and L2NpcInstance constructor).<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Call the L2Character constructor to set the _template of the L2ArtefactInstance (copy skills from template to object and link _calculators to NPC_STD_CALCULATOR)</li>
* <li>Set the name of the L2ArtefactInstance</li>
* <li>Create a RandomAnimation Task that will be launched after the calculated delay if the server allow it</li><BR>
* <BR>
* @param objectId Identifier of the object to initialized
* @param template to apply to the NPC
*/
public L2ArtefactInstance(int objectId, L2NpcTemplate template)
{
super(objectId, template);
}
/**
* Return False.<BR>
* <BR>
*/
@Override
public boolean isAutoAttackable(L2Character attacker)
{
return false;
}
@Override
public boolean isAttackable()
{
return false;
}
/**
* Manage actions when a player click on the L2ArtefactInstance.<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Set the L2NpcInstance as target of the L2PcInstance player (if necessary)</li>
* <li>Send a Server->Client packet MyTargetSelected to the L2PcInstance player (display the select window)</li>
* <li>Send a Server->Client packet ValidateLocation to correct the L2NpcInstance position and heading on the client</li><BR>
* <BR>
* <B><U> Example of use </U> :</B><BR>
* <BR>
* <li>Client packet : Action, AttackRequest</li><BR>
* <BR>
* @param player The L2PcInstance that start an action on the L2ArtefactInstance
*/
@Override
public void onAction(L2PcInstance player)
{
if (!canTarget(player))
{
return;
}
if (this != player.getTarget())
{
// Set the target of the L2PcInstance player
player.setTarget(this);
// Send a Server->Client packet MyTargetSelected to the L2PcInstance player
final MyTargetSelected my = new MyTargetSelected(getObjectId(), 0);
player.sendPacket(my);
// Send a Server->Client packet ValidateLocation to correct the L2ArtefactInstance position and heading on the client
player.sendPacket(new ValidateLocation(this));
}
else
{
// Calculate the distance between the L2PcInstance and the L2NpcInstance
if (!canInteract(player))
{
// Notify the L2PcInstance AI with AI_INTENTION_INTERACT
player.getAI().setIntention(CtrlIntention.AI_INTENTION_INTERACT, this);
}
}
// Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet
player.sendPacket(new ActionFailed());
}
@Override
public void onForcedAttack(L2PcInstance player)
{
// Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet
player.sendPacket(new ActionFailed());
}
@Override
public void reduceCurrentHp(double damage, L2Character attacker)
{
}
@Override
public void reduceCurrentHp(double damage, L2Character attacker, boolean awake)
{
}
}

View File

@@ -0,0 +1,655 @@
/*
* 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.model.actor.instance;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.ai.CtrlIntention;
import com.l2jmobius.gameserver.datatables.MapRegionTable;
import com.l2jmobius.gameserver.instancemanager.AuctionManager;
import com.l2jmobius.gameserver.instancemanager.ClanHallManager;
import com.l2jmobius.gameserver.model.entity.Auction;
import com.l2jmobius.gameserver.model.entity.Auction.Bidder;
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import com.l2jmobius.gameserver.network.serverpackets.MyTargetSelected;
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.network.serverpackets.ValidateLocation;
import com.l2jmobius.gameserver.templates.L2NpcTemplate;
import javolution.util.FastMap;
public final class L2AuctioneerInstance extends L2FolkInstance
{
private static int Cond_All_False = 0;
private static int Cond_Busy_Because_Of_Siege = 1;
private static int Cond_Regular = 3;
private final Map<Integer, Auction> _pendingAuctions = new FastMap<>();
public L2AuctioneerInstance(int objectId, L2NpcTemplate template)
{
super(objectId, template);
}
@Override
public void onAction(L2PcInstance player)
{
if (!canTarget(player))
{
return;
}
player.setLastFolkNPC(this);
// Check if the L2PcInstance already target the L2NpcInstance
if (this != player.getTarget())
{
// Set the target of the L2PcInstance player
player.setTarget(this);
// Send a Server->Client packet MyTargetSelected to the L2PcInstance player
final MyTargetSelected my = new MyTargetSelected(getObjectId(), 0);
player.sendPacket(my);
// Send a Server->Client packet ValidateLocation to correct the L2NpcInstance position and heading on the client
player.sendPacket(new ValidateLocation(this));
}
else
{
// Calculate the distance between the L2PcInstance and the L2NpcInstance
if (!canInteract(player))
{
// Notify the L2PcInstance AI with AI_INTENTION_INTERACT
player.getAI().setIntention(CtrlIntention.AI_INTENTION_INTERACT, this);
}
else
{
showMessageWindow(player);
}
}
// Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet
player.sendPacket(new ActionFailed());
}
@Override
public void onBypassFeedback(L2PcInstance player, String command)
{
final int condition = validateCondition(player);
if (condition <= Cond_All_False)
{
player.sendMessage("Inappropriate conditions.");
return;
}
if (condition == Cond_Busy_Because_Of_Siege)
{
player.sendMessage("Busy because of siege.");
return;
}
else if (condition == Cond_Regular)
{
final StringTokenizer st = new StringTokenizer(command, " ");
final String actualCommand = st.nextToken(); // Get actual command
String val = "";
if (st.countTokens() >= 1)
{
val = st.nextToken();
}
if (actualCommand.equalsIgnoreCase("auction"))
{
if (val.isEmpty())
{
return;
}
try
{
final int days = Integer.parseInt(val);
try
{
int bid = 0;
if (st.countTokens() >= 1)
{
bid = Integer.parseInt(st.nextToken());
}
final Auction a = new Auction(player.getClan().getHasHideout(), player.getClan(), days * 86400000, bid, ClanHallManager.getInstance().getClanHallByOwner(player.getClan()).getName());
if (_pendingAuctions.get(a.getId()) != null)
{
_pendingAuctions.remove(a.getId());
}
_pendingAuctions.put(a.getId(), a);
final String filename = "data/html/auction/AgitSale3.htm";
final NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(filename);
html.replace("%x%", val);
html.replace("%AGIT_AUCTION_END_YY%", String.valueOf(a.getEndDate().get(Calendar.YEAR)));
html.replace("%AGIT_AUCTION_END_MM%", String.valueOf(a.getEndDate().get(Calendar.MONTH) + 1));
html.replace("%AGIT_AUCTION_END_DD%", String.valueOf(a.getEndDate().get(Calendar.DAY_OF_MONTH)));
html.replace("%AGIT_AUCTION_END_HH%", String.valueOf(a.getEndDate().get(Calendar.HOUR_OF_DAY)));
html.replace("%AGIT_AUCTION_MINBID%", String.valueOf(a.getStartingBid()));
html.replace("%AGIT_AUCTION_MIN%", String.valueOf(a.getStartingBid()));
html.replace("%AGIT_AUCTION_DESC%", ClanHallManager.getInstance().getClanHallByOwner(player.getClan()).getDesc());
html.replace("%objectId%", String.valueOf((getObjectId())));
player.sendPacket(html);
}
catch (final Exception e)
{
player.sendMessage("Invalid bid!");
}
}
catch (final Exception e)
{
player.sendMessage("Invalid auction duration!");
}
return;
}
if (actualCommand.equalsIgnoreCase("confirmAuction"))
{
try
{
final Auction a = _pendingAuctions.get(player.getClan().getHasHideout());
a.confirmAuction();
_pendingAuctions.remove(player.getClan().getHasHideout());
}
catch (final Exception e)
{
player.sendMessage("Invalid auction!");
}
return;
}
else if (actualCommand.equalsIgnoreCase("bidding"))
{
if (val.isEmpty())
{
return;
}
if (Config.DEBUG)
{
_log.warning("bidding show successful");
}
try
{
final int auctionId = Integer.parseInt(val);
if (Config.DEBUG)
{
_log.warning("auction test started");
}
final String filename = "data/html/auction/AgitAuctionInfo.htm";
final Auction a = AuctionManager.getInstance().getAuction(auctionId);
final NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(filename);
if (a != null)
{
html.replace("%AGIT_NAME%", a.getItemName());
html.replace("%OWNER_PLEDGE_NAME%", a.getSellerClanName());
html.replace("%OWNER_PLEDGE_MASTER%", a.getSellerName());
html.replace("%AGIT_SIZE%", String.valueOf(ClanHallManager.getInstance().getClanHallById(a.getItemId()).getGrade() * 10));
html.replace("%AGIT_LEASE%", String.valueOf(ClanHallManager.getInstance().getClanHallById(a.getItemId()).getLease()));
html.replace("%AGIT_LOCATION%", ClanHallManager.getInstance().getClanHallById(a.getItemId()).getLocation());
html.replace("%AGIT_AUCTION_END_YY%", String.valueOf(a.getEndDate().get(Calendar.YEAR)));
html.replace("%AGIT_AUCTION_END_MM%", String.valueOf(a.getEndDate().get(Calendar.MONTH) + 1));
html.replace("%AGIT_AUCTION_END_DD%", String.valueOf(a.getEndDate().get(Calendar.DAY_OF_MONTH)));
html.replace("%AGIT_AUCTION_END_HH%", String.valueOf(a.getEndDate().get(Calendar.HOUR_OF_DAY)));
html.replace("%AGIT_AUCTION_REMAIN%", String.valueOf((a.getEndDate().getTimeInMillis() - Calendar.getInstance().getTimeInMillis()) / 3600000) + " hours " + String.valueOf((((a.getEndDate().getTimeInMillis() - Calendar.getInstance().getTimeInMillis()) / 60000) % 60)) + " minutes");
html.replace("%AGIT_AUCTION_MINBID%", String.valueOf(a.getStartingBid()));
html.replace("%AGIT_AUCTION_COUNT%", String.valueOf(a.getBidders().size()));
html.replace("%AGIT_AUCTION_DESC%", ClanHallManager.getInstance().getClanHallById(a.getItemId()).getDesc());
html.replace("%AGIT_LINK_BACK%", "bypass -h npc_" + getObjectId() + "_list");
html.replace("%AGIT_LINK_BIDLIST%", "bypass -h npc_" + getObjectId() + "_bidlist " + a.getId());
html.replace("%AGIT_LINK_RE%", "bypass -h npc_" + getObjectId() + "_bid1 " + a.getId());
}
else
{
_log.warning("Auctioneer Auction null for AuctionId : " + auctionId);
}
player.sendPacket(html);
}
catch (final Exception e)
{
player.sendMessage("Invalid auction!");
}
return;
}
else if (actualCommand.equalsIgnoreCase("bid"))
{
if (val.isEmpty())
{
return;
}
try
{
final int auctionId = Integer.parseInt(val);
try
{
int bid = 0;
if (st.countTokens() >= 1)
{
bid = Integer.parseInt(st.nextToken());
}
AuctionManager.getInstance().getAuction(auctionId).setBid(player, bid);
}
catch (final Exception e)
{
player.sendMessage("Invalid bid!");
}
}
catch (final Exception e)
{
player.sendMessage("Invalid auction!");
}
return;
}
else if (actualCommand.equalsIgnoreCase("bid1"))
{
if ((player.getClan() == null) || (player.getClan().getLevel() < 2))
{
player.sendMessage("Your clan's level needs to be at least 2, before you can bid in an auction.");
return;
}
if (val.isEmpty())
{
return;
}
if (((player.getClan().getAuctionBiddedAt() > 0) && (player.getClan().getAuctionBiddedAt() != Integer.parseInt(val))) || (player.getClan().getHasHideout() > 0))
{
player.sendPacket(new SystemMessage(676));
return;
}
try
{
final String filename = "data/html/auction/AgitBid1.htm";
int minimumBid = AuctionManager.getInstance().getAuction(Integer.parseInt(val)).getHighestBidderMaxBid();
if (minimumBid == 0)
{
minimumBid = AuctionManager.getInstance().getAuction(Integer.parseInt(val)).getStartingBid();
}
final NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(filename);
html.replace("%AGIT_LINK_BACK%", "bypass -h npc_" + getObjectId() + "_bidding " + val);
html.replace("%PLEDGE_ADENA%", String.valueOf(player.getClan().getWarehouse().getAdena()));
html.replace("%AGIT_AUCTION_MINBID%", String.valueOf(minimumBid + 1));
html.replace("npc_%objectId%_bid", "npc_" + getObjectId() + "_bid " + val);
player.sendPacket(html);
return;
}
catch (final Exception e)
{
player.sendMessage("Invalid auction!");
}
return;
}
else if (actualCommand.equalsIgnoreCase("list"))
{
if (Config.DEBUG)
{
_log.warning("cmd list: auction test started");
}
String items = "";
final List<Auction> auctions = AuctionManager.getInstance().getAuctions();
for (final Auction a : auctions)
{
items += "<tr>" + "<td>" + ClanHallManager.getInstance().getClanHallById(a.getItemId()).getLocation() + "</td><td><a action=\"bypass -h npc_" + getObjectId() + "_bidding " + a.getId() + "\">" + a.getItemName() + "</a></td><td>" + a.getEndDate().get(Calendar.YEAR) + "/" + (a.getEndDate().get(Calendar.MONTH) + 1) + "/" + a.getEndDate().get(Calendar.DATE) + "</td><td>" + a.getStartingBid() + "</td>" + "</tr>";
}
final String filename = "data/html/auction/AgitAuctionList.htm";
final NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(filename);
html.replace("%itemsField%", items);
player.sendPacket(html);
return;
}
else if (actualCommand.equalsIgnoreCase("bidlist"))
{
int auctionId = 0;
if (val.isEmpty())
{
if (player.getClan().getAuctionBiddedAt() <= 0)
{
return;
}
auctionId = player.getClan().getAuctionBiddedAt();
}
else
{
auctionId = Integer.parseInt(val);
}
if (Config.DEBUG)
{
_log.warning("cmd bidlist: auction test started");
}
String biders = "";
final Map<Integer, Bidder> bidders = AuctionManager.getInstance().getAuction(auctionId).getBidders();
for (final Bidder b : bidders.values())
{
biders += "<tr>" + "<td>" + b.getClanName() + "</td><td>" + b.getName() + "</td><td>" + b.getTimeBid().get(Calendar.YEAR) + "/" + (b.getTimeBid().get(Calendar.MONTH) + 1) + "/" + b.getTimeBid().get(Calendar.DATE) + "</td><td>" + b.getBid() + "</td>" + "</tr>";
}
final String filename = "data/html/auction/AgitBidderList.htm";
final NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(filename);
html.replace("%AGIT_LIST%", biders);
html.replace("%x%", val);
html.replace("%objectId%", String.valueOf(getObjectId()));
player.sendPacket(html);
return;
}
else if (actualCommand.equalsIgnoreCase("selectedItems"))
{
if ((player.getClan() != null) && (player.getClan().getHasHideout() == 0) && (player.getClan().getAuctionBiddedAt() > 0))
{
final String filename = "data/html/auction/AgitBidInfo.htm";
final NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(filename);
final Auction a = AuctionManager.getInstance().getAuction(player.getClan().getAuctionBiddedAt());
if (a != null)
{
html.replace("%AGIT_NAME%", a.getItemName());
html.replace("%OWNER_PLEDGE_NAME%", a.getSellerClanName());
html.replace("%OWNER_PLEDGE_MASTER%", a.getSellerName());
html.replace("%AGIT_SIZE%", String.valueOf(ClanHallManager.getInstance().getClanHallById(a.getItemId()).getGrade() * 10));
html.replace("%AGIT_LEASE%", String.valueOf(ClanHallManager.getInstance().getClanHallById(a.getItemId()).getLease()));
html.replace("%AGIT_LOCATION%", ClanHallManager.getInstance().getClanHallById(a.getItemId()).getLocation());
html.replace("%AGIT_AUCTION_END_YY%", String.valueOf(a.getEndDate().get(Calendar.YEAR)));
html.replace("%AGIT_AUCTION_END_MM%", String.valueOf(a.getEndDate().get(Calendar.MONTH) + 1));
html.replace("%AGIT_AUCTION_END_DD%", String.valueOf(a.getEndDate().get(Calendar.DAY_OF_MONTH)));
html.replace("%AGIT_AUCTION_END_HH%", String.valueOf(a.getEndDate().get(Calendar.HOUR_OF_DAY)));
html.replace("%AGIT_AUCTION_REMAIN%", String.valueOf((a.getEndDate().getTimeInMillis() - Calendar.getInstance().getTimeInMillis()) / 3600000) + " hours " + String.valueOf((((a.getEndDate().getTimeInMillis() - Calendar.getInstance().getTimeInMillis()) / 60000) % 60)) + " minutes");
html.replace("%AGIT_AUCTION_MINBID%", String.valueOf(a.getStartingBid()));
html.replace("%AGIT_AUCTION_MYBID%", String.valueOf(a.getBidders().get(player.getClanId()).getBid()));
html.replace("%AGIT_AUCTION_DESC%", ClanHallManager.getInstance().getClanHallById(a.getItemId()).getDesc());
html.replace("%objectId%", String.valueOf(getObjectId()));
}
else
{
_log.warning("Auctioneer Auction null for AuctionBiddedAt : " + player.getClan().getAuctionBiddedAt());
}
player.sendPacket(html);
return;
}
else if ((player.getClan() != null) && (AuctionManager.getInstance().getAuction(player.getClan().getHasHideout()) != null))
{
final String filename = "data/html/auction/AgitSaleInfo.htm";
final NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(filename);
final Auction a = AuctionManager.getInstance().getAuction(player.getClan().getHasHideout());
if (a != null)
{
html.replace("%AGIT_NAME%", a.getItemName());
html.replace("%AGIT_OWNER_PLEDGE_NAME%", a.getSellerClanName());
html.replace("%OWNER_PLEDGE_MASTER%", a.getSellerName());
html.replace("%AGIT_SIZE%", String.valueOf(ClanHallManager.getInstance().getClanHallById(a.getItemId()).getGrade() * 10));
html.replace("%AGIT_LEASE%", String.valueOf(ClanHallManager.getInstance().getClanHallById(a.getItemId()).getLease()));
html.replace("%AGIT_LOCATION%", ClanHallManager.getInstance().getClanHallById(a.getItemId()).getLocation());
html.replace("%AGIT_AUCTION_END_YY%", String.valueOf(a.getEndDate().get(Calendar.YEAR)));
html.replace("%AGIT_AUCTION_END_MM%", String.valueOf(a.getEndDate().get(Calendar.MONTH) + 1));
html.replace("%AGIT_AUCTION_END_DD%", String.valueOf(a.getEndDate().get(Calendar.DAY_OF_MONTH)));
html.replace("%AGIT_AUCTION_END_HH%", String.valueOf(a.getEndDate().get(Calendar.HOUR_OF_DAY)));
html.replace("%AGIT_AUCTION_REMAIN%", String.valueOf((a.getEndDate().getTimeInMillis() - Calendar.getInstance().getTimeInMillis()) / 3600000) + " hours " + String.valueOf((((a.getEndDate().getTimeInMillis() - Calendar.getInstance().getTimeInMillis()) / 60000) % 60)) + " minutes");
html.replace("%AGIT_AUCTION_MINBID%", String.valueOf(a.getStartingBid()));
html.replace("%AGIT_AUCTION_BIDCOUNT%", String.valueOf(a.getBidders().size()));
html.replace("%AGIT_AUCTION_DESC%", ClanHallManager.getInstance().getClanHallById(a.getItemId()).getDesc());
html.replace("%id%", String.valueOf(a.getId()));
html.replace("%objectId%", String.valueOf(getObjectId()));
}
else
{
_log.warning("Auctioneer Auction null for getHasHideout : " + player.getClan().getHasHideout());
}
player.sendPacket(html);
return;
}
else if ((player.getClan() != null) && (player.getClan().getHasHideout() != 0))
{
final int ItemId = player.getClan().getHasHideout();
final String filename = "data/html/auction/AgitInfo.htm";
final NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(filename);
html.replace("%AGIT_NAME%", ClanHallManager.getInstance().getClanHallById(ItemId).getName());
html.replace("%AGIT_OWNER_PLEDGE_NAME%", player.getClan().getName());
html.replace("%OWNER_PLEDGE_MASTER%", player.getClan().getLeaderName());
html.replace("%AGIT_SIZE%", String.valueOf(ClanHallManager.getInstance().getClanHallById(ItemId).getGrade() * 10));
html.replace("%AGIT_LEASE%", String.valueOf(ClanHallManager.getInstance().getClanHallById(ItemId).getLease()));
html.replace("%AGIT_LOCATION%", ClanHallManager.getInstance().getClanHallById(ItemId).getLocation());
html.replace("%objectId%", String.valueOf(getObjectId()));
player.sendPacket(html);
return;
}
}
else if (actualCommand.equalsIgnoreCase("cancelBid"))
{
final int bid = AuctionManager.getInstance().getAuction(player.getClan().getAuctionBiddedAt()).getBidders().get(player.getClanId()).getBid();
final String filename = "data/html/auction/AgitBidCancel.htm";
final NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(filename);
html.replace("%AGIT_BID%", String.valueOf(bid));
html.replace("%AGIT_BID_REMAIN%", String.valueOf((bid * 0.9)));
html.replace("%objectId%", String.valueOf(getObjectId()));
player.sendPacket(html);
return;
}
else if (actualCommand.equalsIgnoreCase("doCancelBid"))
{
if (AuctionManager.getInstance().getAuction(player.getClan().getAuctionBiddedAt()) != null)
{
AuctionManager.getInstance().getAuction(player.getClan().getAuctionBiddedAt()).cancelBid(player.getClanId());
player.sendMessage("You have succesfully cancelled your bidding at the auction");
}
return;
}
else if (actualCommand.equalsIgnoreCase("cancelAuction"))
{
if (!player.isClanLeader())
{
player.sendMessage("Only the clan leader has the privilege to do this.");
return;
}
final String filename = "data/html/auction/AgitSaleCancel.htm";
final NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(filename);
html.replace("%AGIT_DEPOSIT%", String.valueOf(ClanHallManager.getInstance().getClanHallByOwner(player.getClan()).getLease()));
html.replace("%objectId%", String.valueOf(getObjectId()));
player.sendPacket(html);
return;
}
else if (actualCommand.equalsIgnoreCase("doCancelAuction"))
{
if (AuctionManager.getInstance().getAuction(player.getClan().getHasHideout()) != null)
{
AuctionManager.getInstance().getAuction(player.getClan().getHasHideout()).cancelAuction();
player.sendMessage("Your auction has been canceled");
}
return;
}
else if (actualCommand.equalsIgnoreCase("sale2"))
{
final String filename = "data/html/auction/AgitSale2.htm";
final NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(filename);
html.replace("%AGIT_LAST_PRICE%", String.valueOf(ClanHallManager.getInstance().getClanHallByOwner(player.getClan()).getLease()));
html.replace("%objectId%", String.valueOf(getObjectId()));
player.sendPacket(html);
return;
}
else if (actualCommand.equalsIgnoreCase("sale"))
{
if (!player.isClanLeader())
{
player.sendMessage("Only the clan leader has the privilege to do this.");
return;
}
final String filename = "data/html/auction/AgitSale1.htm";
final NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(filename);
html.replace("%AGIT_DEPOSIT%", String.valueOf(ClanHallManager.getInstance().getClanHallByOwner(player.getClan()).getLease()));
html.replace("%AGIT_PLEDGE_ADENA%", String.valueOf(player.getClan().getWarehouse().getAdena()));
html.replace("%objectId%", String.valueOf(getObjectId()));
player.sendPacket(html);
return;
}
else if (actualCommand.equalsIgnoreCase("rebid"))
{
if (!player.isClanLeader())
{
player.sendMessage("Only the clan leader has the privilege to do this.");
return;
}
try
{
final String filename = "data/html/auction/AgitBid2.htm";
final NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(filename);
final Auction a = AuctionManager.getInstance().getAuction(player.getClan().getAuctionBiddedAt());
if (a != null)
{
html.replace("%AGIT_AUCTION_MINBID%", String.valueOf(a.getStartingBid()));
html.replace("%AGIT_AUCTION_END_YY%", String.valueOf(a.getEndDate().get(Calendar.YEAR)));
html.replace("%AGIT_AUCTION_END_MM%", String.valueOf(a.getEndDate().get(Calendar.MONTH) + 1));
html.replace("%AGIT_AUCTION_END_DD%", String.valueOf(a.getEndDate().get(Calendar.DAY_OF_MONTH)));
html.replace("%AGIT_AUCTION_END_HH%", String.valueOf(a.getEndDate().get(Calendar.HOUR_OF_DAY)));
html.replace("npc_%objectId%_bid1", "npc_" + getObjectId() + "_bid1 " + a.getId());
}
else
{
_log.warning("Auctioneer Auction null for AuctionBiddedAt : " + player.getClan().getAuctionBiddedAt());
}
player.sendPacket(html);
}
catch (final Exception e)
{
player.sendMessage("Invalid auction!");
}
return;
}
else if (actualCommand.equalsIgnoreCase("location"))
{
final NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile("data/html/auction/location.htm");
html.replace("%location%", MapRegionTable.getInstance().getClosestTownName(player));
html.replace("%LOCATION%", getPictureName(player));
player.sendPacket(html);
return;
}
else if (actualCommand.equalsIgnoreCase("start"))
{
showMessageWindow(player);
return;
}
}
super.onBypassFeedback(player, command);
}
public void showMessageWindow(L2PcInstance player)
{
String filename = "data/html/auction/auction-no.htm";
final int condition = validateCondition(player);
if (condition == Cond_Busy_Because_Of_Siege)
{
filename = "data/html/auction/auction-busy.htm"; // Busy because of siege
}
else
{
filename = "data/html/auction/auction.htm";
}
final NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(filename);
html.replace("%objectId%", String.valueOf(getObjectId()));
html.replace("%npcId%", String.valueOf(getNpcId()));
html.replace("%npcname%", getName());
player.sendPacket(html);
}
private int validateCondition(L2PcInstance player)
{
if ((getCastle() != null) && (getCastle().getCastleId() > 0))
{
if (getCastle().getSiege().getIsInProgress())
{
return Cond_Busy_Because_Of_Siege; // Busy because of siege
}
return Cond_Regular;
}
return Cond_All_False;
}
private String getPictureName(L2PcInstance plyr)
{
final int nearestTownId = MapRegionTable.getInstance().getMapRegion(plyr.getX(), plyr.getY());
String nearestTown;
switch (nearestTownId)
{
case 5:
nearestTown = "GLUDIO";
break;
case 6:
nearestTown = "GLUDIN";
break;
case 7:
nearestTown = "DION";
break;
case 8:
nearestTown = "GIRAN";
break;
case 15:
nearestTown = "GODARD";
break;
default:
nearestTown = "ADEN";
break;
}
return nearestTown;
}
}

View File

@@ -0,0 +1,184 @@
/*
* 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.model.actor.instance;
import java.util.concurrent.Future;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.model.L2Character;
import com.l2jmobius.gameserver.model.L2ItemInstance;
import com.l2jmobius.gameserver.model.L2Skill;
import com.l2jmobius.gameserver.templates.L2NpcTemplate;
import com.l2jmobius.util.Rnd;
import javolution.util.FastMap;
/**
* This class ...
* @version $Revision: 1.15.2.10.2.16 $ $Date: 2005/04/06 16:13:40 $
*/
public final class L2BabyPetInstance extends L2PetInstance
{
protected L2Skill _weakHeal;
protected L2Skill _strongHeal;
private Future<?> _healingTask;
public L2BabyPetInstance(int objectId, L2NpcTemplate template, L2PcInstance owner, L2ItemInstance control)
{
super(objectId, template, owner, control);
// look through the skills that this template has and find the weak and strong heal.
final FastMap<Integer, L2Skill> skills = (FastMap<Integer, L2Skill>) getTemplate().getSkills();
L2Skill skill1 = null;
L2Skill skill2 = null;
for (final L2Skill skill : skills.values())
{
// just in case, also allow cp heal and mp recharges to be considered here...you never know ;)
if (skill.isActive() && (skill.getTargetType() == L2Skill.SkillTargetType.TARGET_OWNER_PET) && ((skill.getSkillType() == L2Skill.SkillType.HEAL) || (skill.getSkillType() == L2Skill.SkillType.HOT) || (skill.getSkillType() == L2Skill.SkillType.BALANCE_LIFE) || (skill.getSkillType() == L2Skill.SkillType.HEAL_PERCENT) || (skill.getSkillType() == L2Skill.SkillType.HEAL_STATIC) || (skill.getSkillType() == L2Skill.SkillType.COMBATPOINTHEAL) || (skill.getSkillType() == L2Skill.SkillType.CPHOT) || (skill.getSkillType() == L2Skill.SkillType.MANAHEAL) || (skill.getSkillType() == L2Skill.SkillType.MANA_BY_LEVEL) || (skill.getSkillType() == L2Skill.SkillType.MANARECHARGE) || (skill.getSkillType() == L2Skill.SkillType.MPHOT)))
{
// only consider two skills. If the pet has more, too bad...they won't be used by its AI.
// for now assign the first two skills in the order they come. Once we have both skills, re-arrange them
if (skill1 == null)
{
skill1 = skill;
}
else
{
skill2 = skill;
break;
}
}
}
// process the results. Only store the ID of the skills. The levels are generated on the fly, based on the pet's level!
if (skill1 != null)
{
if (skill2 == null)
{
// duplicate so that the same skill will be used in both normal and emergency situations
_weakHeal = skill1;
_strongHeal = skill1;
}
else
{
// arrange the weak and strong skills appropriately
if (skill1.getPower() > skill2.getPower())
{
_weakHeal = skill2;
_strongHeal = skill1;
}
else
{
_weakHeal = skill1;
_strongHeal = skill2;
}
}
// start the healing task
_healingTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new Heal(this), 0, 1000);
}
}
@Override
public boolean doDie(L2Character killer)
{
if (!super.doDie(killer))
{
return false;
}
if (_healingTask != null)
{
_healingTask.cancel(false);
_healingTask = null;
}
return true;
}
@Override
public synchronized void unSummon(L2PcInstance owner)
{
super.unSummon(owner);
if (_healingTask != null)
{
_healingTask.cancel(false);
_healingTask = null;
}
}
@Override
public void doRevive()
{
super.doRevive();
if (_healingTask == null)
{
_healingTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new Heal(this), 0, 1000);
}
}
private class Heal implements Runnable
{
private final L2BabyPetInstance _baby;
public Heal(L2BabyPetInstance baby)
{
_baby = baby;
}
@Override
public void run()
{
final L2PcInstance owner = _baby.getOwner();
// if the owner is dead, merely wait for the owner to be resurrected
// if the pet is still casting from the previous iteration, allow the cast to complete...
if (!owner.isDead() && !_baby.isCastingNow())
{
// casting automatically stops any other action (such as autofollow or a move-to).
// We need to gather the necessary info to restore the previous state.
final boolean previousFollowStatus = _baby.getFollowStatus();
// if the owner's HP is more than 80%, do nothing.
// if the owner's HP is very low (less than 20%) have a high chance for strong heal
// otherwise, have a low chance for weak heal
if (((owner.getCurrentHp() / owner.getMaxHp()) < 0.2) && (Rnd.get(4) < 3))
{
_baby.useMagic(_strongHeal, false, false);
}
else if (((owner.getCurrentHp() / owner.getMaxHp()) < 0.8) && (Rnd.get(4) < 1))
{
_baby.useMagic(_weakHeal, false, false);
}
// calling useMagic changes the follow status, if the babypet actually casts
// (as opposed to failing due some factors, such as too low MP, etc).
// if the status has actually been changed, revert it. Else, allow the pet to
// continue whatever it was trying to do.
// NOTE: This is important since the pet may have been told to attack a target.
// reverting the follow status will abort this attack! While aborting the attack
// in order to heal is natural, it is not acceptable to abort the attack on its own,
// merely because the timer stroke and without taking any other action...
if (previousFollowStatus != _baby.getFollowStatus())
{
setFollowStatus(previousFollowStatus);
}
}
}
}
}

View File

@@ -0,0 +1,61 @@
/*
* 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.model.actor.instance;
import com.l2jmobius.gameserver.model.L2Multisell;
import com.l2jmobius.gameserver.templates.L2NpcTemplate;
/**
* @author zabbix Lets drink to code!
*/
public class L2BlacksmithInstance extends L2FolkInstance
{
public L2BlacksmithInstance(int objectId, L2NpcTemplate template)
{
super(objectId, template);
}
@Override
public void onBypassFeedback(L2PcInstance player, String command)
{
if (command.startsWith("multisell"))
{
final int listId = Integer.parseInt(command.substring(9).trim());
L2Multisell.getInstance().createMultiSell(listId, player, false, this);
}
super.onBypassFeedback(player, command);
}
@Override
public String getHtmlPath(int npcId, int val)
{
String pom = "";
if (val == 0)
{
pom = "" + npcId;
}
else
{
pom = npcId + "-" + val;
}
return "data/html/blacksmith/" + pom + ".htm";
}
}

View File

@@ -0,0 +1,713 @@
/*
* 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.model.actor.instance;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.LineNumberReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.StringTokenizer;
import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.GameTimeController;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.ai.CtrlIntention;
import com.l2jmobius.gameserver.ai.L2BoatAI;
import com.l2jmobius.gameserver.model.L2CharPosition;
import com.l2jmobius.gameserver.model.L2Character;
import com.l2jmobius.gameserver.model.L2ItemInstance;
import com.l2jmobius.gameserver.model.actor.knownlist.BoatKnownList;
import com.l2jmobius.gameserver.model.actor.stat.BoatStat;
import com.l2jmobius.gameserver.network.clientpackets.Say2;
import com.l2jmobius.gameserver.network.serverpackets.CreatureSay;
import com.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
import com.l2jmobius.gameserver.network.serverpackets.PlaySound;
import com.l2jmobius.gameserver.network.serverpackets.VehicleDeparture;
import com.l2jmobius.gameserver.network.serverpackets.VehicleInfo;
import com.l2jmobius.gameserver.network.serverpackets.VehicleStarted;
import com.l2jmobius.gameserver.templates.L2CharTemplate;
import com.l2jmobius.gameserver.templates.L2Weapon;
import com.l2jmobius.gameserver.util.Util;
/**
* @author Maktakien
*/
public class L2BoatInstance extends L2Character
{
protected static final Logger _logBoat = Logger.getLogger(L2BoatInstance.class.getName());
protected final ArrayList<L2PcInstance> _passengers = new ArrayList<>();
protected ArrayList<L2BoatPoint> _currentPath;
protected byte _runState = 0;
protected L2BoatTrajet _t1;
protected L2BoatTrajet _t2;
// default
protected int _cycle = 1;
public L2BoatInstance(int objectId, L2CharTemplate template)
{
super(objectId, template);
getKnownList();
getStat();
setAI(new L2BoatAI(new AIAccessor()));
}
@Override
public final BoatKnownList getKnownList()
{
if ((super.getKnownList() == null) || !(super.getKnownList() instanceof BoatKnownList))
{
setKnownList(new BoatKnownList(this));
}
return (BoatKnownList) super.getKnownList();
}
@Override
public final BoatStat getStat()
{
if ((super.getStat() == null) || !(super.getStat() instanceof BoatStat))
{
setStat(new BoatStat(this));
}
return (BoatStat) super.getStat();
}
public void begin()
{
// fistly, check passengers
checkPassengers();
_runState = 0;
_currentPath = null;
if (_cycle == 1)
{
_currentPath = _t1._path;
}
else
{
_currentPath = _t2._path;
}
if (_currentPath == null)
{
getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
return;
}
final L2BoatPoint point = _currentPath.get(0);
if (point != null)
{
getStat().setMoveSpeed(point.getMoveSpeed());
getStat().setRotationSpeed(point.getRotationSpeed());
// departure
getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new L2CharPosition(point.getX(), point.getY(), point.getZ(), 0));
}
}
private void checkPassengers()
{
_passengers.clear();
final Collection<L2PcInstance> knownPlayers = getKnownList().getKnownPlayersInRadius(1000);
if ((knownPlayers != null) && !knownPlayers.isEmpty())
{
for (final L2PcInstance player : getKnownList().getKnownPlayersInRadius(1000))
{
if (player == null)
{
continue;
}
if (player.isInBoat() && (player.getBoat() == this))
{
addPassenger(player);
}
}
}
}
@Override
public boolean moveToNextRoutePoint()
{
_move = null;
_runState++;
if (_runState < _currentPath.size())
{
final L2BoatPoint point = _currentPath.get(_runState);
if (!isMovementDisabled())
{
getStat().setMoveSpeed(point.getMoveSpeed());
getStat().setRotationSpeed(point.getRotationSpeed());
final MoveData m = new MoveData();
m.disregardingGeodata = false;
m.onGeodataPathIndex = -1;
m._xDestination = point.getX();
m._yDestination = point.getY();
m._zDestination = point.getZ();
m._heading = 0;
final double dx = point.getX() - getX();
final double dy = point.getY() - getY();
final double distance = Math.sqrt((dx * dx) + (dy * dy));
if (distance > 1)
{
setHeading(Util.calculateHeadingFrom(getX(), getY(), point.getX(), point.getY()));
}
GameTimeController.getInstance();
m._moveStartTime = GameTimeController.getGameTicks();
_move = m;
GameTimeController.getInstance().registerMovingObject(this);
broadcastPacket(new VehicleDeparture(this));
return true;
}
}
if (_cycle == 1)
{
_cycle = 2;
}
else
{
_cycle = 1;
}
say(10);
ThreadPoolManager.getInstance().scheduleGeneral(new BoatCaptain(1, this), 300000);
return false;
}
@Override
public boolean updatePosition(int gameTicks)
{
final boolean result = super.updatePosition(gameTicks);
if (!_passengers.isEmpty())
{
for (final L2PcInstance player : _passengers)
{
if ((player != null) && (player.getBoat() == this))
{
player.setXYZ(getX(), getY(), getZ());
player.revalidateZone(false);
}
}
}
return result;
}
@Override
public void stopMove(L2CharPosition pos)
{
_move = null;
if (pos != null)
{
setXYZ(pos.x, pos.y, pos.z);
setHeading(pos.heading);
revalidateZone(true);
}
broadcastPacket(new VehicleStarted(getObjectId(), 0));
broadcastPacket(new VehicleInfo(this));
}
private void addPassenger(L2PcInstance player)
{
final int itemId;
if (_cycle == 1)
{
itemId = _t1._IdWTicket1;
}
else
{
itemId = _t2._IdWTicket1;
}
if (itemId != 0)
{
final L2ItemInstance it = player.getInventory().getItemByItemId(itemId);
if ((it != null) && (it.getCount() >= 1))
{
player.getInventory().destroyItem("Boat", it, 1, player, this);
final InventoryUpdate iu = new InventoryUpdate();
iu.addModifiedItem(it);
player.sendPacket(iu);
}
else
{
oustPlayer(player);
return;
}
}
_passengers.add(player);
}
public void oustPlayer(L2PcInstance player)
{
final int x, y, z;
if (_cycle == 1)
{
x = _t1._ntx1;
y = _t1._nty1;
z = _t1._ntz1;
}
else
{
x = _t2._ntx1;
y = _t2._nty1;
z = _t2._ntz1;
}
removePassenger(player);
if (player.isOnline() > 0)
{
player.teleToLocation(x, y, z);
}
else
{
player.setXYZInvisible(x, y, z); // disconnects handling
}
}
public void removePassenger(L2PcInstance player)
{
if (!_passengers.isEmpty() && _passengers.contains(player))
{
_passengers.remove(player);
}
}
/**
* @param i
*/
public void say(int i)
{
final Collection<L2PcInstance> knownPlayers = getKnownList().getKnownPlayers().values();
if ((knownPlayers == null) || knownPlayers.isEmpty())
{
return;
}
CreatureSay sm;
PlaySound ps;
switch (i)
{
case 10:
if (_cycle == 1)
{
sm = new CreatureSay(0, Say2.SHOUT, _t1._npc1, _t1._sysmess10_1);
}
else
{
sm = new CreatureSay(0, Say2.SHOUT, _t2._npc1, _t2._sysmess10_1);
}
ps = new PlaySound(0, "itemsound.ship_arrival_departure", 1, getObjectId(), getX(), getY(), getZ());
for (final L2PcInstance player : knownPlayers)
{
player.sendPacket(sm);
player.sendPacket(ps);
}
break;
case 5:
if (_cycle == 1)
{
sm = new CreatureSay(0, Say2.SHOUT, _t1._npc1, _t1._sysmess5_1);
}
else
{
sm = new CreatureSay(0, Say2.SHOUT, _t2._npc1, _t2._sysmess5_1);
}
ps = new PlaySound(0, "itemsound.ship_5min", 1, getObjectId(), getX(), getY(), getZ());
for (final L2PcInstance player : knownPlayers)
{
player.sendPacket(sm);
player.sendPacket(ps);
}
break;
case 1:
if (_cycle == 1)
{
sm = new CreatureSay(0, Say2.SHOUT, _t1._npc1, _t1._sysmess1_1);
}
else
{
sm = new CreatureSay(0, Say2.SHOUT, _t2._npc1, _t2._sysmess1_1);
}
ps = new PlaySound(0, "itemsound.ship_1min", 1, getObjectId(), getX(), getY(), getZ());
for (final L2PcInstance player : knownPlayers)
{
player.sendPacket(sm);
player.sendPacket(ps);
}
break;
case 0:
if (_cycle == 1)
{
sm = new CreatureSay(0, Say2.SHOUT, _t1._npc1, _t1._sysmess0_1);
}
else
{
sm = new CreatureSay(0, Say2.SHOUT, _t2._npc1, _t2._sysmess0_1);
}
for (final L2PcInstance player : knownPlayers)
{
player.sendPacket(sm);
}
break;
case -1:
if (_cycle == 1)
{
sm = new CreatureSay(0, Say2.SHOUT, _t1._npc1, _t1._sysmessb_1);
}
else
{
sm = new CreatureSay(0, Say2.SHOUT, _t2._npc1, _t2._sysmessb_1);
}
ps = new PlaySound(0, "itemsound.ship_arrival_departure", 1, getObjectId(), getX(), getY(), getZ());
for (final L2PcInstance player : knownPlayers)
{
player.sendPacket(sm);
player.sendPacket(ps);
}
break;
}
}
public void beginCycle()
{
say(10);
ThreadPoolManager.getInstance().scheduleGeneral(new BoatCaptain(1, this), 300000);
}
private class BoatCaptain implements Runnable
{
private final int _state;
private final L2BoatInstance _boat;
/**
* @param i
* @param instance
*/
public BoatCaptain(int i, L2BoatInstance instance)
{
_state = i;
_boat = instance;
}
@Override
public void run()
{
// final BoatCaptain bc;
switch (_state)
{
case 1:
_boat.say(5);
ThreadPoolManager.getInstance().scheduleGeneral(new BoatCaptain(2, _boat), 240000);
break;
case 2:
_boat.say(1);
ThreadPoolManager.getInstance().scheduleGeneral(new BoatCaptain(3, _boat), 40000);
break;
case 3:
_boat.say(0);
ThreadPoolManager.getInstance().scheduleGeneral(new BoatCaptain(4, _boat), 20000);
break;
case 4:
_boat.say(-1);
_boat.begin();
break;
}
}
}
/**
* @param idWaypoint1
* @param idWTicket1
* @param ntx1
* @param nty1
* @param ntz1
* @param idnpc1
* @param sysmess10_1
* @param sysmess5_1
* @param sysmess1_1
* @param sysmess0_1
* @param sysmessb_1
*/
public void SetTrajet1(int idWaypoint1, int idWTicket1, int ntx1, int nty1, int ntz1, String idnpc1, String sysmess10_1, String sysmess5_1, String sysmess1_1, String sysmess0_1, String sysmessb_1)
{
_t1 = new L2BoatTrajet(idWaypoint1, idWTicket1, ntx1, nty1, ntz1, idnpc1, sysmess10_1, sysmess5_1, sysmess1_1, sysmess0_1, sysmessb_1);
}
public void SetTrajet2(int idWaypoint1, int idWTicket1, int ntx1, int nty1, int ntz1, String idnpc1, String sysmess10_1, String sysmess5_1, String sysmess1_1, String sysmess0_1, String sysmessb_1)
{
_t2 = new L2BoatTrajet(idWaypoint1, idWTicket1, ntx1, nty1, ntz1, idnpc1, sysmess10_1, sysmess5_1, sysmess1_1, sysmess0_1, sysmessb_1);
}
private class L2BoatPoint
{
int speed1;
int speed2;
int x;
int y;
int z;
public L2BoatPoint()
{
}
public int getMoveSpeed()
{
return speed1;
}
public int getRotationSpeed()
{
return speed2;
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
public int getZ()
{
return z;
}
}
private class L2BoatTrajet
{
ArrayList<L2BoatPoint> _path;
public int _IdWaypoint1;
public int _IdWTicket1;
public int _ntx1;
public int _nty1;
public int _ntz1;
public String _npc1;
public String _sysmess10_1;
public String _sysmess5_1;
public String _sysmess1_1;
public String _sysmessb_1;
public String _sysmess0_1;
/**
* @param idWaypoint1
* @param idWTicket1
* @param ntx1
* @param nty1
* @param ntz1
* @param npc1
* @param sysmess10_1
* @param sysmess5_1
* @param sysmess1_1
* @param sysmess0_1
* @param sysmessb_1
*/
public L2BoatTrajet(int idWaypoint1, int idWTicket1, int ntx1, int nty1, int ntz1, String npc1, String sysmess10_1, String sysmess5_1, String sysmess1_1, String sysmess0_1, String sysmessb_1)
{
_IdWaypoint1 = idWaypoint1;
_IdWTicket1 = idWTicket1;
_ntx1 = ntx1;
_nty1 = nty1;
_ntz1 = ntz1;
_npc1 = npc1;
_sysmess10_1 = sysmess10_1;
_sysmess5_1 = sysmess5_1;
_sysmess1_1 = sysmess1_1;
_sysmessb_1 = sysmessb_1;
_sysmess0_1 = sysmess0_1;
loadBoatPath();
}
/**
* @param line
*/
public void parseLine(String line)
{
_path = new ArrayList<>();
final StringTokenizer st = new StringTokenizer(line, ";");
Integer.parseInt(st.nextToken());
final int max = Integer.parseInt(st.nextToken());
for (int i = 0; i < max; i++)
{
final L2BoatPoint bp = new L2BoatPoint();
bp.speed1 = Integer.parseInt(st.nextToken());
bp.speed2 = Integer.parseInt(st.nextToken());
bp.x = Integer.parseInt(st.nextToken());
bp.y = Integer.parseInt(st.nextToken());
bp.z = Integer.parseInt(st.nextToken());
_path.add(bp);
}
}
/**
*
*/
private void loadBoatPath()
{
final File boatData = new File(Config.DATAPACK_ROOT, "data/boatpath.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(_IdWaypoint1 + ";"))
{
continue;
}
parseLine(line);
return;
}
_logBoat.warning("No path for boat " + getName() + " !!!");
}
catch (final FileNotFoundException e)
{
_logBoat.warning("boatpath.csv is missing in data folder");
}
catch (final Exception e)
{
_logBoat.warning("error while creating boat table " + e);
}
}
}
/*
* (non-Javadoc)
* @see com.l2jmobius.gameserver.model.L2Character#updateAbnormalEffect()
*/
@Override
public void updateAbnormalEffect()
{
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
* @see com.l2jmobius.gameserver.model.L2Character#getActiveWeaponInstance()
*/
@Override
public L2ItemInstance getActiveWeaponInstance()
{
// TODO Auto-generated method stub
return null;
}
/*
* (non-Javadoc)
* @see com.l2jmobius.gameserver.model.L2Character#getActiveWeaponItem()
*/
@Override
public L2Weapon getActiveWeaponItem()
{
// TODO Auto-generated method stub
return null;
}
/*
* (non-Javadoc)
* @see com.l2jmobius.gameserver.model.L2Character#getSecondaryWeaponInstance()
*/
@Override
public L2ItemInstance getSecondaryWeaponInstance()
{
// TODO Auto-generated method stub
return null;
}
/*
* (non-Javadoc)
* @see com.l2jmobius.gameserver.model.L2Character#getSecondaryWeaponItem()
*/
@Override
public L2Weapon getSecondaryWeaponItem()
{
// TODO Auto-generated method stub
return null;
}
/*
* (non-Javadoc)
* @see com.l2jmobius.gameserver.model.L2Character#getLevel()
*/
@Override
public int getLevel()
{
// TODO Auto-generated method stub
return 0;
}
/*
* (non-Javadoc)
* @see com.l2jmobius.gameserver.model.L2Object#isAutoAttackable(com.l2jmobius.gameserver.model.L2Character)
*/
@Override
public boolean isAutoAttackable(L2Character attacker)
{
// TODO Auto-generated method stub
return false;
}
public void sendBoatInfo(L2PcInstance activeChar)
{
activeChar.sendPacket(new VehicleInfo(this));
if (isMoving())
{
activeChar.sendPacket(new VehicleDeparture(this));
}
}
public class AIAccessor extends L2Character.AIAccessor
{
@Override
public void detachAI()
{
}
}
}

View File

@@ -0,0 +1,228 @@
/*
* 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.model.actor.instance;
import java.util.concurrent.ScheduledFuture;
import com.l2jmobius.gameserver.SevenSigns;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.ai.CtrlIntention;
import com.l2jmobius.gameserver.datatables.SkillTable;
import com.l2jmobius.gameserver.model.L2Character;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.L2Skill;
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import com.l2jmobius.gameserver.network.serverpackets.MagicSkillUse;
import com.l2jmobius.gameserver.network.serverpackets.MyTargetSelected;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.network.serverpackets.ValidateLocation;
import com.l2jmobius.gameserver.templates.L2NpcTemplate;
/**
* @author Layane
*/
public class L2CabaleBufferInstance extends L2NpcInstance
{
@Override
public void onAction(L2PcInstance player)
{
if (!canTarget(player))
{
return;
}
if (this != player.getTarget())
{
// Set the target of the L2PcInstance player
player.setTarget(this);
// Send a Server->Client packet MyTargetSelected to the L2PcInstance player
// The color to display in the select window is White
final MyTargetSelected my = new MyTargetSelected(getObjectId(), 0);
player.sendPacket(my);
// Send a Server->Client packet ValidateLocation to correct the L2ArtefactInstance position and heading on the client
player.sendPacket(new ValidateLocation(this));
}
else
{
// Calculate the distance between the L2PcInstance and the L2NpcInstance
if (!canInteract(player))
{
// Notify the L2PcInstance AI with AI_INTENTION_INTERACT
player.getAI().setIntention(CtrlIntention.AI_INTENTION_INTERACT, this);
}
}
// Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet
player.sendPacket(new ActionFailed());
}
ScheduledFuture<?> aiTask;
private class CabalaAI implements Runnable
{
L2CabaleBufferInstance _caster;
protected CabalaAI(L2CabaleBufferInstance caster)
{
_caster = caster;
}
@Override
public void run()
{
boolean isBuffAWinner = false;
boolean isBuffALoser = false;
final int winningCabal = SevenSigns.getInstance().getCabalHighestScore();
int losingCabal = SevenSigns.CABAL_NULL;
if (winningCabal == SevenSigns.CABAL_DAWN)
{
losingCabal = SevenSigns.CABAL_DUSK;
}
else if (winningCabal == SevenSigns.CABAL_DUSK)
{
losingCabal = SevenSigns.CABAL_DAWN;
}
/**
* For each known player in range, cast either the positive or negative buff. <BR>
* The stats affected depend on the player type, either a fighter or a mystic. <BR>
* <BR>
* Curse of Destruction (Loser)<BR>
* - Fighters: -25% Accuracy, -25% Effect Resistance<BR>
* - Mystics: -25% Casting Speed, -25% Effect Resistance<BR>
* <BR>
* <BR>
* Blessing of Prophecy (Winner) - Fighters: +25% Max Load, +25% Effect Resistance<BR>
* - Mystics: +25% Magic Cancel Resist, +25% Effect Resistance<BR>
*/
for (final L2PcInstance player : getKnownList().getKnownPlayers().values())
{
final int playerCabal = SevenSigns.getInstance().getPlayerCabal(player);
if ((playerCabal == winningCabal) && (playerCabal != SevenSigns.CABAL_NULL) && (_caster.getNpcId() == SevenSigns.ORATOR_NPC_ID))
{
if (!player.isMageClass())
{
if (handleCast(player, 4364))
{
isBuffAWinner = true;
continue;
}
}
else
{
if (handleCast(player, 4365))
{
isBuffAWinner = true;
continue;
}
}
}
else if ((playerCabal == losingCabal) && (playerCabal != SevenSigns.CABAL_NULL) && (_caster.getNpcId() == SevenSigns.PREACHER_NPC_ID))
{
if (!player.isMageClass())
{
if (handleCast(player, 4361))
{
isBuffALoser = true;
continue;
}
}
else
{
if (handleCast(player, 4362))
{
isBuffALoser = true;
continue;
}
}
}
if (isBuffAWinner && isBuffALoser)
{
break;
}
}
}
private boolean handleCast(L2PcInstance player, int skillId)
{
final int skillLevel = (player.getLevel() > 40) ? 1 : 2;
if (player.isDead() || !player.isVisible() || !isInsideRadius(player, getDistanceToWatchObject(player), false, false))
{
return false;
}
final L2Skill skill = SkillTable.getInstance().getInfo(skillId, skillLevel);
if (player.getFirstEffect(skill) == null)
{
skill.getEffects(_caster, player);
broadcastPacket(new MagicSkillUse(_caster, player, skill.getId(), skillLevel, skill.getHitTime(), 0));
final SystemMessage sm = new SystemMessage(SystemMessage.YOU_FEEL_S1_EFFECT);
sm.addSkillName(skillId);
player.sendPacket(sm);
return true;
}
return false;
}
}
public L2CabaleBufferInstance(int objectId, L2NpcTemplate template)
{
super(objectId, template);
if (aiTask != null)
{
aiTask.cancel(true);
}
aiTask = ThreadPoolManager.getInstance().scheduleAiAtFixedRate(new CabalaAI(this), 3000, 3000);
}
@Override
public void deleteMe()
{
if (aiTask != null)
{
aiTask.cancel(true);
aiTask = null;
}
super.deleteMe();
}
@Override
public int getDistanceToWatchObject(L2Object object)
{
return 900;
}
@Override
public boolean isAutoAttackable(L2Character attacker)
{
return false;
}
}

View File

@@ -0,0 +1,197 @@
/*
* 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.model.actor.instance;
import com.l2jmobius.gameserver.ai.CtrlIntention;
import com.l2jmobius.gameserver.instancemanager.CastleManorManager;
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import com.l2jmobius.gameserver.network.serverpackets.MyTargetSelected;
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
import com.l2jmobius.gameserver.network.serverpackets.ValidateLocation;
import com.l2jmobius.gameserver.templates.L2NpcTemplate;
/**
* @author l3x
*/
public class L2CastleBlacksmithInstance extends L2FolkInstance
{
protected static final int COND_ALL_FALSE = 0;
protected static final int COND_BUSY_BECAUSE_OF_SIEGE = 1;
protected static final int COND_OWNER = 2;
public L2CastleBlacksmithInstance(int objectId, L2NpcTemplate template)
{
super(objectId, template);
}
@Override
public void onAction(L2PcInstance player)
{
if (!canTarget(player))
{
return;
}
player.setLastFolkNPC(this);
// Check if the L2PcInstance already target the L2NpcInstance
if (this != player.getTarget())
{
// Set the target of the L2PcInstance player
player.setTarget(this);
// Send a Server->Client packet MyTargetSelected to the L2PcInstance player
final MyTargetSelected my = new MyTargetSelected(getObjectId(), 0);
player.sendPacket(my);
// Send a Server->Client packet ValidateLocation to correct the L2NpcInstance position and heading on the client
player.sendPacket(new ValidateLocation(this));
}
else
{
// Calculate the distance between the L2PcInstance and the L2NpcInstance
if (!canInteract(player))
{
// Notify the L2PcInstance AI with AI_INTENTION_INTERACT
player.getAI().setIntention(CtrlIntention.AI_INTENTION_INTERACT, this);
}
else
{
if (CastleManorManager.getInstance().isDisabled())
{
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
html.setFile("data/html/npcdefault.htm");
html.replace("%objectId%", String.valueOf(getObjectId()));
html.replace("%npcname%", getName());
player.sendPacket(html);
}
else
{
showMessageWindow(player, 0);
}
}
}
// Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet
player.sendPacket(new ActionFailed());
}
@Override
public void onBypassFeedback(L2PcInstance player, String command)
{
if (CastleManorManager.getInstance().isDisabled())
{
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
html.setFile("data/html/npcdefault.htm");
html.replace("%objectId%", String.valueOf(getObjectId()));
html.replace("%npcname%", getName());
player.sendPacket(html);
return;
}
final int condition = validateCondition(player);
if (condition <= COND_ALL_FALSE)
{
return;
}
if (condition == COND_BUSY_BECAUSE_OF_SIEGE)
{
return;
}
else if (condition == COND_OWNER)
{
if (command.startsWith("Chat"))
{
int val = 0;
try
{
val = Integer.parseInt(command.substring(5));
}
catch (final IndexOutOfBoundsException ioobe)
{
}
catch (final NumberFormatException nfe)
{
}
showMessageWindow(player, val);
}
else
{
super.onBypassFeedback(player, command);
}
}
}
private void showMessageWindow(L2PcInstance player, int val)
{
String filename = "data/html/castleblacksmith/castleblacksmith-no.htm";
final int condition = validateCondition(player);
if (condition > COND_ALL_FALSE)
{
if (condition == COND_BUSY_BECAUSE_OF_SIEGE)
{
filename = "data/html/castleblacksmith/castleblacksmith-busy.htm"; // Busy because of siege
}
else if (condition == COND_OWNER)
{ // Clan owns castle
if (val == 0)
{
filename = "data/html/castleblacksmith/castleblacksmith.htm";
}
else
{
filename = "data/html/castleblacksmith/castleblacksmith-" + val + ".htm";
}
}
}
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
html.setFile(filename);
html.replace("%objectId%", String.valueOf(getObjectId()));
html.replace("%npcname%", getName());
html.replace("%castleid%", Integer.toString(getCastle().getCastleId()));
player.sendPacket(html);
}
protected int validateCondition(L2PcInstance player)
{
if (player.isGM())
{
return COND_OWNER;
}
if ((getCastle() != null) && (getCastle().getCastleId() > 0))
{
if (player.getClan() != null)
{
if (getCastle().getSiege().getIsInProgress())
{
return COND_BUSY_BECAUSE_OF_SIEGE; // Busy because of siege
}
else if ((getCastle().getOwnerId() == player.getClanId() // Clan owns castle
) && player.isClanLeader())
{
return COND_OWNER; // Owner
}
}
}
return COND_ALL_FALSE;
}
}

View File

@@ -0,0 +1,215 @@
/*
* 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.model.actor.instance;
import java.util.StringTokenizer;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.ai.CtrlIntention;
import com.l2jmobius.gameserver.datatables.MapRegionTable;
import com.l2jmobius.gameserver.model.L2World;
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import com.l2jmobius.gameserver.network.serverpackets.CreatureSay;
import com.l2jmobius.gameserver.network.serverpackets.MyTargetSelected;
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
import com.l2jmobius.gameserver.network.serverpackets.ValidateLocation;
import com.l2jmobius.gameserver.templates.L2NpcTemplate;
/**
* @author NightMarez
* @version $Revision: 1.3.2.2.2.5 $ $Date: 2005/03/27 15:29:32 $
*/
public final class L2CastleTeleporterInstance extends L2FolkInstance
{
private boolean _currentTask = false;
/**
* @param objectId
* @param template
*/
public L2CastleTeleporterInstance(int objectId, L2NpcTemplate template)
{
super(objectId, template);
}
@Override
public void onBypassFeedback(L2PcInstance player, String command)
{
final StringTokenizer st = new StringTokenizer(command, " ");
final String actualCommand = st.nextToken(); // Get actual command
if (actualCommand.equalsIgnoreCase("tele"))
{
int delay;
if (!getTask())
{
if (getCastle().getSiege().getIsInProgress() && (getCastle().getSiege().getControlTowerCount() == 0))
{
delay = 480000;
}
else
{
delay = 30000;
}
setTask(true);
ThreadPoolManager.getInstance().scheduleGeneral(new oustAllPlayers(), delay);
}
final String filename = "data/html/teleporter/MassGK-1.htm";
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
html.setFile(filename);
player.sendPacket(html);
return;
}
super.onBypassFeedback(player, command);
}
@Override
public void showChatWindow(L2PcInstance player)
{
String filename;
if (!getTask())
{
if (getCastle().getSiege().getIsInProgress() && (getCastle().getSiege().getControlTowerCount() == 0))
{
filename = "data/html/teleporter/MassGK-2.htm";
}
else
{
filename = "data/html/teleporter/MassGK.htm";
}
}
else
{
filename = "data/html/teleporter/MassGK-1.htm";
}
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
html.setFile(filename);
html.replace("%objectId%", String.valueOf(getObjectId()));
player.sendPacket(html);
}
public void oustAllPlayers()
{
getCastle().oustAllPlayers();
}
class oustAllPlayers implements Runnable
{
@Override
public void run()
{
try
{
if (getCastle().getSiege().getIsInProgress())
{
final CreatureSay cs = new CreatureSay(getObjectId(), 1, getName(), "The defenders of " + getCastle().getName() + " castle will be teleported to the inner castle.");
final int region = MapRegionTable.getInstance().getMapRegion(getX(), getY());
for (final L2PcInstance player : L2World.getInstance().getAllPlayers())
{
if (region == MapRegionTable.getInstance().getMapRegion(player.getX(), player.getY()))
{
player.sendPacket(cs);
}
}
}
oustAllPlayers();
setTask(false);
}
catch (final NullPointerException e)
{
e.printStackTrace();
}
}
}
/**
* This is called when a player interacts with this NPC
* @param player
*/
@Override
public void onAction(L2PcInstance player)
{
if (!canTarget(player))
{
return;
}
player.setLastFolkNPC(this);
// Check if the L2PcInstance already target the L2NpcInstance
if (this != player.getTarget())
{
// Set the target of the L2PcInstance player
player.setTarget(this);
// Send a Server->Client packet MyTargetSelected to the L2PcInstance player
final MyTargetSelected my = new MyTargetSelected(getObjectId(), 0);
player.sendPacket(my);
// Send a Server->Client packet ValidateLocation to correct the L2NpcInstance position and heading on the client
player.sendPacket(new ValidateLocation(this));
}
else
{
// Calculate the distance between the L2PcInstance and the L2NpcInstance
if (!canInteract(player))
{
// Notify the L2PcInstance AI with AI_INTENTION_INTERACT
player.getAI().setIntention(CtrlIntention.AI_INTENTION_INTERACT, this);
}
else
{
showChatWindow(player);
}
}
// Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet
player.sendPacket(new ActionFailed());
}
public boolean getTask()
{
return _currentTask;
}
public void setTask(boolean state)
{
_currentTask = state;
}
}

View File

@@ -0,0 +1,235 @@
/*
* 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.model.actor.instance;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.model.L2Clan;
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.network.serverpackets.WareHouseDepositList;
import com.l2jmobius.gameserver.network.serverpackets.WareHouseWithdrawalList;
import com.l2jmobius.gameserver.templates.L2NpcTemplate;
/**
* @author l3x
*/
public class L2CastleWarehouseInstance extends L2FolkInstance
{
protected static int Cond_All_False = 0;
protected static int Cond_Busy_Because_Of_Siege = 1;
protected static int Cond_Owner = 2;
/**
* @param objectId
* @param template
*/
public L2CastleWarehouseInstance(int objectId, L2NpcTemplate template)
{
super(objectId, template);
}
private void showRetrieveWindow(L2PcInstance player)
{
player.sendPacket(new ActionFailed());
player.setActiveWarehouse(player.getWarehouse());
if (player.getActiveWarehouse().getSize() == 0)
{
player.sendPacket(new SystemMessage(SystemMessage.NOTHING_IN_WAREHOUSE));
return;
}
if (Config.DEBUG)
{
_log.fine("Showing stored items");
}
player.sendPacket(new WareHouseWithdrawalList(player, WareHouseWithdrawalList.Private));
}
private void showDepositWindow(L2PcInstance player)
{
player.sendPacket(new ActionFailed());
player.setActiveWarehouse(player.getWarehouse());
player.tempInventoryDisable();
if (Config.DEBUG)
{
_log.fine("Showing items to deposit");
}
player.sendPacket(new WareHouseDepositList(player, WareHouseDepositList.Private));
}
private void showDepositWindowClan(L2PcInstance player)
{
player.sendPacket(new ActionFailed());
if (player.getClan() != null)
{
if (player.getClan().getLevel() == 0)
{
player.sendPacket(new SystemMessage(SystemMessage.ONLY_LEVEL_1_CLAN_OR_HIGHER_CAN_USE_WAREHOUSE));
return;
}
player.setActiveWarehouse(player.getClan().getWarehouse());
player.tempInventoryDisable();
if (Config.DEBUG)
{
_log.fine("Showing items to deposit - clan");
}
final WareHouseDepositList dl = new WareHouseDepositList(player, WareHouseDepositList.Clan);
player.sendPacket(dl);
}
}
private void showWithdrawWindowClan(L2PcInstance player)
{
player.sendPacket(new ActionFailed());
if ((player.getClanPrivileges() & L2Clan.CP_CL_VIEW_WAREHOUSE) != L2Clan.CP_CL_VIEW_WAREHOUSE)
{
player.sendPacket(new SystemMessage(SystemMessage.YOU_DO_NOT_HAVE_THE_RIGHT_TO_USE_CLAN_WAREHOUSE));
return;
}
if (player.getClan().getLevel() == 0)
{
player.sendPacket(new SystemMessage(SystemMessage.ONLY_LEVEL_1_CLAN_OR_HIGHER_CAN_USE_WAREHOUSE));
return;
}
player.setActiveWarehouse(player.getClan().getWarehouse());
if (Config.DEBUG)
{
_log.fine("Showing items to withdraw - clan");
}
player.sendPacket(new WareHouseWithdrawalList(player, WareHouseWithdrawalList.Clan));
}
@Override
public void onBypassFeedback(L2PcInstance player, String command)
{
// little check to prevent enchant exploit
if (player.getActiveEnchantItem() != null)
{
_log.info("Player " + player.getName() + " trying to use enchant exploit, ban this player!");
player.logout();
return;
}
if (command.startsWith("WithdrawP"))
{
showRetrieveWindow(player);
}
else if (command.equals("DepositP"))
{
showDepositWindow(player);
}
else if (command.equals("WithdrawC"))
{
showWithdrawWindowClan(player);
}
else if (command.equals("DepositC"))
{
showDepositWindowClan(player);
}
else if (command.startsWith("Chat"))
{
int val = 0;
try
{
val = Integer.parseInt(command.substring(5));
}
catch (final IndexOutOfBoundsException ioobe)
{
}
catch (final NumberFormatException nfe)
{
}
showChatWindow(player, val);
}
else
{
super.onBypassFeedback(player, command);
}
}
@Override
public void showChatWindow(L2PcInstance player, int val)
{
player.sendPacket(new ActionFailed());
String filename = "data/html/castlewarehouse/castlewarehouse-no.htm";
final int condition = validateCondition(player);
if (condition > Cond_All_False)
{
if (condition == Cond_Busy_Because_Of_Siege)
{
filename = "data/html/castlewarehouse/castlewarehouse-busy.htm"; // Busy because of siege
}
else if (condition == Cond_Owner) // Clan owns castle
{
if (val == 0)
{
filename = "data/html/castlewarehouse/castlewarehouse.htm";
}
else
{
filename = "data/html/castlewarehouse/castlewarehouse-" + val + ".htm";
}
}
}
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
html.setFile(filename);
html.replace("%objectId%", String.valueOf(getObjectId()));
html.replace("%npcname%", getName());
player.sendPacket(html);
}
protected int validateCondition(L2PcInstance player)
{
if (player.isGM())
{
return Cond_Owner;
}
if ((getCastle() != null) && (getCastle().getCastleId() > 0))
{
if (player.getClan() != null)
{
if (getCastle().getSiege().getIsInProgress())
{
return Cond_Busy_Because_Of_Siege; // Busy because of siege
}
else if (getCastle().getOwnerId() == player.getClanId())
{
return Cond_Owner;
}
}
}
return Cond_All_False;
}
}

View File

@@ -0,0 +1,253 @@
/*
* 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.model.actor.instance;
import com.l2jmobius.gameserver.datatables.NpcTable;
import com.l2jmobius.gameserver.datatables.SkillTable;
import com.l2jmobius.gameserver.model.L2Character;
import com.l2jmobius.gameserver.model.L2Skill;
import com.l2jmobius.gameserver.network.serverpackets.MagicSkillUse;
import com.l2jmobius.gameserver.templates.L2NpcTemplate;
import com.l2jmobius.util.Rnd;
/**
* @author Julian This class manages all chest.
*/
public final class L2ChestInstance extends L2MonsterInstance
{
private volatile boolean _isInteracted;
private volatile boolean _specialDrop;
public L2ChestInstance(int objectId, L2NpcTemplate template)
{
super(objectId, template);
_isInteracted = false;
_specialDrop = false;
}
@Override
public void onSpawn()
{
super.onSpawn();
_isInteracted = false;
_specialDrop = false;
setMustRewardExpSp(true);
}
@Override
public boolean hasRandomAnimation()
{
return false;
}
public synchronized boolean isInteracted()
{
return _isInteracted;
}
public synchronized void setInteracted()
{
_isInteracted = true;
}
public synchronized boolean isSpecialDrop()
{
return _specialDrop;
}
public synchronized void setSpecialDrop()
{
_specialDrop = true;
}
@Override
public void doItemDrop(L2NpcTemplate npcTemplate, L2Character lastAttacker)
{
int id = getTemplate().npcId;
if (_specialDrop)
{
if ((id >= 1801) && (id <= 1822))
{
id += 11299;
}
switch (id)
{
case 1671:
id = 13213;
break;
case 1694:
id = 13215;
break;
case 1717:
id = 13217;
break;
case 1740:
id = 13219;
break;
case 1763:
id = 13221;
break;
case 1786:
id = 13223;
break;
}
}
super.doItemDrop(NpcTable.getInstance().getTemplate(id), lastAttacker);
}
// cast - trap chest
public void chestTrap(L2Character player)
{
int trapSkillId = 0;
final int rnd = Rnd.get(120);
if (getTemplate().level >= 61)
{
if (rnd >= 90)
{
trapSkillId = 4139; // explosion
}
else if (rnd >= 50)
{
trapSkillId = 4118; // area paralysis
}
else if (rnd >= 20)
{
trapSkillId = 1167; // poison cloud
}
else
{
trapSkillId = 223; // sting
}
}
else if (getTemplate().level >= 41)
{
if (rnd >= 90)
{
trapSkillId = 4139; // explosion
}
else if (rnd >= 60)
{
trapSkillId = 96; // bleed
}
else if (rnd >= 20)
{
trapSkillId = 1167; // poison cloud
}
else
{
trapSkillId = 4118; // area paralysis
}
}
else if (getTemplate().level >= 21)
{
if (rnd >= 80)
{
trapSkillId = 4139; // explosion
}
else if (rnd >= 50)
{
trapSkillId = 96; // bleed
}
else if (rnd >= 20)
{
trapSkillId = 1167; // poison cloud
}
else
{
trapSkillId = 129; // poison
}
}
else
{
if (rnd >= 80)
{
trapSkillId = 4139; // explosion
}
else if (rnd >= 50)
{
trapSkillId = 96; // bleed
}
else
{
trapSkillId = 129; // poison
}
}
handleCast(player, trapSkillId);
}
private boolean handleCast(L2Character player, int skillId)
{
int skillLevel = 1;
final int lvl = getTemplate().level;
if ((lvl > 20) && (lvl <= 40))
{
skillLevel = 3;
}
else if ((lvl > 40) && (lvl <= 60))
{
skillLevel = 5;
}
else if (lvl > 60)
{
skillLevel = 6;
}
if (player.isDead() || !player.isVisible() || !player.isInsideRadius(this, getDistanceToWatchObject(player), false, false))
{
return false;
}
final L2Skill skill = SkillTable.getInstance().getInfo(skillId, skillLevel);
if (player.getFirstEffect(skill) == null)
{
skill.getEffects(this, player);
broadcastPacket(new MagicSkillUse(this, player, skill.getId(), skillLevel, skill.getHitTime(), 0));
return true;
}
return false;
}
@Override
public boolean isMovementDisabled()
{
if (super.isMovementDisabled())
{
return true;
}
if (isInteracted())
{
return false;
}
return true;
}
}

View File

@@ -0,0 +1,973 @@
/*
* 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.model.actor.instance;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.StringTokenizer;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.datatables.SkillTable;
import com.l2jmobius.gameserver.datatables.TeleportLocationTable;
import com.l2jmobius.gameserver.instancemanager.ClanHallManager;
import com.l2jmobius.gameserver.instancemanager.SiegeManager;
import com.l2jmobius.gameserver.model.L2Clan;
import com.l2jmobius.gameserver.model.L2Skill;
import com.l2jmobius.gameserver.model.L2Skill.SkillType;
import com.l2jmobius.gameserver.model.L2TeleportLocation;
import com.l2jmobius.gameserver.model.entity.ClanHall;
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import com.l2jmobius.gameserver.network.serverpackets.ClanHallDecoration;
import com.l2jmobius.gameserver.network.serverpackets.MyTargetSelected;
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.network.serverpackets.ValidateLocation;
import com.l2jmobius.gameserver.network.serverpackets.WareHouseDepositList;
import com.l2jmobius.gameserver.network.serverpackets.WareHouseWithdrawalList;
import com.l2jmobius.gameserver.templates.L2NpcTemplate;
public class L2ClanHallManagerInstance extends L2FolkInstance
{
protected static int Cond_All_False = 0;
protected static int Cond_Busy_Because_Of_Siege = 1;
protected static int Cond_Owner = 2;
private int _clanHallId = -1;
/**
* @param objectId
* @param template
*/
public L2ClanHallManagerInstance(int objectId, L2NpcTemplate template)
{
super(objectId, template);
}
@Override
public void onBypassFeedback(L2PcInstance player, String command)
{
if (getClanHall() == null)
{
return;
}
final SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm");
final int condition = validateCondition(player);
if (condition <= Cond_All_False)
{
return;
}
else if (condition == Cond_Owner)
{
final StringTokenizer st = new StringTokenizer(command, " ");
final String actualCommand = st.nextToken(); // Get actual command
String val = "";
if (st.countTokens() >= 1)
{
val = st.nextToken();
}
if (actualCommand.equalsIgnoreCase("banish_foreigner"))
{
if ((player.getClanPrivileges() & L2Clan.CP_CH_DISMISS) == L2Clan.CP_CH_DISMISS)
{
getClanHall().banishForeigners();
}
return;
}
else if (actualCommand.equalsIgnoreCase("manage_vault"))
{
if ((player.getClanPrivileges() & L2Clan.CP_CL_VIEW_WAREHOUSE) == L2Clan.CP_CL_VIEW_WAREHOUSE)
{
if (val.equalsIgnoreCase("deposit"))
{
showVaultWindowDeposit(player);
}
else if (val.equalsIgnoreCase("withdraw"))
{
showVaultWindowWithdraw(player);
}
else
{
final NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile("data/html/clanHallManager/vault.htm");
sendHtmlMessage(player, html);
}
}
else
{
player.sendPacket(new SystemMessage(SystemMessage.YOU_ARE_NOT_AUTHORIZED));
}
return;
}
else if (actualCommand.equalsIgnoreCase("door"))
{
if ((player.getClanPrivileges() & L2Clan.CP_CH_OPEN_DOOR) == L2Clan.CP_CH_OPEN_DOOR)
{
if (val.equalsIgnoreCase("open"))
{
getClanHall().openCloseDoors(true);
}
else if (val.equalsIgnoreCase("close"))
{
getClanHall().openCloseDoors(false);
}
else
{
final NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile("data/html/clanHallManager/door.htm");
sendHtmlMessage(player, html);
}
}
else
{
player.sendPacket(new SystemMessage(SystemMessage.YOU_ARE_NOT_AUTHORIZED));
}
return;
}
else if (actualCommand.equalsIgnoreCase("functions"))
{
if ((player.getClanPrivileges() & L2Clan.CP_CH_OTHER_RIGHTS) != L2Clan.CP_CH_OTHER_RIGHTS)
{
player.sendPacket(new SystemMessage(SystemMessage.YOU_ARE_NOT_AUTHORIZED));
return;
}
if (val.equalsIgnoreCase("tele"))
{
final NpcHtmlMessage html = new NpcHtmlMessage(1);
if (getClanHall().getFunction(ClanHall.FUNC_TELEPORT) == null)
{
html.setFile("data/html/clanHallManager/chamberlain-nac.htm");
}
else
{
html.setFile("data/html/clanHallManager/tele" + getClanHall().getLocation() + getClanHall().getFunction(ClanHall.FUNC_TELEPORT).getLvl() + ".htm");
}
sendHtmlMessage(player, html);
}
else if (val.equalsIgnoreCase("item_creation"))
{
if (getClanHall().getFunction(ClanHall.FUNC_ITEM_CREATE) == null)
{
final NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile("data/html/clanHallManager/chamberlain-nac.htm");
sendHtmlMessage(player, html);
return;
}
if (st.countTokens() < 1)
{
return;
}
final int valbuy = Integer.parseInt(st.nextToken()) + (getClanHall().getFunction(ClanHall.FUNC_ITEM_CREATE).getLvl() * 100000);
showBuyWindow(player, valbuy);
}
else if (val.equalsIgnoreCase("support"))
{
final NpcHtmlMessage html = new NpcHtmlMessage(1);
if (getClanHall().getFunction(ClanHall.FUNC_SUPPORT) == null)
{
html.setFile("data/html/clanHallManager/chamberlain-nac.htm");
}
else
{
html.setFile("data/html/clanHallManager/support" + getClanHall().getFunction(ClanHall.FUNC_SUPPORT).getLvl() + ".htm");
html.replace("%mp%", String.valueOf(getCurrentMp()));
}
sendHtmlMessage(player, html);
}
else if (val.equalsIgnoreCase("back"))
{
showMessageWindow(player);
}
else
{
final NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile("data/html/clanHallManager/functions.htm");
if (getClanHall().getFunction(ClanHall.FUNC_RESTORE_EXP) != null)
{
html.replace("%xp_regen%", String.valueOf(getClanHall().getFunction(ClanHall.FUNC_RESTORE_EXP).getLvl()) + "%");
}
else
{
html.replace("%xp_regen%", "0");
}
if (getClanHall().getFunction(ClanHall.FUNC_RESTORE_HP) != null)
{
html.replace("%hp_regen%", String.valueOf(getClanHall().getFunction(ClanHall.FUNC_RESTORE_HP).getLvl()) + "%");
}
else
{
html.replace("%hp_regen%", "0");
}
if (getClanHall().getFunction(ClanHall.FUNC_RESTORE_MP) != null)
{
html.replace("%mp_regen%", String.valueOf(getClanHall().getFunction(ClanHall.FUNC_RESTORE_MP).getLvl()) + "%");
}
else
{
html.replace("%mp_regen", "0");
}
sendHtmlMessage(player, html);
}
return;
}
else if (actualCommand.equalsIgnoreCase("manage"))
{
if ((player.getClanPrivileges() & L2Clan.CP_CH_OTHER_RIGHTS) == L2Clan.CP_CH_OTHER_RIGHTS)
{
if (val.equalsIgnoreCase("recovery"))
{
if (st.countTokens() >= 1)
{
val = st.nextToken();
if (val.equalsIgnoreCase("hp"))
{
if (st.countTokens() >= 1)
{
int fee = 0;
if (Config.DEBUG)
{
_log.warning("Mp editing invoked");
}
val = st.nextToken();
final int percent = Integer.valueOf(val);
switch (percent)
{
case 0:
break;
case 20:
fee = Config.CH_HPREG1_FEE;
break;
case 40:
fee = Config.CH_HPREG2_FEE;
break;
case 80:
fee = Config.CH_HPREG3_FEE;
break;
case 100:
fee = Config.CH_HPREG4_FEE;
break;
case 120:
fee = Config.CH_HPREG5_FEE;
break;
case 140:
fee = Config.CH_HPREG6_FEE;
break;
case 160:
fee = Config.CH_HPREG7_FEE;
break;
case 180:
fee = Config.CH_HPREG8_FEE;
break;
case 200:
fee = Config.CH_HPREG9_FEE;
break;
case 220:
fee = Config.CH_HPREG10_FEE;
break;
case 240:
fee = Config.CH_HPREG11_FEE;
break;
case 260:
fee = Config.CH_HPREG12_FEE;
break;
default:
fee = Config.CH_HPREG13_FEE;
break;
}
if (!getClanHall().updateFunctions(ClanHall.FUNC_RESTORE_HP, percent, fee, Config.CH_HPREG_FEE_RATIO, Calendar.getInstance().getTimeInMillis() + Config.CH_HPREG_FEE_RATIO, (getClanHall().getFunction(ClanHall.FUNC_RESTORE_HP) == null)))
{
player.sendMessage("Not enough adena in clan warehouse.");
}
else
{
revalidateDeco(player);
}
}
}
else if (val.equalsIgnoreCase("mp"))
{
if (st.countTokens() >= 1)
{
int fee = 0;
if (Config.DEBUG)
{
_log.warning("Mp editing invoked");
}
val = st.nextToken();
final int percent = Integer.valueOf(val);
switch (percent)
{
case 0:
break;
case 5:
fee = Config.CH_MPREG1_FEE;
break;
case 10:
fee = Config.CH_MPREG2_FEE;
break;
case 15:
fee = Config.CH_MPREG3_FEE;
break;
case 30:
fee = Config.CH_MPREG4_FEE;
break;
default:
fee = Config.CH_MPREG5_FEE;
break;
}
if (!getClanHall().updateFunctions(ClanHall.FUNC_RESTORE_MP, percent, fee, Config.CH_MPREG_FEE_RATIO, Calendar.getInstance().getTimeInMillis() + Config.CH_MPREG_FEE_RATIO, (getClanHall().getFunction(ClanHall.FUNC_RESTORE_MP) == null)))
{
player.sendMessage("Not enough adena in clan warehouse.");
}
else
{
revalidateDeco(player);
}
}
}
else if (val.equalsIgnoreCase("exp"))
{
if (st.countTokens() >= 1)
{
int fee = 0;
if (Config.DEBUG)
{
_log.warning("Exp editing invoked");
}
val = st.nextToken();
final int percent = Integer.valueOf(val);
switch (percent)
{
case 0:
break;
case 5:
fee = Config.CH_EXPREG1_FEE;
break;
case 10:
fee = Config.CH_EXPREG2_FEE;
break;
case 15:
fee = Config.CH_EXPREG3_FEE;
break;
case 25:
fee = Config.CH_EXPREG4_FEE;
break;
case 35:
fee = Config.CH_EXPREG5_FEE;
break;
case 40:
fee = Config.CH_EXPREG6_FEE;
break;
default:
fee = Config.CH_EXPREG7_FEE;
break;
}
if (!getClanHall().updateFunctions(ClanHall.FUNC_RESTORE_EXP, percent, fee, Config.CH_EXPREG_FEE_RATIO, Calendar.getInstance().getTimeInMillis() + Config.CH_EXPREG_FEE_RATIO, (getClanHall().getFunction(ClanHall.FUNC_RESTORE_EXP) == null)))
{
player.sendMessage("Not enough adena in clan warehouse.");
}
else
{
revalidateDeco(player);
}
}
}
}
final NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile("data/html/clanHallManager/edit_recovery" + getClanHall().getGrade() + ".htm");
if ((getClanHall().getFunction(ClanHall.FUNC_RESTORE_HP) != null) && (getClanHall().getFunction(ClanHall.FUNC_RESTORE_HP).getLvl() != 0))
{
html.replace("%hp%", String.valueOf(getClanHall().getFunction(ClanHall.FUNC_RESTORE_HP).getLvl()) + "%");
html.replace("%hpPrice%", String.valueOf(getClanHall().getFunction(ClanHall.FUNC_RESTORE_HP).getLease()));
html.replace("%hpDate%", format.format(getClanHall().getFunction(ClanHall.FUNC_RESTORE_HP).getEndTime()));
}
else
{
html.replace("%hp%", "0");
html.replace("%hpPrice%", "0");
html.replace("%hpDate%", "0");
}
if ((getClanHall().getFunction(ClanHall.FUNC_RESTORE_EXP) != null) && (getClanHall().getFunction(ClanHall.FUNC_RESTORE_EXP).getLvl() != 0))
{
html.replace("%exp%", String.valueOf(getClanHall().getFunction(ClanHall.FUNC_RESTORE_EXP).getLvl()) + "%");
html.replace("%expPrice%", String.valueOf(getClanHall().getFunction(ClanHall.FUNC_RESTORE_EXP).getLease()));
html.replace("%expDate%", format.format(getClanHall().getFunction(ClanHall.FUNC_RESTORE_EXP).getEndTime()));
}
else
{
html.replace("%exp%", "0");
html.replace("%expPrice%", "0");
html.replace("%expDate%", "0");
}
if ((getClanHall().getFunction(ClanHall.FUNC_RESTORE_MP) != null) && (getClanHall().getFunction(ClanHall.FUNC_RESTORE_MP).getLvl() != 0))
{
html.replace("%mp%", String.valueOf(getClanHall().getFunction(ClanHall.FUNC_RESTORE_MP).getLvl()) + "%");
html.replace("%mpPrice%", String.valueOf(getClanHall().getFunction(ClanHall.FUNC_RESTORE_MP).getLease()));
html.replace("%mpDate%", format.format(getClanHall().getFunction(ClanHall.FUNC_RESTORE_MP).getEndTime()));
}
else
{
html.replace("%mp%", "0");
html.replace("%mpPrice%", "0");
html.replace("%mpDate%", "0");
}
sendHtmlMessage(player, html);
}
else if (val.equalsIgnoreCase("other"))
{
if (st.countTokens() >= 1)
{
val = st.nextToken();
if (val.equalsIgnoreCase("item"))
{
if (st.countTokens() >= 1)
{
int fee = 0;
if (Config.DEBUG)
{
_log.warning("Item editing invoked");
}
val = st.nextToken();
final int lvl = Integer.valueOf(val);
switch (lvl)
{
case 0:
break;
case 1:
fee = Config.CH_ITEM1_FEE;
break;
case 2:
fee = Config.CH_ITEM2_FEE;
break;
default:
fee = Config.CH_ITEM3_FEE;
break;
}
if (!getClanHall().updateFunctions(ClanHall.FUNC_ITEM_CREATE, lvl, fee, Config.CH_ITEM_FEE_RATIO, Calendar.getInstance().getTimeInMillis() + Config.CH_ITEM_FEE_RATIO, (getClanHall().getFunction(ClanHall.FUNC_ITEM_CREATE) == null)))
{
player.sendMessage("Not enough adena in clan warehouse.");
}
else
{
revalidateDeco(player);
}
}
}
else if (val.equalsIgnoreCase("tele"))
{
if (st.countTokens() >= 1)
{
int fee = 0;
if (Config.DEBUG)
{
_log.warning("Tele editing invoked");
}
val = st.nextToken();
final int lvl = Integer.valueOf(val);
switch (lvl)
{
case 0:
break;
case 1:
fee = Config.CH_TELE1_FEE;
break;
default:
fee = Config.CH_TELE2_FEE;
break;
}
if (!getClanHall().updateFunctions(ClanHall.FUNC_TELEPORT, lvl, fee, Config.CH_TELE_FEE_RATIO, Calendar.getInstance().getTimeInMillis() + Config.CH_TELE_FEE_RATIO, (getClanHall().getFunction(ClanHall.FUNC_TELEPORT) == null)))
{
player.sendMessage("Not enough adena in clan warehouse.");
}
else
{
revalidateDeco(player);
}
}
}
else if (val.equalsIgnoreCase("support"))
{
if (st.countTokens() >= 1)
{
int fee = 0;
if (Config.DEBUG)
{
_log.warning("Support editing invoked");
}
val = st.nextToken();
final int lvl = Integer.valueOf(val);
switch (lvl)
{
case 0:
break;
case 1:
fee = Config.CH_SUPPORT1_FEE;
break;
case 2:
fee = Config.CH_SUPPORT2_FEE;
break;
case 3:
fee = Config.CH_SUPPORT3_FEE;
break;
case 4:
fee = Config.CH_SUPPORT4_FEE;
break;
case 5:
fee = Config.CH_SUPPORT5_FEE;
break;
case 6:
fee = Config.CH_SUPPORT6_FEE;
break;
case 7:
fee = Config.CH_SUPPORT7_FEE;
break;
default:
fee = Config.CH_SUPPORT8_FEE;
break;
}
if (!getClanHall().updateFunctions(ClanHall.FUNC_SUPPORT, lvl, fee, Config.CH_SUPPORT_FEE_RATIO, Calendar.getInstance().getTimeInMillis() + Config.CH_SUPPORT_FEE_RATIO, (getClanHall().getFunction(ClanHall.FUNC_SUPPORT) == null)))
{
player.sendMessage("Not enough adena in clan warehouse.");
}
else
{
revalidateDeco(player);
}
}
}
}
final NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile("data/html/clanHallManager/edit_other" + getClanHall().getGrade() + ".htm");
if ((getClanHall().getFunction(ClanHall.FUNC_TELEPORT) != null) && (getClanHall().getFunction(ClanHall.FUNC_TELEPORT).getLvl() != 0))
{
html.replace("%tele%", String.valueOf(getClanHall().getFunction(ClanHall.FUNC_TELEPORT).getLvl()));
html.replace("%telePrice%", String.valueOf(getClanHall().getFunction(ClanHall.FUNC_TELEPORT).getLease()));
html.replace("%teleDate%", format.format(getClanHall().getFunction(ClanHall.FUNC_TELEPORT).getEndTime()));
}
else
{
html.replace("%tele%", "0");
html.replace("%telePrice%", "0");
html.replace("%teleDate%", "0");
}
if ((getClanHall().getFunction(ClanHall.FUNC_SUPPORT) != null) && (getClanHall().getFunction(ClanHall.FUNC_SUPPORT).getLvl() != 0))
{
html.replace("%support%", String.valueOf(getClanHall().getFunction(ClanHall.FUNC_SUPPORT).getLvl()));
html.replace("%supportPrice%", String.valueOf(getClanHall().getFunction(ClanHall.FUNC_SUPPORT).getLease()));
html.replace("%supportDate%", format.format(getClanHall().getFunction(ClanHall.FUNC_SUPPORT).getEndTime()));
}
else
{
html.replace("%support%", "0");
html.replace("%supportPrice%", "0");
html.replace("%supportDate%", "0");
}
if ((getClanHall().getFunction(ClanHall.FUNC_ITEM_CREATE) != null) && (getClanHall().getFunction(ClanHall.FUNC_ITEM_CREATE).getLvl() != 0))
{
html.replace("%item%", String.valueOf(getClanHall().getFunction(ClanHall.FUNC_ITEM_CREATE).getLvl()));
html.replace("%itemPrice%", String.valueOf(getClanHall().getFunction(ClanHall.FUNC_ITEM_CREATE).getLease()));
html.replace("%itemDate%", format.format(getClanHall().getFunction(ClanHall.FUNC_ITEM_CREATE).getEndTime()));
}
else
{
html.replace("%item%", "0");
html.replace("%itemPrice%", "0");
html.replace("%itemDate%", "0");
}
sendHtmlMessage(player, html);
}
else if (val.equalsIgnoreCase("deco"))
{
if (st.countTokens() >= 1)
{
val = st.nextToken();
if (val.equalsIgnoreCase("curtains"))
{
if (st.countTokens() >= 1)
{
int fee = 0;
if (Config.DEBUG)
{
_log.warning("Deco curtains editing invoked");
}
val = st.nextToken();
final int lvl = Integer.valueOf(val);
switch (lvl)
{
case 0:
break;
case 1:
fee = Config.CH_CURTAIN1_FEE;
break;
default:
fee = Config.CH_CURTAIN2_FEE;
break;
}
if (!getClanHall().updateFunctions(ClanHall.FUNC_DECO_CURTAINS, lvl, fee, Config.CH_CURTAIN_FEE_RATIO, Calendar.getInstance().getTimeInMillis() + Config.CH_CURTAIN_FEE_RATIO, (getClanHall().getFunction(ClanHall.FUNC_DECO_CURTAINS) == null)))
{
player.sendMessage("Not enough adena in Clan Warehouse.");
}
else
{
revalidateDeco(player);
}
}
}
else if (val.equalsIgnoreCase("porch"))
{
if (st.countTokens() >= 1)
{
int fee = 0;
if (Config.DEBUG)
{
_log.warning("Deco curtains editing invoked");
}
val = st.nextToken();
final int lvl = Integer.valueOf(val);
switch (lvl)
{
case 0:
break;
case 1:
fee = Config.CH_FRONT1_FEE;
break;
default:
fee = Config.CH_FRONT2_FEE;
break;
}
if (!getClanHall().updateFunctions(ClanHall.FUNC_DECO_FRONTPLATEFORM, lvl, fee, Config.CH_FRONT_FEE_RATIO, Calendar.getInstance().getTimeInMillis() + Config.CH_FRONT_FEE_RATIO, (getClanHall().getFunction(ClanHall.FUNC_DECO_FRONTPLATEFORM) == null)))
{
player.sendMessage("Not enough adena in Clan Warehouse.");
}
else
{
revalidateDeco(player);
}
}
}
}
final NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile("data/html/clanHallManager/deco.htm");
if ((getClanHall().getFunction(ClanHall.FUNC_DECO_CURTAINS) != null) && (getClanHall().getFunction(ClanHall.FUNC_DECO_CURTAINS).getLvl() != 0))
{
html.replace("%curtain%", String.valueOf(getClanHall().getFunction(ClanHall.FUNC_DECO_CURTAINS).getLvl()));
html.replace("%curtainPrice%", String.valueOf(getClanHall().getFunction(ClanHall.FUNC_DECO_CURTAINS).getLease()));
html.replace("%curtainDate%", format.format(getClanHall().getFunction(ClanHall.FUNC_DECO_CURTAINS).getEndTime()));
}
else
{
html.replace("%curtain%", "0");
html.replace("%curtainPrice%", "0");
html.replace("%curtainDate%", "0");
}
if ((getClanHall().getFunction(ClanHall.FUNC_DECO_FRONTPLATEFORM) != null) && (getClanHall().getFunction(ClanHall.FUNC_DECO_FRONTPLATEFORM).getLvl() != 0))
{
html.replace("%porch%", String.valueOf(getClanHall().getFunction(ClanHall.FUNC_DECO_FRONTPLATEFORM).getLvl()));
html.replace("%porchPrice%", String.valueOf(getClanHall().getFunction(ClanHall.FUNC_DECO_FRONTPLATEFORM).getLease()));
html.replace("%porchDate%", format.format(getClanHall().getFunction(ClanHall.FUNC_DECO_FRONTPLATEFORM).getEndTime()));
}
else
{
html.replace("%porch%", "0");
html.replace("%porchPrice%", "0");
html.replace("%porchDate%", "0");
}
sendHtmlMessage(player, html);
}
else if (val.equalsIgnoreCase("back"))
{
showMessageWindow(player);
}
else
{
final NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile("data/html/clanHallManager/manage.htm");
sendHtmlMessage(player, html);
}
}
else
{
player.sendPacket(new SystemMessage(SystemMessage.YOU_ARE_NOT_AUTHORIZED));
}
return;
}
else if (actualCommand.equalsIgnoreCase("support"))
{
setTarget(player);
L2Skill skill;
if (val.isEmpty())
{
return;
}
try
{
final int skill_id = Integer.parseInt(val);
try
{
int skill_lvl = 0;
if (st.countTokens() >= 1)
{
skill_lvl = Integer.parseInt(st.nextToken());
}
skill = SkillTable.getInstance().getInfo(skill_id, skill_lvl);
if (skill.getSkillType() == SkillType.SUMMON)
{
player.doCast(skill);
}
else
{
doCast(skill);
}
if (getClanHall().getFunction(ClanHall.FUNC_SUPPORT) == null)
{
return;
}
final NpcHtmlMessage html = new NpcHtmlMessage(1);
if (getClanHall().getFunction(ClanHall.FUNC_SUPPORT).getLvl() == 0)
{
return;
}
html.setFile("data/html/clanHallManager/support" + getClanHall().getFunction(ClanHall.FUNC_SUPPORT).getLvl() + ".htm");
html.replace("%mp%", String.valueOf(getCurrentMp()));
sendHtmlMessage(player, html);
}
catch (final Exception e)
{
player.sendMessage("Invalid skill level!");
}
}
catch (final Exception e)
{
player.sendMessage("Invalid skill!");
}
return;
}
else if (actualCommand.equalsIgnoreCase("goto"))
{
final int whereTo = Integer.parseInt(val);
doTeleport(player, whereTo);
return;
}
}
super.onBypassFeedback(player, command);
}
/**
* this is called when a player interacts with this NPC
* @param player
*/
@Override
public void onAction(L2PcInstance player)
{
if (!canTarget(player))
{
return;
}
player.setLastFolkNPC(this);
// Check if the L2PcInstance already target the L2NpcInstance
if (this != player.getTarget())
{
// Set the target of the L2PcInstance player
player.setTarget(this);
// Send a Server->Client packet MyTargetSelected to the L2PcInstance player
final MyTargetSelected my = new MyTargetSelected(getObjectId(), 0);
player.sendPacket(my);
// Send a Server->Client packet ValidateLocation to correct the L2NpcInstance position and heading on the client
player.sendPacket(new ValidateLocation(this));
}
else
{
// Calculate the distance between the L2PcInstance and the L2NpcInstance
if (canInteract(player))
{
showMessageWindow(player);
}
}
// Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet
player.sendPacket(new ActionFailed());
}
private void sendHtmlMessage(L2PcInstance player, NpcHtmlMessage html)
{
html.replace("%objectId%", String.valueOf(getObjectId()));
html.replace("%npcname%", getName());
html.replace("%npcId%", String.valueOf(getNpcId()));
player.sendPacket(html);
}
private void showMessageWindow(L2PcInstance player)
{
player.sendPacket(new ActionFailed());
String filename = "data/html/clanHallManager/chamberlain-no.htm";
final int condition = validateCondition(player);
if (condition > Cond_All_False)
{
if (condition == Cond_Owner)
{
filename = "data/html/clanHallManager/chamberlain.htm"; // Owner message window
}
}
final NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(filename);
html.replace("%objectId%", String.valueOf(getObjectId()));
html.replace("%npcId%", String.valueOf(getNpcId()));
html.replace("%npcname%", getName());
player.sendPacket(html);
}
protected int validateCondition(L2PcInstance player)
{
if (getClanHall() == null)
{
return Cond_All_False;
}
if (player.isGM())
{
return Cond_Owner;
}
if (player.getClan() != null)
{
if (getClanHall().getOwnerId() == player.getClanId())
{
return Cond_Owner;
}
}
return Cond_All_False;
}
/**
* Return the L2ClanHall this L2NpcInstance belongs to.
* @return
*/
public final ClanHall getClanHall()
{
if (_clanHallId < 0)
{
_clanHallId = ClanHallManager.getInstance().getNearbyClanHall(getX(), getY(), 500).getId();
if (_clanHallId < 0)
{
return null;
}
}
return ClanHallManager.getInstance().getClanHallById(_clanHallId);
}
private void showVaultWindowDeposit(L2PcInstance player)
{
player.sendPacket(new ActionFailed());
player.setActiveWarehouse(player.getClan().getWarehouse());
player.sendPacket(new WareHouseDepositList(player, WareHouseDepositList.Clan)); // Or Clan Hall??
}
private void showVaultWindowWithdraw(L2PcInstance player)
{
player.sendPacket(new ActionFailed());
player.setActiveWarehouse(player.getClan().getWarehouse());
player.sendPacket(new WareHouseWithdrawalList(player, WareHouseWithdrawalList.Clan)); // Or Clan Hall ??
}
private void doTeleport(L2PcInstance player, int val)
{
if (Config.DEBUG)
{
_log.warning("doTeleport(L2PcInstance player, int val) is called.");
}
final L2TeleportLocation list = TeleportLocationTable.getInstance().getTemplate(val);
if (list != null)
{
if (SiegeManager.getInstance().getSiege(list.getLocX(), list.getLocY(), list.getLocZ()) != null)
{
// you cannot teleport to village that is in siege Not sure about this one though
player.sendPacket(new SystemMessage(707));
return;
}
else if (player.reduceAdena("Teleport", list.getPrice(), this, true))
{
if (Config.DEBUG)
{
_log.warning("Teleporting player " + player.getName() + " for CH to new location: " + list.getLocX() + ":" + list.getLocY() + ":" + list.getLocZ());
}
player.teleToLocation(list.getLocX(), list.getLocY(), list.getLocZ(), true);
}
}
else
{
_log.warning("No teleport destination with id:" + val);
}
player.sendPacket(new ActionFailed());
}
private void revalidateDeco(L2PcInstance player)
{
final ClanHall hall = ClanHallManager.getInstance().getClanHallByOwner(player.getClan());
if (hall != null)
{
player.sendPacket(new ClanHallDecoration(hall));
}
}
}

View File

@@ -0,0 +1,450 @@
/*
* 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.model.actor.instance;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.cache.HtmCache;
import com.l2jmobius.gameserver.datatables.CharTemplateTable;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.model.base.ClassId;
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.network.serverpackets.TutorialCloseHtml;
import com.l2jmobius.gameserver.network.serverpackets.TutorialShowHtml;
import com.l2jmobius.gameserver.network.serverpackets.TutorialShowQuestionMark;
import com.l2jmobius.gameserver.templates.L2NpcTemplate;
/**
* This class ...
* @version $Revision: 1.4.2.1.2.7 $ $Date: 2005/03/27 15:29:32 $
*/
public final class L2ClassMasterInstance extends L2FolkInstance
{
/**
* @param objectId
* @param template
*/
public L2ClassMasterInstance(int objectId, L2NpcTemplate template)
{
super(objectId, template);
}
@Override
public String getHtmlPath(int npcId, int val)
{
String pom = "";
if (val == 0)
{
pom = "" + npcId;
}
else
{
pom = npcId + "-" + val;
}
return "data/html/classmaster/" + pom + ".htm";
}
@Override
public void onBypassFeedback(L2PcInstance player, String command)
{
if (command.startsWith("1stClass"))
{
showHtmlMenu(player, getObjectId(), 1);
}
else if (command.startsWith("2ndClass"))
{
showHtmlMenu(player, getObjectId(), 2);
}
else if (command.startsWith("3rdClass"))
{
showHtmlMenu(player, getObjectId(), 3);
}
else if (command.startsWith("change_class"))
{
final int val = Integer.parseInt(command.substring(13));
if (checkAndChangeClass(player, val))
{
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
html.setFile("data/html/classmaster/ok.htm");
html.replace("%name%", CharTemplateTable.getClassNameById(val));
player.sendPacket(html);
}
}
else
{
super.onBypassFeedback(player, command);
}
}
public static final void onTutorialLink(L2PcInstance player, String request)
{
if (!Config.ALTERNATE_CLASS_MASTER || (request == null) || !request.startsWith("CO"))
{
return;
}
try
{
final int val = Integer.parseInt(request.substring(2));
checkAndChangeClass(player, val);
}
catch (final NumberFormatException e)
{
}
player.sendPacket(new TutorialCloseHtml());
}
public static final void onTutorialQuestionMark(L2PcInstance player, int number)
{
if (!Config.ALTERNATE_CLASS_MASTER || (number != 1001))
{
return;
}
showTutorialHtml(player);
}
public static final void showQuestionMark(L2PcInstance player)
{
if (!Config.ALTERNATE_CLASS_MASTER)
{
return;
}
final ClassId classId = player.getClassId();
if (getMinLevel(classId.level()) > player.getLevel())
{
return;
}
if (!Config.CLASS_MASTER_SETTINGS.isAllowed(classId.level() + 1))
{
return;
}
player.sendPacket(new TutorialShowQuestionMark(1001));
}
public static final void showHtmlMenu(L2PcInstance player, int objectId, int level)
{
final NpcHtmlMessage html = new NpcHtmlMessage(objectId);
if (!Config.ALLOW_CLASS_MASTERS && !Config.ALTERNATE_CLASS_MASTER)
{
html.setFile("data/html/classmaster/disabled.htm");
}
else if (!Config.CLASS_MASTER_SETTINGS.isAllowed(level))
{
final int jobLevel = player.getClassId().level();
final StringBuilder sb = new StringBuilder(100);
sb.append("<html><body>");
switch (jobLevel)
{
case 0:
if (Config.CLASS_MASTER_SETTINGS.isAllowed(1))
{
sb.append("Come back here when you reached level 20 to change your class.<br>");
}
else if (Config.CLASS_MASTER_SETTINGS.isAllowed(2))
{
sb.append("Come back after your first occupation change.<br>");
}
else if (Config.CLASS_MASTER_SETTINGS.isAllowed(3))
{
sb.append("Come back after your second occupation change.<br>");
}
else
{
sb.append("I can't change your occupation.<br>");
}
break;
case 1:
if (Config.CLASS_MASTER_SETTINGS.isAllowed(2))
{
sb.append("Come back here when you reached level 40 to change your class.<br>");
}
else if (Config.CLASS_MASTER_SETTINGS.isAllowed(3))
{
sb.append("Come back after your second occupation change.<br>");
}
else
{
sb.append("I can't change your occupation.<br>");
}
break;
case 2:
if (Config.CLASS_MASTER_SETTINGS.isAllowed(3))
{
sb.append("Come back here when you reached level 76 to change your class.<br>");
}
else
{
sb.append("I can't change your occupation.<br>");
}
break;
case 3:
sb.append("There is no class change available for you anymore.<br>");
break;
}
sb.append("</body></html>");
html.setHtml(sb.toString());
}
else
{
final ClassId currentClassId = player.getClassId();
if (currentClassId.level() >= level)
{
html.setFile("data/html/classmaster/nomore.htm");
}
else
{
final int minLevel = getMinLevel(currentClassId.level());
if ((player.getLevel() >= minLevel) || Config.ALLOW_ENTIRE_TREE)
{
final StringBuilder menu = new StringBuilder(100);
for (final ClassId cid : ClassId.values())
{
if (validateClassId(currentClassId, cid) && (cid.level() == level))
{
menu.append("<a action=\"bypass -h npc_%objectId%_change_class ");
menu.append(String.valueOf(cid.getId()));
menu.append("\">");
menu.append(CharTemplateTable.getClassNameById(cid.getId()));
menu.append("</a><br>");
}
}
if (menu.length() > 0)
{
html.setFile("data/html/classmaster/template.htm");
html.replace("%name%", CharTemplateTable.getClassNameById(currentClassId.getId()));
html.replace("%menu%", menu.toString());
}
else
{
html.setFile("data/html/classmaster/comebacklater.htm");
html.replace("%level%", String.valueOf(getMinLevel(level - 1)));
}
}
else
{
if (minLevel < Integer.MAX_VALUE)
{
html.setFile("data/html/classmaster/comebacklater.htm");
html.replace("%level%", String.valueOf(minLevel));
}
else
{
html.setFile("data/html/classmaster/nomore.htm");
}
}
}
}
html.replace("%objectId%", String.valueOf(objectId));
html.replace("%req_items%", getRequiredItems(level));
player.sendPacket(html);
}
private static final void showTutorialHtml(L2PcInstance player)
{
final ClassId currentClassId = player.getClassId();
if ((getMinLevel(currentClassId.level()) > player.getLevel()) && !Config.ALLOW_ENTIRE_TREE)
{
return;
}
String msg = HtmCache.getInstance().getHtm("data/html/classmaster/tutorialtemplate.htm");
msg = msg.replaceAll("%name%", CharTemplateTable.getClassNameById(currentClassId.getId()));
final StringBuilder menu = new StringBuilder(100);
for (final ClassId cid : ClassId.values())
{
if (validateClassId(currentClassId, cid))
{
menu.append("<a action=\"link CO");
menu.append(String.valueOf(cid.getId()));
menu.append("\">");
menu.append(CharTemplateTable.getClassNameById(cid.getId()));
menu.append("</a><br>");
}
}
msg = msg.replaceAll("%menu%", menu.toString());
msg = msg.replace("%req_items%", getRequiredItems(currentClassId.level() + 1));
player.sendPacket(new TutorialShowHtml(msg));
}
public static final boolean checkAndChangeClass(L2PcInstance player, int val)
{
final ClassId currentClassId = player.getClassId();
if ((getMinLevel(currentClassId.level()) > player.getLevel()) && !Config.ALLOW_ENTIRE_TREE)
{
return false;
}
if (!validateClassId(currentClassId, val))
{
return false;
}
final int newJobLevel = currentClassId.level() + 1;
// Weight/Inventory check
if (!Config.CLASS_MASTER_SETTINGS.getRewardItems(newJobLevel).isEmpty())
{
if ((player.getWeightPenalty() >= 3) || ((player.getInventoryLimit() * 0.8) <= player.getInventory().getSize()))
{
player.sendPacket(new SystemMessage(SystemMessage.INVENTORY_80_PERCENT_FOR_QUEST));
return false;
}
}
// check if player have all required items for class transfer
for (final int _itemId : Config.CLASS_MASTER_SETTINGS.getRequireItems(newJobLevel).keys())
{
final int _count = Config.CLASS_MASTER_SETTINGS.getRequireItems(newJobLevel).get(_itemId);
if (player.getInventory().getInventoryItemCount(_itemId, -1) < _count)
{
player.sendPacket(new SystemMessage(SystemMessage.NOT_ENOUGH_ITEMS));
return false;
}
}
// get all required items for class transfer
for (final int _itemId : Config.CLASS_MASTER_SETTINGS.getRequireItems(newJobLevel).keys())
{
final int _count = Config.CLASS_MASTER_SETTINGS.getRequireItems(newJobLevel).get(_itemId);
if (!player.destroyItemByItemId("ClassMaster", _itemId, _count, player, true))
{
return false;
}
}
// reward player with items
for (final int _itemId : Config.CLASS_MASTER_SETTINGS.getRewardItems(newJobLevel).keys())
{
final int _count = Config.CLASS_MASTER_SETTINGS.getRewardItems(newJobLevel).get(_itemId);
player.addItem("ClassMaster", _itemId, _count, player, true);
}
player.setClassId(val);
if (player.isSubClassActive())
{
player.getSubClasses().get(player.getClassIndex()).setClassId(player.getActiveClass());
}
else
{
player.setBaseClass(player.getActiveClass());
}
player.broadcastUserInfo();
if (Config.CLASS_MASTER_SETTINGS.isAllowed(player.getClassId().level() + 1) && Config.ALTERNATE_CLASS_MASTER && (((player.getClassId().level() == 1) && (player.getLevel() >= 40)) || ((player.getClassId().level() == 2) && (player.getLevel() >= 76))))
{
showQuestionMark(player);
}
return true;
}
/**
* Returns minimum player level required for next class transfer
* @param level - current skillId level (0 - start, 1 - first, etc)
* @return
*/
private static final int getMinLevel(int level)
{
switch (level)
{
case 0:
return 20;
case 1:
return 40;
case 2:
return 76;
default:
return Integer.MAX_VALUE;
}
}
/**
* Returns true if class change is possible
* @param oldCID current player ClassId
* @param val new class index
* @return
*/
private static final boolean validateClassId(ClassId oldCID, int val)
{
try
{
return validateClassId(oldCID, ClassId.values()[val]);
}
catch (final Exception e)
{
// possible ArrayOutOfBoundsException
}
return false;
}
/**
* Returns true if class change is possible
* @param oldCID current player ClassId
* @param newCID new ClassId
* @return true if class change is possible
*/
private static final boolean validateClassId(ClassId oldCID, ClassId newCID)
{
if ((newCID == null) || (newCID.getRace() == null))
{
return false;
}
if (oldCID.equals(newCID.getParent()))
{
return true;
}
if (Config.ALLOW_ENTIRE_TREE && newCID.childOf(oldCID))
{
return true;
}
return false;
}
private static String getRequiredItems(int level)
{
if ((Config.CLASS_MASTER_SETTINGS.getRequireItems(level) == null) || Config.CLASS_MASTER_SETTINGS.getRequireItems(level).isEmpty())
{
return "<tr><td>None</td></r>";
}
final StringBuilder sb = new StringBuilder();
for (final int _itemId : Config.CLASS_MASTER_SETTINGS.getRequireItems(level).keys())
{
final int _count = Config.CLASS_MASTER_SETTINGS.getRequireItems(level).get(_itemId);
sb.append("<tr><td><font color=\"LEVEL\">" + _count + "</font></td><td>" + ItemTable.getInstance().getTemplate(_itemId).getName() + "</td></tr>");
}
return sb.toString();
}
}

View File

@@ -0,0 +1,137 @@
/*
* 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.model.actor.instance;
import java.util.List;
import com.l2jmobius.gameserver.GeoData;
import com.l2jmobius.gameserver.ai.CtrlIntention;
import com.l2jmobius.gameserver.model.L2Character;
import com.l2jmobius.gameserver.model.L2Spawn;
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import com.l2jmobius.gameserver.network.serverpackets.MyTargetSelected;
import com.l2jmobius.gameserver.network.serverpackets.StatusUpdate;
import com.l2jmobius.gameserver.network.serverpackets.ValidateLocation;
import com.l2jmobius.gameserver.templates.L2NpcTemplate;
import javolution.util.FastList;
public class L2ControlTowerInstance extends L2NpcInstance
{
private List<L2Spawn> _Guards;
public L2ControlTowerInstance(int objectId, L2NpcTemplate template)
{
super(objectId, template);
}
@Override
public boolean isAttackable()
{
// Attackable during siege by attacker only
return ((getCastle() != null) && (getCastle().getCastleId() > 0) && getCastle().getSiege().getIsInProgress());
}
@Override
public boolean isAutoAttackable(L2Character attacker)
{
// Attackable during siege by attacker only
return ((attacker != null) && (attacker instanceof L2PcInstance) && (getCastle() != null) && (getCastle().getCastleId() > 0) && getCastle().getSiege().getIsInProgress() && getCastle().getSiege().checkIsAttacker(((L2PcInstance) attacker).getClan()));
}
@Override
public void onForcedAttack(L2PcInstance player)
{
onAction(player);
}
@Override
public void onAction(L2PcInstance player)
{
if (!canTarget(player))
{
return;
}
// Check if the L2PcInstance already target the L2NpcInstance
if (this != player.getTarget())
{
// Set the target of the L2PcInstance player
player.setTarget(this);
// Send a Server->Client packet MyTargetSelected to the L2PcInstance player
final MyTargetSelected my = new MyTargetSelected(getObjectId(), player.getLevel() - getLevel());
player.sendPacket(my);
// Send a Server->Client packet StatusUpdate of the L2NpcInstance to the L2PcInstance to update its HP bar
final StatusUpdate su = new StatusUpdate(getObjectId());
su.addAttribute(StatusUpdate.CUR_HP, (int) getStatus().getCurrentHp());
su.addAttribute(StatusUpdate.MAX_HP, getMaxHp());
player.sendPacket(su);
// Send a Server->Client packet ValidateLocation to correct the L2NpcInstance position and heading on the client
player.sendPacket(new ValidateLocation(this));
}
else
{
if (isAutoAttackable(player) && (Math.abs(player.getZ() - getZ()) < 100 // Less then max height difference, delete check when geo
) && GeoData.getInstance().canSeeTarget(player, this))
{
// Notify the L2PcInstance AI with AI_INTENTION_INTERACT
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, this);
// Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet
player.sendPacket(new ActionFailed());
}
}
}
public void onDeath()
{
if (getCastle().getSiege().getIsInProgress())
{
getCastle().getSiege().killedCT(this);
if ((getGuards() != null) && (getGuards().size() > 0))
{
for (final L2Spawn spawn : getGuards())
{
if (spawn == null)
{
continue;
}
spawn.stopRespawn();
}
}
}
}
public void registerGuard(L2Spawn guard)
{
getGuards().add(guard);
}
public final List<L2Spawn> getGuards()
{
if (_Guards == null)
{
_Guards = new FastList<>();
}
return _Guards;
}
}

View File

@@ -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.model.actor.instance;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.ai.CtrlIntention;
import com.l2jmobius.gameserver.ai.L2CharacterAI;
import com.l2jmobius.gameserver.ai.L2ControllableMobAI;
import com.l2jmobius.gameserver.model.L2Character;
import com.l2jmobius.gameserver.templates.L2NpcTemplate;
/**
* @author littlecrow
*/
public class L2ControllableMobInstance extends L2MonsterInstance
{
private boolean _isInvul;
private L2ControllableMobAI _aiBackup; // to save ai, avoiding beeing detached
protected class ControllableAIAcessor extends AIAccessor
{
@Override
public void detachAI()
{
// do nothing, AI of controllable mobs can't be detached automatically
}
}
@Override
public boolean isAggressive()
{
return true;
}
@Override
public int getAggroRange()
{
// force mobs to be aggro
return 500;
}
public L2ControllableMobInstance(int objectId, L2NpcTemplate template)
{
super(objectId, template);
}
@Override
public L2CharacterAI getAI()
{
if (_ai == null)
{
synchronized (this)
{
if ((_ai == null) && (_aiBackup == null))
{
_ai = new L2ControllableMobAI(new ControllableAIAcessor());
_aiBackup = (L2ControllableMobAI) _ai;
}
else
{
_ai = _aiBackup;
}
}
}
return _ai;
}
@Override
public boolean isInvul()
{
return _isInvul;
}
public void setInvul(boolean isInvul)
{
_isInvul = isInvul;
}
@Override
public void reduceCurrentHp(double i, L2Character attacker, boolean awake)
{
if (isInvul() || isDead())
{
return;
}
if (awake)
{
stopSleeping(null);
}
i = getCurrentHp() - i;
if (i < 0)
{
i = 0;
}
setCurrentHp(i);
if (getCurrentHp() < 0.5)
{
// first die (and calculate rewards), if currentHp < 0,
// then overhit may be calculated
if (Config.DEBUG)
{
_log.fine("char is dead.");
}
stopMove(null);
// Start the doDie process
doDie(attacker);
// now reset currentHp to zero
setCurrentHp(0);
}
}
@Override
public boolean doDie(L2Character killer)
{
if (!super.doDie(killer))
{
return false;
}
removeAI();
return true;
}
@Override
public void deleteMe()
{
removeAI();
super.deleteMe();
}
/**
* Definitively remove AI
*/
protected void removeAI()
{
synchronized (this)
{
if (_aiBackup != null)
{
_aiBackup.setIntention(CtrlIntention.AI_INTENTION_IDLE);
_aiBackup = null;
_ai = null;
}
}
}
}

View File

@@ -0,0 +1,369 @@
/*
* 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.model.actor.instance;
import java.util.List;
import java.util.concurrent.Future;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.datatables.SkillTable;
import com.l2jmobius.gameserver.handler.ISkillHandler;
import com.l2jmobius.gameserver.handler.SkillHandler;
import com.l2jmobius.gameserver.model.L2Character;
import com.l2jmobius.gameserver.model.L2Party;
import com.l2jmobius.gameserver.model.L2Skill;
import com.l2jmobius.gameserver.network.serverpackets.MagicSkillUse;
import com.l2jmobius.util.Rnd;
import javolution.util.FastList;
public class L2CubicInstance
{
protected static Logger _log = Logger.getLogger(L2CubicInstance.class.getName());
public static final int STORM_CUBIC = 1;
public static final int VAMPIRIC_CUBIC = 2;
public static final int LIFE_CUBIC = 3;
public static final int VIPER_CUBIC = 4;
public static final int POLTERGEIST_CUBIC = 5;
public static final int BINDING_CUBIC = 6;
public static final int AQUA_CUBIC = 7;
public static final int SPARK_CUBIC = 8;
protected L2PcInstance _owner;
protected L2Character _target;
protected int _id;
protected int _level = 1;
private final boolean _givenByOther;
protected List<Integer> _skills = new FastList<>();
private Future<?> _disappearTask;
private Future<?> _actionTask;
public L2CubicInstance(L2PcInstance owner, int id, int level, boolean givenByOther)
{
_owner = owner;
_id = id;
_level = level;
_givenByOther = givenByOther;
switch (_id)
{
case STORM_CUBIC:
_skills.add(4049);
break;
case VAMPIRIC_CUBIC:
_skills.add(4050);
break;
case LIFE_CUBIC:
_skills.add(4051);
_disappearTask = ThreadPoolManager.getInstance().scheduleGeneral(new Disappear(), 3600000); // disappear in 60 mins
doAction(_owner);
break;
case VIPER_CUBIC:
_skills.add(4052);
break;
case POLTERGEIST_CUBIC:
_skills.add(4053);
_skills.add(4054);
_skills.add(4055);
break;
case BINDING_CUBIC:
_skills.add(4164);
break;
case AQUA_CUBIC:
_skills.add(4165);
break;
case SPARK_CUBIC:
_skills.add(4166);
break;
}
if (_disappearTask == null)
{
_disappearTask = ThreadPoolManager.getInstance().scheduleGeneral(new Disappear(), 1200000); // disappear in 20 mins
}
}
public void doAction(L2Character target)
{
if (_target == target)
{
return;
}
stopAction();
_target = target;
switch (_id)
{
case STORM_CUBIC:
_actionTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new Action(12), 0, 10000);
break;
case VAMPIRIC_CUBIC:
_actionTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new Action(8), 0, 15000);
break;
case VIPER_CUBIC:
_actionTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new Action(30), 0, 20000);
break;
case POLTERGEIST_CUBIC:
_actionTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new Action(30), 0, 8000);
break;
case BINDING_CUBIC:
case AQUA_CUBIC:
case SPARK_CUBIC:
_actionTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new Action(30), 0, 8000);
break;
case LIFE_CUBIC:
_actionTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new Heal(50), 0, 30000);
break;
}
}
public int getId()
{
return _id;
}
public void setLevel(int level)
{
_level = level;
}
public boolean givenByOther()
{
return _givenByOther;
}
public void stopAction()
{
_target = null;
if (_actionTask != null)
{
_actionTask.cancel(true);
_actionTask = null;
}
}
public void cancelDisappear()
{
if (_disappearTask != null)
{
_disappearTask.cancel(true);
_disappearTask = null;
}
}
private class Action implements Runnable
{
private final int _chance;
Action(int chance)
{
_chance = chance;
// run task
}
@Override
public void run()
{
if (_owner.isDead() || _target.isDead() || (_owner.getTarget() != _target) || !_target.isAutoAttackable(_owner))
{
stopAction();
if (_owner.isDead())
{
_owner.delCubic(_id);
_owner.broadcastUserInfo();
cancelDisappear();
}
return;
}
if (_target != null)
{
try
{
if (Rnd.get(1, 100) < _chance)
{
final L2Skill skill = SkillTable.getInstance().getInfo(_skills.get(Rnd.get(_skills.size())), _level);
if (skill != null)
{
final L2Character[] targets =
{
_target
};
final ISkillHandler handler = SkillHandler.getInstance().getSkillHandler(skill.getSkillType());
int x, y, z;
// temporary range check until real behavior of cubics is known/coded
final int range = (int) _target.getTemplate().collisionRadius + 400; // skill.getCastRange();
x = (_owner.getX() - _target.getX());
y = (_owner.getY() - _target.getY());
z = (_owner.getZ() - _target.getZ());
if (((x * x) + (y * y) + (z * z)) <= (range * range))
{
if (handler != null)
{
handler.useSkill(_owner, skill, targets, false);
}
else
{
skill.useSkill(_owner, targets);
}
final MagicSkillUse msu = new MagicSkillUse(_owner, _target, skill.getId(), _level, 0, 0);
_owner.broadcastPacket(msu);
}
}
}
}
catch (final Exception e)
{
_log.log(Level.SEVERE, "", e);
}
}
}
}
private class Heal implements Runnable
{
private final int _chance;
Heal(int chance)
{
_chance = chance;
// run task
}
@Override
public void run()
{
if (_owner.isDead())
{
stopAction();
_owner.delCubic(_id);
_owner.broadcastUserInfo();
cancelDisappear();
return;
}
try
{
if (Rnd.get(1, 100) < _chance)
{
final L2Skill skill = SkillTable.getInstance().getInfo(_skills.get(Rnd.get(_skills.size())), _level);
if (skill != null)
{
L2Character target, caster;
target = null;
if (_owner.isInParty())
{
caster = _owner;
final L2PcInstance player = _owner;
final L2Party party = player.getParty();
double percentleft = 100.0;
if (party != null)
{
// Get all visible objects in a spheric area near the L2Character
// Get a list of Party Members
final List<L2PcInstance> partyList = party.getPartyMembers();
L2Character partyMember = null;
int x, y, z;
// temporary range check until real behavior of cubics is known/coded
final int range = 400; // skill.getCastRange();
for (int i = 0; i < partyList.size(); i++)
{
partyMember = partyList.get(i);
if (!partyMember.isDead())
{
// if party member not dead, check if he is in castrange of heal cubic
x = (caster.getX() - partyMember.getX());
y = (caster.getY() - partyMember.getY());
z = (caster.getZ() - partyMember.getZ());
if (((x * x) + (y * y) + (z * z)) > (range * range))
{
continue;
}
// member is in cubic casting range, check if he need heal and if he have the lowest HP
if (partyMember.getCurrentHp() < partyMember.getMaxHp())
{
if (percentleft > (partyMember.getCurrentHp() / partyMember.getMaxHp()))
{
percentleft = (partyMember.getCurrentHp() / partyMember.getMaxHp());
target = partyMember;
}
}
}
}
}
}
else
{
if (_owner.getCurrentHp() < _owner.getMaxHp())
{
target = _owner;
}
}
if (target != null)
{
final L2Character[] targets =
{
target
};
final ISkillHandler handler = SkillHandler.getInstance().getSkillHandler(skill.getSkillType());
if (handler != null)
{
handler.useSkill(_owner, skill, targets, false);
}
else
{
skill.useSkill(_owner, targets);
}
final MagicSkillUse msu = new MagicSkillUse(_owner, target, skill.getId(), _level, 0, 0);
_owner.broadcastPacket(msu);
}
}
}
}
catch (final Exception e)
{
}
}
}
private class Disappear implements Runnable
{
Disappear()
{
// run task
}
@Override
public void run()
{
stopAction();
_owner.delCubic(_id);
_owner.broadcastUserInfo();
}
}
}

View File

@@ -0,0 +1,682 @@
/*
* 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.model.actor.instance;
import java.util.Collection;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.ai.CtrlIntention;
import com.l2jmobius.gameserver.ai.L2CharacterAI;
import com.l2jmobius.gameserver.ai.L2DoorAI;
import com.l2jmobius.gameserver.instancemanager.CastleManager;
import com.l2jmobius.gameserver.model.L2CharPosition;
import com.l2jmobius.gameserver.model.L2Character;
import com.l2jmobius.gameserver.model.L2ItemInstance;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.L2Skill;
import com.l2jmobius.gameserver.model.actor.knownlist.DoorKnownList;
import com.l2jmobius.gameserver.model.actor.stat.DoorStat;
import com.l2jmobius.gameserver.model.actor.status.DoorStatus;
import com.l2jmobius.gameserver.model.entity.Castle;
import com.l2jmobius.gameserver.model.entity.ClanHall;
import com.l2jmobius.gameserver.network.L2GameClient;
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import com.l2jmobius.gameserver.network.serverpackets.ConfirmDlg;
import com.l2jmobius.gameserver.network.serverpackets.DoorStatusUpdate;
import com.l2jmobius.gameserver.network.serverpackets.MyTargetSelected;
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
import com.l2jmobius.gameserver.network.serverpackets.ValidateLocation;
import com.l2jmobius.gameserver.templates.L2CharTemplate;
import com.l2jmobius.gameserver.templates.L2Weapon;
import javolution.text.TextBuilder;
import javolution.util.FastList;
/**
* This class ...
* @version $Revision: 1.3.2.2.2.5 $ $Date: 2005/03/27 15:29:32 $
*/
public class L2DoorInstance extends L2Character
{
protected static Logger log = Logger.getLogger(L2DoorInstance.class.getName());
/** The castle index in the array of L2Castle this L2NpcInstance belongs to */
private int _CastleIndex = -2;
private int _mapRegion = -1;
// when door is closed, the dimensions are
private int _rangeXMin = 0;
private int _rangeYMin = 0;
private int _rangeZMin = 0;
private int _rangeXMax = 0;
private int _rangeYMax = 0;
private int _rangeZMax = 0;
// these variables assist in see-through calculation only
private int _A = 0;
private int _B = 0;
private int _C = 0;
private int _D = 0;
protected final int _doorId;
protected final String _name;
private int _open;
private final boolean _unlockable;
private ClanHall _clanhall;
protected long _autoActionDelay = 0;
/** This class may be created only by L2Character and only for AI */
public class AIAccessor extends L2Character.AIAccessor
{
protected AIAccessor()
{
}
@Override
public L2DoorInstance getActor()
{
return L2DoorInstance.this;
}
@Override
public void moveTo(int x, int y, int z, int offset)
{
}
@Override
public void moveTo(int x, int y, int z)
{
}
@Override
public void stopMove(L2CharPosition pos)
{
}
@Override
public void doAttack(L2Character target)
{
}
@Override
public void doCast(L2Skill skill)
{
}
}
@Override
public L2CharacterAI getAI()
{
if (_ai == null)
{
synchronized (this)
{
if (_ai == null)
{
_ai = new L2DoorAI(new AIAccessor());
}
}
}
return _ai;
}
class CloseTask implements Runnable
{
@Override
public void run()
{
try
{
closeMe();
}
catch (final Throwable e)
{
log.log(Level.SEVERE, "", e);
}
}
}
/**
* Manages the auto open and closing of a door.
*/
class AutoOpenClose implements Runnable
{
@Override
public void run()
{
try
{
if (getOpen() == 1)
{
openMe();
}
else
{
closeMe();
}
}
catch (final Exception e)
{
log.warning("Could not auto open/close door ID " + _doorId + " (" + _name + ")");
}
}
}
/**
* @param objectId
* @param template
* @param doorId
* @param name
* @param unlockable
*/
public L2DoorInstance(int objectId, L2CharTemplate template, int doorId, String name, boolean unlockable)
{
super(objectId, template);
getKnownList();
getStat();
getStatus();
_doorId = doorId;
_name = name;
_unlockable = unlockable;
}
@Override
public final DoorKnownList getKnownList()
{
if ((super.getKnownList() == null) || !(super.getKnownList() instanceof DoorKnownList))
{
setKnownList(new DoorKnownList(this));
}
return (DoorKnownList) super.getKnownList();
}
@Override
public final DoorStat getStat()
{
if ((super.getStat() == null) || !(super.getStat() instanceof DoorStat))
{
setStat(new DoorStat(this));
}
return (DoorStat) super.getStat();
}
@Override
public final DoorStatus getStatus()
{
if ((super.getStatus() == null) || !(super.getStatus() instanceof DoorStatus))
{
setStatus(new DoorStatus(this));
}
return (DoorStatus) super.getStatus();
}
public final boolean isUnlockable()
{
return _unlockable;
}
@Override
public final int getLevel()
{
return 1;
}
/**
* @return Returns the doorId.
*/
public int getDoorId()
{
return _doorId;
}
/**
* @return Returns the open.
*/
public int getOpen()
{
return _open;
}
/**
* @param open The open to set.
*/
public void setOpen(int open)
{
_open = open;
}
/**
* Sets the delay in milliseconds for automatic opening/closing of this door instance. <BR>
* <B>Note:</B> A value of -1 cancels the auto open/close task.
* @param actionDelay
*/
public void setAutoActionDelay(long actionDelay)
{
if (_autoActionDelay >= actionDelay)
{
return;
}
ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new AutoOpenClose(), actionDelay, actionDelay);
_autoActionDelay = actionDelay;
}
public int getDamage()
{
final int dmg = 6 - (int) Math.ceil((getCurrentHp() / getMaxHp()) * 6);
if (dmg > 6)
{
return 6;
}
if (dmg < 0)
{
return 0;
}
return dmg;
}
public final Castle getCastle()
{
if (_CastleIndex < 0)
{
_CastleIndex = CastleManager.getInstance().getCastleIndex(this);
}
if (_CastleIndex < 0)
{
return null;
}
return CastleManager.getInstance().getCastles().get(_CastleIndex);
}
public void setClanHall(ClanHall clanhall)
{
_clanhall = clanhall;
}
public ClanHall getClanHall()
{
return _clanhall;
}
public boolean isEnemyOf(L2Character cha)
{
return true;
}
@Override
public boolean isAutoAttackable(L2Character attacker)
{
if ((attacker == null) || !(attacker instanceof L2PlayableInstance))
{
return false;
}
if (getClanHall() != null)
{
return false;
}
// Attackable during siege by attacker only
return ((getCastle() != null) && (getCastle().getCastleId() > 0) && getCastle().getSiege().getIsInProgress() && getCastle().getSiege().checkIsAttacker(((L2PcInstance) attacker).getClan()));
}
public boolean isAttackable(L2Character attacker)
{
return isAutoAttackable(attacker);
}
@Override
public void updateAbnormalEffect()
{
}
public int getDistanceToWatchObject(L2Object object)
{
if (!(object instanceof L2PcInstance))
{
return 0;
}
return 2000;
}
/**
* Return the distance after which the object must be remove from _knownObject according to the type of the object.<BR>
* <BR>
* <B><U> Values </U> :</B><BR>
* <BR>
* <li>object is a L2PcInstance : 4000</li>
* <li>object is not a L2PcInstance : 0</li><BR>
* <BR>
* @param object
* @return
*/
public int getDistanceToForgetObject(L2Object object)
{
if (!(object instanceof L2PcInstance))
{
return 0;
}
return 4000;
}
/**
* Return null.<BR>
* <BR>
*/
@Override
public L2ItemInstance getActiveWeaponInstance()
{
return null;
}
@Override
public L2Weapon getActiveWeaponItem()
{
return null;
}
@Override
public L2ItemInstance getSecondaryWeaponInstance()
{
return null;
}
@Override
public L2Weapon getSecondaryWeaponItem()
{
return null;
}
@Override
public void onAction(L2PcInstance player)
{
if (player == null)
{
return;
}
// Check if the L2PcInstance already target the L2NpcInstance
if (this != player.getTarget())
{
// Set the target of the L2PcInstance player
player.setTarget(this);
// Send a Server->Client packet MyTargetSelected to the L2PcInstance player
final MyTargetSelected my = new MyTargetSelected(getObjectId(), 0);
player.sendPacket(my);
final DoorStatusUpdate su = new DoorStatusUpdate(this);
player.sendPacket(su);
// Send a Server->Client packet ValidateLocation to correct the L2NpcInstance position and heading on the client
player.sendPacket(new ValidateLocation(this));
}
else
{
if (isAutoAttackable(player))
{
if (Math.abs(player.getZ() - getZ()) < 400)
{
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, this);
}
}
else if ((player.getClan() != null) && (getClanHall() != null) && (player.getClanId() == getClanHall().getOwnerId()))
{
if (!isInsideRadius(player, L2NpcInstance.INTERACTION_DISTANCE, false, false))
{
player.getAI().setIntention(CtrlIntention.AI_INTENTION_INTERACT, this);
}
else
{
player.gatesRequest(this);
if (getOpen() == 1)
{
player.sendPacket(new ConfirmDlg(1140, null));
}
else
{
player.sendPacket(new ConfirmDlg(1141, null));
}
}
}
}
// Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet
player.sendPacket(new ActionFailed());
}
@Override
public void onActionShift(L2GameClient client)
{
final L2PcInstance player = client.getActiveChar();
if (player == null)
{
return;
}
if (player.getAccessLevel() >= Config.GM_ACCESSLEVEL)
{
player.setTarget(this);
final MyTargetSelected my = new MyTargetSelected(getObjectId(), player.getLevel());
player.sendPacket(my);
if (isAutoAttackable(player))
{
final DoorStatusUpdate su = new DoorStatusUpdate(this);
player.sendPacket(su);
}
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
final TextBuilder html1 = new TextBuilder("<html><body><table border=0>");
html1.append("<tr><td>S.Y.L. Says:</td></tr>");
html1.append("<tr><td>Current HP " + getCurrentHp() + "</td></tr>");
html1.append("<tr><td>Max HP " + getMaxHp() + "</td></tr>");
html1.append("<tr><td>Max X " + getXMax() + "</td></tr>");
html1.append("<tr><td>Max Y " + getYMax() + "</td></tr>");
html1.append("<tr><td>Max Z " + getZMax() + "</td></tr>");
html1.append("<tr><td>Min X " + getXMin() + "</td></tr>");
html1.append("<tr><td>Min Y " + getYMin() + "</td></tr>");
html1.append("<tr><td>Min Z " + getZMin() + "</td></tr>");
html1.append("<tr><td>Object ID: " + getObjectId() + "</td></tr>");
html1.append("<tr><td>Door ID:<br>" + getDoorId() + "</td></tr>");
html1.append("<tr><td><br></td></tr>");
html1.append("<tr><td>Class: " + getClass().getName() + "</td></tr>");
html1.append("<tr><td><br></td></tr>");
html1.append("</table>");
html1.append("<table><tr>");
html1.append("<td><button value=\"Open\" action=\"bypass -h admin_open " + getDoorId() + "\" width=40 height=15 back=\"sek.cbui94\" fore=\"sek.cbui92\"></td>");
html1.append("<td><button value=\"Close\" action=\"bypass -h admin_close " + getDoorId() + "\" width=40 height=15 back=\"sek.cbui94\" fore=\"sek.cbui92\"></td>");
html1.append("<td><button value=\"Kill\" action=\"bypass -h admin_kill\" width=40 height=15 back=\"sek.cbui94\" fore=\"sek.cbui92\"></td>");
html1.append("<td><button value=\"Delete\" action=\"bypass -h admin_delete\" width=40 height=15 back=\"sek.cbui94\" fore=\"sek.cbui92\"></td>");
html1.append("</tr></table></body></html>");
html.setHtml(html1.toString());
player.sendPacket(html);
}
player.sendPacket(new ActionFailed());
}
@Override
public void broadcastStatusUpdate()
{
final Collection<L2PcInstance> knownPlayers = getKnownList().getKnownPlayers().values();
if ((knownPlayers == null) || knownPlayers.isEmpty())
{
return;
}
final DoorStatusUpdate su = new DoorStatusUpdate(this);
for (final L2PcInstance player : knownPlayers)
{
player.sendPacket(su);
}
}
private void startAutoCloseTask()
{
long delay = 60000;
if (getDoorName().startsWith("goe"))
{
delay = 420000; // Garden of Eva (every 7 minutes)
}
else if (getDoorName().startsWith("aden_tower"))
{
delay = 300000; // Tower of Insolence (every 5 minutes)
}
else if (getDoorName().startsWith("pirate_isle"))
{
delay = 300000; // devils (every 5 minutes)
}
else if (getDoorName().startsWith("cruma"))
{
delay = 1200000; // Cruma Tower (every 20 minutes)
}
ThreadPoolManager.getInstance().scheduleGeneral(new CloseTask(), delay);
}
public final void closeMe()
{
setOpen(1);
broadcastStatusUpdate();
}
public final void openMe()
{
setOpen(0);
broadcastStatusUpdate();
// execute a task to close the door if needed
if (isUnlockable())
{
startAutoCloseTask();
}
}
@Override
public String toString()
{
return "door " + _doorId;
}
public String getDoorName()
{
return _name;
}
public int getXMin()
{
return _rangeXMin;
}
public int getYMin()
{
return _rangeYMin;
}
public int getZMin()
{
return _rangeZMin;
}
public int getXMax()
{
return _rangeXMax;
}
public int getYMax()
{
return _rangeYMax;
}
public int getZMax()
{
return _rangeZMax;
}
public int getA()
{
return _A;
}
public int getB()
{
return _B;
}
public int getC()
{
return _C;
}
public int getD()
{
return _D;
}
public void setRange(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax)
{
_rangeXMin = xMin;
_rangeYMin = yMin;
_rangeZMin = zMin;
_rangeXMax = xMax;
_rangeYMax = yMax;
_rangeZMax = zMax;
_A = (_rangeYMax * (_rangeZMax - _rangeZMin)) + (_rangeYMin * (_rangeZMin - _rangeZMax));
_B = (_rangeZMin * (_rangeXMax - _rangeXMin)) + (_rangeZMax * (_rangeXMin - _rangeXMax));
_C = (_rangeXMin * (_rangeYMax - _rangeYMin)) + (_rangeXMin * (_rangeYMin - _rangeYMax));
_D = -1 * ((_rangeXMin * ((_rangeYMax * _rangeZMax) - (_rangeYMin * _rangeZMax))) + (_rangeXMax * ((_rangeYMin * _rangeZMin) - (_rangeYMin * _rangeZMax))) + (_rangeXMin * ((_rangeYMin * _rangeZMax) - (_rangeYMax * _rangeZMin))));
}
public int getMapRegion()
{
return _mapRegion;
}
public void setMapRegion(int region)
{
_mapRegion = region;
}
public Collection<L2SiegeGuardInstance> getKnownSiegeGuards()
{
final FastList<L2SiegeGuardInstance> result = new FastList<>();
for (final L2Object obj : getKnownList().getKnownObjects().values())
{
if (obj instanceof L2SiegeGuardInstance)
{
result.add((L2SiegeGuardInstance) obj);
}
}
return result;
}
}

View File

@@ -0,0 +1,259 @@
/*
* 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.model.actor.instance;
import java.util.StringTokenizer;
import com.l2jmobius.gameserver.ai.CtrlIntention;
import com.l2jmobius.gameserver.datatables.ClanTable;
import com.l2jmobius.gameserver.instancemanager.ClanHallManager;
import com.l2jmobius.gameserver.model.L2Clan;
import com.l2jmobius.gameserver.model.entity.ClanHall;
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import com.l2jmobius.gameserver.network.serverpackets.MyTargetSelected;
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
import com.l2jmobius.gameserver.network.serverpackets.ValidateLocation;
import com.l2jmobius.gameserver.templates.L2NpcTemplate;
/**
* This class ...
* @version $Revision$ $Date$
*/
public class L2DoormenInstance extends L2FolkInstance
{
// private static Logger _log = Logger.getLogger(L2DoormenInstance.class.getName());
private ClanHall _ClanHall;
private static int Cond_All_False = 0;
private static int Cond_Busy_Because_Of_Siege = 1;
private static int Cond_Castle_Owner = 2;
private static int Cond_Hall_Owner = 3;
/**
* @param objectID
* @param template
*/
public L2DoormenInstance(int objectID, L2NpcTemplate template)
{
super(objectID, template);
}
public final ClanHall getClanHall()
{
// _log.warning(this.getName()+" searching ch");
if (_ClanHall == null)
{
_ClanHall = ClanHallManager.getInstance().getNearbyClanHall(getX(), getY(), 500);
}
return _ClanHall;
}
@Override
public void onBypassFeedback(L2PcInstance player, String command)
{
final int condition = validateCondition(player);
if (condition <= Cond_All_False)
{
return;
}
if (condition == Cond_Busy_Because_Of_Siege)
{
return;
}
else if ((condition == Cond_Castle_Owner) || (condition == Cond_Hall_Owner))
{
if (command.startsWith("Chat"))
{
showMessageWindow(player);
return;
}
else if (command.startsWith("open_doors"))
{
if (condition == Cond_Hall_Owner)
{
getClanHall().openCloseDoors(true);
player.sendPacket(new NpcHtmlMessage(getObjectId(), "<html><head><body>You have <font color=\"LEVEL\">opened</font> the clan hall door.<br>Outsiders may enter the clan hall while the door is open. Please close it when you've finished your business.<br><center><button value=\"Close\" action=\"bypass -h npc_" + getObjectId() + "_close_doors\" width=70 height=15 back=\"sek.cbui94\" fore=\"sek.cbui92\"></center></body></html>"));
}
else
{
final StringTokenizer st = new StringTokenizer(command.substring(10), ", ");
st.nextToken(); // Bypass first value since its castleid/hallid
if (condition == 2)
{
while (st.hasMoreTokens())
{
getCastle().openDoor(player, Integer.parseInt(st.nextToken()));
}
return;
}
}
}
else if (command.startsWith("close_doors"))
{
if (condition == Cond_Hall_Owner)
{
getClanHall().openCloseDoors(false);
player.sendPacket(new NpcHtmlMessage(getObjectId(), "<html><head><body>You have <font color=\"LEVEL\">closed</font> the clan hall door.<br>Good day!<br><center><button value=\"To Begining\" action=\"bypass -h npc_" + getObjectId() + "_Chat\" width=90 height=15 back=\"sek.cbui94\" fore=\"sek.cbui92\"></center></body></html>"));
}
else
{
final StringTokenizer st = new StringTokenizer(command.substring(11), ", ");
st.nextToken(); // Bypass first value since its castleid/hallid
if (condition == 2)
{
while (st.hasMoreTokens())
{
getCastle().closeDoor(player, Integer.parseInt(st.nextToken()));
}
return;
}
}
}
}
super.onBypassFeedback(player, command);
}
/**
* this is called when a player interacts with this NPC
* @param player
*/
@Override
public void onAction(L2PcInstance player)
{
if (!canTarget(player))
{
return;
}
player.setLastFolkNPC(this);
// Check if the L2PcInstance already target the L2NpcInstance
if (this != player.getTarget())
{
// Set the target of the L2PcInstance player
player.setTarget(this);
// Send a Server->Client packet MyTargetSelected to the L2PcInstance player
final MyTargetSelected my = new MyTargetSelected(getObjectId(), 0);
player.sendPacket(my);
// Send a Server->Client packet ValidateLocation to correct the L2NpcInstance position and heading on the client
player.sendPacket(new ValidateLocation(this));
}
else
{
// Calculate the distance between the L2PcInstance and the L2NpcInstance
if (!canInteract(player))
{
// Notify the L2PcInstance AI with AI_INTENTION_INTERACT
player.getAI().setIntention(CtrlIntention.AI_INTENTION_INTERACT, this);
}
else
{
showMessageWindow(player);
}
}
// Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet
player.sendPacket(new ActionFailed());
}
public void showMessageWindow(L2PcInstance player)
{
player.sendPacket(new ActionFailed());
String filename = "data/html/doormen/" + getTemplate().npcId + "-no.htm";
final int condition = validateCondition(player);
if (condition == Cond_Busy_Because_Of_Siege)
{
filename = "data/html/doormen/" + getTemplate().npcId + "-busy.htm"; // Busy because of siege
}
else if (condition == Cond_Castle_Owner)
{
filename = "data/html/doormen/" + getTemplate().npcId + ".htm"; // Owner message window
}
// Prepare doormen for clan hall
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
String str;
if (getClanHall() != null)
{
if (condition == Cond_Hall_Owner)
{
str = "<html><body>Hello!<br><font color=\"55FFFF\">" + player.getName() + "</font>, I am honored to serve your clan.<br>How may i serve you?<br>";
str += "<center><table><tr><td><button value=\"Open Door\" action=\"bypass -h npc_%objectId%_open_doors\" width=70 height=15 back=\"sek.cbui94\" fore=\"sek.cbui92\"><br1></td></tr></table><br>";
str += "<table><tr><td><button value=\"Close Door\" action=\"bypass -h npc_%objectId%_close_doors\" width=70 height=15 back=\"sek.cbui94\" fore=\"sek.cbui92\"></td></tr></table></center></body></html>";
}
else
{
final L2Clan owner = ClanTable.getInstance().getClan(getClanHall().getOwnerId());
if ((owner != null) && (owner.getLeader() != null))
{
str = "<html><body>Hello there!<br>This clan hall is owned by <font color=\"55FFFF\">" + owner.getLeader().getName() + " who is the Lord of the ";
str += owner.getName() + "</font> clan.<br>";
str += "I am sorry, but only the clan members who belong to the <font color=\"55FFFF\">" + owner.getName() + "</font> clan can enter the clan hall.</body></html>";
}
else
{
str = "<html><body>" + getName() + ":<br1>Clan hall <font color=\"LEVEL\">" + getClanHall().getName() + "</font> has no owner.<br>You can rent it at auctioneers.</body></html>";
}
}
html.setHtml(str);
}
else
{
html.setFile(filename);
}
html.replace("%objectId%", String.valueOf(getObjectId()));
player.sendPacket(html);
}
private int validateCondition(L2PcInstance player)
{
if (player.getClan() != null)
{
// Prepare doormen for clan hall
if (getClanHall() != null)
{
if (player.getClanId() == getClanHall().getOwnerId())
{
return Cond_Hall_Owner;
}
return Cond_All_False;
}
if ((getCastle() != null) && (getCastle().getCastleId() > 0))
{
if (getCastle().getSiege().getIsInProgress())
{
return Cond_Busy_Because_Of_Siege; // Busy because of siege
}
else if (getCastle().getOwnerId() == player.getClanId())
{
return Cond_Castle_Owner; // Owner
}
}
}
return Cond_All_False;
}
}

View File

@@ -0,0 +1,33 @@
/*
* 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.model.actor.instance;
import com.l2jmobius.gameserver.templates.L2NpcTemplate;
// This class is here mostly for convinience and for avoidance of hardcoded IDs.
// It refers to Beast (mobs) that can be attacked but can also be fed
// For example, the Beast Farm's Alpen Buffalo.
// This class is only trully used by the handlers in order to check the correctness
// of the target. However, no additional tasks are needed, since they are all
// handled by scripted AI.
public class L2FeedableBeastInstance extends L2MonsterInstance
{
public L2FeedableBeastInstance(int objectId, L2NpcTemplate template)
{
super(objectId, template);
}
}

View File

@@ -0,0 +1,545 @@
/*
* 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.model.actor.instance;
import java.util.Calendar;
import java.util.List;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.SevenSigns;
import com.l2jmobius.gameserver.SevenSignsFestival;
import com.l2jmobius.gameserver.model.L2ItemInstance;
import com.l2jmobius.gameserver.model.L2Party;
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.templates.L2NpcTemplate;
import com.l2jmobius.gameserver.templates.StatsSet;
import javolution.text.TextBuilder;
/**
* Festival of Darkness Guide (Seven Signs)
* @author Tempy
*/
public final class L2FestivalGuideInstance extends L2FolkInstance
{
// private static Logger _log = Logger.getLogger(L2FestivalGuideInstance.class.getName());
protected int _festivalType;
protected int _festivalOracle;
protected int _blueStonesNeeded;
protected int _greenStonesNeeded;
protected int _redStonesNeeded;
/**
* @param objectId
* @param template
*/
public L2FestivalGuideInstance(int objectId, L2NpcTemplate template)
{
super(objectId, template);
switch (getNpcId())
{
case 8127:
case 8132:
_festivalType = SevenSignsFestival.FESTIVAL_LEVEL_MAX_31;
_festivalOracle = SevenSigns.CABAL_DAWN;
_blueStonesNeeded = 900;
_greenStonesNeeded = 540;
_redStonesNeeded = 270;
break;
case 8128:
case 8133:
_festivalType = SevenSignsFestival.FESTIVAL_LEVEL_MAX_42;
_festivalOracle = SevenSigns.CABAL_DAWN;
_blueStonesNeeded = 1500;
_greenStonesNeeded = 900;
_redStonesNeeded = 450;
break;
case 8129:
case 8134:
_festivalType = SevenSignsFestival.FESTIVAL_LEVEL_MAX_53;
_festivalOracle = SevenSigns.CABAL_DAWN;
_blueStonesNeeded = 3000;
_greenStonesNeeded = 1800;
_redStonesNeeded = 900;
break;
case 8130:
case 8135:
_festivalType = SevenSignsFestival.FESTIVAL_LEVEL_MAX_64;
_festivalOracle = SevenSigns.CABAL_DAWN;
_blueStonesNeeded = 4500;
_greenStonesNeeded = 2700;
_redStonesNeeded = 1350;
break;
case 8131:
case 8136:
_festivalType = SevenSignsFestival.FESTIVAL_LEVEL_MAX_NONE;
_festivalOracle = SevenSigns.CABAL_DAWN;
_blueStonesNeeded = 6000;
_greenStonesNeeded = 3600;
_redStonesNeeded = 1800;
break;
case 8137:
case 8142:
_festivalType = SevenSignsFestival.FESTIVAL_LEVEL_MAX_31;
_festivalOracle = SevenSigns.CABAL_DUSK;
_blueStonesNeeded = 900;
_greenStonesNeeded = 540;
_redStonesNeeded = 270;
break;
case 8138:
case 8143:
_festivalType = SevenSignsFestival.FESTIVAL_LEVEL_MAX_42;
_festivalOracle = SevenSigns.CABAL_DUSK;
_blueStonesNeeded = 1500;
_greenStonesNeeded = 900;
_redStonesNeeded = 450;
break;
case 8139:
case 8144:
_festivalType = SevenSignsFestival.FESTIVAL_LEVEL_MAX_53;
_festivalOracle = SevenSigns.CABAL_DUSK;
_blueStonesNeeded = 3000;
_greenStonesNeeded = 1800;
_redStonesNeeded = 900;
break;
case 8140:
case 8145:
_festivalType = SevenSignsFestival.FESTIVAL_LEVEL_MAX_64;
_festivalOracle = SevenSigns.CABAL_DUSK;
_blueStonesNeeded = 4500;
_greenStonesNeeded = 2700;
_redStonesNeeded = 1350;
break;
case 8141:
case 8146:
_festivalType = SevenSignsFestival.FESTIVAL_LEVEL_MAX_NONE;
_festivalOracle = SevenSigns.CABAL_DUSK;
_blueStonesNeeded = 6000;
_greenStonesNeeded = 3600;
_redStonesNeeded = 1800;
break;
}
}
@Override
public void onBypassFeedback(L2PcInstance player, String command)
{
if (command.startsWith("FestivalDesc"))
{
final int val = Integer.parseInt(command.substring(13));
showChatWindow(player, val, null, true);
}
else if (command.startsWith("Festival"))
{
final L2Party playerParty = player.getParty();
final int val = Integer.parseInt(command.substring(9, 10));
switch (val)
{
case 1: // Become a Participant
// Check if the festival period is active, if not then don't allow registration.
if (SevenSigns.getInstance().isSealValidationPeriod())
{
showChatWindow(player, 2, "a", false);
return;
}
// Check if a festival is in progress, then don't allow registration yet.
if (SevenSignsFestival.getInstance().isFestivalInitialized())
{
player.sendMessage("You cannot sign up while a festival is in progress.");
return;
}
// Check if the player is in a formed party already.
if (playerParty == null)
{
showChatWindow(player, 2, "b", false);
return;
}
// Check if the player is the party leader.
if (!playerParty.isLeader(player))
{
showChatWindow(player, 2, "c", false);
return;
}
// Check to see if the party has at least 5 members.
if (playerParty.getMemberCount() < Config.ALT_FESTIVAL_MIN_PLAYER)
{
showChatWindow(player, 2, "b", false);
return;
}
// Check if all the party members are in the required level range.
if (playerParty.getLevel() > SevenSignsFestival.getMaxLevelForFestival(_festivalType))
{
showChatWindow(player, 2, "d", false);
return;
}
// TODO: Check if the player has delevelled by comparing their skill levels.
/*
* Check to see if the player has already signed up, if they are then update the participant list providing all the required criteria has been met.
*/
if (player.isFestivalParticipant())
{
SevenSignsFestival.getInstance().setParticipants(_festivalOracle, _festivalType, playerParty);
showChatWindow(player, 2, "f", false);
return;
}
showChatWindow(player, 1, null, false);
break;
case 2: // Festival 2 xxxx
final int stoneType = Integer.parseInt(command.substring(11));
int stonesNeeded = 0;
switch (stoneType)
{
case SevenSigns.SEAL_STONE_BLUE_ID:
stonesNeeded = _blueStonesNeeded;
break;
case SevenSigns.SEAL_STONE_GREEN_ID:
stonesNeeded = _greenStonesNeeded;
break;
case SevenSigns.SEAL_STONE_RED_ID:
stonesNeeded = _redStonesNeeded;
break;
}
if (!player.destroyItemByItemId("SevenSigns", stoneType, stonesNeeded, this, true))
{
return;
}
SevenSignsFestival.getInstance().setParticipants(_festivalOracle, _festivalType, playerParty);
SevenSignsFestival.getInstance().addAccumulatedBonus(_festivalType, stoneType, stonesNeeded);
showChatWindow(player, 2, "e", false);
break;
case 3: // Score Registration
// Check if the festival period is active, if not then don't register the score.
if (SevenSigns.getInstance().isSealValidationPeriod())
{
showChatWindow(player, 3, "a", false);
return;
}
// Check if a festival is in progress, if it is don't register the score.
if (SevenSignsFestival.getInstance().isFestivalInProgress())
{
player.sendMessage("You cannot register a score while a festival is in progress.");
return;
}
// Check if the player is in a party.
if (playerParty == null)
{
showChatWindow(player, 3, "b", false);
return;
}
final List<L2PcInstance> prevParticipants = SevenSignsFestival.getInstance().getPreviousParticipants(_festivalOracle, _festivalType);
// Check if there are any past participants.
if (prevParticipants == null)
{
return;
}
// Check if this player was among the past set of participants for this festival.
if (!prevParticipants.contains(player))
{
showChatWindow(player, 3, "b", false);
return;
}
// Check if this player was the party leader in the festival.
if (player.getObjectId() != prevParticipants.get(0).getObjectId())
{
showChatWindow(player, 3, "b", false);
return;
}
final L2ItemInstance bloodOfferings = player.getInventory().getItemByItemId(SevenSignsFestival.FESTIVAL_OFFERING_ID);
int offeringCount = 0;
// Check if the player collected any blood offerings during the festival.
if (bloodOfferings == null)
{
player.sendMessage("You do not have any blood offerings to contribute.");
return;
}
offeringCount = bloodOfferings.getCount();
final int offeringScore = offeringCount * SevenSignsFestival.FESTIVAL_OFFERING_VALUE;
final boolean isHighestScore = SevenSignsFestival.getInstance().setFinalScore(player, _festivalOracle, _festivalType, offeringScore);
player.destroyItem("SevenSigns", bloodOfferings, this, false);
// Send message that the contribution score has increased.
final SystemMessage sm = new SystemMessage(SystemMessage.CONTRIB_SCORE_INCREASED);
sm.addNumber(offeringScore);
player.sendPacket(sm);
if (isHighestScore)
{
showChatWindow(player, 3, "c", false);
}
else
{
showChatWindow(player, 3, "d", false);
}
break;
case 4: // Current High Scores
final TextBuilder strBuffer = new TextBuilder("<html><body>Festival Guide:<br>These are the top scores of the week, for the ");
final StatsSet dawnData = SevenSignsFestival.getInstance().getHighestScoreData(SevenSigns.CABAL_DAWN, _festivalType);
final StatsSet duskData = SevenSignsFestival.getInstance().getHighestScoreData(SevenSigns.CABAL_DUSK, _festivalType);
final StatsSet overallData = SevenSignsFestival.getInstance().getOverallHighestScoreData(_festivalType);
final int dawnScore = dawnData.getInteger("score");
final int duskScore = duskData.getInteger("score");
int overallScore = 0;
// If no data is returned, assume there is no record, or all scores are 0.
if (overallData != null)
{
overallScore = overallData.getInteger("score");
}
strBuffer.append(SevenSignsFestival.getFestivalName(_festivalType) + " festival.<br>");
if (dawnScore > 0)
{
strBuffer.append("Dawn: " + calculateDate(dawnData.getString("date")) + ". Score " + dawnScore + "<br>" + dawnData.getString("members") + "<br>");
}
else
{
strBuffer.append("Dawn: No record exists. Score 0<br>");
}
if (duskScore > 0)
{
strBuffer.append("Dusk: " + calculateDate(duskData.getString("date")) + ". Score " + duskScore + "<br>" + duskData.getString("members") + "<br>");
}
else
{
strBuffer.append("Dusk: No record exists. Score 0<br>");
}
if ((overallData != null) && (overallScore > 0))
{
String cabalStr = "Children of Dusk";
if (overallData.getString("cabal").equals("dawn"))
{
cabalStr = "Children of Dawn";
}
strBuffer.append("Consecutive top scores: " + calculateDate(overallData.getString("date")) + ". Score " + overallScore + "<br>Affilated side: " + cabalStr + "<br>" + overallData.getString("members") + "<br>");
}
else
{
strBuffer.append("Consecutive top scores: No record exists. Score 0<br>");
}
strBuffer.append("<a action=\"bypass -h npc_" + getObjectId() + "_Chat 0\">Go back.</a></body></html>");
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
html.setHtml(strBuffer.toString());
player.sendPacket(html);
break;
case 8: // Increase the Festival Challenge
if (playerParty == null)
{
return;
}
if (!SevenSignsFestival.getInstance().isFestivalInProgress())
{
return;
}
if (!playerParty.isLeader(player))
{
showChatWindow(player, 8, "a", false);
break;
}
if (SevenSignsFestival.getInstance().increaseChallenge(_festivalOracle, _festivalType))
{
showChatWindow(player, 8, "b", false);
}
else
{
showChatWindow(player, 8, "c", false);
}
break;
case 9: // Leave the Festival
if (playerParty == null)
{
return;
}
/**
* If the player is the party leader, remove all participants from the festival (i.e. set the party to null, when updating the participant list) otherwise just remove this player from the "arena", and also remove them from the party.
*/
final boolean isLeader = playerParty.isLeader(player);
if (isLeader)
{
SevenSignsFestival.getInstance().updateParticipants(player, null);
}
else
{
SevenSignsFestival.getInstance().updateParticipants(player, playerParty);
playerParty.removePartyMember(player, true);
}
break;
case 0: // Distribute Accumulated Bonus
if (!SevenSigns.getInstance().isSealValidationPeriod())
{
player.sendMessage("Bonuses cannot be paid during the competition period.");
return;
}
if (SevenSignsFestival.getInstance().distribAccumulatedBonus(player) > 0)
{
showChatWindow(player, 0, "a", false);
}
else
{
showChatWindow(player, 0, "b", false);
}
break;
default:
showChatWindow(player, val, null, false);
}
}
else
{
// this class dont know any other commands, let forward
// the command to the parent class
super.onBypassFeedback(player, command);
}
}
private void showChatWindow(L2PcInstance player, int val, String suffix, boolean isDescription)
{
String filename = SevenSigns.SEVEN_SIGNS_HTML_PATH + "festival/";
filename += (isDescription) ? "desc_" : "festival_";
filename += (suffix != null) ? val + suffix + ".htm" : val + ".htm";
// Send a Server->Client NpcHtmlMessage containing the text of the L2NpcInstance to the L2PcInstance
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
html.setFile(filename);
html.replace("%objectId%", String.valueOf(getObjectId()));
html.replace("%festivalType%", SevenSignsFestival.getFestivalName(_festivalType));
html.replace("%cycleMins%", String.valueOf(SevenSignsFestival.getInstance().getMinsToNextCycle()));
if (!isDescription && "2b".equals(val + suffix))
{
html.replace("%minFestivalPartyMembers%", String.valueOf(Config.ALT_FESTIVAL_MIN_PLAYER));
}
// If the stats or bonus table is required, construct them.
if (val == 5)
{
html.replace("%statsTable%", getStatsTable());
}
if (val == 6)
{
html.replace("%bonusTable%", getBonusTable());
}
// festival's fee
if (val == 1)
{
html.replace("%blueStoneNeeded%", String.valueOf(_blueStonesNeeded));
html.replace("%greenStoneNeeded%", String.valueOf(_greenStonesNeeded));
html.replace("%redStoneNeeded%", String.valueOf(_redStonesNeeded));
}
player.sendPacket(html);
// Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet
player.sendPacket(new ActionFailed());
}
private final String getStatsTable()
{
final TextBuilder tableHtml = new TextBuilder();
// Get the scores for each of the festival level ranges (types).
for (int i = 0; i < 5; i++)
{
final int dawnScore = SevenSignsFestival.getInstance().getHighestScore(SevenSigns.CABAL_DAWN, i);
final int duskScore = SevenSignsFestival.getInstance().getHighestScore(SevenSigns.CABAL_DUSK, i);
final String festivalName = SevenSignsFestival.getFestivalName(i);
String winningCabal = "Children of Dusk";
if (dawnScore > duskScore)
{
winningCabal = "Children of Dawn";
}
else if (dawnScore == duskScore)
{
winningCabal = "None";
}
tableHtml.append("<tr><td width=\"100\" align=\"center\">" + festivalName + "</td><td align=\"center\" width=\"35\">" + duskScore + "</td><td align=\"center\" width=\"35\">" + dawnScore + "</td><td align=\"center\" width=\"130\">" + winningCabal + "</td></tr>");
}
return tableHtml.toString();
}
private final String getBonusTable()
{
final TextBuilder tableHtml = new TextBuilder();
// Get the accumulated scores for each of the festival level ranges (types).
for (int i = 0; i < 5; i++)
{
final int accumScore = SevenSignsFestival.getInstance().getAccumulatedBonus(i);
final String festivalName = SevenSignsFestival.getFestivalName(i);
tableHtml.append("<tr><td align=\"center\" width=\"150\">" + festivalName + "</td><td align=\"center\" width=\"150\">" + accumScore + "</td></tr>");
}
return tableHtml.toString();
}
private final String calculateDate(String milliFromEpoch)
{
final long numMillis = Long.valueOf(milliFromEpoch);
final Calendar calCalc = Calendar.getInstance();
calCalc.setTimeInMillis(numMillis);
return calCalc.get(Calendar.YEAR) + "/" + calCalc.get(Calendar.MONTH) + "/" + calCalc.get(Calendar.DAY_OF_MONTH);
}
}

View File

@@ -0,0 +1,131 @@
/*
* 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.model.actor.instance;
import com.l2jmobius.gameserver.SevenSignsFestival;
import com.l2jmobius.gameserver.model.L2Character;
import com.l2jmobius.gameserver.model.L2ItemInstance;
import com.l2jmobius.gameserver.model.L2Party;
import com.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
import com.l2jmobius.gameserver.templates.L2NpcTemplate;
/**
* L2FestivalMonsterInstance This class manages all attackable festival NPCs, spawned during the Festival of Darkness.
* @author Tempy
*/
public class L2FestivalMonsterInstance extends L2MonsterInstance
{
protected int _bonusMultiplier = 1;
/**
* Constructor of L2FestivalMonsterInstance (use L2Character and L2NpcInstance constructor).<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Call the L2Character constructor to set the _template of the L2FestivalMonsterInstance (copy skills from template to object and link _calculators to NPC_STD_CALCULATOR)</li>
* <li>Set the name of the L2MonsterInstance</li>
* <li>Create a RandomAnimation Task that will be launched after the calculated delay if the server allow it</li><BR>
* <BR>
* @param objectId Identifier of the object to initialized
* @param template to apply to the NPC
*/
public L2FestivalMonsterInstance(int objectId, L2NpcTemplate template)
{
super(objectId, template);
}
public void setOfferingBonus(int bonusMultiplier)
{
_bonusMultiplier = bonusMultiplier;
}
/**
* Return True if the attacker is not another L2FestivalMonsterInstance.<BR>
* <BR>
*/
@Override
public boolean isAutoAttackable(L2Character attacker)
{
if (attacker instanceof L2FestivalMonsterInstance)
{
return false;
}
return true;
}
/**
* All mobs in the festival are aggressive, and have high aggro range.
*/
@Override
public boolean isAggressive()
{
return true;
}
/**
* All mobs in the festival really don't need random animation.
*/
@Override
public boolean hasRandomAnimation()
{
return false;
}
/**
* Actions:
* <li>Check if the killing object is a player, and then find the party they belong to.</li>
* <li>Add a blood offering item to the leader of the party.</li>
* <li>Update the party leader's inventory to show the new item addition.</li>
*/
@Override
public void doItemDrop(L2Character lastAttacker)
{
L2PcInstance killingChar = null;
if (!(lastAttacker instanceof L2PcInstance))
{
return;
}
killingChar = (L2PcInstance) lastAttacker;
final L2Party associatedParty = killingChar.getParty();
if (associatedParty == null)
{
return;
}
final L2PcInstance partyLeader = associatedParty.getPartyMembers().get(0);
final L2ItemInstance addedOfferings = partyLeader.getInventory().addItem("Sign", SevenSignsFestival.FESTIVAL_OFFERING_ID, _bonusMultiplier, partyLeader, this);
final InventoryUpdate iu = new InventoryUpdate();
if (addedOfferings.getCount() != _bonusMultiplier)
{
iu.addModifiedItem(addedOfferings);
}
else
{
iu.addNewItem(addedOfferings);
}
partyLeader.sendPacket(iu);
super.doItemDrop(lastAttacker); // Normal drop
}
}

View File

@@ -0,0 +1,122 @@
/*
* 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.model.actor.instance;
import com.l2jmobius.gameserver.datatables.SkillTable;
import com.l2jmobius.gameserver.datatables.SkillTreeTable;
import com.l2jmobius.gameserver.model.L2Skill;
import com.l2jmobius.gameserver.model.L2SkillLearn;
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import com.l2jmobius.gameserver.network.serverpackets.AquireSkillList;
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.templates.L2NpcTemplate;
import javolution.text.TextBuilder;
public class L2FishermanInstance extends L2FolkInstance
{
/**
* @param objectId
* @param template
*/
public L2FishermanInstance(int objectId, L2NpcTemplate template)
{
super(objectId, template);
}
@Override
public String getHtmlPath(int npcId, int val)
{
String pom = "";
if (val == 0)
{
pom = "" + npcId;
}
else
{
pom = npcId + "-" + val;
}
return "data/html/fisherman/" + pom + ".htm";
}
@Override
public void onBypassFeedback(L2PcInstance player, String command)
{
if (command.startsWith("FishSkillList"))
{
player.setSkillLearningClassId(player.getClassId());
showSkillList(player);
}
else
{
super.onBypassFeedback(player, command);
}
}
public void showSkillList(L2PcInstance player)
{
final L2SkillLearn[] skills = SkillTreeTable.getInstance().getAvailableSkills(player);
final AquireSkillList asl = new AquireSkillList(true);
int counts = 0;
for (final L2SkillLearn s : skills)
{
final L2Skill sk = SkillTable.getInstance().getInfo(s.getId(), s.getLevel());
if (sk == null)
{
continue;
}
counts++;
asl.addSkill(s.getId(), s.getLevel(), s.getLevel(), s.getSpCost(), 1);
}
if (counts == 0)
{
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
final int minlevel = SkillTreeTable.getInstance().getMinLevelForNewSkill(player);
if (minlevel > 0)
{
// No more skills to learn, come back when you level.
final SystemMessage sm = new SystemMessage(SystemMessage.DO_NOT_HAVE_FURTHER_SKILLS_TO_LEARN);
sm.addNumber(minlevel);
player.sendPacket(sm);
}
else
{
final TextBuilder sb = new TextBuilder();
sb.append("<html><head><body>");
sb.append("You've learned all skills.<br>");
sb.append("</body></html>");
html.setHtml(sb.toString());
player.sendPacket(html);
}
}
else
{
player.sendPacket(asl);
}
player.sendPacket(new ActionFailed());
}
}

Some files were not shown because too many files have changed in this diff Show More