MagatiaPQ + several minor fixes
Added MagatiaPQ. Fixed a bug on Dojo where parties quitting the boss fight without completing until rest point couldn't not start Dojo again w/o reforming the party. Fixed issues with 2nd job NPC scripts. Reverted command layout to use "!" and "@" again.
This commit is contained in:
@@ -445,6 +445,8 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
if (getMap().getEventInstance() != null) {
|
||||
if (!this.getStats().isFriendly()) {
|
||||
getMap().getEventInstance().monsterKilled(this);
|
||||
} else {
|
||||
getMap().getEventInstance().friendlyKilled(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -246,12 +246,12 @@ public class MapleMap {
|
||||
mr.lockReactor();
|
||||
try {
|
||||
mr.setState((byte) 1);
|
||||
mr.setShouldCollect(true);
|
||||
mr.resetReactorActions();
|
||||
|
||||
broadcastMessage(MaplePacketCreator.triggerReactor((MapleReactor) o, 1));
|
||||
} finally {
|
||||
mr.unlockReactor();
|
||||
}
|
||||
|
||||
broadcastMessage(MaplePacketCreator.triggerReactor((MapleReactor) o, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1076,6 +1076,7 @@ public class MapleMap {
|
||||
final MapleReactor reactor = getReactorByOid(oid);
|
||||
TimerManager tMan = TimerManager.getInstance();
|
||||
broadcastMessage(MaplePacketCreator.destroyReactor(reactor));
|
||||
reactor.cancelReactorTimeout();
|
||||
reactor.setAlive(false);
|
||||
removeMapObject(reactor);
|
||||
|
||||
@@ -1099,12 +1100,12 @@ public class MapleMap {
|
||||
r.lockReactor();
|
||||
try {
|
||||
r.setState((byte) 0);
|
||||
r.setShouldCollect(true);
|
||||
r.resetReactorActions();
|
||||
|
||||
broadcastMessage(MaplePacketCreator.triggerReactor(r, 0));
|
||||
} finally {
|
||||
r.unlockReactor();
|
||||
}
|
||||
|
||||
broadcastMessage(MaplePacketCreator.triggerReactor(r, 0));
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
@@ -1547,8 +1548,8 @@ public class MapleMap {
|
||||
private void respawnReactor(final MapleReactor reactor) {
|
||||
reactor.lockReactor();
|
||||
try {
|
||||
reactor.setShouldCollect(true);
|
||||
reactor.setState((byte) 0);
|
||||
reactor.resetReactorActions();
|
||||
reactor.setAlive(true);
|
||||
} finally {
|
||||
reactor.unlockReactor();
|
||||
@@ -1979,7 +1980,7 @@ public class MapleMap {
|
||||
public MaplePortal getRandomPlayerSpawnpoint() {
|
||||
List<MaplePortal> spawnPoints = new ArrayList<>();
|
||||
for (MaplePortal portal : portals.values()) {
|
||||
if (portal.getType() >= 0 && portal.getType() <= 1) {
|
||||
if (portal.getType() >= 0 && portal.getType() <= 1 && portal.getTargetMapId() == 999999999) {
|
||||
spawnPoints.add(portal);
|
||||
}
|
||||
}
|
||||
@@ -2608,13 +2609,14 @@ public class MapleMap {
|
||||
@Override
|
||||
public void run() {
|
||||
reactor.lockReactor();
|
||||
try {
|
||||
reactor.setState((byte) 0);
|
||||
reactor.setShouldCollect(true);
|
||||
} finally {
|
||||
reactor.unlockReactor();
|
||||
}
|
||||
broadcastMessage(MaplePacketCreator.triggerReactor(reactor, 0));
|
||||
try {
|
||||
reactor.setState((byte) 0);
|
||||
reactor.resetReactorActions();
|
||||
|
||||
broadcastMessage(MaplePacketCreator.triggerReactor(reactor, 0));
|
||||
} finally {
|
||||
reactor.unlockReactor();
|
||||
}
|
||||
}
|
||||
}, reactor.getDelay());
|
||||
}
|
||||
|
||||
@@ -293,11 +293,12 @@ public class MapleMapFactory {
|
||||
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.setName(MapleDataTool.getString(reactor.getChildByPath("name"), ""));
|
||||
myReactor.setPosition(new Point(x, y));
|
||||
myReactor.setDelay(MapleDataTool.getInt(reactor.getChildByPath("reactorTime")) * 1000);
|
||||
myReactor.setState((byte) 0);
|
||||
myReactor.setShouldCollect(true);
|
||||
myReactor.setName(MapleDataTool.getString(reactor.getChildByPath("name"), ""));
|
||||
|
||||
myReactor.resetReactorActions();
|
||||
return myReactor;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import constants.ServerConstants;
|
||||
import java.awt.Rectangle;
|
||||
import java.util.List;
|
||||
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
@@ -38,6 +39,7 @@ import tools.Pair;
|
||||
/**
|
||||
*
|
||||
* @author Lerk
|
||||
* @author Ronan
|
||||
*/
|
||||
public class MapleReactor extends AbstractMapleMapObject {
|
||||
private int rid;
|
||||
@@ -50,6 +52,7 @@ public class MapleReactor extends AbstractMapleMapObject {
|
||||
private boolean alive;
|
||||
private boolean shouldCollect;
|
||||
private boolean attackHit;
|
||||
private ScheduledFuture<?> timeoutTask = null;
|
||||
private Lock reactorLock = new ReentrantLock(true);
|
||||
|
||||
public MapleReactor(MapleReactorStats stats, int rid) {
|
||||
@@ -158,16 +161,57 @@ public class MapleReactor extends AbstractMapleMapObject {
|
||||
return MaplePacketCreator.spawnReactor(this);
|
||||
}
|
||||
|
||||
public void resetReactorActions() {
|
||||
cancelReactorTimeout();
|
||||
setShouldCollect(true);
|
||||
refreshReactorTimeout();
|
||||
}
|
||||
|
||||
public void forceHitReactor(final byte newState) {
|
||||
this.lockReactor();
|
||||
try {
|
||||
setState((byte) newState);
|
||||
this.setShouldCollect(true);
|
||||
this.resetReactorActions();
|
||||
|
||||
map.broadcastMessage(MaplePacketCreator.triggerReactor(this, (short) 0));
|
||||
} finally {
|
||||
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;
|
||||
|
||||
map.broadcastMessage(MaplePacketCreator.triggerReactor(this, (short) 0));
|
||||
try {
|
||||
setState((byte) newState);
|
||||
this.resetReactorActions();
|
||||
|
||||
map.broadcastMessage(MaplePacketCreator.triggerReactor(this, (short) 0));
|
||||
} finally {
|
||||
this.unlockReactor();
|
||||
}
|
||||
}
|
||||
|
||||
public void cancelReactorTimeout() {
|
||||
if (timeoutTask != null) {
|
||||
timeoutTask.cancel(false);
|
||||
timeoutTask = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshReactorTimeout() {
|
||||
int timeOut = stats.getTimeout(state);
|
||||
if(timeOut > -1) {
|
||||
final byte nextState = stats.getTimeoutState(state);
|
||||
|
||||
timeoutTask = TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
timeoutTask = null;
|
||||
tryForceHitReactor(nextState);
|
||||
}
|
||||
}, timeOut);
|
||||
}
|
||||
}
|
||||
|
||||
public void delayedHitReactor(final MapleClient c, long delay) {
|
||||
@@ -189,48 +233,57 @@ public class MapleReactor extends AbstractMapleMapObject {
|
||||
return;
|
||||
}
|
||||
|
||||
attackHit = wHit;
|
||||
|
||||
if(ServerConstants.USE_DEBUG == true) c.getPlayer().dropMessage(5, "Hitted REACTOR " + this.getId() + " with POS " + charPos + " , STANCE " + stance + " , SkillID " + skillid + " , STATE " + stats.getType(state) + " STATESIZE " + stats.getStateSize(state));
|
||||
ReactorScriptManager.getInstance().onHit(c, this);
|
||||
|
||||
int reactorType = stats.getType(state);
|
||||
if (reactorType < 999 && reactorType != -1) {//type 2 = only hit from right (kerning swamp plants), 00 is air left 02 is ground left
|
||||
if (!(reactorType == 2 && (stance == 0 || stance == 2))) { //get next state
|
||||
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;
|
||||
}
|
||||
state = stats.getNextState(state, b);
|
||||
if (stats.getNextState(state, b) == -1) {//end of reactor
|
||||
if (reactorType < 100) {//reactor broken
|
||||
if (delay > 0) {
|
||||
map.destroyReactor(getObjectId());
|
||||
} else {//trigger as normal
|
||||
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));
|
||||
ReactorScriptManager.getInstance().onHit(c, this);
|
||||
|
||||
int reactorType = stats.getType(state);
|
||||
if (reactorType < 999 && reactorType != -1) {//type 2 = only hit from right (kerning swamp plants), 00 is air left 02 is ground left
|
||||
if (!(reactorType == 2 && (stance == 0 || stance == 2))) { //get next state
|
||||
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;
|
||||
}
|
||||
state = stats.getNextState(state, b);
|
||||
if (stats.getNextState(state, b) == -1) {//end of reactor
|
||||
if (reactorType < 100) {//reactor broken
|
||||
if (delay > 0) {
|
||||
map.destroyReactor(getObjectId());
|
||||
} else {//trigger as normal
|
||||
map.broadcastMessage(MaplePacketCreator.triggerReactor(this, stance));
|
||||
}
|
||||
} else {//item-triggered on final step
|
||||
map.broadcastMessage(MaplePacketCreator.triggerReactor(this, stance));
|
||||
}
|
||||
} else {//item-triggered on final step
|
||||
map.broadcastMessage(MaplePacketCreator.triggerReactor(this, stance));
|
||||
}
|
||||
|
||||
ReactorScriptManager.getInstance().act(c, this);
|
||||
} else { //reactor not broken yet
|
||||
map.broadcastMessage(MaplePacketCreator.triggerReactor(this, stance));
|
||||
if (state == stats.getNextState(state, b)) {//current state = next state, looping reactor
|
||||
|
||||
ReactorScriptManager.getInstance().act(c, this);
|
||||
} else { //reactor not broken yet
|
||||
map.broadcastMessage(MaplePacketCreator.triggerReactor(this, stance));
|
||||
if (state == stats.getNextState(state, b)) {//current state = next state, looping reactor
|
||||
ReactorScriptManager.getInstance().act(c, this);
|
||||
}
|
||||
|
||||
setShouldCollect(true); // refresh collectability on item drop-based reactors
|
||||
refreshReactorTimeout();
|
||||
}
|
||||
|
||||
setShouldCollect(true); // refresh collectability on item drop-based reactors
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
state++;
|
||||
map.broadcastMessage(MaplePacketCreator.triggerReactor(this, stance));
|
||||
ReactorScriptManager.getInstance().act(c, this);
|
||||
|
||||
setShouldCollect(true);
|
||||
refreshReactorTimeout();
|
||||
}
|
||||
} else {
|
||||
state++;
|
||||
map.broadcastMessage(MaplePacketCreator.triggerReactor(this, stance));
|
||||
ReactorScriptManager.getInstance().act(c, this);
|
||||
setShouldCollect(true);
|
||||
} finally {
|
||||
this.unlockReactor();
|
||||
}
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
@@ -57,46 +57,51 @@ public class MapleReactorFactory {
|
||||
reactorData = data.getData(StringUtil.getLeftPaddedStr(Integer.toString(infoId) + ".img", '0', 11));
|
||||
MapleData reactorInfoData = reactorData.getChildByPath("0");
|
||||
stats = new MapleReactorStats();
|
||||
List<StateData> statedatas = new ArrayList<StateData>();
|
||||
List<StateData> statedatas = new ArrayList<>();
|
||||
if (reactorInfoData != null) {
|
||||
boolean areaSet = false;
|
||||
byte i = 0;
|
||||
while (reactorInfoData != null) {
|
||||
MapleData eventData = reactorInfoData.getChildByPath("event");
|
||||
if (eventData != null) {
|
||||
int timeOut = -1;
|
||||
|
||||
for (MapleData fknexon : eventData.getChildren()) {
|
||||
if (fknexon.getName().equals("timeOut")) continue;
|
||||
Pair<Integer, Integer> reactItem = null;
|
||||
int type = MapleDataTool.getIntConvert("type", fknexon);
|
||||
if (type == 100) { //reactor waits for item
|
||||
reactItem = new Pair<Integer, Integer>(MapleDataTool.getIntConvert("0", fknexon), MapleDataTool.getIntConvert("1", fknexon));
|
||||
if (!areaSet || loadArea) { //only set area of effect for item-triggered reactors once
|
||||
stats.setTL(MapleDataTool.getPoint("lt", fknexon));
|
||||
stats.setBR(MapleDataTool.getPoint("rb", fknexon));
|
||||
areaSet = true;
|
||||
if (fknexon.getName().equals("timeOut")) {
|
||||
timeOut = MapleDataTool.getInt(fknexon);
|
||||
} else {
|
||||
Pair<Integer, Integer> reactItem = null;
|
||||
int type = MapleDataTool.getIntConvert("type", fknexon);
|
||||
if (type == 100) { //reactor waits for item
|
||||
reactItem = new Pair<Integer, Integer>(MapleDataTool.getIntConvert("0", fknexon), MapleDataTool.getIntConvert("1", fknexon));
|
||||
if (!areaSet || loadArea) { //only set area of effect for item-triggered reactors once
|
||||
stats.setTL(MapleDataTool.getPoint("lt", fknexon));
|
||||
stats.setBR(MapleDataTool.getPoint("rb", fknexon));
|
||||
areaSet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
MapleData activeSkillID = fknexon.getChildByPath("activeSkillID");
|
||||
List<Integer> skillids = null;
|
||||
if (activeSkillID != null) {
|
||||
skillids = new ArrayList<Integer>();
|
||||
for (MapleData skill : activeSkillID.getChildren()) {
|
||||
skillids.add(MapleDataTool.getInt(skill));
|
||||
MapleData activeSkillID = fknexon.getChildByPath("activeSkillID");
|
||||
List<Integer> skillids = null;
|
||||
if (activeSkillID != null) {
|
||||
skillids = new ArrayList<Integer>();
|
||||
for (MapleData skill : activeSkillID.getChildren()) {
|
||||
skillids.add(MapleDataTool.getInt(skill));
|
||||
}
|
||||
}
|
||||
byte nextState = (byte) MapleDataTool.getIntConvert("state", fknexon);
|
||||
statedatas.add(new StateData(type, reactItem, skillids, nextState));
|
||||
}
|
||||
byte nextState = (byte) MapleDataTool.getIntConvert("state", fknexon);
|
||||
statedatas.add(new StateData(type, reactItem, skillids, nextState));
|
||||
}
|
||||
stats.addState(i, statedatas);
|
||||
stats.addState(i, statedatas, timeOut);
|
||||
}
|
||||
i++;
|
||||
reactorInfoData = reactorData.getChildByPath(Byte.toString(i));
|
||||
statedatas = new ArrayList<StateData>();
|
||||
statedatas = new ArrayList<>();
|
||||
}
|
||||
} else //sit there and look pretty; likely a reactor such as Zakum/Papulatus doors that shows if player can enter
|
||||
{
|
||||
statedatas.add(new StateData(999, null, null, (byte) 0));
|
||||
stats.addState((byte) 0, statedatas);
|
||||
stats.addState((byte) 0, statedatas, -1);
|
||||
}
|
||||
reactorStats.put(Integer.valueOf(infoId), stats);
|
||||
if (rid != infoId) {
|
||||
|
||||
@@ -29,11 +29,13 @@ import tools.Pair;
|
||||
|
||||
/**
|
||||
* @author Lerk
|
||||
* @author Ronan
|
||||
*/
|
||||
public class MapleReactorStats {
|
||||
private Point tl;
|
||||
private Point br;
|
||||
private Map<Byte, List<StateData>> stateInfo = new HashMap<Byte, List<StateData>>();
|
||||
private Map<Byte, List<StateData>> stateInfo = new HashMap<>();
|
||||
private Map<Byte, Integer> timeoutInfo = new HashMap<>();
|
||||
|
||||
public void setTL(Point tl) {
|
||||
this.tl = tl;
|
||||
@@ -51,8 +53,18 @@ public class MapleReactorStats {
|
||||
return br;
|
||||
}
|
||||
|
||||
public void addState(byte state, List<StateData> data) {
|
||||
public void addState(byte state, List<StateData> data, int timeOut) {
|
||||
stateInfo.put(state, data);
|
||||
if(timeOut > -1) timeoutInfo.put(state, timeOut);
|
||||
}
|
||||
|
||||
public int getTimeout(byte state) {
|
||||
Integer i = timeoutInfo.get(state);
|
||||
return (i == null) ? -1 : i;
|
||||
}
|
||||
|
||||
public byte getTimeoutState(byte state) {
|
||||
return stateInfo.get(state).get(stateInfo.get(state).size() - 1).getNextState();
|
||||
}
|
||||
|
||||
public byte getStateSize(byte state) {
|
||||
|
||||
Reference in New Issue
Block a user