DEADSOFTWARE

gl: implement touch screen controls
[d2df-sdl.git] / src / game / opengl / r_player.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, version 3 of the License ONLY.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 *)
15 {$INCLUDE ../../shared/a_modes.inc}
16 unit r_player;
18 interface
20 uses g_player, g_base; // TPlayer, TRGB
22 procedure r_Player_Load;
23 procedure r_Player_Free;
25 procedure r_Player_DrawAll;
26 procedure r_Player_DrawDebug (p: TPlayer);
27 procedure r_Player_DrawHealth;
29 procedure r_Player_Draw (p: TPlayer);
30 procedure r_Player_DrawIndicator (p: TPlayer; Color: TRGB);
31 procedure r_Player_DrawBubble (p: TPlayer);
32 procedure r_Player_DrawAim (p: TPlayer);
33 procedure r_Player_DrawGUI (pl: TPlayer);
34 procedure r_Player_DrawRulez (p: TPlayer);
35 procedure r_Player_DrawPain (p: TPlayer);
36 procedure r_Player_DrawPickup (p: TPlayer);
38 {$IFDEF ENABLE_SHELLS}
39 procedure r_Player_DrawShells;
40 {$ENDIF}
42 {$IFDEF ENABLE_CORPSES}
43 procedure r_Player_DrawCorpses;
44 {$ENDIF}
46 implementation
48 uses
49 {$IFDEF ENABLE_HOLMES}
50 g_holmes,
51 {$ENDIF}
52 {$IFDEF ENABLE_MENU}
53 g_menu,
54 {$ENDIF}
55 {$IFDEF ENABLE_SHELLS}
56 g_shells,
57 {$ENDIF}
58 {$IFDEF ENABLE_CORPSES}
59 g_corpses,
60 {$ENDIF}
61 SysUtils, Classes, Math,
62 MAPDEF, utils,
63 g_basic, g_game, g_phys, g_map, g_language, g_weapons, g_items, g_net, g_options,
64 r_playermodel, r_graphics, r_animations, r_textures, r_items, r_game, r_map
65 ;
67 var
68 gItemsTexturesID: array [0..ITEM_MAX] of DWORD;
69 PunchFrames: array [Boolean, 0..2] of DWORD;
70 BulletTexture: DWORD;
71 ShellTexture: DWORD;
73 procedure r_Player_Load;
74 begin
75 g_Frames_CreateWAD(nil, 'FRAMES_ITEM_BLUESPHERE', GameWAD+':TEXTURES\SBLUE', 32, 32, 4, True);
76 g_Frames_CreateWAD(nil, 'FRAMES_ITEM_WHITESPHERE', GameWAD+':TEXTURES\SWHITE', 32, 32, 4, True);
77 g_Frames_CreateWAD(nil, 'FRAMES_ITEM_ARMORGREEN', GameWAD+':TEXTURES\ARMORGREEN', 32, 16, 3, True);
78 g_Frames_CreateWAD(nil, 'FRAMES_ITEM_ARMORBLUE', GameWAD+':TEXTURES\ARMORBLUE', 32, 16, 3, True);
79 g_Frames_CreateWAD(nil, 'FRAMES_ITEM_JETPACK', GameWAD+':TEXTURES\JETPACK', 32, 32, 3, True);
80 g_Frames_CreateWAD(nil, 'FRAMES_ITEM_INVUL', GameWAD+':TEXTURES\INVUL', 32, 32, 4, True);
81 g_Frames_CreateWAD(nil, 'FRAMES_ITEM_INVIS', GameWAD+':TEXTURES\INVIS', 32, 32, 4, True);
82 g_Frames_CreateWAD(nil, 'FRAMES_ITEM_RESPAWN', GameWAD+':TEXTURES\ITEMRESPAWN', 32, 32, 5, True);
83 g_Frames_CreateWAD(nil, 'FRAMES_ITEM_BOTTLE', GameWAD+':TEXTURES\BOTTLE', 16, 32, 4, True);
84 g_Frames_CreateWAD(nil, 'FRAMES_ITEM_HELMET', GameWAD+':TEXTURES\HELMET', 16, 16, 4, True);
85 g_Frames_CreateWAD(nil, 'FRAMES_FLAG_RED', GameWAD+':TEXTURES\FLAGRED', 64, 64, 5, False);
86 g_Frames_CreateWAD(nil, 'FRAMES_FLAG_BLUE', GameWAD+':TEXTURES\FLAGBLUE', 64, 64, 5, False);
87 g_Frames_CreateWAD(nil, 'FRAMES_FLAG_DOM', GameWAD+':TEXTURES\FLAGDOM', 64, 64, 5, False);
88 g_Texture_CreateWADEx('ITEM_MEDKIT_SMALL', GameWAD+':TEXTURES\MED1');
89 g_Texture_CreateWADEx('ITEM_MEDKIT_LARGE', GameWAD+':TEXTURES\MED2');
90 g_Texture_CreateWADEx('ITEM_WEAPON_SAW', GameWAD+':TEXTURES\SAW');
91 g_Texture_CreateWADEx('ITEM_WEAPON_PISTOL', GameWAD+':TEXTURES\PISTOL');
92 g_Texture_CreateWADEx('ITEM_WEAPON_KASTET', GameWAD+':TEXTURES\KASTET');
93 g_Texture_CreateWADEx('ITEM_WEAPON_SHOTGUN1', GameWAD+':TEXTURES\SHOTGUN1');
94 g_Texture_CreateWADEx('ITEM_WEAPON_SHOTGUN2', GameWAD+':TEXTURES\SHOTGUN2');
95 g_Texture_CreateWADEx('ITEM_WEAPON_CHAINGUN', GameWAD+':TEXTURES\MGUN');
96 g_Texture_CreateWADEx('ITEM_WEAPON_ROCKETLAUNCHER', GameWAD+':TEXTURES\RLAUNCHER');
97 g_Texture_CreateWADEx('ITEM_WEAPON_PLASMA', GameWAD+':TEXTURES\PGUN');
98 g_Texture_CreateWADEx('ITEM_WEAPON_BFG', GameWAD+':TEXTURES\BFG');
99 g_Texture_CreateWADEx('ITEM_WEAPON_SUPERPULEMET', GameWAD+':TEXTURES\SPULEMET');
100 g_Texture_CreateWADEx('ITEM_WEAPON_FLAMETHROWER', GameWAD+':TEXTURES\FLAMETHROWER');
101 g_Texture_CreateWADEx('ITEM_AMMO_BULLETS', GameWAD+':TEXTURES\CLIP');
102 g_Texture_CreateWADEx('ITEM_AMMO_BULLETS_BOX', GameWAD+':TEXTURES\AMMO');
103 g_Texture_CreateWADEx('ITEM_AMMO_SHELLS', GameWAD+':TEXTURES\SHELL1');
104 g_Texture_CreateWADEx('ITEM_AMMO_SHELLS_BOX', GameWAD+':TEXTURES\SHELL2');
105 g_Texture_CreateWADEx('ITEM_AMMO_ROCKET', GameWAD+':TEXTURES\ROCKET');
106 g_Texture_CreateWADEx('ITEM_AMMO_ROCKET_BOX', GameWAD+':TEXTURES\ROCKETS');
107 g_Texture_CreateWADEx('ITEM_AMMO_CELL', GameWAD+':TEXTURES\CELL');
108 g_Texture_CreateWADEx('ITEM_AMMO_CELL_BIG', GameWAD+':TEXTURES\CELL2');
109 g_Texture_CreateWADEx('ITEM_AMMO_FUELCAN', GameWAD+':TEXTURES\FUELCAN');
110 g_Texture_CreateWADEx('ITEM_AMMO_BACKPACK', GameWAD+':TEXTURES\BPACK');
111 g_Texture_CreateWADEx('ITEM_KEY_RED', GameWAD+':TEXTURES\KEYR');
112 g_Texture_CreateWADEx('ITEM_KEY_GREEN', GameWAD+':TEXTURES\KEYG');
113 g_Texture_CreateWADEx('ITEM_KEY_BLUE', GameWAD+':TEXTURES\KEYB');
114 g_Texture_CreateWADEx('ITEM_OXYGEN', GameWAD+':TEXTURES\OXYGEN');
115 g_Texture_CreateWADEx('ITEM_SUIT', GameWAD+':TEXTURES\SUIT');
116 g_Texture_CreateWADEx('ITEM_WEAPON_KASTET', GameWAD+':TEXTURES\KASTET');
117 g_Texture_CreateWADEx('ITEM_MEDKIT_BLACK', GameWAD+':TEXTURES\BMED');
119 g_Texture_Get('ITEM_MEDKIT_SMALL', gItemsTexturesID[ITEM_MEDKIT_SMALL]);
120 g_Texture_Get('ITEM_MEDKIT_LARGE', gItemsTexturesID[ITEM_MEDKIT_LARGE]);
121 g_Texture_Get('ITEM_MEDKIT_BLACK', gItemsTexturesID[ITEM_MEDKIT_BLACK]);
122 g_Texture_Get('ITEM_SUIT', gItemsTexturesID[ITEM_SUIT]);
123 g_Texture_Get('ITEM_OXYGEN', gItemsTexturesID[ITEM_OXYGEN]);
124 g_Texture_Get('ITEM_WEAPON_SAW', gItemsTexturesID[ITEM_WEAPON_SAW]);
125 g_Texture_Get('ITEM_WEAPON_SHOTGUN1', gItemsTexturesID[ITEM_WEAPON_SHOTGUN1]);
126 g_Texture_Get('ITEM_WEAPON_SHOTGUN2', gItemsTexturesID[ITEM_WEAPON_SHOTGUN2]);
127 g_Texture_Get('ITEM_WEAPON_CHAINGUN', gItemsTexturesID[ITEM_WEAPON_CHAINGUN]);
128 g_Texture_Get('ITEM_WEAPON_ROCKETLAUNCHER', gItemsTexturesID[ITEM_WEAPON_ROCKETLAUNCHER]);
129 g_Texture_Get('ITEM_WEAPON_PLASMA', gItemsTexturesID[ITEM_WEAPON_PLASMA]);
130 g_Texture_Get('ITEM_WEAPON_BFG', gItemsTexturesID[ITEM_WEAPON_BFG]);
131 g_Texture_Get('ITEM_WEAPON_SUPERPULEMET', gItemsTexturesID[ITEM_WEAPON_SUPERPULEMET]);
132 g_Texture_Get('ITEM_WEAPON_FLAMETHROWER', gItemsTexturesID[ITEM_WEAPON_FLAMETHROWER]);
133 g_Texture_Get('ITEM_AMMO_BULLETS', gItemsTexturesID[ITEM_AMMO_BULLETS]);
134 g_Texture_Get('ITEM_AMMO_BULLETS_BOX', gItemsTexturesID[ITEM_AMMO_BULLETS_BOX]);
135 g_Texture_Get('ITEM_AMMO_SHELLS', gItemsTexturesID[ITEM_AMMO_SHELLS]);
136 g_Texture_Get('ITEM_AMMO_SHELLS_BOX', gItemsTexturesID[ITEM_AMMO_SHELLS_BOX]);
137 g_Texture_Get('ITEM_AMMO_ROCKET', gItemsTexturesID[ITEM_AMMO_ROCKET]);
138 g_Texture_Get('ITEM_AMMO_ROCKET_BOX', gItemsTexturesID[ITEM_AMMO_ROCKET_BOX]);
139 g_Texture_Get('ITEM_AMMO_CELL', gItemsTexturesID[ITEM_AMMO_CELL]);
140 g_Texture_Get('ITEM_AMMO_CELL_BIG', gItemsTexturesID[ITEM_AMMO_CELL_BIG]);
141 g_Texture_Get('ITEM_AMMO_FUELCAN', gItemsTexturesID[ITEM_AMMO_FUELCAN]);
142 g_Texture_Get('ITEM_AMMO_BACKPACK', gItemsTexturesID[ITEM_AMMO_BACKPACK]);
143 g_Texture_Get('ITEM_KEY_RED', gItemsTexturesID[ITEM_KEY_RED]);
144 g_Texture_Get('ITEM_KEY_GREEN', gItemsTexturesID[ITEM_KEY_GREEN]);
145 g_Texture_Get('ITEM_KEY_BLUE', gItemsTexturesID[ITEM_KEY_BLUE]);
146 g_Texture_Get('ITEM_WEAPON_KASTET', gItemsTexturesID[ITEM_WEAPON_KASTET]);
147 g_Texture_Get('ITEM_WEAPON_PISTOL', gItemsTexturesID[ITEM_WEAPON_PISTOL]);
149 g_Frames_CreateWAD(@PunchFrames[False, 0], 'FRAMES_PUNCH', GameWAD + ':WEAPONS\PUNCH', 64, 64, 4, False);
150 g_Frames_CreateWAD(@PunchFrames[False, 1], 'FRAMES_PUNCH_UP', GameWAD + ':WEAPONS\PUNCH_UP', 64, 64, 4, False);
151 g_Frames_CreateWAD(@PunchFrames[False, 2], 'FRAMES_PUNCH_DN', GameWAD + ':WEAPONS\PUNCH_DN', 64, 64, 4, False);
152 g_Frames_CreateWAD(@PunchFrames[True, 0], 'FRAMES_PUNCH_BERSERK', GameWAD + ':WEAPONS\PUNCHB', 64, 64, 4, False);
153 g_Frames_CreateWAD(@PunchFrames[True, 1], 'FRAMES_PUNCH_BERSERK_UP', GameWAD + ':WEAPONS\PUNCHB_UP', 64, 64, 4, False);
154 g_Frames_CreateWAD(@PunchFrames[True, 2], 'FRAMES_PUNCH_BERSERK_DN', GameWAD + ':WEAPONS\PUNCHB_DN', 64, 64, 4, False);
155 g_Texture_CreateWADEx('TEXTURE_SHELL_BULLET', GameWAD + ':TEXTURES\EBULLET');
156 g_Texture_CreateWADEx('TEXTURE_SHELL_SHELL', GameWAD + ':TEXTURES\ESHELL');
157 g_Texture_Get('TEXTURE_SHELL_BULLET', BulletTexture);
158 g_Texture_Get('TEXTURE_SHELL_SHELL', ShellTexture);
159 end;
161 procedure r_Player_Free;
162 begin
163 g_Frames_DeleteByName('FRAMES_PUNCH');
164 g_Frames_DeleteByName('FRAMES_PUNCH_UP');
165 g_Frames_DeleteByName('FRAMES_PUNCH_DN');
166 g_Frames_DeleteByName('FRAMES_PUNCH_BERSERK');
167 g_Frames_DeleteByName('FRAMES_PUNCH_BERSERK_UP');
168 g_Frames_DeleteByName('FRAMES_PUNCH_BERSERK_DN');
169 end;
171 procedure r_Player_DrawAll;
172 var i: Integer;
173 begin
174 if gPlayers <> nil then
175 for i := 0 to High(gPlayers) do
176 if gPlayers[i] <> nil then
177 r_Player_Draw(gPlayers[i])
178 end;
180 procedure r_Player_DrawDebug (p: TPlayer);
181 var
182 fW, fH: Byte;
183 begin
184 if p = nil then Exit;
185 if (@p.Obj) = nil then Exit;
187 e_TextureFontGetSize(gStdFont, fW, fH);
189 e_TextureFontPrint(0, 0 , 'Pos X: ' + IntToStr(p.Obj.X), gStdFont);
190 e_TextureFontPrint(0, fH , 'Pos Y: ' + IntToStr(p.Obj.Y), gStdFont);
191 e_TextureFontPrint(0, fH * 2, 'Vel X: ' + IntToStr(p.Obj.Vel.X), gStdFont);
192 e_TextureFontPrint(0, fH * 3, 'Vel Y: ' + IntToStr(p.Obj.Vel.Y), gStdFont);
193 e_TextureFontPrint(0, fH * 4, 'Acc X: ' + IntToStr(p.Obj.Accel.X), gStdFont);
194 e_TextureFontPrint(0, fH * 5, 'Acc Y: ' + IntToStr(p.Obj.Accel.Y), gStdFont);
195 e_TextureFontPrint(0, fH * 6, 'Old X: ' + IntToStr(p.Obj.oldX), gStdFont);
196 e_TextureFontPrint(0, fH * 7, 'Old Y: ' + IntToStr(p.Obj.oldY), gStdFont);
197 end;
199 procedure r_Player_DrawHealth;
200 var
201 i: Integer;
202 fW, fH: Byte;
203 begin
204 if gPlayers = nil then Exit;
205 e_TextureFontGetSize(gStdFont, fW, fH);
207 for i := 0 to High(gPlayers) do
208 if gPlayers[i] <> nil then
209 begin
210 e_TextureFontPrint(gPlayers[i].Obj.X + gPlayers[i].Obj.Rect.X,
211 gPlayers[i].Obj.Y + gPlayers[i].Obj.Rect.Y + gPlayers[i].Obj.Rect.Height - fH * 2,
212 IntToStr(gPlayers[i].Health), gStdFont);
213 e_TextureFontPrint(gPlayers[i].Obj.X + gPlayers[i].Obj.Rect.X,
214 gPlayers[i].Obj.Y + gPlayers[i].Obj.Rect.Y + gPlayers[i].Obj.Rect.Height - fH,
215 IntToStr(gPlayers[i].Armor), gStdFont);
216 end;
217 end;
219 {$IFDEF ENABLE_CORPSES}
220 procedure r_Player_DrawCorpse (p: TCorpse);
221 var fX, fY: Integer;
222 begin
223 if (p.State <> CORPSE_STATE_REMOVEME) and (p.Model <> nil) then
224 begin
225 p.Obj.lerp(gLerpFactor, fX, fY);
226 r_PlayerModel_Draw(p.Model, fX, fY)
227 end
228 end;
230 procedure r_Player_DrawCorpses;
231 var i: Integer;
232 begin
233 if gCorpses <> nil then
234 for i := 0 to High(gCorpses) do
235 if gCorpses[i] <> nil then
236 r_Player_DrawCorpse(gCorpses[i])
237 end;
238 {$ENDIF}
240 {$IFDEF ENABLE_SHELLS}
241 procedure r_Player_DrawShells;
242 var i, fX, fY: Integer; a: TDFPoint; TextureID: DWORD = DWORD(-1);
243 begin
244 if gShells <> nil then
245 begin
246 for i := 0 to High(gShells) do
247 begin
248 if gShells[i].alive and g_Obj_Collide(sX, sY, sWidth, sHeight, @gShells[i].Obj) then
249 begin
250 gShells[i].Obj.lerp(gLerpFactor, fX, fY);
251 case gShells[i].SType of
252 SHELL_BULLET:
253 begin
254 TextureID := BulletTexture;
255 a.X := 2;
256 a.Y := 1;
257 end;
258 SHELL_SHELL, SHELL_DBLSHELL:
259 begin
260 TextureID := ShellTexture;
261 a.X := 4;
262 a.Y := 2;
263 end
264 else
265 Assert(false)
266 end;
267 e_DrawAdv(TextureID, fX, fY, 0, True, False, gShells[i].RAngle, @a, TMirrorType.None);
268 end
269 end
270 end
271 end;
272 {$ENDIF}
274 procedure r_Player_DrawIndicator (p: TPlayer; Color: TRGB);
275 var
276 indX, indY, fX, fY, fSlope: Integer;
277 indW, indH: Word;
278 indA: Single;
279 a: TDFPoint;
280 nW, nH: Byte;
281 ID: DWORD;
282 c: TRGB;
283 begin
284 if p.Alive then
285 begin
286 p.Obj.lerp(gLerpFactor, fX, fY);
287 fSlope := nlerp(p.SlopeOld, p.Obj.slopeUpLeft, gLerpFactor);
289 case gPlayerIndicatorStyle of
290 0:
291 begin
292 if g_Texture_Get('TEXTURE_PLAYER_INDICATOR', ID) then
293 begin
294 e_GetTextureSize(ID, @indW, @indH);
295 a.X := indW div 2;
296 a.Y := indH div 2;
298 if (p.Obj.X + p.Obj.Rect.X) < 0 then
299 begin
300 indA := 90;
301 indX := fX + p.Obj.Rect.X + p.Obj.Rect.Width;
302 indY := fY + p.Obj.Rect.Y + (p.Obj.Rect.Height - indW) div 2;
303 end
305 else if (p.Obj.X + p.Obj.Rect.X + p.Obj.Rect.Width) > Max(gMapInfo.Width, gPlayerScreenSize.X) then
306 begin
307 indA := 270;
308 indX := fX + p.Obj.Rect.X - indH;
309 indY := fY + p.Obj.Rect.Y + (p.Obj.Rect.Height - indW) div 2;
310 end
312 else if (p.Obj.Y - indH) < 0 then
313 begin
314 indA := 180;
315 indX := fX + p.Obj.Rect.X + (p.Obj.Rect.Width - indW) div 2;
316 indY := fY + p.Obj.Rect.Y + p.Obj.Rect.Height;
317 end
319 else
320 begin
321 indA := 0;
322 indX := fX + p.Obj.Rect.X + (p.Obj.Rect.Width - indW) div 2;
323 indY := fY - indH;
324 end;
326 indY := indY + fSlope;
327 indX := EnsureRange(indX, 0, Max(gMapInfo.Width, gPlayerScreenSize.X) - indW);
328 indY := EnsureRange(indY, 0, Max(gMapInfo.Height, gPlayerScreenSize.Y) - indH);
330 c := e_Colors;
331 e_Colors := Color;
332 e_DrawAdv(ID, indX, indY, 0, True, False, indA, @a);
333 e_Colors := c;
334 end;
335 end;
337 1:
338 begin
339 e_TextureFontGetSize(gStdFont, nW, nH);
340 indX := fX + p.Obj.Rect.X + (p.Obj.Rect.Width - Length(p.Name) * nW) div 2;
341 indY := fY - nH + fSlope;
342 e_TextureFontPrintEx(indX, indY, p.Name, gStdFont, Color.R, Color.G, Color.B, 1.0, True);
343 end;
344 end;
345 end
346 end;
348 procedure r_Player_DrawBubble (p: TPlayer);
349 var
350 bubX, bubY, fX, fY: Integer;
351 ID: LongWord;
352 Rb, Gb, Bb,
353 Rw, Gw, Bw: SmallInt;
354 Dot: Byte;
355 CObj: TObj;
356 begin
357 {$IFDEF ENABLE_CORPSES}
358 CObj := g_Corpses_GetCameraObj(p);
359 {$ELSE}
360 CObj := p.Obj;
361 {$ENDIF}
362 CObj.lerp(gLerpFactor, fX, fY);
363 // NB: _F_Obj.Rect is used to keep the bubble higher; this is not a mistake
364 bubX := fX + p.Obj.Rect.X + IfThen(p.Direction = TDirection.D_LEFT, -4, 18);
365 bubY := fY + p.Obj.Rect.Y - 18;
366 Rb := 64;
367 Gb := 64;
368 Bb := 64;
369 Rw := 240;
370 Gw := 240;
371 Bw := 240;
372 case gChatBubble of
373 1: // simple textual non-bubble
374 begin
375 bubX := fX + p.Obj.Rect.X - 11;
376 bubY := fY + p.Obj.Rect.Y - 17;
377 e_TextureFontPrint(bubX, bubY, '[...]', gStdFont);
378 Exit;
379 end;
380 2: // advanced pixel-perfect bubble
381 begin
382 if p.Team = TEAM_RED then
383 Rb := 255
384 else
385 if p.Team = TEAM_BLUE then
386 Bb := 255;
387 end;
388 3: // colored bubble
389 begin
390 Rb := p.Model.Color.R;
391 Gb := p.Model.Color.G;
392 Bb := p.Model.Color.B;
393 Rw := Min(Rb * 2 + 64, 255);
394 Gw := Min(Gb * 2 + 64, 255);
395 Bw := Min(Bb * 2 + 64, 255);
396 if (Abs(Rw - Rb) < 32)
397 or (Abs(Gw - Gb) < 32)
398 or (Abs(Bw - Bb) < 32) then
399 begin
400 Rb := Max(Rw div 2 - 16, 0);
401 Gb := Max(Gw div 2 - 16, 0);
402 Bb := Max(Bw div 2 - 16, 0);
403 end;
404 end;
405 4: // custom textured bubble
406 begin
407 if g_Texture_Get('TEXTURE_PLAYER_TALKBUBBLE', ID) then
408 if p.Direction = TDirection.D_RIGHT then
409 e_Draw(ID, bubX - 6, bubY - 7, 0, True, False)
410 else
411 e_Draw(ID, bubX - 6, bubY - 7, 0, True, False, TMirrorType.Horizontal);
412 Exit;
413 end;
414 end;
416 // Outer borders
417 e_DrawQuad(bubX + 1, bubY , bubX + 18, bubY + 13, Rb, Gb, Bb);
418 e_DrawQuad(bubX , bubY + 1, bubX + 19, bubY + 12, Rb, Gb, Bb);
419 // Inner box
420 e_DrawFillQuad(bubX + 1, bubY + 1, bubX + 18, bubY + 12, Rw, Gw, Bw, 0);
422 // Tail
423 Dot := IfThen(p.Direction = TDirection.D_LEFT, 14, 5);
424 e_DrawLine(1, bubX + Dot, bubY + 14, bubX + Dot, bubY + 16, Rb, Gb, Bb);
425 e_DrawLine(1, bubX + IfThen(p.Direction = TDirection.D_LEFT, Dot - 1, Dot + 1), bubY + 13, bubX + IfThen(p.Direction = TDirection.D_LEFT, Dot - 1, Dot + 1), bubY + 15, Rw, Gw, Bw);
426 e_DrawLine(1, bubX + IfThen(p.Direction = TDirection.D_LEFT, Dot - 2, Dot + 2), bubY + 13, bubX + IfThen(p.Direction = TDirection.D_LEFT, Dot - 2, Dot + 2), bubY + 14, Rw, Gw, Bw);
427 e_DrawLine(1, bubX + IfThen(p.Direction = TDirection.D_LEFT, Dot - 3, Dot + 3), bubY + 13, bubX + IfThen(p.Direction = TDirection.D_LEFT, Dot - 3, Dot + 3), bubY + 13, Rw, Gw, Bw);
428 e_DrawLine(1, bubX + IfThen(p.Direction = TDirection.D_LEFT, Dot - 3, Dot + 3), bubY + 14, bubX + IfThen(p.Direction = TDirection.D_LEFT, Dot - 1, Dot + 1), bubY + 16, Rb, Gb, Bb);
430 // Dots
431 Dot := 6;
432 e_DrawFillQuad(bubX + Dot, bubY + 8, bubX + Dot + 1, bubY + 9, Rb, Gb, Bb, 0);
433 e_DrawFillQuad(bubX + Dot + 3, bubY + 8, bubX + Dot + 4, bubY + 9, Rb, Gb, Bb, 0);
434 e_DrawFillQuad(bubX + Dot + 6, bubY + 8, bubX + Dot + 7, bubY + 9, Rb, Gb, Bb, 0);
435 end;
437 procedure r_Player_Draw (p: TPlayer);
438 var
439 ID: DWORD;
440 w, h: Word;
441 dr: Boolean;
442 Mirror: TMirrorType;
443 fX, fY, fSlope: Integer;
444 begin
445 p.Obj.lerp(gLerpFactor, fX, fY);
446 fSlope := nlerp(p.SlopeOld, p.Obj.slopeUpLeft, gLerpFactor);
448 if p.Alive then
449 begin
450 if p.Direction = TDirection.D_RIGHT then
451 Mirror := TMirrorType.None
452 else
453 Mirror := TMirrorType.Horizontal;
455 if p.PunchAnim.IsValid() and p.PunchAnim.enabled then
456 begin
457 if p.FKeys[KEY_DOWN].Pressed then ID := PunchFrames[R_BERSERK in p.FRulez, 2]
458 else if p.FKeys[KEY_UP].Pressed then ID := PunchFrames[R_BERSERK in p.FRulez, 1]
459 else ID := PunchFrames[R_BERSERK in p.FRulez, 0];
460 r_AnimState_Draw(ID, p.PunchAnim, fX + IfThen(p.Direction = TDirection.D_LEFT, 15 - p.Obj.Rect.X, p.Obj.Rect.X - 15), fY + fSlope + p.Obj.Rect.Y - 11, 0, Mirror, False);
461 end;
463 if (p.FMegaRulez[MR_INVUL] > gTime) and ((gPlayerDrawn <> p) or (p.SpawnInvul >= gTime)) then
464 if g_Texture_Get('TEXTURE_PLAYER_INVULPENTA', ID) then
465 begin
466 e_GetTextureSize(ID, @w, @h);
467 if p.Direction = TDirection.D_LEFT then
468 e_Draw(ID, fX + p.Obj.Rect.X + (p.Obj.Rect.Width div 2) - (w div 2) + 4,
469 fY + p.Obj.Rect.Y + (p.Obj.Rect.Height div 2) - (h div 2) - 7 + fSlope, 0, True, False)
470 else
471 e_Draw(ID, fX + p.Obj.Rect.X + (p.Obj.Rect.Width div 2) - (w div 2) - 2,
472 fY + p.Obj.Rect.Y + (p.Obj.Rect.Height div 2) - (h div 2) - 7 + fSlope, 0, True, False)
473 end;
475 if p.FMegaRulez[MR_INVIS] > gTime then
476 begin
477 if (gPlayerDrawn <> nil) and ((p = gPlayerDrawn) or
478 ((p.Team = gPlayerDrawn.Team) and (gGameSettings.GameMode <> GM_DM))) then
479 begin
480 if (p.FMegaRulez[MR_INVIS] - gTime) <= 2100 then
481 dr := not Odd((p.FMegaRulez[MR_INVIS] - gTime) div 300)
482 else
483 dr := True;
484 if dr then
485 r_PlayerModel_Draw(p.Model, fX, fY + fSlope, 200)
486 else
487 r_PlayerModel_Draw(p.Model, fX, fY + fSlope);
488 end
489 else
490 r_PlayerModel_Draw(p.Model, fX, fY + fSlope, 254);
491 end
492 else
493 r_PlayerModel_Draw(p.Model, fX, fY + fSlope);
494 end;
496 if g_debug_Frames then
497 begin
498 e_DrawQuad(p.Obj.X + p.Obj.Rect.X,
499 p.Obj.Y + p.Obj.Rect.Y,
500 p.Obj.X + p.Obj.Rect.X + p.Obj.Rect.Width - 1,
501 p.Obj.Y + p.Obj.Rect.Y + p.Obj.Rect.Height - 1,
502 0, 255, 0);
503 end;
505 if (gChatBubble > 0) and (p.FKeys[KEY_CHAT].Pressed) and not p.Ghost then
506 if (p.FMegaRulez[MR_INVIS] <= gTime) or ((gPlayerDrawn <> nil) and ((p = gPlayerDrawn) or
507 ((p.Team = gPlayerDrawn.Team) and (gGameSettings.GameMode <> GM_DM)))) then
508 r_Player_DrawBubble(p);
510 // e_DrawPoint(5, 335, 288, 255, 0, 0); // DL, UR, DL, UR
511 if gAimLine and p.Alive and ((p = gPlayer1) or (p = gPlayer2)) then
512 r_Player_DrawAim(p);
513 end;
515 procedure r_Player_DrawAim (p: TPlayer);
517 procedure drawCast (sz: Integer; ax0, ay0, ax1, ay1: Integer);
518 var
519 ex, ey: Integer;
520 begin
522 {$IFDEF ENABLE_HOLMES}
523 if p.isValidViewPort() and (p = gPlayer1) then
524 begin
525 g_Holmes_plrLaser(ax0, ay0, ax1, ay1);
526 end;
527 {$ENDIF}
529 e_DrawLine(sz, ax0, ay0, ax1, ay1, 255, 0, 0, 96);
530 if (g_Map_traceToNearestWall(ax0, ay0, ax1, ay1, @ex, @ey) <> nil) then
531 begin
532 e_DrawLine(sz, ax0, ay0, ex, ey, 0, 255, 0, 96);
533 end
534 else
535 begin
536 e_DrawLine(sz, ax0, ay0, ex, ey, 0, 0, 255, 96);
537 end;
538 end;
540 var
541 wx, wy, xx, yy: Integer;
542 angle: SmallInt;
543 sz, len: Word;
544 begin
545 wx := p.Obj.X + WEAPONPOINT[p.Direction].X + IfThen(p.Direction = TDirection.D_LEFT, 7, -7);
546 wy := p.Obj.Y + WEAPONPOINT[p.Direction].Y;
547 angle := p.Angle_;
548 len := 1024;
549 sz := 2;
550 case p.CurrWeap of
551 0: begin // Punch
552 len := 12;
553 sz := 4;
554 end;
555 1: begin // Chainsaw
556 len := 24;
557 sz := 6;
558 end;
559 2: begin // Pistol
560 len := 1024;
561 sz := 2;
562 if angle = ANGLE_RIGHTUP then Dec(angle, 2);
563 if angle = ANGLE_RIGHTDOWN then Inc(angle, 4);
564 if angle = ANGLE_LEFTUP then Inc(angle, 2);
565 if angle = ANGLE_LEFTDOWN then Dec(angle, 4);
566 end;
567 3: begin // Shotgun
568 len := 1024;
569 sz := 3;
570 if angle = ANGLE_RIGHTUP then Dec(angle, 2);
571 if angle = ANGLE_RIGHTDOWN then Inc(angle, 4);
572 if angle = ANGLE_LEFTUP then Inc(angle, 2);
573 if angle = ANGLE_LEFTDOWN then Dec(angle, 4);
574 end;
575 4: begin // Double Shotgun
576 len := 1024;
577 sz := 4;
578 if angle = ANGLE_RIGHTUP then Dec(angle, 2);
579 if angle = ANGLE_RIGHTDOWN then Inc(angle, 4);
580 if angle = ANGLE_LEFTUP then Inc(angle, 2);
581 if angle = ANGLE_LEFTDOWN then Dec(angle, 4);
582 end;
583 5: begin // Chaingun
584 len := 1024;
585 sz := 3;
586 if angle = ANGLE_RIGHTUP then Dec(angle, 2);
587 if angle = ANGLE_RIGHTDOWN then Inc(angle, 4);
588 if angle = ANGLE_LEFTUP then Inc(angle, 2);
589 if angle = ANGLE_LEFTDOWN then Dec(angle, 4);
590 end;
591 6: begin // Rocket Launcher
592 len := 1024;
593 sz := 7;
594 if angle = ANGLE_RIGHTUP then Inc(angle, 2);
595 if angle = ANGLE_RIGHTDOWN then Inc(angle, 4);
596 if angle = ANGLE_LEFTUP then Dec(angle, 2);
597 if angle = ANGLE_LEFTDOWN then Dec(angle, 4);
598 end;
599 7: begin // Plasmagun
600 len := 1024;
601 sz := 5;
602 if angle = ANGLE_RIGHTUP then Inc(angle);
603 if angle = ANGLE_RIGHTDOWN then Inc(angle, 3);
604 if angle = ANGLE_LEFTUP then Dec(angle);
605 if angle = ANGLE_LEFTDOWN then Dec(angle, 3);
606 end;
607 8: begin // BFG
608 len := 1024;
609 sz := 12;
610 if angle = ANGLE_RIGHTUP then Inc(angle, 1);
611 if angle = ANGLE_RIGHTDOWN then Inc(angle, 2);
612 if angle = ANGLE_LEFTUP then Dec(angle, 1);
613 if angle = ANGLE_LEFTDOWN then Dec(angle, 2);
614 end;
615 9: begin // Super Chaingun
616 len := 1024;
617 sz := 4;
618 if angle = ANGLE_RIGHTUP then Dec(angle, 2);
619 if angle = ANGLE_RIGHTDOWN then Inc(angle, 4);
620 if angle = ANGLE_LEFTUP then Inc(angle, 2);
621 if angle = ANGLE_LEFTDOWN then Dec(angle, 4);
622 end;
623 end;
624 xx := Trunc(Cos(-DegToRad(angle)) * len) + wx;
625 yy := Trunc(Sin(-DegToRad(angle)) * len) + wy;
626 {$IF DEFINED(D2F_DEBUG)}
627 drawCast(sz, wx, wy, xx, yy);
628 {$ELSE}
629 e_DrawLine(sz, wx, wy, xx, yy, 255, 0, 0, 96);
630 {$ENDIF}
631 end;
633 procedure r_Player_DrawGUI (pl: TPlayer);
634 var
635 ID: DWORD;
636 X, Y, SY, a, p, m: Integer;
637 tw, th: Word;
638 cw, ch: Byte;
639 s: string;
640 stat: TPlayerStatArray;
641 begin
642 X := gPlayerScreenSize.X;
643 SY := gPlayerScreenSize.Y;
644 Y := 0;
646 if gShowScore and (gGameSettings.GameMode in [GM_TDM, GM_CTF]) then
647 begin
648 if gGameSettings.GameMode = GM_CTF then
649 a := 32 + 8
650 else
651 a := 0;
652 if gGameSettings.GameMode = GM_CTF then
653 begin
654 s := 'TEXTURE_PLAYER_REDFLAG';
655 if gFlags[FLAG_RED].State = FLAG_STATE_CAPTURED then
656 s := 'TEXTURE_PLAYER_REDFLAG_S';
657 if gFlags[FLAG_RED].State = FLAG_STATE_DROPPED then
658 s := 'TEXTURE_PLAYER_REDFLAG_D';
659 if g_Texture_Get(s, ID) then
660 e_Draw(ID, X-16-32, 240-72-4, 0, True, False);
661 end;
663 s := IntToStr(gTeamStat[TEAM_RED].Score);
664 e_CharFont_GetSize(gMenuFont, s, tw, th);
665 e_CharFont_PrintEx(gMenuFont, X-16-a-tw, 240-72-4, s, TEAMCOLOR[TEAM_RED]);
667 if gGameSettings.GameMode = GM_CTF then
668 begin
669 s := 'TEXTURE_PLAYER_BLUEFLAG';
670 if gFlags[FLAG_BLUE].State = FLAG_STATE_CAPTURED then
671 s := 'TEXTURE_PLAYER_BLUEFLAG_S';
672 if gFlags[FLAG_BLUE].State = FLAG_STATE_DROPPED then
673 s := 'TEXTURE_PLAYER_BLUEFLAG_D';
674 if g_Texture_Get(s, ID) then
675 e_Draw(ID, X-16-32, 240-32-4, 0, True, False);
676 end;
678 s := IntToStr(gTeamStat[TEAM_BLUE].Score);
679 e_CharFont_GetSize(gMenuFont, s, tw, th);
680 e_CharFont_PrintEx(gMenuFont, X-16-a-tw, 240-32-4, s, TEAMCOLOR[TEAM_BLUE]);
681 end;
683 if g_Texture_Get('TEXTURE_PLAYER_HUDBG', ID) then
684 e_DrawFill(ID, X, 0, 1, (gPlayerScreenSize.Y div 256)+IfThen(gPlayerScreenSize.Y mod 256 > 0, 1, 0),
685 0, False, False);
687 if g_Texture_Get('TEXTURE_PLAYER_HUD', ID) then
688 e_Draw(ID, X+2, Y, 0, True, False);
690 if gGameSettings.GameType in [GT_CUSTOM, GT_SERVER, GT_CLIENT] then
691 begin
692 if gShowStat then
693 begin
694 s := IntToStr(pl.Frags);
695 e_CharFont_GetSize(gMenuFont, s, tw, th);
696 e_CharFont_PrintEx(gMenuFont, X-16-tw, Y, s, _RGB(255, 0, 0));
698 s := '';
699 p := 1;
700 m := 0;
701 stat := g_Player_GetStats();
702 if stat <> nil then
703 begin
704 p := 1;
706 for a := 0 to High(stat) do
707 if stat[a].Name <> pl.Name then
708 begin
709 if stat[a].Frags > m then m := stat[a].Frags;
710 if stat[a].Frags > pl.Frags then p := p+1;
711 end;
712 end;
714 s := IntToStr(p)+' / '+IntToStr(Length(stat))+' ';
715 if pl.Frags >= m then s := s+'+' else s := s+'-';
716 s := s+IntToStr(Abs(pl.Frags-m));
718 e_CharFont_GetSize(gMenuSmallFont, s, tw, th);
719 e_CharFont_PrintEx(gMenuSmallFont, X-16-tw, Y+32, s, _RGB(255, 0, 0));
720 end;
722 if gLMSRespawn > LMS_RESPAWN_NONE then
723 begin
724 s := _lc[I_GAME_WARMUP];
725 e_CharFont_GetSize(gMenuFont, s, tw, th);
726 s := s + ': ' + IntToStr((gLMSRespawnTime - gTime) div 1000);
727 e_CharFont_PrintEx(gMenuFont, X-64-tw, SY-32, s, _RGB(0, 255, 0));
728 end
729 else if gShowLives and (gGameSettings.MaxLives > 0) then
730 begin
731 s := IntToStr(pl.Lives);
732 e_CharFont_GetSize(gMenuFont, s, tw, th);
733 e_CharFont_PrintEx(gMenuFont, X-16-tw, SY-32, s, _RGB(0, 255, 0));
734 end;
735 end;
737 e_CharFont_GetSize(gMenuSmallFont, pl.Name, tw, th);
738 e_CharFont_PrintEx(gMenuSmallFont, X+98-(tw div 2), Y+8, pl.Name, _RGB(255, 0, 0));
740 if R_BERSERK in pl.FRulez then
741 e_Draw(gItemsTexturesID[ITEM_MEDKIT_BLACK], X+37, Y+45, 0, True, False)
742 else
743 e_Draw(gItemsTexturesID[ITEM_MEDKIT_LARGE], X+37, Y+45, 0, True, False);
745 if g_Texture_Get('TEXTURE_PLAYER_ARMORHUD', ID) then
746 e_Draw(ID, X+36, Y+77, 0, True, False);
748 s := IntToStr(IfThen(pl.Health > 0, pl.Health, 0));
749 e_CharFont_GetSize(gMenuFont, s, tw, th);
750 e_CharFont_PrintEx(gMenuFont, X+178-tw, Y+40, s, _RGB(255, 0, 0));
752 s := IntToStr(pl.Armor);
753 e_CharFont_GetSize(gMenuFont, s, tw, th);
754 e_CharFont_PrintEx(gMenuFont, X+178-tw, Y+68, s, _RGB(255, 0, 0));
756 s := IntToStr(pl.GetAmmoByWeapon(pl.CurrWeap));
758 case pl.CurrWeap of
759 WEAPON_KASTET:
760 begin
761 s := '--';
762 ID := gItemsTexturesID[ITEM_WEAPON_KASTET];
763 end;
764 WEAPON_SAW:
765 begin
766 s := '--';
767 ID := gItemsTexturesID[ITEM_WEAPON_SAW];
768 end;
769 WEAPON_PISTOL: ID := gItemsTexturesID[ITEM_WEAPON_PISTOL];
770 WEAPON_CHAINGUN: ID := gItemsTexturesID[ITEM_WEAPON_CHAINGUN];
771 WEAPON_SHOTGUN1: ID := gItemsTexturesID[ITEM_WEAPON_SHOTGUN1];
772 WEAPON_SHOTGUN2: ID := gItemsTexturesID[ITEM_WEAPON_SHOTGUN2];
773 WEAPON_SUPERPULEMET: ID := gItemsTexturesID[ITEM_WEAPON_SUPERPULEMET];
774 WEAPON_ROCKETLAUNCHER: ID := gItemsTexturesID[ITEM_WEAPON_ROCKETLAUNCHER];
775 WEAPON_PLASMA: ID := gItemsTexturesID[ITEM_WEAPON_PLASMA];
776 WEAPON_BFG: ID := gItemsTexturesID[ITEM_WEAPON_BFG];
777 WEAPON_FLAMETHROWER: ID := gItemsTexturesID[ITEM_WEAPON_FLAMETHROWER];
778 end;
780 e_CharFont_GetSize(gMenuFont, s, tw, th);
781 e_CharFont_PrintEx(gMenuFont, X+178-tw, Y+158, s, _RGB(255, 0, 0));
782 e_Draw(ID, X+20, Y+160, 0, True, False);
784 if R_KEY_RED in pl.FRulez then
785 e_Draw(gItemsTexturesID[ITEM_KEY_RED], X+78, Y+214, 0, True, False);
787 if R_KEY_GREEN in pl.FRulez then
788 e_Draw(gItemsTexturesID[ITEM_KEY_GREEN], X+95, Y+214, 0, True, False);
790 if R_KEY_BLUE in pl.FRulez then
791 e_Draw(gItemsTexturesID[ITEM_KEY_BLUE], X+112, Y+214, 0, True, False);
793 if pl.JetFuel > 0 then
794 begin
795 if g_Texture_Get('TEXTURE_PLAYER_HUDAIR', ID) then
796 e_Draw(ID, X+2, Y+116, 0, True, False);
797 if g_Texture_Get('TEXTURE_PLAYER_HUDJET', ID) then
798 e_Draw(ID, X+2, Y+126, 0, True, False);
799 e_DrawLine(4, X+16, Y+122, X+16+Trunc(168*IfThen(pl.Air > 0, pl.Air, 0)/AIR_MAX), Y+122, 0, 0, 196);
800 e_DrawLine(4, X+16, Y+132, X+16+Trunc(168*pl.JetFuel/JET_MAX), Y+132, 208, 0, 0);
801 end
802 else
803 begin
804 if g_Texture_Get('TEXTURE_PLAYER_HUDAIR', ID) then
805 e_Draw(ID, X+2, Y+124, 0, True, False);
806 e_DrawLine(4, X+16, Y+130, X+16+Trunc(168*IfThen(pl.Air > 0, pl.Air, 0)/AIR_MAX), Y+130, 0, 0, 196);
807 end;
809 if gShowPing and g_Game_IsClient then
810 begin
811 s := _lc[I_GAME_PING_HUD] + IntToStr(NetPeer.lastRoundTripTime) + _lc[I_NET_SLIST_PING_MS];
812 e_TextureFontPrint(X + 4, Y + 242, s, gStdFont);
813 Y := Y + 16;
814 end;
816 if pl.Spectator then
817 begin
818 e_TextureFontPrint(X + 4, Y + 242, _lc[I_PLAYER_SPECT], gStdFont);
819 e_TextureFontPrint(X + 4, Y + 258, _lc[I_PLAYER_SPECT2], gStdFont);
820 e_TextureFontPrint(X + 4, Y + 274, _lc[I_PLAYER_SPECT1], gStdFont);
821 if pl.NoRespawn then
822 begin
823 e_TextureFontGetSize(gStdFont, cw, ch);
824 s := _lc[I_PLAYER_SPECT4];
825 e_TextureFontPrintEx(gScreenWidth div 2 - cw*(Length(s) div 2),
826 gScreenHeight-4-ch, s, gStdFont, 255, 255, 255, 1, True);
827 e_TextureFontPrint(X + 4, Y + 290, _lc[I_PLAYER_SPECT1S], gStdFont);
828 end;
830 end;
831 end;
833 procedure r_Player_DrawRulez (p: TPlayer);
834 var
835 dr: Boolean;
836 begin
837 // При взятии неуязвимости рисуется инверсионный белый фон
838 if (p.FMegaRulez[MR_INVUL] >= gTime) and (p.SpawnInvul < gTime) then
839 begin
840 if (p.FMegaRulez[MR_INVUL]-gTime) <= 2100 then
841 dr := not Odd((p.FMegaRulez[MR_INVUL]-gTime) div 300)
842 else
843 dr := True;
845 if dr then
846 e_DrawFillQuad(0, 0, gPlayerScreenSize.X-1, gPlayerScreenSize.Y-1,
847 191, 191, 191, 0, TBlending.Invert);
848 end;
850 // При взятии защитного костюма рисуется зеленоватый фон
851 if p.FMegaRulez[MR_SUIT] >= gTime then
852 begin
853 if (p.FMegaRulez[MR_SUIT]-gTime) <= 2100 then
854 dr := not Odd((p.FMegaRulez[MR_SUIT]-gTime) div 300)
855 else
856 dr := True;
858 if dr then
859 e_DrawFillQuad(0, 0, gPlayerScreenSize.X-1, gPlayerScreenSize.Y-1,
860 0, 96, 0, 200, TBlending.None);
861 end;
863 // При взятии берсерка рисуется красноватый фон
864 if (p.Berserk >= 0) and (LongWord(p.Berserk) >= gTime) and (gFlash = 2) then
865 begin
866 e_DrawFillQuad(0, 0, gPlayerScreenSize.X-1, gPlayerScreenSize.Y-1,
867 255, 0, 0, 200, TBlending.None);
868 end;
869 end;
871 procedure r_Player_DrawPain (p: TPlayer);
872 var
873 a, h: Integer;
874 begin
875 if p.Pain = 0 then Exit;
877 a := p.Pain;
879 if a < 15 then h := 0
880 else if a < 35 then h := 1
881 else if a < 55 then h := 2
882 else if a < 75 then h := 3
883 else if a < 95 then h := 4
884 else h := 5;
886 //if a > 255 then a := 255;
888 e_DrawFillQuad(0, 0, gPlayerScreenSize.X-1, gPlayerScreenSize.Y-1, 255, 0, 0, 255-h*50);
889 //e_DrawFillQuad(0, 0, gPlayerScreenSize.X-1, gPlayerScreenSize.Y-1, 255-min(128, a), 255-a, 255-a, 0, B_FILTER);
890 end;
892 procedure r_Player_DrawPickup (p: TPlayer);
893 var
894 a, h: Integer;
895 begin
896 if p.Pickup = 0 then Exit;
898 a := p.Pickup;
900 if a < 15 then h := 1
901 else if a < 35 then h := 2
902 else if a < 55 then h := 3
903 else if a < 75 then h := 4
904 else h := 5;
906 e_DrawFillQuad(0, 0, gPlayerScreenSize.X-1, gPlayerScreenSize.Y-1, 150, 200, 150, 255-h*50);
907 end;
909 end.