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
client/NetClient.h
Normal file
67
client/NetClient.h
Normal file
@@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
// Client side of the protocol: connection state machine and message queues.
|
||||
// The World consumes snapshots/events; screens consume profile/dialogue/chat.
|
||||
|
||||
#include "Net.h"
|
||||
#include "Protocol.h"
|
||||
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace bs {
|
||||
|
||||
struct ChatEntry {
|
||||
uint32_t entity = 0;
|
||||
std::string name, text;
|
||||
float age = 0.0f;
|
||||
};
|
||||
|
||||
class NetClient {
|
||||
public:
|
||||
enum class State { Idle, Connecting, NeedCharacter, InGame, Failed };
|
||||
|
||||
bool connect(const std::string& host, uint16_t port, const std::string& token);
|
||||
void disconnect();
|
||||
void update(); // poll the network, fill the queues
|
||||
|
||||
void sendCreate(const std::string& name, const Appearance& look);
|
||||
void sendInput(const InputCmd& cmd);
|
||||
void sendAction(ActionKind kind, uint32_t target = 0, float x = 0.0f, float z = 0.0f);
|
||||
void sendChat(const std::string& text);
|
||||
void sendDialogueDone(const std::string& script);
|
||||
|
||||
State state() const { return state_; }
|
||||
const std::string& error() const { return error_; }
|
||||
const WelcomeMsg& welcome() const { return welcome_; }
|
||||
const ProfileMsg& profile() const { return profile_; }
|
||||
bool hasProfile() const { return hasProfile_; }
|
||||
uint32_t localEntity() const { return profile_.entityId ? profile_.entityId : welcome_.entityId; }
|
||||
uint32_t pingMs() const;
|
||||
|
||||
std::map<uint32_t, PlayerInfoMsg> players; // every player entity's name + look
|
||||
std::deque<SnapshotMsg> snapshots; // newest last; the World pops them
|
||||
std::vector<GameEvent> events;
|
||||
std::vector<std::string> dialogues;
|
||||
std::vector<std::string> toasts;
|
||||
std::vector<ChatEntry> chat;
|
||||
std::vector<uint32_t> playersLeft;
|
||||
bool profileChanged = false;
|
||||
|
||||
private:
|
||||
void handle(const std::vector<uint8_t>& data);
|
||||
void send(net::Channel ch, const Writer& w);
|
||||
|
||||
std::unique_ptr<net::Host> host_;
|
||||
uint32_t peer_ = 0;
|
||||
State state_ = State::Idle;
|
||||
std::string error_, token_;
|
||||
WelcomeMsg welcome_;
|
||||
ProfileMsg profile_;
|
||||
bool hasProfile_ = false;
|
||||
std::vector<InputCmd> recentInputs_;
|
||||
};
|
||||
|
||||
} // namespace bs
|
||||
Reference in New Issue
Block a user