summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 8df9e6a)
raw | patch | inline | side by side (parent: 8df9e6a)
author | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Sun, 16 Jan 2022 16:19:14 +0000 (19:19 +0300) | ||
committer | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Fri, 9 Jun 2023 07:51:14 +0000 (10:51 +0300) |
diff --git a/src/game/Doom2DF.lpr b/src/game/Doom2DF.lpr
index 2b4fe158d53daa2ced428c06cd0449bad647e51d..12b9efd61a501b2e6fef77e7a7cfb39ef2717608 100644 (file)
--- a/src/game/Doom2DF.lpr
+++ b/src/game/Doom2DF.lpr
{$IFDEF ENABLE_HOLMES}
InitHolmes;
{$ENDIF}
+ g_PlayerModel_LoadAll;
r_Render_Load;
g_Game_Init;
{$IFNDEF HEADLESS}
diff --git a/src/game/g_game.pas b/src/game/g_game.pas
index 365c0444c34fcb21c0517f25ee98a8008b22ca30..3423b33e4cd3ad2d5d2dc4ce4409db992cc5e4b6 100644 (file)
--- a/src/game/g_game.pas
+++ b/src/game/g_game.pas
end;
procedure g_Game_Init();
-var
- SR: TSearchRec;
- knownFiles: array of AnsiString = nil;
- found: Boolean;
- wext, s: AnsiString;
- f: Integer;
begin
gExit := 0;
gMapToDelete := '';
g_Game_SetLoadingText(Format('Doom 2D: Forever %s', [GAME_VERSION]), 0, False);
g_Game_SetLoadingText('', 0, False);
- g_Game_SetLoadingText(_lc[I_LOAD_MODELS], 0, False);
- // load models from all possible wad types, in all known directories
- // this does a loosy job (linear search, ooph!), but meh
- for wext in wadExtensions do
- begin
- for f := High(ModelDirs) downto Low(ModelDirs) do
- begin
- if (FindFirst(ModelDirs[f]+DirectorySeparator+'*'+wext, faAnyFile, SR) = 0) then
- begin
- repeat
- found := false;
- for s in knownFiles do
- begin
- if (strEquCI1251(forceFilenameExt(SR.Name, ''), forceFilenameExt(ExtractFileName(s), ''))) then
- begin
- found := true;
- break;
- end;
- end;
- if not found then
- begin
- SetLength(knownFiles, length(knownFiles)+1);
- knownFiles[High(knownFiles)] := ModelDirs[f]+DirectorySeparator+SR.Name;
- end;
- until (FindNext(SR) <> 0);
- end;
- FindClose(SR);
- end;
- end;
-
- if (length(knownFiles) = 0) then raise Exception.Create('no player models found!');
-
- if (length(knownFiles) = 1) then e_LogWriteln('1 player model found.', TMsgType.Notify) else e_LogWritefln('%d player models found.', [Integer(length(knownFiles))], TMsgType.Notify);
- for s in knownFiles do
- begin
- if not g_PlayerModel_Load(s) then e_LogWritefln('Error loading model "%s"', [s], TMsgType.Warning);
- end;
+// g_Game_SetLoadingText(_lc[I_LOAD_MODELS], 0, False);
gGameOn := false;
gPauseMain := false;
diff --git a/src/game/g_menu.pas b/src/game/g_menu.pas
index 34c529889e962bda2933788330910fbca2f91a30..f81733b599449751196d0a1c5081663a0e02f259 100644 (file)
--- a/src/game/g_menu.pas
+++ b/src/game/g_menu.pas
TEAM_RED, TEAM_BLUE);
with TGUIModelView(g_GUI_GetWindow('OptionsPlayersP1Menu').GetControl('mvP1Model')) do
begin
- gPlayer1Settings.Model := Model.Name;
+ gPlayer1Settings.Model := Model.GetName();
gPlayer1Settings.Color := Model.Color;
end;
TEAM_RED, TEAM_BLUE);
with TGUIModelView(g_GUI_GetWindow('OptionsPlayersP2Menu').GetControl('mvP2Model')) do
begin
- gPlayer2Settings.Model := Model.Name;
+ gPlayer2Settings.Model := Model.GetName();
gPlayer2Settings.Color := Model.Color;
end;
with TGUIModelView(g_ActiveWindow.GetControl('mv'+s+'Model')) do
begin
NextAnim();
- Model.GetCurrentAnimation.Loop := True;
- Model.GetCurrentAnimationMask.Loop := True;
+ Model.AnimState.Loop := True;
end;
end;
diff --git a/src/game/g_netmsg.pas b/src/game/g_netmsg.pas
index a2e2bc944d5ec6651f93b41a55b749e431255a5d..fb32fa2b4f40361aa7b52809167cdb2c83c3487a 100644 (file)
--- a/src/game/g_netmsg.pas
+++ b/src/game/g_netmsg.pas
if (g_Force_Model_Get() <> 0) then
TmpModel := g_Forced_Model_GetName();
- if TmpModel <> Pl.Model.Name then
+ if TmpModel <> Pl.Model.GetName() then
Pl.SetModel(TmpModel);
if (TmpWeapSwitch <> Pl.WeapSwitchMode) then
NetOut.Write(PID);
NetOut.Write(Pl.Name);
if Mdl = '' then
- NetOut.Write(Pl.Model.Name)
+ NetOut.Write(Pl.Model.GetName())
else
NetOut.Write(Mdl);
NetOut.Write(Pl.FColor.R);
if (g_Force_Model_Get() <> 0) then
TmpModel := g_Forced_Model_GetName();
- if TmpModel <> Pl.Model.Name then
+ if TmpModel <> Pl.Model.GetName() then
Pl.SetModel(TmpModel);
end;
diff --git a/src/game/g_player.pas b/src/game/g_player.pas
index acd49d048b697a658d07a6e02cf64f1b88789a4c..968c9742f14136c8c01ef3f8cdf4eb5e2de64357 100644 (file)
--- a/src/game/g_player.pas
+++ b/src/game/g_player.pas
if not ok then
find_id := Random(Length(gCorpses));
- gCorpses[find_id] := TCorpse.Create(FObj.X, FObj.Y, FModel.Name, FHealth < -20);
+ gCorpses[find_id] := TCorpse.Create(FObj.X, FObj.Y, FModel.GetName(), FHealth < -20);
gCorpses[find_id].FColor := FModel.Color;
gCorpses[find_id].FObj.Vel := FObj.Vel;
gCorpses[find_id].FObj.Accel := FObj.Accel;
else
g_Player_CreateGibs(FObj.X + PLAYER_RECT_CX,
FObj.Y + PLAYER_RECT_CY,
- FModel.Name, FModel.Color);
+ FModel.GetName(), FModel.Color);
end;
end;
end;
procedure TPlayer.MakeBloodSimple(Count: Word);
+ var Blood: TModelBlood;
begin
+ Blood := SELF.FModel.GetBlood();
g_GFX_Blood(FObj.X+PLAYER_RECT.X+(PLAYER_RECT.Width div 2)+8,
FObj.Y+PLAYER_RECT.Y+(PLAYER_RECT.Height div 2),
Count div 2, 3, -1, 16, (PLAYER_RECT.Height*2 div 3),
- FModel.Blood.R, FModel.Blood.G, FModel.Blood.B, FModel.Blood.Kind);
+ Blood.R, Blood.G, Blood.B, Blood.Kind);
g_GFX_Blood(FObj.X+PLAYER_RECT.X+(PLAYER_RECT.Width div 2)-8,
FObj.Y+PLAYER_RECT.Y+(PLAYER_RECT.Height div 2),
Count div 2, -3, -1, 16, (PLAYER_RECT.Height*2) div 3,
- FModel.Blood.R, FModel.Blood.G, FModel.Blood.B, FModel.Blood.Kind);
+ Blood.R, Blood.G, Blood.B, Blood.Kind);
end;
procedure TPlayer.MakeBloodVector(Count: Word; VelX, VelY: Integer);
+ var Blood: TModelBlood;
begin
+ Blood := SELF.FModel.GetBlood();
g_GFX_Blood(FObj.X+PLAYER_RECT.X+(PLAYER_RECT.Width div 2),
FObj.Y+PLAYER_RECT.Y+(PLAYER_RECT.Height div 2),
Count, VelX, VelY, 16, (PLAYER_RECT.Height*2) div 3,
- FModel.Blood.R, FModel.Blood.G, FModel.Blood.B, FModel.Blood.Kind);
+ Blood.R, Blood.G, Blood.B, Blood.Kind);
end;
procedure TPlayer.ProcessWeaponAction(Action: Byte);
if (FActionAnim = A_PAIN) and (FModel.Animation <> A_PAIN) then
begin
FModel.ChangeAnimation(FActionAnim, FActionForce);
- FModel.GetCurrentAnimation.MinLength := i;
- FModel.GetCurrentAnimationMask.MinLength := i;
+ FModel.AnimState.MinLength := i;
end else FModel.ChangeAnimation(FActionAnim, FActionForce and (FModel.Animation <> A_STAND));
- if (FModel.GetCurrentAnimation.Played or ((not FActionChanged) and (FModel.Animation = A_WALK)))
+ if (FModel.AnimState.Played or ((not FActionChanged) and (FModel.Animation = A_WALK)))
then SetAction(A_STAND, True);
if not ((FModel.Animation = A_WALK) and (Abs(FObj.Vel.X) < 4) and not FModel.Fire) then FModel.Update;
// Время до повторного респауна, смены оружия, исользования, захвата флага
for i := T_RESPAWN to T_FLAGCAP do utils.writeInt(st, LongWord(FTime[i]));
// Название модели
- utils.writeStr(st, FModel.Name);
+ utils.writeStr(st, FModel.GetName());
// Цвет модели
utils.writeInt(st, Byte(FColor.R));
utils.writeInt(st, Byte(FColor.G));
index af56f51bbce5cabce54bb8cee797cdbb57e3ce99..8ffb589787109f0a7ccf680e619b87c4dea97ea4 100644 (file)
FLAG_BASEPOINT: TDFPoint = (X:16; Y:43);
type
+ TWeaponPoints = Array [WP_FIRST + 1..WP_LAST, A_STAND..A_LAST, TDirection.D_LEFT..TDirection.D_RIGHT] of Array of TDFPoint;
+
+ TModelMatrix = Array [TDirection.D_LEFT..TDirection.D_RIGHT, A_STAND..A_LAST] of TAnimationState;
+
+ TModelTextures = Array [TDirection.D_LEFT..TDirection.D_RIGHT, A_STAND..A_LAST] of record
+ Resource: String;
+ Mask: String;
+ Frames: Integer;
+ Back: Boolean;
+ end;
+
+ TModelBlood = record
+ R, G, B, Kind: Byte;
+ end;
+
TModelInfo = record
Name: String;
Author: String;
HaveWeapon: Boolean;
end;
- TModelBlood = record
- R, G, B, Kind: Byte;
- end;
-
TModelSound = record
ID: DWORD;
Level: Byte;
TModelSoundArray = Array of TModelSound;
TGibsArray = Array of TGibSprite;
- TWeaponPoints = Array [WP_FIRST + 1..WP_LAST] of
- Array [A_STAND..A_LAST] of
- Array [TDirection.D_LEFT..TDirection.D_RIGHT] of Array of TDFPoint;
- TModelMatrix = Array [TDirection.D_LEFT..TDirection.D_RIGHT] of Array [A_STAND..A_LAST] of TAnimation;
TPlayerModel = class{$IFDEF USE_MEMPOOL}(TPoolObject){$ENDIF}
private
- FName: String;
FDirection: TDirection;
FColor: TRGB;
- FBlood: TModelBlood;
FCurrentAnimation: Byte;
- FAnim: TModelMatrix;
- FMaskAnim: TModelMatrix;
- FWeaponPoints: TWeaponPoints;
+ FAnimState: TAnimationState;
FPainSounds: TModelSoundArray;
FDieSounds: TModelSoundArray;
FSlopSound: Byte;
FCurrentWeapon: Byte;
- FDrawWeapon: Boolean;
FFlag: Byte;
FFlagPoint: TDFPoint;
FFlagAngle: SmallInt;
- FFlagAnim: TAnimation;
+ FFlagAnim: TAnimation; // !!! TAnimationState
FFire: Boolean;
FFireCounter: Byte;
+ FID: Integer;
public
destructor Destroy(); override;
procedure ChangeAnimation(Animation: Byte; Force: Boolean = False);
- function GetCurrentAnimation: TAnimation;
- function GetCurrentAnimationMask: TAnimation;
procedure SetColor(Red, Green, Blue: Byte);
procedure SetWeapon(Weapon: Byte);
procedure SetFlag(Flag: Byte);
function PlaySound(SoundType, Level: Byte; X, Y: Integer): Boolean;
procedure Update();
+ function GetBlood (): TModelBlood;
+ function GetName (): String;
+
published
property Fire: Boolean read FFire;
property Direction: TDirection read FDirection write FDirection;
property Animation: Byte read FCurrentAnimation;
property Weapon: Byte read FCurrentWeapon;
- property Name: String read FName;
public
property Color: TRGB read FColor write FColor;
- property Blood: TModelBlood read FBlood;
- property Anim: TModelMatrix read FAnim;
- property MaskAnim: TModelMatrix read FMaskAnim;
+ property AnimState: TAnimationState read FAnimState;
property CurrentAnimation: Byte read FCurrentAnimation;
property CurrentWeapon: Byte read FCurrentWeapon;
- property DrawWeapon: Boolean read FDrawWeapon;
- property WeaponPoints: TWeaponPoints read FWeaponPoints;
property Flag: Byte read FFlag;
property FlagAnim: TAnimation read FFlagAnim;
property FlagAngle: SmallInt read FFlagAngle;
property FlagPoint: TDFPoint read FFlagPoint;
+
+ property ID: Integer read FID;
end;
+procedure g_PlayerModel_LoadAll;
procedure g_PlayerModel_FreeData();
function g_PlayerModel_Load(FileName: String): Boolean;
function g_PlayerModel_GetNames(): SSArray;
function g_PlayerModel_GetInfo(ModelName: String): TModelInfo;
function g_PlayerModel_GetBlood(ModelName: String): TModelBlood;
function g_PlayerModel_Get(ModelName: String): TPlayerModel;
-function g_PlayerModel_GetAnim(ModelName: String; Anim: Byte; var _Anim, _Mask: TAnimation): Boolean;
+function g_PlayerModel_GetAnim(ModelName: String; AnimTyp: Byte; var _Anim, _Mask: TAnimation): Boolean;
function g_PlayerModel_GetGibs(ModelName: String; var Gibs: TGibsArray): Boolean;
+(* --- private data --- *)
+
+ type
+ TPlayerModelInfo = record
+ Info: TModelInfo;
+ ModelSpeed: Array [A_STAND..A_PAIN] of Byte;
+ FlagPoint: TDFPoint;
+ FlagAngle: SmallInt;
+ WeaponPoints: TWeaponPoints;
+ Gibs: TGibsArray; // !!! move to render
+ PainSounds: TModelSoundArray;
+ DieSounds: TModelSoundArray;
+ SlopSound: Byte;
+ Blood: TModelBlood;
+ // =======================
+ FileName: String;
+ Anim: TModelTextures;
+ GibsCount: Integer;
+ GibsResource:String;
+ GibsMask: String;
+ GibsOnce: Integer;
+ end;
+
+ var
+ PlayerModelsArray: Array of TPlayerModelInfo;
implementation
g_sound, g_console, SysUtils, g_player, CONFIG, r_textures, r_animations,
e_sound, g_options, g_map, Math, e_log, wadreader;
-type
- TPlayerModelInfo = record
- Info: TModelInfo;
- ModelSpeed: Array [A_STAND..A_PAIN] of Byte;
- FlagPoint: TDFPoint;
- FlagAngle: SmallInt;
- WeaponPoints: TWeaponPoints;
- Gibs: TGibsArray;
- PainSounds: TModelSoundArray;
- DieSounds: TModelSoundArray;
- SlopSound: Byte;
- Blood: TModelBlood;
- end;
-
const
FLAG_DEFPOINT: TDFPoint = (X:32; Y:16);
FLAG_DEFANGLE = -20;
WeapNames: Array [WP_FIRST + 1..WP_LAST] of String =
('csaw', 'hgun', 'sg', 'ssg', 'mgun', 'rkt', 'plz', 'bfg', 'spl', 'flm');
-var
- PlayerModelsArray: Array of TPlayerModelInfo;
-
function GetPoint(var str: String; var point: TDFPoint): Boolean;
var
a, x, y: Integer;
Result := True;
end;
-procedure ExtAnimFromBaseAnim(MName: String; AIdx: Integer);
-const
- CopyAnim: array [A_LASTBASE+1..A_LASTEXT] of Integer = (
- A_WALK, A_WALK, A_WALK, A_WALK, A_WALK,
- A_STAND, A_WALK, A_ATTACK, A_WALK, A_SEEUP, A_SEEDOWN,
- A_ATTACKUP, A_ATTACKDOWN
- );
-var
- OIdx, W, I: Integer;
- D: TDirection;
- AName, OName: String;
-begin
- // HACK: shitty workaround to duplicate base animations
- // in place of extended, replace with something better later
-
- Assert((AIdx > A_LASTBASE) and (AIdx <= A_LASTEXT));
- OIdx := CopyAnim[AIdx];
-
- AName := MName + '_RIGHTANIM' + IntToStr(AIdx);
- OName := MName + '_RIGHTANIM' + IntToStr(OIdx);
- Assert(g_Frames_Dup(AName, OName));
- Assert(g_Frames_Dup(AName + '_MASK', OName + '_MASK'));
- AName := MName + '_LEFTANIM' + IntToStr(AIdx);
- OName := MName + '_LEFTANIM' + IntToStr(OIdx);
- if g_Frames_Exists(AName) then
- begin
- g_Frames_Dup(AName, OName);
- g_Frames_Dup(AName + '_MASK', OName + '_MASK');
- end;
-
- with PlayerModelsArray[High(PlayerModelsArray)] do
+ procedure g_PlayerMode_ExtendPoints (id: Integer; AIdx: Integer);
+ const
+ CopyAnim: array [A_LASTBASE+1..A_LASTEXT] of Integer = (
+ A_WALK, A_WALK, A_WALK, A_WALK, A_WALK,
+ A_STAND, A_WALK, A_ATTACK, A_WALK, A_SEEUP, A_SEEDOWN,
+ A_ATTACKUP, A_ATTACKDOWN
+ );
+ var W, I, OIdx: Integer; D: TDirection;
begin
- for W := WP_FIRST + 1 to WP_LAST do
+ OIdx := CopyAnim[AIdx];
+ with PlayerModelsArray[id] do
begin
- for D := TDirection.D_LEFT to TDirection.D_RIGHT do
+ for W := WP_FIRST + 1 to WP_LAST do
begin
- SetLength(WeaponPoints[W, AIdx, D], Length(WeaponPoints[W, OIdx, D]));
- for I := 0 to High(WeaponPoints[W, AIdx, D]) do
- WeaponPoints[W, AIdx, D, I] := WeaponPoints[W, OIdx, D, I]
+ for D := TDirection.D_LEFT to TDirection.D_RIGHT do
+ begin
+ SetLength(WeaponPoints[W, AIdx, D], Length(WeaponPoints[W, OIdx, D]));
+ for I := 0 to High(WeaponPoints[W, AIdx, D]) do
+ WeaponPoints[W, AIdx, D, I] := WeaponPoints[W, OIdx, D, I]
+ end;
end;
end;
end;
-end;
function g_PlayerModel_CalcGibSize (pData: Pointer; dataSize, x, y, w, h: Integer): TRectWH;
var i, j: Integer; done: Boolean; img: TImageData;
config: TConfig;
pData, pData2: Pointer;
WAD: TWADFile;
- s, aname: string;
+ s: string;
prefix: string;
- ok, chk: Boolean;
+ ok, chk, chk2: Boolean;
begin
e_WriteLog(Format('Loading player model "%s"...', [FileName]), TMsgType.Notify);
Description := config.ReadStr('Model', 'description', '');
end;
+ PlayerModelsArray[ID].FileName := FileName;
with PlayerModelsArray[ID] do
begin
Blood.R := MAX(0, MIN(255, config.ReadInt('Blood', 'R', 150)));
for b := A_STAND to A_LAST do
begin
- aname := s+'_RIGHTANIM'+IntToStr(b);
- //e_LogWritefln('### MODEL FILE: [%s]', [prefix+config.ReadStr(AnimNames[b], 'resource', '')]);
- if not (g_Frames_CreateWAD(nil, aname,
- prefix+config.ReadStr(AnimNames[b], 'resource', ''),
- 64, 64, config.ReadInt(AnimNames[b], 'frames', 1),
- config.ReadBool(AnimNames[b], 'backanim', False)) and
- g_Frames_CreateWAD(nil, aname+'_MASK',
- prefix+config.ReadStr(AnimNames[b], 'mask', ''),
- 64, 64, config.ReadInt(AnimNames[b], 'frames', 1),
- config.ReadBool(AnimNames[b], 'backanim', False))) then
+ with PlayerModelsArray[ID].Anim[TDirection.D_RIGHT, b] do
begin
- if b <= A_LASTBASE then
- begin
- config.Free();
- WAD.Free();
- Exit;
- end
- else
+ Resource := config.ReadStr(AnimNames[b], 'resource', '');
+ Mask := config.ReadStr(AnimNames[b], 'mask', '');
+ Frames := config.ReadInt(AnimNames[b], 'frames', 1);
+ Back := config.ReadBool(AnimNames[b], 'backanim', False);
+ if (Resource = '') or (Mask = '') then
begin
- ExtAnimFromBaseAnim(s, b);
- continue;
+ if b <= A_LASTBASE then
+ begin
+ config.Free();
+ WAD.Free();
+ Exit
+ end
+ else
+ begin
+ g_PlayerMode_ExtendPoints(ID, b);
+ continue
+ end
end;
end;
for bb := A_STAND to A_LAST do
for cc := TDirection.D_LEFT to TDirection.D_RIGHT do
begin
- f := config.ReadInt(AnimNames[bb], 'frames', 1);
- if config.ReadBool(AnimNames[bb], 'backanim', False) then
- if f > 2 then f := 2*f-2;
+ f := PlayerModelsArray[ID].Anim[cc, bb].Frames;
+ if PlayerModelsArray[ID].Anim[cc, bb].Back and (f > 2) then
+ f := 2 * f - 2;
SetLength(PlayerModelsArray[ID].WeaponPoints[aa, bb, cc], f);
end;
- if (config.ReadStr(AnimNames[b], 'resource2', '') <> '') and
- (config.ReadStr(AnimNames[b], 'mask2', '') <> '') then
+ with PlayerModelsArray[ID].Anim[TDirection.D_LEFT, b] do
begin
- aname := s+'_LEFTANIM'+IntToStr(b);
- g_Frames_CreateWAD(nil, aname,
- prefix+config.ReadStr(AnimNames[b], 'resource2', ''),
- 64, 64, config.ReadInt(AnimNames[b], 'frames', 1),
- config.ReadBool(AnimNames[b], 'backanim', False));
-
- g_Frames_CreateWAD(nil, aname+'_MASK',
- prefix+config.ReadStr(AnimNames[b], 'mask2', ''),
- 64, 64, config.ReadInt(AnimNames[b], 'frames', 1),
- config.ReadBool(AnimNames[b], 'backanim', False));
+ Frames := PlayerModelsArray[ID].Anim[TDirection.D_RIGHT, b].Frames;
+ Back := PlayerModelsArray[ID].Anim[TDirection.D_RIGHT, b].Back;
end;
PlayerModelsArray[ID].ModelSpeed[b] := Max(1, config.ReadInt(AnimNames[b], 'waitcount', 1) div 3);
SlopSound := Min(Max(config.ReadInt('Sound', 'slop', 0), 0), 2);
- SetLength(Gibs, ReadInt('Gibs', 'count', 0));
+ GibsCount := config.ReadInt('Gibs', 'count', 0);
+ GibsResource := config.ReadStr('Gibs', 'resource', 'GIBS');
+ GibsMask := config.ReadStr('Gibs', 'mask', 'GIBSMASK');
+ GibsOnce := config.ReadInt('Gibs', 'once', -1);
+ SetLength(Gibs, GibsCount); // !!! remove load
if (Gibs <> nil) and
- (WAD.GetResource('TEXTURES/'+config.ReadStr('Gibs', 'resource', 'GIBS'), pData, lenpd)) and
- (WAD.GetResource('TEXTURES/'+config.ReadStr('Gibs', 'mask', 'GIBSMASK'), pData2, lenpd2)) then
+ (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
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 := config.ReadInt('Gibs', 'once', -1) = a+1;
+ Gibs[a].OnlyOne := GibsOnce = a + 1;
end;
FreeMem(pData);
for bb := A_STAND to A_LAST do
if not (bb in [A_DIE1, A_DIE2, A_PAIN]) then
begin
- chk := GetWeapPoints(config.ReadStr(AnimNames[bb], WeapNames[aa]+'_points', ''), aa, bb, TDirection.D_RIGHT,
- config.ReadInt(AnimNames[bb], 'frames', 0),
- config.ReadBool(AnimNames[bb], 'backanim', False),
- WeaponPoints);
+ chk := GetWeapPoints(
+ config.ReadStr(AnimNames[bb], WeapNames[aa] + '_points', ''),
+ aa,
+ bb,
+ TDirection.D_RIGHT,
+ Anim[TDirection.D_RIGHT, bb].Frames,
+ Anim[TDirection.D_RIGHT, bb].Back,
+ WeaponPoints
+ );
if ok and (not chk) and (aa = WEAPON_FLAMETHROWER) then
begin
// workaround for flamethrower
- chk := GetWeapPoints(config.ReadStr(AnimNames[bb], WeapNames[WEAPON_PLASMA]+'_points', ''), aa, bb, TDirection.D_RIGHT,
- config.ReadInt(AnimNames[bb], 'frames', 0),
- config.ReadBool(AnimNames[bb], 'backanim', False),
- WeaponPoints);
+ chk := GetWeapPoints(
+ config.ReadStr(AnimNames[bb], WeapNames[WEAPON_PLASMA] + '_points', ''),
+ aa,
+ bb,
+ TDirection.D_RIGHT,
+ Anim[TDirection.D_RIGHT, bb].Frames,
+ Anim[TDirection.D_RIGHT, bb].Back,
+ WeaponPoints
+ );
if chk then
for f := 0 to High(WeaponPoints[aa, bb, TDirection.D_RIGHT]) do
begin
end;
end;
end;
+
ok := ok and (chk or (bb > A_LASTBASE));
- if not GetWeapPoints(config.ReadStr(AnimNames[bb], WeapNames[aa]+'2_points', ''), aa, bb, TDirection.D_LEFT,
- config.ReadInt(AnimNames[bb], 'frames', 0),
- config.ReadBool(AnimNames[bb], 'backanim', False),
- WeaponPoints) then
+ chk2 := GetWeapPoints(
+ config.ReadStr(AnimNames[bb], WeapNames[aa] + '2_points', ''),
+ aa,
+ bb,
+ TDirection.D_LEFT,
+ Anim[TDirection.D_LEFT, bb].Frames,
+ Anim[TDirection.D_LEFT, bb].Back,
+ WeaponPoints
+ );
+ if not chk2 then
+ begin
for f := 0 to High(WeaponPoints[aa, bb, TDirection.D_RIGHT]) do
begin
WeaponPoints[aa, bb, TDirection.D_LEFT, f].X := -WeaponPoints[aa, bb, TDirection.D_RIGHT, f].X;
WeaponPoints[aa, bb, TDirection.D_LEFT, f].Y := WeaponPoints[aa, bb, TDirection.D_RIGHT, f].Y;
end;
+ end;
if not ok then Break;
end;
Info.HaveWeapon := ok;
s := config.ReadStr('Model', 'flag_point', '');
- if not GetPoint(s, FlagPoint) then FlagPoint := FLAG_DEFPOINT;
+ if not GetPoint(s, FlagPoint) then
+ FlagPoint := FLAG_DEFPOINT;
FlagAngle := config.ReadInt('Model', 'flag_angle', FLAG_DEFANGLE);
end;
end;
function g_PlayerModel_Get(ModelName: String): TPlayerModel;
-var
- a: Integer;
- b: Byte;
- ID, ID2: DWORD;
+ var a: Integer;
begin
Result := nil;
if PlayerModelsArray = nil then Exit;
for a := 0 to High(PlayerModelsArray) do
+ begin
if AnsiLowerCase(PlayerModelsArray[a].Info.Name) = AnsiLowerCase(ModelName) then
begin
Result := TPlayerModel.Create;
with PlayerModelsArray[a] do
begin
- Result.FName := Info.Name;
- Result.FBlood := Blood;
-
- for b := A_STAND to A_LAST do
- begin
- if not (g_Frames_Get(ID, Info.Name+'_RIGHTANIM'+IntToStr(b)) and
- g_Frames_Get(ID2, Info.Name+'_RIGHTANIM'+IntToStr(b)+'_MASK')) then
- begin
- Result.Free();
- Result := nil;
- Exit;
- end;
-
- Result.FAnim[TDirection.D_RIGHT][b] := TAnimation.Create(ID, b in [A_STAND, A_WALK], ModelSpeed[b]);
-
- Result.FMaskAnim[TDirection.D_RIGHT][b] := TAnimation.Create(ID2, b in [A_STAND, A_WALK], ModelSpeed[b]);
-
- if g_Frames_Exists(Info.Name+'_LEFTANIM'+IntToStr(b)) and
- g_Frames_Exists(Info.Name+'_LEFTANIM'+IntToStr(b)+'_MASK') then
- if g_Frames_Get(ID, Info.Name+'_LEFTANIM'+IntToStr(b)) and
- g_Frames_Get(ID2, Info.Name+'_LEFTANIM'+IntToStr(b)+'_MASK') then
- begin
- Result.FAnim[TDirection.D_LEFT][b] := TAnimation.Create(ID, b in [A_STAND, A_WALK], ModelSpeed[b]);
-
- Result.FMaskAnim[TDirection.D_LEFT][b] := TAnimation.Create(ID2, b in [A_STAND, A_WALK], ModelSpeed[b]);
- end;
- end;
-
Result.FPainSounds := PainSounds;
Result.FDieSounds := DieSounds;
Result.FSlopSound := SlopSound;
- Result.FDrawWeapon := Info.HaveWeapon;
- Result.FWeaponPoints := WeaponPoints;
Result.FFlagPoint := FlagPoint;
Result.FFlagAngle := FlagAngle;
+ Result.FID := a;
+
+ Result.ChangeAnimation(A_STAND, True);
Break;
end;
+ end;
end;
end;
-function g_PlayerModel_GetAnim(ModelName: string; Anim: Byte; var _Anim, _Mask: TAnimation): Boolean;
+function g_PlayerModel_GetAnim(ModelName: string; AnimTyp: Byte; var _Anim, _Mask: TAnimation): Boolean;
var
a: Integer;
c: Boolean;
if PlayerModelsArray[a].Info.Name = ModelName then
with PlayerModelsArray[a] do
begin
- if Anim in [A_STAND, A_WALK] then c := True else c := False;
+ if AnimTyp in [A_STAND, A_WALK] then c := True else c := False;
- if not g_Frames_Get(ID, Info.Name+'_RIGHTANIM'+IntToStr(Anim)) then
- if not g_Frames_Get(ID, Info.Name+'_LEFTANIM'+IntToStr(Anim)) then Exit;
+ if not g_Frames_Get(ID, Info.Name+'_RIGHTANIM'+IntToStr(AnimTyp)) then
+ if not g_Frames_Get(ID, Info.Name+'_LEFTANIM'+IntToStr(AnimTyp)) then Exit;
- _Anim := TAnimation.Create(ID, c, ModelSpeed[Anim]);
- _Anim.Speed := ModelSpeed[Anim];
+ _Anim := TAnimation.Create(ID, c, ModelSpeed[AnimTyp]);
+ _Anim.Speed := ModelSpeed[AnimTyp];
- if not g_Frames_Get(ID, Info.Name+'_RIGHTANIM'+IntToStr(Anim)+'_MASK') then
- if not g_Frames_Get(ID, Info.Name+'_LEFTANIM'+IntToStr(Anim)+'_MASK') then Exit;
+ if not g_Frames_Get(ID, Info.Name+'_RIGHTANIM'+IntToStr(AnimTyp)+'_MASK') then
+ if not g_Frames_Get(ID, Info.Name+'_LEFTANIM'+IntToStr(AnimTyp)+'_MASK') then Exit;
- _Mask := TAnimation.Create(ID, c, ModelSpeed[Anim]);
- _Mask.Speed := ModelSpeed[Anim];
+ _Mask := TAnimation.Create(ID, c, ModelSpeed[AnimTyp]);
+ _Mask.Speed := ModelSpeed[AnimTyp];
Break;
end;
end;
procedure g_PlayerModel_FreeData();
-var
- i: DWORD;
- a, b: Integer;
+ var i, b: Integer;
begin
e_WriteLog('Releasing models...', TMsgType.Notify);
if PlayerModelsArray = nil then Exit;
for i := 0 to High(PlayerModelsArray) do
+ begin
with PlayerModelsArray[i] do
begin
- for a := A_STAND to A_LAST do
- begin
- g_Frames_DeleteByName(Info.Name+'_LEFTANIM'+IntToStr(a));
- g_Frames_DeleteByName(Info.Name+'_LEFTANIM'+IntToStr(a)+'_MASK');
- g_Frames_DeleteByName(Info.Name+'_RIGHTANIM'+IntToStr(a));
- g_Frames_DeleteByName(Info.Name+'_RIGHTANIM'+IntToStr(a)+'_MASK');
- end;
-
if PainSounds <> nil then
for b := 0 to High(PainSounds) do
e_DeleteSound(PainSounds[b].ID);
-
if DieSounds <> nil then
for b := 0 to High(DieSounds) do
e_DeleteSound(DieSounds[b].ID);
-
- if Gibs <> nil then
- for b := 0 to High(Gibs) do
- begin
- e_DeleteTexture(Gibs[b].ID);
- e_DeleteTexture(Gibs[b].MaskID);
- end;
end;
-
+ end;
PlayerModelsArray := nil;
end;
{ TPlayerModel }
-procedure TPlayerModel.ChangeAnimation(Animation: Byte; Force: Boolean = False);
-begin
- if not Force then if FCurrentAnimation = Animation then Exit;
-
- FCurrentAnimation := Animation;
-
- if (FDirection = TDirection.D_LEFT) and
- (FAnim[TDirection.D_LEFT][FCurrentAnimation] <> nil) and
- (FMaskAnim[TDirection.D_LEFT][FCurrentAnimation] <> nil) then
+ procedure TPlayerModel.ChangeAnimation (Animation: Byte; Force: Boolean = False);
+ var once: Boolean; speed, count: Integer;
begin
- FAnim[TDirection.D_LEFT][FCurrentAnimation].Reset;
- FMaskAnim[TDirection.D_LEFT][FCurrentAnimation].Reset;
- end
- else
- begin
- FAnim[TDirection.D_RIGHT][FCurrentAnimation].Reset;
- FMaskAnim[TDirection.D_RIGHT][FCurrentAnimation].Reset;
+ if not Force then
+ if FCurrentAnimation = Animation then
+ Exit;
+ FCurrentAnimation := Animation;
+ once := FCurrentAnimation in [A_STAND, A_WALK];
+ speed := PlayerModelsArray[FID].ModelSpeed[FCurrentAnimation];
+ count := PlayerModelsArray[FID].Anim[FDirection, FCurrentAnimation].Frames;
+ FAnimState := TAnimationState.Create(once, speed, count);
end;
-end;
destructor TPlayerModel.Destroy();
-var
- a: Byte;
begin
- for a := A_STAND to A_LAST do
- begin
- FAnim[TDirection.D_LEFT][a].Free();
- FMaskAnim[TDirection.D_LEFT][a].Free();
- FAnim[TDirection.D_RIGHT][a].Free();
- FMaskAnim[TDirection.D_RIGHT][a].Free();
- end;
-
+ FAnimState.Free;
inherited;
end;
-function TPlayerModel.GetCurrentAnimation: TAnimation;
-begin
- if (FDirection = TDirection.D_LEFT) and (FAnim[TDirection.D_LEFT][FCurrentAnimation] <> nil) then
- Result := FAnim[TDirection.D_LEFT][FCurrentAnimation]
- else
- Result := FAnim[TDirection.D_RIGHT][FCurrentAnimation];
-end;
-
-function TPlayerModel.GetCurrentAnimationMask: TAnimation;
-begin
- if (FDirection = TDirection.D_LEFT) and (FMaskAnim[TDirection.D_LEFT][FCurrentAnimation] <> nil) then
- Result := FMaskAnim[TDirection.D_LEFT][FCurrentAnimation]
- else
- Result := FMaskAnim[TDirection.D_RIGHT][FCurrentAnimation];
-end;
-
function TPlayerModel.PlaySound(SoundType, Level: Byte; X, Y: Integer): Boolean;
var
TempArray: array of DWORD;
procedure TPlayerModel.SetFire(Fire: Boolean);
begin
FFire := Fire;
-
- if FFire then FFireCounter := FAnim[TDirection.D_RIGHT, A_ATTACK].Speed*FAnim[TDirection.D_RIGHT, A_ATTACK].TotalFrames
- else FFireCounter := 0;
+ if FFire then
+ FFireCounter := PlayerModelsArray[FID].ModelSpeed[A_ATTACK] * PlayerModelsArray[FID].Anim[TDirection.D_RIGHT, A_ATTACK].Frames
+ else
+ FFireCounter := 0
end;
procedure TPlayerModel.SetFlag(Flag: Byte);
var
- id: DWORD;
+ tid: DWORD;
begin
FFlag := Flag;
FFlagAnim := nil;
case Flag of
- FLAG_RED: g_Frames_Get(id, 'FRAMES_FLAG_RED');
- FLAG_BLUE: g_Frames_Get(id, 'FRAMES_FLAG_BLUE');
+ FLAG_RED: g_Frames_Get(tid, 'FRAMES_FLAG_RED');
+ FLAG_BLUE: g_Frames_Get(tid, 'FRAMES_FLAG_BLUE');
else Exit;
end;
- FFlagAnim := TAnimation.Create(id, True, 8);
+ FFlagAnim := TAnimation.Create(tid, True, 8);
end;
-procedure TPlayerModel.SetWeapon(Weapon: Byte);
-begin
- FCurrentWeapon := Weapon;
-end;
+ procedure TPlayerModel.SetWeapon(Weapon: Byte);
+ begin
+ FCurrentWeapon := Weapon;
+ end;
-procedure TPlayerModel.Update();
-begin
- if (FDirection = TDirection.D_LEFT) and (FAnim[TDirection.D_LEFT][FCurrentAnimation] <> nil) then
- FAnim[TDirection.D_LEFT][FCurrentAnimation].Update else FAnim[TDirection.D_RIGHT][FCurrentAnimation].Update;
+ function TPlayerModel.GetBlood (): TModelBlood;
+ begin
+ Result := PlayerModelsArray[FID].Blood
+ end;
- if (FDirection = TDirection.D_LEFT) and (FMaskAnim[TDirection.D_LEFT][FCurrentAnimation] <> nil) then
- FMaskAnim[TDirection.D_LEFT][FCurrentAnimation].Update else FMaskAnim[TDirection.D_RIGHT][FCurrentAnimation].Update;
+ function TPlayerModel.GetName (): String;
+ begin
+ Result := PlayerModelsArray[FID].Info.Name
+ end;
- if FFlagAnim <> nil then FFlagAnim.Update;
+ procedure TPlayerModel.Update;
+ begin
+ if FAnimState <> nil then
+ FAnimState.Update;
+ if FFlagAnim <> nil then
+ FFlagAnim.Update;
+ if FFireCounter > 0 then
+ Dec(FFireCounter)
+ else
+ FFire := False
+ end;
- if FFireCounter > 0 then Dec(FFireCounter) else FFire := False;
-end;
+ procedure g_PlayerModel_LoadAll;
+ var
+ SR: TSearchRec;
+ knownFiles: array of AnsiString = nil;
+ found: Boolean;
+ wext, s: AnsiString;
+ f: Integer;
+ begin
+ // load models from all possible wad types, in all known directories
+ // this does a loosy job (linear search, ooph!), but meh
+ for wext in wadExtensions do
+ begin
+ for f := High(ModelDirs) downto Low(ModelDirs) do
+ begin
+ if (FindFirst(ModelDirs[f]+DirectorySeparator+'*'+wext, faAnyFile, SR) = 0) then
+ begin
+ repeat
+ found := false;
+ for s in knownFiles do
+ begin
+ if (strEquCI1251(forceFilenameExt(SR.Name, ''), forceFilenameExt(ExtractFileName(s), ''))) then
+ begin
+ found := true;
+ break;
+ end;
+ end;
+ if not found then
+ begin
+ SetLength(knownFiles, length(knownFiles)+1);
+ knownFiles[High(knownFiles)] := ModelDirs[f]+DirectorySeparator+SR.Name;
+ end;
+ until (FindNext(SR) <> 0);
+ end;
+ FindClose(SR);
+ end;
+ end;
+ if (length(knownFiles) = 0) then
+ raise Exception.Create('no player models found!');
+ if (length(knownFiles) = 1) then
+ e_LogWriteln('1 player model found.', TMsgType.Notify)
+ else
+ e_LogWritefln('%d player models found.', [Integer(length(knownFiles))], TMsgType.Notify);
+ for s in knownFiles do
+ if not g_PlayerModel_Load(s) then
+ e_LogWritefln('Error loading model "%s"', [s], TMsgType.Warning);
+ end;
end.
index c15a713800114833cd4fe50d89af4b2705410d05..1602f23e0d2b346d9c4f10e77665ca249486657d 100644 (file)
uses g_playermodel; // TPlayerModel
- procedure r_PlayerModel_Initialize;
- procedure r_PlayerModel_Finalize;
+ procedure r_PlayerModel_Load;
+ procedure r_PlayerModel_Free;
procedure r_PlayerModel_Draw (pm: TPlayerModel; X, Y: Integer; Alpha: Byte = 0);
implementation
uses
SysUtils, Classes, Math,
- MAPDEF,
+ MAPDEF, utils,
+ ImagingTypes, Imaging, ImagingUtility,
r_graphics, g_options, r_animations, r_textures,
g_base, g_basic, g_map, g_weapons
;
const
WeapNames: Array [WP_FIRST + 1..WP_LAST] of String = ('csaw', 'hgun', 'sg', 'ssg', 'mgun', 'rkt', 'plz', 'bfg', 'spl', 'flm');
+ type
+ TDirIdx = TDirection.D_LEFT..TDirection.D_RIGHT;
+ TAnimIdx = A_STAND..A_LAST;
+
var
WeaponID: Array [WP_FIRST + 1..WP_LAST, W_POS_NORMAL..W_POS_DOWN, W_ACT_NORMAL..W_ACT_FIRE] of DWORD;
+ Models: Array of record
+ Frames: Array [TDirIdx, TAnimIdx] of record
+ base: DWORD;
+ mask: DWORD;
+ end;
+ end;
-procedure r_PlayerModel_Initialize;
-var
- a: Integer;
-begin
- for a := WP_FIRST + 1 to WP_LAST do
+ procedure ExtAnimFromBaseAnim(MName: String; AIdx: Integer);
+ const
+ CopyAnim: array [A_LASTBASE+1..A_LASTEXT] of Integer = (
+ A_WALK, A_WALK, A_WALK, A_WALK, A_WALK,
+ A_STAND, A_WALK, A_ATTACK, A_WALK, A_SEEUP, A_SEEDOWN,
+ A_ATTACKUP, A_ATTACKDOWN
+ );
+ var
+ OIdx: Integer;
+ AName, OName: String;
+ begin
+ // HACK: shitty workaround to duplicate base animations
+ // in place of extended, replace with something better later
+
+ Assert((AIdx > A_LASTBASE) and (AIdx <= A_LASTEXT));
+ OIdx := CopyAnim[AIdx];
+
+ AName := MName + '_RIGHTANIM' + IntToStr(AIdx);
+ OName := MName + '_RIGHTANIM' + IntToStr(OIdx);
+ Assert(g_Frames_Dup(AName, OName));
+ Assert(g_Frames_Dup(AName + '_MASK', OName + '_MASK'));
+ AName := MName + '_LEFTANIM' + IntToStr(AIdx);
+ OName := MName + '_LEFTANIM' + IntToStr(OIdx);
+ if g_Frames_Exists(AName) then
+ begin
+ g_Frames_Dup(AName, OName);
+ g_Frames_Dup(AName + '_MASK', OName + '_MASK');
+ end;
+ end;
+
+ procedure r_PlayerModel_Load;
+ var ID1, ID2: DWORD; i, a, b: Integer; prefix, aname: String;
begin
- g_Texture_CreateWAD(WeaponID[a][W_POS_NORMAL][W_ACT_NORMAL], GameWAD+':WEAPONS\'+UpperCase(WeapNames[a]));
- g_Texture_CreateWAD(WeaponID[a][W_POS_NORMAL][W_ACT_FIRE], GameWAD+':WEAPONS\'+UpperCase(WeapNames[a])+'_FIRE');
- g_Texture_CreateWAD(WeaponID[a][W_POS_UP][W_ACT_NORMAL], GameWAD+':WEAPONS\'+UpperCase(WeapNames[a])+'_UP');
- g_Texture_CreateWAD(WeaponID[a][W_POS_UP][W_ACT_FIRE], GameWAD+':WEAPONS\'+UpperCase(WeapNames[a])+'_UP_FIRE');
- g_Texture_CreateWAD(WeaponID[a][W_POS_DOWN][W_ACT_NORMAL], GameWAD+':WEAPONS\'+UpperCase(WeapNames[a])+'_DN');
- g_Texture_CreateWAD(WeaponID[a][W_POS_DOWN][W_ACT_FIRE], GameWAD+':WEAPONS\'+UpperCase(WeapNames[a])+'_DN_FIRE');
+ for a := WP_FIRST + 1 to WP_LAST do
+ begin
+ g_Texture_CreateWAD(WeaponID[a][W_POS_NORMAL][W_ACT_NORMAL], GameWAD+':WEAPONS\'+UpperCase(WeapNames[a]));
+ g_Texture_CreateWAD(WeaponID[a][W_POS_NORMAL][W_ACT_FIRE], GameWAD+':WEAPONS\'+UpperCase(WeapNames[a])+'_FIRE');
+ g_Texture_CreateWAD(WeaponID[a][W_POS_UP][W_ACT_NORMAL], GameWAD+':WEAPONS\'+UpperCase(WeapNames[a])+'_UP');
+ g_Texture_CreateWAD(WeaponID[a][W_POS_UP][W_ACT_FIRE], GameWAD+':WEAPONS\'+UpperCase(WeapNames[a])+'_UP_FIRE');
+ g_Texture_CreateWAD(WeaponID[a][W_POS_DOWN][W_ACT_NORMAL], GameWAD+':WEAPONS\'+UpperCase(WeapNames[a])+'_DN');
+ g_Texture_CreateWAD(WeaponID[a][W_POS_DOWN][W_ACT_FIRE], GameWAD+':WEAPONS\'+UpperCase(WeapNames[a])+'_DN_FIRE');
+ end;
+ Models := nil;
+ if PlayerModelsArray <> nil then
+ begin
+ SetLength(Models, Length(PlayerModelsArray));
+ for i := 0 to High(PlayerModelsArray) do
+ begin
+ prefix := PlayerModelsArray[i].FileName + ':TEXTURES\';
+ for b := A_STAND to A_LAST do
+ begin
+ aname := PlayerModelsArray[i].Info.Name + '_RIGHTANIM' + IntToStr(b);
+ with PlayerModelsArray[i].Anim[TDirection.D_RIGHT, b] do
+ begin
+ if not (g_Frames_CreateWAD(@ID1, aname, prefix + Resource, 64, 64, Frames, Back) and
+ g_Frames_CreateWAD(@ID2, aname + '_MASK', prefix + Mask, 64, 64, Frames, Back)) then
+ begin
+ if b > A_LASTBASE then
+ begin
+ ExtAnimFromBaseAnim(PlayerModelsArray[i].Info.Name, b);
+ continue
+ end
+ end;
+ Models[i].Frames[TDirection.D_RIGHT, b].base := ID1;
+ Models[i].Frames[TDirection.D_RIGHT, b].mask := ID2;
+ end;
+ with PlayerModelsArray[i].Anim[TDirection.D_LEFT, b] do
+ begin
+ if (Resource <> '') and (Mask <> '') then
+ begin
+ aname := PlayerModelsArray[i].Info.Name + '_LEFTANIM' + IntToStr(b);
+ g_Frames_CreateWAD(@ID1, aname, prefix + Resource, 64, 64, Frames, Back);
+ g_Frames_CreateWAD(@ID2, aname + '_MASK', prefix + Mask, 64, 64, Frames, Back);
+ Models[i].Frames[TDirection.D_LEFT, b].base := ID1;
+ Models[i].Frames[TDirection.D_LEFT, b].mask := ID2;
+ end
+ end
+ end
+ end
+ end
end;
-end;
- procedure r_PlayerModel_Finalize;
- var a, b, c: Integer;
+ procedure r_PlayerModel_Free;
+ var i, a, b, c: Integer;
begin
+ if PlayerModelsArray = nil then Exit;
+ for i := 0 to High(PlayerModelsArray) do
+ begin
+ with PlayerModelsArray[i] do
+ begin
+ for a := A_STAND to A_LAST do
+ begin
+ g_Frames_DeleteByName(Info.Name+'_LEFTANIM'+IntToStr(a));
+ g_Frames_DeleteByName(Info.Name+'_LEFTANIM'+IntToStr(a)+'_MASK');
+ g_Frames_DeleteByName(Info.Name+'_RIGHTANIM'+IntToStr(a));
+ g_Frames_DeleteByName(Info.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
+ end;
for a := WP_FIRST + 1 to WP_LAST do
for b := W_POS_NORMAL to W_POS_DOWN do
for c := W_ACT_NORMAL to W_ACT_FIRE do
Mirror: TMirrorType;
pos, act: Byte;
p: TDFPoint;
+ FramesID: DWORD;
begin
// Флаги:
if pm.Direction = TDirection.D_LEFT then
else
Mirror := TMirrorType.Horizontal;
- if pm.DrawWeapon and (not (pm.CurrentAnimation in [A_DIE1, A_DIE2, A_PAIN])) and (pm.CurrentWeapon in [WP_FIRST + 1..WP_LAST]) then
+ if PlayerModelsArray[pm.id].Info.HaveWeapon and (not (pm.CurrentAnimation in [A_DIE1, A_DIE2, A_PAIN])) and (pm.CurrentWeapon in [WP_FIRST + 1..WP_LAST]) then
begin
if pm.CurrentAnimation in [A_SEEUP, A_ATTACKUP] then
pos := W_POS_UP
act := W_ACT_NORMAL;
if Alpha < 201 then
- e_Draw(WeaponID[pm.CurrentWeapon][pos][act],
- X + pm.WeaponPoints[pm.CurrentWeapon, pm.CurrentAnimation, pm.Direction,
- pm.Anim[TDirection.D_RIGHT][pm.CurrentAnimation].CurrentFrame].X,
- Y + pm.WeaponPoints[pm.CurrentWeapon, pm.CurrentAnimation, pm.Direction,
- pm.Anim[TDirection.D_RIGHT][pm.CurrentAnimation].CurrentFrame].Y,
- 0, True, False, Mirror);
+ e_Draw(
+ WeaponID[pm.CurrentWeapon][pos][act],
+ X + PlayerModelsArray[pm.id].WeaponPoints[pm.CurrentWeapon, pm.CurrentAnimation, pm.Direction, pm.AnimState.CurrentFrame].X,
+ Y + PlayerModelsArray[pm.id].WeaponPoints[pm.CurrentWeapon, pm.CurrentAnimation, pm.Direction, pm.AnimState.CurrentFrame].Y,
+ 0,
+ True,
+ False,
+ Mirror
+ );
end;
// Модель:
- if (pm.Direction = TDirection.D_LEFT) and (pm.Anim[TDirection.D_LEFT][pm.CurrentAnimation] <> nil) then
+ if (pm.Direction = TDirection.D_LEFT) and (Models[pm.id].Frames[TDirection.D_LEFT, pm.CurrentAnimation].base <> 0) then
begin
- pm.Anim[TDirection.D_LEFT][pm.CurrentAnimation].Alpha := Alpha;
- r_Animation_Draw(pm.Anim[TDirection.D_LEFT][pm.CurrentAnimation], X, Y, TMirrorType.None);
+ pm.AnimState.Alpha := Alpha; // !!!
+ FramesID := Models[pm.id].Frames[TDirection.D_LEFT, pm.CurrentAnimation].base;
+ r_AnimationState_Draw(FramesID, pm.AnimState, X, Y, TMirrorType.None);
end
else
begin
- pm.Anim[TDirection.D_RIGHT][pm.CurrentAnimation].Alpha := Alpha;
- r_Animation_Draw(pm.Anim[TDirection.D_RIGHT][pm.CurrentAnimation], X, Y, Mirror);
+ pm.AnimState.Alpha := Alpha; // !!!
+ FramesID := Models[pm.id].Frames[TDirection.D_RIGHT, pm.CurrentAnimation].base;
+ r_AnimationState_Draw(FramesID, pm.AnimState, X, Y, Mirror);
end;
// Маска модели:
e_Colors := pm.Color;
- if (pm.Direction = TDirection.D_LEFT) and (pm.MaskAnim[TDirection.D_LEFT][pm.CurrentAnimation] <> nil) then
+ if (pm.Direction = TDirection.D_LEFT) and (Models[pm.id].Frames[TDirection.D_LEFT, pm.CurrentAnimation].mask <> 0) then
begin
- pm.MaskAnim[TDirection.D_LEFT][pm.CurrentAnimation].Alpha := Alpha;
- r_Animation_Draw(pm.MaskAnim[TDirection.D_LEFT][pm.CurrentAnimation], X, Y, TMirrorType.None);
+ pm.AnimState.Alpha := Alpha; // !!!
+ FramesID := Models[pm.id].Frames[TDirection.D_LEFT, pm.CurrentAnimation].mask;
+ r_AnimationState_Draw(FramesID, pm.AnimState, X, Y, TMirrorType.None);
end
else
begin
- pm.MaskAnim[TDirection.D_RIGHT][pm.CurrentAnimation].Alpha := Alpha;
- r_Animation_Draw(pm.MaskAnim[TDirection.D_RIGHT][pm.CurrentAnimation], X, Y, Mirror);
+ pm.AnimState.Alpha := Alpha; // !!!
+ FramesID := Models[pm.id].Frames[TDirection.D_RIGHT, pm.CurrentAnimation].mask;
+ r_AnimationState_Draw(FramesID, pm.AnimState, X, Y, Mirror);
end;
e_Colors.R := 255;
index 2a4befff5d4c80de73134046fee432e2b5ec33b3..5deccdbdfd29a40c7983a34bfc26226b53356dcd 100644 (file)
procedure r_Render_Load;
begin
+ r_PlayerModel_Load;
r_Monsters_Load;
r_Weapon_Load;
r_Items_Load;
r_Items_Free;
r_Weapon_Free;
r_Monsters_Free;
+ r_PlayerModel_Free;
end;
procedure r_Render_Initialize;
LoadGL;
r_Window_Initialize;
r_Console_Init;
- r_PlayerModel_Initialize;
end;
procedure r_Render_Finalize;
begin
FreeGL;
- r_PlayerModel_Finalize;
e_ReleaseEngine
end;