테스트

aion-server 4.8

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

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.aionemu.commons.utils.Rnd;
import com.aionemu.gameserver.configs.main.MembershipConfig;
import com.aionemu.gameserver.controllers.observer.ItemUseObserver;
import com.aionemu.gameserver.dataholders.DataManager;
import com.aionemu.gameserver.model.Race;
import com.aionemu.gameserver.model.TaskId;
import com.aionemu.gameserver.model.gameobjects.Item;
import com.aionemu.gameserver.model.gameobjects.Persistable.PersistentState;
import com.aionemu.gameserver.model.gameobjects.player.Player;
import com.aionemu.gameserver.model.items.ItemSlot;
import com.aionemu.gameserver.model.skill.PlayerSkillEntry;
import com.aionemu.gameserver.model.templates.item.ItemQuality;
import com.aionemu.gameserver.model.templates.item.Stigma;
import com.aionemu.gameserver.network.aion.serverpackets.SM_INVENTORY_UPDATE_ITEM;
import com.aionemu.gameserver.network.aion.serverpackets.SM_ITEM_USAGE_ANIMATION;
import com.aionemu.gameserver.network.aion.serverpackets.SM_SYSTEM_MESSAGE;
import com.aionemu.gameserver.questEngine.model.QuestState;
import com.aionemu.gameserver.questEngine.model.QuestStatus;
import com.aionemu.gameserver.services.item.ItemPacketService;
import com.aionemu.gameserver.services.trade.PricesService;
import com.aionemu.gameserver.skillengine.model.SkillLearnTemplate;
import com.aionemu.gameserver.skillengine.model.SkillTemplate;
import com.aionemu.gameserver.utils.PacketSendUtility;
import com.aionemu.gameserver.utils.ThreadPoolManager;
import com.aionemu.gameserver.utils.audit.AuditLogger;

/**
 * @author ATracer, cura, Neon
 */
public class StigmaService {

	private static final Logger log = LoggerFactory.getLogger(StigmaService.class);

	public static boolean notifyEquipAction(Player player, Item resultItem, long slot) {
		if (resultItem.getItemTemplate().isStigma()) {
			Stigma stigmaInfo = resultItem.getItemTemplate().getStigma();
			int stigmaLevel = resultItem.getEnchantLevel();
			String stigmaName = resultItem.getItemName().replace(" ", "").toUpperCase();
			boolean replace = false;
			for (Item i : player.getEquipment().getEquippedItemsAllStigma()) {
				if (i.getEquipmentSlot() == slot) {
					if (!stigmaName.equals(i.getItemName().replace(" ", "").toUpperCase()))
						return false;
					removeStigmaSkills(player, i.getItemTemplate().getStigma(), i.getEnchantLevel(), i.getEnchantLevel() > resultItem.getEnchantLevel());
					replace = true;
					break;
				}
			}
			if (!replace) {
				// check the number of stigma wearing
				if (ItemSlot.isRegularStigma(slot) && getPossibleStigmaCount(player) <= player.getEquipment().getEquippedItemsRegularStigma().size()) {
					AuditLogger.log(player, "tried to equip stigma, exceeding the socket limit");
					return false;
				} else if (ItemSlot.isAdvancedStigma(slot)
					&& getPossibleAdvancedStigmaCount(player) <= player.getEquipment().getEquippedItemsAdvancedStigma().size()) {
					AuditLogger.log(player, "tried to equip advanced stigma, exceeding the socket limit");
					return false;
				}
			}

			long kinahcount = 25000;
			// Sets the price for equipping stigma during mission in Space of Destiny [ID: 320070000] and Sliver of darkness [ID: 310070000]
			if ((player.getRace() == Race.ASMODIANS && player.getWorldId() == 320070000)
				|| (player.getRace() == Race.ELYOS && player.getWorldId() == 310070000))
				kinahcount = 1000;
			else if (resultItem.getItemTemplate().getItemQuality().equals(ItemQuality.LEGEND))
				kinahcount = 50000;
			else if (resultItem.getItemTemplate().getItemQuality().equals(ItemQuality.UNIQUE))
				kinahcount = 100000;

			if (!player.getInventory().tryDecreaseKinah(PricesService.getPriceForService(kinahcount, player.getRace()))) {
				PacketSendUtility.sendPacket(player, SM_SYSTEM_MESSAGE.STR_STIGMA_NOT_ENOUGH_MONEY());
				return false;
			}
			addStigmaSkills(player, stigmaInfo, stigmaLevel);
		}
		return true;
	}

