Campaign Photo Safari
Photo safari mission system for campaign exploration. Players drive to locations, enter photo mode, and capture specific objects within camera constraints.
Photo safari mission system for campaign exploration. Players drive to locations, enter photo mode, and capture specific objects within camera constraints.
Overview
Manages photo safari missions where players must photograph target objects from correct positions. Tracks found/unfound locations, unlocks progressive hints via trigger zones, and validates photos against camera frustum and distance checks.
Public API
| Function | Args | Returns | Description |
|---|---|---|---|
M.missionaccepted | file | - | Loads photo safari JSON data and initializes mission state |
M.onBeamNGTrigger | data | - | Processes trigger events for hints and photo locations |
M.takepiccheck | - | boolean | Validates photo from photo mode (object in frustum, camera distance) |
Module State
| Field | Type | Description |
|---|---|---|
M.accept | boolean | Whether a photo safari mission is active |
M.photomodeOpen | boolean | Whether player is in a photo-eligible trigger zone |
M.targetObj | string | Name of the scene object to photograph |
Mission Data Format
{
"location_key": {
"objectName": "SceneObjectName",
"closeToPhoto": "trigger_name",
"hints": ["Hint 1", "Hint 2", "Hint 3"]
}
}Photo Validation
takepiccheck() performs these checks:
- Already found - Skip if location already photographed
- Close enough - Player must be near the target trigger
- Camera distance - Camera must not be farther than initial entry distance
- Frustum check - Target object's world box must be fully contained in camera frustum
- Special case: on-site - Additional vehicle position check for
on_sitelocations
-- Frustum validation
if not Engine.sceneGetCameraFrustum():isBoxOutside(sceneObject:getWorldBox())
and Engine.sceneGetCameraFrustum():isBoxContained(sceneObject:getWorldBox()) then
-- Photo accepted!
endHint System
Hints are unlocked progressively by entering specific trigger zones:
-- Predefined hint triggers
local hintTriggers = {
'prototype_2_trigger_CD',
'prototype_2_shady_trigger',
'prototype_2_ranger_trigger',
'prototype_2_stuntman_trigger',
'prototype_2_police_trigger'
}
-- Each trigger visited unlocks the next hint level for all unfound locationsTrigger Flow
Enter hint trigger → Unlock next hint for all unfound locations
Enter photo location trigger → Set photomodeOpen, record target object
Enter closeToPhoto trigger → Enable photo validation, record camera distance
Exit photo location → Disable photomodeOpenIntegration
Called from campaign_exploration.openLocationExtraUI():
if locationInfo.subtype == 'photoMode' then
campaign_photoSafari.missionaccepted(locationData.filepath)
endPhoto safari data is also read by campaign_exploration.getMinimapInfo() for minimap POI display.
Notes
- Photo validation exits photo mode and shows a flash message with the result
simTimeAuthority.pause(false)is called after validation to resume gameplay- The
on_sitelocation has special handling requiring both vehicle and camera positioning seentable tracks which hint triggers have been visited (prevents re-triggering)- Camera distance reference is set on first entry to the
closeToPhototrigger - Uses
Engine.sceneGetCameraFrustum()for real-time frustum queries
See Also
- Campaign Exploration - Triggers photo safari from exploration UI
- Campaign System - Campaign orchestration
Additional Exports
M.cameraDistanceToObject- (undocumented)M.closeToPhoto- (undocumented)M.count- (undocumented)M.description- (undocumented)M.foundLocation- (undocumented)M.location- (undocumented)M.msg- (undocumented)M.photoSafariData- (undocumented)M.photoSafarimissions- (undocumented)M.showhint- (undocumented)
Campaign Exploration
Free-roam exploration mode between campaign scenarios. Manages trigger zones, location markers, road navigation, minimap UI, vehicle spawning, and transitions between exploration and scenarios.
Campaign Rewards
Processes and distributes rewards from campaign scenarios - items, vehicles, and player choices.