Adapting Appearance Stone system from L2jServer.

This commit is contained in:
mobius
2015-02-25 17:57:47 +00:00
parent a3c6227823
commit 7068b969e5
41 changed files with 2830 additions and 717 deletions

View File

@ -75,7 +75,6 @@ public class ItemInfo
};
private int[] _option;
private int _visualId;
private long _visualExpiration;
@ -152,13 +151,13 @@ public class ItemInfo
}
_option = item.getEnchantOptions();
_visualId = item.getVisualId();
_visualExpiration = item.getAppearanceTime();
}
public ItemInfo(L2ItemInstance item, int change)
{
this(item);
_change = change;
_visualExpiration = item.getVisualLifeTime() > 0 ? (item.getVisualLifeTime() - System.currentTimeMillis()) / 1000 : 0;
}
public ItemInfo(TradeItem item)
@ -201,8 +200,9 @@ public class ItemInfo
_change = 0;
// Get shadow item mana
_mana = item.getMana();
_time = item.isTimeLimitedItem() ? (int) (item.getRemainingTime() / 1000) : -9999;
_mana = -1;
_time = -9999;
_location = item.getLocationSlot();
_elemAtkType = item.getAttackElementType();
@ -211,9 +211,9 @@ public class ItemInfo
{
_elemDefAttr[i] = item.getElementDefAttr(i);
}
_option = item.getEnchantOptions();
_visualId = item.getVisualId();
_visualExpiration = item.getVisualExpiration();
}
public ItemInfo(Product item)
@ -303,8 +303,6 @@ public class ItemInfo
_elemDefAttr[i] = item.getElementDefAttr(i);
}
_option = item.getEnchantOptions();
_visualId = item.getAppearanceId();
_visualExpiration = item.getAppearanceTime();
}
public int getObjectId()
@ -364,7 +362,7 @@ public class ItemInfo
public int getTime()
{
return _time;
return _time > 0 ? _time : _visualExpiration > 0 ? (int) _visualExpiration : -9999;
}
public int getLocation()

View File

@ -33,6 +33,7 @@ import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
*/
public final class L2ArmorSet
{
private boolean _isVisual;
private int _minimumPieces;
private final List<Integer> _chests;
private final List<Integer> _legs;
@ -75,6 +76,16 @@ public final class L2ArmorSet
_enchantSkills = new ArrayList<>();
}
public boolean isVisual()
{
return _isVisual;
}
public void setIsVisual(boolean val)
{
_isVisual = val;
}
/**
* @return the minimum amount of pieces equipped to form a set.
*/
@ -329,6 +340,39 @@ public final class L2ArmorSet
}
public int getVisualPiecesCount(L2PcInstance player)
{
final Inventory inv = player.getInventory();
final L2ItemInstance legsItem = inv.getPaperdollItem(Inventory.PAPERDOLL_LEGS);
final L2ItemInstance headItem = inv.getPaperdollItem(Inventory.PAPERDOLL_HEAD);
final L2ItemInstance glovesItem = inv.getPaperdollItem(Inventory.PAPERDOLL_GLOVES);
final L2ItemInstance feetItem = inv.getPaperdollItem(Inventory.PAPERDOLL_FEET);
int legs = 0;
int head = 0;
int gloves = 0;
int feet = 0;
if (legsItem != null)
{
legs = legsItem.getVisualId();
}
if (headItem != null)
{
head = headItem.getVisualId();
}
if (glovesItem != null)
{
gloves = glovesItem.getVisualId();
}
if (feetItem != null)
{
feet = feetItem.getVisualId();
}
return getPiecesCount(legs, head, gloves, feet);
}
public int getCON()
{
return _con;

View File

@ -77,7 +77,7 @@ public class TradeItem
_isTimeLimited = item.isTimeLimitedItem();
_time = item.isTimeLimitedItem() ? (int) (item.getRemainingTime() / 1000) : -9999;
_visualId = item.getVisualId();
_visualExpiration = item.getAppearanceTime();
_visualExpiration = item.getTime();
}
public TradeItem(L2Item item, long count, long price, int enchantLevel, int attackAttribute, int attackAttributeValue, int defenseAttributes[], int appearanceId)

View File

