actual freya branch

This commit is contained in:
2026-09-12 15:41:31 +00:00
parent 8049e0a882
commit 68c1cd27d4
3510 changed files with 336689 additions and 302906 deletions
@@ -0,0 +1,874 @@
/*
* 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.l2jserver.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.Level;
import java.util.logging.Logger;
import javolution.util.FastList;
import javolution.util.FastMap;
import com.l2jserver.Config;
import com.l2jserver.L2DatabaseFactory;
import com.l2jserver.gameserver.SevenSigns;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.instance.L2DefenderInstance;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.network.clientpackets.Say2;
import com.l2jserver.gameserver.network.serverpackets.CreatureSay;
import com.l2jserver.util.Rnd;
/**
* 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 final Logger _log = Logger.getLogger(AutoChatHandler.class.getName());
private static final int DEFAULT_CHAT_DELAY = 60000; // 60 secs by default
protected Map<Integer, AutoChatInstance> _registeredChats;
private AutoChatHandler()
{
_registeredChats = new FastMap<>();
restoreChatData();
L2Spawn.addSpawnListener(this);
}
private void restoreChatData()
{
int numLoaded = 0;
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("SELECT * FROM auto_chat ORDER BY groupId ASC");
ResultSet rs = statement.executeQuery();
PreparedStatement statement2 = con.prepareStatement("SELECT * FROM auto_chat_text WHERE groupId=?");
while (rs.next())
{
numLoaded++;
statement2.setInt(1, rs.getInt("groupId"));
ResultSet rs2 = statement2.executeQuery();
statement2.clearParameters();
rs2.last();
String[] chatTexts = new String[rs2.getRow()];
int i = 0;
rs2.beforeFirst();
while (rs2.next())
{
chatTexts[i++] = rs2.getString("chatText");
}
registerGlobalChat(rs.getInt("npcId"), chatTexts, rs.getLong("chatDelay"));
}
statement2.close();
rs.close();
statement.close();
if (Config.DEBUG)
{
_log.info("AutoChatHandler: Loaded " + numLoaded + " chat group(s) from the database.");
}
}
catch (Exception e)
{
_log.log(Level.WARNING, "AutoSpawnHandler: Could not restore chat data: " + e.getMessage(), e);
}
finally
{
L2DatabaseFactory.close(con);
}
}
public void reload()
{
// unregister all registered spawns
for (AutoChatInstance aci : _registeredChats.values())
{
if (aci != null)
{
// clear timer
if (aci._chatTask != null)
{
aci._chatTask.cancel(true);
}
this.removeChat(aci);
}
}
// create clean list
_registeredChats = new FastMap<>();
// load
restoreChatData();
}
public static AutoChatHandler getInstance()
{
return SingletonHolder._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 int npcId
* @param String[] chatTexts
* @param int 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 L2Npc npcInst
* @param String[] chatTexts
* @param int chatDelay (-1 = default delay)
* @return AutoChatInstance chatInst
*/
public AutoChatInstance registerChat(L2Npc npcInst, String[] chatTexts, long chatDelay)
{
return registerChat(npcInst.getNpcId(), npcInst, chatTexts, chatDelay);
}
private final AutoChatInstance registerChat(int npcId, L2Npc npcInst, String[] chatTexts, long chatDelay)
{
AutoChatInstance chatInst = null;
if (chatDelay < 0)
{
chatDelay = DEFAULT_CHAT_DELAY + Rnd.nextInt(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 int npcId
* @return boolean removedSuccessfully
*/
public boolean removeChat(int npcId)
{
AutoChatInstance chatInst = _registeredChats.get(npcId);
return removeChat(chatInst);
}
/**
* Removes and cancels ALL auto chats for the given chat instance.
* @param AutoChatInstance chatInst
* @return boolean removedSuccessfully
*/
public boolean removeChat(AutoChatInstance chatInst)
{
if (chatInst == null)
{
return false;
}
_registeredChats.remove(chatInst.getNPCId());
chatInst.setActive(false);
if (Config.DEBUG)
{
_log.info("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 int id
* @param boolean byObjectId
* @return AutoChatInstance chatInst
*/
public AutoChatInstance getAutoChatInstance(int id, boolean byObjectId)
{
if (!byObjectId)
{
return _registeredChats.get(id);
}
for (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 boolean isActive
*/
public void setAutoChatActive(boolean isActive)
{
for (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(L2Npc npc)
{
synchronized (_registeredChats)
{
if (npc == null)
{
return;
}
int npcId = npc.getNpcId();
if (_registeredChats.containsKey(npcId))
{
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<>();
protected ScheduledFuture<?> _chatTask;
protected AutoChatInstance(int npcId, String[] chatTexts, long chatDelay, boolean isGlobal)
{
_defaultTexts = chatTexts;
_npcId = npcId;
_defaultDelay = chatDelay;
_globalChat = isGlobal;
if (Config.DEBUG)
{
_log.info("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 L2Npc npcInst
* @return int objectId
*/
public int addChatDefinition(L2Npc 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 L2Npc npcInst
* @param String[] chatTexts
* @param int chatDelay
* @return int objectId
*/
public int addChatDefinition(L2Npc npcInst, String[] chatTexts, long chatDelay)
{
int objectId = npcInst.getObjectId();
AutoChatDefinition chatDef = new AutoChatDefinition(this, npcInst, chatTexts, chatDelay);
if (npcInst instanceof L2DefenderInstance)
{
chatDef.setRandomChat(true);
}
_chatDefinitions.put(objectId, chatDef);
return objectId;
}
/**
* Removes a chat definition specified by the given object ID.
* @param int objectId
* @return boolean removedSuccessfully
*/
public boolean removeChatDefinition(int objectId)
{
if (!_chatDefinitions.containsKey(objectId))
{
return false;
}
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.
* @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 L2Npc[] getNPCInstanceList()
{
List<L2Npc> npcInsts = new FastList<>();
for (AutoChatDefinition chatDefinition : _chatDefinitions.values())
{
npcInsts.add(chatDefinition._npcInstance);
}
return npcInsts.toArray(new L2Npc[npcInsts.size()]);
}
/**
* A series of methods used to get and set default values for new chat definitions.
*/
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 int objectId
* @param long delayValue
*/
public void setChatDelay(int objectId, long delayValue)
{
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 int objectId
* @param String[] textsValue
*/
public void setChatTexts(int objectId, String[] textsValue)
{
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 int objectId
* @param boolean randValue
*/
public void setRandomChat(int objectId, boolean randValue)
{
AutoChatDefinition chatDef = getChatDefinition(objectId);
if (chatDef != null)
{
chatDef.setRandomChat(randValue);
}
}
/**
* Sets the activity of ALL auto chat definitions handled by this chat instance.
* @param boolean isActive
*/
public void setActive(boolean activeValue)
{
if (_isActive == activeValue)
{
return;
}
_isActive = activeValue;
if (!isGlobal())
{
for (AutoChatDefinition chatDefinition : _chatDefinitions.values())
{
chatDefinition.setActive(activeValue);
}
return;
}
if (isActive())
{
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 L2Npc _npcInstance;
protected AutoChatInstance _chatInstance;
private long _chatDelay = 0;
private String[] _chatTexts = null;
private boolean _isActiveDefinition;
private boolean _randomChat;
protected AutoChatDefinition(AutoChatInstance chatInst, L2Npc 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 _isActiveDefinition;
}
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)
{
AutoChatRunner acr = new AutoChatRunner(_npcId, _npcInstance.getObjectId());
if (getChatDelay() == 0)
{
// Schedule it set to 5Ms, isn't error, if use 0 sometine
// chatDefinition return null in AutoChatRunner
_chatTask = ThreadPoolManager.getInstance().scheduleGeneral(acr, 5);
}
else
{
_chatTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(acr, getChatDelay(), getChatDelay());
}
}
else
{
_chatTask.cancel(false);
}
_isActiveDefinition = activeValue;
}
}
/**
* Auto Chat Runner <BR>
* <BR>
* Represents the auto chat scheduled task for each chat instance.
* @author Tempy
*/
private class AutoChatRunner implements Runnable
{
private final int _runnerNpcId;
private final int _objectId;
protected AutoChatRunner(int pNpcId, int pObjectId)
{
_runnerNpcId = pNpcId;
_objectId = pObjectId;
}
@Override
public synchronized void run()
{
AutoChatInstance chatInst = _registeredChats.get(_runnerNpcId);
AutoChatDefinition[] chatDefinitions;
if (chatInst.isGlobal())
{
chatDefinitions = chatInst.getChatDefinitions();
}
else
{
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 (AutoChatDefinition chatDef : chatDefinitions)
{
try
{
L2Npc chatNpc = chatDef._npcInstance;
List<L2PcInstance> nearbyPlayers = new FastList<>();
List<L2PcInstance> nearbyGMs = new FastList<>();
for (L2Character player : chatNpc.getKnownList().getKnownCharactersInRadius(1500))
{
if (!(player instanceof L2PcInstance))
{
continue;
}
if (((L2PcInstance) player).isGM())
{
nearbyGMs.add((L2PcInstance) player);
}
else
{
nearbyPlayers.add((L2PcInstance) player);
}
}
int maxIndex = chatDef.getChatTexts().length;
int lastIndex = Rnd.nextInt(maxIndex);
String creatureName = chatNpc.getName();
String text;
if (!chatDef.isRandomChat())
{
lastIndex = chatDef._chatIndex + 1;
if (lastIndex == maxIndex)
{
lastIndex = 0;
}
chatDef._chatIndex = lastIndex;
}
text = chatDef.getChatTexts()[lastIndex];
if (text == null)
{
return;
}
if (!nearbyPlayers.isEmpty())
{
int randomPlayerIndex = Rnd.nextInt(nearbyPlayers.size());
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 (L2PcInstance nearbyPlayer : nearbyPlayers)
{
if (SevenSigns.getInstance().getPlayerCabal(nearbyPlayer.getObjectId()) == winningCabal)
{
text = text.replaceAll("%player_cabal_winner%", nearbyPlayer.getName());
break;
}
}
}
if (text.indexOf("%player_cabal_loser%") > -1)
{
for (L2PcInstance nearbyPlayer : nearbyPlayers)
{
if (SevenSigns.getInstance().getPlayerCabal(nearbyPlayer.getObjectId()) == losingCabal)
{
text = text.replaceAll("%player_cabal_loser%", nearbyPlayer.getName());
break;
}
}
}
}
if (text == null)
{
return;
}
if (!text.contains("%player_"))
{
CreatureSay cs = new CreatureSay(chatNpc.getObjectId(), Say2.ALL, creatureName, text);
for (L2PcInstance nearbyPlayer : nearbyPlayers)
{
nearbyPlayer.sendPacket(cs);
}
for (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 (Exception e)
{
_log.log(Level.WARNING, "Exception on AutoChatRunner.run(): " + e.getMessage(), e);
return;
}
}
}
}
}
@SuppressWarnings("synthetic-access")
private static class SingletonHolder
{
protected static final AutoChatHandler _instance = new AutoChatHandler();
}
}
@@ -0,0 +1,800 @@
/*
* 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.l2jserver.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.Level;
import java.util.logging.Logger;
import javolution.util.FastList;
import javolution.util.FastMap;
import com.l2jserver.Config;
import com.l2jserver.L2DatabaseFactory;
import com.l2jserver.gameserver.Announcements;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.datatables.MapRegionTable;
import com.l2jserver.gameserver.datatables.NpcTable;
import com.l2jserver.gameserver.datatables.SpawnTable;
import com.l2jserver.gameserver.idfactory.IdFactory;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.templates.chars.L2NpcTemplate;
import com.l2jserver.util.Rnd;
/**
* 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 final Logger _log = Logger.getLogger(AutoSpawnHandler.class.getName());
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;
private AutoSpawnHandler()
{
_registeredSpawns = new FastMap<>();
_runningSpawns = new FastMap<>();
restoreSpawnData();
}
public static AutoSpawnHandler getInstance()
{
return SingletonHolder._instance;
}
public final int size()
{
return _registeredSpawns.size();
}
public void reload()
{
// stop all timers
for (ScheduledFuture<?> sf : _runningSpawns.values())
{
if (sf != null)
{
sf.cancel(true);
}
}
// unregister all registered spawns
for (AutoSpawnInstance asi : _registeredSpawns.values())
{
if (asi != null)
{
this.removeSpawn(asi);
}
}
// create clean list
_registeredSpawns = new FastMap<>();
_runningSpawns = new FastMap<>();
// load
restoreSpawnData();
}
private void restoreSpawnData()
{
int numLoaded = 0;
Connection con = null;
try
{
PreparedStatement statement = null;
PreparedStatement statement2 = null;
ResultSet rs = null;
ResultSet rs2 = null;
con = L2DatabaseFactory.getInstance().getConnection();
// Restore spawn group data, then the location data.
statement = con.prepareStatement("SELECT * FROM random_spawn ORDER BY groupId ASC");
rs = statement.executeQuery();
statement2 = con.prepareStatement("SELECT * FROM random_spawn_loc WHERE groupId=?");
while (rs.next())
{
// Register random spawn group, set various options on the
// created spawn instance.
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.
statement2.setInt(1, rs.getInt("groupId"));
rs2 = statement2.executeQuery();
statement2.clearParameters();
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"));
}
rs2.close();
}
statement2.close();
rs.close();
statement.close();
if (Config.DEBUG)
{
_log.info("AutoSpawnHandler: Loaded " + numLoaded + " spawn group(s) from the database.");
}
}
catch (Exception e)
{
_log.log(Level.WARNING, "AutoSpawnHandler: Could not restore spawn data: " + e.getMessage(), e);
}
finally
{
L2DatabaseFactory.close(con);
}
}
/**
* Registers a spawn with the given parameters with the spawner, and marks it as active. Returns a AutoSpawnInstance containing info about the spawn.
* @param int npcId
* @param int[][] spawnPoints
* @param int initialDelay (If < 0 = default value)
* @param int respawnDelay (If < 0 = default value)
* @param int 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;
}
AutoSpawnInstance newSpawn = new AutoSpawnInstance(npcId, initialDelay, respawnDelay, despawnDelay);
if (spawnPoints != null)
{
for (int[] spawnPoint : spawnPoints)
{
newSpawn.addSpawnLocation(spawnPoint);
}
}
int newId = IdFactory.getInstance().getNextId();
newSpawn._objectId = newId;
_registeredSpawns.put(newId, newSpawn);
setSpawnActive(newSpawn, true);
if (Config.DEBUG)
{
_log.info("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 int npcId
* @param int initialDelay (If < 0 = default value)
* @param int respawnDelay (If < 0 = default value)
* @param int 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 AutoSpawnInstance 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.getNpcId());
// Cancel the currently associated running scheduled task.
ScheduledFuture<?> respawnTask = _runningSpawns.remove(spawnInst._objectId);
respawnTask.cancel(false);
if (Config.DEBUG)
{
_log.info("AutoSpawnHandler: Removed auto spawn for NPC ID " + spawnInst._npcId + " (Object ID = " + spawnInst._objectId + ").");
}
}
catch (Exception e)
{
_log.log(Level.WARNING, "AutoSpawnHandler: Could not auto spawn for NPC ID " + spawnInst._npcId + " (Object ID = " + spawnInst._objectId + "): " + e.getMessage(), e);
return false;
}
return true;
}
/**
* Remove a registered spawn from the list, specified by the given spawn object ID.
* @param int objectId
* @return boolean removedSuccessfully
*/
public void removeSpawn(int objectId)
{
removeSpawn(_registeredSpawns.get(objectId));
}
/**
* Sets the active state of the specified spawn.
* @param AutoSpawnInstance spawnInst
* @param boolean isActive
*/
public void setSpawnActive(AutoSpawnInstance spawnInst, boolean isActive)
{
if (spawnInst == null)
{
return;
}
int objectId = spawnInst._objectId;
if (isSpawnRegistered(objectId))
{
ScheduledFuture<?> spawnTask = null;
if (isActive)
{
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
{
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 boolean isActive
*/
public void setAllActive(boolean isActive)
{
if (_activeState == isActive)
{
return;
}
for (AutoSpawnInstance spawnInst : _registeredSpawns.values())
{
setSpawnActive(spawnInst, isActive);
}
_activeState = isActive;
}
/**
* Returns the number of milliseconds until the next occurrance of the given spawn.
* @param AutoSpawnInstance spawnInst
* @param long milliRemaining
*/
public final long getTimeToNextSpawn(AutoSpawnInstance spawnInst)
{
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 int id
* @param boolean isObjectId
* @return AutoSpawnInstance spawnInst
*/
public final AutoSpawnInstance getAutoSpawnInstance(int id, boolean isObjectId)
{
if (isObjectId)
{
if (isSpawnRegistered(id))
{
return _registeredSpawns.get(id);
}
}
else
{
for (AutoSpawnInstance spawnInst : _registeredSpawns.values())
{
if (spawnInst.getNpcId() == id)
{
return spawnInst;
}
}
}
return null;
}
public Map<Integer, AutoSpawnInstance> getAutoSpawnInstances(int npcId)
{
Map<Integer, AutoSpawnInstance> spawnInstList = new FastMap<>();
for (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 int 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 AutoSpawnInstance 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;
protected AutoSpawner(int objectId)
{
_objectId = objectId;
}
@Override
public void run()
{
try
{
// Retrieve the required spawn instance for this spawn task.
AutoSpawnInstance spawnInst = _registeredSpawns.get(_objectId);
// If the spawn is not scheduled to be active, cancel the spawn
// task.
if (!spawnInst.isSpawnActive())
{
return;
}
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;
}
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 + 1;
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.
L2NpcTemplate npcTemp = NpcTable.getInstance().getTemplate(spawnInst.getNpcId());
if (npcTemp == null)
{
_log.warning("Couldnt find NPC id" + spawnInst.getNpcId() + " Try to update your DP");
return;
}
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);
L2Npc 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);
}
}
String nearestTown = MapRegionTable.getInstance().getClosestTownName(npcInst);
// Announce to all players that the spawn has taken place, with
// the nearest town location.
if (spawnInst.isBroadcasting())
{
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)
{
AutoDespawner rd = new AutoDespawner(_objectId);
ThreadPoolManager.getInstance().scheduleAi(rd, spawnInst.getDespawnDelay() - 1000);
}
}
catch (Exception e)
{
_log.log(Level.WARNING, "AutoSpawnHandler: An error occurred while initializing spawn instance (Object ID = " + _objectId + "): " + e.getMessage(), e);
}
}
}
/**
* 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;
protected AutoDespawner(int objectId)
{
_objectId = objectId;
}
@Override
public void run()
{
try
{
AutoSpawnInstance spawnInst = _registeredSpawns.get(_objectId);
if (spawnInst == null)
{
_log.info("AutoSpawnHandler: No spawn registered for object ID = " + _objectId + ".");
return;
}
for (L2Npc npcInst : spawnInst.getNPCInstanceList())
{
if (npcInst == null)
{
continue;
}
npcInst.deleteMe();
SpawnTable.getInstance().deleteSpawn(npcInst.getSpawn(), false);
spawnInst.removeNpcInstance(npcInst);
if (Config.DEBUG)
{
_log.info("AutoSpawnHandler: Spawns removed for spawn instance (Object ID = " + _objectId + ").");
}
}
}
catch (Exception e)
{
_log.log(Level.WARNING, "AutoSpawnHandler: An error occurred while despawning spawn (Object ID = " + _objectId + "): " + e.getMessage(), e);
}
}
}
/**
* AutoSpawnInstance Class <BR>
* <BR>
* Stores information about a registered auto spawn.
* @author Tempy
*/
public static 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<L2Npc> _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(L2Npc npcInst)
{
return _npcList.add(npcInst);
}
protected boolean removeNpcInstance(L2Npc 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 L2Npc[] getNPCInstanceList()
{
L2Npc[] ret;
synchronized (_npcList)
{
ret = new L2Npc[_npcList.size()];
_npcList.toArray(ret);
}
return ret;
}
public L2Spawn[] getSpawns()
{
List<L2Spawn> npcSpawns = new FastList<>();
for (L2Npc 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 (IndexOutOfBoundsException e)
{
return null;
}
}
}
@SuppressWarnings("synthetic-access")
private static class SingletonHolder
{
protected static final AutoSpawnHandler _instance = new AutoSpawnHandler();
}
}
@@ -0,0 +1,299 @@
/*
* $Header: BlockList.java, 21/11/2005 14:53:53 luisantonioa Exp $
*
* $Author: luisantonioa $
* $Date: 21/11/2005 14:53:53 $
* $Revision: 1 $
* $Log: BlockList.java,v $
* Revision 1 21/11/2005 14:53:53 luisantonioa
* Added copyright notice
*
*
* 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.l2jserver.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.logging.Level;
import java.util.logging.Logger;
import javolution.util.FastList;
import javolution.util.FastMap;
import com.l2jserver.L2DatabaseFactory;
import com.l2jserver.gameserver.datatables.CharNameTable;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
/**
* This class ...
* @version $Revision: 1.2 $ $Date: 2004/06/27 08:12:59 $
*/
public class BlockList
{
private static Logger _log = Logger.getLogger(BlockList.class.getName());
private static Map<Integer, List<Integer>> _offlineList = new FastMap<>();
private final L2PcInstance _owner;
private List<Integer> _blockList;
public BlockList(L2PcInstance owner)
{
_owner = owner;
_blockList = _offlineList.get(owner.getObjectId());
if (_blockList == null)
{
_blockList = loadList(_owner.getObjectId());
}
}
private synchronized void addToBlockList(int target)
{
_blockList.add(target);
updateInDB(target, true);
}
private synchronized void removeFromBlockList(int target)
{
_blockList.remove(Integer.valueOf(target));
updateInDB(target, false);
}
public void playerLogout()
{
_offlineList.put(_owner.getObjectId(), _blockList);
}
private static List<Integer> loadList(int ObjId)
{
Connection con = null;
List<Integer> list = new FastList<>();
try
{
con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("SELECT friendId FROM character_friends WHERE charId=? AND relation=1");
statement.setInt(1, ObjId);
ResultSet rset = statement.executeQuery();
int friendId;
while (rset.next())
{
friendId = rset.getInt("friendId");
if (friendId == ObjId)
{
continue;
}
list.add(friendId);
}
rset.close();
statement.close();
}
catch (Exception e)
{
_log.log(Level.WARNING, "Error found in " + ObjId + " FriendList while loading BlockList: " + e.getMessage(), e);
}
finally
{
L2DatabaseFactory.close(con);
}
return list;
}
private void updateInDB(int targetId, boolean state)
{
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement;
if (state) // add
{
statement = con.prepareStatement("INSERT INTO character_friends (charId, friendId, relation) VALUES (?, ?, 1)");
statement.setInt(1, _owner.getObjectId());
statement.setInt(2, targetId);
}
else
// remove
{
statement = con.prepareStatement("DELETE FROM character_friends WHERE charId=? AND friendId=? AND relation=1");
statement.setInt(1, _owner.getObjectId());
statement.setInt(2, targetId);
}
statement.execute();
statement.close();
}
catch (Exception e)
{
_log.log(Level.WARNING, "Could not add block player: " + e.getMessage(), e);
}
finally
{
L2DatabaseFactory.close(con);
}
}
public boolean isInBlockList(L2PcInstance target)
{
return _blockList.contains(target.getObjectId());
}
public boolean isInBlockList(int targetId)
{
return _blockList.contains(targetId);
}
private boolean isBlockAll()
{
return _owner.getMessageRefusal();
}
public static boolean isBlocked(L2PcInstance listOwner, L2PcInstance target)
{
BlockList blockList = listOwner.getBlockList();
return blockList.isBlockAll() || blockList.isInBlockList(target);
}
public static boolean isBlocked(L2PcInstance listOwner, int targetId)
{
BlockList blockList = listOwner.getBlockList();
return blockList.isBlockAll() || blockList.isInBlockList(targetId);
}
private void setBlockAll(boolean state)
{
_owner.setMessageRefusal(state);
}
private List<Integer> getBlockList()
{
return _blockList;
}
public static void addToBlockList(L2PcInstance listOwner, int targetId)
{
if (listOwner == null)
{
return;
}
String charName = CharNameTable.getInstance().getNameById(targetId);
if (listOwner.getFriendList().contains(targetId))
{
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_ALREADY_IN_FRIENDS_LIST);
sm.addString(charName);
listOwner.sendPacket(sm);
return;
}
if (listOwner.getBlockList().getBlockList().contains(targetId))
{
listOwner.sendMessage("Already in ignore list.");
return;
}
listOwner.getBlockList().addToBlockList(targetId);
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_WAS_ADDED_TO_YOUR_IGNORE_LIST);
sm.addString(charName);
listOwner.sendPacket(sm);
L2PcInstance player = L2World.getInstance().getPlayer(targetId);
if (player != null)
{
sm = SystemMessage.getSystemMessage(SystemMessageId.S1_HAS_ADDED_YOU_TO_IGNORE_LIST);
sm.addString(listOwner.getName());
player.sendPacket(sm);
}
}
public static void removeFromBlockList(L2PcInstance listOwner, int targetId)
{
if (listOwner == null)
{
return;
}
SystemMessage sm;
String charName = CharNameTable.getInstance().getNameById(targetId);
if (!listOwner.getBlockList().getBlockList().contains(targetId))
{
sm = SystemMessage.getSystemMessage(SystemMessageId.TARGET_IS_INCORRECT);
listOwner.sendPacket(sm);
return;
}
listOwner.getBlockList().removeFromBlockList(targetId);
sm = SystemMessage.getSystemMessage(SystemMessageId.S1_WAS_REMOVED_FROM_YOUR_IGNORE_LIST);
sm.addString(charName);
listOwner.sendPacket(sm);
}
public static boolean isInBlockList(L2PcInstance listOwner, L2PcInstance target)
{
return listOwner.getBlockList().isInBlockList(target);
}
public 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)
{
int i = 1;
listOwner.sendPacket(SystemMessageId.BLOCK_LIST_HEADER);
for (int playerId : listOwner.getBlockList().getBlockList())
{
listOwner.sendMessage((i++) + ". " + CharNameTable.getInstance().getNameById(playerId));
}
listOwner.sendPacket(SystemMessageId.FRIEND_LIST_FOOTER);
}
/**
* @param ownerId object id of owner block list
* @param targetId object id of potential blocked player
* @return true if blocked
*/
public static boolean isInBlockList(int ownerId, int targetId)
{
L2PcInstance player = L2World.getInstance().getPlayer(ownerId);
if (player != null)
{
return BlockList.isBlocked(player, targetId);
}
if (!_offlineList.containsKey(ownerId))
{
_offlineList.put(ownerId, loadList(ownerId));
}
return _offlineList.get(ownerId).contains(targetId);
}
}
@@ -0,0 +1,229 @@
/*
* 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.l2jserver.gameserver.model;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jserver.gameserver.templates.StatsSet;
import com.l2jserver.util.Rnd;
/**
* @author kombat
*/
public final class ChanceCondition
{
protected static final Logger _log = Logger.getLogger(ChanceCondition.class.getName());
public static final int EVT_HIT = 1;
public static final int EVT_CRIT = 2;
public static final int EVT_CAST = 4;
public static final int EVT_PHYSICAL = 8;
public static final int EVT_MAGIC = 16;
public static final int EVT_MAGIC_GOOD = 32;
public static final int EVT_MAGIC_OFFENSIVE = 64;
public static final int EVT_ATTACKED = 128;
public static final int EVT_ATTACKED_HIT = 256;
public static final int EVT_ATTACKED_CRIT = 512;
public static final int EVT_HIT_BY_SKILL = 1024;
public static final int EVT_HIT_BY_OFFENSIVE_SKILL = 2048;
public static final int EVT_HIT_BY_GOOD_MAGIC = 4096;
public static final int EVT_EVADED_HIT = 8192;
public static final int EVT_ON_START = 16384;
public static final int EVT_ON_ACTION_TIME = 32768;
public static final int EVT_ON_EXIT = 65536;
public static enum TriggerType
{
// You hit an enemy
ON_HIT(1),
// You hit an enemy - was crit
ON_CRIT(2),
// You cast a skill
ON_CAST(4),
// You cast a skill - it was a physical one
ON_PHYSICAL(8),
// You cast a skill - it was a magic one
ON_MAGIC(16),
// You cast a skill - it was a magic one - good magic
ON_MAGIC_GOOD(32),
// You cast a skill - it was a magic one - offensive magic
ON_MAGIC_OFFENSIVE(64),
// You are attacked by enemy
ON_ATTACKED(128),
// You are attacked by enemy - by hit
ON_ATTACKED_HIT(256),
// You are attacked by enemy - by hit - was crit
ON_ATTACKED_CRIT(512),
// A skill was casted on you
ON_HIT_BY_SKILL(1024),
// An evil skill was casted on you
ON_HIT_BY_OFFENSIVE_SKILL(2048),
// A good skill was casted on you
ON_HIT_BY_GOOD_MAGIC(4096),
// Evading melee attack
ON_EVADED_HIT(8192),
// Effect only - on start
ON_START(16384),
// Effect only - each second
ON_ACTION_TIME(32768),
// Effect only - on exit
ON_EXIT(65536);
private final int _mask;
private TriggerType(int mask)
{
_mask = mask;
}
public final boolean check(int event)
{
return (_mask & event) != 0; // Trigger (sub-)type contains event (sub-)type
}
}
private final TriggerType _triggerType;
private final int _chance;
private final int _mindmg;
private final byte[] _elements;
private final int[] _activationSkills;
private final boolean _pvpOnly;
private ChanceCondition(TriggerType trigger, int chance, int mindmg, byte[] elements, int[] activationSkills, boolean pvpOnly)
{
_triggerType = trigger;
_chance = chance;
_mindmg = mindmg;
_elements = elements;
_pvpOnly = pvpOnly;
_activationSkills = activationSkills;
}
public static ChanceCondition parse(StatsSet set)
{
try
{
TriggerType trigger = set.getEnum("chanceType", TriggerType.class, null);
int chance = set.getInteger("activationChance", -1);
int mindmg = set.getInteger("activationMinDamage", -1);
String elements = set.getString("activationElements", null);
String activationSkills = set.getString("activationSkills", null);
boolean pvpOnly = set.getBool("pvpChanceOnly", false);
if (trigger != null)
{
return new ChanceCondition(trigger, chance, mindmg, parseElements(elements), parseActivationSkills(activationSkills), pvpOnly);
}
}
catch (Exception e)
{
_log.log(Level.WARNING, "", e);
}
return null;
}
public static ChanceCondition parse(String chanceType, int chance, int mindmg, String elements, String activationSkills, boolean pvpOnly)
{
try
{
if (chanceType == null)
{
return null;
}
TriggerType trigger = Enum.valueOf(TriggerType.class, chanceType);
if (trigger != null)
{
return new ChanceCondition(trigger, chance, mindmg, parseElements(elements), parseActivationSkills(activationSkills), pvpOnly);
}
}
catch (Exception e)
{
_log.log(Level.WARNING, "", e);
}
return null;
}
public static final byte[] parseElements(String list)
{
if (list == null)
{
return null;
}
String[] valuesSplit = list.split(",");
byte[] elements = new byte[valuesSplit.length];
for (int i = 0; i < valuesSplit.length; i++)
{
elements[i] = Byte.parseByte(valuesSplit[i]);
}
Arrays.sort(elements);
return elements;
}
public static final int[] parseActivationSkills(String list)
{
if (list == null)
{
return null;
}
String[] valuesSplit = list.split(",");
int[] skillIds = new int[valuesSplit.length];
for (int i = 0; i < valuesSplit.length; i++)
{
skillIds[i] = Integer.parseInt(valuesSplit[i]);
}
return skillIds;
}
public boolean trigger(int event, int damage, byte element, boolean playable, L2Skill skill)
{
if (_pvpOnly && !playable)
{
return false;
}
if ((_elements != null) && (Arrays.binarySearch(_elements, element) < 0))
{
return false;
}
if ((_activationSkills != null) && (skill != null) && (Arrays.binarySearch(_activationSkills, skill.getId()) < 0))
{
return false;
}
// if the skill has "activationMinDamage" setted to higher than -1(default)
// and if "activationMinDamage" is still higher than the recieved damage, the skill wont trigger
if ((_mindmg > -1) && (_mindmg > damage))
{
return false;
}
return _triggerType.check(event) && ((_chance < 0) || (Rnd.get(100) < _chance));
}
@Override
public String toString()
{
return "Trigger[" + _chance + ";" + _triggerType.toString() + "]";
}
}
@@ -0,0 +1,261 @@
/*
* 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.l2jserver.gameserver.model;
import java.util.logging.Level;
import java.util.logging.Logger;
import javolution.util.FastMap;
import com.l2jserver.gameserver.datatables.SkillTable;
import com.l2jserver.gameserver.handler.ISkillHandler;
import com.l2jserver.gameserver.handler.SkillHandler;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.L2Playable;
import com.l2jserver.gameserver.network.serverpackets.MagicSkillLaunched;
import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse;
import com.l2jserver.gameserver.skills.effects.EffectChanceSkillTrigger;
import com.l2jserver.gameserver.templates.skills.L2SkillType;
/**
* CT2.3: Added support for allowing effect as a chance skill trigger (DrHouse)
* @author kombat
*/
public class ChanceSkillList extends FastMap<IChanceSkillTrigger, ChanceCondition>
{
protected static final Logger _log = Logger.getLogger(ChanceSkillList.class.getName());
private static final long serialVersionUID = 1L;
private final L2Character _owner;
public ChanceSkillList(L2Character owner)
{
super();
shared();
_owner = owner;
}
public L2Character getOwner()
{
return _owner;
}
public void onHit(L2Character target, int damage, boolean ownerWasHit, boolean wasCrit)
{
int event;
if (ownerWasHit)
{
event = ChanceCondition.EVT_ATTACKED | ChanceCondition.EVT_ATTACKED_HIT;
if (wasCrit)
{
event |= ChanceCondition.EVT_ATTACKED_CRIT;
}
}
else
{
event = ChanceCondition.EVT_HIT;
if (wasCrit)
{
event |= ChanceCondition.EVT_CRIT;
}
}
onEvent(event, damage, target, null, Elementals.NONE);
}
public void onEvadedHit(L2Character attacker)
{
onEvent(ChanceCondition.EVT_EVADED_HIT, 0, attacker, null, Elementals.NONE);
}
public void onSkillHit(L2Character target, L2Skill skill, boolean ownerWasHit)
{
int event;
if (ownerWasHit)
{
event = ChanceCondition.EVT_HIT_BY_SKILL;
if (skill.isOffensive())
{
event |= ChanceCondition.EVT_HIT_BY_OFFENSIVE_SKILL;
event |= ChanceCondition.EVT_ATTACKED;
}
else
{
event |= ChanceCondition.EVT_HIT_BY_GOOD_MAGIC;
}
}
else
{
event = ChanceCondition.EVT_CAST;
event |= skill.isMagic() ? ChanceCondition.EVT_MAGIC : ChanceCondition.EVT_PHYSICAL;
event |= skill.isOffensive() ? ChanceCondition.EVT_MAGIC_OFFENSIVE : ChanceCondition.EVT_MAGIC_GOOD;
}
onEvent(event, 0, target, skill, skill.getElement());
}
public void onStart(byte element)
{
onEvent(ChanceCondition.EVT_ON_START, 0, _owner, null, element);
}
public void onActionTime(byte element)
{
onEvent(ChanceCondition.EVT_ON_ACTION_TIME, 0, _owner, null, element);
}
public void onExit(byte element)
{
onEvent(ChanceCondition.EVT_ON_EXIT, 0, _owner, null, element);
}
public void onEvent(int event, int damage, L2Character target, L2Skill skill, byte element)
{
if (_owner.isDead())
{
return;
}
final boolean playable = target instanceof L2Playable;
for (FastMap.Entry<IChanceSkillTrigger, ChanceCondition> e = head(), end = tail(); (e = e.getNext()) != end;)
{
if ((e.getValue() != null) && e.getValue().trigger(event, damage, element, playable, skill))
{
if (e.getKey() instanceof L2Skill)
{
makeCast((L2Skill) e.getKey(), target);
}
else if (e.getKey() instanceof EffectChanceSkillTrigger)
{
makeCast((EffectChanceSkillTrigger) e.getKey(), target);
}
}
}
}
private void makeCast(L2Skill skill, L2Character target)
{
try
{
if (skill.getWeaponDependancy(_owner, true) && skill.checkCondition(_owner, target, false))
{
if (skill.triggersChanceSkill()) // skill will trigger another skill, but only if its not chance skill
{
skill = SkillTable.getInstance().getInfo(skill.getTriggeredChanceId(), skill.getTriggeredChanceLevel());
if ((skill == null) || (skill.getSkillType() == L2SkillType.NOTDONE))
{
return;
}
}
if (_owner.isSkillDisabled(skill))
{
return;
}
if (skill.getReuseDelay() > 0)
{
_owner.disableSkill(skill, skill.getReuseDelay());
}
L2Object[] targets = skill.getTargetList(_owner, false, target);
if (targets.length == 0)
{
return;
}
L2Character firstTarget = (L2Character) targets[0];
ISkillHandler handler = SkillHandler.getInstance().getSkillHandler(skill.getSkillType());
_owner.broadcastPacket(new MagicSkillLaunched(_owner, skill.getDisplayId(), skill.getLevel(), targets));
_owner.broadcastPacket(new MagicSkillUse(_owner, firstTarget, skill.getDisplayId(), skill.getLevel(), 0, 0));
// Launch the magic skill and calculate its effects
// TODO: once core will support all possible effects, use effects (not handler)
if (handler != null)
{
handler.useSkill(_owner, skill, targets);
}
else
{
skill.useSkill(_owner, targets);
}
}
}
catch (Exception e)
{
_log.log(Level.WARNING, "", e);
}
}
private void makeCast(EffectChanceSkillTrigger effect, L2Character target)
{
try
{
if ((effect == null) || !effect.triggersChanceSkill())
{
return;
}
L2Skill triggered = SkillTable.getInstance().getInfo(effect.getTriggeredChanceId(), effect.getTriggeredChanceLevel());
if (triggered == null)
{
return;
}
L2Character caster = triggered.getTargetType() == L2Skill.SkillTargetType.TARGET_SELF ? _owner : effect.getEffector();
if ((caster == null) || (triggered.getSkillType() == L2SkillType.NOTDONE) || caster.isSkillDisabled(triggered))
{
return;
}
if (triggered.getReuseDelay() > 0)
{
caster.disableSkill(triggered, triggered.getReuseDelay());
}
L2Object[] targets = triggered.getTargetList(caster, false, target);
if (targets.length == 0)
{
return;
}
L2Character firstTarget = (L2Character) targets[0];
ISkillHandler handler = SkillHandler.getInstance().getSkillHandler(triggered.getSkillType());
_owner.broadcastPacket(new MagicSkillLaunched(_owner, triggered.getDisplayId(), triggered.getLevel(), targets));
_owner.broadcastPacket(new MagicSkillUse(_owner, firstTarget, triggered.getDisplayId(), triggered.getLevel(), 0, 0));
// Launch the magic skill and calculate its effects
// TODO: once core will support all possible effects, use effects (not handler)
if (handler != null)
{
handler.useSkill(caster, triggered, targets);
}
else
{
triggered.useSkill(caster, targets);
}
}
catch (Exception e)
{
_log.log(Level.WARNING, "", e);
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,399 @@
/*
* 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.l2jserver.gameserver.model;
import com.l2jserver.gameserver.model.itemcontainer.Inventory;
import com.l2jserver.gameserver.model.itemcontainer.PcInventory;
/**
* Used to Store data sent to Client for Character.<br>
* 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;
private int _pkKills = 0;
private int _pvpKills = 0;
private int _augmentationId = 0;
private int _transformId = 0;
private int _x = 0;
private int _y = 0;
private int _z = 0;
private String _htmlPrefix = null;
private int _accessLevel = 0;
/**
* Constructor for CharSelectInfoPackage.
* @param objectId character object Id.
* @param name the character's name.
*/
public CharSelectInfoPackage(int objectId, String name)
{
setObjectId(objectId);
_name = name;
_paperdoll = PcInventory.restoreVisibleInventory(objectId);
}
/**
* @return the character object Id.
*/
public int getObjectId()
{
return _objectId;
}
public void setObjectId(int objectId)
{
_objectId = objectId;
}
/**
* @return the character's access level.
*/
public int getAccessLevel()
{
return _accessLevel;
}
/**
* @param level the character's access level to be set.
*/
public void setAccessLevel(int level)
{
_accessLevel = level;
}
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_RHAND][2];
}
public void setKarma(int k)
{
_karma = k;
}
public int getKarma()
{
return _karma;
}
public void setAugmentationId(int augmentationId)
{
_augmentationId = augmentationId;
}
public int getAugmentationId()
{
return _augmentationId;
}
public void setPkKills(int PkKills)
{
_pkKills = PkKills;
}
public int getPkKills()
{
return _pkKills;
}
public void setPvPKills(int PvPKills)
{
_pvpKills = PvPKills;
}
public int getPvPKills()
{
return _pvpKills;
}
public int getTransformId()
{
return _transformId;
}
public void setTransformId(int id)
{
_transformId = id;
}
public int getX()
{
return _x;
}
public int getY()
{
return _y;
}
public int getZ()
{
return _z;
}
public void setX(int x)
{
_x = x;
}
public void setY(int y)
{
_y = y;
}
public void setZ(int z)
{
_z = z;
}
public String getHtmlPrefix()
{
return _htmlPrefix;
}
public void setHtmlPrefix(String s)
{
_htmlPrefix = s;
}
}
@@ -0,0 +1,76 @@
/*
* 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.l2jserver.gameserver.model;
import com.l2jserver.Config;
import com.l2jserver.gameserver.model.L2ItemInstance.ItemLocation;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.itemcontainer.Warehouse;
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 String getName()
{
return "ClanWarehouse";
}
@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);
}
}
@@ -0,0 +1,116 @@
/*
* 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.l2jserver.gameserver.model;
import com.l2jserver.Config;
import com.l2jserver.gameserver.datatables.ItemTable;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.InventoryUpdate;
import com.l2jserver.gameserver.network.serverpackets.ItemList;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
public class CombatFlag
{
// private static final Logger _log = Logger.getLogger(CombatFlag.class.getName());
protected L2PcInstance _player = null;
public int playerId = 0;
private L2ItemInstance _item = null;
private final Location _location;
public L2ItemInstance itemInstance;
private final int _itemId;
// =========================================================
// Constructor
public CombatFlag(int fort_id, int x, int y, int z, int heading, int item_id)
{
_location = new Location(x, y, z, heading);
_itemId = item_id;
}
public synchronized void spawnMe()
{
// Init the dropped L2ItemInstance and add it in the world as a visible object at the position where mob was last
L2ItemInstance i = ItemTable.getInstance().createItem("Combat", _itemId, 1, null, null);
i.dropMe(null, _location.getX(), _location.getY(), _location.getZ());
itemInstance = i;
}
public synchronized void unSpawnMe()
{
if (_player != null)
{
dropIt();
}
if (itemInstance != null)
{
itemInstance.decayMe();
}
}
public boolean activate(L2PcInstance player, L2ItemInstance item)
{
if (player.isMounted())
{
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.CANNOT_EQUIP_ITEM_DUE_TO_BAD_CONDITION));
return false;
}
// Player holding it data
_player = player;
playerId = _player.getObjectId();
itemInstance = null;
// Equip with the weapon
_item = item;
_player.getInventory().equipItem(_item);
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_EQUIPPED);
sm.addItemName(_item);
_player.sendPacket(sm);
// Refresh inventory
if (!Config.FORCE_INVENTORY_UPDATE)
{
InventoryUpdate iu = new InventoryUpdate();
iu.addItem(_item);
_player.sendPacket(iu);
}
else
{
_player.sendPacket(new ItemList(_player, false));
}
// Refresh player stats
_player.broadcastUserInfo();
_player.setCombatFlagEquipped(true);
return true;
}
public void dropIt()
{
// Reset player stats
_player.setCombatFlagEquipped(false);
int slot = _player.getInventory().getSlotFromItem(_item);
_player.getInventory().unEquipItemInBodySlot(slot);
_player.destroyItem("CombatFlag", _item, null, true);
_item = null;
_player.broadcastUserInfo();
_player = null;
playerId = 0;
}
}
@@ -0,0 +1,786 @@
/*
* 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.l2jserver.gameserver.model;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.concurrent.ScheduledFuture;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jserver.Config;
import com.l2jserver.L2DatabaseFactory;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.datatables.SkillTable;
import com.l2jserver.gameserver.instancemanager.CursedWeaponsManager;
import com.l2jserver.gameserver.instancemanager.TransformationManager;
import com.l2jserver.gameserver.model.actor.L2Attackable;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.Earthquake;
import com.l2jserver.gameserver.network.serverpackets.ExRedSky;
import com.l2jserver.gameserver.network.serverpackets.InventoryUpdate;
import com.l2jserver.gameserver.network.serverpackets.ItemList;
import com.l2jserver.gameserver.network.serverpackets.SocialAction;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
import com.l2jserver.gameserver.network.serverpackets.UserInfo;
import com.l2jserver.gameserver.templates.item.L2Item;
import com.l2jserver.gameserver.util.Broadcast;
import com.l2jserver.util.Point3D;
import com.l2jserver.util.Rnd;
public class CursedWeapon
{
private static final Logger _log = Logger.getLogger(CursedWeaponsManager.class.getName());
// _name is the name of the cursed weapon associated with its ID.
private final String _name;
// _itemId is the Item ID of the cursed weapon.
private final int _itemId;
// _skillId is the skills ID.
private final int _skillId;
private final int _skillMaxLevel;
private int _dropRate;
private int _duration;
private int _durationLost;
private int _disapearChance;
private int _stageKills;
// this should be false unless if the cursed weapon is dropped, in that case it would be true.
private boolean _isDropped = false;
// this sets the cursed weapon status to true only if a player has the cursed weapon, otherwise this should be false.
private boolean _isActivated = false;
private ScheduledFuture<?> _removeTask;
private int _nbKills = 0;
private long _endTime = 0;
private int _playerId = 0;
protected L2PcInstance _player = null;
private L2ItemInstance _item = null;
private int _playerKarma = 0;
private int _playerPkKills = 0;
protected int transformationId = 0;
private static final int[] TRANSFORM_IDS = new int[]
{
3630,
3631
};
// =========================================================
// Constructor
public CursedWeapon(int itemId, int skillId, String name)
{
_name = name;
_itemId = itemId;
_skillId = skillId;
_skillMaxLevel = SkillTable.getInstance().getMaxLevel(_skillId);
}
// =========================================================
// Private
public void endOfLife()
{
if (_isActivated)
{
if ((_player != null) && _player.isOnline())
{
// Remove from player
_log.info(_name + " being removed online.");
_player.abortAttack();
_player.setKarma(_playerKarma);
_player.setPkKills(_playerPkKills);
_player.setCursedWeaponEquippedId(0);
removeSkill();
// Remove
_player.getInventory().unEquipItemInBodySlot(L2Item.SLOT_LR_HAND);
_player.store();
// Destroy
L2ItemInstance removedItem = _player.getInventory().destroyItemByItemId("", _itemId, 1, _player, null);
if (!Config.FORCE_INVENTORY_UPDATE)
{
InventoryUpdate iu = new InventoryUpdate();
if (removedItem.getCount() == 0)
{
iu.addRemovedItem(removedItem);
}
else
{
iu.addModifiedItem(removedItem);
}
_player.sendPacket(iu);
}
else
{
_player.sendPacket(new ItemList(_player, true));
}
_player.broadcastUserInfo();
}
else
{
// Remove from Db
_log.info(_name + " being removed offline.");
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection();
// Delete the item
PreparedStatement statement = con.prepareStatement("DELETE FROM items WHERE owner_id=? AND item_id=?");
statement.setInt(1, _playerId);
statement.setInt(2, _itemId);
if (statement.executeUpdate() != 1)
{
_log.warning("Error while deleting itemId " + _itemId + " from userId " + _playerId);
}
statement.close();
/*
* Yesod: Skill is not stored into database any more. // Delete the skill statement = con.prepareStatement("DELETE FROM character_skills WHERE charId=? AND skill_id=?"); statement.setInt(1, _playerId); statement.setInt(2, _skillId); if (statement.executeUpdate() != 1) {
* _log.warning("Error while deleting skillId "+ _skillId +" from userId "+_playerId); }
*/
// Restore the karma
statement = con.prepareStatement("UPDATE characters SET karma=?, pkkills=? WHERE charId=?");
statement.setInt(1, _playerKarma);
statement.setInt(2, _playerPkKills);
statement.setInt(3, _playerId);
if (statement.executeUpdate() != 1)
{
_log.warning("Error while updating karma & pkkills for userId " + _playerId);
}
statement.close();
}
catch (Exception e)
{
_log.log(Level.WARNING, "Could not delete : " + e.getMessage(), e);
}
finally
{
L2DatabaseFactory.close(con);
}
}
}
else
{
// either this cursed weapon is in the inventory of someone who has another cursed weapon equipped,
// OR this cursed weapon is on the ground.
if ((_player != null) && (_player.getInventory().getItemByItemId(_itemId) != null))
{
// Destroy
L2ItemInstance removedItem = _player.getInventory().destroyItemByItemId("", _itemId, 1, _player, null);
if (!Config.FORCE_INVENTORY_UPDATE)
{
InventoryUpdate iu = new InventoryUpdate();
if (removedItem.getCount() == 0)
{
iu.addRemovedItem(removedItem);
}
else
{
iu.addModifiedItem(removedItem);
}
_player.sendPacket(iu);
}
else
{
_player.sendPacket(new ItemList(_player, true));
}
_player.broadcastUserInfo();
}
// is dropped on the ground
else if (_item != null)
{
_item.decayMe();
L2World.getInstance().removeObject(_item);
_log.info(_name + " item has been removed from World.");
}
}
// Delete infos from table if any
CursedWeaponsManager.removeFromDb(_itemId);
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_HAS_DISAPPEARED);
sm.addItemName(_itemId);
CursedWeaponsManager.announce(sm);
// Reset state
cancelTask();
_isActivated = false;
_isDropped = false;
_endTime = 0;
_player = null;
_playerId = 0;
_playerKarma = 0;
_playerPkKills = 0;
_item = null;
_nbKills = 0;
}
private void cancelTask()
{
if (_removeTask != null)
{
_removeTask.cancel(true);
_removeTask = null;
}
}
private class RemoveTask implements Runnable
{
protected RemoveTask()
{
}
@Override
public void run()
{
if (System.currentTimeMillis() >= getEndTime())
{
endOfLife();
}
}
}
private void dropIt(L2Attackable attackable, L2PcInstance player)
{
dropIt(attackable, player, null, true);
}
private void dropIt(L2Attackable attackable, L2PcInstance player, L2Character killer, boolean fromMonster)
{
_isActivated = false;
if (fromMonster)
{
_item = attackable.dropItem(player, _itemId, 1);
_item.setDropTime(0); // Prevent item from being removed by ItemsAutoDestroy
// RedSky and Earthquake
ExRedSky packet = new ExRedSky(10);
Earthquake eq = new Earthquake(player.getX(), player.getY(), player.getZ(), 14, 3);
Broadcast.toAllOnlinePlayers(packet);
Broadcast.toAllOnlinePlayers(eq);
}
else
{
_item = _player.getInventory().getItemByItemId(_itemId);
_player.dropItem("DieDrop", _item, killer, true);
_player.setKarma(_playerKarma);
_player.setPkKills(_playerPkKills);
_player.setCursedWeaponEquippedId(0);
removeSkill();
_player.abortAttack();
// L2ItemInstance item = _player.getInventory().getItemByItemId(_itemId);
// _player.getInventory().dropItem("DieDrop", item, _player, null);
// _player.getInventory().getItemByItemId(_itemId).dropMe(_player, _player.getX(), _player.getY(), _player.getZ());
}
_isDropped = true;
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S2_WAS_DROPPED_IN_THE_S1_REGION);
if (player != null)
{
sm.addZoneName(player.getX(), player.getY(), player.getZ()); // Region Name
}
else if (_player != null)
{
sm.addZoneName(_player.getX(), _player.getY(), _player.getZ()); // Region Name
}
else
{
sm.addZoneName(killer.getX(), killer.getY(), killer.getZ()); // Region Name
}
sm.addItemName(_itemId);
CursedWeaponsManager.announce(sm); // in the Hot Spring region
}
public void cursedOnLogin()
{
doTransform();
giveSkill();
SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.S2_OWNER_HAS_LOGGED_INTO_THE_S1_REGION);
msg.addZoneName(_player.getX(), _player.getY(), _player.getZ());
msg.addItemName(_player.getCursedWeaponEquippedId());
CursedWeaponsManager.announce(msg);
CursedWeapon cw = CursedWeaponsManager.getInstance().getCursedWeapon(_player.getCursedWeaponEquippedId());
SystemMessage msg2 = SystemMessage.getSystemMessage(SystemMessageId.S2_MINUTE_OF_USAGE_TIME_ARE_LEFT_FOR_S1);
int timeLeft = (int) (cw.getTimeLeft() / 60000);
msg2.addItemName(_player.getCursedWeaponEquippedId());
msg2.addNumber(timeLeft);
_player.sendPacket(msg2);
}
/**
* Yesod:<br>
* Rebind the passive skill belonging to the CursedWeapon. Invoke this method if the weapon owner switches to a subclass.
*/
public void giveSkill()
{
int level = 1 + (_nbKills / _stageKills);
if (level > _skillMaxLevel)
{
level = _skillMaxLevel;
}
L2Skill skill = SkillTable.getInstance().getInfo(_skillId, level);
// Yesod:
// To properly support subclasses this skill can not be stored.
_player.addSkill(skill, false);
// Void Burst, Void Flow
skill = SkillTable.FrequentSkill.VOID_BURST.getSkill();
_player.addSkill(skill, false);
skill = SkillTable.FrequentSkill.VOID_FLOW.getSkill();
_player.addSkill(skill, false);
_player.setTransformAllowedSkills(TRANSFORM_IDS);
if (Config.DEBUG)
{
_log.info("Player " + _player.getName() + " has been awarded with skill " + skill);
}
_player.sendSkillList();
}
public void doTransform()
{
if (_itemId == 8689)
{
transformationId = 302;
}
else if (_itemId == 8190)
{
transformationId = 301;
}
if (_player.isTransformed() || _player.isInStance())
{
_player.stopTransformation(true);
ThreadPoolManager.getInstance().scheduleGeneral(() -> TransformationManager.getInstance().transformPlayer(transformationId, _player), 500);
}
else
{
TransformationManager.getInstance().transformPlayer(transformationId, _player);
}
}
public void removeSkill()
{
_player.removeSkill(_skillId);
_player.removeSkill(SkillTable.FrequentSkill.VOID_BURST.getSkill().getId());
_player.removeSkill(SkillTable.FrequentSkill.VOID_FLOW.getSkill().getId());
_player.untransform();
_player.sendSkillList();
}
// =========================================================
// Public
public void reActivate()
{
_isActivated = true;
if ((_endTime - System.currentTimeMillis()) <= 0)
{
endOfLife();
}
else
{
_removeTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new RemoveTask(), _durationLost * 12000L, _durationLost * 12000L);
}
}
public boolean checkDrop(L2Attackable attackable, L2PcInstance player)
{
if (Rnd.get(100000) < _dropRate)
{
// Drop the item
dropIt(attackable, player);
// Start the Life Task
_endTime = System.currentTimeMillis() + (_duration * 60000L);
_removeTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new RemoveTask(), _durationLost * 12000L, _durationLost * 12000L);
return true;
}
return false;
}
public void activate(L2PcInstance player, L2ItemInstance item)
{
// if the player is mounted, attempt to unmount first. Only allow picking up
// the zariche if unmounting is successful.
if (player.isMounted())
{
if (!player.dismount())
{
// TODO: correct this custom message.
player.sendMessage("You may not pick up this item while riding in this territory");
player.dropItem("InvDrop", item, null, true);
return;
}
}
_isActivated = true;
// Player holding it data
_player = player;
_playerId = _player.getObjectId();
_playerKarma = _player.getKarma();
_playerPkKills = _player.getPkKills();
saveData();
// Change player stats
_player.setCursedWeaponEquippedId(_itemId);
_player.setKarma(9999999);
_player.setPkKills(0);
if (_player.isInParty())
{
_player.getParty().removePartyMember(_player);
}
// Disable All Skills
// Do Transform
doTransform();
// Add skill
giveSkill();
// Equip with the weapon
_item = item;
// L2ItemInstance[] items =
_player.getInventory().equipItem(_item);
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_EQUIPPED);
sm.addItemName(_item);
_player.sendPacket(sm);
// Fully heal player
_player.setCurrentHpMp(_player.getMaxHp(), _player.getMaxMp());
_player.setCurrentCp(_player.getMaxCp());
// Refresh inventory
if (!Config.FORCE_INVENTORY_UPDATE)
{
InventoryUpdate iu = new InventoryUpdate();
iu.addItem(_item);
// iu.addItems(Arrays.asList(items));
_player.sendPacket(iu);
}
else
{
_player.sendPacket(new ItemList(_player, false));
}
// Refresh player stats
_player.broadcastUserInfo();
SocialAction atk = new SocialAction(_player, 17);
_player.broadcastPacket(atk);
sm = SystemMessage.getSystemMessage(SystemMessageId.THE_OWNER_OF_S2_HAS_APPEARED_IN_THE_S1_REGION);
sm.addZoneName(_player.getX(), _player.getY(), _player.getZ()); // Region Name
sm.addItemName(_item);
CursedWeaponsManager.announce(sm);
}
public void saveData()
{
if (Config.DEBUG)
{
_log.info("CursedWeapon: Saving data to disk.");
}
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection();
// Delete previous datas
PreparedStatement statement = con.prepareStatement("DELETE FROM cursed_weapons WHERE itemId = ?");
statement.setInt(1, _itemId);
statement.executeUpdate();
if (_isActivated)
{
statement = con.prepareStatement("INSERT INTO cursed_weapons (itemId, charId, playerKarma, playerPkKills, nbKills, endTime) VALUES (?, ?, ?, ?, ?, ?)");
statement.setInt(1, _itemId);
statement.setInt(2, _playerId);
statement.setInt(3, _playerKarma);
statement.setInt(4, _playerPkKills);
statement.setInt(5, _nbKills);
statement.setLong(6, _endTime);
statement.executeUpdate();
statement.close();
}
}
catch (SQLException e)
{
_log.log(Level.SEVERE, "CursedWeapon: Failed to save data.", e);
}
finally
{
L2DatabaseFactory.close(con);
}
}
public void dropIt(L2Character killer)
{
if (Rnd.get(100) <= _disapearChance)
{
// Remove it
endOfLife();
}
else
{
// Unequip & Drop
dropIt(null, null, killer, false);
// Reset player stats
_player.setKarma(_playerKarma);
_player.setPkKills(_playerPkKills);
_player.setCursedWeaponEquippedId(0);
removeSkill();
_player.abortAttack();
_player.broadcastUserInfo();
}
}
public void increaseKills()
{
_nbKills++;
if ((_player != null) && _player.isOnline())
{
_player.setPkKills(_nbKills);
_player.sendPacket(new UserInfo(_player));
if (((_nbKills % _stageKills) == 0) && (_nbKills <= (_stageKills * (_skillMaxLevel - 1))))
{
giveSkill();
}
}
// Reduce time-to-live
_endTime -= _durationLost * 60000L;
saveData();
}
// =========================================================
// Setter
public void setDisapearChance(int disapearChance)
{
_disapearChance = disapearChance;
}
public void setDropRate(int dropRate)
{
_dropRate = dropRate;
}
public void setDuration(int duration)
{
_duration = duration;
}
public void setDurationLost(int durationLost)
{
_durationLost = durationLost;
}
public void setStageKills(int stageKills)
{
_stageKills = stageKills;
}
public void setNbKills(int nbKills)
{
_nbKills = nbKills;
}
public void setPlayerId(int playerId)
{
_playerId = playerId;
}
public void setPlayerKarma(int playerKarma)
{
_playerKarma = playerKarma;
}
public void setPlayerPkKills(int playerPkKills)
{
_playerPkKills = playerPkKills;
}
public void setActivated(boolean isActivated)
{
_isActivated = isActivated;
}
public void setDropped(boolean isDropped)
{
_isDropped = isDropped;
}
public void setEndTime(long endTime)
{
_endTime = endTime;
}
public void setPlayer(L2PcInstance player)
{
_player = player;
}
public void setItem(L2ItemInstance item)
{
_item = item;
}
// =========================================================
// Getter
public boolean isActivated()
{
return _isActivated;
}
public boolean isDropped()
{
return _isDropped;
}
public long getEndTime()
{
return _endTime;
}
public String getName()
{
return _name;
}
public int getItemId()
{
return _itemId;
}
public int getSkillId()
{
return _skillId;
}
public int getPlayerId()
{
return _playerId;
}
public L2PcInstance getPlayer()
{
return _player;
}
public int getPlayerKarma()
{
return _playerKarma;
}
public int getPlayerPkKills()
{
return _playerPkKills;
}
public int getNbKills()
{
return _nbKills;
}
public int getStageKills()
{
return _stageKills;
}
public boolean isActive()
{
return _isActivated || _isDropped;
}
public int getLevel()
{
if (_nbKills > (_stageKills * _skillMaxLevel))
{
return _skillMaxLevel;
}
return (_nbKills / _stageKills);
}
public long getTimeLeft()
{
return _endTime - System.currentTimeMillis();
}
public void goTo(L2PcInstance player)
{
if (player == null)
{
return;
}
if (_isActivated && (_player != null))
{
// Go to player holding the weapon
player.teleToLocation(_player.getX(), _player.getY(), _player.getZ() + 20, true);
}
else if (_isDropped && (_item != null))
{
// Go to item on the ground
player.teleToLocation(_item.getX(), _item.getY(), _item.getZ() + 20, true);
}
else
{
player.sendMessage(_name + " isn't in the World.");
}
}
public Point3D getWorldPosition()
{
if (_isActivated && (_player != null))
{
return _player.getPosition().getWorldPosition();
}
if (_isDropped && (_item != null))
{
return _item.getPosition().getWorldPosition();
}
return null;
}
public long getDuration()
{
return _duration;
}
}
@@ -0,0 +1,204 @@
/*
* $Header$
*
* $Author$
* $Date$
* $Revision$
* $Log$
* Revision 1.1.2.1 2005/04/08 08:03:40 luisantonioa
* *** empty log message ***
*
* Revision 1.1 4/04/2005 17:15:07 luisantonioa
* Created New Class
*
*
* 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.l2jserver.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;
}
static 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 (DesireType desire : desireList)
{
_desireTable.put(desire, new DesireValue());
}
}
public DesireValue getDesireValue(DesireType type)
{
return _desireTable.get(type);
}
public void addValue(DesireType type, float value)
{
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)
{
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)
{
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)
{
Desires desireList = _objectDesireTable.get(object);
if (desireList != null)
{
desireList.createDesire(type);
}
}
public void deleteDesire(L2Object object, DesireType type)
{
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));
}
}
}
@@ -0,0 +1,105 @@
/*
* 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.l2jserver.gameserver.model;
import java.util.concurrent.ScheduledFuture;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
/**
* @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;
}
/*
* if (_owner.getClan() != null && _owner.getClan() == actor.getClan()) return true;
*/
return false;
}
public boolean tryPickUp(L2PetInstance pet)
{
return tryPickUp(pet.getOwner());
}
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);
}
}
@@ -0,0 +1,358 @@
/*
* 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.l2jserver.gameserver.model;
import gnu.trove.TIntObjectHashMap;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.skills.Stats;
import com.l2jserver.gameserver.skills.funcs.FuncAdd;
import com.l2jserver.gameserver.skills.funcs.LambdaConst;
public final class Elementals
{
private static final TIntObjectHashMap<ElementalItems> TABLE = new TIntObjectHashMap<>();
static
{
for (ElementalItems item : ElementalItems.values())
{
TABLE.put(item._itemId, item);
}
}
public final static byte NONE = -1;
public final static byte FIRE = 0;
public final static byte WATER = 1;
public final static byte WIND = 2;
public final static byte EARTH = 3;
public final static byte HOLY = 4;
public final static byte DARK = 5;
public final static int FIRST_WEAPON_BONUS = 20;
public final static int NEXT_WEAPON_BONUS = 5;
public final static int ARMOR_BONUS = 6;
public final static int[] WEAPON_VALUES =
{
0, // Level 1
25, // Level 2
75, // Level 3
150, // Level 4
175, // Level 5
225, // Level 6
300, // Level 7
325, // Level 8
375, // Level 9
450, // Level 10
475, // Level 11
525, // Level 12
600, // Level 13
Integer.MAX_VALUE
// TODO: Higher stones
};
public final static int[] ARMOR_VALUES =
{
0, // Level 1
12, // Level 2
30, // Level 3
60, // Level 4
72, // Level 5
90, // Level 6
120, // Level 7
132, // Level 8
150, // Level 9
180, // Level 10
192, // Level 11
210, // Level 12
240, // Level 13
Integer.MAX_VALUE
// TODO: Higher stones
};
public static enum ElementalItemType
{
Stone(3),
Roughore(3),
Crystal(6),
Jewel(9),
Energy(12);
public int _maxLevel;
private ElementalItemType(int maxLvl)
{
_maxLevel = maxLvl;
}
}
public static enum ElementalItems
{
fireStone(FIRE, 9546, ElementalItemType.Stone),
waterStone(WATER, 9547, ElementalItemType.Stone),
windStone(WIND, 9549, ElementalItemType.Stone),
earthStone(EARTH, 9548, ElementalItemType.Stone),
divineStone(HOLY, 9551, ElementalItemType.Stone),
darkStone(DARK, 9550, ElementalItemType.Stone),
fireRoughtore(FIRE, 10521, ElementalItemType.Roughore),
waterRoughtore(WATER, 10522, ElementalItemType.Roughore),
windRoughtore(WIND, 10524, ElementalItemType.Roughore),
earthRoughtore(EARTH, 10523, ElementalItemType.Roughore),
divineRoughtore(HOLY, 10526, ElementalItemType.Roughore),
darkRoughtore(DARK, 10525, ElementalItemType.Roughore),
fireCrystal(FIRE, 9552, ElementalItemType.Crystal),
waterCrystal(WATER, 9553, ElementalItemType.Crystal),
windCrystal(WIND, 9555, ElementalItemType.Crystal),
earthCrystal(EARTH, 9554, ElementalItemType.Crystal),
divineCrystal(HOLY, 9557, ElementalItemType.Crystal),
darkCrystal(DARK, 9556, ElementalItemType.Crystal),
fireJewel(FIRE, 9558, ElementalItemType.Jewel),
waterJewel(WATER, 9559, ElementalItemType.Jewel),
windJewel(WIND, 9561, ElementalItemType.Jewel),
earthJewel(EARTH, 9560, ElementalItemType.Jewel),
divineJewel(HOLY, 9563, ElementalItemType.Jewel),
darkJewel(DARK, 9562, ElementalItemType.Jewel),
// not yet supported by client (Freya pts)
fireEnergy(FIRE, 9564, ElementalItemType.Energy),
waterEnergy(WATER, 9565, ElementalItemType.Energy),
windEnergy(WIND, 9567, ElementalItemType.Energy),
earthEnergy(EARTH, 9566, ElementalItemType.Energy),
divineEnergy(HOLY, 9569, ElementalItemType.Energy),
darkEnergy(DARK, 9568, ElementalItemType.Energy);
public byte _element;
public int _itemId;
public ElementalItemType _type;
private ElementalItems(byte element, int itemId, ElementalItemType type)
{
_element = element;
_itemId = itemId;
_type = type;
}
}
public static byte getItemElement(int itemId)
{
ElementalItems item = TABLE.get(itemId);
if (item != null)
{
return item._element;
}
return NONE;
}
public static ElementalItems getItemElemental(int itemId)
{
return TABLE.get(itemId);
}
public static int getMaxElementLevel(int itemId)
{
ElementalItems item = TABLE.get(itemId);
if (item != null)
{
return item._type._maxLevel;
}
return -1;
}
public static String getElementName(byte element)
{
switch (element)
{
case FIRE:
return "Fire";
case WATER:
return "Water";
case WIND:
return "Wind";
case EARTH:
return "Earth";
case DARK:
return "Dark";
case HOLY:
return "Holy";
}
return "None";
}
public static byte getElementId(String name)
{
String tmp = name.toLowerCase();
if (tmp.equals("fire"))
{
return FIRE;
}
if (tmp.equals("water"))
{
return WATER;
}
if (tmp.equals("wind"))
{
return WIND;
}
if (tmp.equals("earth"))
{
return EARTH;
}
if (tmp.equals("dark"))
{
return DARK;
}
if (tmp.equals("holy"))
{
return HOLY;
}
return NONE;
}
public static byte getOppositeElement(byte element)
{
return (byte) (((element % 2) == 0) ? (element + 1) : (element - 1));
}
public static class ElementalStatBoni
{
private byte _elementalType;
private int _elementalValue;
private boolean _active;
public ElementalStatBoni(byte type, int value)
{
_elementalType = type;
_elementalValue = value;
_active = false;
}
public void applyBonus(L2PcInstance player, boolean isArmor)
{
// make sure the bonuses are not applied twice..
if (_active)
{
return;
}
switch (_elementalType)
{
case FIRE:
player.addStatFunc(new FuncAdd(isArmor ? Stats.FIRE_RES : Stats.FIRE_POWER, 0x40, this, new LambdaConst(_elementalValue)));
break;
case WATER:
player.addStatFunc(new FuncAdd(isArmor ? Stats.WATER_RES : Stats.WATER_POWER, 0x40, this, new LambdaConst(_elementalValue)));
break;
case WIND:
player.addStatFunc(new FuncAdd(isArmor ? Stats.WIND_RES : Stats.WIND_POWER, 0x40, this, new LambdaConst(_elementalValue)));
break;
case EARTH:
player.addStatFunc(new FuncAdd(isArmor ? Stats.EARTH_RES : Stats.EARTH_POWER, 0x40, this, new LambdaConst(_elementalValue)));
break;
case DARK:
player.addStatFunc(new FuncAdd(isArmor ? Stats.DARK_RES : Stats.DARK_POWER, 0x40, this, new LambdaConst(_elementalValue)));
break;
case HOLY:
player.addStatFunc(new FuncAdd(isArmor ? Stats.HOLY_RES : Stats.HOLY_POWER, 0x40, this, new LambdaConst(_elementalValue)));
break;
}
_active = true;
}
public void removeBonus(L2PcInstance player)
{
// make sure the bonuses are not removed twice
if (!_active)
{
return;
}
((L2Character) player).removeStatsOwner(this);
_active = false;
}
public void setValue(int val)
{
_elementalValue = val;
}
public void setElement(byte type)
{
_elementalType = type;
}
}
// non static:
private ElementalStatBoni _boni = null;
private byte _element = NONE;
private int _value = 0;
public byte getElement()
{
return _element;
}
public void setElement(byte type)
{
_element = type;
_boni.setElement(type);
}
public int getValue()
{
return _value;
}
public void setValue(int val)
{
_value = val;
_boni.setValue(val);
}
@Override
public String toString()
{
return getElementName(_element) + " +" + _value;
}
public Elementals(byte type, int value)
{
_element = type;
_value = value;
_boni = new ElementalStatBoni(_element, _value);
}
public void applyBonus(L2PcInstance player, boolean isArmor)
{
_boni.applyBonus(player, isArmor);
}
public void removeBonus(L2PcInstance player)
{
_boni.removeBonus(player);
}
public void updateBonus(L2PcInstance player, boolean isArmor)
{
_boni.removeBonus(player);
_boni.applyBonus(player, isArmor);
}
}
@@ -0,0 +1,129 @@
/*
* 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.l2jserver.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 int _type;
private final int _group;
private final int _fishGuts;
private final int _gutsCheckTime;
private final int _waitTime;
private final int _combatTime;
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;
_fishGuts = fish_guts;
_gutsCheckTime = guts_check_time;
_waitTime = wait_time;
_combatTime = combat_time;
}
public FishData(FishData copyOf)
{
_id = copyOf.getId();
_level = copyOf.getLevel();
_name = copyOf.getName();
_hp = copyOf.getHP();
_hpRegen = copyOf.getHpRegen();
_type = copyOf.getType();
_group = copyOf.getGroup();
_fishGuts = copyOf.getFishGuts();
_gutsCheckTime = copyOf.getGutsCheckTime();
_waitTime = copyOf.getWaitTime();
_combatTime = copyOf.getCombatTime();
}
/**
* @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 _fishGuts;
}
public int getGutsCheckTime()
{
return _gutsCheckTime;
}
public int getWaitTime()
{
return _waitTime;
}
public int getCombatTime()
{
return _combatTime;
}
public void setType(int type)
{
_type = type;
}
}
@@ -0,0 +1,115 @@
/*
* 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.l2jserver.gameserver.model;
import java.util.concurrent.Future;
import java.util.logging.Logger;
import com.l2jserver.gameserver.GeoData;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.datatables.SkillTable;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.skills.effects.EffectFusion;
import com.l2jserver.gameserver.util.Util;
/**
* @author kombat, Forsaiken
*/
public final class FusionSkill
{
protected static final Logger _log = Logger.getLogger(FusionSkill.class.getName());
protected int _skillCastRange;
protected int _fusionId;
protected int _fusionLevel;
protected L2Character _caster;
protected L2Character _target;
protected Future<?> _geoCheckTask;
public L2Character getCaster()
{
return _caster;
}
public L2Character getTarget()
{
return _target;
}
public FusionSkill(L2Character caster, L2Character target, L2Skill skill)
{
_skillCastRange = skill.getCastRange();
_caster = caster;
_target = target;
_fusionId = skill.getTriggeredId();
_fusionLevel = skill.getTriggeredLevel();
L2Effect effect = _target.getFirstEffect(_fusionId);
if (effect != null)
{
((EffectFusion) effect).increaseEffect();
}
else
{
L2Skill force = SkillTable.getInstance().getInfo(_fusionId, _fusionLevel);
if (force != null)
{
force.getEffects(_caster, _target, null);
}
else
{
_log.warning("Triggered skill [" + _fusionId + ";" + _fusionLevel + "] not found!");
}
}
_geoCheckTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new GeoCheckTask(), 1000, 1000);
}
public void onCastAbort()
{
_caster.setFusionSkill(null);
L2Effect effect = _target.getFirstEffect(_fusionId);
if (effect != null)
{
((EffectFusion) effect).decreaseForce();
}
_geoCheckTask.cancel(true);
}
public class GeoCheckTask implements Runnable
{
@Override
public void run()
{
try
{
if (!Util.checkIfInRange(_skillCastRange, _caster, _target, true))
{
_caster.abortCast();
}
if (!GeoData.getInstance().canSeeTarget(_caster, _target))
{
_caster.abortCast();
}
}
catch (Exception e)
{
// ignore
}
}
}
}
@@ -0,0 +1,43 @@
/*
* 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.l2jserver.gameserver.model;
/**
* This interface provides method to handle triggered skills from other objects.<br>
* For example, other skill, an effect, etc...
* @author DrHouse
*/
public interface IChanceSkillTrigger
{
/**
* Just a flag
*/
public boolean triggersChanceSkill();
/**
* Triggered Id
*/
public int getTriggeredChanceId();
/**
* Triggered level
*/
public int getTriggeredChanceLevel();
/**
* Chance condition object
*/
public ChanceCondition getTriggeredChanceCondition();
}
@@ -0,0 +1,276 @@
/*
* 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.l2jserver.gameserver.model;
import com.l2jserver.gameserver.templates.item.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 augmentation of the item */
private int _augmentation;
/** The quantity of L2ItemInstance */
private long _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 clientside (1=ADD, 2=MODIFY, 3=REMOVE) */
private int _change;
/** The mana of this item */
private int _mana;
private int _time;
private int _location;
private int _elemAtkType = -2;
private int _elemAtkPower = 0;
private final int[] _elemDefAttr =
{
0,
0,
0,
0,
0,
0
};
/**
* Get all information from L2ItemInstance to generate ItemInfo.<BR>
* <BR>
*/
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 augmentation boni
if (item.isAugmented())
{
_augmentation = item.getAugmentation().getAugmentationId();
}
else
{
_augmentation = 0;
}
// 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 clientside
switch (item.getLastChange())
{
case (L2ItemInstance.ADDED):
{
_change = 1;
break;
}
case (L2ItemInstance.MODIFIED):
{
_change = 2;
break;
}
case (L2ItemInstance.REMOVED):
{
_change = 3;
break;
}
}
// Get shadow item mana
_mana = item.getMana();
_time = item.isTimeLimitedItem() ? (int) (item.getRemainingTime() / 1000) : -9999;
_location = item.getLocationSlot();
_elemAtkType = item.getAttackElementType();
_elemAtkPower = item.getAttackElementPower();
for (byte i = 0; i < 6; i++)
{
_elemDefAttr[i] = item.getElementDefAttr(i);
}
}
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 augmentation boni
if (item.isAugmented())
{
_augmentation = item.getAugmentation().getAugmentationId();
}
else
{
_augmentation = 0;
}
// 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 clientside
_change = change;
// Get shadow item mana
_mana = item.getMana();
_time = item.isTimeLimitedItem() ? (int) (item.getRemainingTime() / 1000) : -9999;
_location = item.getLocationSlot();
_elemAtkType = item.getAttackElementType();
_elemAtkPower = item.getAttackElementPower();
for (byte i = 0; i < 6; i++)
{
_elemDefAttr[i] = item.getElementDefAttr(i);
}
}
public int getObjectId()
{
return _objectId;
}
public L2Item getItem()
{
return _item;
}
public int getEnchant()
{
return _enchant;
}
public int getAugmentationBonus()
{
return _augmentation;
}
public long 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;
}
public int getMana()
{
return _mana;
}
public int getTime()
{
return _time;
}
public int getLocation()
{
return _location;
}
public int getAttackElementType()
{
return _elemAtkType;
}
public int getAttackElementPower()
{
return _elemAtkPower;
}
public int getElementDefAttr(byte i)
{
return _elemDefAttr[i];
}
}
@@ -0,0 +1,103 @@
/*
* 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.l2jserver.gameserver.model;
/**
*
*/
public class ItemRequest
{
int _objectId;
int _itemId;
long _count;
long _price;
public ItemRequest(int objectId, long count, long price)
{
_objectId = objectId;
_count = count;
_price = price;
}
public ItemRequest(int objectId, int itemId, long count, long price)
{
_objectId = objectId;
_itemId = itemId;
_count = count;
_price = price;
}
public int getObjectId()
{
return _objectId;
}
public int getItemId()
{
return _itemId;
}
public void setCount(long count)
{
_count = count;
}
public long getCount()
{
return _count;
}
public long 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;
}
ItemRequest other = (ItemRequest) obj;
if (_objectId != other._objectId)
{
return false;
}
return true;
}
}
@@ -0,0 +1,274 @@
/*
* 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.l2jserver.gameserver.model;
import java.util.logging.Logger;
import com.l2jserver.gameserver.datatables.AccessLevels;
/**
* @author FBIagent<br>
*/
public class L2AccessLevel
{
/** The logger<br> */
private static Logger _log = Logger.getLogger(L2AccessLevel.class.getName());
/** The access level<br> */
private int _accessLevel = 0;
/** The access level name<br> */
private String _name = null;
/** Child access levels */
L2AccessLevel[] _childsAccessLevel = null;
/** Child access levels */
private String _childs = null;
/** The name color for the access level<br> */
private int _nameColor = 0;
/** The title color for the access level<br> */
private int _titleColor = 0;
/** Flag to determine if the access level has gm access<br> */
private boolean _isGm = false;
/** Flag for peace zone attack */
private boolean _allowPeaceAttack = false;
/** Flag for fixed res */
private boolean _allowFixedRes = false;
/** Flag for transactions */
private boolean _allowTransaction = false;
/** Flag for AltG commands */
private boolean _allowAltG = false;
/** Flag to give damage */
private boolean _giveDamage = false;
/** Flag to take aggro */
private boolean _takeAggro = false;
/** Flag to gain exp in party */
private boolean _gainExp = false;
/**
* Initializes members<br>
* <br>
* @param accessLevel as int<br>
* @param name as String<br>
* @param nameColor as int<br>
* @param titleColor as int<br>
* @param childs as String<br>
* @param isGm as boolean<br>
* @param allowPeaceAttack as boolean<br>
* @param allowFixedRes as boolean<br>
* @param allowTransaction as boolean<br>
* @param allowAltG as boolean<br>
* @param giveDamage as boolean<br>
* @param takeAggro as boolean<br>
* @param gainExp as boolean<br>
*/
public L2AccessLevel(int accessLevel, String name, int nameColor, int titleColor, String childs, boolean isGm, boolean allowPeaceAttack, boolean allowFixedRes, boolean allowTransaction, boolean allowAltG, boolean giveDamage, boolean takeAggro, boolean gainExp)
{
_accessLevel = accessLevel;
_name = name;
_nameColor = nameColor;
_titleColor = titleColor;
_childs = childs;
_isGm = isGm;
_allowPeaceAttack = allowPeaceAttack;
_allowFixedRes = allowFixedRes;
_allowTransaction = allowTransaction;
_allowAltG = allowAltG;
_giveDamage = giveDamage;
_takeAggro = takeAggro;
_gainExp = gainExp;
}
/**
* Returns the access level<br>
* <br>
* @return int: access level<br>
*/
public int getLevel()
{
return _accessLevel;
}
/**
* Returns the access level name<br>
* <br>
* @return String: access level name<br>
*/
public String getName()
{
return _name;
}
/**
* Returns the name color of the access level<br>
* <br>
* @return int: the name color for the access level<br>
*/
public int getNameColor()
{
return _nameColor;
}
/**
* Returns the title color color of the access level<br>
* <br>
* @return int: the title color for the access level<br>
*/
public int getTitleColor()
{
return _titleColor;
}
/**
* Retuns if the access level has gm access or not<br>
* <br>
* @return boolean: true if access level have gm access, otherwise false<br>
*/
public boolean isGm()
{
return _isGm;
}
/**
* Returns if the access level is allowed to attack in peace zone or not<br>
* <br>
* @return boolean: true if the access level is allowed to attack in peace zone, otherwise false<br>
*/
public boolean allowPeaceAttack()
{
return _allowPeaceAttack;
}
/**
* Retruns if the access level is allowed to use fixed res or not<br>
* <br>
* @return: true if the access level is allowed to use fixed res, otherwise false<br>
*/
public boolean allowFixedRes()
{
return _allowFixedRes;
}
/**
* Returns if the access level is allowed to perform transactions or not<br>
* <br>
* @return boolean: true if access level is allowed to perform transactions, otherwise false<br>
*/
public boolean allowTransaction()
{
return _allowTransaction;
}
/**
* Returns if the access level is allowed to use AltG commands or not<br>
* <br>
* @return boolean: true if access level is allowed to use AltG commands, otherwise false<br>
*/
public boolean allowAltG()
{
return _allowAltG;
}
/**
* Returns if the access level can give damage or not<br>
* <br>
* @return boolean: true if the access level can give damage, otherwise false<br>
*/
public boolean canGiveDamage()
{
return _giveDamage;
}
/**
* Returns if the access level can take aggro or not<br>
* <br>
* @return boolean: true if the access level can take aggro, otherwise false<br>
*/
public boolean canTakeAggro()
{
return _takeAggro;
}
/**
* Returns if the access level can gain exp or not<br>
* <br>
* @return boolean: true if the access level can gain exp, otherwise false<br>
*/
public boolean canGainExp()
{
return _gainExp;
}
/**
* Returns if the access level contains allowedAccess as child<br>
* <br>
* @param accessLevel as AccessLevel<br>
* <br>
* @return boolean: true if a child access level is equals to allowedAccess, otherwise false<br>
*/
public boolean hasChildAccess(L2AccessLevel accessLevel)
{
if (_childsAccessLevel == null)
{
if (_childs == null)
{
return false;
}
setChildAccess(_childs);
for (L2AccessLevel childAccess : _childsAccessLevel)
{
if ((childAccess != null) && ((childAccess.getLevel() == accessLevel.getLevel()) || childAccess.hasChildAccess(accessLevel)))
{
return true;
}
}
}
else
{
for (L2AccessLevel childAccess : _childsAccessLevel)
{
if ((childAccess != null) && ((childAccess.getLevel() == accessLevel.getLevel()) || childAccess.hasChildAccess(accessLevel)))
{
return true;
}
}
}
return false;
}
private void setChildAccess(String childs)
{
String[] childsSplit = childs.split(";");
_childsAccessLevel = new L2AccessLevel[childsSplit.length];
for (int i = 0; i < childsSplit.length; ++i)
{
L2AccessLevel accessLevelInst = AccessLevels.getInstance().getAccessLevel(Integer.parseInt(childsSplit[i]));
if (accessLevelInst == null)
{
_log.warning("AccessLevel: Undefined child access level " + childsSplit[i]);
continue;
}
if (accessLevelInst.hasChildAccess(this))
{
_log.warning("AccessLevel: Child access tree overlapping for " + _name + " and " + accessLevelInst.getName());
continue;
}
_childsAccessLevel[i] = accessLevelInst;
}
}
}
@@ -0,0 +1,92 @@
/*
* 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.l2jserver.gameserver.model;
import com.l2jserver.gameserver.datatables.AccessLevels;
/**
* @author FBIagent<br>
*/
public class L2AdminCommandAccessRight
{
/** The admin command<br> */
private String _adminCommand = null;
/** The access levels which can use the admin command<br> */
private L2AccessLevel[] _accessLevels = null;
private final boolean _requireConfirm;
/**
* Initialized members
* @param adminCommand as String
* @param accessLevels as String
*/
public L2AdminCommandAccessRight(String adminCommand, String accessLevels, boolean confirm)
{
_adminCommand = adminCommand;
_requireConfirm = confirm;
String[] accessLevelsSplit = accessLevels.split(",");
int numLevels = accessLevelsSplit.length;
_accessLevels = new L2AccessLevel[numLevels];
for (int i = 0; i < numLevels; ++i)
{
try
{
_accessLevels[i] = AccessLevels.getInstance().getAccessLevel(Integer.parseInt(accessLevelsSplit[i]));
}
catch (NumberFormatException nfe)
{
_accessLevels[i] = null;
}
}
}
/**
* Returns the admin command the access right belongs to<br>
* <br>
* @return String: the admin command the access right belongs to<br>
*/
public String getAdminCommand()
{
return _adminCommand;
}
/**
* Checks if the given characterAccessLevel is allowed to use the admin command which belongs to this access right<br>
* <br>
* @param characterAccessLevel<br>
* <br>
* @return boolean: true if characterAccessLevel is allowed to use the admin command which belongs to this access right, otherwise false<br>
*/
public boolean hasAccess(L2AccessLevel characterAccessLevel)
{
for (L2AccessLevel accessLevel : _accessLevels)
{
if ((accessLevel != null) && ((accessLevel.getLevel() == characterAccessLevel.getLevel()) || characterAccessLevel.hasChildAccess(accessLevel)))
{
return true;
}
}
return false;
}
public boolean getRequireConfirm()
{
return _requireConfirm;
}
}
@@ -0,0 +1,228 @@
/*
* 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.l2jserver.gameserver.model;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.itemcontainer.Inventory;
/**
* @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 _mw_legs;
private final int _mw_head;
private final int _mw_gloves;
private final int _mw_feet;
private final String[] _skills;
private final int _shield;
private final int _mw_shield;
private final int _shieldSkillId;
private final int _enchant6Skill;
public L2ArmorSet(int chest, int legs, int head, int gloves, int feet, String[] skills, int shield, int shield_skill_id, int enchant6skill, int mw_legs, int mw_head, int mw_gloves, int mw_feet, int mw_shield)
{
_chest = chest;
_legs = legs;
_head = head;
_gloves = gloves;
_feet = feet;
_mw_legs = mw_legs;
_mw_head = mw_head;
_mw_gloves = mw_gloves;
_mw_feet = mw_feet;
_mw_shield = mw_shield;
_skills = skills;
_shield = shield;
_shieldSkillId = shield_skill_id;
_enchant6Skill = enchant6skill;
}
/**
* 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)
{
Inventory inv = player.getInventory();
L2ItemInstance legsItem = inv.getPaperdollItem(Inventory.PAPERDOLL_LEGS);
L2ItemInstance headItem = inv.getPaperdollItem(Inventory.PAPERDOLL_HEAD);
L2ItemInstance glovesItem = inv.getPaperdollItem(Inventory.PAPERDOLL_GLOVES);
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) && ((_mw_legs == 0) || (_mw_legs != legs)))
{
return false;
}
if ((_head != 0) && (_head != head) && ((_mw_head == 0) || (_mw_head != head)))
{
return false;
}
if ((_gloves != 0) && (_gloves != gloves) && ((_mw_gloves == 0) || (_mw_gloves != gloves)))
{
return false;
}
if ((_feet != 0) && (_feet != feet) && ((_mw_feet == 0) || (_mw_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) || (_mw_legs == itemId));
case Inventory.PAPERDOLL_HEAD:
return ((_head == itemId) || (_mw_head == itemId));
case Inventory.PAPERDOLL_GLOVES:
return ((_gloves == itemId) || (_mw_gloves == itemId));
case Inventory.PAPERDOLL_FEET:
return ((_feet == itemId) || (_mw_feet == itemId));
default:
return false;
}
}
public String[] getSkills()
{
return _skills;
}
public boolean containShield(L2PcInstance player)
{
Inventory inv = player.getInventory();
L2ItemInstance shieldItem = inv.getPaperdollItem(Inventory.PAPERDOLL_LHAND);
if ((shieldItem != null) && ((shieldItem.getItemId() == _shield) || (shieldItem.getItemId() == _mw_shield)))
{
return true;
}
return false;
}
public boolean containShield(int shield_id)
{
if (_shield == 0)
{
return false;
}
return ((_shield == shield_id) || (_mw_shield == shield_id));
}
public int getShieldSkillId()
{
return _shieldSkillId;
}
public int getEnchant6skillId()
{
return _enchant6Skill;
}
/**
* Checks if all parts of set are enchanted to +6 or more
* @param player
* @return
*/
public boolean isEnchanted6(L2PcInstance player)
{
// Player don't have full set
if (!containAll(player))
{
return false;
}
Inventory inv = player.getInventory();
L2ItemInstance chestItem = inv.getPaperdollItem(Inventory.PAPERDOLL_CHEST);
L2ItemInstance legsItem = inv.getPaperdollItem(Inventory.PAPERDOLL_LEGS);
L2ItemInstance headItem = inv.getPaperdollItem(Inventory.PAPERDOLL_HEAD);
L2ItemInstance glovesItem = inv.getPaperdollItem(Inventory.PAPERDOLL_GLOVES);
L2ItemInstance feetItem = inv.getPaperdollItem(Inventory.PAPERDOLL_FEET);
if ((chestItem == null) || (chestItem.getEnchantLevel() < 6))
{
return false;
}
if ((_legs != 0) && ((legsItem == null) || (legsItem.getEnchantLevel() < 6)))
{
return false;
}
if ((_gloves != 0) && ((glovesItem == null) || (glovesItem.getEnchantLevel() < 6)))
{
return false;
}
if ((_head != 0) && ((headItem == null) || (headItem.getEnchantLevel() < 6)))
{
return false;
}
if ((_feet != 0) && ((feetItem == null) || (feetItem.getEnchantLevel() < 6)))
{
return false;
}
return true;
}
}
@@ -0,0 +1,182 @@
/*
* 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.l2jserver.gameserver.model;
import javolution.util.FastList;
import com.l2jserver.gameserver.datatables.AugmentationData;
import com.l2jserver.gameserver.datatables.SkillTable;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.network.serverpackets.SkillCoolTime;
import com.l2jserver.gameserver.skills.Stats;
import com.l2jserver.gameserver.skills.funcs.FuncAdd;
import com.l2jserver.gameserver.skills.funcs.LambdaConst;
/**
* Used to store an augmentation and its boni
* @author durgus
*/
public final class L2Augmentation
{
private int _effectsId = 0;
private AugmentationStatBoni _boni = null;
private L2Skill _skill = null;
public L2Augmentation(int effects, L2Skill skill)
{
_effectsId = effects;
_boni = new AugmentationStatBoni(_effectsId);
_skill = skill;
}
public L2Augmentation(int effects, int skill, int skillLevel)
{
this(effects, skill != 0 ? SkillTable.getInstance().getInfo(skill, skillLevel) : null);
}
// =========================================================
// Nested Class
public static class AugmentationStatBoni
{
private final Stats _stats[];
private final float _values[];
private boolean _active;
public AugmentationStatBoni(int augmentationId)
{
_active = false;
FastList<AugmentationData.AugStat> as = AugmentationData.getInstance().getAugStatsById(augmentationId);
_stats = new Stats[as.size()];
_values = new float[as.size()];
int i = 0;
for (AugmentationData.AugStat aStat : as)
{
_stats[i] = aStat.getStat();
_values[i] = aStat.getValue();
i++;
}
}
public void applyBonus(L2PcInstance player)
{
// make sure the bonuses are not applied twice..
if (_active)
{
return;
}
for (int i = 0; i < _stats.length; i++)
{
((L2Character) player).addStatFunc(new FuncAdd(_stats[i], 0x40, this, new LambdaConst(_values[i])));
}
_active = true;
}
public void removeBonus(L2PcInstance player)
{
// make sure the bonuses are not removed twice
if (!_active)
{
return;
}
((L2Character) player).removeStatsOwner(this);
_active = false;
}
}
public int getAttributes()
{
return _effectsId;
}
/**
* Get the augmentation "id" used in serverpackets.
* @return augmentationId
*/
public int getAugmentationId()
{
return _effectsId;
}
public L2Skill getSkill()
{
return _skill;
}
/**
* Applies the bonuses to the player.
* @param player
*/
public void applyBonus(L2PcInstance player)
{
boolean updateTimeStamp = false;
_boni.applyBonus(player);
// add the skill if any
if (_skill != null)
{
player.addSkill(_skill);
if (_skill.isActive())
{
if (!player.getReuseTimeStamp().isEmpty() && player.getReuseTimeStamp().containsKey(_skill.getReuseHashCode()))
{
final long delay = player.getReuseTimeStamp().get(_skill.getReuseHashCode()).getRemaining();
if (delay > 0)
{
player.disableSkill(_skill, delay);
updateTimeStamp = true;
}
}
}
player.sendSkillList();
if (updateTimeStamp)
{
player.sendPacket(new SkillCoolTime(player));
}
}
}
/**
* Removes the augmentation bonuses from the player.
* @param player
*/
public void removeBonus(L2PcInstance player)
{
_boni.removeBonus(player);
// remove the skill if any
if (_skill != null)
{
if (_skill.isPassive())
{
player.removeSkill(_skill, false, true);
}
else
{
player.removeSkill(_skill, false, false);
}
player.sendSkillList();
}
}
}
@@ -0,0 +1,38 @@
/*
* 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.l2jserver.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>
*/
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
@@ -0,0 +1,708 @@
/*
* 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.l2jserver.gameserver.model;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jserver.L2DatabaseFactory;
import com.l2jserver.gameserver.instancemanager.SiegeManager;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
/**
* Clan member class.
*/
public class L2ClanMember
{
private static final Logger _log = Logger.getLogger(L2ClanMember.class.getName());
private final L2Clan _clan;
private int _objectId;
private String _name;
private String _title;
private int _powerGrade;
private int _level;
private int _classId;
private boolean _sex;
private int _raceOrdinal;
private L2PcInstance _player;
private int _pledgeType;
private int _apprentice;
private int _sponsor;
public L2ClanMember(L2Clan clan, String name, int level, int classId, int objectId, int pledgeType, int powerGrade, String title, boolean sex, int raceOrdinal)
{
if (clan == null)
{
throw new IllegalArgumentException("Can not create a ClanMember with a null clan.");
}
_clan = clan;
_name = name;
_level = level;
_classId = classId;
_objectId = objectId;
_powerGrade = powerGrade;
_title = title;
_pledgeType = pledgeType;
_apprentice = 0;
_sponsor = 0;
_sex = sex;
_raceOrdinal = raceOrdinal;
}
public L2ClanMember(L2Clan clan, L2PcInstance player)
{
_clan = clan;
_name = player.getName();
_level = player.getLevel();
_classId = player.getClassId().getId();
_objectId = player.getObjectId();
_pledgeType = player.getPledgeType();
_powerGrade = player.getPowerGrade();
_title = player.getTitle();
_sponsor = 0;
_apprentice = 0;
_sex = player.getAppearance().getSex();
_raceOrdinal = player.getRace().ordinal();
}
public L2ClanMember(L2PcInstance player)
{
if (player.getClan() == null)
{
throw new IllegalArgumentException("Can not create a ClanMember if player has a null clan.");
}
_clan = player.getClan();
_player = player;
_name = _player.getName();
_level = _player.getLevel();
_classId = _player.getClassId().getId();
_objectId = _player.getObjectId();
_powerGrade = _player.getPowerGrade();
_pledgeType = _player.getPledgeType();
_title = _player.getTitle();
_apprentice = 0;
_sponsor = 0;
_sex = _player.getAppearance().getSex();
_raceOrdinal = _player.getRace().ordinal();
}
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();
_powerGrade = _player.getPowerGrade();
_pledgeType = _player.getPledgeType();
_title = _player.getTitle();
_apprentice = _player.getApprentice();
_sponsor = _player.getSponsor();
_sex = _player.getAppearance().getSex();
_raceOrdinal = _player.getRace().ordinal();
}
if (player != null)
{
_clan.addSkillEffects(player);
if ((_clan.getLevel() > 3) && player.isClanLeader())
{
SiegeManager.getInstance().addSiegeSkills(player);
}
if (player.isClanLeader())
{
_clan.setLeader(this);
}
}
_player = player;
}
public L2PcInstance getPlayerInstance()
{
return _player;
}
public boolean isOnline()
{
if ((_player == null) || !_player.isOnline())
{
return false;
}
if (_player.getClient() == null)
{
return false;
}
if (_player.getClient().isDetached())
{
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 _title;
}
public int getPledgeType()
{
if (_player != null)
{
return _player.getPledgeType();
}
return _pledgeType;
}
public void setPledgeType(int pledgeType)
{
_pledgeType = pledgeType;
if (_player != null)
{
_player.setPledgeType(pledgeType);
}
else
{
// db save if char not logged in
updatePledgeType();
}
}
public void updatePledgeType()
{
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("UPDATE characters SET subpledge=? WHERE charId=?");
statement.setLong(1, _pledgeType);
statement.setInt(2, getObjectId());
statement.execute();
statement.close();
}
catch (Exception e)
{
_log.log(Level.WARNING, "Could not update pledge type: " + e.getMessage(), e);
}
finally
{
L2DatabaseFactory.close(con);
}
}
public int getPowerGrade()
{
if (_player != null)
{
return _player.getPowerGrade();
}
return _powerGrade;
}
/**
* @param powerGrade
*/
public void setPowerGrade(int powerGrade)
{
_powerGrade = powerGrade;
if (_player != null)
{
_player.setPowerGrade(powerGrade);
}
else
{
// db save if char not logged in
updatePowerGrade();
}
}
/**
* Update the characters table of the database with power grade.<BR>
* <BR>
*/
public void updatePowerGrade()
{
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("UPDATE characters SET power_grade=? WHERE charId=?");
statement.setLong(1, _powerGrade);
statement.setInt(2, getObjectId());
statement.execute();
statement.close();
}
catch (Exception e)
{
_log.log(Level.WARNING, "Could not update power _grade: " + e.getMessage(), e);
}
finally
{
L2DatabaseFactory.close(con);
}
}
public void initApprenticeAndSponsor(int apprenticeID, int sponsorID)
{
_apprentice = apprenticeID;
_sponsor = sponsorID;
}
public int getRaceOrdinal()
{
if (_player != null)
{
return _player.getRace().ordinal();
}
return _raceOrdinal;
}
public boolean getSex()
{
if (_player != null)
{
return _player.getAppearance().getSex();
}
return _sex;
}
public int getSponsor()
{
if (_player != null)
{
return _player.getSponsor();
}
return _sponsor;
}
public int getApprentice()
{
if (_player != null)
{
return _player.getApprentice();
}
return _apprentice;
}
public String getApprenticeOrSponsorName()
{
if (_player != null)
{
_apprentice = _player.getApprentice();
_sponsor = _player.getSponsor();
}
if (_apprentice != 0)
{
L2ClanMember apprentice = _clan.getClanMember(_apprentice);
if (apprentice != null)
{
return apprentice.getName();
}
return "Error";
}
if (_sponsor != 0)
{
L2ClanMember sponsor = _clan.getClanMember(_sponsor);
if (sponsor != null)
{
return sponsor.getName();
}
return "Error";
}
return "";
}
public L2Clan getClan()
{
return _clan;
}
public int calculatePledgeClass(L2PcInstance player)
{
int pledgeClass = 0;
if (player == null)
{
return pledgeClass;
}
L2Clan clan = player.getClan();
if (clan != null)
{
switch (clan.getLevel())
{
case 4:
if (player.isClanLeader())
{
pledgeClass = 3;
}
break;
case 5:
if (player.isClanLeader())
{
pledgeClass = 4;
}
else
{
pledgeClass = 2;
}
break;
case 6:
switch (player.getPledgeType())
{
case -1:
pledgeClass = 1;
break;
case 100:
case 200:
pledgeClass = 2;
break;
case 0:
if (player.isClanLeader())
{
pledgeClass = 5;
}
else
{
switch (clan.getLeaderSubPledge(player.getObjectId()))
{
case 100:
case 200:
pledgeClass = 4;
break;
case -1:
default:
pledgeClass = 3;
break;
}
}
break;
}
break;
case 7:
switch (player.getPledgeType())
{
case -1:
pledgeClass = 1;
break;
case 100:
case 200:
pledgeClass = 3;
break;
case 1001:
case 1002:
case 2001:
case 2002:
pledgeClass = 2;
break;
case 0:
if (player.isClanLeader())
{
pledgeClass = 7;
}
else
{
switch (clan.getLeaderSubPledge(player.getObjectId()))
{
case 100:
case 200:
pledgeClass = 6;
break;
case 1001:
case 1002:
case 2001:
case 2002:
pledgeClass = 5;
break;
case -1:
default:
pledgeClass = 4;
break;
}
}
break;
}
break;
case 8:
switch (player.getPledgeType())
{
case -1:
pledgeClass = 1;
break;
case 100:
case 200:
pledgeClass = 4;
break;
case 1001:
case 1002:
case 2001:
case 2002:
pledgeClass = 3;
break;
case 0:
if (player.isClanLeader())
{
pledgeClass = 8;
}
else
{
switch (clan.getLeaderSubPledge(player.getObjectId()))
{
case 100:
case 200:
pledgeClass = 7;
break;
case 1001:
case 1002:
case 2001:
case 2002:
pledgeClass = 6;
break;
case -1:
default:
pledgeClass = 5;
break;
}
}
break;
}
break;
case 9:
switch (player.getPledgeType())
{
case -1:
pledgeClass = 1;
break;
case 100:
case 200:
pledgeClass = 5;
break;
case 1001:
case 1002:
case 2001:
case 2002:
pledgeClass = 4;
break;
case 0:
if (player.isClanLeader())
{
pledgeClass = 9;
}
else
{
switch (clan.getLeaderSubPledge(player.getObjectId()))
{
case 100:
case 200:
pledgeClass = 8;
break;
case 1001:
case 1002:
case 2001:
case 2002:
pledgeClass = 7;
break;
case -1:
default:
pledgeClass = 6;
break;
}
}
break;
}
break;
case 10:
switch (player.getPledgeType())
{
case -1:
pledgeClass = 1;
break;
case 100:
case 200:
pledgeClass = 6;
break;
case 1001:
case 1002:
case 2001:
case 2002:
pledgeClass = 5;
break;
case 0:
if (player.isClanLeader())
{
pledgeClass = 10;
}
else
{
switch (clan.getLeaderSubPledge(player.getObjectId()))
{
case 100:
case 200:
pledgeClass = 9;
break;
case 1001:
case 1002:
case 2001:
case 2002:
pledgeClass = 8;
break;
case -1:
default:
pledgeClass = 7;
break;
}
}
break;
}
break;
case 11:
switch (player.getPledgeType())
{
case -1:
pledgeClass = 1;
break;
case 100:
case 200:
pledgeClass = 7;
break;
case 1001:
case 1002:
case 2001:
case 2002:
pledgeClass = 6;
break;
case 0:
if (player.isClanLeader())
{
pledgeClass = 11;
}
else
{
switch (clan.getLeaderSubPledge(player.getObjectId()))
{
case 100:
case 200:
pledgeClass = 10;
break;
case 1001:
case 1002:
case 2001:
case 2002:
pledgeClass = 9;
break;
case -1:
default:
pledgeClass = 8;
break;
}
}
break;
}
break;
default:
pledgeClass = 1;
break;
}
}
return pledgeClass;
}
public void saveApprenticeAndSponsor(int apprentice, int sponsor)
{
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("UPDATE characters SET apprentice=?,sponsor=? WHERE charId=?");
statement.setInt(1, apprentice);
statement.setInt(2, sponsor);
statement.setInt(3, getObjectId());
statement.execute();
statement.close();
}
catch (SQLException e)
{
_log.log(Level.WARNING, "Could not save apprentice/sponsor: " + e.getMessage(), e);
}
finally
{
L2DatabaseFactory.close(con);
}
}
}
@@ -0,0 +1,236 @@
/*
* 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.l2jserver.gameserver.model;
import java.util.List;
import javolution.util.FastList;
import com.l2jserver.Config;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.CreatureSay;
import com.l2jserver.gameserver.network.serverpackets.ExCloseMPCC;
import com.l2jserver.gameserver.network.serverpackets.ExMPCCPartyInfoUpdate;
import com.l2jserver.gameserver.network.serverpackets.ExOpenMPCC;
import com.l2jserver.gameserver.network.serverpackets.L2GameServerPacket;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
/**
* @author chris_00
*/
public class L2CommandChannel
{
private final List<L2Party> _partys;
private L2PcInstance _commandLeader = null;
private int _channelLvl;
/**
* Creates a New Command Channel and Add the Leaders party to the CC
* @param CommandChannelLeader
*/
public L2CommandChannel(L2PcInstance leader)
{
_commandLeader = leader;
_partys = new FastList<>();
_partys.add(leader.getParty());
_channelLvl = leader.getParty().getLevel();
leader.getParty().setCommandChannel(this);
leader.getParty().broadcastToPartyMembers(SystemMessage.getSystemMessage(SystemMessageId.COMMAND_CHANNEL_FORMED));
leader.getParty().broadcastToPartyMembers(new ExOpenMPCC());
}
/**
* Adds a Party to the Command Channel
* @param Party
*/
public void addParty(L2Party party)
{
if (party == null)
{
return;
}
// Update the CCinfo for existing players
broadcastToChannelMembers(new ExMPCCPartyInfoUpdate(party, 1));
_partys.add(party);
if (party.getLevel() > _channelLvl)
{
_channelLvl = party.getLevel();
}
party.setCommandChannel(this);
party.broadcastToPartyMembers(SystemMessage.getSystemMessage(SystemMessageId.JOINED_COMMAND_CHANNEL));
party.broadcastToPartyMembers(new ExOpenMPCC());
}
/**
* Removes a Party from the Command Channel
* @param Party
*/
public void removeParty(L2Party party)
{
if (party == null)
{
return;
}
_partys.remove(party);
_channelLvl = 0;
for (L2Party pty : _partys)
{
if (pty.getLevel() > _channelLvl)
{
_channelLvl = pty.getLevel();
}
}
party.setCommandChannel(null);
party.broadcastToPartyMembers(new ExCloseMPCC());
if (_partys.size() < 2)
{
broadcastToChannelMembers(SystemMessage.getSystemMessage(SystemMessageId.COMMAND_CHANNEL_DISBANDED));
disbandChannel();
}
else
{
// Update the CCinfo for existing players
broadcastToChannelMembers(new ExMPCCPartyInfoUpdate(party, 0));
}
}
/**
* disbands the whole Command Channel
*/
public void disbandChannel()
{
if (_partys != null)
{
for (L2Party party : _partys)
{
if (party != null)
{
removeParty(party);
}
}
}
_partys.clear();
}
/**
* @return overall membercount of the Command Channel
*/
public int getMemberCount()
{
int count = 0;
for (L2Party party : _partys)
{
if (party != null)
{
count += party.getMemberCount();
}
}
return count;
}
/**
* Broadcast packet to every channelmember
* @param L2GameServerPacket
*/
public void broadcastToChannelMembers(L2GameServerPacket gsp)
{
if ((_partys != null) && !_partys.isEmpty())
{
for (L2Party party : _partys)
{
if (party != null)
{
party.broadcastToPartyMembers(gsp);
}
}
}
}
public void broadcastCSToChannelMembers(CreatureSay gsp, L2PcInstance broadcaster)
{
if ((_partys != null) && !_partys.isEmpty())
{
for (L2Party party : _partys)
{
if (party != null)
{
party.broadcastCSToPartyMembers(gsp, broadcaster);
}
}
}
}
/**
* @return list of Parties in Command Channel
*/
public List<L2Party> getPartys()
{
return _partys;
}
/**
* @return list of all Members in Command Channel
*/
public List<L2PcInstance> getMembers()
{
List<L2PcInstance> members = new FastList<>();
for (L2Party party : getPartys())
{
members.addAll(party.getPartyMembers());
}
return members;
}
/**
* @return Level of CC
*/
public int getLevel()
{
return _channelLvl;
}
/**
* @param sets 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;
}
/**
* @param obj
* @return true if proper condition for RaidWar
*/
public boolean meetRaidWarCondition(L2Object obj)
{
if (!((obj instanceof L2Character) && ((L2Character) obj).isRaid()))
{
return false;
}
return (getMemberCount() >= Config.LOOT_RAIDS_PRIVILEGE_CC_SIZE);
}
}
@@ -0,0 +1,187 @@
/*
* 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.l2jserver.gameserver.model;
import javolution.util.FastList;
import com.l2jserver.Config;
import com.l2jserver.util.Rnd;
/**
* @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 (_questDrops == null)
// _questDrops = new FastList<L2DropData>(0);
// _questDrops.add(drop);
}
else
{
if (Config.CUSTOM_DROPLIST_TABLE)
{
// If the drop exists is replaced
for (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() * Config.RATE_DROP_ITEMS), L2DropData.MAX_CHANCE);
d.setChance(drop.getChance());
_categoryChance += d.getChance();
_categoryBalancedChance += Math.min((d.getChance() * 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_DROP_ITEMS_BY_RAID : 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. Previously, this only included adena. According to sh1ny, sealstones are also acceptable drops. if no acceptable drops are in the category, nothing will be
* dropped. otherwise, 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 (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.
int randomIndex = Rnd.get(subCatChance);
int sum = 0;
for (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. to see which one will be dropped, weight all items' chances such that their sum of chances equals MAX_CHANCE. since the individual drops have their base chance, we also ought to use the base category chance for the weight. So weight =
* MAX_CHANCE/basecategoryDropChance. 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. Edited: How _categoryBalancedChance works in high rate servers: 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. 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. 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 %. _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. 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.
* @return selected drop from category, or null if nothing is dropped.
*/
public synchronized L2DropData dropOne(boolean raid)
{
int randomIndex = Rnd.get(getCategoryBalancedChance());
int sum = 0;
for (L2DropData drop : getAllDrops())
{
sum += Math.min((drop.getChance() * (raid ? Config.RATE_DROP_ITEMS_BY_RAID : Config.RATE_DROP_ITEMS)), L2DropData.MAX_CHANCE);
if (sum >= randomIndex)
{
return drop;
}
}
return null;
}
}
@@ -0,0 +1,204 @@
/*
* 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.l2jserver.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 String 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;
}
/**
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = (prime * result) + _itemId;
return result;
}
/**
* @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 (!(obj instanceof L2DropData))
{
return false;
}
final L2DropData other = (L2DropData) obj;
if (_itemId != other._itemId)
{
return false;
}
return true;
}
}
@@ -0,0 +1,724 @@
/*
* 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.l2jserver.gameserver.model;
import java.util.ArrayList;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jserver.gameserver.GameTimeController;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.datatables.SkillTable;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.actor.instance.L2SummonInstance;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.AbnormalStatusUpdate;
import com.l2jserver.gameserver.network.serverpackets.ExOlympiadSpelledInfo;
import com.l2jserver.gameserver.network.serverpackets.MagicSkillLaunched;
import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse;
import com.l2jserver.gameserver.network.serverpackets.PartySpelled;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
import com.l2jserver.gameserver.skills.AbnormalEffect;
import com.l2jserver.gameserver.skills.Env;
import com.l2jserver.gameserver.skills.funcs.Func;
import com.l2jserver.gameserver.skills.funcs.FuncTemplate;
import com.l2jserver.gameserver.skills.funcs.Lambda;
import com.l2jserver.gameserver.templates.effects.EffectTemplate;
import com.l2jserver.gameserver.templates.skills.L2EffectType;
import com.l2jserver.gameserver.templates.skills.L2SkillType;
/**
* This class ...
* @version $Revision: 1.1.2.1.2.12 $ $Date: 2005/04/11 10:06:07 $
*/
public abstract class L2Effect
{
protected static final Logger _log = Logger.getLogger(L2Effect.class.getName());
public static enum EffectState
{
CREATED,
ACTING,
FINISHING
}
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
// casted/used this effect.
private final L2Character _effected;
// the skill that was used.
private final L2Skill _skill;
private final boolean _isHerbEffect;
// 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 final int _abnormalTime;
protected int _periodStartTicks;
protected int _periodFirstTime;
private final EffectTemplate _template;
// function templates
private final FuncTemplate[] _funcTemplates;
// initial count
private final int _totalCount;
// counter
private int _count;
// abnormal effect mask
private final AbnormalEffect _abnormalEffect;
// special effect mask
private final AbnormalEffect _specialEffect;
// event effect mask
private final AbnormalEffect _eventEffect;
// show icon
private final boolean _icon;
// is selfeffect ?
private boolean _isSelfEffect = false;
public boolean preventExitUpdate;
protected final class EffectTask implements Runnable
{
@Override
public void run()
{
try
{
_periodFirstTime = 0;
_periodStartTicks = GameTimeController.getGameTicks();
scheduleEffect();
}
catch (Exception e)
{
_log.log(Level.SEVERE, "", e);
}
}
}
private ScheduledFuture<?> _currentFuture;
/** The Identifier of the stack group */
private final String _abnormalType;
/** The position of the effect in the stack group */
private final byte _abnormalLvl;
private boolean _inUse = false;
private boolean _startConditionsCorrect = true;
/**
* For special behavior. See Formulas.calcEffectSuccess
*/
private double _effectPower;
private L2SkillType _effectSkillType;
/**
* <font color="FF0000"><b>WARNING: scheduleEffect nolonger inside constructor</b></font><br>
* So you must call it explicitly
*/
protected L2Effect(Env env, EffectTemplate template)
{
_state = EffectState.CREATED;
_skill = env.skill;
// _item = env._item == null ? null : env._item.getItem();
_template = template;
_effected = env.target;
_effector = env.player;
_lambda = template.lambda;
_funcTemplates = template.funcTemplates;
_count = template.counter;
_totalCount = _count;
// Support for retail herbs duration when _effected has a Summon
int temp = template.abnormalTime;
if (((_skill.getId() > 2277) && (_skill.getId() < 2286)) || ((_skill.getId() >= 2512) && (_skill.getId() <= 2514)))
{
if ((_effected instanceof L2SummonInstance) || ((_effected instanceof L2PcInstance) && (((L2PcInstance) _effected).getPet() instanceof L2SummonInstance)))
{
temp /= 2;
}
}
if (env.skillMastery)
{
temp *= 2;
}
_abnormalTime = temp;
_abnormalEffect = template.abnormalEffect;
_specialEffect = template.specialEffect;
_eventEffect = template.eventEffect;
_abnormalType = template.abnormalType;
_abnormalLvl = template.abnormalLvl;
_periodStartTicks = GameTimeController.getGameTicks();
_periodFirstTime = 0;
_icon = template.icon;
_effectPower = template.effectPower;
_effectSkillType = template.effectType;
_isHerbEffect = _skill.getName().contains("Herb");
/*
* Commented out by DrHouse: scheduleEffect can call onStart before effect is completly initialized on constructor (child classes constructor)
*/
// scheduleEffect();
}
/**
* Special constructor to "steal" buffs. Must be implemented on every child class that can be stolen.<br>
* <br>
* <font color="FF0000"><b>WARNING: scheduleEffect nolonger inside constructor</b></font> <br>
* So you must call it explicitly
* @param env
* @param effect
*/
protected L2Effect(Env env, L2Effect effect)
{
_template = effect._template;
_state = EffectState.CREATED;
_skill = env.skill;
_effected = env.target;
_effector = env.player;
_lambda = _template.lambda;
_funcTemplates = _template.funcTemplates;
_count = effect.getCount();
_totalCount = _template.counter;
_abnormalTime = _template.abnormalTime;
_abnormalEffect = _template.abnormalEffect;
_specialEffect = _template.specialEffect;
_eventEffect = _template.eventEffect;
_abnormalType = _template.abnormalType;
_abnormalLvl = _template.abnormalLvl;
_periodStartTicks = effect.getPeriodStartTicks();
_periodFirstTime = effect.getTime();
_icon = _template.icon;
_isHerbEffect = _skill.getName().contains("Herb");
/*
* Commented out by DrHouse: scheduleEffect can call onStart before effect is completly initialized on constructor (child classes constructor)
*/
// scheduleEffect();
}
public int getCount()
{
return _count;
}
public int getTotalCount()
{
return _totalCount;
}
public void setCount(int newcount)
{
_count = Math.min(newcount, _totalCount); // sanity check
}
public void setFirstTime(int newFirstTime)
{
_periodFirstTime = Math.min(newFirstTime, _abnormalTime);
_periodStartTicks -= _periodFirstTime * GameTimeController.TICKS_PER_SECOND;
}
public boolean getShowIcon()
{
return _icon;
}
public int getAbnormalTime()
{
return _abnormalTime;
}
public int getTime()
{
return (GameTimeController.getGameTicks() - _periodStartTicks) / GameTimeController.TICKS_PER_SECOND;
}
/**
* Returns the elapsed time of the task.
* @return Time in seconds.
*/
public int getTaskTime()
{
if (_count == _totalCount)
{
return 0;
}
return (Math.abs((_count - _totalCount) + 1) * _abnormalTime) + getTime() + 1;
}
public boolean getInUse()
{
return _inUse;
}
public boolean setInUse(boolean inUse)
{
_inUse = inUse;
if (_inUse)
{
_startConditionsCorrect = onStart();
}
else
{
onExit();
}
return _startConditionsCorrect;
}
public String getAbnormalType()
{
return _abnormalType;
}
public byte getAbnormalLvl()
{
return _abnormalLvl;
}
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 boolean isHerbEffect()
{
return _isHerbEffect;
}
public final double calc()
{
Env env = new Env();
env.player = _effector;
env.target = _effected;
env.skill = _skill;
return _lambda.calc(env);
}
private final synchronized void startEffectTask()
{
if (_abnormalTime > 0)
{
stopEffectTask();
final int initialDelay = Math.max((_abnormalTime - _periodFirstTime) * 1000, 5);
if (_count > 1)
{
_currentFuture = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new EffectTask(), initialDelay, _abnormalTime * 1000);
}
else
{
_currentFuture = ThreadPoolManager.getInstance().scheduleEffect(new EffectTask(), initialDelay);
}
}
if (_state == EffectState.ACTING)
{
if (isSeflEffectType())
{
_effector.addEffect(this);
}
else
{
_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 icon</li><BR>
* <BR>
*/
public final void exit()
{
this.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 icon.<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 icon</li><BR>
* <BR>
*/
public final synchronized void stopEffectTask()
{
if (_currentFuture != null)
{
// Cancel the task
_currentFuture.cancel(false);
// ThreadPoolManager.getInstance().removeEffect(_currentTask);
_currentFuture = null;
if (isSeflEffectType() && (getEffector() != null))
{
getEffector().removeEffect(this);
}
else if (getEffected() != null)
{
getEffected().removeEffect(this);
}
}
}
/** returns effect type */
public abstract L2EffectType getEffectType();
/** Notify started */
public boolean onStart()
{
if (_abnormalEffect != AbnormalEffect.NULL)
{
getEffected().startAbnormalEffect(_abnormalEffect);
}
if (_specialEffect != AbnormalEffect.NULL)
{
getEffected().startSpecialEffect(_specialEffect);
}
if ((_eventEffect != AbnormalEffect.NULL) && (getEffected() instanceof L2PcInstance))
{
getEffected().getActingPlayer().startEventEffect(_eventEffect);
}
return true;
}
/**
* Cancel the effect in the the abnormal effect map of the effected L2Character.<BR>
* <BR>
*/
public void onExit()
{
if (_abnormalEffect != AbnormalEffect.NULL)
{
getEffected().stopAbnormalEffect(_abnormalEffect);
}
if (_specialEffect != AbnormalEffect.NULL)
{
getEffected().stopSpecialEffect(_specialEffect);
}
if ((_eventEffect != AbnormalEffect.NULL) && (getEffected() instanceof L2PcInstance))
{
getEffected().getActingPlayer().stopEventEffect(_eventEffect);
}
}
/** Return true for continuation of this effect */
public abstract boolean onActionTime();
public final void scheduleEffect()
{
switch (_state)
{
case CREATED:
{
_state = EffectState.ACTING;
if (_skill.isPvpSkill() && _icon && (getEffected() instanceof L2PcInstance))
{
SystemMessage smsg = SystemMessage.getSystemMessage(SystemMessageId.YOU_FEEL_S1_EFFECT);
smsg.addSkillName(_skill);
getEffected().sendPacket(smsg);
}
if (_abnormalTime != 0)
{
startEffectTask();
return;
}
// effects not having count or period should start
_startConditionsCorrect = onStart();
}
case ACTING:
{
if (_count > 0)
{
_count--;
if (getInUse())
{ // effect has to be in use
if (onActionTime() && _startConditionsCorrect && (_count > 0))
{
return; // false causes effect to finish right away
}
}
else if (_count > 0)
{ // do not finish it yet, in case reactivated
return;
}
}
_state = EffectState.FINISHING;
}
case FINISHING:
{
// If the time left is equal to zero, send the message
if ((_count == 0) && _icon && (getEffected() instanceof L2PcInstance))
{
SystemMessage smsg3 = SystemMessage.getSystemMessage(SystemMessageId.S1_HAS_WORN_OFF);
smsg3.addSkillName(_skill);
getEffected().sendPacket(smsg3);
}
// if task is null - stopEffectTask does not remove effect
if ((_currentFuture == null) && (getEffected() != null))
{
getEffected().removeEffect(this);
}
// Stop the task of the L2Effect, remove it and update client magic icon
stopEffectTask();
// Cancel the effect in the the abnormal effect map of the L2Character
if (getInUse() || !((_count > 1) || (_abnormalTime > 0)))
{
if (_startConditionsCorrect)
{
onExit();
}
}
if (_skill.getAfterEffectId() > 0)
{
L2Skill skill = SkillTable.getInstance().getInfo(_skill.getAfterEffectId(), _skill.getAfterEffectLvl());
if (skill != null)
{
getEffected().broadcastPacket(new MagicSkillUse(_effected, skill.getId(), skill.getLevel(), 0, 0));
getEffected().broadcastPacket(new MagicSkillLaunched(_effected, skill.getId(), skill.getLevel()));
skill.getEffects(getEffected(), getEffected());
}
}
}
}
}
public Func[] getStatFuncs()
{
if (_funcTemplates == null)
{
return _emptyFunctionSet;
}
ArrayList<Func> funcs = new ArrayList<>(_funcTemplates.length);
Env env = new Env();
env.player = getEffector();
env.target = getEffected();
env.skill = getSkill();
Func f;
for (FuncTemplate t : _funcTemplates)
{
f = t.getFunc(env, this); // effect is owner
if (f != null)
{
funcs.add(f);
}
}
if (funcs.isEmpty())
{
return _emptyFunctionSet;
}
return funcs.toArray(new Func[funcs.size()]);
}
public final void addIcon(AbnormalStatusUpdate mi)
{
if (_state != EffectState.ACTING)
{
return;
}
final ScheduledFuture<?> future = _currentFuture;
final L2Skill sk = getSkill();
if (_totalCount > 1)
{
if (sk.isPotion())
{
mi.addEffect(sk.getId(), getLevel(), sk.getBuffDuration() - (getTaskTime() * 1000));
}
else
{
mi.addEffect(sk.getId(), getLevel(), -1);
}
}
else if (future != null)
{
mi.addEffect(sk.getId(), getLevel(), (int) future.getDelay(TimeUnit.MILLISECONDS));
}
else if (_abnormalTime == -1)
{
mi.addEffect(sk.getId(), getLevel(), _abnormalTime);
}
}
public final void addPartySpelledIcon(PartySpelled ps)
{
if (_state != EffectState.ACTING)
{
return;
}
final ScheduledFuture<?> future = _currentFuture;
final L2Skill sk = getSkill();
if (future != null)
{
ps.addPartySpelledEffect(sk.getId(), getLevel(), (int) future.getDelay(TimeUnit.MILLISECONDS));
}
else if (_abnormalTime == -1)
{
ps.addPartySpelledEffect(sk.getId(), getLevel(), _abnormalTime);
}
}
public final void addOlympiadSpelledIcon(ExOlympiadSpelledInfo os)
{
if (_state != EffectState.ACTING)
{
return;
}
final ScheduledFuture<?> future = _currentFuture;
final L2Skill sk = getSkill();
if (future != null)
{
os.addEffect(sk.getId(), getLevel(), (int) future.getDelay(TimeUnit.MILLISECONDS));
}
else if (_abnormalTime == -1)
{
os.addEffect(sk.getId(), getLevel(), _abnormalTime);
}
}
public int getLevel()
{
return getSkill().getLevel();
}
public int getPeriodStartTicks()
{
return _periodStartTicks;
}
public EffectTemplate getEffectTemplate()
{
return _template;
}
public double getEffectPower()
{
return _effectPower;
}
public L2SkillType getSkillType()
{
return _effectSkillType;
}
public boolean canBeStolen()
{
if (!effectCanBeStolen() || (getEffectType() == L2EffectType.TRANSFORMATION) || getSkill().isPassive() || getSkill().isToggle() || getSkill().isDebuff() || getSkill().isHeroSkill() || getSkill().isGMSkill() || (getSkill().isPotion() && ((getSkill().getId() != 2274) && (getSkill().getId() != 2341))) // Hardcode
// for
// now
// :<
|| isHerbEffect() || !getSkill().canBeDispeled())
{
return false;
}
return true;
}
/**
* Return true if effect itself can be stolen
* @return
*/
protected boolean effectCanBeStolen()
{
return false;
}
/**
* Return bit flag for current effect
* @return int flag
*/
public int getEffectFlags()
{
return 0;
}
@Override
public String toString()
{
return "L2Effect [_skill=" + _skill + ", _state=" + _state + ", _period=" + _abnormalTime + "]";
}
public boolean isSeflEffectType()
{
return false;
}
}
@@ -0,0 +1,110 @@
/*
* 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.l2jserver.gameserver.model;
import java.util.List;
import javolution.util.FastList;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
public final class L2EnchantSkillGroup
{
private final int _id;
private final List<EnchantSkillDetail> _enchantDetails = new FastList<>();
public L2EnchantSkillGroup(int id)
{
_id = id;
}
public void addEnchantDetail(EnchantSkillDetail detail)
{
_enchantDetails.add(detail);
}
public int getId()
{
return _id;
}
public List<EnchantSkillDetail> getEnchantGroupDetails()
{
return _enchantDetails;
}
public static class EnchantSkillDetail
{
private final int _level;
private final int _adenaCost;
private final int _expCost;
private final int _spCost;
private final byte[] _rate;
public EnchantSkillDetail(int lvl, int adena, int exp, int sp, byte rate76, byte rate77, byte rate78, byte rate79, byte rate80, byte rate81, byte rate82, byte rate83, byte rate84, byte rate85)
{
_level = lvl;
_adenaCost = adena;
_expCost = exp;
_spCost = sp;
_rate = new byte[10];
_rate[0] = rate76;
_rate[1] = rate77;
_rate[2] = rate78;
_rate[3] = rate79;
_rate[4] = rate80;
_rate[5] = rate81;
_rate[6] = rate82;
_rate[7] = rate83;
_rate[8] = rate84;
_rate[9] = rate85;
}
/**
* @return Returns the level.
*/
public int getLevel()
{
return _level;
}
/**
* @return Returns the spCost.
*/
public int getSpCost()
{
return _spCost;
}
public int getExpCost()
{
return _expCost;
}
public int getAdenaCost()
{
return _adenaCost;
}
public byte getRate(L2PcInstance ply)
{
if (ply.getLevel() < 76)
{
return 0;
}
return _rate[ply.getLevel() - 76];
}
}
}
@@ -0,0 +1,129 @@
/*
* 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.l2jserver.gameserver.model;
import gnu.trove.TIntIntHashMap;
import com.l2jserver.gameserver.datatables.EnchantGroupsTable;
import com.l2jserver.gameserver.model.L2EnchantSkillGroup.EnchantSkillDetail;
/**
* This class ...
* @version $Revision: 1.2.4.2 $ $Date: 2005/03/27 15:29:33 $
*/
public final class L2EnchantSkillLearn
{
private final int _id;
private final int _baseLvl;
private final TIntIntHashMap _enchantRoutes = new TIntIntHashMap();
public L2EnchantSkillLearn(int id, int baseLvl)
{
_id = id;
_baseLvl = baseLvl;
}
public void addNewEnchantRoute(int route, int group)
{
_enchantRoutes.put(route, group);
}
/**
* @return Returns the id.
*/
public int getId()
{
return _id;
}
/**
* @return Returns the minLevel.
*/
public int getBaseLevel()
{
return _baseLvl;
}
public static int getEnchantRoute(int level)
{
return (int) Math.floor(level / 100);
}
public static int getEnchantIndex(int level)
{
return (level % 100) - 1;
}
public static int getEnchantType(int level)
{
return ((level - 1) / 100) - 1;
}
public L2EnchantSkillGroup getFirstRouteGroup()
{
return EnchantGroupsTable.getInstance().getEnchantSkillGroupById(_enchantRoutes.getValues()[0]);
}
public int[] getAllRoutes()
{
return _enchantRoutes.keys();
}
public int getMinSkillLevel(int level)
{
if ((level % 100) == 1)
{
return _baseLvl;
}
return level - 1;
}
public boolean isMaxEnchant(int level)
{
int enchantType = L2EnchantSkillLearn.getEnchantRoute(level);
if ((enchantType < 1) || !_enchantRoutes.contains(enchantType))
{
return false;
}
int index = L2EnchantSkillLearn.getEnchantIndex(level);
if ((index + 1) >= EnchantGroupsTable.getInstance().getEnchantSkillGroupById(_enchantRoutes.get(enchantType)).getEnchantGroupDetails().size())
{
return true;
}
return false;
}
public EnchantSkillDetail getEnchantSkillDetail(int level)
{
int enchantType = L2EnchantSkillLearn.getEnchantRoute(level);
if ((enchantType < 1) || !_enchantRoutes.contains(enchantType))
{
return null;
}
int index = L2EnchantSkillLearn.getEnchantIndex(level);
L2EnchantSkillGroup group = EnchantGroupsTable.getInstance().getEnchantSkillGroupById(_enchantRoutes.get(enchantType));
if (index < 0)
{
return group.getEnchantGroupDetails().get(0);
}
else if (index >= group.getEnchantGroupDetails().size())
{
return group.getEnchantGroupDetails().get(EnchantGroupsTable.getInstance().getEnchantSkillGroupById(_enchantRoutes.get(enchantType)).getEnchantGroupDetails().size() - 1);
}
return group.getEnchantGroupDetails().get(index);
}
}
@@ -0,0 +1,61 @@
/*
* 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.l2jserver.gameserver.model;
/**
* @author JIV
*/
public class L2ExtractableProduct
{
private final int _id;
private final int _min;
private final int _max;
private final int _chance;
/**
* Create Extractable product
* @param id crete item id
* @param min item count max
* @param max item count min
* @param chance chance for creating
*/
public L2ExtractableProduct(int id, int min, int max, double chance)
{
_id = id;
_min = min;
_max = max;
_chance = (int) (chance * 1000);
}
public int getId()
{
return _id;
}
public int getMin()
{
return _min;
}
public int getMax()
{
return _max;
}
public int getChance()
{
return _chance;
}
}
@@ -0,0 +1,47 @@
/*
* 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.l2jserver.gameserver.model;
/**
* @author -Nemesiss-, Zoey76
*/
public class L2ExtractableProductItem
{
private final int[] _id;
private final int[] _ammount;
private final double _chance;
public L2ExtractableProductItem(int[] id, int[] ammount, double chance)
{
_id = id;
_ammount = ammount;
_chance = chance;
}
public int[] getId()
{
return _id;
}
public int[] getAmmount()
{
return _ammount;
}
public double getChance()
{
return _chance;
}
}
@@ -0,0 +1,42 @@
/*
* 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.l2jserver.gameserver.model;
import javolution.util.FastList;
/**
* @author Zoey76
*/
public class L2ExtractableSkill
{
private final int _hash;
private final FastList<L2ExtractableProductItem> _product;
public L2ExtractableSkill(int hash, FastList<L2ExtractableProductItem> products)
{
_hash = hash;
_product = products;
}
public int getSkillHash()
{
return _hash;
}
public FastList<L2ExtractableProductItem> getProductItemsArray()
{
return _product;
}
}
@@ -0,0 +1,429 @@
/*
* 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.l2jserver.gameserver.model;
import java.util.concurrent.Future;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.datatables.NpcTable;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.actor.instance.L2PenaltyMonsterInstance;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.ExFishingHpRegen;
import com.l2jserver.gameserver.network.serverpackets.ExFishingStartCombat;
import com.l2jserver.gameserver.network.serverpackets.PlaySound;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
import com.l2jserver.gameserver.templates.chars.L2NpcTemplate;
import com.l2jserver.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 _anim = 0;
private int _mode = 0;
private int _deceptiveMode = 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 boolean _isUpperGrade;
private int _lureType;
@Override
public void run()
{
if (_fisher == null)
{
return;
}
if (_fishCurHp >= (_fishMaxHp * 2))
{
// The fish got away
_fisher.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.BAIT_STOLEN_BY_FISH));
doDie(false);
}
else if (_time <= 0)
{
// Time is up, so that fish got away
_fisher.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.FISH_SPIT_THE_HOOK));
doDie(false);
}
else
{
aiTask();
}
}
// =========================================================
public L2Fishing(L2PcInstance Fisher, FishData fish, boolean isNoob, boolean isUpperGrade)
{
_fisher = Fisher;
_fishMaxHp = fish.getHP();
_fishCurHp = _fishMaxHp;
_regenHp = fish.getHpRegen();
_fishId = fish.getId();
_time = fish.getCombatTime() / 1000;
_isUpperGrade = isUpperGrade;
if (isUpperGrade)
{
_deceptiveMode = Rnd.get(100) >= 90 ? 1 : 0;
_lureType = 2;
}
else
{
_deceptiveMode = 0;
_lureType = isNoob ? 0 : 1;
}
_mode = Rnd.get(100) >= 80 ? 1 : 0;
ExFishingStartCombat efsc = new ExFishingStartCombat(_fisher, _time, _fishMaxHp, _mode, _lureType, _deceptiveMode);
_fisher.broadcastPacket(efsc);
_fisher.sendPacket(new PlaySound(1, "SF_S_01", 0, 0, 0, 0, 0));
// Succeeded in getting a bite
_fisher.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.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;
}
ExFishingHpRegen efhr = new ExFishingHpRegen(_fisher, _time, _fishCurHp, _mode, _goodUse, _anim, pen, _deceptiveMode);
_fisher.broadcastPacket(efhr);
_anim = 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)
{
int check = Rnd.get(100);
if (check <= 5)
{
PenaltyMonster();
}
else
{
_fisher.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.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)
{
if (_deceptiveMode == 0)
{
_fishCurHp += (int) _regenHp;
}
}
else
{
if (_deceptiveMode == 1)
{
_fishCurHp += (int) _regenHp;
}
}
if (_stop == 0)
{
_stop = 1;
int check = Rnd.get(100);
if (check >= 70)
{
_mode = _mode == 0 ? 1 : 0;
}
if (_isUpperGrade)
{
check = Rnd.get(100);
if (check >= 90)
{
_deceptiveMode = _deceptiveMode == 0 ? 1 : 0;
}
}
}
else
{
_stop--;
}
}
finally
{
_thinking = false;
ExFishingHpRegen efhr = new ExFishingHpRegen(_fisher, _time, _fishCurHp, _mode, 0, _anim, 0, _deceptiveMode);
if (_anim != 0)
{
_fisher.broadcastPacket(efhr);
}
else
{
_fisher.sendPacket(efhr);
}
}
}
public void useRealing(int dmg, int pen)
{
_anim = 2;
if (Rnd.get(100) > 90)
{
_fisher.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.FISH_RESISTED_ATTEMPT_TO_BRING_IT_IN));
_goodUse = 0;
changeHp(0, pen);
return;
}
if (_fisher == null)
{
return;
}
if (_mode == 1)
{
if (_deceptiveMode == 0)
{
// Reeling is successful, Damage: $s1
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.REELING_SUCCESFUL_S1_DAMAGE);
sm.addNumber(dmg);
_fisher.sendPacket(sm);
if (pen == 50)
{
sm = SystemMessage.getSystemMessage(SystemMessageId.REELING_SUCCESSFUL_PENALTY_S1);
sm.addNumber(pen);
_fisher.sendPacket(sm);
}
_goodUse = 1;
changeHp(dmg, pen);
}
else
{
// Reeling failed, Damage: $s1
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.FISH_RESISTED_REELING_S1_HP_REGAINED);
sm.addNumber(dmg);
_fisher.sendPacket(sm);
_goodUse = 2;
changeHp(-dmg, pen);
}
}
else
{
if (_deceptiveMode == 0)
{
// Reeling failed, Damage: $s1
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.FISH_RESISTED_REELING_S1_HP_REGAINED);
sm.addNumber(dmg);
_fisher.sendPacket(sm);
_goodUse = 2;
changeHp(-dmg, pen);
}
else
{
// Reeling is successful, Damage: $s1
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.REELING_SUCCESFUL_S1_DAMAGE);
sm.addNumber(dmg);
_fisher.sendPacket(sm);
if (pen == 50)
{
sm = SystemMessage.getSystemMessage(SystemMessageId.REELING_SUCCESSFUL_PENALTY_S1);
sm.addNumber(pen);
_fisher.sendPacket(sm);
}
_goodUse = 1;
changeHp(dmg, pen);
}
}
}
public void usePomping(int dmg, int pen)
{
_anim = 1;
if (Rnd.get(100) > 90)
{
_fisher.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.FISH_RESISTED_ATTEMPT_TO_BRING_IT_IN));
_goodUse = 0;
changeHp(0, pen);
return;
}
if (_fisher == null)
{
return;
}
if (_mode == 0)
{
if (_deceptiveMode == 0)
{
// Pumping is successful. Damage: $s1
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.PUMPING_SUCCESFUL_S1_DAMAGE);
sm.addNumber(dmg);
_fisher.sendPacket(sm);
if (pen == 50)
{
sm = SystemMessage.getSystemMessage(SystemMessageId.PUMPING_SUCCESSFUL_PENALTY_S1);
sm.addNumber(pen);
_fisher.sendPacket(sm);
}
_goodUse = 1;
changeHp(dmg, pen);
}
else
{
// Pumping failed, Regained: $s1
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.FISH_RESISTED_PUMPING_S1_HP_REGAINED);
sm.addNumber(dmg);
_fisher.sendPacket(sm);
_goodUse = 2;
changeHp(-dmg, pen);
}
}
else
{
if (_deceptiveMode == 0)
{
// Pumping failed, Regained: $s1
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.FISH_RESISTED_PUMPING_S1_HP_REGAINED);
sm.addNumber(dmg);
_fisher.sendPacket(sm);
_goodUse = 2;
changeHp(-dmg, pen);
}
else
{
// Pumping is successful. Damage: $s1
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.PUMPING_SUCCESFUL_S1_DAMAGE);
sm.addNumber(dmg);
_fisher.sendPacket(sm);
if (pen == 50)
{
sm = SystemMessage.getSystemMessage(SystemMessageId.PUMPING_SUCCESSFUL_PENALTY_S1);
sm.addNumber(pen);
_fisher.sendPacket(sm);
}
_goodUse = 1;
changeHp(dmg, pen);
}
}
}
private void PenaltyMonster()
{
int lvl = (int) Math.round(_fisher.getLevel() * 0.1);
int npcid;
_fisher.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_CAUGHT_SOMETHING_SMELLY_THROW_IT_BACK));
switch (lvl)
{
case 0:
case 1:
npcid = 18319;
break;
case 2:
npcid = 18320;
break;
case 3:
npcid = 18321;
break;
case 4:
npcid = 18322;
break;
case 5:
npcid = 18323;
break;
case 6:
npcid = 18324;
break;
case 7:
npcid = 18325;
break;
case 8:
case 9:
npcid = 18326;
break;
default:
npcid = 18319;
break;
}
L2NpcTemplate temp;
temp = NpcTable.getInstance().getTemplate(npcid);
if (temp != null)
{
try
{
L2Spawn spawn = new L2Spawn(temp);
spawn.setLocx(_fisher.getX());
spawn.setLocy(_fisher.getY());
spawn.setLocz(_fisher.getZ() + 20);
spawn.setAmount(1);
spawn.setHeading(_fisher.getHeading());
spawn.stopRespawn();
((L2PenaltyMonsterInstance) spawn.doSpawn().scheduleDespawn(3 * 60 * 1000)).setPlayerToKill(_fisher);
}
catch (Exception e)
{
// Nothing
}
}
}
}
@@ -0,0 +1,119 @@
/*
* 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.l2jserver.gameserver.model;
import java.lang.reflect.Constructor;
import java.util.logging.Level;
import com.l2jserver.Config;
import com.l2jserver.gameserver.Territory;
import com.l2jserver.gameserver.idfactory.IdFactory;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.templates.chars.L2NpcTemplate;
import com.l2jserver.util.Rnd;
/**
* @author littlecrow A special spawn implementation to spawn controllable mob
*/
public class L2GroupSpawn extends L2Spawn
{
private final Constructor<?> _constructor;
private final L2NpcTemplate _template;
public L2GroupSpawn(L2NpcTemplate mobTemplate) throws SecurityException, ClassNotFoundException, NoSuchMethodException
{
super(mobTemplate);
_constructor = Class.forName("com.l2jserver.gameserver.model.actor.instance.L2ControllableMobInstance").getConstructors()[0];
_template = mobTemplate;
setAmount(1);
}
public L2Npc doGroupSpawn()
{
L2Npc mob = null;
try
{
if (_template.type.equalsIgnoreCase("L2Pet") || _template.type.equalsIgnoreCase("L2Minion"))
{
return null;
}
Object[] parameters =
{
IdFactory.getInstance().getNextId(),
_template
};
Object tmp = _constructor.newInstance(parameters);
if (!(tmp instanceof L2Npc))
{
return null;
}
mob = (L2Npc) tmp;
int newlocx, newlocy, newlocz;
if ((getLocx() == 0) && (getLocy() == 0))
{
if (getLocation() == 0)
{
return null;
}
int p[] = Territory.getInstance().getRandomPoint(getLocation());
newlocx = p[0];
newlocy = p[1];
newlocz = p[2];
}
else
{
newlocx = getLocx();
newlocy = getLocy();
newlocz = getLocz();
}
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 (Exception e)
{
_log.log(Level.WARNING, "NPC class not found: " + e.getMessage(), e);
return null;
}
}
}
@@ -0,0 +1,215 @@
/*
* 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.l2jserver.gameserver.model;
import com.l2jserver.gameserver.templates.item.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 _statMEM;
private int _statDEX;
private int _statWIT;
private int _amountDyeRequire;
public L2HennaInstance(L2Henna template)
{
_template = template;
_symbolId = _template.getSymbolId();
_itemIdDye = _template.getDyeId();
_amountDyeRequire = _template.getAmountDyeRequire();
_price = _template.getPrice();
_statINT = _template.getStatINT();
_statSTR = _template.getStatSTR();
_statCON = _template.getStatCON();
_statMEM = _template.getStatMEM();
_statDEX = _template.getStatDEX();
_statWIT = _template.getStatWIT();
}
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 (_statMEM > 0)
{
res = res + "MEN +" + _statMEM;
}
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 (_statMEM < 0)
{
res = res + ", MEN " + _statMEM;
}
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 getStatMEM()
{
return _statMEM;
}
public void setStatMEM(int StatMEM)
{
_statMEM = StatMEM;
}
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
@@ -0,0 +1,221 @@
/*
* 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.l2jserver.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.
*/
@Deprecated
public float getClassHpAdd()
{
return _classHpAdd;
}
/**
* @param hpAdd The _classHpAdd to set.
*/
public void setClassHpAdd(float hpAdd)
{
_classHpAdd = hpAdd;
}
/**
* @return Returns the _classHpBase.
*/
@Deprecated
public float getClassHpBase()
{
return _classHpBase;
}
/**
* @param hpBase The _classHpBase to set.
*/
public void setClassHpBase(float hpBase)
{
_classHpBase = hpBase;
}
/**
* @return Returns the _classHpModifier.
*/
@Deprecated
public float getClassHpModifier()
{
return _classHpModifier;
}
/**
* @param hpModifier The _classHpModifier to set.
*/
public void setClassHpModifier(float hpModifier)
{
_classHpModifier = hpModifier;
}
/**
* @return Returns the _classCpAdd.
*/
@Deprecated
public float getClassCpAdd()
{
return _classCpAdd;
}
/**
* @param hpAdd The _classCpAdd to set.
*/
public void setClassCpAdd(float cpAdd)
{
_classCpAdd = cpAdd;
}
/**
* @return Returns the _classCpBase.
*/
@Deprecated
public float getClassCpBase()
{
return _classCpBase;
}
/**
* @param hpBase The _classCpBase to set.
*/
public void setClassCpBase(float cpBase)
{
_classCpBase = cpBase;
}
/**
* @return Returns the _classCpModifier.
*/
@Deprecated
public float getClassCpModifier()
{
return _classCpModifier;
}
/**
* @param cpModifier The _classCpModifier to set.
*/
public void setClassCpModifier(float cpModifier)
{
_classCpModifier = cpModifier;
}
/**
* @return Returns the _classid.
*/
public int getClassid()
{
return _classid;
}
/**
* @param _classid The _classid to set.
*/
public void setClassid(int pClassid)
{
_classid = pClassid;
}
/**
* @return Returns the _classLvl.
*/
@Deprecated
public int getClassLvl()
{
return _classLvl;
}
/**
* @param lvl The _classLvl to set.
*/
public void setClassLvl(int lvl)
{
_classLvl = lvl;
}
/**
* @return Returns the _classMpAdd.
*/
@Deprecated
public float getClassMpAdd()
{
return _classMpAdd;
}
/**
* @param mpAdd The _classMpAdd to set.
*/
public void setClassMpAdd(float mpAdd)
{
_classMpAdd = mpAdd;
}
/**
* @return Returns the _classMpBase.
*/
@Deprecated
public float getClassMpBase()
{
return _classMpBase;
}
/**
* @param mpBase The _classMpBase to set.
*/
public void setClassMpBase(float mpBase)
{
_classMpBase = mpBase;
}
/**
* @return Returns the _classMpModifier.
*/
@Deprecated
public float getClassMpModifier()
{
return _classMpModifier;
}
/**
* @param mpModifier The _classMpModifier to set.
*/
public void setClassMpModifier(float mpModifier)
{
_classMpModifier = mpModifier;
}
}
@@ -0,0 +1,65 @@
/*
* 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.l2jserver.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;
}
}
/**
*
*/
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;
}
}
@@ -0,0 +1,484 @@
/*
* 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.l2jserver.gameserver.model;
import java.io.File;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilderFactory;
import javolution.util.FastList;
import javolution.util.FastMap;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import com.l2jserver.Config;
import com.l2jserver.gameserver.datatables.ItemTable;
import com.l2jserver.gameserver.templates.item.L2Item;
/**
* Service class for manor
* @author l3x
*/
public class L2Manor
{
private static Logger _log = Logger.getLogger(L2Manor.class.getName());
private static FastMap<Integer, SeedData> _seeds;
private L2Manor()
{
_seeds = new FastMap<Integer, SeedData>().shared();
parseData();
}
public static L2Manor getInstance()
{
return SingletonHolder._instance;
}
public FastList<Integer> getAllCrops()
{
FastList<Integer> crops = new FastList<>();
for (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)
{
L2Item seedItem = ItemTable.getInstance().getTemplate(seedId);
if (seedItem != null)
{
return seedItem.getReferencePrice();
}
return 0;
}
public int getSeedBasicPriceByCrop(int cropId)
{
for (SeedData seed : _seeds.values())
{
if (seed.getCrop() == cropId)
{
return getSeedBasicPrice(seed.getId());
}
}
return 0;
}
public int getCropBasicPrice(int cropId)
{
L2Item cropItem = ItemTable.getInstance().getTemplate(cropId);
return (cropItem != null) ? cropItem.getReferencePrice() : 0;
}
public int getMatureCrop(int cropId)
{
for (SeedData seed : _seeds.values())
{
if (seed.getCrop() == cropId)
{
return seed.getMature();
}
}
return 0;
}
/**
* Returns price which lord pays to buy one seed
* @param seedId
* @return seed price
*/
public long getSeedBuyPrice(int seedId)
{
long buyPrice = getSeedBasicPrice(seedId);
return (buyPrice > 0 ? buyPrice : 1);
}
public int getSeedMinLevel(int seedId)
{
SeedData seed = _seeds.get(seedId);
if (seed != null)
{
return seed.getLevel() - 5;
}
return -1;
}
public int getSeedMaxLevel(int seedId)
{
SeedData seed = _seeds.get(seedId);
if (seed != null)
{
return seed.getLevel() + 5;
}
return -1;
}
public int getSeedLevelByCrop(int cropId)
{
for (SeedData seed : _seeds.values())
{
if (seed.getCrop() == cropId)
{
return seed.getLevel();
}
}
return 0;
}
public int getSeedLevel(int seedId)
{
SeedData seed = _seeds.get(seedId);
if (seed != null)
{
return seed.getLevel();
}
return -1;
}
public boolean isAlternative(int seedId)
{
for (SeedData seed : _seeds.values())
{
if (seed.getId() == seedId)
{
return seed.isAlternative();
}
}
return false;
}
public int getCropType(int seedId)
{
SeedData seed = _seeds.get(seedId);
if (seed != null)
{
return seed.getCrop();
}
return -1;
}
public int getRewardItem(int cropId, int type)
{
for (SeedData seed : _seeds.values())
{
if (seed.getCrop() == cropId)
{
return seed.getReward(type); // there can be several
// seeds with same crop, but
// reward should be the same for
// all
}
}
return -1;
}
public int getRewardItemBySeed(int seedId, int type)
{
SeedData seed = _seeds.get(seedId);
if (seed != null)
{
return seed.getReward(type);
}
return 0;
}
/**
* Return all crops which can be purchased by given castle
* @param castleId
* @return
*/
public FastList<Integer> getCropsForCastle(int castleId)
{
FastList<Integer> crops = new FastList<>();
for (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)
{
FastList<Integer> seedsID = new FastList<>();
for (SeedData seed : _seeds.values())
{
if ((seed.getManorId() == castleId) && !seedsID.contains(seed.getId()))
{
seedsID.add(seed.getId());
}
}
return seedsID;
}
/**
* Returns castle id where seed can be sowned<br>
* @param seedId
* @return castleId
*/
public int getCastleIdForSeed(int seedId)
{
SeedData seed = _seeds.get(seedId);
if (seed != null)
{
return seed.getManorId();
}
return 0;
}
public int getSeedSaleLimit(int seedId)
{
SeedData seed = _seeds.get(seedId);
if (seed != null)
{
return seed.getSeedLimit();
}
return 0;
}
public int getCropPuchaseLimit(int cropId)
{
for (SeedData seed : _seeds.values())
{
if (seed.getCrop() == cropId)
{
return seed.getCropLimit();
}
}
return 0;
}
private static 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 boolean _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, boolean 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;
}
public int getSeedLimit()
{
return _limitSeeds * Config.RATE_DROP_MANOR;
}
public int getCropLimit()
{
return _limitCrops * Config.RATE_DROP_MANOR;
}
@Override
public String toString()
{
return "SeedData [_id=" + _id + ", _level=" + _level + ", _crop=" + _crop + ", _mature=" + _mature + ", _type1=" + _type1 + ", _type2=" + _type2 + ", _manorId=" + _manorId + ", _isAlternative=" + _isAlternative + ", _limitSeeds=" + _limitSeeds + ", _limitCrops=" + _limitCrops + "]";
}
}
private void parseData()
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(false);
factory.setIgnoringComments(true);
File file = new File(Config.DATAPACK_ROOT, "/data/seeds.xml");
Document doc = null;
try
{
doc = factory.newDocumentBuilder().parse(file);
}
catch (Exception e)
{
_log.log(Level.WARNING, "Could not parse seeds.xml file: " + e.getMessage(), e);
return;
}
doc.getDocumentElement().normalize();
// list
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
// castle
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("castle".equalsIgnoreCase(d.getNodeName()))
{
int castleId = Integer.parseInt(d.getAttributes().getNamedItem("id").getNodeValue());
// crop
for (Node c = d.getFirstChild(); c != null; c = c.getNextSibling())
{
if ("crop".equalsIgnoreCase(c.getNodeName()))
{
int cropId = Integer.parseInt(c.getAttributes().getNamedItem("id").getNodeValue());
int seedId = 0;
int matureId = 0;
int type1R = 0;
int type2R = 0;
boolean isAlt = false;
int level = 0;
int limitSeeds = 0;
int limitCrops = 0;
// attrib
for (Node a = c.getFirstChild(); a != null; a = a.getNextSibling())
{
if (a.getNodeName().equalsIgnoreCase("seed_id"))
{
seedId = Integer.parseInt(a.getAttributes().getNamedItem("val").getNodeValue());
}
else if (a.getNodeName().equalsIgnoreCase("mature_id"))
{
matureId = Integer.parseInt(a.getAttributes().getNamedItem("val").getNodeValue());
}
else if (a.getNodeName().equalsIgnoreCase("reward1"))
{
type1R = Integer.parseInt(a.getAttributes().getNamedItem("val").getNodeValue());
}
else if (a.getNodeName().equalsIgnoreCase("reward2"))
{
type2R = Integer.parseInt(a.getAttributes().getNamedItem("val").getNodeValue());
}
else if (a.getNodeName().equalsIgnoreCase("alternative"))
{
isAlt = Integer.parseInt(a.getAttributes().getNamedItem("val").getNodeValue()) == 1;
}
else if (a.getNodeName().equalsIgnoreCase("level"))
{
level = Integer.parseInt(a.getAttributes().getNamedItem("val").getNodeValue());
}
else if (a.getNodeName().equalsIgnoreCase("limit_seed"))
{
limitSeeds = Integer.parseInt(a.getAttributes().getNamedItem("val").getNodeValue());
}
else if (a.getNodeName().equalsIgnoreCase("limit_crops"))
{
limitCrops = Integer.parseInt(a.getAttributes().getNamedItem("val").getNodeValue());
}
}
SeedData seed = new SeedData(level, cropId, matureId);
seed.setData(seedId, type1R, type2R, castleId, isAlt, limitSeeds, limitCrops);
_seeds.put(seed.getId(), seed);
}
}
}
}
}
_log.info(getClass().getSimpleName() + ": Loaded " + _seeds.size() + " Seeds.");
}
}
@SuppressWarnings("synthetic-access")
private static class SingletonHolder
{
protected static final L2Manor _instance = new L2Manor();
}
public static void main(String[] arg)
{
L2Manor.getInstance();
}
}
@@ -0,0 +1,51 @@
/*
* 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.l2jserver.gameserver.model;
import com.l2jserver.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 long _cost;
private final boolean _isDwarven;
public L2ManufactureItem(int recipeId, long cost)
{
_recipeId = recipeId;
_cost = cost;
_isDwarven = RecipeController.getInstance().getRecipeList(_recipeId).isDwarvenRecipe();
}
public int getRecipeId()
{
return _recipeId;
}
public long getCost()
{
return _cost;
}
public boolean isDwarven()
{
return _isDwarven;
}
}
@@ -0,0 +1,83 @@
/*
* 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.l2jserver.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;
}
}
@@ -0,0 +1,99 @@
/*
* 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.l2jserver.gameserver.model;
import com.l2jserver.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 if The L2Character Identifier to spawn
*/
public void setMinionId(int id)
{
_minionId = id;
}
/**
* Return the Identifier of the Minion to spawn.<BR>
* <BR>
*/
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>
*/
public int getAmount()
{
if (_minionAmountMax > _minionAmountMin)
{
_minionAmount = Rnd.get(_minionAmountMin, _minionAmountMax);
return _minionAmount;
}
return _minionAmountMin;
}
}
@@ -0,0 +1,348 @@
/*
* 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 2, 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* http://www.gnu.org/copyleft/gpl.html
*/
package com.l2jserver.gameserver.model;
import com.l2jserver.gameserver.templates.chars.L2NpcTemplate.AIType;
/**
* Author: ShanSoft By L2JTW
*/
// This Data is for NPC Attributes and AI relate stuffs...
// Still need to finish...Update later...
public class L2NpcAIData
{
// Basic AI
private int _primary_attack;
private int _skill_chance;
private int _canMove;
private int _soulshot;
private int _spiritshot;
private int _soulshotchance;
private int _spiritshotchance;
private int _ischaos;
private String _clan = null;
private int _clanRange;
private String _enemyClan = null;
private int _enemyRange;
// private int _baseShldRate;
// private int _baseShldDef;
private int _dodge;
private int _longrangeskill;
private int _shortrangeskill;
private int _longrangechance;
private int _shortrangechance;
private int _switchrangechance;
private AIType _aiType = AIType.FIGHTER;
// --------------------------------------------------------------------------------------------------------------
// Setting....
// --------------------------------------------------------------------------------------------------------------
public void setPrimaryAttack(int primaryattack)
{
_primary_attack = primaryattack;
}
public void setSkillChance(int skill_chance)
{
_skill_chance = skill_chance;
}
public void setCanMove(int canMove)
{
_canMove = canMove;
}
public void setSoulShot(int soulshot)
{
_soulshot = soulshot;
}
public void setSpiritShot(int spiritshot)
{
_spiritshot = spiritshot;
}
public void setSoulShotChance(int soulshotchance)
{
_soulshotchance = soulshotchance;
}
public void setSpiritShotChance(int spiritshotchance)
{
_spiritshotchance = spiritshotchance;
}
public void setShortRangeSkill(int shortrangeskill)
{
_shortrangeskill = shortrangeskill;
}
public void setShortRangeChance(int shortrangechance)
{
_shortrangechance = shortrangechance;
}
public void setLongRangeSkill(int longrangeskill)
{
_longrangeskill = longrangeskill;
}
public void setLongRangeChance(int longrangechance)
{
_shortrangechance = longrangechance;
}
public void setSwitchRangeChance(int switchrangechance)
{
_switchrangechance = switchrangechance;
}
public void setIsChaos(int ischaos)
{
_ischaos = ischaos;
}
public void setClan(String clan)
{
if ((clan != null) && !clan.equals("") && !clan.equalsIgnoreCase("null"))
{
_clan = clan.intern();
}
}
public void setClanRange(int clanRange)
{
_clanRange = clanRange;
}
public void setEnemyClan(String enemyClan)
{
if ((enemyClan != null) && !enemyClan.equals("") && !enemyClan.equalsIgnoreCase("null"))
{
_enemyClan = enemyClan.intern();
}
}
public void setEnemyRange(int enemyRange)
{
_enemyRange = enemyRange;
}
public void setDodge(int dodge)
{
_dodge = dodge;
}
public void setAi(String ai)
{
if (ai.equalsIgnoreCase("archer"))
{
_aiType = AIType.ARCHER;
}
else if (ai.equalsIgnoreCase("balanced"))
{
_aiType = AIType.BALANCED;
}
else if (ai.equalsIgnoreCase("mage"))
{
_aiType = AIType.MAGE;
}
else if (ai.equalsIgnoreCase("healer"))
{
_aiType = AIType.HEALER;
}
else if (ai.equalsIgnoreCase("corpse"))
{
_aiType = AIType.CORPSE;
}
else
{
_aiType = AIType.FIGHTER;
}
}
/*
* public void setBaseShldRate (int baseShldRate) { _baseShldRate = baseShldRate; } public void setBaseShldDef (int baseShldDef) { _baseShldDef = baseShldDef; }
*/
// --------------------------------------------------------------------------------------------------------------
// Data Recall....
// --------------------------------------------------------------------------------------------------------------
public int getPrimaryAttack()
{
return _primary_attack;
}
public int getSkillChance()
{
return _skill_chance;
}
public int getCanMove()
{
return _canMove;
}
public int getSoulShot()
{
return _soulshot;
}
public int getSpiritShot()
{
return _spiritshot;
}
public int getSoulShotChance()
{
return _soulshotchance;
}
public int getSpiritShotChance()
{
return _spiritshotchance;
}
public int getShortRangeSkill()
{
return _shortrangeskill;
}
public int getShortRangeChance()
{
return _shortrangechance;
}
public int getLongRangeSkill()
{
return _longrangeskill;
}
public int getLongRangeChance()
{
return _longrangechance;
}
public int getSwitchRangeChance()
{
return _switchrangechance;
}
public int getIsChaos()
{
return _ischaos;
}
public String getClan()
{
return _clan;
}
public int getClanRange()
{
return _clanRange;
}
public String getEnemyClan()
{
return _enemyClan;
}
public int getEnemyRange()
{
return _enemyRange;
}
public int getDodge()
{
return _dodge;
}
public AIType getAiType()
{
return _aiType;
}
/*
* public int getBaseShldRate () { return _baseShldRate; } public int getBaseShldDef () { return _baseShldDef; }
*/
}
@@ -0,0 +1,95 @@
/*
* 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.l2jserver.gameserver.model;
/**
* @author Rayan RPG, JIV
* @since 927
*/
public class L2NpcWalkerNode
{
private final int _routeId;
private String _chatText;
private int _chatId = 0;
private final int _moveX;
private final int _moveY;
private final int _moveZ;
private final int _delay;
private final boolean _running;
public L2NpcWalkerNode(int routeId, String chatText, int moveX, int moveY, int moveZ, int delay, boolean running)
{
super();
_routeId = routeId;
_chatText = chatText;
if (_chatText.startsWith("#"))
{
_chatId = Integer.parseInt(_chatText.substring(1));
}
else if (_chatText.trim().isEmpty())
{
_chatText = null;
}
_moveX = moveX;
_moveY = moveY;
_moveZ = moveZ;
_delay = delay;
_running = running;
}
public int getRouteId()
{
return _routeId;
}
public String getChatText()
{
if (_chatId != 0)
{
throw new IllegalStateException("Chat id is defined for walker route!");
}
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;
}
public int getChatId()
{
return _chatId;
}
}
@@ -0,0 +1,727 @@
/*
* 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.l2jserver.gameserver.model;
import com.l2jserver.gameserver.handler.ActionHandler;
import com.l2jserver.gameserver.handler.IActionHandler;
import com.l2jserver.gameserver.idfactory.IdFactory;
import com.l2jserver.gameserver.instancemanager.InstanceManager;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.actor.knownlist.ObjectKnownList;
import com.l2jserver.gameserver.model.actor.poly.ObjectPoly;
import com.l2jserver.gameserver.model.actor.position.ObjectPosition;
import com.l2jserver.gameserver.model.entity.Instance;
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
import com.l2jserver.gameserver.network.serverpackets.ExSendUIEvent;
import com.l2jserver.gameserver.network.serverpackets.L2GameServerPacket;
/**
* Mother class of all objects in the world wich 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 boolean _isVisible; // Object visibility
private ObjectKnownList _knownList;
private String _name;
private int _objectId; // Object identifier
private ObjectPoly _poly;
private ObjectPosition _position;
private int _instanceId = 0;
private InstanceType _instanceType = null;
// =========================================================
// Constructor
public L2Object(int objectId)
{
setInstanceType(InstanceType.L2Object);
_objectId = objectId;
initKnownList();
initPosition();
}
public static enum InstanceType
{
L2Object(null),
L2ItemInstance(L2Object),
L2Character(L2Object),
L2Npc(L2Character),
L2Playable(L2Character),
L2Summon(L2Playable),
L2Decoy(L2Character),
L2Trap(L2Character),
L2PcInstance(L2Playable),
L2NpcInstance(L2Npc),
L2MerchantInstance(L2NpcInstance),
L2WarehouseInstance(L2NpcInstance),
L2StaticObjectInstance(L2Character),
L2DoorInstance(L2Character),
L2NpcWalkerInstance(L2Npc),
L2TerrainObjectInstance(L2Npc),
L2EffectPointInstance(L2Npc),
// Summons, Pets, Decoys and Traps
L2SummonInstance(L2Summon),
L2SiegeSummonInstance(L2SummonInstance),
L2MerchantSummonInstance(L2SummonInstance),
L2PetInstance(L2Summon),
L2BabyPetInstance(L2PetInstance),
L2DecoyInstance(L2Decoy),
L2TrapInstance(L2Trap),
// Attackable
L2Attackable(L2Npc),
L2GuardInstance(L2Attackable),
L2MonsterInstance(L2Attackable),
L2ChestInstance(L2MonsterInstance),
L2ControllableMobInstance(L2MonsterInstance),
L2FeedableBeastInstance(L2MonsterInstance),
L2TamedBeastInstance(L2FeedableBeastInstance),
L2FriendlyMobInstance(L2Attackable),
L2PenaltyMonsterInstance(L2MonsterInstance),
L2RiftInvaderInstance(L2MonsterInstance),
L2RaidBossInstance(L2MonsterInstance),
L2GrandBossInstance(L2RaidBossInstance),
// FlyMobs
L2FlyNpcInstance(L2NpcInstance),
L2FlyMonsterInstance(L2MonsterInstance),
L2FlyRaidBossInstance(L2RaidBossInstance),
L2FlyTerrainObjectInstance(L2Npc),
// Sepulchers
L2SepulcherNpcInstance(L2NpcInstance),
L2SepulcherMonsterInstance(L2MonsterInstance),
// Festival
L2FestivalGiudeInstance(L2Npc),
L2FestivalMonsterInstance(L2MonsterInstance),
// Vehicles
L2Vehicle(L2Character),
L2BoatInstance(L2Vehicle),
L2AirShipInstance(L2Vehicle),
L2ControllableAirShipInstance(L2AirShipInstance),
// Siege
L2DefenderInstance(L2Attackable),
L2ArtefactInstance(L2NpcInstance),
L2ControlTowerInstance(L2Npc),
L2FlameTowerInstance(L2Npc),
L2SiegeFlagInstance(L2Npc),
L2SiegeNpcInstance(L2Npc),
// Fort Siege
L2FortBallistaInstance(L2Npc),
L2FortCommanderInstance(L2DefenderInstance),
// Castle NPCs
L2CastleBlacksmithInstance(L2NpcInstance),
L2CastleChamberlainInstance(L2MerchantInstance),
L2CastleMagicianInstance(L2NpcInstance),
L2CastleTeleporterInstance(L2Npc),
L2CastleWarehouseInstance(L2WarehouseInstance),
L2MercManagerInstance(L2MerchantInstance),
// Fort NPCs
L2FortEnvoyInstance(L2Npc),
L2FortLogisticsInstance(L2MerchantInstance),
L2FortManagerInstance(L2MerchantInstance),
L2FortSiegeNpcInstance(L2NpcWalkerInstance),
L2FortSupportCaptainInstance(L2MerchantInstance),
// Seven Signs
L2CabaleBufferInstance(L2Npc),
L2SignsPriestInstance(L2Npc),
L2DawnPriestInstance(L2SignsPriestInstance),
L2DuskPriestInstance(L2SignsPriestInstance),
L2DungeonGatekeeperInstance(L2Npc),
// City NPCs
L2AdventurerInstance(L2NpcInstance),
L2AuctioneerInstance(L2Npc),
L2ClanHallManagerInstance(L2MerchantInstance),
L2ClanTraderInstance(L2Npc),
L2FameManagerInstance(L2Npc),
L2FishermanInstance(L2MerchantInstance),
L2ManorManagerInstance(L2MerchantInstance),
L2MercenaryManagerInstance(L2Npc),
L2ObservationInstance(L2Npc),
L2OlympiadManagerInstance(L2Npc),
L2PetManagerInstance(L2MerchantInstance),
L2RaceManagerInstance(L2Npc),
L2SymbolMakerInstance(L2Npc),
L2TeleporterInstance(L2Npc),
L2TownPetInstance(L2Npc),
L2TrainerInstance(L2NpcInstance),
L2TrainerHealersInstance(L2TrainerInstance),
L2TransformManagerInstance(L2MerchantInstance),
L2VillageMasterInstance(L2NpcInstance),
L2WyvernManagerInstance(L2NpcInstance),
L2XmassTreeInstance(L2NpcInstance),
// Doormens
L2DoormenInstance(L2NpcInstance),
L2CastleDoormenInstance(L2DoormenInstance),
L2FortDoormenInstance(L2DoormenInstance),
L2ClanHallDoormenInstance(L2DoormenInstance),
// Custom
L2ClassMasterInstance(L2NpcInstance),
L2NpcBufferInstance(L2Npc),
L2TvTEventNpcInstance(L2Npc),
L2WeddingManagerInstance(L2Npc),
L2EventMobInstance(L2Npc);
private final InstanceType _parent;
private final long _typeL;
private final long _typeH;
private final long _maskL;
private final long _maskH;
private InstanceType(InstanceType parent)
{
_parent = parent;
final int high = ordinal() - (Long.SIZE - 1);
if (high < 0)
{
_typeL = 1L << ordinal();
_typeH = 0;
}
else
{
_typeL = 0;
_typeH = 1L << high;
}
if ((_typeL < 0) || (_typeH < 0))
{
throw new Error("Too many instance types, failed to load " + name());
}
if (parent != null)
{
_maskL = _typeL | parent._maskL;
_maskH = _typeH | parent._maskH;
}
else
{
_maskL = _typeL;
_maskH = _typeH;
}
}
public final InstanceType getParent()
{
return _parent;
}
public final boolean isType(InstanceType it)
{
return ((_maskL & it._typeL) > 0) || ((_maskH & it._typeH) > 0);
}
public final boolean isTypes(InstanceType... it)
{
for (InstanceType i : it)
{
if (isType(i))
{
return true;
}
}
return false;
}
}
protected final void setInstanceType(InstanceType i)
{
_instanceType = i;
}
public final InstanceType getInstanceType()
{
return _instanceType;
}
public final boolean isInstanceType(InstanceType i)
{
return _instanceType.isType(i);
}
public final boolean isInstanceTypes(InstanceType... i)
{
return _instanceType.isTypes(i);
}
// =========================================================
// Event - Public
public final void onAction(L2PcInstance player)
{
onAction(player, true);
}
public void onAction(L2PcInstance player, boolean interact)
{
IActionHandler handler = ActionHandler.getInstance().getActionHandler(getInstanceType());
if (handler != null)
{
handler.action(player, this, interact);
}
player.sendPacket(ActionFailed.STATIC_PACKET);
}
public void onActionShift(L2PcInstance player)
{
IActionHandler handler = ActionHandler.getInstance().getActionShiftHandler(getInstanceType());
if (handler != null)
{
handler.action(player, this, true);
}
player.sendPacket(ActionFailed.STATIC_PACKET);
}
public void onForcedAttack(L2PcInstance player)
{
player.sendPacket(ActionFailed.STATIC_PACKET);
}
/**
* Do Nothing.<BR>
* <BR>
* <B><U> Overridden 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()
{
assert (getPosition().getWorldRegion() != null) || _isVisible;
return getPosition().getX();
}
/**
* @return The id of the instance zone the object is in - id 0 is global since everything like dropped items, mobs, players can be in a instanciated area, it must be in l2object
*/
public int getInstanceId()
{
return _instanceId;
}
/**
* @param instanceId The id of the instance zone the object is in - id 0 is global
*/
public void setInstanceId(int instanceId)
{
if (_instanceId == instanceId)
{
return;
}
Instance oldI = InstanceManager.getInstance().getInstance(_instanceId);
Instance newI = InstanceManager.getInstance().getInstance(instanceId);
if (newI == null)
{
return;
}
if (this instanceof L2PcInstance)
{
if ((_instanceId > 0) && (oldI != null))
{
oldI.removePlayer(getObjectId());
if (oldI.isShowTimer())
{
int startTime = (int) ((System.currentTimeMillis() - oldI.getInstanceStartTime()) / 1000);
int endTime = (int) ((oldI.getInstanceEndTime() - oldI.getInstanceStartTime()) / 1000);
if (oldI.isTimerIncrease())
{
sendPacket(new ExSendUIEvent(this, true, true, startTime, endTime, oldI.getTimerText()));
}
else
{
sendPacket(new ExSendUIEvent(this, true, false, endTime - startTime, 0, oldI.getTimerText()));
}
}
}
if (instanceId > 0)
{
newI.addPlayer(getObjectId());
if (newI.isShowTimer())
{
int startTime = (int) ((System.currentTimeMillis() - newI.getInstanceStartTime()) / 1000);
int endTime = (int) ((newI.getInstanceEndTime() - newI.getInstanceStartTime()) / 1000);
if (newI.isTimerIncrease())
{
sendPacket(new ExSendUIEvent(this, false, true, startTime, endTime, newI.getTimerText()));
}
else
{
sendPacket(new ExSendUIEvent(this, false, false, endTime - startTime, 0, newI.getTimerText()));
}
}
}
if (((L2PcInstance) this).getPet() != null)
{
((L2PcInstance) this).getPet().setInstanceId(instanceId);
}
}
else if (this instanceof L2Npc)
{
if ((_instanceId > 0) && (oldI != null))
{
oldI.removeNpc(((L2Npc) this));
}
if (instanceId > 0)
{
newI.addNpc(((L2Npc) this));
}
}
_instanceId = instanceId;
// If we change it for visible objects, me must clear & revalidate knownlists
if (_isVisible && (_knownList != null))
{
if (this instanceof L2PcInstance)
{
// We don't want some ugly looking disappear/appear effects, so don't update
// the knownlist here, but players usually enter instancezones through teleporting
// and the teleport will do the revalidation for us.
}
else
{
decayMe();
spawnMe();
}
}
}
public final int getY()
{
assert (getPosition().getWorldRegion() != null) || _isVisible;
return getPosition().getY();
}
public final int getZ()
{
assert (getPosition().getWorldRegion() != null) || _isVisible;
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 void decayMe()
{
assert getPosition().getWorldRegion() != null;
L2WorldRegion reg = getPosition().getWorldRegion();
synchronized (this)
{
_isVisible = false;
getPosition().setWorldRegion(null);
}
// this can synchronize on others instancies, so it's out of
// synchronized, to avoid deadlocks
// Remove the L2Object from the world
L2World.getInstance().removeVisibleObject(this, reg);
L2World.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()
{
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
_isVisible = true;
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 instancies, 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());
onSpawn();
}
public final void spawnMe(int x, int y, int z)
{
assert getPosition().getWorldRegion() == null;
synchronized (this)
{
// Set the x,y,z position of the L2Object spawn and update its _worldregion
_isVisible = true;
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);
// these can synchronize on others instancies, so they're out of
// synchronized, to avoid deadlocks
// Add the L2Object spawn to _visibleObjects and if necessary to _allplayers of its L2WorldRegion
getPosition().getWorldRegion().addVisibleObject(this);
// Add the L2Object spawn in the world as a visible object
L2World.getInstance().addVisibleObject(this, getPosition().getWorldRegion());
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 visibilty state of the L2Object. <BR>
* <BR>
* <B><U> Concept</U> :</B><BR>
* <BR>
* A L2Object is visble if <B>__IsVisible</B>=true and <B>_worldregion</B>!=null <BR>
* <BR>
*/
public final boolean isVisible()
{
// return getPosition().getWorldRegion() != null && _IsVisible;
return getPosition().getWorldRegion() != null;
}
public final void setIsVisible(boolean value)
{
_isVisible = value;
if (!_isVisible)
{
getPosition().setWorldRegion(null);
}
}
public ObjectKnownList getKnownList()
{
return _knownList;
}
/**
* Initializes the KnownList of the L2Object, is overwritten in classes that require a different knownlist Type. Removes the need for instanceof checks.
*/
public void initKnownList()
{
_knownList = new ObjectKnownList(this);
}
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 ObjectPosition getPosition()
{
return _position;
}
/**
* Initializes the Position class of the L2Object, is overwritten in classes that require a different position Type. Removes the need for instanceof checks.
*/
public void initPosition()
{
_position = new ObjectPosition(this);
}
public final void setObjectPosition(ObjectPosition value)
{
_position = value;
}
/**
* returns reference to region this object is in
*/
public L2WorldRegion getWorldRegion()
{
return getPosition().getWorldRegion();
}
public L2PcInstance getActingPlayer()
{
return null;
}
/**
* Sends the Server->Client info packet for the object.<br>
* <br>
* Is Overridden in: <li>L2AirShipInstance</li> <li>L2BoatInstance</li> <li>L2DoorInstance</li> <li>L2PcInstance</li> <li>L2StaticObjectInstance</li> <li>L2Decoy</li> <li>L2Npc</li> <li>L2Summon</li> <li>L2Trap</li> <li>L2ItemInstance</li>
*/
public void sendInfo(L2PcInstance activeChar)
{
}
@Override
public String toString()
{
return (getClass().getSimpleName() + ":" + getName() + "[" + getObjectId() + "]");
}
/**
* Not Implemented.<BR>
* <BR>
* <B><U> Overridden in </U> :</B><BR>
* <BR>
* <li>L2PcInstance</li><BR>
* <BR>
*/
public void sendPacket(L2GameServerPacket mov)
{
// default implementation
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,170 @@
/*
* 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.l2jserver.gameserver.model;
import gnu.trove.TIntObjectHashMap;
import java.util.ArrayList;
import java.util.List;
import com.l2jserver.gameserver.datatables.SkillTable;
/**
* Class hold information about basic pet stats which are same on each level
* @author JIV
*/
public class L2PetData
{
private final TIntObjectHashMap<L2PetLevelData> _levelStats = new TIntObjectHashMap<>();
private final List<L2PetSkillLearn> _skills = new ArrayList<>();
private int _load = 20000;
private int _hungry_limit = 1;
private int _minlvl = Byte.MAX_VALUE;
private int[] _food = {};
public void addNewStat(L2PetLevelData data, int level)
{
if (_minlvl > level)
{
_minlvl = level;
}
_levelStats.put(level, data);
}
public L2PetLevelData getPetLevelData(int petLevel)
{
return _levelStats.get(petLevel);
}
public int getLoad()
{
return _load;
}
public int getHungry_limit()
{
return _hungry_limit;
}
public int getMinLevel()
{
return _minlvl;
}
public int[] getFood()
{
return _food;
}
public void set_load(int _load)
{
this._load = _load;
}
public void set_hungry_limit(int _hungry_limit)
{
this._hungry_limit = _hungry_limit;
}
public void set_food(int[] _food)
{
this._food = _food;
}
// SKILS
public void addNewSkill(int id, int lvl, int petLvl)
{
_skills.add(new L2PetSkillLearn(id, lvl, petLvl));
}
public int getAvailableLevel(int skillId, int petLvl)
{
int lvl = 0;
for (L2PetSkillLearn temp : _skills)
{
if (temp.getId() != skillId)
{
continue;
}
if (temp.getLevel() == 0)
{
if (petLvl < 70)
{
lvl = (petLvl / 10);
if (lvl <= 0)
{
lvl = 1;
}
}
else
{
lvl = (7 + ((petLvl - 70) / 5));
}
// formula usable for skill that have 10 or more skill levels
int maxLvl = SkillTable.getInstance().getMaxLevel(temp.getId());
if (lvl > maxLvl)
{
lvl = maxLvl;
}
break;
}
else if (temp.getMinLevel() <= petLvl)
{
if (temp.getLevel() > lvl)
{
lvl = temp.getLevel();
}
}
}
return lvl;
}
public List<L2PetSkillLearn> getAvailableSkills()
{
return _skills;
}
public static final class L2PetSkillLearn
{
private final int _id;
private final int _level;
private final int _minLevel;
public L2PetSkillLearn(int id, int lvl, int minLvl)
{
_id = id;
_level = lvl;
_minLevel = minLvl;
}
public int getId()
{
return _id;
}
public int getLevel()
{
return _level;
}
public int getMinLevel()
{
return _minLevel;
}
}
}
@@ -0,0 +1,212 @@
/*
* 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.l2jserver.gameserver.model;
/**
* Stats definition for each pet level
* @author JIV
*/
public class L2PetLevelData
{
private int _ownerExpTaken;
private long _petMaxExp;
private float _petMaxHP;
private float _petMaxMP;
private float _petPAtk;
private float _petPDef;
private float _petMAtk;
private float _petMDef;
private int _petMaxFeed;
private int _petFeedBattle;
private int _petFeedNormal;
private float _petRegenHP;
private float _petRegenMP;
private short _petSoulShot;
private short _petSpiritShot;
// Max Exp
public long getPetMaxExp()
{
return _petMaxExp;
}
public void setPetMaxExp(long pPetMaxExp)
{
_petMaxExp = pPetMaxExp;
}
public int getOwnerExpTaken()
{
return _ownerExpTaken;
}
public void setOwnerExpTaken(int pOwnerExpTaken)
{
_ownerExpTaken = pOwnerExpTaken;
}
// Max HP
public float getPetMaxHP()
{
return _petMaxHP;
}
public void setPetMaxHP(float pPetMaxHP)
{
_petMaxHP = pPetMaxHP;
}
// Max Mp
public float getPetMaxMP()
{
return _petMaxMP;
}
public void setPetMaxMP(float pPetMaxMP)
{
_petMaxMP = pPetMaxMP;
}
// PAtk
public float getPetPAtk()
{
return _petPAtk;
}
public void setPetPAtk(float pPetPAtk)
{
_petPAtk = pPetPAtk;
}
// PDef
public float getPetPDef()
{
return _petPDef;
}
public void setPetPDef(float pPetPDef)
{
_petPDef = pPetPDef;
}
// MAtk
public float getPetMAtk()
{
return _petMAtk;
}
public void setPetMAtk(float pPetMAtk)
{
_petMAtk = pPetMAtk;
}
// MDef
public float getPetMDef()
{
return _petMDef;
}
public void setPetMDef(float pPetMDef)
{
_petMDef = pPetMDef;
}
// 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;
}
// Regen HP
public float getPetRegenHP()
{
return _petRegenHP;
}
public void setPetRegenHP(float pPetRegenHP)
{
_petRegenHP = pPetRegenHP;
}
// Regen MP
public float getPetRegenMP()
{
return _petRegenMP;
}
public void setPetRegenMP(float pPetRegenMP)
{
_petRegenMP = pPetRegenMP;
}
/**
* @return the _petSoulShot
*/
public short getPetSoulShot()
{
return _petSoulShot;
}
/**
* @param soulShot the _petSoulShot to set
*/
public void setPetSoulShot(short soulShot)
{
_petSoulShot = soulShot;
}
/**
* @return the _petSpiritShot
*/
public short getPetSpiritShot()
{
return _petSpiritShot;
}
/**
* @param spiritShot the _petSpiritShot to set
*/
public void setPetSpiritShot(short spiritShot)
{
_petSpiritShot = spiritShot;
}
}
@@ -0,0 +1,52 @@
/*
* 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.l2jserver.gameserver.model;
/**
** @author Gnacik
*/
public class L2PremiumItem
{
private final int _itemId;
private long _count;
private final String _sender;
public L2PremiumItem(int itemid, long count, String sender)
{
_itemId = itemid;
_count = count;
_sender = sender;
}
public void updateCount(long newcount)
{
_count = newcount;
}
public int getItemId()
{
return _itemId;
}
public long getCount()
{
return _count;
}
public String getSender()
{
return _sender;
}
}
@@ -0,0 +1,148 @@
/*
* 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.l2jserver.gameserver.model;
import javolution.util.FastList;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.network.serverpackets.RadarControl;
/**
* @author dalrond
*/
public final class L2Radar
{
private final L2PcInstance _player;
private final FastList<RadarMarker> _markers;
public L2Radar(L2PcInstance player)
{
_player = player;
_markers = new FastList<>();
}
// Add a marker to player's radar
public void addMarker(int x, int y, int z)
{
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)
{
RadarMarker newMarker = new RadarMarker(x, y, z);
_markers.remove(newMarker);
_player.sendPacket(new RadarControl(1, 1, x, y, z));
}
public void removeAllMarkers()
{
for (RadarMarker tempMarker : _markers)
{
_player.sendPacket(new RadarControl(2, 2, tempMarker._x, tempMarker._y, tempMarker._z));
}
_markers.clear();
}
public void loadMarkers()
{
_player.sendPacket(new RadarControl(2, 2, _player.getX(), _player.getY(), _player.getZ()));
for (RadarMarker tempMarker : _markers)
{
_player.sendPacket(new RadarControl(0, 1, tempMarker._x, tempMarker._y, tempMarker._z));
}
}
public static 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;
}
/**
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = (prime * result) + _type;
result = (prime * result) + _x;
result = (prime * result) + _y;
result = (prime * result) + _z;
return result;
}
/**
* @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 (!(obj instanceof RadarMarker))
{
return false;
}
final RadarMarker other = (RadarMarker) obj;
if (_type != other._type)
{
return false;
}
if (_x != other._x)
{
return false;
}
if (_y != other._y)
{
return false;
}
if (_z != other._z)
{
return false;
}
return true;
}
}
}
@@ -0,0 +1,57 @@
/*
* 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.l2jserver.gameserver.model;
/**
* This class describes a RecipeList componant (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>
*/
public L2RecipeInstance(int itemId, int quantity)
{
_itemId = itemId;
_quantity = quantity;
}
/**
* Return the Identifier of the L2RecipeInstance Item needed.<BR>
* <BR>
*/
public int getItemId()
{
return _itemId;
}
/**
* Return the Item quantity needed of the L2RecipeInstance.<BR>
* <BR>
*/
public int getQuantity()
{
return _quantity;
}
}
@@ -0,0 +1,268 @@
/*
* 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.l2jserver.gameserver.model;
import com.l2jserver.gameserver.templates.StatsSet;
/**
* 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 table containing all L2RecipeStatInstance for the statUse parameter of the L2RecipeList */
private L2RecipeStatInstance[] _statUse;
/** The table containing all L2RecipeStatInstance for the altStatChange parameter of the L2RecipeList */
private L2RecipeStatInstance[] _altStatChange;
/** 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 success rate when using the L2RecipeList */
private final int _successRate;
/** 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;
/** The Identifier of the Rare Item crafted with this L2RecipeList */
private int _rareItemId;
/** The quantity of Rare Item crafted when using this L2RecipeList */
private int _rareCount;
/** The chance of Rare Item crafted when using this L2RecipeList */
private int _rarity;
/** If this a common or a dwarven recipe */
private final boolean _isDwarvenRecipe;
/**
* Constructor of L2RecipeList (create a new Recipe).<BR>
* <BR>
*/
public L2RecipeList(StatsSet set, boolean haveRare)
{
_recipes = new L2RecipeInstance[0];
_statUse = new L2RecipeStatInstance[0];
_altStatChange = new L2RecipeStatInstance[0];
_id = set.getInteger("id");
_level = set.getInteger("craftLevel");
_recipeId = set.getInteger("recipeId");
_recipeName = set.getString("recipeName");
_successRate = set.getInteger("successRate");
_itemId = set.getInteger("itemId");
_count = set.getInteger("count");
if (haveRare)
{
_rareItemId = set.getInteger("rareItemId");
_rareCount = set.getInteger("rareCount");
_rarity = set.getInteger("rarity");
}
_isDwarvenRecipe = set.getBool("isDwarvenRecipe");
}
/**
* Add a L2RecipeInstance to the L2RecipeList (add a line Item-Quantity needed to the Recipe).<BR>
* <BR>
*/
public void addRecipe(L2RecipeInstance recipe)
{
int len = _recipes.length;
L2RecipeInstance[] tmp = new L2RecipeInstance[len + 1];
System.arraycopy(_recipes, 0, tmp, 0, len);
tmp[len] = recipe;
_recipes = tmp;
}
/**
* Add a L2RecipeStatInstance of the statUse parameter to the L2RecipeList.<BR>
* <BR>
*/
public void addStatUse(L2RecipeStatInstance statUse)
{
int len = _statUse.length;
L2RecipeStatInstance[] tmp = new L2RecipeStatInstance[len + 1];
System.arraycopy(_statUse, 0, tmp, 0, len);
tmp[len] = statUse;
_statUse = tmp;
}
/**
* Add a L2RecipeStatInstance of the altStatChange parameter to the L2RecipeList.<BR>
* <BR>
*/
public void addAltStatChange(L2RecipeStatInstance statChange)
{
int len = _altStatChange.length;
L2RecipeStatInstance[] tmp = new L2RecipeStatInstance[len + 1];
System.arraycopy(_altStatChange, 0, tmp, 0, len);
tmp[len] = statChange;
_altStatChange = tmp;
}
/**
* Return the Identifier of the Instance.<BR>
* <BR>
*/
public int getId()
{
return _id;
}
/**
* Return the crafting level needed to use this L2RecipeList.<BR>
* <BR>
*/
public int getLevel()
{
return _level;
}
/**
* Return the Identifier of the L2RecipeList.<BR>
* <BR>
*/
public int getRecipeId()
{
return _recipeId;
}
/**
* Return the name of the L2RecipeList.<BR>
* <BR>
*/
public String getRecipeName()
{
return _recipeName;
}
/**
* Return the crafting success rate when using the L2RecipeList.<BR>
* <BR>
*/
public int getSuccessRate()
{
return _successRate;
}
/**
* Return rue if the Item crafted with this L2RecipeList is consumable (shot, arrow,...).<BR>
* <BR>
*/
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>
*/
public int getItemId()
{
return _itemId;
}
/**
* Return the quantity of Item crafted when using this L2RecipeList.<BR>
* <BR>
*/
public int getCount()
{
return _count;
}
/**
* Return the Identifier of the Rare Item crafted with this L2RecipeList.<BR>
* <BR>
*/
public int getRareItemId()
{
return _rareItemId;
}
/**
* Return the quantity of Rare Item crafted when using this L2RecipeList.<BR>
* <BR>
*/
public int getRareCount()
{
return _rareCount;
}
/**
* Return the chance of Rare Item crafted when using this L2RecipeList.<BR>
* <BR>
*/
public int getRarity()
{
return _rarity;
}
/**
* Return <B>true</B> if this a Dwarven recipe or <B>false</B> if its a Common recipe
*/
public boolean isDwarvenRecipe()
{
return _isDwarvenRecipe;
}
/**
* Return the table containing all L2RecipeInstance (1 line of the recipe : Item-Quantity needed) of the L2RecipeList.<BR>
* <BR>
*/
public L2RecipeInstance[] getRecipes()
{
return _recipes;
}
/**
* Return the table containing all L2RecipeStatInstance of the statUse parameter of the L2RecipeList.<BR>
* <BR>
*/
public L2RecipeStatInstance[] getStatUse()
{
return _statUse;
}
/**
* Return the table containing all L2RecipeStatInstance of the AltStatChange parameter of the L2RecipeList.<BR>
* <BR>
*/
public L2RecipeStatInstance[] getAltStatChange()
{
return _altStatChange;
}
}
@@ -0,0 +1,76 @@
/*
* 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.l2jserver.gameserver.model;
/**
* This class describes a RecipeList statUse and altStatChange component.<BR>
* <BR>
*/
public class L2RecipeStatInstance
{
public static enum StatType
{
HP,
MP,
XP,
SP,
GIM // grab item modifier:
// GIM: the default function uses only the skilllevel to determine
// how many item is grabbed in each step
// with this stat changer you can multiple this
}
/** The Identifier of the statType */
private StatType _type;
/** The value of the statType */
private final int _value;
/**
* Constructor of L2RecipeStatInstance.<BR>
* <BR>
*/
public L2RecipeStatInstance(String type, int value)
{
try
{
_type = Enum.valueOf(StatType.class, type);
}
catch (Exception e)
{
throw new IllegalArgumentException();
}
_value = value;
}
/**
* Return the the type of the L2RecipeStatInstance.<BR>
* <BR>
*/
public StatType getType()
{
return _type;
}
/**
* Return the value of the L2RecipeStatInstance.<BR>
* <BR>
*/
public int getValue()
{
return _value;
}
}
@@ -0,0 +1,149 @@
/*
* 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.l2jserver.gameserver.model;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.clientpackets.L2GameClientPacket;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
/**
* This class manages requests (transactions) between two L2PcInstance.
* @author kriau
*/
public class L2Request
{
private static final int REQUEST_TIMEOUT = 15; // in secs
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>
*/
private synchronized void setPartner(L2PcInstance partner)
{
_partner = partner;
}
/**
* Return the L2PcInstance member of a transaction (ex : FriendInvite, JoinAlly, JoinParty...).<BR>
* <BR>
*/
public L2PcInstance getPartner()
{
return _partner;
}
/**
* Set the packet incomed from requestor.<BR>
* <BR>
*/
private synchronized void setRequestPacket(L2GameClientPacket packet)
{
_requestPacket = packet;
}
/**
* Return the packet originally incomed from requestor.<BR>
* <BR>
*/
public L2GameClientPacket getRequestPacket()
{
return _requestPacket;
}
/**
* Checks if request can be made and in success case puts both PC on request state.<BR>
* <BR>
*/
public synchronized boolean setRequest(L2PcInstance partner, L2GameClientPacket packet)
{
if (partner == null)
{
_player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_INVITED_THE_WRONG_TARGET));
return false;
}
if (partner.getRequest().isProcessingRequest())
{
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_IS_BUSY_TRY_LATER);
sm.addString(partner.getName());
_player.sendPacket(sm);
sm = null;
return false;
}
if (isProcessingRequest())
{
_player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.WAITING_FOR_ANOTHER_REPLY));
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>
*/
public boolean isProcessingRequest()
{
return _partner != null;
}
}
@@ -0,0 +1,87 @@
/*
* 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.l2jserver.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;
public final static int TYPE_TPBOOKMARK = 6;
private final int _slot;
private final int _page;
private final int _type;
private final int _id;
private final int _level;
private final int _characterType;
private int _sharedReuseGroup = -1;
public L2ShortCut(int slotId, int pageId, int shortcutType, int shortcutId, int shortcutLevel, int characterType)
{
_slot = slotId;
_page = pageId;
_type = shortcutType;
_id = shortcutId;
_level = shortcutLevel;
_characterType = characterType;
}
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;
}
public int getCharacterType()
{
return _characterType;
}
public int getSharedReuseGroup()
{
return _sharedReuseGroup;
}
public void setSharedReuseGroup(int g)
{
_sharedReuseGroup = g;
}
}
@@ -0,0 +1,120 @@
/*
* 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.l2jserver.gameserver.model;
import java.util.List;
import javolution.util.FastList;
import com.l2jserver.gameserver.model.actor.L2Npc;
public class L2SiegeClan
{
// ==========================================================================================
// Instance
// ===============================================================
// Data Field
private int _clanId = 0;
private List<L2Npc> _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(L2Npc flag)
{
_numFlagsAdded++;
getFlag().add(flag);
}
public boolean removeFlag(L2Npc flag)
{
if (flag == null)
{
return false;
}
boolean ret = getFlag().remove(flag);
// check if null objects or duplicates remain in the list.
// for some reason, this might be happening sometimes...
// delete false duplicates: if this flag got deleted, delete its copies too.
if (ret)
{
while (getFlag().remove(flag))
{
}
}
flag.deleteMe();
_numFlagsAdded--;
return ret;
}
public void removeFlags()
{
for (L2Npc flag : getFlag())
{
removeFlag(flag);
}
}
// =========================================================
// Property
public final int getClanId()
{
return _clanId;
}
public final List<L2Npc> 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
@@ -0,0 +1,301 @@
/*
* 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.l2jserver.gameserver.model;
import java.util.logging.Logger;
import com.l2jserver.Config;
import com.l2jserver.gameserver.model.base.ClassId;
import com.l2jserver.gameserver.model.base.Race;
import com.l2jserver.gameserver.templates.StatsSet;
/**
* @author Zoey76
*/
public final class L2SkillLearn
{
private static final Logger _log = Logger.getLogger(L2SkillLearn.class.getName());
private final String _skillName;
private final int _skillId;
private final int _skillLvl;
private final int _getLevel;
private final boolean _autoGet;
private final int _levelUpSp;
private final int[][] _itemsIdCount;
private final Race[] _races;
private final int[] _preReqSkillIdLvl;
private final int _socialClass;
private final boolean _residenceSkill;
private final int[] _residenceIds;
private final int[][] _subClassLvlNumber;
private final boolean _learnedByNpc;
private final boolean _learnedByFS;
/**
* Constructor for L2SkillLearn.
* @param set the set with the L2SkillLearn data.
*/
public L2SkillLearn(StatsSet set)
{
_skillName = set.getString("skillName");
_skillId = set.getInteger("skillId");
_skillLvl = set.getInteger("skillLvl");
_getLevel = set.getInteger("getLevel");
_autoGet = set.getBool("autoGet", false);
_levelUpSp = set.getInteger("levelUpSp", 0);
if (!set.getString("itemsIdCount", "").isEmpty())
{
final String[] items = set.getString("itemsIdCount").split(";");
_itemsIdCount = new int[items.length][2];
int i = 0;
for (String itemIdCount : items)
{
try
{
_itemsIdCount[i][0] = Integer.parseInt(itemIdCount.split(",")[0]);// Id
_itemsIdCount[i][1] = Integer.parseInt(itemIdCount.split(",")[1]);// Count
i++;
}
catch (Exception e)
{
_log.severe(getClass().getSimpleName() + ": Malformed itemsIdCount for Learn Skill Id " + _skillId + " and level " + _skillLvl + "!");
}
}
}
else
{
_itemsIdCount = null;
}
if (!set.getString("race", "").isEmpty())
{
final int[] allowedRaces = set.getIntegerArray("race");
final int totalRaces = allowedRaces.length;
_races = new Race[totalRaces];
for (int i = 0; i < totalRaces; i++)
{
_races[i] = Race.values()[allowedRaces[i]];
}
}
else
{
_races = null;
}
if (!set.getString("preReqSkillIdLvl", "").isEmpty())
{
_preReqSkillIdLvl = new int[2];
try
{
_preReqSkillIdLvl[0] = Integer.parseInt(set.getString("preReqSkillIdLvl").split(",")[0]);
_preReqSkillIdLvl[1] = Integer.parseInt(set.getString("preReqSkillIdLvl").split(",")[1]);
}
catch (Exception e)
{
_log.severe(getClass().getSimpleName() + ": Malformed preReqSkillIdLvl for Learn Skill Id " + _skillId + " and level " + _skillLvl + "!");
}
}
else
{
_preReqSkillIdLvl = null;
}
_socialClass = set.getInteger("socialClass", 0);
_residenceSkill = set.getBool("residenceSkill", false);
if (!set.getString("residenceIds", "").isEmpty())
{
_residenceIds = set.getIntegerArray("residenceIds");
}
else
{
_residenceIds = null;
}
if (!set.getString("subClassLvlNumber", "").isEmpty())
{
final String[] subLvLNumList = set.getString("subClassLvlNumber").split(";");
_subClassLvlNumber = new int[subLvLNumList.length][2];
int i = 0;
for (String subLvlNum : subLvLNumList)
{
try
{
_subClassLvlNumber[i][0] = Integer.parseInt(subLvlNum.split(",")[0]);
_subClassLvlNumber[i][1] = Integer.parseInt(subLvlNum.split(",")[1]);
i++;
}
catch (Exception e)
{
_log.severe(getClass().getSimpleName() + ": Malformed subClassLvlNumber for Learn Skill Id " + _skillId + " and level " + _skillLvl + "!");
}
}
}
else
{
_subClassLvlNumber = null;
}
_learnedByNpc = set.getBool("learnedByNpc", false);
_learnedByFS = set.getBool("learnedByFS", false);
}
/**
* @return the name of this skill.
*/
public String getName()
{
return _skillName;
}
/**
* @return the ID of this skill.
*/
public int getSkillId()
{
return _skillId;
}
/**
* @return the level of this skill.
*/
public int getSkillLevel()
{
return _skillLvl;
}
/**
* @return the minimum level required to acquire this skill.
*/
public int getGetLevel()
{
return _getLevel;
}
/**
* @return the amount of SP/Clan Reputation to acquire this skill.
*/
public int getLevelUpSp()
{
return _levelUpSp;
}
/**
* @return {@code true} if the skill is auto-get, this skill is automatically delivered.
*/
public boolean isAutoGet()
{
return _autoGet;
}
/**
* @return the multidimensional array with the item IDs and amounts required to acquire this skill.
*/
public int[][] getItemsIdCount()
{
return _itemsIdCount;
}
/**
* @return the array with the races that can acquire this skill.
*/
public Race[] getRaces()
{
return _races;
}
/**
* @return the array with required skill IDs and levels to acquire this skill.
*/
public int[] getPreReqSkillIdLvl()
{
return _preReqSkillIdLvl;
}
/**
* @return the social class required to get this skill.
*/
public int getSocialClass()
{
return _socialClass;
}
/**
* @return {@code true} if this skill is a Residence skill.
*/
public boolean isResidencialSkill()
{
return _residenceSkill;
}
/**
* @return the array with the IDs where this skill is available.
*/
public int[] getRecidenceIds()
{
return _residenceIds;
}
/**
* @return the array with Sub-Class conditions, amount of subclasses and level.
*/
public int[][] getSubClassConditions()
{
return _subClassLvlNumber;
}
/**
* @return {@code true} if this skill is learned from Npc.
*/
public boolean isLearnedByNpc()
{
return _learnedByNpc;
}
/**
* @return {@code true} if this skill is learned by Forgotten Scroll.
*/
public boolean isLearnedByFS()
{
return _learnedByFS;
}
/**
* Used for AltGameSkillLearn mod.<br>
* If the alternative skill learn system is enabled and the player is learning a skill from a different class apply a fee.<br>
* If the player is learning a skill from other class type (mage learning warrior skills or vice versa) the fee is higher.
* @param playerClass the player class Id.
* @param learningClass the skill learning player class Id.
* @return the amount of SP required to acquire this skill, by calculating the cost for the alternative skill learn system.
*/
public int getCalculatedLevelUpSp(ClassId playerClass, ClassId learningClass)
{
if ((playerClass == null) || (learningClass == null))
{
return _levelUpSp;
}
int levelUpSp = _levelUpSp;
// If the alternative skill learn system is enabled and the player is learning a skill from a different class apply a fee.
if (Config.ALT_GAME_SKILL_LEARN && (playerClass != learningClass))
{
// If the player is learning a skill from other class type (mage learning warrior skills or vice versa) the fee is higher.
if (playerClass.isMage() != learningClass.isMage())
{
levelUpSp *= 3;
}
else
{
levelUpSp *= 2;
}
}
return levelUpSp;
}
}
@@ -0,0 +1,676 @@
/*
* 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.l2jserver.gameserver.model;
import java.lang.reflect.Constructor;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javolution.util.FastList;
import com.l2jserver.Config;
import com.l2jserver.gameserver.GeoData;
import com.l2jserver.gameserver.Territory;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.idfactory.IdFactory;
import com.l2jserver.gameserver.model.actor.L2Attackable;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
import com.l2jserver.gameserver.templates.chars.L2NpcTemplate;
import com.l2jserver.util.Rnd;
/**
* 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 final 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;
// 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 spwan point */
private int _locX;
/** The Y position of the spwan point */
private int _locY;
/** The Z position of the spwan 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;
private int _instanceId = 0;
/** The generic constructor of L2NpcInstance managed by this L2Spawn */
private Constructor<?> _constructor;
/** If True a L2NpcInstance is respawned each time that another is killed */
private boolean _doRespawn;
/** If true then spawn is custom */
private boolean _customSpawn;
private L2Npc _lastSpawn;
private static List<SpawnListener> _spawnListeners = new FastList<>();
/** The task launching the function doSpawn() */
class SpawnTask implements Runnable
{
// L2NpcInstance _instance;
// int _objId;
private final L2Npc _oldNpc;
public SpawnTask(/* int objid */L2Npc pOldNpc)
{
// _objId= objid;
_oldNpc = pOldNpc;
}
@Override
public void run()
{
try
{
// doSpawn();
respawnNpc(_oldNpc);
}
catch (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
*/
public L2Spawn(L2NpcTemplate mobTemplate) throws SecurityException, ClassNotFoundException, NoSuchMethodException
{
// Set the _template of the L2Spawn
_template = mobTemplate;
if (_template == null)
{
return;
}
// Create the generic constructor of L2NpcInstance managed by this L2Spawn
Class<?>[] parameters =
{
int.class,
Class.forName("com.l2jserver.gameserver.templates.chars.L2NpcTemplate")
};
_constructor = Class.forName("com.l2jserver.gameserver.model.actor.instance." + _template.type + "Instance").getConstructor(parameters);
}
/**
* Return the maximum number of L2NpcInstance that this L2Spawn can manage.<BR>
* <BR>
*/
public int getAmount()
{
return _maximumCount;
}
/**
* Return the Identifier of the location area where L2NpcInstance can be spwaned.<BR>
* <BR>
*/
public int getLocation()
{
return _location;
}
/**
* Return the X position of the spwan point.<BR>
* <BR>
*/
public int getLocx()
{
return _locX;
}
/**
* Return the Y position of the spwan point.<BR>
* <BR>
*/
public int getLocy()
{
return _locY;
}
/**
* Return the Z position of the spwan point.<BR>
* <BR>
*/
public int getLocz()
{
return _locZ;
}
/**
* Return the Itdentifier of the L2NpcInstance manage by this L2Spwan contained in the L2NpcTemplate.<BR>
* <BR>
*/
public int getNpcid()
{
return _template.npcId;
}
/**
* Return the heading of L2NpcInstance when they are spawned.<BR>
* <BR>
*/
public int getHeading()
{
return _heading;
}
/**
* Return the delay between a L2NpcInstance remove and its re-spawn.<BR>
* <BR>
*/
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>
*/
public void setAmount(int amount)
{
_maximumCount = amount;
}
/**
* Set the Identifier of the location area where L2NpcInstance can be spwaned.<BR>
* <BR>
*/
public void setLocation(int location)
{
_location = location;
}
/**
* Set Minimum Respawn Delay.<BR>
* <BR>
*/
public void setRespawnMinDelay(int date)
{
_respawnMinDelay = date;
}
/**
* Set Maximum Respawn Delay.<BR>
* <BR>
*/
public void setRespawnMaxDelay(int date)
{
_respawnMaxDelay = date;
}
/**
* Set the X position of the spwan point.<BR>
* <BR>
*/
public void setLocx(int locx)
{
_locX = locx;
}
/**
* Set the Y position of the spwan point.<BR>
* <BR>
*/
public void setLocy(int locy)
{
_locY = locy;
}
/**
* Set the Z position of the spwan point.<BR>
* <BR>
*/
public void setLocz(int locz)
{
_locZ = locz;
}
/**
* Set the heading of L2NpcInstance when they are spawned.<BR>
* <BR>
*/
public void setHeading(int heading)
{
_heading = heading;
}
/**
* Set the spawn as custom.<BR>
*/
public void setCustom(boolean custom)
{
_customSpawn = custom;
}
/**
* Return type of spawn.<BR>
* <BR>
*/
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>
*/
public void decreaseCount(/* int npcId */L2Npc 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>
*/
public L2Npc spawnOne(boolean val)
{
return doSpawn(val);
}
/**
* Return true if respawn enabled
*/
public boolean isRespawnEnabled()
{
return _doRespawn;
}
/**
* 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;
}
public L2Npc doSpawn()
{
return doSpawn(false);
}
/**
* 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>
*/
public L2Npc doSpawn(boolean isSummonSpawn)
{
L2Npc mob = null;
try
{
// Check if the L2Spawn is not a L2Pet or L2Minion or L2Decoy spawn
if (_template.type.equalsIgnoreCase("L2Pet") || _template.type.equalsIgnoreCase("L2Decoy") || _template.type.equalsIgnoreCase("L2Trap") || _template.type.equalsIgnoreCase("L2EffectPoint"))
{
_currentCount++;
return mob;
}
// Get L2NpcInstance Init parameters and its generate an Identifier
Object[] parameters =
{
IdFactory.getInstance().getNextId(),
_template
};
// Call the constructor of the L2NpcInstance
// (can be a L2ArtefactInstance, L2FriendlyMobInstance, L2GuardInstance, L2MonsterInstance, L2SiegeGuardInstance, L2BoxInstance,
// L2FeedableBeastInstance, L2TamedBeastInstance, L2FolkInstance or L2TvTEventNpcInstance)
Object tmp = _constructor.newInstance(parameters);
((L2Object) tmp).setInstanceId(_instanceId); // Must be done before object is spawned into visible world
if (isSummonSpawn && (tmp instanceof L2Character))
{
((L2Character) tmp).setShowSummonAnimation(isSummonSpawn);
}
// Check if the Instance is a L2NpcInstance
if (!(tmp instanceof L2Npc))
{
return mob;
}
mob = (L2Npc) tmp;
return initializeNpcInstance(mob);
}
catch (Exception e)
{
_log.log(Level.WARNING, "NPC " + _template.npcId + " class not found", e);
}
return mob;
}
/**
* @param mob
* @return
*/
private L2Npc initializeNpcInstance(L2Npc mob)
{
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
int p[] = Territory.getInstance().getRandomPoint(getLocation());
// Set the calculated position of the L2NpcInstance
newlocx = p[0];
newlocy = p[1];
newlocz = GeoData.getInstance().getSpawnHeight(newlocx, newlocy, p[2], p[3], this);
}
else
{
// The L2NpcInstance is spawned at the exact position (Lox, Locy, Locz)
newlocx = getLocx();
newlocy = getLocy();
if (Config.GEODATA > 0)
{
newlocz = GeoData.getInstance().getSpawnHeight(newlocx, newlocy, getLocz(), getLocz(), this);
}
else
{
newlocz = getLocz();
}
}
mob.stopAllEffects();
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());
}
if (mob instanceof L2Attackable)
{
((L2Attackable) mob).setChampion(false);
}
if (Config.L2JMOD_CHAMPION_ENABLE)
{
// Set champion on next spawn
if ((mob instanceof L2MonsterInstance) && !getTemplate().isQuestMonster && !mob.isRaid() && !((L2MonsterInstance) mob).isRaidMinion() && (Config.L2JMOD_CHAMPION_FREQUENCY > 0) && (mob.getLevel() >= Config.L2JMOD_CHAMP_MIN_LVL) && (mob.getLevel() <= Config.L2JMOD_CHAMP_MAX_LVL) && (Config.L2JMOD_CHAMPION_ENABLE_IN_INSTANCES || (getInstanceId() == 0)))
{
int random = Rnd.get(100);
if (random < Config.L2JMOD_CHAMPION_FREQUENCY)
{
((L2Attackable) 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(L2Npc npc)
{
synchronized (_spawnListeners)
{
for (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 spawn:" + this);
}
if (i < 10)
{
i = 10;
}
_respawnDelay = i * 1000;
}
public L2Npc getLastSpawn()
{
return _lastSpawn;
}
/**
* @param oldNpc
*/
public void respawnNpc(L2Npc oldNpc)
{
if (_doRespawn)
{
oldNpc.refreshID();
/* L2NpcInstance instance = */initializeNpcInstance(oldNpc);
}
}
public L2NpcTemplate getTemplate()
{
return _template;
}
public int getInstanceId()
{
return _instanceId;
}
public void setInstanceId(int instanceId)
{
_instanceId = instanceId;
}
/*
* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString()
{
return "L2Spawn [_template=" + getNpcid() + ", _locX=" + _locX + ", _locY=" + _locY + ", _locZ=" + _locZ + ", _heading=" + _heading + "]";
}
}
@@ -0,0 +1,25 @@
/*
* 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.l2jserver.gameserver.model;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
/**
* @author JIV
*/
public interface L2SquadTrainer
{
public void showSubUnitSkillList(L2PcInstance player);
}
@@ -0,0 +1,59 @@
/*
* 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.l2jserver.gameserver.model;
/**
* @author -Nemesiss-
*/
public class L2SummonItem
{
private final int _itemId;
private final int _npcId;
private final byte _type;
private final int _despawnDelay;
public L2SummonItem(int itemId, int npcId, byte type, int despawnDelay)
{
_itemId = itemId;
_npcId = npcId;
_type = type;
_despawnDelay = despawnDelay;
}
public int getItemId()
{
return _itemId;
}
public int getNpcId()
{
return _npcId;
}
public byte getType()
{
return _type;
}
public boolean isPetSummon()
{
return (_type == 1) || (_type == 2);
}
public int getDespawnDelay()
{
return _despawnDelay;
}
}
@@ -0,0 +1,142 @@
/*
* 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.l2jserver.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;
private int _itemId;
/**
* @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;
}
/**
* @param val
*/
public void setItemId(int val)
{
_itemId = 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;
}
/**
* @return
*/
public int getItemId()
{
return _itemId;
}
}
@@ -0,0 +1,208 @@
/*
* 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/>.
*/
/**
coded by Balancer
balancer@balancer.ru
http://balancer.ru
version 0.1, 2005-03-12
*/
package com.l2jserver.gameserver.model;
import java.util.List;
import java.util.logging.Logger;
import javolution.util.FastList;
import com.l2jserver.util.Rnd;
public class L2Territory
{
private static Logger _log = Logger.getLogger(L2Territory.class.getName());
protected static 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 _xMin;
private int _xMax;
private int _yMin;
private int _yMax;
private int _zMin;
private int _zMax;
private int _procMax;
public L2Territory(int terr)
{
_points = new FastList<>();
_terr = terr;
_xMin = 999999;
_xMax = -999999;
_yMin = 999999;
_yMax = -999999;
_zMin = 999999;
_zMax = -999999;
_procMax = 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 < _xMin)
{
_xMin = x;
}
if (y < _yMin)
{
_yMin = y;
}
if (x > _xMax)
{
_xMax = x;
}
if (y > _yMax)
{
_yMax = y;
}
if (zmin < _zMin)
{
_zMin = zmin;
}
if (zmax > _zMax)
{
_zMax = zmax;
}
_procMax += proc;
}
public void print()
{
for (Point p : _points)
{
_log.info("(" + p._x + "," + p._y + ")");
}
}
public boolean isIntersect(int x, int y, Point p1, Point p2)
{
double dy1 = p1._y - y;
double dy2 = p2._y - y;
if (Math.signum(dy1) == Math.signum(dy2))
{
return false;
}
double dx1 = p1._x - x;
double dx2 = p2._x - x;
if ((dx1 >= 0) && (dx2 >= 0))
{
return true;
}
if ((dx1 < 0) && (dx2 < 0))
{
return false;
}
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++)
{
Point p1 = _points.get(i > 0 ? i - 1 : _points.size() - 1);
Point p2 = _points.get(i);
if (isIntersect(x, y, p1, p2))
{
intersect_count++;
}
}
return (intersect_count % 2) == 1;
}
public int[] getRandomPoint()
{
int[] p = new int[4];
if (_procMax > 0)
{
int pos = 0;
int rnd = Rnd.nextInt(_procMax);
for (Point p1 : _points)
{
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 (int i = 0; i < 100; i++)
{
p[0] = Rnd.get(_xMin, _xMax);
p[1] = Rnd.get(_yMin, _yMax);
if (isInside(p[0], p[1]))
{
double curdistance = 0;
p[2] = _zMin + 100;
p[3] = _zMax;
for (Point p1 : _points)
{
double dx = p1._x - p[0];
double dy = p1._y - p[1];
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 _procMax;
}
}
@@ -0,0 +1,367 @@
/*
* 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.l2jserver.gameserver.model;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
import javolution.util.FastMap;
import com.l2jserver.L2DatabaseFactory;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.datatables.ItemTable;
import com.l2jserver.gameserver.templates.item.L2Item;
/**
* This class ...
* @version $Revision: 1.4.2.1.2.5 $ $Date: 2005/03/27 15:29:33 $
*/
public class L2TradeList
{
private final Map<Integer, L2TradeItem> _items;
private final int _listId;
private String _buystorename, _sellstorename;
private boolean _hasLimitedStockItem;
private String _npcId;
public L2TradeList(int listId)
{
_items = new FastMap<>();
_listId = listId;
}
public void setNpcId(String id)
{
_npcId = id;
}
public String getNpcId()
{
return _npcId;
}
public void addItem(L2TradeItem item)
{
_items.put(item.getItemId(), item);
if (item.hasLimitedStock())
{
setHasLimitedStockItem(true);
}
}
public void replaceItem(int itemID, long price)
{
L2TradeItem item = _items.get(itemID);
if (item != null)
{
item.setPrice(price);
}
}
public void removeItem(int itemID)
{
_items.remove(itemID);
}
/**
* @return Returns the listId.
*/
public int getListId()
{
return _listId;
}
/**
* @param hasLimitedStockItem The hasLimitedStockItem to set.
*/
public void setHasLimitedStockItem(boolean hasLimitedStockItem)
{
_hasLimitedStockItem = hasLimitedStockItem;
}
/**
* @return Returns the hasLimitedStockItem.
*/
public boolean hasLimitedStockItem()
{
return _hasLimitedStockItem;
}
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 Collection<L2TradeItem> getItems()
{
return _items.values();
}
public List<L2TradeItem> getItems(int start, int end)
{
List<L2TradeItem> list = new LinkedList<>();
list.addAll(_items.values());
return list.subList(start, end);
}
public long getPriceForItemId(int itemId)
{
L2TradeItem item = _items.get(itemId);
if (item != null)
{
return item.getPrice();
}
return -1;
}
public L2TradeItem getItemById(int itemId)
{
return _items.get(itemId);
}
/*
* public boolean countDecrease(int itemId) { L2TradeItem item = _items.get(itemId); if (item != null) { return item.hasLimitedStock(); } return false; }
*/
public boolean containsItemId(int itemId)
{
return _items.containsKey(itemId);
}
/**
* Itens representation for trade lists
* @author KenM
*/
public static class L2TradeItem
{
private static final Logger _log = Logger.getLogger(L2TradeItem.class.getName());
private final int _listId;
private final int _itemId;
private final L2Item _template;
private long _price;
// count related
private final AtomicLong _currentCount = new AtomicLong();
private long _maxCount = -1;
private long _restoreDelay;
private long _nextRestoreTime;
public L2TradeItem(int listId, int itemId)
{
_listId = listId;
_itemId = itemId;
_template = ItemTable.getInstance().getTemplate(itemId);
}
/**
* @return Returns the itemId.
*/
public int getItemId()
{
return _itemId;
}
/**
* @param price The price to set.
*/
public void setPrice(long price)
{
_price = price;
}
/**
* @return Returns the price.
*/
public long getPrice()
{
return _price;
}
public L2Item getTemplate()
{
return _template;
}
/**
* @param currentCount The currentCount to set.
*/
public void setCurrentCount(long currentCount)
{
_currentCount.set(currentCount);
}
public boolean decreaseCount(long val)
{
return _currentCount.addAndGet(-val) >= 0;
}
/**
* @return Returns the currentCount.
*/
public long getCurrentCount()
{
if (hasLimitedStock() && isPendingStockUpdate())
{
restoreInitialCount();
}
long ret = _currentCount.get();
return ret > 0 ? ret : 0;
}
public boolean isPendingStockUpdate()
{
return System.currentTimeMillis() >= _nextRestoreTime;
}
public void restoreInitialCount()
{
setCurrentCount(getMaxCount());
_nextRestoreTime = _nextRestoreTime + getRestoreDelay();
// consume until next update is on future
if (isPendingStockUpdate() && (getRestoreDelay() > 0))
{
_nextRestoreTime = System.currentTimeMillis() + getRestoreDelay();
}
// exec asynchronously
try
{
ThreadPoolManager.getInstance().executeTask(new TimerSave());
}
catch (RejectedExecutionException e)
{
// during shutdown executeTask() failed
saveDataTimer();
}
}
/**
* @param maxCount The maxCount to set.
*/
public void setMaxCount(long maxCount)
{
_maxCount = maxCount;
}
/**
* @return Returns the maxCount.
*/
public long getMaxCount()
{
return _maxCount;
}
public boolean hasLimitedStock()
{
return getMaxCount() > -1;
}
/**
* @param restoreDelay The restoreDelay to set (in hours)
*/
public void setRestoreDelay(long restoreDelay)
{
_restoreDelay = restoreDelay * 60 * 60 * 1000;
}
/**
* @return Returns the restoreDelay (in milis)
*/
public long getRestoreDelay()
{
return _restoreDelay;
}
/**
* For resuming when server loads
* @param nextRestoreTime The nextRestoreTime to set.
*/
public void setNextRestoreTime(long nextRestoreTime)
{
_nextRestoreTime = nextRestoreTime;
}
/**
* @return Returns the nextRestoreTime.
*/
public long getNextRestoreTime()
{
return _nextRestoreTime;
}
class TimerSave implements Runnable
{
/**
* @see java.lang.Runnable#run()
*/
@Override
public void run()
{
saveDataTimer();
}
}
protected void saveDataTimer()
{
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("UPDATE merchant_buylists SET savetimer =? WHERE shop_id =? and item_id =?");
statement.setLong(1, _nextRestoreTime);
statement.setInt(2, _listId);
statement.setInt(3, _itemId);
statement.executeUpdate();
statement.close();
}
catch (Exception e)
{
_log.log(Level.SEVERE, "L2TradeItem: Could not update Timer save in Buylist");
}
finally
{
L2DatabaseFactory.close(con);
}
}
}
}
@@ -0,0 +1,205 @@
/*
* 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.l2jserver.gameserver.model;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
/**
* @author KenM
*/
public abstract class L2Transformation implements Cloneable, Runnable
{
private final int _id;
private final int _graphicalId;
private double _collisionRadius;
private double _collisionHeight;
private final boolean _isStance;
public static final int TRANSFORM_ZARICHE = 301;
public static final int TRANSFORM_AKAMANAH = 302;
protected static final int[] EMPTY_ARRAY = {};
private L2PcInstance _player;
/**
* @param id Internal id that server will use to associate this transformation
* @param graphicalId Client visible transformation id
* @param collisionRadius Collision Radius of the player while transformed
* @param collisionHeight Collision Height of the player while transformed
*/
public L2Transformation(int id, int graphicalId, double collisionRadius, double collisionHeight)
{
_id = id;
_graphicalId = graphicalId;
_collisionRadius = collisionRadius;
_collisionHeight = collisionHeight;
_isStance = false;
}
/**
* @param id Internal id(will be used also as client graphical id) that server will use to associate this transformation
* @param collisionRadius Collision Radius of the player while transformed
* @param collisionHeight Collision Height of the player while transformed
*/
public L2Transformation(int id, double collisionRadius, double collisionHeight)
{
this(id, id, collisionRadius, collisionHeight);
}
/**
* @param id Internal id(will be used also as client graphical id) that server will use to associate this transformation Used for stances
*/
public L2Transformation(int id)
{
_id = id;
_graphicalId = id;
_isStance = true;
}
/**
* @return Returns the id.
*/
public int getId()
{
return _id;
}
/**
* @return Returns the graphicalId.
*/
public int getGraphicalId()
{
return _graphicalId;
}
/**
* Return true if this is a stance (vanguard/inquisitor)
* @return
*/
public boolean isStance()
{
return _isStance;
}
/**
* @return Returns the collisionRadius.
*/
public double getCollisionRadius()
{
if (isStance())
{
return _player.getCollisionRadius();
}
return _collisionRadius;
}
/**
* @return Returns the collisionHeight.
*/
public double getCollisionHeight()
{
if (isStance())
{
return _player.getCollisionHeight();
}
return _collisionHeight;
}
// Scriptable Events
public abstract void onTransform();
public abstract void onUntransform();
/**
* @param player The player to set.
*/
private void setPlayer(L2PcInstance player)
{
_player = player;
}
/**
* @return Returns the player.
*/
public L2PcInstance getPlayer()
{
return _player;
}
public void start()
{
resume();
}
public void resume()
{
getPlayer().transform(this);
}
@Override
public void run()
{
stop();
}
public void stop()
{
getPlayer().untransform();
}
public L2Transformation createTransformationForPlayer(L2PcInstance player)
{
try
{
L2Transformation transformation = (L2Transformation) clone();
transformation.setPlayer(player);
return transformation;
}
catch (CloneNotSupportedException e)
{
// should never happen
return null;
}
}
// Override if necessary
public void onLevelUp()
{
}
/**
* Returns true if transformation can do melee attack
*/
public boolean canDoMeleeAttack()
{
return true;
}
/**
* Returns true if transformation can start follow target when trying to cast an skill out of range
*/
public boolean canStartFollowToCast()
{
return true;
}
@Override
public String toString()
{
return getClass().getSimpleName() + " [_id=" + _id + ", _graphicalId=" + _graphicalId + ", _collisionRadius=" + _collisionRadius + ", _collisionHeight=" + _collisionHeight + ", _isStance=" + _isStance + "]";
}
}
@@ -0,0 +1,281 @@
/*
* 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.l2jserver.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.logging.Level;
import java.util.logging.Logger;
import javolution.util.FastList;
import javolution.util.FastMap;
import com.l2jserver.L2DatabaseFactory;
import com.l2jserver.gameserver.datatables.UITable;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.entity.ActionKey;
/**
* @author mrTJO
*/
public class L2UIKeysSettings
{
protected static final Logger _log = Logger.getLogger(L2UIKeysSettings.class.getName());
private final L2PcInstance _player;
Map<Integer, List<ActionKey>> _storedKeys;
Map<Integer, List<Integer>> _storedCategories;
boolean _saved = true;
public L2UIKeysSettings(L2PcInstance player)
{
_player = player;
loadFromDB();
}
public void storeAll(Map<Integer, List<Integer>> catMap, Map<Integer, List<ActionKey>> keyMap)
{
_saved = false;
_storedCategories = catMap;
_storedKeys = keyMap;
}
public void storeCategories(Map<Integer, List<Integer>> catMap)
{
_saved = false;
_storedCategories = catMap;
}
public Map<Integer, List<Integer>> getCategories()
{
return _storedCategories;
}
public void storeKeys(Map<Integer, List<ActionKey>> keyMap)
{
_saved = false;
_storedKeys = keyMap;
}
public Map<Integer, List<ActionKey>> getKeys()
{
return _storedKeys;
}
public void loadFromDB()
{
getCatsFromDB();
getKeysFromDB();
}
/**
* Save Categories and Mapped Keys into GameServer DataBase
*/
public void saveInDB()
{
String query;
int playerId = _player.getObjectId();
if (_saved)
{
return;
}
query = "REPLACE INTO character_ui_categories (`charId`, `catId`, `order`, `cmdId`) VALUES ";
for (int category : _storedCategories.keySet())
{
int order = 0;
for (int key : _storedCategories.get(category))
{
query += "(" + playerId + ", " + category + ", " + (order++) + ", " + key + "),";
}
}
query = query.substring(0, query.length() - 1) + "; ";
Connection con = null;
PreparedStatement statement;
try
{
con = L2DatabaseFactory.getInstance().getConnection();
statement = con.prepareStatement(query);
statement.execute();
statement.close();
}
catch (Exception e)
{
_log.log(Level.WARNING, "Exception: saveInDB(): " + e.getMessage(), e);
}
query = "REPLACE INTO character_ui_actions (`charId`, `cat`, `order`, `cmd`, `key`, `tgKey1`, `tgKey2`, `show`) VALUES";
for (List<ActionKey> keyLst : _storedKeys.values())
{
int order = 0;
for (ActionKey key : keyLst)
{
query += key.getSqlSaveString(playerId, order++) + ",";
}
}
query = query.substring(0, query.length() - 1) + ";";
try
{
if (con == null)
{
con = L2DatabaseFactory.getInstance().getConnection();
}
statement = con.prepareStatement(query);
statement.execute();
statement.close();
}
catch (Exception e)
{
_log.log(Level.WARNING, "Exception: saveInDB(): " + e.getMessage(), e);
}
finally
{
L2DatabaseFactory.close(con);
}
_saved = true;
}
public void getCatsFromDB()
{
if (_storedCategories != null)
{
return;
}
_storedCategories = new FastMap<>();
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement stmt = con.prepareStatement("SELECT * FROM character_ui_categories WHERE `charId` = ? ORDER BY `catId`, `order`");
stmt.setInt(1, _player.getObjectId());
ResultSet rs = stmt.executeQuery();
while (rs.next())
{
int cat = rs.getInt("catId");
int cmd = rs.getInt("cmdId");
insertCategory(cat, cmd);
}
stmt.close();
rs.close();
}
catch (Exception e)
{
_log.log(Level.WARNING, "Exception: getCatsFromDB(): " + e.getMessage(), e);
}
finally
{
L2DatabaseFactory.close(con);
}
if (_storedCategories.size() < 1)
{
_storedCategories = UITable.getInstance().getCategories();
}
}
public void getKeysFromDB()
{
if (_storedKeys != null)
{
return;
}
_storedKeys = new FastMap<>();
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement stmt = con.prepareStatement("SELECT * FROM character_ui_actions WHERE `charId` = ? ORDER BY `cat`, `order`");
stmt.setInt(1, _player.getObjectId());
ResultSet rs = stmt.executeQuery();
while (rs.next())
{
int cat = rs.getInt("cat");
int cmd = rs.getInt("cmd");
int key = rs.getInt("key");
int tgKey1 = rs.getInt("tgKey1");
int tgKey2 = rs.getInt("tgKey2");
int show = rs.getInt("show");
insertKey(cat, cmd, key, tgKey1, tgKey2, show);
}
stmt.close();
rs.close();
}
catch (Exception e)
{
_log.log(Level.WARNING, "Exception: getKeysFromDB(): " + e.getMessage(), e);
}
finally
{
L2DatabaseFactory.close(con);
}
if (_storedKeys.size() < 1)
{
_storedKeys = UITable.getInstance().getKeys();
}
}
public void insertCategory(int cat, int cmd)
{
if (_storedCategories.containsKey(cat))
{
_storedCategories.get(cat).add(cmd);
}
else
{
List<Integer> tmp = new FastList<>();
tmp.add(cmd);
_storedCategories.put(cat, tmp);
}
}
public void insertKey(int cat, int cmdId, int key, int tgKey1, int tgKey2, int show)
{
ActionKey tmk = new ActionKey(cat, cmdId, key, tgKey1, tgKey2, show);
if (_storedKeys.containsKey(cat))
{
_storedKeys.get(cat).add(tmk);
}
else
{
List<ActionKey> tmp = new FastList<>();
tmp.add(tmk);
_storedKeys.put(cat, tmp);
}
}
public boolean isSaved()
{
return _saved;
}
}
@@ -0,0 +1,823 @@
/*
* 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.l2jserver.gameserver.model;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import javolution.util.FastList;
import javolution.util.FastMap;
import com.l2jserver.Config;
import com.l2jserver.gameserver.GmListTable;
import com.l2jserver.gameserver.datatables.CharNameTable;
import com.l2jserver.gameserver.model.actor.L2Playable;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
import com.l2jserver.util.Point3D;
import com.l2jserver.util.StringUtil;
/**
* 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());
/**
* Gracia border Flying objects not allowed to the east of it.
*/
public static final int GRACIA_MAX_X = -166168;
public static final int GRACIA_MAX_Z = 6105;
public static final int GRACIA_MIN_Z = -895;
/*
* 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;
private static final int TILE_SIZE = 32768;
/** Map dimensions */
public static final int MAP_MIN_X = (Config.WORLD_X_MIN - 20) * TILE_SIZE;
public static final int MAP_MAX_X = (Config.WORLD_X_MAX - 19) * TILE_SIZE;
public static final int MAP_MIN_Y = (Config.WORLD_Y_MIN - 18) * TILE_SIZE;
public static final int MAP_MAX_Y = (Config.WORLD_Y_MAX - 17) * TILE_SIZE;
/** 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;
// private FastMap<String, L2PcInstance> _allGms;
/** HashMap(Integer Player id, L2PcInstance) containing all the players in game */
private final Map<Integer, L2PcInstance> _allPlayers;
/** L2ObjectHashMap(L2Object) containing all visible objects */
private final Map<Integer, L2Object> _allObjects;
/** List with the pets instances and their owner id */
private final Map<Integer, L2PetInstance> _petsInstance;
private L2WorldRegion[][] _worldRegions;
/**
* Constructor of L2World.<BR>
* <BR>
*/
private L2World()
{
// _allGms = new FastMap<String, L2PcInstance>();
_allPlayers = new FastMap<Integer, L2PcInstance>().shared();
_petsInstance = new FastMap<Integer, L2PetInstance>().shared();
_allObjects = new FastMap<Integer, L2Object>().shared();
initRegions();
}
/**
* Return the current instance of L2World.<BR>
* <BR>
*/
public static L2World getInstance()
{
return SingletonHolder._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>
*/
public void storeObject(L2Object object)
{
assert !_allObjects.containsKey(object.getObjectId());
if (_allObjects.containsKey(object.getObjectId()))
{
_log.warning("[L2World] object: " + object + " already exist in OID map!");
_log.info(StringUtil.getTraceString(Thread.currentThread().getStackTrace()));
return;
}
_allObjects.put(object.getObjectId(), object);
}
public long timeStoreObject(L2Object object)
{
long time = System.nanoTime();
_allObjects.put(object.getObjectId(), object);
time = System.nanoTime() - time;
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(Integer.valueOf(object.getObjectId())); // suggestion by whatev
// IdFactory.getInstance().releaseId(object.getObjectId());
}
public void removeObjects(List<L2Object> list)
{
for (L2Object o : list)
{
if (o != null)
{
_allObjects.remove(Integer.valueOf(o.getObjectId())); // suggestion by whatev
}
}
// IdFactory.getInstance().releaseId(object.getObjectId());
}
public void removeObjects(L2Object[] objects)
{
for (L2Object o : objects)
{
_allObjects.remove(Integer.valueOf(o.getObjectId())); // suggestion by whatev
// IdFactory.getInstance().releaseId(object.getObjectId());
}
}
public long timeRemoveObject(L2Object object)
{
long time = System.nanoTime();
_allObjects.remove(Integer.valueOf(object.getObjectId()));
time = System.nanoTime() - time;
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
*/
public L2Object findObject(int oID)
{
return _allObjects.get(Integer.valueOf(oID));
}
public long timeFindObject(int objectID)
{
long time = System.nanoTime();
_allObjects.get(Integer.valueOf(objectID));
time = System.nanoTime() - time;
return time;
}
/**
* Added by Tempy - 08 Aug 05 Allows easy retrevial of all visible objects in world. -- do not use that fucntion, its unsafe!
* @deprecated
*/
@Deprecated
public final Map<Integer, 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>
*/
public FastList<L2PcInstance> getAllGMs()
{
return GmListTable.getInstance().getAllGms(true);
}
public Map<Integer, L2PcInstance> getAllPlayers()
{
return _allPlayers;
}
/**
* 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>
* <B>If you have access to player objectId use {@link #getPlayer(int playerObjId)}</B> <BR>
* @param name Name of the player to get Instance
*/
public L2PcInstance getPlayer(String name)
{
return getPlayer(CharNameTable.getInstance().getIdByName(name));
}
/**
* Return the player instance corresponding to the given object ID.<BR>
* <BR>
* @param playerObjId Object ID of the player to get Instance
*/
public L2PcInstance getPlayer(int playerObjId)
{
return _allPlayers.get(Integer.valueOf(playerObjId));
}
/**
* Return the pet instance from the given ownerId.<BR>
* <BR>
* @param ownerId ID of the owner
*/
public L2PetInstance getPet(int ownerId)
{
return _petsInstance.get(Integer.valueOf(ownerId));
}
/**
* Add the given pet instance from the given ownerId.<BR>
* <BR>
* @param ownerId ID of the owner
* @param pet L2PetInstance of the pet
*/
public L2PetInstance addPet(int ownerId, L2PetInstance pet)
{
return _petsInstance.put(ownerId, pet);
}
/**
* Remove the given pet instance.<BR>
* <BR>
* @param ownerId ID of the owner
*/
public void removePet(int ownerId)
{
_petsInstance.remove(Integer.valueOf(ownerId));
}
/**
* Remove the given pet instance.<BR>
* <BR>
* @param pet the pet to remove
*/
public void removePet(L2PetInstance pet)
{
_petsInstance.remove(Integer.valueOf(pet.getOwner().getObjectId()));
}
/**
* 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)
{
// 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)
{
L2PcInstance player = (L2PcInstance) object;
if (!player.isTeleporting())
{
L2PcInstance tmp = _allPlayers.get(Integer.valueOf(player.getObjectId()));
if (tmp != null)
{
_log.warning("Duplicate character!? Closing both characters (" + player.getName() + ")");
player.logout();
tmp.logout();
return;
}
_allPlayers.put(player.getObjectId(), player);
}
}
if (!newRegion.isActive())
{
return;
}
// Get all visible objects contained in the _visibleObjects of L2WorldRegions
// in a circular area of 2000 units
List<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 (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);
// 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);
}
}
/**
* Add the L2PcInstance to _allPlayers of L2World.<BR>
* <BR>
*/
public void addToAllPlayers(L2PcInstance cha)
{
_allPlayers.put(cha.getObjectId(), 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>
*/
public void removeFromAllPlayers(L2PcInstance cha)
{
_allPlayers.remove(Integer.valueOf(cha.getObjectId()));
}
/**
* 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;
}
// removeObject(object);
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 (L2WorldRegion reg : oldRegion.getSurroundingRegions())
{
// synchronized (KnownListUpdateTaskManager.getInstance().getSync())
{
Collection<L2Object> vObj = reg.getVisibleObjects().values();
// synchronized (reg.getVisibleObjects())
{
for (L2Object obj : vObj)
{
if (obj != null)
{
obj.getKnownList().removeKnownObject(object);
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);
}
// If selected L2Object is a GM L2PcInstance, remove it from Set(L2PcInstance) _gmList of GmListTable
// if (((L2PcInstance)object).isGM())
// GmListTable.getInstance().deleteGm((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
*/
public List<L2Object> getVisibleObjects(L2Object object)
{
L2WorldRegion reg = object.getWorldRegion();
if (reg == null)
{
return null;
}
// Create an FastList in order to contain all visible L2Object
List<L2Object> result = new ArrayList<>();
// Go through the FastList of region
for (L2WorldRegion regi : reg.getSurroundingRegions())
{
// Go through visible objects of the selected region
Collection<L2Object> vObj = regi.getVisibleObjects().values();
// synchronized (regi.getVisibleObjects())
{
for (L2Object _object : vObj)
{
if ((_object == null) || _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
*/
public List<L2Object> getVisibleObjects(L2Object object, int radius)
{
if ((object == null) || !object.isVisible())
{
return new ArrayList<>();
}
int x = object.getX();
int y = object.getY();
int sqRadius = radius * radius;
// Create an FastList in order to contain all visible L2Object
List<L2Object> result = new ArrayList<>();
// Go through the FastList of region
for (L2WorldRegion regi : object.getWorldRegion().getSurroundingRegions())
{
// Go through visible objects of the selected region
Collection<L2Object> vObj = regi.getVisibleObjects().values();
// synchronized (regi.getVisibleObjects())
{
for (L2Object _object : vObj)
{
if ((_object == null) || _object.equals(object))
{
continue; // skip our own character
}
int x1 = _object.getX();
int y1 = _object.getY();
double dx = x1 - x;
double dy = y1 - y;
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
*/
public List<L2Object> getVisibleObjects3D(L2Object object, int radius)
{
if ((object == null) || !object.isVisible())
{
return new ArrayList<>();
}
int x = object.getX();
int y = object.getY();
int z = object.getZ();
int sqRadius = radius * radius;
// Create an FastList in order to contain all visible L2Object
List<L2Object> result = new ArrayList<>();
// Go through visible object of the selected region
for (L2WorldRegion regi : object.getWorldRegion().getSurroundingRegions())
{
Collection<L2Object> vObj = regi.getVisibleObjects().values();
// synchronized (regi.getVisibleObjects())
{
for (L2Object _object : vObj)
{
if ((_object == null) || _object.equals(object))
{
continue; // skip our own character
}
int x1 = _object.getX();
int y1 = _object.getY();
int z1 = _object.getZ();
long dx = x1 - x;
long dy = y1 - y;
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
*/
public List<L2Playable> getVisiblePlayable(L2Object object)
{
L2WorldRegion reg = object.getWorldRegion();
if (reg == null)
{
return null;
}
// Create an FastList in order to contain all visible L2Object
List<L2Playable> result = new ArrayList<>();
// Go through the FastList of region
for (L2WorldRegion regi : reg.getSurroundingRegions())
{
// Create an Iterator to go through the visible L2Object of the L2WorldRegion
Map<Integer, L2Playable> _allpls = regi.getVisiblePlayable();
Collection<L2Playable> _playables = _allpls.values();
// Go through visible object of the selected region
// synchronized (_allpls)
{
for (L2Playable _object : _playables)
{
if ((_object == null) || _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 mouvement</li><BR>
* @param Point3D point position of the object
*/
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];
}
/**
* Returns the whole 2d array containing the world regions used by ZoneData.java to setup zones inside the world regions
* @return
*/
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()
{
_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.info("L2World: (" + REGIONS_X + " by " + REGIONS_Y + ") World Region Grid set up.");
}
/**
* Deleted all spawns in the world.
*/
public 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.");
}
@SuppressWarnings("synthetic-access")
private static class SingletonHolder
{
protected static final L2World _instance = new L2World();
}
}
@@ -0,0 +1,520 @@
/*
* 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.l2jserver.gameserver.model;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;
import java.util.logging.Logger;
import javolution.util.FastList;
import javolution.util.FastMap;
import com.l2jserver.Config;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.datatables.SpawnTable;
import com.l2jserver.gameserver.model.actor.L2Attackable;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.L2Playable;
import com.l2jserver.gameserver.model.actor.L2Vehicle;
import com.l2jserver.gameserver.model.zone.L2ZoneType;
import com.l2jserver.gameserver.model.zone.type.L2DerbyTrackZone;
import com.l2jserver.gameserver.model.zone.type.L2PeaceZone;
import com.l2jserver.gameserver.model.zone.type.L2TownZone;
/**
* 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 Map<Integer, L2Playable> _allPlayable;
/** L2ObjectHashSet(L2Object) containing L2Object visible in this L2WorldRegion */
private final Map<Integer, L2Object> _visibleObjects;
private final List<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 = new FastMap<Integer, L2Playable>().shared();
_visibleObjects = new FastMap<Integer, L2Object>().shared();
_surroundingRegions = new ArrayList<>();
_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)
{
// do NOT update the world region while the character is still in the process of teleporting
// Once the teleport is COMPLETED, revalidation occurs safely, at that time.
if (character.isTeleporting())
{
return;
}
for (L2ZoneType z : getZones())
{
if (z != null)
{
z.revalidateInZone(character);
}
}
}
public void removeFromZones(L2Character character)
{
for (L2ZoneType z : getZones())
{
if (z != null)
{
z.removeCharacter(character);
}
}
}
public boolean containsZone(int zoneId)
{
for (L2ZoneType z : getZones())
{
if (z.getId() == zoneId)
{
return true;
}
}
return false;
}
public boolean checkEffectRangeInsidePeaceZone(L2Skill skill, final int x, final int y, final int z)
{
final int range = skill.getEffectRange();
final int up = y + range;
final int down = y - range;
final int left = x + range;
final int right = x - range;
for (L2ZoneType e : getZones())
{
if (((e instanceof L2TownZone) && ((L2TownZone) e).isPeaceZone()) || (e instanceof L2DerbyTrackZone) || (e instanceof L2PeaceZone))
{
if (e.isInsideZone(x, up, z))
{
return false;
}
if (e.isInsideZone(x, down, z))
{
return false;
}
if (e.isInsideZone(left, y, z))
{
return false;
}
if (e.isInsideZone(right, y, z))
{
return false;
}
if (e.isInsideZone(x, y, z))
{
return false;
}
}
}
return true;
}
public void onDeath(L2Character character)
{
for (L2ZoneType z : getZones())
{
if (z != null)
{
z.onDieInside(character);
}
}
}
public void onRevive(L2Character character)
{
for (L2ZoneType z : getZones())
{
if (z != null)
{
z.onReviveInside(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 (L2WorldRegion neighbor : getSurroundingRegions())
{
neighbor.setActive(true);
}
}
else
{
if (areNeighborsEmpty())
{
setActive(false);
}
// check and deactivate
for (L2WorldRegion neighbor : getSurroundingRegions())
{
if (neighbor.areNeighborsEmpty())
{
neighbor.setActive(false);
}
}
}
}
}
private void switchAI(boolean isOn)
{
int c = 0;
if (!isOn)
{
Collection<L2Object> vObj = _visibleObjects.values();
// synchronized (_visibleObjects)
{
for (L2Object o : vObj)
{
if (o instanceof L2Attackable)
{
c++;
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();
// stop the ai tasks
if (mob.hasAI())
{
mob.getAI().setIntention(com.l2jserver.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE);
mob.getAI().stopAITask();
}
}
else if (o instanceof L2Vehicle)
{
c++;
((L2Vehicle) o).getKnownList().removeAllKnownObjects();
}
}
}
_log.fine(c + " mobs were turned off");
}
else
{
Collection<L2Object> vObj = _visibleObjects.values();
// synchronized (_visibleObjects)
{
for (L2Object o : vObj)
{
if (o instanceof L2Attackable)
{
c++;
// Start HP/MP/CP Regeneration task
((L2Attackable) o).getStatus().startHpMpRegeneration();
}
else if (o instanceof L2Npc)
{
((L2Npc) o).startRandomAnimationTimer();
}
}
}
// KnownListUpdateTaskManager.getInstance().updateRegion(this, true, true);
_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.isEmpty())
{
return false;
}
// if any one of the neighbors is occupied, return false
for (L2WorldRegion neighbor : _surroundingRegions)
{
if (neighbor.isActive() && !neighbor._allPlayable.isEmpty())
{
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
*/
public void addVisibleObject(L2Object object)
{
if (object == null)
{
return;
}
assert object.getWorldRegion() == this;
_visibleObjects.put(object.getObjectId(), object);
if (object instanceof L2Playable)
{
_allPlayable.put(object.getObjectId(), (L2Playable) 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
*/
public void removeVisibleObject(L2Object object)
{
if (object == null)
{
return;
}
assert (object.getWorldRegion() == this) || (object.getWorldRegion() == null);
_visibleObjects.remove(object.getObjectId());
if (object instanceof L2Playable)
{
_allPlayable.remove(object.getObjectId());
if (_allPlayable.isEmpty() && !Config.GRIDS_ALWAYS_ON)
{
startDeactivation();
}
}
}
public void addSurroundingRegion(L2WorldRegion region)
{
_surroundingRegions.add(region);
}
/**
* Return the FastList _surroundingRegions containing all L2WorldRegion around the current L2WorldRegion
*/
public List<L2WorldRegion> getSurroundingRegions()
{
return _surroundingRegions;
}
public Map<Integer, L2Playable> getVisiblePlayable()
{
return _allPlayable;
}
public Map<Integer, L2Object> getVisibleObjects()
{
return _visibleObjects;
}
public String getName()
{
return "(" + _tileX + ", " + _tileY + ")";
}
/**
* Deleted all spawns in the world.
*/
public void deleteVisibleNpcSpawns()
{
_log.fine("Deleting all visible NPC's in Region: " + getName());
Collection<L2Object> vNPC = _visibleObjects.values();
// synchronized (_visibleObjects)
{
for (L2Object obj : vNPC)
{
if (obj instanceof L2Npc)
{
L2Npc target = (L2Npc) obj;
target.deleteMe();
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());
}
}
@@ -0,0 +1,80 @@
/*
* 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.l2jserver.gameserver.model;
import com.l2jserver.gameserver.model.actor.L2Character;
/**
* 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(L2Object obj)
{
_x = obj.getX();
_y = obj.getY();
_z = obj.getZ();
}
public Location(L2Character obj)
{
_x = obj.getX();
_y = obj.getY();
_z = obj.getZ();
_heading = obj.getHeading();
}
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;
}
}
@@ -0,0 +1,258 @@
/*
* 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.l2jserver.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 javolution.util.FastList;
import javolution.util.FastMap;
import com.l2jserver.L2DatabaseFactory;
import com.l2jserver.gameserver.model.L2Macro.L2MacroCmd;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.network.serverpackets.SendMacroList;
import com.l2jserver.util.StringUtil;
/**
* 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
{
L2Macro old = _macroses.put(macro.id, macro);
if (old != null)
{
deleteMacroFromDb(old);
}
registerMacroInDb(macro);
}
sendUpdate();
}
public void deleteMacro(int id)
{
L2Macro toRemove = _macroses.get(id);
if (toRemove != null)
{
deleteMacroFromDb(toRemove);
}
_macroses.remove(id);
L2ShortCut[] allShortCuts = _owner.getAllShortCuts();
for (L2ShortCut sc : allShortCuts)
{
if ((sc.getId() == id) && (sc.getType() == L2ShortCut.TYPE_MACRO))
{
_owner.deleteShortCut(sc.getSlot(), sc.getPage());
}
}
sendUpdate();
}
public void sendUpdate()
{
_revision++;
L2Macro[] all = getAllMacroses();
if (all.length == 0)
{
_owner.sendPacket(new SendMacroList(_revision, all.length, null));
}
else
{
for (L2Macro m : all)
{
_owner.sendPacket(new SendMacroList(_revision, all.length, m));
}
}
}
private void registerMacroInDb(L2Macro macro)
{
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("INSERT INTO character_macroses (charId,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 StringBuilder sb = new StringBuilder(300);
for (L2MacroCmd cmd : macro.commands)
{
StringUtil.append(sb, String.valueOf(cmd.type), ",", String.valueOf(cmd.d1), ",", String.valueOf(cmd.d2));
if ((cmd.cmd != null) && (cmd.cmd.length() > 0))
{
StringUtil.append(sb, ",", cmd.cmd);
}
sb.append(';');
}
if (sb.length() > 255)
{
sb.setLength(255);
}
statement.setString(7, sb.toString());
statement.execute();
statement.close();
}
catch (Exception e)
{
_log.log(Level.WARNING, "could not store macro:", e);
}
finally
{
L2DatabaseFactory.close(con);
}
}
/**
* @param shortcut
*/
private void deleteMacroFromDb(L2Macro macro)
{
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("DELETE FROM character_macroses WHERE charId=? AND id=?");
statement.setInt(1, _owner.getObjectId());
statement.setInt(2, macro.id);
statement.execute();
statement.close();
}
catch (Exception e)
{
_log.log(Level.WARNING, "could not delete macro:", e);
}
finally
{
L2DatabaseFactory.close(con);
}
}
public void restore()
{
_macroses.clear();
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("SELECT charId, id, icon, name, descr, acronym, commands FROM character_macroses WHERE charId=?");
statement.setInt(1, _owner.getObjectId());
ResultSet rset = statement.executeQuery();
while (rset.next())
{
int id = rset.getInt("id");
int icon = rset.getInt("icon");
String name = rset.getString("name");
String descr = rset.getString("descr");
String acronym = rset.getString("acronym");
List<L2MacroCmd> commands = FastList.newInstance();
StringTokenizer st1 = new StringTokenizer(rset.getString("commands"), ";");
while (st1.hasMoreTokens())
{
StringTokenizer st = new StringTokenizer(st1.nextToken(), ",");
if (st.countTokens() < 3)
{
continue;
}
int type = Integer.parseInt(st.nextToken());
int d1 = Integer.parseInt(st.nextToken());
int d2 = Integer.parseInt(st.nextToken());
String cmd = "";
if (st.hasMoreTokens())
{
cmd = st.nextToken();
}
L2MacroCmd mcmd = new L2MacroCmd(commands.size(), type, d1, d2, cmd);
commands.add(mcmd);
}
L2Macro m = new L2Macro(id, icon, name, descr, acronym, commands.toArray(new L2MacroCmd[commands.size()]));
FastList.recycle((FastList<?>) commands);
_macroses.put(m.id, m);
}
rset.close();
statement.close();
}
catch (Exception e)
{
_log.log(Level.WARNING, "could not store shortcuts:", e);
}
finally
{
L2DatabaseFactory.close(con);
}
}
}
@@ -0,0 +1,411 @@
/*
* 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.l2jserver.gameserver.model;
import java.util.List;
import javolution.util.FastList;
import com.l2jserver.gameserver.ai.CtrlIntention;
import com.l2jserver.gameserver.ai.L2ControllableMobAI;
import com.l2jserver.gameserver.datatables.SpawnTable;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.instance.L2ControllableMobInstance;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.templates.chars.L2NpcTemplate;
import com.l2jserver.util.Rnd;
/**
* @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
{
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 (Exception e)
{
return "Unspawned";
}
}
public L2NpcTemplate getTemplate()
{
return _npcTemplate;
}
public boolean isGroupMember(L2ControllableMobInstance mobInst)
{
for (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++)
{
L2GroupSpawn spawn = new L2GroupSpawn(getTemplate());
int signX = (Rnd.nextInt(2) == 0) ? -1 : 1;
int signY = (Rnd.nextInt(2) == 0) ? -1 : 1;
int randX = Rnd.nextInt(MobGroupTable.RANDOM_RANGE);
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 (ClassNotFoundException e)
{
}
catch (NoSuchMethodException e2)
{
}
}
public void spawnGroup(L2PcInstance activeChar)
{
spawnGroup(activeChar.getX(), activeChar.getY(), activeChar.getZ());
}
public void teleportGroup(L2PcInstance player)
{
removeDead();
for (L2ControllableMobInstance mobInst : getMobs())
{
if (mobInst == null)
{
continue;
}
if (!mobInst.isDead())
{
int x = player.getX() + Rnd.nextInt(50);
int y = player.getY() + Rnd.nextInt(50);
mobInst.teleToLocation(x, y, player.getZ(), true);
L2ControllableMobAI ai = (L2ControllableMobAI) mobInst.getAI();
ai.follow(player);
}
}
}
public L2ControllableMobInstance getRandomMob()
{
removeDead();
if (getActiveMobCount() == 0)
{
return null;
}
int choice = Rnd.nextInt(getActiveMobCount());
return getMobs().get(choice);
}
public void unspawnGroup()
{
removeDead();
if (getActiveMobCount() == 0)
{
return;
}
for (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 (L2ControllableMobInstance mobInst : getMobs())
{
if (mobInst == null)
{
continue;
}
if (!mobInst.isDead())
{
mobInst.reduceCurrentHp(mobInst.getMaxHp() + 1, activeChar, null);
}
SpawnTable.getInstance().deleteSpawn(mobInst.getSpawn(), false);
}
getMobs().clear();
}
public void setAttackRandom()
{
removeDead();
for (L2ControllableMobInstance mobInst : getMobs())
{
if (mobInst == null)
{
continue;
}
L2ControllableMobAI ai = (L2ControllableMobAI) mobInst.getAI();
ai.setAlternateAI(L2ControllableMobAI.AI_NORMAL);
ai.setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
}
}
public void setAttackTarget(L2Character target)
{
removeDead();
for (L2ControllableMobInstance mobInst : getMobs())
{
if (mobInst == null)
{
continue;
}
L2ControllableMobAI ai = (L2ControllableMobAI) mobInst.getAI();
ai.forceAttack(target);
}
}
public void setIdleMode()
{
removeDead();
for (L2ControllableMobInstance mobInst : getMobs())
{
if (mobInst == null)
{
continue;
}
L2ControllableMobAI ai = (L2ControllableMobAI) mobInst.getAI();
ai.stop();
}
}
public void returnGroup(L2Character activeChar)
{
setIdleMode();
for (L2ControllableMobInstance mobInst : getMobs())
{
if (mobInst == null)
{
continue;
}
int signX = (Rnd.nextInt(2) == 0) ? -1 : 1;
int signY = (Rnd.nextInt(2) == 0) ? -1 : 1;
int randX = Rnd.nextInt(MobGroupTable.RANDOM_RANGE);
int randY = Rnd.nextInt(MobGroupTable.RANDOM_RANGE);
L2ControllableMobAI ai = (L2ControllableMobAI) mobInst.getAI();
ai.move(activeChar.getX() + (signX * randX), activeChar.getY() + (signY * randY), activeChar.getZ());
}
}
public void setFollowMode(L2Character character)
{
removeDead();
for (L2ControllableMobInstance mobInst : getMobs())
{
if (mobInst == null)
{
continue;
}
L2ControllableMobAI ai = (L2ControllableMobAI) mobInst.getAI();
ai.follow(character);
}
}
public void setCastMode()
{
removeDead();
for (L2ControllableMobInstance mobInst : getMobs())
{
if (mobInst == null)
{
continue;
}
L2ControllableMobAI ai = (L2ControllableMobAI) mobInst.getAI();
ai.setAlternateAI(L2ControllableMobAI.AI_CAST);
}
}
public void setNoMoveMode(boolean enabled)
{
removeDead();
for (L2ControllableMobInstance mobInst : getMobs())
{
if (mobInst == null)
{
continue;
}
L2ControllableMobAI ai = (L2ControllableMobAI) mobInst.getAI();
ai.setNotMoving(enabled);
}
}
protected void removeDead()
{
List<L2ControllableMobInstance> deadMobs = new FastList<>();
for (L2ControllableMobInstance mobInst : getMobs())
{
if ((mobInst != null) && mobInst.isDead())
{
deadMobs.add(mobInst);
}
}
getMobs().removeAll(deadMobs);
}
public void setInvul(boolean invulState)
{
removeDead();
for (L2ControllableMobInstance mobInst : getMobs())
{
if (mobInst != null)
{
mobInst.setInvul(invulState);
}
}
}
public void setAttackGroup(MobGroup otherGrp)
{
removeDead();
for (L2ControllableMobInstance mobInst : getMobs())
{
if (mobInst == null)
{
continue;
}
L2ControllableMobAI ai = (L2ControllableMobAI) mobInst.getAI();
ai.forceAttackGroup(otherGrp);
ai.setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
}
}
}
@@ -0,0 +1,86 @@
/*
* 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.l2jserver.gameserver.model;
import java.util.Map;
import javolution.util.FastMap;
import com.l2jserver.gameserver.model.actor.instance.L2ControllableMobInstance;
/**
* @author littlecrow
*/
public class MobGroupTable
{
private final Map<Integer, MobGroup> _groupMap;
public static final int FOLLOW_RANGE = 300;
public static final int RANDOM_RANGE = 300;
private MobGroupTable()
{
_groupMap = new FastMap<>();
}
public static MobGroupTable getInstance()
{
return SingletonHolder._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 (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);
}
@SuppressWarnings("synthetic-access")
private static class SingletonHolder
{
protected static final MobGroupTable _instance = new MobGroupTable();
}
}
@@ -0,0 +1,187 @@
/*
* 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.l2jserver.gameserver.model;
import java.util.List;
import javolution.util.FastList;
import com.l2jserver.gameserver.instancemanager.TownManager;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.ExManagePartyRoomMember;
import com.l2jserver.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 FastList<>();
public PartyMatchRoom(int id, String title, int loot, int minlvl, int maxlvl, int maxmem, L2PcInstance owner)
{
_id = id;
_title = title;
_loot = loot;
_location = TownManager.getClosestLocation(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 (L2PcInstance _member : getPartyMembers())
{
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_LEFT_PARTY_ROOM);
sm.addCharName(player);
_member.sendPacket(sm);
_member.sendPacket(new ExManagePartyRoomMember(player, this, 2));
}
}
public void changeLeader(L2PcInstance newLeader)
{
// Get current leader
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 (L2PcInstance member : getPartyMembers())
{
member.sendPacket(new ExManagePartyRoomMember(newLeader, this, 1));
member.sendPacket(new ExManagePartyRoomMember(oldLeader, this, 1));
member.sendPacket(SystemMessageId.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;
}
}
@@ -0,0 +1,124 @@
/*
* 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.l2jserver.gameserver.model;
import java.util.Map;
import javolution.util.FastMap;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.ExClosePartyRoom;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
/**
* @author Gnacik
*/
public class PartyMatchRoomList
{
private int _maxid = 1;
private final Map<Integer, PartyMatchRoom> _rooms;
private PartyMatchRoomList()
{
_rooms = new FastMap<>();
}
public synchronized void addPartyMatchRoom(int id, PartyMatchRoom room)
{
_rooms.put(id, room);
_maxid++;
}
public void deleteRoom(int id)
{
for (L2PcInstance _member : getRoom(id).getPartyMembers())
{
if (_member == null)
{
continue;
}
_member.sendPacket(new ExClosePartyRoom());
_member.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.PARTY_ROOM_DISBANDED));
_member.setPartyRoom(0);
// _member.setPartyMatching(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 getMaxId()
{
return _maxid;
}
public PartyMatchRoom getPlayerRoom(L2PcInstance player)
{
for (PartyMatchRoom _room : _rooms.values())
{
for (L2PcInstance member : _room.getPartyMembers())
{
if (member.equals(player))
{
return _room;
}
}
}
return null;
}
public int getPlayerRoomId(L2PcInstance player)
{
for (PartyMatchRoom _room : _rooms.values())
{
for (L2PcInstance member : _room.getPartyMembers())
{
if (member.equals(player))
{
return _room.getId();
}
}
}
return -1;
}
public static PartyMatchRoomList getInstance()
{
return SingletonHolder._instance;
}
@SuppressWarnings("synthetic-access")
private static class SingletonHolder
{
protected static final PartyMatchRoomList _instance = new PartyMatchRoomList();
}
}
@@ -0,0 +1,68 @@
/*
* 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.l2jserver.gameserver.model;
import java.util.List;
import javolution.util.FastList;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
/**
* @author Gnacik
*/
public class PartyMatchWaitingList
{
private final List<L2PcInstance> _members;
private PartyMatchWaitingList()
{
_members = new FastList<>();
}
public void addPlayer(L2PcInstance player)
{
// player.setPartyWait(1);
if (!_members.contains(player))
{
_members.add(player);
}
}
public void removePlayer(L2PcInstance player)
{
// player.setPartyWait(0);
if (_members.contains(player))
{
_members.remove(player);
}
}
public List<L2PcInstance> getPlayers()
{
return _members;
}
public static PartyMatchWaitingList getInstance()
{
return SingletonHolder._instance;
}
@SuppressWarnings("synthetic-access")
private static class SingletonHolder
{
protected static final PartyMatchWaitingList _instance = new PartyMatchWaitingList();
}
}
@@ -0,0 +1,258 @@
/*
* 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.l2jserver.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.Level;
import java.util.logging.Logger;
import com.l2jserver.L2DatabaseFactory;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.network.serverpackets.ExAutoSoulShot;
import com.l2jserver.gameserver.network.serverpackets.ShortCutInit;
import com.l2jserver.gameserver.templates.item.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 synchronized void registerShortCut(L2ShortCut shortcut)
{
// verify shortcut
if (shortcut.getType() == L2ShortCut.TYPE_ITEM)
{
L2ItemInstance item = _owner.getInventory().getItemByObjectId(shortcut.getId());
if (item == null)
{
return;
}
if (item.isEtcItem())
{
shortcut.setSharedReuseGroup(item.getEtcItem().getSharedReuseGroup());
}
}
L2ShortCut oldShortCut = _shortCuts.put(shortcut.getSlot() + (12 * shortcut.getPage()), shortcut);
registerShortCutInDb(shortcut, oldShortCut);
}
private void registerShortCutInDb(L2ShortCut shortcut, L2ShortCut oldShortCut)
{
if (oldShortCut != null)
{
deleteShortCutFromDb(oldShortCut);
}
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("REPLACE INTO character_shortcuts (charId,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();
statement.close();
}
catch (Exception e)
{
_log.log(Level.WARNING, "Could not store character shortcut: " + e.getMessage(), e);
}
finally
{
L2DatabaseFactory.close(con);
}
}
/**
* @param slot
*/
public synchronized void deleteShortCut(int slot, int page)
{
L2ShortCut old = _shortCuts.remove(slot + (page * 12));
if ((old == null) || (_owner == null))
{
return;
}
deleteShortCutFromDb(old);
if (old.getType() == L2ShortCut.TYPE_ITEM)
{
L2ItemInstance item = _owner.getInventory().getItemByObjectId(old.getId());
if ((item != null) && (item.getItemType() == L2EtcItemType.SHOT))
{
if (_owner.removeAutoSoulShot(item.getItemId()))
{
_owner.sendPacket(new ExAutoSoulShot(item.getItemId(), 0));
}
}
}
_owner.sendPacket(new ShortCutInit(_owner));
for (int shotId : _owner.getAutoSoulShot())
{
_owner.sendPacket(new ExAutoSoulShot(shotId, 1));
}
}
public synchronized void deleteShortCutByObjectId(int objectId)
{
L2ShortCut toRemove = null;
for (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)
{
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("DELETE FROM character_shortcuts WHERE charId=? AND slot=? AND page=? AND class_index=?");
statement.setInt(1, _owner.getObjectId());
statement.setInt(2, shortcut.getSlot());
statement.setInt(3, shortcut.getPage());
statement.setInt(4, _owner.getClassIndex());
statement.execute();
statement.close();
}
catch (Exception e)
{
_log.log(Level.WARNING, "Could not delete character shortcut: " + e.getMessage(), e);
}
finally
{
L2DatabaseFactory.close(con);
}
}
public void restore()
{
_shortCuts.clear();
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("SELECT charId, slot, page, type, shortcut_id, level FROM character_shortcuts WHERE charId=? AND class_index=?");
statement.setInt(1, _owner.getObjectId());
statement.setInt(2, _owner.getClassIndex());
ResultSet rset = statement.executeQuery();
while (rset.next())
{
int slot = rset.getInt("slot");
int page = rset.getInt("page");
int type = rset.getInt("type");
int id = rset.getInt("shortcut_id");
int level = rset.getInt("level");
L2ShortCut sc = new L2ShortCut(slot, page, type, id, level, 1);
_shortCuts.put(slot + (page * 12), sc);
}
rset.close();
statement.close();
}
catch (Exception e)
{
_log.log(Level.WARNING, "Could not restore character shortcuts: " + e.getMessage(), e);
}
finally
{
L2DatabaseFactory.close(con);
}
// verify shortcuts
for (L2ShortCut sc : getAllShortCuts())
{
if (sc.getType() == L2ShortCut.TYPE_ITEM)
{
L2ItemInstance item = _owner.getInventory().getItemByObjectId(sc.getId());
if (item == null)
{
deleteShortCut(sc.getSlot(), sc.getPage());
}
else if (item.isEtcItem())
{
sc.setSharedReuseGroup(item.getEtcItem().getSharedReuseGroup());
}
}
}
}
}
@@ -0,0 +1,37 @@
/*
* $Header: SpawnListener.java, 7/09/2005 23:44:50 luisantonioa Exp $
*
* $Author: luisantonioa $
* $Date: 7/09/2005 23:44:50 $
* $Revision: 1 $
* $Log: SpawnListener.java,v $
* Revision 1 7/09/2005 23:44:50 luisantonioa
* Added copyright notice
*
*
* 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.l2jserver.gameserver.model;
import com.l2jserver.gameserver.model.actor.L2Npc;
/**
* This class ...
* @version $Revision: 1.2 $ $Date: 2004/06/27 08:12:59 $
*/
public interface SpawnListener
{
public void npcSpawned(L2Npc npc);
}
@@ -0,0 +1,79 @@
/*
* 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.l2jserver.gameserver.model;
/**
* Class explanation:<br>
* For item counting or checking purposes. When you don't want to modify inventory<br>
* class contains itemId, quantity, ownerId, referencePrice, but not objectId<br>
* is stored, this will be only "list" of items with it's owner
*/
public final class TempItem
{
private final int _itemId;
private int _quantity;
private final int _referencePrice;
private final String _itemName;
/**
* @param item
* @param quantity of that item
*/
public TempItem(L2ItemInstance item, int quantity)
{
super();
_itemId = item.getItemId();
_quantity = quantity;
_itemName = item.getItem().getName();
_referencePrice = item.getReferencePrice();
}
/**
* @return the quantity.
*/
public int getQuantity()
{
return _quantity;
}
/**
* @param quantity The quantity to set.
*/
public void setQuantity(int quantity)
{
_quantity = quantity;
}
public int getReferencePrice()
{
return _referencePrice;
}
/**
* @return the itemId.
*/
public int getItemId()
{
return _itemId;
}
/**
* @return the itemName.
*/
public String getItemName()
{
return _itemName;
}
}
@@ -0,0 +1,189 @@
/*
* 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.l2jserver.gameserver.model;
import com.l2jserver.Config;
import com.l2jserver.gameserver.datatables.ItemTable;
import com.l2jserver.gameserver.instancemanager.TerritoryWarManager;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.InventoryUpdate;
import com.l2jserver.gameserver.network.serverpackets.ItemList;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
public class TerritoryWard
{
// private static final Logger _log = Logger.getLogger(CombatFlag.class.getName());
protected L2PcInstance _player = null;
public int playerId = 0;
private L2ItemInstance _item = null;
private L2Npc _npc = null;
private Location _location;
private Location _oldLocation;
private final int _itemId;
private int _ownerCastleId;
private final int _territoryId;
// =========================================================
// Constructor
public TerritoryWard(int territory_id, int x, int y, int z, int heading, int item_id, int castleId, L2Npc npc)
{
_territoryId = territory_id;
_location = new Location(x, y, z, heading);
_itemId = item_id;
_ownerCastleId = castleId;
_npc = npc;
}
public int getTerritoryId()
{
return _territoryId;
}
public int getOwnerCastleId()
{
return _ownerCastleId;
}
public void setOwnerCastleId(int newOwner)
{
_ownerCastleId = newOwner;
}
public L2Npc getNpc()
{
return _npc;
}
public void setNpc(L2Npc npc)
{
_npc = npc;
}
public L2PcInstance getPlayer()
{
return _player;
}
public synchronized void spawnBack()
{
if (_player != null)
{
dropIt();
}
// Init the dropped L2WardInstance and add it in the world as a visible object at the position where last Pc got it
_npc = TerritoryWarManager.getInstance().spawnNPC(36491 + _territoryId, _oldLocation);
}
public synchronized void spawnMe()
{
if (_player != null)
{
dropIt();
}
// Init the dropped L2WardInstance and add it in the world as a visible object at the position where Pc was last
_npc = TerritoryWarManager.getInstance().spawnNPC(36491 + _territoryId, _location);
}
public synchronized void unSpawnMe()
{
if (_player != null)
{
dropIt();
}
if ((_npc != null) && !_npc.isDecayed())
{
_npc.deleteMe();
}
}
public boolean activate(L2PcInstance player, L2ItemInstance item)
{
if (player.isMounted())
{
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.CANNOT_EQUIP_ITEM_DUE_TO_BAD_CONDITION));
player.destroyItem("CombatFlag", item, null, true);
spawnMe();
return false;
}
else if (TerritoryWarManager.getInstance().getRegisteredTerritoryId(player) == 0)
{
player.sendMessage("Non participants can't pickup Territory Wards!");
player.destroyItem("CombatFlag", item, null, true);
spawnMe();
return false;
}
// Player holding it data
_player = player;
playerId = _player.getObjectId();
_oldLocation = new Location(_npc.getX(), _npc.getY(), _npc.getZ(), _npc.getHeading());
_npc = null;
// Equip with the weapon
if (item == null)
{
_item = ItemTable.getInstance().createItem("Combat", _itemId, 1, null, null);
}
else
{
_item = item;
}
_player.getInventory().equipItem(_item);
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_EQUIPPED);
sm.addItemName(_item);
_player.sendPacket(sm);
// Refresh inventory
if (!Config.FORCE_INVENTORY_UPDATE)
{
InventoryUpdate iu = new InventoryUpdate();
iu.addItem(_item);
_player.sendPacket(iu);
}
else
{
_player.sendPacket(new ItemList(_player, false));
}
// Refresh player stats
_player.broadcastUserInfo();
_player.setCombatFlagEquipped(true);
_player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_VE_ACQUIRED_THE_WARD));
TerritoryWarManager.getInstance().giveTWPoint(player, _territoryId, 5);
return true;
}
public void dropIt()
{
// Reset player stats
_player.setCombatFlagEquipped(false);
int slot = _player.getInventory().getSlotFromItem(_item);
_player.getInventory().unEquipItemInBodySlot(slot);
_player.destroyItem("CombatFlag", _item, null, true);
_item = null;
_player.broadcastUserInfo();
_location = new Location(_player.getX(), _player.getY(), _player.getZ(), _player.getHeading());
_player = null;
playerId = 0;
}
}
@@ -0,0 +1,94 @@
/*
* 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.l2jserver.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 long _price;
private long _storePrice;
private long _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(long price)
{
_price = price;
}
public long getOwnersPrice()
{
return _price;
}
public void setstorePrice(long price)
{
_storePrice = price;
}
public long getStorePrice()
{
return _storePrice;
}
public void setCount(long count)
{
_count = count;
}
public long 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
@@ -0,0 +1,42 @@
/*
* 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.l2jserver.gameserver.model;
public class VehiclePathPoint
{
public int x;
public int y;
public int z;
public int moveSpeed;
public int rotationSpeed;
public VehiclePathPoint(int _x, int _y, int _z)
{
x = _x;
y = _y;
z = _z;
moveSpeed = 350;
rotationSpeed = 4000;
}
public VehiclePathPoint(int _x, int _y, int _z, int _m, int _r)
{
x = _x;
y = _y;
z = _z;
moveSpeed = _m;
rotationSpeed = _r;
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,160 @@
/*
* 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.l2jserver.gameserver.model.actor;
import java.util.Collection;
import com.l2jserver.gameserver.model.L2ItemInstance;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.network.serverpackets.CharInfo;
import com.l2jserver.gameserver.taskmanager.DecayTaskManager;
import com.l2jserver.gameserver.templates.chars.L2CharTemplate;
import com.l2jserver.gameserver.templates.chars.L2NpcTemplate;
import com.l2jserver.gameserver.templates.item.L2Weapon;
public abstract class L2Decoy extends L2Character
{
private final L2PcInstance _owner;
public L2Decoy(int objectId, L2CharTemplate template, L2PcInstance owner)
{
super(objectId, template);
setInstanceType(InstanceType.L2Decoy);
_owner = owner;
setXYZInvisible(owner.getX(), owner.getY(), owner.getZ());
setIsInvul(false);
}
@Override
public void onSpawn()
{
super.onSpawn();
getOwner().sendPacket(new CharInfo(this));
}
@Override
public void updateAbnormalEffect()
{
Collection<L2PcInstance> plrs = getKnownList().getKnownPlayers().values();
// synchronized (getKnownList().getKnownPlayers())
{
for (L2PcInstance player : plrs)
{
if (player != null)
{
player.sendPacket(new CharInfo(this));
}
}
}
}
public void stopDecay()
{
DecayTaskManager.getInstance().cancelDecayTask(this);
}
@Override
public void onDecay()
{
deleteMe(_owner);
}
@Override
public boolean isAutoAttackable(L2Character attacker)
{
return _owner.isAutoAttackable(attacker);
}
@Override
public L2ItemInstance getActiveWeaponInstance()
{
return null;
}
@Override
public L2Weapon getActiveWeaponItem()
{
return null;
}
@Override
public L2ItemInstance getSecondaryWeaponInstance()
{
return null;
}
@Override
public L2Weapon getSecondaryWeaponItem()
{
return null;
}
public final int getNpcId()
{
return getTemplate().npcId;
}
@Override
public int getLevel()
{
return getTemplate().level;
}
public void deleteMe(L2PcInstance owner)
{
decayMe();
getKnownList().removeAllKnownObjects();
owner.setDecoy(null);
}
public synchronized void unSummon(L2PcInstance owner)
{
if (isVisible() && !isDead())
{
if (getWorldRegion() != null)
{
getWorldRegion().removeFromZones(this);
}
owner.setDecoy(null);
decayMe();
getKnownList().removeAllKnownObjects();
}
}
public final L2PcInstance getOwner()
{
return _owner;
}
@Override
public L2PcInstance getActingPlayer()
{
return _owner;
}
@Override
public L2NpcTemplate getTemplate()
{
return (L2NpcTemplate) super.getTemplate();
}
@Override
public void sendInfo(L2PcInstance activeChar)
{
activeChar.sendPacket(new CharInfo(this));
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,376 @@
/*
* 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.l2jserver.gameserver.model.actor;
import com.l2jserver.gameserver.ai.CtrlEvent;
import com.l2jserver.gameserver.model.CharEffectList;
import com.l2jserver.gameserver.model.L2Effect;
import com.l2jserver.gameserver.model.L2Skill;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.actor.knownlist.PlayableKnownList;
import com.l2jserver.gameserver.model.actor.stat.PlayableStat;
import com.l2jserver.gameserver.model.actor.status.PlayableStatus;
import com.l2jserver.gameserver.model.quest.QuestState;
import com.l2jserver.gameserver.templates.chars.L2CharTemplate;
import com.l2jserver.gameserver.templates.skills.L2EffectType;
/**
* This class represents all Playable characters in the world.<BR>
* <BR>
* L2PlayableInstance :<BR>
* <BR>
* <li>L2PcInstance</li> <li>L2Summon</li><BR>
* <BR>
*/
public abstract class L2Playable extends L2Character
{
private L2Character _lockedTarget = null;
/**
* Constructor of L2PlayableInstance (use L2Character constructor).<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Call the L2Character constructor to create an empty _skills slot and link copy basic Calculator set to this L2PlayableInstance</li><BR>
* <BR>
* @param objectId Identifier of the object to initialized
* @param template The L2CharTemplate to apply to the L2PlayableInstance
*/
public L2Playable(int objectId, L2CharTemplate template)
{
super(objectId, template);
setInstanceType(InstanceType.L2Playable);
setIsInvul(false);
}
@Override
public PlayableKnownList getKnownList()
{
return (PlayableKnownList) super.getKnownList();
}
@Override
public void initKnownList()
{
setKnownList(new PlayableKnownList(this));
}
@Override
public PlayableStat getStat()
{
return (PlayableStat) super.getStat();
}
@Override
public void initCharStat()
{
setStat(new PlayableStat(this));
}
@Override
public PlayableStatus getStatus()
{
return (PlayableStatus) super.getStatus();
}
@Override
public void initCharStatus()
{
setStatus(new PlayableStatus(this));
}
@Override
public boolean doDie(L2Character killer)
{
// killing is only possible one time
synchronized (this)
{
if (isDead())
{
return false;
}
// now reset currentHp to zero
setCurrentHp(0);
setIsDead(true);
}
// Set target to null and cancel Attack or Cast
setTarget(null);
// Stop movement
stopMove(null);
// Stop HP/MP/CP Regeneration task
getStatus().stopHpMpRegeneration();
// Stop all active skills effects in progress on the L2Character,
// if the Character isn't affected by Soul of The Phoenix or Salvation
if (isPhoenixBlessed())
{
if (getCharmOfLuck())
{
stopCharmOfLuck(null);
}
if (isNoblesseBlessed())
{
stopNoblesseBlessing(null);
}
}
// Same thing if the Character isn't a Noblesse Blessed L2PlayableInstance
else if (isNoblesseBlessed())
{
stopNoblesseBlessing(null);
if (getCharmOfLuck())
{
stopCharmOfLuck(null);
}
}
else
{
stopAllEffectsExceptThoseThatLastThroughDeath();
}
// Send the Server->Client packet StatusUpdate with current HP and MP to all other L2PcInstance to inform
broadcastStatusUpdate();
if (getWorldRegion() != null)
{
getWorldRegion().onDeath(this);
}
// Notify Quest of L2Playable's death
L2PcInstance actingPlayer = getActingPlayer();
if (!actingPlayer.isNotifyQuestOfDeathEmpty())
{
for (QuestState qs : actingPlayer.getNotifyQuestOfDeath())
{
qs.getQuest().notifyDeath((killer == null ? this : killer), this, qs);
}
}
if (killer != null)
{
L2PcInstance player = killer.getActingPlayer();
if (player != null)
{
player.onKillUpdatePvPKarma(this);
}
}
// Notify L2Character AI
getAI().notifyEvent(CtrlEvent.EVT_DEAD);
return true;
}
public boolean checkIfPvP(L2Character target)
{
if (target == null)
{
return false; // Target is null
}
if (target == this)
{
return false; // Target is self
}
if (!(target instanceof L2Playable))
{
return false; // Target is not a L2PlayableInstance
}
L2PcInstance player = null;
if (this instanceof L2PcInstance)
{
player = (L2PcInstance) this;
}
else if (this instanceof L2Summon)
{
player = ((L2Summon) this).getOwner();
}
if (player == null)
{
return false; // Active player is null
}
if (player.getKarma() != 0)
{
return false; // Active player has karma
}
L2PcInstance targetPlayer = null;
if (target instanceof L2PcInstance)
{
targetPlayer = (L2PcInstance) target;
}
else if (target instanceof L2Summon)
{
targetPlayer = ((L2Summon) target).getOwner();
}
if (targetPlayer == null)
{
return false; // Target player is null
}
if (targetPlayer == this)
{
return false; // Target player is self
}
if (targetPlayer.getKarma() != 0)
{
return false; // Target player has karma
}
if (targetPlayer.getPvpFlag() == 0)
{
return false;
}
return true;
/*
* Even at war, there should be PvP flag if( player.getClan() == null || targetPlayer.getClan() == null || ( !targetPlayer.getClan().isAtWarWith(player.getClanId()) && targetPlayer.getWantsPeace() == 0 && player.getWantsPeace() == 0 ) ) { return true; } return false;
*/
}
/**
* Return True.<BR>
* <BR>
*/
@Override
public boolean isAttackable()
{
return true;
}
// Support for Noblesse Blessing skill, where buffs are retained
// after resurrect
public final boolean isNoblesseBlessed()
{
return _effects.isAffected(CharEffectList.EFFECT_FLAG_NOBLESS_BLESSING);
}
public final void stopNoblesseBlessing(L2Effect effect)
{
if (effect == null)
{
stopEffects(L2EffectType.NOBLESSE_BLESSING);
}
else
{
removeEffect(effect);
}
updateAbnormalEffect();
}
// Support for Soul of the Phoenix and Salvation skills
public final boolean isPhoenixBlessed()
{
return _effects.isAffected(CharEffectList.EFFECT_FLAG_PHOENIX_BLESSING);
}
public final void stopPhoenixBlessing(L2Effect effect)
{
if (effect == null)
{
stopEffects(L2EffectType.PHOENIX_BLESSING);
}
else
{
removeEffect(effect);
}
updateAbnormalEffect();
}
/**
* Return True if the Silent Moving mode is active.<BR>
* <BR>
*/
public boolean isSilentMoving()
{
return _effects.isAffected(CharEffectList.EFFECT_FLAG_SILENT_MOVE);
}
// for Newbie Protection Blessing skill, keeps you safe from an attack by a chaotic character >= 10 levels apart from you
public final boolean getProtectionBlessing()
{
return _effects.isAffected(CharEffectList.EFFECT_FLAG_PROTECTION_BLESSING);
}
/**
* @param blessing
*/
public void stopProtectionBlessing(L2Effect effect)
{
if (effect == null)
{
stopEffects(L2EffectType.PROTECTION_BLESSING);
}
else
{
removeEffect(effect);
}
updateAbnormalEffect();
}
// Charm of Luck - During a Raid/Boss war, decreased chance for death penalty
public final boolean getCharmOfLuck()
{
return _effects.isAffected(CharEffectList.EFFECT_FLAG_CHARM_OF_LUCK);
}
public final void stopCharmOfLuck(L2Effect effect)
{
if (effect == null)
{
stopEffects(L2EffectType.CHARM_OF_LUCK);
}
else
{
removeEffect(effect);
}
updateAbnormalEffect();
}
@Override
public void updateEffectIcons(boolean partyOnly)
{
_effects.updateEffectIcons(partyOnly);
}
public boolean isLockedTarget()
{
return _lockedTarget != null;
}
public L2Character getLockedTarget()
{
return _lockedTarget;
}
public void setLockedTarget(L2Character cha)
{
_lockedTarget = cha;
}
public abstract int getKarma();
public abstract byte getPvpFlag();
public abstract boolean useMagic(L2Skill skill, boolean forceUse, boolean dontMove);
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,434 @@
/*
* 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.l2jserver.gameserver.model.actor;
import java.util.Collection;
import java.util.logging.Level;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.model.L2ItemInstance;
import com.l2jserver.gameserver.model.L2Skill;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.actor.knownlist.TrapKnownList;
import com.l2jserver.gameserver.model.quest.Quest;
import com.l2jserver.gameserver.model.quest.Quest.TrapAction;
import com.l2jserver.gameserver.network.serverpackets.AbstractNpcInfo;
import com.l2jserver.gameserver.network.serverpackets.L2GameServerPacket;
import com.l2jserver.gameserver.network.serverpackets.SocialAction;
import com.l2jserver.gameserver.taskmanager.DecayTaskManager;
import com.l2jserver.gameserver.templates.chars.L2NpcTemplate;
import com.l2jserver.gameserver.templates.item.L2Weapon;
/**
* @author nBd
*/
public class L2Trap extends L2Character
{
protected static final int TICK = 1000; // 1s
protected boolean _isTriggered;
protected final L2Skill _skill;
protected final int _lifeTime;
protected int _timeRemaining;
protected boolean _hasLifeTime;
/**
* @param objectId
* @param template
*/
public L2Trap(int objectId, L2NpcTemplate template, int lifeTime, L2Skill skill)
{
super(objectId, template);
setInstanceType(InstanceType.L2Trap);
setName(template.name);
setIsInvul(false);
_isTriggered = false;
_skill = skill;
_hasLifeTime = true;
if (lifeTime != 0)
{
_lifeTime = lifeTime;
}
else
{
_lifeTime = 30000;
}
_timeRemaining = _lifeTime;
if (lifeTime < 0)
{
_hasLifeTime = false;
}
if (skill != null)
{
ThreadPoolManager.getInstance().scheduleGeneral(new TrapTask(), TICK);
}
}
/**
* @see com.l2jserver.gameserver.model.actor.L2Character#getKnownList()
*/
@Override
public TrapKnownList getKnownList()
{
return (TrapKnownList) super.getKnownList();
}
@Override
public void initKnownList()
{
setKnownList(new TrapKnownList(this));
}
@Override
public boolean isAutoAttackable(L2Character attacker)
{
return !canSee(attacker);
}
/**
*
*
*/
public void stopDecay()
{
DecayTaskManager.getInstance().cancelDecayTask(this);
}
/**
* @see com.l2jserver.gameserver.model.actor.L2Character#onDecay()
*/
@Override
public void onDecay()
{
deleteMe();
}
/**
* @return
*/
public final int getNpcId()
{
return getTemplate().npcId;
}
/**
* @see com.l2jserver.gameserver.model.actor.L2Character#doDie(com.l2jserver.gameserver.model.actor.L2Character)
*/
@Override
public boolean doDie(L2Character killer)
{
if (!super.doDie(killer))
{
return false;
}
DecayTaskManager.getInstance().addDecayTask(this);
return true;
}
/**
* @param owner
*/
@Override
public void deleteMe()
{
decayMe();
getKnownList().removeAllKnownObjects();
super.deleteMe();
}
/**
* @param owner
*/
public synchronized void unSummon()
{
if (isVisible() && !isDead())
{
if (getWorldRegion() != null)
{
getWorldRegion().removeFromZones(this);
}
deleteMe();
}
}
/**
* @see com.l2jserver.gameserver.model.actor.L2Character#getActiveWeaponInstance()
*/
@Override
public L2ItemInstance getActiveWeaponInstance()
{
return null;
}
/**
* @see com.l2jserver.gameserver.model.actor.L2Character#getActiveWeaponItem()
*/
@Override
public L2Weapon getActiveWeaponItem()
{
return null;
}
/**
* @see com.l2jserver.gameserver.model.actor.L2Character#getLevel()
*/
@Override
public int getLevel()
{
return getTemplate().level;
}
/**
* @see com.l2jserver.gameserver.model.actor.L2Character#getTemplate()
*/
@Override
public L2NpcTemplate getTemplate()
{
return (L2NpcTemplate) super.getTemplate();
}
/**
* @see com.l2jserver.gameserver.model.actor.L2Character#getSecondaryWeaponInstance()
*/
@Override
public L2ItemInstance getSecondaryWeaponInstance()
{
return null;
}
/**
* @see com.l2jserver.gameserver.model.actor.L2Character#getSecondaryWeaponItem()
*/
@Override
public L2Weapon getSecondaryWeaponItem()
{
return null;
}
/**
* @see com.l2jserver.gameserver.model.actor.L2Character#updateAbnormalEffect()
*/
@Override
public void updateAbnormalEffect()
{
}
public L2Skill getSkill()
{
return _skill;
}
public L2PcInstance getOwner()
{
return null;
}
public int getKarma()
{
return 0;
}
public byte getPvpFlag()
{
return 0;
}
/**
* Checks is triggered
* @return True if trap is triggered.
*/
public boolean isTriggered()
{
return _isTriggered;
}
/**
* Checks trap visibility
* @param cha - checked character
* @return True if character can see trap
*/
public boolean canSee(L2Character cha)
{
return false;
}
/**
* Reveal trap to the detector (if possible)
* @param detector
*/
public void setDetected(L2Character detector)
{
detector.sendPacket(new AbstractNpcInfo.TrapInfo(this, detector));
}
/**
* Check if target can trigger trap
* @param target
* @return
*/
protected boolean checkTarget(L2Character target)
{
return L2Skill.checkForAreaOffensiveSkills(this, target, _skill, false);
}
protected class TrapTask implements Runnable
{
@Override
public void run()
{
try
{
if (!_isTriggered)
{
if (_hasLifeTime)
{
_timeRemaining -= TICK;
if (_timeRemaining < (_lifeTime - 15000))
{
SocialAction sa = new SocialAction(L2Trap.this, 2);
broadcastPacket(sa);
}
if (_timeRemaining < 0)
{
switch (getSkill().getTargetType())
{
case TARGET_AURA:
case TARGET_FRONT_AURA:
case TARGET_BEHIND_AURA:
trigger(L2Trap.this);
break;
default:
unSummon();
}
return;
}
}
for (L2Character target : getKnownList().getKnownCharactersInRadius(_skill.getSkillRadius()))
{
if (!checkTarget(target))
{
continue;
}
trigger(target);
return;
}
ThreadPoolManager.getInstance().scheduleGeneral(new TrapTask(), TICK);
}
}
catch (Exception e)
{
_log.log(Level.SEVERE, "", e);
unSummon();
}
}
}
/**
* Trigger trap
* @param target
*/
public void trigger(L2Character target)
{
_isTriggered = true;
broadcastPacket(new AbstractNpcInfo.TrapInfo(this, null));
setTarget(target);
if (getTemplate().getEventQuests(Quest.QuestEventType.ON_TRAP_ACTION) != null)
{
for (Quest quest : getTemplate().getEventQuests(Quest.QuestEventType.ON_TRAP_ACTION))
{
quest.notifyTrapAction(this, target, TrapAction.TRAP_TRIGGERED);
}
}
ThreadPoolManager.getInstance().scheduleGeneral(new TriggerTask(), 300);
}
protected class TriggerTask implements Runnable
{
@Override
public void run()
{
try
{
doCast(_skill);
ThreadPoolManager.getInstance().scheduleGeneral(new UnsummonTask(), _skill.getHitTime() + 300);
}
catch (Exception e)
{
unSummon();
}
}
}
protected class UnsummonTask implements Runnable
{
@Override
public void run()
{
unSummon();
}
}
@Override
public void sendInfo(L2PcInstance activeChar)
{
if (_isTriggered || canSee(activeChar))
{
activeChar.sendPacket(new AbstractNpcInfo.TrapInfo(this, activeChar));
}
}
@Override
public void broadcastPacket(L2GameServerPacket mov)
{
Collection<L2PcInstance> plrs = getKnownList().getKnownPlayers().values();
for (L2PcInstance player : plrs)
{
if ((player != null) && (_isTriggered || canSee(player)))
{
player.sendPacket(mov);
}
}
}
@Override
public void broadcastPacket(L2GameServerPacket mov, int radiusInKnownlist)
{
Collection<L2PcInstance> plrs = getKnownList().getKnownPlayers().values();
for (L2PcInstance player : plrs)
{
if (player == null)
{
continue;
}
if (isInsideRadius(player, radiusInKnownlist, false, false))
{
if (_isTriggered || canSee(player))
{
player.sendPacket(mov);
}
}
}
}
}
@@ -0,0 +1,520 @@
/*
* 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.l2jserver.gameserver.model.actor;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import javolution.util.FastList;
import com.l2jserver.Config;
import com.l2jserver.gameserver.GameTimeController;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.ai.CtrlIntention;
import com.l2jserver.gameserver.ai.L2CharacterAI;
import com.l2jserver.gameserver.datatables.MapRegionTable;
import com.l2jserver.gameserver.model.L2CharPosition;
import com.l2jserver.gameserver.model.L2ItemInstance;
import com.l2jserver.gameserver.model.L2World;
import com.l2jserver.gameserver.model.L2WorldRegion;
import com.l2jserver.gameserver.model.Location;
import com.l2jserver.gameserver.model.VehiclePathPoint;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.actor.knownlist.VehicleKnownList;
import com.l2jserver.gameserver.model.actor.stat.VehicleStat;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.InventoryUpdate;
import com.l2jserver.gameserver.network.serverpackets.L2GameServerPacket;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
import com.l2jserver.gameserver.templates.chars.L2CharTemplate;
import com.l2jserver.gameserver.templates.item.L2Weapon;
import com.l2jserver.gameserver.util.Util;
/**
* @author DS
*/
public abstract class L2Vehicle extends L2Character
{
protected int _dockId = 0;
protected final FastList<L2PcInstance> _passengers = new FastList<>();
protected Location _oustLoc = null;
private Runnable _engine = null;
protected VehiclePathPoint[] _currentPath = null;
protected int _runState = 0;
public L2Vehicle(int objectId, L2CharTemplate template)
{
super(objectId, template);
setInstanceType(InstanceType.L2Vehicle);
setIsFlying(true);
}
public boolean isBoat()
{
return false;
}
public boolean isAirShip()
{
return false;
}
public boolean canBeControlled()
{
return _engine == null;
}
public void registerEngine(Runnable r)
{
_engine = r;
}
public void runEngine(int delay)
{
if (_engine != null)
{
ThreadPoolManager.getInstance().scheduleGeneral(_engine, delay);
}
}
public void executePath(VehiclePathPoint[] path)
{
_runState = 0;
_currentPath = path;
if ((_currentPath != null) && (_currentPath.length > 0))
{
final VehiclePathPoint point = _currentPath[0];
if (point.moveSpeed > 0)
{
getStat().setMoveSpeed(point.moveSpeed);
}
if (point.rotationSpeed > 0)
{
getStat().setRotationSpeed(point.rotationSpeed);
}
getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new L2CharPosition(point.x, point.y, point.z, 0));
return;
}
getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
}
@Override
public boolean moveToNextRoutePoint()
{
_move = null;
if (_currentPath != null)
{
_runState++;
if (_runState < _currentPath.length)
{
final VehiclePathPoint point = _currentPath[_runState];
if (!isMovementDisabled())
{
if (point.moveSpeed == 0)
{
teleToLocation(point.x, point.y, point.z, point.rotationSpeed, false);
_currentPath = null;
}
else
{
if (point.moveSpeed > 0)
{
getStat().setMoveSpeed(point.moveSpeed);
}
if (point.rotationSpeed > 0)
{
getStat().setRotationSpeed(point.rotationSpeed);
}
MoveData m = new MoveData();
m.disregardingGeodata = false;
m.onGeodataPathIndex = -1;
m._xDestination = point.x;
m._yDestination = point.y;
m._zDestination = point.z;
m._heading = 0;
final double dx = point.x - getX();
final double dy = point.y - getY();
final double distance = Math.sqrt((dx * dx) + (dy * dy));
if (distance > 1)
{
setHeading(Util.calculateHeadingFrom(getX(), getY(), point.x, point.y));
}
m._moveStartTime = GameTimeController.getGameTicks();
_move = m;
GameTimeController.getInstance().registerMovingObject(this);
return true;
}
}
}
else
{
_currentPath = null;
}
}
runEngine(10);
return false;
}
@Override
public void initKnownList()
{
setKnownList(new VehicleKnownList(this));
}
@Override
public VehicleStat getStat()
{
return (VehicleStat) super.getStat();
}
@Override
public void initCharStat()
{
setStat(new VehicleStat(this));
}
public boolean isInDock()
{
return _dockId > 0;
}
public int getDockId()
{
return _dockId;
}
public void setInDock(int d)
{
_dockId = d;
}
public void setOustLoc(Location loc)
{
_oustLoc = loc;
}
public Location getOustLoc()
{
return _oustLoc != null ? _oustLoc : MapRegionTable.getInstance().getTeleToLocation(this, MapRegionTable.TeleportWhereType.Town);
}
public void oustPlayers()
{
L2PcInstance player;
// Use iterator because oustPlayer will try to remove player from _passengers
final Iterator<L2PcInstance> iter = _passengers.iterator();
while (iter.hasNext())
{
player = iter.next();
iter.remove();
if (player != null)
{
oustPlayer(player);
}
}
}
public void oustPlayer(L2PcInstance player)
{
player.setVehicle(null);
player.setInVehiclePosition(null);
removePassenger(player);
}
public boolean addPassenger(L2PcInstance player)
{
if ((player == null) || _passengers.contains(player))
{
return false;
}
// already in other vehicle
if ((player.getVehicle() != null) && (player.getVehicle() != this))
{
return false;
}
_passengers.add(player);
return true;
}
public void removePassenger(L2PcInstance player)
{
try
{
_passengers.remove(player);
}
catch (Exception e)
{
}
}
public boolean isEmpty()
{
return _passengers.isEmpty();
}
public List<L2PcInstance> getPassengers()
{
return _passengers;
}
public void broadcastToPassengers(L2GameServerPacket sm)
{
for (L2PcInstance player : _passengers)
{
if (player != null)
{
player.sendPacket(sm);
}
}
}
/**
* Consume ticket(s) and teleport player from boat if no correct ticket
* @param itemId Ticket itemId
* @param count Ticket count
* @param oustX
* @param oustY
* @param oustZ
*/
public void payForRide(int itemId, int count, int oustX, int oustY, int oustZ)
{
final Collection<L2PcInstance> passengers = getKnownList().getKnownPlayersInRadius(1000);
if ((passengers != null) && !passengers.isEmpty())
{
L2ItemInstance ticket;
InventoryUpdate iu;
for (L2PcInstance player : passengers)
{
if (player == null)
{
continue;
}
if (player.isInBoat() && (player.getBoat() == this))
{
if (itemId > 0)
{
ticket = player.getInventory().getItemByItemId(itemId);
if ((ticket == null) || (player.getInventory().destroyItem("Boat", ticket, count, player, this) == null))
{
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.NOT_CORRECT_BOAT_TICKET));
player.teleToLocation(oustX, oustY, oustZ, true);
continue;
}
iu = new InventoryUpdate();
iu.addModifiedItem(ticket);
player.sendPacket(iu);
}
addPassenger(player);
}
}
}
}
@Override
public boolean updatePosition(int gameTicks)
{
final boolean result = super.updatePosition(gameTicks);
for (L2PcInstance player : _passengers)
{
if ((player != null) && (player.getVehicle() == this))
{
player.getPosition().setXYZ(getX(), getY(), getZ());
player.revalidateZone(false);
}
}
return result;
}
@Override
public void teleToLocation(int x, int y, int z, int heading, boolean allowRandomOffset)
{
if (isMoving())
{
stopMove(null, false);
}
setIsTeleporting(true);
getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
for (L2PcInstance player : _passengers)
{
if (player != null)
{
player.teleToLocation(x, y, z);
}
}
decayMe();
setXYZ(x, y, z);
// temporary fix for heading on teleports
if (heading != 0)
{
getPosition().setHeading(heading);
}
onTeleported();
revalidateZone(true);
}
@Override
public void stopMove(L2CharPosition pos, boolean updateKnownObjects)
{
_move = null;
if (pos != null)
{
setXYZ(pos.x, pos.y, pos.z);
setHeading(pos.heading);
revalidateZone(true);
}
if (Config.MOVE_BASED_KNOWNLIST && updateKnownObjects)
{
getKnownList().findObjects();
}
}
@Override
public void deleteMe()
{
_engine = null;
try
{
if (isMoving())
{
stopMove(null);
}
}
catch (Exception e)
{
_log.log(Level.SEVERE, "Failed stopMove().", e);
}
try
{
oustPlayers();
}
catch (Exception e)
{
_log.log(Level.SEVERE, "Failed oustPlayers().", e);
}
final L2WorldRegion oldRegion = getWorldRegion();
try
{
decayMe();
}
catch (Exception e)
{
_log.log(Level.SEVERE, "Failed decayMe().", e);
}
if (oldRegion != null)
{
oldRegion.removeFromZones(this);
}
try
{
getKnownList().removeAllKnownObjects();
}
catch (Exception e)
{
_log.log(Level.SEVERE, "Failed cleaning knownlist.", e);
}
// Remove L2Object object from _allObjects of L2World
L2World.getInstance().removeObject(this);
super.deleteMe();
}
@Override
public void updateAbnormalEffect()
{
}
@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 int getLevel()
{
return 0;
}
@Override
public boolean isAutoAttackable(L2Character attacker)
{
return false;
}
@Override
public void setAI(L2CharacterAI newAI)
{
if (_ai == null)
{
_ai = newAI;
}
}
public class AIAccessor extends L2Character.AIAccessor
{
@Override
public void detachAI()
{
}
}
}
@@ -0,0 +1,242 @@
/*
* 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.l2jserver.gameserver.model.actor.appearance;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
public class PcAppearance
{
// =========================================================
// Data Field
private L2PcInstance _owner;
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;
private boolean _ghostmode = false;
/** The current visible name of this player, not necessarily the real one */
private String _visibleName;
/** The current visible title of this player, not necessarily the real one */
private String _visibleTitle;
/** 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;
}
// =========================================================
// Method - Public
// =========================================================
// Method - Private
/**
* @param visibleName The visibleName to set.
*/
public final void setVisibleName(String visibleName)
{
_visibleName = visibleName;
}
/**
* @return Returns the visibleName.
*/
public final String getVisibleName()
{
if (_visibleName == null)
{
_visibleName = getOwner().getName();
}
return _visibleName;
}
/**
* @param visibleTitle The visibleTitle to set.
*/
public final void setVisibleTitle(String visibleTitle)
{
_visibleTitle = visibleTitle;
}
/**
* @return Returns the visibleTitle.
*/
public final String getVisibleTitle()
{
if (_visibleTitle == null)
{
_visibleTitle = getOwner().getTitle();
}
return _visibleTitle;
}
// =========================================================
// Property - Public
public final byte getFace()
{
return _face;
}
/**
* @param byte value
*/
public final void setFace(int value)
{
_face = (byte) value;
}
public final byte getHairColor()
{
return _hairColor;
}
/**
* @param byte value
*/
public final void setHairColor(int value)
{
_hairColor = (byte) value;
}
public final byte getHairStyle()
{
return _hairStyle;
}
/**
* @param byte value
*/
public final void setHairStyle(int value)
{
_hairStyle = (byte) value;
}
/**
* @return true if char is female
*/
public final boolean getSex()
{
return _sex;
}
/**
* @param boolean 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 void setGhostMode(boolean b)
{
_ghostmode = b;
}
public boolean isGhost()
{
return _ghostmode;
}
public int getNameColor()
{
return _nameColor;
}
public void setNameColor(int nameColor)
{
if (nameColor < 0)
{
return;
}
_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)
{
if (titleColor < 0)
{
return;
}
_titleColor = titleColor;
}
public void setTitleColor(int red, int green, int blue)
{
_titleColor = (red & 0xFF) + ((green & 0xFF) << 8) + ((blue & 0xFF) << 16);
}
/**
* @param owner The owner to set.
*/
public void setOwner(L2PcInstance owner)
{
_owner = owner;
}
/**
* @return Returns the owner.
*/
public L2PcInstance getOwner()
{
return _owner;
}
}
@@ -0,0 +1,48 @@
/*
* 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.l2jserver.gameserver.model.actor.instance;
import com.l2jserver.gameserver.templates.chars.L2NpcTemplate;
/**
* This class ...
* @version $Revision: $ $Date: $
* @author LBaldi
*/
public class L2AdventurerInstance extends L2NpcInstance
{
public L2AdventurerInstance(int objectId, L2NpcTemplate template)
{
super(objectId, template);
setInstanceType(InstanceType.L2AdventurerInstance);
}
@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";
}
}
@@ -0,0 +1,177 @@
/*
* 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.l2jserver.gameserver.model.actor.instance;
import com.l2jserver.gameserver.ai.L2AirShipAI;
import com.l2jserver.gameserver.instancemanager.AirShipManager;
import com.l2jserver.gameserver.model.L2CharPosition;
import com.l2jserver.gameserver.model.Location;
import com.l2jserver.gameserver.model.actor.L2Vehicle;
import com.l2jserver.gameserver.network.serverpackets.ExAirShipInfo;
import com.l2jserver.gameserver.network.serverpackets.ExGetOffAirShip;
import com.l2jserver.gameserver.network.serverpackets.ExGetOnAirShip;
import com.l2jserver.gameserver.network.serverpackets.ExMoveToLocationAirShip;
import com.l2jserver.gameserver.network.serverpackets.ExStopMoveAirShip;
import com.l2jserver.gameserver.templates.chars.L2CharTemplate;
import com.l2jserver.util.Point3D;
/**
* Flying airships. Very similar to Maktakien boats (see L2BoatInstance) but these do fly :P
* @author DrHouse, reworked by DS
*/
public class L2AirShipInstance extends L2Vehicle
{
public L2AirShipInstance(int objectId, L2CharTemplate template)
{
super(objectId, template);
setInstanceType(InstanceType.L2AirShipInstance);
setAI(new L2AirShipAI(new AIAccessor()));
}
@Override
public boolean isAirShip()
{
return true;
}
public boolean isOwner(L2PcInstance player)
{
return false;
}
public int getOwnerId()
{
return 0;
}
public boolean isCaptain(L2PcInstance player)
{
return false;
}
public int getCaptainId()
{
return 0;
}
public int getHelmObjectId()
{
return 0;
}
public int getHelmItemId()
{
return 0;
}
public boolean setCaptain(L2PcInstance player)
{
return false;
}
public int getFuel()
{
return 0;
}
public void setFuel(int f)
{
}
public int getMaxFuel()
{
return 0;
}
public void setMaxFuel(int mf)
{
}
@Override
public boolean moveToNextRoutePoint()
{
final boolean result = super.moveToNextRoutePoint();
if (result)
{
broadcastPacket(new ExMoveToLocationAirShip(this));
}
return result;
}
@Override
public boolean addPassenger(L2PcInstance player)
{
if (!super.addPassenger(player))
{
return false;
}
player.setVehicle(this);
player.setInVehiclePosition(new Point3D(0, 0, 0));
player.broadcastPacket(new ExGetOnAirShip(player, this));
player.getKnownList().removeAllKnownObjects();
player.setXYZ(getX(), getY(), getZ());
player.revalidateZone(true);
return true;
}
@Override
public void oustPlayer(L2PcInstance player)
{
super.oustPlayer(player);
final Location loc = getOustLoc();
if (player.isOnline())
{
player.broadcastPacket(new ExGetOffAirShip(player, this, loc.getX(), loc.getY(), loc.getZ()));
player.getKnownList().removeAllKnownObjects();
player.setXYZ(loc.getX(), loc.getY(), loc.getZ());
player.revalidateZone(true);
}
else
{
player.setXYZInvisible(loc.getX(), loc.getY(), loc.getZ());
}
}
@Override
public void deleteMe()
{
super.deleteMe();
AirShipManager.getInstance().removeAirShip(this);
}
@Override
public void stopMove(L2CharPosition pos, boolean updateKnownObjects)
{
super.stopMove(pos, updateKnownObjects);
broadcastPacket(new ExStopMoveAirShip(this));
}
@Override
public void updateAbnormalEffect()
{
broadcastPacket(new ExAirShipInfo(this));
}
@Override
public void sendInfo(L2PcInstance activeChar)
{
activeChar.sendPacket(new ExAirShipInfo(this));
}
}
@@ -0,0 +1,89 @@
/*
* 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.l2jserver.gameserver.model.actor.instance;
import com.l2jserver.gameserver.model.L2Skill;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
import com.l2jserver.gameserver.templates.chars.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 L2Npc
{
/**
* 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 L2NpcTemplate Template to apply to the NPC
*/
public L2ArtefactInstance(int objectId, L2NpcTemplate template)
{
super(objectId, template);
setInstanceType(InstanceType.L2ArtefactInstance);
}
/**
* @see com.l2jserver.gameserver.model.actor.L2Npc#onSpawn()
*/
@Override
public void onSpawn()
{
super.onSpawn();
getCastle().registerArtefact(this);
}
/**
* Return False.<BR>
* <BR>
*/
@Override
public boolean isAutoAttackable(L2Character attacker)
{
return false;
}
@Override
public boolean isAttackable()
{
return false;
}
@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(ActionFailed.STATIC_PACKET);
}
@Override
public void reduceCurrentHp(double damage, L2Character attacker, L2Skill skill)
{
}
@Override
public void reduceCurrentHp(double damage, L2Character attacker, boolean awake, boolean isDOT, L2Skill skill)
{
}
}
@@ -0,0 +1,701 @@
/*
* 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.l2jserver.gameserver.model.actor.instance;
import static com.l2jserver.gameserver.model.itemcontainer.PcInventory.MAX_ADENA;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import javolution.util.FastMap;
import com.l2jserver.Config;
import com.l2jserver.gameserver.datatables.MapRegionTable;
import com.l2jserver.gameserver.instancemanager.AuctionManager;
import com.l2jserver.gameserver.instancemanager.ClanHallManager;
import com.l2jserver.gameserver.model.L2Clan;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.entity.Auction;
import com.l2jserver.gameserver.model.entity.Auction.Bidder;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
import com.l2jserver.gameserver.templates.chars.L2NpcTemplate;
public final class L2AuctioneerInstance extends L2Npc
{
private static final int COND_ALL_FALSE = 0;
private static final int COND_BUSY_BECAUSE_OF_SIEGE = 1;
private static final int COND_REGULAR = 3;
private final Map<Integer, Auction> _pendingAuctions = new FastMap<>();
public L2AuctioneerInstance(int objectId, L2NpcTemplate template)
{
super(objectId, template);
setInstanceType(InstanceType.L2AuctioneerInstance);
}
@Override
public void onBypassFeedback(L2PcInstance player, String command)
{
int condition = validateCondition(player);
if (condition <= COND_ALL_FALSE)
{
// TODO: html
player.sendMessage("Wrong conditions.");
return;
}
else if (condition == COND_BUSY_BECAUSE_OF_SIEGE)
{
String filename = "data/html/auction/auction-busy.htm";
NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
html.setFile(player.getHtmlPrefix(), filename);
html.replace("%objectId%", String.valueOf(getObjectId()));
player.sendPacket(html);
return;
}
else if (condition == COND_REGULAR)
{
StringTokenizer st = new StringTokenizer(command, " ");
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
{
int days = Integer.parseInt(val);
try
{
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm");
long bid = 0;
if (st.countTokens() >= 1)
{
bid = Math.min(Long.parseLong(st.nextToken()), MAX_ADENA);
}
Auction a = new Auction(player.getClan().getHasHideout(), player.getClan(), days * 86400000L, bid, ClanHallManager.getInstance().getClanHallByOwner(player.getClan()).getName());
if (_pendingAuctions.get(a.getId()) != null)
{
_pendingAuctions.remove(a.getId());
}
_pendingAuctions.put(a.getId(), a);
String filename = "data/html/auction/AgitSale3.htm";
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(player.getHtmlPrefix(), filename);
html.replace("%x%", val);
html.replace("%AGIT_AUCTION_END%", String.valueOf(format.format(a.getEndDate())));
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("%AGIT_LINK_BACK%", "bypass -h npc_" + getObjectId() + "_sale2");
html.replace("%objectId%", String.valueOf((getObjectId())));
player.sendPacket(html);
}
catch (Exception e)
{
player.sendMessage("Invalid bid!");
}
}
catch (Exception e)
{
player.sendMessage("Invalid auction duration!");
}
return;
}
else if (actualCommand.equalsIgnoreCase("confirmAuction"))
{
try
{
Auction a = _pendingAuctions.get(player.getClan().getHasHideout());
a.confirmAuction();
_pendingAuctions.remove(player.getClan().getHasHideout());
}
catch (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
{
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm");
int auctionId = Integer.parseInt(val);
if (Config.DEBUG)
{
_log.warning("auction test started");
}
String filename = "data/html/auction/AgitAuctionInfo.htm";
Auction a = AuctionManager.getInstance().getAuction(auctionId);
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(player.getHtmlPrefix(), 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%", String.valueOf(format.format(a.getEndDate())));
html.replace("%AGIT_AUCTION_REMAIN%", String.valueOf((a.getEndDate() - System.currentTimeMillis()) / 3600000) + " hours " + String.valueOf((((a.getEndDate() - System.currentTimeMillis()) / 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 (Exception e)
{
player.sendMessage("Invalid auction!");
}
return;
}
else if (actualCommand.equalsIgnoreCase("bid"))
{
if (val.isEmpty())
{
return;
}
try
{
int auctionId = Integer.parseInt(val);
try
{
long bid = 0;
if (st.countTokens() >= 1)
{
bid = Math.min(Long.parseLong(st.nextToken()), MAX_ADENA);
}
AuctionManager.getInstance().getAuction(auctionId).setBid(player, bid);
}
catch (Exception e)
{
player.sendMessage("Invalid bid!");
}
}
catch (Exception e)
{
player.sendMessage("Invalid auction!");
}
return;
}
else if (actualCommand.equalsIgnoreCase("bid1"))
{
if ((player.getClan() == null) || (player.getClan().getLevel() < 2))
{
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.AUCTION_ONLY_CLAN_LEVEL_2_HIGHER));
return;
}
if (val.isEmpty())
{
return;
}
if (((player.getClan().getAuctionBiddedAt() > 0) && (player.getClan().getAuctionBiddedAt() != Integer.parseInt(val))) || (player.getClan().getHasHideout() > 0))
{
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.ALREADY_SUBMITTED_BID));
return;
}
try
{
String filename = "data/html/auction/AgitBid1.htm";
long minimumBid = AuctionManager.getInstance().getAuction(Integer.parseInt(val)).getHighestBidderMaxBid();
if (minimumBid == 0)
{
minimumBid = AuctionManager.getInstance().getAuction(Integer.parseInt(val)).getStartingBid();
}
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(player.getHtmlPrefix(), 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));
html.replace("npc_%objectId%_bid", "npc_" + getObjectId() + "_bid " + val);
player.sendPacket(html);
return;
}
catch (Exception e)
{
player.sendMessage("Invalid auction!");
}
return;
}
else if (actualCommand.equalsIgnoreCase("list"))
{
List<Auction> auctions = AuctionManager.getInstance().getAuctions();
SimpleDateFormat format = new SimpleDateFormat("yy/MM/dd");
/** Limit for make new page, prevent client crash **/
int limit = 15;
int start;
int i = 1;
double npage = Math.ceil((float) auctions.size() / limit);
if (val.isEmpty())
{
start = 1;
}
else
{
start = (limit * (Integer.parseInt(val) - 1)) + 1;
limit *= Integer.parseInt(val);
}
if (Config.DEBUG)
{
_log.warning("cmd list: auction test started");
}
String items = "";
items += "<table width=280 border=0><tr>";
for (int j = 1; j <= npage; j++)
{
items += "<td><center><a action=\"bypass -h npc_" + getObjectId() + "_list " + j + "\"> Page " + j + " </a></center></td>";
}
items += "</tr></table>" + "<table width=280 border=0>";
for (Auction a : auctions)
{
if (a == null)
{
continue;
}
if (i > limit)
{
break;
}
else if (i < start)
{
i++;
continue;
}
else
{
i++;
}
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>" + format.format(a.getEndDate()) + "</td>" + "<td>" + a.getStartingBid() + "</td>" + "</tr>";
}
items += "</table>";
String filename = "data/html/auction/AgitAuctionList.htm";
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(player.getHtmlPrefix(), filename);
html.replace("%AGIT_LINK_BACK%", "bypass -h npc_" + getObjectId() + "_start");
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 = "";
Map<Integer, Bidder> bidders = AuctionManager.getInstance().getAuction(auctionId).getBidders();
for (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>";
}
String filename = "data/html/auction/AgitBidderList.htm";
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(player.getHtmlPrefix(), filename);
html.replace("%AGIT_LIST%", biders);
html.replace("%AGIT_LINK_BACK%", "bypass -h npc_" + getObjectId() + "_selectedItems");
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))
{
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm");
String filename = "data/html/auction/AgitBidInfo.htm";
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(player.getHtmlPrefix(), filename);
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%", String.valueOf(format.format(a.getEndDate())));
html.replace("%AGIT_AUCTION_REMAIN%", String.valueOf((a.getEndDate() - System.currentTimeMillis()) / 3600000) + " hours " + String.valueOf((((a.getEndDate() - System.currentTimeMillis()) / 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()));
html.replace("%AGIT_LINK_BACK%", "bypass -h npc_" + getObjectId() + "_start");
}
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))
{
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm");
String filename = "data/html/auction/AgitSaleInfo.htm";
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(player.getHtmlPrefix(), filename);
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%", String.valueOf(format.format(a.getEndDate())));
html.replace("%AGIT_AUCTION_REMAIN%", String.valueOf((a.getEndDate() - System.currentTimeMillis()) / 3600000) + " hours " + String.valueOf((((a.getEndDate() - System.currentTimeMillis()) / 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("%AGIT_LINK_BACK%", "bypass -h npc_" + getObjectId() + "_start");
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))
{
int ItemId = player.getClan().getHasHideout();
String filename = "data/html/auction/AgitInfo.htm";
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(player.getHtmlPrefix(), filename);
if (ClanHallManager.getInstance().getClanHallById(ItemId) != null)
{
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("%AGIT_LINK_BACK%", "bypass -h npc_" + getObjectId() + "_start");
html.replace("%objectId%", String.valueOf(getObjectId()));
}
else
{
_log.warning("Clan Hall ID NULL : " + ItemId + " Can be caused by concurent write in ClanHallManager");
}
player.sendPacket(html);
return;
}
else if ((player.getClan() != null) && (player.getClan().getHasHideout() == 0))
{
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.NO_OFFERINGS_OWN_OR_MADE_BID_FOR));
return;
}
else if (player.getClan() == null)
{
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.CANNOT_PARTICIPATE_IN_AN_AUCTION));
return;
}
}
else if (actualCommand.equalsIgnoreCase("cancelBid"))
{
long bid = AuctionManager.getInstance().getAuction(player.getClan().getAuctionBiddedAt()).getBidders().get(player.getClanId()).getBid();
String filename = "data/html/auction/AgitBidCancel.htm";
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(player.getHtmlPrefix(), filename);
html.replace("%AGIT_BID%", String.valueOf(bid));
html.replace("%AGIT_BID_REMAIN%", String.valueOf((long) (bid * 0.9)));
html.replace("%AGIT_LINK_BACK%", "bypass -h npc_" + getObjectId() + "_selectedItems");
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.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.CANCELED_BID));
}
return;
}
else if (actualCommand.equalsIgnoreCase("cancelAuction"))
{
if (!((player.getClanPrivileges() & L2Clan.CP_CH_AUCTION) == L2Clan.CP_CH_AUCTION))
{
String filename = "data/html/auction/not_authorized.htm";
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(player.getHtmlPrefix(), filename);
html.replace("%objectId%", String.valueOf(getObjectId()));
player.sendPacket(html);
return;
}
String filename = "data/html/auction/AgitSaleCancel.htm";
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(player.getHtmlPrefix(), filename);
html.replace("%AGIT_DEPOSIT%", String.valueOf(ClanHallManager.getInstance().getClanHallByOwner(player.getClan()).getLease()));
html.replace("%AGIT_LINK_BACK%", "bypass -h npc_" + getObjectId() + "_selectedItems");
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"))
{
String filename = "data/html/auction/AgitSale2.htm";
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(player.getHtmlPrefix(), filename);
html.replace("%AGIT_LAST_PRICE%", String.valueOf(ClanHallManager.getInstance().getClanHallByOwner(player.getClan()).getLease()));
html.replace("%AGIT_LINK_BACK%", "bypass -h npc_" + getObjectId() + "_sale");
html.replace("%objectId%", String.valueOf(getObjectId()));
player.sendPacket(html);
return;
}
else if (actualCommand.equalsIgnoreCase("sale"))
{
if (!((player.getClanPrivileges() & L2Clan.CP_CH_AUCTION) == L2Clan.CP_CH_AUCTION))
{
String filename = "data/html/auction/not_authorized.htm";
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(player.getHtmlPrefix(), filename);
html.replace("%objectId%", String.valueOf(getObjectId()));
player.sendPacket(html);
return;
}
String filename = "data/html/auction/AgitSale1.htm";
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(player.getHtmlPrefix(), 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("%AGIT_LINK_BACK%", "bypass -h npc_" + getObjectId() + "_selectedItems");
html.replace("%objectId%", String.valueOf(getObjectId()));
player.sendPacket(html);
return;
}
else if (actualCommand.equalsIgnoreCase("rebid"))
{
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm");
if (!((player.getClanPrivileges() & L2Clan.CP_CH_AUCTION) == L2Clan.CP_CH_AUCTION))
{
String filename = "data/html/auction/not_authorized.htm";
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(player.getHtmlPrefix(), filename);
html.replace("%objectId%", String.valueOf(getObjectId()));
player.sendPacket(html);
return;
}
try
{
String filename = "data/html/auction/AgitBid2.htm";
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(player.getHtmlPrefix(), filename);
Auction a = AuctionManager.getInstance().getAuction(player.getClan().getAuctionBiddedAt());
if (a != null)
{
html.replace("%AGIT_AUCTION_BID%", String.valueOf(a.getBidders().get(player.getClanId()).getBid()));
html.replace("%AGIT_AUCTION_MINBID%", String.valueOf(a.getStartingBid()));
html.replace("%AGIT_AUCTION_END%", String.valueOf(format.format(a.getEndDate())));
html.replace("%AGIT_LINK_BACK%", "bypass -h npc_" + getObjectId() + "_selectedItems");
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 (Exception e)
{
player.sendMessage("Invalid auction!");
}
return;
}
else if (actualCommand.equalsIgnoreCase("location"))
{
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(player.getHtmlPrefix(), "data/html/auction/location.htm");
html.replace("%location%", MapRegionTable.getInstance().getClosestTownName(player));
html.replace("%LOCATION%", getPictureName(player));
html.replace("%AGIT_LINK_BACK%", "bypass -h npc_" + getObjectId() + "_start");
player.sendPacket(html);
return;
}
else if (actualCommand.equalsIgnoreCase("start"))
{
showChatWindow(player);
return;
}
}
super.onBypassFeedback(player, command);
}
@Override
public void showChatWindow(L2PcInstance player)
{
String filename = "data/html/auction/auction-no.htm";
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";
}
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(player.getHtmlPrefix(), 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)
{
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 14:
nearestTown = "RUNE";
break;
case 15:
nearestTown = "GODARD";
break;
case 16:
nearestTown = "SCHUTTGART";
break;
default:
nearestTown = "ADEN";
break;
}
return nearestTown;
}
}
@@ -0,0 +1,366 @@
/*
* 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.l2jserver.gameserver.model.actor.instance;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Future;
import javolution.util.FastList;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.ai.CtrlIntention;
import com.l2jserver.gameserver.datatables.PetDataTable;
import com.l2jserver.gameserver.datatables.SkillTable;
import com.l2jserver.gameserver.model.L2Effect;
import com.l2jserver.gameserver.model.L2ItemInstance;
import com.l2jserver.gameserver.model.L2PetData.L2PetSkillLearn;
import com.l2jserver.gameserver.model.L2Skill;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
import com.l2jserver.gameserver.skills.SkillHolder;
import com.l2jserver.gameserver.templates.chars.L2NpcTemplate;
import com.l2jserver.util.Rnd;
/**
* This class ...
* @version $Revision: 1.15.2.10.2.16 $ $Date: 2005/04/06 16:13:40 $
*/
public final class L2BabyPetInstance extends L2PetInstance
{
private static final int BUFF_CONTROL = 5771;
private static final int AWAKENING = 5753;
protected FastList<SkillHolder> _buffs = null;
protected SkillHolder _majorHeal = null;
protected SkillHolder _minorHeal = null;
protected SkillHolder _recharge = null;
private Future<?> _castTask;
protected boolean _bufferMode = true;
public L2BabyPetInstance(int objectId, L2NpcTemplate template, L2PcInstance owner, L2ItemInstance control)
{
super(objectId, template, owner, control);
setInstanceType(InstanceType.L2BabyPetInstance);
}
public L2BabyPetInstance(int objectId, L2NpcTemplate template, L2PcInstance owner, L2ItemInstance control, byte level)
{
super(objectId, template, owner, control, level);
setInstanceType(InstanceType.L2BabyPetInstance);
}
@Override
public void onSpawn()
{
super.onSpawn();
L2Skill skill;
double healPower = 0;
for (L2PetSkillLearn psl : PetDataTable.getInstance().getPetData(getNpcId()).getAvailableSkills())
{
int id = psl.getId();
int lvl = PetDataTable.getInstance().getPetData(getNpcId()).getAvailableLevel(id, getLevel());
if (lvl == 0)
{
continue;
}
skill = SkillTable.getInstance().getInfo(id, lvl);
if (skill != null)
{
if ((skill.getId() == BUFF_CONTROL) || (skill.getId() == AWAKENING))
{
continue;
}
switch (skill.getSkillType())
{
case HEAL:
if (healPower == 0)
{
// set both heal types to the same skill
_majorHeal = new SkillHolder(skill);
_minorHeal = _majorHeal;
healPower = skill.getPower();
}
else
{
// another heal skill found - search for most powerful
if (skill.getPower() > healPower)
{
_majorHeal = new SkillHolder(skill);
}
else
{
_minorHeal = new SkillHolder(skill);
}
}
break;
case BUFF:
if (_buffs == null)
{
_buffs = new FastList<>();
}
_buffs.add(new SkillHolder(skill));
break;
case MANAHEAL:
case MANARECHARGE:
_recharge = new SkillHolder(skill);
break;
}
}
}
startCastTask();
}
@Override
public boolean doDie(L2Character killer)
{
if (!super.doDie(killer))
{
return false;
}
stopCastTask();
abortCast();
return true;
}
@Override
public synchronized void unSummon(L2PcInstance owner)
{
stopCastTask();
abortCast();
super.unSummon(owner);
}
@Override
public void doRevive()
{
super.doRevive();
startCastTask();
}
@Override
public void onDecay()
{
super.onDecay();
if (_buffs != null)
{
_buffs.clear();
}
}
private final void startCastTask()
{
if (((_majorHeal != null) || (_buffs != null) || (_recharge != null)) && (_castTask == null) && !isDead())
{
_castTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new CastTask(this), 3000, 1000);
}
}
public void switchMode()
{
_bufferMode = !_bufferMode;
}
private final void stopCastTask()
{
if (_castTask != null)
{
_castTask.cancel(false);
_castTask = null;
}
}
protected void castSkill(L2Skill skill)
{
// 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 = getFollowStatus();
// pet not following and owner outside cast range
if (!previousFollowStatus && !isInsideRadius(getOwner(), skill.getCastRange(), true, true))
{
return;
}
setTarget(getOwner());
useMagic(skill, false, false);
SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.PET_USES_S1);
msg.addSkillName(skill);
getOwner().sendPacket(msg);
// 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 != getFollowStatus())
{
setFollowStatus(previousFollowStatus);
}
}
private class CastTask implements Runnable
{
private final L2BabyPetInstance _baby;
private final List<L2Skill> _currentBuffs = new FastList<>();
public CastTask(L2BabyPetInstance baby)
{
_baby = baby;
}
@Override
public void run()
{
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 != null) && !owner.isDead() && !owner.isInvul() && !_baby.isCastingNow() && !_baby.isBetrayed() && !_baby.isMuted() && !_baby.isOutOfControl() && _bufferMode && (_baby.getAI().getIntention() != CtrlIntention.AI_INTENTION_CAST))
{
L2Skill skill = null;
if (_majorHeal != null)
{
/**
* If the owner's HP is more than 80% for Baby Pets and 70% for Improved Baby pets, do nothing. If the owner's HP is very low, under 15% for Baby pets and under 30% for Improved Baby Pets, have 75% chances of using a strong heal. Otherwise, have 25% chances for weak heal.
*/
final double hpPercent = owner.getCurrentHp() / owner.getMaxHp();
final boolean isImprovedBaby = PetDataTable.isImprovedBaby(getNpcId());
if ((isImprovedBaby && (hpPercent < 0.3)) || (!isImprovedBaby && (hpPercent < 0.15)))
{
skill = _majorHeal.getSkill();
if (!_baby.isSkillDisabled(skill) && (Rnd.get(100) <= 75))
{
if (_baby.getCurrentMp() >= skill.getMpConsume())
{
castSkill(skill);
return;
}
}
}
else if ((_majorHeal.getSkill() != _minorHeal.getSkill()) && ((isImprovedBaby && (hpPercent < 0.7)) || (!isImprovedBaby && (hpPercent < 0.8))))
{
// Cast _minorHeal only if it's different than _majorHeal, then pet has two heals available.
skill = _minorHeal.getSkill();
if (!_baby.isSkillDisabled(skill) && (Rnd.get(100) <= 25))
{
if (_baby.getCurrentMp() >= skill.getMpConsume())
{
castSkill(skill);
return;
}
}
}
}
if (_baby.getFirstEffect(BUFF_CONTROL) == null) // Buff Control is not active
{
// searching for usable buffs
if ((_buffs != null) && !_buffs.isEmpty())
{
for (SkillHolder i : _buffs)
{
skill = i.getSkill();
if (_baby.isSkillDisabled(skill))
{
continue;
}
if (_baby.getCurrentMp() >= skill.getMpConsume())
{
_currentBuffs.add(skill);
}
}
}
// buffs found, checking owner buffs
if (!_currentBuffs.isEmpty())
{
L2Effect[] effects = owner.getAllEffects();
Iterator<L2Skill> iter;
L2Skill currentSkill;
for (L2Effect e : effects)
{
if (e == null)
{
continue;
}
currentSkill = e.getSkill();
// skipping debuffs, passives, toggles
if (currentSkill.isDebuff() || currentSkill.isPassive() || currentSkill.isToggle())
{
continue;
}
// if buff does not need to be casted - remove it from list
iter = _currentBuffs.iterator();
while (iter.hasNext())
{
skill = iter.next();
if ((currentSkill.getId() == skill.getId()) && (currentSkill.getLevel() >= skill.getLevel()))
{
iter.remove();
}
else
{
// effect with same stacktype and greater or equal stackorder
if (skill.hasEffects() && !"none".equals(skill.getEffectTemplates()[0].abnormalType) && e.getAbnormalType().equals(skill.getEffectTemplates()[0].abnormalType) && (e.getAbnormalLvl() >= skill.getEffectTemplates()[0].abnormalLvl))
{
iter.remove();
}
}
}
// no more buffs in list
if (_currentBuffs.isEmpty())
{
break;
}
}
// buffs list ready, casting random
if (!_currentBuffs.isEmpty())
{
castSkill(_currentBuffs.get(Rnd.get(_currentBuffs.size())));
_currentBuffs.clear();
return;
}
}
}
// buffs/heal not casted, trying recharge, if exist
if ((_recharge != null) && owner.isInCombat() // recharge casted only if owner in combat stance
&& ((owner.getCurrentMp() / owner.getMaxMp()) < 0.6) && (Rnd.get(100) <= 60))
{
skill = _recharge.getSkill();
if (!_baby.isSkillDisabled(skill) && (_baby.getCurrentMp() >= skill.getMpConsume()))
{
castSkill(skill);
return;
}
}
}
}
}
}
@@ -0,0 +1,187 @@
/*
* 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.l2jserver.gameserver.model.actor.instance;
import com.l2jserver.gameserver.datatables.ItemTable;
import com.l2jserver.gameserver.instancemanager.HandysBlockCheckerManager.ArenaParticipantsHolder;
import com.l2jserver.gameserver.model.L2ItemInstance;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.entity.BlockCheckerEngine;
import com.l2jserver.gameserver.network.serverpackets.AbstractNpcInfo;
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
import com.l2jserver.gameserver.network.serverpackets.ExCubeGameChangePoints;
import com.l2jserver.gameserver.network.serverpackets.ExCubeGameExtendedChangePoints;
import com.l2jserver.gameserver.network.serverpackets.MyTargetSelected;
import com.l2jserver.gameserver.network.serverpackets.StatusUpdate;
import com.l2jserver.gameserver.network.serverpackets.ValidateLocation;
import com.l2jserver.gameserver.templates.chars.L2NpcTemplate;
import com.l2jserver.util.Rnd;
/**
* @author BiggBoss
*/
public class L2BlockInstance extends L2MonsterInstance
{
private int _colorEffect;
/**
* @param objectId
* @param template
*/
public L2BlockInstance(int objectId, L2NpcTemplate template)
{
super(objectId, template);
setHideName(true);
}
/**
* Will change the color of the block and update the appearance in the known players clients
*/
public void changeColor(L2PcInstance attacker, ArenaParticipantsHolder holder, int team)
{
// Do not update color while sending old info
synchronized (this)
{
final BlockCheckerEngine event = holder.getEvent();
if (_colorEffect == 0x53)
{
// Change color
_colorEffect = 0x00;
// BroadCast to all known players
this.broadcastPacket(new AbstractNpcInfo.NpcInfo(this, attacker));
increaseTeamPointsAndSend(attacker, team, event);
}
else
{
// Change color
_colorEffect = 0x53;
// BroadCast to all known players
this.broadcastPacket(new AbstractNpcInfo.NpcInfo(this, attacker));
increaseTeamPointsAndSend(attacker, team, event);
}
// 30% chance to drop the event items
int random = Rnd.get(100);
// Bond
if ((random > 69) && (random <= 84))
{
dropItem(13787, event, attacker);
}
else if (random > 84)
{
dropItem(13788, event, attacker);
}
}
}
/**
* Sets if the block is red or blue. Mainly used in block spawn
* @param isRed
*/
public void setRed(boolean isRed)
{
_colorEffect = isRed ? 0x53 : 0x00;
}
/**
* Return if the block is red at this momment
* @return
*/
@Override
public int getColorEffect()
{
return _colorEffect;
}
@Override
public boolean isAutoAttackable(L2Character attacker)
{
if (attacker instanceof L2PcInstance)
{
return (attacker.getActingPlayer() != null) && (attacker.getActingPlayer().getBlockCheckerArena() > -1);
}
return true;
}
@Override
public boolean isAttackable()
{
return true;
}
@Override
public boolean doDie(L2Character killer)
{
return false;
}
@Override
public void onAction(L2PcInstance player, boolean interact)
{
if (!canTarget(player))
{
return;
}
player.setLastFolkNPC(this);
if (player.getTarget() != this)
{
player.setTarget(this);
getAI(); // wake up ai
// Send a Server->Client packet MyTargetSelected to the L2PcInstance activeChar
// The activeChar.getLevel() - getLevel() permit to display the correct color in the select window
MyTargetSelected my = new MyTargetSelected(getObjectId(), player.getLevel() - getLevel());
player.sendPacket(my);
// Send a Server->Client packet StatusUpdate of the L2Npc to the L2PcInstance to update its HP bar
StatusUpdate su = new StatusUpdate(this);
su.addAttribute(StatusUpdate.CUR_HP, (int) getCurrentHp());
su.addAttribute(StatusUpdate.MAX_HP, getMaxHp());
player.sendPacket(su);
player.sendPacket(new ValidateLocation(this));
}
else if (interact)
{
player.sendPacket(new ValidateLocation(this));
player.sendPacket(ActionFailed.STATIC_PACKET);
}
}
private void increaseTeamPointsAndSend(L2PcInstance player, int team, BlockCheckerEngine eng)
{
eng.increasePlayerPoints(player, team);
int timeLeft = (int) ((eng.getStarterTime() - System.currentTimeMillis()) / 1000);
boolean isRed = eng.getHolder().getRedPlayers().contains(player);
ExCubeGameChangePoints changePoints = new ExCubeGameChangePoints(timeLeft, eng.getBluePoints(), eng.getRedPoints());
ExCubeGameExtendedChangePoints secretPoints = new ExCubeGameExtendedChangePoints(timeLeft, eng.getBluePoints(), eng.getRedPoints(), isRed, player, eng.getPlayerPoints(player, isRed));
eng.getHolder().broadCastPacketToTeam(changePoints);
eng.getHolder().broadCastPacketToTeam(secretPoints);
}
private void dropItem(int id, BlockCheckerEngine eng, L2PcInstance player)
{
L2ItemInstance drop = ItemTable.getInstance().createItem("Loot", id, 1, player, this);
int x = getX() + Rnd.get(50);
int y = getY() + Rnd.get(50);
int z = getZ();
drop.dropMe(this, x, y, z);
eng.addNewDrop(drop);
}
}
@@ -0,0 +1,90 @@
/*
* 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.l2jserver.gameserver.model.actor.instance;
import java.util.logging.Logger;
import com.l2jserver.gameserver.ai.L2BoatAI;
import com.l2jserver.gameserver.model.L2CharPosition;
import com.l2jserver.gameserver.model.Location;
import com.l2jserver.gameserver.model.actor.L2Vehicle;
import com.l2jserver.gameserver.network.serverpackets.VehicleDeparture;
import com.l2jserver.gameserver.network.serverpackets.VehicleInfo;
import com.l2jserver.gameserver.network.serverpackets.VehicleStarted;
import com.l2jserver.gameserver.templates.chars.L2CharTemplate;
/**
* @author Maktakien, reworked by DS
*/
public class L2BoatInstance extends L2Vehicle
{
protected static final Logger _logBoat = Logger.getLogger(L2BoatInstance.class.getName());
public L2BoatInstance(int objectId, L2CharTemplate template)
{
super(objectId, template);
setInstanceType(InstanceType.L2BoatInstance);
setAI(new L2BoatAI(new AIAccessor()));
}
@Override
public boolean isBoat()
{
return true;
}
@Override
public boolean moveToNextRoutePoint()
{
final boolean result = super.moveToNextRoutePoint();
if (result)
{
broadcastPacket(new VehicleDeparture(this));
}
return result;
}
@Override
public void oustPlayer(L2PcInstance player)
{
super.oustPlayer(player);
final Location loc = getOustLoc();
if (player.isOnline())
{
player.teleToLocation(loc.getX(), loc.getY(), loc.getZ());
}
else
{
player.setXYZInvisible(loc.getX(), loc.getY(), loc.getZ()); // disconnects handling
}
}
@Override
public void stopMove(L2CharPosition pos, boolean updateKnownObjects)
{
super.stopMove(pos, updateKnownObjects);
broadcastPacket(new VehicleStarted(this, 0));
broadcastPacket(new VehicleInfo(this));
}
@Override
public void sendInfo(L2PcInstance activeChar)
{
activeChar.sendPacket(new VehicleInfo(this));
}
}

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