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

Feature: Advanced Fantasy Race and Multiclass Optional Rules #136

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
9 changes: 8 additions & 1 deletion src/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"OSE.Roll": "Roll",
"OSE.Success": "Success",
"OSE.Failure": "Failure",

"OSE.Multiclass": "Multiclass Character",

"OSE.dialog.tweaks": "Tweaks",
"OSE.dialog.partysheet": "Party Overview",
"OSE.dialog.partyselect": "Select PCs",
Expand Down Expand Up @@ -54,6 +55,7 @@

"OSE.details.name": "Name",
"OSE.details.class": "Class",
"OSE.details.race": "Race",
"OSE.details.title": "Title",
"OSE.details.alignment": "Alignment",
"OSE.details.level": "Level",
Expand All @@ -68,6 +70,9 @@
"OSE.details.morale": "Morale",
"OSE.details.reaction": "Reaction",
"OSE.details.appearing": "NA",
"OSE.details.1stClass": "1st Class",
"OSE.details.2ndClass": "2nd Class",
"OSE.details.3rdClass": "3rd Class",

"OSE.Attack": "Attack",
"OSE.Encumbrance": "Encumbrance",
Expand Down Expand Up @@ -109,6 +114,8 @@
"OSE.HealthShort": "HP",
"OSE.HitDice": "Hit Dice",
"OSE.HitDiceShort": "HD",
"OSE.FractionalHpShort": "HPF",
"OSE.FractionalHp": "Remaining HP Fraction",

"OSE.movement.base": "Movement Rate",
"OSE.movement.short": "MV",
Expand Down
7 changes: 7 additions & 0 deletions src/lang/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"OSE.Roll": "Tirar",
"OSE.Success": "Éxito",
"OSE.Failure": "Fallo",
"OSE.Multiclass": "Multiclass Character",
"OSE.dialog.tweaks": "Ajustes",
"OSE.dialog.partysheet": "Resumen del grupo",
"OSE.dialog.partyselect": "Seleccionar PJ",
Expand Down Expand Up @@ -49,6 +50,7 @@
"OSE.table.treasure.roll": "Tirada de tesoro",
"OSE.details.name": "Nombre",
"OSE.details.class": "Clase",
"OSE.details.race": "Race",
"OSE.details.title": "Título",
"OSE.details.alignment": "Alineamiento",
"OSE.details.level": "Nivel",
Expand All @@ -63,6 +65,9 @@
"OSE.details.morale": "Moral",
"OSE.details.reaction": "Reacción",
"OSE.details.appearing": "NA",
"OSE.details.1stClass": "1st Class",
"OSE.details.2ndClass": "2nd Class",
"OSE.details.3rdClass": "3rd Class",
"OSE.Attack": "Ataque",
"OSE.Encumbrance": "Carga",
"OSE.Retainer": "Sirvientes",
Expand Down Expand Up @@ -99,6 +104,8 @@
"OSE.HealthShort": "PG",
"OSE.HitDice": "Dado de Golpe",
"OSE.HitDiceShort": "DG",
"OSE.FractionalHpShort": "HPF",
"OSE.FractionalHp": "Remaining HP Fraction",
"OSE.movement.base": "Movimiento",
"OSE.movement.short": "MV",
"OSE.movement.details": "Detalles de Movimiento",
Expand Down
7 changes: 7 additions & 0 deletions src/lang/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"OSE.Roll": "Lancer",
"OSE.Success": "Succès",
"OSE.Failure": "Échec",
"OSE.Multiclass": "Multiclass Character",

"OSE.dialog.tweaks": "Ajuster",
"OSE.dialog.partysheet": "Fiche de Groupe",
Expand Down Expand Up @@ -52,6 +53,7 @@
"OSE.details.name": "Nom",
"OSE.details.class": "Classe",
"OSE.details.title": "Titre",
"OSE.details.race": "Race",
"OSE.details.alignment": "Alignement",
"OSE.details.level": "Niveau",
"OSE.details.experience.base": "Expérience",
Expand All @@ -65,6 +67,9 @@
"OSE.details.morale": "Moral",
"OSE.details.reaction": "Réaction",
"OSE.details.appearing": "NA",
"OSE.details.1stClass": "1st Class",
"OSE.details.2ndClass": "2nd Class",
"OSE.details.3rdClass": "3rd Class",

"OSE.Attack": "Attaque",
"OSE.Encumbrance": "Encombrement",
Expand Down Expand Up @@ -106,6 +111,8 @@
"OSE.HealthShort": "PV",
"OSE.HitDice": "Dé de Vie",
"OSE.HitDiceShort": "DV",
"OSE.FractionalHpShort": "HPF",
"OSE.FractionalHp": "Remaining HP Fraction",

