Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
Eranziel committed Sep 3, 2021
2 parents 9bfb63a + 1dbc01e commit 54c39f7
Show file tree
Hide file tree
Showing 20 changed files with 497 additions and 361 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
"license": "",
"devDependencies": {
"@league-of-foundry-developers/foundry-vtt-types": "^0.8.9-2",
"@pyoner/svelte-types": "^3.4.4-2",
"@sveltejs/vite-plugin-svelte": "^1.0.0-next.15",
"@tsconfig/svelte": "^2.0.1",
"archiver": "^3.1.1",
Expand Down
60 changes: 15 additions & 45 deletions public/packs/aoe-templates.db

Large diffs are not rendered by default.

15 changes: 9 additions & 6 deletions src/lancer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -481,13 +481,16 @@ Hooks.once("init", async function () {
// ------------------------------------------------------------------------
// Sliding HUD Zone, including accuracy/difficulty window
Hooks.on('renderHeadsUpDisplay', slidingHUD.attach);
Hooks.on('targetToken', (_user: User, _token: Token, isNewTarget: boolean) => {
macros.refreshTargeting(isNewTarget ? "may open new window" : "only refresh open window");
let openingBasicAttackLock = false;
Hooks.on('targetToken', (user: User, _token: Token, isNewTarget: boolean) => {
if (user.isSelf && isNewTarget && !openingBasicAttackLock) {
// this only works because openBasicAttack is a promise and runs on a future tick
openingBasicAttackLock = true;
macros.openBasicAttack().finally(() => {
openingBasicAttackLock = false;
});
}
});
Hooks.on('createActiveEffect', () => macros.refreshTargeting("only refresh open window"));
Hooks.on('deleteActiveEffect', () => macros.refreshTargeting("only refresh open window"));
// updateToken triggers on things like token movement (spotter) and probably a lot of other things
Hooks.on('updateToken', () => macros.refreshTargeting("only refresh open window"));
});

// TODO: either remove when sanity check is no longer needed, or find a better home.
Expand Down
4 changes: 3 additions & 1 deletion src/module/actor/lancer-actor-sheet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,9 @@ export class LancerActorSheet<T extends LancerActorType> extends ActorSheet<
if (!item) return ui.notifications!.warn(`Error rolling macro: Couldn't find weapon with ID ${weaponId}.`);

const weapon = item;
prepareItemMacro(this.actor.id!, weapon.id!);
// @ts-ignore
let id = this.token ? this.token.id : this.actor.id!;
prepareItemMacro(id, weapon.id!);
});

// TODO: This should really just be a single item-macro class
Expand Down
13 changes: 9 additions & 4 deletions src/module/actor/npc-sheet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ export class LancerNPCSheet extends LancerActorSheet<EntryType.NPC> {
ev.stopPropagation(); // Avoids triggering parent event handlers

const el = $(ev.currentTarget).closest(".item")[0] as HTMLElement;

prepareItemMacro(this.actor.id!, <string>el.getAttribute("data-id")).then();
// @ts-ignore
let id = this.token ? this.token.id : this.actor.id!;
prepareItemMacro(id, <string>el.getAttribute("data-id")).then();
});

// Stat rollers
Expand All @@ -74,8 +75,10 @@ export class LancerNPCSheet extends LancerActorSheet<EntryType.NPC> {
bonus: statInput.value,
};

// @ts-ignore
let id = this.token ? this.token.id : this.actor.id!;
console.log(`${lp} Rolling ${mData.title} check, bonus: ${mData.bonus}`);
prepareStatMacro(this.actor.id!, this.getStatPath(ev)!);
prepareStatMacro(id, this.getStatPath(ev)!);
});

// Trigger rollers
Expand All @@ -88,7 +91,9 @@ export class LancerNPCSheet extends LancerActorSheet<EntryType.NPC> {
ev.stopPropagation();
const techElement = $(ev.currentTarget).closest(".item")[0] as HTMLElement;
let techId = techElement.getAttribute("data-id");
prepareItemMacro(this.actor.id!, techId!);
// @ts-ignore
let id = this.token ? this.token.id : this.actor.id!;
prepareItemMacro(id, techId!);
});

// Item/Macroable Dragging
Expand Down
138 changes: 109 additions & 29 deletions src/module/helpers/acc_diff/Form.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,17 @@
import ConsumeLockOn from './ConsumeLockOn.svelte';
import Total from './Total.svelte';
import PlusMinusInput from './PlusMinusInput.svelte';
import type { LancerItem } from '../../item/lancer-item';
import { RangeType } from 'machine-mind';
import { WeaponRangeTemplate } from '../../pixi/weapon-range-template';
import { fade } from '../slidinghud';
import { targetsFromTemplate } from '../../macros';
export let weapon: AccDiffWeapon;
export let base: AccDiffBase;
export let targets: AccDiffTarget[];
export let title: string;
export const lancerItem: any | null = null;
export let lancerItem: LancerItem | null;
export let kind: "hase" | "attack";
Expand All @@ -42,6 +47,36 @@
window.addEventListener('keydown', escHandler);
return { destroy() { window.removeEventListener('keydown', escHandler); } }
}
function findRanges() {
return lancerItem?.rangesFor([
RangeType.Blast,
RangeType.Burst,
RangeType.Cone,
RangeType.Line,
]) ?? [];
}
function deployTemplate(range: WeaponRangeTemplate['range']) {
const creator = lancerItem?.parent;
const token = (
creator?.token?.object ??
creator?.getActiveTokens().shift() ??
undefined
) as Token | undefined;
const t = WeaponRangeTemplate.fromRange(range, token);
if (!t) return;
fade('out');
t.placeTemplate()
.catch(e => {
console.warn(e);
return;
})
.then(t => {
if (t) targetsFromTemplate(t.id!);
fade('in');
});
}
</script>

