Skip to content

Commit

Permalink
Alpha 9
Browse files Browse the repository at this point in the history
Alpha 9
  • Loading branch information
alexanderson1993 authored Feb 3, 2023
2 parents f9a59c8 + f59f2ab commit ac480f5
Show file tree
Hide file tree
Showing 144 changed files with 4,278 additions and 538 deletions.
1 change: 1 addition & 0 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import CrewConfig from "./components/FlightQuickStart/CrewConfig";
import ShipConfig from "./components/FlightQuickStart/ShipConfig";
import MissionConfig from "./components/FlightQuickStart/MissionConfig";
import {ComponentDemo} from "./cards";
import {GamepadConfig} from "./hooks/useGamepadStore";

const DocLayout = lazy(() => import("./docs"));
const Config = lazy(() => import("./pages/Config"));
Expand Down
21 changes: 21 additions & 0 deletions client/src/cards/AlertLevel/data.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {t} from "@server/init/t";
import {pubsub} from "@server/init/pubsub";
import {z} from "zod";

export const alertLevel = t.router({
update: t.procedure
.input(z.object({level: z.union([
z.literal("5"),
z.literal("4"),
z.literal("3"),
z.literal("2"),
z.literal("1"),
z.literal("p")
])}))
.send(({ctx, input}) => {
if (!ctx.ship) throw new Error("Ship not found");

ctx.ship.updateComponent('isShip', {alertLevel:input.level});
pubsub.publish.ship.get({shipId: ctx.ship.id});
})
});
109 changes: 109 additions & 0 deletions client/src/cards/AlertLevel/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import * as React from "react";
import {q} from "@client/context/AppContext";
import Button from "@thorium/ui/Button";
import { AlertLevel } from "@server/components/isShip";

const alertLevelText = [
{
number: 5,
text:
"This alert condition is used when the ship is at normal running status. The crew is on standard duty and the ship is in no danger.",
},
{
number: 4,
text:
"This alert condition is used when the station has a minor problem. All crew except damage control is on standard duty.",
},
{
number: 3,
text:
"This alert condition is used when the ship needs to be ready for a crisis. All off duty personnel are put on stand by status.",
},
{
number: 2,
text:
"This alert condition is used when the ship is in a dangerous situation, but is safe for the moment. All crew members are put on duty.",
},
{
number: 1,
text:
"This alert condition is used when the ship is in danger or under attack. All crew members are put on duty at battle stations.",
},
];

export function AlertLevelCard() {
const [ship] = q.ship.get.useNetRequest();
let [description, setDescription] = React.useState("");

const updateLevel = (newLevel: AlertLevel) => {
q.alertLevel.update.netSend({
level: newLevel
});
}
const displayDesc = (level: number) => {
alertLevelText.forEach((e) => {
if (e.number === level) {
setDescription(e.text);
}
});
}
const clearDesc = () => {
setDescription("");
}
return (
<div className="flex flex-row h-full gap-4">
<div className="flex-1">
<div className="flex flex-col justify-between h-full gap-4">
<Button
className="btn-primary flex-1"
type="button"
onClick={() => updateLevel("5")}
onMouseEnter={() => displayDesc(5)}
onMouseLeave={() => clearDesc()}
>
Alert Condition 5
</Button>
<Button
className="btn-success flex-1"
type="button"
onClick={() => updateLevel("4")}
onMouseEnter={() => displayDesc(4)}
onMouseLeave={() => clearDesc()}
>
Alert Condition 4
</Button>
<Button
className="btn-warning flex-1"
type="button"
onClick={() => updateLevel("3")}
onMouseEnter={() => displayDesc(3)}
onMouseLeave={() => clearDesc()}
>
Alert Condition 3
</Button>
<Button
className="btn-secondary flex-1"
type="button"
onClick={() => updateLevel("2")}
onMouseEnter={() => displayDesc(2)}
onMouseLeave={() => clearDesc()}
>
Alert Condition 2
</Button>
<Button
className="btn-error flex-1"
type="button"
onClick={() => updateLevel("1")}
onMouseEnter={() => displayDesc(1)}
onMouseLeave={() => clearDesc()}
>
Alert Condition 1
</Button>
</div>
</div>
<div className="form-control flex flex-1 h-64">
<textarea className="textarea h-full w-full" value={description} disabled></textarea>
</div>
</div>
);
};
12 changes: 9 additions & 3 deletions client/src/cards/CargoControl/CargoList.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {q} from "@client/context/AppContext";
import {Kelvin} from "@server/utils/unitTypes";
import {cargoSort} from "./cargoSort";

