Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 11/06/14 in all areas

  1. Hello folks. I don't know if it was "a feature" or not, but it was really annoying and it caused some bugs. So, let's begin. Firstly, we should go to the char.cpp (and we will stay here) Now, let's find the ApplyPoint function and then certain cases.. case APPLY_MAX_HP: case APPLY_MAX_HP_PCT: { int i = GetMaxHP(); if(i == 0) break; PointChange(aApplyInfo[bApplyType].bPointType, iVal); float fRatio = (float)GetMaxHP() / (float)i; PointChange(POINT_HP, GetHP() * fRatio - GetHP()); } break; case APPLY_MAX_SP: case APPLY_MAX_SP_PCT: { int i = GetMaxSP(); if(i == 0) break; PointChange(aApplyInfo[bApplyType].bPointType, iVal); float fRatio = (float)GetMaxSP() / (float)i; PointChange(POINT_SP, GetSP() * fRatio - GetSP()); } break; This part of code is written by Nova, which is used in novaline, but i know that some of you use it in other branches. It is causing the main problem, we should change it to look like this: case APPLY_MAX_HP: case APPLY_MAX_HP_PCT: { int i = GetMaxHP(); if(i == 0) break; PointChange(aApplyInfo[bApplyType].bPointType, iVal); } break; case APPLY_MAX_SP: case APPLY_MAX_SP_PCT: { int i = GetMaxSP(); if(i == 0) break; PointChange(aApplyInfo[bApplyType].bPointType, iVal); } break; Done, now we should conern next problem, it will cause a disproportion between max_hp and current hp. Moving on, we should find PointChange function (still in char.cpp). Then, find case POINT_MAX_HP and POINT_MAX_SP, and change it like that: case POINT_MAX_HP: { SetPoint(type, GetPoint(type) + amount); int i = GetMaxHP(); int hp = GetRealPoint(POINT_MAX_HP); int add_hp = MIN(3500, hp * GetPoint(POINT_MAX_HP_PCT) / 100); add_hp += GetPoint(POINT_MAX_HP); add_hp += GetPoint(POINT_PARTY_TANKER_BONUS); SetMaxHP(hp + add_hp); float fRatio = (float)GetMaxHP() / (float)i; PointChange(POINT_HP, GetHP() * fRatio - GetHP()); val = GetMaxHP(); } break; case POINT_MAX_SP: { SetPoint(type, GetPoint(type) + amount); int i = GetMaxSP(); int sp = GetRealPoint(POINT_MAX_SP); int add_sp = MIN(800, sp * GetPoint(POINT_MAX_SP_PCT) / 100); add_sp += GetPoint(POINT_MAX_SP); add_sp += GetPoint(POINT_PARTY_SKILL_MASTER_BONUS); SetMaxSP(sp + add_sp); float fRatio = (float)GetMaxSP() / (float)i; PointChange(POINT_SP, GetSP() * fRatio - GetSP()); val = GetMaxSP(); } break; Short description: I'm using Nova method to calculate HP/SP ratio gain. It should prevent people from using it as a infinite source of hp (using affect.add(max_hp.. affect.add(hp... we would create another bug.) Kind regards, Evor. @DISCLAIMER This method was tested by me and my team. We find it fixing the whole problem, but whenever you find another bug, please report it. Ratio calculation courtesy of Nova.
    4 points
  2. First of all, I wanted to warn you That Work may take away a little of the mineral. So I 'll explain what it is. Image: https://metin2.download/picture/wAIXp4OrfQ0Z5X94xOt12lZOl993CRNX/.jpg Step 1 : Make the render of the Lycans ( see picture ) Step 2: Create a background that fits perfectly with a set: (Measures below) Step 3: Enter the text : PWNSTARZ (only signature) Step 4: Submit below. All work will be rewarded with a like point. Good luck to all the graphs of metin2dev.org
    2 points
  3. M2 Download Center Download Here ( Internal ) Hi devs! The original equipment viewer is not updated for the new equipments I am thinking of costumes + rings + belt Here is the extended version. Here are my modified files to root and uiscript package, the .py files: uiEquipDialog.py Pastebin ~ MEGA UIScriptEquipmentDialog.py Pastebin ~ MEGA UIScriptCostumeEquipmentDialog.py Pastebin ~ MEGA Ehm yeah this was the easiest part of this, now comin' the serverside and binary parts. Server: 1.) Open gamepacket.h than search for: "typedef struct pakcet_view_equip" and replace all structure with this: typedef struct pakcet_view_equip { BYTE header; DWORD vid; struct { DWORD vnum; BYTE count; long alSockets[ITEM_SOCKET_MAX_NUM]; TPlayerItemAttribute aAttr[ITEM_ATTRIBUTE_MAX_NUM]; } equips[16]; } TPacketViewEquip; PS: lel "pakcet" xD nevermind Save&Close 2.) Open char.cpp and search for this: "void CHARACTER::SendEquipment(LPCHARACTER ch)" and replace the event with this(Thanks ATAG): void CHARACTER::SendEquipment(LPCHARACTER ch) { TPacketViewEquip p; p.header = HEADER_GC_VIEW_EQUIP; p.vid = GetVID(); int pos[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 19, 20, 21, 22, 23 }; for (int i = 0; i < 16; i++) { LPITEM item = GetWear(pos[i]); if (item) { p.equips[i].vnum = item->GetVnum(); p.equips[i].count = item->GetCount(); thecore_memcpy(p.equips[i].alSockets, item->GetSockets(), sizeof(p.equips[i].alSockets)); thecore_memcpy(p.equips[i].aAttr, item->GetAttributes(), sizeof(p.equips[i].aAttr)); } else { p.equips[i].vnum = 0; } } ch->GetDesc()->Packet(&p, sizeof(p)); } Serverside done! - Build! Binary: 1.) Open UserInterfacePacket.h than search for this: "typedef struct pakcet_view_equip" and replace with this: typedef struct pakcet_view_equip { BYTE header; DWORD dwVID; TEquipmentItemSet equips[16]; } TPacketGCViewEquip; PS: we met again with pakcet xD, Save&Close. 2.) Open UserInterfacePythonNetworkStreamPhaseGame.cpp than search for this: "bool CPythonNetworkStream::RecvViewEquipPacket()" and replace with this: bool CPythonNetworkStream::RecvViewEquipPacket() { TPacketGCViewEquip kViewEquipPacket; if (!Recv(sizeof(kViewEquipPacket), &kViewEquipPacket)) return false; PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OpenEquipmentDialog", Py_BuildValue("(i)", kViewEquipPacket.dwVID)); for (int i = 0; i < 16; ++i) { TEquipmentItemSet & rItemSet = kViewEquipPacket.equips[i]; PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "SetEquipmentDialogItem", Py_BuildValue("(iiii)", kViewEquipPacket.dwVID, i, rItemSet.vnum, rItemSet.count)); for (int j = 0; j < ITEM_SOCKET_SLOT_MAX_NUM; ++j) PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "SetEquipmentDialogSocket", Py_BuildValue("(iiii)", kViewEquipPacket.dwVID, i, j, rItemSet.alSockets[j])); for (int k = 0; k < ITEM_ATTRIBUTE_SLOT_MAX_NUM; ++k) PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "SetEquipmentDialogAttr", Py_BuildValue("(iiiii)", kViewEquipPacket.dwVID, i, k, rItemSet.aAttr[k].bType, rItemSet.aAttr[k].sValue)); } return true; } Binaryside done! - Build! ---Edit---- Multiple opening bugfix: Open interFaceModule.py and search for this: "def OpenEquipmentDialog(self, vid):" if you found it replace that function with this: def OpenEquipmentDialog(self, vid): if self.equipmentDialogDict.has_key(vid): self.equipmentDialogDict[vid].Destroy() self.CloseEquipmentDialog(vid) dlg = uiEquipmentDialog.EquipmentDialog() dlg.SetItemToolTip(self.tooltipItem) dlg.SetCloseEvent(ui.__mem_func__(self.CloseEquipmentDialog)) dlg.Open(vid) self.equipmentDialogDict[vid] = dlg Show the "View equip" button on the targetbar: Open uitarget.py and check this diff to fix it for yourself: [Hidden Content] ( ----EndEdit---- Ohh I almost forgot, here are the bgs ^^-> ui.7z - MEGA All done, press escape to exit... :')
    1 point
  4. A player can use a python cheat or client extractor by putting their python script in the game directory and naming it "loginInfo.py". This will detour the player from doing so. 1. Unpack your root archive. 2. Edit the file "intrologin.py". 3. Find this line: self.__LoadLoginInfo("loginInfo.py")4. Replace the entire line with this: if not os.path.exists('logininfo.py') and not os.path.isfile('logininfo.py'): self.__LoadLoginInfo("loginInfo.py") else: dbg.LogBox('Ah so you want to try to extract the client?n' 'Or maybe you want to run your favorite cheat?n' 'Not gonna happen...n' 'It seems I have already thought of this.n' 'I am ATLEAST one step ahead of you...n' '------------------------------------------------n' 'n' "TRY HARDER BRO") exception.Abort("Unsupported file, please delete it. (TRY HARDER BRO)") # Syserr.txt returnYou can of-course change the message to whatever you like. "/n" denotes a line break. Here's what it looks like when someone tries to use this bug after you've added the protection:
    1 point
  5. Char_battle.cpp [ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) ] if (pAttacker->GetPoint(POINT_HIT_HP_RECOVERY) && number(0, 4) > 0) // 80% Č®·ü { int i = MIN(dam, iCurHP) * pAttacker->GetPoint(POINT_HIT_HP_RECOVERY) / 100; if (i) { CreateFly(FLY_HP_SMALL, pAttacker); pAttacker->PointChange(POINT_HP, i); } } Replace if (pAttacker->GetPoint(POINT_HIT_HP_RECOVERY) && number(0, 4) > 0) // 80% Č®·ü { int i = MIN(dam, iCurHP) * pAttacker->GetPoint(POINT_HIT_HP_RECOVERY) / 100; if (i && i > 0) { CreateFly(FLY_HP_SMALL, pAttacker); pAttacker->PointChange(POINT_HP, i); } }
    1 point
  6. Hey Guys, Since this is my first post i want to release a little module i wrote 5 minutes ago. First of all this is for everybody who hates sockets(like me) and don't want to use item_proto for Shinings/Effects whatever. The Code is quiet "crappy" but it is working flawlessly. So lets get started. You wanna create something like this where you declare your maps to store the vnum and effectfilepath #include <map> #ifndef ShiningSettings_H #define ShiningSettings_H 1 extern std::map<int, char*> shiningdata; extern std::map<int, char*>::iterator shiningit; #endif Then you wanna create your function for your python module #include "StdAfx.h" #include "ShiningSettings.h" PyObject* addEffect(PyObject* poSelf, PyObject* poArgs) { int vnum; char* effectpath; if(!PyTuple_GetInteger(poArgs, 0, &vnum)) { return Py_BuildException(); } if(!PyTuple_GetString(poArgs, 1, &effectpath)) { return Py_BuildException(); } if(!shiningdata.count(vnum)){ shiningdata[vnum] = effectpath; } return Py_BuildNone(); } void initShining() { static PyMethodDef s_methods[] = { { "Add", addEffect, METH_VARARGS }, { NULL, NULL }, }; Py_InitModule("Shining", s_methods); } Make also sure you start your function in UserInterface.cpp bool RunMainScript(CPythonLauncher& pyLauncher, const char* lpCmdLine){ //Otherfunctions initShining(); } AND in stdafx.h add this void initShining(); After that open up your InstanceBase.cpp and define your early declared maps also include boost algorithm Just copy this at the start of the file #include "boost/algorithm/string.hpp" std::map<int, char*> shiningdata; std::map<int, char*>::iterator shiningit; Then search for if (12010 <= vnum && vnum <= 12049) and copy the following code after the if-clause if(!shiningdata.empty()){ for (shiningit=shiningdata.begin(); shiningit!=shiningdata.end(); shiningit++) if (shiningit->first == vnum) { std::string substr(shiningit->second); std::vector<string> chars; boost::split(chars, substr, boost::is_any_of("#")); for(std::vector<string>::size_type i = 0; i != chars.size(); i++) { __AttachEffectToArmours(chars[i]); } } } } This will split after a # for multiple shining attached to one amour. Then you need to declare and define a function in InstanceBaseEffect.cpp and InstanceBase.h InstanceBaseEffect.cpp DWORD CInstanceBase::__AttachEffectToArmours(string effectfilename) { const char * effectpath = effectfilename.c_str(); CEffectManager::Instance().RegisterEffect(effectpath, false, false); return m_GraphicThingInstance.AttachEffectByName(0, "Bip01", effectpath); } Again if you wish you can modify it. I already hardcoded the bonename and the boneindex. In InstanceBase.h Search for this: protected: DWORD __AttachEffect(UINT eEftType); DWORD __AttachEffectToArmours(string effectfilename); void __DetachEffect(DWORD dwEID); Replace with this: protected: DWORD __AttachEffect(UINT eEftType); DWORD __AttachEffectToArmours(string effectfilename); DWORD __AttachEffect(char filename[128]); void __DetachEffect(DWORD dwEID); Oh Yeah watch out that your filename is no longer than 128 characters. Last but not least: Create a Python Script in your root Folder (call it whatever you like) import Shining ##Modded Version # Implemented Delim for C++ # delimiter : # EffectTable = { 11290 : ["d:/ymir work/pc/common/effect/armor/armor-4-2-2.mse"], 11291 : ["d:/ymir work/pc/common/effect/armor/armor-4-2-2.mse"], 11292 : ["d:/ymir work/pc/common/effect/armor/armor-4-2-2.mse"], 11293 : ["d:/ymir work/pc/common/effect/armor/armor-4-2-2.mse"], 11294 : ["d:/ymir work/pc/common/effect/armor/armor-4-2-2.mse"], 11295 : ["d:/ymir work/pc/common/effect/armor/armor-4-2-2.mse"], 11296 : ["d:/ymir work/pc/common/effect/armor/armor-4-2-2.mse"], 11297 : ["d:/ymir work/pc/common/effect/armor/grun_shining.mse#d:/ymir work/pc/common/effect/armor/armor-4-2-1.mse"], 11298 : ["d:/ymir work/pc/common/effect/armor/armor-4-2-2.mse#d:/ymir work/pc/common/effect/armor/armor-4-2-1.mse"], 11299 : ["d:/ymir work/pc/common/effect/armor/armor-4-2-2.mse#d:/ymir work/pc/common/effect/armor/armor-4-2-1.mse"], 11259 : ["d:/ymir work/pc/common/effect/armor/armor-4-2-2.mse#d:/ymir work/pc/common/effect/armor/armor-4-2-1.mse"], 11269 : ["d:/ymir work/pc/common/effect/armor/armor-4-2-2.mse#d:/ymir work/pc/common/effect/armor/armor-4-2-1.mse"] } def LoadEffectTable(): for effect in EffectTable: for i in range(len(EffectTable[effect])): vnum = effect effectpath = EffectTable[effect][i] Shining.Add(vnum, effectpath) As you can see 2 Shinings are seperated with an "#". Last but no least import your file in your game and add the following line under the python constructor effecttable.LoadEffectTable() I Hope i didn't forgot anything
    1 point
  7. Group Mounts { Vnum 10030 1 71124 1 1 2 71125 1 1 3 71126 1 1 4 71127 1 1 5 71128 1 1 6 71131 1 1 7 71132 1 1 8 71133 1 1 9 71134 1 1 10 71137 1 1 11 71138 1 1 12 71139 1 1 13 71140 1 1 14 71141 1 1 15 71142 1 1 16 71165 1 1 17 71166 1 1 18 71161 1 1 19 71171 1 1 20 71172 1 1 } Add this into special_item_group.txt with your Values
    1 point
  8. into levellog, create the oclumn 'account_id'
    1 point
  9. if (type >= GUILD_WAR_TYPE_MAX_NUM || type < 0) type = GUILD_WAR_TYPE_FIELD;
    1 point
  10. The one I sent you yes. the kraizy.tgz no.
    1 point
  11. Fix for Status point (no points after 91 level) Open char.cpp Search for void CHARACTER::PointChange(BYTE type, int amount, bool bAmount, bool bBroadcast) search and replace with You can also match it with your value (for example limit of status points etc.) I'd tomorrow show how to make a config where u can set a max status point and modify function up to give a number of status points which will perfectly fit to the max of cfg file.
    1 point
×
×
  • 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.