-
Posts
1504 -
Joined
-
Days Won
13 -
Feedback
100%
Content Type
Forums
Store
Third Party - Providers Directory
Feature Plan
Release Notes
Docs
Events
Everything posted by AZICKO
-
MySQL 8 is good, but... You need to modify some SQL queries (wrap some column names) in Metin2 sources to be compatible with MySQL 8, and password function.
-
Premium forum => Is read-only Deletion scheduled => 1 August 2022
-
Added Drafts forum in Temporary category This forum allows you to create draft topics without being visible to other members of the community.
-
This fixes several issues : Unable to destroy an item from the Dragon Soul Inventory A second dialog box appears asking for confirmation before destroying the item When you give yourself any stackable item and split the stack, you can drop the splitted stack in correct amounts, but you cannot destroy a splitted stack, you will always be forced to destroy the whole stack Client/Local_inc.h Add : #define M2_FEATURE_DESTROY_ITEM Client/Packet.h Add : #ifdef M2_FEATURE_DESTROY_ITEM HEADER_CG_ITEM_DESTROY = 21, #endif Add : #ifdef M2_FEATURE_DESTROY_ITEM typedef struct command_item_destroy { BYTE header; TItemPos pos; BYTE count; } TPacketCGItemDestroy; #endif Client/PythonApplicationModule.cpp Add : #ifdef M2_FEATURE_DESTROY_ITEM PyModule_AddIntConstant(poModule, "M2_FEATURE_DESTROY_ITEM", 1); #else PyModule_AddIntConstant(poModule, "M2_FEATURE_DESTROY_ITEM", 0); #endif Client/PythonNetworkStream.h Add : #ifdef M2_FEATURE_DESTROY_ITEM bool SendItemDestroyPacket(TItemPos pos, DWORD count); #endif Client/PythonNetworkStramModule.cpp Add : #ifdef M2_FEATURE_DESTROY_ITEM PyObject* netSendItemDestroyPacket(PyObject* poSelf, PyObject* poArgs) { TItemPos Cell; int count; switch (PyTuple_Size(poArgs)) { case 2: if (!PyTuple_GetInteger(poArgs, 0, &Cell.cell)) return Py_BuildException(); if (!PyTuple_GetInteger(poArgs, 1, &count)) return Py_BuildException(); break; case 3: if (!PyTuple_GetByte(poArgs, 0, &Cell.window_type)) return Py_BuildException(); if (!PyTuple_GetInteger(poArgs, 1, &Cell.cell)) return Py_BuildException(); if (!PyTuple_GetInteger(poArgs, 2, &count)) return Py_BuildException(); break; default: return Py_BuildException(); } CPythonNetworkStream& rkNetStream = CPythonNetworkStream::Instance(); rkNetStream.SendItemDestroyPacket(Cell, count); return Py_BuildNone(); } #endif Add : #ifdef M2_FEATURE_DESTROY_ITEM { "SendItemDestroyPacket", netSendItemDestroyPacket, METH_VARARGS }, #endif Client/PythonNetworkStreamPhaseGameItem.cpp Add : #ifdef M2_FEATURE_DESTROY_ITEM bool CPythonNetworkStream::SendItemDestroyPacket(TItemPos pos, DWORD count) { if (!__CanActMainInstance()) return true; TPacketCGItemDestroy itemDestroyPacket; itemDestroyPacket.header = HEADER_CG_ITEM_DESTROY; itemDestroyPacket.pos = pos; itemDestroyPacket.count = count; if (!Send(sizeof(itemDestroyPacket), &itemDestroyPacket)) { Tracen("SendItemDestroyPacket Error"); return false; } return SendSequence(); } #endif Server/service.h Add : #define M2_FEATURE_DESTROY_ITEM Server/char_item.cpp Add : #ifdef M2_FEATURE_DESTROY_ITEM bool CHARACTER::DestroyItem(TItemPos Cell, BYTE bCount) { 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; if (bCount == 0 || bCount > item->GetCount()) bCount = item->GetCount(); SyncQuickslot(QUICKSLOT_TYPE_ITEM, Cell.cell, 255); if (bCount == item->GetCount()) { item->RemoveFromCharacter(); } else { if (bCount == 0) { if (test_server) sys_log(0, "[DROP_ITEM] drop item count == 0"); return false; } item->SetCount(item->GetCount() - bCount); ITEM_MANAGER::instance().FlushDelayedSave(item); } ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You destroyed: %d x %s."), bCount, item->GetName()); return true; } #endif Server/input.h Add : #ifdef M2_FEATURE_DESTROY_ITEM void ItemDestroy(LPCHARACTER ch, const char* data); #endif Server/char.h Add : #ifdef M2_FEATURE_DESTROY_ITEM bool DestroyItem(TItemPos Cell, BYTE bCount = 0); #endif Server/input_main.cpp Add : #ifdef M2_FEATURE_DESTROY_ITEM case HEADER_CG_ITEM_DESTROY: if (!ch->IsObserverMode()) ItemDestroy(ch, c_pData); break; #endif Add : #ifdef M2_FEATURE_DESTROY_ITEM void CInputMain::ItemDestroy(LPCHARACTER ch, const char* data) { struct command_item_destroy* pinfo = (struct command_item_destroy*)data; if (ch) ch->DestroyItem(pinfo->Cell, pinfo->count); } #endif Server/packet.h Add : #ifdef M2_FEATURE_DESTROY_ITEM HEADER_CG_ITEM_DESTROY = 21, #endif Add : #ifdef M2_FEATURE_DESTROY_ITEM typedef struct command_item_destroy { BYTE header; TItemPos Cell; BYTE count; } TPacketCGItemDestroy; #endif Server/packet_info.cpp Add : #ifdef M2_FEATURE_DESTROY_ITEM Set(HEADER_CG_ITEM_DESTROY, sizeof(TPacketCGItemDestroy), "ItemDestroy", true); #endif Client/game.py Add : if app.M2_FEATURE_DESTROY_ITEM: def __SendDestroyItemPacket(self, itemVNum, itemCount, itemInvenType = player.INVENTORY): if uiPrivateShopBuilder.IsBuildingPrivateShop(): chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.DROP_ITEM_FAILURE_PRIVATE_SHOP) return net.SendItemDestroyPacket(itemInvenType, itemVNum, itemCount) return Add : if app.M2_FEATURE_DESTROY_ITEM: def RequestDestroyItem(self, answer): if not self.itemDropQuestionDialog: return if answer: ## Question Text questionText = "Are you really sure?" ## Dialog itemDropQuestionDialog2 = uiCommon.QuestionDialog() itemDropQuestionDialog2.SetText(questionText) itemDropQuestionDialog2.SetAcceptEvent(lambda arg=True: self.RequestDestroyItemConfirm(arg)) itemDropQuestionDialog2.SetCancelEvent(lambda arg=False: self.RequestDestroyItemConfirm(arg)) itemDropQuestionDialog2.Open() itemDropQuestionDialog2.dropType = self.itemDropQuestionDialog.dropType itemDropQuestionDialog2.dropNumber = self.itemDropQuestionDialog.dropNumber itemDropQuestionDialog2.dropCount = self.itemDropQuestionDialog.dropCount self.itemDropQuestionDialog2 = itemDropQuestionDialog2 self.itemDropQuestionDialog.Close() self.itemDropQuestionDialog = None constInfo.SET_ITEM_QUESTION_DIALOG_STATUS(0) def RequestDestroyItemConfirm(self, answer): if not self.itemDropQuestionDialog2: return if answer: dropType = self.itemDropQuestionDialog2.dropType dropNumber = self.itemDropQuestionDialog2.dropNumber dropCount = self.itemDropQuestionDialog2.dropCount if player.SLOT_TYPE_INVENTORY == dropType: if dropNumber == player.ITEM_MONEY: return else: self.__SendDestroyItemPacket(dropNumber, dropCount) elif player.SLOT_TYPE_DRAGON_SOUL_INVENTORY == dropType: self.__SendDestroyItemPacket(dropNumber, dropCount, player.DRAGON_SOUL_INVENTORY) self.itemDropQuestionDialog2.Close() self.itemDropQuestionDialog2 = None constInfo.SET_ITEM_QUESTION_DIALOG_STATUS(0) Full __DropItem : def __DropItem(self, attachedType, attachedItemIndex, attachedItemSlotPos, attachedItemCount): # PRIVATESHOP_DISABLE_ITEM_DROP - 개인상점 열고 있는 동안 아이템 버림 방지 if uiPrivateShopBuilder.IsBuildingPrivateShop(): chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.DROP_ITEM_FAILURE_PRIVATE_SHOP) return # END_OF_PRIVATESHOP_DISABLE_ITEM_DROP if player.SLOT_TYPE_INVENTORY == attachedType and player.IsEquipmentSlot(attachedItemSlotPos): self.stream.popupWindow.Close() self.stream.popupWindow.Open(localeInfo.DROP_ITEM_FAILURE_EQUIP_ITEM, 0, localeInfo.UI_OK) else: if player.SLOT_TYPE_INVENTORY == attachedType: dropItemIndex = player.GetItemIndex(attachedItemSlotPos) item.SelectItem(dropItemIndex) dropItemName = item.GetItemName() ## Question Text questionText = localeInfo.HOW_MANY_ITEM_DO_YOU_DROP(dropItemName, attachedItemCount) ## Dialog if app.M2_FEATURE_DESTROY_ITEM: itemDropQuestionDialog = uiCommon.QuestionDialogItem() else: itemDropQuestionDialog = uiCommon.QuestionDialog() itemDropQuestionDialog.SetText(questionText) itemDropQuestionDialog.SetAcceptEvent(lambda arg=True: self.RequestDropItem(arg)) if app.M2_FEATURE_DESTROY_ITEM: itemDropQuestionDialog.SetDestroyEvent(lambda arg=TRUE: self.RequestDestroyItem(arg)) itemDropQuestionDialog.SetCancelEvent(lambda arg=False: self.RequestDropItem(arg)) itemDropQuestionDialog.Open() itemDropQuestionDialog.dropType = attachedType itemDropQuestionDialog.dropNumber = attachedItemSlotPos itemDropQuestionDialog.dropCount = attachedItemCount self.itemDropQuestionDialog = itemDropQuestionDialog constInfo.SET_ITEM_QUESTION_DIALOG_STATUS(1) elif player.SLOT_TYPE_DRAGON_SOUL_INVENTORY == attachedType: dropItemIndex = player.GetItemIndex(player.DRAGON_SOUL_INVENTORY, attachedItemSlotPos) item.SelectItem(dropItemIndex) dropItemName = item.GetItemName() ## Question Text questionText = localeInfo.HOW_MANY_ITEM_DO_YOU_DROP(dropItemName, attachedItemCount) ## Dialog if app.M2_FEATURE_DESTROY_ITEM: itemDropQuestionDialog = uiCommon.QuestionDialogItem() else: itemDropQuestionDialog = uiCommon.QuestionDialog() itemDropQuestionDialog.SetText(questionText) itemDropQuestionDialog.SetAcceptEvent(lambda arg=True: self.RequestDropItem(arg)) if app.M2_FEATURE_DESTROY_ITEM: itemDropQuestionDialog.SetDestroyEvent(lambda arg=TRUE: self.RequestDestroyItem(arg)) itemDropQuestionDialog.SetCancelEvent(lambda arg=False: self.RequestDropItem(arg)) itemDropQuestionDialog.Open() itemDropQuestionDialog.dropType = attachedType itemDropQuestionDialog.dropNumber = attachedItemSlotPos itemDropQuestionDialog.dropCount = attachedItemCount self.itemDropQuestionDialog = itemDropQuestionDialog constInfo.SET_ITEM_QUESTION_DIALOG_STATUS(1)
-
You should modify the Alpha channel of the DDS file.
-
Block item swap when shopping or when exchanging
AZICKO replied to ReFresh's topic in Community Support - Questions & Answers
I had suggested the first method, then deleted my answer. With the first method, I can no longer sell items to an NPC. -
I did this, I think we can do even more optimized. I tried : ACMD(do_emotion_allow) { if ( ch->GetArena() ) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("´ë·ÃÀå¿¡¼ »ç¿ëÇÏ½Ç ¼ö ¾ø½À´Ï´Ù.")); return; } char arg1[256]; one_argument(argument, arg1, sizeof(arg1)); if (!*arg1) return; uint32_t val = 0; str_to_number(val, arg1); #ifdef M2_FEATURE_NOTICE_EMOTION LPCHARACTER tch = CHARACTER_MANAGER::instance().Find(val); if (tch) { bool bFrom = !(s_emotion_set.find(std::make_pair(ch->GetVID(), val)) == s_emotion_set.end()); bool bTo = !(s_emotion_set.find(std::make_pair(val, ch->GetVID())) == s_emotion_set.end()); if (bFrom && bTo) { ch->ChatPacket(CHAT_TYPE_INFO, "You are currently sharing emotions with your partner! <3"); return; } if (!bFrom && bTo) { s_emotion_set.insert(std::make_pair(ch->GetVID(), val)); ch->ChatPacket(CHAT_TYPE_INFO, "You allowed emotions with %s.", tch->GetName()); tch->ChatPacket(CHAT_TYPE_INFO, "%s allowed to share emotions.", ch->GetName()); return; } if (bFrom) { ch->ChatPacket(CHAT_TYPE_INFO, "You have already asked to share emotions with %s...", tch->GetName()); ch->ChatPacket(CHAT_TYPE_INFO, "Don't anger your partner and be patient!"); return; } else { s_emotion_set.insert(std::make_pair(ch->GetVID(), val)); ch->ChatPacket(CHAT_TYPE_INFO, "You asked to share emotions with %s.", tch->GetName()); tch->ChatPacket(CHAT_TYPE_INFO, "%s requested to share emotions with you.", ch->GetName()); return; } } #else s_emotion_set.insert(std::make_pair(ch->GetVID(), val)); #endif }
-
C++ Version In: cmd_emotion.cpp (game source) Add: #include "config.h" Find: ACMD(do_emotion_allow) { [...] } Replace like this: ACMD(do_emotion_allow) { if ( ch->GetArena() ) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("´ë·ÃÀå¿¡¼ »ç¿ëÇÏ½Ç ¼ö ¾ø½À´Ï´Ù.")); return; } #ifdef M2_FEATURE_NOTICE_EMOTION if (thecore_heart->pulse - (int32_t)ch->GetLastShoutPulse() < passes_per_sec * 15) { ch->ChatPacket(CHAT_TYPE_INFO, "Please, stop spam!"); return; } ch->SetLastShoutPulse(thecore_heart->pulse); #endif char arg1[256]; one_argument(argument, arg1, sizeof(arg1)); if (!*arg1) return; uint32_t val = 0; str_to_number(val, arg1); s_emotion_set.insert(std::make_pair(ch->GetVID(), val)); #ifdef M2_FEATURE_NOTICE_EMOTION LPCHARACTER tch = CHARACTER_MANAGER::instance().Find(val); if (tch) { tch->ChatPacket(CHAT_TYPE_INFO, "%s requested the use of emotions with you %s", ch->GetName(), tch->GetName()); } #endif } And add define in your service.h or similar: #define M2_FEATURE_NOTICE_EMOTION
-
IP Board Upgrade IPS 4.7.0 (Stable Build) Hide Link And Code Upgrade to 3.3.3 (From 3.1.0)
-
Horse and Pet right click bug
AZICKO replied to forum80's topic in Community Support - Questions & Answers
How? -
Duplicate posts (warns, topics, PM's...) are resolved 2FA re-enabled IP Board Upgrade IPS 4.7.0 Beta 10 (Dev Build)
-
Migrating NGINX to Apache2 + FastCGI with PHP 8.1.7 (It should be temporary) @ Syreldar Kekw
-
the backup link is not expired
-
link is up
-
Check level of party members
AZICKO replied to Doose's topic in Community Support - Questions & Answers
Known bug, sorry.. -
Migration to a new server completed... DNS zone update in progress... PHP 7.4.26 => PHP 8.1.7 MariaDB 10.5.12 => MariaDB 10.5.15 IPS 4.6.12.1 (Stable Build) => IPS 4.7.0 (Dev Build) Websites Server metin2.dev metin2dev.org funky-emu.net Cache is rebuilding, all maintenance tasks are running...
-
Migration to a new server completed... DNS zone update in progress... PHP 7.3 => PHP 8.1 Storage Server img.funky-emu.net dl.funky-emu.net img.metin2.dev metin2.download metin2.top top-metin2.org top-dofus.fr download.dofedex.com funky-emulation.com
-
Core X → Top Metin2 & Metin2 Download → Changelogs
AZICKO replied to AZICKO's topic in Announcements
Migration to a new server completed... DNS zone update in progress... PHP 7.3 => PHP 8.1 -
Core X → Top Metin2 & Metin2 Download → Changelogs
AZICKO replied to AZICKO's topic in Announcements
Migration to a new server completed... DNS zone update in progress... PHP 7.3 => PHP 8.1 -
Oh yes, Mega Link... @GotThisShx The Metin2 Download link contains all the files.
-
-
Thx, Metin2 Downlaod link is ok now
-
Board Discord ID custom profile field removed I thought we could give a link directly to a Discord account (without knowing the full Discord Tag) This only works if we are friends with the member Custom profile field replaced by Discord Tag (Renamed to Discord) Enabled Combined Fluid View in Releases and 3D Models categories => You need to look specifically at these categories to see the difference (Test) Added a monthly donation goal Marketplace Discord custom field has been updated The field now requires the Discord Tag and Discord ID is no longer required I thought we could give a link directly to a Discord account (without knowing the full Discord Tag) This only works if we are friends with the member Massive update in the database The number of reviews has been added on the list of topics Desktop => There is now an alignment on the list of topics (Fluent Design Only)