Skip to content

Commit

Permalink
fix: improve deal damage to actors
Browse files Browse the repository at this point in the history
Currently there is only an automated way of dealign damage to actors
this change brings up a dialog for all players who own an actor and
let them distribute the damage among the attributes. Holding shift will
use the old behavior and no dialog will be shown.
This change also adds the ability to target enemies when shooting.

Fix xdy#222
  • Loading branch information
jonepatr committed Mar 21, 2021
1 parent 79c568f commit bc4cb8e
Show file tree
Hide file tree
Showing 12 changed files with 17,713 additions and 98 deletions.
17,307 changes: 17,254 additions & 53 deletions package-lock.json

Large diffs are not rendered by default.

54 changes: 15 additions & 39 deletions src/module/entities/TwodsixActor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {TWODSIX} from "../config";
import {TwodsixRollSettings} from "../utils/TwodsixRollSettings";
import {TwodsixDiceRoll} from "../utils/TwodsixDiceRoll";
import TwodsixItem from "./TwodsixItem";
import { Stats } from "../utils/actorDamage";

export default class TwodsixActor extends Actor {
/**
Expand Down Expand Up @@ -50,47 +51,22 @@ export default class TwodsixActor extends Actor {
}
}

protected async damageActor(damage:number):Promise<number> {
//TODO Naive implementation, assumes always choose current highest, assumes armor works
//TODO Implement choice of primary/secondary/no armor, and full/half/double armor, as well as 'ignore first X points of armor'.
//TODO Rewrite this...
const characteristics = this.data.data.characteristics;
const armor = this.data.data.primaryArmor.value;
let remaining:number = damage - armor;
let updateData = {};

[remaining, updateData] = this.addDamage(remaining, updateData, 'endurance');
if (remaining > 0 && characteristics['strength'].current > characteristics['dexterity'].current) {
[remaining, updateData] = this.addDamage(remaining, updateData, 'strength');
[remaining, updateData] = this.addDamage(remaining, updateData, 'dexterity');
} else {
[remaining, updateData] = this.addDamage(remaining, updateData, 'dexterity');
[remaining, updateData] = this.addDamage(remaining, updateData, 'strength');
}
if (remaining > 0) {
console.log(`Twodsix | Actor ${this.name} was overkilled by ${remaining}`);
}
this.update(updateData);
return remaining;
}

private addDamage(damage:number, updateData, chrName):[number,any] {
const characteristics = this.data.data.characteristics;
const characteristic = characteristics[chrName];
if (characteristic.current > 0) {
let handledDamage = 0;
let totalDamage = characteristic.damage;
if (damage + characteristic.damage > characteristic.value) {
handledDamage = characteristic.value - characteristic.damage;
totalDamage = characteristic.value;
} else if (damage > 0) {
handledDamage = damage;
totalDamage = characteristic.damage + damage;
protected async damageActor(damage:number, showDamageDialog=true):Promise<void> {
if (showDamageDialog) {
const damageData = {
damage: damage,
damageId: "damage-" + Math.random().toString(36).substring(2, 15)
};
if (this.token) {
damageData["tokenId"] = this.token.id;
} else {
damageData["actorId"] = this.id;
}
updateData[`data.characteristics.${chrName}.damage`] = totalDamage;
return [damage - handledDamage, updateData];
game.socket.emit("system.twodsix", ["createDamageDialog", damageData]);
Hooks.call('createDamageDialog', damageData);
} else {
return [damage, updateData];
const stats = new Stats(this, damage);
stats.applyDamage();
}
}

Expand Down
11 changes: 8 additions & 3 deletions src/module/entities/TwodsixItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,12 @@ export default class TwodsixItem extends Item {
for (let i = 0; i < numberOfAttacks; i++) {
const roll = await this.skillRoll(false, settings, showInChat);
if (game.settings.get("twodsix", "automateDamageRollOnHit") && roll.isSuccess()) {
await this.rollDamage(settings.rollMode, `${roll.effect} + ${bonusDamage}`, showInChat);
const damage = await this.rollDamage(settings.rollMode, `${roll.effect} + ${bonusDamage}`, showInChat);
if (game.user.targets.size === 1) {
game.user.targets.values().next().value.actor.damageActor(damage.total);
} else if (game.user.targets.size > 1){
ui.notifications.warn(game.i18n.localize("TWODSIX.Warnings.AutoDamageForMultipleTargetsNotImplemented"));
}
}
}
}
Expand Down Expand Up @@ -197,8 +202,8 @@ export default class TwodsixItem extends Item {

ChatMessage.create(messageData, {rollMode: rollMode});
}
console.log("DEBUG DAMAGE ROLL:", damageRoll);
return damageRoll;
console.log("DEBUG DAMAGE ROLL:", damage);
return damage;
}

public static burstAttackDM(number:number):number {
Expand Down
4 changes: 4 additions & 0 deletions src/module/hooks/hooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { renderDamageDialog, destroyDamageDialog } from "../utils/actorDamage";

Hooks.on('createDamageDialog', renderDamageDialog);
Hooks.on('destroyDamageDialog', destroyDamageDialog);
5 changes: 5 additions & 0 deletions src/module/hooks/ready.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ Hooks.once("ready", async function () {
await migrateWorld(worldVersion);
}

// A socket hook proxy
game.socket.on("system.twodsix", (data) => {
Hooks.call(data[0], ...data.slice(1));
});

// Wait to register hotbar drop hook on ready so that modules could register earlier if they want to
Hooks.on("hotbarDrop", (bar, data, slot) => createItemMacro(data, slot));

Expand Down
4 changes: 2 additions & 2 deletions src/module/hooks/updateHits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ function getCurrentHits(target: Record<string, any>, ...args: Record<string, any

Hooks.on('preUpdateActor', async (actor:TwodsixActor, update:Record<string, any>) => {
if (update.data?.characteristics) {
update.data.hits =getCurrentHits(actor.data.data.characteristics, update.data.characteristics);
update.data.hits = getCurrentHits({}, actor.data.data.characteristics, update.data.characteristics);
}
});

// eslint-disable-next-line @typescript-eslint/no-unused-vars
Hooks.on('preUpdateToken', async (scene, token:Record<string, any>, update:Record<string, any>) => {
if (update.actorData?.data?.characteristics) {
const actor = TwodsixActor.collection.get(token.actorId);
update.actorData.data.hits = getCurrentHits(
update.actorData.data.hits = getCurrentHits({},
// @ts-ignore
actor.data.data.characteristics,
token.actorData?.data?.characteristics ?? {},
Expand Down
4 changes: 3 additions & 1 deletion src/module/sheets/AbstractTwodsixActorSheet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,10 @@ export abstract class AbstractTwodsixActorSheet extends ActorSheet {
}

if (data.type === 'damageItem') {
const useInvertedShiftClick:boolean = game.settings.get('twodsix', 'invertSkillRollShiftClick');
const showDamageDialog = useInvertedShiftClick ? event["shiftKey"] : !event["shiftKey"];
// @ts-ignore
await this.actor.damageActor(data.payload["damage"]);
await this.actor.damageActor(data.payload["damage"], showDamageDialog);
return;
}

Expand Down
Loading

0 comments on commit bc4cb8e

Please sign in to comment.