Refined weapon rendering

This commit is contained in:
Silent 2014-08-19 12:57:35 +02:00
parent a99b6cab4e
commit 77d61dcdd2
8 changed files with 653 additions and 29 deletions

View file

@ -5,6 +5,8 @@
static void* EntityRender = AddressByVersion<void*>(0x534310, 0, 0);
WRAPPER void CEntity::Render() { VARJMP(EntityRender); }
CWeaponInfo* (*CWeaponInfo::GetWeaponInfo)(eWeaponType, signed char) = AddressByVersion<CWeaponInfo*(*)(eWeaponType, signed char)>(0x743C60, 0, 0);
static RwTexture*& ms_pRemapTexture = **AddressByVersion<RwTexture***>(0x59F1BD, 0, 0);
static unsigned char* ms_currentCol = *AddressByVersion<unsigned char**>(0x4C84C8, 0, 0);

View file

@ -368,6 +368,187 @@ public:
unsigned char flags;
};
enum eWeaponSkill
{
WEAPONSKILL_POOR = 0,
WEAPONSKILL_STD,
WEAPONSKILL_PRO,
WEAPONSKILL_SPECIAL, // for cops using pistols differently for example
WEAPONSKILL_MAX_NUMBER
};
enum eFireType
{
FIRETYPE_MELEE,
FIRETYPE_INSTANT_HIT,
FIRETYPE_PROJECTILE,
FIRETYPE_AREA_EFFECT,
FIRETYPE_CAMERA,
FIRETYPE_USE,
FIRETYPE_LAST_FIRETYPE
};
enum eWeaponSlot
{
WEAPONSLOT_TYPE_UNARMED = 0,
WEAPONSLOT_TYPE_MELEE,
WEAPONSLOT_TYPE_HANDGUN,
WEAPONSLOT_TYPE_SHOTGUN,
WEAPONSLOT_TYPE_SMG, //4
WEAPONSLOT_TYPE_MG,
WEAPONSLOT_TYPE_RIFLE,
WEAPONSLOT_TYPE_HEAVY,
WEAPONSLOT_TYPE_THROWN,
WEAPONSLOT_TYPE_SPECIAL, //9
WEAPONSLOT_TYPE_GIFT, //10
WEAPONSLOT_TYPE_PARACHUTE, //11
WEAPONSLOT_TYPE_DETONATOR, //12
WEAPONSLOT_MAX
};
enum eWeaponState
{
WEAPONSTATE_READY,
WEAPONSTATE_FIRING,
WEAPONSTATE_RELOADING,
WEAPONSTATE_OUT_OF_AMMO,
WEAPONSTATE_MELEE_MADECONTACT
};
/**
* Contains the weapon types/models
*/
enum eWeaponType
{
WEAPONTYPE_UNARMED=0,
WEAPONTYPE_BRASSKNUCKLE,
WEAPONTYPE_GOLFCLUB,
WEAPONTYPE_NIGHTSTICK,
WEAPONTYPE_KNIFE,
WEAPONTYPE_BASEBALLBAT,
WEAPONTYPE_SHOVEL,
WEAPONTYPE_POOL_CUE,
WEAPONTYPE_KATANA,
WEAPONTYPE_CHAINSAW,
// gifts
WEAPONTYPE_DILDO1, // 10
WEAPONTYPE_DILDO2,
WEAPONTYPE_VIBE1,
WEAPONTYPE_VIBE2,
WEAPONTYPE_FLOWERS,
WEAPONTYPE_CANE,
WEAPONTYPE_GRENADE,
WEAPONTYPE_TEARGAS,
WEAPONTYPE_MOLOTOV,
WEAPONTYPE_ROCKET,
WEAPONTYPE_ROCKET_HS, // 20
WEAPONTYPE_FREEFALL_BOMB,
// FIRST SKILL WEAPON
WEAPONTYPE_PISTOL, // handguns
WEAPONTYPE_PISTOL_SILENCED,
WEAPONTYPE_DESERT_EAGLE,
WEAPONTYPE_SHOTGUN, // shotguns
WEAPONTYPE_SAWNOFF_SHOTGUN, // one handed
WEAPONTYPE_SPAS12_SHOTGUN,
WEAPONTYPE_MICRO_UZI, // submachine guns
WEAPONTYPE_MP5,
WEAPONTYPE_AK47, // 30 // machine guns
WEAPONTYPE_M4,
WEAPONTYPE_TEC9, // this uses stat from the micro_uzi
// END SKILL WEAPONS
WEAPONTYPE_COUNTRYRIFLE, // rifles
WEAPONTYPE_SNIPERRIFLE,
WEAPONTYPE_ROCKETLAUNCHER, // specials
WEAPONTYPE_ROCKETLAUNCHER_HS,
WEAPONTYPE_FLAMETHROWER,
WEAPONTYPE_MINIGUN,
WEAPONTYPE_REMOTE_SATCHEL_CHARGE,
WEAPONTYPE_DETONATOR, // 40 // plastic explosive
WEAPONTYPE_SPRAYCAN,
WEAPONTYPE_EXTINGUISHER,
WEAPONTYPE_CAMERA,
WEAPONTYPE_NIGHTVISION,
WEAPONTYPE_INFRARED,
WEAPONTYPE_PARACHUTE,
WEAPONTYPE_LAST_WEAPONTYPE,
WEAPONTYPE_ARMOUR,
// these are possible ways to die
WEAPONTYPE_RAMMEDBYCAR,
WEAPONTYPE_RUNOVERBYCAR, // 50
WEAPONTYPE_EXPLOSION,
WEAPONTYPE_UZI_DRIVEBY,
WEAPONTYPE_DROWNING,
WEAPONTYPE_FALL,
WEAPONTYPE_UNIDENTIFIED, // Used for damage being done
WEAPONTYPE_ANYMELEE,
WEAPONTYPE_ANYWEAPON,
WEAPONTYPE_FLARE,
};
class CWeapon
{
public:
eWeaponType m_eWeaponType;
eWeaponState m_eState;
int m_nAmmoInClip;
int m_nAmmoTotal;
int m_nTimer;
int m_Unknown;
void* m_pParticle;
};
class CWeaponInfo
{
public:
DWORD weaponType;
DWORD targetRange;
DWORD weaponRange;
int dwModelID;
int dwModelID2;
int nSlot;
DWORD hexFlags;
DWORD animStyle;
WORD ammoClip;
DWORD fireOffsetX;
DWORD fireOffsetY;
DWORD fireOffsetZ;
DWORD skillLevel;
DWORD reqStatLevel;
float accuracy;
DWORD moveSpeed;
DWORD animLoopStart;
DWORD animLoopEnd;
DWORD animLoopFire;
DWORD animLoop2Start;
DWORD animLoop2End;
DWORD animLoop2Fire;
DWORD breakoutTime;
DWORD speed;
DWORD radius;
DWORD lifespan;
DWORD spread;
DWORD animStyle2;
public:
inline float GetAccuracy()
{ return accuracy; };
inline DWORD GetWeaponType()
{ return weaponType; };
inline DWORD GetClipSize()
{ return ammoClip; };
inline DWORD GetWeaponSlot()
{ return nSlot; };
static CWeaponInfo* (*GetWeaponInfo)(eWeaponType weaponID, signed char bType);
};
static_assert(sizeof(CEntity) == 0x38, "Wrong size: CEntity");
static_assert(sizeof(CPhysical) == 0x138, "Wrong size: CPhysical");
static_assert(sizeof(CObject) == 0x17C, "Wrong size: CObject");

