185 lines
4.5 KiB
Python
185 lines
4.5 KiB
Python
# game_state.py : structures de donnees broadcastees au client a chaque tick
|
|
|
|
from dataclasses import dataclass, field
|
|
|
|
|
|
@dataclass
|
|
class ProjectileState:
|
|
id: str
|
|
owner_id: str
|
|
x: float
|
|
y: float
|
|
vx: float
|
|
vy: float
|
|
damage: int
|
|
radius: float
|
|
ttl: float
|
|
|
|
def to_dict(self):
|
|
# vx/vy/damage/ttl : info serveur, pas envoyes au client
|
|
return {
|
|
"id": self.id,
|
|
"owner": self.owner_id,
|
|
"x": self.x,
|
|
"y": self.y,
|
|
"radius": self.radius,
|
|
}
|
|
|
|
|
|
@dataclass
|
|
class EnemyState:
|
|
id: str
|
|
type: str
|
|
x: float
|
|
y: float
|
|
hp: int
|
|
max_hp: int
|
|
attack_cooldown: float = 0.0
|
|
is_boss: bool = False
|
|
frozen_timer: float = 0.0 # gel du sort divin Seris
|
|
data: dict = field(default_factory=dict) # interne au boss (phases, charge), pas broadcast
|
|
|
|
def to_dict(self):
|
|
return {
|
|
"id": self.id,
|
|
"type": self.type,
|
|
"x": self.x,
|
|
"y": self.y,
|
|
"hp": self.hp,
|
|
"max_hp": self.max_hp,
|
|
"is_boss": self.is_boss,
|
|
"frozen": self.frozen_timer > 0,
|
|
"is_charging": self.data.get("is_charging", False) if self.is_boss else False,
|
|
}
|
|
|
|
|
|
@dataclass
|
|
class PlayerState:
|
|
id: str
|
|
class_name: str
|
|
username: str
|
|
x: float
|
|
y: float
|
|
hp: int
|
|
max_hp: int
|
|
alive: bool
|
|
|
|
revive_progress: float = 0.0
|
|
|
|
cooldowns: dict = field(default_factory=lambda: {
|
|
"attack": 0,
|
|
"ability_1": 0,
|
|
"ability_2": 0,
|
|
"displacement": 0,
|
|
})
|
|
|
|
# buffs actifs : {"type": "...", "timer": float, ...}
|
|
# types : invulnerable, intangible, flying, casting, damage_mult, speed_mult, combat_buff, divine_freeze_dps
|
|
buffs: list = field(default_factory=list)
|
|
|
|
souls: int = 0
|
|
enemies_killed: int = 0
|
|
|
|
# upgrade_id -> nb stacks (damage_up, cooldown_down, hp_up, speed_up)
|
|
upgrades: dict = field(default_factory=dict)
|
|
|
|
def to_dict(self):
|
|
return {
|
|
"id": self.id,
|
|
"class": self.class_name,
|
|
"username": self.username,
|
|
"x": self.x,
|
|
"y": self.y,
|
|
"hp": self.hp,
|
|
"max_hp": self.max_hp,
|
|
"alive": self.alive,
|
|
"revive_progress": self.revive_progress,
|
|
"cooldowns": self.cooldowns,
|
|
"buffs": self.buffs,
|
|
"souls": self.souls,
|
|
"enemies_killed": self.enemies_killed,
|
|
"upgrades": self.upgrades,
|
|
}
|
|
|
|
|
|
@dataclass
|
|
class AoeZone:
|
|
id: str
|
|
owner_id: str
|
|
zone_type: str
|
|
x: float
|
|
y: float
|
|
radius: float
|
|
damage_per_tick: int
|
|
ticks_remaining: int
|
|
max_ticks: int
|
|
|
|
def to_dict(self):
|
|
return {
|
|
"id": self.id,
|
|
"type": self.zone_type,
|
|
"x": self.x,
|
|
"y": self.y,
|
|
"radius": self.radius,
|
|
"ticks": self.ticks_remaining,
|
|
"max_ticks": self.max_ticks,
|
|
}
|
|
|
|
|
|
@dataclass
|
|
class SoulgateState:
|
|
hp: int
|
|
max_hp: int
|
|
|
|
def to_dict(self):
|
|
return {"hp": self.hp, "max_hp": self.max_hp}
|
|
|
|
|
|
@dataclass
|
|
class WaveState:
|
|
number: int
|
|
phase: int
|
|
enemies_remaining: int
|
|
state: str # combat | preparation | boss | victory
|
|
prep_timer: float = 0.0
|
|
boss_hp: int = 0
|
|
boss_max_hp: int = 0
|
|
boss_name: str = ""
|
|
|
|
def to_dict(self):
|
|
return {
|
|
"number": self.number,
|
|
"phase": self.phase,
|
|
"enemies_remaining": self.enemies_remaining,
|
|
"state": self.state,
|
|
"prep_timer": self.prep_timer,
|
|
"boss_hp": self.boss_hp,
|
|
"boss_max_hp": self.boss_max_hp,
|
|
"boss_name": self.boss_name,
|
|
}
|
|
|
|
|
|
@dataclass
|
|
class GameState:
|
|
tick: int
|
|
players: list
|
|
enemies: list
|
|
projectiles: list
|
|
soulgate: SoulgateState
|
|
wave: WaveState
|
|
effects: list
|
|
aoe_zones: list = field(default_factory=list)
|
|
|
|
def to_dict(self):
|
|
return {
|
|
"type": "game_state",
|
|
"tick": self.tick,
|
|
"players": [p.to_dict() for p in self.players],
|
|
"enemies": [e.to_dict() for e in self.enemies],
|
|
"projectiles": [p.to_dict() for p in self.projectiles],
|
|
"aoe_zones": [z.to_dict() for z in self.aoe_zones],
|
|
"soulgate": self.soulgate.to_dict(),
|
|
"wave": self.wave.to_dict(),
|
|
"effects": self.effects,
|
|
}
|