Brandling Safari: LAN safari-zone creature catching on the HD-2D engine
- Authoritative 30 Hz server (ENet, SQLite): accounts, characters, wild AI, tall grass / water / wandering spawns, fishing, captures, follower chains, clock + weather, LAN beacon - Client: title / join / character creator / play screens, prediction + reconciliation, interpolated players and parties, HD-2D UI (dialogue with Professor Henry, HUD, collection) - Shared deterministic zone generator, movement, protocol, roster, appearance - Paper-doll character art pipeline (PixelLab base walk + per-item animation edits) - Brandling roster from the company list (logo colors, jev types), Blender safari props - Headless test bot
This commit is contained in:
67
shared/Appearance.h
Normal file
67
shared/Appearance.h
Normal file
@@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
// Player look: base body, skin tone, one item per slot and a color per slot.
|
||||
// The layer art and the list of valid items come from
|
||||
// assets/characters/manifest.json (written by tools/character_art.py).
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace bs {
|
||||
|
||||
enum Slot : int { Shoes = 0, Bottom, Top, Hair, Hat, kSlotCount };
|
||||
const char* slotName(int slot); // manifest slot keys: shoes bottom top hair hat
|
||||
int slotFromName(const std::string& s); // -1 if unknown
|
||||
|
||||
struct Appearance {
|
||||
std::string body = "male";
|
||||
uint8_t skin = 0; // index into manifest skinTones
|
||||
std::array<std::string, kSlotCount> items; // "" = nothing in that slot
|
||||
std::array<uint32_t, kSlotCount> colors{}; // 0xRRGGBB per slot
|
||||
};
|
||||
|
||||
struct ItemDef {
|
||||
std::string id, label;
|
||||
int slot = 0;
|
||||
uint32_t color = 0; // default color
|
||||
bool fromBody = false; // carved out of the base body (tee, shorts)
|
||||
};
|
||||
|
||||
struct BodyDef {
|
||||
std::string id, label;
|
||||
int anchorRow = 63; // lowest opaque row of a 64 px frame
|
||||
std::vector<std::string> items;
|
||||
};
|
||||
|
||||
struct NpcArt {
|
||||
std::string sheet, portrait;
|
||||
int anchorRow = 63;
|
||||
};
|
||||
|
||||
// assets/characters/manifest.json
|
||||
struct CharacterManifest {
|
||||
int cell = 64, framesPerDirection = 5, walkFrames = 4, shades = 4;
|
||||
std::vector<std::string> directions; // sheet rows: south, east, north (west = east mirrored)
|
||||
std::array<int, kSlotCount> slotZ{};
|
||||
std::vector<uint32_t> skinTones;
|
||||
std::vector<uint32_t> palette;
|
||||
std::map<std::string, BodyDef> bodies;
|
||||
std::map<std::string, ItemDef> items;
|
||||
std::map<std::string, NpcArt> npcs;
|
||||
|
||||
bool load(const std::string& path, std::string* error = nullptr);
|
||||
const ItemDef* item(const std::string& id) const;
|
||||
bool bodyHas(const std::string& body, const std::string& item) const;
|
||||
|
||||
Appearance defaultLook(const std::string& body = "male") const;
|
||||
// Fixes anything invalid (unknown body/item, wrong slot, missing top/bottom, skin out of
|
||||
// range). Returns false if something had to be changed.
|
||||
bool sanitize(Appearance& a) const;
|
||||
};
|
||||
|
||||
uint32_t parseHexColor(const std::string& s, uint32_t fallback = 0xffffff);
|
||||
std::string hexColor(uint32_t rgb);
|
||||
|
||||
} // namespace bs
|
||||
Reference in New Issue
Block a user