Jump to content

Recommended Posts

  • Premium

This is the hidden content, please

Metin2 Download

The files contain the server side and quests example.

Video: https://metin2.download/video/tMwmR3u7195gtv0qYh0w0ceE5aIkbJdo/.mp4 (yes, at the end the Biologist doesn't give me the rewards because I forgot to change a condition in the quest and I didn't wanna try to record it, again)

So where is the interface file?

I am sorry but I don't have any way to set up an interface for the original sources of the Client. I can share the logic I used:

import ui
import app
import localeInfo
import item
import colorInfo
import net
import uiCommon
import player
import chat
class uiResearchWindow(ui.ScriptWindow):

	BIOLOGIST_QUEST_DICT = {
		0 : { 'item_wanted': 30006, 'pct' : 90, 'required': 20 },
		1 : { 'item_wanted': 30055, 'pct' : 90, 'required': 20 },
		2 : { 'item_wanted': 30047, 'pct' : 90, 'required': 20 },
		3 : { 'item_wanted': 30324, 'pct' : 90, 'required': 25 },
		4 : { 'item_wanted': 30015, 'pct' : 90, 'required': 20 },
		5 : { 'item_wanted': 30050, 'pct' : 90, 'required': 25 },
		6 : { 'item_wanted': 30198, 'pct' : 44, 'required': 30 },
		7 : { 'item_wanted': 30166, 'pct' : 42, 'required': 35 },
		8 : { 'item_wanted': 30495, 'pct' : 30, 'required': 15 },
		9 : { 'item_wanted': 100029, 'pct' : 38, 'required': 40 },
		10 : { 'item_wanted': 30329, 'pct' : 36, 'required': 45 },
		11 : { 'item_wanted': 100039, 'pct' : 34, 'required': 50 },
	}

	MAX_ITEM_QUANTITY = 5
	PCT_BONUS = 10
	PCT_BONUS_PLUS = 30

	BIOLOGIST_PCT_ADDER_VNUM = 102529
	BIOLOGIST_PCT_ADDER_PLUS_VNUM = 102616
	BIOLOGIST_TIME_DELETER_VNUM = 102517

	def __init__(self):
		ui.ScriptWindow.__init__(self)
		self.remainTime = 0
		self.receivedTime = app.GetTime()
		self.remainTimeText = None
		self.questID = 0
		self.itemRequestedText = None
		self.pctSuccessText = None
		self.lastCountDownRefresh = 0
		self.itemToDeliverCount = 1
		self.itemToDeliverVnum = 0
		self.questionDialog = None
		self.popupDialog = None
		self.deliveredItemsQty = 0
		self.isOpened = False
		self.LoadWindow()

	def __del__(self):
		self.remainTime = 0
		self.questID = 0
		self.itemRequestedText = None
		self.pctSuccessText = None
		self.lastCountDownRefresh = 0
		self.itemToDeliverVnum = 0
		self.questionDialog = None
		self.popupDialog = None
		self.isOpened = False
		self.tooltipItem = 0
		ui.ScriptWindow.__del__(self)

	def LoadWindow(self):
		try:
			PythonScriptLoader = ui.PythonScriptLoader()
			PythonScriptLoader.LoadScriptFile(self, "UIScript/researchwindow.py")

		except:
			import exception
			exception.Abort("ResearchWindow.LoadWindow.LoadUIScriptFiles")

		try:
			self.board = self.GetChild("board")
			self.remainTimeText = self.GetChild("ItemCDText")
			self.itemRequestedText = self.GetChild("ItemNametext")
			self.pctSuccessText = self.GetChild("ItemPctText")
			self.buttonTimeDeleterUP = self.GetChild("UpButton1")
			self.itemTimeDeleterTextqty = self.GetChild("ItemSlotbar1Text")
			self.buttonTimeDeleterDown = self.GetChild("DownButton1")

			self.buttonElixirUP = self.GetChild("UpButton2")
			self.buttonElixirTextQty = self.GetChild("ItemSlotbar2Text")
			self.buttonElixirDown = self.GetChild("DownButton2")

			self.buttonElixirPlusUP = self.GetChild("UpButton3")
			self.buttonElixirPlusTextQty = self.GetChild("ItemSlotbar3Text")
			self.buttonElixirPlusDown = self.GetChild("DownButton3")

			self.itemWanted = self.GetChild("current_item")
			self.itemWantedButtonUP = self.GetChild("UpButton0")
			self.itemWantedButtonText = self.GetChild("ItemSlotbar0Text")
			self.itemWantedButtonDown = self.GetChild("DownButton0")

			self.deliverItemButton = self.GetChild("exam_button")
			self.deliveredItemsText = self.GetChild("textItemDeliverdQty")
			self.notifySlot = self.GetChild("NotifySlot")

			self.elixirSlot = self.GetChild("elisir_10_slot")
			self.elixirPlusSlot = self.GetChild("elisir_30_slot")
			self.timeDeleterSlot = self.GetChild("time_deleter_slot")


		except:
			import exception
			exception.Abort("ResearchWindow.LoadWindow.BindObject")

		self.board.SetCloseEvent(ui.__mem_func__(self.Close))

		self.buttonTimeDeleterUP.SAFE_SetEvent(self.__OnClickButtonTimeDeleterUP)
		self.buttonTimeDeleterDown.SAFE_SetEvent(self.__OnClickButtonTimeDeleterDown)

		self.buttonElixirUP.SAFE_SetEvent(self.__OnClickbuttonElixirUP)
		self.buttonElixirDown.SAFE_SetEvent(self.__OnClickbuttonElixirDown)

		self.buttonElixirPlusUP.SAFE_SetEvent(self.__OnClickbuttonElixirPlusUP)
		self.buttonElixirPlusDown.SAFE_SetEvent(self.__OnClickbuttonElixirPlusDown)

		self.itemWantedButtonUP.SAFE_SetEvent(self.__OnClickButtonItemWantedUP)
		self.itemWantedButtonDown.SAFE_SetEvent(self.__OnClickButtonItemWantedDown)
		self.deliverItemButton.SAFE_SetEvent(self.__OnClickDeliverButton)


		item.SelectItem(self.BIOLOGIST_PCT_ADDER_VNUM)
		itemName = item.GetItemName()				
		self.pctAdderName = itemName
		item.SelectItem(self.BIOLOGIST_PCT_ADDER_PLUS_VNUM)
		itemName = item.GetItemName()		
		self.pctAdderPlusName = itemName
		item.SelectItem(self.BIOLOGIST_TIME_DELETER_VNUM)
		itemName = item.GetItemName()		
		self.timeDeleterName = itemName		

	def SendDeliverPacket(self):
		net.SendBiologistManagerDeliverCommand(self.questID, self.itemToDeliverCount,\
			int(self.buttonElixirTextQty.GetText()), int(self.buttonElixirPlusTextQty.GetText()),\
			int(self.itemTimeDeleterTextqty.GetText()))


	def CanSendRequest(self):
		elixirPlayerCount = player.GetItemCountByVnum(self.BIOLOGIST_PCT_ADDER_VNUM)
		elixirPlusPlayerCount = player.GetItemCountByVnum(self.BIOLOGIST_PCT_ADDER_PLUS_VNUM)
		timeDeleterPlayerCount = player.GetItemCountByVnum(self.BIOLOGIST_TIME_DELETER_VNUM)
		itemToDeliverPlayerCount = player.GetItemCountByVnum(self.itemToDeliverVnum)
		if self.itemToDeliverCount > itemToDeliverPlayerCount or \
		int(self.buttonElixirTextQty.GetText()) > elixirPlayerCount or\
		int(self.buttonElixirPlusTextQty.GetText()) > elixirPlusPlayerCount or\
		int(self.itemTimeDeleterTextqty.GetText()) > timeDeleterPlayerCount:
			self.popupDialog = uiCommon.PopupDialog()
			self.popupDialog.SetText(localeInfo.BIOLOGIST_MANAGER_OVERFLOW_ERROR)
			self.popupDialog.SetAcceptEvent(self.__OnClosePopupDialog)
			self.popupDialog.Open()
			return False
		elif self.GetRemainTime() > 0 and int(self.itemTimeDeleterTextqty.GetText()) <= 0:
			self.popupDialog = uiCommon.PopupDialog()
			self.popupDialog.SetText(localeInfo.BIOLOGIST_MANAGER_TIME_ERROR)
			self.popupDialog.SetAcceptEvent(self.__OnClosePopupDialog)
			self.popupDialog.Open()			
		else:
			return True

	def __OnClickDeliverButton(self):
		if self.pct > 100:
			self.questionDialog = uiCommon.QuestionDialog()
			self.questionDialog.Open()
			self.questionDialog.SetText(localeInfo.BIOLOGIST_MANAGER_CHECK_PCT)
			self.questionDialog.SetAcceptText(localeInfo.UI_ACCEPT)
			self.questionDialog.SetCancelText(localeInfo.UI_DENY)
			self.questionDialog.SetAcceptEvent(lambda arg = True: self.QuestionDialogAnswer(arg))
			self.questionDialog.SetCancelEvent(lambda arg = False: self.QuestionDialogAnswer(arg))
			self.questionDialog.SetTop()
		else:
			if self.CanSendRequest() == True:
				self.SendDeliverPacket()
				

	def __OnClosePopupDialog(self):
		self.popupDialog = None
		
	def QuestionDialogAnswer(self, answer):
		if not self.questionDialog:
			return

		if answer == True:
			if self.CanSendRequest() == True:
				self.SendDeliverPacket()

		self.questionDialog.Close()
		self.questionDialog = None

	def __OnClickButtonItemWantedUP(self):
		if self.itemToDeliverCount >= self.MAX_ITEM_QUANTITY:
			chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.BIOLOGIST_MANAGER_ITEMS_OVERFLOW % (str(self.MAX_ITEM_QUANTITY), self.itemName))
			return
		if self.itemToDeliverCount + 1 > player.GetItemCountByVnum(self.itemToDeliverVnum):
			chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.BIOLOGIST_manager_NOT_ENOUGH_ITEMS % (str(self.MAX_ITEM_QUANTITY), self.itemName))
			return				
		self.itemToDeliverCount += 1
		self.itemWantedButtonText.SetText(str(self.itemToDeliverCount))

	def __OnClickButtonItemWantedDown(self):
		if self.itemToDeliverCount <= 1:
			return		
		self.itemToDeliverCount -= 1
		self.itemWantedButtonText.SetText(str(self.itemToDeliverCount))

	def __OnClickButtonTimeDeleterUP(self):
		number = int(self.itemTimeDeleterTextqty.GetText())
		if number >= self.MAX_ITEM_QUANTITY: 
			chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.BIOLOGIST_MANAGER_ITEMS_OVERFLOW % (str(self.MAX_ITEM_QUANTITY), self.timeDeleterName))
			return
		if number + 1 > player.GetItemCountByVnum(self.BIOLOGIST_TIME_DELETER_VNUM):
			chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.BIOLOGIST_manager_NOT_ENOUGH_ITEMS % (str(self.MAX_ITEM_QUANTITY), self.timeDeleterName))
			return	
		self.itemTimeDeleterTextqty.SetText(str(number+1))
		self.UpdatePct()

	def __OnClickButtonTimeDeleterDown(self):
		number = int(self.itemTimeDeleterTextqty.GetText())
		if number <= 0:
			return
		self.itemTimeDeleterTextqty.SetText(str(number-1))
		self.UpdatePct()

	def __OnClickbuttonElixirUP(self):		
		number = int(self.buttonElixirTextQty.GetText())
		if number >= self.MAX_ITEM_QUANTITY:
			chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.BIOLOGIST_MANAGER_ITEMS_OVERFLOW % (str(self.MAX_ITEM_QUANTITY), self.pctAdderName))
			return
		if number + 1 > player.GetItemCountByVnum(self.BIOLOGIST_PCT_ADDER_VNUM):
			chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.BIOLOGIST_manager_NOT_ENOUGH_ITEMS % (str(self.MAX_ITEM_QUANTITY), self.pctAdderName))
			return				
		self.buttonElixirTextQty.SetText(str(number+1))
		self.UpdatePct()

	def __OnClickbuttonElixirDown(self):
		number = int(self.buttonElixirTextQty.GetText())
		if number <= 0:
			return
		self.buttonElixirTextQty.SetText(str(number-1))
		self.UpdatePct()

	def __OnClickbuttonElixirPlusUP(self):
		number = int(self.buttonElixirPlusTextQty.GetText())
		if number >= self.MAX_ITEM_QUANTITY:
			chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.BIOLOGIST_MANAGER_ITEMS_OVERFLOW % (str(self.MAX_ITEM_QUANTITY), self.pctAdderPlusName))
			return
		if number + 1 > player.GetItemCountByVnum(self.BIOLOGIST_PCT_ADDER_PLUS_VNUM):
			chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.BIOLOGIST_manager_NOT_ENOUGH_ITEMS % (str(self.MAX_ITEM_QUANTITY), self.pctAdderPlusName))
			return			
		self.buttonElixirPlusTextQty.SetText(str(number+1))
		self.UpdatePct()

	def __OnClickbuttonElixirPlusDown(self):
		number = int(self.buttonElixirPlusTextQty.GetText())
		if number <= 0:
			return
		self.buttonElixirPlusTextQty.SetText(str(number-1))
		self.UpdatePct()
		
	def GetRemainTime(self):
		return self.remainTime - (app.GetTime() - self.receivedTime)

	def ResearchRequestInfo(self, deliversCounter, successDeliveries, failedDeliveries, timeDeleterUses, elixirUses, elixirPlusUses, remainingTime):
		self.remainTime = remainingTime
		self.deliveredItemsQty += successDeliveries
		self.deliveredItemsText.SetText(str(self.deliveredItemsQty) + "/" + str(self.BIOLOGIST_QUEST_DICT[self.questID]['required']))
		self.itemWanted.SetItemSlot(0, self.itemToDeliverVnum, player.GetItemCountByVnum(self.itemToDeliverVnum))
		text = ""
		
		if failedDeliveries == 1:
			text = localeInfo.BIOLOGIST_SYSTEM_MESSAGE_SINGLE_FAIL % (deliversCounter, self.itemName, successDeliveries, failedDeliveries, self.pctAdderName, elixirUses, self.pctAdderPlusName, elixirPlusUses, self.timeDeleterName, timeDeleterUses)
		else:
			text = localeInfo.BIOLOGIST_SYSTEM_MESSAGE_MULTIPLE_FAIL % (deliversCounter, self.itemName, successDeliveries, failedDeliveries, self.pctAdderName, elixirUses, self.pctAdderPlusName, elixirPlusUses, self.timeDeleterName, timeDeleterUses)
		self.multiHolder = ui.GenerateMultiLine(self.notifySlot, text, 300, colorInfo.GOLD)
		for i in self.multiHolder:
			totalH = self.multiHolder[0].GetTextSize()[1] * len(self.multiHolder) + 3 * (len(self.multiHolder) - 1)
			i.SetPosition(3, 80 / 2 - totalH / 2 + 3 * self.multiHolder.index(i) + i.GetTextSize()[1] * self.multiHolder.index(i))
		self.UpdateSlots()	

	def UpdateInfo(self, questID, remain_time, deliveredItems):
		self.remainTime = remain_time
		self.questID = questID
		self.itemToDeliverVnum = self.BIOLOGIST_QUEST_DICT[questID]['item_wanted']
		self.deliveredItemsQty = deliveredItems
		self.deliveredItemsText.SetText(str(self.deliveredItemsQty) + "/" + str(self.BIOLOGIST_QUEST_DICT[self.questID]['required']))
		item.SelectItem(self.itemToDeliverVnum)
		self.itemName = item.GetItemName()
		self.itemRequestedText.SetText(self.itemName)
		self.itemWanted.SetItemSlot(0, self.itemToDeliverVnum, player.GetItemCountByVnum(self.itemToDeliverVnum))
		self.UpdatePct()
		self.UpdateTimer()

	def UpdatePct(self):
		elixir_qty = int(self.buttonElixirTextQty.GetText())
		elixir_plus_qty = int(self.buttonElixirPlusTextQty.GetText())
		if elixir_qty > 0 and elixir_plus_qty > 0:
			self.pct = self.BIOLOGIST_QUEST_DICT[self.questID]['pct'] + self.PCT_BONUS + self.PCT_BONUS_PLUS
		elif elixir_qty > 0:
			self.pct = self.BIOLOGIST_QUEST_DICT[self.questID]['pct'] + self.PCT_BONUS
		elif elixir_plus_qty > 0:
			self.pct = self.BIOLOGIST_QUEST_DICT[self.questID]['pct'] + self.PCT_BONUS_PLUS
		elif elixir_qty <= 0 and elixir_plus_qty <= 0:
			self.pct = self.BIOLOGIST_QUEST_DICT[self.questID]['pct']
		elif elixir_qty <= 0:
			self.pct -= self.PCT_BONUS
		elif elixir_plus_qty <= 0:
			self.pct -= self.PCT_BONUS_PLUS
		self.pctSuccessText.SetText(str(self.pct) + "%")

	def OnUpdate(self):
		if app.GetTime() <= self.lastCountDownRefresh + 1.0:
			return

		self.lastCountDownRefresh = app.GetTime()
		self.UpdateTimer()

	def UpdateTimer(self):
		remain_time = self.GetRemainTime()
		if remain_time <= 0:
			self.remainTimeText.SetPackedFontColor(colorInfo.GREEN)
			self.remainTimeText.SetText(localeInfo.BIOLOGIST_MANAGER_CAN_DELIVER)
		else:
			self.remainTimeText.SetPackedFontColor(colorInfo.RED)
			self.remainTimeText.SetText("%s" % (str(localeInfo.SecondsToClock(remain_time))))

	def SetItemToolTip(self, tooltipItem):
		self.tooltipItem = tooltipItem

	def OverInItem(self, itemVnum):
		if not self.tooltipItem:
			return

		self.tooltipItem.ClearToolTip()
		metinSlot = []
		for i in range(player.METIN_SOCKET_MAX_NUM):
			metinSlot.append(0)
		attrSlot = []
		for i in range(player.ATTRIBUTE_SLOT_MAX_NUM):
			attrSlot.append((0, 0, 0))
		realValue = []
		for i in range(player.REAL_VALUES_MAX_NUM):
			realValue.append(0)
			
		self.tooltipItem.AddItemData(itemVnum, metinSlot, attrSlot, realValue)

	def OverOutItem(self):
		if 0 != self.tooltipItem:
			self.tooltipItem.HideToolTip()

	def UpdateSlots(self):
		self.elixirSlot.SetItemSlot(0, self.BIOLOGIST_PCT_ADDER_VNUM, player.GetItemCountByVnum(self.BIOLOGIST_PCT_ADDER_VNUM))
		self.elixirPlusSlot.SetItemSlot(0, self.BIOLOGIST_PCT_ADDER_PLUS_VNUM, player.GetItemCountByVnum(self.BIOLOGIST_PCT_ADDER_PLUS_VNUM))
		self.timeDeleterSlot.SetItemSlot(0, self.BIOLOGIST_TIME_DELETER_VNUM, player.GetItemCountByVnum(self.BIOLOGIST_TIME_DELETER_VNUM))
		self.itemWanted.SetItemSlot(0, self.itemToDeliverVnum, player.GetItemCountByVnum(self.itemToDeliverVnum))

	def SetSlotsEvents(self):
		self.elixirSlot.SetEvent(ui.SLOT_OVER_IN_ITEM, self.OverInItem, self.BIOLOGIST_PCT_ADDER_VNUM)
		self.elixirPlusSlot.SetEvent(ui.SLOT_OVER_IN_ITEM, self.OverInItem, self.BIOLOGIST_PCT_ADDER_PLUS_VNUM)
		self.timeDeleterSlot.SetEvent(ui.SLOT_OVER_IN_ITEM, self.OverInItem, self.BIOLOGIST_TIME_DELETER_VNUM)

		self.elixirSlot.SetEvent(ui.SLOT_OVER_OUT_ITEM, self.OverOutItem)
		self.elixirPlusSlot.SetEvent(ui.SLOT_OVER_OUT_ITEM, self.OverOutItem)
		self.timeDeleterSlot.SetEvent(ui.SLOT_OVER_OUT_ITEM, self.OverOutItem)

		
		self.itemWanted.SetEvent(ui.SLOT_OVER_IN_ITEM, self.OverInItem, self.itemToDeliverVnum)
		self.itemWanted.SetEvent(ui.SLOT_OVER_OUT_ITEM, self.OverOutItem)

	def Open(self, questID, remainTime, deliveredItems):
		self.UpdateInfo(questID, remainTime, deliveredItems)
		self.UpdateSlots()
		self.SetSlotsEvents()
		self.Show()
		self.isOpened = True

	def IsOpened(self):
		return self.isOpened

	def Close(self, isOpened = True):
		if self.tooltipItem:
			self.tooltipItem.ClearToolTip()
		self.isOpened = isOpened
		self.Hide()
	
	def Destroy(self):
		self.ClearDictionary()
		if self.tooltipItem:
			self.tooltipItem.ClearToolTip()
		self.remainTime = 0
		self.remainTimeText = None
		self.questID = 0
		self.itemRequestedText = None
		self.pctSuccessText = None
		self.lastCountDownRefresh = 0
		self.itemToDeliverVnum = 0
		self.questionDialog = None
		self.tooltipItem = 0
		self.popupDialog = None
		

	def OnPressEscapeKey(self):
		self.Close()
		return True

