Beauty Shop - Форум администраторов игровых серверов
Форум администраторов игровых серверов StormWall - Защита от DDos атак
Регистрация Мнения Справка Сообщество Календарь
Вернуться   Форум администраторов игровых серверов > MMO > Lineage II

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

Описание темы:Что это такое, с чем употреблять и как реализовать

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

Автор темы (Топик Стартер) Beauty Shop

Думаю все в курсе, что в Lindvior ввели Beauty Shop (салон красоты), предназначенный для изменения внешнего вида персонажей (прически, цвета волос, лица).

Ну и собственно в данном руководстве я хочу более-менее подробно описать, как реализовать данное дело в сервере, в частности на сервере основанном на оверах.

Итак, поехали:

Первым делом создадим 3 новых поля в таблице characters, аналоги полей face, hairStyle и hairColor - назовем их к примеру newFace, newHairStyle и newHairColor. Объяснять как читать и писать в эти поля, а так же как добавить новые переменные и геттеры/сеттеры для них в класс Player я не буду - это самые основы знания Java, не знать такое просто грешно

Может сразу возникнуть вполне закономерный вопрос - а почему бы не использовать существующие поля для хранения информации о внешности? Ответ прост - в некоторых ситуациях нам потребуется знать и то, каким была внешность до посещения салона красоты, к примеру для функции отмены изменений в том же самом салоне, или же для фестиваля хаоса - новые прически на фестивале не отображаются (правда насчет этого информация неподтвержденная, но так написано в патчноутах).

Далее озаботимся хранилищем данных о допустимых прическах и т.д., а так же загрузкой этих данных при запуске сервера.

Хранить данные мы будем в xml-файле следующей структуры:
 
<?xml version="1.0" encoding="utf-8"?>
<!ELEMENT list (config|set)*>
 
