summaryrefslogtreecommitdiff
path: root/src/simulation/Simulation.h
blob: fe65d41669acbfbfc104cd63766f67c39796c755 (plain)
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
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
/*
 * Simulation.h
 *
 *  Created on: Jan 2, 2012
 *      Author: Simon
 */

#ifndef SIMULATION_H_
#define SIMULATION_H_
#include <cstring>
#include "Config.h"
#include "Renderer.h"
#include "Graphics.h"
#include "Elements.h"
#include "Tools.h"
#include "Misc.h"
#include "game/Brush.h"
#include "Gravity.h"
#include "SimulationData.h"

#define CHANNELS ((int)(MAX_TEMP-73)/100+2)

class Simulation;
class Renderer;
class Gravity;
class Air;

//Describes fields in structures such as Particle or Element
struct StructProperty
{
	enum PropertyType { ParticleType, Colour, Integer, UInteger, Float, String };
	std::string Name;
	PropertyType Type;
	intptr_t Offset;
	
	StructProperty(std::string name, PropertyType type, intptr_t offset):
		Name(name),
		Type(type),
		Offset(offset)
	{
		
	}
};

struct Particle
{
	int type;
	int life, ctype;
	float x, y, vx, vy;
	float temp;
	float pavg[2];
	int flags;
	int tmp;
	int tmp2;
	unsigned int dcolour;
	/** Returns a list of properties, their type and offset within the structure that can be changed
	by higher-level processes refering to them by name such as Lua or the property tool **/
	static std::vector<StructProperty> GetProperties()
	{
		std::vector<StructProperty> properties;
		properties.push_back(StructProperty("type", StructProperty::ParticleType, offsetof(Particle, type)));
		properties.push_back(StructProperty("life", StructProperty::ParticleType, offsetof(Particle, life)));
		properties.push_back(StructProperty("ctype", StructProperty::ParticleType, offsetof(Particle, ctype)));
		properties.push_back(StructProperty("x", StructProperty::Float, offsetof(Particle, x)));
		properties.push_back(StructProperty("y", StructProperty::Float, offsetof(Particle, y)));
		properties.push_back(StructProperty("vx", StructProperty::Float, offsetof(Particle, vx)));
		properties.push_back(StructProperty("vy", StructProperty::Float, offsetof(Particle, vy)));
		properties.push_back(StructProperty("temp", StructProperty::Float, offsetof(Particle, temp)));
		properties.push_back(StructProperty("flags", StructProperty::UInteger, offsetof(Particle, flags)));
		properties.push_back(StructProperty("tmp", StructProperty::Integer, offsetof(Particle, tmp)));
		properties.push_back(StructProperty("tmp2", StructProperty::Integer, offsetof(Particle, tmp2)));
		properties.push_back(StructProperty("dcolour", StructProperty::UInteger, offsetof(Particle, dcolour)));
		return properties;
	}
};
typedef struct Particle Particle;

struct part_type
{
	char *name;
	pixel pcolors;
	float advection;
	float airdrag;
	float airloss;
	float loss;
	float collision;
	float gravity;
	float diffusion;
	float hotair;
	int falldown;
	int flammable;
	int explosive;
	int meltable;
	int hardness;
	int menu;
	int enabled;
	int weight;
	int menusection;
	float heat;
	unsigned char hconduct;
	char *descs;
	char state;
	unsigned int properties;
	int (*update_func) (UPDATE_FUNC_ARGS);
	int (*graphics_func) (GRAPHICS_FUNC_ARGS);
};
typedef struct part_type part_type;

struct part_transition
{
	float plv; // transition occurs if pv is lower than this
	int plt;
	float phv; // transition occurs if pv is higher than this
	int pht;
	float tlv; // transition occurs if t is lower than this
	int tlt;
	float thv; // transition occurs if t is higher than this
	int tht;
};
typedef struct part_transition part_transition;


struct wall_type
{
	pixel colour;
	pixel eglow; // if emap set, add this to fire glow
	int drawstyle;
	const char *descs;
};
typedef struct wall_type wall_type;

