Jump to content

Heathcliff

Member
  • Posts

    72
  • Joined

  • Last visited

  • Feedback

    0%

Posts posted by Heathcliff

  1.  

    Hi, first of all thanks for @ Mali for contributing a lot to this community!

    On 11/28/2023 at 10:48 PM, WeedHex said:

    Can someone update the post with:

    -Lycan Missing

    -Size errors with large names

    Wolfman part

    Spoiler

    Search:

    		KILL_BAR_WEAPON_TYPE = {
    			"FIST": "|Ekill_bar/fist|e",
    			item.WEAPON_SWORD: "|Ekill_bar/sword|e",
    			item.WEAPON_DAGGER: "|Ekill_bar/dagger|e",
    			item.WEAPON_BOW: "|Ekill_bar/bow|e",
    			item.WEAPON_TWO_HANDED: "|Ekill_bar/twohand|e",
    			item.WEAPON_BELL: "|Ekill_bar/bell|e",
    			item.WEAPON_FAN: "|Ekill_bar/fan|e",
    		}

    Add under:
     

    		if app.ENABLE_WOLFMAN_CHARACTER:
    			KILL_BAR_RACE.update({ playersettingmodule.RACE_WOLFMAN_M : "|Ekill_bar/wolfman|e", })
    			KILL_BAR_WEAPON_TYPE.update({ item.WEAPON_CLAW : "|Ekill_bar/claw|e", })

     


    Size and position part

    Spoiler

    Search:

    	if app.BL_KILL_BAR:
    		def RepositionKillBar(self, obj):
    			obj["MOVE_Y"] += MiniMap.KILL_BAR_MOVE_DISTANCE
    			return obj
    
    		def AddKillInfo(self, killer, victim, killer_race, victim_race, weapon_type):
    			if len(self.KillList) >= MiniMap.KILL_BAR_MAX_ITEM:
    				self.KillList.sort(
    					key=lambda obj: obj["CoolTime"], reverse=True)
    				del self.KillList[-1]
    			
    			if self.KillList:
    				self.KillList = map(self.RepositionKillBar, self.KillList)
    
    			TBoard = ui.ThinBoard()
    			TBoard.SetParent(self)
    			TBoard.SetSize(155, 10)
    			TBoard.SetPosition(15, 185)
    			TBoard.Show()
    
    			KillText = ui.TextLine()
    			KillText.SetText("{} {} {} {} {}".format(MiniMap.KILL_BAR_RACE.get(int(killer_race), ""), killer, MiniMap.KILL_BAR_WEAPON_TYPE.get(
    				int(weapon_type), MiniMap.KILL_BAR_WEAPON_TYPE.get("FIST")), victim, MiniMap.KILL_BAR_RACE.get(int(victim_race), "")))
    			KillText.SetParent(TBoard)
    			KillText.SetWindowHorizontalAlignCenter()
    			KillText.SetWindowVerticalAlignCenter()
    			KillText.SetHorizontalAlignCenter()
    			KillText.SetVerticalAlignCenter()
    			KillText.Show()
    
    			KillDict = dict()
    			KillDict["ThinBoard"] = TBoard
    			KillDict["TextLine"] = KillText
    			KillDict["CoolTime"] = app.GetTime() + MiniMap.KILL_BAR_COOLTIME
    			KillDict["MOVE_X"] = MiniMap.KILL_BAR_MOVE_DISTANCE
    			KillDict["MOVE_Y"] = 0.0
    
    			self.KillList.append(KillDict)

     

    Change:

    	if app.BL_KILL_BAR:
    		def RepositionKillBar(self, obj):
    			obj["MOVE_Y"] += MiniMap.KILL_BAR_MOVE_DISTANCE
    			return obj
    
    		def AddKillInfo(self, killer, victim, killer_race, victim_race, weapon_type):
    			if len(self.KillList) >= MiniMap.KILL_BAR_MAX_ITEM:
    				self.KillList.sort(
    					key=lambda obj: obj["CoolTime"], reverse=True)
    				del self.KillList[-1]
    			
    			if self.KillList:
    				self.KillList = map(self.RepositionKillBar, self.KillList)
    
    			width = 30
    			height = 10
    			base_x = 15
    			base_y = 185
    
    			TBoard = ui.ThinBoard()
    			TBoard.SetParent(self)
    			TBoard.SetSize(width, height)
    			TBoard.SetPosition(base_x, base_y)
    			TBoard.Show()
    
    			KillText = ui.TextLine()
    			KillText.SetText("{} {} {} {} {}".format(MiniMap.KILL_BAR_RACE.get(int(killer_race), ""), killer, MiniMap.KILL_BAR_WEAPON_TYPE.get(
    				int(weapon_type), MiniMap.KILL_BAR_WEAPON_TYPE.get("FIST")), victim, MiniMap.KILL_BAR_RACE.get(int(victim_race), "")))
    			KillText.SetParent(TBoard)
    			KillText.SetWindowHorizontalAlignCenter()
    			KillText.SetWindowVerticalAlignCenter()
    			KillText.SetHorizontalAlignCenter()
    			KillText.SetVerticalAlignCenter()
    			KillText.Show()
    
    			size_x, size_y = KillText.GetTextSize()
    			TBoard.SetSize(size_x + width, height)
    			TBoard.SetPosition((base_x + 120) - size_x, base_y)
    
    			KillDict = dict()
    			KillDict["ThinBoard"] = TBoard
    			KillDict["TextLine"] = KillText
    			KillDict["CoolTime"] = app.GetTime() + MiniMap.KILL_BAR_COOLTIME
    			KillDict["MOVE_X"] = MiniMap.KILL_BAR_MOVE_DISTANCE
    			KillDict["MOVE_Y"] = 0.0
    
    			self.KillList.append(KillDict)

    Gifs

    Spoiler

    Short text:
    .gif

    Long text:
    .gif


    For claw image you can reuse something from your client like I did

    • Love 2
  2. Hey! 

    Thanks for sharing this with us! 
    There is a little mistake in char.cpp with this line:

    	out.percent_exp = (BYTE)MINMAX(0, GetExp() * 100 / GetNextExp(), 100);

    GetExp() function has DWORD (unsigned long) data type, which range is 0 to 4 294 967 295.
    If you multiply your current exp (if it's bigger than 42 949 672) with 100, you will get 0, because of it's overflowing.
    You can convert it to int64_t (long long).

    	out.percent_exp = MINMAX(0, (int64_t)GetExp() * 100 / GetNextExp(), 100);
    • Love 4
  3. Heey, thanks for check. 
    I'm using that too from the originally released "freebsd9.2_with_source" title.
    All the time I thought there is some mistake in my source somewhere, but actually nothing is wrong. .
    As you said, there is no calling that points to the IsMaskedItem() function,  but my game core is loading it anyway, cause if it has been found, then it will be loaded instatly.
    Literally I thinked about everything, and I missed the easiest thing in this situation ?‍♂️

    By the way thanks, that you checked out your files too.
    This mistery has been solved  and my misery has been gone ? 

    Spoiler

    • Metin2 Dev 1
  4. Hey yoo!

    This little thing allows you to make new regen files called: regen_once.txt (you can rename it to anything).
    Modification is using an already existing function called: regen_load_in_file, which has been used by quests.
    You can use it, to generate some monsters / npcs at the server startup which don't have any respawn time, so if you kill them, they won't appear until a new server restart, or manually reloading your regens if you have those functions.

    In common/service.h - Add:

    #define ENABLE_REGEN_ONCE


    In game/src/sectree_manager.cpp - Search:

    			snprintf(szFilename, sizeof(szFilename), "%s/%s/regen.txt", c_pszMapBasePath, szMapName);
    			regen_load(szFilename, setting.iIndex, setting.iBaseX, setting.iBaseY);


    Add under:

    #ifdef ENABLE_REGEN_ONCE
    			snprintf(szFilename, sizeof(szFilename), "%s/%s/regen_once.txt", c_pszMapBasePath, szMapName);
    			regen_load_in_file(szFilename, setting.iIndex, setting.iBaseX, setting.iBaseY);
    #endif


    In game/src/regen.cpp - Search:

    	snprintf(szFilename, sizeof(szFilename), "%sregen.txt", mbMapDataContainer[lMapIndex]->szBaseName);
    	regen_load(szFilename, lMapIndex, mbMapDataContainer[lMapIndex]->base_x, mbMapDataContainer[lMapIndex]->base_y);


    Add under:

    #ifdef ENABLE_REGEN_ONCE
        snprintf(szFilename, sizeof(szFilename), "%sregen_once.txt", mbMapDataContainer[lMapIndex]->szBaseName);
        regen_load_in_file(szFilename, lMapIndex, mbMapDataContainer[lMapIndex]->base_x, mbMapDataContainer[lMapIndex]->base_y);
    #endif


    If you done it, you can create regen_once.txt with some mobs, and place it to your map folder next to regen.txt. If you don't place it in every map folder, you will get some syserr that says it can't find regen_once.txt. It won't cause any problem. It just inform you, that you didn't create that file for certain maps. 

    • Good 4
    • Love 1
  5. Hey Guys!

    I'm using TXT protos and today I noticed a weird thing. In the most of the time, servers using an item several times with different properties. So pick an item that exist on every servers: Dragon God Life.
    This item exist 6 times in default item_proto.txt with different IDs. So if we want to modify the item (like make it stackable, or make it tradeable, or something like that) which takes place at: 39017 ID. Guess what?  
    It just NOTHING happens at all. Why? Cause this item which has UNIQUE ID, using the same proto values as 71027 does. So if you want to modify 39017 you need to modify 71027 FOR NO REASON
    If you delete the "MAIN" item (which in that case is 71027), then try to generate 39017 with /item command, You will see an item with no name and the ID will be 71027.  -->  LINK
    And this is just one example. There is a bunch of these items in the default files are working like that. It seems they're connected somehow, but I didn't find any clue neither in server source, nor in client source.

    My question is:
    Have you guys ever noticed these kind of weird things about some items and if yes, did you find why is this shit happens? OR this little thing only exist for me?

    Show some mercy for my english skills pls 🤣

    • Metin2 Dev 1
    • Good 1
  6. In char_item.cpp, search:

    	if (iWearCell < 0)
    		return false;

    Add under:

    	if (iWearCell == WEAR_BODY)
    	{
    		int ArmorUseTime = GetQuestFlag("prevent_wallhack.armor_use_time");
    		if (ArmorUseTime)
    		{
    			if (get_global_time() < ArmorUseTime /* limit */) 
    			{
    				ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You can't equip armor so fast"));
    				return false;
    			}
    			else
    				SetQuestFlag("prevent_wallhack.armor_use_time", get_global_time() + 3);
    		}
    	}


    In inpug_login.cpp, search:

    	ch->StartCheckSpeedHackEvent();

    Add under:

    	ch->SetQuestFlag("prevent_wallhack.armor_use_time", get_global_time());


    It works 100%. I'm using this too
    The other two I posted was just a freakin' junk, so sorry for that.
    Have a nice day guys! :D

    • Love 1
  7.  

    19 hours ago, Cunoo said:

    Why? Just repair item_list.txt... Client is not trash can..

     

    19 hours ago, Zeke said:

    Better let a bug crash your client than fixing it with that "fixing" lines. can item been with blank image? logic says no. let it crash to find where you missing files ^^

    Client still inform you that you have icon problems with xy item, and your client won't crash bcs of this small "error". This correction is just for not flooding it every second if you have missing icon. It will inform you once, and set a default image for it as I mentioned before. ?

    • Love 1
  8. M2 Download Center

    This is the hidden content, please
    ( Internal )

     

    Hello Guys! 

    I was so frustated with my syserr floods (%s ĆÄŔĎŔĚ ľř˝Ŕ´Ď´Ů.CItemData::__SetIconImage) when an item has no icon. 

    With this correction the client will only notice you once per item that has no image, and set a default icon for them, so you can drop it to the ground from your inventory, instead of giving attention to make them a new icon, or copy/paste an existing image.
     

    Spoiler

    In GameLib/ItemData.h search:

    
    
    TraceError("%s ĆÄŔĎŔĚ ľř˝Ŕ´Ď´Ů.CItemData::__SetIconImage",c_szFileName);
    m_pIconImage = NULL;

    And replace m_pIconImage = NULL; with:

    
    
    m_pIconImage = (CGraphicSubImage*)CResourceManager::Instance().GetResourcePointer("icon/item/blank.tga");

     

    Download:

    This is the hidden content, please



    Again, is not a big deal and my English is bad as always ?
    Have a nice day guys! ?

    • Metin2 Dev 40
    • Angry 1
    • Not Good 1
    • Think 1
    • Good 12
    • Love 1
    • Love 20
  9. On 10/28/2018 at 6:43 PM, Co0L said:

    For those who have the same problem. Instead of this:

    		startNumber = 0
    		for slot in self.quickslot:
    			for i in xrange(4):
    				slotNumber = i+startNumber
    				(Type, Position) = player.GetLocalQuickSlot(slotNumber)
    				if player.IsSkillCoolTime(Position):
    					(coolTime, elapsedTime) = player.GetSkillCoolTime(Position)
    					slot.SetSlotCoolTime(slotNumber, coolTime, elapsedTime)
    
    					cooldownDelay = 0
    					cooldown = int(coolTime-elapsedTime+cooldownDelay)
    					self.cooldownText[slotNumber].SetOutline()
    					self.cooldownText[slotNumber].SetText("%d" % cooldown)
    					cooldown = str(cooldown)
    					self.cooldownText[slotNumber].SetPosition((7, 2, -1)[len(cooldown) - 1],0)
    					self.cooldownText[slotNumber].Show()
    				else:
    					self.cooldownText[slotNumber].Hide()
    			startNumber += 4

    Use this:
     

    		startNumber = 0
    		for slot in self.quickslot:
    			for i in xrange(4):
    				slotNumber = i+startNumber
    				(Type, Position) = player.GetLocalQuickSlot(slotNumber)
    				if player.IsSkillCoolTime(Position) and player.SLOT_TYPE_SKILL == Type:
    					(coolTime, elapsedTime) = player.GetSkillCoolTime(Position)
    					slot.SetSlotCoolTime(slotNumber, coolTime, elapsedTime)
    
    					cooldownDelay = 0
    					cooldown = int(coolTime-elapsedTime+cooldownDelay)
    					self.cooldownText[slotNumber].SetOutline()
    					self.cooldownText[slotNumber].SetText("%d" % cooldown)
    					cooldown = str(cooldown)
    					self.cooldownText[slotNumber].SetPosition((7, 2, -1)[len(cooldown) - 1],0)
    					self.cooldownText[slotNumber].Show()
    				else:
    					self.cooldownText[slotNumber].Hide()
    			startNumber += 4

     

    • Good 1
  10. Spoiler
    Quote

    There is one bug. When player goes online first time it works, but when relog or teleport the message dont show up again. You have to restart client after that it works again.

     

    How to fix that? 

     

    Remove these lines:

    Spoiler
    • if not name in constInfo.ALREADY_NOTIFY_LIST:
    • constInfo.ALREADY_NOTIFY_LIST.append(name)
    • ALREADY_NOTIFY_LIST = []

    It's not a bug btw :D

    Regards

  11. #_#

    I made it like this some months ago:

    case USE_EXTEND_TIME:
    {
    	LPITEM item2;
    
    	if (!IsValidItemPosition(DestCell) || !(item2 = GetItem(DestCell)))
    		return false;
    
    	if (item2->IsExchanging() || item2->IsEquipped())
    		return false;
    
    	if (item2->GetType() != ITEM_COSTUME || (item2->GetSubType() != COSTUME_BODY && item2->GetSubType() != COSTUME_HAIR && item2->GetSubType() != COSTUME_MOUNT && item2->GetSubType() != COSTUME_WEAPON))
    		return false;
    	
    	int extendTime = (item2->GetSocket(0) + item->GetValue(0)) - get_global_time();
    	if (extendTime >= item2->GetDuration())
    	{
    		ChatPacket(CHAT_TYPE_INFO, LC_TEXT("COSTUME_LIMIT_REACHED_MAX"));
    		return false;
    	}
    
    	item2->SetSocket(0, item2->GetSocket(0) + item->GetValue(0));
    	item->SetCount(item->GetCount() - 1);
    	ChatPacket(CHAT_TYPE_INFO, LC_TEXT("COSTUME_TIME_LIMIT_EXTENDED"));
    }
    break;

     

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