• This is a read only backup of the old Emudevs forum. If you want to have anything removed, please message me on Discord: KittyKaev

[SOLVED] ExtendedCost doesn't work

Status
Not open for further replies.

Blazeqts

Enthusiast
I'm working on a Gearing System.

Here's how it works currently:
If you don't have a specific title, you can't access the vendor.
However, if you don't have the specific title, you have access to the preview vendor.
I believe people call this "MultiVendor" not sure.

The preview vendor uses an ExendedCost so players can't buy anything.

The issue is that, if a player attempts to buy an item in the preview vendor, even if he does not fill the requirements to the ExtendedCost, he will still get the item. For free.


You can see all changes done here; They are all related to this!
EDIT: https://github.com/immvp/ngen/commits/test

Not sure what's wrong with the code.
 
Last edited:

Rochet2

Moderator / Eluna Dev
Can you post the actual script or something that uses the functions coded in the commits?

These 2 parts dont look that great. Shouldnt return a pointer nor a reference to a temporary.
Instead change the return value to VendorItemData (not pointer) and return newItems (not a pointer)
Code:
 [COLOR="#FF0000"]VendorItemData newItems = iter->second;[/COLOR]
 int i = newItems.GetItemCount();
 while (i)
 {
    newItems.getItem(i)->ExtendedCost = 2398;
     i--;
 }

 [COLOR="#FF0000"]return &newItems;[/COLOR]
https://github.com/immvp/ngen/commit/14df5e1c3a04315a5c12aba30a8a67b7ca49b7e3
 
Last edited:

Blazeqts

Enthusiast
Not quite sure what you want me to do exactly. Can you write it and explain what you mean? I'm still new to C++. :)

There is no "script", it's all in the commits on github.
 

Blazeqts

Enthusiast
Forgot to add, it uses SkinLootId from the vendor to determine what title is required. For example, if I set the SkinLootId to 1 on the vendor, the title required will be title id 1, which is "Private".

- - - Updated - - -

Haha, *facepalm*

https://github.com/immvp/ngen/commits/test

This is the correct github link. My bad! :)
 

Eleinder

BETA Tester
Are you using ExtendedCost.dbc or only C++ script?

If you are using the dbc, please post a pic of the dbceditor and the vendor ingame.
If not, sorry but I dont have enough skills to help you in c++

Eleinder.
 

Blazeqts

Enthusiast
Are you using ExtendedCost.dbc or only C++ script?

If you are using the dbc, please post a pic of the dbceditor and the vendor ingame.
If not, sorry but I dont have enough skills to help you in c++

Eleinder.

Only C++.

ALL I need is a "check". I need it to check the extendedcost, and if the player has the required ExtendedCost for the Preview version of the vendor.
 

Blazeqts

Enthusiast
You'll need 8x Tokens to get the Private title. To get access to the vendor, you'll need Private title.

oRUDb3K.jpg


Here's how it looks like if you don't have Private title. This is the PREVIEW version of the vendor that shows if you don't have the title.

Kb9AXNs.jpg


Here I get the title.

lTS51it.jpg


And now I have access to the vendor.

IziLFi5.jpg


Problem is that even tho' it says that you need 2x Brewfest coins to buy the item in the PREVIEW version, you don't. It's only "visual", it doesn't check if you actually have the ExtCost or not. It just hands you the item.
 
Last edited:

Rochet2

Moderator / Eluna Dev
Likely you forgot to replace one GetVendorItems call. Check the buy item code for it.
There it will most likely take the original list where the item was free and thus not charge you for anything.

Link to full list of changes:
https://github.com/immvp/ngen/compare/4a018c1bc87d9307555204f05f73a710f23c2fb4...test

Missed call change:
https://github.com/immvp/ngen/blob/...server/game/Entities/Player/Player.cpp#L21744

I recommend trying to debug to see what happens and where.
For example why doesnt it halt the player from buying.
 

Blazeqts

Enthusiast
Likely you forgot to replace one GetVendorItems call. Check the buy item code for it.
There it will most likely take the original list where the item was free and thus not charge you for anything.

Link to full list of changes:
https://github.com/immvp/ngen/compare/4a018c1bc87d9307555204f05f73a710f23c2fb4...test

Missed call change:
https://github.com/immvp/ngen/blob/...server/game/Entities/Player/Player.cpp#L21744

I recommend trying to debug to see what happens and where.
For example why doesnt it halt the player from buying.

I don't understand the "Replace one GetVendorItems call". :(

Fairly new to C++.
 
Last edited:

Blazeqts

