Autoassigner update + Multi-equip drop

Fixed spawn effect not working properly after the HT spawn sequence patch.
Fixed autoassigner not distributing AP properly for brawlers.
More than one of the same equipment can now be dropped by mobs. Feature uses the minimum/maximum quantity fields from the drop data to determine how many of the same will be dropped each instance.
This commit is contained in:
ronancpl
2018-03-27 16:56:23 -03:00
parent 8b8ce3ca24
commit cd16117553
29 changed files with 230 additions and 162 deletions

View File

@@ -338,8 +338,8 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
petLootCd = System.currentTimeMillis();
}
public MapleJob getJobStyle() {
int jobtype = this.getJob().getId() / 100;
private static MapleJob getJobStyleInternal(int jobid, byte opt) {
int jobtype = jobid / 100;
if(jobtype == MapleJob.WARRIOR.getId() / 100 || jobtype == MapleJob.DAWNWARRIOR1.getId() / 100 || jobtype == MapleJob.ARAN1.getId() / 100) {
return(MapleJob.WARRIOR);
@@ -350,7 +350,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
}
else if(jobtype == MapleJob.BOWMAN.getId() / 100 || jobtype == MapleJob.WINDARCHER1.getId() / 100) {
if(this.getJob().getId() / 10 == MapleJob.CROSSBOWMAN.getId() / 10) return(MapleJob.CROSSBOWMAN);
if(jobid / 10 == MapleJob.CROSSBOWMAN.getId() / 10) return(MapleJob.CROSSBOWMAN);
else return(MapleJob.BOWMAN);
}
@@ -359,12 +359,20 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
}
else if(jobtype == MapleJob.PIRATE.getId() / 100 || jobtype == MapleJob.THUNDERBREAKER1.getId() / 100) {
if(this.getStr() > this.getDex()) return(MapleJob.BRAWLER);
if(opt == (byte) 0x80) return(MapleJob.BRAWLER);
else return(MapleJob.GUNSLINGER);
}
return(MapleJob.BEGINNER);
}
public MapleJob getJobStyle(byte opt) {
return getJobStyleInternal(this.getJob().getId(), opt);
}
public MapleJob getJobStyle() {
return getJobStyle((byte) ((this.getStr() > this.getDex()) ? 0x80 : 0x40));
}
public static MapleCharacter getDefault(MapleClient c) {
MapleCharacter ret = new MapleCharacter();
@@ -846,8 +854,8 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
getMap().broadcastMessage(this, MaplePacketCreator.removePlayerFromMap(getId()), false);
}
getMap().broadcastGMMessage(this, MaplePacketCreator.spawnPlayerMapObject(this), false);
List<Pair<MapleBuffStat, Integer>> dsstat = Collections.singletonList(new Pair<MapleBuffStat, Integer>(MapleBuffStat.DARKSIGHT, 0));
getMap().broadcastGMMessage(this, MaplePacketCreator.giveForeignBuff(id, dsstat), false);
List<Pair<MapleBuffStat, Integer>> ldsstat = Collections.singletonList(new Pair<MapleBuffStat, Integer>(MapleBuffStat.DARKSIGHT, 0));
getMap().broadcastGMMessage(this, MaplePacketCreator.giveForeignBuff(id, ldsstat), false);
for (MapleMonster mon : this.getControlledMonsters()) {
mon.setController(null);
mon.setControllerHasAggro(false);
@@ -1678,7 +1686,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
nextPendingRequest(client);
}
public static boolean deleteCharFromDB(MapleCharacter player) {
public static boolean deleteCharFromDB(MapleCharacter player, int senderAccId) {
int cid = player.getId(), accId = -1, world = 0;
Connection con = null;
@@ -1696,6 +1704,10 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
}
}
if(senderAccId != accId) {
return false;
}
try (PreparedStatement ps = con.prepareStatement("SELECT buddyid FROM buddies WHERE characterid = ?")) {
ps.setInt(1, cid);
@@ -2180,9 +2192,9 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
try {
long curTime = System.currentTimeMillis();
for(Entry<MapleDisease, Long> d : diseaseExpires.entrySet()) {
if(d.getValue() < curTime) {
toExpire.add(d.getKey());
for(Entry<MapleDisease, Long> de : diseaseExpires.entrySet()) {
if(de.getValue() < curTime) {
toExpire.add(de.getKey());
}
}
} finally {
@@ -2972,8 +2984,8 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
}
Map<Integer, Pair<MapleStatEffect, Long>> bestEffects = new LinkedHashMap<>();
for(Entry<MapleBuffStat, Pair<Integer, Integer>> lmse: maxStatups.entrySet()) {
Integer srcid = lmse.getValue().getLeft();
for(Entry<MapleBuffStat, Pair<Integer, Integer>> lmsee: maxStatups.entrySet()) {
Integer srcid = lmsee.getValue().getLeft();
if(!bestEffects.containsKey(srcid)) {
bestEffects.put(srcid, retrievedEffects.get(srcid));
}
@@ -3156,16 +3168,16 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
Map<MapleBuffStat, MapleBuffStatValueHolder> minStatBuffs = new LinkedHashMap<>();
for(Entry<Integer, Map<MapleBuffStat, MapleBuffStatValueHolder>> mbsvhi : buffEffects.entrySet()) {
for(Entry<MapleBuffStat, MapleBuffStatValueHolder> mbsvh : mbsvhi.getValue().entrySet()) {
MapleBuffStat mbs = mbsvh.getKey();
Byte it = stats.get(mbs);
for(Entry<MapleBuffStat, MapleBuffStatValueHolder> mbsvhe : mbsvhi.getValue().entrySet()) {
MapleBuffStat mbs = mbsvhe.getKey();
Byte b = stats.get(mbs);
if(it != null) {
stats.put(mbs, (byte) (it + 1));
if(mbsvh.getValue().value < minStatBuffs.get(mbs).value) minStatBuffs.put(mbs, mbsvh.getValue());
if(b != null) {
stats.put(mbs, (byte) (b + 1));
if(mbsvhe.getValue().value < minStatBuffs.get(mbs).value) minStatBuffs.put(mbs, mbsvhe.getValue());
} else {
stats.put(mbs, (byte) 1);
minStatBuffs.put(mbs, mbsvh.getValue());
minStatBuffs.put(mbs, mbsvhe.getValue());
}
}
}

View File

@@ -965,38 +965,9 @@ public class MapleClient {
return Server.getInstance().getChannel(world, channel);
}
private boolean hasCharacter(int cid) throws SQLException {
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
public boolean deleteCharacter(int cid, int senderAccId) {
try {
con = DatabaseConnection.getConnection();
ps = con.prepareStatement("SELECT id FROM characters WHERE accountid = ?");
ps.setInt(1, getAccID());
rs = ps.executeQuery();
while (rs.next()) {
if (rs.getInt("id") == cid) {
return true;
}
}
} finally {
if(rs != null && !rs.isClosed()) rs.close();
if(ps != null && !ps.isClosed()) ps.close();
if(con != null && !con.isClosed()) con.close();
}
return false;
}
public boolean deleteCharacter(int cid) {
try {
if(!hasCharacter(cid)) {
return false;
}
return MapleCharacter.deleteCharFromDB(MapleCharacter.loadCharFromDB(cid, this, false));
return MapleCharacter.deleteCharFromDB(MapleCharacter.loadCharFromDB(cid, this, false), senderAccId);
} catch(SQLException ex) {
ex.printStackTrace();
return false;

View File

@@ -1447,13 +1447,25 @@ public class Commands {
case "job":
if (sub.length == 2) {
player.changeJob(MapleJob.getById(Integer.parseInt(sub[1])));
int jobid = Integer.parseInt(sub[1]);
if(jobid < 0 || jobid >= 2200) {
player.message("Jobid " + jobid + " is not available.");
break;
}
player.changeJob(MapleJob.getById(jobid));
player.equipChanged();
} else if (sub.length == 3) {
victim = c.getChannelServer().getPlayerStorage().getCharacterByName(sub[1]);
if(victim != null) {
victim.changeJob(MapleJob.getById(Integer.parseInt(sub[2])));
int jobid = Integer.parseInt(sub[2]);
if(jobid < 0 || jobid >= 2200) {
player.message("Jobid " + jobid + " is not available.");
break;
}
victim.changeJob(MapleJob.getById(jobid));
player.equipChanged();
} else {
player.message("Player '" + sub[1] + "' could not be found on this channel.");
@@ -1581,9 +1593,9 @@ public class Commands {
MapleMap newMap = c.getChannelServer().getMapFactory().resetMap(player.getMapId());
int callerid = c.getPlayer().getId();
for (MapleCharacter ch : oldMap.getCharacters()) {
ch.changeMap(newMap);
if(ch.getId() != callerid) ch.dropMessage("You have been relocated due to map reloading. Sorry for the inconvenience.");
for (MapleCharacter chr : oldMap.getCharacters()) {
chr.changeMap(newMap);
if(chr.getId() != callerid) chr.dropMessage("You have been relocated due to map reloading. Sorry for the inconvenience.");
}
newMap.respawn();
break;

View File

@@ -340,7 +340,7 @@ public class Equip extends Item {
List<Pair<String, Integer>> elementalStats = MapleItemInformationProvider.getInstance().getItemLevelupStats(getItemId(), itemLevel);
for(Pair<String, Integer> p: elementalStats) {
if(p.getRight() > 0) stats.add(new Pair(StatUpgrade.valueOf(p.getLeft()), p.getRight()));
if(p.getRight() > 0) stats.add(new Pair<>(StatUpgrade.valueOf(p.getLeft()), p.getRight()));
}
}

View File

@@ -177,6 +177,6 @@ public final class ItemConstants {
}
public static boolean isEquipment(int itemId) {
return itemId < 2000000;
return itemId < 2000000 && itemId != 0;
}
}

View File

@@ -70,7 +70,8 @@ public class ServerConstants {
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).
public static final boolean USE_QUEST_RATE = false; //Exp/Meso gained by quests uses fixed server exp/meso rate times quest rate as multiplier, instead of player rates.
public static final boolean USE_QUEST_RATE = false; //Exp/Meso gained by quests uses fixed server exp/meso rate times quest rate as multiplier, instead of player rates.
public static final boolean USE_MULTIPLE_SAME_EQUIP_DROP = true;//Enables multiple drops by mobs of the same equipment, number of possible drops based on the quantities provided at the drop data.
//Server Rates And Experience
public static final int EXP_RATE = 10;

View File

@@ -289,8 +289,8 @@ public class Main {
BufferedWriter bw = new BufferedWriter(new FileWriter(f));
PrintWriter pw = new PrintWriter(bw);
for (Errors e : problems.values()) {
pw.write(e.createErrorLog());
for (Errors err : problems.values()) {
pw.write(err.createErrorLog());
}
pw.flush();

View File

@@ -66,11 +66,11 @@ public class ThreadTracker {
Map<MonitoredLockType, List<Integer>> lockValues = new HashMap<>();
Set<Long> executingThreads = new HashSet<>();
for(Map.Entry<Long, AtomicInteger> lock : lockCount.entrySet()) {
if(lock.getValue().get() != 0) {
executingThreads.add(lockThreads.get(lock.getKey()));
for(Map.Entry<Long, AtomicInteger> lc : lockCount.entrySet()) {
if(lc.getValue().get() != 0) {
executingThreads.add(lockThreads.get(lc.getKey()));
MonitoredLockType lockId = lockIds.get(lock.getKey());
MonitoredLockType lockId = lockIds.get(lc.getKey());
List<Integer> list = lockValues.get(lockId);
if(list == null) {
@@ -78,7 +78,7 @@ public class ThreadTracker {
lockValues.put(lockId, list);
}
list.add(lock.getValue().get());
list.add(lc.getValue().get());
}
}

View File

@@ -58,6 +58,8 @@ public class AutoAssignHandler extends AbstractMaplePacketHandler {
statGain[0] = 0; statGain[1] = 0; statGain[2] = 0; statGain[3] = 0;
slea.skip(8);
byte opt = slea.readByte(); // useful for pirate autoassigning
if (chr.getRemainingAp() < 1) return;
if(ServerConstants.USE_SERVER_AUTOASSIGNER) {
@@ -106,7 +108,7 @@ public class AutoAssignHandler extends AbstractMaplePacketHandler {
//c.getPlayer().message("SDL: s" + eqpStr + " d" + eqpDex + " l" + eqpLuk + " BASE STATS --> STR: " + chr.getStr() + " DEX: " + chr.getDex() + " INT: " + chr.getInt() + " LUK: " + chr.getLuk());
//c.getPlayer().message("SUM EQUIP STATS -> STR: " + str + " DEX: " + dex + " LUK: " + luk + " INT: " + int_);
MapleJob stance = c.getPlayer().getJobStyle();
MapleJob stance = c.getPlayer().getJobStyle(opt);
int prStat = 0, scStat = 0, trStat = 0, temp, tempAp = chr.getRemainingAp(), CAP;
MapleStat primary, secondary, tertiary = MapleStat.LUK;

View File

@@ -233,10 +233,10 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
// if (checkBirthday(c, birthday)) { //We're using a default birthday, so why restrict rings to only people who know of it?
int toCharge = slea.readInt();
int SN = slea.readInt();
String recipient = slea.readMapleAsciiString();
String recipientName = slea.readMapleAsciiString();
String text = slea.readMapleAsciiString();
CashItem ring = CashItemFactory.getItem(SN);
MapleCharacter partner = c.getChannelServer().getPlayerStorage().getCharacterByName(recipient);
CashItem itemRing = CashItemFactory.getItem(SN);
MapleCharacter partner = c.getChannelServer().getPlayerStorage().getCharacterByName(recipientName);
if (partner == null) {
chr.getClient().announce(MaplePacketCreator.serverNotice(1, "The partner you specified cannot be found.\r\nPlease make sure your partner is online and in the same channel."));
} else {
@@ -247,14 +247,14 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
return;
}*/ //Gotta let them faggots marry too, hence why this is commented out <3
if(ring.toItem() instanceof Equip) {
Equip item = (Equip) ring.toItem();
int ringid = MapleRing.createRing(ring.getItemId(), chr, partner);
item.setRingId(ringid);
cs.addToInventory(item);
c.announce(MaplePacketCreator.showBoughtCashItem(item, c.getAccID()));
cs.gift(partner.getId(), chr.getName(), text, item.getSN(), (ringid + 1));
cs.gainCash(toCharge, -ring.getPrice());
if(itemRing.toItem() instanceof Equip) {
Equip eqp = (Equip) itemRing.toItem();
int ringid = MapleRing.createRing(itemRing.getItemId(), chr, partner);
eqp.setRingId(ringid);
cs.addToInventory(eqp);
c.announce(MaplePacketCreator.showBoughtCashItem(eqp, c.getAccID()));
cs.gift(partner.getId(), chr.getName(), text, eqp.getSN(), (ringid + 1));
cs.gainCash(toCharge, -itemRing.getPrice());
chr.addCrushRing(MapleRing.loadFromDb(ringid));
try {
chr.sendNote(partner.getName(), text, (byte) 1);
@@ -286,7 +286,7 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
int payment = slea.readByte();
slea.skip(3); //0s
int snID = slea.readInt();
CashItem ring = CashItemFactory.getItem(snID);
CashItem itemRing = CashItemFactory.getItem(snID);
String sentTo = slea.readMapleAsciiString();
int available = slea.readShort() - 1;
String text = slea.readAsciiString(available);
@@ -296,14 +296,14 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
chr.dropMessage("The partner you specified cannot be found.\r\nPlease make sure your partner is online and in the same channel.");
} else {
// Need to check to make sure its actually an equip and the right SN...
if(ring.toItem() instanceof Equip) {
Equip item = (Equip) ring.toItem();
int ringid = MapleRing.createRing(ring.getItemId(), chr, partner);
item.setRingId(ringid);
cs.addToInventory(item);
c.announce(MaplePacketCreator.showBoughtCashItem(item, c.getAccID()));
cs.gift(partner.getId(), chr.getName(), text, item.getSN(), (ringid + 1));
cs.gainCash(payment, -ring.getPrice());
if(itemRing.toItem() instanceof Equip) {
Equip eqp = (Equip) itemRing.toItem();
int ringid = MapleRing.createRing(itemRing.getItemId(), chr, partner);
eqp.setRingId(ringid);
cs.addToInventory(eqp);
c.announce(MaplePacketCreator.showBoughtCashItem(eqp, c.getAccID()));
cs.gift(partner.getId(), chr.getName(), text, eqp.getSN(), (ringid + 1));
cs.gainCash(payment, -itemRing.getPrice());
chr.addFriendshipRing(MapleRing.loadFromDb(ringid));
try {
chr.sendNote(partner.getName(), text, (byte) 1);

View File

@@ -99,8 +99,8 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
if (quantity < 0 || price < 110 || c.getPlayer().getItemQuantity(itemid, false) < quantity) {
return;
}
MapleInventoryType type = ItemConstants.getInventoryType(itemid);
Item i = c.getPlayer().getInventory(type).getItem(slot).copy();
MapleInventoryType invType = ItemConstants.getInventoryType(itemid);
Item i = c.getPlayer().getInventory(invType).getItem(slot).copy();
if (i != null && c.getPlayer().getMeso() >= 5000) {
Connection con = null;
try {
@@ -160,7 +160,7 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
Item item = (Item) i;
ps = con.prepareStatement("INSERT INTO mts_items (tab, type, itemid, quantity, seller, price, owner, sellername, sell_ends) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
ps.setInt(1, 1);
ps.setInt(2, (int) type.getType());
ps.setInt(2, (int) invType.getType());
ps.setInt(3, item.getItemId());
ps.setInt(4, quantity);
ps.setInt(5, c.getPlayer().getId());
@@ -172,7 +172,7 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
Equip equip = (Equip) i;
ps = con.prepareStatement("INSERT INTO mts_items (tab, type, itemid, quantity, seller, price, upgradeslots, level, str, dex, `int`, luk, hp, mp, watk, matk, wdef, mdef, acc, avoid, hands, speed, jump, locked, owner, sellername, sell_ends, vicious, flag) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
ps.setInt(1, 1);
ps.setInt(2, (int) type.getType());
ps.setInt(2, (int) invType.getType());
ps.setInt(3, equip.getItemId());
ps.setInt(4, quantity);
ps.setInt(5, c.getPlayer().getId());
@@ -203,7 +203,7 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
}
ps.executeUpdate();
ps.close();
MapleInventoryManipulator.removeFromSlot(c, type, slot, quantity, false);
MapleInventoryManipulator.removeFromSlot(c, invType, slot, quantity, false);
con.close();
} catch (SQLException e) {

View File

@@ -106,11 +106,11 @@ public final class MakerSkillHandler extends AbstractMaplePacketHandler {
for(int i = 0; i < reagents; i++) { // crystals
int reagentid = slea.readInt();
if(ItemConstants.isMakerReagent(reagentid)) {
Short r = reagentids.get(reagentid);
if(r == null) {
Short rs = reagentids.get(reagentid);
if(rs == null) {
reagentids.put(reagentid, (short) 1);
} else {
reagentids.put(reagentid, (short) (r + 1));
reagentids.put(reagentid, (short) (rs + 1));
}
}
}
@@ -126,11 +126,11 @@ public final class MakerSkillHandler extends AbstractMaplePacketHandler {
// 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());
for(Pair<Integer, Short> rp : toUpdate) {
if(rp.getRight() > 0) {
reagentids.put(rp.getLeft(), rp.getRight());
} else {
reagentids.remove(r.getLeft());
reagentids.remove(rp.getLeft());
}
}
}
@@ -453,12 +453,12 @@ public final class MakerSkillHandler extends AbstractMaplePacketHandler {
ii.improveEquipStats(eqp, stats);
for(Short s : randStat) {
ii.scrollOptionEquipWithChaos(eqp, s, false);
for(Short sh : randStat) {
ii.scrollOptionEquipWithChaos(eqp, sh, false);
}
for(Short s : randOption) {
ii.scrollOptionEquipWithChaos(eqp, s, true);
for(Short sh : randOption) {
ii.scrollOptionEquipWithChaos(eqp, sh, true);
}
}

View File

@@ -407,10 +407,10 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
} else if (mode == Action.CONFIRM.getCode()) {
MapleTrade.completeTrade(c.getPlayer());
} else if (mode == Action.ADD_ITEM.getCode() || mode == Action.PUT_ITEM.getCode()) {
MapleInventoryType type = MapleInventoryType.getByType(slea.readByte());
MapleInventoryType ivType = MapleInventoryType.getByType(slea.readByte());
short slot = slea.readShort();
short bundles = slea.readShort();
if (chr.getInventory(type).getItem(slot) == null || chr.getItemQuantity(chr.getInventory(type).getItem(slot).getItemId(), false) < bundles || chr.getInventory(type).getItem(slot).getFlag() == ItemConstants.UNTRADEABLE) {
if (chr.getInventory(ivType).getItem(slot) == null || chr.getItemQuantity(chr.getInventory(ivType).getItem(slot).getItemId(), false) < bundles || chr.getInventory(ivType).getItem(slot).getFlag() == ItemConstants.UNTRADEABLE) {
return;
}
short perBundle = slea.readShort();
@@ -420,7 +420,7 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
FilePrinter.printError(FilePrinter.EXPLOITS + c.getPlayer().getName() + ".txt", c.getPlayer().getName() + " might of possibly packet edited Hired Merchants\nperBundle: " + perBundle + "\nperBundle * bundles (This multiplied cannot be greater than 2000): " + perBundle * bundles + "\nbundles: " + bundles + "\nprice: " + price);
return;
}
Item ivItem = chr.getInventory(type).getItem(slot);
Item ivItem = chr.getInventory(ivType).getItem(slot);
Item sellItem = ivItem.copy();
if (chr.getItemQuantity(ivItem.getItemId(), false) < perBundle * bundles) {
return;
@@ -429,22 +429,22 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
return;
}
sellItem.setQuantity(perBundle);
MaplePlayerShopItem item = new MaplePlayerShopItem(sellItem, bundles, price);
MaplePlayerShopItem shopItem = new MaplePlayerShopItem(sellItem, bundles, price);
MaplePlayerShop shop = chr.getPlayerShop();
MapleHiredMerchant merchant = chr.getHiredMerchant();
if (shop != null && shop.isOwner(c.getPlayer())) {
if (ivItem != null && ivItem.getQuantity() >= bundles * perBundle) {
shop.addItem(item);
shop.addItem(shopItem);
c.announce(MaplePacketCreator.getPlayerShopItemUpdate(shop));
}
} else if (merchant != null && merchant.isOwner(c.getPlayer())) {
merchant.addItem(item);
merchant.addItem(shopItem);
c.announce(MaplePacketCreator.updateHiredMerchant(merchant, c.getPlayer()));
}
if (ItemConstants.isRechargable(ivItem.getItemId())) {
MapleInventoryManipulator.removeFromSlot(c, type, slot, ivItem.getQuantity(), true);
MapleInventoryManipulator.removeFromSlot(c, ivType, slot, ivItem.getQuantity(), true);
} else {
MapleInventoryManipulator.removeFromSlot(c, type, slot, (short) (bundles * perBundle), true);
MapleInventoryManipulator.removeFromSlot(c, ivType, slot, (short) (bundles * perBundle), true);
}
} else if (mode == Action.REMOVE_ITEM.getCode()) {
MaplePlayerShop shop = chr.getPlayerShop();
@@ -456,10 +456,10 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
c.disconnect(true, false);
return;
}
MaplePlayerShopItem item = shop.getItems().get(slot);
Item ivItem = item.getItem().copy();
MaplePlayerShopItem shopItem = shop.getItems().get(slot);
Item ivItem = shopItem.getItem().copy();
shop.removeItem(slot);
ivItem.setQuantity(item.getBundles());
ivItem.setQuantity(shopItem.getBundles());
MapleInventoryManipulator.addFromDrop(c, ivItem, false);
c.announce(MaplePacketCreator.getPlayerShopItemUpdate(shop));
}
@@ -505,35 +505,35 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
c.announce(MaplePacketCreator.updateHiredMerchant(merchant, chr));
} else if (mode == Action.BUY.getCode() || mode == Action.MERCHANT_BUY.getCode()) {
int item = slea.readByte();
int itemid = slea.readByte();
short quantity = slea.readShort();
if (quantity < 1) {
AutobanFactory.PACKET_EDIT.alert(c.getPlayer(), c.getPlayer().getName() + " tried to packet edit with a hired merchant and or player shop.");
FilePrinter.printError(FilePrinter.EXPLOITS + c.getPlayer().getName() + ".txt", c.getPlayer().getName() + " tried to buy item " + item + " with quantity " + quantity + "\r\n");
FilePrinter.printError(FilePrinter.EXPLOITS + c.getPlayer().getName() + ".txt", c.getPlayer().getName() + " tried to buy item " + itemid + " with quantity " + quantity + "\r\n");
c.disconnect(true, false);
return;
}
MaplePlayerShop shop = chr.getPlayerShop();
MapleHiredMerchant merchant = chr.getHiredMerchant();
if (shop != null && shop.isVisitor(c.getPlayer())) {
shop.buy(c, item, quantity);
shop.buy(c, itemid, quantity);
shop.broadcast(MaplePacketCreator.getPlayerShopItemUpdate(shop));
} else if (merchant != null && !merchant.isOwner(chr)) {
merchant.buy(c, item, quantity);
merchant.buy(c, itemid, quantity);
merchant.broadcastToVisitorsThreadsafe(MaplePacketCreator.updateHiredMerchant(merchant, c.getPlayer()));
}
} else if (mode == Action.TAKE_ITEM_BACK.getCode()) {
MapleHiredMerchant merchant = chr.getHiredMerchant();
if (merchant != null && merchant.isOwner(c.getPlayer())) {
int slot = slea.readShort();
MaplePlayerShopItem item = merchant.getItems().get(slot);
if (!MapleInventory.checkSpot(chr, item.getItem())) {
MaplePlayerShopItem shopItem = merchant.getItems().get(slot);
if (!MapleInventory.checkSpot(chr, shopItem.getItem())) {
c.announce(MaplePacketCreator.enableActions());
return;
}
if (item.getBundles() > 0) {
Item iitem = item.getItem();
iitem.setQuantity((short) (item.getItem().getQuantity() * item.getBundles()));
if (shopItem.getBundles() > 0) {
Item iitem = shopItem.getItem();
iitem.setQuantity((short) (shopItem.getItem().getQuantity() * shopItem.getBundles()));
MapleInventoryManipulator.addFromDrop(c, iitem, true);
}
merchant.removeFromSlot(slot);

View File

@@ -114,14 +114,14 @@ public final class StorageHandler extends AbstractMaplePacketHandler {
if (chr.getMeso() < meso) {
c.announce(MaplePacketCreator.getStorageError((byte) 0x0B));
} else {
MapleInventoryType type = ItemConstants.getInventoryType(itemId);
Item item = chr.getInventory(type).getItem(slot).copy();
MapleInventoryType invType = ItemConstants.getInventoryType(itemId);
Item item = chr.getInventory(invType).getItem(slot).copy();
if (item.getItemId() == itemId && (item.getQuantity() >= quantity || ItemConstants.isRechargable(itemId))) {
if (ItemConstants.isRechargable(itemId)) {
quantity = item.getQuantity();
}
chr.gainMeso(meso, false, true, false);
MapleInventoryManipulator.removeFromSlot(c, type, slot, quantity, false);
MapleInventoryManipulator.removeFromSlot(c, invType, slot, quantity, false);
item.setQuantity(quantity);
storage.store(item);
storage.sendStored(c, ItemConstants.getInventoryType(itemId));

View File

@@ -144,9 +144,9 @@ public final class TakeDamageHandler extends AbstractMaplePacketHandler {
is_deadly = true;
}
mpattack += attackInfo.getMpBurn();
MobSkill skill = MobSkillFactory.getMobSkill(attackInfo.getDiseaseSkill(), attackInfo.getDiseaseLevel());
if (skill != null && damage > 0) {
skill.applyEffect(chr, attacker, false, banishPlayers);
MobSkill mobSkill = MobSkillFactory.getMobSkill(attackInfo.getDiseaseSkill(), attackInfo.getDiseaseLevel());
if (mobSkill != null && damage > 0) {
mobSkill.applyEffect(chr, attacker, false, banishPlayers);
}
attacker.setMp(attacker.getMp() - attackInfo.getMpCon());

View File

@@ -489,13 +489,13 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
player.getMap().broadcastMessage(MaplePacketCreator.useChalkboard(player, false));
player.getClient().announce(MaplePacketCreator.enableActions());
} else if (itemType == 539) {
List<String> lines = new LinkedList<>();
List<String> strLines = new LinkedList<>();
for (int i = 0; i < 4; i++) {
lines.add(slea.readMapleAsciiString());
strLines.add(slea.readMapleAsciiString());
}
final int world = c.getWorld();
Server.getInstance().broadcastMessage(world, MaplePacketCreator.getAvatarMega(c.getPlayer(), medal, c.getChannel(), itemId, lines, (slea.readByte() != 0)));
Server.getInstance().broadcastMessage(world, MaplePacketCreator.getAvatarMega(c.getPlayer(), medal, c.getChannel(), itemId, strLines, (slea.readByte() != 0)));
TimerManager.getInstance().schedule(new Runnable() {
@Override
public void run() {

View File

@@ -136,8 +136,8 @@ public class MapleGuild {
if (!mgc.isOnline()) {
continue;
}
List<Integer> ch = notifications.get(mgc.getChannel());
if (ch != null) ch.add(mgc.getId());
List<Integer> chl = notifications.get(mgc.getChannel());
if (chl != null) chl.add(mgc.getId());
//Unable to connect to Channel... error was here
}
} finally {

View File

@@ -34,7 +34,7 @@ public final class DeleteCharHandler extends AbstractMaplePacketHandler {
String pic = slea.readMapleAsciiString();
int cid = slea.readInt();
if (c.checkPic(pic)) {
if(c.deleteCharacter(cid)) {
if(c.deleteCharacter(cid, c.getAccID())) {
FilePrinter.printError(FilePrinter.DELETED_CHARACTERS + c.getAccountName() + ".txt", c.getAccountName() + " deleted CID: " + cid + "\r\n");
c.announce(MaplePacketCreator.deleteCharResponse(cid, 0));
} else {

View File

@@ -194,7 +194,7 @@ public class MapleTrade {
private boolean fitsInInventory() {
List<Pair<Item, MapleInventoryType>> tradeItems = new LinkedList<>();
for (Item item : exchangeItems) {
tradeItems.add(new Pair(item, item.getInventoryType()));
tradeItems.add(new Pair<>(item, item.getInventoryType()));
}
return MapleInventory.checkSpotsAndOwnership(chr, tradeItems);

View File

@@ -869,12 +869,12 @@ public class MapleMonster extends AbstractLoadedMapleLife {
} else if (venom) {
if (from.getJob() == MapleJob.NIGHTLORD || from.getJob() == MapleJob.SHADOWER || from.getJob().isA(MapleJob.NIGHTWALKER3)) {
int poisonLevel, matk, jobid = from.getJob().getId();
int skill = (jobid == 412 ? NightLord.VENOMOUS_STAR : (jobid == 422 ? Shadower.VENOMOUS_STAB : NightWalker.VENOM));
poisonLevel = from.getSkillLevel(SkillFactory.getSkill(skill));
int skillid = (jobid == 412 ? NightLord.VENOMOUS_STAR : (jobid == 422 ? Shadower.VENOMOUS_STAB : NightWalker.VENOM));
poisonLevel = from.getSkillLevel(SkillFactory.getSkill(skillid));
if (poisonLevel <= 0) {
return false;
}
matk = SkillFactory.getSkill(skill).getEffect(poisonLevel).getMatk();
matk = SkillFactory.getSkill(skillid).getEffect(poisonLevel).getMatk();
int luk = from.getLuk();
int maxDmg = (int) Math.ceil(Math.min(Short.MAX_VALUE, 0.2 * luk * matk));
int minDmg = (int) Math.ceil(Math.min(Short.MAX_VALUE, 0.1 * luk * matk));

View File

@@ -20,6 +20,8 @@
*/
package server.life;
import constants.ItemConstants;
import constants.ServerConstants;
import java.io.File;
import java.sql.Connection;
import java.sql.PreparedStatement;
@@ -27,9 +29,11 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import provider.MapleData;
import provider.MapleDataProvider;
import provider.MapleDataProviderFactory;
@@ -37,15 +41,18 @@ import provider.MapleDataTool;
import server.MapleItemInformationProvider;
import tools.DatabaseConnection;
import tools.Pair;
import tools.Randomizer;
public class MapleMonsterInformationProvider {
// Author : LightPepsi
private static final MapleMonsterInformationProvider instance = new MapleMonsterInformationProvider();
private final Map<Integer, List<MonsterDropEntry>> drops = new HashMap<>();
private final Map<Integer, List<MonsterDropEntry>> drops = new HashMap<>();
private final List<MonsterGlobalDropEntry> globaldrops = new ArrayList<>();
private final Map<Integer, List<Integer>> dropsChancePool = new HashMap<>(); // thanks to ronan
private final Set<Integer> hasNoMultiEquipDrops = new HashSet<>();
private final Map<Integer, List<MonsterDropEntry>> extraMultiEquipDrops = new HashMap<>();
protected MapleMonsterInformationProvider() {
retrieveGlobal();
@@ -103,6 +110,46 @@ public class MapleMonsterInformationProvider {
}
}
public List<MonsterDropEntry> retrieveEffectiveDrop(final int monsterId) {
// this reads the drop entries searching for multi-equip, properly processing them
List<MonsterDropEntry> list = retrieveDrop(monsterId);
if (hasNoMultiEquipDrops.contains(monsterId) || !ServerConstants.USE_MULTIPLE_SAME_EQUIP_DROP) {
return list;
}
List<MonsterDropEntry> multiDrops = extraMultiEquipDrops.get(monsterId), extra = new LinkedList<>();
if(multiDrops == null) {
multiDrops = new LinkedList<>();
for(MonsterDropEntry mde : list) {
if(ItemConstants.isEquipment(mde.itemId) && mde.Maximum > 1) {
multiDrops.add(mde);
int rnd = Randomizer.rand(mde.Minimum, mde.Maximum);
for(int i = 0; i < rnd - 1; i++) {
extra.add(mde); // this passes copies of the equips' MDE with min/max quantity > 1, but idc it'll be unused anyways
}
}
}
if(!multiDrops.isEmpty()) extraMultiEquipDrops.put(monsterId, multiDrops);
else hasNoMultiEquipDrops.add(monsterId);
} else {
for(MonsterDropEntry mde : multiDrops) {
int rnd = Randomizer.rand(mde.Minimum, mde.Maximum);
for(int i = 0; i < rnd - 1; i++) {
extra.add(mde);
}
}
}
List<MonsterDropEntry> ret = new LinkedList<>(list);
ret.addAll(extra);
return ret;
}
public final List<MonsterDropEntry> retrieveDrop(final int monsterId) {
if (drops.containsKey(monsterId)) {
return drops.get(monsterId);
@@ -234,6 +281,8 @@ public class MapleMonsterInformationProvider {
public final void clearDrops() {
drops.clear();
hasNoMultiEquipDrops.clear();
extraMultiEquipDrops.clear();
dropsChancePool.clear();
globaldrops.clear();
retrieveGlobal();

View File

@@ -559,7 +559,7 @@ public class MapleMap {
}
distn = Math.sqrt(distn);
return new Pair(getRoundedCoordinate(angle), Integer.valueOf((int)distn));
return new Pair<>(getRoundedCoordinate(angle), Integer.valueOf((int)distn));
}
private static void sortDropEntries(List<MonsterDropEntry> from, List<MonsterDropEntry> item, List<MonsterDropEntry> quest) {
@@ -667,7 +667,7 @@ public class MapleMap {
final List<MonsterDropEntry> dropEntry = new ArrayList<>();
final List<MonsterDropEntry> questEntry = new ArrayList<>();
sortDropEntries(mi.retrieveDrop(mob.getId()), dropEntry, questEntry);
sortDropEntries(mi.retrieveEffectiveDrop(mob.getId()), dropEntry, questEntry);
// Normal Drops
d = dropItemsFromMonsterOnMap(dropEntry, pos, d, chRate, droptype, mobpos, chr, mob);
@@ -1347,9 +1347,9 @@ public class MapleMap {
objectRLock.lock();
try {
for (Object obj : list) {
if(obj instanceof MapleMapObject) {
MapleMapObject mmo = (MapleMapObject) obj;
for (Object ob : list) {
if(ob instanceof MapleMapObject) {
MapleMapObject mmo = (MapleMapObject) ob;
if(mapobjects.containsValue(mmo) && mmo.getType() == MapleMapObjectType.REACTOR) {
listObjects.add(mmo);

View File

@@ -272,9 +272,9 @@ public class MapleMapFactory {
try {
for (MapleData layer : mapData.getChildByPath("back")) { // yolo
int layerNum = Integer.parseInt(layer.getName());
int type = MapleDataTool.getInt(layer.getChildByPath("type"), 0);
int btype = MapleDataTool.getInt(layer.getChildByPath("type"), 0);
backTypes.put(layerNum, type);
backTypes.put(layerNum, btype);
}
} catch (Exception e) {
e.printStackTrace();

View File

@@ -71,12 +71,14 @@ public class MapleMist extends AbstractMapleMapObject {
this.isRecoveryMist = false;
this.isPoisonMist = false;
switch (source.getSourceId()) {
case Evan.RECOVERY_AURA:
isRecoveryMist = true;
break;
case Evan.RECOVERY_AURA:
isRecoveryMist = true;
break;
case Shadower.SMOKE_SCREEN: // Smoke Screen
isPoisonMist = false;
break;
case FPMage.POISON_MIST: // FP mist
case BlazeWizard.FLAME_GEAR: // Flame Gear
case NightWalker.POISON_BOMB: // Poison Bomb

View File

@@ -131,26 +131,26 @@ public class ItemAction extends MapleQuestAction {
// must take all needed items before giving others
for(Pair<Integer, Integer> iEntry: takeItem) {
MapleInventoryType type = ItemConstants.getInventoryType(iEntry.getLeft());
int quantity = iEntry.getRight() * -1; // Invert
for(Pair<Integer, Integer> iPair: takeItem) {
MapleInventoryType type = ItemConstants.getInventoryType(iPair.getLeft());
int quantity = iPair.getRight() * -1; // Invert
if(type.equals(MapleInventoryType.EQUIP)) {
if(chr.getInventory(type).countById(iEntry.getLeft()) < quantity) {
if(chr.getInventory(type).countById(iPair.getLeft()) < quantity) {
// Not enough in the equip inventoty, so check Equipped...
if(chr.getInventory(MapleInventoryType.EQUIPPED).countById(iEntry.getLeft()) > quantity) {
if(chr.getInventory(MapleInventoryType.EQUIPPED).countById(iPair.getLeft()) > quantity) {
// Found it equipped, so change the type to equipped.
type = MapleInventoryType.EQUIPPED;
}
}
}
MapleInventoryManipulator.removeById(chr.getClient(), type, iEntry.getLeft(), quantity, true, false);
chr.announce(MaplePacketCreator.getShowItemGain(iEntry.getLeft(), (short) iEntry.getRight().shortValue(), true));
MapleInventoryManipulator.removeById(chr.getClient(), type, iPair.getLeft(), quantity, true, false);
chr.announce(MaplePacketCreator.getShowItemGain(iPair.getLeft(), (short) iPair.getRight().shortValue(), true));
}
for(Pair<Integer, Integer> iEntry: giveItem) {
MapleInventoryManipulator.addById(chr.getClient(), iEntry.getLeft(), (short) iEntry.getRight().shortValue());
chr.announce(MaplePacketCreator.getShowItemGain(iEntry.getLeft(), (short) iEntry.getRight().shortValue(), true));
for(Pair<Integer, Integer> iPair: giveItem) {
MapleInventoryManipulator.addById(chr.getClient(), iPair.getLeft(), (short) iPair.getRight().shortValue());
chr.announce(MaplePacketCreator.getShowItemGain(iPair.getLeft(), (short) iPair.getRight().shortValue(), true));
}
}

View File

@@ -1394,6 +1394,18 @@ public class MaplePacketCreator {
return spawnMonsterInternal(life, true, false, false, 0, true);
}
private static void encodeParentlessMobSpawnEffect(MaplePacketLittleEndianWriter mplew, boolean newSpawn, int effect) {
if (effect > 0) {
mplew.write(effect);
mplew.write(0);
mplew.writeShort(0);
if (effect == 15) {
mplew.write(0);
}
}
mplew.write(newSpawn ? -2 : -1);
}
/**
* Internal function to handler monster spawning and controlling.
*
@@ -1455,10 +1467,10 @@ public class MaplePacketCreator {
mplew.write(effect != 0 ? effect : -3);
mplew.writeInt(life.getParentMobOid());
} else {
mplew.write(newSpawn ? -2 : -1);
encodeParentlessMobSpawnEffect(mplew, newSpawn, effect);
}
} else {
mplew.write(newSpawn ? -2 : -1);
encodeParentlessMobSpawnEffect(mplew, newSpawn, effect);
}
mplew.write(life.getTeam());