<form id="accdiff" class="accdiff window-content" use:escToCancel
Expand All @@ -50,6 +85,17 @@
<div class="lancer-header mech-weapon medium">
{#if kind == "attack"}
<i class="cci cci-weapon i--m i--light"></i>
{#if lancerItem}
{#each findRanges() as range}
<button
class="range-button"
type="button"
on:click={() => deployTemplate(range)}
>
<i class="cci cci-{range.type.toLowerCase()} i--m i--light"></i>
</button>
{/each}
{/if}
{:else if kind == "hase"}
<i class="fas fa-dice-d20 i--m i--light"></i>
{/if}
Expand Down Expand Up @@ -228,7 +274,7 @@
</div>
</form>

<style>
<style lang="scss">
:global(.accdiff-grid) {
display: flex;
justify-content: space-between;
Expand Down Expand Up @@ -327,9 +373,9 @@
vertical-align: top;
}
/* there's a very specific foundry rule that adds some margin here
/* there's a very specific EMU rule that adds some margin here
because it assumes all icons in buttons are followed by text, I think */
#accdiff .accdiff-target-row button > i {
#accdiff .accdiff-target-row button > i, #accdiff .mech-weapon button > i {
margin-inline-end: 0;
}
Expand All @@ -353,37 +399,71 @@
white-space: nowrap;
}
.accdiff-target-row .accdiff-button {
align-items: center;
display: inline-flex;
justify-content: center;
margin: 0;
border: none;
box-shadow: 1px 1px 1px var(--main-theme-color);
#accdiff button {
transition: 100ms cubic-bezier(0.075, 0.82, 0.165, 1);
}
.accdiff-target-row .accdiff-button:hover {
background-color: var(--main-theme-text);
box-shadow: 1px 1px 1px var(--main-theme-color);
}
.accdiff-target-row .accdiff-button:focus {
box-shadow: 1px 1px 1px var(--main-theme-color);
}
.accdiff-target-row .accdiff-button:active {
transform: translateX(2px) translateY(2px);
box-shadow: -1px -1px 1px var(--main-theme-color);
}
.accdiff-target-row .accdiff-button i {
text-shadow: none;
color: rgba(var(--color-text-lightest), 1);
cursor: pointer;
.accdiff-target-row {
.accdiff-button {
cursor: pointer;
align-items: center;
display: inline-flex;
justify-content: center;
margin: 0;
border: none;
box-shadow: 1px 1px 1px var(--main-theme-color);
&:hover, &:focus {
box-shadow: 1px 1px 1px var(--main-theme-color);
}
&:hover {
background-color: var(--main-theme-text);
}
&:active {
transform: translateX(2px) translateY(2px);
box-shadow: -1px -1px 1px var(--main-theme-color);
}
& i {
text-shadow: none;
color: rgba(var(--color-text-lightest), 1);
}
}
}
.accdiff-target-row .card-title {
background-color: #00000000;
}
#accdiff .mech-weapon {
span {
margin-right: 1em;
margin-left: 1em;
}
.range-button {
cursor: pointer;
box-shadow: 1px 1px 1px 0.6px rgba(0, 0, 0, 0.7);
border: none;
text-align: left;
flex: 0 0;
margin-left: 8px;
margin-right: 0px;
margin-top: 5px;
margin-bottom: 7px;
padding: 0;
background-color: var(--main-theme-color);
&:hover, &:focus {
box-shadow: 1px 1px 1px 0.6px rgba(0, 0, 0, 0.7);
}
&:hover {
background-color: var(--protocol-color);
}
&:active {
transform: translateX(2px) translateY(2px);
box-shadow: -1px -1px 1px 0.6px rgba(0, 0, 0, 0.7);
}
& i {
margin: 2px;
padding: 0;
}
}
}
</style>
2 changes: 2 additions & 0 deletions src/module/helpers/acc_diff/invisibility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ export default class Invisibility implements AccDiffCheckboxPluginData {
return roll;
}
}

readonly rollPrecedence = -9999; // after _everything_
}

// to check whether the static methods match the interface
Expand Down
1 change: 1 addition & 0 deletions src/module/helpers/acc_diff/plugin.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type UIBehaviour = CheckboxUI | NoUI;

declare interface RollModifier {
modifyRoll(roll: string): string
get rollPrecedence(): number // higher numbers happen earlier
}