	public static void onPlayerLogin(Player player) {
		if (player.hasPermission(MembershipConfig.STIGMA_AUTOLEARN)) {
			for (int level = 20; level <= player.getLevel(); level++) {
				for (SkillLearnTemplate template : DataManager.SKILL_TREE_DATA.getTemplatesFor(player.getPlayerClass(), level, player.getRace())) {
					if (template.isStigma())
						SkillLearnService.learnTemporarySkill(player, template.getSkillId(), template.getSkillLevel());
				}
			}
			return;
		}

		mainLoop:
		for (Item item : player.getEquipment().getEquippedItemsAllStigma()) {
			if (!item.getItemTemplate().isStigma()) {
				player.getEquipment().unEquipItem(item.getObjectId(), false);
				log.warn("Unequipped stigma: " + item.getItemId() + ", stigma info missing for item (possibly pre-4.8 stigma)");
				continue;
			}

			if (!isPossibleEquippedStigma(player, item)) {
				player.getEquipment().unEquipItem(item.getObjectId(), false);
				AuditLogger.log(player, "had more equipped stigmas on login than allowed");
				continue;
			}

			if (!item.getItemTemplate().isClassSpecific(player.getPlayerClass())) {
				player.getEquipment().unEquipItem(item.getObjectId(), false);
				AuditLogger.log(player, "had an equipped stigma on login which was not for his class");
				continue;
			}

			// check for double stigmas equipped into the same slot
			for (Item checkStigma : player.getEquipment().getEquippedItemsAllStigma()) {
				if (checkStigma.getEquipmentSlot() == item.getEquipmentSlot() && checkStigma.getItemId() != item.getItemId()) {
					player.getEquipment().unEquipItem(item.getObjectId(), false);
					AuditLogger.log(player, "had two stigmas equipped in the same slot on login");
					continue mainLoop;
				}
			}

			addStigmaSkills(player, item.getItemTemplate().getStigma(), item.getEnchantLevel());
		}

		addLinkedStigmaSkills(player);
	}

	public static void removeLinkedStigmaSkills(Player player) {
		List<PlayerSkillEntry> linkedStigmaSkills = new ArrayList<>();
		while (true) { // remove all linked stigma skills (can be more than one if stigma auto learning is enabled)
			String stack = null;
			linkedStigmaSkills.clear();
			for (PlayerSkillEntry skill : player.getSkillList().getAllSkills()) {
				if (skill.isLinkedStigmaSkill()) {
					SkillTemplate skillTemplate = DataManager.SKILL_DATA.getSkillTemplate(skill.getSkillId());
					if (stack == null)
						stack = skillTemplate.getStack();
					if (skillTemplate.getStack().equalsIgnoreCase(stack))
						linkedStigmaSkills.add(skill);
					if (stack.equalsIgnoreCase("NONE"))
						break;
				}
			}
			if (linkedStigmaSkills.isEmpty())
				break;
			String firstSkillL10n = null, secondSkillL10n = null;
			int skillLevel = 0;
			for (int i = 0; i < linkedStigmaSkills.size(); i++) {
				PlayerSkillEntry skillEntry = linkedStigmaSkills.get(i);
				SkillLearnService.removeSkill(player, skillEntry.getSkillId());
				if (i == 0) {
					firstSkillL10n = DataManager.SKILL_DATA.getSkillTemplate(skillEntry.getSkillId()).getL10n();
					skillLevel = skillEntry.getSkillLevel();
				} else if (i == 1)
					secondSkillL10n = DataManager.SKILL_DATA.getSkillTemplate(skillEntry.getSkillId()).getL10n();
			}
			PacketSendUtility.sendPacket(player, SM_SYSTEM_MESSAGE.STR_MSG_STIGMA_DELETE_HIDDEN_SKILL(firstSkillL10n, skillLevel, secondSkillL10n));
		}
	}