struct gol_menu
{
	const char *name;
	pixel colour;
	int goltype;
	const char *description;
};
typedef struct gol_menu gol_menu;

struct menu_section
{
	char *icon;
	const char *name;
	int itemcount;
	int doshow;
};
typedef struct menu_section menu_section;

struct sign
{
public:
	enum Justification { Left = 0, Centre = 1, Right = 2 };
	sign(std::string text_, int x_, int y_, Justification justification_):
		text(text_),
		x(x_),
		y(y_),
		ju(justification_)
	{}
	int x, y;
	Justification ju;
	std::string text;
};
typedef struct sign sign;

struct playerst
{
	char comm;           //command cell
	char pcomm;          //previous command
	int elem;            //element power
	float legs[16];      //legs' positions
	float accs[8];       //accelerations
	char spwn;           //if stick man was spawned
	unsigned int frames; //frames since last particle spawn - used when spawning LIGH
};
typedef struct playerst playerst;

//#ifdef _cplusplus
class Simulation
{
private:
public:

	Gravity * grav;
	Air * air;

	vector<sign> signs;
	Element * elements;
	vector<SimTool*> tools;
	unsigned int * platent;
	wall_type wtypes[UI_WALLCOUNT];
	gol_menu gmenu[NGOL];
	int goltype[NGOL];
	int grule[NGOL+1][10];
	menu_section msections[SC_TOTAL];

	playerst player;
	playerst player2;
	playerst fighters[256]; //255 is the maximum number of fighters
	unsigned char fighcount; //Contains the number of fighters
	int lighting_recreate;
	int gravwl_timeout;
	Particle portalp[CHANNELS][8][80];
	Particle emptyparticle;
	int portal_rx[8];
	int portal_ry[8];
	int wireless[CHANNELS][2];
	char can_move[PT_NUM][PT_NUM];
	int parts_lastActiveIndex;// = NPART-1;
	int pfree;
	int NUM_PARTS;
	int elementCount[PT_NUM];
	int ISWIRE;
	//Gol sim
	int CGOL;
	int ISGOL;
	int GSPEED;
	unsigned char gol[XRES][YRES];
	unsigned char gol2[XRES][YRES][NGOL+1];
	//Air sim
	float (*vx)[XRES/CELL];
	float (*vy)[XRES/CELL];
	float (*pv)[XRES/CELL];
	float (*hv)[XRES/CELL];
	//Gravity sim
	float *gravx;//gravx[(YRES/CELL) * (XRES/CELL)];
	float *gravy;//gravy[(YRES/CELL) * (XRES/CELL)];
	float *gravp;//gravp[(YRES/CELL) * (XRES/CELL)];
	float *gravmap;//gravmap[(YRES/CELL) * (XRES/CELL)];
	//Walls
	unsigned char bmap[YRES/CELL][XRES/CELL];
	unsigned char emap[YRES/CELL][XRES/CELL];
	float fvx[YRES/CELL][XRES/CELL];
	float fvy[YRES/CELL][XRES/CELL];
	//Particles
	Particle parts[NPART];
	int pmap[YRES][XRES];
	int photons[YRES][XRES];
	//
	int gravityMode;
	//int airMode;
	int ngrav_enable;
	int legacy_enable;
	int aheat_enable;
	int VINE_MODE;
	int water_equal_test;
	int sys_pause;
	int framerender;
	int pretty_powder;
	//
	int sandcolour_r;
	int sandcolour_g;
	int sandcolour_b; //TODO: Make a single variable