@ -161,6 +161,7 @@ import com.l2jserver.gameserver.model.actor.L2Summon;
import com.l2jserver.gameserver.model.actor.L2Vehicle;
import com.l2jserver.gameserver.model.actor.appearance.PcAppearance;
import com.l2jserver.gameserver.model.actor.knownlist.PcKnownList;
import com.l2jserver.gameserver.model.actor.request.AbstractRequest;
import com.l2jserver.gameserver.model.actor.stat.PcStat;
import com.l2jserver.gameserver.model.actor.status.PcStatus;
import com.l2jserver.gameserver.model.actor.tasks.player.DismountTask;
@ -759,6 +760,8 @@ public final class L2PcInstance extends L2Playable
private int _expertiseWeaponPenalty = 0;
private int _expertisePenaltyBonus = 0;
private volatile Map<Class<? extends AbstractRequest>, AbstractRequest> _requests;
private boolean _isEnchanting = false;
private int _activeEnchantItemId = ID_NONE;
private int _activeEnchantSupportItemId = ID_NONE;
@ -767,9 +770,6 @@ public final class L2PcInstance extends L2Playable
private int _firstCompoundOID = -1;
private int _secondCompoundOID = -1;
private L2ItemInstance _usingAStone = null;
private L2ItemInstance _appearanceItem = null;
private L2ItemInstance _targetAppearanceItem = null;
private boolean _usingPrimeShop = false;
@ -15044,6 +15044,105 @@ public final class L2PcInstance extends L2Playable
return getServitors().values().stream().mapToInt(L2Summon::getSummonPoints).sum();
}
/**
* @param request
* @return {@code true} if the request was registered successfully, {@code false} otherwise.
*/
public boolean addRequest(AbstractRequest request)
{
if (_requests == null)
{
synchronized (this)
{
if (_requests == null)
{
_requests = new ConcurrentHashMap<>();
}
}
}
return canRequest(request) && (_requests.putIfAbsent(request.getClass(), request) == null);
}
public boolean canRequest(AbstractRequest request)
{
return (_requests != null) && _requests.values().stream().allMatch(request::canWorkWith);
}
/**
* @param clazz
* @return {@code true} if request was successfully removed, {@code false} in case processing set is not created or not containing the request.
*/
public boolean removeRequest(Class<? extends AbstractRequest> clazz)
{
return (_requests != null) && (_requests.remove(clazz) != null);
}
/**
* @param <T>
* @param requestClass
* @return object that is instance of {@code requestClass} param, {@code null} if not instance or not set.
*/
public <T extends AbstractRequest> T getRequest(Class<T> requestClass)
{
return _requests != null ? requestClass.cast(_requests.get(requestClass)) : null;
}
/**
* @return {@code true} if player has any processing request set, {@code false} otherwise.
*/
public boolean hasRequests()
{
return (_requests != null) && !_requests.isEmpty();
}
public boolean hasItemRequest()
{
return (_requests != null) && _requests.values().stream().anyMatch(AbstractRequest::isItemRequest);
}
/**
* @param requestClass
* @param classes
* @return {@code true} if player has the provided request and processing it, {@code false} otherwise.
*/
@SafeVarargs
public final boolean hasRequest(Class<? extends AbstractRequest> requestClass, Class<? extends AbstractRequest>... classes)
{
if (_requests != null)
{
for (Class<? extends AbstractRequest> clazz : classes)
{
if (_requests.containsKey(clazz))
{
return true;
}
}
return _requests.containsKey(requestClass);
}
return false;
}
/**
* @param objectId
* @return {@code true} if item object id is currently in use by some request, {@code false} otherwise.
*/
public boolean isProcessingItem(int objectId)
{
return (_requests != null) && _requests.values().stream().anyMatch(req -> req.isUsing(objectId));
}
/**
* Removing all requests associated with the item object id provided.
* @param objectId
*/
public void removeRequestsThatProcessesItem(int objectId)
{
if (_requests != null)
{
_requests.values().removeIf(req -> req.isUsing(objectId));
}
}
/*
* Return current vitality points in integer format
*/
@ -15094,36 +15193,6 @@ public final class L2PcInstance extends L2Playable
_secondCompoundOID = secondCompoundOID;
}
public L2ItemInstance getUsingAppearanceStone()
{
return _usingAStone;
}
public void setUsingAppearanceStone(L2ItemInstance stone)
{
_usingAStone = stone;
}
public L2ItemInstance getAppearanceItem()
{
return _appearanceItem;
}
public void setAppearanceItem(L2ItemInstance item)
{
_appearanceItem = item;
}
public L2ItemInstance getTargetAppearanceItem()
{
return _targetAppearanceItem;
}
public void setTargetAppearanceItem(L2ItemInstance item)
{
_targetAppearanceItem = item;
}
public void setUsingPrimeShop(boolean isUsing)
{
_usingPrimeShop = isUsing;

View File

@ -0,0 +1,94 @@
/*
* 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.actor.request;
import java.util.Objects;
import java.util.concurrent.ScheduledFuture;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
/**
* @author UnAfraid
*/
public abstract class AbstractRequest
{
private final L2PcInstance _activeChar;
private volatile long _timestamp = 0;
private volatile boolean _isProcessing;
private ScheduledFuture<?> _timeOutTask;
public AbstractRequest(L2PcInstance activeChar)
{
Objects.requireNonNull(activeChar);
_activeChar = activeChar;
}
public L2PcInstance getActiveChar()
{
return _activeChar;
}
public long getTimestamp()
{
return _timestamp;
}
public void setTimestamp(long timestamp)
{
_timestamp = timestamp;
}
public void scheduleTimeout(long delay)
{
_timeOutTask = ThreadPoolManager.getInstance().scheduleGeneral(this::onTimeout, delay);
}
public boolean isTimeout()
{
return (_timeOutTask != null) && !_timeOutTask.isDone();
}
public boolean isProcessing()
{
return _isProcessing;
}
public boolean setProcessing(boolean isProcessing)
{
return _isProcessing = isProcessing;
}
public boolean canWorkWith(AbstractRequest request)
{
return true;
}
public boolean isItemRequest()
{
return false;
}
public abstract boolean isUsing(int objectId);
public void onTimeout()
{
}
}

View File

@ -0,0 +1,75 @@
/*
* 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.actor.request;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
/**
* @author Sdw
*/
public class ShapeShiftingItemRequest extends AbstractRequest
{
private L2ItemInstance _appearanceStone;
private L2ItemInstance _appearanceExtractItem;
public ShapeShiftingItemRequest(L2PcInstance activeChar, L2ItemInstance appearanceStone)
{
super(activeChar);
_appearanceStone = appearanceStone;
}
public L2ItemInstance getAppearanceStone()
{
return _appearanceStone;
}
public void setAppearanceStone(L2ItemInstance appearanceStone)
{
_appearanceStone = appearanceStone;
}
public L2ItemInstance getAppearanceExtractItem()
{
return _appearanceExtractItem;
}
public void setAppearanceExtractItem(L2ItemInstance appearanceExtractItem)
{
_appearanceExtractItem = appearanceExtractItem;
}
@Override
public boolean isItemRequest()
{
return true;
}
@Override
public boolean canWorkWith(AbstractRequest request)
{
return !request.isItemRequest();
}
@Override
public boolean isUsing(int objectId)
{
return (objectId > 0) && ((objectId == _appearanceStone.getObjectId()) || (objectId == _appearanceExtractItem.getObjectId()));
}
}

View File

@ -1,113 +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.entity;
import java.util.ArrayList;
/**
* @author Erlandys
*/
public class AppearanceStone
{
public enum StoneType
{
NONE,
NORMAL,
BLESSED,
FIXED,
RESTORE
}
public enum AppearanceItemType
{
NONE,
WEAPON,
ARMOR,
ACCESSORY,
ALL
}
private final int _itemId;
private final StoneType _type;
private final AppearanceItemType _itemType;
private final ArrayList<Integer> _grades;
private final long _price;
private final int _targetItem;
private final long _timeForAppearance;
private int _maxGrade;
public AppearanceStone(int itemId, StoneType type, AppearanceItemType itemType, ArrayList<Integer> grades, long price, int targetItem, long timeForAppearance)
{
_itemId = itemId;
_type = type;
_itemType = itemType;
_grades = grades;
_maxGrade = grades.get(0);
for (int gr : _grades)
{
if (_maxGrade < gr)
{
_maxGrade = gr;
}
}
_price = price;
_targetItem = targetItem;
_timeForAppearance = timeForAppearance;
}
public int getItemId()
{
return _itemId;
}
public StoneType getType()
{
return _type;
}
public AppearanceItemType getItemType()
{
return _itemType;
}
public ArrayList<Integer> getGrades()
{
return _grades;
}
public int getMaxGrade()
{
return _maxGrade;
}
public long getPrice()
{
return _price;
}
public int getTargetItem()
{
return _targetItem;
}
public long getTimeForAppearance()
{
return _timeForAppearance;
}
}

View File

@ -358,6 +358,7 @@ public abstract class Inventory extends ItemContainer
if (itemSkill != null)
{
itemSkill.setReferenceItemId(item.getId());
player.addSkill(itemSkill, false);
if (itemSkill.isActive())
@ -454,7 +455,6 @@ public abstract class Inventory extends ItemContainer
if (itemSkill != null)
{
itemSkill.setReferenceItemId(item.getId());
player.addSkill(itemSkill, false);
if (itemSkill.isActive())
@ -644,6 +644,16 @@ public abstract class Inventory extends ItemContainer
}
}
final L2ArmorSet visualArmorSet = ArmorSetsData.getInstance().getSet(chestItem.getVisualId());
if ((visualArmorSet != null) && visualArmorSet.isVisual())
{
int pieces = visualArmorSet.getVisualPiecesCount(player);
if (pieces >= visualArmorSet.getMinimumPieces())
{
addSkills(player, item, visualArmorSet.getSkills(), visualArmorSet.getPiecesCount(player));
}
}
if (update)
{
player.sendSkillList();
@ -687,6 +697,11 @@ public abstract class Inventory extends ItemContainer
{
remove = true;
}
if (removeArmorsetBonus(player, ArmorSetsData.getInstance().getSet(item.getVisualId())))
{
remove = true;
}
}
else
{
@ -697,7 +712,7 @@ public abstract class Inventory extends ItemContainer
}
final L2ArmorSet armorSet = ArmorSetsData.getInstance().getSet(chestItem.getId());
if (armorSet != null)
if ((armorSet != null) && !armorSet.isVisual())
{
if (armorSet.containItem(slot, item.getId())) // removed part of set
{
@ -720,6 +735,25 @@ public abstract class Inventory extends ItemContainer
}
}
}
final L2ArmorSet visualArmorSet = ArmorSetsData.getInstance().getSet(chestItem.getVisualId());
if ((visualArmorSet != null) && visualArmorSet.isVisual())
{
if (visualArmorSet.containItem(slot, item.getVisualId())) // removed part of set
{
if (removeArmorsetBonus(player, visualArmorSet))
{
remove = true;
}
}
else if (visualArmorSet.containShield(item.getVisualId())) // removed shield
{
if (removeShieldSkills(player, visualArmorSet.getShieldSkills()))
{
remove = true;
}
}
}
}
if (remove)
@ -1788,7 +1822,7 @@ public abstract class Inventory extends ItemContainer
public void restore()
{
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("SELECT object_id, item_id, count, enchant_level, loc, loc_data, custom_type1, custom_type2, mana_left, time, appearance_id, appearance_time FROM items WHERE owner_id=? AND (loc=? OR loc=?) ORDER BY loc_data"))
PreparedStatement statement = con.prepareStatement("SELECT object_id, item_id, count, enchant_level, loc, loc_data, custom_type1, custom_type2, mana_left, time FROM items WHERE owner_id=? AND (loc=? OR loc=?) ORDER BY loc_data"))
{
statement.setInt(1, getOwnerId());
statement.setString(2, getBaseLocation().name());

View File

@ -40,6 +40,7 @@ import com.l2jserver.gameserver.model.events.impl.character.player.inventory.OnP
import com.l2jserver.gameserver.model.events.impl.character.player.inventory.OnPlayerItemTransfer;
import com.l2jserver.gameserver.model.items.L2Item;
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
import com.l2jserver.gameserver.model.variables.ItemVariables;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.ExAdenaInvenCount;
import com.l2jserver.gameserver.network.serverpackets.ExUserInfoInvenWeight;
@ -880,7 +881,7 @@ public class PcInventory extends Inventory
{
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,appearance_id FROM items WHERE owner_id=? AND loc='PAPERDOLL'"))
PreparedStatement statement2 = con.prepareStatement("SELECT object_id,item_id,loc_data,enchant_level FROM items WHERE owner_id=? AND loc='PAPERDOLL'"))
{
statement2.setInt(1, objectId);
try (ResultSet invdata = statement2.executeQuery())
@ -888,13 +889,11 @@ public class PcInventory extends Inventory
while (invdata.next())
{
int slot = invdata.getInt("loc_data");
final ItemVariables vars = new ItemVariables(invdata.getInt("object_id"));
paperdoll[slot][0] = invdata.getInt("object_id");
paperdoll[slot][1] = invdata.getInt("item_id");
paperdoll[slot][2] = invdata.getInt("enchant_level");
paperdoll[slot][3] = invdata.getInt("appearance_id");
/*
* if (slot == Inventory.PAPERDOLL_RHAND) { paperdoll[Inventory.PAPERDOLL_RHAND][0] = invdata.getInt("object_id"); paperdoll[Inventory.PAPERDOLL_RHAND][1] = invdata.getInt("item_id"); paperdoll[Inventory.PAPERDOLL_RHAND][2] = invdata.getInt("enchant_level"); }
*/
paperdoll[slot][3] = vars.getInt(ItemVariables.VISUAL_ID, 0);
}
}
}

