1 (* Copyright (C) DooM 2D:Forever Developers
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
38 MARK_BLOCKED
= MARK_WALL
+ MARK_DOOR
;
39 MARK_LIQUID
= MARK_WATER
+ MARK_ACID
;
40 MARK_LIFT
= MARK_LIFTDOWN
+ MARK_LIFTUP
+ MARK_LIFTLEFT
+ MARK_LIFTRIGHT
;
42 procedure g_GFX_Init();
43 procedure g_GFX_Free();
45 procedure g_GFX_Blood(fX
, fY
: Integer; Count
: Word; vx
, vy
: Integer;
46 DevX
, DevY
: Word; CR
, CG
, CB
: Byte; Kind
: Byte = BLOOD_NORMAL
);
47 procedure g_GFX_Spark(fX
, fY
: Integer; Count
: Word; Angle
: SmallInt; DevX
, DevY
: Byte);
48 procedure g_GFX_Water(fX
, fY
: Integer; Count
: Word; fVelX
, fVelY
: Single; DevX
, DevY
, Color
: Byte);
49 procedure g_GFX_SimpleWater(fX
, fY
: Integer; Count
: Word; fVelX
, fVelY
: Single; DefColor
, CR
, CG
, CB
: Byte);
50 procedure g_GFX_Bubbles(fX
, fY
: Integer; Count
: Word; DevX
, DevY
: Byte);
51 procedure g_GFX_SetMax(Count
: Integer);
52 function g_GFX_GetMax(): Integer;
54 procedure g_GFX_OnceAnim(X
, Y
: Integer; Anim
: TAnimation
; AnimType
: Byte = 0);
56 procedure g_Mark(x
, y
, Width
, Height
: Integer; t
: Byte; st
: Boolean);
58 procedure g_GFX_Update();
59 procedure g_GFX_Draw();
62 gCollideMap
: Array of Array of Byte;
67 g_map
, g_basic
, Math
, e_graphics
, GL
, GLExt
,
68 g_options
, g_console
, SysUtils
, g_triggers
, MAPDEF
,
69 g_game
, g_language
, g_net
;
75 AccelX
, AccelY
: Single;
76 Red
, Green
, Blue
: Byte;
81 offsetX
, offsetY
: ShortInt;
87 Animation
: TAnimation
;
100 Particles
: Array of TParticle
;
101 OnceAnims
: Array of TOnceAnim
;
102 MaxParticles
: Integer;
103 CurrentParticle
: Integer;
105 procedure g_Mark(x
, y
, Width
, Height
: Integer; t
: Byte; st
: Boolean);
107 yy
, y2
, xx
, x2
: Integer;
120 Height
:= Height
+ y
;
127 if x
> gMapInfo
.Width
then
129 if y
> gMapInfo
.Height
then
132 y2
:= y
+ Height
- 1;
133 if y2
> gMapInfo
.Height
then
134 y2
:= gMapInfo
.Height
;
137 if x2
> gMapInfo
.Width
then
138 x2
:= gMapInfo
.Width
;
141 begin // Óñòàíîâèòü ïðèçíàê
144 gCollideMap
[yy
][xx
] := gCollideMap
[yy
][xx
] or t
;
147 begin // Óáðàòü ïðèçíàê
151 gCollideMap
[yy
][xx
] := gCollideMap
[yy
][xx
] and t
;
155 procedure CreateCollideMap();
159 g_Game_SetLoadingText(_lc
[I_LOAD_COLLIDE_MAP
]+' 1/6', 0, False);
160 SetLength(gCollideMap
, gMapInfo
.Height
+1);
161 for a
:= 0 to High(gCollideMap
) do
162 SetLength(gCollideMap
[a
], gMapInfo
.Width
+1);
164 if gWater
<> nil then
166 g_Game_SetLoadingText(_lc
[I_LOAD_COLLIDE_MAP
]+' 2/6', 0, True);
167 for a
:= 0 to High(gWater
) do
169 g_Mark(X
, Y
, Width
, Height
, MARK_WATER
, True);
172 if gAcid1
<> nil then
174 g_Game_SetLoadingText(_lc
[I_LOAD_COLLIDE_MAP
]+' 3/6', 0, True);
175 for a
:= 0 to High(gAcid1
) do
177 g_Mark(X
, Y
, Width
, Height
, MARK_ACID
, True);
180 if gAcid2
<> nil then
182 g_Game_SetLoadingText(_lc
[I_LOAD_COLLIDE_MAP
]+' 4/6', 0, True);
183 for a
:= 0 to High(gAcid2
) do
185 g_Mark(X
, Y
, Width
, Height
, MARK_ACID
, True);
188 if gLifts
<> nil then
190 g_Game_SetLoadingText(_lc
[I_LOAD_COLLIDE_MAP
]+' 5/6', 0, True);
191 for a
:= 0 to High(gLifts
) do
194 g_Mark(X
, Y
, Width
, Height
, MARK_LIFT
, False);
197 g_Mark(X
, Y
, Width
, Height
, MARK_LIFTUP
, True)
198 else if LiftType
= 1 then
199 g_Mark(X
, Y
, Width
, Height
, MARK_LIFTDOWN
, True)
200 else if LiftType
= 2 then
201 g_Mark(X
, Y
, Width
, Height
, MARK_LIFTLEFT
, True)
202 else if LiftType
= 3 then
203 g_Mark(X
, Y
, Width
, Height
, MARK_LIFTRIGHT
, True)
207 if gWalls
<> nil then
209 g_Game_SetLoadingText(_lc
[I_LOAD_COLLIDE_MAP
]+' 6/6', 0, True);
210 for a
:= 0 to High(gWalls
) do
212 if gWalls
[a
].Door
then
215 if gWalls
[a
].Enabled
then
217 g_Mark(X
, Y
, Width
, Height
, MARK_DOOR
, True)
218 else // Îòêðûòàÿ äâåðü:
219 if gWalls
[a
].Enabled
then
221 g_Mark(X
, Y
, Width
, Height
, MARK_DOOR
, False);
225 g_Mark(X
, Y
, Width
, Height
, MARK_WALL
, True);
230 procedure g_GFX_Init();
235 procedure g_GFX_Free();
240 SetLength(Particles
, MaxParticles
);
241 CurrentParticle
:= 0;
243 if OnceAnims
<> nil then
245 for a
:= 0 to High(OnceAnims
) do
246 OnceAnims
[a
].Animation
.Free();
254 procedure CorrectOffsets(id
: Integer);
256 with Particles
[id
] do
258 if (X
>= 0) and (Y
> 0) and
259 (Y
< Length(gCollideMap
)) and (X
< Length(gCollideMap
[0])) and
260 (ByteBool(gCollideMap
[Y
-1, X
] and MARK_BLOCKED
)) then
261 offsetY
:= 1 // Ñòåíà ñâåðõó
265 if (X
> 0) and (Y
>= 0) and
266 (Y
< Length(gCollideMap
)) and (X
< Length(gCollideMap
[0])) and
267 (ByteBool(gCollideMap
[Y
, X
-1] and MARK_BLOCKED
)) then
268 offsetX
:= 1 // Ñòåíà ñëåâà
274 procedure g_GFX_SparkVel(fX
, fY
: Integer; Count
: Word; VX
, VY
: Integer; DevX
, DevY
: Byte);
281 l
:= Length(Particles
);
292 for a
:= 1 to Count
do
294 with Particles
[CurrentParticle
] do
296 X
:= fX
-DevX1
+Random(DevX2
);
297 Y
:= fY
-DevY1
+Random(DevY2
);
299 VelX
:= VX
+ (Random
-Random
)*3;
300 VelY
:= VY
+ (Random
-Random
)*3;
308 AccelX
:= -Sign(VelX
)*Random
/100;
312 Green
:= 100+Random(155);
316 State
:= STATE_NORMAL
;
318 LiveTime
:= 30+Random(60);
319 ParticleType
:= PARTICLE_SPARK
;
321 CorrectOffsets(CurrentParticle
);
324 if CurrentParticle
+2 > MaxParticles
then
327 CurrentParticle
:= CurrentParticle
+1;
331 procedure g_GFX_Blood(fX
, fY
: Integer; Count
: Word; vx
, vy
: Integer;
332 DevX
, DevY
: Word; CR
, CG
, CB
: Byte; Kind
: Byte = BLOOD_NORMAL
);
341 if Kind
= BLOOD_SPARKS
then
343 g_GFX_SparkVel(fX
, fY
, 2 + Random(2), -VX
div 2, -VY
div 2, DevX
, DevY
);
346 l
:= Length(Particles
);
357 for a
:= 1 to Count
do
359 with Particles
[CurrentParticle
] do
361 X
:= fX
- DevX1
+ Random(DevX2
);
362 Y
:= fY
- DevY1
+ Random(DevY2
);
364 if (X
< 0) or (X
> gMapInfo
.Width
-1) or
365 (Y
< 0) or (Y
> gMapInfo
.Height
-1) or
366 ByteBool(gCollideMap
[Y
, X
] and MARK_WALL
) then
369 VelX
:= vx
+ (Random
-Random
)*3;
370 VelY
:= vy
+ (Random
-Random
)*3;
378 AccelX
:= -Sign(VelX
)*Random
/100;
381 CRnd
:= 20*Random(6);
384 CC
:= CR
+ CRnd
- 50;
385 if CC
< 0 then CC
:= 0;
386 if CC
> 255 then CC
:= 255;
392 CC
:= CG
+ CRnd
- 50;
393 if CC
< 0 then CC
:= 0;
394 if CC
> 255 then CC
:= 255;
400 CC
:= CB
+ CRnd
- 50;
401 if CC
< 0 then CC
:= 0;
402 if CC
> 255 then CC
:= 255;
409 State
:= STATE_NORMAL
;
411 LiveTime
:= 120+Random(40);
412 ParticleType
:= PARTICLE_BLOOD
;
414 CorrectOffsets(CurrentParticle
);
417 if CurrentParticle
>= MaxParticles
-1 then
420 CurrentParticle
:= CurrentParticle
+1;
424 procedure g_GFX_Spark(fX
, fY
: Integer; Count
: Word; Angle
: SmallInt; DevX
, DevY
: Byte);
430 BaseVelX
, BaseVelY
: Single;
433 l
:= Length(Particles
);
439 Angle
:= 360 - Angle
;
446 b
:= DegToRad(Angle
);
448 BaseVelY
:= 1.6*sin(b
);
449 if Abs(BaseVelX
) < 0.01 then
451 if Abs(BaseVelY
) < 0.01 then
453 for a
:= 1 to Count
do
455 with Particles
[CurrentParticle
] do
457 X
:= fX
-DevX1
+Random(DevX2
);
458 Y
:= fY
-DevY1
+Random(DevY2
);
460 VelX
:= BaseVelX
*Random
;
461 VelY
:= BaseVelY
-Random
;
466 Green
:= 100+Random(155);
470 State
:= STATE_NORMAL
;
472 LiveTime
:= 30+Random(60);
473 ParticleType
:= PARTICLE_SPARK
;
475 CorrectOffsets(CurrentParticle
);
478 if CurrentParticle
+2 > MaxParticles
then
481 CurrentParticle
:= CurrentParticle
+1;
485 procedure g_GFX_Water(fX
, fY
: Integer; Count
: Word; fVelX
, fVelY
: Single; DevX
, DevY
, Color
: Byte);
492 l
:= Length(Particles
);
498 if Abs(fVelX
) < 3.0 then
499 fVelX
:= 3.0 - 6.0*Random
;
506 for a
:= 1 to Count
do
508 with Particles
[CurrentParticle
] do
510 X
:= fX
-DevX1
+Random(DevX2
);
511 Y
:= fY
-DevY1
+Random(DevY2
);
513 if Abs(fVelX
) < 0.5 then
514 VelX
:= 1.0 - 2.0*Random
516 VelX
:= fVelX
*Random
;
517 if Random(10) < 7 then
519 VelY
:= fVelY
*Random
;
526 Red
:= 155 + Random(9)*10;
527 Green
:= Trunc(150*Random
);
532 Red
:= Trunc(150*Random
);
533 Green
:= 175 + Random(9)*10;
538 Red
:= Trunc(200*Random
);
540 Blue
:= 175 + Random(9)*10;
544 Red
:= 90 + Random(12)*10;
552 State
:= STATE_NORMAL
;
554 LiveTime
:= 60+Random(60);
555 ParticleType
:= PARTICLE_WATER
;
557 CorrectOffsets(CurrentParticle
);
560 if CurrentParticle
+2 > MaxParticles
then
563 CurrentParticle
:= CurrentParticle
+1;
567 procedure g_GFX_SimpleWater(fX
, fY
: Integer; Count
: Word; fVelX
, fVelY
: Single; DefColor
, CR
, CG
, CB
: Byte);
572 l
:= Length(Particles
);
578 for a
:= 1 to Count
do
580 with Particles
[CurrentParticle
] do
593 Red
:= 155 + Random(9)*10;
594 Green
:= Trunc(150*Random
);
599 Red
:= Trunc(150*Random
);
600 Green
:= 175 + Random(9)*10;
605 Red
:= Trunc(200*Random
);
607 Blue
:= 175 + Random(9)*10;
609 4: // Ñâîé öâåò, ñâåòëåå
611 Red
:= 20 + Random(19)*10;
614 Red
:= Min(Red
+ CR
, 255);
615 Green
:= Min(Green
+ CG
, 255);
616 Blue
:= Min(Blue
+ CB
, 255);
618 5: // Ñâîé öâåò, òåìíåå
620 Red
:= 20 + Random(19)*10;
623 Red
:= Max(CR
- Red
, 0);
624 Green
:= Max(CG
- Green
, 0);
625 Blue
:= Max(CB
- Blue
, 0);
629 Red
:= 90 + Random(12)*10;
637 State
:= STATE_NORMAL
;
639 LiveTime
:= 60+Random(60);
640 ParticleType
:= PARTICLE_WATER
;
642 CorrectOffsets(CurrentParticle
);
645 if CurrentParticle
+2 > MaxParticles
then
648 CurrentParticle
:= CurrentParticle
+1;
652 procedure g_GFX_Bubbles(fX
, fY
: Integer; Count
: Word; DevX
, DevY
: Byte);
659 l
:= Length(Particles
);
670 for a
:= 1 to Count
do
672 with Particles
[CurrentParticle
] do
674 X
:= fX
-DevX1
+Random(DevX2
);
675 Y
:= fY
-DevY1
+Random(DevY2
);
677 if (X
>= gMapInfo
.Width
) or (X
<= 0) or
678 (Y
>= gMapInfo
.Height
) or (Y
<= 0) then
681 if not ByteBool(gCollideMap
[Y
, X
] and MARK_LIQUID
) then
694 State
:= STATE_NORMAL
;
697 ParticleType
:= PARTICLE_BUBBLES
;
699 CorrectOffsets(CurrentParticle
);
702 if CurrentParticle
+2 > MaxParticles
then
705 CurrentParticle
:= CurrentParticle
+1;
709 procedure g_GFX_SetMax(Count
: Integer);
711 if Count
> 50000 then
714 SetLength(Particles
, Count
);
715 MaxParticles
:= Count
;
716 if CurrentParticle
>= Count
then
717 CurrentParticle
:= 0;
720 function g_GFX_GetMax(): Integer;
722 Result
:= MaxParticles
;
725 function FindOnceAnim
: DWORD
;
729 if OnceAnims
<> nil then
730 for i
:= 0 to High(OnceAnims
) do
731 if OnceAnims
[i
].Animation
= nil then
737 if OnceAnims
= nil then
739 SetLength(OnceAnims
, 16);
744 Result
:= High(OnceAnims
) + 1;
745 SetLength(OnceAnims
, Length(OnceAnims
) + 16);
749 procedure g_GFX_OnceAnim(X
, Y
: Integer; Anim
: TAnimation
; AnimType
: Byte = 0);
756 find_id
:= FindOnceAnim();
758 OnceAnims
[find_id
].AnimType
:= AnimType
;
759 OnceAnims
[find_id
].Animation
:= TAnimation
.Create(Anim
.FramesID
, Anim
.Loop
, Anim
.Speed
);
760 OnceAnims
[find_id
].Animation
.Blending
:= Anim
.Blending
;
761 OnceAnims
[find_id
].Animation
.Alpha
:= Anim
.Alpha
;
762 OnceAnims
[find_id
].X
:= X
;
763 OnceAnims
[find_id
].Y
:= Y
;
766 procedure g_GFX_Update();
775 if Particles
<> nil then
778 h
:= gMapInfo
.Height
;
780 len
:= High(Particles
);
783 if Particles
[a
].State
<> 0 then
786 if Time
= LiveTime
then
788 if (X
+1 >= w
) or (Y
+1 >= h
) or (X
<= 0) or (Y
<= 0) then
790 if State
= STATE_FREE
then
798 if (State
= STATE_STICK
) then
799 if (not ByteBool(gCollideMap
[Y
-1, X
] and MARK_BLOCKED
)) and
800 (not ByteBool(gCollideMap
[Y
+1, X
] and MARK_BLOCKED
)) and
801 (not ByteBool(gCollideMap
[Y
, X
-1] and MARK_BLOCKED
)) and
802 (not ByteBool(gCollideMap
[Y
, X
+1] and MARK_BLOCKED
)) then
803 begin // Îòëèïëà - êàïàåò
806 State
:= STATE_NORMAL
;
809 if Random(200) = 100 then
810 begin // Ïðèëåïëåíà - íî âîçìîæíî ñòåêàåò
816 if not ByteBool(gCollideMap
[Y
, X
] and MARK_BLOCKED
) then
818 if ByteBool(gCollideMap
[Y
, X
] and MARK_LIFTUP
) then
820 if VelY
> -4-Random(3) then
822 if Abs(VelX
) > 0.1 then
823 VelX
:= VelX
- VelX
/10.0;
824 VelX
:= VelX
+ (Random
-Random
)*0.2;
827 if ByteBool(gCollideMap
[Y
, X
] and MARK_LIFTLEFT
) then
829 if VelX
> -8-Random(3) then
833 if ByteBool(gCollideMap
[Y
, X
] and MARK_LIFTRIGHT
) then
834 begin // Ïîòîê âïðàâî
835 if VelX
< 8+Random(3) then
844 if (Abs(VelX
) < 0.1) and (Abs(VelY
) < 0.1) then
845 if (State
<> STATE_STICK
) and
846 (not ByteBool(gCollideMap
[Y
-1, X
] and MARK_BLOCKED
)) and
847 (not ByteBool(gCollideMap
[Y
, X
] and MARK_BLOCKED
)) and
848 (not ByteBool(gCollideMap
[Y
+1, X
] and MARK_BLOCKED
)) then
849 begin // Âèñèò â âîçäóõå - êàïàåò
852 State
:= STATE_NORMAL
;
866 if (X
+s
>= w
) or (X
+s
<= 0) then
872 c
:= gCollideMap
[Y
, X
+s
];
874 if ByteBool(c
and MARK_BLOCKED
) then
880 State
:= STATE_STICK
;
899 if (Y
+s
>= h
) or (Y
+s
<= 0) then
905 c
:= gCollideMap
[Y
+s
, X
];
907 if ByteBool(c
and MARK_BLOCKED
) then
913 if (s
> 0) and (State
<> STATE_STICK
) then
914 State
:= STATE_NORMAL
916 State
:= STATE_STICK
;
929 if (X
+dX
>= w
) or (Y
+dY
>= h
) or
930 (X
+dX
<= 0) or (Y
+dY
<= 0) or
931 ByteBool(gCollideMap
[Y
+dY
, X
+dX
] and MARK_BLOCKED
) then
932 begin // Ñòåíà/äâåðü/ãðàíèöà
944 VelX
:= VelX
+ AccelX
;
945 VelY
:= VelY
+ AccelY
;
947 // Êðîâü ðàñòâîðÿåòñÿ â æèäêîñòè:
948 if ByteBool(gCollideMap
[Y
, X
] and MARK_LIQUID
) then
952 Alpha
:= 255 - Trunc((255.0 * Time
) / LiveTime
);
961 if (Abs(VelX
) < 0.1) and (Abs(VelY
) < 0.1) and
962 (not ByteBool(gCollideMap
[Y
-1, X
] and MARK_BLOCKED
)) and
963 (not ByteBool(gCollideMap
[Y
, X
] and MARK_BLOCKED
)) and
964 (not ByteBool(gCollideMap
[Y
+1, X
] and MARK_BLOCKED
)) then
965 begin // Âèñèò â âîçäóõå
981 if (X
+s
>= w
) or (X
+s
<= 0) then
987 c
:= gCollideMap
[Y
, X
+s
];
989 if ByteBool(c
and MARK_BLOCKED
) then
990 begin // Ñòåíà/äâåðü - ïàäàåò âåðòèêàëüíî
996 if c
= MARK_FREE
then
1000 State
:= STATE_FREE
;
1017 if (Y
+s
>= h
) or (Y
+s
<= 0) then
1019 State
:= STATE_FREE
;
1023 c
:= gCollideMap
[Y
+s
, X
];
1025 if ByteBool(c
and MARK_BLOCKED
) then
1026 begin // Ñòåíà/äâåðü - ïàäàåò âåðòèêàëüíî
1030 AccelY
:= Abs(AccelY
);
1032 else // Èëè íå ïàäàåò
1043 if c
= MARK_FREE
then
1047 State
:= STATE_FREE
;
1054 VelX
:= VelX
+ AccelX
;
1058 AccelY
:= AccelY
+ 0.08;
1059 VelY
:= VelY
+ AccelY
;
1067 if (State
= STATE_STICK
) and (Random(30) = 15) then
1068 begin // Ñòåêàåò/îòëèïàåò
1071 if (not ByteBool(gCollideMap
[Y
, X
-1] and MARK_BLOCKED
)) and
1072 (not ByteBool(gCollideMap
[Y
, X
+1] and MARK_BLOCKED
)) then
1073 State
:= STATE_NORMAL
;
1077 if not ByteBool(gCollideMap
[Y
, X
] and MARK_BLOCKED
) then
1079 if ByteBool(gCollideMap
[Y
, X
] and MARK_LIFTUP
) then
1081 if VelY
> -4-Random(3) then
1083 if Abs(VelX
) > 0.1 then
1084 VelX
:= VelX
- VelX
/10.0;
1085 VelX
:= VelX
+ (Random
-Random
)*0.2;
1088 if ByteBool(gCollideMap
[Y
, X
] and MARK_LIFTLEFT
) then
1089 begin // Ïîòîê âëåâî
1090 if VelX
> -8-Random(3) then
1094 if ByteBool(gCollideMap
[Y
, X
] and MARK_LIFTRIGHT
) then
1095 begin // Ïîòîê âïðàâî
1096 if VelX
< 8+Random(3) then
1105 if (Abs(VelX
) < 0.1) and (Abs(VelY
) < 0.1) then
1106 if (State
<> STATE_STICK
) and
1107 (not ByteBool(gCollideMap
[Y
-1, X
] and MARK_BLOCKED
)) and
1108 (not ByteBool(gCollideMap
[Y
, X
] and MARK_BLOCKED
)) and
1109 (not ByteBool(gCollideMap
[Y
+1, X
] and MARK_BLOCKED
)) then
1110 begin // Âèñèò â âîçäóõå - êàïàåò
1113 State
:= STATE_NORMAL
;
1123 for b
:= 1 to Abs(dX
) do
1125 if (X
+s
>= w
) or (X
+s
<= 0) then
1126 begin // Ñáîêó ãðàíèöà
1127 State
:= STATE_FREE
;
1131 c
:= gCollideMap
[Y
, X
+s
];
1133 if ByteBool(c
and MARK_LIQUID
) and (dY
> 0) then
1134 begin // Ñáîêó æèäêîñòü, à ÷àñòèöà óæå ïàäàåò
1135 State
:= STATE_FREE
;
1139 if ByteBool(c
and MARK_BLOCKED
) then
1140 begin // Ñòåíà/äâåðü
1145 State
:= STATE_STICK
;
1160 for b
:= 1 to Abs(dY
) do
1162 if (Y
+s
>= h
) or (Y
+s
<= 0) then
1163 begin // Ñíèçó/ñâåðõó ãðàíèöà
1164 State
:= STATE_FREE
;
1168 c
:= gCollideMap
[Y
+s
, X
];
1170 if ByteBool(c
and MARK_LIQUID
) and (dY
> 0) then
1171 begin // Ñíèçó æèäêîñòü, à ÷àñòèöà óæå ïàäàåò
1172 State
:= STATE_FREE
;
1176 if ByteBool(c
and MARK_BLOCKED
) then
1177 begin // Ñòåíà/äâåðü
1182 if (s
> 0) and (State
<> STATE_STICK
) then
1183 State
:= STATE_NORMAL
1185 State
:= STATE_STICK
;
1193 VelX
:= VelX
+ AccelX
;
1194 VelY
:= VelY
+ AccelY
;
1210 for b
:= 1 to Abs(dY
) do
1212 if (Y
+s
>= h
) or (Y
+s
<= 0) then
1214 State
:= STATE_FREE
;
1218 if not ByteBool(gCollideMap
[Y
+s
, X
] and MARK_LIQUID
) then
1219 begin // Óæå íå æèäêîñòü
1220 State
:= STATE_FREE
;
1229 VelY
:= VelY
+ AccelY
;
1237 end; // Particles <> nil
1239 if OnceAnims
<> nil then
1241 for a
:= 0 to High(OnceAnims
) do
1242 if OnceAnims
[a
].Animation
<> nil then
1244 case OnceAnims
[a
].AnimType
of
1247 if Random(3) = 0 then
1248 OnceAnims
[a
].X
:= OnceAnims
[a
].X
-1+Random(3);
1249 if Random(2) = 0 then
1250 OnceAnims
[a
].Y
:= OnceAnims
[a
].Y
-Random(2);
1254 if OnceAnims
[a
].Animation
.Played
then
1256 OnceAnims
[a
].Animation
.Free();
1257 OnceAnims
[a
].Animation
:= nil;
1260 OnceAnims
[a
].Animation
.Update();
1265 procedure g_GFX_Draw();
1269 if Particles
<> nil then
1271 glDisable(GL_TEXTURE_2D
);
1275 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
1279 len
:= High(Particles
);
1281 for a
:= 0 to len
do
1282 with Particles
[a
] do
1283 if (State
<> STATE_FREE
) and (X
>= sX
) and (Y
>= sY
) and
1284 (X
<= sX
+sWidth
) and (sY
<= sY
+sHeight
) then
1286 glColor4ub(Red
, Green
, Blue
, Alpha
);
1287 glVertex2i(X
+ offsetX
, Y
+ offsetY
);
1292 glDisable(GL_BLEND
);
1295 if OnceAnims
<> nil then
1296 for a
:= 0 to High(OnceAnims
) do
1297 if OnceAnims
[a
].Animation
<> nil then
1298 with OnceAnims
[a
] do
1299 Animation
.Draw(X
, Y
, M_NONE
);