package javastory.channel.handling;
import java.util.Map;
import javastory.channel.ChannelCharacter;
import javastory.channel.ChannelClient;
import javastory.channel.server.InventoryManipulator;
import javastory.game.Equip;
import javastory.game.GameConstants;
import javastory.game.Inventory;
import javastory.game.Item;
import javastory.game.Jobs;
import javastory.game.data.GemInfo;
import javastory.game.data.ItemInfoProvider;
import javastory.game.data.ItemMakerFactory;
import javastory.game.data.ItemRecipe;
import javastory.game.data.ItemRecipeEntry;
import javastory.game.data.MakerItemInfo;
import javastory.game.data.SkillInfoProvider;
import javastory.io.PacketFormatException;
import javastory.io.PacketReader;
import javastory.tools.Randomizer;
import javastory.tools.packets.ChannelPackets;
public class ItemMakerHandler {
public static void handleItemMaker(final PacketReader reader, final ChannelClient c) throws PacketFormatException {
final int makerType = reader.readInt();
switch (makerType) {
case 1:
makeGem(reader, c);
break;
case 3:
makeCrystal(reader, c);
break;
case 4:
disassemble(reader, c);
break;
}
}
private static boolean disassemble(final PacketReader reader, final ChannelClient c) throws PacketFormatException {
// Disassembling EQ.
final int itemId = reader.readInt();
reader.skip(4);
final byte slot = (byte) reader.readInt();
final ChannelCharacter player = c.getPlayer();
final Inventory equipInventory = player.getEquipInventory();
final Item toUse = equipInventory.getItem(slot);
if (toUse == null || toUse.getItemId() != itemId || toUse.getQuantity() < 1) {
return true;
}
final ItemInfoProvider ii = ItemInfoProvider.getInstance();
if (!ii.isDropRestricted(itemId)) {
final int[] toGive = getCrystal(itemId, ii.getReqLevel(itemId));
InventoryManipulator.addById(c, toGive[0], (byte) toGive[1]);
InventoryManipulator.removeFromSlot(c, equipInventory, slot, (byte) 1, false);
}
c.write(ChannelPackets.ItemMaker_Success());
player.getMap().broadcastMessage(player, ChannelPackets.ItemMaker_Success_3rdParty(player.getId()), false);
return false;
}
private static void makeCrystal(final PacketReader reader, final ChannelClient c) throws PacketFormatException {
// Making Crystals
final int etc = reader.readInt();
final ChannelCharacter player = c.getPlayer();
final Inventory etcInventory = player.getEtcInventory();
if (player.haveItem(etc, 100, false, true)) {
InventoryManipulator.addById(c, getCreateCrystal(etc), (short) 1);
InventoryManipulator.removeById(c, etcInventory, etc, 100, false, false);
c.write(ChannelPackets.ItemMaker_Success());
player.getMap().broadcastMessage(player, ChannelPackets.ItemMaker_Success_3rdParty(player.getId()), false);
}
}
private static boolean makeGem(final PacketReader reader, final ChannelClient c) throws PacketFormatException {
// Gem
final int toCreate = reader.readInt();
final ChannelCharacter player = c.getPlayer();
if (GameConstants.isGem(toCreate)) {
final GemInfo gem = ItemMakerFactory.getInstance().getGemInfo(toCreate);
if (!hasSkill(c, gem.getRequiredSkillLevel())) {
return true;
}
if (player.getMeso() < gem.getCost()) {
return true;
}
final int gemItemId = gem.chooseRandomReward();
if (player.getInventoryForItem(gemItemId).isFull()) {
return true;
}
final int taken = checkRequiredNRemove(c, gem.getRecipe());
if (taken == 0) {
return true;
}
player.gainMeso(-gem.getCost(), false);
InventoryManipulator.addById(c, gemItemId, (byte) (taken == gemItemId ? 9 : 1)); // Gem
// is
// always
// 1
c.write(ChannelPackets.ItemMaker_Success());
player.getMap().broadcastMessage(player, ChannelPackets.ItemMaker_Success_3rdParty(player.getId()), false);
} else {
final boolean stimulator = reader.readByte() > 0;
final int numEnchanter = reader.readInt();
final MakerItemInfo create = ItemMakerFactory.getInstance().getItemInfo(toCreate);
if (numEnchanter > create.TUC) {
return true;
}
if (!hasSkill(c, create.ReqMakerLevel)) {
return true;
}
if (player.getMeso() < create.Cost) {
return true;
}
if (player.getInventoryForItem(toCreate).isFull()) {
return true;
}
if (checkRequiredNRemove(c, create.getRecipe()) == 0) {
return true;
}
player.gainMeso(-create.Cost, false);
final ItemInfoProvider ii = ItemInfoProvider.getInstance();
final Equip toGive = (Equip) ii.getEquipById(toCreate);
final Inventory etcInventory = player.getEtcInventory();
if (stimulator || numEnchanter > 0) {
if (player.haveItem(create.Stimulator, 1, false, true)) {
ii.randomizeStats(toGive);
InventoryManipulator.removeById(c, etcInventory, create.Stimulator, 1, false, false);
}
for (int i = 0; i < numEnchanter; i++) {
final int enchant = reader.readInt();
if (player.haveItem(enchant, 1, false, true)) {
final Map<String, Byte> stats = ii.getItemMakeStats(enchant);
if (stats != null) {
addEnchantStats(stats, toGive);
InventoryManipulator.removeById(c, etcInventory, enchant, 1, false, false);
}
}
}
}
InventoryManipulator.addbyItem(c, toGive);
c.write(ChannelPackets.ItemMaker_Success());
player.getMap().broadcastMessage(player, ChannelPackets.ItemMaker_Success_3rdParty(player.getId()), false);
}
return false;
}
private static int getCreateCrystal(final int etc) {
int itemid;
final short level = ItemInfoProvider.getInstance().getItemMakeLevel(etc);
if (level >= 31 && level <= 50) {
itemid = 4260000;
} else if (level >= 51 && level <= 60) {
itemid = 4260001;
} else if (level >= 61 && level <= 70) {
itemid = 4260002;
} else if (level >= 71 && level <= 80) {
itemid = 4260003;
} else if (level >= 81 && level <= 90) {
itemid = 4260004;
} else if (level >= 91 && level <= 100) {
itemid = 4260005;
} else if (level >= 101 && level <= 110) {
itemid = 4260006;
} else if (level >= 111 && level <= 120) {
itemid = 4260007;
} else if (level >= 121) {
itemid = 4260008;
} else {
throw new RuntimeException("Invalid Item Maker id");
}
return itemid;
}
private static int[] getCrystal(final int itemid, final int level) {
final int[] all = new int[2];
all[0] = -1;
if (level >= 31 && level <= 50) {
all[0] = 4260000;
} else if (level >= 51 && level <= 60) {
all[0] = 4260001;
} else if (level >= 61 && level <= 70) {
all[0] = 4260002;
} else if (level >= 71 && level <= 80) {
all[0] = 4260003;
} else if (level >= 81 && level <= 90) {
all[0] = 4260004;
} else if (level >= 91 && level <= 100) {
all[0] = 4260005;
} else if (level >= 101 && level <= 110) {
all[0] = 4260006;
} else if (level >= 111 && level <= 120) {
all[0] = 4260007;
} else if (level >= 121 && level <= 200) {
all[0] = 4260008;
} else {
throw new RuntimeException("Invalid Item Maker type" + level);
}
if (GameConstants.isWeapon(itemid) || GameConstants.isOverall(itemid)) {
all[1] = Randomizer.rand(5, 11);
} else {
all[1] = Randomizer.rand(3, 7);
}
return all;
}
private static void addEnchantStats(final Map<String, Byte> stats, final Equip item) {
short s = stats.get("incPAD");
if (s != 0) {
item.setWatk((short) (item.getWatk() + s));
}
s = stats.get("incMAD");
if (s != 0) {
item.setMatk((short) (item.getMatk() + s));
}
s = stats.get("incACC");
if (s != 0) {
item.setAcc((short) (item.getAcc() + s));
}
s = stats.get("incEVA");
if (s != 0) {
item.setAvoid((short) (item.getAvoid() + s));
}
s = stats.get("incSpeed");
if (s != 0) {
item.setSpeed((short) (item.getSpeed() + s));
}
s = stats.get("incJump");
if (s != 0) {
item.setJump((short) (item.getJump() + s));
}
s = stats.get("incMaxHP");
if (s != 0) {
item.setHp((short) (item.getHp() + s));
}
s = stats.get("incMaxMP");
if (s != 0) {
item.setMp((short) (item.getMp() + s));
}
s = stats.get("incSTR");
if (s != 0) {
item.setStr((short) (item.getStr() + s));
}
s = stats.get("incDEX");
if (s != 0) {
item.setDex((short) (item.getDex() + s));
}
s = stats.get("incINT");
if (s != 0) {
item.setInt((short) (item.getInt() + s));
}
s = stats.get("incLUK");
if (s != 0) {
item.setLuk((short) (item.getLuk() + s));
}
s = stats.get("randOption");
if (s > 0) {
final boolean success = Randomizer.nextBoolean();
final int ma = item.getMatk(), wa = item.getWatk();
if (wa > 0) {
item.setWatk((short) (success ? wa + s : wa - s));
}
if (ma > 0) {
item.setMatk((short) (success ? ma + s : ma - s));
}
}
s = stats.get("randStat");
if (s > 0) {
final boolean success = Randomizer.nextBoolean();
final int str = item.getStr(), dex = item.getDex(), luk = item.getLuk(), int_ = item.getInt();
if (str > 0) {
item.setStr((short) (success ? str + s : str - s));
}
if (dex > 0) {
item.setDex((short) (success ? dex + s : dex - s));
}
if (int_ > 0) {
item.setInt((short) (success ? int_ + s : int_ - s));
}
if (luk > 0) {
item.setLuk((short) (success ? luk + s : luk - s));
}
}
}
private static int checkRequiredNRemove(final ChannelClient c, final ItemRecipe recipe) {
int removed = 0;
final ChannelCharacter player = c.getPlayer();
for (final ItemRecipeEntry p : recipe) {
if (!player.haveItem(p.ItemId, p.Quantity, false, true)) {
return 0;
}
removed++;
}
for (final ItemRecipeEntry p : recipe) {
final int itemId = p.ItemId;
final Inventory inventory = player.getInventoryForItem(itemId);
InventoryManipulator.removeById(c, inventory, itemId, p.Quantity, false, false);
}
return removed;
}
private static boolean hasSkill(final ChannelClient c, final int reqlvl) {
final ChannelCharacter player = c.getPlayer();
if (Jobs.isCygnus(player.getJobId())) { // KoC Maker skill.
return player.getCurrentSkillLevel(SkillInfoProvider.getSkill(10001007)) >= reqlvl;
} else if (Jobs.isAran(player.getJobId())) { // KoC Maker skill.
return player.getCurrentSkillLevel(SkillInfoProvider.getSkill(20001007)) >= reqlvl;
} else {
return player.getCurrentSkillLevel(SkillInfoProvider.getSkill(1007)) >= reqlvl;
}
}
}