-
Posts
839 -
Joined
-
Days Won
393 -
Feedback
100%
Content Type
Forums
Store
Third Party - Providers Directory
Feature Plan
Release Notes
Docs
Events
Posts posted by xP3NG3Rx
-
-
Put it into the OnUpdate function.
-
Spoiler
Blah blah blah
- 1
-
No, that is the multiline version of the bigboard for ox-quiz, he is looking for this:
Spoilerif app.ENABLE_12ZI: class MissionBoard(ui.Bar): FONT_HEIGHT = 15 LINE_HEIGHT = FONT_HEIGHT + 5 STEP_HEIGHT = LINE_HEIGHT + 5 LONG_TEXT_START_X = 300 SCREEN_WIDTH = wndMgr.GetScreenWidth() def __init__(self): ui.Bar.__init__(self) self.AddFlag("not_pick") self.missionText = None self.missionFullText = None self.curPos = 0 self.dstPos = -5 self.nextScrollTime = 0 self.flowMode = False self.ScrollStartTime = 0.0 self.SetPosition(0, 100) self.SetSize(self.SCREEN_WIDTH, 35) self.SetColor(grp.GenerateColor(0.0, 0.0, 0.0, 0.5)) self.SetWindowHorizontalAlignCenter() self.__CreateTextBar() def __del__(self): ui.Bar.__del__(self) def __CreateTextBar(self): x, y = self.GetGlobalPosition() self.textBar = BigTextBar(self.SCREEN_WIDTH*2, 300, self.FONT_HEIGHT) self.textBar.SetParent(self) self.textBar.SetPosition(6, 8) self.textBar.SetTextColor(242, 231, 193) self.textBar.SetClipRect(0, y, self.SCREEN_WIDTH, y+8+self.STEP_HEIGHT) self.textBar.Show() def CleanMission(self): self.missionText = None self.missionFullText = None self.textBar.ClearBar() self.Hide() def __RefreshBoard(self): self.textBar.ClearBar() if self.missionFullText: (text_width, text_height) = self.textBar.GetTextExtent(self.missionFullText) if text_width>self.SCREEN_WIDTH: self.textBar.TextOut(0, (self.STEP_HEIGHT-8-text_height)/2, self.missionFullText) self.flowMode = True else: self.textBar.TextOut((wndMgr.GetScreenWidth()-text_width)/2, (self.STEP_HEIGHT-8-text_height)/2, self.missionFullText) self.flowMode = False def SetMission(self, text): self.__AppendText(text) self.__RefreshBoard() if self.flowMode: self.dstPos = -text_width self.curPos = self.LONG_TEXT_START_X self.textBar.SetPosition(3 + self.curPos, 8) else: self.dstPos = 0 self.curPos = self.STEP_HEIGHT self.textBar.SetPosition(3, 8 + self.curPos) if not self.IsShow(): self.Show() def SetSubMission(self, text): self.missionFullText = self.missionText + text preflowMode = self.flowMode self.__RefreshBoard() if preflowMode != self.flowMode: if self.flowMode: self.dstPos = -text_width self.curPos = self.LONG_TEXT_START_X self.textBar.SetPosition(3 + self.curPos, 8) else: self.dstPos = 0 self.curPos = self.STEP_HEIGHT self.textBar.SetPosition(3, 8 + self.curPos) def __AppendText(self, text): if text == "": self.CleanMission() return self.missionText = text self.missionFullText = text def OnUpdate(self): if self.missionFullText == None: self.Hide() return if self.dstPos < self.curPos: self.curPos -= 1 if self.flowMode: self.textBar.SetPosition(3 + self.curPos, 8) else: self.textBar.SetPosition(3, 8 + self.curPos) else: if self.flowMode: self.curPos = self.SCREEN_WIDTH
This is the part of the game.py:
if app.ENABLE_12ZI: def BINARY_SetMissionMessage(self, message): self.interface.missionBoard.SetMission(message) def BINARY_SetSubMissionMessage(self, message): self.interface.missionBoard.SetSubMission(message) def BINARY_CleanMissionMessage(self): self.interface.missionBoard.CleanMission()
And some declarations in the interfaceModule.py like the rest of the tipboards.
The rest is c++. -
About the new mob_proto raceflags:
There are three new raceflags. DECO[1 << 17], HIDE[1 << 18] and ATT_CZ[i <<19](? this isn't sure, only the new zodiac mobs have it).
Deco: Means the actor is a decoration and doesn't shown on minimap.Spoiler
Hide: This is the decoration filter for the decorations into the Game options.Spoiler
Att_CZ: I didn't find any informations about the last flag in the binary, so maybe that has only serverside options.- 3
- 1
- 2
- 4
-
Just to make it sure, right?
The best part is the importing of the interfacemodule, you always made my day.- 1
- 2
-
This came with the PvP balancing, but the new pendant system conatins too.
But really, a new bonus implementation is that hard? I think better if you look for another "hobby".- 1
-
They did it again... https://metin2.dev/uploads/custom-emoji/emoticons/default_biggrin.png Now the gameguard isn't runing.
Here is the whole pack with item and mob protos, but the mob_proto isn't clear just dumped with false values, and ofc I don't recommend of use one of them either.
) ( )
(Exclude files: root, outdoor, outdoorempirebattle1) (- 25
- 2
- 1
- 7
- 30
-
Hello.
Today I'd like to share this little stuff what I reversed from the official binary a month ago.
This will fix the positions of textails(name position changes by every update packet on the main character), and also the position of the emotions when you are on a mount .
I've made a little demonstration video where you can see a private server without the fix, my fixxed version and the official aswell.1. Client/bin/playersettingmodule.py
Spoiler1. Add the following code above of the loadGameDataDict declaration:
# SetRaceHeight def __LoadRaceHeight(): try: lines = open("race_height.txt", "r").readlines() except IOError: return for line in lines: tokens = line[:-1].split("\t") if len(tokens) == 0 or not tokens[0]: continue vnum = int(tokens[0]) height = float(tokens[1]) chrmgr.SetRaceHeight(vnum, height)
2. Add the following line below of the dict or extend it however you want:
loadGameDataDict.update({"RACE_HEIGHT": __LoadRaceHeight,})
2.1 extension:
"RACE_HEIGHT" : __LoadRaceHeight,
2. Client/bin/introLoading.py
Spoiler1. Paste the following line below of the self.__LoadNPC() in the DEBUG_LoadData function:
self.__LoadRaceHeight()
2. Add the following line below of the self.loadStepList definition in the LoadData function:
self.loadStepList+=[(98, ui.__mem_func__(self.__LoadRaceHeight)),]
2.1 or extend it:
(98, ui.__mem_func__(self.__LoadRaceHeight)),
3. Add the following function after the __LoadNPC function or anywhere you want:
def __LoadRaceHeight(self): playerSettingModule.LoadGameData("RACE_HEIGHT")
3. Place the race_height.txt from the official client into the yours and pack it in the root.
4. Client/UserInterface/PythonCharacterManagerModule.cppSpoiler1. Add the new function to the module:
PyObject * chrmgrSetRaceHeight(PyObject* poSelf, PyObject* poArgs) { int iRaceIndex; if (!PyTuple_GetInteger(poArgs, 0, &iRaceIndex)) return Py_BadArgument(); float fRaceHeight = 0.0f; if (!PyTuple_GetFloat(poArgs, 1, &fRaceHeight)) return Py_BadArgument(); CRaceManager::Instance().SetRaceHeight(iRaceIndex, fRaceHeight); return Py_BuildNone(); }
And to the methodlist:
{ "SetRaceHeight", chrmgrSetRaceHeight, METH_VARARGS },
5. Client/GameLib/RaceManager.h
Spoiler1. Add these new functions as public:
void SetRaceHeight(int iVnum, float fHeight); float GetRaceHeight(int iVnum);
2. And define the new map which will stores the informations as protected:
std::map<int, float> m_kMap_iRaceKey_fRaceAdditionalHeight;
6. Client/GameLib/RaceManager.cpp
Spoiler1. Add the new functions anywhere you want:
void CRaceManager::SetRaceHeight(int iVnum, float fHeight) { m_kMap_iRaceKey_fRaceAdditionalHeight.insert(std::map<int, float>::value_type(iVnum, fHeight)); } float CRaceManager::GetRaceHeight(int iVnum) { std::map<int, float>::iterator it = m_kMap_iRaceKey_fRaceAdditionalHeight.find(iVnum); if (m_kMap_iRaceKey_fRaceAdditionalHeight.end() == it) return 0.0f; return it->second; }
7. Client/UserInterface/InstanceBase.h
Spoiler1. Paste the following definition of function below of the definition of GetDistance as public:
float GetBaseHeight();
8. Client/UserInterface/InstanceBase.cpp
Spoiler0. Add to the includes:
#include "../gamelib/RaceManager.h"
1. Add the function anywhere you want:
float CInstanceBase::GetBaseHeight() { CActorInstance* pkHorse = m_kHorse.GetActorPtr(); if (!m_kHorse.IsMounting() || !pkHorse) return 0.0f; DWORD dwHorseVnum = m_kHorse.m_pkActor->GetRace(); if ((dwHorseVnum >= 20101 && dwHorseVnum <= 20109) || (dwHorseVnum == 20029 || dwHorseVnum == 20030)) return 100.0f; float fRaceHeight = CRaceManager::instance().GetRaceHeight(dwHorseVnum); if (fRaceHeight == 0.0f) return 100.0f; else return fRaceHeight; }
9. Client/UserInterface/InstanceBaseEffect.cpp
Spoiler1. Replace the fTextTailHeight definition of variable in the AttachTextTail function with this:
float fTextTailHeight = GetBaseHeight() + 10.0f;
2. Replace the following in the SetEmoticon function:
v3Pos.z += float(m_GraphicThingInstance.GetHeight());
With this:
v3Pos.z += float(GetBaseHeight() + m_GraphicThingInstance.GetHeight());
Twice!!! The are two times this line, replace both of them!
10. Client/UserInterface/PythonTextTail.cpp
Spoiler1. Replace the following code in the RegisterChatTail function:
TTextTail * pTextTail = RegisterTextTail(VirtualID, c_szChat, pCharacterInstance->GetGraphicThingInstancePtr(), pCharacterInstance->GetGraphicThingInstanceRef().GetHeight() + 10.0f, c_TextTail_Chat_Color);
With this:
TTextTail * pTextTail = RegisterTextTail(VirtualID, c_szChat, pCharacterInstance->GetGraphicThingInstancePtr(), pCharacterInstance->GetGraphicThingInstanceRef().GetHeight() + pCharacterInstance->GetBaseHeight() + 10.0f, c_TextTail_Chat_Color);
11. Client/GameLib/ActorInstance.cpp
Spoiler0. Add the following to the includes:
#include "RaceManager.h"
1. Replace the whole GetHeight function with this:
float CActorInstance::GetHeight() { DWORD dwRace = GetRace(); float fRaceHeight = CRaceManager::instance().GetRaceHeight(dwRace); if (fRaceHeight == 0.0f) { fRaceHeight = CGraphicThingInstance::GetHeight(); CRaceManager::instance().SetRaceHeight(dwRace, fRaceHeight); } return fRaceHeight; }
I hope you like it, and if you find any problem just let me know in this topic.
- 80
- 1
- 1
- 1
- 3
- 20
- 4
- 94
-
Spoiler
- 2
-
That is the class pointer of the MainStream class.
networkModule.py:
introLogin.py:
- 2
-
Probably with this?
else if ("info" == TokenVector[1]) { if (5 != TokenVector.size()) { TraceError("CPythonNetworkStream::ServerCommand(c_szCommand=%s) - Strange Parameter Count : %s", c_szCommand); return; } long long gold = atoll(TokenVector[2].c_str()); UINT itemVnum = atoi(TokenVector[3].c_str()); UINT count = atoi(TokenVector[4].c_str()); PyObject * poArgs = PyTuple_New(3); PyTuple_SetItem(poArgs, 0, PyLong_FromLongLong(gold)); PyTuple_SetItem(poArgs, 1, PyInt_FromLong(itemVnum)); PyTuple_SetItem(poArgs, 2, PyInt_FromLong(count)); PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_Cube_UpdateInfo", poArgs); }
- 1
-
Spoiler24 minutes ago, Syreldar said:
Stone shards have a time, you can't stack shards with different remaining time.
An idea just turned into my mind now about this. If the item is stackable, and it has realtime limit, the less time will remain on both items which are stacked.
For example you have two items with realtime(same items, different socket time) 1x Item1 have 3 minutes, 1x Item2 have 5 minutes and if you are trying to stack them, a dialog will ask to make sure blabla yes no, and then the result will be 2x Item with 3 minutes. Ofc, it sucks, but something for something, no tho? -
Once I've met with this problem, the reason was a comma before the new weapon type, nothing else. It was missing from here:
Quotestring arIAFVSub1[] = {
"WEAPON_SWORD",
"WEAPON_DAGGER",
"WEAPON_BOW",
"WEAPON_TWO_HANDED",
"WEAPON_BELL",
"WEAPON_FAN",
"WEAPON_ARROW",
"WEAPON_MOUNT_SPEAR",
"WEAPON_CLAW",
"WEAPON_QUIVER",
"WEAPON_BOUQUET"
};The weapon type of the quiver has been overflowed and got 255 as value.
You can check it with this code:
if app.ENABLE_QUIVER_SYSTEM: import chat chat.AppendChat(1, str((itemType, itemSubType))) if itemSubType != item.WEAPON_QUIVER: self.__AppendMetinSlotInfo(metinSlot) else: bHasRealtimeFlag = 0 for i in xrange(item.LIMIT_MAX_NUM): (limitType, limitValue) = item.GetLimit(i) if item.LIMIT_REAL_TIME == limitType: bHasRealtimeFlag = 1 if bHasRealtimeFlag == 1: self.AppendMallItemLastTime(metinSlot[0]) else: self.__AppendMetinSlotInfo(metinSlot)
-
-
This isn't a bad idea, maybe I'll take it to my TODO list.
Spoiler- 1
- 2
-
Via antiflag.
- 1
-
Thanks for it.
SpoilerCHARACTER::MoveItem
- 3
-
I think I need a proper base-finder of process only, but I'm not good enough in hacking soo.
- 2
-
I'm not a hero, and will not, sorry
- 2
- 4
-
Actually this is the same as the normal just with scale, I cannot understand ymir why did it this way.
I mean if you don't change the scale, it is in standard case 1.0 so basically the new functions are not necessary.
Just enough to multiply the sizes with the scales.- 1
-
#ui.py def SetPercentageWithScale(self, curValue, maxValue): wndMgr.SetRenderingRectWithScale(self.hWnd, 0.0, 0.0, -1.0 + float(curValue) / float(maxValue), 0.0)
// EterPythonLib/PythonWindowManagerModule.cpp PyObject * wndImageSetRenderingRectWithScale(PyObject * poSelf, PyObject * poArgs) { UI::CWindow * pWindow; if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) return Py_BuildException(); float fLeft; if (!PyTuple_GetFloat(poArgs, 1, &fLeft)) return Py_BuildException(); float fTop; if (!PyTuple_GetFloat(poArgs, 2, &fTop)) return Py_BuildException(); float fRight; if (!PyTuple_GetFloat(poArgs, 3, &fRight)) return Py_BuildException(); float fBottom; if (!PyTuple_GetFloat(poArgs, 4, &fBottom)) return Py_BuildException(); if (pWindow->IsType(UI::CExpandedImageBox::Type())) ((UI::CExpandedImageBox*)pWindow)->SetRenderingRectWithScale(fLeft, fTop, fRight, fBottom); else if (pWindow->IsType(UI::CAniImageBox::Type())) ((UI::CAniImageBox*)pWindow)->SetRenderingRectWithScale(fLeft, fTop, fRight, fBottom); return Py_BuildNone(); } // Bottom of the file where is the functionlist: { "SetRenderingRectWithScale", wndImageSetRenderingRectWithScale, METH_VARARGS },
// EterPythonLib/PythonWindow.h // class CExpandedImageBox --> Public function definition: void SetRenderingRectWithScale(float fLeft, float fTop, float fRight, float fBottom); // class CAniImageBox --> Public function definition: void SetRenderingRectWithScale(float fLeft, float fTop, float fRight, float fBottom);
// EterPythonLib/PythonWindow.cpp // Add this near to the CExcpandedImageBox functions void CExpandedImageBox::SetRenderingRectWithScale(float fLeft, float fTop, float fRight, float fBottom) { if (!m_pImageInstance) return; ((CGraphicExpandedImageInstance*)m_pImageInstance)->SetRenderingRectWithScale(fLeft, fTop, fRight, fBottom); } // Add this near to the CAniImageBox functions struct FSetRenderingRectWithScale { float fLeft, fTop, fRight, fBottom; void operator () (CGraphicExpandedImageInstance * pInstance) { pInstance->SetRenderingRectWithScale(fLeft, fTop, fRight, fBottom); } }; void CAniImageBox::SetRenderingRectWithScale(float fLeft, float fTop, float fRight, float fBottom) { FSetRenderingRectWithScale setRenderingRect; setRenderingRect.fLeft = fLeft; setRenderingRect.fTop = fTop; setRenderingRect.fRight = fRight; setRenderingRect.fBottom = fBottom; for_each(m_ImageVector.begin(), m_ImageVector.end(), setRenderingRect); }
// EterLib/GrpExpandedImageInstance.h // class CGraphicExpandedImageInstance --> Public function definition: void SetRenderingRectWithScale(float fLeft, float fTop, float fRight, float fBottom);
// EterLib/GrpExpandedImageInstance.cpp void CGraphicExpandedImageInstance::SetRenderingRectWithScale(float fLeft, float fTop, float fRight, float fBottom) { if (IsEmpty()) return; float fWidth = float(GetWidth() * m_v2Scale.x); float fHeight = float(GetHeight() * m_v2Scale.y); m_RenderingRect.left = fWidth * fLeft; m_RenderingRect.top = fHeight * fTop; m_RenderingRect.right = fWidth * fRight; m_RenderingRect.bottom = fHeight * fBottom; }
A couple of minutes of RE
- 1
- 4
-
It has syntax error somewhere in the lua file.
-
crontab + api much more sexy
- 1
-
I think that will never gonna happen.
Update text in Python
in Community Support - Questions & Answers
Posted
Yes, create it then if it isn't exists. The binary will call it aprox. 60 times per second.