index 0392cc43d65ad7db2280bba5d56a4cf87ce6c7fc..9e42436ec5a4440f619ec289298c2cf20444f451 100644 (file)
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*)
-{$INCLUDE g_amodes.inc}
+{$INCLUDE ../shared/a_modes.inc}
+{$M+}
unit g_playermodel;
interface
uses
- g_textures, g_basic, g_weapons, e_graphics, wadreader;
+ MAPDEF, g_textures, g_basic, g_weapons, e_graphics, wadreader;
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;
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 [D_LEFT..D_RIGHT] of Array of TDFPoint;
TPlayerModel = class (TObject)
private
FDirection: TDirection;
FColor: TRGB;
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 [D_LEFT..D_RIGHT] of Array [A_STAND..A_LAST] of TAnimation;
+ FMaskAnim: Array [D_LEFT..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;
end;
TPlayerModelInfo = record
Info: TModelInfo;
ModelSpeed: Array [A_STAND..A_PAIN] of Byte;
- FlagPoint: TPoint;
+ FlagPoint: TDFPoint;
FlagAngle: SmallInt;
WeaponPoints: TWeaponPoints;
Gibs: TGibsArray;
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;
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 := D_LEFT to 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_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
Description := config.ReadStr('Model', 'description', '');
end;
- for b := A_STAND to A_PAIN do
+ for b := A_STAND to A_LAST do
begin
- if not (g_Frames_CreateWAD(nil, s+'_RIGHTANIM'+IntToStr(b),
+ 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 bb := A_STAND to A_LAST do
for cc := D_LEFT to D_RIGHT do
begin
f := config.ReadInt(AnimNames[bb], 'frames', 1);
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));
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,
Dec(WeaponPoints[aa, bb, D_RIGHT, f].X, 6);
Dec(WeaponPoints[aa, bb, 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, D_RIGHT, f].X, 5);
Dec(WeaponPoints[aa, bb, 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);
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);
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);
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);
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,
config.ReadInt(AnimNames[bb], 'frames', 0),
begin
Result.FName := Info.Name;
- 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[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[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[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[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;
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');
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();
var
Mirror: TMirrorType;
pos, act: Byte;
- p: TPoint;
+ p: TDFPoint;
begin
// Ôëàãè:
if Direction = D_LEFT then