DEADSOFTWARE

"dbg_scale" debug variable
[d2df-sdl.git] / src / game / g_panel.pas
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 {$M+}
18 unit g_panel;
20 interface
22 uses
23 MAPDEF, BinEditor, g_textures, xdynrec;
25 type
26 TAddTextureArray = Array of
27 record
28 Texture: Cardinal;
29 Anim: Boolean;
30 end;
32 TPanel = Class (TObject)
33 private
34 FTextureWidth: Word;
35 FTextureHeight: Word;
36 FAlpha: Byte;
37 FBlending: Boolean;
38 FTextureIDs: Array of
39 record
40 case Anim: Boolean of
41 False: (Tex: Cardinal);
42 True: (AnTex: TAnimation);
43 end;
45 mMovingSpeed: TDFPoint;
46 mMovingStart: TDFPoint;
47 mMovingEnd: TDFPoint;
48 mMovingActive: Boolean;
50 private
51 function getx1 (): Integer; inline;
52 function gety1 (): Integer; inline;
53 function getvisvalid (): Boolean; inline;
55 public
56 FCurTexture: Integer; // Íîìåð òåêóùåé òåêñòóðû
57 FCurFrame: Integer;
58 FCurFrameCount: Byte;
59 FX, FY: Integer;
60 FWidth, FHeight: Word;
61 FPanelType: Word;
62 FSaveIt: Boolean; // Ñîõðàíÿòü ïðè SaveState?
63 FEnabled: Boolean;
64 FDoor: Boolean;
65 FMoved: Boolean;
66 FLiftType: Byte;
67 FLastAnimLoop: Byte;
68 arrIdx: Integer; // index in one of internal arrays; sorry
69 tag: Integer; // used in coldets and such; sorry
70 proxyId: Integer; // proxy id in map grid (DO NOT USE!)
72 constructor Create(PanelRec: TDynRecord;
73 AddTextures: TAddTextureArray;
74 CurTex: Integer;
75 var Textures: TLevelTextureArray);
76 destructor Destroy(); override;
78 procedure Draw();
79 procedure DrawShadowVolume(lightX: Integer; lightY: Integer; radius: Integer);
80 procedure Update();
81 procedure SetFrame(Frame: Integer; Count: Byte);
82 procedure NextTexture(AnimLoop: Byte = 0);
83 procedure SetTexture(ID: Integer; AnimLoop: Byte = 0);
84 function GetTextureID(): Cardinal;
85 function GetTextureCount(): Integer;
87 procedure SaveState(var Mem: TBinMemoryWriter);
88 procedure LoadState(var Mem: TBinMemoryReader);
90 public
91 property visvalid: Boolean read getvisvalid; // panel is "visvalid" when it's width and height are positive
93 published
94 property x0: Integer read FX;
95 property y0: Integer read FY;
96 property x1: Integer read getx1; // inclusive!
97 property y1: Integer read gety1; // inclusive!
98 property x: Integer read FX write FX;
99 property y: Integer read FY write FY;
100 property width: Word read FWidth write FWidth;
101 property height: Word read FHeight write FHeight;
102 property panelType: Word read FPanelType write FPanelType;
103 property saveIt: Boolean read FSaveIt write FSaveIt; // Ñîõðàíÿòü ïðè SaveState?
104 property enabled: Boolean read FEnabled write FEnabled; // Ñîõðàíÿòü ïðè SaveState?
105 property door: Boolean read FDoor write FDoor; // Ñîõðàíÿòü ïðè SaveState?
106 property moved: Boolean read FMoved write FMoved; // Ñîõðàíÿòü ïðè SaveState?
107 property liftType: Byte read FLiftType write FLiftType; // Ñîõðàíÿòü ïðè SaveState?
108 property lastAnimLoop: Byte read FLastAnimLoop write FLastAnimLoop; // Ñîõðàíÿòü ïðè SaveState?
110 property movingActive: Boolean read mMovingActive write mMovingActive;
112 public
113 property movingSpeed: TDFPoint read mMovingSpeed write mMovingSpeed;
114 property movingStart: TDFPoint read mMovingStart write mMovingStart;
115 property movingEnd: TDFPoint read mMovingEnd write mMovingEnd;
116 end;
118 TPanelArray = Array of TPanel;
120 implementation
122 uses
123 SysUtils, g_basic, g_map, g_game, g_gfx, e_graphics,
124 g_console, g_language, g_monsters, g_player, e_log, GL;
126 const
127 PANEL_SIGNATURE = $4C4E4150; // 'PANL'
129 { T P a n e l : }
131 constructor TPanel.Create(PanelRec: TDynRecord;
132 AddTextures: TAddTextureArray;
133 CurTex: Integer;
134 var Textures: TLevelTextureArray);
135 var
136 i: Integer;
137 begin
138 X := PanelRec.X;
139 Y := PanelRec.Y;
140 Width := PanelRec.Width;
141 Height := PanelRec.Height;
142 FAlpha := 0;
143 FBlending := False;
144 FCurFrame := 0;
145 FCurFrameCount := 0;
146 LastAnimLoop := 0;
147 Moved := False;
149 mMovingSpeed := PanelRec.moveSpeed;
150 mMovingStart := PanelRec.moveStart;
151 mMovingEnd := PanelRec.moveEnd;
152 mMovingActive := PanelRec['move_active'].varvalue;
154 // Òèï ïàíåëè:
155 PanelType := PanelRec.PanelType;
156 Enabled := True;
157 Door := False;
158 LiftType := 0;
159 SaveIt := False;
161 case PanelType of
162 PANEL_OPENDOOR:
163 begin
164 Enabled := False;
165 Door := True;
166 SaveIt := True;
167 end;
168 PANEL_CLOSEDOOR:
169 begin
170 Door := True;
171 SaveIt := True;
172 end;
173 PANEL_LIFTUP:
174 SaveIt := True;
175 PANEL_LIFTDOWN:
176 begin
177 LiftType := 1;
178 SaveIt := True;
179 end;
180 PANEL_LIFTLEFT:
181 begin
182 LiftType := 2;
183 SaveIt := True;
184 end;
185 PANEL_LIFTRIGHT:
186 begin
187 LiftType := 3;
188 SaveIt := True;
189 end;
190 end;
192 // Íåâèäèìàÿ:
193 if ByteBool(PanelRec.Flags and PANEL_FLAG_HIDE) then
194 begin
195 SetLength(FTextureIDs, 0);
196 FCurTexture := -1;
197 Exit;
198 end;
199 // Ïàíåëè, íå èñïîëüçóþùèå òåêñòóðû:
200 if ByteBool(PanelType and
201 (PANEL_LIFTUP or
202 PANEL_LIFTDOWN or
203 PANEL_LIFTLEFT or
204 PANEL_LIFTRIGHT or
205 PANEL_BLOCKMON)) then
206 begin
207 SetLength(FTextureIDs, 0);
208 FCurTexture := -1;
209 Exit;
210 end;
212 // Åñëè ýòî æèäêîñòü áåç òåêñòóðû - ñïåöòåêñòóðó:
213 if WordBool(PanelType and (PANEL_WATER or PANEL_ACID1 or PANEL_ACID2)) and
214 (not ByteBool(PanelRec.Flags and PANEL_FLAG_WATERTEXTURES)) then
215 begin
216 SetLength(FTextureIDs, 1);
217 FTextureIDs[0].Anim := False;
219 case PanelRec.PanelType of
220 PANEL_WATER:
221 FTextureIDs[0].Tex := LongWord(TEXTURE_SPECIAL_WATER);
222 PANEL_ACID1:
223 FTextureIDs[0].Tex := LongWord(TEXTURE_SPECIAL_ACID1);
224 PANEL_ACID2:
225 FTextureIDs[0].Tex := LongWord(TEXTURE_SPECIAL_ACID2);
226 end;
228 FCurTexture := 0;
229 Exit;
230 end;
232 SetLength(FTextureIDs, Length(AddTextures));
234 if CurTex < 0 then
235 FCurTexture := -1
236 else
237 if CurTex >= Length(FTextureIDs) then
238 FCurTexture := Length(FTextureIDs) - 1
239 else
240 FCurTexture := CurTex;
242 for i := 0 to Length(FTextureIDs)-1 do
243 begin
244 FTextureIDs[i].Anim := AddTextures[i].Anim;
245 if FTextureIDs[i].Anim then
246 begin // Àíèìèðîâàííàÿ òåêñòóðà
247 FTextureIDs[i].AnTex :=
248 TAnimation.Create(Textures[AddTextures[i].Texture].FramesID,
249 True, Textures[AddTextures[i].Texture].Speed);
250 FTextureIDs[i].AnTex.Blending := ByteBool(PanelRec.Flags and PANEL_FLAG_BLENDING);
251 FTextureIDs[i].AnTex.Alpha := PanelRec.Alpha;
252 SaveIt := True;
253 end
254 else
255 begin // Îáû÷íàÿ òåêñòóðà
256 FTextureIDs[i].Tex := Textures[AddTextures[i].Texture].TextureID;
257 end;
258 end;
260 // Òåêñòóð íåñêîëüêî - íóæíî ñîõðàíÿòü òåêóùóþ:
261 if Length(FTextureIDs) > 1 then
262 SaveIt := True;
264 // Åñëè íå ñïåöòåêñòóðà, òî çàäàåì ðàçìåðû:
265 if PanelRec.TextureNum > High(Textures) then
266 begin
267 e_WriteLog(Format('WTF?! PanelRec.TextureNum is out of limits! (%d : %d)', [PanelRec.TextureNum, High(Textures)]), MSG_FATALERROR);
268 FTextureWidth := 2;
269 FTextureHeight := 2;
270 FAlpha := 0;
271 FBlending := ByteBool(0);
272 end
273 else if not g_Map_IsSpecialTexture(Textures[PanelRec.TextureNum].TextureName) then
274 begin
275 FTextureWidth := Textures[PanelRec.TextureNum].Width;
276 FTextureHeight := Textures[PanelRec.TextureNum].Height;
277 FAlpha := PanelRec.Alpha;
278 FBlending := ByteBool(PanelRec.Flags and PANEL_FLAG_BLENDING);
279 end;
280 end;
282 destructor TPanel.Destroy();
283 var
284 i: Integer;
285 begin
286 for i := 0 to High(FTextureIDs) do
287 if FTextureIDs[i].Anim then
288 FTextureIDs[i].AnTex.Free();
289 SetLength(FTextureIDs, 0);
291 Inherited;
292 end;
294 function TPanel.getx1 (): Integer; inline; begin result := X+Width-1; end;
295 function TPanel.gety1 (): Integer; inline; begin result := Y+Height-1; end;
296 function TPanel.getvisvalid (): Boolean; inline; begin result := (Width > 0) and (Height > 0); end;
298 procedure TPanel.Draw();
299 var
300 xx, yy: Integer;
301 NoTextureID: DWORD;
302 NW, NH: Word;
303 begin
304 if {Enabled and} (FCurTexture >= 0) and
305 (Width > 0) and (Height > 0) and (FAlpha < 255) and
306 ((g_dbg_scale <> 1.0) or g_Collide(X, Y, Width, Height, sX, sY, sWidth, sHeight)) then
307 begin
308 if FTextureIDs[FCurTexture].Anim then
309 begin // Àíèìèðîâàííàÿ òåêñòóðà
310 if FTextureIDs[FCurTexture].AnTex = nil then
311 Exit;
313 for xx := 0 to (Width div FTextureWidth)-1 do
314 for yy := 0 to (Height div FTextureHeight)-1 do
315 FTextureIDs[FCurTexture].AnTex.Draw(
316 X + xx*FTextureWidth,
317 Y + yy*FTextureHeight, M_NONE);
318 end
319 else
320 begin // Îáû÷íàÿ òåêñòóðà
321 case FTextureIDs[FCurTexture].Tex of
322 LongWord(TEXTURE_SPECIAL_WATER):
323 e_DrawFillQuad(X, Y, X+Width-1, Y+Height-1,
324 0, 0, 255, 0, B_FILTER);
325 LongWord(TEXTURE_SPECIAL_ACID1):
326 e_DrawFillQuad(X, Y, X+Width-1, Y+Height-1,
327 0, 128, 0, 0, B_FILTER);
328 LongWord(TEXTURE_SPECIAL_ACID2):
329 e_DrawFillQuad(X, Y, X+Width-1, Y+Height-1,
330 128, 0, 0, 0, B_FILTER);
331 LongWord(TEXTURE_NONE):
332 if g_Texture_Get('NOTEXTURE', NoTextureID) then
333 begin
334 e_GetTextureSize(NoTextureID, @NW, @NH);
335 e_DrawFill(NoTextureID, X, Y, Width div NW, Height div NH,
336 0, False, False);
337 end else
338 begin
339 xx := X + (Width div 2);
340 yy := Y + (Height div 2);
341 e_DrawFillQuad(X, Y, xx, yy,
342 255, 0, 255, 0);
343 e_DrawFillQuad(xx, Y, X+Width-1, yy,
344 255, 255, 0, 0);
345 e_DrawFillQuad(X, yy, xx, Y+Height-1,
346 255, 255, 0, 0);
347 e_DrawFillQuad(xx, yy, X+Width-1, Y+Height-1,
348 255, 0, 255, 0);
349 end;
351 else
352 e_DrawFill(FTextureIDs[FCurTexture].Tex, X, Y,
353 Width div FTextureWidth,
354 Height div FTextureHeight,
355 FAlpha, True, FBlending);
356 end;
357 end;
358 end;
359 end;
361 procedure TPanel.DrawShadowVolume(lightX: Integer; lightY: Integer; radius: Integer);
362 procedure extrude (x: Integer; y: Integer);
363 begin
364 glVertex2i(x+(x-lightX)*500, y+(y-lightY)*500);
365 //e_WriteLog(Format(' : (%d,%d)', [x+(x-lightX)*300, y+(y-lightY)*300]), MSG_WARNING);
366 end;
368 procedure drawLine (x0: Integer; y0: Integer; x1: Integer; y1: Integer);
369 begin
370 // does this side facing the light?
371 if ((x1-x0)*(lightY-y0)-(lightX-x0)*(y1-y0) >= 0) then exit;
372 //e_WriteLog(Format('lightpan: (%d,%d)-(%d,%d)', [x0, y0, x1, y1]), MSG_WARNING);
373 // this edge is facing the light, extrude and draw it
374 glVertex2i(x0, y0);
375 glVertex2i(x1, y1);
376 extrude(x1, y1);
377 extrude(x0, y0);
378 end;
380 begin
381 if radius < 4 then exit;
382 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
383 begin
384 if not FTextureIDs[FCurTexture].Anim then
385 begin
386 case FTextureIDs[FCurTexture].Tex of
387 LongWord(TEXTURE_SPECIAL_WATER): exit;
388 LongWord(TEXTURE_SPECIAL_ACID1): exit;
389 LongWord(TEXTURE_SPECIAL_ACID2): exit;
390 LongWord(TEXTURE_NONE): exit;
391 end;
392 end;
393 if (X+Width < lightX-radius) then exit;
394 if (Y+Height < lightY-radius) then exit;
395 if (X > lightX+radius) then exit;
396 if (Y > lightY+radius) then exit;
397 //e_DrawFill(FTextureIDs[FCurTexture].Tex, X, Y, Width div FTextureWidth, Height div FTextureHeight, FAlpha, True, FBlending);
399 glBegin(GL_QUADS);
400 drawLine(x, y, x+width, y); // top
401 drawLine(x+width, y, x+width, y+height); // right
402 drawLine(x+width, y+height, x, y+height); // bottom
403 drawLine(x, y+height, x, y); // left
404 glEnd();
405 end;
406 end;
409 var
410 monMoveList: array of TMonster = nil;
411 monMoveListUsed: Integer = 0;
413 procedure TPanel.Update();
414 var
415 nx, ny: Integer;
416 f: Integer;
418 function doPush (px, py, pw, ph: Integer; out dx, dy: Integer): Boolean;
419 begin
420 result := g_Collide(px, py, pw, ph, nx, ny, Width, Height);
421 if result then
422 begin
423 // need to push
424 if (mMovingSpeed.X < 0) then dx := nx-(px+pw)
425 else if (mMovingSpeed.X > 0) then dx := (nx+Width)-px
426 else dx := 0;
427 if (mMovingSpeed.Y < 0) then dy := ny-(py+ph)
428 else if (mMovingSpeed.Y > 0) then dy := (ny+Height)-py
429 else dy := 0;
430 end
431 else
432 begin
433 dx := 0;
434 dy := 0;
435 end;
436 end;
438 function monMove (mon: TMonster): Boolean;
439 begin
440 result := false; // don't stop
441 mon.GameX := mon.GameX+mMovingSpeed.X;
442 mon.GameY := mon.GameY+mMovingSpeed.Y;
443 if (monMoveListUsed >= Length(monMoveList)) then SetLength(monMoveList, monMoveListUsed+64);
444 monMoveList[monMoveListUsed] := mon;
445 Inc(monMoveListUsed);
446 end;
448 function monPush (mon: TMonster): Boolean;
449 var
450 px, py, pw, ph, dx, dy: Integer;
451 begin
452 result := false; // don't stop
453 mon.getMapBox(px, py, pw, ph);
454 if doPush(px, py, pw, ph, dx, dy) then
455 begin
456 mon.GameX := mon.GameX+dx;
457 mon.GameY := mon.GameY+dy;
458 if (monMoveListUsed >= Length(monMoveList)) then SetLength(monMoveList, monMoveListUsed+64);
459 monMoveList[monMoveListUsed] := mon;
460 Inc(monMoveListUsed);
461 end;
462 end;
464 procedure plrMove (plr: TPlayer);
465 var
466 px, py, pw, ph, dx, dy: Integer;
467 begin
468 if (plr = nil) then exit;
469 plr.getMapBox(px, py, pw, ph);
470 if (py+ph <> Y) then
471 begin
472 // push player
473 if doPush(px, py, pw, ph, dx, dy) then
474 begin
475 plr.GameX := plr.GameX+dx;
476 plr.GameY := plr.GameY+dy;
477 plr.positionChanged();
478 end;
479 exit;
480 end;
481 if (px+pw <= X) then exit;
482 if (px >= X+Width) then exit;
483 plr.GameX := plr.GameX+mMovingSpeed.X;
484 plr.GameY := plr.GameY+mMovingSpeed.Y;
485 plr.positionChanged();
486 end;
488 begin
489 if Enabled and (FCurTexture >= 0) and
490 (FTextureIDs[FCurTexture].Anim) and
491 (FTextureIDs[FCurTexture].AnTex <> nil) and
492 (Width > 0) and (Height > 0) and (FAlpha < 255) then
493 begin
494 FTextureIDs[FCurTexture].AnTex.Update();
495 FCurFrame := FTextureIDs[FCurTexture].AnTex.CurrentFrame;
496 FCurFrameCount := FTextureIDs[FCurTexture].AnTex.CurrentCounter;
497 end;
499 if mMovingActive and (not mMovingSpeed.isZero) then
500 begin
501 monMoveListUsed := 0;
502 nx := X+mMovingSpeed.X;
503 ny := Y+mMovingSpeed.Y;
504 // move monsters on lifts
505 g_Mons_ForEachAt(X, Y-1, Width, 1, monMove);
506 // push monsters
507 g_Mons_ForEachAt(nx, ny, Width, Height, monPush);
508 // move and push players
509 for f := 0 to High(gPlayers) do plrMove(gPlayers[f]);
510 // reverse moving direction, if necessary
511 if (mMovingSpeed.X < 0) and (nx <= mMovingStart.X) then mMovingSpeed.X := -mMovingSpeed.X
512 else if (mMovingSpeed.X > 0) and (nx >= mMovingEnd.X) then mMovingSpeed.X := -mMovingSpeed.X;
513 if (mMovingSpeed.Y < 0) and (ny <= mMovingStart.Y) then mMovingSpeed.Y := -mMovingSpeed.Y
514 else if (mMovingSpeed.Y > 0) and (ny >= mMovingEnd.Y) then mMovingSpeed.Y := -mMovingSpeed.Y;
515 // awake particles
516 g_Mark(X, Y, Width, Height, MARK_WALL, false);
517 X := nx;
518 Y := ny;
519 g_Mark(nx, ny, Width, Height, MARK_WALL);
520 // fix grid
521 if (proxyId >= 0) then mapGrid.moveBody(proxyId, nx, ny);
522 // notify moved monsters about their movement
523 for f := 0 to monMoveListUsed-1 do monMoveList[f].positionChanged();
524 end;
525 end;
527 procedure TPanel.SetFrame(Frame: Integer; Count: Byte);
529 function ClampInt(X, A, B: Integer): Integer;
530 begin
531 Result := X;
532 if X < A then Result := A else if X > B then Result := B;
533 end;
535 begin
536 if Enabled and (FCurTexture >= 0) and
537 (FTextureIDs[FCurTexture].Anim) and
538 (FTextureIDs[FCurTexture].AnTex <> nil) and
539 (Width > 0) and (Height > 0) and (FAlpha < 255) then
540 begin
541 FCurFrame := ClampInt(Frame, 0, FTextureIDs[FCurTexture].AnTex.TotalFrames);
542 FCurFrameCount := Count;
543 FTextureIDs[FCurTexture].AnTex.CurrentFrame := FCurFrame;
544 FTextureIDs[FCurTexture].AnTex.CurrentCounter := FCurFrameCount;
545 end;
546 end;
548 procedure TPanel.NextTexture(AnimLoop: Byte = 0);
549 begin
550 Assert(FCurTexture >= -1, 'FCurTexture < -1');
552 // Íåò òåêñòóð:
553 if Length(FTextureIDs) = 0 then
554 FCurTexture := -1
555 else
556 // Òîëüêî îäíà òåêñòóðà:
557 if Length(FTextureIDs) = 1 then
558 begin
559 if FCurTexture = 0 then
560 FCurTexture := -1
561 else
562 FCurTexture := 0;
563 end
564 else
565 // Áîëüøå îäíîé òåêñòóðû:
566 begin
567 // Ñëåäóþùàÿ:
568 Inc(FCurTexture);
569 // Ñëåäóþùåé íåò - âîçâðàò ê íà÷àëó:
570 if FCurTexture >= Length(FTextureIDs) then
571 FCurTexture := 0;
572 end;
574 // Ïåðåêëþ÷èëèñü íà âèäèìóþ àíèì. òåêñòóðó:
575 if (FCurTexture >= 0) and FTextureIDs[FCurTexture].Anim then
576 begin
577 if (FTextureIDs[FCurTexture].AnTex = nil) then
578 begin
579 g_FatalError(_lc[I_GAME_ERROR_SWITCH_TEXTURE]);
580 Exit;
581 end;
583 if AnimLoop = 1 then
584 FTextureIDs[FCurTexture].AnTex.Loop := True
585 else
586 if AnimLoop = 2 then
587 FTextureIDs[FCurTexture].AnTex.Loop := False;
589 FTextureIDs[FCurTexture].AnTex.Reset();
590 end;
592 LastAnimLoop := AnimLoop;
593 end;
595 procedure TPanel.SetTexture(ID: Integer; AnimLoop: Byte = 0);
596 begin
597 // Íåò òåêñòóð:
598 if Length(FTextureIDs) = 0 then
599 FCurTexture := -1
600 else
601 // Òîëüêî îäíà òåêñòóðà:
602 if Length(FTextureIDs) = 1 then
603 begin
604 if (ID = 0) or (ID = -1) then
605 FCurTexture := ID;
606 end
607 else
608 // Áîëüøå îäíîé òåêñòóðû:
609 begin
610 if (ID >= -1) and (ID <= High(FTextureIDs)) then
611 FCurTexture := ID;
612 end;
614 // Ïåðåêëþ÷èëèñü íà âèäèìóþ àíèì. òåêñòóðó:
615 if (FCurTexture >= 0) and FTextureIDs[FCurTexture].Anim then
616 begin
617 if (FTextureIDs[FCurTexture].AnTex = nil) then
618 begin
619 g_FatalError(_lc[I_GAME_ERROR_SWITCH_TEXTURE]);
620 Exit;
621 end;
623 if AnimLoop = 1 then
624 FTextureIDs[FCurTexture].AnTex.Loop := True
625 else
626 if AnimLoop = 2 then
627 FTextureIDs[FCurTexture].AnTex.Loop := False;
629 FTextureIDs[FCurTexture].AnTex.Reset();
630 end;
632 LastAnimLoop := AnimLoop;
633 end;
635 function TPanel.GetTextureID(): DWORD;
636 begin
637 Result := LongWord(TEXTURE_NONE);
639 if (FCurTexture >= 0) then
640 begin
641 if FTextureIDs[FCurTexture].Anim then
642 Result := FTextureIDs[FCurTexture].AnTex.FramesID
643 else
644 Result := FTextureIDs[FCurTexture].Tex;
645 end;
646 end;
648 function TPanel.GetTextureCount(): Integer;
649 begin
650 Result := Length(FTextureIDs);
651 if Enabled and (FCurTexture >= 0) then
652 if (FTextureIDs[FCurTexture].Anim) and
653 (FTextureIDs[FCurTexture].AnTex <> nil) and
654 (Width > 0) and (Height > 0) and (FAlpha < 255) then
655 Result := Result + 100;
656 end;
658 procedure TPanel.SaveState(Var Mem: TBinMemoryWriter);
659 var
660 sig: DWORD;
661 anim: Boolean;
662 begin
663 if (Mem = nil) then exit;
664 //if not SaveIt then exit;
666 // Ñèãíàòóðà ïàíåëè:
667 sig := PANEL_SIGNATURE; // 'PANL'
668 Mem.WriteDWORD(sig);
669 // Îòêðûòà/çàêðûòà, åñëè äâåðü:
670 Mem.WriteBoolean(FEnabled);
671 // Íàïðàâëåíèå ëèôòà, åñëè ëèôò:
672 Mem.WriteByte(FLiftType);
673 // Íîìåð òåêóùåé òåêñòóðû:
674 Mem.WriteInt(FCurTexture);
675 // Êîîðäû
676 Mem.WriteInt(FX);
677 Mem.WriteInt(FY);
678 // Àíèìèðîâàííàÿ ëè òåêóùàÿ òåêñòóðà:
679 if (FCurTexture >= 0) and (FTextureIDs[FCurTexture].Anim) then
680 begin
681 Assert(FTextureIDs[FCurTexture].AnTex <> nil,
682 'TPanel.SaveState: No animation object');
683 anim := True;
684 end
685 else
686 anim := False;
687 Mem.WriteBoolean(anim);
688 // Åñëè äà - ñîõðàíÿåì àíèìàöèþ:
689 if anim then
690 FTextureIDs[FCurTexture].AnTex.SaveState(Mem);
691 // moving platform state
692 Mem.WriteInt(mMovingSpeed.X);
693 Mem.WriteInt(mMovingSpeed.Y);
694 Mem.WriteInt(mMovingStart.X);
695 Mem.WriteInt(mMovingStart.Y);
696 Mem.WriteInt(mMovingEnd.X);
697 Mem.WriteInt(mMovingEnd.Y);
698 Mem.WriteBoolean(mMovingActive);
699 end;
701 procedure TPanel.LoadState(var Mem: TBinMemoryReader);
702 var
703 sig: DWORD;
704 anim: Boolean;
705 //ox, oy: Integer;
706 begin
707 if (Mem = nil) then exit;
708 //if not SaveIt then exit;
710 // Ñèãíàòóðà ïàíåëè:
711 Mem.ReadDWORD(sig);
712 if sig <> PANEL_SIGNATURE then // 'PANL'
713 begin
714 raise EBinSizeError.Create('TPanel.LoadState: Wrong Panel Signature');
715 end;
716 // Îòêðûòà/çàêðûòà, åñëè äâåðü:
717 Mem.ReadBoolean(FEnabled);
718 // Íàïðàâëåíèå ëèôòà, åñëè ëèôò:
719 Mem.ReadByte(FLiftType);
720 // Íîìåð òåêóùåé òåêñòóðû:
721 Mem.ReadInt(FCurTexture);
722 // Êîîðäû
723 //ox := FX;
724 //oy := FY;
725 Mem.ReadInt(FX);
726 Mem.ReadInt(FY);
727 //e_LogWritefln('panel %s(%s): old=(%s,%s); new=(%s,%s); delta=(%s,%s)', [arrIdx, proxyId, ox, oy, FX, FY, FX-ox, FY-oy]);
728 // Àíèìèðîâàííàÿ ëè òåêóùàÿ òåêñòóðà:
729 Mem.ReadBoolean(anim);
730 // Åñëè äà - çàãðóæàåì àíèìàöèþ:
731 if anim then
732 begin
733 Assert((FCurTexture >= 0) and
734 (FTextureIDs[FCurTexture].Anim) and
735 (FTextureIDs[FCurTexture].AnTex <> nil),
736 'TPanel.LoadState: No animation object');
737 FTextureIDs[FCurTexture].AnTex.LoadState(Mem);
738 end;
739 // moving platform state
740 Mem.ReadInt(mMovingSpeed.X);
741 Mem.ReadInt(mMovingSpeed.Y);
742 Mem.ReadInt(mMovingStart.X);
743 Mem.ReadInt(mMovingStart.Y);
744 Mem.ReadInt(mMovingEnd.X);
745 Mem.ReadInt(mMovingEnd.Y);
746 Mem.ReadBoolean(mMovingActive);
748 if (proxyId >= 0) then mapGrid.moveBody(proxyId, X, Y);
749 end;
751 end.