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

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

View File

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

View File

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

View File

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

View File

@@ -152,7 +152,6 @@ public final class ChangeMapHandler extends AbstractMaplePacketHandler {
} else {
c.announce(MaplePacketCreator.enableActions());
}
//chr.setWorldRates();
} catch (Exception e) {
e.printStackTrace();
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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