From e7ca42c3cecf22bb667b57fd657e2292e54a2f7c Mon Sep 17 00:00:00 2001 From: nexusmrsep <39925111+nexusmrsep@users.noreply.github.com> Date: Fri, 14 Jun 2019 13:33:58 +0200 Subject: [PATCH] Starting bank money, millionaire profession, debt & savings traits (#31306) * Starting bank money, millionaire profession, debt & savings traits --- data/json/mutations.json | 33 +++++++++++++++++++++++++++++++++ data/json/professions.json | 33 +++++++++++++++++++++++++++++++++ src/defense.cpp | 10 +++++----- src/gamemode.h | 6 +++--- src/iexamine.cpp | 9 ++++++++- src/mission_companion.cpp | 4 ++-- src/monattack.cpp | 9 +++++++-- src/newcharacter.cpp | 14 ++++++++++++++ src/npctalk.cpp | 4 ++-- src/npctalk_funcs.cpp | 4 ++-- src/output.h | 2 +- src/player.h | 2 +- 12 files changed, 111 insertions(+), 19 deletions(-) diff --git a/data/json/mutations.json b/data/json/mutations.json index ab52e047d5a83..41d3d1280c5ba 100644 --- a/data/json/mutations.json +++ b/data/json/mutations.json @@ -655,6 +655,39 @@ "cancels": [ "TRUTHTELLER" ], "social_modifiers": { "lie": 40 } }, + { + "type": "mutation", + "id": "SAVINGS", + "name": "Savings", + "points": 1, + "description": "You had some money stashed at the bank for a rainy day. Now that the storm is raging, it's a last call to use it maybe?", + "starting_trait": true, + "purifiable": false, + "valid": false, + "cancels": [ "DEBT", "MILLIONAIRE" ] + }, + { + "type": "mutation", + "id": "DEBT", + "name": "Debt", + "points": -1, + "description": "You needed money and had a big loan in a bank. Good thing nobody will come to collect it now, right? Right?", + "starting_trait": true, + "purifiable": false, + "valid": false, + "cancels": [ "SAVINGS", "MILLIONAIRE" ] + }, + { + "type": "mutation", + "id": "MILLIONAIRE", + "name": "Millionaire", + "points": 3, + "description": "At the time of Cataclysm you were an owner of a fortune stashed in a bank. Does that have any meaning now?", + "valid": false, + "purifiable": false, + "starting_trait": true, + "cancels": [ "DEBT", "SAVINGS" ] + }, { "type": "mutation", "id": "PRETTY", diff --git a/data/json/professions.json b/data/json/professions.json index fb1f5b99601a1..18274d1aa903d 100644 --- a/data/json/professions.json +++ b/data/json/professions.json @@ -2335,6 +2335,39 @@ "female": [ "bra", "panties" ] } }, + { + "type": "profession", + "ident": "millionaire", + "name": "Millionaire", + "description": "You had a fortune, whether inherited, built by hard work, or gained by pure luck. You invested in trade and nothing was beyond your reach. Now it's not worth a dime and no money in the world can guarantee your safety and well being. Hard times are ahead, so it's time to undust your skills and try to sell some ice to the Innuit. What currency do they accept?", + "points": 3, + "traits": [ "MILLIONAIRE" ], + "skills": [ { "level": 3, "name": "barter" }, { "level": 2, "name": "speech" } ], + "items": { + "both": { + "items": [ + "suit", + "skinny_tie", + "tieclip", + "socks", + "dress_shoes", + "smart_phone", + "money_bundle", + "gold_watch", + "gold_ear", + "gold_bracelet", + "gasdiscount_platinum", + "diamond_ring", + "gold_small", + "silver_small", + "platinum_small" + ], + "entries": [ { "item": "cash_card", "charges": 1000000 }, { "item": "diamond", "count": 5 } ] + }, + "male": [ "briefs" ], + "female": [ "bra", "panties" ] + } + }, { "type": "profession", "ident": "priest", diff --git a/src/defense.cpp b/src/defense.cpp index d349f160792ec..38ecd4c1f0b5f 100644 --- a/src/defense.cpp +++ b/src/defense.cpp @@ -59,7 +59,7 @@ int caravan_price( player &u, int price ); void draw_caravan_borders( const catacurses::window &w, int current_window ); void draw_caravan_categories( const catacurses::window &w, int category_selected, - unsigned total_price, unsigned long cash ); + signed total_price, signed long cash ); void draw_caravan_items( const catacurses::window &w, std::vector *items, std::vector *counts, int offset, int item_selected ); @@ -919,7 +919,7 @@ void defense_game::caravan() } } - unsigned total_price = 0; + signed total_price = 0; catacurses::window w = catacurses::newwin( FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, 0, 0 ); @@ -1280,7 +1280,7 @@ void draw_caravan_borders( const catacurses::window &w, int current_window ) } void draw_caravan_categories( const catacurses::window &w, int category_selected, - unsigned total_price, unsigned long cash ) + signed total_price, signed long cash ) { // Clear the window for( int i = 1; i <= 10; i++ ) { @@ -1324,8 +1324,8 @@ void draw_caravan_items( const catacurses::window &w, std::vector *ite item::nname( ( *items )[i], ( *counts )[i] ) ); wprintz( w, c_white, " x %2d", ( *counts )[i] ); if( ( *counts )[i] > 0 ) { - unsigned long price = caravan_price( g->u, item( ( *items )[i], - 0 ).price( false ) * ( *counts )[i] ); + signed long price = caravan_price( g->u, item( ( *items )[i], + 0 ).price( false ) * ( *counts )[i] ); wprintz( w, ( price > g->u.cash ? c_red : c_green ), " (%s)", format_money( price ) ); } } diff --git a/src/gamemode.h b/src/gamemode.h index 1e740d7ef4efe..b01e3d20afb86 100644 --- a/src/gamemode.h +++ b/src/gamemode.h @@ -163,9 +163,9 @@ struct defense_game : public special_game { time_duration time_between_waves; // Cooldown / building / healing time int waves_between_caravans; // How many waves until we get to trade? - unsigned long initial_cash; // How much cash do we start with? - unsigned long cash_per_wave; // How much cash do we get per wave? - unsigned long cash_increase; // How much does the above increase per wave? + signed long initial_cash; // How much cash do we start with? + signed long cash_per_wave; // How much cash do we get per wave? + signed long cash_increase; // How much does the above increase per wave? bool zombies; bool specials; diff --git a/src/iexamine.cpp b/src/iexamine.cpp index d984b7c593688..11001dc8a35ac 100644 --- a/src/iexamine.cpp +++ b/src/iexamine.cpp @@ -360,6 +360,9 @@ class atm_menu add_choice( withdraw_money, _( "Withdraw Money" ) ); } else if( u.cash > 0 ) { add_info( withdraw_money, _( "You need a cash card before you can withdraw money!" ) ); + } else if( u.cash < 0 ) { + add_info( withdraw_money, + _( "You need to pay down your debt first!" ) ); } else { add_info( withdraw_money, _( "You need money in your account before you can withdraw money!" ) ); @@ -380,7 +383,11 @@ class atm_menu //! print a bank statement for @p print = true; void finish_interaction( const bool print = true ) { if( print ) { - add_msg( m_info, _( "Your account now holds %s." ), format_money( u.cash ) ); + if( u.cash < 0 ) { + add_msg( m_info, _( "Your debt is now %s." ), format_money( u.cash ) ); + } else { + add_msg( m_info, _( "Your account now holds %s." ), format_money( u.cash ) ); + } } u.moves -= to_turns( 5_seconds ); diff --git a/src/mission_companion.cpp b/src/mission_companion.cpp index b0245ba535380..8265a5b462eda 100644 --- a/src/mission_companion.cpp +++ b/src/mission_companion.cpp @@ -992,7 +992,7 @@ void talk_function::field_plant( npc &p, const std::string &place ) limiting_number = empty_plots; } - unsigned int a = limiting_number * 300; + signed int a = limiting_number * 300; if( a > g->u.cash ) { popup( _( "I'm sorry, you don't have enough money to plant those seeds..." ) ); return; @@ -1110,7 +1110,7 @@ void talk_function::field_harvest( npc &p, const std::string &place ) int money = ( number_plants * tmp.price( true ) - number_plots * 2 ) / 100; bool liquidate = false; - unsigned int a = number_plots * 2; + signed int a = number_plots * 2; if( a > g->u.cash ) { liquidate = true; popup( _( "You don't have enough to pay the workers to harvest the crop so you are forced " diff --git a/src/monattack.cpp b/src/monattack.cpp index 632b62e836bd5..295af4c2e05aa 100644 --- a/src/monattack.cpp +++ b/src/monattack.cpp @@ -3035,8 +3035,13 @@ bool mattack::photograph( monster *z ) } else if( g->u.is_armed() ) { sounds::sound( z->pos(), 15, sounds::sound_t::alert, _( "\"Drop your weapon! Now!\"" ) ); } - const SpeechBubble &speech = get_speech( z->type->id.str() ); - sounds::sound( z->pos(), speech.volume, sounds::sound_t::alert, speech.text ); + if( cname == g->u.name && g->u.cash < 0 && g->u.has_trait( trait_id( "DEBT" ) ) ) { + sounds::sound( z->pos(), 15, sounds::sound_t::alert, + _( "\"Wanted debtor in sight! Commencing debt enforcement proceedings!\"" ) ); + } else { + const SpeechBubble &speech = get_speech( z->type->id.str() ); + sounds::sound( z->pos(), speech.volume, sounds::sound_t::alert, speech.text ); + } g->events.add( EVENT_ROBOT_ATTACK, calendar::turn + rng( 15_turns, 30_turns ), 0, g->u.global_sm_location() ); diff --git a/src/newcharacter.cpp b/src/newcharacter.cpp index 56c993aa5704f..bc543fd759c88 100644 --- a/src/newcharacter.cpp +++ b/src/newcharacter.cpp @@ -550,6 +550,20 @@ bool avatar::create( character_type type, const std::string &tempname ) mod_skill_level( e.first, e.second ); } + // setup staring bank money + + cash = rng( -200000, 200000 ); + + if( has_trait( trait_id( "MILLIONAIRE" ) ) ) { + cash = rng( 500000000, 1000000000 ); + } + if( has_trait( trait_id( "DEBT" ) ) ) { + cash = rng( -1500000, -3000000 ); + } + if( has_trait( trait_id( "SAVINGS" ) ) ) { + cash = rng( 1500000, 2000000 ); + } + // Learn recipes for( const auto &e : recipe_dict ) { const auto &r = e.second; diff --git a/src/npctalk.cpp b/src/npctalk.cpp index d81f4b15593ff..3b5e2055eb138 100644 --- a/src/npctalk.cpp +++ b/src/npctalk.cpp @@ -2784,7 +2784,7 @@ void conditional_t::set_npc_allies( JsonObject &jo ) void conditional_t::set_npc_service( JsonObject &jo ) { - const unsigned long service_price = jo.get_int( "npc_service" ); + const signed long service_price = jo.get_int( "npc_service" ); condition = [service_price]( const dialogue & d ) { return !d.beta->has_effect( effect_currently_busy ) && d.alpha->cash >= service_price; }; @@ -2792,7 +2792,7 @@ void conditional_t::set_npc_service( JsonObject &jo ) void conditional_t::set_u_has_cash( JsonObject &jo ) { - const unsigned long min_cash = jo.get_int( "u_has_cash" ); + const signed long min_cash = jo.get_int( "u_has_cash" ); condition = [min_cash]( const dialogue & d ) { return d.alpha->cash >= min_cash; }; diff --git a/src/npctalk_funcs.cpp b/src/npctalk_funcs.cpp index 00077148483d2..8f30d00ce5654 100644 --- a/src/npctalk_funcs.cpp +++ b/src/npctalk_funcs.cpp @@ -378,7 +378,7 @@ void talk_function::bionic_install( npc &p ) const item tmp = item( bionic_types[bionic_index], 0 ); const itype &it = *tmp.type; - unsigned int price = tmp.price( true ) * 2; + signed int price = tmp.price( true ) * 2; if( price > g->u.cash ) { popup( _( "You can't afford the procedure..." ) ); @@ -429,7 +429,7 @@ void talk_function::bionic_remove( npc &p ) return; } - unsigned int price; + signed int price; if( item::type_is_defined( bionic_types[bionic_index] ) ) { price = 50000 + ( item( bionic_types[bionic_index], 0 ).price( true ) / 4 ); } else { diff --git a/src/output.h b/src/output.h index cf52efe3f0d5c..6c0ede63fc262 100644 --- a/src/output.h +++ b/src/output.h @@ -803,7 +803,7 @@ std::string format_volume( const units::volume &volume ); std::string format_volume( const units::volume &volume, int width, bool *out_truncated, double *out_value ); -inline const std::string format_money( unsigned long cents ) +inline const std::string format_money( signed long cents ) { return string_format( _( "$%.2f" ), cents / 100.0 ); } diff --git a/src/player.h b/src/player.h index fac99313951bf..2aaea45e9db3b 100644 --- a/src/player.h +++ b/src/player.h @@ -1547,7 +1547,7 @@ class player : public Character int blocks_left; int stim; int radiation; - unsigned long cash; + signed long cash; int movecounter; std::shared_ptr mounted_creature; bool death_drops;// Turned to false for simulating NPCs on distant missions so they don't drop all their gear in sight