	public static void addLinkedStigmaSkills(Player player) {
		List<Item> stigmas = player.getEquipment().getEquippedItemsAllStigma();
		if (stigmas.size() < 6)
			return;

		for (Item stigma : stigmas) {
			if (!stigma.isStigmaChargeable())
				return;
		}

		int skillId = getLinkedStigmaLearnSkill(player);
		if (skillId > 0) {
			// linked stigma level is the lowest enchant level of all equipped stigmas
			int linkedStigmaSkillLevel = stigmas.stream().min((i1, i2) -> i1.getEnchantLevel() - i2.getEnchantLevel()).get().getEnchantLevel() + 1;
			for (SkillLearnTemplate skill : DataManager.SKILL_TREE_DATA.getSkillsForSkill(skillId, player.getPlayerClass(), player.getRace(),
				player.getLevel()))
				SkillLearnService.learnTemporarySkill(player, skill.getSkillId(), linkedStigmaSkillLevel);
		}
	}

	private static int getLinkedStigmaLearnSkill(Player player) {
		// references: http://aion.mouseclic.com/beta/stigma.php
		boolean isEly = player.getRace() == Race.ELYOS;
		switch (player.getPlayerClass()) {
			case GLADIATOR:
				if (isEquipped(player, 140001118) && isEquipped(player, 2, 140001103, 140001104, 140001105))
					return 731; // Wind Lance
				if (isEquipped(player, 140001119) && isEquipped(player, 2, 140001106, 140001107, 140001108))
					return 643; // Unraveling Assault
				return !isEly ? 661 : 662; // Battle Banner
			case TEMPLAR:
				if (isEquipped(player, 140001134) && isEquipped(player, 2, 140001120, 140001122, 140001125))
					return 2921; // Invigorating Strike
				if (isEquipped(player, 140001135) && isEquipped(player, 2, 140001121, 140001123, 140001124))
					return 2918; // Shield of Vengeance
				return 2917; // Eternal Denial
			case ASSASSIN:
				if (isEquipped(player, 140001151) && isEquipped(player, 2, 140001136, 140001137, 140001140))
					return 3241; // Fangdrop Stab
				if (isEquipped(player, 140001152) && isEquipped(player, 2, 140001138, 140001139, 140001141))
					return 3238; // Shimmerbomb
				return 3244; // Explosive Rebranding
			case RANGER:
				if (isEquipped(player, 140001172) && isEquipped(player, 2, 140001153, 140001155, 140001157))
					return 1008; // Ripthread Shot
				if (isEquipped(player, 140001173) && isEquipped(player, 2, 140001154, 140001156, 140001158))
					return 938; // Night Haze
				return isEly ? 1065 : 1064; // Staggering Trap
			case SORCERER:
				if (isEquipped(player, 140001191) && isEquipped(player, 2, 140001174, 140001178, 140001181))
					return 1342; // Slumberswept Wind
				if (isEquipped(player, 140001192) && isEquipped(player, 2, 140001176, 140001177, isEly ? 140001184 : 140001185))
					return 1542; // Aetherblaze
				return 1420; // Repulsion Field
			case SPIRIT_MASTER:
				if (isEquipped(player, 140001209) && isEquipped(player, 2, 140001193, 140001194, 140001195))
					return 3543; // Spirit's Empowerment
				if (isEquipped(player, 140001210) && isEquipped(player, 2, 140001196, isEly ? 140001197 : 140001198, 140001199))
					return 3549; // Command: Absorb Wounds
				return 3851; // Blood Funnel
			case CLERIC:
				if (isEquipped(player, 140001245) && isEquipped(player, 2, 140001228, 140001229, isEly ? 140001230 : 140001231))
					return 4169; // Judge's Edict
				if (isEquipped(player, 140001246) && isEquipped(player, 2, 140001232, 140001233, isEly ? 140001234 : 140001235))
					return 3934; // Restoration Relief
				return isEly ? 3906 : 3911; // Summon Vexing Energy
			case CHANTER:
				if (isEquipped(player, 140001226) && isEquipped(player, 2, 140001211, 140001212, 140001213))
					return 1909; // Word of Instigation
				if (isEquipped(player, 140001227) && isEquipped(player, 2, 140001214, 140001215, 140001216))
					return 1903; // Resonant Strike
				return 1906; // Debilitating Incantation
			case RIDER:
				if (isEquipped(player, 140001279) && isEquipped(player, 2, 140001264, 140001265, 140001269))
					return 2858; // Explosive Exhaust
				if (isEquipped(player, 140001280) && isEquipped(player, 2, 140001266, 140001267, 140001268))
					return 2863; // Powerspike Trigger
				return 2851; // Nerve Pulse
			case GUNNER:
				if (isEquipped(player, 140001262) && isEquipped(player, 2, 140001247, 140001248, 140001249))
					return 2370; // Pursuit Stance
				if (isEquipped(player, 140001263) && isEquipped(player, 2, 140001250, 140001251, 140001252))
					return 2377; // Sequential Fire
				return 2382; // Pulverizer Cannon
			case BARD:
				if (isEquipped(player, 140001296) && isEquipped(player, 2, 140001281, 140001282, 140001284))
					return 4480; // Blazing Requiem
				if (isEquipped(player, 140001297) && isEquipped(player, 2, 140001283, 140001285, 140001286))
					return 4483; // Purging Paean
				return 4566; // Delusional Dirge
		}
		return 0;
	}

