ENH: Targeting

- Fixed Naked AC
- Added save to abilities
- Added basic targeting support, to be tested
master
U~man 2020-07-28 22:19:00 +02:00
parent 695951ee82
commit 8af8a0f635
7 changed files with 65 additions and 37 deletions

View File

@ -418,6 +418,7 @@ export class OseActor extends Actor {
thac0: thac0, thac0: thac0,
dmg: dmgParts, dmg: dmgParts,
save: attData.roll.save, save: attData.roll.save,
target: attData.roll.target
}, },
}; };
@ -576,7 +577,7 @@ export class OseActor extends Actor {
let AcShield = 0; let AcShield = 0;
let AacShield = 0; let AacShield = 0;
const data = this.data.data; 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; data.ac.naked = baseAc - data.scores.dex.mod;
const armors = this.data.items.filter((i) => i.type == "armor"); const armors = this.data.items.filter((i) => i.type == "armor");
armors.forEach((a) => { armors.forEach((a) => {
@ -635,9 +636,6 @@ export class OseActor extends Actor {
data.scores.con.value data.scores.con.value
); );
data.ac.naked = 9 + data.scores.dex.mod;
data.aac.naked = 10 - data.scores.dex.mod;
const capped = { const capped = {
0: -2, 0: -2,
3: -2, 3: -2,

View File

@ -124,14 +124,25 @@ export class OseDice {
total: roll.total, total: roll.total,
}; };
result.target = data.roll.thac0; 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 (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.details = game.i18n.format("OSE.messages.AttackAscendingSuccess", {
result: roll.total, result: roll.total,
}); });
result.isSuccess = true; result.isSuccess = true;
} else { } else {
// B/X Historic THAC0 Calculation // 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", { result.details = game.i18n.format("OSE.messages.AttackFailure", {
bonus: result.target, bonus: result.target,
}); });

View File

@ -66,8 +66,31 @@ export class OseItem extends Item {
rollWeapon(options = {}) { rollWeapon(options = {}) {
let isNPC = this.actor.data.type != "character"; let isNPC = this.actor.data.type != "character";
const targets = 5;
const data = this.data.data; const data = this.data.data;
let type = isNPC ? "attack" : "melee"; 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) { if (data.missile && data.melee && !isNPC) {
// Dialog // Dialog
new Dialog({ new Dialog({
@ -78,32 +101,14 @@ export class OseItem extends Item {
icon: '<i class="fas fa-fist-raised"></i>', icon: '<i class="fas fa-fist-raised"></i>',
label: "Melee", label: "Melee",
callback: () => { callback: () => {
this.actor.rollAttack( rollAttack("melee");
{
item: this.data,
actor: this.actor.data,
roll: {
save: this.data.data.save,
},
},
{ type: "melee", skipDialog: options.skipDialog }
);
}, },
}, },
missile: { missile: {
icon: '<i class="fas fa-bullseye"></i>', icon: '<i class="fas fa-bullseye"></i>',
label: "Missile", label: "Missile",
callback: () => { callback: () => {
this.actor.rollAttack( rollAttack("missile");
{
roll: {
save: this.data.data.save,
},
actor: this.actor.data,
item: this.data,
},
{ type: "missile", skipDialog: options.skipDialog }
);
}, },
}, },
}, },
@ -113,17 +118,7 @@ export class OseItem extends Item {
} else if (data.missile && !isNPC) { } else if (data.missile && !isNPC) {
type = "missile"; type = "missile";
} }
this.actor.rollAttack( rollAttack(type);
{
actor: this.actor.data,
item: this.data,
roll: {
save: this.data.data.save,
},
},
{ type: type, skipDialog: options.skipDialog }
);
return true; return true;
} }

View File

@ -216,6 +216,11 @@
background-size: cover; background-size: cover;
} }
} }
.chat-target {
text-align: right;
font-style: italic;
padding: 2px;
}
.chat-details { .chat-details {
padding: 4px; padding: 4px;
font-size: 13px; font-size: 13px;

View File

@ -218,7 +218,8 @@
"rollType": "result", "rollType": "result",
"rollTarget": 0, "rollTarget": 0,
"blindroll": false, "blindroll": false,
"description": "" "description": "",
"save": ""
} }
} }
} }

View File

@ -7,6 +7,11 @@
</div> </div>
<div class="chat-img" style="background-image:url('{{data.img}}')"></div> <div class="chat-img" style="background-image:url('{{data.img}}')"></div>
</div> </div>
{{#if result.victim}}
<div class="chat-target">
targeting {{result.victim}}
</div>
{{/if}}
<div class="chat-details"> <div class="chat-details">
<div class="roll-result">{{{result.details}}}</div> <div class="roll-result">{{{result.details}}}</div>
</div> </div>

View File

@ -46,6 +46,19 @@
<input type="checkbox" name="data.blindroll" value="{{data.blindroll}}" {{checked data.blindroll}} data-dtype="Number"/> <input type="checkbox" name="data.blindroll" value="{{data.blindroll}}" {{checked data.blindroll}} data-dtype="Number"/>
</div> </div>
</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>
<div class="description"> <div class="description">
{{editor content=data.description target="data.description" button=true {{editor content=data.description target="data.description" button=true