mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-11 11:33:52 +00:00
Open replacement for AzerothCore's creature_movement / waypoints SQL tables plus the per-spawn waypoint arrays. Defines named waypoint paths that creatures patrol along: Stormwind guards walking the city perimeter, AQ40 trash rotating through the chamber, ICC patrols circling the spire. Each entry binds a creatureGuid to a sequence of (x, y, z, delayMs) waypoints. The pathKind controls cycling behavior (Loop / OneShot / Reverse / Random) and moveType controls the locomotion kind (Walk / Run / Fly / Swim) — a flying patrol ignores ground geometry, a swimming patrol stays underwater. This is the first open format with truly variable-length per-entry payload. Earlier formats with multi-slot fields (WSPR's 8-reagent slots, WPSP's 4-item arrays) used fixed-size caps padded with zeros. WCMR instead uses an inline length-prefixed waypoint array — entries can be 4 waypoints or 4000, with the loader advancing through the file by reading the count first then count*16 bytes of waypoint data. Cap of 64K waypoints per path keeps a corrupted file from allocating gigabytes. pathLengthYards(pathId) is the engine helper that sums segment distances between consecutive waypoints (closing the loop for Loop kind). Tested across 12-point and 16-point circular paths that geometrically resolve to the expected ~25y radius and ~60y radius totals. Cross-references back to WCRT — creatureGuid points at the spawned creature instance whose behavior mode follows this patrol. Three preset emitters: --gen-cmr (3 small paths showing each pathKind variant), --gen-cmr-city (4 capital-city guard 6-point loops with 2.0-2.5s waypoint dwell), --gen-cmr-boss (3 long raid-zone patrols up to 16 waypoints, demonstrating that variable-length payloads scale). Validation enforces id+name+creatureGuid+waypoints presence, pathKind 0..3, moveType 0..3, no duplicate ids; warns on 1-waypoint paths (creature would idle in place) and Loop with fewer than 3 waypoints (degenerate — indistinguishable from Reverse). This is the 90th open format milestone. Wired through the cross-format table; WCMR appears in all 18 cross-format utilities. Format count 89 -> 90; CLI flag count 1048 -> 1053.
128 lines
4.4 KiB
C++
128 lines
4.4 KiB
C++
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace wowee {
|
|
namespace pipeline {
|
|
|
|
// Wowee Open Creature Patrol Path catalog (.wcmr) —
|
|
// novel replacement for AzerothCore's creature_movement /
|
|
// waypoints SQL tables plus the per-spawn waypoint
|
|
// arrays. Defines named waypoint paths that creatures
|
|
// patrol along: Stormwind guards walking the city perimeter,
|
|
// AQ40 trash rotating through the chamber, ICC patrols
|
|
// circling the spire.
|
|
//
|
|
// Each entry binds a creatureGuid (server-side spawn id)
|
|
// to a sequence of (x, y, z, delayMs) waypoints. The
|
|
// pathKind controls cycling behavior (Loop / OneShot /
|
|
// Reverse / Random) and moveType controls the locomotion
|
|
// kind (Walk / Run / Fly / Swim) — a flying patrol
|
|
// ignores ground geometry, a swimming patrol stays
|
|
// underwater.
|
|
//
|
|
// Variable-length entries: each path stores its own
|
|
// waypointCount with a corresponding inline waypoint
|
|
// array (no fixed cap). Loaders advance through the file
|
|
// by reading the count first, then count*16 bytes of
|
|
// waypoint data.
|
|
//
|
|
// Cross-references with previously-added formats:
|
|
// WCRT: creatureGuid references the spawned creature
|
|
// instance whose AI follows this patrol.
|
|
//
|
|
// Binary layout (little-endian):
|
|
// magic[4] = "WCMR"
|
|
// version (uint32) = current 1
|
|
// nameLen + name (catalog label)
|
|
// entryCount (uint32)
|
|
// entries (each):
|
|
// pathId (uint32)
|
|
// nameLen + name
|
|
// descLen + description
|
|
// creatureGuid (uint32)
|
|
// pathKind (uint8) / moveType (uint8) / pad[2]
|
|
// waypointCount (uint32)
|
|
// waypoints[count] (each 16 bytes):
|
|
// x (float) / y (float) / z (float) / delayMs (uint32)
|
|
// iconColorRGBA (uint32)
|
|
struct WoweeCreaturePatrol {
|
|
enum PathKind : uint8_t {
|
|
Loop = 0, // patrol forever in a circle
|
|
OneShot = 1, // walk once, then idle at last waypoint
|
|
Reverse = 2, // walk to end, walk back, repeat
|
|
Random = 3, // pick next waypoint randomly each step
|
|
};
|
|
|
|
enum MoveType : uint8_t {
|
|
Walk = 0, // ground walking speed
|
|
Run = 1, // ground run speed
|
|
Fly = 2, // airborne movement (ignores terrain)
|
|
Swim = 3, // underwater movement
|
|
};
|
|
|
|
struct Waypoint {
|
|
float x = 0.0f;
|
|
float y = 0.0f;
|
|
float z = 0.0f;
|
|
uint32_t delayMs = 0; // dwell time at this waypoint
|
|
};
|
|
|
|
struct Entry {
|
|
uint32_t pathId = 0;
|
|
std::string name;
|
|
std::string description;
|
|
uint32_t creatureGuid = 0;
|
|
uint8_t pathKind = Loop;
|
|
uint8_t moveType = Walk;
|
|
uint8_t pad0 = 0;
|
|
uint8_t pad1 = 0;
|
|
std::vector<Waypoint> waypoints;
|
|
uint32_t iconColorRGBA = 0xFFFFFFFFu;
|
|
};
|
|
|
|
std::string name;
|
|
std::vector<Entry> entries;
|
|
|
|
bool isValid() const { return !entries.empty(); }
|
|
|
|
const Entry* findById(uint32_t pathId) const;
|
|
const Entry* findByCreatureGuid(uint32_t creatureGuid) const;
|
|
|
|
// Compute total path length in yards by summing
|
|
// segment distances between consecutive waypoints.
|
|
// For Loop kind, includes the closing segment back to
|
|
// the first waypoint.
|
|
float pathLengthYards(uint32_t pathId) const;
|
|
|
|
static const char* pathKindName(uint8_t k);
|
|
static const char* moveTypeName(uint8_t m);
|
|
};
|
|
|
|
class WoweeCreaturePatrolLoader {
|
|
public:
|
|
static bool save(const WoweeCreaturePatrol& cat,
|
|
const std::string& basePath);
|
|
static WoweeCreaturePatrol load(const std::string& basePath);
|
|
static bool exists(const std::string& basePath);
|
|
|
|
// Preset emitters used by --gen-cmr* variants.
|
|
//
|
|
// makePatrol — 3 small patrols showing each pathKind
|
|
// (4-pt Loop guard, 6-pt OneShot run,
|
|
// 8-pt Random tiger).
|
|
// makeCity — 4 capital-city guard routes (Stormwind /
|
|
// Orgrimmar / Ironforge / Thunder Bluff)
|
|
// with 6-8 waypoints each.
|
|
// makeBoss — 3 raid-zone patrols (AQ40 12-pt Loop /
|
|
// Naxx 8-pt OneShot / ICC 16-pt Random)
|
|
// demonstrating long-path support.
|
|
static WoweeCreaturePatrol makePatrol(const std::string& catalogName);
|
|
static WoweeCreaturePatrol makeCity(const std::string& catalogName);
|
|
static WoweeCreaturePatrol makeBoss(const std::string& catalogName);
|
|
};
|
|
|
|
} // namespace pipeline
|
|
} // namespace wowee
|