Fix compile
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / mapobjects / func / rainsnow.qc
1 #include "rainsnow.qh"
2 REGISTER_NET_LINKED(ENT_CLIENT_RAINSNOW)
3
4 #ifdef SVQC
5 bool rainsnow_SendEntity(entity this, entity to, float sf)
6 {
7         vector myorg = this.origin + this.mins;
8         vector mysize = this.maxs - this.mins;
9         WriteHeader(MSG_ENTITY, ENT_CLIENT_RAINSNOW);
10         WriteByte(MSG_ENTITY, this.state);
11         WriteVector(MSG_ENTITY, myorg);
12         WriteVector(MSG_ENTITY, mysize);
13         WriteShort(MSG_ENTITY, compressShortVector(this.dest));
14         WriteShort(MSG_ENTITY, this.count);
15         WriteByte(MSG_ENTITY, this.cnt);
16         return true;
17 }
18
19 /*QUAKED spawnfunc_func_rain (0 .5 .8) ?
20 This is an invisible area like a trigger, which rain falls inside of.
21
22 Keys:
23 "velocity"
24  falling direction (should be something like '0 0 -700', use the X and Y velocity for wind)
25 "cnt"
26  sets color of rain (default 12 - white)
27 "count"
28  adjusts density, this many particles fall every second for a 1024x1024 area, default is 2000
29 */
30 spawnfunc(func_rain)
31 {
32         this.dest = this.velocity;
33         this.velocity = '0 0 0';
34         if (!this.dest)
35                 this.dest = '0 0 -700';
36         this.angles = '0 0 0';
37         set_movetype(this, MOVETYPE_NONE);
38         this.solid = SOLID_NOT;
39         SetBrushEntityModel(this);
40         if (!this.cnt)
41         {
42                 this.cnt = 12;
43         }
44         if (!this.count)
45                 this.count = 2000;
46         // relative to absolute particle count
47         //this.count = 0.1 * this.count * (this.size_x / 1024) * (this.size_y / 1024);
48         if (this.count < 1)
49                 this.count = 1;
50         if(this.count > 65535)
51                 this.count = 65535;
52
53         this.state = RAINSNOW_RAIN;
54
55         Net_LinkEntity(this, false, 0, rainsnow_SendEntity);
56 }
57
58
59 /*QUAKED spawnfunc_func_snow (0 .5 .8) ?
60 This is an invisible area like a trigger, which snow falls inside of.
61
62 Keys:
63 "velocity"
64  falling direction (should be something like '0 0 -300', use the X and Y velocity for wind)
65 "cnt"
66  sets color of rain (default 12 - white)
67 "count"
68  adjusts density, this many particles fall every second for a 1024x1024 area, default is 2000
69 */
70 spawnfunc(func_snow)
71 {
72         this.dest = this.velocity;
73         this.velocity = '0 0 0';
74         if (!this.dest)
75                 this.dest = '0 0 -300';
76         this.angles = '0 0 0';
77         set_movetype(this, MOVETYPE_NONE);
78         this.solid = SOLID_NOT;
79         SetBrushEntityModel(this);
80         if (!this.cnt)
81         {
82                 this.cnt = 12;
83         }
84         if (!this.count)
85                 this.count = 2000;
86         // relative to absolute particle count
87         //this.count = 0.1 * this.count * (this.size_x / 1024) * (this.size_y / 1024);
88         if (this.count < 1)
89                 this.count = 1;
90         if(this.count > 65535)
91                 this.count = 65535;
92
93         this.state = RAINSNOW_SNOW;
94
95         Net_LinkEntity(this, false, 0, rainsnow_SendEntity);
96 }
97 #elif defined(CSQC)
98 float autocvar_cl_rainsnow_maxdrawdist = 2048;
99
100 void Draw_Rain(entity this)
101 {
102         vector maxdist = '1 1 1' * autocvar_cl_rainsnow_maxdrawdist;
103
104         vector effbox_min = vec_to_max(view_origin - maxdist, this.origin + this.mins);
105         vector effbox_max = vec_to_min(view_origin + maxdist, this.origin + this.maxs);
106
107         vector mysize = effbox_min + effbox_max;
108         float mycount = bound(1, 0.1 * this.count * (mysize.x / 1024) * (mysize.y / 1024), 65535);
109         //LOG_INFO(ftos(mycount));
110
111         if(boxesoverlap(view_origin - maxdist, view_origin + maxdist, this.absmin, this.absmax)) // optimisation: don't render any rain if the player is outside the view distance
112         //if(autocvar_cl_rainsnow_maxdrawdist <= 0 || vdist(vec2(this.origin) - vec2(this.absmin + this.absmax * 0.5), <=, autocvar_cl_rainsnow_maxdrawdist))
113         te_particlerain(effbox_min, effbox_max, this.velocity, floor(mycount * drawframetime + random()), this.glow_color);
114 }
115
116 void Draw_Snow(entity this)
117 {
118         vector maxdist = '1 1 1' * autocvar_cl_rainsnow_maxdrawdist;
119
120         vector effbox_min = vec_to_max(view_origin - maxdist, this.origin + this.mins);
121         vector effbox_max = vec_to_min(view_origin + maxdist, this.origin + this.maxs);
122
123         vector mysize = effbox_min + effbox_max;
124         float mycount = bound(1, 0.1 * this.count * (mysize.x / 1024) * (mysize.y / 1024), 65535);
125         //LOG_INFO(ftos(mycount));
126
127         if(boxesoverlap(view_origin - maxdist, view_origin + maxdist, this.absmin, this.absmax))
128         //if(autocvar_cl_rainsnow_maxdrawdist <= 0 || vdist(vec2(this.origin) - vec2(this.absmin + this.absmax * 0.5), <=, autocvar_cl_rainsnow_maxdrawdist))
129         te_particlesnow(effbox_min, effbox_max, this.velocity, floor(mycount * drawframetime + random()), this.glow_color);
130 }
131
132 NET_HANDLE(ENT_CLIENT_RAINSNOW, bool isnew)
133 {
134         this.state = ReadByte(); // Rain, Snow, or Whatever
135         this.origin = ReadVector();
136         this.maxs = ReadVector();
137         this.velocity = decompressShortVector(ReadShort());
138         this.count = ReadShort();
139         this.glow_color = ReadByte(); // color
140
141         return = true;
142
143         this.mins    = -0.5 * this.maxs;
144         this.maxs    =  0.5 * this.maxs;
145         this.origin  = this.origin - this.mins;
146
147         setorigin(this, this.origin);
148         setsize(this, this.mins, this.maxs);
149         this.solid = SOLID_NOT;
150         if (isnew) IL_PUSH(g_drawables, this);
151         if(this.state == RAINSNOW_RAIN)
152                 this.draw = Draw_Rain;
153         else
154                 this.draw = Draw_Snow;
155 }
156 #endif