Compare commits

...

6 Commits

Author SHA1 Message Date
884823a1bc Init again !!!! 2022-12-02 13:16:42 +01:00
399c22d623 Init again !!!! 2022-12-02 13:15:48 +01:00
085265df5d initiative bugfix 2022-12-01 23:57:33 +01:00
593db9ba5b initiative bugfix 2022-12-01 23:46:27 +01:00
ac96f3ca67 Enhance initiative + fix combat 2022-11-30 20:58:27 +01:00
b2fe67ab05 Enhance tokens/actor management + auto effects 2022-11-30 12:12:44 +01:00
10 changed files with 205 additions and 48 deletions

View File

@ -182,7 +182,8 @@
"BOL.ui.armornoformula": "L'armure {protect.name} n'a pas de formule pour la protection !",
"BOL.ui.selectactor": "Selectionnez votre personnage pour utiliser la macro",
"BOL.ui.itemnotfound": "Impossible de trouver l'objet de cette macro",
"BOL.ui.noinit": "Pas d'initiative trouvée, veuillez en enregistrer une.",
"BOL.featureCategory.origins": "Origines",
"BOL.featureCategory.races": "Races",
"BOL.featureCategory.careers": "Carrières",
@ -477,6 +478,7 @@
"BOL.chat.rollbougette": "Jet de Bougette",
"BOL.chat.bougettesuccess": "Votre bougette reste inchangée !",
"BOL.chat.bougettefailure": "Vous avez trop dépensé, votre bougette s'est réduite...",
"BOL.chat.initiative": "Rang d'intiative (10 à 1)",
"BOL.dialog.soeasy": "Inmanquable (+4)",
"BOL.dialog.veryeasy": "Trés Facile (+2)",

View File

