Updated Meso & Arrow drops + Aran change jobs fix + improved concurrency

Added meso drop data for many mobs that were missing mesos.
Enhanced arrow drop data, now dropping bundles instead of unitary items.
Fixed issues with several Aran change jobs crashing the player shortly after changing jobs.
Improved concurrency in MapleGuild, MapleAlliance and MaplePlayerShop.
New tools: MapleArrowFetcher and MapleMesoFetcher, that were used to compile the updated drop data info.
This commit is contained in:
ronancpl
2017-11-01 13:34:26 -02:00
parent 44949aea37
commit 64af2cfa00
192 changed files with 44793 additions and 271 deletions

View File

@@ -0,0 +1,5 @@
Under the respawn map change code (!c.getPlayer().isAlive()), add before executeStandardPath is done:
PHP Code:
if (player.getMCPQField() != null) { player.getMCPQField().onPlayerRespawn(player);
return;
}

View File

@@ -0,0 +1,22 @@
Add before items are added to inventory, or after mesos are handled:
PHP Code:
else if (c.getPlayer().getMCPQField() != null) { // CPQ Handling boolean consumed = c.getPlayer().getMCPQField().onItemPickup(c.getPlayer(), mapitem);
if (consumed) {
c.getPlayer().getMap().broadcastMessage(MaplePacketCreator.removeItemFromMap(mapitem.getObjectId(), 2, c.getPlayer().getId()),
mapitem.getPosition());
c.getPlayer().getCheatTracker().pickupComplete();
c.getPlayer().getMap().removeMapObject(ob);
} else {
if (MapleInventoryManipulator.addFromDrop(c, mapitem.getItem(), true)) {
c.getPlayer().getMap().broadcastMessage(
MaplePacketCreator.removeItemFromMap(mapitem.getObjectId(), 2, c.getPlayer().getId()),
mapitem.getPosition());
c.getPlayer().getCheatTracker().pickupComplete();
c.getPlayer().getMap().removeMapObject(ob);
} else {
c.getPlayer().getCheatTracker().pickupComplete();
return;
}
}
}

View File

@@ -0,0 +1,73 @@
client/MapleCharacter.java
Add fields:
PHP Code:
private MCField.MCTeam MCPQTeam;private MCParty MCPQParty;
private MCField MCPQField;
private int availableCP = 0;
private int totalCP = 0;
under playerDead() method:
PHP Code:
if (player.getMap().isTown()) { XPdummy *= 0.01;
} else if (MonsterCarnival.isBattlefieldMap(player.getMapId())) {
XPdummy = 0;
}
under the giveDebuff() method, add a field that force adds the disease if some variable cpq is set, regardless of buffs.
method signature:
PHP Code:
public void giveDebuff(MapleDisease disease, MobSkill skill, boolean cpq)
Add these methods:
PHP Code:
public int getTeam() { if (this.MCPQTeam == null) {
return -1;
}
return this.MCPQTeam.code;
}
public MCField.MCTeam getMCPQTeam() {
return MCPQTeam;
}
public void setMCPQTeam(MCField.MCTeam MCPQTeam) {
this.MCPQTeam = MCPQTeam;
}
public MCParty getMCPQParty() {
return MCPQParty;
}
public void setMCPQParty(MCParty MCPQParty) {
this.MCPQParty = MCPQParty;
}
public MCField getMCPQField() {
return MCPQField;
}
public void setMCPQField(MCField MCPQField) {
this.MCPQField = MCPQField;
}
public int getAvailableCP() {
return availableCP;
}
public void setAvailableCP(int availableCP) {
this.availableCP = availableCP;
}
public int getTotalCP() {
return totalCP;
}
public void setTotalCP(int totalCP) {
this.totalCP = totalCP;
}
public void gainCP(int cp) {
this.availableCP += cp;
this.totalCP += cp;
}
public void loseCP(int cp) {
this.availableCP -= cp;
}

View File

@@ -0,0 +1,5 @@
Add this under disconnect() (right after event instance calls onPlayerDisconnect, preferably):
PHP Code:
if (chr.getMCPQField() != null) {
chr.getMCPQField().onPlayerDisconnected(player);
}

View File

@@ -0,0 +1,3 @@
Add to getMonster(int monsterId):
PHP Code:
stats.setCp(MapleDataTool.getIntConvert("getCP", monsterInfoData, 0));

View File

