Merge pull request #27 from thehappyanarchist/THA-Dev

Implemented Morale and Loyalty systems.
master
thehappyanarchist 2020-09-27 17:49:35 -10:00 committed by GitHub
commit 84585118d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 108 additions and 26 deletions

View File

@ -701,6 +701,19 @@
/* Item Controls */ /* Item Controls */
/* ----------------------------------------- */ /* ----------------------------------------- */
} }
.acks.sheet.actor.character .sheet-header .header-details .summary .check-field:hover .check {
display: inline;
}
.acks.sheet.actor.character .sheet-header .header-details .summary .check-field .check {
display: none;
line-height: 35px;
flex: 0 0 20px;
position: absolute;
font-size: 12px;
}
.acks.sheet.actor.character .sheet-header .header-details .summary .check-field .check:hover {
color: rgba(0, 0, 0, 0.9);
}
.acks.sheet.actor.character .sheet-header .xp-bonus { .acks.sheet.actor.character .sheet-header .xp-bonus {
top: -15px; top: -15px;
right: 3px; right: 3px;

View File

@ -69,8 +69,8 @@
"ACKS.Retainer": "Retainer", "ACKS.Retainer": "Retainer",
"ACKS.RetainerWage": "Wage", "ACKS.RetainerWage": "Wage",
"ACKS.RetainerUpkeep": "Upkeep", "ACKS.RetainerUpkeep": "Upkeep",
"ACKS.Loyalty": "Henchmen Morale", "ACKS.Loyalty": "Loyalty",
"ACKS.LoyaltyShort": "MOR", "ACKS.LoyaltyShort": "LYL",
"ACKS.scores.str.long": "Strength", "ACKS.scores.str.long": "Strength",
"ACKS.scores.str.short": "STR", "ACKS.scores.str.short": "STR",
@ -290,5 +290,18 @@
"ACKS.reaction.Unfriendly": "{name} is Unfriendly and may attack", "ACKS.reaction.Unfriendly": "{name} is Unfriendly and may attack",
"ACKS.reaction.Neutral": "{name} is Neutral and uncertain", "ACKS.reaction.Neutral": "{name} is Neutral and uncertain",
"ACKS.reaction.Indifferent": "{name} is Indifferent and uninterested", "ACKS.reaction.Indifferent": "{name} is Indifferent and uninterested",
"ACKS.reaction.Friendly": "{name} is Friendly and helpful" "ACKS.reaction.Friendly": "{name} is Friendly and helpful",
"ACKS.loyalty.check": "Henchman Loyalty Check",
"ACKS.loyalty.hostility": "Becomes Hostile",
"ACKS.loyalty.resignation": "Tenders Resignation",
"ACKS.loyalty.grudging": "Grudging Loyalty",
"ACKS.loyalty.loyal": "Loyal",
"ACKS.loyalty.fanatic": "Fanatic Loyalty",
"ACKS.morale.retreat": "Retreat",
"ACKS.morale.fightingWithdrawal": "Fighting Withdrawl",
"ACKS.morale.fight": "Fight On",
"ACKS.morale.advanceAndPursue": "Advance and Pursue",
"ACKS.morale.fightToTheDeath": "Victory or Death"
} }

View File

