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;
106 result
:= g_Map_CollidePanel(X
, Y
, Width
, Height
, (PANEL_WALL
or PANEL_CLOSEDOOR
or PANEL_OPENDOOR
), false);
117 for a := 0 to High(gWalls) do
118 if gWalls[a].Enabled and
119 not ( ((Y + Height <= gWalls[a].Y) or
120 (Y >= gWalls[a].Y + gWalls[a].Height)) or
121 ((X + Width <= gWalls[a].X) or
122 (X >= gWalls[a].X + gWalls[a].Width)) ) then
130 function g_CollidePlayer(X
, Y
: Integer; Width
, Height
: Word): Boolean;
136 if gPlayers
= nil then Exit
;
138 for a
:= 0 to High(gPlayers
) do
139 if (gPlayers
[a
] <> nil) and gPlayers
[a
].Live
then
140 if gPlayers
[a
].Collide(X
, Y
, Width
, Height
) then
147 function g_CollideMonster(X
, Y
: Integer; Width
, Height
: Word): Boolean;
153 if gMonsters
= nil then Exit
;
155 for a
:= 0 to High(gMonsters
) do
156 if (gMonsters
[a
] <> nil) and gMonsters
[a
].Live
then
157 if g_Obj_Collide(X
, Y
, Width
, Height
, @gMonsters
[a
].Obj
) then
164 function g_CollideItem(X
, Y
: Integer; Width
, Height
: Word): Boolean;
173 for a
:= 0 to High(gItems
) do
174 if gItems
[a
].Live
then
175 if g_Obj_Collide(X
, Y
, Width
, Height
, @gItems
[a
].Obj
) then
182 function g_TraceVector(X1
, Y1
, X2
, Y2
: Integer): Boolean;
186 Xerr
, Yerr
, d
: LongWord;
192 Assert(gCollideMap
<> nil, 'g_TraceVector: gCollideMap = nil');
199 if dx
> 0 then incX
:= 1 else if dx
< 0 then incX
:= -1 else incX
:= 0;
200 if dy
> 0 then incY
:= 1 else if dy
< 0 then incY
:= -1 else incY
:= 0;
205 if dx
> dy
then d
:= dx
else d
:= dy
;
225 if (y
> gMapInfo
.Height
-1) or
226 (y
< 0) or (x
> gMapInfo
.Width
-1) or (x
< 0) then
228 if ByteBool(gCollideMap
[y
, x
] and MARK_BLOCKED
) then
235 function g_CreateUID(UIDType
: Byte): Word;
246 Result
:= UID_MAX_GAME
+$1+Random(UID_MAX_PLAYER
-UID_MAX_GAME
+$1);
249 if gPlayers
<> nil then
250 for i
:= 0 to High(gPlayers
) do
251 if gPlayers
[i
] <> nil then
252 if Result
= gPlayers
[i
].UID
then
263 Result
:= UID_MAX_PLAYER
+$1+Random(UID_MAX_MONSTER
-UID_MAX_GAME
-UID_MAX_PLAYER
+$1);
266 if gMonsters
<> nil then
267 for i
:= 0 to High(gMonsters
) do
268 if gMonsters
[i
] <> nil then
269 if Result
= gMonsters
[i
].UID
then
279 function g_GetUIDType(UID
: Word): Byte;
281 if UID
<= UID_MAX_GAME
then
284 if UID
<= UID_MAX_PLAYER
then
287 Result
:= UID_MONSTER
;
290 function g_Collide(X1
, Y1
: Integer; Width1
, Height1
: Word;
291 X2
, Y2
: Integer; Width2
, Height2
: Word): Boolean;
293 Result
:= not ( ((Y1
+ Height1
<= Y2
) or
294 (Y2
+ Height2
<= Y1
)) or
295 ((X1
+ Width1
<= X2
) or
296 (X2
+ Width2
<= X1
)) );
299 function g_CollideAround(X1
, Y1
: Integer; Width1
, Height1
: Word;
300 X2
, Y2
: Integer; Width2
, Height2
: Word): Boolean;
302 Result
:= g_Collide(X1
, Y1
, Width1
, Height1
, X2
, Y2
, Width2
, Height2
) or
303 g_Collide(X1
+1, Y1
, Width1
, Height1
, X2
, Y2
, Width2
, Height2
) or
304 g_Collide(X1
-1, Y1
, Width1
, Height1
, X2
, Y2
, Width2
, Height2
) or
305 g_Collide(X1
, Y1
+1, Width1
, Height1
, X2
, Y2
, Width2
, Height2
) or
306 g_Collide(X1
, Y1
-1, Width1
, Height1
, X2
, Y2
, Width2
, Height2
);
309 function c(X1
, Y1
, Width1
, Height1
, X2
, Y2
, Width2
, Height2
: Integer): Boolean;
311 Result
:= not (((Y1
+ Height1
<= Y2
) or
312 (Y1
>= Y2
+ Height2
)) or
313 ((X1
+ Width1
<= X2
) or
314 (X1
>= X2
+ Width2
)));
317 function g_Collide2(X1
, Y1
, X2
, Y2
, X3
, Y3
, X4
, Y4
: Integer): Boolean;
319 //Result := not (((Y2 <= Y3) or (Y1 >= Y4)) or ((X2 <= X3) or (X1 >= X4)));
320 Result
:= c(X1
, Y1
, X2
-X1
, Y2
-Y1
, X3
, Y3
, X4
-X3
, Y4
-Y3
);
323 function g_CollidePoint(X
, Y
, X2
, Y2
: Integer; Width
, Height
: Word): Boolean;
327 Result
:= (x
>= 0) and (x
<= Width
) and
328 (y
>= 0) and (y
<= Height
);
331 procedure IncMax(var A
: Integer; B
, Max
: Integer);
333 if A
+B
> Max
then A
:= Max
else A
:= A
+B
;
336 procedure IncMax(var A
: Single; B
, Max
: Single);
338 if A
+B
> Max
then A
:= Max
else A
:= A
+B
;
341 procedure DecMin(var A
: Integer; B
, Min
: Integer);
343 if A
-B
< Min
then A
:= Min
else A
:= A
-B
;
346 procedure DecMin(var A
: Word; B
, Min
: Word);
348 if A
-B
< Min
then A
:= Min
else A
:= A
-B
;
351 procedure DecMin(var A
: Single; B
, Min
: Single);
353 if A
-B
< Min
then A
:= Min
else A
:= A
-B
;
356 procedure IncMax(var A
: Integer; Max
: Integer);
358 if A
+1 > Max
then A
:= Max
else A
:= A
+1;
361 procedure IncMax(var A
: Single; Max
: Single);
363 if A
+1 > Max
then A
:= Max
else A
:= A
+1;
366 procedure IncMax(var A
: Word; B
, Max
: Word);
368 if A
+B
> Max
then A
:= Max
else A
:= A
+B
;
371 procedure IncMax(var A
: Word; Max
: Word);
373 if A
+1 > Max
then A
:= Max
else A
:= A
+1;
376 procedure IncMax(var A
: SmallInt; B
, Max
: SmallInt);
378 if A
+B
> Max
then A
:= Max
else A
:= A
+B
;
381 procedure IncMax(var A
: SmallInt; Max
: SmallInt);
383 if A
+1 > Max
then A
:= Max
else A
:= A
+1;
386 procedure DecMin(var A
: Integer; Min
: Integer);
388 if A
-1 < Min
then A
:= Min
else A
:= A
-1;
391 procedure DecMin(var A
: Single; Min
: Single);
393 if A
-1 < Min
then A
:= Min
else A
:= A
-1;
396 procedure DecMin(var A
: Word; Min
: Word);
398 if A
-1 < Min
then A
:= Min
else A
:= A
-1;
401 procedure DecMin(var A
: Byte; B
, Min
: Byte);
403 if A
-B
< Min
then A
:= Min
else A
:= A
-B
;
406 procedure DecMin(var A
: Byte; Min
: Byte); overload
;
408 if A
-1 < Min
then A
:= Min
else A
:= A
-1;
411 function Sign(A
: Integer): ShortInt;
413 if A
< 0 then Result
:= -1
414 else if A
> 0 then Result
:= 1
418 function Sign(A
: Single): ShortInt;
422 if Abs(A
) < Eps
then Result
:= 0
423 else if A
< 0 then Result
:= -1
427 function PointToRect(X
, Y
, X1
, Y1
: Integer; Width
, Height
: Word): Integer;
429 X
:= X
-X1
; // A(0;0) --- B(W;0)
434 if Y
< 0 then // Ñëåâà ñâåðõó: ðàññòîÿíèå äî A
435 Result
:= Round(Hypot(X
, Y
))
437 if Y
> Height
then // Ñëåâà ñíèçó: ðàññòîÿíèå äî D
438 Result
:= Round(Hypot(X
, Y
-Height
))
439 else // Ñëåâà ïîñåðåäèíå: ðàññòîÿíèå äî AD
446 if y
< 0 then // Ñïðàâà ñâåðõó: ðàññòîÿíèå äî B
447 Result
:= Round(Hypot(X
, Y
))
449 if Y
> Height
then // Ñïðàâà ñíèçó: ðàññòîÿíèå äî C
450 Result
:= Round(Hypot(X
, Y
-Height
))
451 else // Ñïðàâà ïîñåðåäèíå: ðàññòîÿíèå äî BC
456 if Y
< 0 then // Ïîñåðåäèíå ñâåðõó: ðàññòîÿíèå äî AB
459 if Y
> Height
then // Ïîñåðåäèíå ñíèçó: ðàññòîÿíèå äî DC
461 else // Âíóòðè ïðÿìîóãîëüíèêà: ðàññòîÿíèå 0
466 function g_GetAcidHit(X
, Y
: Integer; Width
, Height
: Word): Byte;
468 tab
: array[0..3] of Byte = (0, 5, 10, 20);
474 if g_Map_CollidePanel(X
, Y
, Width
, Height
, PANEL_ACID1
, False) then a
:= a
or 1;
475 if g_Map_CollidePanel(X
, Y
, Width
, Height
, PANEL_ACID2
, False) then a
:= a
or 2;
480 function g_Look(a
, b
: PObj
; d
: TDirection
): Boolean;
482 if ((b
^.X
> a
^.X
) and (d
= D_LEFT
)) or
483 ((b
^.X
< a
^.X
) and (d
= D_RIGHT
)) then
489 Result
:= g_TraceVector(a
^.X
+a
^.Rect
.X
+(a
^.Rect
.Width
div 2),
490 a
^.Y
+a
^.Rect
.Y
+(a
^.Rect
.Height
div 2),
491 b
^.X
+b
^.Rect
.X
+(b
^.Rect
.Width
div 2),
492 b
^.Y
+b
^.Rect
.Y
+(b
^.Rect
.Height
div 2));
495 function GetAngle(baseX
, baseY
, pointX
, PointY
: Integer): SmallInt;
500 a
:= abs(pointX
-baseX
);
501 b
:= abs(pointY
-baseY
);
503 if a
= 0 then c
:= 90
504 else c
:= RadToDeg(ArcTan(b
/a
));
506 if pointY
< baseY
then c
:= -c
;
507 if pointX
> baseX
then c
:= 180-c
;
512 function GetAngle2(vx
, vy
: Integer): SmallInt;
523 c
:= RadToDeg(ArcTan(b
/a
));
535 {function g_CollideLine(x1, y1, x2, y2, rX, rY: Integer; rWidth, rHeight: Word): Boolean;
537 table: array[0..8, 0..8] of Byte =
538 ((0, 0, 3, 3, 1, 2, 2, 0, 1),
539 (0, 0, 0, 0, 4, 7, 2, 0, 1),
540 (3, 0, 0, 0, 4, 4, 1, 3, 1),
541 (3, 0, 0, 0, 0, 0, 5, 6, 1),
542 (1, 4, 4, 0, 0, 0, 5, 5, 1),
543 (2, 7, 4, 0, 0, 0, 0, 0, 1),
544 (2, 2, 1, 5, 5, 0, 0, 0, 1),
545 (0, 0, 3, 6, 5, 0, 0, 0, 1),
546 (1, 1, 1, 1, 1, 1, 1, 1, 1));
548 function GetClass(x, y: Integer): Byte;
552 if x < rX then Result := 7
553 else if x < rX+rWidth then Result := 0
556 else if y < rY+rHeight then
558 if x < rX then Result := 6
559 else if x < rX+rWidth then Result := 8
564 if x < rX then Result := 5
565 else if x < rX+rWidth then Result := 4
571 case table[GetClass(x1, y1), GetClass(x2, y2)] of
574 2: Result := Abs((rY-y1))/Abs((rX-x1)) <= Abs((y2-y1))/Abs((x2-x1));
575 3: Result := Abs((rY-y1))/Abs((rX+rWidth-x1)) <= Abs((y2-y1))/Abs((x2-x1));
576 4: Result := Abs((rY+rHeight-y1))/Abs((rX+rWidth-x1)) >= Abs((y2-y1))/Abs((x2-x1));
577 5: Result := Abs((rY+rHeight-y1))/Abs((rX-x1)) >= Abs((y2-y1))/Abs((x2-x1));
578 6: Result := (Abs((rY-y1))/Abs((rX+rWidth-x1)) <= Abs((y2-y1))/Abs((x2-x1))) and
579 (Abs((rY+rHeight-y1))/Abs((rX-x1)) >= Abs((y2-y1))/Abs((x2-x1)));
580 7: Result := (Abs((rY+rHeight-y1))/Abs((rX+rWidth-x1)) >= Abs((y2-y1))/Abs((x2-x1))) and
581 (Abs((rY-y1))/Abs((rX-x1)) <= Abs((y2-y1))/Abs((x2-x1)));
582 else Result := False;
586 function g_CollideLine(x1
, y1
, x2
, y2
, rX
, rY
: Integer; rWidth
, rHeight
: Word): Boolean;
601 if dx
> 0 then incX
:= 1 else if dx
< 0 then incX
:= -1 else incX
:= 0;
602 if dy
> 0 then incY
:= 1 else if dy
< 0 then incY
:= -1 else incY
:= 0;
607 if dx
> dy
then d
:= dx
else d
:= dy
;
627 if (x
>= rX
) and (x
<= (rX
+ rWidth
- 1)) and
628 (y
>= rY
) and (y
<= (rY
+ rHeight
- 1)) then Exit
;
634 function GetStr(var Str
: string): string;
639 for a
:= 1 to Length(Str
) do
640 if (a
= Length(Str
)) or (Str
[a
+1] = ' ') then
642 Result
:= Copy(Str
, 1, a
);
649 {function GetLines(Text: string; MaxChars: Word): SArray;
657 while Pos(' ', Text) <> 0 do Text := AnsiReplaceStr(Text, ' ', ' ');
661 SetLength(b, Length(b)+1);
662 b[High(b)] := GetStr(Text);
668 if a > High(b) then Break;
673 if Length(str) >= MaxChars then
677 SetLength(Result, Length(Result)+1);
678 Result[High(Result)] := Copy(str, 1, MaxChars);
679 Delete(str, 1, MaxChars);
685 while (a <= High(b)) and (Length(str+' '+b[a]) <= MaxChars) do
691 SetLength(Result, Length(Result)+1);
692 Result[High(Result)] := str;
696 function GetLines(Text: string; FontID
: DWORD
; MaxWidth
: Word): SArray
;
698 function TextLen(Text: string): Word;
702 e_CharFont_GetSize(FontID
, Text, Result
, h
);
710 SetLength(Result
, 0);
715 // Óäàëÿåì ìíîæåñòâåííûå ïðîáåëû:
716 while Pos(' ', Text) <> 0 do
717 Text := AnsiReplaceStr(Text, ' ', ' ');
721 SetLength(b
, Length(b
)+1);
722 b
[High(b
)] := GetStr(Text);
734 if TextLen(str
) > MaxWidth
then
735 begin // Òåêóùàÿ ñòðîêà ñëèøêîì äëèííàÿ => ðàçáèâàåì
738 SetLength(Result
, Length(Result
)+1);
741 while (c
< Length(str
)) and
742 (TextLen(Copy(str
, 1, c
+1)) < MaxWidth
) do
745 Result
[High(Result
)] := Copy(str
, 1, c
);
749 else // Ñòðîêà íîðìàëüíîé äëèíû => ñîåäèíÿåì ñî ñëåäóþùèìè
751 while (a
<= High(b
)) and
752 (TextLen(str
+' '+b
[a
]) < MaxWidth
) do
758 SetLength(Result
, Length(Result
)+1);
759 Result
[High(Result
)] := str
;
764 procedure Sort(var a
: SArray
);
769 if a
= nil then Exit
;
771 for i
:= High(a
) downto Low(a
) do
772 for j
:= Low(a
) to High(a
)-1 do
773 if LowerCase(a
[j
]) > LowerCase(a
[j
+1]) then
781 function Sscanf(const s
: String; const fmt
: String;
782 const Pointers
: array of Pointer): Integer;
789 function GetInt(): Integer;
792 while (n
<= Length(s
)) and (s
[n
] = ' ') do
795 while (n
<= Length(s
)) and (s
[n
] in ['0'..'9', '+', '-']) do
801 Result
:= Length(s1
);
804 function GetFloat(): Integer;
807 while (n
<= Length(s
)) and (s
[n
] = ' ') do
810 while (n
<= Length(s
)) and //jd >= rather than >
811 (s
[n
] in ['0'..'9', '+', '-', '.', 'e', 'E']) do
817 Result
:= Length(s1
);
820 function GetString(): Integer;
823 while (n
<= Length(s
)) and (s
[n
] = ' ') do
826 while (n
<= Length(s
)) and (s
[n
] <> ' ') do
832 Result
:= Length(s1
);
835 function ScanStr(c
: Char): Boolean;
837 while (n
<= Length(s
)) and (s
[n
] <> c
) do
841 Result
:= (n
<= Length(s
));
844 function GetFmt(): Integer;
850 while (fmt
[m
] = ' ') and (m
< Length(fmt
)) do
852 if (m
>= Length(fmt
)) then
855 if (fmt
[m
] = '%') then
859 'd': Result
:= vtInteger
;
860 'f': Result
:= vtExtended
;
861 's': Result
:= vtString
;
867 if (not ScanStr(fmt
[m
])) then
879 for i
:= 0 to High(Pointers
) do
888 L
:= StrToIntDef(s1
, 0);
889 Move(L
, Pointers
[i
]^, SizeOf(LongInt));
898 if GetFloat() > 0 then
900 X
:= StrToFloatDef(s1
, 0.0);
901 Move(X
, Pointers
[i
]^, SizeOf(Extended
));
910 if GetString() > 0 then
912 Move(s1
, Pointers
[i
]^, Length(s1
)+1);
925 function InDWArray(a
: DWORD
; arr
: DWArray
): Boolean;
931 if arr
= nil then Exit
;
933 for b
:= 0 to High(arr
) do
941 function InWArray(a
: Word; arr
: WArray
): Boolean;
947 if arr
= nil then Exit
;
949 for b
:= 0 to High(arr
) do
957 function InSArray(a
: string; arr
: SArray
): Boolean;
963 if arr
= nil then Exit
;
965 a
:= AnsiLowerCase(a
);
967 for b
:= 0 to High(arr
) do
968 if AnsiLowerCase(arr
[b
]) = a
then
975 function GetPos(UID
: Word; o
: PObj
): Boolean;
982 case g_GetUIDType(UID
) of
985 p
:= g_Player_Get(UID
);
986 if p
= nil then Exit
;
987 if not p
.Live
then Exit
;
994 m
:= g_Monsters_Get(UID
);
995 if m
= nil then Exit
;
996 if not m
.Live
then Exit
;
1006 function parse(s
: String): SArray
;
1016 for a
:= 1 to Length(s
) do
1017 if (s
[a
] = ',') or (a
= Length(s
)) then
1019 SetLength(Result
, Length(Result
)+1);
1022 Result
[High(Result
)] := Copy(s
, 1, a
-1)
1023 else // Êîíåö ñòðîêè
1024 Result
[High(Result
)] := s
;
1032 function parse2(s
: string; delim
: Char): SArray
;
1037 if s
= '' then Exit
;
1041 for a
:= 1 to Length(s
) do
1042 if (s
[a
] = delim
) or (a
= Length(s
)) then
1044 SetLength(Result
, Length(Result
)+1);
1046 if s
[a
] = delim
then Result
[High(Result
)] := Copy(s
, 1, a
-1)
1047 else Result
[High(Result
)] := s
;
1055 function g_GetFileTime(fileName
: String): Integer;
1059 if not FileExists(fileName
) then
1065 AssignFile(F
, fileName
);
1067 Result
:= FileGetDate(TFileRec(F
).Handle
);
1071 function g_SetFileTime(fileName
: String; time
: Integer): Boolean;
1075 if (not FileExists(fileName
)) or (time
< 0) then
1081 AssignFile(F
, fileName
);
1083 Result
:= (FileSetDate(TFileRec(F
).Handle
, time
) = 0);
1087 procedure SortSArray(var S
: SArray
);
1095 for i
:= Low(S
) to High(S
) - 1 do
1096 if S
[i
] > S
[i
+ 1] then begin
1105 function b_Text_Format(S
: string): string;
1113 for I
:= 1 to Length(S
) do
1115 if (not Spec
) and (S
[I
] = '\') and (I
+ 1 <= Length(S
)) then
1125 Result
:= Result
+ #10;
1127 Result
:= Result
+ #1;
1129 Result
:= Result
+ #2;
1131 Result
:= Result
+ #3;
1133 Result
:= Result
+ #4;
1135 Result
:= Result
+ #18;
1137 Result
:= Result
+ #19;
1139 Result
:= Result
+ #20;
1141 Result
:= Result
+ #21;
1143 Result
:= Result
+ '\';
1145 Result
:= Result
+ '\' + S
[I
];
1149 Result
:= Result
+ S
[I
];
1151 // reset to white at end
1152 if Rst
then Result
:= Result
+ #2;
1155 function b_Text_Unformat(S
: string): string;
1162 for I
:= 1 to Length(S
) do
1164 if S
[I
] in [#1, #2, #3, #4, #10, #18, #19, #20, #21] then
1169 if (not Spec
) and (S
[I
] = '\') and (I
+ 1 <= Length(S
)) then
1186 '\': Result
:= Result
+ '\';
1188 Result
:= Result
+ '\' + S
[I
];
1192 Result
:= Result
+ S
[I
];