Sync with L2JServer Jan 2nd 2015.

This commit is contained in:
mobius
2015-01-02 16:44:45 +00:00
parent 94b2621431
commit 54c0ceafb8
439 changed files with 63249 additions and 62327 deletions

View File

@@ -280,7 +280,6 @@ public class GameServer
ItemAuctionManager.getInstance();
CastleManager.getInstance().loadInstances();
NpcBufferTable.getInstance();
DayNightSpawnManager.getInstance().trim().notifyChangeMode();
GrandBossManager.getInstance().initZones();
EventDroplist.getInstance();
@@ -324,6 +323,7 @@ public class GameServer
}
SpawnTable.getInstance().load();
DayNightSpawnManager.getInstance().trim().notifyChangeMode();
FourSepulchersManager.getInstance().init();
RaidBossSpawnManager.getInstance();

View File

@@ -95,6 +95,8 @@ public class ItemTable
_slots.put("hatchling", L2Item.SLOT_HATCHLING);
_slots.put("strider", L2Item.SLOT_STRIDER);
_slots.put("babypet", L2Item.SLOT_BABYPET);
_slots.put("brooch", L2Item.SLOT_BROOCH);
_slots.put("brooch_jewel", L2Item.SLOT_BROOCH_JEWEL);
_slots.put("none", L2Item.SLOT_NONE);
// retail compatibility

View File

@@ -235,6 +235,9 @@ public final class SkillTreesData implements DocumentParser
case "subClassConditions":
skillLearn.addSubclassConditions(parseInteger(attrs, "slot"), parseInteger(attrs, "lvl"));
break;
case "removeSkill":
skillLearn.addRemoveSkills(parseInteger(attrs, "id"));
break;
}
}

View File

@@ -146,12 +146,7 @@ public interface DocumentParser
*/
default boolean parseDatapackDirectory(String path, boolean recursive)
{
File dir = new File(path);
if (!dir.exists())
{
dir = new File(Config.DATAPACK_ROOT, path);
}
return parseDirectory(dir, recursive);
return parseDirectory(new File(Config.DATAPACK_ROOT, path), recursive);
}
/**

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) 2004-2015 L2J Server
*
* This file is part of L2J Server.
*
* L2J Server 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.
*
* L2J Server 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.enums;
/**
* @author Sdw
*/
public enum MailType
{
REGULAR,
NEWS_INFORMER,
NPC,
BIRTHDAY,
COMMISSION_ITEM_RETURNED,
COMMISSION_ITEM_SOLD,
MENTOR_NPC,
PRIME_SHOP_GIFT
}

View File

@@ -1,158 +0,0 @@
/*
* Copyright (C) 2004-2015 L2J Server
*
* This file is part of L2J Server.
*
* L2J Server 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.
*
* L2J Server 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.awt.Polygon;
import java.awt.Shape;
import javolution.util.FastList;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.util.Rnd;
/**
* Dimensional Rift Room.
* @author xban1x
*/
public final class DimensionalRiftRoom
{
private final byte _type;
private final byte _room;
private final int _xMin;
private final int _xMax;
private final int _yMin;
private final int _yMax;
private final int _zMin;
private final int _zMax;
private final Location _teleportCoords;
private final Shape _s;
private final boolean _isBossRoom;
private final FastList<L2Spawn> _roomSpawns;
protected final FastList<L2Npc> _roomMobs;
private boolean _partyInside = false;
public DimensionalRiftRoom(byte type, byte room, int xMin, int xMax, int yMin, int yMax, int zMin, int zMax, int xT, int yT, int zT, boolean isBossRoom)
{
_type = type;
_room = room;
_xMin = (xMin + 128);
_xMax = (xMax - 128);
_yMin = (yMin + 128);
_yMax = (yMax - 128);
_zMin = zMin;
_zMax = zMax;
_teleportCoords = new Location(xT, yT, zT);
_isBossRoom = isBossRoom;
_roomSpawns = new FastList<>();
_roomMobs = new FastList<>();
_s = new Polygon(new int[]
{
xMin,
xMax,
xMax,
xMin
}, new int[]
{
yMin,
yMin,
yMax,
yMax
}, 4);
}
public byte getType()
{
return _type;
}
public byte getRoom()
{
return _room;
}
public int getRandomX()
{
return Rnd.get(_xMin, _xMax);
}
public int getRandomY()
{
return Rnd.get(_yMin, _yMax);
}
public Location getTeleportCoorinates()
{
return _teleportCoords;
}
public boolean checkIfInZone(int x, int y, int z)
{
return _s.contains(x, y) && (z >= _zMin) && (z <= _zMax);
}
public boolean isBossRoom()
{
return _isBossRoom;
}
public FastList<L2Spawn> getSpawns()
{
return _roomSpawns;
}
public void spawn()
{
for (L2Spawn spawn : _roomSpawns)
{
spawn.doSpawn();
spawn.startRespawn();
}
}
public DimensionalRiftRoom unspawn()
{
for (L2Spawn spawn : _roomSpawns)
{
spawn.stopRespawn();
if (spawn.getLastSpawn() != null)
{
spawn.getLastSpawn().deleteMe();
}
}
return this;
}
/**
* Returns if party is inside the room.
* @return {@code true} if there is a party inside, {@code false} otherwise
*/
public boolean isPartyInside()
{
return _partyInside;
}
/**
* Sets the party inside.
* @param partyInside
*/
public void setPartyInside(boolean partyInside)
{
_partyInside = partyInside;
}
}

