Commit graph

404 commits

Author SHA1 Message Date
Kelsi
98e3bbd58c feat(editor): add --gen-texture-honeycomb hexagonal-cell pattern
42nd procedural texture: hexagonal cell tiling produced by
Voronoi over a triangular seed lattice — alternating-row hex
seeds at horizontal step sqrt(3)*s and vertical step 1.5*s
naturally produce perfect hexagonal Voronoi cells without
needing the full pointy-top hex-tile math.

Border pixels are detected by ratio of second-nearest /
nearest seed distances (1.04x threshold) so border thickness
scales naturally with hex size and stays a couple of pixels
across the whole image. Useful for beehives, dragon scales,
sci-fi panels, magical wards, mosaic tile floors. Defaults
to 16-px hex side.
2026-05-09 08:49:51 -07:00
Kelsi
92ac80ebc2 refactor(editor): extract --add-tile / --remove-tile / --list-tiles into cli_tiles.cpp
Moves the three per-tile zone-manifest handlers (--add-tile,
--remove-tile, --list-tiles) out of main.cpp into a new
cli_tiles.{hpp,cpp} module. Zones can span multiple ADT tiles;
these manage that list — add creates a fresh blank WHM/WOT
pair at the new tile, remove drops the entry + deletes
WHM/WOT/WOC files, list prints the manifest with file-presence
flags.

main.cpp shrinks by 185 lines (4,616 to 4,431).
2026-05-09 08:47:32 -07:00
Kelsi
29c7ff6af6 feat(editor): add --gen-mesh-stool small-furniture primitive
49th procedural mesh: 5-box backless stool — flat square seat
on 4 short legs at the corners. Smaller-footprint counterpart
to --gen-mesh-bench, pairs with --gen-mesh-table for taverns,
workshops, NPC market stalls, dwarven taprooms.

Defaults to 0.36m square seat at 0.49m total height — typical
3-legged-bar-stool proportions. Customizable per dimension so
the same primitive covers child stools, milking stools, and
tall workshop stools.
2026-05-09 08:44:51 -07:00
Kelsi
dfe997c564 refactor(editor): extract zone-creation handlers into cli_zone_create.cpp
Moves the two zone-creation handlers (--scaffold-zone,
--mvp-zone) out of main.cpp into a new cli_zone_create.{hpp,cpp}
module. Both kickstart a new authoring session by generating a
new zone directory under custom_zones/ — empty for scaffold,
populated with one of each content type (creature + object +
quest with objective + reward) for mvp. Each goes terrain +
manifest, then mvp adds the demo content positioned at the
tile center.

main.cpp shrinks by 155 lines (4,771 to 4,616).
2026-05-09 08:42:49 -07:00
Kelsi
16f9c072c7 feat(editor): add --gen-texture-lattice diagonal-grid pattern
41st procedural texture: garden trellis / mesh fence done as
two perpendicular sets of diagonal lines (+45° and -45°)
drawn simultaneously across the whole image so they form
diamond-shaped openings between the lines.

Distinct from --gen-texture-herringbone (which alternates
strip orientation): lattice draws both diagonal sets at every
pixel. Useful for trellises, wire mesh fences, dragon-scale
chain mail, decorative window grilles. Defaults to 24-px line
spacing with 3-px line width.
2026-05-09 08:40:14 -07:00
Kelsi
6430a3f554 refactor(editor): extract items.json mutation handlers into cli_items_mutate.cpp
Moves the three items.json mutation handlers (--set-item,
--copy-zone-items, --clone-item) out of main.cpp into a new
cli_items_mutate.{hpp,cpp} module. All three operate on the
same {"items": [...]} schema; --set-item supports both
id-lookup ("123") and index-lookup ("#0") with strict
"only changed fields are written" semantics, --copy-zone-items
has replace and --merge modes, --clone-item auto-assigns the
smallest unused id.

