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

Why not just use String.format("%.2f", health) to format health values? #4

Closed
James103 opened this issue May 21, 2021 · 6 comments
Closed

Comments

@James103
Copy link

Instead of using String.valueOf((float) Math.round(health * 100.0F) / 100.0F); to round and display the health values to the nearest hundredth, why not just use String.format("%.2f", health) instead? The latter gives a consistent level of precision (always the nearest hundredth instead of sometimes the nearest tenth or whole number), which provides a consistent full length for the health counter on the mob's name.

With String.valueOf((float) Math.round(health * 100.0F) / 100.0F);, you could get something like the following:

  • "12.34/20❤" would be displayed as "12.34/20❤" as expected.
  • "12.70/20❤" would be displayed as "12.7/20❤", which is rounding further than expected given the first example.
  • "14.00/20❤" would be displayed as "14/20❤". In isolation, this could work, but given the first two examples, there may be some unnecessary further visual precision loss going on here.

With String.format("%.2f", health), all 3 of the above examples would be displayed to 2 decimal places, i.e.

  • "12.34/20❤" remains as "12.34/20❤".
  • "12.70/20❤" remains as "12.70/20❤".
  • "14.00/20❤" remains as "14.00/20❤".
@samolego
Copy link
Owner

Well, if I tell the real reason, I was actually not even aware of that formatting. We learn things every day ;) ...

@James103
Copy link
Author

The following is the full body of the function that I have modified to get what I wanted out of the displays:

    public MutableText getHealthbarText(float health, float maxHealth) {
        if(health < 0.0F) {
            health = 0.0F;
        }
        if(maxHealth <= 0.0F) {
            maxHealth = 1.0F;
        }
        if(health > maxHealth) {
            maxHealth = health;
        }

        String first, second;
        if(this.healthbarStyle.equals(HealthbarStyle.SKYBLOCK)) {
            // String.format("%.2f", health) for rounding
            first = String.format("%.2f", health);
            second = String.valueOf((int) Math.ceil(maxHealth));

            // We return it here because of custom formatting
            return new LiteralText(first)
                    .formatted(health > maxHealth / 2 ? Formatting.GREEN : Formatting.YELLOW)
                    .append(new LiteralText("/")
                        .formatted(Formatting.WHITE))
                    .append(new LiteralText(second)
                        .formatted(Formatting.GREEN))
                    .append(new LiteralText(String.valueOf((char) 10084)) // ❤
                            .formatted(Formatting.RED));
        } else if(this.healthbarStyle.equals(HealthbarStyle.NUMBER)) {
            // Number
            // String.format("%.2f", health) for rounding
            first = String.format("%.2f", health);
            second = "/" + String.format("%.2f", maxHealth);
        } else if(this.healthbarStyle.equals(HealthbarStyle.PERCENTAGE)) {
            first = String.format("%.2f", health * 100.0F / maxHealth).concat("%");
            second = "";
        } else {
            int heartCount, fullHearts;
            char full, empty;
            if(this.healthbarStyle.equals(HealthbarStyle.LINES)) {
                heartCount = maxHealth < 20 ? (int) Math.ceil(maxHealth) : 20;

                empty = '|';
                full = '|';
            } else { // Hearts
                // We ceil the number to not show 0 hearts if entity has like 0.2f health
                int length = this.healthbarStyle == HealthbarStyle.CUSTOM ? customLength : 10;
                heartCount = maxHealth < length ? (int) Math.ceil(maxHealth) : length;

                full = (char) (this.healthbarStyle.equals(HealthbarStyle.HEARTS) ? 9829 : this.customFullChar); // ♥ or custom
                empty = (char) (this.healthbarStyle.equals(HealthbarStyle.HEARTS) ? 9825 : this.customEmptyChar); // ♡ or custom
            }

            // Hearts that should be colored red
            fullHearts = (int) Math.ceil(health * heartCount / maxHealth);

            first = new String(new char[fullHearts]).replace('\0', full);
            second = new String(new char[heartCount - fullHearts]).replace('\0', empty);
        }

        return new LiteralText(first)
                .formatted(Formatting.RED) /*health > maxHealth / 3 ? (health > maxHealth * 1.5F ? Formatting.YELLOW : Formatting.GOLD) : */
                .append(new LiteralText(second).formatted(Formatting.GRAY));
    }

@James103
Copy link
Author

Closing as fixed (implemented) in 6689a04.

@samolego
Copy link
Owner

Yes, release is on the way :). Thanks!

@James103
Copy link
Author

The commit managed to generate an error of the following form:

Upload failed! Status: 400 Error: invalid_input Reason: Error with multipart data: A version with that version_number already exists

See: https://github.com/samolego/HealthCare/runs/2704820180

In other words, have you bumped the version yet?

@samolego
Copy link
Owner

ohno, forgot to add the file to git :|

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants