mirror of
https://github.com/wanderer-industries/wanderer
synced 2025-12-08 08:45:37 +00:00
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf20be8a77 | ||
|
|
450bcb649c | ||
|
|
a00395351e | ||
|
|
602b1028c3 | ||
|
|
4f98e979a2 | ||
|
|
e0f46c4af7 | ||
|
|
bc8a9a2b85 | ||
|
|
c2b03f925d | ||
|
|
efa2e52054 | ||
|
|
cedf5761f8 | ||
|
|
f601bb8751 | ||
|
|
c39d2a56d2 | ||
|
|
805722bbe8 | ||
|
|
fe3e38343b | ||
|
|
616e82c497 | ||
|
|
ab7e47b91f | ||
|
|
cf1c103a46 | ||
|
|
71202a4a29 | ||
|
|
a7e0ceac4c | ||
|
|
6bce701aab | ||
|
|
f8b9e206a5 | ||
|
|
24c32511d8 | ||
|
|
06e7b6e3eb | ||
|
|
873946a1a6 | ||
|
|
854524a03c |
33
CHANGELOG.md
33
CHANGELOG.md
@@ -2,6 +2,39 @@
|
||||
|
||||
<!-- changelog -->
|
||||
|
||||
## [v1.78.1](https://github.com/wanderer-industries/wanderer/compare/v1.78.0...v1.78.1) (2025-09-24)
|
||||
|
||||
|
||||
|
||||
|
||||
### Bug Fixes:
|
||||
|
||||
* pr feedback
|
||||
|
||||
* removed wormhole only logic error
|
||||
|
||||
## [v1.78.0](https://github.com/wanderer-industries/wanderer/compare/v1.77.19...v1.78.0) (2025-09-23)
|
||||
|
||||
|
||||
|
||||
|
||||
### Features:
|
||||
|
||||
* Core: added support for jumpgates connection type
|
||||
|
||||
### Bug Fixes:
|
||||
|
||||
* Map: Add support for Bridge. Made all tooltips left and right paddings.
|
||||
|
||||
## [v1.77.19](https://github.com/wanderer-industries/wanderer/compare/v1.77.18...v1.77.19) (2025-09-14)
|
||||
|
||||
|
||||
|
||||
|
||||
### Bug Fixes:
|
||||
|
||||
* Map: Fixed for all Large wormholes jump mass from 300 to 375. Fixed jump mass and total mass for N290, K329. Fixed static for J005663 was H296 now Y790. Added J492 wormhole. Change lifetime for E587 from 16 to 48
|
||||
|
||||
## [v1.77.18](https://github.com/wanderer-industries/wanderer/compare/v1.77.17...v1.77.18) (2025-09-13)
|
||||
|
||||
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
background-image: linear-gradient(207deg, transparent, var(--conn-frigate));
|
||||
}
|
||||
|
||||
.ConnectionBridge {
|
||||
background-image: linear-gradient(207deg, transparent, var(--conn-bridge));
|
||||
}
|
||||
|
||||
.ConnectionSave {
|
||||
background-image: linear-gradient(207deg, transparent, var(--conn-save));
|
||||
}
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
import React, { RefObject, useMemo } from 'react';
|
||||
import { ContextMenu } from 'primereact/contextmenu';
|
||||
import { PrimeIcons } from 'primereact/api';
|
||||
import { MenuItem } from 'primereact/menuitem';
|
||||
import { ConnectionType, MassState, ShipSizeStatus, SolarSystemConnection, TimeStatus } from '@/hooks/Mapper/types';
|
||||
import clsx from 'clsx';
|
||||
import classes from './ContextMenuConnection.module.scss';
|
||||
import {
|
||||
MASS_STATE_NAMES,
|
||||
MASS_STATE_NAMES_ORDER,
|
||||
@@ -13,7 +6,16 @@ import {
|
||||
SHIP_SIZES_NAMES_SHORT,
|
||||
SHIP_SIZES_SIZE,
|
||||
} from '@/hooks/Mapper/components/map/constants.ts';
|
||||
import { ConnectionType, MassState, ShipSizeStatus, SolarSystemConnection, TimeStatus } from '@/hooks/Mapper/types';
|
||||
import clsx from 'clsx';
|
||||
import { PrimeIcons } from 'primereact/api';
|
||||
import { ContextMenu } from 'primereact/contextmenu';
|
||||
import { MenuItem } from 'primereact/menuitem';
|
||||
import React, { RefObject, useMemo } from 'react';
|
||||
import { Edge } from 'reactflow';
|
||||
import classes from './ContextMenuConnection.module.scss';
|
||||
import { getSystemStaticInfo } from '@/hooks/Mapper/mapRootProvider/hooks/useLoadSystemStatic.ts';
|
||||
import { isNullsecSpace } from '@/hooks/Mapper/components/map/helpers/isKnownSpace.ts';
|
||||
|
||||
export interface ContextMenuConnectionProps {
|
||||
contextMenuRef: RefObject<ContextMenu>;
|
||||
@@ -21,6 +23,7 @@ export interface ContextMenuConnectionProps {
|
||||
onChangeTimeState(): void;
|
||||
onChangeMassState(state: MassState): void;
|
||||
onChangeShipSizeStatus(state: ShipSizeStatus): void;
|
||||
onChangeType(type: ConnectionType): void;
|
||||
onToggleMassSave(isLocked: boolean): void;
|
||||
onHide(): void;
|
||||
edge?: Edge<SolarSystemConnection>;
|
||||
@@ -32,6 +35,7 @@ export const ContextMenuConnection: React.FC<ContextMenuConnectionProps> = ({
|
||||
onChangeTimeState,
|
||||
onChangeMassState,
|
||||
onChangeShipSizeStatus,
|
||||
onChangeType,
|
||||
onToggleMassSave,
|
||||
onHide,
|
||||
edge,
|
||||
@@ -41,84 +45,127 @@ export const ContextMenuConnection: React.FC<ContextMenuConnectionProps> = ({
|
||||
return [];
|
||||
}
|
||||
|
||||
const sourceInfo = getSystemStaticInfo(edge.data?.source);
|
||||
const targetInfo = getSystemStaticInfo(edge.data?.target);
|
||||
|
||||
const bothNullsec =
|
||||
sourceInfo && targetInfo && isNullsecSpace(sourceInfo.system_class) && isNullsecSpace(targetInfo.system_class);
|
||||
|
||||
const isFrigateSize = edge.data?.ship_size_type === ShipSizeStatus.small;
|
||||
const isWormhole = edge.data?.type !== ConnectionType.gate;
|
||||
|
||||
if (edge.data?.type === ConnectionType.bridge) {
|
||||
return [
|
||||
{
|
||||
label: `Set as Wormhole`,
|
||||
icon: 'pi hero-arrow-uturn-left',
|
||||
command: () => onChangeType(ConnectionType.wormhole),
|
||||
},
|
||||
{
|
||||
label: 'Disconnect',
|
||||
icon: PrimeIcons.TRASH,
|
||||
command: onDeleteConnection,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
if (edge.data?.type === ConnectionType.gate) {
|
||||
return [
|
||||
{
|
||||
label: 'Disconnect',
|
||||
icon: PrimeIcons.TRASH,
|
||||
command: onDeleteConnection,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
...(isWormhole
|
||||
{
|
||||
label: `EOL`,
|
||||
className: clsx({
|
||||
[classes.ConnectionTimeEOL]: edge.data?.time_status === TimeStatus.eol,
|
||||
}),
|
||||
icon: PrimeIcons.CLOCK,
|
||||
command: onChangeTimeState,
|
||||
},
|
||||
{
|
||||
label: `Frigate`,
|
||||
className: clsx({
|
||||
[classes.ConnectionFrigate]: isFrigateSize,
|
||||
}),
|
||||
icon: PrimeIcons.CLOUD,
|
||||
command: () =>
|
||||
onChangeShipSizeStatus(
|
||||
edge.data?.ship_size_type === ShipSizeStatus.small ? ShipSizeStatus.large : ShipSizeStatus.small,
|
||||
),
|
||||
},
|
||||
{
|
||||
label: `Save mass`,
|
||||
className: clsx({
|
||||
[classes.ConnectionSave]: edge.data?.locked,
|
||||
}),
|
||||
icon: PrimeIcons.LOCK,
|
||||
command: () => onToggleMassSave(!edge.data?.locked),
|
||||
},
|
||||
...(!isFrigateSize
|
||||
? [
|
||||
{
|
||||
label: `EOL`,
|
||||
className: clsx({
|
||||
[classes.ConnectionTimeEOL]: edge.data?.time_status === TimeStatus.eol,
|
||||
}),
|
||||
icon: PrimeIcons.CLOCK,
|
||||
command: onChangeTimeState,
|
||||
},
|
||||
{
|
||||
label: `Frigate`,
|
||||
className: clsx({
|
||||
[classes.ConnectionFrigate]: isFrigateSize,
|
||||
}),
|
||||
icon: PrimeIcons.CLOUD,
|
||||
command: () =>
|
||||
onChangeShipSizeStatus(
|
||||
edge.data?.ship_size_type === ShipSizeStatus.small ? ShipSizeStatus.large : ShipSizeStatus.small,
|
||||
),
|
||||
},
|
||||
{
|
||||
label: `Save mass`,
|
||||
className: clsx({
|
||||
[classes.ConnectionSave]: edge.data?.locked,
|
||||
}),
|
||||
icon: PrimeIcons.LOCK,
|
||||
command: () => onToggleMassSave(!edge.data?.locked),
|
||||
},
|
||||
...(!isFrigateSize
|
||||
? [
|
||||
{
|
||||
label: `Mass status`,
|
||||
icon: PrimeIcons.CHART_PIE,
|
||||
items: MASS_STATE_NAMES_ORDER.map(x => ({
|
||||
label: MASS_STATE_NAMES[x],
|
||||
className: clsx({
|
||||
[classes.SelectedItem]: edge.data?.mass_status === x,
|
||||
}),
|
||||
command: () => onChangeMassState(x),
|
||||
})),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
|
||||
{
|
||||
label: `Ship Size`,
|
||||
icon: PrimeIcons.CLOUD,
|
||||
items: SHIP_SIZES_NAMES_ORDER.map(x => ({
|
||||
label: (
|
||||
<div className="grid grid-cols-[20px_120px_1fr_40px] gap-2 items-center">
|
||||
<div className="text-[12px] font-bold text-stone-400">{SHIP_SIZES_NAMES_SHORT[x]}</div>
|
||||
<div>{SHIP_SIZES_NAMES[x]}</div>
|
||||
<div></div>
|
||||
<div className="flex justify-end whitespace-nowrap text-[12px] font-bold text-stone-500">
|
||||
{SHIP_SIZES_SIZE[x]} t.
|
||||
</div>
|
||||
</div>
|
||||
) as unknown as string, // TODO my lovely kostyl
|
||||
label: `Mass status`,
|
||||
icon: PrimeIcons.CHART_PIE,
|
||||
items: MASS_STATE_NAMES_ORDER.map(x => ({
|
||||
label: MASS_STATE_NAMES[x],
|
||||
className: clsx({
|
||||
[classes.SelectedItem]: edge.data?.ship_size_type === x,
|
||||
[classes.SelectedItem]: edge.data?.mass_status === x,
|
||||
}),
|
||||
command: () => onChangeShipSizeStatus(x),
|
||||
command: () => onChangeMassState(x),
|
||||
})),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
|
||||
{
|
||||
label: `Ship Size`,
|
||||
icon: PrimeIcons.CLOUD,
|
||||
items: SHIP_SIZES_NAMES_ORDER.map(x => ({
|
||||
label: (
|
||||
<div className="grid grid-cols-[20px_120px_1fr_40px] gap-2 items-center">
|
||||
<div className="text-[12px] font-bold text-stone-400">{SHIP_SIZES_NAMES_SHORT[x]}</div>
|
||||
<div>{SHIP_SIZES_NAMES[x]}</div>
|
||||
<div></div>
|
||||
<div className="flex justify-end whitespace-nowrap text-[12px] font-bold text-stone-500">
|
||||
{SHIP_SIZES_SIZE[x]} t.
|
||||
</div>
|
||||
</div>
|
||||
) as unknown as string, // TODO my lovely kostyl
|
||||
className: clsx({
|
||||
[classes.SelectedItem]: edge.data?.ship_size_type === x,
|
||||
}),
|
||||
command: () => onChangeShipSizeStatus(x),
|
||||
})),
|
||||
},
|
||||
...(bothNullsec
|
||||
? [
|
||||
{
|
||||
label: `Set as Bridge`,
|
||||
icon: 'pi hero-forward',
|
||||
command: () => onChangeType(ConnectionType.bridge),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
label: 'Disconnect',
|
||||
icon: PrimeIcons.TRASH,
|
||||
command: onDeleteConnection,
|
||||
},
|
||||
];
|
||||
}, [edge, onChangeTimeState, onDeleteConnection, onChangeShipSizeStatus, onToggleMassSave, onChangeMassState]);
|
||||
}, [
|
||||
edge,
|
||||
onChangeTimeState,
|
||||
onDeleteConnection,
|
||||
onChangeType,
|
||||
onChangeShipSizeStatus,
|
||||
onToggleMassSave,
|
||||
onChangeMassState,
|
||||
]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -56,7 +56,8 @@ export const KillsCounter = ({
|
||||
className={className}
|
||||
tooltipClassName="!px-0"
|
||||
size={size}
|
||||
interactive={true}
|
||||
interactive
|
||||
smallPaddings
|
||||
>
|
||||
{children}
|
||||
</WdTooltipWrapper>
|
||||
|
||||
@@ -46,7 +46,13 @@ export const LocalCounter = ({ localCounterCharacters, hasUserCharacters, showIc
|
||||
[classes.Pathfinder]: theme === AvailableThemes.pathfinder,
|
||||
})}
|
||||
>
|
||||
<WdTooltipWrapper content={pilotTooltipContent} position={TooltipPosition.right} offset={0} interactive={true}>
|
||||
<WdTooltipWrapper
|
||||
content={pilotTooltipContent}
|
||||
position={TooltipPosition.right}
|
||||
offset={0}
|
||||
interactive={true}
|
||||
smallPaddings
|
||||
>
|
||||
<div className={clsx(classes.hoverTarget)}>
|
||||
<div
|
||||
className={clsx(classes.localCounter, {
|
||||
|
||||
@@ -29,6 +29,13 @@
|
||||
&.Gate {
|
||||
stroke: #9aff40;
|
||||
}
|
||||
|
||||
&.Bridge {
|
||||
stroke: #9aff40;
|
||||
|
||||
stroke-dasharray: 10 5;
|
||||
stroke-linecap: round;
|
||||
}
|
||||
}
|
||||
|
||||
.EdgePathFront {
|
||||
|
||||
@@ -9,6 +9,7 @@ import { PrimeIcons } from 'primereact/api';
|
||||
import { WdTooltipWrapper } from '@/hooks/Mapper/components/ui-kit/WdTooltipWrapper';
|
||||
import { useMapState } from '@/hooks/Mapper/components/map/MapProvider.tsx';
|
||||
import { SHIP_SIZES_DESCRIPTION, SHIP_SIZES_NAMES_SHORT } from '@/hooks/Mapper/components/map/constants.ts';
|
||||
import { TooltipPosition } from '@/hooks/Mapper/components/ui-kit';
|
||||
|
||||
const MAP_TRANSLATES: Record<string, string> = {
|
||||
[Position.Top]: 'translate(-48%, 0%)',
|
||||
@@ -42,7 +43,9 @@ export const SHIP_SIZES_COLORS = {
|
||||
export const SolarSystemEdge = ({ id, source, target, markerEnd, style, data }: EdgeProps<SolarSystemConnection>) => {
|
||||
const sourceNode = useStore(useCallback(store => store.nodeInternals.get(source), [source]));
|
||||
const targetNode = useStore(useCallback(store => store.nodeInternals.get(target), [target]));
|
||||
const isWormhole = data?.type !== ConnectionType.gate;
|
||||
const isWormhole = data?.type === ConnectionType.wormhole;
|
||||
const isGate = data?.type === ConnectionType.gate;
|
||||
const isBridge = data?.type === ConnectionType.bridge;
|
||||
|
||||
const {
|
||||
data: { isThickConnections },
|
||||
@@ -55,9 +58,7 @@ export const SolarSystemEdge = ({ id, source, target, markerEnd, style, data }:
|
||||
|
||||
const offset = isThickConnections ? MAP_OFFSETS_TICK[targetPos] : MAP_OFFSETS[targetPos];
|
||||
|
||||
const method = isWormhole ? getBezierPath : getBezierPath;
|
||||
|
||||
const [edgePath, labelX, labelY] = method({
|
||||
const [edgePath, labelX, labelY] = getBezierPath({
|
||||
sourceX: sx - offset.x,
|
||||
sourceY: sy - offset.y,
|
||||
sourcePosition: sourcePos,
|
||||
@@ -67,7 +68,7 @@ export const SolarSystemEdge = ({ id, source, target, markerEnd, style, data }:
|
||||
});
|
||||
|
||||
return [edgePath, labelX, labelY, sx, sy, tx, ty, sourcePos, targetPos];
|
||||
}, [isThickConnections, sourceNode, targetNode, isWormhole]);
|
||||
}, [isThickConnections, sourceNode, targetNode]);
|
||||
|
||||
if (!sourceNode || !targetNode || !data) {
|
||||
return null;
|
||||
@@ -81,7 +82,8 @@ export const SolarSystemEdge = ({ id, source, target, markerEnd, style, data }:
|
||||
[classes.Tick]: isThickConnections,
|
||||
[classes.TimeCrit]: isWormhole && data.time_status === TimeStatus.eol,
|
||||
[classes.Hovered]: hovered,
|
||||
[classes.Gate]: !isWormhole,
|
||||
[classes.Gate]: isGate,
|
||||
[classes.Bridge]: isBridge,
|
||||
})}
|
||||
d={path}
|
||||
markerEnd={markerEnd}
|
||||
@@ -95,7 +97,8 @@ export const SolarSystemEdge = ({ id, source, target, markerEnd, style, data }:
|
||||
[classes.MassVerge]: isWormhole && data.mass_status === MassState.verge,
|
||||
[classes.MassHalf]: isWormhole && data.mass_status === MassState.half,
|
||||
[classes.Frigate]: isWormhole && data.ship_size_type === ShipSizeStatus.small,
|
||||
[classes.Gate]: !isWormhole,
|
||||
[classes.Gate]: isGate,
|
||||
[classes.Bridge]: isBridge,
|
||||
})}
|
||||
d={path}
|
||||
markerEnd={markerEnd}
|
||||
@@ -147,6 +150,19 @@ export const SolarSystemEdge = ({ id, source, target, markerEnd, style, data }:
|
||||
</WdTooltipWrapper>
|
||||
)}
|
||||
|
||||
{isBridge && (
|
||||
<WdTooltipWrapper
|
||||
content="Ansiblex Jump Bridge"
|
||||
position={TooltipPosition.top}
|
||||
className={clsx(
|
||||
classes.LinkLabel,
|
||||
'pointer-events-auto bg-lime-300 rounded opacity-100 cursor-auto text-neutral-900',
|
||||
)}
|
||||
>
|
||||
B
|
||||
</WdTooltipWrapper>
|
||||
)}
|
||||
|
||||
{isWormhole && data.ship_size_type !== ShipSizeStatus.large && (
|
||||
<WdTooltipWrapper
|
||||
content={SHIP_SIZES_DESCRIPTION[data.ship_size_type]}
|
||||
|
||||
@@ -58,6 +58,7 @@ export const UnsplashedSignature = ({ signature }: UnsplashedSignatureProps) =>
|
||||
</InfoDrawer>
|
||||
</div>
|
||||
}
|
||||
smallPaddings
|
||||
>
|
||||
<div className={clsx(classes.Box, whClassStyle)}>
|
||||
<svg width="13" height="8" viewBox="0 0 13 8" xmlns="http://www.w3.org/2000/svg">
|
||||
|
||||
@@ -716,11 +716,12 @@ export const STATUS_CLASSES: Record<number, string> = {
|
||||
[STATUSES.dangerous]: 'eve-system-status-dangerous',
|
||||
};
|
||||
|
||||
export const TYPE_NAMES_ORDER = [ConnectionType.wormhole, ConnectionType.gate];
|
||||
export const TYPE_NAMES_ORDER = [ConnectionType.wormhole, ConnectionType.gate, ConnectionType.bridge];
|
||||
|
||||
export const TYPE_NAMES = {
|
||||
[ConnectionType.wormhole]: 'Wormhole',
|
||||
[ConnectionType.gate]: 'Gate',
|
||||
[ConnectionType.bridge]: 'Jumpgate',
|
||||
};
|
||||
|
||||
export const MASS_STATE_NAMES_ORDER = [MassState.verge, MassState.half, MassState.normal];
|
||||
|
||||
@@ -15,3 +15,12 @@ export const isKnownSpace = (wormholeClassID: number) => {
|
||||
export const isPossibleSpace = (spaces: number[], wormholeClassID: number) => {
|
||||
return spaces.includes(wormholeClassID);
|
||||
};
|
||||
|
||||
export const isNullsecSpace = (wormholeClassID: number) => {
|
||||
switch (wormholeClassID) {
|
||||
case SOLAR_SYSTEM_CLASS_IDS.ns:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
@@ -49,87 +49,91 @@ export const useMapHandlers = (ref: ForwardedRef<MapHandlers>, onSelectionChange
|
||||
const { charactersUpdated, presentCharacters, characterAdded, characterRemoved, characterUpdated } =
|
||||
useCommandsCharacters();
|
||||
|
||||
useImperativeHandle(ref, () => {
|
||||
return {
|
||||
command(type, data) {
|
||||
switch (type) {
|
||||
case Commands.init:
|
||||
mapInit(data as CommandInit);
|
||||
break;
|
||||
case Commands.addSystems:
|
||||
setTimeout(() => mapAddSystems(data as CommandAddSystems), 100);
|
||||
break;
|
||||
case Commands.updateSystems:
|
||||
mapUpdateSystems(data as CommandUpdateSystems);
|
||||
break;
|
||||
case Commands.removeSystems:
|
||||
setTimeout(() => removeSystems(data as CommandRemoveSystems), 100);
|
||||
break;
|
||||
case Commands.addConnections:
|
||||
setTimeout(() => addConnections(data as CommandAddConnections), 100);
|
||||
break;
|
||||
case Commands.removeConnections:
|
||||
setTimeout(() => removeConnections(data as CommandRemoveConnections), 100);
|
||||
break;
|
||||
case Commands.charactersUpdated:
|
||||
charactersUpdated(data as CommandCharactersUpdated);
|
||||
break;
|
||||
case Commands.characterAdded:
|
||||
characterAdded(data as CommandCharacterAdded);
|
||||
break;
|
||||
case Commands.characterRemoved:
|
||||
characterRemoved(data as CommandCharacterRemoved);
|
||||
break;
|
||||
case Commands.characterUpdated:
|
||||
characterUpdated(data as CommandCharacterUpdated);
|
||||
break;
|
||||
case Commands.presentCharacters:
|
||||
presentCharacters(data as CommandPresentCharacters);
|
||||
break;
|
||||
case Commands.updateConnection:
|
||||
updateConnection(data as CommandUpdateConnection);
|
||||
break;
|
||||
case Commands.mapUpdated:
|
||||
mapUpdated(data as CommandMapUpdated);
|
||||
break;
|
||||
case Commands.killsUpdated:
|
||||
killsUpdated(data as CommandKillsUpdated);
|
||||
break;
|
||||
useImperativeHandle(
|
||||
ref,
|
||||
() => {
|
||||
return {
|
||||
command(type, data) {
|
||||
switch (type) {
|
||||
case Commands.init:
|
||||
mapInit(data as CommandInit);
|
||||
break;
|
||||
case Commands.addSystems:
|
||||
setTimeout(() => mapAddSystems(data as CommandAddSystems), 100);
|
||||
break;
|
||||
case Commands.updateSystems:
|
||||
mapUpdateSystems(data as CommandUpdateSystems);
|
||||
break;
|
||||
case Commands.removeSystems:
|
||||
setTimeout(() => removeSystems(data as CommandRemoveSystems), 100);
|
||||
break;
|
||||
case Commands.addConnections:
|
||||
setTimeout(() => addConnections(data as CommandAddConnections), 100);
|
||||
break;
|
||||
case Commands.removeConnections:
|
||||
setTimeout(() => removeConnections(data as CommandRemoveConnections), 100);
|
||||
break;
|
||||
case Commands.charactersUpdated:
|
||||
charactersUpdated(data as CommandCharactersUpdated);
|
||||
break;
|
||||
case Commands.characterAdded:
|
||||
characterAdded(data as CommandCharacterAdded);
|
||||
break;
|
||||
case Commands.characterRemoved:
|
||||
characterRemoved(data as CommandCharacterRemoved);
|
||||
break;
|
||||
case Commands.characterUpdated:
|
||||
characterUpdated(data as CommandCharacterUpdated);
|
||||
break;
|
||||
case Commands.presentCharacters:
|
||||
presentCharacters(data as CommandPresentCharacters);
|
||||
break;
|
||||
case Commands.updateConnection:
|
||||
updateConnection(data as CommandUpdateConnection);
|
||||
break;
|
||||
case Commands.mapUpdated:
|
||||
mapUpdated(data as CommandMapUpdated);
|
||||
break;
|
||||
case Commands.killsUpdated:
|
||||
killsUpdated(data as CommandKillsUpdated);
|
||||
break;
|
||||
|
||||
case Commands.centerSystem:
|
||||
setTimeout(() => {
|
||||
const systemId = `${data}`;
|
||||
centerSystem(systemId as CommandSelectSystem);
|
||||
}, 100);
|
||||
break;
|
||||
case Commands.centerSystem:
|
||||
setTimeout(() => {
|
||||
const systemId = `${data}`;
|
||||
centerSystem(systemId as CommandSelectSystem);
|
||||
}, 100);
|
||||
break;
|
||||
|
||||
case Commands.selectSystem:
|
||||
selectSystems({ systems: [data as string], delay: 500 });
|
||||
break;
|
||||
case Commands.selectSystem:
|
||||
selectSystems({ systems: [data as string], delay: 500 });
|
||||
break;
|
||||
|
||||
case Commands.selectSystems:
|
||||
selectSystems(data as CommandSelectSystems);
|
||||
break;
|
||||
case Commands.selectSystems:
|
||||
selectSystems(data as CommandSelectSystems);
|
||||
break;
|
||||
|
||||
case Commands.pingAdded:
|
||||
case Commands.pingCancelled:
|
||||
case Commands.routes:
|
||||
case Commands.signaturesUpdated:
|
||||
case Commands.linkSignatureToSystem:
|
||||
case Commands.detailedKillsUpdated:
|
||||
case Commands.characterActivityData:
|
||||
case Commands.trackingCharactersData:
|
||||
case Commands.updateActivity:
|
||||
case Commands.updateTracking:
|
||||
case Commands.userSettingsUpdated:
|
||||
// do nothing
|
||||
break;
|
||||
case Commands.pingAdded:
|
||||
case Commands.pingCancelled:
|
||||
case Commands.routes:
|
||||
case Commands.signaturesUpdated:
|
||||
case Commands.linkSignatureToSystem:
|
||||
case Commands.detailedKillsUpdated:
|
||||
case Commands.characterActivityData:
|
||||
case Commands.trackingCharactersData:
|
||||
case Commands.updateActivity:
|
||||
case Commands.updateTracking:
|
||||
case Commands.userSettingsUpdated:
|
||||
// do nothing
|
||||
break;
|
||||
|
||||
default:
|
||||
console.warn(`Map handlers: Unknown command: ${type}`, data);
|
||||
break;
|
||||
}
|
||||
},
|
||||
};
|
||||
}, []);
|
||||
default:
|
||||
console.warn(`Map handlers: Unknown command: ${type}`, data);
|
||||
break;
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
[],
|
||||
);
|
||||
};
|
||||
|
||||
@@ -118,6 +118,7 @@ $homeDark30: color.adjust($homeBase, $lightness: -30%);
|
||||
|
||||
--conn-time-eol: #7452c3e3;
|
||||
--conn-frigate: #325d88;
|
||||
--conn-bridge: rgba(135, 185, 93, 0.85);
|
||||
--conn-save: rgba(155, 102, 45, 0.85);
|
||||
--selected-item-bg: rgba(98, 98, 98, 0.33);
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ export const SystemSettingsDialog = ({ systemId, visible, setVisible }: SystemSe
|
||||
<Dialog
|
||||
header="System settings"
|
||||
visible={visible}
|
||||
draggable={false}
|
||||
draggable={true}
|
||||
style={{ width: '450px' }}
|
||||
onShow={onShow}
|
||||
onHide={() => {
|
||||
|
||||
@@ -16,8 +16,21 @@ const SystemKillsContent = () => {
|
||||
} = useMapRootState();
|
||||
|
||||
const [systemId] = selectedSystems || [];
|
||||
const whCacheRef = useMemo(() => new Map<number, boolean>(), []);
|
||||
|
||||
const systemStaticInfo = getSystemStaticInfo(systemId)!;
|
||||
const isWormholeSystem = useCallback(
|
||||
(systemId: number): boolean => {
|
||||
const cached = whCacheRef.get(systemId);
|
||||
if (cached !== undefined) return cached;
|
||||
|
||||
const info = getSystemStaticInfo(systemId);
|
||||
const isWH = info?.system_class != null ? isWormholeSpace(Number(info.system_class)) : false;
|
||||
|
||||
whCacheRef.set(systemId, isWH);
|
||||
return isWH;
|
||||
},
|
||||
[whCacheRef],
|
||||
);
|
||||
|
||||
const { kills, isLoading, error } = useSystemKills({
|
||||
systemId,
|
||||
@@ -30,15 +43,9 @@ const SystemKillsContent = () => {
|
||||
const showLoading = isLoading && kills.length === 0;
|
||||
|
||||
const filteredKills = useMemo(() => {
|
||||
if (!settingsKills.whOnly || !settingsKills.showAll) return kills;
|
||||
return kills.filter(kill => {
|
||||
if (!systemStaticInfo) {
|
||||
console.warn(`System with id ${kill.solar_system_id} not found.`);
|
||||
return false;
|
||||
}
|
||||
return isWormholeSpace(systemStaticInfo.system_class);
|
||||
});
|
||||
}, [kills, settingsKills.whOnly, systemStaticInfo, settingsKills.showAll]);
|
||||
if (!settingsKills.whOnly) return kills;
|
||||
return kills.filter(kill => isWormholeSystem(Number(kill.solar_system_id)));
|
||||
}, [kills, settingsKills.whOnly, isWormholeSystem]);
|
||||
|
||||
if (!isSubscriptionActive) {
|
||||
return (
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
import classes from './Connections.module.scss';
|
||||
import { Sidebar } from 'primereact/sidebar';
|
||||
import { useEffect, useMemo, useState, useCallback } from 'react';
|
||||
import { useMapRootState } from '@/hooks/Mapper/mapRootProvider';
|
||||
import { VirtualScroller, VirtualScrollerTemplateOptions } from 'primereact/virtualscroller';
|
||||
import clsx from 'clsx';
|
||||
import {
|
||||
ConnectionType,
|
||||
ConnectionOutput,
|
||||
ConnectionInfoOutput,
|
||||
ConnectionOutput,
|
||||
ConnectionType,
|
||||
OutCommand,
|
||||
Passage,
|
||||
SolarSystemConnection,
|
||||
} from '@/hooks/Mapper/types';
|
||||
import clsx from 'clsx';
|
||||
import { Sidebar } from 'primereact/sidebar';
|
||||
import { VirtualScroller, VirtualScrollerTemplateOptions } from 'primereact/virtualscroller';
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import classes from './Connections.module.scss';
|
||||
|
||||
import { PassageCard } from './PassageCard';
|
||||
import { InfoDrawer, SystemView } from '@/hooks/Mapper/components/ui-kit';
|
||||
import { InfoDrawer, SystemView, TimeAgo } from '@/hooks/Mapper/components/ui-kit';
|
||||
import { kgToTons } from '@/hooks/Mapper/utils/kgToTons.ts';
|
||||
import { TimeAgo } from '@/hooks/Mapper/components/ui-kit';
|
||||
import { PassageCard } from './PassageCard';
|
||||
|
||||
const sortByDate = (a: string, b: string) => new Date(a).getTime() - new Date(b).getTime();
|
||||
|
||||
@@ -78,7 +77,7 @@ export const Connections = ({ selectedConnection, onHide }: OnTheMapProps) => {
|
||||
}, [connections, selectedConnection]);
|
||||
|
||||
const isWormhole = useMemo(() => {
|
||||
return cnInfo?.type !== ConnectionType.gate;
|
||||
return cnInfo?.type === ConnectionType.wormhole;
|
||||
}, [cnInfo]);
|
||||
|
||||
const [passages, setPassages] = useState<Passage[]>([]);
|
||||
|
||||
@@ -185,7 +185,7 @@ export const SignatureSettings = ({ systemId, show, onHide, signatureData }: Map
|
||||
<Dialog
|
||||
header={`Signature Edit [${signatureData?.eve_id}]`}
|
||||
visible={show}
|
||||
draggable={false}
|
||||
draggable={true}
|
||||
style={{ width: '390px' }}
|
||||
onShow={handleShow}
|
||||
onHide={() => {
|
||||
|
||||
@@ -18,6 +18,7 @@ export interface TooltipProps extends Omit<React.HTMLAttributes<HTMLDivElement>,
|
||||
content: (() => React.ReactNode) | React.ReactNode;
|
||||
targetSelector?: string;
|
||||
interactive?: boolean;
|
||||
smallPaddings?: boolean;
|
||||
}
|
||||
|
||||
export interface OffsetPosition {
|
||||
@@ -47,6 +48,7 @@ export const WdTooltip = forwardRef(
|
||||
position: tPosition = TooltipPosition.default,
|
||||
offset = 5,
|
||||
interactive = false,
|
||||
smallPaddings = false,
|
||||
className,
|
||||
...restProps
|
||||
}: TooltipProps,
|
||||
@@ -264,10 +266,14 @@ export const WdTooltip = forwardRef(
|
||||
ref={tooltipRef}
|
||||
className={clsx(
|
||||
classes.tooltip,
|
||||
interactive ? 'pointer-events-auto' : 'pointer-events-none',
|
||||
'absolute px-1 py-1',
|
||||
'absolute px-2 py-1',
|
||||
'border rounded-sm border-green-300 border-opacity-10 bg-stone-900 bg-opacity-90',
|
||||
pos == null && 'invisible',
|
||||
{
|
||||
'pointer-events-auto': interactive,
|
||||
'pointer-events-none': !interactive,
|
||||
invisible: pos == null,
|
||||
'!px-1': smallPaddings,
|
||||
},
|
||||
className,
|
||||
)}
|
||||
style={{
|
||||
|
||||
@@ -8,13 +8,26 @@ export type WdTooltipWrapperProps = {
|
||||
content?: (() => ReactNode) | ReactNode;
|
||||
size?: TooltipSize;
|
||||
interactive?: boolean;
|
||||
smallPaddings?: boolean;
|
||||
tooltipClassName?: string;
|
||||
} & Omit<HTMLProps<HTMLDivElement>, 'content' | 'size'> &
|
||||
Omit<TooltipProps, 'content'>;
|
||||
|
||||
export const WdTooltipWrapper = forwardRef<WdTooltipHandlers, WdTooltipWrapperProps>(
|
||||
(
|
||||
{ className, children, content, offset, position, targetSelector, interactive, size, tooltipClassName, ...props },
|
||||
{
|
||||
className,
|
||||
children,
|
||||
content,
|
||||
offset,
|
||||
position,
|
||||
targetSelector,
|
||||
interactive,
|
||||
smallPaddings,
|
||||
size,
|
||||
tooltipClassName,
|
||||
...props
|
||||
},
|
||||
forwardedRef,
|
||||
) => {
|
||||
const suffix = useMemo(() => Math.random().toString(36).slice(2, 7), []);
|
||||
@@ -31,6 +44,7 @@ export const WdTooltipWrapper = forwardRef<WdTooltipHandlers, WdTooltipWrapperPr
|
||||
position={position}
|
||||
content={content}
|
||||
interactive={interactive}
|
||||
smallPaddings={smallPaddings}
|
||||
targetSelector={finalTargetSelector}
|
||||
className={clsx(size && sizeClass(size), tooltipClassName)}
|
||||
/>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
export enum ConnectionType {
|
||||
wormhole,
|
||||
gate,
|
||||
bridge,
|
||||
}
|
||||
|
||||
export enum MassState {
|
||||
|
||||
@@ -168,6 +168,7 @@ defmodule WandererApp.Api.MapConnection do
|
||||
|
||||
# where 0 - Wormhole
|
||||
# where 1 - Gate
|
||||
# where 2 - Bridge
|
||||
attribute :type, :integer do
|
||||
default(0)
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ defmodule WandererApp.Map.Server.ConnectionsImpl do
|
||||
@connection_time_status_eol 1
|
||||
@connection_type_wormhole 0
|
||||
@connection_type_stargate 1
|
||||
@connection_type_bridge 2
|
||||
@medium_ship_size 1
|
||||
|
||||
def get_connection_auto_expire_hours(), do: WandererApp.Env.map_connection_auto_expire_hours()
|
||||
@@ -146,6 +147,18 @@ defmodule WandererApp.Map.Server.ConnectionsImpl do
|
||||
state
|
||||
end
|
||||
|
||||
def update_connection_type(
|
||||
%{map_id: map_id} = state,
|
||||
%{
|
||||
solar_system_source_id: solar_system_source_id,
|
||||
solar_system_target_id: solar_system_target_id,
|
||||
character_id: character_id
|
||||
} = _connection_info,
|
||||
type
|
||||
) do
|
||||
state
|
||||
end
|
||||
|
||||
def get_connection_info(
|
||||
%{map_id: map_id} = _state,
|
||||
%{
|
||||
@@ -239,7 +252,7 @@ defmodule WandererApp.Map.Server.ConnectionsImpl do
|
||||
} ->
|
||||
connection_start_time = get_start_time(map_id, connection_id)
|
||||
|
||||
type != @connection_type_stargate &&
|
||||
type == @connection_type_wormhole &&
|
||||
DateTime.diff(DateTime.utc_now(), connection_start_time, :hour) >=
|
||||
connection_auto_eol_hours &&
|
||||
is_connection_valid(
|
||||
@@ -295,7 +308,7 @@ defmodule WandererApp.Map.Server.ConnectionsImpl do
|
||||
)
|
||||
|
||||
not is_connection_exist ||
|
||||
(type != @connection_type_stargate && is_connection_valid &&
|
||||
(type == @connection_type_wormhole && is_connection_valid &&
|
||||
DateTime.diff(DateTime.utc_now(), connection_mark_eol_time, :hour) >=
|
||||
connection_auto_expire_hours - connection_auto_eol_hours +
|
||||
+connection_eol_expire_timeout_hours)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<section class="prose prose-lg max-w-full w-full leading-normal tracking-normal text-indigo-400 bg-cover bg-fixed flex items-center justify-center">
|
||||
<section class="prose prose-lg max-w-full w-full leading-normal tracking-normal text-indigo-400 bg-cover bg-fixed flex items-center justify-center">
|
||||
<canvas id="bg-canvas"></canvas>
|
||||
<div class="h-full w-full flex flex-col items-center">
|
||||
<!--Main-->
|
||||
@@ -26,23 +26,71 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="carousel carousel-center bg-neutral rounded-box max-w-[80%] space-x-4 p-4">
|
||||
<%= for post <- @posts do %>
|
||||
<.link class="group carousel-item relative" navigate={~p"/news/#{post.id}"}>
|
||||
<div class="artboard-horizontal phone-1 relative hover:text-white mt-10">
|
||||
<img
|
||||
class="rounded-lg shadow-lg block !w-[400px] !h-[200px] opacity-75"
|
||||
src={post.cover_image_uri}
|
||||
/>
|
||||
<div class="absolute top-0 left-0 w-full h-full bg-gradient-to-b from-transparent to-black opacity-75 group-hover:opacity-25 transition-opacity duration-300">
|
||||
<div id="posts-container" class="bg-neutral rounded-box max-w-[90%] p-4 max-h-[60vh] overflow-y-auto">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
|
||||
<%= for post <- @posts do %>
|
||||
<.link class="group carousel-item relative" navigate={~p"/news/#{post.id}"}>
|
||||
<div class="artboard-horizontal phone-1 relative hover:text-white">
|
||||
<img
|
||||
class="rounded-lg shadow-lg block !w-[300px] !h-[180px] opacity-75"
|
||||
src={post.cover_image_uri}
|
||||
/>
|
||||
<div class="absolute rounded-lg top-0 left-0 w-full h-full bg-gradient-to-b from-transparent to-black opacity-75 group-hover:opacity-25 transition-opacity duration-300">
|
||||
</div>
|
||||
<h3 class="absolute bottom-4 left-14 !text-md font-bold break-normal pt-6 pb-2 ccp-font text-white">
|
||||
{post.title}
|
||||
</h3>
|
||||
</div>
|
||||
<h3 class="absolute bottom-4 left-14 font-bold break-normal pt-6 pb-2 ccp-font text-white">
|
||||
{post.title}
|
||||
</h3>
|
||||
</div>
|
||||
</.link>
|
||||
<% end %>
|
||||
</.link>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const postsContainer = document.getElementById('posts-container');
|
||||
if (!postsContainer) return;
|
||||
|
||||
let scrollSpeed = 0.5; // pixels per frame
|
||||
let isScrolling = true;
|
||||
let scrollDirection = 1; // 1 for down, -1 for up
|
||||
|
||||
function autoScroll() {
|
||||
if (!isScrolling) return;
|
||||
|
||||
const maxScroll = postsContainer.scrollHeight - postsContainer.clientHeight;
|
||||
|
||||
if (maxScroll <= 0) return; // No need to scroll if content fits
|
||||
|
||||
postsContainer.scrollTop += scrollSpeed * scrollDirection;
|
||||
|
||||
// Reverse direction when reaching top or bottom
|
||||
if (postsContainer.scrollTop >= maxScroll) {
|
||||
scrollDirection = -1;
|
||||
} else if (postsContainer.scrollTop <= 0) {
|
||||
scrollDirection = 1;
|
||||
}
|
||||
|
||||
requestAnimationFrame(autoScroll);
|
||||
}
|
||||
|
||||
// Pause scrolling on hover
|
||||
postsContainer.addEventListener('mouseenter', () => {
|
||||
isScrolling = false;
|
||||
});
|
||||
|
||||
// Resume scrolling when mouse leaves
|
||||
postsContainer.addEventListener('mouseleave', () => {
|
||||
isScrolling = true;
|
||||
requestAnimationFrame(autoScroll);
|
||||
});
|
||||
|
||||
// Start autoscroll after a delay
|
||||
setTimeout(() => {
|
||||
requestAnimationFrame(autoScroll);
|
||||
}, 2000);
|
||||
});
|
||||
</script>
|
||||
<%!-- <div class="carousel carousel-center !bg-neutral rounded-box max-w-4xl space-x-6 p-4">
|
||||
|
||||
</div> --%>
|
||||
|
||||
@@ -34,7 +34,11 @@
|
||||
</button>
|
||||
</:action>
|
||||
</.table>
|
||||
<.link :if={@allow_acl_creation} class="btn mt-2 w-full btn-neutral rounded-none" patch={~p"/access-lists/new"}>
|
||||
<.link
|
||||
:if={@allow_acl_creation}
|
||||
class="btn mt-2 w-full btn-neutral rounded-none"
|
||||
patch={~p"/access-lists/new"}
|
||||
>
|
||||
<.icon name="hero-plus-solid" class="w-6 h-6" />
|
||||
<h3 class="card-title text-center text-md">New Access List</h3>
|
||||
</.link>
|
||||
@@ -142,10 +146,10 @@
|
||||
placeholder="Select an owner"
|
||||
options={Enum.map(@characters, fn character -> {character.label, character.id} end)}
|
||||
/>
|
||||
|
||||
|
||||
<!-- Divider between above inputs and the API key section -->
|
||||
<hr class="my-4 border-gray-600" />
|
||||
|
||||
|
||||
<!-- API Key Section with grid layout -->
|
||||
<div class="mt-2">
|
||||
<label class="block text-sm font-medium text-gray-200 mb-1">ACL API key</label>
|
||||
|
||||
2
mix.exs
2
mix.exs
@@ -3,7 +3,7 @@ defmodule WandererApp.MixProject do
|
||||
|
||||
@source_url "https://github.com/wanderer-industries/wanderer"
|
||||
|
||||
@version "1.77.18"
|
||||
@version "1.78.1"
|
||||
|
||||
def project do
|
||||
[
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
%{
|
||||
title: "Guide: Systems and Connections API",
|
||||
author: "Wanderer Team",
|
||||
cover_image_uri: "/images/news/05-07-systems/api-endpoints.png",
|
||||
cover_image_uri: "/images/news/03-05-api/swagger-ui.png",
|
||||
tags: ~w(api map systems connections documentation),
|
||||
description: "Detailed guide for Wanderer's systems and connections API endpoints, including batch operations, updates, and deletions."
|
||||
}
|
||||
@@ -912,4 +912,4 @@ If you have questions about these endpoints or need assistance, please reach out
|
||||
Fly safe,
|
||||
**The Wanderer Team**
|
||||
|
||||
----
|
||||
----
|
||||
|
||||
@@ -23286,7 +23286,7 @@
|
||||
"solarSystemID": 31002568,
|
||||
"statics": [
|
||||
"U210",
|
||||
"H296"
|
||||
"Y790"
|
||||
],
|
||||
"systemName": "J005663",
|
||||
"effectName": null
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"dest": "ls",
|
||||
"src": ["c2"],
|
||||
"static": true,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "24",
|
||||
"total_mass": 2000000000,
|
||||
"name": "A239",
|
||||
@@ -37,7 +37,7 @@
|
||||
"dest": "c6",
|
||||
"src": ["c3", "thera"],
|
||||
"static": false,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "24",
|
||||
"total_mass": 3000000000,
|
||||
"name": "A982",
|
||||
@@ -48,7 +48,7 @@
|
||||
"dest": "c6",
|
||||
"src": ["hs"],
|
||||
"static": false,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "48",
|
||||
"total_mass": 3000000000,
|
||||
"name": "B041",
|
||||
@@ -59,7 +59,7 @@
|
||||
"dest": "hs",
|
||||
"src": ["c2"],
|
||||
"static": true,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "24",
|
||||
"total_mass": 2000000000,
|
||||
"name": "B274",
|
||||
@@ -81,7 +81,7 @@
|
||||
"dest": "hs",
|
||||
"src": ["c6"],
|
||||
"static": false,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "48",
|
||||
"total_mass": 3000000000,
|
||||
"name": "B520",
|
||||
@@ -92,7 +92,7 @@
|
||||
"dest": "barbican",
|
||||
"src": ["hs", "ls", "ns", "jove"],
|
||||
"static": false,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "16",
|
||||
"total_mass": 750000000,
|
||||
"name": "B735",
|
||||
@@ -136,7 +136,7 @@
|
||||
"dest": "c3",
|
||||
"src": ["c4"],
|
||||
"static": true,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "16",
|
||||
"total_mass": 2000000000,
|
||||
"name": "C247",
|
||||
@@ -169,7 +169,7 @@
|
||||
"dest": "conflux",
|
||||
"src": ["hs", "ls", "ns", "jove"],
|
||||
"static": false,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "16",
|
||||
"total_mass": 750000000,
|
||||
"name": "C414",
|
||||
@@ -191,7 +191,7 @@
|
||||
"dest": "c2",
|
||||
"src": ["c5"],
|
||||
"static": true,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "16",
|
||||
"total_mass": 1000000000,
|
||||
"name": "D364",
|
||||
@@ -202,7 +202,7 @@
|
||||
"dest": "c2",
|
||||
"src": ["c2", "drifter"],
|
||||
"static": true,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "16",
|
||||
"total_mass": 2000000000,
|
||||
"name": "D382",
|
||||
@@ -224,7 +224,7 @@
|
||||
"dest": "hs",
|
||||
"src": ["c3", "c4-shattered"],
|
||||
"static": true,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "24",
|
||||
"total_mass": 5000000000,
|
||||
"name": "D845",
|
||||
@@ -246,7 +246,7 @@
|
||||
"dest": "c4",
|
||||
"src": ["c5"],
|
||||
"static": true,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "16",
|
||||
"total_mass": 2000000000,
|
||||
"name": "E175",
|
||||
@@ -257,7 +257,7 @@
|
||||
"dest": "ns",
|
||||
"src": ["c2"],
|
||||
"static": true,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "16",
|
||||
"total_mass": 2000000000,
|
||||
"name": "E545",
|
||||
@@ -269,7 +269,7 @@
|
||||
"src": ["thera"],
|
||||
"static": true,
|
||||
"max_mass_per_jump": 1000000000,
|
||||
"lifetime": "16",
|
||||
"lifetime": "48",
|
||||
"total_mass": 3000000000,
|
||||
"name": "E587",
|
||||
"respawn": ["static"]
|
||||
@@ -279,7 +279,7 @@
|
||||
"dest": "thera",
|
||||
"src": ["c2", "c3", "c4", "c5", "c6"],
|
||||
"static": false,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "16",
|
||||
"total_mass": 750000000,
|
||||
"name": "F135",
|
||||
@@ -323,7 +323,7 @@
|
||||
"dest": "c2",
|
||||
"src": ["c6"],
|
||||
"static": true,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "16",
|
||||
"total_mass": 2000000000,
|
||||
"name": "G024",
|
||||
@@ -356,7 +356,7 @@
|
||||
"dest": "c5",
|
||||
"src": ["c4"],
|
||||
"static": true,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "24",
|
||||
"total_mass": 3000000000,
|
||||
"name": "H900",
|
||||
@@ -367,7 +367,7 @@
|
||||
"dest": "c2",
|
||||
"src": ["c3", "thera"],
|
||||
"static": false,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "16",
|
||||
"total_mass": 2000000000,
|
||||
"name": "I182",
|
||||
@@ -396,13 +396,13 @@
|
||||
"respawn": ["wandering", "reverse"]
|
||||
},
|
||||
{
|
||||
"mass_regen": 500000000,
|
||||
"mass_regen": 0,
|
||||
"dest": "ns",
|
||||
"src": ["c4"],
|
||||
"static": false,
|
||||
"max_mass_per_jump": 1800000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "24",
|
||||
"total_mass": 5000000000,
|
||||
"total_mass": 3000000000,
|
||||
"name": "K329",
|
||||
"respawn": ["wandering"]
|
||||
},
|
||||
@@ -411,7 +411,7 @@
|
||||
"dest": "ns",
|
||||
"src": ["c3", "c4-shattered", "c5-shattered", "c6-shattered"],
|
||||
"static": true,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "16",
|
||||
"total_mass": 3000000000,
|
||||
"name": "K346",
|
||||
@@ -444,7 +444,7 @@
|
||||
"dest": "c3",
|
||||
"src": ["c6"],
|
||||
"static": true,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "16",
|
||||
"total_mass": 2000000000,
|
||||
"name": "L477",
|
||||
@@ -477,7 +477,7 @@
|
||||
"dest": "thera",
|
||||
"src": ["ls"],
|
||||
"static": false,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "16",
|
||||
"total_mass": 2000000000,
|
||||
"name": "M164",
|
||||
@@ -488,7 +488,7 @@
|
||||
"dest": "c3",
|
||||
"src": ["c5"],
|
||||
"static": true,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "16",
|
||||
"total_mass": 1000000000,
|
||||
"name": "M267",
|
||||
@@ -539,13 +539,13 @@
|
||||
"respawn": ["static"]
|
||||
},
|
||||
{
|
||||
"mass_regen": 500000000,
|
||||
"mass_regen": 0,
|
||||
"dest": "ls",
|
||||
"src": ["c4"],
|
||||
"static": false,
|
||||
"max_mass_per_jump": 2000000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "24",
|
||||
"total_mass": 3300000000,
|
||||
"total_mass": 3000000000,
|
||||
"name": "N290",
|
||||
"respawn": ["wandering"]
|
||||
},
|
||||
@@ -565,7 +565,7 @@
|
||||
"dest": "c2",
|
||||
"src": ["c4"],
|
||||
"static": true,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "16",
|
||||
"total_mass": 2000000000,
|
||||
"name": "N766",
|
||||
@@ -576,7 +576,7 @@
|
||||
"dest": "c5",
|
||||
"src": ["c3", "thera"],
|
||||
"static": false,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "24",
|
||||
"total_mass": 3000000000,
|
||||
"name": "N770",
|
||||
@@ -598,7 +598,7 @@
|
||||
"dest": "c3",
|
||||
"src": ["c3", "thera"],
|
||||
"static": false,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "16",
|
||||
"total_mass": 2000000000,
|
||||
"name": "N968",
|
||||
@@ -609,7 +609,7 @@
|
||||
"dest": "c4",
|
||||
"src": ["hs", "ls", "ns"],
|
||||
"static": false,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "24",
|
||||
"total_mass": 1000000000,
|
||||
"name": "O128",
|
||||
@@ -620,7 +620,7 @@
|
||||
"dest": "c3",
|
||||
"src": ["c2", "drifter"],
|
||||
"static": true,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "16",
|
||||
"total_mass": 2000000000,
|
||||
"name": "O477",
|
||||
@@ -708,7 +708,7 @@
|
||||
"dest": "redoubt",
|
||||
"src": ["hs", "ls", "ns", "jove"],
|
||||
"static": false,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "16",
|
||||
"total_mass": 750000000,
|
||||
"name": "R259",
|
||||
@@ -719,7 +719,7 @@
|
||||
"dest": "c6",
|
||||
"src": ["c2", "drifter"],
|
||||
"static": true,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "24",
|
||||
"total_mass": 3000000000,
|
||||
"name": "R474",
|
||||
@@ -730,7 +730,7 @@
|
||||
"dest": "c2",
|
||||
"src": ["hs", "ls", "ns"],
|
||||
"static": false,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "16",
|
||||
"total_mass": 750000000,
|
||||
"name": "R943",
|
||||
@@ -741,7 +741,7 @@
|
||||
"dest": "hs",
|
||||
"src": ["c4"],
|
||||
"static": false,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "24",
|
||||
"total_mass": 3000000000,
|
||||
"name": "S047",
|
||||
@@ -774,7 +774,7 @@
|
||||
"dest": "sentinel",
|
||||
"src": ["hs", "ls", "ns", "jove"],
|
||||
"static": false,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "16",
|
||||
"total_mass": 750000000,
|
||||
"name": "S877",
|
||||
@@ -785,7 +785,7 @@
|
||||
"dest": "c4",
|
||||
"src": ["c3", "thera"],
|
||||
"static": false,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "16",
|
||||
"total_mass": 2000000000,
|
||||
"name": "T405",
|
||||
@@ -807,7 +807,7 @@
|
||||
"dest": "ls",
|
||||
"src": ["c3", "c4-shattered", "c5-shattered"],
|
||||
"static": true,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "24",
|
||||
"total_mass": 3000000000,
|
||||
"name": "U210",
|
||||
@@ -840,7 +840,7 @@
|
||||
"dest": "c6",
|
||||
"src": ["c4"],
|
||||
"static": true,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "24",
|
||||
"total_mass": 3000000000,
|
||||
"name": "U574",
|
||||
@@ -884,7 +884,7 @@
|
||||
"dest": "ls",
|
||||
"src": ["thera"],
|
||||
"static": true,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "16",
|
||||
"total_mass": 2000000000,
|
||||
"name": "V898",
|
||||
@@ -906,7 +906,7 @@
|
||||
"dest": "vidette",
|
||||
"src": ["hs", "ls", "ns", "jove"],
|
||||
"static": false,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "16",
|
||||
"total_mass": 750000000,
|
||||
"name": "V928",
|
||||
@@ -939,7 +939,7 @@
|
||||
"dest": "c3",
|
||||
"src": ["hs", "ls", "ns"],
|
||||
"static": false,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "24",
|
||||
"total_mass": 1000000000,
|
||||
"name": "X702",
|
||||
@@ -950,7 +950,7 @@
|
||||
"dest": "c4",
|
||||
"src": ["c4"],
|
||||
"static": true,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "16",
|
||||
"total_mass": 2000000000,
|
||||
"name": "X877",
|
||||
@@ -961,7 +961,7 @@
|
||||
"dest": "c4",
|
||||
"src": ["c2", "drifter"],
|
||||
"static": true,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "16",
|
||||
"total_mass": 2000000000,
|
||||
"name": "Y683",
|
||||
@@ -1016,7 +1016,7 @@
|
||||
"dest": "c4",
|
||||
"src": ["c6"],
|
||||
"static": true,
|
||||
"max_mass_per_jump": 300000000,
|
||||
"max_mass_per_jump": 375000000,
|
||||
"lifetime": "16",
|
||||
"total_mass": 2000000000,
|
||||
"name": "Z457",
|
||||
@@ -1044,6 +1044,17 @@
|
||||
"name": "Z971",
|
||||
"respawn": ["wandering"]
|
||||
},
|
||||
{
|
||||
"mass_regen": 0,
|
||||
"dest": "ls",
|
||||
"src": ["c1", "c2", "c3", "c4", "c5", "c6"],
|
||||
"static": false,
|
||||
"max_mass_per_jump": 62000000,
|
||||
"lifetime": "24",
|
||||
"total_mass": 100000000,
|
||||
"name": "J492",
|
||||
"respawn": ["wandering", "reverse"]
|
||||
},
|
||||
{
|
||||
"mass_regen": null,
|
||||
"dest": null,
|
||||
|
||||
Reference in New Issue
Block a user