searches, thanks Shadow for helpting with the function generalization

This commit is contained in:
Kashargul
2024-09-20 00:50:05 +02:00
parent 4145064a05
commit da707c15f7
8 changed files with 378 additions and 67 deletions
+49 -2
View File
@@ -51,10 +51,11 @@
.["target"]["active"] = target.icon_selected
.["target"]["front"] = icon2base64(get_flat_icon(target,dir=SOUTH,no_anim=TRUE))
.["target"]["side"] = icon2base64(get_flat_icon(target,dir=WEST,no_anim=TRUE))
.["target"]["side_alt"] = icon2base64(get_flat_icon(target,dir=EAST,no_anim=TRUE))
.["target"]["back"] = icon2base64(get_flat_icon(target,dir=NORTH,no_anim=TRUE))
var/list/target_items = list()
for(var/obj/item in target.module.modules)
target_items += list(list("item" = item.name, "ref" = "\ref[item]", "icon" = icon2html(item, user, sourceonly=TRUE), "desc" = item.desc))
target_items += list(list("name" = item.name, "ref" = "\ref[item]", "icon" = icon2html(item, user, sourceonly=TRUE), "desc" = item.desc))
.["target"]["modules"] = target_items
var/list/module_options = list()
for(var/module in robot_modules)
@@ -102,6 +103,7 @@
var/obj/item/weapon/gun/energy/kinetic_accelerator/kin = locate() in target.module.modules
if(kin)
.["target"]["pka"] = list()
.["target"]["pka"]["name"] = kin.name
var/list/installed_modkits = list()
for(var/obj/item/borg/upgrade/modkit/modkit in kin.modkits)
installed_modkits += list(list("name" = modkit.name, "ref" = "\ref[modkit]", "costs" = modkit.cost))
@@ -132,6 +134,16 @@
.["target"]["pka"]["modkits"] = modkits
.["target"]["pka"]["capacity"] = kin.get_remaining_mod_capacity()
.["target"]["pka"]["max_capacity"] = kin.max_mod_capacity
// Radio section
var/list/radio_channels = list()
for(var/channel in target.radio.channels)
radio_channels += channel
var/list/availalbe_channels = list()
for(var/channel in (radiochannels - target.radio.channels))
availalbe_channels += channel
.["target"]["radio_channels"] = radio_channels
.["target"]["availalbe_channels"] = availalbe_channels
// Section for source data for the module we might want to salvage
if(source)
.["source"] = list()
@@ -146,7 +158,7 @@
break
if(exists)
continue
source_items += list(list("item" = item.name, "ref" = "\ref[item]", "icon" = icon2html(item, user, sourceonly=TRUE), "desc" = item.desc))
source_items += list(list("name" = item.name, "ref" = "\ref[item]", "icon" = icon2html(item, user, sourceonly=TRUE), "desc" = item.desc))
.["source"]["modules"] = source_items
var/list/all_robots = list()
for(var/mob/living/silicon/robot/R in silicon_mob_list)
@@ -283,6 +295,10 @@
target.hands.icon_state = target.get_hud_module_icon()
target.hud_used.update_robot_modules_display()
return TRUE
if("ert_toggle")
target.crisis_override = !target.crisis_override
target.module_reset(FALSE)
return TRUE
if("add_compatibility")
target.module.supported_upgrades |= text2path(params["upgrade"])
return TRUE
@@ -321,3 +337,34 @@
kin.modkits.Remove(rem_kit)
qdel(rem_kit)
return TRUE
if("add_channel")
var/selected_radio_channel = params["channel"]
if(selected_radio_channel == CHANNEL_SPECIAL_OPS)
target.radio.centComm = 1
if(selected_radio_channel == CHANNEL_RAIDER)
qdel(target.radio.keyslot)
target.radio.keyslot = new /obj/item/device/encryptionkey/raider(target)
target.radio.syndie = 1
if(selected_radio_channel == CHANNEL_MERCENARY)
qdel(target.radio.keyslot)
target.radio.keyslot = new /obj/item/device/encryptionkey/syndicate(target)
target.radio.syndie = 1
target.module.channels += list("[selected_radio_channel]" = 1)
target.radio.channels[selected_radio_channel] += target.module.channels[selected_radio_channel]
target.radio.secure_radio_connections[selected_radio_channel] += radio_controller.add_object(target.radio, radiochannels[selected_radio_channel], RADIO_CHAT)
return TRUE
if("rem_channel")
var/selected_radio_channel = params["channel"]
if(selected_radio_channel == CHANNEL_SPECIAL_OPS)
target.radio.centComm = 0
target.module.channels -= selected_radio_channel
if((selected_radio_channel == CHANNEL_MERCENARY || selected_radio_channel == CHANNEL_RAIDER) && !(target.module.channels[CHANNEL_RAIDER] || target.module.channels[CHANNEL_MERCENARY]))
qdel(target.radio.keyslot)
target.radio.keyslot = null
target.radio.syndie = 0
target.radio.channels = list()
for(var/n_chan in target.module.channels)
target.radio.channels[n_chan] -= target.module.channels[n_chan]
radio_controller.remove_object(target.radio, radiochannels[selected_radio_channel])
target.radio.secure_radio_connections -= selected_radio_channel
return TRUE
@@ -1,6 +1,3 @@
import { filter } from 'common/collections';
import { flow } from 'common/fp';
import { createSearch } from 'common/string';
import { useState } from 'react';
import { useBackend } from 'tgui/backend';
import {
@@ -17,6 +14,7 @@ import {
} from 'tgui/components';
import { NoSpriteWarning } from '../components';
import { prepareSearch } from '../functions';
import { Module, Source, Target } from '../types';
export const ModifyRobotModules = (props: {
@@ -61,13 +59,34 @@ export const ModifyRobotModules = (props: {
</Flex.Item>
<Flex.Item grow />
<Flex.Item>
<Button
disabled={!source}
tooltip="Swaps the source and destination module types."
icon="arrows-rotate"
iconSize={4}
onClick={() => act('swap_module')}
/>
<Stack vertical>
<Stack.Item>
<Button
disabled={!source}
tooltip="Swaps the source and destination module types."
icon="arrows-rotate"
iconSize={4}
onClick={() => act('swap_module')}
/>
</Stack.Item>
<Stack.Item>
<Button.Confirm
width="50px"
height="50px"
mt={40}
textAlign="center"
tooltip={
(target.crisis_override ? 'Disable' : 'Enable') +
' ERT module access and reset the robot!'
}
color={target.crisis_override ? 'green' : 'yellow'}
icon="circle-radiation"
iconSize={4}
confirmContent="GO?"
onClick={() => act('ert_toggle')}
/>
</Stack.Item>
</Stack>
</Flex.Item>
<Flex.Item grow />
<Flex.Item width="40%" fill>
@@ -100,22 +119,8 @@ export const ModifyRobotModules = (props: {
);
};
function prepareSearch(modules: Module[], searchText: string = ''): Module[] {
const testSearch = createSearch(searchText, (module: Module) => module.item);
return flow([
(modules: Module[]) => {
// Optional search term
if (!searchText) {
return modules;
} else {
return filter(modules, testSearch);
}
},
])(modules);
}
const SelectionField = (props: {
previewImage: string | null;
previewImage: string | undefined;
searchText: string;
onSearchText: Function;
action: string;
@@ -172,7 +177,7 @@ const SelectionField = (props: {
<Flex.Item>
<Image src={modul_option.icon} />
</Flex.Item>
<Flex.Item ml="10px">{modul_option.item}</Flex.Item>
<Flex.Item ml="10px">{modul_option.name}</Flex.Item>
<Flex.Item grow />
<Flex.Item>
<Icon
@@ -1,12 +1,24 @@
import { useState } from 'react';
import { useBackend } from 'tgui/backend';
import { Box, Button, Flex, NoticeBox } from 'tgui/components';
import {
Box,
Button,
Divider,
Flex,
Image,
Input,
NoticeBox,
} from 'tgui/components';
import { NoSpriteWarning } from '../components';
import { Target } from '../types';
import { prepareSearch } from '../functions';
import { Module, Target } from '../types';
export const ModifyRobotPKA = (props: { target: Target }) => {
const { act } = useBackend();
const { target } = props;
const [searchModkitText, setSearchModkitText] = useState<string>('');
const [searchInstalledtext, setSearchInstalledtext] = useState<string>('');
return (
<>
@@ -15,37 +27,67 @@ export const ModifyRobotPKA = (props: { target: Target }) => {
<NoticeBox danger>{target.name} has no PKA installed.</NoticeBox>
) : (
<Flex height={!target.active ? '80%' : '85%'}>
<Flex.Item width="45%" fill>
<Flex.Item width="35%" fill>
<Divider />
<Box>Remaining Capacity: {target.pka.capacity}</Box>
{target.pka.modkits.map((modkit, i) => {
return (
<Button
fluid
key={i}
disabled={modkit.denied}
color="green"
tooltip={
modkit.denied_by
? 'Modul incompatible with: ' + modkit.denied_by
: ''
}
onClick={() =>
act('install_modkit', {
modkit: modkit.path,
})
}
>
{modkit.name} {modkit.costs}
</Button>
);
})}
<Divider />
<Input
fluid
value={searchModkitText}
placeholder="Search for modkits..."
onInput={(e, value: string) => setSearchModkitText(value)}
/>
<Divider />
{prepareSearch(target.pka.modkits, searchModkitText).map(
(modkit, i) => {
return (
<Button
fluid
key={i}
disabled={modkit.denied}
color="green"
tooltip={
modkit.denied_by
? 'Modul incompatible with: ' + modkit.denied_by
: ''
}
onClick={() =>
act('install_modkit', {
modkit: modkit.path,
})
}
>
{modkit.name} {modkit.costs}
</Button>
);
},
)}
</Flex.Item>
<Flex.Item width="10%" />
<Flex.Item width="45%" fill>
<Flex.Item grow />
<Flex.Item>
<Image
src={getPKAIcon(target.modules, target.pka.name)}
width="150px"
/>
</Flex.Item>
<Flex.Item grow />
<Flex.Item width="35%" fill>
<Divider />
<Box>
Used Capacity: {target.pka.max_capacity - target.pka.capacity}
</Box>
{target.pka.installed_modkits.map((modkit, i) => {
<Divider />
<Input
fluid
value={searchInstalledtext}
placeholder="Search for modkits..."
onInput={(e, value: string) => setSearchInstalledtext(value)}
/>
<Divider />
{prepareSearch(
target.pka.installed_modkits,
searchInstalledtext,
).map((modkit, i) => {
return (
<Button
fluid
@@ -67,3 +109,13 @@ export const ModifyRobotPKA = (props: { target: Target }) => {
</>
);
};
function getPKAIcon(modules: Module[], name: string) {
if (modules) {
const module = modules.filter((module) => module.name === name);
if (module.length > 0) {
return module[0].icon;
}
}
return '';
}
@@ -0,0 +1,125 @@
import { useState } from 'react';
import { useBackend } from 'tgui/backend';
import {
Button,
Divider,
Flex,
Icon,
Image,
Input,
Section,
Stack,
} from 'tgui/components';
import { NoSpriteWarning } from '../components';
import { prepareSearch } from '../functions';
import { Target } from '../types';
export const ModifyRobotRadio = (props: { target: Target }) => {
const { target } = props;
const [searchChannelAddText, setSearchChannelAddText] = useState<string>('');
const [searchChannelRemoveText, setSearchChannelRemoveText] =
useState<string>('');
return (
<>
{!target.active && <NoSpriteWarning name={target.name} />}
<Flex height={!target.active ? '80%' : '85%'}>
<Flex.Item width="30%" fill>
<RadioSection
title="Add Radio Channel"
searchText={searchChannelAddText}
onSearchText={setSearchChannelAddText}
channels={target.availalbe_channels}
action="add_channel"
buttonColor="green"
buttonIcon="arrow-right-to-bracket"
/>
</Flex.Item>
<Flex.Item width="40%">
<Image
src={'data:image/jpeg;base64, ' + target.back}
style={{
display: 'block',
marginLeft: 'auto',
marginRight: 'auto',
width: '200px',
}}
/>
</Flex.Item>
<Flex.Item width="30%" fill>
<RadioSection
title="Remove Radio Channel"
searchText={searchChannelRemoveText}
onSearchText={setSearchChannelRemoveText}
channels={target.radio_channels}
action="rem_channel"
buttonColor="red"
buttonIcon="trash"
/>
</Flex.Item>
</Flex>
</>
);
};
const RadioSection = (props: {
title: string;
searchText: string;
onSearchText: Function;
channels: string[];
action: string;
buttonColor: string;
buttonIcon: string;
}) => {
const { act } = useBackend();
const {
title,
searchText,
onSearchText,
channels,
action,
buttonColor,
buttonIcon,
} = props;
return (
<Section title={title} fill scrollable>
<Input
fluid
value={searchText}
placeholder="Search for channels..."
onInput={(e, value: string) => onSearchText(value)}
/>
<Divider />
<Stack>
<Stack.Item width="100%">
{prepareSearch(channels, searchText).map((channel, i) => {
return (
<Button
fluid
key={i}
onClick={() =>
act(action, {
channel: channel,
})
}
>
<Flex varticalAlign="center">
<Flex.Item>{channel}</Flex.Item>
<Flex.Item grow />
<Flex.Item>
<Icon
name={buttonIcon}
backgroundColor={buttonColor}
size={1.5}
/>
</Flex.Item>
</Flex>
</Button>
);
})}
</Stack.Item>
</Stack>
</Section>
);
};
@@ -1,12 +1,34 @@
import { useState } from 'react';
import { useBackend } from 'tgui/backend';
import { Button, Flex, Image, Section, Stack } from 'tgui/components';
import {
Button,
Divider,
Flex,
Image,
Input,
Section,
Stack,
} from 'tgui/components';
import { NoSpriteWarning } from '../components';
import { install2col } from '../constants';
import { prepareSearch } from '../functions';
import { Target, Upgrade } from '../types';
export const ModifyRobotUpgrades = (props: { target: Target }) => {
const { target } = props;
const [searchAddCompatibilityText, setSearchAddCompatibilityText] =
useState<string>('');
const [searchRemoveCompatibilityText, setSearchRemoveCompatibilityText] =
useState<string>('');
const [searchUtilityUpgradeText, setsearchUtilityUpgradeText] =
useState<string>('');
const [searchBasicUpgradeText, setSearchBasicUpgradeText] =
useState<string>('');
const [searchAdvancedUpgradeText, setSearchAdvancedUpgradeText] =
useState<string>('');
const [searchRestrictedUpgradeText, setSearchRestrictedUpgradeText] =
useState<string>('');
return (
<>
@@ -15,6 +37,8 @@ export const ModifyRobotUpgrades = (props: { target: Target }) => {
<Flex.Item width="30%" fill>
<UpgradeSection
title="Add Compatibility"
searchText={searchAddCompatibilityText}
onSearchText={setSearchAddCompatibilityText}
upgrades={target.whitelisted_upgrades}
action="add_compatibility"
/>
@@ -33,6 +57,8 @@ export const ModifyRobotUpgrades = (props: { target: Target }) => {
<Flex.Item width="30%" fill>
<UpgradeSection
title="Remove Compatibility"
searchText={searchRemoveCompatibilityText}
onSearchText={setSearchRemoveCompatibilityText}
upgrades={target.blacklisted_upgrades}
action="rem_compatibility"
/>
@@ -42,6 +68,8 @@ export const ModifyRobotUpgrades = (props: { target: Target }) => {
<Flex.Item width="25%" fill>
<UpgradeSection
title="Utility Upgrade"
searchText={searchUtilityUpgradeText}
onSearchText={setsearchUtilityUpgradeText}
upgrades={target.utility_upgrades}
action="add_upgrade"
/>
@@ -49,6 +77,8 @@ export const ModifyRobotUpgrades = (props: { target: Target }) => {
<Flex.Item width="25%" fill>
<UpgradeSection
title="Basic Upgrade"
searchText={searchBasicUpgradeText}
onSearchText={setSearchBasicUpgradeText}
upgrades={target.basic_upgrades}
action="add_upgrade"
/>
@@ -56,6 +86,8 @@ export const ModifyRobotUpgrades = (props: { target: Target }) => {
<Flex.Item width="25%" fill>
<UpgradeSection
title="Advanced Upgrade"
searchText={searchAdvancedUpgradeText}
onSearchText={setSearchAdvancedUpgradeText}
upgrades={target.advanced_upgrades}
action="add_upgrade"
/>
@@ -63,6 +95,8 @@ export const ModifyRobotUpgrades = (props: { target: Target }) => {
<Flex.Item width="25%" fill>
<UpgradeSection
title="Restricted Upgrade"
searchText={searchRestrictedUpgradeText}
onSearchText={setSearchRestrictedUpgradeText}
upgrades={target.restricted_upgrades}
action="add_upgrade"
/>
@@ -74,16 +108,25 @@ export const ModifyRobotUpgrades = (props: { target: Target }) => {
const UpgradeSection = (props: {
title: string;
searchText: string;
onSearchText: Function;
upgrades: Upgrade[];
action: string;
}) => {
const { act } = useBackend();
const { title, upgrades, action } = props;
const { title, searchText, onSearchText, upgrades, action } = props;
return (
<Section title={title} fill scrollable scrollableHorizontal>
<Input
fluid
value={searchText}
placeholder="Search for upgrades..."
onInput={(e, value: string) => onSearchText(value)}
/>
<Divider />
<Stack>
<Stack.Item width="100%">
{upgrades.map((upgrade, i) => {
{prepareSearch(upgrades, searchText).map((upgrade, i) => {
return (
<Button
fluid
@@ -0,0 +1,28 @@
import { filter } from 'common/collections';
import { flow } from 'common/fp';
import { createSearch } from 'common/string';
type SearchObject = string | { name: string };
export function prepareSearch<T extends SearchObject>(
objects: T[],
searchText: string = '',
): T[] {
const testSearch = createSearch(searchText, (object: T): string => {
if (typeof object === 'string') {
return object;
} else {
return object['name'];
}
});
return flow([
(objects: T[]) => {
// Optional search term
if (!searchText) {
return objects as any;
} else {
return filter(objects, testSearch) as any;
}
},
])(objects);
}
@@ -1,4 +1,4 @@
import { useState } from 'react';
import { useEffect, useState } from 'react';
import { useBackend } from 'tgui/backend';
import {
Box,
@@ -16,6 +16,7 @@ import { Window } from 'tgui/layouts';
import { ModifyRobotNoModule } from './ModifyRobotNoModule';
import { ModifyRobotModules } from './ModifyRobotTabs/ModifyRobotModules';
import { ModifyRobotPKA } from './ModifyRobotTabs/ModifyRobotPKA';
import { ModifyRobotRadio } from './ModifyRobotTabs/ModifyRobotRadio';
import { ModifyRobotUpgrades } from './ModifyRobotTabs/ModifyRobotUpgrades';
import { Data } from './types';
@@ -27,6 +28,12 @@ export const ModifyRobot = (props) => {
const [tab, setTab] = useState<number>(0);
const [robotName, setRobotName] = useState<string>(target ? target.name : '');
useEffect(() => {
if (target?.name) {
setRobotName(target.name);
}
}, [target?.name]);
const tabs: React.JSX.Element[] = [];
tabs[0] = (
@@ -38,7 +45,7 @@ export const ModifyRobot = (props) => {
);
tabs[1] = <ModifyRobotUpgrades target={target!} />;
tabs[2] = <ModifyRobotPKA target={target!} />;
tabs[3] = <Box />;
tabs[3] = <ModifyRobotRadio target={target!} />;
tabs[4] = <Box />;
tabs[5] = <Box />;
tabs[6] = <Box />;
@@ -69,7 +76,7 @@ export const ModifyRobot = (props) => {
}
/>
</Stack.Item>
{!!target && (
{!!target?.module && (
<>
<Stack.Item>
<Input
@@ -20,9 +20,10 @@ export type Target = {
crisis_override: BooleanLike;
active_restrictions: string[];
possible_restrictions: string[];
front: string | null;
side: string | null;
back: string | null;
front: string | undefined;
side: string | undefined;
side_alt: string | undefined;
back: string | undefined;
modules: Module[];
whitelisted_upgrades: Upgrade[];
blacklisted_upgrades: Upgrade[];
@@ -30,8 +31,11 @@ export type Target = {
basic_upgrades: Upgrade[];
advanced_upgrades: Upgrade[];
restricted_upgrades: Upgrade[];
radio_channels: string[];
availalbe_channels: string[];
pka:
| {
name: string;
modkits: {
name: string;
path: string;
@@ -49,7 +53,7 @@ export type Target = {
export type Upgrade = {
name: string;
path: string;
installed: number;
installed: number | undefined;
};
export type Source = {
@@ -58,4 +62,4 @@ export type Source = {
modules: Module[];
} | null;
export type Module = { item: string; ref: string; icon: string; desc: string };
export type Module = { name: string; ref: string; icon: string; desc: string };