public static final void SubSummon(final LittleEndianAccessor slea, final MapleCharacter chr) { final MapleMapObject obj = chr.getMap().getMapObject(slea.readInt(), MapleMapObjectType.SUMMON); if (obj == null || !(obj instanceof MapleSummon)) { return; } final MapleSummon sum = (MapleSummon) obj; if (sum == null || sum.getOwnerId() != chr.getId() || sum.getSkillLevel() <= 0 || !chr.isAlive()) { return; } switch (sum.getSkill()) { case 35121009: if (!chr.canSummon(2000)) { return; } final int skillId = slea.readInt(); // 35121009? if (sum.getSkill() != skillId) { return; } slea.skip(1); // 0E? chr.updateTick(slea.readInt()); for (int i = 0; i < 3; i++) { final MapleSummon tosummon = new MapleSummon( chr, SkillFactory.getSkill(35121011).getEffect(sum.getSkillLevel()), new Point(sum.getTruePosition().x, sum.getTruePosition().y - 5), SummonMovementType.WALK_STATIONARY); chr.getMap().spawnSummon(tosummon); chr.addSummon(tosummon); } break; case 35111011: // healing if (!chr.canSummon(1000)) { return; } chr.addHP( (int) (chr.getStat().getCurrentMaxHp() * SkillFactory.getSkill(sum.getSkill()).getEffect(sum.getSkillLevel()).getHp() / 100.0)); chr.getClient() .getSession() .write( EffectPacket.showOwnBuffEffect( sum.getSkill(), 2, chr.getLevel(), sum.getSkillLevel())); chr.getMap() .broadcastMessage( chr, EffectPacket.showBuffeffect( chr.getId(), sum.getSkill(), 2, chr.getLevel(), sum.getSkillLevel()), false); break; case 1321007: // beholder Skill bHealing = SkillFactory.getSkill(slea.readInt()); final int bHealingLvl = chr.getTotalSkillLevel(bHealing); if (bHealingLvl <= 0 || bHealing == null) { return; } final MapleStatEffect healEffect = bHealing.getEffect(bHealingLvl); if (bHealing.getId() == 1320009) { healEffect.applyTo(chr); } else if (bHealing.getId() == 1320008) { if (!chr.canSummon(healEffect.getX() * 1000)) { return; } chr.addHP(healEffect.getHp()); } chr.getClient() .getSession() .write(EffectPacket.showOwnBuffEffect(sum.getSkill(), 2, chr.getLevel(), bHealingLvl)); chr.getMap() .broadcastMessage( SummonPacket.summonSkill( chr.getId(), sum.getSkill(), bHealing.getId() == 1320008 ? 5 : (Randomizer.nextInt(3) + 6))); chr.getMap() .broadcastMessage( chr, EffectPacket.showBuffeffect( chr.getId(), sum.getSkill(), 2, chr.getLevel(), bHealingLvl), false); break; } if (GameConstants.isAngel(sum.getSkill())) { if (sum.getSkill() % 10000 == 1087) { MapleItemInformationProvider.getInstance().getItemEffect(2022747).applyTo(chr); } else if (sum.getSkill() % 10000 == 1179) { MapleItemInformationProvider.getInstance().getItemEffect(2022823).applyTo(chr); } else if (sum.getSkill() % 10000 == 1085) { MapleItemInformationProvider.getInstance().getItemEffect(2022746).applyTo(chr); } chr.getClient().getSession().write(EffectPacket.showOwnBuffEffect(sum.getSkill(), 2, 2, 1)); chr.getMap() .broadcastMessage( chr, EffectPacket.showBuffeffect(chr.getId(), sum.getSkill(), 2, 2, 1), false); } }
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); } } }