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:
Gabe
2026-10-02 15:20:27 -05:00
commit 238cd9c6c3
3409 changed files with 100493 additions and 0 deletions

61
client/Common.h Normal file
View File

@@ -0,0 +1,61 @@
#pragma once
// Small client-wide helpers: asset paths, UI textures, color conversion.
#include "hd2d/GL.h"
#include "hd2d/Texture.h"
#include <imgui.h>
#include <glm/glm.hpp>
#include <cstdint>
#include <string>
#ifndef BS_ASSET_DIR
#define BS_ASSET_DIR "assets"
#endif
#ifndef HD2D_ENGINE_ASSET_DIR
#define HD2D_ENGINE_ASSET_DIR "../Vibe-HD-2D/assets"
#endif
namespace bs {
inline std::string gameAsset(const std::string& rel) { return std::string(BS_ASSET_DIR) + "/" + rel; }
inline std::string engineAsset(const std::string& rel) { return std::string(HD2D_ENGINE_ASSET_DIR) + "/" + rel; }
constexpr float kPixelsPerUnit = 32.0f; // world texel density shared by all pixel art
constexpr float kCreaturePixelsPerUnit = 40.0f; // creatures render a bit smaller than trainers
inline ImU32 imColor(uint32_t rgb, int alpha = 255) {
return IM_COL32((rgb >> 16) & 255, (rgb >> 8) & 255, rgb & 255, alpha);
}
inline glm::vec3 linearColor(uint32_t rgb) {
auto f = [](uint32_t c) { float v = float(c & 255) / 255.0f; return v * v * (0.8f + 0.2f * v); };
return {f(rgb >> 16), f(rgb >> 8), f(rgb)};
}
// Plain RGBA8 (not sRGB), nearest-filtered texture for ImGui images: pixel art
// previews and icons stay crisp and show their authored colors.
class UiTexture {
public:
UiTexture() = default;
UiTexture(const UiTexture&) = delete;
UiTexture& operator=(const UiTexture&) = delete;
~UiTexture() { reset(); }
// `img` uses the engine convention (row 0 = bottom); ImGui uv (0,0) is the top-left.
void upload(const hd2d::Image& img);
void reset();
ImTextureID id() const { return ImTextureID(intptr_t(id_)); }
bool valid() const { return id_ != 0; }
glm::ivec2 size() const { return size_; }
// ImGui uv rect of a grid cell (top-left origin, rows counted from the top).
void cellUV(glm::ivec2 cell, int col, int row, ImVec2& uv0, ImVec2& uv1) const;
private:
GLuint id_ = 0;
glm::ivec2 size_{0};
};
float wrapAngle(float a); // to (-pi, pi]
} // namespace bs