	int Load(unsigned char * data, int dataLength);
	int Load(int x, int y, unsigned char * data, int dataLength);
	unsigned char * Save(int & dataLength);
	unsigned char * Save(int x1, int y1, int x2, int y2, int & dataLength);
	Particle Get(int x, int y);
	inline int is_blocking(int t, int x, int y);
	inline int is_boundary(int pt, int x, int y);
	inline int find_next_boundary(int pt, int *x, int *y, int dm, int *em);
	inline int pn_junction_sprk(int x, int y, int pt);
	inline void photoelectric_effect(int nx, int ny);
	inline unsigned direction_to_map(float dx, float dy, int t);
	inline int do_move(int i, int x, int y, float nxf, float nyf);
	inline int try_move(int i, int x, int y, int nx, int ny);
	inline int eval_move(int pt, int nx, int ny, unsigned *rr);
	void init_can_move();
	void create_cherenkov_photon(int pp);
	void create_gain_photon(int pp);
	inline void kill_part(int i);
	int flood_prop(int x, int y, size_t propoffset, void * propvalue, StructProperty::PropertyType proptype);
	int flood_prop_2(int x, int y, size_t propoffset, void * propvalue, StructProperty::PropertyType proptype, int parttype, char * bitmap);
	int flood_water(int x, int y, int i, int originaly, int check);
	inline void detach(int i);
	inline void part_change_type(int i, int x, int y, int t);
	inline int create_part_add_props(int p, int x, int y, int tv, int rx, int ry);
	//int InCurrentBrush(int i, int j, int rx, int ry);
	//int get_brush_flags();
	inline int create_part(int p, int x, int y, int t);
	inline void delete_part(int x, int y, int flags);
	inline int is_wire(int x, int y);
	inline int is_wire_off(int x, int y);
	inline void set_emap(int x, int y);
	inline int parts_avg(int ci, int ni, int t);
	void create_arc(int sx, int sy, int dx, int dy, int midpoints, int variance, int type, int flags);
	int nearest_part(int ci, int t, int max_d);
	void update_particles_i(int start, int inc);
	void update_particles();
	void rotate_area(int area_x, int area_y, int area_w, int area_h, int invert);
	void clear_area(int area_x, int area_y, int area_w, int area_h);

	int Tool(int x, int y, int tool, float strength);
	int ToolBrush(int x, int y, int tool, Brush * cBrush);
	void ToolLine(int x1, int y1, int x2, int y2, int tool, Brush * cBrush);
	void ToolBox(int x1, int y1, int x2, int y2, int tool, Brush * cBrush);
	
	void CreateBox(int x1, int y1, int x2, int y2, int c, int flags);
	int FloodParts(int x, int y, int c, int cm, int bm, int flags);
	int CreateParts(int x, int y, int rx, int ry, int c, int flags, Brush * cBrush = NULL);
	void CreateLine(int x1, int y1, int x2, int y2, int rx, int ry, int c, int flags, Brush * cBrush = NULL);
	
	void CreateWallBox(int x1, int y1, int x2, int y2, int c, int flags);
	int FloodWalls(int x, int y, int c, int cm, int bm, int flags);
	int CreateWalls(int x, int y, int rx, int ry, int c, int flags, Brush * cBrush = NULL);
	void CreateWallLine(int x1, int y1, int x2, int y2, int rx, int ry, int c, int flags, Brush * cBrush = NULL);
	
	void ApplyDecoration(int x, int y, int colR, int colG, int colB, int colA, int mode);
	void ApplyDecorationPoint(int x, int y, int rx, int ry, int colR, int colG, int colB, int colA, int mode, Brush * cBrush = NULL);
	void ApplyDecorationLine(int x1, int y1, int x2, int y2, int rx, int ry, int colR, int colG, int colB, int colA, int mode, Brush * cBrush = NULL);
	void ApplyDecorationBox(int x1, int y1, int x2, int y2, int colR, int colG, int colB, int colA, int mode);
	
	void *transform_save(void *odata, int *size, matrix2d transform, vector2d translate);
	inline void orbitalparts_get(int block1, int block2, int resblock1[], int resblock2[]);
	inline void orbitalparts_set(int *block1, int *block2, int resblock1[], int resblock2[]);
	inline int get_wavelength_bin(int *wm);
	inline int get_normal(int pt, int x, int y, float dx, float dy, float *nx, float *ny);
	inline int get_normal_interp(int pt, float x0, float y0, float dx, float dy, float *nx, float *ny);
	void clear_sim();
	void UpdateParticles();
	Simulation();
	~Simulation();
};
//#endif

#endif /* SIMULATION_H_ */