ENH: Chargen
							parent
							
								
									0ea0e25fba
								
							
						
					
					
						commit
						197d88eeb3
					
				
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 259 KiB After Width: | Height: | Size: 232 KiB | 
|  | @ -110,11 +110,6 @@ | ||||||
|               wether your monster has a survival instinct or will fight till the |               wether your monster has a survival instinct or will fight till the | ||||||
|               end. |               end. | ||||||
|             </li> |             </li> | ||||||
|             <li><strong>Variable weapon damage</strong>:By default, even if the |  | ||||||
|               damage field is shown in the weapons sheets, the rolled damage |  | ||||||
|               will always be a d6, except for monsters. With this enabled, the |  | ||||||
|               damage displayed will be effectively used for characters. |  | ||||||
|             </li> |  | ||||||
|             <li><strong>Encumbrance</strong>:The weight a character is carrying |             <li><strong>Encumbrance</strong>:The weight a character is carrying | ||||||
|               is a significant part of the players treasure hunting adventures. |               is a significant part of the players treasure hunting adventures. | ||||||
|               You have three options here. |               You have three options here. | ||||||
|  | @ -493,7 +488,7 @@ | ||||||
|               <img src="./images/treasure-toggle.png" /> |               <img src="./images/treasure-toggle.png" /> | ||||||
|             </p> |             </p> | ||||||
|             <p> |             <p> | ||||||
|               You can toggle between the default rollable tables and the treasure table. |               You can toggle between the default rollable tables and the treasure table with the Chest icon right next to the table name. | ||||||
|               The default tables are selecting an entry by rolling a dice and returning the matching result. Treasure tables however, have a different behavior. Each entry is rolled with 1d100 and the value is compared to the 'chance field'. So it can return multiple items. |               The default tables are selecting an entry by rolling a dice and returning the matching result. Treasure tables however, have a different behavior. Each entry is rolled with 1d100 and the value is compared to the 'chance field'. So it can return multiple items. | ||||||
|             </p> |             </p> | ||||||
|             <p> |             <p> | ||||||
|  |  | ||||||
|  | @ -15,7 +15,9 @@ | ||||||
|   "OSE.dialog.partysheet": "Party Overview", |   "OSE.dialog.partysheet": "Party Overview", | ||||||
|   "OSE.dialog.selectActors": "Select PCs", |   "OSE.dialog.selectActors": "Select PCs", | ||||||
|   "OSE.dialog.dealXP": "Deal XP", |   "OSE.dialog.dealXP": "Deal XP", | ||||||
|  |   "OSE.dialog.generator": "Character generator", | ||||||
|   "OSE.dialog.generateSaves": "Generate Saves", |   "OSE.dialog.generateSaves": "Generate Saves", | ||||||
|  |   "OSE.dialog.generateScore": "Rolling {score}", | ||||||
| 
 | 
 | ||||||
