Melee fight

This commit is contained in:
2022-08-14 10:10:26 +02:00
parent ab755aac22
commit e73931d032
10 changed files with 360 additions and 197 deletions

View File

@@ -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 });
}