[share] Поддержка самопальных заточек в фениксе - Форум администраторов игровых серверов
Форум администраторов игровых серверов StormWall - Защита от DDos атак
Регистрация Мнения Справка Сообщество Календарь
Вернуться   Форум администраторов игровых серверов > MMO > Lineage II

Lineage II
Дискуссии на тему создания, настройки и обслуживания серверов Lineage 2. При поддержке: Премиум услуги по рекламе

Описание темы:типа эвентовых и т.п.

Ответ
Опции темы
Непрочитано 05.12.2011, 12:58   #1
Аватар для Gaikotsu
Герой

Автор темы (Топик Стартер) [share] Поддержка самопальных заточек в фениксе

Выкладываю простенький класс для феникса, для поддержки самопальных свитков заточки (например поддержки свитков для заточки посоха в эвенте Master of Enchanting или свитки для точения Olf's T-Shirt).

Изначально в пакетах заточки в фениксе имеется поддержка заточек посоха для эвента Master of Enchanting, можно и для других комбинаций добавить, но сами понимаете - код получается из-за всех этих условий жутко громоздким и нечитабельным.
Собственно из-за этого я где-то с месяц назад и набросал для своего удобства класс, который поддерживает неограниченное количество самопальных комбинаций "свиток + затачиваемые свитком вещи", не усложняет сильно серверные пакеты заточки и легко настраивается через датапак.

итак, вот сам класс (куда положить в ядре - видно по заголовку):
Код:
package l2p.gameserver.tables;

import java.io.File;
import java.util.HashMap;
import java.util.logging.Logger;

import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;

import l2p.Config;
import l2p.extensions.multilang.CustomMessage;
import l2p.gameserver.cache.Msg;
import l2p.gameserver.model.L2Player;
import l2p.gameserver.model.items.L2ItemInstance;
import l2p.gameserver.model.items.PcInventory;
import l2p.gameserver.serverpackets.EnchantResult;
import l2p.gameserver.serverpackets.ExPutEnchantTargetItemResult;
import l2p.gameserver.serverpackets.InventoryUpdate;
import l2p.gameserver.serverpackets.SystemMessage;
import l2p.gameserver.tables.ItemTable;
import l2p.gameserver.tables.SkillTable;
import l2p.gameserver.templates.L2Item;
import l2p.util.GArray;
import l2p.util.Log;
import l2p.util.Rnd;
import l2p.util.XMLUtil;

public class EnchantScrollData
{
	private static final String xmlFile = "data/enchant_scrolls.xml";
	
	private static EnchantScrollData _instance;
	private static HashMap<Integer, ScrollData> _data = new HashMap<Integer, ScrollData>();
	private static Logger _log = Logger.getLogger(EnchantScrollData.class.getName());

	private static final class ScrollData
	{
		public int chance = 0;
		public int action_of_fail = 0;
		public int safe_enchant = 0;
		public int max_enchant = 0;
		public int premium_bonus = 0;
		public GArray<Integer> items = new GArray<Integer>();
	}

	public static EnchantScrollData getInstance()
	{
		if(_instance == null)
			_instance = new EnchantScrollData();
		return _instance;
	}

	public EnchantScrollData()
	{
		loadXml();
	}

	private void loadXml()
	{
		final File localFile = new File(xmlFile);
		if (!localFile.exists())
		{
			System.out.println("File '" + xmlFile + "' not found!");
			return;
		}
		Document localDocument = null;
		try
		{
			final DocumentBuilderFactory localDocumentBuilderFactory = DocumentBuilderFactory.newInstance();
			localDocumentBuilderFactory.setValidating(false);
			localDocumentBuilderFactory.setIgnoringComments(true);
			localDocument = localDocumentBuilderFactory.newDocumentBuilder().parse(localFile);
		}
		catch (final Exception e)
		{
			e.printStackTrace();
		}
		try
		{
			parseXml(localDocument);
		}
		catch (final Exception e)
		{
			e.printStackTrace();
		}
	}

	private void parseXml(final Document doc)
	{
		for (Node il = doc.getFirstChild(); il != null; il = il.getNextSibling())
			if ("list".equalsIgnoreCase(il.getNodeName()))
				for (Node area = il.getFirstChild(); area != null; area = area.getNextSibling())
				{
					if ("scroll".equalsIgnoreCase(area.getNodeName()))
					{
						ScrollData data = new ScrollData();
						int scrollId = XMLUtil.getAttributeIntValue(area, "id", 0);
						if (scrollId > 0 && ItemTable.getInstance().isExists(scrollId))
						{
							data.chance = XMLUtil.getAttributeIntValue(area, "chance", 66);
							data.action_of_fail = XMLUtil.getAttributeIntValue(area, "action_of_fail", 0);
							data.safe_enchant = XMLUtil.getAttributeIntValue(area, "safe_enchant", 3);
							data.max_enchant = XMLUtil.getAttributeIntValue(area, "max_enchant", Config.ENCHANT_MAX);
							data.premium_bonus = XMLUtil.getAttributeIntValue(area, "premium_bonus", 0);
							String temp = XMLUtil.getAttributeValue(area, "item_to_enchant");
							if (temp != null && !temp.isEmpty())
							{
								String items[] = temp.split(",");
								for (String item : items)
								{
									int itemId = Integer.parseInt(item);
									if (itemId > 0 && ItemTable.getInstance().isExists(itemId))
										data.items.add(itemId);
									else
										_log.warning("EnchantScrollData: Not found item for enchant with id = " + itemId + ", scroll id = " + scrollId);
								}
							}
							if (data.items.size() == 0)
								_log.warning("EnchantScrollData: not specified enchanting items for scroll with id = " + scrollId);
							else
								_data.put(scrollId, data);
						}
						else
							_log.warning("EnchantScrollData: Not found scroll with id = " + scrollId);
					}
				}
		_log.info("EnchantScrollData: Loaded " + _data.size() + " custom enchant scrolls.");
	}

	public boolean requestEnchantItem(L2Player player, PcInventory inventory, L2ItemInstance scroll, L2ItemInstance item)
	{
		if (player == null || scroll == null || item == null || !_data.containsKey(scroll.getItemId()))
			return false;

		ScrollData data = _data.get(scroll.getItemId());

		if (!data.items.contains(item.getItemId()))
		{
			player.sendPacket(EnchantResult.CANCEL);
			player.sendPacket(Msg.INAPPROPRIATE_ENCHANT_CONDITIONS);
			player.sendActionFailed();
			return true;
		}

		if (item.getLocation() != L2ItemInstance.ItemLocation.INVENTORY && item.getLocation() != L2ItemInstance.ItemLocation.PAPERDOLL)
		{
			player.sendPacket(EnchantResult.CANCEL);
			player.sendPacket(Msg.INAPPROPRIATE_ENCHANT_CONDITIONS);
			player.sendActionFailed();
			return true;
		}

		if (player.getPrivateStoreType() != L2Player.STORE_PRIVATE_NONE)
		{
			player.sendPacket(EnchantResult.CANCEL);
			player.sendPacket(Msg.YOU_CANNOT_PRACTICE_ENCHANTING_WHILE_OPERATING_A_PRIVATE_STORE_OR_PRIVATE_MANUFACTURING_WORKSHOP);
			player.sendActionFailed();
			return true;
		}

		if (item.isStackable() || (scroll = inventory.getItemByObjectId(scroll.getObjectId())) == null)
		{
			player.sendPacket(EnchantResult.CANCEL);
			player.sendActionFailed();
			return true;
		}

		if (item.getOwnerId() != player.getObjectId())
		{
			player.sendPacket(EnchantResult.CANCEL);
			player.sendPacket(Msg.INAPPROPRIATE_ENCHANT_CONDITIONS);
			player.sendActionFailed();
			return true;
		}

		if (item.getEnchantLevel() >= data.max_enchant)
		{
			player.sendPacket(EnchantResult.CANCEL);
			player.sendMessage(new CustomMessage("l2p.gameserver.clientpackets.RequestEnchantItem.MaxLevel", player));
			player.sendActionFailed();
			return true;
		}

		L2ItemInstance removedScroll = null;
		synchronized (inventory)
		{
			removedScroll = inventory.destroyItem(scroll, 1, true);
		}

		if (removedScroll == null)
		{
			player.sendPacket(EnchantResult.CANCEL);
			player.sendActionFailed();
			return true;
		}

		int itemType = item.getItem().getType2();
		double chance = item.getEnchantLevel() < data.safe_enchant ? 100 : data.chance;
		
		if (data.premium_bonus > 0 && player.getNetConnection().getBonus() > 1)
			chance += data.premium_bonus;
		
		chance = Math.min(chance, 100D);

		Log.add(player.getName() + "|Trying to enchant|" + item.getItemId() + "|+" + item.getEnchantLevel() + "|" + item.getObjectId(), "enchants");

		if (Rnd.chance(chance))
		{
			item.setEnchantLevel(item.getEnchantLevel() + 1);
			item.updateDatabase();
			player.sendPacket(new InventoryUpdate().addModifiedItem(item));
			Log.add(player.getName() + "|Successfully enchanted|" + item.getItemId() + "|to+" + item.getEnchantLevel() + "|" + chance, "enchants");
			Log.LogItem(player, Log.EnchantItem, item);
			player.sendPacket(EnchantResult.SUCESS);

			if (item.getEnchantLevel() >= (itemType == L2Item.TYPE2_WEAPON ? 6 : 5))
			{
				player.enableSkill(21006);
				player.altUseSkill(SkillTable.getInstance().getInfo(21006, 1), player);
				player.broadcastPacket(new SystemMessage(SystemMessage.C1_HAS_SUCCESSFULY_ENCHANTED_A__S2_S3).addName(player).addNumber(item.getEnchantLevel()).addItemName(item.getItemId()));
			}
		}
		else
		{
			Log.add(player.getName() + "|Failed to enchant|" + item.getItemId() + "|+" + item.getEnchantLevel() + "|" + chance, "enchants");

			if (data.action_of_fail == 0)
			{
				if (item.isEquipped())
					inventory.unEquipItemInSlot(item.getEquipSlot());

				L2ItemInstance destroyedItem = inventory.destroyItem(item.getObjectId(), 1, true);
				if (destroyedItem == null)
				{
					_log.warning("failed to destroy " + item.getObjectId() + " after unsuccessful enchant attempt by char " + player.getName());
					player.sendActionFailed();
					return true;
				}

				Log.LogItem(player, Log.EnchantItemFail, item);
				player.sendPacket(EnchantResult.FAILED_NO_CRYSTALS);
				player.refreshExpertisePenalty();
			}
			else if (data.action_of_fail == 1)
			{
				item.setEnchantLevel(0);
				player.sendPacket(new InventoryUpdate().addModifiedItem(item));
				player.sendPacket(Msg.FAILED_IN_BLESSED_ENCHANT_THE_ENCHANT_VALUE_OF_THE_ITEM_BECAME_0);
				player.sendPacket(EnchantResult.BLESSED_FAILED);
			}
			else if (data.action_of_fail == 2)
			{
				player.sendPacket(EnchantResult.ANCIENT_FAILED);
			}
		}

		player.refreshOverloaded();
		player.setEnchantScroll(null);
		player.sendChanges();
		return true;
	}

	public boolean requestExTryToPutEnchantTargetItem(L2Player player, PcInventory inventory, L2ItemInstance scroll, L2ItemInstance item)
	{
		if (player == null || scroll == null || item == null || !_data.containsKey(scroll.getItemId()))
			return false;

		ScrollData data = _data.get(scroll.getItemId());

		if (!data.items.contains(item.getItemId()))
		{
			player.sendActionFailed();
			player.sendPacket(Msg.INAPPROPRIATE_ENCHANT_CONDITIONS);
			return true;
		}

		if (item.isStackable())
		{
			player.sendActionFailed();
			player.sendPacket(Msg.DOES_NOT_FIT_STRENGTHENING_CONDITIONS_OF_THE_SCROLL);
			return true;
		}

		if (item.getLocation() != L2ItemInstance.ItemLocation.INVENTORY && item.getLocation() != L2ItemInstance.ItemLocation.PAPERDOLL)
		{
			player.sendActionFailed();
			player.sendPacket(Msg.INAPPROPRIATE_ENCHANT_CONDITIONS);
			return true;
		}

		if (player.getPrivateStoreType() != L2Player.STORE_PRIVATE_NONE)
		{
			player.sendPacket(new ExPutEnchantTargetItemResult(0, 0, 0));
			player.sendPacket(Msg.YOU_CANNOT_PRACTICE_ENCHANTING_WHILE_OPERATING_A_PRIVATE_STORE_OR_PRIVATE_MANUFACTURING_WORKSHOP);
			return true;
		}

		if ((scroll = inventory.getItemByObjectId(scroll.getObjectId())) == null)
		{
			player.setEnchantScroll(null);
			player.sendPacket(new ExPutEnchantTargetItemResult(0, 0, 0));
			return true;
		}

		if (item.getEnchantLevel() >= data.max_enchant)
		{
			player.sendActionFailed();
			player.sendMessage(new CustomMessage("l2p.gameserver.clientpackets.RequestEnchantItem.MaxLevel", player));
			return true;
		}

		if (item.getOwnerId() != player.getObjectId())
		{
			player.sendPacket(new ExPutEnchantTargetItemResult(0, 0, 0));
			return true;
		}

		Log.add(player.getName() + "|Trying to put enchant|" + item.getItemId() + "|+" + item.getEnchantLevel() + "|" + item.getObjectId(), "enchants");
		player.sendPacket(new ExPutEnchantTargetItemResult(1, 0, 0));
		return true;
	}
}
а в датапак кладем xml-файл с названием enchant_scrolls.xml и примерно с таким содержанием (как обявлять новые комбинации понятно из комментариев в начале):
Код:
<?xml version="1.0" encoding="utf-8"?>
<list>
	<!--
	Здесь перечислены нестандартные свитки заточек, используемые для заточки определенных предметов, в основном для эвентов.

	Параметры, которые можно задавать для свитков:
		id		- идентификатор свитка.
		chance		- шанс удачной заточки (по умолчанию равно 66).
		action_of_fail	- действие с затачиваемым предметом при неудачной заточке: 0 - удалить, 1 - обнулить заточку, 2 - оставить старую заточку (по умолчанию равно 0).
		safe_enchant	- до какого уровня заточка является безопасной (по умолчанию равно 3).
		max_enchant	- до скольки максимум можно точить этим свитком (по умолчанию берется стандартный максимум, указанный в конфигурации сервера).
		premium_bonus	- прибавка к шансу успешной заточки, если у игрока активен премиум аккаунт (по умолчанию равно 0).
		item_to_enchant	- идентиикатор предмета, который можно заточить этим свитком (можно указывать несколько предметов, перечисляя идентификаторы через запятую).

	Внимание! Свитки обязательно должны быть зарегистрированы как свитки заточки в хэндлере data/scripts/items/EnchantScrolls.java.
	-->
	<!-- Master Yogi's Scroll: Enchant Weapon -->
	<scroll id="13540" chance="66" action_of_fail="0" safe_enchant="3" max_enchant="23" premium_bonus="0" item_to_enchant="13539" />
	<!-- Olf's T-shirt Enchant Scroll -->
	<scroll id="21581" chance="66" action_of_fail="0" safe_enchant="3" max_enchant="9" premium_bonus="0" item_to_enchant="21580" />
	<!-- Blessed Olf's T-shirt Enchant Scroll -->
	<scroll id="21582" chance="66" action_of_fail="1" safe_enchant="3" max_enchant="9" premium_bonus="0" item_to_enchant="21580" />
	<!-- Blessed Olf's T-shirt Enchant Scroll [Event] -->
	<scroll id="21707" chance="66" action_of_fail="1" safe_enchant="3" max_enchant="9" premium_bonus="0" item_to_enchant="21706" />
</list>
Изменения, которые еще требуется сделать в ядре сервера:

Код:
GameServer.java:

Добавить в любое удобное место метода GameServer(), где вызываются остальные подобные классы, строку

EnchantScrollData.getInstance();
---------
RequestEnchantItem.java:

Добавить после строк

		if (!RequestExTryToPutEnchantSupportItem.checkCatalyst(itemToEnchant, catalyst))
			catalyst = null;

строки

		if (EnchantScrollData.getInstance().requestEnchantItem(activeChar, inventory, scroll, itemToEnchant))
			return;
---------
RequestExTryToPutEnchantTargetItem.java:

Добавить после строк

		if (itemToEnchant == null || scroll == null)
		{
			activeChar.sendPacket(new ExPutEnchantTargetItemResult(0, 0, 0));
			return;
		}

строки

		if (EnchantScrollData.getInstance().requestExTryToPutEnchantTargetItem(activeChar, inventory, scroll, itemToEnchant))
			return;
Ну и не забываем добавить в этих классах в импорты класс EnchantScrollData.

Так же стоит почистить пакеты RequestEnchantItem и RequestExTryToPutEnchantTargetItem от уже ненужных проверок на соответствие вещей на свиток и посох из эвента Master of Enchanting - все равно это будет после всего этого мертвым кодом.

З.Ы. и да, просьба к определенным личностям не тырить шару и не продавать ее потом как свою "собственноручно написанную разработку, которую вы можете купить только у нас" - намек думаю понятно кому адресован
Gaikotsu вне форума Ответить с цитированием
Сказали спасибо:
Непрочитано 05.12.2011, 13:41   #2
Забанен за кидаловo/обман/развод

По умолчанию Re: [share] Поддержка самопальных заточек в фениксе

Цитата:
Сообщение от Gaikotsu Посмотреть сообщение
З.Ы. и да, просьба к определенным личностям не тырить шару и не продавать ее потом как свою "собственноручно написанную разработку, которую вы можете купить только у нас" - намек думаю понятно кому адресован
Чётко под-убрал ))
KilRoy вне форума Отправить сообщение для KilRoy с помощью ICQ Отправить сообщение для KilRoy с помощью Skype™ Ответить с цитированием
Ответ


Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Сброс заточек на нужный лвл hard_root Lineage II 5 11.08.2012 17:40
ОлимпБафер на фениксе и на опен Munhgauzen Работа со скриптами 1 09.10.2011 08:38
Wol поддержка Benedikt Создание сервера 0 05.10.2011 12:45
Дюп на фениксе, л2ж и тд Blast Lineage II 21 13.03.2011 00:42
Ака на Фениксе StealingInShade Lineage II 6 22.03.2010 20:33


© 2007–2024 «Форум администраторов игровых серверов»
Защита сайта от DDoS атак — StormWall
Работает на Булке неизвестной версии с переводом от zCarot
Текущее время: 19:53. Часовой пояс GMT +3.

Вверх