3 * Iter Vehemens ad Necem (IVAN)
4 * Copyright (C) Timo Kiviluoto
5 * Released under the GNU General
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);
29 void rain::Draw(blitdata
& BlitData
) const
31 sLong Volume
= Liquid
->GetVolume();
32 int Drops
= this->Drops
;
37 int c
, DropMax
= Volume
? Limit
<int>(Volume
/ 50, 1, MAX_RAIN_DROPS
) : 0;
42 Drop
= new drop
[DropMax
];
44 for(c
= 0; c
< Drops
; ++c
)
52 for(; Drops
< DropMax
; ++Drops
)
53 RandomizeDropPos(Drops
);
57 for(c
= 0; c
< DropMax
; ++c
)
61 for(; Drops
> DropMax
&& !Drop
[Drops
- 1].MaxAge
; --Drops
);
72 col16 Color
= Liquid
->GetRainColor();
74 for(c
= 0; c
< Drops
; ++c
)
77 feuLong Age
= uShort(GET_TICK()) - Drop
[c
].StartTick
;
79 if(Age
> Drop
[c
].MaxAge
)
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)
93 BlitData
.Bitmap
->AlphaPutPixel(DropPos
+ BlitData
.Dest
, Color
, BlitData
.Luminance
, 255);
99 void rain::RandomizeDropPos(int I
) const
101 Drop
[I
].StartTick
= GET_TICK() - (RAND() & 3);
104 if(Speed
.X
&& (!Speed
.Y
|| RAND() & 1))
106 Pos
.X
= Speed
.X
> 0 ? 0 : 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;
122 if (++BeCounter
< 50) return;
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);
131 LSquareUnder
->SpillFluid(Team
== PLAYER_TEAM
? PLAYER
: 0, Liquid
->SpawnMoreLiquid(DropVolume
), true, OwnLiquid
);
133 if (Volume
== DropVolume
) {
134 LSquareUnder
->RemoveRain(this);
137 Liquid
->EditVolume(-DropVolume
);
144 void rain::Save(outputfile
& SaveFile
) const
146 SaveFile
<< Liquid
<< Speed
<< (uChar
)Team
;
149 void rain::Load(inputfile
& SaveFile
)
152 LSquareUnder
= static_cast<lsquare
*>(game::GetSquareInLoad());
153 Liquid
= static_cast<liquid
*>(ReadType(material
*, SaveFile
));
154 Liquid
->SetMotherEntity(this);
155 Emitation
= Liquid
->GetEmitation();
157 Team
= ReadType(uChar
, SaveFile
);
158 SpeedAbs
= sLong(sqrt(Speed
.GetLengthSquare()));
161 outputfile
& operator<<(outputfile
& SaveFile
, const rain
* Rain
)
163 if(Rain
->HasOwnLiquid())
166 Rain
->Save(SaveFile
);
174 inputfile
& operator>>(inputfile
& SaveFile
, rain
*& Rain
)
179 Rain
->Load(SaveFile
);
182 Rain
= game::ConstructGlobalRain();