summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergeanur <s.anureev@yandex.ua>2020-06-07 03:16:10 +0200
committerSergeanur <s.anureev@yandex.ua>2020-06-07 03:16:10 +0200
commit24bf4c2cbae67be4a0ac5f674f3fb5645e92516b (patch)
tree392d6754b618a6be48c391d86601da905299be89
parenta bit of fonts (diff)
parentMerge branch 'master' into miami (diff)
downloadre3-24bf4c2cbae67be4a0ac5f674f3fb5645e92516b.tar
re3-24bf4c2cbae67be4a0ac5f674f3fb5645e92516b.tar.gz
re3-24bf4c2cbae67be4a0ac5f674f3fb5645e92516b.tar.bz2
re3-24bf4c2cbae67be4a0ac5f674f3fb5645e92516b.tar.lz
re3-24bf4c2cbae67be4a0ac5f674f3fb5645e92516b.tar.xz
re3-24bf4c2cbae67be4a0ac5f674f3fb5645e92516b.tar.zst
re3-24bf4c2cbae67be4a0ac5f674f3fb5645e92516b.zip
-rw-r--r--src/control/Darkel.cpp6
-rw-r--r--src/control/Garages.cpp2
-rw-r--r--src/control/Pickups.cpp2
-rw-r--r--src/control/Replay.cpp2
-rw-r--r--src/control/SceneEdit.cpp4
-rw-r--r--src/control/Script.cpp4
-rw-r--r--src/core/ControllerConfig.cpp6
-rw-r--r--src/core/Debug.cpp6
-rw-r--r--src/core/Frontend.cpp33
-rw-r--r--src/core/Frontend.h18
-rw-r--r--src/core/Pad.cpp4
-rw-r--r--src/core/common.h2
-rw-r--r--src/core/main.cpp4
-rw-r--r--src/core/timebars.cpp2
-rw-r--r--src/entities/Physical.cpp7
-rw-r--r--src/math/Matrix.h4
-rw-r--r--src/modelinfo/ModelIndices.h6
-rw-r--r--src/peds/Ped.cpp345
-rw-r--r--src/peds/Ped.h1
-rw-r--r--src/peds/PlayerPed.cpp8
-rw-r--r--src/peds/Population.cpp6
-rw-r--r--src/peds/Population.h1
-rw-r--r--src/render/Console.cpp2
-rw-r--r--src/render/Hud.cpp16
-rw-r--r--src/render/SpecialFX.cpp2
-rw-r--r--src/rw/TexRead.cpp2
-rw-r--r--src/vehicles/Automobile.cpp33
-rw-r--r--src/vehicles/Bike.cpp1028
-rw-r--r--src/vehicles/Bike.h7
-rw-r--r--src/vehicles/Boat.cpp2
-rw-r--r--src/vehicles/CarGen.cpp2
-rw-r--r--src/vehicles/Plane.cpp4
-rw-r--r--src/vehicles/Train.cpp4
-rw-r--r--src/vehicles/Vehicle.cpp10
-rw-r--r--src/weapons/Weapon.cpp25
-rw-r--r--src/weapons/Weapon.h4
36 files changed, 1386 insertions, 228 deletions
diff --git a/src/control/Darkel.cpp b/src/control/Darkel.cpp
index b6489ef2..f00486e8 100644
--- a/src/control/Darkel.cpp
+++ b/src/control/Darkel.cpp
@@ -75,7 +75,7 @@ CDarkel::DrawMessages()
CFont::SetScale(SCREEN_SCALE_X(1.3f), SCREEN_SCALE_Y(1.3f));
CFont::SetJustifyOff();
CFont::SetColor(CRGBA(255, 255, 128, CalcFade(timePassedSinceStart, 3000, 11000)));
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
if (pStartMessage) {
CFont::PrintString(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, pStartMessage);
}
@@ -85,7 +85,7 @@ CDarkel::DrawMessages()
CFont::SetScale(SCREEN_SCALE_X(1.3f), SCREEN_SCALE_Y(1.3f));
CFont::SetJustifyOff();
CFont::SetColor(CRGBA(255, 255, 128, CalcFade(timePassedSinceStart, 0, 8000)));
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
if (pStartMessage) {
CFont::PrintString(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, pStartMessage);
}
@@ -125,7 +125,7 @@ CDarkel::DrawMessages()
CFont::SetScale(SCREEN_SCALE_X(1.5f), SCREEN_SCALE_Y(1.5f));
CFont::SetJustifyOff();
CFont::SetColor(CRGBA(128, 255, 128, CalcFade(timePassedSinceStart, 0, 5000)));
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
int y = SCREEN_HEIGHT / 2 + SCREEN_SCALE_Y(25.0f - timePassedSinceStart * 0.01f);
CFont::PrintString(SCREEN_WIDTH / 2, y, TheText.Get("KF_3"));
}
diff --git a/src/control/Garages.cpp b/src/control/Garages.cpp
index 64ebddfe..5d459b43 100644
--- a/src/control/Garages.cpp
+++ b/src/control/Garages.cpp
@@ -1337,7 +1337,7 @@ void CGarages::PrintMessages()
CFont::SetBackgroundOff();
CFont::SetCentreSize(SCREEN_SCALE_FROM_RIGHT(50.0f));
CFont::SetCentreOn();
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); // TODO(MIAMI): redo it
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
CFont::SetColor(CRGBA(0, 0, 0, 255));
#if defined(PS2) || defined (FIX_BUGS)
diff --git a/src/control/Pickups.cpp b/src/control/Pickups.cpp
index 3ac1bb4a..2de30a0a 100644
--- a/src/control/Pickups.cpp
+++ b/src/control/Pickups.cpp
@@ -992,7 +992,7 @@ CPickups::RenderPickUpText()
CFont::SetColor(CRGBA(aMessages[i].m_color.red, aMessages[i].m_color.green, aMessages[i].m_color.blue, aMessages[i].m_color.alpha));
CFont::SetBackGroundOnlyTextOff();
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
CFont::PrintString(aMessages[i].m_pos.x, aMessages[i].m_pos.y, strToPrint);
}
NumMessages = 0;
diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp
index 28b999f8..6f9ad156 100644
--- a/src/control/Replay.cpp
+++ b/src/control/Replay.cpp
@@ -1605,7 +1605,7 @@ void CReplay::Display()
CFont::SetScale(SCREEN_SCALE_X(1.5f), SCREEN_SCALE_Y(1.5f));
CFont::SetAlignment(ALIGN_LEFT);
CFont::SetColor(CRGBA(255, 255, 200, 200));
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
if (Mode == MODE_PLAYBACK)
CFont::PrintString(SCREEN_SCALE_X(63.5f), SCREEN_SCALE_Y(30.0f), TheText.Get("REPLAY"));
}
diff --git a/src/control/SceneEdit.cpp b/src/control/SceneEdit.cpp
index f7dcaa3c..535f6bec 100644
--- a/src/control/SceneEdit.cpp
+++ b/src/control/SceneEdit.cpp
@@ -269,7 +269,7 @@ void CSceneEdit::Draw(void)
CFont::SetRightJustifyWrap(0.0f);
CFont::SetBackGroundOnlyTextOff();
#ifdef FIX_BUGS
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
CFont::SetPropOn();
CFont::SetDropColor(CRGBA(0, 0, 0, 255));
CFont::SetDropShadowPosition(1);
@@ -292,7 +292,7 @@ void CSceneEdit::Draw(void)
CFont::SetCentreOff();
CFont::SetScale(SCREEN_SCALE_X(0.7f), SCREEN_SCALE_Y(0.7f));
#ifdef FIX_BUGS
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
#else
CFont::SetFontStyle(FONT_HEADING);
#endif
diff --git a/src/control/Script.cpp b/src/control/Script.cpp
index a2c60872..76264617 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -14288,7 +14288,11 @@ void CTheScripts::UpdateObjectIndices()
if (!pModel)
continue;
strcpy(name, pModel->GetName());
+#ifdef FIX_BUGS
+ for (int k = 0; k < USED_OBJECT_NAME_LENGTH && name[k]; k++)
+#else
for (int k = 0; k < USED_OBJECT_NAME_LENGTH; k++)
+#endif
name[k] = toupper(name[k]);
if (strcmp(name, UsedObjectArray[i].name) == 0) {
found = true;
diff --git a/src/core/ControllerConfig.cpp b/src/core/ControllerConfig.cpp
index e48f2c3f..2a5d20f0 100644
--- a/src/core/ControllerConfig.cpp
+++ b/src/core/ControllerConfig.cpp
@@ -437,9 +437,9 @@ void CControllerConfigManager::InitialiseControllerActionNameArray()
SETACTIONNAME(PED_CYCLE_TARGET_LEFT);
SETACTIONNAME(PED_CYCLE_TARGET_RIGHT);
SETACTIONNAME(PED_CENTER_CAMERA_BEHIND_PLAYER);
+ SETACTIONNAME(VEHICLE_LOOKBEHIND);
SETACTIONNAME(PED_DUCK);
SETACTIONNAME(PED_ANSWER_PHONE);
- SETACTIONNAME(VEHICLE_LOOKBEHIND);
SETACTIONNAME(VEHICLE_LOOKLEFT);
SETACTIONNAME(VEHICLE_LOOKRIGHT);
SETACTIONNAME(VEHICLE_HORN);
@@ -462,6 +462,10 @@ void CControllerConfigManager::InitialiseControllerActionNameArray()
SETACTIONNAME(GO_RIGHT);
SETACTIONNAME(GO_FORWARD);
SETACTIONNAME(GO_BACK);
+ SETACTIONNAME(VEHICLE_TURRETLEFT);
+ SETACTIONNAME(VEHICLE_TURRETRIGHT);
+ SETACTIONNAME(VEHICLE_TURRETUP);
+ SETACTIONNAME(VEHICLE_TURRETDOWN);
SETACTIONNAME(NETWORK_TALK);
SETACTIONNAME(TOGGLE_DPAD);
SETACTIONNAME(SWITCH_DEBUG_CAM_ON);
diff --git a/src/core/Debug.cpp b/src/core/Debug.cpp
index e794dcaf..e319388c 100644
--- a/src/core/Debug.cpp
+++ b/src/core/Debug.cpp
@@ -55,7 +55,7 @@ CDebug::DebugDisplayTextBuffer()
CFont::SetJustifyOn();
CFont::SetRightJustifyWrap(0.0f);
CFont::SetBackGroundOnlyTextOff();
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
#else
// this is not even readable
CFont::SetPropOff();
@@ -65,7 +65,7 @@ CDebug::DebugDisplayTextBuffer()
CFont::SetRightJustifyOn();
CFont::SetRightJustifyWrap(0.0f);
CFont::SetBackGroundOnlyTextOff();
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
CFont::SetPropOff();
#endif
do {
@@ -113,7 +113,7 @@ CDebug::DisplayScreenStrings()
CFont::SetRightJustifyWrap(0.0f);
CFont::SetWrapx(9999.0f);
CFont::SetBackGroundOnlyTextOff();
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
for(i = 0; i < ms_nScreenStrs; i++){
/*
diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp
index 2cc34a95..c4af9ce6 100644
--- a/src/core/Frontend.cpp
+++ b/src/core/Frontend.cpp
@@ -826,7 +826,7 @@ CMenuManager::DrawStandardMenus(bool drawCurrScreen)
if (aScreens[m_nCurrScreen].m_aEntries[0].m_Action == MENUACTION_LABEL) {
CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENULABEL_X_MARGIN));
CFont::SetRightJustifyWrap(SCREEN_SCALE_X(MENULABEL_WIDTH));
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
CFont::SetScale(MENU_X(BIGTEXT2_X_SCALE), MENU_Y(BIGTEXT2_Y_SCALE));
CFont::SetRightJustifyOff();
@@ -911,7 +911,7 @@ CMenuManager::DrawStandardMenus(bool drawCurrScreen)
wchar* leftText;
if (aScreens[m_nCurrScreen].m_aEntries[i].m_SaveSlot >= SAVESLOT_1 && aScreens[m_nCurrScreen].m_aEntries[i].m_SaveSlot <= SAVESLOT_8) {
CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255)));
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
CFont::SetScale(MENU_X(MEDIUMTEXT_X_SCALE), MENU_Y(MEDIUMTEXT_Y_SCALE));
CFont::SetDropShadowPosition(0);
} else {
@@ -1255,7 +1255,7 @@ CMenuManager::DrawStandardMenus(bool drawCurrScreen)
CFont::SetCentreOff();
CFont::SetRightJustifyOn();
if (aScreens[m_nCurrScreen].m_aEntries[i].m_SaveSlot >= SAVESLOT_1 && aScreens[m_nCurrScreen].m_aEntries[i].m_SaveSlot <= SAVESLOT_8) {
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
CFont::SetScale(MENU_X(MEDIUMTEXT_X_SCALE), MENU_Y(MEDIUMTEXT_Y_SCALE));
} else {
CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING));
@@ -1720,7 +1720,7 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8
CFont::SetRightJustifyOff();
CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE));
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
if (!m_bKeyIsOK)
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
@@ -1733,7 +1733,7 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8
CFont::PrintString(MENU_X_LEFT_ALIGNED(275.0f), SCREEN_SCALE_FROM_BOTTOM(114.0f), TheText.Get("FET_CIG")); // BACKSPACE TO CLEAR - LMB,RETURN TO CHANGE
CFont::SetRightJustifyOff();
CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE));
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
m_bKeyIsOK = false;
m_bKeyChangeNotProcessed = false;
}
@@ -1745,7 +1745,7 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8
CFont::PrintString(MENU_X_LEFT_ALIGNED(275.0f), SCREEN_SCALE_FROM_BOTTOM(114.0f), TheText.Get("FET_EIG")); // CANNOT SET A CONTROL FOR THIS ACTION
CFont::SetRightJustifyOff();
CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE));
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
}
}
}
@@ -1918,7 +1918,7 @@ CMenuManager::DrawControllerSetupScreen()
CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_3_X), MENU_Y(CONTSETUP_LIST_TOP), TheText.Get("FET_CCR"));
CFont::SetRightJustifyOff();
CFont::SetScale(MENU_X_LEFT_ALIGNED(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE));
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
int yStart;
if (m_ControlMethod == CONTROL_CLASSIC)
yStart = CONTSETUP_LIST_HEADER_HEIGHT + 29;
@@ -2221,7 +2221,7 @@ CMenuManager::DrawBackground()
if (CheckHover(xStart, xStart + optionWidth, optionTop, optionBottom))
hoveredBottomBarOption = i;
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
CFont::SetScale(MENU_X(0.35f), MENU_Y(0.7f));
CFont::SetRightJustifyOff();
if (hoveredBottomBarOption == i && hoveredBottomBarOption != curBottomBarOption)
@@ -2626,7 +2626,7 @@ CMenuManager::DrawPlayerSetupScreen()
// Skin list
CFont::SetRightJustifyOff();
CFont::SetScale(MENU_X(PLAYERSETUP_ROW_TEXT_X_SCALE), MENU_Y(PLAYERSETUP_ROW_TEXT_Y_SCALE));
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
if (m_nSkinsTotal > 0) {
for (m_pSelectedSkin = m_pSkinListHead.nextSkin; m_pSelectedSkin->skinId != m_nFirstVisibleRowOnList;
m_pSelectedSkin = m_pSelectedSkin->nextSkin);
@@ -3281,7 +3281,7 @@ CMenuManager::SmallMessageScreen(const char* text)
CFont::SetJustifyOn();
CFont::SetBackGroundOnlyTextOn();
CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(95.0f), SCREEN_SCALE_FROM_BOTTOM(165.0f), SCREEN_SCALE_FROM_RIGHT(95.0f), SCREEN_SCALE_Y(115.0f)), CRGBA(50, 50, 50, FadeIn(210)));
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
CFont::SetCentreSize(SCREEN_SCALE_X(430.0f));
CFont::SetCentreOn();
CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255)));
@@ -3293,7 +3293,7 @@ void
CMenuManager::PrintBriefs()
{
CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255)));
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
CFont::SetRightJustifyOff();
CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X * 0.7), MENU_Y(MENU_TEXT_SIZE_Y * 0.9)); // second mulipliers are double, idk why
@@ -3345,7 +3345,7 @@ CMenuManager::PrintStats()
{
int rowNum = ConstructStatLine(99999);
#ifdef GTA3_1_1_PATCH
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
#endif
CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X * 0.7), MENU_Y(MENU_TEXT_SIZE_Y * 0.9)); // second mulipliers are double, idk why
float nextYChange, y, alphaMult;
@@ -4545,11 +4545,6 @@ CMenuManager::ProcessButtonPresses(void)
}
break;
}
- //case MENUACTION_KEYBOARDCTRLS:
- // SwitchToNewScreen(MENUPAGE_KEYBOARD_CONTROLS);
- // m_nSelectedListRow = 0;
- // m_nCurrExLayer = HOVEROPTION_LIST;
- // break;
}
}
ProcessOnOffMenuOptions();
@@ -4767,6 +4762,7 @@ void
CMenuManager::ProcessOnOffMenuOptions()
{
switch (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action) {
+#ifdef LEGACY_MENU_OPTIONS
case MENUACTION_CTRLVIBRATION:
m_PrefsUseVibration = !m_PrefsUseVibration;
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
@@ -4777,6 +4773,7 @@ CMenuManager::ProcessOnOffMenuOptions()
CPad::GetPad(0)->Mode = 0;
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
break;
+#endif
case MENUACTION_FRAMESYNC:
m_PrefsVsyncDisp = !m_PrefsVsyncDisp;
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
@@ -5341,7 +5338,7 @@ CMenuManager::PrintMap(void)
CRGBA(MAPINFOBOX_COLOR.r, MAPINFOBOX_COLOR.g, MAPINFOBOX_COLOR.b, MAPINFOBOX_COLOR.a));
CFont::SetScale(MENU_X(0.4f), MENU_Y(0.7f));
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255)));
float nextX = MENU_X(30.0f), nextY = 95.0f;
diff --git a/src/core/Frontend.h b/src/core/Frontend.h
index e22f878e..afce0acd 100644
--- a/src/core/Frontend.h
+++ b/src/core/Frontend.h
@@ -218,8 +218,8 @@ enum eMenuAction
MENUACTION_YES,
MENUACTION_NO,
MENUACTION_CHANGEMENU,
- MENUACTION_CTRLVIBRATION,
- MENUACTION_CTRLCONFIG,
+ MENUACTION_UNK5,
+ MENUACTION_INVERTPADY,
MENUACTION_FRAMESYNC,
MENUACTION_FRAMELIMIT,
MENUACTION_TRAILS,
@@ -255,7 +255,6 @@ enum eMenuAction
MENUACTION_PARSEHEAP,
// MENUACTION_MEMCARDSAVECONFIRM is that on VC enum??
MENUACTION_DEBUGSTREAM,
- //MENUACTION_KEYBOARDCTRLS,
MENUACTION_GETKEY,
MENUACTION_SHOWHEADBOB,
MENUACTION_UNK80,
@@ -273,13 +272,6 @@ enum eMenuAction
MENUACTION_CTRLMETHOD,
MENUACTION_DYNAMICACOUSTIC,
MENUACTION_MOUSESTEER,
- MENUACTION_UNK103,
- MENUACTION_UNK104,
- MENUACTION_UNK105,
- MENUACTION_UNK106,
- MENUACTION_UNK107,
- MENUACTION_UNK108,
- MENUACTION_UNK109,
MENUACTION_UNK110,
#ifdef MORE_LANGUAGES
MENUACTION_LANG_PL,
@@ -290,7 +282,11 @@ enum eMenuAction
MENUACTION_SCREENMODE,
#endif
#ifdef FREE_CAM
- MENUACTION_FREECAM
+ MENUACTION_FREECAM,
+#endif
+#ifdef LEGACY_MENU_OPTIONS
+ MENUACTION_CTRLVIBRATION,
+ MENUACTION_CTRLCONFIG,
#endif
};
diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp
index a475bf7b..204d9a18 100644
--- a/src/core/Pad.cpp
+++ b/src/core/Pad.cpp
@@ -2517,7 +2517,7 @@ void CPad::PrintErrorMessage(void)
CFont::SetCentreOn();
CFont::SetPropOn();
CFont::SetColor(CRGBA(255, 255, 200, 200));
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
CFont::PrintString
(
SCREEN_WIDTH / 2,
@@ -2534,7 +2534,7 @@ void CPad::PrintErrorMessage(void)
CFont::SetCentreOn();
CFont::SetPropOn();
CFont::SetColor(CRGBA(255, 255, 200, 200));
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
CFont::PrintString
(
SCREEN_WIDTH / 2,
diff --git a/src/core/common.h b/src/core/common.h
index cc570bef..eb43d8d5 100644
--- a/src/core/common.h
+++ b/src/core/common.h
@@ -405,7 +405,7 @@ inline T *WriteSaveBuf(uint8 *&buf, const T &value)
WriteSaveBuf(buf, b);\
WriteSaveBuf(buf, c);\
WriteSaveBuf(buf, d);\
- WriteSaveBuf(buf, size);
+ WriteSaveBuf<uint32>(buf, size);
#define CheckSaveHeader(buf,a,b,c,d,size)\
assert(ReadSaveBuf<char>(buf) == a);\
diff --git a/src/core/main.cpp b/src/core/main.cpp
index 547d3b37..6ffaabf6 100644
--- a/src/core/main.cpp
+++ b/src/core/main.cpp
@@ -514,7 +514,7 @@ LoadingScreen(const char *str1, const char *str2, const char *splashscreen)
CFont::SetScale(SCREEN_SCALE_X(0.75f), yscale);
CFont::SetPropOn();
CFont::SetRightJustifyOff();
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
CFont::SetColor(CRGBA(255, 255, 255, 255));
AsciiToUnicode(str1, tmpstr);
CFont::PrintString(hpos, top, tmpstr);
@@ -711,7 +711,7 @@ DisplayGameDebugText()
CFont::SetPropOn();
CFont::SetBackgroundOff();
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
CFont::SetScale(SCREEN_SCALE_X(0.5f), SCREEN_SCALE_Y(0.5f));
CFont::SetCentreOff();
CFont::SetRightJustifyOff();
diff --git a/src/core/timebars.cpp b/src/core/timebars.cpp
index 6b841a5c..884feffd 100644
--- a/src/core/timebars.cpp
+++ b/src/core/timebars.cpp
@@ -92,7 +92,7 @@ void tbDisplay()
CFont::SetWrapx(640.0f);
CFont::SetRightJustifyOff();
CFont::SetPropOn();
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
sprintf(temp, "FPS: %.2f", Diag_GetFPS());
AsciiToUnicode(temp, wtemp);
CFont::SetColor(CRGBA(255, 255, 255, 255));
diff --git a/src/entities/Physical.cpp b/src/entities/Physical.cpp
index 332d3d81..090eae6b 100644
--- a/src/entities/Physical.cpp
+++ b/src/entities/Physical.cpp
@@ -27,6 +27,10 @@ CPhysical::CPhysical(void)
{
int i;
+#ifdef FIX_BUGS
+ m_nLastTimeCollided = 0;
+#endif
+
m_fForceMultiplier = 1.0f;
m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f);
@@ -68,6 +72,9 @@ CPhysical::CPhysical(void)
m_phy_flagA20 = false;
+#ifdef FIX_BUGS
+ m_nSurfaceTouched = SURFACE_DEFAULT;
+#endif
m_nZoneLevel = LEVEL_NONE;
bIsFrozen = false;
diff --git a/src/math/Matrix.h b/src/math/Matrix.h
index 46789c94..2d721e93 100644
--- a/src/math/Matrix.h
+++ b/src/math/Matrix.h
@@ -30,7 +30,11 @@ public:
RwMatrixDestroy(m_attachment);
}
void Attach(RwMatrix *matrix, bool owner = false){
+#ifdef FIX_BUGS
+ if(m_attachment && m_hasRwMatrix)
+#else
if(m_hasRwMatrix && m_attachment)
+#endif
RwMatrixDestroy(m_attachment);
m_attachment = matrix;
m_hasRwMatrix = owner;
diff --git a/src/modelinfo/ModelIndices.h b/src/modelinfo/ModelIndices.h
index 94ed04f7..ad7b4aaf 100644
--- a/src/modelinfo/ModelIndices.h
+++ b/src/modelinfo/ModelIndices.h
@@ -159,6 +159,12 @@ enum
MI_TAXI_D = 28, // HMOCA
+ MI_BMYBB = 47,
+ MI_WMOST = 52,
+ MI_WMYBE = 58,
+ MI_WFOBE,
+ MI_WMOBE,
+
MI_WFOGO = 63,
MI_WMOGO = 64,
diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp
index 5147e103..70e6303e 100644
--- a/src/peds/Ped.cpp
+++ b/src/peds/Ped.cpp
@@ -185,6 +185,9 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
m_queuedSound = SOUND_NO_SOUND;
m_objective = OBJECTIVE_NONE;
m_prevObjective = OBJECTIVE_NONE;
+#ifdef FIX_BUGS
+ m_objectiveTimer = 0;
+#endif
CharCreatedBy = RANDOM_CHAR;
m_leader = nil;
m_pedInObjective = nil;
@@ -244,6 +247,9 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
m_nPedState = PED_IDLE;
m_nLastPedState = PED_NONE;
m_nMoveState = PEDMOVE_STILL;
+#ifdef FIX_BUGS
+ m_nPrevMoveState = PEDMOVE_NONE;
+#endif
m_nStoredMoveState = PEDMOVE_NONE;
m_pFire = nil;
m_pPointGunAt = nil;
@@ -4341,30 +4347,29 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
if (bInVehicle) {
if (method != WEAPONTYPE_DROWNING) {
-#ifdef VC_PED_PORTS
if (m_pMyVehicle) {
bool bDone = false;
if (m_pMyVehicle->IsBike()) {
m_fHealth = 0.0f;
- //CBike::KnockOffRider -- TODO(MIAMI)
+ ((CBike*)m_pMyVehicle)->KnockOffRider(method, direction, this, false);
bDone = true;
- }
- else {
- if (m_pMyVehicle->IsCar() && m_pMyVehicle->pDriver == this) {
- if (m_pMyVehicle->GetStatus() == STATUS_SIMPLE) {
- m_pMyVehicle->SetStatus(STATUS_PHYSICS);
- CCarCtrl::SwitchVehicleToRealPhysics(m_pMyVehicle);
+ } else {
+ if (m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_CAR) {
+ if (m_pMyVehicle->pDriver == this) {
+ if (m_pMyVehicle->GetStatus() == STATUS_SIMPLE) {
+ m_pMyVehicle->SetStatus(STATUS_PHYSICS);
+ CCarCtrl::SwitchVehicleToRealPhysics(m_pMyVehicle);
+ }
+ m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
+ m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0;
+ m_pMyVehicle->AutoPilot.m_nTempAction = TEMPACT_HANDBRAKESTRAIGHT;
+ m_pMyVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 2000;
}
- m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
- m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0;
- m_pMyVehicle->AutoPilot.m_nTempAction = TEMPACT_HANDBRAKESTRAIGHT;
- m_pMyVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 2000;
}
// TODO(MIAMI): argument
if (m_pMyVehicle->CanPedExitCar(false)) {
SetObjective(OBJECTIVE_LEAVE_CAR_AND_DIE, m_pMyVehicle);
- }
- else {
+ } else {
m_fHealth = 0.0f;
if (m_pMyVehicle && m_pMyVehicle->pDriver == this) {
SetRadioStation();
@@ -4397,7 +4402,6 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
if (bDone)
return true;
}
-#endif
m_fHealth = 1.0f;
return false;
}
@@ -4421,6 +4425,7 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
}
if (method == WEAPONTYPE_DROWNING)
bIsInTheAir = false;
+ // TODO(Miami): timesDrowned
return true;
}
@@ -5684,6 +5689,7 @@ CPed::SetFlee(CVector2D const &from, int time)
}
}
+// --MIAMI: Only some part is done
void
CPed::SetWaitState(eWaitState state, void *time)
{
@@ -5858,13 +5864,20 @@ CPed::SetWaitState(eWaitState state, void *time)
else
m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 100000;
break;
+ case WAITSTATE_FAST_FALL:
+ SetFall(-1, ANIM_KO_SKID_FRONT, true);
+ break;
+ case WAITSTATE_BOMBER:
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_BOMBER, 4.0f);
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time;
+ 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_FAST_FALL:
- case WAITSTATE_BOMBER:
case WAITSTATE_GROUND_ATTACK:
- case WAITSTATE_LANCESITTING:
case WAITSTATE_PLAYANIM_HANDSUP_SIMPLE:
default:
ClearWaitState();
@@ -6790,7 +6803,7 @@ CPed::EnterCar(void)
LineUpPedWithCar(LINE_UP_TO_CAR_START);
if (veh->IsBike()) {
CBike *bike = (CBike*)veh;
- if (bike->GetStatus() != STATUS_ABANDONED || bike->m_bike_flag08 || !m_pVehicleAnim) {
+ if (bike->GetStatus() != STATUS_ABANDONED || bike->bIsBeingPickedUp || !m_pVehicleAnim) {
if (m_nPedState == PED_CARJACK && m_pVehicleAnim) {
if (m_pVehicleAnim->currentTime > 0.4f && m_pVehicleAnim->currentTime - m_pVehicleAnim->timeStep <= 0.4f) {
int anim = m_pVehicleAnim->animId;
@@ -6806,9 +6819,9 @@ CPed::EnterCar(void)
// One is pickup and other one is pullup, not same :p
if ((anim == ANIM_BIKE_PICKUP_R || anim == ANIM_BIKE_PICKUP_L) && m_pVehicleAnim->currentTime > 0.4667f)
- bike->m_bike_flag08 = true;
+ bike->bIsBeingPickedUp = true;
else if ((anim == ANIM_BIKE_PULLUP_R || anim == ANIM_BIKE_PULLUP_L) && m_pVehicleAnim->currentTime > 0.4667f)
- bike->m_bike_flag08 = true;
+ bike->bIsBeingPickedUp = true;
}
}
} else {
@@ -6946,40 +6959,72 @@ CPed::ExitTrain(void)
}
#endif
+// --MIAMI: Done
void
CPed::ExitCar(void)
{
- if (!m_pVehicleAnim)
+ if (!m_pVehicleAnim) {
+ if (InVehicle()) {
+ if (m_pMyVehicle->IsBike()) {
+ // TODO(Miami): What are those?
+ if (m_vehEnterType == 18 || m_vehEnterType == 8) {
+ ((CBike*)m_pMyVehicle)->KnockOffRider(WEAPONTYPE_UNARMED, 0, this, false);
+ }
+ } else if (m_pMyVehicle->IsCar()) {
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_ROLLOUT_LHS)) {
+ ((CAutomobile*)m_pMyVehicle)->KnockPedOutCar(WEAPONTYPE_UNIDENTIFIED, CAR_DOOR_LF, this);
+ } else if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_ROLLOUT_RHS)) {
+ ((CAutomobile*)m_pMyVehicle)->KnockPedOutCar(WEAPONTYPE_UNIDENTIFIED, CAR_DOOR_RF, this);
+ }
+ }
+ }
return;
+ }
AnimationId exitAnim = (AnimationId) m_pVehicleAnim->animId;
float animTime = m_pVehicleAnim->currentTime;
- m_pMyVehicle->ProcessOpenDoor(m_vehEnterType, exitAnim, animTime);
+ if (exitAnim == ANIM_BIKE_GETOFF_BACK) {
+ if (animTime > 0.35f && m_pMyVehicle && m_pMyVehicle->IsBike())
+ ((CBike*)m_pMyVehicle)->KnockOffRider(WEAPONTYPE_UNARMED, 0, this, false);
+ else
+ LineUpPedWithCar(LINE_UP_TO_CAR_FALL);
- if (m_pSeekTarget) {
- // Car is upside down
- if (m_pMyVehicle->GetUp().z > -0.8f) {
- if (exitAnim != ANIM_CAR_CLOSE_RHS && exitAnim != ANIM_CAR_CLOSE_LHS && animTime <= 0.3f)
- LineUpPedWithCar((m_pMyVehicle->GetModelIndex() == MI_DODO ? LINE_UP_TO_CAR_END : LINE_UP_TO_CAR_START));
- else
+ } else if (exitAnim != ANIM_CAR_ROLLOUT_LHS && exitAnim != ANIM_CAR_ROLLOUT_RHS) {
+ m_pMyVehicle->ProcessOpenDoor(m_vehEnterType, exitAnim, animTime);
+
+ if (m_pSeekTarget) {
+ // Car is upside down
+ if (m_pMyVehicle->GetUp().z > -0.8f) {
+ if (exitAnim != ANIM_CAR_CLOSE_RHS && exitAnim != ANIM_CAR_CLOSE_LHS && animTime <= 0.3f)
+ LineUpPedWithCar((m_pMyVehicle->GetModelIndex() == MI_DODO ? LINE_UP_TO_CAR_END : LINE_UP_TO_CAR_START));
+ else
+ LineUpPedWithCar(LINE_UP_TO_CAR_END);
+ }
+ else {
LineUpPedWithCar(LINE_UP_TO_CAR_END);
- } else {
- LineUpPedWithCar(LINE_UP_TO_CAR_END);
+ }
}
- }
- // If there is someone in front of the door, make him fall while we exit.
- if (m_nPedState == PED_EXIT_CAR) {
- CPed *foundPed = nil;
- for (int i = 0; i < m_numNearPeds; i++) {
- if ((m_nearPeds[i]->GetPosition() - GetPosition()).MagnitudeSqr2D() < 0.04f) {
- foundPed = m_nearPeds[i];
- break;
+ // If there is someone in front of the door, make him fall while we exit.
+ if (m_nPedState == PED_EXIT_CAR) {
+ CPed* foundPed = nil;
+ for (int i = 0; i < m_numNearPeds; i++) {
+ if ((m_nearPeds[i]->GetPosition() - GetPosition()).MagnitudeSqr2D() < 0.04f) {
+ foundPed = m_nearPeds[i];
+ break;
+ }
}
+ if(foundPed && (!foundPed->IsPlayer() || m_nPedType == PEDTYPE_COP || m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT || m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS))
+ if (animTime > 0.4f && foundPed->IsPedInControl())
+ foundPed->SetFall(1000, ANIM_KO_SKID_FRONT, 1);
}
- if (foundPed && animTime > 0.4f && foundPed->IsPedInControl())
- foundPed->SetFall(1000, ANIM_KO_SKID_FRONT, 1);
+ } else if (animTime <= 0.07f || !m_pMyVehicle || !m_pMyVehicle->IsCar()) {
+ LineUpPedWithCar(LINE_UP_TO_CAR_FALL);
+ } else if (exitAnim == ANIM_CAR_ROLLOUT_LHS) {
+ ((CAutomobile*)m_pMyVehicle)->KnockPedOutCar(WEAPONTYPE_UNIDENTIFIED, CAR_DOOR_LF, this);
+ } else {
+ ((CAutomobile*)m_pMyVehicle)->KnockPedOutCar(WEAPONTYPE_UNIDENTIFIED, CAR_DOOR_RF, this);
}
}
@@ -7619,6 +7664,7 @@ CPed::FinishLaunchCB(CAnimBlendAssociation *animAssoc, void *arg)
}
}
+// --MIAMI: Done
void
CPed::FinishedWaitCB(CAnimBlendAssociation *animAssoc, void *arg)
{
@@ -7629,6 +7675,7 @@ CPed::FinishedWaitCB(CAnimBlendAssociation *animAssoc, void *arg)
ped->Wait();
}
+// --MIAMI: Some part is done
void
CPed::Wait(void)
{
@@ -7957,15 +8004,38 @@ CPed::Wait(void)
ClearWaitState();
}
break;
- case WAITSTATE_SUN_BATHE_PRE:
- case WAITSTATE_SUN_BATHE_DOWN:
- case WAITSTATE_SUN_BATHE_IDLE:
case WAITSTATE_RIOT:
- case WAITSTATE_FAST_FALL:
+ if (m_nPedState == PED_FLEE_ENTITY || m_nPedState == PED_ATTACK) {
+ ClearWaitState();
+ break;
+ }
+
+ PlayRandomAnimationsFromAnimBlock(this, ASSOCGRP_RIOT, ANIM_RIOT_ANGRY, ANIM_RIOT_FUKU - ANIM_RIOT_ANGRY + 1);
+ if (IsPedInControl() && CGeneral::GetRandomNumberInRange(0.f,1.f) < 0.25f
+ && CPopulation::CanJeerAtStripper(m_modelIndex)) {
+ for (int i = 0; i < m_numNearPeds; ++i) {
+ CPed *nearPed = m_nearPeds[i];
+ if (nearPed) {
+ if ((GetPosition() - nearPed->GetPosition()).MagnitudeSqr() < sq(10.f)) {
+ for (int anim = ANIM_STRIP_A; anim <= ANIM_STRIP_G; anim++) {
+ if (RpAnimBlendClumpGetAssociation(nearPed->GetClump(), anim))
+ Say(SOUND_PED_149);
+ }
+ }
+ }
+ }
+ }
+ break;
case WAITSTATE_BOMBER:
+ if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer)
+ ClearWaitState();
+ break;
case WAITSTATE_STRIPPER:
- case WAITSTATE_GROUND_ATTACK:
- case WAITSTATE_LANCESITTING:
+ 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);
default:
@@ -12525,12 +12595,10 @@ CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg)
if (ped->m_objective == OBJECTIVE_LEAVE_VEHICLE)
ped->RestorePreviousObjective();
-#ifdef VC_PED_PORTS
else if (ped->m_objective == OBJECTIVE_LEAVE_CAR_AND_DIE) {
ped->m_fHealth = 0.0f;
ped->SetDie(ANIM_FLOOR_HIT, 4.0f, 0.5f);
}
-#endif
ped->bInVehicle = false;
if (veh && veh->IsCar() && !veh->IsRoomForPedToLeaveCar(ped->m_vehEnterType, nil)) {
@@ -12590,7 +12658,7 @@ CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg)
}
}
#ifdef VC_PED_PORTS
- else {
+ else if (ped->m_nPedState == PED_DRIVING) {
ped->m_nPedState = PED_IDLE;
}
#endif
@@ -18296,41 +18364,106 @@ CPed::SetNewAttraction(CPedAttractor* pAttractor, const CVector& pos, float head
m_positionInQueue = qid;
}
+// --MIAMI: Done
void
CPed::ClearWaitState(void)
{
+ CAnimBlendAssociation *assoc;
switch (m_nWaitState) {
- case WAITSTATE_PLAYANIM_CHAT:
- case WAITSTATE_SIT_DOWN:
- case WAITSTATE_SIT_DOWN_RVRS:
- case WAITSTATE_SIT_UP:
- case WAITSTATE_SIT_IDLE:
- case WAITSTATE_USE_ATM:
- if (CTimer::GetTimeInMilliseconds() <= m_nWaitTimer) {
- AnimationId id;
- switch (m_nWaitState) { // TODO(MIAMI): actual!
- case WAITSTATE_PLAYANIM_CHAT: id = ANIM_IDLE_CHAT; break;
- case WAITSTATE_SIT_DOWN: id = ANIM_SEAT_DOWN; break;
- case WAITSTATE_SIT_DOWN_RVRS: id = ANIM_SEAT_DOWN2; break;
- case WAITSTATE_SIT_UP: id = ANIM_SEAT_UP; break;
- case WAITSTATE_SIT_IDLE: id = ANIM_SEAT_IDLE; break;
- case WAITSTATE_USE_ATM: id = ANIM_ATM; break;
- }
- CAnimBlendAssociation* pAssoc = RpAnimBlendClumpGetAssociation(GetClump(), id);
- if (pAssoc)
- pAssoc->blendDelta = -8.0f;
- if (m_attractor)
- GetPedAttractorManager()->DeRegisterPed(this, m_attractor);
- }
- break;
- case WAITSTATE_RIOT:
- case WAITSTATE_FAST_FALL:
- case WAITSTATE_BOMBER:
- case WAITSTATE_STRIPPER:
- case WAITSTATE_GROUND_ATTACK:
- case WAITSTATE_LANCESITTING:
- case WAITSTATE_PLAYANIM_HANDSUP_SIMPLE:
- assert(0);
+ case WAITSTATE_PLAYANIM_CHAT:
+ case WAITSTATE_SIT_DOWN:
+ case WAITSTATE_SIT_DOWN_RVRS:
+ case WAITSTATE_SIT_UP:
+ case WAITSTATE_SIT_IDLE:
+ case WAITSTATE_USE_ATM:
+ if (CTimer::GetTimeInMilliseconds() <= m_nWaitTimer) {
+ if (m_nWaitState == WAITSTATE_USE_ATM) {
+ assoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_ATM);
+ if (assoc)
+ assoc->blendDelta = -8.0f;
+ if (m_attractor)
+ GetPedAttractorManager()->DeRegisterPed(this, m_attractor);
+
+ } else if (m_nWaitState == WAITSTATE_PLAYANIM_CHAT) {
+ assoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_CHAT);
+ if (assoc)
+ assoc->blendDelta = -8.0f;
+ if (m_attractor)
+ GetPedAttractorManager()->DeRegisterPed(this, m_attractor);
+
+ } else if (m_nWaitState == WAITSTATE_SIT_DOWN || m_nWaitState == WAITSTATE_SIT_DOWN_RVRS || m_nWaitState == WAITSTATE_SIT_IDLE || m_nWaitState == WAITSTATE_SIT_UP) {
+ switch (m_nWaitState) {
+ case WAITSTATE_SIT_DOWN:
+ assoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_SEAT_DOWN);
+ if (assoc)
+ assoc->blendDelta = -8.0f;
+ break;
+ case WAITSTATE_SIT_IDLE:
+ assoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_SEAT_IDLE);
+ if (assoc)
+ assoc->blendDelta = -8.0f;
+ break;
+ case WAITSTATE_SIT_UP:
+ assoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_SEAT_UP);
+ if (assoc)
+ assoc->blendDelta = -8.0f;
+ break;
+ default:
+ break;
+ }
+ if (m_attractor)
+ GetPedAttractorManager()->DeRegisterPed(this, m_attractor);
+ }
+ }
+ break;
+ case WAITSTATE_RIOT:
+ {
+ CAnimBlock* riotAnimBlock = CAnimManager::GetAnimationBlock("riot");
+
+ for (assoc = RpAnimBlendClumpGetFirstAssociation(GetClump()); assoc; assoc = RpAnimBlendGetNextAssociation(assoc)) {
+ int first = riotAnimBlock->firstIndex;
+ int index = assoc->hierarchy - CAnimManager::GetAnimation(0);
+ if (index >= first && index < first + riotAnimBlock->numAnims) {
+ assoc->blendDelta = -1000.0f;
+ }
+ }
+ break;
+ }
+ case WAITSTATE_FAST_FALL:
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_KO_SKID_FRONT))
+ SetGetUp();
+
+ break;
+ case WAITSTATE_BOMBER:
+ assoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BOMBER);
+ if (assoc)
+ assoc->blendDelta = -8.0f;
+ break;
+ case WAITSTATE_STRIPPER:
+ {
+ CAnimBlock* stripAnimBlock = CAnimManager::GetAnimationBlock("strip");
+
+ for (assoc = RpAnimBlendClumpGetFirstAssociation(GetClump()); assoc; assoc = RpAnimBlendGetNextAssociation(assoc)) {
+ int first = stripAnimBlock->firstIndex;
+ int index = assoc->hierarchy - CAnimManager::GetAnimation(0);
+ if (index >= first && index < first + stripAnimBlock->numAnims) {
+ assoc->blendDelta = -1000.0f;
+ }
+ }
+ break;
+ }
+ case WAITSTATE_LANCESITTING:
+ assoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_SUNBATHE);
+ if (assoc)
+ assoc->blendDelta = -8.0f;
+ break;
+ case WAITSTATE_PLAYANIM_HANDSUP_SIMPLE:
+ assoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_HANDSUP);
+ if (assoc)
+ assoc->blendDelta = -8.0f;
+ break;
+ default:
+ break;
}
m_nWaitState = WAITSTATE_FALSE;
}
@@ -18735,12 +18868,9 @@ CPed::DriveVehicle(void)
float velocityFwdDotProd = DotProduct(bike->m_vecMoveSpeed, bike->GetForward());
if (m_vecTurnSpeed.MagnitudeSqr() > 0.09f) {
- // TODO(Miami)
- /*
- bike->KnockOffRider(walkbackAssoc, 44, 2, this, 0);
+ bike->KnockOffRider(WEAPONTYPE_FALL, 2, this, false);
if (bike->pPassengers[0])
- bike->KnockOffRider(walkbackAssoc, 44, 2, bike->pPassengers[0], 0);
- */
+ bike->KnockOffRider(WEAPONTYPE_FALL, 2, bike->pPassengers[0], false);
return;
}
if (!drivebyAssoc && Abs(velocityFwdDotProd) < 0.02f) {
@@ -18756,12 +18886,9 @@ CPed::DriveVehicle(void)
} else {
float maxReverseSpeed = bike->pHandling->Transmission.fMaxReverseVelocity;
if (3.5f * maxReverseSpeed > velocityFwdDotProd && (bike->m_nWheelsOnGround || bike->GetUp().z < -0.5f)) {
- // TODO(Miami)
- /*
- bike->KnockOffRider(walkbackAssoc, 44, 2, this, 0);
+ bike->KnockOffRider(WEAPONTYPE_FALL, 2, this, false);
if (bike->pPassengers[0])
- bike->KnockOffRider(walkbackAssoc, 44, 2, bike->pPassengers[0], 0);
- */
+ bike->KnockOffRider(WEAPONTYPE_FALL, 2, bike->pPassengers[0], false);
return;
}
if (bike->m_fGasPedal >= 0.0 || velocityFwdDotProd <= maxReverseSpeed * 1.5) {
@@ -19024,6 +19151,42 @@ CPed::DriveVehicle(void)
}
}
+void
+PlayRandomAnimationsFromAnimBlock(CPed* ped, AssocGroupId animGroup, uint32 first, uint32 amount)
+{
+ if (!ped->IsPedInControl())
+ return;
+
+ const char *groupName = CAnimManager::GetAnimGroupName(animGroup);
+ CAnimBlock *animBlock = CAnimManager::GetAnimationBlock(groupName);
+ CAnimBlendAssociation *assoc;
+ for (assoc = RpAnimBlendClumpGetFirstAssociation(ped->GetClump()); assoc; assoc = RpAnimBlendGetNextAssociation(assoc)) {
+ int first = animBlock->firstIndex;
+ int index = assoc->hierarchy - CAnimManager::GetAnimation(0);
+ if (index >= first && index < first + animBlock->numAnims) {
+ break;
+ }
+ }
+
+ if (CTimer::GetTimeInMilliseconds() > ped->m_nWaitTimer && assoc)
+ assoc->flags &= ~ASSOC_REPEAT;
+
+ if (!assoc || assoc->blendDelta < 0.0f) {
+ int selectedAnimOffset;
+ do
+ selectedAnimOffset = CGeneral::GetRandomNumberInRange(0, amount);
+ while (assoc && first + selectedAnimOffset == assoc->animId);
+
+ assoc = CAnimManager::BlendAnimation(ped->GetClump(), animGroup, (AnimationId)(first + selectedAnimOffset), 3.0f);
+
+ assoc->SetFinishCallback(CPed::FinishedWaitCB, ped);
+ if (assoc->flags & ASSOC_REPEAT)
+ ped->m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(3000, 8000);
+ else
+ ped->m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 8000;
+ }
+}
+
bool
IsPedPointerValid_NotInWorld(CPed* pPed)
{
diff --git a/src/peds/Ped.h b/src/peds/Ped.h
index d4f338e8..8e8e3b75 100644
--- a/src/peds/Ped.h
+++ b/src/peds/Ped.h
@@ -1092,6 +1092,7 @@ public:
void FinishTalkingOnMobileCB(CAnimBlendAssociation* assoc, void* arg);
void StartTalkingOnMobileCB(CAnimBlendAssociation* assoc, void* arg);
void FinishFuckUCB(CAnimBlendAssociation *assoc, void *arg);
+void PlayRandomAnimationsFromAnimBlock(CPed* ped, AssocGroupId animGroup, uint32 first, uint32 amount);
// TODO(Miami): Change those when Ped struct is done
#ifndef PED_SKIN
diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp
index 38ba2bf9..08f79c7e 100644
--- a/src/peds/PlayerPed.cpp
+++ b/src/peds/PlayerPed.cpp
@@ -40,6 +40,9 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
{
m_fMoveSpeed = 0.0f;
SetModelIndex(MI_PLAYER);
+#ifdef FIX_BUGS
+ m_fCurrentStamina = m_fMaxStamina = 150.0f;
+#endif
SetInitialState();
m_pWanted = new CWanted();
@@ -56,8 +59,9 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
m_pPointGunAt = nil;
SetPedState(PED_IDLE);
- m_fMaxStamina = 150.0f;
- m_fCurrentStamina = m_fMaxStamina;
+#ifndef FIX_BUGS
+ m_fCurrentStamina = m_fMaxStamina = 150.0f;
+#endif
m_fStaminaProgress = 0.0f;
m_nEvadeAmount = 0;
m_pEvadingFrom = nil;
diff --git a/src/peds/Population.cpp b/src/peds/Population.cpp
index b853937b..18a0c963 100644
--- a/src/peds/Population.cpp
+++ b/src/peds/Population.cpp
@@ -1113,4 +1113,10 @@ CPopulation::IsSkateable(CVector const& pos)
return false;
return foundCol.surfaceB == SURFACE_TARMAC || foundCol.surfaceB == SURFACE_PAVEMENT;
+}
+
+bool
+CPopulation::CanJeerAtStripper(int32 model)
+{
+ return model == MI_WMOBE || model == MI_WMYBE || model == MI_WMOST || model == MI_BMYBB;
} \ No newline at end of file
diff --git a/src/peds/Population.h b/src/peds/Population.h
index 910baa1d..eaf3eade 100644
--- a/src/peds/Population.h
+++ b/src/peds/Population.h
@@ -90,6 +90,7 @@ public:
static bool TestRoomForDummyObject(CObject*);
static bool TestSafeForRealObject(CDummyObject*);
static bool IsSkateable(CVector const&);
+ static bool CanJeerAtStripper(int32 model);
static CPed* AddDeadPedInFrontOfCar(const CVector& pos, CVehicle* pCulprit);
};
diff --git a/src/render/Console.cpp b/src/render/Console.cpp
index 8ea5b7a3..244bfb17 100644
--- a/src/render/Console.cpp
+++ b/src/render/Console.cpp
@@ -63,7 +63,7 @@ CConsole::Display()
CFont::SetJustifyOn();
CFont::SetRightJustifyWrap(0.0f);
CFont::SetBackGroundOnlyTextOff();
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
#ifndef FIX_BUGS
CFont::SetPropOff(); // not sure why this is here anyway
#endif
diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp
index f500b57a..dc425a15 100644
--- a/src/render/Hud.cpp
+++ b/src/render/Hud.cpp
@@ -392,7 +392,7 @@ void CHud::Draw()
CFont::SetCentreSize(SCREEN_SCALE_X(640.0f));
CFont::SetPropOn();
CFont::SetDropShadowPosition(0);
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
if (Min(9999, TotalAmmo - AmmoInClip) != 9999 && !CDarkel::FrenzyOnGoing() && weaponInfo->m_nWeaponSlot > 1 && weapon->m_eWeaponType != WEAPONTYPE_DETONATOR) {
CFont::SetDropShadowPosition(2);
@@ -609,7 +609,7 @@ void CHud::Draw()
CFont::SetRightJustifyOn();
CFont::SetRightJustifyWrap(0.0f);
CFont::SetBackGroundOnlyTextOff();
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
CFont::SetColor(CRGBA(0, 0, 0, fZoneAlpha));
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f) + SCREEN_SCALE_X(1.0f), SCREEN_SCALE_FROM_BOTTOM(128.0f) + SCREEN_SCALE_Y(1.0f), m_ZoneToPrint);
@@ -708,7 +708,7 @@ void CHud::Draw()
CFont::SetRightJustifyOn();
CFont::SetRightJustifyWrap(0.0f);
CFont::SetBackGroundOnlyTextOff();
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
CFont::SetColor(CRGBA(0, 0, 0, fVehicleAlpha));
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f) + SCREEN_SCALE_X(1.0f), SCREEN_SCALE_FROM_BOTTOM(105.f) + SCREEN_SCALE_Y(1.0f), m_pVehicleNameToPrint);
@@ -1020,7 +1020,7 @@ void CHud::Draw()
CFont::SetScale(SCREEN_SCALE_X(0.48f), SCREEN_SCALE_Y(1.120f));
CFont::SetCentreOn();
CFont::SetPropOn();
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
float offsetX = SCREEN_SCALE_X(40.0f) + SCREEN_SCALE_X(8.0f);
float center = SCREEN_SCALE_FROM_RIGHT(50.0f) - SCREEN_SCALE_X(8.0f) - offsetX;
@@ -1223,7 +1223,7 @@ void CHud::DrawAfterFade()
else
#endif
CFont::SetWrapx(SCREEN_SCALE_X(200.0f + 26.0f - 4.0f));
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
CFont::SetBackgroundOn();
CFont::SetBackGroundOnlyTextOff();
CFont::SetBackgroundColor(CRGBA(0, 0, 0, fAlpha * 0.9f));
@@ -1301,7 +1301,7 @@ void CHud::DrawAfterFade()
CFont::SetCentreOn();
CFont::SetPropOn();
CFont::SetCentreSize(SCREEN_SCALE_X(600.0f));
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
CFont::SetColor(CRGBA(0, 0, 0, 255));
CFont::PrintString((SCREEN_WIDTH / 2) + SCREEN_SCALE_X(2.0f), (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(84.0f) + SCREEN_SCALE_Y(2.0f), m_BigMessage[3]);
@@ -1318,7 +1318,7 @@ void CHud::DrawAfterFade()
CFont::SetPropOn();
CFont::SetCentreSize(SCREEN_SCALE_X(620.0f));
CFont::SetColor(CRGBA(0, 0, 0, 255));
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
CFont::PrintString((SCREEN_WIDTH / 2) - SCREEN_SCALE_X(2.0f), (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(84.0f) - SCREEN_SCALE_Y(2.0f), m_BigMessage[4]);
@@ -1375,7 +1375,7 @@ void CHud::DrawAfterFade()
CFont::SetPropOn();
CFont::SetCentreSize(SCREEN_SCALE_FROM_RIGHT(20.0f));
CFont::SetColor(CRGBA(0, 0, 0, 255));
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
#ifdef BETA_SLIDING_TEXT
CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(2.0f) - SCREEN_SCALE_X(OddJob2XOffset), SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(20.0f) + SCREEN_SCALE_Y(2.0f), m_BigMessage[5]);
diff --git a/src/render/SpecialFX.cpp b/src/render/SpecialFX.cpp
index 79ae21a5..4133e2fb 100644
--- a/src/render/SpecialFX.cpp
+++ b/src/render/SpecialFX.cpp
@@ -1050,7 +1050,7 @@ CMoneyMessage::Render()
CFont::SetJustifyOff();
CFont::SetColor(CRGBA(m_Colour.r, m_Colour.g, m_Colour.b, (255.0f - 255.0f * fLifeTime) * m_fOpacity));
CFont::SetBackGroundOnlyTextOff();
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
CFont::PrintString(vecOut.x, vecOut.y, m_aText);
}
}
diff --git a/src/rw/TexRead.cpp b/src/rw/TexRead.cpp
index 122ce655..4087029b 100644
--- a/src/rw/TexRead.cpp
+++ b/src/rw/TexRead.cpp
@@ -233,7 +233,7 @@ ConvertingTexturesScreen(uint32 num, uint32 count, const char *text)
CFont::SetJustifyOff();
CFont::SetColor(CRGBA(255, 217, 106, 255));
CFont::SetBackGroundOnlyTextOff();
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
CFont::PrintString(SCREEN_SCALE_X(170.0f), SCREEN_SCALE_Y(160.0f), TheText.Get(text));
CFont::DrawFonts();
DoRWStuffEndOfFrame();
diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp
index d0157c44..71192d47 100644
--- a/src/vehicles/Automobile.cpp
+++ b/src/vehicles/Automobile.cpp
@@ -421,7 +421,7 @@ CAutomobile::ProcessControl(void)
m_aSuspensionSpringRatio[3] < 1.0f && CSurfaceTable::GetAdhesionGroup(m_aWheelColPoints[3].surfaceB) == ADHESIVE_SAND){
if(GetModelIndex() != MI_RCBANDIT && GetModelIndex() != MI_RHINO){
float slowdown;
- CVector parallelSpeed = m_vecMoveSpeed - DotProduct(m_vecMoveSpeed, GetUp())*m_vecMoveSpeed;
+ CVector parallelSpeed = m_vecMoveSpeed - DotProduct(m_vecMoveSpeed, GetUp())*GetUp();
float fSpeed = parallelSpeed.MagnitudeSqr();
if(fSpeed > SQR(0.3f)){
fSpeed = Sqrt(fSpeed);
@@ -752,7 +752,7 @@ CAutomobile::ProcessControl(void)
fwdSpeed *= 0.7f;
float f = 1.0f - fwdSpeed/0.3f - 0.7f*CWeather::WetRoads;
f = Max(f, 0.4f);
- m_aSuspensionSpringRatio[i] += f*(m_aSuspensionLineLength[i]-m_aSuspensionSpringLength[i])/m_aSuspensionSpringLength[i];
+ m_aSuspensionSpringRatio[i] += 0.35f*f*(m_aSuspensionLineLength[i]-m_aSuspensionSpringLength[i])/m_aSuspensionSpringLength[i];
if(m_aSuspensionSpringRatio[i] > 1.0f)
m_aSuspensionSpringRatio[i] = 1.0f;
}
@@ -1860,7 +1860,7 @@ CAutomobile::PreRender(void)
if(Damage.GetWheelStatus(i) == WHEEL_STATUS_BURST && m_aSuspensionSpringRatioPrev[i] < 1.0f){
static float speedSq;
speedSq = m_vecMoveSpeed.MagnitudeSqr();
- if(speedSq > 0.01f &&
+ if(speedSq > SQR(0.1f) &&
m_aWheelColPoints[i].surfaceB != SURFACE_GRASS &&
m_aWheelColPoints[i].surfaceB != SURFACE_MUD_DRY &&
m_aWheelColPoints[i].surfaceB != SURFACE_SAND &&
@@ -3847,7 +3847,7 @@ CAutomobile::DoDriveByShootings(void)
if (!anim || !anim->IsRunning()) {
if (CPad::GetPad(0)->GetCarGunFired() && CTimer::GetTimeInMilliseconds() > weapon->m_nTimer) {
- weapon->FireFromCar(this, lookingLeft);
+ weapon->FireFromCar(this, lookingLeft, true);
weapon->m_nTimer = CTimer::GetTimeInMilliseconds() + 70;
}
}
@@ -4450,25 +4450,16 @@ CAutomobile::AddWheelDirtAndWater(CColPoint *colpoint, uint32 belowEffectSpeed)
}
return 0;
default:
- if ( CWeather::WetRoads > 0.01f
-#ifdef PC_PARTICLE
- && CTimer::GetFrameCounter() & 1
-#endif
- )
- {
- CParticle::AddParticle(
-#ifdef FIX_BUGS
- PARTICLE_WHEEL_WATER,
-#else
- PARTICLE_WATERSPRAY,
-#endif
- colpoint->point + CVector(0.0f, 0.0f, 0.25f+0.25f),
- CVector(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(0.005f, 0.04f)),
- nil,
- CGeneral::GetRandomNumberInRange(0.1f, 0.5f), waterCol);
+ if(CWeather::WetRoads > 0.01f){
+ if(CTimer::GetFrameCounter() & 1)
+ CParticle::AddParticle(
+ PARTICLE_WATERSPRAY,
+ colpoint->point + CVector(0.0f, 0.0f, 0.25f+0.25f),
+ CVector(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(0.005f, 0.04f)),
+ nil,
+ CGeneral::GetRandomNumberInRange(0.1f, 0.5f), waterCol);
return 0;
}
-
return 1;
}
}
diff --git a/src/vehicles/Bike.cpp b/src/vehicles/Bike.cpp
index a6fb2b82..05f088bf 100644
--- a/src/vehicles/Bike.cpp
+++ b/src/vehicles/Bike.cpp
@@ -2,16 +2,28 @@
#include "General.h"
#include "Pad.h"
#include "DMAudio.h"
+#include "Clock.h"
+#include "Timecycle.h"
+#include "ZoneCull.h"
#include "Camera.h"
#include "Darkel.h"
#include "Rubbish.h"
#include "Explosion.h"
#include "Particle.h"
+#include "ParticleObject.h"
+#include "Shadows.h"
+#include "PointLights.h"
+#include "Coronas.h"
+#include "SpecialFX.h"
+#include "WaterLevel.h"
+#include "Floater.h"
#include "World.h"
#include "SurfaceTable.h"
+#include "Weather.h"
#include "Record.h"
#include "CarCtrl.h"
#include "CarAI.h"
+#include "Script.h"
#include "Stats.h"
#include "Replay.h"
#include "AnimManager.h"
@@ -25,6 +37,23 @@
#include "Bike.h"
#include "Debug.h"
+//--MIAMI: done except for TODOs
+// BUGS: bikes get stuck in sand for some reason
+
+// TODO: maybe put this somewhere else
+inline void
+GetRelativeMatrix(RwMatrix *mat, RwFrame *frm, RwFrame *end)
+{
+ *mat = *RwFrameGetMatrix(frm);
+ frm = RwFrameGetParent(frm);
+ while(frm){
+ RwMatrixTransform(mat, RwFrameGetMatrix(frm), rwCOMBINEPOSTCONCAT);
+ frm = RwFrameGetParent(frm);
+ if(frm == end)
+ frm = nil;
+ }
+}
+
#define FAKESUSPENSION (99999.992f)
CBike::CBike(int32 id, uint8 CreatedBy)
@@ -93,7 +122,7 @@ CBike::CBike(int32 id, uint8 CreatedBy)
m_fGasPedalAudio = 0.0f;
m_bike_flag02 = false;
bWaterTight = false;
- m_bike_flag08 = false;
+ bIsBeingPickedUp = false;
bIsStanding = false;
bExtraSpeed = false;
bIsOnFire = false;
@@ -175,7 +204,7 @@ CBike::ProcessControl(void)
int i;
float wheelRot;
float acceleration = 0.0f;
- bool bCanStand = false;
+ bool bBalancedByRider = false;
bool bStuckInSand = false;
float brake = 0.0f;
CColModel *colModel = GetColModel();
@@ -202,8 +231,8 @@ CBike::ProcessControl(void)
switch(GetStatus()){
case STATUS_PLAYER:
- bCanStand = true;
- m_bike_flag08 = false;
+ bBalancedByRider = true;
+ bIsBeingPickedUp = false;
if(FindPlayerPed()->GetPedState() != PED_EXIT_CAR && FindPlayerPed()->GetPedState() != PED_DRAG_FROM_CAR){
ProcessControlInputs(0);
@@ -264,7 +293,7 @@ CBike::ProcessControl(void)
break;
case STATUS_PLAYER_PLAYBACKFROMBUFFER:
- bCanStand = true;
+ bBalancedByRider = true;
break;
case STATUS_SIMPLE:
@@ -295,7 +324,7 @@ CBike::ProcessControl(void)
CCarCtrl::SteerAICarWithPhysics(this);
PlayHornIfNecessary();
- bCanStand = true;
+ bBalancedByRider = true;
m_bike_flag80 = false;
if(bIsBeingCarJacked){
@@ -303,7 +332,7 @@ CBike::ProcessControl(void)
m_fBrakePedal = 1.0f;
bIsHandbrakeOn = true;
}else
- m_bike_flag08 = false;
+ bIsBeingPickedUp = false;
break;
case STATUS_ABANDONED:
@@ -319,7 +348,7 @@ CBike::ProcessControl(void)
#endif
m_nCarHornTimer = 0;
- bCanStand = (pDriver || pPassengers[0] || bIsBeingCarJacked) && !bIsStanding;
+ bBalancedByRider = (pDriver || pPassengers[0] || bIsBeingCarJacked) && !bIsStanding;
m_fPedLeanAmountLR = 0.0f;
m_fPedLeanAmountUD = 0.0f;
m_bike_flag80 = false;
@@ -342,7 +371,7 @@ CBike::ProcessControl(void)
#endif
m_nCarHornTimer = 0;
- bCanStand = false;
+ bBalancedByRider = false;
m_bike_flag80 = false;
m_fPedLeanAmountLR = 0.0f;
m_fPedLeanAmountUD = 0.0f;
@@ -364,7 +393,7 @@ CBike::ProcessControl(void)
#endif
m_nCarHornTimer = 0;
- bCanStand = true;
+ bBalancedByRider = true;
m_bike_flag80 = false;
break;
}
@@ -373,7 +402,7 @@ CBike::ProcessControl(void)
if(Abs(GetRight().z) > 0.35f || Abs(GetForward().z) > 0.5f)
bIsStanding = false;
- if(bCanStand || m_bike_flag08 || bIsStanding){
+ if(bBalancedByRider || bIsBeingPickedUp || bIsStanding){
float fDx = fDAxisX;
CVector res = vecTestResistance;
CVector localTurnSpeed = Multiply3x3(m_vecTurnSpeed, GetMatrix());
@@ -415,7 +444,7 @@ CBike::ProcessControl(void)
// Skip physics if object is found to have been static recently
bool skipPhysics = false;
- if(!bIsStuck && (GetStatus() == STATUS_ABANDONED || GetStatus() == STATUS_WRECKED) && !m_bike_flag08){
+ if(!bIsStuck && (GetStatus() == STATUS_ABANDONED || GetStatus() == STATUS_WRECKED) && !bIsBeingPickedUp){
bool makeStatic = false;
float moveSpeedLimit, turnSpeedLimit, distanceLimit;
@@ -523,7 +552,7 @@ CBike::ProcessControl(void)
bIsStuck = false;
}
- if(!(bCanStand || m_bike_flag08 || bIsStanding)){
+ if(!(bBalancedByRider || bIsBeingPickedUp || bIsStanding)){
if(GetRight().z < 0.0f){
if(m_fSteerAngle > -DEGTORAD(25.0f))
m_fSteerAngle -= DEGTORAD(0.5f)*CTimer::GetTimeStep();
@@ -551,6 +580,7 @@ CBike::ProcessControl(void)
m_fAirResistance = savedAirResistance;
ProcessBuoyancy();
+
// Rescale spring ratios, i.e. subtract wheel radius
for(i = 0; i < 4; i++){
// wheel radius in relation to suspension line
@@ -741,7 +771,7 @@ CBike::ProcessControl(void)
traction *= pHandling->fTractionMultiplier / 4.0f;
// Turn wheel
- if(GetStatus() == STATUS_PLAYER || !bIsStanding || m_bike_flag08){
+ if(GetStatus() == STATUS_PLAYER || !bIsStanding || bIsBeingPickedUp){
if(Abs(m_vecMoveSpeed.x) < 0.01f && Abs(m_vecMoveSpeed.y) < 0.01f && m_fSteerAngle == 0.0f){
m_fWheelAngle *= Pow(0.96f, CTimer::GetTimeStep());
}else{
@@ -980,7 +1010,7 @@ CBike::ProcessControl(void)
if(assoc)
idleAngle = DEGTORAD(10.0f) * assoc->blendAmount;
}
- if(bCanStand || m_bike_flag08){
+ if(bBalancedByRider || bIsBeingPickedUp){
m_vecAvgSurfaceRight = CrossProduct(GetForward(), m_vecAvgSurfaceNormal);
m_vecAvgSurfaceRight.Normalise();
float lean;
@@ -1175,11 +1205,11 @@ CBike::ProcessControl(void)
}
// Balance bike
- if(bCanStand || m_bike_flag08 || bIsStanding){
+ if(bBalancedByRider || bIsBeingPickedUp || bIsStanding){
float onSideness = clamp(DotProduct(GetRight(), m_vecAvgSurfaceNormal), -1.0f, 1.0f);
CVector worldCOM = Multiply3x3(GetMatrix(), m_vecCentreOfMass);
// Keep bike upright
- if(bCanStand){
+ if(bBalancedByRider){
ApplyTurnForce(-0.07f*onSideness*m_fTurnMass*GetUp()*CTimer::GetTimeStep(), worldCOM+GetRight());
bIsStanding = false;
}else
@@ -1237,11 +1267,295 @@ CBike::Teleport(CVector pos)
void
CBike::PreRender(void)
{
-// TODO: particles and lights and such
+ int i;
+ CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
+
+ // Wheel particles
+
+ if(m_aWheelState[BIKEWHEEL_REAR] != WHEEL_STATE_NORMAL &&
+ m_aWheelColPoints[BIKESUSP_R2].surfaceB != SURFACE_WATER && m_aWheelTimer[BIKESUSP_R2] > 0.0f){
+ static float smokeSize = 0.2f;
+ CVector groundPos = m_aWheelColPoints[BIKESUSP_R2].point;
+ if(m_aSuspensionSpringRatioPrev[BIKESUSP_R1] < 1.0f)
+ groundPos = (groundPos + m_aWheelColPoints[BIKESUSP_R1].point)/2.0f;
+ groundPos += Sin(m_fLeanLRAngle) * 0.8f*GetColModel()->boundingBox.min.z * GetRight();
+ CParticle::AddParticle(PARTICLE_RUBBER_SMOKE,
+ groundPos + CVector(0.0f, 0.0f, 0.25f), CVector(0.0f, 0.0f, 0.0f),
+ nil, smokeSize);
+
+ CSkidmarks::RegisterOne((uintptr)this, groundPos, GetForward().x, GetForward().y,
+ m_aWheelSkidmarkType[BIKEWHEEL_REAR], &m_aWheelSkidmarkBloody[BIKEWHEEL_REAR]);
+
+ if(m_aWheelState[BIKEWHEEL_REAR] == WHEEL_STATE_SPINNING &&
+ (CSurfaceTable::GetAdhesionGroup(m_aWheelColPoints[BIKESUSP_R2].surfaceB) == ADHESIVE_HARD ||
+ CSurfaceTable::GetAdhesionGroup(m_aWheelColPoints[BIKESUSP_R2].surfaceB) == ADHESIVE_ROAD)){
+ CParticle::AddParticle(PARTICLE_BURNINGRUBBER_SMOKE,
+ groundPos + CVector(0.0f, 0.0f, 0.25f),
+ CVector(0.0f, 0.0f, 0.0f));
+ CParticle::AddParticle(PARTICLE_BURNINGRUBBER_SMOKE,
+ groundPos + CVector(0.0f, 0.0f, 0.25f),
+ CVector(0.0f, 0.0f, 0.05f));
+ }
+ }else if(m_aWheelSkidmarkBloody[BIKEWHEEL_REAR] || m_aWheelSkidmarkUnk[BIKEWHEEL_REAR]){
+ CVector groundPos = m_aWheelColPoints[BIKESUSP_R2].point;
+ groundPos += Sin(m_fLeanLRAngle) * 0.8f*GetColModel()->boundingBox.min.z * GetRight();
+
+ CSkidmarks::RegisterOne((uintptr)this, groundPos, GetForward().x, GetForward().y,
+ m_aWheelSkidmarkType[BIKEWHEEL_REAR], &m_aWheelSkidmarkBloody[BIKEWHEEL_REAR]);
+ }
+
+ // Process lights
+
+ // Turn lights on/off
+ bool shouldLightsBeOn =
+ CClock::GetHours() > 20 ||
+ CClock::GetHours() > 19 && CClock::GetMinutes() > (m_randomSeed & 0x3F) ||
+ CClock::GetHours() < 7 ||
+ CClock::GetHours() < 8 && CClock::GetMinutes() < (m_randomSeed & 0x3F) ||
+ m_randomSeed/50000.0f < CWeather::Foggyness ||
+ m_randomSeed/50000.0f < CWeather::WetRoads;
+ if(shouldLightsBeOn != bLightsOn && GetStatus() != STATUS_WRECKED){
+ if(GetStatus() == STATUS_ABANDONED){
+ // Turn off lights on abandoned vehicles only when we they're far away
+ if(bLightsOn &&
+ Abs(TheCamera.GetPosition().x - GetPosition().x) + Abs(TheCamera.GetPosition().y - GetPosition().y) > 100.0f)
+ bLightsOn = false;
+ }else
+ bLightsOn = shouldLightsBeOn;
+ }
+
+ // Actually render the lights
+ bool alarmOn = false;
+ bool alarmOff = false;
+ if(IsAlarmOn()){
+ if(CTimer::GetTimeInMilliseconds() & 0x100)
+ alarmOn = true;
+ else
+ alarmOff = true;
+ }
+ if(bEngineOn && bLightsOn || alarmOn || alarmOff){
+ CalculateLeanMatrix();
+ CVector lookVector = GetPosition() - TheCamera.GetPosition();
+ float camDist = lookVector.Magnitude();
+ if(camDist != 0.0f)
+ lookVector *= 1.0f/camDist;
+ else
+ lookVector = CVector(1.0f, 0.0f, 0.0f);
+
+ // 1.0 if directly behind car, -1.0 if in front
+ float behindness = DotProduct(lookVector, GetForward());
+ // 0.0 if behind car, PI if in front
+ float angle = Abs(PI/2.0f - Acos(Abs(behindness)));
+
+ // Headlight
+
+ CMatrix mat;
+ CVector headLightPos = mi->m_positions[CAR_POS_HEADLIGHTS];
+#ifdef FIX_BUGS
+ if(GetModelIndex() == MI_FAGGIO || GetModelIndex() == MI_PIZZABOY)
+#else
+ if(GetModelIndex() == 152) // this is the bobcat in VC
+#endif
+ {
+ mat.SetUnity();
+ mat.RotateZ(m_fWheelAngle);
+ mat = m_leanMatrix * mat;
+ }else
+ mat = m_leanMatrix;
+ CVector light = mat * headLightPos;
+ if(behindness < 0.0f){
+ // In front of bike
+ float intensity = -0.5f*behindness + 0.3f;
+ float size = 1.0f - behindness;
+
+ if(behindness < -0.97f && camDist < 30.0f){
+ // Directly in front and not too far away
+ if(pHandling->Flags & HANDLING_HALOGEN_LIGHTS){
+ CCoronas::RegisterCorona((uintptr)this + 6, 150, 150, 195, 255,
+ light, 1.2f, 45.0f*TheCamera.LODDistMultiplier,
+ CCoronas::TYPE_HEADLIGHT, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
+ CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, angle);
+ }else{
+ CCoronas::RegisterCorona((uintptr)this + 6, 160, 160, 140, 255,
+ light, 1.2f, 45.0f*TheCamera.LODDistMultiplier,
+ CCoronas::TYPE_HEADLIGHT, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
+ CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, angle);
+ }
+ }
+
+ if(alarmOff){
+ CCoronas::RegisterCorona((uintptr)this, 0, 0, 0, 0,
+ light, size, 0.0f,
+ CCoronas::TYPE_STREAK, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
+ CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, angle);
+ }else{
+ if(pHandling->Flags & HANDLING_HALOGEN_LIGHTS){
+ CCoronas::RegisterCorona((uintptr)this + 1, 190*intensity, 190*intensity, 255*intensity, 255,
+ light, size, 50.0f*TheCamera.LODDistMultiplier,
+ CCoronas::TYPE_STREAK, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
+ CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, angle);
+ }else{
+ CCoronas::RegisterCorona((uintptr)this + 1, 210*intensity, 210*intensity, 195*intensity, 255,
+ light, size, 50.0f*TheCamera.LODDistMultiplier,
+ CCoronas::TYPE_STREAK, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
+ CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, angle);
+ }
+ }
+ }else{
+ CCoronas::UpdateCoronaCoors((uintptr)this, light, 50.0f*TheCamera.LODDistMultiplier, angle);
+ }
+
+ // bright light
+ CBrightLights::RegisterOne(light, GetUp(), GetRight(), GetForward(), pHandling->FrontLights + BRIGHTLIGHT_FRONT);
+
+ // Taillight
+
+ CVector tailLightPos = mi->m_positions[CAR_POS_TAILLIGHTS];
+ light = m_leanMatrix * tailLightPos;
+
+ // Taillight corona
+ if(behindness > 0.0f){
+ // Behind car
+ float intensity = 0.4f*behindness + 0.4f;
+ float size = (behindness + 1.0f)/2.0f;
+
+ if(m_fGasPedal < 0.0f){
+ // reversing
+ // no lights in this case
+ }else{
+ if(m_fBrakePedal > 0.0f){
+ intensity += 0.4f;
+ size += 0.3f;
+ }
+
+ if(alarmOff){
+ CCoronas::RegisterCorona((uintptr)this + 14, 0, 0, 0, 0,
+ light, size, 0.0f,
+ CCoronas::TYPE_STREAK, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
+ CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, angle);
+ }else{
+ CCoronas::RegisterCorona((uintptr)this + 14, 128*intensity, 0, 0, 255,
+ light, size, 50.0f*TheCamera.LODDistMultiplier,
+ CCoronas::TYPE_STREAK, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
+ CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, angle);
+ }
+ }
+ }else{
+ CCoronas::UpdateCoronaCoors((uintptr)this + 14, light, 50.0f*TheCamera.LODDistMultiplier, angle);
+ }
+
+ // bright light
+ CBrightLights::RegisterOne(light, GetUp(), GetRight(), GetForward(), pHandling->RearLights + BRIGHTLIGHT_REAR);
+
+ // Light shadows
+ if(!alarmOff){
+ CVector pos = GetPosition();
+ CVector2D fwd(GetForward());
+ fwd.Normalise();
+ float f = headLightPos.y + 6.0f;
+ pos += CVector(f*fwd.x, f*fwd.y, 2.0f);
+
+// TODO(MIAMI):
+// CShadows::StoreCarLightShadow(this, (uintptr)this + 22, gpShadowExplosionTex, &pos,
+// 7.0f*fwd.x, 7.0f*fwd.y, 3.5f*fwd.y, -3.5f*fwd.x, 45, 45, 45, 7.0f);
+
+ f = (tailLightPos.y - 2.5f) - (headLightPos.y + 6.0f);
+ pos += CVector(f*fwd.x, f*fwd.y, 0.0f);
+// TODO(MIAMI):
+// CShadows::StoreCarLightShadow(this, (uintptr)this + 25, gpShadowExplosionTex, &pos,
+// 3.0f, 0.0f, 0.0f, -3.0f, 35, 0, 0, 4.0f);
+ }
+
+ if(this == FindPlayerVehicle() && !alarmOff){
+ CPointLights::AddLight(CPointLights::LIGHT_DIRECTIONAL, GetPosition(), GetForward(),
+ 20.0f, 1.0f, 1.0f, 1.0f,
+ FindPlayerVehicle()->m_vecMoveSpeed.MagnitudeSqr2D() < sq(0.45f) ? CPointLights::FOG_NORMAL : CPointLights::FOG_NONE,
+ false);
+ CVector pos = GetPosition() - 4.0f*GetForward();
+ if(m_fBrakePedal > 0.0f)
+ CPointLights::AddLight(CPointLights::LIGHT_POINT, pos, CVector(0.0f, 0.0f, 0.0f),
+ 10.0f, 1.0f, 0.0f, 0.0f,
+ CPointLights::FOG_NONE, false);
+ else
+ CPointLights::AddLight(CPointLights::LIGHT_POINT, pos, CVector(0.0f, 0.0f, 0.0f),
+ 7.0f, 0.6f, 0.0f, 0.0f,
+ CPointLights::FOG_NONE, false);
+ }
+ }else if(GetStatus() != STATUS_ABANDONED && GetStatus() != STATUS_WRECKED){
+ // Lights off
+ CalculateLeanMatrix();
+
+ CVector tailLightPos = mi->m_positions[CAR_POS_TAILLIGHTS];
+ CVector light = m_leanMatrix * tailLightPos;
+
+ if(m_fBrakePedal > 0.0f || m_fGasPedal < 0.0f){
+ CVector lookVector = GetPosition() - TheCamera.GetPosition();
+ lookVector.Normalise();
+ float behindness = DotProduct(lookVector, GetForward());
+ if(behindness > 0.0f){
+ if(m_fGasPedal < 0.0f){
+ // reversing
+ // no lights in this case
+ }else{
+ // braking
+ CCoronas::RegisterCorona((uintptr)this + 14, 120, 0, 0, 255,
+ light, 1.2f, 50.0f*TheCamera.LODDistMultiplier,
+ CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
+ CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, 0.0f);
+ CBrightLights::RegisterOne(light, GetUp(), GetRight(), GetForward(), pHandling->RearLights + BRIGHTLIGHT_REAR);
+ }
+ }else{
+ CCoronas::UpdateCoronaCoors((uintptr)this + 14, light, 50.0f*TheCamera.LODDistMultiplier, 0.0f);
+ }
+ }else{
+ CCoronas::UpdateCoronaCoors((uintptr)this + 14, light, 50.0f*TheCamera.LODDistMultiplier, 0.0f);
+ }
+ }
+
+
+ // Wheel particles
+
+ float fwdSpeed = DotProduct(m_vecMoveSpeed, GetForward())*180.0f;
+ int drawParticles = Abs(fwdSpeed) < 90.0f;
+ int susp = BIKESUSP_F1;
+ for(i = 0; i < 2; i++){
+ if(i == BIKEWHEEL_REAR)
+ susp = BIKESUSP_R1;
+
+ static float speedSq;
+ // Sparks for friction of burst wheels
+ if(m_wheelStatus[i] == WHEEL_STATUS_BURST && m_aSuspensionSpringRatioPrev[susp] < 1.0f &&
+ (speedSq = m_vecMoveSpeed.MagnitudeSqr(), speedSq > SQR(0.1f)) &&
+ m_aWheelColPoints[susp].surfaceB != SURFACE_GRASS &&
+ m_aWheelColPoints[susp].surfaceB != SURFACE_MUD_DRY &&
+ m_aWheelColPoints[susp].surfaceB != SURFACE_SAND &&
+ m_aWheelColPoints[susp].surfaceB != SURFACE_SAND_BEACH){
+ CVector normalSpeed = m_aWheelColPoints[susp].normal * DotProduct(m_aWheelColPoints[susp].normal, m_vecMoveSpeed);
+ CVector frictionSpeed = m_vecMoveSpeed - normalSpeed;
+ CVector sparkDir = 0.25f*frictionSpeed;
+ CParticle::AddParticle(PARTICLE_SPARK_SMALL, m_aWheelColPoints[susp].point, sparkDir);
+
+ if(speedSq > 0.04f)
+ CParticle::AddParticle(PARTICLE_SPARK_SMALL, m_aWheelColPoints[susp].point, sparkDir);
+ if(speedSq > 0.16f){
+ CParticle::AddParticle(PARTICLE_SPARK_SMALL, m_aWheelColPoints[susp].point, sparkDir);
+ CParticle::AddParticle(PARTICLE_SPARK_SMALL, m_aWheelColPoints[susp].point, sparkDir);
+ }
+ }else if(m_aSuspensionSpringRatioPrev[i] < 1.0f &&
+ (fwdSpeed > 0.2f || m_aWheelState[i] == WHEEL_STATE_SPINNING)){
+ if(m_aWheelColPoints[susp].surfaceB == SURFACE_GRASS ||
+ m_aWheelColPoints[susp].surfaceB == SURFACE_MUD_DRY ||
+ m_aWheelColPoints[susp].surfaceB == SURFACE_SAND ||
+ m_aWheelColPoints[susp].surfaceB == SURFACE_SAND_BEACH)
+ AddWheelDirtAndWater(&m_aWheelColPoints[susp], drawParticles);
+ }
+ }
+
+ AddDamagedVehicleParticles();
+//TODO(MIAMI): StoreShadowForVehicle once we have it
CMatrix mat;
CVector pos;
- CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
CColModel *colModel = mi->GetColModel();
// Wheel rotation
@@ -1355,7 +1669,58 @@ CBike::PreRender(void)
mat.UpdateRW();
}
-// TODO: exhaust
+ // Exhaust smoke
+ if(bEngineOn && !(pHandling->Flags & HANDLING_NO_EXHAUST) && fwdSpeed < 130.0f){
+ CVector exhaustPos = mi->m_positions[CAR_POS_EXHAUST];
+ CVector pos1, pos2, dir;
+
+ if(exhaustPos != CVector(0.0f, 0.0f, 0.0f)){
+ dir.z = 0.0f;
+ if(fwdSpeed < 10.0f){
+ CVector steerFwd(-Sin(m_fSteerAngle), Cos(m_fSteerAngle), 0.0f);
+ steerFwd = Multiply3x3(GetMatrix(), steerFwd);
+ float r = CGeneral::GetRandomNumberInRange(-0.06f, -0.03f);
+ dir.x = steerFwd.x * r;
+ dir.y = steerFwd.y * r;
+ }else{
+ dir.x = m_vecMoveSpeed.x;
+ dir.y = m_vecMoveSpeed.y;
+ }
+
+ bool dblExhaust = false;
+ pos1 = GetMatrix() * exhaustPos;
+ if(pHandling->Flags & HANDLING_DBL_EXHAUST){
+ dblExhaust = true;
+ pos2 = exhaustPos;
+ pos2.x = -pos2.x;
+ pos2 = GetMatrix() * pos2;
+ }
+
+ static float fumesLimit = 2.0f;
+ if(CGeneral::GetRandomNumberInRange(1.0f, 3.0f)*(m_fGasPedal+1.1f) > fumesLimit){
+ CParticle::AddParticle(PARTICLE_EXHAUST_FUMES, pos1, dir);
+ if(dblExhaust)
+ CParticle::AddParticle(PARTICLE_EXHAUST_FUMES, pos2, dir);
+
+ if(GetStatus() == STATUS_PLAYER && (CTimer::GetFrameCounter()&3) == 0 &&
+ CWeather::Rain == 0.0f){
+ CVector camDist = GetPosition() - TheCamera.GetPosition();
+ if(DotProduct(GetForward(), camDist) > 0.0f ||
+ TheCamera.GetLookDirection() == LOOKING_LEFT ||
+ TheCamera.GetLookDirection() == LOOKING_RIGHT){
+ if(dblExhaust)
+ pos1 = 0.5f*pos1 + 0.5f*pos2;
+
+ if(TheCamera.GetLookDirection() == LOOKING_LEFT ||
+ TheCamera.GetLookDirection() == LOOKING_RIGHT)
+ pos1 -= 0.2f*GetForward();
+
+ CParticle::AddParticle(PARTICLE_HEATHAZE, pos1, CVector(0.0f, 0.0f, 0.0f));
+ }
+ }
+ }
+ }
+ }
}
void
@@ -1566,19 +1931,369 @@ CBike::ProcessControlInputs(uint8 pad)
void
CBike::ProcessBuoyancy(void)
{
- // TODO
+ int i;
+ CVector impulse, point;
+
+ if(mod_Buoyancy.ProcessBuoyancy(this, m_fBuoyancy, &point, &impulse)){
+ bTouchingWater = true;
+ ApplyMoveForce(impulse);
+ ApplyTurnForce(impulse, point);
+
+ float timeStep = Max(CTimer::GetTimeStep(), 0.01f);
+ float impulseRatio = impulse.z / (GRAVITY * m_fMass * timeStep);
+ float waterResistance = Pow(1.0f - 0.05f*impulseRatio, CTimer::GetTimeStep());
+ m_vecMoveSpeed *= waterResistance;
+ m_vecTurnSpeed *= waterResistance;
+
+ if(impulseRatio > 0.8f ||
+ impulseRatio > 0.4f && (m_aSuspensionSpringRatio[0] == 1.0f ||
+ m_aSuspensionSpringRatio[1] == 1.0f ||
+ m_aSuspensionSpringRatio[2] == 1.0f ||
+ m_aSuspensionSpringRatio[3] == 1.0f)){
+ bIsInWater = true;
+ bIsDrowning = true;
+ if(m_vecMoveSpeed.z < -0.1f)
+ m_vecMoveSpeed.z = -0.1f;
+
+ if(pDriver){
+ pDriver->bIsInWater = true;
+ if(pDriver->IsPlayer() || !bWaterTight){
+ if(m_aSuspensionSpringRatio[0] < 1.0f ||
+ m_aSuspensionSpringRatio[1] < 1.0f ||
+ m_aSuspensionSpringRatio[2] < 1.0f ||
+ m_aSuspensionSpringRatio[3] < 1.0f)
+ pDriver->InflictDamage(nil, WEAPONTYPE_DROWNING, CTimer::GetTimeStep(), PEDPIECE_TORSO, 0);
+ else
+ KnockOffRider(WEAPONTYPE_DROWNING, 0, pDriver, false);
+ }
+ }
+ for(i = 0; i < m_nNumMaxPassengers; i++)
+ if(pPassengers[i]){
+ pPassengers[i]->bIsInWater = true;
+ if(pPassengers[i]->IsPlayer() || !bWaterTight){
+ if(m_aSuspensionSpringRatio[0] < 1.0f ||
+ m_aSuspensionSpringRatio[1] < 1.0f ||
+ m_aSuspensionSpringRatio[2] < 1.0f ||
+ m_aSuspensionSpringRatio[3] < 1.0f)
+ pPassengers[i]->InflictDamage(nil, WEAPONTYPE_DROWNING, CTimer::GetTimeStep(), PEDPIECE_TORSO, 0);
+ else
+ KnockOffRider(WEAPONTYPE_DROWNING, 0, pPassengers[i], false);
+ }
+ }
+ }else{
+ bIsInWater = false;
+ bIsDrowning = false;
+ }
+ }else{
+ bIsInWater = false;
+ bIsDrowning = false;
+ bTouchingWater = false;
+ }
}
void
CBike::DoDriveByShootings(void)
{
- // TODO
+ CAnimBlendAssociation *anim;
+ CPlayerInfo* playerInfo = ((CPlayerPed*)this)->GetPlayerInfoForThisPlayerPed();
+ if (playerInfo && !playerInfo->m_bDriveByAllowed)
+ return;
+
+ CWeapon *weapon = pDriver->GetWeapon();
+ if(CWeaponInfo::GetWeaponInfo(weapon->m_eWeaponType)->m_nWeaponSlot != 5)
+ return;
+
+ weapon->Update(pDriver->m_audioEntityId, nil);
+
+ bool lookingLeft = false;
+ bool lookingRight = false;
+ if(TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN ||
+ TheCamera.m_bObbeCinematicCarCamOn){
+ if(CPad::GetPad(0)->GetLookLeft())
+ lookingLeft = true;
+ if(CPad::GetPad(0)->GetLookRight())
+ lookingRight = true;
+ }else{
+ if(TheCamera.Cams[TheCamera.ActiveCam].LookingLeft)
+ lookingLeft = true;
+ if(TheCamera.Cams[TheCamera.ActiveCam].LookingRight)
+ lookingRight = true;
+ }
+
+ if(lookingLeft || lookingRight || CPad::GetPad(0)->GetCarGunFired()){
+ if(lookingLeft){
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_BIKE_DRIVEBY_LHS);
+ if(anim)
+ anim->blendDelta = -1000.0f;
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_BIKE_DRIVEBY_FT);
+ if(anim)
+ anim->blendDelta = -1000.0f;
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_BIKE_DRIVEBY_RHS);
+ if(anim == nil || anim->blendDelta < 0.0f)
+ anim = CAnimManager::AddAnimation(pDriver->GetClump(), m_bikeAnimType, ANIM_BIKE_DRIVEBY_RHS);
+ }else if(lookingRight){
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_BIKE_DRIVEBY_RHS);
+ if(anim)
+ anim->blendDelta = -1000.0f;
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_BIKE_DRIVEBY_FT);
+ if(anim)
+ anim->blendDelta = -1000.0f;
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_BIKE_DRIVEBY_LHS);
+ if(anim == nil || anim->blendDelta < 0.0f)
+ anim = CAnimManager::AddAnimation(pDriver->GetClump(), m_bikeAnimType, ANIM_BIKE_DRIVEBY_LHS);
+ }else{
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_BIKE_DRIVEBY_LHS);
+ if(anim)
+ anim->blendDelta = -1000.0f;
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_BIKE_DRIVEBY_RHS);
+ if(anim)
+ anim->blendDelta = -1000.0f;
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_BIKE_DRIVEBY_FT);
+ if(anim == nil || anim->blendDelta < 0.0f)
+ anim = CAnimManager::AddAnimation(pDriver->GetClump(), m_bikeAnimType, ANIM_BIKE_DRIVEBY_FT);
+ }
+
+ if (!anim || !anim->IsRunning()) {
+ if (CPad::GetPad(0)->GetCarGunFired() && CTimer::GetTimeInMilliseconds() > weapon->m_nTimer) {
+ weapon->FireFromCar(this, lookingLeft, lookingRight);
+ weapon->m_nTimer = CTimer::GetTimeInMilliseconds() + 70;
+ }
+ }
+ }else{
+ weapon->Reload();
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_BIKE_DRIVEBY_RHS);
+ if(anim)
+ anim->blendDelta = -1000.0f;
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_BIKE_DRIVEBY_LHS);
+ if(anim)
+ anim->blendDelta = -1000.0f;
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_BIKE_DRIVEBY_FT);
+ if(anim)
+ anim->blendDelta = -1000.0f;
+ }
}
void
CBike::VehicleDamage(void)
{
- // TODO
+ float impulse = m_fDamageImpulse;
+ float colSpeed = 800.0f*impulse/m_fMass;
+ if(GetStatus() == STATUS_PLAYER)
+ colSpeed *= 0.65f;
+ else if(VehicleCreatedBy == MISSION_VEHICLE)
+ colSpeed *= 0.4f;
+
+ if(!bCanBeDamaged)
+ return;
+
+ if(GetStatus() == STATUS_PLAYER && CStats::GetPercentageProgress() >= 100.0f)
+ impulse *= 0.5f;
+
+ if(bIsStanding && impulse > 20.0f)
+ bIsStanding = false;
+
+ // Inflict damage on the driver and passenger
+ if(pDriver && pDriver->GetPedState() == PED_DRIVING && colSpeed > 10.0f){
+ float fwd = 0.6f;
+ if(Abs(DotProduct(m_vecDamageNormal, GetForward())) > 0.85f){
+ float u = Max(DotProduct(m_vecDamageNormal, CVector(0.0f, 0.0f, 1.0f)), 0.0f);
+ if(u < 0.85f)
+ u = 0.0f;
+ fwd += 7.0f * SQR(u);
+ }
+ float up = 0.05f;
+
+ if(GetModelIndex() == MI_SANCHEZ){
+ fwd *= 0.65f;
+ up *= 0.75f;
+ }
+
+ float total = fwd*Abs(DotProduct(m_vecDamageNormal, GetForward())) +
+ 0.45f*Abs(DotProduct(m_vecDamageNormal, GetRight())) +
+ up*Max(DotProduct(m_vecDamageNormal, GetUp()), 0.0f);
+ float damage = (total - 1.5f*Max(DotProduct(m_vecDamageNormal, GetUp()), 0.0f))*colSpeed;
+
+ if(pDriver->IsPlayer() && CCullZones::CamStairsForPlayer() && CCullZones::FindZoneWithStairsAttributeForPlayer())
+ damage = 0.0f;
+
+ if(damage > 75.0f){
+ int dir = -10;
+ if(pDriver){
+ dir = pDriver->GetLocalDirection(-m_vecDamageNormal);
+ if(pDriver->m_fHealth > 0.0f)
+ pDriver->InflictDamage(m_pDamageEntity, WEAPONTYPE_RAMMEDBYCAR, 0.05f*damage, PEDPIECE_TORSO, dir);
+ if(pDriver && pDriver->GetPedState() == PED_DRIVING)
+ KnockOffRider(WEAPONTYPE_RAMMEDBYCAR, dir, pDriver, false);
+ }
+ if(pPassengers[0]){
+ dir = pPassengers[0]->GetLocalDirection(-m_vecDamageNormal);
+ if(pPassengers[0]->m_fHealth > 0.0f)
+ pPassengers[0]->InflictDamage(m_pDamageEntity, WEAPONTYPE_RAMMEDBYCAR, 0.05f*damage, PEDPIECE_TORSO, dir);
+ if(pPassengers[0] && pPassengers[0]->GetPedState() == PED_DRIVING)
+ KnockOffRider(WEAPONTYPE_RAMMEDBYCAR, dir, pPassengers[0], false);
+ }
+ }
+ }
+
+ if(impulse > 25.0f && GetStatus() != STATUS_WRECKED){
+ float damage = (impulse-25.0f)*pHandling->fCollisionDamageMultiplier;
+ if(damage > 0.0f){
+ if(damage > 5.0f &&
+ pDriver &&
+ m_pDamageEntity && m_pDamageEntity->IsVehicle() &&
+ (this != FindPlayerVehicle() || ((CVehicle*)m_pDamageEntity)->VehicleCreatedBy == MISSION_VEHICLE) &&
+ ((CVehicle*)m_pDamageEntity)->pDriver)
+// TODO(MIAMI): enum
+ pDriver->Say(144);
+
+ int oldHealth = m_fHealth;
+ if(this == FindPlayerVehicle())
+ m_fHealth -= bTakeLessDamage ? damage/6.0f : damage/2.0f;
+ else if(bTakeLessDamage)
+ m_fHealth -= damage/12.0f;
+ else if(m_pDamageEntity && m_pDamageEntity == FindPlayerVehicle())
+ m_fHealth -= damage/1.5f;
+ else
+ m_fHealth -= damage/4.0f;
+ if(m_fHealth <= 0.0f && oldHealth > 0)
+ m_fHealth = 1.0f;
+ }
+ }
+
+ if(m_fHealth < 250.0f){
+ // Car is on fire
+ if(!bIsOnFire){
+ // Set engine on fire and remember who did this
+ bIsOnFire = true;
+ m_fFireBlowUpTimer = 0.0f;
+ m_pSetOnFireEntity = m_pDamageEntity;
+ if(m_pSetOnFireEntity)
+ m_pSetOnFireEntity->RegisterReference(&m_pSetOnFireEntity);
+ }
+ }
+}
+
+void
+CBike::AddDamagedVehicleParticles(void)
+{
+ if(this == FindPlayerVehicle() && TheCamera.GetLookingForwardFirstPerson())
+ return;
+ if(this != FindPlayerVehicle() && (CTimer::GetFrameCounter() + m_randomSeed) & 1)
+ return;
+ if(m_fHealth >= 650.0f)
+ return;
+
+ CVector direction = 0.5f*m_vecMoveSpeed;
+ CVector damagePos = ((CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()))->GetFrontSeatPosn();
+
+ damagePos.z -= 0.4f;
+ damagePos = GetMatrix()*damagePos;
+
+ CalculateLeanMatrix();
+
+ if(m_fHealth < 250.0f){
+ // fire, done in processControl
+ }else if(m_fHealth < 320.0f){
+ direction *= 0.2f;
+ CParticle::AddParticle(PARTICLE_ENGINE_SMOKE2, damagePos, direction + 0.02f*m_leanMatrix.GetRight());
+ }else if(m_fHealth < 390.0f){
+ if(((CTimer::GetFrameCounter() + m_randomSeed) & 3) == 0 ||
+ ((CTimer::GetFrameCounter() + m_randomSeed) & 3) == 2)
+ CParticle::AddParticle(PARTICLE_ENGINE_STEAM, damagePos, direction + 0.05f*m_leanMatrix.GetRight());
+ direction *= 0.3f;
+ CParticle::AddParticle(PARTICLE_ENGINE_SMOKE, damagePos, direction + 0.04f*m_leanMatrix.GetRight());
+ }else if(m_fHealth < 460.0f){
+ int rnd = CTimer::GetFrameCounter() + m_randomSeed;
+ if(rnd < 10 ||
+ rnd < 70 && rnd > 25 ||
+ rnd < 160 && rnd > 100 ||
+ rnd < 200 && rnd > 175 ||
+ rnd > 235)
+ return;
+ direction.z += 0.05f;
+ if(TheCamera.GetLookDirection() != LOOKING_FORWARD){
+ CParticle::AddParticle(PARTICLE_ENGINE_STEAM, damagePos, direction + 0.08f*m_leanMatrix.GetRight(), nil, 0.1f, 0, 0, 0, 1000);
+ }else if(((CTimer::GetFrameCounter() + m_randomSeed) & 1) == 0){
+ direction = 0.8f*m_vecMoveSpeed;
+ CParticle::AddParticle(PARTICLE_ENGINE_STEAM, damagePos, direction + 0.07f*m_leanMatrix.GetRight(), nil, 0.1f, 0, 0, 0, 1000);
+ }
+ }else if(((CTimer::GetFrameCounter() + m_randomSeed) & 3) == 0 ||
+ ((CTimer::GetFrameCounter() + m_randomSeed) & 3) == 2){
+ CParticle::AddParticle(PARTICLE_ENGINE_STEAM, damagePos + 0.06f*m_leanMatrix.GetRight(), direction);
+ }
+}
+
+int32
+CBike::AddWheelDirtAndWater(CColPoint *colpoint, uint32 belowEffectSpeed)
+{
+ int i;
+ CVector dir;
+ static float minSize = 0.02f;
+ static float maxSize = 0.04f;
+ static RwRGBA grassCol = { 8, 24, 8, 255 };
+ static RwRGBA gravelCol = { 64, 64, 64, 255 };
+ static RwRGBA mudCol = { 64, 32, 16, 255 };
+ static RwRGBA sandCol = { 170, 165, 140, 255 };
+ static RwRGBA waterCol = { 48, 48, 64, 0 };
+
+ if(!belowEffectSpeed &&
+ colpoint->surfaceB != SURFACE_SAND && colpoint->surfaceB != SURFACE_SAND_BEACH)
+ return 0;
+
+ switch(colpoint->surfaceB){
+ case SURFACE_GRASS:
+ dir.x = -0.05f*m_vecMoveSpeed.x;
+ dir.y = -0.05f*m_vecMoveSpeed.y;
+ for(i = 0; i < 4; i++){
+ dir.z = CGeneral::GetRandomNumberInRange(0.03f, 0.04f);
+ CParticle::AddParticle(PARTICLE_WHEEL_DIRT, colpoint->point, dir, nil,
+ CGeneral::GetRandomNumberInRange(minSize, maxSize), grassCol);
+ }
+ return 0;
+ case SURFACE_GRAVEL:
+ dir.x = -0.05f*m_vecMoveSpeed.x;
+ dir.y = -0.05f*m_vecMoveSpeed.y;
+ for(i = 0; i < 4; i++){
+ dir.z = CGeneral::GetRandomNumberInRange(0.03f, 0.04f);
+ CParticle::AddParticle(PARTICLE_WHEEL_DIRT, colpoint->point, dir, nil,
+ CGeneral::GetRandomNumberInRange(minSize, maxSize), gravelCol);
+ }
+ return 1;
+ case SURFACE_MUD_DRY:
+ dir.x = -0.05f*m_vecMoveSpeed.x;
+ dir.y = -0.05f*m_vecMoveSpeed.y;
+ for(i = 0; i < 4; i++){
+ dir.z = CGeneral::GetRandomNumberInRange(0.03f, 0.04f);
+ CParticle::AddParticle(PARTICLE_WHEEL_DIRT, colpoint->point, dir, nil,
+ CGeneral::GetRandomNumberInRange(minSize, maxSize), mudCol);
+ }
+ return 0;
+ case SURFACE_SAND:
+ case SURFACE_SAND_BEACH:
+ if(CTimer::GetFrameCounter() & 2)
+ return 0;
+ dir.x = 0.75f*m_vecMoveSpeed.x;
+ dir.y = 0.75f*m_vecMoveSpeed.y;
+ for(i = 0; i < 1; i++){
+ dir.z = CGeneral::GetRandomNumberInRange(0.02f, 0.055f);
+ CParticle::AddParticle(PARTICLE_SAND, colpoint->point, dir, nil,
+ 0.8f*m_vecMoveSpeed.Magnitude(), sandCol);
+ }
+ return 0;
+ default:
+ if(CWeather::WetRoads > 0.01f){
+ CParticle::AddParticle(
+ PARTICLE_WATERSPRAY,
+ colpoint->point + CVector(0.0f, 0.0f, 0.25f+0.25f),
+ CVector(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(0.005f, 0.04f)),
+ nil,
+ CGeneral::GetRandomNumberInRange(0.1f, 0.5f), waterCol);
+ return 0;
+ }
+ return 1;
+ }
+
+ return 0;
}
void
@@ -1650,7 +2365,14 @@ CBike::BlowUpCar(CEntity *culprit)
if(!bCanBeDamaged)
return;
-// TODO: property damage stuff in FIX_BUGS
+#ifdef FIX_BUGS
+ // taken from CAutomobile. maybe tweak values?
+ if(culprit == FindPlayerPed() || culprit == FindPlayerVehicle()){
+ CWorld::Players[CWorld::PlayerInFocus].m_nHavocLevel += 20;
+ CWorld::Players[CWorld::PlayerInFocus].m_fMediaAttention += 10.0f;
+ CStats::PropertyDestroyed += CGeneral::GetRandomNumber()%6000 + 4000;
+ }
+#endif
// explosion pushes vehicle up
m_vecMoveSpeed.z += 0.13f;
@@ -1675,10 +2397,28 @@ CBike::BlowUpCar(CEntity *culprit)
bool
CBike::SetUpWheelColModel(CColModel *colModel)
{
- // TODO, but unused
+ RwMatrix *mat = RwMatrixCreate();
+ CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
+ CColModel *vehColModel = mi->GetColModel();
+
+ colModel->boundingSphere = vehColModel->boundingSphere;
+ colModel->boundingBox = vehColModel->boundingBox;
+
+ GetRelativeMatrix(mat, m_aBikeNodes[BIKE_WHEEL_FRONT], m_aBikeNodes[BIKE_CHASSIS]);
+ colModel->spheres[0].Set(0.5f*mi->m_wheelScale, *RwMatrixGetPos(mat), SURFACE_RUBBER, CAR_PIECE_WHEEL_LF);
+ GetRelativeMatrix(mat, m_aBikeNodes[BIKE_WHEEL_REAR], m_aBikeNodes[BIKE_CHASSIS]);
+ colModel->spheres[1].Set(0.5f*mi->m_wheelScale, *RwMatrixGetPos(mat), SURFACE_RUBBER, CAR_PIECE_WHEEL_LR);
+ colModel->numSpheres = 2;
+#ifdef FIX_BUGS
+ RwMatrixDestroy(mat);
+#endif
return true;
}
+float fBikeBurstForceMult = 0.02f;
+float fBikeBurstFallSpeed = 0.3f;
+float fBikeBurstFallSpeedPlayer = 0.55f;
+
void
CBike::BurstTyre(uint8 wheel, bool applyForces)
{
@@ -1695,8 +2435,7 @@ CBike::BurstTyre(uint8 wheel, bool applyForces)
#ifdef FIX_BUGS
CStats::TyresPopped++;
#endif
-// TODO(MIAMI)
-// DMAudio.PlayOneShot(m_audioEntityId, SOUND_15, 0.0f);
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_TYRE_POP, 0.0f);
if(GetStatus() == STATUS_SIMPLE){
SetStatus(STATUS_PHYSICS);
@@ -1707,7 +2446,26 @@ CBike::BurstTyre(uint8 wheel, bool applyForces)
ApplyMoveForce(GetRight() * m_fMass * CGeneral::GetRandomNumberInRange(-0.02f, 0.02f));
ApplyTurnForce(GetRight() * m_fTurnMass * CGeneral::GetRandomNumberInRange(-0.02f, 0.02f), GetForward());
}
-// TODO: knock off driver
+
+#ifdef FIX_SIGNIFICANT_BUGS
+ // This code checks piece types originally so it is never triggered
+ // as we have converted them to wheel indices above already.
+ if(pDriver){
+ if(wheel == BIKEWHEEL_FRONT && (m_aSuspensionSpringRatioPrev[BIKESUSP_F1] < 1.0f || m_aSuspensionSpringRatioPrev[BIKESUSP_F2] < 1.0f) ||
+ wheel == BIKEWHEEL_REAR && (m_aSuspensionSpringRatioPrev[BIKESUSP_R1] < 1.0f || m_aSuspensionSpringRatioPrev[BIKESUSP_R2] < 1.0f)){
+ float speedSq = m_vecMoveSpeed.MagnitudeSqr();
+ if(speedSq > fBikeBurstFallSpeed &&
+ (GetStatus() != STATUS_PLAYER || speedSq > fBikeBurstFallSpeedPlayer)){
+ if(wheel == BIKEWHEEL_FRONT){
+ KnockOffRider(WEAPONTYPE_RAMMEDBYCAR, 0, pDriver, false);
+ if(pPassengers[0])
+ KnockOffRider(WEAPONTYPE_RAMMEDBYCAR, 0, pPassengers[0], false);
+ }else
+ ApplyTurnForce(2.0f*fBikeBurstForceMult*m_fTurnMass*GetRight(), GetForward());
+ }
+ }
+ }
+#endif
}
}
@@ -1795,6 +2553,206 @@ CBike::PlayCarHorn(void)
}
void
+CBike::KnockOffRider(eWeaponType weapon, uint8 direction, CPed *ped, bool bGetBackOn)
+{
+ AnimationId anim = ANIM_KO_SHOT_FRONT1;
+ if(ped == nil)
+ return;
+
+ if(!ped->IsPlayer()){
+ if(bGetBackOn){
+ if(ped->m_pedStats->m_temper > ped->m_pedStats->m_fear &&
+ ped->CharCreatedBy != MISSION_CHAR && ped->m_pMyVehicle->VehicleCreatedBy != MISSION_VEHICLE &&
+ FindPlayerPed()->m_carInObjective == ped->m_pMyVehicle &&
+ !CTheScripts::IsPlayerOnAMission())
+ ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, ped->m_pMyVehicle);
+ else if(ped->m_pedStats->m_temper > ped->m_pedStats->m_fear &&
+ ped->CharCreatedBy != MISSION_CHAR && ped->m_pMyVehicle->VehicleCreatedBy != MISSION_VEHICLE &&
+ !CTheScripts::IsPlayerOnAMission())
+ ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, ped->m_pMyVehicle);
+ else if(ped->m_pedStats->m_temper <= ped->m_pedStats->m_fear &&
+ ped->CharCreatedBy != MISSION_CHAR && ped->m_pMyVehicle->VehicleCreatedBy != MISSION_VEHICLE &&
+ !CTheScripts::IsPlayerOnAMission()){
+ ped->SetObjective(OBJ_47, ped->m_pMyVehicle);
+ ped->m_nPathDir = CGeneral::GetRandomNumberInRange(0, 8);
+ }
+ }else if(ped->m_leader == nil){
+ if(pDriver == ped)
+ ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, this);
+ else
+ ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, this);
+ }
+ }
+
+ if(ped->IsPed()){
+ CAnimBlendAssociation *assoc;
+ for(assoc = RpAnimBlendClumpGetFirstAssociation(ped->GetClump(), ASSOC_DRIVING);
+ assoc;
+ assoc = RpAnimBlendGetNextAssociation(assoc))
+ assoc->flags |= ASSOC_DELETEFADEDOUT;
+ }
+
+ ped->SetPedState(PED_IDLE);
+ CAnimManager::BlendAnimation(ped->GetClump(), ped->m_animGroup, ANIM_IDLE_STANCE, 100.0f);
+ ped->m_vehEnterType = CAR_DOOR_LF;
+ CPed::PedSetOutCarCB(nil, ped);
+ ped->SetMoveState(PEDMOVE_STILL);
+ if(GetUp().z < 0.0f)
+ ped->SetHeading(CGeneral::LimitRadianAngle(GetForward().Heading() + PI));
+ else
+ ped->SetHeading(GetForward().Heading());
+
+ switch(weapon){
+ case WEAPONTYPE_UNARMED:
+ case WEAPONTYPE_UNIDENTIFIED:
+ ped->m_vecMoveSpeed = m_vecMoveSpeed;
+ ped->m_pCollidingEntity = this;
+ anim = NUM_STD_ANIMS;
+ break;
+
+ case WEAPONTYPE_BASEBALLBAT:
+ default:
+ switch(direction){
+ case 0:
+ anim = ANIM_BIKE_FALL_R;
+ ped->m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.1f);
+ if(m_vecMoveSpeed.MagnitudeSqr() < SQR(0.3f))
+ ped->ApplyMoveForce(5.0f*GetUp() - 6.0f*GetForward());
+ ped->m_pCollidingEntity = this;
+ break;
+ case 1:
+ case 2:
+ if(m_vecMoveSpeed.MagnitudeSqr() > SQR(0.3f)){
+ anim = ANIM_KO_SPIN_R;
+ ped->m_vecMoveSpeed = 0.3f*m_vecMoveSpeed;
+ ped->ApplyMoveForce(5.0f*GetUp() + 6.0f*GetRight());
+ }else{
+ anim = ANIM_KD_LEFT;
+ ped->m_vecMoveSpeed = m_vecMoveSpeed;
+ ped->ApplyMoveForce(4.0f*GetUp() + 8.0f*GetRight());
+ }
+ // BUG or is it intentionally missing?
+ //ped->m_pCollidingEntity = this;
+ break;
+ case 3:
+ if(m_vecMoveSpeed.MagnitudeSqr() > SQR(0.3f)){
+ anim = ANIM_KO_SPIN_L;
+ ped->m_vecMoveSpeed = 0.3f*m_vecMoveSpeed;
+ ped->ApplyMoveForce(5.0f*GetUp() - 6.0f*GetRight());
+ }else{
+ anim = ANIM_KD_RIGHT;
+ ped->m_vecMoveSpeed = m_vecMoveSpeed;
+ ped->ApplyMoveForce(4.0f*GetUp() - 8.0f*GetRight());
+ }
+ // BUG or is it intentionally missing?
+ //ped->m_pCollidingEntity = this;
+ break;
+ }
+ break;
+
+ case WEAPONTYPE_DROWNING:{
+ RwRGBA color;
+ anim = ANIM_FALL_FALL;
+ ped->m_vecMoveSpeed *= 0.2f;
+ ped->m_vecMoveSpeed.z = 0.0f;
+ ped->m_pCollidingEntity = this;
+ color.red = (0.5f * CTimeCycle::GetDirectionalRed() + CTimeCycle::GetAmbientRed_Obj())*0.45f*255;
+ color.green = (0.5f * CTimeCycle::GetDirectionalGreen() + CTimeCycle::GetAmbientGreen_Obj())*0.45f*255;
+ color.blue = (0.5f * CTimeCycle::GetDirectionalBlue() + CTimeCycle::GetAmbientBlue_Obj())*0.45f*255;
+ color.alpha = CGeneral::GetRandomNumberInRange(0, 48) + 48;
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_SPLASH, 0.0f);
+ CVector splashPos = ped->GetPosition() + 2.2f*ped->m_vecMoveSpeed;
+ float waterZ = 0.0f;
+ if(CWaterLevel::GetWaterLevel(splashPos, &waterZ, false))
+ splashPos.z = waterZ;
+ CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, splashPos, CVector(0.0f, 0.0f, 0.1f),
+ 0.0f, 200, color, true);
+ break;
+ }
+
+ case WEAPONTYPE_FALL: {
+ ped->m_vecMoveSpeed = ped->m_pMyVehicle->m_vecMoveSpeed;
+ float forceXY = -0.6*m_fDamageImpulse * ped->m_fMass / m_fMass;
+ ped->ApplyMoveForce(m_vecDamageNormal.x*forceXY, m_vecDamageNormal.y*forceXY,
+ CGeneral::GetRandomNumberInRange(3.0f, 7.0f));
+ ped->m_pCollidingEntity = this;
+ switch(direction){
+ case 0: anim = ANIM_KO_SKID_BACK; break;
+ case 1: anim = ANIM_KD_RIGHT; break;
+ case 2: anim = ANIM_KO_SKID_FRONT; break;
+ case 3: anim = ANIM_KD_LEFT; break;
+ }
+ if(m_nWheelsOnGround == 0)
+ ped->b158_4 = true;
+ break;
+ }
+
+ case WEAPONTYPE_RAMMEDBYCAR: {
+ ped->m_vecMoveSpeed = ped->m_pMyVehicle->m_vecMoveSpeed;
+ static float minForceZ = 8.0f;
+ static float maxForceZ = 15.0f;
+ float forceXY = -0.6*m_fDamageImpulse * ped->m_fMass / m_fMass;
+ ped->ApplyMoveForce(m_vecDamageNormal.x*forceXY, m_vecDamageNormal.y*forceXY,
+ CGeneral::GetRandomNumberInRange(minForceZ, maxForceZ));
+ ped->m_pCollidingEntity = this;
+ switch(direction){
+ case 0: anim = ANIM_KO_SKID_BACK; break;
+ case 1: anim = ANIM_KD_RIGHT; break;
+ case 2: anim = ANIM_KO_SKID_FRONT; break;
+ case 3: anim = ANIM_KD_LEFT; break;
+ }
+ ped->b158_4 = true;
+ if(ped->IsPlayer())
+ ped->Say(SOUND_PED_DAMAGE);
+ break;
+ }
+ }
+
+ if(weapon == WEAPONTYPE_DROWNING){
+ ped->bIsStanding = false;
+ ped->bWasStanding = false;
+ ped->bIsInTheAir = true;
+ ped->bIsInWater = true;
+ ped->bTouchingWater = true;
+ CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_FALL_FALL, 4.0f);
+ }else if(weapon != WEAPONTYPE_UNARMED){
+ if(ped->m_fHealth > 0.0f)
+ ped->SetFall(1000, anim, 0);
+ else
+ ped->SetDie(anim);
+ ped->bIsStanding = false;
+ }
+
+ CEntity *ent = CWorld::TestSphereAgainstWorld(ped->GetPosition()+CVector(0.0f, 0.0, 0.5f), 0.4f, nil, true, false, false, false, false, false);
+ if(ent == nil)
+ ent = CWorld::TestSphereAgainstWorld(ped->GetPosition()+CVector(0.0f, 0.0, 0.8f), 0.4f, nil, true, false, false, false, false, false);
+ if(ent == nil)
+ ent = CWorld::TestSphereAgainstWorld(ped->GetPosition()+CTimer::GetTimeStep()*ped->m_vecMoveSpeed+CVector(0.0f, 0.0, 0.5f), 0.4f, nil, true, false, false, false, false, false);
+ if(ent == nil)
+ ent = CWorld::TestSphereAgainstWorld(ped->GetPosition()+CTimer::GetTimeStep()*ped->m_vecMoveSpeed+CVector(0.0f, 0.0, 0.8f), 0.4f, nil, true, false, false, false, false, false);
+ if(ent){
+ CColPoint point;
+ ent = nil;
+ if(CWorld::ProcessVerticalLine(ped->GetPosition(), ped->GetPosition().z-2.0f, point, ent, true, false, false, false, false, false, nil)){
+ if(ped->m_pMyVehicle == nil){
+ ped->m_pMyVehicle = this;
+ ped->PositionPedOutOfCollision();
+ ped->m_pMyVehicle = nil;
+ }else
+ ped->PositionPedOutOfCollision();
+ }else
+ ped->GetMatrix().Translate(CVector(0.0f, 0.0f, -2.0f));
+ ped->m_pCollidingEntity = ped->m_pMyVehicle;
+ ped->b158_4 = true;
+ ped->bHeadStuckInCollision = true;
+ }else if(weapon == WEAPONTYPE_RAMMEDBYCAR){
+ if(CWorld::TestSphereAgainstWorld(ped->GetPosition()+CVector(0.0f, 0.0, 1.3f), 0.6f, nil, true, false, false, false, false, false) == nil)
+ ped->GetMatrix().Translate(CVector(0.0f, 0.0f, 0.5f));
+ }
+ ped->m_pMyVehicle = nil;
+}
+
+void
CBike::PlayHornIfNecessary(void)
{
if(AutoPilot.m_bSlowedDownBecauseOfPeds ||
@@ -1816,20 +2774,6 @@ CBike::ResetSuspension(void)
}
}
-// TODO: maybe put this somewhere else
-inline void
-GetRelativeMatrix(RwMatrix *mat, RwFrame *frm, RwFrame *end)
-{
- *mat = *RwFrameGetMatrix(frm);
- frm = RwFrameGetParent(frm);
- while(frm){
- RwMatrixTransform(mat, RwFrameGetMatrix(frm), rwCOMBINEPOSTCONCAT);
- frm = RwFrameGetParent(frm);
- if(frm == end)
- frm = nil;
- }
-}
-
void
CBike::SetupSuspensionLines(void)
{
diff --git a/src/vehicles/Bike.h b/src/vehicles/Bike.h
index 02c63c1e..34d2074a 100644
--- a/src/vehicles/Bike.h
+++ b/src/vehicles/Bike.h
@@ -69,11 +69,11 @@ public:
uint8 m_bike_flag01 : 1;
uint8 m_bike_flag02 : 1;
uint8 bWaterTight : 1;
- uint8 m_bike_flag08 : 1;
+ uint8 bIsBeingPickedUp : 1;
uint8 bIsStanding : 1;
uint8 bExtraSpeed : 1; // leaning forward
uint8 bIsOnFire : 1;
- uint8 m_bike_flag80 : 1; // doing wheelie?
+ uint8 m_bike_flag80 : 1;
int16 m_doingBurnout;
float m_fTireTemperature;
float m_fBrakeDestabilization;
@@ -117,9 +117,12 @@ public:
float GetHeightAboveRoad(void);
void PlayCarHorn(void);
+ void KnockOffRider(eWeaponType weapon, uint8 direction, CPed *ped, bool bGetBackOn);
void VehicleDamage(void);
void ProcessBuoyancy(void);
void DoDriveByShootings(void);
+ void AddDamagedVehicleParticles(void);
+ int32 AddWheelDirtAndWater(CColPoint *colpoint, uint32 belowEffectSpeed);
void PlayHornIfNecessary(void);
void ResetSuspension(void);
void SetupSuspensionLines(void);
diff --git a/src/vehicles/Boat.cpp b/src/vehicles/Boat.cpp
index 99b6cbb8..2da58ed7 100644
--- a/src/vehicles/Boat.cpp
+++ b/src/vehicles/Boat.cpp
@@ -975,7 +975,7 @@ CBoat::DoDriveByShootings(void)
if (!anim || !anim->IsRunning()) {
if (CPad::GetPad(0)->GetCarGunFired() && CTimer::GetTimeInMilliseconds() > weapon->m_nTimer) {
- weapon->FireFromCar(this, lookingLeft);
+ weapon->FireFromCar(this, lookingLeft, true);
weapon->m_nTimer = CTimer::GetTimeInMilliseconds() + 70;
}
}
diff --git a/src/vehicles/CarGen.cpp b/src/vehicles/CarGen.cpp
index e6c3bbf3..574f2854 100644
--- a/src/vehicles/CarGen.cpp
+++ b/src/vehicles/CarGen.cpp
@@ -264,7 +264,7 @@ INITSAVEBUF
WriteSaveBuf(buffer, ProcessCounter);
WriteSaveBuf(buffer, GenerateEvenIfPlayerIsCloseCounter);
WriteSaveBuf(buffer, (int16)0); // alignment
- WriteSaveBuf(buffer, sizeof(CarGeneratorArray));
+ WriteSaveBuf(buffer, (uint32)sizeof(CarGeneratorArray));
for (int i = 0; i < NUM_CARGENS; i++)
WriteSaveBuf(buffer, CarGeneratorArray[i]);
VALIDATESAVEBUF(*size)
diff --git a/src/vehicles/Plane.cpp b/src/vehicles/Plane.cpp
index 8f32f12a..bc27ca32 100644
--- a/src/vehicles/Plane.cpp
+++ b/src/vehicles/Plane.cpp
@@ -84,6 +84,10 @@ CPlane::CPlane(int32 id, uint8 CreatedBy)
SetStatus(STATUS_PLANE);
bIsBIGBuilding = true;
m_level = LEVEL_NONE;
+
+#ifdef FIX_BUGS
+ m_isFarAway = true;
+#endif
}
CPlane::~CPlane()
diff --git a/src/vehicles/Train.cpp b/src/vehicles/Train.cpp
index e3bc8a9f..50f7cb1d 100644
--- a/src/vehicles/Train.cpp
+++ b/src/vehicles/Train.cpp
@@ -64,6 +64,10 @@ CTrain::CTrain(int32 id, uint8 CreatedBy)
bUsesCollision = true;
SetStatus(STATUS_TRAIN_MOVING);
+
+#ifdef FIX_BUGS
+ m_isFarAway = true;
+#endif
#else
assert(0 && "No trains in this game");
#endif
diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp
index c5537a48..824aeac1 100644
--- a/src/vehicles/Vehicle.cpp
+++ b/src/vehicles/Vehicle.cpp
@@ -80,6 +80,9 @@ CVehicle::CVehicle(uint8 CreatedBy)
bIsLawEnforcer = false;
bIsAmbulanceOnDuty = false;
bIsFireTruckOnDuty = false;
+#ifdef FIX_BUGS
+ bIsHandbrakeOn = false;
+#endif
CCarCtrl::UpdateCarCount(this, false);
m_fHealth = 1000.0f;
bEngineOn = true;
@@ -117,7 +120,7 @@ CVehicle::CVehicle(uint8 CreatedBy)
m_numPedsUseItAsCover = 0;
bIsCarParkVehicle = false;
bHasAlreadyBeenRecorded = false;
- m_bSirenOrAlarm = 0;
+ m_bSirenOrAlarm = false;
m_nCarHornTimer = 0;
m_nCarHornPattern = 0;
m_nCarHornDelay = 0;
@@ -748,7 +751,7 @@ CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelCon
static bool bBraking;
static bool bDriving;
-#ifdef FIX_BUGS
+#ifdef FIX_SIGNIFICANT_BUGS
bAlreadySkidding = false;
#endif
@@ -903,7 +906,7 @@ CVehicle::ProcessBikeWheel(CVector &wheelFwd, CVector &wheelRight, CVector &whee
static bool bDriving;
static bool bReversing;
-#ifdef FIX_BUGS
+#ifdef FIX_SIGNIFICANT_BUGS
bAlreadySkidding = false;
#endif
@@ -1032,7 +1035,6 @@ CVehicle::ProcessBikeWheel(CVector &wheelFwd, CVector &wheelRight, CVector &whee
float impulse = speed*m_fMass;
float turnImpulse = speed*GetMass(wheelContactPoint, direction);
CVector vTurnImpulse = turnImpulse * direction;
-
ApplyMoveForce(impulse * direction);
float turnRight = DotProduct(vTurnImpulse, GetRight());
diff --git a/src/weapons/Weapon.cpp b/src/weapons/Weapon.cpp
index 114a2240..8aa3db39 100644
--- a/src/weapons/Weapon.cpp
+++ b/src/weapons/Weapon.cpp
@@ -31,6 +31,7 @@
#include "WeaponInfo.h"
#include "World.h"
#include "SurfaceTable.h"
+#include "Bike.h"
// TODO(Miami)
#define AUDIO_NOT_READY
@@ -386,7 +387,7 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
}
bool
-CWeapon::FireFromCar(CVehicle *shooter, bool left)
+CWeapon::FireFromCar(CVehicle *shooter, bool left, bool right)
{
ASSERT(shooter!=nil);
@@ -396,7 +397,7 @@ CWeapon::FireFromCar(CVehicle *shooter, bool left)
if ( m_nAmmoInClip <= 0 )
return false;
- if ( FireInstantHitFromCar(shooter, left) )
+ if ( FireInstantHitFromCar(shooter, left, right) )
{
DMAudio.PlayOneShot(shooter->m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f);
@@ -524,7 +525,22 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
}
damageEntityRegistered = 3;
- // TODO(Miami): Bike
+ if (victimPed->bInVehicle) {
+ CVehicle *victimVeh = victimPed->m_pMyVehicle;
+ if (victimVeh) {
+ if (victimVeh->IsBike()) {
+ CBike *victimBike = (CBike*)victimVeh;
+ victimBike->KnockOffRider(m_eWeaponType, localDir, victimPed, false);
+ if (victimBike->pDriver) {
+ victimBike->pDriver->ReactToAttack(shooterPed);
+ } else {
+ if (victimVeh->pPassengers[0])
+ victimVeh->pPassengers[0]->ReactToAttack(shooterPed);
+ }
+ continue;
+ }
+ }
+ }
if ( !victimPed->DyingOrDead() )
victimPed->ReactToAttack(shooterPed);
@@ -2005,8 +2021,9 @@ CWeapon::FireM16_1stPerson(CEntity *shooter)
}
bool
-CWeapon::FireInstantHitFromCar(CVehicle *shooter, bool left)
+CWeapon::FireInstantHitFromCar(CVehicle *shooter, bool left, bool right)
{
+// TODO(MIAMI): bikes
CWeaponInfo *info = GetInfo();
CVehicleModelInfo *modelInfo = shooter->GetModelInfo();
diff --git a/src/weapons/Weapon.h b/src/weapons/Weapon.h
index b6ce2903..cb1d9835 100644
--- a/src/weapons/Weapon.h
+++ b/src/weapons/Weapon.h
@@ -37,7 +37,7 @@ public:
void Shutdown();
bool Fire (CEntity *shooter, CVector *fireSource);
- bool FireFromCar (CVehicle *shooter, bool left);
+ bool FireFromCar (CVehicle *shooter, bool left, bool right);
bool FireMelee (CEntity *shooter, CVector &fireSource);
bool FireInstantHit(CEntity *shooter, CVector *fireSource);
@@ -52,7 +52,7 @@ public:
bool FireAreaEffect (CEntity *shooter, CVector *fireSource);
bool FireSniper (CEntity *shooter);
bool FireM16_1stPerson (CEntity *shooter);
- bool FireInstantHitFromCar(CVehicle *shooter, bool left);
+ 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);