77
SAFix/PedSA.cpp Normal file
View file

@ -0,0 +1,77 @@
#include "StdAfxSA.h"
#include "PedSA.h"
static void* varGetWeaponSkill = AddressByVersion<void*>(0x5E6580, 0, 0);
WRAPPER unsigned char CPed::GetWeaponSkill() { VARJMP(varGetWeaponSkill); }
static void* varResetGunFlashAlpha = AddressByVersion<void*>(0x5DF4E0, 0, 0);
WRAPPER void CPed::ResetGunFlashAlpha() { VARJMP(varResetGunFlashAlpha); }
static void* varSetGunFlashAlpha = AddressByVersion<void*>(0x5DF400, 0, 0);
WRAPPER void CPed::SetGunFlashAlpha(bool bSecondWeapon) { WRAPARG(bSecondWeapon); VARJMP(varSetGunFlashAlpha); }
static RwObject* GetFirstObjectCallback(RwObject* pObject, void* pData)
{
*static_cast<RwObject**>(pData) = pObject;
return nullptr;
}
RwObject* GetFirstObject(RwFrame* pFrame)
{
RwObject* pObject = nullptr;
RwFrameForAllObjects(pFrame, GetFirstObjectCallback, &pObject);
return pObject;
}
void CPed::RenderWeapon(bool bMuzzleFlash)
{
if ( m_pWeaponObject )
{
RpHAnimHierarchy* pAnimHierarchy = GetAnimHierarchyFromSkinClump(m_pRwObject);
bool bHasParachute = weaponSlots[m_bActiveWeapon].m_eWeaponType == WEAPONTYPE_PARACHUTE;
RwFrame* pFrame = RpClumpGetFrame(reinterpret_cast<RpClump*>(m_pWeaponObject));
*RwFrameGetMatrix(pFrame) = RpHAnimHierarchyGetMatrixArray(pAnimHierarchy)[RpHAnimIDGetIndex(pAnimHierarchy, bHasParachute ? 3 : 24)];
if ( bHasParachute )
{
const RwV3d vecParachuteTranslation = { 0.1f, -0.15f, 0.0f };
const RwV3d vecParachuteRotation = { 0.0f, 1.0f, 0.0f };
RwMatrixTranslate(RwFrameGetMatrix(pFrame), &vecParachuteTranslation, rwCOMBINEPRECONCAT);
RwMatrixRotate(RwFrameGetMatrix(pFrame), &vecParachuteRotation, 90.0f, rwCOMBINEPRECONCAT);
}
RwFrameUpdateObjects(pFrame);
if ( !bMuzzleFlash )
{
RpClumpRender(reinterpret_cast<RpClump*>(m_pWeaponObject));
}
else if ( m_pMuzzleFlashFrame )
{
SetGunFlashAlpha(false);
RpAtomicRender(reinterpret_cast<RpAtomic*>(GetFirstObject(m_pMuzzleFlashFrame)));
}
// Dual weapons
if ( CWeaponInfo::GetWeaponInfo(weaponSlots[m_bActiveWeapon].m_eWeaponType, GetWeaponSkill())->hexFlags >> 11 & 1 )
{
*RwFrameGetMatrix(pFrame) = RpHAnimHierarchyGetMatrixArray(pAnimHierarchy)[RpHAnimIDGetIndex(pAnimHierarchy, 34)];
const RwV3d vecParachuteRotation = { 1.0f, 0.0f, 0.0f };
const RwV3d vecParachuteTranslation = { 0.04f, -0.05f, 0.0f };
RwMatrixRotate(RwFrameGetMatrix(pFrame), &vecParachuteRotation, 180.0f, rwCOMBINEPRECONCAT);
RwMatrixTranslate(RwFrameGetMatrix(pFrame), &vecParachuteTranslation, rwCOMBINEPRECONCAT);
RwFrameUpdateObjects(pFrame);
if ( !bMuzzleFlash )
{
RpClumpRender(reinterpret_cast<RpClump*>(m_pWeaponObject));
}
else if ( m_pMuzzleFlashFrame )
{
SetGunFlashAlpha(true);
RpAtomicRender(reinterpret_cast<RpAtomic*>(GetFirstObject(m_pMuzzleFlashFrame)));
}
}
if ( bMuzzleFlash )
ResetGunFlashAlpha();
}
}

