e74ddcc9068093eaf900b17ff7fed59c53d083d8
1 (* Copyright (C) DooM 2D:Forever Developers
2 *
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.
7 *
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.
12 *
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/>.
15 *)
16 {$INCLUDE ../shared/a_modes.inc}
17 {$DEFINE D2F_NEW_SPARK_THINKER}
20 interface
22 uses
25 const
49 procedure g_GFX_Water(fX, fY: Integer; Count: Word; fVelX, fVelY: Single; DevX, DevY, Color: Byte);
50 procedure g_GFX_SimpleWater(fX, fY: Integer; Count: Word; fVelX, fVelY: Single; DefColor, CR, CG, CB: Byte);
63 var
68 implementation
70 uses
75 type
88 // for bubbles
90 // for water
93 //k8: sorry, i have to emulate virtual methods this way, 'cause i haet `Object`
111 const
120 var
127 // ////////////////////////////////////////////////////////////////////////// //
132 begin
142 // ////////////////////////////////////////////////////////////////////////// //
144 begin
149 // ???
151 begin
157 begin
163 begin
169 begin
175 begin
181 begin
187 begin
189 result := g_Map_HasAnyPanelAtPoint(x, y, (PANEL_WALL or PANEL_CLOSEDOOR or PANEL_OPENDOOR or PANEL_WATER or PANEL_ACID1 or PANEL_ACID2 or PANEL_STEP or PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT));
194 {$IF not DEFINED(HAS_COLLIDE_BITMAP)}
195 begin
197 {$ELSE}
198 var
200 begin
202 begin
208 Exit;
211 begin
217 Exit;
220 Exit;
222 Exit;
237 end
238 else
246 {$ENDIF}
249 {$IF DEFINED(HAS_COLLIDE_BITMAP)}
251 var
253 begin
260 begin
268 begin
276 begin
284 begin
288 begin
303 begin
306 begin
308 begin
309 // Çàêðûòàÿ äâåðü:
317 end
324 {$ENDIF}
328 begin
329 //CreateCollideMap();
334 var
336 begin
343 begin
352 {
353 procedure CorrectOffsets(id: Integer); inline;
354 var
355 part: PParticle;
356 begin
357 part := @Particles[id];
358 part.offsetX := 0;
359 part.offsetY := 0;
360 // check for upper wall
361 if isBlockedAt(part.X, part.Y-1) then part.offsetY := 1;
362 // check for left wall
363 if isBlockedAt(part.X-1, part.Y) then part.offsetX := 1;
364 end;
365 }
368 // ////////////////////////////////////////////////////////////////////////// //
370 var
373 {$IF not DEFINED(D2F_NEW_SPARK_THINKER)}
376 {$ELSE}
379 {$ENDIF}
380 begin
385 begin
387 begin
388 {$IF not DEFINED(D2F_NEW_SPARK_THINKER)}
389 {
390 if (not ByteBool(gCollideMap[Y-1, X] and MARK_BLOCKED)) and
391 (not ByteBool(gCollideMap[Y+1, X] and MARK_BLOCKED)) and
392 (not ByteBool(gCollideMap[Y, X-1] and MARK_BLOCKED)) and
393 (not ByteBool(gCollideMap[Y, X+1] and MARK_BLOCKED))
394 then
395 }
400 {$ELSE}
401 if not g_Map_CollidePanel(X-1, Y-1, 3, 3, (PANEL_STEP or PANEL_WALL or PANEL_OPENDOOR or PANEL_CLOSEDOOR))
402 {$ENDIF}
403 then
408 end
413 exit;
417 {$IF not DEFINED(D2F_NEW_SPARK_THINKER)}
419 begin
438 {$ELSE}
441 begin
443 begin
450 begin
455 begin
460 {$ENDIF}
465 {$IF not DEFINED(D2F_NEW_SPARK_THINKER)}
467 begin
478 {$ELSE}
480 begin
481 // Âèñèò â âîçäóõå - êàïàåò
482 if (nil = g_Map_traceToNearest(X, Y-1, X, Y+1, (GridTagWall or GridTagDoor or GridTagStep or GridTagAcid1 or GridTagAcid2 or GridTagWater), @ex, @ey)) then
483 begin
489 {$ENDIF}
491 {$IF DEFINED(D2F_NEW_SPARK_THINKER)}
492 // horizontal
494 begin
495 pan := g_Map_traceToNearest(X, Y, X+dX, Y, (GridTagWall or GridTagDoor or GridTagStep), @ex, @ey);
497 // free to ride?
499 begin
500 // Ñòåíà/äâåðü
510 // vertical
512 begin
513 pan := g_Map_traceToNearest(X, Y, X, Y+dY, (GridTagWall or GridTagDoor or GridTagStep), @ex, @ey);
515 // free to ride?
517 begin
518 // Ñòåíà/äâåðü
524 begin
526 end
527 else
528 begin
530 if (g_Map_PanelAtPoint(X-1, Y, (GridTagWall or GridTagDoor or GridTagStep)) <> nil) then stickDX := -1
531 else if (g_Map_PanelAtPoint(X+1, Y, (GridTagWall or GridTagDoor or GridTagStep)) <> nil) then stickDX := 1
537 {$ELSE}
538 // horizontal
540 begin
544 begin
546 //c := gCollideMap[Y, X+s];
554 break;
559 // vertical
561 begin
565 begin
567 //c := gCollideMap[Y+s, X];
575 break;
580 {$ENDIF}
582 else
583 begin
586 if (X+dX >= w) or (Y+dY >= h) or (X+dX <= 0) or (Y+dY <= 0) or isBlockedAt(X+dX, Y+dY) {ByteBool(gCollideMap[Y+dY, X+dX] and MARK_BLOCKED)} then
589 exit;
590 //VelX := 0;
591 //VelY := 0;
592 end
593 else
594 begin
603 // Êðîâü ðàñòâîðÿåòñÿ â æèäêîñòè:
605 begin
613 // ////////////////////////////////////////////////////////////////////////// //
615 var
617 {$IF not DEFINED(D2F_NEW_SPARK_THINKER)}
621 {$ELSE}
624 {$ENDIF}
625 begin
626 {$IF not DEFINED(D2F_NEW_SPARK_THINKER)}
629 {$ENDIF}
631 //TODO: trace wall end when water becomes stick
636 {$IF not DEFINED(D2F_NEW_SPARK_THINKER)}
640 {$ELSE}
642 begin
643 // no walls around, drop
645 end
646 else
647 begin
648 if (g_Map_PanelAtPoint(X+stickDX, Y, (GridTagWall or GridTagDoor or GridTagStep)) = nil) then State := STATE_NORMAL;
650 {$ENDIF}
651 exit;
654 {$IF not DEFINED(D2F_NEW_SPARK_THINKER)}
656 begin
679 {$ELSE}
682 begin
683 if ((pan.tag and (GridTagAcid1 or GridTagAcid2 or GridTagWater)) <> 0) then begin die(); exit; end;
685 begin
692 begin
697 begin
702 {$ENDIF}
707 {$IF not DEFINED(D2F_NEW_SPARK_THINKER)}
709 begin
720 {$ELSE}
722 begin
723 // Âèñèò â âîçäóõå - êàïàåò
724 if (nil = g_Map_traceToNearest(X, Y-1, X, Y+1, (GridTagWall or GridTagDoor or GridTagStep or GridTagAcid1 or GridTagAcid2 or GridTagWater), @ex, @ey)) then
725 begin
731 {$ENDIF}
733 {$IF DEFINED(D2F_NEW_SPARK_THINKER)}
734 // horizontal
736 begin
737 pan := g_Map_traceToNearest(X, Y, X+dX, Y, (GridTagWall or GridTagDoor or GridTagStep or GridTagAcid1 or GridTagAcid2 or GridTagWater), @ex, @ey);
739 // free to ride?
741 begin
742 // nope
743 if (dY > 0) and ((pan.tag and (GridTagAcid1 or GridTagAcid2 or GridTagWater)) <> 0) then begin die(); exit; end;
744 // Ñòåíà/äâåðü?
746 begin
757 // vertical
759 begin
760 pan := g_Map_traceToNearest(X, Y, X, Y+dY, (GridTagWall or GridTagDoor or GridTagStep or GridTagAcid1 or GridTagAcid2 or GridTagWater), @ex, @ey);
762 // free to ride?
764 begin
765 // nope
766 if (dY > 0) and ((pan.tag and (GridTagAcid1 or GridTagAcid2 or GridTagWater)) <> 0) then begin die(); exit; end;
767 // Ñòåíà/äâåðü?
769 begin
775 begin
777 end
778 else
779 begin
781 if (g_Map_PanelAtPoint(X-1, Y, (GridTagWall or GridTagDoor or GridTagStep)) <> nil) then stickDX := -1
782 else if (g_Map_PanelAtPoint(X+1, Y, (GridTagWall or GridTagDoor or GridTagStep)) <> nil) then stickDX := 1
789 {$ELSE}
790 // horizontal
792 begin
795 begin
796 // Ñáîêó ãðàíèöà?
798 //c := gCollideMap[Y, X+s];
799 // Ñáîêó æèäêîñòü, à ÷àñòèöà óæå ïàäàåò?
808 Break;
813 // vertical
815 begin
818 begin
819 // Ñíèçó/ñâåðõó ãðàíèöà
821 //c := gCollideMap[Y+s, X];
822 // Ñíèçó æèäêîñòü, à ÷àñòèöà óæå ïàäàåò
831 break;
836 {$ENDIF}
845 // ////////////////////////////////////////////////////////////////////////// //
847 var
849 {$IF not DEFINED(D2F_NEW_SPARK_THINKER)}
852 {$ELSE}
855 {$ENDIF}
856 begin
860 {$IF DEFINED(D2F_NEW_SPARK_THINKER)}
862 begin
863 pan := g_Map_traceToNearest(X, Y-1, X, Y+1, (GridTagWall or GridTagDoor or GridTagStep or GridTagAcid1 or GridTagAcid2 or GridTagWater), @ex, @ey);
865 {$ELSE}
874 {$ENDIF}
877 begin
878 {$IF DEFINED(D2F_NEW_SPARK_THINKER)}
879 pan := g_Map_traceToNearest(X, Y, X+dX, Y, (GridTagWall or GridTagDoor or GridTagStep or GridTagAcid1 or GridTagAcid2 or GridTagWater), @ex, @ey);
880 //e_WriteLog(Format('spark h-trace: (%d,%d)-(%d,%d); dx=%d; end=(%d,%d); hit=%d', [X, Y, X+dX, Y, dX, ex, ey, Integer(pan <> nil)]), MSG_NOTIFY);
882 // free to ride?
884 begin
885 // nope
886 if ((pan.tag and (GridTagAcid1 or GridTagAcid2 or GridTagWater)) <> 0) then begin die(); exit; end;
891 {$ELSE}
895 begin
897 //c := gCollideMap[Y, X+s];
902 Break;
903 end
908 begin
910 break;
913 {$ENDIF}
917 begin
918 {$IF DEFINED(D2F_NEW_SPARK_THINKER)}
919 pan := g_Map_traceToNearest(X, Y, X, Y+dY, (GridTagWall or GridTagDoor or GridTagStep or GridTagAcid1 or GridTagAcid2 or GridTagWater), @ex, @ey);
920 //e_WriteLog(Format('spark y-trace: (%d,%d)-(%d,%d); dy=%d; end=(%d,%d); hit=%d', [X, Y, X, Y+dY, dY, ex, ey, Integer(pan <> nil)]), MSG_NOTIFY);
921 (*
922 if (pan <> nil) then
923 begin
924 e_WriteLog(Format('spark y-trace: %08x (%d,%d)-(%d,%d); dy=%d; end=(%d,%d); hittag=%04x', [LongWord(@self), X, Y, X, Y+dY, dY, ex, ey, pan.tag]), MSG_NOTIFY);
925 end
926 else
927 begin
928 e_WriteLog(Format('spark y-trace: %08x (%d,%d)-(%d,%d); dy=%d; end=(%d,%d); hit=%d', [LongWord(@self), X, Y, X, Y+dY, dY, ex, ey, Integer(pan <> nil)]), MSG_NOTIFY);
929 end;
930 *)
932 // free to ride?
934 begin
935 //die(); exit;
936 // nope
937 if ((pan.tag and (GridTagAcid1 or GridTagAcid2 or GridTagWater)) <> 0) then begin die(); exit; end;
939 begin
942 end
943 else
944 begin
952 {$ELSE}
956 begin
958 //c := gCollideMap[Y+s, X];
962 begin
965 end
967 begin
974 Break;
975 end
980 begin
982 break;
985 {$ENDIF}
991 begin
999 // ////////////////////////////////////////////////////////////////////////// //
1001 var
1006 begin
1012 begin
1015 else
1019 begin
1022 (*
1023 if not isLiquidAt(X, Y+s) {ByteBool(gCollideMap[Y+s, X] and MARK_LIQUID)} then
1024 begin // Óæå íå æèäêîñòü
1025 State := STATE_FREE;
1026 Break;
1027 end;
1028 *)
1029 // we traced liquid before, so don't bother checking
1043 // ////////////////////////////////////////////////////////////////////////// //
1045 var
1050 begin
1061 begin
1063 begin
1073 else
1089 {CorrectOffsets(CurrentParticle);}
1094 else
1102 var
1109 begin
1111 begin
1113 Exit;
1117 Exit;
1127 begin
1129 begin
1133 {
1134 if (X < 0) or (X > gMapInfo.Width-1) or
1135 (Y < 0) or (Y > gMapInfo.Height-1) or
1136 ByteBool(gCollideMap[Y, X] and MARK_WALL) then
1137 Continue;
1138 }
1147 else
1155 begin
1160 end else
1163 begin
1168 end else
1171 begin
1176 end else
1186 {CorrectOffsets(CurrentParticle);}
1191 else
1198 var
1205 begin
1208 Exit;
1227 begin
1229 begin
1248 {CorrectOffsets(CurrentParticle);}
1253 else
1258 procedure g_GFX_Water(fX, fY: Integer; Count: Word; fVelX, fVelY: Single; DevX, DevY, Color: Byte);
1259 var
1264 begin
1267 Exit;
1280 begin
1282 begin
1288 else
1298 begin
1304 begin
1310 begin
1316 begin
1330 {CorrectOffsets(CurrentParticle);}
1335 else
1340 procedure g_GFX_SimpleWater(fX, fY: Integer; Count: Word; fVelX, fVelY: Single; DefColor, CR, CG, CB: Byte);
1341 var
1344 begin
1347 Exit;
1352 begin
1354 begin
1365 begin
1371 begin
1377 begin
1383 begin
1392 begin
1401 begin
1415 {CorrectOffsets(CurrentParticle);}
1420 else
1427 var
1432 begin
1435 Exit;
1445 begin
1447 begin
1453 Continue;
1455 (*
1456 // don't spawn bubbles outside of the liquid
1457 if not isLiquidAt(X, Y) {ByteBool(gCollideMap[Y, X] and MARK_LIQUID)} then
1458 Continue;
1459 *)
1461 // trace liquid, so we'll know where it ends; do it in 8px steps for speed
1462 // tracer will return `false` if we started outside of the liquid
1480 {CorrectOffsets(CurrentParticle);}
1485 else
1491 var
1493 begin
1500 //if CurrentParticle >= Count then
1505 begin
1510 var
1512 begin
1516 begin
1518 Exit;
1522 begin
1525 end
1526 else
1527 begin
1534 var
1536 begin
1538 Exit;
1551 var
1555 begin
1558 begin
1565 begin
1567 begin
1569 begin
1572 //if not alive then Continue;
1573 //e_WriteLog(Format('particle #%d: %d', [State, ParticleType]), MSG_NOTIFY);
1575 {CorrectOffsets(a);}
1582 begin
1585 begin
1587 ONCEANIM_SMOKE:
1588 begin
1597 begin
1600 end
1601 else
1608 var
1610 begin
1612 begin
1626 begin