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

Group mod credits by role instead of bunching them together #706

Merged
merged 6 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import net.minecraft.client.gui.widget.ElementListWidget;
import net.minecraft.client.gui.widget.EntryListWidget;
import net.minecraft.client.render.*;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.OrderedText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
Expand Down Expand Up @@ -207,20 +206,40 @@ public void renderList(DrawContext DrawContext, int mouseX, int mouseY, float de
children().add(new MojangCreditsEntry(line));
}
} else if (!"java".equals(mod.getId())) {
List<String> credits = mod.getCredits();
var credits = mod.getCredits();

if (!credits.isEmpty()) {
children().add(emptyEntry);

for (OrderedText line : textRenderer.wrapLines(CREDITS_TEXT, wrapWidth)) {
children().add(new DescriptionEntry(line));
}

for (String credit : credits) {
var iterator = credits.entrySet().iterator();

while (iterator.hasNext()) {
int indent = 8;
for (OrderedText line : textRenderer.wrapLines(Text.literal(credit), wrapWidth - 16)) {

var role = iterator.next();
var roleName = role.getKey();

for (var line : textRenderer.wrapLines(this.creditsRoleText(roleName), wrapWidth - 16)) {
children().add(new DescriptionEntry(line, indent));
indent = 16;
}

for (var contributor : role.getValue()) {
indent = 16;

for (var line : textRenderer.wrapLines(Text.literal(contributor), wrapWidth - 24)) {
children().add(new DescriptionEntry(line, indent));
indent = 24;
}
}

if (iterator.hasNext()) {
children().add(emptyEntry);
}
}
}
}
Expand Down Expand Up @@ -331,6 +350,18 @@ public void renderScrollBar(BufferBuilder bufferBuilder, Tessellator tessellator
}
}

private Text creditsRoleText(String roleName) {
// Replace spaces and dashes in role names with underscores if they exist
// Notably Quilted Fabric API does this with FabricMC as "Upstream Owner"
var translationKey = roleName.replaceAll("[\s-]", "_");

// Add an s to the default untranslated string if it ends in r since this
// Fixes common role names people use in English (e.g. Author -> Authors)
var fallback = roleName.endsWith("r") ? roleName + "s" : roleName;
Copy link
Member

Choose a reason for hiding this comment

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

this seems a bit strange but I guess it's fine lol. we can remove if it causes issues


return Text.translatableWithFallback("modmenu.credits.role." + translationKey, fallback).append(Text.literal(":"));
}

protected class DescriptionEntry extends ElementListWidget.Entry<DescriptionEntry> {
protected OrderedText text;
protected int indent;
Expand Down
10 changes: 8 additions & 2 deletions src/main/java/com/terraformersmc/modmenu/util/mod/Mod.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,17 @@ default String getTranslatedDescription() {
@NotNull
List<String> getAuthors();

/**
* @return a mapping of contributors to their roles.
*/
@NotNull
List<String> getContributors();
Map<String, Collection<String>> getContributors();

/**
* @return a mapping of roles to each contributor with that role.
*/
@NotNull
List<String> getCredits();
SortedMap<String, SortedSet<String>> getCredits();

@NotNull
Set<Badge> getBadges();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,13 @@ public FabricDummyParentMod(FabricMod host, String id) {
}

@Override
public @NotNull List<String> getContributors() {
return new ArrayList<>();
public @NotNull Map<String, Collection<String>> getContributors() {
return Map.of();
}

@Override
public @NotNull List<String> getCredits() {
return new ArrayList<>();
public @NotNull SortedMap<String, SortedSet<String>> getCredits() {
return new TreeMap<>();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,20 +211,35 @@ public FabricMod(ModContainer modContainer, Set<String> modpackMods) {
}

@Override
public @NotNull List<String> getContributors() {
List<String> authors = metadata.getContributors().stream().map(Person::getName).collect(Collectors.toList());
if ("minecraft".equals(getId()) && authors.isEmpty()) {
return Lists.newArrayList();
public @NotNull Map<String, Collection<String>> getContributors() {
Map<String, Collection<String>> contributors = new HashMap<>();

for (var contributor : this.metadata.getContributors()) {
contributors.put(contributor.getName(), List.of("Contributor"));
}
return authors;

return contributors;
}

@NotNull
public List<String> getCredits() {
List<String> list = new ArrayList<>();
list.addAll(getAuthors());
list.addAll(getContributors());
return list;
@Override
public @NotNull SortedMap<String, SortedSet<String>> getCredits() {
SortedMap<String, SortedSet<String>> credits = new TreeMap<>();

var authors = this.getAuthors();
var contributors = this.getContributors();

for (var author : authors) {
contributors.put(author, List.of("Author"));
}

for (var contributor : contributors.entrySet()) {
for (var role : contributor.getValue()) {
credits.computeIfAbsent(role, key -> new TreeSet<>(String.CASE_INSENSITIVE_ORDER));
credits.get(role).add(contributor.getKey());
}
}

return credits;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,17 @@
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.stream.Collectors;

public class QuiltMod extends FabricMod {
Expand Down Expand Up @@ -51,17 +59,30 @@ public QuiltMod(net.fabricmc.loader.api.ModContainer fabricModContainer, Set<Str
}

@Override
public @NotNull List<String> getContributors() {
List<String> authors = metadata.contributors().stream().map(modContributor -> modContributor.name() + " (" + modContributor.role() + ")").collect(Collectors.toList());
if ("minecraft".equals(getId()) && authors.isEmpty()) {
return Lists.newArrayList();
public @NotNull Map<String, Collection<String>> getContributors() {
Map<String, Collection<String>> contributors = new HashMap<>();

for (var contributor : this.metadata.contributors()) {
contributors.put(contributor.name(), contributor.roles());
}
return authors;

return contributors;
}

@Override
public @NotNull List<String> getCredits() {
return this.getContributors();
public @NotNull SortedMap<String, SortedSet<String>> getCredits() {
SortedMap<String, SortedSet<String>> credits = new TreeMap<>();

var contributors = this.getContributors();

for (var contributor : contributors.entrySet()) {
for (var role : contributor.getValue()) {
credits.computeIfAbsent(role, key -> new TreeSet<>(String.CASE_INSENSITIVE_ORDER));
credits.get(role).add(contributor.getKey());
}
}

return credits;
}


Expand Down
8 changes: 8 additions & 0 deletions src/main/resources/assets/modmenu/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@
"modmenu.wiki": "Wiki",
"modmenu.youtube": "YouTube",

"modmenu.credits.role.author": "Authors",
"modmenu.credits.role.contributor": "Contributors",
"modmenu.credits.role.translator": "Translators",
"modmenu.credits.role.maintainer": "Maintainers",
"modmenu.credits.role.playtester": "Playtesters",
"modmenu.credits.role.illustrator": "Illustrators",
"modmenu.credits.role.owner": "Owners",

"modmenu.modsFolder": "Open Mods Folder",
"modmenu.configsFolder": "Open Configs Folder",

Expand Down
Loading