Various updates

This commit is contained in:
LeRatierBretonnien 2025-01-09 22:26:37 +01:00
parent d0284d2b84
commit 949755b680
36 changed files with 288 additions and 14 deletions

View File

@ -500,6 +500,44 @@ i.lethalfantasy {
align-items: center;
gap: 10px;
}
.lethalfantasy .tab.character-weapons .combat-details .combat-detail .armor-hp {
min-width: 20rem;
max-width: 20rem;
}
.lethalfantasy .tab.character-weapons .combat-details .combat-detail .armor-hp .input {
min-width: 3rem;
max-width: 3rem;
}
.lethalfantasy .tab.character-weapons .wounds {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 10px;
}
.lethalfantasy .tab.character-weapons .wounds .wound {
display: flex;
align-items: center;
gap: 10px;
}
.lethalfantasy .tab.character-weapons .wounds .wound .wound-description {
min-width: 16rem;
max-width: 16rem;
}
.lethalfantasy .tab.character-weapons .wounds .wound .wound-duration {
min-width: 3rem;
max-width: 3rem;
}
.lethalfantasy .tab.character-weapons .wounds .wound .wound-value {
min-width: 3rem;
max-width: 3rem;
}
.lethalfantasy .tab.character-weapons .wounds .wound .item-img {
width: 32px;
height: 32px;
margin: 5px 0 0 0;
}
.lethalfantasy .tab.character-weapons .wounds .wound .name {
min-width: 12rem;
}
.lethalfantasy .tab.character-weapons .weapons {
display: grid;
grid-template-columns: repeat(2, 1fr);
@ -1517,6 +1555,18 @@ i.lethalfantasy {
width: 60px;
text-align: center;
}
.dialog-favor {
display: flex;
justify-content: center;
align-items: center;
}
.dialog-favor select {
border: none;
background-color: rgba(0, 0, 0, 0.1);
color: var(--color-dark-2);
width: 120px;
text-align: center;
}
.main,
.dialog-damage,
.dialog-resource,

View File

@ -146,6 +146,15 @@
}
},
"Label": {
"favorResult": "Favor result",
"disfavorResult": "Disfavor result",
"otherResult": "Other result",
"disfavor": "Disfavor",
"favor": "Favor",
"wounds": "Wounds",
"name": "Name",
"hp": "HP",
"duration": "Duration",
"combatDetails": "Combat details",
"Challenges": "Challenges",
"HP": "HP",
@ -292,9 +301,7 @@
"FIELDS": {}
},
"Roll": {
"attack": "Jet d'attaque <br> {item}",
"changeDice": "Change dice",
"damage": "Jet de dégâts <br> {item}",
"failure": "Failure",
"modifier": "Modifier",
"modifierBonusMalus": "Modifier bonus/malus",
@ -302,7 +309,8 @@
"roll": "Roll",
"save": "Save roll {save}",
"success": "Success",
"visibility": "Visibility"
"visibility": "Visibility",
"favorDisfavor": "Favor/Disfavor"
},
"Save": {
"FIELDS": {

View File

@ -15,6 +15,8 @@ export default class LethalFantasyCharacterSheet extends LethalFantasyActorSheet
actions: {
createEquipment: LethalFantasyCharacterSheet.#onCreateEquipment,
rangedAttackDefense: LethalFantasyCharacterSheet.#onRangedAttackDefense,
armorHitPointsPlus: LethalFantasyCharacterSheet.#onArmorHitPointsPlus,
armorHitPointsMinus: LethalFantasyCharacterSheet.#onArmorHitPointsMinus,
},
}
@ -138,10 +140,6 @@ export default class LethalFantasyCharacterSheet extends LethalFantasyActorSheet
}
}
async #onDropPathItem(item) {
await this.document.addPath(item)
}
static async #onRangedAttackDefense(event, target) {
const hasTarget = false
let roll = await LethalFantasyRoll.promptRangedDefense({
@ -154,10 +152,40 @@ export default class LethalFantasyCharacterSheet extends LethalFantasyActorSheet
await roll.toMessage({}, { rollMode: roll.options.rollMode })
}
static #onArmorHitPointsPlus(event, target) {
let armorHP = this.actor.system.combat.armorHitPoints
armorHP += 1
this.actor.update({ "system.combat.armorHitPoints": armorHP })
}
static #onArmorHitPointsMinus(event, target) {
let armorHP = this.actor.system.combat.armorHitPoints
armorHP -= 1
this.actor.update({ "system.combat.armorHitPoints": Math.max(armorHP, 0) })
}
static #onCreateEquipment(event, target) {
}
_onRender(context, options) {
// Inputs with class `item-quantity`
const woundDescription = this.element.querySelectorAll('.wound-data')
for (const input of woundDescription) {
input.addEventListener("change", (e) => {
e.preventDefault();
e.stopImmediatePropagation();
const newValue = e.currentTarget.value
const index = e.currentTarget.dataset.index
const fieldName = e.currentTarget.dataset.name
let tab = foundry.utils.duplicate(this.actor.system.hp.wounds)
tab[index][fieldName] = newValue
console.log(tab, index, fieldName, newValue)
this.actor.update( { "system.hp.wounds": tab } );
})
}
super._onRender();
}
getBestWeaponClassSkill(skills, rollType, multiplier = 1.0) {
let maxValue = 0
let goodSkill = skills[0]
@ -278,7 +306,7 @@ export default class LethalFantasyCharacterSheet extends LethalFantasyActorSheet
// In all cases
rollTarget.magicUser = this.actor.system.biodata.magicUser
rollTarget.actorModifiers = foundry.utils.duplicate(this.actor.system.modifiers)
console.log(rollTarget)
await this.document.system.roll(rollType, rollTarget)
}
// #endregion