View File

@@ -19,7 +19,9 @@
package com.l2jserver.gameserver.model;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.l2jserver.Config;
import com.l2jserver.gameserver.enums.Race;
@@ -48,6 +50,7 @@ public final class L2SkillLearn
private final List<SubClassData> _subClassLvlNumber = new ArrayList<>();
private final boolean _learnedByNpc;
private final boolean _learnedByFS;
private final Set<Integer> _removeSkills = new HashSet<>();
public class SubClassData
{
@@ -272,6 +275,16 @@ public final class L2SkillLearn
return _learnedByFS;
}
public void addRemoveSkills(int skillId)
{
_removeSkills.add(skillId);
}
public Set<Integer> getRemoveSkills()
{
return _removeSkills;
}
/**
* 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>

View File

@@ -476,7 +476,7 @@ public class L2DoorInstance extends L2Character
OnEventTrigger oe = null;
if (getEmitter() > 0)
{
oe = new OnEventTrigger(this, getOpen());
oe = new OnEventTrigger(getEmitter(), getOpen());
}
for (L2PcInstance player : knownPlayers)
@@ -708,7 +708,7 @@ public class L2DoorInstance extends L2Character
{
if (getEmitter() > 0)
{
activeChar.sendPacket(new OnEventTrigger(this, getOpen()));
activeChar.sendPacket(new OnEventTrigger(getEmitter(), getOpen()));
}
activeChar.sendPacket(new StaticObject(this, activeChar.isGM()));

View File

@@ -279,6 +279,7 @@ import com.l2jserver.gameserver.network.serverpackets.ExStorageMaxCount;
import com.l2jserver.gameserver.network.serverpackets.ExSubjobInfo;
import com.l2jserver.gameserver.network.serverpackets.ExUseSharedGroupItem;
import com.l2jserver.gameserver.network.serverpackets.ExUserInfoAbnormalVisualEffect;
import com.l2jserver.gameserver.network.serverpackets.ExUserInfoCubic;
import com.l2jserver.gameserver.network.serverpackets.ExUserInfoInvenWeight;
import com.l2jserver.gameserver.network.serverpackets.FlyToLocation.FlyType;
import com.l2jserver.gameserver.network.serverpackets.GameGuardQuery;
@@ -2188,7 +2189,7 @@ public final class L2PcInstance extends L2Playable
int slot = getInventory().getSlotFromItem(item);
// we can't unequip talisman by body slot
if (slot == L2Item.SLOT_DECO)
if ((slot == L2Item.SLOT_DECO) || (slot == L2Item.SLOT_BROOCH_JEWEL))
{
items = getInventory().unEquipItemInSlotAndRecord(item.getLocationSlot());
}
@@ -4282,7 +4283,6 @@ public final class L2PcInstance extends L2Playable
// Send a Server->Client packet CharInfo to all L2PcInstance in _KnownPlayers of the L2PcInstance
broadcastPacket(new CharInfo(this));
broadcastPacket(new ExBrExtraUserInfo(this));
}
public final void broadcastUserInfo(UserInfoType... types)
@@ -4302,10 +4302,8 @@ public final class L2PcInstance extends L2Playable
UserInfo ui = new UserInfo(this, false);
ui.addComponentType(UserInfoType.CLAN);
sendPacket(ui);
sendPacket(new ExBrExtraUserInfo(this));
// Send a Server->Client packet TitleUpdate to all L2PcInstance in _KnownPlayers of the L2PcInstance
broadcastPacket(new NicknameChanged(this));
}
@@ -9195,7 +9193,8 @@ public final class L2PcInstance extends L2Playable
cubic.cancelDisappear();
}
_cubics.clear();
broadcastUserInfo();
sendPacket(new ExUserInfoCubic(this));
broadcastPacket(new CharInfo(this));
}
}
@@ -9216,7 +9215,8 @@ public final class L2PcInstance extends L2Playable
}
if (broadcast)
{
broadcastUserInfo();
sendPacket(new ExUserInfoCubic(this));
broadcastPacket(new CharInfo(this));
}
}
}
@@ -9568,6 +9568,7 @@ public final class L2PcInstance extends L2Playable
cubic.cancelDisappear();
}
_cubics.clear();
sendPacket(new ExUserInfoCubic(this));
}
if (getParty() != null)

View File

@@ -131,7 +131,7 @@ public final class L2TeleporterInstance extends L2Npc
}
if (shouldPayFee(player, loc))
{
finalName += " - " + loc.getFeeCount() + " " + getItemName(loc.getFeeId(), true);
finalName += " - " + calculateFee(player, type, loc) + " " + getItemName(loc.getFeeId(), true);
}
sb.append("<button align=left icon=" + (!questLocations.contains(loc.getNpcStringId()) ? "teleport" : "quest") + " action=\"bypass -h npc_" + getObjectId() + "_teleport " + type.ordinal() + " " + id + "\" msg=\"811;" + confirmDesc + "\">" + finalName + "</button>");
});
@@ -192,7 +192,7 @@ public final class L2TeleporterInstance extends L2Npc
{
player.sendPacket(SystemMessageId.YOU_CANNOT_TELEPORT_WHILE_IN_POSSESSION_OF_A_WARD);
}
else if (shouldPayFee(player, loc) && !player.destroyItemByItemId("Teleport", loc.getFeeId(), loc.getFeeCount(), this, true))
else if (shouldPayFee(player, loc) && !player.destroyItemByItemId("Teleport", loc.getFeeId(), calculateFee(player, type, loc), this, true))
{
if (loc.getFeeId() == Inventory.ADENA_ID)
{
@@ -217,6 +217,35 @@ public final class L2TeleporterInstance extends L2Npc
}
}
/**
* For characters below level 77 teleport service is free.<br>
* From 8.00 pm to 00.00 from Monday till Tuesday for all characters there's a 50% discount on teleportation services
* @param player
* @param type
* @param loc
* @return
*/
private long calculateFee(L2PcInstance player, TeleportType type, TeleportLocation loc)
{
if (player.getLevel() < 77)
{
return 0;
}
if (type == TeleportType.NORMAL)
{
final Calendar cal = Calendar.getInstance();
final int hour = cal.get(Calendar.HOUR_OF_DAY);
final int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
if ((hour >= 20) && ((dayOfWeek >= Calendar.MONDAY) && (dayOfWeek <= Calendar.TUESDAY)))
{
return loc.getFeeCount() / 2;
}
}
return loc.getFeeCount();
}
protected boolean shouldPayFee(L2PcInstance player, TeleportLocation loc)
{
return Config.ALT_GAME_FREE_TELEPORT || ((player.getLevel() >= 76) && ((loc.getFeeId() != 0) && (loc.getFeeCount() > 0)));

View File

@@ -913,4 +913,13 @@ public class PcStat extends PlayableStat
return bonus;
}
/**
* Gets the maximum brooch jewel count.
* @return the maximum brooch jewel count
*/
public int getBroochJewelSlots()
{
return (int) calcStat(Stats.BROOCH_JEWELS, 0);
}
}

