Guild PQ + fixed negative EXP error
Implemented Guild PQ. Fixed a problem introduced earlier where negative EXP would be deemed as "integer overflow", provoking many game breaking issues as result.
This commit is contained in:
@@ -281,8 +281,9 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
private boolean loggedIn = false;
|
||||
private MapleDragon dragon = null;
|
||||
private boolean useCS; //chaos scroll upon crafting item.
|
||||
private long useDuey;
|
||||
private long npcCd;
|
||||
private long petLootCd;
|
||||
private long lastHpDec = 0;
|
||||
private int newWarpMap = -1;
|
||||
|
||||
private MapleCharacter() {
|
||||
@@ -310,10 +311,6 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
petLootCd = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public void setHpDecreaseTask(ScheduledFuture<?> mapDotTask) {
|
||||
hpDecreaseTask = mapDotTask;
|
||||
}
|
||||
|
||||
public MapleJob getJobStyle() {
|
||||
int jobtype = this.getJob().getId() / 100;
|
||||
|
||||
@@ -413,12 +410,12 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
useCS = cs;
|
||||
}
|
||||
|
||||
public long getDuey() {
|
||||
return useDuey;
|
||||
public long getNpcCooldown() {
|
||||
return npcCd;
|
||||
}
|
||||
|
||||
public void setDuey(long d) {
|
||||
useDuey = d;
|
||||
public void setNpcCooldown(long d) {
|
||||
npcCd = d;
|
||||
}
|
||||
|
||||
public void addCooldown(int skillId, long startTime, long length, ScheduledFuture<?> timer) {
|
||||
@@ -1104,7 +1101,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
}
|
||||
|
||||
protected MapleMap getWarpMap(int map) {
|
||||
public MapleMap getWarpMap(int map) {
|
||||
MapleMap target;
|
||||
if (getEventInstance() == null) {
|
||||
target = client.getChannelServer().getMapFactory().getMap(map);
|
||||
@@ -1221,14 +1218,8 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
client.announce(MaplePacketCreator.updateParty(client.getChannel(), party, PartyOperation.SILENT_UPDATE, null));
|
||||
updatePartyMemberHP();
|
||||
}
|
||||
if (getMap().getHPDec() > 0) {
|
||||
hpDecreaseTask = TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
doHurtHp();
|
||||
}
|
||||
}, 10000);
|
||||
}
|
||||
|
||||
if (getMap().getHPDec() > 0) resetHpDecreaseTask();
|
||||
}
|
||||
else {
|
||||
FilePrinter.printError(FilePrinter.MAPLE_MAP, "Character " + this.getName() + " got stuck when moving to map " + map.getId() + ".");
|
||||
@@ -1381,7 +1372,13 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
this.getMap().broadcastMessage(pickupPacket, mapitem.getPosition());
|
||||
this.getMap().removeMapObject(ob);
|
||||
mapitem.setPickedUp(true);
|
||||
} else if (MapleInventoryManipulator.addFromDrop(client, mapitem.getItem(), false)) {
|
||||
} else if(mapitem.getItemId() == 4031865 || mapitem.getItemId() == 4031866) {
|
||||
// Add NX to account, show effect and make item disappear
|
||||
this.getCashShop().gainCash(1, mapitem.getItemId() == 4031865 ? 100 : 250);
|
||||
this.getMap().broadcastMessage(pickupPacket, mapitem.getPosition());
|
||||
this.getMap().removeMapObject(ob);
|
||||
mapitem.setPickedUp(true);
|
||||
} else if (MapleInventoryManipulator.addFromDrop(client, mapitem.getItem(), true)) {
|
||||
this.getMap().broadcastMessage(pickupPacket, mapitem.getPosition());
|
||||
this.getMap().removeMapObject(ob);
|
||||
mapitem.setPickedUp(true);
|
||||
@@ -1928,9 +1925,10 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
}
|
||||
|
||||
public void doHurtHp() {
|
||||
private void doHurtHp() {
|
||||
if (!(this.getInventory(MapleInventoryType.EQUIPPED).findById(getMap().getHPDecProtect()) != null || buffMapProtection())) {
|
||||
addHP(-getMap().getHPDec());
|
||||
lastHpDec = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
hpDecreaseTask = TimerManager.getInstance().schedule(new Runnable() {
|
||||
@@ -1940,7 +1938,25 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
}, 10000);
|
||||
}
|
||||
|
||||
|
||||
public void resetHpDecreaseTask() {
|
||||
if (hpDecreaseTask != null) {
|
||||
hpDecreaseTask.cancel(false);
|
||||
}
|
||||
|
||||
long lastHpTask = System.currentTimeMillis() - lastHpDec;
|
||||
if(lastHpTask >= 10000) {
|
||||
doHurtHp();
|
||||
} else {
|
||||
hpDecreaseTask = TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
doHurtHp();
|
||||
}
|
||||
}, lastHpTask);
|
||||
}
|
||||
}
|
||||
|
||||
public void dropMessage(String message) {
|
||||
dropMessage(0, message);
|
||||
}
|
||||
@@ -2086,14 +2102,24 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
|
||||
if(gain < 0) gain = Integer.MAX_VALUE; // integer overflow, heh.
|
||||
if(party < 0) party = Integer.MAX_VALUE; // integer overflow, heh.
|
||||
int equip = (int)Math.min((long)((gain / 10) * pendantExp), Integer.MAX_VALUE);
|
||||
|
||||
long total = gain + equip + party;
|
||||
gainExpInternal(total, equip, party, show, inChat, white);
|
||||
}
|
||||
|
||||
public void loseExp(int loss, boolean show, boolean inChat) {
|
||||
loseExp(loss, show, inChat, true);
|
||||
}
|
||||
|
||||
public void loseExp(int loss, boolean show, boolean inChat, boolean white) {
|
||||
gainExpInternal(-loss, 0, 0, show, inChat, white);
|
||||
}
|
||||
|
||||
private void gainExpInternal(long gain, int equip, int party, boolean show, boolean inChat, boolean white) {
|
||||
long total = gain;
|
||||
long total = Math.max(gain, -exp.get());
|
||||
|
||||
if (level < getMaxLevel()) {
|
||||
long leftover = 0;
|
||||
long nextExp = exp.get() + total;
|
||||
@@ -4265,9 +4291,9 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
}
|
||||
if (getExp() > XPdummy) {
|
||||
gainExp(-XPdummy, false, false);
|
||||
loseExp(XPdummy, false, false);
|
||||
} else {
|
||||
gainExp(-getExp(), false, false);
|
||||
loseExp(getExp(), false, false);
|
||||
}
|
||||
}
|
||||
if (getBuffedValue(MapleBuffStat.MORPH) != null) {
|
||||
|
||||
@@ -972,7 +972,7 @@ public class MapleClient {
|
||||
}
|
||||
|
||||
public void setScriptEngine(String name, ScriptEngine e) {
|
||||
engines.put(name, e);
|
||||
engines.put(name, e);
|
||||
}
|
||||
|
||||
public ScriptEngine getScriptEngine(String name) {
|
||||
@@ -980,7 +980,7 @@ public class MapleClient {
|
||||
}
|
||||
|
||||
public void removeScriptEngine(String name) {
|
||||
engines.remove(name);
|
||||
engines.remove(name);
|
||||
}
|
||||
|
||||
public ScheduledFuture<?> getIdleTask() {
|
||||
|
||||
@@ -97,8 +97,8 @@ public class AutobanManager {
|
||||
* 3: ItemIdSort<br>
|
||||
* 4: SpecialMove<br>
|
||||
* 5: UseCatchItem<br>
|
||||
* 6: Item Drop<br>
|
||||
* 7: Chat<br>
|
||||
* 6: Item Drop<br>
|
||||
* 7: Chat<br>
|
||||
*
|
||||
* @param type type
|
||||
* @return Timestamp checker
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
package client.command;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
@@ -708,13 +709,25 @@ public class Commands {
|
||||
player.dropMessage(6, "Current map id " + player.getMap().getId() + ", event: '" + ((player.getMap().getEventInstance() != null) ? player.getMap().getEventInstance().getName() : "null") + "'; Players: " + player.getMap().getAllPlayers().size() + ", Mobs: " + player.getMap().countMonsters() + ", Reactors: " + player.getMap().countReactors() + ", Items: " + player.getMap().countItems() + ".");
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case "debugevent":
|
||||
if(ServerConstants.USE_DEBUG) {
|
||||
if(player.getEventInstance() == null) player.dropMessage(6, "Player currently not in an event.");
|
||||
else player.dropMessage(6, "Current event name: " + player.getEventInstance().getName() + ".");
|
||||
}
|
||||
break;
|
||||
|
||||
case "debugareas":
|
||||
if(ServerConstants.USE_DEBUG) {
|
||||
player.dropMessage(6, "Configured areas on map " + player.getMapId() + ":");
|
||||
|
||||
byte index = 0;
|
||||
for(Rectangle rect: player.getMap().getAreas()) {
|
||||
player.dropMessage(6, "Id: " + index + " -> posX: " + rect.getX() + " posY: '" + rect.getY() + "' dX: " + rect.getWidth() + " dY: " + rect.getHeight() + ".");
|
||||
index++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "debugreactors":
|
||||
if(ServerConstants.USE_DEBUG) {
|
||||
@@ -722,7 +735,7 @@ public class Commands {
|
||||
|
||||
for(MapleMapObject mmo: player.getMap().getReactors()) {
|
||||
MapleReactor mr = (MapleReactor) mmo;
|
||||
player.dropMessage(6, "Reactor id: " + mr.getId() + " name: '" + mr.getName() + "' -> Type: " + mr.getReactorType() + " State: " + mr.getState() + " Event State: " + mr.getEventState() + " Position: x " + mr.getPosition().getX() + " y " + mr.getPosition().getY() + ".");
|
||||
player.dropMessage(6, "Id: " + mr.getId() + " Oid: " + mr.getObjectId() + " name: '" + mr.getName() + "' -> Type: " + mr.getReactorType() + " State: " + mr.getState() + " Event State: " + mr.getEventState() + " Position: x " + mr.getPosition().getX() + " y " + mr.getPosition().getY() + ".");
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -986,7 +999,7 @@ public class Commands {
|
||||
} else if (sub[0].equals("whereami")) { //This is so not going to work on the first commit
|
||||
player.yellowMessage("Map ID: " + player.getMap().getId());
|
||||
player.yellowMessage("Players on this map:");
|
||||
for (MapleMapObject mmo : player.getMap().getAllPlayer()) {
|
||||
for (MapleMapObject mmo : player.getMap().getPlayers()) {
|
||||
MapleCharacter chr = (MapleCharacter) mmo;
|
||||
player.dropMessage(5, ">> " + chr.getName());
|
||||
}
|
||||
@@ -1203,18 +1216,25 @@ public class Commands {
|
||||
}
|
||||
}
|
||||
if (victim != null) {
|
||||
boolean changingEvent = true;
|
||||
|
||||
if (victim.getEventInstance() != null) {
|
||||
victim.getEventInstance().unregisterPlayer(victim);
|
||||
if(player.getEventInstance() != null && victim.getEventInstance().getLeaderId() == player.getEventInstance().getLeaderId()) {
|
||||
changingEvent = false;
|
||||
}
|
||||
else {
|
||||
victim.getEventInstance().unregisterPlayer(victim);
|
||||
}
|
||||
}
|
||||
//Attempt to join the warpers instance.
|
||||
if (player.getEventInstance() != null) {
|
||||
if (player.getEventInstance() != null && changingEvent) {
|
||||
if (player.getClient().getChannel() == victim.getClient().getChannel()) {//just in case.. you never know...
|
||||
player.getEventInstance().registerPlayer(victim);
|
||||
victim.changeMap(player.getEventInstance().getMapInstance(player.getMapId()), player.getMap().findClosestPortal(player.getPosition()));
|
||||
} else {
|
||||
player.dropMessage("Target isn't on your channel, not able to warp into event instance.");
|
||||
}
|
||||
} else {//If victim isn't in an event instance, just warp them.
|
||||
} else {//If victim isn't in an event instance or is in the same event instance as the one the caller is, just warp them.
|
||||
victim.changeMap(player.getMapId(), player.getMap().findClosestPortal(player.getPosition()));
|
||||
}
|
||||
if (player.getClient().getChannel() != victim.getClient().getChannel()) {//And then change channel if needed.
|
||||
@@ -1348,7 +1368,7 @@ public class Commands {
|
||||
MapleMonster monster = (MapleMonster) monstermo;
|
||||
if (!monster.getStats().isFriendly()) {
|
||||
map.killMonster(monster, player, true);
|
||||
monster.giveExpToCharacter(player, monster.getExp() * c.getPlayer().getExpRate(), true, 1);
|
||||
//monster.giveExpToCharacter(player, monster.getExp() * c.getPlayer().getExpRate(), true, 1);
|
||||
}
|
||||
}
|
||||
player.dropMessage("Killed " + monsters.size() + " monsters.");
|
||||
@@ -1367,7 +1387,7 @@ public class Commands {
|
||||
}
|
||||
|
||||
player.setLevel(Integer.parseInt(sub[1]) - 1);
|
||||
player.gainExp(-player.getExp(), false, false);
|
||||
player.loseExp(player.getExp(), false, false);
|
||||
player.levelUp(false);
|
||||
} else if (sub[0].equals("levelpro")) {
|
||||
if (sub.length < 2){
|
||||
@@ -1381,7 +1401,7 @@ public class Commands {
|
||||
} else if (sub[0].equals("maxstat")) {
|
||||
final String[] s = {"setall", String.valueOf(Short.MAX_VALUE)};
|
||||
executeGMCommand(c, s, heading);
|
||||
player.gainExp(-player.getExp(), false, false);
|
||||
player.loseExp(player.getExp(), false, false);
|
||||
player.setLevel(255);
|
||||
player.setFame(13337);
|
||||
player.setMaxHp(30000);
|
||||
|
||||
@@ -47,12 +47,16 @@ public class ServerConstants {
|
||||
public static final boolean USE_AUTOBAN = false; //Commands the server to detect infractors automatically.
|
||||
public static final boolean USE_ANOTHER_AUTOASSIGN = true; //Based on distributing AP accordingly with higher secondary stat on equipments.
|
||||
public static final boolean USE_REFRESH_RANK_MOVE = true;
|
||||
public static final int MAX_AP = 20000; //Max AP alloted on the auto-assigner.
|
||||
public static final int MAX_EVENT_LEVELS = 8; //Event has different levels of rewarding system.
|
||||
public static final long BLOCK_DUEY_RACE_COND = (long)(0.5 * 1000);
|
||||
public static final long PET_LOOT_UPON_ATTACK = (long)(0.7 * 1000); //Time the pet must wait before trying to pick items up.
|
||||
public static final boolean USE_PERFECT_PITCH = true; //For lvl 30 or above, each lvlup player gains 1 perfect pitch.
|
||||
|
||||
|
||||
public static final int MAX_AP = 20000; //Max AP allotted on the auto-assigner.
|
||||
public static final int MAX_EVENT_LEVELS = 8; //Event has different levels of rewarding system.
|
||||
public static final long BLOCK_NPC_RACE_CONDT = (long)(0.5 * 1000); //Time the player client must wait before reopening a conversation with an NPC.
|
||||
public static final long PET_LOOT_UPON_ATTACK = (long)(0.7 * 1000); //Time the pet must wait before trying to pick items up.
|
||||
|
||||
public static final int ITEM_EXPIRE_TIME = 3 * 60 * 1000; //Time before items start disappearing. Recommended to be set up to 3 minutes.
|
||||
|
||||
//Some Gameplay Enhancing Configuration
|
||||
public static final boolean USE_PERFECT_SCROLLING = true; //Scrolls doesn't use slots upon failure.
|
||||
public static final boolean USE_ENHANCED_CHSCROLL = true; //Equips even more powerful with chaos upgrade.
|
||||
|
||||
@@ -49,7 +49,7 @@ public final class ChangeMapHandler extends AbstractMaplePacketHandler {
|
||||
}
|
||||
if (slea.available() == 0) { //Cash Shop :)
|
||||
if(!chr.getCashShop().isOpened()) {
|
||||
c.disconnect(false, false);
|
||||
c.disconnect(false, false);
|
||||
return;
|
||||
}
|
||||
String[] socket = c.getChannelServer().getIP().split(":");
|
||||
@@ -84,14 +84,14 @@ public final class ChangeMapHandler extends AbstractMaplePacketHandler {
|
||||
chr.announce(MaplePacketCreator.showWheelsLeft(chr.getItemQuantity(5510000, false)));
|
||||
} else {
|
||||
chr.cancelAllBuffs(false);
|
||||
to = chr.getMap().getReturnMap();
|
||||
to = chr.getWarpMap(chr.getMap().getReturnMapId());
|
||||
chr.setStance(0);
|
||||
}
|
||||
chr.setHp(50);
|
||||
chr.changeMap(to, to.getRandomPlayerSpawnpoint());
|
||||
}
|
||||
} else if (targetid != -1 && chr.isGM()) {
|
||||
MapleMap to = c.getChannelServer().getMapFactory().getMap(targetid);
|
||||
MapleMap to = chr.getWarpMap(targetid);
|
||||
chr.changeMap(to, to.getPortal(0));
|
||||
} else if (targetid != -1 && !chr.isGM()) {//Thanks celino for saving me some time (:
|
||||
final int divi = chr.getMapId() / 100;
|
||||
@@ -124,7 +124,7 @@ public final class ChangeMapHandler extends AbstractMaplePacketHandler {
|
||||
}
|
||||
}
|
||||
if (warp) {
|
||||
final MapleMap to = c.getChannelServer().getMapFactory().getMap(targetid);
|
||||
final MapleMap to = chr.getWarpMap(targetid);
|
||||
chr.changeMap(to, to.getPortal(0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ public final class DueyHandler extends AbstractMaplePacketHandler {
|
||||
TOCLIENT_SAMEACC_ERROR(0x0D),
|
||||
TOCLIENT_SUCCESSFULLY_SENT(0x12),
|
||||
TOCLIENT_SUCCESSFUL_MSG(0x17),
|
||||
TOCLIENT_PACKAGE_MSG(0x1B); // Ending byte; 4 if recieved. 3 if delete.
|
||||
TOCLIENT_PACKAGE_MSG(0x1B); // Ending byte; 4 if received. 3 if delete.
|
||||
final byte code;
|
||||
|
||||
private Actions(int code) {
|
||||
|
||||
@@ -37,9 +37,9 @@ public final class GeneralChatHandler extends net.AbstractMaplePacketHandler {
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
String s = slea.readMapleAsciiString();
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
if(chr.getAutobanManager().getLastSpam(7) + 200 > System.currentTimeMillis()) {
|
||||
return;
|
||||
}
|
||||
if(chr.getAutobanManager().getLastSpam(7) + 200 > System.currentTimeMillis()) {
|
||||
return;
|
||||
}
|
||||
if (s.length() > Byte.MAX_VALUE && !chr.isGM()) {
|
||||
AutobanFactory.PACKET_EDIT.alert(c.getPlayer(), c.getPlayer().getName() + " tried to packet edit in General Chat.");
|
||||
FilePrinter.printError(FilePrinter.EXPLOITS + c.getPlayer().getName() + ".txt", c.getPlayer().getName() + " tried to send text with length of " + s.length() + "\r\n");
|
||||
@@ -70,13 +70,13 @@ public final class GeneralChatHandler extends net.AbstractMaplePacketHandler {
|
||||
chr.dropMessage(5, "The map you are in is currently muted. Please try again later.");
|
||||
return;
|
||||
}
|
||||
if (!chr.isHidden()){
|
||||
if (!chr.isHidden()) {
|
||||
chr.getMap().broadcastMessage(MaplePacketCreator.getChatText(chr.getId(), s, chr.getWhiteChat(), show));
|
||||
} else {
|
||||
chr.getMap().broadcastGMMessage(MaplePacketCreator.getChatText(chr.getId(), s, chr.getWhiteChat(), show));
|
||||
}
|
||||
}
|
||||
chr.getAutobanManager().spam(7);
|
||||
chr.getAutobanManager().spam(7);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,8 @@ public final class ItemMoveHandler extends AbstractMaplePacketHandler {
|
||||
} else {
|
||||
MapleInventoryManipulator.move(c, type, src, action);
|
||||
}
|
||||
|
||||
if (c.getPlayer().getMap().getHPDec() > 0) c.getPlayer().resetHpDecreaseTask();
|
||||
c.getPlayer().getAutobanManager().spam(6);
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,9 @@ public final class NPCTalkHandler extends AbstractMaplePacketHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
if(System.currentTimeMillis() - c.getPlayer().getNpcCooldown() < ServerConstants.BLOCK_NPC_RACE_CONDT)
|
||||
return;
|
||||
|
||||
int oid = slea.readInt();
|
||||
MapleMapObject obj = c.getPlayer().getMap().getMapObject(oid);
|
||||
if (obj instanceof MapleNPC) {
|
||||
@@ -45,10 +48,7 @@ public final class NPCTalkHandler extends AbstractMaplePacketHandler {
|
||||
if(ServerConstants.USE_DEBUG == true) c.getPlayer().dropMessage(5, "Talking to NPC " + npc.getId());
|
||||
|
||||
if (npc.getId() == 9010009) { //is duey
|
||||
if(System.currentTimeMillis() - c.getPlayer().getDuey() < ServerConstants.BLOCK_DUEY_RACE_COND)
|
||||
return;
|
||||
|
||||
c.getPlayer().setDuey(System.currentTimeMillis());
|
||||
c.getPlayer().setNpcCooldown(System.currentTimeMillis());
|
||||
c.announce(MaplePacketCreator.sendDuey((byte) 8, DueyHandler.loadItems(c.getPlayer())));
|
||||
} else if (npc.hasShop()) {
|
||||
if (c.getPlayer().getShop() != null) {
|
||||
|
||||
@@ -50,7 +50,7 @@ public class PartySearchStartHandler extends AbstractMaplePacketHandler {
|
||||
int jobs = slea.readInt();
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
MapleMap map = chr.getMap();
|
||||
Collection<MapleMapObject> mapobjs = map.getAllPlayer();
|
||||
Collection<MapleMapObject> mapobjs = map.getPlayers();
|
||||
for (MapleMapObject mapobj : mapobjs) {
|
||||
if (chr.getParty().getMembers().size() > 5) {
|
||||
break;
|
||||
|
||||
@@ -267,18 +267,7 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
|
||||
|
||||
}
|
||||
|
||||
if (player.getMap().getHPDec() > 0) {
|
||||
final MapleCharacter mc = player;
|
||||
|
||||
ScheduledFuture<?> hpDecreaseTask = TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mc.doHurtHp();
|
||||
}
|
||||
}, 10000);
|
||||
|
||||
mc.setHpDecreaseTask(hpDecreaseTask);
|
||||
}
|
||||
if (player.getMap().getHPDec() > 0) player.resetHpDecreaseTask();
|
||||
|
||||
player.dispelBuffCoupons();
|
||||
player.resetPlayerRates();
|
||||
|
||||
@@ -41,7 +41,7 @@ public final class ReactorHitHandler extends AbstractMaplePacketHandler {
|
||||
int skillid = slea.readInt();
|
||||
MapleReactor reactor = c.getPlayer().getMap().getReactorByOid(oid);
|
||||
if (reactor != null && reactor.isAlive()) {
|
||||
reactor.hitReactor(charPos, stance, skillid, c);
|
||||
reactor.hitReactor(true, charPos, stance, skillid, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -540,7 +540,7 @@ public class MapleGuild {
|
||||
this.gp += amount;
|
||||
this.writeToDB(false);
|
||||
this.guildMessage(MaplePacketCreator.updateGP(this.id, this.gp));
|
||||
this.guildMessage(MaplePacketCreator.getGPMessage(amount));
|
||||
this.guildMessage(MaplePacketCreator.getGPMessage(amount));
|
||||
}
|
||||
|
||||
public void removeGP(int amount){
|
||||
|
||||
@@ -111,6 +111,10 @@ public class MaplePartyCharacter {
|
||||
public int getJobId() {
|
||||
return jobid;
|
||||
}
|
||||
|
||||
public int getGuildId() {
|
||||
return character.getGuildId();
|
||||
}
|
||||
|
||||
public void updateDoor(MapleDoor door) {
|
||||
this.door.add(door);
|
||||
|
||||
@@ -131,13 +131,7 @@ public class AbstractPlayerInteraction {
|
||||
}
|
||||
|
||||
public MapleMap getWarpMap(int map) {
|
||||
MapleMap target;
|
||||
if (getPlayer().getEventInstance() == null) {
|
||||
target = c.getChannelServer().getMapFactory().getMap(map);
|
||||
} else {
|
||||
target = getPlayer().getEventInstance().getMapInstance(map);
|
||||
}
|
||||
return target;
|
||||
return getPlayer().getWarpMap(map);
|
||||
}
|
||||
|
||||
public MapleMap getMap(int map) {
|
||||
@@ -529,11 +523,15 @@ public class AbstractPlayerInteraction {
|
||||
return getPlayer().getParty();
|
||||
}
|
||||
|
||||
public boolean isLeader() {
|
||||
return isPartyLeader();
|
||||
}
|
||||
|
||||
public boolean isGuildLeader() {
|
||||
return getPlayer().isGuildLeader();
|
||||
}
|
||||
|
||||
public boolean isLeader() {
|
||||
public boolean isPartyLeader() {
|
||||
if(getParty() == null)
|
||||
return false;
|
||||
|
||||
|
||||
@@ -952,7 +952,11 @@ public class EventInstanceManager {
|
||||
}
|
||||
|
||||
public final void showWrongEffect() {
|
||||
MapleMap map = getMapInstance(getLeader().getMapId());
|
||||
showWrongEffect(getLeader().getMapId());
|
||||
}
|
||||
|
||||
public final void showWrongEffect(int mapId) {
|
||||
MapleMap map = getMapInstance(mapId);
|
||||
map.broadcastMessage(MaplePacketCreator.showEffect("quest/party/wrong_kor"));
|
||||
map.broadcastMessage(MaplePacketCreator.playSound("Party1/Failed"));
|
||||
}
|
||||
@@ -962,7 +966,11 @@ public class EventInstanceManager {
|
||||
}
|
||||
|
||||
public final void showClearEffect(boolean hasGate) {
|
||||
MapleMap map = getMapInstance(getLeader().getMapId());
|
||||
showClearEffect(hasGate, getLeader().getMapId());
|
||||
}
|
||||
|
||||
public final void showClearEffect(boolean hasGate, int mapId) {
|
||||
MapleMap map = getMapInstance(mapId);
|
||||
map.broadcastMessage(MaplePacketCreator.showEffect("quest/party/clear"));
|
||||
map.broadcastMessage(MaplePacketCreator.playSound("Party1/Clear"));
|
||||
if(hasGate) {
|
||||
|
||||
@@ -145,9 +145,17 @@ public class EventManager {
|
||||
}, timestamp);
|
||||
}
|
||||
|
||||
public World getWorldServer() {
|
||||
return wserv;
|
||||
}
|
||||
|
||||
public Channel getChannelServer() {
|
||||
return cserv;
|
||||
}
|
||||
|
||||
public Invocable getIv() {
|
||||
return iv;
|
||||
}
|
||||
|
||||
public EventInstanceManager getInstance(String name) {
|
||||
return instances.get(name);
|
||||
@@ -173,10 +181,6 @@ public class EventManager {
|
||||
}, lobbyDelay * 1000);
|
||||
}
|
||||
|
||||
public Invocable getIv() {
|
||||
return iv;
|
||||
}
|
||||
|
||||
public void setProperty(String key, String value) {
|
||||
props.setProperty(key, value);
|
||||
}
|
||||
@@ -298,8 +302,8 @@ public class EventManager {
|
||||
return startInstance(-1, chr);
|
||||
}
|
||||
|
||||
public boolean startInstance(int lobbyId, MapleCharacter chr) {
|
||||
return startInstance(lobbyId, chr, chr, 1);
|
||||
public boolean startInstance(int lobbyId, MapleCharacter leader) {
|
||||
return startInstance(lobbyId, null, leader, 1);
|
||||
}
|
||||
|
||||
public boolean startInstance(int lobbyId, MapleCharacter chr, MapleCharacter leader, int difficulty) {
|
||||
@@ -321,7 +325,7 @@ public class EventManager {
|
||||
instanceLocks.put(eim.getName(), lobbyId);
|
||||
eim.setLeader(leader);
|
||||
|
||||
eim.registerPlayer(chr);
|
||||
if(chr != null) eim.registerPlayer(chr);
|
||||
iv.invokeFunction("afterSetup", eim);
|
||||
} catch (ScriptException | NoSuchMethodException ex) {
|
||||
Logger.getLogger(EventManager.class.getName()).log(Level.SEVERE, null, ex);
|
||||
@@ -502,7 +506,8 @@ public class EventManager {
|
||||
private void exportReadyGuild(Integer guildId) {
|
||||
MapleGuild mg = server.getGuild(guildId);
|
||||
String callout = "Your guild has been registered to attend to the Sharenian Guild Quest at channel " + this.getChannelServer().getId()
|
||||
+ " and JUST STARTED THE STRATEGY PHASE. After 3 minutes, no more guild members will be allowed to join the effort.";
|
||||
+ " and HAS JUST STARTED THE STRATEGY PHASE. After 3 minutes, no more guild members will be allowed to join the effort."
|
||||
+ " Check out Shuang at the excavation site in Perion for more info.";
|
||||
|
||||
mg.dropMessage(0, callout);
|
||||
}
|
||||
|
||||
@@ -118,6 +118,7 @@ public class NPCScriptManager extends AbstractScriptManager {
|
||||
public void dispose(NPCConversationManager cm) {
|
||||
MapleClient c = cm.getClient();
|
||||
c.getPlayer().setCS(false);
|
||||
c.getPlayer().setNpcCooldown(System.currentTimeMillis());
|
||||
cms.remove(c);
|
||||
scripts.remove(c);
|
||||
|
||||
|
||||
@@ -148,6 +148,7 @@ public class QuestScriptManager extends AbstractScriptManager {
|
||||
public void dispose(QuestActionManager qm, MapleClient c) {
|
||||
qms.remove(c);
|
||||
scripts.remove(c);
|
||||
c.getPlayer().setNpcCooldown(System.currentTimeMillis());
|
||||
resetContext("quest/" + qm.getQuest() + ".js", c);
|
||||
}
|
||||
|
||||
|
||||
@@ -479,7 +479,7 @@ public class MapleMap {
|
||||
}
|
||||
}, null);
|
||||
|
||||
TimerManager.getInstance().schedule(new ExpireMapItemJob(mdrop), 180000);
|
||||
TimerManager.getInstance().schedule(new ExpireMapItemJob(mdrop), ServerConstants.ITEM_EXPIRE_TIME);
|
||||
activateItemReactors(mdrop, chr.getClient());
|
||||
}
|
||||
|
||||
@@ -495,7 +495,7 @@ public class MapleMap {
|
||||
}
|
||||
}, null);
|
||||
|
||||
TimerManager.getInstance().schedule(new ExpireMapItemJob(mdrop), 180000);
|
||||
TimerManager.getInstance().schedule(new ExpireMapItemJob(mdrop), ServerConstants.ITEM_EXPIRE_TIME);
|
||||
}
|
||||
|
||||
public final void disappearingItemDrop(final MapleMapObject dropper, final MapleCharacter owner, final Item item, final Point pos) {
|
||||
@@ -551,6 +551,56 @@ public class MapleMap {
|
||||
return getMapObjectsInRange(new Point(0, 0), Double.POSITIVE_INFINITY, Arrays.asList(MapleMapObjectType.ITEM));
|
||||
}
|
||||
|
||||
public int countPlayers() {
|
||||
return getMapObjectsInRange(new Point(0, 0), Double.POSITIVE_INFINITY, Arrays.asList(MapleMapObjectType.PLAYER)).size();
|
||||
}
|
||||
|
||||
public List<MapleMapObject> getPlayers() {
|
||||
return getMapObjectsInRange(new Point(0, 0), Double.POSITIVE_INFINITY, Arrays.asList(MapleMapObjectType.PLAYER));
|
||||
}
|
||||
|
||||
public List<MapleCharacter> getAllPlayers() {
|
||||
List<MapleCharacter> character = new LinkedList<>();
|
||||
chrRLock.lock();
|
||||
try {
|
||||
for (MapleCharacter a : characters) {
|
||||
character.add(a);
|
||||
}
|
||||
} finally {
|
||||
chrRLock.unlock();
|
||||
}
|
||||
|
||||
return character;
|
||||
}
|
||||
|
||||
public List<MapleCharacter> getPlayersInRange(Rectangle box, List<MapleCharacter> chr) {
|
||||
List<MapleCharacter> character = new LinkedList<>();
|
||||
chrRLock.lock();
|
||||
try {
|
||||
for (MapleCharacter a : characters) {
|
||||
if (chr.contains(a.getClient().getPlayer())) {
|
||||
if (box.contains(a.getPosition())) {
|
||||
character.add(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
chrRLock.unlock();
|
||||
}
|
||||
|
||||
return character;
|
||||
}
|
||||
|
||||
public int countAlivePlayers() {
|
||||
int count = 0;
|
||||
|
||||
for(MapleCharacter mc: getAllPlayers()) {
|
||||
if(mc.isAlive()) count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public boolean damageMonster(final MapleCharacter chr, final MapleMonster monster, final int damage) {
|
||||
if (monster.getId() == 8800000) {
|
||||
for (MapleMapObject object : chr.getMap().getMapObjects()) {
|
||||
@@ -658,7 +708,7 @@ public class MapleMap {
|
||||
int buff = monster.getBuffToGive();
|
||||
if (buff > -1) {
|
||||
MapleItemInformationProvider mii = MapleItemInformationProvider.getInstance();
|
||||
for (MapleMapObject mmo : this.getAllPlayer()) {
|
||||
for (MapleMapObject mmo : this.getPlayers()) {
|
||||
MapleCharacter character = (MapleCharacter) mmo;
|
||||
if (character.isAlive()) {
|
||||
MapleStatEffect statEffect = mii.getItemEffect(buff);
|
||||
@@ -725,14 +775,14 @@ public class MapleMap {
|
||||
}
|
||||
|
||||
public void killFriendlies(MapleMonster mob) {
|
||||
this.killMonster(mob, (MapleCharacter) getAllPlayer().get(0), false);
|
||||
this.killMonster(mob, (MapleCharacter) getPlayers().get(0), false);
|
||||
}
|
||||
|
||||
public void killMonster(int monsId) {
|
||||
for (MapleMapObject mmo : getMapObjects()) {
|
||||
if (mmo instanceof MapleMonster) {
|
||||
if (((MapleMonster) mmo).getId() == monsId) {
|
||||
this.killMonster((MapleMonster) mmo, (MapleCharacter) getAllPlayer().get(0), false);
|
||||
this.killMonster((MapleMonster) mmo, (MapleCharacter) getPlayers().get(0), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -788,43 +838,6 @@ public class MapleMap {
|
||||
}
|
||||
}
|
||||
|
||||
public List<MapleMapObject> getAllPlayer() {
|
||||
return getMapObjectsInRange(new Point(0, 0), Double.POSITIVE_INFINITY, Arrays.asList(MapleMapObjectType.PLAYER));
|
||||
}
|
||||
|
||||
|
||||
public List<MapleCharacter> getAllPlayers() {
|
||||
List<MapleCharacter> character = new LinkedList<>();
|
||||
chrRLock.lock();
|
||||
try {
|
||||
for (MapleCharacter a : characters) {
|
||||
character.add(a);
|
||||
}
|
||||
} finally {
|
||||
chrRLock.unlock();
|
||||
}
|
||||
|
||||
return character;
|
||||
}
|
||||
|
||||
public List<MapleCharacter> getPlayersInRange(Rectangle box, List<MapleCharacter> chr) {
|
||||
List<MapleCharacter> character = new LinkedList<>();
|
||||
chrRLock.lock();
|
||||
try {
|
||||
for (MapleCharacter a : characters) {
|
||||
if (chr.contains(a.getClient().getPlayer())) {
|
||||
if (box.contains(a.getPosition())) {
|
||||
character.add(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
chrRLock.unlock();
|
||||
}
|
||||
|
||||
return character;
|
||||
}
|
||||
|
||||
public void destroyReactor(int oid) {
|
||||
final MapleReactor reactor = getReactorByOid(oid);
|
||||
TimerManager tMan = TimerManager.getInstance();
|
||||
@@ -1052,12 +1065,12 @@ public class MapleMap {
|
||||
final ScheduledFuture<?> monsterItemDrop = TimerManager.getInstance().register(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (MapleMap.this.getMonsterById(m.getId()) != null && !MapleMap.this.getAllPlayer().isEmpty()) {
|
||||
if (MapleMap.this.getMonsterById(m.getId()) != null && !MapleMap.this.getPlayers().isEmpty()) {
|
||||
if (item.getItemId() == 4001101) {
|
||||
MapleMap.this.riceCakes++;
|
||||
MapleMap.this.broadcastMessage(MaplePacketCreator.serverNotice(6, "The Moon Bunny made rice cake number " + (MapleMap.this.riceCakes)));
|
||||
}
|
||||
spawnItemDrop(m, (MapleCharacter) getAllPlayer().get(0), item, m.getPosition(), false, false);
|
||||
spawnItemDrop(m, (MapleCharacter) getPlayers().get(0), item, m.getPosition(), false, false);
|
||||
}
|
||||
}
|
||||
}, delay, delay);
|
||||
@@ -1345,7 +1358,7 @@ public class MapleMap {
|
||||
broadcastMessage(MaplePacketCreator.dropItemFromMapObject(drop, dropper.getPosition(), droppos, (byte) 0));
|
||||
|
||||
if (!everlast) {
|
||||
TimerManager.getInstance().schedule(new ExpireMapItemJob(drop), 180000);
|
||||
TimerManager.getInstance().schedule(new ExpireMapItemJob(drop), ServerConstants.ITEM_EXPIRE_TIME);
|
||||
activateItemReactors(drop, owner.getClient());
|
||||
}
|
||||
}
|
||||
@@ -1438,7 +1451,7 @@ public class MapleMap {
|
||||
}
|
||||
chr.setMapId(mapid);
|
||||
if (onFirstUserEnter.length() != 0 && !chr.hasEntered(onFirstUserEnter, mapid) && MapScriptManager.getInstance().scriptExists(onFirstUserEnter, true)) {
|
||||
if (getAllPlayer().size() <= 1) {
|
||||
if (countPlayers() <= 1) {
|
||||
chr.enteredScript(onFirstUserEnter, mapid);
|
||||
MapScriptManager.getInstance().getMapScript(chr.getClient(), onFirstUserEnter, true);
|
||||
}
|
||||
@@ -2116,6 +2129,28 @@ public class MapleMap {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void makeDisappearItemFromMap(MapleMapObject mapobj) {
|
||||
if(mapobj instanceof MapleMapItem) {
|
||||
makeDisappearItemFromMap((MapleMapItem) mapobj);
|
||||
}
|
||||
}
|
||||
|
||||
public void makeDisappearItemFromMap(MapleMapItem mapitem) {
|
||||
if (mapitem != null && mapitem == getMapObject(mapitem.getObjectId())) {
|
||||
mapitem.itemLock.lock();
|
||||
try {
|
||||
if (mapitem.isPickedUp()) {
|
||||
return;
|
||||
}
|
||||
MapleMap.this.broadcastMessage(MaplePacketCreator.removeItemFromMap(mapitem.getObjectId(), 0, 0), mapitem.getPosition());
|
||||
mapitem.setPickedUp(true);
|
||||
} finally {
|
||||
mapitem.itemLock.unlock();
|
||||
MapleMap.this.removeMapObject(mapitem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ExpireMapItemJob implements Runnable {
|
||||
|
||||
@@ -2127,19 +2162,7 @@ public class MapleMap {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (mapitem != null && mapitem == getMapObject(mapitem.getObjectId())) {
|
||||
mapitem.itemLock.lock();
|
||||
try {
|
||||
if (mapitem.isPickedUp()) {
|
||||
return;
|
||||
}
|
||||
MapleMap.this.broadcastMessage(MaplePacketCreator.removeItemFromMap(mapitem.getObjectId(), 0, 0), mapitem.getPosition());
|
||||
mapitem.setPickedUp(true);
|
||||
} finally {
|
||||
mapitem.itemLock.unlock();
|
||||
MapleMap.this.removeMapObject(mapitem);
|
||||
}
|
||||
}
|
||||
makeDisappearItemFromMap(mapitem);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ public class MapleReactor extends AbstractMapleMapObject {
|
||||
private String name;
|
||||
private boolean alive;
|
||||
private boolean shouldCollect;
|
||||
private boolean attackHit;
|
||||
private Lock reactorLock = new ReentrantLock(true);
|
||||
|
||||
public MapleReactor(MapleReactorStats stats, int rid) {
|
||||
@@ -114,6 +115,10 @@ public class MapleReactor extends AbstractMapleMapObject {
|
||||
public int getReactorType() {
|
||||
return stats.getType(state);
|
||||
}
|
||||
|
||||
public boolean isRecentHitFromAttack() {
|
||||
return attackHit;
|
||||
}
|
||||
|
||||
public void setMap(MapleMap map) {
|
||||
this.map = map;
|
||||
@@ -175,14 +180,17 @@ public class MapleReactor extends AbstractMapleMapObject {
|
||||
}
|
||||
|
||||
public void hitReactor(MapleClient c) {
|
||||
hitReactor(0, (short) 0, 0, c);
|
||||
hitReactor(false, 0, (short) 0, 0, c);
|
||||
}
|
||||
|
||||
public synchronized void hitReactor(int charPos, short stance, int skillid, MapleClient c) {
|
||||
public synchronized void hitReactor(boolean wHit, int charPos, short stance, int skillid, MapleClient c) {
|
||||
try {
|
||||
if(!this.isAlive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
attackHit = wHit;
|
||||
|
||||
if(ServerConstants.USE_DEBUG == true) c.getPlayer().dropMessage(5, "Hitted REACTOR " + this.getId() + " with POS " + charPos + " , STANCE " + stance + " , SkillID " + skillid + " , STATE " + stats.getType(state) + " STATESIZE " + stats.getStateSize(state));
|
||||
ReactorScriptManager.getInstance().onHit(c, this);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user