Attempt on Mystic Doors

Partially fixed Mystic Doors.
This commit is contained in:
ronancpl
2017-07-09 20:00:31 -03:00
parent b3734cbaf7
commit b7c0bb6c07
83 changed files with 443 additions and 241 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
#Tue, 04 Jul 2017 15:35:40 -0300 #Sun, 09 Jul 2017 19:55:31 -0300
C\:\\Nexon\\MapleSolaxia\\MapleSolaxiaV2= C\:\\Nexon\\MapleSolaxia\\MapleSolaxiaV2=
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
+9 -3
View File
@@ -4,9 +4,15 @@
<open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/2"> <open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/2">
<group> <group>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/SendOpcode.java</file> <file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/SendOpcode.java</file>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/server/maps/MapleMapObjectType.java</file> <file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/server/maps/MapleDoor.java</file>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/server/maps/MapleSummon.java</file> <file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/server/MapleStatEffect.java</file>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/channel/handlers/DamageSummonHandler.java</file> <file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/world/MaplePartyCharacter.java</file>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/channel/handlers/DoorHandler.java</file>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/client/MapleBuffStat.java</file>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/server/maps/MapleMap.java</file>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/server/maps/MapleDoorObject.java</file>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/client/MapleCharacter.java</file>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/client/MapleClient.java</file>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/tools/MaplePacketCreator.java</file> <file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/tools/MaplePacketCreator.java</file>
</group> </group>
</open-files> </open-files>
+31 -27
View File
@@ -250,7 +250,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
private Map<Integer, MapleSummon> summons = new LinkedHashMap<>(); private Map<Integer, MapleSummon> summons = new LinkedHashMap<>();
private Map<Integer, MapleCoolDownValueHolder> coolDowns = new LinkedHashMap<>(50); private Map<Integer, MapleCoolDownValueHolder> coolDowns = new LinkedHashMap<>(50);
private EnumMap<MapleDisease, DiseaseValueHolder> diseases = new EnumMap<>(MapleDisease.class); private EnumMap<MapleDisease, DiseaseValueHolder> diseases = new EnumMap<>(MapleDisease.class);
private List<MapleDoor> doors = new ArrayList<>(); private Map<Integer, MapleDoor> doors = new LinkedHashMap<>();
private ScheduledFuture<?> dragonBloodSchedule; private ScheduledFuture<?> dragonBloodSchedule;
private ScheduledFuture<?> mapTimeLimitTask = null; private ScheduledFuture<?> mapTimeLimitTask = null;
private ScheduledFuture<?>[] fullnessSchedule = new ScheduledFuture<?>[3]; private ScheduledFuture<?>[] fullnessSchedule = new ScheduledFuture<?>[3];
@@ -462,8 +462,12 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
return pts; return pts;
} }
public void addDoor(MapleDoor door) { public void addDoor(Integer owner, MapleDoor door) {
doors.add(door); doors.put(owner, door);
}
public void removeDoor(Integer owner) {
doors.remove(owner);
} }
public void addExcluded(int x) { public void addExcluded(int x) {
@@ -659,8 +663,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
Item weapon_item = getInventory(MapleInventoryType.EQUIPPED).getItem((short) -11); Item weapon_item = getInventory(MapleInventoryType.EQUIPPED).getItem((short) -11);
if (weapon_item != null) { if (weapon_item != null) {
MapleWeaponType weapon = MapleItemInformationProvider.getInstance().getWeaponType(weapon_item.getItemId()); MapleWeaponType weapon = MapleItemInformationProvider.getInstance().getWeaponType(weapon_item.getItemId());
int mainstat; int mainstat, secondarystat;
int secondarystat;
if (getJob().isA(MapleJob.THIEF) && weapon == MapleWeaponType.DAGGER_OTHER) { if (getJob().isA(MapleJob.THIEF) && weapon == MapleWeaponType.DAGGER_OTHER) {
weapon = MapleWeaponType.DAGGER_THIEVES; weapon = MapleWeaponType.DAGGER_THIEVES;
} }
@@ -684,7 +687,6 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
} }
int attack = (int) Math.min(Math.floor((2 * getLevel() + 31) / 3), 31); int attack = (int) Math.min(Math.floor((2 * getLevel() + 31) / 3), 31);
maxbasedamage = (int) (localstr * weapMulti + localdex) * attack / 100; maxbasedamage = (int) (localstr * weapMulti + localdex) * attack / 100;
} else { } else {
maxbasedamage = 1; maxbasedamage = 1;
@@ -811,31 +813,33 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
buffstats.add(statup.getLeft()); buffstats.add(statup.getLeft());
} }
} }
List<MapleBuffStatValueHolder> toCancel = deregisterBuffStats(buffstats);
if (effect.isMagicDoor()) { if (effect.isMagicDoor()) {
if (!getDoors().isEmpty()) { MapleDoor destroyDoor = doors.remove(this.getId());
MapleDoor door = getDoors().iterator().next();
for (MapleCharacter chr : door.getTarget().getCharacters()) { if (destroyDoor != null) {
door.sendDestroyData(chr.client); destroyDoor.freeAllocatedPortal();
destroyDoor.getTarget().removeMapObject(destroyDoor.getAreaDoor());
destroyDoor.getTown().removeMapObject(destroyDoor.getTownDoor());
for (MapleCharacter chr : destroyDoor.getTarget().getCharacters()) {
destroyDoor.getAreaDoor().sendDestroyData(chr.getClient());
} }
for (MapleCharacter chr : door.getTown().getCharacters()) { for (MapleCharacter chr : destroyDoor.getTown().getCharacters()) {
door.sendDestroyData(chr.client); destroyDoor.getTownDoor().sendDestroyData(chr.getClient());
}
for (MapleDoor destroyDoor : getDoors()) {
door.getTarget().removeMapObject(destroyDoor);
door.getTown().removeMapObject(destroyDoor);
} }
if (party != null) { if (party != null) {
for (MaplePartyCharacter partyMembers : getParty().getMembers()) { for (MaplePartyCharacter partyMembers : getParty().getMembers()) {
partyMembers.getPlayer().getDoors().remove(door); partyMembers.getPlayer().removeDoor(this.getId());
partyMembers.getDoors().remove(door); partyMembers.removeDoor(this.getId());
} }
silentPartyUpdate(); silentPartyUpdate();
} else {
clearDoors();
} }
} }
} }
List<MapleBuffStatValueHolder> toCancel = deregisterBuffStats(buffstats);
if (effect.getSourceId() == Spearman.HYPER_BODY || effect.getSourceId() == GM.HYPER_BODY || effect.getSourceId() == SuperGM.HYPER_BODY) { if (effect.getSourceId() == Spearman.HYPER_BODY || effect.getSourceId() == GM.HYPER_BODY || effect.getSourceId() == SuperGM.HYPER_BODY) {
List<Pair<MapleStat, Integer>> statup = new ArrayList<>(4); List<Pair<MapleStat, Integer>> statup = new ArrayList<>(4);
statup.add(new Pair<>(MapleStat.HP, Math.min(hp, maxhp))); statup.add(new Pair<>(MapleStat.HP, Math.min(hp, maxhp)));
@@ -1335,10 +1339,6 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
} }
} }
public void clearDoors() {
doors.clear();
}
public void clearSavedLocation(SavedLocationType type) { public void clearSavedLocation(SavedLocationType type) {
savedLocations[type.ordinal()] = null; savedLocations[type.ordinal()] = null;
} }
@@ -2412,8 +2412,8 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
return dojoStage; return dojoStage;
} }
public List<MapleDoor> getDoors() { public Map<Integer, MapleDoor> getDoors() {
return new ArrayList<>(doors); return Collections.unmodifiableMap(doors);
} }
public int getEnergyBar() { public int getEnergyBar() {
@@ -3871,6 +3871,10 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
} }
} }
public Set<Integer> getActiveCoupons() {
return Collections.unmodifiableSet(activeCoupons.keySet());
}
public static MapleCharacter loadCharFromDB(int charid, MapleClient client, boolean channelserver) throws SQLException { public static MapleCharacter loadCharFromDB(int charid, MapleClient client, boolean channelserver) throws SQLException {
try { try {
MapleCharacter ret = new MapleCharacter(); MapleCharacter ret = new MapleCharacter();
+2 -2
View File
@@ -1196,8 +1196,8 @@ public class MapleClient {
} }
server.getPlayerBuffStorage().addBuffsToStorage(player.getId(), player.getAllBuffs()); server.getPlayerBuffStorage().addBuffsToStorage(player.getId(), player.getAllBuffs());
player.cancelBuffEffects(); player.cancelBuffEffects();
player.cancelMagicDoor(); //Cancelling magicdoor? Nope
//Canceling mounts? Noty //Cancelling mounts? Noty
if (player.getBuffedValue(MapleBuffStat.PUPPET) != null) { if (player.getBuffedValue(MapleBuffStat.PUPPET) != null) {
player.cancelEffectFromBuffStat(MapleBuffStat.PUPPET); player.cancelEffectFromBuffStat(MapleBuffStat.PUPPET);
} }
+26 -6
View File
@@ -27,12 +27,12 @@ import server.MapleStatEffect;
import server.life.Element; import server.life.Element;
public class Skill { public class Skill {
public int id; private int id;
public List<MapleStatEffect> effects = new ArrayList<>(); private List<MapleStatEffect> effects = new ArrayList<>();
public Element element; private Element element;
public int animationTime; private int animationTime;
public int job; private int job;
public boolean action; private boolean action;
public Skill(int id) { public Skill(int id) {
this.id = id; this.id = id;
@@ -61,6 +61,10 @@ public class Skill {
return job % 10 == 2; return job % 10 == 2;
} }
public void setElement(Element elem) {
element = elem;
}
public Element getElement() { public Element getElement() {
return element; return element;
} }
@@ -69,11 +73,27 @@ public class Skill {
return animationTime; return animationTime;
} }
public void setAnimationTime(int time) {
animationTime = time;
}
public void incAnimationTime(int time) {
animationTime += time;
}
public boolean isBeginnerSkill() { public boolean isBeginnerSkill() {
return id % 10000000 < 10000; return id % 10000000 < 10000;
} }
public void setAction(boolean act) {
action = act;
}
public boolean getAction() { public boolean getAction() {
return action; return action;
} }
public void addLevelEffect(MapleStatEffect effect) {
effects.add(effect);
}
} }
+8 -6
View File
@@ -74,7 +74,9 @@ import constants.skills.WhiteKnight;
import constants.skills.WindArcher; import constants.skills.WindArcher;
import java.io.File; import java.io.File;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import provider.MapleData; import provider.MapleData;
@@ -122,9 +124,9 @@ public class SkillFactory {
int skillType = MapleDataTool.getInt("skillType", data, -1); int skillType = MapleDataTool.getInt("skillType", data, -1);
String elem = MapleDataTool.getString("elemAttr", data, null); String elem = MapleDataTool.getString("elemAttr", data, null);
if (elem != null) { if (elem != null) {
ret.element = Element.getFromChar(elem.charAt(0)); ret.setElement(Element.getFromChar(elem.charAt(0)));
} else { } else {
ret.element = Element.NEUTRAL; ret.setElement(Element.NEUTRAL);
} }
MapleData effect = data.getChildByPath("effect"); MapleData effect = data.getChildByPath("effect");
if (skillType != -1) { if (skillType != -1) {
@@ -148,7 +150,7 @@ public class SkillFactory {
} else { } else {
action = true; action = true;
} }
ret.action = action; ret.setAction(action);
MapleData hit = data.getChildByPath("hit"); MapleData hit = data.getChildByPath("hit");
MapleData ball = data.getChildByPath("ball"); MapleData ball = data.getChildByPath("ball");
isBuff = effect != null && hit == null && ball == null; isBuff = effect != null && hit == null && ball == null;
@@ -371,12 +373,12 @@ public class SkillFactory {
} }
for (MapleData level : data.getChildByPath("level")) { for (MapleData level : data.getChildByPath("level")) {
ret.effects.add(MapleStatEffect.loadSkillEffectFromData(level, id, isBuff)); ret.addLevelEffect(MapleStatEffect.loadSkillEffectFromData(level, id, isBuff));
} }
ret.animationTime = 0; ret.setAnimationTime(0);
if (effect != null) { if (effect != null) {
for (MapleData effectEntry : effect) { for (MapleData effectEntry : effect) {
ret.animationTime += MapleDataTool.getIntConvert("delay", effectEntry, 0); ret.incAnimationTime(MapleDataTool.getIntConvert("delay", effectEntry, 0));
} }
} }
return ret; return ret;
+2 -2
View File
@@ -709,7 +709,7 @@ public class Commands {
case "debugmap": case "debugmap":
if(ServerConstants.USE_DEBUG) { if(ServerConstants.USE_DEBUG) {
player.dropMessage(6, "Current map id " + player.getMap().getId() + ", event: '" + ((player.getMap().getEventInstance() != null) ? player.getMap().getEventInstance().getName() : "null") + "'; Players: " + player.getMap().getAllPlayers().size() + ", Mobs: " + player.getMap().countMonsters() + ", Reactors: " + player.getMap().countReactors() + ", Items: " + player.getMap().countItems() + "."); player.dropMessage(6, "Current map id " + player.getMap().getId() + ", event: '" + ((player.getMap().getEventInstance() != null) ? player.getMap().getEventInstance().getName() : "null") + "'; Players: " + player.getMap().getAllPlayers().size() + ", Mobs: " + player.getMap().countMonsters() + ", Reactors: " + player.getMap().countReactors() + ", Items: " + player.getMap().countItems() + ", Objects: " + player.getMap().getMapObjects().size() + ".");
} }
break; break;
@@ -764,7 +764,7 @@ public class Commands {
case "debugplayercoupons": case "debugplayercoupons":
if(ServerConstants.USE_DEBUG) { if(ServerConstants.USE_DEBUG) {
String s = "Currently active PLAYER coupons: "; String s = "Currently active PLAYER coupons: ";
for(Integer i : Server.getInstance().getActiveCoupons()) { for(Integer i : player.getActiveCoupons()) {
s += (i + " "); s += (i + " ");
} }
@@ -23,22 +23,22 @@ package net.server.channel.handlers;
import client.MapleClient; import client.MapleClient;
import net.AbstractMaplePacketHandler; import net.AbstractMaplePacketHandler;
import server.maps.MapleDoor; import server.maps.MapleDoorObject;
import server.maps.MapleMapObject; import server.maps.MapleMapObject;
import tools.data.input.SeekableLittleEndianAccessor; import tools.data.input.SeekableLittleEndianAccessor;
/** /**
* *
* @author Matze * @author Matze, Ronan
*/ */
public final class DoorHandler extends AbstractMaplePacketHandler { public final class DoorHandler extends AbstractMaplePacketHandler {
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) { public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
int oid = slea.readInt(); int ownerid = slea.readInt();
boolean mode = (slea.readByte() == 0); // specifies if backwarp or not, 1 town to target, 0 target to town boolean mode = (slea.readByte() == 0); // specifies if backwarp or not, 1 town to target, 0 target to town
for (MapleMapObject obj : c.getPlayer().getMap().getMapObjects()) { for (MapleMapObject obj : c.getPlayer().getMap().getMapObjects()) {
if (obj instanceof MapleDoor) { if (obj instanceof MapleDoorObject) {
MapleDoor door = (MapleDoor) obj; MapleDoorObject door = (MapleDoorObject) obj;
if (door.getOwner().getId() == oid) { if (door.getOwnerId() == ownerid) {
door.warp(c.getPlayer(), mode); door.warp(c.getPlayer(), mode);
return; return;
} }
@@ -116,12 +116,12 @@ public final class SpecialMoveHandler extends AbstractMaplePacketHandler {
if (slea.available() == 5) { if (slea.available() == 5) {
pos = new Point(slea.readShort(), slea.readShort()); pos = new Point(slea.readShort(), slea.readShort());
} }
if (skill.getId() == Priest.MYSTIC_DOOR && !chr.isGM()) {
c.announce(MaplePacketCreator.enableActions());
return;
}
if (chr.isAlive()) { if (chr.isAlive()) {
if (skill.getId() != Priest.MYSTIC_DOOR || chr.canDoor()) { if (skill.getId() != Priest.MYSTIC_DOOR) {
skill.getEffect(skillLevel).applyTo(c.getPlayer(), pos);
} else if(chr.canDoor()) {
//update door lists
chr.cancelMagicDoor();
skill.getEffect(skillLevel).applyTo(c.getPlayer(), pos); skill.getEffect(skillLevel).applyTo(c.getPlayer(), pos);
} else { } else {
chr.message("Please wait 5 seconds before casting Mystic Door again."); chr.message("Please wait 5 seconds before casting Mystic Door again.");
+15 -7
View File
@@ -21,12 +21,16 @@
*/ */
package net.server.world; package net.server.world;
import java.util.ArrayList; import java.util.Map;
import java.util.Map.Entry;
import java.util.LinkedHashMap;
import java.util.Collection; import java.util.Collection;
import server.maps.MapleDoor; import server.maps.MapleDoor;
import server.MapleStatEffect;
import client.MapleCharacter; import client.MapleCharacter;
import client.MapleJob; import client.MapleJob;
import java.util.Collections;
public class MaplePartyCharacter { public class MaplePartyCharacter {
private String name; private String name;
@@ -35,7 +39,7 @@ public class MaplePartyCharacter {
private int channel, world; private int channel, world;
private int jobid; private int jobid;
private int mapid; private int mapid;
private ArrayList<MapleDoor> door = new ArrayList<MapleDoor>(); private Map<Integer, MapleDoor> doors = new LinkedHashMap<>();
private boolean online; private boolean online;
private MapleJob job; private MapleJob job;
private MapleCharacter character; private MapleCharacter character;
@@ -51,8 +55,8 @@ public class MaplePartyCharacter {
this.mapid = maplechar.getMapId(); this.mapid = maplechar.getMapId();
this.online = true; this.online = true;
this.job = maplechar.getJob(); this.job = maplechar.getJob();
for (MapleDoor doors : maplechar.getDoors()) { for (Entry<Integer, MapleDoor> entry : maplechar.getDoors().entrySet()) {
this.door.add(doors); doors.put(entry.getKey(), entry.getValue());
} }
} }
@@ -116,12 +120,16 @@ public class MaplePartyCharacter {
return character.getGuildId(); return character.getGuildId();
} }
public void updateDoor(MapleDoor door) { public void addDoor(Integer owner, MapleDoor door) {
this.door.add(door); this.doors.put(owner, door);
}
public void removeDoor(Integer owner) {
this.doors.remove(owner);
} }
public Collection<MapleDoor> getDoors() { public Collection<MapleDoor> getDoors() {
return door; return Collections.unmodifiableCollection(doors.values());
} }
@Override @Override
+18 -17
View File
@@ -845,27 +845,24 @@ public class MapleStatEffect {
} }
Point doorPosition = new Point(applyto.getPosition().x, y); Point doorPosition = new Point(applyto.getPosition().x, y);
MapleDoor door = new MapleDoor(applyto, doorPosition); MapleDoor door = new MapleDoor(applyto, doorPosition);
if (applyto.getParty() != null) {// out of town door
for (MaplePartyCharacter partyMembers : applyto.getParty().getMembers()) { if(door.getOwnerId() != -1) {
partyMembers.getPlayer().addDoor(door); if (applyto.getParty() != null) {
partyMembers.updateDoor(door); for (MaplePartyCharacter partyMember : applyto.getParty().getMembers()) {
partyMember.getPlayer().addDoor(door.getOwnerId(), door);
partyMember.addDoor(door.getOwnerId(), door);
} }
applyto.silentPartyUpdate(); applyto.silentPartyUpdate();
} else { } else {
applyto.addDoor(door); applyto.addDoor(door.getOwnerId(), door);
} }
applyto.getMap().spawnDoor(door);
door = new MapleDoor(door); //The town door door.getTarget().spawnDoor(door.getAreaDoor());
if (applyto.getParty() != null) {// update town doors door.getTown().spawnDoor(door.getTownDoor());
for (MaplePartyCharacter partyMembers : applyto.getParty().getMembers()) {
partyMembers.getPlayer().addDoor(door);
partyMembers.updateDoor(door);
}
applyto.silentPartyUpdate();
} else { } else {
applyto.addDoor(door); 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
} }
door.getTown().spawnDoor(door);
applyto.disableDoor(); applyto.disableDoor();
} else if (isMist()) { } else if (isMist()) {
Rectangle bounds = calculateBoundingBox(sourceid == NightWalker.POISON_BOMB ? pos : applyfrom.getPosition(), applyfrom.isFacingLeft()); Rectangle bounds = calculateBoundingBox(sourceid == NightWalker.POISON_BOMB ? pos : applyfrom.getPosition(), applyfrom.isFacingLeft());
@@ -966,7 +963,7 @@ public class MapleStatEffect {
} }
private void applyBuffEffect(MapleCharacter applyfrom, MapleCharacter applyto, boolean primary) { private void applyBuffEffect(MapleCharacter applyfrom, MapleCharacter applyto, boolean primary) {
if (!isMonsterRiding() && !isCouponBuff()) { if (!isMonsterRiding() && !isCouponBuff() && !isMysticDoor()) { // last mystic door already dispelled if it has been used before.
applyto.cancelEffect(this, true, -1); applyto.cancelEffect(this, true, -1);
} }
@@ -1295,6 +1292,10 @@ public class MapleStatEffect {
return MapleItemInformationProvider.getInstance().isRateCoupon(sourceid); return MapleItemInformationProvider.getInstance().isRateCoupon(sourceid);
} }
private boolean isMysticDoor() {
return skill && sourceid == Priest.MYSTIC_DOOR;
}
public boolean isMonsterRiding() { public boolean isMonsterRiding() {
return skill && (sourceid % 10000000 == 1004 || sourceid == Corsair.BATTLE_SHIP || sourceid == Beginner.SPACESHIP || sourceid == Noblesse.SPACESHIP 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 || sourceid == Beginner.YETI_MOUNT1 || sourceid == Beginner.YETI_MOUNT2 || sourceid == Beginner.WITCH_BROOMSTICK || sourceid == Beginner.BALROG_MOUNT
@@ -1432,7 +1433,7 @@ public class MapleStatEffect {
public boolean hasNoIcon() { public boolean hasNoIcon() {
return (sourceid == 3111002 || sourceid == 3211002 || + // puppet, puppet return (sourceid == 3111002 || sourceid == 3211002 || + // puppet, puppet
sourceid == 3211005 || sourceid == 2311002 || + // golden eagle, mystic door sourceid == 3211005 || + // golden eagle
sourceid == 2121005 || sourceid == 2221005 || + // elquines, ifrit sourceid == 2121005 || sourceid == 2221005 || + // elquines, ifrit
sourceid == 2321003 || sourceid == 3121006 || + // bahamut, phoenix sourceid == 2321003 || sourceid == 3121006 || + // bahamut, phoenix
sourceid == 3221005 || sourceid == 3111005 || + // frostprey, silver hawk sourceid == 3221005 || sourceid == 3111005 || + // frostprey, silver hawk
+41 -90
View File
@@ -22,115 +22,75 @@
package server.maps; package server.maps;
import java.awt.Point; import java.awt.Point;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.List; import java.util.List;
import server.MaplePortal; import server.MaplePortal;
import tools.MaplePacketCreator;
import client.MapleCharacter; import client.MapleCharacter;
import client.MapleClient;
/** /**
* *
* @author Matze * @author Matze, Ronan
*/ */
public class MapleDoor extends AbstractMapleMapObject { public class MapleDoor {
private MapleCharacter owner; private int ownerId;
private MapleMap town; private MapleMap town;
private MaplePortal townPortal; private MaplePortal townPortal;
private MapleMap target; private MapleMap target;
private Point targetPosition;
private MapleDoorObject townDoor;
private MapleDoorObject areaDoor;
public MapleDoor(MapleCharacter owner, Point targetPosition) { public MapleDoor(MapleCharacter owner, Point targetPosition) {
super(); this.ownerId = owner.getId();
this.owner = owner;
this.target = owner.getMap(); this.target = owner.getMap();
this.targetPosition = targetPosition;
setPosition(this.targetPosition);
this.town = this.target.getReturnMap(); this.town = this.target.getReturnMap();
this.townPortal = getFreePortal(); this.townPortal = allocateFreePortal();
}
public MapleDoor(MapleDoor origDoor) { if(townPortal != null) {
super(); this.areaDoor = new MapleDoorObject(ownerId, town, target, false, targetPosition, townPortal.getPosition());
this.owner = origDoor.owner; this.townDoor = new MapleDoorObject(ownerId, target, town, true, townPortal.getPosition(), targetPosition);
this.town = origDoor.town;
this.townPortal = origDoor.townPortal;
this.target = origDoor.target;
this.targetPosition = origDoor.targetPosition;
this.townPortal = origDoor.townPortal;
setPosition(this.townPortal.getPosition());
}
private MaplePortal getFreePortal() { this.areaDoor.setPairOid(this.townDoor.getObjectId());
List<MaplePortal> freePortals = new ArrayList<MaplePortal>(); this.townDoor.setPairOid(this.areaDoor.getObjectId());
for (MaplePortal port : town.getPortals()) {
if (port.getType() == 6) {
freePortals.add(port);
}
}
Collections.sort(freePortals, new Comparator<MaplePortal>() {
public int compare(MaplePortal o1, MaplePortal o2) {
if (o1.getId() < o2.getId()) {
return -1;
} else if (o1.getId() == o2.getId()) {
return 0;
} else { } else {
return 1; this.ownerId = -1;
}
}
});
for (MapleMapObject obj : town.getMapObjects()) {
if (obj instanceof MapleDoor) {
MapleDoor door = (MapleDoor) obj;
if (door.getOwner().getParty() != null && door.getOwner().getParty().containsMembers(door.getOwner().getMPC())) {
freePortals.remove(door.getTownPortal());
}
}
}
return freePortals.iterator().next();
}
@Override
public void sendSpawnData(MapleClient client) {
if (target.getId() == client.getPlayer().getMapId() || owner == client.getPlayer() && owner.getParty() == null) {
client.announce(MaplePacketCreator.spawnDoor(owner.getId(), town.getId() == client.getPlayer().getMapId() ? townPortal.getPosition() : targetPosition, true));
if (owner.getParty() != null && (owner == client.getPlayer() || owner.getParty().containsMembers(client.getPlayer().getMPC()))) {
client.announce(MaplePacketCreator.partyPortal(town.getId(), target.getId(), targetPosition));
}
}
if (owner.getId() != client.getPlayer().getId()) {
client.announce(MaplePacketCreator.spawnPortal(town.getId(), target.getId(), targetPosition));
} }
} }
@Override public void freeAllocatedPortal() {
public void sendDestroyData(MapleClient client) { if(townPortal != null) {
if (target.getId() == client.getPlayer().getMapId() || owner == client.getPlayer() || owner.getParty() != null && owner.getParty().containsMembers(client.getPlayer().getMPC())) { town.setDisposeDoorPortal(townPortal);
if (owner.getParty() != null && (owner == client.getPlayer() || owner.getParty().containsMembers(client.getPlayer().getMPC()))) {
client.announce(MaplePacketCreator.partyPortal(999999999, 999999999, new Point(-1, -1)));
}
client.announce(MaplePacketCreator.removeDoor(owner.getId(), false));
client.announce(MaplePacketCreator.removeDoor(owner.getId(), true));
} }
} }
public void warp(MapleCharacter chr, boolean toTown) { private MaplePortal allocateFreePortal() {
if (chr == owner || owner.getParty() != null && owner.getParty().containsMembers(chr.getMPC())) { List<MaplePortal> availablePortals = town.getAvailableDoorPortals();
if (!toTown) { if(availablePortals.isEmpty() || !town.getNotUsingDoorPortal()) return null;
chr.changeMap(target, targetPosition);
} else { Collections.shuffle(availablePortals);
chr.changeMap(town, townPortal); while(!availablePortals.isEmpty()) {
} MaplePortal port = availablePortals.remove(0);
} else {
chr.getClient().announce(MaplePacketCreator.enableActions()); if(town.setUsingDoorPortal(port)) {
return port;
} }
} }
public MapleCharacter getOwner() { return null;
return owner; }
public int getOwnerId() {
return ownerId;
}
public MapleDoorObject getTownDoor() {
return townDoor;
}
public MapleDoorObject getAreaDoor() {
return areaDoor;
} }
public MapleMap getTown() { public MapleMap getTown() {
@@ -145,13 +105,4 @@ public class MapleDoor extends AbstractMapleMapObject {
return target; return target;
} }
public Point getTargetPosition() {
return targetPosition;
}
@Override
public MapleMapObjectType getType() {
return MapleMapObjectType.DOOR;
}
} }
+130
View File
@@ -0,0 +1,130 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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.maps;
import client.MapleCharacter;
import java.awt.Point;
import tools.MaplePacketCreator;
import client.MapleClient;
/**
*
* @author Ronan
*/
public class MapleDoorObject extends AbstractMapleMapObject {
private int ownerId;
private int pairOid;
private boolean isTown;
private MapleMap from;
private MapleMap to;
private Point toPos;
public MapleDoorObject(int owner, MapleMap destination, MapleMap origin, boolean town, Point targetPosition, Point toPosition) {
super();
setPosition(targetPosition);
ownerId = owner;
isTown = town;
from = origin;
to = destination;
toPos = toPosition;
}
public void warp(MapleCharacter chr, boolean toTown) {
if (chr.getId() == ownerId || (chr.getParty() != null && chr.getParty().getMemberById(ownerId) != null)) {
chr.changeMap(to, toPos);
} else {
chr.getClient().announce(MaplePacketCreator.blockedMessage(6));
chr.getClient().announce(MaplePacketCreator.enableActions());
}
}
@Override
public void sendSpawnData(MapleClient client) {
if (from.getId() == client.getPlayer().getMapId()) {
client.announce(MaplePacketCreator.spawnPortal(this.getFrom().getId(), this.getTo().getId(), this.toPosition()));
if(!this.inTown()) client.announce(MaplePacketCreator.spawnDoor(this.getOwnerId(), this.getPosition(), true));
if (client.getPlayer().getParty() != null && (ownerId == client.getPlayer().getId() || client.getPlayer().getParty().getMemberById(ownerId) != null)) {
client.announce(MaplePacketCreator.partyPortal(this.getTown().getId(), this.getArea().getId(), this.getAreaPosition()));
}
}
}
@Override
public void sendDestroyData(MapleClient client) {
if (from.getId() == client.getPlayer().getMapId()) {
if (client.getPlayer().getParty() != null && (ownerId == client.getPlayer().getId() || client.getPlayer().getParty().getMemberById(ownerId) != null)) {
client.announce(MaplePacketCreator.partyPortal(999999999, 999999999, new Point(-1, -1)));
}
client.announce(MaplePacketCreator.removeDoor(ownerId, isTown));
}
}
public int getOwnerId() {
return ownerId;
}
public void setPairOid(int oid) {
this.pairOid = oid;
}
public int getPairOid() {
return pairOid;
}
public boolean inTown() {
return isTown;
}
public MapleMap getFrom() {
return from;
}
public MapleMap getTo() {
return to;
}
public MapleMap getTown() {
return isTown ? from : to;
}
public MapleMap getArea() {
return !isTown ? from : to;
}
public Point getAreaPosition() {
return !isTown ? getPosition() : toPos;
}
public Point toPosition() {
return toPos;
}
@Override
public MapleMapObjectType getType() {
return MapleMapObjectType.DOOR;
}
}
+60 -7
View File
@@ -45,6 +45,8 @@ import java.util.LinkedHashMap;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
@@ -94,6 +96,7 @@ public class MapleMap {
private Map<Integer, MaplePortal> portals = new HashMap<>(); private Map<Integer, MaplePortal> portals = new HashMap<>();
private Map<Integer, Integer> backgroundTypes = new HashMap<>(); private Map<Integer, Integer> backgroundTypes = new HashMap<>();
private Map<String, Integer> environment = new LinkedHashMap<String, Integer>(); private Map<String, Integer> environment = new LinkedHashMap<String, Integer>();
private Set<Integer> usedDoors = new HashSet<>();
private List<Rectangle> areas = new ArrayList<>(); private List<Rectangle> areas = new ArrayList<>();
private MapleFootholdTree footholds = null; private MapleFootholdTree footholds = null;
private int mapid; private int mapid;
@@ -1360,24 +1363,74 @@ public class MapleMap {
spawnReactor(reactor); spawnReactor(reactor);
} }
public void spawnDoor(final MapleDoor door) { public void spawnDoor(final MapleDoorObject door) {
spawnAndAddRangedMapObject(door, new DelayedPacketCreation() { spawnAndAddRangedMapObject(door, new DelayedPacketCreation() {
@Override @Override
public void sendPackets(MapleClient c) { public void sendPackets(MapleClient c) {
c.announce(MaplePacketCreator.spawnDoor(door.getOwner().getId(), door.getTargetPosition(), false)); if (door.getFrom().getId() == c.getPlayer().getMapId()) {
if (door.getOwner().getParty() != null && (door.getOwner() == c.getPlayer() || door.getOwner().getParty().containsMembers(c.getPlayer().getMPC()))) { c.announce(MaplePacketCreator.spawnPortal(door.getFrom().getId(), door.getTo().getId(), door.toPosition()));
c.announce(MaplePacketCreator.partyPortal(door.getTown().getId(), door.getTarget().getId(), door.getTargetPosition())); if(!door.inTown()) c.announce(MaplePacketCreator.spawnDoor(door.getOwnerId(), door.getPosition(), false));
if (c.getPlayer().getParty() != null && (door.getOwnerId() == c.getPlayer().getId() || c.getPlayer().getParty().getMemberById(door.getOwnerId()) != null)) {
c.announce(MaplePacketCreator.partyPortal(door.getTown().getId(), door.getArea().getId(), door.getAreaPosition()));
} }
c.announce(MaplePacketCreator.spawnPortal(door.getTown().getId(), door.getTarget().getId(), door.getTargetPosition())); }
c.announce(MaplePacketCreator.enableActions()); c.announce(MaplePacketCreator.enableActions());
} }
}, new SpawnCondition() { }, new SpawnCondition() {
@Override @Override
public boolean canSpawn(MapleCharacter chr) { public boolean canSpawn(MapleCharacter chr) {
return chr.getMapId() == door.getTarget().getId() || chr == door.getOwner() && chr.getParty() == null; return chr.getMapId() == door.getFrom().getId();
} }
}); });
}
public boolean setUsingDoorPortal(MaplePortal port) {
objectWLock.lock();
try {
if(usedDoors.contains(port.getId())) return false;
usedDoors.add(port.getId());
return true;
} finally {
objectWLock.unlock();
}
}
public void setDisposeDoorPortal(MaplePortal port) {
objectWLock.lock();
try {
usedDoors.remove(port.getId());
} finally {
objectWLock.unlock();
}
}
public boolean getNotUsingDoorPortal() {
objectRLock.lock();
try {
return usedDoors.isEmpty();
} finally {
objectRLock.unlock();
}
}
public List<MaplePortal> getAvailableDoorPortals() {
objectRLock.lock();
try {
List<MaplePortal> availablePortals = new ArrayList<>();
for (MaplePortal port : getPortals()) {
if (port.getType() == MaplePortal.DOOR_PORTAL && !usedDoors.contains(port.getId())) {
availablePortals.add(port);
}
}
return availablePortals;
} finally {
objectRLock.unlock();
}
} }
public void spawnSummon(final MapleSummon summon) { public void spawnSummon(final MapleSummon summon) {
@@ -2095,7 +2148,7 @@ public class MapleMap {
} }
private void updateMapObjectVisibility(MapleCharacter chr, MapleMapObject mo) { private void updateMapObjectVisibility(MapleCharacter chr, MapleMapObject mo) {
if (!chr.isMapObjectVisible(mo)) { // monster entered view range if (!chr.isMapObjectVisible(mo)) { // item entered view range
if (mo.getType() == MapleMapObjectType.SUMMON || mo.getPosition().distanceSq(chr.getPosition()) <= getRangedDistance()) { if (mo.getType() == MapleMapObjectType.SUMMON || mo.getPosition().distanceSq(chr.getPosition()) <= getRangedDistance()) {
chr.addVisibleMapObject(mo); chr.addVisibleMapObject(mo);
mo.sendSpawnData(chr.getClient()); mo.sendSpawnData(chr.getClient());
+43 -16
View File
@@ -64,6 +64,7 @@ import server.life.MapleNPC;
import server.life.MobSkill; import server.life.MobSkill;
import server.maps.HiredMerchant; import server.maps.HiredMerchant;
import server.maps.MapleDoor; import server.maps.MapleDoor;
import server.maps.MapleDoorObject;
import server.maps.MapleDragon; import server.maps.MapleDragon;
import server.maps.MapleMap; import server.maps.MapleMap;
import server.maps.MapleMapItem; import server.maps.MapleMapItem;
@@ -1056,24 +1057,22 @@ public class MaplePacketCreator {
mplew.writeShort(SendOpcode.SPAWN_PORTAL.getValue()); mplew.writeShort(SendOpcode.SPAWN_PORTAL.getValue());
mplew.writeInt(townId); mplew.writeInt(townId);
mplew.writeInt(targetId); mplew.writeInt(targetId);
if (pos != null) {
mplew.writePos(pos); mplew.writePos(pos);
}
return mplew.getPacket(); return mplew.getPacket();
} }
/** /**
* Gets a packet to spawn a door. * Gets a packet to spawn a door.
* *
* @param oid The door's object ID. * @param oid The door's owner ID.
* @param pos The position of the door. * @param pos The position of the door.
* @param town * @param launched Already deployed the door.
* @return The remove door packet. * @return The remove door packet.
*/ */
public static byte[] spawnDoor(int oid, Point pos, boolean town) { public static byte[] spawnDoor(int oid, Point pos, boolean launched) {
final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(11); final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(11);
mplew.writeShort(SendOpcode.SPAWN_DOOR.getValue()); mplew.writeShort(SendOpcode.SPAWN_DOOR.getValue());
mplew.writeBool(town); mplew.writeBool(launched);
mplew.writeInt(oid); mplew.writeInt(oid);
mplew.writePos(pos); mplew.writePos(pos);
return mplew.getPacket(); return mplew.getPacket();
@@ -3230,11 +3229,25 @@ public class MaplePacketCreator {
mplew.writeShort(0x8b); mplew.writeShort(0x8b);
mplew.writeShort(1); mplew.writeShort(1);
if (partychar.getDoors().size() > 0) { if (partychar.getDoors().size() > 0) {
for (MapleDoor doors : partychar.getDoors()) { boolean deployedPortal = false;
mplew.writeInt(doors.getTown().getId());
mplew.writeInt(doors.getTarget().getId()); for (MapleDoor door : partychar.getDoors()) {
mplew.writeInt(doors.getPosition().x); if(door.getOwnerId() == partychar.getId()) {
mplew.writeInt(doors.getPosition().y); MapleDoorObject mdo = door.getTownDoor();
mplew.writeInt(mdo.getTo().getId());
mplew.writeInt(mdo.getFrom().getId());
mplew.writeInt(mdo.getPosition().x);
mplew.writeInt(mdo.getPosition().y);
deployedPortal = true;
}
}
if(!deployedPortal) {
mplew.writeInt(999999999);
mplew.writeInt(999999999);
mplew.writeInt(0);
mplew.writeInt(0);
} }
} else { } else {
mplew.writeInt(999999999); mplew.writeInt(999999999);
@@ -3322,11 +3335,25 @@ public class MaplePacketCreator {
for (MaplePartyCharacter partychar : partymembers) { for (MaplePartyCharacter partychar : partymembers) {
if (partychar.getChannel() == forchannel && !leaving) { if (partychar.getChannel() == forchannel && !leaving) {
if (partychar.getDoors().size() > 0) { if (partychar.getDoors().size() > 0) {
for (MapleDoor doors : partychar.getDoors()) { boolean deployedPortal = false;
lew.writeInt(doors.getTown().getId());
lew.writeInt(doors.getTarget().getId()); for (MapleDoor door : partychar.getDoors()) {
lew.writeInt(doors.getPosition().x); if(door.getOwnerId() == partychar.getId()) {
lew.writeInt(doors.getPosition().y); MapleDoorObject mdo = door.getTownDoor();
lew.writeInt(mdo.getTown().getId());
lew.writeInt(mdo.getArea().getId());
lew.writeInt(mdo.getPosition().x);
lew.writeInt(mdo.getPosition().y);
deployedPortal = true;
}
}
if(!deployedPortal) {
lew.writeInt(999999999);
lew.writeInt(999999999);
lew.writeInt(0);
lew.writeInt(0);
} }
} else { } else {
lew.writeInt(999999999); lew.writeInt(999999999);