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:
5
docs/mcpq/src/ChangeMapHandler.txt
Normal file
5
docs/mcpq/src/ChangeMapHandler.txt
Normal 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;
|
||||
}
|
||||
22
docs/mcpq/src/ItemPickupHandler.txt
Normal file
22
docs/mcpq/src/ItemPickupHandler.txt
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
73
docs/mcpq/src/MapleCharacter.txt
Normal file
73
docs/mcpq/src/MapleCharacter.txt
Normal 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;
|
||||
}
|
||||
5
docs/mcpq/src/MapleClient.txt
Normal file
5
docs/mcpq/src/MapleClient.txt
Normal 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);
|
||||
}
|
||||
3
docs/mcpq/src/MapleLifeFactory.txt
Normal file
3
docs/mcpq/src/MapleLifeFactory.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
Add to getMonster(int monsterId):
|
||||
PHP Code:
|
||||
stats.setCp(MapleDataTool.getIntConvert("getCP", monsterInfoData, 0));
|
||||
80
docs/mcpq/src/MapleMap.txt
Normal file
80
docs/mcpq/src/MapleMap.txt
Normal 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;
|
||||
}
|
||||
22
docs/mcpq/src/MapleMapFactory.txt
Normal file
22
docs/mcpq/src/MapleMapFactory.txt
Normal 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.
|
||||
31
docs/mcpq/src/MapleMonster.txt
Normal file
31
docs/mcpq/src/MapleMonster.txt
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
13
docs/mcpq/src/MapleMonsterStats.txt
Normal file
13
docs/mcpq/src/MapleMonsterStats.txt
Normal 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;
|
||||
}
|
||||
6
docs/mcpq/src/MapleReactor.txt
Normal file
6
docs/mcpq/src/MapleReactor.txt
Normal 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;
|
||||
}
|
||||
27
docs/mcpq/src/MapleStatEffect.txt
Normal file
27
docs/mcpq/src/MapleStatEffect.txt
Normal 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;
|
||||
}
|
||||
23
docs/mcpq/src/MobSkill.txt
Normal file
23
docs/mcpq/src/MobSkill.txt
Normal 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;
|
||||
41
docs/mcpq/src/MonterCarnivalHandler.txt
Normal file
41
docs/mcpq/src/MonterCarnivalHandler.txt
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
20
docs/mcpq/src/PetLootHandler.txt
Normal file
20
docs/mcpq/src/PetLootHandler.txt
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
35
docs/mcpq/src/SpawnPoint.txt
Normal file
35
docs/mcpq/src/SpawnPoint.txt
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user