moved almost all hardcoded constants to "define.dat"
[k8-i-v-a-n.git] / src / game / rain.cpp
blob316defa7b838578b879045bc7905ea100910dbbc
1 /*
3 * Iter Vehemens ad Necem (IVAN)
4 * Copyright (C) Timo Kiviluoto
5 * Released under the GNU General
6 * Public License
8 * See LICENSING which should be included
9 * along with this file for more details
13 /* Compiled through materset.cpp */
15 rain::rain(liquid* Liquid, lsquare* LSquareUnder, v2 Speed, int Team, truth OwnLiquid) : entity(OwnLiquid ? HAS_BE : 0), Next(0), Drop(0), Liquid(Liquid), LSquareUnder(LSquareUnder), Speed(Speed), SpeedAbs(sLong(sqrt(Speed.GetLengthSquare()))), Drops(0), OwnLiquid(OwnLiquid), Team(Team)
17 Emitation = Liquid->GetEmitation();
18 BeCounter = RAND_N(50);
21 rain::~rain()
23 delete [] Drop;
25 if(OwnLiquid)
26 delete Liquid;
29 void rain::Draw(blitdata& BlitData) const
31 sLong Volume = Liquid->GetVolume();
32 int Drops = this->Drops;
34 if(!Volume && !Drops)
35 return;
37 int c, DropMax = Volume ? Limit<int>(Volume / 50, 1, MAX_RAIN_DROPS) : 0;
39 if(Drops < DropMax)
41 drop* OldDrop = Drop;
42 Drop = new drop[DropMax];
44 for(c = 0; c < Drops; ++c)
45 if(OldDrop[c].MaxAge)
46 Drop[c] = OldDrop[c];
47 else
48 RandomizeDropPos(c);
50 delete [] OldDrop;
52 for(; Drops < DropMax; ++Drops)
53 RandomizeDropPos(Drops);
55 else
57 for(c = 0; c < DropMax; ++c)
58 if(!Drop[c].MaxAge)
59 RandomizeDropPos(c);
61 for(; Drops > DropMax && !Drop[Drops - 1].MaxAge; --Drops);
63 if(!Drops)
65 this->Drops = 0;
66 delete [] Drop;
67 Drop = 0;
68 return;
72 col16 Color = Liquid->GetRainColor();
74 for(c = 0; c < Drops; ++c)
75 if(Drop[c].MaxAge)
77 feuLong Age = uShort(GET_TICK()) - Drop[c].StartTick;
79 if(Age > Drop[c].MaxAge)
81 Drop[c].MaxAge = 0;
82 continue;
85 v2 DropPos = v2(Drop[c].StartPos) + (Speed * int(Age) >> 8);
87 if(DropPos.X < 0 || DropPos.Y < 0 || DropPos.X >= 16 || DropPos.Y >= 16)
89 Drop[c].MaxAge = 0;
90 continue;
93 BlitData.Bitmap->AlphaPutPixel(DropPos + BlitData.Dest, Color, BlitData.Luminance, 255);
96 this->Drops = Drops;
99 void rain::RandomizeDropPos(int I) const
101 Drop[I].StartTick = GET_TICK() - (RAND() & 3);
102 v2 Pos;
104 if(Speed.X && (!Speed.Y || RAND() & 1))
106 Pos.X = Speed.X > 0 ? 0 : 15;
107 Pos.Y = RAND() & 15;
109 else
111 Pos.X = RAND() & 15;
112 Pos.Y = Speed.Y > 0 ? 0 : 15;
115 Drop[I].StartPos = Pos;
116 int AgeModifier = 5000 / SpeedAbs;
117 Drop[I].MaxAge = AgeModifier > 1 ? 1 + RAND() % AgeModifier : 1;
121 void rain::Be () {
122 if (++BeCounter < 50) return;
123 BeCounter = 0;
124 sLong Volume = Liquid->GetVolume();
125 if (Volume && !Liquid->IsPowder()) { // gum
126 sLong Rand = 5000000/(Volume*SpeedAbs);
127 if (OwnLiquid) Rand >>= 3;
128 if (Rand < 1 || !(RAND() % Rand)) {
129 sLong DropVolume = Min(Volume, 50);
130 /* Gum */
131 LSquareUnder->SpillFluid(Team == PLAYER_TEAM ? PLAYER : 0, Liquid->SpawnMoreLiquid(DropVolume), true, OwnLiquid);
132 if (OwnLiquid) {
133 if (Volume == DropVolume) {
134 LSquareUnder->RemoveRain(this);
135 SendToHell();
136 } else {
137 Liquid->EditVolume(-DropVolume);
144 void rain::Save(outputfile& SaveFile) const
146 SaveFile << Liquid << Speed << (uChar)Team;
149 void rain::Load(inputfile& SaveFile)
151 OwnLiquid = 1;
152 LSquareUnder = static_cast<lsquare *>(game::GetSquareInLoad());
153 Liquid = static_cast<liquid *>(ReadType(material *, SaveFile));
154 Liquid->SetMotherEntity(this);
155 Emitation = Liquid->GetEmitation();
156 SaveFile >> Speed;
157 Team = ReadType(uChar, SaveFile);
158 SpeedAbs = sLong(sqrt(Speed.GetLengthSquare()));
161 outputfile& operator<<(outputfile& SaveFile, const rain* Rain)
163 if(Rain->HasOwnLiquid())
165 SaveFile.Put(true);
166 Rain->Save(SaveFile);
168 else
169 SaveFile.Put(false);
171 return SaveFile;
174 inputfile& operator>>(inputfile& SaveFile, rain*& Rain)
176 if(SaveFile.Get())
178 Rain = new rain;
179 Rain->Load(SaveFile);
181 else
182 Rain = game::ConstructGlobalRain();
184 return SaveFile;