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
+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;
@@ -273,15 +273,14 @@ public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandl
Skill pickpocket = SkillFactory.getSkill(ChiefBandit.PICKPOCKET);
int delay = 0;
final int maxmeso = player.getBuffedValue(MapleBuffStat.PICKPOCKET).intValue();
for (Integer eachd : onedList) {
eachd += Integer.MAX_VALUE;
for (Integer eachd : onedList) {
eachd += Integer.MAX_VALUE;
if (pickpocket.getEffect(player.getSkillLevel(pickpocket)).makeChanceResult()) {
final Integer eachdf;
if(eachd < 0)
eachdf = eachd + Integer.MAX_VALUE;
else
eachdf = eachd;
final Integer eachdf;
if(eachd < 0)
eachdf = eachd + Integer.MAX_VALUE;
else
eachdf = eachd;
TimerManager.getInstance().schedule(new Runnable() {
@Override
@@ -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 {
+54 -3
View File
@@ -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 {
chars.add(chr);
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) {
chars.remove(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 <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 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 <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 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();
}
}
+5 -1
View File
@@ -104,7 +104,7 @@ public class MapleQuest {
MapleData completeReqData = reqData.getChildByPath("1");
if (completeReqData != null) {
for (MapleData completeReq : completeReqData.getChildren()) {
MapleQuestRequirementType type = MapleQuestRequirementType.getByWZName(completeReq.getName());
MapleQuestRequirementType type = MapleQuestRequirementType.getByWZName(completeReq.getName());
MapleQuestRequirement req = this.getRequirement(type, completeReq);
if(req == null)
continue;
@@ -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);
}
}
@@ -76,12 +76,12 @@ public enum MapleQuestRequirementType {
return INFO_EX;
} else if (name.equals("questComplete")) {
return COMPLETED_QUEST;
} else if(name.equals("start")) {
return START;
} else if(name.equals("end")) {
return END;
} else if(name.equals("daybyday")) {
return DAY_BY_DAY;
} else if(name.equals("start")) {
return START;
} else if(name.equals("end")) {
return END;
} else if(name.equals("daybyday")) {
return DAY_BY_DAY;
} else {
return UNDEFINED;
}
+23 -8
View File
@@ -178,14 +178,29 @@ public class ItemAction extends MapleQuestAction {
if (item.getGender() != 2 && item.getGender() != chr.getGender()) {
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;
}
+85 -2
View File
@@ -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)
@@ -34,6 +37,86 @@ public abstract class MapleQuestAction {
}
public MapleQuestActionType getType() {
return type;
}
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;
}
}
File diff suppressed because it is too large Load Diff