Jump to content

VegaS™

Forum Moderator
  • Posts

    656
  • Joined

  • Last visited

  • Days Won

    187
  • Feedback

    100%

Posts posted by VegaS™

  1. Quote

    If you need add more langs, in this fields add the country and the code.

    
        __LANGS_AVAILABLES = ("ES", "EN", "FR", "TR",)
    
        # County with lang
        __COUNTRY_CODES_WITH_LANG = (
            ("MX", __LANGS_AVAILABLES[0]),
            ("US", __LANGS_AVAILABLES[1]),
            ("FR", __LANGS_AVAILABLES[2]),
            ("ES", __LANGS_AVAILABLES[0]),
            ("TR", __LANGS_AVAILABLES[3])
        )

     

    You can do something like that.

    • root/localeInfo.py
    Spoiler
    
    #Search for:
    MODE_NAME_LIST = ( PVP_OPTION_NORMAL, PVP_OPTION_REVENGE, PVP_OPTION_KILL, PVP_OPTION_PROTECT, )
    #Add after:
    LOCALE_REGION_DICT = {
    	'af' : ('za',),
    	'am' : ('et',),
    	'ar' : ('ae', 'bh', 'dz', 'eg', 'iq', 'jo', 'kw', 'lb', 'ly', 'ma', 'om', 'qa', 'sa', 'sy', 'tn', 'ye'),
    	'be' : ('by',),
    	'bg' : ('bg',),
    	'bn' : ('bd',),
    	'cs' : ('cz',),
    	'da' : ('dk',),
    	'de' : ('at', 'ch', 'de', 'li', 'lu'),
    	'dv' : ('mv',),
    	'el' : ('gr',),
    	'en' : ('au', 'bz', 'ca', 'gb', 'ie', 'jm', 'my', 'nz', 'sg', 'tt', 'us', 'za', 'zw'),
    	'es' : ('ar', 'bo', 'cl', 'co', 'cr', 'do', 'ec', 'es', 'gt', 'hn', 'mx', 'ni', 'pa', 'pe', 'pr', 'py', 'sv', 'us', 'uy', 've'),
    	'et' : ('ee',),
    	'fa' : ('ir',),
    	'fi' : ('fi',),
    	'fil' : ('ph',),
    	'fo' : ('fo',),
    	'fr' : ('be', 'ca', 'ch', 'fr', 'lu', 'mc'),
    	'he' : ('il',),
    	'hi' : ('in',),
    	'hr' : ('ba', 'hr'),
    	'hu' : ('hu',),
    	'hy' : ('am',),
    	'id' : ('id',),
    	'ig' : ('ng',),
    	'is' : ('is',),
    	'it' : ('ch', 'it'),
    	'ja' : ('jp',),
    	'ka' : ('ge',),
    	'kk' : ('kz',),
    	'kl' : ('gl',),
    	'km' : ('kh',),
    	'ko' : ('kr',),
    	'ky' : ('kg',),
    	'lb' : ('lu',),
    	'lo' : ('la',),
    	'lt' : ('lt',),
    	'lv' : ('lv',),
    	'mi' : ('nz',),
    	'mk' : ('mk',),
    	'mn' : ('mn',),
    	'ms' : ('bn', 'my'),
    	'mt' : ('mt',),
    	'nb' : ('no',),
    	'ne' : ('np',),
    	'nl' : ('be', 'nl'),
    	'pl' : ('pl',),
    	'prs' : ('af',),
    	'ps' : ('af',),
    	'pt' : ('br', 'pt'),
    	'ro' : ('ro',),
    	'ru' : ('ru',),
    	'rw' : ('rw',),
    	'si' : ('lk',),
    	'sk' : ('sk',),
    	'sl' : ('si',),
    	'sq' : ('al',),
    	'sv' : ('se',),
    	'sw' : ('ke',),
    	'th' : ('th',),
    	'tk' : ('tm',),
    	'tr' : ('tr',),
    	'uk' : ('ua',),
    	'ur' : ('pk',),
    	'vi' : ('vn',),
    	'wo' : ('sn',),
    	'yo' : ('ng',),
    	'zh' : ('cn', 'hk', 'mo', 'sg', 'tw'),
    }

     

    • Add at end of line:
    import requests
    def GetLanguage(locale_region_default = 'en'):
    	language = locale_region_default
    	try:
    		request = requests.get('http://ip-api.com/json/', params=None)
    		if request.status_code is 200:
    			for locale_region, country_code_tuple in LOCALE_REGION_DICT.iteritems():
    				if request.json().get('countryCode').lower() in country_code_tuple:
    					language = locale_region
    
    		return language
    	except requests.exceptions.ConnectionError:
    		return language
    
    # Initialized just one time
    LANGUAGE = GetLanguage()

    How to use it:

    import localeInfo
    print localeInfo.LANGUAGE

     

    • Love 2
  2. The code which you tried is called Python Inner Functions, and for use it you have to declare it inside of another function and call it.
    Delete it and put this:

    • root/game.py
    #Search for:
    		self.SetSize(wndMgr.GetScreenWidth(), wndMgr.GetScreenHeight())
    # Add after:
    		### START OF REGISTER ENVIRONMENT BASED ON SERVER TIME
    		self.environmentInfoDict = {
    			4:	'd:/ymir work/environment/metin2_map_n_flame_dragon_01.msenv',
    			8:	'd:/ymir work/environment/mtthunder.msenv',
    			12:	'd:/ymir work/environment/bayblacksand.msenv',
    			16:	'd:/ymir work/environment/capedragonhead.msenv',
    			20:	'd:/ymir work/environment/snowm02.msenv',
    			22:	'd:/ymir work/environment/trent02.msenv'
    		}
    		
    		environmentHour = (app.GetGlobalTimeStamp() / 60) / 60 % 24
    		if environmentHour in self.environmentInfoDict:
    			environmentFileName = self.environmentInfoDict.get(environmentHour, constInfo.ENVIRONMENT_NIGHT)
    			if app.IsExistFile(environmentFileName):
    				background.RegisterEnvironmentData(0, environmentFileName)
    				background.SetEnvironmentData(0)
    			else:
    				dbg.TraceError('Cannot find environment file (name: {:s})'.format(environmentFileName))
    		### END OF REGISTER ENVIRONMENT BASED ON SERVER TIME

     

    • Love 1
  3.  

    M2 Download Center

    This is the hidden content, please
    ( Internal )

    This is the hidden content, please
    ( GitHub )

    274252NH7Xcab.png.2272a0c2d590769523de1a

    Mhttps://metin2.download/picture/QuI4fRkksSqm6UFD048UKu8SH5zfRuzN/.gif

    Fhttps://metin2.download/picture/6d7VPCh9jWxl2LeT32EjORzb7IXd79ef/.gif

     

    GitHub repository:

    This is the hidden content, please

    02.03.2019 - Polymorph bug fixed.

    • Metin2 Dev 76
    • Not Good 1
    • Cry 1
    • Lmao 1
    • Good 18
    • Love 1
    • Love 71
    • share/locale/germany/quest/quest_functions
    Spoiler
    
    pc.is_fighting

     

    • Src/game/src/questlua_pc.cpp
    Spoiler
    
    //Search for:
    			{ "is_engaged",		pc_is_engaged		},
    // Add after:
    			{ "is_fighting",    pc_is_fighting		},
    
    //Search for:
    	int pc_is_engaged(lua_State* L)
    	{
    		LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr();
    		lua_pushboolean(L, marriage::CManager::instance().IsEngaged(ch->GetPlayerID()));
    		return 1;
    	}
    // Add after:
    	int pc_is_fighting(lua_State* L)
    	{
    		LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr();
    		if (!ch)
    			return 0;
    
    		lua_pushboolean(L, ch->IsPosition(POS_FIGHTING));
    		return 0;
    	}

     

    • How-To-Use:
    Spoiler
    
    when button or info begin
    	if pc.is_fighting() then
    		say("Ummmm....")
    		return
    	end
    	
    	say("Click")
    end

     

     

    • Love 3
  4. Haven't tested.

    • give_item_by_name(item_vnum, item_count, name)

    ______________________________________________________________________________

    • share/locale/germany/quest/quest_functions
    Spoiler
    
    oxevent.give_item_by_name

     

    • Src/game/src/questlua_oxevent.cpp
    Spoiler
    
    //1.1) Search for:
    			{	"give_item",	oxevent_give_item	},
    //1.2) Add after:
    			{	"give_item_by_name",	oxevent_give_item_by_name	},
    			
    //2.1) Search for:
    	ALUA(oxevent_give_item)
    	{
    		if (lua_isnumber(L, 1) && lua_isnumber(L, 2))
    		{
    			COXEventManager::instance().GiveItemToAttender((int)lua_tonumber(L, 1), (int)lua_tonumber(L, 2));
    		}
    
    		return 0;
    	}
    //2.2) Add after:
    	ALUA(oxevent_give_item_by_name)
    	{
    		if (!lua_isnumber(L, 1) && !lua_isnumber(L, 2) && !lua_isstring(L, 3))
    		{
    			sys_err("QUEST : wrong argument");
    			return 0;
    		}
    			
    		const DWORD dwItemVnum = static_cast<DWORD>(lua_tonumber(L, 1));
    		const BYTE bCount = static_cast<BYTE>(lua_tonumber(L, 2));
    		const char * c_pszName = lua_tostring(L, 3);
    		COXEventManager::instance().GiveItemToAttenderByName(dwItemVnum, bCount, c_pszName);
    		return 0;
    	}

     

    • Src/game/src/OXEvent.h
    Spoiler
    
    //1.1) Search for:
    		bool CloseEvent();
    //1.2) Add after:
    		void GiveItemToAttenderByName(const DWORD dwItemVnum, const BYTE bCount, const char * c_pszName);

     

    • Src/game/src/OXEvent.cpp
    Spoiler
    
    //Add this function to end of file
    void COXEventManager::GiveItemToAttenderByName(const DWORD dwItemVnum, const BYTE bCount, const char * c_pszName)
    {
    	itertype(m_map_attender) iter = m_map_attender.begin();
    	for (; iter != m_map_attender.end(); ++iter)
    	{
    		const LPCHARACTER pkChar = CHARACTER_MANAGER::instance().FindByPID(iter->second);
    		if (pkChar && !strcmp(pkChar->GetName(), c_pszName))
    		{
    			pkChar->AutoGiveItem(dwItemVnum, bCount);
    			LogManager::instance().ItemLog(pkChar->GetPlayerID(), 0, bCount, dwItemVnum, "OXEVENT_REWARD", "", pkChar->GetDesc()->GetHostName(), dwItemVnum);
    		}
    	}
    }

     

    • Love 1
  5.  

    • root/game.py
    # Search for:
    		self.interface = interfaceModule.Interface()
    # Replace with:
    		self.interface = interfaceModule.Interface(self)
    • root/interfaceModule.py
    # Search for:
    	def __init__(self):
    		systemSetting.SetInterfaceHandler(self)
    # Replace with:
    	def __init__(self, wndGame):
    		self.wndGame = wndGame
    		systemSetting.SetInterfaceHandler(self)
    • root/uiInventory.py
    	wndGame = self.interface.wndGame
    	if wndGame:
    		wndGame.StartAttack() # Function from game.py

     

    • Love 1
  6. 3 hours ago, avertuss said:

    How can i use spacerbar in cmdchat?

    For this you need extra-shit work without sense in python to split strings, you can use a new CHAT_TYPE as i said in my first post.

    If you want for quest, then you have to do a new function like: (This is local function, just for you as player, if you want to send it for all players, let me know and i will post it)

    • notice_mission('Kill all the monsters without dying.")
    • notice_sub_mission("Kill all the monsters")

     

    • Just in source:
    Spoiler
    
    	ch->ChatPacket(CHAT_TYPE_MISSION, "Kill all the monsters without dying.");
    	ch->ChatPacket(CHAT_TYPE_SUB_MISSION, "Kill all the monsters.");
    	ch->ChatPacket(CHAT_TYPE_MISSION, "");

     

    • Src/game/game/src/questlua_global.cpp
    Spoiler
    
    //1.1) Search for:
    			{	"cmdchat",					_cmdchat				},
    //1.2) Add after:
    			{	"notice_mission",			_notice_mission			},
    			{	"notice_sub_mission",		_notice_sub_mission		},
    			
    //1.1) Search for:		
    	int _get_locale(lua_State* L)
    	{
    		lua_pushstring(L, g_stLocale.c_str());
    		return 1;
    	}
    //1.2) Add after:
    	int _notice_mission(lua_State* L)
    	{
    		ostringstream s;
    		combine_lua_string(L, s);
    		CQuestManager::Instance().GetCurrentCharacterPtr()->ChatPacket(CHAT_TYPE_MISSION, "%s", s.str().c_str());
    		return 0;
    	}
    
    	int _notice_sub_mission(lua_State* L)
    	{
    		ostringstream s;
    		combine_lua_string(L, s);
    		CQuestManager::Instance().GetCurrentCharacterPtr()->ChatPacket(CHAT_TYPE_SUB_MISSION, "%s", s.str().c_str());
    		return 0;
    	}

     

    • Src/game/common/length.h
    Spoiler
    
    //1.) Search for:
    	CHAT_TYPE_MONARCH_NOTICE,
    //1.2) Add after:
    #ifdef ENABLE_12ZI
    	CHAT_TYPE_MISSION,
    	CHAT_TYPE_SUB_MISSION,
    #endif

     

    • Src/Client/UserInterface/Packet.h
    Spoiler
    
    //1.) Search for:
    	CHAT_TYPE_MONARCH_NOTICE,
    //1.2) Add after:
    #ifdef ENABLE_12ZI
    	CHAT_TYPE_MISSION,
    	CHAT_TYPE_SUB_MISSION,
    #endif

     

    • Src/Client/UserInterface/PythonNetworkStreamPhaseGame.cpp
    Spoiler
    
    #ifdef ENABLE_12ZI
    		else if (CHAT_TYPE_MISSION == kChat.type)
    		{
    			if (uChatSize)
    				PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_SetMissionMessage", Py_BuildValue("(s)", buf));
    			else
    				PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_CleanMissionMessage", Py_BuildValue("()"));
    
    		}
    		else if (CHAT_TYPE_SUB_MISSION == kChat.type)
    		{
    			PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_SetSubMissionMessage", Py_BuildValue("(s)", buf));
    		}
    #endif

     

    @avertuss BTW, please stop to quote all of messages, looks very bad, you can use @tagname instead this.

    4 minutes ago, Masakra said:

    Hi, I'm search this function and c++ part:

    
    	def Over(self):
    		wndMgr.Over(self.hWnd)

     

    @Masakra This isn't a request topic for official functions, you can do it in this section Questions and Answers.

    • Love 3
  7. You can do this extension very easy.

    • root/game.py
    # Search for:
    		self.interface = interfaceModule.Interface()
    # Replace with:
    		self.interface = interfaceModule.Interface(self)
    • root/interfaceModule.py
    # Search for:
    	def __init__(self):
    		systemSetting.SetInterfaceHandler(self)
    # Replace with:
    	def __init__(self, wndGame):
    		self.wndGame = wndGame
    		systemSetting.SetInterfaceHandler(self)
    • root/uiInventory.py
    	# PrintButton
    	self.printButton = self.GetChild2("PrintButton")
    	if self.printButton:
    		self.printButton.SetEvent(ui.__mem_func__(self.ClickPrintButton))
    			
    	def ClickPrintButton(self):
    		wndGame = self.interface.wndGame
    		if wndGame:
    			wndGame.BINARY_SetBigMessage('click_print_button') # Function from game.py

     

     

    • Love 4
  8. On 11/18/2018 at 12:54 PM, Caramelito said:

    Will you reverse the noticebar aswell

    You can do it in a simple way.

    • root/interfaceModule.py
    Spoiler
    
    #1.1) Search for:
    		self.bigBoard = None
    #1.2) Add after:
    		if app.ENABLE_12ZI:
    			self.missionBoard = None
    
    #2.1) Search for:
    		self.bigBoard = uiTip.BigBoard()
    		self.bigBoard.Hide()
    #2.2) Add after:
    		if app.ENABLE_12ZI:
    			self.missionBoard = uiTip.MissionBoard()
    			self.missionBoard.Hide()
    
    #3.1) Search and delete:
    		self.__MakeTipBoard()
    
    #4.1) Search for:
    		self.__MakeMessengerWindow()
    #4.2) Add before:
    		self.__MakeTipBoard()	# ENABLE_12ZI Display it below the others ui.
    
    #5.1) Search for:
    		del self.wndItemSelect
    #5.2) Add after:
    		if app.ENABLE_12ZI:
    			del self.missionBoard

     

    • root/game.py
    Spoiler
    
    #1.1) Search for:
    	def BINARY_SetBigMessage(self, message):
    		self.interface.bigBoard.SetTip(message)
    #1.2) Add after:
    	if app.ENABLE_12ZI:
    		def BINARY_SetMissionMessage(self, message):
    			if self.interface:
    				self.interface.missionBoard.SetMission(message)
    			
    		def BINARY_SetSubMissionMessage(self, message):
    			if self.interface:
    				self.interface.missionBoard.SetSubMission(message)
    			
    		def BINARY_CleanMissionMessage(self):
    			if self.interface:
    				self.interface.missionBoard.CleanMission()

     

    • root/uiTip.py
    Spoiler
    
    #1.1) Search for:
    class BigTextBar(TextBar):
    	def __init__(self, width, height, fontSize):
    		ui.Window.__init__(self)
    		self.handle = grp.CreateBigTextBar(width, height, fontSize)
    
    	def __del__(self):
    		ui.Window.__del__(self)
    		grp.DestroyTextBar(self.handle)
    #1.2) Add after:
    if 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

     

    Now all what you need is to call them from server > client how you want.

    PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_SetMissionMessage", Py_BuildValue("(s)", "#MissionMessage"));	
    PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_SetSubMissionMessage", Py_BuildValue("(s)", "#SubMissionMessage"));
    PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_CleanMissionMessage", Py_BuildValue("()"));

    You can do a new CHAT_TYPE_UNKNOWN_NAME or like a command, depends of how you want to use it.

    • game/src/unknown_file.cpp
    Spoiler
    
    ChatPacket(CHAT_TYPE_COMMAND, "SetMissionMessage %s", "VS. Ending Soon");
    ChatPacket(CHAT_TYPE_COMMAND, "SetSubMission %s", "VS. is over. The world begins again under...");
    ChatPacket(CHAT_TYPE_COMMAND, "CleanMission");

     

    • UserInterface/PythonNetworkStreamCommand.cpp
    Spoiler
    
    #ifdef ENABLE_12ZI
    	else if (!strcmpi(szCmd, "SetMissionMessage"))
    	{
    		if (2 != TokenVector.size())
    		{
    			TraceError("CPythonNetworkStream::ServerCommand(c_szCommand=%s) - Strange Parameter Count : %s", c_szCommand);
    			return;
    		}
    
    		const std::string & c_rstrMessage = TokenVector[1].c_str();
    		PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_SetMissionMessage", Py_BuildValue("(s)", c_rstrMessage.c_str()));	
    	}
    	
    	else if (!strcmpi(szCmd, "SetSubMissionMessage"))
    	{
    		if (2 != TokenVector.size())
    		{
    			TraceError("CPythonNetworkStream::ServerCommand(c_szCommand=%s) - Strange Parameter Count : %s", c_szCommand);
    			return;
    		}
    
    		const std::string & c_rstrMessage = TokenVector[1].c_str();
    		PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_SetSubMissionMessage", Py_BuildValue("(s)", c_rstrMessage.c_str()));	
    	}
    	
    	else if (!strcmpi(szCmd, "CleanMissionMessage"))
    	{
    		PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_CleanMissionMessage", Py_BuildValue("()"));	
    	}
    #endif

     

     

    • Love 5
  9. M2 Download Center

    This is the hidden content, please
    ( Internal )

     

    Spoiler

    263356e98cc8a56a717c1fcd7b6326e438977e.g

     

    • root/uiRefine.py

    This is the hidden content, please

    • root/constInfo.py
    Spoiler
    # Showing description of item in refine window.
    ENABLE_REFINE_ITEM_DESCRIPTION = 1

     

    Another idea: (you don't have to use this, is just a example, can add in tooltip where you can drop items which you need, you can add a listbox+scrollbar and send drops from server and cache it in dictionary.)

     

    Spoiler

    263422qniZdab.png.c37eb8795af224c0094f86

     

    This is the hidden content, please

    • Metin2 Dev 128
    • Eyes 2
    • Dislove 1
    • Angry 1
    • Not Good 1
    • Smile Tear 1
    • Good 24
    • Love 4
    • Love 80
  10. You can try it like this.

    BOOL CActorInstance::TestActorCollision(CActorInstance & rVictim)
    {
    	[........................]
    	const std::string c_rstrAtlasMapNames[] =
    	{
    		"metin2_map_a1",
    		"metin2_map_a3",
    		"metin2_map_b1",
    		"metin2_map_b3",
    		"metin2_map_c1",
    		"metin2_map_c3",
    		"season2/metin2_map_skipia_dungeon_01",
    		"season2/metin2_map_skipia_dungeon_02",
    		"metin2_map_duel"
    	};
    	
    	const std::string & c_rstrMapName = CPythonBackground::Instance().GetWarpMapName();
    	for (size_t i = 0; i < _countof(c_rstrAtlasMapNames); ++i)
    	{
    		if (!c_rstrMapName.compare(c_rstrAtlasMapNames[i]))
    		{
    			if (rVictim.IsPC()) // IsNPC(), IsEnemy(), IsStone(), IsWarp(), IsGoto(), IsBuilding(), IsDoor(), IsObject()
    				return false;
    		}
    	}
    }

     

    • Love 1
  11. c517a1375e0a6974b55b8166621815d5.gif

    • Srcs\Server\game\src\shop.cpp
    //Search for:
        ch->Save();
    //Add after:
    #ifdef ENABLE_SHOP_AUTO_CLOSE
    	if (IsPCShop())
    	{
    		BYTE bShopItemCount = 0;
    		for (DWORD i = 0; i < m_itemVector.size() && i < SHOP_HOST_ITEM_MAX_NUM; ++i)
    		{
    			if (m_itemVector[i].pkItem)
    				++bShopItemCount;
    		}
    		
    		if (bShopItemCount == 0) // Last item
    		{
    			m_pkPC->CloseMyShop();
    			m_pkPC->ChatPacket(CHAT_TYPE_NOTICE, "Your store was closed automatically, reason: sold out.");
    		}
    	}
    #endif
    • Srcs\Server\common\service.h
    #define ENABLE_SHOP_AUTO_CLOSE

     

    • Love 2
  12. On 10/27/2018 at 6:33 AM, Saito said:

    better like this:

    Spoiler
    
    
    #ifdef __WEBZEN_CHANNEL_REMINDER__
    	if (ch->IsPC())
    	{
    		if (g_bChannel >= 1 && g_bChannel <= 8)
    		{
    			ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("SAITO_CHANNEL_REMINDER %d"), g_bChannel);
    		}
    		else
    		{
    			ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("SAITO_CHANNEL_REMINDER_GAME99"));
    		}
    	}
    #endif

     

     

    On 4/23/2017 at 5:05 PM, daradevil124 said:
    Spoiler
    
    
    quest channel_id begin
    	state start begin
    		when login begin
    		chat("You are connected to channel "..pc.get_channel_id()..".")
    		end
    	end
    end

     

     

    If I'm not mistaken, that's how it should work.

    • LUA
    -- gameforge.channel_reminder = {}
    -- gameforge.channel_reminder._010_syschat = "You're connected to channel %d."
    
    quest channel_reminder begin
        state start begin
            when login begin
                local channelID = pc.get_channel_id()
                syschat(string.format(gameforge.channel_reminder._010_syschat, (channelID == 99 and 0 or channelID)))
            end
        end
    end
    • Source
    // "CHANNEL_REMINDER_SYSCHAT";
    // "You're connected to channel %d.";
    
    ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("CHANNEL_REMINDER_SYSCHAT"), g_bChannel == 99 ? 0 : g_bChannel);

     

    • Love 2
  13. For quest already exist a option.

    say(string.format("[ITEM value;%d]", 189)) -- c_item_name(vnum)
    say(string.format("[MOB value;%d]", 20091)) -- c_mob_name(vnum)
    • EVENT_TYPE_ITEM_NAME
    • EVENT_TYPE_MONSTER_NAME
    Spoiler
    
    		case EVENT_TYPE_ITEM_NAME:
    		{
    			int iIndex = atoi(GetArgument("value", ScriptCommand.argList));
    			CItemData * pItemData;
    			if (CItemManager::Instance().GetItemDataPointer(iIndex, &pItemData))
    			{
    				pEventSet->strCurrentLine.append(pItemData->GetName());
    				pEventSet->pCurrentTextLine->SetValue(pEventSet->strCurrentLine.c_str());
    				pEventSet->pCurrentTextLine->SetColor(1.0f, 0.2f, 0.2f);
    				pEventSet->iCurrentLetter+= strlen(pItemData->GetName());
    
    				if (pEventSet->iCurrentLetter >= pEventSet->iRestrictedCharacterCount)
    					__InsertLine(*pEventSet);
    
    				pEventSet->lLastDelayTime = pEventSet->lWaitingTime;
    			}
    
    			break;
    		}
    		case EVENT_TYPE_MONSTER_NAME:
    		{
    			int iIndex = atoi(GetArgument("value", ScriptCommand.argList));
    			const char * c_szName;
    
    			CPythonNonPlayer& rkNonPlayer=CPythonNonPlayer::Instance();
    			if (rkNonPlayer.GetName(iIndex, &c_szName))
    			{
    				pEventSet->strCurrentLine.append(c_szName);
    				pEventSet->pCurrentTextLine->SetValue(pEventSet->strCurrentLine.c_str());
    				pEventSet->iCurrentLetter+= strlen(c_szName);
    
    				if (pEventSet->iCurrentLetter >= pEventSet->iRestrictedCharacterCount)
    					__InsertLine(*pEventSet);
    
    				pEventSet->lLastDelayTime = pEventSet->lWaitingTime;
    			}

     

     

    • Love 2
  14. http://listofrandomnames.com/index.cfm?textarea

    3xE3cab.png

     

    I would like to do something like that and can be used very easy for multiple languages too. 'locale/xx/names.list'

    • localeInfo.py

    This is the hidden content, please

    • any_file.py
    • self.textLine.SetText(localeInfo.GetRandomName())
    Spoiler
    
    import localeInfo
    class TextLine(ui.TextLine):
    	def __init__(self):
    		ui.TextLine.__init__(self)
    
    		self.SetParent(self)
    		self.SetPosition(0, 15)
    		self.SetFeather()
    		self.SetFontName("Tahoma:20")
    		self.SetPackedFontColor(0xffcfcc57)
    
    	def __del__(self):
    		ui.TextLine.__del__(self)
    		
    	def __OnToggleButton(self):
    		self.SetText(localeInfo.GetRandomName())
    • Output:
    Spoiler
    
    0907 04:17:05267 :: Antonina
    0907 04:17:05532 :: Magaret
    0907 04:17:05731 :: Hayden
    0907 04:17:05910 :: Jospeh
    0907 04:18:06075 :: Portia
    0907 04:18:06239 :: Chanell
    0907 04:18:06406 :: Miguelina
    0907 04:18:06554 :: Darwin
    0907 04:18:06834 :: Armanda
    0907 04:18:06982 :: Tamekia
    0907 04:18:07115 :: Shera
    0907 04:18:07281 :: Santiago
    0907 04:18:07445 :: Caryl
    0907 04:18:07593 :: Guillermo
    0907 04:18:07758 :: Taisha
    0907 04:18:07924 :: Jenifer
    0907 04:18:08073 :: Diedre
    0907 04:18:08237 :: Asha
    0907 04:18:08418 :: Leone
    0907 04:18:08567 :: Floyd

     

    Download 1000 random names:

    • Metin2 Dev 5
    • Good 1
    • Love 6
  15. That's the single method which is correctly.

    c5ce630f7703c1a66e42f33d825b31e8.gif

    quest test_quest begin
    	state start begin
    		when 20091.chat.string.format("DBG: name(%s), level(%d).", pc.get_name(), pc.get_level()) begin
    			say_title("I'm a potato!")
    		end
    	end
    end

    New quest core: /src/share/locale/germany/quest < qc

    • Metin2 Dev 2
    • Good 2
    • Love 4
  16. I didn't test it, but you can try.

    //@Srcs\Client\UserInterface\InstanceBase.cpp
    //@bool CInstanceBase::IsAttackableInstance(CInstanceBase& rkInstVictim)
    //Search for:
    	if (GetVirtualID() == rkInstVictim.GetVirtualID())
    		return false;
    //Add after:
    	if (IsPC() && rkInstVictim.IsPC())
    	{
    		const std::string & c_rstrMapFileName = CPythonBackground::Instance().GetWarpMapName();
    		if (!c_rstrMapFileName.compare("MAP_NAME"))
    			return true;
    	}
    	
    //@Srcs\Server\game\src\pvp.cpp
    //bool CPVPManager::CanAttack(LPCHARACTER pkChr, LPCHARACTER pkVictim)
    //Search for:
    	if (pkChr == pkVictim)
    		return false;
    //Add after:
    	if (pkChr->GetMapIndex() == MAP_INDEX)
    		return true;

     

    • Love 2
  17. 1 hour ago, Ken said:

    Webzen didn't create a new function to return m_FriendNameMap. They just make m_FriendNameMap public. (It was protected before). Also, you can use const_iterator instead of iterator. (You're not modifying it.)

    I was thinking of this way too, but i'm was so bored to remake tutorial for replace protected m_FriendNameMap with public one <_<, because i did it some months ago just for mailbox. 

    Spoiler

    i9gtfab.png

     

×
  • 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.