@@ -0,0 +1,80 @@
Add fields:
PHP Code:
private boolean respawning = true;
private MCWZData mcpqData;
Add methods:
PHP Code:
public final List<MapleMonster> getAllMonsters() { return getAllMapObjects(MapleMapObjectType.MONSTER);
}
public void addMonsterSpawn(MapleMonster monster, int mobTime, int team) {
Point newpos = calcPointBelow(monster.getPosition());
newpos.y -= 1;
SpawnPoint sp = new SpawnPoint(monster, newpos, mobTime, team);
monsterSpawn.add(sp);
if (!respawning) return;
if (sp.shouldSpawn() || mobTime == -1) {
sp.spawnMonster(this);
}
}
public void setReactorState(MapleReactor reactor, byte state) {
synchronized (this.mapobjects) {
reactor.setState(state);
broadcastMessage(MaplePacketCreator.triggerReactor(reactor, state));
}
}
public <E extends MapleMapObject> List<E> getAllMapObjects(MapleMapObjectType type) {
List<E> ret = new ArrayList<>();
synchronized (mapobjects) {
for (MapleMapObject l : mapobjects.values()) {
if (l.getType() == type) {
ret.add((E) l);
}
}
}
return ret;
}
public void clearDrops() {
List<MapleMapItem> items = getAllMapObjects(MapleMapObjectType.ITEM);
for (MapleMapItem itemmo : items) {
removeMapObject(itemmo);
broadcastMessage(MaplePacketCreator.removeItemFromMap(itemmo.getObjectId(), 0, 0));
}
}
public Collection<SpawnPoint> getSpawnPoints() {
return monsterSpawn;
}
public void respawn() {
for (SpawnPoint sp : this.monsterSpawn) {
if (sp.shouldSpawn()) {
sp.spawnMonster(this);
}
}
}
public void beginSpawning() {
this.respawning = true;
this.respawn();
}
public boolean isRespawning() {
return respawning;
}
public void setRespawning(boolean respawning) {
this.respawning = respawning;
}
public MCWZData getMCPQData() {
return this.mcpqData;
}
public void setMCPQData(MCWZData data) {
this.mcpqData = data;
}

View File

@@ -0,0 +1,22 @@
Add to getMap() method, under where it parses PQ areas:
PHP Code:
MapleData mcData = mapData.getChildByPath("monsterCarnival");if (mcData != null) {
MCWZData mcpqInfo = new MCWZData(mcData);
map.setMCPQData(mcpqInfo);
map.setRespawning(false);
}
Add to getMap() method, under where it parses mobTime:
PHP Code:
int team = MapleDataTool.getInt("team", life, -1);
Change addMonsterSpawn() method call to the following, using the new SpawnPoint construction we defined in MapleMap:
PHP Code:
map.addMonsterSpawn(monster, mobTime, team);
Add the method:
PHP Code:
public MapleMap instanceMap(int mapid, boolean respawns, boolean npcs) { return instanceMap(mapid, respawns, npcs, true);
}
and
PHP Code:
public MapleMap instanceMap(int mapid, boolean respawns, boolean npcs, boolean reactors)
, where the code is the same as getMap but does not try to load from cache and does not store into cache.

View File

@@ -0,0 +1,31 @@
Add fields:
PHP Code:
private int team = -1;
Add methods:
PHP Code:
public int getCP() { return stats.getCp();
}
public int getTeam() {
return team;
}
public void setTeam(int team) {
this.team = team;
}
public void dispel() {
if (!isAlive()) return;
for (MonsterStatus i : MonsterStatus.values()) {
if (monsterBuffs.contains(i)) {
removeMonsterBuff(i);
MaplePacket packet = MaplePacketCreator.cancelMonsterStatus(getObjectId(), Collections.singletonMap(i, Integer.valueOf(1)));
map.broadcastMessage(packet, getPosition());
if (getController() != null && !getController().isMapObjectVisible(MapleMonster.this)) {
getController().getClient().getSession().write(packet);
}
}
}
}

View File

@@ -0,0 +1,13 @@
Add field:
PHP Code:
private int cp;
Add methods:
PHP Code:
public int getCp() {
return cp;
}
public void setCp(int cp) {
this.cp = cp;
}

View File

@@ -0,0 +1,6 @@
Under hitReactor(), add before standard handling:
PHP Code:
if (c.getPlayer().getMCPQField() != null) {
c.getPlayer().getMCPQField().onGuardianHit(c.getPlayer(), this);
return;
}

View File

@@ -0,0 +1,27 @@
Add fields:
PHP Code:
private boolean consumeOnPickup, party;
private int cp, nuffSkill;
Add to stat parsing (loadFromData()):
PHP Code:
ret.cp = MapleDataTool.getInt("cp", source, 0);ret.party = MapleDataTool.getInt("party", source, 0) > 0;
ret.consumeOnPickup = MapleDataTool.getInt("consumeOnPickup", source, 0) > 0;
ret.nuffSkill = MapleDataTool.getInt("nuffSkill", source, -1);
Add methods:
PHP Code:
public int getCP() { return cp;
}
public boolean isParty() {
return party;
}
public boolean isConsumeOnPickup() {
return consumeOnPickup;
}
public int getNuffSkill() {
return nuffSkill;
}

