From 0b71a83cfea54ef387d215aecb32a6cfd73db540 Mon Sep 17 00:00:00 2001 From: Martin Fournier Date: Tue, 21 Dec 2021 06:38:40 -0500 Subject: [PATCH 1/5] Fix blade console input visibility on scroll Before this, when scrolling up the input would be hidden. --- src/Bladeburner/ui/Console.tsx | 93 ++++++++++++++++++++-------------- 1 file changed, 56 insertions(+), 37 deletions(-) diff --git a/src/Bladeburner/ui/Console.tsx b/src/Bladeburner/ui/Console.tsx index 48ca32bc1..7cbc8ec36 100644 --- a/src/Bladeburner/ui/Console.tsx +++ b/src/Bladeburner/ui/Console.tsx @@ -54,7 +54,6 @@ interface IProps { export function Console(props: IProps): React.ReactElement { const classes = useStyles(); - const scrollHook = useRef(null); const [command, setCommand] = useState(""); const setRerender = useState(false)[1]; @@ -64,22 +63,14 @@ export function Console(props: IProps): React.ReactElement { const [consoleHistoryIndex, setConsoleHistoryIndex] = useState(props.bladeburner.consoleHistory.length); - // TODO: Figure out how to actually make the scrolling work correctly. - function scrollToBottom(): void { - if (!scrollHook.current) return; - scrollHook.current.scrollTop = scrollHook.current.scrollHeight; - } - function rerender(): void { setRerender((old) => !old); } useEffect(() => { const id = setInterval(rerender, 1000); - const id2 = setInterval(scrollToBottom, 100); return () => { clearInterval(id); - clearInterval(id2); }; }, []); @@ -139,34 +130,62 @@ export function Console(props: IProps): React.ReactElement { } return ( - - - - {props.bladeburner.consoleLogs.map((log: any, i: number) => ( - - ))} - - - - ), - spellCheck: false, - }} - /> - -
+ + + + + -
+ + + + ), + spellCheck: false, + }} + /> + + ); +} + +interface ILogProps { + entries: string[]; +} + +function Logs({entries}: ILogProps): React.ReactElement { + const scrollHook = useRef(null); + + // TODO: Text gets shifted up as new entries appear, if the user scrolled up it should attempt to keep the text focused + function scrollToBottom(): void { + if (!scrollHook.current) return; + scrollHook.current.scrollTop = scrollHook.current.scrollHeight; + } + + useEffect(() => { + scrollToBottom(); + }, [entries]); + + return ( + + {entries && entries.map((log: any, i: number) => ( + + ))} + ); } From 1427993a25d0b048b547c2a8e02f79473e8c4c31 Mon Sep 17 00:00:00 2001 From: Martin Fournier Date: Tue, 21 Dec 2021 07:35:20 -0500 Subject: [PATCH 2/5] Fix #1901: Fix blade console command history Up or down would not properly update the visible input value --- src/Bladeburner/ui/Console.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Bladeburner/ui/Console.tsx b/src/Bladeburner/ui/Console.tsx index 7cbc8ec36..671345b1a 100644 --- a/src/Bladeburner/ui/Console.tsx +++ b/src/Bladeburner/ui/Console.tsx @@ -104,6 +104,7 @@ export function Console(props: IProps): React.ReactElement { setConsoleHistoryIndex(i); const prevCommand = consoleHistory[i]; event.currentTarget.value = prevCommand; + setCommand(prevCommand); } if (event.keyCode === 40) { @@ -125,6 +126,7 @@ export function Console(props: IProps): React.ReactElement { setConsoleHistoryIndex(consoleHistoryIndex + 1); const prevCommand = consoleHistory[consoleHistoryIndex + 1]; event.currentTarget.value = prevCommand; + setCommand(prevCommand); } } } From f2ccc63b2d91fa1e15212f4b4f036185e2fc6f4f Mon Sep 17 00:00:00 2001 From: Martin Fournier Date: Tue, 21 Dec 2021 06:53:24 -0500 Subject: [PATCH 3/5] Fix #1915: Check blade console skill max level Prevents you from leveling up a skill past its max level. --- src/Bladeburner/Bladeburner.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Bladeburner/Bladeburner.tsx b/src/Bladeburner/Bladeburner.tsx index 5b5112516..06396301a 100644 --- a/src/Bladeburner/Bladeburner.tsx +++ b/src/Bladeburner/Bladeburner.tsx @@ -502,6 +502,7 @@ export class Bladeburner implements IBladeburner { const skill = Skills[skillName]; if (skill == null || !(skill instanceof Skill)) { this.postToConsole("Invalid skill name (Note that it is case-sensitive): " + skillName); + break; } if (args[1].toLowerCase() === "list") { let level = 0; @@ -515,7 +516,11 @@ export class Bladeburner implements IBladeburner { currentLevel = this.skills[skillName]; } const pointCost = skill.calculateCost(currentLevel); - if (this.skillPoints >= pointCost) { + if (skill.maxLvl !== 0 && currentLevel >= skill.maxLvl) { + this.postToConsole( + `This skill ${skill.name} is already at max level (${currentLevel}/${skill.maxLvl}).`, + ); + } else if (this.skillPoints >= pointCost) { this.skillPoints -= pointCost; this.upgradeSkill(skill); this.log(skill.name + " upgraded to Level " + this.skills[skillName]); From dbe36fd6b74507b2033cccacc46f9d3c28cb867f Mon Sep 17 00:00:00 2001 From: Martin Fournier Date: Tue, 21 Dec 2021 07:03:59 -0500 Subject: [PATCH 4/5] Fix #1916: Check blade console blackops rank This prevents the player from starting a blackops without having the rank requirements --- src/Bladeburner/Bladeburner.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Bladeburner/Bladeburner.tsx b/src/Bladeburner/Bladeburner.tsx index 06396301a..7136e7b9a 100644 --- a/src/Bladeburner/Bladeburner.tsx +++ b/src/Bladeburner/Bladeburner.tsx @@ -164,6 +164,12 @@ export class Bladeburner implements IBladeburner { } const action = this.getActionObject(actionId); + if (!(action instanceof BlackOperation)) throw new Error(`Action should be BlackOperation but isn't`); + if (action.reqdRank > (player.bladeburner?.rank ?? 0)) { + this.resetAction(); + this.log("Error: Tried to start a Black Operation without the rank requirement"); + break; + } if (action == null) { throw new Error("Failed to get BlackOperation object for: " + actionId.name); } From 2d269c7a4e10cc2b6c64a0a12ef480353f983b1f Mon Sep 17 00:00:00 2001 From: Martin Fournier Date: Tue, 21 Dec 2021 10:13:12 -0500 Subject: [PATCH 5/5] Fix #2018: Blade console check blackops order Prevents you from running blackops if you have not completed the preceeding one. --- src/Bladeburner/Bladeburner.tsx | 104 ++++++++++++++++---------------- 1 file changed, 51 insertions(+), 53 deletions(-) diff --git a/src/Bladeburner/Bladeburner.tsx b/src/Bladeburner/Bladeburner.tsx index 7136e7b9a..d3d668b8e 100644 --- a/src/Bladeburner/Bladeburner.tsx +++ b/src/Bladeburner/Bladeburner.tsx @@ -34,6 +34,12 @@ import { getTimestamp } from "../utils/helpers/getTimestamp"; import { joinFaction } from "../Faction/FactionHelpers"; import { WorkerScript } from "../Netscript/WorkerScript"; +interface BlackOpsAttempt { + error?: string; + isAvailable?: boolean; + action?: BlackOperation; +} + export class Bladeburner implements IBladeburner { numHosp = 0; moneyLost = 0; @@ -113,6 +119,44 @@ export class Bladeburner implements IBladeburner { return Math.min(1, this.stamina / (0.5 * this.maxStamina)); } + + canAttemptBlackOp(actionId: IActionIdentifier): BlackOpsAttempt { + // Safety measure - don't repeat BlackOps that are already done + if (this.blackops[actionId.name] != null) { + return { error: "Tried to start a Black Operation that had already been completed" } + } + + const action = this.getActionObject(actionId); + if (!(action instanceof BlackOperation)) throw new Error(`Action should be BlackOperation but isn't`); + if (action == null) throw new Error("Failed to get BlackOperation object for: " + actionId.name); + + if (action.reqdRank > this.rank) { + return { error: "Tried to start a Black Operation without the rank requirement" }; + } + + // Can't start a BlackOp if you haven't done the one before it + const blackops = []; + for (const nm in BlackOperations) { + if (BlackOperations.hasOwnProperty(nm)) { + blackops.push(nm); + } + } + blackops.sort(function (a, b) { + return BlackOperations[a].reqdRank - BlackOperations[b].reqdRank; // Sort black ops in intended order + }); + + const i = blackops.indexOf(actionId.name); + if (i === -1) { + return { error: `Invalid Black Op: '${name}'` }; + } + + if (i > 0 && this.blackops[blackops[i - 1]] == null) { + return { error: `Preceding Black Op must be completed before starting '${actionId.name}'.` } + } + + return { isAvailable: true, action } + } + startAction(player: IPlayer, actionId: IActionIdentifier): void { if (actionId == null) return; this.action = actionId; @@ -156,24 +200,13 @@ export class Bladeburner implements IBladeburner { case ActionTypes["BlackOp"]: case ActionTypes["BlackOperation"]: { try { - // Safety measure - don't repeat BlackOps that are already done - if (this.blackops[actionId.name] != null) { + const testBlackOp = this.canAttemptBlackOp(actionId); + if (!testBlackOp.isAvailable) { this.resetAction(); - this.log("Error: Tried to start a Black Operation that had already been completed"); + this.log(`Error: ${testBlackOp.error}`); break; } - - const action = this.getActionObject(actionId); - if (!(action instanceof BlackOperation)) throw new Error(`Action should be BlackOperation but isn't`); - if (action.reqdRank > (player.bladeburner?.rank ?? 0)) { - this.resetAction(); - this.log("Error: Tried to start a Black Operation without the rank requirement"); - break; - } - if (action == null) { - throw new Error("Failed to get BlackOperation object for: " + actionId.name); - } - this.actionTimeToComplete = action.getActionTime(this); + this.actionTimeToComplete = testBlackOp.action.getActionTime(this); } catch (e: any) { exceptionAlert(e); } @@ -2043,44 +2076,9 @@ export class Bladeburner implements IBladeburner { // Special logic for Black Ops if (actionId.type === ActionTypes["BlackOp"]) { - // Can't start a BlackOp if you don't have the required rank - const action = this.getActionObject(actionId); - if (action == null) throw new Error(`Action not found ${actionId.type}, ${actionId.name}`); - if (!(action instanceof BlackOperation)) throw new Error(`Action should be BlackOperation but isn't`); - //const blackOp = (action as BlackOperation); - if (action.reqdRank > this.rank) { - workerScript.log("bladeburner.startAction", () => `Insufficient rank to start Black Op '${actionId.name}'.`); - return false; - } - - // Can't start a BlackOp if its already been done - if (this.blackops[actionId.name] != null) { - workerScript.log("bladeburner.startAction", () => `Black Op ${actionId.name} has already been completed.`); - return false; - } - - // Can't start a BlackOp if you haven't done the one before it - const blackops = []; - for (const nm in BlackOperations) { - if (BlackOperations.hasOwnProperty(nm)) { - blackops.push(nm); - } - } - blackops.sort(function (a, b) { - return BlackOperations[a].reqdRank - BlackOperations[b].reqdRank; // Sort black ops in intended order - }); - - const i = blackops.indexOf(actionId.name); - if (i === -1) { - workerScript.log("bladeburner.startAction", () => `Invalid Black Op: '${name}'`); - return false; - } - - if (i > 0 && this.blackops[blackops[i - 1]] == null) { - workerScript.log( - "bladeburner.startAction", - () => `Preceding Black Op must be completed before starting '${actionId.name}'.`, - ); + const canRunOp = this.canAttemptBlackOp(actionId); + if (!canRunOp.isAvailable) { + workerScript.log("bladeburner.startAction", () => canRunOp.error); return false; } }