Aller au contenu

Nouveau membre ?! Pense à te présenter pour accéder au contenu du forum !

New member ?! Introduce yourself to get access to the forum !

Messages recommandés

Bonjour,

 

J'ai décidé de refaire ce tutoriel

Aujourd'hui je vais vous expliquer comment ajouté l'option "détruire" lorsque vous voulez jeter un item. Ca va être assez long, mais facile si vous suivez bien le tutoriel.

 

Commençons

 

______________________________________________________________________

 

PRÉREQUIS

 

______________________________________________________________________

 

 

1.Des source Serveur

2.Des sources Client

3.Un client

 

______________________________________________________________________

 

1.SOURCE SERVEUR

 

______________________________________________________________________

 

 

Ouvrez votre "packet.h" et recherchez:

	HEADER_CG_ITEM_DROP2			= 20,

Ajoutez ceci juste en dessous:

	HEADER_CG_ITEM_DESTROY			= 21,

 

Recherchez maintenant:
 

typedef struct command_item_drop2
{
	BYTE 	header;
	TItemPos 	Cell;
	DWORD	gold;
	BYTE	count;
} TPacketCGItemDrop2;

Ajoutez ceci juste en dessous:

typedef struct command_item_destroy
{
	BYTE	header;
	TItemPos	Cell;
} TPacketCGItemDestroy;

 

Ouvrez maintenant le fichier packet_info.cpp et recherchez:

	Set(HEADER_CG_ITEM_DROP2, sizeof(TPacketCGItemDrop2), "ItemDrop2", true);

Ajoutez ceci juste en dessous:

	Set(HEADER_CG_ITEM_DESTROY, sizeof(TPacketCGItemDestroy), "ItemDestroy", true);

 

Ouvrez maintenant le fichier input_main.cpp et recherchez la fonction:

void CInputMain::ItemDrop2(LPCHARACTER ch, const char * data)

Ajoutez cette fonction juste après:

void CInputMain::ItemDestroy(LPCHARACTER ch, const char * data)
{
	struct command_item_destroy * pinfo = (struct command_item_destroy *) data;
	if (ch)
		ch->DestroyItem(pinfo->Cell);
}

Cherchez maintenant ceci:

		case HEADER_CG_ITEM_DROP2:
			if (!ch->IsObserverMode())
				ItemDrop2(ch, c_pData);
			break;

Et ajoutez:

		case HEADER_CG_ITEM_DESTROY:
			if (!ch->IsObserverMode())
				ItemDestroy(ch, c_pData);
			break;

 

Ouvrez maintenant le fichier char_item.cpp et recherchez la fonction:

bool CHARACTER::DropItem(TItemPos Cell, BYTE bCount)

Ajoutez cette fonction juste au-dessus:

bool CHARACTER::DestroyItem(TItemPos Cell)
{
	LPITEM item = NULL;
	if (!CanHandleItem())
	{
		if (NULL != DragonSoul_RefineWindow_GetOpener())
			ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°*È*âÀ» ¿¬ »óÅ¿¡¼*´Â ¾ÆÀÌÅÛÀ» ¿Å±æ ¼ö ¾ø½À´Ï´Ù."));
		return false;
	}
	if (IsDead())
		return false;
	if (!IsValidItemPosition(Cell) || !(item = GetItem(Cell)))
		return false;
	if (item->IsExchanging())
		return false;
	if (true == item->isLocked())
		return false;
	if (quest::CQuestManager::instance().GetPCForce(GetPlayerID())->IsRunning() == true)
		return false;
	if (item->GetCount() <= 0)
		return false;
	SyncQuickslot(QUICKSLOT_TYPE_ITEM, Cell.cell, 255);
		ITEM_MANAGER::instance().RemoveItem(item);
			ChatPacket(CHAT_TYPE_INFO, LC_TEXT("L'item %s est desormais detruit."), item->GetName());
		return true;
}

 

Ouvrez maintenant le fichier char.h et recherchez:

		bool			DropItem(TItemPos Cell,  BYTE bCount=0);

