Skip to content

Commit

Permalink
#126: Pass multiple targets to combat manager (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
JORDI.ALONSO authored and JORDI.ALONSO committed May 30, 2022
1 parent e1d3ad6 commit 54ea761
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 74 deletions.
76 changes: 39 additions & 37 deletions src/module/combat/websocket/ws-combat/gm/WSGMCombatManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,18 +131,18 @@ export class WSGMCombatManager extends WSCombatManager<ABFWSGMRequest, ABFWSGMNo
return;
}

const targetToken = getTargetToken(selectedToken, targets);
const targetTokens = getTargetToken(selectedToken, targets);

if (selectedToken?.id) {
await ABFDialogs.confirm(
this.game.i18n.format('macros.combat.dialog.attackConfirm.title'),
this.game.i18n.format('macros.combat.dialog.attackConfirm.body.title', { target: targetToken.name }),
this.game.i18n.format('macros.combat.dialog.attackConfirm.body.title', { target: targetTokens[0]?.name }),
{
onConfirm: () => {
if (selectedToken?.id && targetToken?.id) {
this.combat = this.createNewCombat(selectedToken!, targetToken);
if (selectedToken?.id && targetTokens?.every(t=> { return t?.id })) {
this.combat = this.createNewCombat(selectedToken!, targetTokens);

this.manageAttack(selectedToken!, targetToken);
this.manageAttack(selectedToken!, targetTokens);
}
}
}
Expand All @@ -167,7 +167,7 @@ export class WSGMCombatManager extends WSCombatManager<ABFWSGMRequest, ABFWSGMNo
const { attackerTokenId, defenderTokenId } = msg.payload;

const attacker = this.findTokenById(attackerTokenId);
const defender = this.findTokenById(defenderTokenId);
const defender = defenderTokenId.map(id=> { return this.findTokenById(id) });

if (!attacker || !defender) {
Log.warn('Can not handle user attack request due attacker or defender actor do not exist');
Expand All @@ -176,7 +176,7 @@ export class WSGMCombatManager extends WSCombatManager<ABFWSGMRequest, ABFWSGMNo

try {
if (!this.game.settings.get('animabf', ABFSettingsKeys.AUTO_ACCEPT_COMBAT_REQUESTS)) {
await CombatDialogs.openCombatRequestDialog({ attacker: attacker.actor!, defender: defender.actor! });
await CombatDialogs.openCombatRequestDialog({ attacker: attacker.actor!, defender: defender[0].actor! });
}

this.combat = this.createNewCombat(attacker, defender);
Expand All @@ -203,17 +203,17 @@ export class WSGMCombatManager extends WSCombatManager<ABFWSGMRequest, ABFWSGMNo
}
}

private createNewCombat(attacker: TokenDocument, defender: TokenDocument) {
return new GMCombatDialog(attacker, defender, {
private createNewCombat(attacker: TokenDocument, defenders: Array<TokenDocument>) {
return new GMCombatDialog(attacker, defenders, {
onClose: () => {
this.endCombat();
},
onCounterAttack: bonus => {
onCounterAttack: (defender, bonus) => {
this.endCombat();

this.combat = new GMCombatDialog(
defender,
attacker,
[attacker],
{
onClose: () => {
this.endCombat();
Expand All @@ -233,46 +233,48 @@ export class WSGMCombatManager extends WSCombatManager<ABFWSGMRequest, ABFWSGMNo

this.emit(newMsg);
} else {
this.manageAttack(defender, attacker, bonus);
this.manageAttack(defender, [attacker], bonus);
}
}
});
}

private manageAttack(attacker: TokenDocument, defender: TokenDocument, bonus?: number) {
private manageAttack(attacker: TokenDocument, defenders: Array<TokenDocument>, bonus?: number) {
this.attackDialog = new CombatAttackDialog(
attacker,
defender,
defenders,
{
onAttack: result => {
this.attackDialog?.close({ force: true });
defenders.forEach(defender=> {
this.attackDialog?.close({ force: true });

this.attackDialog = undefined;
this.attackDialog = undefined;

if (this.combat) {
this.combat.updateAttackerData(result);

if (canOwnerReceiveMessage(defender.actor!)) {
const newMsg: GMAttackMessage = {
type: GMMessageTypes.Attack,
payload: { attackerTokenId: attacker.id!, defenderTokenId: defender.id!, result }
};

this.emit(newMsg);
} else {
const { critic } = result.values;

try {
this.manageDefense(attacker, defender, result.type, critic);
} catch (err) {
if (err) {
Log.error(err);
}
if (this.combat) {
this.combat.updateAttackerData(result);

if (canOwnerReceiveMessage(defender.actor!)) {
const newMsg: GMAttackMessage = {
type: GMMessageTypes.Attack,
payload: { attackerTokenId: attacker.id!, defenderTokenId: defender.id!, result }
};

this.emit(newMsg);
} else {
const { critic } = result.values;

this.endCombat();
try {
this.manageDefense(attacker, defender, result.type, critic);
} catch (err) {
if (err) {
Log.error(err);
}

this.endCombat();
}
}
}
}
});
}
},
{ counterAttackBonus: bonus }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export type UserRequestToAttackMessage = {
senderId: string;
payload: {
attackerTokenId: string;
defenderTokenId: string;
defenderTokenId: Array<string>;
};
};

Expand Down
22 changes: 12 additions & 10 deletions src/module/combat/websocket/ws-combat/util/getTargetToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,22 @@ export const getTargetToken = (attackerToken: TokenDocument, targetTokens: UserT
throw new Error(message);
}

const target = targetTokens.values().next().value as TokenDocument;

if (!target.actor?.id) {
message = tgame.i18n.localize('macros.combat.dialog.error.withoutActor.title');
}

if (target.id === attackerToken.id) {
message = tgame.i18n.localize('macros.combat.dialog.error.cannotAttackYourself.title');
}
const resultTargets = new Array<TokenDocument>();
targetTokens.forEach(target => {
if (!target.actor?.id) {
message = tgame.i18n.localize('macros.combat.dialog.error.withoutActor.title');
}

if (target.id === attackerToken.id) {
message = tgame.i18n.localize('macros.combat.dialog.error.cannotAttackYourself.title');
}
resultTargets.push(target.document);
});

if (message) {
ABFDialogs.prompt(message);
throw new Error(message);
}

return target;
return resultTargets;
};
6 changes: 3 additions & 3 deletions src/module/dialogs/combat/CombatAttackDialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,14 +179,14 @@ export class CombatAttackDialog extends FormApplication<FormApplicationOptions,

constructor(
attacker: TokenDocument,
defender: TokenDocument,
defenders: Array<TokenDocument>,
private hooks: {
onAttack: (attackValues: UserCombatAttackResult) => void;
},
options: { allowed?: boolean; counterAttackBonus?: number } = {}
) {
super(getInitialData(attacker, defender, options));

super(getInitialData(attacker, defenders[0], options));
let defender = defenders[0];
this.data = getInitialData(attacker, defender, options);

const weapons = this.attackerActor.data.data.combat.weapons as WeaponDataSource[];
Expand Down
52 changes: 29 additions & 23 deletions src/module/dialogs/combat/GMCombatDialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,17 @@ export type GMCombatAttackResult = UserCombatAttackResult & {
power?: PsychicPowerDataSource;
};

type GMCombatDefenderData = {
actor: ABFActor;
token: TokenDocument;
isReady: boolean;
customModifier: number;
result?: UserCombatDefenseResult & {
spell?: SpellDataSource;
power?: PsychicPowerDataSource;
};
};

type GMCombatDialogData = {
ui: {
isCounter: boolean;
Expand All @@ -27,16 +38,8 @@ type GMCombatDialogData = {
counterAttackBonus?: number;
result?: GMCombatAttackResult;
};
defender: {
actor: ABFActor;
token: TokenDocument;
isReady: boolean;
customModifier: number;
result?: UserCombatDefenseResult & {
spell?: SpellDataSource;
power?: PsychicPowerDataSource;
};
};
defender: GMCombatDefenderData;
listDefenders: Array<GMCombatDefenderData>;
calculations?:
| {
winner: TokenDocument;
Expand All @@ -54,11 +57,18 @@ type GMCombatDialogData = {

const getInitialData = (
attacker: TokenDocument,
defender: TokenDocument,
defenders: Array<TokenDocument>,
options: { isCounter?: boolean; counterAttackBonus?: number } = {}
): GMCombatDialogData => {
const attackerActor = attacker.actor!;
const defenderActor = defender.actor!;
const defend = defenders.map(defender=> {
return {
token: defender,
actor: defender.actor!,
customModifier: 0,
isReady: false
};
})

return {
ui: {
Expand All @@ -71,12 +81,8 @@ const getInitialData = (
counterAttackBonus: options.counterAttackBonus,
isReady: false
},
defender: {
token: defender,
actor: defenderActor,
customModifier: 0,
isReady: false
}
defender: defend[0],
listDefenders: defend
};
};

Expand All @@ -85,16 +91,16 @@ export class GMCombatDialog extends FormApplication<FormApplicationOptions, GMCo

constructor(
attacker: TokenDocument,
defender: TokenDocument,
defenders: Array<TokenDocument>,
private hooks: {
onClose: () => Promise<void> | void;
onCounterAttack: (bonus: number) => Promise<void> | void;
onCounterAttack: (defender: TokenDocument, bonus: number) => Promise<void> | void;
},
options: { isCounter?: boolean; counterAttackBonus?: number } = {}
) {
super(getInitialData(attacker, defender, options));
super(getInitialData(attacker, defenders, options));

this.data = getInitialData(attacker, defender, options);
this.data = getInitialData(attacker, defenders, options);

this.render(true);
}
Expand Down Expand Up @@ -146,7 +152,7 @@ export class GMCombatDialog extends FormApplication<FormApplicationOptions, GMCo
this.applyValuesIfBeAble();

if (this.data.calculations?.canCounter) {
this.hooks.onCounterAttack(this.data.calculations.counterAttackBonus);
this.hooks.onCounterAttack(this.data.defender.token, this.data.calculations.counterAttackBonus);
}
});

Expand Down

0 comments on commit 54ea761

Please sign in to comment.