X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_playermodel.pas;h=6ba81745efde669846f1f91ad94c9593174d7b59;hb=67d37ea13feeca0671d60d88b1963cf1e0e901c4;hp=ebb3915efedfbc09ab7379729f7fa9bcd4dcfd78;hpb=56ec1dee6d63a32353f94eac7e87d6a42b801a25;p=d2df-sdl.git diff --git a/src/game/g_playermodel.pas b/src/game/g_playermodel.pas index ebb3915..6ba8174 100644 --- a/src/game/g_playermodel.pas +++ b/src/game/g_playermodel.pas @@ -1,9 +1,8 @@ -(* 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 @@ -21,7 +20,8 @@ interface uses {$IFDEF USE_MEMPOOL}mempool,{$ENDIF} - MAPDEF, g_textures, g_basic, g_weapons, e_graphics, utils; + MAPDEF, g_textures, g_basic, g_weapons, e_graphics, utils, g_gfx, + ImagingTypes, Imaging, ImagingUtility; const A_STAND = 0; @@ -35,22 +35,22 @@ const 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_WALKATTACK = 10; + A_WALKSEEUP = 11; + A_WALKSEEDOWN = 12; + A_WALKATTACKUP = 13; + A_WALKATTACKDOWN = 14; + A_MELEESTAND = 15; + A_MELEEWALK = 16; + A_MELEEATTACK = 17; + A_MELEEWALKATTACK = 18; + A_MELEESEEUP = 19; + A_MELEESEEDOWN = 20; + A_MELEEATTACKUP = 21; + A_MELEEATTACKDOWN = 22; A_LASTBASE = A_PAIN; - A_LASTEXT = A_FISTATTACKDOWN; + A_LASTEXT = A_MELEEATTACKDOWN; A_LAST = A_LASTEXT; MODELSOUND_PAIN = 0; @@ -64,6 +64,10 @@ type HaveWeapon: Boolean; end; + TModelBlood = record + R, G, B, Kind: Byte; + end; + TModelSound = record ID: DWORD; Level: Byte; @@ -87,6 +91,7 @@ type FName: String; FDirection: TDirection; FColor: TRGB; + FBlood: TModelBlood; FCurrentAnimation: Byte; 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; @@ -125,6 +130,7 @@ type public property Color: TRGB read FColor write FColor; + property Blood: TModelBlood read FBlood; end; procedure g_PlayerModel_LoadData(); @@ -132,6 +138,7 @@ 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_GetGibs(ModelName: String; var Gibs: TGibsArray): Boolean; @@ -140,8 +147,9 @@ function g_PlayerModel_GetGibs(ModelName: String; var Gibs: TGibsArray): Boolea 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, wadreader; + e_sound, g_options, g_map, Math, e_log, wadreader; type TPlayerModelInfo = record @@ -154,6 +162,7 @@ type PainSounds: TModelSoundArray; DieSounds: TModelSoundArray; SlopSound: Byte; + Blood: TModelBlood; end; const @@ -177,9 +186,9 @@ const 'SeeUpAnim','SeeDownAnim','AttackUpAnim','AttackDownAnim','PainAnim', // EXTENDED 'WalkAttackAnim', 'WalkSeeUpAnim', 'WalkSeeDownAnim', - 'WalkAttackUpAnim', 'WalkAttackDownAnim', 'FistStandAnim', 'FistWalkAnim', - 'FistAttackAnim', 'FistWalkAttackAnim', 'FistSeeUpAnim', 'FistSeeDownAnim', - 'FistAttackUpAnim', 'FistAttackDownAnim'); + 'WalkAttackUpAnim', 'WalkAttackDownAnim', 'MeleeStandAnim', 'MeleeWalkAnim', + 'MeleeAttackAnim', 'MeleeWalkAttackAnim', 'MeleeSeeUpAnim', 'MeleeSeeDownAnim', + 'MeleeAttackUpAnim', 'MeleeAttackDownAnim'); WeapNames: Array [WP_FIRST + 1..WP_LAST] of String = ('csaw', 'hgun', 'sg', 'ssg', 'mgun', 'rkt', 'plz', 'bfg', 'spl', 'flm'); @@ -317,6 +326,65 @@ begin 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; @@ -329,7 +397,7 @@ var prefix: string; ok, chk: Boolean; begin - e_WriteLog(Format('Loading player model: %s', [ExtractFileName(FileName)]), TMsgType.Notify); + e_WriteLog(Format('Loading player model "%s"...', [FileName]), TMsgType.Notify); Result := False; @@ -371,6 +439,20 @@ begin Description := config.ReadStr('Model', 'description', ''); end; + 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; + for b := A_STAND to A_LAST do begin aname := s+'_RIGHTANIM'+IntToStr(b); @@ -465,7 +547,8 @@ begin 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; @@ -581,6 +664,7 @@ begin with PlayerModelsArray[a] do begin Result.FName := Info.Name; + Result.FBlood := Blood; for b := A_STAND to A_LAST do begin @@ -723,6 +807,24 @@ 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;