Don't just copy and paste it, it won't work because of:

		realValue = []
		for i in range(player.REAL_VALUES_MAX_NUM):
			realValue.append(0)
			
		self.tooltipItem.AddItemData(itemVnum, metinSlot, attrSlot, realValue)

or the whole SetSlotsEvents function:

	def SetSlotsEvents(self):
		self.elixirSlot.SetEvent(ui.SLOT_OVER_IN_ITEM, self.OverInItem, self.BIOLOGIST_PCT_ADDER_VNUM)
		self.elixirPlusSlot.SetEvent(ui.SLOT_OVER_IN_ITEM, self.OverInItem, self.BIOLOGIST_PCT_ADDER_PLUS_VNUM)
		self.timeDeleterSlot.SetEvent(ui.SLOT_OVER_IN_ITEM, self.OverInItem, self.BIOLOGIST_TIME_DELETER_VNUM)

		self.elixirSlot.SetEvent(ui.SLOT_OVER_OUT_ITEM, self.OverOutItem)
		self.elixirPlusSlot.SetEvent(ui.SLOT_OVER_OUT_ITEM, self.OverOutItem)
		self.timeDeleterSlot.SetEvent(ui.SLOT_OVER_OUT_ITEM, self.OverOutItem)

		
		self.itemWanted.SetEvent(ui.SLOT_OVER_IN_ITEM, self.OverInItem, self.itemToDeliverVnum)
		self.itemWanted.SetEvent(ui.SLOT_OVER_OUT_ITEM, self.OverOutItem)

