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

feat(port): Add book binder with many QoL #2170

Closed
wants to merge 17 commits into from

Conversation

leoCottret
Copy link
Collaborator

@leoCottret leoCottret commented Nov 6, 2022

Summary

SUMMARY: Features "Add book binder with many QoL"

Purpose of change

Being able to copy and keep the most interesting recipes on you, even if they were above your level when you copied them.
Also, it was one of the (many) PR to port before
CleverRaven/Cataclysm-DDA#46304
and
CleverRaven/Cataclysm-DDA#49408 (the final boss)

Describe the solution

Port CleverRaven/Cataclysm-DDA#44399
and CleverRaven/Cataclysm-DDA#50367

Changes from the original PR:

  • when you copy a new recipe, the old recipes that you already know are removed with a message. This means you'll be able to keep the same book binder for the entire game.
    image

  • the PR added some randomness to the spawn of paper, I didn't port it

  • you could only copy recipes that match your skill level, I removed the requirement

    • but instead, I added a check on the skill level when you open your craft menu
    • which means, you can copy any recipe from any book, but you will only be able to craft it when you met the requirement
    • I also removed the learnt recipes, and the recipes already in the book binder from the selection
    • hopefully, those changes will make it more user friendly
  • the pen can be used to write too (it has some charges now)

  • the copying time has been greatly reduced (it was quite long before, probably aligned with DDA pace)

  • lots of change to the book binder item

    • it's not a GENERIC item, but a TOOL
    • it uses paper as charges
    • by default (when you craft it, and when it spawns), it has respectively 0 or 1 charges (the first page is used)
    • then, copying a recipe increases the amount of charges in it
    • when it's full of charges, you can't add new recipes in this one
    • I could make it infinite, but since it's a tool and not a GENERIC item that contains paper, only the weight increases, not the volume. So I set the maximum at 500 pages (roughly 100 recipes). Although with the first point of this section, it doesn't matter much now.
    • lots of extra check have been added, or moved before the recipe to copy selection, to warn the player earlier that the action can't be done (cf tests)

Describe alternatives you've considered

Not porting it, and port the e-book one directly (but way too many changes)
Porting the e-book one in this PR too (too big)

