-
Notifications
You must be signed in to change notification settings - Fork 0
/
level.h
203 lines (158 loc) · 5.81 KB
/
level.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#ifndef LEVEL_H
#define LEVEL_H
#include <pthread.h>
#include <string.h>
#include "block.h"
#include "physics.h"
#include "position.h"
#include "list.h"
#include "npc.h"
#define MAX_CLIENTS_PER_LEVEL 64
#define MAX_NPCS_PER_LEVEL 128
#define MAX_HOOKS_PER_LEVEL 8
struct player_t;
struct client_t;
struct undodb_t;
static inline bool user_compare(unsigned *a, unsigned *b)
{
return *a == *b;
}
LIST(user, unsigned, user_compare)
struct level_hook_data_t
{
unsigned size;
void *data;
};
enum
{
EVENT_TICK,
EVENT_CHAT,
EVENT_MOVE,
EVENT_SPAWN,
EVENT_DESPAWN,
EVENT_BLOCK,
EVENT_SAVE,
EVENT_INIT,
EVENT_DEINIT,
};
typedef bool(*level_hook_func_t)(int event, struct level_t *l, struct client_t *c, void *data, struct level_hook_data_t *arg);
struct level_hooks_t
{
char name[16];
level_hook_func_t func;
struct level_hook_data_t data;
};
struct block_event
{
int x, y, z;
enum blocktype_t bt; /* Existing blocktype */
enum blocktype_t nt; /* New blocktype */
uint16_t data;
};
struct level_t
{
char name[64];
int16_t x;
int16_t y;
int16_t z;
struct position_t spawn;
unsigned owner;
uint8_t rankvisit;
uint8_t rankbuild;
uint8_t rankown;
struct user_list_t uservisit;
struct user_list_t userbuild;
struct user_list_t userown;
struct block_t *blocks;
struct physics_list_t physics, physics2;
struct block_update_list_t updates;
unsigned physics_iter, physics_done;
unsigned updates_iter;
unsigned physics_runtime, updates_runtime;
unsigned physics_runtime_last, updates_runtime_last;
unsigned physics_count_last, updates_count_last;
struct level_hooks_t level_hook[MAX_HOOKS_PER_LEVEL];
/* Max players on a level */
struct client_t *clients[MAX_CLIENTS_PER_LEVEL];
struct npc *npcs[MAX_NPCS_PER_LEVEL];
struct undodb_t *undo;
uint8_t changed:1;
uint8_t instant:1;
uint8_t physics_pause:1;
uint8_t convert:1;
uint8_t delete:1;
uint8_t no_changes:1;
pthread_mutex_t mutex;
int inuse;
pthread_mutex_t inuse_mutex;
pthread_mutex_t hook_mutex;
pthread_mutex_t physics_mutex;
};
bool level_t_compare(struct level_t **a, struct level_t **b);
LIST(level, struct level_t *, level_t_compare)
extern struct level_list_t s_levels;
bool level_get_xyz(const struct level_t *level, unsigned index, int16_t *x, int16_t *y, int16_t *z);
static inline unsigned level_get_index(const struct level_t *level, unsigned x, unsigned y, unsigned z)
{
//return x + (z * level->y + y) * level->x;
return x + (z + y * level->z) * level->x;
}
static inline bool level_valid_xyz(const struct level_t *level, int x, int y, int z)
{
return x >= 0 && x < level->x && y >= 0 && y < level->y && z >= 0 && z < level->z;
}
static inline enum blocktype_t level_get_blocktype(const struct level_t *level, int x, int y, int z)
{
if (y >= level->y) {
if (!level_valid_xyz(level, x, 0, z)) return ADMINIUM;
return AIR;
}
if (!level_valid_xyz(level, x, y, z)) return ADMINIUM;
return level->blocks[level_get_index(level, x, y, z)].type;
}
static inline unsigned level_get_blockowner(const struct level_t *level, int x, int y, int z)
{
return level->blocks[level_get_index(level, x, y, z)].owner;
}
bool level_init(struct level_t *level, int16_t x, int16_t y, int16_t z, const char *name, bool zero);
void level_set_block(struct level_t *level, struct block_t *block, unsigned index);
bool level_send(struct client_t *client);
void level_gen(struct level_t *level, const char *type, int height_range, int sea_height);
bool level_is_loaded(const char *name);
bool level_get_by_name(const char *name, struct level_t **level);
bool level_load(const char *name, struct level_t **level);
void level_save_all(void *arg);
void level_unload(struct level_t *level);
void level_unload_empty(void *arg);
int level_get_new_npc_id(struct level_t *level, struct npc *npc);
void level_notify_all(struct level_t *level, const char *message);
void level_change_block(struct level_t *level, struct client_t *c, int16_t x, int16_t y, int16_t z, uint8_t m, uint8_t t, bool click);
void level_change_block_force(struct level_t *level, struct block_t *block, unsigned index);
void level_addupdate(struct level_t *level, unsigned index, enum blocktype_t newtype, uint16_t newdata);
void level_addupdate_with_owner(struct level_t *level, unsigned index, enum blocktype_t newtype, uint16_t newdata, unsigned owner);
void level_addupdate_force(struct level_t *level, unsigned index, enum blocktype_t newtype, uint16_t newdata);
void level_process_physics(bool can_init);
void level_process_updates(bool can_init);
void register_level_hook_func(const char *name, level_hook_func_t level_hook_func);
void deregister_level_hook_func(const char *name);
void level_copy(struct level_t *src, struct level_t *dst);
bool level_hook_attach(struct level_t *l, const char *name);
bool level_hook_detach(struct level_t *l, const char *name);
bool level_hook_delete(struct level_t *l, const char *name);
bool call_level_hook(int hook, struct level_t *l, struct client_t *c, void *data);
bool level_user_can_visit(const struct level_t *l, const struct player_t *p);
bool level_user_can_build(const struct level_t *l, const struct player_t *p);
bool level_user_can_own(const struct level_t *l, const struct player_t *p);
void level_cuboid(struct level_t *level, unsigned start, unsigned end, enum blocktype_t old_type, enum blocktype_t new_type, const struct player_t *p);
void level_user_undo(struct level_t *level, unsigned globalid, struct client_t *client);
bool level_inuse(struct level_t *level, bool inuse);
void level_reset_physics(struct level_t *level);
void level_reinit_physics(struct level_t *level);
void physics_init(void);
void physics_deinit(void);
void physics_list_update(struct level_t *level, unsigned index, int state);
void *level_save_thread(void *arg);
void *level_load_thread(void *arg);
void *level_gen_thread(struct level_t *level, const char *type);
void level_hooks_deinit(void);
#endif /* LEVEL_H */