WK charges fix + Job level cap + MapleQuestItemFetcher
Fixed WK charges not overriding one another and some concurrency issues within MapleMap and EventInstanceManager. New feature: job level cap, limits EXP gain until job advancement is done. New tool: MapleQuestItemFetcher, searches through the server files for missing quest items and reports the results.
This commit is contained in:
@@ -110,7 +110,7 @@ public enum MapleBuffStat {
|
||||
// needs Soul Stone
|
||||
//end incorrect buffstats
|
||||
|
||||
//WIND_WALK(0x400000000L, true),
|
||||
WIND_WALK(0x400000000L, true),
|
||||
ARAN_COMBO(0x1000000000L, true),
|
||||
COMBO_DRAIN(0x2000000000L, true),
|
||||
COMBO_BARRIER(0x4000000000L, true),
|
||||
|
||||
@@ -2984,10 +2984,18 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
|
||||
private List<Pair<MapleBuffStat, MapleBuffStatValueHolder>> cancelEffectInternal(MapleStatEffect effect, boolean overwrite, long startTime, Set<MapleBuffStat> removedStats) {
|
||||
Map<MapleBuffStat, MapleBuffStatValueHolder> buffstats;
|
||||
Map<MapleBuffStat, MapleBuffStatValueHolder> buffstats = null;
|
||||
MapleBuffStat ombs;
|
||||
if (!overwrite) { // is removing the source effect, meaning every effect from this srcid is being purged
|
||||
buffstats = extractCurrentBuffStats(effect);
|
||||
} else { // is dropping ALL current statups that uses same stats as the given effect
|
||||
} else if ((ombs = getSingletonStatupFromEffect(effect)) != null) { // removing all effects of a buff having non-shareable buff stat.
|
||||
MapleBuffStatValueHolder mbsvh = effects.get(ombs);
|
||||
if(mbsvh != null) {
|
||||
buffstats = extractCurrentBuffStats(mbsvh.effect);
|
||||
}
|
||||
}
|
||||
|
||||
if (buffstats == null) { // all else, is dropping ALL current statups that uses same stats as the given effect
|
||||
buffstats = extractLeastRelevantStatEffectsIfFull(effect);
|
||||
}
|
||||
|
||||
@@ -3178,7 +3186,17 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
return extractedStatBuffs;
|
||||
}
|
||||
|
||||
private boolean isSingletonStatup(MapleBuffStat mbs) {
|
||||
private static MapleBuffStat getSingletonStatupFromEffect(MapleStatEffect mse) {
|
||||
for(Pair<MapleBuffStat, Integer> mbs : mse.getStatups()) {
|
||||
if(isSingletonStatup(mbs.getLeft())) {
|
||||
return mbs.getLeft();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isSingletonStatup(MapleBuffStat mbs) {
|
||||
switch(mbs) { //HPREC and MPREC are supposed to be singleton
|
||||
case COUPON_EXP1:
|
||||
case COUPON_EXP2:
|
||||
@@ -3890,9 +3908,17 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
return maxhp;
|
||||
}
|
||||
|
||||
public int getMaxLevel() {
|
||||
public int getMaxClassLevel() {
|
||||
return isCygnus() ? 120 : 200;
|
||||
}
|
||||
|
||||
public int getMaxLevel() {
|
||||
if(!ServerConstants.USE_ENFORCE_JOB_LEVEL_RANGE || isGmJob()) {
|
||||
return getMaxClassLevel();
|
||||
}
|
||||
|
||||
return GameConstants.getJobMaxLevel(job);
|
||||
}
|
||||
|
||||
public int getMaxMp() {
|
||||
return maxmp;
|
||||
@@ -4691,12 +4717,12 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
|
||||
public void increaseGuildCapacity() { //hopefully nothing is null
|
||||
if (getMeso() < getGuild().getIncreaseGuildCost(getGuild().getCapacity())) {
|
||||
if (getMeso() < MapleGuild.getIncreaseGuildCost(getGuild().getCapacity())) {
|
||||
dropMessage(1, "You don't have enough mesos.");
|
||||
return;
|
||||
}
|
||||
Server.getInstance().increaseGuildCapacity(guildid);
|
||||
gainMeso(-getGuild().getIncreaseGuildCost(getGuild().getCapacity()), true, false, false);
|
||||
gainMeso(-MapleGuild.getIncreaseGuildCost(getGuild().getCapacity()), true, false, false);
|
||||
}
|
||||
|
||||
public boolean isActiveBuffedValue(int skillid) {
|
||||
@@ -4741,13 +4767,18 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
public boolean isCygnus() {
|
||||
return getJobType() == 1;
|
||||
}
|
||||
|
||||
public boolean isGmJob() {
|
||||
int jn = job.getJobNiche();
|
||||
return jn >= 8 && jn <= 9;
|
||||
}
|
||||
|
||||
public boolean isAran() {
|
||||
return getJob().getId() >= 2000 && getJob().getId() <= 2112;
|
||||
return job.getId() >= 2000 && job.getId() <= 2112;
|
||||
}
|
||||
|
||||
public boolean isBeginnerJob() {
|
||||
return (getJob().getId() == 0 || getJob().getId() == 1000 || getJob().getId() == 2000);
|
||||
return (job.getId() == 0 || job.getId() == 1000 || job.getId() == 2000);
|
||||
}
|
||||
|
||||
public boolean isGM() {
|
||||
@@ -4852,9 +4883,9 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
}
|
||||
level++;
|
||||
if (level >= getMaxLevel()) {
|
||||
if (level >= getMaxClassLevel()) {
|
||||
exp.set(0);
|
||||
level = getMaxLevel(); //To prevent levels past 200
|
||||
level = getMaxClassLevel(); //To prevent levels past the maximum
|
||||
}
|
||||
|
||||
maxhp = Math.min(30000, maxhp);
|
||||
|
||||
@@ -57,7 +57,7 @@ public enum MapleJob {
|
||||
THUNDERBREAKER1(1500), THUNDERBREAKER2(1510), THUNDERBREAKER3(1511), THUNDERBREAKER4(1512),
|
||||
|
||||
LEGEND(2000), EVAN(2001),
|
||||
ARAN1(2100),ARAN2(2110), ARAN3(2111), ARAN4(2112),
|
||||
ARAN1(2100), ARAN2(2110), ARAN3(2111), ARAN4(2112),
|
||||
|
||||
EVAN1(2200), EVAN2(2210), EVAN3(2211), EVAN4(2212), EVAN5(2213), EVAN6(2214),
|
||||
EVAN7(2215), EVAN8(2216), EVAN9(2217), EVAN10(2218);
|
||||
|
||||
@@ -1174,7 +1174,7 @@ public class Commands {
|
||||
}
|
||||
|
||||
player.loseExp(player.getExp(), false, false);
|
||||
player.setLevel(Math.min(Integer.parseInt(sub[1]), player.getMaxLevel()) - 1);
|
||||
player.setLevel(Math.min(Integer.parseInt(sub[1]), player.getMaxClassLevel()) - 1);
|
||||
|
||||
player.resetPlayerRates();
|
||||
if(ServerConstants.USE_ADD_RATES_BY_LEVEL == true) player.setPlayerRates();
|
||||
@@ -1189,7 +1189,7 @@ public class Commands {
|
||||
break;
|
||||
}
|
||||
|
||||
while (player.getLevel() < Math.min(255, Integer.parseInt(sub[1]))) {
|
||||
while (player.getLevel() < Math.min(player.getMaxClassLevel(), Integer.parseInt(sub[1]))) {
|
||||
player.levelUp(false);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -63,7 +63,7 @@ public class MonsterStatusEffect {
|
||||
if (cancelTask != null) {
|
||||
cancelTask.cancel(false);
|
||||
}
|
||||
cancelTask = null;
|
||||
cancelTask = null;
|
||||
}
|
||||
|
||||
public ScheduledFuture<?> getCancelTask() {
|
||||
|
||||
@@ -62,7 +62,29 @@ public class GameConstants {
|
||||
330000, 340000, 350000, 360000, 370000, 380000, 390000, 400000, 410000, 420000, 430000, 440000, 450000, 460000, 470000, 480000, 490000, 500000, 510000, 520000,
|
||||
530000, 550000, 570000, 590000, 610000, 630000, 650000, 670000, 690000, 710000, 730000, 750000, 770000, 790000, 810000, 830000, 850000, 870000, 890000, 910000};
|
||||
|
||||
|
||||
public static int getJobMaxLevel(MapleJob job) {
|
||||
if(job.getId() % 1000 == 0) { // beginner
|
||||
return 10;
|
||||
|
||||
} else if(job.getId() % 100 == 0) { // 1st job
|
||||
return 30;
|
||||
|
||||
} else {
|
||||
int jobBranch = job.getId() % 10;
|
||||
|
||||
switch(jobBranch) {
|
||||
case 0:
|
||||
return 70; // 2nd job
|
||||
|
||||
case 1:
|
||||
return 120; // 3rd job
|
||||
|
||||
default:
|
||||
return (job.getId() / 1000 == 1) ? 120 : 200; // 4th job: cygnus is 120, rest is 200
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int getHiddenSkill(final int skill) {
|
||||
switch (skill) {
|
||||
case Aran.HIDDEN_FULL_DOUBLE:
|
||||
@@ -82,7 +104,6 @@ public class GameConstants {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isAranSkills(final int skill) {
|
||||
return Aran.FULL_SWING == skill || Aran.OVER_SWING == skill || Aran.COMBO_TEMPEST == skill || Aran.COMBO_FENRIR == skill || Aran.COMBO_DRAIN == skill
|
||||
|| Aran.HIDDEN_FULL_DOUBLE == skill || Aran.HIDDEN_FULL_TRIPLE == skill || Aran.HIDDEN_OVER_DOUBLE == skill || Aran.HIDDEN_OVER_TRIPLE == skill
|
||||
|
||||
@@ -17,9 +17,11 @@ public class ServerConstants {
|
||||
//Login Configuration
|
||||
public static final int CHANNEL_LOAD = 100; //Max players per channel.
|
||||
|
||||
public static final long RESPAWN_INTERVAL = 10 * 1000; //10 seconds, 10000.
|
||||
public static final long PURGING_INTERVAL = 5 * 60 * 1000;
|
||||
public static final long RANKING_INTERVAL = 60 * 60 * 1000; //60 minutes, 3600000.
|
||||
public static final long COUPON_INTERVAL = 60 * 60 * 1000; //60 minutes, 3600000.
|
||||
|
||||
public static final boolean ENABLE_PIC = false; //Pick true/false to enable or disable Pic. Delete character needs this feature ENABLED.
|
||||
public static final boolean ENABLE_PIN = false; //Pick true/false to enable or disable Pin.
|
||||
|
||||
@@ -50,6 +52,8 @@ public class ServerConstants {
|
||||
public static final boolean USE_AUTOSAVE = true; //Enables server autosaving feature (saves characters to DB each 1 hour).
|
||||
public static final boolean USE_SERVER_AUTOASSIGNER = true; //Server-builtin autoassigner, uses algorithm based on distributing AP accordingly with required secondary stat on equipments.
|
||||
public static final boolean USE_REFRESH_RANK_MOVE = true;
|
||||
public static final boolean USE_ENFORCE_MOB_LEVEL_RANGE = true; //Players N levels below the killed mob will gain no experience from defeating it.
|
||||
public static final boolean USE_ENFORCE_JOB_LEVEL_RANGE = false;//Caps the player level on the minimum required to advance their current jobs.
|
||||
public static final boolean USE_ENFORCE_OWL_SUGGESTIONS = false;//Forces the Owl of Minerva to always display the defined item array on GameConstants.OWL_DATA instead of those featured by the players.
|
||||
public static final boolean USE_ENFORCE_UNMERCHABLE_PET = true; //Forces players to not sell pets via merchants. (since non-named pets gets dirty name and other possible DB-related issues)
|
||||
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 to locate the door faster)
|
||||
@@ -57,7 +61,6 @@ public class ServerConstants {
|
||||
public static final boolean USE_ERASE_UNTRADEABLE_DROP = true; //Forces flagged untradeable items to disappear when dropped.
|
||||
public static final boolean USE_ERASE_PET_ON_EXPIRATION = false;//Forces pets to be removed from inventory when expire time comes, rather than converting it to a doll.
|
||||
public static final boolean USE_BUFF_MOST_SIGNIFICANT = true; //When applying buffs, the player will stick with the highest stat boost among the listed, rather than overwriting stats.
|
||||
public static final boolean USE_UNDERLEVELED_EXP_BLOCK = true; //Players N levels below the killed mob will gain no experience from defeating it.
|
||||
|
||||
//Server Rates And Experience
|
||||
public static final int EXP_RATE = 10;
|
||||
@@ -72,7 +75,7 @@ public class ServerConstants {
|
||||
public static final int PARTY_EXPERIENCE_MOD = 1; //Change for event stuff.
|
||||
|
||||
//Miscellaneous Configuration
|
||||
public static final byte MIN_UNDERLEVEL_TO_EXP_GAIN = 5; //Characters are unable to get EXP from a mob if their level are under this threshold, only if "USE_UNDERLEVELED_EXP_BLOCK" is enabled.
|
||||
public static final byte MIN_UNDERLEVEL_TO_EXP_GAIN = 5; //Characters are unable to get EXP from a mob if their level are under this threshold, only if "USE_ENFORCE_MOB_LEVEL_RANGE" is enabled.
|
||||
public static final byte MAX_MONITORED_BUFFSTATS = 5; //Limits accounting for "dormant" buff effects, that should take place when stronger stat buffs expires.
|
||||
public static final int MAX_AP = 32767; //Max AP allotted on the auto-assigner.
|
||||
public static final int MAX_EVENT_LEVELS = 8; //Event has different levels of rewarding system.
|
||||
@@ -81,7 +84,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 tasks 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 (null) item objects on the map item history.
|
||||
public static final int ITEM_LIMIT_ON_MAP = 200; //Max number of items allowed on a map.
|
||||
|
||||
//Some Gameplay Enhancing Configurations
|
||||
|
||||
@@ -108,7 +108,7 @@ public final class Channel {
|
||||
IoBuffer.setUseDirectBuffer(false);
|
||||
IoBuffer.setAllocator(new SimpleBufferAllocator());
|
||||
acceptor = new NioSocketAcceptor();
|
||||
TimerManager.getInstance().register(new respawnMaps(), 10000);
|
||||
TimerManager.getInstance().register(new respawnMaps(), ServerConstants.RESPAWN_INTERVAL);
|
||||
acceptor.setHandler(new MapleServerHandler(world, channel));
|
||||
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 30);
|
||||
acceptor.getFilterChain().addLast("codec", (IoFilter) new ProtocolCodecFilter(new MapleCodecFactory()));
|
||||
|
||||
@@ -45,11 +45,6 @@ public final class CancelBuffHandler extends AbstractMaplePacketHandler implemen
|
||||
int sourceid = slea.readInt();
|
||||
|
||||
switch (sourceid) {
|
||||
case NightWalker.DARK_SIGHT: // wind walk as a dark sight...
|
||||
c.getPlayer().cancelEffect(SkillFactory.getSkill(NightWalker.DARK_SIGHT).getEffect(1), false, -1);
|
||||
c.getPlayer().cancelEffect(SkillFactory.getSkill(WindArcher.WIND_WALK).getEffect(1), false, -1);
|
||||
break;
|
||||
|
||||
case FPArchMage.BIG_BANG:
|
||||
case ILArchMage.BIG_BANG:
|
||||
case Bishop.BIG_BANG:
|
||||
|
||||
@@ -178,10 +178,14 @@ public final class CloseRangeDamageHandler extends AbstractDealDamageHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((player.getSkillLevel(SkillFactory.getSkill(NightWalker.VANISH)) > 0 || player.getSkillLevel(SkillFactory.getSkill(WindArcher.WIND_WALK)) > 0 || player.getSkillLevel(SkillFactory.getSkill(Rogue.DARK_SIGHT)) > 0) && player.getBuffedValue(MapleBuffStat.DARKSIGHT) != null) {// && player.getBuffSource(MapleBuffStat.DARKSIGHT) != 9101004
|
||||
if ((player.getSkillLevel(SkillFactory.getSkill(NightWalker.VANISH)) > 0 || player.getSkillLevel(SkillFactory.getSkill(Rogue.DARK_SIGHT)) > 0) && player.getBuffedValue(MapleBuffStat.DARKSIGHT) != null) {// && player.getBuffSource(MapleBuffStat.DARKSIGHT) != 9101004
|
||||
player.cancelEffectFromBuffStat(MapleBuffStat.DARKSIGHT);
|
||||
player.cancelBuffStats(MapleBuffStat.DARKSIGHT);
|
||||
} else if(player.getSkillLevel(SkillFactory.getSkill(WindArcher.WIND_WALK)) > 0 && player.getBuffedValue(MapleBuffStat.WIND_WALK) != null) {
|
||||
player.cancelEffectFromBuffStat(MapleBuffStat.WIND_WALK);
|
||||
player.cancelBuffStats(MapleBuffStat.WIND_WALK);
|
||||
}
|
||||
|
||||
applyAttack(attack, player, attackCount);
|
||||
}
|
||||
}
|
||||
@@ -211,10 +211,15 @@ public final class RangedAttackHandler extends AbstractDealDamageHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((player.getSkillLevel(SkillFactory.getSkill(NightWalker.VANISH)) > 0 || player.getSkillLevel(SkillFactory.getSkill(WindArcher.WIND_WALK)) > 0) && player.getBuffedValue(MapleBuffStat.DARKSIGHT) != null && attack.numAttacked > 0 && player.getBuffSource(MapleBuffStat.DARKSIGHT) != 9101004) {
|
||||
|
||||
if (player.getSkillLevel(SkillFactory.getSkill(NightWalker.VANISH)) > 0 && player.getBuffedValue(MapleBuffStat.DARKSIGHT) != null && attack.numAttacked > 0 && player.getBuffSource(MapleBuffStat.DARKSIGHT) != 9101004) {
|
||||
player.cancelEffectFromBuffStat(MapleBuffStat.DARKSIGHT);
|
||||
player.cancelBuffStats(MapleBuffStat.DARKSIGHT);
|
||||
} else if(player.getSkillLevel(SkillFactory.getSkill(WindArcher.WIND_WALK)) > 0 && player.getBuffedValue(MapleBuffStat.WIND_WALK) != null && attack.numAttacked > 0) {
|
||||
player.cancelEffectFromBuffStat(MapleBuffStat.WIND_WALK);
|
||||
player.cancelBuffStats(MapleBuffStat.WIND_WALK);
|
||||
}
|
||||
|
||||
applyAttack(attack, player, bulletCount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +131,12 @@ public class EventInstanceManager {
|
||||
}
|
||||
|
||||
public EventManager getEm() {
|
||||
return em;
|
||||
sL.lock();
|
||||
try {
|
||||
return em;
|
||||
} finally {
|
||||
sL.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int getEventPlayersJobs() {
|
||||
@@ -623,7 +628,10 @@ public class EventInstanceManager {
|
||||
}
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
public synchronized void dispose() {
|
||||
if(disposed) return;
|
||||
|
||||
disposed = true;
|
||||
try {
|
||||
sL.lock();
|
||||
try {
|
||||
@@ -652,8 +660,14 @@ public class EventInstanceManager {
|
||||
killCount.clear();
|
||||
|
||||
disposeExpedition();
|
||||
if(!eventCleared) em.disposeInstance(name);
|
||||
em = null;
|
||||
|
||||
sL.lock();
|
||||
try {
|
||||
if(!eventCleared) em.disposeInstance(name);
|
||||
em = null;
|
||||
} finally {
|
||||
sL.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public MapleMapFactory getMapFactory() {
|
||||
@@ -664,12 +678,11 @@ public class EventInstanceManager {
|
||||
TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if(em == null) return;
|
||||
|
||||
try {
|
||||
sL.lock();
|
||||
try {
|
||||
em.getIv().invokeFunction(methodName, EventInstanceManager.this);
|
||||
if(em == null) return;
|
||||
em.getIv().invokeFunction(methodName, EventInstanceManager.this);
|
||||
} finally {
|
||||
sL.unlock();
|
||||
}
|
||||
@@ -685,10 +698,18 @@ public class EventInstanceManager {
|
||||
}
|
||||
|
||||
public void saveWinner(MapleCharacter chr) {
|
||||
String emName;
|
||||
sL.lock();
|
||||
try {
|
||||
emName = em.getName();
|
||||
} finally {
|
||||
sL.unlock();
|
||||
}
|
||||
|
||||
try {
|
||||
Connection con = DatabaseConnection.getConnection();
|
||||
try (PreparedStatement ps = con.prepareStatement("INSERT INTO eventstats (event, instance, characterid, channel) VALUES (?, ?, ?, ?)")) {
|
||||
ps.setString(1, em.getName());
|
||||
ps.setString(1, emName);
|
||||
ps.setString(2, getName());
|
||||
ps.setInt(3, chr.getId());
|
||||
ps.setInt(4, chr.getClient().getChannel());
|
||||
@@ -706,9 +727,14 @@ public class EventInstanceManager {
|
||||
map.setEventInstance(this);
|
||||
|
||||
if (!mapFactory.isMapLoaded(mapId)) {
|
||||
if (em.getProperty("shuffleReactors") != null && em.getProperty("shuffleReactors").equals("true")) {
|
||||
map.shuffleReactors();
|
||||
}
|
||||
sL.lock();
|
||||
try {
|
||||
if (em.getProperty("shuffleReactors") != null && em.getProperty("shuffleReactors").equals("true")) {
|
||||
map.shuffleReactors();
|
||||
}
|
||||
} finally {
|
||||
sL.unlock();
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
@@ -1035,8 +1061,14 @@ public class EventInstanceManager {
|
||||
|
||||
private void disposeExpedition() {
|
||||
if (expedition != null) {
|
||||
expedition.dispose(eventCleared);
|
||||
em.getChannelServer().getExpeditions().remove(expedition);
|
||||
expedition.dispose(eventCleared);
|
||||
|
||||
sL.lock();
|
||||
try {
|
||||
em.getChannelServer().getExpeditions().remove(expedition);
|
||||
} finally {
|
||||
sL.unlock();
|
||||
}
|
||||
|
||||
expedition = null;
|
||||
}
|
||||
@@ -1044,7 +1076,14 @@ public class EventInstanceManager {
|
||||
|
||||
public final void setEventCleared() {
|
||||
eventCleared = true;
|
||||
em.disposeInstance(name);
|
||||
|
||||
sL.lock();
|
||||
try {
|
||||
em.disposeInstance(name);
|
||||
} finally {
|
||||
sL.unlock();
|
||||
}
|
||||
|
||||
disposeExpedition();
|
||||
}
|
||||
|
||||
|
||||
@@ -1129,7 +1129,6 @@ public class MapleItemInformationProvider {
|
||||
return isQuestItemCache.get(itemId);
|
||||
}
|
||||
MapleData data = getItemData(itemId);
|
||||
System.out.println(data);
|
||||
boolean questItem = MapleDataTool.getIntConvert("info/quest", data, 0) == 1;
|
||||
isQuestItemCache.put(itemId, questItem);
|
||||
return questItem;
|
||||
|
||||
@@ -455,9 +455,10 @@ public class MapleStatEffect {
|
||||
case Marksman.SHARP_EYES:
|
||||
statups.add(new Pair<>(MapleBuffStat.SHARP_EYES, Integer.valueOf(ret.x << 8 | ret.y)));
|
||||
break;
|
||||
// THIEF
|
||||
case Rogue.DARK_SIGHT:
|
||||
case WindArcher.WIND_WALK:
|
||||
statups.add(new Pair<>(MapleBuffStat.WIND_WALK, Integer.valueOf(x)));
|
||||
break;
|
||||
case Rogue.DARK_SIGHT:
|
||||
case NightWalker.DARK_SIGHT:
|
||||
statups.add(new Pair<>(MapleBuffStat.DARKSIGHT, Integer.valueOf(x)));
|
||||
break;
|
||||
@@ -1099,6 +1100,9 @@ public class MapleStatEffect {
|
||||
} else if (isDs()) {
|
||||
List<Pair<MapleBuffStat, Integer>> dsstat = Collections.singletonList(new Pair<>(MapleBuffStat.DARKSIGHT, 0));
|
||||
mbuff = MaplePacketCreator.giveForeignBuff(applyto.getId(), dsstat);
|
||||
} else if (isWw()) {
|
||||
List<Pair<MapleBuffStat, Integer>> dsstat = Collections.singletonList(new Pair<>(MapleBuffStat.WIND_WALK, 0));
|
||||
mbuff = MaplePacketCreator.giveForeignBuff(applyto.getId(), dsstat);
|
||||
} else if (isCombo()) {
|
||||
mbuff = MaplePacketCreator.giveForeignBuff(applyto.getId(), statups);
|
||||
} else if (isMonsterRiding()) {
|
||||
@@ -1353,7 +1357,11 @@ public class MapleStatEffect {
|
||||
}
|
||||
|
||||
private boolean isDs() {
|
||||
return skill && (sourceid == Rogue.DARK_SIGHT || sourceid == WindArcher.WIND_WALK || sourceid == NightWalker.DARK_SIGHT);
|
||||
return skill && (sourceid == Rogue.DARK_SIGHT || sourceid == NightWalker.DARK_SIGHT);
|
||||
}
|
||||
|
||||
private boolean isWw() {
|
||||
return skill && (sourceid == WindArcher.WIND_WALK);
|
||||
}
|
||||
|
||||
private boolean isCombo() {
|
||||
|
||||
@@ -287,7 +287,7 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
}
|
||||
|
||||
int partyLevel = 0;
|
||||
int leechMinLevel = (ServerConstants.USE_UNDERLEVELED_EXP_BLOCK) ? getLevel() - ServerConstants.MIN_UNDERLEVEL_TO_EXP_GAIN : 0; //NO EXP WILL BE GIVEN for those who are underleveled!
|
||||
int leechMinLevel = (ServerConstants.USE_ENFORCE_MOB_LEVEL_RANGE) ? getLevel() - ServerConstants.MIN_UNDERLEVEL_TO_EXP_GAIN : 0; //NO EXP WILL BE GIVEN for those who are underleveled!
|
||||
|
||||
int leechCount = 0;
|
||||
for (MapleCharacter mc : members) {
|
||||
@@ -347,7 +347,7 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
long pXP = (long)xp + (partyExp.containsKey(pID) ? partyExp.get(pID) : 0);
|
||||
partyExp.put(pID, (int)Math.min(pXP, Integer.MAX_VALUE));
|
||||
} else {
|
||||
if(!ServerConstants.USE_UNDERLEVELED_EXP_BLOCK || mc.getLevel() >= getLevel() - ServerConstants.MIN_UNDERLEVEL_TO_EXP_GAIN) {
|
||||
if(!ServerConstants.USE_ENFORCE_MOB_LEVEL_RANGE || mc.getLevel() >= getLevel() - ServerConstants.MIN_UNDERLEVEL_TO_EXP_GAIN) {
|
||||
//NO EXP WILL BE GIVEN for those who are underleveled!
|
||||
giveExpToCharacter(mc, xp, isKiller, 1);
|
||||
} else {
|
||||
@@ -1021,8 +1021,7 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
}
|
||||
|
||||
final MapleMonster mons = this;
|
||||
TimerManager tMan = TimerManager.getInstance();
|
||||
tMan.schedule(
|
||||
TimerManager.getInstance().schedule(
|
||||
new Runnable() {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -602,6 +602,8 @@ public class MapleMap {
|
||||
private void startItemMonitor() {
|
||||
chrWLock.lock();
|
||||
try {
|
||||
if(itemMonitor != null) return;
|
||||
|
||||
itemMonitor = TimerManager.getInstance().register(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -1093,14 +1095,13 @@ public class MapleMap {
|
||||
|
||||
public void destroyReactor(int oid) {
|
||||
final MapleReactor reactor = getReactorByOid(oid);
|
||||
TimerManager tMan = TimerManager.getInstance();
|
||||
broadcastMessage(MaplePacketCreator.destroyReactor(reactor));
|
||||
reactor.cancelReactorTimeout();
|
||||
reactor.setAlive(false);
|
||||
removeMapObject(reactor);
|
||||
|
||||
if (reactor.getDelay() > 0) {
|
||||
tMan.schedule(new Runnable() {
|
||||
TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
respawnReactor(reactor);
|
||||
@@ -1879,9 +1880,12 @@ public class MapleMap {
|
||||
}
|
||||
|
||||
public void addPlayer(final MapleCharacter chr) {
|
||||
int chrSize;
|
||||
chrWLock.lock();
|
||||
try {
|
||||
characters.add(chr);
|
||||
chrSize = characters.size();
|
||||
|
||||
addPartyMemberInternal(chr);
|
||||
} finally {
|
||||
chrWLock.unlock();
|
||||
@@ -1889,7 +1893,7 @@ public class MapleMap {
|
||||
chr.setMapId(mapid);
|
||||
|
||||
itemMonitorTimeout = 1;
|
||||
if (getCharacters().size() <= 1) {
|
||||
if (chrSize == 1) {
|
||||
if(!hasItemMonitor()) startItemMonitor();
|
||||
|
||||
if (onFirstUserEnter.length() != 0 && !chr.hasEntered(onFirstUserEnter, mapid) && MapScriptManager.getInstance().scriptExists(onFirstUserEnter, true)) {
|
||||
|
||||
Reference in New Issue
Block a user