View File

@@ -26,9 +26,11 @@ import java.util.concurrent.ScheduledFuture;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.datatables.CharNameTable;
import com.l2jserver.gameserver.enums.MailType;
import com.l2jserver.gameserver.idfactory.IdFactory;
import com.l2jserver.gameserver.instancemanager.MailManager;
import com.l2jserver.gameserver.model.itemcontainer.Mail;
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
import com.l2jserver.util.Rnd;
/**
@@ -52,7 +54,7 @@ public class Message
private String _receiverName = null;
private final String _subject, _content;
private boolean _unread, _returned;
private int _sendBySystem;
private MailType _messageType;
private boolean _deletedBySender;
private boolean _deletedByReceiver;
private final long _reqAdena;
@@ -60,13 +62,9 @@ public class Message
private Mail _attachments = null;
private ScheduledFuture<?> _unloadTask = null;
public enum SendBySystem
{
PLAYER,
NEWS,
NONE,
ALEGRIA
}
private int _itemId;
private int _enchantLvl;
private final int[] _elementals = new int[6];
/*
* Constructor for restoring from DB.
@@ -84,8 +82,15 @@ public class Message
_unread = rset.getBoolean("isUnread");
_deletedBySender = rset.getBoolean("isDeletedBySender");
_deletedByReceiver = rset.getBoolean("isDeletedByReceiver");
_sendBySystem = rset.getInt("sendBySystem");
_messageType = MailType.values()[rset.getInt("sendBySystem")];
_returned = rset.getBoolean("isReturned");
_itemId = rset.getInt("itemId");
_enchantLvl = rset.getInt("enchantLvl");
final String[] elemDef = rset.getString("elementals").split(";");
for (int i = 0; i < 6; i++)
{
_elementals[i] = Integer.parseInt(elemDef[i]);
}
}
/*
@@ -109,7 +114,7 @@ public class Message
/*
* This constructor used for System Mails
*/
public Message(int receiverId, String subject, String content, SendBySystem sendBySystem)
public Message(int receiverId, String subject, String content, MailType sendBySystem)
{
_messageId = IdFactory.getInstance().getNextId();
_senderId = -1;
@@ -122,10 +127,29 @@ public class Message
_unread = true;
_deletedBySender = true;
_deletedByReceiver = false;
_sendBySystem = sendBySystem.ordinal();
_messageType = sendBySystem;
_returned = false;
}
/*
* This constructor is used for creating new System message
*/
public Message(int senderId, int receiverId, String subject, String content, MailType sendBySystem)
{
_messageId = IdFactory.getInstance().getNextId();
_senderId = senderId;
_receiverId = receiverId;
_subject = subject;
_content = content;
_expiration = System.currentTimeMillis() + (EXPIRATION * 3600000);
_hasAttachments = false;
_unread = true;
_deletedBySender = true;
_deletedByReceiver = false;
_reqAdena = 0;
_messageType = sendBySystem;
}
/*
* This constructor used for auto-generation of the "return attachments" message
*/
@@ -140,7 +164,7 @@ public class Message
_unread = true;
_deletedBySender = true;
_deletedByReceiver = false;
_sendBySystem = SendBySystem.NONE.ordinal();
_messageType = MailType.REGULAR;
_returned = true;
_reqAdena = 0;
_hasAttachments = true;
@@ -150,9 +174,47 @@ public class Message
_unloadTask = ThreadPoolManager.getInstance().scheduleGeneral(new AttachmentsUnloadTask(this), UNLOAD_ATTACHMENTS_INTERVAL + Rnd.get(UNLOAD_ATTACHMENTS_INTERVAL));
}
public Message(int receiverId, L2ItemInstance item, MailType mailType)
{
_messageId = IdFactory.getInstance().getNextId();
_senderId = -1;
_receiverId = receiverId;
_subject = "";
_content = item.getName();
_expiration = System.currentTimeMillis() + (EXPIRATION * 3600000);
_unread = true;
_deletedBySender = true;
_messageType = mailType;
_returned = false;
_reqAdena = 0;
if (mailType == MailType.COMMISSION_ITEM_SOLD)
{
_hasAttachments = false;
_itemId = item.getId();
_enchantLvl = item.getEnchantLevel();
if (item.isArmor())
{
for (int i = 0; i < 6; i++)
{
_elementals[i] = item.getElementDefAttr((byte) i);
}
}
else if (item.isWeapon() && (item.getAttackElementType() >= 0))
{
_elementals[item.getAttackElementType()] = item.getAttackElementPower();
}
}
else if (mailType == MailType.COMMISSION_ITEM_RETURNED)
{
final Mail attachement = createAttachments();
attachement.addItem("CommissionReturnItem", item, null, null);
}
}
public static final PreparedStatement getStatement(Message msg, Connection con) throws SQLException
{
PreparedStatement stmt = con.prepareStatement("INSERT INTO messages (messageId, senderId, receiverId, subject, content, expiration, reqAdena, hasAttachments, isUnread, isDeletedBySender, isDeletedByReceiver, sendBySystem, isReturned) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
PreparedStatement stmt = con.prepareStatement("INSERT INTO messages (messageId, senderId, receiverId, subject, content, expiration, reqAdena, hasAttachments, isUnread, isDeletedBySender, isDeletedByReceiver, sendBySystem, isReturned, itemId, enchantLvl, elementals) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
stmt.setInt(1, msg._messageId);
stmt.setInt(2, msg._senderId);
@@ -165,8 +227,11 @@ public class Message
stmt.setString(9, String.valueOf(msg._unread));
stmt.setString(10, String.valueOf(msg._deletedBySender));
stmt.setString(11, String.valueOf(msg._deletedByReceiver));
stmt.setString(12, String.valueOf(msg._sendBySystem));
stmt.setInt(12, msg._messageType.ordinal());
stmt.setString(13, String.valueOf(msg._returned));
stmt.setInt(14, msg._itemId);
stmt.setInt(15, msg._enchantLvl);
stmt.setString(16, msg._elementals[0] + ";" + msg._elementals[1] + ";" + msg._elementals[2] + ";" + msg._elementals[3] + ";" + msg._elementals[4] + ";" + msg._elementals[5]);
return stmt;
}
@@ -188,17 +253,26 @@ public class Message
public final String getSenderName()
{
if (_senderName == null)
switch (_messageType)
{
if (_sendBySystem != 0)
case REGULAR:
{
return "****";
_senderName = CharNameTable.getInstance().getNameById(_senderId);
break;
}
_senderName = CharNameTable.getInstance().getNameById(_senderId);
if (_senderName == null)
case PRIME_SHOP_GIFT: // Not in client, tbd
{
_senderName = "";
break;
}
case NEWS_INFORMER: // Handled by Sysstring in client
case NPC: // Handled by NpcName in client
case BIRTHDAY: // Handled by Sysstring in client
case COMMISSION_ITEM_SOLD: // Handled by Sysstring in client
case COMMISSION_ITEM_RETURNED: // Handled by Sysstring in client
case MENTOR_NPC: // Handled in client
default:
{
break;
}
}
return _senderName;
@@ -298,9 +372,9 @@ public class Message
}
}
public final int getSendBySystem()
public final MailType getMailType()
{
return _sendBySystem;
return _messageType;
}
public final boolean isReturned()
@@ -339,6 +413,21 @@ public class Message
return _hasAttachments;
}
public int getItemId()
{
return _itemId;
}
public int getEnchantLvl()
{
return _enchantLvl;
}
public int[] getElementals()
{
return _elementals;
}
public final synchronized void removeAttachments()
{
if (_attachments != null)

View File

@@ -820,6 +820,36 @@ public abstract class Inventory extends ItemContainer
}
}
private static final class BroochListener implements PaperdollListener
{
private static BroochListener instance = new BroochListener();
public static BroochListener getInstance()
{
return instance;
}
@Override
public void notifyUnequiped(int slot, L2ItemInstance item, Inventory inventory)
{
if (item.getItem().getBodyPart() == L2Item.SLOT_BROOCH)
{
inventory.unEquipItemInSlot(PAPERDOLL_BROOCH_JEWEL1);
inventory.unEquipItemInSlot(PAPERDOLL_BROOCH_JEWEL2);
inventory.unEquipItemInSlot(PAPERDOLL_BROOCH_JEWEL3);
inventory.unEquipItemInSlot(PAPERDOLL_BROOCH_JEWEL4);
inventory.unEquipItemInSlot(PAPERDOLL_BROOCH_JEWEL5);
inventory.unEquipItemInSlot(PAPERDOLL_BROOCH_JEWEL6);
}
}
// Note (April 3, 2009): Currently on equip, talismans do not display properly, do we need checks here to fix this?
@Override
public void notifyEquiped(int slot, L2ItemInstance item, Inventory inventory)
{
}
}
/**
* Constructor of the inventory
*/
@@ -834,6 +864,7 @@ public abstract class Inventory extends ItemContainer
addPaperdollListener(BowCrossRodListener.getInstance());
addPaperdollListener(ItemSkillsListener.getInstance());
addPaperdollListener(BraceletListener.getInstance());
addPaperdollListener(BroochListener.getInstance());
}
// common
@@ -1026,6 +1057,10 @@ public abstract class Inventory extends ItemContainer
return PAPERDOLL_DECO1; // return first we deal with it later
case L2Item.SLOT_BELT:
return PAPERDOLL_BELT;
case L2Item.SLOT_BROOCH:
return PAPERDOLL_BROOCH;
case L2Item.SLOT_BROOCH_JEWEL:
return PAPERDOLL_BROOCH_JEWEL1;
}
return -1;
}
@@ -1257,6 +1292,17 @@ public abstract class Inventory extends ItemContainer
case PAPERDOLL_BELT:
slot = L2Item.SLOT_BELT;
break;
case PAPERDOLL_BROOCH:
slot = L2Item.SLOT_BROOCH;
break;
case PAPERDOLL_BROOCH_JEWEL1:
case PAPERDOLL_BROOCH_JEWEL2:
case PAPERDOLL_BROOCH_JEWEL3:
case PAPERDOLL_BROOCH_JEWEL4:
case PAPERDOLL_BROOCH_JEWEL5:
case PAPERDOLL_BROOCH_JEWEL6:
slot = L2Item.SLOT_BROOCH_JEWEL;
break;
}
return slot;
}
@@ -1400,6 +1446,12 @@ public abstract class Inventory extends ItemContainer
case L2Item.SLOT_BELT:
pdollSlot = PAPERDOLL_BELT;
break;
case L2Item.SLOT_BROOCH:
pdollSlot = PAPERDOLL_BROOCH;
break;
case L2Item.SLOT_BROOCH_JEWEL:
pdollSlot = PAPERDOLL_BROOCH_JEWEL1;
break;
default:
_log.info("Unhandled slot type: " + slot);
_log.info(StringUtil.getTraceString(Thread.currentThread().getStackTrace()));
@@ -1633,6 +1685,12 @@ public abstract class Inventory extends ItemContainer
setPaperdollItem(PAPERDOLL_GLOVES, null);
setPaperdollItem(PAPERDOLL_CHEST, item);
break;
case L2Item.SLOT_BROOCH:
setPaperdollItem(PAPERDOLL_BROOCH, item);
break;
case L2Item.SLOT_BROOCH_JEWEL:
equipBroochJewel(item);
break;
default:
_log.warning("Unknown body slot " + targetSlot + " for Item ID:" + item.getId());
}
@@ -1807,6 +1865,46 @@ public abstract class Inventory extends ItemContainer
setPaperdollItem(PAPERDOLL_DECO1, item);
}
public int getBroochJewelSlots()
{
return getOwner().getActingPlayer().getStat().getBroochJewelSlots();
}
private void equipBroochJewel(L2ItemInstance item)
{
if (getBroochJewelSlots() == 0)
{
return;
}
// find same (or incompatible) brooch jewel type
for (int i = PAPERDOLL_BROOCH_JEWEL1; i < (PAPERDOLL_BROOCH_JEWEL1 + getBroochJewelSlots()); i++)
{
if (_paperdoll[i] != null)
{
if (getPaperdollItemId(i) == item.getId())
{
// overwtite
setPaperdollItem(i, item);
return;
}
}
}
// no free slot found - put on first free
for (int i = PAPERDOLL_BROOCH_JEWEL1; i < (PAPERDOLL_BROOCH_JEWEL1 + getBroochJewelSlots()); i++)
{
if (_paperdoll[i] == null)
{
setPaperdollItem(i, item);
return;
}
}
// no free slots - put on first
setPaperdollItem(PAPERDOLL_BROOCH_JEWEL1, item);
}
public boolean canEquipCloak()
{
return getOwner().getActingPlayer().getStat().canEquipCloak();

View File

@@ -892,7 +892,7 @@ public class PcInventory extends Inventory
public static int[][] restoreVisibleInventory(int objectId)
{
int[][] paperdoll = new int[31][3];
int[][] paperdoll = new int[33][4];
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement2 = con.prepareStatement("SELECT object_id,item_id,loc_data,enchant_level FROM items WHERE owner_id=? AND loc='PAPERDOLL'"))
{

View File

@@ -101,6 +101,9 @@ public abstract class L2Item extends ListenersContainer implements IIdentifiable
public static final int SLOT_L_BRACELET = 0x200000;
public static final int SLOT_DECO = 0x400000;
public static final int SLOT_BELT = 0x10000000;
public static final int SLOT_BROOCH = 0x20000000;
public static final int SLOT_BROOCH_JEWEL = 0x40000000;
public static final int SLOT_WOLF = -100;
public static final int SLOT_HATCHLING = -101;
public static final int SLOT_STRIDER = -102;

View File

@@ -195,7 +195,10 @@ public enum Stats
REDUCE_DEATH_PENALTY_BY_RAID("reduceDeathPenaltyByRaid"),
// Fishing
FISHING_EXPERTISE("fishingExpertise");
FISHING_EXPERTISE("fishingExpertise"),
// Brooches
BROOCH_JEWELS("broochJewels");
public static final int NUM_STATS = values().length;

View File

@@ -519,6 +519,17 @@ public final class RequestAcquireSkill extends L2GameClientPacket
}
}
if (!s.getRemoveSkills().isEmpty())
{
s.getRemoveSkills().forEach(sk ->
{
if (player.getSkillLevel(sk) > 0)
{
player.removeSkill(sk, true);
}
});
}
// If the player has SP and all required items then consume SP.
if (levelUpSp > 0)
{

View File

@@ -19,6 +19,7 @@
package com.l2jserver.gameserver.network.clientpackets;
import com.l2jserver.Config;
import com.l2jserver.gameserver.enums.MailType;
import com.l2jserver.gameserver.instancemanager.MailManager;
import com.l2jserver.gameserver.model.L2World;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
@@ -81,7 +82,7 @@ public final class RequestRejectPostAttachment extends L2GameClientPacket
return;
}
if (!msg.hasAttachments() || (msg.getSendBySystem() != 0))
if (!msg.hasAttachments() || (msg.getMailType() != MailType.REGULAR))
{
return;
}

