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:
50
src/server/life/ChangeableStats.java
Normal file
50
src/server/life/ChangeableStats.java
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
src/server/life/OverrideMonsterStats.java
Normal file
64
src/server/life/OverrideMonsterStats.java
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user