hlmod / Shop-Core

Documentation
https://hlmod.github.io/Shop-Core/module/create/
GNU General Public License v3.0
28 stars 26 forks source link

Added forward Shop_OnItemPricesDisplay #106

Closed IL0co closed 2 years ago

IL0co commented 3 years ago

Added the ability to change the displayed value of the purchase price and the selling price of an item in its Info Menu

TiBarification commented 2 years ago

I think it would be better to control entire string to display, where you can setup your own requirements for purchasing.

TiBarification commented 2 years ago

Looks good for me, we can keep my idea on hold for now.

TiBarification commented 2 years ago

@IL0co please provide a simple test with your forward usage. Then I think we can merge your changes.

IL0co commented 2 years ago

@IL0co please provide a simple test with your forward usage. Then I think we can merge your changes.

I ran tests, everything went well, the prices on the menu have changed. BUT a bug appeared, when the price changes, the type of the item in the menu changes (on the screen you can see that it says Duration: Forever, but in fact the type of the item remains the same. Tested on an item of type Item_Finite. On the server there were only the core and this module .

Before and after applying new price display. Screenshot_7 Screenshot_8

Console log:

iLoco buy item 'test item', he has 1 count, Price = 500, SellPrice = 400
iLoco see item Test item, he has 2 count. Prise = 500, Sell price = 400
iLoco buy item 'test item', he has 2 count, Price = 500, SellPrice = 400
iLoco see item Test item, he has 3 count. Prise = 500, Sell price = 400
Change item 'Test item' for player iLoco to: Prise from 500 to 250, Sell price from 400 to 300
iLoco buy item 'test item', he has 3 count, Price = 500, SellPrice = 400
iLoco see item Test item, he has 4 count. Prise = 250, Sell price = 300

The code on which the test was carried out:

Spoiler ```cpp #include #pragma newdecls required public void OnPluginEnd() { Shop_UnregisterMe(); } public void OnPluginStart() { if(Shop_IsStarted()) { Shop_Started(); } } public void Shop_Started() { CategoryId cat_id = Shop_RegisterCategory("test", "Test category", ""); if(Shop_StartItem(cat_id, "test item")) { Shop_SetInfo("Test item", "", 500, 400, Item_Finite); Shop_SetCallbacks(CallBack_OnItemRegistered, CallBack_OnItemUse); Shop_EndItem(); } } public void CallBack_OnItemRegistered(CategoryId category_id, const char[] category, const char[] item, ItemId item_id) { } public ShopAction CallBack_OnItemUse(int client, CategoryId category_id, const char[] category, ItemId item_id, const char[] item) { } public bool Shop_OnItemDisplay(int client, ShopMenu menu_action, CategoryId category_id, ItemId item_id, const char[] display, char[] buffer, int maxlength) { PrintToServer("%N see item %s, he has %i count. Prise = %i, Sell price = %i", client, display, Shop_GetClientItemCount(client, item_id), Shop_GetItemPrice(item_id), Shop_GetItemSellPrice(item_id)); } public bool Shop_OnItemPricesDisplay(int client, ShopMenu menu_action, CategoryId category_id, ItemId item_id, int &price, int &sell_price) { if(Shop_GetClientItemCount(client, item_id) < 3) { return false; } char unique[64]; Shop_GetItemNameById(item_id, unique, sizeof(unique)); PrintToServer("Change item '%s' for player %N to: Prise from %i to %i, Sell price from %i to %i", unique, client, price, price - 250, sell_price, sell_price - 100); price -= 250; sell_price -= 100; return true; } public Action Shop_OnItemBuy(int client, CategoryId category_id, const char[] category, ItemId item_id, const char[] item, ItemType type, int &price, int &sell_price, int &value, int &gold_price, int &gold_sell_price) { PrintToServer("%N buy item '%s', he has %i count, Price = %i, SellPrice = %i", client, item, Shop_GetClientItemCount(client, item_id), price, sell_price); } ```
IL0co commented 2 years ago

Screenshot_9Screenshot_10

Console output

iLoco see item 'Test item', he has 0 count. Price = 500, SellPrice = 400
iLoco buy item 'test item', he has 0 count, Price = 500, SellPrice = 400
iLoco see item 'Test item', he has 1 count. Price = 500, SellPrice = 400
iLoco buy item 'test item', he has 1 count, Price = 500, SellPrice = 400
iLoco see item 'Test item', he has 2 count. Price = 500, SellPrice = 400
iLoco buy item 'test item', he has 2 count, Price = 500, SellPrice = 400
iLoco see item 'Test item', he has 3 count. Price = 500, SellPrice = 400
 Change item 'test item' for player iLoco to: Price from 500 to 250, SellPrice from 400 to 300
Code to test ```cpp #include #pragma newdecls required public void OnPluginEnd() { Shop_UnregisterMe(); } public void OnPluginStart() { if(Shop_IsStarted()) { Shop_Started(); } } public void Shop_Started() { CategoryId cat_id = Shop_RegisterCategory("test", "Test category", ""); if(Shop_StartItem(cat_id, "test item")) { Shop_SetInfo("Test item", "", 500, 400, Item_Finite); Shop_SetCallbacks(CallBack_OnItemRegistered, CallBack_OnItemUse); Shop_EndItem(); } } public void CallBack_OnItemRegistered(CategoryId category_id, const char[] category, const char[] item, ItemId item_id) { } public ShopAction CallBack_OnItemUse(int client, CategoryId category_id, const char[] category, ItemId item_id, const char[] item) { } public bool Shop_OnItemDisplay(int client, ShopMenu menu_action, CategoryId category_id, ItemId item_id, const char[] display, char[] buffer, int maxlength) { PrintToServer("%N see item '%s', he has %i count. Price = %i, SellPrice = %i", client, display, Shop_GetClientItemCount(client, item_id), Shop_GetItemPrice(item_id), Shop_GetItemSellPrice(item_id)); } public bool Shop_OnItemPricesDisplay(int client, ShopMenu menu_action, CategoryId category_id, const char[] category, ItemId item_id, const char[] item, int &price, int &sell_price) { if(Shop_GetClientItemCount(client, item_id) < 3) { return false; } PrintToServer(" Change item '%s' for player %N to: Price from %i to %i, SellPrice from %i to %i", item, client, price, price - 250, sell_price, sell_price - 100); price -= 250; sell_price -= 100; return true; } public Action Shop_OnItemBuy(int client, CategoryId category_id, const char[] category, ItemId item_id, const char[] item, ItemType type, int &price, int &sell_price, int &value, int &gold_price, int &gold_sell_price) { PrintToServer("%N buy item '%s', he has %i count, Price = %i, SellPrice = %i", client, item, Shop_GetClientItemCount(client, item_id), price, sell_price); } ```
CrazyHackGUT commented 2 years ago

In API already present methods for retrieving item and category names. I don't understand, for what reasons these strings should be passed to forward too.

IL0co commented 2 years ago

It is more convenient when it is already in the forward parameters than later to receive it through

    char unique[64];
    Shop_GetItemNameById(item_id, unique, sizeof(unique));

Look in the spoiler, there I get an identifier, it's inconvenient. https://github.com/FD-Forks/Shop-Core/pull/106#issuecomment-1081156131:

public bool Shop_OnItemPricesDisplay(int client, ShopMenu menu_action, CategoryId category_id, ItemId item_id, int &price, int &sell_price)
{
    if(Shop_GetClientItemCount(client, item_id) < 3) {
        return false;
    }

    char unique[64];
    Shop_GetItemNameById(item_id, unique, sizeof(unique));

    PrintToServer("Change item '%s' for player %N to: Prise from %i to %i, Sell price from %i to %i", unique, client, price, price - 250, sell_price, sell_price - 100);

    price -= 250;
    sell_price -= 100;
    return true;
}

And in general, we still get unique names before calling the forward, so why not throw them further, into the forward? If you want me to remove it, then request Changes requested

CrazyHackGUT commented 2 years ago

I don't request remove, i just try understand the reasons of this solution.

IL0co commented 2 years ago

I don't request remove, i just try understand the reasons of this solution.

Ease of use, you do not have to separately receive unique names in the forward later.

CrazyHackGUT commented 2 years ago

In how many cases you really need string identifier for item and category?

IL0co commented 2 years ago

In how many cases you really need string identifier for item and category?

Yes, almost always, especially when interacting with StringMap or KeyValues. It will not be useful only when we use only one item in the plugin (medkit, double jump, etc.), that is, when we do not take information from the above mentioned databases. In what there can be problems of transfer of two lines in the forward? 128*2 bits of memory?) I think that the more necessary parameters we pass, the better it will be when working with it (the forward).