View File

@ -42,6 +42,12 @@ export const MONEY = {
}
}
export const FAVOR_CHOICES = {
"none": {label: "None", value: "none"},
"favor": {label: "Favor", value: "favor"},
"disfavor": {label: "Disfavor", value: "disfavor"}
}
export const MOVEMENT_CHOICES = {
"none": {label: "None (D8E)", value: "D8"},
"walk": {label: "Walk (D10E)", value: "D10"},
@ -192,5 +198,6 @@ export const SYSTEM = {
MOVE_DIRECTION_CHOICES,
SIZE_CHOICES,
RANGE_CHOICES,
FAVOR_CHOICES,
ATTACKER_AIM_CHOICES
}

View File

@ -92,6 +92,10 @@ export default class LethalFantasyRoll extends Roll {
return this.options.D30result
}
get badResult() {
return this.options.badResult
}
/**
* Prompt the user with a dialog to configure and execute a roll.
*
@ -117,6 +121,7 @@ export default class LethalFantasyRoll extends Roll {
let hasModifier = true
let hasChangeDice = false
let hasD30 = false
let hasFavor = false
if (options.rollType === "challenge" || options.rollType === "save") {
options.rollName = options.rollTarget.rollKey
@ -137,6 +142,7 @@ export default class LethalFantasyRoll extends Roll {
baseFormula = "D100"
maxValue = 100
hasModifier = true
hasFavor = true
hasChangeDice = false
options.rollTarget.value = options.rollTarget.system.skillTotal
@ -148,6 +154,7 @@ export default class LethalFantasyRoll extends Roll {
maxValue = 20
hasModifier = true
hasChangeDice = false
hasFavor = true
if (options.rollType === "weapon-attack") {
options.rollTarget.value = options.rollTarget.combat.attackModifier + options.rollTarget.weaponSkillModifier
options.rollTarget.charModifier = options.rollTarget.combat.attackModifier
@ -209,6 +216,7 @@ export default class LethalFantasyRoll extends Roll {
const choiceModifier = SYSTEM.CHOICE_MODIFIERS
const choiceDice = SYSTEM.CHOICE_DICE
const choiceFavor = SYSTEM.FAVOR_CHOICES
let modifier = "+0"
let targetName
@ -219,17 +227,20 @@ export default class LethalFantasyRoll extends Roll {
rollName: options.rollName,
rollModes,
hasModifier,
hasFavor,
hasChangeDice,
baseValue: options.rollTarget.value,
changeDice: `${dice}`,
fieldRollMode,
choiceModifier,
choiceDice,
choiceFavor,
baseFormula,
dice,
hasTarget: options.hasTarget,
modifier,
saveSpell: false,
favor : "none",
targetName
}
console.log("dialogContext", dialogContext)
@ -322,12 +333,46 @@ export default class LethalFantasyRoll extends Roll {
*/
if (Hooks.call("fvtt-lethal-fantasy.preRoll", options, rollData) === false) return
const rollBase = new this(baseFormula, options.data, rollData)
let rollBase = new this(baseFormula, options.data, rollData)
const rollModifier = new Roll(modifierFormula, options.data, rollData)
rollModifier.evaluate()
await rollBase.evaluate()
let rollFavor
let badResult
if (rollContext.favor === "favor") {
rollFavor = new this(baseFormula, options.data, rollData)
await rollFavor.evaluate()
if (game?.dice3d) {
await game.dice3d.showForRoll(rollFavor, game.user, true)
}
if (rollFavor.result > rollBase.result) {
badResult = rollBase.result
rollBase = rollFavor
} else {
badResult = rollFavor.result
}
}
if (rollContext.favor === "disfavor") {
rollFavor = new this(baseFormula, options.data, rollData)
await rollFavor.evaluate()
if (game?.dice3d) {
await game.dice3d.showForRoll(rollFavor, game.user, true)
}
if (rollFavor.result < rollBase.result) {
badResult = rollBase.result
rollBase = rollFavor
} else {
badResult = rollFavor.result
}
}
if (hasD30) {
let rollD30 = await new Roll("1D30").evaluate()
if (game?.dice3d) {
await game.dice3d.showForRoll(rollFavor, game.user, true)
}
options.D30result = rollD30.total
}
@ -367,6 +412,7 @@ export default class LethalFantasyRoll extends Roll {
rollBase.options.rollTarget = options.rollTarget
rollBase.options.titleFormula = titleFormula
rollBase.options.D30result = options.D30result
rollBase.options.badResult = badResult
/**
* A hook event that fires after the roll has been made.
@ -589,6 +635,7 @@ export default class LethalFantasyRoll extends Roll {
targetName: this.targetName,
targetArmor: this.targetArmor,
D30result: this.D30result,
badResult: this.badResult,
isPrivate: isPrivate
}
cardData.cssClass = cardData.css.join(" ")

View File

@ -68,7 +68,9 @@ export default class LethalFantasyCharacter extends foundry.abstract.TypeDataMod
value: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
max: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
painDamage: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
wounds: new fields.ArrayField(new fields.SchemaField(woundFieldSchema ) ),
wounds: new fields.ArrayField(new fields.SchemaField(woundFieldSchema ) , { initial: [{description:"", value:0, duration:0},{description:"", value:0, duration:0},
{description:"", value:0, duration:0},{description:"", value:0, duration:0},{description:"", value:0, duration:0},{description:"", value:0, duration:0},
{description:"", value:0, duration:0},{description:"", value:0, duration:0}], min:8} ),
})
schema.perception = new fields.SchemaField({

View File

@ -31,9 +31,7 @@ export default class LethalFantasySkill extends foundry.abstract.TypeDataModel {
validate(options) {
let isError = super.validate(options)
console.log(this)
let bonus = this._source.weaponBonus.attack + this._source.weaponBonus.defense + this._source.weaponBonus.damage
console.log(bonus, this._source.skillTotal)
if (bonus > Math.floor(this._source.skillTotal / 10)) {
ui.notifications.error(game.i18n.localize("LETHALFANTASY.Skill.error.weaponBonus"))
isError = true

View File

View File

@ -0,0 +1 @@
MANIFEST-000006

View File

View File

@ -0,0 +1,7 @@
2025/01/09-22:06:01.230631 7f0abbfff6c0 Recovering log #4
2025/01/09-22:06:01.239976 7f0abbfff6c0 Delete type=3 #2
2025/01/09-22:06:01.240081 7f0abbfff6c0 Delete type=0 #4
2025/01/09-22:26:22.511134 7f0ab9bff6c0 Level-0 table #9: started
2025/01/09-22:26:22.511166 7f0ab9bff6c0 Level-0 table #9: 0 bytes OK
2025/01/09-22:26:22.540103 7f0ab9bff6c0 Delete type=0 #7
2025/01/09-22:26:22.609664 7f0ab9bff6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)

View File

@ -0,0 +1,5 @@
2025/01/09-20:31:12.531379 7f0abaffd6c0 Delete type=3 #1
2025/01/09-22:05:02.668496 7f0ab9bff6c0 Level-0 table #5: started
2025/01/09-22:05:02.668533 7f0ab9bff6c0 Level-0 table #5: 0 bytes OK
2025/01/09-22:05:02.675350 7f0ab9bff6c0 Delete type=0 #3
2025/01/09-22:05:02.689275 7f0ab9bff6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)

Binary file not shown.

View File

View File

@ -0,0 +1 @@
MANIFEST-000006

View File

View File

@ -0,0 +1,7 @@
2025/01/09-22:06:01.242474 7f0abb7fe6c0 Recovering log #4
2025/01/09-22:06:01.252331 7f0abb7fe6c0 Delete type=3 #2
2025/01/09-22:06:01.252401 7f0abb7fe6c0 Delete type=0 #4
2025/01/09-22:26:22.580727 7f0ab9bff6c0 Level-0 table #9: started
2025/01/09-22:26:22.580760 7f0ab9bff6c0 Level-0 table #9: 0 bytes OK
2025/01/09-22:26:22.609536 7f0ab9bff6c0 Delete type=0 #7
2025/01/09-22:26:22.609684 7f0ab9bff6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)

View File

@ -0,0 +1,5 @@
2025/01/09-20:31:12.546769 7f0aba7fc6c0 Delete type=3 #1
2025/01/09-22:05:02.682626 7f0ab9bff6c0 Level-0 table #5: started
2025/01/09-22:05:02.682649 7f0ab9bff6c0 Level-0 table #5: 0 bytes OK
2025/01/09-22:05:02.688999 7f0ab9bff6c0 Delete type=0 #3
2025/01/09-22:05:02.689300 7f0ab9bff6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)

Binary file not shown.

View File

View File

@ -0,0 +1 @@
MANIFEST-000006

View File

View File

@ -0,0 +1,7 @@
2025/01/09-22:06:01.218155 7f0abaffd6c0 Recovering log #4
2025/01/09-22:06:01.228492 7f0abaffd6c0 Delete type=3 #2
2025/01/09-22:06:01.228577 7f0abaffd6c0 Delete type=0 #4
2025/01/09-22:26:22.540188 7f0ab9bff6c0 Level-0 table #9: started
2025/01/09-22:26:22.540210 7f0ab9bff6c0 Level-0 table #9: 0 bytes OK
2025/01/09-22:26:22.580587 7f0ab9bff6c0 Delete type=0 #7
2025/01/09-22:26:22.609674 7f0ab9bff6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)

View File

@ -0,0 +1,5 @@
2025/01/09-20:31:12.516007 7f0aba7fc6c0 Delete type=3 #1
2025/01/09-22:05:02.675509 7f0ab9bff6c0 Level-0 table #5: started
2025/01/09-22:05:02.675540 7f0ab9bff6c0 Level-0 table #5: 0 bytes OK
2025/01/09-22:05:02.682505 7f0ab9bff6c0 Delete type=0 #3
2025/01/09-22:05:02.689288 7f0ab9bff6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)

Binary file not shown.

View File

@ -0,0 +1 @@
MANIFEST-000006

View File

View File

@ -0,0 +1,7 @@
2025/01/09-22:06:01.254140 7f0aba7fc6c0 Recovering log #4
2025/01/09-22:06:01.264214 7f0aba7fc6c0 Delete type=3 #2
2025/01/09-22:06:01.264273 7f0aba7fc6c0 Delete type=0 #4
2025/01/09-22:26:22.480492 7f0ab9bff6c0 Level-0 table #9: started
2025/01/09-22:26:22.480548 7f0ab9bff6c0 Level-0 table #9: 0 bytes OK
2025/01/09-22:26:22.511014 7f0ab9bff6c0 Delete type=0 #7
2025/01/09-22:26:22.609652 7f0ab9bff6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)

View File

@ -0,0 +1,5 @@
2025/01/09-20:31:12.562459 7f0abaffd6c0 Delete type=3 #1
2025/01/09-22:05:02.655239 7f0ab9bff6c0 Level-0 table #5: started
2025/01/09-22:05:02.655331 7f0ab9bff6c0 Level-0 table #5: 0 bytes OK
2025/01/09-22:05:02.668318 7f0ab9bff6c0 Delete type=0 #3
2025/01/09-22:05:02.689254 7f0ab9bff6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)

Binary file not shown.

View File

@ -405,6 +405,45 @@
display: flex;
align-items: center;
gap: 10px;
.armor-hp {
min-width: 20rem;
max-width: 20rem;
.input {
min-width: 3rem;
max-width: 3rem;
}
}
}
}
.wounds {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 10px;
.wound {
display: flex;
align-items: center;
gap: 10px;
.wound-description {
min-width: 16rem;
max-width: 16rem;
}
.wound-duration {
min-width: 3rem;
max-width: 3rem;
}
.wound-value {
min-width: 3rem;
max-width: 3rem;
}
.item-img {
width: 32px;
height: 32px;
margin: 5px 0 0 0;
}
.name {
min-width: 12rem;
}
}
}

View File

@ -28,6 +28,20 @@
}
}
.dialog-favor {
display: flex;
justify-content: center;
align-items: center;
select {
border: none;
background-color: rgba(0, 0, 0, 0.1);
color: var(--color-dark-2);
width: 120px;
text-align: center;
}
}
.main,
.dialog-damage,
.dialog-resource,

View File

@ -6,11 +6,27 @@
<div class="combat-detail">
<button class="action" data-action="rangedAttackDefense">{{localize
"LETHALFANTASY.Label.rangedAttackDefense"}}</button>
{{formField systemFields.combat.fields.armorHitPoints value=system.combat.armorHitPoints localize=true}}
{{formField systemFields.combat.fields.armorHitPoints value=system.combat.armorHitPoints localize=true classes="armor-hp"}}
<a data-action="armorHitPointsPlus"><i class="fa-solid fa-hexagon-plus"></i></a>
<a data-action="armorHitPointsMinus"><i class="fa-solid fa-hexagon-minus"></i></a>
</div>
</div>
</fieldset>
<fieldset>
<legend>{{localize "LETHALFANTASY.Label.wounds"}}</legend>
<div class="wounds">
{{#each system.hp.wounds as |wound idx|}}
<div class="wound">
Name:<input class="wound-description wound-data" type="text" data-type="String" data-index="{{@index}}" value="{{wound.description}}" data-name="description" >
HP:<input class="wound-value wound-data" type="text" data-type="Number" data-index="{{@index}}" value="{{wound.value}}" data-name="value" >
Duration:<input class="wound-duration wound-data" type="text" data-type="Number" data-index="{{@index}}" value="{{wound.duration}}" data-name="duration" >
</div>
{{/each}}
</div>
</fieldset>
<fieldset>
<legend>{{localize "LETHALFANTASY.Label.weapons"}}</legend>
<div class="weapons">

View File

@ -8,6 +8,11 @@
<div class="intro-right">
<span>{{upperFirst rollName}} : {{upperCase rollTarget.rollKey}}</span>
{{#if badResult}}
<span>{{localize "LETHALFANTASY.Label.otherResult"}} : {{badResult}}</span>
{{/if}}
{{#if rollTarget.weapon}}
<span>{{rollTarget.weapon.name}}</span>
{{/if}}

View File

@ -15,7 +15,15 @@
{{/if}}
</fieldSet>
{{#if hasFavor}}
<fieldSet class="dialog-favor">
<legend>{{localize "LETHALFANTASY.Roll.favorDisfavor"}}</legend>
<select name="favor" class="favor-choice" data-tooltip-direction="UP">
{{selectOptions choiceFavor selected=favor}}
</select>
</fieldSet>
{{/if}}
{{#if hasModifier}}
<fieldSet class="dialog-modifier">
<legend>{{localize "LETHALFANTASY.Roll.modifierBonusMalus"}}</legend>