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:
139
client/App.h
Normal file
139
client/App.h
Normal file
@@ -0,0 +1,139 @@
|
||||
#pragma once
|
||||
// Client application: window, renderer, screens (title, join, character
|
||||
// creator, play) and the glue between NetClient, World and the HD-2D UI.
|
||||
|
||||
#include "Common.h"
|
||||
#include "NetClient.h"
|
||||
#include "World.h"
|
||||
|
||||
#include "hd2d/Camera.h"
|
||||
#include "hd2d/DebugUI.h"
|
||||
#include "hd2d/Renderer.h"
|
||||
#include "hd2d/Screenshot.h"
|
||||
#include "hd2d/UI.h"
|
||||
#include "hd2d/Window.h"
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace bs {
|
||||
|
||||
struct Options {
|
||||
std::string screenshot; // capture to this PNG, then exit (hidden window)
|
||||
int frames = 120; // frames before the capture
|
||||
int width = 1600, height = 900;
|
||||
bool show = false; // visible window even when capturing
|
||||
std::string connect; // host[:port] to join right away
|
||||
bool host = false; // start a local server and join it
|
||||
uint16_t port = kDefaultPort;
|
||||
bool autoCreate = false; // skip the creator with a default look
|
||||
bool autoDialogue = false; // captures: advance dialogue automatically
|
||||
std::string screen; // "title" | "creator" capture start screen
|
||||
std::string profile; // identity file suffix (several clients on one machine)
|
||||
std::string name; // character name for --auto-create
|
||||
glm::vec2 move{0.0f}; // held movement for captures
|
||||
bool run = false;
|
||||
float yaw = 0.0f, dist = 0.0f;
|
||||
bool hasYaw = false;
|
||||
float hour = -1.0f; // title backdrop hour
|
||||
std::string weather; // title backdrop weather
|
||||
std::vector<std::string> keys; // scripted key presses: "<frame>:<key>" (space, e, f, tab)
|
||||
std::string look; // --look body,skin,hair,hat,top,bottom,shoes (creator capture)
|
||||
};
|
||||
|
||||
class App {
|
||||
public:
|
||||
explicit App(Options opt) : opt_(std::move(opt)) {}
|
||||
int run();
|
||||
|
||||
private:
|
||||
enum class Screen { Title, Join, Connecting, Creator, Play };
|
||||
struct DialogueScript {
|
||||
std::vector<std::pair<std::string, std::string>> lines; // speaker, text
|
||||
};
|
||||
|
||||
bool init();
|
||||
void shutdown();
|
||||
void frame(float dt);
|
||||
void handleNet();
|
||||
void updateCamera(float dt);
|
||||
|
||||
// screens
|
||||
void drawTitle(ImVec2 vp);
|
||||
void drawJoin(ImVec2 vp);
|
||||
void drawConnecting(ImVec2 vp);
|
||||
void drawCreator(ImVec2 vp);
|
||||
void drawPlay(ImVec2 vp, float dt);
|
||||
void drawHud(ImVec2 vp);
|
||||
void drawLabels(ImVec2 vp);
|
||||
void drawCollection(ImVec2 vp);
|
||||
void drawChat(ImVec2 vp);
|
||||
void drawPause(ImVec2 vp);
|
||||
|
||||
void playInput(float dt);
|
||||
void startDialogue(const std::string& script);
|
||||
void beginConnect(const std::string& host, uint16_t port);
|
||||
bool startLocalServer();
|
||||
void stopLocalServer();
|
||||
void returnToTitle(const std::string& message = {});
|
||||
UiTexture* creatureIcon(uint16_t species);
|
||||
void refreshPreview();
|
||||
bool pressed(int key) const; // game key (ignored while ImGui has the keyboard)
|
||||
bool scripted(const char* key) const;
|
||||
|
||||
Options opt_;
|
||||
hd2d::Window window_;
|
||||
hd2d::Renderer renderer_;
|
||||
hd2d::DebugUI debugUi_;
|
||||
hd2d::OffscreenTarget offscreen_;
|
||||
bool capture_ = false;
|
||||
hd2d::Camera cam_;
|
||||
World world_;
|
||||
NetClient net_;
|
||||
Screen screen_ = Screen::Title;
|
||||
float time_ = 0.0f;
|
||||
int frame_ = 0;
|
||||
bool showDebug_ = false;
|
||||
float uiScale_ = 1.0f;
|
||||
|
||||
// identity
|
||||
std::string token_, lastHost_ = "127.0.0.1", savedName_;
|
||||
uint16_t lastPort_ = kDefaultPort;
|
||||
void loadIdentity();
|
||||
void saveIdentity();
|
||||
|
||||
// title / join
|
||||
int titleSel_ = 0;
|
||||
std::string message_;
|
||||
net::Scanner scanner_;
|
||||
std::vector<net::ServerInfo> found_;
|
||||
float scanTimer_ = 0.0f;
|
||||
char addressBuf_[128] = "127.0.0.1";
|
||||
int serverPid_ = -1;
|
||||
float connectTimer_ = 0.0f;
|
||||
|
||||
// creator
|
||||
Appearance look_;
|
||||
char nameBuf_[24] = "";
|
||||
UiTexture preview_;
|
||||
int previewDir_ = 0;
|
||||
bool creating_ = false;
|
||||
|
||||
// play
|
||||
hd2d::ui::DialogueBox dialogue_;
|
||||
std::string dialogueScript_;
|
||||
hd2d::ui::Toasts toasts_;
|
||||
std::map<std::string, DialogueScript> scripts_;
|
||||
UiTexture henryPortrait_;
|
||||
std::map<uint16_t, std::unique_ptr<UiTexture>> icons_;
|
||||
bool collectionOpen_ = false, pauseOpen_ = false, chatOpen_ = false;
|
||||
int collectionSel_ = 0, pauseSel_ = 0;
|
||||
char chatBuf_[128] = "";
|
||||
bool chatFocus_ = false;
|
||||
float camYawTarget_ = 0.0f;
|
||||
glm::vec2 heldMove_{0.0f};
|
||||
};
|
||||
|
||||
} // namespace bs
|
||||
Reference in New Issue
Block a user