View File

@@ -0,0 +1,23 @@
Add to applyEffect():
PHP Code:
case 150: monStat = MonsterStatus.WEAPON_ATTACK_UP;
break;
case 151:
monStat = MonsterStatus.WEAPON_DEFENSE_UP;
break;
case 152:
monStat = MonsterStatus.MAGIC_ATTACK_UP;
break;
case 153:
monStat = MonsterStatus.MAGIC_DEFENSE_UP;
break;
case 154:
monStat = MonsterStatus.ACC;
break;
case 155:
monStat = MonsterStatus.AVOID;
break;
case 156:
monStat = MonsterStatus.SPEED;
break;

View File

@@ -0,0 +1,41 @@
package net.sf.odinms.net.channel.handler;
import net.sf.odinms.client.MapleCharacter;
import net.sf.odinms.client.MapleClient;
import net.sf.odinms.net.AbstractMaplePacketHandler;
import net.sf.odinms.server.partyquest.mcpq.MCField;
import net.sf.odinms.server.partyquest.mcpq.MCTracker;
import net.sf.odinms.server.partyquest.mcpq.MonsterCarnival;
import net.sf.odinms.tools.data.input.SeekableLittleEndianAccessor;
/**
* Packet handler for Monster Carnival.
* @author s4nta
*/
public class MonsterCarnivalHandler extends AbstractMaplePacketHandler {
@Override
public void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
int tab = slea.readByte();
int num = slea.readByte();
MapleCharacter chr = c.getPlayer();
if (MonsterCarnival.DEBUG) {
MCTracker.log("[MCHandler] " + chr.getName() + " used tab " + tab + " num " + num);
System.out.println("[MCHandler] " + chr.getName() + " used tab " + tab + " num " + num);
}
if (chr.getMCPQField() == null || chr.getMCPQParty() == null) {
MCTracker.log("[MCHandler] " + chr.getName() + " attempting to use Monster Carnival handler without being in Monster Carnival");
return;
}
MCField field = chr.getMCPQField();
if (tab == 0) {
field.onAddSpawn(c.getPlayer(), num);
} else if (tab == 1) {
field.onUseSkill(c.getPlayer(), num);
} else if (tab == 2) { // status
field.onGuardianSummon(c.getPlayer(), num);
}
}
}

View File

@@ -0,0 +1,20 @@
else if (c.getPlayer().getMCPQField() != null) { // CPQ Handling
boolean consumed = c.getPlayer().getMCPQField().onItemPickup(c.getPlayer(), mapitem);
if (consumed) {
c.getPlayer().getMap().broadcastMessage(MaplePacketCreator.removeItemFromMap(mapitem.getObjectId(), 2, c.getPlayer().getId()),
mapitem.getPosition());
c.getPlayer().getCheatTracker().pickupComplete();
c.getPlayer().getMap().removeMapObject(ob);
} else {
if (MapleInventoryManipulator.addFromDrop(c, mapitem.getItem(), true)) {
c.getPlayer().getMap().broadcastMessage(
MaplePacketCreator.removeItemFromMap(mapitem.getObjectId(), 2, c.getPlayer().getId()),
mapitem.getPosition());
c.getPlayer().getCheatTracker().pickupComplete();
c.getPlayer().getMap().removeMapObject(ob);
} else {
c.getPlayer().getCheatTracker().pickupComplete();
return;
}
}
}

View File

@@ -0,0 +1,35 @@
Add field:
PHP Code:
private int team = -1;
Add constructor:
PHP Code:
public SpawnPoint(MapleMonster monster, Point pos, int mobTime, int team) { super();
this.monster = monster;
this.pos = new Point(pos);
this.mobTime = mobTime;
this.immobile = !monster.isMobile();
this.nextPossibleSpawn = System.currentTimeMillis();
this.team = team;
}
Add monster death listener under spawnMonster():
PHP Code:
if (team > -1) { final int cp = mob.getCP();
mob.addListener(new MonsterListener() {
@Override
public void monsterKilled(MapleMonster monster, MapleCharacter highestDamageChar) {
if (highestDamageChar == null) {
return;
}
if (highestDamageChar.getMCPQParty() == null) {
MCTracker.log("Attempted to give CP to character without assigned MCPQ Party.");
return;
}
highestDamageChar.getMCPQField().monsterKilled(highestDamageChar, cp);
}
});
mob.setTeam(team);
}