Skip to content

Commit

Permalink
Merge branch 'next' of github.com:BibliothecaDAO/eternum into feat/us…
Browse files Browse the repository at this point in the history
…e-controller-presets
  • Loading branch information
edisontim committed Dec 11, 2024
2 parents 2efb1d9 + bbfe2b6 commit 2411f7f
Show file tree
Hide file tree
Showing 279 changed files with 5,419 additions and 7,364 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules
target
.snfoundry_cache
.snfoundry_cache
docs/dist
2 changes: 1 addition & 1 deletion client/.env.local.sample
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ VITE_REALMS_ADDRESS=0x755683a990769aad84fa4127bfc8dfa685d4f4fd751bd43e47ca46ff72
VITE_LORDS_ADDRESS=0x5a4cee7e1bfee8a41f884cbdcb17f051ca7cd46bbd5598f91c01887b2f83ee6

VITE_VRF_PROVIDER_ADDRESS="0x0"
VITE_CLIENT_FEE_RECIPIENT=0x045c587318c9ebcf2fbe21febf288ee2e3597a21cd48676005a5770a50d433c5
VITE_PUBLIC_CLIENT_FEE_RECIPIENT=0x045c587318c9ebcf2fbe21febf288ee2e3597a21cd48676005a5770a50d433c5
8 changes: 4 additions & 4 deletions client/.env.preview
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@ VITE_PUBLIC_MASTER_PRIVATE_KEY=0x075362a844768f31c8058ce31aec3dd7751686440b4f220
VITE_PUBLIC_WORLD_ADDRESS="0x00fd85ef42eaed3b90d02d2cdc7417d6cae189ff4ba876aa5608551afbf1fb47"
VITE_PUBLIC_ACCOUNT_CLASS_HASH="0x07dc7899aa655b0aae51eadff6d801a58e97dd99cf4666ee59e704249e51adf2"
VITE_PUBLIC_FEE_TOKEN_ADDRESS=0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7
VITE_PUBLIC_TORII=https://api.cartridge.gg/x/sepolia-rc-16/torii
VITE_PUBLIC_TORII=https://api.cartridge.gg/x/sepolia-rc-17/torii
VITE_PUBLIC_NODE_URL=https://api.cartridge.gg/x/starknet/sepolia
VITE_PUBLIC_DEV=false
VITE_PUBLIC_GAME_VERSION="v1.0.0-rc7"
VITE_PUBLIC_SHOW_FPS=false
VITE_PUBLIC_GRAPHICS_DEV=false
VITE_PUBLIC_TORII_RELAY=/dns4/api.cartridge.gg/tcp/443/x-parity-wss/%2Fx%2Fsepolia-rc-16%2Ftorii%2Fwss
VITE_PUBLIC_TORII_RELAY=/dns4/api.cartridge.gg/tcp/443/x-parity-wss/%2Fx%2Fsepolia-rc-17%2Ftorii%2Fwss
VITE_SEASON_PASS_ADDRESS=0x23cc88996a5f9c7bcb559fdcffc257c0f75abe60f2a7e5d5cd343f8a95967f7
VITE_REALMS_ADDRESS=0x3205f47bd6f0b5e9cd5c79fcae19e12523a024709776d0a9e8b375adf63468d
VITE_LORDS_ADDRESS=0x0342ad5cc14002c005a5cedcfce2bd3af98d5e7fb79e9bf949b3a91cf145d72e

VITE_PUBLIC_CHAIN=sepolia
VITE_PUBLIC_SLOT=sepolia-rc-16
VITE_PUBLIC_SLOT=sepolia-rc-17

VITE_PUBLIC_CONSTRUCTION_FLAG=false
VITE_PUBLIC_HIDE_THREEJS_MENU=false
Expand All @@ -26,4 +26,4 @@ VITE_PUBLIC_IMAGE_PROXY_URL=https://abc.com
VITE_PUBLIC_IPFS_GATEWAY=https://abc.com

