summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 3a016cd)
raw | patch | inline | side by side (parent: 3a016cd)
author | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Sun, 16 Jan 2022 19:46:01 +0000 (22:46 +0300) | ||
committer | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Fri, 9 Jun 2023 07:51:59 +0000 (10:51 +0300) |
diff --git a/src/game/g_player.pas b/src/game/g_player.pas
index 9552d30d2b111a22e1307dcf6001dfc9840f4e25..5a0d7d7cb525a27b2cd189e55c1ba8226efc592b 100644 (file)
--- a/src/game/g_player.pas
+++ b/src/game/g_player.pas
{$IFDEF USE_MEMPOOL}mempool,{$ENDIF}
g_base, g_playermodel, g_basic, g_textures,
g_weapons, g_phys, g_sound, g_saveload, MAPDEF,
- g_panel;
+ g_panel, r_playermodel;
const
KEY_LEFT = 1;
PGib = ^TGib;
TGib = record
alive: Boolean;
- ID: DWORD;
- MaskID: DWORD;
RAngle: Integer;
Color: TRGB;
Obj: TObj;
+ ModelID: Integer;
+ GibID: Integer;
+
procedure getMapBox (out x, y, w, h: Integer); inline;
procedure moveBy (dx, dy: Integer); inline;
procedure g_Player_CreateGibs(fX, fY: Integer; ModelName: string; fColor: TRGB);
var
- a: Integer;
+ a, mid: Integer;
GibsArray: TGibsArray;
Blood: TModelBlood;
begin
if (gGibs = nil) or (Length(gGibs) = 0) then
Exit;
- if not g_PlayerModel_GetGibs(ModelName, GibsArray) then
+ mid := g_PlayerModel_GetIndex(ModelName);
+ if mid = -1 then
+ Exit;
+ if not g_PlayerModel_GetGibs(mid, GibsArray) then
Exit;
- Blood := g_PlayerModel_GetBlood(ModelName);
+ Blood := PlayerModelsArray[mid].Blood;
for a := 0 to High(GibsArray) do
with gGibs[CurrentGib] do
begin
+ ModelID := mid;
+ GibID := GibsArray[a];
Color := fColor;
- ID := GibsArray[a].ID;
- MaskID := GibsArray[a].MaskID;
alive := True;
g_Obj_Init(@Obj);
- Obj.Rect := GibsArray[a].Rect;
- Obj.X := fX-GibsArray[a].Rect.X-(GibsArray[a].Rect.Width div 2);
- Obj.Y := fY-GibsArray[a].Rect.Y-(GibsArray[a].Rect.Height div 2);
+ Obj.Rect := r_PlayerModel_GetGibRect(ModelID, GibID);
+ Obj.X := fX - Obj.Rect.X - (Obj.Rect.Width div 2);
+ Obj.Y := fY - Obj.Rect.Y - (Obj.Rect.Height div 2);
g_Obj_PushA(@Obj, 25 + Random(10), Random(361));
positionChanged(); // this updates spatial accelerators
RAngle := Random(360);
index ca4b6dc6c4fc92ae6e1ef9eab5f6171cc5c36cd4..820c7c5c52ad72bcfa0e5a49dfef8afb19e2381b 100644 (file)
Level: Byte;
end;
- TGibSprite = record
- ID: DWORD;
- MaskID: DWORD;
- Rect: TRectWH;
- OnlyOne: Boolean;
- end;
-
TModelSoundArray = Array of TModelSound;
- TGibsArray = Array of TGibSprite;
+
+ TGibsArray = Array of Integer;
TPlayerModel = class{$IFDEF USE_MEMPOOL}(TPoolObject){$ENDIF}
private
function g_PlayerModel_GetBlood(ModelName: String): TModelBlood;
function g_PlayerModel_Get(ModelName: String): TPlayerModel;
function g_PlayerModel_GetAnim(ModelName: String; AnimTyp: Byte; var _Anim, _Mask: TAnimation): Boolean;
-function g_PlayerModel_GetGibs(ModelName: String; var Gibs: TGibsArray): Boolean;
-
-function g_PlayerModel_GetIndex (ModelName: String): Integer;
+function g_PlayerModel_GetGibs (ModelID: Integer; var Gibs: TGibsArray): Boolean;
+function g_PlayerModel_GetIndex (ModelName: String): Integer;
(* --- private data --- *)
FlagPoint: TDFPoint;
FlagAngle: SmallInt;
WeaponPoints: TWeaponPoints;
- Gibs: TGibsArray; // !!! move to render
PainSounds: TModelSoundArray;
DieSounds: TModelSoundArray;
SlopSound: Byte;
function g_PlayerModel_Load(FileName: string): Boolean;
var
ID: DWORD;
- a, b, len, lenpd, lenpd2, aa, bb, f: Integer;
+ a, b, len, aa, bb, f: Integer;
cc: TDirection;
config: TConfig;
- pData, pData2: Pointer;
+ pData: Pointer;
WAD: TWADFile;
s: string;
prefix: string;
GibsMask := config.ReadStr('Gibs', 'mask', 'GIBSMASK');
GibsOnce := config.ReadInt('Gibs', 'once', -1);
- SetLength(Gibs, GibsCount); // !!! remove load
- if (Gibs <> nil) and
- (WAD.GetResource('TEXTURES/' + GibsResource, pData, lenpd)) and
- (WAD.GetResource('TEXTURES/' + GibsMask, pData2, lenpd2)) then
- begin
- for a := 0 to High(Gibs) do
- if e_CreateTextureMemEx(pData, lenpd, Gibs[a].ID, a*32, 0, 32, 32) and
- e_CreateTextureMemEx(pData2, lenpd2, Gibs[a].MaskID, a*32, 0, 32, 32) then
- begin
- //Gibs[a].Rect := e_GetTextureSize2(Gibs[a].ID);
- Gibs[a].Rect := g_PlayerModel_CalcGibSize(pData, lenpd, a*32, 0, 32, 32);
- with Gibs[a].Rect do
- if Height > 3 then Height := Height-1-Random(2);
- Gibs[a].OnlyOne := GibsOnce = a + 1;
- end;
-
- FreeMem(pData);
- FreeMem(pData2);
- end;
-
ok := True;
for aa := WP_FIRST + 1 to WP_LAST do
for bb := A_STAND to A_LAST do
Result := True;
end;
-function g_PlayerModel_GetGibs(ModelName: string; var Gibs: TGibsArray): Boolean;
-var
- a, i, b: Integer;
- c: Boolean;
-begin
- Result := False;
-
- if PlayerModelsArray = nil then Exit;
- if gGibsCount = 0 then Exit;
-
- c := False;
-
- SetLength(Gibs, gGibsCount);
+ function g_PlayerModel_GetGibs (ModelID: Integer; var Gibs: TGibsArray): Boolean;
+ var i, b: Integer; c: Boolean;
+ begin
+ Gibs := nil;
+ Result := False;
+ if (PlayerModelsArray = nil) or (gGibsCount = 0) then
+ Exit;
- for a := 0 to High(PlayerModelsArray) do
- if PlayerModelsArray[a].Name = ModelName then
+ c := False;
+ SetLength(Gibs, gGibsCount);
+ for i := 0 to High(Gibs) do
begin
- for i := 0 to High(Gibs) do
+ if c and (PlayerModelsArray[ModelID].GibsCount = 1) then
begin
- if c and (Length(PlayerModelsArray[a].Gibs) = 1) then
- begin
- SetLength(Gibs, i);
- Break;
- end;
-
- repeat
- b := Random(Length(PlayerModelsArray[a].Gibs));
- until not (PlayerModelsArray[a].Gibs[b].OnlyOne and c);
+ SetLength(Gibs, i);
+ Break;
+ end;
- Gibs[i] := PlayerModelsArray[a].Gibs[b];
+ repeat
+ b := Random(PlayerModelsArray[ModelID].GibsCount);
+ until not ((PlayerModelsArray[ModelID].GibsOnce = b + 1) and c);
- if Gibs[i].OnlyOne then c := True;
- end;
+ Gibs[i] := b;
- Result := True;
- Break;
+ c := PlayerModelsArray[ModelID].GibsOnce = b + 1;
end;
-end;
+ Result := True;
+ end;
function g_PlayerModel_GetNames(): SSArray;
var
index 8396f14a48065e03ba95f2337a6973f186efc289..931769c8fd2fee7ba6fe2631d5c1a4c1a258f511 100644 (file)
e_input, e_sound,
g_language, g_console, g_menu, g_triggers, g_player, g_options, g_monsters, g_map, g_panel,
g_items, g_weapons, g_gfx, g_phys, g_net, g_gui, g_netmaster,
- g_game, r_console, r_gfx, r_items, r_map, r_panel, r_monsters, r_weapons, r_netmaster, r_player, r_textures
+ g_game, r_console, r_gfx, r_items, r_map, r_panel, r_monsters, r_weapons, r_netmaster, r_player, r_textures,
+ r_playermodel
;
var
drawOther('weapons', @r_Weapon_Draw);
drawOther('shells', @r_Player_DrawShells);
drawOther('drawall', @r_Player_DrawAll);
+ drawOther('gibs', @r_PlayerModel_DrawGibs);
drawOther('corpses', @r_Player_DrawCorpses);
drawPanelType('*wall', PANEL_WALL, g_rlayer_wall);
drawOther('monsters', @r_Monsters_Draw);
index a4be8f8b1e03aa71fb5a0675710d138e0d288103..6306e171713a69eff076b9e77bddfa3908abcc8c 100644 (file)
end;
end;
-procedure r_Player_DrawCorpses;
-var
- i, fX, fY: Integer;
- a: TDFPoint;
-begin
- if gGibs <> nil then
- for i := 0 to High(gGibs) do
- if gGibs[i].alive then
- with gGibs[i] do
- begin
- if not g_Obj_Collide(sX, sY, sWidth, sHeight, @Obj) then
- Continue;
-
- Obj.lerp(gLerpFactor, fX, fY);
-
- a.X := Obj.Rect.X+(Obj.Rect.Width div 2);
- a.y := Obj.Rect.Y+(Obj.Rect.Height div 2);
-
- e_DrawAdv(ID, fX, fY, 0, True, False, RAngle, @a, TMirrorType.None);
-
- e_Colors := Color;
- e_DrawAdv(MaskID, fX, fY, 0, True, False, RAngle, @a, TMirrorType.None);
- e_Colors.R := 255;
- e_Colors.G := 255;
- e_Colors.B := 255;
- end;
-
- if gCorpses <> nil then
- for i := 0 to High(gCorpses) do
- if gCorpses[i] <> nil then
- r_Player_DrawCorpse(gCorpses[i])
-end;
+ procedure r_Player_DrawCorpses;
+ var i: Integer;
+ begin
+ if gCorpses <> nil then
+ for i := 0 to High(gCorpses) do
+ if gCorpses[i] <> nil then
+ r_Player_DrawCorpse(gCorpses[i])
+ end;
procedure r_Player_DrawShells;
var
index f17be32d3e1ed99f8a1a6e9cd70761cb9ba0f0ac..c4fe391680359245ceb2fa49000a899ed6e60774 100644 (file)
interface
- uses g_playermodel; // TPlayerModel
+ uses g_playermodel, g_base; // TPlayerModel, TRectWH
procedure r_PlayerModel_Initialize;
procedure r_PlayerModel_Finalize;
procedure r_PlayerModel_Free;
procedure r_PlayerModel_Update;
procedure r_PlayerModel_Draw (pm: TPlayerModel; X, Y: Integer; Alpha: Byte = 0);
+ procedure r_PlayerModel_DrawGibs;
+
+ function r_PlayerModel_GetGibRect (m, id: Integer): TRectWH;
implementation
uses
SysUtils, Classes, Math,
- MAPDEF, utils,
+ MAPDEF, utils, e_log, wadreader,
ImagingTypes, Imaging, ImagingUtility,
r_graphics, g_options, r_animations, r_textures,
- g_base, g_basic, g_map, g_weapons, g_textures
+ g_basic, g_map, g_weapons, g_textures, g_player, g_phys, g_game
;
const
base: DWORD;
mask: DWORD;
end;
+ Gibs: Array of record
+ base: DWORD;
+ mask: DWORD;
+ rect: TRectWH;
+ end;
end;
RedFlagFrames: DWORD;
BlueFlagFrames: DWORD;
FlagAnimState: TAnimationState;
+ function r_PlayerModel_GetGibRect (m, id: Integer): TRectWH;
+ begin
+ Result := Models[m].Gibs[id].rect
+ end;
+
procedure r_PlayerModel_Initialize;
begin
FlagAnimState := TAnimationState.Create(True, 8, 5);
end;
end;
+ procedure r_PlayerModel_LoadResource (resource: AnsiString; var pData: Pointer; var len: Integer);
+ var WAD: TWADFile;
+ begin
+ pData := nil;
+ len := 0;
+ WAD := TWADFile.Create;
+ WAD.ReadFile(g_ExtractWadName(resource));
+ WAD.GetResource(g_ExtractFilePathName(resource), pData, len);
+ WAD.Free;
+ end;
+
+ function g_PlayerModel_CalcGibSize (pData: Pointer; dataSize, x, y, w, h: Integer): TRectWH;
+ var i, j: Integer; done: Boolean; img: TImageData;
+
+ function IsVoid (i, j: Integer): Boolean;
+ begin
+ result := Byte((PByte(img.bits) + (y+j)*img.width*4 + (x+i)*4 + 3)^) = 0
+ end;
+
+ begin
+ InitImage(img);
+ assert(LoadImageFromMemory(pData, dataSize, img));
+
+ (* trace x from right to left *)
+ done := false; i := 0;
+ while not done and (i < w) do
+ begin
+ j := 0;
+ while (j < h) and IsVoid(i, j) do inc(j);
+ done := (j < h) and (IsVoid(i, j) = false);
+ result.x := i;
+ inc(i);
+ end;
+
+ (* trace y from up to down *)
+ done := false; j := 0;
+ while not done and (j < h) do
+ begin
+ i := 0;
+ while (i < w) and IsVoid(i, j) do inc(i);
+ done := (i < w) and (IsVoid(i, j) = false);
+ result.y := j;
+ inc(j);
+ end;
+
+ (* trace x from right to left *)
+ done := false; i := w - 1;
+ while not done and (i >= 0) do
+ begin
+ j := 0;
+ while (j < h) and IsVoid(i, j) do inc(j);
+ done := (j < h) and (IsVoid(i, j) = false);
+ result.width := i - result.x + 1;
+ dec(i);
+ end;
+
+ (* trace y from down to up *)
+ done := false; j := h - 1;
+ while not done and (j >= 0) do
+ begin
+ i := 0;
+ while (i < w) and IsVoid(i, j) do inc(i);
+ done := (i < w) and (IsVoid(i, j) = false);
+ result.height := j - result.y + 1;
+ dec(j);
+ end;
+
+ FreeImage(img);
+ end;
+
procedure r_PlayerModel_Load;
- var ID1, ID2: DWORD; i, a, b: Integer; prefix, aname: String;
+ var
+ ID1, ID2: DWORD;
+ i, a, b: Integer;
+ prefix, aname: String;
+ base, mask: Pointer;
+ baseLen, maskLen: Integer;
begin
g_Frames_CreateWAD(@RedFlagFrames, 'FRAMES_FLAG_RED', GameWAD + ':TEXTURES\FLAGRED', 64, 64, 5, False);
g_Frames_CreateWAD(@BlueFlagFrames, 'FRAMES_FLAG_BLUE', GameWAD + ':TEXTURES\FLAGBLUE', 64, 64, 5, False);
Models[i].Frames[TDirection.D_LEFT, b].mask := ID2;
end
end
+ end;
+ SetLength(Models[i].Gibs, PlayerModelsArray[i].GibsCount);
+ if PlayerModelsArray[i].GibsCount > 0 then
+ begin
+ r_PlayerModel_LoadResource(prefix + PlayerModelsArray[i].GibsResource, base, baseLen);
+ r_PlayerModel_LoadResource(prefix + PlayerModelsArray[i].GibsMask, mask, maskLen);
+ if (base <> nil) and (mask <> nil) then
+ begin
+ for a := 0 to PlayerModelsArray[i].GibsCount - 1 do
+ begin
+ if e_CreateTextureMemEx(base, baseLen, Models[i].Gibs[a].base, a * 32, 0, 32, 32) and
+ e_CreateTextureMemEx(mask, maskLen, Models[i].Gibs[a].mask, a * 32, 0, 32, 32) then
+ begin
+ Models[i].Gibs[a].rect := g_PlayerModel_CalcGibSize(base, baseLen, a * 32, 0, 32, 32);
+ with Models[i].Gibs[a].Rect do
+ if Height > 3 then
+ Height := Height - 1 - Random(2); // ???
+ end
+ end
+ end;
+ FreeMem(mask);
+ FreeMem(base);
end
end
end
g_Frames_DeleteByName(Name + '_RIGHTANIM' + IntToStr(a));
g_Frames_DeleteByName(Name + '_RIGHTANIM' + IntToStr(a) + '_MASK');
end;
- if Gibs <> nil then
- begin
- for a := 0 to High(Gibs) do
- begin
- e_DeleteTexture(Gibs[a].ID);
- e_DeleteTexture(Gibs[a].MaskID);
- Gibs[a].ID := DWORD(-1);
- Gibs[a].MaskID := DWORD(-1);
- end
- end
end
+ // !!! delete gibs textures here
end;
for a := WP_FIRST + 1 to WP_LAST do
for b := W_POS_NORMAL to W_POS_DOWN do
e_Colors.B := 255;
end;
+ procedure r_PlayerModel_DrawGibs;
+ var i, fX, fY, m, id: Integer; a: TDFPoint; pobj: ^TObj;
+ begin
+ if gGibs <> nil then
+ begin
+ for i := 0 to High(gGibs) do
+ begin
+ if gGibs[i].alive then
+ begin
+ pobj := @gGibs[i].Obj;
+ if not g_Obj_Collide(sX, sY, sWidth, sHeight, pobj) then
+ Continue;
+ pobj.lerp(gLerpFactor, fX, fY);
+ a.X := pobj.Rect.X + (pobj.Rect.Width div 2);
+ a.y := pobj.Rect.Y + (pobj.Rect.Height div 2);
+ m := gGibs[i].ModelID;
+ id := gGibs[i].GibID;
+ e_DrawAdv(Models[m].Gibs[id].base, fX, fY, 0, True, False, gGibs[i].RAngle, @a, TMirrorType.None);
+ e_Colors := gGibs[i].Color;
+ e_DrawAdv(Models[m].Gibs[id].mask, fX, fY, 0, True, False, gGibs[i].RAngle, @a, TMirrorType.None);
+ e_Colors.R := 255;
+ e_Colors.G := 255;
+ e_Colors.B := 255;
+ end
+ end
+ end
+ end;
+
end.