Enthusiast
See the link: Missed Call change
and change it to the fake list getting method if the player doesnt have the title

I see, so here's what I've done.

It gives me this Warning tho:
Player.cpp(21750): warning C4800: 'const VendorItemData *' : forcing value to bool 'true' or 'false' (performance warning)
Player.cpp(21752): warning C4800: 'const VendorItemData *' : forcing value to bool 'true' or 'false' (performance warning)

Code:
	  [COLOR="#FF0000"]  VendorItemData const* vItems = creature->GetVendorItems();
	{
	uint32 const entry = GetEntry();
		uint32 title = sObjectMgr->GetCreatureTemplate(entry)->SkinLootId;
		std::cout << GetName() << " - has title : " << HasTitle(title) << std::endl;
		if (title == 0 || HasTitle(title)) {
			return sObjectMgr->GetNpcVendorItemList(entry);
		}
		return sObjectMgr->GetNpcVendorItemListShowOnly(entry);
}

[/COLOR]
    if (vendorslot >= vItems->GetItemCount())
    {
        SendBuyError(BUY_ERR_CANT_FIND_ITEM, creature, item, 0);
        return false;
    }

    VendorItem const* crItem = vItems->GetItem(vendorslot);
    // store diff item (cheating)
    if (!crItem || crItem->item != item)
    {
        SendBuyError(BUY_ERR_CANT_FIND_ITEM, creature, item, 0);
        return false;
    }

    // check current item amount if it limited
    if (crItem->maxcount != 0)
    {
        if (creature->GetVendorItemCurrentCount(crItem) < pProto->BuyCount * count)
        {
            SendBuyError(BUY_ERR_ITEM_ALREADY_SOLD, creature, item, 0);
            return false;
        }
    }

    if (pProto->RequiredReputationFaction && (uint32(GetReputationRank(pProto->RequiredReputationFaction)) < pProto->RequiredReputationRank))
    {
        SendBuyError(BUY_ERR_REPUTATION_REQUIRE, creature, item, 0);
        return false;
    }

    if (crItem->ExtendedCost)
    {
        ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(crItem->ExtendedCost);
        if (!iece)
        {
            TC_LOG_ERROR("entities.player", "Item %u have wrong ExtendedCost field value %u", pProto->ItemId, crItem->ExtendedCost);
            return false;
        }

        // honor points price
        if (GetHonorPoints() < (iece->reqhonorpoints * count))
        {
            SendEquipError(EQUIP_ERR_NOT_ENOUGH_HONOR_POINTS, NULL, NULL);
            return false;
        }

        // arena points price
        if (GetArenaPoints() < (iece->reqarenapoints * count))
        {
            SendEquipError(EQUIP_ERR_NOT_ENOUGH_ARENA_POINTS, NULL, NULL);
            return false;
        }

        // item base price
        for (uint8 i = 0; i < MAX_ITEM_EXTENDED_COST_REQUIREMENTS; ++i)
        {
            if (iece->reqitem[i] && !HasItemCount(iece->reqitem[i], (iece->reqitemcount[i] * count)))
            {
                SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL);
                return false;
            }
        }

        // check for personal arena rating requirement
        if (GetMaxPersonalArenaRatingRequirement(iece->reqarenaslot) < iece->reqpersonalarenarating)
        {
            // probably not the proper equip err
            SendEquipError(EQUIP_ERR_CANT_EQUIP_RANK, NULL, NULL);
            return false;
        }
    }

Server crashes if I try to buy Anything from Any vendor
 
Last edited:

Jpp

Administrator
It gives me this Warning tho:
Player.cpp(21750): warning C4800: 'const VendorItemData *' : forcing value to bool 'true' or 'false' (performance warning)
Player.cpp(21752): warning C4800: 'const VendorItemData *' : forcing value to bool 'true' or 'false' (performance warning)

You are casting a non-boolean into a boolean.
 

Tommy

Founder
Assuming that:

Code:
	    VendorItemData const* vItems = creature->GetVendorItems();
	{
	uint32 const entry = GetEntry();
		uint32 title = sObjectMgr->GetCreatureTemplate(entry)->SkinLootId;
		std::cout << GetName() << " - has title : " << HasTitle(title) << std::endl;
		if (title == 0 || HasTitle(title)) {
			return sObjectMgr->GetNpcVendorItemList(entry);
		}
		return sObjectMgr->GetNpcVendorItemListShowOnly(entry);
}

is completely wrong and could be the reason why it's crashing.

Code:
std::cout << GetName() << " - has title : " << HasTitle(title) << std::endl;

