2021-09-10 03:38:05 +02:00
import React , { useState } from "react" ;
import { Sleeve } from "../Sleeve" ;
import { IPlayer } from "../../IPlayer" ;
import { SleeveTaskType } from "../SleeveTaskTypesEnum" ;
import { Crimes } from "../../../Crime/Crimes" ;
import { LocationName } from "../../../Locations/data/LocationNames" ;
import { CityName } from "../../../Locations/data/CityNames" ;
import { Factions } from "../../../Faction/Factions" ;
import { FactionWorkType } from "../../../Faction/FactionWorkTypeEnum" ;
2021-09-27 02:55:38 +02:00
import Select , { SelectChangeEvent } from "@mui/material/Select" ;
import MenuItem from "@mui/material/MenuItem" ;
2022-03-19 09:09:59 +01:00
import { FactionNames } from "../../../Faction/data/FactionNames" ;
2021-09-10 03:38:05 +02:00
const universitySelectorOptions : string [ ] = [
"Study Computer Science" ,
"Data Structures" ,
"Networks" ,
"Algorithms" ,
"Management" ,
"Leadership" ,
] ;
const gymSelectorOptions : string [ ] = [ "Train Strength" , "Train Defense" , "Train Dexterity" , "Train Agility" ] ;
2022-04-14 17:40:59 +02:00
const bladeburnerSelectorOptions : string [ ] = [ "Field Analysis" , "Recruitment" , "Diplomacy" , "Infiltrate synthoids" , "Support main sleeve" , "Take on Contracts" ] ;
2021-09-10 03:38:05 +02:00
interface IProps {
sleeve : Sleeve ;
player : IPlayer ;
setABC : ( abc : string [ ] ) = > void ;
}
interface ITaskDetails {
first : string [ ] ;
second : ( s1 : string ) = > string [ ] ;
}
function possibleJobs ( player : IPlayer , sleeve : Sleeve ) : string [ ] {
// Array of all companies that other sleeves are working at
const forbiddenCompanies = [ ] ;
for ( const otherSleeve of player . sleeves ) {
if ( sleeve === otherSleeve ) {
continue ;
}
if ( otherSleeve . currentTask === SleeveTaskType . Company ) {
forbiddenCompanies . push ( otherSleeve . currentTaskLocation ) ;
}
}
2021-09-10 04:57:37 +02:00
const allJobs : string [ ] = Object . keys ( player . jobs ) ;
2021-09-10 03:38:05 +02:00
for ( let i = 0 ; i < allJobs . length ; ++ i ) {
if ( ! forbiddenCompanies . includes ( allJobs [ i ] ) ) {
allJobs [ i ] ;
}
}
return allJobs ;
}
function possibleFactions ( player : IPlayer , sleeve : Sleeve ) : string [ ] {
// Array of all factions that other sleeves are working for
2022-03-19 09:09:59 +01:00
const forbiddenFactions = [ FactionNames . Bladeburners as string ] ;
2021-09-11 07:54:19 +02:00
if ( player . gang ) {
forbiddenFactions . push ( player . gang . facName ) ;
}
2021-09-10 03:38:05 +02:00
for ( const otherSleeve of player . sleeves ) {
if ( sleeve === otherSleeve ) {
continue ;
}
if ( otherSleeve . currentTask === SleeveTaskType . Faction ) {
forbiddenFactions . push ( otherSleeve . currentTaskLocation ) ;
}
}
const factions = [ ] ;
for ( const fac of player . factions ) {
if ( ! forbiddenFactions . includes ( fac ) ) {
factions . push ( fac ) ;
}
}
2022-04-07 01:30:08 +02:00
return factions . filter ( ( faction ) = > {
2022-02-07 12:48:28 +01:00
const facInfo = Factions [ faction ] . getInfo ( ) ;
2022-04-07 01:30:08 +02:00
return facInfo . offerHackingWork || facInfo . offerFieldWork || facInfo . offerSecurityWork ;
2022-02-07 12:48:28 +01:00
} ) ;
2021-09-10 03:38:05 +02:00
}
2022-04-14 17:40:59 +02:00
function possibleContracts ( player : IPlayer , sleeve : Sleeve ) : string [ ] {
const bb = player . bladeburner ;
if ( bb === null ) {
return [ "------" ] ;
}
let contracts = bb . getContractNamesNetscriptFn ( ) ;
for ( const otherSleeve of player . sleeves ) {
if ( sleeve === otherSleeve ) {
continue ;
}
2022-04-14 17:57:01 +02:00
if ( otherSleeve . currentTask === SleeveTaskType . Bladeburner
2022-04-14 17:40:59 +02:00
&& otherSleeve . bbAction == 'Take on Contracts' ) {
contracts = contracts . filter ( x = > x != otherSleeve . bbContract ) ;
}
}
if ( contracts . length === 0 ) {
return [ "------" ] ;
}
return contracts ;
}
2021-09-10 03:38:05 +02:00
const tasks : {
[ key : string ] : undefined | ( ( player : IPlayer , sleeve : Sleeve ) = > ITaskDetails ) ;
[ "------" ] : ( player : IPlayer , sleeve : Sleeve ) = > ITaskDetails ;
[ "Work for Company" ] : ( player : IPlayer , sleeve : Sleeve ) = > ITaskDetails ;
[ "Work for Faction" ] : ( player : IPlayer , sleeve : Sleeve ) = > ITaskDetails ;
[ "Commit Crime" ] : ( player : IPlayer , sleeve : Sleeve ) = > ITaskDetails ;
[ "Take University Course" ] : ( player : IPlayer , sleeve : Sleeve ) = > ITaskDetails ;
[ "Workout at Gym" ] : ( player : IPlayer , sleeve : Sleeve ) = > ITaskDetails ;
2022-04-14 17:40:59 +02:00
[ "Perform Bladeburner Actions" ] : ( player : IPlayer , sleeve : Sleeve ) = > ITaskDetails ;
2021-09-10 03:38:05 +02:00
[ "Shock Recovery" ] : ( player : IPlayer , sleeve : Sleeve ) = > ITaskDetails ;
[ "Synchronize" ] : ( player : IPlayer , sleeve : Sleeve ) = > ITaskDetails ;
} = {
2021-09-10 04:57:37 +02:00
"------" : ( ) : ITaskDetails = > {
2021-09-10 03:38:05 +02:00
return { first : [ "------" ] , second : ( ) = > [ "------" ] } ;
} ,
"Work for Company" : ( player : IPlayer , sleeve : Sleeve ) : ITaskDetails = > {
let jobs = possibleJobs ( player , sleeve ) ;
if ( jobs . length === 0 ) jobs = [ "------" ] ;
return { first : jobs , second : ( ) = > [ "------" ] } ;
} ,
"Work for Faction" : ( player : IPlayer , sleeve : Sleeve ) : ITaskDetails = > {
let factions = possibleFactions ( player , sleeve ) ;
if ( factions . length === 0 ) factions = [ "------" ] ;
return {
first : factions ,
second : ( s1 : string ) = > {
const faction = Factions [ s1 ] ;
const facInfo = faction . getInfo ( ) ;
const options : string [ ] = [ ] ;
if ( facInfo . offerHackingWork ) {
options . push ( "Hacking Contracts" ) ;
}
if ( facInfo . offerFieldWork ) {
options . push ( "Field Work" ) ;
}
if ( facInfo . offerSecurityWork ) {
options . push ( "Security Work" ) ;
}
return options ;
} ,
} ;
} ,
2021-09-10 04:57:37 +02:00
"Commit Crime" : ( ) : ITaskDetails = > {
2021-10-18 21:01:06 +02:00
return { first : Object.values ( Crimes ) . map ( ( crime ) = > crime . name ) , second : ( ) = > [ "------" ] } ;
2021-09-10 03:38:05 +02:00
} ,
"Take University Course" : ( player : IPlayer , sleeve : Sleeve ) : ITaskDetails = > {
let universities : string [ ] = [ ] ;
switch ( sleeve . city ) {
case CityName . Aevum :
universities = [ LocationName . AevumSummitUniversity ] ;
break ;
case CityName . Sector12 :
universities = [ LocationName . Sector12RothmanUniversity ] ;
break ;
case CityName . Volhaven :
universities = [ LocationName . VolhavenZBInstituteOfTechnology ] ;
break ;
default :
universities = [ "No university available in city!" ] ;
break ;
}
return { first : universitySelectorOptions , second : ( ) = > universities } ;
} ,
"Workout at Gym" : ( player : IPlayer , sleeve : Sleeve ) : ITaskDetails = > {
let gyms : string [ ] = [ ] ;
switch ( sleeve . city ) {
case CityName . Aevum :
gyms = [ LocationName . AevumCrushFitnessGym , LocationName . AevumSnapFitnessGym ] ;
break ;
case CityName . Sector12 :
gyms = [ LocationName . Sector12IronGym , LocationName . Sector12PowerhouseGym ] ;
break ;
case CityName . Volhaven :
gyms = [ LocationName . VolhavenMilleniumFitnessGym ] ;
break ;
default :
gyms = [ "No gym available in city!" ] ;
break ;
}
return { first : gymSelectorOptions , second : ( ) = > gyms } ;
} ,
2022-04-14 17:40:59 +02:00
"Perform Bladeburner Actions" : ( player : IPlayer , sleeve : Sleeve ) : ITaskDetails = > {
2022-04-14 17:57:01 +02:00
return {
first : bladeburnerSelectorOptions ,
2022-04-14 17:40:59 +02:00
second : ( s1 : string ) = > {
if ( s1 === "Take on Contracts" ) {
return possibleContracts ( player , sleeve ) ;
} else {
return [ "------" ] ;
}
} } ;
} ,
2021-09-10 04:57:37 +02:00
"Shock Recovery" : ( ) : ITaskDetails = > {
2021-09-10 03:38:05 +02:00
return { first : [ "------" ] , second : ( ) = > [ "------" ] } ;
} ,
2021-09-10 04:57:37 +02:00
Synchronize : ( ) : ITaskDetails = > {
2021-09-10 03:38:05 +02:00
return { first : [ "------" ] , second : ( ) = > [ "------" ] } ;
} ,
} ;
const canDo : {
[ key : string ] : undefined | ( ( player : IPlayer , sleeve : Sleeve ) = > boolean ) ;
[ "------" ] : ( player : IPlayer , sleeve : Sleeve ) = > boolean ;
[ "Work for Company" ] : ( player : IPlayer , sleeve : Sleeve ) = > boolean ;
[ "Work for Faction" ] : ( player : IPlayer , sleeve : Sleeve ) = > boolean ;
[ "Commit Crime" ] : ( player : IPlayer , sleeve : Sleeve ) = > boolean ;
[ "Take University Course" ] : ( player : IPlayer , sleeve : Sleeve ) = > boolean ;
[ "Workout at Gym" ] : ( player : IPlayer , sleeve : Sleeve ) = > boolean ;
2022-04-14 17:40:59 +02:00
[ "Perform Bladeburner Actions" ] : ( player : IPlayer , sleeve : Sleeve ) = > boolean ;
2021-09-10 03:38:05 +02:00
[ "Shock Recovery" ] : ( player : IPlayer , sleeve : Sleeve ) = > boolean ;
[ "Synchronize" ] : ( player : IPlayer , sleeve : Sleeve ) = > boolean ;
} = {
2021-09-10 04:57:37 +02:00
"------" : ( ) = > true ,
"Work for Company" : ( player : IPlayer , sleeve : Sleeve ) = > possibleJobs ( player , sleeve ) . length > 0 ,
"Work for Faction" : ( player : IPlayer , sleeve : Sleeve ) = > possibleFactions ( player , sleeve ) . length > 0 ,
"Commit Crime" : ( ) = > true ,
2021-09-22 18:56:55 +02:00
"Take University Course" : ( player : IPlayer , sleeve : Sleeve ) = >
[ CityName . Aevum , CityName . Sector12 , CityName . Volhaven ] . includes ( sleeve . city ) ,
"Workout at Gym" : ( player : IPlayer , sleeve : Sleeve ) = >
[ CityName . Aevum , CityName . Sector12 , CityName . Volhaven ] . includes ( sleeve . city ) ,
2022-04-14 17:40:59 +02:00
"Perform Bladeburner Actions" : ( player : IPlayer , sleeve : Sleeve ) = > player . inBladeburner ( ) ,
2021-09-10 04:57:37 +02:00
"Shock Recovery" : ( player : IPlayer , sleeve : Sleeve ) = > sleeve . shock < 100 ,
Synchronize : ( player : IPlayer , sleeve : Sleeve ) = > sleeve . sync < 100 ,
2021-09-10 03:38:05 +02:00
} ;
function getABC ( sleeve : Sleeve ) : [ string , string , string ] {
switch ( sleeve . currentTask ) {
case SleeveTaskType . Idle :
return [ "------" , "------" , "------" ] ;
case SleeveTaskType . Company :
return [ "Work for Company" , sleeve . currentTaskLocation , "------" ] ;
2021-09-10 04:57:37 +02:00
case SleeveTaskType . Faction : {
2021-09-10 03:38:05 +02:00
let workType = "" ;
switch ( sleeve . factionWorkType ) {
case FactionWorkType . Hacking :
workType = "Hacking Contracts" ;
break ;
case FactionWorkType . Field :
workType = "Field Work" ;
break ;
case FactionWorkType . Security :
workType = "Security Work" ;
break ;
}
return [ "Work for Faction" , sleeve . currentTaskLocation , workType ] ;
2021-09-10 04:57:37 +02:00
}
2021-09-10 03:38:05 +02:00
case SleeveTaskType . Crime :
return [ "Commit Crime" , sleeve . crimeType , "------" ] ;
case SleeveTaskType . Class :
return [ "Take University Course" , sleeve . className , sleeve . currentTaskLocation ] ;
case SleeveTaskType . Gym :
return [ "Workout at Gym" , sleeve . gymStatType , sleeve . currentTaskLocation ] ;
2022-04-14 17:40:59 +02:00
case SleeveTaskType . Bladeburner :
return [ "Perform Bladeburner Actions" , sleeve . bbAction , sleeve . bbContract ] ;
2021-09-10 03:38:05 +02:00
case SleeveTaskType . Recovery :
return [ "Shock Recovery" , "------" , "------" ] ;
case SleeveTaskType . Synchro :
return [ "Synchronize" , "------" , "------" ] ;
}
}
export function TaskSelector ( props : IProps ) : React . ReactElement {
const abc = getABC ( props . sleeve ) ;
const [ s0 , setS0 ] = useState ( abc [ 0 ] ) ;
const [ s1 , setS1 ] = useState ( abc [ 1 ] ) ;
const [ s2 , setS2 ] = useState ( abc [ 2 ] ) ;
2021-09-22 18:56:55 +02:00
const validActions = Object . keys ( canDo ) . filter ( ( k ) = >
( canDo [ k ] as ( player : IPlayer , sleeve : Sleeve ) = > boolean ) ( props . player , props . sleeve ) ,
2021-09-10 03:38:05 +02:00
) ;
const detailsF = tasks [ s0 ] ;
if ( detailsF === undefined ) throw new Error ( ` No function for task ' ${ s0 } ' ` ) ;
const details = detailsF ( props . player , props . sleeve ) ;
const details2 = details . second ( s1 ) ;
2021-09-11 07:54:19 +02:00
if ( details . first . length > 0 && ! details . first . includes ( s1 ) ) {
setS1 ( details . first [ 0 ] ) ;
props . setABC ( [ s0 , details . first [ 0 ] , s2 ] ) ;
}
if ( details2 . length > 0 && ! details2 . includes ( s2 ) ) {
setS2 ( details2 [ 0 ] ) ;
props . setABC ( [ s0 , s1 , details2 [ 0 ] ] ) ;
}
2021-09-27 02:55:38 +02:00
function onS0Change ( event : SelectChangeEvent < string > ) : void {
2021-09-10 03:38:05 +02:00
const n = event . target . value ;
const detailsF = tasks [ n ] ;
if ( detailsF === undefined ) throw new Error ( ` No function for task ' ${ s0 } ' ` ) ;
const details = detailsF ( props . player , props . sleeve ) ;
const details2 = details . second ( details . first [ 0 ] ) ;
setS2 ( details2 [ 0 ] ) ;
setS1 ( details . first [ 0 ] ) ;
setS0 ( n ) ;
props . setABC ( [ n , details . first [ 0 ] , details2 [ 0 ] ] ) ;
}
2021-09-27 02:55:38 +02:00
function onS1Change ( event : SelectChangeEvent < string > ) : void {
2021-09-10 03:38:05 +02:00
setS1 ( event . target . value ) ;
props . setABC ( [ s0 , event . target . value , s2 ] ) ;
}
2021-09-27 02:55:38 +02:00
function onS2Change ( event : SelectChangeEvent < string > ) : void {
2021-09-10 03:38:05 +02:00
setS2 ( event . target . value ) ;
props . setABC ( [ s0 , s1 , event . target . value ] ) ;
}
return (
< >
2022-04-07 01:30:08 +02:00
< Select onChange = { onS0Change } value = { s0 } sx = { { width : "100%" } } >
2021-09-10 03:38:05 +02:00
{ validActions . map ( ( task ) = > (
2021-09-27 02:55:38 +02:00
< MenuItem key = { task } value = { task } >
2021-09-10 03:38:05 +02:00
{ task }
2021-09-27 02:55:38 +02:00
< / MenuItem >
2021-09-10 03:38:05 +02:00
) ) }
2021-09-27 02:55:38 +02:00
< / Select >
2021-09-10 03:38:05 +02:00
{ ! ( details . first . length === 1 && details . first [ 0 ] === "------" ) && (
2021-09-27 02:55:38 +02:00
< >
2022-04-07 01:30:08 +02:00
< Select onChange = { onS1Change } value = { s1 } sx = { { width : "100%" } } >
2021-09-27 02:55:38 +02:00
{ details . first . map ( ( detail ) = > (
< MenuItem key = { detail } value = { detail } >
{ detail }
< / MenuItem >
) ) }
< / Select >
< / >
2021-09-10 03:38:05 +02:00
) }
{ ! ( details2 . length === 1 && details2 [ 0 ] === "------" ) && (
2021-09-27 02:55:38 +02:00
< >
2022-04-07 01:30:08 +02:00
< Select onChange = { onS2Change } value = { s2 } sx = { { width : "100%" } } >
2021-09-27 02:55:38 +02:00
{ details2 . map ( ( detail ) = > (
< MenuItem key = { detail } value = { detail } >
{ detail }
< / MenuItem >
) ) }
< / Select >
< / >
2021-09-10 03:38:05 +02:00
) }
< / >
) ;
}