	public static boolean isEquipped(Player player, int itemId) {
		if (player.getEquipment().getEquippedItemsByItemId(itemId) != null)
			return player.getEquipment().getEquippedItemsByItemId(itemId).size() > 0;
		return false;
	}

	public static boolean isEquipped(Player player, int neededCount, int... itemIds) {
		int equippedCount = 0;
		for (int itemId : itemIds)
			if (isEquipped(player, itemId))
				equippedCount += 1;
		return equippedCount == neededCount;
	}

	private static int getPossibleStigmaCount(Player player) {
		if (player.hasPermission(MembershipConfig.STIGMA_SLOT_QUEST))
			return 3;
		int playerLevel = player.getLevel();
		boolean isCompleteQuest = isCompleteQuest(player);
		if (isCompleteQuest) {
			if (playerLevel < 30)
				return 1;
			else if (playerLevel < 40)
				return 2;
			else
				return 3;
		}
		return 0;
	}

	private static boolean isCompleteQuest(Player player) {
		// Stigma Quest Elyos: 1929, Asmodians: 2900
		boolean isCompleteQuest = false;

		if (player.getRace() == Race.ELYOS) {
			QuestState qs = player.getQuestStateList().getQuestState(1929);
			if (qs != null)
				isCompleteQuest = player.isCompleteQuest(1929) || (qs.getStatus() == QuestStatus.START && qs.getQuestVars().getQuestVars() == 98);
			else
				isCompleteQuest = player.isCompleteQuest(1929);
		} else {
			QuestState qs = player.getQuestStateList().getQuestState(2900);
			if (qs != null)
				isCompleteQuest = player.isCompleteQuest(2900) || (qs.getStatus() == QuestStatus.START && qs.getQuestVars().getQuestVars() == 99);
			else
				isCompleteQuest = player.isCompleteQuest(2900);
		}
		return isCompleteQuest;
	}

