테스트

aion-server 4.8

Gitteol
최고관리자 · 1 · 💬 0 클론/새로받기
 4.8 61f661d · 1 commits 새로받기(Pull)
game-server/src/com/aionemu/gameserver/services/summons/SummonsService.java
package com.aionemu.gameserver.services.summons;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Future;

import com.aionemu.gameserver.controllers.attack.AggroList;
import com.aionemu.gameserver.dataholders.DataManager;
import com.aionemu.gameserver.model.EmotionType;
import com.aionemu.gameserver.model.gameobjects.Creature;
import com.aionemu.gameserver.model.gameobjects.Npc;
import com.aionemu.gameserver.model.gameobjects.Summon;
import com.aionemu.gameserver.model.gameobjects.VisibleObject;
import com.aionemu.gameserver.model.gameobjects.player.Player;
import com.aionemu.gameserver.model.summons.SummonMode;
import com.aionemu.gameserver.model.summons.UnsummonType;
import com.aionemu.gameserver.network.aion.serverpackets.*;
import com.aionemu.gameserver.skillengine.model.SkillTemplate;
import com.aionemu.gameserver.spawnengine.VisibleObjectSpawner;
import com.aionemu.gameserver.utils.PacketSendUtility;
import com.aionemu.gameserver.utils.ThreadPoolManager;
import com.aionemu.gameserver.world.World;

/**
 * @author xTz
 */
public class SummonsService {

	/**
	 * create summon
	 */
	public static final Summon createSummon(Player master, int npcId, int skillId, int skillLevel, int time) {
		if (master.getSummon() != null) {
			PacketSendUtility.sendPacket(master, SM_SYSTEM_MESSAGE.STR_SKILL_SUMMON_ALREADY_HAVE_A_FOLLOWER());
			return null;
		}
		Summon summon = VisibleObjectSpawner.spawnSummon(master, npcId, skillId, time);
		master.setSummon(summon);
		PacketSendUtility.sendPacket(master, new SM_SUMMON_PANEL(summon));
		PacketSendUtility.broadcastPacket(summon, new SM_EMOTION(summon, EmotionType.CHANGE_SPEED));
		PacketSendUtility.broadcastPacket(summon, new SM_SUMMON_UPDATE(summon));
		return summon;
	}

	/**
	 * Release summon
	 */
	public static final void release(Summon summon, UnsummonType unsummonType) {
		if (summon.getMode() == SummonMode.RELEASE)
			return;
		summon.getController().cancelCurrentSkill(null);
		summon.setMode(SummonMode.RELEASE);
		summon.getObserveController().notifySummonReleaseObservers();
		new ReleaseSummonTask(summon, unsummonType).scheduleOrRun();
	}

	private static class ReleaseSummonTask implements Runnable {

		private final Summon summon;
		private final UnsummonType unsummonType;
		private boolean addedMasterHate;

		public ReleaseSummonTask(Summon owner, UnsummonType unsummonType) {
			this.summon = owner;
			this.unsummonType = unsummonType;
		}

		@Override
		public void run() {
			Player master = summon.getMaster();
			VisibleObject summonObj = World.getInstance().findVisibleObject(summon.getObjectId());
			// transformed npc via SM_TRANSFORM_IN_SUMMON
			if (summonObj != null && summonObj instanceof Npc npc)
				npc.getController().delete();
			else
				summon.getController().delete();

			if (summon.equals(master.getSummon()))
				master.setSummon(null);

			switch (unsummonType) {
				case COMMAND:
				case DISTANCE:
				case UNSPECIFIED:
					SkillTemplate summoningSkill = DataManager.SKILL_DATA.getSkillTemplate(summon.getSummonedBySkillId());
					if (summoningSkill != null && summoningSkill.getCooldown() > 0)
						master.setSkillCoolDown(summoningSkill.getCooldownId(), summoningSkill.getCooldown() * 100 + System.currentTimeMillis());

					if (unsummonType == UnsummonType.DISTANCE)
						PacketSendUtility.sendPacket(master, SM_SYSTEM_MESSAGE.STR_SKILL_SUMMON_UNSUMMON_BY_TOO_DISTANCE());
					else
						PacketSendUtility.sendPacket(master, SM_SYSTEM_MESSAGE.STR_SKILL_SUMMON_UNSUMMONED(summon.getL10n()));
					PacketSendUtility.sendPacket(master, new SM_SUMMON_PANEL_REMOVE(summon.getSummonedBySkillId()));
					PacketSendUtility.sendPacket(master, new SM_SUMMON_OWNER_REMOVE(summon.getObjectId()));
					if (!addedMasterHate)
						scheduleAddMasterHate(summon);
					break;
				case LOGOUT:
					break;
			}
		}

		public void scheduleOrRun() {
			switch (unsummonType) {
				case DISTANCE:
				case LOGOUT:
					run();
					break;
				default:
					Future<?> releaseTask = ThreadPoolManager.getInstance().schedule(this, 5000);
					if (unsummonType == UnsummonType.COMMAND) { // make it cancelable if released by master, master hate will be added delayed
						PacketSendUtility.sendPacket(summon.getMaster(), SM_SYSTEM_MESSAGE.STR_SKILL_SUMMON_UNSUMMON_FOLLOWER(summon.getL10n()));
						PacketSendUtility.sendPacket(summon.getMaster(), new SM_SUMMON_UPDATE(summon));
						summon.setReleaseTask(releaseTask);
					} else
						scheduleAddMasterHate(summon);
			}
		}

