Fixed quest rewarding + Lethal attacks in Dojo

Fixed quests not giving items in some cases, lethal damages rendering
dojo uncompletable and added new scripts.
This commit is contained in:
ronancpl
2017-04-07 21:42:42 -03:00
parent f6935d3d3b
commit c8f905e1a5
23 changed files with 7503 additions and 6922 deletions
+6
View File
@@ -132,3 +132,9 @@ Corre
06 Abril 2017,
Tentativa de correção em casos de falta de respawn em certas areas do jogo.
Otimização de funções que lidam com popular ou despopular areas.
07 Abril 2017,
Correção nos métodos que completam quests, que não atribuíam corretamente itens que dependem de jobs.
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.
Adição de novos scripts de evento no jogo.
+1 -11
View File
@@ -2,16 +2,6 @@
<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
<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">
<group>
<file>file:/C:/Nexon/MapleSolaxia/src/scripting/event/EventManager.java</file>
<file>file:/C:/Nexon/MapleSolaxia/scripts/npc/world0/2012001.js</file>
<file>file:/C:/Nexon/MapleSolaxia/src/net/SendOpcode.java</file>
<file>file:/C:/Nexon/MapleSolaxia/src/server/life/SpawnPoint.java</file>
<file>file:/C:/Nexon/MapleSolaxia/scripts/npc/world0/2012002.js</file>
<file>file:/C:/Nexon/MapleSolaxia/src/server/maps/MapleMapFactory.java</file>
<file>file:/C:/Nexon/MapleSolaxia/src/tools/MaplePacketCreator.java</file>
<file>file:/C:/Nexon/MapleSolaxia/scripts/event/Boats.js</file>
<file>file:/C:/Nexon/MapleSolaxia/src/server/maps/MapleMap.java</file>
</group>
<group/>
</open-files>
</project-private>
+76
View File
@@ -0,0 +1,76 @@
function init() {
// After loading, ChannelServer
}
function setup(eim, leaderid) {
// Setup the instance when invoked, EG : start PQ
}
function playerEntry(eim, player) {
// Warp player in etc..
}
function changedMap(eim, player, mapid) {
// What to do when player've changed map, based on the mapid
}
function scheduledTimeout(eim) {
// When event timeout..
// restartEventTimer(long time)
// stopEventTimer()
// startEventTimer(long time)
// isTimerStarted()
}
function allMonstersDead(eim) {
// When invoking unregisterMonster(MapleMonster mob) OR killed
// Happens only when size = 0
}
function playerDead(eim, player) {
// Happens when player dies
}
function playerRevive(eim, player) {
// Happens when player's revived.
// @Param : returns true/false
}
function playerDisconnected(eim, player) {
// return 0 - Deregister player normally + Dispose instance if there are zero player left
// return x that is > 0 - Deregister player normally + Dispose instance if there x player or below
// return x that is < 0 - Deregister player normally + Dispose instance if there x player or below, if it's leader = boot all
}
function monsterValue(eim, mobid) {
// Invoked when a monster that's registered has been killed
// return x amount for this player - "Saved Points"
}
function leftParty(eim, player) {
// Happens when a player left the party
}
function disbandParty(eim, player) {
// Happens when the party is disbanded by the leader.
}
function clearPQ(eim) {
// Happens when the function EventInstanceManager.finishPQ() is invoked by NPC/Reactor script
}
function removePlayer(eim, player) {
// Happens when the funtion NPCConversationalManager.removePlayerFromInstance() is invoked
}
function registerCarnivalParty(eim, carnivalparty) {
// Happens when carnival PQ is started. - Unused for now.
}
function onMapLoad(eim, player) {
// Happens when player change map - Unused for now.
}
function cancelSchedule() {
}
+84
View File
@@ -0,0 +1,84 @@
/*
* 4th Job Snipe / Concentration
*/
function init() {
em.setProperty("started", "false");
}
function monsterValue(eim, mobId) {
return 1;
}
function setup() {
var eim = em.newInstance("s4aWorld");
eim.setInstanceMap(910500000).resetFully();
eim.startEventTimer(1200000);
em.setProperty("started", "true");
return eim;
}
function playerEntry(eim, player) {
var map = eim.getMapFactory().getMap(910500000);
player.changeMap(map, map.getPortal(0));
}
function playerDead(eim, player) {
}
function playerRevive(eim, player) {
}
function scheduledTimeout(eim) {
eim.disposeIfPlayerBelow(100, 105090200);
em.setProperty("started", "false");
}
function changedMap(eim, player, mapid) {
if (mapid != 910500000) {
eim.unregisterPlayer(player);
if (eim.disposeIfPlayerBelow(0, 0)) {
em.setProperty("started", "false");
}
}
}
function playerDisconnected(eim, player) {
return 0;
}
function leftParty(eim, player) {
// If only 2 players are left, uncompletable:
playerExit(eim, player);
}
function disbandParty(eim) {
//boot whole party and end
eim.disposeIfPlayerBelow(100, 105090200);
em.setProperty("started", "false");
}
function playerExit(eim, player) {
eim.unregisterPlayer(player);
var map = eim.getMapFactory().getMap(105090200);
player.changeMap(map, map.getPortal(0));
}
function clearPQ(eim) {
eim.disposeIfPlayerBelow(100, 105090200);
em.setProperty("started", "false");
}
function allMonstersDead(eim) {
//has nothing to do with monster killing
}
function cancelSchedule() {
}
+62
View File
@@ -0,0 +1,62 @@
/*
NPC Name: Insiginificant Being
Map(s): Dungeon : Another Entrance
Description: Takes you to another Dimension
*/
function start() {
if (cm.getQuestStatus(6108) == 1) {
var ret = checkJob();
if (ret == -1) {
cm.sendOk("Please form a party and talk to me again.");
} else if (ret == 0) {
cm.sendOk("Please make sure that your party is a size of 2.");
} else if (ret == 1) {
cm.sendOk("One of your party member's job is not eligible for entering the other world.");
} else if (ret == 2) {
cm.sendOk("One of your party member's level is not eligible for entering the other world.");
} else {
var em = cm.getEventManager("s4aWorld");
if (em == null) {
cm.sendOk("You're not allowed to enter with unknown reason. Try again." );
} else if (em.getProperty("started").equals("true")) {
cm.sendOk("Someone else is already attempting to defeat the Jr.Balrog in another world." );
} else {
em.startInstance(cm.getParty(), cm.getMap());
}
}
}
else {
cm.sendOk("You're not allowed to enter the other world with unknown reason.");
}
cm.dispose();
}
function action(mode, type, selection) {
}
function checkJob() {
var party = cm.getParty();
if (party == null) {
return -1;
}
// if (party.getMembers().size() != 2) {
// return 0;
// }
var it = party.getMembers().iterator();
while (it.hasNext()) {
var cPlayer = it.next();
if (cPlayer.getJobId() == 312 || cPlayer.getJobId() == 322 || cPlayer.getJobId() == 900) {
if (cPlayer.getLevel() < 120) {
return 2;
}
} else {
return 1;
}
}
return 3;
}
+2 -2
View File
@@ -12786,8 +12786,8 @@ CREATE TABLE IF NOT EXISTS `drop_data_global` (
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC AUTO_INCREMENT=5 ;
INSERT INTO `drop_data_global` (`id`, `continent`, `dropType`, `itemid`, `minimum_quantity`, `maximum_quantity`, `questid`, `chance`, `comments`) VALUES
(1, 0, 0, 4031865, 1, 1, 0, 150000, 'NX Card 100 PTS'),
(2, 0, 0, 4031866, 1, 1, 0, 90000, 'NX Card 250 PTS'),
(1, 0, 0, 4031865, 1, 1, 0, 125000, 'NX Card 100 PTS'),
(2, 0, 0, 4031866, 1, 1, 0, 78000, 'NX Card 250 PTS'),
(3, 0, 0, 4001126, 1, 2, 0, 10000, 'Maple Leaves'),
(4, 0, 0, 2049100, 1, 1, 0, 1500, 'Chaos Scroll 60%'),
(5, 0, 0, 4001006, 1, 1, 0, 12000, 'Flaming Feather');
+3 -3
View File
@@ -18839,9 +18839,9 @@
UPDATE drop_data SET questid=6191 WHERE itemid=4001107;
UPDATE drop_data SET questid=28344 WHERE itemid=4032475;
UPDATE drop_data SET questid=77777 WHERE itemid=4001358; #id 77777 for ALL "quest items" with no v83 quest.
UPDATE drop_data SET questid=77777 WHERE itemid=4001359;
UPDATE drop_data SET questid=77777 WHERE itemid=4001342;
UPDATE drop_data SET questid=7777 WHERE itemid=4001358; #id 7777 for ALL "quest items" with no v83 quest.
UPDATE drop_data SET questid=7777 WHERE itemid=4001359;
UPDATE drop_data SET questid=7777 WHERE itemid=4001342;
UPDATE drop_data SET chance=0 WHERE itemid=2050099;
UPDATE drop_data SET chance=40000 WHERE itemid=4031991;
UPDATE drop_data SET questid=6191 WHERE itemid=4031477;
+13
View File
@@ -123,4 +123,17 @@ public enum MapleJob {
public boolean isA(MapleJob basejob) {
return getId() >= basejob.getId() && getId() / 100 == basejob.getId() / 100;
}
public int getJobNiche() {
return (jobid / 100) % 10;
/*
case 0: BEGINNER;
case 1: WARRIOR;
case 2: MAGICIAN;
case 3: BOWMAN;
case 4: THIEF;
case 5: PIRATE;
*/
}
}
+18
View File
@@ -7,6 +7,17 @@ import constants.skills.Aran;
* @author kevintjuh93
*/
public class GameConstants {
private static final int[] mobHpVal = {0, 15, 20, 25, 35, 50, 65, 80, 95, 110, 125, 150, 175, 200, 225, 250, 275, 300, 325, 350,
375, 405, 435, 465, 495, 525, 580, 650, 720, 790, 900, 990, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800,
1900, 2000, 2100, 2200, 2300, 2400, 2520, 2640, 2760, 2880, 3000, 3200, 3400, 3600, 3800, 4000, 4300, 4600, 4900, 5200,
5500, 5900, 6300, 6700, 7100, 7500, 8000, 8500, 9000, 9500, 10000, 11000, 12000, 13000, 14000, 15000, 17000, 19000, 21000, 23000,
25000, 27000, 29000, 31000, 33000, 35000, 37000, 39000, 41000, 43000, 45000, 47000, 49000, 51000, 53000, 55000, 57000, 59000, 61000, 63000,
65000, 67000, 69000, 71000, 73000, 75000, 77000, 79000, 81000, 83000, 85000, 89000, 91000, 93000, 95000, 97000, 99000, 101000, 103000,
105000, 107000, 109000, 111000, 113000, 115000, 118000, 120000, 125000, 130000, 135000, 140000, 145000, 150000, 155000, 160000, 165000, 170000, 175000, 180000,
185000, 190000, 195000, 200000, 205000, 210000, 215000, 220000, 225000, 230000, 235000, 240000, 250000, 260000, 270000, 280000, 290000, 300000, 310000, 320000,
330000, 340000, 350000, 360000, 370000, 380000, 390000, 400000, 410000, 420000, 430000, 440000, 450000, 460000, 470000, 480000, 490000, 500000, 510000, 520000,
530000, 550000, 570000, 590000, 610000, 630000, 650000, 670000, 690000, 710000, 730000, 750000, 770000, 790000, 810000, 830000, 850000, 870000, 890000, 910000};
public static int getHiddenSkill(final int skill) {
switch (skill) {
@@ -96,4 +107,11 @@ public class GameConstants {
return false;
}
}
public static int getMonsterHP(final int level) {
if (level < 0 || level >= mobHpVal.length) {
return Integer.MAX_VALUE;
}
return mobHpVal[level];
}
}
+3
View File
@@ -55,6 +55,9 @@ public class ServerConstants {
public static final double PET_AUTOHP_RATIO = 0.99; //will automatically consume potions until given ratio of the MaxHP/MaxMP is reached.
public static final double PET_AUTOMP_RATIO = 0.99;
//Should bosses use 1HP,1MP attacks in dojo?
public static final boolean USE_DEADLY_DOJO = false;
//Rates
public static final int EXP_RATE = 10;
public static final int MESO_RATE = 10;
@@ -274,7 +274,6 @@ public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandl
int delay = 0;
final int maxmeso = player.getBuffedValue(MapleBuffStat.PICKPOCKET).intValue();
for (Integer eachd : onedList) {
eachd += Integer.MAX_VALUE;
if (pickpocket.getEffect(player.getSkillLevel(pickpocket)).makeChanceResult()) {
final Integer eachdf;
@@ -30,6 +30,7 @@ import client.inventory.Item;
import client.inventory.MapleInventoryType;
import client.status.MonsterStatus;
import client.status.MonsterStatusEffect;
import constants.ServerConstants;
import constants.skills.Aran;
import constants.skills.Corsair;
@@ -63,7 +64,7 @@ public final class TakeDamageHandler extends AbstractMaplePacketHandler {
int damage = slea.readInt();
int oid = 0, monsteridfrom = 0, pgmr = 0, direction = 0;
int pos_x = 0, pos_y = 0, fake = 0;
boolean is_pgmr = false, is_pg = true;
boolean is_pgmr = false, is_pg = true, is_deadly = false;
int mpattack = 0;
MapleMonster attacker = null;
final MapleMap map = player.getMap();
@@ -111,6 +112,7 @@ public final class TakeDamageHandler extends AbstractMaplePacketHandler {
if (attackInfo != null) {
if (attackInfo.isDeadlyAttack()) {
mpattack = player.getMp() - 1;
is_deadly = true;
}
mpattack += attackInfo.getMpBurn();
MobSkill skill = MobSkillFactory.getMobSkill(attackInfo.getDiseaseSkill(), attackInfo.getDiseaseLevel());
@@ -142,6 +144,13 @@ public final class TakeDamageHandler extends AbstractMaplePacketHandler {
if (damage == -1) {
fake = 4020002 + (player.getJob().getId() / 10 - 40) * 100000;
}
//in dojo player cannot use pot, so deadly attacks should be turned off as well
if(is_deadly && player.getMap().isDojoMap() && !ServerConstants.USE_DEADLY_DOJO) {
damage = 0;
mpattack = 0;
}
if (damage == 0) {
player.getAutobanManager().addMiss();
} else {
@@ -30,6 +30,8 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import javax.script.ScriptException;
@@ -61,6 +63,8 @@ public class EventInstanceManager {
private MapleExpedition expedition = null;
private List<Integer> mapIds = new LinkedList<Integer>();
private List<Boolean> isInstanced = new LinkedList<Boolean>();
private final ReentrantReadWriteLock mutex = new ReentrantReadWriteLock();
private final Lock rL = mutex.readLock(), wL = mutex.writeLock();
private boolean disposed = false;
public EventInstanceManager(EventManager em, String name) {
@@ -78,8 +82,16 @@ public class EventInstanceManager {
if (chr == null || !chr.isLoggedin()){
return;
}
try {
wL.lock();
try {
chars.add(chr);
}
finally {
wL.unlock();
}
chr.setEventInstance(this);
em.getIv().invokeFunction("playerEntry", this, chr);
} catch (ScriptException | NoSuchMethodException ex) {
@@ -125,7 +137,13 @@ public class EventInstanceManager {
}
public void unregisterPlayer(MapleCharacter chr) {
wL.lock();
try {
chars.remove(chr);
} finally {
wL.unlock();
}
chr.setEventInstance(null);
}
@@ -346,4 +364,37 @@ public class EventInstanceManager {
isInstanced.add(false);
return this.getMapFactory().getMap(mapid);
}
public final boolean disposeIfPlayerBelow(final byte size, final int towarp) {
if (disposed) {
return true;
}
MapleMap map = null;
if (towarp > 0) {
map = this.getMapFactory().getMap(towarp);
}
wL.lock();
try {
if (chars != null && chars.size() <= size) {
final List<MapleCharacter> chrs = new LinkedList<MapleCharacter>(chars);
for (MapleCharacter chr : chrs) {
if (chr == null) {
continue;
}
unregisterPlayer(chr);
if (towarp > 0) {
chr.changeMap(map, map.getPortal(0));
}
}
dispose();
return true;
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
wL.unlock();
}
return false;
}
}
+50
View File
@@ -0,0 +1,50 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 ~ 2010 Patrick Huy <[email protected]>
Matthias Butz <[email protected]>
Jan Christian Meyer <[email protected]>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License 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.life;
import constants.GameConstants;
public class ChangeableStats extends OverrideMonsterStats {
public int watk, matk, wdef, mdef, level;
public ChangeableStats(MapleMonsterStats stats, OverrideMonsterStats ostats) {
hp = ostats.getHp();
exp = ostats.getExp();
mp = ostats.getMp();
watk = stats.getPADamage();
matk = stats.getMADamage();
wdef = stats.getPDDamage();
mdef = stats.getMDDamage();
level = stats.getLevel();
}
public ChangeableStats(MapleMonsterStats stats, int newLevel, boolean pqMob) { // here we go i think
final double mod = (double) newLevel / (double) stats.getLevel();
final double hpRatio = (double) stats.getHp() / (double) stats.getExp();
final double pqMod = (pqMob ? 1.5 : 1.0); // god damn
hp = (int) Math.round((!stats.isBoss() ? GameConstants.getMonsterHP(newLevel) : (stats.getHp() * mod)) * pqMod); // right here lol
exp = (int) Math.round((!stats.isBoss() ? (GameConstants.getMonsterHP(newLevel) / hpRatio) : (stats.getExp())) * pqMod);
mp = (int) Math.round(stats.getMp() * mod * pqMod);
watk = (int) Math.round(stats.getPADamage() * mod);
matk = (int) Math.round(stats.getMADamage() * mod);
wdef = Math.min(stats.isBoss() ? 30 : 20, (int) Math.round(stats.getPDDamage() * mod));
mdef = Math.min(stats.isBoss() ? 30 : 20, (int) Math.round(stats.getMDDamage() * mod));
level = newLevel;
}
}
+33 -1
View File
@@ -63,7 +63,7 @@ import tools.Pair;
import tools.Randomizer;
public class MapleMonster extends AbstractLoadedMapleLife {
private ChangeableStats ostats = null; //unused, v83 WZs offers no support for changeable stats.
private MapleMonsterStats stats;
private int hp, mp;
private WeakReference<MapleCharacter> controller = new WeakReference<>(null);
@@ -957,4 +957,36 @@ public class MapleMonster extends AbstractLoadedMapleLife {
public Map<MonsterStatus, MonsterStatusEffect> getStati() {
return stati;
}
// ---- one can always have fun trying these pieces of codes below in-game rofl ----
public final ChangeableStats getChangedStats() {
return ostats;
}
public final int getMobMaxHp() {
if (ostats != null) {
return ostats.hp;
}
return stats.getHp();
}
public final void setOverrideStats(final OverrideMonsterStats ostats) {
this.ostats = new ChangeableStats(stats, ostats);
this.hp = ostats.getHp();
this.mp = ostats.getMp();
}
public final void changeLevel(final int newLevel) {
changeLevel(newLevel, true);
}
public final void changeLevel(final int newLevel, boolean pqMob) {
if (!stats.isChangeable()) {
return;
}
this.ostats = new ChangeableStats(stats, newLevel, pqMob);
this.hp = ostats.getHp();
this.mp = ostats.getMp();
}
}
+9
View File
@@ -36,6 +36,7 @@ import tools.Pair;
* @author Frz
*/
public class MapleMonsterStats {
private boolean changeable;
private int exp, hp, mp, level, PADamage, PDDamage, MADamage, MDDamage, dropPeriod, cp, buffToGive, removeAfter;
private boolean boss, undead, ffaLoot, isExplosiveReward, firstAttack, removeOnMiss;
private String name;
@@ -50,6 +51,14 @@ public class MapleMonsterStats {
private selfDestruction selfDestruction = null;
private boolean friendly;
public void setChange(boolean change) {
this.changeable = change;
}
public boolean isChangeable() {
return changeable;
}
public int getExp() {
return exp;
}
+64
View File
@@ -0,0 +1,64 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 ~ 2010 Patrick Huy <[email protected]>
Matthias Butz <[email protected]>
Jan Christian Meyer <[email protected]>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License 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.life;
public class OverrideMonsterStats {
public int hp;
public int exp, mp;
public OverrideMonsterStats() {
hp = 1;
exp = 0;
mp = 0;
}
public OverrideMonsterStats(int hp, int mp, int exp, boolean change) {
this.hp = /*change ? (hp * 3L / 2L) : */ hp;
this.mp = mp;
this.exp = exp;
}
public OverrideMonsterStats(int hp, int mp, int exp) {
this(hp, mp, exp, true);
}
public int getExp() {
return exp;
}
public void setOExp(int exp) {
this.exp = exp;
}
public int getHp() {
return hp;
}
public void setOHp(int hp) {
this.hp = hp;
}
public int getMp() {
return mp;
}
public void setOMp(int mp) {
this.mp = mp;
}
}
+16 -7
View File
@@ -368,14 +368,14 @@ public class MapleMap {
final MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
final byte droptype = (byte) (mob.getStats().isExplosiveReward() ? 3 : mob.getStats().isFfaLoot() ? 2 : chr.getParty() != null ? 1 : 0);
final int mobpos = mob.getPosition().x;
int chServerrate = chr.getDropRate();
int chRate = chr.getDropRate();
Item idrop;
byte d = 1;
Point pos = new Point(0, mob.getPosition().y);
Map<MonsterStatus, MonsterStatusEffect> stati = mob.getStati();
if (stati.containsKey(MonsterStatus.SHOWDOWN)) {
chServerrate *= (stati.get(MonsterStatus.SHOWDOWN).getStati().get(MonsterStatus.SHOWDOWN).doubleValue() / 100.0 + 1.0);
chRate *= (stati.get(MonsterStatus.SHOWDOWN).getStati().get(MonsterStatus.SHOWDOWN).doubleValue() / 100.0 + 1.0);
}
final MapleMonsterInformationProvider mi = MapleMonsterInformationProvider.getInstance();
@@ -383,7 +383,7 @@ public class MapleMap {
Collections.shuffle(dropEntry);
for (final MonsterDropEntry de : dropEntry) {
if (Randomizer.nextInt(999999) < de.chance * chServerrate) {
if (Randomizer.nextInt(999999) < de.chance * chRate) {
if (droptype == 3) {
pos.x = (int) (mobpos + (d % 2 == 0 ? (40 * (d + 1) / 2) : -(40 * (d / 2))));
} else {
@@ -418,9 +418,7 @@ public class MapleMap {
} else {
pos.x = (int) (mobpos + ((d % 2 == 0) ? (25 * (d + 1) / 2) : -(25 * (d / 2))));
}
if (de.itemId == 0) {
//chr.getCashShop().gainCash(1, 80);
} else {
if (de.itemId != 0) {
if (ItemConstants.getInventoryType(de.itemId) == MapleInventoryType.EQUIP) {
idrop = ii.randomizeStats((Equip) ii.getEquipById(de.itemId));
} else {
@@ -538,7 +536,6 @@ public class MapleMap {
if (damage > 0) {
monster.damage(chr, damage);
if (!monster.isAlive()) { // monster just died
//killMonster(monster, chr, true);
killed = true;
}
} else if (monster.getId() >= 8810002 && monster.getId() <= 8810009) {
@@ -2437,4 +2434,16 @@ public class MapleMap {
public void broadcastShip(final boolean state) {
broadcastMessage(MaplePacketCreator.boatPacket(state));
}
public boolean isDojoMap() {
return mapid >= 925020000 && mapid < 925040000;
}
public final void resetFully() {
resetFully(true);
}
public final void resetFully(final boolean respawn) {
resetMapObjects();
}
}
+4
View File
@@ -222,6 +222,10 @@ public class MapleQuest {
for (MapleQuestAction a : completeActs.values()) {
a.run(c, selection);
}
//dont seems to work...
//c.getClient().getSession().write(MaplePacketCreator.showForeignEffect(12)); // Quest completion
//c.getMap().broadcastMessage(c, MaplePacketCreator.showForeignEffect(c.getId(), 12), false);
}
}
+20 -5
View File
@@ -179,13 +179,28 @@ public class ItemAction extends MapleQuestAction {
return false;
}
if(item.getJob() != -1) {
if (item.getJob() != chr.getJob().getId()) {
return false;
} else if (MapleJob.getBy5ByteEncoding(item.getJob()).getId() / 100 != chr.getJob().getId() / 100) {
return false;
if (item.job > 0) {
final List<Integer> code = getJobBy5ByteEncoding(item.getJob());
boolean jobFound = false;
for (int codec : code) {
if (codec / 100 == chr.getJob().getId() / 100) {
jobFound = true;
break;
}
}
/*
if (!jobFound && item.jobEx > 0) {
final List<Integer> codeEx = getJobBySimpleEncoding(item.jobEx);
for (int codec : codeEx) {
if ((codec / 100 % 10) == (chr.getJob().getId() / 100 % 10)) {
jobFound = true;
break;
}
}
}
*/
return jobFound;
}
return true;
}
@@ -11,6 +11,9 @@ import provider.MapleData;
import server.quest.MapleQuest;
import server.quest.MapleQuestActionType;
import java.util.List;
import java.util.ArrayList;
/**
*
* @author Tyler (Twdtwd)
@@ -36,4 +39,84 @@ public abstract class MapleQuestAction {
public MapleQuestActionType getType() {
return type;
}
public static List<Integer> getJobBy5ByteEncoding(int encoded) {
List<Integer> ret = new ArrayList<Integer>();
if ((encoded & 0x1) != 0) {
ret.add(0);
}
if ((encoded & 0x2) != 0) {
ret.add(100);
}
if ((encoded & 0x4) != 0) {
ret.add(200);
}
if ((encoded & 0x8) != 0) {
ret.add(300);
}
if ((encoded & 0x10) != 0) {
ret.add(400);
}
if ((encoded & 0x20) != 0) {
ret.add(500);
}
if ((encoded & 0x400) != 0) {
ret.add(1000);
}
if ((encoded & 0x800) != 0) {
ret.add(1100);
}
if ((encoded & 0x1000) != 0) {
ret.add(1200);
}
if ((encoded & 0x2000) != 0) {
ret.add(1300);
}
if ((encoded & 0x4000) != 0) {
ret.add(1400);
}
if ((encoded & 0x8000) != 0) {
ret.add(1500);
}
if ((encoded & 0x20000) != 0) {
ret.add(2001); //im not sure of this one
ret.add(2200);
}
if ((encoded & 0x100000) != 0) {
ret.add(2000);
ret.add(2001); //?
}
if ((encoded & 0x200000) != 0) {
ret.add(2100);
}
if ((encoded & 0x400000) != 0) {
ret.add(2001); //?
ret.add(2200);
}
if ((encoded & 0x40000000) != 0) { //i haven't seen any higher than this o.o
ret.add(3000);
ret.add(3200);
ret.add(3300);
ret.add(3500);
}
return ret;
}
public static List<Integer> getJobBySimpleEncoding(int encoded) {
List<Integer> ret = new ArrayList<Integer>();
if ((encoded & 0x1) != 0) {
ret.add(200);
}
if ((encoded & 0x2) != 0) {
ret.add(300);
}
if ((encoded & 0x4) != 0) {
ret.add(400);
}
if ((encoded & 0x8) != 0) {
ret.add(500);
}
return ret;
}
}
+4
View File
@@ -5682,6 +5682,10 @@ public class MaplePacketCreator {
return mplew.getPacket();
}
public static byte[] showForeignEffect(int effect) {
return showForeignEffect(-1, effect);
}
public static byte[] showForeignEffect(int cid, int effect) {
final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendOpcode.SHOW_FOREIGN_EFFECT.getValue());