171 lines
3.5 KiB
Python
171 lines
3.5 KiB
Python
|
|
|
|
from typing import List, Dict, Any
|
|
|
|
|
|
|
|
class StateUpdater:
|
|
|
|
def __init__(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def apply_commands(self, state, commands: List[Dict]) -> List[Dict]:
|
|
|
|
actions = []
|
|
|
|
for command in commands:
|
|
|
|
action = self._process_command(state, command)
|
|
|
|
if action:
|
|
|
|
actions.append(action)
|
|
|
|
return actions
|
|
|
|
|
|
|
|
def tick(self, state, dt: float) -> None:
|
|
|
|
self._update_movements(state, dt)
|
|
|
|
self._update_entities(state, dt)
|
|
|
|
self._update_resources(state, dt)
|
|
|
|
|
|
|
|
def _process_command(self, state, command: Dict) -> Dict:
|
|
|
|
cmd_type = command.get('type')
|
|
|
|
|
|
|
|
if cmd_type == 'select':
|
|
|
|
return {'type': 'selection_changed', 'world_pos': command.get('world_pos')}
|
|
|
|
|
|
|
|
elif cmd_type == 'move':
|
|
|
|
if hasattr(state, 'selected_entities') and state.selected_entities:
|
|
|
|
for entity_id in state.selected_entities:
|
|
|
|
entity = self._find_entity_by_id(state, entity_id)
|
|
|
|
if entity and entity.get('movable', False):
|
|
|
|
entity['target_x'] = command['world_pos'][0]
|
|
|
|
entity['target_y'] = command['world_pos'][1]
|
|
|
|
return {'type': 'move_ordered', 'target_pos': command.get('world_pos')}
|
|
|
|
|
|
|
|
elif cmd_type == 'build':
|
|
|
|
building_type = command.get('building_type')
|
|
|
|
return {'type': 'build_started', 'building_type': building_type}
|
|
|
|
|
|
|
|
elif cmd_type == 'gather':
|
|
|
|
return {'type': 'gather_ordered'}
|
|
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
def _update_movements(self, state, dt: float) -> None:
|
|
|
|
if not hasattr(state, 'entities'):
|
|
|
|
return
|
|
|
|
|
|
|
|
for entity in state.entities:
|
|
|
|
if (entity.get('movable', False) and
|
|
|
|
'target_x' in entity and 'target_y' in entity and
|
|
|
|
'x' in entity and 'y' in entity):
|
|
|
|
|
|
|
|
dx = entity['target_x'] - entity['x']
|
|
|
|
dy = entity['target_y'] - entity['y']
|
|
|
|
distance = (dx**2 + dy**2)**0.5
|
|
|
|
|
|
|
|
if distance > 1.0:
|
|
|
|
speed = entity.get('speed', 50.0)
|
|
|
|
move_dist = speed * dt
|
|
|
|
if move_dist > distance:
|
|
|
|
entity['x'] = entity['target_x']
|
|
|
|
entity['y'] = entity['target_y']
|
|
|
|
else:
|
|
|
|
entity['x'] += (dx / distance) * move_dist
|
|
|
|
entity['y'] += (dy / distance) * move_dist
|
|
|
|
|
|
|
|
def _update_entities(self, state, dt: float) -> None:
|
|
|
|
if hasattr(state, 'entities'):
|
|
|
|
for entity in state.entities:
|
|
|
|
if 'health' in entity and entity['health'] <= 0:
|
|
|
|
state.entities.remove(entity)
|
|
|
|
|
|
|
|
def _update_resources(self, state, dt: float) -> None:
|
|
|
|
if hasattr(state, 'resources'):
|
|
|
|
for resource_type, amount in state.resources.items():
|
|
|
|
if isinstance(amount, (int, float)):
|
|
|
|
state.resources[resource_type] = max(0, amount)
|
|
|
|
|
|
|
|
def _find_entity_by_id(self, state, entity_id: int):
|
|
|
|
if hasattr(state, 'entities'):
|
|
|
|
for entity in state.entities:
|
|
|
|
if entity.get('id') == entity_id:
|
|
|
|
return entity
|
|
|
|
return None
|
|
|