Reactor Loot + Obstacles damage mob + Static calls from scripts
Revised starting AP, now working out with flags. To supply the 9AP shortage of 4/4/4/4, two options: one giving out 9 AP from the start, other giving 4/5 AP when changing jobs (1st, 2nd). This change would also work with the autoassign for beginners flag. Refactored several quest scripts, that would be glitching the player when doing quest start/complete and disposing under the same script status. Cleared some cases with the quest reward system where it would call out a "full inventory" even though new inventory slots could get discovered when doing the quest loot transaction. Fixed an issue with player stores being deployed overlapping in a few scenarios. Fixed reduced EXP gain from kills when triggering skill Mortal Blow. Added "open Duey" functionality when clicking "O" in the incoming package notification. Fixed packages without messages (a quirk from quick delivery) not accounting visually as a "quick" one. Fixed certain mounts (non-item skill mounts, such as Yeti or Spaceship) not showing up properly to other players when changing maps. Added handler for mob damage by environment objects (OrbisPQ jail storage area). Added a placeholder on mob's stolen items to prevent more steals to be placed as soon as the Steal mechanism is triggered. Patched boss logs not removing recent entries from the DB tables (the reset method is actually supposed to clear every entry). Revised a possible memory leak scenario happening due to an exception thrown midway monster kill method. Improved reactor drops, now placing loots visible for the acting player centered (similar as to how mob loots work). Refactored several issues in scripts, related to accessing static Java methods through an object, that would start appearing after transitioning to Java 8.
This commit is contained in:
@@ -168,6 +168,7 @@ import server.maps.MapleMapItem;
|
||||
import net.server.audit.locks.MonitoredLockType;
|
||||
import net.server.audit.locks.factory.MonitoredReentrantLockFactory;
|
||||
import org.apache.mina.util.ConcurrentHashSet;
|
||||
import scripting.quest.QuestActionManager;
|
||||
import server.maps.FieldLimit;
|
||||
|
||||
public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
@@ -305,6 +306,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
private List<Integer> viptrockmaps = new ArrayList<>();
|
||||
private Map<String, MapleEvents> events = new LinkedHashMap<>();
|
||||
private PartyQuest partyQuest = null;
|
||||
private List<Pair<DelayedQuestUpdate, Object[]>> npcUpdateQuests = new LinkedList<>();
|
||||
private MapleDragon dragon = null;
|
||||
private MapleRing marriageRing;
|
||||
private int marriageItemid = -1;
|
||||
@@ -1173,7 +1175,13 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
if (this.isCygnus()) {
|
||||
gainAp(7, true);
|
||||
} else {
|
||||
gainAp(5, true);
|
||||
if (ServerConstants.USE_STARTING_AP_4 || newJob.getId() % 10 >= 1) {
|
||||
gainAp(5, true);
|
||||
}
|
||||
}
|
||||
} else { // thanks Periwinks for noticing an AP shortage from lower levels
|
||||
if (ServerConstants.USE_STARTING_AP_4 && newJob.getId() % 1000 >= 1) {
|
||||
gainAp(4, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3877,10 +3885,8 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
|
||||
List<Pair<MapleBuffStat, MapleBuffStatValueHolder>> toCancel = deregisterBuffStats(buffstats);
|
||||
if (effect.isMonsterRiding()) {
|
||||
if (effect.getSourceId() != Corsair.BATTLE_SHIP) {
|
||||
this.getClient().getWorldServer().unregisterMountHunger(this);
|
||||
this.getMount().setActive(false);
|
||||
}
|
||||
this.getClient().getWorldServer().unregisterMountHunger(this);
|
||||
this.getMount().setActive(false);
|
||||
}
|
||||
|
||||
if (!overwrite) {
|
||||
@@ -6168,7 +6174,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
spGain += (expectedSp - curSp);
|
||||
}
|
||||
|
||||
return getSpGain(spGain, curSp, job);
|
||||
return getSpGain(spGain, curSp, newJob);
|
||||
}
|
||||
|
||||
private int getUsedSp(MapleJob job) {
|
||||
@@ -7391,7 +7397,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
continue;
|
||||
}
|
||||
if (q.progress(id)) {
|
||||
client.announce(MaplePacketCreator.updateQuest(q, false));
|
||||
announceUpdateQuest(DelayedQuestUpdate.UPDATE, q, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7400,8 +7406,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
}
|
||||
}
|
||||
|
||||
public void mount(int id, int skillid) {
|
||||
public MapleMount mount(int id, int skillid) {
|
||||
maplemount = new MapleMount(this, id, skillid);
|
||||
return maplemount;
|
||||
}
|
||||
|
||||
private void playerDead() {
|
||||
@@ -9632,9 +9639,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
quests.put(q.getId(), qs);
|
||||
}
|
||||
|
||||
announce(MaplePacketCreator.updateQuest(qs, false));
|
||||
announceUpdateQuest(DelayedQuestUpdate.UPDATE, qs, false);
|
||||
if (qs.getQuest().getInfoNumber() > 0) {
|
||||
announce(MaplePacketCreator.updateQuest(qs, true));
|
||||
announceUpdateQuest(DelayedQuestUpdate.UPDATE, qs, true);
|
||||
}
|
||||
announce(MaplePacketCreator.updateQuestInfo((short) qs.getQuest().getId(), qs.getNpc()));
|
||||
}
|
||||
@@ -9657,14 +9664,61 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
}
|
||||
}
|
||||
|
||||
public enum DelayedQuestUpdate { // quest updates allow player actions during NPC talk...
|
||||
UPDATE, FORFEIT, COMPLETE
|
||||
}
|
||||
|
||||
private void announceUpdateQuestInternal(Pair<DelayedQuestUpdate, Object[]> questUpdate) {
|
||||
Object[] objs = questUpdate.getRight();
|
||||
|
||||
switch (questUpdate.getLeft()) {
|
||||
case UPDATE:
|
||||
announce(MaplePacketCreator.updateQuest((MapleQuestStatus) objs[0], (Boolean) objs[1]));
|
||||
break;
|
||||
|
||||
case FORFEIT:
|
||||
announce(MaplePacketCreator.forfeitQuest((Short) objs[0]));
|
||||
break;
|
||||
|
||||
case COMPLETE:
|
||||
announce(MaplePacketCreator.completeQuest((Short) objs[0], (Long) objs[1]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void announceUpdateQuest(DelayedQuestUpdate questUpdateType, Object... params) {
|
||||
Pair<DelayedQuestUpdate, Object[]> p = new Pair<>(questUpdateType, params);
|
||||
MapleClient c = this.getClient();
|
||||
if (c.getQM() != null || c.getCM() != null) {
|
||||
synchronized (npcUpdateQuests) {
|
||||
npcUpdateQuests.add(p);
|
||||
}
|
||||
} else {
|
||||
announceUpdateQuestInternal(p);
|
||||
}
|
||||
}
|
||||
|
||||
public void flushDelayedUpdateQuests() {
|
||||
List<Pair<DelayedQuestUpdate, Object[]>> qmQuestUpdateList;
|
||||
|
||||
synchronized (npcUpdateQuests) {
|
||||
qmQuestUpdateList = new ArrayList<>(npcUpdateQuests);
|
||||
npcUpdateQuests.clear();
|
||||
}
|
||||
|
||||
for (Pair<DelayedQuestUpdate, Object[]> q : qmQuestUpdateList) {
|
||||
announceUpdateQuestInternal(q);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateQuest(MapleQuestStatus quest) {
|
||||
synchronized (quests) {
|
||||
quests.put(quest.getQuestID(), quest);
|
||||
}
|
||||
if (quest.getStatus().equals(MapleQuestStatus.Status.STARTED)) {
|
||||
announce(MaplePacketCreator.updateQuest(quest, false));
|
||||
announceUpdateQuest(DelayedQuestUpdate.UPDATE, quest, false);
|
||||
if (quest.getQuest().getInfoNumber() > 0) {
|
||||
announce(MaplePacketCreator.updateQuest(quest, true));
|
||||
announceUpdateQuest(DelayedQuestUpdate.UPDATE, quest, true);
|
||||
}
|
||||
announce(MaplePacketCreator.updateQuestInfo((short) quest.getQuest().getId(), quest.getNpc()));
|
||||
} else if (quest.getStatus().equals(MapleQuestStatus.Status.COMPLETED)) {
|
||||
@@ -9675,11 +9729,11 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
}
|
||||
quest.setCompleted(quest.getCompleted() + 1); // count quest completed Jayd's idea
|
||||
|
||||
announce(MaplePacketCreator.completeQuest(questid, quest.getCompletionTime()));
|
||||
announceUpdateQuest(DelayedQuestUpdate.COMPLETE, questid, quest.getCompletionTime());
|
||||
} else if (quest.getStatus().equals(MapleQuestStatus.Status.NOT_STARTED)) {
|
||||
announce(MaplePacketCreator.updateQuest(quest, false));
|
||||
announceUpdateQuest(DelayedQuestUpdate.UPDATE, quest, false);
|
||||
if (quest.getQuest().getInfoNumber() > 0) {
|
||||
announce(MaplePacketCreator.updateQuest(quest, true));
|
||||
announceUpdateQuest(DelayedQuestUpdate.UPDATE, quest, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import client.MapleJob;
|
||||
import client.Skill;
|
||||
import client.inventory.Item;
|
||||
import client.inventory.MapleInventoryType;
|
||||
import constants.ServerConstants;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
@@ -39,7 +40,7 @@ public class CharacterFactoryRecipe {
|
||||
private int level, map, top, bottom, shoes, weapon;
|
||||
private int str = 4, dex = 4, int_ = 4, luk = 4;
|
||||
private int maxHp = 50, maxMp = 5;
|
||||
private int ap = 9, sp = 0;
|
||||
private int ap = 0, sp = 0;
|
||||
private int meso = 0;
|
||||
private List<Pair<Skill, Integer>> skills = new LinkedList<>();
|
||||
|
||||
@@ -54,6 +55,15 @@ public class CharacterFactoryRecipe {
|
||||
this.bottom = bottom;
|
||||
this.shoes = shoes;
|
||||
this.weapon = weapon;
|
||||
|
||||
if (!ServerConstants.USE_STARTING_AP_4) {
|
||||
if (ServerConstants.USE_AUTOASSIGN_STARTERS_AP) {
|
||||
str = 12;
|
||||
dex = 5;
|
||||
} else {
|
||||
ap = 9;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setStr(int v) {
|
||||
|
||||
@@ -60,6 +60,7 @@ import tools.Pair;
|
||||
public class DueyProcessor {
|
||||
|
||||
public enum Actions {
|
||||
TOSERVER_RECV_ITEM(0x00),
|
||||
TOSERVER_SEND_ITEM(0x02),
|
||||
TOSERVER_CLAIM_PACKAGE(0x04),
|
||||
TOSERVER_REMOVE_PACKAGE(0x05),
|
||||
@@ -113,15 +114,6 @@ public class DueyProcessor {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Timestamp getCurrentDate(boolean quick) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
if (!quick) {
|
||||
cal.add(Calendar.DATE, 1);
|
||||
}
|
||||
|
||||
return new Timestamp(cal.getTime().getTime());
|
||||
}
|
||||
|
||||
private static void showDueyNotification(MapleClient c, MapleCharacter player) {
|
||||
Connection con = null;
|
||||
PreparedStatement ps = null;
|
||||
@@ -204,7 +196,7 @@ public class DueyProcessor {
|
||||
|
||||
dueypack.setSender(rs.getString("SenderName"));
|
||||
dueypack.setMesos(rs.getInt("Mesos"));
|
||||
dueypack.setSentTime(rs.getTimestamp("TimeStamp"));
|
||||
dueypack.setSentTime(rs.getTimestamp("TimeStamp"), rs.getBoolean("Type"));
|
||||
dueypack.setMessage(rs.getString("Message"));
|
||||
|
||||
return dueypack;
|
||||
@@ -250,7 +242,7 @@ public class DueyProcessor {
|
||||
ps.setInt(1, toCid);
|
||||
ps.setString(2, sender);
|
||||
ps.setInt(3, mesos);
|
||||
ps.setTimestamp(4, getCurrentDate(quick));
|
||||
ps.setTimestamp(4, new Timestamp(System.currentTimeMillis()));
|
||||
ps.setString(5, message);
|
||||
ps.setInt(6, quick ? 1 : 0);
|
||||
|
||||
@@ -515,7 +507,11 @@ public class DueyProcessor {
|
||||
}
|
||||
c.getPlayer().setNpcCooldown(timeNow);
|
||||
|
||||
c.announce(MaplePacketCreator.sendDuey(quickDelivery ? 0x1A : 0x8, loadPackages(c.getPlayer())));
|
||||
if (quickDelivery) {
|
||||
c.announce(MaplePacketCreator.sendDuey(0x1A, null));
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.sendDuey(0x8, loadPackages(c.getPlayer())));
|
||||
}
|
||||
} finally {
|
||||
c.releaseClient();
|
||||
}
|
||||
@@ -523,7 +519,7 @@ public class DueyProcessor {
|
||||
}
|
||||
|
||||
public static void dueyCreatePackage(Item item, int mesos, String sender, int recipientCid) {
|
||||
int packageId = createPackage(mesos, "", sender, recipientCid, false);
|
||||
int packageId = createPackage(mesos, null, sender, recipientCid, false);
|
||||
if (packageId != -1) {
|
||||
insertPackageItem(packageId, item);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user