public static byte[] damageFriendlyMob(MapleMonster mob, long damage, boolean display) { if (ServerProperties.ShowPacket()) { System.out.println("调用: " + new java.lang.Throwable().getStackTrace()[0]); } MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.write(SendPacketOpcode.DAMAGE_MONSTER.getValue()); mplew.writeInt(mob.getObjectId()); mplew.write(display ? 1 : 2); if (damage > 2147483647L) { mplew.writeInt(2147483647); } else { mplew.writeInt((int) damage); } if (mob.getHp() > 2147483647L) { mplew.writeInt((int) (mob.getHp() / mob.getMobMaxHp() * 2147483647.0D)); } else { mplew.writeInt((int) mob.getHp()); } if (mob.getMobMaxHp() > 2147483647L) { mplew.writeInt(2147483647); } else { mplew.writeInt((int) mob.getMobMaxHp()); } return mplew.getPacket(); }
@Override public int execute(MapleClient c, String[] splitted) { MapleMonster mob = null; for (final MapleMapObject monstermo : c.getPlayer() .getMap() .getMapObjectsInRange( c.getPlayer().getPosition(), 100000, Arrays.asList(MapleMapObjectType.MONSTER))) { mob = (MapleMonster) monstermo; if (mob.isAlive()) { c.getPlayer().dropMessage(6, "Monster " + mob.toString()); break; // only one } } if (mob == null) { c.getPlayer().dropMessage(6, "No monster was found."); } return 1; }
public static byte[] getNodeProperties(MapleMonster objectid, MapleMap map) { if (objectid.getNodePacket() != null) { return objectid.getNodePacket(); } if (ServerProperties.ShowPacket()) { System.out.println("调用: " + new java.lang.Throwable().getStackTrace()[0]); } MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.write(SendPacketOpcode.MONSTER_PROPERTIES.getValue()); mplew.writeInt(objectid.getObjectId()); mplew.writeInt(map.getNodes().size()); mplew.writeInt(objectid.getPosition().x); mplew.writeInt(objectid.getPosition().y); for (MapleNodes.MapleNodeInfo mni : map.getNodes()) { mplew.writeInt(mni.x); mplew.writeInt(mni.y); mplew.writeInt(mni.attr); if (mni.attr == 2) { mplew.writeInt(500); } } mplew.writeZero(6); objectid.setNodePacket(mplew.getPacket()); return objectid.getNodePacket(); }
@Override public int execute(MapleClient c, String[] splitted) { if (splitted.length < 3) { c.getPlayer().dropMessage(6, splitted[0] + " <怪物ID> <数量>"); return 0; } int mobid = Integer.parseInt(splitted[1]); int mobTime = Integer.parseInt(splitted[2]); MapleMonster npc; try { npc = MapleLifeFactory.getMonster(mobid); } catch (RuntimeException e) { c.getPlayer().dropMessage(5, "错误: " + e.getMessage()); return 0; } if (npc != null) { final int xpos = c.getPlayer().getPosition().x; final int ypos = c.getPlayer().getPosition().y; final int fh = c.getPlayer().getMap().getFootholds().findBelow(c.getPlayer().getPosition()).getId(); npc.setPosition(c.getPlayer().getPosition()); npc.setCy(ypos); npc.setRx0(xpos); npc.setRx1(xpos); npc.setFh(fh); c.getPlayer().getMap().addMonsterSpawn(npc, mobTime, (byte) -1, null); c.getPlayer().dropMessage(6, "请不要重载此地图, 否则服务器重启后怪物会消失"); } else { c.getPlayer().dropMessage(6, "你输入了一个无效的怪物ID"); return 0; } return 1; }
public static byte[] applyMonsterPoisonStatus(MapleMonster mons, List<MonsterStatusEffect> mse) { if (ServerProperties.ShowPacket()) { System.out.println("调用: " + new java.lang.Throwable().getStackTrace()[0]); } if ((mse.size() <= 0) || (mse.get(0) == null)) { return MaplePacketCreator.enableActions(); } MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.write(SendPacketOpcode.APPLY_MONSTER_STATUS.getValue()); mplew.writeInt(mons.getObjectId()); MonsterStatusEffect ms = (MonsterStatusEffect) mse.get(0); if (ms.getStati() == MonsterStatus.中毒) { PacketHelper.writeMonsterStatusMask(mplew, MonsterStatus.持续掉血); mplew.write(mse.size()); for (MonsterStatusEffect m : mse) { mplew.writeInt(m.getFromID()); if (m.isMonsterSkill()) { mplew.writeShort(m.getMobSkill().getSkillId()); mplew.writeShort(m.getMobSkill().getSkillLevel()); } else if (m.getSkill() > 0) { mplew.writeInt(m.getSkill()); } mplew.writeInt(m.getX()); mplew.writeInt(1000); mplew.writeInt(0); mplew.writeInt(10000); mplew.writeInt((int) (m.getDotTime() / 1000L)); mplew.writeInt(0); } mplew.writeShort(1000); mplew.write(1); } else { PacketHelper.writeSingleMask(mplew, ms.getStati()); mplew.writeInt(ms.getX()); if (ms.isMonsterSkill()) { mplew.writeShort(ms.getMobSkill().getSkillId()); mplew.writeShort(ms.getMobSkill().getSkillLevel()); } else if (ms.getSkill() > 0) { mplew.writeInt(ms.getSkill()); } mplew.writeShort(0); mplew.writeShort(0); mplew.write(1); mplew.write(1); } return mplew.getPacket(); }
public static byte[] showBossHP(MapleMonster mob) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.write(SendPacketOpcode.BOSS_ENV.getValue()); mplew.write(6); mplew.writeInt(mob.getId() == 9400589 ? 9300184 : mob.getId()); if (mob.getHp() > 2147483647L) { mplew.writeInt((int) (mob.getHp() / mob.getMobMaxHp() * 2147483647.0D)); } else { mplew.writeInt((int) mob.getHp()); } if (mob.getMobMaxHp() > 2147483647L) { mplew.writeInt(2147483647); } else { mplew.writeInt((int) mob.getMobMaxHp()); } mplew.write(mob.getStats().getTagColor()); mplew.write(mob.getStats().getTagBgColor()); return mplew.getPacket(); }
public static byte[] applyMonsterStatus(MapleMonster mons, MonsterStatusEffect ms) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.write(SendPacketOpcode.APPLY_MONSTER_STATUS.getValue()); mplew.writeInt(mons.getObjectId()); PacketHelper.writeMonsterStatusMask(mplew, ms.getStati()); mplew.writeShort(ms.getX()); if (ms.isMonsterSkill()) { mplew.writeShort(ms.getMobSkill().getSkillId()); mplew.writeShort(ms.getMobSkill().getSkillLevel()); } else if (ms.getSkill() > 0) { mplew.writeInt(ms.getSkill()); } mplew.writeShort(100); mplew.writeShort(1); // delay in ms return mplew.getPacket(); }
public static byte[] controlMonster(MapleMonster life, boolean newSpawn, boolean aggro) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.write(SendPacketOpcode.SPAWN_MONSTER_CONTROL.getValue()); mplew.write(aggro ? 2 : 1); mplew.writeInt(life.getObjectId()); mplew.writeInt(life.getId()); mplew.writePos(life.getTruePosition()); mplew.write(2); mplew.writeShort(life.getFh()); mplew.write(life.getStance()); mplew.write(newSpawn ? -2 : life.isFake() ? -4 : -1); mplew.write(0); mplew.writeLong(0); return mplew.getPacket(); }
/** * 召唤怪物 * * @param life * @param spawnType * @param link * @return */ public static byte[] spawnMonster(MapleMonster life, int spawnType, int link) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.write(SendPacketOpcode.SPAWN_MONSTER.getValue()); mplew.writeInt(life.getObjectId()); mplew.writeInt(life.getId()); mplew.writePos(life.getTruePosition()); mplew.write((life.getController() != null ? 0x08 : 0x02)); mplew.writeShort(life.getFh()); mplew.write(life.getStance()); // if (effect > 0) { // mplew.write(effect); // mplew.writeInt(life.getObjectId()); // } mplew.write(spawnType); mplew.write(1); // 召唤的时候特效,在wz中有对应的值 mplew.writeLong(0); return mplew.getPacket(); }
public static void handleMap(MapleMap map, int numTimes, int size, long now) { if (map.getItemsSize() > 0) { for (MapleMapItem item : map.getAllItemsThreadsafe()) { if (item.shouldExpire(now)) { item.expire(map); } else if (item.shouldFFA(now)) { item.setDropType((byte) 2); } } } if (map.getCharactersSize() > 0 || map.getId() == 931000500) { if (map.canSpawn(now)) { map.respawn(false, now); } boolean hurt = map.canHurt(now); boolean canrune = true; for (MapleCharacter chr : map.getCharactersThreadsafe()) { handleCooldowns(chr, numTimes, hurt, now); } if (map.getMobsSize() > 0) { for (MapleMonster mons : map.getAllMonstersThreadsafe()) { if (mons.getStats().isBoss()) { canrune = false; } if ((mons.isAlive()) && (mons.shouldKill(now))) { map.killMonster(mons); } else if ((mons.isAlive()) && (mons.shouldDrop(now))) { mons.doDropItem(now); } else if ((mons.isAlive()) && (mons.getStatiSize() > 0)) { for (MonsterStatusEffect mse : mons.getAllBuffs()) { if (mse.shouldCancel(now)) { mons.cancelSingleStatus(mse); } } } } } } }
public final void cancelPoisonSchedule(MapleMonster mm) { mm.doPoison(this, weakChr, 0); this.poisonSchedule = 0; this.weakChr = null; }
private static void monsterBomb( MapleCharacter player, MapleCharacter attackedPlayers, MapleMap map, AbstractDealDamageHandler.AttackInfo attack) { // level balances if (attackedPlayers.getLevel() > player.getLevel() + 25) { pvpDamage *= 1.35; } else if (attackedPlayers.getLevel() < player.getLevel() - 25) { pvpDamage /= 1.35; } else if (attackedPlayers.getLevel() > player.getLevel() + 100) { pvpDamage *= 1.50; } else if (attackedPlayers.getLevel() < player.getLevel() - 100) { pvpDamage /= 1.50; } // class balances if (player.getJob().equals(MapleJob.MAGICIAN)) { pvpDamage *= 1.20; } // buff modifiers Integer mguard = attackedPlayers.getBuffedValue(MapleBuffStat.MAGIC_GUARD); Integer mesoguard = attackedPlayers.getBuffedValue(MapleBuffStat.MESOGUARD); if (mguard != null) { int mploss = (int) (pvpDamage / .5); pvpDamage *= .70; if (mploss > attackedPlayers.getMp()) { pvpDamage /= .70; attackedPlayers.cancelBuffStats(MapleBuffStat.MAGIC_GUARD); } else { attackedPlayers.setMp(attackedPlayers.getMp() - mploss); attackedPlayers.updateSingleStat(MapleStat.MP, attackedPlayers.getMp()); } } else if (mesoguard != null) { int mesoloss = (int) (pvpDamage * .75); pvpDamage *= .75; if (mesoloss > attackedPlayers.getMeso()) { pvpDamage /= .75; attackedPlayers.cancelBuffStats(MapleBuffStat.MESOGUARD); } else { attackedPlayers.gainMeso(-mesoloss, false); } } // set up us teh bonmb // training thingy = 9409000 MapleMonster pvpMob = MapleLifeFactory.getMonster(9400711); map.spawnMonsterOnGroundBelow(pvpMob, attackedPlayers.getPosition()); for (int attacks = 0; attacks < attack.numDamage; attacks++) { map.broadcastMessage( MaplePacketCreator.damagePlayer( attack.numDamage, pvpMob.getId(), attackedPlayers.getId(), pvpDamage)); attackedPlayers.addHP(-pvpDamage); } int attackedDamage = pvpDamage * attack.numDamage; attackedPlayers .getClient() .getSession() .write( MaplePacketCreator.serverNotice( 5, player.getName() + " has hit you for " + attackedDamage + " damage!")); map.killMonster(pvpMob, player, false); // rewards if (attackedPlayers.getHp() <= 0 && !attackedPlayers.isAlive()) { int expReward = attackedPlayers.getLevel() * 100; if (player.getPvpKills() * .25 >= player.getPvpDeaths()) { expReward *= 20; } player.gainExp(expReward, true, false); player.gainPvpKill(); player .getClient() .getSession() .write( MaplePacketCreator.serverNotice( 6, "You've killed " + attackedPlayers.getName() + "!! You've gained a pvp kill!")); attackedPlayers.gainPvpDeath(); attackedPlayers .getClient() .getSession() .write(MaplePacketCreator.serverNotice(6, player.getName() + " has killed you!")); attackedPlayers.setHp(0); attackedPlayers.updateSingleStat(MapleStat.HP, 0); } }
public static void SummonAttack( final LittleEndianAccessor slea, final MapleClient c, final MapleCharacter chr) { if (chr == null || !chr.isAlive() || chr.getMap() == null) { return; } final MapleMap map = chr.getMap(); final MapleMapObject obj = map.getMapObject(slea.readInt(), MapleMapObjectType.SUMMON); if (obj == null || !(obj instanceof MapleSummon)) { chr.dropMessage(5, "The summon has disappeared."); return; } final MapleSummon summon = (MapleSummon) obj; if (summon.getOwnerId() != chr.getId() || summon.getSkillLevel() <= 0) { chr.dropMessage(5, "Error."); return; } final SummonSkillEntry sse = SkillFactory.getSummonData(summon.getSkill()); if (summon.getSkill() / 1000000 != 35 && summon.getSkill() != 33101008 && sse == null) { chr.dropMessage(5, "Error in processing attack."); return; } if (!GameConstants.GMS) { slea.skip(8); } int tick = slea.readInt(); if (sse != null && sse.delay > 0) { chr.updateTick(tick); // summon.CheckSummonAttackFrequency(chr, tick); // chr.getCheatTracker().checkSummonAttack(); } if (!GameConstants.GMS) { slea.skip(8); } final byte animation = slea.readByte(); if (!GameConstants.GMS) { slea.skip(8); } final byte numAttacked = slea.readByte(); if (sse != null && numAttacked > sse.mobCount) { chr.dropMessage(5, "Warning: Attacking more monster than summon can do"); chr.getCheatTracker().registerOffense(CheatingOffense.SUMMON_HACK_MOBS); // AutobanManager.getInstance().autoban(c, "Attacking more monster that summon can do (Skillid // : "+summon.getSkill()+" Count : " + numAttacked + ", allowed : " + sse.mobCount + ")"); return; } slea.skip(summon.getSkill() == 35111002 ? 24 : 12); // some pos stuff final List<Pair<Integer, Integer>> allDamage = new ArrayList<Pair<Integer, Integer>>(); for (int i = 0; i < numAttacked; i++) { final MapleMonster mob = map.getMonsterByOid(slea.readInt()); if (mob == null) { continue; } slea.skip(22); // who knows final int damge = slea.readInt(); allDamage.add(new Pair<Integer, Integer>(mob.getObjectId(), damge)); } // if (!summon.isChangedMap()) { map.broadcastMessage( chr, SummonPacket.summonAttack( summon.getOwnerId(), summon.getObjectId(), animation, allDamage, chr.getLevel(), false), summon.getTruePosition()); // } final Skill summonSkill = SkillFactory.getSkill(summon.getSkill()); final MapleStatEffect summonEffect = summonSkill.getEffect(summon.getSkillLevel()); if (summonEffect == null) { chr.dropMessage(5, "Error in attack."); return; } for (Pair<Integer, Integer> attackEntry : allDamage) { final int toDamage = attackEntry.right; final MapleMonster mob = map.getMonsterByOid(attackEntry.left); if (mob == null) { continue; } if (sse != null && sse.delay > 0 && summon.getMovementType() != SummonMovementType.STATIONARY && summon.getMovementType() != SummonMovementType.CIRCLE_STATIONARY && summon.getMovementType() != SummonMovementType.WALK_STATIONARY && chr.getTruePosition().distanceSq(mob.getTruePosition()) > 400000.0) { // chr.getCheatTracker().registerOffense(CheatingOffense.ATTACK_FARAWAY_MONSTER_SUMMON); } if (toDamage > 0 && summonEffect.getMonsterStati().size() > 0) { if (summonEffect.makeChanceResult()) { for (Map.Entry<MonsterStatus, Integer> z : summonEffect.getMonsterStati().entrySet()) { mob.applyStatus( chr, new MonsterStatusEffect(z.getKey(), z.getValue(), summonSkill.getId(), null, false), summonEffect.isPoison(), 4000, true, summonEffect); } } } if (chr.isGM() || toDamage < (chr.getStat().getCurrentMaxBaseDamage() * 5.0 * (summonEffect.getSelfDestruction() + summonEffect.getDamage() + chr.getStat().getDamageIncrease(summonEffect.getSourceId())) / 100.0)) { // 10 x dmg.. eh mob.damage(chr, toDamage, true); chr.checkMonsterAggro(mob); if (!mob.isAlive()) { chr.getClient().getSession().write(MobPacket.killMonster(mob.getObjectId(), 1)); } } else { chr.dropMessage(5, "Warning - high damage."); // AutobanManager.getInstance().autoban(c, "High Summon Damage (" + toDamage + " to " + // attackEntry.right + ")"); // TODO : Check player's stat for damage checking. break; } } if (!summon.isMultiAttack()) { chr.getMap().broadcastMessage(SummonPacket.removeSummon(summon, true)); chr.getMap().removeMapObject(summon); chr.removeVisibleMapObject(summon); chr.removeSummon(summon); if (summon.getSkill() != 35121011) { chr.cancelEffectFromBuffStat(MapleBuffStat.SUMMON); } } }
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) { int objectid = slea.readInt(); short moveid = slea.readShort(); MapleMapObject mmo = c.getPlayer().getMap().getMapObject(objectid); if (mmo == null || mmo.getType() != MapleMapObjectType.MONSTER) { return; } MapleMonster monster = (MapleMonster) mmo; List<LifeMovementFragment> res = null; byte skillByte = slea.readByte(); byte skill = slea.readByte(); int skill_1 = slea.readByte() & 0xFF; byte skill_2 = slea.readByte(); byte skill_3 = slea.readByte(); slea.readByte(); slea.readLong(); // v88 change MobSkill toUse = null; if (skillByte == 1 && monster.getNoSkills() > 0) { int random = Randomizer.getInstance().nextInt(monster.getNoSkills()); Pair<Integer, Integer> skillToUse = monster.getSkills().get(random); toUse = MobSkillFactory.getMobSkill(skillToUse.getLeft(), skillToUse.getRight()); int percHpLeft = (monster.getHp() / monster.getMaxHp()) * 100; if (toUse.getHP() < percHpLeft || !monster.canUseSkill(toUse)) { toUse = null; } } if ((skill_1 >= 100 && skill_1 <= 200) && monster.hasSkill(skill_1, skill_2)) { MobSkill skillData = MobSkillFactory.getMobSkill(skill_1, skill_2); if (skillData != null && monster.canUseSkill(skillData)) { skillData.applyEffect(c.getPlayer(), monster, true); } } slea.readByte(); slea.readInt(); // whatever slea.skip(12); // v88 skip short start_x = slea.readShort(); // hmm.. startpos? short start_y = slea.readShort(); // hmm... slea.readInt(); // v88 skip Point startPos = new Point(start_x, start_y); res = parseMovement(slea); if (monster.getController() != c.getPlayer()) { if (monster.isAttackedBy(c.getPlayer())) { // aggro and controller change monster.switchController(c.getPlayer(), true); } else { return; } } else if (skill == -1 && monster.isControllerKnowsAboutAggro() && !monster.isMobile() && !monster.isFirstAttack()) { monster.setControllerHasAggro(false); monster.setControllerKnowsAboutAggro(false); } boolean aggro = monster.isControllerHasAggro(); if (toUse != null) { c.getSession() .write( MaplePacketCreator.moveMonsterResponse( objectid, moveid, monster.getMp(), aggro, toUse.getSkillId(), toUse.getSkillLevel())); } else { c.getSession() .write(MaplePacketCreator.moveMonsterResponse(objectid, moveid, monster.getMp(), aggro)); } if (aggro) { monster.setControllerKnowsAboutAggro(true); } if (res != null && slea.available() == 17) { c.getPlayer() .getMap() .broadcastMessage( c.getPlayer(), MaplePacketCreator.moveMonster( skillByte, skill, skill_1, skill_2, skill_3, objectid, startPos, res), monster.getPosition()); updatePosition(res, monster, -1); c.getPlayer().getMap().moveMonster(monster, monster.getPosition()); } }