载入中...
搜索中...
未找到
TacticsTypes.h
浏览该文件的文档.
1#pragma once
2#include "common/Export.h"
3
4
10#include "common/ECS.h"
11#include "common/Identity.h"
12#include "common/Result.h"
13#include "common/Revision.h"
14#include "common/SubjectRef.h"
15#include "common/Time.h"
16
17#include <compare>
18#include <cstdint>
19#include <map>
20#include <optional>
21#include <string>
22#include <string_view>
23#include <tuple>
24#include <utility>
25#include <vector>
26
27namespace eve::tactics {
28
30struct Cell {
31 int x = 0;
32 int y = 0;
33 int layer = 0;
34
36 friend bool operator==(const Cell&, const Cell&) noexcept = default;
38 friend auto operator<=>(const Cell& left, const Cell& right) noexcept {
40 return std::tie(left.y, left.x, left.layer) <=> std::tie(right.y, right.x, right.layer);
41 }
42};
43
45enum class BoardTopology : std::uint8_t { Square4, Square8, HexAxial, ExplicitGraph };
46
48enum class BattleStatus : std::uint8_t { Setup, Running, Ended };
49
51enum class BattlePhase : std::uint8_t {
52 Setup,
56 Acting,
58 TurnEnd,
61};
62
64inline constexpr std::string_view kSideAlternatingPolicyId = "side_alternating";
66inline constexpr std::string_view kInitiativePolicyId = "initiative";
74inline constexpr std::string_view kChargeTimeBattlePolicyId = "charge_time_battle";
82inline constexpr int kChargeTimeBattleThreshold = 100;
83
93 static constexpr std::string_view SideAlternating = kSideAlternatingPolicyId;
94 static constexpr std::string_view Initiative = kInitiativePolicyId;
95 static constexpr std::string_view ChargeTimeBattle = kChargeTimeBattlePolicyId;
96};
97
99struct CellState {
100 int moveCost = 100;
101 int height = 0;
102 bool passable = true;
103 std::vector<std::string> tags;
104};
105
115struct EdgeState {
117 bool passable = true;
119 int extraCost = 0;
121 std::vector<std::string> tags;
122};
123
128 std::optional<SubjectRef> occupant;
129};
130
137
141 int movePoints = 0;
143 int initiative = 0;
144
146 [[nodiscard]] Result<void> validate() const;
147};
148
156public:
158 BoardState() = default;
159
161 [[nodiscard]] BoardTopology topology() const noexcept { return topology_; }
163 void setTopology(BoardTopology topology) noexcept { topology_ = topology; }
164
169 [[nodiscard]] Result<void> addCell(Cell cell, CellState state = {});
171 [[nodiscard]] bool contains(Cell cell) const noexcept;
173 [[nodiscard]] Result<CellState> cell(Cell cell) const;
174
179 [[nodiscard]] Result<void> place(SubjectRef subject, Cell cell);
184 [[nodiscard]] Result<void> move(SubjectRef subject, Cell destination);
189 [[nodiscard]] Result<void> remove(SubjectRef subject);
190
192 [[nodiscard]] std::optional<SubjectRef> occupant(Cell cell) const;
194 [[nodiscard]] std::optional<Cell> position(SubjectRef subject) const;
196 [[nodiscard]] std::vector<Cell> cells() const;
198 [[nodiscard]] std::vector<BoardCellRecord> records() const;
200 [[nodiscard]] std::vector<Cell> neighbours(Cell origin) const;
201
213 [[nodiscard]] Result<void> addEdge(Cell from, Cell to, EdgeState state = {});
215 [[nodiscard]] Result<EdgeState> edge(Cell from, Cell to) const;
222 [[nodiscard]] std::optional<EdgeState> tryEdge(Cell from, Cell to) const;
224 [[nodiscard]] std::vector<BoardEdgeRecord> edgeRecords() const;
226 [[nodiscard]] Result<void> validateInvariants() const;
227
228private:
229 [[nodiscard]] static std::string subjectKey(SubjectRef subject);
230
231 BoardTopology topology_ = BoardTopology::Square4;
232 std::map<Cell, CellState> cells_;
233 std::map<Cell, SubjectRef> occupantByCell_;
234 std::map<std::string, Cell> cellBySubject_;
235 std::map<std::pair<Cell, Cell>, EdgeState> edges_;
236};
237
239class TacticalSide : public ecs::Entity {
240public:
242 ENTITY(TacticalSide, ecs::Entity)
243
244
245 void release() override { ecs::DestroyEntity(this); }
246
248 struct Identity {
249 ecs::EntityHandle self{};
251 std::string displayName;
252 };
253
254 COMPONENT(Identity, identity)
255};
256
258class TacticalUnit : public ecs::Entity {
259public:
261 ENTITY(TacticalUnit, ecs::Entity)
262
263
264 void release() override { ecs::DestroyEntity(this); }
265
267 struct Identity {
268 ecs::EntityHandle self{};
271 };
273 struct Membership {
274 ecs::EntityHandle battle{};
275 ecs::EntityHandle side{};
276 };
278 struct Position {
280 int facing = 0;
281 bool placed = false;
282 };
286 int movePoints = 0;
291 int initiative = 0;
300 int charge = 0;
301 bool alive = true;
302 bool acted = false;
303 };
304
305 COMPONENT(Identity, identity)
306 COMPONENT(Membership, membership)
307 COMPONENT(Position, position)
308 COMPONENT(TurnResources, turn)
309};
310
322
330
333 std::uint64_t triggerSequence = 0;
334 std::size_t depth = 0;
335 std::vector<ReactionCandidate> candidates;
336};
337
345
353inline constexpr std::size_t kMaxAbilityPayloadBytes = 4096;
354
356enum class BattleCommandKind : std::uint8_t {
357 Start,
358 Advance,
359 Move,
360 Face,
361 Wait,
362 EndTurn,
363 Finish,
378};
379
418
420enum class ObjectiveKind : std::uint8_t { EliminateSide, SurviveRounds, OccupyCells };
421
423enum class ObjectiveStatus : std::uint8_t { Pending, Completed };
424
435
442
444class Battle : public ecs::Entity {
445public:
447 ENTITY(Battle, ecs::Entity)
448
449
450 void release() override { ecs::DestroyEntity(this); }
451
453 struct Identity {
454 ecs::EntityHandle self{};
456 std::uint64_t seed = 0;
457 };
459 struct Board {
461 };
463 struct TurnState {
469 std::uint64_t round = 0;
470 std::size_t cursor = 0;
471 std::optional<ecs::EntityHandle> activeSide;
472 std::optional<ecs::EntityHandle> activeUnit;
473 std::vector<ecs::EntityHandle> sides;
480 std::vector<ecs::EntityHandle> units;
490 std::vector<ecs::EntityHandle> schedule;
491 };
493 struct Events {
494 std::uint64_t nextSequence = 1;
495 std::vector<BattleEvent> values;
496 };
498 struct Reactions {
499 std::size_t maxDepth = 8;
500 std::vector<ReactionWindow> stack;
501 std::vector<std::string> seen;
502 };
504 struct Commands {
505 std::uint64_t nextSequence = 1;
506 std::vector<BattleCommand> values;
507 };
509 struct Objectives {
510 std::vector<ObjectiveState> values;
511 };
514 std::uint64_t state = 0;
515 std::uint64_t rollIndex = 0;
516 };
518 struct Random {
519 std::map<std::string, RandomStreamState> streams;
520 };
521
522 COMPONENT(Identity, identity)
523 COMPONENT(Board, board)
524 COMPONENT(TurnState, turn)
525 COMPONENT(Events, events)
526 COMPONENT(Reactions, reactions)
527 COMPONENT(Commands, commands)
528 COMPONENT(Objectives, objectives)
529 COMPONENT(Random, random)
530};
531
533[[nodiscard]] std::string_view phaseName(BattlePhase phase) noexcept;
535[[nodiscard]] std::string_view statusName(BattleStatus status) noexcept;
543[[nodiscard]] std::string_view commandKindName(BattleCommandKind kind) noexcept;
544
545} // namespace eve::tactics
int subject
Definition AnimSmr.cpp:163
std::string from
float phase
Definition CaveMesh.cpp:58
#define EVENGINE_API_DOMAINS
Definition Export.h:110
wgpu::PopErrorScopeStatus status
HexVec3 left
HexVec3 right
HexCoordinates to
Cell the unit walks towards on this segment.
Definition HexUnits.cpp:64
Strong identity values shared by persistence, content and logical-name APIs.
TokenKind kind
std::array< float, 3 > position
Topology topology
std::array< PixelCell, kPixelChunkSize *kPixelChunkSize > cells
Move-only, checked operation results for the common layer.
Monotonic state revision for concurrency and change checks.
V3 origin
Definition RoadBake.cpp:138
const RoadEdge * edge
Stable reference to a runtime gameplay subject.
Cell cell
Battle::Events events
Battle::Reactions reactions
TacticalUnit::TurnResources turn
Battle::Random random
Battle::Objectives objectives
BoardState board
Common time values and an injectable deterministic simulation clock.
std::vector< VegetationPresetCommand > commands
Human-readable, scoped identifier in the form namespace:name.
Definition Identity.h:411
Move-only operation result carrying either a value or Status.
Definition Result.h:155
Strong, domain-neutral reference to a runtime subject.
Definition SubjectRef.h:26
static constexpr StrongUint64 zero() noexcept
Returns the zero value for this strong type.
Battle short-root and authoritative owner of board and turn state.
void release() override
Entity.
Authoritative board facts and occupancy indexes for one battle.
BoardState()=default
Construct an empty board with square-four topology.
void setTopology(BoardTopology topology) noexcept
Change topology while retaining existing cell facts.
BoardTopology topology() const noexcept
Return the board topology.
Tactical side short-root entity.
void release() override
Entity.
Tactical unit short-root entity.
void release() override
Entity.
constexpr std::string_view kInitiativePolicyId
Stable id of the built-in per-unit initiative turn policy.
ObjectiveStatus
Objective lifecycle owned by its battle.
constexpr std::string_view kSideAlternatingPolicyId
Stable id of the built-in side-alternating turn policy.
constexpr std::string_view kChargeTimeBattlePolicyId
Stable id of the built-in charge-time (CTB/ATB) turn policy.
BattleStatus
Tactical battle lifecycle.
std::string_view statusName(BattleStatus status) noexcept
Return the stable protocol spelling of a battle status.
constexpr int kChargeTimeBattleThreshold
Charge a unit must accumulate before it may activate under CTB scheduling.
@ EndTurn
End the controlled unit's activation.
BattleCommandKind
Accepted deterministic command kinds recorded for replay.
@ UseAbility
Declare a unit ability activation against a target cell.
ObjectiveKind
Built-in deterministic objective rules.
std::string_view commandKindName(BattleCommandKind kind) noexcept
Return the stable protocol spelling of an accepted command kind.
BattlePhase
Explicit, externally observable battle phase.
@ Ended
The battle is over; only inspection remains.
constexpr std::size_t kMaxAbilityPayloadBytes
Upper bound on the opaque ability payload a declaration may carry.
std::string_view phaseName(BattlePhase phase) noexcept
Return the stable protocol spelling of a battle phase.
BoardTopology
Supported deterministic board-neighbour topologies.
One deterministic fixed-step emitted by SimulationClock.
Definition Time.h:158
One accepted replay command using only persistent identities and values.
SubjectRef targetUnit
The unit this command targeted, when the command targets one.
std::string payload
Opaque caller-owned effect parameters, as declared by the caller.
std::vector< ReactionCandidate > candidates
One deterministic battle lifecycle event owned by Battle.
std::uint64_t correlationCommand
std::uint64_t causationCommand
Authoritative board component.
Accepted external commands in deterministic sequence order.
std::vector< BattleCommand > values
Transient deterministic event projection; not a second state authority.
std::vector< BattleEvent > values
Cold, persistent and authoritative battle identity.
Authoritative objective definitions and completion state.
std::vector< ObjectiveState > values
One named deterministic random stream's serializable state.
Battle-owned named random streams; previews never mutate this component.
std::map< std::string, RandomStreamState > streams
Authoritative transient reaction stack and root-chain cycle guard.
std::vector< ReactionWindow > stack
std::vector< std::string > seen
Authoritative deterministic lifecycle and scheduling state.
std::vector< ecs::EntityHandle > units
Every unit of this battle, as declared by newUnit.
std::vector< ecs::EntityHandle > schedule
The current round's activation queue, in activation order.
std::vector< ecs::EntityHandle > sides
std::optional< ecs::EntityHandle > activeUnit
std::optional< ecs::EntityHandle > activeSide
Owning persistent board record used by snapshots and replay inspection.
std::optional< SubjectRef > occupant
Owning persistent edge record used by snapshots and replay inspection.
One authoritative board cell fact.
std::vector< std::string > tags
Logical board coordinate independent of rendering projection.
friend bool operator==(const Cell &, const Cell &) noexcept=default
Operator ==.
friend auto operator<=>(const Cell &left, const Cell &right) noexcept
Operator <=>.
One authoritative directed edge fact between two adjacent cells.
int extraCost
Additional cost charged only when crossing this direction.
std::vector< std::string > tags
Stable tags for game rules (for example door, one_way).
bool passable
Whether travel is allowed in this exact direction.
Persistent objective definition using stable side identities.
std::vector< Cell > requiredCells
Mutable objective projection and completion revision.
One eligible deterministic reaction choice.
Accepted reaction identity and remaining resource snapshot.
One open reaction window on the battle-owned LIFO stack.
std::vector< ReactionCandidate > candidates
Cold, persistent and authoritative identity component.
Cold, persistent and authoritative identity component.
Linked battle and side identities; both are generation checked on use.
Hot authoritative tactical position and facing.
Hot authoritative per-turn resources.
int charge
Accumulated scheduling charge for charge-time policies.
Typed spelling of the built-in turn-policy ids.
static constexpr std::string_view ChargeTimeBattle
static constexpr std::string_view SideAlternating
static constexpr std::string_view Initiative
Initial and per-round tactical resource values for one unit.
Result< void > validate() const
Validate non-negative consumable resource values.