script, ui: added "sv_min_startmap_health" cvar
[k8vavoom.git] / progs / common / linespec / LightningThinker.vc
blob807ff6011cbc9de87cfb3fbaa09f7ed852be7889
1 //**************************************************************************
2 //**
3 //**    ##   ##    ##    ##   ##   ####     ####   ###     ###
4 //**    ##   ##  ##  ##  ##   ##  ##  ##   ##  ##  ####   ####
5 //**     ## ##  ##    ##  ## ##  ##    ## ##    ## ## ## ## ##
6 //**     ## ##  ########  ## ##  ##    ## ##    ## ##  ###  ##
7 //**      ###   ##    ##   ###    ##  ##   ##  ##  ##       ##
8 //**       #    ##    ##    #      ####     ####   ##       ##
9 //**
10 //**  Copyright (C) 1999-2006 Jānis Legzdiņš
11 //**  Copyright (C) 2018-2023 Ketmar Dark
12 //**
13 //**  This program is free software: you can redistribute it and/or modify
14 //**  it under the terms of the GNU General Public License as published by
15 //**  the Free Software Foundation, version 3 of the License ONLY.
16 //**
17 //**  This program is distributed in the hope that it will be useful,
18 //**  but WITHOUT ANY WARRANTY; without even the implied warranty of
19 //**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 //**  GNU General Public License for more details.
21 //**
22 //**  You should have received a copy of the GNU General Public License
23 //**  along with this program.  If not, see <http://www.gnu.org/licenses/>.
24 //**
25 //**************************************************************************
26 class LightningThinker : Actor;
28 int Sky1Texture;
29 int Sky2Texture;
30 float NextLightningFlash;
31 float LightningFlash;
32 array!int LightningLightLevels;
33 array!ubyte LightningSectors;
34 bool bStopping;
37 //==========================================================================
39 //  Init
41 //==========================================================================
42 void Init () {
43   // check if the level is a lightning level
44   Sky1Texture = Level.Sky1Texture;
45   Sky2Texture = Level.Sky2Texture;
46   LightningFlash = 0.0;
47   LightningLightLevels.length = XLevel.Sectors.length;
48   LightningSectors.length = (XLevel.Sectors.length+7)/8;
49   NextLightningFlash = Random()*15.0+5.0; // don't flash at level start
53 //==========================================================================
55 //  Tick
57 //==========================================================================
58 override void Tick (float DeltaTime) {
59   // update lightning
60   if (!NextLightningFlash || LightningFlash) {
61     DoLightningFlash(DeltaTime);
62   } else {
63     NextLightningFlash -= DeltaTime;
64     if (NextLightningFlash < 0.0) NextLightningFlash = 0.0;
65     if (bStopping) Destroy();
66   }
70 //==========================================================================
72 //  DoLightningFlash
74 //==========================================================================
75 void DoLightningFlash (float DeltaTime) {
76   sector_t *tempSec;
77   bool foundSec;
78   int flashLight;
80   if (LightningFlash) {
81     LightningFlash -= DeltaTime;
82     if (LightningFlash > 0.0) {
83       foreach (auto i; 0..XLevel.Sectors.length) {
84         tempSec = cast([unsafe])(&XLevel.Sectors[i]);
85         if (LightningSectors[i/8]&(1<<(i&7))) {
86           if (LightningLightLevels[i] < tempSec->params.lightlevel-4) {
87             tempSec->params.lightlevel -= 4;
88           }
89         }
90       }
91     } else {
92       // remove the alternate lightning flash special
93       LightningFlash = 0.0;
94       foreach (auto i; 0..XLevel.Sectors.length) {
95         tempSec = cast([unsafe])(&XLevel.Sectors[i]);
96         if (LightningSectors[i/8]&(1<<(i&7))) {
97           tempSec->params.lightlevel = LightningLightLevels[i];
98         }
99       }
100       Level.Sky1Texture = Sky1Texture;
101     }
102     return;
103   }
105   LightningFlash = Random()*0.25+0.25;
106   flashLight = 200+(P_Random()&31);
107   foundSec = false;
108   for (int i = (XLevel.Sectors.length+7)/8-1; i >= 0; --i) LightningSectors[i] = 0;
109   foreach (auto i; 0..XLevel.Sectors.length) {
110     tempSec = cast([unsafe])(&XLevel.Sectors[i]);
111     int Spec = tempSec->special&SECSPEC_BASE_MASK;
112     if (tempSec->ceiling.pic == Level.Game.skyflatnum ||
113         Spec == SECSPEC_LightningOutdoor ||
114         Spec == SECSPEC_LightningIndoor1 ||
115         Spec == SECSPEC_Lightningindoor2)
116     {
117       LightningLightLevels[i] = tempSec->params.lightlevel;
118       LightningSectors[i/8] |= 1<<(i&7);
119       if (tempSec->special == SECSPEC_LightningIndoor1) {
120         tempSec->params.lightlevel += 64;
121         if (tempSec->params.lightlevel > flashLight) {
122           tempSec->params.lightlevel = flashLight;
123         }
124       } else if (tempSec->special == SECSPEC_Lightningindoor2) {
125         tempSec->params.lightlevel += 32;
126         if (tempSec->params.lightlevel > flashLight) {
127           tempSec->params.lightlevel = flashLight;
128         }
129       } else {
130         tempSec->params.lightlevel = flashLight;
131       }
132       if (tempSec->params.lightlevel < LightningLightLevels[i]) {
133         tempSec->params.lightlevel = LightningLightLevels[i];
134       }
135       foundSec = true;
136     }
137   }
139   if (foundSec) {
140     Level.Sky1Texture = Sky2Texture; // set alternate sky
141     PlaySound('world/thunder', CHAN_VOICE, 1.0, ATTN_NONE);
142     XLevel.StartTypedACScripts(VLevel::SCRIPT_Lightning, 0, 0, 0, Activator:none, Always:false, RunNow:false);
143   }
145   // calculate the next lighting flash
146   if (!NextLightningFlash) {
147     if (P_Random() < 50) {
148       // immediate quick flash
149       NextLightningFlash = (Random()*0.5)+0.5;
150     } else {
151       if (Random() < 0.5 && !(XLevel.TicTime&32)) {
152         NextLightningFlash = Random()*8.0+2.0;
153       } else {
154         NextLightningFlash = Random()*16.0+5.0;
155       }
156     }
157   }
161 //==========================================================================
163 //  ForceLightning
165 //==========================================================================
166 void ForceLightning (int Mode) {
167   switch (Mode) {
168     case 1:
169       NextLightningFlash = 0.0;
170       bStopping = true;
171       break;
172     case 2:
173       bStopping = true;
174       break;
175     default:
176       NextLightningFlash = 0.0;
177       break;
178   }
182 defaultproperties {
183   bNoSector = true;
184   bNoBlockmap = true;
185   bNoSplash = true;
186   bAlwaysTick = true;