	private static int getPossibleAdvancedStigmaCount(Player player) {
		if (player.hasPermission(MembershipConfig.STIGMA_SLOT_QUEST))
			return 3;
		int playerLevel = player.getLevel();
		boolean isCompleteQuest = isCompleteQuest(player);
		if (isCompleteQuest) {
			if (playerLevel >= 55)
				return 3;
			else if (playerLevel >= 50)
				return 2;
			else if (playerLevel >= 45)
				return 1;
		}
		return 0;
	}

	private static boolean isPossibleEquippedStigma(Player player, Item item) {
		if (!item.getItemTemplate().isStigma())
			return false;

		long itemSlotToEquip = item.getEquipmentSlot();

		// Stigma
		if (ItemSlot.isRegularStigma(itemSlotToEquip)) {
			int stigmaCount = getPossibleStigmaCount(player);
			if (stigmaCount > 0) {
				if (stigmaCount == 1) {
					if (itemSlotToEquip == ItemSlot.STIGMA1.getSlotIdMask())
						return true;
				} else if (stigmaCount == 2) {
					if (itemSlotToEquip == ItemSlot.STIGMA1.getSlotIdMask() || itemSlotToEquip == ItemSlot.STIGMA2.getSlotIdMask())
						return true;
				} else if (stigmaCount == 3)
					return true;
			}
		}
		// Advanced Stigma
		else if (ItemSlot.isAdvancedStigma(itemSlotToEquip)) {
			int advStigmaCount = getPossibleAdvancedStigmaCount(player);
			if (advStigmaCount > 0) {
				if (advStigmaCount == 1) {
					if (itemSlotToEquip == ItemSlot.ADV_STIGMA1.getSlotIdMask())
						return true;
				} else if (advStigmaCount == 2) {
					if (itemSlotToEquip == ItemSlot.ADV_STIGMA1.getSlotIdMask() || itemSlotToEquip == ItemSlot.ADV_STIGMA2.getSlotIdMask())
						return true;
				} else if (advStigmaCount == 3)
					return true;
			}
		}
		return false;
	}