If you make one, please feel free to share, I'll update the topic and give you credits.

 

Why do you require to go back to the biologist instead of doing everything from the interface?

Two reasons:

  • it's based on my server where we want the player to go back to the biologist.
  • there's already people selling that type of interface, if you so prefer

 

 

The system requires c++20 (serverside)

But I have C++17, what do I do then?

Remove the constness from std::array(older version) and std::view_string, therefore even on the loop(older version):

	for(const auto& val : BiologistQuestNames) //here remove const
	{
		if(IsQuestStatusFindItem(ch, val) == true){
			SendBiologistManagerOpenCommand(ch, iterVal);
			return true;
		}
		++iterVal;
	}

But I have C++14/C+11, what do I do then?

Remove std::view_string and use either std::string or const char* and replace:

utils::view_to_string(BiologistQuestStateCollect);

with whatever is the way to convert a const char* to std::string (if you use const char*) https://stackoverflow.com/questions/24127946/converting-a-const-char-to-stdstring

Remove also the namespace on top:

//TO REMOVE
namespace utils{
	std::string string_view_concat(std::string_view a, std::string_view b){

		std::string rv(a.size() + b.size(), '\0');

		std::copy(b.begin(), b.end(),
				std::copy(a.begin(), a.end(), rv.begin()));

		return rv;
	}

