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:
ronancpl
2018-06-13 00:03:46 -03:00
parent 0b8d3a0b2b
commit dddfdcf315
46 changed files with 5494 additions and 3796 deletions
+41 -21
View File
@@ -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);
}
+12 -10
View File
@@ -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();
}
}
}
+4 -3
View File
@@ -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()) {
+14 -16
View File
@@ -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);
}
/**
+1
View File
@@ -58,6 +58,7 @@ public class MapleMiniDungeon {
}
dispose();
timeoutTask = null;
} finally {
lock.unlock();
}
-8
View File
@@ -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 {