Jump to content

VegaS™

Forum Moderator
  • Posts

    656
  • Joined

  • Last visited

  • Days Won

    187
  • Feedback

    100%

Posts posted by VegaS™

  1. Here're the references to understand how it's working step-by-step:

    • char.cpp

    This is the hidden content, please

    • constants.cpp
    #define MAX_EXP_DELTA_OF_LEV	31
    #define PERCENT_LVDELTA(me, victim) aiPercentByDeltaLev[MINMAX(0, (victim + 15) - me, MAX_EXP_DELTA_OF_LEV - 1)]
    #define PERCENT_LVDELTA_BOSS(me, victim) aiPercentByDeltaLevForBoss[MINMAX(0, (victim + 15) - me, MAX_EXP_DELTA_OF_LEV - 1)]
    • constants.cpp
    const int aiPercentByDeltaLevForBoss_euckr[MAX_EXP_DELTA_OF_LEV] =
    {
    	1,        // -15  0
    	[...]
    	180       // 15   30
    };
    
    const int aiPercentByDeltaLev_euckr[MAX_EXP_DELTA_OF_LEV] =
    {
    	1,        // -15  0
    	[...]
    	180       // 15   30
    };
    • locale_service.cpp
    	if (!aiPercentByDeltaLevForBoss)
    		aiPercentByDeltaLevForBoss = aiPercentByDeltaLevForBoss_euckr;
    
    	if (!aiPercentByDeltaLev)
    		aiPercentByDeltaLev = aiPercentByDeltaLev_euckr;

     

     

     

    • Metin2 Dev 32
    • Dislove 1
    • Confused 1
    • Good 10
    • Love 1
    • Love 26
  2. Then you'll need a small formula like this, for keeping the same values of enum:

    This is the hidden content, please

    So, in that way, you'll get the effect value multiplied by 4 depending on effectID.

    Output:

    dwEff = 1
    m_swordRefineEffectRight = EFFECT_REFINED + 114
    
    dwEff = 5
    m_swordRefineEffectRight = EFFECT_REFINED + 130
    
    dwEff = 12
    m_swordRefineEffectRight = EFFECT_REFINED + 158

     

    • Love 3
  3. 10 minutes ago, VegaS™ said:

     

    I don't know how it's working your system but in your case, you need something very simple, not to evaluate an expression when you can use effectSwordStartID + effectID:

    
    m_swordRefineEffectRight = EFFECT_REFINED + EFFECT_SWORD_EFF_START + dwEff;

    You just need to have the values ordered ascendingly.

    Then you could do it as I said, it's the best method instead of using an array or something.

    Can you show me the EFFECT_SWORD_EFF1....EFFECT_SWORD_EFF40 values from enum?

    • Love 1
  4. It's impossible what you're trying to do, this could be done in python very easily, like:

    m_swordRefineEffectRight = eval("EFFECT_REFINED + EFFECT_SWORD_EFF_%d" % i);

    But in C++ there's no built-in method, just a work-around, and shitty ways.

     

    I don't know how it's working your system but in your case, you need something very simple, not to evaluate an expression when you can use effectSwordStartID + effectID:

    m_swordRefineEffectRight = EFFECT_REFINED + EFFECT_SWORD_EFF_START + dwEff;

    You just need to have the values ordered ascendingly.

    • Love 1
  5. Just if you use SQLMsg* pkMsg then it's called a raw pointer and you've to delete it manually, but for std::unique_ptr<SQLMsg>, you don't have to do it, has no effects the reset method in this case.


    The benefit of using smart pointers like unique_prt || shared_ptr is that they automatically delete the pointed object when no longer needed (i.e. out of scope).

    This is the hidden content, please

     

    • Metin2 Dev 28
    • Confused 1
    • Good 9
    • Love 1
    • Love 27
  6.   

    3 hours ago, Sevence™ said:

    new team metin2dev definitely does not cope with the administration of this forum.

    That's right, I want to see your reaction when your players of a private server, saying the same thing about your staff when the server it's down because of your provider and they've no idea what's behind of it.

    And guess what? You'll get insults also, because they pay you with tens of thousands of euros.

     

    So, do you think your reply it's right in this case with metin2dev? When you just open the forum and download resources? I don't think so.

    This staff bought the forum when it was dead and paying a lot for it from their pocket and they will not get that amount of money even in years (they also have jobs and other things), so you're attitude it's very bad.

    That's a reply from a human being, not from staff.

    • Love 9
  7. I didn't took it personal, I explained everything nicely.

    The thing with "typical metin2 developers", was general, not for you and it's because in the last period I saw a bunch of people who said they rewrote things and in reality they just added "auto" on everything and that's all, 2020 style.. but c++11 it's available since 9 years.

    But seems you got it wrong.

    • Love 1
  8. 51 minutes ago, ManiacRobert said:

    A "2020 style" if someone need

    
    
    
    	auto ignore = std::array<DWORD, 6>{SKILL_HOSIN, SKILL_REFLECT, SKILL_GICHEON, SKILL_JEONGEOP, SKILL_KWAESOK, SKILL_JEUNGRYEOK};
    	if (std::find(std::begin(ignore), std::end(ignore), dwType) != std::end(ignore))

     

     

    I would understand if you really posted a "2020 style" after 3 years (released in 2017) ... but you did it worst than actually is, if you think a std::array and std::find it's better than a switch for 6 values which are static, that's really wrong.

    Also you're redeclaring the std::aray variable each time when the function it's called, that's not 2020 anymore.

     

    Basically if you really want something called "2020", this is:

    static const std::set<std::uint8_t> ignoreSkillSet = {SKILL_HOSIN, SKILL_REFLECT, SKILL_GICHEON, SKILL_JEONGEOP, SKILL_KWAESOK, SKILL_JEUNGRYEOK};
    if (ignoreSkillSet.contains(dwType))
    {
    	const auto& affect = FindAffect(dwType);
    	if (affect && affect->lApplyValue > lApplyValue)
    		return false;
    }

     

    But still, switch is better than everything what you could do with your "2020 style", in this case.

    switch (dwType)
    {
    	case SKILL_HOSIN:
    	case SKILL_REFLECT:
    	case SKILL_GICHEON:
    	case SKILL_JEONGEOP:
    	case SKILL_KWAESOK:
    	case SKILL_JEUNGRYEOK:
    	{
    		[...]
    	}
    	break;
    }

     

    But it's fine, seems you're that type of guy who's using "auto" on everything and think that's cool and 2020 style, typical for metin2 "developers".

    • Metin2 Dev 1
    • Angry 1
    • Lmao 1
    • Love 4
  9. M2 Download Center

    This is the hidden content, please
    ( Internal )

    8ef68592c3f5627a244b93f55d67b440.png

     

    As the title says, here's how you can synchronize your skill_table from client with skill_proto from server.

    [1]. First of all we've to rewrite the enum part of tokens (which is used in CPythonSkill::RegisterSkillTable), that means we change the order of index-tab-line with a new order, because ymir didn't used all columns. In that way we keep the file much cleaner and just with necessary columns (9 columns instead of 27).

    Spoiler
    // Not used
    TABLE_TOKEN_TYPE_NAME
    TABLE_TOKEN_TYPE_TYPE
    TABLE_TOKEN_TYPE_LEVEL_STEP
    TABLE_TOKEN_TYPE_POINT_ON
    TABLE_TOKEN_TYPE_MASTER_BONUS_POLY
    TABLE_TOKEN_TYPE_ATTACK_GRADE_POLY
    TABLE_TOKEN_TYPE_FLAG
    TABLE_TOKEN_TYPE_AFFECT_FLAG
    TABLE_TOKEN_TYPE_POINT_ON2
    TABLE_TOKEN_TYPE_POINT_POLY2
    TABLE_TOKEN_TYPE_DURATION_POLY2
    TABLE_TOKEN_TYPE_AFFECT_FLAG2
    TABLE_TOKEN_TYPE_PREREQUISITE_SKILL_VNUM
    TABLE_TOKEN_TYPE_PREREQUISITE_SKILL_LEVEL
    TABLE_TOKEN_TYPE_SKILL_TYPE
    TABLE_TOKEN_TYPE_MAX_HIT
    TABLE_TOKEN_TYPE_SPLASH_AROUND_DAMAGE_ADJUST_POLY
    TABLE_TOKEN_TYPE_SPLASH_RANGE

     


    Srcs/Client/UserInterface/PythonSkill.h

    Search for the next enum:

    Spoiler
    		enum ESkillTableTokenType
    		{
    			[...]
    		};

     

    Replace it with:

    Spoiler
    #ifdef ENABLE_SKILL_TABLE_RENEW
    		enum ESkillTableTokenType
    		{
    			TABLE_TOKEN_TYPE_VNUM,
    			TABLE_TOKEN_TYPE_MAX_LEVEL,
    			TABLE_TOKEN_TYPE_LEVEL_LIMIT,
    			TABLE_TOKEN_TYPE_POINT_POLY,
    			TABLE_TOKEN_TYPE_SP_COST_POLY,
    			TABLE_TOKEN_TYPE_DURATION_POLY,
    			TABLE_TOKEN_TYPE_DURATION_SP_COST_POLY,
    			TABLE_TOKEN_TYPE_COOLDOWN_POLY,
    			TABLE_TOKEN_TYPE_TARGET_RANGE,
    			TABLE_TOKEN_TYPE_MAX_NUM,
    		};
    #else
    		enum ESkillTableTokenType
    		{
    			TABLE_TOKEN_TYPE_VNUM,
    			TABLE_TOKEN_TYPE_NAME,
    			TABLE_TOKEN_TYPE_TYPE,
    			TABLE_TOKEN_TYPE_LEVEL_STEP,
    			TABLE_TOKEN_TYPE_MAX_LEVEL,
    			TABLE_TOKEN_TYPE_LEVEL_LIMIT,
    			TABLE_TOKEN_TYPE_POINT_ON,
    			TABLE_TOKEN_TYPE_POINT_POLY,
    			TABLE_TOKEN_TYPE_SP_COST_POLY,
    			TABLE_TOKEN_TYPE_DURATION_POLY,
    			TABLE_TOKEN_TYPE_DURATION_SP_COST_POLY,
    			TABLE_TOKEN_TYPE_COOLDOWN_POLY,
    			TABLE_TOKEN_TYPE_MASTER_BONUS_POLY,
    			TABLE_TOKEN_TYPE_ATTACK_GRADE_POLY,
    			TABLE_TOKEN_TYPE_FLAG,
    			TABLE_TOKEN_TYPE_AFFECT_FLAG,
    			TABLE_TOKEN_TYPE_POINT_ON2,
    			TABLE_TOKEN_TYPE_POINT_POLY2,
    			TABLE_TOKEN_TYPE_DURATION_POLY2,
    			TABLE_TOKEN_TYPE_AFFECT_FLAG2,
    			TABLE_TOKEN_TYPE_PREREQUISITE_SKILL_VNUM,
    			TABLE_TOKEN_TYPE_PREREQUISITE_SKILL_LEVEL,
    			TABLE_TOKEN_TYPE_SKILL_TYPE,
    			TABLE_TOKEN_TYPE_MAX_HIT,
    			TABLE_TOKEN_TYPE_SPLASH_AROUND_DAMAGE_ADJUST_POLY,
    			TABLE_TOKEN_TYPE_TARGET_RANGE,
    			TABLE_TOKEN_TYPE_SPLASH_RANGE,
    			TABLE_TOKEN_TYPE_MAX_NUM,
    		};
    #endif

     

    Srcs/Client/UserInterface/Locale_Inc.h

    Spoiler
    #define ENABLE_SKILL_TABLE_RENEW // Enable synchronization skill_proto -> skilltable

     

     

    [2]. Compile the source client again.

    [3]. Open Navicat (preferably the latest versions) and do the following things:

    • Open player table
    • Export Wizard -> Mark skill_proto -> Export to ../location/skilltable.txt
    • Export format -> *.txt
    • Unmark All fields then Unselect All
    • Select available fields: -> {'dwVnum', 'bMaxLevel', 'bLevelLimit', 'szPointPoly', 'szSPCostPoly', 'szDurationPoly', 'szDurationSPCostPoly', 'szCooldownPoly', 'dwTargetRange'}
    • Unmark: Include column titles
    • Text Qualifier: None
    • Copy the skilltable.txt from Desktop to ../locale/en/

     

    HOW-TO - VIDEO (The video is just an example, please follow the tutorial from step [3])

    This is the hidden content, please

     

     

    Thanks to @Syreldar for the idea.

    • Metin2 Dev 105
    • Confused 2
    • Scream 3
    • Good 49
    • Love 11
    • Love 95
  10. 12 minutes ago, DevChuckNorris said:

    Okay that hurt...

    I mean it was good when you was banned...

    I mean.. it was good when @Shogunwas an admin...

    But let's move on, we can't travel back in time. ?

    3 minutes ago, DevChuckNorris said:

    You know there was never a time where only Shogun was an admin right? :D

    Sure, the rest were not important for other members. :(

    But as I said, let's don't look in the past.

  11. 2 minutes ago, masodikbela said:

    At this point I must say that there might be some real scam going on in the background. Here is some more evidence:

    That's right, they didn't wrote the real term of "ad-free", just lies.

    If you choose me right now then I'll hide all ads for VIP members.

    • Lmao 1
    • Love 1
  12. As you guys know, in this period there's a campain in all countries, If you choose me as an administrator, I'll do the following things:

    • permanently ban @DevChuckNorris @pollux
    • remove service section
    • add a new category of nsfw
    • add possibility to have 5 banners in header in the same time
    • remove like/reactions on posts
    • hide the whole content of forum for guests
    • remove grades like developer/3D artist/...
    • no signature
    • account name should be just as numbers, no characters at all, ex: 827192030, 10000391
    • no more bumping
    • no reports, already I know everything
    • you can speak in all languages (even arabic/turkish), not just english
    • and more..just vote me and ban @ASIKOO

     

    • Scream 2
    • Love 4
  13. The poll has closed now, 56 members have voted.

    • Yes, 43 votes (75.44%) ✅
    • No, 14 votes (24.56%)

     

    I will start from now to review all of the topics from that section and remove the ones which doesn't fulfill the conditions.

     

    Edit:

    The following sections were reviewed:

     

    If you've something to tell about those actions, send me a PM.

    But first, read the content of this topic, don't send a message "why my topic is deleted, I'm not a scammer/reseller", thanks.

     

    • Confused 1
    • Love 1
  14. Hi!

    After a long discussion with the whole staff, we decided to make some changes in the Service&Sales section.

    That's because in the last years we met a lot of resellers/scammers here in the forum.

    What we can do at the moment as a fast solution, is to make some changes in our rules.

     

    In that way, we will keep the quality instead of quantity, right now we've over 130 topics in this section and over 50% are not active.

    Most of the users who opened a service until now were like this:

    • account created in 2014, 10 posts
    • account created in 2014, 300 posts, no activity in the last years
    • account created in 2018, 10 posts
    • account created in 2020, 50 posts

    ______________________________________________________________________________________________________________________

    So, we're trying to avoid those things and make some changes for help you with a better quality.

    They should fulfill the next conditions for being able to offer their service in metin2dev:

    • at least 200 posts + registered for more than 2 years + being active over the last 6 months (releases and others)

    [Exception] Those conditions will not be applied in the next cases (but you still will need to help somehow the community itself too, not just selling your services):

    1. You're very good known for your reputation and you had a clean background in the last years and the staff is trusting you.
    2. You're recommended by an user who fulfill the [1] condition.

     

    I want to mention also:

    • current topics will be reviewed again and those which doesn't satisfy the conditions will be deleted.
    • subject approval will have multiple conditions that you'll know after you'll create the topic.

     

    If you're planning to do any form of reselling/scamming in metin2dev, stay away, we've our eyes on you.

    ______________________________________________________________________________________________________________________

    Don't forget also you can contact VegaS™ or Raylee via those links (PM) to report a reseller/scammer with specific proofs.

    Don't forget to vote and do it right!

    • Not Good 2
    • Sad 1
    • Confused 1
    • Lmao 1
    • Love 15
  15. I sent him the code to PM some months ago for test, he said would be nice if I post here too, so here's:

    GameLib/PythonPlayerInput.cpp

    Search for:

    void CPythonPlayer::__SetAutoAttackTargetActorID(DWORD dwVID)
    {
     	m_dwAutoAttackTargetVID = dwVID;
    }

    Replace it with:

    This is the hidden content, please

    UserInterface/InstanceBase.h

    Make the function public from protected.

    		static bool __FindPVPKey(DWORD dwSrcVID, DWORD dwDstVID);

    UserInterface/Locale_Inc.h

    #define ENABLE_BLOCK_AUTO_ATTACK_DUEL

     

     

    • Metin2 Dev 17
    • Think 1
    • Confused 1
    • Good 4
    • Love 6
  16. 18 minutes ago, Bizzy said:
    
    isActivated, usedAmount, totalAmount = metinSocket[:3]

    important? but why that?

     

    a, b, c = 1, 2, 3
    a, b, c = (1, 2, 3)
    (a, b, c) = 1, 2, 3
    (a, b, c) = (1, 2, 3)
    

    All of the methods are doing same.

    isActivated = 0 != metinSocket[0]
    usedAmount = int(metinSocket[1])
    totalAmount = int(metinSocket[2])
    
    # examples
    isActivated, usedAmount, totalAmount = map(int, metinSocket[:3])
    isActivated, usedAmount, totalAmount = metinSocket[:3]
    isActivated, usedAmount, totalAmount = metinSocket[0], metinSocket[1], metinSocket[2]
    isActivated, usedAmount, totalAmount = metinSocket

    I choosed metinSocket[:3], for being sure that's reading just the first three items from the list, because other people have 3+ sockets.

     

    Please follow the rules:

    Rules

    §1 Language

    (1.1) Language

    The language in this board is english. If you want to post something in your own language always add an english translation. The only exception for this rule is this section: Private Servers

     

    • Love 1
  17. Quote
    				if itemVnum >= 72723 and itemVnum <= 72726:
    					metinSocket = [player.GetItemMetinSocket(slotNumber, j) for j in xrange(player.METIN_SOCKET_MAX_NUM)]# <!> globalSlotNumber may be different <!>
    					if isActivated:
    						self.wndItem.ActivateSlot(i, (238.00 / 255.0), (000.00 / 255.0), (000.00 / 255.0), 1.0)
    					else:
    						self.wndItem.DeactivateSlot(slotNumber)
    				
    				if itemVnum >= 72727 and itemVnum <= 72730:
    					metinSocket = [player.GetItemMetinSocket(slotNumber, j) for j in xrange(player.METIN_SOCKET_MAX_NUM)]# <!> globalSlotNumber may be different <!>
    					if isActivated:
    						self.wndItem.ActivateSlot(i, (000.00 / 255.0), (000.00 / 255.0), (238.00 / 255.0), 1.0)
    					else:
    						self.wndItem.DeactivateSlot(slotNumber)

     

    I didn't tested your code, but how you implemented this it's bad because you called multiple times ActivateSlot and DeactivateSlot for no reason (before your code already there're other conditions that are called), so you create small visual bugs for a millisecond. 

    So, you could include it in the default code like this:

     

    Search for:

    Spoiler
    				isActivated = 0 != metinSocket[0]
    
    				if isActivated:
    					self.wndItem.ActivateSlot(slotNumber)
    					potionType = 0;
    					if constInfo.IS_AUTO_POTION_HP(itemVnum):
    						potionType = player.AUTO_POTION_TYPE_HP
    					elif constInfo.IS_AUTO_POTION_SP(itemVnum):
    						potionType = player.AUTO_POTION_TYPE_SP
    
    					usedAmount = int(metinSocket[1])
    					totalAmount = int(metinSocket[2])
    					player.SetAutoPotionInfo(potionType, isActivated, (totalAmount - usedAmount), totalAmount, self.__InventoryLocalSlotPosToGlobalSlotPos(i))
    
    				else:
    					self.wndItem.DeactivateSlot(slotNumber)

    Replace with:

    Spoiler
    				isActivated, usedAmount, totalAmount = metinSocket[:3]
    				if isActivated:
    					potionType = 0
    					if constInfo.IS_AUTO_POTION_HP(itemVnum):
    						potionType = player.AUTO_POTION_TYPE_HP
    						self.wndItem.ActivateSlot(slotNumber, (238.00 / 255.0), (000.00 / 255.0), (000.00 / 255.0), 1.0)
    						
    					elif constInfo.IS_AUTO_POTION_SP(itemVnum):
    						potionType = player.AUTO_POTION_TYPE_SP
    						self.wndItem.ActivateSlot(slotNumber, (000.00 / 255.0), (000.00 / 255.0), (238.00 / 255.0), 1.0)
    
    					player.SetAutoPotionInfo(potionType, isActivated, (totalAmount - usedAmount), totalAmount, slotNumber)
    				else:
    					self.wndItem.DeactivateSlot(slotNumber)

     


    Also you should say that the function ActivateSlot by default doesn't have those features.

     

    Meme for the math method:

    .png

    • Love 3
  18. I'm sure that you saw my graphic mask from some years ago.

    Here you can hide the 'terrain''object''cloud''water''tree', and you can disable the effects and more too if you take a look inside of GameLib.

    That feature class allows you to hide specific effects, tree, bulding by property crc or name (not done yet).

     

    You''ll need also:

    I'll not make a full how-to right now, just take a look, implement the class, call it and do some changes as you want, you've more than the basic idea. ?

    • graphic_mask/building.txt
    general_obj_stone14
    ob-b1-005-woodbarrel
    landmark_statuestone
    B_general_obj_40
    general_obj_jar_yellow01
    • graphic_mask/effect.txt
    8182371290
    1003918098
    volcano_greatsmoke.mse
    warpgate01
    fall_7
    fire_general_obj_charcoal.mse

     

    GameLib/Area.cpp

     

    This is the hidden content, please

    UserInterface/PythonGraphicMask.cpp

    Spoiler
    
    /*********************************************************************
    * title_name		: Test Graphic Mask
    * date_created		: 2018.04.21
    * filename			: PythonGraphicMask.cpp
    * author			: VegaS
    * version_actual	: Version 0.1
    */
    
    #include "stdafx.h"
    #if defined(ENABLE_GRAPHIC_MASK)
    #include "PythonGraphicMask.h"
    #include "PythonSystem.h"
    #include "../GameLib/MapOutdoor.h"
    #include "../GameLib/MapType.h"
    
    CPythonGraphicMask::CPythonGraphicMask()
    {
    	Initialize(PROPERTY_TYPE_NONE, "graphic_mask/default.txt");
    	Initialize(PROPERTY_TYPE_TREE, "graphic_mask/tree.txt");
    	Initialize(PROPERTY_TYPE_BUILDING, "graphic_mask/building.txt");
    	Initialize(PROPERTY_TYPE_EFFECT, "graphic_mask/effect.txt");
    }
    
    CPythonGraphicMask::~CPythonGraphicMask()
    {
    	Destroy();
    }
    
    void CPythonGraphicMask::Initialize(const BYTE bPropertyType, const char * c_pszFileName)
    {
    	m_vecMaskObjectCRC[bPropertyType].clear();
    	
    	if (bPropertyType == PROPERTY_TYPE_NONE)
    		return;
    
    	auto* fp = fopen(c_pszFileName, "r");
    	if (!fp)
    	{
    		Tracef("Can't open file %s.", c_pszFileName);
    		return;
    	}
    
    	char line[256];
    	while (fgets(line, sizeof(line) - 1, fp))
    	{
    		const auto& dwCRC = strtoul(line, nullptr, 0);
    		m_vecMaskObjectCRC[bPropertyType].push_back(dwCRC);
    	}
    }
    
    void CPythonGraphicMask::Destroy()
    {
    	for (auto& i : m_vecMaskObjectCRC)
    		i.clear();
    }
    
    bool CPythonGraphicMask::IsEnabled(BYTE bPropertyType) const
    {
    	if (bPropertyType >= PROPERTY_TYPE_MAX_NUM)
    		return false;
    	
    	switch (bPropertyType)
    	{
    		case prt::PROPERTY_TYPE_TREE:
    			bPropertyType = CMapOutdoor::PART_TREE;
    			break;
    		case prt::PROPERTY_TYPE_BUILDING:
    			bPropertyType = CMapOutdoor::PART_OBJECT;
    			break;
    		case prt::PROPERTY_TYPE_EFFECT:
    			bPropertyType = CMapOutdoor::PART_EFFECT;
    			break;
    		default:
    			break;
    	}
    	
    	static auto& rkSystem = CPythonSystem::Instance();
    	return rkSystem.GetGraphicMaskPart(bPropertyType);
    }
    
    bool CPythonGraphicMask::GetObjectByCRC(const BYTE bPropertyType, const DWORD dwCRC) const
    {
    	if (bPropertyType >= PROPERTY_TYPE_MAX_NUM)
    		return false;
    
    	return std::count(m_vecMaskObjectCRC[bPropertyType].begin(), m_vecMaskObjectCRC[bPropertyType].end(), dwCRC) > 0;
    }
    #endif

     

    UserInterface/PythonGraphicMask.h

    Spoiler
    
    #pragma once
    
    class CPythonGraphicMask : public CSingleton<CPythonGraphicMask>
    {
    	public:
    		CPythonGraphicMask();
    		virtual ~CPythonGraphicMask();
    
    		enum
    		{
    			PROPERTY_TYPE_NONE,
    			PROPERTY_TYPE_TREE,
    			PROPERTY_TYPE_BUILDING,
    			PROPERTY_TYPE_EFFECT,
    			PROPERTY_TYPE_MAX_NUM,
    		};
    	
    		void		Initialize(const BYTE bPropertyType, const char * c_pszFileName);
    		void		Destroy();
    
    		bool		GetObjectByCRC(const BYTE bPropertyType, const DWORD dwCRC) const;
    		bool		IsEnabled(BYTE bPropertyType) const;
    	protected:
    		std::vector<DWORD> m_vecMaskObjectCRC[PROPERTY_TYPE_MAX_NUM];
    };

     

    UserInterface/PythonSystem.cpp

    Spoiler
    
    #if defined(ENABLE_GRAPHIC_MASK)
    bool CPythonSystem::GetGraphicMaskPart(const BYTE bPart) const
    {
    	switch (bPart)
    	{
    		case CMapOutdoor::PART_TERRAIN:
    			return m_Config.bGraphicMaskTerrain;
    		case CMapOutdoor::PART_OBJECT:
    			return m_Config.bGraphicMaskObject;
    		case CMapOutdoor::PART_CLOUD:
    			return m_Config.bGraphicMaskCloud;
    		case CMapOutdoor::PART_WATER:
    			return m_Config.bGraphicMaskWater;
    		case CMapOutdoor::PART_TREE:
    			return m_Config.bGraphicMaskTree;
    		case CMapOutdoor::PART_EFFECT:
    			return m_Config.bGraphicMaskEffect;
    	}
    
    	return false;
    }
    
    void CPythonSystem::SetGraphicMaskPart(const BYTE bPart, const bool bFlag)
    {
    	switch (bPart)
    	{
    		case CMapOutdoor::PART_TERRAIN:
    			m_Config.bGraphicMaskTerrain = bFlag;
    			break;
    		case CMapOutdoor::PART_OBJECT:
    			m_Config.bGraphicMaskObject = bFlag;
    			break;
    		case CMapOutdoor::PART_CLOUD:
    			m_Config.bGraphicMaskCloud = bFlag;
    			break;
    		case CMapOutdoor::PART_WATER:
    			m_Config.bGraphicMaskWater = bFlag;
    			break;
    		case CMapOutdoor::PART_TREE:
    			m_Config.bGraphicMaskTree = bFlag;
    			break;
    		case CMapOutdoor::PART_EFFECT:
    			m_Config.bGraphicMaskEffect = bFlag;
    			break;
    	}
    }
    #endif

     

     

     

     

    • Metin2 Dev 2
    • Eyes 1
    • Good 1
    • Love 5
  19. 1 hour ago, Alerin said:

    Function void CPythonSystem::SetDefaultConfig() is responsible for creating the first config when starting the game for the first time.

      

    The function SetDefaultConfig it's called everytime before LoadConfig when the singleton it's initialized.

    Yes, first it will load the default values then will try to read the values from metin2.cfg, so if you put specific width/height in the default config everything it's fine for the first run.

     

    1 hour ago, Alerin said:

    This is a lock so that the client cannot run at a resolution lower than 800x600. (Lots of people run m2bob in 10x10 so it takes me resources)

     

    Is impossible for a player to have a resolution lower than 800x600 if he set it from config.exe.

    What you did is just for the people who editing metin2.cfg manually, like m2bob does, otherwise has no sense that check inside of the LoadConfig.

    We should block the hacks, not doing workaround conditions for "consuming more resources by resolution if the hackers has the resolution < 800x600", just saying. 

     

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