Enhanced map bounds + HolidayPQ + Battleship
Fixed Abdula not showing book info for Arans. Fixed map bounds, now it hopefully doesn't let items pass through the walkable area anymore. Implemented HolidayPQ. Added a custom item sandbox system, to be used with items generated by the "drop" command. Added the whole-map buff when using the Happy Birthday item. Fixed several battleship issues: - Battleship now shows HP properly at the buff icon. - Cleared some inconsistencies on battleship when interacting with the enhanced buff system. - Battleship now hands out defensive buffs properly.
This commit is contained in:
@@ -121,6 +121,8 @@ public class MapleItemInformationProvider {
|
||||
protected Map<Integer, Pair<String, Integer>> statUpgradeMakerCache = new HashMap<>();
|
||||
protected Map<Integer, MakerItemFactory.MakerItemCreateEntry> makerItemCache = new HashMap<>();
|
||||
protected Map<Integer, Integer> makerCatalystCache = new HashMap<>();
|
||||
protected Map<Integer, Map<String, Integer>> skillUpgradeCache = new HashMap<>();
|
||||
protected Map<Integer, MapleData> skillUpgradeInfoCache = new HashMap<>();
|
||||
|
||||
private MapleItemInformationProvider() {
|
||||
loadCardIdData();
|
||||
@@ -525,8 +527,9 @@ public class MapleItemInformationProvider {
|
||||
return replaceOnExpireCache.get(itemId);
|
||||
}
|
||||
|
||||
int itemReplacement = MapleDataTool.getInt("info/replace/itemid", getItemData(itemId), 0);
|
||||
String msg = MapleDataTool.getString("info/replace/msg", getItemData(itemId));
|
||||
MapleData data = getItemData(itemId);
|
||||
int itemReplacement = MapleDataTool.getInt("info/replace/itemid", data, 0);
|
||||
String msg = MapleDataTool.getString("info/replace/msg", data, "");
|
||||
|
||||
Pair<Integer, String> ret = new Pair<>(itemReplacement, msg);
|
||||
replaceOnExpireCache.put(itemId, ret);
|
||||
@@ -1239,25 +1242,42 @@ public class MapleItemInformationProvider {
|
||||
return bRestricted;
|
||||
}
|
||||
|
||||
public Map<String, Integer> getSkillStats(int itemId, double playerJob) {
|
||||
Map<String, Integer> ret = new LinkedHashMap<>();
|
||||
private Pair<Map<String, Integer>, MapleData> getSkillStatsInternal(int itemId) {
|
||||
Map<String, Integer> ret = skillUpgradeCache.get(itemId);
|
||||
MapleData retSkill = skillUpgradeInfoCache.get(itemId);
|
||||
|
||||
if(ret != null) return new Pair<>(ret, retSkill);
|
||||
|
||||
retSkill = null;
|
||||
ret = new LinkedHashMap<>();
|
||||
MapleData item = getItemData(itemId);
|
||||
if (item == null) {
|
||||
return null;
|
||||
}
|
||||
MapleData info = item.getChildByPath("info");
|
||||
if (info == null) {
|
||||
return null;
|
||||
}
|
||||
for (MapleData data : info.getChildren()) {
|
||||
if (data.getName().startsWith("inc")) {
|
||||
ret.put(data.getName().substring(3), MapleDataTool.getIntConvert(data));
|
||||
if (item != null) {
|
||||
MapleData info = item.getChildByPath("info");
|
||||
if (info != null) {
|
||||
for (MapleData data : info.getChildren()) {
|
||||
if (data.getName().startsWith("inc")) {
|
||||
ret.put(data.getName().substring(3), MapleDataTool.getIntConvert(data));
|
||||
}
|
||||
}
|
||||
ret.put("masterLevel", MapleDataTool.getInt("masterLevel", info, 0));
|
||||
ret.put("reqSkillLevel", MapleDataTool.getInt("reqSkillLevel", info, 0));
|
||||
ret.put("success", MapleDataTool.getInt("success", info, 0));
|
||||
|
||||
retSkill = info.getChildByPath("skill");
|
||||
}
|
||||
}
|
||||
ret.put("masterLevel", MapleDataTool.getInt("masterLevel", info, 0));
|
||||
ret.put("reqSkillLevel", MapleDataTool.getInt("reqSkillLevel", info, 0));
|
||||
ret.put("success", MapleDataTool.getInt("success", info, 0));
|
||||
MapleData skill = info.getChildByPath("skill");
|
||||
|
||||
skillUpgradeCache.put(itemId, ret);
|
||||
skillUpgradeInfoCache.put(itemId, retSkill);
|
||||
return new Pair<>(ret, retSkill);
|
||||
}
|
||||
|
||||
public Map<String, Integer> getSkillStats(int itemId, double playerJob) {
|
||||
Pair<Map<String, Integer>, MapleData> retData = getSkillStatsInternal(itemId);
|
||||
if(retData.getLeft().isEmpty()) return null;
|
||||
|
||||
Map<String, Integer> ret = new LinkedHashMap<>(retData.getLeft());
|
||||
MapleData skill = retData.getRight();
|
||||
int curskill;
|
||||
for (int i = 0; i < skill.getChildren().size(); i++) {
|
||||
curskill = MapleDataTool.getInt(Integer.toString(i), skill, 0);
|
||||
@@ -1933,7 +1953,7 @@ public class MapleItemInformationProvider {
|
||||
}
|
||||
|
||||
private boolean canUseSkillBook(MapleCharacter player, Integer skillBookId) {
|
||||
Map<String, Integer> skilldata = MapleItemInformationProvider.getInstance().getSkillStats(skillBookId, player.getJob().getId());
|
||||
Map<String, Integer> skilldata = getSkillStats(skillBookId, player.getJob().getId());
|
||||
if(skilldata == null || skilldata.get("skillid") == 0) return false;
|
||||
|
||||
Skill skill2 = SkillFactory.getSkill(skilldata.get("skillid"));
|
||||
@@ -1942,7 +1962,7 @@ public class MapleItemInformationProvider {
|
||||
|
||||
public List<Integer> usableMasteryBooks(MapleCharacter player) {
|
||||
List<Integer> masterybook = new LinkedList<>();
|
||||
for(Integer i = 2290000; i <= 2290125; i++) {
|
||||
for(Integer i = 2290000; i <= 2290139; i++) {
|
||||
if(canUseSkillBook(player, i)) {
|
||||
masterybook.add(i);
|
||||
}
|
||||
@@ -1953,7 +1973,7 @@ public class MapleItemInformationProvider {
|
||||
|
||||
public List<Integer> usableSkillBooks(MapleCharacter player) {
|
||||
List<Integer> skillbook = new LinkedList<>();
|
||||
for(Integer i = 2280000; i <= 2280012; i++) {
|
||||
for(Integer i = 2280000; i <= 2280019; i++) {
|
||||
if(canUseSkillBook(player, i)) {
|
||||
skillbook.add(i);
|
||||
}
|
||||
|
||||
@@ -1001,7 +1001,7 @@ public class MapleStatEffect {
|
||||
}
|
||||
}
|
||||
if (sourceid == Corsair.BATTLE_SHIP) {
|
||||
chr.announce(MaplePacketCreator.skillCooldown(5221999, chr.getBattleshipHp()));
|
||||
chr.announceBattleshipHp();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1107,14 +1107,17 @@ public class MapleStatEffect {
|
||||
} else if (isCombo()) {
|
||||
mbuff = MaplePacketCreator.giveForeignBuff(applyto.getId(), statups);
|
||||
} else if (isMonsterRiding()) {
|
||||
if (sourceid == Corsair.BATTLE_SHIP) {//hp
|
||||
if (applyto.getBattleshipHp() <= 0) {
|
||||
applyto.resetBattleshipHp();
|
||||
}
|
||||
|
||||
localstatups = statups;
|
||||
}
|
||||
|
||||
buff = MaplePacketCreator.giveBuff(localsourceid, localDuration, localstatups);
|
||||
mbuff = MaplePacketCreator.showMonsterRiding(applyto.getId(), givemount);
|
||||
localDuration = duration;
|
||||
if (sourceid == Corsair.BATTLE_SHIP) {//hp
|
||||
if (applyto.getBattleshipHp() == 0) {
|
||||
applyto.resetBattleshipHp();
|
||||
}
|
||||
}
|
||||
} else if (isShadowPartner()) {
|
||||
List<Pair<MapleBuffStat, Integer>> stat = Collections.singletonList(new Pair<>(MapleBuffStat.SHADOWPARTNER, 0));
|
||||
mbuff = MaplePacketCreator.giveForeignBuff(applyto.getId(), stat);
|
||||
@@ -1130,9 +1133,8 @@ public class MapleStatEffect {
|
||||
|
||||
if (buff != null) {
|
||||
if (!hasNoIcon()) { //Thanks flav for such a simple release! :)
|
||||
applyto.getClient().announce(buff);
|
||||
}
|
||||
else {
|
||||
applyto.announce(buff);
|
||||
} else {
|
||||
System.out.println("<Error> NO buff icon for id " + sourceid);
|
||||
}
|
||||
}
|
||||
@@ -1146,7 +1148,7 @@ public class MapleStatEffect {
|
||||
applyto.getMap().broadcastMessage(applyto, mbuff, false);
|
||||
}
|
||||
if (sourceid == Corsair.BATTLE_SHIP) {
|
||||
applyto.announce(MaplePacketCreator.skillCooldown(5221999, applyto.getBattleshipHp() / 10));
|
||||
applyto.announceBattleshipHp();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,6 +275,7 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
*
|
||||
* @param from the player that dealt the damage
|
||||
* @param damage
|
||||
* @param stayAlive
|
||||
*/
|
||||
public synchronized void damage(MapleCharacter from, int damage, boolean stayAlive) {
|
||||
Integer trueDamage = applyAndGetHpDamage(damage, stayAlive);
|
||||
@@ -293,7 +294,7 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
|
||||
broadcastMobHpBar(from);
|
||||
}
|
||||
|
||||
|
||||
public void heal(int hp, int mp) {
|
||||
Integer hpHealed = applyAndGetHpDamage(-hp, false);
|
||||
if(hpHealed == null) return;
|
||||
@@ -305,7 +306,7 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
}
|
||||
setMp(mp2Heal);
|
||||
|
||||
if(hp > 0) getMap().broadcastMessage(MaplePacketCreator.healMonster(getObjectId(), hp));
|
||||
if(hp > 0) getMap().broadcastMessage(MaplePacketCreator.healMonster(getObjectId(), hp, getHp(), getMaxHp()));
|
||||
|
||||
maxHpPlusHeal.addAndGet(hpHealed);
|
||||
dispatchMonsterHealed(hpHealed);
|
||||
@@ -695,7 +696,7 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
public boolean hasBossHPBar() {
|
||||
return isBoss() && getTagColor() > 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void sendSpawnData(MapleClient c) {
|
||||
if (!isAlive()) {
|
||||
|
||||
@@ -470,26 +470,26 @@ public class MapleMap {
|
||||
public void generateMapDropRangeCache() {
|
||||
bndLock.lock();
|
||||
try {
|
||||
Integer mapId = Integer.valueOf(mapid);
|
||||
Pair<Integer, Integer> bounds = dropBoundsCache.get(mapId);
|
||||
Pair<Integer, Integer> bounds = dropBoundsCache.get(mapid);
|
||||
|
||||
if(bounds != null) {
|
||||
xLimits = bounds;
|
||||
} else {
|
||||
// assuming MINIMAP always have an equal-greater picture representation of the map area (players won't walk beyond the area known by the minimap).
|
||||
Point lp = new Point(mapArea.x, mapArea.y), rp = new Point(mapArea.x + mapArea.width, mapArea.y), fallback = new Point(mapArea.x + (mapArea.width / 2), mapArea.y);
|
||||
|
||||
lp = bsearchDropPos(lp, fallback);
|
||||
rp = bsearchDropPos(rp, fallback);
|
||||
lp = bsearchDropPos(lp, fallback); // approximated leftmost fh node position
|
||||
rp = bsearchDropPos(rp, fallback); // approximated rightmost fh node position
|
||||
|
||||
xLimits = new Pair<>(lp.x, rp.x);
|
||||
dropBoundsCache.put(mapId, xLimits);
|
||||
xLimits = new Pair<>(lp.x + 14, rp.x - 14);
|
||||
dropBoundsCache.put(mapid, xLimits);
|
||||
}
|
||||
} finally {
|
||||
bndLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public Point bsearchDropPos(Point initial, Point fallback) {
|
||||
private Point bsearchDropPos(Point initial, Point fallback) {
|
||||
Point res, dropPos = null;
|
||||
|
||||
int awayx = fallback.x;
|
||||
@@ -1304,13 +1304,6 @@ public class MapleMap {
|
||||
}
|
||||
}
|
||||
|
||||
public void monsterCloakingDevice() {
|
||||
for (MapleMapObject monstermo : getMapObjectsInRange(new Point(0, 0), Double.POSITIVE_INFINITY, Arrays.asList(MapleMapObjectType.MONSTER))) {
|
||||
MapleMonster monster = (MapleMonster) monstermo;
|
||||
broadcastMessage(MaplePacketCreator.makeMonsterInvisible(monster));
|
||||
}
|
||||
}
|
||||
|
||||
public void softKillAllMonsters() {
|
||||
closeMapSpawnPoints();
|
||||
|
||||
@@ -1809,6 +1802,8 @@ public class MapleMap {
|
||||
monsterItemDrop(monster, monster.getDropPeriodTime() / 3);
|
||||
} else if (monster.getId() == 9300093) {
|
||||
monsterItemDrop(monster, monster.getDropPeriodTime());
|
||||
} else if (monster.getId() == 9400326 || monster.getId() == 9400331 || monster.getId() == 9400336) {
|
||||
monsterItemDrop(monster, monster.getDropPeriodTime());
|
||||
} else {
|
||||
FilePrinter.printError(FilePrinter.UNHANDLED_EVENT, "UNCODED TIMED MOB DETECTED: " + monster.getId() + "\r\n");
|
||||
}
|
||||
@@ -2373,6 +2368,9 @@ public class MapleMap {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
chr.removeSandboxItems();
|
||||
|
||||
if (chr.isHidden()) {
|
||||
broadcastGMMessage(chr, MaplePacketCreator.spawnEnterPlayerMapObject(chr), false);
|
||||
chr.announce(MaplePacketCreator.getGMEffect(0x10, (byte) 1));
|
||||
@@ -2842,11 +2840,11 @@ public class MapleMap {
|
||||
}
|
||||
|
||||
public void setMapPointBoundings(int px, int py, int h, int w) {
|
||||
mapArea.setBounds(px + 80, py, w - 160, h);
|
||||
mapArea.setBounds(px, py, w, h);
|
||||
}
|
||||
|
||||
public void setMapLineBoundings(int vrTop, int vrBottom, int vrLeft, int vrRight) {
|
||||
mapArea.setBounds(vrLeft + 7, vrTop, vrRight - vrLeft - 14, vrBottom - vrTop);
|
||||
mapArea.setBounds(vrLeft, vrTop, vrRight - vrLeft, vrBottom - vrTop);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -58,6 +58,7 @@ public class MapleMiniDungeon {
|
||||
}
|
||||
|
||||
dispose();
|
||||
timeoutTask = null;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
@@ -241,8 +241,6 @@ public class MaplePlayerShop extends AbstractMapleMapObject {
|
||||
if (c.getPlayer().getMeso() >= price) {
|
||||
if (canBuy(c, newItem)) {
|
||||
c.getPlayer().gainMeso(-price, false);
|
||||
|
||||
if(ServerConstants.USE_ANNOUNCE_SHOPITEMSOLD) announceItemSold(newItem, price); // idea thanks to vcoc
|
||||
owner.gainMeso(price, true);
|
||||
|
||||
SoldItem soldItem = new SoldItem(c.getPlayer().getName(), pItem.getItem().getItemId(), quantity, price);
|
||||
@@ -275,12 +273,6 @@ public class MaplePlayerShop extends AbstractMapleMapObject {
|
||||
}
|
||||
}
|
||||
|
||||
private void announceItemSold(Item item, int mesos) {
|
||||
String qtyStr = (item.getQuantity() > 1) ? " (qty. " + item.getQuantity() + ")" : "";
|
||||
|
||||
owner.dropMessage(6, "[PLAYER SHOP] Item '" + MapleItemInformationProvider.getInstance().getName(item.getItemId()) + "'" + qtyStr + " has been sold for " + mesos + " mesos.");
|
||||
}
|
||||
|
||||
public void broadcastToVisitors(final byte[] packet) {
|
||||
visitorLock.lock();
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user