X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_playermodel.pas;h=34dbdfdbe02be7ea1dc9a4056f684f3a3b92e5cd;hb=23a883f6c44413c380997e61b00a756bda95bc03;hp=51dd6c0deecf8cb6215a419f96e04aef8e3af02e;hpb=b07cc041c0c2cbb70ddddaddf81e3b03533d3ac8;p=d2df-sdl.git diff --git a/src/game/g_playermodel.pas b/src/game/g_playermodel.pas index 51dd6c0..34dbdfd 100644 --- a/src/game/g_playermodel.pas +++ b/src/game/g_playermodel.pas @@ -18,9 +18,7 @@ unit g_playermodel; interface -uses - MAPDEF, g_textures, g_base, g_basic, g_weapons, r_graphics, utils, g_gfx, - ImagingTypes, Imaging, ImagingUtility; + uses MAPDEF, g_textures, g_base, g_basic, g_weapons, utils; const A_STAND = 0; @@ -76,31 +74,20 @@ type Back: Boolean; end; +{$IFDEF ENABLE_GFX} TModelBlood = record R, G, B, Kind: Byte; end; - - TModelInfo = record - Name: String; - Author: String; - Description: String; - HaveWeapon: Boolean; - end; +{$ENDIF} TModelSound = record ID: DWORD; 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 @@ -108,12 +95,8 @@ type FColor: TRGB; FCurrentAnimation: Byte; FAnimState: TAnimationState; - FPainSounds: TModelSoundArray; - FDieSounds: TModelSoundArray; - FSlopSound: Byte; FCurrentWeapon: Byte; FFlag: Byte; - FFire: Boolean; FFireCounter: Byte; FID: Integer; @@ -123,15 +106,18 @@ type procedure SetColor(Red, Green, Blue: Byte); procedure SetWeapon(Weapon: Byte); procedure SetFlag(Flag: Byte); - procedure SetFire(Fire: Boolean); + procedure SetFire (Fire: Boolean); + function GetFire (): Boolean; function PlaySound(SoundType, Level: Byte; X, Y: Integer): Boolean; procedure Update(); - function GetBlood (): TModelBlood; + {$IFDEF ENABLE_GFX} + function GetBlood (): TModelBlood; + {$ENDIF} + 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; @@ -149,26 +135,34 @@ 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; AnimTyp: Byte; var _Anim, _Mask: TAnimation): Boolean; -function g_PlayerModel_GetGibs(ModelName: String; var Gibs: TGibsArray): Boolean; +function g_PlayerModel_GetGibs (ModelID: Integer; var Gibs: TGibsArray): Boolean; +function g_PlayerModel_GetIndex (ModelName: String): Integer; + +{$IFDEF ENABLE_GFX} + function g_PlayerModel_GetBlood(ModelName: String): TModelBlood; +{$ENDIF} + +procedure g_PlayerModel_LoadFake (ModelName, FileName: String); (* --- private data --- *) type TPlayerModelInfo = record - Info: TModelInfo; + Name: String; + Author: String; + Description: String; + HaveWeapon: Boolean; 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; + {$IFDEF ENABLE_GFX} + Blood: TModelBlood; + {$ENDIF} // ======================= FileName: String; Anim: TModelTextures; @@ -183,9 +177,13 @@ function g_PlayerModel_GetGibs(ModelName: String; var Gibs: TGibsArray): Boolea implementation -uses - g_sound, g_console, SysUtils, g_player, CONFIG, r_textures, r_animations, - e_sound, g_options, g_map, Math, e_log, wadreader; + uses + {$IFDEF ENABLE_GFX} + g_gfx, + {$ENDIF} + g_sound, g_console, SysUtils, g_player, CONFIG, + e_sound, g_options, g_map, Math, e_log, wadreader + ; const FLAG_DEFPOINT: TDFPoint = (X:32; Y:16); @@ -206,6 +204,20 @@ const WeapNames: Array [WP_FIRST + 1..WP_LAST] of String = ('csaw', 'hgun', 'sg', 'ssg', 'mgun', 'rkt', 'plz', 'bfg', 'spl', 'flm'); + function g_PlayerModel_GetIndex (ModelName: String): Integer; + var i: Integer; + begin + Result := -1; + if PlayerModelsArray <> nil then + begin + i := 0; + while (i < Length(PlayerModelsArray)) and (PlayerModelsArray[i].Name <> ModelName) do + Inc(i); + if i < Length(PlayerModelsArray) then + Result := i + end + end; + function GetPoint(var str: String; var point: TDFPoint): Boolean; var a, x, y: Integer; @@ -299,72 +311,23 @@ 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 + procedure g_PlayerModel_LoadFake (ModelName, FileName: String); + var id: Integer; 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); + SetLength(PlayerModelsArray, Length(PlayerModelsArray) + 1); + id := High(PlayerModelsArray); + PlayerModelsArray[id].Name := ModelName; + PlayerModelsArray[id].HaveWeapon := False; + PlayerModelsArray[id].FileName := FileName; end; - FreeImage(img); -end; - 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; @@ -405,27 +368,26 @@ begin prefix := FileName+':TEXTURES\'; - with PlayerModelsArray[ID].Info do - begin - Name := s; - Author := config.ReadStr('Model', 'author', ''); - Description := config.ReadStr('Model', 'description', ''); - end; - + PlayerModelsArray[ID].Name := s; + PlayerModelsArray[ID].Author := config.ReadStr('Model', 'author', ''); + PlayerModelsArray[ID].Description := config.ReadStr('Model', 'description', ''); PlayerModelsArray[ID].FileName := FileName; - with PlayerModelsArray[ID] do - begin - 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; + + {$IFDEF ENABLE_GFX} + with PlayerModelsArray[ID] do + begin + 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; + {$ENDIF} for b := A_STAND to A_LAST do begin @@ -505,26 +467,6 @@ begin 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 @@ -618,7 +560,7 @@ begin end; {if ok then g_Console_Add(Info.Name+' weapon points ok') else g_Console_Add(Info.Name+' weapon points fail');} - Info.HaveWeapon := ok; + PlayerModelsArray[ID].HaveWeapon := ok; s := config.ReadStr('Model', 'flag_point', ''); if not GetPoint(s, FlagPoint) then @@ -633,7 +575,7 @@ begin Result := True; end; -function g_PlayerModel_Get(ModelName: String): TPlayerModel; +function g_PlayerModel_Get (ModelName: String): TPlayerModel; var a: Integer; begin Result := nil; @@ -642,15 +584,12 @@ begin for a := 0 to High(PlayerModelsArray) do begin - if AnsiLowerCase(PlayerModelsArray[a].Info.Name) = AnsiLowerCase(ModelName) then + if AnsiLowerCase(PlayerModelsArray[a].Name) = AnsiLowerCase(ModelName) then begin Result := TPlayerModel.Create; with PlayerModelsArray[a] do begin - Result.FPainSounds := PainSounds; - Result.FDieSounds := DieSounds; - Result.FSlopSound := SlopSound; Result.FID := a; Result.ChangeAnimation(A_STAND, True); Break; @@ -659,77 +598,34 @@ begin end; end; -function g_PlayerModel_GetAnim(ModelName: string; AnimTyp: Byte; var _Anim, _Mask: TAnimation): Boolean; -var - a: Integer; - c: Boolean; - ID: DWORD; -begin - Result := False; + 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; - if PlayerModelsArray = nil then Exit; - for a := 0 to High(PlayerModelsArray) do - if PlayerModelsArray[a].Info.Name = ModelName then - with PlayerModelsArray[a] do + c := False; + SetLength(Gibs, gGibsCount); + for i := 0 to High(Gibs) do + begin + if c and (PlayerModelsArray[ModelID].GibsCount = 1) then begin - if AnimTyp in [A_STAND, A_WALK] then c := True else c := False; - - 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[AnimTyp]); - _Anim.Speed := ModelSpeed[AnimTyp]; - - 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[AnimTyp]); - _Mask.Speed := ModelSpeed[AnimTyp]; - + SetLength(Gibs, i); Break; end; - 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); - - for a := 0 to High(PlayerModelsArray) do - if PlayerModelsArray[a].Info.Name = ModelName then - begin - for i := 0 to High(Gibs) do - 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); - - 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 @@ -742,25 +638,11 @@ begin for i := 0 to High(PlayerModelsArray) do begin SetLength(Result, Length(Result)+1); - Result[High(Result)] := PlayerModelsArray[i].Info.Name; + Result[High(Result)] := PlayerModelsArray[i].Name; end; end; -function g_PlayerModel_GetInfo(ModelName: string): TModelInfo; -var - a: Integer; -begin - FillChar(Result, SizeOf(Result), 0); - if PlayerModelsArray = nil then Exit; - - for a := 0 to High(PlayerModelsArray) do - if PlayerModelsArray[a].Info.Name = ModelName then - begin - Result := PlayerModelsArray[a].Info; - Break; - end; -end; - +{$IFDEF ENABLE_GFX} function g_PlayerModel_GetBlood(ModelName: string): TModelBlood; var a: Integer; @@ -772,12 +654,13 @@ begin if PlayerModelsArray = nil then Exit; for a := 0 to High(PlayerModelsArray) do - if PlayerModelsArray[a].Info.Name = ModelName then + if PlayerModelsArray[a].Name = ModelName then begin Result := PlayerModelsArray[a].Blood; Break; end; end; +{$ENDIF} procedure g_PlayerModel_FreeData(); var i, b: Integer; @@ -832,33 +715,33 @@ begin if SoundType = MODELSOUND_PAIN then begin - if FPainSounds = nil then Exit; + if PlayerModelsArray[FID].PainSounds = nil then Exit; - for a := 0 to High(FPainSounds) do - if FPainSounds[a].Level = Level then + for a := 0 to High(PlayerModelsArray[FID].PainSounds) do + if PlayerModelsArray[FID].PainSounds[a].Level = Level then begin - SetLength(TempArray, Length(TempArray)+1); - TempArray[High(TempArray)] := FPainSounds[a].ID; + SetLength(TempArray, Length(TempArray) + 1); + TempArray[High(TempArray)] := PlayerModelsArray[FID].PainSounds[a].ID; end; end else begin - if (Level in [2, 3, 5]) and (FSlopSound > 0) then + if (Level in [2, 3, 5]) and (PlayerModelsArray[FID].SlopSound > 0) then begin g_Sound_PlayExAt('SOUND_MONSTER_SLOP', X, Y); - if FSlopSound = 1 then + if PlayerModelsArray[FID].SlopSound = 1 then begin Result := True; Exit; end; end; - if FDieSounds = nil then Exit; + if PlayerModelsArray[FID].DieSounds = nil then Exit; - for a := 0 to High(FDieSounds) do - if FDieSounds[a].Level = Level then + for a := 0 to High(PlayerModelsArray[FID].DieSounds) do + if PlayerModelsArray[FID].DieSounds[a].Level = Level then begin - SetLength(TempArray, Length(TempArray)+1); - TempArray[High(TempArray)] := FDieSounds[a].ID; + SetLength(TempArray, Length(TempArray) + 1); + TempArray[High(TempArray)] := PlayerModelsArray[FID].DieSounds[a].ID; end; if (TempArray = nil) and (Level = 5) then begin @@ -882,14 +765,18 @@ begin FColor.B := Blue; end; -procedure TPlayerModel.SetFire(Fire: Boolean); -begin - FFire := Fire; - if FFire then - FFireCounter := PlayerModelsArray[FID].ModelSpeed[A_ATTACK] * PlayerModelsArray[FID].Anim[TDirection.D_RIGHT, A_ATTACK].Frames - else - FFireCounter := 0 -end; + procedure TPlayerModel.SetFire (Fire: Boolean); + begin + if Fire then + FFireCounter := PlayerModelsArray[FID].ModelSpeed[A_ATTACK] * PlayerModelsArray[FID].Anim[TDirection.D_RIGHT, A_ATTACK].Frames + 1 + else + FFireCounter := 0 + end; + + function TPlayerModel.GetFire (): Boolean; + begin + Result := FFireCounter > 0 + end; procedure TPlayerModel.SetFlag (Flag: Byte); begin @@ -901,14 +788,16 @@ end; FCurrentWeapon := Weapon end; +{$IFDEF ENABLE_GFX} function TPlayerModel.GetBlood (): TModelBlood; begin Result := PlayerModelsArray[FID].Blood end; +{$ENDIF} function TPlayerModel.GetName (): String; begin - Result := PlayerModelsArray[FID].Info.Name + Result := PlayerModelsArray[FID].Name end; procedure TPlayerModel.Update; @@ -917,8 +806,6 @@ end; FAnimState.Update; if FFireCounter > 0 then Dec(FFireCounter) - else - FFire := False end; procedure g_PlayerModel_LoadAll;