Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 05/27/20 in all areas

  1. M2 Download Center Download Here ( Internal ) Download Here ( Latest Version ) This WE is a version compiled directly by me which includes infinite fixes and features. It's certain that you won't longer use the worldeditor_en! To make it simple, I wrote all the details about this feature and the common WE inside the relative config file: (called WorldEditorRemix.ini) ; Info: ; -) 100% translated ; -) granny2.11 ; -) F6 as Insert alternative ; -) many default features not present inside the worldeditor_en (probably, that binary was taken out from an SVN long time ago and resource hacked) such as Ins for all regions and skyboxes ; -) WASD UPLEFTDOWNRIGHT to move around (+asynchronous diagonally movements) ; -) UP-LEFT-DOWN-RIGHT to move around*10 (+asynchronous diagonally movements) ; -) config file for few things ; Output options by default ; few others such as default WASD movement ; whether or not Insert should let you go where you were before the press ; no MAI dump when saving atlas ; whether or not DevIL should compress and remove alpha from minimap.dds ; whether or not loading .mdatr building heights ; default textureset when creating maps ; overlapped tabs ; other stuff ; -) several bugfixes ; default title app name ; attempting to write to an empty textureset name when creating new maps ; ViewRadius doubled every load&save ; shadowmap.dds creation ; assert when saving atlas ; crash when adjusting height ; many buffer under/overflows ; *.mdc collision data saving (for game_test) ; not checking output options when loading maps ; water brush waterid bug (the id was increased until 256 each time the function was called; now it's based on the water height just like it should be) ; init texture map reload map crash and last 2px always blank ; square shape even for up/down height brushes ; add textureset texture button (+multiselection) ; remove textureset texture feature (just selecting a texture from the list and pressing DELETE) ; creation of empty textureset with index -1 (changed to 0) ; change baseposition button ; misspelled stuff ; skybox bottom image (nb: you also need a fixed launcher for this) ; removed boring CTRL requirement (to move the camera) when editing daylight/attr ; fixed refresh texture imagebox onKey pressing the down/up keys (like when onClicking them) ; fixed TextureSet file creation if not existing ; fixed new wolfman motion event handling ; fixed crash when editing animation attack bones and 00010.gr2 was missing ; fixed locale/ymir/mob_proto load (it autodetects the most common structures) and <map>/regen.txt load/save ; fixed ./group.txt load ; fixed load/save/edit <map>/regen.txt (very nice for "m" regens, untested for "g") ; load from PACK is available if pack/property is present! Be sure pack/Index exists! ; fixed multi-object selection crash ; fixed crash when previewing a missing texture ; fixed not clearing of old environment (e.g. skybox) when switching maps ; fixed not creating property folders in root tree (object tab) ; fixed object attachment in Model Tab ; fixed newly particles names in Effect Tab ; fixed crash when saving a .mse script with no mesh model ; fixed crash when inserting a lower gradient ; -) created new TextureSet field when creating new maps ; -) created new Change/Delete Texture buttons when double-clicking a texture ; -) created Background Music playback and Shadow Recalculate buttons ; -) created water height "set 0z", "+1z", "-1z" buttons ; -) server_attr generator ; -) every crash will generate a logs/WorldEditorRemix_{target}_{date}.dmp file useful for debugging ; -) implemented a "water path" mapsettings option (the launcher requires additional code) ; -) implemented a "wind strength" msenv option (the launcher requires additional code) ; -) the "encrypt data" feature does nothing (unimplemented) ; Note: ; 0) there are no regressions in this version! a bug here means it'd also be present in older WE versions too! ; 1) the shadow output option is tricky: when UpdateUI is called, shadows are hidden although the check is pressed (i implemented the shadow recalculate function for that) #fixed since v11 ; 2) the bgm player requires /miles and the fadein/out doesn't work until you load the map ; 3) the adjusting height button works only if mdatr height is detected ; 4) the Debug version is laggy when working on maps such as n_flame_dungeon and n_ice_dungeon (by default, because SphereRadius are intensively checked in SphereLib\spherepack.h) ; 5) if you load a map, the script panels (where you load .msa et similia) will have the camera perspective a little fucked up (0z instead of -32767z or 0x 0y -163,94z) ; 6) few tree objects are not movable and/or highlightable after placed on the ground and their selection is invisible (you can still delete 'em) ; trick: draw a square selecting a normal building and 'em, then move the building and you'll see all of 'em will be moved! ; 7) the server_attr generator will clean all the unused flags! attr[idx]&=~0xFFFFFFF8; ; 8) you can read files from pack/Index 'n stuff but be aware that Property will not be considered! #fixed since v15 ; 9) the MonsterAreaInfo features are laggy and buggy as fuck ; 10) even though you can select many textures at once (using ctrl+click on textureset list; for brushing or initializing a base texture), you can't delete more than one at the same time ; 11) the .mdatr height is tricky; if you move a building, the height will not be refreshed until you put a new building or whatever you want to trigger the update event ; 12) by default, the worldeditor tries to render only the first 8 terrain textures of a 32x32px region (nb: a 1x1 map is a 256x256 px region) ; 13) the minimap rendering cannot catch the buildings/trees inside the first 2x2 regions due a ymir cache fault and you need to set the camera to "see" them ; 14) when the textureset, environment, etc load fails, the old filename still remains loaded ; 15) the attr flag "3" (three) has no implementation, so don't use it! ; 16) load from PACK doesn't load texturesets from files for first (if they are already in pack/), and the object placer's object list will remain empty because it takes the list from property/ (and not from pack/property) ; 17) to save the regen.txt you press CTRL+S ; 18) if you enable the wireframe (f4) when on Attr Tab, you see the terrain all white ; 19) the water brush disappears when the camera renders the waterwheel small/big effect ; 20) the monster area info goes under ground if you're outside the relative sectree ; 21) the full skybox may be displayed only after the top picture has been added (if the other textures have already been inserted) ; 22) the slider in the Attr Tab is something like "16 photoshop layers" in which you can split your attrs; not so helpful and quite confusing sometimes ; 23) the fixed model - object attachment attaches static objects (hairs'skeleton will not mirror the playing animation) ; 24) in environment tab, if you insert lower gradients, you may end up with an out of range crash #fixed since v30 ; 25) brushes working out-of-screen/map-range may affect random terrain places ; TODO: ; A) look at more than 8 textures for region -> DONE ; B) create a shortcut to fix the #5 note -> DONE ; C) disable the radius <= GetRadius()+0.0001f check to fix the #4 note -> REJECTED ; the worldeditor_en calls this assert and, if ignored, the lag ceases to exist (this will not occur in source version) ; at least, if the release version is not a problem for you, use that in those few cases when .mse are abused and try to kill the debug one ; D) translation in more languages other than english -> REJECTED ; english should be enough! ; E) alternative path for d: -> REJECTED ; you can mount d as a subpath of c like this: ; subst d: "c:\mt2stuff" ; F) need to fix note #19 #25 -> TODO [shortcuts] ; ### SHORTCUTS ; # ESC(ape) Clean cursor ; # Canc(el|Delete) Delete stuff such as selected buildings ; # Ctrl+S Save map ; # Ins(ert) or F6 Save shadowmap|minimap.dds ; # F3 BoundGrid Show/Hide ; # F4 Render UI Show/Hide ; # F11 WireFrame Show/Hide ; # R Reload Texture ; # Z and X Decrease/Increase Texture Splat by 0.1 ; # CapsLock Show GaussianCubic effect if shadows are displayed ; # L-Shift+1-6 Show TextureCountThreshold flags (&2-7) as colors on the ground ; # L-Shift+8 Set Max Showable texture to 8 (de-fix note 12) ; # L-Shift+0 Set Max Showable texture to 255 (fix note 12) ; # H Refresh MDATR Heights (useful when you move an object) (fix note 11) ; # Y Set Perspective as default (fix note 5) ; # T Set the Camera to catch all the object on the screen (w/a note 13) then you'll be ready to press Insert/F6 ; # DO NOT HAVE AN OBJECT SELECTED WHEN USING THOSE SHORTCUTS (MW1-7) ; # MouseWheel+1 move cursor x rotation ; # MouseWheel+2 move cursor y rotation ; # MouseWheel+3 move cursor z rotation ; # MouseWheel+4 move cursor height base (1x) ; # MouseWheel+5 move cursor height base (0.5x) ; # MouseWheel+6 move cursor height base (0.05x) ; # MouseWheel+7 move cursor ambience scale (1x) ; # MouseWheel+Q move selected object height base (1x) ; # MouseWheel+9 move selected object x position (1x) (+asyncronous) ; # MouseWheel+0 move selected object y position (1x) (+asyncronous) ; # MW+RSHIFT+9|0 as above but *10x (+asyncronous) ; # MW+RCONTROL+9|0 as above but *100x (+asyncronous) ; # MouseLeft Insert Objects ; # MouseRight Move camera (it could require CTRL too) ; # SPACE Start move/selected animation in Object/Effect/Fly CB ; # ESC Stop animation in Effect/Fly CB [config] ; ### CONFIG OPTIONS VIEW_CHAR_OUTPUT_BY_DEFAULT = 1 VIEW_SHADOW_OUTPUT_BY_DEFAULT = 1 VIEW_WATER_OUTPUT_BY_DEFAULT = 1 ; WINDOW_HEIGHT_SIZE = 1080 ; WINDOW_WIDTH_SIZE = 1920 WINDOW_FOV_SIZE = 45 ; #100 = 1px (minimal px movement when pressing WASD) WASD_MINIMAL_MOVE = 100 ; came back from where you were before pressing Insert/F6 NO_GOTO_AFTER_INSERT = 1 ; disable MAI dumps when saving atlas and/or pressing Insert/F6 NOMAI_ATLAS_DUMP = 1 ; disable minimap.dds alpha saving and enable compression NOMINIMAP_RAWALPHA = 1 ; enable .mdatr height collision loading when moving on buildings or adjusting terrain DETECT_MDATR_HEIGHT = 1 ; disable fog when loading maps NOFOG_ONMAPLOAD = 1 ; refresh all checkbox configurations when loading maps 'n stuff REFRESHALL_ONUPDATEUI = 0 ; set a default mapname prefix when creating new maps ("" to disable) NEW_MAP_MAPNAME_PREFIX = "metin2_map_" ; display a default textureset when creating new maps ("" to disable) ; note: it loads the filepath if exists, otherwise it will create an empty textureset file NEWMAP_TEXTURESETLOADPATH = "textureset\metin2_a1.txt" ; create a default textureset as "textureset/{mapname}.txt" ; note: this option is not considered if NEWMAP_TEXTURESETLOADPATH is not empty. [before v24] ; note: this option is not considered if the TextureSet path input is not empty when creating a new map [since v24] NEWMAP_TEXTURESETSAVEASMAPNAME = 1 ; remove the weird attr flags from the generated server_attr SERVERATTR_REMOVE_WEIRD_FLAGS = 1 ; show diffuse lighting to object VIEW_OBJECT_LIGHTING = 1 ; path of mob_proto used for regen MOB_PROTO_PATH = "locale/ymir/mob_proto" ; select monster area info checkbox at startup VIEW_MONSTER_AREA_INFO = 0 ; brush cursor / object selection color RGB float between 0.0 to 1.0 (default: green -> 0 1 0) RENDER_CURSOR_COLOR_R = 0.0 RENDER_CURSOR_COLOR_G = 1.0 RENDER_CURSOR_COLOR_B = 0.0 Download: [Hidden Content] How To Map: This release will not cover this part. Look at CryPrime`s tutorials to understand how to do it. About the ServerAttr Generator: (since v14) This is a beta function but it should work fine. I tested it on gm_guild_build (1x1), metin2_map_a1 (4x5), metin2_map_trent (2x2), metin2_n_snowm_01 (6x6) and the result was the same as the blackyuko map editor. (I use a different lzo version and I clean deprecated and useless flags, so the size is different from this last one but the "final image" will be the same; using game_test to fix his server_attr will let mine and his perfectly equal byte per byte) I also give you the source code of my server_attr generator function. CLICK A server_attr file is based on all the attr.atr files merged into a one raw RGBA image and each one scaled from 256x256 to 512x512. After that, the image will be splitted into sectors of 128x128 px and each one compressed using lzo compression. The server_attr header is composed by the size of the map*4. (e.g. a 4x4 will have a 16x16 size with 256 sectors inside) (gj ymir CLICK) An uncompressed server_attr sector is just like this: CLICK (the sub 4 byte header is the size returned by the LzoCompress which indicates how much the compressed sector data are large) Each attr.atr is just like this: CLICK (the header is composed of 6 byte in total: 3 WORDs respectively for version, width and height; they are always 2634, 1, 1 so don't bother about it) A single attr.atr scaled from 256x256 to 512x512 will be just like this: CLICK You can use the game_test (from source) to perform few tasks like: Create a server_attr from a .mcd file (I won't suggest it) a <collision data filename> <map directory> Regenerate an old server_attr to server_attr.new using the current lzo compression and cleaning useless flag CLICK c <filename> Other stuff such as b to create a character instance or q to quit About the SkyBox Bottom pic fix: (since v21) Both metin2launch.exe and worldeditor.exe should be edited to see the bottom pic of the skybox. Ymir messed up the code wrongly flipping the bottom image. Open ./Srcs/Client/EterLib/SkyBox.cpp and replace: ////// Face 5: BOTTOM v3QuadPoints[0] = D3DXVECTOR3(1.0f, -1.0f, -1.0f); v3QuadPoints[1] = D3DXVECTOR3(1.0f, 1.0f, -1.0f); v3QuadPoints[2] = D3DXVECTOR3(-1.0f, -1.0f, -1.0f); v3QuadPoints[3] = D3DXVECTOR3(-1.0f, 1.0f, -1.0f); with: ////// Face 5: BOTTOM v3QuadPoints[0] = D3DXVECTOR3(1.0f, 1.0f, -1.0f); v3QuadPoints[1] = D3DXVECTOR3(1.0f, -1.0f, -1.0f); v3QuadPoints[2] = D3DXVECTOR3(-1.0f, 1.0f, -1.0f); v3QuadPoints[3] = D3DXVECTOR3(-1.0f, -1.0f, -1.0f); then recompile. Credits:
    2 points
  2. Download Metin2 Download Hi, I did not find a share with the Sources of Metin2... I share the sources with you today ! Kraizy sources with all branches of development. External Link : Mega or Go Sincerly, ASIKOO
    2 points
  3. M2 Download Center Download Here ( Internal ) Hi there Devs, I successfully extended the maximum number of items in a stack, so I'd like to share it. Originally the type of the "count" variables are "BYTE", so the maximum number only 255. I changed this to "WORD" (unsigned short), so now its about 60k. client packet.h Search for this: typedef struct command_item_drop2 then replace this in the struct: BYTE count; to this: WORD count; Then search for this: typedef struct command_item_move then replace this in the struct: BYTE num; To this: WORD num; Search for this: typedef struct SShopItemTable then replace this in the struct: BYTE count; to this: WORD count; Search for this: typedef struct packet_set_item2 then replace this in the struct: BYTE count; to this: WORD count; Then search for this: typedef struct packet_update_item then replace this in the struct: BYTE count; to this: WORD count; Then search for this: typedef struct SEquipmentItemSet replace this: BYTE count; to this: WORD count; PythonNetworkPhaseGame.cpp->RecvExchangePacket function Replace this: CPythonExchange::Instance().SetItemToSelf(iSlotIndex, exchange_packet.arg1, (BYTE) exchange_packet.arg3); To this: CPythonExchange::Instance().SetItemToSelf(iSlotIndex, exchange_packet.arg1, (WORD) exchange_packet.arg3); and this: CPythonExchange::Instance().SetItemToTarget(iSlotIndex, exchange_packet.arg1, (BYTE) exchange_packet.arg3); to this: CPythonExchange::Instance().SetItemToTarget(iSlotIndex, exchange_packet.arg1, (WORD) exchange_packet.arg3); pythonexchange.cpp: Replace this: BYTE CPythonExchange::GetItemCountFromTarget(BYTE pos) With this: WORD CPythonExchange::GetItemCountFromTarget(BYTE pos) Then this: BYTE CPythonExchange::GetItemCountFromSelf(BYTE pos) With this: WORD CPythonExchange::GetItemCountFromSelf(BYTE pos) And this: void CPythonExchange::SetItemToTarget(DWORD pos, DWORD vnum, BYTE count) With this: void CPythonExchange::SetItemToTarget(DWORD pos, DWORD vnum, WORD count) And then this: void CPythonExchange::SetItemToSelf(DWORD pos, DWORD vnum, BYTE count) With this: void CPythonExchange::SetItemToSelf(DWORD pos, DWORD vnum, WORD count) pythonexchange.h Replace this ones: BYTE GetItemCountFromTarget(BYTE pos); BYTE GetItemCountFromSelf(BYTE pos); void SetItemToTarget(DWORD pos, DWORD vnum, BYTE count); void SetItemToSelf(DWORD pos, DWORD vnum, BYTE count); BYTE item_count[EXCHANGE_ITEM_MAX_NUM]; To this: WORD GetItemCountFromTarget(BYTE pos); WORD GetItemCountFromSelf(BYTE pos); void SetItemToTarget(DWORD pos, DWORD vnum, WORD count); void SetItemToSelf(DWORD pos, DWORD vnum, WORD count); WORD item_count[EXCHANGE_ITEM_MAX_NUM]; PythonNetworkStreamPhaseGameItem.cpp Replace the whole function: bool CPythonNetworkStream::SendShopSellPacketNew With this: typedef struct fckOFF { BYTE bySlot; WORD byCount; } TfckOFF; bool CPythonNetworkStream::SendShopSellPacketNew(BYTE bySlot, WORD byCount) { if (!__CanActMainInstance()) return true; TPacketCGShop PacketShop; PacketShop.header = HEADER_CG_SHOP; PacketShop.subheader = SHOP_SUBHEADER_CG_SELL2; TfckOFF second; second.byCount = byCount; second.bySlot = bySlot; if (!Send(sizeof(TPacketCGShop), &PacketShop)) { Tracef("SendShopSellPacket Error\n"); return false; } if (!Send(sizeof(TfckOFF), &second)) { Tracef("SendShopAddSellPacket Error\n"); return false; } /*if (!Send(sizeof(WORD), &byCount)) { Tracef("SendShopAddSellPacket Error\n"); return false; }*/ Tracef(" SendShopSellPacketNew(bySlot=%d, byCount=%u)\n", bySlot, byCount); return SendSequence(); } Then replace this: bool CPythonNetworkStream::SendItemMovePacket(TItemPos pos, TItemPos change_pos, BYTE num) bool CPythonNetworkStream::SendSafeBoxItemMovePacket(BYTE bySourcePos, BYTE byTargetPos, BYTE byCount) To this: bool CPythonNetworkStream::SendItemMovePacket(TItemPos pos, TItemPos change_pos, WORD num) bool CPythonNetworkStream::SendSafeBoxItemMovePacket(BYTE bySourcePos, BYTE byTargetPos, WORD byCount) pythonplayermodule.cpp Replace the whole function: PyObject * playerSetItemCount(PyObject* poSelf, PyObject* poArgs) With this: PyObject * playerSetItemCount(PyObject* poSelf, PyObject* poArgs) { switch (PyTuple_Size(poArgs)) { case 2: { int iSlotIndex; if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) return Py_BuildException(); WORD wCount; if (!PyTuple_GetInteger(poArgs, 1, &wCount)) return Py_BuildException(); if (0 == wCount) return Py_BuildException(); CPythonPlayer::Instance().SetItemCount(TItemPos (INVENTORY, iSlotIndex), wCount); return Py_BuildNone(); } case 3: { TItemPos Cell; if (!PyTuple_GetByte(poArgs, 0, &Cell.window_type)) return Py_BuildException(); if (!PyTuple_GetInteger(poArgs, 1, &Cell.cell)) return Py_BuildException(); WORD wCount; if (!PyTuple_GetInteger(poArgs, 2, &wCount)) return Py_BuildException(); CPythonPlayer::Instance().SetItemCount(Cell, wCount); return Py_BuildNone(); } default: return Py_BuildException(); } } PythonNetworkStreamModule.cpp Replace the following function: PyObject* netSendItemMovePacket(PyObject* poSelf, PyObject* poArgs) With this: PyObject* netSendItemMovePacket(PyObject* poSelf, PyObject* poArgs) { TItemPos Cell; TItemPos ChangeCell; int num; switch (PyTuple_Size(poArgs)) { case 3: if (!PyTuple_GetInteger(poArgs, 0, &Cell.cell)) return Py_BuildException(); if (!PyTuple_GetInteger(poArgs, 1, &ChangeCell.cell)) return Py_BuildException(); if (!PyTuple_GetInteger(poArgs, 2, &num)) return Py_BuildException(); break; case 5: { if (!PyTuple_GetByte(poArgs, 0, &Cell.window_type)) return Py_BuildException(); if (!PyTuple_GetInteger(poArgs, 1, &Cell.cell)) return Py_BuildException(); if (!PyTuple_GetByte(poArgs, 2, &ChangeCell.window_type)) return Py_BuildException(); if (!PyTuple_GetInteger(poArgs, 3, &ChangeCell.cell)) return Py_BuildException(); if (!PyTuple_GetInteger(poArgs, 4, &num)) return Py_BuildException(); } break; default: return Py_BuildException(); } CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); rkNetStream.SendItemMovePacket(Cell, ChangeCell, (WORD) num);//ez a sor az return Py_BuildNone(); } GameType.h Search for this: typedef struct packet_item Then replace this: BYTE count; With this: WORD count; Search for this: typedef struct packet_shop_item And edit this: BYTE count; to this: WORD count; AbstractPlayer.h Replace this: virtual void SetItemCount(TItemPos itemPos, BYTE byCount) = 0; With this: virtual void SetItemCount(TItemPos itemPos, WORD byCount) = 0; PythonPlayer.cpp Replace this: void CPythonPlayer::SetItemCount(TItemPos Cell, BYTE byCount) With this: void CPythonPlayer::SetItemCount(TItemPos Cell, WORD byCount) PythonPlayer.h Replace this: void SetItemCount(TItemPos Cell, BYTE byCount); With this: void SetItemCount(TItemPos Cell, WORD byCount); PythonNetworkStream.h And this: bool SendSafeBoxItemMovePacket(BYTE bySourcePos, BYTE byTargetPos, BYTE byCount); bool SendShopSellPacketNew(BYTE bySlot, BYTE byCount); bool SendItemMovePacket(TItemPos pos, TItemPos change_pos, BYTE num); With this: bool SendSafeBoxItemMovePacket(BYTE bySourcePos, BYTE byTargetPos, WORD byCount); bool SendShopSellPacketNew(BYTE bySlot, WORD byCount); bool SendItemMovePacket(TItemPos pos, TItemPos change_pos, WORD num); Now we are done with the client, you can build it now. server common/tables.h Search this: typedef struct SShopItemTable Then replace this: BYTE count; To this: WORD count; packet.h Search for this: typedef struct command_item_drop2 Then edit this: BYTE count; To this: WORD count; Then search this:: typedef struct command_item_move Replace this: BYTE count; With this: WORD count; Then search this: typedef struct packet_item_set Replace this: BYTE count; To this: WORD count; Search this: typedef struct packet_item_update Replace this: BYTE count; To this: WORD count; Search this: struct packet_shop_item Replace this: BYTE count; To this: WORD count; Search this: typedef struct pakcet_view_equip Then replace this: BYTE count; To this: WORD count; input_main.cpp Replace this whole function: int CInputMain::Shop(LPCHARACTER ch, const char * data, size_t uiBytes) With this: typedef struct fckOFF { BYTE bySlot; WORD byCount; } TfckOFF; int CInputMain::Shop(LPCHARACTER ch, const char * data, size_t uiBytes) { TPacketCGShop * p = (TPacketCGShop *) data; if (uiBytes < sizeof(TPacketCGShop)) return -1; if (test_server) sys_log(0, "CInputMain::Shop() ==> SubHeader %d", p->subheader); const char * c_pData = data + sizeof(TPacketCGShop); uiBytes -= sizeof(TPacketCGShop); switch (p->subheader) { case SHOP_SUBHEADER_CG_END: sys_log(1, "INPUT: %s SHOP: END", ch->GetName()); CShopManager::instance().StopShopping(ch); return 0; case SHOP_SUBHEADER_CG_BUY: { if (uiBytes < sizeof(BYTE) + sizeof(BYTE)) return -1; BYTE bPos = *(c_pData + 1); sys_log(1, "INPUT: %s SHOP: BUY %d", ch->GetName(), bPos); CShopManager::instance().Buy(ch, bPos); return (sizeof(BYTE) + sizeof(BYTE)); } case SHOP_SUBHEADER_CG_SELL: { if (uiBytes < sizeof(BYTE)) return -1; BYTE pos = *c_pData; sys_log(0, "INPUT: %s SHOP: SELL", ch->GetName()); CShopManager::instance().Sell(ch, pos); return sizeof(BYTE); } case SHOP_SUBHEADER_CG_SELL2: { if (uiBytes < sizeof(TfckOFF)) return -1; TfckOFF*p2 = (TfckOFF*)c_pData; /*BYTE pos = *(c_pData++); WORD count = *(c_pData);*/ sys_log(0, "INPUT: %s SHOP: SELL2", ch->GetName()); CShopManager::instance().Sell(ch, p2->bySlot, p2->byCount); return sizeof(TfckOFF); } default: sys_err("CInputMain::Shop : Unknown subheader %d : %s", p->subheader, ch->GetName()); break; } return 0; } shop_manager.cpp Replace this: void CShopManager::Sell(LPCHARACTER ch, BYTE bCell, BYTE bCount) To this: void CShopManager::Sell(LPCHARACTER ch, BYTE bCell, WORD bCount) shop.h Search this: typedef struct shop_item Replace this: BYTE count; To this: WORD count; shop_manager.h Replace this: void Sell(LPCHARACTER ch, BYTE bCell, BYTE bCount=0); To this: void Sell(LPCHARACTER ch, BYTE bCell, WORD bCount=0); char_item.cpp Replace this: bool CHARACTER::DropItem(TItemPos Cell, BYTE bCount) To this: bool CHARACTER::DropItem(TItemPos Cell, WORD bCount) Then replace this: bool CHARACTER::MoveItem(TItemPos Cell, TItemPos DestCell, BYTE count) To this: bool CHARACTER::MoveItem(TItemPos Cell, TItemPos DestCell, WORD count) And replace this in this function: count = MIN(200 - item2->GetCount(), count); To this: count = MIN(ITEM_MAX_COUNT - item2->GetCount(), count); Then replace this: LPITEM CHARACTER::AutoGiveItem(DWORD dwItemVnum, BYTE bCount, int iRarePct, bool bMsg) To this: LPITEM CHARACTER::AutoGiveItem(DWORD dwItemVnum, WORD bCount, int iRarePct, bool bMsg) And replace this in this function: BYTE bCount2 = MIN(200 - item->GetCount(), bCount); To this: WORD bCount2 = MIN(ITEM_MAX_COUNT - item->GetCount(), bCount); And replace this inside the PickupItem function: BYTE bCount = item->GetCount(); To this: WORD bCount = item->GetCount(); And this (still inside this function): BYTE bCount2 = MIN(200 - item2->GetCount(), bCount); To this: WORD bCount2 = MIN(ITEM_MAX_COUNT - item2->GetCount(), bCount); item.cpp->DWORD CItem::GetCount() Replace this: return MIN(m_dwCount, 200); To this: return MIN(m_dwCount, ITEM_MAX_COUNT); safebox.cpp Replace this: bool CSafebox::MoveItem(BYTE bCell, BYTE bDestCell, BYTE count) To this: bool CSafebox::MoveItem(BYTE bCell, BYTE bDestCell, WORD count) Then replace this inside this function: count = MIN(200 - item2->GetCount(), count); To this: count = MIN(ITEM_MAX_COUNT - item2->GetCount(), count); common/item_lenght.h Here you can set the maximum number in a stack. Change this as big as you want (between 0 and ~60k) ITEM_MAX_COUNT = 200, (I changed this to 300, just for the test) char.h Replace this: bool DropItem(TItemPos Cell, BYTE bCount=0); bool MoveItem(TItemPos pos, TItemPos change_pos, BYTE num); LPITEM AutoGiveItem(DWORD dwItemVnum, BYTE bCount=1, int iRarePct = -1, bool bMsg = true); To this: bool DropItem(TItemPos Cell, WORD bCount=0); bool MoveItem(TItemPos pos, TItemPos change_pos, WORD num); LPITEM AutoGiveItem(DWORD dwItemVnum, WORD bCount=1, int iRarePct = -1, bool bMsg = true); safebox.h Replace this: bool MoveItem(BYTE bCell, BYTE bDestCell, BYTE count); To this: bool MoveItem(BYTE bCell, BYTE bDestCell, WORD count); oxevent.cpp Replace this: bool COXEventManager::GiveItemToAttender(DWORD dwItemVnum, BYTE count) To this: bool COXEventManager::GiveItemToAttender(DWORD dwItemVnum, WORD count) oxevent.h Replace this: bool GiveItemToAttender(DWORD dwItemVnum, BYTE count); With this: bool GiveItemToAttender(DWORD dwItemVnum, WORD count); Now we are done with the server, don't foget to build the db and the gamefile too! database We have to do 2 more things: Go to the player database, right click on the item table -> desing table, then edit the count column's type from tinyint to smallint and the lenght from 3 to 4. shop_item table->desing table: edit the count column's type from tinyint to smallint And we are done I also captured the "progress" like in my "Expand maximum level" topic, its about 40 minutes long again, its not necessary at all to watch it, but if you are interested about the progress, or you just bored and have 40-50 minute freetime, watch it, if you want Special thanks to TheSLZ for testing the edits. If you have any problem/remark/question, or you've just found a bug, feel free to tell/ask it here or in PM. Have a nice day, ~masodikbela
    1 point
  4. M2 Download Center Download Here ( Internal ) I know many people like me come here or try to find in another forums this select new character official.. and is just a part or is incomplete.. but i find a full version and i come here to reupload. so GL on servers. For make large description on characters / kingdoms: Check change BOX_VISIBLE_LINE_COUNT from 5 to 14 in PythonEventManager.h Thanks @Lajk Download: [Hidden Content]
    1 point
  5. I will show you how to easily create animations. Do you know this animation? You must have seen her on some server. It would seem that someone went to the trouble to match her with metin, right? This is just the first impression. If you deal with models in metin then you will do such animation in a simple way. Here is a page with thousands of different animations. All you have to do is load your model in FBX format and the animations will adapt themselves. Then you save the file and later adjust it slightly in the program, because the animation does not include hair bones and various armor elements, such as leg or shoulders (although this is not necessary, because I saw that people sell these animations without any editing). [Hidden Content]
    1 point
  6. M2 Download Center Download Here ( Internal ) Introduction Hey, since I'm often asked if I can make an example for this or that in Python, I just post some of these examples in this thread from time to time. Usually they just end up in my trash (that's why the collection is small for now) but maybe it will help some of you to learn something. You are also welcome to post examples here and I will add them to the startpost. You have a wish for a certain example? Then write it in here. PS: These examples are designed very simple, so that they can be understood. Examples ui.ComoBox() ui.ScrollBar() with text ui.AniImageBox() as loading bar ui.ListBox() ui.ToggleButton() ui.RadioButtonGroup() ui.DragButton() ui.Bar(), ui.Box(), ui.Line() ui.Gauge(), ui.SliderBar() ui.TextLine(), ui.EditLine() Pagination Tabs DropDown Tree Category Navigation ListBox Search TextLineScrollable Class Collapsible window
    1 point
  7. M2 Download Center Download Here ( Internal )
    1 point
  8. M2 Download Center Download Here ( Internal ) VirusTotal: [Hidden Content] Hi ! Today ThunderCore Society will offer you a special tool for Granny3D Models. Note: That tool isn't for begginers and we don't offer suport for that. We hereby inform you that we take the copyrights file and his contents because ThunderCore Society has paid to perform this work. Attention: NonCommercial — You may not use the material for commercial purposes. NoDerivatives — If you transform, or build upon the material, you may not distribute the modified material. No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. Kind Regards - Johnny White
    1 point
  9. Hello, first of all this not a release, it's just 1-5 second work. Today I found a problem on my server, it was lagging when we were in map in small distance and attacking a lot of monsters. There was like 1-3s delay and it was horrible. I know a lot of you know about it, dont write it here please. Open: PythonNetworkStreamPhaseGame.cpp Search for: const DWORD MAX_RECV_COUNT = You have different value there, I recommend edit it to 32 It will look like this: const DWORD MAX_RECV_COUNT = 32; Save it, build it, enjoy. Result for me: No delay when mount/unmount, no delay when adding new status points etc.
    1 point
  10. M2 Download Center Download Here ( Internal ) Today I bring you another exclusive release from Tim. This time is the granny.dll compatible with Granny 2.8 models and new binaries. Included for completeness is the already public granny DLL for the old binaries, and the bulkconverter.exe tool. What can I do with this? You can use granny models from any Granny version up to 2.8 in your client. How do I use this? Just replace the original dll in your client. Please note, it only works on original, packed client binaries. A tool (bulkconverter.exe) is provided so you can easily convert your current models to 2.8 for best performance. Usage: bulkconverter foldername Will convert all the gr2 files found inside foldername to v2.8 Granny format. Regards
    1 point
  11. M2 Download Center Download Here ( Internal ) Hair pinned with Japanese pins only for shaman lady. Such a curiosity - Hair pinned with Japanese pins called Kanzashi. In the Japanese culture, the material of which the pins were made was evidence of a person's social status. High ranking aristocrats had the right to wear gold pins, middle ranking aristocrats had the right to wear silver pins, and ordinary people, regardless of their material status, had to settle for brass pins. Download: [Hidden Content]
    1 point
  12. M2 Download Center Download Here ( Internal ) Hello togehter, today i want to share a small, but in my opinion, usefull security upgrade for your player password-hashes. The current default hash, which is used by the most of you (some exeptions might be out there) is the MD5 Hash. This hash might be not the best choice for hashing passwords in this modern days. This is why i thought about something to change there. And my solution for this is Argon2. This Method had won the Password Hashing Competition and this is why i had choosen this over bcrypt or scrypt. This tutorial isn't a 100% beginner firendly guide! Just follow my instructions if you got a little bit of c++ knowledge and know how to work with the source! Create the libargon2 Change the hash inner the game-core source (DEFAULT PASSWORD() MYSQL FUNC TUTORIAL) For now you just need to edit the account.account table and set the size for the password to 128 (Why 128? Db.h EArgon2::HASH_LENGTH = 64. 64 * 2 = 128) And you need to replace your hashes with the argon2 once. For this follow the link to the generation: [Hidden Content] Example config for the tutorial setup: Have fun
    1 point
  13. EterNexus [Hidden Content]
    1 point
  14. Who doesn't have the OnOverIn / OnOverOut here are the functions and declarations of them:
    1 point
  15. password_hash [Hidden Content] example: password_hash('test', PASSWORD_ARGON2I) to log in you need to do selecto on mysql with the email name. Download the password and compare with the function example SELECT `password` FROM `account` WHERE `login` = test [Hidden Content] if(password_verify($_POST['password'], $row['password']){ return true; }else{ return false; } @TOPIC Nice idea, I was thinking recently whether to publish a similar solution. The performance is poorer, the longer the hash counts, the harder it is to break it. Imagine a computer that does 1 million md5 per sec and 1k argon2 per sec. Even if the calculation of it is longer, it does not affect the performance of the game. The user will not feel the difference when logging in 0.01sec for 0.1 sec
    1 point
  16. Hello, not the first time some people tell me this, but its too ridiculous now. The following person is pretending to be me to sell clientside protections and so on. He contacts server owners (portugal / brazil as far as i know) and tell them he analysed the server and found exploits. Scammer Discord: XEN0N.#4640 Scammer steam profile: https://steamcommunity.com/id/xen0nncsgo/ Image (pt language. The black square contained my website which the scammer claimed it was his [i know where to send the bills now]): Facts: I dont know that wannabe I do NOT do any metin2 services I will never contact you whatsover regarding metin2 My ONLY discord is: TMoore#1156 . I do not use skype for years and will also not log it and message you whatsover.
    1 point
  17. So i was bored and tried this client According to the files modification's date, it is a 2005 client. There wasen't any "locale" at the time, but there was a "DefaultCodePage" what can be 936 and 949. (In short 936 is china, 949 is korea) Login window (936): Charselect (936): Createchar (936): pc2 wasen't introduced yet so there was only Warrior M, Assasin F, Sura M, Shaman F. There wasen't seperate quest letter icon and console worked by default: They could store yang in the storage o_O: There is no skipia entrance in map1 since did not exist yet: The old "thin" bridges: Ymir remade them to make it bigger, the thin version caused some problem. Edit: if anyone want to install this client run the installer with xp compatible mode then it will start. Also be aware that the installer shows c:\program files\metin2 but will install to your last drive's root, in my case F:\metin2.
    1 point
  18. Warrior Strange visual bug Hi, I have a problem, as you well know, there is this problem on all servers, including the official one. The problem is as follows. If a warrior gives magic to another player, and immediately standing still gives another skill, the second skill is not seen. Okay, no more theory, I've made a little video. Thanks, Sincerly, r00t3r
    1 point
  19. Latest BR patch. Includes some models re-exported via 2.12.02 granny. And no, before you will ask the new shrimp pet which is defined in the npclist.txt is not available yet, neither the summer armors, they gonna release later maybe. I've forgot to pack the property, here you go. Metin2 Download
    1 point
  20. The first regular update blog post is now available. https://quantum-core.io/changelog/updates/2020/05/06/dev-update-1.html
    1 point
  21. Hello everyone. Let me share these with you here. This post contains everything for the recent[v20.1.5.1 05.05.2020] item and mob proto structure. About the mob_proto it might be some false data, but it's okay , it is impossible to figure out totally from clientside only. I am going to explain my thoughts about the new AI Flags as well as about everything I know, or think. enum EMisc { CHARACTER_NAME_MAX_LEN = 24, MOB_SKILL_MAX_NUM = 5, ITEM_NAME_MAX_LEN = 24, ITEM_LIMIT_MAX_NUM = 2, ITEM_VALUES_MAX_NUM = 6, ITEM_APPLY_MAX_NUM = 4, ITEM_SOCKET_MAX_NUM = 3, CHARACTER_FOLDER_MAX_LEN = 64, }; Fist stop, this enum contains some basic informations which mostly the same, except one. ITEM_APPLY_MAX_NUM has been increased to 4 from 3. Why? Because of the new mounting system what they have done. The seal items of the mounts control everything about the mounting and its bonuses; - New APPLY_MOUNT bonus, its value is the vnum of the mount, stored into POINT_MOUNT. - The bonuses what the mount gives are in the rest of the applies. This why they had to add an extra apply because some mounts gives up to 3 bonuses. typedef struct SItemLimit { BYTE bType; long lValue; } TItemLimit; typedef struct SItemApply { WORD wType; long lValue; } TItemApply; Ho-ho-ho another stop here for a sentence. Might be you cannot see any new values, but if you check the datatypes in the TItemApply, you will see they have changed the datatype of the ApplyType from BYTE(unsigned char) to WORD(unsigned short). Why? The answer is easy; because of their number of the bonuses reached the 255 limit of the BYTE, above of 255 the data will overflow. This modification they made with the 6th 7th bonuses. They added lots of worthless bonuses to be different from the private section and to squeeze out the money of the players with the 6th 7th bonuses. enum EItemAntiFlag { ITEM_ANTIFLAG_FEMALE = (1 << 0), ITEM_ANTIFLAG_MALE = (1 << 1), ITEM_ANTIFLAG_WARRIOR = (1 << 2), ITEM_ANTIFLAG_ASSASSIN = (1 << 3), ITEM_ANTIFLAG_SURA = (1 << 4), ITEM_ANTIFLAG_SHAMAN = (1 << 5), ITEM_ANTIFLAG_GET = (1 << 6), ITEM_ANTIFLAG_DROP = (1 << 7), ITEM_ANTIFLAG_SELL = (1 << 8), ITEM_ANTIFLAG_EMPIRE_A = (1 << 9), ITEM_ANTIFLAG_EMPIRE_B = (1 << 10) ITEM_ANTIFLAG_EMPIRE_R = (1 << 11) ITEM_ANTIFLAG_SAVE = (1 << 12) ITEM_ANTIFLAG_GIVE = (1 << 13) ITEM_ANTIFLAG_PKDROP = (1 << 14) ITEM_ANTIFLAG_STACK = (1 << 15) ITEM_ANTIFLAG_MYSHOP = (1 << 16) ITEM_ANTIFLAG_SAFEBOX = (1 << 17) ITEM_ANTIFLAG_WOLFMAN = (1 << 18) ITEM_ANTIFLAG_RT_REMOVE = (1 << 19) ITEM_ANTIFLAG_QUICKSLOT = (1 << 20) ITEM_ANTIFLAG_CHANGELOOK = (1 << 21) ITEM_ANTIFLAG_REINFORCE = (1 << 22) ITEM_ANTIFLAG_ENCHANT = (1 << 23) ITEM_ANTIFLAG_ENERGY = (1 << 24) ITEM_ANTIFLAG_PETFEED = (1 << 25) ITEM_ANTIFLAG_APPLY = (1 << 26) ITEM_ANTIFLAG_ACCE = (1 << 27) ITEM_ANTIFLAG_MAIL = (1 << 28) }; Okay, here also there are many of new antiflags and I am going the explain the new flags only: ITEM_ANTIFLAG_RT_REMOVE : This one kind of funny, because this doesn't have any reference at clientside, but it should be ANTIFLAG_REAL_TIME_REMOVE. Which blocks the destroyitem function when the real_time_expire_event is executed. It is about 98% sure. Only the new pet system seals have this flag, and their transport box. Isn't it funny that I've just figured this out now when I wrote this? haha ITEM_ANTIFLAG_QUICKSLOT : Obviously blocks to attach the item with this flag to the quickslots. ITEM_ANTIFLAG_CHANGELOOK : This one will block the changelook process. That item which has this flag cannot be used for appearance for another. ITEM_ANTIFLAG_REINFORCE : Blocks to add new bonuses to an item. ITEM_ANTIFLAG_ENCHANT : Blocks to change the attributes of an item. ITEM_ANTIFLAG_ENERGY : Blocks to use the item for making Energy Fragment from it. ITEM_ANTIFLAG_PETFEED : This flag blocks the pet, to eat the item which has it. ITEM_ANTIFLAG_APPLY : This flag will make the item unstonable, you will not be able to put any stones into it. Or It blocks every applicable item to use on it, can be both too, dunno. ITEM_ANTIFLAG_ACCE : This flag will block theowadan to absorb the bonuses from the item which has this flag. ITEM_ANTIFLAG_MAIL : The flag will make the item unsendable via mail. enum EItemFlag { ITEM_FLAG_REFINEABLE = (1 << 0), ITEM_FLAG_SAVE = (1 << 1), ITEM_FLAG_STACKABLE = (1 << 2), ITEM_FLAG_COUNT_PER_1GOLD = (1 << 3), ITEM_FLAG_SLOW_QUERY = (1 << 4), ITEM_FLAG_RARE = (1 << 5), ITEM_FLAG_UNIQUE = (1 << 6), ITEM_FLAG_MAKECOUNT = (1 << 7), ITEM_FLAG_IRREMOVABLE = (1 << 8), ITEM_FLAG_CONFIRM_WHEN_USE = (1 << 9), ITEM_FLAG_QUEST_USE = (1 << 10), ITEM_FLAG_QUEST_USE_MULTIPLE= (1 << 11), ITEM_FLAG_QUEST_GIVE = (1 << 12), ITEM_FLAG_LOG = (1 << 13), ITEM_FLAG_APPLICABLE = (1 << 14), }; Small confess about the normal Flags, I'm too lazy to explain everything so I just put here the list of them Anyway they didn't add any new, just removed some unused from 2003 devphase. enum EItemWearFlag { WEARABLE_BODY = (1 << 0), WEARABLE_HEAD = (1 << 1), WEARABLE_FOOTS = (1 << 2), WEARABLE_WRIST = (1 << 3), WEARABLE_WEAPON = (1 << 4), WEARABLE_NECK = (1 << 5), WEARABLE_EAR = (1 << 6), WEARABLE_UNIQUE = (1 << 7), WEARABLE_SHIELD = (1 << 8), WEARABLE_ARROW = (1 << 9), WEARABLE_HAIR = (1 << 10), WEARABLE_ABILITY = (1 << 11), WEARABLE_PENDANT = (1 << 12), }; Here for a comment, they have just added the pendant as new, and changed the index of the unique with the shield. Also wondering when they are going to remove the unused wear ability flag, and its I dont know how many slots from the equipments .. Those were back in time couple of hidden items, for the collection quests bonus holder of the results, or whatever, stupid thing, unused, supposed to be removed. Done. The Immune flag is untouched, pf obviously because it is used for nothing at all rofl. About the LimitTypes, they removed the PC_BANG value, and its items, codes completely. typedef struct SItemTable { DWORD dwVnum; DWORD dwVnumRange; char szName[ITEM_NAME_MAX_LEN + 1]; char szLocaleName[ITEM_NAME_MAX_LEN + 1]; BYTE bType; BYTE bSubType; BYTE bWeight; BYTE bSize; DWORD dwAntiFlags; DWORD dwFlags; DWORD dwWearFlags; DWORD dwImmuneFlag; DWORD dwBuyItemPrice; DWORD dwSellItemPrice; TItemLimit aLimits[ITEM_LIMIT_MAX_NUM]; TItemApply aApplies[ITEM_APPLY_MAX_NUM]; long alValues[ITEM_VALUES_MAX_NUM]; long alSockets[ITEM_SOCKET_MAX_NUM]; DWORD dwRefinedVnum; WORD wRefineSet; DWORD dw67Material; BYTE bAlterToMagicItemPct; BYTE bSpecular; BYTE bGainSocketPct; BYTE bMaskType; BYTE bMaskSubType; } TItemTable; Okay, lets do this one too. So, as you can see here are couple of new values, compared to the old one from 2013. Let's roll over on the new values. dw67Material : This one will be the vnum for the 6th 7th bonus adder, which material is necessary to add the bonus to the item. You can read about this on the official wiki. bMaskType : This is used for the private shop search to categorize the items. bMaskSubType : This is also used for the private shop search to categorize the items. Last word about the item_proto: I will not put the types, subtypes, and their mask version and describe them because none of you will use it . Coming up the mob_proto. enum EMobEnchants { MOB_ENCHANT_CURSE, MOB_ENCHANT_SLOW, MOB_ENCHANT_POISON, MOB_ENCHANT_STUN, MOB_ENCHANT_CRITICAL, MOB_ENCHANT_PENETRATE, MOB_ENCHANTS_MAX_NUM, }; Yes this is untoucheed. No, they didn't add bleeding as enchant to the mobs. It is an effect of some skills of the monsters in the zodiac temple. enum EMobResists { MOB_RESIST_FIST, MOB_RESIST_SWORD, MOB_RESIST_TWOHAND, MOB_RESIST_DAGGER, MOB_RESIST_BELL, MOB_RESIST_FAN, MOB_RESIST_BOW, MOB_RESIST_CLAW, MOB_RESIST_FIRE, MOB_RESIST_ELECT, MOB_RESIST_MAGIC, MOB_RESIST_WIND, MOB_RESIST_POISON, MOB_RESIST_BLEEDING, MOB_RESISTS_MAX_NUM, }; Here you can see couple of new values, all of them obvious, and readable to understand. But if it isn't... MOB_RESIST_FIST: Resist to fist, so when you hit the monster without weapon equipped and it has this defence value, the damage will be reduced. MOB_RESIST_CLAW: Resist against claw attacks, come on, I don't want to do this. MOB_RESIST_BLEEDING: Same as resist_poison just against of the bleeding. enum EMobElementaryWhatevers { MOB_ELEMENTAL_ELEC, MOB_ELEMENTAL_FIRE, MOB_ELEMENTAL_ICE, MOB_ELEMENTAL_WIND, MOB_ELEMENTAL_EARTH, MOB_ELEMENTAL_DARK, MOB_ELEMENTAL_MAX_NUM }; Without serverside these values are not understandable properly. Naturaly those monsters which has elemental resists they have this values as well on the same elemental. Forexample: Lets see the Death reaper(1093). He has UNDEAD and ATT_DARK as RaceFlag, 50% resist fist(just telling ;]), ElemDark=1 and resist dark "-20%" But some monsters are having these values 100+ which is.... no idea why. Zodiac monsters only if I'm not wrong. enum EMobAIFlags { AIFLAG_AGGRESSIVE = (1 << 0), AIFLAG_NOMOVE = (1 << 1), AIFLAG_COWARD = (1 << 2), AIFLAG_NOATTACKSHINSU = (1 << 3), AIFLAG_NOATTACKJINNO = (1 << 4), AIFLAG_NOATTACKCHUNJO = (1 << 5), AIFLAG_ATTACKMOB = (1 << 6), AIFLAG_BERSERK = (1 << 7), AIFLAG_STONESKIN = (1 << 8), AIFLAG_GODSPEED = (1 << 9), AIFLAG_DEATHBLOW = (1 << 10), AIFLAG_REVIVE = (1 << 11), AIFLAG_HEALER = (1 << 12), AIFLAG_COUNT = (1 << 13), AIFLAG_NORECOVERY = (1 << 14), AIFLAG_REFLECT = (1 << 15), AIFLAG_FALL = (1 << 16), AIFLAG_VIT = (1 << 17), AIFLAG_RATTSPEED = (1 << 18), AIFLAG_RCASTSPEED = (1 << 19), AIFLAG_RHP_REGEN = (1 << 20), AIFLAG_TIMEVIT = (1 << 21), }; Here you can see many of new AIFlag values. I am not 100% sure about them, but here is what I think about these new values: AIFLAG_HEALER : This one is the healer, who will heal all members in its group. AIFLAG_COUNT : Who has this flag, you can make just 1 damage on it. AIFLAG_NORECOVERY : This will blocks the monster to recover its health. AIFLAG_REFLECT : <vice> With this flag the monster will be able to transform you into a monster, npc, or statue. AIFLAG_FALL : Ability to force you to fall off your mount. AIFLAG_VIT : <versa> Make your attack damage half, for 10 minutes, until the zodiac floor expires. AIFLAG_RATTSPEED : Reduces the speed of your attack. AIFLAG_RCASTSPEED : Reduces the speed of your skills, it means the cooldown of your skills will be increased. AIFLAG_RHP_REGEN : Reduces the regeneration of your health. AIFLAG_TIMEVIT : <versa> Make your attack damage half, for x seconds. About the vice-versa, those values are imaginable in switched description too. If the reflect is removing your attack damage with the half of it for x seconds then the VIT flags are the transformations. Forexample: the timevit is for tranforming you into monster, or mount for couple of seconds. the vit is for transforming you into a statue until the zodiac floor runs, or until one of your mate hits you. typedef struct SMobSkillLevel { DWORD dwVnum; BYTE bLevel; } TMobSkillLevel; typedef struct SMobTable { DWORD dwVnum; char szName[CHARACTER_NAME_MAX_LEN + 1]; char szLocaleName[CHARACTER_NAME_MAX_LEN + 1]; BYTE bType; BYTE bRank; BYTE bBattleType; BYTE bLevel; BYTE bScale; BYTE bSize; DWORD dwGoldMin; DWORD dwGoldMax; DWORD dwExp; DWORD dwMaxHP; BYTE bRegenCycle; BYTE bRegenPercent; WORD wDef; DWORD dwAIFlag; DWORD dwRaceFlag; DWORD dwImmuneFlag; BYTE bStr, bDex, bCon, bInt; DWORD dwDamageRange[2]; short sAttackSpeed; short sMovingSpeed; BYTE bAggresiveHPPct; WORD wAggressiveSight; WORD wAttackRange; char cEnchants[MOB_ENCHANTS_MAX_NUM]; char cResists[MOB_RESISTS_MAX_NUM]; char cElementalFlags[MOB_ELEMENTAL_MAX_NUM]; char cResistDark, cResistIce, cResistEarth; DWORD dwResurrectionVnum; DWORD dwDropItemVnum; BYTE bMountCapacity; BYTE bOnClickType; BYTE bEmpire; char szFolder[CHARACTER_FOLDER_MAX_LEN + 1]; float fDamMultiply; DWORD dwSummonVnum; DWORD dwDrainSP; DWORD dwMonsterColor; DWORD dwPolymorphItemVnum; TMobSkillLevel Skills[MOB_SKILL_MAX_NUM]; BYTE bBerserkPoint; BYTE bStoneSkinPoint; BYTE bGodSpeedPoint; BYTE bDeathBlowPoint; BYTE bRevivePoint; BYTE bHealPoint; BYTE bRAttSpeedPoint; BYTE bRCastSpeedPoint; BYTE bRHPRegenPoint; FLOAT fHitRange; } TMobTable; bScale: : Scale value between 50 and 200. It will resize the monster. cElementalFlags : So I've told you some info about this, I don't know more. cResistDark : This is a missing elemental resist, they have added it, I just don't really know why even there, not into the resists array, stupid. cResistIce : This is a missing elemental resist, they have added it, I just don't really know why even there, not into the resists array, stupid. cResistEarth : This is a missing elemental resist, they have added it, I just don't really know why even there, not into the resists array, stupid. bHealPoint : Healing percent for the healers. bRAttSpeedPoint : These can be used for what I've named them or the REFLECT or the VIT and TIMEVIT flags too, to give them special value, so it is still a questionmark. bRCastSpeedPoint : These can be used for what I've named them or the REFLECT or the VIT and TIMEVIT flags too, to give them special value, so it is still a questionmark. bRHPRegenPoint : These can be used for what I've named them or the REFLECT or the VIT and TIMEVIT flags too, to give them special value, so it is still a questionmark. fHitRange : Because the client is using its default value to make the checks, this one for sure is on serverside, to check the distance between the character and the monster to validate the attack, skill or the movement of the monsters. But still not 100% I hope it is understandable, my english isn't the best sorry for that. If I missed something let me know in PM.
    1 point
  22. Thanks for the remark, but I never used this command in game as a player, this should be active just for debug as GM's, no sense for players. About the fix, could be done directly from here too: File: cmd_general.cpp costume Search for: snprintf(buf, bufferSize, FN_point_string(attr.bType), attr.sValue); Replace it with: [Hidden Content] hair Search for: offset = snprintf(buf, bufsiz, FN_point_string(aff->bApplyOn), aff->lApplyValue); Replace it with: const char * cPointString = FN_point_string(aff->bApplyOn); if (!*cPointString) return false; offset = snprintf(buf, bufsiz, cPointString, aff->lApplyValue); There's no sense for showing to a player 'UNK... 23%' since he don't know what it's.. I think it's better just to ignore the type if doesn't exist and don't show it in the chat. If you really want to do something like this, you can add a sys_log as an error to see the bonus missing and add it into the function.
    1 point
  23. Hello guys, While trying things on my server, I stumbled accross a weird core-downer. It is really simple but I say "weird" because in litteraly 10 years it has never happened to me nor anyone I know. It probably gets triggered by a malfunctioning quest I had taken from 2012 and forgot to remove (quests were not my concern at the time). I didn't want to only remove the quest but instead I decided to fix the coredowner. It happens because the game is not expected to trigger the function get_leader_vid() without a party. However, there is no check at all if it somehow did and on my server it randomly got triggered without a party and the core simply crashed. So instead of digging further, I thus added a check to avoid the core to crash. Please note that my sources were vanilla at that time. Well, head to questlua_npc.cpp and find the function "npc_get_leader_vid". It should normally look like this: //Function "npc_get_leader_vid" { CQuestManager& q = CQuestManager::instance(); LPCHARACTER npc = q.GetCurrentNPCCharacterPtr(); LPPARTY party = npc->GetParty(); LPCHARACTER leader = party->GetLeader(); if (leader) lua_pushnumber(L, leader->GetVID()); else lua_pushnumber(L, 0); return 1; } Then simply check if "party" exists or not; it should look like this: [Hidden Content] Here you are, note that the coredowner is rare, but it can happen so it's better to avoid it.
    1 point
  24. M2 Download Center Download Here ( Internal ) Hey, I will share a function (Set Atlas Scale) that you can set your own scale in your Atlas Window. As you can see in the Preview the Atlas is bigger than the default. You need to have good quality of Map Image, I think you can use World Editor for this. Preview:
    1 point
  25. Serverfiles are a all the same, bunch on quests, maps and mobs. You dont download and use serverfiles, thats what newbies are recommending to you still. First step is to make your own serverfiles structure, clean of all quests, drops, etc. So that you have a good working ground. With that you also should use a client as untouched as possible. In topic: Difference between serverfiles is their game / db binaries and their share folder. Game / db binaries may contain different or modified systems from serverfile to serverfile. This you solve by compiling and doing your own set of game / db. Share folder contains the mob drops, quests, maps. Here you should start from 0 quests and add them as needed, so you really know whats there. It can really be insecure to use serverfiles from people, as most wannabes will add malware to it. This happens because almost everyone will tell you to extract "tar.gz" in hardcoded folders, instead of teaching you how to make it from scratch. A note: When someones tell you to install mysql by extracted its mysql folder into /var/db/mysql, you know that person is an absolute 0 and most likely just a tutorial follower. People use freebsd because metin2 game / db was built in it. You can adapt it to for example ubuntu, now you will find freebsd to be a real mature and overall good OS. For database edits, you can use Navicat or Mysql Workbench, those are the most used for easy visual databse editing. Regarding your specific edit, most probably your serverfiles were using the mob_proto from .txt files and replicating it to the databse, in that case all changes made on database are ignored and replaced by .txt ones. So you need to edit the .txt file instead (select all, paste into empty excell document is the easiest as it will auto adapt all columns) OR make your server read information from database. Python is for the client, as you are starting you dont need such a big knowledge of it as there are well structured tutorials for it. Its more a common understanding of programming, with time you will see what does what. C++ is needed for the server and client sources, but again like python, learn programming. If you know how to program, you can code in any language, its just a matter of learning that language specific syntax (thats what documentation exists for). Regarding doubling the space of shop, lets pretend i have no clue where it is: 1 - I will try to find identify the function / functions that open shop for example 2 - I will trace the variables it uses 3 - I will check the variable types in this case, as different variable types can have different maximum / minimum sizes. For finding and following things, visual studio and its search + intellisense its a wonder Complete full understanding of the game, you will not have now. With time and practice you will memorize what comes from, its normal in every project
    1 point
  26. Bug-Fix for all others. Preview is now only on Items in Inventory UiToolTip-Fix.txt
    1 point
  27. Hi everyone, This is a funny project, the player can swim, fly, jump , and more with improvement in the future:  Let's see video:  Cordialy
    1 point
  28. M2 Download Center Download Here ( Internal ) Hello, today I want to share with you my quest. What it does? It changes your attributes on an item if you place it on a certain NPC (in this case "Handu-Up") and puts best in slot PVP attributes. What this quest can't do (yet): Differentiate between Average Damage, Skill damage - type weapons like Poison Sword (If someone could show me how to exit a FOR-Loop in LUA I might be ablte to do it) #added Change attributes on other items than your "standard" equipement like costumes etc. Keep in mind that I just wanted to look back into quest scripting so I it's not perfect written by any means but it works and I think some people will have a use for it. Here is the Code (Downloadable as attachement down below): German:
    1 point
  29. Samuraicore v1.2 [Hidden Content]
    1 point
  30. M2 Download Center Download Here ( Internal )
    1 point
  31. Well, I've been meaning to share an actual fix after seeing different attempts at it (one or two which were totally off and decided to remove some code, and the other which recalculated the flag on each check), so here it goes: The bug: If you equip an item without immune after equipping another one with immune, you lose your immune. Internally, the problem is that your immune flag gets recalculated every time you equip an item, but it bases off the proto immunes, forgetting completely about the actual bonuses on the item. The solution itself is rather short! In the functions CItem::EquipTo and CItem::Unequip (in item.cpp) Find: SET_BIT(dwImmuneFlag, m_pOwner->GetWear(i)->m_pProto->dwImmuneFlag); Replace with: SET_BIT(dwImmuneFlag, m_pOwner->GetWear(i)->GetRealImmuneFlag()); Then add the function referred up there to item.cpp: DWORD CItem::GetRealImmuneFlag() { DWORD dwImmuneFlag = m_pProto->dwImmuneFlag; for (int i = 0; i < ITEM_ATTRIBUTE_MAX_NUM; ++i) { if (GetAttributeType(i)) { const TPlayerItemAttribute& ia = GetAttribute(i); if (ia.bType == APPLY_IMMUNE_STUN && !IS_SET(dwImmuneFlag, IMMUNE_STUN)) SET_BIT(dwImmuneFlag, IMMUNE_STUN); else if (ia.bType == APPLY_IMMUNE_FALL && !IS_SET(dwImmuneFlag, IMMUNE_FALL)) SET_BIT(dwImmuneFlag, IMMUNE_FALL); else if (ia.bType == APPLY_IMMUNE_SLOW && !IS_SET(dwImmuneFlag, IMMUNE_SLOW)) SET_BIT(dwImmuneFlag, IMMUNE_SLOW); } } return dwImmuneFlag; } As a new function, it also needs to have an entry on item.h, so find: long GetLimitValue(DWORD idx) const { return m_pProto ? m_pProto->aLimits[idx].lValue : 0; } And add afterwards: DWORD GetRealImmuneFlag(); That's about it. I hope I am not missing anything, as we no longer have the original commit history anymore. If this is not enough, please tell me in the comments, I'll recheck again. Now, as a final note, since I criticized the other solutions (Though only one actually works) I will also go a bit against mine: Is this the best solution possible? It's probable that the answer is no, and that the really best solution involves changes in the point system as a whole. That is however more messy and error prone, so I stayed out of it for the time being. Anyway, hope it helps. Regards!
    1 point
  32. I need 6 character file and how i add it to my server with all weapon and armor
    0 points
  33. I need 6million euro
    0 points
  34. M2 Download Center Download Here ( Internal ) Hi ! Today ThunderCore Society will offer you a special tool for 3d MAX Software. Note: That tool isn't for begginers and we don't offer suport for that. We hereby inform you that we take the copyrights file and his contents because ThunderCore Society has paid to perform this work. There exists an "readme" file that contains some informations about how to install the script. Attention: These files are under copyright and licensed by ThunderCore Society. Any violation of the license may result in suing. Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. NonCommercial — You may not use the material for commercial purposes. NoDerivatives — If you transform, or build upon the material, you may not distribute the modified material. No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits.
    0 points
×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.