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}
23 MAPDEF
, BinEditor
, g_textures
, xdynrec
;
26 TAddTextureArray
= Array of
32 TPanel
= Class (TObject
)
36 mGUID
: Integer; // will be assigned in "g_map.pas"
44 False: (Tex
: Cardinal);
45 True: (AnTex
: TAnimation
);
48 mMovingSpeed
: TDFPoint
;
49 mMovingStart
: TDFPoint
;
51 mMovingActive
: Boolean;
54 function getx1 (): Integer; inline;
55 function gety1 (): Integer; inline;
56 function getvisvalid (): Boolean; inline;
59 FCurTexture
: Integer; // Íîìåð òåêóùåé òåêñòóðû
63 FWidth
, FHeight
: Word;
65 FSaveIt
: Boolean; // Ñîõðàíÿòü ïðè SaveState?
71 // sorry, there fields are public to allow setting 'em in g_map; this should be fixed later
72 // for now, PLEASE, don't modify 'em, or all hell will break loose
73 arrIdx
: Integer; // index in one of internal arrays; sorry
74 tag
: Integer; // used in coldets and such; sorry; see g_map.GridTagXXX
75 proxyId
: Integer; // proxy id in map grid (DO NOT USE!)
76 mapId
: AnsiString; // taken directly from map file; dunno why it is here
78 constructor Create(PanelRec
: TDynRecord
;
79 AddTextures
: TAddTextureArray
;
81 var Textures
: TLevelTextureArray
; aguid
: Integer);
82 destructor Destroy(); override;
85 procedure DrawShadowVolume(lightX
: Integer; lightY
: Integer; radius
: Integer);
87 procedure SetFrame(Frame
: Integer; Count
: Byte);
88 procedure NextTexture(AnimLoop
: Byte = 0);
89 procedure SetTexture(ID
: Integer; AnimLoop
: Byte = 0);
90 function GetTextureID(): Cardinal;
91 function GetTextureCount(): Integer;
93 procedure SaveState(var Mem
: TBinMemoryWriter
);
94 procedure LoadState(var Mem
: TBinMemoryReader
);
96 procedure positionChanged (); inline;
98 function isGBack (): Boolean; inline; // gRenderBackgrounds
99 function isGStep (): Boolean; inline; // gSteps
100 function isGWall (): Boolean; inline; // gWalls
101 function isGAcid1 (): Boolean; inline; // gAcid1
102 function isGAcid2 (): Boolean; inline; // gAcid2
103 function isGWater (): Boolean; inline; // gWater
104 function isGFore (): Boolean; inline; // gRenderForegrounds
105 function isGLift (): Boolean; inline; // gLifts
106 function isGBlockMon (): Boolean; inline; // gBlockMon
110 property visvalid
: Boolean read getvisvalid
; // panel is "visvalid" when it's width and height are positive
113 property guid
: Integer read mGUID
; // will be assigned in "g_map.pas"
114 property x0
: Integer read FX
;
115 property y0
: Integer read FY
;
116 property x1
: Integer read getx1
; // inclusive!
117 property y1
: Integer read gety1
; // inclusive!
118 property x
: Integer read FX write FX
;
119 property y
: Integer read FY write FY
;
120 property width
: Word read FWidth write FWidth
;
121 property height
: Word read FHeight write FHeight
;
122 property panelType
: Word read FPanelType write FPanelType
;
123 property saveIt
: Boolean read FSaveIt write FSaveIt
; // Ñîõðàíÿòü ïðè SaveState?
124 property enabled
: Boolean read FEnabled write FEnabled
; // Ñîõðàíÿòü ïðè SaveState?
125 property door
: Boolean read FDoor write FDoor
; // Ñîõðàíÿòü ïðè SaveState?
126 property moved
: Boolean read FMoved write FMoved
; // Ñîõðàíÿòü ïðè SaveState?
127 property liftType
: Byte read FLiftType write FLiftType
; // Ñîõðàíÿòü ïðè SaveState?
128 property lastAnimLoop
: Byte read FLastAnimLoop write FLastAnimLoop
; // Ñîõðàíÿòü ïðè SaveState?
130 property movingActive
: Boolean read mMovingActive write mMovingActive
;
133 property movingSpeed
: TDFPoint read mMovingSpeed write mMovingSpeed
;
134 property movingStart
: TDFPoint read mMovingStart write mMovingStart
;
135 property movingEnd
: TDFPoint read mMovingEnd write mMovingEnd
;
138 TPanelArray
= Array of TPanel
;
143 SysUtils
, g_basic
, g_map
, g_game
, g_gfx
, e_graphics
,
144 g_console
, g_language
, g_monsters
, g_player
, e_log
, GL
;
147 PANEL_SIGNATURE
= $4C4E4150; // 'PANL'
151 constructor TPanel
.Create(PanelRec
: TDynRecord
;
152 AddTextures
: TAddTextureArray
;
154 var Textures
: TLevelTextureArray
; aguid
: Integer);
160 Width
:= PanelRec
.Width
;
161 Height
:= PanelRec
.Height
;
169 mapId
:= PanelRec
.id
;
172 mMovingSpeed
:= PanelRec
.moveSpeed
;
173 mMovingStart
:= PanelRec
.moveStart
;
174 mMovingEnd
:= PanelRec
.moveEnd
;
175 mMovingActive
:= PanelRec
['move_active'].varvalue
;
178 PanelType
:= PanelRec
.PanelType
;
216 if ByteBool(PanelRec
.Flags
and PANEL_FLAG_HIDE
) then
218 SetLength(FTextureIDs
, 0);
222 // Ïàíåëè, íå èñïîëüçóþùèå òåêñòóðû:
223 if ByteBool(PanelType
and
228 PANEL_BLOCKMON
)) then
230 SetLength(FTextureIDs
, 0);
235 // Åñëè ýòî æèäêîñòü áåç òåêñòóðû - ñïåöòåêñòóðó:
236 if WordBool(PanelType
and (PANEL_WATER
or PANEL_ACID1
or PANEL_ACID2
)) and
237 (not ByteBool(PanelRec
.Flags
and PANEL_FLAG_WATERTEXTURES
)) then
239 SetLength(FTextureIDs
, 1);
240 FTextureIDs
[0].Anim
:= False;
242 case PanelRec
.PanelType
of
244 FTextureIDs
[0].Tex
:= LongWord(TEXTURE_SPECIAL_WATER
);
246 FTextureIDs
[0].Tex
:= LongWord(TEXTURE_SPECIAL_ACID1
);
248 FTextureIDs
[0].Tex
:= LongWord(TEXTURE_SPECIAL_ACID2
);
255 SetLength(FTextureIDs
, Length(AddTextures
));
260 if CurTex
>= Length(FTextureIDs
) then
261 FCurTexture
:= Length(FTextureIDs
) - 1
263 FCurTexture
:= CurTex
;
265 for i
:= 0 to Length(FTextureIDs
)-1 do
267 FTextureIDs
[i
].Anim
:= AddTextures
[i
].Anim
;
268 if FTextureIDs
[i
].Anim
then
269 begin // Àíèìèðîâàííàÿ òåêñòóðà
270 FTextureIDs
[i
].AnTex
:=
271 TAnimation
.Create(Textures
[AddTextures
[i
].Texture
].FramesID
,
272 True, Textures
[AddTextures
[i
].Texture
].Speed
);
273 FTextureIDs
[i
].AnTex
.Blending
:= ByteBool(PanelRec
.Flags
and PANEL_FLAG_BLENDING
);
274 FTextureIDs
[i
].AnTex
.Alpha
:= PanelRec
.Alpha
;
278 begin // Îáû÷íàÿ òåêñòóðà
279 FTextureIDs
[i
].Tex
:= Textures
[AddTextures
[i
].Texture
].TextureID
;
283 // Òåêñòóð íåñêîëüêî - íóæíî ñîõðàíÿòü òåêóùóþ:
284 if Length(FTextureIDs
) > 1 then
287 // Åñëè íå ñïåöòåêñòóðà, òî çàäàåì ðàçìåðû:
288 if PanelRec
.TextureNum
> High(Textures
) then
290 e_WriteLog(Format('WTF?! PanelRec.TextureNum is out of limits! (%d : %d)', [PanelRec
.TextureNum
, High(Textures
)]), MSG_FATALERROR
);
294 FBlending
:= ByteBool(0);
296 else if not g_Map_IsSpecialTexture(Textures
[PanelRec
.TextureNum
].TextureName
) then
298 FTextureWidth
:= Textures
[PanelRec
.TextureNum
].Width
;
299 FTextureHeight
:= Textures
[PanelRec
.TextureNum
].Height
;
300 FAlpha
:= PanelRec
.Alpha
;
301 FBlending
:= ByteBool(PanelRec
.Flags
and PANEL_FLAG_BLENDING
);
305 destructor TPanel
.Destroy();
309 for i
:= 0 to High(FTextureIDs
) do
310 if FTextureIDs
[i
].Anim
then
311 FTextureIDs
[i
].AnTex
.Free();
312 SetLength(FTextureIDs
, 0);
317 function TPanel
.getx1 (): Integer; inline; begin result
:= X
+Width
-1; end;
318 function TPanel
.gety1 (): Integer; inline; begin result
:= Y
+Height
-1; end;
319 function TPanel
.getvisvalid (): Boolean; inline; begin result
:= (Width
> 0) and (Height
> 0); end;
321 function TPanel
.isGBack (): Boolean; inline; begin result
:= ((tag
and GridTagBack
) <> 0); end;
322 function TPanel
.isGStep (): Boolean; inline; begin result
:= ((tag
and GridTagStep
) <> 0); end;
323 function TPanel
.isGWall (): Boolean; inline; begin result
:= ((tag
and (GridTagWall
or GridTagDoor
)) <> 0); end;
324 function TPanel
.isGAcid1 (): Boolean; inline; begin result
:= ((tag
and GridTagAcid1
) <> 0); end;
325 function TPanel
.isGAcid2 (): Boolean; inline; begin result
:= ((tag
and GridTagAcid2
) <> 0); end;
326 function TPanel
.isGWater (): Boolean; inline; begin result
:= ((tag
and GridTagWater
) <> 0); end;
327 function TPanel
.isGFore (): Boolean; inline; begin result
:= ((tag
and GridTagFore
) <> 0); end;
328 function TPanel
.isGLift (): Boolean; inline; begin result
:= ((tag
and GridTagLift
) <> 0); end;
329 function TPanel
.isGBlockMon (): Boolean; inline; begin result
:= ((tag
and GridTagBlockMon
) <> 0); end;
331 procedure TPanel
.Draw();
337 if {Enabled and} (FCurTexture
>= 0) and
338 (Width
> 0) and (Height
> 0) and (FAlpha
< 255) and
339 ((g_dbg_scale
<> 1.0) or g_Collide(X
, Y
, Width
, Height
, sX
, sY
, sWidth
, sHeight
)) then
341 if FTextureIDs
[FCurTexture
].Anim
then
342 begin // Àíèìèðîâàííàÿ òåêñòóðà
343 if FTextureIDs
[FCurTexture
].AnTex
= nil then
346 for xx
:= 0 to (Width
div FTextureWidth
)-1 do
347 for yy
:= 0 to (Height
div FTextureHeight
)-1 do
348 FTextureIDs
[FCurTexture
].AnTex
.Draw(
349 X
+ xx
*FTextureWidth
,
350 Y
+ yy
*FTextureHeight
, M_NONE
);
353 begin // Îáû÷íàÿ òåêñòóðà
354 case FTextureIDs
[FCurTexture
].Tex
of
355 LongWord(TEXTURE_SPECIAL_WATER
):
356 e_DrawFillQuad(X
, Y
, X
+Width
-1, Y
+Height
-1,
357 0, 0, 255, 0, B_FILTER
);
358 LongWord(TEXTURE_SPECIAL_ACID1
):
359 e_DrawFillQuad(X
, Y
, X
+Width
-1, Y
+Height
-1,
360 0, 128, 0, 0, B_FILTER
);
361 LongWord(TEXTURE_SPECIAL_ACID2
):
362 e_DrawFillQuad(X
, Y
, X
+Width
-1, Y
+Height
-1,
363 128, 0, 0, 0, B_FILTER
);
364 LongWord(TEXTURE_NONE
):
365 if g_Texture_Get('NOTEXTURE', NoTextureID
) then
367 e_GetTextureSize(NoTextureID
, @NW
, @NH
);
368 e_DrawFill(NoTextureID
, X
, Y
, Width
div NW
, Height
div NH
,
372 xx
:= X
+ (Width
div 2);
373 yy
:= Y
+ (Height
div 2);
374 e_DrawFillQuad(X
, Y
, xx
, yy
,
376 e_DrawFillQuad(xx
, Y
, X
+Width
-1, yy
,
378 e_DrawFillQuad(X
, yy
, xx
, Y
+Height
-1,
380 e_DrawFillQuad(xx
, yy
, X
+Width
-1, Y
+Height
-1,
385 e_DrawFill(FTextureIDs
[FCurTexture
].Tex
, X
, Y
,
386 Width
div FTextureWidth
,
387 Height
div FTextureHeight
,
388 FAlpha
, True, FBlending
);
394 procedure TPanel
.DrawShadowVolume(lightX
: Integer; lightY
: Integer; radius
: Integer);
395 procedure extrude (x
: Integer; y
: Integer);
397 glVertex2i(x
+(x
-lightX
)*500, y
+(y
-lightY
)*500);
398 //e_WriteLog(Format(' : (%d,%d)', [x+(x-lightX)*300, y+(y-lightY)*300]), MSG_WARNING);
401 procedure drawLine (x0
: Integer; y0
: Integer; x1
: Integer; y1
: Integer);
403 // does this side facing the light?
404 if ((x1
-x0
)*(lightY
-y0
)-(lightX
-x0
)*(y1
-y0
) >= 0) then exit
;
405 //e_WriteLog(Format('lightpan: (%d,%d)-(%d,%d)', [x0, y0, x1, y1]), MSG_WARNING);
406 // this edge is facing the light, extrude and draw it
414 if radius
< 4 then exit
;
415 if Enabled
and (FCurTexture
>= 0) and (Width
> 0) and (Height
> 0) and (FAlpha
< 255) and g_Collide(X
, Y
, Width
, Height
, sX
, sY
, sWidth
, sHeight
) then
417 if not FTextureIDs
[FCurTexture
].Anim
then
419 case FTextureIDs
[FCurTexture
].Tex
of
420 LongWord(TEXTURE_SPECIAL_WATER
): exit
;
421 LongWord(TEXTURE_SPECIAL_ACID1
): exit
;
422 LongWord(TEXTURE_SPECIAL_ACID2
): exit
;
423 LongWord(TEXTURE_NONE
): exit
;
426 if (X
+Width
< lightX
-radius
) then exit
;
427 if (Y
+Height
< lightY
-radius
) then exit
;
428 if (X
> lightX
+radius
) then exit
;
429 if (Y
> lightY
+radius
) then exit
;
430 //e_DrawFill(FTextureIDs[FCurTexture].Tex, X, Y, Width div FTextureWidth, Height div FTextureHeight, FAlpha, True, FBlending);
433 drawLine(x
, y
, x
+width
, y
); // top
434 drawLine(x
+width
, y
, x
+width
, y
+height
); // right
435 drawLine(x
+width
, y
+height
, x
, y
+height
); // bottom
436 drawLine(x
, y
+height
, x
, y
); // left
442 procedure TPanel
.positionChanged (); inline;
444 if (proxyId
>= 0) then mapGrid
.moveBody(proxyId
, X
, Y
);
449 monMoveList
: array of TMonster
= nil;
450 monMoveListUsed
: Integer = 0;
452 procedure TPanel
.Update();
457 function doPush (px
, py
, pw
, ph
: Integer; out dx
, dy
: Integer): Boolean;
459 result
:= g_Collide(px
, py
, pw
, ph
, nx
, ny
, Width
, Height
);
463 if (mMovingSpeed
.X
< 0) then dx
:= nx
-(px
+pw
)
464 else if (mMovingSpeed
.X
> 0) then dx
:= (nx
+Width
)-px
466 if (mMovingSpeed
.Y
< 0) then dy
:= ny
-(py
+ph
)
467 else if (mMovingSpeed
.Y
> 0) then dy
:= (ny
+Height
)-py
477 function monMove (mon
: TMonster
): Boolean;
479 result
:= false; // don't stop
480 mon
.GameX
:= mon
.GameX
+mMovingSpeed
.X
;
481 mon
.GameY
:= mon
.GameY
+mMovingSpeed
.Y
;
482 if (monMoveListUsed
>= Length(monMoveList
)) then SetLength(monMoveList
, monMoveListUsed
+64);
483 monMoveList
[monMoveListUsed
] := mon
;
484 Inc(monMoveListUsed
);
487 function monPush (mon
: TMonster
): Boolean;
489 px
, py
, pw
, ph
, dx
, dy
: Integer;
491 result
:= false; // don't stop
492 mon
.getMapBox(px
, py
, pw
, ph
);
493 if doPush(px
, py
, pw
, ph
, dx
, dy
) then
495 mon
.GameX
:= mon
.GameX
+dx
;
496 mon
.GameY
:= mon
.GameY
+dy
;
497 if (monMoveListUsed
>= Length(monMoveList
)) then SetLength(monMoveList
, monMoveListUsed
+64);
498 monMoveList
[monMoveListUsed
] := mon
;
499 Inc(monMoveListUsed
);
503 procedure plrMove (plr
: TPlayer
);
505 px
, py
, pw
, ph
, dx
, dy
: Integer;
507 if (plr
= nil) then exit
;
508 plr
.getMapBox(px
, py
, pw
, ph
);
512 if doPush(px
, py
, pw
, ph
, dx
, dy
) then
514 plr
.GameX
:= plr
.GameX
+dx
;
515 plr
.GameY
:= plr
.GameY
+dy
;
516 plr
.positionChanged();
520 if (px
+pw
<= X
) then exit
;
521 if (px
>= X
+Width
) then exit
;
522 plr
.GameX
:= plr
.GameX
+mMovingSpeed
.X
;
523 plr
.GameY
:= plr
.GameY
+mMovingSpeed
.Y
;
524 plr
.positionChanged();
528 if Enabled
and (FCurTexture
>= 0) and
529 (FTextureIDs
[FCurTexture
].Anim
) and
530 (FTextureIDs
[FCurTexture
].AnTex
<> nil) and
531 (Width
> 0) and (Height
> 0) and (FAlpha
< 255) then
533 FTextureIDs
[FCurTexture
].AnTex
.Update();
534 FCurFrame
:= FTextureIDs
[FCurTexture
].AnTex
.CurrentFrame
;
535 FCurFrameCount
:= FTextureIDs
[FCurTexture
].AnTex
.CurrentCounter
;
538 if mMovingActive
and (not mMovingSpeed
.isZero
) then
540 monMoveListUsed
:= 0;
541 nx
:= X
+mMovingSpeed
.X
;
542 ny
:= Y
+mMovingSpeed
.Y
;
543 // move monsters on lifts
544 g_Mons_ForEachAt(X
, Y
-1, Width
, 1, monMove
);
546 g_Mons_ForEachAt(nx
, ny
, Width
, Height
, monPush
);
547 // move and push players
548 for f
:= 0 to High(gPlayers
) do plrMove(gPlayers
[f
]);
549 // reverse moving direction, if necessary
550 if (mMovingSpeed
.X
< 0) and (nx
<= mMovingStart
.X
) then mMovingSpeed
.X
:= -mMovingSpeed
.X
551 else if (mMovingSpeed
.X
> 0) and (nx
>= mMovingEnd
.X
) then mMovingSpeed
.X
:= -mMovingSpeed
.X
;
552 if (mMovingSpeed
.Y
< 0) and (ny
<= mMovingStart
.Y
) then mMovingSpeed
.Y
:= -mMovingSpeed
.Y
553 else if (mMovingSpeed
.Y
> 0) and (ny
>= mMovingEnd
.Y
) then mMovingSpeed
.Y
:= -mMovingSpeed
.Y
;
555 g_Mark(X
, Y
, Width
, Height
, MARK_WALL
, false);
558 g_Mark(nx
, ny
, Width
, Height
, MARK_WALL
);
561 // notify moved monsters about their movement
562 for f
:= 0 to monMoveListUsed
-1 do monMoveList
[f
].positionChanged();
566 procedure TPanel
.SetFrame(Frame
: Integer; Count
: Byte);
568 function ClampInt(X
, A
, B
: Integer): Integer;
571 if X
< A
then Result
:= A
else if X
> B
then Result
:= B
;
575 if Enabled
and (FCurTexture
>= 0) and
576 (FTextureIDs
[FCurTexture
].Anim
) and
577 (FTextureIDs
[FCurTexture
].AnTex
<> nil) and
578 (Width
> 0) and (Height
> 0) and (FAlpha
< 255) then
580 FCurFrame
:= ClampInt(Frame
, 0, FTextureIDs
[FCurTexture
].AnTex
.TotalFrames
);
581 FCurFrameCount
:= Count
;
582 FTextureIDs
[FCurTexture
].AnTex
.CurrentFrame
:= FCurFrame
;
583 FTextureIDs
[FCurTexture
].AnTex
.CurrentCounter
:= FCurFrameCount
;
587 procedure TPanel
.NextTexture(AnimLoop
: Byte = 0);
589 Assert(FCurTexture
>= -1, 'FCurTexture < -1');
592 if Length(FTextureIDs
) = 0 then
595 // Òîëüêî îäíà òåêñòóðà:
596 if Length(FTextureIDs
) = 1 then
598 if FCurTexture
= 0 then
604 // Áîëüøå îäíîé òåêñòóðû:
608 // Ñëåäóþùåé íåò - âîçâðàò ê íà÷àëó:
609 if FCurTexture
>= Length(FTextureIDs
) then
613 // Ïåðåêëþ÷èëèñü íà âèäèìóþ àíèì. òåêñòóðó:
614 if (FCurTexture
>= 0) and FTextureIDs
[FCurTexture
].Anim
then
616 if (FTextureIDs
[FCurTexture
].AnTex
= nil) then
618 g_FatalError(_lc
[I_GAME_ERROR_SWITCH_TEXTURE
]);
623 FTextureIDs
[FCurTexture
].AnTex
.Loop
:= True
626 FTextureIDs
[FCurTexture
].AnTex
.Loop
:= False;
628 FTextureIDs
[FCurTexture
].AnTex
.Reset();
631 LastAnimLoop
:= AnimLoop
;
634 procedure TPanel
.SetTexture(ID
: Integer; AnimLoop
: Byte = 0);
637 if Length(FTextureIDs
) = 0 then
640 // Òîëüêî îäíà òåêñòóðà:
641 if Length(FTextureIDs
) = 1 then
643 if (ID
= 0) or (ID
= -1) then
647 // Áîëüøå îäíîé òåêñòóðû:
649 if (ID
>= -1) and (ID
<= High(FTextureIDs
)) then
653 // Ïåðåêëþ÷èëèñü íà âèäèìóþ àíèì. òåêñòóðó:
654 if (FCurTexture
>= 0) and FTextureIDs
[FCurTexture
].Anim
then
656 if (FTextureIDs
[FCurTexture
].AnTex
= nil) then
658 g_FatalError(_lc
[I_GAME_ERROR_SWITCH_TEXTURE
]);
663 FTextureIDs
[FCurTexture
].AnTex
.Loop
:= True
666 FTextureIDs
[FCurTexture
].AnTex
.Loop
:= False;
668 FTextureIDs
[FCurTexture
].AnTex
.Reset();
671 LastAnimLoop
:= AnimLoop
;
674 function TPanel
.GetTextureID(): DWORD
;
676 Result
:= LongWord(TEXTURE_NONE
);
678 if (FCurTexture
>= 0) then
680 if FTextureIDs
[FCurTexture
].Anim
then
681 Result
:= FTextureIDs
[FCurTexture
].AnTex
.FramesID
683 Result
:= FTextureIDs
[FCurTexture
].Tex
;
687 function TPanel
.GetTextureCount(): Integer;
689 Result
:= Length(FTextureIDs
);
690 if Enabled
and (FCurTexture
>= 0) then
691 if (FTextureIDs
[FCurTexture
].Anim
) and
692 (FTextureIDs
[FCurTexture
].AnTex
<> nil) and
693 (Width
> 0) and (Height
> 0) and (FAlpha
< 255) then
694 Result
:= Result
+ 100;
697 procedure TPanel
.SaveState(Var Mem
: TBinMemoryWriter
);
702 if (Mem
= nil) then exit
;
703 //if not SaveIt then exit;
706 sig
:= PANEL_SIGNATURE
; // 'PANL'
708 // Îòêðûòà/çàêðûòà, åñëè äâåðü:
709 Mem
.WriteBoolean(FEnabled
);
710 // Íàïðàâëåíèå ëèôòà, åñëè ëèôò:
711 Mem
.WriteByte(FLiftType
);
712 // Íîìåð òåêóùåé òåêñòóðû:
713 Mem
.WriteInt(FCurTexture
);
717 // Àíèìèðîâàííàÿ ëè òåêóùàÿ òåêñòóðà:
718 if (FCurTexture
>= 0) and (FTextureIDs
[FCurTexture
].Anim
) then
720 Assert(FTextureIDs
[FCurTexture
].AnTex
<> nil,
721 'TPanel.SaveState: No animation object');
726 Mem
.WriteBoolean(anim
);
727 // Åñëè äà - ñîõðàíÿåì àíèìàöèþ:
729 FTextureIDs
[FCurTexture
].AnTex
.SaveState(Mem
);
730 // moving platform state
731 Mem
.WriteInt(mMovingSpeed
.X
);
732 Mem
.WriteInt(mMovingSpeed
.Y
);
733 Mem
.WriteInt(mMovingStart
.X
);
734 Mem
.WriteInt(mMovingStart
.Y
);
735 Mem
.WriteInt(mMovingEnd
.X
);
736 Mem
.WriteInt(mMovingEnd
.Y
);
737 Mem
.WriteBoolean(mMovingActive
);
740 procedure TPanel
.LoadState(var Mem
: TBinMemoryReader
);
746 if (Mem
= nil) then exit
;
747 //if not SaveIt then exit;
751 if sig
<> PANEL_SIGNATURE
then // 'PANL'
753 raise EBinSizeError
.Create('TPanel.LoadState: Wrong Panel Signature');
755 // Îòêðûòà/çàêðûòà, åñëè äâåðü:
756 Mem
.ReadBoolean(FEnabled
);
757 // Íàïðàâëåíèå ëèôòà, åñëè ëèôò:
758 Mem
.ReadByte(FLiftType
);
759 // Íîìåð òåêóùåé òåêñòóðû:
760 Mem
.ReadInt(FCurTexture
);
766 //e_LogWritefln('panel %s(%s): old=(%s,%s); new=(%s,%s); delta=(%s,%s)', [arrIdx, proxyId, ox, oy, FX, FY, FX-ox, FY-oy]);
767 // Àíèìèðîâàííàÿ ëè òåêóùàÿ òåêñòóðà:
768 Mem
.ReadBoolean(anim
);
769 // Åñëè äà - çàãðóæàåì àíèìàöèþ:
772 Assert((FCurTexture
>= 0) and
773 (FTextureIDs
[FCurTexture
].Anim
) and
774 (FTextureIDs
[FCurTexture
].AnTex
<> nil),
775 'TPanel.LoadState: No animation object');
776 FTextureIDs
[FCurTexture
].AnTex
.LoadState(Mem
);
778 // moving platform state
779 Mem
.ReadInt(mMovingSpeed
.X
);
780 Mem
.ReadInt(mMovingSpeed
.Y
);
781 Mem
.ReadInt(mMovingStart
.X
);
782 Mem
.ReadInt(mMovingStart
.Y
);
783 Mem
.ReadInt(mMovingEnd
.X
);
784 Mem
.ReadInt(mMovingEnd
.Y
);
785 Mem
.ReadBoolean(mMovingActive
);
788 mapGrid
.proxyEnabled
[proxyId
] := FEnabled
;