VITE_VRF_PROVIDER_ADDRESS="0x051fea4450da9d6aee758bdeba88b2f665bcbf549d2c61421aa724e9ac0ced8f"
VITE_CLIENT_FEE_RECIPIENT=0x045c587318c9ebcf2fbe21febf288ee2e3597a21cd48676005a5770a50d433c5
VITE_PUBLIC_CLIENT_FEE_RECIPIENT=0x045c587318c9ebcf2fbe21febf288ee2e3597a21cd48676005a5770a50d433c5
2 changes: 1 addition & 1 deletion client/.env.production
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ VITE_PUBLIC_IMAGE_PROXY_URL=https://abc.com
VITE_PUBLIC_IPFS_GATEWAY=https://abc.com

VITE_VRF_PROVIDER_ADDRESS="0x051fea4450da9d6aee758bdeba88b2f665bcbf549d2c61421aa724e9ac0ced8f"
VITE_CLIENT_FEE_RECIPIENT=0x045c587318c9ebcf2fbe21febf288ee2e3597a21cd48676005a5770a50d433c5
VITE_PUBLIC_CLIENT_FEE_RECIPIENT=0x045c587318c9ebcf2fbe21febf288ee2e3597a21cd48676005a5770a50d433c5
7 changes: 6 additions & 1 deletion client/dojoConfig.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { createDojoConfig } from "@dojoengine/core";
import devManifest from "../contracts/manifest_dev.json";
import mainnetManifest from "../contracts/manifest_mainnet.json";
import productionManifest from "../contracts/manifest_prod.json";