export function CargoList({
Expand All @@ -8,7 +9,12 @@ export function CargoList({
onClick,
}: {
selectedRoom:
| {id: number; contents: {[inventoryTemplateName: string]: number}}
| {
id: number;
contents: {
[inventoryTemplateName: string]: {temperature: Kelvin; count: number};
};
}
| undefined;
enRouteContainerId: number | undefined;
selectedContainerId: number | null;
Expand All @@ -22,7 +28,7 @@ export function CargoList({
Object.entries(selectedRoom.contents)
.sort(cargoSort)
.map(([key, value]) => {
if (value === 0) return null;
if (value.count === 0) return null;
const inventoryType = inventoryTypes[key];
let itemVolume = Math.max(
Math.round(inventoryType.volume * 1000) / 1000,
Expand All @@ -43,7 +49,7 @@ export function CargoList({
<span className="font-bold">
{key} {inventoryType ? `(${itemVolume} / unit)` : ""}
</span>
<span className="tabular-nums">{value}</span>
<span className="tabular-nums">{value.count}</span>
</div>
</li>
);
Expand Down
5 changes: 4 additions & 1 deletion client/src/cards/CargoControl/cargoSort.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
export function cargoSort([keyA]: [string, number], [keyB]: [string, number]) {
export function cargoSort(
[keyA]: [string, {count: number}],
[keyB]: [string, {count: number}]
) {
return keyA.localeCompare(keyB);
}
69 changes: 46 additions & 23 deletions client/src/cards/CargoControl/data.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {t} from "@server/init/t";
import {pubsub} from "@server/init/pubsub";
import {matchSorter} from "match-sorter";
import {InventoryTemplate} from "server/src/classes/Plugins/Inventory";
import {findClosestNode} from "server/src/systems/PassengerMovementSystem";
import {DataContext} from "server/src/utils/DataContext";
import {Entity} from "server/src/utils/ecs";
Expand All @@ -10,6 +9,8 @@ import {
createShipMapGraph,
} from "server/src/utils/shipMapPathfinder";
import {z} from "zod";
import {Kelvin} from "@server/utils/unitTypes";
import {getInventoryTemplates} from "@server/utils/getInventoryTemplates";

const transferId = z.object({
type: z.union([z.literal("room"), z.literal("entity")]),
Expand All @@ -18,7 +19,15 @@ const transferId = z.object({

export const cargoControl = t.router({
inventoryTypes: t.procedure.request(({ctx}) => {
return ctx.flight?.inventoryTemplates || {};
const inventorySystem = ctx.flight?.ecs.systems.find(
sys => sys.constructor.name === "InventoryTemplateSystem"
);
return Object.fromEntries(
inventorySystem?.entities.map(entity => [
entity.components.identity?.name,
{...entity.components.identity, ...entity.components.isInventory},
]) || []
);
}),
rooms: t.procedure
.filter((publish: {shipId: number} | null, {ctx}) => {
Expand All @@ -27,6 +36,7 @@ export const cargoControl = t.router({
})
.request(({ctx}) => {
if (!ctx.ship) throw new Error("No ship selected");
const inventoryTemplates = getInventoryTemplates(ctx.flight?.ecs);
const rooms =
ctx.ship?.components.shipMap?.deckNodes
.filter(node => node.isRoom && node.flags?.includes("cargo"))
Expand All @@ -38,10 +48,7 @@ export const cargoControl = t.router({
position: {x: node.x, y: node.y},
volume: node.volume,
contents: node.contents,
used: calculateCargoUsed(
node.contents,
ctx.flight?.inventoryTemplates || {}
),
used: calculateCargoUsed(node.contents, inventoryTemplates),
};
}) || [];
const decks = ctx.ship.components.shipMap?.decks || [];
Expand All @@ -58,6 +65,8 @@ export const cargoControl = t.router({
})
.request(({ctx}) => {
if (!ctx.ship) throw new Error("No ship selected");
const inventoryTemplates = getInventoryTemplates(ctx.flight?.ecs);

return (
ctx.flight?.ecs.entities
.filter(
Expand All @@ -79,7 +88,7 @@ export const cargoControl = t.router({
contents: entity.components.cargoContainer?.contents || {},
used: calculateCargoUsed(
entity.components.cargoContainer?.contents || {},
ctx.flight?.inventoryTemplates || {}
inventoryTemplates
),
volume: entity.components.cargoContainer?.volume || 0,
destinationNode:
Expand Down Expand Up @@ -130,7 +139,7 @@ export const cargoControl = t.router({
});

// And the cargo items in the room.
Object.entries(node.contents).forEach(([name, count], i) => {
Object.entries(node.contents).forEach(([name, {count}], i) => {
if (count === 0) return;
output.push({
id: Number(`${node.id}${i}${count}`),
Expand Down Expand Up @@ -270,30 +279,32 @@ export const cargoControl = t.router({
const toContainer = getCargoContents(ctx, input.toId);
if (!toContainer) throw new Error("No destination container found.");

const inventoryTemplates = getInventoryTemplates(ctx.flight?.ecs);

let itemCounts: {[key: string]: number} = {};
let destinationVolume = toContainer.volume;
// First loop to see if there are any errors
input.transfers.forEach(({item, count}) => {
if (
!fromContainer.contents[item] ||
fromContainer.contents[item] < count
fromContainer.contents[item].count < count
) {
itemCounts[item] = fromContainer.contents[item];
itemCounts[item] = fromContainer.contents[item].count;
}
const destinationUsedSpace = calculateCargoUsed(
toContainer.contents || {},
ctx.flight?.inventoryTemplates || {}
inventoryTemplates
);
const movedVolume = calculateCargoUsed(
{[item]: itemCounts[item] || count},
ctx.flight?.inventoryTemplates || {}
{[item]: {count: itemCounts[item] || count}},
inventoryTemplates
);

if (destinationUsedSpace + movedVolume > destinationVolume) {
const volumeLeft = destinationVolume - destinationUsedSpace;
const singleVolume = calculateCargoUsed(
{[item]: 1},
ctx.flight?.inventoryTemplates || {}
{[item]: {count: 1}},
inventoryTemplates
);
const cargoItemsThatFitInVolumeLeft = Math.floor(
volumeLeft / singleVolume
Expand All @@ -307,17 +318,29 @@ export const cargoControl = t.router({
throw new Error("Not enough space in destination.");
}
const actualMovedVolume = calculateCargoUsed(
{[item]: itemCounts[item] || count},
ctx.flight?.inventoryTemplates || {}
{[item]: {count: itemCounts[item] || count}},
inventoryTemplates
);
destinationVolume -= actualMovedVolume;
});

// Then loop to do the actual transfer
input.transfers.forEach(({item, count}) => {
fromContainer.contents[item] -= itemCounts[item] || count;
if (!toContainer.contents[item]) toContainer.contents[item] = 0;
toContainer.contents[item] += itemCounts[item] || count;
fromContainer.contents[item].count -= itemCounts[item] || count;
if (!toContainer.contents[item])
toContainer.contents[item] = {count: 0, temperature: 295.37};

// Average the temperatures of the items being transferred.
// The formula we'll use for combining heat is
// (T1 * C1 + T2 * C2) / (C1 + C2)
const T1 = fromContainer.contents[item].temperature;
const T2 = toContainer.contents[item].temperature;
const C1 = toContainer.contents[item].count;
const C2 = itemCounts[item] || count;

toContainer.contents[item].count += C2;
toContainer.contents[item].temperature =
(T1 * C1 + T2 * C2) / (C1 + C2);
});

if (ctx.ship) {
Expand All @@ -333,10 +356,10 @@ export const cargoControl = t.router({

function calculateCargoUsed(
contents: {
[inventoryTemplateName: string]: number;
[inventoryTemplateName: string]: {count: number};
},
inventory: {
[inventoryTemplateName: string]: InventoryTemplate;
[inventoryTemplateName: string]: {volume: number};
}
) {
if (!contents) return 0;
Expand All @@ -345,7 +368,7 @@ function calculateCargoUsed(
if (!template) {
return acc;
}
return acc + contents[key] * template.volume;
return acc + contents[key].count * template.volume;
}, 0);

return Math.round(value * 1000) / 1000;
Expand Down
8 changes: 6 additions & 2 deletions client/src/cards/ComponentDemo/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const SearchableListDemo = () => {
},
]}
selectedItem={selected}
setSelectedItem={id => {
setSelectedItem={({id}) => {
setSelected(id);
}}
/>
Expand Down Expand Up @@ -113,7 +113,7 @@ export function ComponentDemo() {
null
);
return (
<div className="flex flex-col gap-8 text-white h-full overflow-y-auto">
<div className="flex flex-col gap-8 text-white h-full overflow-y-auto p-4">
<div className="flex flex-col gap-4">
<h2 className="text-3xl">Alert</h2>
<div className="alert">
Expand Down Expand Up @@ -231,6 +231,10 @@ export function ComponentDemo() {
<Button>Item 3</Button>
</div>
</div>
<div>
<h2 className="text-3xl">Gamepad Focus Border</h2>
<Button className="btn-active gamepad-focus">I am focused</Button>
</div>
<div>
<h2 className="text-3xl">Divider</h2>
<div className="flex flex-col w-full">
Expand Down
Loading

0 comments on commit ac480f5

Please sign in to comment.