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

Add u_buy_monster talk effect #33446

Merged
merged 2 commits into from
Aug 23, 2019
Merged
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
2 changes: 2 additions & 0 deletions doc/NPCs.md
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,8 @@ Effect | Description
`add_debt: mod_list` | Increases the NPC's debt to the player by the values in the `mod_list`.<br/>The following would increase the NPC's debt to the player by 1500x the NPC's altruism and 1000x the NPC's opinion of the player's value: `{ "effect": { "add_debt": [ [ "ALTRUISM", 3 ], [ "VALUE", 2 ], [ "TOTAL", 500 ] ] } }`
`u_consume_item`, `npc_consume_item: item_string`, (*optional* `count: count_num`) | You or the NPC will delete the item or `count_num` copies of the item from their inventory.<br/>This effect will fail if the you or NPC does not have at least `count_num` copies of the item, so it should be checked with `u_has_items` or `npc_has_items`.
`u_remove_item_with`, `npc_remove_item_with: item_string` | You or the NPC will delete any instances of item in inventory.<br/>This is an unconditional remove and will not fail if you or the NPC does not have the item.
`u_buy_monster: monster_type_string`, (*optional* `cost: cost_num`, *optional* `count: count_num`, *optional* `name: name_string`, *optional* `pacified: pacified_bool`) | The NPC will give your character `count_num` (default 1) instances of the monster as pets and will subtract `cost_num` from `op_of_u.owed` if specified. If the `op_o_u.owed` is less than `cost_num`, the trade window will open and the player will have to trade to make up the difference; the NPC will not give the player the item unless `cost_num` is satisfied.<br/>If cost isn't present, the NPC gives your character the item at no charge.<br/>If `name_string` is specified the monster(s) will have the specified name. If `pacified_bool` is set to true, the monster will have the pacified effect applied.


#### Behaviour / AI

Expand Down
2 changes: 2 additions & 0 deletions src/dialogue.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ struct talk_effect_fun_t {
void set_bulk_trade_accept( bool is_trade, bool is_npc = false );
void set_npc_gets_item( bool to_use );
void set_add_mission( std::string mission_id );
void set_u_buy_monster( const std::string &monster_id, int cost, int count, bool pacified,
const translation &name );

void operator()( const dialogue &d ) const {
if( !function ) {
Expand Down
58 changes: 58 additions & 0 deletions src/npctalk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "json.h"
#include "line.h"
#include "map.h"
#include "map_iterator.h"
#include "mapgen_functions.h"
#include "martialarts.h"
#include "messages.h"
Expand Down Expand Up @@ -2097,6 +2098,55 @@ void talk_effect_fun_t::set_add_mission( const std::string mission_id )
};
}

void talk_effect_fun_t::set_u_buy_monster( const std::string &monster_type_id, int cost, int count,
bool pacified, const translation &name )
{
function = [monster_type_id, cost, count, pacified, name]( const dialogue & d ) {
npc &p = *d.beta;
player &u = *d.alpha;
if( !npc_trading::pay_npc( p, cost ) ) {
popup( _( "You can't afford it!" ) );
return;
}

const mtype_id mtype( monster_type_id );
const efftype_id effect_pet( "pet" );
const efftype_id effect_pacified( "pacified" );
const tripoint_range points = g->m.points_in_radius( u.pos(), 3 );

for( int i = 0; i < count; i++ ) {
monster tmp( mtype );

// Our monster is always a pet.
tmp.friendly = -1;
tmp.add_effect( effect_pet, 1_turns, num_bp, true );

if( pacified ) {
tmp.add_effect( effect_pacified, 1_turns, num_bp, true );
}

if( !name.empty() ) {
tmp.unique_name = name.translated();
}

if( const cata::optional<tripoint> pos = random_point( points, [&]( const tripoint & p ) {
return g->is_empty( p ) && tmp.can_move_to( p );
} ) ) {
tmp.spawn( *pos );
g->add_zombie( tmp );
} else {
add_msg( m_debug, "Cannot place u_buy_monster, no valid placement locations." );
}
}

if( name.empty() ) {
popup( _( "%1$s gives you %2$d %3$s." ), p.name, count, mtype.obj().nname( count ) );
} else {
popup( _( "%1$s gives you %2$s." ), p.name, name );
}
};
}

void talk_effect_t::set_effect_consequence( const talk_effect_fun_t &fun, dialogue_consequence con )
{
effects.push_back( fun );
Expand Down Expand Up @@ -2293,6 +2343,14 @@ void talk_effect_t::parse_sub_effect( JsonObject jo )
subeffect_fun.set_npc_cbm_recharge_rule( setting );
} else if( jo.has_member( "mapgen_update" ) ) {
subeffect_fun.set_mapgen_update( jo, "mapgen_update" );
} else if( jo.has_string( "u_buy_monster" ) ) {
const std::string &monster_type_id = jo.get_string( "u_buy_monster" );
const int cost = jo.get_int( "cost", 0 );
const int count = jo.get_int( "count", 1 );
const bool pacified = jo.get_bool( "pacified", false );
translation name;
jo.read( "name", name );
subeffect_fun.set_u_buy_monster( monster_type_id, cost, count, pacified, name );
} else {
jo.throw_error( "invalid sub effect syntax :" + jo.str() );
}
Expand Down