main.cpp shrinks by 316 lines (5,087 to 4,771) and finally
drops below 5K. items.json now has its full mutation surface
in one focused module instead of scattered through the
megafile.
2026-05-09 08:33:59 -07:00
Kelsi
f29cf0f29c feat(editor): add --gen-mesh-crate shipping-crate primitive
48th procedural mesh: 5-box wooden shipping crate — main
cube body plus 4 reinforcement posts running along the
vertical edges. The posts extend slightly proud of the body
on each axis so they read as separate rails rather than
texture detail, and don't z-fight the body's faces from any
viewing angle.

Useful for dock yards, warehouse interiors, dungeon room
set dressing, NPC merchant shops. Defaults to a 0.80m cube
with 0.05m post half-thickness.
2026-05-09 08:28:53 -07:00
Kelsi
44c1c60db3 refactor(editor): extract item-export handlers into cli_items_export.cpp
Moves the three item-export handlers (--export-zone-items-md,
--export-project-items-md, --export-project-items-csv) out of
main.cpp into a new cli_items_export.{hpp,cpp} module. All
three render items.json data as human-readable Markdown / CSV
reports for design docs, PR descriptions, GitHub Pages, and
spreadsheet pivot-table workflows.

main.cpp shrinks by 262 lines (5,349 to 5,087).
2026-05-09 08:26:52 -07:00
Kelsi
84403027ae feat(editor): add --gen-texture-gingham 3-tone fabric pattern
40th procedural texture: classic gingham picnic-blanket /
shirt fabric — two perpendicular sets of stripes with a
darker color where they cross. The crossing creates the
characteristic 3-tone checker pattern that's distinct from
plain --gen-texture-checker (solid blocks).

Useful for picnic blankets, country tablecloths, NPC shirt
textures, fabric set dressing. Defaults to 16-px stripe
spacing with 8-px stripe width (50% coverage per axis).
2026-05-09 08:24:12 -07:00
Kelsi
05350becbc refactor(editor): extract random-* / gen-random-* into cli_random.cpp
Moves the four random-population handlers (--random-populate-zone,
--random-populate-items, --gen-random-zone, --gen-random-project)
out of main.cpp into a new cli_random.{hpp,cpp} module. All four
use the same seeded LCG so re-runs reproduce the same content;
the gen-random-* pair shells out to scaffold-zone +
random-populate-zone + random-populate-items so the simpler
single-purpose handlers stay the source of truth.

main.cpp shrinks by 439 lines (5,788 to 5,349). The inline word
lexicons (creature names, object paths, item prefixes/nouns) move
with random-populate-zone and -items into the new module.
2026-05-09 08:22:06 -07:00
Kelsi
a953142b50 feat(editor): add --gen-mesh-tombstone graveyard primitive
47th procedural mesh: 3-box vertical headstone — wide low
base plinth, tall thin main slab on top, and a slightly-
wider decorative crown that acts as a flat-cap stand-in for
the arched-top headstone shape (which would need rotated
faces). Pairs with --gen-mesh-grave (horizontal mound) and
--gen-mesh-coffin for graveyards, dungeon crypts, haunted-
zone set dressing.

Vertical layout: 15% base, 75% slab, 10% crown. Defaults to
0.60 wide x 1.10 tall x 0.18 deep with the base 1.45x wider
than the slab on each footprint axis.
2026-05-09 08:19:04 -07:00
Kelsi
7af7534dc6 refactor(editor): extract add-* append handlers into cli_add.cpp
Moves the three add-* coordinate-based append handlers
(--add-object, --add-creature, --add-item) out of main.cpp
into a new cli_add.{hpp,cpp} module. All three append a
single entry to a zone's JSON file with optional positional
args after the required ones. --add-item handles raw
nlohmann::json (no dedicated editor class) and auto-assigns
the smallest unused id when the user passes 0 / nothing.

main.cpp shrinks by 198 lines (5,986 to 5,788).
2026-05-09 08:16:52 -07:00
Kelsi
83a6992ae0 feat(editor): add --gen-texture-spider-web radial-ring pattern
39th procedural texture: classic geometric spider web — N
radial spokes plus M concentric polygonal rings centered on
the image. Spoke pixels are detected by angular distance to
the nearest spoke scaled by radius, so spokes stay constant
pixel width regardless of how far they reach.