Ajoutez ceci juste au-dessus:

		bool			DestroyItem(TItemPos Cell);

 

Ouvrez maintenant le fichier input.h et recherchez:

		void		ItemDrop2(LPCHARACTER ch, const char * data);

Ajoutez ceci juste en dessous:

		void		ItemDestroy(LPCHARACTER ch, const char * data);

 

 

______________________________________________________________________

 

2. SOURCE CLIENT

 

______________________________________________________________________

 

 

 

Ouvrez le fichier packet.h et recherchez:

	HEADER_CG_ITEM_DROP2                        = 20,

Ajoutez ceci juste en dessous:

	HEADER_CG_ITEM_DESTROY						= 21,

Recherchez maintenant:

typedef struct command_item_drop2
{
    BYTE        header;
    TItemPos    pos;
    DWORD       gold;
    BYTE        count;
} TPacketCGItemDrop2;

Ajoutez ceci juste en dessous:

typedef struct command_item_destroy
{
	BYTE  header;
	TItemPos pos;
}TPacketCGItemDestroy;

 

Ouvrez maintenant le fichier PythonNetworkStreamPhaseGameItem.cpp et recherchez la fonction:

bool CPythonNetworkStream::SendItemDropPacketNew(TItemPos pos, DWORD elk, DWORD count)

Ajoutez cette fonction juste en dessous:

bool CPythonNetworkStream::SendItemDestroyPacket(TItemPos pos)
{
	if (!__CanActMainInstance())
		return true;
	TPacketCGItemDestroy itemDestroyPacket;
	itemDestroyPacket.header = HEADER_CG_ITEM_DESTROY;
	itemDestroyPacket.pos = pos;
	if (!Send(sizeof(itemDestroyPacket), &itemDestroyPacket))
	{
		Tracen("SendItemDestroyPacket Error");
		return false;
	}
	return SendSequence();
}

 

Ouvrez maintenant le fichier PythonNetworkStreamModule.cpp et recherchez la fonction:

PyObject* netSendItemDropPacket(PyObject* poSelf, PyObject* poArgs)

Ajoutez cette fonction juste en dessous:

PyObject* netSendItemDestroyPacket(PyObject* poSelf, PyObject* poArgs)
{
	TItemPos Cell;

	if (!PyTuple_GetInteger(poArgs, 0, &Cell.cell))
		return Py_BuildException();
	CPythonNetworkStream& rkNetStream = CPythonNetworkStream::Instance();
	rkNetStream.SendItemDestroyPacket(Cell);
	return Py_BuildNone();
}

Recherchez maintenant:

		{ "SendItemDropPacketNew",				netSendItemDropPacketNew,				METH_VARARGS },

Ajoutez ceci juste après:

		{ "SendItemDestroyPacket",				netSendItemDestroyPacket,				METH_VARARGS },

 

Ouvrez maintenant le fichier PythonNetworkStream.h et recherchez la fonction:

		bool SendItemDropPacketNew(TItemPos pos, DWORD elk, DWORD count);

Ajoutez ceci juste après:

		bool SendItemDestroyPacket(TItemPos pos);

 

 

______________________________________________________________________

 

3. PYTHON CLIENT

 

______________________________________________________________________

 

 

Ouvrez le fichier uicommon.py du pack root et recherchez la class:

class QuestionDialog(ui.ScriptWindow):

Juste après celle class, ajoutez la class suivante:

