Maker-oriented commit
Implemented the multiple features of the Maker skill (equip disassembly, leftover merging into monster crystal and item crafting). Updated the DB with the Maker data featured on the WZ. Added a new table for the strenghtening reagents gain data (compiled with the MapleSkillMakerReagentIndexer). Fixed quests that improves the Maker skill level and some other Maker-related quests.
This commit is contained in:
@@ -1665,17 +1665,27 @@ public class Commands {
|
||||
break;
|
||||
|
||||
case "givenx":
|
||||
if (sub.length < 3){
|
||||
player.yellowMessage("Syntax: !givenx <playername> <gainnx>");
|
||||
if (sub.length < 2){
|
||||
player.yellowMessage("Syntax: !givenx [<playername>] <gainnx>");
|
||||
break;
|
||||
}
|
||||
|
||||
String recv;
|
||||
int value;
|
||||
if(sub.length > 2) {
|
||||
recv = sub[1];
|
||||
value = Integer.parseInt(sub[2]);
|
||||
} else {
|
||||
recv = c.getPlayer().getName();
|
||||
value = Integer.parseInt(sub[1]);
|
||||
}
|
||||
|
||||
victim = cserv.getPlayerStorage().getCharacterByName(sub[1]);
|
||||
victim = cserv.getPlayerStorage().getCharacterByName(recv);
|
||||
if(victim != null) {
|
||||
victim.getCashShop().gainCash(1, Integer.parseInt(sub[2]));
|
||||
victim.getCashShop().gainCash(1, value);
|
||||
player.message("NX given.");
|
||||
} else {
|
||||
player.message("Player '" + sub[1] + "' could not be found on this channel.");
|
||||
player.message("Player '" + recv + "' could not be found on this channel.");
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1695,17 +1705,27 @@ public class Commands {
|
||||
break;
|
||||
|
||||
case "givems":
|
||||
if (sub.length < 3){
|
||||
player.yellowMessage("Syntax: !givems <playername> <gainms>");
|
||||
if (sub.length < 2){
|
||||
player.yellowMessage("Syntax: !givems [<playername>] <gainmeso>");
|
||||
break;
|
||||
}
|
||||
|
||||
victim = cserv.getPlayerStorage().getCharacterByName(sub[1]);
|
||||
String recv_;
|
||||
int value_;
|
||||
if(sub.length > 2) {
|
||||
recv_ = sub[1];
|
||||
value_ = Integer.parseInt(sub[2]);
|
||||
} else {
|
||||
recv_ = c.getPlayer().getName();
|
||||
value_ = Integer.parseInt(sub[1]);
|
||||
}
|
||||
|
||||
victim = cserv.getPlayerStorage().getCharacterByName(recv_);
|
||||
if(victim != null) {
|
||||
victim.gainMeso(Integer.parseInt(sub[2]), true);
|
||||
victim.gainMeso(value_, true);
|
||||
player.message("MESO given.");
|
||||
} else {
|
||||
player.message("Player '" + sub[1] + "' could not be found on this channel.");
|
||||
player.message("Player '" + recv_ + "' could not be found on this channel.");
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
94
src/constants/EquipType.java
Normal file
94
src/constants/EquipType.java
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* This file is part of the MapleSolaxiaV2 Maple Story Server
|
||||
*
|
||||
* Copyright (C) 2017 RonanLana
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package constants;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author RonanLana
|
||||
*/
|
||||
public enum EquipType {
|
||||
UNDEFINED(-1),
|
||||
ACCESSORY(0),
|
||||
CAP(100),
|
||||
CAPE(110),
|
||||
COAT(104),
|
||||
FACE(2),
|
||||
GLOVES(108),
|
||||
HAIR(3),
|
||||
LONGCOAT(105),
|
||||
PANTS(106),
|
||||
PET_EQUIP(180),
|
||||
PET_EQUIP_FIELD(181),
|
||||
PET_EQUIP_LABEL(182),
|
||||
PET_EQUIP_QUOTE(183),
|
||||
RING(111),
|
||||
SHIELD(109),
|
||||
SHOES(107),
|
||||
TAMING(190),
|
||||
TAMING_SADDLE(191),
|
||||
SWORD(1302),
|
||||
AXE(1312),
|
||||
MACE(1322),
|
||||
DAGGER(1332),
|
||||
WAND(1372),
|
||||
STAFF(1382),
|
||||
SWORD_2H(1402),
|
||||
AXE_2H(1412),
|
||||
MACE_2H(1422),
|
||||
SPEAR(1432),
|
||||
POLEARM(1442),
|
||||
BOW(1452),
|
||||
CROSSBOW(1462),
|
||||
CLAW(1472),
|
||||
KNUCKLER(1482),
|
||||
PISTOL(1492);
|
||||
|
||||
private final int i;
|
||||
private static final Map<Integer, EquipType> map = new HashMap(34);
|
||||
|
||||
private EquipType(int val) {
|
||||
this.i = val;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return i;
|
||||
}
|
||||
|
||||
static {
|
||||
for (EquipType eqEnum : EquipType.values()) {
|
||||
map.put(eqEnum.i, eqEnum);
|
||||
}
|
||||
}
|
||||
|
||||
public static EquipType getEquipTypeById(int itemid) {
|
||||
EquipType ret;
|
||||
int val = itemid / 100000;
|
||||
|
||||
if(val == 13 || val == 14) {
|
||||
ret = map.get(itemid / 1000);
|
||||
} else {
|
||||
ret = map.get(itemid / 10000);
|
||||
}
|
||||
|
||||
return (ret != null) ? ret : EquipType.UNDEFINED;
|
||||
}
|
||||
}
|
||||
@@ -89,6 +89,10 @@ public final class ItemConstants {
|
||||
return itemId / 1000 == 5000;
|
||||
}
|
||||
|
||||
public static boolean isAccessory(int itemId) {
|
||||
return itemId >= 1110000 && itemId < 1140000;
|
||||
}
|
||||
|
||||
public static boolean isTownScroll(int itemId) {
|
||||
return itemId >= 2030000 && itemId < 2030021;
|
||||
}
|
||||
@@ -135,4 +139,16 @@ public final class ItemConstants {
|
||||
}
|
||||
return MapleInventoryType.getByType(type);
|
||||
}
|
||||
|
||||
public static boolean isMakerReagent(int itemId) {
|
||||
return itemId / 10000 == 425;
|
||||
}
|
||||
|
||||
public static boolean isOverall(int itemId) {
|
||||
return itemId / 10000 == 105;
|
||||
}
|
||||
|
||||
public static boolean isWeapon(int itemId) {
|
||||
return itemId >= 1302000 && itemId < 1492024;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +65,7 @@ public class ServerConstants {
|
||||
public static final boolean USE_ERASE_UNTRADEABLE_DROP = true; //Forces flagged untradeable items to disappear when dropped.
|
||||
public static final boolean USE_ERASE_PET_ON_EXPIRATION = false;//Forces pets to be removed from inventory when expire time comes, rather than converting it to a doll.
|
||||
public static final boolean USE_BUFF_MOST_SIGNIFICANT = true; //When applying buffs, the player will stick with the highest stat boost among the listed, rather than overwriting stats.
|
||||
public static final boolean USE_MAKER_FEE_HEURISTICS = true; //Apply compiled values for stimulants and reagents into the Maker fee calculations (max error revolves around 50k mesos). Set false to use basic constant values instead (results are never higher than requested by the client-side).
|
||||
|
||||
//Server Rates And Experience
|
||||
public static final int EXP_RATE = 10;
|
||||
@@ -86,7 +87,7 @@ public class ServerConstants {
|
||||
public static final long BLOCK_NPC_RACE_CONDT = (long)(0.5 * 1000); //Time the player client must wait before reopening a conversation with an NPC.
|
||||
public static final long PET_LOOT_UPON_ATTACK = (long)(0.7 * 1000); //Time the pet must wait before trying to pick items up.
|
||||
|
||||
//Dangling Items Configuration
|
||||
//Dangling Items/Locks Configuration
|
||||
public static final int ITEM_EXPIRE_TIME = 3 * 60 * 1000; //Time before items start disappearing. Recommended to be set up to 3 minutes.
|
||||
public static final int ITEM_MONITOR_TIME = 5 * 60 * 1000; //Interval between item monitoring tasks on maps, which checks for dangling (null) item objects on the map item history.
|
||||
public static final int LOCK_MONITOR_TIME = 30 * 1000; //Waiting time for a lock to be released. If it reach timed out, a critical server deadlock has made present.
|
||||
@@ -98,7 +99,7 @@ public class ServerConstants {
|
||||
public static final boolean USE_PERFECT_GM_SCROLL = true; //Scrolls from GMs never uses up slots nor fails.
|
||||
public static final boolean USE_PERFECT_SCROLLING = true; //Scrolls doesn't use slots upon failure.
|
||||
public static final boolean USE_ENHANCED_CHSCROLL = true; //Equips even more powerful with chaos upgrade.
|
||||
public static final boolean USE_ENHANCED_CRAFTING = true; //Applys chaos scroll on every equip crafted.
|
||||
public static final boolean USE_ENHANCED_CRAFTING = true; //Apply chaos scroll on every equip crafted.
|
||||
public static final int SCROLL_CHANCE_RATE = 0; //Number of rolls for success on a scroll, set 0 for default.
|
||||
public static final int CHSCROLL_STAT_RANGE = 6; //Stat upgrade range (-N, N) on chaos scrolls.
|
||||
|
||||
@@ -118,10 +119,12 @@ public class ServerConstants {
|
||||
public static final boolean USE_EQUIPMNT_LVLUP_SLOTS = true;//Equips can upgrade slots at level up.
|
||||
public static final boolean USE_EQUIPMNT_LVLUP_POWER = true;//Enable more powerful stat upgrades at equip level up.
|
||||
public static final boolean USE_SPIKES_AVOID_BANISH = true; //Shoes equipped with spikes prevents mobs from banishing wearer.
|
||||
public static final boolean USE_CHAIR_EXTRAHEAL = true; //Enable map chairs to further recover player's HP and MP (player must have the Chair Mastery skill).
|
||||
public static final int MAX_EQUIPMNT_LVLUP_STAT_UP = 10000; //Max stat upgrade an equipment can have on a levelup.
|
||||
public static final int MAX_EQUIPMNT_STAT = 32767; //Max stat on an equipment by leveling up.
|
||||
public static final int USE_EQUIPMNT_LVLUP = 7; //All equips lvlup at max level of N, set 1 to disable.
|
||||
|
||||
//Map-Chair Configuration
|
||||
public static final boolean USE_CHAIR_EXTRAHEAL = true; //Enable map chairs to further recover player's HP and MP (player must have the Chair Mastery skill).
|
||||
public static final byte CHAIR_EXTRA_HEAL_HP = 70; //Each chair extra heal proc increasing HP.
|
||||
public static final byte CHAIR_EXTRA_HEAL_MP = 42; //Each chair extra heal proc increasing MP.
|
||||
|
||||
|
||||
@@ -21,12 +21,27 @@
|
||||
*/
|
||||
package net.server.channel.handlers;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import constants.ItemConstants;
|
||||
import client.MapleClient;
|
||||
import client.inventory.Equip;
|
||||
import client.inventory.Item;
|
||||
import client.inventory.MapleInventoryType;
|
||||
import constants.EquipType;
|
||||
import constants.ServerConstants;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import server.MapleInventoryManipulator;
|
||||
import server.MapleItemInformationProvider;
|
||||
import server.MakerItemFactory;
|
||||
import server.MakerItemFactory.MakerItemCreateEntry;
|
||||
import tools.FilePrinter;
|
||||
import tools.Pair;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
@@ -36,50 +51,317 @@ import tools.data.input.SeekableLittleEndianAccessor;
|
||||
* @author Jay Estrella, Ronan
|
||||
*/
|
||||
public final class MakerSkillHandler extends AbstractMaplePacketHandler {
|
||||
private MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
|
||||
|
||||
private static MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
|
||||
|
||||
@Override
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
slea.readInt();
|
||||
int type = slea.readInt();
|
||||
int toCreate = slea.readInt();
|
||||
int toDisassemble = -1, pos = -1;
|
||||
boolean makerSucceeded = true;
|
||||
|
||||
MakerItemCreateEntry recipe;
|
||||
Map<Integer, Short> reagentids = new LinkedHashMap<>();
|
||||
int stimulantid = -1;
|
||||
|
||||
if(type == 3) { // building monster crystal
|
||||
int fromLeftover = toCreate;
|
||||
toCreate = ii.getMakerCrystalFromLeftover(toCreate);
|
||||
if(toCreate == -1) {
|
||||
c.announce(MaplePacketCreator.serverNotice(1, ii.getName(toCreate) + " is unavailable for Monster Crystal conversion."));
|
||||
return;
|
||||
}
|
||||
|
||||
recipe = MakerItemFactory.generateLeftoverCrystalEntry(fromLeftover);
|
||||
} else if(type == 4) { // disassembling
|
||||
slea.readInt(); // 1... probably inventory type
|
||||
pos = slea.readInt();
|
||||
|
||||
Item it = c.getPlayer().getInventory(MapleInventoryType.EQUIP).getItem((short) pos);
|
||||
if(it != null && it.getItemId() == toCreate) {
|
||||
Pair<Integer, Integer> p;
|
||||
|
||||
if((p = generateDisassemblyInfo(toCreate)) != null) {
|
||||
recipe = MakerItemFactory.generateDisassemblyCrystalEntry(p.getLeft(), p.getRight());
|
||||
toDisassemble = toCreate;
|
||||
toCreate = ii.getMakerCrystalFromEquip(toCreate);
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.serverNotice(1, ii.getName(toCreate) + " is unavailable for Monster Crystal disassembly."));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.serverNotice(1, "An unknown error occurred when trying to apply that item for disassembly."));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if(toCreate < 2000000) { // only equips uses stimulant and reagents
|
||||
if(slea.readByte() != 0) { // stimulant
|
||||
stimulantid = getMakerStimulant(toCreate);
|
||||
if(!c.getAbstractPlayerInteraction().haveItem(stimulantid)) {
|
||||
stimulantid = -1;
|
||||
}
|
||||
}
|
||||
|
||||
int reagents = Math.min(slea.readInt(), getMakerReagentSlots(toCreate));
|
||||
for(int i = 0; i < reagents; i++) { // crystals
|
||||
int reagentid = slea.readInt();
|
||||
if(ItemConstants.isMakerReagent(reagentid)) {
|
||||
Short r = reagentids.get(reagentid);
|
||||
if(r == null) {
|
||||
reagentids.put(reagentid, (short) 1);
|
||||
} else {
|
||||
reagentids.put(reagentid, (short) (r + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<Pair<Integer, Short>> toUpdate = new LinkedList<>();
|
||||
for(Entry<Integer, Short> r : reagentids.entrySet()) {
|
||||
int qty = c.getAbstractPlayerInteraction().getItemQuantity(r.getKey());
|
||||
|
||||
if(qty < r.getValue()) {
|
||||
toUpdate.add(new Pair<>(r.getKey(), (short) qty));
|
||||
}
|
||||
}
|
||||
|
||||
// remove those not present on player inventory
|
||||
if(!toUpdate.isEmpty()) {
|
||||
for(Pair<Integer, Short> r : toUpdate) {
|
||||
if(r.getRight() > 0) {
|
||||
reagentids.put(r.getLeft(), r.getRight());
|
||||
} else {
|
||||
reagentids.remove(r.getLeft());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!reagentids.isEmpty()) removeOddMakerReagents(toCreate, reagentids);
|
||||
}
|
||||
|
||||
recipe = MakerItemFactory.getItemCreateEntry(toCreate, stimulantid, reagentids);
|
||||
}
|
||||
|
||||
MakerItemCreateEntry recipe = MakerItemFactory.getItemCreateEntry(toCreate);
|
||||
short createStatus = getCreateStatus(c, recipe);
|
||||
|
||||
switch(createStatus) {
|
||||
case 4: // no req skill level
|
||||
c.announce(MaplePacketCreator.serverNotice(1, "You don't have enough Maker level to complete this operation."));
|
||||
case -1:// non-available for Maker itemid has been tried to forge
|
||||
FilePrinter.printError(FilePrinter.EXPLOITS, "Player " + c.getPlayer().getName() + " tried to craft itemid " + toCreate + " using the Maker skill.");
|
||||
c.announce(MaplePacketCreator.serverNotice(1, "The requested item could not be crafted on this operation."));
|
||||
break;
|
||||
|
||||
case 3: // no meso
|
||||
c.announce(MaplePacketCreator.serverNotice(1, "You don't have enough mesos to complete this operation."));
|
||||
break;
|
||||
|
||||
case 2: // no req level
|
||||
c.announce(MaplePacketCreator.serverNotice(1, "You don't have enough level to complete this operation."));
|
||||
break;
|
||||
|
||||
|
||||
case 1: // no items
|
||||
c.announce(MaplePacketCreator.serverNotice(1, "You don't have all required items in your inventory to make " + recipe.getRewardAmount() + " " + ii.getName(toCreate) + "."));
|
||||
break;
|
||||
|
||||
case 2: // no meso
|
||||
NumberFormat nf = new DecimalFormat("#,###,###,###");
|
||||
c.announce(MaplePacketCreator.serverNotice(1, "You don't have enough mesos (" + nf.format(recipe.getCost()) + ") to complete this operation."));
|
||||
break;
|
||||
|
||||
case 3: // no req level
|
||||
c.announce(MaplePacketCreator.serverNotice(1, "You don't have enough level to complete this operation."));
|
||||
break;
|
||||
|
||||
case 4: // no req skill level
|
||||
c.announce(MaplePacketCreator.serverNotice(1, "You don't have enough Maker level to complete this operation."));
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!c.getPlayer().getInventory(ii.getInventoryType(toCreate)).isFull()) {
|
||||
if (MapleInventoryManipulator.checkSpace(c, toCreate, (short) recipe.getRewardAmount(), "")) {
|
||||
for (Pair<Integer, Integer> p : recipe.getReqItems()) {
|
||||
int toRemove = p.getLeft();
|
||||
MapleInventoryManipulator.removeById(c, ii.getInventoryType(toRemove), toRemove, p.getRight(), false, false);
|
||||
c.getAbstractPlayerInteraction().gainItem(p.getLeft(), (short) -p.getRight());
|
||||
}
|
||||
|
||||
if(toDisassemble != -1) {
|
||||
MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.EQUIP, (short) pos, (short) 1, false);
|
||||
c.announce(MaplePacketCreator.getShowItemGain(toDisassemble, (short) -1, true));
|
||||
}
|
||||
|
||||
int cost = recipe.getCost();
|
||||
if(stimulantid == -1 && reagentids.isEmpty()) {
|
||||
if(cost > 0) c.getPlayer().gainMeso(-cost);
|
||||
|
||||
c.getPlayer().setCS(true);
|
||||
c.getAbstractPlayerInteraction().gainItem(toCreate, (short) recipe.getRewardAmount());
|
||||
c.getPlayer().setCS(false);
|
||||
} else {
|
||||
if(stimulantid != -1) c.getAbstractPlayerInteraction().gainItem(stimulantid, (short) -1);
|
||||
if(!reagentids.isEmpty()) {
|
||||
for(Entry<Integer, Short> r : reagentids.entrySet()) {
|
||||
c.getAbstractPlayerInteraction().gainItem(r.getKey(), (short) (-1 * r.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
if(cost > 0) c.getPlayer().gainMeso(-cost);
|
||||
makerSucceeded = addBoostedMakerItem(c, toCreate, stimulantid, reagentids);
|
||||
}
|
||||
|
||||
if(makerSucceeded) c.announce(MaplePacketCreator.serverNotice(1, "You have successfully created " + recipe.getRewardAmount() + " " + ii.getName(toCreate) + "."));
|
||||
else c.getPlayer().dropMessage(5, "The Maker skill lights up, but the skill winds up as if nothing happened.");
|
||||
|
||||
c.announce(MaplePacketCreator.showMakerEffect(makerSucceeded));
|
||||
c.getPlayer().getMap().broadcastMessage(c.getPlayer(), MaplePacketCreator.showForeignMakerEffect(c.getPlayer().getId(), makerSucceeded), false);
|
||||
|
||||
if(toCreate == 4260003 && c.getPlayer().getQuestStatus(6033) == 1) {
|
||||
c.getAbstractPlayerInteraction().setQuestProgress(6033, 1);
|
||||
}
|
||||
MapleInventoryManipulator.addById(c, toCreate, (short) recipe.getRewardAmount());
|
||||
|
||||
c.announce(MaplePacketCreator.serverNotice(1, "You have created " + recipe.getRewardAmount() + " " + ii.getName(toCreate) + "."));
|
||||
c.announce(MaplePacketCreator.showMakerEffect());
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.serverNotice(1, "Your inventory is full."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private short getCreateStatus(MapleClient c, MakerItemCreateEntry recipe) {
|
||||
// checks and prevents hackers from PE'ing Maker operations with invalid operations
|
||||
private static void removeOddMakerReagents(int toCreate, Map<Integer, Short> reagentids) {
|
||||
Map<Integer, Integer> reagentType = new LinkedHashMap<>();
|
||||
List<Integer> toRemove = new LinkedList<>();
|
||||
|
||||
boolean isWeapon = ItemConstants.isWeapon(toCreate);
|
||||
|
||||
for(Entry<Integer, Short> r : reagentids.entrySet()) {
|
||||
int curRid = r.getKey();
|
||||
int type = r.getKey() / 100;
|
||||
|
||||
if(type < 42502 && !isWeapon) { // only weapons should gain w.att/m.att from these.
|
||||
toRemove.add(curRid);
|
||||
} else {
|
||||
Integer tableRid = reagentType.get(type);
|
||||
|
||||
if(tableRid != null) {
|
||||
if(tableRid < curRid) {
|
||||
toRemove.add(tableRid);
|
||||
reagentType.put(type, curRid);
|
||||
} else {
|
||||
toRemove.add(curRid);
|
||||
}
|
||||
} else {
|
||||
reagentType.put(type, curRid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// removing less effective gems of repeated type
|
||||
for(Integer i : toRemove) {
|
||||
reagentids.remove(i);
|
||||
}
|
||||
|
||||
// only quantity 1 of each gem will be accepted by the Maker skill
|
||||
for(Integer i : reagentids.keySet()) {
|
||||
reagentids.put(i, (short) 1);
|
||||
}
|
||||
}
|
||||
|
||||
private static int getMakerReagentSlots(int itemId) {
|
||||
try {
|
||||
int eqpLevel = ii.getEquipStats(itemId).get("reqLevel");
|
||||
|
||||
if(eqpLevel < 78) {
|
||||
return 1;
|
||||
} else if(eqpLevel >= 78 && eqpLevel < 108) {
|
||||
return 2;
|
||||
} else {
|
||||
return 3;
|
||||
}
|
||||
} catch(NullPointerException npe) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static int getMakerStimulant(int itemId) {
|
||||
EquipType et = EquipType.getEquipTypeById(itemId);
|
||||
|
||||
switch(et) {
|
||||
case GLOVES:
|
||||
return 4130000;
|
||||
|
||||
case SHOES:
|
||||
return 4130001;
|
||||
|
||||
case SWORD:
|
||||
return 4130002;
|
||||
|
||||
case AXE:
|
||||
return 4130003;
|
||||
|
||||
case MACE:
|
||||
return 4130004;
|
||||
|
||||
case SWORD_2H:
|
||||
return 4130005;
|
||||
|
||||
case AXE_2H:
|
||||
return 4130006;
|
||||
|
||||
case MACE_2H:
|
||||
return 4130007;
|
||||
|
||||
case SPEAR:
|
||||
return 4130008;
|
||||
|
||||
case POLEARM:
|
||||
return 4130009;
|
||||
|
||||
case WAND:
|
||||
return 4130010;
|
||||
|
||||
case STAFF:
|
||||
return 4130011;
|
||||
|
||||
case BOW:
|
||||
return 4130012;
|
||||
|
||||
case CROSSBOW:
|
||||
return 4130013;
|
||||
|
||||
case DAGGER:
|
||||
return 4130014;
|
||||
|
||||
case CLAW:
|
||||
return 4130015;
|
||||
|
||||
case KNUCKLER:
|
||||
return 4130016;
|
||||
|
||||
case PISTOL:
|
||||
return 4130017;
|
||||
|
||||
case CAP:
|
||||
return 4130018;
|
||||
|
||||
case COAT:
|
||||
return 4130019;
|
||||
|
||||
case PANTS:
|
||||
return 4130020;
|
||||
|
||||
case LONGCOAT:
|
||||
return 4130021;
|
||||
|
||||
case SHIELD:
|
||||
return 4130022;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
private static Pair<Integer, Integer> generateDisassemblyInfo(int itemId) {
|
||||
int recvFee = ii.getMakerDisassembledFee(itemId);
|
||||
if(recvFee > -1) {
|
||||
int recvQty = ii.getMakerDisassembledQuantity(itemId);
|
||||
if(recvQty > 0) {
|
||||
return new Pair<>(recvFee, recvQty);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static short getCreateStatus(MapleClient c, MakerItemCreateEntry recipe) {
|
||||
if(recipe == null) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!hasItems(c, recipe)) {
|
||||
return 1;
|
||||
}
|
||||
@@ -99,7 +381,7 @@ public final class MakerSkillHandler extends AbstractMaplePacketHandler {
|
||||
return 0;
|
||||
}
|
||||
|
||||
private boolean hasItems(MapleClient c, MakerItemCreateEntry recipe) {
|
||||
private static boolean hasItems(MapleClient c, MakerItemCreateEntry recipe) {
|
||||
for (Pair<Integer, Integer> p : recipe.getReqItems()) {
|
||||
int itemId = p.getLeft();
|
||||
if (c.getPlayer().getInventory(ii.getInventoryType(itemId)).countById(itemId) < p.getRight()) {
|
||||
@@ -108,4 +390,84 @@ public final class MakerSkillHandler extends AbstractMaplePacketHandler {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean addBoostedMakerItem(MapleClient c, int itemid, int stimulantid, Map<Integer, Short> reagentids) {
|
||||
if(stimulantid != -1 && !ii.rollSuccessChance(90.0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Item item = ii.getEquipById(itemid);
|
||||
if(item == null) return false;
|
||||
|
||||
Equip eqp = (Equip)item;
|
||||
if(ItemConstants.isAccessory(item.getItemId()) && eqp.getUpgradeSlots() <= 0) eqp.setUpgradeSlots(3);
|
||||
|
||||
if(ServerConstants.USE_ENHANCED_CRAFTING == true) {
|
||||
if(!(c.getPlayer().isGM() && ServerConstants.USE_PERFECT_GM_SCROLL)) {
|
||||
eqp.setUpgradeSlots((byte)(eqp.getUpgradeSlots() + 1));
|
||||
}
|
||||
item = MapleItemInformationProvider.getInstance().scrollEquipWithId(eqp, 2049100, true, 0, c.getPlayer().isGM());
|
||||
}
|
||||
|
||||
if(!reagentids.isEmpty()) {
|
||||
Map<String, Integer> stats = new LinkedHashMap<>();
|
||||
List<Short> randOption = new LinkedList<>();
|
||||
List<Short> randStat = new LinkedList<>();
|
||||
|
||||
for(Entry<Integer, Short> r : reagentids.entrySet()) {
|
||||
Pair<String, Integer> reagentBuff = ii.getMakerReagentStatUpgrade(r.getKey());
|
||||
|
||||
if(reagentBuff != null) {
|
||||
String s = reagentBuff.getLeft();
|
||||
|
||||
if(s.substring(0, 4).contains("rand")) {
|
||||
if(s.substring(4).equals("Stat")) {
|
||||
randStat.add((short) (reagentBuff.getRight() * r.getValue()));
|
||||
} else {
|
||||
randOption.add((short) (reagentBuff.getRight() * r.getValue()));
|
||||
}
|
||||
} else {
|
||||
String stat = s.substring(3);
|
||||
|
||||
if(!stat.equals("ReqLevel")) { // improve req level... really?
|
||||
switch (stat) {
|
||||
case "MaxHP":
|
||||
stat = "MHP";
|
||||
break;
|
||||
|
||||
case "MaxMP":
|
||||
stat = "MMP";
|
||||
break;
|
||||
}
|
||||
|
||||
Integer d = stats.get(stat);
|
||||
if(d == null) {
|
||||
stats.put(stat, reagentBuff.getRight() * r.getValue());
|
||||
} else {
|
||||
stats.put(stat, d + (reagentBuff.getRight() * r.getValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ii.improveEquipStats(eqp, stats);
|
||||
|
||||
for(Short s : randStat) {
|
||||
ii.scrollOptionEquipWithChaos(eqp, s, false);
|
||||
}
|
||||
|
||||
for(Short s : randOption) {
|
||||
ii.scrollOptionEquipWithChaos(eqp, s, true);
|
||||
}
|
||||
}
|
||||
|
||||
if(stimulantid != -1) {
|
||||
eqp = ii.randomizeUpgradeStats(eqp);
|
||||
}
|
||||
|
||||
MapleInventoryManipulator.addFromDrop(c, item, false, -1);
|
||||
c.announce(MaplePacketCreator.getShowItemGain(itemid, (short) 1, true));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -342,14 +342,9 @@ public class AbstractPlayerInteraction {
|
||||
|
||||
public Item evolvePet(byte slot, int afterId) {
|
||||
MaplePet evolved = null;
|
||||
MaplePet target = null;
|
||||
Item tmp;
|
||||
MaplePet target;
|
||||
|
||||
long period = 90; //refreshes expiration date: 90 days
|
||||
period *= 24;
|
||||
period *= 60;
|
||||
period *= 60;
|
||||
period *= 1000;
|
||||
long period = 90 * 24 * 60 * 60 * 1000; //refreshes expiration date: 90 days
|
||||
|
||||
target = getPlayer().getPet(slot);
|
||||
if(target == null) {
|
||||
@@ -357,7 +352,7 @@ public class AbstractPlayerInteraction {
|
||||
return(null);
|
||||
}
|
||||
|
||||
tmp = gainItem(afterId, (short)1, false, true, period, target);
|
||||
Item tmp = gainItem(afterId, (short) 1, false, true, period, target);
|
||||
getPlayer().unequipPet(target, true, false);
|
||||
|
||||
/*
|
||||
@@ -410,18 +405,13 @@ public class AbstractPlayerInteraction {
|
||||
return gainItem(id, quantity, randomStats, showMessage, expires, null);
|
||||
}
|
||||
|
||||
private boolean isAccessory(int id) {
|
||||
int val = id / 10000;
|
||||
return(val >= 111 && val <= 113);
|
||||
}
|
||||
|
||||
public Item gainItem(int id, short quantity, boolean randomStats, boolean showMessage, long expires, MaplePet from) {
|
||||
public Item gainItem(int id, short quantity, boolean randomStats, boolean showMessage, long expires, MaplePet from) {
|
||||
Item item = null;
|
||||
MaplePet evolved = null;
|
||||
MaplePet evolved;
|
||||
int petId = -1;
|
||||
|
||||
if (quantity >= 0) {
|
||||
if (id >= 5000000 && id <= 5000100) {
|
||||
if (ItemConstants.isPet(id)) {
|
||||
petId = MaplePet.createPet(id);
|
||||
|
||||
if(from != null) {
|
||||
@@ -451,12 +441,13 @@ public class AbstractPlayerInteraction {
|
||||
|
||||
if(item != null) {
|
||||
Equip it = (Equip)item;
|
||||
if(isAccessory(item.getItemId()) && it.getUpgradeSlots() <= 0) it.setUpgradeSlots(3);
|
||||
if(ItemConstants.isAccessory(item.getItemId()) && it.getUpgradeSlots() <= 0) it.setUpgradeSlots(3);
|
||||
|
||||
if(ServerConstants.USE_ENHANCED_CRAFTING == true && c.getPlayer().getCS() == true) {
|
||||
Equip eqp = (Equip)item;
|
||||
eqp.setUpgradeSlots((byte)(eqp.getUpgradeSlots() + 1));
|
||||
|
||||
if(!(c.getPlayer().isGM() && ServerConstants.USE_PERFECT_GM_SCROLL)) {
|
||||
eqp.setUpgradeSlots((byte)(eqp.getUpgradeSlots() + 1));
|
||||
}
|
||||
item = MapleItemInformationProvider.getInstance().scrollEquipWithId(item, 2049100, true, 0, c.getPlayer().isGM());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,8 +104,18 @@ public class CashShop {
|
||||
}
|
||||
|
||||
if (ItemConstants.EXPIRING_ITEMS) {
|
||||
if(itemId == 5211048 || itemId == 5360042) { // 4 Hour 2X coupons, the period is 1, but we don't want them to last a day.
|
||||
item.setExpiration(System.currentTimeMillis() + (1000 * 60 * 60 * 4));
|
||||
if(period == 1) {
|
||||
if(itemId == 5211048 || itemId == 5360042) { // 4 Hour 2X coupons, the period is 1, but we don't want them to last a day.
|
||||
item.setExpiration(System.currentTimeMillis() + (1000 * 60 * 60 * 4));
|
||||
/*
|
||||
} else if(itemId == 5211047 || itemId == 5360014) { // 3 Hour 2X coupons, unused as of now
|
||||
item.setExpiration(System.currentTimeMillis() + (1000 * 60 * 60 * 3));
|
||||
*/
|
||||
} else if(itemId == 5211060) { // 2 Hour 3X coupons.
|
||||
item.setExpiration(System.currentTimeMillis() + (1000 * 60 * 60 * 2));
|
||||
} else {
|
||||
item.setExpiration(System.currentTimeMillis() + (1000 * 60 * 60 * 24));
|
||||
}
|
||||
} else {
|
||||
item.setExpiration(System.currentTimeMillis() + (1000 * 60 * 60 * 24 * period));
|
||||
}
|
||||
|
||||
@@ -21,75 +21,147 @@
|
||||
*/
|
||||
package server;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import constants.EquipType;
|
||||
import constants.ServerConstants;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import tools.DatabaseConnection;
|
||||
import java.util.Map.Entry;
|
||||
import tools.Pair;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jay Estrella
|
||||
* @author Jay Estrella, Ronan
|
||||
*/
|
||||
public class MakerItemFactory {
|
||||
private static Map<Integer, MakerItemCreateEntry> createCache = new HashMap<Integer, MakerItemCreateEntry>();
|
||||
|
||||
public static MakerItemCreateEntry getItemCreateEntry(int toCreate) {
|
||||
if (createCache.get(toCreate) != null) {
|
||||
return createCache.get(toCreate);
|
||||
} else {
|
||||
try {
|
||||
Connection con = DatabaseConnection.getConnection();
|
||||
PreparedStatement ps = con.prepareStatement("SELECT req_level, req_maker_level, req_meso, quantity FROM makercreatedata WHERE itemid = ?");
|
||||
ps.setInt(1, toCreate);
|
||||
ResultSet rs = ps.executeQuery();
|
||||
int reqLevel = 0;
|
||||
int reqMakerLevel = 0;
|
||||
int cost = 0;
|
||||
int toGive = 0;
|
||||
if (rs.next()) {
|
||||
reqLevel = rs.getInt("req_level");
|
||||
reqMakerLevel = rs.getInt("req_maker_level");
|
||||
cost = rs.getInt("req_meso");
|
||||
toGive = rs.getInt("quantity");
|
||||
}
|
||||
ps.close();
|
||||
rs.close();
|
||||
MakerItemCreateEntry ret = new MakerItemCreateEntry(cost, reqLevel, reqMakerLevel, toGive);
|
||||
ps = con.prepareStatement("SELECT req_item, count FROM makerrecipedata WHERE itemid = ?");
|
||||
ps.setInt(1, toCreate);
|
||||
rs = ps.executeQuery();
|
||||
while (rs.next()) {
|
||||
ret.addReqItem(rs.getInt("req_item"), rs.getInt("count"));
|
||||
}
|
||||
rs.close();
|
||||
ps.close();
|
||||
con.close();
|
||||
createCache.put(toCreate, ret);
|
||||
} catch (SQLException sqle) {
|
||||
sqle.printStackTrace();
|
||||
private static MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
|
||||
|
||||
public static MakerItemCreateEntry getItemCreateEntry(int toCreate, int stimulantid, Map<Integer, Short> reagentids) {
|
||||
MakerItemCreateEntry makerEntry = ii.getMakerItemEntry(toCreate);
|
||||
if(makerEntry == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// THEY DECIDED FOR SOME BIZARRE PATTERN ON THE FEE THING, ALMOST RANDOMIZED.
|
||||
if(stimulantid != -1) {
|
||||
makerEntry.addCost(getMakerStimulantFee(toCreate));
|
||||
}
|
||||
|
||||
if(!reagentids.isEmpty()) {
|
||||
for(Entry<Integer, Short> r : reagentids.entrySet()) {
|
||||
makerEntry.addCost((getMakerReagentFee(toCreate, ((r.getKey() % 10) + 1))) * r.getValue());
|
||||
}
|
||||
}
|
||||
return createCache.get(toCreate);
|
||||
|
||||
makerEntry.trimCost(); // "commit" the real cost of the recipe.
|
||||
return makerEntry;
|
||||
}
|
||||
|
||||
public static MakerItemCreateEntry generateLeftoverCrystalEntry(int fromLeftoverid) {
|
||||
MakerItemCreateEntry ret = new MakerItemCreateEntry(0, 0, 1, 1);
|
||||
ret.addReqItem(fromLeftoverid, 100);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static MakerItemCreateEntry generateDisassemblyCrystalEntry(int cost, int crystalGain) { // equipment at specific position already taken
|
||||
MakerItemCreateEntry ret = new MakerItemCreateEntry(cost, 0, 1, crystalGain);
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static double getMakerStimulantFee(int itemid) {
|
||||
if(ServerConstants.USE_MAKER_FEE_HEURISTICS) {
|
||||
EquipType et = EquipType.getEquipTypeById(itemid);
|
||||
int eqpLevel = ii.getEquipStats(itemid).get("reqLevel");
|
||||
|
||||
switch(et) {
|
||||
case CAP:
|
||||
return 1145.736246 * Math.exp(0.03336832546 * eqpLevel);
|
||||
|
||||
case LONGCOAT:
|
||||
return 2117.469118 * Math.exp(0.03355349137 * eqpLevel);
|
||||
|
||||
case SHOES:
|
||||
return 1218.624674 * Math.exp(0.0342266043 * eqpLevel);
|
||||
|
||||
case GLOVES:
|
||||
return 2129.531152 * Math.exp(0.03421778102 * eqpLevel);
|
||||
|
||||
case COAT:
|
||||
return 1770.630579 * Math.exp(0.03359768677 * eqpLevel);
|
||||
|
||||
case PANTS:
|
||||
return 1442.98837 * Math.exp(0.03444783295 * eqpLevel);
|
||||
|
||||
case SHIELD:
|
||||
return 6312.40136 * Math.exp(0.0237929527 * eqpLevel);
|
||||
|
||||
default: // weapons
|
||||
return 4313.581428 * Math.exp(0.03147837094 * eqpLevel);
|
||||
}
|
||||
} else {
|
||||
return 14000;
|
||||
}
|
||||
}
|
||||
|
||||
private static double getMakerReagentFee(int itemid, int reagentLevel) {
|
||||
if(ServerConstants.USE_MAKER_FEE_HEURISTICS) {
|
||||
EquipType et = EquipType.getEquipTypeById(itemid);
|
||||
int eqpLevel = ii.getEquipStats(itemid).get("reqLevel");
|
||||
|
||||
switch(et) {
|
||||
case CAP:
|
||||
return 5592.01613 * Math.exp(0.02914576018 * eqpLevel) * reagentLevel;
|
||||
|
||||
case LONGCOAT:
|
||||
return 3405.23441 * Math.exp(0.03413001038 * eqpLevel) * reagentLevel;
|
||||
|
||||
case SHOES:
|
||||
return 2115.697484 * Math.exp(0.0354881705 * eqpLevel) * reagentLevel;
|
||||
|
||||
case GLOVES:
|
||||
return 4684.040894 * Math.exp(0.03166500585 * eqpLevel) * reagentLevel;
|
||||
|
||||
case COAT:
|
||||
return 2955.89017 * Math.exp(0.0339948456 * eqpLevel) * reagentLevel;
|
||||
|
||||
case PANTS:
|
||||
return 1774.722181 * Math.exp(0.03854321409 * eqpLevel) * reagentLevel;
|
||||
|
||||
case SHIELD:
|
||||
return 12014.11296 * Math.exp(0.02185471162 * eqpLevel) * reagentLevel;
|
||||
|
||||
default: // weapons
|
||||
return 4538.650247 * Math.exp(0.0371980303 * eqpLevel) * reagentLevel;
|
||||
}
|
||||
} else {
|
||||
return 8000 * reagentLevel;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MakerItemCreateEntry {
|
||||
private int reqLevel, reqMakerLevel;
|
||||
private int cost;
|
||||
private List<Pair<Integer, Integer>> reqItems = new ArrayList<Pair<Integer, Integer>>(); // itemId / amount
|
||||
private double cost;
|
||||
private int reqCost;
|
||||
private List<Pair<Integer, Integer>> reqItems = new ArrayList<>(); // itemId / amount
|
||||
private int toGive;
|
||||
|
||||
private MakerItemCreateEntry(int cost, int reqLevel, int reqMakerLevel, int toGive) {
|
||||
public MakerItemCreateEntry(int cost, int reqLevel, int reqMakerLevel, int toGive) {
|
||||
this.cost = cost;
|
||||
this.reqLevel = reqLevel;
|
||||
this.reqMakerLevel = reqMakerLevel;
|
||||
this.toGive = toGive;
|
||||
}
|
||||
|
||||
public MakerItemCreateEntry(MakerItemCreateEntry mi) {
|
||||
this.cost = mi.cost;
|
||||
this.reqLevel = mi.reqLevel;
|
||||
this.reqMakerLevel = mi.reqMakerLevel;
|
||||
this.toGive = mi.toGive;
|
||||
|
||||
for(Pair<Integer, Integer> p : mi.reqItems) {
|
||||
reqItems.add(p);
|
||||
}
|
||||
}
|
||||
|
||||
public int getRewardAmount() {
|
||||
return toGive;
|
||||
@@ -108,11 +180,20 @@ public class MakerItemFactory {
|
||||
}
|
||||
|
||||
public int getCost() {
|
||||
return cost;
|
||||
return reqCost;
|
||||
}
|
||||
|
||||
public void addCost(double amount) {
|
||||
cost += amount;
|
||||
}
|
||||
|
||||
protected void addReqItem(int itemId, int amount) {
|
||||
reqItems.add(new Pair<>(itemId, amount));
|
||||
}
|
||||
|
||||
public void trimCost() {
|
||||
reqCost = (int) (cost / 1000);
|
||||
reqCost *= 1000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -410,7 +410,7 @@ public class MapleInventoryManipulator {
|
||||
}
|
||||
if (dst == -6) { // unequip the overall
|
||||
Item top = c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).getItem((short) -5);
|
||||
if (top != null && isOverall(top.getItemId())) {
|
||||
if (top != null && ItemConstants.isOverall(top.getItemId())) {
|
||||
if (c.getPlayer().getInventory(MapleInventoryType.EQUIP).isFull()) {
|
||||
c.announce(MaplePacketCreator.getInventoryFull());
|
||||
c.announce(MaplePacketCreator.getShowInventoryFull());
|
||||
@@ -420,7 +420,7 @@ public class MapleInventoryManipulator {
|
||||
}
|
||||
} else if (dst == -5) {
|
||||
final Item bottom = c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).getItem((short) -6);
|
||||
if (bottom != null && isOverall(source.getItemId())) {
|
||||
if (bottom != null && ItemConstants.isOverall(source.getItemId())) {
|
||||
if (c.getPlayer().getInventory(MapleInventoryType.EQUIP).isFull()) {
|
||||
c.announce(MaplePacketCreator.getInventoryFull());
|
||||
c.announce(MaplePacketCreator.getShowInventoryFull());
|
||||
@@ -477,7 +477,7 @@ public class MapleInventoryManipulator {
|
||||
target.setPosition(src);
|
||||
c.getPlayer().getInventory(MapleInventoryType.EQUIP).addFromDB(target);
|
||||
}
|
||||
if (c.getPlayer().getBuffedValue(MapleBuffStat.BOOSTER) != null && isWeapon(source.getItemId())) {
|
||||
if (c.getPlayer().getBuffedValue(MapleBuffStat.BOOSTER) != null && ItemConstants.isWeapon(source.getItemId())) {
|
||||
c.getPlayer().cancelBuffStats(MapleBuffStat.BOOSTER);
|
||||
}
|
||||
|
||||
@@ -590,12 +590,4 @@ public class MapleInventoryManipulator {
|
||||
private static boolean isDroppedItemRestricted(Item it) {
|
||||
return ServerConstants.USE_ERASE_UNTRADEABLE_DROP && ((it.getFlag() & ItemConstants.UNTRADEABLE) == ItemConstants.UNTRADEABLE);
|
||||
}
|
||||
|
||||
private static boolean isOverall(int itemId) {
|
||||
return itemId / 10000 == 105;
|
||||
}
|
||||
|
||||
private static boolean isWeapon(int itemId) {
|
||||
return itemId >= 1302000 && itemId < 1492024;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,9 @@ import constants.skills.Assassin;
|
||||
import constants.skills.Gunslinger;
|
||||
import constants.skills.NightWalker;
|
||||
import java.sql.Connection;
|
||||
import server.MakerItemFactory.MakerItemCreateEntry;
|
||||
import server.life.MapleMonsterInformationProvider;
|
||||
import server.life.MapleLifeFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -111,6 +113,10 @@ public class MapleItemInformationProvider {
|
||||
protected Map<Integer, Boolean> isQuestItemCache = new HashMap<>();
|
||||
protected Map<Integer, String> equipmentSlotCache = new HashMap<>();
|
||||
protected Map<Integer, Boolean> noCancelMouseCache = new HashMap<>();
|
||||
protected Map<Integer, Integer> mobCrystalMakerCache = new HashMap<>();
|
||||
protected Map<Integer, Pair<String, Integer>> statUpgradeMakerCache = new HashMap<>();
|
||||
protected Map<Integer, MakerItemFactory.MakerItemCreateEntry> makerItemCache = new HashMap<>();
|
||||
|
||||
|
||||
private MapleItemInformationProvider() {
|
||||
loadCardIdData();
|
||||
@@ -575,11 +581,77 @@ public class MapleItemInformationProvider {
|
||||
return (short)Math.min(Short.MAX_VALUE, value);
|
||||
}
|
||||
|
||||
private static short chscrollRandomizedStat() {
|
||||
return (short) Randomizer.rand(-ServerConstants.CHSCROLL_STAT_RANGE, ServerConstants.CHSCROLL_STAT_RANGE);
|
||||
private static short chscrollRandomizedStat(int range) {
|
||||
return (short) Randomizer.rand(-range, range);
|
||||
}
|
||||
|
||||
private void scrollEquipWithChaos(Equip nEquip) {
|
||||
public void scrollOptionEquipWithChaos(Equip nEquip, int range, boolean option) {
|
||||
// option: watk, matk, wdef, mdef, spd, jump, hp, mp
|
||||
// stat: dex, luk, str, int, avoid, acc
|
||||
|
||||
if(!option) {
|
||||
if (nEquip.getStr() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setStr(getMaximumShortMaxIfOverflow(nEquip.getStr(), (nEquip.getStr() + chscrollRandomizedStat(range))));
|
||||
else nEquip.setStr(getMaximumShortMaxIfOverflow(0, (nEquip.getStr() + chscrollRandomizedStat(range))));
|
||||
}
|
||||
if (nEquip.getDex() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setDex(getMaximumShortMaxIfOverflow(nEquip.getDex(), (nEquip.getDex() + chscrollRandomizedStat(range))));
|
||||
else nEquip.setDex(getMaximumShortMaxIfOverflow(0, (nEquip.getDex() + chscrollRandomizedStat(range))));
|
||||
}
|
||||
if (nEquip.getInt() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setInt(getMaximumShortMaxIfOverflow(nEquip.getInt(), (nEquip.getInt() + chscrollRandomizedStat(range))));
|
||||
else nEquip.setInt(getMaximumShortMaxIfOverflow(0, (nEquip.getInt() + chscrollRandomizedStat(range))));
|
||||
}
|
||||
if (nEquip.getLuk() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setLuk(getMaximumShortMaxIfOverflow(nEquip.getLuk(), (nEquip.getLuk() + chscrollRandomizedStat(range))));
|
||||
else nEquip.setLuk(getMaximumShortMaxIfOverflow(0, (nEquip.getLuk() + chscrollRandomizedStat(range))));
|
||||
}
|
||||
if (nEquip.getAcc() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setAcc(getMaximumShortMaxIfOverflow(nEquip.getAcc(), (nEquip.getAcc() + chscrollRandomizedStat(range))));
|
||||
else nEquip.setAcc(getMaximumShortMaxIfOverflow(0, (nEquip.getAcc() + chscrollRandomizedStat(range))));
|
||||
}
|
||||
if (nEquip.getAvoid() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setAvoid(getMaximumShortMaxIfOverflow(nEquip.getAvoid(), (nEquip.getAvoid() + chscrollRandomizedStat(range))));
|
||||
else nEquip.setAvoid(getMaximumShortMaxIfOverflow(0, (nEquip.getAvoid() + chscrollRandomizedStat(range))));
|
||||
}
|
||||
} else {
|
||||
if (nEquip.getWatk() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setWatk(getMaximumShortMaxIfOverflow(nEquip.getWatk(), (nEquip.getWatk() + chscrollRandomizedStat(range))));
|
||||
else nEquip.setWatk(getMaximumShortMaxIfOverflow(0, (nEquip.getWatk() + chscrollRandomizedStat(range))));
|
||||
}
|
||||
if (nEquip.getWdef() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setWdef(getMaximumShortMaxIfOverflow(nEquip.getWdef(), (nEquip.getWdef() + chscrollRandomizedStat(range))));
|
||||
else nEquip.setWdef(getMaximumShortMaxIfOverflow(0, (nEquip.getWdef() + chscrollRandomizedStat(range))));
|
||||
}
|
||||
if (nEquip.getMatk() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setMatk(getMaximumShortMaxIfOverflow(nEquip.getMatk(), (nEquip.getMatk() + chscrollRandomizedStat(range))));
|
||||
else nEquip.setMatk(getMaximumShortMaxIfOverflow(0, (nEquip.getMatk() + chscrollRandomizedStat(range))));
|
||||
}
|
||||
if (nEquip.getMdef() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setMdef(getMaximumShortMaxIfOverflow(nEquip.getMdef(), (nEquip.getMdef() + chscrollRandomizedStat(range))));
|
||||
else nEquip.setMdef(getMaximumShortMaxIfOverflow(0, (nEquip.getMdef() + chscrollRandomizedStat(range))));
|
||||
}
|
||||
|
||||
if (nEquip.getSpeed() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setSpeed(getMaximumShortMaxIfOverflow(nEquip.getSpeed(), (nEquip.getSpeed() + chscrollRandomizedStat(range))));
|
||||
else nEquip.setSpeed(getMaximumShortMaxIfOverflow(0, (nEquip.getSpeed() + chscrollRandomizedStat(range))));
|
||||
}
|
||||
if (nEquip.getJump() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setJump(getMaximumShortMaxIfOverflow(nEquip.getJump(), (nEquip.getJump() + chscrollRandomizedStat(range))));
|
||||
else nEquip.setJump(getMaximumShortMaxIfOverflow(0, (nEquip.getJump() + chscrollRandomizedStat(range))));
|
||||
}
|
||||
if (nEquip.getHp() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setHp(getMaximumShortMaxIfOverflow(nEquip.getHp(), (nEquip.getHp() + chscrollRandomizedStat(range))));
|
||||
else nEquip.setHp(getMaximumShortMaxIfOverflow(0, (nEquip.getHp() + chscrollRandomizedStat(range))));
|
||||
}
|
||||
if (nEquip.getMp() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setMp(getMaximumShortMaxIfOverflow(nEquip.getMp(), (nEquip.getMp() + chscrollRandomizedStat(range))));
|
||||
else nEquip.setMp(getMaximumShortMaxIfOverflow(0, (nEquip.getMp() + chscrollRandomizedStat(range))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void scrollEquipWithChaos(Equip nEquip, int range) {
|
||||
if(ServerConstants.SCROLL_CHANCE_RATE > 0) {
|
||||
int temp;
|
||||
short curStr, curDex, curInt, curLuk, curWatk, curWdef, curMatk, curMdef, curAcc, curAvoid, curSpeed, curJump, curHp, curMp;
|
||||
@@ -618,99 +690,99 @@ public class MapleItemInformationProvider {
|
||||
|
||||
for(int i = 0; i < ServerConstants.SCROLL_CHANCE_RATE; i++) {
|
||||
if (nEquip.getStr() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curStr + chscrollRandomizedStat();
|
||||
else temp = nEquip.getStr() + chscrollRandomizedStat();
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curStr + chscrollRandomizedStat(range);
|
||||
else temp = nEquip.getStr() + chscrollRandomizedStat(range);
|
||||
|
||||
curStr = getMaximumShortMaxIfOverflow(temp, curStr);
|
||||
}
|
||||
|
||||
if (nEquip.getDex() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curDex + chscrollRandomizedStat();
|
||||
else temp = nEquip.getDex() + chscrollRandomizedStat();
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curDex + chscrollRandomizedStat(range);
|
||||
else temp = nEquip.getDex() + chscrollRandomizedStat(range);
|
||||
|
||||
curDex = getMaximumShortMaxIfOverflow(temp, curDex);
|
||||
}
|
||||
|
||||
if (nEquip.getInt() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curInt + chscrollRandomizedStat();
|
||||
else temp = nEquip.getInt() + chscrollRandomizedStat();
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curInt + chscrollRandomizedStat(range);
|
||||
else temp = nEquip.getInt() + chscrollRandomizedStat(range);
|
||||
|
||||
curInt = getMaximumShortMaxIfOverflow(temp, curInt);
|
||||
}
|
||||
|
||||
if (nEquip.getLuk() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curLuk + chscrollRandomizedStat();
|
||||
else temp = nEquip.getLuk() + chscrollRandomizedStat();
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curLuk + chscrollRandomizedStat(range);
|
||||
else temp = nEquip.getLuk() + chscrollRandomizedStat(range);
|
||||
|
||||
curLuk = getMaximumShortMaxIfOverflow(temp, curLuk);
|
||||
}
|
||||
|
||||
if (nEquip.getWatk() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curWatk + chscrollRandomizedStat();
|
||||
else temp = nEquip.getWatk() + chscrollRandomizedStat();
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curWatk + chscrollRandomizedStat(range);
|
||||
else temp = nEquip.getWatk() + chscrollRandomizedStat(range);
|
||||
|
||||
curWatk = getMaximumShortMaxIfOverflow(temp, curWatk);
|
||||
}
|
||||
|
||||
if (nEquip.getWdef() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curWdef + chscrollRandomizedStat();
|
||||
else temp = nEquip.getWdef() + chscrollRandomizedStat();
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curWdef + chscrollRandomizedStat(range);
|
||||
else temp = nEquip.getWdef() + chscrollRandomizedStat(range);
|
||||
|
||||
curWdef = getMaximumShortMaxIfOverflow(temp, curWdef);
|
||||
}
|
||||
|
||||
if (nEquip.getMatk() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curMatk + chscrollRandomizedStat();
|
||||
else temp = nEquip.getMatk() + chscrollRandomizedStat();
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curMatk + chscrollRandomizedStat(range);
|
||||
else temp = nEquip.getMatk() + chscrollRandomizedStat(range);
|
||||
|
||||
curMatk = getMaximumShortMaxIfOverflow(temp, curMatk);
|
||||
}
|
||||
|
||||
if (nEquip.getMdef() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curMdef + chscrollRandomizedStat();
|
||||
else temp = nEquip.getMdef() + chscrollRandomizedStat();
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curMdef + chscrollRandomizedStat(range);
|
||||
else temp = nEquip.getMdef() + chscrollRandomizedStat(range);
|
||||
|
||||
curMdef = getMaximumShortMaxIfOverflow(temp, curMdef);
|
||||
}
|
||||
|
||||
if (nEquip.getAcc() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curAcc + chscrollRandomizedStat();
|
||||
else temp = nEquip.getAcc() + chscrollRandomizedStat();
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curAcc + chscrollRandomizedStat(range);
|
||||
else temp = nEquip.getAcc() + chscrollRandomizedStat(range);
|
||||
|
||||
curAcc = getMaximumShortMaxIfOverflow(temp, curAcc);
|
||||
}
|
||||
|
||||
if (nEquip.getAvoid() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curAvoid + chscrollRandomizedStat();
|
||||
else temp = nEquip.getAvoid() + chscrollRandomizedStat();
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curAvoid + chscrollRandomizedStat(range);
|
||||
else temp = nEquip.getAvoid() + chscrollRandomizedStat(range);
|
||||
|
||||
curAvoid = getMaximumShortMaxIfOverflow(temp, curAvoid);
|
||||
}
|
||||
|
||||
if (nEquip.getSpeed() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curSpeed + chscrollRandomizedStat();
|
||||
else temp = nEquip.getSpeed() + chscrollRandomizedStat();
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curSpeed + chscrollRandomizedStat(range);
|
||||
else temp = nEquip.getSpeed() + chscrollRandomizedStat(range);
|
||||
|
||||
curSpeed = getMaximumShortMaxIfOverflow(temp, curSpeed);
|
||||
}
|
||||
|
||||
if (nEquip.getJump() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curJump + chscrollRandomizedStat();
|
||||
else temp = nEquip.getJump() + chscrollRandomizedStat();
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curJump + chscrollRandomizedStat(range);
|
||||
else temp = nEquip.getJump() + chscrollRandomizedStat(range);
|
||||
|
||||
curJump = getMaximumShortMaxIfOverflow(temp, curJump);
|
||||
}
|
||||
|
||||
if (nEquip.getHp() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curHp + chscrollRandomizedStat();
|
||||
else temp = nEquip.getHp() + chscrollRandomizedStat();
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curHp + chscrollRandomizedStat(range);
|
||||
else temp = nEquip.getHp() + chscrollRandomizedStat(range);
|
||||
|
||||
curHp = getMaximumShortMaxIfOverflow(temp, curHp);
|
||||
}
|
||||
|
||||
if (nEquip.getMp() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curMp + chscrollRandomizedStat();
|
||||
else temp = nEquip.getMp() + chscrollRandomizedStat();
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curMp + chscrollRandomizedStat(range);
|
||||
else temp = nEquip.getMp() + chscrollRandomizedStat(range);
|
||||
|
||||
curMp = getMaximumShortMaxIfOverflow(temp, curMp);
|
||||
}
|
||||
@@ -734,60 +806,60 @@ public class MapleItemInformationProvider {
|
||||
|
||||
else {
|
||||
if (nEquip.getStr() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setStr(getMaximumShortMaxIfOverflow(nEquip.getStr(), (nEquip.getStr() + chscrollRandomizedStat())));
|
||||
else nEquip.setStr(getMaximumShortMaxIfOverflow(0, (nEquip.getStr() + chscrollRandomizedStat())));
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setStr(getMaximumShortMaxIfOverflow(nEquip.getStr(), (nEquip.getStr() + chscrollRandomizedStat(range))));
|
||||
else nEquip.setStr(getMaximumShortMaxIfOverflow(0, (nEquip.getStr() + chscrollRandomizedStat(range))));
|
||||
}
|
||||
if (nEquip.getDex() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setDex(getMaximumShortMaxIfOverflow(nEquip.getDex(), (nEquip.getDex() + chscrollRandomizedStat())));
|
||||
else nEquip.setDex(getMaximumShortMaxIfOverflow(0, (nEquip.getDex() + chscrollRandomizedStat())));
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setDex(getMaximumShortMaxIfOverflow(nEquip.getDex(), (nEquip.getDex() + chscrollRandomizedStat(range))));
|
||||
else nEquip.setDex(getMaximumShortMaxIfOverflow(0, (nEquip.getDex() + chscrollRandomizedStat(range))));
|
||||
}
|
||||
if (nEquip.getInt() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setInt(getMaximumShortMaxIfOverflow(nEquip.getInt(), (nEquip.getInt() + chscrollRandomizedStat())));
|
||||
else nEquip.setInt(getMaximumShortMaxIfOverflow(0, (nEquip.getInt() + chscrollRandomizedStat())));
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setInt(getMaximumShortMaxIfOverflow(nEquip.getInt(), (nEquip.getInt() + chscrollRandomizedStat(range))));
|
||||
else nEquip.setInt(getMaximumShortMaxIfOverflow(0, (nEquip.getInt() + chscrollRandomizedStat(range))));
|
||||
}
|
||||
if (nEquip.getLuk() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setLuk(getMaximumShortMaxIfOverflow(nEquip.getLuk(), (nEquip.getLuk() + chscrollRandomizedStat())));
|
||||
else nEquip.setLuk(getMaximumShortMaxIfOverflow(0, (nEquip.getLuk() + chscrollRandomizedStat())));
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setLuk(getMaximumShortMaxIfOverflow(nEquip.getLuk(), (nEquip.getLuk() + chscrollRandomizedStat(range))));
|
||||
else nEquip.setLuk(getMaximumShortMaxIfOverflow(0, (nEquip.getLuk() + chscrollRandomizedStat(range))));
|
||||
}
|
||||
if (nEquip.getWatk() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setWatk(getMaximumShortMaxIfOverflow(nEquip.getWatk(), (nEquip.getWatk() + chscrollRandomizedStat())));
|
||||
else nEquip.setWatk(getMaximumShortMaxIfOverflow(0, (nEquip.getWatk() + chscrollRandomizedStat())));
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setWatk(getMaximumShortMaxIfOverflow(nEquip.getWatk(), (nEquip.getWatk() + chscrollRandomizedStat(range))));
|
||||
else nEquip.setWatk(getMaximumShortMaxIfOverflow(0, (nEquip.getWatk() + chscrollRandomizedStat(range))));
|
||||
}
|
||||
if (nEquip.getWdef() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setWdef(getMaximumShortMaxIfOverflow(nEquip.getWdef(), (nEquip.getWdef() + chscrollRandomizedStat())));
|
||||
else nEquip.setWdef(getMaximumShortMaxIfOverflow(0, (nEquip.getWdef() + chscrollRandomizedStat())));
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setWdef(getMaximumShortMaxIfOverflow(nEquip.getWdef(), (nEquip.getWdef() + chscrollRandomizedStat(range))));
|
||||
else nEquip.setWdef(getMaximumShortMaxIfOverflow(0, (nEquip.getWdef() + chscrollRandomizedStat(range))));
|
||||
}
|
||||
if (nEquip.getMatk() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setMatk(getMaximumShortMaxIfOverflow(nEquip.getMatk(), (nEquip.getMatk() + chscrollRandomizedStat())));
|
||||
else nEquip.setMatk(getMaximumShortMaxIfOverflow(0, (nEquip.getMatk() + chscrollRandomizedStat())));
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setMatk(getMaximumShortMaxIfOverflow(nEquip.getMatk(), (nEquip.getMatk() + chscrollRandomizedStat(range))));
|
||||
else nEquip.setMatk(getMaximumShortMaxIfOverflow(0, (nEquip.getMatk() + chscrollRandomizedStat(range))));
|
||||
}
|
||||
if (nEquip.getMdef() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setMdef(getMaximumShortMaxIfOverflow(nEquip.getMdef(), (nEquip.getMdef() + chscrollRandomizedStat())));
|
||||
else nEquip.setMdef(getMaximumShortMaxIfOverflow(0, (nEquip.getMdef() + chscrollRandomizedStat())));
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setMdef(getMaximumShortMaxIfOverflow(nEquip.getMdef(), (nEquip.getMdef() + chscrollRandomizedStat(range))));
|
||||
else nEquip.setMdef(getMaximumShortMaxIfOverflow(0, (nEquip.getMdef() + chscrollRandomizedStat(range))));
|
||||
}
|
||||
if (nEquip.getAcc() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setAcc(getMaximumShortMaxIfOverflow(nEquip.getAcc(), (nEquip.getAcc() + chscrollRandomizedStat())));
|
||||
else nEquip.setAcc(getMaximumShortMaxIfOverflow(0, (nEquip.getAcc() + chscrollRandomizedStat())));
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setAcc(getMaximumShortMaxIfOverflow(nEquip.getAcc(), (nEquip.getAcc() + chscrollRandomizedStat(range))));
|
||||
else nEquip.setAcc(getMaximumShortMaxIfOverflow(0, (nEquip.getAcc() + chscrollRandomizedStat(range))));
|
||||
}
|
||||
if (nEquip.getAvoid() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setAvoid(getMaximumShortMaxIfOverflow(nEquip.getAvoid(), (nEquip.getAvoid() + chscrollRandomizedStat())));
|
||||
else nEquip.setAvoid(getMaximumShortMaxIfOverflow(0, (nEquip.getAvoid() + chscrollRandomizedStat())));
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setAvoid(getMaximumShortMaxIfOverflow(nEquip.getAvoid(), (nEquip.getAvoid() + chscrollRandomizedStat(range))));
|
||||
else nEquip.setAvoid(getMaximumShortMaxIfOverflow(0, (nEquip.getAvoid() + chscrollRandomizedStat(range))));
|
||||
}
|
||||
if (nEquip.getSpeed() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setSpeed(getMaximumShortMaxIfOverflow(nEquip.getSpeed(), (nEquip.getSpeed() + chscrollRandomizedStat())));
|
||||
else nEquip.setSpeed(getMaximumShortMaxIfOverflow(0, (nEquip.getSpeed() + chscrollRandomizedStat())));
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setSpeed(getMaximumShortMaxIfOverflow(nEquip.getSpeed(), (nEquip.getSpeed() + chscrollRandomizedStat(range))));
|
||||
else nEquip.setSpeed(getMaximumShortMaxIfOverflow(0, (nEquip.getSpeed() + chscrollRandomizedStat(range))));
|
||||
}
|
||||
if (nEquip.getJump() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setJump(getMaximumShortMaxIfOverflow(nEquip.getJump(), (nEquip.getJump() + chscrollRandomizedStat())));
|
||||
else nEquip.setJump(getMaximumShortMaxIfOverflow(0, (nEquip.getJump() + chscrollRandomizedStat())));
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setJump(getMaximumShortMaxIfOverflow(nEquip.getJump(), (nEquip.getJump() + chscrollRandomizedStat(range))));
|
||||
else nEquip.setJump(getMaximumShortMaxIfOverflow(0, (nEquip.getJump() + chscrollRandomizedStat(range))));
|
||||
}
|
||||
if (nEquip.getHp() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setHp(getMaximumShortMaxIfOverflow(nEquip.getHp(), (nEquip.getHp() + chscrollRandomizedStat())));
|
||||
else nEquip.setHp(getMaximumShortMaxIfOverflow(0, (nEquip.getHp() + chscrollRandomizedStat())));
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setHp(getMaximumShortMaxIfOverflow(nEquip.getHp(), (nEquip.getHp() + chscrollRandomizedStat(range))));
|
||||
else nEquip.setHp(getMaximumShortMaxIfOverflow(0, (nEquip.getHp() + chscrollRandomizedStat(range))));
|
||||
}
|
||||
if (nEquip.getMp() > 0) {
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setMp(getMaximumShortMaxIfOverflow(nEquip.getMp(), (nEquip.getMp() + chscrollRandomizedStat())));
|
||||
else nEquip.setMp(getMaximumShortMaxIfOverflow(0, (nEquip.getMp() + chscrollRandomizedStat())));
|
||||
if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setMp(getMaximumShortMaxIfOverflow(nEquip.getMp(), (nEquip.getMp() + chscrollRandomizedStat(range))));
|
||||
else nEquip.setMp(getMaximumShortMaxIfOverflow(0, (nEquip.getMp() + chscrollRandomizedStat(range))));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -831,58 +903,11 @@ public class MapleItemInformationProvider {
|
||||
case 2049100:
|
||||
case 2049101:
|
||||
case 2049102:
|
||||
scrollEquipWithChaos(nEquip);
|
||||
scrollEquipWithChaos(nEquip, ServerConstants.CHSCROLL_STAT_RANGE);
|
||||
break;
|
||||
|
||||
default:
|
||||
for (Entry<String, Integer> stat : stats.entrySet()) {
|
||||
switch (stat.getKey()) {
|
||||
case "STR":
|
||||
nEquip.setStr(getShortMaxIfOverflow(nEquip.getStr() + stat.getValue().intValue()));
|
||||
break;
|
||||
case "DEX":
|
||||
nEquip.setDex(getShortMaxIfOverflow(nEquip.getDex() + stat.getValue().intValue()));
|
||||
break;
|
||||
case "INT":
|
||||
nEquip.setInt(getShortMaxIfOverflow(nEquip.getInt() + stat.getValue().intValue()));
|
||||
break;
|
||||
case "LUK":
|
||||
nEquip.setLuk(getShortMaxIfOverflow(nEquip.getLuk() + stat.getValue().intValue()));
|
||||
break;
|
||||
case "PAD":
|
||||
nEquip.setWatk(getShortMaxIfOverflow(nEquip.getWatk() + stat.getValue().intValue()));
|
||||
break;
|
||||
case "PDD":
|
||||
nEquip.setWdef(getShortMaxIfOverflow(nEquip.getWdef() + stat.getValue().intValue()));
|
||||
break;
|
||||
case "MAD":
|
||||
nEquip.setMatk(getShortMaxIfOverflow(nEquip.getMatk() + stat.getValue().intValue()));
|
||||
break;
|
||||
case "MDD":
|
||||
nEquip.setMdef(getShortMaxIfOverflow(nEquip.getMdef() + stat.getValue().intValue()));
|
||||
break;
|
||||
case "ACC":
|
||||
nEquip.setAcc(getShortMaxIfOverflow(nEquip.getAcc() + stat.getValue().intValue()));
|
||||
break;
|
||||
case "EVA":
|
||||
nEquip.setAvoid(getShortMaxIfOverflow(nEquip.getAvoid() + stat.getValue().intValue()));
|
||||
break;
|
||||
case "Speed":
|
||||
nEquip.setSpeed(getShortMaxIfOverflow(nEquip.getSpeed() + stat.getValue().intValue()));
|
||||
break;
|
||||
case "Jump":
|
||||
nEquip.setJump(getShortMaxIfOverflow(nEquip.getJump() + stat.getValue().intValue()));
|
||||
break;
|
||||
case "MHP":
|
||||
nEquip.setHp(getShortMaxIfOverflow(nEquip.getHp() + stat.getValue().intValue()));
|
||||
break;
|
||||
case "MMP":
|
||||
nEquip.setMp(getShortMaxIfOverflow(nEquip.getMp() + stat.getValue().intValue()));
|
||||
break;
|
||||
case "afterImage":
|
||||
break;
|
||||
}
|
||||
}
|
||||
improveEquipStats(nEquip, stats);
|
||||
break;
|
||||
}
|
||||
if (!ItemConstants.isCleanSlate(scrollId)) {
|
||||
@@ -903,6 +928,57 @@ public class MapleItemInformationProvider {
|
||||
}
|
||||
return equip;
|
||||
}
|
||||
|
||||
public static void improveEquipStats(Equip nEquip, Map<String, Integer> stats) {
|
||||
for (Entry<String, Integer> stat : stats.entrySet()) {
|
||||
switch (stat.getKey()) {
|
||||
case "STR":
|
||||
nEquip.setStr(getShortMaxIfOverflow(nEquip.getStr() + stat.getValue().intValue()));
|
||||
break;
|
||||
case "DEX":
|
||||
nEquip.setDex(getShortMaxIfOverflow(nEquip.getDex() + stat.getValue().intValue()));
|
||||
break;
|
||||
case "INT":
|
||||
nEquip.setInt(getShortMaxIfOverflow(nEquip.getInt() + stat.getValue().intValue()));
|
||||
break;
|
||||
case "LUK":
|
||||
nEquip.setLuk(getShortMaxIfOverflow(nEquip.getLuk() + stat.getValue().intValue()));
|
||||
break;
|
||||
case "PAD":
|
||||
nEquip.setWatk(getShortMaxIfOverflow(nEquip.getWatk() + stat.getValue().intValue()));
|
||||
break;
|
||||
case "PDD":
|
||||
nEquip.setWdef(getShortMaxIfOverflow(nEquip.getWdef() + stat.getValue().intValue()));
|
||||
break;
|
||||
case "MAD":
|
||||
nEquip.setMatk(getShortMaxIfOverflow(nEquip.getMatk() + stat.getValue().intValue()));
|
||||
break;
|
||||
case "MDD":
|
||||
nEquip.setMdef(getShortMaxIfOverflow(nEquip.getMdef() + stat.getValue().intValue()));
|
||||
break;
|
||||
case "ACC":
|
||||
nEquip.setAcc(getShortMaxIfOverflow(nEquip.getAcc() + stat.getValue().intValue()));
|
||||
break;
|
||||
case "EVA":
|
||||
nEquip.setAvoid(getShortMaxIfOverflow(nEquip.getAvoid() + stat.getValue().intValue()));
|
||||
break;
|
||||
case "Speed":
|
||||
nEquip.setSpeed(getShortMaxIfOverflow(nEquip.getSpeed() + stat.getValue().intValue()));
|
||||
break;
|
||||
case "Jump":
|
||||
nEquip.setJump(getShortMaxIfOverflow(nEquip.getJump() + stat.getValue().intValue()));
|
||||
break;
|
||||
case "MHP":
|
||||
nEquip.setHp(getShortMaxIfOverflow(nEquip.getHp() + stat.getValue().intValue()));
|
||||
break;
|
||||
case "MMP":
|
||||
nEquip.setMp(getShortMaxIfOverflow(nEquip.getMp() + stat.getValue().intValue()));
|
||||
break;
|
||||
case "afterImage":
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Item getEquipById(int equipId) {
|
||||
return getEquipById(equipId, -1);
|
||||
@@ -986,6 +1062,31 @@ public class MapleItemInformationProvider {
|
||||
return equip;
|
||||
}
|
||||
|
||||
private static short getRandUpgradedStat(short defaultValue, int maxRange) {
|
||||
if (defaultValue == 0) {
|
||||
return 0;
|
||||
}
|
||||
int lMaxRange = maxRange;
|
||||
return (short) (defaultValue + Math.floor(Randomizer.nextDouble() * (lMaxRange + 1)));
|
||||
}
|
||||
|
||||
public Equip randomizeUpgradeStats(Equip equip) {
|
||||
equip.setStr(getRandUpgradedStat(equip.getStr(), 2));
|
||||
equip.setDex(getRandUpgradedStat(equip.getDex(), 2));
|
||||
equip.setInt(getRandUpgradedStat(equip.getInt(), 2));
|
||||
equip.setLuk(getRandUpgradedStat(equip.getLuk(), 2));
|
||||
equip.setMatk(getRandUpgradedStat(equip.getMatk(), 2));
|
||||
equip.setWatk(getRandUpgradedStat(equip.getWatk(), 2));
|
||||
equip.setAcc(getRandUpgradedStat(equip.getAcc(), 2));
|
||||
equip.setAvoid(getRandUpgradedStat(equip.getAvoid(), 2));
|
||||
equip.setJump(getRandUpgradedStat(equip.getJump(), 2));
|
||||
equip.setWdef(getRandUpgradedStat(equip.getWdef(), 5));
|
||||
equip.setMdef(getRandUpgradedStat(equip.getMdef(), 5));
|
||||
equip.setHp(getRandUpgradedStat(equip.getHp(), 5));
|
||||
equip.setMp(getRandUpgradedStat(equip.getMp(), 5));
|
||||
return equip;
|
||||
}
|
||||
|
||||
public MapleStatEffect getItemEffect(int itemId) {
|
||||
MapleStatEffect ret = itemEffects.get(Integer.valueOf(itemId));
|
||||
if (ret == null) {
|
||||
@@ -1503,6 +1604,212 @@ public class MapleItemInformationProvider {
|
||||
return list;
|
||||
}
|
||||
|
||||
private static int getCrystalForLevel(int level) {
|
||||
int range = (level - 1) / 10;
|
||||
|
||||
if(range < 5) {
|
||||
return 4260000;
|
||||
} else if(range > 11) {
|
||||
return 4260008;
|
||||
} else {
|
||||
switch(range) {
|
||||
case 5:
|
||||
return 4260001;
|
||||
|
||||
case 6:
|
||||
return 4260002;
|
||||
|
||||
case 7:
|
||||
return 4260003;
|
||||
|
||||
case 8:
|
||||
return 4260004;
|
||||
|
||||
case 9:
|
||||
return 4260005;
|
||||
|
||||
case 10:
|
||||
return 4260006;
|
||||
|
||||
default:
|
||||
return 4260007;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Pair<String, Integer> getMakerReagentStatUpgrade(int itemId) {
|
||||
try {
|
||||
Pair<String, Integer> statUpgd = statUpgradeMakerCache.get(itemId);
|
||||
if(statUpgd != null) {
|
||||
return statUpgd;
|
||||
} else if(statUpgradeMakerCache.containsKey(itemId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Connection con = DatabaseConnection.getConnection();
|
||||
PreparedStatement ps = con.prepareStatement("SELECT stat, value FROM makerreagentdata WHERE itemid = ?");
|
||||
ps.setInt(1, itemId);
|
||||
ResultSet rs = ps.executeQuery();
|
||||
if(rs.next()) {
|
||||
String statType = rs.getString("stat");
|
||||
int statGain = rs.getInt("value");
|
||||
|
||||
statUpgd = new Pair<>(statType, statGain);
|
||||
}
|
||||
rs.close();
|
||||
ps.close();
|
||||
con.close();
|
||||
|
||||
statUpgradeMakerCache.put(itemId, statUpgd);
|
||||
return statUpgd;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public int getMakerCrystalFromLeftover(Integer leftoverId) {
|
||||
try {
|
||||
Integer itemid = mobCrystalMakerCache.get(leftoverId);
|
||||
if(itemid != null) {
|
||||
return itemid;
|
||||
}
|
||||
|
||||
itemid = -1;
|
||||
|
||||
Connection con = DatabaseConnection.getConnection();
|
||||
PreparedStatement ps = con.prepareStatement("SELECT dropperid FROM drop_data WHERE itemid = ? ORDER BY dropperid;");
|
||||
ps.setInt(1, leftoverId);
|
||||
ResultSet rs = ps.executeQuery();
|
||||
if(rs.next()) {
|
||||
int dropperid = rs.getInt("dropperid");
|
||||
itemid = getCrystalForLevel(MapleLifeFactory.getMonsterLevel(dropperid) - 1);
|
||||
}
|
||||
rs.close();
|
||||
ps.close();
|
||||
con.close();
|
||||
|
||||
mobCrystalMakerCache.put(leftoverId, itemid);
|
||||
return itemid;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public MakerItemCreateEntry getMakerItemEntry(int toCreate) {
|
||||
MakerItemCreateEntry makerEntry;
|
||||
|
||||
if ((makerEntry = makerItemCache.get(toCreate)) != null) {
|
||||
return new MakerItemCreateEntry(makerEntry);
|
||||
} else {
|
||||
try {
|
||||
Connection con = DatabaseConnection.getConnection();
|
||||
PreparedStatement ps = con.prepareStatement("SELECT req_level, req_maker_level, req_meso, quantity FROM makercreatedata WHERE itemid = ?");
|
||||
ps.setInt(1, toCreate);
|
||||
ResultSet rs = ps.executeQuery();
|
||||
int reqLevel = 0;
|
||||
int reqMakerLevel = 0;
|
||||
int cost = 0;
|
||||
int toGive = 0;
|
||||
if (rs.next()) {
|
||||
reqLevel = rs.getInt("req_level");
|
||||
reqMakerLevel = rs.getInt("req_maker_level");
|
||||
cost = rs.getInt("req_meso");
|
||||
toGive = rs.getInt("quantity");
|
||||
}
|
||||
ps.close();
|
||||
rs.close();
|
||||
makerEntry = new MakerItemCreateEntry(cost, reqLevel, reqMakerLevel, toGive);
|
||||
ps = con.prepareStatement("SELECT req_item, count FROM makerrecipedata WHERE itemid = ?");
|
||||
ps.setInt(1, toCreate);
|
||||
rs = ps.executeQuery();
|
||||
while (rs.next()) {
|
||||
makerEntry.addReqItem(rs.getInt("req_item"), rs.getInt("count"));
|
||||
}
|
||||
rs.close();
|
||||
ps.close();
|
||||
con.close();
|
||||
makerItemCache.put(toCreate, new MakerItemCreateEntry(makerEntry));
|
||||
} catch (SQLException sqle) {
|
||||
sqle.printStackTrace();
|
||||
makerEntry = null;
|
||||
}
|
||||
}
|
||||
|
||||
return makerEntry;
|
||||
}
|
||||
|
||||
public int getMakerCrystalFromEquip(Integer equipId) {
|
||||
try {
|
||||
Map<String, Integer> stats = getEquipStats(equipId);
|
||||
return getCrystalForLevel(stats.get("reqLevel"));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int getMakerStimulantFromEquip(Integer equipId) {
|
||||
try {
|
||||
return getCrystalForLevel(getEquipStats(equipId).get("reqLevel"));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int getMakerDisassembledQuantity(Integer itemId) {
|
||||
int avail = 0;
|
||||
Connection con;
|
||||
try {
|
||||
con = DatabaseConnection.getConnection();
|
||||
PreparedStatement ps = con.prepareStatement("SELECT count FROM makerrecipedata WHERE itemid = ? AND req_item >= 4260000 AND req_item <= 4260008 ORDER BY count DESC");
|
||||
ps.setInt(1, itemId);
|
||||
ResultSet rs = ps.executeQuery();
|
||||
|
||||
if(rs.next()) {
|
||||
avail = (int) Math.ceil(rs.getInt("count") / 2); // return to the player half of the crystals needed
|
||||
}
|
||||
|
||||
rs.close();
|
||||
ps.close();
|
||||
con.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return avail;
|
||||
}
|
||||
|
||||
public int getMakerDisassembledFee(Integer itemId) {
|
||||
int fee = -1;
|
||||
Connection con;
|
||||
try {
|
||||
con = DatabaseConnection.getConnection();
|
||||
PreparedStatement ps = con.prepareStatement("SELECT req_meso FROM makercreatedata WHERE itemid = ?");
|
||||
ps.setInt(1, itemId);
|
||||
ResultSet rs = ps.executeQuery();
|
||||
|
||||
if(rs.next()) { // cost is 13.6363~ % of the original value trimmed by 1000.
|
||||
float val = (float) (rs.getInt("req_meso") * 0.13636363636364);
|
||||
fee = (int) (val / 1000);
|
||||
fee *= 1000;
|
||||
}
|
||||
|
||||
rs.close();
|
||||
ps.close();
|
||||
con.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return fee;
|
||||
}
|
||||
|
||||
public Set<String> getWhoDrops(Integer itemId) {
|
||||
Set<String> list = new HashSet<>();
|
||||
Connection con = null;
|
||||
|
||||
@@ -157,6 +157,27 @@ public class MapleLifeFactory {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getMonsterLevel(int mid) {
|
||||
try {
|
||||
MapleMonsterStats stats = monsterStats.get(Integer.valueOf(mid));
|
||||
if (stats == null) {
|
||||
MapleData monsterData = data.getData(StringUtil.getLeftPaddedStr(Integer.toString(mid) + ".img", '0', 11));
|
||||
if (monsterData == null) {
|
||||
return -1;
|
||||
}
|
||||
MapleData monsterInfoData = monsterData.getChildByPath("info");
|
||||
return MapleDataTool.getIntConvert("level", monsterInfoData);
|
||||
} else {
|
||||
return stats.getLevel();
|
||||
}
|
||||
} catch(NullPointerException npe) {
|
||||
System.out.println("[SEVERE] MOB " + mid + " failed to load. Issue: " + npe.getMessage() + "\n\n");
|
||||
npe.printStackTrace();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static void decodeElementalString(MapleMonsterStats stats, String elemAttr) {
|
||||
for (int i = 0; i < elemAttr.length(); i += 2) {
|
||||
|
||||
@@ -5887,14 +5887,23 @@ public class MaplePacketCreator {
|
||||
return mplew.getPacket();
|
||||
}
|
||||
|
||||
public static byte[] showMakerEffect() {
|
||||
public static byte[] showMakerEffect(boolean makerSucceeded) {
|
||||
final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
|
||||
mplew.writeShort(SendOpcode.SHOW_ITEM_GAIN_INCHAT.getValue());
|
||||
mplew.write(16);
|
||||
mplew.writeInt(0);
|
||||
mplew.writeInt(makerSucceeded ? 0 : 1);
|
||||
return mplew.getPacket();
|
||||
}
|
||||
|
||||
|
||||
public static byte[] showForeignMakerEffect(int cid, boolean makerSucceeded) {
|
||||
final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
|
||||
mplew.writeShort(SendOpcode.SHOW_FOREIGN_EFFECT.getValue());
|
||||
mplew.writeInt(cid);
|
||||
mplew.write(16);
|
||||
mplew.writeInt(makerSucceeded ? 0 : 1);
|
||||
return mplew.getPacket();
|
||||
}
|
||||
|
||||
public static byte[] showForeignEffect(int effect) {
|
||||
return showForeignEffect(-1, effect);
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ public enum MonitoredLockType {
|
||||
MAP_OBJS(37),
|
||||
MAP_FACTORY(38),
|
||||
MAP_ITEM(39),
|
||||
MAP_BOUNDS(41),
|
||||
MAP_BOUNDS(40),
|
||||
MINIDUNGEON(41),
|
||||
REACTOR(42);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user