Ehance UI and weapon damages
This commit is contained in:
@ -38,7 +38,7 @@ export class VadentisActorSheet extends ActorSheet {
|
||||
data.equipements = this.actor.getEquipements();
|
||||
|
||||
data.optionsBase = VadentisUtility.createDirectOptionList(0, 50);
|
||||
data.optionsMalus = VadentisUtility.createDirectOptionList(-50, 0);
|
||||
data.optionsMalus = VadentisUtility.createDirectReverseOptionList(-50, 0);
|
||||
data.optionsBonus = VadentisUtility.createDirectOptionList(0, 50);
|
||||
data.optionsPV = VadentisUtility.createOptionList(-50, 200);
|
||||
data.optionsPE = VadentisUtility.createOptionList(-50, 200);
|
||||
@ -103,6 +103,17 @@ export class VadentisActorSheet extends ActorSheet {
|
||||
const weapon = this.actor.getOwnedItem(li.data("item-id"));
|
||||
this.actor.rollWeapon(weapon);
|
||||
});
|
||||
html.find('.weapon-damage').click((event) => {
|
||||
const li = $(event.currentTarget).parents(".item");
|
||||
const weapon = this.actor.getOwnedItem(li.data("item-id"));
|
||||
this.actor.rollDamage(weapon, 'damage');
|
||||
});
|
||||
html.find('.weapon-damage-critical').click((event) => {
|
||||
const li = $(event.currentTarget).parents(".item");
|
||||
const weapon = this.actor.getOwnedItem(li.data("item-id"));
|
||||
this.actor.rollDamage(weapon, 'criticaldamage');
|
||||
});
|
||||
|
||||
html.find('.competence-base').change((event) => {
|
||||
let skillName = event.currentTarget.attributes.skillname.value;
|
||||
this.actor.updateCompetence(skillName, "base", parseInt(event.target.value));
|
||||
|
@ -1,5 +1,9 @@
|
||||
/* -------------------------------------------- */
|
||||
import { VadentisUtility } from "./vadentis-utility.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
const MIN_PV = -50;
|
||||
const MIN_PE = -50;
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/**
|
||||
@ -114,36 +118,84 @@ export class VadentisActor extends Actor {
|
||||
myRoll.evaluate();
|
||||
myRoll.toMessage( { flavor: `Lancer de ${name} : ${devotionSort.name} (${formulaFull})` } );
|
||||
|
||||
if (myRoll.total >= devotionSort.data.difficulty) {
|
||||
if (myRoll.results[0] > 1 && myRoll.total >= devotionSort.data.difficulty) {
|
||||
let content = `${this.name} a réussi son ${name} et perd ${devotionSort.data.pe} Points d'Energie. L'effet suivant se produit: <br>${devotionSort.data.effect}`;
|
||||
let newEnergie = this.data.data.stats.pointsenergie.value - devotionSort.data.pe;
|
||||
await this.update( {'data.stats.pointsenergie.value': newEnergie });
|
||||
|
||||
if ( devotionSort.data.damage != "") {
|
||||
let degatsText = `<br>Et provoque les dégats suivants : `;
|
||||
let formula = devotionSort.data.damage;
|
||||
if (myRoll.results[0] == 20 ) { // Critique ?
|
||||
content += `<br>Et provoque les dégats critiques suivants : ${devotionSort.data.damagecritical}`;
|
||||
} else {
|
||||
content += `<br>Et provoque les dégats suivants : ${devotionSort.data.damage}`;
|
||||
degatsText += `<br>Et provoque les dégats critiques suivants : `;
|
||||
formula = devotionSort.data.damagecritical;
|
||||
}
|
||||
content += degatsText;
|
||||
/*let myRoll = new Roll(formula);
|
||||
myRoll.evaluate();
|
||||
if (game.modules.get("dice-so-nice") && game.modules.get("dice-so-nice").active) {
|
||||
await game.dice3d.showForRoll(degatsRoll, game.user, true);
|
||||
}
|
||||
content += myRoll.total + `(${devotionSort.data.damagecritical})`; */
|
||||
content += `${devotionSort.data.damagecritical}`;
|
||||
}
|
||||
if ( newEnergie < 0) {
|
||||
content += `<br>Les Points d'Energie de ${this.name} sont négatifs ! Il convient d'éditer ses Points de Vie en conséquence.`;
|
||||
content += `<br><strong>Attention</strong> : Les Points d'Energie de ${this.name} sont négatifs ! Il convient d'éditer ses Points de Vie en conséquence.`;
|
||||
}
|
||||
ChatMessage.create( { content: content} );
|
||||
} else {
|
||||
ChatMessage.create( { content: `${this.name} a échoué son lancer de ${name}` } );
|
||||
if (myRoll.results[0] == 1 ) { // Critique ?
|
||||
ChatMessage.create( { content: `${this.name} a fait un <strong>échec critique</strong> à son lancer de ${name}` } );
|
||||
} else {
|
||||
ChatMessage.create( { content: `${this.name} a échoué son lancer de ${name}` } );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollDamage( weapon, damageType ) {
|
||||
let formula = VadentisUtility.processDamageString( weapon.data.data[damageType], this );
|
||||
let degatsRoll = await VadentisUtility.processRoll( formula );
|
||||
|
||||
ChatMessage.create( { content: `${this.name} frappe avec ${weapon.name} et produit ${degatsRoll.total} Points de Dégâts (${formula}).` } );
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async applyDamage( damageValue ) {
|
||||
let pvData = this.data.data.stats.pointsvie;
|
||||
let newValue = Math.max( pvData.value - damageValue, MIN_PV);
|
||||
await this.update( {'data.stats.pointsvie.value': newValue });
|
||||
ChatMessage.create( { content: `${this.name} vient de perdre ${damageValue} Points de Vie. Ses Points de Vie actuels sont désormais de ${newValue}.` } );
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
_getCombatValue(mydata) {
|
||||
if ( Number(mydata.base)) {
|
||||
return mydata.base + mydata.malus + mydata.bonus;
|
||||
}else {
|
||||
return Number(mydata.base[0]) + Number(mydata.malus[0]) + Number(mydata.bonus[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getInitiativeScore( ) {
|
||||
let initData = this.data.data.combat.initiative;
|
||||
return this._getCombatValue( initData);
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getDefenseScore( ) {
|
||||
let defenseData = this.data.data.combat.defense;
|
||||
return defenseData.base + defenseData.malus + defenseData.bonus;
|
||||
return this._getCombatValue( defenseData);
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getForceScore( ) {
|
||||
let forceData = this.data.data.combat.force;
|
||||
return this._getCombatValue( forceData);
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getAttaqueScore( ) {
|
||||
let attaqueData = this.data.data.combat.attaque;
|
||||
return attaqueData.base + attaqueData.malus + attaqueData.bonus;
|
||||
return this._getCombatValue( attaqueData);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -193,7 +245,7 @@ export class VadentisActor extends Actor {
|
||||
/* -------------------------------------------- */
|
||||
rollCombat( combatName ) {
|
||||
let stat = this.data.data.combat[combatName];
|
||||
let statValue = stat.base + stat.malus + stat.bonus;
|
||||
let statValue = this._getCombatValue( stat );
|
||||
let formulaFull = `1d20+${stat.base}+${stat.malus}+${stat.bonus}`;
|
||||
let myRoll = new Roll("1d20+"+statValue);
|
||||
myRoll.evaluate();
|
||||
|
@ -3,5 +3,43 @@ import { VadentisUtility } from "./vadentis-utility.js";
|
||||
/* -------------------------------------------- */
|
||||
export class VadentisCombat extends Combat {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollInitiative(ids, formula = undefined, messageOptions = {} ) {
|
||||
console.log("Initiative is requested !!!");
|
||||
|
||||
ids = typeof ids === "string" ? [ids] : ids;
|
||||
const currentId = this.combatant._id;
|
||||
for (let cId = 0; cId < ids.length; cId++) {
|
||||
const c = this.getCombatant(ids[cId]);
|
||||
let initBonus = c.actor ? c.actor.getInitiativeScore() : 0;
|
||||
console.log("Init for ", initBonus);
|
||||
const roll = super._getInitiativeRoll(c, "1d20+"+initBonus);
|
||||
|
||||
if (roll.total <= 0) roll.total = 0;
|
||||
console.log("Compute init for", roll.total);
|
||||
await this.updateEmbeddedEntity("Combatant", { _id: c._id, initiative: roll.total });
|
||||
|
||||
// Send a chat message
|
||||
let rollMode = messageOptions.rollMode || game.settings.get("core", "rollMode");
|
||||
let messageData = mergeObject(
|
||||
{
|
||||
speaker: {
|
||||
scene: canvas.scene._id,
|
||||
actor: c.actor ? c.actor._id : null,
|
||||
token: c.token._id,
|
||||
alias: c.token.name,
|
||||
sound: CONFIG.sounds.dice,
|
||||
},
|
||||
flavor: `${c.token.name} a fait son jet d'Initiative (1d20+${initBonus})
|
||||
<br>
|
||||
`,
|
||||
},
|
||||
messageOptions
|
||||
);
|
||||
roll.toMessage(messageData, { rollMode, create: true });
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,11 +18,22 @@ export class VadentisUtility extends Entity {
|
||||
return loadTemplates(templatePaths);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static updateCombat( combat, round, diff, id ) {
|
||||
if (game.user.isGM && combat.data.round != 0 && combat.turns && combat.data.active) {
|
||||
let turn = combat.turns.find(t => t.tokenId == combat.current.tokenId);
|
||||
ChatMessage.create( { content: `Round ${combat.data.round} : C'est au tour de ${turn.actor.name}<br>` } );
|
||||
|
||||
canvas.tokens.get(turn.token._id).control();
|
||||
canvas.tokens.cycleTokens(1, true);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static createOptionList( min, max) {
|
||||
let options = ""
|
||||
for(let i=min; i<=max; i++) {
|
||||
options+= `<option value="${i}">${i}</option>\n`;
|
||||
options += `<option value="${i}">${i}</option>\n`;
|
||||
}
|
||||
return options;
|
||||
}
|
||||
@ -31,10 +42,18 @@ export class VadentisUtility extends Entity {
|
||||
static createDirectOptionList( min, max) {
|
||||
let options = {};
|
||||
for(let i=min; i<=max; i++) {
|
||||
options[i] = i;
|
||||
options[`${i}`] = `${i}`;
|
||||
}
|
||||
return options;
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
static createDirectReverseOptionList( min, max) {
|
||||
let options = {};
|
||||
for(let i=max; i>=min; i--) {
|
||||
options[`${i}`] = `${i}`;
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static getTarget() {
|
||||
@ -46,6 +65,25 @@ export class VadentisUtility extends Entity {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static processDamageString( formula, actor ) {
|
||||
let workFormula = formula.toLowerCase();
|
||||
if ( workFormula.includes('bonus de force')) {
|
||||
workFormula = workFormula.replace('bonus de force', actor.getForceScore());
|
||||
}
|
||||
return workFormula;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async processRoll( formula ) {
|
||||
let myRoll = new Roll(formula);
|
||||
myRoll.evaluate();
|
||||
if (game.modules.get("dice-so-nice") && game.modules.get("dice-so-nice").active) {
|
||||
await game.dice3d.showForRoll(myRoll, game.user, true);
|
||||
}
|
||||
return myRoll;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async performAttack( combatData) {
|
||||
let attacker = game.actors.get(combatData.attackerActorId);
|
||||
@ -53,16 +91,27 @@ export class VadentisUtility extends Entity {
|
||||
if( attacker && defender) {
|
||||
let defense = defender.getDefenseScore();
|
||||
let attaque = attacker.getAttaqueScore();
|
||||
console.log("Attaque : ", attaque);
|
||||
let myRoll = new Roll("1d20"+attaque);
|
||||
myRoll.evaluate()
|
||||
if (game.modules.get("dice-so-nice") && game.modules.get("dice-so-nice").active) {
|
||||
await game.dice3d.showForRoll(myRoll, game.user, true);
|
||||
}
|
||||
if (myRoll.total >= defense) { // Success !
|
||||
ChatMessage.create( { content: `${attacker.name} a réussi son attaque sur ${defender.name} (${myRoll.total} / ${defense}) !<br> Les dégâts sont de : ${combatData.arme.data.damage}`});
|
||||
|
||||
let myRoll = await this.processRoll("1d20+"+attaque);
|
||||
if (myRoll.results[0] > 1 && myRoll.total >= defense) { // Success !
|
||||
let degats = `normaux : ${combatData.arme.data.damage}`;
|
||||
let formula = combatData.arme.data.damage.toLowerCase();
|
||||
if ( myRoll.results[0] == 20) {
|
||||
degats = `critiques : ${combatData.arme.data.criticaldamage}`;
|
||||
formula = combatData.arme.data.criticaldamage.toLowerCase();
|
||||
}
|
||||
ChatMessage.create( { content: `${attacker.name} a réussi son attaque sur ${defender.name} (${myRoll.total} / ${defense}) !<br> Les dégâts sont ${degats}`});
|
||||
|
||||
formula = this.processDamageString( formula, attacker );
|
||||
let degatsRoll = await this.processRoll(formula);
|
||||
ChatMessage.create( { content: `Et les dégats infligés sont de ${degatsRoll.total} (${formula}) à appliquer à ${defender.name}`});
|
||||
defender.applyDamage( degatsRoll.total );
|
||||
} else { //Echec
|
||||
ChatMessage.create( { content: `${attacker.name} a raté son attaque sur ${defender.name} (${myRoll.total} / ${defense}) !` });
|
||||
if ( myRoll.results[0] == 1) {
|
||||
ChatMessage.create( { content: `${attacker.name} a fait un <strong>échec critique</strong> et a raté son attaque sur ${defender.name} (${myRoll.total} / ${defense}) !` });
|
||||
} else {
|
||||
ChatMessage.create( { content: `${attacker.name} a raté son attaque sur ${defender.name} (${myRoll.total} / ${defense}) !` });
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ui.notifications.warn("Impossible de trouver l'attaquant et le défenseur.")
|
||||
|
Reference in New Issue
Block a user