Jump to content

Cunoo

Inactive Member
  • Posts

    326
  • Joined

  • Last visited

  • Feedback

    0%

Posts posted by Cunoo

  1. 10 hours ago, ReFresh said:

    Hello guys,

    have someone some function which will check empire of player via server source when player login?

    It must work like: If player is in Pyungmoo then it will check his empire and if player empire != Pyungmoo then it will warp player to his local town etc. It must check local towns with player empire. 

    I need to have this function because when you change the empire via quest, player can disconnect his account in changing empire state by connecting to server again and then when he login he has empire changed but he will still in town of another empire.

    Thanks for possible answers!

    Sincerely,

    ReFresh

    I don't have source check, but I think you can do it with quest specifically in empire change quest with simple check.. I think could be do at least 2+ variant.. Simple variant is add automatic warp in your new empire.. I think you dont must totally logout account, because warp too reload all needed informations..

  2. I'm not 100% sure, but I think problem is in ClientBootManager or something merge files.. Try to check simply with mob_proto function.. Because I think all leaked 2014 sources have this problem.. (only item_proto have this problem.. There is missing little code part) I can check it too late (now i go sleep) but I fixed it 3 years ago.. So I can help you.

  3. 11 hours ago, superkonto said:

    Not true.

     

     

    You have absolutely no idea what are you talking about.

    Any ilegal work where you are not bound by contract is hobby.. Why? Because you can't legalized it.. You think someone does this for a living and nothing else? Maybe yes, but time running out.. ;) I live near Germany and believe me a server that can support you with money is in plain sight of the gf. And all the attempts at legalization under the guise of fictitious companies and product are just ilegal cover. Just because no one is looking at it doesn't mean there won't be an initiative to do so in the future.

    2 hours ago, TMP4 said:

    It depends what you are asking. Selling complete Metin2 files are copyright infringement all over the EU because common union laws.

    In the other hand, selling add-ons probably not. You just need to accounting them as custom software development or similar in tax return and in that case actually just the buyer commits copyright infringement since you are not required by any law to check your client's it-system about copyright. Ofc if you have a webshop showcasing your M2 systems that's not really "custom software development" at all but still you have much better chance to get away with it.

    They're doing at their own risk what they are doing. I can understand that some people pay their price to cut off their development time to start their server. It's demand and supply.

    My only problem is the price at some seller. Because the demand is high and the supply is low, they went sky rocket.

      Reveal hidden contents

    By the way you may know but having a metin2 server is copyright infringement too. Not as high as selling other's property because you just using it actually, but still.

     

    Sorry for doublepost. 

    But I mean this is not complete truth.. Why? Because if you has e-shop or something like this.. You can sell systems or apps without hit and looking in metin source.. So if you hook your code in copyrighted source it is just illegal.. And I think the rules for doing business with a product determine what you can sell... and that certainly doesn't include malware..

  4. True is you can buy only illegal software... All project's from "developers" are illegal and you makes money for this guys.. Too many people's make money from server and leave it with new project.. Because this don't have a future..  If you want good source, do math earnings vs losed money, if you rlly want start project.. For all mt2 developers is metin just hobby.. All make some features for nothing (read nothing to money) and if you really want clean start source.. The best way is start programming.. Learn more about languages.. Metin is good start for understanding about this.. But too big chance is you can't create something good and legal..  My advice is, don't support this guys..

  5. 1 hour ago, I3ooI3oo said:

    What do you mean? I can't understand what you mean with that message. That dynamic imports are from Overfall2. (It's not hard to remove them, pretty easy.)

    Helping with leaked server files is against metin2.dev rules.

    A pro boha, nepoužívej ten nechutnej translate.

     

     

    I don't use translator, but I have installed extension in my phone for translate Italian language.. And this extension automatically translate quote's.. Now to topic.. 

    I want say only this:

    1. How you know about Overfall2? If you're so principled? You simply studied the files... (this is what I mean)

    2. This rule is complete bullshit. Why? Because metin itself is leaked!!!

    3. If we want to play moralists ourselves, so we can delete all files from hdd.

    4. I think it's hypocrisy to break a rule and demand the same rule from others!

    5. If owner cannot secure the leak, he should not collect user data.. WTF?

     

    So all I'm saying is that to slap a "copyright" on something where it's already fundamentally disrespected is a monstrosity. That's all.. 

    • Not Good 1
    • Love 1
  6. Hi,

    I have a problem with these files on this forum.
    I think problem is not with me but in code itself.
    Why? Because we have tested it in several peoples and the error is manifested in all of them..
    The paradox is that maybe it has not been detected yet, because many peoples do not even use this feature.

    Problem is here with that feature

    bool removeRefineEffect = true;


    In short, if you add new shining for example sword+9 you cant see normal refine effect its hidden.. But this working only for weapon and costume weapon..Armor and costume armor is ignored... You take double effect (normal refine + new custom set in shining_table)
    Here is all code from InstanceBase.cpp

    Spoiler
    void CInstanceBase::__GetShiningEffect(CItemData* pItem)
    {
        bool removeRefineEffect = true;
     
        CItemData::TItemShiningTable shiningTable = pItem->GetItemShiningTable();
     
        if (pItem->GetType() == CItemData::ITEM_TYPE_WEAPON || (pItem->GetType() == CItemData::ITEM_TYPE_COSTUME && pItem->GetSubType() == CItemData::COSTUME_WEAPON))
        {
            BYTE bSubType = pItem->GetType() == CItemData::ITEM_TYPE_COSTUME && pItem->GetSubType() == CItemData::COSTUME_WEAPON ? pItem->GetValue(3) : pItem->GetSubType();
     
            __ClearWeaponShiningEffect();
     
            if (shiningTable.Any() && removeRefineEffect)
            {
                __ClearWeaponRefineEffect();
            }
     
            for (int i = 0; i < CItemData::ITEM_SHINING_MAX_COUNT; i++)
            {
                if (strcmp(shiningTable.szShinings[i], ""))
                {
                    if (bSubType == CItemData::WEAPON_BOW)
                    {
                        __AttachWeaponShiningEffect(i, shiningTable.szShinings[i], "PART_WEAPON_LEFT");
                    }
                    else
                    {
                        bool twoSidedWeapon = bSubType == CItemData::WEAPON_DAGGER || (IsMountingHorse() && bSubType == CItemData::WEAPON_FAN);
     
                        if (twoSidedWeapon)
                        {
                            __AttachWeaponShiningEffect(i, shiningTable.szShinings[i], "PART_WEAPON_LEFT");
                        }
     
                        __AttachWeaponShiningEffect(i, shiningTable.szShinings[i], "PART_WEAPON");
                    }
                }
            }
        }
     
        if ((pItem->GetType() == CItemData::ITEM_TYPE_ARMOR && pItem->GetSubType() == CItemData::ARMOR_BODY) || (pItem->GetType() == CItemData::ITEM_TYPE_COSTUME && pItem->GetSubType() == CItemData::COSTUME_BODY))
        {
            __ClearArmorShiningEffect();
     
            if (shiningTable.Any() && removeRefineEffect)
            {
                __ClearArmorRefineEffect();
            }
     
            for (int i = 0; i < CItemData::ITEM_SHINING_MAX_COUNT; i++)
            {
                if (strcmp(shiningTable.szShinings[i], ""))
                {
                    __AttachArmorShiningEffect(i, shiningTable.szShinings[i]);
                }
            }
        }
    }
     
    void CInstanceBase::__AttachWeaponShiningEffect(int effectIndex, const char* effectFileName, const char* boneName)
    {
        if (IsAffect(AFFECT_INVISIBILITY))
        {
            return;
        }
     
        if (effectIndex >= CItemData::ITEM_SHINING_MAX_COUNT)
        {
            return;
        }
     
        CEffectManager::Instance().RegisterEffect(effectFileName, false, false);
     
        if (!strcmp(boneName, "PART_WEAPON"))
        {
            const char* c_szRightBoneName;
     
            m_GraphicThingInstance.GetAttachingBoneName(CRaceData::PART_WEAPON, &c_szRightBoneName);
     
            if (strcmp(c_szRightBoneName, ""))
            {
                m_weaponShiningEffects[0][effectIndex] = m_GraphicThingInstance.AttachEffectByName(0, c_szRightBoneName, effectFileName);
            }
        }
        else if (!strcmp(boneName, "PART_WEAPON_LEFT"))
        {
            const char* c_szLeftBoneName;
     
            m_GraphicThingInstance.GetAttachingBoneName(CRaceData::PART_WEAPON_LEFT, &c_szLeftBoneName);
     
            if (strcmp(c_szLeftBoneName, ""))
            {
                m_weaponShiningEffects[1][effectIndex] = m_GraphicThingInstance.AttachEffectByName(0, c_szLeftBoneName, effectFileName);
            }
        }
        else
        {
            Tracef("Invalid partname for getting attaching bone name. %s - %s", effectFileName, boneName);
        }
    }
     
    void CInstanceBase::__AttachArmorShiningEffect(int effectIndex, const char* effectFileName, const char* boneName)
    {
        if (IsAffect(AFFECT_INVISIBILITY))
        {
            return;
        }
     
        if (effectIndex >= CItemData::ITEM_SHINING_MAX_COUNT)
        {
            return;
        }
     
        if (!strcmp(boneName, ""))
        {
            Tracef("Empty bone name for attaching armor shining. Effect Index: %i, EffectFileName: %s", effectIndex, effectFileName);
            return;
        }
     
        CEffectManager::Instance().RegisterEffect(effectFileName, false, false);
        m_armorShiningEffects[effectIndex] = m_GraphicThingInstance.AttachEffectByName(0, boneName, effectFileName);
    }
     
    void CInstanceBase::__ClearWeaponShiningEffect(bool detaching)
    {
        if (detaching)
        {
            for (int i = 0; i < CItemData::ITEM_SHINING_MAX_COUNT; i++)
            {
                if (m_weaponShiningEffects[0][i])
                {
                    __DetachEffect(m_weaponShiningEffects[0][i]);
                }
                if (m_weaponShiningEffects[1][i])
                {
                    __DetachEffect(m_weaponShiningEffects[1][i]);
                }
            }
        }
     
        memset(&m_weaponShiningEffects, 0, sizeof(m_weaponShiningEffects));
    }
     
    void CInstanceBase::__ClearArmorShiningEffect(bool detaching)
    {
        if (detaching)
        {
            for (int i = 0; i < CItemData::ITEM_SHINING_MAX_COUNT; i++)
            {
                if (m_armorShiningEffects[i])
                {
                    __DetachEffect(m_armorShiningEffects[i]);
                }
            }
        }
     
        memset(&m_armorShiningEffects, 0, sizeof(m_armorShiningEffects));
    }

     

    And these member functions

    Spoiler
    bool CInstanceBase::SetWeapon(DWORD eWeapon)
    {
        if (IsPoly())
            return false;
     
        if (__IsShapeAnimalWear())
            return false;
     
        if (__IsChangableWeapon(eWeapon) == false)
            eWeapon = 0;
     
        m_GraphicThingInstance.AttachWeapon(eWeapon);
        m_awPart[CRaceData::PART_WEAPON] = eWeapon;
     
        //Weapon Effect
        CItemData * pItemData;
        if (CItemManager::Instance().GetItemDataPointer(eWeapon, &pItemData))
        {
            if (pItemData->GetType() == CItemData::ITEM_TYPE_COSTUME)
            {
                __ClearWeaponRefineEffect();
                __ClearWeaponShiningEffect();
            }
     
            __GetRefinedEffect(pItemData);
            __GetShiningEffect(pItemData);
        }
        else
        {
            __ClearWeaponRefineEffect();
            __ClearWeaponShiningEffect();
        }
     
        return true;
    }
     
    void CInstanceBase::SetArmor(DWORD dwArmor)
    {
        DWORD dwShape;
        if (__ArmorVnumToShape(dwArmor, &dwShape))
        {
            CItemData * pItemData;
            if (CItemManager::Instance().GetItemDataPointer(dwArmor, &pItemData))
            {
                float fSpecularPower=pItemData->GetSpecularPowerf();
                SetShape(dwShape, fSpecularPower);
                __GetRefinedEffect(pItemData);
                __GetShiningEffect(pItemData);
                return;
            }
            else
            {
                __ClearArmorRefineEffect();
                __ClearArmorShiningEffect();
            }
        }
     
        SetShape(dwArmor);
    }

     

    I tried to detect problem but no matter what I tried and dug whole code, I came back to the beginning..

    Someone has an idea how to repair it? Because this can help too much peoples.

    Thanks anyway!

  7. I found another bug, but I think last.. (deep tested)

    InstanceBase.cpp

    bool removeRefineEffect = true;

    This doesn't work on armor.. Any solution? Trying solved this, but I failed in it.. I think problem is SetArmor..

    Here if anyone want check it // + for others, everything here is fixed except this little thing.

    Spoiler
    void CInstanceBase::__GetShiningEffect(CItemData* pItem)
    {
        bool removeRefineEffect = true;
     
        CItemData::TItemShiningTable shiningTable = pItem->GetItemShiningTable();
     
        if (pItem->GetType() == CItemData::ITEM_TYPE_WEAPON || (pItem->GetType() == CItemData::ITEM_TYPE_COSTUME && pItem->GetSubType() == CItemData::COSTUME_WEAPON))
        {
            BYTE bSubType = pItem->GetType() == CItemData::ITEM_TYPE_COSTUME && pItem->GetSubType() == CItemData::COSTUME_WEAPON ? pItem->GetValue(3) : pItem->GetSubType();
     
            __ClearWeaponShiningEffect();
     
            if (shiningTable.Any() && removeRefineEffect)
            {
                __ClearWeaponRefineEffect();
            }
     
            for (int i = 0; i < CItemData::ITEM_SHINING_MAX_COUNT; i++)
            {
                if (strcmp(shiningTable.szShinings[i], ""))
                {
                    if (bSubType == CItemData::WEAPON_BOW)
                    {
                        __AttachWeaponShiningEffect(i, shiningTable.szShinings[i], "PART_WEAPON_LEFT");
                    }
                    else
                    {
                        bool twoSidedWeapon = bSubType == CItemData::WEAPON_DAGGER || (IsMountingHorse() && bSubType == CItemData::WEAPON_FAN);
     
                        if (twoSidedWeapon)
                        {
                            __AttachWeaponShiningEffect(i, shiningTable.szShinings[i], "PART_WEAPON_LEFT");
                        }
     
                        __AttachWeaponShiningEffect(i, shiningTable.szShinings[i], "PART_WEAPON");
                    }
                }
            }
        }
     
        if ((pItem->GetType() == CItemData::ITEM_TYPE_ARMOR && pItem->GetSubType() == CItemData::ARMOR_BODY) || (pItem->GetType() == CItemData::ITEM_TYPE_COSTUME && pItem->GetSubType() == CItemData::COSTUME_BODY))
        {
            __ClearArmorShiningEffect();
     
            if (shiningTable.Any() && removeRefineEffect)
            {
                __ClearArmorRefineEffect();
            }
     
            for (int i = 0; i < CItemData::ITEM_SHINING_MAX_COUNT; i++)
            {
                if (strcmp(shiningTable.szShinings[i], ""))
                {
                    __AttachArmorShiningEffect(i, shiningTable.szShinings[i]);
                }
            }
        }
    }
     
    void CInstanceBase::__AttachWeaponShiningEffect(int effectIndex, const char* effectFileName, const char* boneName)
    {
        if (IsAffect(AFFECT_INVISIBILITY))
        {
            return;
        }
     
        if (effectIndex >= CItemData::ITEM_SHINING_MAX_COUNT)
        {
            return;
        }
     
        CEffectManager::Instance().RegisterEffect(effectFileName, false, false);
     
        if (!strcmp(boneName, "PART_WEAPON"))
        {
            const char* c_szRightBoneName;
     
            m_GraphicThingInstance.GetAttachingBoneName(CRaceData::PART_WEAPON, &c_szRightBoneName);
     
            if (strcmp(c_szRightBoneName, ""))
            {
                m_weaponShiningEffects[0][effectIndex] = m_GraphicThingInstance.AttachEffectByName(0, c_szRightBoneName, effectFileName);
            }
        }
        else if (!strcmp(boneName, "PART_WEAPON_LEFT"))
        {
            const char* c_szLeftBoneName;
     
            m_GraphicThingInstance.GetAttachingBoneName(CRaceData::PART_WEAPON_LEFT, &c_szLeftBoneName);
     
            if (strcmp(c_szLeftBoneName, ""))
            {
                m_weaponShiningEffects[1][effectIndex] = m_GraphicThingInstance.AttachEffectByName(0, c_szLeftBoneName, effectFileName);
            }
        }
        else
        {
            Tracef("Invalid partname for getting attaching bone name. %s - %s", effectFileName, boneName);
        }
    }
     
    void CInstanceBase::__AttachArmorShiningEffect(int effectIndex, const char* effectFileName, const char* boneName)
    {
        if (IsAffect(AFFECT_INVISIBILITY))
        {
            return;
        }
     
        if (effectIndex >= CItemData::ITEM_SHINING_MAX_COUNT)
        {
            return;
        }
     
        if (!strcmp(boneName, ""))
        {
            Tracef("Empty bone name for attaching armor shining. Effect Index: %i, EffectFileName: %s", effectIndex, effectFileName);
            return;
        }
     
        CEffectManager::Instance().RegisterEffect(effectFileName, false, false);
        m_armorShiningEffects[effectIndex] = m_GraphicThingInstance.AttachEffectByName(0, boneName, effectFileName);
    }
     
    void CInstanceBase::__ClearWeaponShiningEffect(bool detaching)
    {
        if (detaching)
        {
            for (int i = 0; i < CItemData::ITEM_SHINING_MAX_COUNT; i++)
            {
                if (m_weaponShiningEffects[0][i])
                {
                    __DetachEffect(m_weaponShiningEffects[0][i]);
                }
                if (m_weaponShiningEffects[1][i])
                {
                    __DetachEffect(m_weaponShiningEffects[1][i]);
                }
            }
        }
     
        memset(&m_weaponShiningEffects, 0, sizeof(m_weaponShiningEffects));
    }
     
    void CInstanceBase::__ClearArmorShiningEffect(bool detaching)
    {
        if (detaching)
        {
            for (int i = 0; i < CItemData::ITEM_SHINING_MAX_COUNT; i++)
            {
                if (m_armorShiningEffects[i])
                {
                    __DetachEffect(m_armorShiningEffects[i]);
                }
            }
        }
     
        memset(&m_armorShiningEffects, 0, sizeof(m_armorShiningEffects));
    }

     

    Spoiler
    bool CInstanceBase::SetWeapon(DWORD eWeapon)
    {
        if (IsPoly())
            return false;
     
        if (__IsShapeAnimalWear())
            return false;
     
        if (__IsChangableWeapon(eWeapon) == false)
            eWeapon = 0;
     
        m_GraphicThingInstance.AttachWeapon(eWeapon);
        m_awPart[CRaceData::PART_WEAPON] = eWeapon;
     
        //Weapon Effect
        CItemData * pItemData;
        if (CItemManager::Instance().GetItemDataPointer(eWeapon, &pItemData))
        {
            if (pItemData->GetType() == CItemData::ITEM_TYPE_COSTUME)
            {
                __ClearWeaponRefineEffect();
                __ClearWeaponShiningEffect();
            }
     
            __GetRefinedEffect(pItemData);
            __GetShiningEffect(pItemData);
        }
        else
        {
            __ClearWeaponRefineEffect();
            __ClearWeaponShiningEffect();
        }
     
        return true;
    }
     
    void CInstanceBase::SetArmor(DWORD dwArmor)
    {
        DWORD dwShape;
        if (__ArmorVnumToShape(dwArmor, &dwShape))
        {
            CItemData * pItemData;
            if (CItemManager::Instance().GetItemDataPointer(dwArmor, &pItemData))
            {
                float fSpecularPower=pItemData->GetSpecularPowerf();
                SetShape(dwShape, fSpecularPower);
                __GetRefinedEffect(pItemData);
                __GetShiningEffect(pItemData);
                return;
            }
            else
            {
                __ClearArmorRefineEffect();
                __ClearArmorShiningEffect();
            }
        }
     
        SetShape(dwArmor);
    }

     

     

    • Metin2 Dev 1
  8. 2 hours ago, .plechito&#x27; said:

    Myslím, že je to opravdu subjektivní pro každou osobu. 🙂 
    Pokud se podíváte na věci, které GF dnes vydává, už to nesedí do starého metinského stylu. Ale úplně rozumím tomu, co jsi napsal!🙂 

    Maybe that's why metin is in decline... Let's just say that the new stuff from 2013+ doesn't fit the game anymore... However, I don't mean that in a bad way towards you... As I said once before, I remember you from the old Lothira and I always appreciated your work. 🙂

    • Metin2 Dev 1
    • Cry 1
    • Think 1
    • Good 2
    • Love 1
  9. Idk.. Too much realistic.. I've always liked your work... But lately it seems to me that it's going too far forward and out of the standard... Maybe if you spent more time on implementing the whole world... I mean textures, directx, shaders, and adapting the whole global world to the models, then that would be it. I think the metin engine has a lot of potential but either the models are escaping the world or the world is escaping the models.. For example, look at the weapons from 2010-2012, how they look to the original game.. They fit perfectly, but today's weapons, armors, mounts, even though they are much nicer, they run away from the original graphics of the game.I would compare it to putting cars from gta 5 into gta san andreas. 😕

    • Good 2
  10. 22 minutes ago, Paladin said:

     

    I dont think i changed something  but i dont remember, i already compared with other sources instancebase.cpp is normal

    In client syserr there is 0704 12:54:10706 :: CEffectManager::RegisterEffect - LoadScript() Error
    0704 12:54:10706 :: CInstanceBase::RegisterEffect(eEftType=81, c_szEftAttachBone=, c_szEftName=, isCache=0) - Error but idk

    playersettingmodule.py in root. But I nevermind its original, because look at number of type 81????? Too much. Post here (idealy pastebin) instancebase.cpp, instancebase.h + playersettingmodule.py.. We have 0 informations about your case..

  11.  

    It's not good because metin2 has always been about trading as well. I mean, players would automatically look for the cheapest items in the shops. Plus it would force players to constantly lower prices because someone always wants to be cheaper to sell... I've seen this in other implementations, mainly through offline shops and it hasn't worked. Anyway, that's nice, but economically inappropriate.

  12. This is old topic, but if anyone want idea, here is my function...

    bool CHARACTER::DoRefineWithScroll(LPITEM item)
    {
    	if (!CanHandleItem(true))
    	{
    		ClearRefineMode();
    		return false;
    	}
    
    	ClearRefineMode();
    
    	const TRefineTable * prt = CRefineManager::instance().GetRefineRecipe(item->GetRefineSet());
    
    	if (!prt)
    		return false;
    
    	LPITEM pkItemScroll;
    
    	if (m_iRefineAdditionalCell < 0)
    		return false;
    
    	pkItemScroll = GetInventoryItem(m_iRefineAdditionalCell);
    
    	if (!pkItemScroll)
    		return false;
    
    	if (!(pkItemScroll->GetType() == ITEM_USE && pkItemScroll->GetSubType() == USE_TUNING))
    		return false;
    
    	if (pkItemScroll->GetVnum() == item->GetVnum())
    		return false;
    
    	DWORD result_vnum = item->GetRefinedVnum();
    	DWORD result_fail_vnum = item->GetRefineFromVnum();
    
    	if (result_vnum == 0)
    	{
    		ChatPacket(CHAT_TYPE_INFO, LC_TEXT("No advancement possible."));
    		return false;
    	}
    
    	TItemTable * pProto = ITEM_MANAGER::instance().GetTable(item->GetRefinedVnum());
    
    	if (!pProto)
    	{
    		sys_err("DoRefineWithScroll NOT GET ITEM PROTO %d", item->GetRefinedVnum());
    		ChatPacket(CHAT_TYPE_INFO, LC_TEXT("This Item can't be made better."));
    		return false;
    	}
    
    	// Check level limit in korea only
    	if (!g_iUseLocale)
    	{
    		for (int i = 0; i < ITEM_LIMIT_MAX_NUM; ++i)
    		{
    			long limit = pProto->aLimits[i].lValue;
    
    			switch (pProto->aLimits[i].bType)
    			{
    				case LIMIT_LEVEL:
    					if (GetLevel() < limit)
    					{
    						ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Your Level is lower than the required Level of the Item."));
    						return false;
    					}
    					break;
    			}
    		}
    	}
    
    	if (GetGold() < prt->cost)
    	{
    		ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Not enough Yang for an advancement."));
    		return false;
    	}
    
    	for (int i = 0; i < prt->material_count; ++i)
    	{
    		if (CountSpecifyItem(prt->materials[i].vnum) < prt->materials[i].count)
    		{
    			if (test_server)
    			{
    				ChatPacket(CHAT_TYPE_INFO, "Find %d, count %d, require %d", prt->materials[i].vnum, CountSpecifyItem(prt->materials[i].vnum), prt->materials[i].count);
    			}
    			ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Not enough material for an advancement."));
    			return false;
    		}
    	}
    
    	for (int i = 0; i < prt->material_count; ++i)
    		RemoveSpecifyItem(prt->materials[i].vnum, prt->materials[i].count);
    
    	int prob = number(1, 100);
    	int success_prob = prt->prob;
    	bool bDestroyWhenFail = false;
    
    	const char* szRefineType = "SCROLL";
    
    	const char blessing_scroll_prob[9] = {90, 80, 70, 60, 50, 40, 30, 20, 10};
    	const char magic_stone_prob[9] = {90, 80, 70, 60, 50, 40, 30, 20, 10};
    	const char dragon_scroll_prob[9] = {100, 90, 80, 70, 60, 50, 40, 30, 20};
    
    	if (pkItemScroll->GetValue(0) == BLESSING_SCROLL)
    	{
    		success_prob = blessing_scroll_prob[MINMAX(0, item->GetRefineLevel(), 8)];
    		szRefineType = "BLESSING_SCROLL";
    	}
    	else if (pkItemScroll->GetValue(0) == MAGIC_STONE)
    	{
    		success_prob = magic_stone_prob[MINMAX(0, item->GetRefineLevel(), 8)];
    		bDestroyWhenFail = true;
    		szRefineType = "MAGIC_STONE";
    	}
    	else if (pkItemScroll->GetValue(0) == DRAGON_SCROLL)
    	{
    		success_prob = dragon_scroll_prob[MINMAX(0, item->GetRefineLevel(), 8)];
    		szRefineType = "DRAGON_SCROLL";
    	}
    	else
    	{
    		sys_err("REFINE : Unknown refine scroll item. Value0: %d", pkItemScroll->GetValue(0));
    	}
    
    	if (test_server)
    	{
    		ChatPacket(CHAT_TYPE_INFO, "[Only Test] Success_Prob %d, RefineLevel %d ", success_prob, item->GetRefineLevel());
    	}
    
    	pkItemScroll->SetCount(pkItemScroll->GetCount() - 1);
    
    	if (prob <= success_prob)
    	{
    		LPITEM pkNewItem = ITEM_MANAGER::instance().CreateItem(result_vnum, 1, 0, false);
    
    		if (pkNewItem)
    		{
    			ITEM_MANAGER::CopyAllAttrTo(item, pkNewItem);
    			LogManager::instance().ItemLog(this, pkNewItem, "REFINE SUCCESS", pkNewItem->GetName());
    
    			BYTE bCell = item->GetCell();
    
    			NotifyRefineSuccess(this, item, szRefineType);
    			DBManager::instance().SendMoneyLog(MONEY_LOG_REFINE, item->GetVnum(), -prt->cost);
    			ITEM_MANAGER::instance().RemoveItem(item, "REMOVE (REFINE SUCCESS)");
    
    			pkNewItem->AddToCharacter(this, TItemPos(INVENTORY, bCell));
    			ITEM_MANAGER::instance().FlushDelayedSave(pkNewItem);
    			pkNewItem->AttrLog();
    			//PointChange(POINT_GOLD, -prt->cost);
    			PayRefineFee(prt->cost);
    		}
    		else
    		{
    			sys_err("cannot create item %u", result_vnum);
    			NotifyRefineFail(this, item, szRefineType);
    		}
    	}
    	else if (!bDestroyWhenFail && result_fail_vnum)
    	{
    		LPITEM pkNewItem = ITEM_MANAGER::instance().CreateItem(result_fail_vnum, 1, 0, false);
    
    		if (pkNewItem)
    		{
    			ITEM_MANAGER::CopyAllAttrTo(item, pkNewItem);
    			LogManager::instance().ItemLog(this, pkNewItem, "REFINE FAIL", pkNewItem->GetName());
    
    			BYTE bCell = item->GetCell();
    
    			DBManager::instance().SendMoneyLog(MONEY_LOG_REFINE, item->GetVnum(), -prt->cost);
    			NotifyRefineFail(this, item, szRefineType, -1);
    			ITEM_MANAGER::instance().RemoveItem(item, "REMOVE (REFINE FAIL)");
    
    			pkNewItem->AddToCharacter(this, TItemPos(INVENTORY, bCell));
    			ITEM_MANAGER::instance().FlushDelayedSave(pkNewItem);
    
    			pkNewItem->AttrLog();
    
    			//PointChange(POINT_GOLD, -prt->cost);
    			PayRefineFee(prt->cost);
    		}
    		else
    		{
    			sys_err("cannot create item %u", result_fail_vnum);
    			NotifyRefineFail(this, item, szRefineType);
    		}
    	}
    	else
    	{
    		NotifyRefineFail(this, item, szRefineType);
    
    		PayRefineFee(prt->cost);
    	}
    
    	return true;
    }

     

    • Metin2 Dev 1
    • Good 1
  13. 13 minutes ago, hachiwari said:

    Oryginal item table is good for all systems, you don't need new table

     

    That's true, but I think it's better to have more tables than one. Why? Because in practice, if one is dealing with some problem with lost items due to a bug in some system, it is better to have an overview. If anyone here has had such a leak, then they know how much time and resources it takes on a really played server. You're right anyway, but I don't think having one more table will hurt.

  14. What happens if the game crashes or is stopped during a fight? I was wondering if you could save the items in a database, something like item_duel.sql. Just like all the items from the game are stored in item.sql... After restarting the game, they could be restored using a simple button... So I'm thinking of making the whole system easier to manage in a repository kind of way...

    • Metin2 Dev 1
    • Good 1
×
×
  • 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.