summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/control/Pickups.h3
-rw-r--r--src/control/Script.cpp2
-rw-r--r--src/control/TrafficLights.cpp14
-rw-r--r--src/control/TrafficLights.h2
-rw-r--r--src/core/EventList.h1
-rw-r--r--src/core/Frontend.cpp1
-rw-r--r--src/core/Pad.cpp96
-rw-r--r--src/core/Stats.cpp24
-rw-r--r--src/core/Stats.h1
-rw-r--r--src/core/World.cpp13
-rw-r--r--src/core/World.h1
-rw-r--r--src/core/re3.cpp4
-rw-r--r--src/objects/Stinger.cpp232
-rw-r--r--src/objects/Stinger.h40
-rw-r--r--src/peds/CopPed.cpp46
-rw-r--r--src/peds/CopPed.h2
-rw-r--r--src/peds/Ped.cpp901
-rw-r--r--src/peds/Ped.h19
-rw-r--r--src/render/Fluff.cpp6
-rw-r--r--src/render/Fluff.h2
-rw-r--r--src/render/Glass.h1
-rw-r--r--src/render/Hud.cpp51
-rw-r--r--src/render/SpecialFX.cpp1
-rw-r--r--src/render/SpecialFX.h8
-rw-r--r--src/text/Text.cpp14
-rw-r--r--src/text/Text.h1
-rw-r--r--src/weapons/Weapon.cpp723
-rw-r--r--src/weapons/Weapon.h17
-rw-r--r--src/weapons/WeaponEffects.cpp63
-rw-r--r--src/weapons/WeaponInfo.cpp51
-rw-r--r--src/weapons/WeaponInfo.h2
31 files changed, 1717 insertions, 625 deletions
diff --git a/src/control/Pickups.h b/src/control/Pickups.h
index 8f6ef4c3..d7d22174 100644
--- a/src/control/Pickups.h
+++ b/src/control/Pickups.h
@@ -110,6 +110,9 @@ public:
static CVehicle *pPlayerVehicle;
static CVector StaticCamCoors;
static uint32 StaticCamStartTime;
+
+//TODO(MIAMI)
+ static void RemoveAllPickupsOfACertainWeaponGroupWithNoAmmo(eWeaponType) {}
};
extern uint16 AmmoForWeapon[20];
diff --git a/src/control/Script.cpp b/src/control/Script.cpp
index b99110b0..6898d574 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -3772,7 +3772,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
CPed* pNearPed = ped->m_nearPeds[i];
if (pNearPed->m_leader == ped) {
pNearPed->Teleport(pos);
- pNearPed->PositionPedOutOfCollision(); // TODO(MIAMI): this is PositionAnyPedOutOfCollision!!!
+ pNearPed->PositionAnyPedOutOfCollision();
}
}
}
diff --git a/src/control/TrafficLights.cpp b/src/control/TrafficLights.cpp
index 54c97d06..5559b1c4 100644
--- a/src/control/TrafficLights.cpp
+++ b/src/control/TrafficLights.cpp
@@ -18,6 +18,8 @@
// TODO: figure out the meaning of this
enum { SOME_FLAG = 0x80 };
+bool CTrafficLights::bGreenLightsCheat;
+
void
CTrafficLights::DisplayActualLight(CEntity *ent)
{
@@ -310,6 +312,12 @@ CTrafficLights::LightForPeds(void)
uint8
CTrafficLights::LightForCars1(void)
{
+ if (CWeather::Wind > 1.1f)
+ return CAR_LIGHTS_GREEN;
+
+ if (bGreenLightsCheat)
+ return CAR_LIGHTS_GREEN;
+
uint32 period = CTimer::GetTimeInMilliseconds() % 16384;
if(period < 5000)
@@ -323,6 +331,12 @@ CTrafficLights::LightForCars1(void)
uint8
CTrafficLights::LightForCars2(void)
{
+ if (CWeather::Wind > 1.1f)
+ return CAR_LIGHTS_GREEN;
+
+ if (bGreenLightsCheat)
+ return CAR_LIGHTS_GREEN;
+
uint32 period = CTimer::GetTimeInMilliseconds() % 16384;
if(period < 6000)
diff --git a/src/control/TrafficLights.h b/src/control/TrafficLights.h
index f3df6cd5..6cd5e04a 100644
--- a/src/control/TrafficLights.h
+++ b/src/control/TrafficLights.h
@@ -16,6 +16,8 @@ enum {
class CTrafficLights
{
public:
+ static bool bGreenLightsCheat;
+
static void DisplayActualLight(CEntity *ent);
static void ScanForLightsOnMap(void);
static int FindTrafficLightType(CEntity *light);
diff --git a/src/core/EventList.h b/src/core/EventList.h
index 0531aed7..dcca1270 100644
--- a/src/core/EventList.h
+++ b/src/core/EventList.h
@@ -24,6 +24,7 @@ enum eEventType
EVENT_CAR_SET_ON_FIRE,
EVENT_ASSAULT_NASTYWEAPON,
EVENT_ASSAULT_NASTYWEAPON_POLICE,
+ EVENT_UNK, // Not on SA it seems
EVENT_ICECREAM,
EVENT_ATM,
EVENT_SHOPSTALL,
diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp
index 715e9061..cdecb8b4 100644
--- a/src/core/Frontend.cpp
+++ b/src/core/Frontend.cpp
@@ -5369,6 +5369,7 @@ CMenuManager::ConstructStatLine(int rowIdx)
STAT_LINE("FEST_CC", &CStats::CriminalsCaught, false, nil);
STAT_LINE("FEST_FE", &CStats::FiresExtinguished, false, nil);
STAT_LINE("DAYPLC", &(nTemp = CTimer::GetTimeInMilliseconds() + 100), false, nil);
+ //TODO(MIAMI): move this function to the CStats and add reading of Stat lines tied with "MEDIA" for the "CHASESTAT" cheatcode
return counter;
#undef STAT_LINE
diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp
index 42b26c63..193ca1c5 100644
--- a/src/core/Pad.cpp
+++ b/src/core/Pad.cpp
@@ -47,6 +47,7 @@
#include "platform.h"
#include "Stats.h"
#include "CarCtrl.h"
+#include "TrafficLights.h"
#ifdef GTA_PS2
#include "eetypes.h"
@@ -208,15 +209,20 @@ void HealthCheat()
}
}
-void VehicleCheat(bool something, int model)
+void VehicleCheat(int model)
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
- CStreaming::RequestModel(model, 0);
- CStreaming::LoadAllRequestedModels(something);
+ CStreaming::RequestModel(model, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::LoadAllRequestedModels(false);
if (CStreaming::ms_aInfoForModel[model].m_loadState == STREAMSTATE_LOADED) {
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
- int32 node = ThePaths.FindNodeClosestToCoors(FindPlayerCoors(), PATH_CAR, 100.0f);
+ if (!(CStreaming::ms_aInfoForModel[model].m_loadState & STREAMFLAGS_DONT_REMOVE)) {
+ CStreaming::SetModelIsDeletable(model);
+ CStreaming::SetModelTxdIsDeletable(model);
+ }
+
+ int32 node = ThePaths.FindNodeClosestToCoors(FindPlayerCoors(), PATH_CAR, 100.0f);
if (node < 0) return;
#ifdef FIX_BUGS
@@ -362,16 +368,16 @@ void SunnyWeatherCheat()
CWeather::ForceWeatherNow(WEATHER_SUNNY);
}
-void CloudyWeatherCheat()
+void ExtraSunnyWeatherCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT7"), true);
- CWeather::ForceWeatherNow(WEATHER_CLOUDY);
+ CWeather::ForceWeatherNow(WEATHER_EXTRA_SUNNY);
}
-void StormyWeatherCheat()
+void CloudyWeatherCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT7"), true);
- CWeather::ForceWeatherNow(WEATHER_HURRICANE);
+ CWeather::ForceWeatherNow(WEATHER_CLOUDY);
}
void RainyWeatherCheat()
@@ -442,6 +448,12 @@ void PinkCarsCheat()
gbPinkCars = true;
}
+void TrafficLightsCheat()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+ CTrafficLights::bGreenLightsCheat = true;
+}
+
void MadCarsCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
@@ -548,6 +560,11 @@ void FlyingFishCheat(void)
CVehicle::bCheat8 = !CVehicle::bCheat8;
}
+void DoShowChaseStatCheat(void) {
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+ CStats::ShowChaseStatOnScreen = 1;
+}
+
bool
CControllerState::CheckForInput(void)
{
@@ -1030,7 +1047,7 @@ void CPad::AddToCheatString(char c)
// "CCCCCC321TCT" - CIRCLE CIRCLE CIRCLE CIRCLE CIRCLE CIRCLE R1 L2 L1 TRIANGLE CIRCLE TRIANGLE
else if ( !_CHEATCMP("TCT123CCCCCC") )
- VehicleCheat(true, MI_RHINO);
+ VehicleCheat(MI_RHINO);
// "CCCSSSSS1TCT" - CIRCLE CIRCLE CIRCLE SQUARE SQUARE SQUARE SQUARE SQUARE L1 TRIANGLE CIRCLE TRIANGLE
else if ( !_CHEATCMP("TCT1SSSSSCCC") )
@@ -1142,19 +1159,22 @@ void CPad::AddToPCCheatString(char c)
// "APLEASANTDAY"
else if (!Cheat_strncmp(KeyBoardCheatString, "\\FKU[\\VHFW]I")) {
KeyBoardCheatString[0] = ' ';
- CloudyWeatherCheat();
+ SunnyWeatherCheat();
}
// "ALOVELYDAY"
else if (!Cheat_strncmp(KeyBoardCheatString, "\\FKZY`YVML")) {
KeyBoardCheatString[0] = ' ';
- SunnyWeatherCheat();
+ ExtraSunnyWeatherCheat();
}
// "ABITDRIEG"
-
+ else if (!Cheat_strncmp(KeyBoardCheatString, "JJPSQoLIB")) {
+ KeyBoardCheatString[0] = ' ';
+ CloudyWeatherCheat();
+ }
// "CATSANDDOGS"
else if (!Cheat_strncmp(KeyBoardCheatString, "VLVEQiDZULP")) {
KeyBoardCheatString[0] = ' ';
- StormyWeatherCheat();
+ RainyWeatherCheat();
}
// "CANTSEEATHING"
else if (!Cheat_strncmp(KeyBoardCheatString, "JSPIa\\HLT_[IJ")) {
@@ -1164,10 +1184,13 @@ void CPad::AddToPCCheatString(char c)
// "PANZER"
else if (!Cheat_strncmp(KeyBoardCheatString, "UJaONk")) {
KeyBoardCheatString[0] = ' ';
- VehicleCheat(true, MI_RHINO);
+ VehicleCheat(MI_RHINO);
}
// "LIFEISPASSINGMEBY"
-
+ else if (!Cheat_strncmp(KeyBoardCheatString, "\\GLNTiLZTL][PeSOh")) {
+ KeyBoardCheatString[0] = ' ';
+ FastWeatherCheat();
+ }
// "BIGBANG"
else if (!Cheat_strncmp(KeyBoardCheatString, "JSHCTdE")) {
KeyBoardCheatString[0] = ' ';
@@ -1221,6 +1244,7 @@ void CPad::AddToPCCheatString(char c)
// "CHASESTAT"
else if (!Cheat_strncmp(KeyBoardCheatString, "WF[TRnDOD")) {
KeyBoardCheatString[0] = ' ';
+ DoShowChaseStatCheat();
}
// "CHICKSWITHGUNS"
else if (!Cheat_strncmp(KeyBoardCheatString, "VS\\HUoL^TVPQOc")) {
@@ -1235,6 +1259,7 @@ void CPad::AddToPCCheatString(char c)
// "GREENLIGHT"
else if (!Cheat_strncmp(KeyBoardCheatString, "WMNJYiHLSR")) {
KeyBoardCheatString[0] = ' ';
+ TrafficLightsCheat();
}
// "MIAMITRAFFIC"
else if (!Cheat_strncmp(KeyBoardCheatString, "FNMGNmWPNLVU")) {
@@ -1254,47 +1279,47 @@ void CPad::AddToPCCheatString(char c)
// "TRAVELINSTYLE"
else if (!Cheat_strncmp(KeyBoardCheatString, "HQ`U`iLSFaNZ[")) {
KeyBoardCheatString[0] = ' ';
- VehicleCheat(true, MI_BLOODRA);
+ VehicleCheat(MI_BLOODRA);
}
// "THELASTRIDE"
else if (!Cheat_strncmp(KeyBoardCheatString, "HIPSanDSFSa")) {
KeyBoardCheatString[0] = ' ';
- VehicleCheat(true, MI_ROMERO);
+ VehicleCheat(MI_ROMERO);
}
// "ROCKANDROLLCAR"
else if (!Cheat_strncmp(KeyBoardCheatString, "UFJMYjUKOLXKVr")) {
KeyBoardCheatString[0] = ' ';
- VehicleCheat(true, MI_LOVEFIST);
+ VehicleCheat(MI_LOVEFIST);
}
// "RUBBISHCAR"
else if (!Cheat_strncmp(KeyBoardCheatString, "UFJI`dEIV]")) {
KeyBoardCheatString[0] = ' ';
- VehicleCheat(true, MI_TRASH);
+ VehicleCheat(MI_TRASH);
}
// "GETTHEREQUICKLY"
else if (!Cheat_strncmp(KeyBoardCheatString, "\\QRDVpTLSPU\\[eT")) {
KeyBoardCheatString[0] = ' ';
- VehicleCheat(true, MI_BLOODRB);
+ VehicleCheat(MI_BLOODRB);
}
// "GETTHEREFAST"
else if (!Cheat_strncmp(KeyBoardCheatString, "WXHGRmHOU_RO")) {
KeyBoardCheatString[0] = ' ';
- VehicleCheat(true, MI_SABRETUR);
+ VehicleCheat(MI_SABRETUR);
}
// "BETTERTHANWALKING"
else if (!Cheat_strncmp(KeyBoardCheatString, "JSPLY\\ZUBSaZLtaK^")) {
KeyBoardCheatString[0] = ' ';
- VehicleCheat(true, MI_CADDY);
+ VehicleCheat(MI_CADDY);
}
// "GETTHEREFASTINDEED"
else if (!Cheat_strncmp(KeyBoardCheatString, "GJLE[dWZBQfZLvRXa[^WHL")) {
KeyBoardCheatString[0] = ' ';
- VehicleCheat(true, MI_HOTRINA);
+ VehicleCheat(MI_HOTRINA);
}
// "GETTHEREAMAZINGLYFAST"
else if (!Cheat_strncmp(KeyBoardCheatString, "WXHGfgJUJeNUHe_Kdg^HJ")) {
KeyBoardCheatString[0] = ' ';
- VehicleCheat(true, MI_HOTRINB);
+ VehicleCheat(MI_HOTRINB);
}
// LOOKLIKELANCE
else if (!Cheat_strncmp(KeyBoardCheatString, "HHUBY`NPMV\\WS")) {
@@ -1346,6 +1371,16 @@ void CPad::AddToPCCheatString(char c)
KeyBoardCheatString[0] = ' ';
ChangePlayerModel("igdiaz");
}
+ // DEEPFRIEDMARSBARS
+ else if (!Cheat_strncmp(KeyBoardCheatString, "VWHC`mDTEPVZMpRK")) {
+ KeyBoardCheatString[0] = ' ';
+ gfTommyFatness = 0.26f;
+ }
+ // PROGRAMMER
+ else if (!Cheat_strncmp(KeyBoardCheatString, "UJTNNmJVS[")) {
+ KeyBoardCheatString[0] = ' ';
+ gfTommyFatness = -0.3f;
+ }
// SEAWAYS
else if (!Cheat_strncmp(KeyBoardCheatString, "V^HXN`V")) {
KeyBoardCheatString[0] = ' ';
@@ -1366,17 +1401,6 @@ void CPad::AddToPCCheatString(char c)
KeyBoardCheatString[0] = ' ';
FannyMagnetCheat();
}
- // "ILOVESCOTLAND"
- if (!_CHEATCMP("DNALTOCSEVOLI"))
- RainyWeatherCheat();
-
- // "MADWEATHER"
- if (!_CHEATCMP("REHTAEWDAM"))
- FastWeatherCheat();
-
- // "CHITTYCHITTYBB"
- if (!_CHEATCMP("BBYTTIHCYTTIHC"))
- ChittyChittyBangBangCheat();
// "NASTYLIMBSCHEAT"
if (!_CHEATCMP("TAEHCSBMILYTSAN"))
@@ -3117,6 +3141,8 @@ void CPad::ResetCheats(void)
gbBlackCars = false;
gbPinkCars = false;
CCarCtrl::bMadDriversCheat = false;
+ CTrafficLights::bGreenLightsCheat = false;
+ CStats::ShowChaseStatOnScreen = 0;
gbFastTime = false;
CTimer::SetTimeScale(1.0f);
}
diff --git a/src/core/Stats.cpp b/src/core/Stats.cpp
index 1efcee01..9c3ad084 100644
--- a/src/core/Stats.cpp
+++ b/src/core/Stats.cpp
@@ -341,6 +341,30 @@ wchar *CStats::FindCriminalRatingString()
return TheText.Get(CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney > 10000000 ? "RATNG52" : "RATNG51");
}
+wchar *CStats::FindChaseString(float fMediaLevel) {
+ if (fMediaLevel < 20.0f) return TheText.Get("MEDIA1");
+ if (fMediaLevel < 50.0f) return TheText.Get("MEDIA2");
+ if (fMediaLevel < 75.0f) return TheText.Get("MEDIA3");
+ if (fMediaLevel < 100.0f) return TheText.Get("MEDIA4");
+ if (fMediaLevel < 150.0f) return TheText.Get("MEDIA5");
+ if (fMediaLevel < 200.0f) return TheText.Get("MEDIA6");
+ if (fMediaLevel < 250.0f) return TheText.Get("MEDIA7");
+ if (fMediaLevel < 300.0f) return TheText.Get("MEDIA8");
+ if (fMediaLevel < 350.0f) return TheText.Get("MEDIA9");
+ if (fMediaLevel < 400.0f) return TheText.Get("MEDIA10");
+ if (fMediaLevel < 500.0f) return TheText.Get("MEDIA11");
+ if (fMediaLevel < 600.0f) return TheText.Get("MEDIA12");
+ if (fMediaLevel < 700.0f) return TheText.Get("MEDIA13");
+ if (fMediaLevel < 800.0f) return TheText.Get("MEDIA14");
+ if (fMediaLevel < 900.0f) return TheText.Get("MEDIA15");
+ if (fMediaLevel < 1000.0f) return TheText.Get("MEDIA16");
+ if (fMediaLevel < 1200.0f) return TheText.Get("MEDIA17");
+ if (fMediaLevel < 1400.0f) return TheText.Get("MEDIA18");
+ if (fMediaLevel < 1600.0f) return TheText.Get("MEDIA19");
+ if (fMediaLevel < 1800.0f) return TheText.Get("MEDIA20");
+ return TheText.Get("MEDIA21");
+}
+
int32 CStats::FindCriminalRatingNumber()
{
int32 rating;
diff --git a/src/core/Stats.h b/src/core/Stats.h
index f9ad4174..ad6fe516 100644
--- a/src/core/Stats.h
+++ b/src/core/Stats.h
@@ -118,6 +118,7 @@ public:
static void RegisterLevelFireMission(int32);
static void AnotherFireExtinguished();
static wchar *FindCriminalRatingString();
+ static wchar *FindChaseString(float fMediaLevel);
static void AnotherKillFrenzyPassed();
static void SetTotalNumberKillFrenzies(int32);
static void SetTotalNumberMissions(int32);
diff --git a/src/core/World.cpp b/src/core/World.cpp
index fb2dbad3..6d5e8a81 100644
--- a/src/core/World.cpp
+++ b/src/core/World.cpp
@@ -49,6 +49,7 @@ bool CWorld::bProcessCutsceneOnly;
bool CWorld::bDoingCarCollisions;
bool CWorld::bIncludeCarTyres;
+bool CWorld::bIncludeBikers;
CColPoint CWorld::m_aTempColPts[MAX_COLLISION_POINTS];
@@ -63,6 +64,7 @@ CWorld::Initialise()
bIncludeDeadPeds = false;
bForceProcessControl = false;
bIncludeCarTyres = false;
+ bIncludeBikers = false;
}
void
@@ -272,7 +274,9 @@ CWorld::ProcessLineOfSightSector(CSector &sector, const CColLine &line, CColPoin
{
float mindist = dist;
bool deadPeds = !!bIncludeDeadPeds;
+ bool bikers = !!bIncludeBikers;
bIncludeDeadPeds = false;
+ bIncludeBikers = false;
if(checkBuildings) {
ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_BUILDINGS], line, point, mindist, entity,
@@ -290,11 +294,13 @@ CWorld::ProcessLineOfSightSector(CSector &sector, const CColLine &line, CColPoin
if(checkPeds) {
if(deadPeds) bIncludeDeadPeds = true;
+ if(bikers) bIncludeBikers = true;
ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_PEDS], line, point, mindist, entity,
ignoreSeeThrough, false, ignoreShootThrough);
ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_PEDS_OVERLAP], line, point, mindist, entity,
ignoreSeeThrough, false, ignoreShootThrough);
bIncludeDeadPeds = false;
+ bIncludeBikers = false;
}
if(checkObjects) {
@@ -312,6 +318,7 @@ CWorld::ProcessLineOfSightSector(CSector &sector, const CColLine &line, CColPoin
}
bIncludeDeadPeds = deadPeds;
+ bIncludeBikers = bikers;
if(mindist < dist) {
dist = mindist;
@@ -325,22 +332,24 @@ CWorld::ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColP
CEntity *&entity, bool ignoreSeeThrough, bool ignoreSomeObjects, bool ignoreShootThrough)
{
bool deadPeds = false;
+ bool bikers = false;
float mindist = dist;
CPtrNode *node;
CEntity *e;
CColModel *colmodel;
if(list.first && bIncludeDeadPeds && ((CEntity *)list.first->item)->IsPed()) deadPeds = true;
+ if(list.first && bIncludeBikers && ((CEntity *)list.first->item)->IsPed()) bikers = true;
for(node = list.first; node; node = node->next) {
e = (CEntity *)node->item;
- if(e->m_scanCode != GetCurrentScanCode() && e != pIgnoreEntity && (e->bUsesCollision || deadPeds) &&
+ if(e->m_scanCode != GetCurrentScanCode() && e != pIgnoreEntity && (e->bUsesCollision || deadPeds || bikers) &&
!(ignoreSomeObjects && CameraToIgnoreThisObject(e))) {
colmodel = nil;
e->m_scanCode = GetCurrentScanCode();
if(e->IsPed()) {
- if(e->bUsesCollision || deadPeds && ((CPed *)e)->m_nPedState == PED_DEAD) {
+ if(e->bUsesCollision || deadPeds && ((CPed *)e)->m_nPedState == PED_DEAD || bikers) {
colmodel = ((CPedModelInfo *)CModelInfo::GetModelInfo(e->GetModelIndex()))->AnimatePedColModelSkinned(e->GetClump());
} else
colmodel = nil;
diff --git a/src/core/World.h b/src/core/World.h
index 8d539061..606a3466 100644
--- a/src/core/World.h
+++ b/src/core/World.h
@@ -71,6 +71,7 @@ public:
static bool bProcessCutsceneOnly;
static bool bDoingCarCollisions;
static bool bIncludeCarTyres;
+ static bool bIncludeBikers;
static CColPoint m_aTempColPts[MAX_COLLISION_POINTS];
static void Remove(CEntity *entity);
diff --git a/src/core/re3.cpp b/src/core/re3.cpp
index 0b80862e..1393314c 100644
--- a/src/core/re3.cpp
+++ b/src/core/re3.cpp
@@ -80,7 +80,7 @@ void WeaponCheat1();
void WeaponCheat2();
void WeaponCheat3();
void HealthCheat();
-void VehicleCheat(bool something, int model);
+void VehicleCheat(int model);
void BlowUpCarsCheat();
void ChangePlayerCheat();
void MayhemCheat();
@@ -353,7 +353,7 @@ DebugMenuPopulate(void)
DebugMenuAddCmd("Cheats", "Health", HealthCheat);
DebugMenuAddCmd("Cheats", "Wanted level up", WantedLevelUpCheat);
DebugMenuAddCmd("Cheats", "Wanted level down", WantedLevelDownCheat);
- DebugMenuAddCmd("Cheats", "Tank", []() { VehicleCheat(true, MI_TAXI); });
+ DebugMenuAddCmd("Cheats", "Tank", []() { VehicleCheat(MI_TAXI); });
DebugMenuAddCmd("Cheats", "Blow up cars", BlowUpCarsCheat);
DebugMenuAddCmd("Cheats", "Change player", ChangePlayerCheat);
DebugMenuAddCmd("Cheats", "Mayhem", MayhemCheat);
diff --git a/src/objects/Stinger.cpp b/src/objects/Stinger.cpp
new file mode 100644
index 00000000..f33125ee
--- /dev/null
+++ b/src/objects/Stinger.cpp
@@ -0,0 +1,232 @@
+#include "common.h"
+#include "Stinger.h"
+#include "CopPed.h"
+#include "ModelIndices.h"
+#include "RpAnimBlend.h"
+#include "World.h"
+#include "Automobile.h"
+#include "Bike.h"
+#include "Particle.h"
+#include "AnimBlendAssociation.h"
+#include "General.h"
+
+uint32 NumOfStingerSegments;
+
+/* -- CStingerSegment -- */
+
+CStingerSegment::CStingerSegment()
+{
+ m_fMass = 1.0f;
+ m_fTurnMass = 1.0f;
+ m_fAirResistance = 0.99999f;
+ m_fElasticity = 0.75f;
+ m_fBuoyancy = GRAVITY * m_fMass * 0.1f;
+ bExplosionProof = true;
+ SetModelIndex(MI_PLC_STINGER);
+ ObjectCreatedBy = ESCALATOR_OBJECT;
+ NumOfStingerSegments++;
+}
+
+CStingerSegment::~CStingerSegment()
+{
+ NumOfStingerSegments--;
+}
+
+/* -- CStinger -- */
+
+CStinger::CStinger()
+{
+ bIsDeployed = false;
+}
+
+void
+CStinger::Init(CPed *pPed)
+{
+ int32 i;
+
+ pOwner = pPed;
+ for (i = 0; i < NUM_STINGER_SEGMENTS; i++) {
+ pSpikes[i] = new CStingerSegment;
+ pSpikes[i]->bUsesCollision = false;
+ }
+ bIsDeployed = true;
+ m_vPos = pPed->GetPosition();
+ m_vPos.z -= 1.0f;
+ m_fMax_Z = Atan2(-pPed->GetForward().x, pPed->GetForward().y) + HALFPI;
+
+ for (i = 0; i < NUM_STINGER_SEGMENTS; i++) {
+ pSpikes[i]->SetOrientation(0.0f, 0.0f, Atan2(-pPed->GetForward().x, pPed->GetForward().y));
+ pSpikes[i]->SetPosition(m_vPos);
+ }
+
+ CVector2D fwd2d(pPed->GetForward().x, pPed->GetForward().y);
+
+ for (i = 0; i < ARRAY_SIZE(m_vPositions); i++)
+ m_vPositions[i] = fwd2d * 1.8f * Sin(DEGTORAD(i));
+
+ m_nSpikeState = STINGERSTATE_NONE;
+ m_nTimeOfDeploy = CTimer::GetTimeInMilliseconds();
+}
+
+void
+CStinger::Remove()
+{
+ if (!bIsDeployed) return;
+
+ for (int32 i = 0; i < NUM_STINGER_SEGMENTS; i++) {
+ CStingerSegment *spikeSegment = pSpikes[i];
+ if (spikeSegment->m_entryInfoList.first != nil)
+ spikeSegment->bRemoveFromWorld = true;
+ else
+ delete spikeSegment;
+ }
+ bIsDeployed = false;
+}
+
+void
+CStinger::Deploy(CPed *pPed)
+{
+ if (NumOfStingerSegments < NUM_STINGER_SEGMENTS*2 && !pPed->bInVehicle && pPed->IsPedInControl()) {
+ if (!bIsDeployed && RpAnimBlendClumpGetAssociation(pPed->GetClump(), ANIM_WEAPON_THROWU) == nil) {
+ Init(pPed);
+ pPed->SetPedState(PED_DEPLOY_STINGER);
+ CAnimManager::AddAnimation(pPed->GetClump(), ASSOCGRP_STD, ANIM_WEAPON_THROWU);
+ }
+ }
+}
+
+void
+CStinger::CheckForBurstTyres()
+{
+ CVector firstPos = pSpikes[0]->GetPosition();
+ firstPos.z += 0.2f;
+ CVector lastPos = pSpikes[NUM_STINGER_SEGMENTS - 1]->GetPosition();
+ lastPos.z += 0.2f;
+ float dist = (lastPos - firstPos).Magnitude();
+ if (dist < 0.1f) return;
+
+ CVehicle *vehsInRange[16];
+ int16 numObjects;
+ CEntity entity;
+
+ CWorld::FindObjectsInRange((lastPos + firstPos) / 2.0f,
+ dist, true, &numObjects, 15, (CEntity**)vehsInRange,
+ false, true, false, false, false);
+
+ for (int32 i = 0; i < numObjects; i++) {
+ CAutomobile *pAutomobile = nil;
+ CBike *pBike = nil;
+
+ if (vehsInRange[i]->IsCar())
+ pAutomobile = (CAutomobile*)vehsInRange[i];
+ else if (vehsInRange[i]->IsBike())
+ pBike = (CBike*)vehsInRange[i];
+
+ if (pAutomobile == nil && pBike == nil) continue;
+
+ float maxWheelDistToSpike = sq(((CVehicleModelInfo*)CModelInfo::GetModelInfo(vehsInRange[i]->GetModelIndex()))->m_wheelScale + 0.1f);
+
+ for (int wheelId = 0; wheelId < 4; wheelId++) {
+ if ((pAutomobile != nil && pAutomobile->m_aSuspensionSpringRatioPrev[wheelId] < 1.0f) ||
+ (pBike != nil && pBike->m_aSuspensionSpringRatioPrev[wheelId] < 1.0f)) {
+ CVector vecWheelPos;
+ if (pAutomobile != nil)
+ vecWheelPos = pAutomobile->m_aWheelColPoints[wheelId].point;
+ else if (pBike != nil)
+ vecWheelPos = pBike->m_aWheelColPoints[wheelId].point;
+
+ for (int32 spike = 0; spike < NUM_STINGER_SEGMENTS; spike++) {
+ if ((pSpikes[spike]->GetPosition() - vecWheelPos).Magnitude() < maxWheelDistToSpike) {
+ if (pBike) {
+ if (wheelId < 2)
+ vehsInRange[i]->BurstTyre(CAR_PIECE_WHEEL_LF, true);
+ else
+ vehsInRange[i]->BurstTyre(CAR_PIECE_WHEEL_LR, true);
+ }
+ else {
+ switch (wheelId) {
+ case 0: vehsInRange[i]->BurstTyre(CAR_PIECE_WHEEL_LF, true); break;
+ case 1: vehsInRange[i]->BurstTyre(CAR_PIECE_WHEEL_LR, true); break;
+ case 2: vehsInRange[i]->BurstTyre(CAR_PIECE_WHEEL_RF, true); break;
+ case 3: vehsInRange[i]->BurstTyre(CAR_PIECE_WHEEL_RR, true); break;
+ }
+ }
+ vecWheelPos.z += 0.15f;
+ for (int j = 0; j < 4; j++)
+ CParticle::AddParticle(PARTICLE_BULLETHIT_SMOKE, vecWheelPos, vehsInRange[i]->GetRight() * 0.1f);
+ }
+ }
+ }
+ }
+ }
+}
+
+void
+CStinger::Process()
+{
+ switch (m_nSpikeState)
+ {
+ case STINGERSTATE_NONE:
+ if (pOwner != nil
+ && !pOwner->bInVehicle
+ && pOwner->GetPedState() == PED_DEPLOY_STINGER
+ && RpAnimBlendClumpGetAssociation(pOwner->GetClump(), ANIM_WEAPON_THROWU)->currentTime > 0.39f)
+ {
+ m_nSpikeState = STINGERSTATE_DEPLOYING;
+ for (int i = 0; i < NUM_STINGER_SEGMENTS; i++)
+ CWorld::Add(pSpikes[i]);
+ pOwner->SetIdle();
+ }
+ break;
+ case STINGERSTATE_DEPLOYED:
+ if (pOwner != nil && pOwner->m_nPedType == PEDTYPE_COP)
+ ((CCopPed*)pOwner)->m_bThrowsSpikeTrap = false;
+ break;
+ case STINGERSTATE_UNDEPLOYING:
+ if (CTimer::GetTimeInMilliseconds() > m_nTimeOfDeploy + 2500)
+ m_nSpikeState = STINGERSTATE_REMOVE;
+ // no break
+ case STINGERSTATE_DEPLOYING:
+ if (m_nSpikeState == STINGERSTATE_DEPLOYING && CTimer::GetTimeInMilliseconds() > m_nTimeOfDeploy + 2500)
+ m_nSpikeState = STINGERSTATE_DEPLOYED;
+ else {
+ float progress = (CTimer::GetTimeInMilliseconds() - m_nTimeOfDeploy) / 2500.0f;
+ if (m_nSpikeState != STINGERSTATE_DEPLOYING)
+ progress = 1.0f - progress;
+
+ float degangle = progress * ARRAY_SIZE(m_vPositions);
+ float angle1 = m_fMax_Z + DEGTORAD(degangle);
+ float angle2 = m_fMax_Z - DEGTORAD(degangle);
+ int pos = clamp(degangle, 0, ARRAY_SIZE(m_vPositions)-1);
+
+ CVector2D pos2d = m_vPositions[pos];
+ CVector pos3d = m_vPos;
+ CColPoint colPoint;
+ CEntity *pEntity;
+ if (CWorld::ProcessVerticalLine(CVector(pos3d.x, pos3d.y, pos3d.z - 10.0f), pos3d.z, colPoint, pEntity, true, false, false, false, true, false, nil))
+ pos3d.z = colPoint.point.z + 0.15f;
+
+ angle1 = CGeneral::LimitRadianAngle(angle1);
+ angle2 = CGeneral::LimitRadianAngle(angle2);
+
+ for (int spike = 0; spike < NUM_STINGER_SEGMENTS; spike++) {
+ if (CWorld::TestSphereAgainstWorld(pos3d + CVector(pos2d.x, pos2d.y, 0.6f), 0.3f, nil, true, false, false, true, false, false))
+ pos2d = CVector2D(0.0f, 0.0f);
+
+ if (spike % 2 == 0) {
+ pSpikes[spike]->SetOrientation(0.0f, 0.0f, angle1);
+ pos3d.x += pos2d.x;
+ pos3d.y += pos2d.y;
+ } else {
+ pSpikes[spike]->SetOrientation(0.0f, 0.0f, angle2);
+ }
+ pSpikes[spike]->SetPosition(pos3d);
+ }
+ }
+ break;
+ case STINGERSTATE_REMOVE:
+ Remove();
+ break;
+ }
+ CheckForBurstTyres();
+} \ No newline at end of file
diff --git a/src/objects/Stinger.h b/src/objects/Stinger.h
new file mode 100644
index 00000000..250cf62d
--- /dev/null
+++ b/src/objects/Stinger.h
@@ -0,0 +1,40 @@
+#pragma once
+
+#include "Object.h"
+
+class CStingerSegment : public CObject
+{
+public:
+ CStingerSegment();
+ ~CStingerSegment();
+};
+
+#define NUM_STINGER_SEGMENTS (12)
+
+enum {
+ STINGERSTATE_NONE = 0,
+ STINGERSTATE_DEPLOYING,
+ STINGERSTATE_DEPLOYED,
+ STINGERSTATE_UNDEPLOYING,
+ STINGERSTATE_REMOVE,
+};
+
+class CStinger
+{
+public:
+ bool bIsDeployed;
+ uint32 m_nTimeOfDeploy;
+ CVector m_vPos;
+ float m_fMax_Z;
+ float m_fMin_Z;
+ CVector2D m_vPositions[60];
+ CStingerSegment *pSpikes[NUM_STINGER_SEGMENTS];
+ class CPed *pOwner;
+ uint8 m_nSpikeState;
+ CStinger();
+ void Init(CPed *pPed);
+ void Remove();
+ void Deploy(CPed *pPed);
+ void CheckForBurstTyres();
+ void Process();
+}; \ No newline at end of file
diff --git a/src/peds/CopPed.cpp b/src/peds/CopPed.cpp
index 6c9eb276..9160319b 100644
--- a/src/peds/CopPed.cpp
+++ b/src/peds/CopPed.cpp
@@ -18,6 +18,7 @@
#include "Camera.h"
#include "PedPlacement.h"
#include "Ropes.h"
+#include "Stinger.h"
CCopPed::CCopPed(eCopType copType, int32 modifier) : CPed(PEDTYPE_COP)
{
@@ -92,14 +93,17 @@ CCopPed::CCopPed(eCopType copType, int32 modifier) : CPed(PEDTYPE_COP)
m_nHassleTimer = 0;
field_61C = 0;
field_624 = 0;
+ m_pStinger = new CStinger;
if (m_pPointGunAt)
- m_pPointGunAt->CleanUpOldReference((CEntity**)&m_pPointGunAt);
+ m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt);
m_pPointGunAt = nil;
}
CCopPed::~CCopPed()
{
ClearPursuit();
+ m_pStinger->Remove();
+ delete m_pStinger;
}
// --MIAMI: Done
@@ -597,7 +601,7 @@ CCopPed::CopAI(void)
}
}
-// --MIAMI: Done except commented things
+// --MIAMI: Done
void
CCopPed::ProcessControl(void)
{
@@ -607,15 +611,13 @@ CCopPed::ProcessControl(void)
CPed::ProcessControl();
if (m_bThrowsSpikeTrap) {
- // TODO(Miami)
- /*
if (CGame::currArea != AREA_MALL)
ProcessStingerCop();
- */
return;
}
- // TODO(Miami): CStinger::Process
+ if (m_pStinger && m_pStinger->bIsDeployed && m_pStinger->m_nSpikeState == STINGERSTATE_DEPLOYED && CGame::currArea != AREA_MALL)
+ m_pStinger->Process();
if (bWasPostponed)
return;
@@ -854,4 +856,36 @@ CCopPed::ProcessHeliSwat(void)
SetInTheAir();
bKnockedUpIntoAir = true;
}
+}
+
+// --MIAMI: Done
+void
+CCopPed::ProcessStingerCop(void)
+{
+ if (m_pStinger->bIsDeployed || FindPlayerVehicle() && (FindPlayerVehicle()->IsCar() || FindPlayerVehicle()->IsBike())) {
+ if (m_pStinger->bIsDeployed) {
+ m_pStinger->Process();
+ } else {
+ CVector2D vehDist = GetPosition() - FindPlayerVehicle()->GetPosition();
+ CVector2D dirVehGoing = FindPlayerVehicle()->m_vecMoveSpeed;
+ if (vehDist.MagnitudeSqr() < sq(30.0f)) {
+ if (dirVehGoing.MagnitudeSqr() > 0.0f) {
+ vehDist.Normalise();
+ dirVehGoing.Normalise();
+ if (DotProduct2D(vehDist, dirVehGoing) > 0.8f) {
+ float angle = (CrossProduct2D(vehDist, dirVehGoing - vehDist) < 0.0f ?
+ FindPlayerVehicle()->GetForward().Heading() - HALFPI :
+ HALFPI + FindPlayerVehicle()->GetForward().Heading());
+
+ SetHeading(angle);
+ m_fRotationCur = angle;
+ m_fRotationDest = angle;
+ m_pStinger->Deploy(this);
+ }
+ }
+ }
+ }
+ } else {
+ ClearPursuit();
+ }
} \ No newline at end of file
diff --git a/src/peds/CopPed.h b/src/peds/CopPed.h
index edec145e..190d619e 100644
--- a/src/peds/CopPed.h
+++ b/src/peds/CopPed.h
@@ -30,6 +30,7 @@ public:
uintptr m_nRopeID;
uint32 m_nHassleTimer;
uint32 field_61C;
+ class CStinger *m_pStinger;
int32 field_624;
int8 field_628;
@@ -44,6 +45,7 @@ public:
void ScanForCrimes(void);
void CopAI(void);
void ProcessHeliSwat(void);
+ void ProcessStingerCop(void);
};
#ifndef PED_SKIN
diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp
index 0cc5eeaf..f197ae2c 100644
--- a/src/peds/Ped.cpp
+++ b/src/peds/Ped.cpp
@@ -65,6 +65,7 @@
#include "Bike.h"
#include "WindModifiers.h"
#include "CutsceneShadow.h"
+#include "Clock.h"
#define CAN_SEE_ENTITY_ANGLE_THRESHOLD DEGTORAD(60.0f)
@@ -145,6 +146,8 @@ void *CPed::operator new(size_t sz, int handle) { return CPools::GetPedPool()->N
void CPed::operator delete(void *p, size_t sz) { CPools::GetPedPool()->Delete((CPed*)p); }
void CPed::operator delete(void *p, int handle) { CPools::GetPedPool()->Delete((CPed*)p); }
+float gfTommyFatness = 1.0f;
+
// --MIAMI: Done
CPed::~CPed(void)
{
@@ -285,7 +288,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
m_fleeFromPosX = 0;
m_fleeFromPosY = 0;
m_fleeTimer = 0;
- pThreatEx = nil;
+ m_threatEx = nil;
m_vecSeekPosEx = CVector(0.0f, 0.0f, 0.0f);
m_distanceToCountSeekDoneEx = 0.0f;
m_nWaitState = WAITSTATE_FALSE;
@@ -422,8 +425,8 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
bHasAlreadyUsedAttractor = false;
b155_2 = false;
bCarPassenger = false;
- b155_8 = false;
- b155_10 = false;
+ bFleeWhenStanding = false;
+ bGotUpOfMyOwnAccord = false;
bMiamiViceCop = false;
bMoneyHasBeenGivenByScript = false;
bHasBeenPhotographed = false;
@@ -444,7 +447,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
bDoomAim = true;
bCanBeShotInVehicle = true;
bPushedAlongByCar = false;
- b157_40 = false;
+ bRemoveMeWhenIGotIntoCar = false;
bIgnoreThreatsBehindObjects = false;
bNeverEverTargetThisPed = false;
@@ -453,7 +456,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
b158_8 = false;
bCollectBusFare = false;
bBoughtIceCream = false;
- b158_40 = false;
+ bDonePositionOutOfCollision = false;
b158_80 = false;
if (CGeneral::GetRandomNumber() & 3)
@@ -462,9 +465,9 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
bHasACamera = true;
if (CGeneral::GetRandomNumberInRange(0.0f, 1.0f) <= 0.95f)
- b157_8 = false;
+ bCanGiveUpSunbathing = false;
else
- b157_8 = true;
+ bCanGiveUpSunbathing = true;
m_audioEntityId = DMAudio.CreateEntity(AUDIOTYPE_PHYSICAL, this);
DMAudio.SetEntityStatus(m_audioEntityId, 1);
@@ -2097,6 +2100,8 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
m_fRotationDest = veh->GetForward().Heading();
} else if (veh->bIsBus) {
m_fRotationDest = 0.5f * PI + veh->GetForward().Heading();
+ } else if (m_vehEnterType == CAR_WINDSCREEN) {
+ m_fRotationDest = veh->GetForward().Heading() + PI;
} else {
m_fRotationDest = veh->GetForward().Heading();
}
@@ -2317,7 +2322,6 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
if (seatPosMult > 0.2f || vehIsUpsideDown || veh->IsBike()) {
SetPosition(neededPos);
-
SetHeading(m_fRotationCur);
} else {
CMatrix vehDoorMat(veh->GetMatrix());
@@ -4082,7 +4086,7 @@ CPed::ClearAll(void)
m_fleeFromPosY = 0.0f;
m_fleeFrom = nil;
m_fleeTimer = 0;
- pThreatEx = nil;
+ m_threatEx = nil;
bUsesCollision = true;
ClearPointGunAt();
bIsPointingGunAt = false;
@@ -4181,6 +4185,7 @@ CPed::SetStoredState(void)
}
}
+// --MIAMI: Done
void
CPed::SetDie(AnimationId animId, float delta, float speed)
{
@@ -4196,6 +4201,7 @@ CPed::SetDie(AnimationId animId, float delta, float speed)
if (DyingOrDead())
return;
+ CAnimBlendAssociation *dieAssoc = nil;
if (m_nPedState == PED_FALL || m_nPedState == PED_GETUP)
delta *= 0.5f;
@@ -4203,7 +4209,7 @@ CPed::SetDie(AnimationId animId, float delta, float speed)
ClearAll();
m_fHealth = 0.0f;
if (m_nPedState == PED_DRIVING) {
- if (!IsPlayer())
+ if (!IsPlayer() && (!m_pMyVehicle || !m_pMyVehicle->IsBike()))
FlagToDestroyWhenNextProcessed();
} else if (bInVehicle) {
if (m_pVehicleAnim)
@@ -4212,11 +4218,11 @@ CPed::SetDie(AnimationId animId, float delta, float speed)
QuitEnteringCar();
}
- m_nPedState = PED_DIE;
+ SetPedState(PED_DIE);
if (animId == NUM_STD_ANIMS) {
bIsPedDieAnimPlaying = false;
} else {
- CAnimBlendAssociation *dieAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animId, delta);
+ dieAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animId, delta);
if (speed > 0.0f)
dieAssoc->speed = speed;
@@ -4230,10 +4236,17 @@ CPed::SetDie(AnimationId animId, float delta, float speed)
Say(SOUND_PED_DEATH);
if (m_nLastPedState == PED_ENTER_CAR || m_nLastPedState == PED_CARJACK)
QuitEnteringCar();
+
if (!bInVehicle)
StopNonPartialAnims();
m_bloodyFootprintCountOrDeathTime = CTimer::GetTimeInMilliseconds();
+ if (!CGame::nastyGame && animId == ANIM_FLOOR_HIT) {
+ if (dieAssoc) {
+ dieAssoc->SetCurrentTime(dieAssoc->hierarchy->totalLength - 0.01f);
+ dieAssoc->SetRun();
+ }
+ }
}
// --MIAMI: Done except commented things
@@ -4787,6 +4800,7 @@ CPed::ClearFall(void)
SetGetUp();
}
+// --MIAMI: Done
void
CPed::SetGetUp(void)
{
@@ -4809,7 +4823,7 @@ CPed::SetGetUp(void)
CVehicle *collidingVeh = (CVehicle*)m_pCollidingEntity;
CVehicle *veh = (CVehicle*)CPedPlacement::IsPositionClearOfCars(&GetPosition());
- if (veh && veh->m_vehType != VEHICLE_TYPE_BIKE ||
+ if (veh && veh->m_vehType != VEHICLE_TYPE_BIKE && veh != m_attachedTo ||
collidingVeh && collidingVeh->IsVehicle() && collidingVeh->m_vehType != VEHICLE_TYPE_BIKE
&& ((uint8)(CTimer::GetFrameCounter() + m_randomSeed + 5) % 8 ||
CCollision::ProcessColModels(GetMatrix(), *GetColModel(), collidingVeh->GetMatrix(), *collidingVeh->GetColModel(),
@@ -4829,6 +4843,7 @@ CPed::SetGetUp(void)
bGetUpAnimStarted = true;
m_pCollidingEntity = nil;
bKnockedUpIntoAir = false;
+ bKnockedOffBike = false;
CAnimBlendAssociation *animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_SPRINT);
if (animAssoc) {
if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN)) {
@@ -4839,12 +4854,21 @@ CPed::SetGetUp(void)
animAssoc->flags |= ASSOC_DELETEFADEDOUT;
}
- if (RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FRONTAL))
+ if (m_nWaitState == WAITSTATE_SUN_BATHE_IDLE) {
+ m_headingRate = 0.0f;
+
+ // TODO(Miami): Looks like that should've been another getup anim but R* forgot it. Visit here later
+ if (bFleeWhenStanding && m_threatEx)
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_GETUP1, 1000.0f);
+ else
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_GETUP1, 1000.0f);
+
+ } else if (RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FRONTAL))
animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_GETUP_FRONT, 1000.0f);
else
animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_GETUP1, 1000.0f);
- animAssoc->SetFinishCallback(PedGetupCB,this);
+ animAssoc->SetFinishCallback(PedGetupCB, this);
} else {
m_fHealth = 0.0f;
SetDie(NUM_STD_ANIMS, 4.0f, 0.0f);
@@ -6478,7 +6502,7 @@ CPed::SetFlee(CVector2D const &from, int time)
}
}
-// --MIAMI: Only some part is done
+// --MIAMI: Done
void
CPed::SetWaitState(eWaitState state, void *time)
{
@@ -6630,7 +6654,7 @@ CPed::SetWaitState(eWaitState state, void *time)
case WAITSTATE_SIT_DOWN:
animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_SEAT_DOWN, 4.0f);
animAssoc->SetFinishCallback(FinishedWaitCB, this);
- m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 10000;
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 100000;
break;
case WAITSTATE_SIT_UP:
animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_SEAT_UP, 4.0f);
@@ -6638,7 +6662,7 @@ CPed::SetWaitState(eWaitState state, void *time)
m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 100000;
break;
case WAITSTATE_SIT_IDLE:
- animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_SEAT_IDLE, 5000.0f);
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_SEAT_IDLE, 128.f);
animAssoc->SetFinishCallback(FinishedWaitCB, this);
if (time)
m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time;
@@ -6646,13 +6670,19 @@ CPed::SetWaitState(eWaitState state, void *time)
m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(25000, 30000);
break;
case WAITSTATE_USE_ATM:
- animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_ATM, 5000.0f);
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_ATM, 4.0f);
animAssoc->SetFinishCallback(FinishedWaitCB, this);
if (time)
m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time;
else
m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 100000;
break;
+ case WAITSTATE_SUN_BATHE_IDLE:
+ m_headingRate = 0.0f;
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_SUNBATHE, ANIM_SUNBATHE, 4.0f);
+ animAssoc->SetDeleteCallback(DeleteSunbatheIdleAnimCB, this);
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(50000, 100000);
+ break;
case WAITSTATE_FAST_FALL:
SetFall(-1, ANIM_KO_SKID_FRONT, true);
break;
@@ -6660,14 +6690,31 @@ CPed::SetWaitState(eWaitState state, void *time)
CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_BOMBER, 4.0f);
m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time;
break;
+ case WAITSTATE_GROUND_ATTACK:
+ {
+ CWeaponInfo* currentWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
+ if (!currentWeapon)
+ break;
+ if (GetFireAnimGround(currentWeapon, false)) {
+ if (!RpAnimBlendClumpGetAssociation(GetClump(), GetFireAnimGround(currentWeapon, false))) {
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 5000;
+ CAnimBlendAssociation* newAnim = CAnimManager::BlendAnimation(GetClump(),
+ currentWeapon->m_AnimToPlay, GetFireAnimGround(currentWeapon, false), 8.0f);
+ newAnim->SetDeleteCallback(FinishedWaitCB, this);
+ }
+ }
+ break;
+ }
case WAITSTATE_LANCESITTING:
CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_LANCE, ANIM_SUNBATHE, 4.0f);
break;
- case WAITSTATE_SUN_BATHE_PRE:
- case WAITSTATE_SUN_BATHE_DOWN:
- case WAITSTATE_SUN_BATHE_IDLE:
- case WAITSTATE_GROUND_ATTACK:
case WAITSTATE_PLAYANIM_HANDSUP_SIMPLE:
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_HANDSUP, 4.0f);
+ animAssoc->flags &= ~ASSOC_FADEOUTWHENDONE;
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ animAssoc->SetDeleteCallback(FinishedWaitCB, this);
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time;
+ break;
default:
ClearWaitState();
RestoreHeadingRate();
@@ -8374,7 +8421,7 @@ CPed::FinishedWaitCB(CAnimBlendAssociation *animAssoc, void *arg)
ped->Wait();
}
-// --MIAMI: Some part is done
+// --MIAMI: Done
void
CPed::Wait(void)
{
@@ -8575,28 +8622,24 @@ CPed::Wait(void)
} else if (m_pedStats->m_fear <= 100 - pedWeLook->m_pedStats->m_temper) {
if (GetWeapon()->IsTypeMelee()) {
-#ifdef VC_PED_PORTS
if(m_pedStats->m_flags & STAT_GUN_PANIC) {
-#endif
- SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE, m_pLookTarget);
- if (m_nPedState == PED_FLEE_ENTITY || m_nPedState == PED_FLEE_POS) {
+ SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE, m_pLookTarget);
+ if (m_nPedState == PED_FLEE_ENTITY || m_nPedState == PED_FLEE_POS) {
- bUsePedNodeSeek = true;
- m_pNextPathNode = nil;
- }
- if (m_nMoveState != PEDMOVE_RUN)
- SetMoveState(PEDMOVE_WALK);
+ bUsePedNodeSeek = true;
+ m_pNextPathNode = nil;
+ }
+ if (m_nMoveState != PEDMOVE_RUN)
+ SetMoveState(PEDMOVE_WALK);
- if (m_nPedType != PEDTYPE_COP) {
- ProcessObjective();
- SetMoveState(PEDMOVE_WALK);
- }
-#ifdef VC_PED_PORTS
+ if (m_nPedType != PEDTYPE_COP) {
+ ProcessObjective();
+ SetMoveState(PEDMOVE_WALK);
+ }
} else {
SetObjective(OBJECTIVE_NONE);
SetWanderPath(CGeneral::GetRandomNumberInRange(0.0f, 8.0f));
}
-#endif
} else {
SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, m_pLookTarget);
SetObjectiveTimer(20000);
@@ -8646,9 +8689,7 @@ CPed::Wait(void)
bBoughtIceCream = true;
}
ClearWaitState();
- }
-#ifdef VC_PED_PORTS
- else if (m_nWaitState == WAITSTATE_PLAYANIM_TAXI) {
+ } else if (m_nWaitState == WAITSTATE_PLAYANIM_TAXI) {
if (m_pedInObjective) {
if (m_objective == OBJECTIVE_GOTO_CHAR_ON_FOOT || m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT) {
@@ -8660,7 +8701,6 @@ CPed::Wait(void)
}
}
}
-#endif
break;
case WAITSTATE_FINISH_FLEE:
@@ -8689,7 +8729,14 @@ CPed::Wait(void)
if (m_attractor)
GetPedAttractorManager()->BroadcastDeparture(this, m_attractor);
ClearWaitState();
- //TODO(MIAMI): scan for threats!
+ if (bFleeWhenStanding) {
+ if (m_threatEx) {
+ SetFlee(m_threatEx, 10000);
+ bFleeWhenStanding = false;
+ m_threatEx = nil;
+ Say(SOUND_PED_FLEE_SPRINT);
+ }
+ }
}
break;
case WAITSTATE_SIT_IDLE:
@@ -8699,10 +8746,26 @@ CPed::Wait(void)
m_fRotationDest = m_fRotationCur;
bTurnedAroundOnAttractor = false;
}
- // TODO(MIAMI): scan for threats!
if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
ClearWaitState();
SetWaitState(WAITSTATE_SIT_UP, 0);
+ } else {
+ if (m_fleeFrom && m_fleeFrom->IsVehicle()) {
+ m_pNextPathNode = nil;
+ m_threatEx = m_threatEntity;
+ bFleeWhenStanding = true;
+ ClearWaitState();
+ SetWaitState(WAITSTATE_SIT_UP, 0);
+ } else {
+ uint32 threatFlag = ScanForThreats();
+ if (threatFlag == PED_FLAG_GUN || threatFlag == PED_FLAG_EXPLOSION || threatFlag == PED_FLAG_DEADPEDS) {
+ m_pNextPathNode = nil;
+ m_threatEx = m_threatEntity;
+ bFleeWhenStanding = true;
+ ClearWaitState();
+ SetWaitState(WAITSTATE_SIT_UP, 0);
+ }
+ }
}
break;
case WAITSTATE_USE_ATM:
@@ -8712,6 +8775,56 @@ CPed::Wait(void)
ClearWaitState();
}
break;
+ case WAITSTATE_SUN_BATHE_IDLE:
+ if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer && bCanGiveUpSunbathing) {
+ m_pNextPathNode = nil;
+ bGotUpOfMyOwnAccord = true;
+ SetGetUp();
+ ClearWaitState();
+
+ } else if (CWeather::Rain <= 0.1f) {
+ if (CClock::GetHours() <= 18 || CGeneral::GetRandomNumberInRange(0.f, 1.0f) < 0.005f) {
+ uint32 threatFlag = ScanForThreats();
+ if (threatFlag == PED_FLAG_GUN || threatFlag == PED_FLAG_EXPLOSION || threatFlag == PED_FLAG_DEADPEDS) {
+ // Get up in case of danger
+ m_pNextPathNode = nil;
+ m_threatEx = m_threatEntity;
+ bFleeWhenStanding = true;
+ SetGetUp();
+ ClearWaitState();
+ }
+ CPlayerPed *player = FindPlayerPed();
+ if (player) {
+ // Get up if player coming towards us with a car
+ if (player->InVehicle()){
+ CVector vehSpeedPerSec = player->m_pMyVehicle->m_vecMoveSpeed * GAME_SPEED_TO_METERS_PER_SECOND;
+ CVector vehPos = player->m_pMyVehicle->GetPosition();
+ CVector ourPos = GetPosition();
+ float timeUntilVehReachPed = DotProduct(ourPos - vehPos, vehSpeedPerSec) / vehSpeedPerSec.MagnitudeSqr();
+ if (timeUntilVehReachPed > 0.0 && timeUntilVehReachPed < 8.0f) {
+ if ((ourPos - (timeUntilVehReachPed * vehSpeedPerSec + vehPos)).Magnitude() < 5.0f) {
+ m_pNextPathNode = nil;
+ m_threatEx = player;
+ bFleeWhenStanding = true;
+ SetGetUp();
+ ClearWaitState();
+ }
+ }
+ }
+ }
+ } else {
+ m_pNextPathNode = nil;
+ bGotUpOfMyOwnAccord = true;
+ SetGetUp();
+ ClearWaitState();
+ }
+ } else {
+ m_pNextPathNode = nil;
+ bGotUpOfMyOwnAccord = true;
+ SetGetUp();
+ ClearWaitState();
+ }
+ break;
case WAITSTATE_RIOT:
if (m_nPedState == PED_FLEE_ENTITY || m_nPedState == PED_ATTACK) {
ClearWaitState();
@@ -8741,11 +8854,10 @@ CPed::Wait(void)
case WAITSTATE_STRIPPER:
PlayRandomAnimationsFromAnimBlock(this, ASSOCGRP_STRIP, ANIM_STRIP_A, ANIM_STRIP_G - ANIM_STRIP_A + 1);
break;
- case WAITSTATE_SUN_BATHE_PRE:
- case WAITSTATE_SUN_BATHE_DOWN:
- case WAITSTATE_SUN_BATHE_IDLE:
case WAITSTATE_PLAYANIM_HANDSUP_SIMPLE:
- assert(0);
+ if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer)
+ ClearWaitState();
+ break;
default:
break;
}
@@ -9522,6 +9634,7 @@ CPed::SetLanding(void)
bIsLanding = true;
}
+// --MIAMI: Done
void
CPed::Initialise(void)
{
@@ -9694,6 +9807,7 @@ CPed::SetAnimOffsetForEnterOrExitVehicle(void)
CAnimManager::RemoveAnimBlockRef(bikedBlock);
}
+// --MIAMI: Done
void
CPed::InvestigateEvent(void)
{
@@ -9707,7 +9821,7 @@ CPed::InvestigateEvent(void)
if (CTimer::GetTimeInMilliseconds() > m_standardTimer) {
if (m_standardTimer) {
- if (m_eventType < EVENT_ASSAULT_NASTYWEAPON)
+ if (m_eventType < EVENT_UNK)
SetWaitState(WAITSTATE_TURN180, nil);
m_standardTimer = 0;
@@ -9761,13 +9875,14 @@ CPed::InvestigateEvent(void)
animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_STANCE);
if (animAssoc && animAssoc->animId == ANIM_IDLE_CAM) {
- CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 14.0f);
+ CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f);
SetLookTimer(CGeneral::GetRandomNumberInRange(1000, 2500));
} else if (CGeneral::GetRandomNumber() & 3) {
CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_CAM, 4.0f);
SetLookTimer(CGeneral::GetRandomNumberInRange(2500, 5000));
- Say(SOUND_PED_CHAT_EVENT);
+ if (!CGame::germanGame)
+ Say(SOUND_PED_CHAT_EVENT);
} else {
m_standardTimer = 0;
@@ -9788,7 +9903,7 @@ CPed::InvestigateEvent(void)
animToPlay = ANIM_XPRESS_SCRATCH;
CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animToPlay, 4.0f);
- SetLookTimer(CGeneral::GetRandomNumberInRange(1000, 2500));
+ SetLookTimer(CGeneral::GetRandomNumberInRange(1500, 4000));
} else if (animAssoc && animAssoc->animId == ANIM_IDLE_HBHB) {
animAssoc->blendDelta = -8.0f;
@@ -9816,7 +9931,8 @@ CPed::InvestigateEvent(void)
CAnimManager::BlendAnimation(GetClump(), animGroup, animToPlay, 4.0f);
SetLookTimer(CGeneral::GetRandomNumberInRange(1000, 2500));
}
- Say(SOUND_PED_CHAT_EVENT);
+ if (!CGame::germanGame)
+ Say(SOUND_PED_CHAT_EVENT);
}
break;
case EVENT_ICECREAM:
@@ -9878,19 +9994,22 @@ CPed::InvestigateEvent(void)
SetMoveState(PEDMOVE_WALK);
return;
}
- if (distSqr > 1.44f) {
+ if (distSqr > sq(1.2f)) {
SetMoveState(PEDMOVE_WALK);
return;
}
+ bool willStandStill = false;
for (int i = 0; i < m_numNearPeds; i++) {
if ((m_eventOrThreat - m_nearPeds[i]->GetPosition()).MagnitudeSqr() < sq(0.4f)) {
SetMoveState(PEDMOVE_STILL);
- return;
+ willStandStill = true;
+ break;
}
}
- SetMoveState(PEDMOVE_WALK);
+ if (!willStandStill)
+ SetMoveState(PEDMOVE_WALK);
}
}
@@ -10184,12 +10303,12 @@ CPed::Look(void)
TurnBody();
}
+// --MIAMI: Done
bool
CPed::LookForInterestingNodes(void)
{
CBaseModelInfo *model;
CPtrNode *ptrNode;
- CVector effectPos;
CVector effectDist;
C2dEffect *effect;
CMatrix *objMat;
@@ -10230,7 +10349,7 @@ CPed::LookForInterestingNodes(void)
effect = model->Get2dEffect(e);
if (effect->type == EFFECT_ATTRACTOR && effect->attractor.probability >= randVal) {
objMat = &veh->GetMatrix();
- effectPos = veh->GetMatrix() * effect->pos;
+ CVector effectPos = veh->GetMatrix() * effect->pos;
effectDist = effectPos - GetPosition();
if (effectDist.MagnitudeSqr() < sq(8.0f)) {
found = true;
@@ -10248,7 +10367,7 @@ CPed::LookForInterestingNodes(void)
effect = model->Get2dEffect(e);
if (effect->type == EFFECT_ATTRACTOR && effect->attractor.probability >= randVal) {
objMat = &obj->GetMatrix();
- effectPos = obj->GetMatrix() * effect->pos;
+ CVector effectPos = obj->GetMatrix() * effect->pos;
effectDist = effectPos - GetPosition();
if (effectDist.MagnitudeSqr() < sq(8.0f)) {
found = true;
@@ -10266,7 +10385,7 @@ CPed::LookForInterestingNodes(void)
effect = model->Get2dEffect(e);
if (effect->type == EFFECT_ATTRACTOR && effect->attractor.probability >= randVal) {
objMat = &building->GetMatrix();
- effectPos = building->GetMatrix() * effect->pos;
+ CVector effectPos = building->GetMatrix() * effect->pos;
effectDist = effectPos - GetPosition();
if (effectDist.MagnitudeSqr() < sq(8.0f)) {
found = true;
@@ -10284,7 +10403,7 @@ CPed::LookForInterestingNodes(void)
effect = model->Get2dEffect(e);
if (effect->type == EFFECT_ATTRACTOR && effect->attractor.probability >= randVal) {
objMat = &building->GetMatrix();
- effectPos = building->GetMatrix() * effect->pos;
+ CVector effectPos = building->GetMatrix() * effect->pos;
effectDist = effectPos - GetPosition();
if (effectDist.MagnitudeSqr() < sq(8.0f)) {
found = true;
@@ -10310,12 +10429,13 @@ CPed::LookForInterestingNodes(void)
return false;
}
+ CVector2D effectPos = *objMat * effect->pos;
switch (effect->attractor.type) {
case ATTRACTORTYPE_ICECREAM:
- SetInvestigateEvent(EVENT_ICECREAM, CVector2D(effectPos), 0.1f, 15000, angleToFace);
+ SetInvestigateEvent(EVENT_ICECREAM, effectPos, 0.1f, 15000, angleToFace);
break;
case ATTRACTORTYPE_STARE:
- SetInvestigateEvent(EVENT_SHOPSTALL, CVector2D(effectPos), 1.0f,
+ SetInvestigateEvent(EVENT_SHOPSTALL, effectPos, 1.0f,
CGeneral::GetRandomNumberInRange(8000, 10 * effect->attractor.probability + 8500),
angleToFace);
break;
@@ -10325,6 +10445,7 @@ CPed::LookForInterestingNodes(void)
return true;
}
+// --MIAMI: Done
void
CPed::SetInvestigateEvent(eEventType event, CVector2D pos, float distanceToCountDone, uint16 time, float angle)
{
@@ -10333,7 +10454,7 @@ CPed::SetInvestigateEvent(eEventType event, CVector2D pos, float distanceToCount
SetStoredState();
bFindNewNodeAfterStateRestore = false;
- m_nPedState = PED_INVESTIGATE;
+ SetPedState(PED_INVESTIGATE);
m_standardTimer = CTimer::GetTimeInMilliseconds() + time;
m_eventType = event;
m_eventOrThreat = pos;
@@ -10861,7 +10982,7 @@ CPed::ProcessControl(void)
CVisibilityPlugins::SetClumpAlpha(GetClump(), alpha);
bIsShooting = false;
- b158_40 = false;
+ bDonePositionOutOfCollision = false;
BuildPedLists();
bIsInWater = false;
bIsDrowning = false;
@@ -13017,8 +13138,8 @@ CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg)
}
}
- if (ped->b157_40) {
- ped->b157_40 = false;
+ if (ped->bRemoveMeWhenIGotIntoCar) {
+ ped->bRemoveMeWhenIGotIntoCar = false;
ped->bRemoveFromWorld = true;
}
if (ped->bCollectBusFare) {
@@ -13435,6 +13556,7 @@ CPed::ReactToPointGun(CEntity *entWithGun)
}
}
+// --MIAMI: Done
void
CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg)
{
@@ -13458,8 +13580,17 @@ CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg)
}
ped->bInVehicle = false;
- if (veh && (veh->IsCar() || veh->IsBike()) && !veh->IsRoomForPedToLeaveCar(ped->m_vehEnterType, nil)) {
- ped->PositionPedOutOfCollision();
+ if (veh && (veh->IsCar() || veh->IsBike())) {
+ CWorld::pIgnoreEntity = veh;
+ if (CWorld::TestSphereAgainstWorld(ped->GetPosition() - CVector(0.f, 0.f, 0.2f),
+ 0.4f, veh, true, true, false, false, false, false)
+ || CWorld::TestSphereAgainstWorld(ped->GetPosition() + CVector(0.f, 0.f, 0.2f),
+ 0.4f, veh, true, true, false, false, false, false)
+ || !CWorld::GetIsLineOfSightClear(veh->GetPosition(), ped->GetPosition(), true, false, false, true, false, false, false)) {
+ CWorld::pIgnoreEntity = nil;
+ ped->PositionPedOutOfCollision();
+ }
+ CWorld::pIgnoreEntity = nil;
}
if (ped->m_nPedState == PED_EXIT_CAR) {
@@ -13543,6 +13674,7 @@ CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg)
}
}
}
+ // NB: Probably VC doesn't use a function for that, so it's GetBikeDoorFlag doesn't check for CAR_WINDSCREEN
if (veh && veh->IsBike())
veh->m_nGettingOutFlags &= ~GetBikeDoorFlag(ped->m_vehEnterType);
else
@@ -13555,6 +13687,11 @@ CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg)
veh->m_nDoorLock = CARLOCK_UNLOCKED;
if (ped->m_nPedType == PEDTYPE_COP && veh->IsLawEnforcementVehicle())
veh->ChangeLawEnforcerState(false);
+ if (veh->IsBike()) {
+ if (Abs(veh->m_vecMoveSpeed.x) < 0.1 && Abs(veh->m_vecMoveSpeed.y) < 0.1f) {
+ ((CBike*)veh)->bIsStanding = true;
+ }
+ }
} else {
veh->RemovePassenger(ped);
}
@@ -13818,6 +13955,146 @@ CPed::PedSetQuickDraggedOutCarPositionCB(CAnimBlendAssociation *animAssoc, void
bool
CPed::PositionPedOutOfCollision(void)
{
+ CVehicle *veh = m_pMyVehicle;
+ if (!veh)
+ return false;
+
+ if (bDonePositionOutOfCollision)
+ return true;
+
+ bool foundAPos = false;
+ CColModel *vehCol = veh->GetColModel();
+ CVector vehPos = veh->GetPosition();
+ CVector ourPos = GetPosition();
+ CVector newPos = ourPos;
+ CWorld::pIgnoreEntity = veh;
+ bUsesCollision = false;
+ bJustCheckCollision = true;
+ m_vecMoveSpeed = CVector(0.f, 0.f, 0.f);
+ if (veh->IsOnItsSide()) {
+ // Top of the veh.
+ newPos = vehPos;
+ newPos.z = FEET_OFFSET + vehCol->boundingBox.max.x + vehPos.z;
+ GetMatrix().SetTranslate(newPos);
+ if (!CheckCollision()) {
+ if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false))
+ foundAPos = true;
+ }
+
+ } else if (m_vehEnterType != 0) {
+ // Try the normal way
+ CVector pos = GetPositionToOpenCarDoor(m_pMyVehicle, m_vehEnterType);
+ newPos = pos;
+ GetMatrix().SetTranslate(newPos);
+ if (!CheckCollision()) {
+ if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false))
+ foundAPos = true;
+ }
+ }
+
+ float vehRelativeExitX = vehCol->boundingBox.min.x - 0.355f;
+ if (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR)
+ vehRelativeExitX = 0.355f + vehCol->boundingBox.max.x;
+
+ if (!foundAPos) {
+ // Check sides of veh., respective to seat column-veh. center difference(why?)
+ float exitOffset = vehRelativeExitX - DotProduct(ourPos - vehPos, veh->GetRight());
+ newPos = exitOffset * veh->GetRight() + ourPos;
+ GetMatrix().SetTranslate(newPos);
+ if (!CheckCollision()) {
+ if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false))
+ foundAPos = true;
+ }
+ }
+ if (!foundAPos) {
+ // Iterate through sections of veh. length + static offset on X
+ float minY = vehCol->boundingBox.min.y;
+ float ySection = (vehCol->boundingBox.max.y - minY) / 3.f;
+ for (int i = 0; i < 4; i++) {
+ float fwdMult = i * ySection + minY;
+ newPos = vehRelativeExitX * veh->GetRight() + fwdMult * veh->GetForward() + vehPos;
+ GetMatrix().SetTranslate(newPos);
+ if (!CheckCollision()) {
+ if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false)) {
+ foundAPos = true;
+ break;
+ }
+ }
+ }
+ }
+ if (!foundAPos) {
+ // Back of veh.
+ newPos = (vehCol->boundingBox.min.y - 0.355f) * veh->GetForward() + vehPos;
+ GetMatrix().SetTranslate(newPos);
+ if (!CheckCollision()) {
+ if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false))
+ foundAPos = true;
+ }
+ }
+ if (!foundAPos) {
+ // Front of veh.
+ newPos = (0.355f + vehCol->boundingBox.max.y) * veh->GetForward() + vehPos;
+ GetMatrix().SetTranslate(newPos);
+ if (!CheckCollision()) {
+ if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false))
+ foundAPos = true;
+ }
+ }
+ if (!foundAPos) {
+ // Opposite X side + back
+ newPos = vehCol->boundingBox.min.y * veh->GetForward() + vehPos - vehRelativeExitX * veh->GetRight();
+ GetMatrix().SetTranslate(newPos);
+ if (!CheckCollision()) {
+ if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false))
+ foundAPos = true;
+ }
+ }
+ if (!foundAPos) {
+ // Opposite X side + front
+ newPos = vehCol->boundingBox.max.y * veh->GetForward() + vehPos - vehRelativeExitX * veh->GetRight();
+ GetMatrix().SetTranslate(newPos);
+ if (!CheckCollision()) {
+ if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false))
+ foundAPos = true;
+ }
+ }
+ if (!foundAPos) {
+ // Top of veh.
+ if (veh->m_vehType == 0) {
+ newPos = vehCol->boundingBox.max.z * veh->GetUp() + vehPos;
+ newPos.z += FEET_OFFSET;
+ GetMatrix().SetTranslate(newPos);
+ if (!CheckCollision()) {
+ if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false))
+ foundAPos = true;
+ }
+ }
+ }
+ m_vecMoveSpeed = CVector(0.f, 0.f, 0.f);
+ m_vecTurnSpeed = CVector(0.f, 0.f, 0.f);
+ veh->m_vecMoveSpeed = CVector(0.f, 0.f, 0.f);
+ veh->m_vecTurnSpeed = CVector(0.f, 0.f, 0.f);
+ CWorld::pIgnoreEntity = nil;
+ bUsesCollision = true;
+ bJustCheckCollision = false;
+ bDonePositionOutOfCollision = true;
+ if (foundAPos)
+ return true;
+ int foundNode = ThePaths.FindNodeClosestToCoors(vehPos, PATH_PED, 999999.9f, true, false, false, false);
+ if (foundNode < 0)
+ return false;
+ newPos = ThePaths.m_pathNodes[foundNode].GetPosition();
+ CPedPlacement::FindZCoorForPed(&newPos);
+ GetMatrix().SetTranslate(newPos);
+ SetHeading(m_pMyVehicle->GetForward().Heading());
+ return true;
+}
+
+// --MIAMI: Done
+// "Any" means he shouldn't have to be in vehicle.
+bool
+CPed::PositionAnyPedOutOfCollision(void)
+{
CVehicle *veh;
CVector posNearVeh;
CVector posSomewhereClose;
@@ -13826,9 +14103,6 @@ CPed::PositionPedOutOfCollision(void)
int smallestDistNearVeh = 999;
int smallestDistSomewhereClose = 999;
- if (!m_pMyVehicle)
- return false;
-
CVector vehPos = m_pMyVehicle->GetPosition();
CVector potentialPos;
potentialPos.y = GetPosition().y - 3.5f;
@@ -13839,15 +14113,7 @@ CPed::PositionPedOutOfCollision(void)
for (int xTry = 0; xTry < 15; xTry++) {
CPedPlacement::FindZCoorForPed(&potentialPos);
- CVector distVec = potentialPos - vehPos;
- float dist = distVec.Magnitude();
-
- // Makes close distances bigger for some reason.
- float mult = (0.6f + dist) / dist;
- CVector adjustedPotentialPos = distVec * mult + vehPos;
- if (CWorld::GetIsLineOfSightClear(vehPos, adjustedPotentialPos, true, false, false, true, false, false, false)
- && !CWorld::TestSphereAgainstWorld(potentialPos, 0.6f, this, true, false, false, true, false, false)) {
-
+ if (!CWorld::TestSphereAgainstWorld(potentialPos, 0.6f, this, true, false, false, true, false, false)) {
float potentialChangeSqr = (potentialPos - GetPosition()).MagnitudeSqr();
veh = (CVehicle*)CWorld::TestSphereAgainstWorld(potentialPos, 0.6f, this, false, true, false, false, false, false);
if (veh) {
@@ -13881,6 +14147,7 @@ CPed::PositionPedOutOfCollision(void)
return true;
}
+// --MIAMI: Done
bool
CPed::PossiblyFindBetterPosToSeekCar(CVector *pos, CVehicle *veh)
{
@@ -14060,6 +14327,7 @@ CPed::Render(void)
}
}
+// --MIAMI: Done
void
CPed::ProcessObjective(void)
{
@@ -14097,15 +14365,6 @@ CPed::ProcessObjective(void)
}
switch (m_objective) {
- case OBJECTIVE_NONE:
- case OBJECTIVE_GUARD_AREA:
- case OBJECTIVE_FOLLOW_CAR_IN_CAR:
- case OBJECTIVE_FIRE_AT_OBJECT_FROM_VEHICLE:
- case OBJECTIVE_DESTROY_OBJECT:
- case OBJECTIVE_GOTO_AREA_IN_CAR:
- case OBJECTIVE_FOLLOW_CAR_ON_FOOT_WITH_OFFSET:
- case OBJECTIVE_SET_LEADER:
- break;
case OBJECTIVE_WAIT_ON_FOOT:
if (GetPedState() == PED_DRIVING)
m_objective = OBJECTIVE_NONE;
@@ -14190,7 +14449,7 @@ CPed::ProcessObjective(void)
{
if (m_pedInObjective) {
if (m_pedInObjective->IsPlayer() && CharCreatedBy != MISSION_CHAR
- && m_nPedType != PEDTYPE_COP && FindPlayerPed()->m_pWanted->m_CurrentCops
+ && m_nPedType != PEDTYPE_COP && FindPlayerPed()->m_pWanted->m_CurrentCops != 0
&& !bKindaStayInSamePlace) {
SetObjective(OBJECTIVE_FLEE_ON_FOOT_TILL_SAFE);
@@ -14230,7 +14489,7 @@ CPed::ProcessObjective(void)
float closestVehDist = 60.0f;
int16 lastVehicle;
CEntity* vehicles[8];
- CWorld::FindObjectsInRange(GetPosition(), 30.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
+ CWorld::FindObjectsInRange(GetPosition(), ENTER_CAR_MAX_DIST, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
CVehicle *foundVeh = nil;
for(int i = 0; i < lastVehicle; i++) {
CVehicle *nearVeh = (CVehicle*)vehicles[i];
@@ -14303,7 +14562,6 @@ CPed::ProcessObjective(void)
SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
break;
}
-
if (!m_pedInObjective || m_pedInObjective->DyingOrDead()) {
bObjectiveCompleted = true;
ClearLookFlag();
@@ -14553,7 +14811,7 @@ CPed::ProcessObjective(void)
if (m_carInObjective && m_carInObjective->m_fHealth > 0.0f) {
distWithTarget = m_carInObjective->GetPosition() - GetPosition();
if (!bInVehicle) {
- if (nEnterCarRangeMultiplier * 30.0f < distWithTarget.Magnitude()) {
+ if (nEnterCarRangeMultiplier * ENTER_CAR_MAX_DIST < distWithTarget.Magnitude()) {
if (!m_carInObjective->pDriver && !m_carInObjective->GetIsOnScreen() && !GetIsOnScreen())
WarpPedToNearEntityOffScreen(m_carInObjective);
@@ -14579,6 +14837,15 @@ CPed::ProcessObjective(void)
}
break;
}
+ case OBJECTIVE_DESTROY_OBJECT:
+ if (m_pPointGunAt) {
+ if (m_nPedState != PED_ATTACK)
+ SetAttack(m_pPointGunAt);
+ } else {
+ bScriptObjectiveCompleted = true;
+ RestorePreviousObjective();
+ }
+ break;
case OBJECTIVE_DESTROY_CAR:
{
if (!m_carInObjective) {
@@ -14602,9 +14869,7 @@ CPed::ProcessObjective(void)
break;
}
- if (m_attackTimer < CTimer::GetTimeInMilliseconds() && wepInfo->m_eWeaponFire != WEAPON_FIRE_MELEE
- && distWithTargetSc < wepRange) {
-
+ if (m_attackTimer < CTimer::GetTimeInMilliseconds() && distWithTargetSc < wepRange) {
// I hope so
CVector ourHead = GetMatrix() * CVector(0.5f, 0.0f, 0.6f);
CVector maxShotPos = m_carInObjective->GetPosition() - ourHead;
@@ -14619,6 +14884,8 @@ CPed::ProcessObjective(void)
CWorld::bIncludeDeadPeds = false;
if (foundEnt == m_carInObjective) {
SetAttack(m_carInObjective);
+ if (m_pPointGunAt)
+ m_pPointGunAt->CleanUpOldReference((CEntity**)&m_pPointGunAt);
m_pPointGunAt = m_carInObjective;
if (m_pPointGunAt)
m_pPointGunAt->RegisterReference((CEntity **) &m_pPointGunAt);
@@ -14632,75 +14899,30 @@ CPed::ProcessObjective(void)
}
}
} else if (m_nPedState != PED_ATTACK && !bKindaStayInSamePlace) {
+ if (wepRange <= 5.0f) {
+ if (Abs(distWithTarget.x) > wepRange || Abs(distWithTarget.y) > wepRange ||
+ (distWithTarget.z > -1.0f && distWithTarget.z < 0.3)) {
+ SetSeek(m_carInObjective, 3.0f);
+ SetMoveState(PEDMOVE_RUN);
+ } else {
+ SetIdle();
+ }
+ } else {
+ float safeDistance = wepRange * 0.25f;
- float safeDistance;
- if (wepRange <= 5.0f)
- safeDistance = 3.0f;
- else
- safeDistance = wepRange * 0.25f;
-
- SetSeek(m_carInObjective, safeDistance);
- SetMoveState(PEDMOVE_RUN);
+ SetSeek(m_carInObjective, safeDistance);
+ SetMoveState(PEDMOVE_RUN);
+ }
}
SetLookFlag(m_carInObjective, false);
TurnBody();
break;
}
- case OBJECTIVE_GOTO_AREA_ANY_MEANS:
- {
- distWithTarget = m_nextRoutePointPos - GetPosition();
- distWithTarget.z = 0.0f;
- if (InVehicle()) {
- CCarAI::GetCarToGoToCoors(m_pMyVehicle, &m_nextRoutePointPos);
- CCarCtrl::RegisterVehicleOfInterest(m_pMyVehicle);
- if (distWithTarget.MagnitudeSqr() < sq(20.0f)) {
- m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0;
- ForceStoredObjective(OBJECTIVE_GOTO_AREA_ANY_MEANS);
- SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
- }
- break;
- }
- if (distWithTarget.Magnitude() > 30.0f) {
- if (m_pMyVehicle) {
- m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0;
- } else {
- float closestVehDist = SQR(60.0f);
- int16 lastVehicle;
- CEntity* vehicles[8];
- CWorld::FindObjectsInRange(GetPosition(), 25.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
- CVehicle* foundVeh = nil;
- for (int i = 0; i < lastVehicle; i++) {
- CVehicle* nearVeh = (CVehicle*)vehicles[i];
- /*
- Not used.
- CVector vehSpeed = nearVeh->GetSpeed();
- CVector ourSpeed = GetSpeed();
- */
- CVector vehDistVec = nearVeh->GetPosition() - GetPosition();
- if (vehDistVec.MagnitudeSqr() < closestVehDist
- && m_pedInObjective->m_pMyVehicle != nearVeh)
- {
- foundVeh = nearVeh;
- closestVehDist = vehDistVec.MagnitudeSqr();
- }
- }
- m_pMyVehicle = foundVeh;
- if (m_pMyVehicle) {
- m_pMyVehicle->RegisterReference((CEntity **) &m_pMyVehicle);
- m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0;
- SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, m_pMyVehicle);
- }
- }
- break;
- }
- // fall through
- }
case OBJECTIVE_GOTO_AREA_ON_FOOT:
case OBJECTIVE_RUN_TO_AREA:
case OBJECTIVE_SPRINT_TO_AREA:
{
- if ((m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT || m_objective == OBJECTIVE_RUN_TO_AREA || m_objective == OBJECTIVE_SPRINT_TO_AREA)
- && InVehicle()) {
+ if (InVehicle()) {
SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
} else {
distWithTarget = m_nextRoutePointPos - GetPosition();
@@ -14717,7 +14939,6 @@ CPed::ProcessObjective(void)
if (!m_pNextPathNode) {
bool found = FindBestCoordsFromNodes(m_vecSeekPos, &bestCoords);
if (m_pNextPathNode) {
-
// Because it already does that if it finds better coords.
if (!found) {
bestCoords = CPathFind::TakeWidthIntoAccountForWandering(m_pNextPathNode, m_randomSeed);
@@ -14731,6 +14952,7 @@ CPed::ProcessObjective(void)
if (m_pNextPathNode)
m_vecSeekPos = CPathFind::TakeWidthIntoAccountForWandering(m_pNextPathNode, m_randomSeed);
}
+ CVector seekPos = m_vecSeekPos;
SetSeek(m_vecSeekPos, m_distanceToCountSeekDone);
}
}
@@ -14767,7 +14989,8 @@ CPed::ProcessObjective(void)
int nextPoint = GetNextPointOnRoute();
m_nextRoutePointPos = CRouteNode::GetPointPosition(nextPoint);
} else {
- SetSeek(m_nextRoutePointPos, 0.8f);
+ CVector seekPos = m_nextRoutePointPos;
+ SetSeek(seekPos, 0.8f);
}
break;
case OBJECTIVE_SOLICIT_VEHICLE:
@@ -14831,31 +15054,27 @@ CPed::ProcessObjective(void)
}
case OBJECTIVE_BUY_ICE_CREAM:
if (m_carInObjective) {
- if (m_nPedState != PED_FLEE_ENTITY && m_nPedState != PED_BUY_ICECREAM)
+ if (m_nPedState != PED_FLEE_ENTITY && m_nPedState != PED_BUY_ICECREAM && m_nPedState != PED_CHAT)
SetSeekCar(m_carInObjective, 0);
- } else {
- RestorePreviousObjective();
- RestorePreviousState();
- if (IsPedInControl())
- m_pMyVehicle = nil;
}
break;
case OBJECTIVE_STEAL_ANY_CAR:
+ case OBJECTIVE_STEAL_ANY_MISSION_CAR:
{
if (bInVehicle) {
bScriptObjectiveCompleted = true;
RestorePreviousObjective();
} else if (m_hitRecoverTimer < CTimer::GetTimeInMilliseconds()) {
CVehicle *carToSteal = nil;
- float closestCarDist = 30.0f;
+ float closestCarDist = nEnterCarRangeMultiplier * ENTER_CAR_MAX_DIST;
CVector pos = GetPosition();
int16 lastVehicle;
CEntity *vehicles[8];
- CWorld::FindObjectsInRange(pos, CHECK_NEARBY_THINGS_MAX_DIST, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
+ CWorld::FindObjectsInRange(pos, closestCarDist, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
for(int i = 0; i < lastVehicle; i++) {
CVehicle *nearVeh = (CVehicle*)vehicles[i];
- if (nearVeh->VehicleCreatedBy != MISSION_VEHICLE) {
+ if (m_objective == OBJECTIVE_STEAL_ANY_MISSION_CAR || nearVeh->VehicleCreatedBy != MISSION_VEHICLE) {
if (nearVeh->m_vecMoveSpeed.Magnitude() <= 0.1f) {
if (nearVeh->CanPedOpenLocks(this)) {
CVector vehDistVec = GetPosition() - nearVeh->GetPosition();
@@ -14968,60 +15187,6 @@ CPed::ProcessObjective(void)
CPed::SetWanderPath(m_nPathDir);
}
break;
- case OBJECTIVE_FLEE_CAR:
- if (!bInVehicle && m_nPedState != PED_FLEE_ENTITY && m_pMyVehicle) {
- RestorePreviousObjective();
- SetFlee(m_pMyVehicle, 6000);
- break;
- }
- // fall through
- case OBJECTIVE_LEAVE_CAR:
- if (CTimer::GetTimeInMilliseconds() > m_leaveCarTimer) {
- if (InVehicle() &&
- (FindPlayerPed() != this || !CPad::GetPad(0)->GetAccelerate() || bBusJacked)) {
-
- if (m_nPedState != PED_EXIT_CAR && m_nPedState != PED_DRAG_FROM_CAR && m_nPedState != PED_EXIT_TRAIN
- && (m_nPedType != PEDTYPE_COP
- || m_pMyVehicle->IsBoat()
- || m_pMyVehicle->m_vecMoveSpeed.MagnitudeSqr2D() < sq(0.005f))) {
-#ifdef GTA_TRAIN
- if (m_pMyVehicle->IsTrain())
- SetExitTrain(m_pMyVehicle);
- else
-#endif
- if (m_pMyVehicle->IsBoat())
- SetExitBoat(m_pMyVehicle);
- else
- SetExitCar(m_pMyVehicle, 0);
- }
- } else {
- RestorePreviousObjective();
- }
- }
- if (bHeldHostageInCar) {
- if (CTheScripts::IsPlayerOnAMission()) {
- CVehicle *playerVeh = FindPlayerVehicle();
- if (playerVeh && playerVeh->IsPassenger(this)) {
- if (m_leaveCarTimer != 0)
- m_leaveCarTimer = 0;
- }
- }
- }
- break;
- case OBJECTIVE_AIM_GUN_AT:
- if (m_pedInObjective) {
- if (!bObstacleShowedUpDuringKillObjective)
- SetPointGunAt(m_pedInObjective);
-
- if (m_nMoveState == PEDMOVE_STILL && IsPedInControl()) {
- SetLookFlag(m_pedInObjective, false);
- TurnBody();
- }
- } else {
- ClearObjective();
- }
- break;
-#ifdef VC_PED_PORTS
case OBJECTIVE_LEAVE_CAR_AND_DIE:
{
if (CTimer::GetTimeInMilliseconds() > m_leaveCarTimer) {
@@ -15049,6 +15214,59 @@ CPed::ProcessObjective(void)
}
break;
}
+ case OBJECTIVE_GOTO_AREA_ANY_MEANS:
+ {
+ distWithTarget = m_nextRoutePointPos - GetPosition();
+ distWithTarget.z = 0.0f;
+ if (InVehicle()) {
+ CCarAI::GetCarToGoToCoors(m_pMyVehicle, &m_nextRoutePointPos);
+ CCarCtrl::RegisterVehicleOfInterest(m_pMyVehicle);
+ if (distWithTarget.MagnitudeSqr() < sq(20.0f)) {
+ m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0;
+ ForceStoredObjective(OBJECTIVE_GOTO_AREA_ANY_MEANS);
+ SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
+ }
+ break;
+ }
+ if (distWithTarget.Magnitude() > 30.0f) {
+ if (m_pMyVehicle) {
+ m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0;
+ } else {
+ float closestVehDist = SQR(60.0f);
+ int16 lastVehicle;
+ CEntity* vehicles[8];
+ // NB: 25.0f in here is prolly a forgotten setting, all other places now use 30.0f (ENTER_CAR_MAX_DIST)
+ CWorld::FindObjectsInRange(GetPosition(), 25.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
+ CVehicle* foundVeh = nil;
+ for (int i = 0; i < lastVehicle; i++) {
+ CVehicle* nearVeh = (CVehicle*)vehicles[i];
+ /*
+ Not used.
+ CVector vehSpeed = nearVeh->GetSpeed();
+ CVector ourSpeed = GetSpeed();
+ */
+ CVector vehDistVec = nearVeh->GetPosition() - GetPosition();
+ if (vehDistVec.MagnitudeSqr() < closestVehDist && m_pedInObjective->m_pMyVehicle != nearVeh) {
+ foundVeh = nearVeh;
+ closestVehDist = vehDistVec.MagnitudeSqr();
+ }
+ }
+ m_pMyVehicle = foundVeh;
+ if (m_pMyVehicle) {
+ m_pMyVehicle->RegisterReference((CEntity **) &m_pMyVehicle);
+ m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0;
+ SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, m_pMyVehicle);
+ }
+ }
+ break;
+ }
+ // Falls to different objectives in III and VC
+#ifdef FIX_BUGS
+ break;
+#else
+ // fall through
+#endif
+ }
case OBJECTIVE_GOTO_SEAT_ON_FOOT:
case OBJECTIVE_GOTO_ATM_ON_FOOT:
case OBJECTIVE_GOTO_BUS_STOP_ON_FOOT:
@@ -15059,8 +15277,7 @@ CPed::ProcessObjective(void)
m_objectiveTimer = 0;
if (m_attractor)
GetPedAttractorManager()->DeRegisterPed(this, m_attractor);
- }
- else {
+ } else {
CVector distance = m_nextRoutePointPos - GetPosition();
distance.z = 0.0f;
if (m_objective == OBJECTIVE_GOTO_SHELTER_ON_FOOT) {
@@ -15176,6 +15393,59 @@ CPed::ProcessObjective(void)
}
}
return;
+ case OBJECTIVE_FLEE_CAR:
+ if (!bInVehicle && m_nPedState != PED_FLEE_ENTITY && m_pMyVehicle) {
+ RestorePreviousObjective();
+ SetFlee(m_pMyVehicle, 6000);
+ break;
+ }
+ // fall through
+ case OBJECTIVE_LEAVE_CAR:
+ if (CTimer::GetTimeInMilliseconds() > m_leaveCarTimer) {
+ if (InVehicle() &&
+ (FindPlayerPed() != this || !CPad::GetPad(0)->GetAccelerate() || bBusJacked)) {
+
+ if (m_nPedState != PED_EXIT_CAR && m_nPedState != PED_DRAG_FROM_CAR && m_nPedState != PED_EXIT_TRAIN
+ && (m_nPedType != PEDTYPE_COP
+ || m_pMyVehicle->IsBoat()
+ || m_pMyVehicle->m_vecMoveSpeed.MagnitudeSqr2D() < sq(0.005f))) {
+#ifdef GTA_TRAIN
+ if (m_pMyVehicle->IsTrain())
+ SetExitTrain(m_pMyVehicle);
+ else
+#endif
+ if (m_pMyVehicle->IsBoat())
+ SetExitBoat(m_pMyVehicle);
+ else
+ SetExitCar(m_pMyVehicle, 0);
+ }
+ } else {
+ RestorePreviousObjective();
+ }
+ }
+ if (bHeldHostageInCar) {
+ if (CTheScripts::IsPlayerOnAMission()) {
+ CVehicle *playerVeh = FindPlayerVehicle();
+ if (playerVeh && playerVeh->IsPassenger(this)) {
+ if (m_leaveCarTimer != 0)
+ m_leaveCarTimer = 0;
+ }
+ }
+ }
+ break;
+ case OBJECTIVE_AIM_GUN_AT:
+ if (m_pedInObjective) {
+ if (!bObstacleShowedUpDuringKillObjective)
+ SetPointGunAt(m_pedInObjective);
+
+ if (m_nMoveState == PEDMOVE_STILL && IsPedInControl()) {
+ SetLookFlag(m_pedInObjective, false);
+ TurnBody();
+ }
+ } else {
+ ClearObjective();
+ }
+ break;
case OBJECTIVE_WAIT_ON_FOOT_AT_SHELTER:
SetIdle();
if (m_attractor && CWeather::Rain < 0.2f)
@@ -15207,8 +15477,8 @@ CPed::ProcessObjective(void)
} else if (m_pedInObjective) {
SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS, m_pedInObjective);
}
- } else {
SetMoveAnim();
+ } else {
ClearLookFlag();
SetMoveAnim();
if (m_pCurrentPhysSurface && m_pCurrentPhysSurface->IsVehicle())
@@ -15268,7 +15538,7 @@ CPed::ProcessObjective(void)
GetPedAttractorManager()->DeRegisterPed(this, m_attractor);
SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, pBus);
bDontDragMeOutCar = true;
- b157_40 = true;
+ bRemoveMeWhenIGotIntoCar = true;
CPlayerPed *player = FindPlayerPed();
if (pBus->IsPassenger(player) || pBus->IsDriver(player)) {
bCollectBusFare = true;
@@ -15309,7 +15579,6 @@ CPed::ProcessObjective(void)
}
break;
}
-#endif
}
if (bObjectiveCompleted
|| m_objectiveTimer > 0 && CTimer::GetTimeInMilliseconds() > m_objectiveTimer) {
@@ -15329,6 +15598,7 @@ CPed::ProcessObjective(void)
}
}
+// --MIAMI: Done
void
CPed::SetShootTimer(uint32 time)
{
@@ -16441,7 +16711,78 @@ CPed::PreRender(void)
RwMatrixScale(head, &zero, rwCOMBINEPRECONCAT);
}
- // TODO(Miami): Some cheat??
+ if (IsPlayer() && gfTommyFatness != 1.0f) {
+ RpHAnimHierarchy* hier = GetAnimHierarchyFromSkinClump(GetClump());
+ int32 idx;
+ RwV3d scale;
+
+ scale.x = 1.0f;
+ scale.y = 1.0f + gfTommyFatness * 0.7f;
+ scale.z = 1.0f + gfTommyFatness * 0.7f;
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_HEAD));
+ RwMatrix* head = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(head, &scale, rwCOMBINEPRECONCAT);
+
+ scale.y = 1.0f + gfTommyFatness * 0.2f;
+ scale.z = 1.0f + gfTommyFatness * 0.2f;
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_NECK));
+ RwMatrix* neck = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(neck, &scale, rwCOMBINEPRECONCAT);
+
+ scale.y = 1.0f + gfTommyFatness * 0.5f;
+ scale.z = 1.0f + gfTommyFatness * 0.5f;
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_MID));
+ RwMatrix* mid = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(mid, &scale, rwCOMBINEPRECONCAT);
+
+ scale.y = 1.0f + gfTommyFatness;
+ scale.z = 1.0f + gfTommyFatness;
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_UPPERLEGL));
+ RwMatrix* upperLegL = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(upperLegL, &scale, rwCOMBINEPRECONCAT);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_UPPERLEGR));
+ RwMatrix* upperLegR = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(upperLegR, &scale, rwCOMBINEPRECONCAT);
+
+ scale.y = 1.0f + gfTommyFatness * 0.5f;
+ scale.z = 1.0f + gfTommyFatness * 0.5f;
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_LOWERLEGR));
+ RwMatrix* lowerLegR = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(lowerLegR, &scale, rwCOMBINEPRECONCAT);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_LOWERLEGL));
+ RwMatrix* lowerLegL = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(lowerLegL, &scale, rwCOMBINEPRECONCAT);
+
+ scale.y = 1.0f + gfTommyFatness * 0.23f;
+ scale.z = 1.0f + gfTommyFatness * 0.23f;
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_FOOTL));
+ RwMatrix* footL = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(footL, &scale, rwCOMBINEPRECONCAT);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_FOOTR));
+ RwMatrix* footR = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(footR, &scale, rwCOMBINEPRECONCAT);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_UPPERARML));
+ RwMatrix* upperArmL = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(upperArmL, &scale, rwCOMBINEPRECONCAT);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_UPPERARMR));
+ RwMatrix* upperArmR = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(upperArmR, &scale, rwCOMBINEPRECONCAT);
+
+ scale.y = 1.0f + gfTommyFatness * 0.2f;
+ scale.z = 1.0f + gfTommyFatness * 0.2f;
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_FOREARML));
+ RwMatrix* foreArmL = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(foreArmL, &scale, rwCOMBINEPRECONCAT);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_FOREARMR));
+ RwMatrix* foreArmR = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(foreArmR, &scale, rwCOMBINEPRECONCAT);
+ }
if (bBodyPartJustCameOff && bIsPedDieAnimPlaying && m_bodyPartBleeding != -1 && (CTimer::GetFrameCounter() & 7) > 3) {
CVector bloodDir(0.0f, 0.0f, 0.0f);
@@ -16512,15 +16853,14 @@ CPed::PreRender(void)
}
}
+// --MIAMI: Done
void
CPed::ProcessBuoyancy(void)
{
+ float buoyancyLevel = 1.1f;
static uint32 nGenerateRaindrops = 0;
static uint32 nGenerateWaterCircles = 0;
- CRGBA color(((0.5f * CTimeCycle::GetDirectionalRed() + CTimeCycle::GetAmbientRed()) * 127.5f),
- ((0.5f * CTimeCycle::GetDirectionalBlue() + CTimeCycle::GetAmbientBlue()) * 127.5f),
- ((0.5f * CTimeCycle::GetDirectionalGreen() + CTimeCycle::GetAmbientGreen()) * 127.5f),
- (CGeneral::GetRandomNumber() % 256 * 48.0f) + 48);
+ CRGBA color;
if (bInVehicle)
return;
@@ -16528,26 +16868,27 @@ CPed::ProcessBuoyancy(void)
CVector buoyancyPoint;
CVector buoyancyImpulse;
-#ifndef VC_PED_PORTS
- float buoyancyLevel = (m_nPedState == PED_DEAD ? 1.5f : 1.3f);
-#else
- float buoyancyLevel = (m_nPedState == PED_DEAD ? 1.8f : 1.1f);
-#endif
+ if (DyingOrDead())
+ buoyancyLevel = 1.8f;
if (mod_Buoyancy.ProcessBuoyancy(this, GRAVITY * m_fMass * buoyancyLevel, &buoyancyPoint, &buoyancyImpulse)) {
bTouchingWater = true;
CEntity *entity;
CColPoint point;
if (CWorld::ProcessVerticalLine(GetPosition(), GetPosition().z - 3.0f, point, entity, false, true, false, false, false, false, nil)
- && entity->IsVehicle() && ((CVehicle*)entity)->IsBoat()) {
+ && entity->IsVehicle() && ((CVehicle*)entity)->IsBoat() && !entity->bRenderScorched) {
bIsInWater = false;
return;
}
+ color.r = (0.5f * CTimeCycle::GetDirectionalRed() + CTimeCycle::GetAmbientRed()) * 127.5f;
+ color.g = (0.5f * CTimeCycle::GetDirectionalBlue() + CTimeCycle::GetAmbientBlue()) * 127.5f;
+ color.b = (0.5f * CTimeCycle::GetDirectionalGreen() + CTimeCycle::GetAmbientGreen()) * 127.5f;
+ color.a = (CGeneral::GetRandomNumber() % 256 * 48.0f) + 48;
bIsInWater = true;
ApplyMoveForce(buoyancyImpulse);
if (!DyingOrDead()) {
if (bTryingToReachDryLand) {
- if (buoyancyImpulse.z / m_fMass > 0.0032f * CTimer::GetTimeStep()) {
+ if (buoyancyImpulse.z / m_fMass > GRAVITY * 0.4f * CTimer::GetTimeStep()) {
bTryingToReachDryLand = false;
CVector pos = GetPosition();
if (PlacePedOnDryLand()) {
@@ -16559,19 +16900,15 @@ CPed::ProcessBuoyancy(void)
bIsInTheAir = false;
}
pos.z = pos.z - 0.8f;
-#ifdef PC_PARTICLE
CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, pos, CVector(0.0f, 0.0f, 0.0f), 0.0f, 50, color, true);
-#else
- CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, pos, CVector(0.0f, 0.0f, 0.0f), 0.0f, 50, CRGBA(0, 0, 0, 0), true);
-#endif
m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
- m_nPedState = PED_IDLE;
+ SetPedState(PED_IDLE);
return;
}
}
}
float speedMult = 0.0f;
- if (buoyancyImpulse.z / m_fMass > 0.006f * CTimer::GetTimeStep()
+ if (buoyancyImpulse.z / m_fMass > GRAVITY * CTimer::GetTimeStep()
|| mod_Buoyancy.m_waterlevel > GetPosition().z) {
speedMult = pow(0.9f, CTimer::GetTimeStep());
m_vecMoveSpeed.x *= speedMult;
@@ -16581,7 +16918,7 @@ CPed::ProcessBuoyancy(void)
bIsDrowning = true;
InflictDamage(nil, WEAPONTYPE_DROWNING, 3.0f * CTimer::GetTimeStep(), PEDPIECE_TORSO, 0);
}
- if (buoyancyImpulse.z / m_fMass > 0.002f * CTimer::GetTimeStep()) {
+ if (buoyancyImpulse.z / m_fMass > GRAVITY * 0.25f * CTimer::GetTimeStep()) {
if (speedMult == 0.0f) {
speedMult = pow(0.9f, CTimer::GetTimeStep());
}
@@ -16593,7 +16930,6 @@ CPed::ProcessBuoyancy(void)
} else {
m_vecMoveSpeed.z = -0.01f;
DMAudio.PlayOneShot(m_audioEntityId, SOUND_SPLASH, 0.0f);
-#ifdef PC_PARTICLE
CVector aBitForward = 2.2f * m_vecMoveSpeed + GetPosition();
float level = 0.0f;
if (CWaterLevel::GetWaterLevel(aBitForward, &level, false))
@@ -16602,18 +16938,6 @@ CPed::ProcessBuoyancy(void)
CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, aBitForward, CVector(0.0f, 0.0f, 0.1f), 0.0f, 200, color, true);
nGenerateRaindrops = CTimer::GetTimeInMilliseconds() + 80;
nGenerateWaterCircles = CTimer::GetTimeInMilliseconds() + 100;
-#else
- CVector aBitForward = 1.6f * m_vecMoveSpeed + GetPosition();
- float level = 0.0f;
- if (CWaterLevel::GetWaterLevel(aBitForward, &level, false))
- aBitForward.z = level + 0.5f;
-
- CVector vel = m_vecMoveSpeed * 0.1f;
- vel.z = 0.18f;
- CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, aBitForward, vel, 0.0f, 350, CRGBA(0, 0, 0, 0), true);
- nGenerateRaindrops = CTimer::GetTimeInMilliseconds() + 300;
- nGenerateWaterCircles = CTimer::GetTimeInMilliseconds() + 60;
-#endif
}
}
} else
@@ -16630,15 +16954,9 @@ CPed::ProcessBuoyancy(void)
if (pos.z != 0.0f) {
nGenerateWaterCircles = 0;
for(int i = 0; i < 4; i++) {
-#ifdef PC_PARTICLE
pos.x += CGeneral::GetRandomNumberInRange(-0.75f, 0.75f);
pos.y += CGeneral::GetRandomNumberInRange(-0.75f, 0.75f);
CParticle::AddParticle(PARTICLE_RAIN_SPLASH_BIGGROW, pos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, color, 0, 0, 0, 0);
-#else
- pos.x += CGeneral::GetRandomNumberInRange(-2.5f, 2.5f);
- pos.y += CGeneral::GetRandomNumberInRange(-2.5f, 2.5f);
- CParticle::AddParticle(PARTICLE_RAIN_SPLASH_BIGGROW, pos+CVector(0.0f, 0.0f, 1.0f), CVector(0.0f, 0.0f, 0.0f));
-#endif
}
}
}
@@ -16650,17 +16968,9 @@ CPed::ProcessBuoyancy(void)
pos.z = level;
if (pos.z >= 0.0f) {
-#ifdef PC_PARTICLE
pos.z += 0.25f;
-#else
- pos.z += 0.5f;
-#endif
nGenerateRaindrops = 0;
-#ifdef PC_PARTICLE
CParticleObject::AddObject(POBJECT_SPLASHES_AROUND, pos, CVector(0.0f, 0.0f, 0.0f), 4.5f, 1500, CRGBA(0,0,0,0), true);
-#else
- CParticleObject::AddObject(POBJECT_SPLASHES_AROUND, pos, CVector(0.0f, 0.0f, 0.0f), 4.5f, 2500, CRGBA(0,0,0,0), true);
-#endif
}
}
}
@@ -19399,10 +19709,7 @@ CPed::Solicit(void)
void
CPed::SetExitBoat(CVehicle *boat)
{
- if (m_nPedState == PED_FOLLOW_PATH) {
- ClearFollowPath();
- }
- m_nPedState = PED_IDLE;
+ SetPedState(PED_IDLE);
CVector newPos = GetPosition();
RemoveInCarAnims();
CColModel* boatCol = boat->GetColModel();
@@ -20873,6 +21180,46 @@ CPed::ScanForDelayedResponseThreats(void)
// --MIAMI: Done
void
+CPed::DeleteSunbatheIdleAnimCB(CAnimBlendAssociation *assoc, void *arg)
+{
+ CPed *ped = (CPed*) arg;
+
+ if (CTimer::GetTimeInMilliseconds() <= ped->m_nWaitTimer
+ && !ped->bGotUpOfMyOwnAccord && !ped->bFleeWhenStanding && !ped->m_threatEx) {
+ ped->m_pNextPathNode = nil;
+ ped->bFleeWhenStanding = true;
+ ped->m_threatEx = FindPlayerPed();
+ ped->SetGetUp();
+ ped->ClearWaitState();
+ }
+ ped->m_nWaitTimer = 0;
+ ped->RestoreHeadingRate();
+ ped->Wait();
+}
+
+// --MIAMI: Done
+void
+CPed::PedSetPreviousStateCB(CAnimBlendAssociation* assoc, void* arg)
+{
+ CPed* ped = (CPed*)arg;
+ ped->RestorePreviousState();
+ ped->m_pVehicleAnim = nil;
+}
+
+// --MIAMI: Done
+void
+CPed::PedAnimShuffleCB(CAnimBlendAssociation* assoc, void* arg)
+{
+ CPed *ped = (CPed*)arg;
+ if (ped->EnteringCar()) {
+ PedSetInCarCB(nil, ped);
+ } else if (ped->m_nPedState != PED_DRIVING) {
+ ped->QuitEnteringCar();
+ }
+}
+
+// --MIAMI: Done
+void
PlayRandomAnimationsFromAnimBlock(CPed* ped, AssocGroupId animGroup, uint32 first, uint32 amount)
{
if (!ped->IsPedInControl())
diff --git a/src/peds/Ped.h b/src/peds/Ped.h
index 815d9c2d..752973bc 100644
--- a/src/peds/Ped.h
+++ b/src/peds/Ped.h
@@ -14,6 +14,7 @@
#define FEET_OFFSET 1.04f
#define CHECK_NEARBY_THINGS_MAX_DIST 15.0f
+#define ENTER_CAR_MAX_DIST 30.0f
class CAccident;
class CObject;
@@ -358,6 +359,8 @@ enum eMoveState {
PEDMOVE_THROWN
};
+extern float gfTommyFatness;
+
class CVehicle;
class CPed : public CPhysical
@@ -457,8 +460,8 @@ public:
uint32 bHasAlreadyUsedAttractor : 1;
uint32 b155_2 : 1;
uint32 bCarPassenger : 1;
- uint32 b155_8 : 1;
- uint32 b155_10 : 1;
+ uint32 bFleeWhenStanding : 1;
+ uint32 bGotUpOfMyOwnAccord : 1;
uint32 bMiamiViceCop : 1;
uint32 bMoneyHasBeenGivenByScript : 1; //
uint32 bHasBeenPhotographed : 1; //
@@ -475,10 +478,10 @@ public:
uint32 bDontFight : 1;
uint32 bDoomAim : 1;
uint32 bCanBeShotInVehicle : 1;
- uint32 b157_8 : 1;
+ uint32 bCanGiveUpSunbathing : 1;
uint32 bMakeFleeScream : 1;
uint32 bPushedAlongByCar : 1;
- uint32 b157_40 : 1;
+ uint32 bRemoveMeWhenIGotIntoCar : 1;
uint32 bIgnoreThreatsBehindObjects : 1;
uint32 bNeverEverTargetThisPed : 1;
@@ -487,7 +490,7 @@ public:
uint32 b158_8 : 1;
uint32 bCollectBusFare : 1;
uint32 bBoughtIceCream : 1;
- uint32 b158_40 : 1;
+ uint32 bDonePositionOutOfCollision : 1;
uint32 b158_80 : 1;
// our own flags
@@ -580,7 +583,7 @@ public:
float m_fleeFromPosY;
CEntity *m_fleeFrom;
uint32 m_fleeTimer;
- CEntity* pThreatEx; // TODO(Miami): What is this?
+ CEntity* m_threatEx; // TODO(Miami): What is this?
CEntity* m_collidingEntityWhileFleeing;
uint32 m_collidingThingTimer;
CEntity *m_pCollidingEntity;
@@ -831,6 +834,7 @@ public:
void ReactToPointGun(CEntity*);
void SeekCar(void);
bool PositionPedOutOfCollision(void);
+ bool PositionAnyPedOutOfCollision(void);
bool RunToReportCrime(eCrimeType);
bool PlacePedOnDryLand(void);
bool PossiblyFindBetterPosToSeekCar(CVector*, CVehicle*);
@@ -905,6 +909,9 @@ public:
static void RestoreHeadingRateCB(CAnimBlendAssociation *assoc, void *arg);
static void PedSetQuickDraggedOutCarPositionCB(CAnimBlendAssociation *assoc, void *arg);
static void PedSetDraggedOutCarPositionCB(CAnimBlendAssociation *assoc, void *arg);
+ static void DeleteSunbatheIdleAnimCB(CAnimBlendAssociation *assoc, void *arg);
+ static void PedSetPreviousStateCB(CAnimBlendAssociation *assoc, void *arg);
+ static void PedAnimShuffleCB(CAnimBlendAssociation *assoc, void *arg);
bool IsPlayer(void);
bool IsFemale(void) { return m_nPedType == PEDTYPE_CIVFEMALE || m_nPedType == PEDTYPE_PROSTITUTE; }
diff --git a/src/render/Fluff.cpp b/src/render/Fluff.cpp
index 77d2af2a..31bf92a8 100644
--- a/src/render/Fluff.cpp
+++ b/src/render/Fluff.cpp
@@ -1611,13 +1611,13 @@ void CScriptPath::Clear(void) {
m_state = SCRIPT_PATH_DISABLED;
}
-void CScriptPath::InitialiseOne(int32 numNodes, float width) {
+void CScriptPath::InitialiseOne(int32 numNodes, float length) {
char Dest[32];
sprintf(Dest, "data\\paths\\spath%d.dat", numNodes);
m_pNode = CPlane::LoadPath(Dest, m_numNodes, m_fTotalLength, false);
m_fSpeed = 1.0f;
m_fPosition = 0.0f;
- m_fObjectLength = width;
+ m_fObjectLength = length;
m_state = SCRIPT_PATH_INITIALIZED;
}
@@ -1697,7 +1697,7 @@ INITSAVEBUF
VALIDATESAVEBUF(*size);
}
-CObject* g_pScriptPathObjects[18];
+CObject *g_pScriptPathObjects[18];
void CScriptPaths::Load_ForReplay(void) {
for (int i = 0; i < 3; i++) {
diff --git a/src/render/Fluff.h b/src/render/Fluff.h
index a31ac335..0fc57c73 100644
--- a/src/render/Fluff.h
+++ b/src/render/Fluff.h
@@ -24,7 +24,7 @@ public:
void Clear(void);
void Update(void);
- void InitialiseOne(int32 numNodes, float width);
+ void InitialiseOne(int32 numNodes, float length);
void FindCoorsFromDistanceOnPath(float t, float *pX, float *pY, float *pZ);
void SetObjectToControl(CObject *pObj);
};
diff --git a/src/render/Glass.h b/src/render/Glass.h
index 736e5205..937ab6a9 100644
--- a/src/render/Glass.h
+++ b/src/render/Glass.h
@@ -53,4 +53,5 @@ public:
//TODO(MIAMI)
static void CarWindscreenShatters(CVehicle *vehicle, bool unk) {}
+ static void BreakGlassPhysically(CVector, float) {}
}; \ No newline at end of file
diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp
index cbf3c7f2..c05a3d31 100644
--- a/src/render/Hud.cpp
+++ b/src/render/Hud.cpp
@@ -21,6 +21,8 @@
#include "User.h"
#include "World.h"
#include "CutsceneMgr.h"
+#include "Stats.h"
+#include "main.h"
// Game has colors inlined in code.
// For easier modification we collect them here:
@@ -91,6 +93,8 @@ float CHud::PagerXOffset;
int16 CHud::PagerTimer;
int16 CHud::PagerOn;
+wchar *prevChaseString;
+
uint32 CHud::m_WantedFadeTimer;
uint32 CHud::m_WantedState;
uint32 CHud::m_WantedTimer;
@@ -524,6 +528,53 @@ void CHud::Draw()
}
}
+ static int32 nMediaLevelCounter = 0;
+ if (CStats::ShowChaseStatOnScreen != 0) {
+ float fCurAttentionLevel = CWorld::Players[CWorld::PlayerInFocus].m_fMediaAttention;
+ if (0.7f * CStats::HighestChaseValue > fCurAttentionLevel
+ || fCurAttentionLevel <= 40.0f || CTheScripts::IsPlayerOnAMission()) {
+ nMediaLevelCounter = 0;
+ }
+ else {
+ if (fCurAttentionLevel == CStats::HighestChaseValue) {
+ sprintf(gString, "%s %d", UnicodeToAscii(TheText.Get("CHSE")), (int32)fCurAttentionLevel);
+ }
+ else {
+ sprintf(gString, "%s %d" "-%d-", UnicodeToAscii(TheText.Get("CHSE")), (int32)fCurAttentionLevel, (int32)CStats::HighestChaseValue);
+ }
+ AsciiToUnicode(gString, gUString);
+ CFont::SetBackgroundOff();
+ CFont::SetScale(SCREEN_SCALE_X(HUD_TEXT_SCALE_X), SCREEN_SCALE_Y(HUD_TEXT_SCALE_Y));
+ CFont::SetCentreOff();
+ CFont::SetRightJustifyOn();
+ CFont::SetRightJustifyWrap(0.0f);
+ CFont::SetBackGroundOnlyTextOff();
+ CFont::SetFontStyle(FONT_HEADING);
+ CFont::SetPropOff();
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, 255));
+
+ CRGBA colour;
+ if (CTimer::GetTimeInMilliseconds() & 0x200)
+ colour = CRGBA(204, 0, 185, 180);
+ else
+ colour = CRGBA(178, 0, 162, 180);
+ CFont::SetColor(colour);
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f), SCREEN_SCALE_Y(113.0f), gUString);
+
+ if (CStats::FindChaseString(fCurAttentionLevel) != prevChaseString) {
+ prevChaseString = CStats::FindChaseString(fCurAttentionLevel);
+ nMediaLevelCounter = 100;
+ }
+
+ if (nMediaLevelCounter != 0) {
+ nMediaLevelCounter--;
+ UnicodeMakeUpperCase(gUString, CStats::FindChaseString(fCurAttentionLevel));
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f), SCREEN_SCALE_Y(138.0f), gUString);
+ }
+ }
+ }
+
/*
DrawZoneName
*/
diff --git a/src/render/SpecialFX.cpp b/src/render/SpecialFX.cpp
index e9079bef..fa8379f0 100644
--- a/src/render/SpecialFX.cpp
+++ b/src/render/SpecialFX.cpp
@@ -32,6 +32,7 @@ RwIm3DVertex TraceVertices[6];
RwImVertexIndex TraceIndexList[12];
bool CSpecialFX::bSnapShotActive;
+int32 CSpecialFX::SnapShotFrames;
void
CSpecialFX::Init(void)
diff --git a/src/render/SpecialFX.h b/src/render/SpecialFX.h
index 8c79856b..8bd0d5e1 100644
--- a/src/render/SpecialFX.h
+++ b/src/render/SpecialFX.h
@@ -4,6 +4,7 @@ class CSpecialFX
{
public:
static bool bSnapShotActive;
+ static int32 SnapShotFrames;
static void Render(void);
static void Update(void);
@@ -56,6 +57,13 @@ public:
static void AddTrace(CVector*, CVector*);
static void Render(void);
static void Update(void);
+
+//TODO(MIAMI)
+ static void AddTrace(CVector *, CVector *, float, unsigned int, unsigned char) {}
+ static void AddTrace(CVector *a, CVector *b, int32 weapontype, class CEntity *shooter)
+ {
+ AddTrace(a, b); //TODO: temp
+ }
};
enum
diff --git a/src/text/Text.cpp b/src/text/Text.cpp
index dab1cae3..64f303eb 100644
--- a/src/text/Text.cpp
+++ b/src/text/Text.cpp
@@ -495,6 +495,20 @@ UnicodeToAsciiForMemoryCard(wchar *src)
}
void
+UnicodeMakeUpperCase(wchar *dst, wchar *src) //idk what to do with it, seems to be incorrect implementation by R*
+{
+ while (*src != '\0') {
+ if (*src < 'a' || *src > 'z')
+ *dst = *src;
+ else
+ *dst = *src - 32;
+ dst++;
+ src++;
+ }
+ *dst = '\0';
+}
+
+void
UnicodeStrcpy(wchar *dst, const wchar *src)
{
while((*dst++ = *src++) != '\0');
diff --git a/src/text/Text.h b/src/text/Text.h
index d163b9c9..0bad9a83 100644
--- a/src/text/Text.h
+++ b/src/text/Text.h
@@ -8,6 +8,7 @@ void UnicodeStrcpy(wchar *dst, const wchar *src);
void UnicodeStrcat(wchar *dst, wchar *append);
int UnicodeStrlen(const wchar *str);
void TextCopy(wchar *dst, const wchar *src);
+void UnicodeMakeUpperCase(wchar *dst, wchar *src);
struct CKeyEntry
{
diff --git a/src/weapons/Weapon.cpp b/src/weapons/Weapon.cpp
index 0cd439c2..48f90897 100644
--- a/src/weapons/Weapon.cpp
+++ b/src/weapons/Weapon.cpp
@@ -32,51 +32,20 @@
#include "World.h"
#include "SurfaceTable.h"
#include "Bike.h"
+#include "Glass.h"
+#include "Sprite.h"
+#include "Pickups.h"
// TODO(Miami)
#define AUDIO_NOT_READY
-// TODO(Miami): Those are mostly placeholders!!!
-uint16 gReloadSampleTime[] =
-{
- 0, // UNARMED
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0, // GRENADE
- 0, // DETONATEGRENADE
- 0, // TEARGAS
- 0, // MOLOTOV
- 0, // ROCKET
- 250, // COLT45
- 250, // PYTHON
- 650, // SHOTGUN
- 650, // SPAS12 SHOTGUN
- 650, // STUBBY SHOTGUN
- 400, // TEC9
- 400, // UZIhec
- 400, // SILENCED_INGRAM
- 400, // MP5
- 300, // M16
- 300, // AK47
- 423, // SNIPERRIFLE
- 423, // LASERSCOPE
- 400, // ROCKETLAUNCHER
- 0, // FLAMETHROWER
- 0, // M60
- 0, // MINIGUN
- 0, // DETONATOR
- 0, // HELICANNON
- 0 // CAMERA
-};
+float fReloadAnimSampleFraction[5] = { 0.5f, 0.7f, 0.75f, 0.75f, 0.7f };
+float fSeaSparrowAimingAngle = 10.0f;
+float fHunterAimingAngle = 30.0f;
+float fPlayerAimScaleDist = 5.0f;
+float fPlayerAimScale = 2.5f;
+
+bool CWeapon::bPhotographHasBeenTaken;
CWeaponInfo *
CWeapon::GetInfo()
@@ -86,6 +55,17 @@ CWeapon::GetInfo()
return info;
}
+CWeapon::CWeapon(eWeaponType type, int32 ammo)
+{
+ m_eWeaponType = type;
+ m_eWeaponState = WEAPONSTATE_READY;
+ m_nAmmoTotal = Min(ammo, 99999);
+ m_nAmmoInClip = 0;
+ Reload();
+ m_nTimer = 0;
+ m_bAddRotOffset = false;
+}
+
void
CWeapon::InitialiseWeapons(void)
{
@@ -94,6 +74,7 @@ CWeapon::InitialiseWeapons(void)
CExplosion::Initialise();
CProjectileInfo::Initialise();
CBulletInfo::Initialise();
+ bPhotographHasBeenTaken = false;
}
void
@@ -115,19 +96,7 @@ CWeapon::UpdateWeapons(void)
CBulletInfo::Update();
}
-//--MIAMI: done
-CWeapon::CWeapon(eWeaponType type, int32 ammo)
-{
- m_eWeaponType = type;
- m_eWeaponState = WEAPONSTATE_READY;
- m_nAmmoTotal = Min(ammo, 99999);
- m_nAmmoInClip = 0;
- Reload();
- m_nTimer = 0;
- m_bAddRotOffset = false;
-}
-// --MIAMI: Done
void
CWeapon::Initialise(eWeaponType type, int32 ammo)
{
@@ -137,24 +106,23 @@ CWeapon::Initialise(eWeaponType type, int32 ammo)
m_nAmmoInClip = 0;
Reload();
m_nTimer = 0;
- int modelId = CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_nModelId;
- if (modelId != -1)
+ int32 modelId = CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_nModelId;
+ int32 model2Id = CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_nModel2Id;
+
+ if ( modelId != -1 )
CModelInfo::GetModelInfo(modelId)->AddRef();
-
- int model2Id = CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_nModel2Id;
- if (model2Id != -1)
+ if ( model2Id != -1 )
CModelInfo::GetModelInfo(model2Id)->AddRef();
}
-// --MIAMI: Done
void
CWeapon::Shutdown()
{
- int modelId = CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_nModelId;
+ int32 modelId = CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_nModelId;
if (modelId != -1)
CModelInfo::GetModelInfo(modelId)->RemoveRef();
- int model2Id = CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_nModel2Id;
+ int32 model2Id = CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_nModel2Id;
if (model2Id != -1)
CModelInfo::GetModelInfo(model2Id)->RemoveRef();
@@ -172,12 +140,18 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
CVector fireOffset(0.0f, 0.0f, 0.6f);
CVector *source = fireSource;
+#ifdef FIX_BUGS
+ static CVector shooterSource;
+#else
+ CVector shooterSource;
+#endif
- if (!fireSource) {
- static CVector tmp;
- tmp = shooter->GetMatrix() * fireOffset;
- source = &tmp;
+ if ( !fireSource )
+ {
+ shooterSource = shooter->GetMatrix() * fireOffset;
+ source = &shooterSource;
}
+
if ( m_bAddRotOffset )
{
float heading = RADTODEG(shooter->GetForward().Heading());
@@ -213,6 +187,17 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
break;
}
+ case WEAPONTYPE_SNIPERRIFLE:
+ case WEAPONTYPE_LASERSCOPE:
+ {
+ if (shooter == FindPlayerPed())
+ fired = FireSniper(shooter);
+ else
+ fired = FireInstantHit(shooter, source);
+
+ break;
+ }
+
case WEAPONTYPE_COLT45:
case WEAPONTYPE_PYTHON:
case WEAPONTYPE_UZI:
@@ -236,17 +221,6 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
break;
}
- case WEAPONTYPE_SNIPERRIFLE:
- case WEAPONTYPE_LASERSCOPE:
- {
- if (shooter == FindPlayerPed()) {
- fired = FireSniper(shooter);
- } else {
- fired = FireInstantHit(shooter, source);
- }
- break;
- }
-
case WEAPONTYPE_ROCKETLAUNCHER:
{
if ( shooter->IsPed() && ((CPed*)shooter)->m_pSeekTarget != nil )
@@ -272,8 +246,6 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
if ( shooter == FindPlayerPed() )
{
fired = FireProjectile(shooter, source, ((CPlayerPed*)shooter)->m_fAttackButtonCounter*0.0375f);
- if ( m_eWeaponType == WEAPONTYPE_GRENADE )
- CStats::KgsOfExplosivesUsed++;
}
else if ( shooter->IsPed() && ((CPed*)shooter)->m_pSeekTarget != nil )
{
@@ -309,6 +281,13 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
break;
}
+
+ case WEAPONTYPE_CAMERA:
+ {
+ fired = TakePhotograph(shooter);
+
+ break;
+ }
default:
{
@@ -324,14 +303,59 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
if (shooter->IsPed())
{
CPed* shooterPed = (CPed*)shooter;
-
- shooterPed->bIsShooting = true;
-
- if (shooterPed->IsPlayer())
- isPlayer = true;
-
+
+ if ( m_eWeaponType != WEAPONTYPE_CAMERA )
+ {
+ shooterPed->bIsShooting = true;
+
+ if (shooterPed->IsPlayer())
+ isPlayer = true;
+ }
+
DMAudio.PlayOneShot(shooterPed->m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f);
+
+ if ( isPlayer )
+ {
+ CPed *aimPed = (CPed *)shooterPed->m_pSeekTarget;
+ if ( aimPed )
+ {
+ if ( aimPed->IsPed() )
+ shooterPed->Say(SOUND_PED_ON_FIRE);
+ }
+ }
}
+
+ switch ( m_eWeaponType )
+ {
+ case WEAPONTYPE_COLT45:
+ case WEAPONTYPE_PYTHON:
+ case WEAPONTYPE_SHOTGUN:
+ case WEAPONTYPE_SPAS12_SHOTGUN:
+ case WEAPONTYPE_STUBBY_SHOTGUN:
+ case WEAPONTYPE_TEC9:
+ case WEAPONTYPE_UZI:
+ case WEAPONTYPE_SILENCED_INGRAM:
+ case WEAPONTYPE_MP5:
+ case WEAPONTYPE_M4:
+ case WEAPONTYPE_RUGER:
+ case WEAPONTYPE_SNIPERRIFLE:
+ case WEAPONTYPE_LASERSCOPE:
+ case WEAPONTYPE_M60:
+ case WEAPONTYPE_MINIGUN:
+ CStats::RoundsFiredByPlayer++;
+ break;
+
+ case WEAPONTYPE_GRENADE:
+ case WEAPONTYPE_DETONATOR_GRENADE:
+ case WEAPONTYPE_MOLOTOV:
+ case WEAPONTYPE_ROCKET:
+ case WEAPONTYPE_ROCKETLAUNCHER:
+ case WEAPONTYPE_DETONATOR:
+ case WEAPONTYPE_HELICANNON:
+ CStats::KgsOfExplosivesUsed++;
+ break;
+ }
+
if (m_nAmmoInClip > 0)
m_nAmmoInClip--;
@@ -365,13 +389,10 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
return true;
}
- if (addFireRateAsDelay)
+ if ( addFireRateAsDelay )
m_nTimer = CTimer::GetTimeInMilliseconds() + GetInfo()->m_nFiringRate;
else
m_nTimer = CTimer::GetTimeInMilliseconds();
-
- if (shooter == FindPlayerPed())
- CStats::RoundsFiredByPlayer++;
}
}
else
@@ -380,12 +401,11 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
{
m_nTimer = CTimer::GetTimeInMilliseconds() + GetInfo()->m_nReload;
m_eWeaponState = WEAPONSTATE_FIRING;
-#ifndef AUDIO_NOT_READY
+
if (shooter->IsPed() && m_eWeaponType != WEAPONTYPE_CHAINSAW)
{
- DMAudio.PlayOneShot(((CPed*)shooter)->m_audioEntityId, 188, m_eWeaponType << 8);
+ DMAudio.PlayOneShot(((CPed*)shooter)->m_audioEntityId, SOUND_MELEE_ATTACK_START, m_eWeaponType << 8);
}
-#endif
}
fired = FireMelee(shooter, *source);
@@ -397,7 +417,6 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
return fired;
}
-// --MIAMI: Done
bool
CWeapon::FireFromCar(CVehicle *shooter, bool left, bool right)
{
@@ -438,7 +457,6 @@ CWeapon::FireFromCar(CVehicle *shooter, bool left, bool right)
return true;
}
-// --MIAMI: Done, except commented things
bool
CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
{
@@ -446,20 +464,27 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
CWeaponInfo *info = GetInfo();
- bool anim2Playing = RpAnimBlendClumpGetAssociation(shooter->GetClump(), CPed::GetFireAnimGround(info, false));
-
+ bool anim2Playing = false;
+
+ if ( CPed::GetFireAnimGround(info, false) != (AnimationId)0 )
+ {
+ if ( RpAnimBlendClumpGetAssociation(shooter->GetClump(), CPed::GetFireAnimGround(info, false)) )
+ anim2Playing = true;
+ }
+
ASSERT(shooter->IsPed());
CPed *shooterPed = (CPed*)shooter;
- if (shooterPed == FindPlayerPed()) {
+ if (shooterPed == FindPlayerPed())
+ {
if (m_eWeaponType == WEAPONTYPE_GOLFCLUB || m_eWeaponType == WEAPONTYPE_NIGHTSTICK ||
- (m_eWeaponType >= WEAPONTYPE_BASEBALLBAT && m_eWeaponType <= WEAPONTYPE_CHAINSAW)) {
+ (m_eWeaponType >= WEAPONTYPE_BASEBALLBAT && m_eWeaponType <= WEAPONTYPE_CHAINSAW))
+ {
+ CGlass::BreakGlassPhysically(fireSource, info->m_fRadius);
- // TODO(Miami): BreakGlassPhysically
- if (m_eWeaponType == WEAPONTYPE_CHAINSAW) {
+ if (m_eWeaponType == WEAPONTYPE_CHAINSAW)
CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_PED, FindPlayerPed(), FindPlayerPed(), 1000);
- }
}
}
@@ -505,11 +530,10 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
{
CColSphere *sphere = &victimPedCol->spheres[s];
- if (useLocalPos) {
+ if (useLocalPos)
collisionDist = sphere->center - (*fireSource);
- } else {
+ else
collisionDist = victimPedPos + sphere->center - (*fireSource);
- }
if ( SQR(sphere->radius + info->m_fRadius) > collisionDist.MagnitudeSqr() )
{
@@ -532,21 +556,26 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
bool isHeavy = m_eWeaponType >= WEAPONTYPE_GOLFCLUB && m_eWeaponType <= WEAPONTYPE_KATANA && m_eWeaponType != WEAPONTYPE_HAMMER;
- if (shooterPed->m_fDamageImpulse == 0.0f) {
+ if (shooterPed->m_fDamageImpulse == 0.0f)
+ {
shooterPed->m_pDamageEntity = victimPed;
victimPed->RegisterReference(&shooterPed->m_pDamageEntity);
}
damageEntityRegistered = 3;
- if (victimPed->bInVehicle) {
+ if (victimPed->bInVehicle)
+ {
CVehicle *victimVeh = victimPed->m_pMyVehicle;
- if (victimVeh) {
- if (victimVeh->IsBike()) {
+ if (victimVeh)
+ {
+ if (victimVeh->IsBike())
+ {
CBike *victimBike = (CBike*)victimVeh;
victimBike->KnockOffRider(m_eWeaponType, localDir, victimPed, false);
- if (victimBike->pDriver) {
+ if (victimBike->pDriver)
victimBike->pDriver->ReactToAttack(shooterPed);
- } else {
+ else
+ {
if (victimVeh->pPassengers[0])
victimVeh->pPassengers[0]->ReactToAttack(shooterPed);
}
@@ -625,9 +654,7 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
}
if (info->m_AnimToPlay == ASSOCGRP_KNIFE)
{
- dir.x += 0.1f * shooterPed->GetUp().x + 0.05f * shooterPed->GetRight().x;
- dir.y += 0.1f * shooterPed->GetUp().y + 0.05f * shooterPed->GetRight().y;
- dir.z += 0.1f * shooterPed->GetUp().z + 0.05f * shooterPed->GetRight().z;
+ dir += 0.1f * shooterPed->GetUp() + 0.05f * shooterPed->GetRight();
CParticle::AddParticle(PARTICLE_BLOOD_SPURT, bloodPos, dir);
CParticle::AddParticle(PARTICLE_BLOOD_SPURT, bloodPos, dir);
CParticle::AddParticle(PARTICLE_BLOOD_SPURT, bloodPos, dir);
@@ -637,7 +664,7 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
if ( !victimPed->OnGround() )
{
if ( victimPed->m_fHealth > 0.0f
- && (victimPed->m_fHealth < 30.0f && victimPedHealth > 20.0f ||
+ && (victimPed->m_fHealth < 30.0f && victimPedHealth > 30.0f ||
(isHeavy || m_eWeaponType == WEAPONTYPE_BRASSKNUCKLE) && !victimPed->IsPlayer()) )
{
posOffset.Normalise();
@@ -703,7 +730,8 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
float oldHealth = nearCar->m_fHealth;
if (m_eWeaponType == WEAPONTYPE_CHAINSAW)
{
- for(int i=0; i<4; i++) {
+ for( int32 i=0; i<4; i++ )
+ {
CParticle::AddParticle(PARTICLE_SPARK_SMALL, gaTempSphereColPoints[0].point, CVector(0.0f, 0.0f, 0.3f));
CParticle::AddParticle(PARTICLE_SPARK, gaTempSphereColPoints[0].point, gaTempSphereColPoints[0].normal * 0.1f);
}
@@ -716,7 +744,7 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
}
else
{
- nearCar->VehicleDamage(info->m_nDamage* (0.00075f * nearCar->pHandling->fMass), gaTempSphereColPoints[0].pieceB);
+ nearCar->VehicleDamage(info->m_nDamage* (0.01f * nearCar->pHandling->fMass), gaTempSphereColPoints[0].pieceB);
}
if (nearCar->m_fHealth < oldHealth)
{
@@ -808,7 +836,6 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
return true;
}
-// --MIAMI: Done except comments
bool
CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
{
@@ -856,13 +883,13 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
target = threatAttack->GetPosition();
target -= *fireSource;
- float distToTarget = target.Magnitude();
+ float distToTarget = Max(target.Magnitude(), 0.01f);
target *= info->m_fRange / distToTarget;
target += *fireSource;
if (shooter == FindPlayerPed() && inaccuracy != 0.f)
{
- float newInaccuracy = 2.5f * FindPlayerPed()->m_fAttackButtonCounter * (inaccuracy * Min(1.f, 5.f / distToTarget));
+ float newInaccuracy = fPlayerAimScale * FindPlayerPed()->m_fAttackButtonCounter * (inaccuracy * Min(1.f, fPlayerAimScaleDist / distToTarget));
if (FindPlayerPed()->bIsDucking)
newInaccuracy *= 0.4f;
@@ -886,10 +913,10 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
if (shooter == FindPlayerPed())
CWorld::bIncludeDeadPeds = true;
- // bProcessPedsOnBoatsAndBikes = true; // TODO(Miami)
+ CWorld::bIncludeBikers = true;
CWorld::ProcessLineOfSight(*fireSource, target, point, victim, true, true, true, true, true, false, false, true);
CWorld::bIncludeDeadPeds = false;
- // bProcessPedsOnBoatsAndBikes = false; // TODO(Miami)
+ CWorld::bIncludeBikers = false;
}
else
{
@@ -899,9 +926,9 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
shooterPed->TransformToNode(target, PED_HANDR);
- // bProcessPedsOnBoatsAndBikes = true; // TODO(Miami)
+ CWorld::bIncludeBikers = true;
CWorld::ProcessLineOfSight(*fireSource, target, point, victim, true, true, true, true, true, false, false, true);
- // bProcessPedsOnBoatsAndBikes = false; // TODO(Miami)
+ CWorld::bIncludeBikers = false;
}
}
else if ( shooter == FindPlayerPed() && TheCamera.Cams[0].Using3rdPersonMouseCam() )
@@ -909,11 +936,11 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
CVector src, trgt;
TheCamera.Find3rdPersonCamTargetVector(info->m_fRange, *fireSource, src, trgt);
- // bProcessPedsOnBoatsAndBikes = true; // TODO(Miami)
+ CWorld::bIncludeBikers = true;
CWorld::bIncludeDeadPeds = true;
CWorld::bIncludeCarTyres = true;
CWorld::ProcessLineOfSight(src, trgt, point, victim, true, true, true, true, true, false, false, true);
- // bProcessPedsOnBoatsAndBikes = false; // TODO(Miami)
+ CWorld::bIncludeBikers = false;
CWorld::bIncludeDeadPeds = false;
CWorld::bIncludeCarTyres = false;
@@ -990,9 +1017,9 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
CWeapon::DoDoomAiming(shooter, fireSource, &target);
}
- // CWorld::bProcessPedsOnBoatsAndBikes = 1; // TODO(Miami)
+ CWorld::bIncludeBikers = true;
CWorld::ProcessLineOfSight(*fireSource, target, point, victim, true, true, true, true, true, false, false, true);
- // CWorld::bProcessPedsOnBoatsAndBikes = 0; // TODO(Miami)
+ CWorld::bIncludeBikers = false;
int32 rotSpeed = 1;
if (m_eWeaponType == WEAPONTYPE_M4)
@@ -1007,7 +1034,7 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
}
}
- if (victim && shooter->IsPed())
+ if ( shooter->IsPed() && victim)
{
if (victim == ((CPed*)shooter)->m_leader)
return false;
@@ -1134,6 +1161,71 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
}
void
+CWeapon::AddGunFlashBigGuns(CVector start, CVector end)
+{
+ CPointLights::AddLight(CPointLights::LIGHT_POINT,
+ start, CVector(0.0f, 0.0f, 0.0f), 5.0f,
+ 1.0f, 0.8f, 0.0f, CPointLights::FOG_NONE, false);
+ CVector gunflashPos = start;
+
+ CVector shootVec = end - start;
+
+ // Wtf did you do there R*?
+ shootVec.Normalise();
+ CVector2D ahead = shootVec;
+ ahead.Normalise();
+
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.08f);
+ 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.06f);
+ 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.06f);
+
+ gunflashPos = start;
+ gunflashPos += CVector(-0.1f * ahead.x, -0.1f * ahead.y, 0.0f);
+ gunflashPos.z += 0.04f;
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
+ gunflashPos.z += 0.04f;
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
+ gunflashPos.z += 0.03f;
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
+
+ gunflashPos = start;
+ gunflashPos += CVector(-0.1f * ahead.x, -0.1f * ahead.y, 0.0f);
+ gunflashPos.z -= 0.04f;
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
+ gunflashPos.z -= 0.04f;
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
+ gunflashPos.z -= 0.03f;
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
+
+ CVector offset = CrossProduct(CVector(ahead.x, ahead.y, 0.0f), CVector(0.0f, 0.0f, 5.0f));
+ offset.Normalise2D();
+
+ gunflashPos = start;
+ gunflashPos += CVector(-0.1f * ahead.x, -0.1f * ahead.y, 0.0f);
+ gunflashPos += CVector(0.06f * offset.x, 0.06f * offset.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
+ gunflashPos += CVector(0.04f * offset.x, 0.04f * offset.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.03f);
+ gunflashPos += CVector(0.03f * offset.x, 0.03f * offset.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
+
+ gunflashPos = start;
+ gunflashPos += CVector(-0.1f * ahead.x, -0.1f * ahead.y, 0.0f);
+ gunflashPos -= CVector(0.06f * offset.x, 0.06f * offset.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
+ gunflashPos -= CVector(0.04f * offset.x, 0.04f * offset.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.03f);
+ gunflashPos -= CVector(0.03f * offset.x, 0.03f * offset.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
+
+ CVector gunsmokePos = start;
+ float rnd = CGeneral::GetRandomNumberInRange(0.05f, 0.25f);
+ CParticle::AddParticle(PARTICLE_GUNSMOKE2, gunsmokePos, CVector(ahead.x * rnd, ahead.y * rnd, 0.0f));
+}
+
+void
CWeapon::AddGunshell(CEntity *shooter, CVector const &source, CVector2D const &direction, float size)
{
ASSERT(shooter!=nil);
@@ -1162,7 +1254,7 @@ CWeapon::AddGunshell(CEntity *shooter, CVector const &source, CVector2D const &d
}
}
-// --MIAMI: Done?
+
void
CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
CVector *source, CVector *target, CColPoint *point, CVector2D ahead)
@@ -1227,7 +1319,7 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
CGlass::WasGlassHitByBullet(victim, point->point);
CVector traceTarget = point->point;
- CBulletTraces::AddTrace(source, &traceTarget);
+ CBulletTraces::AddTrace(source, &traceTarget, m_eWeaponType, shooter);
if (victim->IsPed() && shooter->IsVehicle() && ((CVehicle*)shooter)->pDriver)
shooter = ((CVehicle*)shooter)->pDriver;
@@ -1492,7 +1584,7 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
}
}
else
- CBulletTraces::AddTrace(source, target);
+ CBulletTraces::AddTrace(source, target, m_eWeaponType, shooter);
if ( shooter == FindPlayerPed() )
CPad::GetPad(0)->StartShake_Distance(240, 128, FindPlayerPed()->GetPosition().x, FindPlayerPed()->GetPosition().y, FindPlayerPed()->GetPosition().z);
@@ -1500,7 +1592,7 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
BlowUpExplosiveThings(victim);
}
-// --MIAMI: Done except comments, and didn't check particle coords precisely
+
bool
CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
{
@@ -1576,6 +1668,7 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
{
float shootAngle = DEGTORAD(RADTODEG(halfAngleRange - angleBetweenTwoShot * i) + shooterAngle);
CVector2D shootRot(-Sin(shootAngle), Cos(shootAngle));
+ shootRot.Normalise();
CVector source, target;
CColPoint point;
@@ -1590,10 +1683,9 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
target = f * Left + target - source;
target *= info->m_fRange;
target += source;
- CWorld::bIncludeDeadPeds = true;
CWorld::bIncludeCarTyres = true;
- //bProcessPedsOnBoatsAndBikes = true; // TODO(Miami): bProcessPedsOnBoatsAndBikes
-
+ CWorld::bIncludeBikers = true;
+ CWorld::bIncludeDeadPeds = true;
CWorld::ProcessLineOfSight(source, target, point, victim, true, true, true, true, true, false, false, true);
CWorld::bIncludeDeadPeds = false;
CWorld::bIncludeCarTyres = false;
@@ -1626,11 +1718,11 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
if (shooter == FindPlayerPed())
CWorld::bIncludeDeadPeds = true;
- //bProcessPedsOnBoatsAndBikes = true; // TODO(Miami): bProcessPedsOnBoatsAndBikes
+ CWorld::bIncludeBikers = true;
CWorld::ProcessLineOfSight(*fireSource, target, point, victim, true, true, true, true, true, false, false, true);
CWorld::bIncludeDeadPeds = false;
}
- //bProcessPedsOnBoatsAndBikes = false; // TODO(Miami): bProcessPedsOnBoatsAndBikes
+ CWorld::bIncludeBikers = false;
if ( victim )
{
@@ -1684,7 +1776,7 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
}
}
}
- CBulletTraces::AddTrace(fireSource, &point.point);
+ CBulletTraces::AddTrace(fireSource, &point.point, m_eWeaponType, shooter);
if ( victim->IsPed() )
{
@@ -1899,7 +1991,7 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
{
CVector traceTarget = *fireSource;
traceTarget += (target - (*fireSource)) * Min(info->m_fRange, 30.0f) / info->m_fRange;
- CBulletTraces::AddTrace(fireSource, &traceTarget);
+ CBulletTraces::AddTrace(fireSource, &traceTarget, m_eWeaponType, shooter);
}
}
@@ -1980,6 +2072,14 @@ CWeapon::FireProjectile(CEntity *shooter, CVector *fireSource, float power)
}
else
CProjectileInfo::AddProjectile(shooter, projectileType, *fireSource, power);
+
+
+ CWorld::pIgnoreEntity = nil;
+
+ if ( shooter->IsPed() )
+ CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_PED, shooter, (CPed *)shooter, 1000);
+ else if ( shooter->IsVehicle() && ((CVehicle*)shooter)->pDriver )
+ CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_VEHICLE, shooter, ((CVehicle*)shooter)->pDriver, 1000);
return true;
}
@@ -2032,24 +2132,76 @@ CWeapon::FireAreaEffect(CEntity *shooter, CVector *fireSource)
CShotInfo::AddShot(shooter, m_eWeaponType, *fireSource, target);
CWeapon::GenerateFlameThrowerParticles(*fireSource, dir);
+
+ if ( shooter == (CEntity *)FindPlayerPed() )
+ {
+ for ( int32 i = 0; i < FindPlayerPed()->m_numNearPeds; i++ )
+ {
+ if ( FindPlayerPed()->m_nearPeds[i]->CharCreatedBy == RANDOM_CHAR )
+ {
+ if ( FindPlayerPed()->m_nearPeds[i]->IsPedInControl() && FindPlayerPed()->m_nearPeds[i]->m_nPedState != PED_FLEE_ENTITY )
+ FindPlayerPed()->m_nearPeds[i]->SetFlee(shooter, 10000);
+ }
+ }
+ }
return true;
}
bool
+CWeapon::LaserScopeDot(CVector *pOutPos, float *pOutSize)
+{
+ CWeaponInfo *info = GetInfo();
+
+ float range = info->m_fRange;
+
+ CVector source, target;
+ CEntity *foundEnt = nil;
+ CColPoint foundCol;
+
+ source = 0.5f * TheCamera.Cams[TheCamera.ActiveCam].Front + TheCamera.Cams[TheCamera.ActiveCam].Source;
+ target = TheCamera.Cams[TheCamera.ActiveCam].Front;
+ target.Normalise();
+ target *= range;
+ target += source;
+
+ if ( CWorld::ProcessLineOfSight(source, target, foundCol, foundEnt, true, true, true, true, false, false, false) )
+ {
+ CVector pos = foundCol.point;
+ float w, h;
+
+ if ( CSprite::CalcScreenCoors(foundCol.point, pos, &w, &h, true) )
+ {
+ *pOutPos = pos;
+ *pOutSize = w * 0.05f;
+
+ CCoronas::RegisterCorona((uintptr)this + 7, 128, 0, 0, 255, pos, 1.2f, 50.0f, CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, 0.0f);
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool
CWeapon::FireSniper(CEntity *shooter)
{
ASSERT(shooter!=nil);
-
- int16 mode = TheCamera.Cams[TheCamera.ActiveCam].Mode;
- if (!( mode == CCam::MODE_M16_1STPERSON
- || mode == CCam::MODE_SNIPER
- || mode == CCam::MODE_ROCKETLAUNCHER
- || mode == CCam::MODE_M16_1STPERSON_RUNABOUT
- || mode == CCam::MODE_SNIPER_RUNABOUT
- || mode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT) )
+
+ if ( (CEntity *)FindPlayerPed() == shooter )
{
- return false;
+ int16 mode = TheCamera.Cams[TheCamera.ActiveCam].Mode;
+ if (!( mode == CCam::MODE_M16_1STPERSON
+ || mode == CCam::MODE_SNIPER
+ || mode == CCam::MODE_CAMERA
+ || mode == CCam::MODE_ROCKETLAUNCHER
+ || mode == CCam::MODE_M16_1STPERSON_RUNABOUT
+ || mode == CCam::MODE_SNIPER_RUNABOUT
+ || mode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT) )
+ {
+ return false;
+ }
}
#ifndef FIX_BUGS
@@ -2076,14 +2228,74 @@ CWeapon::FireSniper(CEntity *shooter)
FindPlayerPed()->GetPosition().x,
FindPlayerPed()->GetPosition().y,
FindPlayerPed()->GetPosition().z);
+
+ CParticle::HandleShootableBirdsStuff(shooter, source);
CamShakeNoPos(&TheCamera, 0.2f);
}
+ if ( shooter->IsPed() )
+ CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_PED, shooter, (CPed*)shooter, 1000);
+ else if ( shooter->IsVehicle() && ((CVehicle*)shooter)->pDriver )
+ CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_VEHICLE, shooter, ((CVehicle*)shooter)->pDriver, 1000);
+
return true;
}
-// --MIAMI: Done
+bool
+CWeapon::TakePhotograph(CEntity *shooter)
+{
+ if ( TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_CAMERA )
+ {
+ CSpecialFX::bSnapShotActive = true;
+ CSpecialFX::SnapShotFrames = 0;
+ CStats::PhotosTaken++;
+ bPhotographHasBeenTaken = true;
+
+ for ( int32 i = CPools::GetPedPool()->GetSize() - 1; i >= 0; i--)
+ {
+ CPed *ped = CPools::GetPedPool()->GetSlot(i);
+ if ( ped )
+ {
+ if ( (ped->GetPosition() - TheCamera.GetPosition()).Magnitude() < 125.0f )
+ {
+ CVector pedPos = ped->GetPosition();
+ pedPos.z += 0.8f;
+
+ CVector pos;
+ float w, h;
+
+ if ( CSprite::CalcScreenCoors(pedPos, pos, &w, &h, false) )
+ {
+ if ( SCREEN_WIDTH * 0.1f < pos.x && SCREEN_WIDTH * 0.9f > pos.x
+ && SCREEN_HEIGHT * 0.1f < pos.y && SCREEN_HEIGHT * 0.9f > pos.y )
+ {
+ CVector source, target;
+ CEntity *foundEnt = nil;
+ CColPoint foundCol;
+
+ target = pedPos;
+ source = TheCamera.GetForward() * 2.0f + TheCamera.GetPosition();
+
+ if ( CWorld::ProcessLineOfSight(source, target, foundCol, foundEnt, true, true, true, true, true, true, false) )
+ {
+ if ( foundEnt != (CEntity*)ped )
+ continue;
+ }
+
+ ped->bHasBeenPhotographed = true;
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
bool
CWeapon::FireM16_1stPerson(CEntity *shooter)
{
@@ -2106,7 +2318,7 @@ CWeapon::FireM16_1stPerson(CEntity *shooter)
CWeaponInfo *info = GetInfo();
CWorld::bIncludeCarTyres = true;
- // bProcessPedsOnBoatsAndBikes = true; // TODO(Miami)
+ CWorld::bIncludeBikers = true;
CColPoint point;
CEntity *victim;
@@ -2125,7 +2337,7 @@ CWeapon::FireM16_1stPerson(CEntity *shooter)
}
CWorld::pIgnoreEntity = nil;
CWorld::bIncludeDeadPeds = false;
- // bProcessPedsOnBoatsAndBikes = false; // TODO(Miami)
+ CWorld::bIncludeBikers = false;
CWorld::bIncludeCarTyres = false;
CVector2D front(cam->Front.x, cam->Front.y);
@@ -2180,41 +2392,81 @@ CWeapon::FireM16_1stPerson(CEntity *shooter)
bool
CWeapon::FireInstantHitFromCar(CVehicle *shooter, bool left, bool right)
{
-// TODO(MIAMI): bikes
CWeaponInfo *info = GetInfo();
CVehicleModelInfo *modelInfo = shooter->GetModelInfo();
-
+
CVector source, target;
- if ( left )
+
+ if ( shooter->IsBike() )
{
- source = shooter->GetMatrix() * CVector(-shooter->GetColModel()->boundingBox.max.x + -0.2f,
- float(CGeneral::GetRandomNumber() & 255) * 0.001f + modelInfo->GetFrontSeatPosn().y,
- modelInfo->GetFrontSeatPosn().z + 0.5f);
- source += CTimer::GetTimeStep() * shooter->m_vecMoveSpeed;
-
-
- target = shooter->GetMatrix() * CVector(-info->m_fRange,
- modelInfo->GetFrontSeatPosn().y,
+ if ( shooter->pDriver )
+ {
+ source = info->m_vecFireOffset;
+
+ shooter->pDriver->TransformToNode(source, PED_HANDR);
+ source += CTimer::GetTimeStep() * shooter->m_vecMoveSpeed;
+
+ if ( left )
+ target = source - info->m_fRange * shooter->GetRight();
+ else if ( right )
+ target = source + info->m_fRange * shooter->GetRight();
+ else
+ target = source + info->m_fRange * shooter->GetForward();
+
+ }
+ else if ( left )
+ {
+ source = shooter->GetMatrix() * CVector(-shooter->GetColModel()->boundingBox.max.x + -0.25f,
+ float(CGeneral::GetRandomNumber() & 255) * 0.001f + modelInfo->GetFrontSeatPosn().y - 0.05f,
+ modelInfo->GetFrontSeatPosn().z + 0.63f);
+ source += CTimer::GetTimeStep() * shooter->m_vecMoveSpeed;
+
+
+ target = shooter->GetMatrix() * CVector(-info->m_fRange,
+ modelInfo->GetFrontSeatPosn().y,
+ modelInfo->GetFrontSeatPosn().z + 0.6f);
+ }
+ else if ( right )
+ {
+ source = shooter->GetMatrix() * CVector(shooter->GetColModel()->boundingBox.max.x + 0.25f,
+ float(CGeneral::GetRandomNumber() & 255) * 0.001f + modelInfo->GetFrontSeatPosn().y - 0.18f,
+ modelInfo->GetFrontSeatPosn().z + 0.52f);
+ source += CTimer::GetTimeStep() * shooter->m_vecMoveSpeed;
+
+ target = shooter->GetMatrix() * CVector(info->m_fRange,
+ modelInfo->GetFrontSeatPosn().y,
+ modelInfo->GetFrontSeatPosn().z + 0.5f);
+ }
+ else
+ {
+ source = shooter->GetMatrix() * CVector(float(CGeneral::GetRandomNumber() & 255) * 0.001f + -0.4f,
+ modelInfo->GetFrontSeatPosn().y + shooter->GetColModel()->boundingBox.max.y + 0.2f,
+ modelInfo->GetFrontSeatPosn().z + 0.55f);
+ source += CTimer::GetTimeStep() * shooter->m_vecMoveSpeed;
+
+ target = shooter->GetMatrix() * CVector(0.0f,
+ info->m_fRange,
modelInfo->GetFrontSeatPosn().z + 0.5f);
+ }
}
else
{
- source = shooter->GetMatrix() * CVector(shooter->GetColModel()->boundingBox.max.x + 0.2f,
- float(CGeneral::GetRandomNumber() & 255) * 0.001f + modelInfo->GetFrontSeatPosn().y,
- modelInfo->GetFrontSeatPosn().z + 0.5f);
+ if ( left )
+ source = info->m_vecFireOffset;
+ else
+ {
+ source = 1.8f * info->m_vecFireOffset;
+ source.z -= 0.1f;
+ }
+
+ shooter->pDriver->TransformToNode(source, PED_HANDR);
source += CTimer::GetTimeStep() * shooter->m_vecMoveSpeed;
-
- target = shooter->GetMatrix() * CVector(info->m_fRange,
- modelInfo->GetFrontSeatPosn().y,
- modelInfo->GetFrontSeatPosn().z + 0.5f);
- }
- #undef FRONTSEATPOS
-
- if ( TheCamera.GetLookingLRBFirstPerson() && !left )
- {
- source -= 0.3f * shooter->GetForward();
- target -= 0.3f * shooter->GetForward();
+
+ if ( left )
+ target = source - info->m_fRange * shooter->GetRight();
+ else
+ target = source + info->m_fRange * shooter->GetRight();
}
target += CVector(float(CGeneral::GetRandomNumber()&255)*0.01f-1.28f,
@@ -2226,9 +2478,14 @@ CWeapon::FireInstantHitFromCar(CVehicle *shooter, bool left, bool right)
CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_PED, FindPlayerPed(), FindPlayerPed(), 1000);
if ( !TheCamera.GetLookingLRBFirstPerson() )
- CParticle::AddParticle(PARTICLE_GUNFLASH, source, CVector(0.0f, 0.0f, 0.0f));
+ {
+ if ( !shooter->IsBike() )
+ CParticle::AddParticle(PARTICLE_GUNFLASH, source, CVector(0.0f, 0.0f, 0.0f));
+ else
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, source, 1.4f*shooter->m_vecMoveSpeed);
+ }
else
- CamShakeNoPos(&TheCamera, 0.01f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, source, 1.6f*shooter->m_vecMoveSpeed, nil, 0.18f);
CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_VEHICLE, shooter, FindPlayerPed(), 1000);
@@ -2237,7 +2494,12 @@ CWeapon::FireInstantHitFromCar(CVehicle *shooter, bool left, bool right)
CColPoint point;
CEntity *victim;
+
+ CWorld::bIncludeBikers = true;
+ CWorld::pIgnoreEntity = shooter;
ProcessLineOfSight(source, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false);
+ CWorld::pIgnoreEntity = NULL;
+ CWorld::bIncludeBikers = false;
if ( !(CTimer::GetFrameCounter() & 3) )
MakePedsJumpAtShot(shooter, &source, &target);
@@ -2245,7 +2507,7 @@ CWeapon::FireInstantHitFromCar(CVehicle *shooter, bool left, bool right)
if ( victim )
{
CVector traceTarget = point.point;
- CBulletTraces::AddTrace(&source, &traceTarget);
+ CBulletTraces::AddTrace(&source, &traceTarget, m_eWeaponType, shooter);
if ( victim->IsPed() )
{
@@ -2332,7 +2594,7 @@ CWeapon::FireInstantHitFromCar(CVehicle *shooter, bool left, bool right)
{
float norm = 30.0f/info->m_fRange;
CVector traceTarget = (target-source)*norm + source;
- CBulletTraces::AddTrace(&source, &traceTarget);
+ CBulletTraces::AddTrace(&source, &traceTarget, m_eWeaponType, shooter);
}
if ( shooter == FindPlayerVehicle() )
@@ -2341,7 +2603,6 @@ CWeapon::FireInstantHitFromCar(CVehicle *shooter, bool left, bool right)
return true;
}
-// --MIAMI: Done
void
CWeapon::DoDoomAiming(CEntity *shooter, CVector *source, CVector *target)
{
@@ -2484,7 +2745,7 @@ CWeapon::DoTankDoomAiming(CEntity *shooter, CEntity *driver, CVector *source, CV
}
}
-// --MIAMI: Done
+
void
CWeapon::DoDriveByAutoAiming(CEntity *driver, CVehicle *vehicle, CVector *source, CVector *target)
{
@@ -2538,11 +2799,11 @@ CWeapon::DoDriveByAutoAiming(CEntity *driver, CVehicle *vehicle, CVector *source
float maxAimDistance = CAR_DRIVEBYAUTOAIMING_MAXDIST;
if (model == MI_HUNTER)
{
- maxAimDistance = Tan(DEGTORAD(30.f));
+ maxAimDistance = Tan(DEGTORAD(fHunterAimingAngle));
}
else if (model == MI_SEASPAR || model == MI_SPARROW)
{
- maxAimDistance = Tan(DEGTORAD(10.f));
+ maxAimDistance = Tan(DEGTORAD(fSeaSparrowAimingAngle));
}
if ( closestEntityDist < maxAimDistance )
@@ -2587,7 +2848,7 @@ CWeapon::Update(int32 audioEntity, CPed *pedToAdjustSound)
{
if ( IsShotgun(m_eWeaponType) && AEHANDLE_IS_OK(audioEntity) )
{
- uint32 timePassed = m_nTimer - gReloadSampleTime[m_eWeaponType];
+ uint32 timePassed = m_nTimer - CWeaponInfo::ms_aReloadSampleTime[m_eWeaponType];
if ( CTimer::GetPreviousTimeInMilliseconds() < timePassed && CTimer::GetTimeInMilliseconds() >= timePassed )
DMAudio.PlayOneShot(audioEntity, SOUND_WEAPON_RELOAD, 0.0f);
}
@@ -2596,7 +2857,7 @@ CWeapon::Update(int32 audioEntity, CPed *pedToAdjustSound)
{
if ( GetInfo()->m_eWeaponFire != WEAPON_FIRE_MELEE && m_nAmmoTotal == 0 ) {
m_eWeaponState = WEAPONSTATE_OUT_OF_AMMO;
- // TODO(Miami): CPickups::RemoveAllPickupsOfACertainWeaponGroupWithNoAmmo
+ CPickups::RemoveAllPickupsOfACertainWeaponGroupWithNoAmmo(m_eWeaponType);
} else
m_eWeaponState = WEAPONSTATE_READY;
}
@@ -2621,20 +2882,20 @@ CWeapon::Update(int32 audioEntity, CPed *pedToAdjustSound)
float soundStart = 0.75f;
switch (info->m_AnimToPlay) {
case ASSOCGRP_PYTHON:
- soundStart = 0.5f;
+ soundStart = fReloadAnimSampleFraction[0];
break;
case ASSOCGRP_COLT:
case ASSOCGRP_TEC:
- soundStart = 0.7f;
+ soundStart = fReloadAnimSampleFraction[1];
break;
case ASSOCGRP_UZI:
- soundStart = 0.75f;
+ soundStart = fReloadAnimSampleFraction[2];
break;
case ASSOCGRP_RIFLE:
- soundStart = 0.75f;
+ soundStart = fReloadAnimSampleFraction[3];
break;
case ASSOCGRP_M60:
- soundStart = 0.7f;
+ soundStart = fReloadAnimSampleFraction[4];
break;
default:
break;
@@ -2650,8 +2911,9 @@ CWeapon::Update(int32 audioEntity, CPed *pedToAdjustSound)
m_nTimer = CTimer::GetTimeInMilliseconds();
}
} else {
- uint32 timePassed = m_nTimer - gReloadSampleTime[m_eWeaponType];
- if (CTimer::GetPreviousTimeInMilliseconds() < timePassed && CTimer::GetTimeInMilliseconds() >= timePassed) {
+ uint32 timePassed = m_nTimer - CWeaponInfo::ms_aReloadSampleTime[m_eWeaponType];
+ if (CTimer::GetPreviousTimeInMilliseconds() < timePassed && CTimer::GetTimeInMilliseconds() >= timePassed)
+ {
#ifdef AUDIO_NOT_READY
DMAudio.PlayOneShot(audioEntity, SOUND_WEAPON_RELOAD, 0.0f);
#else
@@ -2745,17 +3007,20 @@ FireOneInstantHitRound(CVector *source, CVector *target, int32 damage)
}
case ENTITY_TYPE_VEHICLE:
{
+ CStats::BulletsThatHit++;
DMAudio.PlayOneShot(((CPhysical*)victim)->m_audioEntityId, SOUND_WEAPON_HIT_VEHICLE, 1.0f);
break;
}
case ENTITY_TYPE_PED:
{
+ CStats::BulletsThatHit++;
DMAudio.PlayOneShot(((CPhysical*)victim)->m_audioEntityId, SOUND_WEAPON_HIT_PED, 1.0f);
((CPed*)victim)->Say(SOUND_PED_BULLET_HIT);
break;
}
case ENTITY_TYPE_OBJECT:
{
+ CStats::BulletsThatHit++;
PlayOneShotScriptObject(SCRIPT_SOUND_BULLET_HIT_GROUND_2, point.point);
break;
}
@@ -2863,7 +3128,6 @@ CWeapon::HitsGround(CEntity *holder, CVector *fireSource, CEntity *aimingTo)
return false;
}
-// --MIAMI: Done
void
CWeapon::BlowUpExplosiveThings(CEntity *thing)
{
@@ -2898,11 +3162,11 @@ bool
CWeapon::HasWeaponAmmoToBeUsed(void)
{
// FIX: This is better (not bug tho)
-#if 0
+//#if 0
if (m_eWeaponType <= WEAPONTYPE_CHAINSAW)
-#else
- if (CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_eWeaponFire == WEAPON_FIRE_MELEE)
-#endif
+//#else
+// if (CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_eWeaponFire == WEAPON_FIRE_MELEE)
+//#endif
return true;
else
return m_nAmmoTotal != 0;
@@ -2914,72 +3178,7 @@ CWeapon::ProcessLineOfSight(CVector const &point1, CVector const &point2, CColPo
return CWorld::ProcessLineOfSight(point1, point2, point, entity, checkBuildings, checkVehicles, checkPeds, checkObjects, checkDummies, ignoreSeeThrough, ignoreSomeObjects);
}
-void
-CWeapon::AddGunFlashBigGuns(CVector start, CVector end)
-{
- CPointLights::AddLight(CPointLights::LIGHT_POINT,
- start, CVector(0.0f, 0.0f, 0.0f), 5.0f,
- 1.0f, 0.8f, 0.0f, CPointLights::FOG_NONE, false);
- CVector gunflashPos = start;
-
- CVector shootVec = end - start;
-
- // Wtf did you do there R*?
- shootVec.Normalise();
- CVector2D ahead = shootVec;
- ahead.Normalise();
-
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.08f);
- 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.06f);
- 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.06f);
-
- gunflashPos = start;
- gunflashPos += CVector(-0.1f * ahead.x, -0.1f * ahead.y, 0.0f);
- gunflashPos.z += 0.04f;
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
- gunflashPos.z += 0.04f;
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
- gunflashPos.z += 0.03f;
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
-
- gunflashPos = start;
- gunflashPos += CVector(-0.1f * ahead.x, -0.1f * ahead.y, 0.0f);
- gunflashPos.z -= 0.04f;
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
- gunflashPos.z -= 0.04f;
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
- gunflashPos.z -= 0.03f;
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
-
- CVector offset = CrossProduct(CVector(ahead.x, ahead.y, 0.0f), CVector(0.0f, 0.0f, 5.0f));
- offset.Normalise2D();
-
- gunflashPos = start;
- gunflashPos += CVector(-0.1f * ahead.x, -0.1f * ahead.y, 0.0f);
- gunflashPos += CVector(0.06f * offset.x, 0.06f * offset.y, 0.0f);
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
- gunflashPos += CVector(0.04f * offset.x, 0.04f * offset.y, 0.0f);
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.03f);
- gunflashPos += CVector(0.03f * offset.x, 0.03f * offset.y, 0.0f);
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
-
- gunflashPos = start;
- gunflashPos += CVector(-0.1f * ahead.x, -0.1f * ahead.y, 0.0f);
- gunflashPos -= CVector(0.06f * offset.x, 0.06f * offset.y, 0.0f);
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
- gunflashPos -= CVector(0.04f * offset.x, 0.04f * offset.y, 0.0f);
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.03f);
- gunflashPos -= CVector(0.03f * offset.x, 0.03f * offset.y, 0.0f);
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
-
- CVector gunsmokePos = start;
- float rnd = CGeneral::GetRandomNumberInRange(0.05f, 0.25f);
- CParticle::AddParticle(PARTICLE_GUNSMOKE2, gunsmokePos, CVector(ahead.x * rnd, ahead.y * rnd, 0.0f));
-}
-// --MIAMI: Done
void
CWeapon::CheckForShootingVehicleOccupant(CEntity **victim, CColPoint *point, eWeaponType weapon, CVector const& source, CVector const& target)
{
diff --git a/src/weapons/Weapon.h b/src/weapons/Weapon.h
index cb59582f..f720b312 100644
--- a/src/weapons/Weapon.h
+++ b/src/weapons/Weapon.h
@@ -21,7 +21,9 @@ public:
int32 m_nAmmoTotal;
uint32 m_nTimer;
bool m_bAddRotOffset;
-
+
+ static bool bPhotographHasBeenTaken;
+
CWeapon() {
m_bAddRotOffset = false;
}
@@ -41,6 +43,7 @@ public:
bool FireMelee (CEntity *shooter, CVector &fireSource);
bool FireInstantHit(CEntity *shooter, CVector *fireSource);
+ static void AddGunFlashBigGuns(CVector start, CVector end);
void AddGunshell (CEntity *shooter, CVector const &source, CVector2D const &direction, float size);
void DoBulletImpact(CEntity *shooter, CEntity *victim, CVector *source, CVector *target, CColPoint *point, CVector2D ahead);
@@ -50,13 +53,15 @@ public:
static void GenerateFlameThrowerParticles(CVector pos, CVector dir);
bool FireAreaEffect (CEntity *shooter, CVector *fireSource);
+ bool LaserScopeDot (CVector *pOutPos, float *pOutSize);
bool FireSniper (CEntity *shooter);
+ bool TakePhotograph (CEntity *shooter);
bool FireM16_1stPerson (CEntity *shooter);
bool FireInstantHitFromCar(CVehicle *shooter, bool left, bool right);
- static void DoDoomAiming (CEntity *shooter, CVector *source, CVector *target);
- static void DoTankDoomAiming (CEntity *shooter, CEntity *driver, CVector *source, CVector *target);
- static void DoDriveByAutoAiming(CEntity *driver, CVehicle *vehicle, CVector *source, CVector *target);
+ static void DoDoomAiming (CEntity *shooter, CVector *source, CVector *target);
+ static void DoTankDoomAiming (CEntity *shooter, CEntity *driver, CVector *source, CVector *target);
+ static void DoDriveByAutoAiming(CEntity *driver, CVehicle *vehicle, CVector *source, CVector *target);
void Reload(void);
void Update(int32 audioEntity, CPed *pedToAdjustSound);
@@ -68,14 +73,12 @@ public:
bool HitsGround(CEntity *holder, CVector *fireSource, CEntity *aimingTo);
static void BlowUpExplosiveThings(CEntity *thing);
bool HasWeaponAmmoToBeUsed(void);
- static void AddGunFlashBigGuns(CVector, CVector);
static bool IsShotgun(int weapon) { return weapon == WEAPONTYPE_SHOTGUN || weapon == WEAPONTYPE_SPAS12_SHOTGUN || weapon == WEAPONTYPE_STUBBY_SHOTGUN; }
- // TODO(Miami): Is that still used?
static bool ProcessLineOfSight(CVector const &point1, CVector const &point2, CColPoint &point, CEntity *&entity, eWeaponType type, CEntity *shooter, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects);
- static void CheckForShootingVehicleOccupant(CEntity**, CColPoint*, eWeaponType, CVector const&, CVector const&);
+ static void CheckForShootingVehicleOccupant(CEntity **victim, CColPoint *point, eWeaponType weapon, CVector const& source, CVector const& target);
#ifdef COMPATIBLE_SAVES
void Save(uint8*& buf);
diff --git a/src/weapons/WeaponEffects.cpp b/src/weapons/WeaponEffects.cpp
index fb50bbe0..7a5be722 100644
--- a/src/weapons/WeaponEffects.cpp
+++ b/src/weapons/WeaponEffects.cpp
@@ -3,6 +3,9 @@
#include "WeaponEffects.h"
#include "TxdStore.h"
#include "Sprite.h"
+#include "PlayerPed.h"
+#include "World.h"
+#include "WeaponType.h"
RwTexture *gpCrossHairTex;
RwRaster *gpCrossHairRaster;
@@ -24,10 +27,10 @@ CWeaponEffects::Init(void)
{
gCrossHair.m_bActive = false;
gCrossHair.m_vecPos = CVector(0.0f, 0.0f, 0.0f);
- gCrossHair.m_nRed = 0;
+ gCrossHair.m_nRed = 255;
gCrossHair.m_nGreen = 0;
gCrossHair.m_nBlue = 0;
- gCrossHair.m_nAlpha = 255;
+ gCrossHair.m_nAlpha = 127;
gCrossHair.m_fSize = 1.0f;
gCrossHair.m_fRotation = 0.0f;
@@ -46,9 +49,7 @@ void
CWeaponEffects::Shutdown(void)
{
RwTextureDestroy(gpCrossHairTex);
-#ifdef GTA3_1_1_PATCH
gpCrossHairTex = nil;
-#endif
}
void
@@ -56,10 +57,6 @@ CWeaponEffects::MarkTarget(CVector pos, uint8 red, uint8 green, uint8 blue, uint
{
gCrossHair.m_bActive = true;
gCrossHair.m_vecPos = pos;
- gCrossHair.m_nRed = red;
- gCrossHair.m_nGreen = green;
- gCrossHair.m_nBlue = blue;
- gCrossHair.m_nAlpha = alpha;
gCrossHair.m_fSize = size;
}
@@ -72,12 +69,32 @@ CWeaponEffects::ClearCrossHair(void)
void
CWeaponEffects::Render(void)
{
+ static float aCrossHairSize[WEAPONTYPE_TOTALWEAPONS] =
+ {
+ 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
+ 0.4f, 0.4f,
+ 0.5f,
+ 0.3f,
+ 0.9f, 0.9f, 0.9f,
+ 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
+ 0.1f, 0.1f,
+ 1.0f,
+ 0.6f,
+ 0.7f,
+ 0.0f, 0.0f
+ };
+
+
+
if ( gCrossHair.m_bActive )
{
+ float size = aCrossHairSize[FindPlayerPed()->GetWeapon()->m_eWeaponType];
+
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)FALSE);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)FALSE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)TRUE);
- RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDONE);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDONE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVDESTALPHA);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)gpCrossHairRaster);
RwV3d pos;
@@ -85,15 +102,25 @@ CWeaponEffects::Render(void)
if ( CSprite::CalcScreenCoors(gCrossHair.m_vecPos, &pos, &w, &h, true) )
{
float recipz = 1.0f / pos.z;
- CSprite::RenderOneXLUSprite(pos.x, pos.y, pos.z,
- gCrossHair.m_fSize * w, gCrossHair.m_fSize * h,
- gCrossHair.m_nRed, gCrossHair.m_nGreen, gCrossHair.m_nBlue, 255,
- recipz, 255);
+ CSprite::RenderOneXLUSprite_Rotate_Aspect(pos.x, pos.y, pos.z,
+ w, h,
+ 255, 88, 100, 158,
+ recipz, gCrossHair.m_fRotation, gCrossHair.m_nAlpha);
+
+ float recipz2 = 1.0f / pos.z;
+
+ CSprite::RenderOneXLUSprite_Rotate_Aspect(pos.x, pos.y, pos.z,
+ size*w, size*h,
+ 107, 134, 247, 158,
+ recipz2, TWOPI - gCrossHair.m_fRotation, gCrossHair.m_nAlpha);
+
+ gCrossHair.m_fRotation += 0.02f;
+ if ( gCrossHair.m_fRotation > TWOPI )
+ gCrossHair.m_fRotation = 0.0;
}
-
+
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)FALSE);
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)FALSE);
- RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)TRUE);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE);
}
} \ No newline at end of file
diff --git a/src/weapons/WeaponInfo.cpp b/src/weapons/WeaponInfo.cpp
index 0f71aeda..6debf725 100644
--- a/src/weapons/WeaponInfo.cpp
+++ b/src/weapons/WeaponInfo.cpp
@@ -9,16 +9,57 @@
#include "ModelInfo.h"
#include "ModelIndices.h"
+uint16 CWeaponInfo::ms_aReloadSampleTime[WEAPONTYPE_TOTALWEAPONS] =
+{
+ 0, // UNARMED
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0, // GRENADE
+ 0, // DETONATEGRENADE
+ 0, // TEARGAS
+ 0, // MOLOTOV
+ 0, // ROCKET
+ 250, // COLT45
+ 250, // PYTHON
+ 650, // SHOTGUN
+ 650, // SPAS12 SHOTGUN
+ 650, // STUBBY SHOTGUN
+ 400, // TEC9
+ 400, // UZIhec
+ 400, // SILENCED_INGRAM
+ 400, // MP5
+ 300, // M16
+ 300, // AK47
+ 423, // SNIPERRIFLE
+ 423, // LASERSCOPE
+ 400, // ROCKETLAUNCHER
+ 0, // FLAMETHROWER
+ 0, // M60
+ 0, // MINIGUN
+ 0, // DETONATOR
+ 0, // HELICANNON
+ 0 // CAMERA
+};
+
// Yeah...
-int32 CWeaponInfo::ms_aMaxAmmoForWeapon[WEAPONTYPE_TOTALWEAPONS] = {
+int32 CWeaponInfo::ms_aMaxAmmoForWeapon[WEAPONTYPE_TOTALWEAPONS] =
+{
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1
};
CWeaponInfo CWeaponInfo::ms_apWeaponInfos[WEAPONTYPE_TOTALWEAPONS];
-
-// --MIAMI: Todo
-static char ms_aWeaponNames[][32] = {
+char CWeaponInfo::ms_aWeaponNames[WEAPONTYPE_TOTALWEAPONS][32] =
+{
"Unarmed",
"BrassKnuckle",
"ScrewDriver",
@@ -61,7 +102,7 @@ static char ms_aWeaponNames[][32] = {
CWeaponInfo*
CWeaponInfo::GetWeaponInfo(eWeaponType weaponType)
{
- return &CWeaponInfo::ms_apWeaponInfos[weaponType];
+ return &ms_apWeaponInfos[weaponType];
}
// --MIAMI: done except WEAPONTYPE_TOTALWEAPONS value
diff --git a/src/weapons/WeaponInfo.h b/src/weapons/WeaponInfo.h
index e7013004..7ce3d861 100644
--- a/src/weapons/WeaponInfo.h
+++ b/src/weapons/WeaponInfo.h
@@ -8,7 +8,9 @@ enum AssocGroupId;
class CWeaponInfo {
static CWeaponInfo ms_apWeaponInfos[WEAPONTYPE_TOTALWEAPONS];
+ static char ms_aWeaponNames[WEAPONTYPE_TOTALWEAPONS][32];
public:
+ static uint16 ms_aReloadSampleTime[WEAPONTYPE_TOTALWEAPONS];
static int32 ms_aMaxAmmoForWeapon[WEAPONTYPE_TOTALWEAPONS];
eWeaponFire m_eWeaponFire;