	public static void chargeStigma(Player player, Item stigma, Item chargeStone) {
		Stigma stigmaInfo = stigma.getItemTemplate().getStigma();
		if (stigma.getItemId() != chargeStone.getItemId() || chargeStone.getEnchantLevel() > 0 || stigma.getEnchantLevel() >= 10)
			return;
		if (!stigma.isStigmaChargeable())
			return;

		final boolean isSuccess = Rnd.chance() < Math.max(25, 100 - (stigma.getEnchantLevel() * 10));

		final int parentItemId = stigma.getItemId();
		final int parentObjectId = stigma.getObjectId();
		PacketSendUtility.broadcastPacket(player,
			new SM_ITEM_USAGE_ANIMATION(player.getObjectId(), parentObjectId, chargeStone.getObjectId(), parentItemId, 5000, 0, 0), true);
		final ItemUseObserver observer = new ItemUseObserver() {

			@Override
			public void abort() {
				player.getController().cancelTask(TaskId.ITEM_USE);
				player.removeItemCoolDown(stigma.getItemTemplate().getUseLimits().getDelayId());
				PacketSendUtility.sendPacket(player, SM_SYSTEM_MESSAGE.STR_ITEM_CANCELED());
				PacketSendUtility.broadcastPacket(player,
					new SM_ITEM_USAGE_ANIMATION(player.getObjectId(), parentObjectId, chargeStone.getObjectId(), parentItemId, 0, 2, 0), true);
				player.getObserveController().removeObserver(this);
			}
		};
		player.getObserveController().attach(observer);
		player.getController().addTask(TaskId.ITEM_USE, ThreadPoolManager.getInstance().schedule(new Runnable() {

			@Override
			public void run() {
				player.getObserveController().removeObserver(observer);
				PacketSendUtility.broadcastPacket(player,
					new SM_ITEM_USAGE_ANIMATION(player.getObjectId(), parentObjectId, parentItemId, 0, isSuccess ? 1 : 2, 1), true);
				if (!player.getInventory().decreaseByObjectId(chargeStone.getObjectId(), 1, ItemPacketService.ItemUpdateType.DEC_STIGMA_USE))
					return;
				if (!isSuccess) {
					if (stigma.isEquipped())
						player.getEquipment().unEquipItem(stigma.getObjectId());
					player.getInventory().decreaseByObjectId(stigma.getObjectId(), 1, ItemPacketService.ItemUpdateType.DEC_STIGMA_USE);
					PacketSendUtility.sendPacket(player, SM_SYSTEM_MESSAGE.STR_MSG_STIGMA_ENCHANT_FAIL(stigma.getL10n()));
				} else {
					stigma.setEnchantLevel(stigma.getEnchantLevel() + 1);
					if (stigma.isEquipped()) {
						removeStigmaSkills(player, stigmaInfo, stigma.getEnchantLevel() - 1, false);
						addStigmaSkills(player, stigmaInfo, stigma.getEnchantLevel());
					}
					PacketSendUtility.sendPacket(player, SM_SYSTEM_MESSAGE.STR_MSG_STIGMA_ENCHANT_SUCCESS(stigma.getL10n()));
					PacketSendUtility.sendPacket(player, new SM_INVENTORY_UPDATE_ITEM(player, stigma));
					if (stigma.getPersistentState() != PersistentState.DELETED) {
						stigma.setPersistentState(PersistentState.UPDATE_REQUIRED);
						if (stigma.isEquipped())
							player.getEquipment().setPersistentState(PersistentState.UPDATE_REQUIRED);
						else
							player.getInventory().setPersistentState(PersistentState.UPDATE_REQUIRED);
					}
				}
			}

		}, 5000));
	}

	private static void addStigmaSkills(Player player, Stigma stigma, int stigmaLevel) {
		for (String skillGroup : stigma.getGainSkillGroups())
			for (SkillTemplate st : DataManager.SKILL_DATA.getSkillTemplatesByGroup(skillGroup))
				for (SkillLearnTemplate skill : DataManager.SKILL_TREE_DATA.getTemplatesForSkill(st.getSkillId(), player.getPlayerClass(), player.getRace()))
					if (player.getLevel() >= skill.getMinLevel())
						SkillLearnService.learnTemporarySkill(player, skill.getSkillId(), stigmaLevel + 1);
	}

	public static void removeStigmaSkills(Player player, Stigma stigma, int stigmaLevel, boolean notifyPlayer) {
		List<String> notifiedSkillL10ns = new ArrayList<>();
		for (String skillGroup : stigma.getGainSkillGroups()) {
			for (SkillTemplate st : DataManager.SKILL_DATA.getSkillTemplatesByGroup(skillGroup)) {
				if (notifyPlayer && st.getL10n() != null && !notifiedSkillL10ns.contains(st.getL10n())) {
					notifiedSkillL10ns.add(st.getL10n());
					PacketSendUtility.sendPacket(player, SM_SYSTEM_MESSAGE.STR_STIGMA_YOU_CANNOT_USE_THIS_SKILL_AFTER_UNEQUIP_STIGMA_STONE(st.getL10n()));
				}
				for (SkillLearnTemplate skill : DataManager.SKILL_TREE_DATA.getTemplatesForSkill(st.getSkillId(), player.getPlayerClass(), player.getRace()))
					SkillLearnService.removeSkill(player, skill.getSkillId());
			}
		}
		removeLinkedStigmaSkills(player);
	}
}

📎 첨부파일

댓글 작성 권한이 없습니다.
🏆 포인트 랭킹 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