	std::string view_to_string(std::string_view a){
		std::string st = {a.begin(), a.end()};
		return st;
	}
}

the concat function can be replaced with the + operator (both have to be strings, not const* char):

std::string new_string = old_string + string_to_concat;

I still use C++98/03

Don't bother downloading these files.

I want to set the cooldown even when some one fails, not only on success, how can I do that?

Replace:

			else{ //set cooldown for success delivery
				pPC->SetFlag(timerFlag, get_global_time() + BiologistQuestCooldowns.at(questID));
				++successDeliveries;
			}
		}
		else{ //fail, but we don't set the cooldown for failing
			itemToDeliver->SetCount(itemToDeliver->GetCount() - 1); //remove the item to deliver
			pPC->SetFlag(timerFlag, 0);
			++failedDeliveries;
		}

with:

			else{ //set cooldown for success delivery
				pPC->SetFlag(timerFlag, get_global_time() + BiologistQuestCooldowns.at(questID));
				++successDeliveries;
			}
		}
		else{ //fail, but we don't set the cooldown for failing
			itemToDeliver->SetCount(itemToDeliver->GetCount() - 1); //remove the item to deliver
			pPC->SetFlag(timerFlag, get_global_time() + BiologistQuestCooldowns.at(questID));
			++failedDeliveries;
		}

 

What if I don't wanna use elixirs, time deleter or something else?