View File

@ -19,7 +19,6 @@
package com.l2jserver.gameserver.model.items;
import com.l2jserver.gameserver.model.StatsSet;
import com.l2jserver.gameserver.model.entity.AppearanceStone;
import com.l2jserver.gameserver.model.holders.SkillHolder;
import com.l2jserver.gameserver.model.items.type.ArmorType;
import com.l2jserver.gameserver.model.skills.Skill;
@ -118,10 +117,4 @@ public final class L2Armor extends L2Item
}
return _enchant4Skill.getSkill();
}
@Override
public AppearanceStone getAppearanceStone()
{
return null;
}
}

View File

@ -21,10 +21,8 @@ package com.l2jserver.gameserver.model.items;
import java.util.ArrayList;
import java.util.List;
import com.l2jserver.gameserver.data.xml.impl.AppearanceItemData;
import com.l2jserver.gameserver.model.L2ExtractableProduct;
import com.l2jserver.gameserver.model.StatsSet;
import com.l2jserver.gameserver.model.entity.AppearanceStone;
import com.l2jserver.gameserver.model.itemcontainer.Inventory;
import com.l2jserver.gameserver.model.items.type.EtcItemType;
import com.l2jserver.util.StringUtil;
@ -39,7 +37,6 @@ public final class L2EtcItem extends L2Item
private final boolean _isBlessed;
private final List<L2ExtractableProduct> _extractableItems;
private final boolean _isInfinite;
private final AppearanceStone _appearanceStone;
/**
* Constructor for EtcItem.
@ -123,7 +120,6 @@ public final class L2EtcItem extends L2Item
}
_isInfinite = set.getBoolean("is_infinite", false);
_appearanceStone = (_handler != null) && _handler.equals("Appearance") ? AppearanceItemData.getInstance().getStone(getId()) : null;
}
/**
@ -175,10 +171,4 @@ public final class L2EtcItem extends L2Item
{
return _isInfinite;
}
@Override
public AppearanceStone getAppearanceStone()
{
return _appearanceStone;
}
}

View File

@ -35,7 +35,6 @@ import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.L2Summon;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.conditions.Condition;
import com.l2jserver.gameserver.model.entity.AppearanceStone;
import com.l2jserver.gameserver.model.events.ListenersContainer;
import com.l2jserver.gameserver.model.holders.SkillHolder;
import com.l2jserver.gameserver.model.interfaces.IIdentifiable;
@ -964,6 +963,4 @@ public abstract class L2Item extends ListenersContainer implements IIdentifiable
{
return null;
}
public abstract AppearanceStone getAppearanceStone();
}

View File

@ -64,9 +64,6 @@ public class L2WarehouseItem
private final int _time;
private final int _appearanceId;
private final long _appearanceTime;
public L2WarehouseItem(L2ItemInstance item)
{
_item = item.getItem();
@ -97,8 +94,6 @@ public class L2WarehouseItem
_elemDefAttr[i] = item.getElementDefAttr(i);
}
_enchantOptions = item.getEnchantOptions();
_appearanceId = item.getVisualId();
_appearanceTime = item.getAppearanceTime();
}
/**
@ -301,14 +296,4 @@ public class L2WarehouseItem
{
return _item.toString();
}
public int getAppearanceId()
{
return _appearanceId;
}
public long getAppearanceTime()
{
return _appearanceTime;
}
}

View File

@ -26,7 +26,6 @@ import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.conditions.Condition;
import com.l2jserver.gameserver.model.conditions.ConditionGameChance;
import com.l2jserver.gameserver.model.entity.AppearanceStone;
import com.l2jserver.gameserver.model.events.EventDispatcher;
import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcSkillSee;
import com.l2jserver.gameserver.model.holders.SkillHolder;
@ -450,10 +449,4 @@ public final class L2Weapon extends L2Item
caster.sendPacket(sm);
}
}
@Override
public AppearanceStone getAppearanceStone()
{
return null;
}
}

View File

@ -0,0 +1,29 @@
/*
* 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.items.appearance;
/**
* @author UnAfraid
*/
public enum AppearanceHandType
{
NONE,
ONE_HANDED,
TWO_HANDED,
}

