HammeriteAudioBrushProperties
Audio. Inherits RefCounted
The acoustic character of a room, authored on the air brush that carves it.
In the subtractive world an air brush IS a room and the compiler already derives which rooms exist and which openings join them. What it cannot derive is intent: whether a courtyard should be treated as open sky, how much weather gets into a covered alley, whether a chamber should ring like stone or be deadened like a carpeted study. Those are authoring decisions, and before this schema existed there was nowhere on a brush to put them - which is why acoustics needed a parallel world of hand-placed zone entities to hold them. So: hammerite-audio declares them, core stores them sparsely on the brush, and the audio graph reads them off the cells. Core never learns what a reverb preset is. Every property AUTO-derives by default, so an author who places nothing and touches nothing still gets a working graph - the overrides exist for the cases derivation gets wrong.
Methods
| Returns | Method |
|---|---|
void | register() static |
bool | is_excluded(map: HammeriteMap, cell: HammeriteCell) static |
int | zone_type_for_cell(map: HammeriteMap, cell: HammeriteCell) static |
int | preset_id_for_cell(map: HammeriteMap, cell: HammeriteCell) static |
int | get_preset(brush: HammeriteBrush) static |
bool | set_preset(brush: HammeriteBrush, preset_id: int) static |
float | weather_exposure_for_cell(map: HammeriteMap, cell: HammeriteCell) static |
Enumerations
enum ZoneTypeChoice
| Value | Name | Description |
|---|---|---|
0 | AUTO | Exterior when the room is open to the sky itself (HammeriteMap.cell_is_open_to_sky()), else interior. |
1 | INTERIOR | Weather is heard only through the openings that lead outdoors. |
2 | EXTERIOR | Outdoors: weather is heard all round. |
3 | SEMI_EXTERIOR | Covered outdoors, weather scaled by KEY_WEATHER_EXPOSURE. Never derived. |
Constants
SCHEMA_ID
const SCHEMA_ID = &"audio"
Schema id, and therefore the namespace of every key below.
KEY_ZONE_TYPE
const KEY_ZONE_TYPE = &"audio/zone_type"
Brush property holding a ZoneTypeChoice; read it through zone_type_for_cell().
KEY_PRESET
const KEY_PRESET = &"audio/reverb_preset"
Brush property holding a reverb preset by its id, PRESET_AUTO for "pick one from what the room is built of". Read it through preset_id_for_cell() or get_preset(), write it through set_preset().
KEY_WEATHER_EXPOSURE
const KEY_WEATHER_EXPOSURE = &"audio/weather_exposure"
Brush property, 0..1: how much weather reaches a semi-exterior room. See weather_exposure_for_cell().
KEY_EXCLUDE
const KEY_EXCLUDE = &"audio/exclude"
Brush property: true leaves the room out of the audio graph. See is_excluded().
KEY_AMBIENT
const KEY_AMBIENT = &"audio/ambient"
Brush property: the game's id for the room's ambient bed, resolved through HammeriteAudioRuntime.ambient_resolver. Empty is silence.
KEY_AMBIENT_VOLUME
const KEY_AMBIENT_VOLUME = &"audio/ambient_volume"
Brush property: the room's ambience level, in dB.
PRESET_AUTO
const PRESET_AUTO = -1
The KEY_PRESET value meaning "pick the preset from what the room is built of" - sample the boundary materials rather than take an authored answer. Not a real preset id, and deliberately outside their range, so that every other value stored IS the id. It used to be 0 with the ids offset by one above it, which made set_property(KEY_PRESET, HammeriteAudioPreset.Kind.STONE_HALL_LARGE) - id 0 - mean Auto, and every other preset come out one off (#242).
Method descriptions
register()
static func register() -> void
Declare the acoustic schema with HammeriteBrushPropertyRegistry. Called from the HammeriteAudio autoload rather than from the editor plugin, because the registry is what supplies DEFAULTS at read time: a shipped game with no editor still has to resolve every property an author never overrode. Idempotent - registering twice replaces the schema rather than stacking a second copy.
is_excluded()
static func is_excluded(map: HammeriteMap, cell: HammeriteCell) -> bool
Is cell's room excluded from the audio graph?
zone_type_for_cell()
static func zone_type_for_cell(map: HammeriteMap, cell: HammeriteCell) -> int
The HammeriteAudioZone.ZoneType for cell, resolving AUTO through the compiled graph: a room that is open to the sky ITSELF is exterior, anything else is interior. Note this asks HammeriteMap.cell_is_open_to_sky(), not HammeriteMap.cell_reaches_sky(). Those differ exactly where it matters here: a room with a window onto a courtyard REACHES the sky, and the lightmapper rightly lets daylight in through the window - but the room is not outdoors, and its weather should arrive through that window rather than falling on the listener's head. Using reachability made every room with a window read as open air, which is the wrong answer for every one of them. Semi-exterior is never derived - a covered space looks exactly like an open one to either test - so it is the one answer an author has to give.
preset_id_for_cell()
static func preset_id_for_cell(map: HammeriteMap, cell: HammeriteCell) -> int
The authored preset id for cell, or -1 when the author left it on Auto and the caller should derive one from the room's materials instead.
get_preset()
static func get_preset(brush: HammeriteBrush) -> int
The reverb preset brush's room is authored to, or PRESET_AUTO for one derived from what it is built of.
set_preset()
static func set_preset(brush: HammeriteBrush, preset_id: int) -> bool
Author brush's room to reverb preset preset_id, or to PRESET_AUTO for one derived from its materials. False for a preset no table defines. The value stored IS the id, so this and HammeriteBrush.set_property() agree - which they did not when the property held the id plus one (#242).
weather_exposure_for_cell()
static func weather_exposure_for_cell(map: HammeriteMap, cell: HammeriteCell) -> float
Weather exposure for cell (0 sheltered .. 1 open). Only a semi-exterior room has a partial answer; the other two are decided by what they are, and returning their implied value here keeps callers from having to special-case the zone type.