Skip to content

Commit 7233661

Browse files
authored
feat: trade resources (#543)
* impl Mul<MarketFee> for Gold * set_fee * set_fee * store * cheat set vault * sell_resources * withdraw_resources_up_to * withdraw_resources * sell * test * destructure * sum * buy * test * endpoints * dprint * request * deps * MarketImpl * MarketPrice * scene * fix buy * market
1 parent b92dad1 commit 7233661

56 files changed

Lines changed: 1233 additions & 226 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.npmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ignore-scripts=true

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/src-tauri/src/command/cheat/market.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,17 @@ pub async fn cheat_set_market_fee(app: AppHandle, req: CheatSetMarketFeeRequest)
1313
.await
1414
.map_err(Into::into)
1515
}
16+
17+
#[tauri::command]
18+
pub async fn cheat_set_market_vault_resources(
19+
app: AppHandle,
20+
req: CheatSetMarketVaultResourcesRequest,
21+
) -> Result<()> {
22+
app
23+
.client(async |cl| {
24+
cl.cheat_set_market_vault_resources(req)
25+
.await
26+
})
27+
.await
28+
.map_err(Into::into)
29+
}

app/src-tauri/src/command/market.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ use nil_payload::request::market::*;
77
use nil_payload::response::market::*;
88
use tauri::AppHandle;
99

