ENH: Reaction

master
U~man 2020-07-10 19:53:38 +02:00
parent 6926e44041
commit acd30407a4
10 changed files with 80 additions and 16 deletions

View File

@ -29,6 +29,9 @@
"OSE.TreasureTableHint": "Drop a rollable table here to roll the monster treasure", "OSE.TreasureTableHint": "Drop a rollable table here to roll the monster treasure",
"OSE.Size": "Size", "OSE.Size": "Size",
"OSE.Morale": "Morale", "OSE.Morale": "Morale",
"OSE.MoraleCheck": "Morale Check",
"OSE.Reaction": "Reaction",
"OSE.ReactionCheck": "Reaction Check",
"OSE.Retainer": "Retainer", "OSE.Retainer": "Retainer",
"OSE.Appearing": "NA", "OSE.Appearing": "NA",
"OSE.Attack": "Attack", "OSE.Attack": "Attack",
@ -162,6 +165,7 @@
"OSE.items.roundAttacks": "Attacks Spent this Round", "OSE.items.roundAttacks": "Attacks Spent this Round",
"OSE.items.roundAttacksMax": "Maximum Attacks per Round", "OSE.items.roundAttacksMax": "Maximum Attacks per Round",
"OSE.items.resetAttacks": "Reset all Attacks per Round", "OSE.items.resetAttacks": "Reset all Attacks per Round",
"OSE.items.hasShield": "Has a Shield bonus",
"OSE.armor.type": "Armor Type", "OSE.armor.type": "Armor Type",
"OSE.armor.unarmored": "Unarmored", "OSE.armor.unarmored": "Unarmored",
@ -211,5 +215,11 @@
"OSE.colors.purple": "Purple", "OSE.colors.purple": "Purple",
"OSE.colors.blue": "Blue", "OSE.colors.blue": "Blue",
"OSE.colors.orange": "Orange", "OSE.colors.orange": "Orange",
"OSE.colors.white": "White" "OSE.colors.white": "White",
"OSE.reaction.Hostile": "{name} is Hostile",
"OSE.reaction.Unfriendly": "{name} is Unfriendly",
"OSE.reaction.Neutral": "{name} is Neutral",
"OSE.reaction.Indifferent": "{name} is Indifferent",
"OSE.reaction.Friendly": "{name} is Friendly"
} }

View File

@ -98,6 +98,7 @@ export class OseActorSheetCharacter extends OseActorSheet {
}); });
data.data.aac.value = baseAac + data.data.scores.dex.mod + shield; data.data.aac.value = baseAac + data.data.scores.dex.mod + shield;
data.data.ac.value = baseAc - data.data.scores.dex.mod - shield; data.data.ac.value = baseAc - data.data.scores.dex.mod - shield;
data.data.shield = shield;
return data; return data;
} }

View File

@ -118,6 +118,40 @@ export class OseActor extends Actor {
}); });
} }
rollReaction(options = {}) {
const label = game.i18n.localize(`OSE.Reaction`);
const rollParts = ["2d6"];
const data = {
...this.data,
...{
rollData: {
type: "Table",
table: {
2: game.i18n.format("OSE.reaction.Hostile", {name: this.data.name}),
3: game.i18n.format("OSE.reaction.Unfriendly", {name: this.data.name}),
6: game.i18n.format("OSE.reaction.Neutral", {name: this.data.name}),
9: game.i18n.format("OSE.reaction.Indifferent", {name: this.data.name}),
12: game.i18n.format("OSE.reaction.Friendly", {name: this.data.name})
}
},
},
};
let skip = options.event && options.event.ctrlKey;
// Roll and return
return OseDice.Roll({
event: options.event,
parts: rollParts,
data: data,
skipDialog: skip,
speaker: ChatMessage.getSpeaker({ actor: this }),
flavor: `${label} ${game.i18n.localize("OSE.Roll")}`,
title: `${label} ${game.i18n.localize("OSE.Roll")}`,
});
}
rollCheck(score, options = {}) { rollCheck(score, options = {}) {
const label = game.i18n.localize(`OSE.scores.${score}.long`); const label = game.i18n.localize(`OSE.scores.${score}.long`);
const rollParts = ["1d20"]; const rollParts = ["1d20"];

View File

@ -174,6 +174,11 @@ export class OseActorSheetMonster extends OseActorSheet {
actorObject.rollMorale({ event: event }); actorObject.rollMorale({ event: event });
}); });
html.find(".reaction-check a").click((ev) => {
let actorObject = this.actor;
actorObject.rollReaction({ event: event });
});
html html
.find(".counter input") .find(".counter input")
.click((ev) => ev.target.select()) .click((ev) => ev.target.select())

View File

@ -35,5 +35,5 @@ export const OSE = {
blue: "OSE.colors.blue", blue: "OSE.colors.blue",
orange: "OSE.colors.orange", orange: "OSE.colors.orange",
white: "OSE.colors.white" white: "OSE.colors.white"
} },
}; };

View File

@ -28,6 +28,16 @@ export class OseDice {
} else { } else {
result.isFailure = true; result.isFailure = true;
} }
} else if (data.rollData.type == "Table") {
// Reaction
let table = data.rollData.table;
let output = "";
for (let i = 0; i <= roll.total; i++) {
if (table[i]) {
output = table[i];
}
}
result.details = output;
} }
return result; return result;
} }

View File