|   "OSE.Formula": "Formula", |   "OSE.Formula": "Formula", | ||||||
|   "OSE.SitMod": "Situational Modifier", |   "OSE.SitMod": "Situational Modifier", | ||||||
|  | @ -162,8 +164,6 @@ | ||||||
|   "OSE.Setting.AscendingACHint": "The more the better", |   "OSE.Setting.AscendingACHint": "The more the better", | ||||||
|   "OSE.Setting.Morale": "Enable monsters Morale Rating", |   "OSE.Setting.Morale": "Enable monsters Morale Rating", | ||||||
|   "OSE.Setting.MoraleHint": "Morale Rating is shown on monster sheets", |   "OSE.Setting.MoraleHint": "Morale Rating is shown on monster sheets", | ||||||
|   "OSE.Setting.VariableWeaponDamage": "Variable Weapon Damage", |  | ||||||
|   "OSE.Setting.VariableWeaponDamageHint": "Weapons have different damage dice", |  | ||||||
|   "OSE.Setting.Encumbrance": "Encumbrance", |   "OSE.Setting.Encumbrance": "Encumbrance", | ||||||
|   "OSE.Setting.EncumbranceHint": "Choose the way encumbrance is calculated", |   "OSE.Setting.EncumbranceHint": "Choose the way encumbrance is calculated", | ||||||
|   "OSE.Setting.EncumbranceDisabled": "Disabled", |   "OSE.Setting.EncumbranceDisabled": "Disabled", | ||||||
|  |  | ||||||
|  | @ -147,8 +147,6 @@ | ||||||
|   "OSE.Setting.AscendingACHint": "En cuanto más mejor", |   "OSE.Setting.AscendingACHint": "En cuanto más mejor", | ||||||
|   "OSE.Setting.Morale": "Activar puntuación de Moral para monstruos", |   "OSE.Setting.Morale": "Activar puntuación de Moral para monstruos", | ||||||
|   "OSE.Setting.MoraleHint": "La puntuación de moral se ve en las hojas de monstruo", |   "OSE.Setting.MoraleHint": "La puntuación de moral se ve en las hojas de monstruo", | ||||||
|   "OSE.Setting.VariableWeaponDamage": "Daño de arma variable", |  | ||||||
|   "OSE.Setting.VariableWeaponDamageHint": "Las armas tienen diferente dado de daño", |  | ||||||
|   "OSE.Setting.Encumbrance": "Carga", |   "OSE.Setting.Encumbrance": "Carga", | ||||||
|   "OSE.Setting.EncumbranceHint": "Elige como se calcula la Carga", |   "OSE.Setting.EncumbranceHint": "Elige como se calcula la Carga", | ||||||
|   "OSE.Setting.EncumbranceDisabled": "Disabled", |   "OSE.Setting.EncumbranceDisabled": "Disabled", | ||||||
|  |  | ||||||
|  | @ -161,8 +161,6 @@ | ||||||
|   "OSE.Setting.AscendingACHint": "Le plus est le mieux", |   "OSE.Setting.AscendingACHint": "Le plus est le mieux", | ||||||
|   "OSE.Setting.Morale": "Activer le Score de Moral", |   "OSE.Setting.Morale": "Activer le Score de Moral", | ||||||
|   "OSE.Setting.MoraleHint": "Le Score de Moral est affiché sur la fiche de Monstre", |   "OSE.Setting.MoraleHint": "Le Score de Moral est affiché sur la fiche de Monstre", | ||||||
|   "OSE.Setting.VariableWeaponDamage": "Dégâts d'Arme Variables", |  | ||||||
|   "OSE.Setting.VariableWeaponDamageHint": "Les Armes peuvent avoir des dégâts d'arme différents", |  | ||||||
|   "OSE.Setting.Encumbrance": "Encombrement", |   "OSE.Setting.Encumbrance": "Encombrement", | ||||||
|   "OSE.Setting.EncumbranceHint": "Choisissez comment l'encombrement est calculé", |   "OSE.Setting.EncumbranceHint": "Choisissez comment l'encombrement est calculé", | ||||||
|   "OSE.Setting.EncumbranceDisabled": "Désactivé", |   "OSE.Setting.EncumbranceDisabled": "Désactivé", | ||||||
|  |  | ||||||
|  | @ -57,11 +57,6 @@ export class OseActorSheetCharacter extends OseActorSheet { | ||||||
|   getData() { |   getData() { | ||||||
|     const data = super.getData(); |     const data = super.getData(); | ||||||
| 
 | 
 | ||||||
|     // Settings
 |  | ||||||
|     data.config.variableWeaponDamage = game.settings.get( |  | ||||||
|       "ose", |  | ||||||
|       "variableWeaponDamage" |  | ||||||
|     ); |  | ||||||
|     data.config.ascendingAC = game.settings.get("ose", "ascendingAC"); |     data.config.ascendingAC = game.settings.get("ose", "ascendingAC"); | ||||||
|     data.config.individualInit = game.settings.get("ose", "individualInit"); |     data.config.individualInit = game.settings.get("ose", "individualInit"); | ||||||
|     data.config.encumbrance = game.settings.get("ose", "encumbranceOption"); |     data.config.encumbrance = game.settings.get("ose", "encumbranceOption"); | ||||||
|  |  | ||||||
|  | @ -274,6 +274,9 @@ export class OseActor extends Actor { | ||||||
|   rollHitDice(options = {}) { |   rollHitDice(options = {}) { | ||||||
|     const label = game.i18n.localize(`OSE.roll.hd`); |     const label = game.i18n.localize(`OSE.roll.hd`); | ||||||
|     const rollParts = [this.data.data.hp.hd]; |     const rollParts = [this.data.data.hp.hd]; | ||||||
|  |     if (this.data.type == 'character') { | ||||||
|  |       rollParts.push(this.data.data.scores.con.mod); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     const data = { |     const data = { | ||||||
|       ...this.data, |       ...this.data, | ||||||
|  | @ -373,10 +376,7 @@ export class OseActor extends Actor { | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     let dmgParts = []; |     let dmgParts = []; | ||||||
|     if ( |     if (!attData.dmg) { | ||||||
|       (!attData.dmg || !game.settings.get("ose", "variableWeaponDamage")) && |  | ||||||
|       this.type == "character" |  | ||||||
|     ) { |  | ||||||
|       dmgParts.push("1d6"); |       dmgParts.push("1d6"); | ||||||
|     } else { |     } else { | ||||||
|       dmgParts.push(attData.dmg); |       dmgParts.push(attData.dmg); | ||||||
|  | @ -404,11 +404,7 @@ export class OseActor extends Actor { | ||||||
|     const rollParts = ["1d20"]; |     const rollParts = ["1d20"]; | ||||||
|     const dmgParts = []; |     const dmgParts = []; | ||||||
|     let label = game.i18n.format("OSE.roll.attacks", { name: this.data.name }); |     let label = game.i18n.format("OSE.roll.attacks", { name: this.data.name }); | ||||||
|     if ( |     if (!attData.dmg) { | ||||||
|       !attData.dmg || |  | ||||||
|       (!game.settings.get("ose", "variableWeaponDamage") && |  | ||||||
|         this.data.type == "character") |  | ||||||
|     ) { |  | ||||||
|       dmgParts.push("1d6"); |       dmgParts.push("1d6"); | ||||||
|     } else { |     } else { | ||||||
|       label = game.i18n.format("OSE.roll.attacksWith", { name: attData.label }); |       label = game.i18n.format("OSE.roll.attacksWith", { name: attData.label }); | ||||||
|  |  | ||||||
|  | @ -1,13 +1,14 @@ | ||||||
| // eslint-disable-next-line no-unused-vars
 |  | ||||||
| import { OseActor } from '../actor/entity.js'; | import { OseActor } from '../actor/entity.js'; | ||||||
|  | import { OseDice } from "../dice.js"; | ||||||
| 
 | 
 | ||||||
| export class OseCharacterCreator extends FormApplication { | export class OseCharacterCreator extends FormApplication { | ||||||
|   static get defaultOptions() { |   static get defaultOptions() { | ||||||
|     const options = super.defaultOptions; |     const options = super.defaultOptions; | ||||||
|  |     options.classes = ["ose", "dialog", "creator"], | ||||||
|     options.id = 'character-creator'; |     options.id = 'character-creator'; | ||||||
|     options.template = |     options.template = | ||||||
|       'systems/ose/templates/actors/dialogs/character-creation.html'; |       'systems/ose/templates/actors/dialogs/character-creation.html'; | ||||||
|     options.width = 380; |     options.width = 235; | ||||||
|     return options; |     return options; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | @ -18,7 +19,7 @@ export class OseCharacterCreator extends FormApplication { | ||||||
|    * @type {String} |    * @type {String} | ||||||
|    */ |    */ | ||||||
|   get title() { |   get title() { | ||||||
|     return `${this.object.name}: ${game.i18n.localize('OSE.dialog.tweaks')}`; |     return `${this.object.name}: ${game.i18n.localize('OSE.dialog.generator')}`; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|  | @ -36,9 +37,66 @@ export class OseCharacterCreator extends FormApplication { | ||||||
| 
 | 
 | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| 
 | 
 | ||||||
|  |   doStats(ev) { | ||||||
|  |     let list = $(ev.currentTarget).closest('.attribute-list'); | ||||||
|  |     let values = []; | ||||||
|  |     list.find('.score-value').each((i, s) => { | ||||||
|  |       if (s.value != 0) { | ||||||
|  |         values.push(parseInt(s.value)); | ||||||
|  |       } | ||||||
|  |     }) | ||||||
|  | 
 | ||||||
|  |     let n = values.length; | ||||||
|  |     let sum = values.reduce((a,b) => a+b); | ||||||
|  |     let mean = parseFloat(sum) / n; | ||||||
|  |     let std = Math.sqrt(values.map(x => Math.pow(x-mean,2)).reduce((a,b) => a+b)/n); | ||||||
|  | 
 | ||||||
|  |     let stats = list.siblings('.roll-stats'); | ||||||
|  |     stats.find('.sum').text(sum); | ||||||
|  |     stats.find('.avg').text(Math.round(10 * sum / n) / 10); | ||||||
|  |     stats.find('.std').text(Math.round(100 * std) / 100); | ||||||
|  |     if (n >= 6) { | ||||||
|  |       $(ev.currentTarget).closest('form').find('button[type="submit"]').removeAttr('disabled'); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   rollScore(score, options={}) { | ||||||
|  |     const label = game.i18n.localize(`OSE.scores.${score}.long`); | ||||||
|  |     const rollParts = ["3d6"]; | ||||||
|  |     const data = { | ||||||
|  |       ...this.object.data, | ||||||
|  |       ...{ | ||||||
|  |         rollData: { | ||||||
|  |           type: "result" | ||||||
|  |         }, | ||||||
|  |       }, | ||||||
|  |     }; | ||||||
|  |     // Roll and return
 | ||||||
|  |     return OseDice.Roll({ | ||||||
|  |       event: options.event, | ||||||
|  |       parts: rollParts, | ||||||
|  |       data: data, | ||||||
|  |       skipDialog: true, | ||||||
|  |       speaker: ChatMessage.getSpeaker({ actor: this }), | ||||||
|  |       flavor: game.i18n.format('OSE.dialog.generateScore', {score: label}), | ||||||
|  |       title: game.i18n.format('OSE.dialog.generateScore', {score: label}), | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   /** @override */ |   /** @override */ | ||||||
|   activateListeners(html) { |   activateListeners(html) { | ||||||
|     super.activateListeners(html); |     super.activateListeners(html); | ||||||
|  |     html.find('a.score-roll').click((ev) => { | ||||||
|  |       let el = ev.currentTarget.parentElement.parentElement; | ||||||
|  |       let score = el.dataset.score; | ||||||
|  |       this.rollScore(score, {event: ev}).then(r => { | ||||||
|  |         $(el).find('input').val(r.total).trigger('change'); | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     html.find('input.score-value').change(ev => { | ||||||
|  |       this.doStats(ev); | ||||||
|  |     }) | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   /** |   /** | ||||||
|  |  | ||||||
|  | @ -103,12 +103,12 @@ export class OseDice { | ||||||
|               ) |               ) | ||||||
|               .then((displayed) => { |               .then((displayed) => { | ||||||
|                 ChatMessage.create(chatData); |                 ChatMessage.create(chatData); | ||||||
|                 resolve(); |                 resolve(roll); | ||||||
|               }); |               }); | ||||||
|           } else { |           } else { | ||||||
|             chatData.sound = CONFIG.sounds.dice; |             chatData.sound = CONFIG.sounds.dice; | ||||||
|             ChatMessage.create(chatData); |             ChatMessage.create(chatData); | ||||||
|             resolve(); |             resolve(roll); | ||||||
|           } |           } | ||||||
|         }); |         }); | ||||||
|       }); |       }); | ||||||
|  | @ -215,17 +215,17 @@ export class OseDice { | ||||||
|                       ) |                       ) | ||||||
|                       .then(() => { |                       .then(() => { | ||||||
|                         ChatMessage.create(chatData); |                         ChatMessage.create(chatData); | ||||||
|                         resolve(); |                         resolve(roll); | ||||||
|                       }); |                       }); | ||||||
|                   } else { |                   } else { | ||||||
|                     ChatMessage.create(chatData); |                     ChatMessage.create(chatData); | ||||||
|                     resolve(); |                     resolve(roll); | ||||||
|                   } |                   } | ||||||
|                 }); |                 }); | ||||||
|             } else { |             } else { | ||||||
|               chatData.sound = CONFIG.sounds.dice; |               chatData.sound = CONFIG.sounds.dice; | ||||||
|               ChatMessage.create(chatData); |               ChatMessage.create(chatData); | ||||||
|               resolve(); |               resolve(roll); | ||||||
|             } |             } | ||||||
|           }); |           }); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|  | @ -28,15 +28,6 @@ export const registerSettings = function () { | ||||||
|     config: true, |     config: true, | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|   game.settings.register("ose", "variableWeaponDamage", { |  | ||||||
|     name: game.i18n.localize("OSE.Setting.VariableWeaponDamage"), |  | ||||||
|     hint: game.i18n.localize("OSE.Setting.VariableWeaponDamageHint"), |  | ||||||
|     default: false, |  | ||||||
|     scope: "world", |  | ||||||
|     type: Boolean, |  | ||||||
|     config: true, |  | ||||||
|   }); |  | ||||||
| 
 |  | ||||||
|   game.settings.register("ose", "encumbranceOption", { |   game.settings.register("ose", "encumbranceOption", { | ||||||
|     name: game.i18n.localize("OSE.Setting.Encumbrance"), |     name: game.i18n.localize("OSE.Setting.Encumbrance"), | ||||||
|     hint: game.i18n.localize("OSE.Setting.EncumbranceHint"), |     hint: game.i18n.localize("OSE.Setting.EncumbranceHint"), | ||||||
|  |  | ||||||
|  | @ -5,6 +5,33 @@ | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .ose.dialog.creator { | ||||||
|  |   .attribute-list { | ||||||
|  |     .form-fields { | ||||||
|  |       flex: 0 0 50px; | ||||||
|  |       input { | ||||||
|  |         text-align: center; | ||||||
|  |         font-weight: bold; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   .roll-stats { | ||||||
|  |     flex: 0 0 65px; | ||||||
|  |     padding: 5px; | ||||||
|  |     margin-left: 4px; | ||||||
|  |     border-left: 1px solid $colorTan; | ||||||
|  |     .form-group { | ||||||
|  |       .form-fields { | ||||||
|  |         span { | ||||||
|  |           text-align: center; | ||||||
|  |           line-height: 24px; | ||||||
|  |           flex: 0; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .ose.dialog.party-sheet { | .ose.dialog.party-sheet { | ||||||
|   min-width: 250px; |   min-width: 250px; | ||||||
|   min-height: 250px; |   min-height: 250px; | ||||||
|  | @ -45,7 +72,7 @@ | ||||||
|       margin-bottom: 2px; |       margin-bottom: 2px; | ||||||
|       font-size: 12px; |       font-size: 12px; | ||||||
|       text-align: center; |       text-align: center; | ||||||
|       .fields .field-row{ |       .fields .field-row { | ||||||
|         &:nth-child(odd) { |         &:nth-child(odd) { | ||||||
|           background-color: rgba(0, 0, 0, 0.1); |           background-color: rgba(0, 0, 0, 0.1); | ||||||
|         } |         } | ||||||
|  | @ -120,7 +147,7 @@ | ||||||
|       flex: 0 0 30px; |       flex: 0 0 30px; | ||||||
|       font-size: 26px; |       font-size: 26px; | ||||||
|       line-height: 25px; |       line-height: 25px; | ||||||
|       color:white; |       color: white; | ||||||
|       margin: 0 2px 5px 8px; |       margin: 0 2px 5px 8px; | ||||||
|       border-radius: 8px; |       border-radius: 8px; | ||||||
|       background: url("/systems/ose/assets/chest.png") no-repeat center; |       background: url("/systems/ose/assets/chest.png") no-repeat center; | ||||||
|  | @ -128,7 +155,8 @@ | ||||||
|       padding: 5px 8px; |       padding: 5px 8px; | ||||||
|       cursor: pointer; |       cursor: pointer; | ||||||
|       filter: grayscale(1) opacity(0.5); |       filter: grayscale(1) opacity(0.5); | ||||||
|       &.active,&:hover { |       &.active, | ||||||
|  |       &:hover { | ||||||
|         filter: none; |         filter: none; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  | @ -172,12 +200,15 @@ | ||||||
|     box-shadow: 0 0 2px #fff inset; |     box-shadow: 0 0 2px #fff inset; | ||||||
|     .chat-title { |     .chat-title { | ||||||
|       margin: 4px 0; |       margin: 4px 0; | ||||||
|  |       height: 30px; | ||||||
|  |       overflow: hidden; | ||||||
|       h2 { |       h2 { | ||||||
|         border: none; |         border: none; | ||||||
|         line-height: 34px; |         line-height: 34px; | ||||||
|         margin: 0; |         margin: 0; | ||||||
|         text-indent: 10px; |         text-indent: 10px; | ||||||
|         font-size: 16px; |         font-size: 16px; | ||||||
|  |         word-break: break-all; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     .chat-img { |     .chat-img { | ||||||
|  |  | ||||||
|  | @ -1,7 +1,39 @@ | ||||||
| <form autocomplete="off" onsubmit="event.preventDefault();"> | <form autocomplete="off" onsubmit="event.preventDefault();"> | ||||||
|     <ol class="attribute-list"> |     <div class="flexrow"> | ||||||
|         {{#each config.scores as |score id| }} |         <div class="attribute-list"> | ||||||
|         <li data-score="{{id}}">{{score}}</li> |             {{#each config.scores as |score id| }} | ||||||
|         {{/each}} |             <div data-score="{{id}}" class="form-group"> | ||||||
|     </ol> |                 <label><a class="score-roll"><i class="fas fa-dice"></i></a> {{score}}</label> | ||||||
|  |                 <div class="form-fields"> | ||||||
|  |                     <input class="score-value" name="data.scores.{{id}}.value" type="text" value="0" data-dtype="Number"/> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |             {{/each}} | ||||||
|  |         </div> | ||||||
|  |         <div class="roll-stats"> | ||||||
|  |             <div class="form-group"> | ||||||
|  |                 <label>Sum</label> | ||||||
|  |                 <div class="form-fields"> | ||||||
|  |                     <span class="sum">0</span> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |             <div class="form-group"> | ||||||
|  |                 <label>Avg</label> | ||||||
|  |                 <div class="form-fields"> | ||||||
|  |                     <span class="avg">0</span> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |             <div class="form-group"> | ||||||
|  |                 <label>σ</label> | ||||||
|  |                 <div class="form-fields"> | ||||||
|  |                     <span class="std">0</span> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  |     <footer class="sheet-footer"> | ||||||
|  |       <button type="submit" disabled> | ||||||
|  |         <i class="fas fa-save"></i>{{localize "Save Changes"}} | ||||||
|  |       </button> | ||||||
|  |     </footer> | ||||||
| </form> | </form> | ||||||
		Loading…
	
		Reference in New Issue