10+
#[tauri::command]
11+
pub async fn buy_resources(app: AppHandle, req: BuyResourcesRequest) -> Result<()> {
12+
app
13+
.client(async |cl| cl.buy_resources(req).await)
14+
.await
15+
.map_err(Into::into)
16+
}
17+
1018
#[tauri::command]
1119
pub async fn get_market(app: AppHandle, req: GetMarketRequest) -> Result<GetMarketResponse> {
1220
app
@@ -26,6 +34,14 @@ pub async fn get_market_fee(
2634
.map_err(Into::into)
2735
}
2836

37+
#[tauri::command]
38+
pub async fn sell_resources(app: AppHandle, req: SellResourcesRequest) -> Result<()> {
39+
app
40+
.client(async |cl| cl.sell_resources(req).await)
41+
.await
42+
.map_err(Into::into)
43+
}
44+
2945
#[tauri::command]
3046
pub async fn send_resources(app: AppHandle, req: SendResourcesRequest) -> Result<()> {
3147
app

app/src-tauri/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ pub fn run() {
7272
command::cheat::infrastructure::cheat_set_building_level,
7373
command::cheat::infrastructure::cheat_set_max_infrastructure,
7474
command::cheat::market::cheat_set_market_fee,
75+
command::cheat::market::cheat_set_market_vault_resources,
7576
command::cheat::military::cheat_get_idle_armies_at,
7677
command::cheat::military::cheat_get_idle_personnel_at,
7778
command::cheat::military::cheat_get_maneuvers,
@@ -125,8 +126,10 @@ pub fn run() {
125126
command::infrastructure::workshop::add_workshop_recruit_order,
126127
command::infrastructure::workshop::cancel_workshop_recruit_order,
127128
command::infrastructure::workshop::get_workshop_recruit_catalog,
129+
command::market::buy_resources,
128130
command::market::get_market,
129131
command::market::get_market_fee,
132+
command::market::sell_resources,
130133
command::market::send_resources,
131134
command::military::cancel_maneuver,
132135
command::military::get_armies,

app/src/commands/cheat/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
export * from "./npc";
55
export * from "./city";
66
export * from "./round";
7+
export * from "./market";
78
export * from "./player";
89
export * from "./behavior";
910
export * from "./military";

app/src/commands/cheat/market.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22
// SPDX-License-Identifier: AGPL-3.0-only
33

44
import { invoke } from "@tauri-apps/api/core";
5-
import type { CheatSetMarketFeeRequest, MarketFee } from "@tsukilabs/nil-bindings";
5+
import type {
6+
CheatSetMarketFeeRequest,
7+
CheatSetMarketVaultResourcesRequest,
8+
MarketFee,
9+
Resources,
10+
} from "@tsukilabs/nil-bindings";
611

712
export async function cheatSetMarketFee(fee: MarketFee) {
813
const req: CheatSetMarketFeeRequest = {
@@ -11,5 +16,13 @@ export async function cheatSetMarketFee(fee: MarketFee) {
1116
};
1217

1318
await invoke("cheat_set_market_fee", { req });
14-
await NIL.world.updateConfig();
19+
}
20+
21+
export async function cheatSetMarketVaultResources(resources: Resources) {
22+
const req: CheatSetMarketVaultResourcesRequest = {
23+
world: NIL.world.getIdStrict(),
24+
resources,
25+
};
26+
27+
await invoke("cheat_set_market_vault_resources", { req });
1528
}

app/src/commands/market.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,26 @@
33

44
import { invoke } from "@tauri-apps/api/core";
55
import type {
6+
BuyResourcesRequest,
67
GetMarketFeeRequest,
78
GetMarketFeeResponse,
89
GetMarketRequest,
910
GetMarketResponse,
1011
Resources,
1112
Ruler,
13+
SellResourcesRequest,
1214
SendResourcesRequest,
1315
} from "@tsukilabs/nil-bindings";
1416

17+
export async function buyResources(resources: Resources) {
18+
const req: BuyResourcesRequest = {
19+
world: NIL.world.getIdStrict(),
20+
resources,
21+
};
22+
23+
await invoke("buy_resources", { req });
24+
}
25+
1526
export async function getMarket() {
1627
const req: GetMarketRequest = {
1728
world: NIL.world.getIdStrict(),
@@ -28,6 +39,15 @@ export async function getMarketFee() {
2839
return invoke<GetMarketFeeResponse>("get_market_fee", { req });
2940
}
3041

42+
export async function sellResources(resources: Resources) {
43+
const req: SellResourcesRequest = {
44+
world: NIL.world.getIdStrict(),
45+
resources,
46+
};
47+
48+
await invoke("sell_resources", { req });
49+
}
50+
3151
export async function sendResources(recipient: Ruler, resources: Resources) {
3252
const req: SendResourcesRequest = {
3353
world: NIL.world.getIdStrict(),
Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,47 @@
11
// Copyright (C) Call of Nil contributors
22
// SPDX-License-Identifier: AGPL-3.0-only
33

4-
import { asyncRef } from "@tb-dev/vue";
4+
import { computed } from "vue";
5+
import { throttle } from "es-toolkit/function";
6+
import { asyncRef, useMutex } from "@tb-dev/vue";
57
import { MarketImpl } from "@/core/model/market/market";
8+
import type { Resources, Ruler } from "@tsukilabs/nil-bindings";
69

710
export function useMarket() {
811
const market = asyncRef(null, () => MarketImpl.load());
12+
const throttledLoad = throttle(market.load, 1000);
13+
14+
const { locked, lock } = useMutex();
15+
16+
const loading = computed(() => {
17+
return market.loading.value || locked.value;
18+
});
19+
20+
async function buyResources(resources: Resources) {
21+
await lock(async () => {
22+
await market.state.value?.buy(resources);
23+
});
24+
}
25+
26+
async function sellResources(resources: Resources) {
27+
await lock(async () => {
28+
await market.state.value?.sell(resources);
29+
});
30+
}
31+
32+
async function sendResources(recipient: Ruler, resources: Resources) {
33+
await lock(async () => {
34+
await market.state.value?.send(recipient, resources);
35+
});
36+
}
937

1038
return {
1139
market: market.state,
12-
loading: market.loading,
40+
loading,
1341
load: market.load,
42+
throttledLoad,
43+
buyResources,
44+
sellResources,
45+
sendResources,
1446
};
1547
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright (C) Call of Nil contributors
2+
// SPDX-License-Identifier: AGPL-3.0-only
3+
4+
import type { DeepReadonly } from "es-toolkit/types";
5+
import type { Gold, MarketPrice } from "@tsukilabs/nil-bindings";
6+
7+
export class MarketPriceImpl implements DeepReadonly<MarketPrice> {
8+
public readonly food: Gold;
9+
public readonly iron: Gold;
10+
public readonly stone: Gold;
11+
public readonly wood: Gold;
12+
13+
private constructor(price: MarketPrice) {
14+
this.food = price.food;
15+
this.iron = price.iron;
16+
this.stone = price.stone;
17+
this.wood = price.wood;
18+
}
19+
20+
public static create(price: MarketPrice) {
21+
if (price instanceof MarketPriceImpl) {
22+
return price;
23+
}
24+
25+
return new MarketPriceImpl(price);
26+
}
27+
}

0 commit comments

Comments
 (0)