载入中...
搜索中...
未找到
RTSSystems.cpp
浏览该文件的文档.
74 ShotPlacement result{deterministicShotRandom(subject, sequence, 0) >= definition.accuracy, intended};
78 const float radius = std::sqrt(deterministicShotRandom(subject, sequence, 2)) * definition.scatterRadius;
87 return faction != nullptr && faction->identity()->subject.isValid() ? faction->identity()->subject.format()
110 const auto found = std::find_if(viewer.intel()->contacts.begin(), viewer.intel()->contacts.end(),
114 const auto contribution = [&](const weapon::WeaponDefinition& definition, WorldPosition source) {
134 auto buildings = ecs::View<Building, Building::Identity, Building::Placement, Building::Faction,
162 {"rts.movement_groups", "ecs::View<Unit, Unit::Navigation>; generation-checked owned group members",
163 "Unit::Motion/Navigation/Orders/Durability/Containment/Supply/Morale/Tactics/Crowd; RTS membership; map grid",
164 "Unit::Navigation::formationSpeedFactor/formationTarget/waypointIndex; RTS movement-group membership",
171 {"rts.motion", "ecs::View<Unit, Unit::Identity, Unit::Motion, Unit::Orders>", "Unit::Identity; Unit::Orders",
176 {"rts.command_state", "Units with Stop, HoldPosition, or AttackMove orders", "Unit::Orders; Unit::Motion",
178 {"rts.navigation", "moving Units with canonical map routes", "Unit::Orders; Unit::Motion; map Pathfinder",
182 {"rts.traffic_reservation", "moving Units inside or approaching connected narrow canonical map corridors",
186 {"rts.fog", "vision-enabled Units/Buildings and Factions", "positions; factions; map FOV explored state",
189 "ecs::View<Unit, Identity, Motion, Navigation, Orders, Crowd, Combat, Containment, Supply, Morale, Tactics, "
191 "Unit::Identity/Motion/Navigation/Orders/Crowd/Combat/Containment/Supply/Morale/Tactics/Command/Effects; "
193 "Unit::Motion; Unit::Crowd::heading; injected Crowd positions/targets/interaction/velocity", "none",
194 "none; injected Crowd advances synchronously", "simulation.movement; zero-time pre-production reconciliation"},
195 {"rts.worker_assignment", "Unit workers; ResourceNode stock/capacity", "positions; orders; stock; links",
197 {"rts.mining", "Unit workers; ResourceNode stock; Building dropoffs", "active orders; positions; stock",
200 {"rts.construction", "Building construction; Unit builders", "orders; faction; motion; build rates",
202 {"rts.repair", "Building integrity; Unit repairers", "orders; faction; integrity; repair rates",
203 "Building::Integrity; Unit::Orders", "none", "delegated resource debit receipt", "simulation.repair"},
210 {"rts.containment", "Units, transports, and garrison Buildings", "orders; faction; capacity; live handles",
211 "Unit::Containment; transport/building occupants; Unit::Motion; Building::Capture", "none", "none",
215 "Unit/Building::Supply; Unit::Orders; canonical weapon ammo", "none", "none", "simulation.logistics"},
217 "canonical supply orders; positions; stable subjects", "Unit::Supply convoy projection", "none", "none",
219 {"rts.morale", "live uncontained Units", "positions; factions; suppression; morale auras", "Unit::Morale",
221 {"rts.shield", "live Units and Buildings with shields", "shield capacity, rate, delay and cooldown",
223 {"rts.command_network", "live Units and completed powered Buildings", "positions; factions; command policy",
225 {"rts.ability", "casting Units and live combat targets", "ability policy; factions; canonical effect state",
226 "Unit::Abilities; target durability/shield/effects", "none", "delegated damage/economy receipts",
229 "weapon projectile trajectories; target positions/factions", "target durability/shield", "none",
231 {"rts.artillery", "live uncontained indirect-fire Units", "motion; deployment policy", "Unit::Artillery",
234 "orders; factions; weapon ranges; last-fire positions", "Unit::Orders; Unit::Artillery", "none", "none",
237 "orders; factions; positions; weapon definitions; durability", "Unit::Tactics; Unit::Combat", "none", "none",
243 {"rts.combat_fire", "armed Units; live Unit/Building targets", "sensing facts; factions; orders; weapons",
247 "Unit::Identity; Unit::Action; active OrderRecord", "Unit::Orders; generic order lifecycle state", "none",
249 {"rts.reinforcement_production_policy", "live production Buildings sharing a faction combat group",
253 {"rts.production_crowd_projection", "ecs::View<Unit, Unit::Motion, Unit::Crowd, Unit::Containment>",
254 "Unit::Crowd/Containment; committed Crowd spawn state", "Unit::Motion; Unit::Crowd::heading", "none",
260 "production blocked/cleared and UnitProduced after authoritative mutation", "simulation.production"},
263 "Faction/Unit/Building::Technology; RTS-owned combat, motion, worker and durability projections", "none",
267 "Match participants/state/events; surrender durability", "none", "match lifecycle events", "simulation.match"},
268 {"rts.effects.unit", "ecs::View<Unit, Unit::Identity, Unit::Effects>", "Unit::Identity; SimulationStep",
280 if (!std::isfinite(position.x) || !std::isfinite(position.y) || !definition.isValid() || !placement)
291 if (!source->placed || construction->progress < 1.0f || !integrity->alive || !infrastructure->powered ||
311Result<std::size_t> TacticsSystem::step(const combat::DamageRuntime* damage, const SimulationStep& step) {
329 auto units = ecs::View<Unit, Unit::Identity, Unit::Motion, Unit::Faction, Unit::Combat, Unit::Durability,
334 candidates.push_back({identity->self, &faction->link, {motion->x, motion->y}, durability->state.health,
340 auto buildings = ecs::View<Building, Building::Identity, Building::Placement, Building::Faction,
352 auto tacticalUnits = ecs::View<Unit, Unit::Identity, Unit::Motion, Unit::Orders, Unit::Faction, Unit::Combat,
366 auto [identity, motion, orders, faction, combat, tactics, weaponLink, durability, containment] = *it;
373 if (!self->morale()->retreating || tactics->combatGroup == 0 || weaponLink->link.resolve() == nullptr ||
395 if (protectedFaction == nullptr || !FactionRelationSystem::isAllied(*protectedFaction, faction->link)) {
414 auto [memberIdentity, memberMotion, memberSupply, memberDurability, memberContainment] = *convoyIt;
451 offset = {travelDirection.x * tactics->escortOffsetX - travelDirection.y * tactics->escortOffsetY,
511 tactics->guardX = escorts[index].center.x - retreatDirection.x * depth + side.x * slot * spacing;
512 tactics->guardY = escorts[index].center.y - retreatDirection.y * depth + side.y * slot * spacing;
633 (victim.airborne && !definition.targetsAir) || (!victim.airborne && !definition.targetsGround) ||
738 shooter->tactics()->fireControlEffectiveness = bestEffectiveness < 0.0f ? 1.0f : bestEffectiveness;
739 auto committedShot = commitShot(shooter->identity()->subject, shooter->faction()->link.resolve(),
752 auto turretBuildings = ecs::View<Building, Building::Identity, Building::Orders, Building::Faction,
785 (candidate.airborne && !definition.targetsAir) || (!candidate.airborne && !definition.targetsGround) ||
823 auto committedShot = commitShot(building->identity()->subject, building->faction()->link.resolve(),
837 auto defenseBuildings = ecs::View<Building, Building::Identity, Building::Placement, Building::Orders,
841 auto [identity, placement, orders, faction, weaponLink, combat, integrity, construction, infrastructure] = *it;
847 DiagnosticCode::InvalidArgument, "RTS air-defense network range must be finite and non-negative",
852 !infrastructure->powered || combat->airDefenseNetworkRange <= 0.0f || weaponEntity == nullptr ||
869 if (visited[other] || !FactionRelationSystem::isAllied(defenses[other].building->faction()->link,
933Result<std::size_t> AISystem::step(const SimulationStep& step, const AIProductionRequest& requestProduction) {
936 Diagnostic::error(DiagnosticCode::InvalidArgument, "RTS AI step delta must be non-negative", "step.delta"));
960 if (strategy->workerDefinition.isValid() && definition->id == strategy->workerDefinition) ++workerCount;
1051 DiagnosticCode::InvariantViolation, "RTS movement order candidate has no identity", "unit.identity"));
1052 if (containment->container.isBound() || !motion->arrived || navigation->trafficWaiting) continue;
1056 if (!record || (record->kind != OrderKind::Move && record->kind != OrderKind::AttackMove)) continue;
1081 DiagnosticCode::InvariantViolation, "RTS command-state candidate has no identity", "unit.identity"));
1112Result<std::size_t> NavigationSystem::step(map::Pathfinder& pathfinder, const NavigationGrid& grid,
1130 auto* unit = identity == nullptr ? nullptr : dynamic_cast<Unit*>(ecs::try_get(identity->self));
1271 const WorldPosition endpoint = navigation->patrolTowardTarget ? record->target : navigation->patrolOrigin;
1295const Faction::Intel::Contact* FogOfWarSystem::contact(const Faction& faction, SubjectRef subject) noexcept {
1302Result<std::size_t> FogOfWarSystem::step(const SimulationStep& step, const NavigationGrid& grid, State& state,
1306 Diagnostic::error(DiagnosticCode::InvalidArgument, "RTS fog provider is required", "fog.provider"));
1309 Diagnostic::error(DiagnosticCode::InvalidArgument, "RTS fog step/grid is invalid", "fog.grid"));
1323 auto addSource = [&](ecs::EntityHandle handle, const FactionLink& factionLink, WorldPosition position,
1329 !std::isfinite(detectionStrength) || !std::isfinite(radarRange) || !std::isfinite(radarResolution) ||
1330 !std::isfinite(jammingRange) || sight < 0.0f || detectionRange < 0.0f || detectionStrength < 0.0f ||
1333 DiagnosticCode::InvalidArgument, "RTS vision values must be finite and non-negative", "vision"));
1342 auto units = ecs::View<Unit, Unit::Identity, Unit::Motion, Unit::Faction, Unit::Vision, Unit::Containment>();
1346 auto added = addSource(identity->self, faction->link, {motion->x, motion->y}, vision->sightRange,
1351 auto buildings = ecs::View<Building, Building::Identity, Building::Placement, Building::Faction,
1380 auto binding = std::find_if(state.bindings.begin(), state.bindings.end(), [&](const auto& value) {
1414 if (enemyFaction == nullptr || enemyFaction == viewer || provider(*enemyFaction) == fov) return;
1452 const float resolution = radar->radarResolution > 0.0f ? radar->radarResolution : grid.cellSize;
1504 auto* unit = identity == nullptr ? nullptr : dynamic_cast<Unit*>(ecs::try_get(identity->self));
1512 auto nodes = ecs::View<ResourceNode, ResourceNode::Identity, ResourceNode::Position, ResourceNode::Stock,
1552Result<std::size_t> MiningSystem::step(const SimulationStep& step, const ResourceCredit& credit) {
1561 auto* unit = identity == nullptr ? nullptr : dynamic_cast<Unit*>(ecs::try_get(identity->self));
1581 if (worker->cargo >= worker->capacity || (!node->stock()->infinite && node->stock()->remaining <= 0.0f)) {
1627Result<std::size_t> ConstructionSystem::step(const SimulationStep& step, const LifecycleEventSink& events) {
1630 DiagnosticCode::InvalidArgument, "RTS construction step delta must be non-negative", "step.delta"));
1632 auto buildings = ecs::View<Building, Building::Identity, Building::Construction, Building::Faction>();
1635 auto* building = identity == nullptr ? nullptr : dynamic_cast<Building*>(ecs::try_get(identity->self));
1637 if (!std::isfinite(construction->progress) || !std::isfinite(construction->buildTimeSeconds) ||
1648 auto units = ecs::View<Unit, Unit::Identity, Unit::Motion, Unit::Orders, Unit::Worker, Unit::Faction>();
1651 auto* unit = unitIdentity == nullptr ? nullptr : dynamic_cast<Unit*>(ecs::try_get(unitIdentity->self));
1658 if (!record || record->kind != OrderKind::Build || !isSameHandle(record->targetEntity, identity->self))
1708 std::size_t budget = idle.size() > policy->reserveWorkers ? idle.size() - policy->reserveWorkers : 0;
1712 auto buildings = ecs::View<Building, Building::Identity, Building::Faction, Building::Construction,
1777Result<std::size_t> RepairSystem::step(const SimulationStep& step, combat::DamageRuntime& settlement,
1781 DiagnosticCode::InvalidArgument, "RTS repair requires non-negative time and a debit callback", "repair"));
1783 auto units = ecs::View<Unit, Unit::Identity, Unit::Motion, Unit::Orders, Unit::Worker, Unit::Faction>();
1786 auto* unit = identity == nullptr ? nullptr : dynamic_cast<Unit*>(ecs::try_get(identity->self));
1800 const float missing = static_cast<float>(std::max(0.0, integrity->state.maxHealth - integrity->state.health));
1806 const float requested = std::min(missing, worker->repairRate * static_cast<float>(step.delta.seconds()));
1832Result<std::size_t> CaptureSystem::step(const SimulationStep& step, const LifecycleEventSink& events) {
1835 DiagnosticCode::InvalidArgument, "RTS capture step delta must be non-negative", "step.delta"));
1836 struct Force { ecs::EntityHandle faction{}; float strength = 0.0f; std::vector<Unit*> units; };
1838 auto buildings = ecs::View<Building, Building::Identity, Building::Capture, Building::Construction,
1842 auto* building = identity == nullptr ? nullptr : dynamic_cast<Building*>(ecs::try_get(identity->self));
1851 auto units = ecs::View<Unit, Unit::Identity, Unit::Motion, Unit::Orders, Unit::Capture, Unit::Faction>();
1854 auto* unit = unitIdentity == nullptr ? nullptr : dynamic_cast<Unit*>(ecs::try_get(unitIdentity->self));
1856 faction->link.resolve() == nullptr || FactionRelationSystem::isAllied(faction->link, owner->link))
1861 if (!record || record->kind != OrderKind::Capture || !isSameHandle(record->targetEntity, identity->self))
1866 if (found == forces.end()) { forces.push_back({faction->link.handle(), 0.0f, {}}); found = forces.end() - 1; }
1880 capture->progress = std::max(0.0f, capture->progress - force.strength * dt / capture->durationSeconds);
1927 DiagnosticCode::InvalidArgument, "RTS infrastructure step delta must be non-negative", "step.delta"));
1935 auto* building = identity == nullptr ? nullptr : dynamic_cast<Building*>(ecs::try_get(identity->self));
1941 !std::isfinite(infrastructure->buildInfluenceRadius) || infrastructure->buildInfluenceRadius < 0.0f)
1943 DiagnosticCode::InvalidArgument, "RTS building infrastructure values must be finite and non-negative",
2003 auto garrisons = ecs::View<Building, Building::Identity, Building::Garrison, Building::Capture>();
2010 auto units = ecs::View<Unit, Unit::Identity, Unit::Motion, Unit::Orders, Unit::Faction, Unit::Containment>();
2013 auto* unit = identity == nullptr ? nullptr : dynamic_cast<Unit*>(ecs::try_get(identity->self));
2045 if (!record || (record->kind != OrderKind::Garrison && record->kind != OrderKind::BoardTransport) ||
2064 if (building != nullptr && building->integrity()->alive && building->construction()->progress >= 1.0f) {
2071 if (occupants == nullptr || owner == nullptr || !FactionRelationSystem::isAllied(*owner, faction->link) ||
2098Result<std::size_t> releaseOccupants(std::vector<ecs::EntityHandle>& occupants, WorldPosition destination) {
2101 Diagnostic::error(DiagnosticCode::InvalidArgument, "RTS unload destination must be finite", "destination"));
2133Result<std::size_t> ContainmentSystem::evacuate(Building& building, WorldPosition destination) {
2148 if (faction == nullptr || !FactionRelationSystem::isAllied(relay.faction()->link, supplier.faction()->link))
2150 DiagnosticCode::StaleHandle, "RTS supply rendezvous requires a shared live faction", "supply.faction"));
2206 DiagnosticCode::NotFound, "RTS supply rendezvous has no reachable candidate", "supply.rendezvous"));
2209 return Result<SupplyRendezvousSelection>::success(result, Status::success(StatusCode::Applied));
2212Result<std::size_t> SupplySystem::step(const SimulationStep& step, const AmmoProductionPurchase& purchase,
2219 auto producers = ecs::View<Building, Building::Identity, Building::Construction, Building::Integrity,
2231 "RTS building ammunition production values must be finite and non-negative", "building.supply"));
2235 if (remaining < 1.0f) supply->productionProgress = std::min(supply->productionProgress, 0.999f);
2291 const int magazineSpace = std::max(0, static_cast<int>(std::floor(resource.max - resource.value)));
2299 const int space = pool->state()->max < 0 ? rounds : std::max(0, pool->state()->max - pool->state()->count);
2305 const int reserveCapacity = std::max(resource.reserve, weaponEntity->definition()->def == nullptr
2319 auto recipientView = ecs::View<Unit, Unit::Identity, Unit::Weapon, Unit::Faction, Unit::Containment,
2328 if (capacity > carried) recipients.push_back({unit, capacity - carried, float(carried) / float(capacity)});
2330 std::sort(recipients.begin(), recipients.end(), [](const Recipient& left, const Recipient& right) {
2338 auto supplierView = ecs::View<Unit, Unit::Identity, Unit::Motion, Unit::Orders, Unit::Faction, Unit::Supply,
2354 recipientReservations[target->identity()->subject.format()] += supplier->supply()->reservedStock;
2370 if ((!order || (order->kind != OrderKind::Resupply && order->kind != OrderKind::SupplyRelay)) &&
2385 if (distanceSquared(motion->x, motion->y, supply->returnPoint.x, supply->returnPoint.y) <= 0.01f) {
2479 if (!order || (order->kind != OrderKind::Resupply && order->kind != OrderKind::SupplyRelay)) continue;
2481 if (target == nullptr || !target->durability()->alive || target->containment()->container.isBound() ||
2508 auto failed = orders->values.fail(order->id, "supply relay requires a smaller-capacity relay target");
2562 const float distance = distanceSquared(motion->x, motion->y, target->motion()->x, target->motion()->y);
2593 (order->kind == OrderKind::SupplyRelay && target->supply()->stock >= target->supply()->capacity) ||
2617 auto buildings = ecs::View<Building, Building::Identity, Building::Placement, Building::Faction, Building::Construction,
2655 auto view = ecs::View<Unit, Unit::Identity, Unit::Motion, Unit::Orders, Unit::Faction, Unit::Supply,
2715Result<std::size_t> MoraleSystem::step(const SimulationStep& step, const LifecycleEventSink& events) {
2720 auto units = ecs::View<Unit, Unit::Identity, Unit::Motion, Unit::Faction, Unit::Morale, Unit::Containment,
2724 if (!durability->alive || containment->container.isBound() || morale->capacity <= 0.0f) continue;
2725 if (!std::isfinite(morale->suppression) || !std::isfinite(morale->capacity) || morale->capacity < 0.0f ||
2728 Diagnostic::error(DiagnosticCode::InvalidArgument, "RTS morale values must be finite", "unit.morale"));
2758Result<std::size_t> ShieldSystem::step(const SimulationStep& step, const LifecycleEventSink& events) {
2805 auto unitJammers = ecs::View<Unit, Unit::Motion, Unit::Faction, Unit::Command, Unit::Durability,
2809 if (durability->alive && durability->state.health > 0.0 && !containment->container.isBound() &&
2813 auto buildingJammers = ecs::View<Building, Building::Placement, Building::Faction, Building::Command,
2844 auto units = ecs::View<Unit, Unit::Identity, Unit::Motion, Unit::Faction, Unit::Command, Unit::Durability,
2853 command->outOfCommandSpeedFactor > 1.0f || !std::isfinite(command->outOfCommandDamageFactor) ||
2870 active.push_back({identity->self, faction->link.resolve(), {motion->x, motion->y}, command->range,
2877 auto buildings = ecs::View<Building, Building::Identity, Building::Placement, Building::Faction,
2887 DiagnosticCode::InvalidArgument, "RTS building command policy is invalid", "building.command"));
2888 const bool live = integrity->alive && integrity->state.health > 0.0 && construction->progress >= 1.0f &&
2890 command->jammed = live && isJammed(faction->link.resolve(), {placement->worldX, placement->worldY});
2893 active.push_back({identity->self, faction->link.resolve(), {placement->worldX, placement->worldY},
2949 return Result<std::size_t>::success(active.size() + recipients.size(), Status::success(StatusCode::Applied));
2954Result<void> settleAbility(Unit& caster, const AbilitySpec& spec, ecs::EntityHandle targetHandle,
2991 DiagnosticCode::InvalidArgument, "ability target is not a live RTS combat subject", "target"));
2992 const bool allied = faction != nullptr && FactionRelationSystem::isAllied(*faction, caster.faction()->link);
2997 Diagnostic::error(DiagnosticCode::Conflict, "ability target relationship is invalid", "target"));
3045 if (durability->alive && distanceSquared(point.x, point.y, motion->x, motion->y) <= radius * radius)
3048 auto buildings = ecs::View<Building, Building::Identity, Building::Placement, Building::Integrity>();
3051 if (integrity->alive && distanceSquared(point.x, point.y, placement->worldX, placement->worldY) <=
3057 FactionLink* faction = dynamic_cast<Unit*>(entity) ? &dynamic_cast<Unit*>(entity)->faction()->link
3063 return Result<void>::success(Status::success(targets.empty() ? StatusCode::NoOp : StatusCode::Applied));
3068 if (spec.id.empty() || !std::isfinite(spec.range) || spec.range < 0.0f || !std::isfinite(spec.radius) ||
3069 spec.radius < 0.0f || !std::isfinite(spec.cooldown) || spec.cooldown < 0.0f || !std::isfinite(spec.damage) ||
3070 spec.damage < 0.0f || !std::isfinite(spec.healing) || spec.healing < 0.0f || !std::isfinite(spec.castTime) ||
3071 spec.castTime < 0.0f || !std::isfinite(spec.channelTickInterval) || spec.channelTickInterval < 0.0f ||
3078 Diagnostic::error(DiagnosticCode::Conflict, "unit definition cannot cast this ability", "caster"));
3080 if (spec.target == AbilityTarget::Self) destination = {caster.motion()->x, caster.motion()->y};
3091 DiagnosticCode::Conflict, "enemy ability target is not currently visible and detected", "target"));
3096 Diagnostic::error(DiagnosticCode::Conflict, "ability target is outside cast range", "target"));
3102Result<void> AbilitySystem::cast(Unit& caster, const AbilitySpec& spec, ecs::EntityHandle target,
3111 Diagnostic::error(DiagnosticCode::Conflict, "unit is already casting an ability", "ability.channel"));
3112 auto found = std::find_if(caster.abilities()->cooldowns.begin(), caster.abilities()->cooldowns.end(),
3120 Diagnostic::error(DiagnosticCode::Unsupported, "ability resource debit provider is absent", {}));
3145Result<std::size_t> AbilitySystem::step(const SimulationStep& step, combat::DamageRuntime& damage,
3150 Diagnostic::error(DiagnosticCode::InvalidArgument, "RTS ability delta must be non-negative", "step.delta"));
3212 DiagnosticCode::InvalidArgument, "RTS artillery step delta must be non-negative", "step.delta"));
3214 auto units = ecs::View<Unit, Unit::Motion, Unit::Artillery, Unit::Containment, Unit::Durability,
3257 if (!isFinitePosition(target) || !std::isfinite(distance) || distance <= 0.0f || !std::isfinite(weaponRange) ||
3258 weaponRange < 0.0f || !std::isfinite(grid.cellSize) || grid.cellSize <= 0.0f || !std::isfinite(grid.originX) ||
3268 Diagnostic::error(DiagnosticCode::StaleHandle, "RTS artillery faction link is stale", "unit.faction"));
3271 const auto found = std::find_if(ownFaction->intel()->contacts.begin(), ownFaction->intel()->contacts.end(),
3282 FactionRelationSystem::isAllied(dynamic_cast<Faction*>(faction->link.resolve()), ownFaction) ||
3292 auto buildings = ecs::View<Building, Building::Identity, Building::Placement, Building::Faction,
3297 FactionRelationSystem::isAllied(dynamic_cast<Faction*>(faction->link.resolve()), ownFaction) ||
3327 if (distanceSquared(candidate.x, candidate.y, position.x, position.y) < separation * separation)
3340 const float preferred = deterministicShotRandom(unit.identity()->subject, 0, 17) >= 0.5f ? 1.0f : -1.0f;
3364 const WorldPosition candidate{unit.motion()->x + directions[index].x / directionLength * distance,
3369 std::unique_ptr<map::Path> path(pathfinder.findPath(worldToCell(unit.motion()->x, grid.originX),
3394 DiagnosticCode::NotFound, "RTS artillery has no reachable relocation candidate", "artillery.relocation"));
3408Result<std::size_t> FireSupportSystem::request(Unit& requester, WorldPosition center, float radius,
3410 if (!isFinitePosition(center) || !std::isfinite(radius) || radius <= 0.0f || shotsPerResponder <= 0 ||
3414 Diagnostic::error(DiagnosticCode::InvalidArgument, "RTS fire support request is invalid", "fireSupport"));
3417 auto view = ecs::View<Unit, Unit::Identity, Unit::Motion, Unit::Faction, Unit::Orders, Unit::Weapon,
3420 auto [identity, motion, faction, orders, weaponLink, artillery, durability, containment, morale] = *it;
3423 if (unit == nullptr || unit == &requester || !durability->alive || containment->container.isBound() ||
3424 morale->retreating || !FactionRelationSystem::isAllied(faction->link, requester.faction()->link) ||
3433 if (record && record->kind != OrderKind::HoldPosition && record->kind != OrderKind::AttackMove &&
3487 struct Exposure { ecs::EntityHandle handle{}; ecs::Entity* faction = nullptr; WorldPosition position; };
3489 auto exposedUnits = ecs::View<Unit, Unit::Identity, Unit::Faction, Unit::Artillery, Unit::Durability>();
3496 auto exposedBuildings = ecs::View<Building, Building::Identity, Building::Faction, Building::IndirectFire,
3505 auto responders = ecs::View<Unit, Unit::Identity, Unit::Motion, Unit::Faction, Unit::Orders, Unit::Weapon,
3508 auto [identity, motion, faction, orders, weaponLink, artillery, durability, containment] = *it;
3544 const float distance = distanceSquared(motion->x, motion->y, exposure.position.x, exposure.position.y);
3595 DiagnosticCode::InvalidArgument, "RTS projectile snapshot payload count does not match live trajectories",
3599 if (!liveKeys.contains(value.key) || stagedPayloads.contains(value.key) || !value.source.isValid() ||
3600 !value.faction.isValid() || !isFinitePosition(value.targetPoint) || !std::isfinite(value.targetHeight) ||
3646 Diagnostic::error(DiagnosticCode::StaleHandle, "RTS projectile homing target is stale", "target"));
3650Result<void> RTSProjectileSystem::launch(SubjectRef source, ecs::EntityHandle faction, WorldPosition origin,
3654 if (!source.isValid() || definition.projectile.speed <= 0.0f || !std::isfinite(damageFactor) ||
3659 auto id = LogicalId::fromParts("projectile", definition.id.empty() ? "weapon" : definition.id);
3662 Diagnostic::error(DiagnosticCode::InvalidArgument, "weapon id cannot identify a projectile", {}));
3701 payload.damageType = definition.damageType.empty() ? "damage.physical" : definition.damageType;
3703 payload.damage = static_cast<double>(definition.damage) * std::max(1, definition.projectile.pelletCount) *
3717Result<std::size_t> RTSProjectileSystem::step(const SimulationStep& step, combat::DamageRuntime& damage,
3732 const float range = cloaked ? observer->vision()->detectionRange : observer->vision()->sightRange;
3740 return range > 0.0f && distanceSquared(observer->placement()->worldX, observer->placement()->worldY,
3820 !subject.isValid() || (airborne && !payload.targetsAir) || (!airborne && !payload.targetsGround) ||
3828 request.source = payload.source; request.target = subject; request.damageType = payload.damageType;
3898 return heightQuery ? heightQuery(origin, target, source, targetEntity) : CombatHeightProfile{};
3909 if (resource.kind == weapon::ResourceKind::Ammo && !resource.infinite && resource.value <= 0.0f)
3960 if (!removed && removed.code() != StatusCode::NotFound) return Result<std::size_t>::failure(removed.status());
3965 const std::string faction = target.faction == nullptr ? std::string{} : factionKey(*target.faction);
3973 auto units = ecs::View<Unit, Unit::Identity, Unit::Definition, Unit::Motion, Unit::Faction, Unit::Durability,
3976 auto [identity, unitDefinition, motion, faction, durability, containment, morale, shield, effects, tags,
3990 auto buildings = ecs::View<Building, Building::Identity, Building::Definition, Building::Placement,
3994 auto [identity, buildingDefinition, placement, faction, integrity, shield, effects, tags] = *it;
3995 if (!identity->subject.isValid() || !integrity->alive || integrity->state.health <= 0.0) continue;
4007 auto observedFireSpotter = [&](ecs::Entity* ownFaction, const Target& target) -> ecs::EntityHandle {
4010 auto consider = [&](ecs::EntityHandle handle, ecs::Entity* observerFaction, WorldPosition position,
4023 auto unitObservers = ecs::View<Unit, Unit::Identity, Unit::Motion, Unit::Faction, Unit::Vision,
4031 auto buildingObservers = ecs::View<Building, Building::Identity, Building::Placement, Building::Faction,
4042 auto attackers = ecs::View<Unit, Unit::Identity, Unit::Motion, Unit::Orders, Unit::Faction, Unit::Weapon,
4046 auto [identity, motion, orders, faction, weaponLink, policy, durability, containment, morale, artillery,
4050 if (!durability->alive || durability->state.health <= 0.0 || containment->container.isBound()) continue;
4054 (veterancy->veteranThreshold > 0.0f && veterancy->eliteThreshold <= veterancy->veteranThreshold) ||
4055 !std::isfinite(veterancy->veteranDamageFactor) || !std::isfinite(veterancy->eliteDamageFactor) ||
4056 !std::isfinite(veterancy->veteranHealthFactor) || !std::isfinite(veterancy->eliteHealthFactor) ||
4071 DiagnosticCode::InvalidArgument, "RTS weapon preferred target bonus must be finite and at least one",
4074 if (std::any_of(policy->targetPriorities.begin(), policy->targetPriorities.end(), [](const auto& entry) {
4078 DiagnosticCode::InvalidArgument, "RTS target priority entries require non-empty ids and finite weights",
4096 DiagnosticCode::InvalidArgument, "RTS coordinated volley timing must be finite and non-negative",
4099 if (!explicitAttack && tactics->combatGroup != 0 && tactics->coordinatedVolleyInterval > 0.0f) {
4154 const ShotPlacement shot = placeShot(identity->subject, policy->shotSequence++, definition, aimPoint);
4242 (!definition.friendlyFire && FactionRelationSystem::isAllied(*found->second.faction, faction->link)))
4253 const bool indirect = definition.projectile.speed > 0.0f && definition.projectile.gravity > 0.0f;
4257 if (!explicitAttack && distance > policy->acquisitionRange * policy->acquisitionRange) return nullptr;
4258 if (explicitAttack && !FactionIntelSystem::isTargetable(dynamic_cast<Faction*>(faction->link.resolve()),
4292 auto queried = sensing.query(eve::sensing::QueryOrigin{motion->x, motion->y, std::nullopt}, acquisition);
4301 const float policyPriority = preferred == policy->targetPriorities.end() ? 1.0f : preferred->second;
4317 const bool indirect = definition.projectile.speed > 0.0f && definition.projectile.gravity > 0.0f;
4318 const float targetDistance = distanceSquared(motion->x, motion->y, target->position.x, target->position.y);
4328 if (distanceSquared(motion->x, motion->y, target->position.x, target->position.y) > range * range) continue;
4344 if (std::fabs(std::remainder(weaponEntity->aim()->desiredYaw - weaponEntity->aim()->yaw, 360.0f)) >
4365 const float moraleFactor = morale->active ? std::clamp(morale->suppressedDamageFactor, 0.0f, 1.0f)
4388 request.damageType = definition.damageType.empty() ? "damage.physical" : definition.damageType;
4389 const float damageFactor = morale->active ? std::clamp(morale->suppressedDamageFactor, 0.0f, 1.0f) : 1.0f;
4407 if (target->morale != nullptr && target->morale->capacity > 0.0f && policy->suppressionPerShot > 0.0f) {
4413 if (!allyDurability->alive || allyContainment->container.isBound() || aura->auraRange <= 0.0f ||
4422 if (target->morale->suppression >= target->morale->capacity * 0.5f) target->morale->active = true;
4458 auto armedBuildings = ecs::View<Building, Building::Identity, Building::Placement, Building::Orders,
4462 auto [identity, placement, orders, faction, weaponLink, policy, integrity, construction, garrison] = *it;
4463 if (!integrity->alive || integrity->state.health <= 0.0 || construction->progress < 1.0f) continue;
4470 DiagnosticCode::InvalidArgument, "RTS weapon preferred target bonus must be finite and at least one",
4473 if (std::any_of(policy->targetPriorities.begin(), policy->targetPriorities.end(), [](const auto& entry) {
4477 DiagnosticCode::InvalidArgument, "RTS target priority entries require non-empty ids and finite weights",
4483 "RTS turret turn rate and aim tolerance must be finite and non-negative", "building.combat.aim"));
4497 (!definition.friendlyFire && FactionRelationSystem::isAllied(*found->second.faction, faction->link)) ||
4509 if (explicitAttack && !FactionIntelSystem::isTargetable(dynamic_cast<Faction*>(faction->link.resolve()),
4516 auto failed = orders->values.fail(record->id, "building attack target is invalid or destroyed");
4524 acquisition.shape = eve::sensing::QueryCircle{placement->worldX, placement->worldY, acquisitionRange};
4541 const float policyPriority = preferred == policy->targetPriorities.end() ? 1.0f : preferred->second;
4553 if (distanceSquared(placement->worldX, placement->worldY, target->position.x, target->position.y) >
4556 auto clear = fireLine({placement->worldX, placement->worldY}, target->position, identity->self,
4570 if (std::fabs(std::remainder(weaponEntity->aim()->desiredYaw - weaponEntity->aim()->yaw, 360.0f)) >
4609 request.damageType = definition.damageType.empty() ? "damage.physical" : definition.damageType;
4641Result<std::size_t> OrderActionSystem::step(const SimulationStep& step, IRTSActionExecutor& executor) {
4685 "RTS reinforcement request requires a preferred product and enqueue boundary", "reinforcement"));
4702 Diagnostic::error(DiagnosticCode::InvalidArgument, "RTS reinforcement fallback chain contains a cycle",
4710 DiagnosticCode::InvalidArgument, "RTS reinforcement policy delta must be non-negative", "step.delta"));
4729 if (!durability->alive || containment->container.isBound() || tactics->combatGroup == 0) continue;
4734 auto buildings = ecs::View<Building, Building::Identity, Building::Faction, Building::Production,
4758 if (group.limit == 0 || (rally->reinforcementLimit > 0 && rally->reinforcementLimit < group.limit))
4762 if (found == group.typeLimits.end() || limit < found->second) group.typeLimits[product] = limit;
4772 std::sort(group.demands.begin(), group.demands.end(), [](const Demand& left, const Demand& right) {
4874Result<std::size_t> EffectSystem::step(const SimulationStep& step, combat::DamageRuntime& settlement,
4878 DiagnosticCode::InvalidArgument, "RTS effects step delta must be non-negative", "step.delta"));
4884 Unit* unit = identity == nullptr ? nullptr : dynamic_cast<Unit*>(ecs::try_get(identity->self));
4885 if (unit == nullptr || &*unit->identity() != identity || &*unit->effects() != effects) continue;
4910 Building* building = identity == nullptr ? nullptr : dynamic_cast<Building*>(ecs::try_get(identity->self));
std::array< std::uint64_t, kPixelChunkSize *kPixelChunkSize > updated
Definition PixelWorld.cpp:53
Deterministic phase-one RTS systems and their ECS contracts.
std::map< std::string, std::span< const std::uint8_t > > members
Definition UnityPackage.cpp:81
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
static Result< Duration > fromSeconds(double seconds)
Convert finite seconds to the nearest nanosecond.
Definition Time.cpp:16
Human-readable, scoped identifier in the form namespace:name.
Definition Identity.h:411
static std::optional< LogicalId > fromParts(std::string_view namespaceName, std::string_view name)
Builds a logical ID from separate namespace and name components.
Definition Identity.cpp:48
const std::string & format() const noexcept
Returns the canonical namespace:name representation.
Definition Identity.h:436
bool isValid() const noexcept
Returns whether this value contains a valid namespace and name.
Definition Identity.h:433
void ignore(std::string_view reason={}) const noexcept
Explicitly discard this result after documenting the reason.
Definition Result.h:393
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
static Status success(StatusCode code=StatusCode::Ok)
Construct a successful status with an explicit non-error outcome.
Definition Status.h:81
bool isValid() const noexcept
Return whether this reference is valid and non-nil.
Definition SubjectRef.h:38
Result< DamageAmounts > preview(const CombatState &target, const DamageRequest &request) const
Resolve provider damage amounts before settlement stages, without mutating the target.
Definition Damage.cpp:181
Result< settlement::SettlementResult > heal(CombatState &target, SubjectRef source, double amount) const
Resolve and atomically commit health restoration through the configured settlement pipeline.
Definition Damage.cpp:262
Result< DamageOutcome > apply(CombatState &target, const DamageRequest &request) const
Resolve and atomically commit one damage request.
Definition Damage.cpp:200
Dynamic field-of-view / fog-of-war facade. Phase A: 2D shadowcast + multi-revealer + explored memory....
Definition Fov.h:27
Pathfinding facade. Single-agent: A*. Group (same goal): Flow Field + follow. Grid/topology internals...
Definition Pathfinder.h:20
Path * findPath(int sx, int sy, int gx, int gy)
A* from (sx,sy) to (gx,gy). Returns owned Path* (may be empty if unreachable). Never returns nullptr ...
Definition Pathfinder.cpp:493
static eve::Result< CostSpec > single(std::string_view resource, std::int64_t amount)
Build a one-resource cost.
Definition ResourceAccount.cpp:117
static Result< std::size_t > step(const SimulationStep &step, const AIProductionRequest &requestProduction)
Think for enabled factions and submit production/attack decisions.
Definition RTSSystems.cpp:933
static Result< void > validate(Faction &faction, WorldPosition position, LogicalId definition, const PlacementValidation &placement, bool requireInfluence=true)
Validate one proposed building position without mutating either domain.
Definition RTSSystems.cpp:277
RTS building domain root with placement and production composition.
Definition RTSTypes.h:840
static Result< FanOutReceipt > fanOut(std::span< const ecs::EntityHandle > unitHandles, const CommandSpec &command, const FormationSpec &formation)
Submit one command to every selected live Unit.
Definition RTSFormation.cpp:124
static Result< std::size_t > step()
Synchronize combat guard flags and settle Stop orders immediately.
Definition RTSSystems.cpp:1073
ecs::Entity * resolve() const noexcept
Resolve the target for this call, or return null when stale.
Definition RTSTypes.h:214
static bool isAllied(Faction *left, Faction *right) noexcept
Return true when both live factions are identical or share a team in a common Match.
Definition RTSSystems_Faction.cpp:58
Faction domain root; membership is a set of typed runtime handles.
Definition RTSTypes.h:1178
Interface isolating RTS orders from the shared action runtime.
Definition RTSAction.h:38
virtual Result< ActionExecutionResult > execute(Unit &unit, const OrderRecord &order, const SimulationStep &step)=0
Execute or advance one active RTS order.
static Result< std::size_t > step()
Complete arrived Move and AttackMove orders after their final path waypoint.
Definition RTSSystems.cpp:1043
Entity-local RTS effect component backed by the canonical adapter.
Definition RTSEffects.h:118
double multiplier(std::string_view field) const noexcept
Return a composed active status multiplier.
Definition RTSEffects.h:141
RTS impact adapter over the canonical pooled weapon projectile trajectory runtime.
Definition RTSSystems.h:653
Harvestable RTS resource node; deposited balances are owned by an external resource account.
Definition RTSTypes.h:1071
static Result< std::size_t > step(const combat::DamageRuntime *damage=nullptr, const SimulationStep &step={})
Follow protected entities, intercept local threats, and distribute group fire.
Definition RTSSystems.cpp:311
Entity-local sorted tags; this is the RTS entity's tag authority.
Definition RTSTypes.h:153
const std::vector< std::string > & values() const noexcept
Return tags in deterministic order.
Definition RTSTypes.h:162
Gameplay-facing 2D candidate query service; it never values or selects targets.
Definition Sensing.h:151
eve::Result< void > upsert(std::string_view id, float x, float y, std::string_view faction, std::string_view tagsCsv, std::string_view visibleToCsv)
Inserts or replaces mirrored facts. CSV fields contain comma-separated stable keys.
Definition Sensing.cpp:238
eve::Result< void > remove(std::string_view id)
Removes mirrored facts, or returns NotFound when the id is absent.
Definition Sensing.cpp:251
Owner-thread deterministic projectile simulator with a bounded reusable pool.
Definition ProjectileRuntime.h:118
Result< void > restore(const ProjectileRuntimeSnapshot &snapshot)
Atomically replace this pool from a validated snapshot.
Definition ProjectileRuntime.cpp:195
std::vector< ProjectileState > states() const
Return owning live states in stable slot order.
Definition ProjectileRuntime.cpp:180
static void update(WeaponEntity &w, float dt)
每帧推进:冷却 / 连发 / 装填 / 炮口旋转 / 逻辑自身。
Definition WeaponSystem.cpp:387
static bool tryFire(WeaponEntity &w, const FireRequest &req)
尝试开火;满足条件时扣弹药、调逻辑、推事件并返回 true。
Definition WeaponSystem.cpp:397
@ Building
Result< T > applied(T value, std::vector< Diagnostic > diagnostics={})
Construct an Applied result with an owning payload and optional diagnostics.
Definition EditingResult.h:43
Result< T > failed(Status status, eve::DiagnosticCode code, RuleId rule, std::string message)
Construct a failed editing result with explicit status and diagnostic categories.
Definition EditingResult.h:70
void worldToCell(const GridConfig &cfg, float px, float py, int &cx, int &cy, int mapW, int mapH)
Maps planar coordinates to the nearest cell. Staggered/hex layouts use a bounded nearest-neighbor sea...
Definition GridProjection.cpp:69
@ Running
float distanceSquared(float ax, float ay, float bx, float by)
Definition RTSSystemMovementInternal.h:23
Result< std::optional< OrderRecord > > readCurrent(OrderComponent &orders)
Definition RTSSystemMovementInternal.h:56
bool isSameHandle(const ecs::EntityHandle &left, const ecs::EntityHandle &right)
Definition RTSSystemMovementInternal.h:17
bool isMovementOrder(OrderKind kind)
Definition RTSSystemMovementInternal.h:29
std::optional< WorldPosition > entityPosition(const ecs::EntityHandle &handle)
Definition RTSSystemMovementInternal.h:48
bool isFinitePosition(WorldPosition position)
Definition RTSSystemMovementInternal.h:15
Definition RTS.cpp:24
std::function< Result< resource::Receipt >(Unit &, const resource::CostSpec &)> AbilityResourceDebit
Debits an ability resource cost through the game-owned canonical economy boundary.
Definition RTSSystems.h:492
std::function< map::Fov *(Faction &)> FogProvider
Resolves the canonical FOV instance used by a faction; allies may deliberately share one instance.
Definition RTSSystems.h:310
std::span< const SystemContract > systemContracts() noexcept
Return the phase-one RTS ECS contracts for tooling and review.
Definition RTSSystems.cpp:160
std::function< Result< resource::Receipt >(Building &, const resource::CostSpec &)> PassiveIncomeCredit
Credits passive building income through the game-owned canonical economy boundary.
Definition RTSSystems.h:402
std::function< void(const LifecycleEvent &, SimulationTick)> LifecycleEventSink
Read-only observer invoked after a non-combat lifecycle transition commits.
Definition RTSSystems.h:127
std::function< Result< std::string >(Building &, std::string_view)> ReinforcementEnqueue
Game-owned transactional enqueue boundary used while resolving reinforcement fallbacks.
Definition RTSSystems.h:746
std::function< Result< resource::Receipt >(Unit &, const resource::CostSpec &)> ResourceCredit
Callback that credits gathered resources to the authoritative account selected by the game.
Definition RTSSystems.h:358
std::function< void(const CombatFireEvent &, SimulationTick)> CombatFireEventSink
Read-only observer invoked after a weapon consumes one authoritative shot.
Definition RTSSystems.h:91
std::function< Result< void >(WorldPosition, LogicalId)> PlacementValidation
Caller-owned canonical terrain/occupancy validation used after RTS influence checks.
Definition RTSSystems.h:183
@ HoldPosition
@ Escort
@ AttackMove
@ Attack
@ Patrol
@ SupplyRelay
@ Resupply
std::function< Result< std::optional< ProjectileCollision > >(WorldPosition from, float fromHeight, WorldPosition to, float toHeight, SubjectRef source, ecs::EntityHandle intendedTarget)> ProjectileCollisionQuery
Map/physics-owned swept collision query; empty means the segment remained clear.
Definition RTSSystems.h:620
std::function< void(const combat::DamageRequest &request, const combat::DamageOutcome &outcome, SimulationTick tick, DamageChannel channel)> DamageEventSink
Read-only observer invoked after canonical damage has committed.
Definition RTSSystems.h:71
std::function< void(Unit &, const OrderRecord &)> NavigationEvent
Notification emitted once when a newly planned order has no canonical map route.
Definition RTSSystems.h:270
std::function< Result< void >(Faction &, Building &, const LogicalId &)> AIProductionRequest
Authoritative production boundary invoked by AI policy decisions.
Definition RTSSystems.h:571
std::function< Result< bool >(WorldPosition origin, WorldPosition target, ecs::EntityHandle source, ecs::EntityHandle targetEntity, const weapon::WeaponDefinition &weapon)> FireLineQuery
Uses canonical sensing, weapon and damage providers for RTS automatic fire.
Definition RTSSystems.h:584
std::function< CombatHeightProfile(WorldPosition origin, WorldPosition target, ecs::EntityHandle source, ecs::EntityHandle targetEntity)> CombatHeightQuery
Resolve absolute heights for one authorized projectile launch.
Definition RTSSystems.h:589
std::function< Result< resource::Receipt >(Unit &, Building &, const resource::CostSpec &)> RepairDebit
Callback that debits repair costs from the authoritative account selected by the game.
Definition RTSSystems.h:383
std::function< Result< std::size_t >(Building &, std::string_view, std::int64_t, std::size_t)> AmmoProductionPurchase
Assigns and transfers tactical ammunition through canonical WeaponEntity resource state.
Definition RTSSystems.h:425
std::function< Result< void >(Building &, std::string_view)> ReinforcementCancel
Pauses canonical production tasks when a shared rally combat group reaches reinforcement limits.
Definition RTSSystems.h:744
std::function< ecs::Entity *(SubjectRef)> ProjectileSubjectResolver
Resolve one stable RTS subject while restoring projectile relationships.
Definition RTSSystems.h:650
@ DistanceAscending
@ TruncateToMax
Keep the best maxCount candidates after sorting (legacy circle/box limit).
Result< AbilityReceipt > validateAbility(Battle &battle, SubjectRef actor, const LogicalId &action, Cell targetCell, SubjectRef targetUnit, std::string_view payload)
Validate one ability declaration without mutating anything.
Definition TacticsBattle.cpp:344
WidgetDesc progress(float fraction, std::string id, std::string overlay)
Progress bar; fraction is clamped to [0,1].
Definition Widget.cpp:395
WidgetDesc grid(int columns, std::vector< WidgetDesc > children, std::string id)
Fixed-column grid; children are placed in source order.
Definition Widget.cpp:687
@ Ranged
@ Ballistic
@ InvalidArgument
@ NotFound
@ Unsupported
@ InvariantViolation
@ StaleHandle
@ Conflict
@ NotFound
@ NoOp
@ Applied
detail::StrongUint64< detail::SimulationTickTag > SimulationTick
Deterministic simulation time step; it is not wall-clock time.
Definition Time.h:31
Mutable combat state owned by the gameplay domain for one subject.
Definition Damage.h:37
A subject-agnostic continuous task retained for audit and save games.
Definition Production.h:158
Typed ability policy; lifecycle effects remain owned by the canonical effect container.
Definition RTSTypes.h:133
Deterministic, canonical-map-validated artillery relocation choice.
Definition RTSSystems.h:520
bool avoidedDepartedPosition
Definition RTSSystems.h:526
Automatic targeting policy for a stationary defensive building.
Definition RTSTypes.h:958
Static command provider and hostile jamming policy.
Definition RTSTypes.h:1016
Construction progress and generation-checked assigned builders.
Definition RTSTypes.h:897
Building garrison capacity and generation-checked occupants.
Definition RTSTypes.h:973
Last indirect-fire exposure for static artillery and counter-battery observation.
Definition RTSTypes.h:1025
RTS infrastructure projection; economy balances remain owned by the linked provider.
Definition RTSTypes.h:1005
float buildInfluenceRadius
Definition RTSTypes.h:1010
Building health and repair economy configuration.
Definition RTSTypes.h:904
Placement world key and authoritative cell state.
Definition RTSTypes.h:859
RTS shield layer for structures; canonical CombatState remains health authority.
Definition RTSTypes.h:912
Static ammunition stock and transfer policy for completed buildings.
Definition RTSTypes.h:979
Static vision contribution projected into a faction-owned canonical map FOV provider.
Definition RTSTypes.h:991
Canonical weapon entity used by an armed building.
Definition RTSTypes.h:954
Adapter-owned keys previously mirrored into a shared sensing world.
Definition RTSSystems.h:595
Absolute muzzle and target heights resolved by the authoritative map/game adapter.
Definition RTSSystems.h:586
One domain-neutral command submitted to a unit's generic order queue.
Definition RTSTypes.h:101
Runtime-only revealer bindings; authoritative explored cells remain owned by map::Fov.
Definition RTSSystems.h:316
Complete in-flight RTS projectile state with stable gameplay relationships.
Definition RTSSystems.h:644
std::vector< RTSProjectilePayloadSnapshot > payloads
Definition RTSSystems.h:646
weapon::ProjectileRuntimeSnapshot runtime
Definition RTSSystems.h:645
Concurrent worker capacity and current generation-checked assignments.
Definition RTSTypes.h:1099
Authoritative world position and interaction radius.
Definition RTSTypes.h:1086
A safe map-reachable rendezvous selected around a predicted moving relay intercept.
Definition RTSSystems.h:446
Static metadata for one ECS system's access and phase contract.
Definition RTSSystems.h:56
Indirect-fire deployment and deterministic area-fire policy.
Definition RTSTypes.h:740
RTS stance and pursuit limits used by automatic combat policies.
Definition RTSTypes.h:610
Command-network policy and derived connection state for a mobile unit or relay.
Definition RTSTypes.h:655
Unit containment state for transports and building garrisons.
Definition RTSTypes.h:693
Canonical combat durability state consumed by combat::DamageRuntime.
Definition RTSTypes.h:631
Suppression, recovery, retreat policy, and friendly morale aura.
Definition RTSTypes.h:724
Authoritative kinematic state used by the phase-one move slice.
Definition RTSTypes.h:560
RTS shield layer consumed before canonical health damage and regenerated deterministically.
Definition RTSTypes.h:636
Tactical ammunition logistics; weapon ammunition remains authoritative in WeaponEntity.
Definition RTSTypes.h:699
Escort geometry and combat-group coordination state.
Definition RTSTypes.h:764
Vision contribution projected into a faction-owned canonical map FOV provider.
Definition RTSTypes.h:586
Worker gathering and delivery state; balances remain owned by the linked economy account.
Definition RTSTypes.h:598
World2D origin used for range tests and distance sorting.
Definition Sensing.h:117
std::vector< std::string > excludeFactions
Definition Sensing.h:105
std::vector< std::string > requiredTags
Definition Sensing.h:102
Data-driven trajectory and lifetime definition.
Definition ProjectileRuntime.h:51
std::vector< ProjectileSlotSnapshot > slots
Definition ProjectileRuntime.h:98
Owning spawn request; homing requests require a generation-checked target.
Definition ProjectileRuntime.h:64
ProjectilePoint position
Definition ProjectileRuntime.h:65