ENH: Ability rolls and auto item tags
							parent
							
								
									10460834c2
								
							
						
					
					
						commit
						9b8dc1211d
					
				|  | @ -32,6 +32,9 @@ | |||
|   "OSE.roll.exploration": "{exploration} test", | ||||
|   "OSE.roll.details.exploration": "Roll 1d6 <= {expl} for success", | ||||
|   "OSE.roll.reaction": "Reaction roll", | ||||
|   "OSE.roll.type.result": "Result", | ||||
|   "OSE.roll.type.above": "Above", | ||||
|   "OSE.roll.type.below": "Below", | ||||
| 
 | ||||
|   "OSE.details.name": "Name", | ||||
|   "OSE.details.class": "Class", | ||||
|  | @ -169,6 +172,8 @@ | |||
|   "OSE.items.Quantity": "Qt.", | ||||
|   "OSE.items.Roll": "Roll", | ||||
|   "OSE.items.BlindRoll": "Blind", | ||||
|   "OSE.items.RollTarget": "Target", | ||||
|   "OSE.items.RollType": "Type", | ||||
|   "OSE.items.Damage": "Damage", | ||||
|   "OSE.items.Melee": "Melee", | ||||
|   "OSE.items.Missile": "Missile", | ||||
|  |  | |||
|  | @ -32,6 +32,9 @@ | |||
|   "OSE.roll.exploration": "Prueba de {exploration}", | ||||
|   "OSE.roll.details.exploration": "Tirar 1d6 <= {expl} para éxito", | ||||
|   "OSE.roll.reaction": "Tirada de Reacción", | ||||
|   "OSE.roll.type.result": "Resultado", | ||||
|   "OSE.roll.type.above": "Encima", | ||||
|   "OSE.roll.type.below": "Debajo", | ||||
| 
 | ||||
|   "OSE.details.name": "Nombre", | ||||
|   "OSE.details.class": "Clase", | ||||
|  | @ -167,6 +170,8 @@ | |||
|   "OSE.items.Quantity": "Qt.", | ||||
|   "OSE.items.Roll": "Tirada", | ||||
|   "OSE.items.BlindRoll": "Ciega", | ||||
|   "OSE.items.RollTarget": "Mira", | ||||
|   "OSE.items.RollType": "Tipo", | ||||
|   "OSE.items.Damage": "Daño", | ||||
|   "OSE.items.Melee": "CC", | ||||
|   "OSE.items.Missile": "Distancia", | ||||
|  |  | |||
|  | @ -32,6 +32,9 @@ | |||
|   "OSE.roll.exploration": "Test de {exploration}", | ||||
|   "OSE.roll.details.exploration": "Lancez 1d6 <= {expl} pour réussir", | ||||
|   "OSE.roll.reaction": "Jet de Réaction", | ||||
|   "OSE.roll.type.result": "Resultat", | ||||
|   "OSE.roll.type.above": "Au-Dessus", | ||||
|   "OSE.roll.type.below": "En-Dessous", | ||||
| 
 | ||||
