-
Notifications
You must be signed in to change notification settings - Fork 0
/
base_element.h
141 lines (112 loc) · 4.5 KB
/
base_element.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
#include <SDL2/SDL.h>
using namespace std;
// BASE
#define AIR_THERM_CONDUCTIVITY 0.024
class Element{
public:
int x;
int y;
SDL_Colour colour = {106, 13, 173}; // Purple (this should be overridden by child class)
SDL_Colour baseColour = {106, 13, 173};
string state = "";
string tag = ""; // Used to differentiate elements
bool updated = false;
bool onFire = false;
float fireSmokiness = 0.02; // higher is more smoky
float temperature = 0; // measured in °C compared to air temperature
float thermalConductivity = 0.05; // 0 to 1
float igniteTemp = 100;
int fireTicks = 1000;
float health = 100;
float heatCapacity = 1; // must be greater than 1
int acidResistance = 1; // >= 0, greater the value -> more acid required to destroy element
Element(int x, int y): x(x), y(y){
initElement();
}
void initElement() {
colour = baseColour;
onFire = false;
thermalConductivity *= 0.6 + 1.07*((float)rand()/RAND_MAX);
fireTicks *= 0.6 + 1.07*((float)rand()/RAND_MAX);
heatCapacity *= 0.6 + 1.07*((float)rand()/RAND_MAX);
}
void setX(int X){
x = X;
}
void setY(int Y){
y = Y;
}
void render(SDL_Renderer* renderer, int size, bool heatmap){
SDL_SetRenderDrawColor(renderer, colour.r, colour.g, colour.b, colour.a);
if (heatmap) {
SDL_Colour heat_col;
if (temperature < -100) {
heat_col = {50, 50, 50, 200};
} else if (temperature < -50) {
heat_col = {0, 0, 200, 50};
} else if (temperature < -20) {
heat_col = {0, 255, 200, 50};
} else if (temperature < 1) {
heat_col = {0, 255, 0, 50};
} else if (temperature < 10000) {
heat_col = {255, (Uint8)(255 - log(temperature) * 27.686), 0, 200};
} else {
heat_col = {255, 255, 255, 200};
}
SDL_SetRenderDrawColor(renderer, heat_col.r, heat_col.g, heat_col.b, heat_col.a);
}
SDL_Rect rect = {x * size, y * size, size, size};
SDL_RenderFillRect(renderer, &rect);
}
virtual void update(double deltaTime){} // virtual means this function can be overridden by child class
void updateFire() {
if (!canBeSetOnFire()) {return;}
if (temperature > igniteTemp) {
ignite();
}
if (!onFire) {return;}
if (temperature < igniteTemp - 1) {
putOutFire();
return;
}
// increase temperature
temperature += 5;
// reduce fire ticks destroy self if so
fireTicks --;
if (fireTicks <= 0) {
health = 0;
return;
}
// look like fire
colour.r = (Uint8)(200 + rand()%40);
colour.g = (Uint8)(rand()%255);
colour.b = (Uint8)(rand()%10);
// // spread to neighbours by chance
// if ((float)rand()/RAND_MAX > fireDiffusivity) {return;}
// // pick a random neighbour
// int dx = rand()%(fireSpreadRange*2+1) - fireSpreadRange; // has the effect of being in the range [-fireSpreadRange, fireSpreadRange] (incl. 0)
// int dy = rand()%(fireSpreadRange*2+1) - fireSpreadRange;
// if (dx == 0 && dy == 0) {return;}
// if (grid.isEmpty(x+dx, y+dy)) {return;}
// if (!grid.getPtr(x+dx, y+dy)->canBeSetOnFire()) {return;}
// // grid.getPtr(x+dx, y+dy)->attemptSetOnFire();
}
virtual void setFreeFalling(){}
void ignite() {
if (onFire) {return;}
temperature = max((float)igniteTemp+1, temperature);
onFire = true;
}
void putOutFire() {
if (!onFire) {return;}
onFire = false;
colour = baseColour;
}
virtual bool attemptSetOnFire() {return false;}
virtual bool canBeSetOnFire() {return false;}
virtual double getDensity() {return NAN;}
virtual int acidify() {health -= 100 / acidResistance; return acidResistance;}
void print(){
cout << "Element of x: " << x << " y: " << y << "\n";
}
};