Useful for haunted house decals, dungeon corner overlays,
witch-hut interiors, magical-trap ground markers. Defaults
to 8 spokes (every 45 deg) and 5 evenly-spaced rings.
2026-05-09 08:14:04 -07:00
Kelsi
614d48a49b refactor(editor): extract remove-* by-index handlers into cli_remove.cpp
Moves the four bounds-checked remove-by-index handlers
(--remove-creature, --remove-object, --remove-quest,
--remove-item) out of main.cpp into a new
cli_remove.{hpp,cpp} module. All four share the same
load-erase-save pattern with index validation and a "what
was removed" report for audit trails. The first three use
their respective editor classes (NpcSpawner, ObjectPlacer,
QuestEditor); --remove-item walks raw nlohmann::json since
items.json doesn't have a dedicated editor class yet.

main.cpp shrinks by 145 lines (6,131 to 5,986).
2026-05-09 08:11:50 -07:00
Kelsi
f1a2e6850b feat(editor): add --gen-mesh-mailbox wayside primitive
46th procedural mesh: 4-box mailbox — vertical post with a
horizontal box body on top and a small flag (pole + plate)
mounted on the right (+X) side near the front. Useful for
inns, post stations, manor gates, frontier outposts, courier
routes between zones.

Defaults to a 1.10m post + 0.45L x 0.20W x 0.20H body
(~1.44m total). The box body is intentionally slightly wider
than the post on each axis so the body visually caps the
post. Flag plate extends +X away from the body so it reads
as a raised flag from the road side.
2026-05-09 08:08:37 -07:00
Kelsi
3fdf75a03b refactor(editor): extract clone-* duplicate handlers into cli_clone.cpp
Moves the three clone-* handlers (--clone-quest,
--clone-creature, --clone-object) out of main.cpp into a new
cli_clone.{hpp,cpp} module. All three deep-copy by index,
optionally rename, and (for creature/object) offset the new
copy by 5 yards along X to prevent z-fighting with the
original. Each resets the per-entity unique id so downstream
systems that dedupe by id stay consistent.