View File

@@ -18,7 +18,6 @@
*/
package com.l2jserver.gameserver.network.serverpackets;
import java.util.Collections;
import java.util.List;
import com.l2jserver.gameserver.datatables.SkillData;
@@ -32,28 +31,25 @@ import com.l2jserver.gameserver.model.holders.ItemHolder;
*/
public class AcquireSkillList extends L2GameServerPacket
{
final L2PcInstance _activeChar;
final List<L2SkillLearn> _learnable;
public AcquireSkillList(L2PcInstance activeChar)
{
_activeChar = activeChar;
_learnable = SkillTreesData.getInstance().getAvailableSkills(activeChar, activeChar.getClassId(), false, false);
}
@Override
protected void writeImpl()
{
final List<L2SkillLearn> learnable = SkillTreesData.getInstance().getAvailableSkills(_activeChar, _activeChar.getClassId(), false, false);
List<Integer> re = Collections.emptyList();
writeC(0x90);
writeH(learnable.size());
for (L2SkillLearn skill : learnable)
writeH(_learnable.size());
for (L2SkillLearn skill : _learnable)
{
writeD(skill.getSkillId());
writeH(skill.getSkillLevel());
writeQ(skill.getLevelUpSp());
writeC(skill.getGetLevel());
writeC(0x00); // Dual Class Level Required
writeC(skill.getGetLevel()); // Dual Class Level Required
writeC(skill.getRequiredItems().size());
for (ItemHolder item : skill.getRequiredItems())
{
@@ -61,12 +57,12 @@ public class AcquireSkillList extends L2GameServerPacket
writeQ(item.getCount());
}
writeC(re.size());
for (int skillId : re)
writeC(skill.getRemoveSkills().size());
for (int skillId : skill.getRemoveSkills())
{
writeD(skillId);
writeH(SkillData.getInstance().getMaxLevel(skillId));
}
}
}
}
}