class QuestionDialogItem(ui.ScriptWindow):

	def __init__(self):
		ui.ScriptWindow.__init__(self)
		self.__CreateDialog()

	def __del__(self):
		ui.ScriptWindow.__del__(self)

	def __CreateDialog(self):
		pyScrLoader = ui.PythonScriptLoader()
		pyScrLoader.LoadScriptFile(self, "uiscript/questiondialogitem.py")

		self.board = self.GetChild("board")
		self.textLine = self.GetChild("message")
		self.acceptButton = self.GetChild("accept")
		self.destroyButton = self.GetChild("destroy")
		self.cancelButton = self.GetChild("cancel")

	def Open(self):
		self.SetCenterPosition()
		self.SetTop()
		self.Show()

	def Close(self):
		self.Hide()

	def SetWidth(self, width):
		height = self.GetHeight()
		self.SetSize(width, height)
		self.board.SetSize(width, height)
		self.SetCenterPosition()
		self.UpdateRect()

	def SAFE_SetAcceptEvent(self, event):
		self.acceptButton.SAFE_SetEvent(event)

	def SAFE_SetCancelEvent(self, event):
		self.cancelButton.SAFE_SetEvent(event)

	def SetAcceptEvent(self, event):
		self.acceptButton.SetEvent(event)

	def SetDestroyEvent(self, event):
		self.destroyButton.SetEvent(event)

	def SetCancelEvent(self, event):
		self.cancelButton.SetEvent(event)

	def SetText(self, text):
		self.textLine.SetText(text)

	def SetAcceptText(self, text):
		self.acceptButton.SetText(text)

	def SetCancelText(self, text):
		self.cancelButton.SetText(text)

	def OnPressEscapeKey(self):
		self.Close()
		return True

 

Ouvrez maintenant le fichier game.py et cherchez la def suivante:

def __DropItem(self, attachedType, attachedItemIndex, attachedItemSlotPos, attachedItemCount):

Recherchez ce bout de code dans la fonction (2x):

				itemDropQuestionDialog = uiCommon.QuestionDialog()

Remplacez par:

				itemDropQuestionDialog = uiCommon.QuestionDialogItem()

Toujours dans la même fonction, recherchez:

				itemDropQuestionDialog.SetAcceptEvent(lambda arg=True: self.RequestDropItem(arg))

Ajoutez ceci juste après:

				itemDropQuestionDialog.SetDestroyEvent(lambda arg=True: self.RequestDestroyItem(arg))

Recherchez maintenant la fonction:

	def	RequestDropItem(self, answer):

Ajoutez cette fonction juste après:

	def RequestDestroyItem(self, answer):
		if not self.itemDropQuestionDialog:
			return
		if answer:
			dropType = self.itemDropQuestionDialog.dropType
			dropNumber = self.itemDropQuestionDialog.dropNumber
			if player.SLOT_TYPE_INVENTORY == dropType:
				if dropNumber == player.ITEM_MONEY:
					return
				else:
					self.__SendDestroyItemPacket(dropNumber)
    
		self.itemDropQuestionDialog.Close()
		self.itemDropQuestionDialog = None
		constInfo.SET_ITEM_DROP_QUESTION_DIALOG_STATUS(0)

Recherchez ensuite la fonction:

	def __SendDropItemPacket(self, itemVNum, itemCount, itemInvenType = player.INVENTORY):

Et ajoutez celle-ci juste après:

	def __SendDestroyItemPacket(self, itemVNum, itemInvenType = player.INVENTORY):
		if uiPrivateShopBuilder.IsBuildingPrivateShop():
			chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.DROP_ITEM_FAILURE_PRIVATE_SHOP)
			return
		net.SendItemDestroyPacket(itemVNum)

 

Ouvrez maintenant le fichier locale_interface.txt et ajoutez ceci:

DESTROY	Destroy

Placez le fichier questiondialogitem.py dans votre pack uiscript !

Contenu Masqué !

    Donnez un like à l'auteur afin de pouvoir visualiser tout le contenu.

 

Screen du système:

 

194036DestroyItem.png

 

Voilà c'est fini !

 

Source du totoriel : .Avenue™ de Metin2Dev

Traduction: moi

 

Cordialement,

#Saw.

 

 

Modifié par #Saw

Partager ce message


Lien à poster
Partager sur d’autres sites

Edition du sujet : ajout du tag "metin2 source" et du préfixe "tutoriel".

Partager ce message


Lien à poster
Partager sur d’autres sites

Merci :D Ça serait cool que tu expliques le code aussi pour les petites têtes blondes :o Je l'aurais bien fait mais je peux plus éditer :( 

Partager ce message


Lien à poster
Partager sur d’autres sites

