]> git.localhorst.tv Git - blank.git/blob - src/client/client.cpp
9c87549a3e27094c1ad8ffc8cc47b3143c550b53
[blank.git] / src / client / client.cpp
1 #include "InitialState.hpp"
2 #include "InteractiveState.hpp"
3 #include "MasterState.hpp"
4
5 #include "../app/Environment.hpp"
6 #include "../app/init.hpp"
7 #include "../app/TextureIndex.hpp"
8
9 #include <iostream>
10
11
12 namespace blank {
13 namespace client {
14
15 InitialState::InitialState(MasterState &master)
16 : master(master)
17 , message() {
18         message.Position(glm::vec3(0.0f), Gravity::CENTER);
19         message.Set(master.GetEnv().assets.large_ui_font, "logging in");
20 }
21
22 void InitialState::OnEnter() {
23
24 }
25
26 void InitialState::Handle(const SDL_Event &evt) {
27         if (evt.type == SDL_QUIT) {
28                 master.Quit();
29         }
30 }
31
32 void InitialState::Update(int dt) {
33         master.Update(dt);
34 }
35
36 void InitialState::Render(Viewport &viewport) {
37         message.Render(viewport);
38 }
39
40
41 // TODO: this clutter is a giant mess
42 InteractiveState::InteractiveState(MasterState &master, uint32_t player_id)
43 : master(master)
44 , block_types()
45 , save(master.GetEnv().config.GetWorldPath(master.GetWorldConf().name, master.GetClientConf().host))
46 , world(block_types, master.GetWorldConf(), save)
47 , chunk_renderer(world, master.GetWorldConf().load.load_dist)
48 , interface(
49         master.GetInterfaceConf(),
50         master.GetEnv(),
51         world,
52         *world.AddPlayer(master.GetInterfaceConf().player_name, player_id)
53 ) {
54         TextureIndex tex_index;
55         master.GetEnv().loader.LoadBlockTypes("default", block_types, tex_index);
56         chunk_renderer.LoadTextures(master.GetEnv().loader, tex_index);
57         chunk_renderer.FogDensity(master.GetWorldConf().fog_density);
58         // TODO: better solution for initializing HUD
59         interface.SelectNext();
60 }
61
62 void InteractiveState::OnEnter() {
63         master.GetEnv().window.GrabMouse();
64 }
65
66 void InteractiveState::Handle(const SDL_Event &event) {
67         switch (event.type) {
68                 case SDL_KEYDOWN:
69                         interface.HandlePress(event.key);
70                         break;
71                 case SDL_KEYUP:
72                         interface.HandleRelease(event.key);
73                         break;
74                 case SDL_MOUSEBUTTONDOWN:
75                         interface.HandlePress(event.button);
76                         break;
77                 case SDL_MOUSEBUTTONUP:
78                         interface.HandleRelease(event.button);
79                         break;
80                 case SDL_MOUSEMOTION:
81                         interface.Handle(event.motion);
82                         break;
83                 case SDL_MOUSEWHEEL:
84                         interface.Handle(event.wheel);
85                         break;
86                 case SDL_QUIT:
87                         master.Quit();
88                         break;
89                 default:
90                         break;
91         }
92 }
93
94 void InteractiveState::Update(int dt) {
95         master.Update(dt);
96
97         interface.Update(dt);
98         world.Update(dt);
99         chunk_renderer.Rebase(interface.Player().ChunkCoords());
100         chunk_renderer.Update(dt);
101
102         master.GetClient().SendPlayerUpdate(interface.Player());
103
104         glm::mat4 trans = interface.Player().Transform(interface.Player().ChunkCoords());
105         glm::vec3 dir(trans * glm::vec4(0.0f, 0.0f, -1.0f, 0.0f));
106         glm::vec3 up(trans * glm::vec4(0.0f, 1.0f, 0.0f, 0.0f));
107         master.GetEnv().audio.Position(interface.Player().Position());
108         master.GetEnv().audio.Velocity(interface.Player().Velocity());
109         master.GetEnv().audio.Orientation(dir, up);
110 }
111
112 void InteractiveState::Render(Viewport &viewport) {
113         viewport.WorldPosition(interface.Player().Transform(interface.Player().ChunkCoords()));
114         chunk_renderer.Render(viewport);
115         world.Render(viewport);
116         interface.Render(viewport);
117 }
118
119
120 MasterState::MasterState(
121         Environment &env,
122         const World::Config &wc,
123         const Interface::Config &ic,
124         const Client::Config &cc)
125 : env(env)
126 , world_conf(wc)
127 , intf_conf(ic)
128 , client_conf(cc)
129 , state()
130 , client(cc)
131 , init_state(*this)
132 , login_packet(-1) {
133         client.GetConnection().SetHandler(this);
134 }
135
136 void MasterState::Quit() {
137         env.state.PopUntil(this);
138 }
139
140
141 void MasterState::OnEnter() {
142         login_packet = client.SendLogin(intf_conf.player_name);
143         env.state.Push(&init_state);
144 }
145
146
147 void MasterState::Handle(const SDL_Event &event) {
148
149 }
150
151
152 void MasterState::Update(int dt) {
153         client.Handle();
154         client.Update(dt);
155 }
156
157
158 void MasterState::Render(Viewport &) {
159
160 }
161
162
163 void MasterState::OnPacketLost(std::uint16_t id) {
164         if (id == login_packet) {
165                 login_packet = client.SendLogin(intf_conf.player_name);
166         }
167 }
168
169 void MasterState::OnTimeout() {
170         if (client.GetConnection().Closed()) {
171                 Quit();
172                 // TODO: push disconnected message
173         }
174 }
175
176 void MasterState::On(const Packet::Join &pack) {
177         pack.ReadWorldName(world_conf.name);
178
179         if (state) {
180                 // changing worlds
181                 std::cout << "server changing worlds" << std::endl;
182         } else {
183                 // joining game
184                 std::cout << "joined game" << std::endl;
185         }
186
187         uint32_t player_id;
188         pack.ReadPlayerID(player_id);
189         state.reset(new InteractiveState(*this, player_id));
190
191         pack.ReadPlayer(state->GetInterface().Player());
192
193         env.state.PopAfter(this);
194         env.state.Push(state.get());
195 }
196
197 void MasterState::On(const Packet::Part &pack) {
198         if (state) {
199                 // kicked
200                 std::cout << "kicked by server" << std::endl;
201         } else {
202                 // join refused
203                 std::cout << "login refused by server" << std::endl;
204         }
205         Quit();
206 }
207
208 }
209 }