mirror of
https://github.com/thepaperpilot/Planar-Pioneers.git
synced 2024-11-24 17:31:47 +00:00
Implement influences
This commit is contained in:
parent
2a362a95c3
commit
44844f0de7
2 changed files with 339 additions and 66 deletions
|
@ -2,7 +2,7 @@ import ModalVue from "components/Modal.vue";
|
|||
import SpacerVue from "components/layout/Spacer.vue";
|
||||
import StickyVue from "components/layout/Sticky.vue";
|
||||
import { GenericAchievement, createAchievement } from "features/achievements/achievement";
|
||||
import { BoardNode } from "features/boards/board";
|
||||
import { BoardNode, getUniqueNodeID } from "features/boards/board";
|
||||
import { jsx } from "features/feature";
|
||||
import { createRepeatable } from "features/repeatable";
|
||||
import { createResource } from "features/resources/resource";
|
||||
|
@ -18,7 +18,7 @@ import {
|
|||
createMultiplicativeModifier,
|
||||
createSequentialModifier
|
||||
} from "game/modifiers";
|
||||
import { noPersist, persistent } from "game/persistence";
|
||||
import { State, noPersist, persistent } from "game/persistence";
|
||||
import { createCostRequirement } from "game/requirements";
|
||||
import { adjectives, colors, uniqueNamesGenerator } from "unique-names-generator";
|
||||
import Decimal, { DecimalSource } from "util/bignum";
|
||||
|
@ -28,7 +28,14 @@ import { Computable, ProcessedComputable, convertComputable } from "util/compute
|
|||
import { VueFeature, render, renderRow, trackHover } from "util/vue";
|
||||
import { ComputedRef, Ref, computed, ref, unref } from "vue";
|
||||
import { createCollapsibleModifierSections, createFormulaPreview, estimateTime } from "./common";
|
||||
import { main, mineLootTable, resourceNames } from "./projEntry";
|
||||
import {
|
||||
InfluenceState,
|
||||
Influences,
|
||||
influences as influenceTypes,
|
||||
main,
|
||||
mineLootTable,
|
||||
resourceNames
|
||||
} from "./projEntry";
|
||||
import type { ResourceState, Resources, PortalState } from "./projEntry";
|
||||
import { getColor, getName, sfc32 } from "./utils";
|
||||
|
||||
|
@ -39,7 +46,12 @@ export type Treasure = GenericAchievement & {
|
|||
resourceMulti: DecimalSource;
|
||||
};
|
||||
|
||||
export function createPlane(id: string, tier: Resources, seed: number) {
|
||||
export function createPlane(
|
||||
id: string,
|
||||
tier: Resources,
|
||||
seed: number,
|
||||
influences: InfluenceState[]
|
||||
) {
|
||||
return createLayer(id, function (this: BaseLayer) {
|
||||
const random = sfc32(0, seed >> 0, seed >> 32, 1);
|
||||
for (let i = 0; i < 12; i++) random();
|
||||
|
@ -49,8 +61,21 @@ export function createPlane(id: string, tier: Resources, seed: number) {
|
|||
const background = getColor([0.18, 0.2, 0.25], random);
|
||||
const resource = createResource<DecimalSource>(0, getName(random));
|
||||
const tierIndex = resourceNames.indexOf(tier);
|
||||
let difficultyRand = random();
|
||||
if (influences.some(i => i.type === "increaseDiff")) {
|
||||
difficultyRand = difficultyRand / 2 + 0.5;
|
||||
}
|
||||
if (influences.some(i => i.type === "decreaseDiff")) {
|
||||
difficultyRand = difficultyRand / 2;
|
||||
}
|
||||
const difficulty = random() + tierIndex + 1;
|
||||
const length = Math.ceil(random() * (tierIndex + 2));
|
||||
const rewardsLevel = influences.some(i => i.type === "increaseRewards")
|
||||
? difficulty + 1
|
||||
: difficulty;
|
||||
let length = Math.ceil(random() * (tierIndex + 2));
|
||||
if (influences.some(i => i.type === "increaseLength")) {
|
||||
length++;
|
||||
}
|
||||
|
||||
const resourceModifiers: WithRequired<Modifier, "description" | "invert">[] = [];
|
||||
const resourceGainModifier = createSequentialModifier(() => resourceModifiers);
|
||||
|
@ -62,21 +87,30 @@ export function createPlane(id: string, tier: Resources, seed: number) {
|
|||
cost: FormulaSource;
|
||||
}[] = [];
|
||||
|
||||
function prepareFeature(
|
||||
feature: VueFeature,
|
||||
canClick: Computable<boolean>,
|
||||
modifier: WithRequired<Modifier, "description" | "invert">,
|
||||
cost: FormulaSource,
|
||||
previewModifier: WithRequired<Modifier, "invert"> = modifier
|
||||
) {
|
||||
function prepareFeature({
|
||||
feature,
|
||||
canClick,
|
||||
modifier,
|
||||
cost,
|
||||
previewModifier,
|
||||
showETA
|
||||
}: {
|
||||
feature: VueFeature;
|
||||
canClick: Computable<boolean>;
|
||||
modifier: WithRequired<Modifier, "description" | "invert">;
|
||||
cost: FormulaSource;
|
||||
previewModifier?: WithRequired<Modifier, "invert">;
|
||||
showETA?: Computable<boolean | undefined>;
|
||||
}) {
|
||||
canClick = convertComputable(canClick);
|
||||
showETA = convertComputable(showETA);
|
||||
|
||||
const isHovering = trackHover(feature);
|
||||
previews.push({
|
||||
shouldShowPreview: computed(
|
||||
() => unref(canClick as ProcessedComputable<boolean>) && isHovering.value
|
||||
),
|
||||
modifier: previewModifier,
|
||||
modifier: previewModifier ?? modifier,
|
||||
cost
|
||||
});
|
||||
resourceModifiers.push(modifier);
|
||||
|
@ -84,7 +118,10 @@ export function createPlane(id: string, tier: Resources, seed: number) {
|
|||
unrefFormulaSource(cost)
|
||||
);
|
||||
addTooltip(feature, {
|
||||
display: eta,
|
||||
display:
|
||||
showETA == null
|
||||
? eta
|
||||
: () => (unref(showETA as ProcessedComputable<boolean>) ? eta.value : ""),
|
||||
direction: Direction.Down
|
||||
});
|
||||
}
|
||||
|
@ -101,10 +138,15 @@ export function createPlane(id: string, tier: Resources, seed: number) {
|
|||
.times(10)
|
||||
.times(costFormula.evaluate())
|
||||
);
|
||||
const influenceTreasures: Influences[] = [];
|
||||
for (let i = 0; i < length; i++) {
|
||||
const featureWeights = {
|
||||
upgrades: 16,
|
||||
repeatables: i <= 1 ? 0 : 8
|
||||
upgrades: 32,
|
||||
repeatables: i <= 1 ? 0 : 16
|
||||
// conversion: i <= 3 ? 0 : 8,
|
||||
// xp: i <= 5 ? 0 : 4,
|
||||
// dimensions: i <= 7 ? 0 : 2,
|
||||
// prestige: i <= 7 && i < length - 1 ? 0 : 1
|
||||
};
|
||||
const type = pickRandom(featureWeights, random);
|
||||
switch (type) {
|
||||
|
@ -177,12 +219,13 @@ export function createPlane(id: string, tier: Resources, seed: number) {
|
|||
},
|
||||
visibility: upgradeVisibility
|
||||
}));
|
||||
prepareFeature(
|
||||
upgrade,
|
||||
() => !upgrade.bought.value && upgrade.canPurchase.value,
|
||||
prepareFeature({
|
||||
feature: upgrade,
|
||||
canClick: () => upgrade.canPurchase.value,
|
||||
modifier,
|
||||
cost
|
||||
);
|
||||
cost,
|
||||
showETA: () => !upgrade.bought.value
|
||||
});
|
||||
upgrades.push(upgrade);
|
||||
}
|
||||
features.push(upgrades);
|
||||
|
@ -193,6 +236,7 @@ export function createPlane(id: string, tier: Resources, seed: number) {
|
|||
const repeatableTypeWeights = {
|
||||
add: 1.5,
|
||||
mult: 3
|
||||
// pow was too hard to implement such that the cost would be invertible
|
||||
};
|
||||
const upgradeType = pickRandom(repeatableTypeWeights, random);
|
||||
// Repeatables will estimate 5 purchases between each increment of `n`
|
||||
|
@ -279,23 +323,30 @@ export function createPlane(id: string, tier: Resources, seed: number) {
|
|||
}),
|
||||
visibility: repeatableVisibility
|
||||
}));
|
||||
prepareFeature(
|
||||
repeatable,
|
||||
() => unref(repeatable.canClick),
|
||||
prepareFeature({
|
||||
feature: repeatable,
|
||||
canClick: () => unref(repeatable.canClick),
|
||||
modifier,
|
||||
cost,
|
||||
previewModifier
|
||||
);
|
||||
});
|
||||
repeatables.push(repeatable);
|
||||
}
|
||||
features.push(repeatables);
|
||||
break;
|
||||
}
|
||||
const treasureWeights = {
|
||||
cache: 100,
|
||||
generation: 10,
|
||||
resourceMulti: 5,
|
||||
energyMulti: 5
|
||||
cache: influences.some(i => i.type === "increaseCaches") ? 10 : 1,
|
||||
generation: influences.some(i => i.type === "increaseGens") ? 10 : 1,
|
||||
resourceMulti: influences.some(i => i.type === "increaseResourceMults") ? 10 : 1,
|
||||
energyMulti: influences.some(i => i.type === "increaseEnergyMults") ? 2.5 : 0.25,
|
||||
influences:
|
||||
Object.keys(main.influenceNodes.value).length + influenceTreasures.length ===
|
||||
Object.keys(influenceTypes).length
|
||||
? 0
|
||||
: influences.some(i => i.type === "increaseInfluences")
|
||||
? 20
|
||||
: 2
|
||||
};
|
||||
const treasureType = pickRandom(treasureWeights, random);
|
||||
let description = "";
|
||||
|
@ -307,8 +358,8 @@ export function createPlane(id: string, tier: Resources, seed: number) {
|
|||
let resourceMulti: DecimalSource;
|
||||
switch (treasureType) {
|
||||
case "cache":
|
||||
randomResource = getRandomResource(random);
|
||||
description = `Gain ${format(difficulty)}x your current ${randomResource}.`;
|
||||
randomResource = getRandomResource(random, influences);
|
||||
description = `Gain ${format(rewardsLevel)}x your current ${randomResource}.`;
|
||||
onComplete = () =>
|
||||
main.grantResource(
|
||||
randomResource,
|
||||
|
@ -317,29 +368,61 @@ export function createPlane(id: string, tier: Resources, seed: number) {
|
|||
main.resourceNodes.value[randomResource]
|
||||
?.state as unknown as ResourceState | null
|
||||
)?.amount ?? 0,
|
||||
difficulty
|
||||
rewardsLevel
|
||||
)
|
||||
);
|
||||
break;
|
||||
case "generation":
|
||||
randomResource = getRandomResource(random);
|
||||
const gain = Decimal.div(difficulty, 120).times(mineLootTable[randomResource]);
|
||||
randomResource = getRandomResource(random, influences);
|
||||
const gain = Decimal.div(rewardsLevel, 120).times(
|
||||
mineLootTable[randomResource]
|
||||
);
|
||||
description = `Gain ${format(gain)} ${randomResource}/s while plane is active.`;
|
||||
update = diff => main.grantResource(randomResource, Decimal.times(diff, gain));
|
||||
link = computed(() => main.resourceNodes.value[randomResource]);
|
||||
break;
|
||||
case "resourceMulti":
|
||||
effectedResource = randomResource = getRandomResource(random);
|
||||
resourceMulti = Decimal.div(difficulty, 17).pow_base(2);
|
||||
effectedResource = randomResource = getRandomResource(random, influences);
|
||||
resourceMulti = Decimal.div(rewardsLevel, 17).pow_base(2);
|
||||
description = `Gain ${format(
|
||||
resourceMulti
|
||||
)}x ${randomResource} while plane is active.`;
|
||||
break;
|
||||
case "energyMulti":
|
||||
effectedResource = "energy";
|
||||
resourceMulti = Decimal.div(difficulty, 17);
|
||||
resourceMulti = Decimal.div(rewardsLevel, 17);
|
||||
description = `Gain ${format(resourceMulti)}x energy while plane is active.`;
|
||||
break;
|
||||
case "influences":
|
||||
const randomInfluence = pickRandom(
|
||||
(Object.keys(influenceTypes) as Influences[]).reduce((acc, curr) => {
|
||||
acc[curr] =
|
||||
curr in main.influenceNodes.value ||
|
||||
influenceTreasures.includes(curr)
|
||||
? 0
|
||||
: 1;
|
||||
return acc;
|
||||
}, {} as Record<Influences, number>),
|
||||
random
|
||||
);
|
||||
influenceTreasures.push(randomInfluence);
|
||||
description = `Gain a new portal influence`;
|
||||
onComplete = () =>
|
||||
main.board.placeInAvailableSpace({
|
||||
id: getUniqueNodeID(main.board),
|
||||
position: {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
...main.board.types.portal.nodes.value.find(
|
||||
n => (n.state as unknown as PortalState).id === id
|
||||
)!.position
|
||||
},
|
||||
type: "influence",
|
||||
state: {
|
||||
type: randomInfluence,
|
||||
data: influenceTypes[randomInfluence].initialData
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
const milestoneVisibility = visibility;
|
||||
const cost = nextCost.value;
|
||||
|
@ -510,6 +593,7 @@ export function createPlane(id: string, tier: Resources, seed: number) {
|
|||
return {
|
||||
tier: persistent(tier),
|
||||
seed: persistent(seed),
|
||||
influences: persistent(influences as unknown as State[]),
|
||||
name,
|
||||
color,
|
||||
resource,
|
||||
|
@ -539,7 +623,7 @@ export function createPlane(id: string, tier: Resources, seed: number) {
|
|||
style="display: inline"
|
||||
onClick={() => (showModifiersModal.value = true)}
|
||||
>
|
||||
open modifiers
|
||||
modifiers
|
||||
</button>
|
||||
</span>
|
||||
</StickyVue>
|
||||
|
@ -578,8 +662,23 @@ export function createPlane(id: string, tier: Resources, seed: number) {
|
|||
}
|
||||
|
||||
// Using separate method from what's used in mining, because planes are influenced by influences and not things like dowsing
|
||||
function getRandomResource(random: () => number) {
|
||||
const sumResourceWeights = (Object.values(mineLootTable) as number[]).reduce((a, b) => a + b);
|
||||
function getRandomResource(random: () => number, influences: InfluenceState[]) {
|
||||
influences = influences.filter(
|
||||
i => i.type === "increaseResources" || i.type === "decreaseResources"
|
||||
);
|
||||
const sumResourceWeights = (Object.keys(mineLootTable) as Resources[]).reduce((a, b) => {
|
||||
let weight = mineLootTable[b];
|
||||
influences
|
||||
.filter(i => i.data === b)
|
||||
.forEach(influence => {
|
||||
if (influence.type === "increaseResources") {
|
||||
weight *= 1000;
|
||||
} else {
|
||||
weight /= 1000;
|
||||
}
|
||||
});
|
||||
return a + weight;
|
||||
}, 0);
|
||||
const resourceWeightsKeys = Object.keys(mineLootTable) as Resources[];
|
||||
const r = Math.floor(random() * sumResourceWeights);
|
||||
let weight = 0;
|
||||
|
|
|
@ -66,7 +66,7 @@ export interface EmpowererState {
|
|||
|
||||
export interface PortalGeneratorState {
|
||||
tier: Resources | undefined;
|
||||
influences: string[];
|
||||
influences: Influences[];
|
||||
}
|
||||
|
||||
export interface PortalState {
|
||||
|
@ -74,6 +74,11 @@ export interface PortalState {
|
|||
powered: boolean;
|
||||
}
|
||||
|
||||
export interface InfluenceState {
|
||||
type: Influences;
|
||||
data: State;
|
||||
}
|
||||
|
||||
export const mineLootTable = {
|
||||
dirt: 120,
|
||||
sand: 60,
|
||||
|
@ -216,6 +221,95 @@ const passives = {
|
|||
|
||||
export type Passives = keyof typeof passives;
|
||||
|
||||
export const influences = {
|
||||
increaseResources: {
|
||||
description: (state: InfluenceState) => {
|
||||
const resources = state.data as Resources[];
|
||||
if (resources.length === 0) {
|
||||
return "Increase resource odds - Drag a resource to me!";
|
||||
}
|
||||
if (resources.length === 1) {
|
||||
return `Increase ${resources[0]}'s odds`;
|
||||
}
|
||||
return `Increase ${resources.length} resources' odds`;
|
||||
},
|
||||
cost: 2,
|
||||
initialData: []
|
||||
},
|
||||
decreaseResources: {
|
||||
description: (state: InfluenceState) => {
|
||||
const resources = state.data as Resources[];
|
||||
if (resources.length === 0) {
|
||||
return "Decrease resource odds - Drag a resource to me!";
|
||||
}
|
||||
if (resources.length === 1) {
|
||||
return `Decrease ${resources[0]}'s odds`;
|
||||
}
|
||||
return `Decrease ${resources.length} resources' odds`;
|
||||
},
|
||||
cost: 2,
|
||||
initialData: []
|
||||
},
|
||||
increaseLength: {
|
||||
description: "Increase length",
|
||||
cost: 100,
|
||||
initialData: undefined
|
||||
},
|
||||
increaseCaches: {
|
||||
description: "Increase caches odds",
|
||||
cost: 10,
|
||||
initialData: undefined
|
||||
},
|
||||
increaseGens: {
|
||||
description: "Increase generators odds",
|
||||
cost: 10,
|
||||
initialData: undefined
|
||||
},
|
||||
increaseInfluences: {
|
||||
description: "Increase influences odds",
|
||||
cost: 10,
|
||||
initialData: undefined
|
||||
},
|
||||
increaseEnergyMults: {
|
||||
description: "Increase energy mults odds",
|
||||
cost: 10,
|
||||
initialData: undefined
|
||||
},
|
||||
increaseResourceMults: {
|
||||
description: "Increase resource mults odds",
|
||||
cost: 10,
|
||||
initialData: undefined
|
||||
},
|
||||
increaseDiff: {
|
||||
description: "Increase difficulty/rewards odds",
|
||||
cost: 10,
|
||||
initialData: undefined
|
||||
},
|
||||
decreaseDiff: {
|
||||
description: "Decrease difficulty/rewards odds",
|
||||
cost: 10,
|
||||
initialData: undefined
|
||||
},
|
||||
increaseRewards: {
|
||||
description: "Increase rewards level",
|
||||
cost: 1e4,
|
||||
initialData: undefined
|
||||
}
|
||||
// relic: {
|
||||
// description: "Max length/difficulty, add tier-unique relic",
|
||||
// cost: 1e6,
|
||||
// initialData: undefined
|
||||
// }
|
||||
} as const satisfies Record<
|
||||
string,
|
||||
{
|
||||
description: string | ((state: InfluenceState) => string);
|
||||
cost: DecimalSource;
|
||||
initialData?: State;
|
||||
}
|
||||
>;
|
||||
export type Influences = keyof typeof influences;
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
|
@ -242,6 +336,13 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
|||
iron: board.types.portalGenerator.nodes.value[0]
|
||||
}));
|
||||
|
||||
const influenceNodes: ComputedRef<Record<Influences, BoardNode>> = computed(() => ({
|
||||
...board.types.influence.nodes.value.reduce((acc, curr) => {
|
||||
acc[(curr.state as unknown as InfluenceState).type] = curr;
|
||||
return acc;
|
||||
}, {} as Record<Influences, BoardNode>)
|
||||
}));
|
||||
|
||||
const resourceLevels = computed(() =>
|
||||
resourceNames.reduce((acc, curr) => {
|
||||
const amount =
|
||||
|
@ -336,11 +437,12 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
|||
id: "deselect",
|
||||
icon: "close",
|
||||
tooltip: (node: BoardNode) => ({
|
||||
text:
|
||||
"resources" in (node.state as object) ? "Disconnect resources" : "Disconnect tools"
|
||||
text: "tools" in (node.state as object) ? "Disconnect tools" : "Disconnect resources"
|
||||
}),
|
||||
onClick(node: BoardNode) {
|
||||
if ("resources" in (node.state as object)) {
|
||||
if (Array.isArray(node.state)) {
|
||||
node.state = [];
|
||||
} else if ("resources" in (node.state as object)) {
|
||||
node.state = { ...(node.state as object), resources: [] };
|
||||
} else if ("tools" in (node.state as object)) {
|
||||
node.state = { ...(node.state as object), tools: [] };
|
||||
|
@ -349,6 +451,9 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
|||
board.selectedNode.value = null;
|
||||
},
|
||||
visibility: (node: BoardNode) => {
|
||||
if (Array.isArray(node.state)) {
|
||||
return node.state.length > 0;
|
||||
}
|
||||
if ("resources" in (node.state as object)) {
|
||||
return (node.state as { resources: Resources[] }).resources.length > 0;
|
||||
}
|
||||
|
@ -886,11 +991,9 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
|||
}-tier portal`
|
||||
};
|
||||
}
|
||||
if ((board as GenericBoard).draggingNode.value?.type === "resource") {
|
||||
const resource = (
|
||||
(board as GenericBoard).draggingNode.value
|
||||
?.state as unknown as ResourceState
|
||||
).type;
|
||||
const draggingNode = (board as GenericBoard).draggingNode.value;
|
||||
if (draggingNode?.type === "resource") {
|
||||
const resource = (draggingNode.state as unknown as ResourceState).type;
|
||||
const text =
|
||||
(node.state as unknown as PortalGeneratorState).tier === resource
|
||||
? "Disconnect"
|
||||
|
@ -899,8 +1002,17 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
|||
text,
|
||||
color: "var(--accent2)"
|
||||
};
|
||||
} else if (draggingNode?.type === "influence") {
|
||||
const influence = (draggingNode.state as unknown as InfluenceState).type;
|
||||
const { influences } = node.state as unknown as PortalGeneratorState;
|
||||
if (influences.includes(influence)) {
|
||||
return { text: "Disconnect", color: "var(--accent2)" };
|
||||
}
|
||||
return {
|
||||
text: "Add influence",
|
||||
color: "var(--accent2)"
|
||||
};
|
||||
}
|
||||
// TODO handle influences
|
||||
return null;
|
||||
},
|
||||
actionDistance: Math.PI / 4,
|
||||
|
@ -937,12 +1049,18 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
|||
while (`portal-${id}` in layers) {
|
||||
id++;
|
||||
}
|
||||
const { tier, influences } =
|
||||
node.state as unknown as PortalGeneratorState;
|
||||
addLayer(
|
||||
createPlane(
|
||||
`portal-${id}`,
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
(node.state as unknown as PortalGeneratorState).tier!,
|
||||
Math.floor(Math.random() * 4294967296)
|
||||
tier!,
|
||||
Math.floor(Math.random() * 4294967296),
|
||||
influences.map(
|
||||
influence =>
|
||||
influenceNodes.value[influence]
|
||||
.state as unknown as InfluenceState
|
||||
)
|
||||
),
|
||||
player
|
||||
);
|
||||
|
@ -974,7 +1092,8 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
|||
tier: droppedType === currentType ? undefined : droppedType
|
||||
};
|
||||
} else if (otherNode.type === "influence") {
|
||||
const droppedInfluence = otherNode.state as string;
|
||||
const droppedInfluence = (otherNode.state as unknown as InfluenceState)
|
||||
.type;
|
||||
const currentInfluences = (node.state as unknown as PortalGeneratorState)
|
||||
.influences;
|
||||
if (currentInfluences.includes(droppedInfluence)) {
|
||||
|
@ -1022,6 +1141,42 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
|||
outlineColor: node =>
|
||||
(layers[(node.state as unknown as PortalState).id] as GenericPlane).background,
|
||||
draggable: true
|
||||
},
|
||||
influence: {
|
||||
shape: Shape.Circle,
|
||||
size: 50,
|
||||
title: node => (node.state as unknown as InfluenceState).type,
|
||||
label: node => {
|
||||
if (node === board.selectedNode.value) {
|
||||
const state = node.state as unknown as InfluenceState;
|
||||
const desc = influences[state.type].description;
|
||||
return { text: typeof desc === "function" ? desc(state) : desc };
|
||||
}
|
||||
return null;
|
||||
},
|
||||
actionDistance: Math.PI / 4,
|
||||
actions: [deselectAllAction],
|
||||
canAccept: (node, otherNode) => {
|
||||
if (otherNode.type !== "resource") {
|
||||
return false;
|
||||
}
|
||||
return Array.isArray(node.state);
|
||||
},
|
||||
onDrop: (node, otherNode) => {
|
||||
if (otherNode.type !== "resource") {
|
||||
return;
|
||||
}
|
||||
const resource = (otherNode.state as unknown as ResourceState).type;
|
||||
const resources = node.state as Resources[];
|
||||
if (resources.includes(resource)) {
|
||||
node.state = resources.filter(r => r !== resource);
|
||||
} else {
|
||||
node.state = [...resources, resource];
|
||||
}
|
||||
board.selectedNode.value = node;
|
||||
},
|
||||
outlineColor: "var(--danger)",
|
||||
draggable: true
|
||||
}
|
||||
},
|
||||
style: {
|
||||
|
@ -1098,21 +1253,25 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
|||
});
|
||||
}
|
||||
if (portalGenerator.value != null) {
|
||||
if ((portalGenerator.value.state as unknown as PortalGeneratorState).tier != null) {
|
||||
const state = portalGenerator.value.state as unknown as PortalGeneratorState;
|
||||
if (state.tier != null) {
|
||||
links.push({
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
startNode: portalGenerator.value!,
|
||||
endNode:
|
||||
resourceNodes.value[
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
(portalGenerator.value.state as unknown as PortalGeneratorState)
|
||||
.tier!
|
||||
],
|
||||
startNode: portalGenerator.value,
|
||||
endNode: resourceNodes.value[state.tier],
|
||||
stroke: "var(--foreground)",
|
||||
strokeWidth: 4
|
||||
});
|
||||
// TODO link to influences
|
||||
}
|
||||
state.influences.forEach(influence => {
|
||||
console.log(influence);
|
||||
links.push({
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
startNode: portalGenerator.value!,
|
||||
endNode: influenceNodes.value[influence],
|
||||
stroke: "var(--foreground)",
|
||||
strokeWidth: 4
|
||||
});
|
||||
});
|
||||
(board as GenericBoard).types.portal.nodes.value.forEach(node => {
|
||||
const plane = layers[(node.state as unknown as PortalState).id] as GenericPlane;
|
||||
plane.links.value.forEach(n => {
|
||||
|
@ -1142,6 +1301,19 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
|||
return links;
|
||||
});
|
||||
}
|
||||
Object.values(influenceNodes.value).forEach(node => {
|
||||
const state = node.state as unknown as InfluenceState;
|
||||
if (state.type === "increaseResources" || state.type === "decreaseResources") {
|
||||
(state.data as Resources[]).forEach(resource => {
|
||||
links.push({
|
||||
startNode: node,
|
||||
endNode: resourceNodes.value[resource],
|
||||
stroke: "var(--foreground)",
|
||||
strokeWidth: 4
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
return links;
|
||||
}
|
||||
}));
|
||||
|
@ -1597,6 +1769,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
|||
passives,
|
||||
resourceNodes,
|
||||
toolNodes,
|
||||
influenceNodes,
|
||||
grantResource,
|
||||
activePortals,
|
||||
display: jsx(() => (
|
||||
|
@ -1630,7 +1803,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
|||
style="display: inline"
|
||||
onClick={() => (showModifiersModal.value = true)}
|
||||
>
|
||||
open modifiers
|
||||
modifiers
|
||||
</button>
|
||||
</span>
|
||||
{player.devSpeed === 0 ? (
|
||||
|
@ -1662,7 +1835,8 @@ export const getInitialLayers = (
|
|||
createPlane(
|
||||
`portal-${id}`,
|
||||
layer.tier ?? "dirt",
|
||||
layer.seed ?? Math.floor(Math.random() * 4294967296)
|
||||
layer.seed ?? Math.floor(Math.random() * 4294967296),
|
||||
(layer.influences ?? []) as unknown as InfluenceState[]
|
||||
)
|
||||
);
|
||||
id++;
|
||||
|
|
Loading…
Reference in a new issue