/
Simulation.h
221 lines (200 loc) · 7.01 KB
/
Simulation.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
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
#pragma once
#include "Particle.h"
#include "Stickman.h"
#include "WallType.h"
#include "Sign.h"
#include "ElementDefs.h"
#include "BuiltinGOL.h"
#include "MenuSection.h"
#include "CoordStack.h"
#include "gravity/GravityPtr.h"
#include "common/tpt-rand.h"
#include "Element.h"
#include "SimulationConfig.h"
#include <cstring>
#include <cstddef>
#include <vector>
#include <array>
#include <memory>
#include <optional>
constexpr int CHANNELS = int(MAX_TEMP - 73) / 100 + 2;
class Snapshot;
class Brush;
class SimulationSample;
struct matrix2d;
struct vector2d;
class Simulation;
class Renderer;
class Gravity;
class Air;
class GameSave;
class Simulation
{
public:
GravityPtr grav;
std::unique_ptr<Air> air;
RNG rng;
std::vector<sign> signs;
//Element * elements;
int currentTick;
int replaceModeSelected;
int replaceModeFlags;
int debug_nextToUpdate;
int debug_mostRecentlyUpdated = -1; // -1 when between full update loops
int parts_lastActiveIndex;
int pfree;
int NUM_PARTS;
bool elementRecount;
int elementCount[PT_NUM];
int ISWIRE;
bool force_stacking_check;
int emp_decor;
int emp_trigger_count;
bool etrd_count_valid;
int etrd_life0_count;
int lightningRecreate;
//Stickman
playerst player;
playerst player2;
playerst fighters[MAX_FIGHTERS]; //Defined in Stickman.h
unsigned char fighcount; //Contains the number of fighters
bool gravWallChanged;
//Portals and Wifi
Particle portalp[CHANNELS][8][80];
int portal_rx[8];
int portal_ry[8];
int wireless[CHANNELS][2];
//Gol sim
int CGOL;
int GSPEED;
unsigned int gol[YRES][XRES][5];
//Air sim
float (*vx)[XCELLS];
float (*vy)[XCELLS];
float (*pv)[XCELLS];
float (*hv)[XCELLS];
//Gravity sim
float *gravx;//gravx[YCELLS * XCELLS];
float *gravy;//gravy[YCELLS * XCELLS];
float *gravp;//gravp[YCELLS * XCELLS];
float *gravmap;//gravmap[YCELLS * XCELLS];
//Walls
unsigned char bmap[YCELLS][XCELLS];
unsigned char emap[YCELLS][XCELLS];
float fvx[YCELLS][XCELLS];
float fvy[YCELLS][XCELLS];
//Particles
Particle parts[NPART];
int pmap[YRES][XRES];
int photons[YRES][XRES];
unsigned int pmap_count[YRES][XRES];
//Simulation Settings
int edgeMode;
int gravityMode;
float customGravityX;
float customGravityY;
int legacy_enable;
int aheat_enable;
int water_equal_test;
int sys_pause;
int framerender;
int pretty_powder;
int sandcolour;
int sandcolour_interface;
int sandcolour_frame;
int deco_space;
uint64_t frameCount;
bool ensureDeterminism;
void Load(const GameSave *save, bool includePressure, Vec2<int> blockP); // block coordinates
std::unique_ptr<GameSave> Save(bool includePressure, Rect<int> partR); // particle coordinates
void SaveSimOptions(GameSave &gameSave);
SimulationSample GetSample(int x, int y);
std::unique_ptr<Snapshot> CreateSnapshot() const;
void Restore(const Snapshot &snap);
int is_blocking(int t, int x, int y) const;
int is_boundary(int pt, int x, int y) const;
int find_next_boundary(int pt, int *x, int *y, int dm, int *em, bool reverse) const;
void photoelectric_effect(int nx, int ny);
int do_move(int i, int x, int y, float nxf, float nyf);
bool move(int i, int x, int y, float nxf, float nyf);
int try_move(int i, int x, int y, int nx, int ny);
int eval_move(int pt, int nx, int ny, unsigned *rr) const;
struct PlanMoveResult
{
int fin_x, fin_y, clear_x, clear_y;
float fin_xf, fin_yf, clear_xf, clear_yf;
float vx, vy;
};
template<bool UpdateEmap, class Sim>
static PlanMoveResult PlanMove(Sim &sim, int i, int x, int y);
bool IsWallBlocking(int x, int y, int type) const;
void create_cherenkov_photon(int pp);
void create_gain_photon(int pp);
void kill_part(int i);
bool FloodFillPmapCheck(int x, int y, int type) const;
int flood_prop(int x, int y, StructProperty prop, PropertyValue propvalue);
bool flood_water(int x, int y, int i);
int FloodINST(int x, int y);
void detach(int i);
bool part_change_type(int i, int x, int y, int t);
//int InCurrentBrush(int i, int j, int rx, int ry);
//int get_brush_flags();
int create_part(int p, int x, int y, int t, int v = -1);
void delete_part(int x, int y);
void get_sign_pos(int i, int *x0, int *y0, int *w, int *h);
int is_wire(int x, int y);
int is_wire_off(int x, int y);
void set_emap(int x, int y);
int parts_avg(int ci, int ni, int t);
void UpdateParticles(int start, int end); // Dispatches an update to the range [start, end).
void SimulateGoL();
void RecalcFreeParticles(bool do_life_dec);
void CheckStacking();
void BeforeSim();
void AfterSim();
void clear_area(int area_x, int area_y, int area_w, int area_h);
void SetEdgeMode(int newEdgeMode);
void SetDecoSpace(int newDecoSpace);
//Drawing Deco
void ApplyDecoration(int x, int y, int colR, int colG, int colB, int colA, int mode);
void ApplyDecorationPoint(int x, int y, int colR, int colG, int colB, int colA, int mode, Brush const &cBrush);
void ApplyDecorationLine(int x1, int y1, int x2, int y2, int colR, int colG, int colB, int colA, int mode, Brush const &cBrush);
void ApplyDecorationBox(int x1, int y1, int x2, int y2, int colR, int colG, int colB, int colA, int mode);
bool ColorCompare(Renderer *ren, int x, int y, int replaceR, int replaceG, int replaceB);
void ApplyDecorationFill(Renderer *ren, int x, int y, int colR, int colG, int colB, int colA, int replaceR, int replaceG, int replaceB);
//Drawing Tools like HEAT, AIR, and GRAV
int Tool(int x, int y, int tool, int brushX, int brushY, float strength = 1.0f);
int ToolBrush(int x, int y, int tool, Brush const &cBrush, float strength = 1.0f);
void ToolLine(int x1, int y1, int x2, int y2, int tool, Brush const &cBrush, float strength = 1.0f);
void ToolBox(int x1, int y1, int x2, int y2, int tool, float strength = 1.0f);
//Drawing Walls
int CreateWalls(int x, int y, int rx, int ry, int wall, Brush const *cBrush = nullptr);
void CreateWallLine(int x1, int y1, int x2, int y2, int rx, int ry, int wall, Brush const *cBrush = nullptr);
void CreateWallBox(int x1, int y1, int x2, int y2, int wall);
int FloodWalls(int x, int y, int wall, int bm);
//Drawing Particles
int CreateParts(int positionX, int positionY, int c, Brush const &cBrush, int flags = -1);
int CreateParts(int x, int y, int rx, int ry, int c, int flags = -1);
int CreatePartFlags(int x, int y, int c, int flags);
void CreateLine(int x1, int y1, int x2, int y2, int c, Brush const &cBrush, int flags = -1);
void CreateLine(int x1, int y1, int x2, int y2, int c);
void CreateBox(int x1, int y1, int x2, int y2, int c, int flags = -1);
int FloodParts(int x, int y, int c, int cm, int flags = -1);
void GetGravityField(int x, int y, float particleGrav, float newtonGrav, float & pGravX, float & pGravY);
int get_wavelength_bin(int *wm);
struct GetNormalResult
{
bool success;
float nx, ny;
int lx, ly, rx, ry;
};
GetNormalResult get_normal(int pt, int x, int y, float dx, float dy) const;
template<bool PhotoelectricEffect, class Sim>
static GetNormalResult get_normal_interp(Sim &sim, int pt, float x0, float y0, float dx, float dy);
void clear_sim();
Simulation();
~Simulation();
bool useLuaCallbacks = false;
private:
CoordStack& getCoordStackSingleton();
};