305
SAFix/PedSA.h Normal file
View file

@ -0,0 +1,305 @@
#ifndef __PEDSA
#define __PEDSA
#include "GeneralSA.h"
class CEntryExit;
class CPedFlags
{
public:
unsigned int bIsStanding : 1; // is ped standing on something
unsigned int bWasStanding : 1; // was ped standing on something
unsigned int bIsLooking : 1; // is ped looking at something or in a direction
unsigned int bIsRestoringLook : 1; // is ped restoring head postion from a look
unsigned int bIsAimingGun : 1; // is ped aiming gun
unsigned int bIsRestoringGun : 1; // is ped moving gun back to default posn
unsigned int bCanPointGunAtTarget : 1; // can ped point gun at target
unsigned int bIsTalking : 1; // is ped talking(see Chat())
unsigned int bInVehicle : 1; // is in a vehicle
unsigned int bIsInTheAir : 1; // is in the air
unsigned int bIsLanding : 1; // is landing after being in the air
unsigned int bHitSomethingLastFrame : 1; // has been in a collision last fram
unsigned int bIsNearCar : 1; // has been in a collision last fram
unsigned int bRenderPedInCar : 1; // has been in a collision last fram
unsigned int bUpdateAnimHeading : 1; // update ped heading due to heading change during anim sequence
unsigned int bRemoveHead : 1; // waiting on AntiSpazTimer to remove head
unsigned int bFiringWeapon : 1; // is pulling trigger
unsigned int bHasACamera : 1; // does ped possess a camera to document accidents
unsigned int bPedIsBleeding : 1; // Ped loses a lot of blood if true
unsigned int bStopAndShoot : 1; // Ped cannot reach target to attack with fist, need to use gun
unsigned int bIsPedDieAnimPlaying : 1; // is ped die animation finished so can dead now
unsigned int bStayInSamePlace :1; // when set, ped stays put
unsigned int bKindaStayInSamePlace :1; // when set, ped doesn't seek out opponent or cover large distances. Will still shuffle and look for cover
unsigned int bBeingChasedByPolice :1; // use nodes for routefind
unsigned int bNotAllowedToDuck :1; // Is this ped allowed to duck at all?
unsigned int bCrouchWhenShooting :1; // duck behind cars etc
unsigned int bIsDucking :1; // duck behind cars etc
unsigned int bGetUpAnimStarted :1; // don't want to play getup anim if under something
unsigned int bDoBloodyFootprints :1; // unsigned int bIsLeader :1;
unsigned int bDontDragMeOutCar :1;
unsigned int bStillOnValidPoly :1; // set if the polygon the ped is on is still valid for collision
unsigned int bAllowMedicsToReviveMe :1;
unsigned int bResetWalkAnims :1;
unsigned int bOnBoat :1; // flee but only using nodes
unsigned int bBusJacked :1; // flee but only using nodes
unsigned int bFadeOut :1; // set if you want ped to fade out
unsigned int bKnockedUpIntoAir :1; // has ped been knocked up into the air by a car collision
unsigned int bHitSteepSlope :1; // has ped collided/is standing on a steep slope (surface type)
unsigned int bCullExtraFarAway :1; // special ped only gets culled if it's extra far away (for roadblocks)
unsigned int bTryingToReachDryLand :1; // has ped just exited boat and trying to get to dry land
unsigned int bCollidedWithMyVehicle :1;
unsigned int bRichFromMugging :1; // ped has lots of cash cause they've been mugging people
unsigned int bChrisCriminal :1; // Is a criminal as killed during Chris' police mission (should be counted as such)
unsigned int bShakeFist :1; // test shake hand at look entity
unsigned int bNoCriticalHits : 1; // ped cannot be killed by a single bullet
unsigned int bHasAlreadyBeenRecorded : 1; // Used for replays
unsigned int bUpdateMatricesRequired : 1; // if PedIK has altered bones so matrices need updated this frame
unsigned int bFleeWhenStanding :1; //
unsigned int bMiamiViceCop :1; //
unsigned int bMoneyHasBeenGivenByScript :1; //
unsigned int bHasBeenPhotographed :1; //
unsigned int bIsDrowning : 1;
unsigned int bDrownsInWater : 1;
unsigned int bHeadStuckInCollision : 1;
unsigned int bDeadPedInFrontOfCar :1;
unsigned int bStayInCarOnJack :1;
unsigned int bDontFight :1;
unsigned int bDoomAim :1;
unsigned int bCanBeShotInVehicle : 1;
unsigned int bPushedAlongByCar :1; // ped is getting pushed along by car collision (so don't take damage from horz velocity)
unsigned int bNeverEverTargetThisPed :1;
unsigned int bThisPedIsATargetPriority :1;
unsigned int bCrouchWhenScared :1;
unsigned int bKnockedOffBike :1;
unsigned int bDonePositionOutOfCollision :1;
unsigned int bDontRender : 1;
unsigned int bHasBeenAddedToPopulation :1;
unsigned int bHasJustLeftCar :1;
unsigned int bIsInDisguise :1;
unsigned int bDoesntListenToPlayerGroupCommands :1;
unsigned int bIsBeingArrested :1;
unsigned int bHasJustSoughtCover :1;
unsigned int bKilledByStealth :1;
unsigned int bDoesntDropWeaponsWhenDead :1;
unsigned int bCalledPreRender :1;
unsigned int bBloodPuddleCreated : 1; // Has a static puddle of blood been created yet
unsigned int bPartOfAttackWave :1;
unsigned int bClearRadarBlipOnDeath :1;
unsigned int bNeverLeavesGroup :1; // flag that we want to test 3 extra spheres on col model
unsigned int bTestForBlockedPositions :1; // this sets these indicator flags for various posisions on the front of the ped
unsigned int bRightArmBlocked :1;
unsigned int bLeftArmBlocked :1;
unsigned int bDuckRightArmBlocked :1;
unsigned int bMidriffBlockedForJump :1;
unsigned int bFallenDown :1;
unsigned int bUseAttractorInstantly :1;
unsigned int bDontAcceptIKLookAts :1;
unsigned int bHasAScriptBrain : 1;
unsigned int bWaitingForScriptBrainToLoad : 1;
unsigned int bHasGroupDriveTask :1;
unsigned int bCanExitCar :1;
unsigned int CantBeKnockedOffBike :2; // 0=Default(harder for mission peds) 1=Never 2=Always normal(also for mission peds)
unsigned int bHasBeenRendered : 1;
unsigned int bIsCached :1;
unsigned int bPushOtherPeds :1; // GETS RESET EVERY FRAME - SET IN TASK: want to push other peds around (eg. leader of a group or ped trying to get in a car)
unsigned int bHasBulletProofVest :1;
unsigned int bUsingMobilePhone :1;
unsigned int bUpperBodyDamageAnimsOnly :1;
unsigned int bStuckUnderCar :1;
unsigned int bKeepTasksAfterCleanUp :1; // If true ped will carry on with task even after cleanup
unsigned int bIsDyingStuck :1;
unsigned int bIgnoreHeightCheckOnGotoPointTask :1; // set when walking round buildings, reset when task quits
unsigned int bForceDieInCar:1;
unsigned int bCheckColAboveHead:1;
unsigned int bIgnoreWeaponRange : 1;
unsigned int bDruggedUp : 1;
unsigned int bWantedByPolice : 1; // if this is set, the cops will always go after this ped when they are doing a KillCriminal task
unsigned int bSignalAfterKill: 1;
unsigned int bCanClimbOntoBoat :1;
unsigned int bPedHitWallLastFrame: 1; // useful to store this so that AI knows (normal will still be available)
unsigned int bIgnoreHeightDifferenceFollowingNodes: 1;
unsigned int bMoveAnimSpeedHasBeenSetByTask: 1;
unsigned int bGetOutUpsideDownCar :1;
unsigned int bJustGotOffTrain :1;
unsigned int bDeathPickupsPersist :1;
unsigned int bTestForShotInVehicle :1;
unsigned int bUsedForReplay : 1; // This ped is controlled by replay and should be removed when replay is done.
};
class CVehicle;
class CPed;
class CPlayerPedData
{
public:
class CWanted* m_Wanted; // 0x0
void* m_pClothes; // 0x4
CPed* m_ArrestingOfficer; // 0x8
CVector2D m_vecFightMovement; // 0xC
float m_moveBlendRatio; // 0x14
float m_fSprintEnergy; // 0x18
float m_fSprintControlCounter; // 0x1C
BYTE m_nChosenWeapon; // 0x20
BYTE m_nCarDangerCounter; // 0x21
DWORD m_nStandStillTimer; // 0x24
DWORD m_nHitAnimDelayTimer; // 0x28
float m_fAttackButtonCounter; // 0x2C
void *m_pDangerCar; // 0x30
DWORD m_bStoppedMoving : 1; // 0x34
DWORD m_bAdrenaline : 1;
DWORD m_bHaveTargetSelected : 1;
DWORD m_bFreeAiming : 1;
DWORD bCanBeDamaged : 1;
DWORD bAllMeleeAttackPtsBlocked : 1;
DWORD m_JustBeenSnacking : 1;
DWORD m_bRequireHandleBreath : 1;
DWORD m_GroupStuffDisabled : 1; // 0x35
DWORD m_GroupAlwaysFollow : 1;
DWORD m_GroupNeverFollow : 1;
DWORD m_bInVehicleDontAllowWeaponChange : 1;
DWORD m_bRenderWeapon : 1;
DWORD m_bUnused1 : 1;
DWORD m_bUnused2 : 1;
DWORD m_bUnused3 : 1;
DWORD m_bCopMode : 1; // 0x36
DWORD m_PlayerGroup; // 0x38
DWORD m_AdrenalineEndTime; // 0x3C
BYTE m_nDrunkenness; // 0x40
BYTE m_bFadeDrunkenness; // 0x41
BYTE m_nDrugLevel; // 0x42
BYTE m_nScriptLimitToGangSize; // 0x43
float m_fBreath; // 0x44
DWORD m_MeleeWeaponAnimReferenced; // 0x48
DWORD m_MeleeWeaponAnimReferencedExtra; // 0x4C
float m_fFPSMoveHeading; // 0x50
float m_fLookPitch; // 0x54
float m_fSkateBoardSpeed; // 0x58
float m_fSkateBoardLean; // 0x5C
void *m_pSpecialAtomic; // 0x60
float m_fGunSpinSpeed; // 0x64
float m_fGunSpinAngle; // 0x68
DWORD m_LastTimeFiring; // 0x6C
DWORD m_nTargetBone; // 0x70
CVector m_vecTargetBoneOffset; // 0x74
DWORD m_busFaresCollected; // 0x80
BYTE m_bPlayerSprintDisabled; // 0x84
BYTE m_bDontAllowWeaponChange; // 0x85
BYTE m_bForceInteriorLighting; // 0x86
WORD m_DPadDownPressedInMilliseconds; // 0x88
WORD m_DPadUpPressedInMilliseconds; // 0x8A
BYTE m_wetness; // 0x8C
BYTE m_playersGangActive; // 0x8D
BYTE m_waterCoverPerc; // 0x8E
FLOAT m_waterHeight; // 0x90
DWORD m_FireHSMissilePressedTime; // 0x94
void* m_LastHSMissileTarget;
DWORD m_nModelIndexOfLastBuildingShot;
DWORD m_LastHSMissileLOSTime :31;
DWORD m_bLastHSMissileLOS :1;
void* m_pCurrentProstitutePed;
void* m_pLastProstituteShagged;
};
class NOVMT CPed : public CPhysical
{
public:
BYTE __pad1[820];
CPedFlags pedFlags;
class CPedIntelligence* pPedIntelligence;
CPlayerPedData* pPlayerData;
unsigned char PedCreatedBy;
BYTE __pad7[76];
int iMoveAnimGroup;
BYTE __pad2[28];
RwObject* m_pWeaponObject;
RwFrame* m_pMuzzleFlashFrame;
BYTE __pad10[68];
float fHealth;
float fMaxHealth;
float fArmour;
BYTE __pad8[12];
float m_fCurrentRotation;
float m_fTargetRotation;
BYTE __pad3[44];
CVehicle* pVehicle;
BYTE __pad9[8];
DWORD pedType;
BYTE __pad4[4];
CWeapon weaponSlots[13];
BYTE __pad5[12];
BYTE m_bActiveWeapon;
BYTE __pad65[20];
unsigned char bFightingStyle, bFightingStyleExtra;
BYTE __pad6[92];
CEntryExit* pCurrentEntryExit;
BYTE __pad64[12];
public:
inline bool Save_Stub()
{ return CPed::Save(); }
inline bool Load_Stub()
{ return CPed::Load(); }
virtual bool Save();
virtual bool Load();
inline DWORD GetPedType()
{ return pedType; };
inline CPedFlags& GetPedFlags()
{ return pedFlags; };
inline CVehicle* GetVehiclePtr()
{ return pVehicle; };
inline CWeapon* GetWeaponSlots()
{ return weaponSlots; };
inline int GetMoveAnimGroup()
{ return iMoveAnimGroup; };
inline void SetMoveAnimGroup(int a)
{ iMoveAnimGroup = a; };
inline CPedIntelligence* GetPedIntelligencePtr()
{ return pPedIntelligence; };
inline float GetHealth()
{ return fHealth; };
inline float GetArmour()
{ return fArmour; };
inline CPlayerPedData* GetPlayerData()
{ return pPlayerData; };
inline BYTE GetActiveWeapon()
{ return m_bActiveWeapon; };
inline void SetCurrentHeading(float fVal)
{ m_fCurrentRotation = fVal; }
inline void SetTargetHeading(float fVal)
{ m_fTargetRotation = fVal; }
unsigned char GetWeaponSkill();
void ResetGunFlashAlpha();
void SetGunFlashAlpha(bool bSecondWeapon);
void RenderWeapon(bool bMuzzleFlash);
};
static_assert(sizeof(CPed) == 0x79C, "Wrong size: CPed");
#endif