|   "OSE.details.name": "Nom", | ||||
|   "OSE.details.class": "Classe", | ||||
|  | @ -109,9 +112,9 @@ | |||
|   "OSE.MeleeShort": "MEL", | ||||
|   "OSE.Melee": "Mêlée", | ||||
|   "OSE.MeleeBonus": "Bonus de Mêlée", | ||||
|   "OSE.MissileShort": "PRO", | ||||
|   "OSE.Missile": "Projectiles", | ||||
|   "OSE.MissileBonus": "Bonus de Projectile", | ||||
|   "OSE.MissileShort": "DIS", | ||||
|   "OSE.Missile": "Distance", | ||||
|   "OSE.MissileBonus": "Bonus à Distance", | ||||
|   "OSE.Initiative": "Initiative", | ||||
|   "OSE.InitiativeBonus": "Bonus d'Initiative", | ||||
|   "OSE.InitiativeShort": "INIT", | ||||
|  | @ -167,9 +170,11 @@ | |||
|   "OSE.items.Quantity": "Qt.", | ||||
|   "OSE.items.Roll": "Jet", | ||||
|   "OSE.items.BlindRoll": "Aveugle", | ||||
|   "OSE.items.RollTarget": "Cible", | ||||
|   "OSE.items.RollType": "Type", | ||||
|   "OSE.items.Damage": "Dégâts", | ||||
|   "OSE.items.Melee": "Mêlée", | ||||
|   "OSE.items.Missile": "Projectile", | ||||
|   "OSE.items.Missile": "Distance", | ||||
|   "OSE.items.Slow": "Lent", | ||||
|   "OSE.items.ArmorAC": "CA", | ||||
|   "OSE.items.ArmorAAC": "CAA", | ||||
|  |  | |||
|  | @ -71,7 +71,7 @@ export class OseActor extends Actor { | |||
|       ...this.data, | ||||
|       ...{ | ||||
|         rollData: { | ||||
|           type: "Above", | ||||
|           type: "above", | ||||
|           target: this.data.data.saves[save].value, | ||||
|           details: game.i18n.format("OSE.roll.details.save", { save: label }), | ||||
|         }, | ||||
|  | @ -99,7 +99,7 @@ export class OseActor extends Actor { | |||
|       ...this.data, | ||||
|       ...{ | ||||
|         rollData: { | ||||
|           type: "Below", | ||||
|           type: "below", | ||||
|           target: this.data.data.details.morale, | ||||
|         }, | ||||
|       }, | ||||
|  | @ -125,7 +125,7 @@ export class OseActor extends Actor { | |||
|       ...this.data, | ||||
|       ...{ | ||||
|         rollData: { | ||||
|           type: "Below", | ||||
|           type: "below", | ||||
|           target: this.data.data.retainer.loyalty, | ||||
|         }, | ||||
|       }, | ||||
|  | @ -151,7 +151,7 @@ export class OseActor extends Actor { | |||
|       ...this.data, | ||||
|       ...{ | ||||
|         rollData: { | ||||
|           type: "Table", | ||||
|           type: "table", | ||||
|           table: { | ||||
|             2: game.i18n.format("OSE.reaction.Hostile", { | ||||
|               name: this.data.name, | ||||
|  | @ -195,7 +195,7 @@ export class OseActor extends Actor { | |||
|       ...this.data, | ||||
|       ...{ | ||||
|         rollData: { | ||||
|           type: "Check", | ||||
|           type: "check", | ||||
|           target: this.data.data.scores[score].value, | ||||
|           details: game.i18n.format("OSE.roll.details.attribute", { | ||||
|             score: label, | ||||
|  | @ -226,7 +226,7 @@ export class OseActor extends Actor { | |||
|       ...this.data, | ||||
|       ...{ | ||||
|         rollData: { | ||||
|           type: "Hit Dice", | ||||
|           type: "hit dice", | ||||
|         }, | ||||
|       }, | ||||
|     }; | ||||
|  | @ -257,7 +257,7 @@ export class OseActor extends Actor { | |||
|       ...this.data, | ||||
|       ...{ | ||||
|         rollData: { | ||||
|           type: "Appearing", | ||||
|           type: "appearing", | ||||
|         }, | ||||
|       }, | ||||
|     }; | ||||
|  | @ -282,7 +282,7 @@ export class OseActor extends Actor { | |||
|       ...this.data, | ||||
|       ...{ | ||||
|         rollData: { | ||||
|           type: "Below", | ||||
|           type: "below", | ||||
|           target: this.data.data.exploration[expl], | ||||
|           details: game.i18n.format("OSE.roll.details.exploration", { | ||||
|             expl: label, | ||||
|  | @ -312,7 +312,7 @@ export class OseActor extends Actor { | |||
|       ...this.data, | ||||
|       ...{ | ||||
|         rollData: { | ||||
|           type: "Damage", | ||||
|           type: "damage", | ||||
|           stat: attData.type, | ||||
|           scores: data.scores, | ||||
|         }, | ||||
|  | @ -389,7 +389,7 @@ export class OseActor extends Actor { | |||
|       ...this.data, | ||||
|       ...{ | ||||
|         rollData: { | ||||
|           type: "Attack", | ||||
|           type: "attack", | ||||
|           thac0: thac0, | ||||
|           weapon: { | ||||
|             parts: dmgParts, | ||||
|  |  | |||
|  | @ -7,6 +7,11 @@ export const OSE = { | |||
|     con: "OSE.scores.con.long", | ||||
|     cha: "OSE.scores.cha.long", | ||||
|   }, | ||||
|   roll_type: { | ||||
|     result: "OSE.roll.type.result", | ||||
|     above: "OSE.roll.type.above", | ||||
|     below: "OSE.roll.type.below" | ||||
|   }, | ||||
|   saves_short: { | ||||
|     death: "OSE.saves.death.short", | ||||
|     wand: "OSE.saves.wand.short", | ||||
|  | @ -60,5 +65,10 @@ export const OSE = { | |||
|     "Ogre", | ||||
|     "Orcish", | ||||
|     "Pixie" | ||||
|   ] | ||||
|   ], | ||||
|   tags: { | ||||
|     melee: "OSE.items.Melee", | ||||
|     missile: "OSE.items.Missile", | ||||
|     slow: "OSE.items.Slow", | ||||
|   } | ||||
| }; | ||||
|  |  | |||
|  | @ -7,28 +7,28 @@ export class OseDice { | |||
|     }; | ||||
| 
 | ||||
|     let die = roll.parts[0].total; | ||||
|     if (data.rollData.type == "Above") { | ||||
|     if (data.rollData.type == "above") { | ||||
|       // SAVING THROWS
 | ||||
|       if (roll.total >= result.target) { | ||||
|         result.isSuccess = true; | ||||
|       } else { | ||||
|         result.isFailure = true; | ||||
|       } | ||||
|     } else if (data.rollData.type == "Below") { | ||||
|     } else if (data.rollData.type == "below") { | ||||
|       // MORALE, EXPLORATION
 | ||||
|       if (roll.total <= result.target) { | ||||
|         result.isSuccess = true; | ||||
|       } else { | ||||
|         result.isFailure = true; | ||||
|       } | ||||
|     } else if (data.rollData.type == "Check") { | ||||
|     } else if (data.rollData.type == "check") { | ||||
|       // SCORE CHECKS (1s and 20s)
 | ||||
|       if (die == 1 || (roll.total <= result.target && die < 20)) { | ||||
|         result.isSuccess = true; | ||||
|       } else { | ||||
|         result.isFailure = true; | ||||
|       } | ||||
|     } else if (data.rollData.type == "Table") { | ||||
|     } else if (data.rollData.type == "table") { | ||||
|       // Reaction
 | ||||
|       let table = data.rollData.table; | ||||
|       let output = ""; | ||||
|  | @ -251,7 +251,7 @@ export class OseDice { | |||
|       speaker: speaker | ||||
|     }; | ||||
|     if (skipDialog) { | ||||
|       return data.rollData.type === "Attack" | ||||
|       return data.rollData.type === "attack" | ||||
|         ? OseDice.sendAttackRoll(rollData) | ||||
|         : OseDice.sendRoll(rollData); | ||||
|     } | ||||
|  | @ -264,7 +264,7 @@ export class OseDice { | |||
|           rolled = true; | ||||
|           rollData.form = html[0].children[0]; | ||||
|           roll = | ||||
|             data.rollData.type === "Attack" | ||||
|             data.rollData.type === "attack" | ||||
|               ? OseDice.sendAttackRoll(rollData) | ||||
|               : OseDice.sendRoll(rollData); | ||||
|         }, | ||||
|  |  | |||
|  | @ -102,19 +102,23 @@ export class OseItem extends Item { | |||
|   } | ||||
| 
 | ||||
|   async rollFormula(options = {}) { | ||||
|     if (!this.data.data.roll) { | ||||
|     const data = this.data.data; | ||||
|     if (!data.roll) { | ||||
|       throw new Error("This Item does not have a formula to roll!"); | ||||
|     } | ||||
| 
 | ||||
|     const label = `${this.name}`; | ||||
|     const rollParts = [this.data.data.roll]; | ||||
|     const rollParts = [data.roll]; | ||||
| 
 | ||||
|     const data = { | ||||
|     let type = data.rollType; | ||||
| 
 | ||||
|     const newData = { | ||||
|       ...this.data, | ||||
|       ...{ | ||||
|         rollData: { | ||||
|           type: "Formula", | ||||
|           blindroll: this.data.data.blindroll, | ||||
|           type: type, | ||||
|           target: data.rollTarget, | ||||
|           blindroll: data.blindroll, | ||||
|         }, | ||||
|       }, | ||||
|     }; | ||||
|  | @ -123,7 +127,7 @@ export class OseItem extends Item { | |||
|     return OseDice.Roll({ | ||||
|       event: options.event, | ||||
|       parts: rollParts, | ||||
|       data: data, | ||||
|       data: newData, | ||||
|       skipDialog: true, | ||||
|       speaker: ChatMessage.getSpeaker({ actor: this }), | ||||
|       flavor: game.i18n.format("OSE.roll.formula", { label: label }), | ||||
|  | @ -144,8 +148,8 @@ export class OseItem extends Item { | |||
|   getTags() { | ||||
|     let formatTag = (tag) => { | ||||
|       if (!tag) return ""; | ||||
|       return `<li class='tag'>${tag}</li>` | ||||
|     } | ||||
|       return `<li class='tag'>${tag}</li>`; | ||||
|     }; | ||||
| 
 | ||||
|     const data = this.data.data; | ||||
|     switch (this.data.type) { | ||||
|  | @ -156,11 +160,63 @@ export class OseItem extends Item { | |||
|       case "item": | ||||
|         return ""; | ||||
|       case "spell": | ||||
|         return `${formatTag(data.class)}${formatTag(data.range)}${formatTag(data.duration)}${formatTag(CONFIG.OSE.saves_long[data.save])}${formatTag(data.roll)}`; | ||||
|         return `${formatTag(data.class)}${formatTag(data.range)}${formatTag( | ||||
|           data.duration | ||||
|         )}${formatTag(CONFIG.OSE.saves_long[data.save])}${formatTag( | ||||
|           data.roll | ||||
|         )}`;
 | ||||
|       case "ability": | ||||
|         return `${formatTag(data.requirements)}${formatTag(data.roll)}`; | ||||
|     } | ||||
|     return "TEST"; | ||||
|     return ""; | ||||
|   } | ||||
| 
 | ||||
|   pushTag(values) { | ||||
|     const data = this.data.data; | ||||
|     let update = []; | ||||
|     if (data.tags) { | ||||
|       update = duplicate(data.tags); | ||||
|     } | ||||
|     let newData = {}; | ||||
|     var regExp = /\(([^)]+)\)/; | ||||
|     if (update) { | ||||
|       values.forEach((val) => { | ||||
|         // Catch infos in brackets
 | ||||
|         var matches = regExp.exec(val); | ||||
|         let title = ""; | ||||
|         if (matches) { | ||||
|           title = matches[1]; | ||||
|           val = val.substring(0, matches.index); | ||||
|         } | ||||
|         // Auto fill checkboxes
 | ||||
|         switch (val) { | ||||
|           case CONFIG.OSE.tags.melee: | ||||
|             newData.melee = true; | ||||
|             break; | ||||
|           case CONFIG.OSE.tags.slow: | ||||
|             newData.slow = true; | ||||
|             break; | ||||
|           case CONFIG.OSE.tags.missile: | ||||
|             newData.missile = true; | ||||
|             break; | ||||
|         } | ||||
|         update.push({ title: title, value: val }); | ||||
|       }); | ||||
|     } else { | ||||
|       update = values; | ||||
|     } | ||||
|     newData.tags = update; | ||||
|     console.log(newData); | ||||
|     return this.update({ data: newData }); | ||||
|   } | ||||
| 
 | ||||
|   popTag(value) { | ||||
|     const data = this.data.data; | ||||
|     let update = data.tags.filter((el) => el.value != value); | ||||
|     let newData = { | ||||
|       tags: update, | ||||
|     }; | ||||
|     return this.update({ data: newData }); | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|  |  | |||
|  | @ -51,41 +51,6 @@ export class OseItemSheet extends ItemSheet { | |||
| 
 | ||||
|   /* -------------------------------------------- */ | ||||
| 
 | ||||
|   _pushTag(values) { | ||||
|     const data = this.object.data.data; | ||||
|     let update = []; | ||||
|     if (data.tags) { | ||||
|       update = duplicate(data.tags); | ||||
|     } | ||||
|     var regExp = /\(([^)]+)\)/; | ||||
|     if (update) { | ||||
|       values.forEach(val => { | ||||
|         // Catch infos in brackets
 | ||||
|         var matches = regExp.exec(val); | ||||
|         let title = ""; | ||||
|         if (matches) { | ||||
|           title = matches[1]; | ||||
|           val = val.substring(0, matches.index); | ||||
|         } | ||||
|         update.push({title: title, value: val}); | ||||
|       }) | ||||
|     } else { | ||||
|       update = values; | ||||
|     } | ||||
|     let newData = { | ||||
|       tags: update | ||||
|     }; | ||||
|     return this.object.update({ data: newData }); | ||||
|   } | ||||
| 
 | ||||
|   _popTag(value) { | ||||
|     const data = this.object.data.data; | ||||
|     let update = data.tags.filter((el) => el.value != value); | ||||
|     let newData = { | ||||
|       tags: update | ||||
|     }; | ||||
|     return this.object.update({ data: newData }); | ||||
|   } | ||||
|   /** | ||||
|    * Activate event listeners using the prepared sheet HTML | ||||
|    * @param html {HTML}   The prepared HTML object ready to be rendered into the DOM | ||||
|  | @ -95,12 +60,12 @@ export class OseItemSheet extends ItemSheet { | |||
|       if (event.which == 13) { | ||||
|         let value = $(ev.currentTarget).val(); | ||||
|         let values = value.split(','); | ||||
|         this._pushTag(values); | ||||
|         this.object.pushTag(values); | ||||
|       } | ||||
|     }); | ||||
|     html.find('.tag-delete').click((ev) => { | ||||
|       let value = ev.currentTarget.parentElement.dataset.tag; | ||||
|       this._popTag(value); | ||||
|       this.object.popTag(value); | ||||
|     }); | ||||
|     super.activateListeners(html); | ||||
|   } | ||||
|  |  | |||
|  | @ -62,7 +62,7 @@ Hooks.once("init", async function () { | |||
|  */ | ||||
| Hooks.once("setup", function () { | ||||
|   // Localize CONFIG objects once up-front
 | ||||
|   const toLocalize = ["saves_short", "saves_long", "scores", "armor", "colors"]; | ||||
|   const toLocalize = ["saves_short", "saves_long", "scores", "armor", "colors", "roll_type", "tags"]; | ||||
|   for (let o of toLocalize) { | ||||
|     CONFIG.OSE[o] = Object.entries(CONFIG.OSE[o]).reduce((obj, e) => { | ||||
|       obj[e[0]] = game.i18n.localize(e[1]); | ||||
|  |  | |||
|  | @ -2,22 +2,14 @@ | |||
|   "name": "ose", | ||||
|   "title": "Old-School Essentials", | ||||
|   "description": "Play B/X OSR modules with Old-School Essentials on Foundry VTT", | ||||
|   "version": 0.8, | ||||
|   "version": 0.9, | ||||
|   "minimumCoreVersion": "0.6.2", | ||||
|   "compatibleCoreVersion": "0.6.5", | ||||
|   "templateVersion": 2, | ||||
|   "author": "U~man", | ||||
|   "esmodules": ["ose.js"], | ||||
|   "styles": ["ose.css"], | ||||
|   "packs": [ | ||||
|     { | ||||
|       "name": "OSEMacros", | ||||
|       "label": "Old School Essentials Macros", | ||||
|       "system": "ose", | ||||
|       "path": "./packs/macros.db", | ||||
|       "entity": "Macro" | ||||
|     } | ||||
|   ], | ||||
|   "packs": [], | ||||
|   "languages": [ | ||||
|     { | ||||
|       "lang": "en", | ||||
|  | @ -39,5 +31,5 @@ | |||
|   "gridUnits": "ft", | ||||
|   "url": "https://gitlab.com/mesfoliesludiques/foundryvtt-ose", | ||||
|   "manifest": "https://gitlab.com/mesfoliesludiques/foundryvtt-ose/raw/master/src/system.json", | ||||
|   "download": "https://gitlab.com/mesfoliesludiques/foundryvtt-ose/-/raw/master/package/ose-v0.8.zip" | ||||
|   "download": "https://gitlab.com/mesfoliesludiques/foundryvtt-ose/-/raw/master/package/ose-v0.9.zip" | ||||
| } | ||||
|  |  | |||
|  | @ -210,6 +210,8 @@ | |||
|     "ability": { | ||||
|       "requirements": "", | ||||
|       "roll": "", | ||||
|       "rollType": "result", | ||||
|       "rollTarget": 0, | ||||
|       "blindroll": false, | ||||
|       "description": "" | ||||
|     } | ||||
|  |  | |||
|  | @ -22,6 +22,24 @@ | |||
|             <input type="text" name="data.roll" value="{{data.roll}}" data-dtype="String" /> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="form-group block-input"> | ||||
|           <label>{{localize 'OSE.items.RollType'}}</label> | ||||
|           <div class="form-fields"> | ||||
|             <select name="data.rollType"> | ||||
|               {{#select data.rollType}} | ||||
|               {{#each config.roll_type as |t a|}} | ||||
|               <option value="{{a}}">{{t}}</option> | ||||
|               {{/each}} | ||||
|               {{/select}} | ||||
|             </select> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="form-group"> | ||||
|           <label>{{localize 'OSE.items.RollTarget'}}</label> | ||||
|           <div class="form-fields"> | ||||
|             <input type="text" name="data.rollTarget" value="{{data.rollTarget}}" data-dtype="Number" /> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="form-group"> | ||||
|           <label>{{localize 'OSE.items.BlindRoll'}}</label> | ||||
|           <div class="form-fields"> | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue