package server;
import client.MapleCharacter;
import client.MapleTrait.MapleTraitType;
import client.inventory.Equip;
import client.inventory.Item;
import client.inventory.ItemFlag;
import client.inventory.MapleInventoryType;
import constants.GameConstants;
import constants.ItemConstants;
import database.DatabaseConnection;
import handling.channel.handler.EquipmentEnchant;
import java.awt.Point;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import provider.MapleData;
import provider.MapleDataDirectoryEntry;
import provider.MapleDataEntry;
import provider.MapleDataFileEntry;
import provider.MapleDataProvider;
import provider.MapleDataProviderFactory;
import provider.MapleDataTool;
import provider.wz.MapleDataType;
import server.StructSetItem.SetItem;
import server.farm.inventory.FarmItemInformation;
import tools.Pair;
import tools.StringUtil;
import tools.Triple;
import tools.packet.CWvsContext;
public class MapleItemInformationProvider {
private final static MapleItemInformationProvider instance = new MapleItemInformationProvider();
protected final MapleDataProvider chrData = MapleDataProviderFactory.getDataProvider("Character.wz");
protected final MapleDataProvider etcData = MapleDataProviderFactory.getDataProvider("Etc.wz");
protected final MapleDataProvider itemData = MapleDataProviderFactory.getDataProvider("Item.wz");
protected final MapleDataProvider stringData = MapleDataProviderFactory.getDataProvider("String.wz");
protected final Map<Integer, ItemInformation> dataCache = new TreeMap<>((v1, v2) -> v1.compareTo(v2));
protected final Map<Integer, Short> petFlagInfo = new TreeMap<>((v1, v2) -> v1.compareTo(v2));
protected final Map<Integer, FarmItemInformation> farmDataCache = new TreeMap<>((v1, v2) -> v1.compareTo(v2));
protected final Map<String, List<Triple<String, Point, Point>>> afterImage = new HashMap<>();
protected final Map<Integer, List<StructItemOption>> potentialCache = new HashMap<>();
protected final Map<Integer, Map<Integer, StructItemOption>> socketCache = new HashMap<>(); // Grade, (id, data)
protected final Map<Integer, MapleStatEffect> itemEffects = new TreeMap<>((v1, v2) -> v1.compareTo(v2));
protected final Map<Integer, MapleStatEffect> itemEffectsEx = new TreeMap<>((v1, v2) -> v1.compareTo(v2));
protected final Map<Integer, Integer> mobIds = new TreeMap<>((v1, v2) -> v1.compareTo(v2));
protected final Map<Integer, Pair<Integer, Integer>> potLife = new HashMap<>(); //itemid to lifeid, levels
protected final Map<Integer, StructFamiliar> familiars = new HashMap<>(); //by familiarID
protected final Map<Integer, StructFamiliar> familiars_Item = new HashMap<>(); //by cardID
protected final Map<Integer, StructFamiliar> familiars_Mob = new HashMap<>(); //by mobID
protected Map<Integer, Integer> androidType = new TreeMap<>((v1, v2) -> v1.compareTo(v2));
protected Map<Integer, StructAndroid> androidInfo = new TreeMap<>((v1, v2) -> v1.compareTo(v2));
protected final Map<Integer, Triple<Integer, List<Integer>, List<Integer>>> monsterBookSets = new TreeMap<>((v1, v2) -> v1.compareTo(v2));
protected final Map<Integer, StructSetItem> setItems = new HashMap<>();
protected final Map<Integer, Boolean> noCursedScroll = new HashMap();
protected final Map<Integer, Boolean> noNegativeScroll = new HashMap();
protected final Map<Integer, Integer> forceUpgrade = new HashMap();
protected Map<Integer, Map<String, String>> expCardTimes = new HashMap();
protected final Map<Integer, Pair<Integer, Integer>> socketReqLevel = new TreeMap<>((v1, v2) -> v1.compareTo(v2));
protected final Map<Integer, Integer> soulSkill = new TreeMap<>((v1, v2) -> v1.compareTo(v2));
protected final Map<Integer, ArrayList<Integer>> tempOption = new TreeMap<>((v1, v2) -> v1.compareTo(v2));
protected final Map<Integer, String> faceList = new TreeMap<>((v1, v2) -> v1.compareTo(v2));
protected final Map<Integer, String> hairList = new TreeMap<>((v1, v2) -> v1.compareTo(v2));
public void runEtc(boolean reload) {
if (reload) {
setItems.clear();
potentialCache.clear();
socketCache.clear();
androidInfo.clear();
potLife.clear();
afterImage.clear();
}
if (!setItems.isEmpty() || !potentialCache.isEmpty() || !socketCache.isEmpty() || !androidInfo.isEmpty() || !potLife.isEmpty() || !afterImage.isEmpty()) {
return;
}
final MapleData setsData = etcData.getData("SetItemInfo.img");
StructSetItem itemz;
SetItem itez;
for (MapleData dat : setsData) {
itemz = new StructSetItem();
itemz.setItemID = Integer.parseInt(dat.getName());
itemz.completeCount = (byte) MapleDataTool.getIntConvert("completeCount", dat, 0);
for (MapleData level : dat.getChildByPath("ItemID")) {
if (level.getType() != MapleDataType.INT) {
for (MapleData leve : level) {
if (!leve.getName().equals("representName") && !leve.getName().equals("typeName")) {
itemz.itemIDs.add(MapleDataTool./*getInt*/getIntConvert(leve));
}
}
} else {
itemz.itemIDs.add(MapleDataTool.getInt(level));
}
}
for (MapleData level : dat.getChildByPath("Effect")) {
itez = new SetItem();
itez.incPDD = MapleDataTool.getIntConvert("incPDD", level, 0);
itez.incMDD = MapleDataTool.getIntConvert("incMDD", level, 0);
itez.incSTR = MapleDataTool.getIntConvert("incSTR", level, 0);
itez.incDEX = MapleDataTool.getIntConvert("incDEX", level, 0);
itez.incINT = MapleDataTool.getIntConvert("incINT", level, 0);
itez.incLUK = MapleDataTool.getIntConvert("incLUK", level, 0);
itez.incACC = MapleDataTool.getIntConvert("incACC", level, 0);
itez.incPAD = MapleDataTool.getIntConvert("incPAD", level, 0);
itez.incMAD = MapleDataTool.getIntConvert("incMAD", level, 0);
itez.incSpeed = MapleDataTool.getIntConvert("incSpeed", level, 0);
itez.incMHP = MapleDataTool.getIntConvert("incMHP", level, 0);
itez.incMMP = MapleDataTool.getIntConvert("incMMP", level, 0);
itez.incMHPr = MapleDataTool.getIntConvert("incMHPr", level, 0);
itez.incMMPr = MapleDataTool.getIntConvert("incMMPr", level, 0);
itez.incAllStat = MapleDataTool.getIntConvert("incAllStat", level, 0);
itez.option1 = MapleDataTool.getIntConvert("Option/1/option", level, 0);
itez.option2 = MapleDataTool.getIntConvert("Option/2/option", level, 0);
itez.option1Level = MapleDataTool.getIntConvert("Option/1/level", level, 0);
itez.option2Level = MapleDataTool.getIntConvert("Option/2/level", level, 0);
itemz.items.put(Integer.parseInt(level.getName()), itez);
}
setItems.put(itemz.setItemID, itemz);
}
StructItemOption item;
final MapleData potsData = itemData.getData("ItemOption.img");
List<StructItemOption> items;
for (MapleData dat : potsData) {
items = new LinkedList<>();
for (MapleData potLevel : dat.getChildByPath("level")) {
item = new StructItemOption();
item.opID = Integer.parseInt(dat.getName());
item.optionType = MapleDataTool.getIntConvert("info/optionType", dat, 0);
item.reqLevel = MapleDataTool.getIntConvert("info/reqLevel", dat, 0);
for (final String i : StructItemOption.types) {
if (i.equals("face")) {
item.face = MapleDataTool.getString("face", potLevel, "");
} else {
final int level = MapleDataTool.getIntConvert(i, potLevel, 0);
if (level > 0) { // Save memory
item.data.put(i, level);
}
}
}
switch (item.opID) {
case 31001: // Haste
case 31002: // Mystic Door
case 31003: // Sharp Eyes
case 31004: // Hyper Body
item.data.put("skillID", (item.opID - 23001));
break;
case 41005: // Combat Orders
case 41006: // Advanced Blessing
case 41007: // Speed Infusion
item.data.put("skillID", (item.opID - 33001));
break;
}
items.add(item);
}
potentialCache.put(Integer.parseInt(dat.getName()), items);
}
final Map<Integer, StructItemOption> gradeS = new HashMap<>();
final Map<Integer, StructItemOption> gradeA = new HashMap<>();
final Map<Integer, StructItemOption> gradeB = new HashMap<>();
final Map<Integer, StructItemOption> gradeC = new HashMap<>();
final Map<Integer, StructItemOption> gradeD = new HashMap<>();
/*final MapleData nebuliteData = itemData.getData("Install/0306.img");
for (MapleData dat : nebuliteData) {
item = new StructItemOption();
item.opID = Integer.parseInt(dat.getName()); // Item Id
item.optionType = MapleDataTool.getInt("optionType", dat.getChildByPath("socket"), 0);
for (MapleData info : dat.getChildByPath("socket/option")) {
final String optionString = MapleDataTool.getString("optionString", info, "");
final int level = MapleDataTool.getInt("level", info, 0);
if (level > 0) { // Save memory
item.data.put(optionString, level);
}
}
switch (item.opID) {
case 3063370: // Haste
item.data.put("skillID", 8000);
break;
case 3063380: // Mystic Door
item.data.put("skillID", 8001);
break;
case 3063390: // Sharp Eyes
item.data.put("skillID", 8002);
break;
case 3063400: // Hyper Body
item.data.put("skillID", 8003);
break;
case 3064470: // Combat Orders
item.data.put("skillID", 8004);
break;
case 3064480: // Advanced Blessing
item.data.put("skillID", 8005);
break;
case 3064490: // Speed Infusion
item.data.put("skillID", 8006);
break;
}
switch (GameConstants.getNebuliteGrade(item.opID)) {
case 4: //S
gradeS.put(Integer.parseInt(dat.getName()), item);
break;
case 3: //A
gradeA.put(Integer.parseInt(dat.getName()), item);
break;
case 2: //B
gradeB.put(Integer.parseInt(dat.getName()), item);
break;
case 1: //C
gradeC.put(Integer.parseInt(dat.getName()), item);
break;
case 0: //D
gradeD.put(Integer.parseInt(dat.getName()), item);
break; // impossible to be -1 since we're looping in 306.img.xml
}
}*/
socketCache.put(4, gradeS);
socketCache.put(3, gradeA);
socketCache.put(2, gradeB);
socketCache.put(1, gradeC);
socketCache.put(0, gradeD);
final MapleDataDirectoryEntry e = (MapleDataDirectoryEntry) etcData.getRoot().getEntry("Android");
for (MapleDataEntry d : e.getFiles()) {
final MapleData iz = etcData.getData("Android/" + d.getName());
StructAndroid android = new StructAndroid();
int type = Integer.parseInt(d.getName().substring(0, 4));
android.type = type;
android.gender = MapleDataTool.getIntConvert("info/gender", iz, 0);
for (MapleData ds : iz.getChildByPath("costume/skin")) {
android.skin.add(MapleDataTool.getInt(ds, 2000));
}
for (MapleData ds : iz.getChildByPath("costume/hair")) {
android.hair.add(MapleDataTool.getInt(ds, android.gender == 0 ? 20101 : 21101));
}
for (MapleData ds : iz.getChildByPath("costume/face")) {
android.face.add(MapleDataTool.getInt(ds, android.gender == 0 ? 30110 : 31510));
}
androidInfo.put(type, android);
}
final MapleData lifesData = etcData.getData("ItemPotLifeInfo.img");
for (MapleData d : lifesData) {
if (d.getChildByPath("info") != null && MapleDataTool.getInt("type", d.getChildByPath("info"), 0) == 1) {
potLife.put(MapleDataTool.getInt("counsumeItem", d.getChildByPath("info"), 0), new Pair<>(Integer.parseInt(d.getName()), d.getChildByPath("level").getChildren().size()));
}
}
List<Triple<String, Point, Point>> thePointK = new ArrayList<>();
List<Triple<String, Point, Point>> thePointA = new ArrayList<>();
final MapleDataDirectoryEntry a = (MapleDataDirectoryEntry) chrData.getRoot().getEntry("Afterimage");
for (MapleDataEntry b : a.getFiles()) {
final MapleData iz = chrData.getData("Afterimage/" + b.getName());
List<Triple<String, Point, Point>> thePoint = new ArrayList<>();
Map<String, Pair<Point, Point>> dummy = new HashMap<>();
for (MapleData i : iz) {
for (MapleData xD : i) {
if (xD.getName().contains("prone") || xD.getName().contains("double") || xD.getName().contains("triple")) {
continue;
}
if ((b.getName().contains("bow") || b.getName().contains("Bow")) && !xD.getName().contains("shoot")) {
continue;
}
if ((b.getName().contains("gun") || b.getName().contains("cannon")) && !xD.getName().contains("shot")) {
continue;
}
if (dummy.containsKey(xD.getName())) {
if (xD.getChildByPath("lt") != null) {
Point lt = (Point) xD.getChildByPath("lt").getData();
Point ourLt = dummy.get(xD.getName()).left;
if (lt.x < ourLt.x) {
ourLt.x = lt.x;
}
if (lt.y < ourLt.y) {
ourLt.y = lt.y;
}
}
if (xD.getChildByPath("rb") != null) {
Point rb = (Point) xD.getChildByPath("rb").getData();
Point ourRb = dummy.get(xD.getName()).right;
if (rb.x > ourRb.x) {
ourRb.x = rb.x;
}
if (rb.y > ourRb.y) {
ourRb.y = rb.y;
}
}
} else {
Point lt = null, rb = null;
if (xD.getChildByPath("lt") != null) {
lt = (Point) xD.getChildByPath("lt").getData();
}
if (xD.getChildByPath("rb") != null) {
rb = (Point) xD.getChildByPath("rb").getData();
}
dummy.put(xD.getName(), new Pair<>(lt, rb));
}
}
}
for (Entry<String, Pair<Point, Point>> ez : dummy.entrySet()) {
if (ez.getKey().length() > 2 && ez.getKey().substring(ez.getKey().length() - 2, ez.getKey().length() - 1).equals("D")) { //D = double weapon
thePointK.add(new Triple<>(ez.getKey(), ez.getValue().left, ez.getValue().right));
} else if (ez.getKey().contains("PoleArm")) { //D = double weapon
thePointA.add(new Triple<>(ez.getKey(), ez.getValue().left, ez.getValue().right));
} else {
thePoint.add(new Triple<>(ez.getKey(), ez.getValue().left, ez.getValue().right));
}
}
afterImage.put(b.getName().substring(0, b.getName().length() - 4), thePoint);
}
afterImage.put("katara", thePointK); //hackish
afterImage.put("aran", thePointA); //hackish
}
public void runItems(boolean reload) {
if (reload) {
dataCache.clear();
}
if (!dataCache.isEmpty()) {
return;
}
//these must be loaded before items..
/*final MapleData fData = etcData.getData("FamiliarInfo.img");
for (MapleData d : fData) {
StructFamiliar f = new StructFamiliar();
f.grade = 0;
f.mob = MapleDataTool.getInt("mob", d, 0);
f.passive = MapleDataTool.getInt("passive", d, 0);
f.itemid = MapleDataTool.getInt("consume", d, 0);
f.familiar = Integer.parseInt(d.getName());
familiars.put(f.familiar, f);
familiars_Item.put(f.itemid, f);
familiars_Mob.put(f.mob, f);
}*/
/*final MapleDataDirectoryEntry e = (MapleDataDirectoryEntry) chrData.getRoot().getEntry("Familiar");
for (MapleDataEntry d : e.getFiles()) {
final int id = Integer.parseInt(d.getName().substring(0, d.getName().length() - 4));
if (familiars.containsKey(id)) {
familiars.get(id).grade = (byte) MapleDataTool.getInt("grade", chrData.getData("Familiar/" + d.getName()).getChildByPath("info"), 0);
}
}*/
/*final MapleData mSetsData = etcData.getData("MonsterBookSet.img");
for (MapleData d : mSetsData.getChildByPath("setList")) {
if (MapleDataTool.getInt("deactivated", d, 0) > 0) {
continue;
}
final List<Integer> set = new ArrayList<>(), potential = new ArrayList<>(3);
for (MapleData ds : d.getChildByPath("stats/potential")) {
if (ds.getType() != MapleDataType.STRING && MapleDataTool.getInt(ds, 0) > 0) {
potential.add(MapleDataTool.getInt(ds, 0));
if (potential.size() >= 5) {
break;
}
}
}
for (MapleData ds : d.getChildByPath("cardList")) {
set.add(MapleDataTool.getInt(ds, 0));
}
monsterBookSets.put(Integer.parseInt(d.getName()), new Triple<>(MapleDataTool.getInt("setScore", d, 0), set, potential));
}*/
try {
Connection con = DatabaseConnection.getConnection();
// Load Item Data
PreparedStatement ps = con.prepareStatement("SELECT * FROM wz_itemdata");
ResultSet rs = ps.executeQuery();
while (rs.next()) {
initItemInformation(rs);
}
rs.close();
ps.close();
// Load Item Equipment Data
ps = con.prepareStatement("SELECT * FROM wz_itemequipdata ORDER BY itemid");
rs = ps.executeQuery();
while (rs.next()) {
initItemEquipData(rs);
}
rs.close();
ps.close();
// Load Item Addition Data
ps = con.prepareStatement("SELECT * FROM wz_itemadddata ORDER BY itemid");
rs = ps.executeQuery();
while (rs.next()) {
initItemAddData(rs);
}
rs.close();
ps.close();
// Load Item Reward Data
ps = con.prepareStatement("SELECT * FROM wz_itemrewarddata ORDER BY itemid");
rs = ps.executeQuery();
while (rs.next()) {
initItemRewardData(rs);
}
rs.close();
ps.close();
// Finalize all Equipments
for (Entry<Integer, ItemInformation> entry : dataCache.entrySet()) {
if (GameConstants.getInventoryType(entry.getKey()) == MapleInventoryType.EQUIP) {
finalizeEquipData(entry.getValue());
}
}
} catch (SQLException ex) {
}
//System.out.println(dataCache.size() + " items loaded.");
}
public final void loadHairFace(boolean reload) {
if (reload) {
hairList.clear();
faceList.clear();
}
if (!hairList.isEmpty() || !faceList.isEmpty()) {
return;
}
String[] types = {"Hair", "Face"};
for (String type : types) {
for (MapleData c : stringData.getData("Eqp.img").getChildByPath("Eqp/" + type)) {
if (chrData.getData(type + "/" + StringUtil.getLeftPaddedStr(c.getName() + ".img", '0', 12)) != null) {
int dataid = Integer.parseInt(c.getName());
String name = MapleDataTool.getString("name", c, "無名稱");
if (type.equals("Hair")) {
hairList.put(dataid, name);
} else {
faceList.put(dataid, name);
}
}
}
}
}
public boolean hairExists(int hair) {
return hairList.containsKey(hair);
}
public boolean faceExists(int face) {
return faceList.containsKey(face);
}
public final Map<Integer, String> getHairList() {
Map<Integer, String> list = new TreeMap<>((v1, v2) -> v1.compareTo(v2));
list.putAll(hairList);
return list;
}
public final Map<Integer, String> getFaceList() {
Map<Integer, String> list = new TreeMap<>((v1, v2) -> v1.compareTo(v2));
list.putAll(faceList);
return list;
}
public final List<StructItemOption> getPotentialInfo(final int potId) {
return potentialCache.get(potId);
}
public final Map<Integer, List<StructItemOption>> getAllPotentialInfo() {
return potentialCache;
}
public final StructItemOption getSocketInfo(final int potId) {
final int grade = GameConstants.getNebuliteGrade(potId);
if (grade == -1) {
return null;
}
return socketCache.get(grade).get(potId);
}
public final Map<Integer, StructItemOption> getAllSocketInfo(final int grade) {
return socketCache.get(grade);
}
public final Collection<Integer> getMonsterBookList() {
return mobIds.values();
}
public final Map<Integer, Integer> getMonsterBook() {
return mobIds;
}
public final Pair<Integer, Integer> getPot(int f) {
return potLife.get(f);
}
public final StructFamiliar getFamiliar(int f) {
return familiars.get(f);
}
public final Map<Integer, StructFamiliar> getFamiliars() {
return familiars;
}
public final StructFamiliar getFamiliarByItem(int f) {
return familiars_Item.get(f);
}
public final StructFamiliar getFamiliarByMob(int f) {
return familiars_Mob.get(f);
}
public static final MapleItemInformationProvider getInstance() {
return instance;
}
public final Collection<ItemInformation> getAllItems() {
return dataCache.values();
}
public final StructAndroid getAndroidInfo(int i) {
return (StructAndroid) this.androidInfo.get(i);
}
public final Triple<Integer, List<Integer>, List<Integer>> getMonsterBookInfo(int i) {
return monsterBookSets.get(i);
}
public final Map<Integer, Triple<Integer, List<Integer>, List<Integer>>> getAllMonsterBookInfo() {
return monsterBookSets;
}
public final MapleData getItemData(final int itemId) {
MapleData ret = null;
final String idStr = "0" + String.valueOf(itemId);
MapleDataDirectoryEntry root = itemData.getRoot();
for (final MapleDataDirectoryEntry topDir : root.getSubdirectories()) {
// we should have .img files here beginning with the first 4 IID
for (final MapleDataFileEntry iFile : topDir.getFiles()) {
if (iFile.getName().equals(idStr.substring(0, 4) + ".img")) {
ret = itemData.getData(topDir.getName() + "/" + iFile.getName());
if (ret == null) {
return null;
}
ret = ret.getChildByPath(idStr);
return ret;
} else if (iFile.getName().equals(idStr.substring(1) + ".img")) {
ret = itemData.getData(topDir.getName() + "/" + iFile.getName());
return ret;
}
}
}
//equips dont have item effects :)
/*
* root = equipData.getRoot(); for (final MapleDataDirectoryEntry topDir
* : root.getSubdirectories()) { for (final MapleDataFileEntry iFile :
* topDir.getFiles()) { if (iFile.getName().equals(idStr + ".img")) {
* ret = equipData.getData(topDir.getName() + "/" + iFile.getName());
* return ret; } }
}
*/
root = chrData.getRoot();
for (final MapleDataDirectoryEntry topDir : root.getSubdirectories()) {
for (final MapleDataFileEntry iFile : topDir.getFiles()) {
if (iFile.getName().equals(idStr + ".img")) {
return chrData.getData(topDir.getName() + "/" + iFile.getName());
}
}
}
return ret;
}
public Integer getItemIdByMob(int mobId) {
return mobIds.get(mobId);
}
public Integer getSetId(int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return null;
}
return i.cardSet;
}
public List<Pair<Integer, String>> getAllItems2() {
//if (!itemNameCache.isEmpty()) {
// return itemNameCache;
//}
List<Pair<Integer, String>> itemPairs = new ArrayList<>();
MapleData itemsData;
itemsData = stringData.getData("Cash.img");
for (MapleData itemFolder : itemsData.getChildren()) {
itemPairs.add(new Pair<>(Integer.parseInt(itemFolder.getName()), MapleDataTool.getString("name", itemFolder, "NO-NAME")));
}
itemsData = stringData.getData("Consume.img");
for (MapleData itemFolder : itemsData.getChildren()) {
itemPairs.add(new Pair<>(Integer.parseInt(itemFolder.getName()), MapleDataTool.getString("name", itemFolder, "NO-NAME")));
}
itemsData = stringData.getData("Eqp.img").getChildByPath("Eqp");
for (MapleData eqpType : itemsData.getChildren()) {
for (MapleData itemFolder : eqpType.getChildren()) {
itemPairs.add(new Pair<>(Integer.parseInt(itemFolder.getName()), MapleDataTool.getString("name", itemFolder, "NO-NAME")));
}
}
itemsData = stringData.getData("Etc.img").getChildByPath("Etc");
for (MapleData itemFolder : itemsData.getChildren()) {
itemPairs.add(new Pair<>(Integer.parseInt(itemFolder.getName()), MapleDataTool.getString("name", itemFolder, "NO-NAME")));
}
itemsData = stringData.getData("Ins.img");
for (MapleData itemFolder : itemsData.getChildren()) {
itemPairs.add(new Pair<>(Integer.parseInt(itemFolder.getName()), MapleDataTool.getString("name", itemFolder, "NO-NAME")));
}
itemsData = stringData.getData("Pet.img");
for (MapleData itemFolder : itemsData.getChildren()) {
itemPairs.add(new Pair<>(Integer.parseInt(itemFolder.getName()), MapleDataTool.getString("name", itemFolder, "NO-NAME")));
}
return itemPairs;
}
/**
* returns the maximum of items in one slot
*
* @param itemId
* @return
*/
public final short getSlotMax(final int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return 0;
}
return i.slotMax;
}
public final int getWholePrice(final int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return 0;
}
return i.wholePrice;
}
public final double getPrice(final int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return -1.0;
}
return i.price;
}
protected int rand(int min, int max) {
return Math.abs(Randomizer.rand(min, max));
}
public Equip levelUpEquip(Equip equip, Map<String, Integer> sta) {
Equip nEquip = (Equip) equip.copy();
//is this all the stats?
try {
for (Entry<String, Integer> stat : sta.entrySet()) {
switch (stat.getKey()) {
case "STRMin":
nEquip.setStr((short) (nEquip.getStr() + rand(stat.getValue(), sta.get("STRMax"))));
break;
case "DEXMin":
nEquip.setDex((short) (nEquip.getDex() + rand(stat.getValue(), sta.get("DEXMax"))));
break;
case "INTMin":
nEquip.setInt((short) (nEquip.getInt() + rand(stat.getValue(), sta.get("INTMax"))));
break;
case "LUKMin":
nEquip.setLuk((short) (nEquip.getLuk() + rand(stat.getValue(), sta.get("LUKMax"))));
break;
case "PADMin":
nEquip.setWatk((short) (nEquip.getWatk() + rand(stat.getValue(), sta.get("PADMax"))));
break;
case "PDDMin":
nEquip.setWdef((short) (nEquip.getWdef() + rand(stat.getValue(), sta.get("PDDMax"))));
break;
case "MADMin":
nEquip.setMatk((short) (nEquip.getMatk() + rand(stat.getValue(), sta.get("MADMax"))));
break;
case "MDDMin":
nEquip.setMdef((short) (nEquip.getMdef() + rand(stat.getValue(), sta.get("MDDMax"))));
break;
case "ACCMin":
nEquip.setAcc((short) (nEquip.getAcc() + rand(stat.getValue(), sta.get("ACCMax"))));
break;
case "EVAMin":
nEquip.setAvoid((short) (nEquip.getAvoid() + rand(stat.getValue(), sta.get("EVAMax"))));
break;
case "SpeedMin":
nEquip.setSpeed((short) (nEquip.getSpeed() + rand(stat.getValue(), sta.get("SpeedMax"))));
break;
case "JumpMin":
nEquip.setJump((short) (nEquip.getJump() + rand(stat.getValue(), sta.get("JumpMax"))));
break;
case "MHPMin":
nEquip.setHp((short) (nEquip.getHp() + rand(stat.getValue(), sta.get("MHPMax"))));
break;
case "MMPMin":
nEquip.setMp((short) (nEquip.getMp() + rand(stat.getValue(), sta.get("MMPMax"))));
break;
case "MaxHPMin":
nEquip.setHp((short) (nEquip.getHp() + rand(stat.getValue(), sta.get("MaxHPMax"))));
break;
case "MaxMPMin":
nEquip.setMp((short) (nEquip.getMp() + rand(stat.getValue(), sta.get("MaxMPMax"))));
break;
}
}
} catch (NullPointerException e) {
}
return nEquip;
}
public final List<Triple<String, String, String>> getEquipAdditions(final int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return null;
}
return i.equipAdditions;
}
public final String getEquipAddReqs(final int itemId, final String key, final String sub) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return null;
}
for (Triple<String, String, String> data : i.equipAdditions) {
if (data.getLeft().equals("key") && data.getMid().equals("con:" + sub)) {
return data.getRight();
}
}
return null;
}
public final Map<Integer, Map<String, Integer>> getEquipIncrements(final int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return null;
}
return i.equipIncs;
}
public final List<Integer> getEquipSkills(final int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return null;
}
return i.incSkill;
}
public final Map<String, Integer> getEquipStats(final int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return null;
}
return i.equipStats;
}
public final boolean canEquip(final Map<String, Integer> stats, final int itemid, final int level, final int job, final int fame, final int str, final int dex, final int luk, final int int_, int supremacy, byte reqLevel) {
if (level + supremacy >= 0xFF) {
supremacy = 0xFF - level;
}
if ((level + supremacy) >= (reqLevel != 0 ? reqLevel : stats.containsKey("reqLevel") ? stats.get("reqLevel") : 0) && str >= (stats.containsKey("reqSTR") ? stats.get("reqSTR") : 0) && dex >= (stats.containsKey("reqDEX") ? stats.get("reqDEX") : 0) && luk >= (stats.containsKey("reqLUK") ? stats.get("reqLUK") : 0) && int_ >= (stats.containsKey("reqINT") ? stats.get("reqINT") : 0)) {
final Integer fameReq = stats.get("reqPOP");
return fameReq == null || fame >= fameReq;
}
return false;
}
public final int getReqLevel(final int itemId) {
if (getEquipStats(itemId) == null || !getEquipStats(itemId).containsKey("reqLevel")) {
return 0;
}
return getEquipStats(itemId).get("reqLevel");
}
public final int getSlots(final int itemId) {
if (getEquipStats(itemId) == null || !getEquipStats(itemId).containsKey("tuc")) {
return 0;
}
return getEquipStats(itemId).get("tuc");
}
public final Integer getSetItemID(final int itemId) {
if (getEquipStats(itemId) == null || !getEquipStats(itemId).containsKey("setItemID")) {
return 0;
}
return getEquipStats(itemId).get("setItemID");
}
public final StructSetItem getSetItem(final int setItemId) {
return setItems.get((byte) setItemId);
}
public final List<Integer> getScrollReqs(final int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return null;
}
return i.scrollReqs;
}
public int getScrollSuccess(int itemId) {
if (itemId / 10000 != 204 || getEquipStats(itemId) == null || !getEquipStats(itemId).containsKey("success")) {
return 0;
}
return (getEquipStats(itemId).get("success"));
}
public final Item scrollEquipWithId(final Item equip, final Item scroll, final boolean ws, final MapleCharacter chr, final int vegas) {
if (equip.getType() == 1) { // See Item.java
final Equip nEquip = (Equip) equip;
final Map<String, Integer> stats = getEquipStats(scroll.getItemId());
final Map<String, Integer> eqstats = getEquipStats(equip.getItemId());
//判斷捲軸成功率與爆率
int success;
int curse;
boolean noCursed = isNoCursedScroll(scroll.getItemId());
String scrollType;
int craft = chr.getTrait(MapleTraitType.craft).getLevel() / 10;
int lucksKey = ItemFlag.LUCKY_DAY.check(equip.getFlag()) ? 10 : 0;
if (ItemFlag.LUCKY_DAY.check(equip.getFlag()) && !ItemConstants.類型.潛能卷軸(scroll.getItemId()) && !ItemConstants.類型.附加潛能卷軸(scroll.getItemId()) && !ItemConstants.類型.裝備強化卷軸(scroll.getItemId()) && (!ItemConstants.類型.特殊卷軸(scroll.getItemId())) && !ItemConstants.類型.回真卷軸(scroll.getItemId())) {
equip.setFlag((short) (equip.getFlag() - ItemFlag.LUCKY_DAY.getValue()));
}
final int added = lucksKey + craft;
if (ItemConstants.類型.潛能卷軸(scroll.getItemId())) {
success = 0;
curse = 100;
if (scroll.getItemId() / 100 == 20494) {
scrollType = "普通";
curse = noCursed ? 0 : 100;
switch (scroll.getItemId()) {//普通卷轴成功率判断
case 2049402://超級潛在能力賦予卷軸
case 2049404://[6週年]潛在能力賦予卷軸
case 2049405://真. 楓葉之心項鍊專用潛在能力卷軸
case 2049406://特殊賦予潛在能力卷軸
case 2049414://紫色靈魂戒指專用潛在能力賦予卷軸
case 2049415://藍色靈魂戒指專用潛在能力賦予卷軸
case 2049417://特殊潛在能力賦予 卷軸
case 2049419://特別潛在能力賦予捲軸
case 2049423://恰吉面具潛能賦予卷軸
success = 100;
break;
case 2049400://高級潛在能力賦予卷軸
case 2049407://高級潛在能力賦予卷軸
case 2049412://高級潛在能力賦予卷軸
success = 90;
break;
case 2049421://心之項鍊潛在能力賦予卷軸
case 2049424://賦予卡爾頓的鬍子潛在能力卷軸
success = 80;
break;
case 2049401://潛在能力賦予卷軸
case 2049408://潛在能力賦予卷軸
case 2049416://潛在能力賦予卷軸
success = 70;
break;
default:
if (scroll.getItemId() >= 2049427 && scroll.getItemId() <= 2049446) {//賞金獵人
success = 100;
}
}
switch (scroll.getItemId()) {//專用捲軸失敗不爆物判斷
case 2049404://[6週年]潛在能力賦予卷軸
case 2049405://真. 楓葉之心項鍊專用潛在能力卷軸
case 2049414://紫色靈魂戒指專用潛在能力賦予卷軸
case 2049415://藍色靈魂戒指專用潛在能力賦予卷軸
case 2049421://心之項鍊潛在能力賦予卷軸
case 2049423://恰吉面具潛能賦予卷軸
case 2049424://賦予卡爾頓的鬍子潛在能力卷軸
case 2049426://10週年武器專用潛在能力附加卷軸
case 2049427://賞金獵人
scrollType = "專用";
curse = 0;
default:
if (scroll.getItemId() >= 2049427 && scroll.getItemId() <= 2049446) {//賞金獵人
scrollType = "專用";
curse = 0;
}
}
} else if (scroll.getItemId() / 100 == 20497) {
success = stats == null || !stats.containsKey("success") ? 0 : stats.get("success");
curse = noCursed ? 0 : stats == null || !stats.containsKey("cursed") ? 0 : stats.get("cursed");
if (scroll.getItemId() >= 2049700 && scroll.getItemId() < 2049750) {
scrollType = "特殊";
} else if (scroll.getItemId() >= 2049750 && scroll.getItemId() < 2049759) {
scrollType = "罕見";
} else if (scroll.getItemId() == 2049780 || scroll.getItemId() == 2049782) {
scrollType = "傳說";
} else {
success = 0;
scrollType = "未知";
}
} else {
scrollType = "未知";
}
scrollType += "潛能附加捲軸";
} else if (ItemConstants.類型.附加潛能卷軸(scroll.getItemId())) {
scrollType = "附加潛在能力附加捲軸";
success = ItemConstants.卷軸.getBonusPotentialScrollSucc(scroll.getItemId());
curse = ItemConstants.卷軸.getBonusPotentialScrollCurse(scroll.getItemId());
} else if (ItemConstants.類型.裝備強化卷軸(scroll.getItemId()) || ItemConstants.類型.回真卷軸(scroll.getItemId())) {
success = stats == null || !stats.containsKey("success") ? 0 : stats.get("success");
curse = noCursed ? 0 : stats == null || !stats.containsKey("cursed") ? 100 : stats.get("cursed");
if (ItemConstants.類型.裝備強化卷軸(scroll.getItemId())) {
scrollType = "強化捲軸";
if (getForceUpgrade(scroll.getItemId()) == 1 && success == 0) {
success = Math.max((scroll.getItemId() == 2049301 || scroll.getItemId() == 2049307 ? 80 : 100) - nEquip.getEnhance() * 10, 5);
}
} else {
scrollType = "回真捲軸";
}
} else {
if (ItemConstants.類型.幸運日卷軸(scroll.getItemId())) {
if (ItemConstants.類型.保護卷軸(scroll.getItemId())) {
scrollType = "幸運日+防爆捲軸";
} else {
scrollType = "幸運日捲軸";
}
} else if (ItemConstants.類型.保護卷軸(scroll.getItemId())) {
scrollType = "防爆捲軸";
} else if (ItemConstants.類型.安全卷軸(scroll.getItemId())) {
scrollType = "安全捲軸";
} else if (ItemConstants.類型.卷軸保護卡(scroll.getItemId())) {
scrollType = "捲軸保護卡";
} else if (ItemConstants.類型.白醫卷軸(scroll.getItemId())) {
scrollType = "白醫捲軸";
} else if (ItemConstants.類型.混沌卷軸(scroll.getItemId())) {
scrollType = "混沌捲軸";
} else {
scrollType = "普通捲軸";
}
success = stats == null || !stats.containsKey("success") ? ItemConstants.類型.提升卷(scroll.getItemId()) ? ItemConstants.卷軸.getSuccessTablet(scroll.getItemId(), nEquip.getLevel()) : 0 : stats.get("success");
curse = stats == null || !stats.containsKey("cursed") ? ItemConstants.類型.提升卷(scroll.getItemId()) ? ItemConstants.卷軸.getCurseTablet(scroll.getItemId(), nEquip.getLevel()) : 0 : stats.get("cursed");
success = (success + (vegas == 5610000 && success == 10 ? 20 : (vegas == 5610001 && success == 60 ? 30 : 0))) * (100 + added) / 100;
}
if (chr.isShowInfo()) {
chr.showMessage(30, scrollType + " - 默認幾率:" + success + "% 性向加成:" + craft + "% 幸運日加成:" + lucksKey + "% 最終概率:" + success + "% 失敗消失概率:" + curse + "%");
}
if (success <= 0) {
chr.dropMessage(1, "捲軸:" + scroll + " 成功幾率為:" + success + " 這個捲軸可能還未修復。");
chr.getClient().getSession().write(CWvsContext.enableActions());
return nEquip;
}
if (ItemConstants.類型.潛能卷軸(scroll.getItemId()) || ItemConstants.類型.附加潛能卷軸(scroll.getItemId()) || ItemConstants.類型.裝備強化卷軸(scroll.getItemId()) || ItemConstants.類型.特殊卷軸(scroll.getItemId()) || ItemConstants.類型.回真卷軸(scroll.getItemId()) || Randomizer.nextInt(100) <= success) {
if (ItemConstants.類型.幸運日卷軸(scroll.getItemId()) || ItemConstants.類型.保護卷軸(scroll.getItemId())) {
if (ItemConstants.類型.幸運日卷軸(scroll.getItemId())) {//幸運日
short flag = nEquip.getFlag();
flag = (short) (flag | ItemFlag.LUCKY_DAY.getValue());
nEquip.setFlag(flag);
}
if (ItemConstants.類型.保護卷軸(scroll.getItemId())) {//保護捲軸
short flag = nEquip.getFlag();
flag = (short) (flag | ItemFlag.SHIELD_WARD.getValue());
nEquip.setFlag(flag);
}
} else if (ItemConstants.類型.安全卷軸(scroll.getItemId())) {//安全捲軸
short flag = nEquip.getFlag();
flag = (short) (flag | ItemFlag.SLOTS_PROTECT.getValue());
nEquip.setFlag(flag);
} else if (ItemConstants.類型.卷軸保護卡(scroll.getItemId())) {//捲軸保護卡
short flag = nEquip.getFlag();
flag = (short) (flag | ItemFlag.SCROLL_PROTECT.getValue());
nEquip.setFlag(flag);
} else if (ItemConstants.類型.裝備強化卷軸(scroll.getItemId())) {//強化捲軸
if (Randomizer.nextInt(100) > success) {
if (Randomizer.nextInt(100) < curse) {
return null; //destroyed, nib
} else {
return nEquip;
}
}
for (int i = 0; i < Math.min(getForceUpgrade(scroll.getItemId()), ItemConstants.卷軸.getEnhanceTimes(nEquip.getItemId()) - nEquip.getEnhance()); i++) {
EquipmentEnchant.StarForceEnhanceItem(nEquip, false);
}
} else if (ItemConstants.類型.潛能卷軸(scroll.getItemId())) {//潛能捲軸
if (Randomizer.nextInt(100) > success) {
return Randomizer.nextInt(99) < curse ? null : nEquip;
}
if (scroll.getItemId() >= 2049700 && scroll.getItemId() < 2049750) {//稀有潛能捲軸
nEquip.resetPotential(2, nEquip.getPotential(3, false) != 0);
} else if (scroll.getItemId() >= 2049750 && scroll.getItemId() < 2049759) {//罕見潛能捲軸
nEquip.resetPotential(3, nEquip.getPotential(3, false) != 0);
} else if (scroll.getItemId() == 2049780 || scroll.getItemId() == 2049782) {//傳說潛能捲軸
nEquip.resetPotential(4, nEquip.getPotential(3, false) != 0);
} else if (scroll.getItemId() == 2049419) {//附加3條潛能
nEquip.resetPotential(true);
} else {
nEquip.resetPotential(false);
}
} else if (ItemConstants.類型.附加潛能卷軸(scroll.getItemId())) {//附加潛能捲軸
if (Randomizer.nextInt(100) > success) {
return Randomizer.nextInt(99) < curse ? null : nEquip;
}
if (scroll.getItemId() == 2048306) {//3行附加潛能捲軸
nEquip.resetPotential(true, true);
} else {
nEquip.resetPotential(true);
}
} else if (ItemConstants.類型.回真卷軸(scroll.getItemId())) {//回真捲軸
if (equip.getType() != 1) {
return equip;
}
if (Randomizer.nextInt(100) > success) {
return Randomizer.nextInt(99) < curse ? null : nEquip;
}
return resetEquipStats(nEquip);
} else if (scroll.getItemId() == 2040727) { // Spikes on shoe, prevents slip鞋子防滑卷軸10%
short flag = nEquip.getFlag();
flag |= ItemFlag.SPIKES.getValue();
nEquip.setFlag(flag);
} else if (scroll.getItemId() == 2041058) { // Cape for Cold protection披風防寒卷軸10%
short flag = nEquip.getFlag();
flag |= ItemFlag.COLD.getValue();
nEquip.setFlag(flag);
} else if (ItemConstants.類型.白醫卷軸(scroll.getItemId())) {//白醫捲軸
nEquip.setUpgradeSlots((byte) (nEquip.getUpgradeSlots() + (stats == null ? 0 : stats.get("recover"))));
} else if (ItemConstants.類型.混沌卷軸(scroll.getItemId())) {//混沌捲軸
final int z = ItemConstants.卷軸.getChaosNumber(scroll.getItemId());
int increase = Randomizer.nextBoolean() ? 1 : (ItemConstants.類型.樂觀混沌卷軸(scroll.getItemId())) || (isNegativeScroll(scroll.getItemId())) ? 1 : -1;
if (nEquip.getStr() > 0) {
nEquip.setStr((short) (nEquip.getStr() + Randomizer.nextInt(z) * (Randomizer.nextBoolean() ? 1 : increase)));
}
if (nEquip.getDex() > 0) {
nEquip.setDex((short) (nEquip.getDex() + Randomizer.nextInt(z) * (Randomizer.nextBoolean() ? 1 : increase)));
}
if (nEquip.getInt() > 0) {
nEquip.setInt((short) (nEquip.getInt() + Randomizer.nextInt(z) * (Randomizer.nextBoolean() ? 1 : increase)));
}
if (nEquip.getLuk() > 0) {
nEquip.setLuk((short) (nEquip.getLuk() + Randomizer.nextInt(z) * (Randomizer.nextBoolean() ? 1 : increase)));
}
if (nEquip.getWatk() > 0) {
nEquip.setWatk((short) (nEquip.getWatk() + Randomizer.nextInt(z) * (Randomizer.nextBoolean() ? 1 : increase)));
}
if (nEquip.getWdef() > 0) {
nEquip.setWdef((short) (nEquip.getWdef() + Randomizer.nextInt(z) * (Randomizer.nextBoolean() ? 1 : increase)));
}
if (nEquip.getMatk() > 0) {
nEquip.setMatk((short) (nEquip.getMatk() + Randomizer.nextInt(z) * (Randomizer.nextBoolean() ? 1 : increase)));
}
if (nEquip.getMdef() > 0) {
nEquip.setMdef((short) (nEquip.getMdef() + Randomizer.nextInt(z) * (Randomizer.nextBoolean() ? 1 : increase)));
}
if (nEquip.getAcc() > 0) {
nEquip.setAcc((short) (nEquip.getAcc() + Randomizer.nextInt(z) * (Randomizer.nextBoolean() ? 1 : increase)));
}
if (nEquip.getAvoid() > 0) {
nEquip.setAvoid((short) (nEquip.getAvoid() + Randomizer.nextInt(z) * (Randomizer.nextBoolean() ? 1 : increase)));
}
if (nEquip.getSpeed() > 0) {
nEquip.setSpeed((short) (nEquip.getSpeed() + Randomizer.nextInt(z) * (Randomizer.nextBoolean() ? 1 : increase)));
}
if (nEquip.getJump() > 0) {
nEquip.setJump((short) (nEquip.getJump() + Randomizer.nextInt(z) * (Randomizer.nextBoolean() ? 1 : increase)));
}
if (nEquip.getHp() > 0) {
nEquip.setHp((short) (nEquip.getHp() + Randomizer.nextInt(z) * (Randomizer.nextBoolean() ? 1 : increase)));
}
if (nEquip.getMp() > 0) {
nEquip.setMp((short) (nEquip.getMp() + Randomizer.nextInt(z) * (Randomizer.nextBoolean() ? 1 : increase)));
}
} else {
for (Entry<String, Integer> stat : stats.entrySet()) {
final String key = stat.getKey();
switch (key) {
case "STR":
nEquip.setStr((short) (nEquip.getStr() + stat.getValue()));
break;
case "DEX":
nEquip.setDex((short) (nEquip.getDex() + stat.getValue()));
break;
case "INT":
nEquip.setInt((short) (nEquip.getInt() + stat.getValue()));
break;
case "LUK":
nEquip.setLuk((short) (nEquip.getLuk() + stat.getValue()));
break;
case "PAD":
nEquip.setWatk((short) (nEquip.getWatk() + stat.getValue()));
break;
case "PDD":
nEquip.setWdef((short) (nEquip.getWdef() + stat.getValue()));
break;
case "MAD":
nEquip.setMatk((short) (nEquip.getMatk() + stat.getValue()));
break;
case "MDD":
nEquip.setMdef((short) (nEquip.getMdef() + stat.getValue()));
break;
case "ACC":
nEquip.setAcc((short) (nEquip.getAcc() + stat.getValue()));
break;
case "EVA":
nEquip.setAvoid((short) (nEquip.getAvoid() + stat.getValue()));
break;
case "Speed":
nEquip.setSpeed((short) (nEquip.getSpeed() + stat.getValue()));
break;
case "Jump":
nEquip.setJump((short) (nEquip.getJump() + stat.getValue()));
break;
case "MHP":
nEquip.setHp((short) (nEquip.getHp() + stat.getValue()));
break;
case "MMP":
nEquip.setMp((short) (nEquip.getMp() + stat.getValue()));
break;
}
}
}
if (!ItemConstants.類型.白醫卷軸(scroll.getItemId()) && !ItemConstants.類型.特殊卷軸(scroll.getItemId()) && !ItemConstants.類型.裝備強化卷軸(scroll.getItemId()) && !ItemConstants.類型.潛能卷軸(scroll.getItemId()) && !ItemConstants.類型.附加潛能卷軸(scroll.getItemId()) && 2040727 != scroll.getItemId() && 2041058 != scroll.getItemId()) {
if (ItemConstants.類型.阿斯旺卷軸(scroll.getItemId())) {
nEquip.setUpgradeSlots((byte) (nEquip.getUpgradeSlots() - eqstats.get("tuc")));
} else {
nEquip.setUpgradeSlots((byte) (nEquip.getUpgradeSlots() - 1));
}
nEquip.setLevel((byte) (nEquip.getLevel() + 1));
short oldFlag = nEquip.getFlag();
if (ItemFlag.SLOTS_PROTECT.check(oldFlag)) {
nEquip.setFlag((short) (oldFlag - ItemFlag.SLOTS_PROTECT.getValue()));
}
}
} else {
if (!ws && !ItemConstants.類型.白醫卷軸(scroll.getItemId()) && 2040727 != scroll.getItemId() && 2041058 != scroll.getItemId()) {
short oldFlag = nEquip.getFlag();
if (ItemFlag.SLOTS_PROTECT.check(oldFlag)) {
nEquip.setFlag((short) (oldFlag - ItemFlag.SLOTS_PROTECT.getValue()));
chr.showMessage(11, "由卷軸的效果來,不會扣掉可以升級的次數。");
} else if (ItemConstants.類型.阿斯旺卷軸(scroll.getItemId())) {
nEquip.setUpgradeSlots((byte) (nEquip.getUpgradeSlots() - eqstats.get("tuc")));
} else {
nEquip.setUpgradeSlots((byte) (nEquip.getUpgradeSlots() - 1));
}
}
if (Randomizer.nextInt(99) < curse) {
return null;
}
}
}
return equip;
}
public final Item getEquipById(final int equipId) {
return getEquipById(equipId, -1);
}
public final Item getEquipById(final int equipId, final int ringId) {
final ItemInformation i = getItemInformation(equipId);
if (i == null) {
return new Equip(equipId, (short) 0, ringId, (byte) 0);
}
final Item eq = i.eq.copy();
eq.setUniqueId(ringId);
return eq;
}
protected final short getRandStatFusion(final short defaultValue, final int value1, final int value2) {
if (defaultValue == 0) {
return 0;
}
final int range = ((value1 + value2) / 2) - defaultValue;
final int rand = Randomizer.nextInt(Math.abs(range) + 1);
return (short) (defaultValue + (range < 0 ? -rand : rand));
}
protected final short getRandStat(final short defaultValue, final int maxRange) {
if (defaultValue == 0) {
return 0;
}
// vary no more than ceil of 10% of stat
final int lMaxRange = (int) Math.min(Math.ceil(defaultValue * 0.1), maxRange);
return (short) ((defaultValue - lMaxRange) + Randomizer.nextInt(lMaxRange * 2 + 1));
}
protected final short getRandStatAbove(final short defaultValue, final int maxRange) {
if (defaultValue <= 0) {
return 0;
}
final int lMaxRange = (int) Math.min(Math.ceil(defaultValue * 0.1), maxRange);
return (short) ((defaultValue) + Randomizer.nextInt(lMaxRange + 1));
}
public final Equip randomizeStats(final Equip equip) {
equip.setStr(getRandStat(equip.getStr(), 5));
equip.setDex(getRandStat(equip.getDex(), 5));
equip.setInt(getRandStat(equip.getInt(), 5));
equip.setLuk(getRandStat(equip.getLuk(), 5));
equip.setMatk(getRandStat(equip.getMatk(), 5));
equip.setWatk(getRandStat(equip.getWatk(), 5));
equip.setAcc(getRandStat(equip.getAcc(), 5));
equip.setAvoid(getRandStat(equip.getAvoid(), 5));
equip.setJump(getRandStat(equip.getJump(), 5));
equip.setHands(getRandStat(equip.getHands(), 5));
equip.setSpeed(getRandStat(equip.getSpeed(), 5));
equip.setWdef(getRandStat(equip.getWdef(), 10));
equip.setMdef(getRandStat(equip.getMdef(), 10));
equip.setHp(getRandStat(equip.getHp(), 10));
equip.setMp(getRandStat(equip.getMp(), 10));
return equip;
}
public final Equip randomizeStats_Above(final Equip equip) {
equip.setStr(getRandStatAbove(equip.getStr(), 5));
equip.setDex(getRandStatAbove(equip.getDex(), 5));
equip.setInt(getRandStatAbove(equip.getInt(), 5));
equip.setLuk(getRandStatAbove(equip.getLuk(), 5));
equip.setMatk(getRandStatAbove(equip.getMatk(), 5));
equip.setWatk(getRandStatAbove(equip.getWatk(), 5));
equip.setAcc(getRandStatAbove(equip.getAcc(), 5));
equip.setAvoid(getRandStatAbove(equip.getAvoid(), 5));
equip.setJump(getRandStatAbove(equip.getJump(), 5));
equip.setHands(getRandStatAbove(equip.getHands(), 5));
equip.setSpeed(getRandStatAbove(equip.getSpeed(), 5));
equip.setWdef(getRandStatAbove(equip.getWdef(), 10));
equip.setMdef(getRandStatAbove(equip.getMdef(), 10));
equip.setHp(getRandStatAbove(equip.getHp(), 10));
equip.setMp(getRandStatAbove(equip.getMp(), 10));
return equip;
}
public final Equip fuse(final Equip equip1, final Equip equip2) {
if (equip1.getItemId() != equip2.getItemId()) {
return equip1;
}
final Equip equip = (Equip) getEquipById(equip1.getItemId());
equip.setStr(getRandStatFusion(equip.getStr(), equip1.getStr(), equip2.getStr()));
equip.setDex(getRandStatFusion(equip.getDex(), equip1.getDex(), equip2.getDex()));
equip.setInt(getRandStatFusion(equip.getInt(), equip1.getInt(), equip2.getInt()));
equip.setLuk(getRandStatFusion(equip.getLuk(), equip1.getLuk(), equip2.getLuk()));
equip.setMatk(getRandStatFusion(equip.getMatk(), equip1.getMatk(), equip2.getMatk()));
equip.setWatk(getRandStatFusion(equip.getWatk(), equip1.getWatk(), equip2.getWatk()));
equip.setAcc(getRandStatFusion(equip.getAcc(), equip1.getAcc(), equip2.getAcc()));
equip.setAvoid(getRandStatFusion(equip.getAvoid(), equip1.getAvoid(), equip2.getAvoid()));
equip.setJump(getRandStatFusion(equip.getJump(), equip1.getJump(), equip2.getJump()));
equip.setHands(getRandStatFusion(equip.getHands(), equip1.getHands(), equip2.getHands()));
equip.setSpeed(getRandStatFusion(equip.getSpeed(), equip1.getSpeed(), equip2.getSpeed()));
equip.setWdef(getRandStatFusion(equip.getWdef(), equip1.getWdef(), equip2.getWdef()));
equip.setMdef(getRandStatFusion(equip.getMdef(), equip1.getMdef(), equip2.getMdef()));
equip.setHp(getRandStatFusion(equip.getHp(), equip1.getHp(), equip2.getHp()));
equip.setMp(getRandStatFusion(equip.getMp(), equip1.getMp(), equip2.getMp()));
return equip;
}
public final int getTotalStat(final Equip equip) { //i get COOL when my defense is higher on gms...
return equip.getStr() + equip.getDex() + equip.getInt() + equip.getLuk() + equip.getMatk() + equip.getWatk() + equip.getAcc() + equip.getAvoid() + equip.getJump()
+ equip.getHands() + equip.getSpeed() + equip.getHp() + equip.getMp() + equip.getWdef() + equip.getMdef();
}
public final MapleStatEffect getItemEffect(final int itemId) {
MapleStatEffect ret = itemEffects.get(Integer.valueOf(itemId));
if (ret == null) {
final MapleData item = getItemData(itemId);
if (item == null || item.getChildByPath("spec") == null) {
return null;
}
ret = MapleStatEffect.loadItemEffectFromData(item.getChildByPath("spec"), itemId);
itemEffects.put(itemId, ret);
}
return ret;
}
public final MapleStatEffect getItemEffectEX(final int itemId) {
MapleStatEffect ret = itemEffectsEx.get(Integer.valueOf(itemId));
if (ret == null) {
final MapleData item = getItemData(itemId);
if (item == null || item.getChildByPath("specEx") == null) {
return null;
}
ret = MapleStatEffect.loadItemEffectFromData(item.getChildByPath("specEx"), itemId);
itemEffectsEx.put(itemId, ret);
}
return ret;
}
public final int getCreateId(final int id) {
final ItemInformation i = getItemInformation(id);
if (i == null) {
return 0;
}
return i.create;
}
public final int getCardMobId(final int id) {
final ItemInformation i = getItemInformation(id);
if (i == null) {
return 0;
}
return i.monsterBook;
}
public final int getBagType(final int id) {
final ItemInformation i = getItemInformation(id);
if (i == null) {
return 0;
}
return i.flag & 0xF;
}
public int[][] getSummonMobs(int itemId) {
MapleData data = getItemData(itemId);
int theInt = data.getChildByPath("mob").getChildren().size();
int[][] mobs2spawn = new int[theInt][2];
for (int x = 0; x < theInt; x++) {
mobs2spawn[x][0] = MapleDataTool.getIntConvert("mob/" + x + "/id", data);
mobs2spawn[x][1] = MapleDataTool.getIntConvert("mob/" + x + "/prob", data);
}
return mobs2spawn;
}
public final int getWatkForProjectile(final int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null || i.equipStats == null || i.equipStats.get("incPAD") == null) {
return 0;
}
return i.equipStats.get("incPAD");
}
public final boolean canScroll(final int scrollid, final int itemid) {
return (scrollid / 100) % 100 == (itemid / 10000) % 100 || itemid / 1000 == 1672;//心臟
}
public final String getName(final int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return null;
}
return i.name;
}
public final String getDesc(final int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return null;
}
return i.desc;
}
public final String getMsg(final int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return null;
}
return i.msg;
}
public final short getItemMakeLevel(final int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return 0;
}
return i.itemMakeLevel;
}
public final boolean isDropRestricted(final int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return false;
}
return ((i.flag & 0x200) != 0 || (i.flag & 0x400) != 0 || GameConstants.isDropRestricted(itemId)) && (itemId == 3012000 || itemId == 3012015 || itemId / 10000 != 301) && itemId != 2041200 && itemId != 5640000 && itemId != 4170023 && itemId != 2040124 && itemId != 2040125 && itemId != 2040126 && itemId != 2040211 && itemId != 2040212 && itemId != 2040227 && itemId != 2040228 && itemId != 2040229 && itemId != 2040230 && itemId != 1002926 && itemId != 1002906 && itemId != 1002927;
}
public final boolean isPickupRestricted(final int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return false;
}
return ((i.flag & 0x80) != 0 || GameConstants.isPickupRestricted(itemId)) && itemId != 4001168 && itemId != 4031306 && itemId != 4031307;
}
public final boolean isAccountShared(final int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return false;
}
return (i.flag & 0x100) != 0;
}
public final int getStateChangeItem(final int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return 0;
}
return i.stateChange;
}
public final int getMeso(final int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return 0;
}
return i.meso;
}
public final boolean isShareTagEnabled(final int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return false;
}
return (i.flag & 0x800) != 0;
}
public final boolean isKarmaEnabled(final int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return false;
}
return i.karmaEnabled == 1;
}
public final boolean isPKarmaEnabled(final int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return false;
}
return i.karmaEnabled == 2;
}
public final boolean isPickupBlocked(final int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return false;
}
return (i.flag & 0x40) != 0;
}
public final boolean isLogoutExpire(final int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return false;
}
return (i.flag & 0x20) != 0;
}
public final boolean cantSell(final int itemId) { //true = cant sell, false = can sell
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return false;
}
return (i.flag & 0x10) != 0;
}
public final Pair<Integer, List<StructRewardItem>> getRewardItem(final int itemid) {
final ItemInformation i = getItemInformation(itemid);
if (i == null) {
return null;
}
return new Pair<>(i.totalprob, i.rewardItems);
}
public final boolean isMobHP(final int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return false;
}
return (i.flag & 0x1000) != 0;
}
public final boolean isQuestItem(final int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return false;
}
return (i.flag & 0x200) != 0 && itemId / 10000 != 301;
}
public final Pair<Integer, List<Integer>> questItemInfo(final int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return null;
}
return new Pair<>(i.questId, i.questItems);
}
public final Pair<Integer, String> replaceItemInfo(final int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return null;
}
return new Pair<>(i.replaceItem, i.replaceMsg);
}
public final List<Triple<String, Point, Point>> getAfterImage(final String after) {
return afterImage.get(after);
}
public final String getAfterImage(final int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return null;
}
return i.afterImage;
}
public final boolean itemExists(final int itemId) {
if (GameConstants.getInventoryType(itemId) == MapleInventoryType.UNDEFINED) {
return false;
}
return getItemInformation(itemId) != null;
}
public final boolean isCash(final int itemId) {
if (getEquipStats(itemId) == null) {
return GameConstants.getInventoryType(itemId) == MapleInventoryType.CASH;
}
return GameConstants.getInventoryType(itemId) == MapleInventoryType.CASH || getEquipStats(itemId).get("cash") != null;
}
public final ItemInformation getItemInformation(final int itemId) {
if (itemId <= 0) {
return null;
}
return dataCache.get(itemId);
}
private ItemInformation tmpInfo = null;
public void initItemRewardData(ResultSet sqlRewardData) throws SQLException {
final int itemID = sqlRewardData.getInt("itemid");
if (tmpInfo == null || tmpInfo.itemId != itemID) {
if (!dataCache.containsKey(itemID)) {
System.out.println("[initItemRewardData] Tried to load an item while this is not in the cache: " + itemID);
return;
}
tmpInfo = dataCache.get(itemID);
}
if (tmpInfo.rewardItems == null) {
tmpInfo.rewardItems = new ArrayList<>();
}
StructRewardItem add = new StructRewardItem();
add.itemid = sqlRewardData.getInt("item");
add.period = (add.itemid == 1122017 ? Math.max(sqlRewardData.getInt("period"), 7200) : sqlRewardData.getInt("period"));
add.prob = sqlRewardData.getInt("prob");
add.quantity = sqlRewardData.getShort("quantity");
add.worldmsg = sqlRewardData.getString("worldMsg").length() <= 0 ? null : sqlRewardData.getString("worldMsg");
add.effect = sqlRewardData.getString("effect");
tmpInfo.rewardItems.add(add);
}
public void initItemAddData(ResultSet sqlAddData) throws SQLException {
final int itemID = sqlAddData.getInt("itemid");
if (tmpInfo == null || tmpInfo.itemId != itemID) {
if (!dataCache.containsKey(itemID)) {
System.out.println("[initItemAddData] Tried to load an item while this is not in the cache: " + itemID);
return;
}
tmpInfo = dataCache.get(itemID);
}
if (tmpInfo.equipAdditions == null) {
tmpInfo.equipAdditions = new LinkedList<>();
}
while (sqlAddData.next()) {
tmpInfo.equipAdditions.add(new Triple<>(sqlAddData.getString("key"), sqlAddData.getString("subKey"), sqlAddData.getString("value")));
}
}
public void initItemEquipData(ResultSet sqlEquipData) throws SQLException {
final int itemID = sqlEquipData.getInt("itemid");
if (tmpInfo == null || tmpInfo.itemId != itemID) {
if (!dataCache.containsKey(itemID)) {
System.out.println("[initItemEquipData] Tried to load an item while this is not in the cache: " + itemID);
return;
}
tmpInfo = dataCache.get(itemID);
}
if (tmpInfo.equipStats == null) {
tmpInfo.equipStats = new HashMap<>();
}
final int itemLevel = sqlEquipData.getInt("itemLevel");
if (itemLevel == -1) {
tmpInfo.equipStats.put(sqlEquipData.getString("key"), sqlEquipData.getInt("value"));
} else {
if (tmpInfo.equipIncs == null) {
tmpInfo.equipIncs = new HashMap<>();
}
Map<String, Integer> toAdd = tmpInfo.equipIncs.get(itemLevel);
if (toAdd == null) {
toAdd = new HashMap<>();
tmpInfo.equipIncs.put(itemLevel, toAdd);
}
toAdd.put(sqlEquipData.getString("key"), sqlEquipData.getInt("value"));
}
}
public void finalizeEquipData(ItemInformation item) {
int itemId = item.itemId;
// Some equips do not have equip data. So we initialize it anyway if not initialized
// already
// Credits: Jay :)
if (item.equipStats == null) {
item.equipStats = new HashMap<>();
}
item.eq = new Equip(itemId, (byte) 0, -1, (byte) 0);
short stats = GameConstants.getStat(itemId, 0);
if (stats > 0) {
item.eq.setStr(stats);
item.eq.setDex(stats);
item.eq.setInt(stats);
item.eq.setLuk(stats);
}
stats = GameConstants.getATK(itemId, 0);
if (stats > 0) {
item.eq.setWatk(stats);
item.eq.setMatk(stats);
}
stats = GameConstants.getHpMp(itemId, 0);
if (stats > 0) {
item.eq.setHp(stats);
item.eq.setMp(stats);
}
stats = GameConstants.getDEF(itemId, 0);
if (stats > 0) {
item.eq.setWdef(stats);
item.eq.setMdef(stats);
}
//讀取裝備屬性(新增屬性在這裡)
if (item.equipStats.size() > 0) {
for (Entry<String, Integer> stat : item.equipStats.entrySet()) {
final String key = stat.getKey();
switch (key) {
case "STR":
item.eq.setStr(GameConstants.getStat(itemId, stat.getValue()));
break;
case "DEX":
item.eq.setDex(GameConstants.getStat(itemId, stat.getValue()));
break;
case "INT":
item.eq.setInt(GameConstants.getStat(itemId, stat.getValue()));
break;
case "LUK":
item.eq.setLuk(GameConstants.getStat(itemId, stat.getValue()));
break;
case "PAD":
item.eq.setWatk(GameConstants.getATK(itemId, stat.getValue()));
break;
case "PDD":
item.eq.setWdef(GameConstants.getDEF(itemId, stat.getValue()));
break;
case "MAD":
item.eq.setMatk(GameConstants.getATK(itemId, stat.getValue()));
break;
case "MDD":
item.eq.setMdef(GameConstants.getDEF(itemId, stat.getValue()));
break;
case "ACC":
item.eq.setAcc((short) (int) stat.getValue());
break;
case "EVA":
item.eq.setAvoid((short) (int) stat.getValue());
break;
case "Speed":
item.eq.setSpeed((short) (int) stat.getValue());
break;
case "Jump":
item.eq.setJump((short) (int) stat.getValue());
break;
case "MHP":
item.eq.setHp(GameConstants.getHpMp(itemId, stat.getValue()));
break;
case "MMP":
item.eq.setMp(GameConstants.getHpMp(itemId, stat.getValue()));
break;
case "tuc":
item.eq.setUpgradeSlots(stat.getValue().byteValue());
break;
case "Craft":
item.eq.setHands(stat.getValue().shortValue());
break;
case "durability":
item.eq.setDurability(stat.getValue());
break;
case "charmEXP":
item.eq.setCharmEXP(stat.getValue().shortValue());
break;
case "PVPDamage":
item.eq.setPVPDamage(stat.getValue().shortValue());
break;
case "bdR":
item.eq.setBossDamage(stat.getValue().byteValue());
break;
case "imdR":
item.eq.setIgnorePDR(stat.getValue().byteValue());
break;
}
}
if (item.equipStats.get("cash") != null && item.eq.getCharmEXP() <= 0) { //set the exp
short exp = 0;
int identifier = itemId / 10000;
if (ItemConstants.類型.武器(itemId) || identifier == 106) { //weapon overall
exp = 60;
} else if (identifier == 100) { //hats
exp = 50;
} else if (ItemConstants.類型.飾品(itemId) || identifier == 102 || identifier == 108 || identifier == 107) { //gloves shoes accessory
exp = 40;
} else if (identifier == 104 || identifier == 105 || identifier == 110) { //top bottom cape
exp = 30;
}
item.eq.setCharmEXP(exp);
}
}
}
public void initItemInformation(ResultSet sqlItemData) throws SQLException {
final ItemInformation ret = new ItemInformation();
final int itemId = sqlItemData.getInt("itemid");
ret.itemId = itemId;
ret.slotMax = GameConstants.getSlotMax(itemId) > 0 ? GameConstants.getSlotMax(itemId) : sqlItemData.getShort("slotMax");
ret.price = Double.parseDouble(sqlItemData.getString("price"));
ret.wholePrice = sqlItemData.getInt("wholePrice");
ret.stateChange = sqlItemData.getInt("stateChange");
ret.name = sqlItemData.getString("name");
ret.desc = sqlItemData.getString("desc");
ret.msg = sqlItemData.getString("msg");
ret.flag = sqlItemData.getInt("flags");
ret.karmaEnabled = sqlItemData.getByte("karma");
ret.meso = sqlItemData.getInt("meso");
ret.monsterBook = sqlItemData.getInt("monsterBook");
ret.itemMakeLevel = sqlItemData.getShort("itemMakeLevel");
ret.questId = sqlItemData.getInt("questId");
ret.create = sqlItemData.getInt("create");
ret.replaceItem = sqlItemData.getInt("replaceId");
ret.replaceMsg = sqlItemData.getString("replaceMsg");
ret.afterImage = sqlItemData.getString("afterImage");
ret.cardSet = 0;
if (ret.monsterBook > 0 && itemId / 10000 == 238) {
mobIds.put(ret.monsterBook, itemId);
for (Entry<Integer, Triple<Integer, List<Integer>, List<Integer>>> set : monsterBookSets.entrySet()) {
if (set.getValue().mid.contains(itemId)) {
ret.cardSet = set.getKey();
break;
}
}
}
final String scrollRq = sqlItemData.getString("scrollReqs");
if (scrollRq.length() > 0) {
ret.scrollReqs = new ArrayList<>();
final String[] scroll = scrollRq.split(",");
for (String s : scroll) {
if (s.length() > 1) {
ret.scrollReqs.add(Integer.parseInt(s));
}
}
}
final String consumeItem = sqlItemData.getString("consumeItem");
if (consumeItem.length() > 0) {
ret.questItems = new ArrayList<>();
final String[] scroll = scrollRq.split(",");
for (String s : scroll) {
if (s.length() > 1) {
ret.questItems.add(Integer.parseInt(s));
}
}
}
ret.totalprob = sqlItemData.getInt("totalprob");
final String incRq = sqlItemData.getString("incSkill");
if (incRq.length() > 0) {
ret.incSkill = new ArrayList<>();
final String[] scroll = incRq.split(",");
for (String s : scroll) {
if (s.length() > 1) {
ret.incSkill.add(Integer.parseInt(s));
}
}
}
dataCache.put(itemId, ret);
}
public boolean isEquip(int itemId) {
return itemId / 1000000 == 1;
}
public final FarmItemInformation getFarmItemInformation(final int itemId) {
if (itemId <= 0) {
return null;
}
return farmDataCache.get(itemId);
}
public void initFarmItemInformation(ResultSet sqlItemData) throws SQLException {
final FarmItemInformation ret = new FarmItemInformation();
final int itemId = sqlItemData.getInt("itemid");
ret.itemId = itemId;
ret.slotMax = GameConstants.getSlotMax(itemId) > 0 ? GameConstants.getSlotMax(itemId) : sqlItemData.getShort("slotMax");
ret.price = Double.parseDouble(sqlItemData.getString("price"));
ret.wholePrice = sqlItemData.getInt("wholePrice");
ret.stateChange = sqlItemData.getInt("stateChange");
ret.name = sqlItemData.getString("name");
ret.desc = sqlItemData.getString("desc");
ret.msg = sqlItemData.getString("msg");
ret.flag = sqlItemData.getInt("flags");
ret.karmaEnabled = sqlItemData.getByte("karma");
ret.meso = sqlItemData.getInt("meso");
ret.monsterBook = sqlItemData.getInt("monsterBook");
ret.itemMakeLevel = sqlItemData.getShort("itemMakeLevel");
ret.questId = sqlItemData.getInt("questId");
ret.create = sqlItemData.getInt("create");
ret.replaceItem = sqlItemData.getInt("replaceId");
ret.replaceMsg = sqlItemData.getString("replaceMsg");
ret.afterImage = sqlItemData.getString("afterImage");
ret.cardSet = 0;
if (ret.monsterBook > 0 && itemId / 10000 == 238) {
mobIds.put(ret.monsterBook, itemId);
for (Entry<Integer, Triple<Integer, List<Integer>, List<Integer>>> set : monsterBookSets.entrySet()) {
if (set.getValue().mid.contains(itemId)) {
ret.cardSet = set.getKey();
break;
}
}
}
final String scrollRq = sqlItemData.getString("scrollReqs");
if (scrollRq.length() > 0) {
ret.scrollReqs = new ArrayList<>();
final String[] scroll = scrollRq.split(",");
for (String s : scroll) {
if (s.length() > 1) {
ret.scrollReqs.add(Integer.parseInt(s));
}
}
}
final String consumeItem = sqlItemData.getString("consumeItem");
if (consumeItem.length() > 0) {
ret.questItems = new ArrayList<>();
final String[] scroll = scrollRq.split(",");
for (String s : scroll) {
if (s.length() > 1) {
ret.questItems.add(Integer.parseInt(s));
}
}
}
ret.totalprob = sqlItemData.getInt("totalprob");
final String incRq = sqlItemData.getString("incSkill");
if (incRq.length() > 0) {
ret.incSkill = new ArrayList<>();
final String[] scroll = incRq.split(",");
for (String s : scroll) {
if (s.length() > 1) {
ret.incSkill.add(Integer.parseInt(s));
}
}
}
farmDataCache.put(itemId, ret);
}
public static MapleInventoryType getInventoryType(final int itemId) {
final byte type = (byte) (itemId / 1000000);
if (type < 1 || type > 5) {
return MapleInventoryType.UNDEFINED;
}
return MapleInventoryType.getByType(type);
}
public short getPetFlagInfo(int itemId) {
if (this.petFlagInfo.containsKey(itemId)) {
return (this.petFlagInfo.get(itemId));
}
short flag = 0;
if (itemId / 10000 != 500) {
return flag;
}
MapleData item = getItemData(itemId);
if (item == null) {
return flag;
}
if (MapleDataTool.getIntConvert("info/pickupItem", item, 0) > 0) {
flag = (short) (flag | 0x1);
}
if (MapleDataTool.getIntConvert("info/longRange", item, 0) > 0) {
flag = (short) (flag | 0x2);
}
if (MapleDataTool.getIntConvert("info/pickupAll", item, 0) > 0) {
flag = (short) (flag | 0x4);
}
if (MapleDataTool.getIntConvert("info/sweepForDrop", item, 0) > 0) {
flag = (short) (flag | 0x10);
}
if (MapleDataTool.getIntConvert("info/consumeHP", item, 0) > 0) {
flag = (short) (flag | 0x20);
}
if (MapleDataTool.getIntConvert("info/consumeMP", item, 0) > 0) {
flag = (short) (flag | 0x40);
}
if (MapleDataTool.getIntConvert("info/autoBuff", item, 0) > 0) {
flag = (short) (flag | 0x200);
}
this.petFlagInfo.put(itemId, flag);
return flag;
}
public int getItemIncMHPr(int itemId) {
if ((getEquipStats(itemId) == null) || (!getEquipStats(itemId).containsKey("MHPr"))) {
return 0;
}
return (getEquipStats(itemId).get("MHPr"));
}
public int getItemIncMMPr(int itemId) {
if ((getEquipStats(itemId) == null) || (!getEquipStats(itemId).containsKey("MMPr"))) {
return 0;
}
return (getEquipStats(itemId).get("MMPr"));
}
public boolean isSuperiorEquip(int itemId) {
Map<String, Integer> equipStats = getEquipStats(itemId);
if (equipStats == null) {
return false;
}
return equipStats.containsKey("superiorEqp") && equipStats.get("superiorEqp") == 1;
}
public boolean isNoCursedScroll(int itemId) {
if (this.noCursedScroll.containsKey(itemId)) {
return (this.noCursedScroll.get(itemId));
}
if (itemId / 10000 != 204) {
return false;
}
boolean noCursed = MapleDataTool.getIntConvert("info/noCursed", getItemData(itemId), 0) > 0;
this.noCursedScroll.put(itemId, noCursed);
return noCursed;
}
public boolean isNegativeScroll(int itemId) {
if (this.noNegativeScroll.containsKey(itemId)) {
return (this.noNegativeScroll.get(itemId));
}
if (itemId / 10000 != 204) {
return false;
}
boolean noNegative = MapleDataTool.getIntConvert("info/noNegative", getItemData(itemId), 0) > 0;
this.noNegativeScroll.put(itemId, noNegative);
return noNegative;
}
public int getForceUpgrade(int itemId) {
if (this.forceUpgrade.containsKey(itemId)) {
return (this.forceUpgrade.get(itemId));
}
int upgrade = 0;
if (itemId / 100 != 20493) {
return upgrade;
}
upgrade = MapleDataTool.getIntConvert("info/forceUpgrade", getItemData(itemId), 1);
this.forceUpgrade.put(itemId, upgrade);
return upgrade;
}
public Equip resetEquipStats(Equip oldEquip) {
Equip newEquip = (Equip) getEquipById(oldEquip.getItemId());
oldEquip.reset(newEquip);
return newEquip;
}
public final boolean isOnlyTradeBlock(final int itemId) {
final MapleData data = getItemData(itemId);
boolean tradeblock = false;
if (MapleDataTool.getIntConvert("info/tradeBlock", data, 0) == 1) {
tradeblock = true;
}
return tradeblock;
}
public final double getExpCardRate(final int itemId) {
return MapleDataTool.getIntConvert("info/rate", getItemData(itemId), 100) / 100.0;
}
public final int getExpCardMaxLevel(final int itemId) {
return MapleDataTool.getIntConvert("info/maxLevel", getItemData(itemId), 249);
}
public boolean isExpOrDropCardTime(int itemId) {
Calendar cal = Calendar.getInstance();
String day = MapleDayInt.getDayInt(cal.get(7));
Map times;
if (expCardTimes.containsKey(itemId)) {
times = (Map) expCardTimes.get(itemId);
} else {
List<MapleData> data = getItemData(itemId).getChildByPath("info").getChildByPath("time").getChildren();
Map hours = new HashMap();
for (MapleData childdata : data) {
String[] time = MapleDataTool.getString(childdata).split(":");
hours.put(time[0], time[1]);
}
times = hours;
expCardTimes.put(itemId, hours);
cal.get(7);
}
if (times.containsKey(day)) {
String[] hourspan = ((String) times.get(day)).split("-");
int starthour = Integer.parseInt(hourspan[0]);
int endhour = Integer.parseInt(hourspan[1]);
if ((cal.get(11) >= starthour) && (cal.get(11) <= endhour)) {
return true;
}
}
return false;
}
public static class MapleDayInt {
public static String getDayInt(int day) {
if (day == 1) {
return "SUN";
}
if (day == 2) {
return "MON";
}
if (day == 3) {
return "TUE";
}
if (day == 4) {
return "WED";
}
if (day == 5) {
return "THU";
}
if (day == 6) {
return "FRI";
}
if (day == 7) {
return "SAT";
}
return null;
}
}
public Pair<Integer, Integer> getSocketReqLevel(int itemId) {
int socketId = itemId % 1000 + 1;
if (!socketReqLevel.containsKey(socketId)) {
MapleData skillOptionData = itemData.getData("SkillOption.img");
MapleData socketData = skillOptionData.getChildByPath("socket");
int reqLevelMax = MapleDataTool.getIntConvert(socketId + "/reqLevelMax", socketData, 250);
int reqLevelMin = MapleDataTool.getIntConvert(socketId + "/reqLevelMin", socketData, 70);
socketReqLevel.put(socketId, new Pair(reqLevelMax, reqLevelMin));
}
return socketReqLevel.get(socketId);
}
public int getSoulSkill(int itemId) {
int soulName = itemId % 1000 + 1;
if (!soulSkill.containsKey(soulName)) {
MapleData skillOptionData = itemData.getData("SkillOption.img");
MapleData skillData = skillOptionData.getChildByPath("skill");
int skillId = MapleDataTool.getIntConvert(soulName + "/skillId", skillData, 0);
soulSkill.put(soulName, skillId);
}
return soulSkill.get(soulName);
}
public ArrayList<Integer> getTempOption(int itemId) {
int soulName = itemId % 1000 + 1;
if (!tempOption.containsKey(soulName)) {
MapleData skillOptionData = itemData.getData("SkillOption.img");
MapleData tempOptionData = skillOptionData.getChildByPath("skill/" + soulName + "/tempOption");
ArrayList<Integer> pots = new ArrayList();
for (MapleData pot : tempOptionData) {
pots.add(MapleDataTool.getIntConvert("id", pot, 1));
}
tempOption.put(soulName, pots);
}
return tempOption.get(soulName);
}
public int getAndroidType(int itemId) {
if (androidType.containsKey(itemId)) {
return (androidType.get(itemId));
}
int type = 0;
if (itemId / 10000 != 166) {
return type;
}
type = MapleDataTool.getIntConvert("info/android", getItemData(itemId), 1);
androidType.put(itemId, type);
return type;
}
}