Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions packages/client/embedded_plugins/Admin-Controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,9 @@ async function createPlanet(coords, level, type) {
//PUNK when dfares/types update, need to update here
type++;

//PUNK add more spaceType later
const spaceType = 1; // Math.round(df.spaceTypePerlin(coords));
const perlin = Math.round(df.spaceTypePerlin(coords));
const distFromOrigin = Math.sqrt(coords.x ** 2 + coords.y ** 2);
const spaceType = df.spaceTypeFromPerlin(perlin, distFromOrigin);

const args = Promise.resolve([
location,
Expand Down
3 changes: 3 additions & 0 deletions packages/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"@latticexyz/utils": "2.2.22-13071c45dd7d28c1860e703d12b07624c271f508",
"@latticexyz/world": "2.2.22-13071c45dd7d28c1860e703d12b07624c271f508",
"@lit-labs/react": "1.0.2",
"@radix-ui/react-tabs": "^1.1.9",
"@rainbow-me/rainbowkit": "2.2.4",
"@rollup/plugin-wasm": "6.2.2",
"@spectrum-web-components/slider": "0.47.1",
Expand All @@ -44,6 +45,7 @@
"async-mutex": "0.5.0",
"auto-bind": "5.0.1",
"big-integer": "1.6.52",
"clsx": "^2.1.1",
"color": "4.2.3",
"contracts": "workspace:*",
"delay": "6.0.0",
Expand All @@ -67,6 +69,7 @@
"react-howler": "^5.2.0",
"rxjs": "7.5.5",
"styled-components": "5.3.3",
"tailwind-merge": "^3.2.0",
"ts-dedent": "2.2.0",
"viem": "2.26.3",
"vite-plugin-node-polyfills": "0.23.0",
Expand Down
Binary file added packages/client/public/img/markets/rarible.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 7 additions & 2 deletions packages/client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,21 @@ import {
import { createGlobalStyle } from "styled-components";

import { Theme } from "./Frontend/Components/Theme";
import { BluePillLandingPage } from "./Frontend/Pages/BluePillLandingPage";
import { GameLandingPage } from "./Frontend/Pages/GameLandingPage";
import { GamePage } from "./Frontend/Pages/GamePage";
import { HelloPage } from "./Frontend/Pages/HelloPage";
import { ClassicLandingPage } from "./Frontend/Pages/LandingPage";
import { ArtifactsGallery } from "./Frontend/Gallery/Pages/ArtifactsGalleryPage";
import { NotFoundPage } from "./Frontend/Pages/NotFoundPage";
import { RedPillLandingPage } from "./Frontend/Pages/RedPillLandingPage";
import { SandboxPage } from "./Frontend/Pages/SandboxPage";
import { TxConfirmPopup } from "./Frontend/Pages/TxConfirmPopup";
import { WelcomePage } from "./Frontend/Pages/WelcomePage";
import dfstyles from "./Frontend/Styles/dfstyles";
import { getNetworkConfig } from "./mud/getNetworkConfig";
import { PlanetTestPage } from "./PlanetTest/PlanetTestPage";
import { BluePillLandingPage } from "./Frontend/Pages/BluePillLandingPage";
import { RedPillLandingPage } from "./Frontend/Pages/RedPillLandingPage";

const GlobalStyle = createGlobalStyle`
body {
width: 100vw;
Expand Down Expand Up @@ -85,6 +87,9 @@ export const App = () => {
{/* <Route path="/welcome" element={<WelcomePage />} /> */}
{/* <Route path="/game" element={<GamePage />} /> */}
<Route path="/test" element={<PlanetTestPage />} />

<Route path="/gallery" element={<ArtifactsGallery />} />

{/* <Route path="/hello" element={<HelloPage />} /> */}
<Route path="*" element={<NotFoundPage />} />
<Route
Expand Down
5 changes: 3 additions & 2 deletions packages/client/src/Backend/GameLogic/ArtifactUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export class ArtifactUtils {
id: artifactId,
planetDiscoveredOn: "0" as LocationId,
rarity: artifactRec.rarity as ArtifactRarity,
planetBiome: 0 as Biome,
planetBiome: artifactRec.biome as Biome,
mintedAtTimestamp: 0,
discoverer: EMPTY_ADDRESS,
artifactType,
Expand Down Expand Up @@ -154,6 +154,7 @@ export class ArtifactUtils {
owner: EthAddress,
index: number,
rarity: number,
biome: number,
): Artifact | undefined {
const artifactId = artifactIdFromDecStr(tokenId.toString());
const {
Expand Down Expand Up @@ -204,7 +205,7 @@ export class ArtifactUtils {
id: artifactId,
planetDiscoveredOn: "0" as LocationId,
rarity: rarity as ArtifactRarity,
planetBiome: 0 as Biome,
planetBiome: biome as Biome,
mintedAtTimestamp: 0,
discoverer: EMPTY_ADDRESS,
artifactType,
Expand Down
10 changes: 9 additions & 1 deletion packages/client/src/Backend/GameLogic/PlanetUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,14 @@ export class PlanetUtils {
const planetRec = getComponentValue(PlanetConstants, planetEntity);

if (planetRec) {
// If planet is in contract, it is OK to input any value for perlin and distSquare
// NOTICE:
// When a planet is stored onchain, any provided Perlin value will be accepted.
// However, supplying an incorrect distSquare value may result in the planet's
// computed distSquare and universeZone being inaccurate.
//
// In this case, a distSquare value of 0 was provided as input.
// It should be noted that this may indicate the presence of invalid or corrupted data.

const planet: Planet = this.readPlanet(planetId, 0, 0);
return planet;
} else {
Expand Down Expand Up @@ -182,6 +189,7 @@ export class PlanetUtils {
spaceType = planetRec.spaceType as SpaceType;
planetType = planetRec.planetType as PlanetType;
planetLevel = planetRec.level as PlanetLevel;
perlin = planetRec.perlin;
universeZone = this._initZone(distSquare);

const ownerInContract = getComponentValue(PlanetOwner, planetEntity);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import type { Artifact } from "@df/types";
import { useEffect, useRef } from "react";
import styled from "styled-components";

import { ArtifactRenderer } from "../../Renderers/Artifacts/ArtifactRenderer";

export function ArtifactImage({
artifact,
size,
thumb = true, // Not used but kept for API consistency
}: {
artifact: Artifact | null;
size: number;
thumb?: boolean;
}) {
if (!artifact) return;
const canvasRef = useRef<HTMLCanvasElement | null>(null);
const rendererRef = useRef<ArtifactRenderer | null>(null);

useEffect(() => {
if (!artifact) return;
const canvas = canvasRef.current;
if (!canvas || !artifact) return;

const renderer = new ArtifactRenderer(canvas, false);
renderer.setVisible(true);
renderer.setArtifacts([artifact]);
rendererRef.current = renderer;
if (!renderer) return;
return () => {
renderer.destroy?.();
rendererRef.current = null;
};
}, []);

useEffect(() => {
if (!artifact) return;
const canvas = canvasRef.current;
if (!canvas || !artifact) return;

const renderer = new ArtifactRenderer(canvas, false);
renderer.setVisible(true);
renderer.setArtifacts([artifact]);
rendererRef.current = renderer;
if (!renderer) return;
return () => {
renderer.destroy?.();
rendererRef.current = null;
};
}, [artifact]);

return (
<StyledCanvas className=" " ref={canvasRef} width={size} height={size} />
);
}

const StyledCanvas = styled.canvas`
display: block;
margin: 0;
padding: 0;
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import type { Artifact } from "@df/types";
import { useEffect, useRef } from "react";
import styled from "styled-components";

import { ArtifactRenderer } from "../../Renderers/Artifacts/ArtifactRenderer";

export function ArtifactImageMarket({
artifact,
size,
thumb = true, // Not used but kept for API consistency
}: {
artifact: Artifact | null;
size: number;
thumb?: boolean;
}) {
if (!artifact) return;
const canvasRef = useRef<HTMLCanvasElement | null>(null);
const rendererRef = useRef<ArtifactRenderer | null>(null);

useEffect(() => {
if (!artifact) return;
const canvas = canvasRef.current;
if (!canvas || !artifact) return;

const renderer = new ArtifactRenderer(canvas, false);
renderer.setVisible(true);
renderer.setArtifacts([artifact]);
rendererRef.current = renderer;
if (!renderer) return;
return () => {
renderer.destroy?.();
rendererRef.current = null;
};
}, []);

useEffect(() => {
if (!artifact) return;
const canvas = canvasRef.current;
if (!canvas || !artifact) return;

const renderer = new ArtifactRenderer(canvas, false);
renderer.setVisible(true);
renderer.setArtifacts([artifact]);
rendererRef.current = renderer;
if (!renderer) return;
return () => {
renderer.destroy?.();
rendererRef.current = null;
};
}, [artifact]);

return (
<StyledCanvas
className="mx-auto origin-center"
ref={canvasRef}
width={size}
height={size}
/>
);
}

const StyledCanvas = styled.canvas``;
152 changes: 152 additions & 0 deletions packages/client/src/Frontend/Gallery/Components/GalleryArtModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import { ArtifactRarityLabelAnim } from "@frontend/Components/Labels/ArtifactLabels";
import {
artifactRarityFromName,
artifactTypeFromName,
getSpriteImageStyle,
hexToDecimal,
} from "@frontend/Gallery/Utils/gallery-Utils";
import { useEffect, useRef } from "react";
import { ArtifactRarity } from "@df/types";

interface Artifact {
name: string;
image: string;
type: string;
rarity: string;
description: string;
owner: string;
}

interface GalleryArtModalProps {
artifact: Artifact | null;
onClose: () => void;
onPrev: () => void;
onNext: () => void;
}

const ARTIFACT_URL = "/df_ares_artifact_icons/";
export function MarketLink({ href, imgSrc }: { href: string; imgSrc: string }) {
return (
<a
href={href}
target="_blank"
rel="noopener noreferrer"
className="flex transform items-center justify-center rounded p-2 transition-transform duration-200 hover:scale-110 hover:text-gray-300"
>
<img src={imgSrc} alt="Market" className="h-5 w-5" />
</a>
);
}

export function GalleryArtModal({
artifact,
onClose,
onPrev,
onNext,
}: GalleryArtModalProps) {
const overlayRef = useRef<HTMLDivElement>(null);
// Helper function to create market links

useEffect(() => {
function handleClickOutside(event: MouseEvent) {
if (overlayRef.current && event.target === overlayRef.current) {
onClose();
}
}
function handleKeyDown(event: KeyboardEvent) {
if (event.key === "Escape") onClose();
if (event.key === "ArrowLeft") onPrev();
if (event.key === "ArrowRight") onNext();
}
window.addEventListener("mousedown", handleClickOutside);
window.addEventListener("keydown", handleKeyDown);
return () => {
window.removeEventListener("mousedown", handleClickOutside);
window.removeEventListener("keydown", handleKeyDown);
};
}, [onClose, onPrev, onNext]);

if (!artifact) return null;

const rarity =
artifactRarityFromName(artifact.rarity) || ArtifactRarity.Unknown;

return (
<div
ref={overlayRef}
className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50"
>
<div className="relative w-full max-w-md rounded-lg bg-black p-6 shadow-lg">
<div className="flex items-center justify-between">
<h2 className="text-xl font-bold">{artifact.name}</h2>
<button
onClick={onClose}
className="transform text-gray-500 transition-transform duration-200 hover:scale-110 hover:text-gray-300 hover:text-gray-700"
>
&times;
</button>
</div>

<div className="relative h-full w-full">
<img
src={artifact.image}
alt={artifact.name}
className="h-full w-full rounded object-contain shadow-md"
onError={(e) => (e.currentTarget.src = "./icons/broadcast.svg")}
/>
<img
src={`${ARTIFACT_URL}/${artifactTypeFromName(artifact.type)}.png`}
alt={artifact.name}
width={128}
height={128}
className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 rounded"
style={{
objectFit: "contain" as const,
transition: "filter 0.1s linear",
boxShadow: getSpriteImageStyle(artifact).boxShadow,
}}
onError={(e) => (e.currentTarget.src = "./icons/broadcast.svg")}
/>
</div>

<div className="absolute bottom-1/4 left-1/2 w-full -translate-x-1/2 translate-y-1/2 text-center">
<ArtifactRarityLabelAnim rarity={rarity} />
<h2 className="text-sm font-bold text-white drop-shadow-md">
{hexToDecimal(artifact.name.slice(10))}
</h2>
<p className="text-gray-700">{artifact.description}</p>
<p className="text-sm text-gray-500">
Owner: {artifact.owner.slice(0, 6)}...{artifact.owner.slice(-4)}
</p>
</div>

<div className="flex -translate-y-1/2 items-center justify-center text-center">
<MarketLink
href={`https://opensea.io/item/base/0x14a11b17105cc70f154f84ede21e9b08dd832577/${hexToDecimal(artifact.name.slice(10))}`}
imgSrc="https://opensea.io/static/images/logos/opensea-logo.svg"
/>
<MarketLink
href={`https://rarible.com/token/base/0x14a11b17105cc70f154f84ede21e9b08dd832577:${hexToDecimal(artifact.name.slice(10))}`}
imgSrc="../public/img/markets/rarible.png"
/>
</div>

<div className="text-4xl font-bold text-white">
<div className="absolute left-0 top-1/2 -translate-y-1/2 transform transition-transform duration-200 hover:scale-110 hover:text-gray-300">
<button
onClick={onPrev}
className="p-2 text-white hover:text-gray-300"
>
&#8592;
</button>{" "}
</div>
<div className="absolute right-0 top-1/2 -translate-y-1/2 transform transition-transform duration-200 hover:scale-110 hover:text-gray-300">
<button onClick={onNext} className="p-2 hover:text-gray-300">
&#8594;
</button>{" "}
</div>
</div>
</div>
</div>
);
}
Loading
Loading