		private void scheduleAddMasterHate(Summon summon) {
			addedMasterHate = true;
			if (!summon.getMaster().isDead() && summon.getMaster().isOnline()) {
				List<AggroList> summonOnlyHaters = findSummonOnlyHaters(summon);
				if (!summonOnlyHaters.isEmpty()) // add master hate to every npc which was only attacked by the summon before
					ThreadPoolManager.getInstance().schedule(() -> {
						if (!summon.getMaster().isDead())
							summonOnlyHaters.forEach(aggroList -> aggroList.addHate(summon.getMaster(), 1));
					}, 1000);
			}
		}

		private List<AggroList> findSummonOnlyHaters(Summon owner) {
			Collection<VisibleObject> npcsKnownByMaster = owner.getMaster().getKnownList().getKnownObjects().values();
			List<AggroList> aggroLists = new ArrayList<>();
			npcsKnownByMaster.forEach(object -> {
				if (object instanceof Creature) {
					AggroList aggroList = ((Creature) object).getAggroList();
					if (aggroList.isHating(owner) && !aggroList.isHating(owner.getMaster()))
						aggroLists.add(aggroList);
				}
			});
			return aggroLists;
		}
	}

	/**
	 * Change to rest mode
	 */
	public static final void restMode(Summon summon) {
		summon.getController().cancelCurrentSkill(null);
		summon.setMode(SummonMode.REST);
		Player master = summon.getMaster();
		PacketSendUtility.sendPacket(master, SM_SYSTEM_MESSAGE.STR_SKILL_SUMMON_REST_MODE(summon.getL10n()));
		PacketSendUtility.sendPacket(master, new SM_SUMMON_UPDATE(summon));
		summon.getLifeStats().triggerRestoreTask();
	}

	public static final void setUnkMode(Summon summon) {
		summon.setMode(SummonMode.UNK);
		Player master = summon.getMaster();
		PacketSendUtility.sendPacket(master, new SM_SUMMON_UPDATE(summon));
	}

	/**
	 * Change to guard mode
	 */
	public static final void guardMode(Summon summon) {
		summon.getController().cancelCurrentSkill(null);
		summon.setMode(SummonMode.GUARD);
		Player master = summon.getMaster();
		PacketSendUtility.sendPacket(master, SM_SYSTEM_MESSAGE.STR_SKILL_SUMMON_GUARD_MODE(summon.getL10n()));
		PacketSendUtility.sendPacket(master, new SM_SUMMON_UPDATE(summon));
		summon.getLifeStats().triggerRestoreTask();
	}

	/**
	 * Change to attackMode
	 */
	public static final void attackMode(Summon summon) {
		summon.setMode(SummonMode.ATTACK);
		Player master = summon.getMaster();
		PacketSendUtility.sendPacket(master, SM_SYSTEM_MESSAGE.STR_SKILL_SUMMON_ATTACK_MODE(summon.getL10n()));
		PacketSendUtility.sendPacket(master, new SM_SUMMON_UPDATE(summon));
		summon.getLifeStats().cancelRestoreTask();
	}

	public static final void doMode(SummonMode summonMode, Summon summon) {
		doMode(summonMode, summon, 0, null);
	}

	public static final void doMode(SummonMode summonMode, Summon summon, UnsummonType unsummonType) {
		doMode(summonMode, summon, 0, unsummonType);
	}

	public static final void doMode(SummonMode summonMode, Summon summon, int targetObjId, UnsummonType unsummonType) {
		if (summon.isDead())
			return;

		if (summon.getMaster() == null)
			return;

		if (unsummonType == UnsummonType.COMMAND && summonMode != SummonMode.RELEASE)
			summon.cancelReleaseTask();

		switch (summonMode) {
			case REST:
				summon.getController().restMode();
				break;
			case ATTACK:
				summon.getController().attackMode(targetObjId);
				break;
			case GUARD:
				summon.getController().guardMode();
				break;
			case RELEASE:
				if (unsummonType != null) {
					summon.getController().release(unsummonType);
				}
				break;
			case UNK:
				break;
		}
	}
}

📎 첨부파일

댓글 작성 권한이 없습니다.
🏆 포인트 랭킹 TOP 10
순위 닉네임 포인트
1 no_profile 타키야겐지쪽지보내기 자기소개 아이디로 검색 전체게시물 102,949
2 no_profile 동가리쪽지보내기 자기소개 아이디로 검색 전체게시물 63,733
3 no_profile 라프텔쪽지보내기 자기소개 아이디로 검색 전체게시물 51,771
4 no_profile 불멸의행복쪽지보내기 자기소개 아이디로 검색 전체게시물 36,923
5 서번트쪽지보내기 자기소개 아이디로 검색 전체게시물 35,011
6 no_profile 닥터스쪽지보내기 자기소개 아이디로 검색 전체게시물 29,470
7 no_profile 검은고양이쪽지보내기 자기소개 아이디로 검색 전체게시물 29,077
8 no_profile Revolution쪽지보내기 자기소개 아이디로 검색 전체게시물 28,199
9 no_profile 보거스쪽지보내기 자기소개 아이디로 검색 전체게시물 26,731
10 no_profile 호롤롤로쪽지보내기 자기소개 아이디로 검색 전체게시물 17,020
알림 0