feat(Core): added support for jumpgates connection type

This commit is contained in:
Dmitry Popov
2025-03-23 21:51:26 +01:00
parent affe184ccd
commit 854524a03c
6 changed files with 54 additions and 30 deletions

View File

@@ -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 { import {
MASS_STATE_NAMES, MASS_STATE_NAMES,
MASS_STATE_NAMES_ORDER, MASS_STATE_NAMES_ORDER,
@@ -13,7 +6,14 @@ import {
SHIP_SIZES_NAMES_SHORT, SHIP_SIZES_NAMES_SHORT,
SHIP_SIZES_SIZE, SHIP_SIZES_SIZE,
} from '@/hooks/Mapper/components/map/constants.ts'; } 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 { Edge } from 'reactflow';
import classes from './ContextMenuConnection.module.scss';
export interface ContextMenuConnectionProps { export interface ContextMenuConnectionProps {
contextMenuRef: RefObject<ContextMenu>; contextMenuRef: RefObject<ContextMenu>;
@@ -42,7 +42,7 @@ export const ContextMenuConnection: React.FC<ContextMenuConnectionProps> = ({
} }
const isFrigateSize = edge.data?.ship_size_type === ShipSizeStatus.small; const isFrigateSize = edge.data?.ship_size_type === ShipSizeStatus.small;
const isWormhole = edge.data?.type !== ConnectionType.gate; const isWormhole = edge.data?.type === ConnectionType.wormhole;
return [ return [
...(isWormhole ...(isWormhole

View File

@@ -1,14 +1,14 @@
import { useCallback, useMemo, useState } from 'react'; import { useCallback, useMemo, useState } from 'react';
import classes from './SolarSystemEdge.module.scss';
import { EdgeLabelRenderer, EdgeProps, getBezierPath, getSmoothStepPath, Position, useStore } from 'reactflow';
import { getEdgeParams } from '@/hooks/Mapper/components/map/utils.ts';
import clsx from 'clsx';
import { ConnectionType, MassState, ShipSizeStatus, SolarSystemConnection, TimeStatus } from '@/hooks/Mapper/types';
import { PrimeIcons } from 'primereact/api';
import { WdTooltipWrapper } from '@/hooks/Mapper/components/ui-kit/WdTooltipWrapper';
import { useMapState } from '@/hooks/Mapper/components/map/MapProvider.tsx'; 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 { SHIP_SIZES_DESCRIPTION, SHIP_SIZES_NAMES_SHORT } from '@/hooks/Mapper/components/map/constants.ts';
import { getEdgeParams } from '@/hooks/Mapper/components/map/utils.ts';
import { WdTooltipWrapper } from '@/hooks/Mapper/components/ui-kit/WdTooltipWrapper';
import { ConnectionType, MassState, ShipSizeStatus, SolarSystemConnection, TimeStatus } from '@/hooks/Mapper/types';
import clsx from 'clsx';
import { PrimeIcons } from 'primereact/api';
import { EdgeLabelRenderer, EdgeProps, getBezierPath, getSmoothStepPath, Position, useStore } from 'reactflow';
import classes from './SolarSystemEdge.module.scss';
const MAP_TRANSLATES: Record<string, string> = { const MAP_TRANSLATES: Record<string, string> = {
[Position.Top]: 'translate(-48%, 0%)', [Position.Top]: 'translate(-48%, 0%)',
@@ -42,7 +42,7 @@ export const SHIP_SIZES_COLORS = {
export const SolarSystemEdge = ({ id, source, target, markerEnd, style, data }: EdgeProps<SolarSystemConnection>) => { export const SolarSystemEdge = ({ id, source, target, markerEnd, style, data }: EdgeProps<SolarSystemConnection>) => {
const sourceNode = useStore(useCallback(store => store.nodeInternals.get(source), [source])); const sourceNode = useStore(useCallback(store => store.nodeInternals.get(source), [source]));
const targetNode = useStore(useCallback(store => store.nodeInternals.get(target), [target])); const targetNode = useStore(useCallback(store => store.nodeInternals.get(target), [target]));
const isWormhole = data?.type !== ConnectionType.gate; const isWormhole = data?.type === ConnectionType.wormhole;
const { const {
data: { isThickConnections }, data: { isThickConnections },

View File

@@ -716,11 +716,12 @@ export const STATUS_CLASSES: Record<number, string> = {
[STATUSES.dangerous]: 'eve-system-status-dangerous', [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.jumpgate];
export const TYPE_NAMES = { export const TYPE_NAMES = {
[ConnectionType.wormhole]: 'Wormhole', [ConnectionType.wormhole]: 'Wormhole',
[ConnectionType.gate]: 'Gate', [ConnectionType.gate]: 'Gate',
[ConnectionType.jumpgate]: 'Jumpgate',
}; };
export const MASS_STATE_NAMES_ORDER = [MassState.verge, MassState.half, MassState.normal]; export const MASS_STATE_NAMES_ORDER = [MassState.verge, MassState.half, MassState.normal];

View File

@@ -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 { useMapRootState } from '@/hooks/Mapper/mapRootProvider';
import { VirtualScroller, VirtualScrollerTemplateOptions } from 'primereact/virtualscroller';
import clsx from 'clsx';
import { import {
ConnectionType,
ConnectionOutput,
ConnectionInfoOutput, ConnectionInfoOutput,
ConnectionOutput,
ConnectionType,
OutCommand, OutCommand,
Passage, Passage,
SolarSystemConnection, SolarSystemConnection,
} from '@/hooks/Mapper/types'; } 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, TimeAgo } from '@/hooks/Mapper/components/ui-kit';
import { InfoDrawer, SystemView } from '@/hooks/Mapper/components/ui-kit';
import { kgToTons } from '@/hooks/Mapper/utils/kgToTons.ts'; 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(); 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]); }, [connections, selectedConnection]);
const isWormhole = useMemo(() => { const isWormhole = useMemo(() => {
return cnInfo?.type !== ConnectionType.gate; return cnInfo?.type === ConnectionType.wormhole;
}, [cnInfo]); }, [cnInfo]);
const [passages, setPassages] = useState<Passage[]>([]); const [passages, setPassages] = useState<Passage[]>([]);

View File

@@ -1,6 +1,7 @@
export enum ConnectionType { export enum ConnectionType {
wormhole, wormhole,
gate, gate,
jumpgate,
} }
export enum MassState { export enum MassState {

View File

@@ -69,6 +69,7 @@ defmodule WandererApp.Map.Server.ConnectionsImpl do
@connection_time_status_eol 1 @connection_time_status_eol 1
@connection_type_wormhole 0 @connection_type_wormhole 0
@connection_type_stargate 1 @connection_type_stargate 1
@connection_type_jumpgate 2
def get_connection_auto_expire_hours(), do: WandererApp.Env.map_connection_auto_expire_hours() def get_connection_auto_expire_hours(), do: WandererApp.Env.map_connection_auto_expire_hours()
@@ -144,6 +145,28 @@ defmodule WandererApp.Map.Server.ConnectionsImpl do
state state
end 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
# :ok =
# maybe_add_connection(
# map_id,
# %{solar_system_id: solar_system_target_id},
# %{
# solar_system_id: solar_system_source_id
# },
# character_id
# )
state
end
def get_connection_info( def get_connection_info(
%{map_id: map_id} = _state, %{map_id: map_id} = _state,
%{ %{
@@ -236,7 +259,7 @@ defmodule WandererApp.Map.Server.ConnectionsImpl do
} -> } ->
connection_start_time = get_start_time(map_id, connection_id) 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) >= DateTime.diff(DateTime.utc_now(), connection_start_time, :hour) >=
connection_auto_eol_hours && connection_auto_eol_hours &&
is_connection_valid( is_connection_valid(
@@ -292,7 +315,7 @@ defmodule WandererApp.Map.Server.ConnectionsImpl do
) )
not is_connection_exist || 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) >= DateTime.diff(DateTime.utc_now(), connection_mark_eol_time, :hour) >=
connection_auto_expire_hours - connection_auto_eol_hours + connection_auto_expire_hours - connection_auto_eol_hours +
+connection_eol_expire_timeout_hours) +connection_eol_expire_timeout_hours)