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:
@@ -65,7 +65,6 @@ public enum MapleBuffStat {
|
||||
SPARK(0x20000000L),
|
||||
MAP_CHAIR(0x40000000L),
|
||||
FINALATTACK(0x80000000L),
|
||||
BATTLESHIP(0xA00000040L), // weird one
|
||||
WATK(0x100000000L),
|
||||
WDEF(0x200000000L),
|
||||
MATK(0x400000000L),
|
||||
|
||||
@@ -200,7 +200,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
private int owlSearch;
|
||||
private long lastfametime, lastUsedCashItem, lastHealed, lastBuyback, lastDeathtime, lastMesoDrop = -1, jailExpiration = -1;
|
||||
private transient int localmaxhp, localmaxmp, localstr, localdex, localluk, localint_, magic, watk;
|
||||
private boolean hidden, canDoor = true, berserk, hasMerchant, whiteChat = false;
|
||||
private boolean hidden, canDoor = true, berserk, hasMerchant, hasSandboxItem = false, whiteChat = false;
|
||||
private int linkedLevel = 0;
|
||||
private String linkedName = null;
|
||||
private boolean finishedDojoTutorial;
|
||||
@@ -479,9 +479,6 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
effLock.lock();
|
||||
chrLock.lock();
|
||||
try {
|
||||
if (this.coolDowns.containsKey(Integer.valueOf(skillId))) {
|
||||
this.coolDowns.remove(Integer.valueOf(skillId));
|
||||
}
|
||||
this.coolDowns.put(Integer.valueOf(skillId), new MapleCoolDownValueHolder(skillId, startTime, length));
|
||||
} finally {
|
||||
chrLock.unlock();
|
||||
@@ -961,6 +958,33 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
public boolean canDoor() {
|
||||
return canDoor;
|
||||
}
|
||||
|
||||
public void setHasSandboxItem() {
|
||||
hasSandboxItem = true;
|
||||
}
|
||||
|
||||
public void removeSandboxItems() { // sandbox idea thanks to Morty
|
||||
if(!hasSandboxItem) return;
|
||||
|
||||
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
|
||||
for(MapleInventoryType invType : MapleInventoryType.values()) {
|
||||
MapleInventory inv = this.getInventory(invType);
|
||||
|
||||
inv.lockInventory();
|
||||
try {
|
||||
for(Item item : new ArrayList<>(inv.list())) {
|
||||
if(MapleInventoryManipulator.isSandboxItem(item)) {
|
||||
MapleInventoryManipulator.removeFromSlot(client, invType, item.getPosition(), item.getQuantity(), false);
|
||||
dropMessage(5, "[" + ii.getName(item.getItemId()) + "] has passed its trial conditions and will be removed from your inventory.");
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
inv.unlockInventory();
|
||||
}
|
||||
}
|
||||
|
||||
hasSandboxItem = false;
|
||||
}
|
||||
|
||||
public FameStatus canGiveFame(MapleCharacter from) {
|
||||
if (gmLevel > 0) {
|
||||
@@ -1789,10 +1813,18 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
return getInventory(ItemConstants.getInventoryType(itemid)).getNextFreeSlot() > -1;
|
||||
}
|
||||
|
||||
public boolean isRidingBattleship() {
|
||||
Integer bv = getBuffedValue(MapleBuffStat.MONSTER_RIDING);
|
||||
return bv != null && bv.equals(Corsair.BATTLE_SHIP);
|
||||
}
|
||||
|
||||
public void announceBattleshipHp() {
|
||||
announce(MaplePacketCreator.skillCooldown(5221999, battleshipHp));
|
||||
}
|
||||
|
||||
public void decreaseBattleshipHp(int decrease) {
|
||||
this.battleshipHp -= decrease;
|
||||
if (battleshipHp <= 0) {
|
||||
this.battleshipHp = 0;
|
||||
Skill battleship = SkillFactory.getSkill(Corsair.BATTLE_SHIP);
|
||||
int cooldown = battleship.getEffect(getSkillLevel(battleship)).getCooldown();
|
||||
announce(MaplePacketCreator.skillCooldown(Corsair.BATTLE_SHIP, cooldown));
|
||||
@@ -1800,7 +1832,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
removeCooldown(5221999);
|
||||
cancelEffectFromBuffStat(MapleBuffStat.MONSTER_RIDING);
|
||||
} else {
|
||||
announce(MaplePacketCreator.skillCooldown(5221999, battleshipHp / 10)); //:D
|
||||
announceBattleshipHp();
|
||||
addCooldown(5221999, 0, Long.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
@@ -2575,8 +2607,9 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
Pair<Integer, String> replace = ii.getReplaceOnExpire(item.getItemId());
|
||||
if (replace.left > 0) {
|
||||
toadd.add(replace.left);
|
||||
if (replace.right != null)
|
||||
if (!replace.right.isEmpty()) {
|
||||
dropMessage(replace.right);
|
||||
}
|
||||
}
|
||||
for (Integer itemid : toadd) {
|
||||
MapleInventoryManipulator.addById(client, itemid, (short) 1);
|
||||
@@ -3032,7 +3065,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
}
|
||||
|
||||
private void debugListAllBuffs() {
|
||||
public void debugListAllBuffs() {
|
||||
effLock.lock();
|
||||
chrLock.lock();
|
||||
try {
|
||||
@@ -3057,7 +3090,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
}
|
||||
|
||||
private void debugListAllBuffsCount() {
|
||||
public void debugListAllBuffsCount() {
|
||||
effLock.lock();
|
||||
chrLock.lock();
|
||||
try {
|
||||
@@ -3568,6 +3601,13 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
Pair<MapleStatEffect, Long> msel = lmse.getRight();
|
||||
msel.getLeft().updateBuffEffect(this, getActiveStatupsFromSourceid(lmse.getLeft()), msel.getRight());
|
||||
}
|
||||
|
||||
if (this.isRidingBattleship()) {
|
||||
List<Pair<MapleBuffStat, Integer>> statups = new ArrayList<>(1);
|
||||
statups.add(new Pair<>(MapleBuffStat.MONSTER_RIDING, 0));
|
||||
this.announce(MaplePacketCreator.giveBuff(1932000, 5221006, statups));
|
||||
this.announceBattleshipHp();
|
||||
}
|
||||
}
|
||||
|
||||
private static MapleBuffStat getSingletonStatupFromEffect(MapleStatEffect mse) {
|
||||
@@ -5805,6 +5845,10 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
ret.getInventory(MapleInventoryType.SETUP).setSlotLimit(rs.getByte("setupslots"));
|
||||
ret.getInventory(MapleInventoryType.ETC).setSlotLimit(rs.getByte("etcslots"));
|
||||
for (Pair<Item, MapleInventoryType> item : ItemFactory.INVENTORY.loadItems(ret.id, !channelserver)) {
|
||||
if(MapleInventoryManipulator.isSandboxItem(item.getLeft())) {
|
||||
ret.setHasSandboxItem();
|
||||
}
|
||||
|
||||
ret.getInventory(item.getRight()).addFromDB(item.getLeft());
|
||||
Item itemz = item.getLeft();
|
||||
if (itemz.getPetId() > -1) {
|
||||
@@ -6015,12 +6059,6 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
for(MapleQuestStatus mqs : loadedQuestStatus.values()) {
|
||||
mqs.resetUpdated();
|
||||
}
|
||||
*/
|
||||
|
||||
loadedQuestStatus.clear();
|
||||
|
||||
ps = con.prepareStatement("SELECT skillid,skilllevel,masterlevel,expiration FROM skills WHERE characterid = ?");
|
||||
@@ -6550,11 +6588,11 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
statup.add(new Pair<>(MapleStat.LUK, tluk));
|
||||
announce(MaplePacketCreator.updatePlayerStats(statup, this));
|
||||
}
|
||||
|
||||
|
||||
public void resetBattleshipHp() {
|
||||
this.battleshipHp = 4000 * getSkillLevel(SkillFactory.getSkill(Corsair.BATTLE_SHIP)) + ((getLevel() - 120) * 2000);
|
||||
this.battleshipHp = 400 * getSkillLevel(SkillFactory.getSkill(Corsair.BATTLE_SHIP)) + ((getLevel() - 120) * 200);
|
||||
}
|
||||
|
||||
|
||||
public void resetEnteredScript() {
|
||||
if (entered.containsKey(map.getId())) {
|
||||
entered.remove(map.getId());
|
||||
|
||||
@@ -64,6 +64,7 @@ import client.inventory.MapleInventoryType;
|
||||
import constants.GameConstants;
|
||||
import constants.ServerConstants;
|
||||
import scripting.AbstractPlayerInteraction;
|
||||
import scripting.event.EventInstanceManager;
|
||||
import scripting.event.EventManager;
|
||||
import scripting.npc.NPCConversationManager;
|
||||
import scripting.npc.NPCScriptManager;
|
||||
@@ -798,8 +799,9 @@ public class MapleClient {
|
||||
player.closePlayerInteractions();
|
||||
QuestScriptManager.getInstance().dispose(this);
|
||||
|
||||
if (player.getEventInstance() != null) {
|
||||
player.getEventInstance().playerDisconnected(player);
|
||||
EventInstanceManager eim = player.getEventInstance();
|
||||
if (eim != null) {
|
||||
eim.playerDisconnected(player);
|
||||
}
|
||||
if (player.getMap() != null) {
|
||||
int mapId = player.getMapId();
|
||||
|
||||
@@ -1285,8 +1285,10 @@ public class Commands {
|
||||
byte b = toDrop.getFlag();
|
||||
b |= ItemConstants.ACCOUNT_SHARING;
|
||||
b |= ItemConstants.UNTRADEABLE;
|
||||
b |= ItemConstants.SANDBOX;
|
||||
|
||||
toDrop.setFlag(b);
|
||||
toDrop.setOwner("TRIAL-MODE");
|
||||
}
|
||||
|
||||
c.getPlayer().getMap().spawnItemDrop(c.getPlayer(), c.getPlayer(), toDrop, c.getPlayer().getPosition(), true, true);
|
||||
|
||||
@@ -77,7 +77,7 @@ public class MapleInventoryManipulator {
|
||||
if (i.hasNext()) {
|
||||
Item eItem = (Item) i.next();
|
||||
short oldQ = eItem.getQuantity();
|
||||
if (oldQ < slotMax && (eItem.getOwner().equals(owner) || owner == null)) {
|
||||
if (oldQ < slotMax && ((eItem.getOwner().equals(owner) || owner == null) && eItem.getFlag() == flag)) {
|
||||
short newQ = (short) Math.min(oldQ + quantity, slotMax);
|
||||
quantity -= (newQ - oldQ);
|
||||
eItem.setQuantity(newQ);
|
||||
@@ -89,6 +89,7 @@ public class MapleInventoryManipulator {
|
||||
}
|
||||
}
|
||||
}
|
||||
boolean sandboxItem = (flag & ItemConstants.SANDBOX) == ItemConstants.SANDBOX;
|
||||
while (quantity > 0 || ItemConstants.isRechargeable(itemId)) {
|
||||
short newQ = (short) Math.min(quantity, slotMax);
|
||||
if (newQ != 0) {
|
||||
@@ -106,6 +107,7 @@ public class MapleInventoryManipulator {
|
||||
nItem.setOwner(owner);
|
||||
}
|
||||
c.announce(MaplePacketCreator.modifyInventory(true, Collections.singletonList(new ModifyInventory(0, nItem))));
|
||||
if(sandboxItem) c.getPlayer().setHasSandboxItem();
|
||||
if ((ItemConstants.isRechargeable(itemId)) && quantity == 0) {
|
||||
break;
|
||||
}
|
||||
@@ -125,6 +127,7 @@ public class MapleInventoryManipulator {
|
||||
return false;
|
||||
}
|
||||
c.announce(MaplePacketCreator.modifyInventory(true, Collections.singletonList(new ModifyInventory(0, nItem))));
|
||||
if(MapleInventoryManipulator.isSandboxItem(nItem)) c.getPlayer().setHasSandboxItem();
|
||||
}
|
||||
} else if (quantity == 1) {
|
||||
Item nEquip = ii.getEquipById(itemId);
|
||||
@@ -140,6 +143,7 @@ public class MapleInventoryManipulator {
|
||||
return false;
|
||||
}
|
||||
c.announce(MaplePacketCreator.modifyInventory(true, Collections.singletonList(new ModifyInventory(0, nEquip))));
|
||||
if(MapleInventoryManipulator.isSandboxItem(nEquip)) c.getPlayer().setHasSandboxItem();
|
||||
} else {
|
||||
throw new RuntimeException("Trying to create equip with non-one quantity");
|
||||
}
|
||||
@@ -173,7 +177,7 @@ public class MapleInventoryManipulator {
|
||||
if (i.hasNext()) {
|
||||
Item eItem = (Item) i.next();
|
||||
short oldQ = eItem.getQuantity();
|
||||
if (oldQ < slotMax && item.getOwner().equals(eItem.getOwner())) {
|
||||
if (oldQ < slotMax && item.getFlag() == eItem.getFlag() && item.getOwner().equals(eItem.getOwner())) {
|
||||
short newQ = (short) Math.min(oldQ + quantity, slotMax);
|
||||
quantity -= (newQ - oldQ);
|
||||
eItem.setQuantity(newQ);
|
||||
@@ -199,10 +203,12 @@ public class MapleInventoryManipulator {
|
||||
return false;
|
||||
}
|
||||
c.announce(MaplePacketCreator.modifyInventory(true, Collections.singletonList(new ModifyInventory(0, nItem))));
|
||||
if(MapleInventoryManipulator.isSandboxItem(nItem)) c.getPlayer().setHasSandboxItem();
|
||||
}
|
||||
} else {
|
||||
Item nItem = new Item(item.getItemId(), (short) 0, quantity, petId);
|
||||
nItem.setExpiration(item.getExpiration());
|
||||
nItem.setFlag(item.getFlag());
|
||||
|
||||
short newSlot = c.getPlayer().getInventory(type).addItem(nItem);
|
||||
if (newSlot == -1) {
|
||||
@@ -211,6 +217,7 @@ public class MapleInventoryManipulator {
|
||||
return false;
|
||||
}
|
||||
c.announce(MaplePacketCreator.modifyInventory(true, Collections.singletonList(new ModifyInventory(0, nItem))));
|
||||
if(MapleInventoryManipulator.isSandboxItem(nItem)) c.getPlayer().setHasSandboxItem();
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
}
|
||||
} else if (quantity == 1) {
|
||||
@@ -221,6 +228,7 @@ public class MapleInventoryManipulator {
|
||||
return false;
|
||||
}
|
||||
c.announce(MaplePacketCreator.modifyInventory(true, Collections.singletonList(new ModifyInventory(0, item))));
|
||||
if(MapleInventoryManipulator.isSandboxItem(item)) c.getPlayer().setHasSandboxItem();
|
||||
} else {
|
||||
FilePrinter.printError(FilePrinter.ITEM, "Tried to pickup Equip id " + item.getItemId() + " containing more than 1 quantity --> " + quantity);
|
||||
c.announce(MaplePacketCreator.getInventoryFull());
|
||||
@@ -625,4 +633,8 @@ public class MapleInventoryManipulator {
|
||||
private static boolean isDroppedItemRestricted(Item it) {
|
||||
return ServerConstants.USE_ERASE_UNTRADEABLE_DROP && ((it.getFlag() & ItemConstants.UNTRADEABLE) == ItemConstants.UNTRADEABLE);
|
||||
}
|
||||
|
||||
public static boolean isSandboxItem(Item it) {
|
||||
return (it.getFlag() & ItemConstants.SANDBOX) == ItemConstants.SANDBOX;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ public final class ItemConstants {
|
||||
public final static int UNTRADEABLE = 0x08;
|
||||
public final static int KARMA_EQP = 0x10;
|
||||
public final static int KARMA_UNTRADEABLE = 0x20; // let 0x20 until it's proven something uses this
|
||||
public final static int SANDBOX = 0x40; // let 0x40 until it's proven something uses this
|
||||
public final static int PET_COME = 0x80;
|
||||
public final static int ACCOUNT_SHARING = 0x100;
|
||||
|
||||
|
||||
@@ -57,9 +57,11 @@ public final class MobDamageMobFriendlyHandler extends AbstractMaplePacketHandle
|
||||
} else if(monster.getId() == 9300093) { //tylus
|
||||
monster.getMap().broadcastMessage(MaplePacketCreator.serverNotice(6, "Tylus has fallen by the overwhelming forces of the ambush."));
|
||||
} else if(monster.getId() == 9300137) { //juliet
|
||||
monster.getMap().broadcastMessage(MaplePacketCreator.serverNotice(6, "Juliet has fainted on the middle of the combat."));
|
||||
monster.getMap().broadcastMessage(MaplePacketCreator.serverNotice(6, "Juliet has fainted in the middle of the combat."));
|
||||
} else if(monster.getId() == 9300138) { //romeo
|
||||
monster.getMap().broadcastMessage(MaplePacketCreator.serverNotice(6, "Romeo has fainted on the middle of the combat."));
|
||||
monster.getMap().broadcastMessage(MaplePacketCreator.serverNotice(6, "Romeo has fainted in the middle of the combat."));
|
||||
} else if(monster.getId() == 9400322 || monster.getId() == 9400327 || monster.getId() == 9400332) {
|
||||
monster.getMap().broadcastMessage(MaplePacketCreator.serverNotice(6, "The Snowman has melted on the heat of the battle."));
|
||||
}
|
||||
|
||||
c.getPlayer().getMap().killFriendlies(monster);
|
||||
|
||||
@@ -263,11 +263,14 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
|
||||
if (!c.hasVotedAlready()){
|
||||
player.announce(MaplePacketCreator.earnTitleMessage("You can vote now! Vote and earn a vote point!"));
|
||||
}
|
||||
*/
|
||||
*/
|
||||
if (player.isGM()){
|
||||
Server.getInstance().broadcastGMMessage(c.getWorld(), MaplePacketCreator.earnTitleMessage((player.gmLevel() < 6 ? "GM " : "Admin ") + player.getName() + " has logged in"));
|
||||
}
|
||||
|
||||
} else {
|
||||
if(player.isRidingBattleship()) {
|
||||
player.announceBattleshipHp();
|
||||
}
|
||||
}
|
||||
|
||||
showDueyNotification(c, player);
|
||||
|
||||
@@ -409,8 +409,12 @@ public final class RingActionHandler extends AbstractMaplePacketHandler {
|
||||
if(guestChr != null && MapleInventoryManipulator.checkSpace(guestChr.getClient(), newItemId, 1, "") && MapleInventoryManipulator.addById(guestChr.getClient(), newItemId, (short) 1, expiration)) {
|
||||
guestChr.dropMessage(6, "[WEDDING] You've been invited to " + groom + " and " + bride + "'s Wedding!");
|
||||
} else {
|
||||
c.getPlayer().sendNote(name, "You've been invited to " + groom + " and " + bride + "'s Wedding! Receive your invitation from Duey!", (byte) 0);
|
||||
|
||||
if(guestChr != null && guestChr.isLoggedinWorld()) {
|
||||
guestChr.dropMessage(6, "[WEDDING] You've been invited to " + groom + " and " + bride + "'s Wedding! Receive your invitation from Duey!");
|
||||
} else {
|
||||
c.getPlayer().sendNote(name, "You've been invited to " + groom + " and " + bride + "'s Wedding! Receive your invitation from Duey!", (byte) 0);
|
||||
}
|
||||
|
||||
Item weddingTicket = new Item(newItemId, (short) 0, (short) 1);
|
||||
weddingTicket.setExpiration(expiration);
|
||||
|
||||
|
||||
@@ -237,10 +237,8 @@ public final class TakeDamageHandler extends AbstractMaplePacketHandler {
|
||||
}
|
||||
chr.addMPHP(-damage, -mpattack);
|
||||
} else {
|
||||
if (chr.getBuffedValue(MapleBuffStat.MONSTER_RIDING) != null) {
|
||||
if (chr.getBuffedValue(MapleBuffStat.MONSTER_RIDING).intValue() == Corsair.BATTLE_SHIP) {
|
||||
chr.decreaseBattleshipHp(damage);
|
||||
}
|
||||
if (chr.isRidingBattleship()) {
|
||||
chr.decreaseBattleshipHp(damage);
|
||||
}
|
||||
chr.addMPHP(-damage, -mpattack);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import constants.ServerConstants;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import client.inventory.manipulator.MapleInventoryManipulator;
|
||||
import server.MapleItemInformationProvider;
|
||||
import server.MapleStatEffect;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
|
||||
@@ -94,8 +95,16 @@ public final class UseItemHandler extends AbstractMaplePacketHandler {
|
||||
|
||||
remove(c, slot);
|
||||
|
||||
ii.getItemEffect(toUse.getItemId()).applyTo(chr);
|
||||
chr.checkBerserk(chr.isHidden());
|
||||
if(toUse.getItemId() != 2022153) {
|
||||
ii.getItemEffect(toUse.getItemId()).applyTo(chr);
|
||||
chr.checkBerserk(chr.isHidden());
|
||||
} else {
|
||||
MapleStatEffect mse = ii.getItemEffect(toUse.getItemId());
|
||||
for(MapleCharacter player : chr.getMap().getCharacters()) {
|
||||
mse.applyTo(player);
|
||||
player.checkBerserk(player.isHidden());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -234,8 +234,7 @@ public class EventInstanceManager {
|
||||
wL.lock();
|
||||
try {
|
||||
chars.put(chr.getId(), chr);
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
wL.unlock();
|
||||
}
|
||||
|
||||
@@ -420,8 +419,7 @@ public class EventInstanceManager {
|
||||
rL.lock();
|
||||
try {
|
||||
return chars.size();
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
rL.unlock();
|
||||
}
|
||||
}
|
||||
@@ -430,8 +428,7 @@ public class EventInstanceManager {
|
||||
rL.lock();
|
||||
try {
|
||||
return chars.get(id);
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
rL.unlock();
|
||||
}
|
||||
}
|
||||
@@ -440,8 +437,7 @@ public class EventInstanceManager {
|
||||
rL.lock();
|
||||
try {
|
||||
return new ArrayList<>(chars.values());
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
rL.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -1883,13 +1883,25 @@ public class MaplePacketCreator {
|
||||
mplew.writeInt(CHAR_MAGIC_SPAWN);
|
||||
mplew.writeShort(0);
|
||||
mplew.write(0);
|
||||
final Item mount = chr.getInventory(MapleInventoryType.EQUIPPED).getItem((short) -18);
|
||||
if (chr.getBuffedValue(MapleBuffStat.MONSTER_RIDING) != null && mount != null) {
|
||||
mplew.writeInt(mount.getItemId());
|
||||
mplew.writeInt(1004);
|
||||
|
||||
Integer bv = chr.getBuffedValue(MapleBuffStat.MONSTER_RIDING);
|
||||
if (bv != null) {
|
||||
if(bv.equals(Corsair.BATTLE_SHIP)) {
|
||||
mplew.writeInt(1932000);
|
||||
mplew.writeInt(Corsair.BATTLE_SHIP);
|
||||
} else {
|
||||
final Item mount = chr.getInventory(MapleInventoryType.EQUIPPED).getItem((short) -18);
|
||||
if(mount != null) {
|
||||
mplew.writeInt(mount.getItemId());
|
||||
mplew.writeInt(1004);
|
||||
} else {
|
||||
mplew.writeLong(0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mplew.writeLong(0);
|
||||
}
|
||||
|
||||
mplew.writeInt(CHAR_MAGIC_SPAWN);
|
||||
mplew.skip(9);
|
||||
mplew.writeInt(CHAR_MAGIC_SPAWN);
|
||||
@@ -2107,7 +2119,7 @@ public class MaplePacketCreator {
|
||||
if (ring != null) {
|
||||
mplew.writeInt(chr.getId());
|
||||
mplew.writeInt(ring.getPartnerChrId());
|
||||
mplew.writeInt(ring.getRingId());
|
||||
mplew.writeInt(ring.getItemId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3967,21 +3979,24 @@ public class MaplePacketCreator {
|
||||
}
|
||||
|
||||
public static byte[] damageMonster(int oid, int damage) {
|
||||
return damageMonster(oid, damage, 0, 0);
|
||||
}
|
||||
|
||||
public static byte[] healMonster(int oid, int heal, int curhp, int maxhp) {
|
||||
return damageMonster(oid, -heal, curhp, maxhp);
|
||||
}
|
||||
|
||||
private static byte[] damageMonster(int oid, int damage, int curhp, int maxhp) {
|
||||
final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
|
||||
mplew.writeShort(SendOpcode.DAMAGE_MONSTER.getValue());
|
||||
mplew.writeInt(oid);
|
||||
mplew.write(0);
|
||||
mplew.writeInt(damage);
|
||||
mplew.write(0);
|
||||
mplew.write(0);
|
||||
mplew.write(0);
|
||||
mplew.writeInt(curhp);
|
||||
mplew.writeInt(maxhp);
|
||||
return mplew.getPacket();
|
||||
}
|
||||
|
||||
public static byte[] healMonster(int oid, int heal) {
|
||||
return damageMonster(oid, -heal);
|
||||
}
|
||||
|
||||
|
||||
public static byte[] updateBuddylist(Collection<BuddylistEntry> buddylist) {
|
||||
final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
|
||||
mplew.writeShort(SendOpcode.BUDDYLIST.getValue());
|
||||
|
||||
Reference in New Issue
Block a user