View File

@ -0,0 +1,29 @@
/*
* 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.items.appearance;
/**
* @author UnAfraid
*/
public enum AppearanceMagicType
{
NONE,
MAGICAL,
PHYISICAL,
}

View File

@ -0,0 +1,210 @@
/*
* 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.items.appearance;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.l2jserver.gameserver.datatables.ItemTable;
import com.l2jserver.gameserver.enums.Race;
import com.l2jserver.gameserver.model.StatsSet;
import com.l2jserver.gameserver.model.items.L2Item;
import com.l2jserver.gameserver.model.items.type.ArmorType;
import com.l2jserver.gameserver.model.items.type.CrystalType;
import com.l2jserver.gameserver.model.items.type.WeaponType;
/**
* @author UnAfraid
*/
public class AppearanceStone
{
private final int _id;
private final int _cost;
private final int _visualId;
private final long _lifeTime;
private final AppearanceType _type;
private final WeaponType _weaponType;
private final ArmorType _armorType;
private final AppearanceHandType _handType;
private final AppearanceMagicType _magicType;
private List<CrystalType> _crystalTypes;
private List<AppearanceTargetType> _targetTypes;
private List<Integer> _bodyParts;
private List<Race> _races;
private List<Race> _racesNot;
public AppearanceStone(StatsSet set)
{
_id = set.getInt("id");
_visualId = set.getInt("visualId", 0);
_cost = set.getInt("cost", 0);
_lifeTime = set.getDuration("lifeTime", Duration.ofSeconds(0)).toMillis();
_type = set.getEnum("type", AppearanceType.class, AppearanceType.NONE);
_weaponType = set.getEnum("weaponType", WeaponType.class, WeaponType.NONE);
_armorType = set.getEnum("armorType", ArmorType.class, ArmorType.NONE);
_handType = set.getEnum("handType", AppearanceHandType.class, AppearanceHandType.NONE);
_magicType = set.getEnum("magicType", AppearanceMagicType.class, AppearanceMagicType.NONE);
final CrystalType crystalType = set.getEnum("crystalType", CrystalType.class, CrystalType.NONE);
if (crystalType != CrystalType.NONE)
{
addCrystalType(crystalType);
}
final AppearanceTargetType targetType = set.getEnum("targetType", AppearanceTargetType.class, AppearanceTargetType.NONE);
if (targetType != AppearanceTargetType.NONE)
{
addTargetType(targetType);
}
final int bodyPart = ItemTable._slots.get(set.getString("bodyPart", "none"));
if (bodyPart != L2Item.SLOT_NONE)
{
addBodyPart(bodyPart);
}
final Race race = set.getEnum("race", Race.class, Race.NONE);
if (race != Race.NONE)
{
addRace(race);
}
final Race raceNot = set.getEnum("raceNot", Race.class, Race.NONE);
if (raceNot != Race.NONE)
{
addRaceNot(raceNot);
}
}
public int getId()
{
return _id;
}
public int getVisualId()
{
return _visualId;
}
public int getCost()
{
return _cost;
}
public long getLifeTime()
{
return _lifeTime;
}
public AppearanceType getType()
{
return _type;
}
public WeaponType getWeaponType()
{
return _weaponType;
}
public ArmorType getArmorType()
{
return _armorType;
}
public AppearanceHandType getHandType()
{
return _handType;
}
public AppearanceMagicType getMagicType()
{
return _magicType;
}
public void addCrystalType(CrystalType type)
{
if (_crystalTypes == null)
{
_crystalTypes = new ArrayList<>();
}
_crystalTypes.add(type);
}
public List<CrystalType> getCrystalTypes()
{
return _crystalTypes != null ? _crystalTypes : Collections.emptyList();
}
public void addTargetType(AppearanceTargetType type)
{
if (_targetTypes == null)
{
_targetTypes = new ArrayList<>();
}
_targetTypes.add(type);
}
public List<AppearanceTargetType> getTargetTypes()
{
return _targetTypes != null ? _targetTypes : Collections.emptyList();
}
public void addBodyPart(Integer part)
{
if (_bodyParts == null)
{
_bodyParts = new ArrayList<>();
}
_bodyParts.add(part);
}
public List<Integer> getBodyParts()
{
return _bodyParts != null ? _bodyParts : Collections.emptyList();
}
public void addRace(Race race)
{
if (_races == null)
{
_races = new ArrayList<>();
}
_races.add(race);
}
public List<Race> getRaces()
{
return _races != null ? _races : Collections.emptyList();
}
public void addRaceNot(Race race)
{
if (_racesNot == null)
{
_racesNot = new ArrayList<>();
}
_racesNot.add(race);
}
public List<Race> getRacesNot()
{
return _racesNot != null ? _racesNot : Collections.emptyList();
}
}