<!ELEMENT config (#PCDATA)*>
<!ATTLIST config
	coin_item_id CDATA #REQUIRED
	def_reset_price CDATA #REQUIRED>
 
<!ELEMENT set (hair|face)*>
<!ATTLIST set
	id CDATA #REQUIRED>
 
<!ELEMENT hair (color)*>
<!ATTLIST hair
	id CDATA #REQUIRED
	adena CDATA #REQUIRED
	coins CDATA #REQUIRED
	reset_price CDATA #IMPLIED>
 
<!ELEMENT color (#PCDATA)>
<!ATTLIST color
	id CDATA #REQUIRED
	adena CDATA #REQUIRED
	coins CDATA #REQUIRED>
 
<!ELEMENT face (#PCDATA)>
<!ATTLIST face
	id CDATA #REQUIRED
	adena CDATA #REQUIRED
	coins CDATA #REQUIRED
	reset_price CDATA #IMPLIED>
 
Code: XML
И для примера фрагмент xml с данными
 
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE list SYSTEM "beauty_shop.dtd">
<list>
	<config coin_item_id="36308" def_reset_price="1000000" />
	<!-- Human Male Fighter -->
	<set id="0">
		<!-- Прически -->
		<hair id="10001" adena="15000000" coins="0" />	<!-- Настоящий мачо A -->
		<hair id="10002" adena="15000000" coins="0" />	<!-- Прекрасный юноша A -->
		<hair id="10003" adena="0" coins="4">	<!-- Пират -->
			<color id="101" adena="3000000" coins="0" />	<!-- Рекомендация дизайнера -->
			<color id="102" adena="0" coins="1" />	<!-- Светло-кобальтовое небо -->
			<color id="103" adena="0" coins="1" />	<!-- Лиловый виноград -->
			<color id="104" adena="0" coins="1" />	<!-- Розовый карандаш -->
			<color id="105" adena="0" coins="1" />	<!-- Черная бездна -->
			<color id="106" adena="0" coins="1" />	<!-- Изумрудное украшение -->
			<color id="107" adena="0" coins="1" />	<!-- Желтая бабочка -->
			<color id="108" adena="0" coins="1" />	<!-- Вечнозеленый -->
			<color id="109" adena="0" coins="1" />	<!-- Волшебная метель -->
			<color id="110" adena="0" coins="1" />	<!-- Молчание серого ветра -->
		</hair>
		<hair id="10004" adena="0" coins="4">	<!-- Настоящий смельчак -->
			<color id="101" adena="3000000" coins="0" />	<!-- Рекомендация дизайнера -->
			<color id="102" adena="0" coins="1" />	<!-- Светло-кобальтовое небо -->
			<color id="103" adena="0" coins="1" />	<!-- Лиловый виноград -->
			<color id="104" adena="0" coins="1" />	<!-- Розовый карандаш -->
			<color id="105" adena="0" coins="1" />	<!-- Черная бездна -->
			<color id="106" adena="0" coins="1" />	<!-- Изумрудное украшение -->
			<color id="107" adena="0" coins="1" />	<!-- Желтая бабочка -->
			<color id="108" adena="0" coins="1" />	<!-- Вечнозеленый -->
			<color id="109" adena="0" coins="1" />	<!-- Волшебная метель -->
			<color id="110" adena="0" coins="1" />	<!-- Молчание серого ветра -->
		</hair>
		<hair id="10005" adena="15000000" coins="0" />	<!-- Потому что она - моя женщина A -->
		<hair id="10006" adena="15000000" coins="0" />	<!-- Честь джентльмена A -->
		<hair id="10007" adena="0" coins="3" />	<!-- Настоящий мачо B -->
		<hair id="10008" adena="0" coins="3" />	<!-- Прекрасный юноша B -->
		<hair id="10009" adena="0" coins="3" />	<!-- Потому что она - моя женщина B -->
		<hair id="10010" adena="0" coins="3" />	<!-- Честь джентльмена B -->
		<!-- Лица -->
		<face id="20001" adena="2000000" coins="0" reset_price="500000" />	<!-- Стиль A -->
		<face id="20002" adena="2000000" coins="0" reset_price="500000" />	<!-- Стиль B -->
		<face id="20003" adena="2000000" coins="0" reset_price="500000" />	<!-- Стиль C -->
		<face id="20004" adena="0" coins="2" />	<!-- Стиль Орена -->
		<face id="20005" adena="0" coins="2" />	<!-- Стиль Годдарда -->
	</set>
	<!-- Human Female Fighter -->
	<set id="1">
		<!-- Прически -->
		<hair id="10001" adena="15000000" coins="0" />	<!-- Холодная городская девушка A -->
		<hair id="10002" adena="15000000" coins="0" />	<!-- Грибочек A -->
		<hair id="10003" adena="0" coins="4">	<!-- Пират -->
			<color id="101" adena="3000000" coins="0" />	<!-- Рекомендация дизайнера -->
			<color id="102" adena="0" coins="1" />	<!-- Светло-кобальтовое небо -->
			<color id="103" adena="0" coins="1" />	<!-- Лиловый виноград -->
			<color id="104" adena="0" coins="1" />	<!-- Розовый карандаш -->
			<color id="105" adena="0" coins="1" />	<!-- Черная бездна -->
			<color id="106" adena="0" coins="1" />	<!-- Изумрудное украшение -->
			<color id="107" adena="0" coins="1" />	<!-- Желтая бабочка -->
			<color id="108" adena="0" coins="1" />	<!-- Вечнозеленый -->
			<color id="109" adena="0" coins="1" />	<!-- Волшебная метель -->
			<color id="110" adena="0" coins="1" />	<!-- Молчание серого ветра -->
		</hair>
		<hair id="10004" adena="0" coins="4">	<!-- Конский хвост -->
			<color id="101" adena="3000000" coins="0" />	<!-- Рекомендация дизайнера -->
			<color id="102" adena="0" coins="1" />	<!-- Светло-кобальтовое небо -->
			<color id="103" adena="0" coins="1" />	<!-- Лиловый виноград -->
			<color id="104" adena="0" coins="1" />	<!-- Розовый карандаш -->
			<color id="105" adena="0" coins="1" />	<!-- Черная бездна -->
			<color id="106" adena="0" coins="1" />	<!-- Изумрудное украшение -->
			<color id="107" adena="0" coins="1" />	<!-- Желтая бабочка -->
			<color id="108" adena="0" coins="1" />	<!-- Вечнозеленый -->
			<color id="109" adena="0" coins="1" />	<!-- Волшебная метель -->
			<color id="110" adena="0" coins="1" />	<!-- Молчание серого ветра -->
		</hair>
		<hair id="10005" adena="15000000" coins="0" />	<!-- Харизматичная амазонка A -->
		<hair id="10006" adena="15000000" coins="0" />	<!-- Унесенная ветром A -->
		<hair id="10007" adena="0" coins="3" />	<!-- Холодная городская девушка B -->
		<hair id="10008" adena="0" coins="3" />	<!-- Грибочек B -->
		<hair id="10009" adena="0" coins="3" />	<!-- Харизматичная амазонка B -->
		<hair id="10010" adena="0" coins="3" />	<!-- Унесенная ветром B -->
		<!-- Лица -->
		<face id="20001" adena="2000000" coins="0" reset_price="500000" />	<!-- Стиль A -->
		<face id="20002" adena="2000000" coins="0" reset_price="500000" />	<!-- Стиль B -->
		<face id="20003" adena="2000000" coins="0" reset_price="500000" />	<!-- Стиль C -->
		<face id="20004" adena="0" coins="2" />	<!-- Стиль Орена -->
		<face id="20005" adena="0" coins="2" />	<!-- Стиль Годдарда -->
	</set>
 
	...
 
</list>
 
Code: XML
Внимательные могут сразу же заметить избыточность данных в файле - для каждой расы/пола в общем-то данные одни и те же. Я это знаю, просто обычно предпочитаю реализовывать многое с учетом того, что может быть сейчас и все одинаково для любой расы/пола, но кто их корейцев знает - могут и изменить в будущем эту ситуацию. Так что в принципе если вам такая избыточность не нужна - это легко все дорабатывается до одного единственного набора данных для любой расы/пола. Опять же это делать вам самим, тем более что это легко - ломать не строить .

Далее добавляем в ядро сервера парсер этих данных и хранилище для них.

Парсер:
 
package l2p.gameserver.data.xml.parser;
 
import l2p.commons.data.xml.AbstractFileParser;
import l2p.gameserver.Config;
import l2p.gameserver.data.xml.holder.BeautyShopHolder;
import l2p.gameserver.model.beautyshop.BeautyShopFace;
import l2p.gameserver.model.beautyshop.BeautyShopSet;
import l2p.gameserver.model.beautyshop.BeautyShopHairColor;
import l2p.gameserver.model.beautyshop.BeautyShopHairStyle;
import l2p.gameserver.utils.Util;
 
import org.dom4j.Element;
 
import gnu.trove.map.hash.TIntObjectHashMap;
 
import java.io.File;
import java.util.Iterator;
 
public final class BeautyShopParser extends AbstractFileParser<BeautyShopHolder>
{
	private static final BeautyShopParser _instance = new BeautyShopParser();
 
	public static BeautyShopParser getInstance()
	{
		return _instance;
	}
 
	private BeautyShopParser()
	{
		super(BeautyShopHolder.getInstance());
	}
 
	@Override
	public File getXMLFile()
	{
		return new File(Config.DATAPACK_ROOT, "data/beauty_shop.xml");
	}
 
	@Override
	public String getDTDFileName()
	{
		return "beauty_shop.dtd";
	}
 
	@Override
	protected void readData(Element rootElement) throws Exception
	{
		long defResetPrice = 0L;
 
		for (Iterator iterator = rootElement.elementIterator("config"); iterator.hasNext();)
		{
			Element element = (Element) iterator.next();
			Config.BS_COIN_ITEM_ID = Util.parseValue(element.attributeValue("coin_item_id"), 36308);
			defResetPrice = Util.parseValue(element.attributeValue("def_reset_price"), 1000000L);
		}
 
		for (Iterator iterator = rootElement.elementIterator("set"); iterator.hasNext();)
		{
			Element element = (Element) iterator.next();
			int setId = Util.parseValue(element.attributeValue("id"), 0);
 
			TIntObjectHashMap<BeautyShopHairStyle> hairStyles = new TIntObjectHashMap<BeautyShopHairStyle>();
			TIntObjectHashMap<BeautyShopFace> faces = new TIntObjectHashMap<BeautyShopFace>();
 
			for (Iterator<Element> subIterator = element.elementIterator("hair"); subIterator.hasNext();)
			{
				Element subElement = subIterator.next();
				int id = Util.parseValue(subElement.attributeValue("id"), 0);
				long adena = Util.parseValue(subElement.attributeValue("adena"), 0L);
				long coins = Util.parseValue(subElement.attributeValue("coins"), 0L);
				long resetPrice = Util.parseValue(subElement.attributeValue("reset_price"), defResetPrice);
				TIntObjectHashMap<BeautyShopHairColor> colors = new TIntObjectHashMap<BeautyShopHairColor>();
 
				for (Iterator<Element> colorIterator = subElement.elementIterator("color"); colorIterator.hasNext();)
				{
					Element colorElement = colorIterator.next();
					int cId = Util.parseValue(colorElement.attributeValue("id"), 0);
					long cAdena = Util.parseValue(colorElement.attributeValue("adena"), 0L);
					long cCoins = Util.parseValue(colorElement.attributeValue("coins"), 0L);
					colors.put(cId, new BeautyShopHairColor(cId, cAdena, cCoins));
				}
 
				if (colors.isEmpty())
					colors.put(101, new BeautyShopHairColor(101, 0, 0));
 
				hairStyles.put(id, new BeautyShopHairStyle(id, adena, coins, resetPrice, colors));
			}
 
			for (Iterator<Element> subIterator = element.elementIterator("face"); subIterator.hasNext();)
			{
				Element subElement = subIterator.next();
				int id = Util.parseValue(subElement.attributeValue("id"), 0);
				long adena = Util.parseValue(subElement.attributeValue("adena"), 0L);
				long coins = Util.parseValue(subElement.attributeValue("coins"), 0L);
				long resetPrice = Util.parseValue(subElement.attributeValue("reset_price"), defResetPrice);
				faces.put(id, new BeautyShopFace(id, adena, coins, resetPrice));
			}
 
			getHolder().addSet(new BeautyShopSet(setId, hairStyles, faces));
		}
	}
}
 
Code: Java
Хранилище:
 
package l2p.gameserver.data.xml.holder;
 
import gnu.trove.map.hash.TIntObjectHashMap;
import l2p.commons.data.xml.AbstractHolder;
import l2p.gameserver.model.Player;
import l2p.gameserver.model.base.Race;
import l2p.gameserver.model.base.Sex;
import l2p.gameserver.model.beautyshop.BeautyShopSet;
 
public final class BeautyShopHolder extends AbstractHolder
{
	private static final BeautyShopHolder _instance = new BeautyShopHolder();
	private static final TIntObjectHashMap<BeautyShopSet> _sets = new TIntObjectHashMap<BeautyShopSet>();
 
	public static BeautyShopHolder getInstance()
	{
		return _instance;
	}
 
	public void addSet(BeautyShopSet set)
	{
		if (_sets.containsKey(set.getId()))
			warn("Duplicate set declaration, set id - " + set.getId());
 
		_sets.put(set.getId(), set);
	}
 
	public BeautyShopSet getSet(int id)
	{
		return _sets.get(id);
	}
 
	public BeautyShopSet getSet(Player player)
	{
		int id = -1;
 
		if (player.getRace() == Race.HUMAN)
		{
			if (!player.getClassId().isMage())
				id = player.getSex() == Sex.MALE ? 0 : 1;
			else
				id = player.getSex() == Sex.MALE ? 8 : 9;
		}
		else if (player.getRace() == Race.DARK_ELF)
			id = player.getSex() == Sex.MALE ? 2 : 3;
		else if (player.getRace() == Race.DWARF)
			id = player.getSex() == Sex.MALE ? 4 : 5;
		else if (player.getRace() == Race.ELF)
			id = player.getSex() == Sex.MALE ? 6 : 7;
		else if (player.getRace() == Race.ORC)
		{
			if (!player.getClassId().isMage())
				id = player.getSex() == Sex.MALE ? 10 : 11;
			else
				id = player.getSex() == Sex.MALE ? 12 : 13;
		}
		else if (player.getRace() == Race.KAMAEL)
			id = player.getSex() == Sex.MALE ? 14 : 15;
 
		return getSet(id);
	}
 
	@Override
	public int size()
	{
		return _sets.size();
	}
 
	@Override
	public void clear()
	{
		_sets.clear();
	}
 
	@Override
	public void log()
	{
		info(String.format("loaded %d beauty shop set(s) count.", size()));
	}
}
 
Code: Java
Структуры для хранения данных:
 
package l2p.gameserver.model.beautyshop;
 
import gnu.trove.map.hash.TIntObjectHashMap;
 
public class BeautyShopSet
{
	private final int _id;
	private final TIntObjectHashMap<BeautyShopHairStyle> _hairStyles;
	private final TIntObjectHashMap<BeautyShopFace> _faces;
 
	public BeautyShopSet(int id, TIntObjectHashMap<BeautyShopHairStyle> hairStyles, TIntObjectHashMap<BeautyShopFace> faces)
	{
		_id = id;
		_hairStyles = hairStyles;
		_faces = faces;
	}
 
	public int getId()
	{
		return _id;
	}
 
	public TIntObjectHashMap<BeautyShopHairStyle> getHairStyles()
	{
		return _hairStyles;
	}
 
	public BeautyShopHairStyle getHairStyle(int id)
	{
		return _hairStyles.get(id);
	}
 
	public TIntObjectHashMap<BeautyShopFace> getFaces()
	{
		return _faces;
	}
 
	public BeautyShopFace getFace(int id)
	{
		return _faces.get(id);
	}
}
 
 
package l2p.gameserver.model.beautyshop;
 
public class BeautyShopFace
{
	private final int _id;
	private final long _adena;
	private final long _coins;
	private final long _resetPrice;
 
	public BeautyShopFace(int id, long adena, long coins, long resetPrice)
	{
		_id = id;
		_adena = adena;
		_coins = coins;
		_resetPrice = resetPrice;
	}
 
	public int getId()
	{
		return _id;
	}
 
	public long getAdena()
	{
		return _adena;
	}
 
	public long getCoins()
	{
		return _coins;
	}
 
	public long getResetPrice()
	{
		return _resetPrice;
	}
}
 
 
package l2p.gameserver.model.beautyshop;
 
import gnu.trove.map.hash.TIntObjectHashMap;
 
public class BeautyShopHairStyle
{
	private final int _id;
	private final long _adena;
	private final long _coins;
	private final long _resetPrice;
 
	private final TIntObjectHashMap<BeautyShopHairColor> _hairColors;
 
	public BeautyShopHairStyle(int id, long adena, long coins, long resetPrice, TIntObjectHashMap<BeautyShopHairColor> hairColors)
	{
		_id = id;
		_adena = adena;
		_coins = coins;
		_resetPrice = resetPrice;
		_hairColors = hairColors;
	}
 
	public int getId()
	{
		return _id;
	}
 
	public long getAdena()
	{
		return _adena;
	}
 
	public long getCoins()
	{
		return _coins;
	}
 
	public long getResetPrice()
	{
		return _resetPrice;
	}
 
	public TIntObjectHashMap<BeautyShopHairColor> getHairColors()
	{
		return _hairColors;
	}
 
	public BeautyShopHairColor getHairColor(int id)
	{
		return _hairColors.get(id);
	}
}
 
 
package l2p.gameserver.model.beautyshop;
 
public class BeautyShopHairColor
{
	private final int _id;
	private final long _adena;
	private final long _coins;
 
	public BeautyShopHairColor(int id, long adena, long coins)
	{
		_id = id;
		_adena = adena;
		_coins = coins;
	}
 
	public int getId()
	{
		return _id;
	}
 
	public long getAdena()
	{
		return _adena;
	}
 
	public long getCoins()
	{
		return _coins;
	}
}
 
Code: Java
В парсере вы можете заметить для чтения значений используется некие методы c названием Util.parseValue( ... ) - приводить их код я не буду, т.к. и так понятно как и что они делают - можете просто написать свою реализацию их или же использовать уже что-то готовое (методы, выполняющие примерно те же функции, насколько помню вроде как были и в оригинальном овере).

Далее нам необходимо внести мелкие изменения в пакеты UserInfo, CharInfo и GMViewCharacterInfo, для корректного отображения новой внешности.

Изменения простейшие, типа таких:
 
		_hairStyle = player.getNewHairStyle() > 0 ? player.getNewHairStyle() : player.getHairStyle();
		_hairColor = player.getNewHairColor() > 0 ? player.getNewHairColor() : player.getHairColor();
		_face = player.getNewFace() > 0 ? player.getNewFace() : player.getFace();
 
Code: Java
Ну и напоследок самое главное - все пакеты, связанные с салоном красоты.
Объяснять их содержимое думаю нет смысла - они достаточно просты и по их коду и так все понятно.

Но сначала не забудем добавить в GamePacketHandler обработку необходимых клиентских пакетов:
 
case 0xD7:
	msg = new RequestShowBeautyList();
	break;
case 0xD8:
	msg = new RequestRegistBeauty();
	break;
case 0xDA:
	msg = new RequestShowResetShopList();
	break;
case 0xEE:
	msg = new NotifyExitBeautyShop();
	break;
 
Code: Java
Ну и непосредственно сами пакеты.

Клиентские:
 
package l2p.gameserver.network.clientpackets;
 
import l2p.gameserver.model.Player;
import l2p.gameserver.network.serverpackets.ExResponseBeautyList;
 
public class RequestShowBeautyList extends L2GameClientPacket
{
	private int _type;
 
	@Override
	protected void readImpl()
	{
		_type = readD();
	}
 
	@Override
	protected void runImpl()
	{
		Player player = getClient().getActiveChar();
 
		if (player == null)
			return;
 
		player.sendPacket(new ExResponseBeautyList(player, _type));
	}
}
 
 
package l2p.gameserver.network.clientpackets;
 
import l2p.gameserver.Config;
import l2p.gameserver.data.xml.holder.BeautyShopHolder;
import l2p.gameserver.model.Player;
import l2p.gameserver.model.beautyshop.BeautyShopSet;
import l2p.gameserver.network.serverpackets.ExResponseBeautyList;
import l2p.gameserver.network.serverpackets.ExResponseBeautyRegistReset;
 
public class RequestRegistBeauty extends L2GameClientPacket
{
	private int _hairStyle, _face, _hairColor;
 
	@Override
	protected void readImpl()
	{
		_hairStyle = readD();
		_face = readD();
		_hairColor = readD();
	}
 
	@Override
	protected void runImpl()
	{
		Player player = getClient().getActiveChar();
 
		if (player == null)
			return;
 
		long reqAdena = 0;
		long reqCoins = 0;
		boolean change = false;
		BeautyShopSet set = BeautyShopHolder.getInstance().getSet(player);
 
		if (set == null)
		{
			player.sendPacket(new ExResponseBeautyRegistReset(player, 0, 0), new ExResponseBeautyList(player, 0));
			return;
		}
 
		if (_hairStyle > 0 && _hairColor > 0 && (_hairStyle != player.getNewHairStyle() || _hairColor != player.getNewHairColor()))
		{
			if (set.getHairStyle(_hairStyle) == null || set.getHairStyle(_hairStyle).getHairColor(_hairColor) == null)
			{
				player.sendPacket(new ExResponseBeautyRegistReset(player, 0, 0), new ExResponseBeautyList(player, 0));
				return;
			}
 
			if (_hairStyle != player.getNewHairStyle())
			{
				reqAdena += set.getHairStyle(_hairStyle).getAdena() + set.getHairStyle(_hairStyle).getHairColor(_hairColor).getAdena();
				reqCoins += set.getHairStyle(_hairStyle).getCoins() + set.getHairStyle(_hairStyle).getHairColor(_hairColor).getCoins();
			}
			else
			{
				reqAdena += set.getHairStyle(_hairStyle).getHairColor(_hairColor).getAdena();
				reqCoins += set.getHairStyle(_hairStyle).getHairColor(_hairColor).getCoins();
			}
 
			change = true;
		}
 
		if (_face > 0 && _face != player.getNewFace())
		{
			if (set.getFace(_face) == null)
			{
				player.sendPacket(new ExResponseBeautyRegistReset(player, 0, 0), new ExResponseBeautyList(player, 0));
				return;
			}
 
			reqAdena += set.getFace(_face).getAdena();
			reqCoins += set.getFace(_face).getCoins();
			change = true;
		}
 
		if (!change || player.getItemCount(57) < reqAdena || player.getItemCount(Config.BS_COIN_ITEM_ID) < reqCoins)
		{
			player.sendPacket(new ExResponseBeautyRegistReset(player, 0, 0), new ExResponseBeautyList(player, 0));
			return;
		}
 
		if (reqAdena > 0)
			player.getInventory().destroyItemByItemId(57, reqAdena);
 
		if (reqCoins > 0)
			player.getInventory().destroyItemByItemId(Config.BS_COIN_ITEM_ID, reqCoins);
 
		if (_hairStyle > 0)
		{
			player.setNewHairStyle(_hairStyle);
			player.setNewHairColor(_hairColor);
		}
 
		if (_face > 0)
			player.setNewFace(_face);
 
		player.sendPacket(new ExResponseBeautyRegistReset(player, 0, 1), new ExResponseBeautyList(player, 0));
	}
}
 
 
package l2p.gameserver.network.clientpackets;
 
import l2p.gameserver.data.xml.holder.BeautyShopHolder;
import l2p.gameserver.model.Player;
import l2p.gameserver.model.beautyshop.BeautyShopSet;
import l2p.gameserver.network.serverpackets.ExResponseBeautyRegistReset;
 
public class RequestShowResetShopList extends L2GameClientPacket
{
	private int _hairStyle, _face, _hairColor;
 
	@Override
	protected void readImpl()
	{
		_hairStyle = readD();
		_face = readD();
		_hairColor = readD();
	}
 
	@Override
	protected void runImpl()
	{
		Player player = getClient().getActiveChar();
 
		if (player == null)
			return;
 
		long reqAdena = 0;
		boolean reset = false;
		BeautyShopSet set = BeautyShopHolder.getInstance().getSet(player);
 
		if (set == null)
		{
			player.sendPacket(new ExResponseBeautyRegistReset(player, 1, 0));
			return;
		}
 
		if (_hairStyle > 0 && _hairColor > 0)
		{
			if (set.getHairStyle(_hairStyle) == null)
			{
				player.sendPacket(new ExResponseBeautyRegistReset(player, 1, 0));
				return;
			}
 
			reqAdena += set.getHairStyle(_hairStyle).getResetPrice();
			reset = true;
		}
 
		if (_face > 0)
		{
			if (set.getFace(_face) == null)
			{
				player.sendPacket(new ExResponseBeautyRegistReset(player, 1, 0));
				return;
			}
 
			reqAdena += set.getFace(_face).getResetPrice();
			reset = true;
		}
 
		if (!reset || player.getAdena() < reqAdena)
		{
			player.sendPacket(new ExResponseBeautyRegistReset(player, 1, 0));
			return;
		}
 
		player.getInventory().destroyItemByItemId(57, reqAdena);
 
		if (_hairStyle > 0)
		{
			player.setNewHairStyle(0);
			player.setNewHairColor(0);
		}
 
		if (_face > 0)
			player.setNewFace(0);
 
		player.sendPacket(new ExResponseBeautyRegistReset(player, 1, 1));
	}
}
 
 
package l2p.gameserver.network.clientpackets;
 
import l2p.gameserver.model.Player;
 
public class NotifyExitBeautyShop extends L2GameClientPacket
{
	@Override
	protected void readImpl()
	{}
 
	@Override
	protected void runImpl()
	{
		Player player = getClient().getActiveChar();
 
		if (player == null)
			return;
 
		player.broadcastCharInfo();
	}
}
 
Code: Java
И серверные пакеты:
 
package l2p.gameserver.network.serverpackets;
 
import l2p.gameserver.network.serverpackets.components.ServerPacket;
 
public class ExShowBeautyMenu extends L2GameServerPacket
{
	public int _type;	// 0 - выбор нового внешнего вида, 1 - возврат старого
 
	public ExShowBeautyMenu(int type)
	{
		_type = type;
	}
 
	@Override
	protected void writeImpl()
	{
		writeEx(ServerPacket.ExShowBeautyMenu);
		writeD(_type);
	}
}
 
 
package l2p.gameserver.network.serverpackets;
 
import l2p.gameserver.Config;
import l2p.gameserver.data.xml.holder.BeautyShopHolder;
import l2p.gameserver.model.Player;
import l2p.gameserver.model.beautyshop.BeautyShopFace;
import l2p.gameserver.model.beautyshop.BeautyShopHairStyle;
import l2p.gameserver.model.beautyshop.BeautyShopSet;
import l2p.gameserver.network.serverpackets.components.ServerPacket;
 
public class ExResponseBeautyList extends L2GameServerPacket
{
	private int _type;
	private long _adena;
	private long _coins;
	private int[][] _data;
	private boolean _send = false;
 
	public ExResponseBeautyList(Player player, int type)
	{
		BeautyShopSet set = BeautyShopHolder.getInstance().getSet(player);
 
		if (set == null)
			return;
 
		int i = 0;
 
		if (type == 0)
		{
			_data = new int[set.getHairStyles().size()][2];
 
			for (BeautyShopHairStyle style : set.getHairStyles().valueCollection())
			{
				_data[i][0] = style.getId();
				_data[i][1] = 0;
				i++;
			}
		}
		else
		{
			_data = new int[set.getFaces().size()][2];
 
			for (BeautyShopFace face : set.getFaces().valueCollection())
			{
				_data[i][0] = face.getId();
				_data[i][1] = 0;
				i++;
			}
		}
 
		_type = type;
		_adena = player.getAdena();
		_coins = player.getItemCount(Config.BS_COIN_ITEM_ID);
		_send = true;
	}
 
	@Override
	protected void writeImpl()
	{
		if (!_send)
			return;
 
		writeEx(ServerPacket.ExResponseBeautyList);
		writeQ(_adena);
		writeQ(_coins);
		writeD(_type);
		writeD(_data.length);
 
		for (int[] element : _data)
		{
			writeD(element[0]);
			writeD(element[1]);
		}
	}
}
 
 
package l2p.gameserver.network.serverpackets;
 
import l2p.gameserver.Config;
import l2p.gameserver.model.Player;
import l2p.gameserver.network.serverpackets.components.ServerPacket;
 
public class ExResponseBeautyRegistReset extends L2GameServerPacket
{
	private int _type;
	private int _result;
	private int _hairStyle;
	private int _hairColor;
	private int _face;
	private long _adena;
	private long _coins;
 
	public ExResponseBeautyRegistReset(Player player, int type, int result)
	{
		_type = type;
		_result = result;
		_hairStyle = player.getNewHairStyle() > 0 ? player.getNewHairStyle() : player.getHairStyle();
		_hairColor = player.getNewHairColor() > 0 ? player.getNewHairColor() : player.getHairColor();
		_face = player.getNewFace() > 0 ? player.getNewFace() : player.getFace();
		_adena = player.getAdena();
		_coins = player.getItemCount(Config.BS_COIN_ITEM_ID);
	}
 
	@Override
	protected void writeImpl()
	{
		writeEx(ServerPacket.ExResponseBeautyRegistReset);
		writeQ(_adena);
		writeQ(_coins);
		writeD(_type);
		writeD(_result);
		writeD(_hairStyle);
		writeD(_face);
		writeD(_hairColor);
	}
}
 
 
package l2p.gameserver.network.serverpackets;
 
import l2p.gameserver.Config;
import l2p.gameserver.model.Player;
import l2p.gameserver.network.serverpackets.components.ServerPacket;
 
public class ExResponseResetList extends L2GameServerPacket
{
	private int _hairStyle;
	private int _hairColor;
	private int _face;
	private long _adena; 
	private long _coins;
 
	public ExResponseResetList(Player player)
	{
		_hairStyle = player.getHairStyle();
		_hairColor = player.getHairColor();
		_face = player.getFace();
		_adena = player.getAdena();
		_coins = player.getItemCount(Config.BS_COIN_ITEM_ID);
 
	}
 
	@Override
	protected void writeImpl()
	{
		writeEx(ServerPacket.ExResponseResetList);
		writeQ(_adena);
		writeQ(_coins);
		writeD(_hairStyle);
		writeD(_face);
		writeD(_hairColor);
	}
}
 
Code: Java
И опкоды этих пакетов:
 
	public static final int ExShowBeautyMenu = 0x13E;
	public static final int ExResponseBeautyList = 0x13F;
	public static final int ExResponseBeautyRegistReset = 0x140;
	public static final int ExResponseResetList = 0x141;
 
 
Code: Java

Ну вот собственно и все. Если я что и не описал или не пояснил - это в основном мелочи, до которых вы сами сможете без проблем додуматься.
Gaikotsu вне форума Ответить с цитированием
Непрочитано 13.09.2013, 18:44   #2
Аватар для ..Kirito..
Герой

По умолчанию Re: Beauty Shop

Ваще от души, благодарочка)
__________________
..Kirito.. вне форума Ответить с цитированием
Непрочитано 13.09.2013, 19:11   #3
Аватар для kloni1
Пользователь

По умолчанию Re: Beauty Shop

Большое спасибо будет что скопи пастить
__________________
Помог не забудь "Спасибо"
kloni1 вне форума Отправить сообщение для kloni1 с помощью ICQ Ответить с цитированием
Непрочитано 13.09.2013, 19:14   #4
Аватар для Gaikotsu
Герой

Автор темы (Топик Стартер) Re: Beauty Shop

ну дык реализация то достаточно примитивная - у меня самого реализация почти всего этого заняла где-то один день всего, ну и еще потом просто по мелочам корректировал возникавшие мелкие ньюансы.
Gaikotsu вне форума Ответить с цитированием
Непрочитано 13.09.2013, 20:39   #5
Аватар для elastic
Ooh, who's that handsome devil?

По умолчанию Re: Beauty Shop

Спасибо, дополнил имеющееся.
elastic вне форума Отправить сообщение для elastic с помощью ICQ Ответить с цитированием
Непрочитано 13.09.2013, 21:07   #6
Аватар для Zeratyl
Гвардии штабс-капитан N7 ═════ ★ ★ ★ ★ ★ ═════

По умолчанию Re: Beauty Shop

Приятно видеть такие темы среди тонн <...>, аки бальзам на душу. Месье, вы - настоящий джентльмен! Мое почтение.
Zeratyl вне форума Отправить сообщение для Zeratyl с помощью ICQ Отправить сообщение для Zeratyl с помощью AIM Отправить сообщение для Zeratyl с помощью MSN Отправить сообщение для Zeratyl с помощью Yahoo Отправить сообщение для Zeratyl с помощью Skype™ Ответить с цитированием
Непрочитано 13.09.2013, 21:33   #7
Супергерой

По умолчанию Re: Beauty Shop

И правда ТС заслуживает уважение! Как подметил Зератул, приятно видеть лучик света среди океана тьмы )

Вклад хотябы малой доли знаний с каждого из нас как сделал Гаикотсу, и вёрнет ЗГ к прежднему виду. Где было тонна мануалов гайдов каждую неделю где люди спрашивали друг друга и получали ответ.)) Хорошее было время)
OneThunder вне форума Ответить с цитированием
Непрочитано 15.09.2013, 16:40   #8
Пользователь