main.cpp shrinks by 184 lines (6,315 to 6,131).
2026-05-09 08:06:20 -07:00
Kelsi
56cad647b0 feat(editor): add --gen-texture-bubbles overlapping-circle pattern
38th procedural texture: scattered bubbles done as randomly-
placed circles of varied radii, with bright rim outlines that
stay visible even where bubbles overlap (rim color wins on
any pixel that lies in any bubble's ring band).

Three colors: background, translucent-feeling fill for the
bubble interior, and a bright rim. Defaults to 50 bubbles
of radius 6-24 px with 2-px rims. Useful for water surfaces,
foam patches, soap suds, magical-effect overlays, slime
particle effects.
2026-05-09 08:03:54 -07:00
Kelsi
408d7a611a refactor(editor): extract quest-reward handlers into cli_quest_reward.cpp
Moves the two quest-reward mutation handlers
(--add-quest-reward-item, --set-quest-reward) out of main.cpp
into a new cli_quest_reward.{hpp,cpp} module. Both operate on
a quest's reward struct in zone.json: the first greedy-consumes
multiple item paths in one invocation, the second uses
order-independent flag/value pairs (--xp / --gold / --silver
/ --copper) with strict 'only changed fields are written'
semantics so partial updates don't clobber unrelated fields.

main.cpp shrinks by 114 lines (6,429 to 6,315).
2026-05-09 08:01:28 -07:00
Kelsi
af3c4f0bd6 feat(editor): add --gen-mesh-signpost wayfinding primitive
45th procedural mesh: 4-box signpost — stone base anchor,
tall vertical pole, thin sign board mounted face-out near
the top, and a small decorative cap. Useful for crossroads,
tavern fronts, town entrances, dungeon area markers, quest
hub indicators.

Sign board's long axis runs along Z so the player reads the
sign when facing parallel to the road. Defaults to a 2.5 m
post with a 0.8 x 0.35 m board (~2.7 m total).
2026-05-09 07:58:45 -07:00
Kelsi
db8d499e8e refactor(editor): extract quest+objective handlers into cli_quest_objective.cpp
Moves three contiguous quest mutation handlers (--add-quest,
--add-quest-objective, --remove-quest-objective) out of
main.cpp into a new cli_quest_objective.{hpp,cpp} module.
All three operate on a zone's quests.json with the same
QuestEditor load-edit-save flow; the objective add/remove
pair includes auto-generated description text from
type+name+count for tooltip-friendly defaults.

main.cpp shrinks by 174 lines (6,603 to 6,429). Reward and
clone-quest handlers stay inline for follow-up extractions.
2026-05-09 07:56:16 -07:00
Kelsi
4189051c09 feat(editor): add --gen-texture-parquet basket-weave wood floor
37th procedural texture: basket-weave parquet flooring done as
a checkerboard of 2N x 2N cells. Half the cells are split into
two horizontal planks (wood A); the other half are split into
two vertical planks (wood B). Adjacent perpendicular pairs
form the classic interlocked basket-weave.

A third "gap" color paints thin lines along plank edges and
the cell midline, giving the inset / wood-joint appearance.
Defaults to 32-px cells with 1-px gaps. Useful for parlour
floors, manor halls, magical libraries, dwarven flooring.
2026-05-09 07:52:29 -07:00
Kelsi
191a821ec8 refactor(editor): move --import-obj into cli_wom_io.cpp
Adds --import-obj as the 5th handler in cli_wom_io.{hpp,cpp},
joining its export-side sibling. The handler is the WOM-side
counterpart to --import-wob-obj (which lives in cli_world_io
because it produces WOB) — together they close the OBJ
round-trip story for both single meshes and multi-group
buildings.

main.cpp shrinks by 183 lines (6,786 to 6,603).
2026-05-09 07:50:02 -07:00
Kelsi
549bdaf191 feat(editor): add --gen-mesh-well village-prop primitive
44th procedural mesh: 7-box water well — 4 stone walls
arranged in a hollow square (interior visible, like a real
well shaft) + 2 vertical roof posts on opposite sides + 1
horizontal cross beam at the top where rope/bucket would
mount. Useful for village squares, courtyards, dungeon
water sources, druidic shrines.

Defaults to 1.4 m square footprint with 0.8 m walls and
1.6 m roof posts (~2.4 m total height). The east/west
walls are shortened so the corner joints line up cleanly
without overlap geometry.
2026-05-09 07:47:15 -07:00
Kelsi
5c350ee0af refactor(editor): extract WOB/WOT/WOC inspectors into cli_world_info.cpp
Moves the three open-format world-asset inspectors
(--info-wob, --info-wot, --info-woc) out of main.cpp into a
new cli_world_info.{hpp,cpp} module. Each prints a quick
structural summary (groups / portals / chunk counts /
triangles / bounds) without paying the full deserialization
cost a viewer would.

main.cpp shrinks by 144 lines (6,926 to 6,786). The
--copy-project handler that interleaved between --info-wob
and --info-wot stays inline -- it isn't an inspector and
belongs with project-mutation operations. All --json output
modes preserved.
2026-05-09 07:44:57 -07:00
Kelsi
a07df23755 feat(editor): add --gen-texture-frost crystal-rosette pattern
36th procedural texture: scattered ice nuclei with 6-spike
rosettes radiating at 60 deg intervals. Each spike's pixel
intensity falls linearly from full at the seed to zero at
the end of the ray, so spikes fade naturally into the
background. Per-seed angular jitter prevents all rosettes
from aligning to the same orientation.

Useful for winter zones, ice biomes, frosted-window decals,
magical cold-effect overlays. Defaults to 80 seeds with
18-px rays in 256x256.
2026-05-09 07:41:17 -07:00
Kelsi
0a1ba6f94b refactor(editor): extract --info-{zone,project}-audio into cli_info_audio.cpp
Moves the two audio-config audit handlers (--info-zone-audio,
--info-project-audio) out of main.cpp into a new
cli_info_audio.{hpp,cpp} module. Both surface the music /
day-ambience / night-ambience / volume settings stored in
zone.json so designers can spot zones still missing audio
assignment before a release pass.

main.cpp shrinks by 127 lines (7,053 to 6,926). Drops the
dead `label` lambda inside info-project-audio that the
unused-but-set-variable warning had been flagging. Both
--json output modes preserved.
2026-05-09 07:38:36 -07:00
Kelsi
55a768f1f3 feat(editor): add --gen-mesh-ladder utility primitive
43rd procedural mesh: 2 vertical rails + N evenly-spaced
horizontal rungs. Sits flat against +Z (the climbing face)
so it can be parented to walls, wagons, ship hulls, mage
tower trapdoors, attic openings, dungeon shafts.

Defaults to 3.0m tall × 0.6m wide with 8 rungs (typical
home/loft ladder). Rung spacing computes as height/(rungs+1)
so the first rung sits a half-step from the floor and the
last rung the same distance from the top — keeps the ladder
visually symmetric regardless of rung count.
2026-05-09 07:36:02 -07:00
Kelsi
30fbd39272 refactor(editor): extract --info-{zone,project}-density into cli_info_density.cpp
Moves the two content-density audit handlers
(--info-zone-density, --info-project-density) out of main.cpp
into a new cli_info_density.{hpp,cpp} module. Both count
creatures/objects/quests per tile to surface sparse zones
(boring) and over-stuffed ones (frame-rate bombs); the project
variant rolls per-zone numbers into a project-wide table with
per-zone averages for content-pacing reviews.

main.cpp shrinks by 201 lines (7,254 to 7,053). Both --json
output modes preserved for balance-audit pipelines.
2026-05-09 07:33:40 -07:00
Kelsi
4ec0c1aea2 feat(editor): add --gen-texture-shingles roof-tile pattern
35th procedural texture: roof shingles done as half-row-staggered
rows of rectangular tiles. Three colors: shingle base, a shadow
band at the top of each row (where the row above overlaps), and
thin vertical seams between adjacent shingles in the same row.

The half-row stagger comes from the standard roofing convention
of offsetting alternate courses by half a tile width — gives the
classic interlocked look that pure brick patterns lack.

Useful for roofs, scale armor close-ups, fish bellies, anywhere
needing tightly-packed offset rectangles. Defaults to 32x24
shingles with 4-px shadow + 1-px seams.
2026-05-09 07:30:50 -07:00
Kelsi
a25961e2dd refactor(editor): extract --info-{zone,project}-water into cli_info_water.cpp
Moves the two water-layer audit handlers (--info-zone-water,
--info-project-water) out of main.cpp into a new
cli_info_water.{hpp,cpp} module. Both aggregate liquid data
(water/ocean/magma/slime) across MH2O chunks; the project
variant rolls per-zone counts into a project-wide total with
height range and per-type histogram.

main.cpp shrinks by 209 lines (7,463 to 7,254). Both --json
output modes preserved for capacity-planning pipelines.
2026-05-09 07:28:15 -07:00
Kelsi
8d71618c28 feat(editor): add --gen-mesh-bed bedroom-prop primitive
42nd procedural mesh: 8-box bed — 4 corner legs, mattress
slab, tall headboard at the +Z end, shorter footboard at the
-Z end, and a small pillow on the mattress near the headboard.
Pairs with --gen-mesh-table / --gen-mesh-bookshelf for inn
rooms, manor bedrooms, barracks, dungeon cells.

Defaults to 2.0 × 1.2 (length × width) with 0.30 leg height
and 0.20 mattress thickness — proportions of a single bed.
Customizable per dimension so the same primitive covers
single, double, and king-size beds plus child cots.
2026-05-09 07:25:11 -07:00
Kelsi
c005396040 refactor(editor): extract --info-{zone,project}-extents into cli_info_extents.cpp
Moves the two spatial-bounds info handlers (--info-zone-extents,
--info-project-extents) out of main.cpp into a new
cli_info_extents.{hpp,cpp} module. Both compute world-space XYZ
bounding boxes from manifest tile coords + per-chunk height
samples; the project variant unions every zone's box into one.

main.cpp shrinks by 232 lines (7,695 to 7,463). Both --json
output modes preserved for camera-framing pipelines.
2026-05-09 07:22:06 -07:00
Kelsi
c572c16114 feat(editor): add --gen-texture-stained-glass voronoi pattern
34th procedural texture: cathedral / magical-window stained
glass done as a Voronoi-cell tessellation. Each pixel snaps to
its nearest seed point; pixels near a cell boundary (small
relative gap to the second-nearest seed) become the lead color
producing the leaded-glass dividers between colored regions.

Three stained colors cycle across cells (cellIdx % 3) for a
balanced palette without per-cell color authoring. Defaults to
32 cells in 256x256, using ratio-based boundary detection so
lead-line thickness scales naturally with cell density.

Useful for cathedral windows, mage tower decals, magical
portals, ritual circle backdrops.
2026-05-09 07:19:02 -07:00
Kelsi
3009f406f8 refactor(editor): extract --info-{zone,project}-bytes into cli_info_bytes.cpp
Moves the two disk-byte audit handlers (--info-zone-bytes,
--info-project-bytes) out of main.cpp into a new
cli_info_bytes.{hpp,cpp} module. Both categorize files by
extension into open / proprietary / derived buckets — the
project-wide variant is the headline metric for tracking
the open-format migration's progress against the .m2/.wmo/
.blp/.dbc baseline.

main.cpp shrinks by 244 lines (7,939 to 7,695). Both --json
output modes preserved for machine-readable reports.
2026-05-09 07:16:27 -07:00
Kelsi
6c9edc8130 feat(editor): add --gen-mesh-lamppost urban-prop primitive
41st procedural mesh: 4-box urban lighting fixture — square
base plinth, tall thin vertical pole, lantern body box around
the pole top (overlaps so the lamp visually caps the pole),
and a slightly-wider cap plate that reads as an awning.

Useful for streets, plazas, courtyards, taverns — anywhere
that wants explicit lighting fixtures without modeling each
one by hand. Defaults to 3-meter pole + 0.5-meter lantern
(~3.6m total). Customizable per dimension to cover everything
from candlestick-stands to tall ornate streetlamps.
2026-05-09 07:12:46 -07:00
Kelsi
7950648943 refactor(editor): extract --info-{zone,project}-tree into cli_info_tree.cpp
Moves the two tree-style content browser handlers
(--info-zone-tree, --info-project-tree) out of main.cpp into
a new cli_info_tree.{hpp,cpp} module. Both render
Unix-`tree`-style hierarchical views — one drilling into a
single zone (manifest, tiles, creatures, objects, quests,
files) and one giving a bird's-eye view of every zone in a
project with bake/viewer status.

main.cpp shrinks by 201 lines (8,140 to 7,939). The remaining
info-zone/-project-* pairs (bytes, extents, water, density,
audio) form the next natural extraction batch.
2026-05-09 07:10:12 -07:00
Kelsi
b783a62289 feat(editor): add --gen-texture-scales overlapping-circle pattern
33rd procedural texture: fish / dragon / chain mail scales done
as a half-row-staggered grid of circles whose centers sit at the
bottom-center of each cell. Adjacent rows offset by half a cell
width, with circle radius slightly larger than half the cell, so
the circles interlock into the classic overlapping-scale look.

Three colors: background fills the gaps, scale body fills most of
each circle, and a rim color highlights the top arc to give the
raised / armored feel.

Defaults to 24×16 cells; scaled by cellW × cellH for fine control
of scale density. Useful for chain mail, dragonhide, fish skin,
roof shingles, anywhere needing tiled curved scales.
2026-05-09 07:06:29 -07:00
Kelsi
e128d91d66 refactor(editor): extract WOB/WHM/WOC IO into cli_world_io.cpp
Moves all six world-asset interchange handlers (--export-wob-glb,
--export-wob-obj, --import-wob-obj, --export-whm-glb,
--export-whm-obj, --export-woc-obj) out of main.cpp into a new
cli_world_io.{hpp,cpp} module. WOB / WHM / WOC are our open
replacements for proprietary WMO / ADT-heightmap / ADT-collision
data; these are the bridge that lets the open formats round-trip
through Blender, MeshLab, Three.js, and the rest of the standard
3D toolchain.

main.cpp shrinks by 858 lines (8,997 to 8,140). The single-mesh
--import-obj handler stays inline for now -- it shadow-mirrors
cli_wom_io's --import-stl semantics and will move there next.
2026-05-09 07:03:14 -07:00
Kelsi
61bc9dfb15 feat(editor): add --gen-mesh-table furniture primitive
40th procedural mesh: simple 5-box table — flat top slab on
4 vertical corner legs. Pairs with --gen-mesh-bench /
--gen-mesh-throne / --gen-mesh-bookshelf for taverns,
dining halls, libraries, and study set dressing.

Defaults to 1.6 × 1.0 base × 0.85 tall, 0.10-square legs,
0.06-thick top — sensible dining-table proportions.
Customizable per dimension so a single primitive covers
desks, end tables, and big banquet tables.
2026-05-09 06:58:38 -07:00
Kelsi
b59c310742 refactor(editor): extract WOM <-> OBJ/GLB/STL into cli_wom_io.cpp
Moves the four WOM interchange-format handlers (--export-obj,
--export-glb, --export-stl, --import-stl) out of main.cpp into
a new cli_wom_io.{hpp,cpp} module. WOM is our open M2
replacement; these are the bridge that lets it round-trip
through every external 3D tool — Blender, Three.js, slicers,
CAD packages — so the open format is actually useful.

main.cpp shrinks by 467 lines (9,464 to 8,997). The five WOB
and WHM exporters (--export-wob-glb, --export-whm-glb, etc.)
remain inline for a follow-up extraction.
2026-05-09 06:55:00 -07:00
Kelsi
c1f3d5aba4 feat(editor): add --gen-texture-herringbone chevron pattern
32nd procedural texture: classic V-shaped herringbone done as
horizontal strips of parallel slanted lines whose slant
direction flips every strip. Implementation is a per-pixel
shear: shifting x by the row's local-y collapses each diagonal
into a vertical band in shifted-x space, so a single modulo
picks line vs background.

Useful for parquet floors, brick patios, fabric weaves, fish
scale-style chain mail, anywhere needing a strong directional
pattern. Two-color, defaults to 32-px strips with 12-px line
spacing and 4-px line width.
2026-05-09 06:49:29 -07:00
Kelsi
9362623297 refactor(editor): extract GLB inspectors into cli_glb_inspect.cpp
Moves all 4 GLB introspection handlers (--validate-glb /
--info-glb shared, --info-glb-tree, --info-glb-bytes,
--check-glb-bounds) out of main.cpp into a new
cli_glb_inspect.{hpp,cpp} module. GLB is our open replacement
for proprietary M2/WMO bake outputs, so these belong with the
other open-format tooling.

main.cpp shrinks by 657 lines (10,121 to 9,464). Every
handler preserves its --json output mode for machine-readable
reports.
2026-05-09 06:46:02 -07:00
Kelsi
ecb97428aa feat(editor): add --gen-mesh-bookshelf cabinet primitive
39th procedural mesh: 5-panel cabinet (back / left / right /
top / bottom) divided into N bays by N-1 horizontal shelves,
with rows of pseudo-random book boxes on each level. Book
widths and heights vary per bay (seeded by bay index so
re-generating the same shelf gives the same layout) so the
result reads as a stocked library instead of a perfect grid.

Defaults to 1.5x2.0x0.4 with 4 shelves (~72 books). Useful
for studies, libraries, mage towers, anywhere that needs
filled-out furniture set dressing.
2026-05-09 06:39:39 -07:00
Kelsi
06a4fdb60f refactor(editor): extract interop --validate-* into cli_validate_interop.cpp
Moves the four structural validators for INTEROP file formats
(--validate-stl, --validate-png, --validate-blp, --validate-jsondbc)
out of main.cpp into a new cli_validate_interop.{hpp,cpp} module.
These check files coming in/out of wowee from third-party tools,
distinct from cli_format_validate.cpp which validates the native
open formats (WOM, WOB, WOC, WHM).

main.cpp shrinks by 524 lines (10,644 to 10,121). Each validator
preserves its --json output mode for machine-readable reports.
2026-05-09 06:36:02 -07:00
Kelsi
8cd6f46aa3 feat(editor): add --gen-texture-argyle sweater-knit pattern
31st procedural texture: classic argyle pattern done by working
in a 45-rotated coord system (u, v) = (x+y, x-y) so lozenges
become axis-aligned squares for the checkerboard step. Diagonal
stitch lines fall out of u%cell and v%cell crossing zero.

Three-color: A/B for the alternating diamond fill, third color
for the diagonal stitch overlay. Defaults to 64-pixel cells with
2-pixel stitches. Useful for sweater fabric, seat cushions,
heraldic banner overlays.
2026-05-09 06:29:16 -07:00
Kelsi
0d2312ec8d refactor(editor): extract single-file --convert-* into cli_convert_single.cpp
Moves the five single-file format converters (--convert-m2,
--convert-wmo, --convert-dbc-json, --convert-json-dbc,
--convert-blp-png) out of two dedicated post-loop blocks in
main.cpp into a new cli_convert_single.{hpp,cpp} module. The
batch wrappers in cli_convert.cpp keep working — they shell
out to wowee_editor with these flags.

main.cpp shrinks by ~335 lines (10,979 → 10,644). The two
trailing for-loops were dead code after wiring the dispatcher
into the main loop, so they're gone too.
2026-05-09 06:25:04 -07:00
Kelsi
2658e8297a feat(editor): add --gen-mesh-coffin hexagonal-prism primitive
38th procedural mesh: classic 6-sided coffin with the
narrow-head / wide-shoulder / tapered-foot top-down profile
that's instantly recognizable from any angle. Built as 6 side
quads + top lid fan + bottom panel fan, all with face-shared
normals so it shades cleanly under any lighting.

Pairs with --gen-mesh-grave for graveyard set dressing.
Defaults to 2.0×0.8×0.6 (length × shoulder-width × height).
2026-05-09 06:18:42 -07:00
Kelsi
f0bbc228ef refactor(editor): extract --migrate-* handlers into cli_migrate.cpp
Moves the four schema-migration handlers (--migrate-wom,
--migrate-zone, --migrate-project, --migrate-jsondbc) out of
main.cpp into a new cli_migrate.{hpp,cpp} module. Same
behavior — they're idempotent in-place upgraders for older
WOM revisions and JSON DBC sidecar schemas. main.cpp shrinks
by 282 lines (11,261 → 10,979).
2026-05-09 06:13:41 -07:00
Kelsi
8fd6df6113 feat(editor): add --gen-texture-tartan plaid pattern
3-color crossing-band pattern: 6-band repeat sequence (A A B
C C B) per axis, with the pixel color at any position being
the average of the horizontal-band and vertical-band colors.
That averaging at intersections produces the characteristic
diamond grid of Scottish tartans without explicit "weave"
math — the band overlap pattern just falls out.

Defaults: bandPx=32 (repeat=192px). Useful for clan banners,
kilts, blanket textures, fabric set dressing. Brings the
procedural texture pattern set to 33.
2026-05-09 06:02:13 -07:00
Kelsi
d03c2dad1f refactor(editor): extract zone/project mesh-bake handlers into cli_bake.cpp
Moves the 3D-export bake handlers out of main.cpp:
  --bake-zone-glb     --bake-zone-stl     --bake-zone-obj
  --bake-project-obj  --bake-project-stl  --bake-project-glb

The STL + GLB project bakes share a combined dispatcher (one
function with internal STL-vs-GLB branching) since they walk
the same per-zone asset list and only differ in the output
emission code.

main.cpp drops 12,119 → 11,261 lines (-858). The combined-OR
opener spanning multiple lines created a parse-error fragment
in the extraction; caught + manually fixed before commit
(same pattern as the WOM info attachments/particles/sequences
extraction).
2026-05-09 05:57:25 -07:00