View file

@ -95,6 +95,7 @@
<ClCompile Include="AudioHardwareSA.cpp" />
<ClCompile Include="GeneralSA.cpp" />
<ClCompile Include="ModelInfoSA.cpp" />
<ClCompile Include="PedSA.cpp" />
<ClCompile Include="PNGFile.cpp" />
<ClCompile Include="ScriptSA.cpp" />
<ClCompile Include="SilentPatchSA.cpp" />
@ -131,6 +132,7 @@
<ClInclude Include="LinkListSA.h" />
<ClInclude Include="Maths.h" />
<ClInclude Include="ModelInfoSA.h" />
<ClInclude Include="PedSA.h" />
<ClInclude Include="PNGFile.h" />
<ClInclude Include="ScriptSA.h" />
<ClInclude Include="StdAfxSA.h" />

View file

@ -48,6 +48,9 @@
<ClCompile Include="PNGFile.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PedSA.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\SilentPatch\win2000.asm">
@ -109,6 +112,9 @@
<ClInclude Include="PNGFile.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PedSA.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\SilentPatch\nvc.fx">

View file

@ -4,6 +4,7 @@
#include "GeneralSA.h"
#include "ModelInfoSA.h"
#include "VehicleSA.h"
#include "PedSA.h"
#include "AudioHardwareSA.h"
#include "LinkListSA.h"
#include "PNGFile.h"
@ -23,6 +24,10 @@ static void* varRpMaterialSetTexture = AddressByVersion<void*>(0x74DBC0, 0, 0);
WRAPPER RpMaterial *RpMaterialSetTexture(RpMaterial *material, RwTexture *texture) { VARJMP(varRpMaterialSetTexture); }
static void* varRwFrameGetLTM = AddressByVersion<void*>(0x7F0990, 0, 0);
WRAPPER RwMatrix* RwFrameGetLTM(RwFrame* frame) { VARJMP(varRwFrameGetLTM); }
static void* varRwMatrixTranslate = AddressByVersion<void*>(0x7F2450, 0, 0);
WRAPPER RwMatrix* RwMatrixTranslate(RwMatrix* matrix, const RwV3d* translation, RwOpCombineType combineOp) { WRAPARG(matrix); WRAPARG(translation); WRAPARG(combineOp); VARJMP(varRwMatrixTranslate); }
static void* varRwMatrixRotate = AddressByVersion<void*>(0x7F1FD0, 0, 0);
WRAPPER RwMatrix* RwMatrixRotate(RwMatrix* matrix, const RwV3d* axis, RwReal angle, RwOpCombineType combineOp) { WRAPARG(matrix); WRAPARG(axis); WRAPARG(angle); WRAPARG(combineOp); VARJMP(varRwMatrixRotate); }
static void* varRwD3D9SetRenderState = AddressByVersion<void*>(0x7FC2D0, 0, 0);
WRAPPER void RwD3D9SetRenderState(RwUInt32 state, RwUInt32 value) { WRAPARG(state); WRAPARG(value); VARJMP(varRwD3D9SetRenderState); }
static void* var_rwD3D9SetVertexShader = AddressByVersion<void*>(0x7F9FB0, 0, 0);
@ -67,6 +72,16 @@ RwFrame* RwFrameForAllObjects(RwFrame* frame, RwObjectCallBack callBack, void* d
return frame;
}
RwFrame* RwFrameUpdateObjects(RwFrame* frame)
{
if ( !rwObjectTestPrivateFlags(&frame->root->object, rwFRAMEPRIVATEHIERARCHYSYNCLTM|rwFRAMEPRIVATEHIERARCHYSYNCOBJ) )
rwLinkListAddLLLink(&RWSRCGLOBAL(dirtyFrameList), &frame->root->inDirtyListLink);
rwObjectSetPrivateFlags(&frame->root->object, rwObjectGetPrivateFlags(&frame->root->object) | (rwFRAMEPRIVATEHIERARCHYSYNCLTM|rwFRAMEPRIVATEHIERARCHYSYNCOBJ));
rwObjectSetPrivateFlags(&frame->object, rwObjectGetPrivateFlags(&frame->object) | (rwFRAMEPRIVATESUBTREESYNCLTM|rwFRAMEPRIVATESUBTREESYNCOBJ));
return frame;
}
RwMatrix* RwMatrixUpdate(RwMatrix* matrix)
{
matrix->flags &= ~(rwMATRIXTYPEMASK|rwMATRIXINTERNALIDENTITY);
@ -108,6 +123,23 @@ RpClump* RpClumpForAllAtomics(RpClump* clump, RpAtomicCallBack callback, void* p
return clump;
}
RpClump* RpClumpRender(RpClump* clump)
{
for ( RwLLLink* link = rwLinkListGetFirstLLLink(&clump->atomicList); link != rwLinkListGetTerminator(&clump->atomicList); link = rwLLLinkGetNext(link) )
{
RpAtomic* curAtomic = rwLLLinkGetData(link, RpAtomic, inClumpLink);
if ( RpAtomicGetFlags(curAtomic) & rpATOMICRENDER )
{
// Not sure why they need this
RwFrameGetLTM(RpAtomicGetFrame(curAtomic));
if ( !RpAtomicRender(curAtomic) )
return NULL;
}
}
return clump;
}
RpGeometry* RpGeometryForAllMaterials(RpGeometry* geometry, RpMaterialCallBack fpCallBack, void* pData)
{
for ( RwInt32 i = 0, j = geometry->matList.numMaterials; i < j; i++ )
@ -118,9 +150,32 @@ RpGeometry* RpGeometryForAllMaterials(RpGeometry* geometry, RpMaterialCallBack f
return geometry;
}
RwInt32 RpHAnimIDGetIndex(RpHAnimHierarchy* hierarchy, RwInt32 ID)
{
RpHAnimNodeInfo* curNodeInfo = hierarchy->pNodeInfo;
RwInt32 curNumNodes = hierarchy->numNodes;
if ( curNumNodes > 0 )
{
for ( RwInt32 i = 0; i < curNumNodes; i++ )
{
if ( ID == curNodeInfo->nodeID )
return i;
curNodeInfo++;
}
}
return -1;
}
RwMatrix* RpHAnimHierarchyGetMatrixArray(RpHAnimHierarchy* hierarchy)
{
return hierarchy->pMatrixArray;
}
// Other wrappers
void (*GTAdelete)(void*) = AddressByVersion<void(*)(void*)>(0x82413F, 0, 0);
const char* (*GetFrameNodeName)(RwFrame*) = AddressByVersion<const char*(*)(RwFrame*)>(0x72FB30, 0, 0);
RpHAnimHierarchy* (*GetAnimHierarchyFromSkinClump)(RpClump*) = AddressByVersion<RpHAnimHierarchy*(*)(RpClump*)>(0x734A40, 0, 0);
auto SetVolume = AddressByVersion<void(__thiscall*)(void*,float)>(0x4D7C60, 0, 0);
auto InitializeUtrax = AddressByVersion<void(__thiscall*)(void*)>(0x4F35B0, 0, 0);
auto CanSeeOutSideFromCurrArea = AddressByVersion<bool(*)()>(0x53C4A0, 0, 0);
@ -128,9 +183,6 @@ auto CanSeeOutSideFromCurrArea = AddressByVersion<bool(*)()>(0x53C4A0, 0, 0)
auto __rwD3D9TextureHasAlpha = AddressByVersion<BOOL(*)(RwTexture*)>(0x4C9EA0, 0, 0);
auto RenderOneXLUSprite = AddressByVersion<void(*)(float, float, float, float, float, int, int, int, int, float, char, char, char)>(0x70D000, 0, 0);
// That function is fake
auto RenderWeaponHooked = AddressByVersion<void(*)(CEntity*)>(0x732F95, 0, 0);
static BOOL (*IsAlreadyRunning)();
static void (*TheScriptsLoad)();
static void (*WipeLocalVariableMemoryForMissionScript)();
@ -162,7 +214,7 @@ unsigned char* ZonesVisited = *AddressByVersion<unsigned char**>(0x57216A, 0,
float& m_fDNBalanceParam = **AddressByVersion<float**>(0x4A9062, 0, 0);
RpLight*& pAmbient = **AddressByVersion<RpLight***>(0x5BA53A, 0, 0);
CLinkListSA<CEntity*>& ms_weaponPedsForPC = **AddressByVersion<CLinkListSA<CEntity*>**>(0x53EACA, 0, 0);
CLinkListSA<CPed*>& ms_weaponPedsForPC = **AddressByVersion<CLinkListSA<CPed*>**>(0x53EACA, 0, 0);
CLinkListSA<AlphaObjectInfo>& m_alphaList = **AddressByVersion<CLinkListSA<AlphaObjectInfo>**>(0x733A4D, 0, 0);
@ -398,31 +450,26 @@ void SetRendererForAtomic(RpAtomic* pAtomic)
RpAtomicSetRenderCallBack(pAtomic, renderer);
}
void RenderWeapon(CEntity* pEntity)
void RenderWeapon(CPed* pPed)
{
int nPushedAlpha, nAlphaFunction;
RwRenderStateGet(rwRENDERSTATEALPHATESTFUNCTIONREF, &nPushedAlpha);
RwRenderStateGet(rwRENDERSTATEALPHATESTFUNCTION, &nAlphaFunction);
if ( nPushedAlpha != 255 )
RwRenderStateSet(rwRENDERSTATEALPHATESTFUNCTIONREF, reinterpret_cast<void*>(255));
if ( nAlphaFunction != rwALPHATESTFUNCTIONEQUAL )
RwRenderStateSet(rwRENDERSTATEALPHATESTFUNCTION, reinterpret_cast<void*>(rwALPHATESTFUNCTIONEQUAL));
RenderWeaponHooked(pEntity);
if ( nPushedAlpha != 255 )
RwRenderStateSet(rwRENDERSTATEALPHATESTFUNCTIONREF, reinterpret_cast<void*>(nPushedAlpha));
if ( nAlphaFunction != rwALPHATESTFUNCTIONEQUAL )
RwRenderStateSet(rwRENDERSTATEALPHATESTFUNCTION, reinterpret_cast<void*>(nAlphaFunction));
ms_weaponPedsForPC.Insert(pEntity);
pPed->RenderWeapon(false);
ms_weaponPedsForPC.Insert(pPed);
}
void RenderWeaponsList()
void RenderWeaponPedsForPC()
{
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, reinterpret_cast<void*>(TRUE));
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, FALSE);
for ( auto it = ms_weaponPedsForPC.m_lnListHead.m_pNext; it != &ms_weaponPedsForPC.m_lnListTail; it = it->m_pNext )
{
it->V()->SetupLighting();
it->V()->RenderWeapon(true);
it->V()->RemoveLighting();
}
}
/*void RenderWeaponsList()
{
int nPushedAlpha, nAlphaFunction;
int nZWrite;
@ -449,7 +496,7 @@ void RenderWeaponsList()
RwRenderStateSet(rwRENDERSTATEALPHATESTFUNCTION, reinterpret_cast<void*>(nAlphaFunction));
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, reinterpret_cast<void*>(nZWrite));
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, reinterpret_cast<void*>(nAlphaBlending));
}
}*/
RpAtomic* RenderPedCB(RpAtomic* pAtomic)
{
@ -1350,7 +1397,7 @@ __forceinline void Patch_SA_10()
Patch<DWORD>(AddressByRegion_10<DWORD>(0x7469A0), 0x909000B0);
// Weapons rendering
InjectHook(0x5E7859, RenderWeapon);
/*InjectHook(0x5E7859, RenderWeapon);
InjectHook(0x732F30, RenderWeaponsList, PATCH_JUMP);
//Patch<WORD>(0x53EAC4, 0x0DEB);
//Patch<WORD>(0x705322, 0x0DEB);
@ -1364,7 +1411,9 @@ __forceinline void Patch_SA_10()
//Nop(0x732F93, 6);
//Nop(0x733144, 6);
Nop(0x732FA6, 6);
//Nop(0x5E46DA, 2);
//Nop(0x5E46DA, 2);*/
InjectHook(0x5E7859, RenderWeapon);
InjectHook(0x732F30, RenderWeaponPedsForPC, PATCH_JUMP);
// Hunter interior & static_rotor for helis
InjectHook(0x4C78F2, HunterTest, PATCH_JUMP);

View file

@ -30,6 +30,7 @@
#include <rwcore.h>
#include <rpworld.h>
#include <rphanim.h>
#include <rtpng.h>
#include <d3d9.h>
@ -50,6 +51,7 @@ struct AlphaObjectInfo
// SA operator delete
extern void (*GTAdelete)(void* data);
extern const char* (*GetFrameNodeName)(RwFrame*);
extern RpHAnimHierarchy* (*GetAnimHierarchyFromSkinClump)(RpClump*);
extern unsigned char& nGameClockDays;
extern unsigned char& nGameClockMonths;