Weapon data and optics
ROCK already resolves the equipped weapon's physical and record-authored evidence. Consume these snapshots instead of re-scanning the scene graph or reimplementing classification in every addon.
queryEquippedWeaponClassificationV1 · slot 33
bool queryEquippedWeaponClassificationV1(
RockProviderWeaponClassificationV1* outResult);
Returns the current equipped weapon's coarse size class, raw weapon-keyword mask, form ID, weapon generation, confidence, source, and provenance.
The output must have the exact current size. Returns false when the provider
is unavailable or no equipped weapon can be classified.
Size classes:
Melee;Pistol;Rifle;Heavy.
Classification source and current confidence:
| Source | Meaning | Confidence |
|---|---|---|
Keyword | One or more recognized WeaponType* keywords. | 1.0 |
WeightFallback | Physical/mesh fallback when authored tags were absent. | 0.65 |
Default | Conservative default classification. | 0.35 |
None | No usable classification. | 0.0 |
keywordFlags is deliberately a mask, not a single enum. A weapon can be both
Rifle and Shotgun, for example. Prefer the most specific flag your feature
understands, then fall back to sizeClass.
Provenance flags identify keyword evidence, mesh-bounds fallback, and whether the result is generation-bound.
RockProviderWeaponClassificationV1 weapon{};
if (RockProviderApi::inst->queryEquippedWeaponClassificationV1(&weapon) &&
weapon.valid != 0) {
const bool shotgun = hasWeaponKeywordFlagV1(
weapon.keywordFlags,
RockProviderWeaponKeywordFlagV1::Shotgun);
// Pick shotgun-specific behavior, otherwise use weapon.sizeClass.
}
getWeaponEvidenceDetailCountV1 · slot 10
std::uint32_t getWeaponEvidenceDetailCountV1();
Returns the number of current generated weapon evidence rows, or 0 when
unready/no rows. Current public maximum is eight.
copyWeaponEvidenceDetailsV1 · slot 11
std::uint32_t copyWeaponEvidenceDetailsV1(
RockProviderWeaponEvidenceDetailV1* outDetails,
std::uint32_t maxDetails);
Copies up to maxDetails rows and returns the number copied. Returns 0 for a
null buffer, zero capacity, unready provider, or no data.
Each row describes one generated collision/evidence body:
- body ID and weapon generation;
- public part kind plus reload/support/socket/action semantic roles;
- fallback grip-pose ID;
- local generated bounds and total point count;
- source name;
- installed OMOD and attach-point form IDs when known;
- classification provenance (
NameToken,SlotAnchor,RigAnchor, orAttachmentEvidence); - legacy interaction/source root identity witnesses.
Prefer the record-authored OMOD/attach identity and semantic enum fields. Never dereference the root witnesses.
getWeaponEvidenceDetailPointCountV1 · slot 12
std::uint32_t getWeaponEvidenceDetailPointCountV1(
std::uint32_t bodyId);
Returns the local generated mesh point count for the evidence body, or 0 if
the body is absent/stale. Public output is bounded to 252 points per detail.
copyWeaponEvidenceDetailPointsV1 · slot 13
std::uint32_t copyWeaponEvidenceDetailPointsV1(
std::uint32_t bodyId,
RockProviderPoint3* outPoints,
std::uint32_t maxPoints);
Copies local game-unit mesh points for one evidence body. Returns the copied
count, or 0 for invalid buffer/capacity, stale body identity, or unavailable
data. Associate them with the same weaponGenerationKey as the detail row.
Use bounds for broad decisions; copy the full cloud only when your feature actually needs geometry.
getWeaponEmitterCountV1 · slot 37
std::uint32_t getWeaponEmitterCountV1();
Returns the current count of discovered flashlight, laser, and reticle emitters,
or 0 when unavailable. Maximum is 32.
copyWeaponEmittersV1 · slot 38
std::uint32_t copyWeaponEmittersV1(
RockProviderWeaponEmitterV1* outEmitters,
std::uint32_t maxEmitters);
Copies value-only emitter rows. Each row includes:
- kind:
Flashlight,Laser, orReticle; - source: live effect geometry or an authored add-on node;
- weapon-local transform and forward vector;
- effective
activeand nodevisiblestate; - whether effect state is actually known;
- add-on value, OMOD, attach-point, source name, and weapon generation.
active == 0 means “known inactive” only when EffectStateKnown is set. An
add-on marker without a live effect can have unknown effect state.
Use TransformValid and DirectionValid independently. Do not assume a
visible marker means its effect is active.
getScopeSightStateV1 · slot 67 · callback-only
RockProviderResultV1 getScopeSightStateV1(
std::uint64_t ownerToken,
RockProviderScopeSightStateV1* outState);
Requires ScopeSightState and the game-thread callback boundary. Returns the
current equipped optic state without requiring the consumer to traverse weapon
nodes.
Fields include:
- frame, publication sequence, weapon form/generation, and broader generations;
Available,Active,MenuOpen, anchor/bounds validity, native overlay validity, and direct-transition requirement flags;- activation source: native geometry, ROCK geometry, or manual input;
- native overlay index;
- weapon-local anchor and sight bounds;
- matching sight/scope body, OMOD, and attach-point identities.
Returns TargetUnavailable when there is no current scope/sight snapshot,
WrongThread outside the callback boundary, or standard validation/
owner/capability/readiness errors.
ManualDirectTransitionRequired is a coordination signal: the current optic
cannot rely solely on the ordinary native geometry transition. It is not
permission to manipulate arbitrary native menu or render state.
getWeaponCompositionStateV1 · slot 68
RockProviderResultV1 getWeaponCompositionStateV1(
std::uint64_t ownerToken,
RockProviderWeaponCompositionStateV1* outState);
Requires WeaponComposition. This synchronized value query is not
callback-only.
Returns:
- weapon form/generation;
compositionSignaturefor change detection;- number of entries;
- aggregate semantic coverage mask;
- missing-coverage mask;
- publication sequence.
In semanticCoverageMask, bit N corresponds to public
RockProviderWeaponPartKindV1 ordinal N. missingCoverageMask instead uses
the composition entry's stableIndex: a bit means an active entry had no
matching semantic evidence row.
Treat compositionSignature as an opaque equality token. Re-read entries when
it changes; do not persist or decode the hash.
Returns TargetUnavailable when no current composition exists.
copyWeaponCompositionEntriesV1 · slot 69
RockProviderResultV1 copyWeaponCompositionEntriesV1(
std::uint64_t ownerToken,
RockProviderWeaponCompositionEntryV1* outEntries,
std::uint32_t maxEntries,
std::uint32_t* outEntryCount);
Requires WeaponComposition. Copies up to 64 installed composition rows. Zero
capacity permits a null data pointer and reports count 0; use the state call's
entryCount to size a buffer.
Each entry provides OMOD form ID, attach-point form ID, stable index, semantic coverage bits, and flags:
Active;Disabled;AttachPointResolved;SemanticEvidenceMatched.
The stable index is stable within the current composition snapshot, not across weapon generations.
Example: cache weapon metadata by generation/signature
struct WeaponCache
{
std::uint64_t generation{0};
std::uint64_t compositionSignature{0};
RockProviderWeaponClassificationV1 classification{};
std::array<RockProviderWeaponCompositionEntryV1, 64> entries{};
std::uint32_t entryCount{0};
};
bool refreshWeaponCache(std::uint64_t ownerToken, WeaponCache& cache)
{
RockProviderWeaponCompositionStateV1 state{};
if (RockProviderApi::inst->getWeaponCompositionStateV1(
ownerToken, &state) != RockProviderResultV1::Ok) {
cache = {};
return false;
}
if (cache.generation == state.weaponGenerationKey &&
cache.compositionSignature == state.compositionSignature) {
return true;
}
RockProviderWeaponClassificationV1 classification{};
if (!RockProviderApi::inst->queryEquippedWeaponClassificationV1(
&classification)) {
cache = {};
return false;
}
std::uint32_t copied = 0;
const auto result = RockProviderApi::inst->copyWeaponCompositionEntriesV1(
ownerToken,
cache.entries.data(),
static_cast<std::uint32_t>(cache.entries.size()),
&copied);
if (result != RockProviderResultV1::Ok) {
cache = {};
return false;
}
cache.generation = state.weaponGenerationKey;
cache.compositionSignature = state.compositionSignature;
cache.classification = classification;
cache.entryCount = copied;
return true;
}
This gives reload, scope, handling, UI, or analytics addons a shared weapon identity without scanning live objects themselves.