Melee fight
This commit is contained in:
parent
ab755aac22
commit
e73931d032
@ -325,6 +325,25 @@ export class CrucibleActor extends Actor {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async rollArmor( rollData) {
|
||||||
|
let armor = this.getEquippedArmor()
|
||||||
|
if (armor) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return { armor: "none"}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async incDecHP( formula ) {
|
||||||
|
let dmgRoll = new Roll(formula).roll( {async: false})
|
||||||
|
await CrucibleUtility.showDiceSoNice(dmgRoll, game.settings.get("core", "rollMode"))
|
||||||
|
let hp = duplicate(this.data.data.secondary.hp)
|
||||||
|
hp.value = Number(hp.value) + Number(dmgRoll.total)
|
||||||
|
this.update( {'data.secondary.hp': hp })
|
||||||
|
return Number(dmgRoll.total)
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getAbility(abilKey) {
|
getAbility(abilKey) {
|
||||||
return this.data.data.abilities[abilKey];
|
return this.data.data.abilities[abilKey];
|
||||||
@ -590,20 +609,71 @@ export class CrucibleActor extends Actor {
|
|||||||
let rollData = this.getCommonRollData()
|
let rollData = this.getCommonRollData()
|
||||||
rollData.mode = "shield"
|
rollData.mode = "shield"
|
||||||
rollData.shield = shield
|
rollData.shield = shield
|
||||||
|
rollData.useshield = true
|
||||||
rollData.img = shield.img
|
rollData.img = shield.img
|
||||||
this.startRoll(rollData)
|
this.startRoll(rollData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
rollArmorDie() {
|
async rollArmorDie(rollData = undefined) {
|
||||||
let armor = this.getEquippedArmor()
|
let armor = this.getEquippedArmor()
|
||||||
if (armor) {
|
if (armor) {
|
||||||
armor = duplicate(armor)
|
armor = duplicate(armor)
|
||||||
let diceColor = armor.data.absorprionroll
|
let reduce = 0
|
||||||
let rollTable = CrucibleUtility.getRollTableFromDiceColor( diceColor)
|
let multiply = 1
|
||||||
|
let disadvantage = false
|
||||||
|
let advantage = false
|
||||||
|
let messages = ["Armor applied"]
|
||||||
|
|
||||||
|
if (rollData) {
|
||||||
|
if (CrucibleUtility.isArmorLight(armor) && CrucibleUtility.isWeaponPenetrating(rollData.attackRollData.weapon) ) {
|
||||||
|
return { armorIgnored: true, nbSuccess: 0, messages: ["Armor ignored : Penetrating weapons ignore Light Armors."] }
|
||||||
|
}
|
||||||
|
if (CrucibleUtility.isWeaponPenetrating(rollData.attackRollData.weapon) ) {
|
||||||
|
messages.push("Armor reduced by 1 (Penetrating weapon)")
|
||||||
|
reduce = 1
|
||||||
|
}
|
||||||
|
if (CrucibleUtility.isWeaponLight(rollData.attackRollData.weapon) ) {
|
||||||
|
messages.push("Armor with advantage (Light weapon)")
|
||||||
|
advantage = true
|
||||||
|
}
|
||||||
|
if (CrucibleUtility.isWeaponHeavy(rollData.attackRollData.weapon) ) {
|
||||||
|
messages.push("Armor with disadvantage (Heavy weapon)")
|
||||||
|
disadvantage = true
|
||||||
|
}
|
||||||
|
if (CrucibleUtility.isWeaponHack(rollData.attackRollData.weapon) ) {
|
||||||
|
messages.push("Armor reduced by 1 (Hack weapon)")
|
||||||
|
reduce = 1
|
||||||
|
}
|
||||||
|
if (CrucibleUtility.isWeaponUndamaging(rollData.attackRollData.weapon) ) {
|
||||||
|
messages.push("Armor multiplied by 2 (Undamaging weapon)")
|
||||||
|
multiply = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let diceColor = armor.data.absorprionroll
|
||||||
|
let armorResult = await CrucibleUtility.getRollTableFromDiceColor( diceColor, false )
|
||||||
|
let armorValue = (Number(armorResult.data.text) - reduce) * multiply
|
||||||
|
if ( advantage || disadvantage) {
|
||||||
|
let armorResult2 = await CrucibleUtility.getRollTableFromDiceColor( diceColor, false )
|
||||||
|
let armorValue2 = (Number(armorResult2.data.text) - reduce) * multiply
|
||||||
|
if ( advantage) {
|
||||||
|
armorValue = (armorValue2 > armorValue) ? armorValue2 : armorValue
|
||||||
|
messages.push(`Armor advantage - Roll 1 = ${armorValue} - Roll 2 = ${armorValue2}`)
|
||||||
|
}
|
||||||
|
if ( disadvantage) {
|
||||||
|
armorValue = (armorValue2 < armorValue) ? armorValue2 : armorValue
|
||||||
|
messages.push(`Armor disadvantage - Roll 1 = ${armorValue} - Roll 2 = ${armorValue2}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
armorResult.armorValue = armorValue
|
||||||
|
if ( !rollData) {
|
||||||
|
ChatMessage.create( { content: "Armor result : " + armorValue } )
|
||||||
|
}
|
||||||
|
messages.push( "Armor result : " + armorValue)
|
||||||
|
return { armorIgnored: false, nbSuccess: armorValue, messages: messages }
|
||||||
}
|
}
|
||||||
|
return { armorIgnored: true, nbSuccess: 0, messages: ["No armor equipped."] }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
@ -68,7 +68,7 @@ export class CrucibleRollDialog extends Dialog {
|
|||||||
this.rollData.rollAdvantage = event.currentTarget.value
|
this.rollData.rollAdvantage = event.currentTarget.value
|
||||||
})
|
})
|
||||||
html.find('#useshield').change((event) => {
|
html.find('#useshield').change((event) => {
|
||||||
this.rollData.useShield = event.currentTarget.checked
|
this.rollData.useshield = event.currentTarget.checked
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,9 @@ export class CrucibleUtility {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async init() {
|
static async init() {
|
||||||
Hooks.on('renderChatLog', (log, html, data) => CrucibleUtility.chatListeners(html));
|
Hooks.on('renderChatLog', (log, html, data) => CrucibleUtility.chatListeners(html));
|
||||||
Hooks.on("dropCanvasData", (canvas, data) => {
|
/*Hooks.on("dropCanvasData", (canvas, data) => {
|
||||||
CrucibleUtility.dropItemOnToken(canvas, data)
|
CrucibleUtility.dropItemOnToken(canvas, data)
|
||||||
});
|
});*/
|
||||||
|
|
||||||
this.rollDataStore = {}
|
this.rollDataStore = {}
|
||||||
this.defenderStore = {}
|
this.defenderStore = {}
|
||||||
@ -51,6 +51,11 @@ export class CrucibleUtility {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------- */
|
||||||
|
static upperFirst(text) {
|
||||||
|
if (typeof text !== 'string') return text
|
||||||
|
return text.charAt(0).toUpperCase() + text.slice(1)
|
||||||
|
}
|
||||||
|
|
||||||
/*-------------------------------------------- */
|
/*-------------------------------------------- */
|
||||||
static getSkills() {
|
static getSkills() {
|
||||||
@ -90,18 +95,87 @@ export class CrucibleUtility {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async getRollTableFromDiceColor(diceColor) {
|
static isArmorLight(armor) {
|
||||||
|
if (armor && (armor.data.armortype.includes("light") || armor.data.armortype.includes("clothes"))) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static isWeaponPenetrating(weapon) {
|
||||||
|
if (weapon && weapon.data.qualities.toLowerCase().includes("penetrating")) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static isWeaponLight(weapon) {
|
||||||
|
if (weapon && weapon.data.qualities.toLowerCase().includes("light")) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static isWeaponHeavy(weapon) {
|
||||||
|
if (weapon && weapon.data.qualities.toLowerCase().includes("heavy")) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static isWeaponHack(weapon) {
|
||||||
|
if (weapon && weapon.data.qualities.toLowerCase().includes("hack")) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static isWeaponUndamaging(weapon) {
|
||||||
|
if (weapon && weapon.data.qualities.toLowerCase().includes("undamaging")) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static isWeaponDangerous(weapon) {
|
||||||
|
if (weapon && weapon.data.qualities.toLowerCase().includes("dangerous")) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static isWeaponDeadly(weapon) {
|
||||||
|
if (weapon && weapon.data.qualities.toLowerCase().includes("deadly")) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async getRollTableFromDiceColor(diceColor, displayChat = true) {
|
||||||
let rollTableName = __color2RollTable[diceColor]
|
let rollTableName = __color2RollTable[diceColor]
|
||||||
if (rollTableName) {
|
if (rollTableName) {
|
||||||
const pack = game.packs.get("fvtt-crucible-rpg.rolltables")
|
const pack = game.packs.get("fvtt-crucible-rpg.rolltables")
|
||||||
const index = await pack.getIndex()
|
const index = await pack.getIndex()
|
||||||
const entry = index.find(e => e.name === rollTableName)
|
const entry = index.find(e => e.name === rollTableName)
|
||||||
let table = await pack.getDocument(entry._id)
|
let table = await pack.getDocument(entry._id)
|
||||||
const draw = await table.draw({ displayChat: true, rollMode: "gmroll" })
|
const draw = await table.draw({ displayChat: displayChat, rollMode: "gmroll" })
|
||||||
return draw.results.length > 0 ? draw.results[0] : undefined
|
return draw.results.length > 0 ? draw.results[0] : undefined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async getCritical(level, weapon) {
|
||||||
|
const pack = game.packs.get("fvtt-crucible-rpg.rolltables")
|
||||||
|
|
||||||
|
let tableName = "Crit " + level + " (" + this.upperFirst(weapon.data.damage) + ")"
|
||||||
|
const index = await pack.getIndex()
|
||||||
|
const entry = index.find(e => e.name === tableName)
|
||||||
|
let table = await pack.getDocument(entry._id)
|
||||||
|
const draw = await table.draw({ displayChat: false, rollMode: "gmroll" })
|
||||||
|
return draw.results.length > 0 ? draw.results[0] : undefined
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async chatListeners(html) {
|
static async chatListeners(html) {
|
||||||
|
|
||||||
@ -110,11 +184,11 @@ export class CrucibleUtility {
|
|||||||
})
|
})
|
||||||
html.on("click", '.roll-defense-melee', event => {
|
html.on("click", '.roll-defense-melee', event => {
|
||||||
let rollId = $(event.currentTarget).data("roll-id")
|
let rollId = $(event.currentTarget).data("roll-id")
|
||||||
let rollData = CrucibleUtility.getRollData( rollId )
|
let rollData = CrucibleUtility.getRollData(rollId)
|
||||||
rollData.defenseWeaponId = $(event.currentTarget).data("defense-weapon-id")
|
rollData.defenseWeaponId = $(event.currentTarget).data("defense-weapon-id")
|
||||||
let actor = game.canvas.tokens.get(rollData.defenderTokenId).actor
|
let actor = game.canvas.tokens.get(rollData.defenderTokenId).actor
|
||||||
if (actor && (game.user.isGM || actor.isOwner) ) {
|
if (actor && (game.user.isGM || actor.isOwner)) {
|
||||||
actor.rollDefenseMelee(rollData )
|
actor.rollDefenseMelee(rollData)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -197,12 +271,12 @@ export class CrucibleUtility {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static getTarget() {
|
static getTarget() {
|
||||||
if (game.user.targets && game.user.targets.size == 1) {
|
if (game.user.targets) {
|
||||||
for (let target of game.user.targets) {
|
for (let target of game.user.targets) {
|
||||||
return target;
|
return target
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@ -245,15 +319,102 @@ export class CrucibleUtility {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getSuccessResult(sum){
|
static getSuccessResult(rollData) {
|
||||||
ui.notifications.warn("Not implemented up to now !")
|
if (rollData.sumSuccess <= -3) {
|
||||||
|
return { result: "miss", fumble: true, attackerHPLoss: "2d3", hpLossType: "melee" }
|
||||||
|
}
|
||||||
|
if (rollData.sumSuccess == -2) {
|
||||||
|
return { result: "miss", dangerous_fumble: true, attackerHPLoss: "1d3", hpLossType: "melee" }
|
||||||
|
}
|
||||||
|
if (rollData.sumSuccess == -1) {
|
||||||
|
return { result: "miss" }
|
||||||
|
}
|
||||||
|
if (rollData.sumSuccess == 0) {
|
||||||
|
if (rollData.attackRollData.weapon.data.isranged) {
|
||||||
|
return { result: "target_space", aoe: true }
|
||||||
|
} else {
|
||||||
|
return { result: "clash", hack_vs_shields: true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rollData.sumSuccess == 1) {
|
||||||
|
return { result: "hit", defenderDamage: "1", entangle: true, knockback: true }
|
||||||
|
}
|
||||||
|
if (rollData.sumSuccess == 2) {
|
||||||
|
return { result: "hit", defenderDamage: "2", critical_1: true, entangle: true, knockback: true, penetrating_impale: true, hack_armors: true }
|
||||||
|
}
|
||||||
|
if (rollData.sumSuccess >= 3) {
|
||||||
|
return { result: "hit", defenderDamage: "3", critical_2: true, entangle: true, knockback: true, penetrating_impale: true, hack_armors: true }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async processAttackDefense( rollData) {
|
static async getFumble(weapon) {
|
||||||
if ( rollData.attackRollData) {
|
const pack = game.packs.get("fvtt-crucible-rpg.rolltables")
|
||||||
|
const index = await pack.getIndex()
|
||||||
|
let entry
|
||||||
|
|
||||||
|
if (weapon.isranged) {
|
||||||
|
entry = index.find(e => e.name === "Fumble! (ranged)")
|
||||||
|
}
|
||||||
|
if (!weapon.isranged) {
|
||||||
|
entry = index.find(e => e.name === "Fumble! (melee)")
|
||||||
|
}
|
||||||
|
let table = await pack.getDocument(entry._id)
|
||||||
|
const draw = await table.draw({ displayChat: false, rollMode: "gmroll" })
|
||||||
|
return draw.results.length > 0 ? draw.results[0] : undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async processSuccessResult(rollData) {
|
||||||
|
if (game.user.isGM) { // Only GM process this
|
||||||
|
let result = rollData.successDetails
|
||||||
|
let attacker = game.actors.get(rollData.actorId)
|
||||||
|
let defender = game.canvas.tokens.get(rollData.attackRollData.defenderTokenId).actor
|
||||||
|
|
||||||
|
if (attacker && result.attackerHPLoss) {
|
||||||
|
result.attackerHPLossValue = await attacker.incDecHP("-" + result.attackerHPLoss)
|
||||||
|
}
|
||||||
|
if (attacker && defender && result.defenderDamage) {
|
||||||
|
let dmgDice = (rollData.attackRollData.weapon.data.isranged) ? "d6" : "d8"
|
||||||
|
result.damageWeaponFormula = result.defenderDamage + dmgDice
|
||||||
|
result.defenderHPLossValue = await defender.incDecHP("-" + result.damageWeaponFormula)
|
||||||
|
}
|
||||||
|
if (result.fumble || (result.dangerous_fumble && CrucibleUtility.isWeaponDangerous(rollData.attackRollData.weapon))) {
|
||||||
|
result.fumbleDetails = await this.getFumble(rollData.weapon)
|
||||||
|
}
|
||||||
|
if (result.critical_1 || result.critical_2) {
|
||||||
|
let isDeadly = CrucibleUtility.isWeaponDeadly(rollData.attackRollData.weapon)
|
||||||
|
result.critical = await this.getCritical((result.critical_1) ? "I" : "II", rollData.attackRollData.weapon )
|
||||||
|
result.criticalText = result.critical.data.text
|
||||||
|
}
|
||||||
|
this.createChatWithRollMode(rollData.alias, {
|
||||||
|
content: await renderTemplate(`systems/fvtt-crucible-rpg/templates/chat-attack-defense-result.html`, rollData)
|
||||||
|
})
|
||||||
|
console.log("Results processed", rollData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async processAttackDefense(rollData) {
|
||||||
|
if (rollData.attackRollData) {
|
||||||
|
//console.log("Defender token, ", rollData, rollData.defenderTokenId)
|
||||||
|
let defender = game.canvas.tokens.get(rollData.attackRollData.defenderTokenId).actor
|
||||||
let sumSuccess = rollData.attackRollData.nbSuccess - rollData.nbSuccess
|
let sumSuccess = rollData.attackRollData.nbSuccess - rollData.nbSuccess
|
||||||
this.getSuccessResult(sumSuccess)
|
if (sumSuccess > 0) {
|
||||||
|
let armorResult = await defender.rollArmorDie(rollData)
|
||||||
|
rollData.armorResult = armorResult
|
||||||
|
sumSuccess += rollData.armorResult.nbSuccess
|
||||||
|
if (sumSuccess < 0) { // Never below 0
|
||||||
|
sumSuccess = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rollData.sumSuccess = sumSuccess
|
||||||
|
rollData.successDetails = this.getSuccessResult(rollData)
|
||||||
|
if (game.user.isGM) {
|
||||||
|
this.processSuccessResult(rollData)
|
||||||
|
} else {
|
||||||
|
game.socket.emit("system.fvtt-crucible-rpg", { msg: "msg_gm_process_attack_defense", data: rollData });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,6 +424,9 @@ export class CrucibleUtility {
|
|||||||
if (msg.name == "msg_update_roll") {
|
if (msg.name == "msg_update_roll") {
|
||||||
this.updateRollData(msg.data)
|
this.updateRollData(msg.data)
|
||||||
}
|
}
|
||||||
|
if (msg.name == "msg_gm_process_attack_defense") {
|
||||||
|
this.processSuccessResult(msg.data)
|
||||||
|
}
|
||||||
if (msg.name == "msg_gm_item_drop" && game.user.isGM) {
|
if (msg.name == "msg_gm_item_drop" && game.user.isGM) {
|
||||||
let actor = game.actors.get(msg.data.actorId)
|
let actor = game.actors.get(msg.data.actorId)
|
||||||
let item
|
let item
|
||||||
@ -412,7 +576,7 @@ export class CrucibleUtility {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// shield => 14
|
// shield => 14
|
||||||
if (rollData.useShield && rollData.shield) {
|
if (rollData.useshield && rollData.shield) {
|
||||||
diceFormula += "+ 1" + String(rollData.shield.data.shielddie) + "cs>=5"
|
diceFormula += "+ 1" + String(rollData.shield.data.shielddie) + "cs>=5"
|
||||||
} else {
|
} else {
|
||||||
diceFormula += " + 0d6cs>=5"
|
diceFormula += " + 0d6cs>=5"
|
||||||
@ -431,6 +595,7 @@ export class CrucibleUtility {
|
|||||||
if (rollData.rollAdvantage != "none") {
|
if (rollData.rollAdvantage != "none") {
|
||||||
|
|
||||||
rollData.rollOrder = 1
|
rollData.rollOrder = 1
|
||||||
|
rollData.rollType = (rollData.rollAdvantage == "roll-advantage") ? "Advantage": "Disadvantage"
|
||||||
this.createChatWithRollMode(rollData.alias, {
|
this.createChatWithRollMode(rollData.alias, {
|
||||||
content: await renderTemplate(`systems/fvtt-crucible-rpg/templates/chat-generic-result.html`, rollData)
|
content: await renderTemplate(`systems/fvtt-crucible-rpg/templates/chat-generic-result.html`, rollData)
|
||||||
})
|
})
|
||||||
@ -457,6 +622,7 @@ export class CrucibleUtility {
|
|||||||
}
|
}
|
||||||
rollData.rollOrder = 3
|
rollData.rollOrder = 3
|
||||||
}
|
}
|
||||||
|
rollData.nbSuccess = Math.max(0, rollData.nbSuccess)
|
||||||
|
|
||||||
rollData.isFirstRollAdvantage = false
|
rollData.isFirstRollAdvantage = false
|
||||||
// Manage exp
|
// Manage exp
|
||||||
@ -522,7 +688,7 @@ export class CrucibleUtility {
|
|||||||
chatGM.whisper = this.getUsers(user => user.isGM);
|
chatGM.whisper = this.getUsers(user => user.isGM);
|
||||||
chatGM.content = "Blinde message of " + game.user.name + "<br>" + chatOptions.content;
|
chatGM.content = "Blinde message of " + game.user.name + "<br>" + chatOptions.content;
|
||||||
console.log("blindMessageToGM", chatGM);
|
console.log("blindMessageToGM", chatGM);
|
||||||
game.socket.emit("system.fvtt-crucible-rgp", { msg: "msg_gm_chat_message", data: chatGM });
|
game.socket.emit("system.fvtt-crucible-rpg", { msg: "msg_gm_chat_message", data: chatGM });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
@ -218,11 +218,11 @@
|
|||||||
"styles": [
|
"styles": [
|
||||||
"styles/simple.css"
|
"styles/simple.css"
|
||||||
],
|
],
|
||||||
"templateVersion": 14,
|
"templateVersion": 16,
|
||||||
"title": "Crucible RPG",
|
"title": "Crucible RPG",
|
||||||
"manifest": "https://www.uberwald.me/gitea/public/fvtt-crucible-rpg/raw/master/system.json",
|
"manifest": "https://www.uberwald.me/gitea/public/fvtt-crucible-rpg/raw/master/system.json",
|
||||||
"download": "https://www.uberwald.me/gitea/public/fvtt-crucible-rpg/archive/fvtt-crucible-rpg-v0.1.26.zip",
|
"download": "https://www.uberwald.me/gitea/public/fvtt-crucible-rpg/archive/fvtt-crucible-rpg-v0.1.26.zip",
|
||||||
"url": "https://www.uberwald.me/gitea/public/fvtt-crucible-rpg",
|
"url": "https://www.uberwald.me/gitea/public/fvtt-crucible-rpg",
|
||||||
"version": "0.1.26",
|
"version": "0.1.29",
|
||||||
"background" : "./images/ui/crucible_welcome_page.webp"
|
"background" : "./images/ui/crucible_welcome_page.webp"
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
"biodata": {
|
"biodata": {
|
||||||
"class": "",
|
"class": "",
|
||||||
"age": 0,
|
"age": 0,
|
||||||
"size": "",
|
"size": 0,
|
||||||
"weight": "",
|
"weight": "",
|
||||||
"hair": "",
|
"hair": "",
|
||||||
"sex": "",
|
"sex": "",
|
||||||
|
@ -453,9 +453,17 @@
|
|||||||
<div>
|
<div>
|
||||||
<ul>
|
<ul>
|
||||||
<li class="flexrow item">
|
<li class="flexrow item">
|
||||||
<label class="generic-label">Weight</label>
|
<label class="generic-label">Size</label>
|
||||||
<input type="text" class="" name="data.biodata.weight" value="{{data.biodata.weight}}"
|
<select class="competence-base flexrow" type="text" name="data.biodata.size" value="{{data.biodata.size}}" data-dtype="Number">
|
||||||
data-dtype="String" />
|
{{#select data.biodata.size}}
|
||||||
|
<option value="1">Tiny</option>
|
||||||
|
<option value="2">Small</option>
|
||||||
|
<option value="3">Medium</option>
|
||||||
|
<option value="4">Large</option>
|
||||||
|
<option value="5">Huge</option>
|
||||||
|
<option value="6">Gargantuan</option>
|
||||||
|
{{/select}}
|
||||||
|
</select>
|
||||||
</li>
|
</li>
|
||||||
<li class="flexrow item">
|
<li class="flexrow item">
|
||||||
<label class="generic-label">Sex</label>
|
<label class="generic-label">Sex</label>
|
||||||
@ -469,166 +477,12 @@
|
|||||||
<li class="flexrow item" data-item-id="{{race._id}}">
|
<li class="flexrow item" data-item-id="{{race._id}}">
|
||||||
<label class="generic-label">Race</label>
|
<label class="generic-label">Race</label>
|
||||||
<a class="item-edit"><img class="stat-icon" src="{{race.img}}"></a>
|
<a class="item-edit"><img class="stat-icon" src="{{race.img}}"></a>
|
||||||
<input type="text" class="" name="data.biodata.racename" value="{{race.name}}" disabled
|
<input type="text" class="" name="data.biodata.racename" value="{{data.biodata.racename}}" data-dtype="String" />
|
||||||
data-dtype="String" />
|
|
||||||
<div class="item-controls">
|
|
||||||
<a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<li class="flexrow item" data-item-id="{{role._id}}">
|
|
||||||
<label class="generic-label">Role</label>
|
|
||||||
<a class="item-edit"><img class="stat-icon" src="{{role.img}}"></a>
|
|
||||||
<input type="text" class="" name="data.biodata.rolename" value="{{role.name}}" disabled
|
|
||||||
data-dtype="String" />
|
|
||||||
<div class="item-controls">
|
|
||||||
<a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
|
|
||||||
</div>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
|
||||||
<ul class="stat-list alternate-list">
|
|
||||||
<li class="item flexrow list-item items-title-bg">
|
|
||||||
<span class="item-name-label-header">
|
|
||||||
<h3><label class="items-title-text">Virtues</label></h3>
|
|
||||||
</span>
|
|
||||||
<span class="item-field-label-short">Status</label></span>
|
|
||||||
</li>
|
|
||||||
{{#each virtues as |virtue key|}}
|
|
||||||
<li class="item stat flexrow list-item list-item-shadow" data-arme-id="{{virtue.id}}"
|
|
||||||
data-item-id="{{virtue._id}}">
|
|
||||||
<a class="item-edit item-name-img" title="Edit Item"><img class="sheet-competence-img"
|
|
||||||
src="{{virtue.img}}" /></a>
|
|
||||||
<span class="item-name-label">{{virtue.name}}</span>
|
|
||||||
<span class="item-field-label-short"><label class="short-label">
|
|
||||||
{{#if virtue.data.activated}}
|
|
||||||
Activated
|
|
||||||
{{else}}
|
|
||||||
-
|
|
||||||
{{/if}}
|
|
||||||
</label>
|
|
||||||
</span>
|
|
||||||
<div class="item-filler"> </div>
|
|
||||||
<div class="item-controls item-controls-fixed">
|
|
||||||
<a class="item-control vice-virtue-activate" title="Activated">{{#if virtue.data.activated}}<i
|
|
||||||
class="fas fa-circle"></i>{{else}}<i class="fas fa-genderless"></i>{{/if}}</a>
|
|
||||||
<a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
{{/each}}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<ul class="stat-list alternate-list">
|
|
||||||
<li class="item flexrow list-item items-title-bg">
|
|
||||||
<span class="item-name-label-header">
|
|
||||||
<h3><label class="items-title-text">Vices</label></h3>
|
|
||||||
</span>
|
|
||||||
<span class="item-field-label-short">Status</label></span>
|
|
||||||
</li>
|
|
||||||
{{#each vices as |vice key|}}
|
|
||||||
<li class="item stat flexrow list-item list-item-shadow" data-arme-id="{{vice.id}}"
|
|
||||||
data-item-id="{{vice._id}}">
|
|
||||||
<a class="item-edit item-name-img" title="Edit Item"><img class="sheet-competence-img"
|
|
||||||
src="{{vice.img}}" /></a>
|
|
||||||
<span class="item-name-label">{{vice.name}}</span>
|
|
||||||
<span class="item-field-label-short"><label class="short-label">
|
|
||||||
{{#if vice.data.activated}}
|
|
||||||
Activated
|
|
||||||
{{else}}
|
|
||||||
-
|
|
||||||
{{/if}}
|
|
||||||
</label>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<div class="item-filler"> </div>
|
|
||||||
<div class="item-controls item-controls-fixed">
|
|
||||||
<a class="item-control vice-virtue-activate" title="Activated">{{#if vice.data.activated}}<i
|
|
||||||
class="fas fa-circle"></i>{{else}}<i class="fas fa-genderless"></i>{{/if}}</a>
|
|
||||||
<a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
{{/each}}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li class="item flexrow list-item items-title-bg">
|
|
||||||
<span class="item-name-label-header">
|
|
||||||
<h3><label class="items-title-text">Psychology</label></h3>
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
<li class="flexrow">
|
|
||||||
<label class="short-label">Worst Fear </label>
|
|
||||||
<input type="text" class="" name="data.biodata.worstfear" value="{{data.biodata.worstfear}}"
|
|
||||||
data-dtype="String" />
|
|
||||||
<label class="attribute-value checkbox"><input type="checkbox" class="change-worstfear"
|
|
||||||
name="data.biodata.worstfearactive" {{checked data.biodata.worstfearactive}} /> Active ?</label>
|
|
||||||
</li>
|
|
||||||
<li class="flexrow">
|
|
||||||
<label class="short-label">Desires </label>
|
|
||||||
<input type="text" class="" name="data.biodata.desires" value="{{data.biodata.desires}}"
|
|
||||||
data-dtype="String" />
|
|
||||||
<label class="attribute-value checkbox"><input type="checkbox" class="change-desires"
|
|
||||||
name="data.biodata.desiresactive" {{checked data.biodata.desiresactive}} /> Active ?</label>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h3>Catchphrase : </h3>
|
|
||||||
<ul>
|
|
||||||
<li class="flexrow">
|
|
||||||
<label class="short-label">Catchphrase </label>
|
|
||||||
<input type="text" class="" name="data.biodata.catchphrase" value="{{data.biodata.catchphrase}}"
|
|
||||||
data-dtype="String" />
|
|
||||||
</li>
|
|
||||||
<li class="flexrow">
|
|
||||||
<label class="short-label">Catchphrase Trigger : </label>
|
|
||||||
<input type="text" class="" name="data.biodata.catchphrasetrigger" value="{{data.biodata.catchphrasetrigger}}"
|
|
||||||
data-dtype="String" />
|
|
||||||
</li>
|
|
||||||
<li class="flexrow">
|
|
||||||
<label class="short-label">Catchphrase used </label>
|
|
||||||
<label class="attribute-value checkbox"><input type="checkbox" name="data.biodata.catchphraseused" {{checked
|
|
||||||
data.biodata.catchphraseused}} /></label>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li class="item flexrow list-item items-title-bg">
|
|
||||||
<span class="item-name-label-header">
|
|
||||||
<h3><label class="items-title-text">Development</label></h3>
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
<li class="flexrow">
|
|
||||||
<label class="short-label">Character Value : </label>
|
|
||||||
<input type="text" class="" name="data.biodata.charactervalue" value="{{data.biodata.charactervalue}}"
|
|
||||||
data-dtype="String" />
|
|
||||||
</li>
|
|
||||||
<li class="flexrow">
|
|
||||||
<label class="short-label">Character Development Points Total (CDP total) : </label>
|
|
||||||
<input type="text" class="" name="data.biodata.cdp" value="{{data.biodata.cdp}}" data-dtype="Number" />
|
|
||||||
</li>
|
|
||||||
<li class="flexrow">
|
|
||||||
<label class="short-label">Hero Level (max) : </label>
|
|
||||||
<input type="text" class="" name="data.biodata.maxlevelremaining" value="{{data.biodata.maxlevelremaining}}" data-dtype="Number" />
|
|
||||||
</li>
|
|
||||||
<li class="flexrow">
|
|
||||||
<label class="short-label">Hero Levels Remaining : </label>
|
|
||||||
<select class="status-small-label color-class-common" type="text" name="data.biodata.currentlevelremaining" value="{{data.biodata.currentlevelremaining}}" data-dtype="Number" {{#unless @root.editScore}}disabled{{/unless}}>
|
|
||||||
{{#select data.biodata.currentlevelremaining}}
|
|
||||||
{{{@root.levelRemainingList}}}
|
|
||||||
{{/select}}
|
|
||||||
</select>
|
|
||||||
</li>
|
|
||||||
<li class="flexrow">
|
|
||||||
<label class="short-label">Threat Level : </label>
|
|
||||||
<input type="text" class="" name="data.biodata.threatlevel" value="{{data.biodata.threatlevel}}"
|
|
||||||
data-dtype="Number" />
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
<h3>Background : </h3>
|
<h3>Background : </h3>
|
||||||
|
73
templates/chat-attack-defense-result.html
Normal file
73
templates/chat-attack-defense-result.html
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
<div class="chat-message-header">
|
||||||
|
{{#if actorImg}}
|
||||||
|
<img class="actor-icon" src="{{actorImg}}" alt="{{alias}}" />
|
||||||
|
{{/if}}
|
||||||
|
<h4 class=chat-actor-name>{{alias}}</h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
{{#if img}}
|
||||||
|
<div >
|
||||||
|
<img class="chat-icon" src="{{img}}" alt="{{name}}" />
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<div class="flexcol">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Fight result !</strong></li>
|
||||||
|
{{#if successDetails.fumbleDetails}}
|
||||||
|
<li>Fumble ! : {{successDetails.fumbleDetails}} </li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if armorResult}}
|
||||||
|
{{#each armorResult.messages as |message idx|}}
|
||||||
|
<li>{{message}}</li>
|
||||||
|
{{/each}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if successDetails.hack_vs_shields}}
|
||||||
|
<li>Hack weapon : check shield !</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if successDetails.entangle}}
|
||||||
|
<li>Entangle weapon : attacker can entangle !</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if successDetails.knockback}}
|
||||||
|
<li>Knockback weapon : check knockback !</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if successDetails.hack_armors}}
|
||||||
|
<li>Hack weapon : check armor damage !</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if successDetails.penetrating_impale}}
|
||||||
|
<li>Penetrating weapon : apply the Impale condition !</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if (or successDetails.critical_1 successDetails.critical_2)}}
|
||||||
|
<li>Critical {{#if successDetails.critical_1}} 1 {{else}} 2 {{/if}} : {{successDetails.criticalText}} </li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if successDetails.attackerHPLossValue}}
|
||||||
|
<li>Attacker has lost HP : {{successDetails.attackerHPLossValue}} HP </li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if successDetails.defenderHPLossValue}}
|
||||||
|
<li>Defender has lost HP : {{successDetails.defenderHPLossValue}} HP </li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<li>Success details : {{successDetails.result}} </li>
|
||||||
|
|
||||||
|
<li><strong>Final successes</strong> {{sumSuccess}} </li>
|
||||||
|
|
||||||
|
<!-- <button class="chat-card-button reroll-level-remaining" data-roll-id="{{rollId}}">Reroll</button> -->
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
@ -19,10 +19,10 @@
|
|||||||
<div>
|
<div>
|
||||||
<ul>
|
<ul>
|
||||||
{{#if (eq rollOrder 1)}}
|
{{#if (eq rollOrder 1)}}
|
||||||
<li><strong>Roll with advantage - Roll 1</strong></li>
|
<li><strong>Roll with {{rollType}} - Roll 1</strong></li>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if (eq rollOrder 2)}}
|
{{#if (eq rollOrder 2)}}
|
||||||
<li><strong>Roll with advantage - Roll 2</strong></li>
|
<li><strong>Roll with {{rollType}} - Roll 2</strong></li>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if (eq rollOrder 3)}}
|
{{#if (eq rollOrder 3)}}
|
||||||
<li><strong>Roll with advantage - Final result !</strong></li>
|
<li><strong>Roll with advantage - Final result !</strong></li>
|
||||||
@ -118,7 +118,7 @@
|
|||||||
</li>
|
</li>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if useShield}}
|
{{#if useshield}}
|
||||||
<li>Shield : {{shield.name}} - {{shield.data.shielddie}}
|
<li>Shield : {{shield.name}} - {{shield.data.shielddie}}
|
||||||
({{#each roll.terms.14.results as |die idx|}}
|
({{#each roll.terms.14.results as |die idx|}}
|
||||||
{{die.result}}
|
{{die.result}}
|
||||||
|
@ -65,7 +65,7 @@
|
|||||||
<div class="flexrow">
|
<div class="flexrow">
|
||||||
<span class="roll-dialog-label">Disadvantage : </span>
|
<span class="roll-dialog-label">Disadvantage : </span>
|
||||||
<select class="status-small-label color-class-common" type="text" id="disadvantage" value="{{disadvantage}}" data-dtype="String" >
|
<select class="status-small-label color-class-common" type="text" id="disadvantage" value="{{disadvantage}}" data-dtype="String" >
|
||||||
{{#select isadvantage}}
|
{{#select disadvantage}}
|
||||||
<option value="none">None</option>
|
<option value="none">None</option>
|
||||||
<option value="disadvantage1">1 Disadvantage</option>
|
<option value="disadvantage1">1 Disadvantage</option>
|
||||||
<option value="disadvantage2">2 Disadvantages</option>
|
<option value="disadvantage2">2 Disadvantages</option>
|
||||||
|
Loading…
Reference in New Issue
Block a user