View File

@@ -205,10 +205,7 @@ public class CharInfo extends L2GameServerPacket
writeC(_activeChar.getPrivateStoreType().getId()); // Confirmed
writeH(_activeChar.getCubics().size()); // Confirmed
for (int cubicId : _activeChar.getCubics().keySet())
{
writeH(cubicId); // Confirmed
}
_activeChar.getCubics().keySet().forEach(this::writeH);
writeC(_activeChar.isInPartyMatchRoom() ? 0x01 : 0x00); // Confirmed
@@ -270,4 +267,4 @@ public class CharInfo extends L2GameServerPacket
{
return PAPERDOLL_ORDER;
}
}
}

View File

@@ -154,14 +154,6 @@ public class CharSelectionInfo extends L2GameServerPacket
writeD(charInfoPackage.getPaperdollItemId(slot));
}
writeD(0x00); // Brooch
writeD(0x00); // Jewel 1
writeD(0x00); // Jewel 2
writeD(0x00); // Jewel 3
writeD(0x00); // Jewel 4
writeD(0x00); // Jewel 5
writeD(0x00); // Jewel 6
writeD(0x00); // rhand item visual id
writeD(0x00); // lhand item visual id
writeD(0x00); // gloves item visual id

View File

@@ -21,6 +21,7 @@ package com.l2jserver.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.List;
import com.l2jserver.gameserver.instancemanager.MentorManager;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.network.NpcStringId;
import com.l2jserver.gameserver.network.SystemMessageId;
@@ -59,7 +60,10 @@ public final class CreatureSay extends L2GameServerPacket
{
_mask |= 0x02;
}
// TODO : if mentor, _mask |= 0x04;
if ((MentorManager.getInstance().getMentee(receiver.getObjectId(), sender.getObjectId()) != null) || (MentorManager.getInstance().getMentee(sender.getObjectId(), receiver.getObjectId()) != null))
{
_mask |= 0x04;
}
if ((receiver.getAllyId() > 0) && (receiver.getAllyId() == sender.getAllyId()))
{
_mask |= 0x08;

View File

@@ -19,7 +19,6 @@
package com.l2jserver.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.l2jserver.gameserver.datatables.SkillData;
@@ -37,7 +36,7 @@ public class ExAcquireSkillInfo extends L2GameServerPacket
private final int _spCost;
private final int _minLevel;
private final List<ItemHolder> _itemReq = new ArrayList<>();
private final List<Integer> _skillRem;
private final List<Integer> _skillRem = new ArrayList<>();
/**
* Special constructor for Alternate Skill Learning system.<br>
@@ -53,7 +52,7 @@ public class ExAcquireSkillInfo extends L2GameServerPacket
_spCost = sp;
_minLevel = skillLearn.getGetLevel();
_itemReq.addAll(skillLearn.getRequiredItems());
_skillRem = Collections.emptyList();
_skillRem.addAll(skillLearn.getRemoveSkills());
}
@Override

View File

@@ -18,9 +18,11 @@
*/
package com.l2jserver.gameserver.network.serverpackets;
import com.l2jserver.gameserver.enums.MailType;
import com.l2jserver.gameserver.model.entity.Message;
import com.l2jserver.gameserver.model.itemcontainer.ItemContainer;
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
import com.l2jserver.gameserver.network.SystemMessageId;
/**
* @author Migi, DS
@@ -52,6 +54,23 @@ public class ExReplyReceivedPost extends AbstractItemPacket
{
writeC(0xFE);
writeH(0xAC);
writeD(_msg.getMailType().ordinal()); // GOD
if (_msg.getMailType() == MailType.COMMISSION_ITEM_RETURNED)
{
writeD(SystemMessageId.THE_REGISTRATION_PERIOD_FOR_THE_ITEM_YOU_REGISTERED_HAS_EXPIRED.getId());
writeD(SystemMessageId.THE_AUCTION_HOUSE_REGISTRATION_PERIOD_HAS_EXPIRED_AND_THE_CORRESPONDING_ITEM_IS_BEING_FORWARDED.getId());
}
else if (_msg.getMailType() == MailType.COMMISSION_ITEM_SOLD)
{
writeD(_msg.getItemId());
writeD(_msg.getEnchantLvl());
for (int i = 0; i < 6; i++)
{
writeD(_msg.getElementals()[i]);
}
writeD(SystemMessageId.THE_ITEM_YOU_REGISTERED_HAS_BEEN_SOLD.getId());
writeD(SystemMessageId.S1_HAS_BEEN_SOLD.getId());
}
writeD(_msg.getId());
writeD(_msg.isLocked() ? 1 : 0);
writeD(0x00); // Unknown
@@ -75,6 +94,6 @@ public class ExReplyReceivedPost extends AbstractItemPacket
writeQ(_msg.getReqAdena());
writeD(_msg.hasAttachments() ? 1 : 0);
writeD(_msg.getSendBySystem());
writeD(_msg.isReturned() ? 1 : 0);
}
}

View File

@@ -52,6 +52,7 @@ public class ExReplySentPost extends AbstractItemPacket
{
writeC(0xFE);
writeH(0xAE);
writeD(0x00); // GOD
writeD(_msg.getId());
writeD(_msg.isLocked() ? 1 : 0);
writeS(_msg.getReceiverName());
@@ -66,12 +67,13 @@ public class ExReplySentPost extends AbstractItemPacket
writeItem(item);
writeD(item.getObjectId());
}
writeQ(_msg.getReqAdena());
writeD(_msg.getSendBySystem());
}
else
{
writeD(0x00);
}
writeQ(_msg.getReqAdena());
writeD(_msg.hasAttachments() ? 0x01 : 0x00);
writeD(_msg.isReturned() ? 0x01 : 00);
}
}

View File

@@ -20,8 +20,10 @@ package com.l2jserver.gameserver.network.serverpackets;
import java.util.List;
import com.l2jserver.gameserver.enums.MailType;
import com.l2jserver.gameserver.instancemanager.MailManager;
import com.l2jserver.gameserver.model.entity.Message;
import com.l2jserver.gameserver.network.SystemMessageId;
/**
* @author Migi, DS
@@ -46,22 +48,32 @@ public class ExShowReceivedPostList extends L2GameServerPacket
writeD(_inbox.size());
for (Message msg : _inbox)
{
writeD(msg.getMailType().ordinal());
if (msg.getMailType() == MailType.COMMISSION_ITEM_SOLD)
{
writeD(SystemMessageId.THE_ITEM_YOU_REGISTERED_HAS_BEEN_SOLD.getId());
}
else if (msg.getMailType() == MailType.COMMISSION_ITEM_RETURNED)
{
writeD(SystemMessageId.THE_REGISTRATION_PERIOD_FOR_THE_ITEM_YOU_REGISTERED_HAS_EXPIRED.getId());
}
writeD(msg.getId());
writeS(msg.getSubject());
writeS(msg.getSenderName());
writeD(msg.isLocked() ? 0x01 : 0x00);
writeD(msg.getExpirationSeconds());
writeD(msg.isUnread() ? 0x01 : 0x00);
writeD(0x01);
writeD(((msg.getMailType() == MailType.COMMISSION_ITEM_SOLD) || (msg.getMailType() == MailType.COMMISSION_ITEM_RETURNED)) ? 0 : 1);
writeD(msg.hasAttachments() ? 0x01 : 0x00);
writeD(msg.isReturned() ? 0x01 : 0x00);
writeD(msg.getSendBySystem());
writeD(0x00);
writeD(0x00); // SysString in some case it seems
}
}
else
{
writeD(0x00);
}
writeD(100); // TODO: Find me
writeD(1000); // TODO: Find me
}
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright (C) 2004-2015 L2J Server
*
* This file is part of L2J Server.
*
* L2J Server 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.
*
* L2J Server 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.network.serverpackets;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
/**
* @author Sdw
*/
public class ExUserInfoCubic extends L2GameServerPacket
{
private final L2PcInstance _activeChar;
public ExUserInfoCubic(L2PcInstance cha)
{
_activeChar = cha;
}
@Override
protected void writeImpl()
{
writeC(0xFE);
writeH(0x157);
writeD(_activeChar.getObjectId());
writeH(_activeChar.getCubics().size());
_activeChar.getCubics().keySet().forEach(this::writeH);
writeD(_activeChar.getAgathionId());
}
}

View File

@@ -64,7 +64,15 @@ public abstract class L2GameServerPacket extends SendablePacket<L2GameClient>
Inventory.PAPERDOLL_DECO4,
Inventory.PAPERDOLL_DECO5,
Inventory.PAPERDOLL_DECO6,
Inventory.PAPERDOLL_BELT
Inventory.PAPERDOLL_BELT,
Inventory.PAPERDOLL_BROOCH,
Inventory.PAPERDOLL_BROOCH_JEWEL1,
Inventory.PAPERDOLL_BROOCH_JEWEL2,
Inventory.PAPERDOLL_BROOCH_JEWEL3,
Inventory.PAPERDOLL_BROOCH_JEWEL4,
Inventory.PAPERDOLL_BROOCH_JEWEL5,
Inventory.PAPERDOLL_BROOCH_JEWEL6
};
private static final int[] PAPERDOLL_ORDER_AUGMENT = new int[]

