diff --git a/src/routers/scene_router.py b/src/routers/scene_router.py index 0e5da18..7c29028 100644 --- a/src/routers/scene_router.py +++ b/src/routers/scene_router.py @@ -5,9 +5,10 @@ from typing import Dict, Union, List import opensimplex -from fastapi import APIRouter +from fastapi import APIRouter, HTTPException from lynx.common.actions.create_object import CreateObject from lynx.common.actions.remove_object import RemoveObject +from lynx.common.actions.update_resources import UpdateResources from lynx.common.object import Object from lynx.common.scene import Scene from lynx.common.vector import Vector @@ -26,7 +27,6 @@ terminate_process_for_object, log_and_return_message, set_agent_dead, - add_agent_to_player ) from src.utils.tick_handler import create_tick @@ -57,11 +57,26 @@ async def get(tick_number: int, player: str = "") -> Dict[str, Union[int, str, L async def add(r: AddObjectDTO, background_tasks: BackgroundTasks): logger.debug(f"Starting to add object to scene, starting to deserialize object") object = Object.deserialize(r.serialized_object) + player = state.scene.get_player(object.owner) + + if player is None: + logger.error(f"Player with id: {object.owner} does not exist") + raise HTTPException(status_code=400, detail={"message": f"Player with id: {object.owner} does not exist"}) + + if player.add_agent_from_object(object) is False: + logger.error(f"Player with id: {object.owner} cannot add agent") + cost = player.calculate_slot_cost() + raise HTTPException( + status_code=400, + detail={ + "message": "Cannot create agent, you should buy more slots", + "cost": cost + } + ) + logger.debug(f"Object has been successfully deserialized, starting to add object to scene") state.scene.add_to_pending_actions(CreateObject(r.serialized_object).serialize()) - logger.debug(f"Object has been successfully added to pending actions. Starting to add agent to player") - await add_agent_to_player(state.scene, object) - logger.debug(f"Agent has been successfully added to player") + logger.debug(f"Object has been successfully added to pending actions.") if object.tick != "": logger.debug(f"Object has tick {object.tick}") background_tasks.add_task(spawn_process_for_new_agent, object) @@ -69,6 +84,24 @@ async def add(r: AddObjectDTO, background_tasks: BackgroundTasks): return {"serialized_object": object.serialize()} +@router.post("/buy-slot/{player_id}") +async def buy_slot(player_id: str) -> None: + logger.debug(f"Starting to buy slot for player {player_id}") + player = state.scene.get_player(player_id) + if player is None: + logger.warning(f"Player with id: {player_id} does not exist") + return {"message": f"Player with id: {player_id} does not exist"} + + if player.can_purchase_slot() is False: + logger.warning(f"Player with id: {player_id} cannot buy slot") + return {"message": "Cannot buy slot, you should collect more resources"} + + logger.debug(f"Player has enough resources, starting to buy slot") + player.purchase_slot(state.scene) + logger.debug(f"Slot has been successfully bought") + return {"message": "Slot has been successfully bought"} + + @router.delete("/delete_object/{player_id}/{object_id}") async def delete_object(player_id: str, object_id: int): logger.debug(f"Starting to delete object {object_id} from scene") @@ -144,22 +177,29 @@ async def get_ranking(): @router.get("/player-agents/{player_id}") -async def get_agents_from_player_list(player_id: str): +async def get_agents_from_player_list(player_id: str) -> Dict: logger.debug(f"Starting to get agents for player {player_id}") - player = state.scene.get_player(player_id) if player is None: logger.warning(f"Player with id: {player_id} does not exist") - return [] + return {} logger.debug(f"Agents for player {player_id} have been successfully fetched") - return player.get_agents() + slot_cost = player.calculate_slot_cost() + agent_max = player.max_agents + number_of_agents = player.alive_agents_count() + return { + "agents": player.get_agents(), + "slot_cost": slot_cost, + "agent_max": agent_max, + "number_of_agents": number_of_agents, + } @router.delete("/player-agents/{player_id}/{agent_id}") async def delete_agent_from_list(player_id: str, agent_id: int): logger.debug(f"Starting to delete agent {agent_id} for player {player_id}") - + player = state.scene.get_player(player_id) if player is None: return log_and_return_message(f"Player with id: {player_id} does not exist") @@ -197,7 +237,7 @@ async def get_agent_from_list(player_id: str, agent_id: int): @router.get("/player-resources/{player_id}") async def get_player_resources(player_id: str): logger.debug(f"Starting to get resources for player {player_id}") - + player = state.scene.get_player(player_id) if player is None: logger.warning(f"Player with id: {player_id} does not exist") diff --git a/src/utils/helper_functions.py b/src/utils/helper_functions.py index daf879f..fc14a0c 100644 --- a/src/utils/helper_functions.py +++ b/src/utils/helper_functions.py @@ -136,24 +136,6 @@ async def set_agent_dead(player_id: str, object_id: int): player.agents[object_id].time_death = datetime.now().isoformat() logger.debug(f"Agent {object_id} has been successfully set dead") - -async def add_agent_to_player(scene: Scene, object: Object): - player = scene.get_player(object.owner) - if player is None: - logger.warning(f"Player with id: {object.owner} does not exist") - return - - agent = Agent( - id=object.id, - type=object.get_type(), - time_creation=datetime.now().isoformat(), - time_death=None, - is_alive=True, - tick=object.tick, - ) - player.add_agent(agent) - - async def spawn_process_for_new_agent(object: Object): logger.debug(f"Starting to spawn process for new agent {object.id}") await wait_for_next_tick()