mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-25 07:32:27 +01:00
Fix relevant linter errors and run formatter
This commit is contained in:
parent
b29c8e0039
commit
02b07bb332
@ -13,7 +13,6 @@ import { CorporationUnlockUpgrade } from "./data/CorporationUnlockUpgrades";
|
|||||||
import { CorporationUpgrade } from "./data/CorporationUpgrades";
|
import { CorporationUpgrade } from "./data/CorporationUpgrades";
|
||||||
import { Cities } from "../Locations/Cities";
|
import { Cities } from "../Locations/Cities";
|
||||||
import { EmployeePositions } from "./EmployeePositions";
|
import { EmployeePositions } from "./EmployeePositions";
|
||||||
import { Employee } from "./Employee";
|
|
||||||
import { ResearchMap } from "./ResearchMap";
|
import { ResearchMap } from "./ResearchMap";
|
||||||
import { isRelevantMaterial } from "./ui/Helpers";
|
import { isRelevantMaterial } from "./ui/Helpers";
|
||||||
|
|
||||||
@ -304,7 +303,7 @@ export function BuyBackShares(corporation: ICorporation, player: IPlayer, numSha
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function AssignJob(office: OfficeSpace, employeeName: string, job: string): void {
|
export function AssignJob(office: OfficeSpace, employeeName: string, job: string): void {
|
||||||
const employee = office.employees.find(e => e.name === employeeName);
|
const employee = office.employees.find((e) => e.name === employeeName);
|
||||||
|
|
||||||
if (!employee) throw new Error(`Could not find employee '${name}'.`);
|
if (!employee) throw new Error(`Could not find employee '${name}'.`);
|
||||||
if (!Object.values(EmployeePositions).includes(job)) throw new Error(`'${job}' is not a valid job.`);
|
if (!Object.values(EmployeePositions).includes(job)) throw new Error(`'${job}' is not a valid job.`);
|
||||||
@ -334,9 +333,13 @@ export function UpgradeOfficeSize(corp: ICorporation, office: OfficeSpace, size:
|
|||||||
|
|
||||||
export function BuyCoffee(corp: ICorporation, office: OfficeSpace): boolean {
|
export function BuyCoffee(corp: ICorporation, office: OfficeSpace): boolean {
|
||||||
const cost = office.getCoffeeCost();
|
const cost = office.getCoffeeCost();
|
||||||
if (corp.funds < cost) { return false; }
|
if (corp.funds < cost) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!office.setCoffee()) { return false; }
|
if (!office.setCoffee()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
corp.funds -= cost;
|
corp.funds -= cost;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -345,9 +348,13 @@ export function BuyCoffee(corp: ICorporation, office: OfficeSpace): boolean {
|
|||||||
export function ThrowParty(corp: ICorporation, office: OfficeSpace, costPerEmployee: number): number {
|
export function ThrowParty(corp: ICorporation, office: OfficeSpace, costPerEmployee: number): number {
|
||||||
const mult = 1 + costPerEmployee / 10e6;
|
const mult = 1 + costPerEmployee / 10e6;
|
||||||
const cost = costPerEmployee * office.employees.length;
|
const cost = costPerEmployee * office.employees.length;
|
||||||
if (corp.funds < cost) { return 0; }
|
if (corp.funds < cost) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!office.setParty(mult)) { return 0; }
|
if (!office.setParty(mult)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
corp.funds -= cost;
|
corp.funds -= cost;
|
||||||
|
|
||||||
return mult;
|
return mult;
|
||||||
|
@ -3,7 +3,6 @@ import { getRandomInt } from "../utils/helpers/getRandomInt";
|
|||||||
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../utils/JSONReviver";
|
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../utils/JSONReviver";
|
||||||
import { EmployeePositions } from "./EmployeePositions";
|
import { EmployeePositions } from "./EmployeePositions";
|
||||||
import { ICorporation } from "./ICorporation";
|
import { ICorporation } from "./ICorporation";
|
||||||
import { OfficeSpace } from "./OfficeSpace";
|
|
||||||
import { IIndustry } from "./IIndustry";
|
import { IIndustry } from "./IIndustry";
|
||||||
|
|
||||||
interface IParams {
|
interface IParams {
|
||||||
@ -57,7 +56,7 @@ export class Employee {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Returns the amount the employee needs to be paid
|
//Returns the amount the employee needs to be paid
|
||||||
process(marketCycles = 1, office: OfficeSpace): number {
|
process(marketCycles = 1): number {
|
||||||
const gain = 0.003 * marketCycles;
|
const gain = 0.003 * marketCycles;
|
||||||
const det = gain * Math.random();
|
const det = gain * Math.random();
|
||||||
this.exp += gain;
|
this.exp += gain;
|
||||||
|
@ -78,7 +78,9 @@ export class OfficeSpace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update employee jobs and job counts
|
// Update employee jobs and job counts
|
||||||
for (const employee of this.employees) { employee.pos = employee.nextPos; }
|
for (const employee of this.employees) {
|
||||||
|
employee.pos = employee.nextPos;
|
||||||
|
}
|
||||||
this.calculateTotalEmployees();
|
this.calculateTotalEmployees();
|
||||||
this.calculateNextEmployees();
|
this.calculateNextEmployees();
|
||||||
|
|
||||||
@ -113,13 +115,13 @@ export class OfficeSpace {
|
|||||||
|
|
||||||
let totalSalary = 0;
|
let totalSalary = 0;
|
||||||
for (const employee of this.employees) {
|
for (const employee of this.employees) {
|
||||||
const salary = employee.process(marketCycles, this);
|
const salary = employee.process(marketCycles);
|
||||||
totalSalary += salary;
|
totalSalary += salary;
|
||||||
|
|
||||||
if (this.autoCoffee) {
|
if (this.autoCoffee) {
|
||||||
employee.ene = this.maxEne;
|
employee.ene = this.maxEne;
|
||||||
} else if (this.coffeeMult > 1) {
|
} else if (this.coffeeMult > 1) {
|
||||||
const mult = 1 + (this.coffeeMult - 1) * this.employees.length / this.coffeeEmployees;
|
const mult = 1 + ((this.coffeeMult - 1) * this.employees.length) / this.coffeeEmployees;
|
||||||
employee.ene *= mult;
|
employee.ene *= mult;
|
||||||
} else {
|
} else {
|
||||||
employee.ene *= perfMult;
|
employee.ene *= perfMult;
|
||||||
@ -129,7 +131,7 @@ export class OfficeSpace {
|
|||||||
employee.mor = this.maxMor;
|
employee.mor = this.maxMor;
|
||||||
employee.hap = this.maxHap;
|
employee.hap = this.maxHap;
|
||||||
} else if (this.partyMult > 1) {
|
} else if (this.partyMult > 1) {
|
||||||
const mult = 1 + (this.partyMult - 1) * this.employees.length / this.partyEmployees;
|
const mult = 1 + ((this.partyMult - 1) * this.employees.length) / this.partyEmployees;
|
||||||
employee.mor *= mult;
|
employee.mor *= mult;
|
||||||
employee.hap *= mult;
|
employee.hap *= mult;
|
||||||
} else {
|
} else {
|
||||||
|
@ -128,24 +128,30 @@ export class Product {
|
|||||||
|
|
||||||
// Make progress on this product based on current employee productivity
|
// Make progress on this product based on current employee productivity
|
||||||
createProduct(marketCycles: number, employeeProd: typeof this["creationProd"]): void {
|
createProduct(marketCycles: number, employeeProd: typeof this["creationProd"]): void {
|
||||||
if (this.fin) { return; }
|
if (this.fin) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Designing/Creating a Product is based mostly off Engineers
|
// Designing/Creating a Product is based mostly off Engineers
|
||||||
const opProd = employeeProd[EmployeePositions.Operations];
|
const opProd = employeeProd[EmployeePositions.Operations];
|
||||||
const engrProd = employeeProd[EmployeePositions.Engineer];
|
const engrProd = employeeProd[EmployeePositions.Engineer];
|
||||||
const mgmtProd = employeeProd[EmployeePositions.Management];
|
const mgmtProd = employeeProd[EmployeePositions.Management];
|
||||||
const total = opProd + engrProd + mgmtProd;
|
const total = opProd + engrProd + mgmtProd;
|
||||||
if (total <= 0) { return; }
|
if (total <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Management is a multiplier for the production from Engineers
|
// Management is a multiplier for the production from Engineers
|
||||||
const mgmtFactor = 1 + mgmtProd / (1.2 * total);
|
const mgmtFactor = 1 + mgmtProd / (1.2 * total);
|
||||||
const prodMult = (Math.pow(engrProd, 0.34) + Math.pow(opProd, 0.2)) * mgmtFactor;
|
const prodMult = (Math.pow(engrProd, 0.34) + Math.pow(opProd, 0.2)) * mgmtFactor;
|
||||||
const progress = Math.min(marketCycles * 0.01 * prodMult, 100 - this.prog);
|
const progress = Math.min(marketCycles * 0.01 * prodMult, 100 - this.prog);
|
||||||
if (progress <= 0) { return; }
|
if (progress <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.prog += progress;
|
this.prog += progress;
|
||||||
for (const pos of Object.keys(employeeProd)) {
|
for (const pos of Object.keys(employeeProd)) {
|
||||||
this.creationProd[pos] += employeeProd[pos] * progress / 100;
|
this.creationProd[pos] += (employeeProd[pos] * progress) / 100;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ export function Industry(props: IProps): React.ReactElement {
|
|||||||
return (
|
return (
|
||||||
<Box display="flex">
|
<Box display="flex">
|
||||||
<Box sx={{ width: "50%" }}>
|
<Box sx={{ width: "50%" }}>
|
||||||
<IndustryOverview rerender={props.rerender} currentCity={props.city} office={props.office} />
|
<IndustryOverview rerender={props.rerender} />
|
||||||
<IndustryOffice rerender={props.rerender} office={props.office} />
|
<IndustryOffice rerender={props.rerender} office={props.office} />
|
||||||
</Box>
|
</Box>
|
||||||
<Box sx={{ width: "50%" }}>
|
<Box sx={{ width: "50%" }}>
|
||||||
|
@ -36,14 +36,6 @@ interface IProps {
|
|||||||
rerender: () => void;
|
rerender: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function countEmployee(employees: Employee[], job: string): number {
|
|
||||||
let n = 0;
|
|
||||||
for (let i = 0; i < employees.length; ++i) {
|
|
||||||
if (employees[i].pos === job) n++;
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ISwitchProps {
|
interface ISwitchProps {
|
||||||
manualMode: boolean;
|
manualMode: boolean;
|
||||||
switchMode: (f: (b: boolean) => boolean) => void;
|
switchMode: (f: (b: boolean) => boolean) => void;
|
||||||
@ -181,7 +173,7 @@ interface IAutoAssignProps {
|
|||||||
rerender: () => void;
|
rerender: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function EmployeeCount(props: { num: number, next: number }): React.ReactElement {
|
function EmployeeCount(props: { num: number; next: number }): React.ReactElement {
|
||||||
return (
|
return (
|
||||||
<Typography display="flex" alignItems="center" justifyContent="flex-end">
|
<Typography display="flex" alignItems="center" justifyContent="flex-end">
|
||||||
{props.num === props.next ? null : props.num}
|
{props.num === props.next ? null : props.num}
|
||||||
@ -192,9 +184,6 @@ function EmployeeCount(props: { num: number, next: number }): React.ReactElement
|
|||||||
}
|
}
|
||||||
|
|
||||||
function AutoAssignJob(props: IAutoAssignProps): React.ReactElement {
|
function AutoAssignJob(props: IAutoAssignProps): React.ReactElement {
|
||||||
const corp = useCorporation();
|
|
||||||
const division = useDivision();
|
|
||||||
|
|
||||||
const currJob = props.office.employeeJobs[props.job];
|
const currJob = props.office.employeeJobs[props.job];
|
||||||
const nextJob = props.office.employeeNextJobs[props.job];
|
const nextJob = props.office.employeeNextJobs[props.job];
|
||||||
const nextUna = props.office.employeeNextJobs[EmployeePositions.Unassigned];
|
const nextUna = props.office.employeeNextJobs[EmployeePositions.Unassigned];
|
||||||
@ -319,9 +308,9 @@ function AutoManagement(props: IProps): React.ReactElement {
|
|||||||
<Tooltip
|
<Tooltip
|
||||||
title={
|
title={
|
||||||
<Typography>
|
<Typography>
|
||||||
The base amount of material this office can produce. Does not include production multipliers
|
The base amount of material this office can produce. Does not include production multipliers from
|
||||||
from upgrades and materials. This value is based off the productivity of your Operations,
|
upgrades and materials. This value is based off the productivity of your Operations, Engineering,
|
||||||
Engineering, and Management employees
|
and Management employees
|
||||||
</Typography>
|
</Typography>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@ -473,8 +462,17 @@ export function IndustryOffice(props: IProps): React.ReactElement {
|
|||||||
title={<Typography>Throw an office party to increase your employee's morale and happiness</Typography>}
|
title={<Typography>Throw an office party to increase your employee's morale and happiness</Typography>}
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
<Button disabled={corp.funds < props.office.getCoffeeCost() || props.office.coffeeMult > 0} onClick={() => BuyCoffee(corp, props.office)}>
|
<Button
|
||||||
{props.office.coffeeMult > 0 ? "Buying coffee..." : <span>Buy Coffee - <MoneyCost money={props.office.getCoffeeCost()} corp={corp} /></span>}
|
disabled={corp.funds < props.office.getCoffeeCost() || props.office.coffeeMult > 0}
|
||||||
|
onClick={() => BuyCoffee(corp, props.office)}
|
||||||
|
>
|
||||||
|
{props.office.coffeeMult > 0 ? (
|
||||||
|
"Buying coffee..."
|
||||||
|
) : (
|
||||||
|
<span>
|
||||||
|
Buy Coffee - <MoneyCost money={props.office.getCoffeeCost()} corp={corp} />
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
</span>
|
</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@ -487,7 +485,10 @@ export function IndustryOffice(props: IProps): React.ReactElement {
|
|||||||
title={<Typography>Throw an office party to increase your employee's morale and happiness</Typography>}
|
title={<Typography>Throw an office party to increase your employee's morale and happiness</Typography>}
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
<Button disabled={corp.funds < 0 || props.office.partyMult > 0} onClick={() => setThrowPartyOpen(true)}>
|
<Button
|
||||||
|
disabled={corp.funds < 0 || props.office.partyMult > 0}
|
||||||
|
onClick={() => setThrowPartyOpen(true)}
|
||||||
|
>
|
||||||
{props.office.partyMult > 0 ? "Throwing Party..." : "Throw Party"}
|
{props.office.partyMult > 0 ? "Throwing Party..." : "Throw Party"}
|
||||||
</Button>
|
</Button>
|
||||||
</span>
|
</span>
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// (top-left panel in the Industry UI)
|
// (top-left panel in the Industry UI)
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
|
|
||||||
import { OfficeSpace } from "../OfficeSpace";
|
|
||||||
import { Industries } from "../IndustryData";
|
import { Industries } from "../IndustryData";
|
||||||
import { HireAdVert } from "../Actions";
|
import { HireAdVert } from "../Actions";
|
||||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
@ -89,8 +88,6 @@ function MakeProductButton(): React.ReactElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
currentCity: string;
|
|
||||||
office: OfficeSpace;
|
|
||||||
rerender: () => void;
|
rerender: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,14 +215,20 @@ export function IndustryOverview(props: IProps): React.ReactElement {
|
|||||||
<Tooltip
|
<Tooltip
|
||||||
title={
|
title={
|
||||||
<Typography>
|
<Typography>
|
||||||
Hire AdVert.Inc to advertise your company. Each level of
|
Hire AdVert.Inc to advertise your company. Each level of this upgrade grants your company a static
|
||||||
this upgrade grants your company a static increase of 3 and 1 to its awareness and
|
increase of 3 and 1 to its awareness and popularity, respectively. It will then increase your company's
|
||||||
popularity, respectively. It will then increase your company's awareness by 1%, and its popularity
|
awareness by 1%, and its popularity by a random percentage between 1% and 3%. These effects are increased
|
||||||
by a random percentage between 1% and 3%. These effects are increased by other upgrades
|
by other upgrades that increase the power of your advertising.
|
||||||
that increase the power of your advertising.
|
|
||||||
</Typography>
|
</Typography>
|
||||||
}>
|
}
|
||||||
<Button disabled={division.getAdVertCost() > corp.funds} onClick={() => HireAdVert(corp, division)}>
|
>
|
||||||
|
<Button
|
||||||
|
disabled={division.getAdVertCost() > corp.funds}
|
||||||
|
onClick={function () {
|
||||||
|
HireAdVert(corp, division);
|
||||||
|
props.rerender();
|
||||||
|
}}
|
||||||
|
>
|
||||||
Hire AdVert - <MoneyCost money={division.getAdVertCost()} corp={corp} />
|
Hire AdVert - <MoneyCost money={division.getAdVertCost()} corp={corp} />
|
||||||
</Button>
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
@ -531,7 +531,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
bladeburner: NetscriptBladeburner(Player, workerScript),
|
bladeburner: NetscriptBladeburner(Player, workerScript),
|
||||||
codingcontract: NetscriptCodingContract(Player, workerScript),
|
codingcontract: NetscriptCodingContract(Player, workerScript),
|
||||||
sleeve: NetscriptSleeve(Player),
|
sleeve: NetscriptSleeve(Player),
|
||||||
corporation: NetscriptCorporation(Player, workerScript),
|
corporation: NetscriptCorporation(Player),
|
||||||
stanek: NetscriptStanek(Player, workerScript, helper),
|
stanek: NetscriptStanek(Player, workerScript, helper),
|
||||||
infiltration: NetscriptInfiltration(Player),
|
infiltration: NetscriptInfiltration(Player),
|
||||||
ui: NetscriptUserInterface(),
|
ui: NetscriptUserInterface(),
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import { WorkerScript } from "../Netscript/WorkerScript";
|
|
||||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||||
import { netscriptDelay } from "../NetscriptEvaluator";
|
|
||||||
|
|
||||||
import { OfficeSpace } from "../Corporation/OfficeSpace";
|
import { OfficeSpace } from "../Corporation/OfficeSpace";
|
||||||
import { Employee } from "../Corporation/Employee";
|
import { Employee } from "../Corporation/Employee";
|
||||||
@ -60,7 +58,6 @@ import {
|
|||||||
import { CorporationUnlockUpgrades } from "../Corporation/data/CorporationUnlockUpgrades";
|
import { CorporationUnlockUpgrades } from "../Corporation/data/CorporationUnlockUpgrades";
|
||||||
import { CorporationUpgrades } from "../Corporation/data/CorporationUpgrades";
|
import { CorporationUpgrades } from "../Corporation/data/CorporationUpgrades";
|
||||||
import { EmployeePositions } from "../Corporation/EmployeePositions";
|
import { EmployeePositions } from "../Corporation/EmployeePositions";
|
||||||
import { calculateIntelligenceBonus } from "../PersonObjects/formulas/intelligence";
|
|
||||||
import { Industry } from "../Corporation/Industry";
|
import { Industry } from "../Corporation/Industry";
|
||||||
import { IndustryResearchTrees, IndustryStartingCosts } from "../Corporation/IndustryData";
|
import { IndustryResearchTrees, IndustryStartingCosts } from "../Corporation/IndustryData";
|
||||||
import { CorporationConstants } from "../Corporation/data/Constants";
|
import { CorporationConstants } from "../Corporation/data/Constants";
|
||||||
@ -69,7 +66,7 @@ import { Factions } from "../Faction/Factions";
|
|||||||
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
|
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
|
||||||
import { InternalAPI, NetscriptContext } from "src/Netscript/APIWrapper";
|
import { InternalAPI, NetscriptContext } from "src/Netscript/APIWrapper";
|
||||||
|
|
||||||
export function NetscriptCorporation(player: IPlayer, workerScript: WorkerScript): InternalAPI<NSCorporation> {
|
export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation> {
|
||||||
function createCorporation(corporationName: string, selfFund = true): boolean {
|
function createCorporation(corporationName: string, selfFund = true): boolean {
|
||||||
if (!player.canAccessCorporation() || player.hasCorporation()) return false;
|
if (!player.canAccessCorporation() || player.hasCorporation()) return false;
|
||||||
if (!corporationName) return false;
|
if (!corporationName) return false;
|
||||||
@ -257,7 +254,7 @@ export function NetscriptCorporation(player: IPlayer, workerScript: WorkerScript
|
|||||||
|
|
||||||
function getMaterial(divisionName: string, cityName: string, materialName: string): Material {
|
function getMaterial(divisionName: string, cityName: string, materialName: string): Material {
|
||||||
const warehouse = getWarehouse(divisionName, cityName);
|
const warehouse = getWarehouse(divisionName, cityName);
|
||||||
const matName = (materialName ).replace(/ /g, "");
|
const matName = materialName.replace(/ /g, "");
|
||||||
const material = warehouse.materials[matName];
|
const material = warehouse.materials[matName];
|
||||||
if (material === undefined) throw new Error(`Invalid material name: '${materialName}'`);
|
if (material === undefined) throw new Error(`Invalid material name: '${materialName}'`);
|
||||||
return material;
|
return material;
|
||||||
@ -780,7 +777,7 @@ export function NetscriptCorporation(player: IPlayer, workerScript: WorkerScript
|
|||||||
const corporation = getCorporation();
|
const corporation = getCorporation();
|
||||||
const office = getOffice(divisionName, cityName);
|
const office = getOffice(divisionName, cityName);
|
||||||
|
|
||||||
return ThrowParty(corporation, office, costPerEmployee)
|
return ThrowParty(corporation, office, costPerEmployee);
|
||||||
},
|
},
|
||||||
buyCoffee:
|
buyCoffee:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
|
Loading…
Reference in New Issue
Block a user