Merge branch 'master' into master

This commit is contained in:
TheLastScrub
2021-03-13 22:01:29 -08:00
committed by GitHub
8 changed files with 575 additions and 240 deletions
+1 -1
View File
@@ -207,7 +207,7 @@
"DG.ModifySkillRollDialogue.Title": "Modify Roll",
"DG.ModifySkillRollDialogue.Test": "Test:",
"DG.ModifySkillRollDialogue.OriginalTarget": "Original Target:",
"DG.ModifySkillRollDialogue.TargetModifier": "Modify Target:",
"DG.ModifySkillRollDialogue.TargetModifier": "Modify Target (+/-):",
"DG.ModifySkillRollDialogue.ModifierTooltip": "Give a positive or negative modifier here to add/subtract from the target for the skill check.",
"DG.ModifyDamageRollDialogue.Weapon": "Weapon:",
+216
View File
@@ -0,0 +1,216 @@
{
"DG.SystemName": "Delta Green",
"DG.AgentNameFieldTooltip": "APELLIDO, NOMBRE (Y ALIAS SI CORRESPONDE)",
"DG.RollLuck": "Tira Suerte",
"DG.Luck": "Suerte",
"DG.FallbackText.ProfessionAndOrRank": "PROFESION (RANGO SI CORRESPONDE)",
"DG.Skills.accounting": "Contabilidad",
"DG.Skills.alertness": "Alerta",
"DG.Skills.anthropology": "Antropología",
"DG.Skills.archeology": "Arqueología",
"DG.Skills.artillery": "Artillería",
"DG.Skills.athletics": "Atletismo",
"DG.Skills.bureaucracy": "Burocracia",
"DG.Skills.computer_science": "Informatica",
"DG.Skills.criminology": "Criminología",
"DG.Skills.demolitions": "Explosivos",
"DG.Skills.disguise": "Disfrazarse",
"DG.Skills.dodge": "Esquivar",
"DG.Skills.drive": "Conducir",
"DG.Skills.firearms": "Armas de Fuego",
"DG.Skills.first_aid": "Primeros Auxilios",
"DG.Skills.forensics": "Medicina Forense",
"DG.Skills.heavy_machiner": "Maquinaria Pesada",
"DG.Skills.heavy_weapons": "Armas Pesadas",
"DG.Skills.history": "Historia",
"DG.Skills.humint": "HUMINT",
"DG.Skills.law": "Derecho",
"DG.Skills.medicine": "Medicina",
"DG.Skills.melee_weapons": "Armas Cuerpo a Cuerpo",
"DG.Skills.navigate": "Orientarse",
"DG.Skills.occult": "Ocultismo",
"DG.Skills.persuade": "Persuadir",
"DG.Skills.pharmacy": "Farmacología",
"DG.Skills.psychotherapy": "Psicoterapia",
"DG.Skills.ride": "Equitación",
"DG.Skills.search": "Buscar",
"DG.Skills.sigint": "SIGINT",
"DG.Skills.stealth": "Sigilo",
"DG.Skills.surgery": "Cirugia",
"DG.Skills.survival": "Supervivemcia",
"DG.Skills.swim": "Nadar",
"DG.Skills.unarmed_combat": "Combate sin Armas",
"DG.Skills.unnatural": "Antinatural",
"DG.Skills.AddTypedOrCustomSkill": "Añadir Tipo o Habilidad Personalizada",
"DG.Skills.AddSkill": "Añadir Habilidad",
"DG.Skills.SkillGroup": "Habilidad Grupal",
"DG.Skills.SkillName": "Nombre de la Habilidad",
"DG.TypeSkills.Art": "Arte",
"DG.TypeSkills.Craft": "Fabricar",
"DG.TypeSkills.ForeignLanguage": "Lengua Extranjera",
"DG.TypeSkills.MilitaryScience": "Ciencia Militar",
"DG.TypeSkills.Pilot": "Pilotar",
"DG.TypeSkills.Science": "Ciencia",
"DG.TypeSkills.Other": "Otra",
"DG.Attributes.HP": "PV",
"DG.Attributes.WP": "PVOL",
"DG.Attributes.SAN": "COR",
"DG.Attributes.str": "FUE",
"DG.Attributes.con": "CON",
"DG.Attributes.dex": "DES",
"DG.Attributes.int": "INT",
"DG.Attributes.pow": "POD",
"DG.Attributes.cha": "CAR",
"DG.Navigation.Skills": "Habilidades",
"DG.Navigation.Physical": "Físico",
"DG.Navigation.Mental": "Mental",
"DG.Navigation.Gear": "Equipo",
"DG.Navigation.CV": "C.V.",
"DG.Navigation.Contacts": "Contactos",
"DG.About.OnlineHelp": "Documentación del sistema abierto en (EN LÍNEA)",
"DG.About.OnlineHelpTooltip": "Inicie el navegador con la ayuda en línea de GitHub.",
"DG.About.OnlineBugTracker": "Preguntas, informes de errores o solicitudes de funciones (EN LÍNEA)",
"DG.About.OnlineBugTrackerTooltip": "Inicie el navegador con el rastreador de problemas de GitHub. ",
"DG.Roll.Rolling": "Tirando",
"DG.Roll.Target": "Objetivo: ",
"DG.Roll.Success": "Exito",
"DG.Roll.Failure": "Fallo",
"DG.Roll.Critical": "Critico",
"DG.Roll.Lethality": "Letalidad",
"DG.Roll.Lethal": "Letal",
"DG.Roll.For": "Para",
"DG.Roll.Damage": "Daño",
"DG.Roll.RollingDamageFor": "Tirando DAÑO para",
"DG.Roll.Or": "O",
"DG.Roll.Roll": "Tirar",
"DG.Physical.Wounds": "Heridas",
"DG.Physical.FirstAidLabel": "Los Primeros Auxilios Ya Han Sido Aplicados: ",
"DG.Generic.AddButtonLabel": "Añadir",
"DG.Mental.BreakingPoint": "Punto Ruptura: ",
"DG.Mental.Reset": "Borrar",
"DG.Mental.SanityLossIncidentsLabel": "Incidentes o perdida de COR sin Locura",
"DG.Mental.Violence": "Violencia",
"DG.Mental.Helplessness": "Impotencia",
"DG.Mental.AdaptedToViolence": "Adaptado a la Violencia",
"DG.Mental.AdaptedToHelplessness": "Adaptado a la Impotencia",
"DG.Mental.Motivations": "Motivaciones",
"DG.Mental.Disorders": "Desordenes",
"DG.Gear.Weapons": "ARMAS",
"DG.Gear.Armor": "ARMADURA",
"DG.Gear.OtherGear": "OTRO EQUIPO",
"DG.Gear.Name": "Nombre",
"DG.Gear.DamageOrLethality": "Daño/Letalidad",
"DG.Gear.ArmorPiercing": "Perforación de Armadura",
"DG.Gear.ArmorRating": "Clasificación de Armadura",
"DG.Gear.Equipped": "Equipado",
"DG.CV.Sex": "Sexo",
"DG.CV.SexPlaceholder": "Sexo",
"DG.CV.AgeAndDoB": "Edad y F.D.N.",
"DG.CV.AgeAndDoBPlaceholder": "Edad & Fecha de Nacimiento",
"DG.CV.Employer": "Empleador",
"DG.CV.EmployerPlaceholder": "Empleador o Historial laboral",
"DG.CV.Nationality": "Nacionalidad",
"DG.CV.NationalityPlaceholder": "Nacionalidad",
"DG.CV.Education": "Educación",
"DG.CV.EducationPlaceholder": "Educación o Entrenamiento",
"DG.CV.PhysicalDescriptionLabel": "Descripción Física/Notas",
"DG.Bonds.Bond": "Vículo",
"DG.Bonds.Name": "Nombre",
"DG.Bonds.Score": "Puntuación",
"DG.Bonds.NewBond": "Nuevo Vínculo",
"DG.ItemTypes.weapon": "Arma",
"DG.ItemTypes.armor": "Armadura",
"DG.ItemTypes.motivation": "Motivación",
"DG.ItemTypes.bond": "Vínculo",
"DG.ItemTypes.gear": "Equipo",
"DG.ItemTypes.NewPrefix": "Nuevo ",
"DG.Tooltip.HP": "Puntos de Vida, un personaje cae inconsciente a los 2 PV, y muere con 0 PV.",
"DG.Tooltip.MaximumHP": "La salud máxima es el promedio de FUE + CON, redondeado hacia arriba.",
"DG.Tooltip.WP": "Los Puntos de Voluntad son el combustible mental. Los agentes requieren puntos de voluntad para seguir adelante a pesar del agotamiento o situaciones mentalmente graves. Consulte la página 47 del Manual del Agente para obtener más detalles.",
"DG.Tooltip.MaximumWP": "Los Ptos Voluntad máximos son iguales al POD.",
"DG.Tooltip.SanityLabel": "Click para hacer una tirada de Cordura...",
"DG.Tooltip.CurrentSanityPartOne": "Cordura actual, punto de ruptura actual es ",
"DG.Tooltip.CurrentSanityPartTwo": ", haga clic en la etiqueta COR anterior para realizar una tirada de de cordura.",
"DG.Tooltip.MaximumSanity": "La cordura máxima es igual a 99 - la habilidad Antinatural.",
"DG.Tooltip.SkillLabel": "Click para hacer una tirada de habilidad.",
"DG.Tooltip.CannotRollSkillLabel": "No se puede usar una habilidad al 0%. Consulte la página 28 del Manual del Agente.",
"DG.Tooltip.SkillFailCheckbox": "Después de fallar una prueba sobre esta habilidad (si el dominio es de al menos 1%), marque esta casilla. Al final de la sesión, agregue puntos porcentuales 1D4-1 a la habilidad y desmarque la casilla. No se aplica a la habilidad Antinatural. Consulte la página 29 del Manual del Agente.",
"DG.Tooltip.DistinguishingFeature": "Característica Distintiva (rellene si la puntuación es 12 o superior, u 8 o inferior).",
"DG.Tooltip.x5AttributeLabel": "Click para una tirada x5.",
"DG.Tooltip.FirstAidAttempted": "Una vez que un agente recibe primeros auxilios, no puede beneficiarse de él de nuevo hasta que reciba más daños de una fuente diferente.",
"DG.Tooltip.AdaptedToViolence": "Adaptarse a la violencia significa que la empatía de su agente sufre al ser testigo de tanta violencia. Pierde permanentemente 1D6 CAR y la misma cantidad de cada uno de sus vínculos.",
"DG.Tooltip.AdaptedToHelplessness": "Estar adaptado a la impotencia significa que el impulso personal de su Agente sufre cuando se aleja del mundo que lo rodea. Tan pronto como su Agente se adapte a la indefensión, perderá permanentemente 1D6 POD. ",
"DG.Tooltip.ToggleEquippedState": "Haga clic para alternar si este artículo está equipado o no. ",
"DG.Gear.Expense.Incidental": "Incidental",
"DG.Gear.Expense.Standard": "Estándar",
"DG.Gear.Expense.Unusual": "Inusual",
"DG.Gear.Expense.Major": "Destacado",
"DG.Gear.Expense.Extreme": "Extremo",
"DG.ItemWindow.Bonds.Description": "Descripción / Desarrollos ",
"DG.ItemWindow.Bonds.ScoreTooltip": "Una puntuación más alta representa una relación más fuerte entre el agente y el vínculo. ",
"DG.ItemWindow.Motivations.Attributes": "Atributos",
"DG.ItemWindow.Motivations.Motivation": "Motivación",
"DG.ItemWindow.Motivations.Description": "Descripción / Notas",
"DG.ItemWindow.Motivations.Disorder": "Trastorno",
"DG.ItemWindow.Motivations.IsDisorder": "Es Trastorno",
"DG.ItemWindow.Motivations.MotivationNameTooltip": "Algo que impulsa al personaje. ",
"DG.ItemWindow.Motivations.DisorderNameTooltip": "Un trastorno reemplaza una motivación después de llegar al punto de ruptura.",
"DG.ItemWindow.Motivations.IsDisorderTooltip": "Marque esta opción si agrega un trastorno o si se ha perdido una motivación existente debido a la adquisición de un trastorno.",
"DG.ItemWindow.Motivations.DisorderHasBeenCured": "El trastorno ha sido \"curado \" ",
"DG.ItemWindow.Motivations.DisorderHasBeenCuredTooltip": "Un éxito crítico en una tirada de suerte terapéutica puede curar un trastorno. Sin embargo, puede regresar la próxima vez que se alcance un punto de ruptura. ",
"DG.ItemWindow.Gear.Attributes": "Atributos",
"DG.ItemWindow.Gear.Description": "Descripción",
"DG.ItemWindow.Gear.NamePlaceholder": "Nombre",
"DG.ItemWindow.Gear.Expense": "Gasto",
"DG.ItemWindow.Gear.Equipped": "Equipado",
"DG.ItemWindow.Armor.Description": "Descripción",
"DG.ItemWindow.Armor.NamePlaceholder": "Nombre",
"DG.ItemWindow.Armor.ArmorRating": "Tasa Armadura",
"DG.ItemWindow.Armor.Expense": "Gasto",
"DG.ItemWindow.Armor.Equipped": "Equipado",
"DG.ItemWindow.Weapons.Description": "Descripción",
"DG.ItemWindow.Weapons.NamePlaceholder": "Nombre",
"DG.ItemWindow.Weapons.Skill": "Habilidad",
"DG.ItemWindow.Weapons.Expense": "Gasto",
"DG.ItemWindow.Weapons.Damage": "Daño",
"DG.ItemWindow.Weapons.Lethality": "Letalidad",
"DG.ItemWindow.Weapons.IsLethality": "Es Letal",
"DG.ItemWindow.Weapons.LethalityTooltip": "Un arma letal tiene la oportunidad de matar instantáneamente a un objetivo. Tira 1D100 en lugar de un dado de daño. Si no es letal, el daño se calcula en su lugar tirando 2d10, donde un '00' en el primer d10 es igual a 10.",
"DG.ItemWindow.Weapons.IsLethalityTooltip": "Marca si el arma tiene un % de letalidad asociada.",
"DG.ItemWindow.Weapons.ArmorPiercing": "Perforación de armaduras",
"DG.ItemWindow.Weapons.Ammo": "Munición (Cantidad/Tipo)",
"DG.ItemWindow.Weapons.Range": "Alcance",
"DG.ItemWindow.Weapons.KillRadius": "Radio de muerte",
"DG.ModifySkillRollDialogue.Title": "Modificar Tirada",
"DG.ModifySkillRollDialogue.Test": "Test:",
"DG.ModifySkillRollDialogue.OriginalTarget": "Objetivo Original:",
"DG.ModifySkillRollDialogue.TargetModifier": "Modificar Objetivo (+/-):",
"DG.ModifySkillRollDialogue.ModifierTooltip": "Dar un modificador positivo o negativo aquí para sumar o restar al objetivo en la chequeo de habilidades.",
"DG.ModifyDamageRollDialogue.Weapon": "Arma:",
"DG.ModifyDamageRollDialogue.OuterModifierTooltip": "Utilice este campo para modificar la fórmula, como duplicar el resultado.",
"DG.ModifyDamageRollDialogue.InnerModifierTooltip": "Utilice este campo para añadir un modificador como '+1' u otro término como '+1d4'."
}
+1 -1
View File
@@ -207,7 +207,7 @@
"DG.ModifySkillRollDialogue.Title": "ロールの変更",
"DG.ModifySkillRollDialogue.Test": "テスト:",
"DG.ModifySkillRollDialogue.OriginalTarget": "元のターゲット:",
"DG.ModifySkillRollDialogue.TargetModifier": "変換:",
"DG.ModifySkillRollDialogue.TargetModifier": "変換(+/-):",
"DG.ModifySkillRollDialogue.ModifierTooltip": "スキルチェックのターゲットに加算/減算します。",
"DG.ModifyDamageRollDialogue.Weapon": "武器:",
+46 -15
View File
@@ -79,12 +79,14 @@ export class DeltaGreenActorSheet extends ActorSheet {
// Can add extra buttons to form header here if necessary
_getHeaderButtons(){
let buttons = super._getHeaderButtons();
let label = "";
let label = "Roll Luck";
let label2 = "Luck";
try{
label = game.i18n.translations.DG.RollLuck;
label2 = game.i18n.translations.DG.Luck;
}
catch{
label = "Roll Luck"
ui.notifications.warn('Missing translation key for either DG.RollLuck or DG.Luck key.')
}
buttons = [
@@ -92,7 +94,7 @@ export class DeltaGreenActorSheet extends ActorSheet {
label: label,
class: "test-extra-icon",
icon: "fas fa-dice",
onclick: (ev) => sendPercentileTestToChat(this.actor, "Luck", 50)
onclick: (ev) => sendPercentileTestToChat(this.actor, label2, 50)
}].concat(buttons);
//buttons = [
@@ -161,7 +163,7 @@ export class DeltaGreenActorSheet extends ActorSheet {
// Drag events for macros.
if (this.actor.owner) {
let handler = ev => this._onDragItemStart(ev);
let handler = ev => this._onDragStart(ev);
html.find('li.item').each((i, li) => {
if (li.classList.contains("inventory-header")) return;
li.setAttribute("draggable", true);
@@ -203,29 +205,29 @@ export class DeltaGreenActorSheet extends ActorSheet {
let htmlContent = "";
htmlContent += `<div>`;
htmlContent += ` <label>${game.i18n.translations.DG.Skills.SkillGroup}:</label>`;
htmlContent += ` <label>${game.i18n.translations.DG?.Skills?.SkillGroup ?? "Skill Group"}:</label>`;
htmlContent += ` <select name="new-type-skill-group" />`;
htmlContent += ` <option>${game.i18n.translations.DG.TypeSkills.Art}</option>`;
htmlContent += ` <option>${game.i18n.translations.DG.TypeSkills.Craft}</option>`;
htmlContent += ` <option>${game.i18n.translations.DG.TypeSkills.ForeignLanguage}</option>`;
htmlContent += ` <option>${game.i18n.translations.DG.TypeSkills.MilitaryScience}</option>`;
htmlContent += ` <option>${game.i18n.translations.DG.TypeSkills.Pilot}</option>`;
htmlContent += ` <option>${game.i18n.translations.DG.TypeSkills.Science}</option>`;
htmlContent += ` <option>${game.i18n.translations.DG.TypeSkills.Other}</option>`;
htmlContent += ` <option>${game.i18n.translations.DG?.TypeSkills?.Art ?? "Art"}</option>`;
htmlContent += ` <option>${game.i18n.translations.DG?.TypeSkills?.Craft ?? "Craft"}</option>`;
htmlContent += ` <option>${game.i18n.translations.DG?.TypeSkills?.ForeignLanguage ?? "Foreign Language"}</option>`;
htmlContent += ` <option>${game.i18n.translations.DG?.TypeSkills?.MilitaryScience ?? "Military Science"}</option>`;
htmlContent += ` <option>${game.i18n.translations.DG?.TypeSkills?.Pilot ?? "Pilot"}</option>`;
htmlContent += ` <option>${game.i18n.translations.DG?.TypeSkills?.Science ?? "Science"}</option>`;
htmlContent += ` <option>${game.i18n.translations.DG?.TypeSkills?.Other ?? "Other"}</option>`;
htmlContent += ` </select>`;
htmlContent += `</div>`;
htmlContent += `<div>`;
htmlContent += ` <label>${game.i18n.translations.DG.Skills.SkillName}</label>`;
htmlContent += ` <label>${game.i18n.translations.DG?.Skills.SkillName ?? "Skill Name"}</label>`;
htmlContent += ` <input type="text" name="new-type-skill-label" />`;
htmlContent += `</div>`;
new Dialog({
content: htmlContent,
title: game.i18n.translations.DG.Skills.AddTypedOrCustomSkill,
title: game.i18n.translations.DG?.Skills?.AddTypedOrCustomSkill ?? "Add Typed or Custom Skill",
buttons: {
add:{
label: game.i18n.translations.DG.Skills.AddSkill,
label: game.i18n.translations.DG?.Skills?.AddSkill ?? "Add Skill",
callback: btn =>{
let newTypeSkillLabel = btn.find("[name='new-type-skill-label']").val();
let newTypeSkillGroup = btn.find("[name='new-type-skill-group']").val();
@@ -405,4 +407,33 @@ export class DeltaGreenActorSheet extends ActorSheet {
console.log(ex);
}
}
_onDragStart(event) {
const li = event.currentTarget;
if ( event.target.classList.contains("entity-link") ) return;
// Create drag data
const dragData = {
actorId: this.actor.id,
sceneId: this.actor.isToken ? canvas.scene?.id : null,
tokenId: this.actor.isToken ? this.actor.token.id : null
};
// Owned Items
if ( li.dataset.itemId ) {
const item = this.actor.items.get(li.dataset.itemId);
dragData.type = "Item";
dragData.data = item.data;
}
// Active Effect
if ( li.dataset.effectId ) {
const effect = this.actor.effects.get(li.dataset.effectId);
dragData.type = "ActiveEffect";
dragData.data = effect.data;
}
// Set data transfer
event.dataTransfer.setData("text/plain", JSON.stringify(dragData));
}
}
+57 -1
View File
@@ -3,6 +3,7 @@ import { DeltaGreenActor } from "./actor/actor.js";
import { DeltaGreenActorSheet } from "./actor/actor-sheet.js";
import { DeltaGreenItem } from "./item/item.js";
import { DeltaGreenItemSheet } from "./item/item-sheet.js";
import { sendPercentileTestToChat, sendLethalityTestToChat, sendDamageRollToChat } from "./roll/roll.js";
import { preloadHandlebarsTemplates } from "./templates.js";
@@ -11,7 +12,9 @@ Hooks.once('init', async function() {
game.deltagreen = {
DeltaGreenActor,
DeltaGreenItem,
rollItemMacro
rollItemMacro,
rollItemSkillCheckMacro,
rollSkillMacro
};
/**
@@ -153,9 +156,62 @@ function rollItemMacro(itemName) {
let actor;
if (speaker.token) actor = game.actors.tokens[speaker.token];
if (!actor) actor = game.actors.get(speaker.actor);
if(!actor) return ui.notifications.warn('Must have an Actor selected first.');
const item = actor ? actor.items.find(i => i.name === itemName) : null;
if (!item) return ui.notifications.warn(`Your controlled Actor does not have an item named ${itemName}`);
// Trigger the item roll
return item.roll();
}
function rollItemSkillCheckMacro(itemName) {
const speaker = ChatMessage.getSpeaker();
let actor;
if (speaker.token) actor = game.actors.tokens[speaker.token];
if (!actor) actor = game.actors.get(speaker.actor);
if(!actor) return ui.notifications.warn('Must have an Actor selected first.');
const item = actor ? actor.items.find(i => i.name === itemName) : null;
if (!item) return ui.notifications.warn(`Your controlled Actor does not have an item named ${itemName}`);
let skillName = item.data.data.skill.toString();
let skill = actor.data.data.skills[skillName];
let translatedSkillLabel = "";
try{
translatedSkillLabel = game.i18n.localize("DG.Skills." + skillName)
}
catch{
translatedSkillLabel = skillName;
}
sendPercentileTestToChat(actor, translatedSkillLabel, skill.proficiency);
}
function rollSkillMacro(skillName) {
const speaker = ChatMessage.getSpeaker();
let actor;
if (speaker.token) actor = game.actors.tokens[speaker.token];
if (!actor) actor = game.actors.get(speaker.actor);
if(!actor) return ui.notifications.warn('Must have an Actor selected first.');
let skill = actor.data.data.skills[skillName];
if(!skill) return ui.notifications.warn('Bad skill name passed to macro.');
let translatedSkillLabel = "";
try{
translatedSkillLabel = game.i18n.localize("DG.Skills." + skillName)
}
catch{
translatedSkillLabel = skillName;
}
sendPercentileTestToChat(actor, translatedSkillLabel, skill.proficiency);
}
+247 -220
View File
@@ -27,174 +27,155 @@ export function sendPercentileTestToChat(actor, skill, target, inhuman_flag=fals
}
}
if(isCritical){
resultString = `${game.i18n.localize("DG.Roll.Critical")} `;
}
if(isSuccess){
resultString += `${game.i18n.localize("DG.Roll.Success")}`;
if(isCritical){
resultString = `${game.i18n.localize("DG.Roll.Critical")} `;
resultString = resultString.toUpperCase() + '!';
styleOverride="color: green";
}
if(isSuccess){
resultString += `${game.i18n.localize("DG.Roll.Success")}`;
if(isCritical){
resultString = resultString.toUpperCase() + '!';
styleOverride="color: green";
}
}
else{
resultString += `${game.i18n.localize("DG.Roll.Failure")}`;
if(isCritical){
resultString = resultString.toUpperCase() + '!';
styleOverride="color: red";
}
}
html = `<div class="dice-roll">`
html += ` <div class="dice-result">`
html += ` <div style="${styleOverride}" class="dice-formula">${resultString}</div>`
html += ` <div class="dice-tooltip">`
html += ` <section class="tooltip-part">`
html += ` <div class="dice">`
html += ` <p class="part-formula">`
html += ` ${roll.formula}`
html += ` <span class="part-total">${roll.total}</span>`
html += ` </p>`
html += ` <ol class="dice-rolls">`
html += ` <li class="roll die ${roll.formula}">${roll.total}</li>`
html += ` </ol>`
html += ` </div>`
html += ` </section>`
html += ` </div>`
html += ` <h4 class="dice-total">${roll.total}</h4>`
html += `</div>`
let chatData = {
speaker: ChatMessage.getSpeaker({actor: actor}),
content: html,
flavor: label,
type: CHAT_MESSAGE_TYPES.ROLL,
roll: roll,
rollMode: game.settings.get("core", "rollMode")
};
// play the dice rolling sound, like a regular in-chat roll
AudioHelper.play({src: "sounds/dice.wav", volume: 0.8, autoplay: true, loop: false}, true);
ChatMessage.create(chatData, {});
}
else{
resultString += `${game.i18n.localize("DG.Roll.Failure")}`;
export function skillCheckResultIsCritical(rollResult){
let isCritical = false;
if(rollResult === 1 || rollResult === 100){
// really good, or reeaaaally bad
isCritical = true;
}
else if(rollResult % 11 === 0){
// any matching dice are a crit, i.e. 11, 22, 33...99.
isCritical = true;
}
return isCritical;
}
export function sendLethalityTestToChat(actor, weaponName, target){
let roll = new Roll('1D100', actor.data.data).roll();
let isCritical = false;
let skillCheckTotal = roll.total;
// page 57 of agent's handbook
// For a failed lethality check, the damage on the tens die is a 10 for a roll of '0'. E.g. '30' + '0' = 13 damage.
// Lethality rolls do not fumble or critically succeed, but the attack roll can.
// In this situation, the lethality threshold doubles (e.g. 20% would become 40%),
// and if the lethality roll fails, the damage is doubled per normal. However right now
// the attack roll and damage roll are completely separate... Perhaps in the future, use a
// button in the skill check roll to allow doubling this logic?
// try to determine what the d100 result would be as if it was two d10's being rolled
let damageDie1 = Math.floor(skillCheckTotal / 10);
let damageDie2 = skillCheckTotal - (damageDie1 * 10);
if(damageDie2 === 0){
// if the result is evenly divisible by 10 (e.g. 30, 40, 50...)
// then the percentile die result was actually one lower than the calculation above would show.
// For example, a '70' is actually a 60 + 10, so the damage die should be 6 + 10 = 16, not 7 + 0 = 7.
damageDie1 -= 1;
damageDie2 = 10;
}
let damageDie1Label = damageDie1.toString();
let damageDie2Label = damageDie2.toString();
if(damageDie1 === 0){
// a roll of 00 on the tens part of the d100 counts as a ten if it becomes a damage die
// Will leave the labeling as a '0' though, to be consistent with a regular d10 roll
damageDie1 = 10;
}
if(damageDie2 === 10){
// keep the labelling consistent, show a '0' for a ten
damageDie2Label = '0';
}
let nonlethalDamage = damageDie1 + damageDie2;
let isLethal = false;
let html = '';
let label = `${game.i18n.localize("DG.Roll.Rolling")} ${game.i18n.localize("DG.Roll.Lethality").toUpperCase()} ${game.i18n.localize("DG.Roll.For")} ${weaponName.toUpperCase()} ${game.i18n.localize("DG.Roll.Target")} ${target}`;
let resultString = '';
let styleOverride = '';
if(skillCheckTotal <= target){
isLethal = true;
resultString = `${game.i18n.localize("DG.Roll.Lethal").toUpperCase()}`;
if(isCritical){
resultString = resultString.toUpperCase() + '!';
styleOverride="color: red";
}
else{
resultString = `${game.i18n.localize("DG.Roll.Failure")}`;
}
html = `<div class="dice-roll">`;
html += ` <div class="dice-result">`;
html += ` <div style="${styleOverride}" class="dice-formula">${resultString}</div>`;
html += ` <div class="dice-tooltip">`;
html += ` <section class="tooltip-part">`;
html += ` <div class="dice">`;
html += ` <p class="part-formula">`;
html += ` d100 ${game.i18n.localize("DG.Roll.Or").toUpperCase()} d10 + d10`;
html += ` <span class="part-total">${roll.total}</span>`;
html += ` </p>`;
html += ` <ol class="dice-rolls">`;
html += ` <li class="roll die d10">${damageDie1Label}</li>`;
html += ` <li class="roll die d10">${damageDie2Label}</li>`;
html += ` </ol>`;
html += ` </div>`;
html += ` </section>`;
html += ` </div>`;
html += ` <h4 class="dice-total">${roll.total} (${nonlethalDamage} ${game.i18n.localize("DG.Roll.Damage")})</h4>`;
html += `</div>`;
let chatData = {
speaker: ChatMessage.getSpeaker({actor: actor}),
content: html,
flavor: label,
type: CHAT_MESSAGE_TYPES.ROLL,
roll: roll,
rollMode: game.settings.get("core", "rollMode")
};
// play the dice rolling sound, like a regular in-chat roll
AudioHelper.play({src: "sounds/dice.wav", volume: 0.8, autoplay: true, loop: false}, true);
ChatMessage.create(chatData, {});
}
export function sendDamageRollToChat(actor, label, diceFormula){
let roll = new Roll(diceFormula, actor.data.data);
html = `<div class="dice-roll">`
html += ` <div class="dice-result">`
html += ` <div style="${styleOverride}" class="dice-formula">${resultString}</div>`
html += ` <div class="dice-tooltip">`
html += ` <section class="tooltip-part">`
html += ` <div class="dice">`
html += ` <p class="part-formula">`
html += ` ${roll.formula}`
html += ` <span class="part-total">${roll.total}</span>`
html += ` </p>`
html += ` <ol class="dice-rolls">`
html += ` <li class="roll die ${roll.formula}">${roll.total}</li>`
html += ` </ol>`
html += ` </div>`
html += ` </section>`
html += ` </div>`
html += ` <h4 class="dice-total">${roll.total}</h4>`
html += `</div>`
label = `${game.i18n.localize("DG.Roll.RollingDamageFor")} ${label.toUpperCase()}`;
let chatData = {
speaker: ChatMessage.getSpeaker({actor: actor}),
content: html,
flavor: label,
type: CHAT_MESSAGE_TYPES.ROLL,
roll: roll,
rollMode: game.settings.get("core", "rollMode")
};
roll.roll().toMessage({
speaker: ChatMessage.getSpeaker({ actor: actor }),
// play the dice rolling sound, like a regular in-chat roll
AudioHelper.play({src: "sounds/dice.wav", volume: 0.8, autoplay: true, loop: false}, true);
ChatMessage.create(chatData, {});
}
export function skillCheckResultIsCritical(rollResult){
let isCritical = false;
if(rollResult === 1 || rollResult === 100){
// really good, or reeaaaally bad
isCritical = true;
}
else if(rollResult % 11 === 0){
// any matching dice are a crit, i.e. 11, 22, 33...99.
isCritical = true;
}
return isCritical;
}
export function sendLethalityTestToChat(actor, weaponName, target){
let roll = new Roll('1D100', actor.data.data).roll();
let isCritical = false;
let skillCheckTotal = roll.total;
// page 57 of agent's handbook
// For a failed lethality check, the damage on the tens die is a 10 for a roll of '0'. E.g. '30' + '0' = 13 damage.
// Lethality rolls do not fumble or critically succeed, but the attack roll can.
// In this situation, the lethality threshold doubles (e.g. 20% would become 40%),
// and if the lethality roll fails, the damage is doubled per normal. However right now
// the attack roll and damage roll are completely separate... Perhaps in the future, use a
// button in the skill check roll to allow doubling this logic?
// try to determine what the d100 result would be as if it was two d10's being rolled
let damageDie1 = Math.floor(skillCheckTotal / 10);
let damageDie2 = skillCheckTotal - (damageDie1 * 10);
if(damageDie2 === 0){
// if the result is evenly divisible by 10 (e.g. 30, 40, 50...)
// then the percentile die result was actually one lower than the calculation above would show.
// For example, a '70' is actually a 60 + 10, so the damage die should be 6 + 10 = 16, not 7 + 0 = 7.
damageDie1 -= 1;
damageDie2 = 10;
}
let damageDie1Label = damageDie1.toString();
let damageDie2Label = damageDie2.toString();
if(damageDie1 === 0){
// a roll of 00 on the tens part of the d100 counts as a ten if it becomes a damage die
// Will leave the labeling as a '0' though, to be consistent with a regular d10 roll
damageDie1 = 10;
}
if(damageDie2 === 10){
// keep the labelling consistent, show a '0' for a ten
damageDie2Label = '0';
}
let nonlethalDamage = damageDie1 + damageDie2;
let isLethal = false;
let html = '';
let label = `${game.i18n.localize("DG.Roll.Rolling")} <b>${game.i18n.localize("DG.Roll.Lethality").toUpperCase()}</b> ${game.i18n.localize("DG.Roll.For")} <b>${weaponName.toUpperCase()}</b> ${game.i18n.localize("DG.Roll.Target")} ${target}`;
let resultString = '';
let styleOverride = '';
if(skillCheckTotal <= target){
isLethal = true;
resultString = `${game.i18n.localize("DG.Roll.Lethal").toUpperCase()}`;
styleOverride="color: red";
}
else{
resultString = `${game.i18n.localize("DG.Roll.Failure")}`;
}
html = `<div class="dice-roll">`;
html += ` <div class="dice-result">`;
html += ` <div style="${styleOverride}" class="dice-formula">${resultString}</div>`;
html += ` <div class="dice-tooltip">`;
html += ` <section class="tooltip-part">`;
html += ` <div class="dice">`;
html += ` <p class="part-formula">`;
html += ` d100 ${game.i18n.localize("DG.Roll.Or").toUpperCase()} d10 + d10`;
html += ` <span class="part-total">${roll.total}</span>`;
html += ` </p>`;
html += ` <ol class="dice-rolls">`;
html += ` <li class="roll die d10">${damageDie1Label}</li>`;
html += ` <li class="roll die d10">${damageDie2Label}</li>`;
html += ` </ol>`;
html += ` </div>`;
html += ` </section>`;
html += ` </div>`;
html += ` <h4 class="dice-total">${roll.total} (${nonlethalDamage} ${game.i18n.localize("DG.Roll.Damage")})</h4>`;
html += `</div>`;
let chatData = {
speaker: ChatMessage.getSpeaker({actor: actor}),
content: html,
flavor: label,
type: CHAT_MESSAGE_TYPES.ROLL,
roll: roll,
@@ -212,21 +193,61 @@ export function sendPercentileTestToChat(actor, skill, target, inhuman_flag=fals
targetModifier: 20
},
};
let html = await renderTemplate(template, backingData);
new Dialog({
content: html,
title: game.i18n.localize("DG.ModifySkillRollDialogue.Title"),
default: "roll",
buttons: {
roll:{
label: game.i18n.translations.DG.Roll.Roll,
// play the dice rolling sound, like a regular in-chat roll
AudioHelper.play({src: "sounds/dice.wav", volume: 0.8, autoplay: true, loop: false}, true);
callback: html => {
try{
let targetModifier = html.find("[name='targetModifier']").val(); // this is text as a heads up
ChatMessage.create(chatData, {});
}
export function sendDamageRollToChat(actor, label, diceFormula){
let roll = new Roll(diceFormula, actor.data.data);
try{
label = `${game.i18n.localize("DG.Roll.Rolling")} <b>${game.i18n.localize("DG.Roll.Damage").toUpperCase()}</b> ${game.i18n.localize("DG.Roll.For")} <b>${label.toUpperCase()}</b>`;
}
catch{
label = `Rolling <b>DAMAGE</b> for <b>${label.toUpperCase()}</b>`
}
roll.roll().toMessage({
speaker: ChatMessage.getSpeaker({ actor: actor }),
flavor: label,
type: CHAT_MESSAGE_TYPES.ROLL,
roll: roll,
rollMode: game.settings.get("core", "rollMode")
});
}
export async function showModifyPercentileTestDialogue(actor, label, originalTarget, isLethalityTest){
let template = "systems/deltagreen/templates/dialog/modify-percentile-roll.html";
let backingData = {
data:{
label: label,
originalTarget: originalTarget,
targetModifier: 20
},
};
let html = await renderTemplate(template, backingData);
new Dialog({
content: html,
title: game.i18n.localize("DG.ModifySkillRollDialogue.Title"),
default: "roll",
buttons: {
roll:{
label: game.i18n.translations.DG.Roll.Roll,
callback: html => {
try{
let targetModifier = html.find("[name='targetModifier']").val(); // this is text as a heads up
let newTarget = parseInt(originalTarget); // this should be an int, but technically the incoming value is text, so parse it just to be safe
if(targetModifier.trim() != "" && !isNaN(targetModifier)){
newTarget += parseInt(targetModifier);
}
let newTarget = parseInt(originalTarget); // this should be an int, but technically the incoming value is text, so parse it just to be safe
if(targetModifier.trim() != "" && !isNaN(targetModifier)){
newTarget += parseInt(targetModifier);
@@ -238,65 +259,71 @@ export function sendPercentileTestToChat(actor, skill, target, inhuman_flag=fals
else{
sendPercentileTestToChat(actor, label, newTarget,inhuman_flag); //take care of inhuman stat, by default the value is false
}
if(isLethalityTest){
sendLethalityTestToChat(actor, label, newTarget);
}
catch(ex){
console.log(ex);
else{
sendPercentileTestToChat(actor, label, newTarget);
}
}
catch(ex){
console.log(ex);
}
}
}
}
).render(true);
}
}
}
).render(true);
}
export async function showModifyDamageRollDialogue(actor, label, originalFormula){
let template = "systems/deltagreen/templates/dialog/modify-damage-roll.html";
let backingData = {
data:{
label: label,
originalFormula: originalFormula,
outerModifier: "2 * ",
innerModifier: "+ 0"
},
};
let html = await renderTemplate(template, backingData);
export async function showModifyDamageRollDialogue(actor, label, originalFormula){
let template = "systems/deltagreen/templates/dialog/modify-damage-roll.html";
let backingData = {
data:{
label: label,
originalFormula: originalFormula,
outerModifier: "2 * ",
innerModifier: "+ 0"
},
};
let html = await renderTemplate(template, backingData);
new Dialog({
content: html,
title: game.i18n.localize("DG.ModifySkillRollDialogue.Title"),
default: "roll",
buttons: {
roll:{
label: game.i18n.translations.DG.Roll.Roll,
new Dialog({
content: html,
title: game.i18n.localize("DG.ModifySkillRollDialogue.Title"),
default: "roll",
buttons: {
roll:{
label: game.i18n.translations.DG.Roll.Roll,
callback: html => {
try{
let outerModifier = html.find("[name='outerModifier']").val(); // this is text as a heads up
let innerModifier = html.find("[name='innerModifier']").val(); // this is text as a heads up
let modifiedBaseRoll = html.find("[name='originalFormula']").val(); // this is text as a heads up
if(innerModifier.replace(" ", "") === "+0"){
innerModifier = "";
}
let newRoll = "";
if(outerModifier.trim() != ""){
newRoll += outerModifier + "(" + modifiedBaseRoll + innerModifier.trim() + ")";
}
else{
newRoll += modifiedBaseRoll + innerModifier.trim();
}
sendDamageRollToChat(actor, label, newRoll);
callback: html => {
try{
let outerModifier = html.find("[name='outerModifier']").val(); // this is text as a heads up
let innerModifier = html.find("[name='innerModifier']").val(); // this is text as a heads up
let modifiedBaseRoll = html.find("[name='originalFormula']").val(); // this is text as a heads up
if(innerModifier.replace(" ", "") === "+0"){
innerModifier = "";
}
catch(ex){
console.log(ex);
let newRoll = "";
if(outerModifier.trim() != ""){
newRoll += outerModifier + "(" + modifiedBaseRoll + innerModifier.trim() + ")";
}
else{
newRoll += modifiedBaseRoll + innerModifier.trim();
}
sendDamageRollToChat(actor, label, newRoll);
}
catch(ex){
console.log(ex);
}
}
}
}
).render(true);
}
}
}
).render(true);
}
+5
View File
@@ -46,6 +46,11 @@
"lang": "ja",
"name": "日本語",
"path": "lang/ja.json"
},
{
"lang": "es",
"name": "Español",
"path": "lang/es.json"
}
],
"gridDistance": 1,
+2 -2
View File
@@ -262,8 +262,8 @@
data-roll="d100"
data-rolltype="skill"
data-target="{{getActorSkillProp ../data item.data.skill 'proficiency'}}"
data-label="{{getActorSkillProp ../data item.data.skill 'label'}}"
title="Click to roll {{getActorSkillProp ../data item.data.skill 'label'}}"
data-label="{{localize (concat 'DG.Skills.' item.data.skill)}}"
title="{{localize 'DG.Tooltip.SkillLabel'}} ({{localize (concat 'DG.Skills.' item.data.skill)}})"
>
{{item.name}}
</h4>