@ -140,6 +140,16 @@ export class AcksActorSheetCharacter extends AcksActorSheet {
activateListeners(html) { activateListeners(html) {
super.activateListeners(html); super.activateListeners(html);
html.find(".morale-check a").click((ev) => {
let actorObject = this.actor;
actorObject.rollMorale({ event: event });
});
html.find(".loyalty-check a").click((ev) => {
let actorObject = this.actor;
actorObject.rollLoyalty({ event: event });
});
html.find(".ability-score .attribute-name a").click((ev) => { html.find(".ability-score .attribute-name a").click((ev) => {
let actorObject = this.actor; let actorObject = this.actor;
let element = event.currentTarget; let element = event.currentTarget;

View File

@ -162,21 +162,40 @@ export class AcksActor extends Actor {
rollMorale(options = {}) { rollMorale(options = {}) {
const rollParts = ["2d6"]; const rollParts = ["2d6"];
rollParts.push(this.data.data.details.morale);
const data = { const data = {
actor: this.data, actor: this.data,
roll: { roll: {
type: "below", type: "table",
target: this.data.data.details.morale, table: {
1: game.i18n.format("ACKS.morale.retreat", {
name: this.data.name,
}),
3: game.i18n.format("ACKS.morale.fightingWithdrawal", {
name: this.data.name,
}),
6: game.i18n.format("ACKS.morale.fight", {
name: this.data.name,
}),
9: game.i18n.format("ACKS.morale.advanceAndPursue", {
name: this.data.name,
}),
12: game.i18n.format("ACKS.morale.fightToTheDeath", {
name: this.data.name,
}),
},
}, },
}; };
let skip = options.event && options.event.ctrlKey;
// Roll and return // Roll and return
return AcksDice.Roll({ return AcksDice.Roll({
event: options.event, event: options.event,
parts: rollParts, parts: rollParts,
data: data, data: data,
skipDialog: true, skipDialog: skip,
speaker: ChatMessage.getSpeaker({ actor: this }), speaker: ChatMessage.getSpeaker({ actor: this }),
flavor: game.i18n.localize("ACKS.roll.morale"), flavor: game.i18n.localize("ACKS.roll.morale"),
title: game.i18n.localize("ACKS.roll.morale"), title: game.i18n.localize("ACKS.roll.morale"),
@ -184,26 +203,44 @@ export class AcksActor extends Actor {
} }
rollLoyalty(options = {}) { rollLoyalty(options = {}) {
const label = game.i18n.localize(`ACKS.roll.loyalty`);
const rollParts = ["2d6"]; const rollParts = ["2d6"];
rollParts.push(this.data.data.details.morale);
const data = { const data = {
actor: this.data, actor: this.data,
roll: { roll: {
type: "below", type: "table",
target: this.data.data.retainer.loyalty, table: {
1: game.i18n.format("ACKS.loyalty.hostility", {
name: this.data.name,
}),
3: game.i18n.format("ACKS.loyalty.resignation", {
name: this.data.name,
}),
6: game.i18n.format("ACKS.loyalty.grudging", {
name: this.data.name,
}),
9: game.i18n.format("ACKS.loyalty.loyal", {
name: this.data.name,
}),
12: game.i18n.format("ACKS.loyalty.fanatic", {
name: this.data.name,
}),
},
}, },
}; };
let skip = options.event && options.event.ctrlKey;
// Roll and return // Roll and return
return AcksDice.Roll({ return AcksDice.Roll({
event: options.event, event: options.event,
parts: rollParts, parts: rollParts,
data: data, data: data,
skipDialog: true, skipDialog: skip,
speaker: ChatMessage.getSpeaker({ actor: this }), speaker: ChatMessage.getSpeaker({ actor: this }),
flavor: label, flavor: game.i18n.localize("ACKS.loyalty.check"),
title: label, title: game.i18n.localize("ACKS.loyalty.check"),
}); });
} }

View File

@ -16,7 +16,7 @@ export class AcksDice {
result.isFailure = true; result.isFailure = true;
} }
} else if (data.roll.type == "below") { } else if (data.roll.type == "below") {
// MORALE // ?
if (roll.total <= result.target) { if (roll.total <= result.target) {
result.isSuccess = true; result.isSuccess = true;
} else { } else {
@ -35,7 +35,11 @@ export class AcksDice {
roll._total = 1; roll._total = 1;
} }
} else if (data.roll.type == "table") { } else if (data.roll.type == "table") {
// Reaction // Reaction, MORALE
// Roll cannot be less than 2 on a 2d6 roll
if (roll.total < 2) {
roll._total = 2
}
let table = data.roll.table; let table = data.roll.table;
let output = ""; let output = "";
for (let i = 0; i <= roll.total; i++) { for (let i = 0; i <= roll.total; i++) {

View File

@ -157,7 +157,7 @@
"d": 0, "d": 0,
"w": 0 "w": 0
}, },
"morale": 7 "morale": 0
}, },
"attacks": "" "attacks": ""
} }

View File

@ -57,17 +57,6 @@
data-dtype="Number" /> data-dtype="Number" />
</div> </div>
</li> </li>
{{#if data.retainer.enabled}}
<li class="attribute ability-score" data-stat="lr">
<h4 class="attribute-name box-title" title="{{ localize 'ACKS.Loyalty' }}">
<a>{{ localize "ACKS.LoyaltyShort" }}</a>
</h4>
<div class="attribute-value">
<input name="data.retainer.loyalty" type="text" value="{{data.retainer.loyalty}}" placeholder="0"
data-dtype="Number" />
</div>
</li>
{{/if}}
</ul> </ul>
</div> </div>
{{!-- Resource Tracking --}} {{!-- Resource Tracking --}}

View File

@ -22,6 +22,22 @@
/> />
<label>{{localize 'ACKS.details.alignment'}}</label> <label>{{localize 'ACKS.details.alignment'}}</label>
</li> </li>
{{#if data.retainer.enabled}}
<li class="flexrow check-field">
<div class="check morale-check" title="{{localize 'ACKS.roll.morale'}}"><a><i class="fas fa-dice"></i></a></div>
<div>
<input type="text" name="data.details.morale" value="{{data.details.morale}}" />
<label>{{localize 'ACKS.details.morale'}}</label>
</div>
</li>
<li class="flex2 check-field" data-stat="lr">
<div class="check loyalty-check" title="{{localize 'ACKS.loyalty.check'}}"><a><i class="fas fa-dice"></i></a></div>
<div class="attribute-value">
<input name="data.retainer.loyalty" type="text" value="{{data.retainer.loyalty}}" placeholder="Loyal" data-dtype="String" />
<label>{{localize 'ACKS.Loyalty'}}</label>
</div>
</li>
{{/if}}
</ul> </ul>
<ul class="summary flexrow"> <ul class="summary flexrow">
<li class="flex3"> <li class="flex3">