Melee fight
This commit is contained in:
@@ -18,9 +18,9 @@ export class CrucibleUtility {
|
||||
/* -------------------------------------------- */
|
||||
static async init() {
|
||||
Hooks.on('renderChatLog', (log, html, data) => CrucibleUtility.chatListeners(html));
|
||||
Hooks.on("dropCanvasData", (canvas, data) => {
|
||||
/*Hooks.on("dropCanvasData", (canvas, data) => {
|
||||
CrucibleUtility.dropItemOnToken(canvas, data)
|
||||
});
|
||||
});*/
|
||||
|
||||
this.rollDataStore = {}
|
||||
this.defenderStore = {}
|
||||
@@ -51,7 +51,12 @@ export class CrucibleUtility {
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------- */
|
||||
static upperFirst(text) {
|
||||
if (typeof text !== 'string') return text
|
||||
return text.charAt(0).toUpperCase() + text.slice(1)
|
||||
}
|
||||
|
||||
/*-------------------------------------------- */
|
||||
static getSkills() {
|
||||
return duplicate(this.skills)
|
||||
@@ -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]
|
||||
if (rollTableName) {
|
||||
const pack = game.packs.get("fvtt-crucible-rpg.rolltables")
|
||||
const index = await pack.getIndex()
|
||||
const entry = index.find(e => e.name === rollTableName)
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
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) {
|
||||
|
||||
@@ -110,12 +184,12 @@ export class CrucibleUtility {
|
||||
})
|
||||
html.on("click", '.roll-defense-melee', event => {
|
||||
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")
|
||||
let actor = game.canvas.tokens.get(rollData.defenderTokenId).actor
|
||||
if (actor && (game.user.isGM || actor.isOwner) ) {
|
||||
actor.rollDefenseMelee(rollData )
|
||||
}
|
||||
let actor = game.canvas.tokens.get(rollData.defenderTokenId).actor
|
||||
if (actor && (game.user.isGM || actor.isOwner)) {
|
||||
actor.rollDefenseMelee(rollData)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -197,12 +271,12 @@ export class CrucibleUtility {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static getTarget() {
|
||||
if (game.user.targets && game.user.targets.size == 1) {
|
||||
if (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){
|
||||
ui.notifications.warn("Not implemented up to now !")
|
||||
static getSuccessResult(rollData) {
|
||||
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) {
|
||||
if ( rollData.attackRollData) {
|
||||
static async getFumble(weapon) {
|
||||
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
|
||||
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") {
|
||||
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) {
|
||||
let actor = game.actors.get(msg.data.actorId)
|
||||
let item
|
||||
@@ -412,7 +576,7 @@ export class CrucibleUtility {
|
||||
}
|
||||
|
||||
// shield => 14
|
||||
if (rollData.useShield && rollData.shield) {
|
||||
if (rollData.useshield && rollData.shield) {
|
||||
diceFormula += "+ 1" + String(rollData.shield.data.shielddie) + "cs>=5"
|
||||
} else {
|
||||
diceFormula += " + 0d6cs>=5"
|
||||
@@ -429,8 +593,9 @@ export class CrucibleUtility {
|
||||
rollData.roll = myRoll
|
||||
rollData.nbSuccess = myRoll.total
|
||||
if (rollData.rollAdvantage != "none") {
|
||||
|
||||
|
||||
rollData.rollOrder = 1
|
||||
rollData.rollType = (rollData.rollAdvantage == "roll-advantage") ? "Advantage": "Disadvantage"
|
||||
this.createChatWithRollMode(rollData.alias, {
|
||||
content: await renderTemplate(`systems/fvtt-crucible-rpg/templates/chat-generic-result.html`, rollData)
|
||||
})
|
||||
@@ -457,6 +622,7 @@ export class CrucibleUtility {
|
||||
}
|
||||
rollData.rollOrder = 3
|
||||
}
|
||||
rollData.nbSuccess = Math.max(0, rollData.nbSuccess)
|
||||
|
||||
rollData.isFirstRollAdvantage = false
|
||||
// Manage exp
|
||||
@@ -522,7 +688,7 @@ export class CrucibleUtility {
|
||||
chatGM.whisper = this.getUsers(user => user.isGM);
|
||||
chatGM.content = "Blinde message of " + game.user.name + "<br>" + chatOptions.content;
|
||||
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 });
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user