#include "../app/TextureIndex.hpp"
#include <iostream>
+#include <glm/gtx/io.hpp>
+
+using namespace std;
namespace blank {
}
-InteractiveState::InteractiveState(MasterState &master)
+// TODO: this clutter is a giant mess
+InteractiveState::InteractiveState(MasterState &master, uint32_t player_id)
: master(master)
, block_types()
, save(master.GetEnv().config.GetWorldPath(master.GetWorldConf().name, master.GetClientConf().host))
, world(block_types, master.GetWorldConf(), save)
, chunk_renderer(world, master.GetWorldConf().load.load_dist)
-, interface(master.GetInterfaceConf(), master.GetEnv(), world) {
+, interface(
+ master.GetInterfaceConf(),
+ master.GetEnv(),
+ world,
+ *world.AddPlayer(master.GetInterfaceConf().player_name, player_id)
+) {
TextureIndex tex_index;
master.GetEnv().loader.LoadBlockTypes("default", block_types, tex_index);
chunk_renderer.LoadTextures(master.GetEnv().loader, tex_index);
chunk_renderer.Rebase(interface.Player().ChunkCoords());
chunk_renderer.Update(dt);
+ master.GetClient().SendPlayerUpdate(interface.Player());
+
glm::mat4 trans = interface.Player().Transform(interface.Player().ChunkCoords());
glm::vec3 dir(trans * glm::vec4(0.0f, 0.0f, -1.0f, 0.0f));
glm::vec3 up(trans * glm::vec4(0.0f, 1.0f, 0.0f, 0.0f));
, client_conf(cc)
, state()
, client(cc)
-, init_state(*this) {
+, init_state(*this)
+, login_packet(-1) {
client.GetConnection().SetHandler(this);
}
void MasterState::Quit() {
+ if (!client.GetConnection().Closed()) {
+ client.SendPart();
+ }
env.state.PopUntil(this);
}
void MasterState::OnEnter() {
- client.SendLogin(intf_conf.player_name);
+ login_packet = client.SendLogin(intf_conf.player_name);
env.state.Push(&init_state);
}
void MasterState::Update(int dt) {
client.Handle();
client.Update(dt);
- if (client.GetConnection().Closed()) {
- Quit();
- // TODO: push disconnected message
- }
}
}
+void MasterState::OnPacketLost(uint16_t id) {
+ if (id == login_packet) {
+ login_packet = client.SendLogin(intf_conf.player_name);
+ }
+}
+
+void MasterState::OnTimeout() {
+ if (client.GetConnection().Closed()) {
+ // TODO: push disconnected message
+ cout << "connection timed out" << endl;
+ Quit();
+ }
+}
+
void MasterState::On(const Packet::Join &pack) {
pack.ReadWorldName(world_conf.name);
if (state) {
// changing worlds
- std::cout << "server changing worlds" << std::endl;
+ cout << "server changing worlds to \"" << world_conf.name << '"' << endl;
} else {
// joining game
- std::cout << "joined game" << std::endl;
+ cout << "joined game \"" << world_conf.name << '"' << endl;
}
- state.reset(new InteractiveState(*this));
+
+ uint32_t player_id;
+ pack.ReadPlayerID(player_id);
+ state.reset(new InteractiveState(*this, player_id));
pack.ReadPlayer(state->GetInterface().Player());
void MasterState::On(const Packet::Part &pack) {
if (state) {
// kicked
- std::cout << "kicked by server" << std::endl;
+ cout << "kicked by server" << endl;
} else {
// join refused
- std::cout << "login refused by server" << std::endl;
+ cout << "login refused by server" << endl;
}
Quit();
}
+void MasterState::On(const Packet::SpawnEntity &pack) {
+ if (!state) {
+ cout << "got entity spawn before world was created" << endl;
+ Quit();
+ return;
+ }
+ uint32_t entity_id;
+ pack.ReadEntityID(entity_id);
+ Entity *entity = state->GetWorld().AddEntity(entity_id);
+ if (!entity) {
+ cout << "entity ID inconsistency" << endl;
+ Quit();
+ return;
+ }
+ pack.ReadEntity(*entity);
+ cout << "spawned entity " << entity->Name() << " at " << entity->AbsolutePosition() << endl;
+}
+
+void MasterState::On(const Packet::DespawnEntity &pack) {
+ if (!state) {
+ cout << "got entity despawn before world was created" << endl;
+ Quit();
+ return;
+ }
+ uint32_t entity_id;
+ pack.ReadEntityID(entity_id);
+ for (Entity &entity : state->GetWorld().Entities()) {
+ if (entity.ID() == entity_id) {
+ entity.Kill();
+ cout << "despawned entity " << entity.Name() << " at " << entity.AbsolutePosition() << endl;
+ return;
+ }
+ }
+}
+
+void MasterState::On(const Packet::EntityUpdate &pack) {
+ if (!state) {
+ cout << "got entity update before world was created" << endl;
+ Quit();
+ return;
+ }
+
+ auto world_iter = state->GetWorld().Entities().begin();
+ auto world_end = state->GetWorld().Entities().end();
+
+ uint32_t count = 0;
+ pack.ReadEntityCount(count);
+
+ for (uint32_t i = 0; i < count; ++i) {
+ uint32_t entity_id = 0;
+ pack.ReadEntityID(entity_id, i);
+
+ while (world_iter != world_end && world_iter->ID() < entity_id) {
+ ++world_iter;
+ }
+ if (world_iter == world_end) {
+ // nothing can be done from here
+ return;
+ }
+ if (world_iter->ID() == entity_id) {
+ pack.ReadEntity(*world_iter, i);
+ }
+ }
+}
+
}
}