Savior Commit
Fixed some bugs regarding dojo, updated drop data, minor tweaks on Mystic Doors, added expeditions for Showa Manor, Zakum and Pink Bean, smart search for item slots on quest/npc rewarding system, attempt on boss HPbar to focus on player's current target, quests with selectable rewards now hands the item correctly, after the first PQ instance next ones are loaded more smoothly.
This commit is contained in:
@@ -60,10 +60,10 @@ import client.inventory.MapleInventory;
|
||||
import client.inventory.MapleInventoryType;
|
||||
import client.inventory.MaplePet;
|
||||
import client.inventory.ModifyInventory;
|
||||
import client.inventory.PetDataFactory;
|
||||
import constants.ItemConstants;
|
||||
import constants.ServerConstants;
|
||||
import server.life.MapleNPC;
|
||||
import tools.Pair;
|
||||
|
||||
public class AbstractPlayerInteraction {
|
||||
|
||||
@@ -113,22 +113,24 @@ public class AbstractPlayerInteraction {
|
||||
getPlayer().getMap().warpEveryone(map);
|
||||
}
|
||||
|
||||
public void warpParty(int id) {
|
||||
if (getPlayer().getParty() != null) {
|
||||
MaplePartyCharacter leader = getPlayer().getParty().getMemberById(getPlayer().getParty().getLeaderId());
|
||||
if(leader != null) {
|
||||
int leaderMapId = leader.getMapId();
|
||||
|
||||
for (MapleCharacter mc : getPartyMembers()) {
|
||||
if(mc.getMapId() == leaderMapId) {
|
||||
if (id == 925020100) {
|
||||
mc.setDojoParty(true);
|
||||
}
|
||||
mc.changeMap(id);
|
||||
}
|
||||
}
|
||||
public void warpParty(int id) {
|
||||
warpParty(id, 0);
|
||||
}
|
||||
|
||||
public void warpParty(int id, int portalId) {
|
||||
warpParty(id, portalId, getMapId(), getMapId());
|
||||
}
|
||||
|
||||
public void warpParty(int id, int fromMinId, int fromMaxId) {
|
||||
warpParty(id, 0, fromMinId, fromMaxId);
|
||||
}
|
||||
|
||||
public void warpParty(int id, int portalId, int fromMinId, int fromMaxId) {
|
||||
for (MapleCharacter mc : getPartyMembers()) {
|
||||
if(mc.getMapId() >= fromMinId && mc.getMapId() <= fromMaxId) {
|
||||
mc.changeMap(id, portalId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<MapleCharacter> getPartyMembers() {
|
||||
@@ -205,6 +207,29 @@ public class AbstractPlayerInteraction {
|
||||
public boolean canHold(int itemid, int quantity) {
|
||||
return getPlayer().canHold(itemid, quantity);
|
||||
}
|
||||
|
||||
private List<Integer> convertToIntegerArray(List<Double> list) {
|
||||
List<Integer> intList = new LinkedList<>();
|
||||
for(Double d: list) intList.add(d.intValue());
|
||||
|
||||
return intList;
|
||||
}
|
||||
|
||||
public boolean canHoldAll(List<Double> itemids, List<Double> quantity) {
|
||||
return canHoldAll(convertToIntegerArray(itemids), convertToIntegerArray(quantity), true);
|
||||
}
|
||||
|
||||
private boolean canHoldAll(List<Integer> itemids, List<Integer> quantity, boolean isInteger) {
|
||||
int size = Math.min(itemids.size(), quantity.size());
|
||||
|
||||
List<Pair<Item, MapleInventoryType>> addedItems = new LinkedList<>();
|
||||
for(int i = 0; i < size; i++) {
|
||||
Item it = new Item(itemids.get(i), (short) 0, quantity.get(i).shortValue());
|
||||
addedItems.add(new Pair<>(it, MapleItemInformationProvider.getInstance().getInventoryType(itemids.get(i))));
|
||||
}
|
||||
|
||||
return MapleInventory.checkSpots(c.getPlayer(), addedItems);
|
||||
}
|
||||
|
||||
//---- \/ \/ \/ \/ \/ \/ \/ NOT TESTED \/ \/ \/ \/ \/ \/ \/ \/ \/ ----
|
||||
|
||||
|
||||
@@ -116,6 +116,10 @@ public class EventInstanceManager {
|
||||
mapFactory = new MapleMapFactory(this, MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Map.wz")), MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/String.wz")), (byte) 0, (byte) 1);//Fk this
|
||||
mapFactory.setChannel(em.getChannelServer().getId());
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public EventManager getEm() {
|
||||
return em;
|
||||
@@ -239,8 +243,10 @@ public class EventInstanceManager {
|
||||
}
|
||||
|
||||
public void dropMessage(int type, String message) {
|
||||
for (MapleCharacter chr : getPlayers()) {
|
||||
chr.dropMessage(type, message);
|
||||
if(!eventCleared) {
|
||||
for (MapleCharacter chr : getPlayers()) {
|
||||
chr.dropMessage(type, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -346,21 +352,22 @@ public class EventInstanceManager {
|
||||
}
|
||||
|
||||
public void unregisterPlayer(MapleCharacter chr) {
|
||||
try {
|
||||
em.getIv().invokeFunction("playerUnregistered", EventInstanceManager.this, chr);
|
||||
} catch (ScriptException | NoSuchMethodException ex) {
|
||||
Logger.getLogger(EventManager.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
|
||||
wL.lock();
|
||||
try {
|
||||
try {
|
||||
em.getIv().invokeFunction("playerUnregistered", EventInstanceManager.this, chr);
|
||||
} catch (ScriptException | NoSuchMethodException ex) {
|
||||
Logger.getLogger(EventManager.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
|
||||
chars.remove(chr.getId());
|
||||
gridRemove(chr);
|
||||
dropExclusiveItems(chr);
|
||||
} finally {
|
||||
wL.unlock();
|
||||
}
|
||||
|
||||
|
||||
gridRemove(chr);
|
||||
dropExclusiveItems(chr);
|
||||
|
||||
chr.setEventInstance(null);
|
||||
}
|
||||
|
||||
@@ -832,33 +839,37 @@ public class EventInstanceManager {
|
||||
|
||||
//gives out EXP & a random item in a similar fashion of when clearing KPQ, LPQ, etc.
|
||||
public final boolean giveEventReward(MapleCharacter player, int eventLevel) {
|
||||
List<Integer> rewardsSet, rewardsQty;
|
||||
Integer rewardExp;
|
||||
|
||||
rL.lock();
|
||||
try {
|
||||
eventLevel--; //event level starts counting from 1
|
||||
if(eventLevel >= collectionSet.size()) return true;
|
||||
|
||||
List<Integer> rewardsSet = collectionSet.get(eventLevel);
|
||||
List<Integer> rewardsQty = collectionQty.get(eventLevel);
|
||||
rewardsSet = collectionSet.get(eventLevel);
|
||||
rewardsQty = collectionQty.get(eventLevel);
|
||||
|
||||
Integer rewardExp = collectionExp.get(eventLevel);
|
||||
if(rewardExp == null) rewardExp = 0;
|
||||
|
||||
if(rewardsSet == null || rewardsSet.isEmpty()) {
|
||||
if(rewardExp > 0) player.gainExp(rewardExp);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!hasRewardSlot(player, eventLevel)) return false;
|
||||
|
||||
AbstractPlayerInteraction api = player.getClient().getAbstractPlayerInteraction();
|
||||
int rnd = (int)Math.floor(Math.random() * rewardsSet.size());
|
||||
|
||||
api.gainItem(rewardsSet.get(rnd), rewardsQty.get(rnd).shortValue());
|
||||
if(rewardExp > 0) player.gainExp(rewardExp);
|
||||
return true;
|
||||
rewardExp = collectionExp.get(eventLevel);
|
||||
} finally {
|
||||
rL.unlock();
|
||||
}
|
||||
|
||||
if(rewardExp == null) rewardExp = 0;
|
||||
|
||||
if(rewardsSet == null || rewardsSet.isEmpty()) {
|
||||
if(rewardExp > 0) player.gainExp(rewardExp);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!hasRewardSlot(player, eventLevel)) return false;
|
||||
|
||||
AbstractPlayerInteraction api = player.getClient().getAbstractPlayerInteraction();
|
||||
int rnd = (int)Math.floor(Math.random() * rewardsSet.size());
|
||||
|
||||
api.gainItem(rewardsSet.get(rnd), rewardsQty.get(rnd).shortValue());
|
||||
if(rewardExp > 0) player.gainExp(rewardExp);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void disposeExpedition() {
|
||||
@@ -898,10 +909,12 @@ public class EventInstanceManager {
|
||||
}
|
||||
|
||||
public final boolean isEventTeamLackingNow(boolean testLeader, int minPlayers, MapleCharacter quitter) {
|
||||
if(eventCleared && getPlayerCount() > 1) return false;
|
||||
|
||||
if(!eventCleared && testLeader && getLeaderId() == quitter.getId()) return true;
|
||||
if(getPlayerCount() <= minPlayers) return true;
|
||||
if(eventCleared) {
|
||||
if(getPlayerCount() <= 1) return true;
|
||||
} else {
|
||||
if(testLeader && getLeaderId() == quitter.getId()) return true;
|
||||
if(getPlayerCount() <= minPlayers) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -52,10 +52,12 @@ import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import server.quest.MapleQuest;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Matze
|
||||
* @author Ronan
|
||||
*/
|
||||
public class EventManager {
|
||||
private Invocable iv;
|
||||
@@ -67,9 +69,12 @@ public class EventManager {
|
||||
private final Queue<Integer> queuedGuilds = new LinkedList<>();
|
||||
private final Map<Integer, Integer> queuedGuildLeaders = new HashMap<>();
|
||||
private List<Boolean> openedLobbys;
|
||||
private List<EventInstanceManager> readyInstances = new LinkedList<>();
|
||||
private Integer readyId = 0;
|
||||
private Properties props = new Properties();
|
||||
private String name;
|
||||
private Lock lobbyLock = new ReentrantLock();
|
||||
private Lock queueLock = new ReentrantLock();
|
||||
|
||||
private static final int limitGuilds = 10; // max numbers of guilds in queue for GPQ.
|
||||
private static final int maxLobbys = 8; // an event manager holds up to this amount of concurrent lobbys
|
||||
@@ -166,7 +171,14 @@ public class EventManager {
|
||||
}
|
||||
|
||||
public EventInstanceManager newInstance(String name) {
|
||||
EventInstanceManager ret = new EventInstanceManager(this, name);
|
||||
EventInstanceManager ret = getReadyInstance();
|
||||
|
||||
if(ret == null) {
|
||||
ret = new EventInstanceManager(this, name);
|
||||
} else {
|
||||
ret.setName(name);
|
||||
}
|
||||
|
||||
instances.put(name, ret);
|
||||
return ret;
|
||||
}
|
||||
@@ -510,8 +522,8 @@ public class EventManager {
|
||||
|
||||
private void exportReadyGuild(Integer guildId) {
|
||||
MapleGuild mg = server.getGuild(guildId);
|
||||
String callout = "Your guild has been registered to attend to the Sharenian Guild Quest at channel " + this.getChannelServer().getId()
|
||||
+ " and HAS JUST STARTED THE STRATEGY PHASE. After 3 minutes, no more guild members will be allowed to join the effort."
|
||||
String callout = "[Guild Quest] Your guild has been registered to attend to the Sharenian Guild Quest at channel " + this.getChannelServer().getId()
|
||||
+ " and HAS JUST STARTED THE STRATEGY PHASE. After 3 minutes, no more guild members will be allowed to join the effort."
|
||||
+ " Check out Shuang at the excavation site in Perion for more info.";
|
||||
|
||||
mg.dropMessage(0, callout);
|
||||
@@ -519,7 +531,7 @@ public class EventManager {
|
||||
|
||||
private void exportMovedQueueToGuild(Integer guildId, int place) {
|
||||
MapleGuild mg = server.getGuild(guildId);
|
||||
String callout = "Your guild has been registered to attend to the Sharenian Guild Quest at channel " + this.getChannelServer().getId()
|
||||
String callout = "[Guild Quest] Your guild has been registered to attend to the Sharenian Guild Quest at channel " + this.getChannelServer().getId()
|
||||
+ " and is currently on the " + ordinal(place) + " place on the waiting queue.";
|
||||
|
||||
mg.dropMessage(0, callout);
|
||||
@@ -606,4 +618,64 @@ public class EventManager {
|
||||
|
||||
return startInstance(chr);
|
||||
}
|
||||
}
|
||||
|
||||
public void startQuest(MapleCharacter chr, int id, int npcid) {
|
||||
try {
|
||||
MapleQuest.getInstance(id).forceStart(chr, npcid);
|
||||
} catch (NullPointerException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void completeQuest(MapleCharacter chr, int id, int npcid) {
|
||||
try {
|
||||
MapleQuest.getInstance(id).forceComplete(chr, npcid);
|
||||
} catch (NullPointerException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void fillEimQueue() {
|
||||
Thread t = new Thread(new EventManagerWorker()); //call new thread to fill up readied instances queue
|
||||
t.start();
|
||||
}
|
||||
|
||||
private EventInstanceManager getReadyInstance() {
|
||||
queueLock.lock();
|
||||
try {
|
||||
if(readyInstances.isEmpty()) {
|
||||
fillEimQueue();
|
||||
return null;
|
||||
}
|
||||
|
||||
EventInstanceManager eim = readyInstances.remove(0);
|
||||
fillEimQueue();
|
||||
|
||||
return eim;
|
||||
} finally {
|
||||
queueLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private void instantiateQueuedInstance() {
|
||||
queueLock.lock();
|
||||
try {
|
||||
if(readyInstances.size() >= Math.ceil((double)maxLobbys / 3.0)) return;
|
||||
|
||||
readyInstances.add(new EventInstanceManager(this, "sampleName" + readyId));
|
||||
readyId++;
|
||||
} finally {
|
||||
queueLock.unlock();
|
||||
}
|
||||
|
||||
instantiateQueuedInstance(); // keep filling the queue until reach threshold.
|
||||
}
|
||||
|
||||
private class EventManagerWorker implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
instantiateQueuedInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,11 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
package scripting.npc;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import net.server.Server;
|
||||
import net.server.guild.MapleAlliance;
|
||||
@@ -48,7 +44,6 @@ import server.partyquest.Pyramid;
|
||||
import server.partyquest.Pyramid.PyramidMode;
|
||||
import server.quest.MapleQuest;
|
||||
import tools.LogHelper;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.FilePrinter;
|
||||
import tools.MaplePacketCreator;
|
||||
import client.MapleCharacter;
|
||||
@@ -60,12 +55,8 @@ import client.Skill;
|
||||
import client.SkillFactory;
|
||||
import client.inventory.Item;
|
||||
import client.inventory.ItemFactory;
|
||||
import client.inventory.MapleInventoryType;
|
||||
import client.inventory.MaplePet;
|
||||
import constants.ExpTable;
|
||||
import constants.ServerConstants;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
|
||||
@@ -64,12 +64,12 @@ public class QuestActionManager extends NPCConversationManager {
|
||||
return forceCompleteQuest(quest);
|
||||
}
|
||||
|
||||
// For compatability with some older scripts...
|
||||
// For compatibility with some older scripts...
|
||||
public void startQuest() {
|
||||
forceStartQuest();
|
||||
}
|
||||
|
||||
// For compatability with some older scripts...
|
||||
// For compatibility with some older scripts...
|
||||
public void completeQuest() {
|
||||
forceCompleteQuest();
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ import scripting.event.EventManager;
|
||||
import server.MapleItemInformationProvider;
|
||||
import server.TimerManager;
|
||||
import server.life.MapleLifeFactory;
|
||||
import server.life.MapleMonster;
|
||||
import server.maps.MapMonitor;
|
||||
import server.maps.MapleReactor;
|
||||
import server.maps.ReactorDropEntry;
|
||||
@@ -163,6 +164,14 @@ public class ReactorActionManager extends AbstractPlayerInteraction {
|
||||
public void spawnNpc(int npcId, Point pos) {
|
||||
spawnNpc(npcId, pos, reactor.getMap());
|
||||
}
|
||||
|
||||
public void hitMonsterWithReactor(int id, int hitsToKill) { // until someone comes with a better solution, why not?
|
||||
MapleMonster mm = reactor.getMap().getMonsterById(id);
|
||||
if(mm != null) {
|
||||
int damage = (int)Math.ceil(mm.getMaxHp() / hitsToKill);
|
||||
reactor.getMap().damageMonster(this.getPlayer(), mm, damage);
|
||||
}
|
||||
}
|
||||
|
||||
public MapleReactor getReactor() {
|
||||
return reactor;
|
||||
|
||||
Reference in New Issue
Block a user