ENH: Targeting
- Fixed Naked AC - Added save to abilities - Added basic targeting support, to be testedmaster
							parent
							
								
									695951ee82
								
							
						
					
					
						commit
						8af8a0f635
					
				|  | @ -418,6 +418,7 @@ export class OseActor extends Actor { | |||
|         thac0: thac0, | ||||
|         dmg: dmgParts, | ||||
|         save: attData.roll.save, | ||||
|         target: attData.roll.target | ||||
|       }, | ||||
|     }; | ||||
| 
 | ||||
|  | @ -576,7 +577,7 @@ export class OseActor extends Actor { | |||
|     let AcShield = 0; | ||||
|     let AacShield = 0; | ||||
|     const data = this.data.data; | ||||
|     data.aac.naked = baseAc + data.scores.dex.mod; | ||||
|     data.aac.naked = baseAac + data.scores.dex.mod; | ||||
|     data.ac.naked = baseAc - data.scores.dex.mod; | ||||
|     const armors = this.data.items.filter((i) => i.type == "armor"); | ||||
|     armors.forEach((a) => { | ||||
|  | @ -635,9 +636,6 @@ export class OseActor extends Actor { | |||
|       data.scores.con.value | ||||
|     ); | ||||
| 
 | ||||
|     data.ac.naked = 9 + data.scores.dex.mod; | ||||
|     data.aac.naked = 10 - data.scores.dex.mod; | ||||
| 
 | ||||
|     const capped = { | ||||
|       0: -2, | ||||
|       3: -2, | ||||
|  |  | |||
|  | @ -124,14 +124,25 @@ export class OseDice { | |||
|       total: roll.total, | ||||
|     }; | ||||
|     result.target = data.roll.thac0; | ||||
| 
 | ||||
|     const targetAc = data.roll.target ? data.roll.target.actor.data.data.ac.value : 9; | ||||
|     const targetAac = data.roll.target ? data.roll.target.actor.data.data.aac.value : 0; | ||||
|     result.victim = data.roll.target ? data.roll.target.actor.name : null; | ||||
| 
 | ||||
|     if (game.settings.get("ose", "ascendingAC")) { | ||||
|       if (roll.total < targetAac) { | ||||
|         result.details = game.i18n.format("OSE.messages.AttackFailure", { | ||||
|           bonus: result.target, | ||||
|         }); | ||||
|         return result; | ||||
|       } | ||||
|       result.details = game.i18n.format("OSE.messages.AttackAscendingSuccess", { | ||||
|         result: roll.total, | ||||
|       }); | ||||
|       result.isSuccess = true; | ||||
|     } else { | ||||
|       // B/X Historic THAC0 Calculation
 | ||||
|       if (result.target - roll.total > 9) { | ||||
|       if (result.target - roll.total > targetAc) { | ||||
|         result.details = game.i18n.format("OSE.messages.AttackFailure", { | ||||
|           bonus: result.target, | ||||
|         }); | ||||
|  |  | |||
|  | @ -66,8 +66,31 @@ export class OseItem extends Item { | |||
| 
 | ||||
|   rollWeapon(options = {}) { | ||||
|     let isNPC = this.actor.data.type != "character"; | ||||
|     const targets = 5; | ||||
|     const data = this.data.data; | ||||
|     let type = isNPC ? "attack" : "melee"; | ||||
|     const rollData = | ||||
|     { | ||||
|       item: this.data, | ||||
|       actor: this.actor.data, | ||||
|       roll: { | ||||
|         save: this.data.data.save, | ||||
|         target: null | ||||
|       } | ||||
|     }; | ||||
| 
 | ||||
|     // rollAttack to target helper
 | ||||
|     const rollAttack = async (type) => { | ||||
|       if (game.user.targets.size > 0) { | ||||
|         for (let t of game.user.targets.values()) { | ||||
|           rollData.roll.target = t; | ||||
|           await this.actor.rollAttack(rollData, { type: type, skipDialog: options.skipDialog }); | ||||
|         } | ||||
|       } else { | ||||
|         this.actor.rollAttack(rollData, { type: type, skipDialog: options.skipDialog }); | ||||
|       } | ||||
|     }; | ||||
| 
 | ||||
|     if (data.missile && data.melee && !isNPC) { | ||||
|       // Dialog
 | ||||
|       new Dialog({ | ||||
|  | @ -78,32 +101,14 @@ export class OseItem extends Item { | |||
|             icon: '<i class="fas fa-fist-raised"></i>', | ||||
|             label: "Melee", | ||||
|             callback: () => { | ||||
|               this.actor.rollAttack( | ||||
|                 { | ||||
|                   item: this.data, | ||||
|                   actor: this.actor.data, | ||||
|                   roll: { | ||||
|                     save: this.data.data.save, | ||||
|                   }, | ||||
|                 }, | ||||
|                 { type: "melee", skipDialog: options.skipDialog } | ||||
|               ); | ||||
|               rollAttack("melee"); | ||||
|             }, | ||||
|           }, | ||||
|           missile: { | ||||
|             icon: '<i class="fas fa-bullseye"></i>', | ||||
|             label: "Missile", | ||||
|             callback: () => { | ||||
|               this.actor.rollAttack( | ||||
|                 { | ||||
|                   roll: { | ||||
|                     save: this.data.data.save, | ||||
|                   }, | ||||
|                   actor: this.actor.data, | ||||
|                   item: this.data, | ||||
|                 }, | ||||
|                 { type: "missile", skipDialog: options.skipDialog } | ||||
|               ); | ||||
|               rollAttack("missile"); | ||||
|             }, | ||||
|           }, | ||||
|         }, | ||||
|  | @ -113,17 +118,7 @@ export class OseItem extends Item { | |||
|     } else if (data.missile && !isNPC) { | ||||
|       type = "missile"; | ||||
|     } | ||||
|     this.actor.rollAttack( | ||||
|       { | ||||
|         actor: this.actor.data, | ||||
|         item: this.data, | ||||
|         roll: { | ||||
|           save: this.data.data.save, | ||||
|         }, | ||||
|       }, | ||||
|       { type: type, skipDialog: options.skipDialog } | ||||
|     ); | ||||
| 
 | ||||
|     rollAttack(type); | ||||
|     return true; | ||||
|   } | ||||
| 
 | ||||
|  |  | |||
|  | @ -216,6 +216,11 @@ | |||
|       background-size: cover; | ||||
|     } | ||||
|   } | ||||
|   .chat-target { | ||||
|     text-align: right; | ||||
|     font-style: italic; | ||||
|     padding: 2px; | ||||
|   } | ||||
|   .chat-details { | ||||
|     padding: 4px; | ||||
|     font-size: 13px; | ||||
|  |  | |||
|  | @ -218,7 +218,8 @@ | |||
|       "rollType": "result", | ||||
|       "rollTarget": 0, | ||||
|       "blindroll": false, | ||||
|       "description": "" | ||||
|       "description": "", | ||||
|       "save": "" | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -7,6 +7,11 @@ | |||
|             </div> | ||||
|             <div class="chat-img" style="background-image:url('{{data.img}}')"></div> | ||||
|         </div> | ||||
|         {{#if result.victim}} | ||||
|         <div class="chat-target"> | ||||
|             targeting {{result.victim}} | ||||
|         </div> | ||||
|         {{/if}} | ||||
|         <div class="chat-details"> | ||||
|             <div class="roll-result">{{{result.details}}}</div> | ||||
|         </div> | ||||
|  |  | |||
|  | @ -46,6 +46,19 @@ | |||
|             <input type="checkbox" name="data.blindroll" value="{{data.blindroll}}" {{checked data.blindroll}}  data-dtype="Number"/> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="form-group"> | ||||
|           <label>{{localize 'OSE.spells.Save'}}</label> | ||||
|           <div class="form-fields"> | ||||
|             <select name="data.save"> | ||||
|               {{#select data.save}} | ||||
|               <option value=""></option> | ||||
|               {{#each config.saves_short as |save a|}} | ||||
|               <option value="{{a}}">{{save}}</option> | ||||
|               {{/each}} | ||||
|               {{/select}} | ||||
|             </select> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div class="description"> | ||||
|         {{editor content=data.description target="data.description" button=true | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue