Weapon fixes and thingies #555

Merged
erorcun merged 1 commits from miami into miami 5 years ago

Binary file not shown.

@ -84,7 +84,8 @@ public:
void SetRun(void) { flags |= ASSOC_RUNNING; }
inline float GetTimeLeft() { return hierarchy->totalLength - currentTime; }
float GetTimeLeft() { return hierarchy->totalLength - currentTime; }
float GetProgress() { return currentTime / hierarchy->totalLength; }
static CAnimBlendAssociation *FromLink(CAnimBlendLink *l) {
return (CAnimBlendAssociation*)((uint8*)l - offsetof(CAnimBlendAssociation, link));

@ -134,13 +134,13 @@ AnimAssocDesc aStdAnimDescs[] = {
{ ANIM_DRIVE_LOW_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_DRIVEBY_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_DRIVEBY_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_DRIVEBY_L_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_DRIVEBY_L_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_DRIVEBY_LOW_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_DRIVEBY_LOW_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_CAR_LB, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_DRIVE_BOAT, ASSOC_DELETEFADEDOUT | ASSOC_DRIVING },
{ ANIM_DRIVE_BOAT_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_DRIVE_BOAT_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_DRIVE_BOAT_BACK, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_BOAT_LB, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_BIKE_PICKUP_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_BIKE_PICKUP_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_BIKE_PULLUP_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },

@ -118,13 +118,13 @@ enum AnimationId
ANIM_DRIVE_LOW_R,
ANIM_DRIVEBY_L,
ANIM_DRIVEBY_R,
ANIM_DRIVEBY_L_L, // TODO: is this LOW?
ANIM_DRIVEBY_L_R,
ANIM_DRIVEBY_LOW_L,
ANIM_DRIVEBY_LOW_R,
ANIM_CAR_LB,
ANIM_DRIVE_BOAT,
ANIM_DRIVE_BOAT_L,
ANIM_DRIVE_BOAT_R,
ANIM_DRIVE_BOAT_BACK,
ANIM_BOAT_LB,
ANIM_BIKE_PICKUP_R,
ANIM_BIKE_PICKUP_L,

@ -9,6 +9,7 @@
#define TIME_COPS_WAIT_TO_EXIT_AFTER_STOPPING 2500
class CZoneInfo;
class CAutomobile;
enum{
MAX_CARS_TO_KEEP = 2,

@ -44,15 +44,44 @@ uint32 CPickups::StaticCamStartTime;
tPickupMessage CPickups::aMessages[NUMPICKUPMESSAGES];
// 20 ?! Some Miami leftover? (Originally at 0x5ED8D4)
// TODO(Miami)
uint16 AmmoForWeapon[20] = { 0, 1, 45, 125, 25, 150, 300, 25, 5, 250, 5, 5, 0, 500, 0, 100, 0, 0, 0, 0 };
uint16 AmmoForWeapon_OnStreet[20] = { 0, 1, 9, 25, 5, 30, 60, 5, 1, 50, 1, 1, 0, 200, 0, 100, 0, 0, 0, 0 };
uint16 AmmoForWeapon_OnStreet[WEAPONTYPE_TOTALWEAPONS] = {
0,
1,
4,
4,
4,
4,
34,
16,
100,
60,
60,
60,
60,
60,
20,
4,
14,
1,
400,
};
uint16 CostOfWeapon[20] = { 0, 10, 250, 800, 1500, 3000, 5000, 10000, 25000, 25000, 2000, 2000, 0, 50000, 0, 3000, 0, 0, 0, 0 };
uint8 aWeaponReds[] = { 255, 0, 128, 255, 255, 0, 255, 0, 128, 128, 255, 255, 128, 0, 255, 0 };
uint8 aWeaponGreens[] = { 0, 255, 128, 255, 0, 255, 128, 255, 0, 255, 255, 0, 255, 0, 255, 0 };
uint8 aWeaponBlues[] = { 0, 0, 255, 0, 255, 255, 0, 128, 255, 0, 255, 0, 128, 255, 0, 0 };
float aWeaponScale[] = { 1.0f, 2.0f, 1.5f, 1.0f, 1.0f, 1.5f, 1.0f, 2.0f, 1.0f, 2.0f, 2.5f, 1.0f, 1.0f, 1.0f, 1.0f };
// TODO(Miami): Those are all placeholders!!
uint8 aWeaponReds[] = { 0, 255, 0, 128, 255, 255, 0, 255, 0, 128, 128, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 128, 0, 255, 0 };
uint8 aWeaponGreens[] = { 0, 0, 255, 128, 255, 0, 255, 128, 255, 0, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
0, 255, 0, 255, 0 };
uint8 aWeaponBlues[] = { 0, 0, 0, 255, 0, 255, 255, 0, 128, 255, 0, 255,
255, 255, 255, 255, 255, 255, 255, 255,
0, 128, 255, 0, 0 };
float aWeaponScale[] = { 1.0f, 1.0f, 2.0f, 1.5f, 1.0f, 1.0f, 1.5f, 1.0f, 2.0f, 1.0f, 2.0f, 2.5f,
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f };
void
CPickup::RemoveKeepType()
@ -380,6 +409,30 @@ CPickups::Init(void)
CollectedPickUpIndex = 0;
}
// --MIAMI: Done
bool
CPickups::TestForPickupsInBubble(CVector pos, float range)
{
for (int i = 0; i < NUMPICKUPS; i++) {
if ((aPickUps[i].m_vecPos - pos).Magnitude() < range)
return true;
}
return false;
}
// --MIAMI: Done
bool
CPickups::TryToMerge_WeaponType(CVector pos, eWeaponType weapon, uint8 type, uint32 quantity, bool unused) {
for (int i = 0; i < NUMPICKUPS; i++) {
if (aPickUps[i].m_eType == type && aPickUps[i].m_eModelIndex == ModelForWeapon(weapon))
if ((aPickUps[i].m_vecPos - pos).Magnitude() < 7.5f) {
aPickUps[i].m_nQuantity += quantity;
return true;
}
}
return false;
}
bool
CPickups::IsPickUpPickedUp(int32 pickupId)
{
@ -561,53 +614,22 @@ CPickups::GetNewUniquePickupIndex(int32 slot)
return slot | (aPickUps[slot].m_nIndex << 16);
}
// --MIAMI: Done
int32
CPickups::ModelForWeapon(eWeaponType weaponType)
{
switch (weaponType)
{
case WEAPONTYPE_BASEBALLBAT: return MI_BASEBALL_BAT;
case WEAPONTYPE_COLT45: return MI_COLT;
case WEAPONTYPE_UZI: return MI_UZI;
case WEAPONTYPE_SHOTGUN: return MI_SHOTGUN;
case WEAPONTYPE_AK47: return MI_AK47;
case WEAPONTYPE_M16: return MI_M16;
case WEAPONTYPE_SNIPERRIFLE: return MI_SNIPER;
case WEAPONTYPE_ROCKETLAUNCHER: return MI_ROCKETLAUNCHER;
case WEAPONTYPE_FLAMETHROWER: return MI_FLAMETHROWER;
case WEAPONTYPE_MOLOTOV: return MI_MOLOTOV;
case WEAPONTYPE_GRENADE: return MI_GRENADE;
default: break;
}
return 0;
return CWeaponInfo::GetWeaponInfo(weaponType)->m_nModelId;
}
// --MIAMI: Done
eWeaponType
CPickups::WeaponForModel(int32 model)
{
if (model == MI_PICKUP_BODYARMOUR) return WEAPONTYPE_ARMOUR;
switch (model)
{
case MI_GRENADE: return WEAPONTYPE_GRENADE;
case MI_AK47: return WEAPONTYPE_AK47;
case MI_BASEBALL_BAT: return WEAPONTYPE_BASEBALLBAT;
case MI_COLT: return WEAPONTYPE_COLT45;
case MI_MOLOTOV: return WEAPONTYPE_MOLOTOV;
case MI_ROCKETLAUNCHER: return WEAPONTYPE_ROCKETLAUNCHER;
case MI_SHOTGUN: return WEAPONTYPE_SHOTGUN;
case MI_SNIPER: return WEAPONTYPE_SNIPERRIFLE;
case MI_UZI: return WEAPONTYPE_UZI;
case MI_MISSILE: return WEAPONTYPE_UNARMED;
case MI_M16: return WEAPONTYPE_M16;
case MI_FLAMETHROWER: return WEAPONTYPE_FLAMETHROWER;
}
return WEAPONTYPE_UNARMED;
}
int32
CPickups::FindColourIndexForWeaponMI(int32 model)
{
return WeaponForModel(model) - 1;
if (model == MI_PICKUP_HEALTH) return WEAPONTYPE_HEALTH;
if (model == MI_PICKUP_ADRENALINE) return WEAPONTYPE_ARMOUR;
if (model == -1) return WEAPONTYPE_UNARMED;
return (eWeaponType)((CWeaponModelInfo*)CModelInfo::GetModelInfo(model))->GetWeaponInfo();
}
void
@ -685,15 +707,15 @@ CPickups::DoPickUpEffects(CEntity *entity)
int16 colorId;
if (entity->GetModelIndex() == MI_PICKUP_ADRENALINE || entity->GetModelIndex() == MI_PICKUP_CAMERA)
colorId = 11;
colorId = WEAPONTYPE_LAST_WEAPONTYPE;
else if (entity->GetModelIndex() == MI_PICKUP_BODYARMOUR || entity->GetModelIndex() == MI_PICKUP_BRIBE)
colorId = 12;
colorId = WEAPONTYPE_LAST_WEAPONTYPE + 1;
else if (entity->GetModelIndex() == MI_PICKUP_INFO || entity->GetModelIndex() == MI_PICKUP_KILLFRENZY)
colorId = 13;
colorId = WEAPONTYPE_LAST_WEAPONTYPE + 2;
else if (entity->GetModelIndex() == MI_PICKUP_HEALTH || entity->GetModelIndex() == MI_PICKUP_BONUS)
colorId = 14;
colorId = WEAPONTYPE_LAST_WEAPONTYPE + 3;
else
colorId = FindColourIndexForWeaponMI(entity->GetModelIndex());
colorId = WeaponForModel(entity->GetModelIndex());
assert(colorId >= 0);

@ -85,11 +85,12 @@ public:
static bool IsPickUpPickedUp(int32 pickupId);
static int32 ModelForWeapon(eWeaponType weaponType);
static enum eWeaponType WeaponForModel(int32 model);
static int32 FindColourIndexForWeaponMI(int32 model);
static int32 GetActualPickupIndex(int32 index);
static int32 GetNewUniquePickupIndex(int32 slot);
static void PassTime(uint32 time);
static bool GivePlayerGoodiesWithPickUpMI(int16 modelIndex, int playerIndex);
static bool TestForPickupsInBubble(CVector pos, float range);
static bool TryToMerge_WeaponType(CVector pos, eWeaponType weapon, uint8 type, uint32 quantity, bool unused);
static void Load(uint8 *buf, uint32 size);
static void Save(uint8 *buf, uint32 *size);
@ -103,7 +104,7 @@ public:
};
extern uint16 AmmoForWeapon[20];
extern uint16 AmmoForWeapon_OnStreet[20];
extern uint16 AmmoForWeapon_OnStreet[WEAPONTYPE_TOTALWEAPONS];
extern uint16 CostOfWeapon[20];
enum ePacmanPickupType

@ -2901,13 +2901,7 @@ int8 CRunningScript::ProcessCommands200To299(int32 command)
pVehicle->AutoPilot.m_nCarMission = MISSION_CRUISE;
pVehicle->bEngineOn = true;
pPed->bUsesCollision = false;
#ifdef FIX_BUGS
AnimationId anim = pVehicle->GetDriverAnim();
#else
AnimationId anim = pVehicle->bLowVehicle ? ANIM_CAR_LSIT : ANIM_CAR_SIT;
#endif
pPed->m_pVehicleAnim = CAnimManager::BlendAnimation(pPed->GetClump(), ASSOCGRP_STD, anim, 100.0f);
pPed->StopNonPartialAnims();
pPed->AddInCarAnims(pVehicle, true);
pPed->m_nZoneLevel = CTheZones::GetLevelFromPosition(&pPed->GetPosition());
CWorld::Add(pPed);
ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed);
@ -4080,13 +4074,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command)
pPed->SetPedState(PED_DRIVING);
pVehicle->SetStatus(STATUS_PHYSICS);
pPed->bUsesCollision = false;
#ifdef FIX_BUGS
AnimationId anim = pVehicle->GetDriverAnim();
#else
AnimationId anim = pVehicle->bLowVehicle ? ANIM_CAR_LSIT : ANIM_CAR_SIT;
#endif
pPed->m_pVehicleAnim = CAnimManager::BlendAnimation(pPed->GetClump(), ASSOCGRP_STD, anim, 100.0f);
pPed->StopNonPartialAnims();
pPed->AddInCarAnims(pVehicle, false);
pPed->m_nZoneLevel = CTheZones::GetLevelFromPosition(&pPed->GetPosition());
CWorld::Add(pPed);
ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed);
@ -9753,6 +9741,12 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
return 0;
}
case COMMAND_IS_ANY_PICKUP_AT_COORDS:
{
CollectParameters(&m_nIp, 3);
CVector pos = *(CVector*)&ScriptParams[0];
CRunningScript::UpdateCompareFlag(CPickups::TestForPickupsInBubble(pos, 0.5f));
return 0;
}
case COMMAND_GET_FIRST_PICKUP_COORDS:
case COMMAND_GET_NEXT_PICKUP_COORDS:
case COMMAND_REMOVE_ALL_CHAR_WEAPONS:
@ -9778,6 +9772,15 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
case COMMAND_IS_INT_VAR_EQUAL_TO_CONSTANT:
case COMMAND_IS_INT_LVAR_EQUAL_TO_CONSTANT:
case COMMAND_GET_DEAD_CHAR_PICKUP_COORDS:
{
CollectParameters(&m_nIp, 1);
CPed *pTarget = CPools::GetPedPool()->GetAt(ScriptParams[0]);
CVector pos;
pTarget->CreateDeadPedPickupCoors(&pos.x, &pos.y, &pos.z);
*(CVector*)&ScriptParams[0] = pos;
StoreParameters(&m_nIp, 3);
return 0;
}
case COMMAND_CREATE_PROTECTION_PICKUP:
case COMMAND_IS_CHAR_IN_ANY_BOAT:
case COMMAND_IS_PLAYER_IN_ANY_BOAT:

@ -5536,9 +5536,10 @@ CMenuManager::PrintMap(void)
if (mapPoint.y > fMapCenterY - fMapSize && mapPoint.y < fMapCenterY + fMapSize &&
mapPoint.x > fMapCenterX - fMapSize && mapPoint.x < fMapCenterX + fMapSize) {
// Don't ask me the meanings, I don't know. Found them by trying
float diffX = fMapCenterX - fMapSize, diffY = fMapCenterY - fMapSize;
float x = ((mapPoint.x - diffX) / (fMapSize * 2)) * 4000.0f - 2000.0f;
float y = 2000.0f - ((mapPoint.y - diffY) / (fMapSize * 2)) * 4000.0f;
float x = ((mapPoint.x - diffX) / (fMapSize * 2)) * (WORLD_SIZE_X / MENU_MAP_WIDTH_SCALE) - (WORLD_SIZE_X / 2 + MENU_MAP_LEFT_OFFSET * MENU_MAP_LENGTH_UNIT);
float y = (WORLD_SIZE_Y / 2 - MENU_MAP_TOP_OFFSET * MENU_MAP_LENGTH_UNIT) - ((mapPoint.y - diffY) / (fMapSize * 2)) * (WORLD_SIZE_Y / MENU_MAP_HEIGHT_SCALE);
CRadar::ToggleTargetMarker(x, y);
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
}
@ -5584,7 +5585,8 @@ CMenuManager::PrintMap(void)
if (fMapCenterY + fMapSize < SCREEN_HEIGHT - MENU_Y(60.0f))
fMapCenterY = SCREEN_HEIGHT - MENU_Y(60.0f) - fMapSize;
fMapCenterY = Min(fMapCenterY, fMapSize); // To not show beyond north border
if (fMapCenterY - fMapSize > SCREEN_HEIGHT / 2)
fMapCenterY = SCREEN_HEIGHT / 2 + fMapSize;
bMenuMapActive = false;
@ -5654,9 +5656,7 @@ CMenuManager::ConstructStatLine(int rowIdx)
STAT_LINE("PL_STAT", nil, false, nil);
int percentCompleted = (CStats::TotalProgressInGame == 0 ? 0 :
CStats::ProgressMade * 100.0f / (CGame::nastyGame ? CStats::TotalProgressInGame : CStats::TotalProgressInGame - 1));
percentCompleted = Min(percentCompleted, 100);
int percentCompleted = CStats::GetPercentageProgress();
STAT_LINE("PER_COM", &percentCompleted, false, nil);
STAT_LINE("NMISON", &CStats::MissionsGiven, false, nil);

@ -142,6 +142,7 @@ CPlayerInfo::Clear(void)
m_bFastReload = false;
m_bGetOutOfJailFree = false;
m_bGetOutOfHospitalFree = false;
m_bDriveByAllowed = true;
m_nPreviousTimeRewardedForExplosion = 0;
m_nExplosionsSinceLastReward = 0;
}

@ -54,6 +54,7 @@ public:
bool m_bFastReload;
bool m_bGetOutOfJailFree;
bool m_bGetOutOfHospitalFree;
bool m_bDriveByAllowed;
char m_aSkinName[32];
RwTexture *m_pSkinTexture;

@ -87,12 +87,11 @@ static_assert(RADAR_TILE_SIZE == (RADAR_SIZE_Y / RADAR_NUM_TILES), "CRadar: not
CRGBA CRadar::ArrowBlipColour1;
CRGBA CRadar::ArrowBlipColour2;
uint16 CRadar::MapLegendCounter;
uint16 CRadar::MapLegendList[NUM_MAP_LEGENDS];
int16 CRadar::MapLegendList[NUM_MAP_LEGENDS];
int CRadar::TargetMarkerId = -1;
CVector CRadar::TargetMarkerPos;
#endif
// taken from VC
float CRadar::cachedCos;
float CRadar::cachedSin;
@ -273,12 +272,9 @@ void CRadar::ClearBlip(int32 i)
if (index != -1) {
SetRadarMarkerState(index, false);
ms_RadarTrace[index].m_bInUse = false;
#ifndef MENU_MAP
// Ssshhh
ms_RadarTrace[index].m_eBlipType = BLIP_NONE;
ms_RadarTrace[index].m_eBlipDisplay = BLIP_DISPLAY_NEITHER;
ms_RadarTrace[index].m_eRadarSprite = RADAR_SPRITE_NONE;
#endif
}
}
@ -481,11 +477,6 @@ void CRadar::DrawBlips()
CEntity *blipEntity = nil;
for(int blipId = 0; blipId < NUMRADARBLIPS; blipId++) {
#ifdef MENU_MAP
// A little hack to reuse cleared blips in menu map. hehe
if (!CMenuManager::bMenuMapActive || ms_RadarTrace[blipId].m_eBlipType == BLIP_CAR ||
ms_RadarTrace[blipId].m_eBlipType == BLIP_CHAR || ms_RadarTrace[blipId].m_eBlipType == BLIP_OBJECT)
#endif
if (!ms_RadarTrace[blipId].m_bInUse)
continue;
@ -1338,9 +1329,8 @@ void CRadar::TransformRadarPointToScreenSpace(CVector2D &out, const CVector2D &i
{
#ifdef MENU_MAP
if (CMenuManager::bMenuMapActive) {
// fMapSize is actually half map size. Radar range is 1000, so if x is -2000, in.x + 2.0f is 0.
out.x = (CMenuManager::fMapCenterX - CMenuManager::fMapSize) + (in.x + 2.0f) * CMenuManager::fMapSize * 2.0f / 4.0f;
out.y = (CMenuManager::fMapCenterY - CMenuManager::fMapSize) + (2.0f - in.y) * CMenuManager::fMapSize * 2.0f / 4.0f;
out.x = (CMenuManager::fMapCenterX - CMenuManager::fMapSize) + (MENU_MAP_LENGTH / 2 + MENU_MAP_LEFT_OFFSET + in.x) * CMenuManager::fMapSize * MENU_MAP_WIDTH_SCALE * 2.0f / MENU_MAP_LENGTH;
out.y = (CMenuManager::fMapCenterY - CMenuManager::fMapSize) + (MENU_MAP_LENGTH / 2 - MENU_MAP_TOP_OFFSET - in.y) * CMenuManager::fMapSize * MENU_MAP_HEIGHT_SCALE * 2.0f / MENU_MAP_LENGTH;
} else
#endif
{
@ -1428,7 +1418,7 @@ CRadar::InitFrontEndMap()
CalculateCachedSinCos();
vec2DRadarOrigin.x = 0.0f;
vec2DRadarOrigin.y = 0.0f;
m_radarRange = 1000.0f; // doesn't mean anything, just affects the calculation in TransformRadarPointToScreenSpace
m_radarRange = MENU_MAP_LENGTH_UNIT; // just affects the multiplier in TransformRadarPointToScreenSpace
for (int i = 0; i < NUM_MAP_LEGENDS; i++) {
MapLegendList[i] = RADAR_SPRITE_NONE;
}

@ -1,6 +1,13 @@
#pragma once
#include "Sprite2d.h"
#define MENU_MAP_LENGTH_UNIT 1190.0f // in game unit
#define MENU_MAP_WIDTH_SCALE 1.112f // in game unit (originally 1.112494151260504f)
#define MENU_MAP_HEIGHT_SCALE 1.119f // in game unit (originally 1.118714268907563f)
#define MENU_MAP_TOP_OFFSET 0.28f // in length unit defined above - ~333 game unit
#define MENU_MAP_LEFT_OFFSET 0.185f // in length unit defined above - ~220 game unit
#define MENU_MAP_LENGTH (4000.f / MENU_MAP_LENGTH_UNIT)
enum eBlipType
{
BLIP_NONE,
@ -111,7 +118,7 @@ public:
#define NUM_MAP_LEGENDS 75
static CRGBA ArrowBlipColour1;
static CRGBA ArrowBlipColour2;
static uint16 MapLegendList[NUM_MAP_LEGENDS];
static int16 MapLegendList[NUM_MAP_LEGENDS];
static uint16 MapLegendCounter;
static int TargetMarkerId;
static CVector TargetMarkerPos;

@ -249,6 +249,14 @@ int32 CStats::FindCriminalRatingNumber()
return rating;
}
float CStats::GetPercentageProgress()
{
float percentCompleted = (CStats::TotalProgressInGame == 0 ? 0 :
CStats::ProgressMade * 100.0f / (CGame::nastyGame ? CStats::TotalProgressInGame : CStats::TotalProgressInGame - 1.0f));
return Min(percentCompleted, 100.0f);
}
void CStats::SaveStats(uint8 *buf, uint32 *size)
{
CheckPointReachedSuccessfully();

@ -90,4 +90,5 @@ public:
static int32 FindCriminalRatingNumber();
static void SaveStats(uint8 *buf, uint32 *size);
static void LoadStats(uint8 *buf, uint32 size);
static float GetPercentageProgress();
};

@ -340,21 +340,6 @@ CWorld::ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColP
if(e->IsPed()) {
if(e->bUsesCollision || deadPeds && ((CPed *)e)->m_nPedState == PED_DEAD) {
colmodel = ((CPedModelInfo *)CModelInfo::GetModelInfo(e->GetModelIndex()))->AnimatePedColModelSkinned(e->GetClump());
/* this should all be gone, right?
if(((CPed *)e)->UseGroundColModel())
colmodel = &CTempColModels::ms_colModelPedGroundHit;
else
#ifdef ANIMATE_PED_COL_MODEL
colmodel = CPedModelInfo::AnimatePedColModel(
((CPedModelInfo *)CModelInfo::GetModelInfo(e->GetModelIndex()))
->GetHitColModel(),
RpClumpGetFrame(e->GetClump()));
#else
colmodel =
((CPedModelInfo *)CModelInfo::GetModelInfo(e->GetModelIndex()))
->GetHitColModel();
#endif
*/
} else
colmodel = nil;

@ -400,22 +400,6 @@ CEntity::PreRender(void)
GetMatrix().UpdateRW();
UpdateRwFrame();
}
}else if(IsPickupModel(GetModelIndex())){
if(((CObject*)this)->bIsPickup){
CPickups::DoPickUpEffects(this);
GetMatrix().UpdateRW();
UpdateRwFrame();
}else if(GetModelIndex() == MI_GRENADE){
CMotionBlurStreaks::RegisterStreak((uintptr)this,
100, 100, 100,
GetPosition() - 0.07f*TheCamera.GetRight(),
GetPosition() + 0.07f*TheCamera.GetRight());
}else if(GetModelIndex() == MI_MOLOTOV){
CMotionBlurStreaks::RegisterStreak((uintptr)this,
0, 100, 0,
GetPosition() - 0.07f*TheCamera.GetRight(),
GetPosition() + 0.07f*TheCamera.GetRight());
}
}else if(GetModelIndex() == MI_MISSILE){
CVector pos = GetPosition();
float flicker = (CGeneral::GetRandomNumber() & 0xF)/(float)0x10;
@ -437,7 +421,22 @@ CEntity::PreRender(void)
CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
}else if(IsGlass(GetModelIndex())){
if(!((CSimpleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()))->m_isArtistGlass)
PreRenderForGlassWindow();
}else if (((CObject*)this)->bIsPickup) {
CPickups::DoPickUpEffects(this);
GetMatrix().UpdateRW();
UpdateRwFrame();
} else if (GetModelIndex() == MI_GRENADE) {
CMotionBlurStreaks::RegisterStreak((uintptr)this,
100, 100, 100,
GetPosition() - 0.07f * TheCamera.GetRight(),
GetPosition() + 0.07f * TheCamera.GetRight());
} else if (GetModelIndex() == MI_MOLOTOV) {
CMotionBlurStreaks::RegisterStreak((uintptr)this,
0, 100, 0,
GetPosition() - 0.07f * TheCamera.GetRight(),
GetPosition() + 0.07f * TheCamera.GetRight());
}
// fall through
case ENTITY_TYPE_DUMMY:

@ -395,7 +395,9 @@ enum
MI_AK47 = 276,
MI_SHOTGUN = 279,
MI_M16 = 280,
MI_TEC9 = 281,
MI_UZI = 282,
MI_SILENCEDINGRAM = 283,
MI_MP5 = 284,
MI_SNIPER = 285,
MI_ROCKETLAUNCHER = 287,
@ -511,29 +513,6 @@ IsBannerModel(int16 id)
id == MI_ITALYBANNER1 ||
id == MI_CHINALANTERN;
}
inline bool
IsPickupModel(int16 id)
{
return id == MI_GRENADE ||
id == MI_AK47 ||
id == MI_BASEBALL_BAT ||
id == MI_COLT ||
id == MI_MOLOTOV ||
id == MI_ROCKETLAUNCHER ||
id == MI_SHOTGUN ||
id == MI_SNIPER ||
id == MI_UZI ||
id == MI_M16 ||
id == MI_FLAMETHROWER ||
id == MI_PICKUP_ADRENALINE ||
id == MI_PICKUP_BODYARMOUR ||
id == MI_PICKUP_INFO ||
id == MI_PICKUP_HEALTH ||
id == MI_PICKUP_BONUS ||
id == MI_PICKUP_BRIBE ||
id == MI_PICKUP_KILLFRENZY ||
id == MI_PICKUP_CAMERA;
}
inline bool
IsPolicePedModel(int16 id)

@ -200,7 +200,7 @@ CCivilianPed::ProcessControl(void)
if (DyingOrDead())
return;
GetWeapon()->Update(m_audioEntityId);
GetWeapon()->Update(m_audioEntityId, nil);
switch (m_nPedState) {
case PED_WANDER_RANGE:
case PED_WANDER_PATH:

@ -589,7 +589,7 @@ CCopPed::ProcessControl(void)
ArrestPlayer();
return;
}
GetWeapon()->Update(m_audioEntityId);
GetWeapon()->Update(m_audioEntityId, nil);
if (m_moved.Magnitude() > 0.0f)
Avoid();

@ -49,7 +49,7 @@ CEmergencyPed::ProcessControl(void)
return;
if(!DyingOrDead()) {
GetWeapon()->Update(m_audioEntityId);
GetWeapon()->Update(m_audioEntityId, nil);
if (IsPedInControl() && m_moved.Magnitude() > 0.0f)
Avoid();

@ -67,6 +67,9 @@ uint16 gnNumTempPedList;
CColPoint aTempPedColPts[MAX_COLLISION_POINTS];
// TODO(Miami)
#define AUDIO_NOT_READY
// Corresponds to ped sounds (from SOUND_PED_DEATH to SOUND_PED_TAXI_CALL)
PedAudioData CommentWaitTime[39] = {
{500, 800, 500, 2},
@ -645,6 +648,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
m_maxWeaponTypeAllowed = WEAPONTYPE_UNARMED;
m_currentWeapon = WEAPONTYPE_UNARMED;
m_storedWeapon = WEAPONTYPE_UNIDENTIFIED;
m_delayedWeapon = WEAPONTYPE_UNIDENTIFIED;
for(int i = 0; i < TOTAL_WEAPON_SLOTS; i++) {
CWeapon &weapon = GetWeapon(i);
@ -656,7 +660,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
}
m_lastFightMove = FIGHTMOVE_NULL;
GiveWeapon(WEAPONTYPE_UNARMED, 0);
GiveWeapon(WEAPONTYPE_UNARMED, 0, true);
m_wepAccuracy = 60;
m_lastWepDam = -1;
m_collPoly.valid = false;
@ -1179,7 +1183,7 @@ CPed::FinishedReloadCB(CAnimBlendAssociation *reloadAssoc, void *arg)
crouchFireAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), ANIM_WEAPON_CROUCHFIRE);
}
if (!!weapon->m_bReload && reloadAssoc) {
if (reloadAssoc->animId == ANIM_WEAPON_CROUCHRELOAD && !crouchFireAssoc) {
if (reloadAssoc->animId == GetCrouchReloadAnim(weapon) && !crouchFireAssoc) {
CAnimBlendAssociation *crouchAssoc = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_WEAPON_CROUCH, 8.0f);
crouchAssoc->SetCurrentTime(crouchAssoc->hierarchy->totalLength);
crouchAssoc->flags &= ~ASSOC_RUNNING;
@ -1212,7 +1216,7 @@ CPed::FinishedAttackCB(CAnimBlendAssociation *attackAssoc, void *arg)
if (ped->m_nPedState != PED_ATTACK) {
if (ped->bIsDucking && ped->IsPedInControl()) {
if (currentWeapon->m_bReload) {
reloadAnimAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), ANIM_WEAPON_CROUCHRELOAD);
reloadAnimAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), GetCrouchReloadAnim(currentWeapon));
}
if (currentWeapon->m_bCrouchFire && attackAssoc) {
if (attackAssoc->animId == ANIM_WEAPON_CROUCHFIRE && !reloadAnimAssoc) {
@ -1238,7 +1242,7 @@ CPed::FinishedAttackCB(CAnimBlendAssociation *attackAssoc, void *arg)
if (ped->bIsDucking && ped->bCrouchWhenShooting) {
if (currentWeapon->m_bReload) {
reloadAnimAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), ANIM_WEAPON_CROUCHRELOAD);
reloadAnimAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), GetCrouchReloadAnim(currentWeapon));
}
if (currentWeapon->m_bCrouchFire && attackAssoc) {
if (attackAssoc->animId == ANIM_WEAPON_CROUCHFIRE && !reloadAnimAssoc) {
@ -1302,7 +1306,7 @@ CPed::FinishedAttackCB(CAnimBlendAssociation *attackAssoc, void *arg)
}
}
// --MIAMI: Done
// --MIAMI: Done except melee weapons
void
CPed::Attack(void)
{
@ -1354,11 +1358,11 @@ CPed::Attack(void)
}
if (ourWeapon->m_bReload) {
reloadAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_RELOAD);
reloadAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetReloadAnim(ourWeapon));
}
if (!!ourWeapon->m_bReload && !reloadAnimAssoc) {
reloadAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHRELOAD);
reloadAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchReloadAnim(ourWeapon));
}
if ( reloadAnimAssoc && reloadAnimAssoc->IsRunning() ) {
@ -1518,14 +1522,22 @@ CPed::Attack(void)
case ASSOCGRP_UNARMED:
if (weaponAnimAssoc->animId == ANIM_FIGHT_PPUNCH || // TODO(Miami): Remove after fighting done
weaponAnimAssoc->animId == ANIM_MELEE_ATTACK || weaponAnimAssoc->animId == ANIM_MELEE_ATTACK_START) {
#ifdef AUDIO_NOT_READY
DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_PUNCH_39, 0.0f);
#else
DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_PUNCH_39, (damagerType | (ourWeaponType << 8)));
#endif
}
break;
case ASSOCGRP_KNIFE:
case ASSOCGRP_BASEBALLBAT:
case ASSOCGRP_GOLFCLUB:
case ASSOCGRP_CHAINSAW:
#ifdef AUDIO_NOT_READY
DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, 1.0f);
#else
DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, (damagerType | (ourWeaponType << 8)));
#endif
break;
default:
break;
@ -1587,12 +1599,12 @@ CPed::Attack(void)
if (bIsDucking) {
newReloadAssoc = CAnimManager::BlendAnimation(
GetClump(), ourWeapon->m_AnimToPlay,
ANIM_WEAPON_CROUCHRELOAD,
GetCrouchReloadAnim(ourWeapon),
8.0f);
} else {
newReloadAssoc = CAnimManager::BlendAnimation(
GetClump(), ourWeapon->m_AnimToPlay,
ANIM_WEAPON_RELOAD,
GetReloadAnim(ourWeapon),
8.0f);
}
newReloadAssoc->SetFinishCallback(FinishedReloadCB, this);
@ -1602,7 +1614,26 @@ CPed::Attack(void)
bIsAttacking = false;
bIsPointingGunAt = false;
m_shootTimer = CTimer::GetTimeInMilliseconds();
#ifdef AUDIO_NOT_READY
switch (ourWeaponType) {
case WEAPONTYPE_UZI:
case WEAPONTYPE_TEC9:
case WEAPONTYPE_SILENCED_INGRAM:
case WEAPONTYPE_MP5:
DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_UZI_BULLET_ECHO, 0.0f);
break;
case WEAPONTYPE_AK47:
DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, 0.0f);
break;
case WEAPONTYPE_M16:
DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_M16_BULLET_ECHO, 0.0f);
break;
default:
break;
}
#else
DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, GetWeapon()->m_eWeaponType);
#endif
return;
}
}
@ -1647,10 +1678,28 @@ CPed::Attack(void)
ClearAimFlag();
// Echoes of bullets, at the end of the attack. (Bug: doesn't play while reloading)
if (weaponAnimAssoc->currentTime - weaponAnimAssoc->timeStep < ourWeapon->m_fAnimLoopEnd) {
if (weaponAnimAssoc->currentTime - weaponAnimAssoc->timeStep < animLoopEnd) {
// What?! Weapon id as volume??
#ifdef AUDIO_NOT_READY
switch (ourWeaponType) {
case WEAPONTYPE_UZI:
case WEAPONTYPE_TEC9:
case WEAPONTYPE_SILENCED_INGRAM:
case WEAPONTYPE_MP5:
DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_UZI_BULLET_ECHO, 0.0f);
break;
case WEAPONTYPE_AK47:
DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, 0.0f);
break;
case WEAPONTYPE_M16:
DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_M16_BULLET_ECHO, 0.0f);
break;
default:
break;
}
#else
DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, GetWeapon()->m_eWeaponType);
#endif
}
// Fun fact: removing this part leds to reloading flamethrower
@ -2133,7 +2182,7 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
case ANIM_VAN_GETIN:
#ifdef VC_PED_PORTS
multExtractedFromAnim = true;
zBlend = Max(m_pVehicleAnim->currentTime / m_pVehicleAnim->hierarchy->totalLength - 0.3f, 0.0f) / (1.0f - 0.3f);
zBlend = Max(m_pVehicleAnim->GetProgress() - 0.3f, 0.0f) / (1.0f - 0.3f);
// fall through
#endif
case ANIM_CAR_QJACKED:
@ -2144,7 +2193,7 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
#ifdef VC_PED_PORTS
if (!multExtractedFromAnim) {
multExtractedFromAnim = true;
zBlend = Max(m_pVehicleAnim->currentTime / m_pVehicleAnim->hierarchy->totalLength - 0.5f, 0.0f) / (1.0f - 0.5f);
zBlend = Max(m_pVehicleAnim->GetProgress() - 0.5f, 0.0f) / (1.0f - 0.5f);
}
// fall through
#endif
@ -2152,14 +2201,14 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
case ANIM_CAR_CRAWLOUT_RHS2:
case ANIM_VAN_GETOUT_L:
case ANIM_VAN_GETOUT:
seatPosMult = m_pVehicleAnim->currentTime / m_pVehicleAnim->hierarchy->totalLength;
seatPosMult = m_pVehicleAnim->GetProgress();
break;
case ANIM_CAR_GETIN_RHS:
case ANIM_CAR_GETIN_LHS:
#ifdef VC_PED_PORTS
if (veh && veh->IsCar() && veh->bIsBus) {
multExtractedFromAnimBus = true;
zBlend = Min(m_pVehicleAnim->currentTime / m_pVehicleAnim->hierarchy->totalLength, 0.5f) / 0.5f;
zBlend = Min(m_pVehicleAnim->GetProgress(), 0.5f) / 0.5f;
}
// fall through
#endif
@ -4520,6 +4569,9 @@ CPed::SetGetUp(void)
}
if (m_nPedState != PED_GETUP) {
SetStoredState();
if (m_nPedState == PED_FOLLOW_PATH)
ClearFollowPath();
m_nPedState = PED_GETUP;
}
@ -5119,7 +5171,7 @@ CPed::SetAttack(CEntity *victim)
return;
if (curWeapon->m_bReload &&
(RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_RELOAD) || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHRELOAD))) {
(RpAnimBlendClumpGetAssociation(GetClump(), GetReloadAnim(curWeapon)) || RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchReloadAnim(curWeapon)))) {
if (!IsPlayer() || m_nPedState != PED_ATTACK || ((CPlayerPed*)this)->m_bHaveTargetSelected)
bIsAttacking = false;
else
@ -5511,13 +5563,13 @@ CPed::FightStrike(CVector &touchedNodePos)
for (int j = 0; j < hisCol->numSpheres; j++) {
attackDistance = hisCol->spheres[j].center;
attackDistance -= touchedNodePos;
CColSphere *ourPieces = hisCol->spheres;
float maxDistanceToBeat = ourPieces[j].radius + tFightMoves[m_lastFightMove].strikeRadius;
CColSphere *hisPieces = hisCol->spheres;
float maxDistanceToBeat = hisPieces[j].radius + tFightMoves[m_lastFightMove].strikeRadius;
// We can beat him too
if (sq(maxDistanceToBeat) > attackDistance.MagnitudeSqr()) {
pedFound = true;
closestPedPiece = (ePedPieceTypes) ourPieces[j].piece;
closestPedPiece = (ePedPieceTypes) hisPieces[j].piece;
break;
}
}
@ -6324,28 +6376,22 @@ CPed::CreateDeadPedMoney(void)
}
void
CPed::CreateDeadPedWeaponPickups(void)
CPed::CreateDeadPedPickupCoors(float *x, float *y, float *z)
{
bool found = false;
float angleToPed;
CVector pickupPos;
if (bInVehicle)
return;
for(int i = 0; i < TOTAL_WEAPON_SLOTS; i++) {
eWeaponType weapon = GetWeapon(i).m_eWeaponType;
int weaponAmmo = GetWeapon(i).m_nAmmoTotal;
if (weapon == WEAPONTYPE_UNARMED || weapon == WEAPONTYPE_DETONATOR || (weaponAmmo == 0 && !GetWeapon(i).IsTypeMelee()))
continue;
#define NUMBER_OF_ATTEMPTS 32
for (int i = 0; i < NUMBER_OF_ATTEMPTS; i++) {
angleToPed = i * 1.75f;
pickupPos = GetPosition();
pickupPos.x += 1.5f * Sin(angleToPed);
pickupPos.y += 1.5f * Cos(angleToPed);
pickupPos.x = 1.5f * Sin((CGeneral::GetRandomNumber() % 256) * PI / 128) + GetPosition().x;
pickupPos.y = 1.5f * Cos((CGeneral::GetRandomNumber() % 256) * PI / 128) + GetPosition().y;
pickupPos.z = CWorld::FindGroundZFor3DCoord(pickupPos.x, pickupPos.y, pickupPos.z, &found) + 0.5f;
if (!found)
continue;
CVector pedPos = GetPosition();
pedPos.z += 0.3f;
@ -6353,21 +6399,53 @@ CPed::CreateDeadPedWeaponPickups(void)
float distance = pedToPickup.Magnitude();
// outer edge of pickup
distance = (distance + 0.3f) / distance;
distance = (distance + 0.4f) / distance;
CVector pickupPos2 = pedPos;
pickupPos2 += distance * pedToPickup;
// pickup must be on ground and line to its edge must be clear
if (!found || CWorld::GetIsLineOfSightClear(pickupPos2, pedPos, true, false, false, false, false, false, false)) {
// otherwise try another position (but disregard second check apparently)
angleToPed += 3.14f;
pickupPos = GetPosition();
pickupPos.x += 1.5f * Sin(angleToPed);
pickupPos.y += 1.5f * Cos(angleToPed);
pickupPos.z = CWorld::FindGroundZFor3DCoord(pickupPos.x, pickupPos.y, pickupPos.z, &found) + 0.5f;
if ((pickupPos - FindPlayerCoors()).Magnitude2D() > 2.0f || i > NUMBER_OF_ATTEMPTS / 2) {
if (i > NUMBER_OF_ATTEMPTS / 2 || !CPickups::TestForPickupsInBubble(pickupPos, 1.3f)) {
if (CWorld::GetIsLineOfSightClear(pickupPos2, pedPos,
true, i < NUMBER_OF_ATTEMPTS / 2, false, i < NUMBER_OF_ATTEMPTS / 2, false, false, false)) {
if (i > NUMBER_OF_ATTEMPTS / 2 || !CWorld::TestSphereAgainstWorld(pickupPos, 1.2f, nil, false, true, false, false, false, false)) {
*x = pickupPos.x;
*y = pickupPos.y;
*z = pickupPos.z;
return;
}
}
}
}
}
*x = GetPosition().x;
*y = GetPosition().y;
*z = GetPosition().z + 0.4f;
#undef NUMBER_OF_ATTEMPTS
}
void
CPed::CreateDeadPedWeaponPickups(void)
{
CVector pickupPos;
if (bInVehicle)
return;
for(int i = 0; i < TOTAL_WEAPON_SLOTS; i++) {
eWeaponType weapon = GetWeapon(i).m_eWeaponType;
int weaponAmmo = GetWeapon(i).m_nAmmoTotal;
if (weapon == WEAPONTYPE_UNARMED || weapon == WEAPONTYPE_DETONATOR || (weaponAmmo == 0 && !GetWeapon(i).IsTypeMelee()))
continue;
int quantity = Min(weaponAmmo, AmmoForWeapon_OnStreet[weapon] / 2);
CreateDeadPedPickupCoors(&pickupPos.x, &pickupPos.y, &pickupPos.z);
if (!CPickups::TryToMerge_WeaponType(pickupPos, weapon, PICKUP_ONCE_TIMEOUT, quantity, false)) {
CPickups::GenerateNewOne_WeaponType(pickupPos, weapon, PICKUP_ONCE_TIMEOUT, Min(weaponAmmo, quantity));
}
if (found)
CPickups::GenerateNewOne_WeaponType(pickupPos, weapon, PICKUP_ONCE_TIMEOUT, Min(weaponAmmo, AmmoForWeapon_OnStreet[weapon]));
}
ClearWeapons();
}
@ -8945,7 +9023,11 @@ CPed::InvestigateEvent(void)
bool
CPed::IsPedDoingDriveByShooting(void)
{
#ifdef FIX_BUGS
if (FindPlayerPed() == this && CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_nWeaponSlot == 5) {
#else
if (FindPlayerPed() == this && GetWeapon()->m_eWeaponType == WEAPONTYPE_UZI) {
#endif
if (TheCamera.Cams[TheCamera.ActiveCam].LookingLeft || TheCamera.Cams[TheCamera.ActiveCam].LookingRight)
return true;
}
@ -9982,11 +10064,8 @@ CPed::ProcessControl(void)
if (m_nPedState == PED_FOLLOW_PATH) {
if (DotProduct(m_vecDamageNormal, GetForward()) < -0.866f && CanPedJumpThis(collidingEnt, &m_vecDamageNormal)) {
SetJump();
// Moved break into here, for compatibility with III
break;
}
// break;
break;
}
#endif
if (m_pedInObjective &&
@ -10957,15 +11036,13 @@ CPed::ProcessControl(void)
return;
}
if (m_pMyVehicle->pDriver != this || m_pMyVehicle->IsBoat()) {
if (m_pMyVehicle->pDriver != this) {
LookForSexyPeds();
LookForSexyCars();
break;
}
if (m_pMyVehicle->m_vehType == VEHICLE_TYPE_BIKE || !m_pMyVehicle->pDriver->IsPlayer()) {
break;
}
// TODO(Miami): Start KILL_CHAR_ON_BOAT objective
CPad* pad = CPad::GetPad(0);
@ -10995,12 +11072,24 @@ CPed::ProcessControl(void)
}
}
#endif
// TODO(Miami): This part moved to DriveVehicle in VC
float steerAngle = m_pMyVehicle->m_fSteerAngle;
CAnimBlendAssociation *lDriveAssoc;
CAnimBlendAssociation *rDriveAssoc;
CAnimBlendAssociation *lbAssoc;
CAnimBlendAssociation *sitAssoc;
if (m_pMyVehicle->bLowVehicle) {
if (m_pMyVehicle->IsBoat() && !(m_pMyVehicle->pHandling->Flags & HANDLING_SIT_IN_BOAT)) {
sitAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_BOAT);
if (!sitAssoc || sitAssoc->blendAmount < 1.0f) {
break;
}
lDriveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_BOAT_L);
rDriveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_BOAT_R);
lbAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BOAT_LB);
} else if (m_pMyVehicle->bLowVehicle) {
sitAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_LSIT);
if (!sitAssoc || sitAssoc->blendAmount < 1.0f) {
@ -11020,18 +11109,21 @@ CPed::ProcessControl(void)
lDriveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_L);
rDriveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_R);
lbAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_LB);
}
if (lbAssoc &&
TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON
&& TheCamera.Cams[TheCamera.ActiveCam].DirectionWasLooking == LOOKING_LEFT) {
lbAssoc->blendDelta = -1000.0f;
}
}
CAnimBlendAssociation *driveByAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVEBY_L);
if (!driveByAssoc)
driveByAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVEBY_R);
if (!driveByAssoc)
driveByAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVEBY_LOW_L);
if (!driveByAssoc)
driveByAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVEBY_LOW_R);
if (m_pMyVehicle->bLowVehicle || m_pMyVehicle->m_fGasPedal >= 0.0f || driveByAssoc) {
if (steerAngle == 0.0f || driveByAssoc) {
@ -11046,6 +11138,8 @@ CPed::ProcessControl(void)
if (rDriveAssoc)
rDriveAssoc->blendAmount = clamp(steerAngle * -100.0f / 61.0f, 0.0f, 1.0f);
else if (m_pMyVehicle->IsBoat() && !(m_pMyVehicle->pHandling->Flags & HANDLING_SIT_IN_BOAT))
CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_DRIVE_BOAT_R);
else if (m_pMyVehicle->bLowVehicle)
CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_DRIVE_LOW_R);
else
@ -11057,6 +11151,8 @@ CPed::ProcessControl(void)
if (lDriveAssoc)
lDriveAssoc->blendAmount = clamp(steerAngle * 100.0f / 61.0f, 0.0f, 1.0f);
else if (m_pMyVehicle->IsBoat() && !(m_pMyVehicle->pHandling->Flags & HANDLING_SIT_IN_BOAT))
CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_DRIVE_BOAT_L);
else if (m_pMyVehicle->bLowVehicle)
CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_DRIVE_LOW_L);
else
@ -11069,10 +11165,18 @@ CPed::ProcessControl(void)
if ((TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::MODE_1STPERSON
|| TheCamera.Cams[TheCamera.ActiveCam].DirectionWasLooking != LOOKING_LEFT)
&& (!lbAssoc || lbAssoc->blendAmount < 1.0f)) {
&& (!lbAssoc || lbAssoc->blendAmount < 1.0f && lbAssoc->blendDelta <= 0.0f)) {
if(m_pMyVehicle->IsBoat() && !(m_pMyVehicle->pHandling->Flags & HANDLING_SIT_IN_BOAT))
CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_BOAT_LB, 4.0f);
else
CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_LB, 4.0f);
}
}
// TODO(Miami): This part belongs to DriveVehicle
if (!m_pMyVehicle)
return;
break;
}
case PED_DIE:
@ -11124,7 +11228,8 @@ CPed::ProcessControl(void)
}
m_pCurrentPhysSurface = nil;
}
}
} else
ServiceTalking();
}
void
@ -11145,11 +11250,27 @@ CPed::SetInTheAir(void)
}
// --MIAMI: Done
void
CPed::RestoreHeadPosition(void)
{
bool canUseMyBody = false;
if (m_nPedState != PED_DRIVING && m_nPedState != PED_DRAG_FROM_CAR && !bIsDucking) {
if (m_animGroup != ASSOCGRP_SEXYWOMAN && m_animGroup != ASSOCGRP_WOMAN)
canUseMyBody = true;
}
if (!canUseMyBody)
m_pedIK.m_flags |= CPedIK::LOOKAROUND_HEAD_ONLY;
if (m_pedIK.RestoreLookAt()) {
bIsRestoringLook = false;
canUseMyBody = false;
if (m_nPedState != PED_DRIVING && m_nPedState != PED_DRAG_FROM_CAR && !bIsDucking) {
if (m_animGroup != ASSOCGRP_SEXYWOMAN && m_animGroup != ASSOCGRP_WOMAN)
canUseMyBody = true;
}
if(canUseMyBody)
m_pedIK.m_flags &= ~CPedIK::LOOKAROUND_HEAD_ONLY;
}
}
@ -12234,19 +12355,7 @@ CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg)
ped->SetObjective(OBJECTIVE_NONE);
}
if (veh->pDriver == ped) {
if (veh->bLowVehicle) {
ped->m_pVehicleAnim = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_LSIT, 100.0f);
} else {
ped->m_pVehicleAnim = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_SIT, 100.0f);
}
} else if (veh->bLowVehicle) {
ped->m_pVehicleAnim = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_SITPLO, 100.0f);
} else {
ped->m_pVehicleAnim = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_SITP, 100.0f);
}
ped->StopNonPartialAnims();
ped->AddInCarAnims(veh, veh->pDriver == ped);
if (veh->bIsBus)
ped->bRenderPedInCar = false;
@ -12651,11 +12760,11 @@ CPed::ReplaceWeaponWhenExitingVehicle(void)
}
}
// --MIAMI: Add driveby check, enumarate weapon slots
// --MIAMI: Done
inline void
CPed::RemoveWeaponWhenEnteringVehicle(void)
{
if (IsPlayer() && GetWeapon(5).m_eWeaponType && GetWeapon(5).m_nAmmoTotal > 0) {
if (IsPlayer() && HasWeaponSlot(5) && GetWeapon(5).m_nAmmoTotal > 0 && ((CPlayerPed*)this)->GetPlayerInfoForThisPlayerPed()->m_bDriveByAllowed) {
if (m_storedWeapon == WEAPONTYPE_UNIDENTIFIED)
m_storedWeapon = GetWeapon()->m_eWeaponType;
SetCurrentWeapon(GetWeapon(5).m_eWeaponType);
@ -14190,7 +14299,7 @@ CPed::ProcessObjective(void)
if (reloadAssoc || !m_pedInObjective->IsPedShootable()) {
if (reloadAssoc &&
(!reloadAssoc->IsRunning() || reloadAssoc->currentTime / reloadAssoc->hierarchy->totalLength > 0.8f)) {
(!reloadAssoc->IsRunning() || reloadAssoc->GetProgress() > 0.8f)) {
CAnimBlendAssociation *punchAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FIGHT_PPUNCH, 8.0f);
punchAssoc->flags |= ASSOC_DELETEFADEDOUT;
punchAssoc->flags |= ASSOC_FADEOUTWHENDONE;
@ -17529,33 +17638,11 @@ CPed::WarpPedIntoCar(CVehicle *car)
DMAudio.PlayOneShot(car->m_audioEntityId, SOUND_CAR_ENGINE_START, 1.0f);
}
#ifdef VC_PED_PORTS
RpAnimBlendClumpSetBlendDeltas(GetClump(), ASSOC_PARTIAL, -1000.0f);
// VC uses AddInCarAnims but we don't have that
m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, car->GetDriverAnim(), 100.0f);
RemoveWeaponWhenEnteringVehicle();
#else
if (car->IsBoat()) {
#ifndef FIX_BUGS
m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_DRIVE_BOAT, 100.0f);
#else
m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, car->GetDriverAnim(), 100.0f);
#endif
CWeaponInfo *ourWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
RemoveWeaponModel(ourWeapon->m_nModelId);
} else {
// Because we can use Uzi for drive by
AddInCarAnims(car, car->pDriver == this);
RemoveWeaponWhenEnteringVehicle();
if (car->bLowVehicle)
m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_LSIT, 100.0f);
else
m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_SIT, 100.0f);
}
#endif
StopNonPartialAnims();
if (car->bIsBus)
bRenderPedInCar = false;
@ -17837,25 +17924,13 @@ CPed::SetEnterCar_AllClear(CVehicle *car, uint32 doorNode, uint32 doorFlag)
m_vecOffsetSeek = doorOpenPos - GetPosition();
m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 600;
if (car->IsBoat()) {
#ifdef VC_PED_PORTS
// VC checks for handling flag, but we can't do that
if(car->GetModelIndex() == MI_SPEEDER)
if(car->pHandling->Flags & HANDLING_SIT_IN_BOAT)
m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_SIT, 100.0f);
else
m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_DRIVE_BOAT, 100.0f);
PedSetInCarCB(nil, this);
bVehExitWillBeInstant = true;
#else
#ifndef FIX_BUGS
m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_DRIVE_BOAT, 100.0f);
#else
m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, car->GetDriverAnim(), 100.0f);
#endif
m_pVehicleAnim->SetFinishCallback(PedSetInCarCB, this);
#endif
if (IsPlayer())
CWaterLevel::AllocateBoatWakeArray();
} else {
@ -18418,14 +18493,15 @@ CPed::Load(uint8*& buf)
#undef CopyToBuf
#endif
// --MIAMI: Done
void
CPed::GiveDelayedWeapon(eWeaponType weapon, uint32 ammo)
{
m_storedWeapon = weapon;
m_storedWeaponAmmo = ammo;
if (m_storedWeapon != WEAPONTYPE_UNIDENTIFIED) {
int modelId1 = CWeaponInfo::GetWeaponInfo(m_storedWeapon)->m_nModelId;
int modelId2 = CWeaponInfo::GetWeaponInfo(m_storedWeapon)->m_nModel2Id;
m_delayedWeapon = weapon;
m_delayedWeaponAmmo = ammo;
if (m_delayedWeapon != WEAPONTYPE_UNIDENTIFIED) {
int modelId1 = CWeaponInfo::GetWeaponInfo(m_delayedWeapon)->m_nModelId;
int modelId2 = CWeaponInfo::GetWeaponInfo(m_delayedWeapon)->m_nModel2Id;
if (modelId1 != -1)
CStreaming::RequestModel(modelId1, STREAMFLAGS_DEPENDENCY);
if (modelId2 != -1)
@ -18433,18 +18509,19 @@ CPed::GiveDelayedWeapon(eWeaponType weapon, uint32 ammo)
if ((modelId1 == -1 || CStreaming::HasModelLoaded(modelId1))
&& (modelId2 == -1 || CStreaming::HasModelLoaded(modelId2))) {
GiveWeapon(m_storedWeapon, m_storedWeaponAmmo, 1);
m_storedWeapon = WEAPONTYPE_UNIDENTIFIED;
GiveWeapon(m_delayedWeapon, m_delayedWeaponAmmo, true);
m_delayedWeapon = WEAPONTYPE_UNIDENTIFIED;
}
}
}
// --MIAMI: Done
void
CPed::RequestDelayedWeapon()
{
if (m_storedWeapon != WEAPONTYPE_UNIDENTIFIED) {
int modelId1 = CWeaponInfo::GetWeaponInfo(m_storedWeapon)->m_nModelId;
int modelId2 = CWeaponInfo::GetWeaponInfo(m_storedWeapon)->m_nModel2Id;
if (m_delayedWeapon != WEAPONTYPE_UNIDENTIFIED) {
int modelId1 = CWeaponInfo::GetWeaponInfo(m_delayedWeapon)->m_nModelId;
int modelId2 = CWeaponInfo::GetWeaponInfo(m_delayedWeapon)->m_nModel2Id;
if (modelId1 != -1)
CStreaming::RequestModel(modelId1, STREAMFLAGS_DEPENDENCY);
if (modelId2 != -1)
@ -18452,12 +18529,13 @@ CPed::RequestDelayedWeapon()
if ((modelId1 == -1 || CStreaming::HasModelLoaded(modelId1))
&& (modelId2 == -1 || CStreaming::HasModelLoaded(modelId2))) {
GiveWeapon(m_storedWeapon, m_storedWeaponAmmo, 1);
m_storedWeapon = WEAPONTYPE_UNIDENTIFIED;
GiveWeapon(m_delayedWeapon, m_delayedWeaponAmmo, 1);
m_delayedWeapon = WEAPONTYPE_UNIDENTIFIED;
}
}
}
// --MIAMI: Done
void
CPed::ClearFollowPath()
{
@ -18467,3 +18545,43 @@ CPed::ClearFollowPath()
m_nPathNodes = 0;
m_nCurPathNode = 0;
}
// --MIAMI: Done
void
CPed::AddInCarAnims(CVehicle* car, bool isDriver)
{
AnimationId anim;
AssocGroupId group;
if (car->IsBoat()) {
if (car->pHandling->Flags & HANDLING_SIT_IN_BOAT) {
anim = ANIM_CAR_SIT;
} else {
anim = ANIM_DRIVE_BOAT;
}
group = ASSOCGRP_STD;
} else if (car->IsBike()) {
if (isDriver) {
// TODO(Miami): Bikes
} else {
// TODO(Miami): Bikes
}
} else {
if (isDriver) {
if (car->bLowVehicle) {
anim = ANIM_CAR_LSIT;
} else {
anim = ANIM_CAR_SIT;
}
} else {
if (car->bLowVehicle) {
anim = ANIM_CAR_SITPLO;
} else {
anim = ANIM_CAR_SITP;
}
}
group = ASSOCGRP_STD;
}
m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), group, anim, 100.0f);
StopNonPartialAnims();
}

@ -523,7 +523,8 @@ public:
CVector2D *m_wanderRangeBounds; // array with 2 CVector2D (actually unused CRange2D class) - unused
CWeapon m_weapons[TOTAL_WEAPON_SLOTS];
eWeaponType m_storedWeapon;
uint32 m_storedWeaponAmmo;
eWeaponType m_delayedWeapon;
uint32 m_delayedWeaponAmmo;
uint8 m_currentWeapon; // eWeaponType
uint8 m_maxWeaponTypeAllowed; // eWeaponType
uint8 m_wepSkills;
@ -704,7 +705,7 @@ public:
void RemoveWeaponAnims(int, float);
void CreateDeadPedMoney(void);
void CreateDeadPedWeaponPickups(void);
// void CreateDeadPedPickupCoors(float *x, float *y, float *z);
void CreateDeadPedPickupCoors(float *x, float *y, float *z);
void SetAttackTimer(uint32);
void SetBeingDraggedFromCar(CVehicle*, uint32, bool);
void SetRadioStation(void);
@ -775,6 +776,7 @@ public:
void ClearFollowPath();
void GiveDelayedWeapon(eWeaponType weapon, uint32 ammo);
void RequestDelayedWeapon();
void AddInCarAnims(CVehicle* car, bool isDriver);
// Static methods
static CVector GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float offset);
@ -875,7 +877,7 @@ public:
bool Dead(void) { return m_nPedState == PED_DEAD; }
bool Dying(void) { return m_nPedState == PED_DIE; }
bool DyingOrDead(void) { return m_nPedState == PED_DIE || m_nPedState == PED_DEAD; }
bool OnGround(void) { return m_nPedState == PED_FALL || m_nPedState == PED_DIE || m_nPedState == PED_DEAD; }
bool OnGround(void) { return m_nPedState == PED_FALL || m_nPedState == PED_DIE || m_nPedState == PED_DEAD || m_nWaitState == WAITSTATE_SUN_BATHE_IDLE; }
bool Driving(void) { return m_nPedState == PED_DRIVING; }
bool InVehicle(void) { return bInVehicle && m_pMyVehicle; } // True when ped is sitting/standing in vehicle, not in enter/exit state.
@ -891,7 +893,7 @@ public:
void RemoveWeaponWhenEnteringVehicle(void);
bool IsNotInWreckedVehicle();
// My addons. Maybe inlined in VC?
// My names. Inlined in VC
AnimationId GetFireAnimNotDucking(CWeaponInfo* weapon) {
// TODO(Miami): Revert that when weapons got ported
if (weapon->m_AnimToPlay == ASSOCGRP_STD)
@ -928,6 +930,20 @@ public:
else
return ANIM_WEAPON_FIRE;
}
static AnimationId GetCrouchReloadAnim(CWeaponInfo* weapon) {
if (!!weapon->m_bReload)
return ANIM_WEAPON_CROUCHRELOAD;
else
return (AnimationId)0;
}
static AnimationId GetReloadAnim(CWeaponInfo* weapon) {
if (!!weapon->m_bReload)
return ANIM_WEAPON_RELOAD;
else
return (AnimationId)0;
}
// --
// My additions, because there were many, many instances of that.

@ -451,7 +451,7 @@ CPlayerPed::SetRealMoveAnim(void)
} else if (curSprintAssoc->blendDelta >= 0.0f || curSprintAssoc->blendAmount >= 0.8f) {
if (m_fMoveSpeed < 0.4f) {
AnimationId runStopAnim;
if (curSprintAssoc->currentTime / curSprintAssoc->hierarchy->totalLength < 0.5) // double
if (curSprintAssoc->GetProgress() < 0.5) // double
runStopAnim = ANIM_RUN_STOP;
else
runStopAnim = ANIM_RUN_STOP_R;
@ -638,7 +638,7 @@ CPlayerPed::PlayerControlSniper(CPad *padUsed)
firePos = GetMatrix() * firePos;
GetWeapon()->Fire(this, &firePos);
}
GetWeapon()->Update(m_audioEntityId);
GetWeapon()->Update(m_audioEntityId, nil);
}
// --MIAMI: Made compatible with slots, but still TODO
@ -742,7 +742,7 @@ CPlayerPed::PlayerControlM16(CPad *padUsed)
firePos = GetMatrix() * firePos;
GetWeapon()->Fire(this, &firePos);
}
GetWeapon()->Update(m_audioEntityId);
GetWeapon()->Update(m_audioEntityId, nil);
}
void
@ -1561,7 +1561,7 @@ CPlayerPed::ProcessControl(void)
}
if (padUsed && IsPedShootable()) {
ProcessWeaponSwitch(padUsed);
GetWeapon()->Update(m_audioEntityId);
GetWeapon()->Update(m_audioEntityId, this);
}
ProcessAnimGroups();
if (padUsed) {

@ -734,7 +734,7 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree
}
CPed*
CPopulation::AddPedInCar(CVehicle* car, bool isPassenger)
CPopulation::AddPedInCar(CVehicle* car, bool isDriver)
{
int defaultModel = MI_MALE01;
int miamiViceIndex = 0;
@ -777,7 +777,7 @@ CPopulation::AddPedInCar(CVehicle* car, bool isPassenger)
case MI_VICECHEE: // TODO(MIAMI): figure out new structure of the function
preferredModel = COP_MIAMIVICE;
pedType = PEDTYPE_COP;
miamiViceIndex = (isPassenger ? 2 * CCarCtrl::MiamiViceCycle : 2 * CCarCtrl::MiamiViceCycle + 1);
miamiViceIndex = (isDriver ? 2 * CCarCtrl::MiamiViceCycle : 2 * CCarCtrl::MiamiViceCycle + 1);
break;
case MI_TAXI:
case MI_CABBIE:
@ -828,29 +828,11 @@ CPopulation::AddPedInCar(CVehicle* car, bool isPassenger)
CPed *newPed = CPopulation::AddPed((ePedType)pedType, preferredModel, car->GetPosition(), miamiViceIndex);
newPed->bUsesCollision = false;
// what??
if (pedType != PEDTYPE_COP) {
newPed->SetCurrentWeapon(WEAPONTYPE_COLT45);
if (newPed->GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED) {
newPed->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(newPed->GetWeapon()->m_eWeaponType)->m_nModelId);
}
/*
// Miami leftover
if (car->m_vehType == VEHICLE_TYPE_BIKE) {
newPed->m_pVehicleAnim = CAnimManager::BlendAnimation(newPed->GetClump(), ASSOCGRP_STD, *((CBike*)car + 308h), 100.0f);
} else */
// FIX: Make peds comfortable while driving car/boat
#ifdef FIX_BUGS
{
newPed->m_pVehicleAnim = CAnimManager::BlendAnimation(newPed->GetClump(), ASSOCGRP_STD, car->GetDriverAnim(), 100.0f);
}
#else
{
newPed->m_pVehicleAnim = CAnimManager::BlendAnimation(newPed->GetClump(), ASSOCGRP_STD, ANIM_CAR_SIT, 100.0f);
}
#endif
newPed->StopNonPartialAnims();
newPed->AddInCarAnims(car, isDriver);
return newPed;
}

@ -70,7 +70,7 @@ public:
static void LoadPedGroups();
static void UpdatePedCount(ePedType, bool);
static void DealWithZoneChange(eLevelName oldLevel, eLevelName newLevel, bool);
static CPed *AddPedInCar(CVehicle *car, bool isPassenger);
static CPed *AddPedInCar(CVehicle *car, bool isDriver);
static bool IsPointInSafeZone(CVector *coors);
static void RemovePed(CPed *ent);
static int32 ChooseCivilianOccupation(int32);

@ -3017,11 +3017,15 @@ void
CAutomobile::DoDriveByShootings(void)
{
CAnimBlendAssociation *anim;
CPlayerInfo* playerInfo = ((CPlayerPed*)this)->GetPlayerInfoForThisPlayerPed();
if (playerInfo && !playerInfo->m_bDriveByAllowed)
return;
CWeapon *weapon = pDriver->GetWeapon();
if(CWeaponInfo::GetWeaponInfo(weapon->m_eWeaponType)->m_nWeaponSlot != 5)
return;
weapon->Update(pDriver->m_audioEntityId);
weapon->Update(pDriver->m_audioEntityId, nil);
bool lookingLeft = false;
bool lookingRight = false;
@ -3037,37 +3041,42 @@ CAutomobile::DoDriveByShootings(void)
lookingRight = true;
}
AnimationId rightAnim = ANIM_DRIVEBY_R;
AnimationId leftAnim = ANIM_DRIVEBY_L;
if (pDriver->m_pMyVehicle->bLowVehicle) {
rightAnim = ANIM_DRIVEBY_LOW_R;
leftAnim = ANIM_DRIVEBY_LOW_L;
}
if(lookingLeft || lookingRight){
if(lookingLeft){
anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_R);
anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), rightAnim);
if(anim)
anim->blendDelta = -1000.0f;
anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_L);
anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), leftAnim);
if(anim == nil || anim->blendDelta < 0.0f)
CAnimManager::AddAnimation(pDriver->GetClump(), ASSOCGRP_STD, ANIM_DRIVEBY_L);
else
anim->SetRun();
anim = CAnimManager::AddAnimation(pDriver->GetClump(), ASSOCGRP_STD, leftAnim);
}else if(pDriver->m_pMyVehicle->pPassengers[0] == nil || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON){
anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_L);
anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), leftAnim);
if(anim)
anim->blendDelta = -1000.0f;
anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_R);
anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), rightAnim);
if(anim == nil || anim->blendDelta < 0.0f)
CAnimManager::AddAnimation(pDriver->GetClump(), ASSOCGRP_STD, ANIM_DRIVEBY_R);
else
anim->SetRun();
anim = CAnimManager::AddAnimation(pDriver->GetClump(), ASSOCGRP_STD, rightAnim);
}
if(CPad::GetPad(0)->GetCarGunFired() && CTimer::GetTimeInMilliseconds() > weapon->m_nTimer){
if (!anim || !anim->IsRunning()) {
if (CPad::GetPad(0)->GetCarGunFired() && CTimer::GetTimeInMilliseconds() > weapon->m_nTimer) {
weapon->FireFromCar(this, lookingLeft);
weapon->m_nTimer = CTimer::GetTimeInMilliseconds() + 70;
}
}
}else{
weapon->Reload();
anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_L);
anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), leftAnim);
if(anim)
anim->blendDelta = -1000.0f;
anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_R);
anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), rightAnim);
if(anim)
anim->blendDelta = -1000.0f;
}

@ -19,6 +19,9 @@
#include "Pools.h"
#include "Pad.h"
#include "Boat.h"
#include "AnimBlendAssociation.h"
#include "RpAnimBlend.h"
#include "Record.h"
#define INVALID_ORIENTATION (-9999.99f)
@ -149,6 +152,9 @@ CBoat::ProcessControl(void)
ProcessControlInputs(0);
if(GetModelIndex() == MI_PREDATOR)
DoFixedMachineGuns();
if (!CRecordDataForChase::IsRecording())
DoDriveByShootings();
break;
case STATUS_SIMPLE:
m_bIsAnchored = false;
@ -912,6 +918,68 @@ CBoat::AddWakePoint(CVector point)
}
}
void
CBoat::DoDriveByShootings(void)
{
CAnimBlendAssociation *anim;
CPlayerInfo* playerInfo = ((CPlayerPed*)this)->GetPlayerInfoForThisPlayerPed();
if (playerInfo && !playerInfo->m_bDriveByAllowed)
return;
CWeapon *weapon = pDriver->GetWeapon();
if(CWeaponInfo::GetWeaponInfo(weapon->m_eWeaponType)->m_nWeaponSlot != 5)
return;
weapon->Update(pDriver->m_audioEntityId, nil);
bool lookingLeft = false;
bool lookingRight = false;
if(TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN){
if(CPad::GetPad(0)->GetLookLeft())
lookingLeft = true;
if(CPad::GetPad(0)->GetLookRight())
lookingRight = true;
}else{
if(TheCamera.Cams[TheCamera.ActiveCam].LookingLeft)
lookingLeft = true;
if(TheCamera.Cams[TheCamera.ActiveCam].LookingRight)
lookingRight = true;
}
if(lookingLeft || lookingRight){
if(lookingLeft){
anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_R);
if(anim)
anim->blendDelta = -1000.0f;
anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_L);
if(anim == nil || anim->blendDelta < 0.0f)
anim = CAnimManager::AddAnimation(pDriver->GetClump(), ASSOCGRP_STD, ANIM_DRIVEBY_L);
}else if(pDriver->m_pMyVehicle->pPassengers[0] == nil || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON){
anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_L);
if(anim)
anim->blendDelta = -1000.0f;
anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_R);
if(anim == nil || anim->blendDelta < 0.0f)
anim = CAnimManager::AddAnimation(pDriver->GetClump(), ASSOCGRP_STD, ANIM_DRIVEBY_R);
}
if (!anim || !anim->IsRunning()) {
if (CPad::GetPad(0)->GetCarGunFired() && CTimer::GetTimeInMilliseconds() > weapon->m_nTimer) {
weapon->FireFromCar(this, lookingLeft);
weapon->m_nTimer = CTimer::GetTimeInMilliseconds() + 70;
}
}
}else{
weapon->Reload();
anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_L);
if(anim)
anim->blendDelta = -1000.0f;
anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_R);
if(anim)
anim->blendDelta = -1000.0f;
}
}
#ifdef COMPATIBLE_SAVES
void
CBoat::Save(uint8*& buf)

@ -61,6 +61,7 @@ public:
void SetupModelNodes();
void PruneWakeTrail(void);
void AddWakePoint(CVector point);
void DoDriveByShootings(void);
static CBoat *apFrameWakeGeneratingBoats[4];

@ -1045,7 +1045,7 @@ CVehicle::SetUpDriver(void)
if(VehicleCreatedBy != RANDOM_VEHICLE)
return nil;
pDriver = CPopulation::AddPedInCar(this, false);
pDriver = CPopulation::AddPedInCar(this, true);
pDriver->m_pMyVehicle = this;
pDriver->m_pMyVehicle->RegisterReference((CEntity**)&pDriver->m_pMyVehicle);
pDriver->bInVehicle = true;
@ -1061,7 +1061,7 @@ CVehicle::SetupPassenger(int n)
if(pPassengers[n])
return pPassengers[n];
pPassengers[n] = CPopulation::AddPedInCar(this, true);
pPassengers[n] = CPopulation::AddPedInCar(this, false);
pPassengers[n]->m_pMyVehicle = this;
pPassengers[n]->m_pMyVehicle->RegisterReference((CEntity**)&pPassengers[n]->m_pMyVehicle);
pPassengers[n]->bInVehicle = true;

@ -300,7 +300,6 @@ public:
CVehicleModelInfo* GetModelInfo() { return (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()); }
bool IsTaxi(void) { return GetModelIndex() == MI_TAXI || GetModelIndex() == MI_CABBIE || GetModelIndex() == MI_ZEBRA || GetModelIndex() == MI_KAUFMAN; }
bool IsRealHeli(void) { return !!(pHandling->Flags & HANDLING_IS_HELI); }
AnimationId GetDriverAnim(void) { return IsCar() && bLowVehicle ? ANIM_CAR_LSIT : (IsBoat() && GetModelIndex() != MI_SPEEDER ? ANIM_DRIVE_BOAT : ANIM_CAR_SIT); }
static bool bWheelsOnlyCheat;
static bool bAllDodosCheat;

@ -30,25 +30,28 @@
#include "WeaponInfo.h"
#include "World.h"
// TODO(Miami)
#define AUDIO_NOT_READY
uint16 gReloadSampleTime[WEAPONTYPE_LAST_WEAPONTYPE] =
{
0, // UNARMED
0, // BASEBALLBAT
0, // GRENADE
0, // DETONATEGRENADE
0, // MOLOTOV
0, // ROCKET
250, // COLT45
650, // SHOTGUN
400, // TEC9
400, // UZIhec
400, // SILENCED_INGRAM
400, // MP5
650, // SHOTGUN
300, // AK47
300, // M16
300, // AK47
423, // SNIPERRIFLE
400, // ROCKETLAUNCHER
0, // FLAMETHROWER
0, // MOLOTOV
0, // ROCKET
0, // GRENADE
0, // DETONATEGRENADE
0, // DETONATOR
0 // HELICANNON
};
@ -96,10 +99,7 @@ CWeapon::Initialise(eWeaponType type, int32 ammo)
{
m_eWeaponType = type;
m_eWeaponState = WEAPONSTATE_READY;
if (ammo > 99999)
m_nAmmoTotal = 99999;
else
m_nAmmoTotal = ammo;
m_nAmmoTotal = Min(ammo, 99999);
m_nAmmoInClip = 0;
Reload();
m_nTimer = 0;
@ -283,8 +283,11 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
DMAudio.PlayOneShot(shooterPed->m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f);
}
if ( m_nAmmoInClip > 0 ) m_nAmmoInClip--;
if ( m_nAmmoTotal > 0 && (m_nAmmoTotal < 25000 || isPlayer) ) m_nAmmoTotal--;
if ( m_nAmmoInClip > 0 )
m_nAmmoInClip--;
if ( m_nAmmoTotal > 0 && (m_nAmmoTotal < 25000 || isPlayer) && (!isPlayer || CStats::GetPercentageProgress() < 100.0f || m_eWeaponType == WEAPONTYPE_DETONATOR))
m_nAmmoTotal--;
if ( m_eWeaponState == WEAPONSTATE_READY && m_eWeaponType == WEAPONTYPE_FLAMETHROWER )
DMAudio.PlayOneShot(((CPhysical*)shooter)->m_audioEntityId, SOUND_WEAPON_FLAMETHROWER_FIRE, 0.0f);
@ -331,7 +334,7 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
}
bool
CWeapon::FireFromCar(CAutomobile *shooter, bool left)
CWeapon::FireFromCar(CVehicle *shooter, bool left)
{
ASSERT(shooter!=nil);
@ -393,10 +396,10 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
{
bool collided = false;
CColModel *victimPedCol = &CTempColModels::ms_colModelPed1;
if ( victimPed->OnGround() || !victimPed->IsPedHeadAbovePos(-0.3f) )
victimPedCol = &CTempColModels::ms_colModelPedGroundHit;
// TODO(Miami)
if (victimPed->m_nPedState == PED_DRIVING && (m_eWeaponType == WEAPONTYPE_UNARMED /*|| m_eWeaponType == WEAPONTYPE_BRASSKNUCKLES*/
|| info->m_bFightMode))
continue;
float victimPedRadius = victimPed->GetBoundRadius() + info->m_fRadius;
if ( victimPed->bUsesCollision || victimPed->Dead() || victimPed->Driving() )
@ -405,12 +408,29 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
if ( SQR(victimPedRadius) > (victimPedPos-(*fireSource)).MagnitudeSqr() )
{
CVector collisionDist;
CColModel* victimPedCol = &CTempColModels::ms_colModelPed1;
bool useLocalPos = false;
if (victimPed->m_nPedState == PED_FALL
|| victimPed->m_nPedState == PED_DIE && victimPed->bIsPedDieAnimPlaying
|| victimPed->m_nWaitState == WAITSTATE_SIT_IDLE
|| victimPed->m_nWaitState == WAITSTATE_SUN_BATHE_IDLE)
{
useLocalPos = true;
victimPedCol = ((CPedModelInfo*)CModelInfo::GetModelInfo(victimPed->GetModelIndex()))->AnimatePedColModelSkinnedWorld(victimPed->GetClump());
} else if (victimPed->DyingOrDead()) {
victimPedCol = &CTempColModels::ms_colModelPedGroundHit;
}
int32 s = 0;
while ( s < victimPedCol->numSpheres )
{
CColSphere *sphere = &victimPedCol->spheres[s];
collisionDist = victimPedPos+sphere->center-(*fireSource);
if (useLocalPos) {
collisionDist = sphere->center - (*fireSource);
} else {
collisionDist = victimPedPos + sphere->center - (*fireSource);
}
if ( SQR(sphere->radius + info->m_fRadius) > collisionDist.MagnitudeSqr() )
{
@ -659,45 +679,15 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
switch ( m_eWeaponType )
{
case WEAPONTYPE_AK47:
{
static uint8 counter = 0;
if ( !(++counter & 1) )
{
CPointLights::AddLight(CPointLights::LIGHT_POINT,
*fireSource, CVector(0.0f, 0.0f, 0.0f), 5.0f,
1.0f, 0.8f, 0.0f, CPointLights::FOG_NONE, false);
CVector gunflashPos = *fireSource;
gunflashPos += CVector(0.06f*ahead.x, 0.06f*ahead.y, 0.0f);
CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.10f);
gunflashPos += CVector(0.06f*ahead.x, 0.06f*ahead.y, 0.0f);
CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.08f);
gunflashPos += CVector(0.05f*ahead.x, 0.05f*ahead.y, 0.0f);
CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.06f);
gunflashPos += CVector(0.04f*ahead.x, 0.04f*ahead.y, 0.0f);
CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
CVector gunsmokePos = *fireSource;
float rnd = CGeneral::GetRandomNumberInRange(0.05f, 0.25f);
CParticle::AddParticle(PARTICLE_GUNSMOKE2, gunsmokePos, CVector(ahead.x*rnd, ahead.y*rnd, 0.0f));
CVector gunshellPos = *fireSource;
gunshellPos -= CVector(0.5f*ahead.x, 0.5f*ahead.y, 0.0f);
CVector dir = CrossProduct(CVector(ahead.x, ahead.y, 0.0f), CVector(0.0f, 0.0f, 5.0f));
dir.Normalise2D();
AddGunshell(shooter, gunshellPos, CVector2D(dir.x, dir.y), 0.018f);
}
break;
}
case WEAPONTYPE_M16:
case WEAPONTYPE_AK47:
// case WEAPONTYPE_M60:
// case WEAPONTYPE_MINIGUN:
case WEAPONTYPE_HELICANNON:
{
static uint8 counter = 0;
if ( !(++counter & 1) )
if ( info->m_nFiringRate >= 50 && !(++counter & 1) )
{
CPointLights::AddLight(CPointLights::LIGHT_POINT,
*fireSource, CVector(0.0f, 0.0f, 0.0f), 5.0f,
@ -1669,7 +1659,7 @@ CWeapon::FireM16_1stPerson(CEntity *shooter)
}
bool
CWeapon::FireInstantHitFromCar(CAutomobile *shooter, bool left)
CWeapon::FireInstantHitFromCar(CVehicle *shooter, bool left)
{
CWeaponInfo *info = GetInfo();
@ -2040,8 +2030,10 @@ CWeapon::Reload(void)
}
void
CWeapon::Update(int32 audioEntity)
CWeapon::Update(int32 audioEntity, CPed *pedToAdjustSound)
{
CWeaponInfo *info = GetInfo();
switch ( m_eWeaponState )
{
case WEAPONSTATE_MELEE_MADECONTACT:
@ -2074,9 +2066,57 @@ CWeapon::Update(int32 audioEntity)
{
if ( AEHANDLE_IS_OK(audioEntity) && m_eWeaponType < WEAPONTYPE_LAST_WEAPONTYPE )
{
CAnimBlendAssociation *reloadAssoc = nil;
if (pedToAdjustSound) {
if (CPed::GetReloadAnim(info) && (!CWorld::Players[CWorld::PlayerInFocus].m_bFastReload || !pedToAdjustSound->IsPlayer())) {
reloadAssoc = RpAnimBlendClumpGetAssociation(pedToAdjustSound->GetClump(), CPed::GetReloadAnim(info));
if (!reloadAssoc) {
reloadAssoc = RpAnimBlendClumpGetAssociation(pedToAdjustSound->GetClump(), CPed::GetCrouchReloadAnim(info));
}
}
}
if (reloadAssoc && reloadAssoc->IsRunning() && reloadAssoc->blendAmount > 0.2f) {
float soundStart = 0.75f;
switch (info->m_AnimToPlay) {
case ASSOCGRP_PYTHON:
soundStart = 0.5f;
break;
case ASSOCGRP_COLT:
case ASSOCGRP_TEC:
soundStart = 0.7f;
break;
case ASSOCGRP_UZI:
soundStart = 0.75f;
break;
case ASSOCGRP_RIFLE:
soundStart = 0.75f;
break;
case ASSOCGRP_M60:
soundStart = 0.7f;
break;
default:
break;
}
if (reloadAssoc->GetProgress() >= soundStart && (reloadAssoc->currentTime - reloadAssoc->timeStep) / reloadAssoc->hierarchy->totalLength < soundStart) {
#ifdef AUDIO_NOT_READY
DMAudio.PlayOneShot(audioEntity, SOUND_WEAPON_RELOAD, 0.0f);
#else
DMAudio.PlayOneShot(audioEntity, SOUND_WEAPON_RELOAD, m_eWeaponType);
#endif
}
if (CTimer::GetTimeInMilliseconds() > m_nTimer && reloadAssoc->GetProgress() < 0.9f) {
m_nTimer = CTimer::GetTimeInMilliseconds();
}
} else {
uint32 timePassed = m_nTimer - gReloadSampleTime[m_eWeaponType];
if ( CTimer::GetPreviousTimeInMilliseconds() < timePassed && CTimer::GetTimeInMilliseconds() >= timePassed )
if (CTimer::GetPreviousTimeInMilliseconds() < timePassed && CTimer::GetTimeInMilliseconds() >= timePassed) {
#ifdef AUDIO_NOT_READY
DMAudio.PlayOneShot(audioEntity, SOUND_WEAPON_RELOAD, 0.0f);
#else
DMAudio.PlayOneShot(audioEntity, SOUND_WEAPON_RELOAD, m_eWeaponType);
#endif
}
}
}
if ( CTimer::GetTimeInMilliseconds() > m_nTimer )

@ -7,7 +7,8 @@
class CEntity;
class CPhysical;
class CAutomobile;
class CVehicle;
class CPed;
struct CColPoint;
class CWeaponInfo;
@ -35,7 +36,7 @@ public:
void Shutdown();
bool Fire (CEntity *shooter, CVector *fireSource);
bool FireFromCar (CAutomobile *shooter, bool left);
bool FireFromCar (CVehicle *shooter, bool left);
bool FireMelee (CEntity *shooter, CVector &fireSource);
bool FireInstantHit(CEntity *shooter, CVector *fireSource);
@ -50,14 +51,14 @@ public:
bool FireAreaEffect (CEntity *shooter, CVector *fireSource);
bool FireSniper (CEntity *shooter);
bool FireM16_1stPerson (CEntity *shooter);
bool FireInstantHitFromCar(CAutomobile *shooter, bool left);
bool FireInstantHitFromCar(CVehicle *shooter, bool left);
static void DoDoomAiming (CEntity *shooter, CVector *source, CVector *target);
static void DoTankDoomAiming (CEntity *shooter, CEntity *driver, CVector *source, CVector *target);
static void DoDriveByAutoAiming(CEntity *shooter, CVector *source, CVector *target);
void Reload(void);
void Update(int32 audioEntity);
void Update(int32 audioEntity, CPed *pedToAdjustSound);
bool IsTypeMelee (void);
bool IsType2Handed(void);

@ -20,21 +20,21 @@ CWeaponInfo CWeaponInfo::ms_apWeaponInfos[WEAPONTYPE_TOTALWEAPONS];
static char ms_aWeaponNames[][32] = {
"Unarmed",
"BaseballBat",
"Grenade",
"DetonateGrenade",
"Molotov",
"Rocket",
"Colt45",
"Shotgun",
"Tec9",
"Uzi",
"SilencedIngram",
"Mp5",
"Shotgun",
"AK47",
"M16",
"AK47",
"SniperRifle",
"RocketLauncher",
"FlameThrower",
"Molotov",
"Rocket",
"Grenade",
"DetonateGrenade",
"Detonator",
"HeliCannon",
};

@ -5,24 +5,25 @@ enum eWeaponType
{
WEAPONTYPE_UNARMED,
WEAPONTYPE_BASEBALLBAT,
WEAPONTYPE_GRENADE,
WEAPONTYPE_DETONATOR_GRENADE,
WEAPONTYPE_MOLOTOV,
WEAPONTYPE_ROCKET,
WEAPONTYPE_COLT45,
WEAPONTYPE_SHOTGUN,
WEAPONTYPE_TEC9,
WEAPONTYPE_UZI,
WEAPONTYPE_SILENCED_INGRAM,
WEAPONTYPE_MP5,
WEAPONTYPE_SHOTGUN,
WEAPONTYPE_AK47,
WEAPONTYPE_M16,
WEAPONTYPE_AK47,
WEAPONTYPE_SNIPERRIFLE,
WEAPONTYPE_ROCKETLAUNCHER,
WEAPONTYPE_FLAMETHROWER,
WEAPONTYPE_MOLOTOV,
WEAPONTYPE_ROCKET,
WEAPONTYPE_GRENADE,
WEAPONTYPE_DETONATOR_GRENADE,
WEAPONTYPE_DETONATOR,
WEAPONTYPE_HELICANNON,
WEAPONTYPE_LAST_WEAPONTYPE,
WEAPONTYPE_HEALTH,
WEAPONTYPE_ARMOUR,
WEAPONTYPE_RAMMEDBYCAR,
WEAPONTYPE_RUNOVERBYCAR,