@Override public void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) { c.getPlayer().resetAfkTime(); AttackInfo attack = parseDamage(slea, false); MapleCharacter player = c.getPlayer(); MaplePacket packet = MaplePacketCreator.magicAttack( player.getId(), attack.skill, attack.stance, attack.numAttackedAndDamage, attack.allDamage, -1, attack.speed); if (attack.skill == 2121001 || attack.skill == 2221001 || attack.skill == 2321001) { packet = MaplePacketCreator.magicAttack( player.getId(), attack.skill, attack.stance, attack.numAttackedAndDamage, attack.allDamage, attack.charge, attack.speed); } player.getMap().broadcastMessage(player, packet, false, true); MapleStatEffect effect = attack.getAttackEffect(c.getPlayer()); int maxdamage; // TODO fix magic damage calculation maxdamage = 99999; ISkill skill = SkillFactory.getSkill(attack.skill); int skillLevel = c.getPlayer().getSkillLevel(skill); MapleStatEffect effect_ = skill.getEffect(skillLevel); if (effect_.getCooldown() > 0) { if (player.skillisCooling(attack.skill)) { // player.getCheatTracker().registerOffense(CheatingOffense.COOLDOWN_HACK); return; } else { c.getSession().write(MaplePacketCreator.skillCooldown(attack.skill, effect_.getCooldown())); ScheduledFuture<?> timer = TimerManager.getInstance() .schedule( new CancelCooldownAction(c.getPlayer(), attack.skill), effect_.getCooldown() * 1000); player.addCooldown( attack.skill, System.currentTimeMillis(), effect_.getCooldown() * 1000, timer); } } applyAttack(attack, player, maxdamage, effect.getAttackCount()); // MP Eater for (int i = 1; i <= 3; i++) { ISkill eaterSkill = SkillFactory.getSkill(2000000 + i * 100000); int eaterLevel = player.getSkillLevel(eaterSkill); if (eaterLevel > 0) { for (Pair<Integer, List<Integer>> singleDamage : attack.allDamage) { eaterSkill .getEffect(eaterLevel) .applyPassive(player, player.getMap().getMapObject(singleDamage.getLeft()), 0); } break; } } }
@Override public void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) { // System.out.println("SummonDamage 封包: "+slea.toString()); int oid = slea.readInt(); slea.skip(5); MapleCharacter player = c.getPlayer(); if (!player.isAlive()) { return; } MapleSummon summon = null; boolean is磁场 = false; boolean is磁场攻击 = false; // System.out.println("接收到的召唤兽的oid"+oid); /* * for (List<MapleSummon> sums : c.getPlayer().getSummons().values()) { * for (MapleSummon sum : sums) { * //System.out.println("召唤兽的oid"+sum.getObjectId()); if * (sum.getObjectId() == oid) { summon = sum; break; } } } */ Object obj = c.getPlayer().getMap().getMapObject(oid); if (obj instanceof MapleSummon) { summon = (MapleSummon) obj; } if (summon == null) { // System.out.println("召唤兽伤害被拦截"); return; } int skillid; int skilllevel; Point pos; skillid = summon.getSkill(); skilllevel = summon.getSkillLevel(); pos = summon.getPosition(); ISkill summonSkill = SkillFactory.getSkill(skillid); MapleStatEffect summonEffect = summonSkill.getEffect(skilllevel); List<SummonAttackEntry> allDamage = new ArrayList<SummonAttackEntry>(); int numAttacked = changeNumAttacked(slea.readByte(), skillid); // 这里还读了一个byte int numAccackMonster = numAttacked >> 4; int numAccackMonsterCount = numAttacked & 0xf; // System.out.println("攻击怪的个数: " + numAttacked); player.getCheatTracker().checkSummonAttack(); int oid1 = slea.readInt(); // 第一个磁场的oid if (skillid == 机械师.磁场) { // is磁场 = true; for (List<MapleSummon> sums : c.getPlayer().getSummons().values()) { for (MapleSummon sum : sums) { if (sum.getObjectId() == oid1) { is磁场攻击 = true; oid = oid1; break; } } } if (is磁场攻击) { slea.skip(4); // 第二个磁场的oid slea.skip(4); // 第三个磁场的oid slea.skip(4); // 没用的 } } slea.skip(4); slea.skip(4); // 00 for (int x = 0; x < numAccackMonster; x++) { int monsterOid = slea.readInt(); // attacked oid slea.skip(4); // mobid 对应的怪物在WZ里的id slea.skip(19); int damage = slea.readInt(); for (int i = 0; i < numAccackMonsterCount; i++) {} // 以后召唤兽可能会多重攻击 slea.skip(8); // System.out.println("mobid: " + monsterOid); // System.out.println("打怪伤害: " + damage); allDamage.add(new SummonAttackEntry(monsterOid, damage)); } if (!player.isAlive()) { player.getCheatTracker().registerOffense(CheatingOffense.ATTACKING_WHILE_DEAD); return; } player .getMap() .broadcastMessage( player, MaplePacketCreator.summonAttack(player, oid, 4, allDamage, numAttacked), pos); for (SummonAttackEntry attackEntry : allDamage) { int damage = attackEntry.getDamage(); // System.out.println("遍历回来的伤害:"+damage); MapleMonster target = player.getMap().getMonsterByOid(attackEntry.getMonsterOid()); if (target != null) { if (damage > 0 && summonEffect.getMonsterStati().size() > 0) { if (summonEffect.makeChanceResult()) { MonsterStatusEffect monsterStatusEffect = new MonsterStatusEffect(summonEffect.getMonsterStati(), summonSkill, false); target.applyStatus(player, monsterStatusEffect, summonEffect.isPoison(), 4000); } } if (damage > 30000) { damage = 30000; } player.getMap().damageMonster(player, target, damage); player.checkMonsterAggro(target); // System.out.println("target == null"); } } if (是自爆召唤兽(skillid) || is磁场 && !is磁场攻击) { // System.out.println("机械召唤兽的removeSpecialMapObject特殊处理"); player.getMap().broadcastMessage(MaplePacketCreator.removeSpecialMapObject(summon, true)); player.getMap().removeMapObject(summon); player.removeVisibleMapObject(summon); // player.getSummons().remove(skillid); player.removeSummon(skillid); } }