Why do you have this? For console output, why not use TC_LOG_INFO? GetName() should call c_str() for const char* so it won't crash the server. Example:

Code:
GetName().c_str()

As for the logic, I'm assuming if a player has a certain title they can view the vendor? Here's my output:

P.S: I didn't do this in VS, so I'm blind regarding compiling or intellisense.

Code:
	VendorItemData const* vItems = creature->GetVendorItems();
        if (vItems && !vItems->Empty())
	{
	    uint32 const entry = GetEntry();
            uint32 title = sObjectMgr->GetCreatureTemplate(entry)->SkinLootId;
	    TC_LOG_INFO("%s :: Not::Sure::What::To::Put::Here", GetName().c_str());
	    if (title == 0 || HasTitle(title))
		return sObjectMgr->GetNpcVendorItemList(entry);

	    return sObjectMgr->GetNpcVendorItemListShowOnly(entry);
        }
 

Blazeqts

Enthusiast
Assuming that:

Code:
	    VendorItemData const* vItems = creature->GetVendorItems();
	{
	uint32 const entry = GetEntry();
		uint32 title = sObjectMgr->GetCreatureTemplate(entry)->SkinLootId;
		std::cout << GetName() << " - has title : " << HasTitle(title) << std::endl;
		if (title == 0 || HasTitle(title)) {
			return sObjectMgr->GetNpcVendorItemList(entry);
		}
		return sObjectMgr->GetNpcVendorItemListShowOnly(entry);
}

is completely wrong and could be the reason why it's crashing.

Code:
std::cout << GetName() << " - has title : " << HasTitle(title) << std::endl;

Why do you have this? For console output, why not use TC_LOG_INFO? GetName() should call c_str() for const char* so it won't crash the server. Example:

Code:
GetName().c_str()

As for the logic, I'm assuming if a player has a certain title they can view the vendor? Here's my output:

P.S: I didn't do this in VS, so I'm blind regarding compiling or intellisense.

Code:
	VendorItemData const* vItems = creature->GetVendorItems();
        if (vItems && !vItems->Empty())
	{
	    uint32 const entry = GetEntry();
            uint32 title = sObjectMgr->GetCreatureTemplate(entry)->SkinLootId;
	    TC_LOG_INFO("%s :: Not::Sure::What::To::Put::Here", GetName().c_str());
	    if (title == 0 || HasTitle(title))
		return sObjectMgr->GetNpcVendorItemList(entry);

	    return sObjectMgr->GetNpcVendorItemListShowOnly(entry);
        }

Tommy, my man to the rescue!

Yes, it's for TC LOG INFO, I can remove it and it wouldn't matter to me. I just have it for the sake of having it. :)

And yes, if you don't have title, the extendedcost will be set to X. If you do have the title, it'll just proceed like any other vendor.

Errors:
Code:
3>D:\Trinity\TrinityCore\src\server\game\Entities\Player\Player.cpp(21751): warning C4800: 'const VendorItemData *' : forcing value to bool 'true' or 'false' (performance warning)
3>D:\Trinity\TrinityCore\src\server\game\Entities\Player\Player.cpp(21753): warning C4800: 'const VendorItemData *' : forcing value to bool 'true' or 'false' (performance warning)
 

Tommy

Founder
Tommy, my man to the rescue!

Yes, it's for TC LOG INFO, I can remove it and it wouldn't matter to me. I just have it for the sake of having it. :)

And yes, if you don't have title, the extendedcost will be set to X. If you do have the title, it'll just proceed like any other vendor.

Errors:
Code:
3>D:\Trinity\TrinityCore\src\server\game\Entities\Player\Player.cpp(21751): warning C4800: 'const VendorItemData *' : forcing value to bool 'true' or 'false' (performance warning)
3>D:\Trinity\TrinityCore\src\server\game\Entities\Player\Player.cpp(21753): warning C4800: 'const VendorItemData *' : forcing value to bool 'true' or 'false' (performance warning)

Can you paste those lines the errors are showing up on? Won't do me any good as is. :p
 

Blazeqts

Enthusiast
Can you paste those lines the errors are showing up on? Won't do me any good as is. :p

Haha, laughing irl.

Code:
Line 21751:	return sObjectMgr->GetNpcVendorItemList(entry);

Line 21753:	return sObjectMgr->GetNpcVendorItemListShowOnly(entry);
 

Tommy

Founder
What function do you have your code in, in Player.cpp? As far as I see, removing both returns will solve the forcing value to boolean. If your function was VendorItemData and not bool you could return VendorItemData. Probably have to think of some other way to return what you want.
 
Status
Not open for further replies.
Top