Merge branch 'pr/427'
This commit is contained in:
+216
-150
@@ -50,7 +50,6 @@ import client.MapleCharacter;
|
||||
import client.MapleDisease;
|
||||
import client.MapleJob;
|
||||
import client.MapleMount;
|
||||
import client.MapleStat;
|
||||
import client.Skill;
|
||||
import client.SkillFactory;
|
||||
import client.inventory.Item;
|
||||
@@ -111,6 +110,10 @@ import constants.skills.SuperGM;
|
||||
import constants.skills.ThunderBreaker;
|
||||
import constants.skills.WhiteKnight;
|
||||
import constants.skills.WindArcher;
|
||||
import net.server.world.MapleParty;
|
||||
import net.server.world.MaplePartyCharacter;
|
||||
import server.partyquest.MapleCarnivalFactory;
|
||||
import server.partyquest.MapleCarnivalFactory.MCSkill;
|
||||
|
||||
/**
|
||||
* @author Matze
|
||||
@@ -129,6 +132,8 @@ public class MapleStatEffect {
|
||||
private boolean overTime, repeatEffect;
|
||||
private int sourceid;
|
||||
private int moveTo;
|
||||
private int cp, nuffSkill;
|
||||
private List<MapleDisease> cureDebuffs;
|
||||
private boolean skill;
|
||||
private List<Pair<MapleBuffStat, Integer>> statups;
|
||||
private Map<MonsterStatus, Integer> monsterStatus;
|
||||
@@ -155,17 +160,15 @@ public class MapleStatEffect {
|
||||
}
|
||||
|
||||
private static byte mapProtection(int sourceid) {
|
||||
if(sourceid == 2022001 || sourceid == 2022186) {
|
||||
if (sourceid == 2022001 || sourceid == 2022186) {
|
||||
return 1; //elnath cold
|
||||
}
|
||||
|
||||
else if(sourceid == 2022040) {
|
||||
} else if (sourceid == 2022040) {
|
||||
return 2; //aqua road underwater
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
else return 0;
|
||||
}
|
||||
|
||||
|
||||
private static MapleStatEffect loadFromData(MapleData source, int sourceid, boolean skill, boolean overTime) {
|
||||
MapleStatEffect ret = new MapleStatEffect();
|
||||
ret.duration = MapleDataTool.getIntConvert("time", source, -1);
|
||||
@@ -177,6 +180,27 @@ public class MapleStatEffect {
|
||||
ret.hpCon = (short) MapleDataTool.getInt("hpCon", source, 0);
|
||||
int iprop = MapleDataTool.getInt("prop", source, 100);
|
||||
ret.prop = iprop / 100.0;
|
||||
|
||||
ret.cp = MapleDataTool.getInt("cp", source, 0);
|
||||
List<MapleDisease> cure = new ArrayList<MapleDisease>(5);
|
||||
if (MapleDataTool.getInt("poison", source, 0) > 0) {
|
||||
cure.add(MapleDisease.POISON);
|
||||
}
|
||||
if (MapleDataTool.getInt("seal", source, 0) > 0) {
|
||||
cure.add(MapleDisease.SEAL);
|
||||
}
|
||||
if (MapleDataTool.getInt("darkness", source, 0) > 0) {
|
||||
cure.add(MapleDisease.DARKNESS);
|
||||
}
|
||||
if (MapleDataTool.getInt("weakness", source, 0) > 0) {
|
||||
cure.add(MapleDisease.WEAKEN);
|
||||
}
|
||||
if (MapleDataTool.getInt("curse", source, 0) > 0) {
|
||||
cure.add(MapleDisease.CURSE);
|
||||
}
|
||||
ret.cureDebuffs = cure;
|
||||
ret.nuffSkill = MapleDataTool.getInt("nuffSkill", source, 0);
|
||||
|
||||
ret.mobCount = MapleDataTool.getInt("mobCount", source, 1);
|
||||
ret.cooldown = MapleDataTool.getInt("cooltime", source, 0);
|
||||
ret.morphId = MapleDataTool.getInt("morph", source, 0);
|
||||
@@ -192,7 +216,7 @@ public class MapleStatEffect {
|
||||
ret.duration *= 1000; // items have their times stored in ms, of course
|
||||
ret.overTime = overTime;
|
||||
}
|
||||
|
||||
|
||||
ArrayList<Pair<MapleBuffStat, Integer>> statups = new ArrayList<>();
|
||||
ret.watk = (short) MapleDataTool.getInt("pad", source, 0);
|
||||
ret.wdef = (short) MapleDataTool.getInt("pdd", source, 0);
|
||||
@@ -200,23 +224,23 @@ public class MapleStatEffect {
|
||||
ret.mdef = (short) MapleDataTool.getInt("mdd", source, 0);
|
||||
ret.acc = (short) MapleDataTool.getIntConvert("acc", source, 0);
|
||||
ret.avoid = (short) MapleDataTool.getInt("eva", source, 0);
|
||||
|
||||
|
||||
ret.speed = (short) MapleDataTool.getInt("speed", source, 0);
|
||||
ret.jump = (short) MapleDataTool.getInt("jump", source, 0);
|
||||
|
||||
|
||||
ret.mapProtection = mapProtection(sourceid);
|
||||
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.MAP_PROTECTION, Integer.valueOf(ret.mapProtection));
|
||||
|
||||
|
||||
if (ret.overTime && ret.getSummonMovementType() == null) {
|
||||
if(!skill) {
|
||||
if(isPyramidBuff(sourceid)) {
|
||||
if (!skill) {
|
||||
if (isPyramidBuff(sourceid)) {
|
||||
ret.berserk = MapleDataTool.getInt("berserk", source, 0);
|
||||
ret.booster = MapleDataTool.getInt("booster", source, 0);
|
||||
|
||||
|
||||
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.BERSERK, Integer.valueOf(ret.berserk));
|
||||
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.BOOSTER, Integer.valueOf(ret.booster));
|
||||
|
||||
} else if(isDojoBuff(sourceid) || isHpMpRecovery(sourceid)) {
|
||||
|
||||
} else if (isDojoBuff(sourceid) || isHpMpRecovery(sourceid)) {
|
||||
ret.mhpR = (byte) MapleDataTool.getInt("mhpR", source, 0);
|
||||
ret.mhpRRate = (short) (MapleDataTool.getInt("mhpRRate", source, 0) * 100);
|
||||
ret.mmpR = (byte) MapleDataTool.getInt("mmpR", source, 0);
|
||||
@@ -224,9 +248,9 @@ public class MapleStatEffect {
|
||||
|
||||
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.HPREC, Integer.valueOf(ret.mhpR));
|
||||
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.MPREC, Integer.valueOf(ret.mmpR));
|
||||
|
||||
} else if(isRateCoupon(sourceid)) {
|
||||
switch(MapleDataTool.getInt("expR", source, 0)) {
|
||||
|
||||
} else if (isRateCoupon(sourceid)) {
|
||||
switch (MapleDataTool.getInt("expR", source, 0)) {
|
||||
case 1:
|
||||
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.COUPON_EXP1, 1);
|
||||
break;
|
||||
@@ -244,7 +268,7 @@ public class MapleStatEffect {
|
||||
break;
|
||||
}
|
||||
|
||||
switch(MapleDataTool.getInt("drpR", source, 0)) {
|
||||
switch (MapleDataTool.getInt("drpR", source, 0)) {
|
||||
case 1:
|
||||
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.COUPON_DRP1, 1);
|
||||
break;
|
||||
@@ -257,18 +281,18 @@ public class MapleStatEffect {
|
||||
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.COUPON_DRP3, 1);
|
||||
break;
|
||||
}
|
||||
} else if(isExpIncrease(sourceid)) {
|
||||
} else if (isExpIncrease(sourceid)) {
|
||||
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.EXP_INCREASE, MapleDataTool.getInt("expinc", source, 0));
|
||||
}
|
||||
} else {
|
||||
if(isMapChair(sourceid)) {
|
||||
if (isMapChair(sourceid)) {
|
||||
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.MAP_CHAIR, 1);
|
||||
} else if((sourceid == Beginner.NIMBLE_FEET || sourceid == Noblesse.NIMBLE_FEET || sourceid == Evan.NIMBLE_FEET || sourceid == Legend.AGILE_BODY) && ServerConstants.USE_ULTRA_NIMBLE_FEET == true) {
|
||||
ret.jump = (short)(ret.speed * 4);
|
||||
} else if ((sourceid == Beginner.NIMBLE_FEET || sourceid == Noblesse.NIMBLE_FEET || sourceid == Evan.NIMBLE_FEET || sourceid == Legend.AGILE_BODY) && ServerConstants.USE_ULTRA_NIMBLE_FEET == true) {
|
||||
ret.jump = (short) (ret.speed * 4);
|
||||
ret.speed *= 15;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.WATK, Integer.valueOf(ret.watk));
|
||||
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.WDEF, Integer.valueOf(ret.wdef));
|
||||
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.MATK, Integer.valueOf(ret.matk));
|
||||
@@ -278,26 +302,26 @@ public class MapleStatEffect {
|
||||
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.SPEED, Integer.valueOf(ret.speed));
|
||||
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.JUMP, Integer.valueOf(ret.jump));
|
||||
}
|
||||
|
||||
|
||||
MapleData ltd = source.getChildByPath("lt");
|
||||
if (ltd != null) {
|
||||
ret.lt = (Point) ltd.getData();
|
||||
ret.rb = (Point) source.getChildByPath("rb").getData();
|
||||
|
||||
if(ServerConstants.USE_MAXRANGE_ECHO_OF_HERO && (sourceid == Beginner.ECHO_OF_HERO || sourceid == Noblesse.ECHO_OF_HERO || sourceid == Legend.ECHO_OF_HERO || sourceid == Evan.ECHO_OF_HERO)) {
|
||||
|
||||
if (ServerConstants.USE_MAXRANGE_ECHO_OF_HERO && (sourceid == Beginner.ECHO_OF_HERO || sourceid == Noblesse.ECHO_OF_HERO || sourceid == Legend.ECHO_OF_HERO || sourceid == Evan.ECHO_OF_HERO)) {
|
||||
ret.lt = new Point(Integer.MIN_VALUE, Integer.MIN_VALUE);
|
||||
ret.rb = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int x = MapleDataTool.getInt("x", source, 0);
|
||||
|
||||
if((sourceid == Beginner.RECOVERY || sourceid == Noblesse.RECOVERY || sourceid == Evan.RECOVERY || sourceid == Legend.RECOVERY) && ServerConstants.USE_ULTRA_RECOVERY == true) {
|
||||
|
||||
if ((sourceid == Beginner.RECOVERY || sourceid == Noblesse.RECOVERY || sourceid == Evan.RECOVERY || sourceid == Legend.RECOVERY) && ServerConstants.USE_ULTRA_RECOVERY == true) {
|
||||
x *= 10;
|
||||
}
|
||||
ret.x = x;
|
||||
ret.y = MapleDataTool.getInt("y", source, 0);
|
||||
|
||||
|
||||
ret.damage = MapleDataTool.getIntConvert("damage", source, 100);
|
||||
ret.fixdamage = MapleDataTool.getIntConvert("fixdamage", source, -1);
|
||||
ret.attackCount = MapleDataTool.getIntConvert("attackCount", source, 1);
|
||||
@@ -416,8 +440,8 @@ public class MapleStatEffect {
|
||||
break;
|
||||
case BlazeWizard.ELEMENTAL_RESET:
|
||||
case Evan.ELEMENTAL_RESET:
|
||||
statups.add(new Pair<>(MapleBuffStat.ELEMENTAL_RESET, Integer.valueOf(x)));
|
||||
break;
|
||||
statups.add(new Pair<>(MapleBuffStat.ELEMENTAL_RESET, Integer.valueOf(x)));
|
||||
break;
|
||||
case Evan.MAGIC_SHIELD:
|
||||
statups.add(new Pair<>(MapleBuffStat.MAGIC_SHIELD, Integer.valueOf(x)));
|
||||
break;
|
||||
@@ -425,7 +449,7 @@ public class MapleStatEffect {
|
||||
statups.add(new Pair<>(MapleBuffStat.MAGIC_RESISTANCE, Integer.valueOf(x)));
|
||||
break;
|
||||
case Evan.SLOW:
|
||||
statups.add(new Pair<>(MapleBuffStat.SLOW, Integer.valueOf(x)));
|
||||
statups.add(new Pair<>(MapleBuffStat.SLOW, Integer.valueOf(x)));
|
||||
// BOWMAN
|
||||
case Priest.MYSTIC_DOOR:
|
||||
case Hunter.SOUL_ARROW:
|
||||
@@ -474,7 +498,7 @@ public class MapleStatEffect {
|
||||
break;
|
||||
case ChiefBandit.PICKPOCKET:
|
||||
statups.add(new Pair<>(MapleBuffStat.PICKPOCKET, Integer.valueOf(x)));
|
||||
break;
|
||||
break;
|
||||
case NightLord.SHADOW_STARS:
|
||||
statups.add(new Pair<>(MapleBuffStat.SHADOW_CLAW, Integer.valueOf(0)));
|
||||
break;
|
||||
@@ -605,7 +629,7 @@ public class MapleStatEffect {
|
||||
case Buccaneer.BARRAGE:
|
||||
case Gunslinger.BLANK_SHOT:
|
||||
case DawnWarrior.COMA:
|
||||
case ThunderBreaker.BARRAGE:
|
||||
case ThunderBreaker.BARRAGE:
|
||||
case Aran.ROLLING_SPIN:
|
||||
case Evan.FIRE_BREATH:
|
||||
case Evan.BLAZE:
|
||||
@@ -633,7 +657,7 @@ public class MapleStatEffect {
|
||||
case ILWizard.SLOW:
|
||||
case BlazeWizard.SLOW:
|
||||
monsterStatus.put(MonsterStatus.SPEED, Integer.valueOf(ret.x));
|
||||
break;
|
||||
break;
|
||||
case FPWizard.POISON_BREATH:
|
||||
case FPMage.ELEMENT_COMPOSITION:
|
||||
monsterStatus.put(MonsterStatus.POISON, Integer.valueOf(1));
|
||||
@@ -655,7 +679,7 @@ public class MapleStatEffect {
|
||||
monsterStatus.put(MonsterStatus.FREEZE, Integer.valueOf(1));
|
||||
break;
|
||||
case Evan.PHANTOM_IMPRINT:
|
||||
monsterStatus.put(MonsterStatus.PHANTOM_IMPRINT, Integer.valueOf(x));
|
||||
monsterStatus.put(MonsterStatus.PHANTOM_IMPRINT, Integer.valueOf(x));
|
||||
//ARAN
|
||||
case Aran.COMBO_ABILITY:
|
||||
statups.add(new Pair<>(MapleBuffStat.ARAN_COMBO, Integer.valueOf(100)));
|
||||
@@ -723,19 +747,19 @@ public class MapleStatEffect {
|
||||
public boolean applyEchoOfHero(MapleCharacter applyfrom) {
|
||||
Map<Integer, MapleCharacter> mapPlayers = applyfrom.getMap().getMapPlayers();
|
||||
mapPlayers.remove(applyfrom.getId());
|
||||
|
||||
|
||||
boolean hwResult = applyTo(applyfrom);
|
||||
for (MapleCharacter chr : mapPlayers.values()) { // Echo of Hero not buffing players in the map detected thanks to Masterrulax
|
||||
applyTo(applyfrom, chr, false, null, false, 1);
|
||||
}
|
||||
|
||||
|
||||
return hwResult;
|
||||
}
|
||||
|
||||
|
||||
public boolean applyTo(MapleCharacter chr) {
|
||||
return applyTo(chr, chr, true, null, false, 1);
|
||||
}
|
||||
|
||||
|
||||
public boolean applyTo(MapleCharacter chr, boolean useMaxRange) {
|
||||
return applyTo(chr, chr, true, null, useMaxRange, 1);
|
||||
}
|
||||
@@ -750,16 +774,16 @@ public class MapleStatEffect {
|
||||
applyto.toggleHide(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (primary && isHeal()) {
|
||||
affectedPlayers = applyBuff(applyfrom, useMaxRange);
|
||||
}
|
||||
|
||||
|
||||
int hpchange = calcHPChange(applyfrom, primary, affectedPlayers);
|
||||
int mpchange = calcMPChange(applyfrom, primary);
|
||||
if (primary) {
|
||||
if (itemConNo != 0) {
|
||||
if(!applyto.getClient().getAbstractPlayerInteraction().hasItem(itemCon, itemConNo)) {
|
||||
if (!applyto.getClient().getAbstractPlayerInteraction().hasItem(itemCon, itemConNo)) {
|
||||
applyto.announce(MaplePacketCreator.enableActions());
|
||||
return false;
|
||||
}
|
||||
@@ -771,7 +795,7 @@ public class MapleStatEffect {
|
||||
applyto.broadcastStance(applyto.isFacingLeft() ? 5 : 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (isDispel() && makeChanceResult()) {
|
||||
applyto.dispelDebuffs();
|
||||
} else if (isCureAllAbnormalStatus()) {
|
||||
@@ -784,24 +808,26 @@ public class MapleStatEffect {
|
||||
/*if (applyfrom.getMp() < getMpCon()) {
|
||||
AutobanFactory.MPCON.addPoint(applyfrom.getAutobanManager(), "mpCon hack for skill:" + sourceid + "; Player MP: " + applyto.getMp() + " MP Needed: " + getMpCon());
|
||||
} */
|
||||
|
||||
|
||||
if (!applyto.applyHpMpChange(hpCon, hpchange, mpchange)) {
|
||||
applyto.announce(MaplePacketCreator.enableActions());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (moveTo != -1) {
|
||||
if (moveTo != applyto.getMapId()) {
|
||||
MapleMap target;
|
||||
MaplePortal pt;
|
||||
|
||||
|
||||
if (moveTo == 999999999) {
|
||||
if(sourceid != 2030100) {
|
||||
if (sourceid != 2030100) {
|
||||
target = applyto.getMap().getReturnMap();
|
||||
pt = target.getRandomPlayerSpawnpoint();
|
||||
} else {
|
||||
if(!applyto.canRecoverLastBanish()) return false;
|
||||
|
||||
if (!applyto.canRecoverLastBanish()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Pair<Integer, Integer> lastBanishInfo = applyto.getLastBanishData();
|
||||
target = applyto.getWarpMap(lastBanishInfo.getLeft());
|
||||
pt = target.getPortal(lastBanishInfo.getRight());
|
||||
@@ -810,12 +836,12 @@ public class MapleStatEffect {
|
||||
target = applyto.getClient().getWorldServer().getChannel(applyto.getClient().getChannel()).getMapFactory().getMap(moveTo);
|
||||
int targetid = target.getId() / 10000000;
|
||||
if (targetid != 60 && applyto.getMapId() / 10000000 != 61 && targetid != applyto.getMapId() / 10000000 && targetid != 21 && targetid != 20 && targetid != 12 && (applyto.getMapId() / 10000000 != 10 && applyto.getMapId() / 10000000 != 12)) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
pt = target.getRandomPlayerSpawnpoint();
|
||||
}
|
||||
|
||||
|
||||
applyto.changeMap(target, pt);
|
||||
} else {
|
||||
return false;
|
||||
@@ -842,15 +868,15 @@ public class MapleStatEffect {
|
||||
SummonMovementType summonMovementType = getSummonMovementType();
|
||||
if (overTime || isCygnusFA() || summonMovementType != null) {
|
||||
if (summonMovementType != null && pos != null) {
|
||||
if(summonMovementType.getValue() == summonMovementType.STATIONARY.getValue()) {
|
||||
if (summonMovementType.getValue() == summonMovementType.STATIONARY.getValue()) {
|
||||
applyto.cancelBuffStats(MapleBuffStat.PUPPET);
|
||||
} else {
|
||||
applyto.cancelBuffStats(MapleBuffStat.SUMMON);
|
||||
}
|
||||
|
||||
|
||||
applyto.announce(MaplePacketCreator.enableActions());
|
||||
}
|
||||
|
||||
|
||||
applyBuffEffect(applyfrom, applyto, primary);
|
||||
}
|
||||
|
||||
@@ -863,7 +889,7 @@ public class MapleStatEffect {
|
||||
applyMonsterBuff(applyfrom);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (this.getFatigue() != 0) {
|
||||
applyto.getMount().setTiredness(applyto.getMount().getTiredness() + this.getFatigue());
|
||||
}
|
||||
@@ -880,25 +906,29 @@ public class MapleStatEffect {
|
||||
if (isMagicDoor() && !FieldLimit.DOOR.check(applyto.getMap().getFieldLimit())) { // Magic Door
|
||||
int y = applyto.getFh();
|
||||
if (y == 0) {
|
||||
y = applyto.getPosition().y;
|
||||
y = applyto.getPosition().y;
|
||||
}
|
||||
Point doorPosition = new Point(applyto.getPosition().x, y);
|
||||
MapleDoor door = new MapleDoor(applyto, doorPosition);
|
||||
|
||||
if(door.getOwnerId() >= 0) {
|
||||
|
||||
if (door.getOwnerId() >= 0) {
|
||||
applyto.applyPartyDoor(door, false);
|
||||
|
||||
door.getTarget().spawnDoor(door.getAreaDoor());
|
||||
door.getTown().spawnDoor(door.getTownDoor());
|
||||
|
||||
|
||||
applyto.disableDoorSpawn();
|
||||
} else {
|
||||
MapleInventoryManipulator.addFromDrop(applyto.getClient(), new Item(4006000, (short) 0, (short) 1), false);
|
||||
|
||||
if(door.getOwnerId() == -3) applyto.dropMessage(5, "Mystic Door cannot be cast far from a spawn point. Nearest one is at " + door.getDoorStatus().getRight() + "pts " + door.getDoorStatus().getLeft());
|
||||
else if(door.getOwnerId() == -2) applyto.dropMessage(5, "Mystic Door cannot be cast on a slope, try elsewhere.");
|
||||
else applyto.dropMessage(5, "There are no door portals available for the town at this moment. Try again later.");
|
||||
|
||||
|
||||
if (door.getOwnerId() == -3) {
|
||||
applyto.dropMessage(5, "Mystic Door cannot be cast far from a spawn point. Nearest one is at " + door.getDoorStatus().getRight() + "pts " + door.getDoorStatus().getLeft());
|
||||
} else if (door.getOwnerId() == -2) {
|
||||
applyto.dropMessage(5, "Mystic Door cannot be cast on a slope, try elsewhere.");
|
||||
} else {
|
||||
applyto.dropMessage(5, "There are no door portals available for the town at this moment. Try again later.");
|
||||
}
|
||||
|
||||
applyto.cancelBuffStats(MapleBuffStat.SOULARROW); // cancel door buff
|
||||
}
|
||||
} else if (isMist()) {
|
||||
@@ -907,14 +937,51 @@ public class MapleStatEffect {
|
||||
applyfrom.getMap().spawnMist(mist, getDuration(), mist.isPoisonMist(), false, mist.isRecoveryMist());
|
||||
} else if (isTimeLeap()) {
|
||||
applyto.removeAllCooldownsExcept(Buccaneer.TIME_LEAP, true);
|
||||
} else if (cp != 0 && applyto.getMonsterCarnival() != null) {
|
||||
applyto.gainCP(cp);
|
||||
} else if (nuffSkill != 0 && applyto.getParty() != null && applyto.getMap().isCPQMap()) { // by Drago-Dragohe4rt
|
||||
final MCSkill skil = MapleCarnivalFactory.getInstance().getSkill(nuffSkill);
|
||||
if (skil != null) {
|
||||
final MapleDisease dis = skil.getDisease();
|
||||
MapleParty inimigos = applyfrom.getParty().getEnemy();
|
||||
if (nuffSkill == 8) {
|
||||
int amount = inimigos.getMembers().size() - 1;
|
||||
int randd = (int) Math.floor(Math.random() * amount);
|
||||
MapleCharacter chrApp = applyfrom.getClient().getChannelServer().getPlayerStorage().getCharacterById(inimigos.getMemberByPos(randd).getId());
|
||||
if (chrApp != null && chrApp.getMap().isCPQMap()) {
|
||||
chrApp.dispel();
|
||||
}
|
||||
} else {
|
||||
for (MaplePartyCharacter chrsInimigos : inimigos.getPartyMembers()) {
|
||||
MapleCharacter chrApp = chrsInimigos.getPlayer();
|
||||
if (chrApp != null && chrApp.getMap().isCPQMap()) {
|
||||
if (dis == null) {
|
||||
chrApp.dispel();
|
||||
} else if (skil.getSkill() != null) {
|
||||
chrApp.giveDebuff(dis, skil.getSkill());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (cureDebuffs.size() > 0) { // by Drago-Dragohe4rt
|
||||
for (final MapleDisease debuff : cureDebuffs) {
|
||||
if (applyfrom.getParty() != null) {
|
||||
for (MaplePartyCharacter chrs : applyfrom.getParty().getPartyMembers()) {
|
||||
chrs.getPlayer().dispelDebuff(debuff);
|
||||
}
|
||||
} else {
|
||||
applyfrom.dispelDebuff(debuff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private int applyBuff(MapleCharacter applyfrom, boolean useMaxRange) {
|
||||
int affectedc = 1;
|
||||
|
||||
|
||||
if (isPartyBuff() && (applyfrom.getParty() != null || isGmBuff())) {
|
||||
Rectangle bounds = (!useMaxRange) ? calculateBoundingBox(applyfrom.getPosition(), applyfrom.isFacingLeft()) : new Rectangle(Integer.MIN_VALUE / 2, Integer.MIN_VALUE / 2, Integer.MAX_VALUE, Integer.MAX_VALUE);
|
||||
List<MapleMapObject> affecteds = applyfrom.getMap().getMapObjectsInRect(bounds, Arrays.asList(MapleMapObjectType.PLAYER));
|
||||
@@ -933,7 +1000,7 @@ public class MapleStatEffect {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
affectedc += affectedp.size(); // used for heal
|
||||
for (MapleCharacter affected : affectedp) {
|
||||
applyTo(applyfrom, affected, false, null, useMaxRange, affectedc);
|
||||
@@ -941,7 +1008,7 @@ public class MapleStatEffect {
|
||||
affected.getMap().broadcastMessage(affected, MaplePacketCreator.showBuffeffect(affected.getId(), sourceid, 2), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return affectedc;
|
||||
}
|
||||
|
||||
@@ -952,15 +1019,15 @@ public class MapleStatEffect {
|
||||
int i = 0;
|
||||
for (MapleMapObject mo : affected) {
|
||||
MapleMonster monster = (MapleMonster) mo;
|
||||
if (isDispel()) {
|
||||
monster.debuffMob(skill_.getId());
|
||||
if (isDispel()) {
|
||||
monster.debuffMob(skill_.getId());
|
||||
} else {
|
||||
if (makeChanceResult()) {
|
||||
monster.applyStatus(applyfrom, new MonsterStatusEffect(getMonsterStati(), skill_, null, false), isPoison(), getDuration());
|
||||
if (isCrash()) {
|
||||
monster.debuffMob(skill_.getId());
|
||||
}
|
||||
if (makeChanceResult()) {
|
||||
monster.applyStatus(applyfrom, new MonsterStatusEffect(getMonsterStati(), skill_, null, false), isPoison(), getDuration());
|
||||
if (isCrash()) {
|
||||
monster.debuffMob(skill_.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
i++;
|
||||
if (i >= mobCount) {
|
||||
@@ -982,17 +1049,17 @@ public class MapleStatEffect {
|
||||
Rectangle bounds = new Rectangle(mylt.x, mylt.y, myrb.x - mylt.x, myrb.y - mylt.y);
|
||||
return bounds;
|
||||
}
|
||||
|
||||
|
||||
public int getBuffLocalDuration() {
|
||||
return !ServerConstants.USE_BUFF_EVERLASTING ? duration : Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
|
||||
public void silentApplyBuff(MapleCharacter chr, long localStartTime) {
|
||||
int localDuration = getBuffLocalDuration();
|
||||
localDuration = alchemistModifyVal(chr, localDuration, false);
|
||||
//CancelEffectAction cancelAction = new CancelEffectAction(chr, this, starttime);
|
||||
//ScheduledFuture<?> schedule = TimerManager.getInstance().schedule(cancelAction, ((starttime + localDuration) - Server.getInstance().getCurrentTime()));
|
||||
|
||||
|
||||
chr.registerEffect(this, localStartTime, localStartTime + localDuration, true);
|
||||
SummonMovementType summonMovementType = getSummonMovementType();
|
||||
if (summonMovementType != null) {
|
||||
@@ -1016,7 +1083,7 @@ public class MapleStatEffect {
|
||||
// final ScheduledFuture<?> schedule = TimerManager.getInstance().schedule(cancelAction, ((starttime + 99999) - Server.getInstance().getCurrentTime()));
|
||||
applyto.registerEffect(this, starttime, Long.MAX_VALUE, false);
|
||||
}
|
||||
|
||||
|
||||
public final void applyBeaconBuff(final MapleCharacter applyto, int objectid) { // thanks Thora & Hyun for reporting an issue with homing beacon autoflagging mobs when changing maps
|
||||
final List<Pair<MapleBuffStat, Integer>> stat = Collections.singletonList(new Pair<>(MapleBuffStat.HOMING_BEACON, objectid));
|
||||
applyto.announce(MaplePacketCreator.giveBuff(1, sourceid, stat));
|
||||
@@ -1024,14 +1091,14 @@ public class MapleStatEffect {
|
||||
final long starttime = Server.getInstance().getCurrentTime();
|
||||
applyto.registerEffect(this, starttime, Long.MAX_VALUE, false);
|
||||
}
|
||||
|
||||
|
||||
public void updateBuffEffect(MapleCharacter target, List<Pair<MapleBuffStat, Integer>> activeStats, long starttime) {
|
||||
int localDuration = getBuffLocalDuration();
|
||||
localDuration = alchemistModifyVal(target, localDuration, false);
|
||||
|
||||
|
||||
long leftDuration = (starttime + localDuration) - Server.getInstance().getCurrentTime();
|
||||
if(leftDuration > 0) {
|
||||
target.announce(MaplePacketCreator.giveBuff((skill ? sourceid : -sourceid), (int)leftDuration, activeStats));
|
||||
if (leftDuration > 0) {
|
||||
target.announce(MaplePacketCreator.giveBuff((skill ? sourceid : -sourceid), (int) leftDuration, activeStats));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1067,7 +1134,7 @@ public class MapleStatEffect {
|
||||
if (applyto.getMount() == null) {
|
||||
applyto.mount(ridingMountId, sourceid);
|
||||
}
|
||||
|
||||
|
||||
applyto.getClient().getWorldServer().registerMountHunger(applyto);
|
||||
}
|
||||
if (sourceid == Corsair.BATTLE_SHIP) {
|
||||
@@ -1089,8 +1156,8 @@ public class MapleStatEffect {
|
||||
localsourceid = ridingMountId;
|
||||
localstatups = Collections.singletonList(new Pair<>(MapleBuffStat.MONSTER_RIDING, 0));
|
||||
} else if (isSkillMorph()) {
|
||||
for(int i = 0; i < localstatups.size(); i++) {
|
||||
if(localstatups.get(i).getLeft().equals(MapleBuffStat.MORPH)) {
|
||||
for (int i = 0; i < localstatups.size(); i++) {
|
||||
if (localstatups.get(i).getLeft().equals(MapleBuffStat.MORPH)) {
|
||||
localstatups.set(i, new Pair<>(MapleBuffStat.MORPH, getMorph(applyto)));
|
||||
break;
|
||||
}
|
||||
@@ -1110,7 +1177,7 @@ public class MapleStatEffect {
|
||||
buff = MaplePacketCreator.givePirateBuff(statups, sourceid, seconds);
|
||||
mbuff = MaplePacketCreator.giveForeignPirateBuff(applyto.getId(), sourceid, seconds, localstatups);
|
||||
} else if (isInfusion()) {
|
||||
buff = MaplePacketCreator.givePirateBuff(localstatups, sourceid, seconds);
|
||||
buff = MaplePacketCreator.givePirateBuff(localstatups, sourceid, seconds);
|
||||
mbuff = MaplePacketCreator.giveForeignPirateBuff(applyto.getId(), sourceid, seconds, localstatups);
|
||||
} else if (isDs()) {
|
||||
List<Pair<MapleBuffStat, Integer>> dsstat = Collections.singletonList(new Pair<>(MapleBuffStat.DARKSIGHT, 0));
|
||||
@@ -1125,10 +1192,10 @@ public class MapleStatEffect {
|
||||
if (applyto.getBattleshipHp() <= 0) {
|
||||
applyto.resetBattleshipHp();
|
||||
}
|
||||
|
||||
|
||||
localstatups = statups;
|
||||
}
|
||||
|
||||
|
||||
buff = MaplePacketCreator.giveBuff(localsourceid, localDuration, localstatups);
|
||||
mbuff = MaplePacketCreator.showMonsterRiding(applyto.getId(), givemount);
|
||||
localDuration = duration;
|
||||
@@ -1144,15 +1211,15 @@ public class MapleStatEffect {
|
||||
List<Pair<MapleBuffStat, Integer>> stat = Collections.singletonList(new Pair<>(MapleBuffStat.MORPH, Integer.valueOf(getMorph(applyto))));
|
||||
mbuff = MaplePacketCreator.giveForeignBuff(applyto.getId(), stat);
|
||||
}
|
||||
|
||||
|
||||
if (buff != null) {
|
||||
if (!hasNoIcon()) { //Thanks flav for such a simple release! :)
|
||||
if (!hasNoIcon()) { //Thanks flav for such a simple release! :)
|
||||
applyto.announce(buff);
|
||||
} else {
|
||||
} else {
|
||||
System.out.println("<Error> NO buff icon for id " + sourceid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
long starttime = Server.getInstance().getCurrentTime();
|
||||
//CancelEffectAction cancelAction = new CancelEffectAction(applyto, this, starttime);
|
||||
//ScheduledFuture<?> schedule = TimerManager.getInstance().schedule(cancelAction, localDuration);
|
||||
@@ -1273,7 +1340,7 @@ public class MapleStatEffect {
|
||||
case Beginner.ECHO_OF_HERO:
|
||||
case Noblesse.ECHO_OF_HERO:
|
||||
case Legend.ECHO_OF_HERO:
|
||||
case Evan.ECHO_OF_HERO:
|
||||
case Evan.ECHO_OF_HERO:
|
||||
case SuperGM.HEAL_PLUS_DISPEL:
|
||||
case SuperGM.HASTE:
|
||||
case SuperGM.HOLY_SYMBOL:
|
||||
@@ -1346,45 +1413,44 @@ public class MapleStatEffect {
|
||||
public boolean isRecovery() {
|
||||
return sourceid == Beginner.RECOVERY || sourceid == Noblesse.RECOVERY || sourceid == Legend.RECOVERY || sourceid == Evan.RECOVERY;
|
||||
}
|
||||
|
||||
|
||||
public boolean isMapChair() {
|
||||
return sourceid == Beginner.MAP_CHAIR || sourceid == Noblesse.MAP_CHAIR || sourceid == Legend.MAP_CHAIR;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isMapChair(int sourceid) {
|
||||
return sourceid == Beginner.MAP_CHAIR || sourceid == Noblesse.MAP_CHAIR || sourceid == Legend.MAP_CHAIR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean isDojoBuff() {
|
||||
return sourceid >= 2022359 && sourceid <= 2022421;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isDojoBuff(int sourceid) {
|
||||
return sourceid >= 2022359 && sourceid <= 2022421;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isHpMpRecovery(int sourceid) {
|
||||
return sourceid == 2022198 || sourceid == 2022337;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isPyramidBuff(int sourceid) {
|
||||
return sourceid >= 2022585 && sourceid <= 2022617;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isRateCoupon(int sourceid) {
|
||||
int itemType = sourceid / 1000;
|
||||
return itemType == 5211 || itemType == 5360;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isExpIncrease(int sourceid) {
|
||||
return sourceid >= 2022450 && sourceid <= 2022452;
|
||||
}
|
||||
|
||||
|
||||
private boolean isDs() {
|
||||
return skill && (sourceid == Rogue.DARK_SIGHT || sourceid == NightWalker.DARK_SIGHT);
|
||||
}
|
||||
|
||||
|
||||
private boolean isWw() {
|
||||
return skill && (sourceid == WindArcher.WIND_WALK);
|
||||
}
|
||||
@@ -1412,11 +1478,11 @@ public class MapleStatEffect {
|
||||
private boolean isCouponBuff() {
|
||||
return isRateCoupon(sourceid);
|
||||
}
|
||||
|
||||
|
||||
private boolean isMysticDoor() {
|
||||
return skill && sourceid == Priest.MYSTIC_DOOR;
|
||||
}
|
||||
|
||||
|
||||
public boolean isMonsterRiding() {
|
||||
return skill && (sourceid % 10000000 == 1004 || sourceid == Corsair.BATTLE_SHIP || sourceid == Beginner.SPACESHIP || sourceid == Noblesse.SPACESHIP
|
||||
|| sourceid == Beginner.YETI_MOUNT1 || sourceid == Beginner.YETI_MOUNT2 || sourceid == Beginner.WITCH_BROOMSTICK || sourceid == Beginner.BALROG_MOUNT
|
||||
@@ -1431,11 +1497,11 @@ public class MapleStatEffect {
|
||||
public boolean isPoison() {
|
||||
return skill && (sourceid == FPMage.POISON_MIST || sourceid == FPWizard.POISON_BREATH || sourceid == FPMage.ELEMENT_COMPOSITION || sourceid == NightWalker.POISON_BOMB || sourceid == BlazeWizard.FLAME_GEAR);
|
||||
}
|
||||
|
||||
|
||||
public boolean isMorph() {
|
||||
return morphId > 0;
|
||||
}
|
||||
|
||||
|
||||
public boolean isMorphWithoutAttack() {
|
||||
return morphId > 0 && morphId < 100; // Every morph item I have found has been under 100, pirate skill transforms start at 1000.
|
||||
}
|
||||
@@ -1453,9 +1519,9 @@ public class MapleStatEffect {
|
||||
}
|
||||
|
||||
private boolean isCrash() {
|
||||
return skill && (sourceid == DragonKnight.POWER_CRASH || sourceid == Crusader.ARMOR_CRASH || sourceid == WhiteKnight.MAGIC_CRASH);
|
||||
return skill && (sourceid == DragonKnight.POWER_CRASH || sourceid == Crusader.ARMOR_CRASH || sourceid == WhiteKnight.MAGIC_CRASH);
|
||||
}
|
||||
|
||||
|
||||
private boolean isDispel() {
|
||||
return skill && (sourceid == Priest.DISPEL || sourceid == SuperGM.HEAL_PLUS_DISPEL);
|
||||
}
|
||||
@@ -1463,13 +1529,15 @@ public class MapleStatEffect {
|
||||
private boolean isCureAllAbnormalStatus() {
|
||||
if (skill) {
|
||||
return isHerosWill(sourceid);
|
||||
} else if (sourceid == 2022544) return true;
|
||||
|
||||
} else if (sourceid == 2022544) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isHerosWill(int skillid) {
|
||||
switch(skillid) {
|
||||
switch (skillid) {
|
||||
case Hero.HEROS_WILL:
|
||||
case Paladin.HEROS_WILL:
|
||||
case DarkKnight.HEROS_WILL:
|
||||
@@ -1504,7 +1572,7 @@ public class MapleStatEffect {
|
||||
private boolean isCygnusFA() {
|
||||
return skill && (sourceid == DawnWarrior.FINAL_ATTACK || sourceid == WindArcher.FINAL_ATTACK);
|
||||
}
|
||||
|
||||
|
||||
private boolean isHyperBody() {
|
||||
return skill && (sourceid == Spearman.HYPER_BODY || sourceid == GM.HYPER_BODY || sourceid == SuperGM.HYPER_BODY);
|
||||
}
|
||||
@@ -1561,17 +1629,16 @@ public class MapleStatEffect {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public boolean hasNoIcon() {
|
||||
return (sourceid == 3111002 || sourceid == 3211002 || + // puppet, puppet
|
||||
sourceid == 3211005 || + // golden eagle
|
||||
sourceid == 3211005 || + // golden eagle
|
||||
sourceid == 2121005 || sourceid == 2221005 || + // elquines, ifrit
|
||||
sourceid == 2321003 || sourceid == 3121006 || + // bahamut, phoenix
|
||||
sourceid == 3221005 || sourceid == 3111005 || + // frostprey, silver hawk
|
||||
sourceid == 2311006 || sourceid == 5220002 || + // summon dragon, wrath of the octopi
|
||||
sourceid == 5211001 || sourceid == 5211002); // octopus, gaviota
|
||||
}
|
||||
|
||||
|
||||
public boolean isSkill() {
|
||||
return skill;
|
||||
}
|
||||
@@ -1579,7 +1646,7 @@ public class MapleStatEffect {
|
||||
public int getSourceId() {
|
||||
return sourceid;
|
||||
}
|
||||
|
||||
|
||||
public int getBuffSourceId() {
|
||||
return skill ? sourceid : -sourceid;
|
||||
}
|
||||
@@ -1589,28 +1656,27 @@ public class MapleStatEffect {
|
||||
}
|
||||
|
||||
/*
|
||||
private static class CancelEffectAction implements Runnable {
|
||||
private static class CancelEffectAction implements Runnable {
|
||||
|
||||
private MapleStatEffect effect;
|
||||
private WeakReference<MapleCharacter> target;
|
||||
private long startTime;
|
||||
private MapleStatEffect effect;
|
||||
private WeakReference<MapleCharacter> target;
|
||||
private long startTime;
|
||||
|
||||
public CancelEffectAction(MapleCharacter target, MapleStatEffect effect, long startTime) {
|
||||
this.effect = effect;
|
||||
this.target = new WeakReference<>(target);
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
MapleCharacter realTarget = target.get();
|
||||
if (realTarget != null) {
|
||||
realTarget.cancelEffect(effect, false, startTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
public CancelEffectAction(MapleCharacter target, MapleStatEffect effect, long startTime) {
|
||||
this.effect = effect;
|
||||
this.target = new WeakReference<>(target);
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
MapleCharacter realTarget = target.get();
|
||||
if (realTarget != null) {
|
||||
realTarget.cancelEffect(effect, false, startTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
public short getHp() {
|
||||
return hp;
|
||||
}
|
||||
@@ -1618,7 +1684,7 @@ public class MapleStatEffect {
|
||||
public short getMp() {
|
||||
return mp;
|
||||
}
|
||||
|
||||
|
||||
public double getHpRate() {
|
||||
return hpR;
|
||||
}
|
||||
@@ -1626,7 +1692,7 @@ public class MapleStatEffect {
|
||||
public double getMpRate() {
|
||||
return mpR;
|
||||
}
|
||||
|
||||
|
||||
public byte getHpR() {
|
||||
return mhpR;
|
||||
}
|
||||
@@ -1634,7 +1700,7 @@ public class MapleStatEffect {
|
||||
public byte getMpR() {
|
||||
return mmpR;
|
||||
}
|
||||
|
||||
|
||||
public short getHpRRate() {
|
||||
return mhpRRate;
|
||||
}
|
||||
@@ -1654,7 +1720,7 @@ public class MapleStatEffect {
|
||||
public short getMatk() {
|
||||
return matk;
|
||||
}
|
||||
|
||||
|
||||
public short getWatk() {
|
||||
return watk;
|
||||
}
|
||||
@@ -1714,4 +1780,4 @@ public class MapleStatEffect {
|
||||
public Map<MonsterStatus, Integer> getMonsterStati() {
|
||||
return monsterStatus;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,6 +75,7 @@ import server.MapleStatEffect;
|
||||
import server.maps.MapleSummon;
|
||||
|
||||
public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
|
||||
private ChangeableStats ostats = null; //unused, v83 WZs offers no support for changeable stats.
|
||||
private MapleMonsterStats stats;
|
||||
private AtomicInteger hp = new AtomicInteger(1);
|
||||
@@ -216,7 +217,9 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
}
|
||||
|
||||
public synchronized void addHp(int hp) {
|
||||
if(this.hp.get() <= 0) return;
|
||||
if (this.hp.get() <= 0) {
|
||||
return;
|
||||
}
|
||||
this.hp.addAndGet(hp);
|
||||
}
|
||||
|
||||
@@ -300,7 +303,9 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
}
|
||||
|
||||
private boolean applyAnimationIfRoaming(int attackPos, MobSkill skill) { // roam: not casting attack or skill animations
|
||||
if(!animationLock.tryLock()) return false;
|
||||
if (!animationLock.tryLock()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
long animationTime;
|
||||
@@ -328,7 +333,9 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
}
|
||||
|
||||
if(delta >= 0) {
|
||||
if(stayAlive) curHp--;
|
||||
if (stayAlive) {
|
||||
curHp--;
|
||||
}
|
||||
int trueDamage = Math.min(curHp, delta);
|
||||
|
||||
hp.addAndGet(-trueDamage);
|
||||
@@ -428,7 +435,9 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
return;
|
||||
}
|
||||
|
||||
if(ServerConstants.USE_DEBUG) from.dropMessage(5, "Hitted MOB " + this.getId() + ", OID " + this.getObjectId());
|
||||
if (ServerConstants.USE_DEBUG) {
|
||||
from.dropMessage(5, "Hitted MOB " + this.getId() + ", OID " + this.getObjectId());
|
||||
}
|
||||
dispatchMonsterDamaged(from, trueDamage);
|
||||
|
||||
if (!takenDamage.containsKey(from.getId())) {
|
||||
@@ -442,7 +451,9 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
|
||||
public void heal(int hp, int mp) {
|
||||
Integer hpHealed = applyAndGetHpDamage(-hp, false);
|
||||
if(hpHealed == null) return;
|
||||
if (hpHealed == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int mp2Heal = getMp() + mp;
|
||||
int maxMp = getMaxMp();
|
||||
@@ -451,7 +462,9 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
}
|
||||
setMp(mp2Heal);
|
||||
|
||||
if(hp > 0) getMap().broadcastMessage(MaplePacketCreator.healMonster(getObjectId(), hp, getHp(), getMaxHp()));
|
||||
if (hp > 0) {
|
||||
getMap().broadcastMessage(MaplePacketCreator.healMonster(getObjectId(), hp, getHp(), getMaxHp()));
|
||||
}
|
||||
|
||||
maxHpPlusHeal.addAndGet(hpHealed);
|
||||
dispatchMonsterHealed(hpHealed);
|
||||
@@ -465,7 +478,7 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
MapleCharacter pchar = getMap().getAnyCharacterFromParty(pid); // thanks G h o s t, Alfred, Vcoc, BHB for poiting out a bug in detecting party members after membership transactions in a party took place
|
||||
|
||||
List<MapleCharacter> members;
|
||||
if(pchar != null) {
|
||||
if (pchar != null) {
|
||||
members = pchar.getPartyMembersOnSameMap();
|
||||
} else {
|
||||
members = new LinkedList<>();
|
||||
@@ -902,7 +915,9 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
}
|
||||
|
||||
private void setControllerHasAggro(boolean controllerHasAggro) {
|
||||
if (!fake) this.controllerHasAggro = controllerHasAggro;
|
||||
if (!fake) {
|
||||
this.controllerHasAggro = controllerHasAggro;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isControllerKnowsAboutAggro() {
|
||||
@@ -910,7 +925,9 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
}
|
||||
|
||||
private void setControllerKnowsAboutAggro(boolean controllerKnowsAboutAggro) {
|
||||
if (!fake) this.controllerKnowsAboutAggro = controllerKnowsAboutAggro;
|
||||
if (!fake) {
|
||||
this.controllerKnowsAboutAggro = controllerKnowsAboutAggro;
|
||||
}
|
||||
}
|
||||
|
||||
private void setControllerHasPuppet(boolean controllerHasPuppet) {
|
||||
@@ -1181,7 +1198,20 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
ch.registerMobStatus(mapid, status, cancelTask, duration + animationTime - 100, overtimeAction, overtimeDelay);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public final void dispelSkill(final MobSkill skillId) {
|
||||
List<MonsterStatus> toCancel = new ArrayList<MonsterStatus>();
|
||||
for (Entry<MonsterStatus, MonsterStatusEffect> effects : stati.entrySet()) {
|
||||
MonsterStatusEffect mse = effects.getValue();
|
||||
if (mse.getMobSkill() != null && mse.getMobSkill().getSkillId() == skillId.getSkillId()) { //not checking for level.
|
||||
toCancel.add(effects.getKey());
|
||||
}
|
||||
}
|
||||
for (MonsterStatus stat : toCancel) {
|
||||
debuffMobStat(stat);
|
||||
}
|
||||
}
|
||||
|
||||
public void applyMonsterBuff(final Map<MonsterStatus, Integer> stats, final int x, int skillId, long duration, MobSkill skill, final List<Integer> reflection) {
|
||||
final Runnable cancelTask = new Runnable() {
|
||||
|
||||
@@ -1265,12 +1295,20 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
|
||||
if(ServerConstants.USE_ANTI_IMMUNITY_CRASH) {
|
||||
if (skillid == Crusader.ARMOR_CRASH) {
|
||||
if(!isBuffed(MonsterStatus.WEAPON_REFLECT)) debuffMobStat(MonsterStatus.WEAPON_IMMUNITY);
|
||||
if(!isBuffed(MonsterStatus.MAGIC_REFLECT)) debuffMobStat(MonsterStatus.MAGIC_IMMUNITY);
|
||||
if(!isBuffed(MonsterStatus.WEAPON_REFLECT)) {
|
||||
debuffMobStat(MonsterStatus.WEAPON_IMMUNITY);
|
||||
}
|
||||
if(!isBuffed(MonsterStatus.MAGIC_REFLECT)) {
|
||||
debuffMobStat(MonsterStatus.MAGIC_IMMUNITY);
|
||||
}
|
||||
} else if (skillid == WhiteKnight.MAGIC_CRASH) {
|
||||
if(!isBuffed(MonsterStatus.MAGIC_REFLECT)) debuffMobStat(MonsterStatus.MAGIC_IMMUNITY);
|
||||
if(!isBuffed(MonsterStatus.MAGIC_REFLECT)) {
|
||||
debuffMobStat(MonsterStatus.MAGIC_IMMUNITY);
|
||||
}
|
||||
} else {
|
||||
if(!isBuffed(MonsterStatus.WEAPON_REFLECT)) debuffMobStat(MonsterStatus.WEAPON_IMMUNITY);
|
||||
if(!isBuffed(MonsterStatus.WEAPON_REFLECT)) {
|
||||
debuffMobStat(MonsterStatus.WEAPON_IMMUNITY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1669,11 +1707,16 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
|
||||
private float getDifficultyRate(final int difficulty) {
|
||||
switch(difficulty) {
|
||||
case 6: return(7.7f);
|
||||
case 5: return(5.6f);
|
||||
case 4: return(3.2f);
|
||||
case 3: return(2.1f);
|
||||
case 2: return(1.4f);
|
||||
case 6:
|
||||
return(7.7f);
|
||||
case 5:
|
||||
return(5.6f);
|
||||
case 4:
|
||||
return(3.2f);
|
||||
case 3:
|
||||
return(2.1f);
|
||||
case 2:
|
||||
return(1.4f);
|
||||
}
|
||||
|
||||
return(1.0f);
|
||||
@@ -1862,8 +1905,8 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a new controller for the given monster from the chars with deployed puppet
|
||||
* nearby on the map it is from...
|
||||
* Finds a new controller for the given monster from the chars with deployed
|
||||
* puppet nearby on the map it is from...
|
||||
*
|
||||
*/
|
||||
private void aggroUpdatePuppetController(MapleCharacter newController) {
|
||||
@@ -1960,8 +2003,8 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
}
|
||||
|
||||
/**
|
||||
* Applied damage input for this mob, enough damage taken implies
|
||||
* an aggro target update for the attacker shortly.
|
||||
* Applied damage input for this mob, enough damage taken implies an aggro
|
||||
* target update for the attacker shortly.
|
||||
*
|
||||
*/
|
||||
public void aggroMonsterDamage(MapleCharacter attacker, int damage) {
|
||||
@@ -2014,7 +2057,9 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
}
|
||||
|
||||
public void aggroUpdatePuppetVisibility() {
|
||||
if (!availablePuppetUpdate) return;
|
||||
if (!availablePuppetUpdate) {
|
||||
return;
|
||||
}
|
||||
|
||||
availablePuppetUpdate = false;
|
||||
Runnable r = new Runnable() {
|
||||
@@ -2022,7 +2067,9 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
public void run() {
|
||||
try {
|
||||
MapleCharacter chrController = MapleMonster.this.getActiveController();
|
||||
if (chrController == null) return;
|
||||
if (chrController == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
MapleStatEffect puppetEffect = chrController.getBuffEffect(MapleBuffStat.PUPPET);
|
||||
if (puppetEffect != null) {
|
||||
@@ -2052,7 +2099,8 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all applied damage input for this mob, doesn't refresh target aggro.
|
||||
* Clears all applied damage input for this mob, doesn't refresh target
|
||||
* aggro.
|
||||
*
|
||||
*/
|
||||
public void aggroClearDamages() {
|
||||
@@ -2073,6 +2121,10 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
}
|
||||
}
|
||||
|
||||
public final int getRemoveAfter() {
|
||||
return stats.removeAfter();
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
this.getMap().dismissRemoveAfter(this);
|
||||
disposeLocks();
|
||||
@@ -2093,4 +2145,4 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
statiLock = statiLock.dispose();
|
||||
animationLock = animationLock.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,306 +44,308 @@ import tools.Pair;
|
||||
import tools.Randomizer;
|
||||
|
||||
public class MapleMonsterInformationProvider {
|
||||
// Author : LightPepsi
|
||||
// Author : LightPepsi
|
||||
|
||||
private static final MapleMonsterInformationProvider instance = new MapleMonsterInformationProvider();
|
||||
|
||||
public static MapleMonsterInformationProvider getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
private final Map<Integer, List<MonsterDropEntry>> drops = new HashMap<>();
|
||||
private final List<MonsterGlobalDropEntry> globaldrops = new ArrayList<>();
|
||||
private final Map<Integer, List<MonsterGlobalDropEntry>> continentdrops = new HashMap<>();
|
||||
|
||||
private final Map<Integer, List<Integer>> dropsChancePool = new HashMap<>(); // thanks to ronan
|
||||
private final Set<Integer> hasNoMultiEquipDrops = new HashSet<>();
|
||||
private final Map<Integer, List<MonsterDropEntry>> extraMultiEquipDrops = new HashMap<>();
|
||||
|
||||
private final Map<Pair<Integer, Integer>, Integer> mobAttackAnimationTime = new HashMap<>();
|
||||
private final Map<MobSkill, Integer> mobSkillAnimationTime = new HashMap<>();
|
||||
|
||||
private final Map<Integer, Pair<Integer, Integer>> mobAttackInfo = new HashMap<>();
|
||||
|
||||
private final Map<Integer, Boolean> mobBossCache = new HashMap<>();
|
||||
private final Map<Integer, String> mobNameCache = new HashMap<>();
|
||||
private static final MapleMonsterInformationProvider instance = new MapleMonsterInformationProvider();
|
||||
|
||||
protected MapleMonsterInformationProvider() {
|
||||
retrieveGlobal();
|
||||
}
|
||||
|
||||
public final List<MonsterGlobalDropEntry> getRelevantGlobalDrops(int mapid) {
|
||||
int continentid = mapid / 100000000;
|
||||
|
||||
List<MonsterGlobalDropEntry> contiItems = continentdrops.get(continentid);
|
||||
if (contiItems == null) { // continent separated global drops found thanks to marcuswoon
|
||||
contiItems = new ArrayList<>();
|
||||
|
||||
for (MonsterGlobalDropEntry e : globaldrops) {
|
||||
if (e.continentid < 0 || e.continentid == continentid) {
|
||||
contiItems.add(e);
|
||||
}
|
||||
public static MapleMonsterInformationProvider getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
private final Map<Integer, List<MonsterDropEntry>> drops = new HashMap<>();
|
||||
private final List<MonsterGlobalDropEntry> globaldrops = new ArrayList<>();
|
||||
private final Map<Integer, List<MonsterGlobalDropEntry>> continentdrops = new HashMap<>();
|
||||
|
||||
private final Map<Integer, List<Integer>> dropsChancePool = new HashMap<>(); // thanks to ronan
|
||||
private final Set<Integer> hasNoMultiEquipDrops = new HashSet<>();
|
||||
private final Map<Integer, List<MonsterDropEntry>> extraMultiEquipDrops = new HashMap<>();
|
||||
|
||||
private final Map<Pair<Integer, Integer>, Integer> mobAttackAnimationTime = new HashMap<>();
|
||||
private final Map<MobSkill, Integer> mobSkillAnimationTime = new HashMap<>();
|
||||
|
||||
private final Map<Integer, Pair<Integer, Integer>> mobAttackInfo = new HashMap<>();
|
||||
|
||||
private final Map<Integer, Boolean> mobBossCache = new HashMap<>();
|
||||
private final Map<Integer, String> mobNameCache = new HashMap<>();
|
||||
|
||||
protected MapleMonsterInformationProvider() {
|
||||
retrieveGlobal();
|
||||
}
|
||||
|
||||
public final List<MonsterGlobalDropEntry> getRelevantGlobalDrops(int mapid) {
|
||||
int continentid = mapid / 100000000;
|
||||
|
||||
List<MonsterGlobalDropEntry> contiItems = continentdrops.get(continentid);
|
||||
if (contiItems == null) { // continent separated global drops found thanks to marcuswoon
|
||||
contiItems = new ArrayList<>();
|
||||
|
||||
for (MonsterGlobalDropEntry e : globaldrops) {
|
||||
if (e.continentid < 0 || e.continentid == continentid) {
|
||||
contiItems.add(e);
|
||||
}
|
||||
}
|
||||
|
||||
continentdrops.put(continentid, contiItems);
|
||||
}
|
||||
|
||||
return contiItems;
|
||||
}
|
||||
|
||||
private void retrieveGlobal() {
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
Connection con = null;
|
||||
|
||||
try {
|
||||
con = DatabaseConnection.getConnection();
|
||||
ps = con.prepareStatement("SELECT * FROM drop_data_global WHERE chance > 0");
|
||||
rs = ps.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
globaldrops.add(
|
||||
new MonsterGlobalDropEntry(
|
||||
rs.getInt("itemid"),
|
||||
rs.getInt("chance"),
|
||||
rs.getByte("continent"),
|
||||
rs.getInt("minimum_quantity"),
|
||||
rs.getInt("maximum_quantity"),
|
||||
rs.getShort("questid")));
|
||||
}
|
||||
|
||||
rs.close();
|
||||
ps.close();
|
||||
con.close();
|
||||
} catch (SQLException e) {
|
||||
System.err.println("Error retrieving drop" + e);
|
||||
} finally {
|
||||
try {
|
||||
if (ps != null && !ps.isClosed()) {
|
||||
ps.close();
|
||||
}
|
||||
if (rs != null && !rs.isClosed()) {
|
||||
rs.close();
|
||||
}
|
||||
if (con != null && !con.isClosed()) {
|
||||
con.close();
|
||||
}
|
||||
} catch (SQLException ignore) {
|
||||
ignore.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<MonsterDropEntry> retrieveEffectiveDrop(final int monsterId) {
|
||||
// this reads the drop entries searching for multi-equip, properly processing them
|
||||
|
||||
List<MonsterDropEntry> list = retrieveDrop(monsterId);
|
||||
if (hasNoMultiEquipDrops.contains(monsterId) || !ServerConstants.USE_MULTIPLE_SAME_EQUIP_DROP) {
|
||||
return list;
|
||||
}
|
||||
|
||||
List<MonsterDropEntry> multiDrops = extraMultiEquipDrops.get(monsterId), extra = new LinkedList<>();
|
||||
if (multiDrops == null) {
|
||||
multiDrops = new LinkedList<>();
|
||||
|
||||
for (MonsterDropEntry mde : list) {
|
||||
if (ItemConstants.isEquipment(mde.itemId) && mde.Maximum > 1) {
|
||||
multiDrops.add(mde);
|
||||
|
||||
int rnd = Randomizer.rand(mde.Minimum, mde.Maximum);
|
||||
for (int i = 0; i < rnd - 1; i++) {
|
||||
extra.add(mde); // this passes copies of the equips' MDE with min/max quantity > 1, but idc it'll be unused anyways
|
||||
}
|
||||
|
||||
continentdrops.put(continentid, contiItems);
|
||||
}
|
||||
|
||||
return contiItems;
|
||||
}
|
||||
}
|
||||
|
||||
private void retrieveGlobal() {
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
Connection con = null;
|
||||
|
||||
try {
|
||||
con = DatabaseConnection.getConnection();
|
||||
ps = con.prepareStatement("SELECT * FROM drop_data_global WHERE chance > 0");
|
||||
rs = ps.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
globaldrops.add(
|
||||
new MonsterGlobalDropEntry(
|
||||
rs.getInt("itemid"),
|
||||
rs.getInt("chance"),
|
||||
rs.getByte("continent"),
|
||||
rs.getInt("minimum_quantity"),
|
||||
rs.getInt("maximum_quantity"),
|
||||
rs.getShort("questid")));
|
||||
}
|
||||
|
||||
rs.close();
|
||||
ps.close();
|
||||
con.close();
|
||||
} catch (SQLException e) {
|
||||
System.err.println("Error retrieving drop" + e);
|
||||
} finally {
|
||||
try {
|
||||
if (ps != null && !ps.isClosed()) {
|
||||
ps.close();
|
||||
}
|
||||
if (rs != null && !rs.isClosed()) {
|
||||
rs.close();
|
||||
}
|
||||
if (con != null && !con.isClosed()) {
|
||||
con.close();
|
||||
}
|
||||
} catch (SQLException ignore) {
|
||||
ignore.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<MonsterDropEntry> retrieveEffectiveDrop(final int monsterId) {
|
||||
// this reads the drop entries searching for multi-equip, properly processing them
|
||||
|
||||
List<MonsterDropEntry> list = retrieveDrop(monsterId);
|
||||
if (hasNoMultiEquipDrops.contains(monsterId) || !ServerConstants.USE_MULTIPLE_SAME_EQUIP_DROP) {
|
||||
return list;
|
||||
}
|
||||
|
||||
List<MonsterDropEntry> multiDrops = extraMultiEquipDrops.get(monsterId), extra = new LinkedList<>();
|
||||
if(multiDrops == null) {
|
||||
multiDrops = new LinkedList<>();
|
||||
|
||||
for(MonsterDropEntry mde : list) {
|
||||
if(ItemConstants.isEquipment(mde.itemId) && mde.Maximum > 1) {
|
||||
multiDrops.add(mde);
|
||||
|
||||
int rnd = Randomizer.rand(mde.Minimum, mde.Maximum);
|
||||
for(int i = 0; i < rnd - 1; i++) {
|
||||
extra.add(mde); // this passes copies of the equips' MDE with min/max quantity > 1, but idc it'll be unused anyways
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!multiDrops.isEmpty()) extraMultiEquipDrops.put(monsterId, multiDrops);
|
||||
else hasNoMultiEquipDrops.add(monsterId);
|
||||
} else {
|
||||
for(MonsterDropEntry mde : multiDrops) {
|
||||
int rnd = Randomizer.rand(mde.Minimum, mde.Maximum);
|
||||
for(int i = 0; i < rnd - 1; i++) {
|
||||
extra.add(mde);
|
||||
}
|
||||
}
|
||||
if (!multiDrops.isEmpty()) {
|
||||
extraMultiEquipDrops.put(monsterId, multiDrops);
|
||||
} else {
|
||||
hasNoMultiEquipDrops.add(monsterId);
|
||||
}
|
||||
} else {
|
||||
for (MonsterDropEntry mde : multiDrops) {
|
||||
int rnd = Randomizer.rand(mde.Minimum, mde.Maximum);
|
||||
for (int i = 0; i < rnd - 1; i++) {
|
||||
extra.add(mde);
|
||||
}
|
||||
|
||||
List<MonsterDropEntry> ret = new LinkedList<>(list);
|
||||
ret.addAll(extra);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
List<MonsterDropEntry> ret = new LinkedList<>(list);
|
||||
ret.addAll(extra);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public final List<MonsterDropEntry> retrieveDrop(final int monsterId) {
|
||||
if (drops.containsKey(monsterId)) {
|
||||
return drops.get(monsterId);
|
||||
}
|
||||
final List<MonsterDropEntry> ret = new LinkedList<>();
|
||||
|
||||
if (monsterId >= 9300127 && monsterId <= 9300136 || monsterId >= 9300315 && monsterId <= 9300324) {
|
||||
int dropArray[] = {2022157, 2022158, 2022159, 2022160, 2022161, 2022162, 2022163, 2022164, 2022165, 2022166, 2022167, 2022168, 2022169, 2022170, 2022171, 2022172, 2022173, 2022174, 2022175, 2022176, 2022177, 2022178, 4001129}; //These are the drops, -1 means meso :D
|
||||
for (int id : dropArray) {
|
||||
ret.add(new MonsterDropEntry(id, 2000, 1, 1, (short) 0));
|
||||
}
|
||||
} else {
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
Connection con = null;
|
||||
try {
|
||||
con = DatabaseConnection.getConnection();
|
||||
ps = con.prepareStatement("SELECT itemid, chance, minimum_quantity, maximum_quantity, questid FROM drop_data WHERE dropperid = ?");
|
||||
ps.setInt(1, monsterId);
|
||||
rs = ps.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
ret.add(new MonsterDropEntry(rs.getInt("itemid"), rs.getInt("chance"), rs.getInt("minimum_quantity"), rs.getInt("maximum_quantity"), rs.getShort("questid")));
|
||||
}
|
||||
|
||||
con.close();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
return ret;
|
||||
}
|
||||
|
||||
public final List<MonsterDropEntry> retrieveDrop(final int monsterId) {
|
||||
if (drops.containsKey(monsterId)) {
|
||||
return drops.get(monsterId);
|
||||
}
|
||||
final List<MonsterDropEntry> ret = new LinkedList<>();
|
||||
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
Connection con = null;
|
||||
try {
|
||||
con = DatabaseConnection.getConnection();
|
||||
ps = con.prepareStatement("SELECT itemid, chance, minimum_quantity, maximum_quantity, questid FROM drop_data WHERE dropperid = ?");
|
||||
ps.setInt(1, monsterId);
|
||||
rs = ps.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
ret.add(
|
||||
new MonsterDropEntry(
|
||||
rs.getInt("itemid"),
|
||||
rs.getInt("chance"),
|
||||
rs.getInt("minimum_quantity"),
|
||||
rs.getInt("maximum_quantity"),
|
||||
rs.getShort("questid")));
|
||||
}
|
||||
|
||||
} finally {
|
||||
try {
|
||||
if (ps != null && !ps.isClosed()) {
|
||||
ps.close();
|
||||
}
|
||||
if (rs != null && !rs.isClosed()) {
|
||||
rs.close();
|
||||
}
|
||||
if (con != null && !con.isClosed()) {
|
||||
con.close();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
return ret;
|
||||
} finally {
|
||||
try {
|
||||
if (ps != null && !ps.isClosed()) {
|
||||
ps.close();
|
||||
}
|
||||
if (rs != null && !rs.isClosed()) {
|
||||
rs.close();
|
||||
}
|
||||
if (con != null && !con.isClosed()) {
|
||||
con.close();
|
||||
}
|
||||
} catch (SQLException ignore) {
|
||||
ignore.printStackTrace();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
drops.put(monsterId, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public final List<Integer> retrieveDropPool(final int monsterId) { // ignores Quest and Party Quest items
|
||||
if (dropsChancePool.containsKey(monsterId)) {
|
||||
return dropsChancePool.get(monsterId);
|
||||
}
|
||||
|
||||
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
|
||||
|
||||
List<MonsterDropEntry> dropList = retrieveDrop(monsterId);
|
||||
List<Integer> ret = new ArrayList<>();
|
||||
|
||||
int accProp = 0;
|
||||
for(MonsterDropEntry mde : dropList) {
|
||||
if(!ii.isQuestItem(mde.itemId) && !ii.isPartyQuestItem(mde.itemId)) {
|
||||
accProp += mde.chance;
|
||||
}
|
||||
|
||||
ret.add(accProp);
|
||||
}
|
||||
} catch (SQLException ignore) {
|
||||
ignore.printStackTrace();
|
||||
return ret;
|
||||
}
|
||||
|
||||
if(accProp == 0) ret.clear(); // don't accept mobs dropping no relevant items
|
||||
|
||||
dropsChancePool.put(monsterId, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public final void setMobAttackAnimationTime(int monsterId, int attackPos, int animationTime) {
|
||||
mobAttackAnimationTime.put(new Pair<>(monsterId, attackPos), animationTime);
|
||||
}
|
||||
}
|
||||
|
||||
public final Integer getMobAttackAnimationTime(int monsterId, int attackPos) {
|
||||
Integer time = mobAttackAnimationTime.get(new Pair<>(monsterId, attackPos));
|
||||
return time == null ? 0 : time;
|
||||
}
|
||||
|
||||
public final void setMobSkillAnimationTime(MobSkill skill, int animationTime) {
|
||||
mobSkillAnimationTime.put(skill, animationTime);
|
||||
}
|
||||
|
||||
public final Integer getMobSkillAnimationTime(MobSkill skill) {
|
||||
Integer time = mobSkillAnimationTime.get(skill);
|
||||
return time == null ? 0 : time;
|
||||
}
|
||||
|
||||
public final void setMobAttackInfo(int monsterId, int attackPos, int mpCon, int coolTime) {
|
||||
mobAttackInfo.put((monsterId << 3) + attackPos, new Pair<>(mpCon, coolTime));
|
||||
}
|
||||
|
||||
public final Pair<Integer, Integer> getMobAttackInfo(int monsterId, int attackPos) {
|
||||
if (attackPos < 0 || attackPos > 7) return null;
|
||||
return mobAttackInfo.get((monsterId << 3) + attackPos);
|
||||
drops.put(monsterId, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public final List<Integer> retrieveDropPool(final int monsterId) { // ignores Quest and Party Quest items
|
||||
if (dropsChancePool.containsKey(monsterId)) {
|
||||
return dropsChancePool.get(monsterId);
|
||||
}
|
||||
|
||||
public static ArrayList<Pair<Integer, String>> getMobsIDsFromName(String search) {
|
||||
MapleDataProvider dataProvider = MapleDataProviderFactory.getDataProvider(new File("wz/String.wz"));
|
||||
ArrayList<Pair<Integer, String>> retMobs = new ArrayList<Pair<Integer, String>>();
|
||||
MapleData data = dataProvider.getData("Mob.img");
|
||||
List<Pair<Integer, String>> mobPairList = new LinkedList<Pair<Integer, String>>();
|
||||
for (MapleData mobIdData : data.getChildren()) {
|
||||
int mobIdFromData = Integer.parseInt(mobIdData.getName());
|
||||
String mobNameFromData = MapleDataTool.getString(mobIdData.getChildByPath("name"), "NO-NAME");
|
||||
mobPairList.add(new Pair<Integer, String>(mobIdFromData, mobNameFromData));
|
||||
}
|
||||
for (Pair<Integer, String> mobPair : mobPairList) {
|
||||
if (mobPair.getRight().toLowerCase().contains(search.toLowerCase())) {
|
||||
retMobs.add(mobPair);
|
||||
}
|
||||
}
|
||||
return retMobs;
|
||||
}
|
||||
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
|
||||
|
||||
public boolean isBoss(int id) {
|
||||
Boolean boss = mobBossCache.get(id);
|
||||
if (boss == null) {
|
||||
try {
|
||||
boss = MapleLifeFactory.getMonster(id).isBoss();
|
||||
} catch (NullPointerException npe) {
|
||||
boss = false;
|
||||
} catch (Exception e) { //nonexistant mob
|
||||
boss = false;
|
||||
|
||||
e.printStackTrace();
|
||||
System.err.println("Nonexistant mob id " + id);
|
||||
}
|
||||
|
||||
mobBossCache.put(id, boss);
|
||||
}
|
||||
|
||||
return boss;
|
||||
}
|
||||
|
||||
public String getMobNameFromId(int id) {
|
||||
String mobName = mobNameCache.get(id);
|
||||
if (mobName == null) {
|
||||
try
|
||||
{
|
||||
mobName = MapleLifeFactory.getMonster(id).getName();
|
||||
}
|
||||
catch (NullPointerException npe)
|
||||
{
|
||||
mobName = ""; //nonexistant mob
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
System.err.println("Nonexistant mob id " + id);
|
||||
mobName = ""; //nonexistant mob
|
||||
}
|
||||
|
||||
mobNameCache.put(id, mobName);
|
||||
}
|
||||
|
||||
return mobName;
|
||||
}
|
||||
List<MonsterDropEntry> dropList = retrieveDrop(monsterId);
|
||||
List<Integer> ret = new ArrayList<>();
|
||||
|
||||
public final void clearDrops() {
|
||||
drops.clear();
|
||||
hasNoMultiEquipDrops.clear();
|
||||
extraMultiEquipDrops.clear();
|
||||
dropsChancePool.clear();
|
||||
globaldrops.clear();
|
||||
continentdrops.clear();
|
||||
retrieveGlobal();
|
||||
}
|
||||
}
|
||||
int accProp = 0;
|
||||
for (MonsterDropEntry mde : dropList) {
|
||||
if (!ii.isQuestItem(mde.itemId) && !ii.isPartyQuestItem(mde.itemId)) {
|
||||
accProp += mde.chance;
|
||||
}
|
||||
|
||||
ret.add(accProp);
|
||||
}
|
||||
|
||||
if (accProp == 0) {
|
||||
ret.clear(); // don't accept mobs dropping no relevant items
|
||||
}
|
||||
dropsChancePool.put(monsterId, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public final void setMobAttackAnimationTime(int monsterId, int attackPos, int animationTime) {
|
||||
mobAttackAnimationTime.put(new Pair<>(monsterId, attackPos), animationTime);
|
||||
}
|
||||
|
||||
public final Integer getMobAttackAnimationTime(int monsterId, int attackPos) {
|
||||
Integer time = mobAttackAnimationTime.get(new Pair<>(monsterId, attackPos));
|
||||
return time == null ? 0 : time;
|
||||
}
|
||||
|
||||
public final void setMobSkillAnimationTime(MobSkill skill, int animationTime) {
|
||||
mobSkillAnimationTime.put(skill, animationTime);
|
||||
}
|
||||
|
||||
public final Integer getMobSkillAnimationTime(MobSkill skill) {
|
||||
Integer time = mobSkillAnimationTime.get(skill);
|
||||
return time == null ? 0 : time;
|
||||
}
|
||||
|
||||
public final void setMobAttackInfo(int monsterId, int attackPos, int mpCon, int coolTime) {
|
||||
mobAttackInfo.put((monsterId << 3) + attackPos, new Pair<>(mpCon, coolTime));
|
||||
}
|
||||
|
||||
public final Pair<Integer, Integer> getMobAttackInfo(int monsterId, int attackPos) {
|
||||
if (attackPos < 0 || attackPos > 7) {
|
||||
return null;
|
||||
}
|
||||
return mobAttackInfo.get((monsterId << 3) + attackPos);
|
||||
}
|
||||
|
||||
public static ArrayList<Pair<Integer, String>> getMobsIDsFromName(String search) {
|
||||
MapleDataProvider dataProvider = MapleDataProviderFactory.getDataProvider(new File("wz/String.wz"));
|
||||
ArrayList<Pair<Integer, String>> retMobs = new ArrayList<Pair<Integer, String>>();
|
||||
MapleData data = dataProvider.getData("Mob.img");
|
||||
List<Pair<Integer, String>> mobPairList = new LinkedList<Pair<Integer, String>>();
|
||||
for (MapleData mobIdData : data.getChildren()) {
|
||||
int mobIdFromData = Integer.parseInt(mobIdData.getName());
|
||||
String mobNameFromData = MapleDataTool.getString(mobIdData.getChildByPath("name"), "NO-NAME");
|
||||
mobPairList.add(new Pair<Integer, String>(mobIdFromData, mobNameFromData));
|
||||
}
|
||||
for (Pair<Integer, String> mobPair : mobPairList) {
|
||||
if (mobPair.getRight().toLowerCase().contains(search.toLowerCase())) {
|
||||
retMobs.add(mobPair);
|
||||
}
|
||||
}
|
||||
return retMobs;
|
||||
}
|
||||
|
||||
public boolean isBoss(int id) {
|
||||
Boolean boss = mobBossCache.get(id);
|
||||
if (boss == null) {
|
||||
try {
|
||||
boss = MapleLifeFactory.getMonster(id).isBoss();
|
||||
} catch (NullPointerException npe) {
|
||||
boss = false;
|
||||
} catch (Exception e) { //nonexistant mob
|
||||
boss = false;
|
||||
|
||||
e.printStackTrace();
|
||||
System.err.println("Nonexistant mob id " + id);
|
||||
}
|
||||
|
||||
mobBossCache.put(id, boss);
|
||||
}
|
||||
|
||||
return boss;
|
||||
}
|
||||
|
||||
public String getMobNameFromId(int id) {
|
||||
String mobName = mobNameCache.get(id);
|
||||
if (mobName == null) {
|
||||
try {
|
||||
mobName = MapleLifeFactory.getMonster(id).getName();
|
||||
} catch (NullPointerException npe) {
|
||||
mobName = ""; //nonexistant mob
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
System.err.println("Nonexistant mob id " + id);
|
||||
mobName = ""; //nonexistant mob
|
||||
}
|
||||
|
||||
mobNameCache.put(id, mobName);
|
||||
}
|
||||
|
||||
return mobName;
|
||||
}
|
||||
|
||||
public final void clearDrops() {
|
||||
drops.clear();
|
||||
hasNoMultiEquipDrops.clear();
|
||||
extraMultiEquipDrops.clear();
|
||||
dropsChancePool.clear();
|
||||
globaldrops.clear();
|
||||
continentdrops.clear();
|
||||
retrieveGlobal();
|
||||
}
|
||||
}
|
||||
|
||||
+103
-96
@@ -1,24 +1,24 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <[email protected]>
|
||||
Matthias Butz <[email protected]>
|
||||
Jan Christian Meyer <[email protected]>
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <[email protected]>
|
||||
Matthias Butz <[email protected]>
|
||||
Jan Christian Meyer <[email protected]>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package server.life;
|
||||
|
||||
import java.awt.Point;
|
||||
@@ -44,6 +44,7 @@ import tools.ArrayMap;
|
||||
* @author Danny (Leifde)
|
||||
*/
|
||||
public class MobSkill {
|
||||
|
||||
private int skillId, skillLevel, mpCon;
|
||||
private List<Integer> toSummon = new ArrayList<Integer>();
|
||||
private int spawnEffect, hp, x, y;
|
||||
@@ -106,17 +107,17 @@ public class MobSkill {
|
||||
|
||||
public void applyDelayedEffect(final MapleCharacter player, final MapleMonster monster, final boolean skill, int animationTime) {
|
||||
Runnable toRun = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if(monster.isAlive()) {
|
||||
applyEffect(player, monster, skill, null);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (monster.isAlive()) {
|
||||
applyEffect(player, monster, skill, null);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
monster.getMap().getChannelServer().registerOverallAction(monster.getMap().getId(), toRun, animationTime);
|
||||
}
|
||||
|
||||
|
||||
public void applyEffect(MapleCharacter player, MapleMonster monster, boolean skill, List<MapleCharacter> banishPlayers) {
|
||||
MapleDisease disease = null;
|
||||
Map<MonsterStatus, Integer> stats = new ArrayMap<MonsterStatus, Integer>();
|
||||
@@ -142,50 +143,50 @@ public class MobSkill {
|
||||
case 153:
|
||||
stats.put(MonsterStatus.MAGIC_DEFENSE_UP, Integer.valueOf(x));
|
||||
break;
|
||||
case 114:
|
||||
if (lt != null && rb != null && skill) {
|
||||
List<MapleMapObject> objects = getObjectsInRange(monster, MapleMapObjectType.MONSTER);
|
||||
final int hps = (getX() / 1000) * (int) (950 + 1050 * Math.random());
|
||||
for (MapleMapObject mons : objects) {
|
||||
((MapleMonster) mons).heal(hps, getY());
|
||||
}
|
||||
} else {
|
||||
monster.heal(getX(), getY());
|
||||
}
|
||||
break;
|
||||
case 120:
|
||||
case 114:
|
||||
if (lt != null && rb != null && skill) {
|
||||
List<MapleMapObject> objects = getObjectsInRange(monster, MapleMapObjectType.MONSTER);
|
||||
final int hps = (getX() / 1000) * (int) (950 + 1050 * Math.random());
|
||||
for (MapleMapObject mons : objects) {
|
||||
((MapleMonster) mons).heal(hps, getY());
|
||||
}
|
||||
} else {
|
||||
monster.heal(getX(), getY());
|
||||
}
|
||||
break;
|
||||
case 120:
|
||||
disease = MapleDisease.SEAL;
|
||||
break;
|
||||
case 121:
|
||||
disease = MapleDisease.DARKNESS;
|
||||
break;
|
||||
case 122:
|
||||
disease = MapleDisease.WEAKEN;
|
||||
break;
|
||||
case 123:
|
||||
disease = MapleDisease.STUN;
|
||||
break;
|
||||
case 124:
|
||||
disease = MapleDisease.CURSE;
|
||||
break;
|
||||
case 125:
|
||||
disease = MapleDisease.POISON;
|
||||
break;
|
||||
case 126: // Slow
|
||||
disease = MapleDisease.SLOW;
|
||||
break;
|
||||
case 127:
|
||||
if (lt != null && rb != null && skill) {
|
||||
for (MapleCharacter character : getPlayersInRange(monster, player)) {
|
||||
character.dispel();
|
||||
}
|
||||
} else {
|
||||
player.dispel();
|
||||
}
|
||||
break;
|
||||
case 128: // Seduce
|
||||
disease = MapleDisease.SEDUCE;
|
||||
break;
|
||||
break;
|
||||
case 121:
|
||||
disease = MapleDisease.DARKNESS;
|
||||
break;
|
||||
case 122:
|
||||
disease = MapleDisease.WEAKEN;
|
||||
break;
|
||||
case 123:
|
||||
disease = MapleDisease.STUN;
|
||||
break;
|
||||
case 124:
|
||||
disease = MapleDisease.CURSE;
|
||||
break;
|
||||
case 125:
|
||||
disease = MapleDisease.POISON;
|
||||
break;
|
||||
case 126: // Slow
|
||||
disease = MapleDisease.SLOW;
|
||||
break;
|
||||
case 127:
|
||||
if (lt != null && rb != null && skill) {
|
||||
for (MapleCharacter character : getPlayersInRange(monster, player)) {
|
||||
character.dispel();
|
||||
}
|
||||
} else {
|
||||
player.dispel();
|
||||
}
|
||||
break;
|
||||
case 128: // Seduce
|
||||
disease = MapleDisease.SEDUCE;
|
||||
break;
|
||||
case 129: // Banish
|
||||
if (lt != null && rb != null && skill) {
|
||||
for (MapleCharacter chr : getPlayersInRange(monster, player)) {
|
||||
@@ -214,35 +215,40 @@ public class MobSkill {
|
||||
stats.put(MonsterStatus.MAGIC_IMMUNITY, Integer.valueOf(x));
|
||||
}
|
||||
break;
|
||||
case 143: // Weapon Reflect
|
||||
stats.put(MonsterStatus.WEAPON_REFLECT, 10);
|
||||
stats.put(MonsterStatus.WEAPON_IMMUNITY, 10);
|
||||
reflection.add(x);
|
||||
break;
|
||||
case 144: // Magic Reflect
|
||||
stats.put(MonsterStatus.MAGIC_REFLECT, 10);
|
||||
stats.put(MonsterStatus.MAGIC_IMMUNITY, 10);
|
||||
reflection.add(x);
|
||||
break;
|
||||
case 145: // Weapon / Magic reflect
|
||||
stats.put(MonsterStatus.WEAPON_REFLECT, 10);
|
||||
stats.put(MonsterStatus.WEAPON_IMMUNITY, 10);
|
||||
stats.put(MonsterStatus.MAGIC_REFLECT, 10);
|
||||
stats.put(MonsterStatus.MAGIC_IMMUNITY, 10);
|
||||
reflection.add(x);
|
||||
case 143: // Weapon Reflect
|
||||
stats.put(MonsterStatus.WEAPON_REFLECT, 10);
|
||||
stats.put(MonsterStatus.WEAPON_IMMUNITY, 10);
|
||||
reflection.add(x);
|
||||
break;
|
||||
case 154: // accuracy up
|
||||
case 155: // avoid up
|
||||
case 156: // speed up
|
||||
case 144: // Magic Reflect
|
||||
stats.put(MonsterStatus.MAGIC_REFLECT, 10);
|
||||
stats.put(MonsterStatus.MAGIC_IMMUNITY, 10);
|
||||
reflection.add(x);
|
||||
break;
|
||||
case 145: // Weapon / Magic reflect
|
||||
stats.put(MonsterStatus.WEAPON_REFLECT, 10);
|
||||
stats.put(MonsterStatus.WEAPON_IMMUNITY, 10);
|
||||
stats.put(MonsterStatus.MAGIC_REFLECT, 10);
|
||||
stats.put(MonsterStatus.MAGIC_IMMUNITY, 10);
|
||||
reflection.add(x);
|
||||
break;
|
||||
case 154:
|
||||
stats.put(MonsterStatus.ACC, Integer.valueOf(x));
|
||||
break;
|
||||
case 155:
|
||||
stats.put(MonsterStatus.AVOID, Integer.valueOf(x));
|
||||
break;
|
||||
case 156:
|
||||
stats.put(MonsterStatus.SPEED, Integer.valueOf(x));
|
||||
break;
|
||||
case 200: // summon
|
||||
int skillLimit = this.getLimit();
|
||||
MapleMap map = monster.getMap();
|
||||
|
||||
|
||||
if (map.isDojoMap()) { // spawns in dojo should be unlimited
|
||||
skillLimit = Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
|
||||
if (map.getSpawnedMonstersOnMap() < 80) {
|
||||
List<Integer> summons = getSummons();
|
||||
int summonLimit = monster.countAvailableMobSummons(summons.size(), skillLimit);
|
||||
@@ -252,9 +258,10 @@ public class MobSkill {
|
||||
|
||||
for (Integer mobId : summons.subList(0, summonLimit)) {
|
||||
MapleMonster toSpawn = MapleLifeFactory.getMonster(mobId);
|
||||
if(toSpawn != null) {
|
||||
if(bossRushMap) toSpawn.disableDrops(); // no littering on BRPQ pls
|
||||
|
||||
if (toSpawn != null) {
|
||||
if (bossRushMap) {
|
||||
toSpawn.disableDrops(); // no littering on BRPQ pls
|
||||
}
|
||||
toSpawn.setPosition(monster.getPosition());
|
||||
int ypos, xpos;
|
||||
xpos = (int) monster.getPosition().getX();
|
||||
@@ -277,7 +284,7 @@ public class MobSkill {
|
||||
} else {
|
||||
xpos = (int) (monster.getPosition().getX() + Randomizer.nextInt(1000) - 500);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
switch (map.getId()) {
|
||||
case 220080001: //Pap map
|
||||
@@ -297,9 +304,9 @@ public class MobSkill {
|
||||
}
|
||||
toSpawn.setPosition(new Point(xpos, ypos));
|
||||
if (toSpawn.getId() == 8500004) {
|
||||
map.spawnFakeMonster(toSpawn);
|
||||
map.spawnFakeMonster(toSpawn);
|
||||
} else {
|
||||
map.spawnMonsterWithEffect(toSpawn, getSpawnEffect(), toSpawn.getPosition());
|
||||
map.spawnMonsterWithEffect(toSpawn, getSpawnEffect(), toSpawn.getPosition());
|
||||
}
|
||||
monster.addSummonedMob(toSpawn);
|
||||
}
|
||||
|
||||
+380
-53
@@ -84,18 +84,21 @@ import server.life.MapleNPC;
|
||||
import server.life.MonsterDropEntry;
|
||||
import server.life.MonsterGlobalDropEntry;
|
||||
import server.life.SpawnPoint;
|
||||
import server.partyquest.MonsterCarnival;
|
||||
import server.partyquest.MonsterCarnivalParty;
|
||||
//import server.partyquest.Pyramid;
|
||||
import scripting.event.EventInstanceManager;
|
||||
import server.life.MaplePlayerNPC;
|
||||
import server.life.MobSkill;
|
||||
import server.life.MobSkillFactory;
|
||||
import server.life.MonsterListener;
|
||||
import server.partyquest.GuardianSpawnPoint;
|
||||
import server.partyquest.MapleCarnivalFactory;
|
||||
import server.partyquest.MapleCarnivalFactory.MCSkill;
|
||||
import tools.FilePrinter;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.Pair;
|
||||
import tools.Randomizer;
|
||||
|
||||
public class MapleMap {
|
||||
|
||||
private static final List<MapleMapObjectType> rangedMapobjectTypes = Arrays.asList(MapleMapObjectType.SHOP, MapleMapObjectType.ITEM, MapleMapObjectType.NPC, MapleMapObjectType.MONSTER, MapleMapObjectType.DOOR, MapleMapObjectType.SUMMON, MapleMapObjectType.REACTOR);
|
||||
private static final Map<Integer, Pair<Integer, Integer>> dropBoundsCache = new HashMap<>(100);
|
||||
|
||||
@@ -275,7 +278,9 @@ public class MapleMap {
|
||||
}
|
||||
|
||||
public MapleMap getReturnMap() {
|
||||
if(returnMapId == 999999999) return this;
|
||||
if (returnMapId == 999999999) {
|
||||
return this;
|
||||
}
|
||||
return getChannelServer().getMapFactory().getMap(returnMapId);
|
||||
}
|
||||
|
||||
@@ -538,8 +543,11 @@ public class MapleMap {
|
||||
}
|
||||
|
||||
public Point calcDropPos(Point initial, Point fallback) {
|
||||
if(initial.x < xLimits.left) initial.x = xLimits.left;
|
||||
else if(initial.x > xLimits.right) initial.x = xLimits.right;
|
||||
if (initial.x < xLimits.left) {
|
||||
initial.x = xLimits.left;
|
||||
} else if(initial.x > xLimits.right) {
|
||||
initial.x = xLimits.right;
|
||||
}
|
||||
|
||||
Point ret = calcPointBelow(new Point(initial.x, initial.y - 85));
|
||||
if (ret == null) {
|
||||
@@ -559,8 +567,8 @@ public class MapleMap {
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches angle relative between spawn and door points
|
||||
* where 3 O'Clock is 0 and 12 O'Clock is 270 degrees
|
||||
* Fetches angle relative between spawn and door points where 3 O'Clock is 0
|
||||
* and 12 O'Clock is 270 degrees
|
||||
*
|
||||
* @param spawnPoint
|
||||
* @param doorPoint
|
||||
@@ -574,10 +582,11 @@ public class MapleMap {
|
||||
double inRads = Math.atan2(dy, dx);
|
||||
|
||||
// We need to map to coord system when 0 degree is at 3 O'clock, 270 at 12 O'clock
|
||||
if (inRads < 0)
|
||||
if (inRads < 0) {
|
||||
inRads = Math.abs(inRads);
|
||||
else
|
||||
} else {
|
||||
inRads = 2 * Math.PI - inRads;
|
||||
}
|
||||
|
||||
return Math.toDegrees(inRads);
|
||||
}
|
||||
@@ -650,7 +659,9 @@ public class MapleMap {
|
||||
mesos = (int) (mesos * chr.getBuffedValue(MapleBuffStat.MESOUP).doubleValue() / 100.0);
|
||||
}
|
||||
mesos = mesos * chr.getMesoRate();
|
||||
if(mesos <= 0) mesos = Integer.MAX_VALUE;
|
||||
if (mesos <= 0) {
|
||||
mesos = Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
spawnMesoDrop(mesos, calcDropPos(pos, mob.getPosition()), mob, chr, false, droptype);
|
||||
}
|
||||
@@ -713,7 +724,9 @@ public class MapleMap {
|
||||
chRate *= (stati.getStati().get(MonsterStatus.SHOWDOWN).doubleValue() / 100.0 + 1.0);
|
||||
}
|
||||
|
||||
if(useBaseRate) chRate = 1;
|
||||
if (useBaseRate) {
|
||||
chRate = 1;
|
||||
}
|
||||
|
||||
final MapleMonsterInformationProvider mi = MapleMonsterInformationProvider.getInstance();
|
||||
final List<MonsterGlobalDropEntry> globalEntry = mi.getRelevantGlobalDrops(this.getId());
|
||||
@@ -773,7 +786,9 @@ public class MapleMap {
|
||||
private void startItemMonitor() {
|
||||
chrWLock.lock();
|
||||
try {
|
||||
if(itemMonitor != null) return;
|
||||
if (itemMonitor != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
itemMonitor = TimerManager.getInstance().register(new Runnable() {
|
||||
@Override
|
||||
@@ -806,7 +821,9 @@ public class MapleMap {
|
||||
objectRLock.unlock();
|
||||
}
|
||||
|
||||
if(tryClean) cleanItemMonitor();
|
||||
if (tryClean) {
|
||||
cleanItemMonitor();
|
||||
}
|
||||
}
|
||||
}, ServerConstants.ITEM_MONITOR_TIME, ServerConstants.ITEM_MONITOR_TIME);
|
||||
|
||||
@@ -861,7 +878,9 @@ public class MapleMap {
|
||||
try {
|
||||
mapobj = registeredDrops.remove(0).get();
|
||||
while(mapobj == null) {
|
||||
if(registeredDrops.isEmpty()) break;
|
||||
if (registeredDrops.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
mapobj = registeredDrops.remove(0).get();
|
||||
}
|
||||
} finally {
|
||||
@@ -1004,7 +1023,9 @@ public class MapleMap {
|
||||
if(mdrop.getOwnerId() == charid) {
|
||||
mdrop.lockItem();
|
||||
try {
|
||||
if(mdrop.isPickedUp()) return;
|
||||
if (mdrop.isPickedUp()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mdrop.setPartyOwnerId(partyid);
|
||||
|
||||
@@ -1197,7 +1218,9 @@ public class MapleMap {
|
||||
int count = 0;
|
||||
|
||||
for(MapleCharacter mc: getAllPlayers()) {
|
||||
if(mc.isAlive()) count++;
|
||||
if (mc.isAlive()) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
@@ -1233,7 +1256,9 @@ public class MapleMap {
|
||||
public List<MapleMonster> getMonsters() {
|
||||
List<MapleMonster> mobs = new ArrayList<>();
|
||||
for (MapleMapObject object : this.getMapObjects()) {
|
||||
if(object instanceof MapleMonster) mobs.add((MapleMonster)object);
|
||||
if (object instanceof MapleMonster) {
|
||||
mobs.add((MapleMonster)object);
|
||||
}
|
||||
}
|
||||
return mobs;
|
||||
}
|
||||
@@ -1276,7 +1301,9 @@ public class MapleMap {
|
||||
}
|
||||
|
||||
public void killMonster(final MapleMonster monster, final MapleCharacter chr, final boolean withDrops, int animation) {
|
||||
if(monster == null) return;
|
||||
if (monster == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (chr == null) {
|
||||
if(removeKilledMonsterObject(monster)) {
|
||||
@@ -1288,12 +1315,18 @@ public class MapleMap {
|
||||
if (monster.getStats().getLevel() >= chr.getLevel() + 30 && !chr.isGM()) {
|
||||
AutobanFactory.GENERAL.alert(chr, " for killing a " + monster.getName() + " which is over 30 levels higher.");
|
||||
}
|
||||
|
||||
/*if (chr.getQuest(MapleQuest.getInstance(29400)).getStatus().equals(MapleQuestStatus.Status.STARTED)) {
|
||||
if (chr.getLevel() >= 120 && monster.getStats().getLevel() >= 120) {
|
||||
//FIX MEDAL SHET
|
||||
} else if (monster.getStats().getLevel() >= chr.getLevel()) {
|
||||
}
|
||||
}*/
|
||||
|
||||
if (monster.getCP() > 0 && chr.getMap().isCPQMap()) {
|
||||
chr.gainCP(monster.getCP());
|
||||
}
|
||||
|
||||
int buff = monster.getBuffToGive();
|
||||
if (buff > -1) {
|
||||
MapleItemInformationProvider mii = MapleItemInformationProvider.getInstance();
|
||||
@@ -1307,13 +1340,7 @@ public class MapleMap {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (monster.getCP() > 0 && chr.getCarnival() != null) {
|
||||
chr.getCarnivalParty().addCP(chr, monster.getCP());
|
||||
chr.announce(MaplePacketCreator.updateCP(chr.getCP(), chr.getObtainedCP()));
|
||||
broadcastMessage(MaplePacketCreator.updatePartyCP(chr.getCarnivalParty()));
|
||||
//they drop items too ):
|
||||
}
|
||||
|
||||
if (monster.getId() >= 8800003 && monster.getId() <= 8800010) {
|
||||
boolean makeZakReal = true;
|
||||
Collection<MapleMapObject> objects = getMapObjects();
|
||||
@@ -1389,7 +1416,9 @@ public class MapleMap {
|
||||
for (MapleMonster mob : mobList) {
|
||||
if (mob.getId() == mobId) {
|
||||
MapleCharacter chr = mapChars.get(mob.getHighestDamagerId());
|
||||
if(chr == null) chr = defaultChr;
|
||||
if (chr == null) {
|
||||
chr = defaultChr;
|
||||
}
|
||||
|
||||
this.killMonster(mob, chr, true);
|
||||
}
|
||||
@@ -1788,7 +1817,9 @@ public class MapleMap {
|
||||
|
||||
public void spawnRevives(final MapleMonster monster) {
|
||||
monster.setMap(this);
|
||||
if(getEventInstance() != null) getEventInstance().registerMonster(monster);
|
||||
if (getEventInstance() != null) {
|
||||
getEventInstance().registerMonster(monster);
|
||||
}
|
||||
|
||||
spawnAndAddRangedMapObject(monster, new DelayedPacketCreation() {
|
||||
@Override
|
||||
@@ -1890,7 +1921,9 @@ public class MapleMap {
|
||||
monster.changeDifficulty(difficulty, isPq);
|
||||
|
||||
monster.setMap(this);
|
||||
if(getEventInstance() != null) getEventInstance().registerMonster(monster);
|
||||
if (getEventInstance() != null) {
|
||||
getEventInstance().registerMonster(monster);
|
||||
}
|
||||
|
||||
spawnAndAddRangedMapObject(monster, new DelayedPacketCreation() {
|
||||
@Override
|
||||
@@ -1901,6 +1934,22 @@ public class MapleMap {
|
||||
|
||||
monster.aggroUpdateController();
|
||||
|
||||
if ((monster.getTeam() == 1 || monster.getTeam() == 0) && (isCPQMap() || isCPQMap2())) {
|
||||
List<MCSkill> teamS = null;
|
||||
if (monster.getTeam() == 0) {
|
||||
teamS = redTeamBuffs;
|
||||
} else if (monster.getTeam() == 1) {
|
||||
teamS = blueTeamBuffs;
|
||||
}
|
||||
if (teamS != null) {
|
||||
for (MCSkill skil : teamS) {
|
||||
if (skil != null) {
|
||||
skil.getSkill().applyEffect(null, monster, false, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (monster.hasBossHPBar()) {
|
||||
broadcastBossHpMessage(monster, monster.hashCode(), monster.makeBossHPBarPacket(), monster.getPosition());
|
||||
}
|
||||
@@ -1932,9 +1981,13 @@ public class MapleMap {
|
||||
monster.setMap(this);
|
||||
Point spos = new Point(pos.x, pos.y - 1);
|
||||
spos = calcPointBelow(spos);
|
||||
if(spos == null) return;
|
||||
if (spos == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(getEventInstance() != null) getEventInstance().registerMonster(monster);
|
||||
if (getEventInstance() != null) {
|
||||
getEventInstance().registerMonster(monster);
|
||||
}
|
||||
|
||||
spos.y--;
|
||||
monster.setPosition(spos);
|
||||
@@ -2008,7 +2061,9 @@ public class MapleMap {
|
||||
}
|
||||
|
||||
c.announce(MaplePacketCreator.spawnPortal(door.getFrom().getId(), door.getTo().getId(), door.toPosition()));
|
||||
if(!door.inTown()) c.announce(MaplePacketCreator.spawnDoor(door.getOwnerId(), door.getPosition(), false));
|
||||
if (!door.inTown()) {
|
||||
c.announce(MaplePacketCreator.spawnDoor(door.getOwnerId(), door.getPosition(), false));
|
||||
}
|
||||
}
|
||||
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
@@ -2153,7 +2208,9 @@ public class MapleMap {
|
||||
// spawns item instances of all defined item ids on a list
|
||||
public final void spawnItemDropList(List<Integer> list, int minCopies, int maxCopies, final MapleMapObject dropper, final MapleCharacter owner, Point pos, final boolean ffaDrop, final boolean playerDrop) {
|
||||
int copies = (maxCopies - minCopies) + 1;
|
||||
if(copies < 1) return;
|
||||
if(copies < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
Collections.shuffle(list);
|
||||
|
||||
@@ -2166,8 +2223,7 @@ public class MapleMap {
|
||||
for(int i = 0; i < list.size(); i++) {
|
||||
if(list.get(i) == 0) {
|
||||
spawnMesoDrop(owner != null ? 10 * owner.getMesoRate() : 10, calcDropPos(dropPos, pos), dropper, owner, playerDrop, (byte) (ffaDrop ? 2 : 0));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
final Item drop;
|
||||
int randomedId = list.get(i);
|
||||
|
||||
@@ -2280,7 +2336,9 @@ public class MapleMap {
|
||||
|
||||
private void addPartyMemberInternal(MapleCharacter chr) {
|
||||
int partyid = chr.getPartyId();
|
||||
if(partyid == -1) return;
|
||||
if (partyid == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<Integer> partyEntry = mapParty.get(partyid);
|
||||
if(partyEntry == null) {
|
||||
@@ -2295,12 +2353,17 @@ public class MapleMap {
|
||||
|
||||
private void removePartyMemberInternal(MapleCharacter chr) {
|
||||
int partyid = chr.getPartyId();
|
||||
if(partyid == -1) return;
|
||||
if (partyid == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<Integer> partyEntry = mapParty.get(partyid);
|
||||
if(partyEntry != null) {
|
||||
if(partyEntry.size() > 1) partyEntry.remove(chr.getId());
|
||||
else mapParty.remove(partyid);
|
||||
if (partyEntry.size() > 1) {
|
||||
partyEntry.remove(chr.getId());
|
||||
} else {
|
||||
mapParty.remove(partyid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2441,7 +2504,9 @@ public class MapleMap {
|
||||
}, travelTime);
|
||||
} else if (MapleMiniDungeonInfo.isDungeonMap(mapid)) {
|
||||
MapleMiniDungeon mmd = chr.getClient().getChannelServer().getMiniDungeon(mapid);
|
||||
if(mmd != null) mmd.registerPlayer(chr);
|
||||
if (mmd != null) {
|
||||
mmd.registerPlayer(chr);
|
||||
}
|
||||
}
|
||||
|
||||
MaplePet[] pets = chr.getPets();
|
||||
@@ -2454,6 +2519,23 @@ public class MapleMap {
|
||||
}
|
||||
}
|
||||
|
||||
if (chr.getMonsterCarnival() != null) {
|
||||
chr.getClient().announce(MaplePacketCreator.getClock(chr.getMonsterCarnival().getTimeLeftSeconds()));
|
||||
if (isCPQMap()) {
|
||||
int team = -1;
|
||||
int oposition = -1;
|
||||
if (chr.getTeam() == 0) {
|
||||
team = 0;
|
||||
oposition = 1;
|
||||
}
|
||||
if (chr.getTeam() == 1) {
|
||||
team = 1;
|
||||
oposition = 0;
|
||||
}
|
||||
chr.getClient().announce(MaplePacketCreator.startMonsterCarnival(chr, team, oposition));
|
||||
}
|
||||
}
|
||||
|
||||
chr.removeSandboxItems();
|
||||
|
||||
if (chr.getChalkboard() != null) {
|
||||
@@ -2537,19 +2619,16 @@ public class MapleMap {
|
||||
chr.announce(MaplePacketCreator.rollSnowBall(true, 0, null, null));
|
||||
}
|
||||
|
||||
MonsterCarnival carnival = chr.getCarnival();
|
||||
MonsterCarnivalParty cparty = chr.getCarnivalParty();
|
||||
if (carnival != null && cparty != null && (mapid == 980000101 || mapid == 980000201 || mapid == 980000301 || mapid == 980000401 || mapid == 980000501 || mapid == 980000601)) {
|
||||
chr.getClient().announce(MaplePacketCreator.getClock((int) (carnival.getTimeLeft() / 1000)));
|
||||
chr.getClient().announce(MaplePacketCreator.startCPQ(chr, carnival.oppositeTeam(cparty)));
|
||||
}
|
||||
if (hasClock()) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
chr.getClient().announce((MaplePacketCreator.getClockTime(cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND))));
|
||||
}
|
||||
if (hasBoat() > 0) {
|
||||
if(hasBoat() == 1) chr.getClient().announce((MaplePacketCreator.boatPacket(true)));
|
||||
else chr.getClient().announce(MaplePacketCreator.boatPacket(false));
|
||||
if (hasBoat() == 1) {
|
||||
chr.getClient().announce((MaplePacketCreator.boatPacket(true)));
|
||||
} else {
|
||||
chr.getClient().announce(MaplePacketCreator.boatPacket(false));
|
||||
}
|
||||
}
|
||||
|
||||
chr.receivePartyMemberHP();
|
||||
@@ -3222,6 +3301,10 @@ public class MapleMap {
|
||||
public boolean hasClock() {
|
||||
return clock;
|
||||
}
|
||||
|
||||
public void addClock(int seconds) {
|
||||
broadcastMessage(MaplePacketCreator.getClock(seconds));
|
||||
}
|
||||
|
||||
public void setTown(boolean isTown) {
|
||||
this.town = isTown;
|
||||
@@ -3324,6 +3407,7 @@ public class MapleMap {
|
||||
}
|
||||
|
||||
private class MobLootEntry implements Runnable {
|
||||
|
||||
private byte droptype;
|
||||
private int mobpos;
|
||||
private int chRate;
|
||||
@@ -3434,7 +3518,9 @@ public class MapleMap {
|
||||
}
|
||||
|
||||
public void instanceMapRespawn() {
|
||||
if(!allowSummons) return;
|
||||
if (!allowSummons) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int numShouldSpawn = (short) ((monsterSpawn.size() - spawnedMonstersOnMap.get()));//Fking lol'd
|
||||
if (numShouldSpawn > 0) {
|
||||
@@ -3454,7 +3540,9 @@ public class MapleMap {
|
||||
}
|
||||
|
||||
public void instanceMapForceRespawn() {
|
||||
if(!allowSummons) return;
|
||||
if (!allowSummons) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int numShouldSpawn = (short) ((monsterSpawn.size() - spawnedMonstersOnMap.get()));//Fking lol'd
|
||||
if (numShouldSpawn > 0) {
|
||||
@@ -3537,7 +3625,9 @@ public class MapleMap {
|
||||
}
|
||||
|
||||
public void respawn() {
|
||||
if(!allowSummons) return;
|
||||
if (!allowSummons) {
|
||||
return;
|
||||
}
|
||||
|
||||
int numPlayers;
|
||||
chrRLock.lock();
|
||||
@@ -3996,7 +4086,9 @@ public class MapleMap {
|
||||
|
||||
public boolean isHorntailDefeated() { // all parts of dead horntail can be found here?
|
||||
for(int i = 8810010; i <= 8810017; i++) {
|
||||
if(getMonsterById(i) == null) return false;
|
||||
if (getMonsterById(i) == null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -4100,6 +4192,241 @@ public class MapleMap {
|
||||
}
|
||||
}
|
||||
|
||||
private final List<Point> takenSpawns = new LinkedList<>();
|
||||
private final List<GuardianSpawnPoint> guardianSpawns = new LinkedList<>();
|
||||
private final List<MCSkill> blueTeamBuffs = new ArrayList();
|
||||
private final List<MCSkill> redTeamBuffs = new ArrayList();
|
||||
private List<Integer> skillIds = new ArrayList();
|
||||
private List<Pair<Integer, Integer>> mobsToSpawn = new ArrayList();
|
||||
|
||||
public List<MCSkill> getBlueTeamBuffs() {
|
||||
return blueTeamBuffs;
|
||||
}
|
||||
|
||||
public List<MCSkill> getRedTeamBuffs() {
|
||||
return redTeamBuffs;
|
||||
}
|
||||
|
||||
public void clearBuffList() {
|
||||
redTeamBuffs.clear();
|
||||
blueTeamBuffs.clear();
|
||||
}
|
||||
|
||||
public List<MapleMapObject> getAllPlayer() {
|
||||
return getMapObjectsInRange(new Point(0, 0), Double.POSITIVE_INFINITY, Arrays.asList(MapleMapObjectType.PLAYER));
|
||||
}
|
||||
|
||||
public boolean isCPQMap() {
|
||||
switch (this.getId()) {
|
||||
case 980000101:
|
||||
case 980000201:
|
||||
case 980000301:
|
||||
case 980000401:
|
||||
case 980000501:
|
||||
case 980000601:
|
||||
case 980031100:
|
||||
case 980032100:
|
||||
case 980033100:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isCPQMap2() {
|
||||
switch (this.getId()) {
|
||||
case 980031100:
|
||||
case 980032100:
|
||||
case 980033100:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isCPQLobby() {
|
||||
switch (this.getId()) {
|
||||
case 980000100:
|
||||
case 980000200:
|
||||
case 980000300:
|
||||
case 980000400:
|
||||
case 980000500:
|
||||
case 980000600:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isBlueCPQMap() {
|
||||
switch (this.getId()) {
|
||||
case 980000501:
|
||||
case 980000601:
|
||||
case 980031200:
|
||||
case 980032200:
|
||||
case 980033200:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPurpleCPQMap() {
|
||||
switch (this.getId()) {
|
||||
case 980000301:
|
||||
case 980000401:
|
||||
case 980031200:
|
||||
case 980032200:
|
||||
case 980033200:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Point getRandomSP(int team) {
|
||||
if (takenSpawns.size() > 0) {
|
||||
for (SpawnPoint sp : monsterSpawn) {
|
||||
for (Point pt : takenSpawns) {
|
||||
if ((sp.getPosition().x == pt.x && sp.getPosition().y == pt.y) || (sp.getTeam() != team && !this.isBlueCPQMap())) {
|
||||
continue;
|
||||
} else {
|
||||
takenSpawns.add(pt);
|
||||
return sp.getPosition();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (SpawnPoint sp : monsterSpawn) {
|
||||
if (sp.getTeam() == team || this.isBlueCPQMap()) {
|
||||
takenSpawns.add(sp.getPosition());
|
||||
return sp.getPosition();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public GuardianSpawnPoint getRandomGuardianSpawn(int team) {
|
||||
boolean alltaken = false;
|
||||
for (GuardianSpawnPoint a : this.guardianSpawns) {
|
||||
if (!a.isTaken()) {
|
||||
alltaken = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (alltaken) {
|
||||
return null;
|
||||
}
|
||||
if (this.guardianSpawns.size() > 0) {
|
||||
while (true) {
|
||||
for (GuardianSpawnPoint gsp : this.guardianSpawns) {
|
||||
if (!gsp.isTaken() && Math.random() < 0.3 && (gsp.getTeam() == -1 || gsp.getTeam() == team)) {
|
||||
return gsp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addGuardianSpawnPoint(GuardianSpawnPoint a) {
|
||||
this.guardianSpawns.add(a);
|
||||
}
|
||||
|
||||
public int spawnGuardian(int team, int num) {
|
||||
try {
|
||||
if (team == 0 && redTeamBuffs.size() >= 4 || team == 1 && blueTeamBuffs.size() >= 4) {
|
||||
return 2;
|
||||
}
|
||||
final MCSkill skil = MapleCarnivalFactory.getInstance().getGuardian(num);
|
||||
if (team == 0 && redTeamBuffs.contains(skil)) {
|
||||
return 0;
|
||||
} else if (team == 1 && blueTeamBuffs.contains(skil)) {
|
||||
return 0;
|
||||
}
|
||||
GuardianSpawnPoint pt = this.getRandomGuardianSpawn(team);
|
||||
if (pt == null) {
|
||||
return -1;
|
||||
}
|
||||
int reactorID = 9980000 + team;
|
||||
MapleReactor reactor = new MapleReactor(MapleReactorFactory.getReactorS(reactorID), reactorID);
|
||||
pt.setTaken(true);
|
||||
reactor.setPosition(pt.getPosition());
|
||||
reactor.setName(team + "" + num); //lol
|
||||
reactor.resetReactorActions(0);
|
||||
this.spawnReactor(reactor);
|
||||
reactor.setGuardian(pt);
|
||||
this.buffMonsters(team, skil);
|
||||
getReactorByOid(reactor.getObjectId()).hitReactor(((MapleCharacter) this.getAllPlayer().get(0)).getClient());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
public void buffMonsters(int team, MCSkill skil) {
|
||||
if (team == 0) {
|
||||
redTeamBuffs.add(skil);
|
||||
} else if (team == 1) {
|
||||
blueTeamBuffs.add(skil);
|
||||
}
|
||||
for (MapleMapObject mmo : this.mapobjects.values()) {
|
||||
if (mmo.getType() == MapleMapObjectType.MONSTER) {
|
||||
MapleMonster mob = (MapleMonster) mmo;
|
||||
if (mob.getTeam() == team) {
|
||||
if (skil != null) {
|
||||
skil.getSkill().applyEffect(null, mob, false, null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final List<Integer> getSkillIds() {
|
||||
return skillIds;
|
||||
}
|
||||
|
||||
public final void addSkillId(int z) {
|
||||
this.skillIds.add(z);
|
||||
}
|
||||
|
||||
public final void addMobSpawn(int mobId, int spendCP) {
|
||||
this.mobsToSpawn.add(new Pair<Integer, Integer>(mobId, spendCP));
|
||||
}
|
||||
|
||||
public final List<Pair<Integer, Integer>> getMobsToSpawn() {
|
||||
return mobsToSpawn;
|
||||
}
|
||||
|
||||
public boolean isCPQWinnerMap() {
|
||||
switch (this.getId()) {
|
||||
case 980000103:
|
||||
case 980000203:
|
||||
case 980000303:
|
||||
case 980000403:
|
||||
case 980000503:
|
||||
case 980000603:
|
||||
case 980031300:
|
||||
case 980032300:
|
||||
case 980033300:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isCPQLoserMap() {
|
||||
switch (this.getId()) {
|
||||
case 980000104:
|
||||
case 980000204:
|
||||
case 980000304:
|
||||
case 980000404:
|
||||
case 980000504:
|
||||
case 980000604:
|
||||
case 980031400:
|
||||
case 980032400:
|
||||
case 980033400:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
for(MapleMonster mm : this.getMonsters()) {
|
||||
mm.dispose();
|
||||
@@ -4140,4 +4467,4 @@ public class MapleMap {
|
||||
chrWLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,12 +48,14 @@ import server.life.MapleMonster;
|
||||
import server.life.MaplePlayerNPC;
|
||||
import server.life.MaplePlayerNPCFactory;
|
||||
import scripting.event.EventInstanceManager;
|
||||
import server.partyquest.GuardianSpawnPoint;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.StringUtil;
|
||||
|
||||
public class MapleMapFactory {
|
||||
|
||||
private static Map<Integer, Float> mapRecoveryRate = new HashMap<>();
|
||||
|
||||
|
||||
private MapleDataProvider source;
|
||||
private MapleData nameData;
|
||||
private EventInstanceManager event;
|
||||
@@ -68,12 +70,12 @@ public class MapleMapFactory {
|
||||
this.world = world;
|
||||
this.channel = channel;
|
||||
this.event = eim;
|
||||
|
||||
|
||||
ReentrantReadWriteLock rrwl = new MonitoredReentrantReadWriteLock(MonitoredLockType.MAP_FACTORY);
|
||||
this.mapsRLock = rrwl.readLock();
|
||||
this.mapsWLock = rrwl.writeLock();
|
||||
}
|
||||
|
||||
|
||||
public MapleMap resetMap(int mapid) {
|
||||
mapsWLock.lock();
|
||||
try {
|
||||
@@ -81,14 +83,23 @@ public class MapleMapFactory {
|
||||
} finally {
|
||||
mapsWLock.unlock();
|
||||
}
|
||||
|
||||
|
||||
return getMap(mapid);
|
||||
}
|
||||
|
||||
|
||||
private void loadLifeFromWz(MapleMap map, MapleData mapData) {
|
||||
for (MapleData life : mapData.getChildByPath("life")) {
|
||||
life.getName();
|
||||
String id = MapleDataTool.getString(life.getChildByPath("id"));
|
||||
String type = MapleDataTool.getString(life.getChildByPath("type"));
|
||||
int team = MapleDataTool.getInt("team", life, -1);
|
||||
if (map.isCPQMap2() && type.equals("m")) {
|
||||
if((Integer.parseInt(life.getName()) % 2) == 0) {
|
||||
team = 0;
|
||||
} else {
|
||||
team = 1;
|
||||
}
|
||||
}
|
||||
int cy = MapleDataTool.getInt(life.getChildByPath("cy"));
|
||||
MapleData dF = life.getChildByPath("f");
|
||||
int f = (dF != null) ? MapleDataTool.getInt(dF) : 0;
|
||||
@@ -99,12 +110,11 @@ public class MapleMapFactory {
|
||||
int y = MapleDataTool.getInt(life.getChildByPath("y"));
|
||||
int hide = MapleDataTool.getInt("hide", life, 0);
|
||||
int mobTime = MapleDataTool.getInt("mobTime", life, 0);
|
||||
int team = MapleDataTool.getInt("team", life, -1);
|
||||
|
||||
loadLifeRaw(map, Integer.parseInt(id), type, cy, f, fh, rx0, rx1, x, y, hide, mobTime, team);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void loadLifeFromDb(MapleMap map) {
|
||||
try {
|
||||
Connection con = DatabaseConnection.getConnection();
|
||||
@@ -113,7 +123,7 @@ public class MapleMapFactory {
|
||||
ps.setInt(2, map.getWorld());
|
||||
|
||||
ResultSet rs = ps.executeQuery();
|
||||
while(rs.next()) {
|
||||
while (rs.next()) {
|
||||
int id = rs.getInt("life");
|
||||
String type = rs.getString("type");
|
||||
int cy = rs.getInt("cy");
|
||||
@@ -137,12 +147,12 @@ public class MapleMapFactory {
|
||||
sqle.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void loadLifeRaw(MapleMap map, int id, String type, int cy, int f, int fh, int rx0, int rx1, int x, int y, int hide, int mobTime, int team) {
|
||||
AbstractLoadedMapleLife myLife = loadLife(id, type, cy, f, fh, rx0, rx1, x, y, hide);
|
||||
if (myLife instanceof MapleMonster) {
|
||||
MapleMonster monster = (MapleMonster) myLife;
|
||||
|
||||
|
||||
if (mobTime == -1) { //does not respawn, force spawn once
|
||||
map.spawnMonster(monster);
|
||||
} else {
|
||||
@@ -155,10 +165,10 @@ public class MapleMapFactory {
|
||||
map.addMapObject(myLife);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private synchronized MapleMap loadMapFromWz(int mapid, Integer omapid) {
|
||||
MapleMap map;
|
||||
|
||||
|
||||
mapsRLock.lock();
|
||||
try {
|
||||
map = maps.get(omapid);
|
||||
@@ -169,7 +179,7 @@ public class MapleMapFactory {
|
||||
if (map != null) {
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
String mapName = getMapName(mapid);
|
||||
MapleData mapData = source.getData(mapName); // source.getData issue with giving nulls in rare ocasions found thanks to MedicOP
|
||||
MapleData infoData = mapData.getChildByPath("info");
|
||||
@@ -209,9 +219,9 @@ public class MapleMapFactory {
|
||||
bounds[0] = MapleDataTool.getInt(infoData.getChildByPath("VRTop"));
|
||||
bounds[1] = MapleDataTool.getInt(infoData.getChildByPath("VRBottom"));
|
||||
|
||||
if(bounds[0] == bounds[1]) { // old-style baked map
|
||||
if (bounds[0] == bounds[1]) { // old-style baked map
|
||||
MapleData minimapData = mapData.getChildByPath("miniMap");
|
||||
if(minimapData != null) {
|
||||
if (minimapData != null) {
|
||||
bounds[0] = MapleDataTool.getInt(minimapData.getChildByPath("centerX")) * -1;
|
||||
bounds[1] = MapleDataTool.getInt(minimapData.getChildByPath("centerY")) * -1;
|
||||
bounds[2] = MapleDataTool.getInt(minimapData.getChildByPath("height"));
|
||||
@@ -272,7 +282,7 @@ public class MapleMapFactory {
|
||||
map.addMapleArea(new Rectangle(x1, y1, (x2 - x1), (y2 - y1)));
|
||||
}
|
||||
}
|
||||
if(event == null) {
|
||||
if (event == null) {
|
||||
try {
|
||||
Connection con = DatabaseConnection.getConnection();
|
||||
try (PreparedStatement ps = con.prepareStatement("SELECT * FROM playernpcs WHERE map = ? AND world = ?")) {
|
||||
@@ -288,23 +298,47 @@ public class MapleMapFactory {
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
List<MaplePlayerNPC> dnpcs = MaplePlayerNPCFactory.getDeveloperNpcsFromMapid(mapid);
|
||||
if(dnpcs != null) {
|
||||
for(MaplePlayerNPC dnpc : dnpcs) {
|
||||
if (dnpcs != null) {
|
||||
for (MaplePlayerNPC dnpc : dnpcs) {
|
||||
map.addPlayerNPCMapObject(dnpc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
loadLifeFromWz(map, mapData);
|
||||
loadLifeFromDb(map);
|
||||
|
||||
|
||||
if (map.isCPQMap()) {
|
||||
MapleData mcData = mapData.getChildByPath("monsterCarnival");
|
||||
if (mcData != null) {
|
||||
MapleData guardianGenData = mcData.getChildByPath("guardianGenPos");
|
||||
for (MapleData node : guardianGenData.getChildren()) {
|
||||
GuardianSpawnPoint pt = new GuardianSpawnPoint(new Point(MapleDataTool.getIntConvert("x", node), MapleDataTool.getIntConvert("y", node)));
|
||||
pt.setTeam(MapleDataTool.getIntConvert("team", node, -1));
|
||||
pt.setTaken(false);
|
||||
map.addGuardianSpawnPoint(pt);
|
||||
}
|
||||
}
|
||||
if (mcData.getChildByPath("skill") != null) {
|
||||
for (MapleData area : mcData.getChildByPath("skill")) {
|
||||
map.addSkillId(MapleDataTool.getInt(area));
|
||||
}
|
||||
}
|
||||
|
||||
if (mcData.getChildByPath("mob") != null) {
|
||||
for (MapleData area : mcData.getChildByPath("mob")) {
|
||||
map.addMobSpawn(MapleDataTool.getInt(area.getChildByPath("id")), MapleDataTool.getInt(area.getChildByPath("spendCP")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mapData.getChildByPath("reactor") != null) {
|
||||
for (MapleData reactor : mapData.getChildByPath("reactor")) {
|
||||
String id = MapleDataTool.getString(reactor.getChildByPath("id"));
|
||||
if (id != null) {
|
||||
MapleReactor newReactor = loadReactor(reactor, id);
|
||||
MapleReactor newReactor = loadReactor(reactor, id, (byte) MapleDataTool.getInt(reactor.getChildByPath("f"), 0));
|
||||
map.spawnReactor(newReactor);
|
||||
}
|
||||
}
|
||||
@@ -313,7 +347,7 @@ public class MapleMapFactory {
|
||||
map.setMapName(MapleDataTool.getString("mapName", nameData.getChildByPath(getMapStringName(omapid)), ""));
|
||||
map.setStreetName(MapleDataTool.getString("streetName", nameData.getChildByPath(getMapStringName(omapid)), ""));
|
||||
} catch (Exception e) {
|
||||
if(omapid / 1000 != 1020) { // explorer job introducion scenes
|
||||
if (omapid / 1000 != 1020) { // explorer job introducion scenes
|
||||
e.printStackTrace();
|
||||
System.err.println("Not found mapid " + omapid);
|
||||
}
|
||||
@@ -332,13 +366,13 @@ public class MapleMapFactory {
|
||||
map.setTimeLimit(MapleDataTool.getIntConvert("timeLimit", infoData, -1));
|
||||
map.setFieldType(MapleDataTool.getIntConvert("fieldType", infoData, 0));
|
||||
map.setMobCapacity(MapleDataTool.getIntConvert("fixedMobCapacity", infoData, 500));//Is there a map that contains more than 500 mobs?
|
||||
|
||||
|
||||
MapleData recData = infoData.getChildByPath("recovery");
|
||||
if(recData != null) {
|
||||
if (recData != null) {
|
||||
float recoveryRate = MapleDataTool.getFloat(recData);
|
||||
mapRecoveryRate.put(mapid, recoveryRate);
|
||||
}
|
||||
|
||||
|
||||
HashMap<Integer, Integer> backTypes = new HashMap<>();
|
||||
try {
|
||||
for (MapleData layer : mapData.getChildByPath("back")) { // yolo
|
||||
@@ -351,7 +385,7 @@ public class MapleMapFactory {
|
||||
e.printStackTrace();
|
||||
// swallow cause I'm cool
|
||||
}
|
||||
|
||||
|
||||
map.setBackgroundTypes(backTypes);
|
||||
map.generateMapDropRangeCache();
|
||||
|
||||
@@ -361,21 +395,21 @@ public class MapleMapFactory {
|
||||
} finally {
|
||||
mapsWLock.unlock();
|
||||
}
|
||||
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
public MapleMap getMap(int mapid) {
|
||||
Integer omapid = Integer.valueOf(mapid);
|
||||
MapleMap map;
|
||||
|
||||
|
||||
mapsRLock.lock();
|
||||
try {
|
||||
map = maps.get(omapid);
|
||||
} finally {
|
||||
mapsRLock.unlock();
|
||||
}
|
||||
|
||||
|
||||
return (map != null) ? map : loadMapFromWz(mapid, omapid);
|
||||
}
|
||||
|
||||
@@ -387,7 +421,7 @@ public class MapleMapFactory {
|
||||
mapsRLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private AbstractLoadedMapleLife loadLife(int id, String type, int cy, int f, int fh, int rx0, int rx1, int x, int y, int hide) {
|
||||
AbstractLoadedMapleLife myLife = MapleLifeFactory.getLife(id, type);
|
||||
myLife.setCy(cy);
|
||||
@@ -402,10 +436,11 @@ public class MapleMapFactory {
|
||||
return myLife;
|
||||
}
|
||||
|
||||
private MapleReactor loadReactor(MapleData reactor, String id) {
|
||||
private MapleReactor loadReactor(MapleData reactor, String id, final byte FacingDirection) {
|
||||
MapleReactor myReactor = new MapleReactor(MapleReactorFactory.getReactor(Integer.parseInt(id)), Integer.parseInt(id));
|
||||
int x = MapleDataTool.getInt(reactor.getChildByPath("x"));
|
||||
int y = MapleDataTool.getInt(reactor.getChildByPath("y"));
|
||||
myReactor.setFacingDirection(FacingDirection);
|
||||
myReactor.setPosition(new Point(x, y));
|
||||
myReactor.setDelay(MapleDataTool.getInt(reactor.getChildByPath("reactorTime")) * 1000);
|
||||
myReactor.setName(MapleDataTool.getString(reactor.getChildByPath("name"), ""));
|
||||
@@ -442,7 +477,7 @@ public class MapleMapFactory {
|
||||
} else if (mapid >= 677000000 && mapid < 677100000) {
|
||||
builder.append("Episode1GL");
|
||||
} else if (mapid >= 670000000 && mapid < 682000000) {
|
||||
if((mapid >= 674030000 && mapid < 674040000) || (mapid >= 680100000 && mapid < 680200000)) {
|
||||
if ((mapid >= 674030000 && mapid < 674040000) || (mapid >= 680100000 && mapid < 680200000)) {
|
||||
builder.append("etc");
|
||||
} else {
|
||||
builder.append("weddingGL");
|
||||
@@ -452,7 +487,7 @@ public class MapleMapFactory {
|
||||
} else if (mapid >= 683000000 && mapid < 684000000) {
|
||||
builder.append("event");
|
||||
} else if (mapid >= 800000000 && mapid < 900000000) {
|
||||
if((mapid >= 889100000 && mapid < 889200000)) {
|
||||
if ((mapid >= 889100000 && mapid < 889200000)) {
|
||||
builder.append("etc");
|
||||
} else {
|
||||
builder.append("jp");
|
||||
@@ -480,17 +515,17 @@ public class MapleMapFactory {
|
||||
mapsRLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void dispose() {
|
||||
Collection<MapleMap> mapValues = getMaps().values();
|
||||
|
||||
for(MapleMap map: mapValues) {
|
||||
|
||||
for (MapleMap map : mapValues) {
|
||||
map.dispose();
|
||||
}
|
||||
|
||||
|
||||
this.event = null;
|
||||
}
|
||||
|
||||
|
||||
public static float getMapRecoveryRate(int mapid) {
|
||||
Float recRate = mapRecoveryRate.get(mapid);
|
||||
return recRate != null ? recRate : 1.0f;
|
||||
|
||||
@@ -1,27 +1,28 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <[email protected]>
|
||||
Matthias Butz <[email protected]>
|
||||
Jan Christian Meyer <[email protected]>
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <[email protected]>
|
||||
Matthias Butz <[email protected]>
|
||||
Jan Christian Meyer <[email protected]>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package server.maps;
|
||||
|
||||
import client.MapleClient;
|
||||
import client.status.MonsterStatus;
|
||||
import constants.ServerConstants;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
@@ -36,6 +37,7 @@ import server.TimerManager;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.Pair;
|
||||
import net.server.audit.locks.MonitoredLockType;
|
||||
import server.partyquest.GuardianSpawnPoint;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -43,6 +45,7 @@ import net.server.audit.locks.MonitoredLockType;
|
||||
* @author Ronan
|
||||
*/
|
||||
public class MapleReactor extends AbstractMapleMapObject {
|
||||
|
||||
private int rid;
|
||||
private MapleReactorStats stats;
|
||||
private byte state;
|
||||
@@ -54,28 +57,30 @@ public class MapleReactor extends AbstractMapleMapObject {
|
||||
private boolean shouldCollect;
|
||||
private boolean attackHit;
|
||||
private ScheduledFuture<?> timeoutTask = null;
|
||||
private GuardianSpawnPoint guardian = null;
|
||||
private byte facingDirection = 0;
|
||||
private Lock reactorLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.REACTOR, true);
|
||||
private Lock hitLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.REACTOR_HIT, true);
|
||||
|
||||
public MapleReactor(MapleReactorStats stats, int rid) {
|
||||
this.evstate = (byte)0;
|
||||
this.evstate = (byte) 0;
|
||||
this.stats = stats;
|
||||
this.rid = rid;
|
||||
this.alive = true;
|
||||
}
|
||||
|
||||
|
||||
public void setShouldCollect(boolean collect) {
|
||||
this.shouldCollect = collect;
|
||||
}
|
||||
|
||||
|
||||
public boolean getShouldCollect() {
|
||||
return shouldCollect;
|
||||
}
|
||||
|
||||
|
||||
public void lockReactor() {
|
||||
reactorLock.lock();
|
||||
}
|
||||
|
||||
|
||||
public void unlockReactor() {
|
||||
reactorLock.unlock();
|
||||
}
|
||||
@@ -83,19 +88,19 @@ public class MapleReactor extends AbstractMapleMapObject {
|
||||
public void setState(byte state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
|
||||
public byte getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
public void setEventState(byte substate) {
|
||||
this.evstate = substate;
|
||||
}
|
||||
|
||||
|
||||
public byte getEventState() {
|
||||
return evstate;
|
||||
}
|
||||
|
||||
|
||||
public MapleReactorStats getStats() {
|
||||
return stats;
|
||||
}
|
||||
@@ -120,7 +125,7 @@ public class MapleReactor extends AbstractMapleMapObject {
|
||||
public int getReactorType() {
|
||||
return stats.getType(state);
|
||||
}
|
||||
|
||||
|
||||
public boolean isRecentHitFromAttack() {
|
||||
return attackHit;
|
||||
}
|
||||
@@ -140,7 +145,7 @@ public class MapleReactor extends AbstractMapleMapObject {
|
||||
public boolean isAlive() {
|
||||
return alive;
|
||||
}
|
||||
|
||||
|
||||
public boolean isActive() {
|
||||
return alive && stats.getType(state) != -1;
|
||||
}
|
||||
@@ -172,10 +177,12 @@ public class MapleReactor extends AbstractMapleMapObject {
|
||||
cancelReactorTimeout();
|
||||
setShouldCollect(true);
|
||||
refreshReactorTimeout();
|
||||
|
||||
if(map != null) map.searchItemReactors(this);
|
||||
|
||||
if (map != null) {
|
||||
map.searchItemReactors(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void forceHitReactor(final byte newState) {
|
||||
this.lockReactor();
|
||||
try {
|
||||
@@ -185,10 +192,12 @@ public class MapleReactor extends AbstractMapleMapObject {
|
||||
this.unlockReactor();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void tryForceHitReactor(final byte newState) { // weak hit state signal, if already changed reactor state before timeout then drop this
|
||||
if(!this.reactorLock.tryLock()) return;
|
||||
|
||||
if (!this.reactorLock.tryLock()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this.resetReactorActions(newState);
|
||||
map.broadcastMessage(MaplePacketCreator.triggerReactor(this, (short) 0));
|
||||
@@ -196,19 +205,19 @@ public class MapleReactor extends AbstractMapleMapObject {
|
||||
this.reactorLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void cancelReactorTimeout() {
|
||||
if (timeoutTask != null) {
|
||||
timeoutTask.cancel(false);
|
||||
timeoutTask = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void refreshReactorTimeout() {
|
||||
int timeOut = stats.getTimeout(state);
|
||||
if(timeOut > -1) {
|
||||
if (timeOut > -1) {
|
||||
final byte nextState = stats.getTimeoutState(state);
|
||||
|
||||
|
||||
timeoutTask = TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -218,7 +227,7 @@ public class MapleReactor extends AbstractMapleMapObject {
|
||||
}, timeOut);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void delayedHitReactor(final MapleClient c, long delay) {
|
||||
TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
@@ -231,20 +240,22 @@ public class MapleReactor extends AbstractMapleMapObject {
|
||||
public void hitReactor(MapleClient c) {
|
||||
hitReactor(false, 0, (short) 0, 0, c);
|
||||
}
|
||||
|
||||
|
||||
public void hitReactor(boolean wHit, int charPos, short stance, int skillid, MapleClient c) {
|
||||
try {
|
||||
if(!this.isActive()) {
|
||||
if (!this.isActive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(hitLock.tryLock()) {
|
||||
|
||||
if (hitLock.tryLock()) {
|
||||
this.lockReactor();
|
||||
try {
|
||||
cancelReactorTimeout();
|
||||
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));
|
||||
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);
|
||||
|
||||
int reactorType = stats.getType(state);
|
||||
@@ -253,7 +264,9 @@ public class MapleReactor extends AbstractMapleMapObject {
|
||||
for (byte b = 0; b < stats.getStateSize(state); b++) {//YAY?
|
||||
List<Integer> activeSkills = stats.getActiveSkills(state, b);
|
||||
if (activeSkills != null) {
|
||||
if (!activeSkills.contains(skillid)) continue;
|
||||
if (!activeSkills.contains(skillid)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
state = stats.getNextState(state, b);
|
||||
if (stats.getNextState(state, b) == -1) {//end of reactor
|
||||
@@ -276,7 +289,7 @@ public class MapleReactor extends AbstractMapleMapObject {
|
||||
|
||||
setShouldCollect(true); // refresh collectability on item drop-based reactors
|
||||
refreshReactorTimeout();
|
||||
if(stats.getType(state) == 100) {
|
||||
if (stats.getType(state) == 100) {
|
||||
map.searchItemReactors(this);
|
||||
}
|
||||
}
|
||||
@@ -286,21 +299,23 @@ public class MapleReactor extends AbstractMapleMapObject {
|
||||
} else {
|
||||
state++;
|
||||
map.broadcastMessage(MaplePacketCreator.triggerReactor(this, stance));
|
||||
ReactorScriptManager.getInstance().act(c, this);
|
||||
if (this.getId() != 9980000 && this.getId() != 9980001) {
|
||||
ReactorScriptManager.getInstance().act(c, this);
|
||||
}
|
||||
|
||||
setShouldCollect(true);
|
||||
refreshReactorTimeout();
|
||||
if(stats.getType(state) == 100) {
|
||||
if (stats.getType(state) == 100) {
|
||||
map.searchItemReactors(this);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
this.unlockReactor();
|
||||
}
|
||||
|
||||
|
||||
hitLock.unlock();
|
||||
}
|
||||
} catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
@@ -316,4 +331,20 @@ public class MapleReactor extends AbstractMapleMapObject {
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public GuardianSpawnPoint getGuardian() {
|
||||
return guardian;
|
||||
}
|
||||
|
||||
public void setGuardian(GuardianSpawnPoint guardian) {
|
||||
this.guardian = guardian;
|
||||
}
|
||||
|
||||
public final void setFacingDirection(final byte facingDirection) {
|
||||
this.facingDirection = facingDirection;
|
||||
}
|
||||
|
||||
public final byte getFacingDirection() {
|
||||
return facingDirection;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,61 @@ public class MapleReactorFactory {
|
||||
private static MapleDataProvider data = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Reactor.wz"));
|
||||
private static Map<Integer, MapleReactorStats> reactorStats = new HashMap<Integer, MapleReactorStats>();
|
||||
|
||||
|
||||
public static final MapleReactorStats getReactorS(int rid) {
|
||||
MapleReactorStats stats = reactorStats.get(Integer.valueOf(rid));
|
||||
if (stats == null) {
|
||||
int infoId = rid;
|
||||
MapleData reactorData = data.getData(StringUtil.getLeftPaddedStr(Integer.toString(infoId) + ".img", '0', 11));
|
||||
MapleData link = reactorData.getChildByPath("info/link");
|
||||
if (link != null) {
|
||||
infoId = MapleDataTool.getIntConvert("info/link", reactorData);
|
||||
stats = reactorStats.get(Integer.valueOf(infoId));
|
||||
}
|
||||
if (stats == null) {
|
||||
stats = new MapleReactorStats();
|
||||
reactorData = data.getData(StringUtil.getLeftPaddedStr(Integer.toString(infoId) + ".img", '0', 11));
|
||||
if (reactorData == null) {
|
||||
return stats;
|
||||
}
|
||||
boolean canTouch = MapleDataTool.getInt("info/activateByTouch", reactorData, 0) > 0;
|
||||
boolean areaSet = false;
|
||||
boolean foundState = false;
|
||||
for (byte i = 0; true; i++) {
|
||||
MapleData reactorD = reactorData.getChildByPath(String.valueOf(i));
|
||||
if (reactorD == null) {
|
||||
break;
|
||||
}
|
||||
MapleData reactorInfoData_ = reactorD.getChildByPath("event");
|
||||
if (reactorInfoData_ != null && reactorInfoData_.getChildByPath("0") != null) {
|
||||
MapleData reactorInfoData = reactorInfoData_.getChildByPath("0");
|
||||
Pair<Integer, Integer> reactItem = null;
|
||||
int type = MapleDataTool.getIntConvert("type", reactorInfoData);
|
||||
if (type == 100) { //reactor waits for item
|
||||
reactItem = new Pair<Integer, Integer>(MapleDataTool.getIntConvert("0", reactorInfoData), MapleDataTool.getIntConvert("1", reactorInfoData, 1));
|
||||
if (!areaSet) { //only set area of effect for item-triggered reactors once
|
||||
stats.setTL(MapleDataTool.getPoint("lt", reactorInfoData));
|
||||
stats.setBR(MapleDataTool.getPoint("rb", reactorInfoData));
|
||||
areaSet = true;
|
||||
}
|
||||
}
|
||||
foundState = true;
|
||||
stats.addState(i, type, reactItem, (byte) MapleDataTool.getIntConvert("state", reactorInfoData), MapleDataTool.getIntConvert("timeOut", reactorInfoData_, -1), (byte) (canTouch ? 2 : (MapleDataTool.getIntConvert("2", reactorInfoData, 0) > 0 || reactorInfoData.getChildByPath("clickArea") != null || type == 9 ? 1 : 0)));
|
||||
} else {
|
||||
stats.addState(i, 999, null, (byte) (foundState ? -1 : (i + 1)), 0, (byte) 0);
|
||||
}
|
||||
}
|
||||
reactorStats.put(Integer.valueOf(infoId), stats);
|
||||
if (rid != infoId) {
|
||||
reactorStats.put(Integer.valueOf(rid), stats);
|
||||
}
|
||||
} else { // stats exist at infoId but not rid; add to map
|
||||
reactorStats.put(Integer.valueOf(rid), stats);
|
||||
}
|
||||
}
|
||||
return stats;
|
||||
}
|
||||
|
||||
public static MapleReactorStats getReactor(int rid) {
|
||||
MapleReactorStats stats = reactorStats.get(Integer.valueOf(rid));
|
||||
if (stats == null) {
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
package server.maps;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -58,6 +59,12 @@ public class MapleReactorStats {
|
||||
if(timeOut > -1) timeoutInfo.put(state, timeOut);
|
||||
}
|
||||
|
||||
public void addState(byte state, int type, Pair<Integer, Integer> reactItem, byte nextState, int timeOut, byte canTouch) {
|
||||
List<StateData> data = new ArrayList<>();
|
||||
data.add(new StateData(type, reactItem, null, nextState));
|
||||
stateInfo.put(state, data);
|
||||
}
|
||||
|
||||
public int getTimeout(byte state) {
|
||||
Integer i = timeoutInfo.get(state);
|
||||
return (i == null) ? -1 : i;
|
||||
|
||||
@@ -31,6 +31,7 @@ public enum SavedLocationType {
|
||||
EVENT,
|
||||
BOSSPQ,
|
||||
HAPPYVILLE,
|
||||
MONSTER_CARNIVAL,
|
||||
DEVELOPER;
|
||||
|
||||
public static SavedLocationType fromString(String Str) {
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package server.partyquest;
|
||||
|
||||
import java.awt.Point;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author David
|
||||
*/
|
||||
public class GuardianSpawnPoint {
|
||||
|
||||
private Point position;
|
||||
private boolean taken;
|
||||
private int team = -1;
|
||||
|
||||
public GuardianSpawnPoint(Point a) {
|
||||
this.position = a;
|
||||
this.taken = true;
|
||||
}
|
||||
|
||||
public Point getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public void setPosition(Point position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public boolean isTaken() {
|
||||
return taken;
|
||||
}
|
||||
|
||||
public void setTaken(boolean taken) {
|
||||
this.taken = taken;
|
||||
}
|
||||
|
||||
public int getTeam() {
|
||||
return team;
|
||||
}
|
||||
|
||||
public void setTeam(int team) {
|
||||
this.team = team;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package server.partyquest;
|
||||
|
||||
import client.MapleDisease;
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import server.life.MobSkillFactory;
|
||||
import provider.MapleDataProvider;
|
||||
import provider.MapleDataProviderFactory;
|
||||
import provider.MapleData;
|
||||
import provider.MapleDataTool;
|
||||
import server.life.MobSkill;
|
||||
|
||||
/**
|
||||
*@author Drago/Dragohe4rt
|
||||
*/
|
||||
public class MapleCarnivalFactory {
|
||||
|
||||
private final static MapleCarnivalFactory instance = new MapleCarnivalFactory();
|
||||
private final Map<Integer, MCSkill> skills = new HashMap<Integer, MCSkill>();
|
||||
private final Map<Integer, MCSkill> guardians = new HashMap<Integer, MCSkill>();
|
||||
private final MapleDataProvider dataRoot = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Skill.wz"));
|
||||
|
||||
public MapleCarnivalFactory() {
|
||||
//whoosh
|
||||
initialize();
|
||||
}
|
||||
|
||||
public static final MapleCarnivalFactory getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
if (skills.size() != 0) {
|
||||
return;
|
||||
}
|
||||
for (MapleData z : dataRoot.getData("MCSkill.img")) {
|
||||
skills.put(Integer.parseInt(z.getName()), new MCSkill(MapleDataTool.getInt("spendCP", z, 0), MapleDataTool.getInt("mobSkillID", z, 0), MapleDataTool.getInt("level", z, 0), MapleDataTool.getInt("target", z, 1) > 1));
|
||||
}
|
||||
for (MapleData z : dataRoot.getData("MCGuardian.img")) {
|
||||
guardians.put(Integer.parseInt(z.getName()), new MCSkill(MapleDataTool.getInt("spendCP", z, 0), MapleDataTool.getInt("mobSkillID", z, 0), MapleDataTool.getInt("level", z, 0), true));
|
||||
}
|
||||
}
|
||||
|
||||
public MCSkill getSkill(final int id) {
|
||||
return skills.get(id);
|
||||
}
|
||||
|
||||
public MCSkill getGuardian(final int id) {
|
||||
return guardians.get(id);
|
||||
}
|
||||
|
||||
public static class MCSkill {
|
||||
|
||||
public int cpLoss, skillid, level;
|
||||
public boolean targetsAll;
|
||||
|
||||
public MCSkill(int _cpLoss, int _skillid, int _level, boolean _targetsAll) {
|
||||
cpLoss = _cpLoss;
|
||||
skillid = _skillid;
|
||||
level = _level;
|
||||
targetsAll = _targetsAll;
|
||||
}
|
||||
|
||||
public MobSkill getSkill() {
|
||||
return MobSkillFactory.getMobSkill(skillid, 1); //level?
|
||||
}
|
||||
|
||||
public MapleDisease getDisease() {
|
||||
if (skillid <= 0) {
|
||||
return MapleDisease.getRandom();
|
||||
}
|
||||
return MapleDisease.getBySkill(skillid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,174 +1,489 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <[email protected]>
|
||||
Matthias Butz <[email protected]>
|
||||
Jan Christian Meyer <[email protected]>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package server.partyquest;
|
||||
|
||||
import client.MapleCharacter;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import client.MapleCharacter;
|
||||
import constants.LinguaConstants;
|
||||
import net.server.Server;
|
||||
import net.server.channel.Channel;
|
||||
import net.server.world.MapleParty;
|
||||
import net.server.world.MaplePartyCharacter;
|
||||
import server.TimerManager;
|
||||
import server.maps.MapleMap;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.MaplePacketCreator;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author kevintjuh93 - LOST MOTIVATION >=(
|
||||
* @author Drago/Dragohe4rt
|
||||
*/
|
||||
|
||||
public class MonsterCarnival {
|
||||
private MonsterCarnivalParty red, blue;
|
||||
|
||||
public static int D = 3;
|
||||
public static int C = 2;
|
||||
public static int B = 1;
|
||||
public static int A = 0;
|
||||
|
||||
private MapleParty p1, p2;
|
||||
private MapleMap map;
|
||||
private int room;
|
||||
private long time = 0;
|
||||
private long timeStarted = 0;
|
||||
private ScheduledFuture<?> schedule = null;
|
||||
private ScheduledFuture<?> timer, effectTimer;
|
||||
private long startTime = 0;
|
||||
private int summons = 8, summonss = 8;
|
||||
private MapleCharacter leader1, leader2, Grupo1, Grupo2;
|
||||
private int redCP, blueCP, redTotalCP, blueTotalCP;
|
||||
private boolean cpq1;
|
||||
|
||||
public MonsterCarnival(int room, byte channel, MonsterCarnivalParty red1, MonsterCarnivalParty blue1) {
|
||||
//this.map = Channel.getInstance(channel).getMapFactory().getMap(980000001 + (room * 100));
|
||||
this.room = room;
|
||||
this.red = red1;
|
||||
this.blue = blue1;
|
||||
this.timeStarted = System.currentTimeMillis();
|
||||
this.time = 600000;
|
||||
map.broadcastMessage(MaplePacketCreator.getClock((int) (time / 1000)));
|
||||
|
||||
for (MapleCharacter chr : red.getMembers())
|
||||
chr.setCarnival(this);
|
||||
for (MapleCharacter chr : blue.getMembers())
|
||||
chr.setCarnival(this);
|
||||
|
||||
this.schedule = TimerManager.getInstance().schedule(new Runnable() {
|
||||
public MonsterCarnival(MapleParty p1, MapleParty p2, int mapid, boolean cpq1) {
|
||||
try {
|
||||
this.cpq1 = cpq1;
|
||||
this.p1 = p1;
|
||||
this.p2 = p2;
|
||||
Channel cs = Server.getInstance().getWorld(p2.getLeader().getWorld()).getChannel(p2.getLeader().getChannel());
|
||||
p1.setEnemy(p2);
|
||||
p2.setEnemy(p1);
|
||||
map = cs.getMapFactory().resetMap(mapid);
|
||||
int redPortal = 0;
|
||||
int bluePortal = 0;
|
||||
if (map.isPurpleCPQMap()) {
|
||||
redPortal = 2;
|
||||
bluePortal = 1;
|
||||
}
|
||||
for (MaplePartyCharacter mpc : p1.getMembers()) {
|
||||
MapleCharacter mc = cs.getPlayerStorage().getCharacterByName(mpc.getName());
|
||||
if (mc != null) {
|
||||
mc.setMonsterCarnival(this);
|
||||
mc.setTeam(0);
|
||||
mc.setFestivalPoints(0);
|
||||
mc.changeMap(map, map.getPortal(redPortal));
|
||||
mc.dropMessage(6, LinguaConstants.Linguas(mc).CPQEntrada);
|
||||
if (p1.getLeader().getId() == mc.getId()) {
|
||||
leader1 = mc;
|
||||
}
|
||||
Grupo1 = mc;
|
||||
}
|
||||
}
|
||||
for (MaplePartyCharacter mpc : p2.getMembers()) {
|
||||
MapleCharacter mc = cs.getPlayerStorage().getCharacterByName(mpc.getName());
|
||||
if (mc != null) {
|
||||
mc.setMonsterCarnival(this);
|
||||
mc.setTeam(1);
|
||||
mc.setFestivalPoints(0);
|
||||
mc.changeMap(map, map.getPortal(bluePortal));
|
||||
mc.dropMessage(6, LinguaConstants.Linguas(mc).CPQEntrada);
|
||||
if (p2.getLeader().getId() == mc.getId()) {
|
||||
leader2 = mc;
|
||||
}
|
||||
Grupo2 = mc;
|
||||
}
|
||||
}
|
||||
if (Grupo1 == null || Grupo2 == null) {
|
||||
for (MaplePartyCharacter mpc : p2.getMembers()) {
|
||||
mpc.getPlayer().dropMessage(5, LinguaConstants.Linguas(mpc.getPlayer()).CPQErro);
|
||||
}
|
||||
for (MaplePartyCharacter mpc : p2.getMembers()) {
|
||||
mpc.getPlayer().dropMessage(5, LinguaConstants.Linguas(mpc.getPlayer()).CPQErro);
|
||||
}
|
||||
return;
|
||||
}
|
||||
Grupo1.getClient().announce(MaplePacketCreator.startMonsterCarnival(Grupo1, 0, 1));
|
||||
Grupo2.getClient().announce(MaplePacketCreator.startMonsterCarnival(Grupo2, 1, 0));
|
||||
startTime = System.currentTimeMillis() + 60 * 10000;
|
||||
timer = TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (red.getTotalCP() > blue.getTotalCP()) {
|
||||
red.setWinner(true);
|
||||
blue.setWinner(false);
|
||||
red.displayMatchResult();
|
||||
blue.displayMatchResult();
|
||||
} else if (blue.getTotalCP() > red.getTotalCP()) {
|
||||
red.setWinner(false);
|
||||
blue.setWinner(true);
|
||||
red.displayMatchResult();
|
||||
blue.displayMatchResult();
|
||||
} else {
|
||||
red.setWinner(false);
|
||||
blue.setWinner(false);
|
||||
red.displayMatchResult();
|
||||
blue.displayMatchResult();
|
||||
}
|
||||
saveResults();
|
||||
warpOut();
|
||||
timeUp();
|
||||
}
|
||||
|
||||
}, time);
|
||||
/* if (room == 0) {
|
||||
MapleData data = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Map.wz")).getData("Map/Map9" + (980000001 + (room * 100)) + ".img").getChildByPath("monsterCarnival");
|
||||
if (data != null) {
|
||||
for (MapleData p : data.getChildByPath("mobGenPos").getChildren()) {
|
||||
MapleData team = p.getChildByPath("team");
|
||||
if (team != null) {
|
||||
if (team.getData().equals(0))
|
||||
redmonsterpoints.add(new Point(MapleDataTool.getInt(p.getChildByPath("x")), MapleDataTool.getInt(p.getChildByPath("y"))));
|
||||
else
|
||||
bluemonsterpoints.add(new Point(MapleDataTool.getInt(p.getChildByPath("x")), MapleDataTool.getInt(p.getChildByPath("y"))));
|
||||
} else
|
||||
monsterpoints.add(new Point(MapleDataTool.getInt(p.getChildByPath("x")), MapleDataTool.getInt(p.getChildByPath("y"))));
|
||||
}
|
||||
for (MapleData p : data.getChildByPath("guardianGenPos").getChildren()) {
|
||||
MapleData team = p.getChildByPath("team");
|
||||
if (team != null) {
|
||||
if (team.getData().equals(0))
|
||||
redreactorpoints.add(new Point(MapleDataTool.getInt(p.getChildByPath("x")), MapleDataTool.getInt(p.getChildByPath("y"))));
|
||||
else
|
||||
bluereactorpoints.add(new Point(MapleDataTool.getInt(p.getChildByPath("x")), MapleDataTool.getInt(p.getChildByPath("y"))));
|
||||
} else
|
||||
reactorpoints.add(new Point(MapleDataTool.getInt(p.getChildByPath("x")), MapleDataTool.getInt(p.getChildByPath("y"))));
|
||||
}
|
||||
}
|
||||
} */
|
||||
}
|
||||
|
||||
public long getTimeLeft() {
|
||||
return time - (System.currentTimeMillis() - timeStarted);
|
||||
}
|
||||
|
||||
public MonsterCarnivalParty getPartyRed() {
|
||||
return red;
|
||||
}
|
||||
|
||||
public MonsterCarnivalParty getPartyBlue() {
|
||||
return blue;
|
||||
}
|
||||
|
||||
public MonsterCarnivalParty oppositeTeam(MonsterCarnivalParty team) {
|
||||
if (team == red)
|
||||
return blue;
|
||||
else
|
||||
return red;
|
||||
}
|
||||
|
||||
public void playerLeft(MapleCharacter chr) {
|
||||
map.broadcastMessage(chr, MaplePacketCreator.leaveCPQ(chr));
|
||||
}
|
||||
|
||||
private void warpOut() {
|
||||
this.schedule = TimerManager.getInstance().schedule(new Runnable() {
|
||||
}, 10 * 60 * 1000);
|
||||
effectTimer = TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
red.warpOut();
|
||||
blue.warpOut();
|
||||
complete();
|
||||
}
|
||||
}, 12000);
|
||||
}, 10 * 60 * 1000 - 10 * 1000);
|
||||
TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
map.addClock(60 * 10);
|
||||
}
|
||||
}, 2000);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void playerDisconnected(int charid) {
|
||||
int team = -1;
|
||||
for (MaplePartyCharacter mpc : leader1.getParty().getMembers()) {
|
||||
if (mpc.getId() == charid) {
|
||||
team = 0;
|
||||
}
|
||||
}
|
||||
for (MaplePartyCharacter mpc : leader2.getParty().getMembers()) {
|
||||
if (mpc.getId() == charid) {
|
||||
team = 1;
|
||||
}
|
||||
}
|
||||
for (MapleCharacter chrMap : map.getAllPlayers()) {
|
||||
if (team == -1) {
|
||||
team = 1;
|
||||
}
|
||||
String teamS = "";
|
||||
switch (team) {
|
||||
case 0:
|
||||
teamS = LinguaConstants.Linguas(chrMap).CPQVermelho;
|
||||
break;
|
||||
case 1:
|
||||
teamS = LinguaConstants.Linguas(chrMap).CPQAzul;
|
||||
break;
|
||||
}
|
||||
chrMap.dropMessage(5, teamS + LinguaConstants.Linguas(chrMap).CPQPlayerExit);
|
||||
}
|
||||
earlyFinish();
|
||||
}
|
||||
|
||||
public void earlyFinish() {
|
||||
dispose(true);
|
||||
}
|
||||
|
||||
public void leftParty(int charid) {
|
||||
playerDisconnected(charid);
|
||||
}
|
||||
|
||||
protected void dispose() {
|
||||
dispose(false);
|
||||
}
|
||||
|
||||
public void summon() {
|
||||
this.summons--;
|
||||
}
|
||||
|
||||
public boolean canSummon() {
|
||||
return this.summons > 0;
|
||||
}
|
||||
|
||||
public void summons() {
|
||||
this.summonss--;
|
||||
}
|
||||
|
||||
public boolean canSummons() {
|
||||
return this.summonss > 0;
|
||||
}
|
||||
|
||||
protected void dispose(boolean warpout) {
|
||||
Channel cs = Server.getInstance().getWorld(p1.getLeader().getWorld()).getChannel(p1.getLeader().getChannel());
|
||||
MapleMap out;
|
||||
if (!cpq1) { // cpq2
|
||||
out = cs.getMapFactory().getMap(980030000);
|
||||
} else {
|
||||
out = cs.getMapFactory().getMap(980000000);
|
||||
}
|
||||
for (MaplePartyCharacter mpc : leader1.getParty().getMembers()) {
|
||||
MapleCharacter mc = cs.getPlayerStorage().getCharacterByName(mpc.getName());
|
||||
if (mc != null) {
|
||||
mc.resetCP();
|
||||
mc.setTeam(-1);
|
||||
mc.setMonsterCarnival(null);
|
||||
if (warpout) {
|
||||
mc.changeMap(out, out.getPortal(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (MaplePartyCharacter mpc : leader2.getParty().getMembers()) {
|
||||
MapleCharacter mc = cs.getPlayerStorage().getCharacterByName(mpc.getName());
|
||||
if (mc != null) {
|
||||
mc.resetCP();
|
||||
mc.setTeam(-1);
|
||||
mc.setMonsterCarnival(null);
|
||||
if (warpout) {
|
||||
mc.changeMap(out, out.getPortal(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.timer != null) {
|
||||
this.timer.cancel(true);
|
||||
this.timer = null;
|
||||
}
|
||||
if (this.effectTimer != null) {
|
||||
this.effectTimer.cancel(true);
|
||||
this.effectTimer = null;
|
||||
}
|
||||
redTotalCP = 0;
|
||||
blueTotalCP = 0;
|
||||
leader1.getParty().setEnemy(null);
|
||||
leader2.getParty().setEnemy(null);
|
||||
|
||||
}
|
||||
|
||||
public void exit() {
|
||||
dispose();
|
||||
}
|
||||
|
||||
public ScheduledFuture<?> getTimer() {
|
||||
return this.timer;
|
||||
}
|
||||
|
||||
public void finish(int winningTeam) {
|
||||
try {
|
||||
Channel cs = Server.getInstance().getWorld(p1.getLeader().getWorld()).getChannel(p1.getLeader().getChannel());
|
||||
if (winningTeam == 0) {
|
||||
for (MaplePartyCharacter mpc : leader1.getParty().getMembers()) {
|
||||
MapleCharacter mc = cs.getPlayerStorage().getCharacterByName(mpc.getName());
|
||||
if (mc != null) {
|
||||
mc.gainFestivalPoints(this.redTotalCP);
|
||||
mc.setMonsterCarnival(null);
|
||||
if (cpq1) {
|
||||
mc.changeMap(cs.getMapFactory().getMap(map.getId() + 2), cs.getMapFactory().getMap(map.getId() + 2).getPortal(0));
|
||||
} else {
|
||||
mc.changeMap(cs.getMapFactory().getMap(map.getId() + 200), cs.getMapFactory().getMap(map.getId() + 200).getPortal(0));
|
||||
}
|
||||
mc.setTeam(-1);
|
||||
mc.dispelDebuffs();
|
||||
}
|
||||
}
|
||||
for (MaplePartyCharacter mpc : leader2.getParty().getMembers()) {
|
||||
MapleCharacter mc = cs.getPlayerStorage().getCharacterByName(mpc.getName());
|
||||
if (mc != null) {
|
||||
mc.gainFestivalPoints(this.blueTotalCP);
|
||||
mc.setMonsterCarnival(null);
|
||||
if (cpq1) {
|
||||
mc.changeMap(cs.getMapFactory().getMap(map.getId() + 3), cs.getMapFactory().getMap(map.getId() + 3).getPortal(0));
|
||||
} else {
|
||||
mc.changeMap(cs.getMapFactory().getMap(map.getId() + 300), cs.getMapFactory().getMap(map.getId() + 300).getPortal(0));
|
||||
}
|
||||
mc.setTeam(-1);
|
||||
mc.dispelDebuffs();
|
||||
}
|
||||
}
|
||||
} else if (winningTeam == 1) {
|
||||
for (MaplePartyCharacter mpc : leader2.getParty().getMembers()) {
|
||||
MapleCharacter mc = cs.getPlayerStorage().getCharacterByName(mpc.getName());
|
||||
if (mc != null) {
|
||||
mc.gainFestivalPoints(this.blueTotalCP);
|
||||
mc.setMonsterCarnival(null);
|
||||
if (cpq1) {
|
||||
mc.changeMap(cs.getMapFactory().getMap(map.getId() + 2), cs.getMapFactory().getMap(map.getId() + 2).getPortal(0));
|
||||
} else {
|
||||
mc.changeMap(cs.getMapFactory().getMap(map.getId() + 200), cs.getMapFactory().getMap(map.getId() + 200).getPortal(0));
|
||||
}
|
||||
mc.setTeam(-1);
|
||||
mc.dispelDebuffs();
|
||||
}
|
||||
}
|
||||
for (MaplePartyCharacter mpc : leader1.getParty().getMembers()) {
|
||||
MapleCharacter mc = cs.getPlayerStorage().getCharacterByName(mpc.getName());
|
||||
if (mc != null) {
|
||||
mc.gainFestivalPoints(this.redTotalCP);
|
||||
mc.setMonsterCarnival(null);
|
||||
if (cpq1) {
|
||||
mc.changeMap(cs.getMapFactory().getMap(map.getId() + 3), cs.getMapFactory().getMap(map.getId() + 3).getPortal(0));
|
||||
} else {
|
||||
mc.changeMap(cs.getMapFactory().getMap(map.getId() + 300), cs.getMapFactory().getMap(map.getId() + 300).getPortal(0));
|
||||
}
|
||||
mc.setTeam(-1);
|
||||
mc.dispelDebuffs();
|
||||
}
|
||||
}
|
||||
}
|
||||
dispose();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void timeUp() {
|
||||
int cp1 = this.redTotalCP;
|
||||
int cp2 = this.blueTotalCP;
|
||||
if (cp1 == cp2) {
|
||||
extendTime();
|
||||
return;
|
||||
}
|
||||
if (cp1 > cp2) {
|
||||
finish(0);
|
||||
} else {
|
||||
finish(1);
|
||||
}
|
||||
}
|
||||
|
||||
public long getTimeLeft() {
|
||||
return (startTime - System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public int getTimeLeftSeconds() {
|
||||
return (int) (getTimeLeft() / 1000);
|
||||
}
|
||||
|
||||
public void extendTime() {
|
||||
for (MapleCharacter chrMap : map.getAllPlayers()) {
|
||||
chrMap.dropMessage(5, LinguaConstants.Linguas(chrMap).CPQTempoExtendido);
|
||||
}
|
||||
startTime = System.currentTimeMillis() + 3 * 1000;
|
||||
map.addClock(3 * 60);
|
||||
timer = TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
timeUp();
|
||||
}
|
||||
}, 3 * 60 * 1000);
|
||||
effectTimer = TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
complete();
|
||||
}
|
||||
}, 3 * 60 * 1000 - 10);
|
||||
}
|
||||
|
||||
public void complete() {
|
||||
int cp1 = this.redTotalCP;
|
||||
int cp2 = this.blueTotalCP;
|
||||
if (cp1 == cp2) {
|
||||
return;
|
||||
}
|
||||
boolean redWin = cp1 > cp2;
|
||||
int chnl = leader1.getClient().getChannel();
|
||||
int chnl1 = leader2.getClient().getChannel();
|
||||
if (chnl != chnl1) {
|
||||
throw new RuntimeException("Os líderes estão em canais diferentes.");
|
||||
}
|
||||
|
||||
public int getRoom() {
|
||||
return room;
|
||||
}
|
||||
|
||||
public void saveResults() {
|
||||
Connection con = null;
|
||||
try {
|
||||
con = DatabaseConnection.getConnection();
|
||||
PreparedStatement ps = con.prepareStatement("INSERT INTO carnivalresults VALUES (?,?,?,?)");
|
||||
for (MapleCharacter chr : red.getMembers()) {
|
||||
ps.setInt(1, chr.getId());
|
||||
ps.setInt(2, chr.getCP());
|
||||
ps.setInt(3, red.getTotalCP());
|
||||
ps.setInt(4, red.isWinner() ? 1 : 0);
|
||||
ps.execute();
|
||||
}
|
||||
for (MapleCharacter chr : blue.getMembers()) {
|
||||
ps.setInt(1, chr.getId());
|
||||
ps.setInt(2, chr.getCP());
|
||||
ps.setInt(3, blue.getTotalCP());
|
||||
ps.setInt(4, blue.isWinner() ? 1 : 0);
|
||||
ps.execute();
|
||||
}
|
||||
ps.close();
|
||||
con.close();
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
Channel cs = Server.getInstance().getWorld(p1.getLeader().getWorld()).getChannel(p1.getLeader().getChannel());
|
||||
map.killAllMonsters();
|
||||
for (MaplePartyCharacter mpc : leader1.getParty().getMembers()) {
|
||||
MapleCharacter mc;
|
||||
mc = cs.getPlayerStorage().getCharacterByName(mpc.getName());
|
||||
if (mc != null) {
|
||||
if (redWin) {
|
||||
mc.getClient().announce(MaplePacketCreator.showEffect("quest/carnival/win"));
|
||||
mc.getClient().announce(MaplePacketCreator.playSound("MobCarnival/Win"));
|
||||
mc.dispelDebuffs();
|
||||
} else {
|
||||
mc.getClient().announce(MaplePacketCreator.showEffect("quest/carnival/lose"));
|
||||
mc.getClient().announce(MaplePacketCreator.playSound("MobCarnival/Lose"));
|
||||
mc.dispelDebuffs();
|
||||
}
|
||||
}
|
||||
}
|
||||
for (MaplePartyCharacter mpc : leader2.getParty().getMembers()) {
|
||||
MapleCharacter mc;
|
||||
mc = cs.getPlayerStorage().getCharacterByName(mpc.getName());
|
||||
if (mc != null) {
|
||||
if (!redWin) {
|
||||
mc.getClient().announce(MaplePacketCreator.showEffect("quest/carnival/win"));
|
||||
mc.getClient().announce(MaplePacketCreator.playSound("MobCarnival/Win"));
|
||||
mc.dispelDebuffs();
|
||||
} else {
|
||||
mc.getClient().announce(MaplePacketCreator.showEffect("quest/carnival/lose"));
|
||||
mc.getClient().announce(MaplePacketCreator.playSound("MobCarnival/Lose"));
|
||||
mc.dispelDebuffs();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MapleParty getRed() {
|
||||
return p1;
|
||||
}
|
||||
|
||||
public void setRed(MapleParty p1) {
|
||||
this.p1 = p1;
|
||||
}
|
||||
|
||||
public MapleParty getBlue() {
|
||||
return p2;
|
||||
}
|
||||
|
||||
public void setBlue(MapleParty p2) {
|
||||
this.p2 = p2;
|
||||
}
|
||||
|
||||
public MapleCharacter getLeader1() {
|
||||
return leader1;
|
||||
}
|
||||
|
||||
public void setLeader1(MapleCharacter leader1) {
|
||||
this.leader1 = leader1;
|
||||
}
|
||||
|
||||
public MapleCharacter getLeader2() {
|
||||
return leader2;
|
||||
}
|
||||
|
||||
public void setLeader2(MapleCharacter leader2) {
|
||||
this.leader2 = leader2;
|
||||
}
|
||||
|
||||
public MapleCharacter getEnemyLeader(int team) {
|
||||
switch (team) {
|
||||
case 0:
|
||||
return leader2;
|
||||
case 1:
|
||||
return leader1;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getBlueCP() {
|
||||
return blueCP;
|
||||
}
|
||||
|
||||
public void setBlueCP(int blueCP) {
|
||||
this.blueCP = blueCP;
|
||||
}
|
||||
|
||||
public int getBlueTotalCP() {
|
||||
return blueTotalCP;
|
||||
}
|
||||
|
||||
public void setBlueTotalCP(int blueTotalCP) {
|
||||
this.blueTotalCP = blueTotalCP;
|
||||
}
|
||||
|
||||
public int getRedCP() {
|
||||
return redCP;
|
||||
}
|
||||
|
||||
public void setRedCP(int redCP) {
|
||||
this.redCP = redCP;
|
||||
}
|
||||
|
||||
public int getRedTotalCP() {
|
||||
return redTotalCP;
|
||||
}
|
||||
|
||||
public void setRedTotalCP(int redTotalCP) {
|
||||
this.redTotalCP = redTotalCP;
|
||||
}
|
||||
|
||||
public int getTotalCP(int team) {
|
||||
if (team == 0) {
|
||||
return redTotalCP;
|
||||
} else if (team == 1) {
|
||||
return blueTotalCP;
|
||||
} else {
|
||||
throw new RuntimeException("Equipe desconhecida");
|
||||
}
|
||||
}
|
||||
|
||||
public void setTotalCP(int totalCP, int team) {
|
||||
if (team == 0) {
|
||||
this.redTotalCP = totalCP;
|
||||
} else if (team == 1) {
|
||||
this.blueTotalCP = totalCP;
|
||||
}
|
||||
}
|
||||
|
||||
public int getCP(int team) {
|
||||
if (team == 0) {
|
||||
return redCP;
|
||||
} else if (team == 1) {
|
||||
return blueCP;
|
||||
} else {
|
||||
throw new RuntimeException("Equipe desconhecida" + team);
|
||||
}
|
||||
}
|
||||
|
||||
public void setCP(int CP, int team) {
|
||||
if (team == 0) {
|
||||
this.redCP = CP;
|
||||
} else if (team == 1) {
|
||||
this.blueCP = CP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user