Testing

  • remove the flags UNLOAD, and RELOAD, spawn new character with 0 skills
  • test the following conditions: book is full, no paper on player, no writing tool, in the dark, you get special messages before selecting a recipe to copy
  • test the following conditions: 2 papers on the player, or "1 paper left" in the book: only the recipes with a number of page below or equal to those requirements can be selected (wasn't the case)
  • spawn the "A History of Firefighting" book
  • copy the fire axe and the crash axe recipe
  • the book has now 5 + 4 pages in it
  • open the copy recipe menu, they are not here anymore
  • drop the "A History of Firefighting" book, and go away from it
  • select view recipe, they are here
  • increase your fabrication skill to 5, try to craft them, they don't appear
  • increase your fabrication skill to 6, the crash axe appears
  • increase your fabrication skill to 9, the fire axe appears
  • drop the book binder, go away from it
  • they don't appear in the craft menu (not memorised yet)
  • read the "A History of Firefighting" book once
  • try to copy a recipe, then view the recipes. They disappeared because you learnt them by reading the book

@github-actions github-actions bot added JSON related to game datas in JSON format. src changes related to source code. labels Nov 6, 2022
@leoCottret leoCottret marked this pull request as draft November 6, 2022 16:03
@leoCottret leoCottret changed the title [Port] Add book binder [Port] Add book binder with many QoL Nov 6, 2022
@leoCottret
Copy link
Collaborator Author

If it passes clang-tidy checks, this is ready for review

@leoCottret leoCottret marked this pull request as ready for review November 7, 2022 01:21
@scarf005
Copy link
Member

scarf005 commented Nov 7, 2022

that's great. one more idea: maybe it could also extract recipies from a book without requiring pen and paper, at the cost of destroying the book

@leoCottret
Copy link
Collaborator Author

that's great. one more idea: maybe it could also extract recipies from a book without requiring pen and paper, at the cost of destroying the book

Would it be worth it though? You would lose the ability to potentially read the book, for you and your followers.
I asked a bit on discord what other people think, because I don't mind to add it if needed.

src/item.h Outdated Show resolved Hide resolved
@Coolthulhu
Copy link
Member

/home/runner/work/Cataclysm-BN/Cataclysm-BN/src/iuse.cpp:9867:10: error: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty,-warnings-as-errors]
    if( !not_learnt_recipes.size() ) {
        ~^~~~~~~~~~~~~~~~~~~~~~~~~
        not_learnt_recipes.empty()

*
* @return true if the recipe was added, false if it is a duplicate
*/
bool eipc_recipe_add( const recipe_id &recipe_id );
Copy link
Member

Choose a reason for hiding this comment

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

This should be changed just like eipc_recipe_remove.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This doesn't work, eipc_recipe_add is used in iuse.cpp and activity_actor.cpp

Copy link
Contributor

Choose a reason for hiding this comment

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

They both could be extracted into item_functions.h (declarations) + item_functions.cpp (definitions), that's a file specifically for new functions that use public members of item class.

@leoCottret leoCottret marked this pull request as draft November 21, 2022 21:20
@leoCottret leoCottret marked this pull request as ready for review November 22, 2022 17:35
Copy link
Contributor

@olanti-p olanti-p left a comment

Choose a reason for hiding this comment

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

The binder is working in-game, so functional part is good, this is more code style nitpicks and commentary.

Comment on lines +236 to +243
"id": "napkin",
"name": { "str": "napkin" },
"category": "spare_parts",
"weight": "3 g",
"color": "white",
"comestible_type": "FOOD",
"symbol": "`",
"description": "A piece of paper. Can be used for fires.",
"description": "A napkin. Can be used for fires.",
Copy link
Contributor

Choose a reason for hiding this comment

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

Is adding this new item intentional? It looks like a merge conflict.
There are no references to napkin anywhere, it won't spawn in game world.


void bookbinder_copy_activity_actor::do_turn( player_activity &, Character &p )
{
if( character_funcs::fine_detail_vision_mod( p ) > 4.0f ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

A function has been added for this, no need for magic numbers anymore

Suggested change
if( character_funcs::fine_detail_vision_mod( p ) > 4.0f ) {
if( !character_funcs::can_see_fine_details( p ) ) {


player->consume_tools( writing_tools, pages );
} else {
debugmsg( "Recipe book already has '%s' recipe when it should not.", rec_id.str() );
Copy link
Contributor

Choose a reason for hiding this comment

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

The cast here is done automatically

Suggested change
debugmsg( "Recipe book already has '%s' recipe when it should not.", rec_id.str() );
debugmsg( "Recipe book already has '%s' recipe when it should not.", rec_id );

return 0;
}

if( character_funcs::fine_detail_vision_mod( *p ) > 4.0f ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if( character_funcs::fine_detail_vision_mod( *p ) > 4.0f ) {
if( !character_funcs::can_see_fine_details( *p ) ) {

std::string current_recipes = it.get_var( "EIPC_RECIPES" );
if( current_recipes.empty() ) {
return false;
} else if( current_recipes.find( "," + recipe_id.str() + "," ) != std::string::npos ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This pattern

std::string current_recipes = it.get_var( "EIPC_RECIPES" );
 . . .
check if current_recipes.find( "," + recipe_id.str() + "," ) != std::string::npos is true

repeats multiple times thorough the PR and should ideally be extracted into a dedicated function (say, bool eipc_recipe_check( const item &it, const recipe_id &recipe_id ), but that's more of a nit towards original implementation.

Comment on lines +9863 to +9865
p->add_msg_if_player( m_info, _
( string_format( "You already know some recipes. You remove %d pages from the book binder.",
total_pages_removed ) ) );
Copy link
Contributor

Choose a reason for hiding this comment

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

_() must receive either a string literal or a string specifically marked for translation via translate_marker(). Passing it a dynamically generated string won't work.

Suggested change
p->add_msg_if_player( m_info, _
( string_format( "You already know some recipes. You remove %d pages from the book binder.",
total_pages_removed ) ) );
p->add_msg_if_player( m_info, string_format( _( "You already know some recipes. You remove %d pages from the book binder." ),
total_pages_removed ) );



std::vector<const recipe *> not_learnt_recipes;
std::string old_recipes = binder->get_var( "EIPC_RECIPES" );
Copy link
Contributor

Choose a reason for hiding this comment

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

Unused store (the variable gets assigned here, but nothing uses the value, and a few lines down it get re-assigned again with new value).

Suggested change
std::string old_recipes = binder->get_var( "EIPC_RECIPES" );

}

// only keep not learnt recipes and those that are not already in the book
old_recipes = binder->get_var( "EIPC_RECIPES" );
Copy link
Contributor

Choose a reason for hiding this comment

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

(unused store part 2)

Suggested change
old_recipes = binder->get_var( "EIPC_RECIPES" );
std::string old_recipes = binder->get_var( "EIPC_RECIPES" );


for( const recipe *rec : not_learnt_recipes ) {

const int pages = 1 + rec->difficulty / 2;
Copy link
Contributor

Choose a reason for hiding this comment

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

This pattern should also have been extracted into a function, say

int calc_recipe_binder_usage( const recipe_id& r ) {
    return 1 + r->difficulty / 2;
}

Comment on lines +248 to +253
std::vector<const recipe *> recipe_subset::get_recipes()
{
std::vector<const recipe *> ret( recipes.begin(), recipes.end() );
return ret;
}

Copy link
Contributor

Choose a reason for hiding this comment

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

I really hate how all functions here straight up allocate vectors on each call.

@Coolthulhu Coolthulhu removed their assignment Dec 11, 2022
@scarf005 scarf005 changed the title [Port] Add book binder with many QoL feat(port): Add book binder with many QoL Nov 13, 2023
@Lamandus
Copy link
Contributor

is this PR still worked on?

@Lamandus
Copy link
Contributor

Lamandus commented Apr 2, 2024

Same here, open it up again, if you are willing to work on it.

@Lamandus Lamandus closed this Apr 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
JSON related to game datas in JSON format. src changes related to source code.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants