Skip to content

Commit

Permalink
Transformation use action can pick random item from itemgroups (#77893)
Browse files Browse the repository at this point in the history
* transformation use action can pick random item from itemgroups

* add some description for use action
  • Loading branch information
GuardianDll authored Nov 17, 2024
1 parent aa5f97a commit 9ac7d05
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 5 deletions.
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
27 changes: 22 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,11 @@ void iuse_transform::finalize( const itype_id & )

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

if( !target_group.is_empty() ) {
dump.emplace_back( "TOOL", _( "Can transform into one of several items" ) );
return;
}
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

0 comments on commit 9ac7d05

Please sign in to comment.