Block 4 — Raid Resolution (2 days)
Goal: Dispatched raids play out in three phases on the city map: group travel, looting with probabilistic encounter + backup window, and group return. Encounters can kill or capture raccoons.
Depends on: Block 3 (dispatch system, city map, raid targets, crew assignment).
Deliverables
New Enums
UENUM(BlueprintType)
enum class ERaidPhase : uint8
{
Traveling,
Looting,
EncounterPending,
Returning,
Complete
};New Structs
USTRUCT(BlueprintType)
struct FActiveRaid
{
UPROPERTY() FGuid RaidId;
UPROPERTY() TSoftObjectPtr<URaidTargetDataAsset> Target;
UPROPERTY() TArray<FGuid> CrewRaccoonIds;
UPROPERTY() TArray<FGuid> BackupRaccoonIds; // encounter-only reinforcements
UPROPERTY() ERaidPhase Phase;
UPROPERTY() float TravelTime; // seconds, group travel to target
UPROPERTY() float TravelElapsed; // seconds into travel
UPROPERTY() float LootProgress; // 0.0–1.0
UPROPERTY() float TotalWork; // fixed per target
UPROPERTY() float CompletionSpeed; // from weighted formula
UPROPERTY() bool bEncounterScheduled; // rolled at dispatch
UPROPERTY() float BackupWindowRemaining; // countdown when EncounterPending
UPROPERTY() float BackupTravelTime; // backup group travel time
UPROPERTY() float BackupTravelElapsed; // backup group progress
UPROPERTY() UEncounterDataAsset* PendingEncounter; // which encounter, if scheduled
UPROPERTY() FLootPayload PendingLoot;
UPROPERTY() TArray<TWeakObjectPtr<ATNTRaccoonAIPawn>> SpawnedPawns; // transient
UPROPERTY() TArray<TWeakObjectPtr<ATNTRaccoonAIPawn>> BackupPawns; // transient
UPROPERTY() bool bIsDaytimeRaid; // snapshot at dispatch for 2x encounter chance
};URaidSubsystem — Full Resolution (C++)
| Function | Signature | Purpose |
|---|---|---|
DispatchRaid | FGuid (URaidTargetDataAsset*, TArray<FGuid>) | (Update from Block 3) Calculate CrewAvgSpeed = sum(Speed) / CrewSize. TravelTime = NavMeshDistance(HideoutExit, Target) / (CrewAvgSpeed * SpeedScale). Generate loot. Roll encounter chance (see formula below). Spawn crew AI pawns as a group at HideoutExit. Set Phase = Traveling. Snapshot bIsDaytimeRaid from current clock. |
TickRaids | void (float DeltaTime) | Called from subsystem Tick. Phase state machine per active raid — see “Tick State Machine” below. |
ResolveEncounter | FEncounterResult (FActiveRaid&) | Sum relevant stat from all on-site crew + arrived backup. Compare vs threshold. Apply tiered casualties. Broadcast OnEncounterResolved. |
DispatchBackup | void (FGuid RaidId, TArray<FGuid> BackupIds) | Validate all backup raccoons are Idle. Set status to Raiding. Calculate backup group travel time (NavMeshDistance / BackupAvgSpeed * SpeedScale). Add to FActiveRaid::BackupRaccoonIds. Spawn backup AI pawns at HideoutExit. |
GenerateLoot | FLootPayload (URaidTargetDataAsset*, TArray<FGuid>) | C++ — weighted random rolls. Same as Block 3 spec. Hauler Strength scales loot volume. |
CompleteRaid | void (FGuid) | Set original crew raccoons to Idle (or leave dead/captured ones removed). Despawn crew AI pawns. Despawn any remaining backup pawns. Deposit FLootPayload to Loot Sorting Station. Broadcast OnRaidCompleted. |
GetActiveRaids | TArray<FActiveRaid> () | For HUD and city map display. |
Internal state (extends Block 1 stub — ActiveRaids declared there; OnEncounterPending and OnRaidDispatched declared in Block 3):
| Member | Type | Purpose |
|---|---|---|
OnRaidCompleted | FOnRaidCompleted (DYNAMIC_MULTICAST_DELEGATE_TwoParams) | BlueprintAssignable. Params: FGuid RaidId, FLootPayload Loot |
OnEncounterResolved | FOnEncounterResolved (DYNAMIC_MULTICAST_DELEGATE_TwoParams) | BlueprintAssignable. Params: FGuid RaidId, FEncounterResult Result |
HideoutExitActor | ATNTHideoutExit* | Cached spawn/despawn point for AI pawns in L_City. Resolved in Initialize() |
BackupWindowDuration | float | Tunable backup window length (120–180s). UPROPERTY(EditDefaultsOnly) |
StealthScale | float | Tunable divisor for encounter chance formula (default 200). UPROPERTY(EditDefaultsOnly) |
SpeedScale | float | Tunable multiplier for travel speed calculation. UPROPERTY(EditDefaultsOnly) |
Encounter Chance Formula
Rolled once at dispatch time. Result stored in bEncounterScheduled.
EncounterChance = TargetBaseChance * (1 - CrewStealthSum / StealthScale)
if bIsDaytimeRaid: EncounterChance *= 2.0
if any crew raccoon is Scout: EncounterChance *= 0.5
EncounterChance = clamp(EncounterChance, 0, 0.95)
bEncounterScheduled = (FMath::FRand() < EncounterChance)
If scheduled, select encounter type from target’s weighted encounter pool (random by pool weights). Store in PendingEncounter.
StealthScale is a global tunable constant (e.g., 200). TargetBaseChance comes from the URaidTargetDataAsset.
Tick State Machine
Per active raid, each tick:
Traveling:
TravelElapsed += DeltaTime
if TravelElapsed >= TravelTime:
Phase = Looting
// crew pawns arrive at building, begin looting animation
Looting:
LootProgress += CompletionSpeed * DeltaTime / TotalWork
if LootProgress >= 0.5 AND bEncounterScheduled AND Phase == Looting:
Phase = EncounterPending
BackupWindowRemaining = BackupWindowDuration // tunable, 120–180 seconds
Broadcast OnEncounterPending(RaidId, PendingEncounter)
if LootProgress >= 1.0:
Phase = Returning
TravelElapsed = 0 // reset for return trip
EncounterPending:
BackupWindowRemaining -= DeltaTime
// Also tick backup travel if backup dispatched:
if BackupRaccoonIds.Num() > 0:
BackupTravelElapsed += DeltaTime
if BackupWindowRemaining <= 0 OR player confirms resolve:
// Determine which backup arrived:
// backup counts if BackupTravelElapsed >= BackupTravelTime
ResolveEncounter(Raid)
// Remove dead/captured raccoons from crew
bEncounterScheduled = false // consumed
Phase = Looting // resume from 50%
// If entire crew wiped: Phase = Returning (abort, partial/no loot)
Returning:
TravelElapsed += DeltaTime
if TravelElapsed >= TravelTime:
CompleteRaid(RaidId)
Phase = Complete
Encounter Resolution — Stat Check
// Dual-check: use whichever stat sum is higher
int32 StatSumA = GetCrewStatSum(OnSiteIds, EncounterCheckStatA);
int32 StatSumB = GetCrewStatSum(OnSiteIds, EncounterCheckStatB);
int32 BestSum = FMath::Max(StatSumA, StatSumB);
if (BestSum >= Threshold) → Pass
else → Fail, apply casualtiesOnSiteIds = original crew (alive) + backup that arrived before window closed.
Encounter DataAssets (authored)
| Asset | Check A | Check B | Threshold (Easy) | Threshold (Medium) | Threshold (Hard) |
|---|---|---|---|---|---|
DA_AggressiveDog | Speed | Strength | 15 | 25 | 40 |
DA_AnimalControl | Stealth | Cunning | 12 | 22 | 35 |
Casualty Tiers
float Deficit = (Threshold - BestSum) / (float)Threshold;
int32 Casualties;
if (Deficit <= 0.20) Casualties = 1; // close fail
else if (Deficit <= 0.50) Casualties = 2; // medium fail
else Casualties = FMath::CeilToInt(OnSiteIds.Num() * 0.5f); // catastrophic
// Select victims: sort on-site raccoons by relevant stat ascending
// Kill/capture from weakest first| Encounter Type | Fail Consequence |
|---|---|
| Aggressive Dog | Raccoons die. RemoveRaccoon(Id). Permanent. |
| Animal Control | Raccoons captured. RemoveRaccoon(Id). Post-MVP: recoverable from Animal Control HQ. |
Backup raccoons are in the casualty pool — they can die/be captured too.
Raccoon AI Pawns (City Map)
ATNTRaccoonAIPawn extending APawn:
- Spawned by
URaidSubsystem::DispatchRaidatATNTHideoutExitlocation inL_City UFloatingPawnMovementwithMaxSpeedset fromCrewAvgSpeed * SpeedScale- All crew pawns move as a group — same speed, same path
- Controlled by
BP_RaccoonAIController(AAIControllersubclass) - Visual: capsule/sphere with team-colored material during blockout
Behavior Tree (BT_RaccoonRaid):
Simple sequence:
- MoveTo →
TargetBuilding(group travel) - PlayAnimation → looting idle at building
- WaitForSignal →
URaidSubsystemsignals looting complete (may include encounter pause) - MoveTo →
HideoutExit(return home)
Backup Pawns: Separate group, same behavior tree but target is the building where the encounter is happening. After encounter resolves, backup pawns reroute to HideoutExit and despawn on arrival.
Blackboard (BB_RaccoonRaid):
| Key | Type | Set By |
|---|---|---|
TargetBuilding | Object (AActor*) | URaidSubsystem at spawn |
HideoutExit | Object (AActor*) | URaidSubsystem at spawn |
MoveSpeed | Float | CrewAvgSpeed * SpeedScale |
RaidPhase | Enum | Updated by URaidSubsystem |
Encounter Visual Feedback
When OnEncounterPending fires:
- HUD alert: “[Crew] encountered [threat] at [Target]! Backup window: 2:00”
- Encounter icon appears over building on city map
- Crew pawns freeze in defensive pose
When OnEncounterResolved fires:
- Death → affected pawn fades out with skull icon
- Capture → affected pawn dragged off-screen by invisible force, net icon
- Pass → brief relief animation, green checkmark, looting resumes
- Backup arrival → new pawns visibly running to join the group
Raid Completion Flow
TickRaidsdetectsLootProgress >= 1.0- Phase → Returning, crew pawns navigate back to HideoutExit
TravelElapsed >= TravelTime→CompleteRaid(RaidId)- Surviving crew raccoons → Idle via
URaccoonSubsystem::SetStatus - AI pawns despawned from city map
FLootPayloaddeposited to Loot Sorting Station storage (if cap allows)OnRaidCompletedbroadcast with RaidId + LootPayload- HUD notification: “Crew returned from [Target]!”
Done When
- Dispatched raids play out on city map — crew pawns visibly travel as a group to target and back
- Travel speed scales with crew average Speed stat
- Looting phase progresses and completes
- Encounter chance is rolled at dispatch based on Stealth, Scout presence, and daytime modifier
- When encounter triggers at 50% progress, raid pauses and backup window opens
- Player can walk to Raid Board, see encounter alert, and dispatch backup raccoons
- Backup raccoons travel as their own group; only arrived backup counts for stat check
- Encounter resolves with tiered casualties (1 / 2 / half crew)
- Failed dog encounter kills raccoons (permanent removal)
- Failed animal control encounter captures raccoons (permanent removal)
- Backup raccoons can be casualties
- Crew returns → loot deposited → raccoons update status
-
OnRaidCompleted,OnEncounterPending,OnEncounterResolveddelegates fire correctly - AI pawns show visual feedback for encounter results
References
Raid Encounters · Encounters MOC · Core Loop · Game Clock · Raid Resolution