| Commit message (Collapse) | Author | Age | Files | Lines |
| | |
|
| |
|
|
|
|
|
|
|
|
|
| |
Every persisted setting now lives in a single descriptor table
(config_table.cpp) with its section, key, type, default and clamp range.
config_save(), config_load() and config_reset_defaults() iterate it, so the
three functions can no longer disagree about defaults or bounds, and the old
hand-written 350-line parser is gone.
Section and key names are unchanged, so existing config files keep loading, and
the duplicated [view] scalar clamp block is replaced by per-entry limits.
|
| | |
|
| |
|
|
|
|
|
|
| |
esp.cpp keeps the scan and drawing (~1000 lines, down from 3665). Entity
lookups and NPC classification move to entity_query.cpp together with the
per-map caches and the session reset; combat (aimbot, silent aim, melee,
spread, triggerbot) moves to combat.cpp. Shared helpers are declared in
esp_internal.h.
|
| |
|
|
|
| |
Second slice of the esp.cpp split. Model-name lookup joins the shared helpers in
esp_internal.h.
|
| |
|
|
|
|
| |
First slice of the esp.cpp split. Shared helpers move to esp_internal.h
(entity lookups, screen size, surf primitives, segment projection); esp.cpp
keeps the definitions and drops their static qualifiers.
|
| |
|
|
|
|
|
|
| |
hl2h.h becomes an umbrella over core.h (logging, init stage, module snapshots,
interfaces, netvars, CUserCmd, engine constants, vector math), settings.h
(feature ids, feature state, user settings) and features.h (cross-module
declarations). Translation units keep including hl2h.h, so this only moves
declarations.
|
| |
|
|
|
|
|
|
|
| |
Move vtable patching into hooks.cpp: one call clones the table, validates every
slot, records the originals and installs the clone. Installs happen from the
setup, game and paint threads, so the bookkeeping is mutex-protected.
Client, CInput, IVModelRender, IStudioRender and ISurface all use it, and
hooks_restore_all() can now put every interface back (previously impossible).
|
| |
|
|
|
|
|
|
|
|
|
| |
Shadow-depth and reflection passes call DrawModelExecute with a material
already forced via IVModelRender::ForcedMaterialOverride. Chams could not tell
that apart from a free draw, substituted its own material (putting chams into
the shadow map) and then cleared the override to null, which broke the shadow
material for every model drawn afterwards.
Hook slot 1 as a tracker so the current forced material is known, and skip the
chams substitution whenever one is active.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Crash/UB:
- gate every hook behind an init-stage flag until config/surface/input are ready
- publish module maps as immutable atomic snapshots instead of reallocating
shared vectors under unlocked readers
- validate the %ebp walk in the RandomSeed/RandomFloat hooks against the stack
- bounds-check every RecvTable/RecvProp/string dereference with module_range()
- preserve the Itanium vtable header when cloning (client, CInput, model render,
studio render)
- reject negative usercmd sequence numbers; guard config_load against a null
section target; cap the bone parent walk; check mprotect; drop PROT_EXEC on
the GOT patch; absorb server.so .bss tail
Correctness:
- filter dormant entities across ESP, aimbot, triggerbot, melee, items and
projectiles (slot self-tested against the local player)
- reset the server-health latch per map and only latch on valid model indices
- bone cache sized for the 128-target scan; set valid=false on every failure;
head_position keeps searching past an invalid bone
- vischeck steps past glass by probing until clear, and ignores entities owned
by the target (held weapons, bone followers)
- aimbot: maxs no longer disables it, AABB-aware FOV prefilter, lock hysteresis,
lead point re-checked for FOV and visibility
- spread: seed hook arms on the no-spread toggle alone; engine toggle only
controls the RandomFloat zeroing
- resolve m_hOwnerEntity/m_hOwner; NPC lead velocity from the server entity
- vector_angles pitch range, point_ground normal test, underwater jump+duck no
longer skips combat, semi-auto press/release edge for synthetic fire
- item/projectile markers and blast rings refresh origin per frame while
discovery stays at 10 Hz; trajectory uses the real m_DmgRadius and honours
the blast-radius toggle
Rendering/GUI:
- one overlay draw per engine frame (FRAME_RENDER_START boundary), fixing
alpha stacking and the speed-graph flicker
- clipped lines/outlines and ellipsised text instead of drawing past the
content pane or shifting over neighbours
- dropdown dismissal consumes the click; hover ignores hidden controls
- chams: reset AlphaModulate, reference shared materials once, restore prop
tint colour; fonts created once per handle
- projection uses Source's 4:3 aspect scaling and roll; screen size refreshed
each frame; FOV circle gated on the aim toggles, not the bind
Performance:
- TTL caches for NPC relation, friendly/neutral and damage class
- model names memoised per model index
- entity pointer -> index cache for the triggerbot (was a 4096-slot walk/tick)
Build:
- real Makefile with -MMD dependency tracking, debug/release objects and an
always-relink rule; build.sh kept as a thin wrapper
|
| |
|
|
|
| |
One line with each nonzero m_iAmmo type as "type:count/max" (0:270/270
8:3/3 11:5/5 ...) to diagnose any remaining "full ammo still shows" reports.
|
| |
|
|
|
|
|
|
|
|
| |
- local_ammo now prefers the authoritative server m_iAmmo array (header skip)
and only falls back to the client netvar array. The client offset can be off
by an element, which made "full" checks flicker as other ammo was spent.
- Frag grenade pickups were falling through to a generic "Ammo" label with
ammo_type=-1, so the usable filter never ran. w_grenade/w_frag/
items/grenade/frag_grenade are now "Frag grenade" and map to m_iAmmo[11]
(sk_max_grenade, stock 5); AR2/SMG1 grenade variants map to m_iAmmo[8].
|
| |
|
|
|
|
|
|
|
|
|
|
| |
The health charger's candidate m_iJuice offset (0x3c8) read 0 on a full
charger, so the empty-hide made health chargers disappear entirely. Restrict
the hide to suit chargers (verified 0x47c) until the health offset is
confirmed; health chargers stay visible.
Classify with the server class name when the client class is generic, accept
`healthcharger` in the health branch (maps use item_healthcharger /
CNewWallHealth, not the func_healthcharger brush), and log up to eight
`juice:` lines with the class and both candidate offsets/values.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- Prefer the local player's thrown frag over the pre-throw estimate: resolve
CBaseGrenade::m_hThrower from the server datamap (client owner handles as
fallback), then seed the prediction from the live origin/velocity. The real
frag is a spinning VPhysics box with a random Y angular impulse, so bounce
points remain approximate; the doc now says so.
- Keep 512 path points sampled every other 20 ms step (up to 24 s) instead of
127 points / ~2.5 s, so the line reaches the landing instead of stopping in
mid-air.
- Radius rings use 36 segments; a segment whose near-plane-clipped endpoint
the engine overlay refuses falls back to the local projection, and that
projection now uses the configured camera FOV instead of a hardcoded 75
degrees (the wide-FOV ring no longer kinks/drops pieces).
|
| |
|
|
|
|
|
|
| |
CWallHealth derives CBaseToggle and CNewRecharge derives CBaseAnimating, so
m_iJuice is at different offsets (0x3c8 and 0x47c here). Collect every
m_iJuice datamap match, derive the suit offset from m_iMaxJuice-20, and pick
by the server class name. Also detect health brushes via wallhealth/recharge
rather than the ESP label. Verified the offsets resolve distinctly on :99.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- Projectiles gets a "Grenade trajectory" toggle. While a frag grenade is
held, simulate the weapon_frag throw (1200 u/s forward + 120 z, player
velocity, gravity 600) and trace each step with a new
trace_solid_segment(); reflect on impact, stop on a slow upward-normal hit,
and draw the path, landing cross and a 300-unit blast ring. Verified on :99
(arcs, bounces off the tunnel wall, lands).
- With the RPG equipped, armoured NPCs (striders, gunships, dropships,
hunter-choppers) sort before normal enemies during target acquisition.
Added helicopter/chopper to the ARMORED model list.
- Empty health/suit chargers are hidden: read m_iJuice from the server
datamap (0 = depleted, -1 = unreadable/fail open).
- The citadel supercharged gravity gun (d3_citadel_03, d3_citadel_04,
d3_breen_01 via IVEngineClient::GetLevelName) is treated as a normal
weapon, so the melee aimbot no longer restricts it to VULNERABLE NPCs.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Testing on :99 showed the material $alpha path is a dead end: UnlitGeneric
takes translucency from the base texture/vertex alpha, and the debug materials
have neither. Follow Amalgam: apply alpha with IVRenderView::SetBlend
(VEngineRenderView014 slot 4) around the model draw, saving/restoring it.
To have something translucent to blend, write a tiny UnlitGeneric VMT with
$model 1 + $translucent 1 + a white base texture to
<game>/<mod>/materials/hl2hake/translucent.vmt (plus a custom/ copy). It is
written by a preload constructor so it exists before the material system scans
its search paths, then loaded once with FindMaterial. Styles 0/3/4/6 use it
when the colour alpha is below 255.
Also:
- Visible wireframe + through-wall: fill the visible silhouette first so the
through-wall pass cannot show in the wireframe gaps, then draw a brightened
contour. Style 6 is now "Solid + contour" (recolour + visible edges).
- find_modules builds local snapshots and publishes them under a mutex; the
setup thread and the server retry could reset the shared vectors live and
crash at startup.
Verified on :99: Solid + alpha 64 renders a see-through viewmodel, Solid +
contour shows a blue fill with bright blue contours, Additive is a translucent
coloured glow and Fullbright is a white additive glow.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Testing on :99 showed ADDITIVE on debugtranslucentsinglecolor did nothing and
alpha lost the colour, because that VMT has no $translucent and the engine
bound an unreferenced material. Use debug/debugtranslucentmodelhulls (VMT has
$additive 1 + $color) for Additive/Fullbright, and addref every preloaded
material so the engine stops warning "bad reference count 0" and applies
$color/ColorModulate. Verified: Solid is flat blue, Additive is a translucent
coloured glow, Fullbright is a white additive glow, White is opaque white.
Also drop the viewmodel additive base (the solid material is opaque, so it
made an opaque blob) and never call FindMaterial inside DrawModelExecute.
Document that the alpha control is stored but has no effect until a custom
$translucent model VMT is added.
|
| |
|
|
|
|
|
|
| |
Fullbright was additive with the chosen colour lifted only 25% toward white,
which on a dark scene looked almost identical to Solid/Flat. Force white for
the Fullbright colour so the additive pass reads as a distinctly brighter,
white-hot glow; the faint translucent base still gives it a silhouette on
bright backgrounds.
|
| |
|
|
|
|
|
|
|
|
|
| |
- Colour picker gains an optional alpha bar (checkerboard preview, #RRGGBBAA
readout); add_color_alpha is used for the chams colours. Chams colours are
now r,g,b,a and chams_apply sets $alpha plus MATERIAL_VAR_TRANSLUCENT when
alpha < 255. Config stores vis_a / inv_a / vm a.
- The additive viewmodel base is now a faint translucent tint (alpha/8)
instead of an opaque fill, so additive/Fullbright stay see-through and the
viewmodel no longer becomes a solid blob. Fullbright whitening reduced to
25% so blue stays blue instead of turning lavender.
|
| |
|
|
|
|
|
|
| |
Viewmodels are collated as RENDER_GROUP_VIEW_MODEL_OPAQUE, so an additive
forced material can vanish against a bright sky/wall (additive adds nothing to
an already-bright surface). Draw a dim opaque solid base before the additive
viewmodel pass so the first-person model always has a visible silhouette; the
additive layer still provides the glow.
|
| |
|
|
|
|
|
| |
vgui/white is an UnlitGeneric with $vertexcolor/$vertexalpha, no basetexture
and no $model, so it renders nothing on model vertices; Flat was invisible on
the viewmodel and would be invisible on NPCs too. Flat now uses the solid
model shader with the FLAT flag. Remove the vgui/white probe.
|
| |
|
|
|
|
|
|
|
| |
- Flat uses the solid model shader with the FLAT flag on the viewmodel;
vgui/white does not draw skinned models and made the hands vanish.
- Glow outline draws its wireframe contour with ZNEARER and a brightened
colour, so the solid base no longer hides the contour.
- Fullbright is now additive + self-illuminated with the colour lifted toward
white, so it reads differently from Solid and Additive glow.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
- Hostile/neutral/friendly each have independent visible and through-wall
settings: enable, style and colour. Viewmodel has its own enable/style/colour.
- Styles: Flat, Wireframe, Additive, Solid, White, Fullbright, Glow outline.
Additive uses the model solid material + ADDITIVE flag (the VGUI additive
was invisible on NPCs). White/fullbright are solid-based, so the viewmodel
no longer disappears/checkerboards. Glow outline adds a wireframe contour
pass for depth.
- Config: [chams] active/bind, [chams_hostile|neutral|friendly] vis/inv
settings, [chams_vm]. GUI sections for each group.
|
| |
|
|
|
|
|
| |
The viewmodel was always solid. Use the selected style material for the
model-debug styles (wireframe/solid/white/fullbright); Flat and Additive use
the solid model shader with the same flags because their VGUI materials do not
draw skinned models.
|
| |
|
|
|
|
|
| |
models/debug/debugwhite is EP2-only and additivevertexcolorvertexalpha is not
loadable in the base game. Preload vgui/white for Flat and vgui/white_additive
for Additive; the other debug styles were already found. The viewmodel keeps
the solid model shader.
|
| |
|
|
|
|
|
|
|
| |
FindMaterial inside DrawModelExecute did not load the style VMTs, so every
style fell back to the solid material. Preload the six style materials from
outer_draw (throttled) and have the render hook use the cached pointers only.
world_find_material now returns only the exact requested material; the caller
falls back to the solid style. Add a vgui/white probe and per-style preload
logs.
|
| |
|
|
|
|
|
|
| |
The base game only has debug/debugtranslucentsinglecolor resident, so the
other debug VMTs silently fell back to it and every style looked flat. Use that
material for every style and apply material flags instead: FLAT, WIREFRAME,
ADDITIVE, and FLAT|SELFILLUM for fullbright; white forces the colour. Flags are
cleared after the draw.
|
| |
|
|
|
|
|
|
|
| |
VGUI/white materials do not draw skinned models, so every viewmodel style
except the model debug one made the hands/weapon disappear. Use model debug
materials for all styles: wireframe, additive vertex colour, translucent
single colour, translucent vertex colour, MRM fullbright. The viewmodel
always uses debug/debugtranslucentsinglecolor. A missing style now falls back
to that material instead of vgui/white.
|
| |
|
|
|
|
|
|
|
|
| |
- world_find_material now tries the exact requested style first (resident,
then FindMaterial) before falling back to debugwhite/vgui white. The old
candidate scan returned vgui/white for every style, so all materials looked
flat.
- Add a real CK_DROPDOWN control (overlay list, outside-click close, config
save) and use it for the Chams material selector.
- Chams viewmodel toggle included in config/UI.
|
| |
|
|
|
|
|
|
|
| |
- Material selector 0..4: debugwhite, debug wireframe (ignorez), vgui
white_additive, debugtranslucentsinglecolor, vgui/white; cached per index
with a debugwhite fallback.
- Add "Viewmodel (hands/weapon)" toggle; viewmodel entities (class contains
viewmodel or model path /v_...) get a normal-depth chams pass.
- [chams] gains viewmodel= and material=.
|
| |
|
|
|
|
| |
FindMaterial diagnostics are no longer logged per attempt; the chosen material
is logged once. Accept any candidate name returned by FindMaterial, not just
debugwhite.
|
| |
|
|
|
|
| |
ColorModulate alone left the forced material white. Also set the shader's
$color and $color2 vars (IMaterialVar SetVecValue 3-float) and restore them to
white after the draw. Log which fallback material was selected.
|
| |
|
|
|
|
|
| |
models/debug/debugwhite is not resident and FindMaterial did not return it.
Log each FindMaterial attempt and fall back to debugwhite2/3, vgui/white,
debug/debugtranslucentsinglecolor and the ignorez debug wireframe material so
chams can still render.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
- Hook IVModelRender::DrawModelExecute (VEngineModel016 slot 19) and force
models/debug/debugwhite for NPC models, identified by
ModelRenderInfo_t::entity_index.
- Two passes: MATERIAL_VAR_IGNOREZ through walls, then normal depth, with
IMaterial::ColorModulate for the configured colour; restore the shared
material's flag/colour afterwards.
- Material lookup via the IMaterialSystem list, FindMaterial fallback.
- New Chams feature/card with Through walls and colour; [chams] config.
- Remove the temporary ammo/projectile/fuse diagnostics.
|
| |
|
|
|
|
|
|
| |
The datamap offset points at the array length header, so every ammo count was
read one type early. That made the RPG slot read the buckshot count (30) and
permanently exceed the 3-rocket cap, which is why RPG pickups never showed and
grenades/AR2/weapon ammo never hid. Read the elements 4 bytes after the field
offset.
|
| |
|
|
|
|
|
|
|
| |
- Exempt chargers and ammo/supply crates from the fullness filter; reusable
dispensers stay visible at max ammo/health.
- Log the local ammo current/max table once and the first 24 ammo filter
decisions, so the RPG/grenade/weapon cases can be diagnosed.
- Classify the launched w_missile as an RPG projectile (class not item/
weapon) and exclude the w_missile_closed ammo pickup from projectile ESP.
|
| |
|
|
|
|
|
|
|
|
|
| |
The client m_iAmmo/m_hMyWeapons recv props still do not resolve, but the
listen server has the same CBaseCombatCharacter arrays in its datamap. Resolve
m_iAmmo and m_hMyWeapons there:
- reserve ammo comes from server_player_ammo() when the client array is
missing, so full-ammo filtering works (RPG rockets at 3);
- the owned-weapon mask is filled from the server m_hMyWeapons[48] handles,
so fallen weapons count as ammo before the player equips them.
Widen the datamap field-size filter to 512 for the 192-byte handle array.
|
| |
|
|
|
|
|
|
|
|
| |
- Match m_iAmmo/m_hMyWeapons by name prefix so element props such as
m_iAmmo[0] are accepted.
- Handle them before the nested-table recursion, since RecvPropArray3 may put
the element descriptor in m_pDataTable.
- Allow name strings outside client.so (engine/server too), and log the first
16 array props plus the first 8 unreadable prop names so the remaining
resolution failure is visible in the normal log.
|
| |
|
|
|
|
|
|
| |
m_iAmmo and m_hMyWeapons were not resolving (both -1). Array props keep their
element descriptor in m_pArrayProp and its offset can hold the array base; the
walker was also treating a non-null m_pDataTable on an array as a nested table
and skipping the name match. Process array props by name, use the element
offset when present, and log the first 16 array props under HL2H_DEBUG.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
- Resolve m_iAmmo and m_hMyWeapons arrays from the client recv tables.
- "Only if usable" now compares m_iAmmo[type] against sk_max_* (stock caps as
fallback: RPG rockets 3, AR2 60, ...). Full ammo hides the pickup, including
RPG rockets and fallen weapons converted to ammo.
- Inventory now comes from m_hMyWeapons directly, so fallen weapons are ammo
before the player equips the matching weapon.
- Projection: fall back to local math when ScreenPosition claims "behind" for
a point with positive view depth, and build NPC boxes from vertical samples
so feet behind the near plane no longer drop the whole target. Log the first
8 near-target projection failures for diagnosis.
|
| |
|
|
|
|
|
|
| |
Transition-box edges and projectile radius rings were only drawn when both
endpoints projected. An edge with one corner behind the camera vanished, so a
half-visible box or ring showed nothing. Add a segment projector that clips at
the near plane in view space, then clips the 2D result to the screen bounds,
and use it for both.
|
| |
|
|
|
|
|
|
|
|
|
| |
- world_to_screen now rejects NaN/inf and absurd projections. A point on the
view axis (directly below the feet) could produce NaN and corrupt the
ISurface clip state, hiding the whole ESP for that frame.
- Draw projectile radius rings even when the projectile centre is off-screen
or behind the camera.
- Owner netvars are -1 on this client, so the "owned weapon -> ammo" rule now
accumulates the weapon types the player has actually held (active weapon,
server fallback), reset when the local entity changes.
|
| |
|
|
|
|
|
|
|
| |
- World weapons of a type already in the local player's inventory are retagged
as ammo ("SMG ammo", ...). Inventory scan only counts weapons owned by the
local player index, so NPC weapons do not trigger it.
- Projectile fuse: log det/cur/base/raw server value, and fall back to a
3-second first-sighting countdown when m_flDetonateTime or engine time is
unavailable.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
- Items: "Only if usable" hides health tags at full health and armor at full
suit. Health ceiling is the server player's m_iMaxHealth; armor uses the
server m_ArmorValue against HL2's 100 cap. Fails open when unreadable.
- Projectiles: new Visuals feature/card for thrown grenades, RPG rockets,
helicopter bombs and AR2 balls. Fuse from server m_flDetonateTime vs engine
time; radius from m_DmgRadius with per-type fallback; optional 24-segment
radius ring and FRAG timer label.
- Melee: the killbot now handles the gravity gun as well; only VULNERABLE
targets, 1200-unit range, primary attack to launch the held object, and no
aim-punch compensation because the launch uses EyeVectors.
- Server/netvars: m_ArmorValue, m_flDetonateTime, m_DmgRadius.
|
| |
|
|
|
|
|
| |
Wayland/XWayland discards window gamma ramps, so mat_monitorgamma could not
work on the development setup. Drop the slider, config key and readback.
Keep the in-engine HDR tonemap brightness and document that Fullbright turns
tonemapping off.
|
| |
|
|
|
|
|
|
|
| |
The engine applies mat_monitorgamma (SDL receives changing ramp midpoints),
but Wayland/XWayland compositors discard the window gamma ramp, so the gamma
slider has no visible effect there. Add an in-engine brightness control that
does not depend on the window system: mat_force_tonemap_scale, exposed as
"HDR brightness" (x10, 0 = automatic). Drop the temporary SDL gamma ramp
diagnostic.
|
| |
|
|
|
|
|
| |
The engine clamps mat_monitorgamma at 2.6, so the 2.8..3.0 end of the slider
did nothing. Read the value back one tick later (ClientCmd is queued) and
interpose SDL_SetWindowGammaRamp to see whether the engine pushes a ramp at
all.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
- Each changelevel trigger now shows its own target map. The trigger whose
target is the map we came from is marked "<- map"; the forward one is
"-> map". No more appending one global previous-map line to every box.
- Draw the volume as a projected 8-corner / 12-edge wireframe with the tag
above its highest visible corner instead of a screen-space rectangle.
- Camera FOV is 40..140 (stock 75) and viewmodel FOV 20..120 (stock 54); 0 is
no longer allowed and old configs using 0 migrate to the stock value.
- Log the mat_monitorgamma readback via ICvar so we can tell whether the
command is rejected or the OS/compositor ignores the gamma ramp.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- ESP: alert state (IDLE/ALERT/COMBAT/SCRIPT), enemy weapon labels, hostile/
neutral/friendly colour pickers, off-screen direction arrows, and
trigger_changelevel volumes with next/previous map labels.
- Aim: silent aim reuses the Aimbot FOV, vischeck and bone settings; add
optional aim-punch compensation for aimbot, silent aim, triggerbot and
melee (server bullets add m_vecPunchAngle to the usercmd angles).
- View: always-on Camera / display card with camera FOV (writes the client
m_iDefaultFOV netvar), viewmodel FOV and monitor gamma (client cvars).
- Movement: Jump assist card with auto crouch-jump and edge jump (point
ground probe 0.12 s ahead).
- Spread: Engine spread override toggle gates the direct RandomFloat zeroing;
off leaves only the seed search.
- Server: entity count/base/classname helpers, trigger_changelevel map name
and world bounds via IServerUnknown/ICollideable.
- Netvars: m_vecPunchAngle and m_iDefaultFOV.
|