More concurrency fixes + Zombify + BPQ available
Fixed some inconsistencies due to race conditions in the project, added Zombify monster effect, made BPQ available and some minor patches.
This commit is contained in:
@@ -138,3 +138,9 @@ Corre
|
|||||||
Agora é possível variar atributos de mobs a serem spawnados (classes ChangeableStats, OverrideStats).
|
Agora é possível variar atributos de mobs a serem spawnados (classes ChangeableStats, OverrideStats).
|
||||||
Removido ataques letais (1HP/1MP) de bosses em Dojo, que tornava impossível a completude do mesmo.
|
Removido ataques letais (1HP/1MP) de bosses em Dojo, que tornava impossível a completude do mesmo.
|
||||||
Adição de novos scripts de evento no jogo.
|
Adição de novos scripts de evento no jogo.
|
||||||
|
|
||||||
|
08 - 09 Abril 2017,
|
||||||
|
Adição de efeito: Zombify.
|
||||||
|
Adição da expedição BPQ.
|
||||||
|
Aprimoramento de métodos que usam acesso concorrente no projeto.
|
||||||
|
Diversas pequenas alterações nos WZs do cliente/servidor.
|
||||||
@@ -3,8 +3,7 @@
|
|||||||
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/2" lastBookmarkId="0"/>
|
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/2" lastBookmarkId="0"/>
|
||||||
<open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/2">
|
<open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/2">
|
||||||
<group>
|
<group>
|
||||||
<file>file:/C:/Nexon/MapleSolaxia/scripts/portal/outPerrion_2.js</file>
|
<file>file:/C:/Nexon/MapleSolaxia/src/server/maps/MapleMap.java</file>
|
||||||
<file>file:/C:/Nexon/MapleSolaxia/src/scripting/AbstractPlayerInteraction.java</file>
|
|
||||||
</group>
|
</group>
|
||||||
</open-files>
|
</open-files>
|
||||||
</project-private>
|
</project-private>
|
||||||
|
|||||||
13
scripts/map/onFirstUserEnter/balog_summon.js
Normal file
13
scripts/map/onFirstUserEnter/balog_summon.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
importPackage(Packages.server.life);
|
||||||
|
importPackage(Packages.tools);
|
||||||
|
importPackage(Packages.server.events);
|
||||||
|
|
||||||
|
function start(ms) {
|
||||||
|
try {
|
||||||
|
ms.getPlayer().resetEnteredScript();
|
||||||
|
ms.getPlayer().getClient().getSession().write(MaplePacketCreator.getClock(BalrogPQ.getSecondsLeft())); // 60 mins(1hr)
|
||||||
|
BalrogPQ.spawnBalrog(1, ms.getPlayer());
|
||||||
|
} catch(err) {
|
||||||
|
ms.getPlayer().dropMessage(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,45 +1,9 @@
|
|||||||
/*/*
|
importPackage(Packages.server.events);
|
||||||
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/>.
|
|
||||||
*/
|
|
||||||
//@Author FateJiki
|
|
||||||
//@Author Even (modifier)
|
|
||||||
importPackage(Packages.server.expeditions);
|
|
||||||
importPackage(Packages.tools);
|
|
||||||
importPackage(Packages.scripting.event);
|
|
||||||
|
|
||||||
|
|
||||||
var status = 0;
|
var status = 0;
|
||||||
var expedition;
|
|
||||||
var player;
|
|
||||||
var em;
|
|
||||||
//var barlog_easy = MapleExpeditionType.BALROG_EASY;
|
|
||||||
//var barlog_hard = MapleExpeditionType.BALROG_HARD;
|
|
||||||
|
|
||||||
function start(){
|
function start(){
|
||||||
status = 0;
|
status = 0;
|
||||||
|
action(1, 0, 0);
|
||||||
cm.sendNext("Hi there. I am #b#nMu Young#n#k, the temple Keeper. This expedition is currently unavailable.");
|
|
||||||
cm.dispose();
|
|
||||||
|
|
||||||
//action(1, 0, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function action(mode, type, selection){
|
function action(mode, type, selection){
|
||||||
|
|||||||
@@ -1,10 +1,51 @@
|
|||||||
|
importPackage(Packages.server.events);
|
||||||
|
|
||||||
|
var status = 0;
|
||||||
|
var dispose = false;
|
||||||
function start(){
|
function start(){
|
||||||
cm.sendYesNo("If you leave now, you'll have to start over. Are you sure you want to leave?");
|
status == 0;
|
||||||
|
action(1, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function action(mode, type, selection){
|
function action(mode, type, selection){
|
||||||
if (mode == 1) {
|
if(mode <= 0){
|
||||||
cm.warp(105100301);
|
if(!cm.getPlayer().getMap().getAllmonsters().size() == 2){
|
||||||
}
|
cm.sendOk("Alrighty. We have high hopes for you so make us mercenaries proud!");
|
||||||
|
cm.dispose();
|
||||||
|
} else {
|
||||||
|
cm.getPlayer().getMap().killAllMonsters();
|
||||||
|
BalrogPQ.partyLeader = "undefined";
|
||||||
|
BalrogPQ.balrogSpawned = false;
|
||||||
|
BalrogPQ.close();
|
||||||
|
cm.warp(105100100);
|
||||||
cm.dispose();
|
cm.dispose();
|
||||||
}
|
}
|
||||||
|
} else if(status == 0){
|
||||||
|
if(cm.getPlayer().getMap().getCharacters().size() > 1){
|
||||||
|
cm.sendYesNo("Are you really going to leave this battle and leave your fellow travelers to die?");
|
||||||
|
dispose = false;
|
||||||
|
status++;
|
||||||
|
} else if(cm.getPlayer().getMap().getCharacters().size() <= 1 && cm.getPlayer().getMap().getAllmonsters().size() != 2){
|
||||||
|
cm.sendYesNo("If you're a coward, you will leave.");
|
||||||
|
dispose = true;
|
||||||
|
status++;
|
||||||
|
} else if(cm.getPlayer().getMap().getAllmonsters().size() == 0){
|
||||||
|
cm.sendOk("Wow! You defeated the balrog.");
|
||||||
|
dispose = true;
|
||||||
|
cm.getPlayer().getClient().getChannelServer().broadcastPacket(Packages.tools.MaplePacketCreator.serverNotice(0, BalrogPQ.partyLeader + "'s party has successfully defeated the Balrog! Praise to them, they finished with " + cm.getPlayer().getMap().getCharacters().size() + " players."));
|
||||||
|
status++;
|
||||||
|
} else {
|
||||||
|
cm.sendYesNo("So you are really going to leave?");
|
||||||
|
status++;
|
||||||
|
}
|
||||||
|
} else if(status == 1){
|
||||||
|
if(dispose){
|
||||||
|
cm.getPlayer().getMap().killAllMonsters();
|
||||||
|
BalrogPQ.partyLeader = "undefined";
|
||||||
|
BalrogPQ.balrogSpawned = false;
|
||||||
|
BalrogPQ.close();
|
||||||
|
}
|
||||||
|
cm.warp(105100100);
|
||||||
|
cm.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18846,6 +18846,7 @@
|
|||||||
UPDATE drop_data SET chance=40000 WHERE itemid=4031991;
|
UPDATE drop_data SET chance=40000 WHERE itemid=4031991;
|
||||||
UPDATE drop_data SET questid=6191 WHERE itemid=4031477;
|
UPDATE drop_data SET questid=6191 WHERE itemid=4031477;
|
||||||
UPDATE drop_data SET questid=6190 WHERE itemid=4001111;
|
UPDATE drop_data SET questid=6190 WHERE itemid=4001111;
|
||||||
|
UPDATE drop_data SET questid=28282 WHERE itemid=4001373;
|
||||||
|
|
||||||
# two items named "Sparta": remove the entries where lv100 Sparta is being dropped by low-level mobs.
|
# two items named "Sparta": remove the entries where lv100 Sparta is being dropped by low-level mobs.
|
||||||
UPDATE IGNORE drop_data SET itemid=1402011 WHERE itemid=1302056 AND dropperid < 8000000;
|
UPDATE IGNORE drop_data SET itemid=1402011 WHERE itemid=1302056 AND dropperid < 8000000;
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ public enum MapleDisease {
|
|||||||
SLOW(0x1),
|
SLOW(0x1),
|
||||||
SEDUCE(0x80),
|
SEDUCE(0x80),
|
||||||
FISHABLE(0x100),
|
FISHABLE(0x100),
|
||||||
|
ZOMBIFY(0x4000),
|
||||||
CONFUSE(0x80000),
|
CONFUSE(0x80000),
|
||||||
STUN(0x2000000000000L),
|
STUN(0x2000000000000L),
|
||||||
POISON(0x4000000000000L),
|
POISON(0x4000000000000L),
|
||||||
|
|||||||
@@ -43,9 +43,9 @@ public enum ItemFactory {
|
|||||||
CASH_CYGNUS(4, false),
|
CASH_CYGNUS(4, false),
|
||||||
CASH_ARAN(5, false),
|
CASH_ARAN(5, false),
|
||||||
MERCHANT(6, false);
|
MERCHANT(6, false);
|
||||||
private int value;
|
private final int value;
|
||||||
private boolean account;
|
private final boolean account;
|
||||||
private static ReentrantLock lock = new ReentrantLock(true);
|
private static final ReentrantLock lock = new ReentrantLock(true);
|
||||||
|
|
||||||
private ItemFactory(int value, boolean account) {
|
private ItemFactory(int value, boolean account) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
|||||||
@@ -26,13 +26,14 @@ import java.util.Collection;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.locks.Lock;
|
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||||
|
|
||||||
public class PlayerStorage {
|
public class PlayerStorage {
|
||||||
private final ReentrantReadWriteLock locks = new ReentrantReadWriteLock();
|
private final ReentrantReadWriteLock locks = new ReentrantReadWriteLock(true);
|
||||||
private final Lock rlock = locks.readLock();
|
private final ReadLock rlock = locks.readLock();
|
||||||
private final Lock wlock = locks.writeLock();
|
private final WriteLock wlock = locks.writeLock();
|
||||||
private final Map<Integer, MapleCharacter> storage = new LinkedHashMap<>();
|
private final Map<Integer, MapleCharacter> storage = new LinkedHashMap<>();
|
||||||
|
|
||||||
public void addPlayer(MapleCharacter chr) {
|
public void addPlayer(MapleCharacter chr) {
|
||||||
@@ -98,6 +99,11 @@ public class PlayerStorage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getSize(){
|
public int getSize(){
|
||||||
|
rlock.lock();
|
||||||
|
try {
|
||||||
return storage.size();
|
return storage.size();
|
||||||
|
} finally {
|
||||||
|
rlock.unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -27,9 +27,11 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||||
|
|
||||||
import net.MapleServerHandler;
|
import net.MapleServerHandler;
|
||||||
@@ -72,6 +74,8 @@ public final class Channel {
|
|||||||
private Map<Integer, HiredMerchant> hiredMerchants = new HashMap<>();
|
private Map<Integer, HiredMerchant> hiredMerchants = new HashMap<>();
|
||||||
private final Map<Integer, Integer> storedVars = new HashMap<>();
|
private final Map<Integer, Integer> storedVars = new HashMap<>();
|
||||||
private ReentrantReadWriteLock merchant_lock = new ReentrantReadWriteLock(true);
|
private ReentrantReadWriteLock merchant_lock = new ReentrantReadWriteLock(true);
|
||||||
|
private ReadLock merchRlock = merchant_lock.readLock();
|
||||||
|
private WriteLock merchWlock = merchant_lock.writeLock();
|
||||||
private List<MapleExpedition> expeditions = new ArrayList<>();
|
private List<MapleExpedition> expeditions = new ArrayList<>();
|
||||||
private List<MapleExpeditionType> expedType = new ArrayList<>();
|
private List<MapleExpeditionType> expedType = new ArrayList<>();
|
||||||
private MapleEvent event;
|
private MapleEvent event;
|
||||||
@@ -130,8 +134,7 @@ public final class Channel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void closeAllMerchants() {
|
public void closeAllMerchants() {
|
||||||
WriteLock wlock = merchant_lock.writeLock();
|
merchWlock.lock();
|
||||||
wlock.lock();
|
|
||||||
try {
|
try {
|
||||||
final Iterator<HiredMerchant> hmit = hiredMerchants.values().iterator();
|
final Iterator<HiredMerchant> hmit = hiredMerchants.values().iterator();
|
||||||
while (hmit.hasNext()) {
|
while (hmit.hasNext()) {
|
||||||
@@ -141,7 +144,7 @@ public final class Channel {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} finally {
|
} finally {
|
||||||
wlock.unlock();
|
merchWlock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,26 +231,29 @@ public final class Channel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Map<Integer, HiredMerchant> getHiredMerchants() {
|
public Map<Integer, HiredMerchant> getHiredMerchants() {
|
||||||
return hiredMerchants;
|
merchRlock.lock();
|
||||||
|
try {
|
||||||
|
return Collections.unmodifiableMap(hiredMerchants);
|
||||||
|
} finally {
|
||||||
|
merchRlock.unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addHiredMerchant(int chrid, HiredMerchant hm) {
|
public void addHiredMerchant(int chrid, HiredMerchant hm) {
|
||||||
WriteLock wlock = merchant_lock.writeLock();
|
merchWlock.lock();
|
||||||
wlock.lock();
|
|
||||||
try {
|
try {
|
||||||
hiredMerchants.put(chrid, hm);
|
hiredMerchants.put(chrid, hm);
|
||||||
} finally {
|
} finally {
|
||||||
wlock.unlock();
|
merchWlock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeHiredMerchant(int chrid) {
|
public void removeHiredMerchant(int chrid) {
|
||||||
WriteLock wlock = merchant_lock.writeLock();
|
merchWlock.lock();
|
||||||
wlock.lock();
|
|
||||||
try {
|
try {
|
||||||
hiredMerchants.remove(chrid);
|
hiredMerchants.remove(chrid);
|
||||||
} finally {
|
} finally {
|
||||||
wlock.unlock();
|
merchWlock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,8 +30,9 @@ import java.util.LinkedList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.concurrent.locks.Lock;
|
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||||
|
|
||||||
import javax.script.ScriptException;
|
import javax.script.ScriptException;
|
||||||
|
|
||||||
@@ -64,7 +65,8 @@ public class EventInstanceManager {
|
|||||||
private List<Integer> mapIds = new LinkedList<Integer>();
|
private List<Integer> mapIds = new LinkedList<Integer>();
|
||||||
private List<Boolean> isInstanced = new LinkedList<Boolean>();
|
private List<Boolean> isInstanced = new LinkedList<Boolean>();
|
||||||
private final ReentrantReadWriteLock mutex = new ReentrantReadWriteLock();
|
private final ReentrantReadWriteLock mutex = new ReentrantReadWriteLock();
|
||||||
private final Lock rL = mutex.readLock(), wL = mutex.writeLock();
|
private final ReadLock rL = mutex.readLock();
|
||||||
|
private final WriteLock wL = mutex.writeLock();
|
||||||
private boolean disposed = false;
|
private boolean disposed = false;
|
||||||
|
|
||||||
public EventInstanceManager(EventManager em, String name) {
|
public EventInstanceManager(EventManager em, String name) {
|
||||||
@@ -148,12 +150,24 @@ public class EventInstanceManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getPlayerCount() {
|
public int getPlayerCount() {
|
||||||
|
rL.lock();
|
||||||
|
try {
|
||||||
return chars.size();
|
return chars.size();
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
|
rL.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public List<MapleCharacter> getPlayers() {
|
public List<MapleCharacter> getPlayers() {
|
||||||
|
rL.lock();
|
||||||
|
try {
|
||||||
return new ArrayList<>(chars);
|
return new ArrayList<>(chars);
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
|
rL.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void registerMonster(MapleMonster mob) {
|
public void registerMonster(MapleMonster mob) {
|
||||||
if (!mob.getStats().isFriendly()) { //We cannot register moon bunny
|
if (!mob.getStats().isFriendly()) { //We cannot register moon bunny
|
||||||
@@ -247,7 +261,14 @@ public class EventInstanceManager {
|
|||||||
} catch (ScriptException | NoSuchMethodException ex) {
|
} catch (ScriptException | NoSuchMethodException ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wL.lock();
|
||||||
|
try {
|
||||||
chars.clear();
|
chars.clear();
|
||||||
|
} finally {
|
||||||
|
wL.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
mobs.clear();
|
mobs.clear();
|
||||||
killCount.clear();
|
killCount.clear();
|
||||||
mapFactory = null;
|
mapFactory = null;
|
||||||
@@ -374,11 +395,10 @@ public class EventInstanceManager {
|
|||||||
map = this.getMapFactory().getMap(towarp);
|
map = this.getMapFactory().getMap(towarp);
|
||||||
}
|
}
|
||||||
|
|
||||||
wL.lock();
|
rL.lock();
|
||||||
try {
|
try {
|
||||||
if (chars != null && chars.size() <= size) {
|
if (chars != null && chars.size() <= size) {
|
||||||
final List<MapleCharacter> chrs = new LinkedList<MapleCharacter>(chars);
|
for (MapleCharacter chr : chars) {
|
||||||
for (MapleCharacter chr : chrs) {
|
|
||||||
if (chr == null) {
|
if (chr == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -393,7 +413,7 @@ public class EventInstanceManager {
|
|||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
} finally {
|
} finally {
|
||||||
wL.unlock();
|
rL.unlock();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -699,7 +699,8 @@ public class MapleStatEffect {
|
|||||||
AutobanFactory.MPCON.addPoint(applyfrom.getAutobanManager(), "mpCon hack for skill:" + sourceid + "; Player MP: " + applyto.getMp() + " MP Needed: " + getMpCon());
|
AutobanFactory.MPCON.addPoint(applyfrom.getAutobanManager(), "mpCon hack for skill:" + sourceid + "; Player MP: " + applyto.getMp() + " MP Needed: " + getMpCon());
|
||||||
} */
|
} */
|
||||||
if (hpchange != 0) {
|
if (hpchange != 0) {
|
||||||
if (hpchange < 0 && (-hpchange) > applyto.getHp()) {
|
if (hpchange < 0 && (-hpchange) > applyto.getHp() && !applyto.hasDisease(MapleDisease.ZOMBIFY)) {
|
||||||
|
applyto.getClient().announce(MaplePacketCreator.enableActions());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int newHp = applyto.getHp() + hpchange;
|
int newHp = applyto.getHp() + hpchange;
|
||||||
@@ -712,6 +713,7 @@ public class MapleStatEffect {
|
|||||||
int newMp = applyto.getMp() + mpchange;
|
int newMp = applyto.getMp() + mpchange;
|
||||||
if (mpchange != 0) {
|
if (mpchange != 0) {
|
||||||
if (mpchange < 0 && -mpchange > applyto.getMp()) {
|
if (mpchange < 0 && -mpchange > applyto.getMp()) {
|
||||||
|
applyto.getClient().announce(MaplePacketCreator.enableActions());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1037,12 +1039,18 @@ public class MapleStatEffect {
|
|||||||
} else {
|
} else {
|
||||||
hpchange += hp;
|
hpchange += hp;
|
||||||
}
|
}
|
||||||
} else {
|
if (applyfrom.hasDisease(MapleDisease.ZOMBIFY)) {
|
||||||
|
hpchange /= 2;
|
||||||
|
}
|
||||||
|
} else { // assumption: this is heal
|
||||||
hpchange += makeHealHP(hp / 100.0, applyfrom.getTotalMagic(), 3, 5);
|
hpchange += makeHealHP(hp / 100.0, applyfrom.getTotalMagic(), 3, 5);
|
||||||
|
if (applyfrom.hasDisease(MapleDisease.ZOMBIFY)) {
|
||||||
|
hpchange = -hpchange;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hpR != 0) {
|
if (hpR != 0) {
|
||||||
hpchange += (int) (applyfrom.getCurrentMaxHp() * hpR);
|
hpchange += (int) (applyfrom.getCurrentMaxHp() * hpR) / (applyfrom.hasDisease(MapleDisease.ZOMBIFY) ? 2 : 1);
|
||||||
applyfrom.checkBerserk();
|
applyfrom.checkBerserk();
|
||||||
}
|
}
|
||||||
if (primary) {
|
if (primary) {
|
||||||
|
|||||||
108
src/server/events/BalrogPQ.java
Normal file
108
src/server/events/BalrogPQ.java
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
package server.events;
|
||||||
|
import client.MapleCharacter;
|
||||||
|
import java.util.*;
|
||||||
|
import server.life.MapleLifeFactory;
|
||||||
|
import java.awt.Point;
|
||||||
|
import server.maps.MapleMap;
|
||||||
|
import server.TimerManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author FateJiki
|
||||||
|
* @Mapid 105100300
|
||||||
|
*/
|
||||||
|
public class BalrogPQ {
|
||||||
|
public static final int[] EasyBalrogParts = {8830002, 8830003, 8830000};
|
||||||
|
public static final int[] HardBalrogParts = {8830000, 8830001, 8830002};
|
||||||
|
public static List<MapleCharacter> candidates = new ArrayList<MapleCharacter>();
|
||||||
|
public static boolean hasStarted = false;
|
||||||
|
public static String partyLeader = "undefined";
|
||||||
|
public static boolean balrogSpawned = false;
|
||||||
|
public static long timeStamp = 0;
|
||||||
|
public static byte channel = 1;
|
||||||
|
|
||||||
|
public static void addCandidate(MapleCharacter chr){
|
||||||
|
synchronized(candidates){
|
||||||
|
candidates.add(chr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void warpAllCandidates(){
|
||||||
|
for(MapleCharacter c : candidates){
|
||||||
|
c.changeMap(105100300);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isFull(MapleCharacter chr){
|
||||||
|
return chr.getClient().getChannelServer().getMapFactory().getMap(105100300).getCharacters().size() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void warpIn(MapleCharacter chr){
|
||||||
|
if(hasStarted){
|
||||||
|
chr.changeMap(105100300);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void scheduleChecks(MapleMap map){
|
||||||
|
final MapleMap fmap = map;
|
||||||
|
TimerManager tMan = TimerManager.getInstance();
|
||||||
|
tMan.schedule(new Runnable(){
|
||||||
|
@Override
|
||||||
|
public void run(){
|
||||||
|
for(MapleCharacter chrs : fmap.getCharacters()){
|
||||||
|
chrs.changeMap(105100100);
|
||||||
|
chrs.message("You did not defeat the balrog in time..");
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} , 60 * 60 * 1000);
|
||||||
|
|
||||||
|
tMan.schedule(new Runnable(){
|
||||||
|
@Override
|
||||||
|
public void run(){
|
||||||
|
if(fmap.getCharacters().size() <= 3){
|
||||||
|
if(fmap.getCharacters().size() > 0){
|
||||||
|
for(MapleCharacter chrs : fmap.getCharacters()){
|
||||||
|
chrs.message("[The Order]: What? You're down to that many mercenaries? I need you get you out of there.");
|
||||||
|
chrs.changeMap(105100100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmap.killAllMonsters();
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} , 60 * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void open(MapleCharacter chr){
|
||||||
|
channel = (byte)chr.getClient().getChannel();
|
||||||
|
hasStarted = true;
|
||||||
|
timeStamp = System.currentTimeMillis();
|
||||||
|
scheduleChecks(chr.getClient().getChannelServer().getMapFactory().getMap(105100300));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getSecondsLeft(){ // assuming the thing lasts 60 minutes
|
||||||
|
int hour = 60 * 60; // 3600 seconds = 1hr
|
||||||
|
long elapsed = System.currentTimeMillis() - timeStamp;
|
||||||
|
int secondsLeft = (int)(hour - (elapsed / 1000));
|
||||||
|
return secondsLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void close(){
|
||||||
|
hasStarted = false;
|
||||||
|
balrogSpawned = false;
|
||||||
|
partyLeader = "undefined";
|
||||||
|
candidates.clear();
|
||||||
|
timeStamp = 0;
|
||||||
|
}
|
||||||
|
public static void spawnBalrog(int mode, MapleCharacter chr){
|
||||||
|
if(!balrogSpawned){
|
||||||
|
for(int i = 0; i < HardBalrogParts.length; i++){
|
||||||
|
chr.getClient().getChannelServer().getMapFactory().getMap(105100300).spawnMonsterOnGroundBelow(MapleLifeFactory.getMonster(HardBalrogParts[i]), new Point(412, 258));
|
||||||
|
balrogSpawned = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// DO NUFFIN'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -274,7 +274,7 @@ public class MobSkill {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
System.out.println("Unhandeled Mob skill: " + skillId);
|
System.out.println("Unhandled Mob skill: " + skillId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (stats.size() > 0) {
|
if (stats.size() > 0) {
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||||
import provider.MapleData;
|
import provider.MapleData;
|
||||||
import provider.MapleDataProvider;
|
import provider.MapleDataProvider;
|
||||||
import provider.MapleDataProviderFactory;
|
import provider.MapleDataProviderFactory;
|
||||||
@@ -42,20 +44,22 @@ public class MobSkillFactory {
|
|||||||
private static Map<String, MobSkill> mobSkills = new HashMap<String, MobSkill>();
|
private static Map<String, MobSkill> mobSkills = new HashMap<String, MobSkill>();
|
||||||
private final static MapleDataProvider dataSource = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Skill.wz"));
|
private final static MapleDataProvider dataSource = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Skill.wz"));
|
||||||
private static MapleData skillRoot = dataSource.getData("MobSkill.img");
|
private static MapleData skillRoot = dataSource.getData("MobSkill.img");
|
||||||
private static ReentrantReadWriteLock dataLock = new ReentrantReadWriteLock();
|
private final static ReentrantReadWriteLock dataLock = new ReentrantReadWriteLock();
|
||||||
|
private final static ReadLock rL = dataLock.readLock();
|
||||||
|
private final static WriteLock wL = dataLock.writeLock();
|
||||||
|
|
||||||
public static MobSkill getMobSkill(final int skillId, final int level) {
|
public static MobSkill getMobSkill(final int skillId, final int level) {
|
||||||
final String key = skillId + "" + level;
|
final String key = skillId + "" + level;
|
||||||
dataLock.readLock().lock();
|
rL.lock();
|
||||||
try {
|
try {
|
||||||
MobSkill ret = mobSkills.get(key);
|
MobSkill ret = mobSkills.get(key);
|
||||||
if (ret != null) {
|
if (ret != null) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
dataLock.readLock().unlock();
|
rL.unlock();
|
||||||
}
|
}
|
||||||
dataLock.writeLock().lock();
|
wL.lock();
|
||||||
try {
|
try {
|
||||||
MobSkill ret;
|
MobSkill ret;
|
||||||
ret = mobSkills.get(key);
|
ret = mobSkills.get(key);
|
||||||
@@ -103,7 +107,7 @@ public class MobSkillFactory {
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
} finally {
|
} finally {
|
||||||
dataLock.writeLock().unlock();
|
wL.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,7 +81,6 @@ import tools.Pair;
|
|||||||
import tools.Randomizer;
|
import tools.Randomizer;
|
||||||
|
|
||||||
public class MapleMap {
|
public class MapleMap {
|
||||||
|
|
||||||
private static final List<MapleMapObjectType> rangedMapobjectTypes = Arrays.asList(MapleMapObjectType.SHOP, MapleMapObjectType.ITEM, MapleMapObjectType.NPC, MapleMapObjectType.MONSTER, MapleMapObjectType.DOOR, MapleMapObjectType.SUMMON, MapleMapObjectType.REACTOR);
|
private static final List<MapleMapObjectType> rangedMapobjectTypes = Arrays.asList(MapleMapObjectType.SHOP, MapleMapObjectType.ITEM, MapleMapObjectType.NPC, MapleMapObjectType.MONSTER, MapleMapObjectType.DOOR, MapleMapObjectType.SUMMON, MapleMapObjectType.REACTOR);
|
||||||
private Map<Integer, MapleMapObject> mapobjects = new LinkedHashMap<>();
|
private Map<Integer, MapleMapObject> mapobjects = new LinkedHashMap<>();
|
||||||
private Collection<SpawnPoint> monsterSpawn = Collections.synchronizedList(new LinkedList<SpawnPoint>());
|
private Collection<SpawnPoint> monsterSpawn = Collections.synchronizedList(new LinkedList<SpawnPoint>());
|
||||||
@@ -875,8 +874,14 @@ public class MapleMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Collection<MapleMapObject> getMapObjects() {
|
public Collection<MapleMapObject> getMapObjects() {
|
||||||
|
objectRLock.lock();
|
||||||
|
try {
|
||||||
return Collections.unmodifiableCollection(mapobjects.values());
|
return Collections.unmodifiableCollection(mapobjects.values());
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
|
objectRLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean containsNPC(int npcid) {
|
public boolean containsNPC(int npcid) {
|
||||||
if (npcid == 9000066) {
|
if (npcid == 9000066) {
|
||||||
@@ -898,7 +903,12 @@ public class MapleMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public MapleMapObject getMapObject(int oid) {
|
public MapleMapObject getMapObject(int oid) {
|
||||||
|
objectRLock.lock();
|
||||||
|
try {
|
||||||
return mapobjects.get(oid);
|
return mapobjects.get(oid);
|
||||||
|
} finally {
|
||||||
|
objectRLock.unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1285,11 +1295,9 @@ public class MapleMap {
|
|||||||
|
|
||||||
public void addPlayer(final MapleCharacter chr) {
|
public void addPlayer(final MapleCharacter chr) {
|
||||||
chrWLock.lock();
|
chrWLock.lock();
|
||||||
chrRLock.lock();
|
|
||||||
try {
|
try {
|
||||||
characters.add(chr);
|
characters.add(chr);
|
||||||
} finally {
|
} finally {
|
||||||
chrRLock.unlock();
|
|
||||||
chrWLock.unlock();
|
chrWLock.unlock();
|
||||||
}
|
}
|
||||||
chr.setMapId(mapid);
|
chr.setMapId(mapid);
|
||||||
@@ -1528,11 +1536,9 @@ public class MapleMap {
|
|||||||
|
|
||||||
public void removePlayer(MapleCharacter chr) {
|
public void removePlayer(MapleCharacter chr) {
|
||||||
chrWLock.lock();
|
chrWLock.lock();
|
||||||
chrRLock.lock();
|
|
||||||
try {
|
try {
|
||||||
characters.remove(chr);
|
characters.remove(chr);
|
||||||
} finally {
|
} finally {
|
||||||
chrRLock.unlock();
|
|
||||||
chrWLock.unlock();
|
chrWLock.unlock();
|
||||||
}
|
}
|
||||||
removeMapObject(chr.getObjectId());
|
removeMapObject(chr.getObjectId());
|
||||||
@@ -1841,6 +1847,8 @@ public class MapleMap {
|
|||||||
player.setPosition(newPosition);
|
player.setPosition(newPosition);
|
||||||
Collection<MapleMapObject> visibleObjects = player.getVisibleMapObjects();
|
Collection<MapleMapObject> visibleObjects = player.getVisibleMapObjects();
|
||||||
MapleMapObject[] visibleObjectsNow = visibleObjects.toArray(new MapleMapObject[visibleObjects.size()]);
|
MapleMapObject[] visibleObjectsNow = visibleObjects.toArray(new MapleMapObject[visibleObjects.size()]);
|
||||||
|
|
||||||
|
objectRLock.lock();
|
||||||
try {
|
try {
|
||||||
for (MapleMapObject mo : visibleObjectsNow) {
|
for (MapleMapObject mo : visibleObjectsNow) {
|
||||||
if (mo != null) {
|
if (mo != null) {
|
||||||
@@ -1853,7 +1861,10 @@ public class MapleMap {
|
|||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
objectRLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (MapleMapObject mo : getMapObjectsInRange(player.getPosition(), 722500, rangedMapobjectTypes)) {
|
for (MapleMapObject mo : getMapObjectsInRange(player.getPosition(), 722500, rangedMapobjectTypes)) {
|
||||||
if (!player.isMapObjectVisible(mo)) {
|
if (!player.isMapObjectVisible(mo)) {
|
||||||
mo.sendSpawnData(player.getClient());
|
mo.sendSpawnData(player.getClient());
|
||||||
@@ -2399,6 +2410,8 @@ public class MapleMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void toggleHiddenNPC(int id) {
|
public void toggleHiddenNPC(int id) {
|
||||||
|
objectRLock.lock();
|
||||||
|
try {
|
||||||
for (MapleMapObject obj : mapobjects.values()) {
|
for (MapleMapObject obj : mapobjects.values()) {
|
||||||
if (obj.getType() == MapleMapObjectType.NPC) {
|
if (obj.getType() == MapleMapObjectType.NPC) {
|
||||||
MapleNPC npc = (MapleNPC) obj;
|
MapleNPC npc = (MapleNPC) obj;
|
||||||
@@ -2411,6 +2424,9 @@ public class MapleMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
objectRLock.unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMobInterval(short interval) {
|
public void setMobInterval(short interval) {
|
||||||
|
|||||||
@@ -9646,6 +9646,7 @@
|
|||||||
</canvas>
|
</canvas>
|
||||||
<int name="price" value="1"/>
|
<int name="price" value="1"/>
|
||||||
<int name="slotMax" value="200"/>
|
<int name="slotMax" value="200"/>
|
||||||
|
<int name="quest" value="1"/>
|
||||||
</imgdir>
|
</imgdir>
|
||||||
</imgdir>
|
</imgdir>
|
||||||
<imgdir name="04002000">
|
<imgdir name="04002000">
|
||||||
|
|||||||
@@ -12821,6 +12821,13 @@
|
|||||||
<imgdir name="0">
|
<imgdir name="0">
|
||||||
</imgdir>
|
</imgdir>
|
||||||
<imgdir name="1">
|
<imgdir name="1">
|
||||||
|
<imgdir name="item">
|
||||||
|
<imgdir name="0">
|
||||||
|
<int name="count" value="1"/>
|
||||||
|
<int name="id" value="1142079"/>
|
||||||
|
</imgdir>
|
||||||
|
</imgdir>
|
||||||
|
<int name="exp" value="6800"/>
|
||||||
</imgdir>
|
</imgdir>
|
||||||
</imgdir>
|
</imgdir>
|
||||||
<imgdir name="2245">
|
<imgdir name="2245">
|
||||||
|
|||||||
@@ -24325,11 +24325,16 @@
|
|||||||
<imgdir name="2244">
|
<imgdir name="2244">
|
||||||
<imgdir name="0">
|
<imgdir name="0">
|
||||||
<int name="npc" value="1061017"/>
|
<int name="npc" value="1061017"/>
|
||||||
<int name="lvmin" value="10"/>
|
<int name="lvmin" value="50"/>
|
||||||
</imgdir>
|
</imgdir>
|
||||||
<imgdir name="1">
|
<imgdir name="1">
|
||||||
<int name="npc" value="1061017"/>
|
<int name="npc" value="1061017"/>
|
||||||
<string name="endscript" value="q2244e"/>
|
<imgdir name="mob">
|
||||||
|
<imgdir name="0">
|
||||||
|
<int name="count" value="200"/>
|
||||||
|
<int name="id" value="8830003"/>
|
||||||
|
</imgdir>
|
||||||
|
</imgdir>
|
||||||
</imgdir>
|
</imgdir>
|
||||||
</imgdir>
|
</imgdir>
|
||||||
<imgdir name="2245">
|
<imgdir name="2245">
|
||||||
|
|||||||
Reference in New Issue
Block a user