/*
* 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 .
*/
package com.l2jserver.gameserver.network.clientpackets;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import com.l2jserver.Config;
import com.l2jserver.gameserver.enums.ItemLocation;
import com.l2jserver.gameserver.enums.PrivateStoreType;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.items.L2Armor;
import com.l2jserver.gameserver.model.items.L2Item;
import com.l2jserver.gameserver.model.items.L2Weapon;
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
import com.l2jserver.gameserver.model.items.type.CrystalType;
import com.l2jserver.gameserver.network.SystemMessageId;
public abstract class AbstractRefinePacket extends L2GameClientPacket
{
public static final int GRADE_NONE = 0;
public static final int GRADE_MID = 1;
public static final int GRADE_HIGH = 2;
public static final int GRADE_TOP = 3;
public static final int GRADE_ACC = 4; // Accessory LS
protected static final int GEMSTONE_D = 2130;
protected static final int GEMSTONE_C = 2131;
protected static final int GEMSTONE_B = 2132;
private static final Map _lifeStones = new HashMap<>();
protected static final class LifeStone
{
// lifestone level to player level table
private static final int[] LEVELS =
{
46,
49,
52,
55,
58,
61,
64,
67,
70,
76,
80,
82,
84,
85
};
private final int _grade;
private final int _level;
public LifeStone(int grade, int level)
{
_grade = grade;
_level = level;
}
public final int getLevel()
{
return _level;
}
public final int getGrade()
{
return _grade;
}
public final int getPlayerLevel()
{
return LEVELS[_level];
}
}
static
{
// itemId, (LS grade, LS level)
_lifeStones.put(8723, new LifeStone(GRADE_NONE, 0));
_lifeStones.put(8724, new LifeStone(GRADE_NONE, 1));
_lifeStones.put(8725, new LifeStone(GRADE_NONE, 2));
_lifeStones.put(8726, new LifeStone(GRADE_NONE, 3));
_lifeStones.put(8727, new LifeStone(GRADE_NONE, 4));
_lifeStones.put(8728, new LifeStone(GRADE_NONE, 5));
_lifeStones.put(8729, new LifeStone(GRADE_NONE, 6));
_lifeStones.put(8730, new LifeStone(GRADE_NONE, 7));
_lifeStones.put(8731, new LifeStone(GRADE_NONE, 8));
_lifeStones.put(8732, new LifeStone(GRADE_NONE, 9));
_lifeStones.put(8733, new LifeStone(GRADE_MID, 0));
_lifeStones.put(8734, new LifeStone(GRADE_MID, 1));
_lifeStones.put(8735, new LifeStone(GRADE_MID, 2));
_lifeStones.put(8736, new LifeStone(GRADE_MID, 3));
_lifeStones.put(8737, new LifeStone(GRADE_MID, 4));
_lifeStones.put(8738, new LifeStone(GRADE_MID, 5));
_lifeStones.put(8739, new LifeStone(GRADE_MID, 6));
_lifeStones.put(8740, new LifeStone(GRADE_MID, 7));
_lifeStones.put(8741, new LifeStone(GRADE_MID, 8));
_lifeStones.put(8742, new LifeStone(GRADE_MID, 9));
_lifeStones.put(8743, new LifeStone(GRADE_HIGH, 0));
_lifeStones.put(8744, new LifeStone(GRADE_HIGH, 1));
_lifeStones.put(8745, new LifeStone(GRADE_HIGH, 2));
_lifeStones.put(8746, new LifeStone(GRADE_HIGH, 3));
_lifeStones.put(8747, new LifeStone(GRADE_HIGH, 4));
_lifeStones.put(8748, new LifeStone(GRADE_HIGH, 5));
_lifeStones.put(8749, new LifeStone(GRADE_HIGH, 6));
_lifeStones.put(8750, new LifeStone(GRADE_HIGH, 7));
_lifeStones.put(8751, new LifeStone(GRADE_HIGH, 8));
_lifeStones.put(8752, new LifeStone(GRADE_HIGH, 9));
_lifeStones.put(8753, new LifeStone(GRADE_TOP, 0));
_lifeStones.put(8754, new LifeStone(GRADE_TOP, 1));
_lifeStones.put(8755, new LifeStone(GRADE_TOP, 2));
_lifeStones.put(8756, new LifeStone(GRADE_TOP, 3));
_lifeStones.put(8757, new LifeStone(GRADE_TOP, 4));
_lifeStones.put(8758, new LifeStone(GRADE_TOP, 5));
_lifeStones.put(8759, new LifeStone(GRADE_TOP, 6));
_lifeStones.put(8760, new LifeStone(GRADE_TOP, 7));
_lifeStones.put(8761, new LifeStone(GRADE_TOP, 8));
_lifeStones.put(8762, new LifeStone(GRADE_TOP, 9));
_lifeStones.put(9573, new LifeStone(GRADE_NONE, 10));
_lifeStones.put(9574, new LifeStone(GRADE_MID, 10));
_lifeStones.put(9575, new LifeStone(GRADE_HIGH, 10));
_lifeStones.put(9576, new LifeStone(GRADE_TOP, 10));
_lifeStones.put(10483, new LifeStone(GRADE_NONE, 11));
_lifeStones.put(10484, new LifeStone(GRADE_MID, 11));
_lifeStones.put(10485, new LifeStone(GRADE_HIGH, 11));
_lifeStones.put(10486, new LifeStone(GRADE_TOP, 11));
_lifeStones.put(12754, new LifeStone(GRADE_ACC, 0));
_lifeStones.put(12755, new LifeStone(GRADE_ACC, 1));
_lifeStones.put(12756, new LifeStone(GRADE_ACC, 2));
_lifeStones.put(12757, new LifeStone(GRADE_ACC, 3));
_lifeStones.put(12758, new LifeStone(GRADE_ACC, 4));
_lifeStones.put(12759, new LifeStone(GRADE_ACC, 5));
_lifeStones.put(12760, new LifeStone(GRADE_ACC, 6));
_lifeStones.put(12761, new LifeStone(GRADE_ACC, 7));
_lifeStones.put(12762, new LifeStone(GRADE_ACC, 8));
_lifeStones.put(12763, new LifeStone(GRADE_ACC, 9));
_lifeStones.put(12821, new LifeStone(GRADE_ACC, 10));
_lifeStones.put(12822, new LifeStone(GRADE_ACC, 11));
_lifeStones.put(12840, new LifeStone(GRADE_ACC, 0));
_lifeStones.put(12841, new LifeStone(GRADE_ACC, 1));
_lifeStones.put(12842, new LifeStone(GRADE_ACC, 2));
_lifeStones.put(12843, new LifeStone(GRADE_ACC, 3));
_lifeStones.put(12844, new LifeStone(GRADE_ACC, 4));
_lifeStones.put(12845, new LifeStone(GRADE_ACC, 5));
_lifeStones.put(12846, new LifeStone(GRADE_ACC, 6));
_lifeStones.put(12847, new LifeStone(GRADE_ACC, 7));
_lifeStones.put(12848, new LifeStone(GRADE_ACC, 8));
_lifeStones.put(12849, new LifeStone(GRADE_ACC, 9));
_lifeStones.put(12850, new LifeStone(GRADE_ACC, 10));
_lifeStones.put(12851, new LifeStone(GRADE_ACC, 11));
_lifeStones.put(14008, new LifeStone(GRADE_ACC, 12));
_lifeStones.put(14166, new LifeStone(GRADE_NONE, 12));
_lifeStones.put(14167, new LifeStone(GRADE_MID, 12));
_lifeStones.put(14168, new LifeStone(GRADE_HIGH, 12));
_lifeStones.put(14169, new LifeStone(GRADE_TOP, 12));
_lifeStones.put(16160, new LifeStone(GRADE_NONE, 13));
_lifeStones.put(16161, new LifeStone(GRADE_MID, 13));
_lifeStones.put(16162, new LifeStone(GRADE_HIGH, 13));
_lifeStones.put(16163, new LifeStone(GRADE_TOP, 13));
_lifeStones.put(16177, new LifeStone(GRADE_ACC, 13));
_lifeStones.put(16164, new LifeStone(GRADE_NONE, 13));
_lifeStones.put(16165, new LifeStone(GRADE_MID, 13));
_lifeStones.put(16166, new LifeStone(GRADE_HIGH, 13));
_lifeStones.put(16167, new LifeStone(GRADE_TOP, 13));
_lifeStones.put(16178, new LifeStone(GRADE_ACC, 13));
}
protected static final LifeStone getLifeStone(int itemId)
{
return _lifeStones.get(itemId);
}
/**
* Checks player, source item, lifestone and gemstone validity for augmentation process
* @param player
* @param item
* @param refinerItem
* @param gemStones
* @return
*/
protected static final boolean isValid(L2PcInstance player, L2ItemInstance item, L2ItemInstance refinerItem, L2ItemInstance gemStones)
{
if (!isValid(player, item, refinerItem))
{
return false;
}
// GemStones must belong to owner
if (gemStones.getOwnerId() != player.getObjectId())
{
return false;
}
// .. and located in inventory
if (gemStones.getItemLocation() != ItemLocation.INVENTORY)
{
return false;
}
final CrystalType grade = item.getItem().getItemGrade();
final LifeStone ls = _lifeStones.get(refinerItem.getId());
// Check for item id
if (getGemStoneId(grade) != gemStones.getId())
{
return false;
}
// Count must be greater or equal of required number
if (getGemStoneCount(grade, ls.getGrade()) > gemStones.getCount())
{
return false;
}
return true;
}
/**
* Checks player, source item and lifestone validity for augmentation process
* @param player
* @param item
* @param refinerItem
* @return
*/
protected static final boolean isValid(L2PcInstance player, L2ItemInstance item, L2ItemInstance refinerItem)
{
if (!isValid(player, item))
{
return false;
}
// Item must belong to owner
if (refinerItem.getOwnerId() != player.getObjectId())
{
return false;
}
// Lifestone must be located in inventory
if (refinerItem.getItemLocation() != ItemLocation.INVENTORY)
{
return false;
}
final LifeStone ls = _lifeStones.get(refinerItem.getId());
if (ls == null)
{
return false;
}
// weapons can't be augmented with accessory ls
if ((item.getItem() instanceof L2Weapon) && (ls.getGrade() == GRADE_ACC))
{
return false;
}
// and accessory can't be augmented with weapon ls
if ((item.getItem() instanceof L2Armor) && (ls.getGrade() != GRADE_ACC))
{
return false;
}
// check for level of the lifestone
if (player.getLevel() < ls.getPlayerLevel())
{
return false;
}
return true;
}
/**
* Check both player and source item conditions for augmentation process
* @param player
* @param item
* @return
*/
protected static final boolean isValid(L2PcInstance player, L2ItemInstance item)
{
if (!isValid(player))
{
return false;
}
// Item must belong to owner
if (item.getOwnerId() != player.getObjectId())
{
return false;
}
if (item.isAugmented())
{
return false;
}
if (item.isHeroItem())
{
return false;
}
if (item.isShadowItem())
{
return false;
}
if (item.isCommonItem())
{
return false;
}
if (item.isEtcItem())
{
return false;
}
if (item.isTimeLimitedItem())
{
return false;
}
if (item.isPvp() && !Config.ALT_ALLOW_AUGMENT_PVP_ITEMS)
{
return false;
}
if (item.getItem().getCrystalType().isLesser(CrystalType.C))
{
return false;
}
// Source item can be equipped or in inventory
switch (item.getItemLocation())
{
case INVENTORY:
case PAPERDOLL:
break;
default:
return false;
}
if (item.getItem() instanceof L2Weapon)
{
switch (((L2Weapon) item.getItem()).getItemType())
{
case NONE:
case FISHINGROD:
return false;
default:
break;
}
}
else if (item.getItem() instanceof L2Armor)
{
// only accessories can be augmented
switch (item.getItem().getBodyPart())
{
case L2Item.SLOT_LR_FINGER:
case L2Item.SLOT_LR_EAR:
case L2Item.SLOT_NECK:
break;
default:
return false;
}
}
else
{
return false; // neither weapon nor armor ?
}
// blacklist check
if (Arrays.binarySearch(Config.AUGMENTATION_BLACKLIST, item.getId()) >= 0)
{
return false;
}
return true;
}
/**
* Check if player's conditions valid for augmentation process
* @param player
* @return
*/
protected static final boolean isValid(L2PcInstance player)
{
if (player.getPrivateStoreType() != PrivateStoreType.NONE)
{
player.sendPacket(SystemMessageId.YOU_CANNOT_AUGMENT_ITEMS_WHILE_A_PRIVATE_STORE_OR_PRIVATE_WORKSHOP_IS_IN_OPERATION);
return false;
}
if (player.getActiveTradeList() != null)
{
player.sendPacket(SystemMessageId.YOU_CANNOT_AUGMENT_ITEMS_WHILE_TRADING);
return false;
}
if (player.isDead())
{
player.sendPacket(SystemMessageId.YOU_CANNOT_AUGMENT_ITEMS_WHILE_DEAD);
return false;
}
if (player.isParalyzed())
{
player.sendPacket(SystemMessageId.YOU_CANNOT_AUGMENT_ITEMS_WHILE_PARALYZED);
return false;
}
if (player.isFishing())
{
player.sendPacket(SystemMessageId.YOU_CANNOT_AUGMENT_ITEMS_WHILE_FISHING);
return false;
}
if (player.isSitting())
{
player.sendPacket(SystemMessageId.YOU_CANNOT_AUGMENT_ITEMS_WHILE_SITTING_DOWN);
return false;
}
if (player.isCursedWeaponEquipped())
{
return false;
}
if (player.isEnchanting() || player.isProcessingTransaction())
{
return false;
}
return true;
}
/**
* @param itemGrade
* @return GemStone itemId based on item grade
*/
protected static final int getGemStoneId(CrystalType itemGrade)
{
switch (itemGrade)
{
case C:
case B:
return GEMSTONE_D;
case A:
case S:
return GEMSTONE_C;
case S80:
case S84:
return GEMSTONE_B;
default:
return 0;
}
}
/**
* Different for weapon and accessory augmentation.
* @param itemGrade
* @param lifeStoneGrade
* @return GemStone count based on item grade and life stone grade
*/
protected static final int getGemStoneCount(CrystalType itemGrade, int lifeStoneGrade)
{
switch (lifeStoneGrade)
{
case GRADE_ACC:
switch (itemGrade)
{
case C:
return 200;
case B:
return 300;
case A:
return 200;
case S:
return 250;
case S80:
return 360;
case S84:
return 480;
default:
return 0;
}
default:
switch (itemGrade)
{
case C:
return 20;
case B:
return 30;
case A:
return 20;
case S:
return 25;
case S80:
case S84:
return 36;
default:
return 0;
}
}
}
}