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

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;
}
}

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();
}
}

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;
}

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;
}
}

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();
}
}

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);
}
}

View File

@@ -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;
}

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;
}

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;
}
}