package handling.channel.handler;
import client.MapleBuffStat;
import client.MapleCharacter;
import client.MapleClient;
import client.MapleDisease;
import client.PlayerStats;
import client.Skill;
import client.SkillFactory;
import client.SummonSkillEntry;
import client.status.MonsterStatus;
import client.status.MonsterStatusEffect;
import constants.GameConstants;
import handling.world.WorldBroadcastService;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import server.MapleItemInformationProvider;
import server.MapleStatEffect;
import server.Randomizer;
import server.life.MapleMonster;
import server.maps.MapleMap;
import server.maps.MapleMapObject;
import server.maps.MapleMapObjectType;
import server.maps.MapleSummon;
import server.maps.SummonMovementType;
import tools.AttackPair;
import tools.FileoutputUtil;
import tools.MaplePacketCreator;
import tools.Pair;
import tools.data.input.SeekableLittleEndianAccessor;
import tools.packet.BuffPacket;
import tools.packet.MobPacket;
import tools.packet.SummonPacket;
public class SummonHandler {
public static void MoveSummon(SeekableLittleEndianAccessor slea, MapleCharacter chr) {
// 52
// 5D 78 2F 00
// E7 FE 1D 01
// 04 00 E7 FE 1B 01 00 00 FE FF 00 00 0C 3C 00 00 E7 FE 34 01 00 00 3C 00 00 00 0C 68 01 01 00 00 38 FF 0C 00 00 00 E7 FE 26 01 00 00 80 FF 00 00 0C 5A 00 00
if ((chr == null) || (chr.getMap() == null)) {
return;
}
MapleSummon sum = chr.getSummons().get(slea.readInt());
if (sum == null) {
FileoutputUtil.log("找不到地图物体:召唤兽!");
return;
}
if ((sum.getOwnerId() != chr.getId()) || (sum.getSkillLevel() <= 0) || (sum.getMovementType() == SummonMovementType.不会移动)) {
return;
}
Point startPos = new Point(slea.readShort(), slea.readShort());
List res = MovementParse.parseMovement(slea, 4);
Point pos = sum.getPosition();
MovementParse.updatePosition(res, sum, 0);
if (res.size() > 0) {
if (slea.available() != 1L) {
FileoutputUtil.log("slea.available() != 1 (召唤兽移动错误) 剩余封包长度: " + slea.available());
FileoutputUtil.log(FileoutputUtil.Movement_Sumon, "slea.available() = " + slea.available() + " (召唤兽移动错误) 封包: " + slea.toString(true));
return;
}
chr.getMap().broadcastMessage(chr, SummonPacket.moveSummon(chr.getId(), sum.getSkillId(), pos, res), sum.getTruePosition());
}
}
/**
* 召唤物受到伤害
* @param slea
* @param chr
*/
public static void DamageSummon(SeekableLittleEndianAccessor slea, MapleCharacter chr) {
// 54 FA FE 30 00 FF 00 00 00 00 04 87 01 00 00
if ((chr == null) || (!chr.isAlive()) || (chr.getMap() == null)) {
return;
}
MapleSummon summon = chr.getSummons().get(slea.readInt());
if ((summon == null) || (summon.getOwnerId() != chr.getId())) {
FileoutputUtil.log("找不到地图物体:召唤兽!");
return;
}
int type = slea.readByte();
int damage = slea.readInt();
int monsterIdFrom = slea.readInt();
slea.skip(1);
boolean remove = false;
if ((summon.is替身术()) && (damage > 0)) {
summon.addSummonHp(-damage);
if (summon.getSummonHp() <= 0) {
remove = true;
}
chr.getMap().broadcastMessage(chr, SummonPacket.damageSummon(chr.getId(), summon.getSkillId(), damage, type, monsterIdFrom), summon.getTruePosition());
}
if (remove) {
chr.dispelSkill(summon.getSkillId());
}
}
/**
* 召唤兽攻击
* @param slea
* @param c
* @param chr
*/
public static void SummonAttack(SeekableLittleEndianAccessor slea, MapleClient c, MapleCharacter chr) {
// 53 5D 78 2F 00 03 A1 86 01 00 06 80 01 5A FF F6 00 5C FF F6 00 64 00 17 00 00 00 E6 FE 35 01
int count;
if ((chr == null) || (!chr.isAlive()) || (chr.getMap() == null)) {
return;
}
MapleMap map = chr.getMap();
MapleSummon summon = chr.getSummons().get(slea.readInt());
if (summon == null || (summon.getOwnerId() != chr.getId()) || (summon.getSkillLevel() <= 0)) {
chr.dropMessage(5, "出现错误.");
return;
}
SummonSkillEntry sse = SkillFactory.getSummonData(summon.getSkillId());
if ((summon.getSkillId() / 1000000 != 35) && (summon.getSkillId() != 33101008) && (sse == null)) {
chr.dropMessage(5, "召唤兽攻击处理出错。");
return;
}
byte animation = slea.readByte();
byte numAttackedAndDamage = 0x11;
byte numAttacked = 1;
byte numDamage = 1;
if (summon.getSkillId() == 1301013 && summon.getScream()) {
//TODO 添加灵魂助力震惊的效果
chr.send_other(SummonPacket.summonSkill(chr.getId(), 217592, 141), false);
chr.send_other(MaplePacketCreator.showOwnBuffEffect(1301013, 3, chr.getLevel(), 1), false);
chr.send(BuffPacket.灵魂助力特殊(summon.SummonTime(360000), summon.setScream(false), summon.getControl()));
}
if (sse != null) {
count = sse.mobCount;
if (summon.getSkillId() == 1301013) {
count = 10;
}
if (numAttacked > count) {
if (chr.isShowPacket()) {
chr.dropMessage(-5, "召唤兽攻击次数错误 (Skillid : " + summon.getSkillId() + " 怪物数量 : " + numAttacked + " 默认数量: " + count + ")");
}
chr.dropMessage(5, "[警告] 请不要使用非法程序。召唤兽攻击怪物数量错误.");
return;
}
int numAttackCount = chr.getStat().getAttackCount(summon.getSkillId()) + sse.attackCount;
if (numDamage > numAttackCount) {
if (chr.isShowPacket()) {
chr.dropMessage(-5, "召唤兽攻击次数错误 (Skillid : " + summon.getSkillId() + " 打怪次数 : " + numDamage + " 默认次数: " + sse.attackCount + " 超级技能增加次数: " + chr.getStat().getAttackCount(summon.getSkillId()) + ")");
}
chr.dropMessage(5, "[警告] 请不要使用非法程序。召唤兽攻击怪物次数错误.");
return;
}
}
List<AttackPair> allDamage = new ArrayList();
for (int i = 0; i < numAttacked; i++) {
MapleMonster mob = map.getMonsterByOid(slea.readInt());
if (mob == null) {
continue;
}
slea.skip(13);
List allDamageNumbers = new ArrayList();
for (int j = 0; j < numDamage; j++) {
int damge = slea.readInt();
if (chr.isShowPacket()) {
chr.dropMessage(-5, "召唤兽攻击 打怪数量: " + numAttacked + " 打怪次数: " + numDamage + " 打怪伤害: " + damge + " 怪物OID: " + mob.getObjectId());
}
allDamageNumbers.add(new Pair(damge, false));
}
slea.skip(4);
allDamage.add(new AttackPair(mob.getObjectId(), allDamageNumbers));
}
Skill summonSkill = SkillFactory.getSkill(summon.getSkillId());
MapleStatEffect summonEffect = summonSkill.getEffect(summon.getSkillLevel());
if (summonEffect == null) {
chr.dropMessage(5, "召唤兽攻击出现错误 => 攻击效果为空.");
return;
}
if (allDamage.isEmpty()) {
return;
}
map.broadcastMessage(chr, SummonPacket.summonAttack(summon.getOwnerId(), summon.getObjectId(), animation, numAttackedAndDamage, allDamage, chr.getLevel(), false), summon.getTruePosition());
for (AttackPair attackEntry : allDamage) {
MapleMonster targetMob = map.getMonsterByOid(attackEntry.objectid);
if (targetMob == null) {
continue;
}
int totDamageToOneMonster = 0;
for (Pair eachde : attackEntry.attack) {
int toDamage = ((Integer) eachde.left);
totDamageToOneMonster += toDamage;
}
if (totDamageToOneMonster > 0) {
if ((summonEffect.getMonsterStati().size() > 0)
&& (summonEffect.makeChanceResult())) {
for (Map.Entry z : summonEffect.getMonsterStati().entrySet()) {
targetMob.applyStatus(chr, new MonsterStatusEffect((MonsterStatus) z.getKey(), (Integer) z.getValue(), summonSkill.getId(), null, false), summonEffect.isPoison(), 4000L, true, summonEffect);
}
}
if (chr.isShowPacket()) {
chr.dropMessage(5, "召唤兽打怪最终伤害 : " + totDamageToOneMonster);
}
targetMob.damage(chr, totDamageToOneMonster, true);
chr.checkMonsterAggro(targetMob);
if (!targetMob.isAlive()) {
chr.getClient().getSession().write(MobPacket.killMonster(targetMob.getObjectId(), 1));
}
}
}
if (!summon.isMultiAttack()) {
chr.getMap().broadcastMessage(SummonPacket.removeSummon(summon, true));
chr.getMap().removeMapObject(summon);
chr.removeVisibleMapObject(summon);
chr.removeSummon(summon.getSkillId());
if (summon.getSkillId() != 35121011) {
chr.dispelSkill(summon.getSkillId());
}
}
}
public static void RemoveSummon(SeekableLittleEndianAccessor slea, MapleClient c) {
MapleSummon summon = c.getPlayer().getSummons().get(slea.readInt());
if (summon ==null || (summon.getOwnerId() != c.getPlayer().getId()) || (summon.getSkillLevel() <= 0)) {
c.getPlayer().dropMessage(5, "移除召唤兽出现错误.");
return;
}
if (c.getPlayer().isShowPacket()) {
c.getPlayer().dropSpouseMessage(10, "收到移除召唤兽信息 - 召唤兽技能ID: " + summon.getSkillId() + " 技能名字 " + SkillFactory.getSkillName(summon.getSkillId()));
}
c.getPlayer().getMap().broadcastMessage(SummonPacket.removeSummon(summon, false));
c.getPlayer().getMap().removeMapObject(summon);
c.getPlayer().removeVisibleMapObject(summon);
c.getPlayer().removeSummon(summon.getSkillId());
c.getPlayer().dispelSkill(summon.getSkillId());
}
public static void SubSummon(SeekableLittleEndianAccessor slea, MapleCharacter chr) {
MapleSummon sum = chr.getSummons().get(slea.readInt());
if (sum == null || (sum.getOwnerId() != chr.getId()) || (sum.getSkillLevel() <= 0) || (!chr.isAlive())) {
return;
}
switch (sum.getSkillId()) {
case 1301013:
Skill bHealing = SkillFactory.getSkill(slea.readInt());
int bHealingLvl = chr.getTotalSkillLevel(bHealing);
if ((bHealingLvl <= 0) || (bHealing == null)) {
return;
}
MapleStatEffect healEffect = bHealing.getEffect(bHealingLvl);
if (bHealing.getId() == 1310016) {
healEffect.applyTo(chr);
} else if (bHealing.getId() == 1301013) {
if (!chr.canSummon(healEffect.getX() * 1000)) {
return;
}
int healHp = Math.min(1000, healEffect.getHp() * chr.getLevel());
chr.addHP(healHp);
}
chr.getClient().getSession().write(MaplePacketCreator.showOwnBuffEffect(sum.getSkillId(), 3, chr.getLevel(), bHealingLvl));//2+1 119
chr.getMap().broadcastMessage(SummonPacket.summonSkill(chr.getId(), sum.getSkillId(), bHealing.getId() == 1301013 ? 5 : Randomizer.nextInt(3) + 6));
chr.getMap().broadcastMessage(chr, MaplePacketCreator.showBuffeffect(chr, sum.getSkillId(), 3, chr.getLevel(), bHealingLvl), false);//2+1 119
}
}
}