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

Merged
merged 2 commits into from
Nov 17, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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;
}
GuardianDll marked this conversation as resolved.
Show resolved Hide resolved
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