Knights' Seal & I. MaxHP + Adherent mob status + Script point-warps
Fixed Seal skill not working for Blaze Wizard. Added a check against Seal skill on bosses. Reviewed improper usage of "random spawn point arrival" at several warps on scripts. Refactored CPQ modules fetching players from the channel storage, this should be unneeded after a recent update on the player object from MPC. Added door objects as a visible map object for the player server-side view component. Fixed a few scenarios where mobs would unexpectedly show up impervious to mob status. Fixed scenario where a player wouldn't receive disease informations from other players after changing maps. Fixed some magic-type skills (such as Magic Claw or Freeze) not displaying damage value for other players when the player is within melee-range from the mob. Added check for whether a given quest is scripted before trying to find the script. Fixed registering items onto MTS leading to loss of a few of its properties (expiration, item level, etc). Fixed "Improved MaxHP" skill gains not working for Thunderbreakers. Refactored pet autopot to also apply on HP/MP consumption by items/skills. Added portal sound effect on Mystic Doors.
This commit is contained in:
@@ -26,5 +26,6 @@ package client;
|
||||
public interface AbstractCharacterListener {
|
||||
public void onHpChanged(int oldHp);
|
||||
public void onHpmpPoolUpdate();
|
||||
public void onStatUpdate();
|
||||
public void onAnnounceStatPoolUpdate();
|
||||
}
|
||||
|
||||
@@ -220,6 +220,10 @@ public abstract class AbstractMapleCharacterObject extends AbstractAnimatedMaple
|
||||
listener.onHpmpPoolUpdate();
|
||||
}
|
||||
|
||||
private void dispatchStatUpdated() {
|
||||
listener.onStatUpdate();
|
||||
}
|
||||
|
||||
private void dispatchStatPoolUpdateAnnounced() {
|
||||
listener.onAnnounceStatPoolUpdate();
|
||||
}
|
||||
@@ -299,6 +303,7 @@ public abstract class AbstractMapleCharacterObject extends AbstractAnimatedMaple
|
||||
try {
|
||||
statUpdates.clear();
|
||||
boolean poolUpdate = false;
|
||||
boolean statUpdate = false;
|
||||
|
||||
if (hpMpPool != null) {
|
||||
short newHp = (short) (hpMpPool >> 48);
|
||||
@@ -370,7 +375,7 @@ public abstract class AbstractMapleCharacterObject extends AbstractAnimatedMaple
|
||||
statUpdates.put(MapleStat.AVAILABLEAP, remainingAp);
|
||||
}
|
||||
|
||||
poolUpdate = true; // recalc stats
|
||||
statUpdate = true;
|
||||
}
|
||||
|
||||
if (newSp != null) {
|
||||
@@ -385,6 +390,10 @@ public abstract class AbstractMapleCharacterObject extends AbstractAnimatedMaple
|
||||
if (poolUpdate) {
|
||||
dispatchHpmpPoolUpdated();
|
||||
}
|
||||
|
||||
if (statUpdate) {
|
||||
dispatchStatUpdated();
|
||||
}
|
||||
|
||||
if (!silent) {
|
||||
dispatchStatPoolUpdateAnnounced();
|
||||
|
||||
@@ -91,6 +91,7 @@ import server.life.MobSkillFactory;
|
||||
import server.maps.FieldLimit;
|
||||
import server.maps.MapleHiredMerchant;
|
||||
import server.maps.MapleDoor;
|
||||
import server.maps.MapleDoorObject;
|
||||
import server.maps.MapleDragon;
|
||||
import server.maps.MapleMap;
|
||||
import server.maps.MapleMapEffect;
|
||||
@@ -136,6 +137,7 @@ import client.inventory.manipulator.MapleCashidGenerator;
|
||||
import client.inventory.manipulator.MapleInventoryManipulator;
|
||||
import client.newyear.NewYearCardRecord;
|
||||
import client.processor.FredrickProcessor;
|
||||
import client.processor.PetAutopotProcessor;
|
||||
import constants.ExpTable;
|
||||
import constants.GameConstants;
|
||||
import constants.ItemConstants;
|
||||
@@ -145,6 +147,7 @@ import constants.skills.Beginner;
|
||||
import constants.skills.Bishop;
|
||||
import constants.skills.BlazeWizard;
|
||||
import constants.skills.Bowmaster;
|
||||
import constants.skills.Brawler;
|
||||
import constants.skills.Buccaneer;
|
||||
import constants.skills.Corsair;
|
||||
import constants.skills.Crusader;
|
||||
@@ -166,7 +169,7 @@ import constants.skills.Priest;
|
||||
import constants.skills.Ranger;
|
||||
import constants.skills.Shadower;
|
||||
import constants.skills.Sniper;
|
||||
import constants.skills.Swordsman;
|
||||
import constants.skills.Warrior;
|
||||
import constants.skills.ThunderBreaker;
|
||||
import org.apache.mina.util.ConcurrentHashSet;
|
||||
|
||||
@@ -357,6 +360,11 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatUpdate() {
|
||||
recalcLocalStats();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnnounceStatPoolUpdate() {
|
||||
List<Pair<MapleStat, Integer>> statup = new ArrayList<>(8);
|
||||
@@ -1647,7 +1655,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
|
||||
for(MapleDoor door : partyDoors.values()) {
|
||||
for(MapleCharacter pchar : partyMembers) {
|
||||
door.getTownDoor().sendDestroyData(pchar.getClient(), true);
|
||||
MapleDoorObject mdo = door.getTownDoor();
|
||||
mdo.sendDestroyData(pchar.getClient(), true);
|
||||
pchar.removeVisibleMapObject(mdo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1655,7 +1665,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
Collection<MapleDoor> leaverDoors = partyLeaver.getDoors();
|
||||
for(MapleDoor door : leaverDoors) {
|
||||
for(MapleCharacter pchar : partyMembers) {
|
||||
door.getTownDoor().sendDestroyData(pchar.getClient(), true);
|
||||
MapleDoorObject mdo = door.getTownDoor();
|
||||
mdo.sendDestroyData(pchar.getClient(), true);
|
||||
pchar.removeVisibleMapObject(mdo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1666,7 +1678,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
|
||||
if(door != null) {
|
||||
for(MapleCharacter pchar : partyMembers) {
|
||||
door.getTownDoor().sendSpawnData(pchar.getClient());
|
||||
MapleDoorObject mdo = door.getTownDoor();
|
||||
mdo.sendSpawnData(pchar.getClient());
|
||||
pchar.addVisibleMapObject(mdo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1677,17 +1691,24 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
|
||||
if(partyDoors != null) {
|
||||
for(MapleDoor door : partyDoors.values()) {
|
||||
door.getTownDoor().sendDestroyData(partyLeaver.getClient(), true);
|
||||
MapleDoorObject mdo = door.getTownDoor();
|
||||
mdo.sendDestroyData(partyLeaver.getClient(), true);
|
||||
partyLeaver.removeVisibleMapObject(mdo);
|
||||
}
|
||||
}
|
||||
|
||||
for(MapleDoor door : leaverDoors) {
|
||||
door.getTownDoor().sendDestroyData(partyLeaver.getClient(), true);
|
||||
MapleDoorObject mdo = door.getTownDoor();
|
||||
mdo.sendDestroyData(partyLeaver.getClient(), true);
|
||||
partyLeaver.removeVisibleMapObject(mdo);
|
||||
}
|
||||
|
||||
for(MapleDoor door : leaverDoors) {
|
||||
door.updateDoorPortal(partyLeaver);
|
||||
door.getTownDoor().sendSpawnData(partyLeaver.getClient());
|
||||
|
||||
MapleDoorObject mdo = door.getTownDoor();
|
||||
mdo.sendSpawnData(partyLeaver.getClient());
|
||||
partyLeaver.addVisibleMapObject(mdo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2697,6 +2718,24 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
}
|
||||
}
|
||||
|
||||
public void collectDiseases() {
|
||||
for (MapleCharacter chr : map.getAllPlayers()) {
|
||||
int cid = chr.getId();
|
||||
|
||||
for (Entry<MapleDisease, Pair<Long, MobSkill>> di : chr.getAllDiseases().entrySet()) {
|
||||
MapleDisease disease = di.getKey();
|
||||
MobSkill skill = di.getValue().getRight();
|
||||
final List<Pair<MapleDisease, Integer>> debuff = Collections.singletonList(new Pair<>(disease, Integer.valueOf(skill.getX())));
|
||||
|
||||
if (disease != MapleDisease.SLOW) {
|
||||
this.announce(MaplePacketCreator.giveForeignDebuff(cid, debuff, skill));
|
||||
} else {
|
||||
this.announce(MaplePacketCreator.giveForeignSlowDebuff(cid, debuff, skill));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void giveDebuff(final MapleDisease disease, MobSkill skill) {
|
||||
if (!hasDisease(disease) && getDiseasesSize() < 2) {
|
||||
if (!(disease == MapleDisease.SEDUCE || disease == MapleDisease.STUN)) {
|
||||
@@ -6063,12 +6102,8 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
}
|
||||
|
||||
public boolean hasEntered(String script, int mapId) {
|
||||
if (entered.containsKey(mapId)) {
|
||||
if (entered.get(mapId).equals(script)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
String e = entered.get(mapId);
|
||||
return script.equals(e);
|
||||
}
|
||||
|
||||
public void hasGivenFame(MapleCharacter to) {
|
||||
@@ -6416,7 +6451,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
addhp += Randomizer.rand(12, 16);
|
||||
addmp += Randomizer.rand(10, 12);
|
||||
} else if (job.isA(MapleJob.WARRIOR) || job.isA(MapleJob.DAWNWARRIOR1)) {
|
||||
improvingMaxHP = isCygnus() ? SkillFactory.getSkill(DawnWarrior.MAX_HP_INCREASE) : SkillFactory.getSkill(Swordsman.IMPROVED_MAX_HP_INCREASE);
|
||||
improvingMaxHP = isCygnus() ? SkillFactory.getSkill(DawnWarrior.MAX_HP_INCREASE) : SkillFactory.getSkill(Warrior.IMPROVED_MAXHP);
|
||||
if (job.isA(MapleJob.CRUSADER)) {
|
||||
improvingMaxMP = SkillFactory.getSkill(1210000);
|
||||
} else if (job.isA(MapleJob.DAWNWARRIOR2)) {
|
||||
@@ -6437,7 +6472,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
addhp += 30000;
|
||||
addmp += 30000;
|
||||
} else if (job.isA(MapleJob.PIRATE) || job.isA(MapleJob.THUNDERBREAKER1)) {
|
||||
improvingMaxHP = isCygnus() ? SkillFactory.getSkill(ThunderBreaker.IMPROVE_MAX_HP) : SkillFactory.getSkill(5100000);
|
||||
improvingMaxHP = isCygnus() ? SkillFactory.getSkill(ThunderBreaker.IMPROVE_MAX_HP) : SkillFactory.getSkill(Brawler.IMPROVE_MAX_HP);
|
||||
improvingMaxHPLevel = getSkillLevel(improvingMaxHP);
|
||||
addhp += Randomizer.rand(22, 28);
|
||||
addmp += Randomizer.rand(18, 23);
|
||||
@@ -6446,7 +6481,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
int aids = Randomizer.rand(4, 8);
|
||||
addmp += aids + Math.floor(aids * 0.1);
|
||||
}
|
||||
if (improvingMaxHPLevel > 0 && (job.isA(MapleJob.WARRIOR) || job.isA(MapleJob.PIRATE) || job.isA(MapleJob.DAWNWARRIOR1))) {
|
||||
if (improvingMaxHPLevel > 0 && (job.isA(MapleJob.WARRIOR) || job.isA(MapleJob.PIRATE) || job.isA(MapleJob.DAWNWARRIOR1) || job.isA(MapleJob.THUNDERBREAKER1))) {
|
||||
addhp += improvingMaxHP.getEffect(improvingMaxHPLevel).getX();
|
||||
}
|
||||
if (improvingMaxMPLevel > 0 && (job.isA(MapleJob.MAGICIAN) || job.isA(MapleJob.CRUSADER) || job.isA(MapleJob.BLAZEWIZARD1))) {
|
||||
@@ -7920,7 +7955,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
client.announce(MaplePacketCreator.updatePlayerStats(hpmpupdate, true, this));
|
||||
}
|
||||
|
||||
if (oldmaxhp != localmaxhp) {
|
||||
if (oldmaxhp != localmaxhp) { // thanks Wh1SK3Y for pointing out a deadlock occuring related to party members HP
|
||||
updatePartyMemberHP();
|
||||
}
|
||||
} finally {
|
||||
@@ -8072,15 +8107,11 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
}
|
||||
|
||||
public void resetEnteredScript() {
|
||||
if (entered.containsKey(map.getId())) {
|
||||
entered.remove(map.getId());
|
||||
}
|
||||
entered.remove(map.getId());
|
||||
}
|
||||
|
||||
public void resetEnteredScript(int mapId) {
|
||||
if (entered.containsKey(mapId)) {
|
||||
entered.remove(mapId);
|
||||
}
|
||||
entered.remove(mapId);
|
||||
}
|
||||
|
||||
public void resetEnteredScript(String script) {
|
||||
@@ -9102,11 +9133,35 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
}
|
||||
|
||||
updateHpMp(nextHp, nextMp);
|
||||
return true;
|
||||
} finally {
|
||||
statWlock.unlock();
|
||||
effLock.unlock();
|
||||
}
|
||||
|
||||
// autopot on HPMP deplete... thanks shavit for finding out D. Roar doesn't trigger autopot request
|
||||
if (hpchange < 0) {
|
||||
MapleKeyBinding autohpPot = this.getKeymap().get(91);
|
||||
if (autohpPot != null) {
|
||||
int autohpItemid = autohpPot.getAction();
|
||||
Item autohpItem = this.getInventory(MapleInventoryType.USE).findById(autohpItemid);
|
||||
if (autohpItem != null) {
|
||||
PetAutopotProcessor.runAutopotAction(client, autohpItem.getPosition(), autohpItemid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mpchange < 0) {
|
||||
MapleKeyBinding autompPot = this.getKeymap().get(92);
|
||||
if (autompPot != null) {
|
||||
int autompItemid = autompPot.getAction();
|
||||
Item autompItem = this.getInventory(MapleInventoryType.USE).findById(autompItemid);
|
||||
if (autompItem != null) {
|
||||
PetAutopotProcessor.runAutopotAction(client, autompItem.getPosition(), autompItemid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setInventory(MapleInventoryType type, MapleInventory inv) {
|
||||
|
||||
@@ -217,7 +217,11 @@ public class MapleFamily {
|
||||
int repsToSenior = rsEntries.getInt("reptosenior");
|
||||
String precepts = rsEntries.getString("precepts");
|
||||
//Timestamp lastResetTime = rsEntries.getTimestamp("lastresettime"); //taken care of by FamilyDailyResetWorker
|
||||
MapleFamily family = Server.getInstance().getWorld(world).getFamily(familyid);
|
||||
World wserv = Server.getInstance().getWorld(world);
|
||||
if (wserv == null) {
|
||||
continue;
|
||||
}
|
||||
MapleFamily family = wserv.getFamily(familyid);
|
||||
if(family == null) {
|
||||
family = new MapleFamily(familyid, world);
|
||||
Server.getInstance().getWorld(world).addFamily(familyid, family);
|
||||
|
||||
@@ -68,7 +68,7 @@ import constants.skills.Shadower;
|
||||
import constants.skills.Sniper;
|
||||
import constants.skills.Spearman;
|
||||
import constants.skills.SuperGM;
|
||||
import constants.skills.Swordsman;
|
||||
import constants.skills.Warrior;
|
||||
import constants.skills.ThunderBreaker;
|
||||
import constants.skills.WhiteKnight;
|
||||
import constants.skills.WindArcher;
|
||||
@@ -189,7 +189,7 @@ public class SkillFactory {
|
||||
case Beginner.MONSTER_RIDER:
|
||||
case Beginner.ECHO_OF_HERO:
|
||||
case Beginner.MAP_CHAIR:
|
||||
case Swordsman.IRON_BODY:
|
||||
case Warrior.IRON_BODY:
|
||||
case Fighter.AXE_BOOSTER:
|
||||
case Fighter.POWER_GUARD:
|
||||
case Fighter.RAGE:
|
||||
|
||||
@@ -38,6 +38,7 @@ import constants.skills.BlazeWizard;
|
||||
import constants.skills.Brawler;
|
||||
import constants.skills.DawnWarrior;
|
||||
import constants.skills.Magician;
|
||||
import constants.skills.ThunderBreaker;
|
||||
import constants.skills.Warrior;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -697,7 +698,7 @@ public class AssignAPProcessor {
|
||||
}
|
||||
} else if (job.isA(MapleJob.PIRATE) || job.isA(MapleJob.THUNDERBREAKER1)) {
|
||||
if(!usedAPReset) {
|
||||
Skill increaseHP = SkillFactory.getSkill(Brawler.IMPROVE_MAX_HP);
|
||||
Skill increaseHP = SkillFactory.getSkill(job.isA(MapleJob.PIRATE) ? Brawler.IMPROVE_MAX_HP : ThunderBreaker.IMPROVE_MAX_HP);
|
||||
int sLvl = player.getSkillLevel(increaseHP);
|
||||
|
||||
if(sLvl > 0)
|
||||
|
||||
@@ -37,7 +37,6 @@ import java.sql.Timestamp;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import client.inventory.manipulator.MapleInventoryManipulator;
|
||||
import constants.ServerConstants;
|
||||
import java.util.Collections;
|
||||
import net.server.Server;
|
||||
import net.server.world.World;
|
||||
|
||||
178
src/client/processor/PetAutopotProcessor.java
Normal file
178
src/client/processor/PetAutopotProcessor.java
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
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>
|
||||
|
||||
Copyleft (L) 2016 - 2019 RonanLana (HeavenMS)
|
||||
|
||||
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 client.processor;
|
||||
|
||||
import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import client.inventory.Item;
|
||||
import client.inventory.MapleInventory;
|
||||
import client.inventory.MapleInventoryType;
|
||||
import client.inventory.manipulator.MapleInventoryManipulator;
|
||||
import constants.ServerConstants;
|
||||
import java.util.List;
|
||||
import server.MapleItemInformationProvider;
|
||||
import server.MapleStatEffect;
|
||||
import tools.MaplePacketCreator;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Ronan - multi-pot consumption feature
|
||||
*/
|
||||
public class PetAutopotProcessor {
|
||||
|
||||
private static class AutopotAction {
|
||||
|
||||
private MapleClient c;
|
||||
private short slot;
|
||||
private int itemId;
|
||||
|
||||
private Item toUse;
|
||||
private List<Item> toUseList;
|
||||
|
||||
private boolean hasHpGain, hasMpGain;
|
||||
private int maxHp, maxMp, curHp, curMp;
|
||||
private double incHp, incMp;
|
||||
|
||||
private boolean cursorOnNextAvailablePot(MapleCharacter chr) {
|
||||
if(toUseList == null) {
|
||||
toUseList = chr.getInventory(MapleInventoryType.USE).linkedListById(itemId);
|
||||
}
|
||||
|
||||
toUse = null;
|
||||
while(!toUseList.isEmpty()) {
|
||||
Item it = toUseList.remove(0);
|
||||
|
||||
if(it.getQuantity() > 0) {
|
||||
toUse = it;
|
||||
slot = it.getPosition();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public AutopotAction(MapleClient c, short slot, int itemId) {
|
||||
this.c = c;
|
||||
this.slot = slot;
|
||||
this.itemId = itemId;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
MapleClient c = this.c;
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
if (!chr.isAlive()) {
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
|
||||
int useCount = 0, qtyCount = 0;
|
||||
MapleStatEffect stat = null;
|
||||
|
||||
MapleInventory useInv = chr.getInventory(MapleInventoryType.USE);
|
||||
useInv.lockInventory();
|
||||
try {
|
||||
toUse = useInv.getItem(slot);
|
||||
if (toUse != null) {
|
||||
if (toUse.getItemId() != itemId) {
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
|
||||
toUseList = null;
|
||||
|
||||
// from now on, toUse becomes the "cursor" for the current pot being used
|
||||
if (toUse.getQuantity() <= 0) {
|
||||
if (!cursorOnNextAvailablePot(chr)) {
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
stat = MapleItemInformationProvider.getInstance().getItemEffect(toUse.getItemId());
|
||||
hasHpGain = stat.getHp() > 0 || stat.getHpRate() > 0.0;
|
||||
hasMpGain = stat.getMp() > 0 || stat.getMpRate() > 0.0;
|
||||
|
||||
maxHp = chr.getCurrentMaxHp();
|
||||
maxMp = chr.getCurrentMaxMp();
|
||||
|
||||
curHp = chr.getHp();
|
||||
curMp = chr.getMp();
|
||||
|
||||
incHp = stat.getHp();
|
||||
if(incHp <= 0 && hasHpGain) incHp = Math.ceil(maxHp * stat.getHpRate());
|
||||
|
||||
incMp = stat.getMp();
|
||||
if(incMp <= 0 && hasMpGain) incMp = Math.ceil(maxMp * stat.getMpRate());
|
||||
|
||||
if (ServerConstants.USE_COMPULSORY_AUTOPOT) {
|
||||
if (hasHpGain) {
|
||||
qtyCount = (int) Math.ceil(((ServerConstants.PET_AUTOHP_RATIO * maxHp) - curHp) / incHp);
|
||||
}
|
||||
|
||||
if (hasMpGain) {
|
||||
qtyCount = Math.max(qtyCount, (int) Math.ceil(((ServerConstants.PET_AUTOMP_RATIO * maxMp) - curMp) / incMp));
|
||||
}
|
||||
} else {
|
||||
qtyCount = 1; // non-compulsory autopot concept thanks to marcuswoon
|
||||
}
|
||||
|
||||
while (true) {
|
||||
short qtyToUse = (short) Math.min(qtyCount, toUse.getQuantity());
|
||||
MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.USE, slot, qtyToUse, false);
|
||||
|
||||
curHp += (incHp * qtyToUse);
|
||||
curMp += (incMp * qtyToUse);
|
||||
|
||||
useCount += qtyToUse;
|
||||
qtyCount -= qtyToUse;
|
||||
|
||||
if(toUse.getQuantity() == 0 && qtyCount > 0) {
|
||||
// depleted out the current slot, fetch for more
|
||||
|
||||
if(!cursorOnNextAvailablePot(chr)) {
|
||||
break; // no more pots available
|
||||
}
|
||||
} else {
|
||||
break; // gracefully finished it's job, quit the loop
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
useInv.unlockInventory();
|
||||
}
|
||||
|
||||
for (int i = 0; i < useCount; i++) {
|
||||
stat.applyTo(chr);
|
||||
}
|
||||
|
||||
chr.announce(MaplePacketCreator.enableActions());
|
||||
}
|
||||
}
|
||||
|
||||
public static void runAutopotAction(MapleClient c, short slot, int itemid) {
|
||||
AutopotAction action = new AutopotAction(c, slot, itemid);
|
||||
action.run();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -135,7 +135,7 @@ public class ServerConstants {
|
||||
public static final boolean USE_MAKER_FEE_HEURISTICS = true; //Apply compiled values for stimulants and reagents into the Maker fee calculations (max error revolves around 50k mesos). Set false to use basic constant values instead (results are never higher than requested by the client-side).
|
||||
|
||||
//Custom Configuration
|
||||
public static final boolean USE_ENABLE_CUSTOM_NPC_SCRIPT = true;//Enables usage of custom HeavenMS NPC scripts (Agent E, Coco, etc). Will not disable Abdula (it's actually useful for the gameplay), quests or NPC shops.
|
||||
public static final boolean USE_ENABLE_CUSTOM_NPC_SCRIPT = true;//Enables usage of custom HeavenMS NPC scripts (Agent E, Coco, etc). Will not disable Abdula (it's actually useful for the gameplay) or quests.
|
||||
public static final boolean USE_STARTER_MERGE = false; //Allows any players to use the Equipment Merge custom mechanic (as opposed to the high-level, Maker lv3 requisites).
|
||||
|
||||
//Commands Configuration
|
||||
|
||||
@@ -47,7 +47,6 @@ public class Aran {
|
||||
public static final int HIDDEN_FULL_TRIPLE = 21110008;
|
||||
public static final int SMART_KNOCKBACK = 21111001;
|
||||
public static final int OVER_SWING = 21120002;
|
||||
public static final int HIGH_DEFENSE = 21120004;
|
||||
public static final int COMBO_TEMPEST = 21120006;
|
||||
public static final int COMBO_BARRIER = 21120007;
|
||||
public static final int HIDDEN_OVER_DOUBLE = 21120009;
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
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 constants.skills;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BubblesDev
|
||||
*/
|
||||
public class Swordsman {
|
||||
public static final int IMPROVED_MAX_HP_INCREASE = 1000001;
|
||||
public static final int IRON_BODY = 1000003;
|
||||
}
|
||||
@@ -11,4 +11,5 @@ package constants.skills;
|
||||
public class Warrior {
|
||||
public static final int IMPROVED_HPREC = 1000000;
|
||||
public static final int IMPROVED_MAXHP = 1000001;
|
||||
public static final int IRON_BODY = 1000003;
|
||||
}
|
||||
|
||||
@@ -677,6 +677,7 @@ public class Server {
|
||||
MapleCharacter player = c.getPlayer();
|
||||
if(player != null && player.isLoggedinWorld()) {
|
||||
player.announceDiseases();
|
||||
player.collectDiseases();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1111,18 +1112,25 @@ public class Server {
|
||||
|
||||
public MapleGuild getGuild(int id, int world, MapleCharacter mc) {
|
||||
synchronized (guilds) {
|
||||
if (guilds.get(id) != null) {
|
||||
return guilds.get(id);
|
||||
MapleGuild g = guilds.get(id);
|
||||
if (g != null) {
|
||||
return g;
|
||||
}
|
||||
MapleGuild g = new MapleGuild(id, world);
|
||||
|
||||
g = new MapleGuild(id, world);
|
||||
if (g.getId() == -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if(mc != null) {
|
||||
mc.setMGC(g.getMGC(mc.getId()));
|
||||
if(g.getMGC(mc.getId()) == null) System.out.println("null for " + mc.getName() + " when loading guild " + id);
|
||||
g.getMGC(mc.getId()).setCharacter(mc);
|
||||
MapleGuildCharacter mgc = g.getMGC(mc.getId());
|
||||
if (mgc != null) {
|
||||
mc.setMGC(mgc);
|
||||
mgc.setCharacter(mc);
|
||||
} else {
|
||||
FilePrinter.printError(FilePrinter.GUILD_CHAR_ERROR, "Could not find " + mc.getName() + " when loading guild " + id + ".");
|
||||
}
|
||||
|
||||
g.setOnline(mc.getId(), true, mc.getClient().getChannel());
|
||||
}
|
||||
|
||||
|
||||
@@ -653,16 +653,16 @@ public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandl
|
||||
|
||||
// Find the base damage to base futher calculations on.
|
||||
// Several skills have their own formula in this section.
|
||||
long calcDmgMax = 0;
|
||||
long calcDmgMax = 0;
|
||||
|
||||
if(magic && ret.skill != 0) {
|
||||
calcDmgMax = (chr.getTotalMagic() * chr.getTotalMagic() / 1000 + chr.getTotalMagic()) / 30 + chr.getTotalInt() / 200;
|
||||
if(magic && ret.skill != 0) { // thanks onechord for noticing a few false positives stemming from maxdmg as 0
|
||||
calcDmgMax = (long) (Math.ceil((chr.getTotalMagic() * Math.ceil(chr.getTotalMagic() / 1000.0) + chr.getTotalMagic()) / 30.0) + Math.ceil(chr.getTotalInt() / 200.0));
|
||||
} else if(ret.skill == 4001344 || ret.skill == NightWalker.LUCKY_SEVEN || ret.skill == NightLord.TRIPLE_THROW) {
|
||||
calcDmgMax = (chr.getTotalLuk() * 5) * chr.getTotalWatk() / 100;
|
||||
calcDmgMax = (long) ((chr.getTotalLuk() * 5) * Math.ceil(chr.getTotalWatk() / 100.0));
|
||||
} else if(ret.skill == DragonKnight.DRAGON_ROAR) {
|
||||
calcDmgMax = (chr.getTotalStr() * 4 + chr.getTotalDex()) * chr.getTotalWatk() / 100;
|
||||
calcDmgMax = (long) ((chr.getTotalStr() * 4 + chr.getTotalDex()) * Math.ceil(chr.getTotalWatk() / 100.0));
|
||||
} else if(ret.skill == NightLord.VENOMOUS_STAR || ret.skill == Shadower.VENOMOUS_STAB) {
|
||||
calcDmgMax = (int) (18.5 * (chr.getTotalStr() + chr.getTotalLuk()) + chr.getTotalDex() * 2) / 100 * chr.calculateMaxBaseDamage(chr.getTotalWatk());
|
||||
calcDmgMax = (long) (Math.ceil((18.5 * (chr.getTotalStr() + chr.getTotalLuk()) + chr.getTotalDex() * 2) / 100.0) * chr.calculateMaxBaseDamage(chr.getTotalWatk()));
|
||||
} else {
|
||||
calcDmgMax = chr.calculateMaxBaseDamage(chr.getTotalWatk());
|
||||
}
|
||||
|
||||
@@ -124,7 +124,11 @@ public final class AllianceOperationHandler extends AbstractMaplePacketHandler {
|
||||
Server.getInstance().resetAllianceGuildPlayersRank(guildid);
|
||||
|
||||
chr.getMGC().setAllianceRank(2);
|
||||
Server.getInstance().getGuild(chr.getGuildId()).getMGC(chr.getId()).setAllianceRank(2);
|
||||
MapleGuild g = Server.getInstance().getGuild(chr.getGuildId());
|
||||
if (g != null) {
|
||||
g.getMGC(chr.getId()).setAllianceRank(2);
|
||||
}
|
||||
|
||||
chr.saveGuildStatus();
|
||||
|
||||
Server.getInstance().allianceMessage(alliance.getId(), MaplePacketCreator.addGuildToAlliance(alliance, guildid, c), -1, -1);
|
||||
|
||||
@@ -33,7 +33,6 @@ import client.MapleBuffStat;
|
||||
import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import client.MapleJob;
|
||||
import client.MapleStat;
|
||||
import client.Skill;
|
||||
import client.SkillFactory;
|
||||
import constants.GameConstants;
|
||||
@@ -47,6 +46,7 @@ import constants.skills.Rogue;
|
||||
import constants.skills.WindArcher;
|
||||
|
||||
public final class CloseRangeDamageHandler extends AbstractDealDamageHandler {
|
||||
|
||||
@Override
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
|
||||
@@ -152,6 +152,12 @@ public final class EnterMTSHandler extends AbstractMaplePacketHandler {
|
||||
equip.setWdef((short) rs.getInt("wdef"));
|
||||
equip.setUpgradeSlots((byte) rs.getInt("upgradeslots"));
|
||||
equip.setLevel((byte) rs.getInt("level"));
|
||||
equip.setItemLevel(rs.getByte("itemlevel"));
|
||||
equip.setItemExp(rs.getInt("itemexp"));
|
||||
equip.setRingId(rs.getInt("ringid"));
|
||||
equip.setExpiration(rs.getLong("expiration"));
|
||||
equip.setGiftFrom(rs.getString("giftFrom"));
|
||||
|
||||
items.add(new MTSItemInfo((Item) equip, rs.getInt("price") + 100 + (int) (rs.getInt("price") * 0.1), rs.getInt("id"), rs.getInt("seller"), rs.getString("sellername"), rs.getString("sell_ends")));
|
||||
}
|
||||
}
|
||||
@@ -209,7 +215,12 @@ public final class EnterMTSHandler extends AbstractMaplePacketHandler {
|
||||
equip.setWdef((short) rs.getInt("wdef"));
|
||||
equip.setUpgradeSlots((byte) rs.getInt("upgradeslots"));
|
||||
equip.setLevel((byte) rs.getInt("level"));
|
||||
equip.setItemLevel(rs.getByte("itemlevel"));
|
||||
equip.setItemExp(rs.getInt("itemexp"));
|
||||
equip.setRingId(rs.getInt("ringid"));
|
||||
equip.setFlag((short) rs.getInt("flag"));
|
||||
equip.setExpiration(rs.getLong("expiration"));
|
||||
equip.setGiftFrom(rs.getString("giftFrom"));
|
||||
items.add(new MTSItemInfo((Item) equip, rs.getInt("price"), rs.getInt("id"), rs.getInt("seller"), rs.getString("sellername"), rs.getString("sell_ends")));
|
||||
}
|
||||
}
|
||||
@@ -256,7 +267,12 @@ public final class EnterMTSHandler extends AbstractMaplePacketHandler {
|
||||
equip.setWdef((short) rs.getInt("wdef"));
|
||||
equip.setUpgradeSlots((byte) rs.getInt("upgradeslots"));
|
||||
equip.setLevel((byte) rs.getInt("level"));
|
||||
equip.setItemLevel(rs.getByte("itemlevel"));
|
||||
equip.setItemExp(rs.getInt("itemexp"));
|
||||
equip.setRingId(rs.getInt("ringid"));
|
||||
equip.setFlag((short) rs.getInt("flag"));
|
||||
equip.setExpiration(rs.getLong("expiration"));
|
||||
equip.setGiftFrom(rs.getString("giftFrom"));
|
||||
items.add(new MTSItemInfo((Item) equip, rs.getInt("price"), rs.getInt("id"), rs.getInt("seller"), rs.getString("sellername"), rs.getString("sell_ends")));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,48 +160,55 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
|
||||
}
|
||||
if (!i.getInventoryType().equals(MapleInventoryType.EQUIP)) {
|
||||
Item item = (Item) i;
|
||||
ps = con.prepareStatement("INSERT INTO mts_items (tab, type, itemid, quantity, seller, price, owner, sellername, sell_ends) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
ps = con.prepareStatement("INSERT INTO mts_items (tab, type, itemid, quantity, expiration, giftFrom, seller, price, owner, sellername, sell_ends) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
ps.setInt(1, 1);
|
||||
ps.setInt(2, (int) invType.getType());
|
||||
ps.setInt(3, item.getItemId());
|
||||
ps.setInt(4, quantity);
|
||||
ps.setInt(5, c.getPlayer().getId());
|
||||
ps.setInt(6, price);
|
||||
ps.setString(7, item.getOwner());
|
||||
ps.setString(8, c.getPlayer().getName());
|
||||
ps.setString(9, date);
|
||||
ps.setLong(5, item.getExpiration());
|
||||
ps.setString(6, item.getGiftFrom());
|
||||
ps.setInt(7, c.getPlayer().getId());
|
||||
ps.setInt(8, price);
|
||||
ps.setString(9, item.getOwner());
|
||||
ps.setString(10, c.getPlayer().getName());
|
||||
ps.setString(11, date);
|
||||
} else {
|
||||
Equip equip = (Equip) i;
|
||||
ps = con.prepareStatement("INSERT INTO mts_items (tab, type, itemid, quantity, seller, price, upgradeslots, level, str, dex, `int`, luk, hp, mp, watk, matk, wdef, mdef, acc, avoid, hands, speed, jump, locked, owner, sellername, sell_ends, vicious, flag) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
ps = con.prepareStatement("INSERT INTO mts_items (tab, type, itemid, quantity, expiration, giftFrom, seller, price, upgradeslots, level, str, dex, `int`, luk, hp, mp, watk, matk, wdef, mdef, acc, avoid, hands, speed, jump, locked, owner, sellername, sell_ends, vicious, flag, itemexp, itemlevel, ringid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
ps.setInt(1, 1);
|
||||
ps.setInt(2, (int) invType.getType());
|
||||
ps.setInt(3, equip.getItemId());
|
||||
ps.setInt(4, quantity);
|
||||
ps.setInt(5, c.getPlayer().getId());
|
||||
ps.setInt(6, price);
|
||||
ps.setInt(7, equip.getUpgradeSlots());
|
||||
ps.setInt(8, equip.getLevel());
|
||||
ps.setInt(9, equip.getStr());
|
||||
ps.setInt(10, equip.getDex());
|
||||
ps.setInt(11, equip.getInt());
|
||||
ps.setInt(12, equip.getLuk());
|
||||
ps.setInt(13, equip.getHp());
|
||||
ps.setInt(14, equip.getMp());
|
||||
ps.setInt(15, equip.getWatk());
|
||||
ps.setInt(16, equip.getMatk());
|
||||
ps.setInt(17, equip.getWdef());
|
||||
ps.setInt(18, equip.getMdef());
|
||||
ps.setInt(19, equip.getAcc());
|
||||
ps.setInt(20, equip.getAvoid());
|
||||
ps.setInt(21, equip.getHands());
|
||||
ps.setInt(22, equip.getSpeed());
|
||||
ps.setInt(23, equip.getJump());
|
||||
ps.setInt(24, 0);
|
||||
ps.setString(25, equip.getOwner());
|
||||
ps.setString(26, c.getPlayer().getName());
|
||||
ps.setString(27, date);
|
||||
ps.setInt(28, equip.getVicious());
|
||||
ps.setInt(29, equip.getFlag());
|
||||
ps.setLong(5, equip.getExpiration());
|
||||
ps.setString(6, equip.getGiftFrom());
|
||||
ps.setInt(7, c.getPlayer().getId());
|
||||
ps.setInt(8, price);
|
||||
ps.setInt(9, equip.getUpgradeSlots());
|
||||
ps.setInt(10, equip.getLevel());
|
||||
ps.setInt(11, equip.getStr());
|
||||
ps.setInt(12, equip.getDex());
|
||||
ps.setInt(13, equip.getInt());
|
||||
ps.setInt(14, equip.getLuk());
|
||||
ps.setInt(15, equip.getHp());
|
||||
ps.setInt(16, equip.getMp());
|
||||
ps.setInt(17, equip.getWatk());
|
||||
ps.setInt(18, equip.getMatk());
|
||||
ps.setInt(19, equip.getWdef());
|
||||
ps.setInt(20, equip.getMdef());
|
||||
ps.setInt(21, equip.getAcc());
|
||||
ps.setInt(22, equip.getAvoid());
|
||||
ps.setInt(23, equip.getHands());
|
||||
ps.setInt(24, equip.getSpeed());
|
||||
ps.setInt(25, equip.getJump());
|
||||
ps.setInt(26, 0);
|
||||
ps.setString(27, equip.getOwner());
|
||||
ps.setString(28, c.getPlayer().getName());
|
||||
ps.setString(29, date);
|
||||
ps.setInt(30, equip.getVicious());
|
||||
ps.setInt(31, equip.getFlag());
|
||||
ps.setInt(32, equip.getItemExp());
|
||||
ps.setByte(33, equip.getItemLevel()); // thanks Jefe for noticing missing itemlevel labels
|
||||
ps.setInt(34, equip.getRingId());
|
||||
}
|
||||
ps.executeUpdate();
|
||||
ps.close();
|
||||
@@ -320,8 +327,13 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
|
||||
equip.setWdef((short) rs.getInt("wdef"));
|
||||
equip.setUpgradeSlots((byte) rs.getInt("upgradeslots"));
|
||||
equip.setLevel((byte) rs.getInt("level"));
|
||||
equip.setItemLevel(rs.getByte("itemlevel"));
|
||||
equip.setItemExp(rs.getInt("itemexp"));
|
||||
equip.setRingId(rs.getInt("ringid"));
|
||||
equip.setVicious((byte) rs.getInt("vicious"));
|
||||
equip.setFlag((short) rs.getInt("flag"));
|
||||
equip.setExpiration(rs.getLong("expiration"));
|
||||
equip.setGiftFrom(rs.getString("giftFrom"));
|
||||
equip.setPosition(c.getPlayer().getInventory(ItemConstants.getInventoryType(rs.getInt("itemid"))).getNextFreeSlot());
|
||||
i = equip.copy();
|
||||
}
|
||||
@@ -569,6 +581,11 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
|
||||
equip.setUpgradeSlots((byte) rs.getInt("upgradeslots"));
|
||||
equip.setLevel((byte) rs.getInt("level"));
|
||||
equip.setFlag((short) rs.getInt("flag"));
|
||||
equip.setItemLevel(rs.getByte("itemlevel"));
|
||||
equip.setItemExp(rs.getInt("itemexp"));
|
||||
equip.setRingId(rs.getInt("ringid"));
|
||||
equip.setExpiration(rs.getLong("expiration"));
|
||||
equip.setGiftFrom(rs.getString("giftFrom"));
|
||||
items.add(new MTSItemInfo((Item) equip, rs.getInt("price"), rs.getInt("id"), rs.getInt("seller"), rs.getString("sellername"), rs.getString("sell_ends")));
|
||||
}
|
||||
}
|
||||
@@ -623,7 +640,12 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
|
||||
equip.setWdef((short) rse.getInt("wdef"));
|
||||
equip.setUpgradeSlots((byte) rse.getInt("upgradeslots"));
|
||||
equip.setLevel((byte) rse.getInt("level"));
|
||||
equip.setItemLevel(rs.getByte("itemlevel"));
|
||||
equip.setItemExp(rs.getInt("itemexp"));
|
||||
equip.setRingId(rs.getInt("ringid"));
|
||||
equip.setFlag((short) rs.getInt("flag"));
|
||||
equip.setExpiration(rs.getLong("expiration"));
|
||||
equip.setGiftFrom(rs.getString("giftFrom"));
|
||||
items.add(new MTSItemInfo((Item) equip, rse.getInt("price"), rse.getInt("id"), rse.getInt("seller"), rse.getString("sellername"), rse.getString("sell_ends")));
|
||||
}
|
||||
}
|
||||
@@ -686,7 +708,12 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
|
||||
equip.setWdef((short) rs.getInt("wdef"));
|
||||
equip.setUpgradeSlots((byte) rs.getInt("upgradeslots"));
|
||||
equip.setLevel((byte) rs.getInt("level"));
|
||||
equip.setItemLevel(rs.getByte("itemlevel"));
|
||||
equip.setItemExp(rs.getInt("itemexp"));
|
||||
equip.setRingId(rs.getInt("ringid"));
|
||||
equip.setFlag((short) rs.getInt("flag"));
|
||||
equip.setExpiration(rs.getLong("expiration"));
|
||||
equip.setGiftFrom(rs.getString("giftFrom"));
|
||||
items.add(new MTSItemInfo((Item) equip, rs.getInt("price"), rs.getInt("id"), rs.getInt("seller"), rs.getString("sellername"), rs.getString("sell_ends")));
|
||||
}
|
||||
}
|
||||
@@ -747,7 +774,12 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
|
||||
equip.setWdef((short) rs.getInt("wdef"));
|
||||
equip.setUpgradeSlots((byte) rs.getInt("upgradeslots"));
|
||||
equip.setLevel((byte) rs.getInt("level"));
|
||||
equip.setItemLevel(rs.getByte("itemlevel"));
|
||||
equip.setItemExp(rs.getInt("itemexp"));
|
||||
equip.setRingId(rs.getInt("ringid"));
|
||||
equip.setFlag((short) rs.getInt("flag"));
|
||||
equip.setExpiration(rs.getLong("expiration"));
|
||||
equip.setGiftFrom(rs.getString("giftFrom"));
|
||||
items.add(new MTSItemInfo((Item) equip, rs.getInt("price"), rs.getInt("id"), rs.getInt("seller"), rs.getString("sellername"), rs.getString("sell_ends")));
|
||||
}
|
||||
}
|
||||
@@ -841,7 +873,12 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
|
||||
equip.setWdef((short) rs.getInt("wdef"));
|
||||
equip.setUpgradeSlots((byte) rs.getInt("upgradeslots"));
|
||||
equip.setLevel((byte) rs.getInt("level"));
|
||||
equip.setItemLevel(rs.getByte("itemlevel"));
|
||||
equip.setItemExp(rs.getInt("itemexp"));
|
||||
equip.setRingId(rs.getInt("ringid"));
|
||||
equip.setFlag((short) rs.getInt("flag"));
|
||||
equip.setExpiration(rs.getLong("expiration"));
|
||||
equip.setGiftFrom(rs.getString("giftFrom"));
|
||||
items.add(new MTSItemInfo((Item) equip, rs.getInt("price"), rs.getInt("id"), rs.getInt("seller"), rs.getString("sellername"), rs.getString("sell_ends")));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,9 +62,13 @@ public final class MagicDamageHandler extends AbstractDealDamageHandler {
|
||||
c.announce(MaplePacketCreator.getEnergy("energy", chr.getDojoEnergy()));
|
||||
}
|
||||
|
||||
int charge = (attack.skill == Evan.FIRE_BREATH || attack.skill == Evan.ICE_BREATH || attack.skill == FPArchMage.BIG_BANG || attack.skill == ILArchMage.BIG_BANG || attack.skill == Bishop.BIG_BANG) ? attack.charge : -1;
|
||||
byte[] packet = MaplePacketCreator.magicAttack(chr, attack.skill, attack.skilllevel, attack.stance, attack.numAttackedAndDamage, attack.allDamage, charge, attack.speed, attack.direction, attack.display);
|
||||
|
||||
byte[] packet;
|
||||
if ((attack.skill == Evan.FIRE_BREATH || attack.skill == Evan.ICE_BREATH || attack.skill == FPArchMage.BIG_BANG || attack.skill == ILArchMage.BIG_BANG || attack.skill == Bishop.BIG_BANG)) {
|
||||
packet = MaplePacketCreator.magicAttack(chr, attack.skill, attack.skilllevel, attack.stance, attack.numAttackedAndDamage, attack.allDamage, attack.charge, attack.speed, attack.direction, attack.display);
|
||||
} else {
|
||||
packet = MaplePacketCreator.closeRangeAttack(chr, attack.skill, attack.skilllevel, attack.stance, attack.numAttackedAndDamage, attack.allDamage, attack.speed, attack.direction, attack.display);
|
||||
}
|
||||
|
||||
chr.getMap().broadcastMessage(chr, packet, false, true);
|
||||
MapleStatEffect effect = attack.getAttackEffect(chr, null);
|
||||
Skill skill = SkillFactory.getSkill(attack.skill);
|
||||
|
||||
@@ -36,7 +36,6 @@ import server.life.MobSkillFactory;
|
||||
import server.maps.MapleMap;
|
||||
import server.maps.MapleMapObject;
|
||||
import server.maps.MapleMapObjectType;
|
||||
import server.movement.LifeMovementFragment;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.Pair;
|
||||
import tools.Randomizer;
|
||||
|
||||
@@ -4,167 +4,39 @@
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
Copyleft (L) 2016 - 2018 RonanLana (HeavenMS)
|
||||
|
||||
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 net.server.channel.handlers;
|
||||
|
||||
import client.MapleClient;
|
||||
import client.MapleCharacter;
|
||||
import client.inventory.Item;
|
||||
import client.inventory.MapleInventory;
|
||||
import client.inventory.MapleInventoryType;
|
||||
import client.processor.PetAutopotProcessor;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import client.inventory.manipulator.MapleInventoryManipulator;
|
||||
import server.MapleItemInformationProvider;
|
||||
import server.MapleStatEffect;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
import constants.ServerConstants;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Ronan - multi-pot consumption feature
|
||||
*/
|
||||
public final class PetAutoPotHandler extends AbstractMaplePacketHandler {
|
||||
short slot;
|
||||
int itemId;
|
||||
Item toUse;
|
||||
List<Item> toUseList;
|
||||
|
||||
boolean hasHpGain, hasMpGain;
|
||||
int maxHp, maxMp, curHp, curMp;
|
||||
double incHp, incMp;
|
||||
|
||||
@Override
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
if (!c.getPlayer().isAlive()) {
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
|
||||
slea.readByte();
|
||||
slea.readLong();
|
||||
slea.readInt();
|
||||
slot = slea.readShort();
|
||||
itemId = slea.readInt();
|
||||
short slot = slea.readShort();
|
||||
int itemId = slea.readInt();
|
||||
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
MapleInventory useInv = chr.getInventory(MapleInventoryType.USE);
|
||||
|
||||
int useCount = 0, qtyCount = 0;
|
||||
MapleStatEffect stat = null;
|
||||
|
||||
useInv.lockInventory();
|
||||
try {
|
||||
toUse = useInv.getItem(slot);
|
||||
|
||||
if (toUse != null) {
|
||||
if (toUse.getItemId() != itemId) {
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
|
||||
toUseList = null;
|
||||
|
||||
// from now on, toUse becomes the "cursor" for the current pot being used
|
||||
if (toUse.getQuantity() <= 0) {
|
||||
if (!cursorOnNextAvailablePot(chr)) {
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
stat = MapleItemInformationProvider.getInstance().getItemEffect(toUse.getItemId());
|
||||
hasHpGain = stat.getHp() > 0 || stat.getHpRate() > 0.0;
|
||||
hasMpGain = stat.getMp() > 0 || stat.getMpRate() > 0.0;
|
||||
|
||||
maxHp = chr.getCurrentMaxHp();
|
||||
maxMp = chr.getCurrentMaxMp();
|
||||
|
||||
curHp = chr.getHp();
|
||||
curMp = chr.getMp();
|
||||
|
||||
incHp = stat.getHp();
|
||||
if(incHp <= 0 && hasHpGain) incHp = Math.ceil(maxHp * stat.getHpRate());
|
||||
|
||||
incMp = stat.getMp();
|
||||
if(incMp <= 0 && hasMpGain) incMp = Math.ceil(maxMp * stat.getMpRate());
|
||||
|
||||
if (ServerConstants.USE_COMPULSORY_AUTOPOT) {
|
||||
if (hasHpGain) {
|
||||
qtyCount = (int) Math.ceil(((ServerConstants.PET_AUTOHP_RATIO * maxHp) - curHp) / incHp);
|
||||
}
|
||||
|
||||
if (hasMpGain) {
|
||||
qtyCount = Math.max(qtyCount, (int) Math.ceil(((ServerConstants.PET_AUTOMP_RATIO * maxMp) - curMp) / incMp));
|
||||
}
|
||||
} else {
|
||||
qtyCount = 1; // non-compulsory autopot concept thanks to marcuswoon
|
||||
}
|
||||
|
||||
while (true) {
|
||||
short qtyToUse = (short) Math.min(qtyCount, toUse.getQuantity());
|
||||
MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.USE, slot, qtyToUse, false);
|
||||
|
||||
curHp += (incHp * qtyToUse);
|
||||
curMp += (incMp * qtyToUse);
|
||||
|
||||
useCount += qtyToUse;
|
||||
qtyCount -= qtyToUse;
|
||||
|
||||
if(toUse.getQuantity() == 0 && qtyCount > 0) {
|
||||
// depleted out the current slot, fetch for more
|
||||
|
||||
if(!cursorOnNextAvailablePot(chr)) {
|
||||
break; // no more pots available
|
||||
}
|
||||
} else {
|
||||
break; // gracefully finished it's job, quit the loop
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
useInv.unlockInventory();
|
||||
}
|
||||
|
||||
for (int i = 0; i < useCount; i++) {
|
||||
stat.applyTo(chr);
|
||||
}
|
||||
|
||||
chr.announce(MaplePacketCreator.enableActions());
|
||||
PetAutopotProcessor.runAutopotAction(c, slot, itemId);
|
||||
}
|
||||
|
||||
private boolean cursorOnNextAvailablePot(MapleCharacter chr) {
|
||||
if(toUseList == null) {
|
||||
toUseList = chr.getInventory(MapleInventoryType.USE).linkedListById(itemId);
|
||||
}
|
||||
|
||||
toUse = null;
|
||||
while(!toUseList.isEmpty()) {
|
||||
Item it = toUseList.remove(0);
|
||||
|
||||
if(it.getQuantity() > 0) {
|
||||
toUse = it;
|
||||
slot = it.getPosition();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,11 +268,12 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
|
||||
if(familyEntry != null) {
|
||||
familyEntry.setCharacter(player);
|
||||
player.setFamilyEntry(familyEntry);
|
||||
|
||||
c.announce(MaplePacketCreator.getFamilyInfo(familyEntry));
|
||||
familyEntry.announceToSenior(MaplePacketCreator.sendFamilyLoginNotice(player.getName(), true), true);
|
||||
} else {
|
||||
FilePrinter.printError(FilePrinter.FAMILY_ERROR, "Player " + player.getName() + "'s family doesn't have an entry for them. (" + f.getID() + ")");
|
||||
}
|
||||
c.announce(MaplePacketCreator.getFamilyInfo(familyEntry));
|
||||
familyEntry.announceToSenior(MaplePacketCreator.sendFamilyLoginNotice(player.getName(), true), true);
|
||||
} else {
|
||||
FilePrinter.printError(FilePrinter.FAMILY_ERROR, "Player " + player.getName() + " has an invalid family ID. (" + player.getFamilyId() + ")");
|
||||
c.announce(MaplePacketCreator.getFamilyInfo(null));
|
||||
@@ -379,8 +380,6 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
|
||||
final List<Pair<MapleDisease, Integer>> debuff = Collections.singletonList(new Pair<>(e.getKey(), Integer.valueOf(e.getValue().getRight().getX())));
|
||||
c.announce(MaplePacketCreator.giveDebuff(debuff, e.getValue().getRight()));
|
||||
}
|
||||
|
||||
player.announceDiseases();
|
||||
}
|
||||
} else {
|
||||
if(player.isRidingBattleship()) {
|
||||
|
||||
@@ -26,6 +26,8 @@ import client.MapleClient;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import server.life.MapleMonster;
|
||||
import server.maps.MapleMapObject;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.Pair;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
@@ -48,5 +50,21 @@ public final class PlayerMapTransitionHandler extends AbstractMaplePacketHandler
|
||||
final List<Pair<MapleBuffStat, Integer>> stat = Collections.singletonList(new Pair<>(MapleBuffStat.HOMING_BEACON, 0));
|
||||
chr.announce(MaplePacketCreator.giveBuff(1, beaconid, stat));
|
||||
}
|
||||
|
||||
for (MapleMapObject mo : chr.getMap().getMonsters()) { // thanks BHB, IxianMace, Jefe for noticing several issues regarding mob statuses (such as freeze)
|
||||
MapleMonster m = (MapleMonster) mo;
|
||||
if (m.getSpawnEffect() == 0 || m.getHp() < m.getMaxHp()) { // avoid effect-spawning mobs
|
||||
if (m.getController() == chr) {
|
||||
c.announce(MaplePacketCreator.stopControllingMonster(m.getObjectId()));
|
||||
m.sendDestroyData(c);
|
||||
m.aggroRedirectController();
|
||||
} else {
|
||||
m.sendDestroyData(c);
|
||||
}
|
||||
|
||||
m.aggroSwitchController(chr, false);
|
||||
m.sendSpawnData(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -244,7 +244,7 @@ public final class TakeDamageHandler extends AbstractMaplePacketHandler {
|
||||
Skill highDef = SkillFactory.getSkill(Aran.HIGH_DEFENSE);
|
||||
int hdLevel = chr.getSkillLevel(highDef);
|
||||
if (highDef != null && hdLevel > 0) {
|
||||
damage *= (highDef.getEffect(hdLevel).getX() / 1000.0);
|
||||
damage *= Math.ceil(highDef.getEffect(hdLevel).getX() / 1000.0);
|
||||
}
|
||||
}
|
||||
Integer mesoguard = chr.getBuffedValue(MapleBuffStat.MESOGUARD);
|
||||
|
||||
@@ -580,14 +580,6 @@ public class MapleGuild {
|
||||
}
|
||||
|
||||
membersLock.lock();
|
||||
members.sort(new Comparator<MapleGuildCharacter>() {
|
||||
@Override
|
||||
public int compare(MapleGuildCharacter t, MapleGuildCharacter o) {
|
||||
if(t.getGuildRank() <= 1 && o.getGuildRank() > 1) return -1;
|
||||
else if(t.getGuildRank() > 1 && o.getGuildRank() <= 1) return 1;
|
||||
else return 0;
|
||||
}
|
||||
});
|
||||
try {
|
||||
this.broadcast(MaplePacketCreator.changeRank(mgc));
|
||||
} finally {
|
||||
@@ -597,7 +589,7 @@ public class MapleGuild {
|
||||
|
||||
public void setGuildNotice(String notice) {
|
||||
this.notice = notice;
|
||||
writeToDB(false);
|
||||
this.writeToDB(false);
|
||||
|
||||
membersLock.lock();
|
||||
try {
|
||||
|
||||
@@ -130,7 +130,7 @@ public class MapleParty {
|
||||
public Collection<MaplePartyCharacter> getMembers() {
|
||||
lock.lock();
|
||||
try {
|
||||
return Collections.unmodifiableList(members);
|
||||
return new LinkedList<>(members);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
@@ -139,7 +139,7 @@ public class MapleParty {
|
||||
public List<MaplePartyCharacter> getPartyMembers() {
|
||||
lock.lock();
|
||||
try {
|
||||
return Collections.unmodifiableList(members);
|
||||
return new LinkedList<>(members);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
@@ -65,9 +65,7 @@ public abstract class AbstractScriptManager {
|
||||
}
|
||||
|
||||
protected NashornScriptEngine getScriptEngine(String path, MapleClient c) {
|
||||
String cachePath = "scripts/" + path;
|
||||
NashornScriptEngine engine = c.getScriptEngine(cachePath);
|
||||
|
||||
NashornScriptEngine engine = c.getScriptEngine("scripts/" + path);
|
||||
if (engine == null) {
|
||||
engine = getScriptEngine(path);
|
||||
c.setScriptEngine(path, engine);
|
||||
|
||||
@@ -31,7 +31,6 @@ import java.util.Properties;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.script.Invocable;
|
||||
import javax.script.ScriptException;
|
||||
|
||||
import constants.ServerConstants;
|
||||
@@ -59,6 +58,7 @@ import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import jdk.nashorn.api.scripting.NashornScriptEngine;
|
||||
import net.server.audit.LockCollector;
|
||||
import net.server.audit.locks.MonitoredLockType;
|
||||
import net.server.audit.locks.MonitoredReentrantLock;
|
||||
@@ -72,7 +72,7 @@ import server.ThreadManager;
|
||||
* @author Ronan
|
||||
*/
|
||||
public class EventManager {
|
||||
private Invocable iv;
|
||||
private NashornScriptEngine iv;
|
||||
private Channel cserv;
|
||||
private World wserv;
|
||||
private Server server;
|
||||
@@ -95,7 +95,7 @@ public class EventManager {
|
||||
|
||||
private static final int maxLobbys = 8; // an event manager holds up to this amount of concurrent lobbys
|
||||
|
||||
public EventManager(Channel cserv, Invocable iv, String name) {
|
||||
public EventManager(Channel cserv, NashornScriptEngine iv, String name) {
|
||||
this.server = Server.getInstance();
|
||||
this.iv = iv;
|
||||
this.cserv = cserv;
|
||||
@@ -256,7 +256,7 @@ public class EventManager {
|
||||
return cserv;
|
||||
}
|
||||
|
||||
public Invocable getIv() {
|
||||
public NashornScriptEngine getIv() {
|
||||
return iv;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,8 +27,8 @@ import java.util.Map.Entry;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.script.Invocable;
|
||||
import javax.script.ScriptEngine;
|
||||
import jdk.nashorn.api.scripting.NashornScriptEngine;
|
||||
|
||||
import net.server.channel.Channel;
|
||||
import scripting.AbstractScriptManager;
|
||||
@@ -41,11 +41,11 @@ public class EventScriptManager extends AbstractScriptManager {
|
||||
|
||||
private class EventEntry {
|
||||
|
||||
public EventEntry(Invocable iv, EventManager em) {
|
||||
public EventEntry(NashornScriptEngine iv, EventManager em) {
|
||||
this.iv = iv;
|
||||
this.em = em;
|
||||
}
|
||||
public Invocable iv;
|
||||
public NashornScriptEngine iv;
|
||||
public EventManager em;
|
||||
}
|
||||
private Map<String, EventEntry> events = new LinkedHashMap<>();
|
||||
@@ -54,7 +54,7 @@ public class EventScriptManager extends AbstractScriptManager {
|
||||
super();
|
||||
for (String script : scripts) {
|
||||
if (!script.equals("")) {
|
||||
Invocable iv = getScriptEngine("event/" + script + ".js");
|
||||
NashornScriptEngine iv = getScriptEngine("event/" + script + ".js");
|
||||
events.put(script, new EventEntry(iv, new EventManager(cserv, iv, script)));
|
||||
}
|
||||
}
|
||||
@@ -71,7 +71,7 @@ public class EventScriptManager extends AbstractScriptManager {
|
||||
public void init() {
|
||||
for (EventEntry entry : events.values()) {
|
||||
try {
|
||||
((ScriptEngine) entry.iv).put("em", entry.em);
|
||||
entry.iv.put("em", entry.em);
|
||||
entry.iv.invokeFunction("init", (Object) null);
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(EventScriptManager.class.getName()).log(Level.SEVERE, null, ex);
|
||||
@@ -88,7 +88,7 @@ public class EventScriptManager extends AbstractScriptManager {
|
||||
Channel cserv = events.values().iterator().next().em.getChannelServer();
|
||||
for (Entry<String, EventEntry> entry : events.entrySet()) {
|
||||
String script = entry.getKey();
|
||||
Invocable iv = getScriptEngine("event/" + script + ".js");
|
||||
NashornScriptEngine iv = getScriptEngine("event/" + script + ".js");
|
||||
events.put(script, new EventEntry(iv, new EventManager(cserv, iv, script)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,23 +21,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package scripting.map;
|
||||
|
||||
import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import constants.ServerConstants;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.UndeclaredThrowableException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.script.Compilable;
|
||||
import javax.script.Invocable;
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineFactory;
|
||||
import javax.script.ScriptEngineManager;
|
||||
import javax.script.ScriptException;
|
||||
import jdk.nashorn.api.scripting.NashornScriptEngine;
|
||||
import scripting.AbstractScriptManager;
|
||||
import tools.FilePrinter;
|
||||
|
||||
public class MapScriptManager {
|
||||
public class MapScriptManager extends AbstractScriptManager {
|
||||
|
||||
private static MapScriptManager instance = new MapScriptManager();
|
||||
|
||||
@@ -45,7 +41,7 @@ public class MapScriptManager {
|
||||
return instance;
|
||||
}
|
||||
|
||||
private Map<String, Invocable> scripts = new HashMap<>();
|
||||
private Map<String, NashornScriptEngine> scripts = new HashMap<>();
|
||||
private ScriptEngineFactory sef;
|
||||
|
||||
private MapScriptManager() {
|
||||
@@ -57,53 +53,42 @@ public class MapScriptManager {
|
||||
scripts.clear();
|
||||
}
|
||||
|
||||
public boolean scriptExists(String scriptName, boolean firstUser) {
|
||||
File scriptFile = new File("scripts/map/" + (firstUser ? "onFirstUserEnter/" : "onUserEnter/") + scriptName + ".js");
|
||||
return scriptFile.exists();
|
||||
}
|
||||
|
||||
public void runMapScript(MapleClient c, String scriptName, boolean firstUser) {
|
||||
if (scripts.containsKey(scriptName)) {
|
||||
public boolean runMapScript(MapleClient c, String mapScriptPath, boolean firstUser) {
|
||||
if (firstUser) {
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
int mapid = chr.getMapId();
|
||||
if (chr.hasEntered(mapScriptPath, mapid)) {
|
||||
return false;
|
||||
} else {
|
||||
chr.enteredScript(mapScriptPath, mapid);
|
||||
}
|
||||
}
|
||||
|
||||
NashornScriptEngine iv = scripts.get(mapScriptPath);
|
||||
if (iv != null) {
|
||||
try {
|
||||
scripts.get(scriptName).invokeFunction("start", new MapScriptMethods(c));
|
||||
iv.invokeFunction("start", new MapScriptMethods(c));
|
||||
return true;
|
||||
} catch (final ScriptException | NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return;
|
||||
}
|
||||
String type = firstUser ? "onFirstUserEnter/" : "onUserEnter/";
|
||||
|
||||
File scriptFile = new File("scripts/map/" + type + scriptName + ".js");
|
||||
if (!scriptExists(scriptName, firstUser)) {
|
||||
return;
|
||||
}
|
||||
FileReader fr = null;
|
||||
ScriptEngine se = sef.getScriptEngine();
|
||||
|
||||
try {
|
||||
fr = new FileReader(scriptFile);
|
||||
|
||||
// java 8 support here thanks to Arufonsu
|
||||
if (ServerConstants.JAVA_8){
|
||||
se.eval("load('nashorn:mozilla_compat.js');" + System.lineSeparator());
|
||||
iv = getScriptEngine("map/" + mapScriptPath + ".js");
|
||||
if (iv == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
((Compilable) se).compile(fr).eval();
|
||||
|
||||
final Invocable script = ((Invocable) se);
|
||||
scripts.put(scriptName, script);
|
||||
script.invokeFunction("start", new MapScriptMethods(c));
|
||||
scripts.put(mapScriptPath, iv);
|
||||
iv.invokeFunction("start", new MapScriptMethods(c));
|
||||
return true;
|
||||
} catch (final UndeclaredThrowableException | ScriptException ute) {
|
||||
FilePrinter.printError(FilePrinter.MAP_SCRIPT + type + scriptName + ".txt", ute);
|
||||
FilePrinter.printError(FilePrinter.MAP_SCRIPT + mapScriptPath + ".txt", ute);
|
||||
} catch (final Exception e) {
|
||||
FilePrinter.printError(FilePrinter.MAP_SCRIPT + type + scriptName + ".txt", e);
|
||||
} finally {
|
||||
if (fr != null) {
|
||||
try {
|
||||
fr.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
FilePrinter.printError(FilePrinter.MAP_SCRIPT + mapScriptPath + ".txt", e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -679,12 +679,11 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
|
||||
try {
|
||||
final MapleMap map, mapExit;
|
||||
Channel cs = c.getChannelServer();
|
||||
PlayerStorage ps = cs.getPlayerStorage();
|
||||
|
||||
map = cs.getMapFactory().getMap(980000100 + 100 * field);
|
||||
mapExit = cs.getMapFactory().getMap(980000000);
|
||||
for (MaplePartyCharacter mpc : c.getPlayer().getParty().getMembers()) {
|
||||
final MapleCharacter mc = ps.getCharacterById(mpc.getId());
|
||||
final MapleCharacter mc = mpc.getPlayer();
|
||||
if (mc != null) {
|
||||
mc.setChallenged(false);
|
||||
mc.changeMap(map, map.getPortal(0));
|
||||
@@ -715,9 +714,8 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
|
||||
}
|
||||
|
||||
public void cancelCPQLobby() {
|
||||
PlayerStorage ps = c.getChannelServer().getPlayerStorage();
|
||||
for (MaplePartyCharacter mpc : c.getPlayer().getParty().getMembers()) {
|
||||
MapleCharacter mc = ps.getCharacterById(mpc.getId());
|
||||
MapleCharacter mc = mpc.getPlayer();
|
||||
if (mc != null) {
|
||||
mc.clearCpqTimer();
|
||||
}
|
||||
@@ -741,11 +739,11 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
|
||||
final MapleMap lobbyMap = getPlayer().getMap();
|
||||
if (challenger != null) {
|
||||
if (challenger.getParty() == null) {
|
||||
throw new RuntimeException("Nao existe oponente!");
|
||||
throw new RuntimeException("No opponent found!");
|
||||
}
|
||||
PlayerStorage ps = c.getChannelServer().getPlayerStorage();
|
||||
|
||||
for (MaplePartyCharacter mpc : challenger.getParty().getMembers()) {
|
||||
MapleCharacter mc = ps.getCharacterById(mpc.getId());
|
||||
MapleCharacter mc = mpc.getPlayer();
|
||||
if (mc != null) {
|
||||
mc.changeMap(lobbyMap, lobbyMap.getPortal(0));
|
||||
TimerManager tMan = TimerManager.getInstance();
|
||||
@@ -758,7 +756,7 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
|
||||
}
|
||||
}
|
||||
for (MaplePartyCharacter mpc : getPlayer().getParty().getMembers()) {
|
||||
MapleCharacter mc = ps.getCharacterById(mpc.getId());
|
||||
MapleCharacter mc = mpc.getPlayer();
|
||||
if (mc != null) {
|
||||
TimerManager tMan = TimerManager.getInstance();
|
||||
tMan.schedule(new Runnable() {
|
||||
@@ -776,15 +774,14 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
PlayerStorage ps = c.getChannelServer().getPlayerStorage();
|
||||
for (MaplePartyCharacter mpc : getPlayer().getParty().getMembers()) {
|
||||
MapleCharacter mc = ps.getCharacterById(mpc.getId());
|
||||
MapleCharacter mc = mpc.getPlayer();
|
||||
if (mc != null) {
|
||||
mc.setMonsterCarnival(null);
|
||||
}
|
||||
}
|
||||
for (MaplePartyCharacter mpc : challenger.getParty().getMembers()) {
|
||||
MapleCharacter mc = ps.getCharacterById(mpc.getId());
|
||||
MapleCharacter mc = mpc.getPlayer();
|
||||
if (mc != null) {
|
||||
mc.setMonsterCarnival(null);
|
||||
}
|
||||
@@ -809,11 +806,11 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
|
||||
final MapleMap lobbyMap = getPlayer().getMap();
|
||||
if (challenger != null) {
|
||||
if (challenger.getParty() == null) {
|
||||
throw new RuntimeException("Não existe oponente!");
|
||||
throw new RuntimeException("No opponent found!");
|
||||
}
|
||||
PlayerStorage ps = c.getChannelServer().getPlayerStorage();
|
||||
|
||||
for (MaplePartyCharacter mpc : challenger.getParty().getMembers()) {
|
||||
MapleCharacter mc = ps.getCharacterById(mpc.getId());
|
||||
MapleCharacter mc = mpc.getPlayer();
|
||||
if (mc != null) {
|
||||
mc.changeMap(lobbyMap, lobbyMap.getPortal(0));
|
||||
mapClock(10);
|
||||
@@ -826,15 +823,14 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
PlayerStorage ps = c.getChannelServer().getPlayerStorage();
|
||||
for (MaplePartyCharacter mpc : getPlayer().getParty().getMembers()) {
|
||||
MapleCharacter mc = ps.getCharacterById(mpc.getId());
|
||||
MapleCharacter mc = mpc.getPlayer();
|
||||
if (mc != null) {
|
||||
mc.setMonsterCarnival(null);
|
||||
}
|
||||
}
|
||||
for (MaplePartyCharacter mpc : challenger.getParty().getMembers()) {
|
||||
MapleCharacter mc = ps.getCharacterById(mpc.getId());
|
||||
MapleCharacter mc = mpc.getPlayer();
|
||||
if (mc != null) {
|
||||
mc.setMonsterCarnival(null);
|
||||
}
|
||||
@@ -907,12 +903,11 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
|
||||
try {
|
||||
final MapleMap map, mapExit;
|
||||
Channel cs = c.getChannelServer();
|
||||
PlayerStorage ps = c.getChannelServer().getPlayerStorage();
|
||||
|
||||
mapExit = cs.getMapFactory().getMap(980030000);
|
||||
map = cs.getMapFactory().getMap(980031000 + 1000 * field);
|
||||
for (MaplePartyCharacter mpc : c.getPlayer().getParty().getMembers()) {
|
||||
final MapleCharacter mc = ps.getCharacterById(mpc.getId());
|
||||
final MapleCharacter mc = mpc.getPlayer();
|
||||
if (mc != null) {
|
||||
mc.setChallenged(false);
|
||||
mc.changeMap(map, map.getPortal(0));
|
||||
|
||||
@@ -29,8 +29,6 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.script.Invocable;
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptException;
|
||||
|
||||
import jdk.nashorn.api.scripting.NashornScriptEngine;
|
||||
@@ -54,10 +52,10 @@ public class NPCScriptManager extends AbstractScriptManager {
|
||||
}
|
||||
|
||||
private Map<MapleClient, NPCConversationManager> cms = new HashMap<>();
|
||||
private Map<MapleClient, Invocable> scripts = new HashMap<>();
|
||||
private Map<MapleClient, NashornScriptEngine> scripts = new HashMap<>();
|
||||
|
||||
public boolean isNpcScriptAvailable(MapleClient c, String fileName) {
|
||||
Invocable iv = null;
|
||||
NashornScriptEngine iv = null;
|
||||
if (fileName != null) {
|
||||
iv = getScriptEngine("npc/" + fileName + ".js", c);
|
||||
}
|
||||
@@ -96,7 +94,7 @@ public class NPCScriptManager extends AbstractScriptManager {
|
||||
NashornScriptEngine iv = getScriptEngine("npc/" + filename + ".js", c);
|
||||
|
||||
if (iv == null) {
|
||||
c.getPlayer().dropMessage(1, npc + "");
|
||||
c.getPlayer().dropMessage(1, "NPC " + npc + " is uncoded.");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
@@ -173,7 +171,7 @@ public class NPCScriptManager extends AbstractScriptManager {
|
||||
}
|
||||
|
||||
public void action(MapleClient c, byte mode, byte type, int selection) {
|
||||
Invocable iv = scripts.get(c);
|
||||
NashornScriptEngine iv = scripts.get(c);
|
||||
if (iv != null) {
|
||||
try {
|
||||
c.setClickedNPC();
|
||||
|
||||
@@ -22,23 +22,17 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
package scripting.portal;
|
||||
|
||||
import client.MapleClient;
|
||||
import constants.ServerConstants;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.UndeclaredThrowableException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.script.Compilable;
|
||||
import javax.script.Invocable;
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineFactory;
|
||||
import javax.script.ScriptEngineManager;
|
||||
import javax.script.ScriptException;
|
||||
import jdk.nashorn.api.scripting.NashornScriptEngine;
|
||||
import scripting.AbstractScriptManager;
|
||||
import server.maps.MaplePortal;
|
||||
import tools.FilePrinter;
|
||||
|
||||
public class PortalScriptManager {
|
||||
public class PortalScriptManager extends AbstractScriptManager {
|
||||
|
||||
private static PortalScriptManager instance = new PortalScriptManager();
|
||||
|
||||
@@ -46,7 +40,7 @@ public class PortalScriptManager {
|
||||
return instance;
|
||||
}
|
||||
|
||||
private Map<String, PortalScript> scripts = new HashMap<>();
|
||||
private Map<String, NashornScriptEngine> scripts = new HashMap<>();
|
||||
private ScriptEngineFactory sef;
|
||||
|
||||
private PortalScriptManager() {
|
||||
@@ -54,47 +48,28 @@ public class PortalScriptManager {
|
||||
sef = sem.getEngineByName("javascript").getFactory();
|
||||
}
|
||||
|
||||
private PortalScript getPortalScript(String scriptName) {
|
||||
if (scripts.containsKey(scriptName)) {
|
||||
return scripts.get(scriptName);
|
||||
private NashornScriptEngine getPortalScript(String scriptName) {
|
||||
String scriptPath = "portal/" + scriptName + ".js";
|
||||
NashornScriptEngine iv = scripts.get(scriptPath);
|
||||
if (iv != null) {
|
||||
return iv;
|
||||
}
|
||||
File scriptFile = new File("scripts/portal/" + scriptName + ".js");
|
||||
if (!scriptFile.exists()) {
|
||||
scripts.put(scriptName, null);
|
||||
|
||||
iv = getScriptEngine(scriptPath);
|
||||
if (iv == null) {
|
||||
return null;
|
||||
}
|
||||
FileReader fr = null;
|
||||
ScriptEngine portal = sef.getScriptEngine();
|
||||
try {
|
||||
fr = new FileReader(scriptFile);
|
||||
|
||||
// java 8 support here thanks to Arufonsu
|
||||
if (ServerConstants.JAVA_8){
|
||||
portal.eval("load('nashorn:mozilla_compat.js');" + System.lineSeparator());
|
||||
}
|
||||
|
||||
((Compilable) portal).compile(fr).eval();
|
||||
} catch (ScriptException | IOException | UndeclaredThrowableException e) {
|
||||
FilePrinter.printError(FilePrinter.PORTAL + scriptName + ".txt", e);
|
||||
} finally {
|
||||
if (fr != null) {
|
||||
try {
|
||||
fr.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
PortalScript script = ((Invocable) portal).getInterface(PortalScript.class);
|
||||
scripts.put(scriptName, script);
|
||||
return script;
|
||||
|
||||
scripts.put(scriptPath, iv);
|
||||
return iv;
|
||||
}
|
||||
|
||||
public boolean executePortalScript(MaplePortal portal, MapleClient c) {
|
||||
try {
|
||||
PortalScript script = getPortalScript(portal.getScriptName());
|
||||
if (script != null) {
|
||||
return script.enter(new PortalPlayerInteraction(c, portal));
|
||||
NashornScriptEngine iv = getPortalScript(portal.getScriptName());
|
||||
if (iv != null) {
|
||||
boolean couldWarp = (boolean) iv.invokeFunction("enter", new PortalPlayerInteraction(c, portal));
|
||||
return couldWarp;
|
||||
}
|
||||
} catch (UndeclaredThrowableException ute) {
|
||||
FilePrinter.printError(FilePrinter.PORTAL + portal.getScriptName() + ".txt", ute);
|
||||
|
||||
@@ -25,8 +25,6 @@ import java.lang.reflect.UndeclaredThrowableException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.script.Invocable;
|
||||
|
||||
import jdk.nashorn.api.scripting.NashornScriptEngine;
|
||||
import scripting.AbstractScriptManager;
|
||||
import server.quest.MapleQuest;
|
||||
@@ -48,7 +46,16 @@ public class QuestScriptManager extends AbstractScriptManager {
|
||||
}
|
||||
|
||||
private Map<MapleClient, QuestActionManager> qms = new HashMap<>();
|
||||
private Map<MapleClient, Invocable> scripts = new HashMap<>();
|
||||
private Map<MapleClient, NashornScriptEngine> scripts = new HashMap<>();
|
||||
|
||||
private NashornScriptEngine getQuestScriptEngine(MapleClient c, short questid) {
|
||||
NashornScriptEngine iv = getScriptEngine("quest/" + questid + ".js", c);
|
||||
if (iv == null && GameConstants.isMedalQuest(questid)) {
|
||||
iv = getScriptEngine("quest/medalQuest.js", c); // start generic medal quest
|
||||
}
|
||||
|
||||
return iv;
|
||||
}
|
||||
|
||||
public void start(MapleClient c, short questid, int npc) {
|
||||
MapleQuest quest = MapleQuest.getInstance(questid);
|
||||
@@ -63,18 +70,19 @@ public class QuestScriptManager extends AbstractScriptManager {
|
||||
}
|
||||
if(c.canClickNPC()) {
|
||||
qms.put(c, qm);
|
||||
NashornScriptEngine iv = getScriptEngine("quest/" + questid + ".js", c);
|
||||
if (iv == null) {
|
||||
if(GameConstants.isMedalQuest(questid)) { // start generic medal quest
|
||||
iv = getScriptEngine("quest/medalQuest.js", c);
|
||||
} else {
|
||||
FilePrinter.printError(FilePrinter.QUEST_UNCODED, "START Quest " + questid + " is uncoded.");
|
||||
}
|
||||
}
|
||||
if (iv == null || QuestScriptManager.getInstance() == null) {
|
||||
|
||||
if (!quest.hasScriptRequirement(false)) { // lack of scripted quest checks found thanks to Mali, Resinate
|
||||
qm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
NashornScriptEngine iv = getQuestScriptEngine(c, questid);
|
||||
if (iv == null) {
|
||||
FilePrinter.printError(FilePrinter.QUEST_UNCODED, "START Quest " + questid + " is uncoded.");
|
||||
qm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
iv.put("qm", qm);
|
||||
scripts.put(c, iv);
|
||||
c.setClickedNPC();
|
||||
@@ -90,7 +98,7 @@ public class QuestScriptManager extends AbstractScriptManager {
|
||||
}
|
||||
|
||||
public void start(MapleClient c, byte mode, byte type, int selection) {
|
||||
Invocable iv = scripts.get(c);
|
||||
NashornScriptEngine iv = scripts.get(c);
|
||||
if (iv != null) {
|
||||
try {
|
||||
c.setClickedNPC();
|
||||
@@ -118,16 +126,19 @@ public class QuestScriptManager extends AbstractScriptManager {
|
||||
}
|
||||
if(c.canClickNPC()){
|
||||
qms.put(c, qm);
|
||||
NashornScriptEngine iv = getScriptEngine("quest/" + questid + ".js", c);
|
||||
if (iv == null) {
|
||||
if(GameConstants.isMedalQuest(questid)) { // start generic medal quest
|
||||
iv = getScriptEngine("quest/medalQuest.js", c);
|
||||
} else {
|
||||
FilePrinter.printError(FilePrinter.QUEST_UNCODED, "END Quest " + questid + " is uncoded.");
|
||||
qm.dispose();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!quest.hasScriptRequirement(true)) {
|
||||
qm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
NashornScriptEngine iv = getQuestScriptEngine(c, questid);
|
||||
if (iv == null) {
|
||||
FilePrinter.printError(FilePrinter.QUEST_UNCODED, "END Quest " + questid + " is uncoded.");
|
||||
qm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
iv.put("qm", qm);
|
||||
scripts.put(c, iv);
|
||||
c.setClickedNPC();
|
||||
@@ -143,7 +154,7 @@ public class QuestScriptManager extends AbstractScriptManager {
|
||||
}
|
||||
|
||||
public void end(MapleClient c, byte mode, byte type, int selection) {
|
||||
Invocable iv = scripts.get(c);
|
||||
NashornScriptEngine iv = scripts.get(c);
|
||||
if (iv != null) {
|
||||
try {
|
||||
c.setClickedNPC();
|
||||
|
||||
@@ -35,8 +35,8 @@ import java.util.List;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.script.Invocable;
|
||||
import javax.script.ScriptException;
|
||||
import jdk.nashorn.api.scripting.NashornScriptEngine;
|
||||
import scripting.AbstractPlayerInteraction;
|
||||
import scripting.event.EventInstanceManager;
|
||||
import scripting.event.EventManager;
|
||||
@@ -58,10 +58,10 @@ import tools.MaplePacketCreator;
|
||||
*/
|
||||
public class ReactorActionManager extends AbstractPlayerInteraction {
|
||||
private MapleReactor reactor;
|
||||
private Invocable iv;
|
||||
private NashornScriptEngine iv;
|
||||
private ScheduledFuture<?> sprayTask = null;
|
||||
|
||||
public ReactorActionManager(MapleClient c, MapleReactor reactor, Invocable iv) {
|
||||
public ReactorActionManager(MapleClient c, MapleReactor reactor, NashornScriptEngine iv) {
|
||||
super(c);
|
||||
this.reactor = reactor;
|
||||
this.iv = iv;
|
||||
|
||||
@@ -29,7 +29,6 @@ import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.script.Invocable;
|
||||
import javax.script.ScriptException;
|
||||
|
||||
import jdk.nashorn.api.scripting.NashornScriptEngine;
|
||||
|
||||
@@ -824,6 +824,7 @@ public class MapleStatEffect {
|
||||
break;
|
||||
case ILMage.SEAL:
|
||||
case FPMage.SEAL:
|
||||
case BlazeWizard.SEAL:
|
||||
monsterStatus.put(MonsterStatus.SEAL, Integer.valueOf(1));
|
||||
break;
|
||||
case Hermit.SHADOW_WEB: // shadow web
|
||||
@@ -1200,6 +1201,8 @@ public class MapleStatEffect {
|
||||
MapleMonster monster = (MapleMonster) mo;
|
||||
if (isDispel()) {
|
||||
monster.debuffMob(skill_.getId());
|
||||
} else if (isSeal() && monster.isBoss()) { // thanks IxianMace for noticing seal working on bosses
|
||||
// do nothing
|
||||
} else {
|
||||
if (makeChanceResult()) {
|
||||
monster.applyStatus(applyfrom, new MonsterStatusEffect(getMonsterStati(), skill_, null, false), isPoison(), getDuration());
|
||||
@@ -1705,6 +1708,10 @@ public class MapleStatEffect {
|
||||
private boolean isCrash() {
|
||||
return skill && (sourceid == DragonKnight.POWER_CRASH || sourceid == Crusader.ARMOR_CRASH || sourceid == WhiteKnight.MAGIC_CRASH);
|
||||
}
|
||||
|
||||
private boolean isSeal() {
|
||||
return skill && (sourceid == ILMage.SEAL || sourceid == FPMage.SEAL || sourceid == BlazeWizard.SEAL);
|
||||
}
|
||||
|
||||
private boolean isDispel() {
|
||||
return skill && (sourceid == Priest.DISPEL || sourceid == SuperGM.HEAL_PLUS_DISPEL);
|
||||
|
||||
@@ -101,6 +101,7 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
private List<Integer> stolenItems = new ArrayList<>(5);
|
||||
private int team;
|
||||
private int parentMobOid = 0;
|
||||
private int spawnEffect = 0;
|
||||
private final HashMap<Integer, AtomicLong> takenDamage = new HashMap<>();
|
||||
private ScheduledFuture<?> monsterItemDrop = null;
|
||||
private Runnable removeAfterAction = null;
|
||||
@@ -138,6 +139,14 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
|
||||
maxHpPlusHeal.set(hp.get());
|
||||
}
|
||||
|
||||
public void setSpawnEffect(int effect) {
|
||||
spawnEffect = effect;
|
||||
}
|
||||
|
||||
public int getSpawnEffect() {
|
||||
return spawnEffect;
|
||||
}
|
||||
|
||||
public void disableDrops() {
|
||||
this.dropsDisabled = true;
|
||||
@@ -1060,6 +1069,7 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
@Override
|
||||
public void sendDestroyData(MapleClient client) {
|
||||
client.announce(MaplePacketCreator.killMonster(getObjectId(), false));
|
||||
client.announce(MaplePacketCreator.killMonster(getObjectId(), true));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -102,10 +102,12 @@ public class MapleDoor {
|
||||
|
||||
for (MapleCharacter chr : targetChars) {
|
||||
areaDoor.sendDestroyData(chr.getClient());
|
||||
chr.removeVisibleMapObject(areaDoor);
|
||||
}
|
||||
|
||||
for (MapleCharacter chr : townChars) {
|
||||
townDoor.sendDestroyData(chr.getClient());
|
||||
chr.removeVisibleMapObject(townDoor);
|
||||
}
|
||||
|
||||
owner.removePartyDoor(false);
|
||||
@@ -115,6 +117,7 @@ public class MapleDoor {
|
||||
MapleDoor door = chr.getMainTownDoor();
|
||||
if (door != null) {
|
||||
townDoor.sendSpawnData(chr.getClient());
|
||||
chr.addVisibleMapObject(townDoor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +87,8 @@ public class MapleDoorObject extends AbstractMapleMapObject {
|
||||
public void warp(final MapleCharacter chr) {
|
||||
MapleParty party = chr.getParty();
|
||||
if (chr.getId() == ownerId || (party != null && party.getMemberById(ownerId) != null)) {
|
||||
chr.announce(MaplePacketCreator.playPortalSound());
|
||||
|
||||
if(!inTown() && party == null) {
|
||||
chr.changeMap(to, getLinkedPortalId());
|
||||
} else {
|
||||
|
||||
@@ -2063,6 +2063,8 @@ public class MapleMap {
|
||||
|
||||
spos.y--;
|
||||
monster.setPosition(spos);
|
||||
monster.setSpawnEffect(effect);
|
||||
|
||||
spawnAndAddRangedMapObject(monster, new DelayedPacketCreation() {
|
||||
@Override
|
||||
public void sendPackets(MapleClient c) {
|
||||
@@ -2116,7 +2118,11 @@ public class MapleMap {
|
||||
spawnAndAddRangedMapObject(door, new DelayedPacketCreation() {
|
||||
@Override
|
||||
public void sendPackets(MapleClient c) {
|
||||
door.sendSpawnData(c, false);
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
if (chr != null) {
|
||||
door.sendSpawnData(c, false);
|
||||
chr.addVisibleMapObject(door);
|
||||
}
|
||||
}
|
||||
}, new SpawnCondition() {
|
||||
@Override
|
||||
@@ -2465,22 +2471,23 @@ public class MapleMap {
|
||||
chr.setMapId(mapid);
|
||||
chr.updateActiveEffects();
|
||||
|
||||
MapScriptManager msm = MapScriptManager.getInstance();
|
||||
if (chrSize == 1) {
|
||||
if(!hasItemMonitor()) {
|
||||
startItemMonitor();
|
||||
aggroMonitor.startAggroCoordinator();
|
||||
}
|
||||
|
||||
if (onFirstUserEnter.length() != 0 && !chr.hasEntered(onFirstUserEnter, mapid) && MapScriptManager.getInstance().scriptExists(onFirstUserEnter, true)) {
|
||||
chr.enteredScript(onFirstUserEnter, mapid);
|
||||
MapScriptManager.getInstance().runMapScript(chr.getClient(), onFirstUserEnter, true);
|
||||
if (onFirstUserEnter.length() != 0) {
|
||||
msm.runMapScript(chr.getClient(), "onFirstUserEnter/" + onFirstUserEnter, true);
|
||||
}
|
||||
}
|
||||
if (onUserEnter.length() != 0) {
|
||||
if (onUserEnter.equals("cygnusTest") && (mapid < 913040000 || mapid > 913040006)) {
|
||||
chr.saveLocation("INTRO");
|
||||
}
|
||||
MapScriptManager.getInstance().runMapScript(chr.getClient(), onUserEnter, false);
|
||||
|
||||
msm.runMapScript(chr.getClient(), "onUserEnter/" + onUserEnter, false);
|
||||
}
|
||||
if (FieldLimit.CANNOTUSEMOUNTS.check(fieldLimit) && chr.getBuffedValue(MapleBuffStat.MONSTER_RIDING) != null) {
|
||||
chr.cancelEffectFromBuffStat(MapleBuffStat.MONSTER_RIDING);
|
||||
@@ -3020,8 +3027,8 @@ public class MapleMap {
|
||||
}
|
||||
}
|
||||
|
||||
private void sendObjectPlacement(MapleClient mapleClient) {
|
||||
MapleCharacter chr = mapleClient.getPlayer();
|
||||
private void sendObjectPlacement(MapleClient c) {
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
Collection<MapleMapObject> objects;
|
||||
|
||||
objectRLock.lock();
|
||||
@@ -3033,7 +3040,7 @@ public class MapleMap {
|
||||
|
||||
for (MapleMapObject o : objects) {
|
||||
if (isNonRangedType(o.getType())) {
|
||||
o.sendSpawnData(mapleClient);
|
||||
o.sendSpawnData(c);
|
||||
} else if (o.getType() == MapleMapObjectType.MONSTER) {
|
||||
((MapleMonster) o).aggroUpdateController();
|
||||
} else if (o.getType() == MapleMapObjectType.SUMMON) {
|
||||
|
||||
@@ -50,7 +50,7 @@ public class MonsterCarnival {
|
||||
bluePortal = 1;
|
||||
}
|
||||
for (MaplePartyCharacter mpc : p1.getMembers()) {
|
||||
MapleCharacter mc = cs.getPlayerStorage().getCharacterById(mpc.getId());
|
||||
MapleCharacter mc = mpc.getPlayer();
|
||||
if (mc != null) {
|
||||
mc.setMonsterCarnival(this);
|
||||
mc.setTeam(0);
|
||||
@@ -64,7 +64,7 @@ public class MonsterCarnival {
|
||||
}
|
||||
}
|
||||
for (MaplePartyCharacter mpc : p2.getMembers()) {
|
||||
MapleCharacter mc = cs.getPlayerStorage().getCharacterById(mpc.getId());
|
||||
MapleCharacter mc = mpc.getPlayer();
|
||||
if (mc != null) {
|
||||
mc.setMonsterCarnival(this);
|
||||
mc.setTeam(1);
|
||||
@@ -213,7 +213,7 @@ public class MonsterCarnival {
|
||||
out = cs.getMapFactory().getMap(980000010);
|
||||
}
|
||||
for (MaplePartyCharacter mpc : leader1.getParty().getMembers()) {
|
||||
MapleCharacter mc = cs.getPlayerStorage().getCharacterById(mpc.getId());
|
||||
MapleCharacter mc = mpc.getPlayer();
|
||||
if (mc != null) {
|
||||
mc.resetCP();
|
||||
mc.setTeam(-1);
|
||||
@@ -224,7 +224,7 @@ public class MonsterCarnival {
|
||||
}
|
||||
}
|
||||
for (MaplePartyCharacter mpc : leader2.getParty().getMembers()) {
|
||||
MapleCharacter mc = cs.getPlayerStorage().getCharacterById(mpc.getId());
|
||||
MapleCharacter mc = mpc.getPlayer();
|
||||
if (mc != null) {
|
||||
mc.resetCP();
|
||||
mc.setTeam(-1);
|
||||
@@ -269,7 +269,7 @@ public class MonsterCarnival {
|
||||
Channel cs = map.getChannelServer();
|
||||
if (winningTeam == 0) {
|
||||
for (MaplePartyCharacter mpc : leader1.getParty().getMembers()) {
|
||||
MapleCharacter mc = cs.getPlayerStorage().getCharacterById(mpc.getId());
|
||||
MapleCharacter mc = mpc.getPlayer();
|
||||
if (mc != null) {
|
||||
mc.gainFestivalPoints(this.redTotalCP);
|
||||
mc.setMonsterCarnival(null);
|
||||
@@ -283,7 +283,7 @@ public class MonsterCarnival {
|
||||
}
|
||||
}
|
||||
for (MaplePartyCharacter mpc : leader2.getParty().getMembers()) {
|
||||
MapleCharacter mc = cs.getPlayerStorage().getCharacterById(mpc.getId());
|
||||
MapleCharacter mc = mpc.getPlayer();
|
||||
if (mc != null) {
|
||||
mc.gainFestivalPoints(this.blueTotalCP);
|
||||
mc.setMonsterCarnival(null);
|
||||
@@ -298,7 +298,7 @@ public class MonsterCarnival {
|
||||
}
|
||||
} else if (winningTeam == 1) {
|
||||
for (MaplePartyCharacter mpc : leader2.getParty().getMembers()) {
|
||||
MapleCharacter mc = cs.getPlayerStorage().getCharacterById(mpc.getId());
|
||||
MapleCharacter mc = mpc.getPlayer();
|
||||
if (mc != null) {
|
||||
mc.gainFestivalPoints(this.blueTotalCP);
|
||||
mc.setMonsterCarnival(null);
|
||||
@@ -312,7 +312,7 @@ public class MonsterCarnival {
|
||||
}
|
||||
}
|
||||
for (MaplePartyCharacter mpc : leader1.getParty().getMembers()) {
|
||||
MapleCharacter mc = cs.getPlayerStorage().getCharacterById(mpc.getId());
|
||||
MapleCharacter mc = mpc.getPlayer();
|
||||
if (mc != null) {
|
||||
mc.gainFestivalPoints(this.redTotalCP);
|
||||
mc.setMonsterCarnival(null);
|
||||
@@ -393,12 +393,10 @@ public class MonsterCarnival {
|
||||
if (chnl != chnl1) {
|
||||
throw new RuntimeException("Os lideres estao em canais diferentes.");
|
||||
}
|
||||
|
||||
Channel cs = map.getChannelServer();
|
||||
|
||||
map.killAllMonsters();
|
||||
for (MaplePartyCharacter mpc : leader1.getParty().getMembers()) {
|
||||
MapleCharacter mc;
|
||||
mc = cs.getPlayerStorage().getCharacterById(mpc.getId());
|
||||
MapleCharacter mc = mpc.getPlayer();
|
||||
if (mc != null) {
|
||||
if (redWin) {
|
||||
mc.getClient().announce(MaplePacketCreator.showEffect("quest/carnival/win"));
|
||||
@@ -412,8 +410,7 @@ public class MonsterCarnival {
|
||||
}
|
||||
}
|
||||
for (MaplePartyCharacter mpc : leader2.getParty().getMembers()) {
|
||||
MapleCharacter mc;
|
||||
mc = cs.getPlayerStorage().getCharacterById(mpc.getId());
|
||||
MapleCharacter mc = mpc.getPlayer();
|
||||
if (mc != null) {
|
||||
if (!redWin) {
|
||||
mc.getClient().announce(MaplePacketCreator.showEffect("quest/carnival/win"));
|
||||
|
||||
@@ -490,6 +490,8 @@ public class MapleQuest {
|
||||
ret = new BuffExceptRequirement(this, data);
|
||||
break;
|
||||
case SCRIPT:
|
||||
ret = new ScriptRequirement(this, data);
|
||||
break;
|
||||
case NORMAL_AUTO_START:
|
||||
case START:
|
||||
case END:
|
||||
@@ -561,7 +563,6 @@ public class MapleQuest {
|
||||
|
||||
public int getNpcRequirement(boolean complete) {
|
||||
Map<MapleQuestRequirementType, MapleQuestRequirement> reqs = !complete ? startReqs : completeReqs;
|
||||
|
||||
MapleQuestRequirement mqr = reqs.get(MapleQuestRequirementType.NPC);
|
||||
if (mqr != null) {
|
||||
return ((NpcRequirement) mqr).get();
|
||||
@@ -570,6 +571,17 @@ public class MapleQuest {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasScriptRequirement(boolean complete) {
|
||||
Map<MapleQuestRequirementType, MapleQuestRequirement> reqs = !complete ? startReqs : completeReqs;
|
||||
MapleQuestRequirement mqr = reqs.get(MapleQuestRequirementType.SCRIPT);
|
||||
|
||||
if (mqr != null) {
|
||||
return ((ScriptRequirement) mqr).get();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
53
src/server/quest/requirements/ScriptRequirement.java
Normal file
53
src/server/quest/requirements/ScriptRequirement.java
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server
|
||||
Copyleft (L) 2016 - 2018 RonanLana
|
||||
|
||||
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.quest.requirements;
|
||||
|
||||
import client.MapleCharacter;
|
||||
import provider.MapleData;
|
||||
import provider.MapleDataTool;
|
||||
import server.quest.MapleQuest;
|
||||
import server.quest.MapleQuestRequirementType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Ronan
|
||||
*/
|
||||
public class ScriptRequirement extends MapleQuestRequirement {
|
||||
private boolean reqScript;
|
||||
|
||||
public ScriptRequirement(MapleQuest quest, MapleData data) {
|
||||
super(MapleQuestRequirementType.BUFF);
|
||||
processData(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processData(MapleData data) {
|
||||
reqScript = !MapleDataTool.getString(data, "").isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean check(MapleCharacter chr, Integer npcid) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean get() {
|
||||
return reqScript;
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,7 @@ public class FilePrinter {
|
||||
MOB_MOVEMENT = "game/MobMovement.txt",
|
||||
MAP_SCRIPT = "game/mapscript/",
|
||||
DIRECTION = "game/directions/",
|
||||
GUILD_CHAR_ERROR = "guilds/GuildCharError.txt",
|
||||
SAVE_CHAR = "players/SaveToDB.txt",
|
||||
INSERT_CHAR = "players/InsertCharacter.txt",
|
||||
LOAD_CHAR = "players/LoadCharFromDB.txt",
|
||||
|
||||
Reference in New Issue
Block a user