Knights' Seal & I. MaxHP + Adherent mob status + Script point-warps
Fixed Seal skill not working for Blaze Wizard. Added a check against Seal skill on bosses. Reviewed improper usage of "random spawn point arrival" at several warps on scripts. Refactored CPQ modules fetching players from the channel storage, this should be unneeded after a recent update on the player object from MPC. Added door objects as a visible map object for the player server-side view component. Fixed a few scenarios where mobs would unexpectedly show up impervious to mob status. Fixed scenario where a player wouldn't receive disease informations from other players after changing maps. Fixed some magic-type skills (such as Magic Claw or Freeze) not displaying damage value for other players when the player is within melee-range from the mob. Added check for whether a given quest is scripted before trying to find the script. Fixed registering items onto MTS leading to loss of a few of its properties (expiration, item level, etc). Fixed "Improved MaxHP" skill gains not working for Thunderbreakers. Refactored pet autopot to also apply on HP/MP consumption by items/skills. Added portal sound effect on Mystic Doors.
This commit is contained in:
@@ -677,6 +677,7 @@ public class Server {
|
||||
MapleCharacter player = c.getPlayer();
|
||||
if(player != null && player.isLoggedinWorld()) {
|
||||
player.announceDiseases();
|
||||
player.collectDiseases();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1111,18 +1112,25 @@ public class Server {
|
||||
|
||||
public MapleGuild getGuild(int id, int world, MapleCharacter mc) {
|
||||
synchronized (guilds) {
|
||||
if (guilds.get(id) != null) {
|
||||
return guilds.get(id);
|
||||
MapleGuild g = guilds.get(id);
|
||||
if (g != null) {
|
||||
return g;
|
||||
}
|
||||
MapleGuild g = new MapleGuild(id, world);
|
||||
|
||||
g = new MapleGuild(id, world);
|
||||
if (g.getId() == -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if(mc != null) {
|
||||
mc.setMGC(g.getMGC(mc.getId()));
|
||||
if(g.getMGC(mc.getId()) == null) System.out.println("null for " + mc.getName() + " when loading guild " + id);
|
||||
g.getMGC(mc.getId()).setCharacter(mc);
|
||||
MapleGuildCharacter mgc = g.getMGC(mc.getId());
|
||||
if (mgc != null) {
|
||||
mc.setMGC(mgc);
|
||||
mgc.setCharacter(mc);
|
||||
} else {
|
||||
FilePrinter.printError(FilePrinter.GUILD_CHAR_ERROR, "Could not find " + mc.getName() + " when loading guild " + id + ".");
|
||||
}
|
||||
|
||||
g.setOnline(mc.getId(), true, mc.getClient().getChannel());
|
||||
}
|
||||
|
||||
|
||||
@@ -653,16 +653,16 @@ public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandl
|
||||
|
||||
// Find the base damage to base futher calculations on.
|
||||
// Several skills have their own formula in this section.
|
||||
long calcDmgMax = 0;
|
||||
long calcDmgMax = 0;
|
||||
|
||||
if(magic && ret.skill != 0) {
|
||||
calcDmgMax = (chr.getTotalMagic() * chr.getTotalMagic() / 1000 + chr.getTotalMagic()) / 30 + chr.getTotalInt() / 200;
|
||||
if(magic && ret.skill != 0) { // thanks onechord for noticing a few false positives stemming from maxdmg as 0
|
||||
calcDmgMax = (long) (Math.ceil((chr.getTotalMagic() * Math.ceil(chr.getTotalMagic() / 1000.0) + chr.getTotalMagic()) / 30.0) + Math.ceil(chr.getTotalInt() / 200.0));
|
||||
} else if(ret.skill == 4001344 || ret.skill == NightWalker.LUCKY_SEVEN || ret.skill == NightLord.TRIPLE_THROW) {
|
||||
calcDmgMax = (chr.getTotalLuk() * 5) * chr.getTotalWatk() / 100;
|
||||
calcDmgMax = (long) ((chr.getTotalLuk() * 5) * Math.ceil(chr.getTotalWatk() / 100.0));
|
||||
} else if(ret.skill == DragonKnight.DRAGON_ROAR) {
|
||||
calcDmgMax = (chr.getTotalStr() * 4 + chr.getTotalDex()) * chr.getTotalWatk() / 100;
|
||||
calcDmgMax = (long) ((chr.getTotalStr() * 4 + chr.getTotalDex()) * Math.ceil(chr.getTotalWatk() / 100.0));
|
||||
} else if(ret.skill == NightLord.VENOMOUS_STAR || ret.skill == Shadower.VENOMOUS_STAB) {
|
||||
calcDmgMax = (int) (18.5 * (chr.getTotalStr() + chr.getTotalLuk()) + chr.getTotalDex() * 2) / 100 * chr.calculateMaxBaseDamage(chr.getTotalWatk());
|
||||
calcDmgMax = (long) (Math.ceil((18.5 * (chr.getTotalStr() + chr.getTotalLuk()) + chr.getTotalDex() * 2) / 100.0) * chr.calculateMaxBaseDamage(chr.getTotalWatk()));
|
||||
} else {
|
||||
calcDmgMax = chr.calculateMaxBaseDamage(chr.getTotalWatk());
|
||||
}
|
||||
|
||||
@@ -124,7 +124,11 @@ public final class AllianceOperationHandler extends AbstractMaplePacketHandler {
|
||||
Server.getInstance().resetAllianceGuildPlayersRank(guildid);
|
||||
|
||||
chr.getMGC().setAllianceRank(2);
|
||||
Server.getInstance().getGuild(chr.getGuildId()).getMGC(chr.getId()).setAllianceRank(2);
|
||||
MapleGuild g = Server.getInstance().getGuild(chr.getGuildId());
|
||||
if (g != null) {
|
||||
g.getMGC(chr.getId()).setAllianceRank(2);
|
||||
}
|
||||
|
||||
chr.saveGuildStatus();
|
||||
|
||||
Server.getInstance().allianceMessage(alliance.getId(), MaplePacketCreator.addGuildToAlliance(alliance, guildid, c), -1, -1);
|
||||
|
||||
@@ -33,7 +33,6 @@ import client.MapleBuffStat;
|
||||
import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import client.MapleJob;
|
||||
import client.MapleStat;
|
||||
import client.Skill;
|
||||
import client.SkillFactory;
|
||||
import constants.GameConstants;
|
||||
@@ -47,6 +46,7 @@ import constants.skills.Rogue;
|
||||
import constants.skills.WindArcher;
|
||||
|
||||
public final class CloseRangeDamageHandler extends AbstractDealDamageHandler {
|
||||
|
||||
@Override
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
|
||||
@@ -152,6 +152,12 @@ public final class EnterMTSHandler extends AbstractMaplePacketHandler {
|
||||
equip.setWdef((short) rs.getInt("wdef"));
|
||||
equip.setUpgradeSlots((byte) rs.getInt("upgradeslots"));
|
||||
equip.setLevel((byte) rs.getInt("level"));
|
||||
equip.setItemLevel(rs.getByte("itemlevel"));
|
||||
equip.setItemExp(rs.getInt("itemexp"));
|
||||
equip.setRingId(rs.getInt("ringid"));
|
||||
equip.setExpiration(rs.getLong("expiration"));
|
||||
equip.setGiftFrom(rs.getString("giftFrom"));
|
||||
|
||||
items.add(new MTSItemInfo((Item) equip, rs.getInt("price") + 100 + (int) (rs.getInt("price") * 0.1), rs.getInt("id"), rs.getInt("seller"), rs.getString("sellername"), rs.getString("sell_ends")));
|
||||
}
|
||||
}
|
||||
@@ -209,7 +215,12 @@ public final class EnterMTSHandler extends AbstractMaplePacketHandler {
|
||||
equip.setWdef((short) rs.getInt("wdef"));
|
||||
equip.setUpgradeSlots((byte) rs.getInt("upgradeslots"));
|
||||
equip.setLevel((byte) rs.getInt("level"));
|
||||
equip.setItemLevel(rs.getByte("itemlevel"));
|
||||
equip.setItemExp(rs.getInt("itemexp"));
|
||||
equip.setRingId(rs.getInt("ringid"));
|
||||
equip.setFlag((short) rs.getInt("flag"));
|
||||
equip.setExpiration(rs.getLong("expiration"));
|
||||
equip.setGiftFrom(rs.getString("giftFrom"));
|
||||
items.add(new MTSItemInfo((Item) equip, rs.getInt("price"), rs.getInt("id"), rs.getInt("seller"), rs.getString("sellername"), rs.getString("sell_ends")));
|
||||
}
|
||||
}
|
||||
@@ -256,7 +267,12 @@ public final class EnterMTSHandler extends AbstractMaplePacketHandler {
|
||||
equip.setWdef((short) rs.getInt("wdef"));
|
||||
equip.setUpgradeSlots((byte) rs.getInt("upgradeslots"));
|
||||
equip.setLevel((byte) rs.getInt("level"));
|
||||
equip.setItemLevel(rs.getByte("itemlevel"));
|
||||
equip.setItemExp(rs.getInt("itemexp"));
|
||||
equip.setRingId(rs.getInt("ringid"));
|
||||
equip.setFlag((short) rs.getInt("flag"));
|
||||
equip.setExpiration(rs.getLong("expiration"));
|
||||
equip.setGiftFrom(rs.getString("giftFrom"));
|
||||
items.add(new MTSItemInfo((Item) equip, rs.getInt("price"), rs.getInt("id"), rs.getInt("seller"), rs.getString("sellername"), rs.getString("sell_ends")));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,48 +160,55 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
|
||||
}
|
||||
if (!i.getInventoryType().equals(MapleInventoryType.EQUIP)) {
|
||||
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, expiration, giftFrom, seller, price, owner, sellername, sell_ends) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
ps.setInt(1, 1);
|
||||
ps.setInt(2, (int) invType.getType());
|
||||
ps.setInt(3, item.getItemId());
|
||||
ps.setInt(4, quantity);
|
||||
ps.setInt(5, c.getPlayer().getId());
|
||||
ps.setInt(6, price);
|
||||
ps.setString(7, item.getOwner());
|
||||
ps.setString(8, c.getPlayer().getName());
|
||||
ps.setString(9, date);
|
||||
ps.setLong(5, item.getExpiration());
|
||||
ps.setString(6, item.getGiftFrom());
|
||||
ps.setInt(7, c.getPlayer().getId());
|
||||
ps.setInt(8, price);
|
||||
ps.setString(9, item.getOwner());
|
||||
ps.setString(10, c.getPlayer().getName());
|
||||
ps.setString(11, date);
|
||||
} else {
|
||||
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, expiration, giftFrom, 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, itemexp, itemlevel, ringid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
ps.setInt(1, 1);
|
||||
ps.setInt(2, (int) invType.getType());
|
||||
ps.setInt(3, equip.getItemId());
|
||||
ps.setInt(4, quantity);
|
||||
ps.setInt(5, c.getPlayer().getId());
|
||||
ps.setInt(6, price);
|
||||
ps.setInt(7, equip.getUpgradeSlots());
|
||||
ps.setInt(8, equip.getLevel());
|
||||
ps.setInt(9, equip.getStr());
|
||||
ps.setInt(10, equip.getDex());
|
||||
ps.setInt(11, equip.getInt());
|
||||
ps.setInt(12, equip.getLuk());
|
||||
ps.setInt(13, equip.getHp());
|
||||
ps.setInt(14, equip.getMp());
|
||||
ps.setInt(15, equip.getWatk());
|
||||
ps.setInt(16, equip.getMatk());
|
||||
ps.setInt(17, equip.getWdef());
|
||||
ps.setInt(18, equip.getMdef());
|
||||
ps.setInt(19, equip.getAcc());
|
||||
ps.setInt(20, equip.getAvoid());
|
||||
ps.setInt(21, equip.getHands());
|
||||
ps.setInt(22, equip.getSpeed());
|
||||
ps.setInt(23, equip.getJump());
|
||||
ps.setInt(24, 0);
|
||||
ps.setString(25, equip.getOwner());
|
||||
ps.setString(26, c.getPlayer().getName());
|
||||
ps.setString(27, date);
|
||||
ps.setInt(28, equip.getVicious());
|
||||
ps.setInt(29, equip.getFlag());
|
||||
ps.setLong(5, equip.getExpiration());
|
||||
ps.setString(6, equip.getGiftFrom());
|
||||
ps.setInt(7, c.getPlayer().getId());
|
||||
ps.setInt(8, price);
|
||||
ps.setInt(9, equip.getUpgradeSlots());
|
||||
ps.setInt(10, equip.getLevel());
|
||||
ps.setInt(11, equip.getStr());
|
||||
ps.setInt(12, equip.getDex());
|
||||
ps.setInt(13, equip.getInt());
|
||||
ps.setInt(14, equip.getLuk());
|
||||
ps.setInt(15, equip.getHp());
|
||||
ps.setInt(16, equip.getMp());
|
||||
ps.setInt(17, equip.getWatk());
|
||||
ps.setInt(18, equip.getMatk());
|
||||
ps.setInt(19, equip.getWdef());
|
||||
ps.setInt(20, equip.getMdef());
|
||||
ps.setInt(21, equip.getAcc());
|
||||
ps.setInt(22, equip.getAvoid());
|
||||
ps.setInt(23, equip.getHands());
|
||||
ps.setInt(24, equip.getSpeed());
|
||||
ps.setInt(25, equip.getJump());
|
||||
ps.setInt(26, 0);
|
||||
ps.setString(27, equip.getOwner());
|
||||
ps.setString(28, c.getPlayer().getName());
|
||||
ps.setString(29, date);
|
||||
ps.setInt(30, equip.getVicious());
|
||||
ps.setInt(31, equip.getFlag());
|
||||
ps.setInt(32, equip.getItemExp());
|
||||
ps.setByte(33, equip.getItemLevel()); // thanks Jefe for noticing missing itemlevel labels
|
||||
ps.setInt(34, equip.getRingId());
|
||||
}
|
||||
ps.executeUpdate();
|
||||
ps.close();
|
||||
@@ -320,8 +327,13 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
|
||||
equip.setWdef((short) rs.getInt("wdef"));
|
||||
equip.setUpgradeSlots((byte) rs.getInt("upgradeslots"));
|
||||
equip.setLevel((byte) rs.getInt("level"));
|
||||
equip.setItemLevel(rs.getByte("itemlevel"));
|
||||
equip.setItemExp(rs.getInt("itemexp"));
|
||||
equip.setRingId(rs.getInt("ringid"));
|
||||
equip.setVicious((byte) rs.getInt("vicious"));
|
||||
equip.setFlag((short) rs.getInt("flag"));
|
||||
equip.setExpiration(rs.getLong("expiration"));
|
||||
equip.setGiftFrom(rs.getString("giftFrom"));
|
||||
equip.setPosition(c.getPlayer().getInventory(ItemConstants.getInventoryType(rs.getInt("itemid"))).getNextFreeSlot());
|
||||
i = equip.copy();
|
||||
}
|
||||
@@ -569,6 +581,11 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
|
||||
equip.setUpgradeSlots((byte) rs.getInt("upgradeslots"));
|
||||
equip.setLevel((byte) rs.getInt("level"));
|
||||
equip.setFlag((short) rs.getInt("flag"));
|
||||
equip.setItemLevel(rs.getByte("itemlevel"));
|
||||
equip.setItemExp(rs.getInt("itemexp"));
|
||||
equip.setRingId(rs.getInt("ringid"));
|
||||
equip.setExpiration(rs.getLong("expiration"));
|
||||
equip.setGiftFrom(rs.getString("giftFrom"));
|
||||
items.add(new MTSItemInfo((Item) equip, rs.getInt("price"), rs.getInt("id"), rs.getInt("seller"), rs.getString("sellername"), rs.getString("sell_ends")));
|
||||
}
|
||||
}
|
||||
@@ -623,7 +640,12 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
|
||||
equip.setWdef((short) rse.getInt("wdef"));
|
||||
equip.setUpgradeSlots((byte) rse.getInt("upgradeslots"));
|
||||
equip.setLevel((byte) rse.getInt("level"));
|
||||
equip.setItemLevel(rs.getByte("itemlevel"));
|
||||
equip.setItemExp(rs.getInt("itemexp"));
|
||||
equip.setRingId(rs.getInt("ringid"));
|
||||
equip.setFlag((short) rs.getInt("flag"));
|
||||
equip.setExpiration(rs.getLong("expiration"));
|
||||
equip.setGiftFrom(rs.getString("giftFrom"));
|
||||
items.add(new MTSItemInfo((Item) equip, rse.getInt("price"), rse.getInt("id"), rse.getInt("seller"), rse.getString("sellername"), rse.getString("sell_ends")));
|
||||
}
|
||||
}
|
||||
@@ -686,7 +708,12 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
|
||||
equip.setWdef((short) rs.getInt("wdef"));
|
||||
equip.setUpgradeSlots((byte) rs.getInt("upgradeslots"));
|
||||
equip.setLevel((byte) rs.getInt("level"));
|
||||
equip.setItemLevel(rs.getByte("itemlevel"));
|
||||
equip.setItemExp(rs.getInt("itemexp"));
|
||||
equip.setRingId(rs.getInt("ringid"));
|
||||
equip.setFlag((short) rs.getInt("flag"));
|
||||
equip.setExpiration(rs.getLong("expiration"));
|
||||
equip.setGiftFrom(rs.getString("giftFrom"));
|
||||
items.add(new MTSItemInfo((Item) equip, rs.getInt("price"), rs.getInt("id"), rs.getInt("seller"), rs.getString("sellername"), rs.getString("sell_ends")));
|
||||
}
|
||||
}
|
||||
@@ -747,7 +774,12 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
|
||||
equip.setWdef((short) rs.getInt("wdef"));
|
||||
equip.setUpgradeSlots((byte) rs.getInt("upgradeslots"));
|
||||
equip.setLevel((byte) rs.getInt("level"));
|
||||
equip.setItemLevel(rs.getByte("itemlevel"));
|
||||
equip.setItemExp(rs.getInt("itemexp"));
|
||||
equip.setRingId(rs.getInt("ringid"));
|
||||
equip.setFlag((short) rs.getInt("flag"));
|
||||
equip.setExpiration(rs.getLong("expiration"));
|
||||
equip.setGiftFrom(rs.getString("giftFrom"));
|
||||
items.add(new MTSItemInfo((Item) equip, rs.getInt("price"), rs.getInt("id"), rs.getInt("seller"), rs.getString("sellername"), rs.getString("sell_ends")));
|
||||
}
|
||||
}
|
||||
@@ -841,7 +873,12 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
|
||||
equip.setWdef((short) rs.getInt("wdef"));
|
||||
equip.setUpgradeSlots((byte) rs.getInt("upgradeslots"));
|
||||
equip.setLevel((byte) rs.getInt("level"));
|
||||
equip.setItemLevel(rs.getByte("itemlevel"));
|
||||
equip.setItemExp(rs.getInt("itemexp"));
|
||||
equip.setRingId(rs.getInt("ringid"));
|
||||
equip.setFlag((short) rs.getInt("flag"));
|
||||
equip.setExpiration(rs.getLong("expiration"));
|
||||
equip.setGiftFrom(rs.getString("giftFrom"));
|
||||
items.add(new MTSItemInfo((Item) equip, rs.getInt("price"), rs.getInt("id"), rs.getInt("seller"), rs.getString("sellername"), rs.getString("sell_ends")));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,9 +62,13 @@ public final class MagicDamageHandler extends AbstractDealDamageHandler {
|
||||
c.announce(MaplePacketCreator.getEnergy("energy", chr.getDojoEnergy()));
|
||||
}
|
||||
|
||||
int charge = (attack.skill == Evan.FIRE_BREATH || attack.skill == Evan.ICE_BREATH || attack.skill == FPArchMage.BIG_BANG || attack.skill == ILArchMage.BIG_BANG || attack.skill == Bishop.BIG_BANG) ? attack.charge : -1;
|
||||
byte[] packet = MaplePacketCreator.magicAttack(chr, attack.skill, attack.skilllevel, attack.stance, attack.numAttackedAndDamage, attack.allDamage, charge, attack.speed, attack.direction, attack.display);
|
||||
|
||||
byte[] packet;
|
||||
if ((attack.skill == Evan.FIRE_BREATH || attack.skill == Evan.ICE_BREATH || attack.skill == FPArchMage.BIG_BANG || attack.skill == ILArchMage.BIG_BANG || attack.skill == Bishop.BIG_BANG)) {
|
||||
packet = MaplePacketCreator.magicAttack(chr, attack.skill, attack.skilllevel, attack.stance, attack.numAttackedAndDamage, attack.allDamage, attack.charge, attack.speed, attack.direction, attack.display);
|
||||
} else {
|
||||
packet = MaplePacketCreator.closeRangeAttack(chr, attack.skill, attack.skilllevel, attack.stance, attack.numAttackedAndDamage, attack.allDamage, attack.speed, attack.direction, attack.display);
|
||||
}
|
||||
|
||||
chr.getMap().broadcastMessage(chr, packet, false, true);
|
||||
MapleStatEffect effect = attack.getAttackEffect(chr, null);
|
||||
Skill skill = SkillFactory.getSkill(attack.skill);
|
||||
|
||||
@@ -36,7 +36,6 @@ import server.life.MobSkillFactory;
|
||||
import server.maps.MapleMap;
|
||||
import server.maps.MapleMapObject;
|
||||
import server.maps.MapleMapObjectType;
|
||||
import server.movement.LifeMovementFragment;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.Pair;
|
||||
import tools.Randomizer;
|
||||
|
||||
@@ -4,167 +4,39 @@
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
Copyleft (L) 2016 - 2018 RonanLana (HeavenMS)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package net.server.channel.handlers;
|
||||
|
||||
import client.MapleClient;
|
||||
import client.MapleCharacter;
|
||||
import client.inventory.Item;
|
||||
import client.inventory.MapleInventory;
|
||||
import client.inventory.MapleInventoryType;
|
||||
import client.processor.PetAutopotProcessor;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import client.inventory.manipulator.MapleInventoryManipulator;
|
||||
import server.MapleItemInformationProvider;
|
||||
import server.MapleStatEffect;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
import constants.ServerConstants;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Ronan - multi-pot consumption feature
|
||||
*/
|
||||
public final class PetAutoPotHandler extends AbstractMaplePacketHandler {
|
||||
short slot;
|
||||
int itemId;
|
||||
Item toUse;
|
||||
List<Item> toUseList;
|
||||
|
||||
boolean hasHpGain, hasMpGain;
|
||||
int maxHp, maxMp, curHp, curMp;
|
||||
double incHp, incMp;
|
||||
|
||||
@Override
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
if (!c.getPlayer().isAlive()) {
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
|
||||
slea.readByte();
|
||||
slea.readLong();
|
||||
slea.readInt();
|
||||
slot = slea.readShort();
|
||||
itemId = slea.readInt();
|
||||
short slot = slea.readShort();
|
||||
int itemId = slea.readInt();
|
||||
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
MapleInventory useInv = chr.getInventory(MapleInventoryType.USE);
|
||||
|
||||
int useCount = 0, qtyCount = 0;
|
||||
MapleStatEffect stat = null;
|
||||
|
||||
useInv.lockInventory();
|
||||
try {
|
||||
toUse = useInv.getItem(slot);
|
||||
|
||||
if (toUse != null) {
|
||||
if (toUse.getItemId() != itemId) {
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
|
||||
toUseList = null;
|
||||
|
||||
// from now on, toUse becomes the "cursor" for the current pot being used
|
||||
if (toUse.getQuantity() <= 0) {
|
||||
if (!cursorOnNextAvailablePot(chr)) {
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
stat = MapleItemInformationProvider.getInstance().getItemEffect(toUse.getItemId());
|
||||
hasHpGain = stat.getHp() > 0 || stat.getHpRate() > 0.0;
|
||||
hasMpGain = stat.getMp() > 0 || stat.getMpRate() > 0.0;
|
||||
|
||||
maxHp = chr.getCurrentMaxHp();
|
||||
maxMp = chr.getCurrentMaxMp();
|
||||
|
||||
curHp = chr.getHp();
|
||||
curMp = chr.getMp();
|
||||
|
||||
incHp = stat.getHp();
|
||||
if(incHp <= 0 && hasHpGain) incHp = Math.ceil(maxHp * stat.getHpRate());
|
||||
|
||||
incMp = stat.getMp();
|
||||
if(incMp <= 0 && hasMpGain) incMp = Math.ceil(maxMp * stat.getMpRate());
|
||||
|
||||
if (ServerConstants.USE_COMPULSORY_AUTOPOT) {
|
||||
if (hasHpGain) {
|
||||
qtyCount = (int) Math.ceil(((ServerConstants.PET_AUTOHP_RATIO * maxHp) - curHp) / incHp);
|
||||
}
|
||||
|
||||
if (hasMpGain) {
|
||||
qtyCount = Math.max(qtyCount, (int) Math.ceil(((ServerConstants.PET_AUTOMP_RATIO * maxMp) - curMp) / incMp));
|
||||
}
|
||||
} else {
|
||||
qtyCount = 1; // non-compulsory autopot concept thanks to marcuswoon
|
||||
}
|
||||
|
||||
while (true) {
|
||||
short qtyToUse = (short) Math.min(qtyCount, toUse.getQuantity());
|
||||
MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.USE, slot, qtyToUse, false);
|
||||
|
||||
curHp += (incHp * qtyToUse);
|
||||
curMp += (incMp * qtyToUse);
|
||||
|
||||
useCount += qtyToUse;
|
||||
qtyCount -= qtyToUse;
|
||||
|
||||
if(toUse.getQuantity() == 0 && qtyCount > 0) {
|
||||
// depleted out the current slot, fetch for more
|
||||
|
||||
if(!cursorOnNextAvailablePot(chr)) {
|
||||
break; // no more pots available
|
||||
}
|
||||
} else {
|
||||
break; // gracefully finished it's job, quit the loop
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
useInv.unlockInventory();
|
||||
}
|
||||
|
||||
for (int i = 0; i < useCount; i++) {
|
||||
stat.applyTo(chr);
|
||||
}
|
||||
|
||||
chr.announce(MaplePacketCreator.enableActions());
|
||||
PetAutopotProcessor.runAutopotAction(c, slot, itemId);
|
||||
}
|
||||
|
||||
private boolean cursorOnNextAvailablePot(MapleCharacter chr) {
|
||||
if(toUseList == null) {
|
||||
toUseList = chr.getInventory(MapleInventoryType.USE).linkedListById(itemId);
|
||||
}
|
||||
|
||||
toUse = null;
|
||||
while(!toUseList.isEmpty()) {
|
||||
Item it = toUseList.remove(0);
|
||||
|
||||
if(it.getQuantity() > 0) {
|
||||
toUse = it;
|
||||
slot = it.getPosition();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,11 +268,12 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
|
||||
if(familyEntry != null) {
|
||||
familyEntry.setCharacter(player);
|
||||
player.setFamilyEntry(familyEntry);
|
||||
|
||||
c.announce(MaplePacketCreator.getFamilyInfo(familyEntry));
|
||||
familyEntry.announceToSenior(MaplePacketCreator.sendFamilyLoginNotice(player.getName(), true), true);
|
||||
} else {
|
||||
FilePrinter.printError(FilePrinter.FAMILY_ERROR, "Player " + player.getName() + "'s family doesn't have an entry for them. (" + f.getID() + ")");
|
||||
}
|
||||
c.announce(MaplePacketCreator.getFamilyInfo(familyEntry));
|
||||
familyEntry.announceToSenior(MaplePacketCreator.sendFamilyLoginNotice(player.getName(), true), true);
|
||||
} else {
|
||||
FilePrinter.printError(FilePrinter.FAMILY_ERROR, "Player " + player.getName() + " has an invalid family ID. (" + player.getFamilyId() + ")");
|
||||
c.announce(MaplePacketCreator.getFamilyInfo(null));
|
||||
@@ -379,8 +380,6 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
|
||||
final List<Pair<MapleDisease, Integer>> debuff = Collections.singletonList(new Pair<>(e.getKey(), Integer.valueOf(e.getValue().getRight().getX())));
|
||||
c.announce(MaplePacketCreator.giveDebuff(debuff, e.getValue().getRight()));
|
||||
}
|
||||
|
||||
player.announceDiseases();
|
||||
}
|
||||
} else {
|
||||
if(player.isRidingBattleship()) {
|
||||
|
||||
@@ -26,6 +26,8 @@ import client.MapleClient;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import server.life.MapleMonster;
|
||||
import server.maps.MapleMapObject;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.Pair;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
@@ -48,5 +50,21 @@ public final class PlayerMapTransitionHandler extends AbstractMaplePacketHandler
|
||||
final List<Pair<MapleBuffStat, Integer>> stat = Collections.singletonList(new Pair<>(MapleBuffStat.HOMING_BEACON, 0));
|
||||
chr.announce(MaplePacketCreator.giveBuff(1, beaconid, stat));
|
||||
}
|
||||
|
||||
for (MapleMapObject mo : chr.getMap().getMonsters()) { // thanks BHB, IxianMace, Jefe for noticing several issues regarding mob statuses (such as freeze)
|
||||
MapleMonster m = (MapleMonster) mo;
|
||||
if (m.getSpawnEffect() == 0 || m.getHp() < m.getMaxHp()) { // avoid effect-spawning mobs
|
||||
if (m.getController() == chr) {
|
||||
c.announce(MaplePacketCreator.stopControllingMonster(m.getObjectId()));
|
||||
m.sendDestroyData(c);
|
||||
m.aggroRedirectController();
|
||||
} else {
|
||||
m.sendDestroyData(c);
|
||||
}
|
||||
|
||||
m.aggroSwitchController(chr, false);
|
||||
m.sendSpawnData(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -244,7 +244,7 @@ public final class TakeDamageHandler extends AbstractMaplePacketHandler {
|
||||
Skill highDef = SkillFactory.getSkill(Aran.HIGH_DEFENSE);
|
||||
int hdLevel = chr.getSkillLevel(highDef);
|
||||
if (highDef != null && hdLevel > 0) {
|
||||
damage *= (highDef.getEffect(hdLevel).getX() / 1000.0);
|
||||
damage *= Math.ceil(highDef.getEffect(hdLevel).getX() / 1000.0);
|
||||
}
|
||||
}
|
||||
Integer mesoguard = chr.getBuffedValue(MapleBuffStat.MESOGUARD);
|
||||
|
||||
@@ -580,14 +580,6 @@ public class MapleGuild {
|
||||
}
|
||||
|
||||
membersLock.lock();
|
||||
members.sort(new Comparator<MapleGuildCharacter>() {
|
||||
@Override
|
||||
public int compare(MapleGuildCharacter t, MapleGuildCharacter o) {
|
||||
if(t.getGuildRank() <= 1 && o.getGuildRank() > 1) return -1;
|
||||
else if(t.getGuildRank() > 1 && o.getGuildRank() <= 1) return 1;
|
||||
else return 0;
|
||||
}
|
||||
});
|
||||
try {
|
||||
this.broadcast(MaplePacketCreator.changeRank(mgc));
|
||||
} finally {
|
||||
@@ -597,7 +589,7 @@ public class MapleGuild {
|
||||
|
||||
public void setGuildNotice(String notice) {
|
||||
this.notice = notice;
|
||||
writeToDB(false);
|
||||
this.writeToDB(false);
|
||||
|
||||
membersLock.lock();
|
||||
try {
|
||||
|
||||
@@ -130,7 +130,7 @@ public class MapleParty {
|
||||
public Collection<MaplePartyCharacter> getMembers() {
|
||||
lock.lock();
|
||||
try {
|
||||
return Collections.unmodifiableList(members);
|
||||
return new LinkedList<>(members);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
@@ -139,7 +139,7 @@ public class MapleParty {
|
||||
public List<MaplePartyCharacter> getPartyMembers() {
|
||||
lock.lock();
|
||||
try {
|
||||
return Collections.unmodifiableList(members);
|
||||
return new LinkedList<>(members);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user