declare interface Dehydrated {
Expand Down
33 changes: 18 additions & 15 deletions src/module/helpers/acc_diff/spotter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { AccDiffPlugin, AccDiffPluginData } from "./plugin";
import type { AccDiffData, AccDiffTarget } from "./index";
import type { LancerActor } from "../../actor/lancer-actor";
import type { Mech, Pilot } from "machine-mind";
import type { LancerToken } from "../../token";

// this is an example of a case implemented without defining a full class
function adjacentSpotter(actor: LancerActor): boolean {
Expand All @@ -11,24 +12,25 @@ function adjacentSpotter(actor: LancerActor): boolean {
return false;
}

// this isn't adjacency, it's "is within range 1 LOS with a hack for larger mechs", but it's good enough
// computation taken from sensor-sight
let radius = actor.data.data.derived.mm!.Size;
let token = actor.getActiveTokens()[0];
// TODO: TYPECHECK: center does always seem to exist on this thing ts thinks is a LancerTokenDocument
let point = (token as any).center;
// computation shamelessly stolen from sensor-sight

function inRange(token: { x: number; y: number }) {
const range = Math.sqrt((token.x - point.x) * (token.x - point.x) + (token.y - point.y) * (token.y - point.y));
const scale = canvas!.scene!.data.gridType > 1 ? Math.sqrt(3) / 2 : 1; // for hexes
const grid = canvas!.scene!.data.grid;
return (radius + 0.01) * grid * scale > range;
// TODO: report this as a bug to league-types
let token: LancerToken = actor.getActiveTokens()[0] as unknown as LancerToken;

const spaces = token.getOccupiedSpaces("updated position");
function adjacent(token: LancerToken) {
const otherSpaces = token.getOccupiedSpaces("updated position");
const rays = spaces.flatMap(s => otherSpaces.map(t => ({ ray: new Ray(s, t) })));
const min_d = Math.min(
...canvas.grid!.grid!.measureDistances(rays, { gridSpaces: true })
);
return min_d < 1.1;
}

// TODO: TYPECHECK: all of this seems to work
let adjacentPilots = (canvas!.tokens!.objects!.children as Token[])
.filter((t: Token) => t.actor?.is_mech() && inRange((t as any).center) && t.id != token.id)
.map((t: Token) => (t.actor!.data.data.derived.mm! as Mech).Pilot);
let adjacentPilots = (canvas!.tokens!.objects!.children as LancerToken[])
.filter((t: LancerToken) => t.actor?.is_mech() && adjacent(t) && t.id != token.id)
.map((t: LancerToken) => (t.actor!.data.data.derived.mm! as Mech).Pilot);

return !!adjacentPilots.find((p: Pilot | null) => p?.Talents.find(t => t.LID == "t_spotter"));
}
Expand All @@ -52,11 +54,12 @@ function spotter(): AccDiffPluginData {
},
modifyRoll(roll: string) {
if (this.uiState) {
return roll.replace("1d20", "2d20kh1[spotter]");
return `{${roll},${roll}}kh[🎯 spotter]`;
} else {
return roll;
}
},
rollPrecedence: -100, // after numeric modifiers
hydrate(data: AccDiffData, target?: AccDiffTarget) {
this.actor = data.lancerActor || null;
this.target = target || null;
Expand Down
6 changes: 5 additions & 1 deletion src/module/helpers/compcon-login-form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ export default class CompconLoginForm extends FormApplication {
populatePilotCache();
return this.close();
} catch (e) {
ui.notifications!.error(`Could not log in to Comp/Con: ${e}`);
if (e instanceof Error) {
ui.notifications!.error(`Could not log in to Comp/Con: ${e.message}`);
} else {
ui.notifications!.error(`Could not log in to Comp/Con: ${e}`);
}
}
}
}
11 changes: 3 additions & 8 deletions src/module/helpers/refs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -299,10 +299,7 @@ export function editable_mm_ref_list_item<T extends LancerItemType>(
iconPath: `systems/${game.system.id}/assets/icons/macro-icons/mech_system.svg`,
title: sys.Name,
fn: "prepareItemMacro",
args: [
sys.Flags.orig_doc.actor?.id ?? "",
sys.Flags.orig_doc.id
]
args: [sys.Flags.orig_doc.actor?.id ?? "", sys.Flags.orig_doc.id],
};

let limited = "";
Expand Down Expand Up @@ -348,14 +345,12 @@ export function editable_mm_ref_list_item<T extends LancerItemType>(
</div>
<ul style="grid-area: 2/1/3/3">`;


for (var i = 0; i < talent.CurrentRank; i++) {

let talent_actions = "";

if (talent.Ranks[i].Actions) {
talent_actions = talent.Ranks[i].Actions.map((a: Action, i: number | undefined) => {
return buildActionHTML(a, { full: true, num: i });
talent_actions = talent.Ranks[i].Actions.map((a: Action) => {
return buildActionHTML(a, { full: true, num: talent.Actions.indexOf(a) });
}).join("");
}

Expand Down
Loading

0 comments on commit 54c39f7

Please sign in to comment.