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

Traders have trading standards #57660

Closed
wants to merge 12 commits into from
Closed
35 changes: 7 additions & 28 deletions src/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6352,31 +6352,7 @@ int item::price( bool practical ) const
int res = 0;

visit_items( [&res, practical]( const item * e, item * ) {
if( e->rotten() ) {
// TODO: Special case things that stay useful when rotten
return VisitResponse::NEXT;
}

int child = units::to_cent( practical ? e->type->price_post : e->type->price );
if( e->damage() > 0 ) {
// maximal damage level is 4, maximal reduction is 40% of the value.
child -= child * static_cast<double>( e->damage_level() ) / 10;
}

if( e->count_by_charges() || e->made_of( phase_id::LIQUID ) ) {
// price from json data is for default-sized stack
child *= e->charges / static_cast<double>( e->type->stack_size );

} else if( e->magazine_integral() && e->ammo_remaining() && e->ammo_data() ) {
// items with integral magazines may contain ammunition which can affect the price
child += item( e->ammo_data(), calendar::turn, e->ammo_remaining() ).price( practical );

} else if( e->is_tool() && e->type->tool->max_charges != 0 ) {
// if tool has no ammo (e.g. spray can) reduce price proportional to remaining charges
child *= e->ammo_remaining() / static_cast<double>( std::max( e->type->charges_default(), 1 ) );
}

res += child;
res += e->price_no_contents( practical );
return VisitResponse::NEXT;
} );

Expand All @@ -6390,8 +6366,12 @@ int item::price_no_contents( bool practical ) const
}
int price = units::to_cent( practical ? type->price_post : type->price );
if( damage() > 0 ) {
// maximal damage level is 4, maximal reduction is 40% of the value.
price -= price * static_cast< double >( damage_level() ) / 10;
// maximal damage level is 4, maximal reduction is 80% of the value.
price -= price * static_cast< double >( damage_level() ) / 5;
}

if( is_filthy() ) {
price *= 0.5;
}

if( count_by_charges() || made_of( phase_id::LIQUID ) ) {
Expand All @@ -6407,7 +6387,6 @@ int item::price_no_contents( bool practical ) const
price *= ammo_remaining() / static_cast< double >( std::max( type->charges_default(), 1 ) );

}

return price;
}

Expand Down
4 changes: 3 additions & 1 deletion src/npc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1937,6 +1937,7 @@ bool npc::wants_to_sell( const item &it, int at_price, int /*market_price*/ ) co
}

// TODO: Base on inventory
// why should he sell things for free?
return at_price >= 0;
}

Expand All @@ -1956,8 +1957,9 @@ bool npc::wants_to_buy( const item &it, int at_price, int /*market_price*/ ) con
return false;
}

// Item sale refusal if worthless
// TODO: Base on inventory
return at_price > 0;
return at_price > 1;
}

// Will the NPC freely exchange items with the player?
Expand Down
28 changes: 20 additions & 8 deletions src/npctrade.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,16 +136,17 @@ double npc_trading::net_price_adjustment( const Character &buyer, const Characte
{
// Adjust the prices based on your social skill.
// cap adjustment so nothing is ever sold below value
///\EFFECT_INT_NPC slightly increases bartering price changes, relative to your INT

///\EFFECT_BARTER_NPC increases bartering price changes, relative to your BARTER
// Boost the NPC selling/buying power
// average (a+b)/2;

///\EFFECT_INT slightly increases bartering price changes, relative to NPC INT

///\EFFECT_BARTER increases bartering price changes, relative to NPC BARTER
double adjust = 0.05 * ( seller.int_cur - buyer.int_cur ) +
price_adjustment( seller.get_skill_level( skill_speech ) -
buyer.get_skill_level( skill_speech ) );
// double average = ( seller.int_cur + buyer.int_cur ) / 2;
double selladjust = 0.05;
if( seller.is_npc() ) {
selladjust = 0.2;
}
double adjust = ( ( selladjust * seller.int_cur ) - ( 0.05 * buyer.int_cur ) ) +
price_adjustment( seller.get_skill_level( skill_speech ) - buyer.get_skill_level( skill_speech ) );
return std::max( adjust, 1.0 );
}

Expand Down Expand Up @@ -202,6 +203,14 @@ int npc_trading::trading_price( Character const &buyer, Character const &seller,
return VisitResponse::SKIP;
}
}
// Prevent free items
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This resets the price of active bombs to 1 cent.

I don't think it's a good idea to hardcode minimum values like this. For example thread is defined in JSON to have a price of 25 cents per 200 units (or unit price of 0.125 cents) and you're just introducing confusing by overriding the JSON definition.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didnt realise that was doing it to bombs, good spotting. However with this PR, traders refuse to buy items that cost 1 cent - and active bombs will be on that category. Perhaps it can be given another flag if this is not enough?

However thread having 25 cents per 200 units is setting it to below 1 cent per item, and that is the problem - I think there is no way to make this system sell something to you for less than a cent. So setting it to 1 cent per item is the only way to stop you from buying it for free.

If you have a better suggestion for preventing items being sold for free, please let me know.. Otherwise I think 1c per item minimum is the best solution for now.

if( price < 1 ) {
if( e->count_by_charges() ) {
ret = 1 * amount;
} else {
ret = 1;
}
}
ret += price;
return VisitResponse::NEXT;
} );
Expand All @@ -221,6 +230,9 @@ void item_pricing::set_values( int ip_count )
charges = i_p->count();
if( charges > 0 ) {
price /= charges;
if( price < 1 ) {
price = 1;
}
vol /= charges;
weight /= charges;
} else {
Expand Down