67285caa60e8cb5349cdd9f606ca1a66dc7f70ca
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/>.
16 {$INCLUDE ../shared/a_modes.inc}
25 GAME_VERSION
= '0.667';
31 UID_MAX_PLAYER
= $7FFF;
32 UID_MAX_MONSTER
= $FFFF;
35 TDirection
= (D_LEFT
, D_RIGHT
);
36 WArray
= array of Word;
37 DWArray
= array of DWORD
;
38 String20
= String[20];
40 function g_CreateUID(UIDType
: Byte): Word;
41 function g_GetUIDType(UID
: Word): Byte;
42 function g_Collide(X1
, Y1
: Integer; Width1
, Height1
: Word;
43 X2
, Y2
: Integer; Width2
, Height2
: Word): Boolean;
44 function g_CollideLine(x1
, y1
, x2
, y2
, rX
, rY
: Integer; rWidth
, rHeight
: Word): Boolean;
45 function g_CollidePoint(X
, Y
, X2
, Y2
: Integer; Width
, Height
: Word): Boolean;
46 function g_CollideLevel(X
, Y
: Integer; Width
, Height
: Word): Boolean;
47 function g_CollideAround(X1
, Y1
: Integer; Width1
, Height1
: Word;
48 X2
, Y2
: Integer; Width2
, Height2
: Word): Boolean;
49 function g_CollidePlayer(X
, Y
: Integer; Width
, Height
: Word): Boolean;
50 function g_CollideMonster(X
, Y
: Integer; Width
, Height
: Word): Boolean;
51 function g_CollideItem(X
, Y
: Integer; Width
, Height
: Word): Boolean;
52 function g_PatchLength(X1
, Y1
, X2
, Y2
: Integer): Word;
53 function g_TraceVector(X1
, Y1
, X2
, Y2
: Integer): Boolean;
54 function g_GetAcidHit(X
, Y
: Integer; Width
, Height
: Word): Byte;
55 function g_Look(a
, b
: PObj
; d
: TDirection
): Boolean;
56 procedure IncMax(var A
: Integer; B
, Max
: Integer); overload
;
57 procedure IncMax(var A
: Single; B
, Max
: Single); overload
;
58 procedure IncMax(var A
: Integer; Max
: Integer); overload
;
59 procedure IncMax(var A
: Single; Max
: Single); overload
;
60 procedure IncMax(var A
: Word; B
, Max
: Word); overload
;
61 procedure IncMax(var A
: Word; Max
: Word); overload
;
62 procedure IncMax(var A
: SmallInt; B
, Max
: SmallInt); overload
;
63 procedure IncMax(var A
: SmallInt; Max
: SmallInt); overload
;
64 procedure DecMin(var A
: Integer; B
, Min
: Integer); overload
;
65 procedure DecMin(var A
: Single; B
, Min
: Single); overload
;
66 procedure DecMin(var A
: Integer; Min
: Integer); overload
;
67 procedure DecMin(var A
: Single; Min
: Single); overload
;
68 procedure DecMin(var A
: Word; B
, Min
: Word); overload
;
69 procedure DecMin(var A
: Word; Min
: Word); overload
;
70 procedure DecMin(var A
: Byte; B
, Min
: Byte); overload
;
71 procedure DecMin(var A
: Byte; Min
: Byte); overload
;
72 function Sign(A
: Integer): ShortInt; overload
;
73 function Sign(A
: Single): ShortInt; overload
;
74 function PointToRect(X
, Y
, X1
, Y1
: Integer; Width
, Height
: Word): Integer;
75 function GetAngle(baseX
, baseY
, pointX
, PointY
: Integer): SmallInt;
76 function GetAngle2(vx
, vy
: Integer): SmallInt;
77 function GetLines(Text: string; FontID
: DWORD
; MaxWidth
: Word): SArray
;
78 procedure Sort(var a
: SArray
);
79 function Sscanf(const s
: string; const fmt
: string;
80 const Pointers
: array of Pointer): Integer;
81 function InDWArray(a
: DWORD
; arr
: DWArray
): Boolean;
82 function InWArray(a
: Word; arr
: WArray
): Boolean;
83 function InSArray(a
: string; arr
: SArray
): Boolean;
84 function GetPos(UID
: Word; o
: PObj
): Boolean;
85 function parse(s
: string): SArray
;
86 function parse2(s
: string; delim
: Char): SArray
;
87 function g_GetFileTime(fileName
: String): Integer;
88 function g_SetFileTime(fileName
: String; time
: Integer): Boolean;
89 procedure SortSArray(var S
: SArray
);
90 function b_Text_Format(S
: string): string;
91 function b_Text_Unformat(S
: string): string;
96 Math
, g_map
, g_gfx
, g_player
, SysUtils
, MAPDEF
,
97 StrUtils
, e_graphics
, g_monsters
, g_items
;
99 function g_PatchLength(X1
, Y1
, X2
, Y2
: Integer): Word;
101 Result
:= Min(Round(Hypot(Abs(X2
-X1
), Abs(Y2
-Y1
))), 65535);
104 function g_CollideLevel(X
, Y
: Integer; Width
, Height
: Word): Boolean;
113 for a
:= 0 to High(gWalls
) do
114 if gWalls
[a
].Enabled
and
115 not ( ((Y
+ Height
<= gWalls
[a
].Y
) or
116 (Y
>= gWalls
[a
].Y
+ gWalls
[a
].Height
)) or
117 ((X
+ Width
<= gWalls
[a
].X
) or
118 (X
>= gWalls
[a
].X
+ gWalls
[a
].Width
)) ) then
125 function g_CollidePlayer(X
, Y
: Integer; Width
, Height
: Word): Boolean;
131 if gPlayers
= nil then Exit
;
133 for a
:= 0 to High(gPlayers
) do
134 if (gPlayers
[a
] <> nil) and gPlayers
[a
].Live
then
135 if gPlayers
[a
].Collide(X
, Y
, Width
, Height
) then
142 function g_CollideMonster(X
, Y
: Integer; Width
, Height
: Word): Boolean;
148 if gMonsters
= nil then Exit
;
150 for a
:= 0 to High(gMonsters
) do
151 if (gMonsters
[a
] <> nil) and gMonsters
[a
].Live
then
152 if g_Obj_Collide(X
, Y
, Width
, Height
, @gMonsters
[a
].Obj
) then
159 function g_CollideItem(X
, Y
: Integer; Width
, Height
: Word): Boolean;
168 for a
:= 0 to High(gItems
) do
169 if gItems
[a
].Live
then
170 if g_Obj_Collide(X
, Y
, Width
, Height
, @gItems
[a
].Obj
) then
177 function g_TraceVector(X1
, Y1
, X2
, Y2
: Integer): Boolean;
181 Xerr
, Yerr
, d
: LongWord;
187 Assert(gCollideMap
<> nil, 'g_TraceVector: gCollideMap = nil');
194 if dx
> 0 then incX
:= 1 else if dx
< 0 then incX
:= -1 else incX
:= 0;
195 if dy
> 0 then incY
:= 1 else if dy
< 0 then incY
:= -1 else incY
:= 0;
200 if dx
> dy
then d
:= dx
else d
:= dy
;
220 if (y
> gMapInfo
.Height
-1) or
221 (y
< 0) or (x
> gMapInfo
.Width
-1) or (x
< 0) then
223 if ByteBool(gCollideMap
[y
, x
] and MARK_BLOCKED
) then
230 function g_CreateUID(UIDType
: Byte): Word;
241 Result
:= UID_MAX_GAME
+$1+Random(UID_MAX_PLAYER
-UID_MAX_GAME
+$1);
244 if gPlayers
<> nil then
245 for i
:= 0 to High(gPlayers
) do
246 if gPlayers
[i
] <> nil then
247 if Result
= gPlayers
[i
].UID
then
258 Result
:= UID_MAX_PLAYER
+$1+Random(UID_MAX_MONSTER
-UID_MAX_GAME
-UID_MAX_PLAYER
+$1);
261 if gMonsters
<> nil then
262 for i
:= 0 to High(gMonsters
) do
263 if gMonsters
[i
] <> nil then
264 if Result
= gMonsters
[i
].UID
then
274 function g_GetUIDType(UID
: Word): Byte;
276 if UID
<= UID_MAX_GAME
then
279 if UID
<= UID_MAX_PLAYER
then
282 Result
:= UID_MONSTER
;
285 function g_Collide(X1
, Y1
: Integer; Width1
, Height1
: Word;
286 X2
, Y2
: Integer; Width2
, Height2
: Word): Boolean;
288 Result
:= not ( ((Y1
+ Height1
<= Y2
) or
289 (Y2
+ Height2
<= Y1
)) or
290 ((X1
+ Width1
<= X2
) or
291 (X2
+ Width2
<= X1
)) );
294 function g_CollideAround(X1
, Y1
: Integer; Width1
, Height1
: Word;
295 X2
, Y2
: Integer; Width2
, Height2
: Word): Boolean;
297 Result
:= g_Collide(X1
, Y1
, Width1
, Height1
, X2
, Y2
, Width2
, Height2
) or
298 g_Collide(X1
+1, Y1
, Width1
, Height1
, X2
, Y2
, Width2
, Height2
) or
299 g_Collide(X1
-1, Y1
, Width1
, Height1
, X2
, Y2
, Width2
, Height2
) or
300 g_Collide(X1
, Y1
+1, Width1
, Height1
, X2
, Y2
, Width2
, Height2
) or
301 g_Collide(X1
, Y1
-1, Width1
, Height1
, X2
, Y2
, Width2
, Height2
);
304 function c(X1
, Y1
, Width1
, Height1
, X2
, Y2
, Width2
, Height2
: Integer): Boolean;
306 Result
:= not (((Y1
+ Height1
<= Y2
) or
307 (Y1
>= Y2
+ Height2
)) or
308 ((X1
+ Width1
<= X2
) or
309 (X1
>= X2
+ Width2
)));
312 function g_Collide2(X1
, Y1
, X2
, Y2
, X3
, Y3
, X4
, Y4
: Integer): Boolean;
314 //Result := not (((Y2 <= Y3) or (Y1 >= Y4)) or ((X2 <= X3) or (X1 >= X4)));
315 Result
:= c(X1
, Y1
, X2
-X1
, Y2
-Y1
, X3
, Y3
, X4
-X3
, Y4
-Y3
);
318 function g_CollidePoint(X
, Y
, X2
, Y2
: Integer; Width
, Height
: Word): Boolean;
322 Result
:= (x
>= 0) and (x
<= Width
) and
323 (y
>= 0) and (y
<= Height
);
326 procedure IncMax(var A
: Integer; B
, Max
: Integer);
328 if A
+B
> Max
then A
:= Max
else A
:= A
+B
;
331 procedure IncMax(var A
: Single; B
, Max
: Single);
333 if A
+B
> Max
then A
:= Max
else A
:= A
+B
;
336 procedure DecMin(var A
: Integer; B
, Min
: Integer);
338 if A
-B
< Min
then A
:= Min
else A
:= A
-B
;
341 procedure DecMin(var A
: Word; B
, Min
: Word);
343 if A
-B
< Min
then A
:= Min
else A
:= A
-B
;
346 procedure DecMin(var A
: Single; B
, Min
: Single);
348 if A
-B
< Min
then A
:= Min
else A
:= A
-B
;
351 procedure IncMax(var A
: Integer; Max
: Integer);
353 if A
+1 > Max
then A
:= Max
else A
:= A
+1;
356 procedure IncMax(var A
: Single; Max
: Single);
358 if A
+1 > Max
then A
:= Max
else A
:= A
+1;
361 procedure IncMax(var A
: Word; B
, Max
: Word);
363 if A
+B
> Max
then A
:= Max
else A
:= A
+B
;
366 procedure IncMax(var A
: Word; Max
: Word);
368 if A
+1 > Max
then A
:= Max
else A
:= A
+1;
371 procedure IncMax(var A
: SmallInt; B
, Max
: SmallInt);
373 if A
+B
> Max
then A
:= Max
else A
:= A
+B
;
376 procedure IncMax(var A
: SmallInt; Max
: SmallInt);
378 if A
+1 > Max
then A
:= Max
else A
:= A
+1;
381 procedure DecMin(var A
: Integer; Min
: Integer);
383 if A
-1 < Min
then A
:= Min
else A
:= A
-1;
386 procedure DecMin(var A
: Single; Min
: Single);
388 if A
-1 < Min
then A
:= Min
else A
:= A
-1;
391 procedure DecMin(var A
: Word; Min
: Word);
393 if A
-1 < Min
then A
:= Min
else A
:= A
-1;
396 procedure DecMin(var A
: Byte; B
, Min
: Byte);
398 if A
-B
< Min
then A
:= Min
else A
:= A
-B
;
401 procedure DecMin(var A
: Byte; Min
: Byte); overload
;
403 if A
-1 < Min
then A
:= Min
else A
:= A
-1;
406 function Sign(A
: Integer): ShortInt;
408 if A
< 0 then Result
:= -1
409 else if A
> 0 then Result
:= 1
413 function Sign(A
: Single): ShortInt;
417 if Abs(A
) < Eps
then Result
:= 0
418 else if A
< 0 then Result
:= -1
422 function PointToRect(X
, Y
, X1
, Y1
: Integer; Width
, Height
: Word): Integer;
424 X
:= X
-X1
; // A(0;0) --- B(W;0)
429 if Y
< 0 then // Ñëåâà ñâåðõó: ðàññòîÿíèå äî A
430 Result
:= Round(Hypot(X
, Y
))
432 if Y
> Height
then // Ñëåâà ñíèçó: ðàññòîÿíèå äî D
433 Result
:= Round(Hypot(X
, Y
-Height
))
434 else // Ñëåâà ïîñåðåäèíå: ðàññòîÿíèå äî AD
441 if y
< 0 then // Ñïðàâà ñâåðõó: ðàññòîÿíèå äî B
442 Result
:= Round(Hypot(X
, Y
))
444 if Y
> Height
then // Ñïðàâà ñíèçó: ðàññòîÿíèå äî C
445 Result
:= Round(Hypot(X
, Y
-Height
))
446 else // Ñïðàâà ïîñåðåäèíå: ðàññòîÿíèå äî BC
451 if Y
< 0 then // Ïîñåðåäèíå ñâåðõó: ðàññòîÿíèå äî AB
454 if Y
> Height
then // Ïîñåðåäèíå ñíèçó: ðàññòîÿíèå äî DC
456 else // Âíóòðè ïðÿìîóãîëüíèêà: ðàññòîÿíèå 0
461 function g_GetAcidHit(X
, Y
: Integer; Width
, Height
: Word): Byte;
463 tab
: array[0..3] of Byte = (0, 5, 10, 20);
469 if g_Map_CollidePanel(X
, Y
, Width
, Height
, PANEL_ACID1
, False) then a
:= a
or 1;
470 if g_Map_CollidePanel(X
, Y
, Width
, Height
, PANEL_ACID2
, False) then a
:= a
or 2;
475 function g_Look(a
, b
: PObj
; d
: TDirection
): Boolean;
477 if ((b
^.X
> a
^.X
) and (d
= D_LEFT
)) or
478 ((b
^.X
< a
^.X
) and (d
= D_RIGHT
)) then
484 Result
:= g_TraceVector(a
^.X
+a
^.Rect
.X
+(a
^.Rect
.Width
div 2),
485 a
^.Y
+a
^.Rect
.Y
+(a
^.Rect
.Height
div 2),
486 b
^.X
+b
^.Rect
.X
+(b
^.Rect
.Width
div 2),
487 b
^.Y
+b
^.Rect
.Y
+(b
^.Rect
.Height
div 2));
490 function GetAngle(baseX
, baseY
, pointX
, PointY
: Integer): SmallInt;
495 a
:= abs(pointX
-baseX
);
496 b
:= abs(pointY
-baseY
);
498 if a
= 0 then c
:= 90
499 else c
:= RadToDeg(ArcTan(b
/a
));
501 if pointY
< baseY
then c
:= -c
;
502 if pointX
> baseX
then c
:= 180-c
;
507 function GetAngle2(vx
, vy
: Integer): SmallInt;
518 c
:= RadToDeg(ArcTan(b
/a
));
530 {function g_CollideLine(x1, y1, x2, y2, rX, rY: Integer; rWidth, rHeight: Word): Boolean;
532 table: array[0..8, 0..8] of Byte =
533 ((0, 0, 3, 3, 1, 2, 2, 0, 1),
534 (0, 0, 0, 0, 4, 7, 2, 0, 1),
535 (3, 0, 0, 0, 4, 4, 1, 3, 1),
536 (3, 0, 0, 0, 0, 0, 5, 6, 1),
537 (1, 4, 4, 0, 0, 0, 5, 5, 1),
538 (2, 7, 4, 0, 0, 0, 0, 0, 1),
539 (2, 2, 1, 5, 5, 0, 0, 0, 1),
540 (0, 0, 3, 6, 5, 0, 0, 0, 1),
541 (1, 1, 1, 1, 1, 1, 1, 1, 1));
543 function GetClass(x, y: Integer): Byte;
547 if x < rX then Result := 7
548 else if x < rX+rWidth then Result := 0
551 else if y < rY+rHeight then
553 if x < rX then Result := 6
554 else if x < rX+rWidth then Result := 8
559 if x < rX then Result := 5
560 else if x < rX+rWidth then Result := 4
566 case table[GetClass(x1, y1), GetClass(x2, y2)] of
569 2: Result := Abs((rY-y1))/Abs((rX-x1)) <= Abs((y2-y1))/Abs((x2-x1));
570 3: Result := Abs((rY-y1))/Abs((rX+rWidth-x1)) <= Abs((y2-y1))/Abs((x2-x1));
571 4: Result := Abs((rY+rHeight-y1))/Abs((rX+rWidth-x1)) >= Abs((y2-y1))/Abs((x2-x1));
572 5: Result := Abs((rY+rHeight-y1))/Abs((rX-x1)) >= Abs((y2-y1))/Abs((x2-x1));
573 6: Result := (Abs((rY-y1))/Abs((rX+rWidth-x1)) <= Abs((y2-y1))/Abs((x2-x1))) and
574 (Abs((rY+rHeight-y1))/Abs((rX-x1)) >= Abs((y2-y1))/Abs((x2-x1)));
575 7: Result := (Abs((rY+rHeight-y1))/Abs((rX+rWidth-x1)) >= Abs((y2-y1))/Abs((x2-x1))) and
576 (Abs((rY-y1))/Abs((rX-x1)) <= Abs((y2-y1))/Abs((x2-x1)));
577 else Result := False;
581 function g_CollideLine(x1
, y1
, x2
, y2
, rX
, rY
: Integer; rWidth
, rHeight
: Word): Boolean;
596 if dx
> 0 then incX
:= 1 else if dx
< 0 then incX
:= -1 else incX
:= 0;
597 if dy
> 0 then incY
:= 1 else if dy
< 0 then incY
:= -1 else incY
:= 0;
602 if dx
> dy
then d
:= dx
else d
:= dy
;
622 if (x
>= rX
) and (x
<= (rX
+ rWidth
- 1)) and
623 (y
>= rY
) and (y
<= (rY
+ rHeight
- 1)) then Exit
;
629 function GetStr(var Str
: string): string;
634 for a
:= 1 to Length(Str
) do
635 if (a
= Length(Str
)) or (Str
[a
+1] = ' ') then
637 Result
:= Copy(Str
, 1, a
);
644 {function GetLines(Text: string; MaxChars: Word): SArray;
652 while Pos(' ', Text) <> 0 do Text := AnsiReplaceStr(Text, ' ', ' ');
656 SetLength(b, Length(b)+1);
657 b[High(b)] := GetStr(Text);
663 if a > High(b) then Break;
668 if Length(str) >= MaxChars then
672 SetLength(Result, Length(Result)+1);
673 Result[High(Result)] := Copy(str, 1, MaxChars);
674 Delete(str, 1, MaxChars);
680 while (a <= High(b)) and (Length(str+' '+b[a]) <= MaxChars) do
686 SetLength(Result, Length(Result)+1);
687 Result[High(Result)] := str;
691 function GetLines(Text: string; FontID
: DWORD
; MaxWidth
: Word): SArray
;
693 function TextLen(Text: string): Word;
697 e_CharFont_GetSize(FontID
, Text, Result
, h
);
705 SetLength(Result
, 0);
710 // Óäàëÿåì ìíîæåñòâåííûå ïðîáåëû:
711 while Pos(' ', Text) <> 0 do
712 Text := AnsiReplaceStr(Text, ' ', ' ');
716 SetLength(b
, Length(b
)+1);
717 b
[High(b
)] := GetStr(Text);
729 if TextLen(str
) > MaxWidth
then
730 begin // Òåêóùàÿ ñòðîêà ñëèøêîì äëèííàÿ => ðàçáèâàåì
733 SetLength(Result
, Length(Result
)+1);
736 while (c
< Length(str
)) and
737 (TextLen(Copy(str
, 1, c
+1)) < MaxWidth
) do
740 Result
[High(Result
)] := Copy(str
, 1, c
);
744 else // Ñòðîêà íîðìàëüíîé äëèíû => ñîåäèíÿåì ñî ñëåäóþùèìè
746 while (a
<= High(b
)) and
747 (TextLen(str
+' '+b
[a
]) < MaxWidth
) do
753 SetLength(Result
, Length(Result
)+1);
754 Result
[High(Result
)] := str
;
759 procedure Sort(var a
: SArray
);
764 if a
= nil then Exit
;
766 for i
:= High(a
) downto Low(a
) do
767 for j
:= Low(a
) to High(a
)-1 do
768 if LowerCase(a
[j
]) > LowerCase(a
[j
+1]) then
776 function Sscanf(const s
: String; const fmt
: String;
777 const Pointers
: array of Pointer): Integer;
784 function GetInt(): Integer;
787 while (n
<= Length(s
)) and (s
[n
] = ' ') do
790 while (n
<= Length(s
)) and (s
[n
] in ['0'..'9', '+', '-']) do
796 Result
:= Length(s1
);
799 function GetFloat(): Integer;
802 while (n
<= Length(s
)) and (s
[n
] = ' ') do
805 while (n
<= Length(s
)) and //jd >= rather than >
806 (s
[n
] in ['0'..'9', '+', '-', '.', 'e', 'E']) do
812 Result
:= Length(s1
);
815 function GetString(): Integer;
818 while (n
<= Length(s
)) and (s
[n
] = ' ') do
821 while (n
<= Length(s
)) and (s
[n
] <> ' ') do
827 Result
:= Length(s1
);
830 function ScanStr(c
: Char): Boolean;
832 while (n
<= Length(s
)) and (s
[n
] <> c
) do
836 Result
:= (n
<= Length(s
));
839 function GetFmt(): Integer;
845 while (fmt
[m
] = ' ') and (m
< Length(fmt
)) do
847 if (m
>= Length(fmt
)) then
850 if (fmt
[m
] = '%') then
854 'd': Result
:= vtInteger
;
855 'f': Result
:= vtExtended
;
856 's': Result
:= vtString
;
862 if (not ScanStr(fmt
[m
])) then
874 for i
:= 0 to High(Pointers
) do
883 L
:= StrToIntDef(s1
, 0);
884 Move(L
, Pointers
[i
]^, SizeOf(LongInt));
893 if GetFloat() > 0 then
895 X
:= StrToFloatDef(s1
, 0.0);
896 Move(X
, Pointers
[i
]^, SizeOf(Extended
));
905 if GetString() > 0 then
907 Move(s1
, Pointers
[i
]^, Length(s1
)+1);
920 function InDWArray(a
: DWORD
; arr
: DWArray
): Boolean;
926 if arr
= nil then Exit
;
928 for b
:= 0 to High(arr
) do
936 function InWArray(a
: Word; arr
: WArray
): Boolean;
942 if arr
= nil then Exit
;
944 for b
:= 0 to High(arr
) do
952 function InSArray(a
: string; arr
: SArray
): Boolean;
958 if arr
= nil then Exit
;
960 a
:= AnsiLowerCase(a
);
962 for b
:= 0 to High(arr
) do
963 if AnsiLowerCase(arr
[b
]) = a
then
970 function GetPos(UID
: Word; o
: PObj
): Boolean;
977 case g_GetUIDType(UID
) of
980 p
:= g_Player_Get(UID
);
981 if p
= nil then Exit
;
982 if not p
.Live
then Exit
;
989 m
:= g_Monsters_Get(UID
);
990 if m
= nil then Exit
;
991 if not m
.Live
then Exit
;
1001 function parse(s
: String): SArray
;
1011 for a
:= 1 to Length(s
) do
1012 if (s
[a
] = ',') or (a
= Length(s
)) then
1014 SetLength(Result
, Length(Result
)+1);
1017 Result
[High(Result
)] := Copy(s
, 1, a
-1)
1018 else // Êîíåö ñòðîêè
1019 Result
[High(Result
)] := s
;
1027 function parse2(s
: string; delim
: Char): SArray
;
1032 if s
= '' then Exit
;
1036 for a
:= 1 to Length(s
) do
1037 if (s
[a
] = delim
) or (a
= Length(s
)) then
1039 SetLength(Result
, Length(Result
)+1);
1041 if s
[a
] = delim
then Result
[High(Result
)] := Copy(s
, 1, a
-1)
1042 else Result
[High(Result
)] := s
;
1050 function g_GetFileTime(fileName
: String): Integer;
1054 if not FileExists(fileName
) then
1060 AssignFile(F
, fileName
);
1062 Result
:= FileGetDate(TFileRec(F
).Handle
);
1066 function g_SetFileTime(fileName
: String; time
: Integer): Boolean;
1070 if (not FileExists(fileName
)) or (time
< 0) then
1076 AssignFile(F
, fileName
);
1078 Result
:= (FileSetDate(TFileRec(F
).Handle
, time
) = 0);
1082 procedure SortSArray(var S
: SArray
);
1090 for i
:= Low(S
) to High(S
) - 1 do
1091 if S
[i
] > S
[i
+ 1] then begin
1100 function b_Text_Format(S
: string): string;
1108 for I
:= 1 to Length(S
) do
1110 if (not Spec
) and (S
[I
] = '\') and (I
+ 1 <= Length(S
)) then
1120 Result
:= Result
+ #10;
1122 Result
:= Result
+ #1;
1124 Result
:= Result
+ #2;
1126 Result
:= Result
+ #3;
1128 Result
:= Result
+ #4;
1130 Result
:= Result
+ #18;
1132 Result
:= Result
+ #19;
1134 Result
:= Result
+ #20;
1136 Result
:= Result
+ #21;
1138 Result
:= Result
+ '\';
1140 Result
:= Result
+ '\' + S
[I
];
1144 Result
:= Result
+ S
[I
];
1146 // reset to white at end
1147 if Rst
then Result
:= Result
+ #2;
1150 function b_Text_Unformat(S
: string): string;
1157 for I
:= 1 to Length(S
) do
1159 if S
[I
] in [#1, #2, #3, #4, #10, #18, #19, #20, #21] then
1164 if (not Spec
) and (S
[I
] = '\') and (I
+ 1 <= Length(S
)) then
1181 '\': Result
:= Result
+ '\';
1183 Result
:= Result
+ '\' + S
[I
];
1187 Result
:= Result
+ S
[I
];