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

Refactor devilution.DefaultClass::CheckCursMove() #1995

Open
AJenbo opened this issue May 17, 2021 · 2 comments
Open

Refactor devilution.DefaultClass::CheckCursMove() #1995

AJenbo opened this issue May 17, 2021 · 2 comments
Labels
good first issue Good for newcomers help wanted Extra attention is needed

Comments

@AJenbo
Copy link
Member

AJenbo commented May 17, 2021

I've selected devilution.DefaultClass::CheckCursMove() for refactoring, which is a unit of 421 lines of code. Addressing this will make our codebase more maintainable and improve Better Code Hub's Write Short Units of Code guideline rating! 👍

Here's the gist of this guideline:

  • Definition 📖
    Limit the length of code units to 15 lines of code.
  • Why
    Small units are easier to analyse, test and reuse.
  • How 🔧
    When writing new units, don't let them grow above 15 lines of code. When a unit grows beyond this, split it in smaller units of no longer than 15 lines.

You can find more info about this guideline in Building Maintainable Software. 📖


Good luck and happy coding! :shipit: ✨ 💯

@AJenbo AJenbo added good first issue Good for newcomers help wanted Extra attention is needed labels May 17, 2021
@mpanneton
Copy link

Hi! I may be able to help to refactor certain part of this code.

First, many conditions check things like: (mx + 2 < MAXDUNX && my + 1 < MAXDUNY) can it be replace it by using the currentTile Point variable on line 343 and the function bool InDungeonBounds(Point position) in the gendung.h file?

instead of : if (!flipflag && mx + 2 < MAXDUNX && my + 1 < MAXDUNY && dMonster[mx + 2][my + 1] != 0 && IsTileLit({ mx + 2, my + 1 }))

We could have : if (!flipflag && InDungeonBounds(currentTile) && dMonster[mx + 2][my + 1] != 0 && IsTileLit({ mx + 2, my + 1 }))

Thanks!

@AJenbo
Copy link
Member Author

AJenbo commented May 9, 2022

@mpanneton Hi an welcome :)

This looks like a really good part to start on. I would suggest a few further steps for the code in question.

On line 594 you will see currentTile being used build an offset that is then used for the acutal comparisons:

Point testPosition = currentTile + Direction::South;
Object *object = ObjectAtPosition(testPosition);

This avoid applying the offset in each comparison.

If you create a helper IsMonsterAtPosition() for dMonster similar to IsObjectAtPosition() is for dObject, that would also avoid having to repeat testPosition for x/y.

Leaving us with the following:

Point testPosition = currentTile + Direction::South + Direction::SouthEast;
if (!flipflag && InDungeonBounds(testPosition) && IsMonsterAtPosition(testPosition) && IsTileLit(testPosition)) {
    cursPosition = testPosition
}

I'm thinking that this can also be punted of in to a small helper function since there is lots of similar checks in the code, this would again save on repetition and make things more readable:

bool IsVisibleMonsterOnTile(Point tile)
{
    return InDungeonBounds(tile) && IsMonsterAtPosition(tile) && IsTileLit(tile)
}

Point testPosition = currentTile + Direction::South + Direction::SouthEast;
if (!flipflag && IsVisibleMonsterOnTile(testPosition)) {
    cursPosition = testPosition
}

(IsMonsterAtPosition might be redundant at this point, but could be useful elsewhere)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants