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(buf, size); #define CheckSaveHeader(buf,a,b,c,d,size)\ assert(ReadSaveBuf(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 (foundPed && animTime > 0.4f && foundPed->IsPedInControl()) - foundPed->SetFall(1000, ANIM_KO_SKID_FRONT, 1); + + // 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); + } + } 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_RIOT: + 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: + 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_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); 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; + 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); + } } - CAnimBlendAssociation* pAssoc = RpAnimBlendClumpGetAssociation(GetClump(), id); - if (pAssoc) - pAssoc->blendDelta = -8.0f; - 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; } - 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_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 } } @@ -1794,6 +2552,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) { @@ -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);