You are stopping the TimerManager instead of just stopping your task which will cause the ScheduledThreadPoolExecutor to shutdown and no longer run any tasks that a lot of the other classes in your source use. In this case, spawnItemDrop from MapleMap is trying to schedule the ExpireMapItemJob Runnable but you have shutdown the thread executor so it will throw that exception. Here is how you fix it:
Place this:
PHP Code:
private ScheduledFuture<?> fishTask = null;
Anywhere under these:
PHP Code:
private ScheduledFuture<?> dragonBloodSchedule;
private ScheduledFuture<?> mapTimeLimitTask = null;
private ScheduledFuture<?>[] fullnessSchedule = new ScheduledFuture<?>[3];
private ScheduledFuture<?> hpDecreaseTask;
private ScheduledFuture<?> beholderHealingSchedule, beholderBuffSchedule, BerserkSchedule;
private ScheduledFuture<?> expiretask;
private ScheduledFuture<?> recoveryTask;
And change this:
PHP Code:
public void goFish(boolean fish) {
TimerManager tMan = TimerManager.getInstance();
final MapleCharacter chr = this;
if(fish) {
//tMan.start();
tMan.register(new Runnable() {
@Override
public void run() {
Fishing.doFishing(chr);
}
},5000, 5000 );
}
else {
tMan.stop();
}
}
To this:
PHP Code:
public void goFish(boolean fish) {
TimerManager tMan = TimerManager.getInstance();
final MapleCharacter chr = this;
if(fish) {
fishTask = tMan.register(new Runnable() {
@Override
public void run() {
Fishing.doFishing(chr);
}
}, 5000, 5000);
}
else {
if (fishTask != null) {
fishTask.cancel(false);
fishTask = null; // This is because we do not want a reference to the canceled ScheduledFuture
// And in case this is called twice with false as the argument it will not try to call again.
}
}
}
And finally find the empty method in MapleCharacter that looks like this:
PHP Code:
public final void empty(final boolean remove) {
if (dragonBloodSchedule != null) {
dragonBloodSchedule.cancel(false);
}
if (hpDecreaseTask != null) {
hpDecreaseTask.cancel(false);
}
if (beholderHealingSchedule != null) {
beholderHealingSchedule.cancel(false);
}
if (beholderBuffSchedule != null) {
beholderBuffSchedule.cancel(false);
}
if (BerserkSchedule != null) {
BerserkSchedule.cancel(false);
}
if (recoveryTask != null) {
recoveryTask.cancel(false);
}
cancelExpirationTask();
for (ScheduledFuture<?> sf : timers) {
sf.cancel(false);
}
timers.clear();
if (maplemount != null) {
maplemount.empty();
maplemount = null;
}
if (remove) {
partyQuest = null;
events = null;
mpc = null;
mgc = null;
events = null;
party = null;
family = null;
client = null;
map = null;
timers = null;
}
}
And change it to this:
PHP Code:
public final void empty(final boolean remove) {
if (dragonBloodSchedule != null) {
dragonBloodSchedule.cancel(false);
}
if (hpDecreaseTask != null) {
hpDecreaseTask.cancel(false);
}
if (beholderHealingSchedule != null) {
beholderHealingSchedule.cancel(false);
}
if (beholderBuffSchedule != null) {
beholderBuffSchedule.cancel(false);
}
if (BerserkSchedule != null) {
BerserkSchedule.cancel(false);
}
if (recoveryTask != null) {
recoveryTask.cancel(false);
}
if (fishTask != null) {
fishTask.cancel(false);
}
cancelExpirationTask();
for (ScheduledFuture<?> sf : timers) {
sf.cancel(false);
}
timers.clear();
if (maplemount != null) {
maplemount.empty();
maplemount = null;
}
if (remove) {
partyQuest = null;
events = null;
mpc = null;
mgc = null;
events = null;
party = null;
family = null;
client = null;
map = null;
timers = null;
}
}
This last edit is optional but is just "good practice." You can add an isFishing method anywhere in MapleCharacter that looks like this:
PHP Code:
public boolean isFishing() {
return fishTask != null;
}
And then add it to the CancelChairHandler like this:
PHP Code:
if (id == -1) {
if (c.getPlayer().isFishing())
c.getPlayer().goFish(false);
}
This just saves some negligible overhead from calling the method because we add the null check it does but do not create any other references and simply return a value.