Try yourself first, if you encounter any error during your endeavour, just ask (don't be afraid to ask, people might help you).

Why the double checks in the client AND the server?????

I'll never forget: "what if they craft the packet?" "...fudge. Unlikely, but you are right."

Is it bug free???

I'll never make such claims, if you find some, please report them

Edited by Intel
Core X - External 2 Internal
  • Metin2 Dev 91
  • Good 19
  • Love 2
  • Love 48
Link to comment
https://metin2.dev/topic/29513-biologist-manager-c-lua/
Share on other sites

  • 3 months later...
  • Premium
On 12/4/2022 at 5:49 AM, garofolo said:

basically every system is based on the python part and he posted incomplete


uiscript part?
 

as I said:

Quote

I am sorry but I don't have any way to set up an interface for the original sources of the Client. I can share the logic I used:

uiscript I thought it could be made from the video, and something has to be edited from mine (same reasons, different sources, different stuff):

import uiScriptLocale
import colorInfo

TASKBAR = "d:/ymir work/ui/taskbar/"

window = {
	"name" : "ResearchWindow",

	"x" : 100,
	"y" : 20,

	"style" : ("movable", "float","limit",),

	"width" : 330,
	"height" : 330,

	"children" :
	(
		{
			"name" : "board",
			"type" : "board_with_titlebar",

			"x" : 0,
			"y" : 0,

			"width" : 330,
			"height" : 330,

			"title": uiScriptLocale.RESEARCH_TITLE,

			"children" :
			(
				{
					"name" : "thinboardAllContainer",
					"type" : "thinboard",

					"x" : 7,
					"y" : 27,
					
					"width" : 316,
					"height" : 296,
				
					
					"style" : ["not_pick"],
					
					"children" :
					(
						{
							"name" : "thinboardDeliverContainer",
							"type" : "thinboard",

							"x" : 5,
							"y" : 5,
							
							"width" : 306,
							"height" : 116,
						
							
							"style" : ["not_pick"],
							"children" :
							(
								{
									"name" : "current_item",
									"type" : "grid_table",

									"x" : 31,
									"y" : 34,

									"start_index" : 0,
									"x_count" : 1,
									"y_count" : 1,
									"x_step" : 32,
									"y_step" : 32,

									"image" : "d:/ymir work/ui/public/Slot_Base.sub",
								},
								{
									"name" : "UpButton0",
									"type" : "button",
									"tooltip_text" : uiScriptLocale.RESEARCH_UP,
									"x" : 31-4,
									"y" : 34+32+2,
									"default_image" : TASKBAR + "pageup.sub",
									"over_image" : TASKBAR + "pageup_over.sub",
									"down_image" : TASKBAR + "pageup_click.sub",
								},
								{
									"name" : "DownButton0",
									"type" : "button",
									"tooltip_text" : uiScriptLocale.RESEARCH_DOWN,

									"x" : 31-4,
									"y" : 34+32+12,

									"default_image" : TASKBAR + "pagedown.sub",
									"over_image" : TASKBAR + "pagedown_over.sub",
									"down_image" : TASKBAR + "pagedown_click.sub",
								},
								{ 
									"name":"ItemSlotbar0", 
									"type":"slotbar", 
									"x":40, 
									"y":34+36, 
									"preset":"parameter_slot_09", 
									"children" :
									(
										{ "name":"ItemSlotbar0Text", "type":"text", "x":1, "y":2, "text":"1", "r":1.0, "g":1.0, "b":1.0, "a":1.0, "text_horizontal_align":"center", "horizontal_align":"center"},
									),
								},
								{
									"name" : "textItemName",
									"type" : "text",

									"x" : 111 - 27,
									"y" : 18,
									
									
									"color" : colorInfo.FONT_COLOR, 
									"fontsize":"middle",
									
									"text" : uiScriptLocale.RESEARCH_OBJECT,
									
									"style" : ["not_pick"],
								},
								{
									"name" : "ItemNametext",
									"type" : "text",

									"x" : 111 - 27 + 84,
									"y" : 18,
									
									
									"color" : colorInfo.GOLD_COLOR, 
									"fontsize":"middle",
									
									"text" : uiScriptLocale.RESEARCH_OBJECT,
									
									"style" : ["not_pick"],
								},
								{
									"name" : "textItemDeliverd",
									"type" : "text",

									"x" : 111 - 27,
									"y" : 18 + 16,
									
									
									"color" : colorInfo.FONT_COLOR, 
									"fontsize":"middle",
									
									"text" : uiScriptLocale.RESEARCH_DELIVERED,
									
									"style" : ["not_pick"],
								},
								{
									"name" : "textItemDeliverdQty",
									"type" : "text",

									"x" : 111 - 27 + 55,
									"y" : 18 + 16,
									
									
									"color" : colorInfo.GOLD_COLOR, 
									"fontsize":"middle",
									
									"text" : "0/0",
									
									"style" : ["not_pick"],
								},								
								{
									"name" : "textItemPct",
									"type" : "text",

									"x" : 111 - 27,
									"y" : 18 + 16 * 2,
									
									
									"color" : colorInfo.FONT_COLOR, 
									"fontsize":"middle",
									
									"text" : uiScriptLocale.RESEARCH_PCT,
									
									"style" : ["not_pick"],
								},
								{
									"name" : "ItemPctText",
									"type" : "text",

									"x" : 111 - 27 + 104,
									"y" : 18 + 16 * 2,
									
									
									"color" : colorInfo.GOLD_COLOR, 
									"fontsize":"middle",
									
									"text" : "",
									
									"style" : ["not_pick"],
								},								
								{
									"name" : "textItemCD",
									"type" : "text",

									"x" : 111 - 27,
									"y" : 18 + 16 * 3,
									
									
									"color" : colorInfo.FONT_COLOR, 
									"fontsize":"middle",
									
									"text" : uiScriptLocale.RESEARCH_TIMER,
									
									"style" : ["not_pick"],
								},
								{
									"name" : "ItemCDText",
									"type" : "text",

									"x" : 111 - 27 + 77,
									"y" : 18 + 16 * 3,
									
									
									"color" : colorInfo.RED, 
									"fontsize":"middle",
									
									"text" : "",
									
									"style" : ["not_pick"],
								},								
								{
									"name" : "exam_button",
									"type" : "dynamic_button",

									"x" : 0,
									"y" : 86,

									"text" : uiScriptLocale.RESEARCH_BUTTON,
									"horizontal_align" : "center",

									"preset" : "not_so_largerer_button",
								},
								{
									"name" : "CD_Image",
									"type" : "image",

									"x" : 246,
									"y" : 46+13,

									"image" : "d:/ymir work/ui/game/mailbox/mailbox_icon_cd.sub",
								},
								{
									"name" : "CD_checkbox",
									"type" : "checkbox_new",


									"x" : 272,
									"y" : 51+14,
								},
							),
						},
						{
							"name" : "thinboardIconContainer",
							"type" : "thinboard",

							"x" : 51-15,
							"y" : 136,
							
							"width" : 214+30,
							"height" : 40,
						
							
							"style" : ["not_pick"],
							
							"children" :
							(
								{
									"name" : "time_deleter_slot",
									"type" : "grid_table",

									"x" : 46,
									"y" : 3,

									"start_index" : 0,
									"x_count" : 1,
									"y_count" : 1,
									"x_step" : 32,
									"y_step" : 32,

									#"image" : "d:/ymir work/ui/public/Slot_Base.sub",
								},
								#{
								#	"name" : "cd_reset_icon",
								#	"type" : "image",
								#	
								#	"x" : 46,
								#	"y" : 3,
								#
								#	"image" : "d:/icon/item/102517.tga",
								#},
								{
									"name" : "UpButton1",
									"type" : "button",
									"tooltip_text" : uiScriptLocale.RESEARCH_UP,
									"x" : 9,
									"y" : 9,
									"default_image" : TASKBAR + "pageup.sub",
									"over_image" : TASKBAR + "pageup_over.sub",
									"down_image" : TASKBAR + "pageup_click.sub",
								},
								{
									"name" : "DownButton1",
									"type" : "button",
									"tooltip_text" : uiScriptLocale.RESEARCH_DOWN,

									"x" : 9,
									"y" : 19,

									"default_image" : TASKBAR + "pagedown.sub",
									"over_image" : TASKBAR + "pagedown_over.sub",
									"down_image" : TASKBAR + "pagedown_click.sub",
								},
								{ 
									"name":"ItemSlotbar1", 
									"type":"slotbar", 
									"x":22, 
									"y":11, 
									"preset":"parameter_slot_09", 
									"children" :
									(
										{ "name":"ItemSlotbar1Text", "type":"text", "x":1, "y":2, "text":"0", "r":1.0, "g":1.0, "b":1.0, "a":1.0, "text_horizontal_align":"center", "horizontal_align":"center"},
									),
								},
								{
									"name" : "elisir_10_slot",
									"type" : "grid_table",

									"x" : 126,
									"y" : 3,

									"start_index" : 0,
									"x_count" : 1,
									"y_count" : 1,
									"x_step" : 32,
									"y_step" : 32,

									#"image" : "d:/ymir work/ui/public/Slot_Base.sub",
								},
								#{
								#	"name" : "elisir_10_icon",
								#	"type" : "image",
									
								#	"x" : 126,
								#	"y" : 3,

								#	"image" : "d:/icon/item/102529.tga",
								#},
								{
									"name" : "UpButton2",
									"type" : "button",
									"tooltip_text" : uiScriptLocale.RESEARCH_UP,
									"x" : 92,
									"y" : 9,
									"default_image" : TASKBAR + "pageup.sub",
									"over_image" : TASKBAR + "pageup_over.sub",
									"down_image" : TASKBAR + "pageup_click.sub",
								},
								{
									"name" : "DownButton2",
									"type" : "button",
									"tooltip_text" : uiScriptLocale.RESEARCH_DOWN,

									"x" : 92,
									"y" : 19,

									"default_image" : TASKBAR + "pagedown.sub",
									"over_image" : TASKBAR + "pagedown_over.sub",
									"down_image" : TASKBAR + "pagedown_click.sub",
								},
								{ 
									"name":"ItemSlotbar2", 
									"type":"slotbar", 
									"x":104, 
									"y":11, 
									"preset":"parameter_slot_09", 
									"children" :
									(
										{ "name":"ItemSlotbar2Text", "type":"text", "x":1, "y":2, "text":"0", "r":1.0, "g":1.0, "b":1.0, "a":1.0, "text_horizontal_align":"center", "horizontal_align":"center"},
									),
								},
								{
									"name" : "elisir_30_slot",
									"type" : "grid_table",

									"x" : 206,
									"y" : 3,

									"start_index" : 0,
									"x_count" : 1,
									"y_count" : 1,
									"x_step" : 32,
									"y_step" : 32,

									#"image" : "d:/ymir work/ui/public/Slot_Base.sub",
								},								
								#{
								#	"name" : "elisir_30_icon",
								#	"type" : "image",
								#	
								#	"x" : 206,
								#	"y" : 3,

								#	"image" : "d:/icon/item/102616.tga",
								#},
								{
									"name" : "UpButton3",
									"type" : "button",
									"tooltip_text" : uiScriptLocale.RESEARCH_UP,
									"x" : 172,
									"y" : 9,
									"default_image" : TASKBAR + "pageup.sub",
									"over_image" : TASKBAR + "pageup_over.sub",
									"down_image" : TASKBAR + "pageup_click.sub",
								},
								{
									"name" : "DownButton3",
									"type" : "button",
									"tooltip_text" : uiScriptLocale.RESEARCH_DOWN,

									"x" : 172,
									"y" : 19,

									"default_image" : TASKBAR + "pagedown.sub",
									"over_image" : TASKBAR + "pagedown_over.sub",
									"down_image" : TASKBAR + "pagedown_click.sub",
								},
								{ 
									"name":"ItemSlotbar3", 
									"type":"slotbar", 
									"x":184, 
									"y":11, 
									"preset":"parameter_slot_09", 
									"children" :
									(
										{ "name":"ItemSlotbar3Text", "type":"text", "x":1, "y":2, "text":"0", "r":1.0, "g":1.0, "b":1.0, "a":1.0, "text_horizontal_align":"center", "horizontal_align":"center"},
									),
								},
							),
						},
						{
							"name" : "MessagesName",
							"type" : "text",
							"x" : 115,
							"y" : 169+16,
							"text" : uiScriptLocale.SYSTEM_MESSAGES,
							"color" : colorInfo.GOLD, 
							"fontsize":"middle",
							"children" : 
							(

								{
									"name" : "NotifySlot", "type" : "slotbar", "x" : -110, "y" : 18 * 1, "width" : 305, "height" : 16*5,
									"children" :
									(
										{ "name" : "NotifyValue1", "type" : "text", "x" : 0, "y" : 0, "text" : " ", "horizontal_align" : "center", "text_horizontal_align" : "center", },
									),
								},
							),
						},
					),
				},
			),
		},
	),
}

 

  • Metin2 Dev 3
  • muscle 1
Link to comment
https://metin2.dev/topic/29513-biologist-manager-c-lua/#findComment-153507
Share on other sites

  • 3 months later...
  • Premium

Updated with check flagitems count in IsQuestStatusFindItem (download file already updated):

---
 Server/game/src/biologist_manager.cpp          | 17 ++++++++++++++---
 Server/game/src/biologist_manager.h            |  2 +-
 Server/game/src/player_achievement_manager.cpp |  8 ++++++--
 3 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/Server/game/src/biologist_manager.cpp b/Server/game/src/biologist_manager.cpp
index 23ed25be..02b17bde 100644
--- a/Server/game/src/biologist_manager.cpp
+++ b/Server/game/src/biologist_manager.cpp
@@ -22,7 +22,7 @@ bool CBiologistManager::IsValidQuestID(LPCHARACTER ch, const uint8_t questID)
 	return true;
 }
 
