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
+1
View File
@@ -69,6 +69,7 @@ Monsters, Maps & Reactors:
* Added meso drop data for basically every missing overworld mob. * Added meso drop data for basically every missing overworld mob.
* Monsterbook displays drop data info conformant with the underlying DB (needs custom wz). See more on the MobBookUpdate feature. * Monsterbook displays drop data info conformant with the underlying DB (needs custom wz). See more on the MobBookUpdate feature.
* Every skill/mastery book is now droppable by mobs. * Every skill/mastery book is now droppable by mobs.
* Mobs now can drop more than one of the same equipment (number of possible drops defined at droptime, uses the minimum/maximum quantity fields on DB).
* Added Boss HP Bar for dozens of bosses (needs provided custom wz). * Added Boss HP Bar for dozens of bosses (needs provided custom wz).
* If multiple bosses are on the same area, client will prioritize Boss HP bar of the target of the player. * If multiple bosses are on the same area, client will prioritize Boss HP bar of the target of the player.
* Boats, elevator and other travelling mechanics fully working. * Boats, elevator and other travelling mechanics fully working.
+5
View File
@@ -835,3 +835,8 @@ Modificado "hint" banners para usar menor espaço visual.
Resolvido problema com HP threshold em MoveLifeHandler. Resolvido problema com HP threshold em MoveLifeHandler.
Aprimorado quests e eventos de bosses da região de Mushroom Castle, agora sendo repetíveis. Aprimorado quests e eventos de bosses da região de Mushroom Castle, agora sendo repetíveis.
Corrigido tempo de duração do Body Pressure sendo resetado sempre que acerta um mob. Corrigido tempo de duração do Body Pressure sendo resetado sempre que acerta um mob.
26 - 27 Março 2018,
Corrigido animação de spawn dos bosses do dojo que foi quebrada recentemente.
Corrigido autoassigner para piratas somente preenchendo requisitos de gunslinger.
Mobs agora podem dropar mais de um equip de mesmo tipo, sistema utiliza quantidades min/max na tabela de drops.
+31 -19
View File
@@ -338,8 +338,8 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
petLootCd = System.currentTimeMillis(); petLootCd = System.currentTimeMillis();
} }
public MapleJob getJobStyle() { private static MapleJob getJobStyleInternal(int jobid, byte opt) {
int jobtype = this.getJob().getId() / 100; int jobtype = jobid / 100;
if(jobtype == MapleJob.WARRIOR.getId() / 100 || jobtype == MapleJob.DAWNWARRIOR1.getId() / 100 || jobtype == MapleJob.ARAN1.getId() / 100) { if(jobtype == MapleJob.WARRIOR.getId() / 100 || jobtype == MapleJob.DAWNWARRIOR1.getId() / 100 || jobtype == MapleJob.ARAN1.getId() / 100) {
return(MapleJob.WARRIOR); return(MapleJob.WARRIOR);
@@ -350,7 +350,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
} }
else if(jobtype == MapleJob.BOWMAN.getId() / 100 || jobtype == MapleJob.WINDARCHER1.getId() / 100) { 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); else return(MapleJob.BOWMAN);
} }
@@ -359,13 +359,21 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
} }
else if(jobtype == MapleJob.PIRATE.getId() / 100 || jobtype == MapleJob.THUNDERBREAKER1.getId() / 100) { 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); else return(MapleJob.GUNSLINGER);
} }
return(MapleJob.BEGINNER); 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) { public static MapleCharacter getDefault(MapleClient c) {
MapleCharacter ret = new MapleCharacter(); MapleCharacter ret = new MapleCharacter();
ret.client = c; ret.client = c;
@@ -846,8 +854,8 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
getMap().broadcastMessage(this, MaplePacketCreator.removePlayerFromMap(getId()), false); getMap().broadcastMessage(this, MaplePacketCreator.removePlayerFromMap(getId()), false);
} }
getMap().broadcastGMMessage(this, MaplePacketCreator.spawnPlayerMapObject(this), false); getMap().broadcastGMMessage(this, MaplePacketCreator.spawnPlayerMapObject(this), false);
List<Pair<MapleBuffStat, Integer>> dsstat = Collections.singletonList(new Pair<MapleBuffStat, Integer>(MapleBuffStat.DARKSIGHT, 0)); List<Pair<MapleBuffStat, Integer>> ldsstat = Collections.singletonList(new Pair<MapleBuffStat, Integer>(MapleBuffStat.DARKSIGHT, 0));
getMap().broadcastGMMessage(this, MaplePacketCreator.giveForeignBuff(id, dsstat), false); getMap().broadcastGMMessage(this, MaplePacketCreator.giveForeignBuff(id, ldsstat), false);
for (MapleMonster mon : this.getControlledMonsters()) { for (MapleMonster mon : this.getControlledMonsters()) {
mon.setController(null); mon.setController(null);
mon.setControllerHasAggro(false); mon.setControllerHasAggro(false);
@@ -1678,7 +1686,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
nextPendingRequest(client); nextPendingRequest(client);
} }
public static boolean deleteCharFromDB(MapleCharacter player) { public static boolean deleteCharFromDB(MapleCharacter player, int senderAccId) {
int cid = player.getId(), accId = -1, world = 0; int cid = player.getId(), accId = -1, world = 0;
Connection con = null; 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 = ?")) { try (PreparedStatement ps = con.prepareStatement("SELECT buddyid FROM buddies WHERE characterid = ?")) {
ps.setInt(1, cid); ps.setInt(1, cid);
@@ -2180,9 +2192,9 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
try { try {
long curTime = System.currentTimeMillis(); long curTime = System.currentTimeMillis();
for(Entry<MapleDisease, Long> d : diseaseExpires.entrySet()) { for(Entry<MapleDisease, Long> de : diseaseExpires.entrySet()) {
if(d.getValue() < curTime) { if(de.getValue() < curTime) {
toExpire.add(d.getKey()); toExpire.add(de.getKey());
} }
} }
} finally { } finally {
@@ -2972,8 +2984,8 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
} }
Map<Integer, Pair<MapleStatEffect, Long>> bestEffects = new LinkedHashMap<>(); Map<Integer, Pair<MapleStatEffect, Long>> bestEffects = new LinkedHashMap<>();
for(Entry<MapleBuffStat, Pair<Integer, Integer>> lmse: maxStatups.entrySet()) { for(Entry<MapleBuffStat, Pair<Integer, Integer>> lmsee: maxStatups.entrySet()) {
Integer srcid = lmse.getValue().getLeft(); Integer srcid = lmsee.getValue().getLeft();
if(!bestEffects.containsKey(srcid)) { if(!bestEffects.containsKey(srcid)) {
bestEffects.put(srcid, retrievedEffects.get(srcid)); bestEffects.put(srcid, retrievedEffects.get(srcid));
} }
@@ -3156,16 +3168,16 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
Map<MapleBuffStat, MapleBuffStatValueHolder> minStatBuffs = new LinkedHashMap<>(); Map<MapleBuffStat, MapleBuffStatValueHolder> minStatBuffs = new LinkedHashMap<>();
for(Entry<Integer, Map<MapleBuffStat, MapleBuffStatValueHolder>> mbsvhi : buffEffects.entrySet()) { for(Entry<Integer, Map<MapleBuffStat, MapleBuffStatValueHolder>> mbsvhi : buffEffects.entrySet()) {
for(Entry<MapleBuffStat, MapleBuffStatValueHolder> mbsvh : mbsvhi.getValue().entrySet()) { for(Entry<MapleBuffStat, MapleBuffStatValueHolder> mbsvhe : mbsvhi.getValue().entrySet()) {
MapleBuffStat mbs = mbsvh.getKey(); MapleBuffStat mbs = mbsvhe.getKey();
Byte it = stats.get(mbs); Byte b = stats.get(mbs);
if(it != null) { if(b != null) {
stats.put(mbs, (byte) (it + 1)); stats.put(mbs, (byte) (b + 1));
if(mbsvh.getValue().value < minStatBuffs.get(mbs).value) minStatBuffs.put(mbs, mbsvh.getValue()); if(mbsvhe.getValue().value < minStatBuffs.get(mbs).value) minStatBuffs.put(mbs, mbsvhe.getValue());
} else { } else {
stats.put(mbs, (byte) 1); stats.put(mbs, (byte) 1);
minStatBuffs.put(mbs, mbsvh.getValue()); minStatBuffs.put(mbs, mbsvhe.getValue());
} }
} }
} }
+2 -31
View File
@@ -965,38 +965,9 @@ public class MapleClient {
return Server.getInstance().getChannel(world, channel); return Server.getInstance().getChannel(world, channel);
} }
private boolean hasCharacter(int cid) throws SQLException { public boolean deleteCharacter(int cid, int senderAccId) {
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try { try {
con = DatabaseConnection.getConnection(); return MapleCharacter.deleteCharFromDB(MapleCharacter.loadCharFromDB(cid, this, false), senderAccId);
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));
} catch(SQLException ex) { } catch(SQLException ex) {
ex.printStackTrace(); ex.printStackTrace();
return false; return false;
+17 -5
View File
@@ -1447,13 +1447,25 @@ public class Commands {
case "job": case "job":
if (sub.length == 2) { 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(); player.equipChanged();
} else if (sub.length == 3) { } else if (sub.length == 3) {
victim = c.getChannelServer().getPlayerStorage().getCharacterByName(sub[1]); victim = c.getChannelServer().getPlayerStorage().getCharacterByName(sub[1]);
if(victim != null) { 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(); player.equipChanged();
} else { } else {
player.message("Player '" + sub[1] + "' could not be found on this channel."); 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()); MapleMap newMap = c.getChannelServer().getMapFactory().resetMap(player.getMapId());
int callerid = c.getPlayer().getId(); int callerid = c.getPlayer().getId();
for (MapleCharacter ch : oldMap.getCharacters()) { for (MapleCharacter chr : oldMap.getCharacters()) {
ch.changeMap(newMap); chr.changeMap(newMap);
if(ch.getId() != callerid) ch.dropMessage("You have been relocated due to map reloading. Sorry for the inconvenience."); if(chr.getId() != callerid) chr.dropMessage("You have been relocated due to map reloading. Sorry for the inconvenience.");
} }
newMap.respawn(); newMap.respawn();
break; break;
+1 -1
View File
@@ -340,7 +340,7 @@ public class Equip extends Item {
List<Pair<String, Integer>> elementalStats = MapleItemInformationProvider.getInstance().getItemLevelupStats(getItemId(), itemLevel); List<Pair<String, Integer>> elementalStats = MapleItemInformationProvider.getInstance().getItemLevelupStats(getItemId(), itemLevel);
for(Pair<String, Integer> p: elementalStats) { 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()));
} }
} }
+1 -1
View File
@@ -177,6 +177,6 @@ public final class ItemConstants {
} }
public static boolean isEquipment(int itemId) { public static boolean isEquipment(int itemId) {
return itemId < 2000000; return itemId < 2000000 && itemId != 0;
} }
} }
+1
View File
@@ -71,6 +71,7 @@ public class ServerConstants {
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_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_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 //Server Rates And Experience
public static final int EXP_RATE = 10; public static final int EXP_RATE = 10;
+2 -2
View File
@@ -289,8 +289,8 @@ public class Main {
BufferedWriter bw = new BufferedWriter(new FileWriter(f)); BufferedWriter bw = new BufferedWriter(new FileWriter(f));
PrintWriter pw = new PrintWriter(bw); PrintWriter pw = new PrintWriter(bw);
for (Errors e : problems.values()) { for (Errors err : problems.values()) {
pw.write(e.createErrorLog()); pw.write(err.createErrorLog());
} }
pw.flush(); pw.flush();
+5 -5
View File
@@ -66,11 +66,11 @@ public class ThreadTracker {
Map<MonitoredLockType, List<Integer>> lockValues = new HashMap<>(); Map<MonitoredLockType, List<Integer>> lockValues = new HashMap<>();
Set<Long> executingThreads = new HashSet<>(); Set<Long> executingThreads = new HashSet<>();
for(Map.Entry<Long, AtomicInteger> lock : lockCount.entrySet()) { for(Map.Entry<Long, AtomicInteger> lc : lockCount.entrySet()) {
if(lock.getValue().get() != 0) { if(lc.getValue().get() != 0) {
executingThreads.add(lockThreads.get(lock.getKey())); executingThreads.add(lockThreads.get(lc.getKey()));
MonitoredLockType lockId = lockIds.get(lock.getKey()); MonitoredLockType lockId = lockIds.get(lc.getKey());
List<Integer> list = lockValues.get(lockId); List<Integer> list = lockValues.get(lockId);
if(list == null) { if(list == null) {
@@ -78,7 +78,7 @@ public class ThreadTracker {
lockValues.put(lockId, list); lockValues.put(lockId, list);
} }
list.add(lock.getValue().get()); list.add(lc.getValue().get());
} }
} }
@@ -58,6 +58,8 @@ public class AutoAssignHandler extends AbstractMaplePacketHandler {
statGain[0] = 0; statGain[1] = 0; statGain[2] = 0; statGain[3] = 0; statGain[0] = 0; statGain[1] = 0; statGain[2] = 0; statGain[3] = 0;
slea.skip(8); slea.skip(8);
byte opt = slea.readByte(); // useful for pirate autoassigning
if (chr.getRemainingAp() < 1) return; if (chr.getRemainingAp() < 1) return;
if(ServerConstants.USE_SERVER_AUTOASSIGNER) { 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("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_); //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; int prStat = 0, scStat = 0, trStat = 0, temp, tempAp = chr.getRemainingAp(), CAP;
MapleStat primary, secondary, tertiary = MapleStat.LUK; MapleStat primary, secondary, tertiary = MapleStat.LUK;
@@ -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? // 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 toCharge = slea.readInt();
int SN = slea.readInt(); int SN = slea.readInt();
String recipient = slea.readMapleAsciiString(); String recipientName = slea.readMapleAsciiString();
String text = slea.readMapleAsciiString(); String text = slea.readMapleAsciiString();
CashItem ring = CashItemFactory.getItem(SN); CashItem itemRing = CashItemFactory.getItem(SN);
MapleCharacter partner = c.getChannelServer().getPlayerStorage().getCharacterByName(recipient); MapleCharacter partner = c.getChannelServer().getPlayerStorage().getCharacterByName(recipientName);
if (partner == null) { 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.")); 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 { } else {
@@ -247,14 +247,14 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
return; return;
}*/ //Gotta let them faggots marry too, hence why this is commented out <3 }*/ //Gotta let them faggots marry too, hence why this is commented out <3
if(ring.toItem() instanceof Equip) { if(itemRing.toItem() instanceof Equip) {
Equip item = (Equip) ring.toItem(); Equip eqp = (Equip) itemRing.toItem();
int ringid = MapleRing.createRing(ring.getItemId(), chr, partner); int ringid = MapleRing.createRing(itemRing.getItemId(), chr, partner);
item.setRingId(ringid); eqp.setRingId(ringid);
cs.addToInventory(item); cs.addToInventory(eqp);
c.announce(MaplePacketCreator.showBoughtCashItem(item, c.getAccID())); c.announce(MaplePacketCreator.showBoughtCashItem(eqp, c.getAccID()));
cs.gift(partner.getId(), chr.getName(), text, item.getSN(), (ringid + 1)); cs.gift(partner.getId(), chr.getName(), text, eqp.getSN(), (ringid + 1));
cs.gainCash(toCharge, -ring.getPrice()); cs.gainCash(toCharge, -itemRing.getPrice());
chr.addCrushRing(MapleRing.loadFromDb(ringid)); chr.addCrushRing(MapleRing.loadFromDb(ringid));
try { try {
chr.sendNote(partner.getName(), text, (byte) 1); chr.sendNote(partner.getName(), text, (byte) 1);
@@ -286,7 +286,7 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
int payment = slea.readByte(); int payment = slea.readByte();
slea.skip(3); //0s slea.skip(3); //0s
int snID = slea.readInt(); int snID = slea.readInt();
CashItem ring = CashItemFactory.getItem(snID); CashItem itemRing = CashItemFactory.getItem(snID);
String sentTo = slea.readMapleAsciiString(); String sentTo = slea.readMapleAsciiString();
int available = slea.readShort() - 1; int available = slea.readShort() - 1;
String text = slea.readAsciiString(available); 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."); chr.dropMessage("The partner you specified cannot be found.\r\nPlease make sure your partner is online and in the same channel.");
} else { } else {
// Need to check to make sure its actually an equip and the right SN... // Need to check to make sure its actually an equip and the right SN...
if(ring.toItem() instanceof Equip) { if(itemRing.toItem() instanceof Equip) {
Equip item = (Equip) ring.toItem(); Equip eqp = (Equip) itemRing.toItem();
int ringid = MapleRing.createRing(ring.getItemId(), chr, partner); int ringid = MapleRing.createRing(itemRing.getItemId(), chr, partner);
item.setRingId(ringid); eqp.setRingId(ringid);
cs.addToInventory(item); cs.addToInventory(eqp);
c.announce(MaplePacketCreator.showBoughtCashItem(item, c.getAccID())); c.announce(MaplePacketCreator.showBoughtCashItem(eqp, c.getAccID()));
cs.gift(partner.getId(), chr.getName(), text, item.getSN(), (ringid + 1)); cs.gift(partner.getId(), chr.getName(), text, eqp.getSN(), (ringid + 1));
cs.gainCash(payment, -ring.getPrice()); cs.gainCash(payment, -itemRing.getPrice());
chr.addFriendshipRing(MapleRing.loadFromDb(ringid)); chr.addFriendshipRing(MapleRing.loadFromDb(ringid));
try { try {
chr.sendNote(partner.getName(), text, (byte) 1); chr.sendNote(partner.getName(), text, (byte) 1);
@@ -99,8 +99,8 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
if (quantity < 0 || price < 110 || c.getPlayer().getItemQuantity(itemid, false) < quantity) { if (quantity < 0 || price < 110 || c.getPlayer().getItemQuantity(itemid, false) < quantity) {
return; return;
} }
MapleInventoryType type = ItemConstants.getInventoryType(itemid); MapleInventoryType invType = ItemConstants.getInventoryType(itemid);
Item i = c.getPlayer().getInventory(type).getItem(slot).copy(); Item i = c.getPlayer().getInventory(invType).getItem(slot).copy();
if (i != null && c.getPlayer().getMeso() >= 5000) { if (i != null && c.getPlayer().getMeso() >= 5000) {
Connection con = null; Connection con = null;
try { try {
@@ -160,7 +160,7 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
Item item = (Item) i; Item item = (Item) i;
ps = con.prepareStatement("INSERT INTO mts_items (tab, type, itemid, quantity, seller, price, owner, sellername, sell_ends) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"); ps = con.prepareStatement("INSERT INTO mts_items (tab, type, itemid, quantity, seller, price, owner, sellername, sell_ends) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
ps.setInt(1, 1); ps.setInt(1, 1);
ps.setInt(2, (int) type.getType()); ps.setInt(2, (int) invType.getType());
ps.setInt(3, item.getItemId()); ps.setInt(3, item.getItemId());
ps.setInt(4, quantity); ps.setInt(4, quantity);
ps.setInt(5, c.getPlayer().getId()); ps.setInt(5, c.getPlayer().getId());
@@ -172,7 +172,7 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
Equip equip = (Equip) i; 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 = 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(1, 1);
ps.setInt(2, (int) type.getType()); ps.setInt(2, (int) invType.getType());
ps.setInt(3, equip.getItemId()); ps.setInt(3, equip.getItemId());
ps.setInt(4, quantity); ps.setInt(4, quantity);
ps.setInt(5, c.getPlayer().getId()); ps.setInt(5, c.getPlayer().getId());
@@ -203,7 +203,7 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
} }
ps.executeUpdate(); ps.executeUpdate();
ps.close(); ps.close();
MapleInventoryManipulator.removeFromSlot(c, type, slot, quantity, false); MapleInventoryManipulator.removeFromSlot(c, invType, slot, quantity, false);
con.close(); con.close();
} catch (SQLException e) { } catch (SQLException e) {
@@ -106,11 +106,11 @@ public final class MakerSkillHandler extends AbstractMaplePacketHandler {
for(int i = 0; i < reagents; i++) { // crystals for(int i = 0; i < reagents; i++) { // crystals
int reagentid = slea.readInt(); int reagentid = slea.readInt();
if(ItemConstants.isMakerReagent(reagentid)) { if(ItemConstants.isMakerReagent(reagentid)) {
Short r = reagentids.get(reagentid); Short rs = reagentids.get(reagentid);
if(r == null) { if(rs == null) {
reagentids.put(reagentid, (short) 1); reagentids.put(reagentid, (short) 1);
} else { } 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 // remove those not present on player inventory
if(!toUpdate.isEmpty()) { if(!toUpdate.isEmpty()) {
for(Pair<Integer, Short> r : toUpdate) { for(Pair<Integer, Short> rp : toUpdate) {
if(r.getRight() > 0) { if(rp.getRight() > 0) {
reagentids.put(r.getLeft(), r.getRight()); reagentids.put(rp.getLeft(), rp.getRight());
} else { } else {
reagentids.remove(r.getLeft()); reagentids.remove(rp.getLeft());
} }
} }
} }
@@ -453,12 +453,12 @@ public final class MakerSkillHandler extends AbstractMaplePacketHandler {
ii.improveEquipStats(eqp, stats); ii.improveEquipStats(eqp, stats);
for(Short s : randStat) { for(Short sh : randStat) {
ii.scrollOptionEquipWithChaos(eqp, s, false); ii.scrollOptionEquipWithChaos(eqp, sh, false);
} }
for(Short s : randOption) { for(Short sh : randOption) {
ii.scrollOptionEquipWithChaos(eqp, s, true); ii.scrollOptionEquipWithChaos(eqp, sh, true);
} }
} }
@@ -407,10 +407,10 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
} else if (mode == Action.CONFIRM.getCode()) { } else if (mode == Action.CONFIRM.getCode()) {
MapleTrade.completeTrade(c.getPlayer()); MapleTrade.completeTrade(c.getPlayer());
} else if (mode == Action.ADD_ITEM.getCode() || mode == Action.PUT_ITEM.getCode()) { } 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 slot = slea.readShort();
short bundles = 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; return;
} }
short perBundle = slea.readShort(); 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); 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; return;
} }
Item ivItem = chr.getInventory(type).getItem(slot); Item ivItem = chr.getInventory(ivType).getItem(slot);
Item sellItem = ivItem.copy(); Item sellItem = ivItem.copy();
if (chr.getItemQuantity(ivItem.getItemId(), false) < perBundle * bundles) { if (chr.getItemQuantity(ivItem.getItemId(), false) < perBundle * bundles) {
return; return;
@@ -429,22 +429,22 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
return; return;
} }
sellItem.setQuantity(perBundle); sellItem.setQuantity(perBundle);
MaplePlayerShopItem item = new MaplePlayerShopItem(sellItem, bundles, price); MaplePlayerShopItem shopItem = new MaplePlayerShopItem(sellItem, bundles, price);
MaplePlayerShop shop = chr.getPlayerShop(); MaplePlayerShop shop = chr.getPlayerShop();
MapleHiredMerchant merchant = chr.getHiredMerchant(); MapleHiredMerchant merchant = chr.getHiredMerchant();
if (shop != null && shop.isOwner(c.getPlayer())) { if (shop != null && shop.isOwner(c.getPlayer())) {
if (ivItem != null && ivItem.getQuantity() >= bundles * perBundle) { if (ivItem != null && ivItem.getQuantity() >= bundles * perBundle) {
shop.addItem(item); shop.addItem(shopItem);
c.announce(MaplePacketCreator.getPlayerShopItemUpdate(shop)); c.announce(MaplePacketCreator.getPlayerShopItemUpdate(shop));
} }
} else if (merchant != null && merchant.isOwner(c.getPlayer())) { } else if (merchant != null && merchant.isOwner(c.getPlayer())) {
merchant.addItem(item); merchant.addItem(shopItem);
c.announce(MaplePacketCreator.updateHiredMerchant(merchant, c.getPlayer())); c.announce(MaplePacketCreator.updateHiredMerchant(merchant, c.getPlayer()));
} }
if (ItemConstants.isRechargable(ivItem.getItemId())) { if (ItemConstants.isRechargable(ivItem.getItemId())) {
MapleInventoryManipulator.removeFromSlot(c, type, slot, ivItem.getQuantity(), true); MapleInventoryManipulator.removeFromSlot(c, ivType, slot, ivItem.getQuantity(), true);
} else { } 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()) { } else if (mode == Action.REMOVE_ITEM.getCode()) {
MaplePlayerShop shop = chr.getPlayerShop(); MaplePlayerShop shop = chr.getPlayerShop();
@@ -456,10 +456,10 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
c.disconnect(true, false); c.disconnect(true, false);
return; return;
} }
MaplePlayerShopItem item = shop.getItems().get(slot); MaplePlayerShopItem shopItem = shop.getItems().get(slot);
Item ivItem = item.getItem().copy(); Item ivItem = shopItem.getItem().copy();
shop.removeItem(slot); shop.removeItem(slot);
ivItem.setQuantity(item.getBundles()); ivItem.setQuantity(shopItem.getBundles());
MapleInventoryManipulator.addFromDrop(c, ivItem, false); MapleInventoryManipulator.addFromDrop(c, ivItem, false);
c.announce(MaplePacketCreator.getPlayerShopItemUpdate(shop)); c.announce(MaplePacketCreator.getPlayerShopItemUpdate(shop));
} }
@@ -505,35 +505,35 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
c.announce(MaplePacketCreator.updateHiredMerchant(merchant, chr)); c.announce(MaplePacketCreator.updateHiredMerchant(merchant, chr));
} else if (mode == Action.BUY.getCode() || mode == Action.MERCHANT_BUY.getCode()) { } else if (mode == Action.BUY.getCode() || mode == Action.MERCHANT_BUY.getCode()) {
int item = slea.readByte(); int itemid = slea.readByte();
short quantity = slea.readShort(); short quantity = slea.readShort();
if (quantity < 1) { if (quantity < 1) {
AutobanFactory.PACKET_EDIT.alert(c.getPlayer(), c.getPlayer().getName() + " tried to packet edit with a hired merchant and or player shop."); 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); c.disconnect(true, false);
return; return;
} }
MaplePlayerShop shop = chr.getPlayerShop(); MaplePlayerShop shop = chr.getPlayerShop();
MapleHiredMerchant merchant = chr.getHiredMerchant(); MapleHiredMerchant merchant = chr.getHiredMerchant();
if (shop != null && shop.isVisitor(c.getPlayer())) { if (shop != null && shop.isVisitor(c.getPlayer())) {
shop.buy(c, item, quantity); shop.buy(c, itemid, quantity);
shop.broadcast(MaplePacketCreator.getPlayerShopItemUpdate(shop)); shop.broadcast(MaplePacketCreator.getPlayerShopItemUpdate(shop));
} else if (merchant != null && !merchant.isOwner(chr)) { } else if (merchant != null && !merchant.isOwner(chr)) {
merchant.buy(c, item, quantity); merchant.buy(c, itemid, quantity);
merchant.broadcastToVisitorsThreadsafe(MaplePacketCreator.updateHiredMerchant(merchant, c.getPlayer())); merchant.broadcastToVisitorsThreadsafe(MaplePacketCreator.updateHiredMerchant(merchant, c.getPlayer()));
} }
} else if (mode == Action.TAKE_ITEM_BACK.getCode()) { } else if (mode == Action.TAKE_ITEM_BACK.getCode()) {
MapleHiredMerchant merchant = chr.getHiredMerchant(); MapleHiredMerchant merchant = chr.getHiredMerchant();
if (merchant != null && merchant.isOwner(c.getPlayer())) { if (merchant != null && merchant.isOwner(c.getPlayer())) {
int slot = slea.readShort(); int slot = slea.readShort();
MaplePlayerShopItem item = merchant.getItems().get(slot); MaplePlayerShopItem shopItem = merchant.getItems().get(slot);
if (!MapleInventory.checkSpot(chr, item.getItem())) { if (!MapleInventory.checkSpot(chr, shopItem.getItem())) {
c.announce(MaplePacketCreator.enableActions()); c.announce(MaplePacketCreator.enableActions());
return; return;
} }
if (item.getBundles() > 0) { if (shopItem.getBundles() > 0) {
Item iitem = item.getItem(); Item iitem = shopItem.getItem();
iitem.setQuantity((short) (item.getItem().getQuantity() * item.getBundles())); iitem.setQuantity((short) (shopItem.getItem().getQuantity() * shopItem.getBundles()));
MapleInventoryManipulator.addFromDrop(c, iitem, true); MapleInventoryManipulator.addFromDrop(c, iitem, true);
} }
merchant.removeFromSlot(slot); merchant.removeFromSlot(slot);
@@ -114,14 +114,14 @@ public final class StorageHandler extends AbstractMaplePacketHandler {
if (chr.getMeso() < meso) { if (chr.getMeso() < meso) {
c.announce(MaplePacketCreator.getStorageError((byte) 0x0B)); c.announce(MaplePacketCreator.getStorageError((byte) 0x0B));
} else { } else {
MapleInventoryType type = ItemConstants.getInventoryType(itemId); MapleInventoryType invType = ItemConstants.getInventoryType(itemId);
Item item = chr.getInventory(type).getItem(slot).copy(); Item item = chr.getInventory(invType).getItem(slot).copy();
if (item.getItemId() == itemId && (item.getQuantity() >= quantity || ItemConstants.isRechargable(itemId))) { if (item.getItemId() == itemId && (item.getQuantity() >= quantity || ItemConstants.isRechargable(itemId))) {
if (ItemConstants.isRechargable(itemId)) { if (ItemConstants.isRechargable(itemId)) {
quantity = item.getQuantity(); quantity = item.getQuantity();
} }
chr.gainMeso(meso, false, true, false); chr.gainMeso(meso, false, true, false);
MapleInventoryManipulator.removeFromSlot(c, type, slot, quantity, false); MapleInventoryManipulator.removeFromSlot(c, invType, slot, quantity, false);
item.setQuantity(quantity); item.setQuantity(quantity);
storage.store(item); storage.store(item);
storage.sendStored(c, ItemConstants.getInventoryType(itemId)); storage.sendStored(c, ItemConstants.getInventoryType(itemId));
@@ -144,9 +144,9 @@ public final class TakeDamageHandler extends AbstractMaplePacketHandler {
is_deadly = true; is_deadly = true;
} }
mpattack += attackInfo.getMpBurn(); mpattack += attackInfo.getMpBurn();
MobSkill skill = MobSkillFactory.getMobSkill(attackInfo.getDiseaseSkill(), attackInfo.getDiseaseLevel()); MobSkill mobSkill = MobSkillFactory.getMobSkill(attackInfo.getDiseaseSkill(), attackInfo.getDiseaseLevel());
if (skill != null && damage > 0) { if (mobSkill != null && damage > 0) {
skill.applyEffect(chr, attacker, false, banishPlayers); mobSkill.applyEffect(chr, attacker, false, banishPlayers);
} }
attacker.setMp(attacker.getMp() - attackInfo.getMpCon()); attacker.setMp(attacker.getMp() - attackInfo.getMpCon());
@@ -489,13 +489,13 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
player.getMap().broadcastMessage(MaplePacketCreator.useChalkboard(player, false)); player.getMap().broadcastMessage(MaplePacketCreator.useChalkboard(player, false));
player.getClient().announce(MaplePacketCreator.enableActions()); player.getClient().announce(MaplePacketCreator.enableActions());
} else if (itemType == 539) { } else if (itemType == 539) {
List<String> lines = new LinkedList<>(); List<String> strLines = new LinkedList<>();
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
lines.add(slea.readMapleAsciiString()); strLines.add(slea.readMapleAsciiString());
} }
final int world = c.getWorld(); 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() { TimerManager.getInstance().schedule(new Runnable() {
@Override @Override
public void run() { public void run() {
+2 -2
View File
@@ -136,8 +136,8 @@ public class MapleGuild {
if (!mgc.isOnline()) { if (!mgc.isOnline()) {
continue; continue;
} }
List<Integer> ch = notifications.get(mgc.getChannel()); List<Integer> chl = notifications.get(mgc.getChannel());
if (ch != null) ch.add(mgc.getId()); if (chl != null) chl.add(mgc.getId());
//Unable to connect to Channel... error was here //Unable to connect to Channel... error was here
} }
} finally { } finally {
@@ -34,7 +34,7 @@ public final class DeleteCharHandler extends AbstractMaplePacketHandler {
String pic = slea.readMapleAsciiString(); String pic = slea.readMapleAsciiString();
int cid = slea.readInt(); int cid = slea.readInt();
if (c.checkPic(pic)) { 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"); FilePrinter.printError(FilePrinter.DELETED_CHARACTERS + c.getAccountName() + ".txt", c.getAccountName() + " deleted CID: " + cid + "\r\n");
c.announce(MaplePacketCreator.deleteCharResponse(cid, 0)); c.announce(MaplePacketCreator.deleteCharResponse(cid, 0));
} else { } else {
+1 -1
View File
@@ -194,7 +194,7 @@ public class MapleTrade {
private boolean fitsInInventory() { private boolean fitsInInventory() {
List<Pair<Item, MapleInventoryType>> tradeItems = new LinkedList<>(); List<Pair<Item, MapleInventoryType>> tradeItems = new LinkedList<>();
for (Item item : exchangeItems) { for (Item item : exchangeItems) {
tradeItems.add(new Pair(item, item.getInventoryType())); tradeItems.add(new Pair<>(item, item.getInventoryType()));
} }
return MapleInventory.checkSpotsAndOwnership(chr, tradeItems); return MapleInventory.checkSpotsAndOwnership(chr, tradeItems);
+3 -3
View File
@@ -869,12 +869,12 @@ public class MapleMonster extends AbstractLoadedMapleLife {
} else if (venom) { } else if (venom) {
if (from.getJob() == MapleJob.NIGHTLORD || from.getJob() == MapleJob.SHADOWER || from.getJob().isA(MapleJob.NIGHTWALKER3)) { if (from.getJob() == MapleJob.NIGHTLORD || from.getJob() == MapleJob.SHADOWER || from.getJob().isA(MapleJob.NIGHTWALKER3)) {
int poisonLevel, matk, jobid = from.getJob().getId(); int poisonLevel, matk, jobid = from.getJob().getId();
int skill = (jobid == 412 ? NightLord.VENOMOUS_STAR : (jobid == 422 ? Shadower.VENOMOUS_STAB : NightWalker.VENOM)); int skillid = (jobid == 412 ? NightLord.VENOMOUS_STAR : (jobid == 422 ? Shadower.VENOMOUS_STAB : NightWalker.VENOM));
poisonLevel = from.getSkillLevel(SkillFactory.getSkill(skill)); poisonLevel = from.getSkillLevel(SkillFactory.getSkill(skillid));
if (poisonLevel <= 0) { if (poisonLevel <= 0) {
return false; return false;
} }
matk = SkillFactory.getSkill(skill).getEffect(poisonLevel).getMatk(); matk = SkillFactory.getSkill(skillid).getEffect(poisonLevel).getMatk();
int luk = from.getLuk(); int luk = from.getLuk();
int maxDmg = (int) Math.ceil(Math.min(Short.MAX_VALUE, 0.2 * luk * matk)); 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)); int minDmg = (int) Math.ceil(Math.min(Short.MAX_VALUE, 0.1 * luk * matk));
@@ -20,6 +20,8 @@
*/ */
package server.life; package server.life;
import constants.ItemConstants;
import constants.ServerConstants;
import java.io.File; import java.io.File;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
@@ -27,9 +29,11 @@ import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import provider.MapleData; import provider.MapleData;
import provider.MapleDataProvider; import provider.MapleDataProvider;
import provider.MapleDataProviderFactory; import provider.MapleDataProviderFactory;
@@ -37,6 +41,7 @@ import provider.MapleDataTool;
import server.MapleItemInformationProvider; import server.MapleItemInformationProvider;
import tools.DatabaseConnection; import tools.DatabaseConnection;
import tools.Pair; import tools.Pair;
import tools.Randomizer;
public class MapleMonsterInformationProvider { public class MapleMonsterInformationProvider {
// Author : LightPepsi // Author : LightPepsi
@@ -46,6 +51,8 @@ public class MapleMonsterInformationProvider {
private final List<MonsterGlobalDropEntry> globaldrops = new ArrayList<>(); private final List<MonsterGlobalDropEntry> globaldrops = new ArrayList<>();
private final Map<Integer, List<Integer>> dropsChancePool = new HashMap<>(); // thanks to ronan 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() { protected MapleMonsterInformationProvider() {
retrieveGlobal(); 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) { public final List<MonsterDropEntry> retrieveDrop(final int monsterId) {
if (drops.containsKey(monsterId)) { if (drops.containsKey(monsterId)) {
return drops.get(monsterId); return drops.get(monsterId);
@@ -234,6 +281,8 @@ public class MapleMonsterInformationProvider {
public final void clearDrops() { public final void clearDrops() {
drops.clear(); drops.clear();
hasNoMultiEquipDrops.clear();
extraMultiEquipDrops.clear();
dropsChancePool.clear(); dropsChancePool.clear();
globaldrops.clear(); globaldrops.clear();
retrieveGlobal(); retrieveGlobal();
+5 -5
View File
@@ -559,7 +559,7 @@ public class MapleMap {
} }
distn = Math.sqrt(distn); 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) { 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> dropEntry = new ArrayList<>();
final List<MonsterDropEntry> questEntry = new ArrayList<>(); final List<MonsterDropEntry> questEntry = new ArrayList<>();
sortDropEntries(mi.retrieveDrop(mob.getId()), dropEntry, questEntry); sortDropEntries(mi.retrieveEffectiveDrop(mob.getId()), dropEntry, questEntry);
// Normal Drops // Normal Drops
d = dropItemsFromMonsterOnMap(dropEntry, pos, d, chRate, droptype, mobpos, chr, mob); d = dropItemsFromMonsterOnMap(dropEntry, pos, d, chRate, droptype, mobpos, chr, mob);
@@ -1347,9 +1347,9 @@ public class MapleMap {
objectRLock.lock(); objectRLock.lock();
try { try {
for (Object obj : list) { for (Object ob : list) {
if(obj instanceof MapleMapObject) { if(ob instanceof MapleMapObject) {
MapleMapObject mmo = (MapleMapObject) obj; MapleMapObject mmo = (MapleMapObject) ob;
if(mapobjects.containsValue(mmo) && mmo.getType() == MapleMapObjectType.REACTOR) { if(mapobjects.containsValue(mmo) && mmo.getType() == MapleMapObjectType.REACTOR) {
listObjects.add(mmo); listObjects.add(mmo);
+2 -2
View File
@@ -272,9 +272,9 @@ public class MapleMapFactory {
try { try {
for (MapleData layer : mapData.getChildByPath("back")) { // yolo for (MapleData layer : mapData.getChildByPath("back")) { // yolo
int layerNum = Integer.parseInt(layer.getName()); 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) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
+2
View File
@@ -74,9 +74,11 @@ public class MapleMist extends AbstractMapleMapObject {
case Evan.RECOVERY_AURA: case Evan.RECOVERY_AURA:
isRecoveryMist = true; isRecoveryMist = true;
break; break;
case Shadower.SMOKE_SCREEN: // Smoke Screen case Shadower.SMOKE_SCREEN: // Smoke Screen
isPoisonMist = false; isPoisonMist = false;
break; break;
case FPMage.POISON_MIST: // FP mist case FPMage.POISON_MIST: // FP mist
case BlazeWizard.FLAME_GEAR: // Flame Gear case BlazeWizard.FLAME_GEAR: // Flame Gear
case NightWalker.POISON_BOMB: // Poison Bomb case NightWalker.POISON_BOMB: // Poison Bomb
+10 -10
View File
@@ -131,26 +131,26 @@ public class ItemAction extends MapleQuestAction {
// must take all needed items before giving others // must take all needed items before giving others
for(Pair<Integer, Integer> iEntry: takeItem) { for(Pair<Integer, Integer> iPair: takeItem) {
MapleInventoryType type = ItemConstants.getInventoryType(iEntry.getLeft()); MapleInventoryType type = ItemConstants.getInventoryType(iPair.getLeft());
int quantity = iEntry.getRight() * -1; // Invert int quantity = iPair.getRight() * -1; // Invert
if(type.equals(MapleInventoryType.EQUIP)) { 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... // 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. // Found it equipped, so change the type to equipped.
type = MapleInventoryType.EQUIPPED; type = MapleInventoryType.EQUIPPED;
} }
} }
} }
MapleInventoryManipulator.removeById(chr.getClient(), type, iEntry.getLeft(), quantity, true, false); MapleInventoryManipulator.removeById(chr.getClient(), type, iPair.getLeft(), quantity, true, false);
chr.announce(MaplePacketCreator.getShowItemGain(iEntry.getLeft(), (short) iEntry.getRight().shortValue(), true)); chr.announce(MaplePacketCreator.getShowItemGain(iPair.getLeft(), (short) iPair.getRight().shortValue(), true));
} }
for(Pair<Integer, Integer> iEntry: giveItem) { for(Pair<Integer, Integer> iPair: giveItem) {
MapleInventoryManipulator.addById(chr.getClient(), iEntry.getLeft(), (short) iEntry.getRight().shortValue()); MapleInventoryManipulator.addById(chr.getClient(), iPair.getLeft(), (short) iPair.getRight().shortValue());
chr.announce(MaplePacketCreator.getShowItemGain(iEntry.getLeft(), (short) iEntry.getRight().shortValue(), true)); chr.announce(MaplePacketCreator.getShowItemGain(iPair.getLeft(), (short) iPair.getRight().shortValue(), true));
} }
} }
+14 -2
View File
@@ -1394,6 +1394,18 @@ public class MaplePacketCreator {
return spawnMonsterInternal(life, true, false, false, 0, true); 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. * Internal function to handler monster spawning and controlling.
* *
@@ -1455,10 +1467,10 @@ public class MaplePacketCreator {
mplew.write(effect != 0 ? effect : -3); mplew.write(effect != 0 ? effect : -3);
mplew.writeInt(life.getParentMobOid()); mplew.writeInt(life.getParentMobOid());
} else { } else {
mplew.write(newSpawn ? -2 : -1); encodeParentlessMobSpawnEffect(mplew, newSpawn, effect);
} }
} else { } else {
mplew.write(newSpawn ? -2 : -1); encodeParentlessMobSpawnEffect(mplew, newSpawn, effect);
} }
mplew.write(life.getTeam()); mplew.write(life.getTeam());
+1
View File
@@ -12062,6 +12062,7 @@
<imgdir name="item"> <imgdir name="item">
<imgdir name="0"> <imgdir name="0">
<int name="id" value="4031852"/> <int name="id" value="4031852"/>
<int name="count" value="-1"/>
</imgdir> </imgdir>
</imgdir> </imgdir>
</imgdir> </imgdir>