View File

@ -0,0 +1,31 @@
/*
* 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.items.appearance;
/**
* @author UnAfraid
*/
public enum AppearanceTargetType
{
NONE,
WEAPON,
ARMOR,
ACCESSORY,
ALL
}

View File

@ -0,0 +1,31 @@
/*
* 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.items.appearance;
/**
* @author UnAfraid
*/
public enum AppearanceType
{
NONE,
NORMAL,
BLESSED,
FIXED,
RESTORE;
}

View File

@ -37,12 +37,14 @@ import com.l2jserver.Config;
import com.l2jserver.L2DatabaseFactory;
import com.l2jserver.gameserver.GeoData;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.data.xml.impl.AppearanceItemData;
import com.l2jserver.gameserver.data.xml.impl.EnchantItemOptionsData;
import com.l2jserver.gameserver.data.xml.impl.OptionData;
import com.l2jserver.gameserver.datatables.ItemTable;
import com.l2jserver.gameserver.enums.InstanceType;
import com.l2jserver.gameserver.enums.ItemLocation;
import com.l2jserver.gameserver.enums.ShotType;
import com.l2jserver.gameserver.enums.UserInfoType;
import com.l2jserver.gameserver.idfactory.IdFactory;
import com.l2jserver.gameserver.instancemanager.ItemsOnGroundManager;
import com.l2jserver.gameserver.instancemanager.MercTicketManager;
@ -69,14 +71,17 @@ import com.l2jserver.gameserver.model.items.L2Armor;
import com.l2jserver.gameserver.model.items.L2EtcItem;
import com.l2jserver.gameserver.model.items.L2Item;
import com.l2jserver.gameserver.model.items.L2Weapon;
import com.l2jserver.gameserver.model.items.appearance.AppearanceStone;
import com.l2jserver.gameserver.model.items.type.EtcItemType;
import com.l2jserver.gameserver.model.items.type.ItemType;
import com.l2jserver.gameserver.model.options.EnchantOptions;
import com.l2jserver.gameserver.model.options.Options;
import com.l2jserver.gameserver.model.stats.functions.AbstractFunction;
import com.l2jserver.gameserver.model.variables.ItemVariables;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.DropItem;
import com.l2jserver.gameserver.network.serverpackets.ExAdenaInvenCount;
import com.l2jserver.gameserver.network.serverpackets.ExUserInfoEquipSlot;
import com.l2jserver.gameserver.network.serverpackets.ExUserInfoInvenWeight;
import com.l2jserver.gameserver.network.serverpackets.GetItem;
import com.l2jserver.gameserver.network.serverpackets.InventoryUpdate;
@ -163,6 +168,7 @@ public final class L2ItemInstance extends L2Object
private ScheduledFuture<?> itemLootShedule = null;
private ScheduledFuture<?> _lifeTimeTask;
private ScheduledFuture<?> _appearanceLifeTimeTask;
private final DropProtection _dropProtection = new DropProtection();
@ -170,9 +176,6 @@ public final class L2ItemInstance extends L2Object
private final List<Options> _enchantOptions = new ArrayList<>();
private int _appearanceId = 0;
private long _appearanceTime = -1;
/**
* Constructor of the L2ItemInstance from the objectId and the itemId.
* @param objectId : int designating the ID of the object in the world
@ -1502,8 +1505,8 @@ public final class L2ItemInstance extends L2Object
public static L2ItemInstance restoreFromDb(int ownerId, ResultSet rs)
{
L2ItemInstance inst = null;
int objectId, item_id, loc_data, enchant_level, custom_type1, custom_type2, manaLeft, appearance_id;
long time, count, appearance_time;
int objectId, item_id, loc_data, enchant_level, custom_type1, custom_type2, manaLeft;
long time, count;
ItemLocation loc;
try
{
@ -1517,8 +1520,6 @@ public final class L2ItemInstance extends L2Object
custom_type2 = rs.getInt("custom_type2");
manaLeft = rs.getInt("mana_left");
time = rs.getLong("time");
appearance_id = rs.getInt("appearance_id");
appearance_time = rs.getLong("appearance_time");
}
catch (Exception e)
{
@ -1545,8 +1546,6 @@ public final class L2ItemInstance extends L2Object
// Setup life time for shadow weapons
inst._mana = manaLeft;
inst._time = time;
inst._appearanceId = appearance_id;
inst._appearanceTime = appearance_time;
// load augmentation and elemental enchant
if (inst.isEquipable())
@ -1665,7 +1664,7 @@ public final class L2ItemInstance extends L2Object
}
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("UPDATE items SET owner_id=?,count=?,loc=?,loc_data=?,enchant_level=?,custom_type1=?,custom_type2=?,mana_left=?,time=?,appearance_id=?,appearance_time=? " + "WHERE object_id = ?"))
PreparedStatement ps = con.prepareStatement("UPDATE items SET owner_id=?,count=?,loc=?,loc_data=?,enchant_level=?,custom_type1=?,custom_type2=?,mana_left=?,time=? " + "WHERE object_id = ?"))
{
ps.setInt(1, _ownerId);
ps.setLong(2, getCount());
@ -1676,9 +1675,7 @@ public final class L2ItemInstance extends L2Object
ps.setInt(7, getCustomType2());
ps.setInt(8, getMana());
ps.setLong(9, getTime());
ps.setInt(10, getVisualId());
ps.setLong(11, getAppearanceTime());
ps.setInt(12, getObjectId());
ps.setInt(10, getObjectId());
ps.executeUpdate();
_existsInDb = true;
_storedInDb = true;
@ -2260,27 +2257,101 @@ public final class L2ItemInstance extends L2Object
_lifeTimeTask.cancel(false);
_lifeTimeTask = null;
}
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
{
_appearanceLifeTimeTask.cancel(false);
_appearanceLifeTimeTask = null;
}
}
public final ItemVariables getVariables()
{
final ItemVariables vars = getScript(ItemVariables.class);
return vars != null ? vars : addScript(new ItemVariables(getObjectId()));
}
public int getVisualId()
{
return _appearanceId;
final int visualId = getVariables().getInt(ItemVariables.VISUAL_ID, 0);
if (visualId > 0)
{
final int appearanceStoneId = getVariables().getInt(ItemVariables.VISUAL_APPEARANCE_STONE_ID, 0);
if (appearanceStoneId > 0)
{
final AppearanceStone stone = AppearanceItemData.getInstance().getStone(appearanceStoneId);
if (stone != null)
{
final L2PcInstance player = getActingPlayer();
if (player != null)
{
if (!stone.getRaces().isEmpty() && !stone.getRaces().contains(player.getRace()))
{
return 0;
}
if (!stone.getRacesNot().isEmpty() && stone.getRacesNot().contains(player.getRace()))
{
return 0;
}
}
}
}
}
return visualId;
}
public void setAppearanceId(int appearanceId)
public void setVisualId(int visualId)
{
_storedInDb = false;
_appearanceId = appearanceId;
getVariables().set(ItemVariables.VISUAL_ID, visualId);
}
public long getAppearanceTime()
public long getVisualLifeTime()
{
_storedInDb = false;
return _appearanceTime;
return getVariables().getLong(ItemVariables.VISUAL_APPEARANCE_LIFE_TIME, 0);
}
public void setAppearanceTime(long appearanceTime)
public void scheduleVisualLifeTime()
{
_appearanceTime = appearanceTime;
if (_appearanceLifeTimeTask != null)
{
_appearanceLifeTimeTask.cancel(false);
}
if (getVisualLifeTime() > 0)
{
final long time = getVisualLifeTime() - System.currentTimeMillis();
if (time > 0)
{
_appearanceLifeTimeTask = ThreadPoolManager.getInstance().scheduleGeneral(this::onVisualLifeTimeEnd, time);
}
else
{
ThreadPoolManager.getInstance().executeGeneral(this::onVisualLifeTimeEnd);
}
}
}
private final void onVisualLifeTimeEnd()
{
final ItemVariables vars = getVariables();
vars.remove(ItemVariables.VISUAL_ID);
vars.remove(ItemVariables.VISUAL_APPEARANCE_STONE_ID);
vars.remove(ItemVariables.VISUAL_APPEARANCE_LIFE_TIME);
vars.storeMe();
final L2PcInstance player = getActingPlayer();
if (player != null)
{
final InventoryUpdate iu = new InventoryUpdate();
iu.addModifiedItem(this);
player.broadcastUserInfo(UserInfoType.APPAREANCE);
player.sendPacket(new ExUserInfoEquipSlot(player));
player.sendPacket(iu);
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.S1_HAS_BEEN_RESTORED_TO_ITS_PREVIOUS_APPEARANCE_AS_ITS_TEMPORARY_MODIFICATION_HAS_EXPIRED).addItemName(this));
}
}
public boolean isAppearanceable()
{
return isWeapon() || isArmor();
}
}

View File

@ -0,0 +1,173 @@
/*
* Copyright (C) 2004-2015 L2J DataPack
*
* This file is part of L2J DataPack.
*
* L2J DataPack 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 DataPack 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.variables;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jserver.L2DatabaseFactory;
/**
* @author UnAfraid
*/
public class ItemVariables extends AbstractVariables
{
private static final Logger _log = Logger.getLogger(ItemVariables.class.getName());
// SQL Queries.
private static final String SELECT_QUERY = "SELECT * FROM item_variables WHERE id = ?";
private static final String SELECT_COUNT = "SELECT COUNT(*) FROM item_variables WHERE id = ?";
private static final String DELETE_QUERY = "DELETE FROM item_variables WHERE id = ?";
private static final String INSERT_QUERY = "INSERT INTO item_variables (id, var, val) VALUES (?, ?, ?)";
private final int _objectId;
// Static Constants
public static final String VISUAL_ID = "visualId";
public static final String VISUAL_APPEARANCE_STONE_ID = "visualAppearanceStoneId";
public static final String VISUAL_APPEARANCE_LIFE_TIME = "visualAppearanceLifetime";
public ItemVariables(int objectId)
{
_objectId = objectId;
restoreMe();
}
public static boolean hasVariables(int objectId)
{
// Restore previous variables.
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement st = con.prepareStatement(SELECT_COUNT))
{
st.setInt(1, objectId);
try (ResultSet rset = st.executeQuery())
{
if (rset.next())
{
return rset.getInt(1) > 0;
}
}
}
catch (SQLException e)
{
_log.log(Level.WARNING, ItemVariables.class.getSimpleName() + ": Couldn't select variables count for: " + objectId, e);
return false;
}
return true;
}
@Override
public boolean restoreMe()
{
// Restore previous variables.
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement st = con.prepareStatement(SELECT_QUERY))
{
st.setInt(1, _objectId);
try (ResultSet rset = st.executeQuery())
{
while (rset.next())
{
set(rset.getString("var"), rset.getString("val"), false);
}
}
}
catch (SQLException e)
{
_log.log(Level.WARNING, getClass().getSimpleName() + ": Couldn't restore variables for: " + _objectId, e);
return false;
}
finally
{
compareAndSetChanges(true, false);
}
return true;
}
@Override
public boolean storeMe()
{
// No changes, nothing to store.
if (!hasChanges())
{
return false;
}
try (Connection con = L2DatabaseFactory.getInstance().getConnection())
{
// Clear previous entries.
try (PreparedStatement st = con.prepareStatement(DELETE_QUERY))
{
st.setInt(1, _objectId);
st.execute();
}
// Insert all variables.
try (PreparedStatement st = con.prepareStatement(INSERT_QUERY))
{
st.setInt(1, _objectId);
for (Entry<String, Object> entry : getSet().entrySet())
{
st.setString(2, entry.getKey());
st.setString(3, String.valueOf(entry.getValue()));
st.addBatch();
}
st.executeBatch();
}
}
catch (SQLException e)
{
_log.log(Level.WARNING, getClass().getSimpleName() + ": Couldn't update variables for: " + _objectId, e);
return false;
}
finally
{
compareAndSetChanges(true, false);
}
return true;
}
@Override
public boolean deleteMe()
{
try (Connection con = L2DatabaseFactory.getInstance().getConnection())
{
// Clear previous entries.
try (PreparedStatement st = con.prepareStatement(DELETE_QUERY))
{
st.setInt(1, _objectId);
st.execute();
}
// Clear all entries
getSet().clear();
}
catch (Exception e)
{
_log.log(Level.WARNING, getClass().getSimpleName() + ": Couldn't delete variables for: " + _objectId, e);
return false;
}
return true;
}
}