ryzom / ryzomcore

Ryzom Core is the open-source project related to the Ryzom game. This community repository is synchronized with the Ryzom Forge repository, based on the Core branch.
https://wiki.ryzom.dev
GNU Affero General Public License v3.0
336 stars 91 forks source link

Item groups #301

Closed ryzom-pipeline closed 7 years ago

ryzom-pipeline commented 7 years ago

Original report by Guillaume DUPUY (Bitbucket: [Guillaume DUPUY](https://bitbucket.org/Guillaume DUPUY), ).


The goal is to be able to setup item groups, equip / move them in one click (instead of equipping each item individually).

Currently there is no unique item ID available to the client, and the only accessible information about an item in a storage is in CItemImage :

NLMISC::CCDBNodeLeaf *Sheet;
NLMISC::CCDBNodeLeaf *Quality;
NLMISC::CCDBNodeLeaf *Quantity;
NLMISC::CCDBNodeLeaf *UserColor;
NLMISC::CCDBNodeLeaf *Price;
NLMISC::CCDBNodeLeaf *Weight;
NLMISC::CCDBNodeLeaf *NameId;
NLMISC::CCDBNodeLeaf *InfoVersion;
NLMISC::CCDBNodeLeaf *ResaleFlag;

It turns out using Sheet, Quality, UserColor and Weight is very good to get a unique-ish ID for an item, because weight changes a lot on an item (on most item, you get a different weight every (0.1% to 0.5% precraft value)). It is, however, sometime insufficient on jewels, where weight vary from 0.1 to 0.2 kg (so it changes every 10% precraft value), and differents recipe usually gives the same value.

You can mitigate this by using the price (which depends on the exact recipe and the current HP). It's a bit more tricky and can require adjusting the price over time, but it should cover 99% of the cases. It's also not accessible for item in room inventory / guild inventory.

After some tests, I found out that I could uniquely identify every item with that (and i'm not the easiest user, as almost all of my gear is high quality fyros q250, so not much to differentiate them), so I think that this should cover it. Obviously, if we get client-side access to an unique ID this should be much easier to do.

The implementation would look like this :

On top of that, if a player right click on an item (which is part of an item set, if doable, or in every case with the suboption beeing noop if not), an option "Set" should appear with the following suboption :

A dedicated interface where you can edit itemGroup (probably with drag'n'drop) would be a nice addition (but I have no idea how to do this).

I've made a quick example video (it's on yubo test server, don't mind the red mats). There is a time where the player cannot act (like regular equip, and it's equal to the sum of "cannot act time" from each item), but it's not displayed to the user (it's a bug who should and will be fixed, currently it's just a proof of concept) : http://manda.glorf.fr/videos/itemset.mp4

The patch (which is quite ugly, real code won't be like that) is attached.

ryzom-pipeline commented 7 years ago

Original comment by Guillaume DUPUY (Bitbucket: [Guillaume DUPUY](https://bitbucket.org/Guillaume DUPUY), ).


Work in progress, code can be seen here : https://bitbucket.org/Glorf/ryzomcore/branch/item_group

I'm currently using some C++11 features (mostly auto), should I keep it like this or remove them to be compatible with old compilers ?

ryzom-pipeline commented 7 years ago

Original comment by Cédric Ochs (Bitbucket: [Cédric OCHS](https://bitbucket.org/Cédric OCHS), ).


I think STLport doesn't support std::auto and STLport is used up to VC++ 2010 because STLport is faster than MS STL for these compilers. Since VC++ 2012, we don't need STLport anymore.

So I suggest you to not use std::auto (I think it's not too hard to put a real class name or type instead of std::auto :p).

ryzom-pipeline commented 7 years ago

Original comment by Guillaume DUPUY (Bitbucket: [Guillaume DUPUY](https://bitbucket.org/Guillaume DUPUY), ).


I removed C++11 features (range-based for is pretty fucking cool tho, sad to see this go :p). Is there any way to make a template for action inside a group (in a submenu) ? The only template with action inside that I found are used outside of a group, and I couldn't make it work :( So currently I have to hardcode the different submenu for multiple item groups, it's pretty ugly : https://bitbucket.org/Glorf/ryzomcore/commits/9d6bcf933bd258527a4ce2195bfb7658e9ece8af#Lcode/ryzom/client/data/gamedev/interfaces_v3/widgets.xmlT1825

ryzom-pipeline commented 7 years ago

Original comment by Cédric Ochs (Bitbucket: [Cédric OCHS](https://bitbucket.org/Cédric OCHS), ).


Dynamic context menus are managed in C++ code, you can have a look at emotes ones :)

ryzom-pipeline commented 7 years ago

Original comment by Guillaume DUPUY (Bitbucket: [Guillaume DUPUY](https://bitbucket.org/Guillaume DUPUY), ).


Thanks, it works much better now :-) Is there a way to bind a group to a submenu of a group directly in an xml file? Currently i'm doing something like this :

//attach item group subgroup to right-click in bag group
CWidgetManager* pWM = CWidgetManager::getInstance();
CGroupMenu   *pRootMenu = dynamic_cast<CGroupMenu*>(pWM->getElementFromId("ui:interface:item_menu_in_bag"));
CGroupSubMenu *pMenu = pRootMenu->getRootMenu();
//get item subgroup
CGroupMenu   *pGroupMenu = dynamic_cast<CGroupMenu*>(pWM->getElementFromId("ui:interface:item_menu_in_bag:item_group_menu"));
CGroupSubMenu *pGroupSubMenu = pGroupMenu->getRootMenu();
if(pMenu && pGroupSubMenu)
    pMenu->setSubMenu(pMenu->getNumLine() - 1, pGroupSubMenu);
else
    nlinfo("Couldn't update yet, maybe wait a little bit ?");

And the XML looks like this (item_text_edition unchanged, it's just for context) :

<action id="item_text_edition"
        name="uimItemTextEdit"
        handler="item_text_edition"
        params="ui:interface:edit_custom" />
<action id="item_group"
        name="uimGroup" />
<!-- Will be activated and populated in code -->
<group type="menu"
                id="item_group_menu"
        extends="base_menu">
</group>
ryzom-pipeline commented 7 years ago

Original comment by Meelis Mägi (Bitbucket: [Meelis Mägi](https://bitbucket.org/Meelis Mägi), ).


You want to attach your custom submenu to current right-click menu? I believe you need to add the action into menu and then toggle visibility when you need it.

ryzom-pipeline commented 7 years ago

Original comment by Guillaume DUPUY (Bitbucket: [Guillaume DUPUY](https://bitbucket.org/Guillaume DUPUY), ).


To add a custom submenu in a group (here current right-click menu), I need to link it to an action (a line in the group).

That works fine and I show/hide the action when I need it (and update the submenu), it's cool. I'm just wondering about the "link submenu to an action". Currently I have to link it manually in code, and I wonder if there is a way to do this directly in xml. I'm speaking about something like this :

<action id="item_group" name="uimGroup" linked_menu="item_group_menu"/>

ryzom-pipeline commented 7 years ago

Original comment by Guillaume DUPUY (Bitbucket: [Guillaume DUPUY](https://bitbucket.org/Guillaume DUPUY), ).


The feature is fairly mature, I finally added translation. Is there any place to put the translation in Ryzomcore/develop branch ? The only reference to *.uxt file I found is in compatiblity-develop, do I do a second PR against this, or do I simply do a PR against ryzomcore-data ?

ryzom-pipeline commented 7 years ago

Original comment by Meelis Mägi (Bitbucket: [Meelis Mägi](https://bitbucket.org/Meelis Mägi), ).


translations are in compatibility-develop branch. ryzomcore-data has not been updated for translations either.

ryzom-pipeline commented 7 years ago

Original comment by Meelis Mägi (Bitbucket: [Meelis Mägi](https://bitbucket.org/Meelis Mägi), ).


merged in f89c971