-bool CBiologistManager::IsQuestStatusFindItem(LPCHARACTER ch, std::string_view quest_name)
+bool CBiologistManager::IsQuestStatusFindItem(LPCHARACTER ch, std::string_view quest_name, uint8_t questID)
 {
 	auto pPC = quest::CQuestManager::instance().GetPCForce(ch->GetPlayerID());
 	std::string questName = utils::view_to_string(quest_name);
@@ -30,8 +30,9 @@ bool CBiologistManager::IsQuestStatusFindItem(LPCHARACTER ch, std::string_view q
 	auto findItemValue = quest::CQuestManager::Instance().GetQuestStateIndex(questName, questState);
 
 	std::string questFlag = utils::string_view_concat(quest_name, ".__status");
+	std::string questFlagItem = utils::string_view_concat(quest_name, utils::view_to_string(BiologistQuestFlagItemsDeliveredCount));
 	int questStateValue = pPC->GetFlag(questFlag);
-
+	const uint32_t questFlagItemCount = pPC->GetFlag(questFlagItem);
 	//if the quest has not started yet, the status can be 0
 	//therefore if 0, the interface cannot be opened
 	if(questStateValue == 0)
@@ -41,6 +42,10 @@ bool CBiologistManager::IsQuestStatusFindItem(LPCHARACTER ch, std::string_view q
 	if(questStateValue != findItemValue)
 		return false;
 	//otherwise it's in a "finditem" state,
+
+	if(questFlagItemCount >= BiologistQuestItemLimits[questID])
+		return false;
+
 	return true;
 }
 
@@ -64,7 +69,7 @@ bool CBiologistManager::CheckOpenInterface(LPCHARACTER ch)
 	uint8_t iterVal = 0;
 	for(const auto& val : BiologistQuestNames)
 	{
-		if(IsQuestStatusFindItem(ch, val) == true){
+		if(IsQuestStatusFindItem(ch, val, iterVal) == true){
 			SendBiologistManagerOpenCommand(ch, iterVal);
 			return true;
 		}
@@ -238,6 +243,12 @@ void CBiologistManager::ExecuteDeliveryRequest(LPCHARACTER ch, uint8_t questID,
 
 void CBiologistManager::ResearchPacket(LPCHARACTER ch, const uint8_t questID, uint8_t subheader, uint8_t deliversCounter, uint8_t successDeliveries, uint8_t failedDeliveries, uint8_t  timeDeleterUses, uint8_t elixirUses, uint8_t elixirPlusUses)
 {
+	if(ch == nullptr)
+		return;
+
+	if(ch->GetDesc() == nullptr)
+		return;
+
 	time_t remainingTime = GetRemainingTime(ch, questID);
 
 	TPacketGCBiologistManagerSendResearch p;
diff --git a/Server/game/src/biologist_manager.h b/Server/game/src/biologist_manager.h
index 2174854f..71b32342 100644
--- a/Server/game/src/biologist_manager.h
+++ b/Server/game/src/biologist_manager.h
@@ -61,7 +61,7 @@ class CBiologistManager : public singleton<CBiologistManager>
 		CBiologistManager() = default;
 		virtual ~CBiologistManager() = default;
 
-		bool	IsQuestStatusFindItem(LPCHARACTER ch, std::string_view quest_name);
+		bool	IsQuestStatusFindItem(LPCHARACTER ch, std::string_view quest_name, uint8_t questID);
 		void	SetQuestStateToBack(DWORD playerID, const uint8_t questID);
 		void	SendBiologistManagerOpenCommand(LPCHARACTER ch, const uint8_t questID);
 		bool	CheckOpenInterface(LPCHARACTER ch);
--

 

Edited by xXIntelXx
  • Good 1
  • Love 3
Link to comment
https://metin2.dev/topic/29513-biologist-manager-c-lua/#findComment-156450
Share on other sites

  • 2 weeks later...
  • Premium

Updated to set all the values from settings.lua (or w/e file .lua you might load at startup besides settings.lua with similar characteristics)

EX:

--[[
structure:
[QUEST_NAME,QUEST_ITEM,QUEST_CD,QUEST_PCT,QUEST_ITEM_TO_SEND]
]]--
add_biologist_info("ue_collect_item_lv30",30006,0,90,20)
add_biologist_info("ue_collect_item_lv40",30055,0,90,20)
add_biologist_info("ue_collect_item_lv50",30047,0,90,20)
add_biologist_info("ue_collect_item_lv60",30324,0,90,25)
add_biologist_info("ue_collect_item_lv70",30015,0,90,20)
add_biologist_info("ue_collect_item_lv75",30050,3600,90,25)
add_biologist_info("ue_collect_item_lv80",30198,7200,44,30)
add_biologist_info("ue_collect_item_lv90",30166,10800,42,35)
add_biologist_info("ue_collect_item_lv95",30495,10800,30,15)
add_biologist_info("ue_collect_item_lv100",100029,14400,38,40)
add_biologist_info("ue_collect_item_lv105",30329,14400,36,45)
add_biologist_info("ue_collect_item_lv110",100039,18000,34,50)
--[[
structure:
[PCT_ADDER_VNUM,PCT_ADDER_PLUS_VNUM,TIME_DELETER_VNUM,ITEM_MAX_TO_SEND,PCT_ADDER,PCT_ADDER_PLUS]
]]--
add_biologist_globals(102529,102616,102517,5,10,20)

Also found a little mistake:

Qfm6Lub.png

Git patch would be, well..

diff --git a/Locale/italy/settings.lua b/Locale/italy/settings.lua
index ec787cd9..0eaa5e94 100644
--- a/Locale/italy/settings.lua
+++ b/Locale/italy/settings.lua
@@ -322,3 +322,29 @@ add_dungeon_party_size(4, 8)
 add_dungeon_party_size(5, 8)
 add_dungeon_party_size(11, 4)
 add_dungeon_party_size(12, 4)
+
+
+
...........................
@@ -2415,7 +2539,9 @@ namespace quest
 			{	"vid_is_near_to",				_vid_is_near_to	   			},
 			{	"damage_to_vid",				_damage_to_vid	   			},
 			{	"damage_to_vid_pct",			_damage_to_vid_pct	   		},
-			
+
+			{	"add_biologist_info",			_add_biologist_info	   		},
+			{	"add_biologist_globals",		_add_biologist_globals	   	},
 
 			{	NULL,	NULL	}

probably incompatible? ?

Edited by Metin2 Dev International
Core X - External 2 Internal
Link to comment
https://metin2.dev/topic/29513-biologist-manager-c-lua/#findComment-156769
Share on other sites

  • 4 weeks later...
  • Premium

Updated with biologist pulse (avoiding spamming of requests) and replaced GetPCForce with GetPC (with related checks)

GetPCForce can lead to this crash:

NnnvPle.png

I am not sure if it's because of our questmanager refactor or not, but it's probably 99.99% of the times better this way.

Edited by Intel
Core X - External 2 Internal
Link to comment
https://metin2.dev/topic/29513-biologist-manager-c-lua/#findComment-157320
Share on other sites

  • 1 year later...

https://metin2.download/picture/NOLSNNgfWK2d0Yx745541kUX8Mes0Yu5/.png

I have this error when i compile src game? I don't have reminder_processor.h.. any solution please? 

Edited by Metin2 Dev International
Core X - External 2 Internal
Link to comment
https://metin2.dev/topic/29513-biologist-manager-c-lua/#findComment-165452
Share on other sites

  • Premium

Just remove that line, it's part of the timer notification, which is not in the download files (not even in my files yet, but that's another discussion lol)

 

It seems like you miss the include to biologist_manager in questlua_global though (I really have to check the files as soon as I am at the PC)

Edited by Intel
Link to comment
https://metin2.dev/topic/29513-biologist-manager-c-lua/#findComment-165453
Share on other sites

Ok, yes i forgot to include #include "biologist_manager.h" in questlua_global.cpp. 

 

Now i removed #include "reminder_processor.h" and "public ReminderProcessor" from biologist_manager.h and i have these errors.

spacer.png

Edited by Metin2 Dev International
Core X - External 2 Internal
Link to comment
https://metin2.dev/topic/29513-biologist-manager-c-lua/#findComment-165454
Share on other sites

  • Premium
7 minutes ago, EugeeN said:

Ok, yes i forgot to include #include "biologist_manager.h" in questlua_global.cpp. 

 

Now i removed #include "reminder_processor.h" and "public ReminderProcessor" from biologist_manager.h and i have these errors.

spacer.png

I am not sure

This is the hidden content, please
this link is updated, otherwise:
This is the hidden content, please

 

  • Metin2 Dev 2
  • Good 2
Link to comment
https://metin2.dev/topic/29513-biologist-manager-c-lua/#findComment-165455
Share on other sites

I have just this error now !

And i think we need to remove public ReminderProcessor too !

 

Update1: I removed  ",public ReminderProcessor " from BIOLOGIST_MANAGER.H !

Update2: I made in "questpc.h" DoQuestStateChange a public member!

I don't know if is the right way, but at the end i compiled succesfully src game.

 

Do you have a ready-made quest model? Thanks !

spacer.png

Edited by EugeeN
Core X - External 2 Internal
Link to comment
https://metin2.dev/topic/29513-biologist-manager-c-lua/#findComment-165456
Share on other sites

  • Premium
20 minutes ago, EugeeN said:

I have just this error now !

And i think we need to remove public ReminderProcessor too !

 

Update1: I removed  ",public ReminderProcessor " from BIOLOGIST_MANAGER.H !

Update2: I made in "questpc.h" DoQuestStateChange a public member!

I don't know if is the right way, but at the end i compiled succesfully src game.

 

Do you have a ready-made quest model? Thanks !

spacer.png

Oh, that function was private? Gotta check on marty's, but from mines, it was already public (considering the guild quests we had 10 years ago, I guess that's why)

 

The rest correct. In the files I think I left a quest example

  • Good 1
Link to comment
https://metin2.dev/topic/29513-biologist-manager-c-lua/#findComment-165457
Share on other sites

Hi, again! 

Can you give me please these files?

"default_image" : TASKBAR + "pageup.sub",
"over_image" : TASKBAR + "pageup_over.sub",
"down_image" : TASKBAR + "pageup_click.sub",

 

"default_image" : TASKBAR + "pagedown.sub",
"over_image" : TASKBAR + "pagedown_over.sub",
"down_image" : TASKBAR + "pagedown_click.sub",

 

"image" : "d:/ymir work/ui/game/mailbox/mailbox_icon_cd.sub",
 

Link to comment
https://metin2.dev/topic/29513-biologist-manager-c-lua/#findComment-165467
Share on other sites

  • Premium
23 hours ago, EugeeN said:

Hi, again! 

Can you give me please these files?

"default_image" : TASKBAR + "pageup.sub",
"over_image" : TASKBAR + "pageup_over.sub",
"down_image" : TASKBAR + "pageup_click.sub",

 

"default_image" : TASKBAR + "pagedown.sub",
"over_image" : TASKBAR + "pagedown_over.sub",
"down_image" : TASKBAR + "pagedown_click.sub",

 

"image" : "d:/ymir work/ui/game/mailbox/mailbox_icon_cd.sub",
 

those are part of my client ahah

.png

you can change them as you'd like

 

 

 

 

  • Metin2 Dev 1
Link to comment
https://metin2.dev/topic/29513-biologist-manager-c-lua/#findComment-165482
Share on other sites

  • 1 year later...

Hi, i got this errors after compiling.
 

In file included from input_main.cpp:43:
In file included from ./biologist_manager.h:3:
In file included from ./stdafx.h:4:
./../../common/utils.h:3:13: error: redefinition of 'str_to_number'
inline bool str_to_number (bool& out, const char *in)
            ^
./../../common/utils.h:3:13: note: previous definition is here
inline bool str_to_number (bool& out, const char *in)
            ^
In file included from input_main.cpp:43:
In file included from ./biologist_manager.h:3:
In file included from ./stdafx.h:4:
./../../common/utils.h:11:13: error: redefinition of 'str_to_number'
inline bool str_to_number (char& out, const char *in)
            ^
./../../common/utils.h:11:13: note: previous definition is here
inline bool str_to_number (char& out, const char *in)
            ^
In file included from input_main.cpp:43:
In file included from ./biologist_manager.h:3:
In file included from ./stdafx.h:4:
./../../common/utils.h:19:13: error: redefinition of 'str_to_number'
inline bool str_to_number (unsigned char& out, const char *in)
            ^
./../../common/utils.h:19:13: note: previous definition is here
inline bool str_to_number (unsigned char& out, const char *in)
            ^
In file included from input_main.cpp:43:
In file included from ./biologist_manager.h:3:
In file included from ./stdafx.h:4:
./../../common/utils.h:27:13: error: redefinition of 'str_to_number'
inline bool str_to_number (short& out, const char *in)
            ^
./../../common/utils.h:27:13: note: previous definition is here
inline bool str_to_number (short& out, const char *in)
            ^
In file included from input_main.cpp:43:
In file included from ./biologist_manager.h:3:
In file included from ./stdafx.h:4:
./../../common/utils.h:35:13: error: redefinition of 'str_to_number'
inline bool str_to_number (unsigned short& out, const char *in)
            ^
./../../common/utils.h:35:13: note: previous definition is here
inline bool str_to_number (unsigned short& out, const char *in)
            ^
In file included from input_main.cpp:43:
In file included from ./biologist_manager.h:3:
In file included from ./stdafx.h:4:
./../../common/utils.h:43:13: error: redefinition of 'str_to_number'
inline bool str_to_number (int& out, const char *in)
            ^
./../../common/utils.h:43:13: note: previous definition is here
inline bool str_to_number (int& out, const char *in)
            ^
In file included from input_main.cpp:43:
In file included from ./biologist_manager.h:3:
In file included from ./stdafx.h:4:
./../../common/utils.h:51:13: error: redefinition of 'str_to_number'
inline bool str_to_number (unsigned int& out, const char *in)
            ^
./../../common/utils.h:51:13: note: previous definition is here
inline bool str_to_number (unsigned int& out, const char *in)
            ^
In file included from input_main.cpp:43:
In file included from ./biologist_manager.h:3:
In file included from ./stdafx.h:4:
./../../common/utils.h:59:13: error: redefinition of 'str_to_number'
inline bool str_to_number (long& out, const char *in)
            ^
./../../common/utils.h:59:13: note: previous definition is here
inline bool str_to_number (long& out, const char *in)
            ^
In file included from input_main.cpp:43:
In file included from ./biologist_manager.h:3:
In file included from ./stdafx.h:4:
./../../common/utils.h:67:13: error: redefinition of 'str_to_number'
inline bool str_to_number (unsigned long& out, const char *in)
            ^
./../../common/utils.h:67:13: note: previous definition is here
inline bool str_to_number (unsigned long& out, const char *in)
            ^
In file included from input_main.cpp:43:
In file included from ./biologist_manager.h:3:
In file included from ./stdafx.h:4:
./../../common/utils.h:75:13: error: redefinition of 'str_to_number'
inline bool str_to_number (long long& out, const char *in)
            ^
./../../common/utils.h:75:13: note: previous definition is here
inline bool str_to_number (long long& out, const char *in)
            ^
In file included from input_main.cpp:43:
In file included from ./biologist_manager.h:3:
In file included from ./stdafx.h:4:
./../../common/utils.h:83:13: error: redefinition of 'str_to_number'
inline bool str_to_number (float& out, const char *in)
            ^
./../../common/utils.h:83:13: note: previous definition is here
inline bool str_to_number (float& out, const char *in)
            ^
In file included from input_main.cpp:43:
In file included from ./biologist_manager.h:3:
In file included from ./stdafx.h:4:
./../../common/utils.h:91:13: error: redefinition of 'str_to_number'
inline bool str_to_number (double& out, const char *in)
            ^
./../../common/utils.h:91:13: note: previous definition is here
inline bool str_to_number (double& out, const char *in)
            ^
In file included from input_main.cpp:43:
In file included from ./biologist_manager.h:3:
In file included from ./stdafx.h:4:
./../../common/utils.h:100:13: error: redefinition of 'str_to_number'
inline bool str_to_number (long double& out, const char *in)
            ^
./../../common/utils.h:100:13: note: previous definition is here
inline bool str_to_number (long double& out, const char *in)
            ^
In file included from input_main.cpp:43:
In file included from ./biologist_manager.h:3:
In file included from ./stdafx.h:4:
./../../common/utils.h:109:14: error: redefinition of 'str_to_number'
        inline bool str_to_number(unsigned long long& out, const char* in)
                    ^
./../../common/utils.h:109:14: note: previous definition is here
        inline bool str_to_number(unsigned long long& out, const char* in)
                    ^
In file included from input_main.cpp:43:
In file included from ./biologist_manager.h:3:
In file included from ./stdafx.h:4:
./../../common/utils.h:117:36: error: redefinition of 'check_mul_error'
        template <typename T> inline bool check_mul_error(T a, T b) {
                                          ^
./../../common/utils.h:117:36: note: previous definition is here
        template <typename T> inline bool check_mul_error(T a, T b) {
                                          ^
In file included from input_main.cpp:43:
./biologist_manager.h:17:71: error: expected class name
class CBiologistManager : public singleton<CBiologistManager>, public ReminderProcessor                                                                   

 

Edited by klausthorax
Link to comment
https://metin2.dev/topic/29513-biologist-manager-c-lua/#findComment-172691
Share on other sites

Don't use any images from : imgur, turkmmop, freakgamers, inforge, hizliresim... Or your content will be deleted without notice...
Use : https://metin2.download/media/add/

Please use https://metin2.download/ when uploading files smaller than 100MB, otherwise the approval will take longer due to manual upload.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
×
×
  • 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.