CrazyHackGUT commented 2 years ago

Yes, almost always, especially when interacting with StringMap or KeyValues.

Use IntToString(view_as<int>(iItemId), szId, sizeof(szId)). Item identifiers is just a integers, you should know about this. And they statically, you never receive behavior when ItemId can be changed in runtime and points to another item in next tick. I don't see any problems with this.

You can continue use StringMap or KeyValues, with just converting ItemId to int

IL0co commented 2 years ago

Yes, almost always, especially when interacting with StringMap or KeyValues.

Use IntToString(view_as<int>(iItemId), szId, sizeof(szId)). Item identifiers is just a integers, you should know about this. And they statically, you never receive behavior when ItemId can be changed in runtime and points to another item in next tick. I don't see any problems with this.

You misunderstood, a unique name is not a received string from ItemId or CategoryId, it is a string that we pass as the first argument during registration. https://github.com/FD-Forks/Shop-Core/blob/62eb5833bd1ffc1f2d77ffbcc65f5340bd2ecddf/addons/sourcemod/scripting/include/shop/register.inc#L54-L67

You can continue use StringMap or KeyValues, with just converting ItemId to int

I have not seen such cases when they used it this way, and there is no rationality in this, when you can jump by unique names and not go to a converted string...

R1KO commented 2 years ago

You misunderstood, a unique name is not a received string from ItemId or CategoryId, it is a string that we pass as the first argument during registration.

Он и имел ввиду что ид такой же уникальный как и имя, и если для кв/хеш-мапы нужна строка то её можно получить из ид или привести ид к строке

IL0co commented 2 years ago

You misunderstood, a unique name is not a received string from ItemId or CategoryId, it is a string that we pass as the first argument during registration.

Он и имел ввиду что ид такой же уникальный как и имя, и если для кв/хеш-мапы нужна строка то её можно получить из ид или привести ид к строке

У меня под словом unique name разумеется уникальное имя, строка. А вот ItemId или CategoryId это идентификатор (Unique id), уникальное имя но в виде числа, числа позиция из ArrayList'a. Большинство использует unique name для своих целей, конвертация ItemId или CategoryId в строку и последующие манипуляции в конфиге ну такое себе развлечение как по мне. Если смотреть в сторону оптимизации, то да, лучше заменять unique name на Unique id.