Skip to content

Commit

Permalink
feat: adds support for searching transport town markets
Browse files Browse the repository at this point in the history
  • Loading branch information
jmgilman committed May 24, 2024
1 parent dbb6334 commit 4a418fd
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 31 deletions.
4 changes: 2 additions & 2 deletions pymerc/game/player.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from pymerc.game.exports import ExportsList, ExportsSummed
from pymerc.game.imports import ImportsList, ImportsSummed
from pymerc.game.town import Town
from pymerc.game.transport import Transport
from pymerc.game.transport import Transport, TransportList

if TYPE_CHECKING:
from pymerc.client import Client
Expand Down Expand Up @@ -51,7 +51,7 @@ async def load(self):
if self.business.transport_ids:
for id in self.business.transport_ids:
tasks.append(self._client.transport(id))
self.transports = await asyncio.gather(*tasks)
self.transports = TransportList(await asyncio.gather(*tasks))

for transport in self.transports:
for item, exp in transport.exports.items():
Expand Down
44 changes: 19 additions & 25 deletions pymerc/game/town.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import math
from typing import TYPE_CHECKING, Optional

from pymerc.api.models import common
from pymerc.api.models import towns as models
from pymerc.api.models.map import Region

if TYPE_CHECKING:
from pymerc.client import Client
Expand All @@ -19,24 +19,24 @@ def __init__(self, client: Client, id: int):

async def load(self):
"""Loads the data for the town."""
self._data = await self._client.towns_api.get_data(self.id)
self.data = await self._client.towns_api.get_data(self.id)
self._market = await self._client.towns_api.get_market_data(self.id)

@property
def data(self) -> models.TownData:
"""The data for the town."""
return self._data

@property
def market(self) -> dict[str, models.TownMarketItem]:
"""The market data for the town."""
return self._market.markets

@property
def name(self) -> str:
"""The name of the town."""
return self.data.name

@property
def structures(self) -> dict[str, models.TownDomainStructure]:
"""The structures in the town."""
structures = {}
for domain in self._data.domain.values():
for domain in self.data.domain.values():
if domain.structure is not None:
structures[domain.structure.type] = domain.structure

Expand All @@ -46,7 +46,7 @@ def structures(self) -> dict[str, models.TownDomainStructure]:
def total_satisfaction(self) -> int:
"""The percent satisfaction of the town across all categories."""
demands = sum(
[category.products for category in self._data.commoners.sustenance], []
[category.products for category in self.data.commoners.sustenance], []
)
desire_total = sum(demand.desire for demand in demands)
result_total = sum(demand.result for demand in demands)
Expand All @@ -59,42 +59,36 @@ def total_structures(self) -> int:
return len(
[
domain
for domain in self._data.domain.values()
for domain in self.data.domain.values()
if domain.structure is not None
]
)

@property
def total_taxes(self) -> int:
"""The total taxes collected by the town."""
return sum(self._data.government.taxes_collected.__dict__.values())
return sum(self.data.government.taxes_collected.__dict__.values())

async def fetch_market_item(self, name: str) -> models.TownMarketItemDetails:
async def fetch_market_item(
self, item: common.Item
) -> models.TownMarketItemDetails:
"""Fetches the details for a market item.
Args:
name (str): The name of the item
item (Item): The item to fetch the details for
Returns:
TownMarketItemDetails: The details for the item
"""
return await self._client.towns.get_market_item(self.id, name)

async def fetch_region(self) -> Region:
"""Fetches the region of the town.
Returns:
Region: The region of the town.
"""
return await self._client.regions.get(self._data.region)
return await self._client.towns_api.get_market_item(self.id, item)

def item(self, name: str) -> Optional[models.TownMarketItem]:
def item(self, item: common.Item) -> Optional[models.TownMarketItem]:
"""Get an item from the market.
Args:
name (str): The name of the item
item (Item): The item to get
Returns:
Optional[TownMarketItem]: The item, if found
"""
return self._market.markets.get(name)
return self._market.markets.get(item)
57 changes: 53 additions & 4 deletions pymerc/game/transport.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
from __future__ import annotations

from collections import UserList
from typing import TYPE_CHECKING, Optional

from pymerc.api.models import common
from pymerc.api.models.towns import TownMarketItemDetails
from pymerc.game.exports import Export, Exports
from pymerc.game.imports import Import, Imports
from pymerc.game.town import Town

if TYPE_CHECKING:
from pymerc.client import Client
Expand All @@ -16,18 +19,28 @@ class Transport:
exports: Exports
id: int
imports: Imports
town: Optional[Town]

def __init__(self, client: Client, id: int):
self._client = client
self.id = id
self.exports = Exports()
self.imports = Imports()
self.town = None

async def load(self):
"""Loads the data for the transport."""
self.data = await self._client.transports_api.get(self.id)
if self.data.route:
self.town = await self._client.town(self.data.route.remote_town)

await self._load_imports_exports()

@property
def docked(self) -> bool:
"""Whether the transport is docked."""
return self.town is not None

@property
def inventory(self) -> common.Inventory:
"""The inventory of the transport."""
Expand All @@ -51,12 +64,48 @@ def route_item(self, item: common.Item) -> Optional[common.InventoryAccountAsset

async def _load_imports_exports(self):
"""Loads the imports and exports for the transport."""
if self.data.route:
town = await self._client.town(self.data.route.remote_town)
if self.docked:
for item, manager in self.route.managers.items():
asset = self.route.account.assets[item]
flow = self.data.route.current_flows[item]
if manager.buy_volume:
self.imports[item] = Import(asset, flow, manager, town, self)
self.imports[item] = Import(asset, flow, manager, self.town, self)
if manager.sell_volume:
self.exports[item] = Export(asset, flow, manager, town, self)
self.exports[item] = Export(asset, flow, manager, self.town, self)


class TransportList(UserList[Transport]):
"""A list of transports."""

def search_markets(self, item: common.Item) -> list[TownItem]:
"""Searches the markets for the item.
Args:
item (Item): The item to search for.
Returns:
list: A list of the markets for the item.
"""
items = []
for transport in self:
if transport.docked:
if item in transport.town.market:
items.append(
TownItem(item, transport.town.market[item], transport.town)
)
return items


class TownItem:
"""Represents an item in a town."""

def __init__(
self, item: common.Item, asset: common.InventoryAccountAsset, town: Town
):
self.item = item
self.asset = asset
self.town = town

def fetch_details(self) -> TownMarketItemDetails:
"""Fetches the details for the item from the town's market."""
return self.town.fetch_market_item(self.item)

0 comments on commit 4a418fd

Please sign in to comment.