Note:

Pour ceux qui ont un bug avec l'inventaire après comme celui qui est venu me chercher pv :

 

Changer dans le code à ajouter dans le game.py :

constInfo.SET_ITEM_DROP_QUESTION_DIALOG_STATUS(0)

En :

constInfo.SET_ITEM_QUESTION_DIALOG_STATUS(0)

 

Bien cordialement.

Partager ce message


Lien à poster
Partager sur d’autres sites
Posté(e) (modifié)

Merci.

Edit: 

Contenu Masqué !

    Donnez un like à l'auteur afin de pouvoir visualiser tout le contenu.
e fichier : 

Contenu Masqué !

    Donnez un like à l'auteur afin de pouvoir visualiser tout le contenu.
 est vide, normal?

Modifié par Abass

Partager ce message


Lien à poster
Partager sur d’autres sites

Je confirme @#Saw le fichier est vide :/

Partager ce message


Lien à poster
Partager sur d’autres sites
Posté(e) (modifié)
import uiScriptLocale

window = {
	"name" : "QuestionDialog",
	"style" : ("movable", "float",),

	"x" : SCREEN_WIDTH/2 - 125,
	"y" : SCREEN_HEIGHT/2 - 52,

	"width" : 340,
	"height" : 105,

	"children" :
	(
		{
			"name" : "board",
			"type" : "board",

			"x" : 0,
			"y" : 0,

			"width" : 340,
			"height" : 105,

			"children" :
			(
				{
					"name" : "message",
					"type" : "text",

					"x" : 0,
					"y" : 38,

					"horizontal_align" : "center",
					"text" : uiScriptLocale.MESSAGE,

					"text_horizontal_align" : "center",
					"text_vertical_align" : "center",
				},
				{
					"name" : "accept",
					"type" : "button",

					"x" : -60,
					"y" : 63,

					"width" : 61,
					"height" : 21,

					"horizontal_align" : "center",
					"text" : uiScriptLocale.YES,

					"default_image" : "d:/ymir work/ui/public/middle_button_01.sub",
					"over_image" : "d:/ymir work/ui/public/middle_button_02.sub",
					"down_image" : "d:/ymir work/ui/public/middle_button_03.sub",
				},
				{
					"name" : "destroy",
					"type" : "button",

					"x" : 0,
					"y" : 63,

					"width" : 61,
					"height" : 21,

					"horizontal_align" : "center",
					"text" : uiScriptLocale.DESTROY,

					"default_image" : "d:/ymir work/ui/public/middle_button_01.sub",
					"over_image" : "d:/ymir work/ui/public/middle_button_02.sub",
					"down_image" : "d:/ymir work/ui/public/middle_button_03.sub",
				},
				{
					"name" : "cancel",
					"type" : "button",

					"x" : 60,
					"y" : 63,

					"width" : 61,
					"height" : 21,

					"horizontal_align" : "center",
					"text" : uiScriptLocale.NO,

					"default_image" : "d:/ymir work/ui/public/middle_button_01.sub",
					"over_image" : "d:/ymir work/ui/public/middle_button_02.sub",
					"down_image" : "d:/ymir work/ui/public/middle_button_03.sub",
				},
			),
		},
	),
}

Voilà voilà... ^^'

Et j'ajoute que pour ceux qui ne voudrait pas que les joueurs puissent détruire tous les items, vous pouvez simplement ajouter dans la fonction destroy :

	int pVnumTable[] = {vnum1, vnum2};
	
	for (int i = 0; i < _countof(pVnumTable); i++){
		if (pVnumTable[i] == item->GetVnum())
		{
			ChatPacket(CHAT_TYPE_INFO, LC_TEXT("TEXT"));
			return false;
		}
	}

 

Modifié par Takuma

Partager ce message


Lien à poster
Partager sur d’autres sites

Merci

Partager ce message


Lien à poster
Partager sur d’autres sites

Merci

Partager ce message


Lien à poster
Partager sur d’autres sites

×

Information importante

By using this site, you agree to our Conditions d’utilisation.