public SM_CASTSPELL_RESULT( Skill skill, List<Effect> effects, int hitTime, boolean chainSuccess, int spellStatus, int dashStatus) { this.skill = skill; this.effector = skill.getEffector(); this.target = skill.getFirstTarget(); this.effects = effects; this.cooldown = effector.getSkillCooldown(skill.getSkillTemplate()); this.spellStatus = spellStatus; this.chainSuccess = chainSuccess; this.targetType = 0; this.hitTime = hitTime; this.dashStatus = dashStatus; }
/** * @param skill * @param properties * @return */ public static final boolean set(Skill skill, Properties properties) { FirstTargetAttribute value = properties.getFirstTarget(); skill.setFirstTargetAttribute(value); switch (value) { case ME: skill.setFirstTargetRangeCheck(false); skill.setFirstTarget(skill.getEffector()); break; case TARGETORME: boolean changeTargetToMe = false; if (skill.getFirstTarget() == null) { skill.setFirstTarget(skill.getEffector()); } else if (skill.getFirstTarget().isAttackableNpc()) { Player playerEffector = (Player) skill.getEffector(); if (skill.getFirstTarget().isEnemy(playerEffector)) { changeTargetToMe = true; } } else if ((skill.getFirstTarget() instanceof Player) && (skill.getEffector() instanceof Player)) { Player playerEffected = (Player) skill.getFirstTarget(); Player playerEffector = (Player) skill.getEffector(); if (!playerEffected.getRace().equals(playerEffector.getRace()) || playerEffected.isEnemy(playerEffector)) { changeTargetToMe = true; } } else if (skill.getFirstTarget() instanceof Npc) { Npc npcEffected = (Npc) skill.getFirstTarget(); Player playerEffector = (Player) skill.getEffector(); if (npcEffected.isEnemy(playerEffector)) { changeTargetToMe = true; } } else if ((skill.getFirstTarget() instanceof Summon) && (skill.getEffector() instanceof Player)) { Summon summon = (Summon) skill.getFirstTarget(); Player playerEffected = summon.getMaster(); Player playerEffector = (Player) skill.getEffector(); if (playerEffected.isEnemy(playerEffector)) { changeTargetToMe = true; } } if (changeTargetToMe) { if (skill.getEffector() instanceof Player) PacketSendUtility.sendPacket( (Player) skill.getEffector(), SM_SYSTEM_MESSAGE.STR_SKILL_AUTO_CHANGE_TARGET_TO_MY); skill.setFirstTarget(skill.getEffector()); } break; case TARGET: // Exception for effect skills which are not used directly if (skill.getSkillId() > 8000 && skill.getSkillId() < 9000) break; // Exception for NPC skills which applied on players if (skill.getSkillTemplate().getDispelCategory() == DispelCategoryType.NPC_BUFF || skill.getSkillTemplate().getDispelCategory() == DispelCategoryType.NPC_DEBUFF_PHYSICAL) break; if (skill.getFirstTarget() == null || skill.getFirstTarget().equals(skill.getEffector())) { if (skill.getEffector() instanceof Player) { if (skill.getSkillTemplate().getProperties().getTargetType() == TargetRangeAttribute.AREA) return skill.getFirstTarget() != null; TargetRelationAttribute relation = skill.getSkillTemplate().getProperties().getTargetRelation(); TargetRangeAttribute type = skill.getSkillTemplate().getProperties().getTargetType(); if ((relation != TargetRelationAttribute.ALL && relation != TargetRelationAttribute.MYPARTY) || type == TargetRangeAttribute.PARTY || skill.getSkillId() == 3069) { // TODO: Remove ID, find logic! PacketSendUtility.sendPacket( (Player) skill.getEffector(), SM_SYSTEM_MESSAGE.STR_SKILL_TARGET_IS_NOT_VALID); return false; } } } break; case MYPET: Creature effector = skill.getEffector(); if (effector instanceof Player) { Summon summon = ((Player) effector).getSummon(); if (summon != null) skill.setFirstTarget(summon); else return false; } else { return false; } break; case MYMASTER: Creature peteffector = skill.getEffector(); if (peteffector instanceof Summon) { Player player = ((Summon) peteffector).getMaster(); if (player != null) skill.setFirstTarget(player); else return false; } else { return false; } break; case PASSIVE: skill.setFirstTarget(skill.getEffector()); break; case TARGET_MYPARTY_NONVISIBLE: Creature effected = skill.getFirstTarget(); if (effected == null || skill.getEffector() == null) return false; if (!(effected instanceof Player) || !(skill.getEffector() instanceof Player) || !((Player) skill.getEffector()).isInGroup2()) return false; boolean myParty = false; for (Player member : ((Player) skill.getEffector()).getPlayerGroup2().getMembers()) { if (member == skill.getEffector()) continue; if (member == effected) { myParty = true; break; } } if (!myParty) return false; skill.setFirstTargetRangeCheck(false); break; case POINT: skill.setFirstTarget(skill.getEffector()); skill.setFirstTargetRangeCheck(false); return true; default: break; } if (skill.getFirstTarget() != null) skill.getEffectedList().add(skill.getFirstTarget()); return true; }
@Override public boolean validate(Skill env) { if (env.getFirstTarget() == null || env.getEffector() == null) return false; return PositionUtil.isInFrontOfTarget(env.getEffector(), env.getFirstTarget()); }
@Override protected void writeImpl(AionConnection con) { writeD(effector.getObjectId()); writeC(targetType); switch (targetType) { case 0: case 3: case 4: writeD(target.getObjectId()); break; case 1: writeF(skill.getX()); writeF(skill.getY()); writeF(skill.getZ()); break; case 2: writeF(skill.getX()); writeF(skill.getY()); writeF(skill.getZ()); writeF(0); // unk1 writeF(0); // unk2 writeF(0); // unk3 writeF(0); // unk4 writeF(0); // unk5 writeF(0); // unk6 writeF(0); // unk7 writeF(0); // unk8 break; } writeH(skill.getSkillTemplate().getSkillId()); writeC(skill.getSkillTemplate().getLvl()); writeD(cooldown); writeH(hitTime); writeC(0); // unk /** * 0 : chain skill (counter too) 16 : no damage to all target like dodge, resist or effect size * is 0 32 : regular */ if (effects.isEmpty()) writeH(16); else if (chainSuccess) writeH(32); else writeH(0); // Get dash status writeC(this.dashStatus); switch (this.dashStatus) { case 1: case 2: case 3: case 4: case 6: writeC(skill.getH()); writeF(skill.getX()); writeF(skill.getY()); writeF(skill.getZ()); break; default: break; } writeH(effects.size()); for (Effect effect : effects) { Creature effected = effect.getEffected(); if (effected != null) { writeD(effected.getObjectId()); writeC(effect.getEffectResult().getId()); // 0 - NORMAL, 1 - ABSORBED, 2 - CONFLICT writeC( (int) (100f * effected.getLifeStats().getCurrentHp() / target.getLifeStats().getMaxHp())); // target %hp } else { // point point skills writeD(0); writeC(0); writeC(0); } writeC( (int) (100f * effector.getLifeStats().getCurrentHp() / effector.getLifeStats().getMaxHp())); // attacker %hp /** * Spell Status 1 : stumble 2 : knockback 4 : open aerial 8 : close aerial 16 : spin 32 : * block 64 : parry 128 :dodge 256 : resist */ writeC(this.spellStatus); writeC(effect.getSkillMoveType().getId()); writeH(0); writeC(effect.getCarvedSignet()); // current carve signet count switch (this.spellStatus) { case 1: case 2: case 4: case 8: writeF(effect.getTargetX()); writeF(effect.getTargetY()); writeF(effect.getTargetZ()); break; case 16: writeC(effect.getEffector().getHeading()); break; default: switch (effect.getSkillMoveType()) { case PULL: case KNOCKBACK: writeF(effect.getTargetX()); writeF(effect.getTargetY()); writeF(effect.getTargetZ()); default: break; } break; } writeC(1); // loops size - always 1? // TODO for(lop size) { writeC(effect.isMphealInstant() ? 1 : 0); if (effect.isDelayedDamage()) writeD(0); else writeD(effect.getReserved1()); // TODO value from specific effect using loop writeC(effect.getAttackStatus().getId()); // setting counter skill from packet to have the best synchronization of time with client if (effect.getEffected() instanceof Player) { if (effect.getAttackStatus().isCounterSkill()) ((Player) effect.getEffected()).setLastCounterSkill(effect.getAttackStatus()); } writeC(effect.getShieldDefense()); /** * shield Type: 1: reflector 2: normal shield 8: protect effect (ex. skillId: 417 Bodyguard) * TODO find out 4 */ switch (effect.getShieldDefense()) { case 0: case 2: break; case 8: case 10: writeD(effect.getProtectorId()); // protectorId writeD(effect.getProtectedDamage()); // protected damage writeD(effect.getProtectedSkillId()); // skillId break; case 16: writeD(0); writeD(0); writeD(0); writeD(0); writeD(0); writeD(effect.getMpShield()); writeD(effect.getReflectedSkillId()); break; default: writeD(effect.getProtectorId()); // protectorId writeD(effect.getProtectedDamage()); // protected damage writeD(effect.getProtectedSkillId()); // skillId writeD(effect.getReflectedDamage()); // reflect damage writeD(effect.getReflectedSkillId()); // skill id writeD(0); writeD(0); break; } } } }