Skip to content

Commit

Permalink
Allow spawning npc via iuse action (#36358)
Browse files Browse the repository at this point in the history
  • Loading branch information
ZhilkinSerg authored and kevingranade committed Dec 27, 2019
1 parent 50c0b67 commit ba506fb
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 0 deletions.
5 changes: 5 additions & 0 deletions data/json/item_actions.json
Original file line number Diff line number Diff line change
Expand Up @@ -1024,6 +1024,11 @@
"id": "place_monster",
"name": "Activate"
},
{
"type": "item_action",
"id": "place_npc",
"name": "Activate"
},
{
"type": "item_action",
"id": "place_trap",
Expand Down
7 changes: 7 additions & 0 deletions doc/JSON_INFO.md
Original file line number Diff line number Diff line change
Expand Up @@ -1851,6 +1851,13 @@ The contents of use_action fields can either be a string indicating a built-in f
"skill2": "unarmed", // Another id, just like the skill1. Both entries are optional.
"moves": 60 // how many move points the action takes.
},
"use_action": {
"type": "place_npc", // place npc of specific class on the map
"npc_class_id": "true_foodperson", // npc class id, see npcs/classes.json
"summon_msg": "You summon a food hero!", // (optional) message when summoning the npc.
"place_randomly": true, // if true: places npc randomly around the player, if false: let the player decide where to put it (default: false)
"moves": 50 // how many move points the action takes.
},
"use_action": {
"type": "ups_based_armor", // Armor that can be activated and uses power from an UPS, needs additional json code to work
"activate_msg": "You activate your foo.", // Message when the player activates the item.
Expand Down
1 change: 1 addition & 0 deletions src/item_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,7 @@ void Item_factory::init()
add_actor( std::make_unique<pick_lock_actor>() );
add_actor( std::make_unique<deploy_furn_actor>() );
add_actor( std::make_unique<place_monster_iuse>() );
add_actor( std::make_unique<place_npc_iuse>() );
add_actor( std::make_unique<reveal_map_actor>() );
add_actor( std::make_unique<salvage_actor>() );
add_actor( std::make_unique<unfold_vehicle_iuse>() );
Expand Down
39 changes: 39 additions & 0 deletions src/iuse_actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,45 @@ std::unique_ptr<iuse_actor> ups_based_armor_actor::clone() const
return std::make_unique<ups_based_armor_actor>( *this );
}

std::unique_ptr<iuse_actor> place_npc_iuse::clone() const
{
return std::make_unique<place_npc_iuse>( *this );
}

void place_npc_iuse::load( const JsonObject &obj )
{
npc_class_id = string_id<npc_template>( obj.get_string( "npc_class_id" ) );
obj.read( "summon_msg", summon_msg );
obj.read( "moves", moves );
obj.read( "place_randomly", place_randomly );
}

int place_npc_iuse::use( player &p, item &, bool, const tripoint & ) const
{
cata::optional<tripoint> target_pos;
if( place_randomly ) {
const tripoint_range target_range = points_in_radius( p.pos(), 1 );
target_pos = random_point( target_range, []( const tripoint & t ) {
return !g->m.passable( t );
} );
} else {
const std::string query = _( "Place npc where?" );
target_pos = choose_adjacent( _( "Place npc where?" ) );
}
if( !target_pos ) {
return 0;
}
if( !g->m.passable( target_pos.value() ) ) {
p.add_msg_if_player( m_info, _( "There is no square to spawn npc in!" ) );
return 0;
}

g->m.place_npc( target_pos.value().xy(), npc_class_id );
p.mod_moves( -moves );
p.add_msg_if_player( m_info, "%s", _( summon_msg ) );
return 1;
}

void ups_based_armor_actor::load( const JsonObject &obj )
{
obj.read( "activate_msg", activate_msg );
Expand Down
19 changes: 19 additions & 0 deletions src/iuse_actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "explosion.h"
#include "game_constants.h"
#include "iuse.h"
class npc_template;
#include "ret_val.h"
#include "string_id.h"
#include "translations.h"
Expand Down Expand Up @@ -310,6 +311,24 @@ class place_monster_iuse : public iuse_actor
std::unique_ptr<iuse_actor> clone() const override;
};

/**
* This iuse contains the logic to summon an npc on the map.
*/
class place_npc_iuse : public iuse_actor
{
public:
string_id<npc_template> npc_class_id;
bool place_randomly = false;
int moves = 100;
std::string summon_msg;

place_npc_iuse() : iuse_actor( "place_npc" ) { }
~place_npc_iuse() override = default;
void load( const JsonObject &obj ) override;
int use( player &, item &, bool, const tripoint & ) const override;
std::unique_ptr<iuse_actor> clone() const override;
};

/**
* Items that can be worn and can be activated to consume energy from UPS.
* Note that the energy consumption is done in @ref player::process_active_items, it is
Expand Down

0 comments on commit ba506fb

Please sign in to comment.