Reworked Autoassigner & Hero's Will & Trade + Visual NX + New commands
Reworked autoassigner (improved limits between required secondary and surplus primary stats). Hero's will removes most of diseases, tonic removes slow. Added visual info for collected NX cards. Added commands cake (cake boss with customizable HP) and setgmlevel. Reworked Trade system now checking for slots smartly (instead of just checking for empty slots).
This commit is contained in:
@@ -1528,7 +1528,11 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
this.getMap().pickItemDrop(pickupPacket, mapitem);
|
||||
} else if(mapitem.getItemId() == 4031865 || mapitem.getItemId() == 4031866) {
|
||||
// Add NX to account, show effect and make item disappear
|
||||
this.getCashShop().gainCash(1, mapitem.getItemId() == 4031865 ? 100 : 250);
|
||||
int nxGain = mapitem.getItemId() == 4031865 ? 100 : 250;
|
||||
this.getCashShop().gainCash(1, nxGain);
|
||||
|
||||
showHint("You have earned #e#b" + nxGain + " NX#k#n. (" + this.getCashShop().getCash(1) + " NX)");
|
||||
|
||||
this.getMap().pickItemDrop(pickupPacket, mapitem);
|
||||
} else if (MapleInventoryManipulator.addFromDrop(client, mapitem.getItem(), true)) {
|
||||
this.getMap().pickItemDrop(pickupPacket, mapitem);
|
||||
@@ -1597,7 +1601,10 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
} else if(mapitem.getItemId() == 4031865 || mapitem.getItemId() == 4031866) {
|
||||
// Add NX to account, show effect and make item disappear
|
||||
this.getCashShop().gainCash(1, mapitem.getItemId() == 4031865 ? 100 : 250);
|
||||
int nxGain = mapitem.getItemId() == 4031865 ? 100 : 250;
|
||||
this.getCashShop().gainCash(1, nxGain);
|
||||
|
||||
showHint("You have earned #e#b" + nxGain + " NX#k#n. (" + this.getCashShop().getCash(1) + " NX)");
|
||||
} else if (useItem(client, mapitem.getItem().getItemId())) {
|
||||
if (mapitem.getItem().getItemId() / 10000 == 238) {
|
||||
this.getMonsterBook().addCard(client, mapitem.getItem().getItemId());
|
||||
@@ -2166,6 +2173,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
dispelDebuff(MapleDisease.POISON);
|
||||
dispelDebuff(MapleDisease.SEAL);
|
||||
dispelDebuff(MapleDisease.WEAKEN);
|
||||
dispelDebuff(MapleDisease.SLOW);
|
||||
}
|
||||
|
||||
public void cancelAllDebuffs() {
|
||||
@@ -3225,8 +3233,12 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
|
||||
public boolean isPartyMember(MapleCharacter chr) {
|
||||
return isPartyMember(chr.getId());
|
||||
}
|
||||
|
||||
public boolean isPartyMember(int cid) {
|
||||
for(MapleCharacter mpcu: getPartyMembers()) {
|
||||
if(mpcu.getId() == chr.getId()) {
|
||||
if(mpcu.getId() == cid) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -3238,6 +3250,11 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
return playerShop;
|
||||
}
|
||||
|
||||
public void setGMLevel(int level) {
|
||||
this.gmLevel = Math.min(level, 6);
|
||||
this.gmLevel = Math.max(level, 0);
|
||||
}
|
||||
|
||||
public void closePlayerInteractions() {
|
||||
closeNpcShop();
|
||||
closeTrade();
|
||||
@@ -3430,9 +3447,9 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
//---- /\ /\ /\ /\ /\ /\ /\ NOT TESTED /\ /\ /\ /\ /\ /\ /\ /\ /\ ----
|
||||
|
||||
public boolean needQuestItem(int questid, int itemid) {
|
||||
if (questid <= 0) {
|
||||
return true; //For non quest items :3
|
||||
}
|
||||
if (questid <= 0) return true; //For non quest items :3
|
||||
if (this.getQuestStatus(questid) != 1) return false;
|
||||
|
||||
MapleQuest quest = MapleQuest.getInstance(questid);
|
||||
return getInventory(ItemConstants.getInventoryType(itemid)).countById(itemid) < quest.getItemAmountNeeded(itemid);
|
||||
}
|
||||
@@ -4119,8 +4136,19 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
|
||||
private void setCouponRates() {
|
||||
setActiveCoupons();
|
||||
activateCouponsEffects();
|
||||
List<Integer> couponEffects;
|
||||
|
||||
chrLock.lock();
|
||||
try {
|
||||
setActiveCoupons();
|
||||
couponEffects = activateCouponsEffects();
|
||||
} finally {
|
||||
chrLock.unlock();
|
||||
}
|
||||
|
||||
for(Integer couponId: couponEffects) {
|
||||
commitBuffCoupon(couponId);
|
||||
}
|
||||
}
|
||||
|
||||
private void revertCouponRates() {
|
||||
@@ -4167,13 +4195,16 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
this.mesoCoupon = 1;
|
||||
}
|
||||
|
||||
private void activateCouponsEffects() {
|
||||
private List<Integer> activateCouponsEffects() {
|
||||
List<Integer> toCommitEffect = new LinkedList<>();
|
||||
|
||||
if(ServerConstants.USE_STACK_COUPON_RATES) {
|
||||
for(Entry<Integer,Integer> coupon: activeCoupons.entrySet()) {
|
||||
int couponId = coupon.getKey();
|
||||
int couponQty = coupon.getValue();
|
||||
|
||||
commitBuffCoupon(couponId);
|
||||
toCommitEffect.add(couponId);
|
||||
|
||||
if(ItemConstants.isExpCoupon(couponId)) setExpCouponRate(couponId, couponQty);
|
||||
else setDropCouponRate(couponId, couponQty);
|
||||
}
|
||||
@@ -4198,8 +4229,8 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
}
|
||||
|
||||
if(maxExpCouponId > -1) commitBuffCoupon(maxExpCouponId);
|
||||
if(maxDropCouponId > -1) commitBuffCoupon(maxDropCouponId);
|
||||
if(maxExpCouponId > -1) toCommitEffect.add(maxExpCouponId);
|
||||
if(maxDropCouponId > -1) toCommitEffect.add(maxDropCouponId);
|
||||
|
||||
this.expCoupon = maxExpRate;
|
||||
this.dropCoupon = maxDropRate;
|
||||
@@ -4209,30 +4240,27 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
this.expRate *= this.expCoupon;
|
||||
this.dropRate *= this.dropCoupon;
|
||||
this.mesoRate *= this.mesoCoupon;
|
||||
|
||||
return toCommitEffect;
|
||||
}
|
||||
|
||||
private void setActiveCoupons() {
|
||||
chrLock.lock();
|
||||
try {
|
||||
activeCoupons.clear();
|
||||
activeCouponRates.clear();
|
||||
activeCoupons.clear();
|
||||
activeCouponRates.clear();
|
||||
|
||||
Map<Integer, Integer> coupons = Server.getInstance().getCouponRates();
|
||||
List<Integer> active = Server.getInstance().getActiveCoupons();
|
||||
Map<Integer, Integer> coupons = Server.getInstance().getCouponRates();
|
||||
List<Integer> active = Server.getInstance().getActiveCoupons();
|
||||
|
||||
for(Item it: this.getInventory(MapleInventoryType.CASH).list()) {
|
||||
if(ItemConstants.isRateCoupon(it.getItemId()) && active.contains(it.getItemId())) {
|
||||
Integer count = activeCoupons.get(it.getItemId());
|
||||
for(Item it: this.getInventory(MapleInventoryType.CASH).list()) {
|
||||
if(ItemConstants.isRateCoupon(it.getItemId()) && active.contains(it.getItemId())) {
|
||||
Integer count = activeCoupons.get(it.getItemId());
|
||||
|
||||
if(count != null) activeCoupons.put(it.getItemId(), count + 1);
|
||||
else {
|
||||
activeCoupons.put(it.getItemId(), 1);
|
||||
activeCouponRates.put(it.getItemId(), coupons.get(it.getItemId()));
|
||||
}
|
||||
if(count != null) activeCoupons.put(it.getItemId(), count + 1);
|
||||
else {
|
||||
activeCoupons.put(it.getItemId(), 1);
|
||||
activeCouponRates.put(it.getItemId(), coupons.get(it.getItemId()));
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
chrLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4261,7 +4289,12 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
|
||||
public Set<Integer> getActiveCoupons() {
|
||||
return Collections.unmodifiableSet(activeCoupons.keySet());
|
||||
chrLock.lock();
|
||||
try {
|
||||
return Collections.unmodifiableSet(activeCoupons.keySet());
|
||||
} finally {
|
||||
chrLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public static MapleCharacter loadCharFromDB(int charid, MapleClient client, boolean channelserver) throws SQLException {
|
||||
@@ -5006,7 +5039,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}, buffInterval, buffInterval);
|
||||
}
|
||||
} else if (effect.isRecovery()) {
|
||||
int healInterval = (ServerConstants.USE_ULTRA_RECOVERY) ? 2500 : 5000;
|
||||
int healInterval = (ServerConstants.USE_ULTRA_RECOVERY) ? 2000 : 5000;
|
||||
final byte heal = (byte) effect.getX();
|
||||
|
||||
chrLock.lock();
|
||||
@@ -6198,10 +6231,14 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
|
||||
public void timeoutFromDojo() {
|
||||
if(map.isDojoMap()) {
|
||||
client.getPlayer().changeMap(client.getChannelServer().getMapFactory().getMap(925020000));
|
||||
client.getPlayer().changeMap(client.getChannelServer().getMapFactory().getMap(925020002));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void showHint(String msg) {
|
||||
client.announceHint(msg);
|
||||
}
|
||||
|
||||
public void showNote() {
|
||||
try {
|
||||
Connection con = DatabaseConnection.getConnection();
|
||||
|
||||
@@ -60,6 +60,7 @@ import net.server.world.World;
|
||||
import org.apache.mina.core.session.IoSession;
|
||||
|
||||
import client.inventory.MapleInventoryType;
|
||||
import constants.GameConstants;
|
||||
import constants.ServerConstants;
|
||||
import scripting.AbstractPlayerInteraction;
|
||||
import scripting.event.EventManager;
|
||||
@@ -798,7 +799,12 @@ public class MapleClient {
|
||||
player.getEventInstance().playerDisconnected(player);
|
||||
}
|
||||
if (player.getMap() != null) {
|
||||
int mapId = player.getMapId();
|
||||
player.getMap().removePlayer(player);
|
||||
|
||||
if(GameConstants.isDojo(mapId)) {
|
||||
this.getChannelServer().freeDojoSectionIfEmpty(mapId);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (final Throwable t) {
|
||||
@@ -1031,6 +1037,10 @@ public class MapleClient {
|
||||
public int getGMLevel() {
|
||||
return gmlevel;
|
||||
}
|
||||
|
||||
public void setGMLevel(int level) {
|
||||
gmlevel = level;
|
||||
}
|
||||
|
||||
public void setScriptEngine(String name, ScriptEngine e) {
|
||||
engines.put(name, e);
|
||||
@@ -1263,11 +1273,15 @@ public class MapleClient {
|
||||
player.setTargetHpBarTime(timeNow);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public synchronized void announce(final byte[] packet) {//MINA CORE IS A FUCKING BITCH AND I HATE IT <3
|
||||
session.write(packet);
|
||||
}
|
||||
|
||||
public void announceHint(String msg) {
|
||||
announce(MaplePacketCreator.sendHint(msg, 500, 10));
|
||||
announce(MaplePacketCreator.enableActions());
|
||||
}
|
||||
|
||||
public void changeChannel(int channel) {
|
||||
Server server = Server.getInstance();
|
||||
|
||||
@@ -100,6 +100,7 @@ import client.inventory.MapleInventoryType;
|
||||
import client.inventory.MaplePet;
|
||||
import constants.GameConstants;
|
||||
import constants.ItemConstants;
|
||||
import constants.ServerConstants;
|
||||
import java.util.ArrayList;
|
||||
import server.life.SpawnPoint;
|
||||
import server.maps.FieldLimit;
|
||||
@@ -698,7 +699,7 @@ public class Commands {
|
||||
|
||||
case "goto":
|
||||
if (sub.length < 2){
|
||||
player.yellowMessage("Syntax: @goto <map name>");
|
||||
player.yellowMessage("Syntax: !goto <map name>");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -791,8 +792,15 @@ public class Commands {
|
||||
player.updateSingleStat(MapleStat.AVAILABLESP, player.getRemainingSp());
|
||||
} else {
|
||||
victim = c.getChannelServer().getPlayerStorage().getCharacterByName(sub[1]);
|
||||
victim.setRemainingSp(Integer.parseInt(sub[2]));
|
||||
victim.updateSingleStat(MapleStat.AVAILABLESP, player.getRemainingSp());
|
||||
|
||||
if(victim != null) {
|
||||
victim.setRemainingSp(Integer.parseInt(sub[2]));
|
||||
victim.updateSingleStat(MapleStat.AVAILABLESP, player.getRemainingSp());
|
||||
|
||||
player.dropMessage(5, "SP given.");
|
||||
} else {
|
||||
player.message("Player '" + sub[1] + "' could not be found on this channel.");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -807,8 +815,13 @@ public class Commands {
|
||||
player.updateSingleStat(MapleStat.AVAILABLEAP, player.getRemainingAp());
|
||||
} else {
|
||||
victim = c.getChannelServer().getPlayerStorage().getCharacterByName(sub[1]);
|
||||
victim.setRemainingAp(Integer.parseInt(sub[2]));
|
||||
victim.updateSingleStat(MapleStat.AVAILABLEAP, victim.getRemainingAp());
|
||||
|
||||
if(victim != null) {
|
||||
victim.setRemainingAp(Integer.parseInt(sub[2]));
|
||||
victim.updateSingleStat(MapleStat.AVAILABLEAP, victim.getRemainingAp());
|
||||
} else {
|
||||
player.message("Player '" + sub[1] + "' could not be found on this channel.");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -841,8 +854,13 @@ public class Commands {
|
||||
case "bomb":
|
||||
if (sub.length > 1){
|
||||
victim = c.getWorldServer().getPlayerStorage().getCharacterByName(sub[1]);
|
||||
victim.getMap().spawnMonsterOnGroundBelow(MapleLifeFactory.getMonster(9300166), victim.getPosition());
|
||||
Server.getInstance().broadcastGMMessage(MaplePacketCreator.serverNotice(5, player.getName() + " used !bomb on " + victim.getName()));
|
||||
|
||||
if(victim != null) {
|
||||
victim.getMap().spawnMonsterOnGroundBelow(MapleLifeFactory.getMonster(9300166), victim.getPosition());
|
||||
Server.getInstance().broadcastGMMessage(MaplePacketCreator.serverNotice(5, player.getName() + " used !bomb on " + victim.getName()));
|
||||
} else {
|
||||
player.message("Player '" + sub[1] + "' could not be found on this world.");
|
||||
}
|
||||
} else {
|
||||
player.getMap().spawnMonsterOnGroundBelow(MapleLifeFactory.getMonster(9300166), player.getPosition());
|
||||
}
|
||||
@@ -1093,6 +1111,10 @@ public class Commands {
|
||||
}
|
||||
|
||||
int itemId = Integer.parseInt(sub[1]);
|
||||
if(MapleItemInformationProvider.getInstance().getName(itemId) == null) {
|
||||
player.yellowMessage("Item id '" + sub[1] + "' does not exist.");
|
||||
break;
|
||||
}
|
||||
|
||||
short quantity = 1;
|
||||
if(sub.length >= 3) quantity = Short.parseShort(sub[2]);
|
||||
@@ -1138,10 +1160,11 @@ public class Commands {
|
||||
}
|
||||
|
||||
player.loseExp(player.getExp(), false, false);
|
||||
|
||||
player.revertPlayerRates();
|
||||
player.setLevel(Math.min(Integer.parseInt(sub[1]), player.getMaxLevel()) - 1);
|
||||
player.setPlayerRates();
|
||||
|
||||
player.resetPlayerRates();
|
||||
if(ServerConstants.USE_ADD_RATES_BY_LEVEL == true) player.setPlayerRates();
|
||||
player.setWorldRates();
|
||||
|
||||
player.levelUp(false);
|
||||
break;
|
||||
@@ -1173,10 +1196,13 @@ public class Commands {
|
||||
final String[] s = {"setstat", String.valueOf(Short.MAX_VALUE)};
|
||||
executeSolaxiaCommandLv2(cserv, srv, c, s);
|
||||
player.loseExp(player.getExp(), false, false);
|
||||
player.revertPlayerRates();
|
||||
player.setLevel(255);
|
||||
player.setPlayerRates();
|
||||
player.setFame(13337);
|
||||
|
||||
player.resetPlayerRates();
|
||||
if(ServerConstants.USE_ADD_RATES_BY_LEVEL == true) player.setPlayerRates();
|
||||
player.setWorldRates();
|
||||
|
||||
player.setFame(13337);
|
||||
player.setMaxHp(30000);
|
||||
player.setMaxMp(30000);
|
||||
player.updateSingleStat(MapleStat.LEVEL, 255);
|
||||
@@ -1190,9 +1216,7 @@ public class Commands {
|
||||
for (MapleData skill_ : MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/" + "String.wz")).getData("Skill.img").getChildren()) {
|
||||
try {
|
||||
skill = SkillFactory.getSkill(Integer.parseInt(skill_.getName()));
|
||||
if (GameConstants.isInJobTree(skill.getId(), player.getJob().getId())) {
|
||||
player.changeSkillLevel(skill, (byte) skill.getMaxLevel(), skill.getMaxLevel(), -1);
|
||||
}
|
||||
player.changeSkillLevel(skill, (byte) skill.getMaxLevel(), skill.getMaxLevel(), -1);
|
||||
} catch (NumberFormatException nfe) {
|
||||
nfe.printStackTrace();
|
||||
break;
|
||||
@@ -1228,8 +1252,9 @@ public class Commands {
|
||||
data = dataProvider.getData("Mob.img");
|
||||
} else if (sub[1].equalsIgnoreCase("SKILL")) {
|
||||
data = dataProvider.getData("Skill.img");
|
||||
} else if (sub[1].equalsIgnoreCase("MAP")) {
|
||||
sb.append("#bUse the '!m' command to find a map. If it finds a map with the same name, it will warp you to it.");
|
||||
/*} else if (sub[1].equalsIgnoreCase("MAP")) {
|
||||
TODO
|
||||
*/
|
||||
} else {
|
||||
sb.append("#bInvalid search.\r\nSyntax: '!search [type] [name]', where [type] is NPC, ITEM, MOB, or SKILL.");
|
||||
}
|
||||
@@ -1288,14 +1313,14 @@ public class Commands {
|
||||
MapleMap target = cserv.getMapFactory().getMap(mapid);
|
||||
MaplePortal targetPortal = target.getPortal(0);
|
||||
victim.changeMap(target, targetPortal);
|
||||
player.dropMessage(victim.getName() + " was jailed for " + minutesJailed + " minutes.");
|
||||
player.message(victim.getName() + " was jailed for " + minutesJailed + " minutes.");
|
||||
}
|
||||
else {
|
||||
player.dropMessage(victim.getName() + "'s time in jail has been extended for " + minutesJailed + " minutes.");
|
||||
player.message(victim.getName() + "'s time in jail has been extended for " + minutesJailed + " minutes.");
|
||||
}
|
||||
|
||||
} else {
|
||||
player.dropMessage(sub[1] + " not found on this channel! Make sure your target is logged on and on the same channel as yours.");
|
||||
player.message("Player '" + sub[1] + "' could not be found on this channel.");
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1308,14 +1333,14 @@ public class Commands {
|
||||
victim = cserv.getPlayerStorage().getCharacterByName(sub[1]);
|
||||
if (victim != null) {
|
||||
if(victim.getJailExpirationTimeLeft() <= 0) {
|
||||
player.dropMessage("This player is already free.");
|
||||
player.message("This player is already free.");
|
||||
break;
|
||||
}
|
||||
victim.removeJailExpirationTime();
|
||||
victim.dropMessage("By lack of concrete proof you are now unjailed. Enjoy freedom!");
|
||||
player.dropMessage(victim.getName() + " was unjailed.");
|
||||
victim.message("By lack of concrete proof you are now unjailed. Enjoy freedom!");
|
||||
player.message(victim.getName() + " was unjailed.");
|
||||
} else {
|
||||
player.dropMessage(sub[1] + " not found on this channel! Make sure your target is logged on and on the same channel as yours.");
|
||||
player.message("Player '" + sub[1] + "' could not be found on this channel.");
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1325,8 +1350,13 @@ public class Commands {
|
||||
player.equipChanged();
|
||||
} else if (sub.length == 3) {
|
||||
victim = c.getChannelServer().getPlayerStorage().getCharacterByName(sub[1]);
|
||||
victim.changeJob(MapleJob.getById(Integer.parseInt(sub[2])));
|
||||
player.equipChanged();
|
||||
|
||||
if(victim != null) {
|
||||
victim.changeJob(MapleJob.getById(Integer.parseInt(sub[2])));
|
||||
player.equipChanged();
|
||||
} else {
|
||||
player.message("Player '" + sub[1] + "' could not be found on this channel.");
|
||||
}
|
||||
} else {
|
||||
player.message("Syntax: !job <job id> <opt: IGN of another person>");
|
||||
}
|
||||
@@ -1379,17 +1409,21 @@ public class Commands {
|
||||
|
||||
case "checkdmg":
|
||||
victim = c.getWorldServer().getPlayerStorage().getCharacterByName(sub[1]);
|
||||
int maxBase = victim.calculateMaxBaseDamage(victim.getTotalWatk());
|
||||
Integer watkBuff = victim.getBuffedValue(MapleBuffStat.WATK);
|
||||
Integer matkBuff = victim.getBuffedValue(MapleBuffStat.MATK);
|
||||
Integer blessing = victim.getSkillLevel(10000000 * player.getJobType() + 12);
|
||||
if(watkBuff == null) watkBuff = 0;
|
||||
if(matkBuff == null) matkBuff = 0;
|
||||
if(victim != null) {
|
||||
int maxBase = victim.calculateMaxBaseDamage(victim.getTotalWatk());
|
||||
Integer watkBuff = victim.getBuffedValue(MapleBuffStat.WATK);
|
||||
Integer matkBuff = victim.getBuffedValue(MapleBuffStat.MATK);
|
||||
Integer blessing = victim.getSkillLevel(10000000 * player.getJobType() + 12);
|
||||
if(watkBuff == null) watkBuff = 0;
|
||||
if(matkBuff == null) matkBuff = 0;
|
||||
|
||||
player.dropMessage(5, "Cur Str: " + victim.getTotalStr() + " Cur Dex: " + victim.getTotalDex() + " Cur Int: " + victim.getTotalInt() + " Cur Luk: " + victim.getTotalLuk());
|
||||
player.dropMessage(5, "Cur WATK: " + victim.getTotalWatk() + " Cur MATK: " + victim.getTotalMagic());
|
||||
player.dropMessage(5, "Cur WATK Buff: " + watkBuff + " Cur MATK Buff: " + matkBuff + " Cur Blessing Level: " + blessing);
|
||||
player.dropMessage(5, victim.getName() + "'s maximum base damage (before skills) is " + maxBase);
|
||||
player.dropMessage(5, "Cur Str: " + victim.getTotalStr() + " Cur Dex: " + victim.getTotalDex() + " Cur Int: " + victim.getTotalInt() + " Cur Luk: " + victim.getTotalLuk());
|
||||
player.dropMessage(5, "Cur WATK: " + victim.getTotalWatk() + " Cur MATK: " + victim.getTotalMagic());
|
||||
player.dropMessage(5, "Cur WATK Buff: " + watkBuff + " Cur MATK Buff: " + matkBuff + " Cur Blessing Level: " + blessing);
|
||||
player.dropMessage(5, victim.getName() + "'s maximum base damage (before skills) is " + maxBase);
|
||||
} else {
|
||||
player.message("Player '" + sub[1] + "' could not be found on this world.");
|
||||
}
|
||||
break;
|
||||
|
||||
case "inmap":
|
||||
@@ -1440,12 +1474,16 @@ public class Commands {
|
||||
player.yellowMessage("Syntax: !sethpmp [<playername>] <value>");
|
||||
}
|
||||
|
||||
victim.setHp(statUpdate);
|
||||
victim.setMp(statUpdate);
|
||||
victim.updateSingleStat(MapleStat.HP, statUpdate);
|
||||
victim.updateSingleStat(MapleStat.MP, statUpdate);
|
||||
|
||||
victim.checkBerserk(victim.isHidden());
|
||||
if(victim != null) {
|
||||
victim.setHp(statUpdate);
|
||||
victim.setMp(statUpdate);
|
||||
victim.updateSingleStat(MapleStat.HP, statUpdate);
|
||||
victim.updateSingleStat(MapleStat.MP, statUpdate);
|
||||
|
||||
victim.checkBerserk(victim.isHidden());
|
||||
} else {
|
||||
player.message("Player '" + sub[1] + "' could not be found on this world.");
|
||||
}
|
||||
break;
|
||||
|
||||
case "music":
|
||||
@@ -1477,7 +1515,7 @@ public class Commands {
|
||||
}
|
||||
victim = c.getWorldServer().getPlayerStorage().getCharacterByName(sub[1]);
|
||||
if (victim == null){
|
||||
player.yellowMessage("Player not found!");
|
||||
player.message("Player '" + sub[1] + "' could not be found on this world.");
|
||||
break;
|
||||
}
|
||||
boolean monitored = MapleLogger.monitored.contains(victim.getName());
|
||||
@@ -1504,7 +1542,7 @@ public class Commands {
|
||||
}
|
||||
victim = c.getWorldServer().getPlayerStorage().getCharacterByName(sub[1]);
|
||||
if (victim == null){
|
||||
player.yellowMessage("Player not found!");
|
||||
player.message("Player '" + sub[1] + "' could not be found on this world.");
|
||||
break;
|
||||
}
|
||||
boolean monitored_ = MapleLogger.ignored.contains(victim.getName());
|
||||
@@ -1552,8 +1590,13 @@ public class Commands {
|
||||
}
|
||||
|
||||
victim = cserv.getPlayerStorage().getCharacterByName(sub[1]);
|
||||
victim.setFame(Integer.parseInt(sub[2]));
|
||||
victim.updateSingleStat(MapleStat.FAME, victim.getFame());
|
||||
if(victim != null) {
|
||||
victim.setFame(Integer.parseInt(sub[2]));
|
||||
victim.updateSingleStat(MapleStat.FAME, victim.getFame());
|
||||
player.message("FAME given.");
|
||||
} else {
|
||||
player.message("Player '" + sub[1] + "' could not be found on this channel.");
|
||||
}
|
||||
break;
|
||||
|
||||
case "givenx":
|
||||
@@ -1561,8 +1604,14 @@ public class Commands {
|
||||
player.yellowMessage("Syntax: !givenx <playername> <gainnx>");
|
||||
break;
|
||||
}
|
||||
cserv.getPlayerStorage().getCharacterByName(sub[1]).getCashShop().gainCash(1, Integer.parseInt(sub[2]));
|
||||
player.message("NX given.");
|
||||
|
||||
victim = cserv.getPlayerStorage().getCharacterByName(sub[1]);
|
||||
if(victim != null) {
|
||||
victim.getCashShop().gainCash(1, Integer.parseInt(sub[2]));
|
||||
player.message("NX given.");
|
||||
} else {
|
||||
player.message("Player '" + sub[1] + "' could not be found on this channel.");
|
||||
}
|
||||
break;
|
||||
|
||||
case "givevp":
|
||||
@@ -1570,8 +1619,14 @@ public class Commands {
|
||||
player.yellowMessage("Syntax: !givevp <playername> <gainvotepoint>");
|
||||
break;
|
||||
}
|
||||
cserv.getPlayerStorage().getCharacterByName(sub[1]).getClient().addVotePoints(Integer.parseInt(sub[2]));
|
||||
player.message("VP given.");
|
||||
|
||||
victim = cserv.getPlayerStorage().getCharacterByName(sub[1]);
|
||||
if(victim != null) {
|
||||
victim.getClient().addVotePoints(Integer.parseInt(sub[2]));
|
||||
player.message("VP given.");
|
||||
} else {
|
||||
player.message("Player '" + sub[1] + "' could not be found on this channel.");
|
||||
}
|
||||
break;
|
||||
|
||||
case "givems":
|
||||
@@ -1579,8 +1634,14 @@ public class Commands {
|
||||
player.yellowMessage("Syntax: !givemx <playername> <gainmx>");
|
||||
break;
|
||||
}
|
||||
cserv.getPlayerStorage().getCharacterByName(sub[1]).gainMeso(Integer.parseInt(sub[2]), true);
|
||||
player.message("MESO given.");
|
||||
|
||||
victim = cserv.getPlayerStorage().getCharacterByName(sub[1]);
|
||||
if(victim != null) {
|
||||
victim.gainMeso(Integer.parseInt(sub[2]), true);
|
||||
player.message("MESO given.");
|
||||
} else {
|
||||
player.message("Player '" + sub[1] + "' could not be found on this channel.");
|
||||
}
|
||||
break;
|
||||
|
||||
case "id":
|
||||
@@ -1634,8 +1695,12 @@ public class Commands {
|
||||
}
|
||||
|
||||
victim = cserv.getPlayerStorage().getCharacterByName(sub[1]);
|
||||
victim.setHpMp(0);
|
||||
Server.getInstance().broadcastGMMessage(MaplePacketCreator.serverNotice(5, player.getName() + " used !kill on " + victim.getName()));
|
||||
if(victim != null) {
|
||||
victim.setHpMp(0);
|
||||
Server.getInstance().broadcastGMMessage(MaplePacketCreator.serverNotice(5, player.getName() + " used !kill on " + victim.getName()));
|
||||
} else {
|
||||
player.message("Player '" + sub[1] + "' could not be found on this channel.");
|
||||
}
|
||||
break;
|
||||
|
||||
case "seed":
|
||||
@@ -1659,7 +1724,6 @@ public class Commands {
|
||||
case "maxenergy":
|
||||
c.getPlayer().setDojoEnergy(10000);
|
||||
c.announce(MaplePacketCreator.getEnergy("energy", 10000));
|
||||
System.out.println("gauge " + player.getDojoEnergy());
|
||||
break;
|
||||
|
||||
case "killall":
|
||||
@@ -1857,17 +1921,25 @@ public class Commands {
|
||||
break;
|
||||
|
||||
case "healperson":
|
||||
victim = cserv.getPlayerStorage().getCharacterByName(sub[1]);
|
||||
victim = cserv.getPlayerStorage().getCharacterByName(sub[1]);
|
||||
if(victim != null) {
|
||||
victim.setHp(victim.getMaxHp());
|
||||
victim.updateSingleStat(MapleStat.HP, victim.getMaxHp());
|
||||
victim.setMp(victim.getMaxMp());
|
||||
victim.updateSingleStat(MapleStat.MP, victim.getMaxMp());
|
||||
} else {
|
||||
player.message("Player '" + sub[1] + "' could not be found on this channel.");
|
||||
}
|
||||
break;
|
||||
|
||||
case "hurt":
|
||||
victim = cserv.getPlayerStorage().getCharacterByName(sub[1]);
|
||||
victim = cserv.getPlayerStorage().getCharacterByName(sub[1]);
|
||||
if(victim != null) {
|
||||
victim.setHp(1);
|
||||
victim.updateSingleStat(MapleStat.HP, 1);
|
||||
} else {
|
||||
player.message("Player '" + sub[1] + "' could not be found on this channel.");
|
||||
}
|
||||
break;
|
||||
|
||||
case "killmap":
|
||||
@@ -1925,12 +1997,12 @@ public class Commands {
|
||||
|
||||
victim = c.getChannelServer().getPlayerStorage().getCharacterByName(sub[1]);
|
||||
if(victim == null) {
|
||||
victim.setFace(itemId);
|
||||
victim.updateSingleStat(MapleStat.FACE, itemId);
|
||||
victim.equipChanged();
|
||||
} else {
|
||||
player.yellowMessage("Player '" + sub[1] + "' has not been found on this channel.");
|
||||
break;
|
||||
}
|
||||
victim.setFace(itemId);
|
||||
victim.updateSingleStat(MapleStat.FACE, itemId);
|
||||
victim.equipChanged();
|
||||
}
|
||||
} catch(Exception e) {}
|
||||
|
||||
@@ -1961,13 +2033,13 @@ public class Commands {
|
||||
}
|
||||
|
||||
victim = c.getChannelServer().getPlayerStorage().getCharacterByName(sub[1]);
|
||||
if(victim == null) {
|
||||
if(victim != null) {
|
||||
victim.setHair(itemId);
|
||||
victim.updateSingleStat(MapleStat.HAIR, itemId);
|
||||
victim.equipChanged();
|
||||
} else {
|
||||
player.yellowMessage("Player '" + sub[1] + "' has not been found on this channel.");
|
||||
break;
|
||||
}
|
||||
victim.setHair(itemId);
|
||||
victim.updateSingleStat(MapleStat.HAIR, itemId);
|
||||
victim.equipChanged();
|
||||
}
|
||||
} catch(Exception e) {}
|
||||
break;
|
||||
@@ -1987,7 +2059,7 @@ public class Commands {
|
||||
case "servermessage":
|
||||
c.getWorldServer().setServerMessage(joinStringFrom(sub, 1));
|
||||
break;
|
||||
|
||||
|
||||
case "proitem":
|
||||
if (sub.length < 3) {
|
||||
player.yellowMessage("Syntax: !proitem <itemid> <statvalue>");
|
||||
@@ -2056,19 +2128,24 @@ public class Commands {
|
||||
|
||||
case "exprate":
|
||||
if (sub.length < 2){
|
||||
player.yellowMessage("Syntax: !exprate <newrate>");
|
||||
break;
|
||||
}
|
||||
c.getWorldServer().setExpRate(Integer.parseInt(sub[1]));
|
||||
c.getWorldServer().broadcastPacket(MaplePacketCreator.serverNotice(6, "[Rate] Exp Rate has been changed to " + sub[1] + "x."));
|
||||
player.yellowMessage("Syntax: !exprate <newrate>");
|
||||
break;
|
||||
}
|
||||
|
||||
int exprate = Math.max(Integer.parseInt(sub[1]), 1);
|
||||
c.getWorldServer().setExpRate(exprate);
|
||||
c.getWorldServer().broadcastPacket(MaplePacketCreator.serverNotice(6, "[Rate] Exp Rate has been changed to " + exprate + "x."));
|
||||
break;
|
||||
|
||||
case "mesorate":
|
||||
if (sub.length < 2){
|
||||
player.yellowMessage("Syntax: !mesorate <newrate>");
|
||||
break;
|
||||
}
|
||||
c.getWorldServer().setMesoRate(Integer.parseInt(sub[1]));
|
||||
c.getWorldServer().broadcastPacket(MaplePacketCreator.serverNotice(6, "[Rate] Meso Rate has been changed to " + sub[1] + "x."));
|
||||
|
||||
int mesorate = Math.max(Integer.parseInt(sub[1]), 1);
|
||||
c.getWorldServer().setMesoRate(mesorate);
|
||||
c.getWorldServer().broadcastPacket(MaplePacketCreator.serverNotice(6, "[Rate] Meso Rate has been changed to " + mesorate + "x."));
|
||||
break;
|
||||
|
||||
case "droprate":
|
||||
@@ -2076,8 +2153,10 @@ public class Commands {
|
||||
player.yellowMessage("Syntax: !droprate <newrate>");
|
||||
break;
|
||||
}
|
||||
c.getWorldServer().setDropRate(Integer.parseInt(sub[1]));
|
||||
c.getWorldServer().broadcastPacket(MaplePacketCreator.serverNotice(6, "[Rate] Drop Rate has been changed to " + sub[1] + "x."));
|
||||
|
||||
int droprate = Math.max(Integer.parseInt(sub[1]), 1);
|
||||
c.getWorldServer().setDropRate(droprate);
|
||||
c.getWorldServer().broadcastPacket(MaplePacketCreator.serverNotice(6, "[Rate] Drop Rate has been changed to " + droprate + "x."));
|
||||
break;
|
||||
|
||||
case "bossdroprate":
|
||||
@@ -2085,14 +2164,21 @@ public class Commands {
|
||||
player.yellowMessage("Syntax: !bossdroprate <newrate>");
|
||||
break;
|
||||
}
|
||||
c.getWorldServer().setBossDropRate(Integer.parseInt(sub[1]));
|
||||
c.getWorldServer().broadcastPacket(MaplePacketCreator.serverNotice(6, "[Rate] Boss Drop Rate has been changed to " + sub[1] + "x."));
|
||||
|
||||
int bossdroprate = Math.max(Integer.parseInt(sub[1]), 1);
|
||||
c.getWorldServer().setBossDropRate(bossdroprate);
|
||||
c.getWorldServer().broadcastPacket(MaplePacketCreator.serverNotice(6, "[Rate] Boss Drop Rate has been changed to " + bossdroprate + "x."));
|
||||
break;
|
||||
|
||||
case "itemvac":
|
||||
List<MapleMapObject> list = player.getMap().getMapObjectsInRange(player.getPosition(), Double.POSITIVE_INFINITY, Arrays.asList(MapleMapObjectType.ITEM));
|
||||
for (MapleMapObject item : list) {
|
||||
player.pickupItem(item);
|
||||
List<MapleMapObject> list = player.getMap().getMapObjectsInRange(player.getPosition(), Double.POSITIVE_INFINITY, Arrays.asList(MapleMapObjectType.ITEM));
|
||||
for (MapleMapObject item : list) {
|
||||
MapleMapItem mapItem = (MapleMapItem) item;
|
||||
int ownerId = mapItem.getOwner();
|
||||
|
||||
if(ownerId <= 0 || player.getId() == ownerId || player.isPartyMember(ownerId) || System.currentTimeMillis() - mapItem.getDropTime() >= 15 * 1000) {
|
||||
player.pickupItem(item);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2144,6 +2230,19 @@ public class Commands {
|
||||
case "pianus":
|
||||
player.getMap().spawnMonsterOnGroundBelow(MapleLifeFactory.getMonster(8510000), player.getPosition());
|
||||
break;
|
||||
|
||||
case "cake":
|
||||
MapleMonster monster = MapleLifeFactory.getMonster(9400606);
|
||||
if(sub.length > 1) {
|
||||
int newHp = Integer.parseInt(sub[1]);
|
||||
if(newHp < 0) newHp = Integer.MAX_VALUE;
|
||||
|
||||
monster.getStats().setHp(newHp);
|
||||
monster.setHp(newHp);
|
||||
}
|
||||
|
||||
player.getMap().spawnMonsterOnGroundBelow(monster, player.getPosition());
|
||||
break;
|
||||
|
||||
case "playernpc":
|
||||
if (sub.length < 3){
|
||||
@@ -2270,6 +2369,25 @@ public class Commands {
|
||||
MapleCharacter victim;
|
||||
|
||||
switch(sub[0]) {
|
||||
case "setgmlevel":
|
||||
if (sub.length < 3){
|
||||
player.yellowMessage("Syntax: !setgmlevel <playername> <newlevel>");
|
||||
break;
|
||||
}
|
||||
|
||||
int newLevel = Integer.parseInt(sub[2]);
|
||||
MapleCharacter target = cserv.getPlayerStorage().getCharacterByName(sub[1]);
|
||||
if(target != null) {
|
||||
target.setGMLevel(newLevel);
|
||||
target.getClient().setGMLevel(newLevel);
|
||||
|
||||
target.dropMessage("You are now a level " + newLevel + " GM");
|
||||
player.dropMessage(target + " is now a level " + newLevel + " GM");
|
||||
} else {
|
||||
player.dropMessage("Player '"+ sub[1] +"' was not found on this channel.");
|
||||
}
|
||||
break;
|
||||
|
||||
case "warpworld":
|
||||
if (sub.length < 2){
|
||||
player.yellowMessage("Syntax: !warpworld <worldid>");
|
||||
@@ -2341,8 +2459,12 @@ public class Commands {
|
||||
player.yellowMessage("Syntax: !getacc <playername>");
|
||||
break;
|
||||
}
|
||||
victim = c.getChannelServer().getPlayerStorage().getCharacterByName(sub[1]);
|
||||
player.message(victim.getName() + "'s account name is " + victim.getClient().getAccountName() + ".");
|
||||
victim = c.getWorldServer().getPlayerStorage().getCharacterByName(sub[1]);
|
||||
if(victim != null) {
|
||||
player.message(victim.getName() + "'s account name is " + victim.getClient().getAccountName() + ".");
|
||||
} else {
|
||||
player.message("Player '" + sub[1] + "' could not be found on this world.");
|
||||
}
|
||||
break;
|
||||
|
||||
case "shutdown":
|
||||
|
||||
@@ -553,8 +553,7 @@ public class Equip extends Item {
|
||||
}
|
||||
|
||||
public final void showLevelupMessage(String msg, MapleClient c) {
|
||||
c.announce(MaplePacketCreator.sendHint(msg, 500, 10));
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
c.getPlayer().showHint(msg);
|
||||
}
|
||||
|
||||
public void setItemExp(int exp) {
|
||||
|
||||
@@ -80,7 +80,7 @@ public enum ItemFactory {
|
||||
MapleInventoryType mit = MapleInventoryType.getByType(rs.getByte("inventorytype"));
|
||||
|
||||
if (mit.equals(MapleInventoryType.EQUIP) || mit.equals(MapleInventoryType.EQUIPPED)) {
|
||||
Equip equip = new Equip(rs.getInt("itemid"), (byte) rs.getInt("position"));
|
||||
Equip equip = new Equip(rs.getInt("itemid"), (short) rs.getInt("position"));
|
||||
equip.setOwner(rs.getString("owner"));
|
||||
equip.setQuantity((short) rs.getInt("quantity"));
|
||||
equip.setAcc((short) rs.getInt("acc"));
|
||||
|
||||
@@ -327,6 +327,66 @@ public class MapleInventory implements Iterable<Item> {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static long fnvHash32(final String k) {
|
||||
final int FNV_32_INIT = 0x811c9dc5;
|
||||
final int FNV_32_PRIME = 0x01000193;
|
||||
|
||||
int rv = FNV_32_INIT;
|
||||
final int len = k.length();
|
||||
for(int i = 0; i < len; i++) {
|
||||
rv ^= k.charAt(i);
|
||||
rv *= FNV_32_PRIME;
|
||||
}
|
||||
|
||||
return rv >= 0 ? rv : (2L * Integer.MAX_VALUE) + rv;
|
||||
}
|
||||
|
||||
private static Long hashKey(Integer itemId, String owner) {
|
||||
return (itemId.longValue() << 32L) + fnvHash32(owner);
|
||||
}
|
||||
|
||||
public static boolean checkSpotsAndOwnership(MapleCharacter chr, List<Pair<Item, MapleInventoryType>> items) {
|
||||
List<Integer> zeroedList = new ArrayList<>(5);
|
||||
for(byte i = 0; i < 5; i++) zeroedList.add(0);
|
||||
|
||||
return checkSpotsAndOwnership(chr, items, zeroedList);
|
||||
}
|
||||
|
||||
public static boolean checkSpotsAndOwnership(MapleCharacter chr, List<Pair<Item, MapleInventoryType>> items, List<Integer> typesSlotsUsed) {
|
||||
// assumption: no "UNDEFINED" or "EQUIPPED" items shall be tested here, all counts are >= 0.
|
||||
|
||||
Map<Long, Short> rcvItems = new LinkedHashMap<>();
|
||||
Map<Long, Byte> rcvTypes = new LinkedHashMap<>();
|
||||
Map<Long, String> rcvOwners = new LinkedHashMap<>();
|
||||
|
||||
for (Pair<Item, MapleInventoryType> item : items) {
|
||||
Long itemHash = hashKey(item.left.getItemId(), item.left.getOwner());
|
||||
Short qty = rcvItems.get(itemHash);
|
||||
|
||||
if(qty == null) {
|
||||
rcvItems.put(itemHash, item.left.getQuantity());
|
||||
rcvTypes.put(itemHash, item.right.getType());
|
||||
rcvOwners.put(itemHash, item.left.getOwner());
|
||||
} else {
|
||||
rcvItems.put(itemHash, (short)(qty + item.left.getQuantity()));
|
||||
}
|
||||
}
|
||||
|
||||
MapleClient c = chr.getClient();
|
||||
for(Entry<Long, Short> it: rcvItems.entrySet()) {
|
||||
int itemType = rcvTypes.get(it.getKey()) - 1;
|
||||
int usedSlots = typesSlotsUsed.get(itemType);
|
||||
|
||||
Long itemId = it.getKey() >> 32L;
|
||||
int result = MapleInventoryManipulator.checkSpaceProgressively(c, itemId.intValue(), it.getValue(), rcvOwners.get(it.getKey()), usedSlots);
|
||||
boolean hasSpace = ((result % 2) != 0);
|
||||
|
||||
if(!hasSpace) return false;
|
||||
typesSlotsUsed.set(itemType, (result >> 1));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public MapleInventoryType getType() {
|
||||
return type;
|
||||
|
||||
@@ -214,7 +214,7 @@ public class MaplePet extends Item {
|
||||
if (newCloseness < 0) newCloseness = 0;
|
||||
|
||||
closeness = newCloseness;
|
||||
if (level > 1 && newCloseness < ExpTable.getClosenessNeededForLevel(level)) {
|
||||
if (level > 1 && newCloseness < ExpTable.getClosenessNeededForLevel(level - 1)) {
|
||||
level -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,9 +44,8 @@ public class ServerConstants {
|
||||
public static final boolean USE_ITEM_SORT_BY_NAME = false; //Item sorting based on name rather than id.
|
||||
public static final boolean USE_PARTY_SEARCH = false;
|
||||
public static final boolean USE_AUTOBAN = false; //Commands the server to detect infractors automatically.
|
||||
public static final boolean USE_ANOTHER_AUTOASSIGN = true; //Based on distributing AP accordingly to required secondary stat on equipments.
|
||||
public static final boolean USE_ANOTHER_AUTOASSIGNER = true; //Based on distributing AP accordingly to required secondary stat on equipments.
|
||||
public static final boolean USE_REFRESH_RANK_MOVE = true;
|
||||
public static final boolean USE_PERMISSIVE_BUFFS = false; //WARNING: Allows players that does not have increased certain buff-type skills to use it's effect. Used mainly on buff-cast commands, however making this active may generate a source for possible client-edited exploits.
|
||||
public static final boolean USE_ENFORCE_MDOOR_POSITION = true; //Forces mystic door to be spawned near spawnpoints. (since things bugs out other way, and this helps players locate the door faster)
|
||||
public static final boolean USE_ERASE_UNTRADEABLE_DROP = true; //Forces flagged untradeable items to disappear when dropped.
|
||||
|
||||
@@ -66,7 +65,7 @@ public class ServerConstants {
|
||||
|
||||
//Dangling Items Configuration
|
||||
public static final int ITEM_EXPIRE_TIME = 3 * 60 * 1000; //Time before items start disappearing. Recommended to be set up to 3 minutes.
|
||||
public static final int ITEM_MONITOR_TIME = 5 * 60 * 1000; //Interval between item monitoring task on maps, which checks for dangling item objects on the map item history.
|
||||
public static final int ITEM_MONITOR_TIME = 5 * 60 * 1000; //Interval between item monitoring tasks on maps, which checks for dangling item objects on the map item history.
|
||||
public static final int ITEM_LIMIT_ON_MAP = 250; //Max number of items allowed on a map.
|
||||
|
||||
//Some Gameplay Enhancing Configurations
|
||||
@@ -91,8 +90,8 @@ public class ServerConstants {
|
||||
//Equipment Configuration
|
||||
public static final boolean USE_EQUIPMNT_LVLUP_SLOTS = true;//Equips can upgrade slots at level up.
|
||||
public static final boolean USE_EQUIPMNT_LVLUP_POWER = true;//Enable more powerful stats upgrades at equip level up.
|
||||
public static final boolean USE_SPIKES_AVOID_BANISH = true; //Shoes equipped with spikes blocks mobs from banishing wearer.
|
||||
public static final boolean USE_CHAIR_EXTRAHEAL = true; //Enable map chairs to further recover player`s HP and MP.
|
||||
public static final boolean USE_SPIKES_AVOID_BANISH = true; //Shoes equipped with spikes prevents mobs from banishing wearer.
|
||||
public static final boolean USE_CHAIR_EXTRAHEAL = true; //Enable map chairs to further recover player's HP and MP.
|
||||
public static final int MAX_EQUIPMNT_LVLUP_STAT_GAIN = 10000; //Max stat upgrade an equipment can have on a levelup.
|
||||
public static final int MAX_EQUIPMNT_STAT = 32767; //Max stat on an equipment by leveling up.
|
||||
public static final int USE_EQUIPMNT_LVLUP = 7; //All equips lvlup at max level of N, set 1 to disable.
|
||||
|
||||
@@ -24,7 +24,7 @@ package net;
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import net.server.Server;
|
||||
|
||||
@@ -47,6 +47,7 @@ public class MapleServerHandler extends IoHandlerAdapter {
|
||||
private PacketProcessor processor;
|
||||
private int world = -1, channel = -1;
|
||||
private static final SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy HH:mm");
|
||||
private static AtomicLong sessionId = new AtomicLong(7777);
|
||||
|
||||
public MapleServerHandler() {
|
||||
this.processor = PacketProcessor.getProcessor(-1, -1);
|
||||
@@ -97,8 +98,7 @@ public class MapleServerHandler extends IoHandlerAdapter {
|
||||
MapleClient client = new MapleClient(sendCypher, recvCypher, session);
|
||||
client.setWorld(world);
|
||||
client.setChannel(channel);
|
||||
Random r = new Random();
|
||||
client.setSessionId(r.nextLong()); // Generates a random session id.
|
||||
client.setSessionId(sessionId.getAndIncrement()); // Generates a reasonable session id.
|
||||
session.write(MaplePacketCreator.getHello(ServerConstants.VERSION, ivSend, ivRecv));
|
||||
session.setAttribute(MapleClient.CLIENT_KEY, client);
|
||||
}
|
||||
|
||||
@@ -67,8 +67,8 @@ import java.util.Calendar;
|
||||
import server.quest.MapleQuest;
|
||||
|
||||
public class Server implements Runnable {
|
||||
private final Map<Integer, Integer> couponRates = new LinkedHashMap<>();
|
||||
private final List<Integer> activeCoupons = new LinkedList<>();
|
||||
private static final Map<Integer, Integer> couponRates = new LinkedHashMap<>();
|
||||
private static final List<Integer> activeCoupons = new LinkedList<>();
|
||||
|
||||
private IoAcceptor acceptor;
|
||||
private List<Map<Integer, String>> channels = new LinkedList<>();
|
||||
|
||||
@@ -374,8 +374,11 @@ public final class Channel {
|
||||
mask ^= (1 << slot);
|
||||
|
||||
usedDojo &= mask;
|
||||
if(party != null) dojoParty.remove(party.hashCode());
|
||||
else if(dojoParty.containsValue(slot)) { // they left the dojo before completing it, no party there!
|
||||
if(party != null) {
|
||||
if(dojoParty.remove(party.hashCode()) != null) return;
|
||||
}
|
||||
|
||||
if(dojoParty.containsValue(slot)) { // strange case, no party there!
|
||||
Set<Entry<Integer, Integer>> es = Collections.unmodifiableSet(dojoParty.entrySet());
|
||||
|
||||
for(Entry<Integer, Integer> e: es) {
|
||||
@@ -411,6 +414,20 @@ public final class Channel {
|
||||
}
|
||||
}
|
||||
|
||||
public void freeDojoSectionIfEmpty(int dojoMapId) {
|
||||
final int slot = getDojoSlot(dojoMapId);
|
||||
final int delta = (dojoMapId) % 100;
|
||||
final int stage = (dojoMapId / 100) % 100;
|
||||
final int dojoBaseMap = (dojoMapId >= 925030000) ? 925030000 : 925020000;
|
||||
|
||||
for (int i = 0; i < 5; i++) { //only 32 stages, but 38 maps
|
||||
MapleMap dojoMap = getMapFactory().getMap(dojoBaseMap + (100 * (stage + i)) + delta);
|
||||
if(!dojoMap.getAllPlayers().isEmpty()) return;
|
||||
}
|
||||
|
||||
freeDojoSlot(slot, null);
|
||||
}
|
||||
|
||||
public void startDojoSchedule(final int dojoMapId) {
|
||||
final int slot = getDojoSlot(dojoMapId);
|
||||
final int stage = (dojoMapId / 100) % 100;
|
||||
|
||||
@@ -270,7 +270,7 @@ public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandl
|
||||
player.checkMonsterAggro(monster);
|
||||
if (player.getBuffedValue(MapleBuffStat.PICKPOCKET) != null && (attack.skill == 0 || attack.skill == Rogue.DOUBLE_STAB || attack.skill == Bandit.SAVAGE_BLOW || attack.skill == ChiefBandit.ASSAULTER || attack.skill == ChiefBandit.BAND_OF_THIEVES || attack.skill == Shadower.ASSASSINATE || attack.skill == Shadower.TAUNT || attack.skill == Shadower.BOOMERANG_STEP)) {
|
||||
Skill pickpocket = SkillFactory.getSkill(ChiefBandit.PICKPOCKET);
|
||||
int picklv = (player.getSkillLevel(pickpocket) > 0 || !ServerConstants.USE_PERMISSIVE_BUFFS) ? player.getSkillLevel(pickpocket) : pickpocket.getMaxLevel();
|
||||
int picklv = (player.isGM()) ? pickpocket.getMaxLevel() : player.getSkillLevel(pickpocket);
|
||||
if(picklv > 0) {
|
||||
int delay = 0;
|
||||
final int maxmeso = player.getBuffedValue(MapleBuffStat.PICKPOCKET).intValue();
|
||||
@@ -650,7 +650,7 @@ public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandl
|
||||
} else {
|
||||
// Normal Combo
|
||||
int skillLv = chr.getSkillLevel(oid);
|
||||
if(skillLv <= 0 && ServerConstants.USE_PERMISSIVE_BUFFS) skillLv = SkillFactory.getSkill(oid).getMaxLevel();
|
||||
if(skillLv <= 0 || chr.isGM()) skillLv = SkillFactory.getSkill(oid).getMaxLevel();
|
||||
|
||||
if(skillLv > 0) {
|
||||
MapleStatEffect ceffect = SkillFactory.getSkill(oid).getEffect(skillLv);
|
||||
|
||||
@@ -31,27 +31,39 @@ import client.inventory.Equip;
|
||||
import client.inventory.Item;
|
||||
import client.inventory.MapleInventory;
|
||||
import client.inventory.MapleInventoryType;
|
||||
//import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
//import java.util.List;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Generic
|
||||
* @author Generic, Ronan
|
||||
*/
|
||||
public class AutoAssignHandler extends AbstractMaplePacketHandler {
|
||||
|
||||
private static int getNthHighestStat(List<Short> statList, short rank) { // ranks from 0
|
||||
return(statList.size() <= rank ? 0 : statList.get(rank));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
MapleJob stance;
|
||||
|
||||
if(ServerConstants.USE_ANOTHER_AUTOASSIGN == true) {
|
||||
int eqpStr = 0, eqpDex = 0, eqpLuk = 0;
|
||||
slea.skip(8);
|
||||
if (chr.getRemainingAp() < 1) return;
|
||||
|
||||
if(ServerConstants.USE_ANOTHER_AUTOASSIGNER == true) {
|
||||
// ---------- Ronan Lana's AUTOASSIGNER -------------
|
||||
// This method excels for assigning APs in such a way to cover all equipments AP requirements.
|
||||
|
||||
int str = 0, dex = 0, luk = 0, int_ = 0;
|
||||
List<Short> eqpStrList = new ArrayList<>();
|
||||
List<Short> eqpDexList = new ArrayList<>();
|
||||
List<Short> eqpLukList = new ArrayList<>();
|
||||
|
||||
MapleInventory iv = chr.getInventory(MapleInventoryType.EQUIPPED);
|
||||
Collection<Item> equippedC = iv.list();
|
||||
@@ -59,29 +71,33 @@ public class AutoAssignHandler extends AbstractMaplePacketHandler {
|
||||
|
||||
for (Item item : equippedC) { //selecting the biggest AP value of each stat from each equipped item.
|
||||
nEquip = (Equip)item;
|
||||
if(nEquip.getStr() > eqpStr) eqpStr = nEquip.getStr();
|
||||
if(nEquip.getStr() > 0) eqpStrList.add(nEquip.getStr());
|
||||
str += nEquip.getStr();
|
||||
|
||||
if(nEquip.getDex() > eqpDex) eqpDex = nEquip.getDex();
|
||||
if(nEquip.getDex() > 0) eqpDexList.add(nEquip.getDex());
|
||||
dex += nEquip.getDex();
|
||||
|
||||
if(nEquip.getLuk() > eqpLuk) eqpLuk = nEquip.getLuk();
|
||||
if(nEquip.getLuk() > 0) eqpLukList.add(nEquip.getLuk());
|
||||
luk += nEquip.getLuk();
|
||||
|
||||
//if(nEquip.getInt() > eqpInt) eqpInt = nEquip.getInt(); //not needed...
|
||||
//if(nEquip.getInt() > 0) eqpIntList.add(nEquip.getInt()); //not needed...
|
||||
int_ += nEquip.getInt();
|
||||
}
|
||||
|
||||
Collections.sort(eqpStrList, Collections.reverseOrder());
|
||||
Collections.sort(eqpDexList, Collections.reverseOrder());
|
||||
Collections.sort(eqpLukList, Collections.reverseOrder());
|
||||
|
||||
//Autoassigner looks up the 1st/2nd placed equips for their stats to calculate the optimal upgrade.
|
||||
int eqpStr = getNthHighestStat(eqpStrList, (short) 0) + getNthHighestStat(eqpStrList, (short) 1);
|
||||
int eqpDex = getNthHighestStat(eqpDexList, (short) 0) + getNthHighestStat(eqpDexList, (short) 1);
|
||||
int eqpLuk = getNthHighestStat(eqpLukList, (short) 0) + getNthHighestStat(eqpLukList, (short) 1);
|
||||
|
||||
//c.getPlayer().message("----------------------------------------SDL: " + eqpStr + eqpDex + eqpLuk + " BASE STATS --> STR: " + chr.getStr() + " DEX: " + chr.getDex() + " INT: " + chr.getInt() + " LUK: " + chr.getLuk());
|
||||
//c.getPlayer().message("----------------------------------------");
|
||||
//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_);
|
||||
|
||||
// ---------- Ronan Lana's AUTOASSIGN -------------
|
||||
// This method excels for assigning APs in such a way to cover all equipments AP requirements.
|
||||
if (chr.getRemainingAp() < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
stance = c.getPlayer().getJobStyle();
|
||||
MapleJob stance = c.getPlayer().getJobStyle();
|
||||
int prStat = 0, scStat = 0, trStat = 0, temp, tempAp = chr.getRemainingAp(), CAP;
|
||||
|
||||
MapleStat primary, secondary, tertiary = MapleStat.INT;
|
||||
@@ -294,10 +310,6 @@ public class AutoAssignHandler extends AbstractMaplePacketHandler {
|
||||
c.announce(MaplePacketCreator.serverNotice(1, "Better AP applications detected:\r\nSTR: +" + str + "\r\nDEX: +" + dex + "\r\nINT: +" + int_ + "\r\nLUK: +" + luk));
|
||||
}
|
||||
else {
|
||||
slea.skip(8);
|
||||
if (chr.getRemainingAp() < 1) {
|
||||
return;
|
||||
}
|
||||
int total = 0;
|
||||
int extras = 0;
|
||||
if(slea.available() < 16) {
|
||||
|
||||
@@ -152,7 +152,6 @@ public final class ChangeMapHandler extends AbstractMaplePacketHandler {
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
}
|
||||
//chr.setWorldRates();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@@ -73,7 +73,6 @@ public final class CloseRangeDamageHandler extends AbstractDealDamageHandler {
|
||||
if (player.getMap().isDojoMap() && attack.numAttacked > 0) {
|
||||
player.setDojoEnergy(player.getDojoEnergy() + ServerConstants.DOJO_ENERGY_ATK);
|
||||
c.announce(MaplePacketCreator.getEnergy("energy", player.getDojoEnergy()));
|
||||
System.out.println("gauge " + player.getDojoEnergy());
|
||||
}
|
||||
|
||||
player.getMap().broadcastMessage(player, MaplePacketCreator.closeRangeAttack(player, attack.skill, attack.skilllevel, attack.stance, attack.numAttackedAndDamage, attack.allDamage, attack.speed, attack.direction, attack.display), false, true);
|
||||
@@ -97,7 +96,7 @@ public final class CloseRangeDamageHandler extends AbstractDealDamageHandler {
|
||||
ceffect = advcombo.getEffect(advComboSkillLevel);
|
||||
} else {
|
||||
int comboLv = player.getSkillLevel(combo);
|
||||
if(comboLv <= 0 && ServerConstants.USE_PERMISSIVE_BUFFS) comboLv = SkillFactory.getSkill(oid).getMaxLevel();
|
||||
if(comboLv <= 0 || player.isGM()) comboLv = SkillFactory.getSkill(oid).getMaxLevel();
|
||||
|
||||
if(comboLv > 0) ceffect = combo.getEffect(comboLv);
|
||||
else ceffect = null;
|
||||
@@ -168,7 +167,6 @@ public final class CloseRangeDamageHandler extends AbstractDealDamageHandler {
|
||||
player.setDojoEnergy(0);
|
||||
c.announce(MaplePacketCreator.getEnergy("energy", player.getDojoEnergy()));
|
||||
c.announce(MaplePacketCreator.serverNotice(5, "As you used the secret skill, your energy bar has been reset."));
|
||||
System.out.println("gauge " + player.getDojoEnergy());
|
||||
} else if (attack.skill > 0) {
|
||||
Skill skill = SkillFactory.getSkill(attack.skill);
|
||||
MapleStatEffect effect_ = skill.getEffect(player.getSkillLevel(skill));
|
||||
|
||||
@@ -25,7 +25,6 @@ import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import net.server.Server;
|
||||
import server.MapleTrade;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ public final class GeneralChatHandler extends net.AbstractMaplePacketHandler {
|
||||
return;
|
||||
}
|
||||
char heading = s.charAt(0);
|
||||
if (heading == '/' || heading == '!' || heading == '@') { // client seems to not send command with '/' heading to the server, if not a GM account
|
||||
if (heading == '!' || heading == '@') {
|
||||
String[] sp = s.split(" ");
|
||||
sp[0] = sp[0].toLowerCase().substring(1);
|
||||
|
||||
@@ -59,8 +59,8 @@ public final class GeneralChatHandler extends net.AbstractMaplePacketHandler {
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy HH:mm");
|
||||
FilePrinter.print(FilePrinter.USED_COMMANDS, c.getPlayer().getName() + " used: " + heading + command + "on " + sdf.format(Calendar.getInstance().getTime()) + "\r\n");
|
||||
}
|
||||
} else {
|
||||
}
|
||||
} else if (heading != '/') {
|
||||
int show = slea.readByte();
|
||||
if(chr.getMap().isMuted() && !chr.isGM()) {
|
||||
chr.dropMessage(5, "The map you are in is currently muted. Please try again later.");
|
||||
|
||||
@@ -35,16 +35,17 @@ import tools.data.input.SeekableLittleEndianAccessor;
|
||||
public final class ItemMoveHandler extends AbstractMaplePacketHandler {
|
||||
@Override
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
slea.skip(4);
|
||||
slea.skip(4);
|
||||
if(c.getPlayer().getAutobanManager().getLastSpam(6) + 300 > System.currentTimeMillis()) {
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
|
||||
MapleInventoryType type = MapleInventoryType.getByType(slea.readByte());
|
||||
byte src = (byte) slea.readShort();
|
||||
byte action = (byte) slea.readShort();
|
||||
short src = slea.readShort(); //is there any reason to use byte instead of short in src and action?
|
||||
short action = slea.readShort();
|
||||
short quantity = slea.readShort();
|
||||
|
||||
if (src < 0 && action > 0) {
|
||||
MapleInventoryManipulator.unequip(c, src, action);
|
||||
} else if (action < 0) {
|
||||
|
||||
@@ -62,7 +62,6 @@ public final class MagicDamageHandler extends AbstractDealDamageHandler {
|
||||
if (player.getMap().isDojoMap() && attack.numAttacked > 0) {
|
||||
player.setDojoEnergy(player.getDojoEnergy() + + ServerConstants.DOJO_ENERGY_ATK);
|
||||
c.announce(MaplePacketCreator.getEnergy("energy", player.getDojoEnergy()));
|
||||
System.out.println("gauge " + player.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;
|
||||
|
||||
@@ -25,10 +25,7 @@ import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import client.inventory.PetCommand;
|
||||
import client.inventory.PetDataFactory;
|
||||
import client.inventory.Item;
|
||||
import client.inventory.MapleInventoryType;
|
||||
import client.inventory.MaplePet;
|
||||
import constants.ExpTable;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.Randomizer;
|
||||
|
||||
@@ -51,9 +51,6 @@ import client.inventory.MaplePet;
|
||||
import client.inventory.PetDataFactory;
|
||||
import constants.GameConstants;
|
||||
import constants.ServerConstants;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import server.TimerManager;
|
||||
|
||||
public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
|
||||
|
||||
@@ -152,7 +149,6 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
|
||||
con.close();
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
//ignore
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
@@ -226,13 +222,17 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
|
||||
player.showNote();
|
||||
if (player.getParty() != null) {
|
||||
MaplePartyCharacter pchar = player.getMPC();
|
||||
|
||||
//Use this in case of enabling party HPbar HUD when logging in, however "you created a party" will appear on chat.
|
||||
//c.announce(MaplePacketCreator.partyCreated(pchar));
|
||||
|
||||
pchar.setChannel(c.getChannel());
|
||||
pchar.setMapId(player.getMapId());
|
||||
pchar.setOnline(true);
|
||||
world.updateParty(player.getParty().getId(), PartyOperation.LOG_ONOFF, pchar);
|
||||
player.updatePartyMemberHP();
|
||||
}
|
||||
player.updatePartyMemberHP();
|
||||
|
||||
|
||||
if (player.getInventory(MapleInventoryType.EQUIPPED).findById(1122017) != null) {
|
||||
player.equipPendantOfSpirit();
|
||||
}
|
||||
@@ -258,7 +258,6 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
|
||||
player.changeSkillLevel(SkillFactory.getSkill(10000000 * player.getJobType() + 12), (byte) (player.getLinkedLevel() / 10), 20, -1);
|
||||
player.checkBerserk(player.isHidden());
|
||||
player.expirationTask();
|
||||
//player.setWorldRates();
|
||||
if (GameConstants.hasSPTable(player.getJob()) && player.getJob().getId() != 2001) {
|
||||
player.createDragon();
|
||||
}
|
||||
@@ -277,7 +276,6 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
|
||||
if (player.getMap().getHPDec() > 0) player.resetHpDecreaseTask();
|
||||
|
||||
player.resetPlayerRates();
|
||||
|
||||
if(ServerConstants.USE_ADD_RATES_BY_LEVEL == true) player.setPlayerRates();
|
||||
player.setWorldRates();
|
||||
player.updateCouponRates();
|
||||
|
||||
@@ -74,7 +74,6 @@ public final class RangedAttackHandler extends AbstractDealDamageHandler {
|
||||
if (player.getMap().isDojoMap() && attack.numAttacked > 0) {
|
||||
player.setDojoEnergy(player.getDojoEnergy() + ServerConstants.DOJO_ENERGY_ATK);
|
||||
c.announce(MaplePacketCreator.getEnergy("energy", player.getDojoEnergy()));
|
||||
System.out.println("gauge " + player.getDojoEnergy());
|
||||
}
|
||||
|
||||
if (attack.skill == Buccaneer.ENERGY_ORB || attack.skill == ThunderBreaker.SPARK || attack.skill == Shadower.TAUNT || attack.skill == NightLord.TAUNT) {
|
||||
|
||||
@@ -236,7 +236,6 @@ public final class TakeDamageHandler extends AbstractMaplePacketHandler {
|
||||
if (GameConstants.isDojo(map.getId())) {
|
||||
player.setDojoEnergy(player.getDojoEnergy() + ServerConstants.DOJO_ENERGY_DMG);
|
||||
c.announce(MaplePacketCreator.getEnergy("energy", player.getDojoEnergy()));
|
||||
System.out.println("gauge " + player.getDojoEnergy());
|
||||
}
|
||||
|
||||
for (MapleCharacter chr : banishPlayers) { // chill, if this list ever gets non-empty an attacker does exist, trust me :)
|
||||
|
||||
@@ -59,6 +59,7 @@ public final class UseItemHandler extends AbstractMaplePacketHandler {
|
||||
return;
|
||||
} else if (itemId == 2050002) {
|
||||
c.getPlayer().dispelDebuff(MapleDisease.WEAKEN);
|
||||
c.getPlayer().dispelDebuff(MapleDisease.SLOW);
|
||||
remove(c, slot);
|
||||
return;
|
||||
} else if (itemId == 2050003) {
|
||||
|
||||
@@ -801,6 +801,16 @@ public class AbstractPlayerInteraction {
|
||||
public void goDojoUp() {
|
||||
c.announce(MaplePacketCreator.dojoWarpUp());
|
||||
}
|
||||
|
||||
public void resetDojoEnergy() {
|
||||
c.getPlayer().setDojoEnergy(0);
|
||||
}
|
||||
|
||||
public void resetPartyDojoEnergy() {
|
||||
for(MapleCharacter pchr: c.getPlayer().getPartyMembersOnSameMap()) {
|
||||
pchr.setDojoEnergy(0);
|
||||
}
|
||||
}
|
||||
|
||||
public void enableActions() {
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
|
||||
@@ -754,6 +754,8 @@ public class MapleStatEffect {
|
||||
applyto.dispelDebuffs();
|
||||
} else if (isHeroWill()) {
|
||||
applyto.dispelDebuff(MapleDisease.SEDUCE);
|
||||
applyto.dispelDebuff(MapleDisease.ZOMBIFY);
|
||||
applyto.dispelDebuffs();
|
||||
}
|
||||
if (isComboReset()) {
|
||||
applyto.setCombo((short) 0);
|
||||
@@ -763,7 +765,7 @@ public class MapleStatEffect {
|
||||
} */
|
||||
if (hpchange != 0) {
|
||||
if (hpchange < 0 && (-hpchange) >= applyto.getHp() && (!applyto.hasDisease(MapleDisease.ZOMBIFY) || hpCon > 0)) {
|
||||
if(!ServerConstants.USE_PERMISSIVE_BUFFS) {
|
||||
if(!applyto.isGM()) {
|
||||
applyto.getClient().announce(MaplePacketCreator.enableActions());
|
||||
return false;
|
||||
}
|
||||
@@ -778,7 +780,7 @@ public class MapleStatEffect {
|
||||
int newMp = applyto.getMp() + mpchange;
|
||||
if (mpchange != 0) {
|
||||
if (mpchange < 0 && -mpchange > applyto.getMp()) {
|
||||
if(!ServerConstants.USE_PERMISSIVE_BUFFS) {
|
||||
if(!applyto.isGM()) {
|
||||
applyto.getClient().announce(MaplePacketCreator.enableActions());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -22,24 +22,24 @@
|
||||
package server;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import tools.LogHelper;
|
||||
import tools.MaplePacketCreator;
|
||||
import client.MapleCharacter;
|
||||
import client.inventory.Item;
|
||||
import client.inventory.MapleInventory;
|
||||
import client.inventory.MapleInventoryType;
|
||||
import constants.ItemConstants;
|
||||
import constants.ServerConstants;
|
||||
import tools.Pair;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Matze
|
||||
* @author Ronan (concurrency safety)
|
||||
* @author Ronan (concurrency safety & check available slots)
|
||||
*/
|
||||
public class MapleTrade {
|
||||
private MapleTrade partner = null;
|
||||
@@ -192,22 +192,12 @@ public class MapleTrade {
|
||||
}
|
||||
|
||||
private boolean fitsInInventory() {
|
||||
MapleItemInformationProvider mii = MapleItemInformationProvider.getInstance();
|
||||
Map<MapleInventoryType, Integer> neededSlots = new LinkedHashMap<>();
|
||||
List<Pair<Item, MapleInventoryType>> tradeItems = new LinkedList<>();
|
||||
for (Item item : exchangeItems) {
|
||||
MapleInventoryType type = mii.getInventoryType(item.getItemId());
|
||||
if (neededSlots.get(type) == null) {
|
||||
neededSlots.put(type, 1);
|
||||
} else {
|
||||
neededSlots.put(type, neededSlots.get(type) + 1);
|
||||
}
|
||||
tradeItems.add(new Pair(item, MapleItemInformationProvider.getInstance().getInventoryType(item.getItemId())));
|
||||
}
|
||||
for (Map.Entry<MapleInventoryType, Integer> entry : neededSlots.entrySet()) {
|
||||
if (chr.getInventory(entry.getKey()).isFull(entry.getValue() - 1)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
return MapleInventory.checkSpotsAndOwnership(chr, tradeItems);
|
||||
}
|
||||
|
||||
public static void completeTrade(MapleCharacter c) {
|
||||
|
||||
@@ -72,7 +72,7 @@ public class MapleLifeFactory {
|
||||
stats.setMp(MapleDataTool.getIntConvert("maxMP", monsterInfoData, 0));
|
||||
stats.setExp(MapleDataTool.getIntConvert("exp", monsterInfoData, 0));
|
||||
stats.setLevel(MapleDataTool.getIntConvert("level", monsterInfoData));
|
||||
stats.setRemoveAfter(MapleDataTool.getIntConvert("removeAfter", monsterInfoData, 0));
|
||||
stats.setRemoveAfter(MapleDataTool.getIntConvert("removeAfter", monsterInfoData, 0));
|
||||
stats.setBoss(MapleDataTool.getIntConvert("boss", monsterInfoData, 0) > 0);
|
||||
stats.setExplosiveReward(MapleDataTool.getIntConvert("explosiveReward", monsterInfoData, 0) > 0);
|
||||
stats.setFfaLoot(MapleDataTool.getIntConvert("publicReward", monsterInfoData, 0) > 0);
|
||||
|
||||
@@ -526,7 +526,10 @@ public class MapleMap {
|
||||
if (chr.getBuffedValue(MapleBuffStat.MESOUP) != null) {
|
||||
mesos = (int) (mesos * chr.getBuffedValue(MapleBuffStat.MESOUP).doubleValue() / 100.0);
|
||||
}
|
||||
spawnMesoDrop(mesos * chr.getMesoRate(), calcDropPos(pos, mob.getPosition()), mob, chr, false, droptype);
|
||||
mesos = mesos * chr.getMesoRate();
|
||||
if(mesos <= 0) mesos = Integer.MAX_VALUE;
|
||||
|
||||
spawnMesoDrop(mesos, calcDropPos(pos, mob.getPosition()), mob, chr, false, droptype);
|
||||
}
|
||||
} else {
|
||||
if (ItemConstants.getInventoryType(de.itemId) == MapleInventoryType.EQUIP) {
|
||||
@@ -1468,7 +1471,7 @@ public class MapleMap {
|
||||
} else if (monster.getId() == 9300093) {
|
||||
monsterItemDrop(monster, new Item(4031495, (short) 0, (short) 1), monster.getDropPeriodTime());
|
||||
} else {
|
||||
FilePrinter.printError(FilePrinter.UNHANDLED_EVENT, "UNCODED TIMED MOB DETECTED: " + monster.getId());
|
||||
FilePrinter.printError(FilePrinter.UNHANDLED_EVENT, "UNCODED TIMED MOB DETECTED: " + monster.getId() + "\r\n");
|
||||
}
|
||||
}
|
||||
spawnedMonstersOnMap.incrementAndGet();
|
||||
|
||||
@@ -77,9 +77,7 @@ public class MapleMapItem extends AbstractMapleMapObject {
|
||||
}
|
||||
|
||||
public final int getItemId() {
|
||||
if (getMeso() > 0) {
|
||||
return meso;
|
||||
}
|
||||
if (meso > 0) return meso;
|
||||
return item.getItemId();
|
||||
}
|
||||
|
||||
|
||||
@@ -4234,7 +4234,7 @@ public class MaplePacketCreator {
|
||||
return mplew.getPacket();
|
||||
}
|
||||
|
||||
public static void addPetInfo(final MaplePacketLittleEndianWriter mplew, MaplePet pet, boolean showpet) {
|
||||
private static void addPetInfo(final MaplePacketLittleEndianWriter mplew, MaplePet pet, boolean showpet) {
|
||||
mplew.write(1);
|
||||
if (showpet) {
|
||||
mplew.write(0);
|
||||
|
||||
Reference in New Issue
Block a user