Merge pull request #173 from TheLastScrub:TheLastScrub/issue129

[ENH] Sort Custom Skills & Special Trainings alphabetically / by column
This commit is contained in:
TheLastScrub
2025-02-16 20:06:34 -08:00
committed by GitHub
6 changed files with 139 additions and 49 deletions
+1
View File
@@ -88,6 +88,7 @@ The roll tables added to generate operation code names comes from Reddit user /u
- Spanish Translation submitted by [CthulhuRol](https://github.com/CthulhuRol)
- Catalonian Translation submitted by [trombonecot](https://github.com/trombonecot)
- French Translation submitted by [Hrunh](https://github.com/Hrunh)
- Japanese Translation submitted by [ryotai-trpg](https://github.com/ryotai-trpg)
## Fonts (Some in use, others that I would like to use at some point)
+2 -1
View File
@@ -457,7 +457,7 @@ explicitly define a number of rows, rather than columns. */
}
.deltagreen .skill-and-training-controls {
flex: 0 0 80px;
flex: 0 0 35px;
}
.deltagreen .action-pill {
@@ -525,6 +525,7 @@ input.percentile-skill-input {
margin-left: 5px;
height: unset;
align-self: center;
text-align: center !important;
}
input.checkbox-skill-input {
+95 -16
View File
@@ -70,26 +70,43 @@ export default class DeltaGreenActorSheet extends ActorSheet {
// Make it easy for the sheet handlebars to understand how to sort the skills.
data.sortSkillsSetting = game.settings.get("deltagreen", "sortSkills");
let sortedSkills = [];
for (const [key, skill] of Object.entries(this.actor.system.skills)) {
skill.key = key;
skill.sortLabel = game.i18n.localize(`DG.Skills.${key}`);
if (this.actor.type !== "vehicle") {
// fill an array that is sorted based on the appropriate localized entry
let sortedSkills = [];
for (const [key, skill] of Object.entries(this.actor.system.skills)) {
skill.key = key;
skill.sortLabel = game.i18n.localize(`DG.Skills.${key}`);
if (skill.sortLabel === "" || skill.sortLabel === `DG.Skills.${key}`) {
skill.sortLabel = skill.label;
if (skill.sortLabel === "" || skill.sortLabel === `DG.Skills.${key}`) {
skill.sortLabel = skill.label;
}
// if the actor is an NPC or Unnatural, and they have 'hide untrained skills' active,
// it will break the sorting logic, so we have to skip over these
if (
!(
(this.actor.type == "npc" || this.actor.type == "unnatural") &&
this.actor.system.showUntrainedSkills == true &&
skill.proficiency < 1
)
) {
sortedSkills.push(skill);
}
}
sortedSkills.push(skill);
sortedSkills.sort(function (a, b) {
return a.sortLabel.localeCompare(b.sortLabel, game.i18n.lang);
});
// if sorting by columns, re-arrange the array to be columns first, then rows
if (game.settings.get("deltagreen", "sortSkills")) {
let columnSortedSkills = this.reorderForColumnSorting(sortedSkills, 3);
this.actor.system.sortedSkills = columnSortedSkills;
} else {
this.actor.system.sortedSkills = sortedSkills;
}
}
//console.log(sortedSkills);
sortedSkills.sort(function (a, b) {
return a.sortLabel.localeCompare(b.sortLabel, game.i18n.lang);
});
this.actor.system.sortedSkills = sortedSkills;
// Prepare a simplified version of the special training for display on sheet.
if (this.actor.type !== "vehicle") {
const specialTraining = this.actor.system.specialTraining.map(
@@ -129,6 +146,53 @@ export default class DeltaGreenActorSheet extends ActorSheet {
data.specialTraining = specialTraining;
}
// try to make a combined array of both typed skills and special trainings,
// so that it can be sorted together neatly on the sheet
if (this.actor.type !== "vehicle") {
let sortedCustomSkills = [];
for (const [key, skill] of Object.entries(
this.actor.system.typedSkills
)) {
skill.type = "typeSkill";
skill.key = key;
skill.sortLabel = skill.group + "." + skill.label;
skill.sortLabel = skill.sortLabel.toUpperCase();
skill.actorType = this.actor.type;
if (skill.sortLabel === "" || skill.sortLabel === `DG.Skills.${key}`) {
skill.sortLabel = skill.label;
}
sortedCustomSkills.push(skill);
}
for (var i = 0; i < data.specialTraining.length; i++) {
let training = data.specialTraining[i];
training.type = "training";
training.sortLabel = training.name.toUpperCase();
training.actorType = this.actor.type;
sortedCustomSkills.push(training);
}
sortedCustomSkills.sort(function (a, b) {
return a.sortLabel.localeCompare(b.sortLabel, game.i18n.lang);
});
if (game.settings.get("deltagreen", "sortSkills")) {
let columnSortedSkills = this.reorderForColumnSorting(
sortedCustomSkills,
2
);
this.actor.system.sortedCustomSkills = columnSortedSkills;
} else {
this.actor.system.sortedCustomSkills = sortedCustomSkills;
}
}
switch (this.actor.type) {
case "agent":
data.enrichedDescription = await TextEditor.enrichHTML(
@@ -155,6 +219,21 @@ export default class DeltaGreenActorSheet extends ActorSheet {
return data;
}
reorderForColumnSorting(arr, numCols) {
let numRows = Math.ceil(arr.length / numCols);
let reordered = new Array(arr.length);
for (let i = 0; i < arr.length; i++) {
let row = i % numRows;
let col = Math.floor(i / numRows);
let newIndex = row * numCols + col;
reordered[newIndex] = arr[i];
}
return reordered;
}
// some handlers may wish to avoid leading players to think they should be seeking out magic
// so control whether an actor sheet shows the hypergeometry (rituals and tomes) section
shouldShowHyperGeometrySection(actor) {
+2 -2
View File
@@ -96,9 +96,9 @@
<span>{{localize "DG.Sheet.BlockHeaders.SkillsAndTraining"}}</span>
</div>
<div class="grid grid-3col {{#if sortSkillsSetting}}grid-13row{{/if}}">
<div class="grid grid-3col">
{{#each actor.system.sortedSkills as |skill key|}}
<div class="flexrow flex-group-center flex-thin-border">
<div class="flexrow flex-group-left flex-thin-border">
<label class="{{if_gt skill.proficiency 0 'rollable' 'not-rollable'}} skill-label" data-key="{{skill.key}}" data-rolltype="skill" for="system.skills.{{skill.key}}.value"
{{#if skill.proficiency}}title="{{localize 'DG.Tooltip.SkillLabel'}}"{{/if}}
{{#unless skill.proficiency}}title="{{localize 'DG.Tooltip.CannotRollSkillLabel'}}"{{/unless}}
+2 -2
View File
@@ -97,11 +97,11 @@
<i class="far fa-eye{{#if actor.system.showUntrainedSkills}}-slash{{/if}}"></i>
</a>
</div>
<div class="grid grid-3col {{#if sortSkillsSetting}}grid-13row{{/if}}">
<div class="grid grid-3col">
{{#each actor.system.sortedSkills as |skill key|}}
{{#if (hideSkillBasedOnProficiencyAndUserChoice ../actor.system.showUntrainedSkills skill.proficiency)}}
<div class="flexrow flex-group-center flex-thin-border">
<div class="flexrow flex-group-left flex-thin-border">
<label class="{{if_gt skill.proficiency 0 'rollable' 'not-rollable'}} skill-label" data-rolltype="skill" data-key="{{skill.key}}" for="system.skills.{{skill.key}}.value"
{{#if skill.proficiency}}title="{{localize 'DG.Tooltip.SkillLabel'}}"{{/if}}
{{#unless skill.proficiency}}title="{{localize 'DG.Tooltip.CannotRollSkillLabel'}}"{{/unless}}
@@ -7,39 +7,48 @@
</div>
<div class="grid-2col">
{{#each actor.system.typedSkills as |skill key|}}
<div class="item flexrow flex-group-center flex-thin-border">
{{#each actor.system.sortedCustomSkills as |skill|}}
{{#if_eq type "typeSkill"}}
<div class="item flexrow flex-group-left flex-thin-border">
<div class="flexrow">
<label class="{{if_gt skill.proficiency 0 'rollable' 'not-rollable'}} skill-label" data-key="{{skill.key}}" data-rolltype="skill" data-roll="d100" data-target="{{skill.proficiency}}" data-label="{{skill.label}}"
{{#if skill.proficiency}}title="{{localize 'DG.Tooltip.SkillLabel'}}"{{/if}}
{{#unless skill.proficiency}}title="{{localize 'DG.Tooltip.CannotRollSkillLabel'}}"{{/unless}}
>
{{skill.group}} ({{skill.label}})
<i class="fas fa-dice"></i>
</label>
<input class="percentile-skill-input" type="text" name="system.typedSkills.{{skill.key}}.proficiency" value="{{skill.proficiency}}" data-dtype="Number"/>
{{#if_eq skill.actorType "agent"}}
<input class="checkbox-skill-input" type="checkbox" name="system.typedSkills.{{skill.key}}.failure" {{checked skill.failure}} data-dtype="Boolean" {{#if skill.cannotBeImprovedByFailure}} disabled {{/if}} />
{{/if_eq}}
</div>
<div class="item-controls skill-and-training-controls">
<a class="item-control typed-skill-edit" title="Edit Skill"><i class="fas fa-edit" data-typedskill="{{skill.key}}" ></i></a>
<a class="item-control typed-skill-delete" title="Delete Skill"><i class="fas fa-trash" data-typedskill="{{skill.key}}" ></i></a>
</div>
</div>
{{/if_eq}}
{{#if_eq type "training"}}
<div class="item flexrow flex-group-left flex-thin-border special-training-box">
<div class="flexrow">
<label class="{{if_gt skill.proficiency 0 'rollable' 'not-rollable'}} skill-label" data-key="{{key}}" data-rolltype="skill" data-roll="d100" data-target="{{skill.proficiency}}" data-label="{{skill.label}}"
{{#if skill.proficiency}}title="{{localize 'DG.Tooltip.SkillLabel'}}"{{/if}}
{{#unless skill.proficiency}}title="{{localize 'DG.Tooltip.CannotRollSkillLabel'}}"{{/unless}}
>
{{skill.group}} ({{skill.label}})
<label class="{{if_gt skill.targetNumber 0 'rollable' 'not-rollable'}}" data-key="{{skill.key}}" data-name="{{skill.name}}" data-rolltype="special-training">
{{skill.name}} ({{skill.attribute}}, {{skill.targetNumber}}%)
<i class="fas fa-dice"></i>
</label>
<input class="percentile-skill-input" type="text" name="system.typedSkills.{{key}}.proficiency" value="{{skill.proficiency}}" data-dtype="Number"/>
{{#if_eq ../actorType "agent"}}
<input class="checkbox-skill-input" type="checkbox" name="system.typedSkills.{{key}}.failure" {{checked skill.failure}} data-dtype="Boolean" {{#if skill.cannotBeImprovedByFailure}} disabled {{/if}} />
{{/if_eq}}
</div>
<div class="item-controls skill-and-training-controls">
<a class="item-control typed-skill-edit" title="Edit Skill"><i class="fas fa-edit" data-typedskill="{{key}}" ></i></a>
<a class="item-control typed-skill-delete" title="Delete Skill"><i class="fas fa-trash" data-typedskill="{{key}}" ></i></a>
<div class="item-controls skill-and-training-controls">
<a class="item-control special-training-action" data-action="Edit" data-id="{{skill.id}}" title="Edit Training"><i class="fas fa-edit"></i></a>
<a class="item-control special-training-delete" title="Delete Training" data-id="{{skill.id}}" ><i class="fas fa-trash"></i></a>
</div>
</div>
</div>
{{/each}}
{{#each specialTraining as |training|}}
<div class="item flexrow flex-group-center flex-thin-border special-training-box">
<label class="{{if_gt training.targetNumber 0 'rollable' 'not-rollable'}}" data-key="{{training.key}}" data-name="{{training.name}}" data-rolltype="special-training">
{{training.name}} ({{training.attribute}}, {{training.targetNumber}}%)
<i class="fas fa-dice"></i>
</label>
<div class="item-controls skill-and-training-controls">
<a class="item-control special-training-action" data-action="Edit" data-id="{{training.id}}" title="Edit Training"><i class="fas fa-edit"></i></a>
<a class="item-control special-training-delete" title="Delete Training" data-id="{{training.id}}" ><i class="fas fa-trash"></i></a>
</div>
</div>
{{/each}}
{{/if_eq}}
{{/each}}
</div>