diff --git a/packages/hardhat/contracts/Game.sol b/packages/hardhat/contracts/Game.sol
index ba911094..715573bd 100644
--- a/packages/hardhat/contracts/Game.sol
+++ b/packages/hardhat/contracts/Game.sol
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.24;
+import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol";
import { ResourceId, WorldResourceIdLib, WorldResourceIdInstance } from "@latticexyz/world/src/WorldResourceId.sol";
import { Hook } from "@latticexyz/store/src/Hook.sol";
@@ -10,58 +11,249 @@ import { IOptionalSystemHook } from "@latticexyz/world/src/IOptionalSystemHook.s
import { BEFORE_CALL_SYSTEM, AFTER_CALL_SYSTEM, ALL } from "@latticexyz/world/src/systemHookTypes.sol";
import { RESOURCE_SYSTEM } from "@latticexyz/world/src/worldResourceTypes.sol";
import { OptionalSystemHooks } from "@latticexyz/world/src/codegen/tables/OptionalSystemHooks.sol";
+import { hasBeforeAndAfterSystemHook, getEntityAtCoord, getEntityFromPlayer, getPosition, getIsLoggedOff, getPlayerFromEntity } from "../utils/EntityUtils.sol";
import { IWorld } from "@biomesaw/world/src/codegen/world/IWorld.sol";
import { VoxelCoord } from "@biomesaw/utils/src/Types.sol";
+import { decodeCallData } from "../utils/HookUtils.sol";
+import { weiToString } from "../utils/GameUtils.sol";
-contract Game is ICustomUnregisterDelegation, IOptionalSystemHook {
- address public immutable biomeWorldAddress;
+struct LeaderboardEntry {
+ address player;
+ uint256 balance;
+}
+
+struct PlayerBalance {
+ address player;
+ uint256 balance;
+}
- address public delegatorAddress;
+struct PlayerWithdrawal {
+ address player;
+ uint256 lastWithdrawal;
+}
+
+struct PlayerHitter {
+ address player;
+ address lastHitter;
+}
+
+contract Game is IOptionalSystemHook {
+ address public immutable biomeWorldAddress;
event GameNotif(address player, string message);
- constructor(address _biomeWorldAddress, address _delegatorAddress) {
+ constructor(address _biomeWorldAddress) {
biomeWorldAddress = _biomeWorldAddress;
-
- // Set the store address, so that when reading from MUD tables in the
- // Biomes world, we don't need to pass the store address every time.
StoreSwitch.setStoreAddress(_biomeWorldAddress);
+ }
+
+ address[] public players;
+ mapping(address => uint256) public balance;
+ mapping(address => uint256) public lastWithdrawal;
+ mapping(address => address) public lastHitter;
+
+ ResourceId HitSystemId = WorldResourceIdLib.encode({ typeId: RESOURCE_SYSTEM, namespace: "", name: "HitSystem" });
+ ResourceId LogoffSystemId =
+ WorldResourceIdLib.encode({ typeId: RESOURCE_SYSTEM, namespace: "", name: "LogoffSystem" });
+ ResourceId SpawnSystemId = WorldResourceIdLib.encode({ typeId: RESOURCE_SYSTEM, namespace: "", name: "SpawnSystem" });
+
+ function isPlayerRegistered(address player) public view returns (bool) {
+ for (uint i = 0; i < players.length; i++) {
+ if (players[i] == player) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ function removePlayer(address player) internal {
+ for (uint i = 0; i < players.length; i++) {
+ if (players[i] == player) {
+ players[i] = players[players.length - 1];
+ players.pop();
+ return;
+ }
+ }
+ }
+
+ function registerPlayer() external payable {
+ require(msg.value >= 0.00035 ether, "Must send atleast minimum ETH to register");
+
+ address player = msg.sender;
+ require(
+ hasBeforeAndAfterSystemHook(address(this), player, HitSystemId),
+ "The player hasn't allowed the hit hook yet"
+ );
+ require(
+ hasBeforeAndAfterSystemHook(address(this), player, LogoffSystemId),
+ "The player hasn't allowed the logoff hook yet"
+ );
+ require(
+ hasBeforeAndAfterSystemHook(address(this), player, SpawnSystemId),
+ "The player hasn't allowed the spawn hook yet"
+ );
+
+ require(!isPlayerRegistered(player), "Player is already registered");
+
+ players.push(player);
+ balance[player] = msg.value;
+ lastWithdrawal[player] = block.timestamp;
+ lastHitter[player] = address(0);
- delegatorAddress = _delegatorAddress;
+ emit GameNotif(address(0), string.concat("Player ", Strings.toHexString(player), " has joined the game"));
+ }
+
+ function withdraw() external {
+ address player = msg.sender;
+ require(isPlayerRegistered(player), "You are not a registered player.");
+ require(lastWithdrawal[player] + 2 hours < block.timestamp, "Can't withdraw yet.");
+
+ uint256 amount = balance[player];
+ require(amount > 0, "Your balance is zero.");
+
+ removePlayer(player);
+ balance[player] = 0;
+ lastWithdrawal[player] = block.timestamp;
+ lastHitter[player] = address(0);
+
+ // Safe transfer of funds
+ (bool sent, ) = player.call{ value: amount }("");
+ require(sent, "Failed to send Ether");
}
- // Use this modifier to restrict access to the Biomes World contract only
- // eg. for hooks that are only allowed to be called by the Biomes World contract
modifier onlyBiomeWorld() {
require(msg.sender == biomeWorldAddress, "Caller is not the Biomes World contract");
_; // Continue execution
}
function supportsInterface(bytes4 interfaceId) external view override returns (bool) {
- return
- interfaceId == type(ICustomUnregisterDelegation).interfaceId ||
- interfaceId == type(IOptionalSystemHook).interfaceId ||
- interfaceId == type(IERC165).interfaceId;
- }
-
- function canUnregister(address delegator) external override onlyBiomeWorld returns (bool) {
- return true;
+ return interfaceId == type(IOptionalSystemHook).interfaceId || interfaceId == type(IERC165).interfaceId;
}
- function onRegisterHook(
+ function onUnregisterHook(
address msgSender,
ResourceId systemId,
uint8 enabledHooksBitmap,
bytes32 callDataHash
- ) external override onlyBiomeWorld {}
+ ) external override onlyBiomeWorld {
+ uint256 playerBalance = balance[msgSender];
+ address recipient = lastHitter[msgSender];
+ removePlayer(msgSender);
- function onUnregisterHook(
+ if (playerBalance > 0) {
+ balance[msgSender] = 0;
+ if (recipient == address(0)) {
+ (bool sent, ) = msgSender.call{ value: playerBalance }("");
+ require(sent, "Failed to send Ether");
+ } else {
+ balance[recipient] += playerBalance;
+ lastHitter[msgSender] = address(0);
+ }
+ }
+ }
+
+ function onAfterCallSystem(
+ address msgSender,
+ ResourceId systemId,
+ bytes memory callData
+ ) external override onlyBiomeWorld {
+ if (!isPlayerRegistered(msgSender)) {
+ return;
+ }
+
+ if (ResourceId.unwrap(systemId) == ResourceId.unwrap(LogoffSystemId)) {
+ require(false, "Cannot logoff when registered.");
+ return;
+ } else if (ResourceId.unwrap(systemId) == ResourceId.unwrap(SpawnSystemId)) {
+ uint256 playerBalance = balance[msgSender];
+ if (playerBalance == 0) {
+ return;
+ }
+
+ address recipient = lastHitter[msgSender];
+ balance[msgSender] = 0;
+
+ removePlayer(msgSender);
+
+ if (recipient == address(0)) {
+ (bool sent, ) = msgSender.call{ value: playerBalance }("");
+ require(sent, "Failed to send Ether");
+ } else {
+ balance[recipient] += playerBalance;
+ lastHitter[msgSender] = address(0);
+ }
+ } else if (ResourceId.unwrap(systemId) == ResourceId.unwrap(HitSystemId)) {
+ (, bytes memory callDataArgs) = decodeCallData(callData);
+ address hitPlayer = abi.decode(callDataArgs, (address));
+
+ if (isPlayerRegistered(hitPlayer)) {
+ lastHitter[hitPlayer] = msgSender;
+
+ bytes32 hitPlayerEntity = getEntityFromPlayer(hitPlayer);
+ if (hitPlayerEntity == bytes32(0)) {
+ uint256 hitPlayerBalance = balance[hitPlayer];
+ balance[hitPlayer] = 0;
+ balance[msgSender] += hitPlayerBalance;
+ removePlayer(hitPlayer);
+ }
+ }
+ }
+ }
+
+ function getRegisteredPlayers() external view returns (address[] memory) {
+ return players;
+ }
+
+ function getBalancesLeaderboard() external view returns (LeaderboardEntry[] memory) {
+ LeaderboardEntry[] memory leaderboard = new LeaderboardEntry[](players.length);
+ for (uint256 i = 0; i < players.length; i++) {
+ leaderboard[i] = LeaderboardEntry({ player: players[i], balance: balance[players[i]] });
+ }
+
+ return leaderboard;
+ }
+
+ function getRegisteredPlayerEntityIds() external view returns (bytes32[] memory) {
+ bytes32[] memory registeredPlayerEntityIds = new bytes32[](players.length);
+ for (uint i = 0; i < players.length; i++) {
+ registeredPlayerEntityIds[i] = getEntityFromPlayer(players[i]);
+ }
+ return registeredPlayerEntityIds;
+ }
+
+ function getAllBalances() public view returns (PlayerBalance[] memory playerBalances) {
+ playerBalances = new PlayerBalance[](players.length);
+ for (uint256 i = 0; i < players.length; i++) {
+ playerBalances[i] = PlayerBalance(players[i], balance[players[i]]);
+ }
+ }
+
+ function getAllLastWithdrawals() public view returns (PlayerWithdrawal[] memory playerWithdrawals) {
+ playerWithdrawals = new PlayerWithdrawal[](players.length);
+ for (uint256 i = 0; i < players.length; i++) {
+ playerWithdrawals[i] = PlayerWithdrawal(players[i], lastWithdrawal[players[i]]);
+ }
+ }
+
+ function getAllLastHitters() public view returns (PlayerHitter[] memory playerLastHitters) {
+ playerLastHitters = new PlayerHitter[](players.length);
+ for (uint256 i = 0; i < players.length; i++) {
+ playerLastHitters[i] = PlayerHitter(players[i], lastHitter[players[i]]);
+ }
+ }
+
+ function onRegisterHook(
address msgSender,
ResourceId systemId,
uint8 enabledHooksBitmap,
bytes32 callDataHash
- ) external override onlyBiomeWorld {}
+ ) external override onlyBiomeWorld {
+ require(
+ getEntityFromPlayer(msgSender) != bytes32(0),
+ "You Must First Spawn An Avatar In Biome-1 To Play The Game."
+ );
+ }
function onBeforeCallSystem(
address msgSender,
@@ -69,17 +261,55 @@ contract Game is ICustomUnregisterDelegation, IOptionalSystemHook {
bytes memory callData
) external override onlyBiomeWorld {}
- function onAfterCallSystem(
- address msgSender,
- ResourceId systemId,
- bytes memory callData
- ) external override onlyBiomeWorld {}
+ function getDisplayName() external view returns (string memory) {
+ return "Bounty Hunter";
+ }
- function basicGetter() external view returns (uint256) {
- return 42;
+ function getAvatars() external view returns (address[] memory) {
+ return players;
}
- function getRegisteredPlayers() external view returns (address[] memory) {
- return new address[](0);
+ function getStatus() external view returns (string memory) {
+ if (!isPlayerRegistered(msg.sender)) {
+ return "You are not registered yet.";
+ }
+
+ uint256 playerBalanceWei = balance[msg.sender];
+ address recipient = lastHitter[msg.sender];
+ bool canWithdraw = lastWithdrawal[msg.sender] + 2 hours < block.timestamp;
+
+ return
+ string.concat(
+ "Your balance is ",
+ weiToString(playerBalanceWei),
+ " ether and your last hitter is ",
+ recipient != address(0) ? Strings.toHexString(recipient) : "no one",
+ canWithdraw ? ". You may withdraw!" : ". See countdown for next withdrawal."
+ );
+ }
+
+ function getUnregisterMessage() external view returns (string memory) {
+ if (!isPlayerRegistered(msg.sender)) {
+ return "";
+ }
+
+ uint256 playerBalance = balance[msg.sender];
+ address recipient = lastHitter[msg.sender];
+
+ if (playerBalance > 0) {
+ if (recipient == address(0)) {
+ return "You have unclaimed balance. You will be unregistered and the balance will be sent to you.";
+ } else {
+ return "You have unclaimed balance. You will be unregistered and the balance will be sent to your last hitter.";
+ }
+ }
+ }
+
+ function getCountdownEndTimestamp() external view returns (uint256) {
+ if (!isPlayerRegistered(msg.sender)) {
+ return 0;
+ }
+
+ return lastWithdrawal[msg.sender] + 2 hours;
}
}
diff --git a/packages/hardhat/deploy/00_deploy_game.ts b/packages/hardhat/deploy/00_deploy_game.ts
index 322eef8e..51412fb7 100644
--- a/packages/hardhat/deploy/00_deploy_game.ts
+++ b/packages/hardhat/deploy/00_deploy_game.ts
@@ -49,7 +49,7 @@ const deployGameContract: DeployFunction = async function (hre: HardhatRuntimeEn
await deploy("Game", {
from: deployer,
// Contract constructor arguments
- args: [useBiomesWorldAddress, "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266"],
+ args: [useBiomesWorldAddress],
log: true,
// autoMine: can be passed to the deploy function to make the deployment process faster on local networks by
// automatically mining the contract deployment transaction. There is no effect on live networks.
diff --git a/packages/nextjs/.firebaserc b/packages/nextjs/.firebaserc
new file mode 100644
index 00000000..5bd33d43
--- /dev/null
+++ b/packages/nextjs/.firebaserc
@@ -0,0 +1,5 @@
+{
+ "projects": {
+ "default": "biomes-bounty-hunter"
+ }
+}
diff --git a/packages/nextjs/app/debug/_components/contract/utilsDisplay.tsx b/packages/nextjs/app/debug/_components/contract/utilsDisplay.tsx
index 49df7359..2cbb858c 100644
--- a/packages/nextjs/app/debug/_components/contract/utilsDisplay.tsx
+++ b/packages/nextjs/app/debug/_components/contract/utilsDisplay.tsx
@@ -22,7 +22,7 @@ export interface Area {
interface LeaderboardEntry {
player: string;
- kills: bigint;
+ balance: bigint;
}
function BuildComponent({ build }: { build: Build | BuildWithPos }) {
@@ -116,9 +116,9 @@ function AreaComponent({ area }: { area: Area }) {
function LeaderboardComponent({ leaderboard }: { leaderboard: LeaderboardEntry[] }) {
const sortedLeaderboard = leaderboard.sort((a, b) => {
- if (a.kills > b.kills) {
+ if (a.balance > b.balance) {
return -1;
- } else if (a.kills < b.kills) {
+ } else if (a.balance < b.balance) {
return 1;
} else {
return 0;
@@ -131,14 +131,14 @@ function LeaderboardComponent({ leaderboard }: { leaderboard: LeaderboardEntry[]
Player
- Kills
+ Balance
{sortedLeaderboard.map((entry, index) => (
{displayTxResult(entry.player)}
- {entry.kills.toString()}
+ {formatEther(entry.balance) + " Ξ"}
))}
@@ -227,11 +227,11 @@ export function isValidArea(area: DisplayContent | DisplayContent[]) {
}
export function isLeaderboardEntry(entry: DisplayContent | DisplayContent[]) {
- // Checks if entry has the correct structure for address and numKills
+ // Checks if entry has the correct structure for address and balance
if (entry === undefined || entry === null) return false;
if (typeof entry !== "object") return false;
- return isAddress(entry.player) && typeof entry.kills === "bigint";
+ return isAddress(entry.player) && typeof entry.balance === "bigint";
}
export function isLeaderboard(leaderboard: DisplayContent | DisplayContent[]) {
diff --git a/packages/nextjs/app/page.tsx b/packages/nextjs/app/page.tsx
index d24f87f5..b6ad148d 100644
--- a/packages/nextjs/app/page.tsx
+++ b/packages/nextjs/app/page.tsx
@@ -17,7 +17,8 @@ const Home: NextPage = () => {
const isBiomesRegistered = useGlobalState(({ isBiomesRegistered }) => isBiomesRegistered);
const isGameRegistered = useGlobalState(({ isGameRegistered }) => isGameRegistered);
- const isBiomesClientSetup = useGlobalState(({ isBiomesClientSetup }) => isBiomesClientSetup);
+ // const isBiomesClientSetup = useGlobalState(({ isBiomesClientSetup }) => isBiomesClientSetup);
+ const isBiomesClientSetup = true;
useEffect(() => {
if (connectedAddress) {
diff --git a/packages/nextjs/components/Game.tsx b/packages/nextjs/components/Game.tsx
index 4ad2a72d..a2c5a1ea 100644
--- a/packages/nextjs/components/Game.tsx
+++ b/packages/nextjs/components/Game.tsx
@@ -1,8 +1,11 @@
import { useReducer } from "react";
+import Link from "next/link";
import { Abi, AbiFunction } from "abitype";
+import { formatEther } from "viem";
import { useAccount } from "wagmi";
-import { DisplayVariable, displayTxResult } from "~~/app/debug/_components/contract";
+import { DisplayVariable, WriteOnlyFunctionForm, displayTxResult } from "~~/app/debug/_components/contract";
import { useDeployedContractInfo } from "~~/hooks/scaffold-eth";
+import { useGlobalState } from "~~/services/store/store";
import { GenericContract, InheritedFunctions } from "~~/utils/scaffold-eth/contract";
export const Game: React.FC = ({}) => {
@@ -10,6 +13,8 @@ export const Game: React.FC = ({}) => {
const [refreshDisplayVariables] = useReducer(value => !value, false);
const { data: deployedContractData, isLoading: deployedContractLoading } = useDeployedContractInfo("Game");
+ const setIsBiomesClientSetup = useGlobalState(({ setIsBiomesClientSetup }) => setIsBiomesClientSetup);
+
if (connectedAddress === undefined) {
return Connect your wallet to continue
;
}
@@ -32,13 +37,50 @@ export const Game: React.FC = ({}) => {
})
.sort((a, b) => (b.inheritedFrom ? b.inheritedFrom.localeCompare(a.inheritedFrom) : 1));
- const basicGetterFn = viewFunctions.find(({ fn }) => fn.name === "basicGetter");
+ const writeFunctions = ((deployedContractData.abi as Abi).filter(part => part.type === "function") as AbiFunction[])
+ .filter(fn => {
+ const isWriteableFunction =
+ fn.stateMutability !== "view" &&
+ fn.stateMutability !== "pure" &&
+ fn.name !== "onAfterCallSystem" &&
+ fn.name !== "onBeforeCallSystem" &&
+ fn.name !== "onRegisterHook" &&
+ fn.name !== "onUnregisterHook" &&
+ fn.name !== "canUnregister";
+ return isWriteableFunction;
+ })
+ .map(fn => {
+ return {
+ fn,
+ inheritedFrom: ((deployedContractData as GenericContract)?.inheritedFunctions as InheritedFunctions)?.[fn.name],
+ };
+ })
+ .sort((a, b) => (b.inheritedFrom ? b.inheritedFrom.localeCompare(a.inheritedFrom) : 1));
+
+ const registeredPlayersGetter = viewFunctions.find(({ fn }) => fn.name === "getRegisteredPlayerEntityIds");
+ const balancesGetter = viewFunctions.find(({ fn }) => fn.name === "getAllBalances");
+ const withdrawalsGetter = viewFunctions.find(({ fn }) => fn.name === "getAllLastWithdrawals");
+ const hittersGetter = viewFunctions.find(({ fn }) => fn.name === "getAllLastHitters");
+ const leaderboardGetter = viewFunctions.find(({ fn }) => fn.name === "getBalancesLeaderboard");
+
+ const withdrawFunction = writeFunctions.find(fn => fn.fn.name === "withdraw");
+
+ if (
+ balancesGetter === undefined ||
+ withdrawalsGetter === undefined ||
+ hittersGetter === undefined ||
+ registeredPlayersGetter === undefined ||
+ leaderboardGetter === undefined ||
+ withdrawFunction === undefined
+ ) {
+ return Missing required functions
;
+ }
return (
- Play in{" "}
+ Kill participating avatars in{" "}
{
>
Biomes
{" "}
+ to get their ether. Stay alive to keep it. View & withdraw your earnings here.
diff --git a/packages/nextjs/components/HowToPlay.tsx b/packages/nextjs/components/HowToPlay.tsx
index da4210d3..cc6faab5 100644
--- a/packages/nextjs/components/HowToPlay.tsx
+++ b/packages/nextjs/components/HowToPlay.tsx
@@ -15,8 +15,45 @@ export const HowToPlayComponent: React.FC = ({}) => {
- Your Instructions Here
+ 1. View Participating Avatars
+
+
+
+
+
+
+
+
+ 2. Hit Them
+
+
+
+
+
+
+
+
+
+ 3. Withdraw Your Earnings... If You Survive
+
+
+
If a participating avatar dies and you hit them last, you get their ether.
+
If you survive, withdraw your earned ether every 2 hours.
+
);
diff --git a/packages/nextjs/components/Landing.tsx b/packages/nextjs/components/Landing.tsx
index dba0f692..b787ea7f 100644
--- a/packages/nextjs/components/Landing.tsx
+++ b/packages/nextjs/components/Landing.tsx
@@ -45,9 +45,9 @@ export const Landing: React.FC = ({}) => {
-
Your Game Title
+
Bounty Hunter
- Your game description
+ Kill players to get their ether. Stay alive to keep it.
{
}}
className="mt-4"
>
- Your Game Image
+
diff --git a/packages/nextjs/components/RegisterBiomes.tsx b/packages/nextjs/components/RegisterBiomes.tsx
index 2174bf5a..4392b483 100644
--- a/packages/nextjs/components/RegisterBiomes.tsx
+++ b/packages/nextjs/components/RegisterBiomes.tsx
@@ -7,7 +7,7 @@ import { useTargetNetwork } from "~~/hooks/scaffold-eth/useTargetNetwork";
import { useGlobalState } from "~~/services/store/store";
import { getAllContracts } from "~~/utils/scaffold-eth/contractsData";
-const GameRequiredHooks: string[] = ["LogoffSystem"];
+const GameRequiredHooks: string[] = ["LogoffSystem", "SpawnSystem", "HitSystem"];
export const RegisterBiomes: React.FC = ({}) => {
const { address: connectedAddress } = useAccount();
@@ -87,7 +87,9 @@ export const RegisterBiomes: React.FC = ({}) => {
HOOKS
{
Join Game
- Your Register Game Description
+ Deposit 0.00035 ETH to register your player. If anyone kills your player, they will get this eth. If you
+ kill other players, you will get their eth.
@@ -109,19 +110,14 @@ export const RegisterGame: React.FC = ({}) => {
contractAddress={deployedContractData.address}
abi={deployedContractData.abi as Abi}
functionName={registerPlayFunctionData.fn.name}
- value={"0.0015"}
+ value={"0.00035"}
onWrite={(txnReceipt: TransactionReceipt) => {
console.log("txnReceipt", txnReceipt);
checkPlayerRegistered();
}}
/>
) : (
-
setIsGameRegistered(true)}
- >
- Mock Game Register
-
+
Register function not found
)}
) : (
diff --git a/packages/nextjs/contracts/deployedContracts.ts b/packages/nextjs/contracts/deployedContracts.ts
index 51929f1a..9b6e80ee 100644
--- a/packages/nextjs/contracts/deployedContracts.ts
+++ b/packages/nextjs/contracts/deployedContracts.ts
@@ -7,7 +7,7 @@ import { GenericContractsDeclaration } from "~~/utils/scaffold-eth/contract";
const deployedContracts = {
690: {
Game: {
- address: "0x09F61e35b34EB7855fb234dc81109d774Bb16973",
+ address: "0x4941Bf9a1B5EAFEde0e311140BD6b05a86C9908f",
abi: [
{
inputs: [
@@ -16,15 +16,31 @@ const deployedContracts = {
name: "_biomeWorldAddress",
type: "address",
},
- {
- internalType: "address",
- name: "_delegatorAddress",
- type: "address",
- },
],
stateMutability: "nonpayable",
type: "constructor",
},
+ {
+ inputs: [
+ {
+ internalType: "bytes",
+ name: "data",
+ type: "bytes",
+ },
+ {
+ internalType: "uint256",
+ name: "start",
+ type: "uint256",
+ },
+ {
+ internalType: "uint256",
+ name: "end",
+ type: "uint256",
+ },
+ ],
+ name: "Slice_OutOfBounds",
+ type: "error",
+ },
{
anonymous: false,
inputs: [
@@ -45,8 +61,14 @@ const deployedContracts = {
type: "event",
},
{
- inputs: [],
- name: "basicGetter",
+ inputs: [
+ {
+ internalType: "address",
+ name: "",
+ type: "address",
+ },
+ ],
+ name: "balance",
outputs: [
{
internalType: "uint256",
@@ -70,15 +92,206 @@ const deployedContracts = {
stateMutability: "view",
type: "function",
},
+ {
+ inputs: [],
+ name: "getAllBalances",
+ outputs: [
+ {
+ components: [
+ {
+ internalType: "address",
+ name: "player",
+ type: "address",
+ },
+ {
+ internalType: "uint256",
+ name: "balance",
+ type: "uint256",
+ },
+ ],
+ internalType: "struct PlayerBalance[]",
+ name: "playerBalances",
+ type: "tuple[]",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [],
+ name: "getAllLastHitters",
+ outputs: [
+ {
+ components: [
+ {
+ internalType: "address",
+ name: "player",
+ type: "address",
+ },
+ {
+ internalType: "address",
+ name: "lastHitter",
+ type: "address",
+ },
+ ],
+ internalType: "struct PlayerHitter[]",
+ name: "playerLastHitters",
+ type: "tuple[]",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [],
+ name: "getAllLastWithdrawals",
+ outputs: [
+ {
+ components: [
+ {
+ internalType: "address",
+ name: "player",
+ type: "address",
+ },
+ {
+ internalType: "uint256",
+ name: "lastWithdrawal",
+ type: "uint256",
+ },
+ ],
+ internalType: "struct PlayerWithdrawal[]",
+ name: "playerWithdrawals",
+ type: "tuple[]",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [],
+ name: "getAvatars",
+ outputs: [
+ {
+ internalType: "address[]",
+ name: "",
+ type: "address[]",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [],
+ name: "getBalancesLeaderboard",
+ outputs: [
+ {
+ components: [
+ {
+ internalType: "address",
+ name: "player",
+ type: "address",
+ },
+ {
+ internalType: "uint256",
+ name: "balance",
+ type: "uint256",
+ },
+ ],
+ internalType: "struct LeaderboardEntry[]",
+ name: "",
+ type: "tuple[]",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [],
+ name: "getCountdownEndTimestamp",
+ outputs: [
+ {
+ internalType: "uint256",
+ name: "",
+ type: "uint256",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [],
+ name: "getDisplayName",
+ outputs: [
+ {
+ internalType: "string",
+ name: "",
+ type: "string",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [],
+ name: "getRegisteredPlayerEntityIds",
+ outputs: [
+ {
+ internalType: "bytes32[]",
+ name: "",
+ type: "bytes32[]",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [],
+ name: "getRegisteredPlayers",
+ outputs: [
+ {
+ internalType: "address[]",
+ name: "",
+ type: "address[]",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [],
+ name: "getStatus",
+ outputs: [
+ {
+ internalType: "string",
+ name: "",
+ type: "string",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [],
+ name: "getUnregisterMessage",
+ outputs: [
+ {
+ internalType: "string",
+ name: "",
+ type: "string",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
{
inputs: [
{
internalType: "address",
- name: "delegator",
+ name: "player",
type: "address",
},
],
- name: "canUnregister",
+ name: "isPlayerRegistered",
outputs: [
{
internalType: "bool",
@@ -86,12 +299,18 @@ const deployedContracts = {
type: "bool",
},
],
- stateMutability: "nonpayable",
+ stateMutability: "view",
type: "function",
},
{
- inputs: [],
- name: "delegatorAddress",
+ inputs: [
+ {
+ internalType: "address",
+ name: "",
+ type: "address",
+ },
+ ],
+ name: "lastHitter",
outputs: [
{
internalType: "address",
@@ -103,13 +322,19 @@ const deployedContracts = {
type: "function",
},
{
- inputs: [],
- name: "getRegisteredPlayers",
+ inputs: [
+ {
+ internalType: "address",
+ name: "",
+ type: "address",
+ },
+ ],
+ name: "lastWithdrawal",
outputs: [
{
- internalType: "address[]",
+ internalType: "uint256",
name: "",
- type: "address[]",
+ type: "uint256",
},
],
stateMutability: "view",
@@ -217,6 +442,32 @@ const deployedContracts = {
stateMutability: "nonpayable",
type: "function",
},
+ {
+ inputs: [
+ {
+ internalType: "uint256",
+ name: "",
+ type: "uint256",
+ },
+ ],
+ name: "players",
+ outputs: [
+ {
+ internalType: "address",
+ name: "",
+ type: "address",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [],
+ name: "registerPlayer",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
{
inputs: [
{
@@ -225,75 +476,417 @@ const deployedContracts = {
type: "bytes4",
},
],
- name: "supportsInterface",
+ name: "supportsInterface",
+ outputs: [
+ {
+ internalType: "bool",
+ name: "",
+ type: "bool",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [],
+ name: "withdraw",
+ outputs: [],
+ stateMutability: "nonpayable",
+ type: "function",
+ },
+ ],
+ inheritedFunctions: {
+ onAfterCallSystem: "@latticexyz/world/src/IOptionalSystemHook.sol",
+ onBeforeCallSystem: "@latticexyz/world/src/IOptionalSystemHook.sol",
+ onRegisterHook: "@latticexyz/world/src/IOptionalSystemHook.sol",
+ onUnregisterHook: "@latticexyz/world/src/IOptionalSystemHook.sol",
+ supportsInterface: "@latticexyz/world/src/IOptionalSystemHook.sol",
+ },
+ },
+ },
+ 17069: {
+ Game: {
+ address: "0x25074032327f9a4ec7A8c193c310234AF6Ca62De",
+ abi: [
+ {
+ inputs: [
+ {
+ internalType: "address",
+ name: "_biomeWorldAddress",
+ type: "address",
+ },
+ {
+ components: [
+ {
+ internalType: "int16",
+ name: "x",
+ type: "int16",
+ },
+ {
+ internalType: "int16",
+ name: "y",
+ type: "int16",
+ },
+ {
+ internalType: "int16",
+ name: "z",
+ type: "int16",
+ },
+ ],
+ internalType: "struct VoxelCoord",
+ name: "lowerSouthwestCorner",
+ type: "tuple",
+ },
+ {
+ components: [
+ {
+ internalType: "int16",
+ name: "x",
+ type: "int16",
+ },
+ {
+ internalType: "int16",
+ name: "y",
+ type: "int16",
+ },
+ {
+ internalType: "int16",
+ name: "z",
+ type: "int16",
+ },
+ ],
+ internalType: "struct VoxelCoord",
+ name: "size",
+ type: "tuple",
+ },
+ {
+ internalType: "address",
+ name: "_gameStarter",
+ type: "address",
+ },
+ ],
+ stateMutability: "nonpayable",
+ type: "constructor",
+ },
+ {
+ inputs: [
+ {
+ internalType: "bytes",
+ name: "data",
+ type: "bytes",
+ },
+ {
+ internalType: "uint256",
+ name: "start",
+ type: "uint256",
+ },
+ {
+ internalType: "uint256",
+ name: "end",
+ type: "uint256",
+ },
+ ],
+ name: "Slice_OutOfBounds",
+ type: "error",
+ },
+ {
+ anonymous: false,
+ inputs: [
+ {
+ indexed: false,
+ internalType: "address",
+ name: "player",
+ type: "address",
+ },
+ {
+ indexed: false,
+ internalType: "string",
+ name: "message",
+ type: "string",
+ },
+ ],
+ name: "GameNotif",
+ type: "event",
+ },
+ {
+ inputs: [],
+ name: "biomeWorldAddress",
+ outputs: [
+ {
+ internalType: "address",
+ name: "",
+ type: "address",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [],
+ name: "claimRewardPool",
+ outputs: [],
+ stateMutability: "nonpayable",
+ type: "function",
+ },
+ {
+ inputs: [],
+ name: "gameEndBlock",
+ outputs: [
+ {
+ internalType: "uint256",
+ name: "",
+ type: "uint256",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [],
+ name: "gameStarter",
+ outputs: [
+ {
+ internalType: "address",
+ name: "",
+ type: "address",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [],
+ name: "getAlivePlayers",
+ outputs: [
+ {
+ internalType: "address[]",
+ name: "",
+ type: "address[]",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [],
+ name: "getAreas",
+ outputs: [
+ {
+ components: [
+ {
+ internalType: "string",
+ name: "name",
+ type: "string",
+ },
+ {
+ components: [
+ {
+ components: [
+ {
+ internalType: "int16",
+ name: "x",
+ type: "int16",
+ },
+ {
+ internalType: "int16",
+ name: "y",
+ type: "int16",
+ },
+ {
+ internalType: "int16",
+ name: "z",
+ type: "int16",
+ },
+ ],
+ internalType: "struct VoxelCoord",
+ name: "lowerSouthwestCorner",
+ type: "tuple",
+ },
+ {
+ components: [
+ {
+ internalType: "int16",
+ name: "x",
+ type: "int16",
+ },
+ {
+ internalType: "int16",
+ name: "y",
+ type: "int16",
+ },
+ {
+ internalType: "int16",
+ name: "z",
+ type: "int16",
+ },
+ ],
+ internalType: "struct VoxelCoord",
+ name: "size",
+ type: "tuple",
+ },
+ ],
+ internalType: "struct Area",
+ name: "area",
+ type: "tuple",
+ },
+ ],
+ internalType: "struct NamedArea[]",
+ name: "",
+ type: "tuple[]",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [],
+ name: "getAvatars",
+ outputs: [
+ {
+ internalType: "address[]",
+ name: "",
+ type: "address[]",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [],
+ name: "getCountdownEndBlock",
+ outputs: [
+ {
+ internalType: "uint256",
+ name: "",
+ type: "uint256",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [],
+ name: "getDeadPlayers",
+ outputs: [
+ {
+ internalType: "address[]",
+ name: "",
+ type: "address[]",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [],
+ name: "getDisplayName",
outputs: [
{
- internalType: "bool",
+ internalType: "string",
name: "",
- type: "bool",
+ type: "string",
},
],
stateMutability: "view",
type: "function",
},
- ],
- inheritedFunctions: {
- canUnregister: "@latticexyz/world/src/ICustomUnregisterDelegation.sol",
- supportsInterface: "@latticexyz/world/src/IOptionalSystemHook.sol",
- onAfterCallSystem: "@latticexyz/world/src/IOptionalSystemHook.sol",
- onBeforeCallSystem: "@latticexyz/world/src/IOptionalSystemHook.sol",
- onRegisterHook: "@latticexyz/world/src/IOptionalSystemHook.sol",
- onUnregisterHook: "@latticexyz/world/src/IOptionalSystemHook.sol",
- },
- },
- },
- 17069: {
- Game: {
- address: "0xaFFFd91f427b81e0e56be9A4b6369f8DE6f24994",
- abi: [
{
- inputs: [
- {
- internalType: "address",
- name: "_biomeWorldAddress",
- type: "address",
- },
+ inputs: [],
+ name: "getDisqualifiedPlayers",
+ outputs: [
{
- internalType: "address",
- name: "_delegatorAddress",
- type: "address",
+ internalType: "address[]",
+ name: "",
+ type: "address[]",
},
],
- stateMutability: "nonpayable",
- type: "constructor",
+ stateMutability: "view",
+ type: "function",
},
{
- anonymous: false,
- inputs: [
- {
- indexed: false,
- internalType: "address",
- name: "player",
- type: "address",
- },
+ inputs: [],
+ name: "getKillsLeaderboard",
+ outputs: [
{
- indexed: false,
- internalType: "string",
- name: "message",
- type: "string",
+ components: [
+ {
+ internalType: "address",
+ name: "player",
+ type: "address",
+ },
+ {
+ internalType: "bool",
+ name: "isAlive",
+ type: "bool",
+ },
+ {
+ internalType: "uint256",
+ name: "kills",
+ type: "uint256",
+ },
+ ],
+ internalType: "struct LeaderboardEntry[]",
+ name: "",
+ type: "tuple[]",
},
],
- name: "GameNotif",
- type: "event",
+ stateMutability: "view",
+ type: "function",
},
{
inputs: [],
- name: "basicGetter",
+ name: "getMatchArea",
outputs: [
{
- internalType: "uint256",
+ components: [
+ {
+ components: [
+ {
+ internalType: "int16",
+ name: "x",
+ type: "int16",
+ },
+ {
+ internalType: "int16",
+ name: "y",
+ type: "int16",
+ },
+ {
+ internalType: "int16",
+ name: "z",
+ type: "int16",
+ },
+ ],
+ internalType: "struct VoxelCoord",
+ name: "lowerSouthwestCorner",
+ type: "tuple",
+ },
+ {
+ components: [
+ {
+ internalType: "int16",
+ name: "x",
+ type: "int16",
+ },
+ {
+ internalType: "int16",
+ name: "y",
+ type: "int16",
+ },
+ {
+ internalType: "int16",
+ name: "z",
+ type: "int16",
+ },
+ ],
+ internalType: "struct VoxelCoord",
+ name: "size",
+ type: "tuple",
+ },
+ ],
+ internalType: "struct Area",
name: "",
- type: "uint256",
+ type: "tuple",
},
],
stateMutability: "view",
@@ -301,44 +894,51 @@ const deployedContracts = {
},
{
inputs: [],
- name: "biomeWorldAddress",
+ name: "getRegisteredPlayerEntityIds",
outputs: [
{
- internalType: "address",
+ internalType: "bytes32[]",
name: "",
- type: "address",
+ type: "bytes32[]",
},
],
stateMutability: "view",
type: "function",
},
{
- inputs: [
+ inputs: [],
+ name: "getRewardPool",
+ outputs: [
{
- internalType: "address",
- name: "delegator",
- type: "address",
+ internalType: "uint256",
+ name: "",
+ type: "uint256",
},
],
- name: "canUnregister",
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [],
+ name: "getStatus",
outputs: [
{
- internalType: "bool",
+ internalType: "string",
name: "",
- type: "bool",
+ type: "string",
},
],
- stateMutability: "nonpayable",
+ stateMutability: "view",
type: "function",
},
{
inputs: [],
- name: "delegatorAddress",
+ name: "getUnregisterMessage",
outputs: [
{
- internalType: "address",
+ internalType: "string",
name: "",
- type: "address",
+ type: "string",
},
],
stateMutability: "view",
@@ -346,12 +946,12 @@ const deployedContracts = {
},
{
inputs: [],
- name: "getRegisteredPlayers",
+ name: "isGameStarted",
outputs: [
{
- internalType: "address[]",
+ internalType: "bool",
name: "",
- type: "address[]",
+ type: "bool",
},
],
stateMutability: "view",
@@ -459,6 +1059,78 @@ const deployedContracts = {
stateMutability: "nonpayable",
type: "function",
},
+ {
+ inputs: [],
+ name: "registerPlayer",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ components: [
+ {
+ internalType: "int16",
+ name: "x",
+ type: "int16",
+ },
+ {
+ internalType: "int16",
+ name: "y",
+ type: "int16",
+ },
+ {
+ internalType: "int16",
+ name: "z",
+ type: "int16",
+ },
+ ],
+ internalType: "struct VoxelCoord",
+ name: "lowerSouthwestCorner",
+ type: "tuple",
+ },
+ {
+ components: [
+ {
+ internalType: "int16",
+ name: "x",
+ type: "int16",
+ },
+ {
+ internalType: "int16",
+ name: "y",
+ type: "int16",
+ },
+ {
+ internalType: "int16",
+ name: "z",
+ type: "int16",
+ },
+ ],
+ internalType: "struct VoxelCoord",
+ name: "size",
+ type: "tuple",
+ },
+ ],
+ name: "setMatchArea",
+ outputs: [],
+ stateMutability: "nonpayable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint256",
+ name: "numBlocksToEnd",
+ type: "uint256",
+ },
+ ],
+ name: "startGame",
+ outputs: [],
+ stateMutability: "nonpayable",
+ type: "function",
+ },
{
inputs: [
{
@@ -480,18 +1152,17 @@ const deployedContracts = {
},
],
inheritedFunctions: {
- canUnregister: "@latticexyz/world/src/ICustomUnregisterDelegation.sol",
- supportsInterface: "@latticexyz/world/src/IOptionalSystemHook.sol",
onAfterCallSystem: "@latticexyz/world/src/IOptionalSystemHook.sol",
onBeforeCallSystem: "@latticexyz/world/src/IOptionalSystemHook.sol",
onRegisterHook: "@latticexyz/world/src/IOptionalSystemHook.sol",
onUnregisterHook: "@latticexyz/world/src/IOptionalSystemHook.sol",
+ supportsInterface: "@latticexyz/world/src/IOptionalSystemHook.sol",
},
},
},
31337: {
Game: {
- address: "0xddE78e6202518FF4936b5302cC2891ec180E8bFf",
+ address: "0x9385556B571ab92bf6dC9a0DbD75429Dd4d56F91",
abi: [
{
inputs: [
@@ -509,6 +1180,27 @@ const deployedContracts = {
stateMutability: "nonpayable",
type: "constructor",
},
+ {
+ inputs: [
+ {
+ internalType: "bytes",
+ name: "data",
+ type: "bytes",
+ },
+ {
+ internalType: "uint256",
+ name: "start",
+ type: "uint256",
+ },
+ {
+ internalType: "uint256",
+ name: "end",
+ type: "uint256",
+ },
+ ],
+ name: "Slice_OutOfBounds",
+ type: "error",
+ },
{
anonymous: false,
inputs: [
@@ -529,15 +1221,21 @@ const deployedContracts = {
type: "event",
},
{
- inputs: [],
- name: "basicGetter",
- outputs: [
+ inputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
+ name: "allowedItemDrops",
+ outputs: [
+ {
+ internalType: "address",
+ name: "",
+ type: "address",
+ },
+ ],
stateMutability: "view",
type: "function",
},
@@ -573,6 +1271,25 @@ const deployedContracts = {
stateMutability: "nonpayable",
type: "function",
},
+ {
+ inputs: [
+ {
+ internalType: "bytes32",
+ name: "",
+ type: "bytes32",
+ },
+ ],
+ name: "coordHashToBuilder",
+ outputs: [
+ {
+ internalType: "address",
+ name: "",
+ type: "address",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
{
inputs: [],
name: "delegatorAddress",
@@ -586,9 +1303,22 @@ const deployedContracts = {
stateMutability: "view",
type: "function",
},
+ {
+ inputs: [
+ {
+ internalType: "bytes32",
+ name: "toolEntityId",
+ type: "bytes32",
+ },
+ ],
+ name: "dropItem",
+ outputs: [],
+ stateMutability: "nonpayable",
+ type: "function",
+ },
{
inputs: [],
- name: "getRegisteredPlayers",
+ name: "getAllowedItemDrops",
outputs: [
{
internalType: "address[]",
@@ -599,6 +1329,171 @@ const deployedContracts = {
stateMutability: "view",
type: "function",
},
+ {
+ inputs: [],
+ name: "getBuild",
+ outputs: [
+ {
+ components: [
+ {
+ internalType: "uint8[]",
+ name: "objectTypeIds",
+ type: "uint8[]",
+ },
+ {
+ components: [
+ {
+ internalType: "int16",
+ name: "x",
+ type: "int16",
+ },
+ {
+ internalType: "int16",
+ name: "y",
+ type: "int16",
+ },
+ {
+ internalType: "int16",
+ name: "z",
+ type: "int16",
+ },
+ ],
+ internalType: "struct VoxelCoord[]",
+ name: "relativePositions",
+ type: "tuple[]",
+ },
+ ],
+ internalType: "struct Build",
+ name: "",
+ type: "tuple",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [],
+ name: "getBuilds",
+ outputs: [
+ {
+ components: [
+ {
+ internalType: "string",
+ name: "name",
+ type: "string",
+ },
+ {
+ components: [
+ {
+ internalType: "uint8[]",
+ name: "objectTypeIds",
+ type: "uint8[]",
+ },
+ {
+ components: [
+ {
+ internalType: "int16",
+ name: "x",
+ type: "int16",
+ },
+ {
+ internalType: "int16",
+ name: "y",
+ type: "int16",
+ },
+ {
+ internalType: "int16",
+ name: "z",
+ type: "int16",
+ },
+ ],
+ internalType: "struct VoxelCoord[]",
+ name: "relativePositions",
+ type: "tuple[]",
+ },
+ ],
+ internalType: "struct Build",
+ name: "build",
+ type: "tuple",
+ },
+ ],
+ internalType: "struct NamedBuild[]",
+ name: "",
+ type: "tuple[]",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [],
+ name: "getDisplayName",
+ outputs: [
+ {
+ internalType: "string",
+ name: "",
+ type: "string",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [],
+ name: "getStatus",
+ outputs: [
+ {
+ internalType: "string",
+ name: "",
+ type: "string",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [],
+ name: "getUnregisterMessage",
+ outputs: [
+ {
+ internalType: "string",
+ name: "",
+ type: "string",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ components: [
+ {
+ internalType: "int16",
+ name: "x",
+ type: "int16",
+ },
+ {
+ internalType: "int16",
+ name: "y",
+ type: "int16",
+ },
+ {
+ internalType: "int16",
+ name: "z",
+ type: "int16",
+ },
+ ],
+ internalType: "struct VoxelCoord",
+ name: "baseWorldCoord",
+ type: "tuple",
+ },
+ ],
+ name: "matchBuild",
+ outputs: [],
+ stateMutability: "nonpayable",
+ type: "function",
+ },
{
inputs: [
{
@@ -701,6 +1596,41 @@ const deployedContracts = {
stateMutability: "nonpayable",
type: "function",
},
+ {
+ inputs: [
+ {
+ internalType: "uint8[]",
+ name: "objectTypeIds",
+ type: "uint8[]",
+ },
+ {
+ components: [
+ {
+ internalType: "int16",
+ name: "x",
+ type: "int16",
+ },
+ {
+ internalType: "int16",
+ name: "y",
+ type: "int16",
+ },
+ {
+ internalType: "int16",
+ name: "z",
+ type: "int16",
+ },
+ ],
+ internalType: "struct VoxelCoord[]",
+ name: "relativePositions",
+ type: "tuple[]",
+ },
+ ],
+ name: "setBuild",
+ outputs: [],
+ stateMutability: "nonpayable",
+ type: "function",
+ },
{
inputs: [
{
@@ -733,4 +1663,4 @@ const deployedContracts = {
},
} as const;
-export default deployedContracts satisfies GenericContractsDeclaration;
+export default deployedContracts satisfies GenericContractsDeclaration;
\ No newline at end of file
diff --git a/packages/nextjs/firebase.json b/packages/nextjs/firebase.json
new file mode 100644
index 00000000..c5c52092
--- /dev/null
+++ b/packages/nextjs/firebase.json
@@ -0,0 +1,10 @@
+{
+ "hosting": {
+ "public": "out",
+ "ignore": [
+ "firebase.json",
+ "**/.*",
+ "**/node_modules/**"
+ ]
+ }
+}
diff --git a/packages/nextjs/package.json b/packages/nextjs/package.json
index 3e8833eb..3abaf2d2 100644
--- a/packages/nextjs/package.json
+++ b/packages/nextjs/package.json
@@ -11,7 +11,8 @@
"format": "prettier --write . '!(node_modules|.next|contracts)/**/*'",
"check-types": "tsc --noEmit --incremental",
"vercel": "vercel",
- "vercel:yolo": "vercel --build-env NEXT_PUBLIC_IGNORE_BUILD_ERROR=true"
+ "vercel:yolo": "vercel --build-env NEXT_PUBLIC_IGNORE_BUILD_ERROR=true",
+ "deploy": "NEXT_PUBLIC_IGNORE_BUILD_ERROR=true yarn run build && firebase use biomes-bounty-hunter && firebase deploy"
},
"dependencies": {
"@biomesaw/utils": "0.0.8",
diff --git a/packages/nextjs/public/bountyhunter.png b/packages/nextjs/public/bountyhunter.png
new file mode 100644
index 00000000..a0607297
Binary files /dev/null and b/packages/nextjs/public/bountyhunter.png differ