Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transformation use action can pick random item from itemgroups #77893

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/JSON_INFO.md
Original file line number Diff line number Diff line change
Expand Up @@ -4508,6 +4508,7 @@ The contents of `use_action` fields can either be a string indicating a built-in
"use_action": {
"type": "transform", // The type of method, in this case one that transforms the item
"target": "gasoline_lantern_on", // The item to transform to
"target_group": "twisted_geometry", // If used, target is a random item from itemgroup
"variant_type": "condom_plain", // (optional) Defaults to `<any>`. Specific variant type to set for the transformed item. Special string `<any>` will pick a random variant from all available variants, based on the variant's defined weight
"active": true, // Whether the item is active once transformed
"ammo_scale": 0, // For use when an item automatically transforms into another when its ammo drops to 0, or to allow guns to transform with 0 ammo
Expand Down
26 changes: 21 additions & 5 deletions src/iuse_actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,11 @@ std::unique_ptr<iuse_actor> iuse_transform::clone() const
void iuse_transform::load( const JsonObject &obj, const std::string & )
{
obj.read( "target", target, true );
obj.read( "target_group", target_group, true );

if( !target.is_empty() && !target_group.is_empty() ) {
obj.throw_error_at( "target_group", "Cannot use both target and target_group at once" );
}

obj.read( "msg", msg_transform );
obj.read( "variant_type", variant_type );
Expand Down Expand Up @@ -272,7 +277,8 @@ std::optional<int> iuse_transform::use( Character *p, item &it, const tripoint &
}
}

if( it.count_by_charges() != target->count_by_charges() && it.count() > 1 ) {
if( target_group.is_empty() && it.count_by_charges() != target->count_by_charges() &&
it.count() > 1 ) {
item take_one = it.split( 1 );
do_transform( p, take_one, variant_type );
p->i_add_or_drop( take_one );
Expand All @@ -293,8 +299,12 @@ void iuse_transform::do_transform( Character *p, item &it, const std::string &va
// defined here to allow making a new item assigned to the pointer
item obj_it;
if( container.is_empty() ) {
obj = &it.convert( target, p );
obj->set_itype_variant( variant_type );
if( !target_group.is_empty() ) {
obj = &it.convert( item_group::item_from( target_group ).typeId(), p );
} else {
obj = &it.convert( target, p );
obj->set_itype_variant( variant_type );
}
if( ammo_qty >= 0 || !random_ammo_qty.empty() ) {
int qty;
if( !random_ammo_qty.empty() ) {
Expand All @@ -320,7 +330,9 @@ void iuse_transform::do_transform( Character *p, item &it, const std::string &va
obj->set_itype_variant( variant_type );
int count = std::max( ammo_qty, 1 );
item cont;
if( target->count_by_charges() ) {
if( !target_group.is_empty() ) {
cont = item( item_group::item_from( target_group ).typeId(), calendar::turn );
} else if( target->count_by_charges() ) {
cont = item( target, calendar::turn, count );
count = 1;
} else {
Expand Down Expand Up @@ -423,7 +435,7 @@ std::string iuse_transform::get_name() const

void iuse_transform::finalize( const itype_id & )
{
if( !item::type_is_defined( target ) ) {
if( !item::type_is_defined( target ) && target_group.is_empty() ) {
debugmsg( "Invalid transform target: %s", target.c_str() );
}

Expand All @@ -439,6 +451,10 @@ void iuse_transform::finalize( const itype_id & )

void iuse_transform::info( const item &it, std::vector<iteminfo> &dump ) const
{

if( !target_group.is_empty() ) {
return;
}
Comment on lines +455 to +457
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That should generate some informative output at least, so you know you can transform it when you look at iteminfo. Ideally a proper description of the item group, but that might be extremely complicated with nested distribution groups, so at least in my opinion some generic sentence would be enough for now.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't even refer to the result output, so I'm not sure what to write here. "Activation can transform into.. Something?"

int amount = std::max( ammo_qty, 1 );
item dummy( target, calendar::turn, target->count_by_charges() ? amount : 1 );
dummy.set_itype_variant( variant_type );
Expand Down
3 changes: 3 additions & 0 deletions src/iuse_actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ class iuse_transform : public iuse_actor
/** type of the resulting item */
itype_id target;

/** or one of items from itemgroup */
item_group_id target_group;

/** if set transform item to container and place new item (of type @ref target) inside */
itype_id container;

Expand Down
Loading