View File

@@ -18,7 +18,6 @@
*/
package com.l2jserver.gameserver.network.serverpackets;
import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
/**
* @author Gnacik, UnAfraid
@@ -28,15 +27,9 @@ public class OnEventTrigger extends L2GameServerPacket
private final int _emitterId;
private final int _enabled;
public OnEventTrigger(L2DoorInstance door, boolean enabled)
public OnEventTrigger(int emitterId, boolean enabled)
{
_emitterId = door.getEmitter();
_enabled = enabled ? 1 : 0;
}
public OnEventTrigger(int id, boolean enabled)
{
_emitterId = id;
_emitterId = emitterId;
_enabled = enabled ? 1 : 0;
}

View File

@@ -19,6 +19,7 @@
package com.l2jserver.gameserver.network.serverpackets;
import com.l2jserver.Config;
import com.l2jserver.gameserver.instancemanager.MentorManager;
import com.l2jserver.gameserver.model.PcCondOverride;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
@@ -46,7 +47,10 @@ public final class TradeStart extends AbstractItemPacket
{
_mask |= 0x02;
}
// TODO : if mentor, _mask |= 0x04;
if ((MentorManager.getInstance().getMentee(player.getObjectId(), _partner.getObjectId()) != null) || (MentorManager.getInstance().getMentee(_partner.getObjectId(), player.getObjectId()) != null))
{
_mask |= 0x04;
}
if ((player.getAllyId() > 0) && (player.getAllyId() == _partner.getAllyId()))
{
_mask |= 0x08;

View File

@@ -1,18 +1,18 @@
/*
* Copyright (C) 2004-2015 L2J Server
*
*
* This file is part of L2J Server.
*
*
* L2J Server 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.
*
*
* L2J Server 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/>.
*/
@@ -314,8 +314,8 @@ public class UserInfo extends AbstractMaskPacket<UserInfoType>
if (containsMask(UserInfoType.SLOTS))
{
writeH(9);
writeC(_activeChar.getInventory().getTalismanSlots());
writeC(_activeChar.getInventory().canEquipCloak() ? 0x01 : 0x00);
writeC(_activeChar.getInventory().getTalismanSlots()); // Confirmed
writeC(_activeChar.getInventory().getBroochJewelSlots()); // Confirmed
writeC(_activeChar.getTeam().getId()); // Confirmed
writeC(0x00); // Red dotted ring on the floor
writeC(0x00);
@@ -386,4 +386,4 @@ public class UserInfo extends AbstractMaskPacket<UserInfoType>
return relation;
}
}
}

View File

@@ -29,6 +29,7 @@ import java.util.logging.Level;
import com.l2jserver.Config;
import com.l2jserver.L2DatabaseFactory;
import com.l2jserver.gameserver.datatables.CharNameTable;
import com.l2jserver.gameserver.enums.MailType;
import com.l2jserver.gameserver.instancemanager.MailManager;
import com.l2jserver.gameserver.model.entity.Message;
import com.l2jserver.gameserver.model.itemcontainer.Mail;
@@ -106,7 +107,7 @@ public class TaskBirthday extends Task
text = text.replace("$s1", String.valueOf(age));
}
Message msg = new Message(playerId, Config.ALT_BIRTHDAY_MAIL_SUBJECT, text, Message.SendBySystem.ALEGRIA);
Message msg = new Message(playerId, Config.ALT_BIRTHDAY_MAIL_SUBJECT, text, MailType.BIRTHDAY);
Mail attachments = msg.createAttachments();
attachments.addItem("Birthday", Config.ALT_BIRTHDAY_GIFT, 1, null, null);