index f3e1f8d79e5c7652ba9a002d1216f422016c8198..6ffea1fbc3fc094fb714fb25df4ef20623235c4a 100644 (file)
-(* Copyright (C) DooM 2D:Forever Developers
+(* Copyright (C) Doom 2D: Forever Developers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * the Free Software Foundation, version 3 of the License ONLY.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*)
-{$MODE DELPHI}
+{$INCLUDE ../shared/a_modes.inc}
+{$M+}
unit g_playermodel;
interface
uses
- g_textures, g_basic, g_weapons, e_graphics, wadreader;
+ {$IFDEF USE_MEMPOOL}mempool,{$ENDIF}
+ MAPDEF, g_textures, g_basic, g_weapons, e_graphics, utils, g_gfx,
+ ImagingTypes, Imaging, ImagingUtility;
const
A_STAND = 0;
A_ATTACKUP = 7;
A_ATTACKDOWN = 8;
A_PAIN = 9;
+ // EXTENDED
+ A_WALKATTACK = 10;
+ A_WALKSEEUP = 11;
+ A_WALKSEEDOWN = 12;
+ A_WALKATTACKUP = 13;
+ A_WALKATTACKDOWN = 14;
+ A_FISTSTAND = 15;
+ A_FISTWALK = 16;
+ A_FISTATTACK = 17;
+ A_FISTWALKATTACK = 18;
+ A_FISTSEEUP = 19;
+ A_FISTSEEDOWN = 20;
+ A_FISTATTACKUP = 21;
+ A_FISTATTACKDOWN = 22;
+
+ A_LASTBASE = A_PAIN;
+ A_LASTEXT = A_FISTATTACKDOWN;
+ A_LAST = A_LASTEXT;
MODELSOUND_PAIN = 0;
MODELSOUND_DIE = 1;
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_PAIN] of
- Array [D_LEFT..D_RIGHT] of Array of TPoint;
+ Array [A_STAND..A_LAST] of
+ Array [TDirection.D_LEFT..TDirection.D_RIGHT] of Array of TDFPoint;
- TPlayerModel = class (TObject)
+ TPlayerModel = class{$IFDEF USE_MEMPOOL}(TPoolObject){$ENDIF}
private
FName: String;
FDirection: TDirection;
FColor: TRGB;
+ FBlood: TModelBlood;
FCurrentAnimation: Byte;
- FAnim: Array [D_LEFT..D_RIGHT] of Array [A_STAND..A_PAIN] of TAnimation;
- FMaskAnim: Array [D_LEFT..D_RIGHT] of Array [A_STAND..A_PAIN] of TAnimation;
+ FAnim: Array [TDirection.D_LEFT..TDirection.D_RIGHT] of Array [A_STAND..A_LAST] of TAnimation;
+ FMaskAnim: Array [TDirection.D_LEFT..TDirection.D_RIGHT] of Array [A_STAND..A_LAST] of TAnimation;
FWeaponPoints: TWeaponPoints;
FPainSounds: TModelSoundArray;
FDieSounds: TModelSoundArray;
FCurrentWeapon: Byte;
FDrawWeapon: Boolean;
FFlag: Byte;
- FFlagPoint: TPoint;
+ FFlagPoint: TDFPoint;
FFlagAngle: SmallInt;
FFlagAnim: TAnimation;
FFire: Boolean;
procedure Update();
procedure Draw(X, Y: Integer; Alpha: Byte = 0);
+ 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;
end;
procedure g_PlayerModel_LoadData();
procedure g_PlayerModel_FreeData();
function g_PlayerModel_Load(FileName: String): Boolean;
-function g_PlayerModel_GetNames(): SArray;
+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_GetGibs(ModelName: String; var Gibs: TGibsArray): Boolean;
+
implementation
uses
+ {$INCLUDE ../nogl/noGLuses.inc}
g_main, g_sound, g_console, SysUtils, g_player, CONFIG,
- GL, GLExt, e_sound, g_options, g_map, Math, e_log;
+ e_sound, g_options, g_map, Math, e_log, wadreader;
type
TPlayerModelInfo = record
Info: TModelInfo;
ModelSpeed: Array [A_STAND..A_PAIN] of Byte;
- FlagPoint: TPoint;
+ FlagPoint: TDFPoint;
FlagAngle: SmallInt;
WeaponPoints: TWeaponPoints;
Gibs: TGibsArray;
PainSounds: TModelSoundArray;
DieSounds: TModelSoundArray;
SlopSound: Byte;
+ Blood: TModelBlood;
end;
const
W_ACT_NORMAL = 0;
W_ACT_FIRE = 1;
- FLAG_BASEPOINT: TPoint = (X:16; Y:43);
- FLAG_DEFPOINT: TPoint = (X:32; Y:16);
+ FLAG_BASEPOINT: TDFPoint = (X:16; Y:43);
+ FLAG_DEFPOINT: TDFPoint = (X:32; Y:16);
FLAG_DEFANGLE = -20;
- WEAPONBASE: Array [WP_FIRST + 1..WP_LAST] of TPoint =
+ WEAPONBASE: Array [WP_FIRST + 1..WP_LAST] of TDFPoint =
((X:8; Y:4), (X:8; Y:8), (X:16; Y:16), (X:16; Y:24),
(X:16; Y:16), (X:24; Y:24), (X:16; Y:16), (X:24; Y:24),
(X:16; Y:16), (X:8; Y:8));
- AnimNames: Array [A_STAND..A_PAIN] of String =
+ AnimNames: Array [A_STAND..A_LASTEXT] of String =
('StandAnim','WalkAnim','Die1Anim','Die2Anim','AttackAnim',
- 'SeeUpAnim','SeeDownAnim','AttackUpAnim','AttackDownAnim','PainAnim');
+ 'SeeUpAnim','SeeDownAnim','AttackUpAnim','AttackDownAnim','PainAnim',
+ // EXTENDED
+ 'WalkAttackAnim', 'WalkSeeUpAnim', 'WalkSeeDownAnim',
+ 'WalkAttackUpAnim', 'WalkAttackDownAnim', 'FistStandAnim', 'FistWalkAnim',
+ 'FistAttackAnim', 'FistWalkAttackAnim', 'FistSeeUpAnim', 'FistSeeDownAnim',
+ 'FistAttackUpAnim', 'FistAttackDownAnim');
WeapNames: Array [WP_FIRST + 1..WP_LAST] of String =
('csaw', 'hgun', 'sg', 'ssg', 'mgun', 'rkt', 'plz', 'bfg', 'spl', 'flm');
end;
end;
-function GetPoint(var str: String; var point: TPoint): Boolean;
+function GetPoint(var str: String; var point: TDFPoint): Boolean;
var
a, x, y: Integer;
s: String;
begin
X := X - WEAPONBASE[weapon].X;
Y := Y - WEAPONBASE[weapon].Y;
- if dir = D_LEFT then
+ if dir = TDirection.D_LEFT then
X := -X;
end;
end;
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
+ begin
+ for W := WP_FIRST + 1 to WP_LAST do
+ begin
+ 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;
+
+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;
+
function g_PlayerModel_Load(FileName: string): Boolean;
var
ID: DWORD;
config: TConfig;
pData, pData2: Pointer;
WAD: TWADFile;
- s: string;
+ s, aname: string;
prefix: string;
ok, chk: Boolean;
begin
- e_WriteLog(Format('Loading player model: %s', [ExtractFileName(FileName)]), MSG_NOTIFY);
+ e_WriteLog(Format('Loading player model "%s"...', [FileName]), TMsgType.Notify);
Result := False;
Description := config.ReadStr('Model', 'description', '');
end;
- for b := A_STAND to A_PAIN do
+ with PlayerModelsArray[ID] do
begin
- if not (g_Frames_CreateWAD(nil, s+'_RIGHTANIM'+IntToStr(b),
+ Blood.R := MAX(0, MIN(255, config.ReadInt('Blood', 'R', 150)));
+ Blood.G := MAX(0, MIN(255, config.ReadInt('Blood', 'G', 0)));
+ Blood.B := MAX(0, MIN(255, config.ReadInt('Blood', 'B', 0)));
+ case config.ReadStr('Blood', 'Kind', 'NORMAL') of
+ 'NORMAL': Blood.Kind := BLOOD_NORMAL;
+ 'SPARKS': Blood.Kind := BLOOD_CSPARKS;
+ 'COMBINE': Blood.Kind := BLOOD_COMBINE;
+ else
+ Blood.Kind := BLOOD_NORMAL
+ end
+ end;
+
+ 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, s+'_RIGHTANIM'+IntToStr(b)+'_MASK',
+ 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
begin
- config.Free();
- WAD.Free();
- Exit;
+ if b <= A_LASTBASE then
+ begin
+ config.Free();
+ WAD.Free();
+ Exit;
+ end
+ else
+ begin
+ ExtAnimFromBaseAnim(s, b);
+ continue;
+ end;
end;
for aa := WP_FIRST + 1 to WP_LAST do
- for bb := A_STAND to A_PAIN do
- for cc := D_LEFT to D_RIGHT do
+ 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 (config.ReadStr(AnimNames[b], 'resource2', '') <> '') and
(config.ReadStr(AnimNames[b], 'mask2', '') <> '') then
begin
- g_Frames_CreateWAD(nil, s+'_LEFTANIM'+IntToStr(b),
+ 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, s+'_LEFTANIM'+IntToStr(b)+'_MASK',
+ 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));
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 := 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 := config.ReadInt('Gibs', 'once', -1) = a+1;
ok := True;
for aa := WP_FIRST + 1 to WP_LAST do
- for bb := A_STAND to A_PAIN do
+ 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, D_RIGHT,
+ 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);
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, D_RIGHT,
+ 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);
if chk then
- for f := 0 to High(WeaponPoints[aa, bb, D_RIGHT]) do
+ for f := 0 to High(WeaponPoints[aa, bb, TDirection.D_RIGHT]) do
begin
case bb of
A_STAND, A_PAIN:
begin
- Dec(WeaponPoints[aa, bb, D_RIGHT, f].X, 6);
- Dec(WeaponPoints[aa, bb, D_RIGHT, f].Y, 8);
+ Dec(WeaponPoints[aa, bb, TDirection.D_RIGHT, f].X, 6);
+ Dec(WeaponPoints[aa, bb, TDirection.D_RIGHT, f].Y, 8);
end;
- A_WALK:
+ A_WALKATTACK, A_WALK:
begin
- Dec(WeaponPoints[aa, bb, D_RIGHT, f].X, 9);
- Dec(WeaponPoints[aa, bb, D_RIGHT, f].Y, 9);
+ Dec(WeaponPoints[aa, bb, TDirection.D_RIGHT, f].X, 9);
+ Dec(WeaponPoints[aa, bb, TDirection.D_RIGHT, f].Y, 9);
end;
A_ATTACK:
begin
- Dec(WeaponPoints[aa, bb, D_RIGHT, f].X, 5);
- Dec(WeaponPoints[aa, bb, D_RIGHT, f].Y, 8);
+ Dec(WeaponPoints[aa, bb, TDirection.D_RIGHT, f].X, 5);
+ Dec(WeaponPoints[aa, bb, TDirection.D_RIGHT, f].Y, 8);
end;
- A_SEEUP:
+ A_WALKSEEUP, A_SEEUP:
begin
- Dec(WeaponPoints[aa, bb, D_RIGHT, f].X, 5);
- Dec(WeaponPoints[aa, bb, D_RIGHT, f].Y, 16);
+ Dec(WeaponPoints[aa, bb, TDirection.D_RIGHT, f].X, 5);
+ Dec(WeaponPoints[aa, bb, TDirection.D_RIGHT, f].Y, 16);
end;
- A_SEEDOWN:
+ A_WALKSEEDOWN, A_SEEDOWN:
begin
- Dec(WeaponPoints[aa, bb, D_RIGHT, f].X, 6);
- Dec(WeaponPoints[aa, bb, D_RIGHT, f].Y, 5);
+ Dec(WeaponPoints[aa, bb, TDirection.D_RIGHT, f].X, 6);
+ Dec(WeaponPoints[aa, bb, TDirection.D_RIGHT, f].Y, 5);
end;
- A_ATTACKUP:
+ A_WALKATTACKUP, A_ATTACKUP:
begin
- Dec(WeaponPoints[aa, bb, D_RIGHT, f].X, 5);
- Dec(WeaponPoints[aa, bb, D_RIGHT, f].Y, 16);
+ Dec(WeaponPoints[aa, bb, TDirection.D_RIGHT, f].X, 5);
+ Dec(WeaponPoints[aa, bb, TDirection.D_RIGHT, f].Y, 16);
end;
- A_ATTACKDOWN:
+ A_WALKATTACKDOWN, A_ATTACKDOWN:
begin
- Dec(WeaponPoints[aa, bb, D_RIGHT, f].X, 6);
- Dec(WeaponPoints[aa, bb, D_RIGHT, f].Y, 4);
+ Dec(WeaponPoints[aa, bb, TDirection.D_RIGHT, f].X, 6);
+ Dec(WeaponPoints[aa, bb, TDirection.D_RIGHT, f].Y, 4);
end;
end;
end;
end;
- ok := ok and chk;
+ ok := ok and (chk or (bb > A_LASTBASE));
- if not GetWeapPoints(config.ReadStr(AnimNames[bb], WeapNames[aa]+'2_points', ''), aa, bb, D_LEFT,
+ 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
- for f := 0 to High(WeaponPoints[aa, bb, D_RIGHT]) do
+ for f := 0 to High(WeaponPoints[aa, bb, TDirection.D_RIGHT]) do
begin
- WeaponPoints[aa, bb, D_LEFT, f].X := -WeaponPoints[aa, bb, D_RIGHT, f].X;
- WeaponPoints[aa, bb, D_LEFT, f].Y := WeaponPoints[aa, bb, D_RIGHT, f].Y;
+ 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;
if not ok then Break;
with PlayerModelsArray[a] do
begin
Result.FName := Info.Name;
+ Result.FBlood := Blood;
- for b := A_STAND to A_PAIN do
+ 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;
+ Exit;
+ end;
- Result.FAnim[D_RIGHT][b] := TAnimation.Create(ID, b in [A_STAND, A_WALK], ModelSpeed[b]);
+ Result.FAnim[TDirection.D_RIGHT][b] := TAnimation.Create(ID, b in [A_STAND, A_WALK], ModelSpeed[b]);
- Result.FMaskAnim[D_RIGHT][b] := TAnimation.Create(ID2, 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[D_LEFT][b] := TAnimation.Create(ID, 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[D_LEFT][b] := TAnimation.Create(ID2, 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;
- end;
+ Result.FDrawWeapon := Info.HaveWeapon;
+ Result.FWeaponPoints := WeaponPoints;
- Result.FDrawWeapon := Info.HaveWeapon;
- Result.FWeaponPoints := WeaponPoints;
+ Result.FFlagPoint := FlagPoint;
+ Result.FFlagAngle := FlagAngle;
- Result.FFlagPoint := FlagPoint;
- Result.FFlagAngle := FlagAngle;
-
- Break;
- end;
+ Break;
+ end;
end;
end;
end;
end;
-function g_PlayerModel_GetNames(): SArray;
+function g_PlayerModel_GetNames(): SSArray;
var
i: DWORD;
begin
end;
end;
+function g_PlayerModel_GetBlood(ModelName: string): TModelBlood;
+var
+ a: Integer;
+begin
+ Result.R := 150;
+ Result.G := 0;
+ Result.B := 0;
+ Result.Kind := BLOOD_NORMAL;
+ if PlayerModelsArray = nil then Exit;
+
+ for a := 0 to High(PlayerModelsArray) do
+ if PlayerModelsArray[a].Info.Name = ModelName then
+ begin
+ Result := PlayerModelsArray[a].Blood;
+ Break;
+ end;
+end;
+
procedure g_PlayerModel_FreeData();
var
i: DWORD;
for c := W_ACT_NORMAL to W_ACT_FIRE do
e_DeleteTexture(WeaponID[a][b][c]);
- e_WriteLog('Releasing models...', MSG_NOTIFY);
+ e_WriteLog('Releasing models...', TMsgType.Notify);
if PlayerModelsArray = nil then Exit;
for i := 0 to High(PlayerModelsArray) do
with PlayerModelsArray[i] do
begin
- for a := A_STAND to A_PAIN do
+ 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');
FCurrentAnimation := Animation;
- if (FDirection = D_LEFT) and
- (FAnim[D_LEFT][FCurrentAnimation] <> nil) and
- (FMaskAnim[D_LEFT][FCurrentAnimation] <> nil) then
+ if (FDirection = TDirection.D_LEFT) and
+ (FAnim[TDirection.D_LEFT][FCurrentAnimation] <> nil) and
+ (FMaskAnim[TDirection.D_LEFT][FCurrentAnimation] <> nil) then
begin
- FAnim[D_LEFT][FCurrentAnimation].Reset;
- FMaskAnim[D_LEFT][FCurrentAnimation].Reset;
+ FAnim[TDirection.D_LEFT][FCurrentAnimation].Reset;
+ FMaskAnim[TDirection.D_LEFT][FCurrentAnimation].Reset;
end
else
begin
- FAnim[D_RIGHT][FCurrentAnimation].Reset;
- FMaskAnim[D_RIGHT][FCurrentAnimation].Reset;
+ FAnim[TDirection.D_RIGHT][FCurrentAnimation].Reset;
+ FMaskAnim[TDirection.D_RIGHT][FCurrentAnimation].Reset;
end;
end;
var
a: Byte;
begin
- for a := A_STAND to A_PAIN do
+ for a := A_STAND to A_LAST do
begin
- FAnim[D_LEFT][a].Free();
- FMaskAnim[D_LEFT][a].Free();
- FAnim[D_RIGHT][a].Free();
- FMaskAnim[D_RIGHT][a].Free();
+ 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;
inherited;
var
Mirror: TMirrorType;
pos, act: Byte;
- p: TPoint;
+ p: TDFPoint;
begin
// Ôëàãè:
- if Direction = D_LEFT then
- Mirror := M_NONE
+ if Direction = TDirection.D_LEFT then
+ Mirror := TMirrorType.None
else
- Mirror := M_HORIZONTAL;
+ Mirror := TMirrorType.Horizontal;
if (FFlag <> FLAG_NONE) and (FFlagAnim <> nil) and
(not (FCurrentAnimation in [A_DIE1, A_DIE2])) then
begin
- p.X := IfThen(Direction = D_LEFT,
+ p.X := IfThen(Direction = TDirection.D_LEFT,
FLAG_BASEPOINT.X,
64-FLAG_BASEPOINT.X);
p.Y := FLAG_BASEPOINT.Y;
- FFlagAnim.DrawEx(X+IfThen(Direction = D_LEFT, FFlagPoint.X-1, 2*FLAG_BASEPOINT.X-FFlagPoint.X+1)-FLAG_BASEPOINT.X,
+ FFlagAnim.DrawEx(X+IfThen(Direction = TDirection.D_LEFT, FFlagPoint.X-1, 2*FLAG_BASEPOINT.X-FFlagPoint.X+1)-FLAG_BASEPOINT.X,
Y+FFlagPoint.Y-FLAG_BASEPOINT.Y+1, Mirror, p,
- IfThen(FDirection = D_RIGHT, FFlagAngle, -FFlagAngle));
+ IfThen(FDirection = TDirection.D_RIGHT, FFlagAngle, -FFlagAngle));
end;
// Îðóæèå:
- if Direction = D_RIGHT then
- Mirror := M_NONE
+ if Direction = TDirection.D_RIGHT then
+ Mirror := TMirrorType.None
else
- Mirror := M_HORIZONTAL;
+ Mirror := TMirrorType.Horizontal;
if FDrawWeapon and
(not (FCurrentAnimation in [A_DIE1, A_DIE2, A_PAIN])) and
if Alpha < 201 then
e_Draw(WeaponID[FCurrentWeapon][pos][act],
X+FWeaponPoints[FCurrentWeapon, FCurrentAnimation, FDirection,
- FAnim[D_RIGHT][FCurrentAnimation].CurrentFrame].X,
+ FAnim[TDirection.D_RIGHT][FCurrentAnimation].CurrentFrame].X,
Y+FWeaponPoints[FCurrentWeapon, FCurrentAnimation, FDirection,
- FAnim[D_RIGHT][FCurrentAnimation].CurrentFrame].Y,
+ FAnim[TDirection.D_RIGHT][FCurrentAnimation].CurrentFrame].Y,
0, True, False, Mirror);
end;
// Ìîäåëü:
- if (FDirection = D_LEFT) and
- (FAnim[D_LEFT][FCurrentAnimation] <> nil) then
+ if (FDirection = TDirection.D_LEFT) and
+ (FAnim[TDirection.D_LEFT][FCurrentAnimation] <> nil) then
begin
- FAnim[D_LEFT][FCurrentAnimation].Alpha := Alpha;
- FAnim[D_LEFT][FCurrentAnimation].Draw(X, Y, M_NONE);
+ FAnim[TDirection.D_LEFT][FCurrentAnimation].Alpha := Alpha;
+ FAnim[TDirection.D_LEFT][FCurrentAnimation].Draw(X, Y, TMirrorType.None);
end
else
begin
- FAnim[D_RIGHT][FCurrentAnimation].Alpha := Alpha;
- FAnim[D_RIGHT][FCurrentAnimation].Draw(X, Y, Mirror);
+ FAnim[TDirection.D_RIGHT][FCurrentAnimation].Alpha := Alpha;
+ FAnim[TDirection.D_RIGHT][FCurrentAnimation].Draw(X, Y, Mirror);
end;
// Ìàñêà ìîäåëè:
e_Colors := FColor;
- if (FDirection = D_LEFT) and
- (FMaskAnim[D_LEFT][FCurrentAnimation] <> nil) then
+ if (FDirection = TDirection.D_LEFT) and
+ (FMaskAnim[TDirection.D_LEFT][FCurrentAnimation] <> nil) then
begin
- FMaskAnim[D_LEFT][FCurrentAnimation].Alpha := Alpha;
- FMaskAnim[D_LEFT][FCurrentAnimation].Draw(X, Y, M_NONE);
+ FMaskAnim[TDirection.D_LEFT][FCurrentAnimation].Alpha := Alpha;
+ FMaskAnim[TDirection.D_LEFT][FCurrentAnimation].Draw(X, Y, TMirrorType.None);
end
else
begin
- FMaskAnim[D_RIGHT][FCurrentAnimation].Alpha := Alpha;
- FMaskAnim[D_RIGHT][FCurrentAnimation].Draw(X, Y, Mirror);
+ FMaskAnim[TDirection.D_RIGHT][FCurrentAnimation].Alpha := Alpha;
+ FMaskAnim[TDirection.D_RIGHT][FCurrentAnimation].Draw(X, Y, Mirror);
end;
e_Colors.R := 255;
function TPlayerModel.GetCurrentAnimation: TAnimation;
begin
- if (FDirection = D_LEFT) and (FAnim[D_LEFT][FCurrentAnimation] <> nil) then
- Result := FAnim[D_LEFT][FCurrentAnimation]
+ if (FDirection = TDirection.D_LEFT) and (FAnim[TDirection.D_LEFT][FCurrentAnimation] <> nil) then
+ Result := FAnim[TDirection.D_LEFT][FCurrentAnimation]
else
- Result := FAnim[D_RIGHT][FCurrentAnimation];
+ Result := FAnim[TDirection.D_RIGHT][FCurrentAnimation];
end;
function TPlayerModel.GetCurrentAnimationMask: TAnimation;
begin
- if (FDirection = D_LEFT) and (FMaskAnim[D_LEFT][FCurrentAnimation] <> nil) then
- Result := FMaskAnim[D_LEFT][FCurrentAnimation]
+ if (FDirection = TDirection.D_LEFT) and (FMaskAnim[TDirection.D_LEFT][FCurrentAnimation] <> nil) then
+ Result := FMaskAnim[TDirection.D_LEFT][FCurrentAnimation]
else
- Result := FMaskAnim[D_RIGHT][FCurrentAnimation];
+ Result := FMaskAnim[TDirection.D_RIGHT][FCurrentAnimation];
end;
function TPlayerModel.PlaySound(SoundType, Level: Byte; X, Y: Integer): Boolean;
begin
FFire := Fire;
- if FFire then FFireCounter := FAnim[D_RIGHT, A_ATTACK].Speed*FAnim[D_RIGHT, A_ATTACK].TotalFrames
+ if FFire then FFireCounter := FAnim[TDirection.D_RIGHT, A_ATTACK].Speed*FAnim[TDirection.D_RIGHT, A_ATTACK].TotalFrames
else FFireCounter := 0;
end;
procedure TPlayerModel.Update();
begin
- if (FDirection = D_LEFT) and (FAnim[D_LEFT][FCurrentAnimation] <> nil) then
- FAnim[D_LEFT][FCurrentAnimation].Update else FAnim[D_RIGHT][FCurrentAnimation].Update;
+ 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;
- if (FDirection = D_LEFT) and (FMaskAnim[D_LEFT][FCurrentAnimation] <> nil) then
- FMaskAnim[D_LEFT][FCurrentAnimation].Update else FMaskAnim[D_RIGHT][FCurrentAnimation].Update;
+ 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;
if FFlagAnim <> nil then FFlagAnim.Update;