feat(calculation-details): improve the overall ability of this component (#74)
This commit is contained in:
@@ -33,183 +33,81 @@ Hammerhead II x1
|
||||
export const hashFit =
|
||||
"fit:v1:H4sIAAAAAAAAClXOMQ7CMAwF0L2n6AE8xD92bLMiRhi4AQMSrND7i7itGrG9JHb+R4QLnet8fyzL8zOf5tv7+7pcaWIoiTY04u7WrcGrLe/LZk+zppkA7CODdTBIGOydKFTVoiRzzfMdIFZrmYdKHOyWlEEdW0ZQW3N7hYNxsJZBHsRgL+ammRagypZBU9RO3yid1bKuEkRyylDy0CxIxTBthXQdScmmIt7I/+72D6JNPx7qugdyAQAA";
|
||||
|
||||
export const fullFit = {
|
||||
name: "C3 Ratter : NishEM",
|
||||
ship_type_id: 29984,
|
||||
description: "",
|
||||
items: [
|
||||
{
|
||||
flag: 125,
|
||||
quantity: 1,
|
||||
type_id: 45626,
|
||||
},
|
||||
{
|
||||
flag: 126,
|
||||
quantity: 1,
|
||||
type_id: 45591,
|
||||
},
|
||||
{
|
||||
flag: 127,
|
||||
quantity: 1,
|
||||
type_id: 45601,
|
||||
},
|
||||
{
|
||||
flag: 128,
|
||||
quantity: 1,
|
||||
type_id: 45615,
|
||||
},
|
||||
{
|
||||
flag: 11,
|
||||
quantity: 1,
|
||||
type_id: 22291,
|
||||
},
|
||||
{
|
||||
flag: 12,
|
||||
quantity: 1,
|
||||
type_id: 22291,
|
||||
},
|
||||
{
|
||||
flag: 13,
|
||||
quantity: 1,
|
||||
type_id: 22291,
|
||||
},
|
||||
{
|
||||
flag: 19,
|
||||
quantity: 1,
|
||||
type_id: 41218,
|
||||
},
|
||||
{
|
||||
flag: 20,
|
||||
quantity: 1,
|
||||
type_id: 35790,
|
||||
},
|
||||
{
|
||||
flag: 21,
|
||||
quantity: 1,
|
||||
type_id: 2281,
|
||||
},
|
||||
{
|
||||
flag: 22,
|
||||
quantity: 1,
|
||||
type_id: 15766,
|
||||
},
|
||||
{
|
||||
flag: 23,
|
||||
quantity: 1,
|
||||
type_id: 19187,
|
||||
},
|
||||
{
|
||||
flag: 24,
|
||||
quantity: 1,
|
||||
type_id: 19187,
|
||||
},
|
||||
{
|
||||
flag: 25,
|
||||
quantity: 1,
|
||||
type_id: 35790,
|
||||
},
|
||||
{
|
||||
flag: 27,
|
||||
quantity: 1,
|
||||
type_id: 25715,
|
||||
charge: {
|
||||
type_id: 20308,
|
||||
},
|
||||
},
|
||||
{
|
||||
flag: 28,
|
||||
quantity: 1,
|
||||
type_id: 25715,
|
||||
charge: {
|
||||
type_id: 20308,
|
||||
},
|
||||
},
|
||||
{
|
||||
flag: 29,
|
||||
quantity: 1,
|
||||
type_id: 25715,
|
||||
charge: {
|
||||
type_id: 20308,
|
||||
},
|
||||
},
|
||||
{
|
||||
flag: 30,
|
||||
quantity: 1,
|
||||
type_id: 25715,
|
||||
charge: {
|
||||
type_id: 20308,
|
||||
},
|
||||
},
|
||||
{
|
||||
flag: 31,
|
||||
quantity: 1,
|
||||
type_id: 25715,
|
||||
charge: {
|
||||
type_id: 20308,
|
||||
},
|
||||
},
|
||||
{
|
||||
flag: 32,
|
||||
quantity: 1,
|
||||
type_id: 25715,
|
||||
charge: {
|
||||
type_id: 20308,
|
||||
},
|
||||
},
|
||||
{
|
||||
flag: 33,
|
||||
quantity: 1,
|
||||
type_id: 28756,
|
||||
},
|
||||
{
|
||||
flag: 92,
|
||||
quantity: 1,
|
||||
type_id: 31724,
|
||||
},
|
||||
{
|
||||
flag: 93,
|
||||
quantity: 1,
|
||||
type_id: 31824,
|
||||
},
|
||||
{
|
||||
flag: 94,
|
||||
quantity: 1,
|
||||
type_id: 31378,
|
||||
},
|
||||
{
|
||||
flag: 5,
|
||||
quantity: 3720,
|
||||
type_id: 24492,
|
||||
},
|
||||
{
|
||||
flag: 5,
|
||||
quantity: 5472,
|
||||
type_id: 2679,
|
||||
},
|
||||
{
|
||||
flag: 5,
|
||||
quantity: 1,
|
||||
type_id: 35795,
|
||||
},
|
||||
{
|
||||
flag: 5,
|
||||
quantity: 1,
|
||||
type_id: 35794,
|
||||
},
|
||||
{
|
||||
flag: 5,
|
||||
quantity: 8,
|
||||
type_id: 30486,
|
||||
},
|
||||
{
|
||||
flag: 5,
|
||||
quantity: 1,
|
||||
type_id: 35794,
|
||||
},
|
||||
{
|
||||
flag: 5,
|
||||
quantity: 396,
|
||||
type_id: 24492,
|
||||
},
|
||||
],
|
||||
};
|
||||
export const fullFits = [
|
||||
{
|
||||
name: "Tengu",
|
||||
ship_type_id: 29984,
|
||||
description: "",
|
||||
items: [
|
||||
{ flag: 125, quantity: 1, type_id: 45626 },
|
||||
{ flag: 126, quantity: 1, type_id: 45591 },
|
||||
{ flag: 127, quantity: 1, type_id: 45601 },
|
||||
{ flag: 128, quantity: 1, type_id: 45615 },
|
||||
{ flag: 11, quantity: 1, type_id: 22291 },
|
||||
{ flag: 12, quantity: 1, type_id: 22291 },
|
||||
{ flag: 13, quantity: 1, type_id: 22291 },
|
||||
{ flag: 19, quantity: 1, type_id: 41218 },
|
||||
{ flag: 20, quantity: 1, type_id: 35790 },
|
||||
{ flag: 21, quantity: 1, type_id: 2281 },
|
||||
{ flag: 22, quantity: 1, type_id: 15766 },
|
||||
{ flag: 23, quantity: 1, type_id: 19187 },
|
||||
{ flag: 24, quantity: 1, type_id: 19187 },
|
||||
{ flag: 25, quantity: 1, type_id: 35790 },
|
||||
{ flag: 27, quantity: 1, type_id: 25715, charge: { type_id: 20308 } },
|
||||
{ flag: 28, quantity: 1, type_id: 25715, charge: { type_id: 20308 } },
|
||||
{ flag: 29, quantity: 1, type_id: 25715, charge: { type_id: 20308 } },
|
||||
{ flag: 30, quantity: 1, type_id: 25715, charge: { type_id: 20308 } },
|
||||
{ flag: 31, quantity: 1, type_id: 25715, charge: { type_id: 20308 } },
|
||||
{ flag: 32, quantity: 1, type_id: 25715, charge: { type_id: 20308 } },
|
||||
{ flag: 33, quantity: 1, type_id: 28756 },
|
||||
{ flag: 92, quantity: 1, type_id: 31724 },
|
||||
{ flag: 93, quantity: 1, type_id: 31824 },
|
||||
{ flag: 94, quantity: 1, type_id: 31378 },
|
||||
{ flag: 5, quantity: 3720, type_id: 24492 },
|
||||
{ flag: 5, quantity: 5472, type_id: 2679 },
|
||||
{ flag: 5, quantity: 1, type_id: 35795 },
|
||||
{ flag: 5, quantity: 1, type_id: 35794 },
|
||||
{ flag: 5, quantity: 8, type_id: 30486 },
|
||||
{ flag: 5, quantity: 1, type_id: 35794 },
|
||||
{ flag: 5, quantity: 396, type_id: 24492 },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Legion",
|
||||
ship_type_id: 29986,
|
||||
description: "",
|
||||
items: [
|
||||
{ flag: 21, quantity: 1, type_id: 527 },
|
||||
{ flag: 19, quantity: 1, type_id: 2024 },
|
||||
{ flag: 15, quantity: 1, type_id: 2364 },
|
||||
{ flag: 27, quantity: 1, type_id: 3025, charge: { type_id: 253 } },
|
||||
{ flag: 28, quantity: 1, type_id: 3025, charge: { type_id: 253 } },
|
||||
{ flag: 29, quantity: 1, type_id: 3025, charge: { type_id: 253 } },
|
||||
{ flag: 30, quantity: 1, type_id: 3025, charge: { type_id: 253 } },
|
||||
{ flag: 31, quantity: 1, type_id: 3025, charge: { type_id: 253 } },
|
||||
{ flag: 32, quantity: 1, type_id: 3025, charge: { type_id: 253 } },
|
||||
{ flag: 20, quantity: 1, type_id: 3244 },
|
||||
{ flag: 11, quantity: 1, type_id: 3530 },
|
||||
{ flag: 14, quantity: 1, type_id: 5839 },
|
||||
{ flag: 34, quantity: 1, type_id: 11578 },
|
||||
{ flag: 5, quantity: 6, type_id: 12826 },
|
||||
{ flag: 12, quantity: 1, type_id: 14072 },
|
||||
{ flag: 13, quantity: 1, type_id: 14072 },
|
||||
{ flag: 33, quantity: 1, type_id: 28756 },
|
||||
{ flag: 5, quantity: 2, type_id: 30832 },
|
||||
{ flag: 5, quantity: 2, type_id: 30834 },
|
||||
{ flag: 92, quantity: 1, type_id: 31055 },
|
||||
{ flag: 94, quantity: 1, type_id: 31071 },
|
||||
{ flag: 93, quantity: 1, type_id: 31215 },
|
||||
{ flag: 5, quantity: 1, type_id: 32014 },
|
||||
{ flag: 5, quantity: 1, type_id: 33474 },
|
||||
{ flag: 22, quantity: 1, type_id: 35656 },
|
||||
{ flag: 126, quantity: 1, type_id: 45586 },
|
||||
{ flag: 128, quantity: 1, type_id: 45598 },
|
||||
{ flag: 125, quantity: 1, type_id: 45612 },
|
||||
{ flag: 127, quantity: 1, type_id: 45622 },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export const fullFit = fullFits[0];
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { Decorator, Meta, StoryObj } from "@storybook/react";
|
||||
import React from "react";
|
||||
|
||||
import { fullFit } from "../../.storybook/fits";
|
||||
import { fullFits } from "../../.storybook/fits";
|
||||
|
||||
import { DogmaEngineProvider } from "../DogmaEngineProvider";
|
||||
import { EsiProvider } from "../EsiProvider";
|
||||
@@ -18,7 +18,9 @@ const meta: Meta<typeof CalculationDetail> = {
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof CalculationDetail>;
|
||||
|
||||
const useShipSnapshotProvider: Decorator<{ source: "Ship" | { Item: number } }> = (Story, context) => {
|
||||
const useShipSnapshotProvider: Decorator<{
|
||||
source: "Ship" | "Char" | "Structure" | "Target" | { Item?: number; Cargo?: number };
|
||||
}> = (Story, context) => {
|
||||
const [skills, setSkills] = React.useState<Record<string, number>>({});
|
||||
|
||||
return (
|
||||
@@ -41,7 +43,7 @@ export const Default: Story = {
|
||||
decorators: [useShipSnapshotProvider],
|
||||
parameters: {
|
||||
snapshot: {
|
||||
fit: fullFit,
|
||||
fit: fullFits[1],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -29,17 +29,42 @@ const Effect = (props: { effect: ShipSnapshotItemAttributeEffect }) => {
|
||||
|
||||
const eveAttribute = eveData.dogmaAttributes?.[props.effect.source_attribute_id];
|
||||
|
||||
let sourceName;
|
||||
let attribute;
|
||||
let sourceName = "Unknown";
|
||||
let attribute = undefined;
|
||||
|
||||
if (props.effect.source === "Ship") {
|
||||
sourceName = "Ship";
|
||||
attribute = shipSnapshot.hull?.attributes.get(props.effect.source_attribute_id);
|
||||
} else if (props.effect.source.Item !== undefined) {
|
||||
const item = shipSnapshot.items?.[props.effect.source.Item];
|
||||
} else if (props.effect.source === "Char") {
|
||||
sourceName = "Char";
|
||||
attribute = shipSnapshot.char?.attributes.get(props.effect.source_attribute_id);
|
||||
} else if (props.effect.source === "Structure") {
|
||||
sourceName = "Structure";
|
||||
attribute = shipSnapshot.structure?.attributes.get(props.effect.source_attribute_id);
|
||||
} else if (props.effect.source === "Target") {
|
||||
sourceName = "Target";
|
||||
attribute = shipSnapshot.target?.attributes.get(props.effect.source_attribute_id);
|
||||
} else {
|
||||
let item = undefined;
|
||||
let sourceType = undefined;
|
||||
|
||||
/* Lookup the source of the effect. */
|
||||
if (props.effect.source.Item !== undefined) {
|
||||
item = shipSnapshot.items?.[props.effect.source.Item];
|
||||
sourceType = "Item";
|
||||
} else if (props.effect.source.Skill !== undefined) {
|
||||
item = shipSnapshot.skills?.[props.effect.source.Skill];
|
||||
sourceType = "Skill";
|
||||
} else if (props.effect.source.Charge !== undefined) {
|
||||
item = shipSnapshot.items?.[props.effect.source.Charge].charge;
|
||||
sourceType = "Charge";
|
||||
}
|
||||
|
||||
/* Find the attribute on the source. */
|
||||
if (item === undefined) {
|
||||
sourceName = "Unknown";
|
||||
sourceName = `Unknown ${sourceType}`;
|
||||
} else {
|
||||
sourceName = eveData.typeIDs?.[item?.type_id]?.name;
|
||||
sourceName = `${sourceType} - ` + eveData.typeIDs?.[item?.type_id]?.name ?? sourceName;
|
||||
attribute = item?.attributes.get(props.effect.source_attribute_id);
|
||||
}
|
||||
}
|
||||
@@ -50,6 +75,7 @@ const Effect = (props: { effect: ShipSnapshotItemAttributeEffect }) => {
|
||||
<span>
|
||||
{attribute?.value || eveAttribute?.defaultValue}
|
||||
{props.effect.penalty ? " (penalized)" : ""}
|
||||
{attribute?.value === undefined ? " (default)" : ""}
|
||||
</span>
|
||||
<span>
|
||||
{sourceName} - {eveAttribute?.name}
|
||||
@@ -63,8 +89,6 @@ const CalculationDetailMeta = (props: { attributeId: number; attribute: ShipSnap
|
||||
const eveData = React.useContext(EveDataContext);
|
||||
|
||||
const eveAttribute = eveData.dogmaAttributes?.[props.attributeId];
|
||||
let index = 0;
|
||||
|
||||
const sortedEffects = props.attribute.effects.sort((a, b) => {
|
||||
const aIndex = Object.keys(EffectOperatorOrder).indexOf(a.operator);
|
||||
const bIndex = Object.keys(EffectOperatorOrder).indexOf(b.operator);
|
||||
@@ -74,6 +98,7 @@ const CalculationDetailMeta = (props: { attributeId: number; attribute: ShipSnap
|
||||
return aIndex - bIndex;
|
||||
});
|
||||
|
||||
let index = 0;
|
||||
return (
|
||||
<div className={styles.line}>
|
||||
<div className={styles.entry} onClick={() => setExpanded(!expanded)}>
|
||||
@@ -88,7 +113,7 @@ const CalculationDetailMeta = (props: { attributeId: number; attribute: ShipSnap
|
||||
<div className={styles.effect}>
|
||||
<span>=</span>
|
||||
<span>{props.attribute.base_value}</span>
|
||||
<span>base value {props.attributeId < 0 && <>(list of effects might be incomplete)</>}</span>
|
||||
<span>Base value {props.attributeId < 0 && <>(list of effects might be incomplete)</>}</span>
|
||||
</div>
|
||||
{sortedEffects.map((effect) => {
|
||||
index += 1;
|
||||
@@ -103,17 +128,31 @@ const CalculationDetailMeta = (props: { attributeId: number; attribute: ShipSnap
|
||||
* Show in detail for each attribute how the value came to be. This includes
|
||||
* the base value, all effects (and their source) and the final value.
|
||||
*/
|
||||
export const CalculationDetail = (props: { source: "Ship" | { Item: number } }) => {
|
||||
export const CalculationDetail = (props: {
|
||||
source: "Ship" | "Char" | "Structure" | "Target" | { Item?: number; Charge?: number };
|
||||
}) => {
|
||||
const shipSnapshot = React.useContext(ShipSnapshotContext);
|
||||
|
||||
let attributes;
|
||||
let attributes: [number, ShipSnapshotItemAttribute][] = [];
|
||||
|
||||
if (props.source === "Ship") {
|
||||
attributes = [...(shipSnapshot.hull?.attributes.entries() || [])];
|
||||
} else if (props.source === "Char") {
|
||||
attributes = [...(shipSnapshot.char?.attributes.entries() || [])];
|
||||
} else if (props.source === "Structure") {
|
||||
attributes = [...(shipSnapshot.structure?.attributes.entries() || [])];
|
||||
} else if (props.source === "Target") {
|
||||
attributes = [...(shipSnapshot.target?.attributes.entries() || [])];
|
||||
} else if (props.source.Item !== undefined) {
|
||||
const item = shipSnapshot.items?.[props.source.Item];
|
||||
if (item !== undefined) {
|
||||
attributes = [...item.attributes.entries()];
|
||||
}
|
||||
} else if (props.source.Charge !== undefined) {
|
||||
const item = shipSnapshot.items?.[props.source.Charge].charge;
|
||||
if (item !== undefined) {
|
||||
attributes = [...item.attributes.entries()];
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -6,7 +6,7 @@ import { EveDataContext } from "../EveDataProvider";
|
||||
export interface ShipSnapshotItemAttributeEffect {
|
||||
operator: string;
|
||||
penalty: boolean;
|
||||
source: "Ship" | { Item: number };
|
||||
source: "Ship" | "Char" | "Structure" | "Target" | { Item?: number; Charge?: number; Skill?: number };
|
||||
source_category: string;
|
||||
source_attribute_id: number;
|
||||
}
|
||||
@@ -55,8 +55,14 @@ export type ShipSnapshotSlotsType = keyof ShipSnapshotSlots;
|
||||
|
||||
interface ShipSnapshot {
|
||||
loaded?: boolean;
|
||||
|
||||
hull?: ShipSnapshotItem;
|
||||
items?: ShipSnapshotItem[];
|
||||
skills?: ShipSnapshotItem[];
|
||||
char?: ShipSnapshotItem;
|
||||
structure?: ShipSnapshotItem;
|
||||
target?: ShipSnapshotItem;
|
||||
|
||||
slots: ShipSnapshotSlots;
|
||||
|
||||
fit?: EsiFit;
|
||||
@@ -349,6 +355,10 @@ export const ShipSnapshotProvider = (props: ShipSnapshotProps) => {
|
||||
loaded: true,
|
||||
hull: snapshot.hull,
|
||||
items: snapshot.items,
|
||||
skills: snapshot.skills,
|
||||
char: snapshot.char,
|
||||
structure: snapshot.structure,
|
||||
target: snapshot.target,
|
||||
slots,
|
||||
fit: currentFit,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user