"OSE.movement.base": "Déplacement",
"OSE.movement.short": "DP",
Expand Down
7 changes: 7 additions & 0 deletions src/lang/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"OSE.Roll": "Tiro",
"OSE.Success": "Successo",
"OSE.Failure": "Fallimento",
"OSE.Multiclass": "Multiclass Character",
"OSE.dialog.tweaks": "Modifiche",
"OSE.dialog.partysheet": "Panoramica del Gruppo",
"OSE.dialog.partyselect": "Scegli Pg",
Expand Down Expand Up @@ -50,6 +51,7 @@
"OSE.details.name": "Nome",
"OSE.details.class": "Classe",
"OSE.details.title": "Titolo",
"OSE.details.race": "Race",
"OSE.details.alignment": "Allineamento",
"OSE.details.level": "Livello",
"OSE.details.experience.base": "Esperienza",
Expand All @@ -63,6 +65,9 @@
"OSE.details.morale": "Morale",
"OSE.details.reaction": "Reazione",
"OSE.details.appearing": "Nr. Mostri",
"OSE.details.1stClass": "1st Class",
"OSE.details.2ndClass": "2nd Class",
"OSE.details.3rdClass": "3rd Class",
"OSE.Attack": "Attacco",
"OSE.Encumbrance": "Ingombro",
"OSE.Retainer": "Seguace",
Expand Down Expand Up @@ -99,6 +104,8 @@
"OSE.HealthShort": "PF",
"OSE.HitDice": "Dadi Vita",
"OSE.HitDiceShort": "DV",
"OSE.FractionalHpShort": "HPF",
"OSE.FractionalHp": "Remaining HP Fraction",
"OSE.movement.base": "Movimento",
"OSE.movement.short": "MV",
"OSE.movement.details": "Dettagli Movimento",
Expand Down
9 changes: 8 additions & 1 deletion src/lang/pt-BR.json
Original file line number Diff line number Diff line change
Expand Up @@ -280,5 +280,12 @@
"OSE.error.notEnoughGP": "Este Ator não tem PO suficiente para pagar por este inventário.",
"OSE.error.itemNoLongerExistsOnActor": "O Item solicitado {itemId} não existe mais no Ator {actorName}.",
"OSE.error.noTokenControlled": "Você deve ter um ou mais Tokens controlados para poder usar esta opção.",
"OSE.error.noGP": "Você precisa do item PO para usar este recurso."
"OSE.error.noGP": "Você precisa do item PO para usar este recurso.",
"OSE.Multiclass": "Multiclass Character",
"OSE.details.1stClass": "1st Class",
"OSE.details.2ndClass": "2nd Class",
"OSE.details.3rdClass": "3rd Class",
"OSE.FractionalHpShort": "HPF",
"OSE.FractionalHp": "Remaining HP Fraction",
"OSE.details.race": "Race"
}
2 changes: 1 addition & 1 deletion src/module/actor/character-sheet.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export class OseActorSheetCharacter extends OseActorSheet {
* Extend and override the default options used by the 5e Actor Sheet
* @returns {Object}
*/
static get defaultOptions() {
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
classes: ["ose", "sheet", "actor", "character"],
template: `${OSE.systemPath()}/templates/actors/character-sheet.html`,
Expand Down
89 changes: 75 additions & 14 deletions src/module/actor/entity.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,21 +63,82 @@ export class OseActor extends Actor {
if (this.data.type != "character") {
return;
}
let modified = Math.floor(
value + (this.data.data.details.xp.bonus * value) / 100
);
return this.update({
"data.details.xp.value": modified + this.data.data.details.xp.value,
}).then(() => {
const speaker = ChatMessage.getSpeaker({ actor: this });
ChatMessage.create({
content: game.i18n.format("OSE.messages.GetExperience", {
name: this.name,
value: modified,
}),
speaker,
if(!this.data.data.multiclass?.enabled){
let modified = Math.floor(
value + (this.data.data.details.xp.bonus * value) / 100
);
return this.update({
"data.details.xp.value": modified + this.data.data.details.xp.value,
}).then(() => {
const speaker = ChatMessage.getSpeaker({ actor: this });
ChatMessage.create({
content: game.i18n.format("OSE.messages.GetExperience", {
name: this.name,
value: modified,
}),
speaker,
});
});
});
} else {
let xpModified;
let xp2Modified;
let xp3Modified;
let xpForUpdate = value;
let xpsToDisperse = {};
let total = 0;
const xp2Enabled = this.data.data.details.xp2.enabled;
const xp3Enabled = this.data.data.details.xp3.enabled;

if(xp2Enabled){
xpForUpdate = Math.floor(value / 2);
}

if(xp2Enabled && xp3Enabled){
xpForUpdate = Math.floor(value / 3);
}

xpModified = Math.floor(
xpForUpdate + (this.data.data.details.xp.bonus * xpForUpdate) / 100
);

total = xpModified + total;
xpsToDisperse = {
...xpsToDisperse,
"data.details.xp.value": xpModified + this.data.data.details.xp.value
};

if(xp2Enabled){
xp2Modified = Math.floor(
xpForUpdate + (this.data.data.details.xp2.bonus * xpForUpdate) / 100
);
xpsToDisperse = {
...xpsToDisperse,
"data.details.xp2.value":
xp2Modified + this.data.data.details.xp2.value
};
total = xp2Modified + total;
}

if(xp3Enabled){
xp3Modified = Math.floor(
xpForUpdate + (this.data.data.details.xp3.bonus * xpForUpdate) / 100
);
xpsToDisperse = {...xpsToDisperse, "data.details.xp3.value": xp3Modified + this.data.data.details.xp3.value};
total = xp3Modified + total;
}

return this.update(xpsToDisperse).then(() => {
const speaker = ChatMessage.getSpeaker({ actor: this });
ChatMessage.create({
content: game.i18n.format("OSE.messages.GetExperience", {
name: this.name,
value: total,
}),
speaker,
});
});

}
}

isNew() {
Expand Down
43 changes: 43 additions & 0 deletions src/module/dialog/entity-tweaks.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,38 @@ export class OseEntityTweaks extends FormApplication {

/** @override */
activateListeners(html) {

html.find("#multiclass").change(e => {
const multiClassEnabled = $(e.currentTarget).is(":checked");
if(!multiClassEnabled){
html.find("#xp2enabled").val(false);
html.find("#xp3enabled").val(false);
html.find("#experience2").val(0);
html.find("#experience3").val(0);
html.find("#experiencenext2").val(0);
html.find("#experiencenext3").val(0);
html.find(".additional-classes").hide();
html.find(".first-class-multiclass-label").hide();
} else {
html.find(".additional-classes").show();
html.find(".first-class-multiclass-label").show();
}
});

html.find("#xp2enabled").change(e => {
const xp2Enabled = $(e.currentTarget).is(":checked");
if(!xp2Enabled){
html.find("#xp3enabled").val(false).attr("disabled", true);
html.find("#experience3").val(0).attr("readonly", true);
html.find("#experiencenext3").val(0).attr("readonly", true);

} else {
html.find("#xp3enabled").attr("disabled", false);
html.find("#experience3").attr("readonly", false);
html.find("#experiencenext3").attr("readonly", false);
}
});

super.activateListeners(html);
}

Expand All @@ -54,6 +86,17 @@ export class OseEntityTweaks extends FormApplication {
async _updateObject(event, formData) {
event.preventDefault();
// Update the actor
const multiClassEnabled = $("#multiclass").is(":checked");
const xp2Enabled = $("#xp2enabled").is(":checked");

if(!multiClassEnabled){
formData['data.details.xp2.enabled'] = false;
formData['data.details.xp3.enabled'] = false;
}
if(!xp2Enabled){
formData['data.details.xp3.enabled'] = false;
}

this.object.update(formData);
// Re-draw the updated sheet
this.object.sheet.render(true);
Expand Down
14 changes: 14 additions & 0 deletions src/scss/character.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
min-width: 450px;
min-height: 550px;


/* ----------------------------------------- */
/* Sheet Header */
/* ----------------------------------------- */
Expand Down Expand Up @@ -44,6 +45,10 @@
/* ----------------------------------------- */
/* Sheet Body */
/* ----------------------------------------- */
.multiclass .sheet-body {
height: calc(100% - 240px);
}

.sheet-body {
.tab {
height: 100%;
Expand Down Expand Up @@ -242,3 +247,12 @@
/* Item Controls */
/* ----------------------------------------- */
}

/* Tweaks Dialog */

.additional-classes{
margin-bottom: 15px;
&.hidden {
display: none;
}
}
2 changes: 1 addition & 1 deletion src/templates/actors/character-sheet.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<form class="{{cssClass}}" autocomplete="off">
<form class="{{cssClass}}{{#if data.multiclass.enabled}} multiclass{{/if}}" autocomplete="off">
{{! Sheet Header }}
<header class="sheet-header flexrow">
{{> (path "/templates/actors/partials/character-header.html") }}
Expand Down
Loading