@ -141,6 +141,7 @@ export class BoLActorSheet extends ActorSheet {
formData.ammos = this.actor.ammos
formData.misc = this.actor.misc
formData.combat = this.actor.buildCombat()
formData.initiativeRank = this.actor.getInitiativeRank()
//formData.combatCreature = this.actor.buildCombatCreature()
formData.features = this.actor.buildFeatures()
formData.isGM = game.user.isGM

View File

@ -618,26 +618,72 @@ export class BoLActor extends Actor {
let lastHP = await this.getFlag("world", hpID)
if (lastHP != this.system.resources.hp.value && game.user.isGM) { // Only GM sends this
await this.setFlag("world", hpID, this.system.resources.hp.value)
let prone = this.effects.find( ef => ef.label == "EFFECT.StatusProne")
let dead = this.effects.find( ef => ef.label == "EFFECT.StatusDead")
if (this.system.resources.hp.value <= 0) {
if ( !prone) {
await this.createEmbeddedDocuments("ActiveEffect", [
{label: 'EFFECT.StatusProne', icon: 'icons/svg/falling.svg', flags: { core: { statusId: 'prone' } } }
])
}
if ( this.system.resources.hp.value < -5 && !dead) {
await this.createEmbeddedDocuments("ActiveEffect", [
{label: 'EFFECT.StatusDead', icon: 'icons/svg/skull.svg', flags: { core: { statusId: 'dead' } } }
])
}
ChatMessage.create({
alias: this.name,
whisper: BoLUtility.getWhisperRecipientsAndGMs(this.name),
content: await renderTemplate('systems/bol/templates/chat/chat-vitality-zero.hbs', { name: this.name, img: this.img, hp: this.system.resources.hp.value })
})
} else {
if ( prone ) {
await this.deleteEmbeddedDocuments("ActiveEffect", [ prone.id ] )
}
if ( dead ) {
await this.deleteEmbeddedDocuments("ActiveEffect", [ dead.id ] )
}
}
}
}
/*-------------------------------------------- */
registerInit(initScore, isCritical, isFumble) {
this.update({ 'system.combat.lastinit': initScore, 'system.combat.iscritical': isCritical, 'system.combat.isfumble': isFumble })
async registerInit(rollData) {
rollData.actor = undefined // Cleanup if present
await this.setFlag("world", "last-initiative", rollData)
}
/*-------------------------------------------- */
getLastInitData() {
return this.system.combat
getInitiativeRank(rollData = undefined) {
if (!rollData) {
rollData = this.getFlag("world", "last-initiative")
}
let fvttInit = 4 // Pietaille par defaut
if (this.type == 'character' ) {
fvttInit = 5
if (!rollData) {
fvttInit = -1
} else {
if (rollData.isLegendary) {
fvttInit = 10
} else if (rollData.isCritical) {
fvttInit = 9
} else if (rollData.isSuccess ) {
fvttInit = 8
} else if (rollData.isFumble) {
fvttInit = 3
}
}
}
if ( this.getCharType() == 'adversary') {
fvttInit = 7
}
if ( this.getCharType() == 'tough') {
fvttInit = 6
}
return fvttInit
}
/*-------------------------------------------- */
async subHeroPoints(nb) {
let newHeroP = this.system.resources.hero.value - nb;

View File

@ -41,7 +41,7 @@ Hooks.once('init', async function () {
*/
CONFIG.Combat.initiative = {
formula: "2d6+@attributes.mind.value+@aptitudes.init.value",
decimals: 3
decimals: 2
};
// Define custom Entity classes
@ -120,7 +120,7 @@ function welcomeMessage() {
Hooks.once('ready', async function () {
BoLUtility.ready()
BoLCharacterSummary.ready()
BoLCharacterSummary.ready()
registerUsageCount('bol')

View File

@ -36,6 +36,7 @@ export class BoLRoll {
let rollData = {
mode: mode,
actorId: actor.id,
tokenId: actor.token?.id,
img: actor.img,
attribute: attribute,
attrValue: attribute.value,
@ -352,7 +353,7 @@ export class BoLRoll {
html.find('#attr').change((event) => {
let attrKey = event.currentTarget.value
let actor = game.actors.get( this.rollData.actorId)
let actor = BoLUtility.getActorFromRollData(this.rollData)
this.rollData.attribute = duplicate(actor.system.attributes[attrKey])
this.rollData.attrValue = actor.system.attributes[attrKey].value
this.rollData.bolApplicableEffects = this.updateApplicableEffects(this.rollData)
@ -360,7 +361,7 @@ export class BoLRoll {
})
html.find('#apt').change((event) => {
let aptKey = event.currentTarget.value
let actor = game.actors.get( this.rollData.actorId)
let actor = BoLUtility.getActorFromRollData(this.rollData)
this.rollData.aptitude = duplicate(actor.system.aptitudes[aptKey])
this.rollData.aptValue = actor.system.aptitudes[aptKey].value
this.rollData.bolApplicableEffects = this.updateApplicableEffects(this.rollData)
@ -432,7 +433,7 @@ export class BoLRoll {
// initialize default flags/values
const rollOptionTpl = `systems/bol/templates/dialogs/${rollData.mode}-roll-dialog.hbs`
let actor = game.actors.get( rollData.actorId )
let actor = BoLUtility.getActorFromRollData(rollData)
let defender
if ( rollData.targetId) {
let token = game.scenes.current.tokens.get(rollData.targetId)
@ -547,7 +548,7 @@ export class BoLDefaultRoll {
async roll() {
const r = new Roll(this.rollData.formula)
// console.log("Roll formula", this.rollData.formula)
//console.log("Roll formula", this.rollData.formula)
await r.roll({ "async": false })
const activeDice = r.terms[0].results.filter(r => r.active)
const diceTotal = activeDice.map(r => r.result).reduce((a, b) => a + b)
@ -562,14 +563,15 @@ export class BoLDefaultRoll {
//this.rollData.isRealCritical = true
//this.rollData.isFumble = true
let actor = game.actors.get( this.rollData.actorId)
let actor = BoLUtility.getActorFromRollData(this.rollData)
if (this.rollData.reroll == undefined) {
this.rollData.reroll = actor.heroReroll()
}
if (this.rollData.registerInit) {
actor.registerInit(r.total, this.rollData.isCritical, this.rollData.isFumble)
actor.registerInit(this.rollData)
this.rollData.initiativeRank = actor.getInitiativeRank(this.rollData)
}
if (this.rollData.isSuccess && this.rollData.mode == "spell") { // PP cost management
this.rollData.remainingPP = actor.spendPowerPoint(this.rollData.ppCost + this.rollData.ppCostArmor)
@ -586,7 +588,7 @@ export class BoLDefaultRoll {
/* -------------------------------------------- */
async sendChatMessage() {
let actor = game.actors.get( this.rollData.actorId)
let actor = BoLUtility.getActorFromRollData(this.rollData)
this._buildChatMessage(this.rollData).then( async msgFlavor => {
let msg = await this.rollData.roll.toMessage({
user: game.user.id,
@ -633,7 +635,7 @@ export class BoLDefaultRoll {
/* -------------------------------------------- */
async sendDamageMessage() {
let actor = game.actors.get( this.rollData.actorId)
let actor = BoLUtility.getActorFromRollData(this.rollData)
this._buildDamageChatMessage(this.rollData).then(async msgFlavor => {
let msg = await this.rollData.damageRoll.toMessage({
user: game.user.id,
@ -648,7 +650,7 @@ export class BoLDefaultRoll {
/* -------------------------------------------- */
getDamageAttributeValue(attrDamage, actorId = undefined) {
let actor = game.actors.get( (actorId) ? actorId: this.rollData.actorId)
let actor = BoLUtility.getActorFromRollData(this.rollData)
return actor.getDamageAttributeValue( attrDamage )
}

View File

@ -10,6 +10,8 @@ Init order =
3 - Echec critique
*/
import { BoLUtility } from "../system/bol-utility.js";
export class BoLCombatManager extends Combat {
@ -18,35 +20,12 @@ export class BoLCombatManager extends Combat {
console.log(`${game.system.title} | Combat.rollInitiative()`, ids, formula, messageOptions);
// Structure input data
ids = typeof ids === "string" ? [ids] : ids;
const currentId = this.combatant._id;
//const currentId = this.combatant.id;
// calculate initiative
for (let cId = 0; cId < ids.length; cId++) {
const combatant = this.combatants.get(ids[cId]);
let fvttInit = 5
//console.log("TYPE", combatant.actor.type)
if (combatant.actor.type == 'character') {
let initData = combatant.actor.getLastInitData()
console.log("Init data !!!", initData)
if (initData.isLegendary) {
fvttInit = 10
} else if (initData.isCritical) {
fvttInit = 9
} else if (initData.lastinit >= 9) {
fvttInit = 8
} else if (initData.isFumble) {
fvttInit = 3
}
} else {
fvttInit = 4 // Pietaille par defautco
//console.log("ACTOR", combatant.actor.getCharType())
if ( combatant.actor.getCharType() == 'adversary') {
fvttInit = 7
}
if ( combatant.actor.getCharType() == 'tough') {
fvttInit = 6
}
}
const combatant = this.combatants.get(ids[cId])
let fvttInit = combatant.actor.getInitiativeRank()
fvttInit += (cId / 100)
await this.updateEmbeddedDocuments("Combatant", [{ _id: ids[cId], initiative: fvttInit }]);
}

View File

@ -76,12 +76,24 @@ export class BoLUtility {
static getLogoTopLeft() {
return this.logoTopLeft
}
/* -------------------------------------------- */
static getActorFromRollData(rollData) {
let actor = game.actors.get( rollData.actorId)
if (rollData.tokenId) {
let token = canvas.tokens.placeables.find(t => t.id == rollData.tokenId)
if (token) {
actor = token.actor
}
}
return actor
}
/* -------------------------------------------- */
static async ready() {
//$("#logo").attr("src", this.getLogoTopLeft() )
$("#logo").css("content", `url(${this.getLogoTopLeft()})`)
CONFIG.statusEffects = duplicate(game.bol.config.statusEffects)
}
/* -------------------------------------------- */
@ -166,7 +178,7 @@ export class BoLUtility {
static getOtherWhisperRecipients(name) {
let users = []
for (let user of game.users) {
if (!user.isGM && user.name != name) {
if ( !user.isGM && user.name != name) {
users.push(user.id)
}
}

View File

@ -342,4 +342,113 @@ BOL.bolEffectModifier = {
"+6": "+6",
"+8": "+8",
}
BOL.statusEffects = [
{
"id": "dead",
"label": "EFFECT.StatusDead",
"icon": "icons/svg/skull.svg"
},
{
"id": "unconscious",
"label": "EFFECT.StatusUnconscious",
"icon": "icons/svg/unconscious.svg"
},
{
"id": "sleep",
"label": "EFFECT.StatusAsleep",
"icon": "icons/svg/sleep.svg"
},
{
"id": "stun",
"label": "EFFECT.StatusStunned",
"icon": "icons/svg/daze.svg"
},
{
"id": "prone",
"label": "EFFECT.StatusProne",
"icon": "icons/svg/falling.svg"
},
{
"id": "restrain",
"label": "EFFECT.StatusRestrained",
"icon": "icons/svg/net.svg"
},
{
"id": "paralysis",
"label": "EFFECT.StatusParalysis",
"icon": "icons/svg/paralysis.svg"
},
{
"id": "fly",
"label": "EFFECT.StatusFlying",
"icon": "icons/svg/wing.svg"
},
{
"id": "blind",
"label": "EFFECT.StatusBlind",
"icon": "icons/svg/blind.svg"
},
{
"id": "deaf",
"label": "EFFECT.StatusDeaf",
"icon": "icons/svg/deaf.svg"
},
{
"id": "silence",
"label": "EFFECT.StatusSilenced",
"icon": "icons/svg/silenced.svg"
},
{
"id": "fear",
"label": "EFFECT.StatusFear",
"icon": "icons/svg/terror.svg"
},
{
"id": "burning",
"label": "EFFECT.StatusBurning",
"icon": "icons/svg/fire.svg"
},
{
"id": "frozen",
"label": "EFFECT.StatusFrozen",
"icon": "icons/svg/frozen.svg"
},
{
"id": "shock",
"label": "EFFECT.StatusShocked",
"icon": "icons/svg/lightning.svg"
},
{
"id": "disease",
"label": "EFFECT.StatusDisease",
"icon": "icons/svg/biohazard.svg"
},
{
"id": "poison",
"label": "EFFECT.StatusPoison",
"icon": "icons/svg/poison.svg"
},
{
"id": "curse",
"label": "EFFECT.StatusCursed",
"icon": "icons/svg/sun.svg"
},
{
"id": "invisible",
"label": "EFFECT.StatusInvisible",
"icon": "icons/svg/invisible.svg"
},
{
"id": "target",
"label": "EFFECT.StatusTarget",
"icon": "icons/svg/target.svg"
},
{
"id": "eye",
"label": "EFFECT.StatusMarked",
"icon": "icons/svg/eye.svg"
}
]
BOL.debug = false;

View File

@ -14,7 +14,7 @@
],
"url": "https://www.uberwald.me/gitea/public/bol",
"license": "LICENSE.txt",
"version": "10.4.5",
"version": "10.4.10",
"compatibility": {
"minimum": "10",
"verified": "10",
@ -203,7 +203,7 @@
],
"socket": true,
"manifest": "https://www.uberwald.me/gitea/public/bol/raw/v10/system.json",
"download": "https://www.uberwald.me/gitea/public/bol/archive/bol-v10.4.5.zip",
"download": "https://www.uberwald.me/gitea/public/bol/archive/bol-v10.4.10.zip",
"background": "systems/images/map_lemurie.webp",
"gridDistance": 1.5,
"gridUnits": "m",

View File

@ -34,6 +34,12 @@
</div>
{{/if}}
{{#if initiativeRank}}
<div>
{{localize "BOL.chat.initiative"}}: {{initiativeRank}}
</div>
{{/if}}
{{#if (eq mode "bougette")}}
<div>
{{localize "BOL.chat.rollbougette"}} :