Update confrontation

This commit is contained in:
2023-06-28 11:12:51 +02:00
parent 88385d2307
commit a3df0499a7
17 changed files with 424 additions and 66 deletions

View File

@ -122,6 +122,11 @@ export class EcrymeActorSheet extends ActorSheet {
let skillKey = $(event.currentTarget).data("skill-key")
this.actor.rollSkillConfront(categKey, skillKey)
});
html.find('.roll-weapon-confront').click((event) => {
const li = $(event.currentTarget).parents(".item")
let weaponId = li.data("item-id");
this.actor.rollWeaponConfront(weaponId)
});
html.find('.impact-modify').click((event) => {
let impactType = $(event.currentTarget).data("impact-type")

View File

@ -298,6 +298,12 @@ export class EcrymeActor extends Actor {
}
}
}
/* -------------------------------------------- */
modifyConfrontBonus( modifier ) {
let newBonus = this.system.internals.confrontbonus + bonus
this.update({'system.internals.confrontbonus': newBonus})
}
/* -------------------------------------------- */
spentSkillTranscendence(skill, value) {
@ -306,8 +312,18 @@ export class EcrymeActor extends Actor {
this.update({ [`system.skills.${skill.categKey}.skilllist.${skill.skillKey}.value`]: newValue })
}
/* -------------------------------------------- */
getBonusList() {
let bonusList = []
for(let i=0; i<this.system.internals.confrontbonus; i++) {
bonusList.push( { value: 1, type: "bonus", location: "mainpool"})
}
return bonusList
}
/* -------------------------------------------- */
getCommonRollData() {
this.system.internals.confrontbonus = 5 // TO BE REMOVED!!!!
let rollData = EcrymeUtility.getBasicRollData()
rollData.alias = this.name
rollData.actorImg = this.img
@ -315,8 +331,9 @@ export class EcrymeActor extends Actor {
rollData.img = this.img
rollData.isReroll = false
rollData.traits = duplicate(this.getRollTraits())
rollData.spleen = this.getSpleen()
rollData.ideal = this.getIdeal()
rollData.spleen = duplicate(this.getSpleen() || {})
rollData.ideal = duplicate(this.getIdeal() || {})
rollData.confrontBonus = this.getBonusList()
return rollData
}
@ -358,6 +375,25 @@ export class EcrymeActor extends Actor {
confrontStartDialog.render(true)
}
/* -------------------------------------------- */
async rollWeaponConfront(weaponId) {
let weapon = this.items.get(weaponId)
let rollData
if (weapon && weapon.system.weapontype == "melee") {
rollData = this.getCommonSkill("physical", "fencing")
} else {
rollData = this.getCommonSkill("physical", "shooting")
}
rollData.mode = "weapon"
rollData.weapon = duplicate(weapon)
rollData.title = game.i18n.localize("ECRY.ui.confrontation") + " : " + game.i18n.localize(rollData.skill.name)
rollData.executionTotal = rollData.skill.value
rollData.preservationTotal = rollData.skill.value
rollData.applyTranscendence = "execution"
let confrontStartDialog = await EcrymeConfrontStartDialog.create(this, rollData)
confrontStartDialog.render(true)
}
/* -------------------------------------------- */
rollWeapon(weaponId) {
let weapon = this.items.get(weaponId)

View File

@ -6,7 +6,10 @@ export const ECRYME_CONFIG = {
spleen: "Spleen",
ideal: "Ideal"
},
weaponTypes: {
"melee": "ECRY.ui.melee",
"ranged": "ECRY.ui.ranged"
},
traitLevel: [
{value: -3, text: "-3"},
{value: -2, text: "-2"},

View File

@ -2,9 +2,9 @@
import { EcrymeCommands } from "../app/ecryme-commands.js";
/* -------------------------------------------- */
const __maxImpacts = {superficial: 4, light: 3, serious: 2, major: 1}
const __nextImpacts = {superficial: "light", light: "serious", serious: "major", major: "major"}
const __maxImpacts = { superficial: 4, light: 3, serious: 2, major: 1 }
const __nextImpacts = { superficial: "light", light: "serious", serious: "major", major: "major" }
const __effect2Impact= [ "none", "superficial", "superficial", "light", "light", "serious", "serious", "major", "major" ]
/* -------------------------------------------- */
export class EcrymeUtility {
@ -49,7 +49,7 @@ export class EcrymeUtility {
})
Handlebars.registerHelper('valueAtIndex', function (arr, idx) {
return arr[idx];
})
})
Handlebars.registerHelper('for', function (from, to, incr, block) {
let accum = '';
for (let i = from; i <= to; i += incr)
@ -102,6 +102,89 @@ export class EcrymeUtility {
}
return actor
}
/* -------------------------------------------- */
static getImpactFromEffect(effectValue) {
if (effectValue >= __effect2Impact.length) {
return "major"
}
return __effect2Impact[effectValue]
}
/* -------------------------------------------- */
static async processConfrontation() {
let confront = {
type: "confront-data",
rollData1: this.confrontData1,
rollData2: this.confrontData2,
}
// Compute margin
confront.marginExecution = this.confrontData1.executionTotal - this.confrontData2.preservationTotal
confront.marginPreservation = this.confrontData1.preservationTotal - this.confrontData2.executionTotal
console.log(confront.marginExecution, confront.marginPreservation)
// Filter margin
let maxMargin // Dummy max
if ( confront.marginExecution > 0) { // Successful hit
// Limit with skill+spec
maxMargin = confront.rollData1.skill.value + ((confront.rollData1.spec) ? 2 : 0)
confront.marginExecution = Math.min(confront.marginExecution, maxMargin)
} else { // Failed hit
maxMargin = confront.rollData2.skill.value + ((confront.rollData2.spec) ? 2 : 0)
confront.marginExecution = -Math.min(Math.abs(confront.marginExecution), maxMargin)
}
if ( confront.marginPreservation > 0) { // Successful defense
// Limit with skill+spec
maxMargin = confront.rollData1.skill.value + ((confront.rollData1.spec) ? 2 : 0)
confront.marginPreservation = Math.min(confront.marginPreservation, maxMargin)
} else { // Failed defense
maxMargin = confront.rollData2.skill.value + ((confront.rollData2.spec) ? 2 : 0)
confront.marginPreservation = - Math.min(Math.abs(confront.marginPreservation), maxMargin)
}
// Compute effects
confront.effectExecution = confront.marginExecution
if (confront.rollData1.weapon && confront.marginExecution > 0) {
confront.effectExecution += confront.rollData1.weapon.system.effect
confront.impactExecution = this.getImpactFromEffect(confront.effectExecution)
}
if ( confront.marginExecution < 0) {
confront.bonus2 = -confront.marginExecution
}
confront.effectPreservation = confront.marginPreservation
if (confront.rollData2.weapon && confront.marginPreservation < 0) {
confront.effectPreservation = - (Math.abs(confront.marginPreservation) + confront.rollData2.weapon.system.effect)
confront.impactPreservation = this.getImpactFromEffect(Math.abs(confront.effectPreservation))
}
if ( confront.marginPreservation > 0) {
confront.bonus1 = -confront.marginPreservation
}
let msg = await this.createChatWithRollMode(this.confrontData1.alias, {
content: await renderTemplate(`systems/fvtt-ecryme/templates/chat/chat-confrontation-result.hbs`, confront)
})
msg.setFlag("world", "ecryme-rolldata", confront)
console.log("Confront result", confront)
this.lastConfront = confront
}
/* -------------------------------------------- */
static manageConfrontation(rollData) {
console.log("Confront", rollData)
// Auto - Reset
if (this.confrontData1 && this.confrontData2) {
this.confrontData1 = undefined
this.confrontData2 = undefined
}
// Then attribute
if (!this.confrontData1) {
this.confrontData1 = rollData
} else if (this.confrontData1 && this.confrontData1.rollId != rollData.rollId) {
this.confrontData2 = rollData
this.processConfrontation().catch("Error during confrontation processing")
} else {
ui.notifications.warn(game.i18n.localize("ECRY.warn.confrontalready"))
}
}
/* -------------------------------------------- */
static chatMenuManager(html, options) {
@ -132,15 +215,24 @@ export class EcrymeUtility {
/* -------------------------------------------- */
static async chatListeners(html) {
html.on("click", '.roll-destin', event => {
html.on("click", '.button-select-confront', event => {
let messageId = EcrymeUtility.findChatMessageId(event.currentTarget)
let message = game.messages.get(messageId)
let rollData = message.getFlag("world", "rolldata")
let actor = this.getActorFromRollData(rollData)
actor.incDecDestin(-1)
rollData.isReroll = true
this.rollEcryme(rollData).catch("Error on rollEcryme")
let rollData = message.getFlag("world", "ecryme-rolldata")
EcrymeUtility.manageConfrontation(rollData)
})
html.on("click", '.button-apply-impact', event => {
let messageId = EcrymeUtility.findChatMessageId(event.currentTarget)
let message = game.messages.get(messageId)
let actor = game.actors.get($(event.currentTarget).data("actor-id"))
actor.modifyImpact($(event.currentTarget).data("impact-type"), $(event.currentTarget).data("impact"), 1)
})
html.on("click", '.button-apply-bonus', event => {
let messageId = EcrymeUtility.findChatMessageId(event.currentTarget)
let message = game.messages.get(messageId)
let actor = game.actors.get($(event.currentTarget).data("actor-id"))
actor.modifyConfrontBonus( $(event.currentTarget).data("bonus") )
})
html.on("click", '.draw-tarot-card', event => {
let messageId = EcrymeUtility.findChatMessageId(event.currentTarget)
this.drawDeckCard(messageId)
@ -158,6 +250,7 @@ export class EcrymeUtility {
'systems/fvtt-ecryme/templates/items/partial-item-description.hbs',
'systems/fvtt-ecryme/templates/dialogs/partial-common-roll-dialog.hbs',
'systems/fvtt-ecryme/templates/dialogs/partial-confront-dice-area.hbs',
'systems/fvtt-ecryme/templates/dialogs/partial-confront-bonus-area.hbs',
'systems/fvtt-ecryme/templates/actors/partial-impacts.hbs',
]
return loadTemplates(templatePaths);
@ -254,7 +347,7 @@ export class EcrymeUtility {
}
/* -------------------------------------------- */
static chatDataSetup(content, modeOverride, isRoll = false, forceWhisper) {
static chatDataSetup(content, modeOverride, forceWhisper, isRoll = false) {
let chatData = {
user: game.user.id,
rollMode: modeOverride || game.settings.get("core", "rollMode"),
@ -276,7 +369,7 @@ export class EcrymeUtility {
static getImpactMax(impactLevel) {
return __maxImpacts[impactLevel]
}
static getNextImpactLevel(impactLevel) {
static getNextImpactLevel(impactLevel) {
return __nextImpacts[impactLevel]
}
/* -------------------------------------------- */
@ -288,7 +381,9 @@ export class EcrymeUtility {
rollMode = rollMode ?? game.settings.get("core", "rollMode");
switch (rollMode) {
case "blindroll": //GM only
whisper = this.getUsers(user => user.isGM);
blind = true;
break
case "gmroll": //GM + rolling player
whisper = this.getUsers(user => user.isGM);
break;
@ -313,7 +408,8 @@ export class EcrymeUtility {
rollData.margin = rollData.total - rollData.difficulty
if (rollData.total > rollData.difficulty) {
rollData.isSuccess = true
rollData.margin = Math.min(rollData.margin, rollData.skill.value)
let maxMargin = rollData.skill.value + (rollData.spec) ? 2 : 0
rollData.margin = Math.min(rollData.margin, maxMargin)
}
}
@ -388,7 +484,6 @@ export class EcrymeUtility {
content: await renderTemplate(`systems/fvtt-ecryme/templates/chat/chat-generic-result.hbs`, rollData)
})
msg.setFlag("world", "ecryme-rolldata", rollData)
console.log("Rolldata result", rollData)
}
@ -501,6 +596,7 @@ export class EcrymeUtility {
static getBasicRollData() {
let rollData = {
rollId: randomID(16),
type: "roll-data",
bonusMalusPerso: 0,
bonusMalusSituation: 0,
bonusMalusDef: 0,

View File

@ -9,7 +9,7 @@ export class EcrymeConfrontDialog extends Dialog {
let options = mergeObject(super.defaultOptions, {
classes: ["fvtt-ecryme ecryme-confrontation-dialog"],
dragDrop: [{ dragSelector: ".confront-dice-container", dropSelector: null }],
width: 540, height: 'fit-content', 'z-index': 99999
width: 620, height: 'fit-content', 'z-index': 99999
});
let html = await renderTemplate('systems/fvtt-ecryme/templates/dialogs/confront-dialog.hbs', rollData);
@ -50,6 +50,7 @@ export class EcrymeConfrontDialog extends Dialog {
let msg = await EcrymeUtility.createChatMessage(this.rollData.alias, "blindroll", {
content: await renderTemplate(`systems/fvtt-ecryme/templates/chat/chat-confrontation-pending.hbs`, this.rollData)
})
console.log("MSG", this.rollData)
msg.setFlag("world", "ecryme-rolldata", this.rollData)
}
@ -61,16 +62,26 @@ export class EcrymeConfrontDialog extends Dialog {
let button = this.buttonDisabled
setTimeout(function () { $(".launchConfront").attr("disabled", button) }, 180)
}
/* ------------------ -------------------------- */
_onDragStart(event) {
super._onDragStart(event)
console.log("DRAG", event)
const diceData = {
diceIndex: $(event.srcElement).data("dice-idx"),
diceValue: $(event.srcElement).data("dice-value"),
let dragType = $(event.srcElement).data("drag-type")
let diceData = {}
console.log("DRAGTYPE", dragType)
if (dragType == "dice") {
diceData = {
dragType: "dice",
diceIndex: $(event.srcElement).data("dice-idx"),
diceValue: $(event.srcElement).data("dice-value"),
}
} else {
diceData = {
dragType: "bonus",
bonusIndex: $(event.srcElement).data("bonus-idx"),
bonusValue: 1
}
}
event.dataTransfer.setData("text/plain", JSON.stringify(diceData));
}
@ -78,28 +89,42 @@ export class EcrymeConfrontDialog extends Dialog {
/* -------------------------------------------- */
_onDrop(event) {
let dataJSON = event.dataTransfer.getData('text/plain')
console.log("DICEDATA", dataJSON)
let data = JSON.parse(dataJSON)
let idx = Number(data.diceIndex)
//console.log("DATA", data, event, event.srcElement.className)
if (event.srcElement.className.includes("execution")) {
this.rollData.availableDices[idx].location = "execution"
}
if (event.srcElement.className.includes("preservation")) {
this.rollData.availableDices[idx].location = "preservation"
}
if (event.srcElement.className.includes("dice-list")) {
this.rollData.availableDices[idx].location = "mainpool"
}
if (this.rollData.availableDices.filter(d => d.location == "execution").length == 2 && this.rollData.availableDices.filter(d => d.location == "preservation").length == 2) {
this.buttonDisabled = false
if ( data.dragType == "dice") {
let idx = Number(data.diceIndex)
//console.log("DATA", data, event, event.srcElement.className)
if (event.srcElement.className.includes("execution") &&
this.rollData.availableDices.filter(d => d.location == "execution").length < 2) {
this.rollData.availableDices[idx].location = "execution"
}
if (event.srcElement.className.includes("preservation") &&
this.rollData.availableDices.filter(d => d.location == "preservation").length < 2) {
this.rollData.availableDices[idx].location = "preservation"
}
if (event.srcElement.className.includes("dice-list")) {
this.rollData.availableDices[idx].location = "mainpool"
}
if (this.rollData.availableDices.filter(d => d.location == "execution").length == 2 && this.rollData.availableDices.filter(d => d.location == "preservation").length == 2) {
this.buttonDisabled = false
} else {
this.buttonDisabled = true
}
} else {
this.buttonDisabled = true
let idx = Number(data.bonusIndex)
if (event.srcElement.className.includes("execution")) {
this.rollData.confrontBonus[idx].location = "execution"
}
if (event.srcElement.className.includes("preservation")) {
this.rollData.confrontBonus[idx].location = "preservation"
}
if (event.srcElement.className.includes("bonus-list")) {
this.rollData.confrontBonus[idx].location = "mainpool"
}
}
// Manage total values
this.computeTotals().catch("Error on dice pools")
this.computeTotals()
}
/* -------------------------------------------- */
@ -115,20 +140,27 @@ export class EcrymeConfrontDialog extends Dialog {
}
/* -------------------------------------------- */
async computeTotals() {
computeTotals() {
let rollData = this.rollData
let actor = game.actors.get(rollData.actorId)
rollData.executionTotal = rollData.availableDices.filter(d => d.location == "execution").reduce((previous, current) => {
return previous + current.result
}, rollData.skill.value)
rollData.executionTotal = rollData.confrontBonus.filter(d => d.location == "execution").reduce((previous, current) => {
return previous + 1
}, rollData.executionTotal)
rollData.preservationTotal = rollData.availableDices.filter(d => d.location == "preservation").reduce((previous, current) => {
return previous + current.result
}, rollData.skill.value)
rollData.preservationTotal = rollData.confrontBonus.filter(d => d.location == "preservation").reduce((previous, current) => {
return previous + 1
}, rollData.preservationTotal)
this.processTranscendence()
if (rollData.selectedSpecs && rollData.selectedSpecs.length > 0) {
rollData.spec = actor.getSpecialization(rollData.selectedSpecs[0])
rollData.spec = duplicate(actor.getSpecialization(rollData.selectedSpecs[0]))
this.rollData.executionTotal += "+2"
this.rollData.preservationTotal += "+2"
}
@ -161,7 +193,7 @@ export class EcrymeConfrontDialog extends Dialog {
rollData.preservationTotal += rollData.bonusMalusTraits
rollData.preservationTotal += rollData.bonusMalusPerso
this.refreshDialog()
this.refreshDialog().catch("Error on refresh confrontation dialog")
}
/* -------------------------------------------- */