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:
ronancpl
2017-09-01 01:20:01 -03:00
parent 001125ccdb
commit 74b4ca4132
179 changed files with 36378 additions and 35614 deletions

View File

@@ -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();

View File

@@ -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();

View File

@@ -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":

View File

@@ -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) {

View File

@@ -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"));

View File

@@ -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;

View File

@@ -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;
}
}