import { env } from "./env";
const {
VITE_PUBLIC_NODE_URL,
Expand All @@ -11,9 +13,12 @@ const {
VITE_PUBLIC_ACCOUNT_CLASS_HASH,
VITE_PUBLIC_DEV,
VITE_PUBLIC_FEE_TOKEN_ADDRESS,
VITE_PUBLIC_CHAIN,
} = env;

const manifest = VITE_PUBLIC_DEV === true ? devManifest : productionManifest;
let manifest = VITE_PUBLIC_DEV === true ? devManifest : productionManifest;

manifest = VITE_PUBLIC_CHAIN === "mainnet" ? mainnetManifest : manifest;

export const dojoConfig = createDojoConfig({
rpcUrl: VITE_PUBLIC_NODE_URL,
Expand Down
2 changes: 1 addition & 1 deletion client/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const envSchema = z.object({
VITE_PUBLIC_ACCOUNT_CLASS_HASH: z.string().startsWith("0x"),
VITE_PUBLIC_FEE_TOKEN_ADDRESS: z.string().startsWith("0x"),

VITE_CLIENT_FEE_RECIPIENT: z.string().startsWith("0x"),
VITE_PUBLIC_CLIENT_FEE_RECIPIENT: z.string().startsWith("0x"),

// External Contracts
VITE_SEASON_PASS_ADDRESS: z.string().startsWith("0x"),
Expand Down
Binary file added client/public/images/Eternum-Mark-Black.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified client/public/images/apple-touch-icon-180x180.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified client/public/images/favicon.ico
Binary file not shown.
Binary file modified client/public/images/maskable-icon-512x512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified client/public/images/pwa-192x192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified client/public/images/pwa-512x512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified client/public/images/pwa-64x64.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/public/models/buildings-opt/wonder.glb
Binary file not shown.
Binary file added client/public/models/buildings-opt/wonder2.glb
Binary file not shown.
2 changes: 1 addition & 1 deletion client/pwa-assets.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ import { defineConfig, minimal2023Preset } from "@vite-pwa/assets-generator/conf

export default defineConfig({
preset: minimal2023Preset,
images: ["public/images/oroborus.png"],
images: ["public/images/Eternum-Mark-Black.png"],
});
2 changes: 2 additions & 0 deletions client/src/dojo/createClientComponents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ export function createClientComponents({ contractComponents }: SetupNetworkResul
Population: overridableComponent(contractComponents.Population),
Resource: overridableComponent(contractComponents.Resource),
Weight: overridableComponent(contractComponents.Weight),
OwnedResourcesTracker: overridableComponent(contractComponents.OwnedResourcesTracker),
Army: overridableComponent(contractComponents.Army),
BuildingQuantityv2: overridableComponent(contractComponents.BuildingQuantityv2),
Structure: overridableComponent(contractComponents.Structure),
ArrivalTime: overridableComponent(contractComponents.ArrivalTime),
};
}
14 changes: 14 additions & 0 deletions client/src/dojo/modelManager/ArmyMovementManager.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useAccountStore } from "@/hooks/context/accountStore";
import useUIStore from "@/hooks/store/useUIStore";
import { type HexPosition } from "@/types";
import { FELT_CENTER } from "@/ui/config";
import {
Expand Down Expand Up @@ -263,12 +264,23 @@ export class ArmyMovementManager {
});
};

private readonly _optimisticArrivalTimeUpdate = (overrideId: string) => {
this.setup.components.ArrivalTime.addOverride(overrideId, {
entity: this.entity,
value: {
entity_id: this.entityId,
arrives_at: BigInt(useUIStore.getState().nextBlockTimestamp || 0),
},
});
};

private readonly _optimisticExplore = (col: number, row: number, currentArmiesTick: number) => {
const overrideId = uuid();

this._optimisticStaminaUpdate(overrideId, configManager.getExploreStaminaCost(), currentArmiesTick);
this._optimisticTileUpdate(overrideId, col, row);
this._optimisticPositionUpdate(overrideId, col, row);
this._optimisticArrivalTimeUpdate(overrideId);
this._optimisticCapacityUpdate(
overrideId,
// all resources you can find have the same weight as wood
Expand Down Expand Up @@ -315,6 +327,7 @@ export class ArmyMovementManager {

this._optimisticStaminaUpdate(overrideId, configManager.getTravelStaminaCost() * pathLength, currentArmiesTick);
this._optimisticFoodCosts(overrideId, TravelTypes.Travel);
this._optimisticArrivalTimeUpdate(overrideId);

this.setup.components.Position.addOverride(overrideId, {
entity: this.entity,
Expand All @@ -338,6 +351,7 @@ export class ArmyMovementManager {
this.setup.components.Stamina.removeOverride(overrideId);
this.setup.components.Resource.removeOverride(overrideId);
this.setup.components.Weight.removeOverride(overrideId);
this.setup.components.ArrivalTime.removeOverride(overrideId);
};

private readonly _optimisticFoodCosts = (overrideId: string, travelType: TravelTypes) => {
Expand Down
20 changes: 19 additions & 1 deletion client/src/dojo/modelManager/BattleManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ArmyInfo } from "@/hooks/helpers/useArmies";
import { Structure } from "@/hooks/helpers/useStructures";
import { Health } from "@/types";
import { multiplyByPrecision } from "@/ui/utils/utils";
import { BattleSide, EternumGlobalConfig, ID } from "@bibliothecadao/eternum";
import { BattleSide, EternumGlobalConfig, ID, MIN_TROOPS_BATTLE } from "@bibliothecadao/eternum";
import {
ComponentValue,
Components,
Expand Down Expand Up @@ -38,6 +38,7 @@ export enum RaidStatus {
OwnStructure = "Can't raid your own structure",
NoArmy = "No army selected",
ArmyNotInBattle = "Selected army not in this battle",
MinTroops = "Minimum 100 troops required",
}

export enum LeaveStatus {
Expand All @@ -48,6 +49,7 @@ export enum LeaveStatus {
}

export enum BattleStartStatus {
MinTroops = "Minimum 100 troops required",
BattleStart = "Start battle",
ForceStart = "Force start",
NothingToAttack = "Nothing to attack",
Expand Down Expand Up @@ -312,6 +314,13 @@ export class BattleManager {

if (structure.isMine) return RaidStatus.OwnStructure;

// Calculate total troops
const totalTroops = selectedArmy.troops
? Object.values(selectedArmy.troops).reduce((sum, count) => sum + Number(count), 0)
: 0;

if (totalTroops < MIN_TROOPS_BATTLE) return RaidStatus.MinTroops;

const staminaManager = new StaminaManager(this.dojo.setup, selectedArmy.entity_id);
if (staminaManager.getStamina(currentArmiesTick).amount === 0) return RaidStatus.NoStamina;

Expand All @@ -323,6 +332,15 @@ export class BattleManager {
defender: ArmyInfo | undefined,
currentTimestamp: number,
): BattleStartStatus {
if (!selectedArmy) return BattleStartStatus.NothingToAttack;

// Calculate total troops
const totalTroops = selectedArmy.troops
? Object.values(selectedArmy.troops).reduce((sum, count) => sum + Number(count), 0)
: 0;

if (totalTroops < MIN_TROOPS_BATTLE) return BattleStartStatus.MinTroops;

if (!defender) return BattleStartStatus.NothingToAttack;

if (!this.isBattle() && defender.health.current > 0n) return BattleStartStatus.BattleStart;
Expand Down
7 changes: 4 additions & 3 deletions client/src/dojo/modelManager/LeaderboardManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
TickIds,
WORLD_CONFIG_ID,
} from "@bibliothecadao/eternum";
import { Entity, getComponentValue, HasValue, runQuery } from "@dojoengine/recs";
import { Entity, HasValue, getComponentValue, runQuery } from "@dojoengine/recs";
import { getEntityIdFromKeys } from "@dojoengine/utils";
import { configManager } from "../setup";
import { ClientConfigManager } from "./ConfigManager";
Expand All @@ -33,15 +33,16 @@ export class LeaderboardManager {
);
if (!hyperstructure) return;

const epochIndex = hyperstructure.current_epoch - 1 >= 0 ? hyperstructure.current_epoch - 1 : 0;
const currentEpoch = getComponentValue(
this.dojoResult.setup.components.Epoch,
getEntityIdFromKeys([BigInt(hyperstructureEntityId), BigInt(hyperstructure.current_epoch)]),
getEntityIdFromKeys([BigInt(hyperstructureEntityId), BigInt(epochIndex)]),
);
if (!currentEpoch) return;

const coOwners = (currentEpoch.owners as any).map((owner: any) => {
let [owner_address, percentage] = owner.value.map((value: any) => value.value);
return { address: owner_address, percentage: Number(percentage) / 10_000 };
return { address: ContractAddress(owner_address), percentage: Number(percentage) };
});

return { coOwners, timestamp: Number(currentEpoch.start_timestamp) };
Expand Down
84 changes: 21 additions & 63 deletions client/src/dojo/modelManager/ResourceInventoryManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import { uuid } from "@latticexyz/utils";
import { type SetupResult } from "../setup";

export class ResourceInventoryManager {
entityId: ID;
carrierEntityId: ID;

constructor(
private readonly setup: SetupResult,
entityId: ID,
carrierEntityId: ID,
) {
this.entityId = entityId;
this.carrierEntityId = carrierEntityId;
}

private readonly _optimisticOffloadAll = (
Expand All @@ -21,27 +21,38 @@ export class ResourceInventoryManager {
inventoryResources: Resource[],
) => {
inventoryResources.forEach((resource) => {
const entity = getEntityIdFromKeys([BigInt(receiverEntityId), BigInt(resource.resourceId)]);
const receiverBalance = getComponentValue(this.setup.components.Resource, entity)?.balance || 0n;
const receiveResourceEntity = getEntityIdFromKeys([BigInt(receiverEntityId), BigInt(resource.resourceId)]);
const receiverBalance = getComponentValue(this.setup.components.Resource, receiveResourceEntity)?.balance || 0n;

// optimistically update the balance of the receiver
this.setup.components.Resource.addOverride(overrideId, {
entity,
entity: receiveResourceEntity,
value: {
entity_id: receiverEntityId,
resource_type: resource.resourceId,
balance: receiverBalance + BigInt(resource.amount),
},
});
});

const entity = getEntityIdFromKeys([BigInt(this.entityId)]);
const carrierEntity = getEntityIdFromKeys([BigInt(this.carrierEntityId)]);

this.setup.components.Weight.addOverride(overrideId, {
entity,
entity: carrierEntity,
value: {
entity_id: this.carrierEntityId,
value: 0n,
},
});

// need to update this for the arrivals list to get updated
this.setup.components.OwnedResourcesTracker.addOverride(overrideId, {
entity: carrierEntity,
value: {
entity_id: this.carrierEntityId,
resource_types: 0n,
},
});
};

public onOffloadAll = async (receiverEntityId: ID, inventoryResources: Resource[]) => {
Expand All @@ -51,69 +62,16 @@ export class ResourceInventoryManager {
if (inventoryResources.length > 0) {
await this.setup.systemCalls
.send_resources({
sender_entity_id: this.entityId,
sender_entity_id: this.carrierEntityId,
recipient_entity_id: receiverEntityId,
resources: inventoryResources.flatMap((resource) => [resource.resourceId, resource.amount]),
signer: useAccountStore.getState().account!,
})
.finally(() => {
this.setup.components.Resource.removeOverride(overrideId);
this.setup.components.Weight.removeOverride(overrideId);
this.setup.components.OwnedResourcesTracker.removeOverride(overrideId);
});
}
};

public onOffloadAllMultiple = async (
transfers: {
senderEntityId: ID;
recipientEntityId: ID;
resources: Resource[];
}[],
) => {
const overrideId = uuid();

// Apply optimistic updates for each transfer
transfers.forEach((transfer) => {
transfer.resources.forEach((resource) => {
const recipientEntity = getEntityIdFromKeys([BigInt(transfer.recipientEntityId), BigInt(resource.resourceId)]);
const recipientBalance = getComponentValue(this.setup.components.Resource, recipientEntity)?.balance || 0n;

this.setup.components.Resource.addOverride(overrideId, {
entity: recipientEntity,
value: {
resource_type: resource.resourceId,
balance: recipientBalance + BigInt(resource.amount),
},
});
});

// Reset weight for sender
const senderEntity = getEntityIdFromKeys([BigInt(transfer.senderEntityId)]);
this.setup.components.Weight.addOverride(overrideId, {
entity: senderEntity,
value: {
value: 0n,
},
});
});

try {
await this.setup.systemCalls.send_resources_multiple({
calls: transfers.map((transfer) => ({
sender_entity_id: transfer.senderEntityId,
recipient_entity_id: transfer.recipientEntityId,
resources: transformResources(transfer.resources),
})),
signer: useAccountStore.getState().account!,
});
} finally {
// Clean up overrides
this.setup.components.Resource.removeOverride(overrideId);
this.setup.components.Weight.removeOverride(overrideId);
}
};
}

const transformResources = (resources: Resource[]) => {
return resources.flatMap((resource) => [resource.resourceId, resource.amount]);
};
6 changes: 6 additions & 0 deletions client/src/dojo/modelManager/TileManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ export class TileManager {
return (realm?.level || RealmLevels.Settlement) as RealmLevels;
};

getWonder = () => {
const realmEntityId = useUIStore.getState().structureEntityId;
const realm = getComponentValue(this.setup.components.Realm, getEntityIdFromKeys([BigInt(realmEntityId)]));
return realm?.has_wonder || false;
};

existingBuildings = () => {
const builtBuildings = Array.from(
runQuery([
Expand Down
Loading

0 comments on commit 2411f7f

Please sign in to comment.