/* * This file is part of aion-unique <aion-unique.org>. * * aion-unique is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * aion-unique is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with aion-unique. If not, see <http://www.gnu.org/licenses/>. */ package com.aionemu.gameserver.controllers; import java.util.List; import com.aionemu.gameserver.controllers.attack.AttackResult; import com.aionemu.gameserver.controllers.attack.AttackUtil; import com.aionemu.gameserver.model.gameobjects.Creature; import com.aionemu.gameserver.model.gameobjects.Summon; import com.aionemu.gameserver.model.gameobjects.VisibleObject; import com.aionemu.gameserver.model.gameobjects.Summon.SummonMode; import com.aionemu.gameserver.model.gameobjects.player.Player; import com.aionemu.gameserver.network.aion.serverpackets.SM_ATTACK; import com.aionemu.gameserver.network.aion.serverpackets.SM_ATTACK_STATUS; import com.aionemu.gameserver.network.aion.serverpackets.SM_EMOTION; import com.aionemu.gameserver.network.aion.serverpackets.SM_SUMMON_OWNER_REMOVE; import com.aionemu.gameserver.network.aion.serverpackets.SM_SUMMON_PANEL_REMOVE; import com.aionemu.gameserver.network.aion.serverpackets.SM_SUMMON_UPDATE; import com.aionemu.gameserver.network.aion.serverpackets.SM_SYSTEM_MESSAGE; import com.aionemu.gameserver.network.aion.serverpackets.SM_ATTACK_STATUS.TYPE; import com.aionemu.gameserver.restrictions.RestrictionsManager; import com.aionemu.gameserver.utils.PacketSendUtility; import com.aionemu.gameserver.utils.ThreadPoolManager; /** * @author ATracer * */ public class SummonController extends CreatureController<Summon> { @Override public void notSee(VisibleObject object, boolean isOutOfRange) { super.notSee(object, isOutOfRange); if(getOwner().getMaster() == null) return; if(object.getObjectId() == getOwner().getMaster().getObjectId()) { release(UnsummonType.DISTANCE); } } @Override public Summon getOwner() { return (Summon) super.getOwner(); } /** * Release summon */ public void release(final UnsummonType unsummonType) { final Summon owner = getOwner(); if(owner.getMode() == SummonMode.RELEASE) return; owner.setMode(SummonMode.RELEASE); final Player master = owner.getMaster(); final int summonObjId = owner.getObjectId(); switch(unsummonType) { case COMMAND: PacketSendUtility.sendPacket(master, SM_SYSTEM_MESSAGE.SUMMON_UNSUMMON(getOwner().getNameId())); PacketSendUtility.sendPacket(master, new SM_SUMMON_UPDATE(getOwner())); break; case DISTANCE: PacketSendUtility.sendPacket(getOwner().getMaster(), SM_SYSTEM_MESSAGE .SUMMON_UNSUMMON_BY_TOO_DISTANCE()); PacketSendUtility.sendPacket(master, new SM_SUMMON_UPDATE(getOwner())); break; case LOGOUT: case UNSPECIFIED: break; } ThreadPoolManager.getInstance().schedule(new Runnable(){ @Override public void run() { owner.setMaster(null); master.setSummon(null); owner.getController().delete(); switch(unsummonType) { case COMMAND: case DISTANCE: case UNSPECIFIED: PacketSendUtility .sendPacket(master, SM_SYSTEM_MESSAGE.SUMMON_DISMISSED(getOwner().getNameId())); PacketSendUtility.sendPacket(master, new SM_SUMMON_OWNER_REMOVE(summonObjId)); // TODO temp till found on retail PacketSendUtility.sendPacket(master, new SM_SUMMON_PANEL_REMOVE()); break; case LOGOUT: break; } } }, 5000); } /** * Change to rest mode */ public void restMode() { getOwner().setMode(SummonMode.REST); Player master = getOwner().getMaster(); PacketSendUtility.sendPacket(master, SM_SYSTEM_MESSAGE.SUMMON_RESTMODE(getOwner().getNameId())); PacketSendUtility.sendPacket(master, new SM_SUMMON_UPDATE(getOwner())); } /** * Change to guard mode */ public void guardMode() { getOwner().setMode(SummonMode.GUARD); Player master = getOwner().getMaster(); PacketSendUtility.sendPacket(master, SM_SYSTEM_MESSAGE.SUMMON_GUARDMODE(getOwner().getNameId())); PacketSendUtility.sendPacket(master, new SM_SUMMON_UPDATE(getOwner())); } /** * Change to attackMode */ public void attackMode() { getOwner().setMode(SummonMode.ATTACK); Player master = getOwner().getMaster(); PacketSendUtility.sendPacket(master, SM_SYSTEM_MESSAGE.SUMMON_ATTACKMODE(getOwner().getNameId())); PacketSendUtility.sendPacket(master, new SM_SUMMON_UPDATE(getOwner())); } @Override public void attackTarget(Creature target) { Summon summon = getOwner(); Player master = getOwner().getMaster(); if(!summon.canAttack()) return; if(!RestrictionsManager.canAttack(master, target)) return; if(!summon.isEnemy(target)) return; /** * notify attack observers */ super.attackTarget(target); List<AttackResult> attackList = AttackUtil.calculateAttackResult(summon, target); int damage = 0; for(AttackResult result : attackList) { damage += result.getDamage(); } int attackType = 0; PacketSendUtility.broadcastPacket(summon, new SM_ATTACK(summon, target, summon.getGameStats() .getAttackCounter(), 274, attackType, attackList)); target.getController().onAttack(summon, damage); summon.getGameStats().increaseAttackCounter(); } @Override public void onAttack(Creature creature, int damage) { if(getOwner().getLifeStats().isAlreadyDead()) return; //temp if(getOwner().getMode() == SummonMode.RELEASE) return; super.onAttack(creature, damage); getOwner().getLifeStats().reduceHp(damage, creature); PacketSendUtility.broadcastPacket(getOwner(), new SM_ATTACK_STATUS(getOwner(), TYPE.REGULAR, 0, damage)); PacketSendUtility.sendPacket(getOwner().getMaster(), new SM_SUMMON_UPDATE(getOwner())); } @Override public void onDie(Creature lastAttacker) { release(UnsummonType.UNSPECIFIED); Summon owner = getOwner(); PacketSendUtility.broadcastPacket(owner, new SM_EMOTION(owner, 13, 0, lastAttacker == null ? 0 : lastAttacker .getObjectId())); } public static enum UnsummonType { LOGOUT, DISTANCE, COMMAND, UNSPECIFIED } }