diff options
Diffstat (limited to 'src/vehicles/DamageManager.cpp')
-rw-r--r-- | src/vehicles/DamageManager.cpp | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/src/vehicles/DamageManager.cpp b/src/vehicles/DamageManager.cpp new file mode 100644 index 00000000..1a7f25ed --- /dev/null +++ b/src/vehicles/DamageManager.cpp @@ -0,0 +1,243 @@ +#include "common.h" +#include "patcher.h" +#include "General.h" +#include "DamageManager.h" + + +float G_aComponentDamage[] = { 2.5f, 1.25f, 3.2f, 1.4f, 2.5f, 2.8f, 0.5f }; + +void +CDamageManager::ResetDamageStatus(void) +{ + memset(this, 0, sizeof(*this)); +} + +void +CDamageManager::FuckCarCompletely(void) +{ + int i; + + m_wheelStatus[0] = 2; + // wheels 1-3 not reset? + + m_doorStatus[0] = 3; + m_doorStatus[1] = 3; + m_doorStatus[2] = 3; + m_doorStatus[3] = 3; + m_doorStatus[4] = 3; + m_doorStatus[5] = 3; + + for(i = 0; i < 3; i++){ +#ifdef FIX_BUGS + ProgressPanelDamage(VEHBUMPER_FRONT); + ProgressPanelDamage(VEHBUMPER_REAR); +#else + // this can't be right + ProgressPanelDamage(COMPONENT_BUMPER_FRONT); + ProgressPanelDamage(COMPONENT_BUMPER_REAR); +#endif + } + // Why set to no damage? + m_lightStatus = 0; + m_panelStatus = 0; + SetEngineStatus(250); +} + +bool +CDamageManager::ApplyDamage(tComponent component, float damage, float unused) +{ + tComponentGroup group; + uint8 subComp; + + GetComponentGroup(component, &group, &subComp); + damage *= G_aComponentDamage[group]; + if(damage > 150.0f){ + switch(group){ + case COMPGROUP_WHEEL: + ProgressWheelDamage(subComp); + break; + case COMPGROUP_DOOR: + case COMPGROUP_BOOT: + ProgressDoorDamage(subComp); + break; + case COMPGROUP_BONNET: + if(damage > 220.0f) + ProgressEngineDamage(); + ProgressDoorDamage(subComp); + break; + case COMPGROUP_PANEL: + // so windscreen is a light? + SetLightStatus((eLights)subComp, 1); + // fall through + case COMPGROUP_BUMPER: + if(damage > 220.0f && + (component == COMPONENT_PANEL_FRONT_LEFT || + component == COMPONENT_PANEL_FRONT_RIGHT || + component == COMPONENT_PANEL_WINDSCREEN)) + ProgressEngineDamage(); + ProgressPanelDamage(subComp); + break; + } + return true; + } + return false; +} + +bool +CDamageManager::GetComponentGroup(tComponent component, tComponentGroup *componentGroup, uint8 *subComp) +{ + *subComp = -2; // ?? + + // This is done very strangely in the game, maybe an optimized switch? + if(component >= COMPONENT_PANEL_FRONT_LEFT){ + if(component >= COMPONENT_BUMPER_FRONT) + *componentGroup = COMPGROUP_BUMPER; + else + *componentGroup = COMPGROUP_PANEL; + *subComp = component - COMPONENT_PANEL_FRONT_LEFT; + return true; + }else if(component >= COMPONENT_DOOR_BONNET){ + if(component == COMPONENT_DOOR_BONNET) + *componentGroup = COMPGROUP_BONNET; + else if(component == COMPONENT_DOOR_BOOT) + *componentGroup = COMPGROUP_BOOT; + else + *componentGroup = COMPGROUP_DOOR; + *subComp = component - COMPONENT_DOOR_BONNET; + return true; + }else if(component >= COMPONENT_WHEEL_FRONT_LEFT){ + *componentGroup = COMPGROUP_WHEEL; + *subComp = component - COMPONENT_WHEEL_FRONT_LEFT; + return true; + }else if(component >= COMPONENT_DEFAULT){ + *componentGroup = COMPGROUP_DEFAULT; + *subComp = component - COMPONENT_DEFAULT; + return true; + }else + return false; +} + +void +CDamageManager::SetDoorStatus(int32 door, uint32 status) +{ + m_doorStatus[door] = status; +} + +int32 +CDamageManager::GetDoorStatus(int32 door) +{ + return m_doorStatus[door]; +} + +bool +CDamageManager::ProgressDoorDamage(uint8 door) +{ + int status = GetDoorStatus(door); + if(status == 3) + return false; + SetDoorStatus(door, status+1); + return true; +} + +void +CDamageManager::SetPanelStatus(int32 panel, uint32 status) +{ + m_panelStatus = dpb(status, panel*4, 4, m_panelStatus); +} + +int32 +CDamageManager::GetPanelStatus(int32 panel) +{ + return ldb(panel*4, 4, m_panelStatus); +} + +bool +CDamageManager::ProgressPanelDamage(uint8 panel) +{ + int status = GetPanelStatus(panel); + if(status == 3) + return false; + SetPanelStatus(panel, status+1); + return true; +} + +void +CDamageManager::SetLightStatus(eLights light, uint32 status) +{ + m_lightStatus = dpb(status, light*2, 2, m_lightStatus); +} + +int32 +CDamageManager::GetLightStatus(eLights light) +{ + return ldb(light*2, 2, m_lightStatus); +} + +void +CDamageManager::SetWheelStatus(int32 wheel, uint32 status) +{ + m_wheelStatus[wheel] = status; +} + +int32 +CDamageManager::GetWheelStatus(int32 wheel) +{ + return m_wheelStatus[wheel]; +} + +bool +CDamageManager::ProgressWheelDamage(uint8 wheel) +{ + int status = GetWheelStatus(wheel); + if(status == 3) + return false; + SetWheelStatus(wheel, status+1); + return true; +} + +void +CDamageManager::SetEngineStatus(uint32 status) +{ + if(status > 250) + m_engineStatus = 250; + else + m_engineStatus = status; +} + +int32 +CDamageManager::GetEngineStatus(void) +{ + return m_engineStatus; +} + +bool +CDamageManager::ProgressEngineDamage(void) +{ + int status = GetEngineStatus(); + int newstatus = status + 32 + (CGeneral::GetRandomNumber() & 0x1F); + if(status < 225 && newstatus > 224) + newstatus = 224; + SetEngineStatus(newstatus); + return true; +} + +STARTPATCHES + InjectHook(0x545850, &CDamageManager::ResetDamageStatus, PATCH_JUMP); + InjectHook(0x545B70, &CDamageManager::FuckCarCompletely, PATCH_JUMP); + InjectHook(0x545790, &CDamageManager::GetComponentGroup, PATCH_JUMP); + InjectHook(0x545A80, &CDamageManager::ApplyDamage, PATCH_JUMP); + InjectHook(0x545920, &CDamageManager::SetDoorStatus, PATCH_JUMP); + InjectHook(0x545930, &CDamageManager::GetDoorStatus, PATCH_JUMP); + InjectHook(0x545970, &CDamageManager::ProgressDoorDamage, PATCH_JUMP); + InjectHook(0x5458B0, &CDamageManager::SetPanelStatus, PATCH_JUMP); + InjectHook(0x5458E0, (int32 (CDamageManager::*)(int32))&CDamageManager::GetPanelStatus, PATCH_JUMP); + InjectHook(0x545A00, &CDamageManager::ProgressPanelDamage, PATCH_JUMP); + InjectHook(0x545860, &CDamageManager::SetLightStatus, PATCH_JUMP); + InjectHook(0x545890, &CDamageManager::GetLightStatus, PATCH_JUMP); + InjectHook(0x545900, &CDamageManager::SetWheelStatus, PATCH_JUMP); + InjectHook(0x545910, &CDamageManager::GetWheelStatus, PATCH_JUMP); + InjectHook(0x545A40, &CDamageManager::ProgressWheelDamage, PATCH_JUMP); + InjectHook(0x545940, &CDamageManager::SetEngineStatus, PATCH_JUMP); + InjectHook(0x545960, &CDamageManager::GetEngineStatus, PATCH_JUMP); + InjectHook(0x5459B0, &CDamageManager::ProgressEngineDamage, PATCH_JUMP); +ENDPATCHES |