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 database.DatabaseConnection;
import java.awt.Point;
import java.io.File;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
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 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.Triple;
public class MapleItemInformationProvider {
private final static MapleItemInformationProvider instance = new MapleItemInformationProvider();
protected final MapleDataProvider chrData = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Character.wz"));
protected final MapleDataProvider etcData = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Etc.wz"));
protected final MapleDataProvider itemData = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Item.wz"));
protected final MapleDataProvider stringData = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/String.wz"));
protected final Map<Integer, ItemInformation> dataCache = new HashMap<>();
protected final Map<Integer, FarmItemInformation> farmDataCache = new HashMap<>();
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 HashMap<>();
protected final Map<Integer, MapleStatEffect> itemEffectsEx = new HashMap<>();
protected final Map<Integer, Integer> mobIds = new HashMap<>();
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 final Map<Integer, Triple<List<Integer>, List<Integer>, List<Integer>>> androids = new HashMap<>();
protected final Map<Integer, Triple<Integer, List<Integer>, List<Integer>>> monsterBookSets = new HashMap<>();
protected final Map<Integer, StructSetItem> setItems = new HashMap<>();
public void runEtc() {
if (!setItems.isEmpty() || !potentialCache.isEmpty() || !socketCache.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(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());
final List<Integer> face = new ArrayList<>(), hair = new ArrayList<>(), skin = new ArrayList<>();
for (MapleData ds : iz.getChildByPath("costume/face")) {
face.add(MapleDataTool.getInt(ds, 2000));
}
for (MapleData ds : iz.getChildByPath("costume/hair")) {
hair.add(MapleDataTool.getInt(ds, 30000));
}
for (MapleData ds : iz.getChildByPath("costume/skin")) {
skin.add(MapleDataTool.getInt(ds, 20000));
}
androids.put(Integer.parseInt(d.getName().substring(0, 4)), new Triple<>(skin, hair, face));
}
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() {
if (GameConstants.GMS) { //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 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 Triple<List<Integer>, List<Integer>, List<Integer>> getAndroidInfo(int i) {
return androids.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;
}
protected 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; } }
}
*/
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 Integer.valueOf(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((int) 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().intValue(), sta.get("STRMax").intValue())));
break;
case "DEXMin":
nEquip.setDex((short) (nEquip.getDex() + rand(stat.getValue().intValue(), sta.get("DEXMax").intValue())));
break;
case "INTMin":
nEquip.setInt((short) (nEquip.getInt() + rand(stat.getValue().intValue(), sta.get("INTMax").intValue())));
break;
case "LUKMin":
nEquip.setLuk((short) (nEquip.getLuk() + rand(stat.getValue().intValue(), sta.get("LUKMax").intValue())));
break;
case "PADMin":
nEquip.setWatk((short) (nEquip.getWatk() + rand(stat.getValue().intValue(), sta.get("PADMax").intValue())));
break;
case "PDDMin":
nEquip.setWdef((short) (nEquip.getWdef() + rand(stat.getValue().intValue(), sta.get("PDDMax").intValue())));
break;
case "MADMin":
nEquip.setMatk((short) (nEquip.getMatk() + rand(stat.getValue().intValue(), sta.get("MADMax").intValue())));
break;
case "MDDMin":
nEquip.setMdef((short) (nEquip.getMdef() + rand(stat.getValue().intValue(), sta.get("MDDMax").intValue())));
break;
case "ACCMin":
nEquip.setAcc((short) (nEquip.getAcc() + rand(stat.getValue().intValue(), sta.get("ACCMax").intValue())));
break;
case "EVAMin":
nEquip.setAvoid((short) (nEquip.getAvoid() + rand(stat.getValue().intValue(), sta.get("EVAMax").intValue())));
break;
case "SpeedMin":
nEquip.setSpeed((short) (nEquip.getSpeed() + rand(stat.getValue().intValue(), sta.get("SpeedMax").intValue())));
break;
case "JumpMin":
nEquip.setJump((short) (nEquip.getJump() + rand(stat.getValue().intValue(), sta.get("JumpMax").intValue())));
break;
case "MHPMin":
nEquip.setHp((short) (nEquip.getHp() + rand(stat.getValue().intValue(), sta.get("MHPMax").intValue())));
break;
case "MMPMin":
nEquip.setMp((short) (nEquip.getMp() + rand(stat.getValue().intValue(), sta.get("MMPMax").intValue())));
break;
case "MaxHPMin":
nEquip.setHp((short) (nEquip.getHp() + rand(stat.getValue().intValue(), sta.get("MaxHPMax").intValue())));
break;
case "MaxMPMin":
nEquip.setMp((short) (nEquip.getMp() + rand(stat.getValue().intValue(), sta.get("MaxMPMax").intValue())));
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(setItemId);
}
public final List<Integer> getScrollReqs(final int itemId) {
final ItemInformation i = getItemInformation(itemId);
if (i == null) {
return null;
}
return i.scrollReqs;
}
public final Item scrollEquipWithId(final Item equip, final Item scrollId, 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(scrollId.getItemId());
final Map<String, Integer> eqstats = getEquipStats(equip.getItemId());
final int succ = (GameConstants.isTablet(scrollId.getItemId()) ? GameConstants.getSuccessTablet(scrollId.getItemId(), nEquip.getLevel()) : ((GameConstants.isEquipScroll(scrollId.getItemId()) || GameConstants.isPotentialScroll(scrollId.getItemId()) || !stats.containsKey("success") ? 0 : stats.get("success"))));
final int curse = (GameConstants.isTablet(scrollId.getItemId()) ? GameConstants.getCurseTablet(scrollId.getItemId(), nEquip.getLevel()) : ((GameConstants.isEquipScroll(scrollId.getItemId()) || GameConstants.isPotentialScroll(scrollId.getItemId()) || !stats.containsKey("cursed") ? 0 : stats.get("cursed"))));
final int added = (ItemFlag.LUCKY_DAY.check(equip.getFlag()) ? 10 : 0) + (chr.getTrait(MapleTraitType.craft).getLevel() / 10);
int success = succ + (vegas == 5610000 && succ == 10 ? 20 : (vegas == 5610001 && succ == 60 ? 30 : 0)) + added;
if (ItemFlag.LUCKY_DAY.check(equip.getFlag()) && !GameConstants.isPotentialScroll(scrollId.getItemId()) && !GameConstants.isEquipScroll(scrollId.getItemId()) && !GameConstants.isSpecialScroll(scrollId.getItemId())) {
equip.setFlag((short) (equip.getFlag() - ItemFlag.LUCKY_DAY.getValue()));
}
if (GameConstants.isPotentialScroll(scrollId.getItemId()) || GameConstants.isEquipScroll(scrollId.getItemId()) || GameConstants.isSpecialScroll(scrollId.getItemId()) || Randomizer.nextInt(100) <= success) {
switch (scrollId.getItemId()) {
case 2049000:
case 2049001:
case 2049002:
case 2049003:
case 2049004:
case 2049005: {
if (eqstats.containsKey("tuc") && nEquip.getLevel() + nEquip.getUpgradeSlots() < eqstats.get("tuc")) {
nEquip.setUpgradeSlots((byte) (nEquip.getUpgradeSlots() + 1));
}
break;
}
case 2049006:
case 2049007:
case 2049008: {
if (eqstats.containsKey("tuc") && nEquip.getLevel() + nEquip.getUpgradeSlots() < eqstats.get("tuc")) {
nEquip.setUpgradeSlots((byte) (nEquip.getUpgradeSlots() + 2));
}
break;
}
case 2040727: { // Spikes on shoe, prevents slip
short flag = nEquip.getFlag();
flag |= ItemFlag.SPIKES.getValue();
nEquip.setFlag(flag);
break;
}
case 2041058: { // Cape for Cold protection
short flag = nEquip.getFlag();
flag |= ItemFlag.COLD.getValue();
nEquip.setFlag(flag);
break;
}
case 5063000:
case 2530000:
case 2530001: {
short flag = nEquip.getFlag();
flag |= ItemFlag.LUCKY_DAY.getValue();
nEquip.setFlag(flag);
break;
}
case 5064000:
case 2531000: {
short flag = nEquip.getFlag();
flag |= ItemFlag.SHIELD_WARD.getValue();
nEquip.setFlag(flag);
break;
}
default: {
if(GameConstants.icsog(scrollId.getItemId())) {//Incredible chaos scroll of goodnes
final int z = GameConstants.getChaosNumber(scrollId.getItemId());
if (nEquip.getStr() > 0) {
nEquip.setStr((short) (nEquip.getStr() + Randomizer.nextInt(z)) );
}
if (nEquip.getDex() > 0) {
nEquip.setDex((short) (nEquip.getDex() + Randomizer.nextInt(z) ));
}
if (nEquip.getInt() > 0) {
nEquip.setInt((short) (nEquip.getInt() + Randomizer.nextInt(z)));
}
if (nEquip.getLuk() > 0) {
nEquip.setLuk((short) (nEquip.getLuk() + Randomizer.nextInt(z)));
}
if (nEquip.getWatk() > 0) {
nEquip.setWatk((short) (nEquip.getWatk() + Randomizer.nextInt(z) ));
}
if (nEquip.getWdef() > 0) {
nEquip.setWdef((short) (nEquip.getWdef() + Randomizer.nextInt(z)));
}
if (nEquip.getMatk() > 0) {
nEquip.setMatk((short) (nEquip.getMatk() + Randomizer.nextInt(z)));
}
if (nEquip.getMdef() > 0) {
nEquip.setMdef((short) (nEquip.getMdef() + Randomizer.nextInt(z)));
}
if (nEquip.getAcc() > 0) {
nEquip.setAcc((short) (nEquip.getAcc() + Randomizer.nextInt(z)));
}
if (nEquip.getAvoid() > 0) {
nEquip.setAvoid((short) (nEquip.getAvoid() + Randomizer.nextInt(z)));
}
if (nEquip.getSpeed() > 0) {
nEquip.setSpeed((short) (nEquip.getSpeed() + Randomizer.nextInt(z)));
}
if (nEquip.getJump() > 0) {
nEquip.setJump((short) (nEquip.getJump() + Randomizer.nextInt(z)));
}
if (nEquip.getHp() > 0) {
nEquip.setHp((short) (nEquip.getHp() + Randomizer.nextInt(z)));
}
if (nEquip.getMp() > 0) {
nEquip.setMp((short) (nEquip.getMp() + Randomizer.nextInt(z)));
}
} else if (GameConstants.isChaosScroll(scrollId.getItemId())) {
final int z = GameConstants.getChaosNumber(scrollId.getItemId());
if (nEquip.getStr() > 0) {
nEquip.setStr((short) (nEquip.getStr() + Randomizer.nextInt(z) * (Randomizer.nextBoolean() ? 1 : -1)));
}
if (nEquip.getDex() > 0) {
nEquip.setDex((short) (nEquip.getDex() + Randomizer.nextInt(z) * (Randomizer.nextBoolean() ? 1 : -1)));
}
if (nEquip.getInt() > 0) {
nEquip.setInt((short) (nEquip.getInt() + Randomizer.nextInt(z) * (Randomizer.nextBoolean() ? 1 : -1)));
}
if (nEquip.getLuk() > 0) {
nEquip.setLuk((short) (nEquip.getLuk() + Randomizer.nextInt(z) * (Randomizer.nextBoolean() ? 1 : -1)));
}
if (nEquip.getWatk() > 0) {
nEquip.setWatk((short) (nEquip.getWatk() + Randomizer.nextInt(z) * (Randomizer.nextBoolean() ? 1 : -1)));
}
if (nEquip.getWdef() > 0) {
nEquip.setWdef((short) (nEquip.getWdef() + Randomizer.nextInt(z) * (Randomizer.nextBoolean() ? 1 : -1)));
}
if (nEquip.getMatk() > 0) {
nEquip.setMatk((short) (nEquip.getMatk() + Randomizer.nextInt(z) * (Randomizer.nextBoolean() ? 1 : -1)));
}
if (nEquip.getMdef() > 0) {
nEquip.setMdef((short) (nEquip.getMdef() + Randomizer.nextInt(z) * (Randomizer.nextBoolean() ? 1 : -1)));
}
if (nEquip.getAcc() > 0) {
nEquip.setAcc((short) (nEquip.getAcc() + Randomizer.nextInt(z) * (Randomizer.nextBoolean() ? 1 : -1)));
}
if (nEquip.getAvoid() > 0) {
nEquip.setAvoid((short) (nEquip.getAvoid() + Randomizer.nextInt(z) * (Randomizer.nextBoolean() ? 1 : -1)));
}
if (nEquip.getSpeed() > 0) {
nEquip.setSpeed((short) (nEquip.getSpeed() + Randomizer.nextInt(z) * (Randomizer.nextBoolean() ? 1 : -1)));
}
if (nEquip.getJump() > 0) {
nEquip.setJump((short) (nEquip.getJump() + Randomizer.nextInt(z) * (Randomizer.nextBoolean() ? 1 : -1)));
}
if (nEquip.getHp() > 0) {
nEquip.setHp((short) (nEquip.getHp() + Randomizer.nextInt(z) * (Randomizer.nextBoolean() ? 1 : -1)));
}
if (nEquip.getMp() > 0) {
nEquip.setMp((short) (nEquip.getMp() + Randomizer.nextInt(z) * (Randomizer.nextBoolean() ? 1 : -1)));
}
break;
} else if (GameConstants.isEquipScroll(scrollId.getItemId())) {
final int chanc = Math.max((scrollId.getItemId() == 2049300 || scrollId.getItemId() == 2049303 || scrollId.getItemId() == 2049306 ? 100 : (scrollId.getItemId() == 2049308 ? 50 : scrollId.getItemId() == 2049305 ? 60 : 80)) - (nEquip.getEnhance() * 10), 10) + added;
if (Randomizer.nextInt(100) > chanc) {
return null; //destroyed, nib
}
for (int i = 0; i < (scrollId.getItemId() == 2049308 ? 5 : (scrollId.getItemId() == 2049305 ? 4 : (scrollId.getItemId() == 2049304 ? 3 : scrollId.getItemId() == 2049309 ? 2 : 1))); i++) {
if (nEquip.getStr() > 0 || Randomizer.nextInt(50) == 1) { //1/50
nEquip.setStr((short) (nEquip.getStr() + Randomizer.nextInt(5)));
}
if (nEquip.getStr() > 0 && (GameConstants.isTyrant(nEquip.getItemId()) || Randomizer.nextInt(1) == 1)) {
nEquip.setStr((short) (nEquip.getStr() + 22));
}
if (nEquip.getStr() > 0 && (GameConstants.isNovaGear(nEquip.getItemId()) || Randomizer.nextInt(1) == 1)) {
nEquip.setStr((short) (nEquip.getStr() + 12));
}
if (nEquip.getDex() > 0 || Randomizer.nextInt(50) == 1) { //1/50
nEquip.setDex((short) (nEquip.getDex() + Randomizer.nextInt(5)));
}
if (nEquip.getDex() > 0 && (GameConstants.isTyrant(nEquip.getItemId()) || Randomizer.nextInt(1) == 1)) {
nEquip.setDex((short) (nEquip.getDex() + 22));
}
if (nEquip.getDex() > 0 && (GameConstants.isNovaGear(nEquip.getItemId()) || Randomizer.nextInt(1) == 1)) {
nEquip.setDex((short) (nEquip.getDex() + 12));
}
if (nEquip.getInt() > 0 || Randomizer.nextInt(50) == 1) { //1/50
nEquip.setInt((short) (nEquip.getInt() + Randomizer.nextInt(5)));
}
if (nEquip.getInt() > 0 && (GameConstants.isTyrant(nEquip.getItemId()) || Randomizer.nextInt(1) == 1)) {
nEquip.setInt((short) (nEquip.getInt() + 22));
}
if (nEquip.getInt() > 0 && (GameConstants.isTyrant(nEquip.getItemId()) || Randomizer.nextInt(1) == 1)) {
nEquip.setInt((short) (nEquip.getInt() + 12));
}
if (nEquip.getLuk() > 0 || Randomizer.nextInt(50) == 1) { //1/50
nEquip.setLuk((short) (nEquip.getLuk() + Randomizer.nextInt(5)));
}
if (nEquip.getLuk() > 0 && (GameConstants.isTyrant(nEquip.getItemId()) || Randomizer.nextInt(1) == 1)) {
nEquip.setLuk((short) (nEquip.getLuk() + 22));
}
if (nEquip.getLuk() > 0 && (GameConstants.isNovaGear(nEquip.getItemId()) || Randomizer.nextInt(1) == 1)) {
nEquip.setLuk((short) (nEquip.getLuk() + 12));
}
if (nEquip.getWatk() > 0 && GameConstants.isWeapon(nEquip.getItemId())) {
nEquip.setWatk((short) (nEquip.getWatk() + (nEquip.getWatk() / 50 + 1)));
}
if (nEquip.getWatk() > 0 && !GameConstants.isWeapon(nEquip.getItemId()) && Randomizer.nextInt(5) == 1 || Randomizer.nextInt(5) == 1 && !GameConstants.isWeapon(nEquip.getItemId())) {
nEquip.setWatk((short) (nEquip.getWatk() + Randomizer.nextInt(5)));
}
if (nEquip.getWatk() > 0 && GameConstants.isTyrant(nEquip.getItemId()) && nEquip.getEnhance() > 3) {
nEquip.setWatk((short) (nEquip.getWatk() + 5));
}
if (nEquip.getWatk() > 0 && GameConstants.isNovaGear(nEquip.getItemId()) && nEquip.getEnhance() > 5) {
nEquip.setWatk((short) (nEquip.getWatk() + 2));
}
if (nEquip.getWdef() > 0 || Randomizer.nextInt(40) == 1) { //1/40
nEquip.setWdef((short) (nEquip.getWdef() + Randomizer.nextInt(5)));
}
if (nEquip.getMatk() > 0 && GameConstants.isWeapon(nEquip.getItemId())) {
nEquip.setMatk((short) (nEquip.getMatk() + (nEquip.getMatk() / 50 + 1)));
}
if (nEquip.getMatk() > 0 && GameConstants.isTyrant(nEquip.getItemId()) && nEquip.getEnhance() > 3) {
nEquip.setMatk((short) (nEquip.getMatk() + 5));
}
if (nEquip.getMatk() > 0 && GameConstants.isNovaGear(nEquip.getItemId()) && nEquip.getEnhance() > 5) {
nEquip.setMatk((short) (nEquip.getMatk() + 2));
}
if (nEquip.getMdef() > 0 || Randomizer.nextInt(40) == 1) { //1/40
nEquip.setMdef((short) (nEquip.getMdef() + Randomizer.nextInt(5)));
}
if (nEquip.getAcc() > 0 || Randomizer.nextInt(20) == 1) { //1/20
nEquip.setAcc((short) (nEquip.getAcc() + Randomizer.nextInt(5)));
}
if (nEquip.getAvoid() > 0 || Randomizer.nextInt(20) == 1) { //1/20
nEquip.setAvoid((short) (nEquip.getAvoid() + Randomizer.nextInt(5)));
}
if (nEquip.getSpeed() > 0 || Randomizer.nextInt(10) == 1) { //1/10
nEquip.setSpeed((short) (nEquip.getSpeed() + Randomizer.nextInt(5)));
}
if (nEquip.getJump() > 0 || Randomizer.nextInt(10) == 1) { //1/10
nEquip.setJump((short) (nEquip.getJump() + Randomizer.nextInt(5)));
}
if (nEquip.getHp() > 0 || Randomizer.nextInt(5) == 1) { //1/5
nEquip.setHp((short) (nEquip.getHp() + Randomizer.nextInt(5)));
}
if (nEquip.getMp() > 0 || Randomizer.nextInt(5) == 1) { //1/5
nEquip.setMp((short) (nEquip.getMp() + Randomizer.nextInt(5)));
}
nEquip.setEnhance((byte) (nEquip.getEnhance() + 1));
}
break;
} else if (GameConstants.isPotentialScroll(scrollId.getItemId())) {
if (nEquip.getState() <= 17 && (scrollId.getItemId() / 100 == 20497)) {
final int chanc = (scrollId.getItemId() == 2049701 ? 80 : 100) + added; // 2049701
if (Randomizer.nextInt(100) > chanc) {
return null; //destroyed, nib
}
nEquip.renewPotential(2, 0, (short) 0, false);
} else if (nEquip.getState() == 0) {
final int chanc = (scrollId.getItemId() == 5534000 || scrollId.getItemId() == 2049402 || scrollId.getItemId() == 2049406 ? 100 : scrollId.getItemId() == 2049701 ? 80 : (scrollId.getItemId() == 2049400 || scrollId.getItemId() == 2049407 || scrollId.getItemId() == 2049413 ? 90 : 70)) + added;
if (Randomizer.nextInt(100) > chanc) {
return null; //destroyed, nib
}
nEquip.resetPotential();
}
break;
} else {
for (Entry<String, Integer> stat : stats.entrySet()) {
final String key = stat.getKey();
switch (key) {
case "STR":
nEquip.setStr((short) (nEquip.getStr() + stat.getValue().intValue()));
break;
case "DEX":
nEquip.setDex((short) (nEquip.getDex() + stat.getValue().intValue()));
break;
case "INT":
nEquip.setInt((short) (nEquip.getInt() + stat.getValue().intValue()));
break;
case "LUK":
nEquip.setLuk((short) (nEquip.getLuk() + stat.getValue().intValue()));
break;
case "PAD":
nEquip.setWatk((short) (nEquip.getWatk() + stat.getValue().intValue()));
break;
case "PDD":
nEquip.setWdef((short) (nEquip.getWdef() + stat.getValue().intValue()));
break;
case "MAD":
nEquip.setMatk((short) (nEquip.getMatk() + stat.getValue().intValue()));
break;
case "MDD":
nEquip.setMdef((short) (nEquip.getMdef() + stat.getValue().intValue()));
break;
case "ACC":
nEquip.setAcc((short) (nEquip.getAcc() + stat.getValue().intValue()));
break;
case "EVA":
nEquip.setAvoid((short) (nEquip.getAvoid() + stat.getValue().intValue()));
break;
case "Speed":
nEquip.setSpeed((short) (nEquip.getSpeed() + stat.getValue().intValue()));
break;
case "Jump":
nEquip.setJump((short) (nEquip.getJump() + stat.getValue().intValue()));
break;
case "MHP":
nEquip.setHp((short) (nEquip.getHp() + stat.getValue().intValue()));
break;
case "MMP":
nEquip.setMp((short) (nEquip.getMp() + stat.getValue().intValue()));
break;
}
}
break;
}
}
}
if (!GameConstants.isCleanSlate(scrollId.getItemId()) && !GameConstants.isSpecialScroll(scrollId.getItemId()) && !GameConstants.isEquipScroll(scrollId.getItemId()) && !GameConstants.isPotentialScroll(scrollId.getItemId())) {
if (GameConstants.isAzwanScroll(scrollId.getItemId())) {
nEquip.setUpgradeSlots((byte) (nEquip.getUpgradeSlots() - stats.get("tuc")));
} else {
nEquip.setUpgradeSlots((byte) (nEquip.getUpgradeSlots() - 1));
}
nEquip.setLevel((byte) (nEquip.getLevel() + 1));
}
} else {
if (!ws && !GameConstants.isCleanSlate(scrollId.getItemId()) && !GameConstants.isSpecialScroll(scrollId.getItemId()) && !GameConstants.isEquipScroll(scrollId.getItemId()) && !GameConstants.isPotentialScroll(scrollId.getItemId())) {
if (GameConstants.isAzwanScroll(scrollId.getItemId())) {
nEquip.setUpgradeSlots((byte) (nEquip.getUpgradeSlots() - stats.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(Integer.valueOf(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(Integer.valueOf(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;
}
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().intValue()));
break;
case "DEX":
item.eq.setDex(GameConstants.getStat(itemId, stat.getValue().intValue()));
break;
case "INT":
item.eq.setInt(GameConstants.getStat(itemId, stat.getValue().intValue()));
break;
case "LUK":
item.eq.setLuk(GameConstants.getStat(itemId, stat.getValue().intValue()));
break;
case "PAD":
item.eq.setWatk(GameConstants.getATK(itemId, stat.getValue().intValue()));
break;
case "PDD":
item.eq.setWdef(GameConstants.getDEF(itemId, stat.getValue().intValue()));
break;
case "MAD":
item.eq.setMatk(GameConstants.getATK(itemId, stat.getValue().intValue()));
break;
case "MDD":
item.eq.setMdef(GameConstants.getDEF(itemId, stat.getValue().intValue()));
break;
case "ACC":
item.eq.setAcc((short) stat.getValue().intValue());
break;
case "EVA":
item.eq.setAvoid((short) stat.getValue().intValue());
break;
case "Speed":
item.eq.setSpeed((short) stat.getValue().intValue());
break;
case "Jump":
item.eq.setJump((short) stat.getValue().intValue());
break;
case "MHP":
item.eq.setHp(GameConstants.getHpMp(itemId, stat.getValue().intValue()));
break;
case "MMP":
item.eq.setMp(GameConstants.getHpMp(itemId, stat.getValue().intValue()));
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().intValue());
break;
case "charmEXP":
item.eq.setCharmEXP(stat.getValue().shortValue());
break;
case "PVPDamage":
item.eq.setPVPDamage(stat.getValue().shortValue());
break;
}
}
if (item.equipStats.get("cash") != null && item.eq.getCharmEXP() <= 0) { //set the exp
short exp = 0;
int identifier = itemId / 10000;
if (GameConstants.isWeapon(itemId) || identifier == 106) { //weapon overall
exp = 60;
} else if (identifier == 100) { //hats
exp = 50;
} else if (GameConstants.isAccessory(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 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;
}
}