По умолчанию Re: Beauty Shop

good work ~
__________________
https://github.com/L2Miko
iquelite вне форума Отправить сообщение для iquelite с помощью MSN Ответить с цитированием
Непрочитано 17.09.2013, 14:06   #9
Аватар для Zubastic
ZG troll squad

По умолчанию Re: Beauty Shop

Кстати вопрос: зачем древо ифов вместо кейса?)
__________________
Zubastic вне форума Ответить с цитированием
Непрочитано 17.09.2013, 14:16   #10
Аватар для Ashe
Олдфаг

По умолчанию Re: Beauty Shop

Цитата:
Сообщение от Zubastic Посмотреть сообщение
Кстати вопрос: зачем древо ифов вместо кейса?)
Ты бы уточнил о чём говоришь.
__________________
Fortuna - non penis, in manus non recipe.
Ashe вне форума Ответить с цитированием
Ответ

Метки
beauty shop, lindvior, салон красоты


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

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

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

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

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Item Mall/Prime Shop что такое и с чем его едят? VISTALL Lineage II 152 18.02.2021 12:01
Item Mall / Prime Shop L2jServer Freya High Five Part 5 Blackmau5 Lineage II 9 15.12.2012 17:22
Импорты. MegaPvP Lineage II 3 28.03.2011 19:06
Адаптируем SQL BimBom Работа со скриптами 9 14.10.2009 15:14
GM SHOP Col + Adena graver Lineage II 11 24.07.2008 22:07


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

Вверх