@ -29,12 +29,18 @@
&.armor-class { &.armor-class {
background: url('/systems/ose/assets/shield.png') no-repeat center; background: url('/systems/ose/assets/shield.png') no-repeat center;
background-size: 70px; background-size: 70px;
.shield {
text-align: right;
padding: 0 14px;
font-size: 18px;
}
} }
margin: 10px 0; margin: 10px 0;
height: 70px; height: 70px;
position: relative; position: relative;
input { .health-value {
font-size: 16px; font-size: 16px;
text-align: center;
font-weight: bolder; font-weight: bolder;
text-shadow: 0 0 2px white, 0 1px 2px white, 1px 0 2px white, 1px 1px 2px white; text-shadow: 0 0 2px white, 0 1px 2px white, 1px 0 2px white, 1px 1px 2px white;
} }

View File

@ -3,7 +3,7 @@
min-width: 460px; min-width: 460px;
.header-details { .header-details {
.summary { .summary {
.morale-check { .morale-check,.reaction-check {
line-height: 35px; line-height: 35px;
flex: 0 0 20px; flex: 0 0 20px;
&:hover { &:hover {

View File

@ -103,25 +103,22 @@
<div class="flex2"> <div class="flex2">
<div class="flexrow"> <div class="flexrow">
<div class="health"> <div class="health">
<input class="health-top" name="data.hp.value" type="text" value="{{data.hp.value}}" data-dtype="Number" <input class="health-value health-top" name="data.hp.value" type="text" value="{{data.hp.value}}" data-dtype="Number"
placeholder="0" title="{{localize 'OSE.Health'}}" /> placeholder="0" title="{{localize 'OSE.Health'}}" />
<input class="health-bottom" name="data.hp.max" type="text" value="{{data.hp.max}}" data-dtype="Number" <input class="health-value health-bottom" name="data.hp.max" type="text" value="{{data.hp.max}}" data-dtype="Number"
placeholder="0" title="{{localize 'OSE.HealthMax'}}" /> placeholder="0" title="{{localize 'OSE.HealthMax'}}" />
<div class="health-empty" style="height:{{counter false data.hp.value data.hp.max}}%"></div> <div class="health-empty" style="height:{{counter false data.hp.value data.hp.max}}%"></div>
<div class="health-full" style="height:{{counter true data.hp.value data.hp.max}}%"></div> <div class="health-full" style="height:{{counter true data.hp.value data.hp.max}}%"></div>
</div> </div>
<div class="health armor-class"> <div class="health armor-class">
{{#if config.ascendingAC}} {{#if config.ascendingAC}}
<input class="health-top" name="data.aac.value" type="text" value="{{data.aac.value}}" <div class="health-value health-top" title="{{localize 'OSE.ArmorClass'}}">{{data.aac.value}}</div>
data-dtype="Number" placeholder="0" title="{{localize 'OSE.ArmorClass'}}" disabled/> <div class="health-value health-bottom" title="{{localize 'OSE.ArmorClassNaked'}}">{{add 10 data.scores.dex.mod}}</div>
<input class="health-bottom" type="text" value="{{add 10 data.scores.dex.mod}}"
title="{{localize 'OSE.ArmorClassNaked'}}" disabled />
{{else}} {{else}}
<input class="health-top" name="data.ac.value" type="text" value="{{data.ac.value}}" data-dtype="Number" <div class="health-value health-top" title="{{localize 'OSE.ArmorClass'}}">{{data.ac.value}}</div>
placeholder="0" title="{{localize 'OSE.ArmorClass'}}" disabled/> <div class="health-value health-bottom" title="{{localize 'OSE.ArmorClassNaked'}}">{{subtract data.scores.dex.mod 9}}</div>
<input class="health-bottom" type="text" value="{{subtract data.scores.dex.mod 9}}"
title="{{localize 'OSE.ArmorClass'}}" disabled />
{{/if}} {{/if}}
{{#if data.shield}}<div class="shield" title="{{localize 'OSE.items.hasShield'}} ({{data.shield}})"><i class="fas fa-shield-alt"></i></div>{{/if}}
</div> </div>
</div> </div>
<div class="flexrow"> <div class="flexrow">

View File

@ -4,10 +4,11 @@
<input name="name" type="text" value="{{actor.name}}" placeholder="{{localize 'OSE.Name'}}" /> <input name="name" type="text" value="{{actor.name}}" placeholder="{{localize 'OSE.Name'}}" />
</h1> </h1>
<ul class="summary flexrow"> <ul class="summary flexrow">
<li class="flex2"> <li class="flex">
<input type="text" name="data.details.alignment" value="{{data.details.alignment}}" /> <input type="text" name="data.details.alignment" value="{{data.details.alignment}}" />
<label>{{localize 'OSE.Alignment'}}</label> <label>{{localize 'OSE.Alignment'}}</label>
</li> </li>
<li class="reaction-check" title="{{localize 'OSE.ReactionCheck'}}"><a><i class="fas fa-dice"></i></a></li>
<li> <li>
<input type="text" name="data.details.appearing" value="{{data.details.appearing}}" /> <input type="text" name="data.details.appearing" value="{{data.details.appearing}}" />
<label>{{localize 'OSE.Appearing'}}</label> <label>{{localize 'OSE.Appearing'}}</label>
@ -18,7 +19,7 @@
<input type="text" name="data.details.morale" value="{{data.details.morale}}" /> <input type="text" name="data.details.morale" value="{{data.details.morale}}" />
<label>{{localize 'OSE.Morale'}}</label> <label>{{localize 'OSE.Morale'}}</label>
</div> </div>
<div class="morale-check"><a><i class="fas fa-dice"></i></a></div> <div class="morale-check" title="{{localize 'OSE.MoraleCheck'}}"><a><i class="fas fa-dice"></i></a></div>
</li> </li>
{{/if}} {{/if}}
</ul> </ul>