diff options
Diffstat (limited to 'src/entities/Entity.cpp')
-rw-r--r-- | src/entities/Entity.cpp | 302 |
1 files changed, 202 insertions, 100 deletions
diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp index c38f12c7..b2fcfbc7 100644 --- a/src/entities/Entity.cpp +++ b/src/entities/Entity.cpp @@ -1,5 +1,6 @@ #include "common.h" +#include "VuVector.h" #include "General.h" #include "RwHelper.h" #include "ModelIndices.h" @@ -22,6 +23,9 @@ #include "MemoryHeap.h" #include "Bones.h" #include "Debug.h" +#include "Ped.h" +#include "Dummy.h" +#include "WindModifiers.h" #include "SaveBuf.h" int gBuildings; @@ -47,18 +51,17 @@ CEntity::CEntity(void) bRenderScorched = false; bHasBlip = false; bIsBIGBuilding = false; - bRenderDamaged = false; + bStreamBIGBuilding = false; + bRenderDamaged = false; bBulletProof = false; bFireProof = false; bCollisionProof = false; bMeleeProof = false; bOnlyDamagedByPlayer = false; bStreamingDontDelete = false; - bZoneCulled = false; - bZoneCulled2 = false; - bRemoveFromWorld = false; + bHasHitWall = false; bImBeingRendered = false; bTouchingWater = false; @@ -66,13 +69,20 @@ CEntity::CEntity(void) bDrawLast = false; bNoBrightHeadLights = false; bDoNotRender = false; - bDistanceFade = false; - m_flagE2 = false; + + m_flagE1 = false; + bDontCastShadowsOn = false; + bOffscreen = false; + bIsStaticWaitingForCollision = false; + bDontStream = false; + bUnderwater = false; + bHasPreRenderEffects = false; m_scanCode = 0; m_modelIndex = -1; m_rwObject = nil; + m_area = AREA_MAIN_MAP; m_randomSeed = CGeneral::GetRandomNumber(); m_pFirstReference = nil; } @@ -87,6 +97,7 @@ void CEntity::SetModelIndex(uint32 id) { m_modelIndex = id; + bHasPreRenderEffects = HasPreRenderEffects(); CreateRwObject(); } @@ -94,6 +105,7 @@ void CEntity::SetModelIndexNoCreate(uint32 id) { m_modelIndex = id; + bHasPreRenderEffects = HasPreRenderEffects(); } void @@ -114,6 +126,7 @@ CEntity::CreateRwObject(void) GetMatrix().AttachRW(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic *)m_rwObject)), false); else if(RwObjectGetType(m_rwObject) == rpCLUMP) GetMatrix().AttachRW(RwFrameGetMatrix(RpClumpGetFrame((RpClump *)m_rwObject)), false); + mi->AddRef(); } } @@ -127,6 +140,7 @@ CEntity::AttachToRwObject(RwObject *obj) GetMatrix().Attach(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic *)m_rwObject)), false); else if(RwObjectGetType(m_rwObject) == rpCLUMP) GetMatrix().Attach(RwFrameGetMatrix(RpClumpGetFrame((RpClump *)m_rwObject)), false); + CModelInfo::GetModelInfo(m_modelIndex)->AddRef(); } } @@ -140,7 +154,6 @@ CEntity::DetachFromRwObject(void) GetMatrix().Detach(); } -#ifdef PED_SKIN RpAtomic* AtomicRemoveAnimFromSkinCB(RpAtomic *atomic, void *data) { @@ -152,15 +165,14 @@ AtomicRemoveAnimFromSkinCB(RpAtomic *atomic, void *data) hier->interpolator->currentAnim = nil; } #else - if(hier && hier->pCurrentAnim){ - RpHAnimAnimationDestroy(hier->pCurrentAnim); - hier->pCurrentAnim = nil; + if(hier && hier->currentAnim){ + RpHAnimAnimationDestroy(hier->currentAnim->pCurrentAnim); + hier->currentAnim = nil; } #endif } return atomic; } -#endif void CEntity::DeleteRwObject(void) @@ -174,10 +186,8 @@ CEntity::DeleteRwObject(void) RpAtomicDestroy((RpAtomic*)m_rwObject); RwFrameDestroy(f); }else if(RwObjectGetType(m_rwObject) == rpCLUMP){ -#ifdef PED_SKIN if(IsClumpSkinned((RpClump*)m_rwObject)) RpClumpForAllAtomics((RpClump*)m_rwObject, AtomicRemoveAnimFromSkinCB, nil); -#endif RpClumpDestroy((RpClump*)m_rwObject); } m_rwObject = nil; @@ -241,13 +251,12 @@ CEntity::UpdateRwFrame(void) RwFrameUpdateObjects((RwFrame*)rwObjectGetParent(m_rwObject)); } -#ifdef PED_SKIN void CEntity::UpdateRpHAnim(void) { - RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump()); - RpHAnimHierarchyUpdateMatrices(hier); - + if(IsClumpSkinned(GetClump())){ + RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump()); + RpHAnimHierarchyUpdateMatrices(hier); #if 0 int i; char buf[256]; @@ -276,22 +285,42 @@ CEntity::UpdateRpHAnim(void) void RenderSkeleton(RpHAnimHierarchy *hier); RenderSkeleton(hier); #endif + } +} + +bool +CEntity::HasPreRenderEffects(void) +{ + return IsTreeModel(GetModelIndex()) || + GetModelIndex() == MI_COLLECTABLE1 || + GetModelIndex() == MI_MONEY || + GetModelIndex() == MI_CARMINE || + GetModelIndex() == MI_NAUTICALMINE || + GetModelIndex() == MI_BRIEFCASE || + GetModelIndex() == MI_GRENADE || + GetModelIndex() == MI_MOLOTOV || + GetModelIndex() == MI_MISSILE || + GetModelIndex() == MI_BEACHBALL || + IsGlass(GetModelIndex()) || + IsObject() && ((CObject*)this)->bIsPickup || + IsLightWithPreRenderEffects(GetModelIndex()); } -#endif void CEntity::PreRender(void) { + if (CModelInfo::GetModelInfo(GetModelIndex())->GetNum2dEffects() != 0) + ProcessLightsForEntity(); + + if(!bHasPreRenderEffects) + return; + switch(m_type){ case ENTITY_TYPE_BUILDING: - if(GetModelIndex() == MI_RAILTRACKS){ - CShadows::StoreShadowForPole(this, 0.0f, -10.949f, 5.0f, 8.0f, 1.0f, 0); - CShadows::StoreShadowForPole(this, 0.0f, 10.949f, 5.0f, 8.0f, 1.0f, 1); - }else if(IsTreeModel(GetModelIndex())){ - CShadows::StoreShadowForTree(this); + if(IsTreeModel(GetModelIndex())){ + float dist = (TheCamera.GetPosition() - GetPosition()).Magnitude2D(); + CObject::fDistToNearestTree = Min(CObject::fDistToNearestTree, dist); ModifyMatrixForTreeInWind(); - }else if(IsBannerModel(GetModelIndex())){ - ModifyMatrixForBannerInWind(); } break; case ENTITY_TYPE_OBJECT: @@ -311,22 +340,6 @@ CEntity::PreRender(void) GetMatrix().UpdateRW(); UpdateRwFrame(); } - }else if(IsPickupModel(GetModelIndex())){ - if(((CObject*)this)->bIsPickup){ - CPickups::DoPickUpEffects(this); - GetMatrix().UpdateRW(); - UpdateRwFrame(); - }else if(GetModelIndex() == MI_GRENADE){ - CMotionBlurStreaks::RegisterStreak((uintptr)this, - 100, 100, 100, - GetPosition() - 0.07f*TheCamera.GetRight(), - GetPosition() + 0.07f*TheCamera.GetRight()); - }else if(GetModelIndex() == MI_MOLOTOV){ - CMotionBlurStreaks::RegisterStreak((uintptr)this, - 0, 100, 0, - GetPosition() - 0.07f*TheCamera.GetRight(), - GetPosition() + 0.07f*TheCamera.GetRight()); - } }else if(GetModelIndex() == MI_MISSILE){ CVector pos = GetPosition(); float flicker = (CGeneral::GetRandomNumber() & 0xF)/(float)0x10; @@ -334,7 +347,7 @@ CEntity::PreRender(void) gpShadowExplosionTex, &pos, 8.0f, 0.0f, 0.0f, -8.0f, 255, 200.0f*flicker, 160.0f*flicker, 120.0f*flicker, - 20.0f, false, 1.0f); + 20.0f, false, 1.0f, nil, false); CPointLights::AddLight(CPointLights::LIGHT_POINT, pos, CVector(0.0f, 0.0f, 0.0f), 8.0f, @@ -349,12 +362,44 @@ CEntity::PreRender(void) CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); }else if(IsGlass(GetModelIndex())){ PreRenderForGlassWindow(); + }else if (((CObject*)this)->bIsPickup) { + CPickups::DoPickUpEffects(this); + GetMatrix().UpdateRW(); + UpdateRwFrame(); + } else if (GetModelIndex() == MI_GRENADE) { + CMotionBlurStreaks::RegisterStreak((uintptr)this, + 100, 100, 100, + GetPosition() - 0.07f * TheCamera.GetRight(), + GetPosition() + 0.07f * TheCamera.GetRight()); + } else if (GetModelIndex() == MI_MOLOTOV) { + CMotionBlurStreaks::RegisterStreak((uintptr)this, + 0, 100, 0, + GetPosition() - 0.07f * TheCamera.GetRight(), + GetPosition() + 0.07f * TheCamera.GetRight()); + }else if(GetModelIndex() == MI_BEACHBALL){ + CVector pos = GetPosition(); + CShadows::StoreShadowToBeRendered(SHADOWTYPE_DARK, + gpShadowPedTex, &pos, + 0.4f, 0.0f, 0.0f, 0.4f, + CTimeCycle::GetShadowStrength(), + CTimeCycle::GetShadowStrength(), + CTimeCycle::GetShadowStrength(), + CTimeCycle::GetShadowStrength(), + 20.0f, false, 1.0f, nil, false); } // fall through case ENTITY_TYPE_DUMMY: if(GetModelIndex() == MI_TRAFFICLIGHTS){ CTrafficLights::DisplayActualLight(this); CShadows::StoreShadowForPole(this, 2.957f, 0.147f, 0.0f, 16.0f, 0.4f, 0); + }else if(GetModelIndex() == MI_TRAFFICLIGHTS_VERTICAL){ + CTrafficLights::DisplayActualLight(this); + }else if(GetModelIndex() == MI_TRAFFICLIGHTS_MIAMI){ + CTrafficLights::DisplayActualLight(this); + CShadows::StoreShadowForPole(this, 4.819f, 1.315f, 0.0f, 16.0f, 0.4f, 0); + }else if(GetModelIndex() == MI_TRAFFICLIGHTS_TWOVERTICAL){ + CTrafficLights::DisplayActualLight(this); + CShadows::StoreShadowForPole(this, 7.503f, 0.0f, 0.0f, 16.0f, 0.4f, 0); }else if(GetModelIndex() == MI_SINGLESTREETLIGHTS1) CShadows::StoreShadowForPole(this, 0.744f, 0.0f, 0.0f, 16.0f, 0.4f, 0); else if(GetModelIndex() == MI_SINGLESTREETLIGHTS2) @@ -363,14 +408,8 @@ CEntity::PreRender(void) CShadows::StoreShadowForPole(this, 1.143f, 0.145f, 0.0f, 16.0f, 0.4f, 0); else if(GetModelIndex() == MI_DOUBLESTREETLIGHTS) CShadows::StoreShadowForPole(this, 0.0f, -0.048f, 0.0f, 16.0f, 0.4f, 0); - else if(GetModelIndex() == MI_STREETLAMP1 || - GetModelIndex() == MI_STREETLAMP2) - CShadows::StoreShadowForPole(this, 0.0f, 0.0f, 0.0f, 16.0f, 0.4f, 0); break; } - - if (CModelInfo::GetModelInfo(GetModelIndex())->GetNum2dEffects() != 0) - ProcessLightsForEntity(); } void @@ -386,7 +425,6 @@ CEntity::Render(void) } } - bool CEntity::GetIsTouching(CVUVECTOR const ¢er, float radius) { @@ -594,14 +632,12 @@ CEntity::SetupBigBuilding(void) bStreamingDontDelete = true; bUsesCollision = false; m_level = CTheZones::GetLevelFromPosition(&GetPosition()); - if(m_level == LEVEL_GENERIC){ - if(mi->GetTxdSlot() != CTxdStore::FindTxdSlot("generic")){ - mi->SetTexDictionary("generic"); - printf("%d:%s txd has been set to generic\n", m_modelIndex, mi->GetModelName()); - } - } - if(mi->m_lodDistances[0] > 2000.0f) + if(mi->m_lodDistances[0] <= 2000.0f) + bStreamBIGBuilding = true; + if(mi->m_lodDistances[0] > 2500.0f || mi->m_ignoreDrawDist) m_level = LEVEL_GENERIC; + else if(m_level == LEVEL_GENERIC) + printf("%s isn't in a level\n", mi->GetModelName()); } float WindTabel[] = { @@ -622,27 +658,31 @@ CEntity::ModifyMatrixForTreeInWind(void) CMatrix mat(GetMatrix().m_attachment); if(CWeather::Wind >= 0.5){ - t = m_randomSeed + 16*CTimer::GetTimeInMilliseconds(); + t = m_randomSeed + 8*CTimer::GetTimeInMilliseconds(); f = (t & 0xFFF)/(float)0x1000; flutter = f * WindTabel[(t>>12)+1 & 0xF] + (1.0f - f) * WindTabel[(t>>12) & 0xF] + 1.0f; - strength = CWeather::Wind < 0.8f ? 0.008f : 0.014f; + strength = -0.015f*CWeather::Wind; }else if(CWeather::Wind >= 0.2){ t = (uintptr)this + CTimer::GetTimeInMilliseconds(); f = (t & 0xFFF)/(float)0x1000; flutter = Sin(f * 6.28f); - strength = 0.008f; + strength = -0.008f; }else{ t = (uintptr)this + CTimer::GetTimeInMilliseconds(); f = (t & 0xFFF)/(float)0x1000; flutter = Sin(f * 6.28f); - strength = 0.005f; + strength = -0.005f; } mat.GetUp().x = strength * flutter; + if(IsPalmTreeModel(GetModelIndex())) + mat.GetUp().x += -0.07f*CWeather::Wind; mat.GetUp().y = mat.GetUp().x; + CWindModifiers::FindWindModifier(GetPosition(), &mat.GetUp().x, &mat.GetUp().y); + mat.UpdateRW(); UpdateRwFrame(); } @@ -654,6 +694,7 @@ float BannerWindTabel[] = { 0.28f, 0.28f, 0.22f, 0.1f, 0.0f, -0.1f, -0.17f, -0.12f }; +// unused void CEntity::ModifyMatrixForBannerInWind(void) { @@ -693,10 +734,61 @@ CEntity::ModifyMatrixForBannerInWind(void) void CEntity::PreRenderForGlassWindow(void) { + if(((CSimpleModelInfo*)CModelInfo::GetModelInfo(m_modelIndex))->m_isArtistGlass) + return; CGlass::AskForObjectToBeRenderedInGlass(this); bIsVisible = false; } +RpMaterial* +SetAtomicAlphaCB(RpMaterial *material, void *data) +{ + ((RwRGBA*)RpMaterialGetColor(material))->alpha = (uint8)(uintptr)data; + return material; +} + +RpAtomic* +SetClumpAlphaCB(RpAtomic *atomic, void *data) +{ + RpGeometry *geometry = RpAtomicGetGeometry(atomic); + RpGeometrySetFlags(geometry, RpGeometryGetFlags(geometry) | rpGEOMETRYMODULATEMATERIALCOLOR); + RpGeometryForAllMaterials(geometry, SetAtomicAlphaCB, (void*)data); + return atomic; +} + +void +CEntity::SetRwObjectAlpha(int32 alpha) +{ + if (m_rwObject != nil) { + switch (RwObjectGetType(m_rwObject)) { + case rpATOMIC: { + RpGeometry *geometry = RpAtomicGetGeometry((RpAtomic*)m_rwObject); + RpGeometrySetFlags(geometry, RpGeometryGetFlags(geometry) | rpGEOMETRYMODULATEMATERIALCOLOR); + RpGeometryForAllMaterials(geometry, SetAtomicAlphaCB, (void*)alpha); + break; + } + case rpCLUMP: + RpClumpForAllAtomics((RpClump*)m_rwObject, SetClumpAlphaCB, (void*)alpha); + break; + } + } +} + +bool IsEntityPointerValid(CEntity* pEntity) +{ + if (!pEntity) + return false; + switch (pEntity->GetType()) { + case ENTITY_TYPE_NOTHING: return false; + case ENTITY_TYPE_BUILDING: return IsBuildingPointerValid((CBuilding*)pEntity); + case ENTITY_TYPE_VEHICLE: return IsVehiclePointerValid((CVehicle*)pEntity); + case ENTITY_TYPE_PED: return IsPedPointerValid((CPed*)pEntity); + case ENTITY_TYPE_OBJECT: return IsObjectPointerValid((CObject*)pEntity); + case ENTITY_TYPE_DUMMY: return IsDummyPointerValid((CDummy*)pEntity); + } + return false; +} + #ifdef COMPATIBLE_SAVES void CEntity::SaveEntityFlags(uint8*& buf) @@ -721,32 +813,37 @@ CEntity::SaveEntityFlags(uint8*& buf) if (bRenderScorched) tmp |= BIT(20); if (bHasBlip) tmp |= BIT(21); if (bIsBIGBuilding) tmp |= BIT(22); - if (bRenderDamaged) tmp |= BIT(23); + if (bStreamBIGBuilding) tmp |= BIT(23); - if (bBulletProof) tmp |= BIT(24); - if (bFireProof) tmp |= BIT(25); - if (bCollisionProof) tmp |= BIT(26); - if (bMeleeProof) tmp |= BIT(27); - if (bOnlyDamagedByPlayer) tmp |= BIT(28); - if (bStreamingDontDelete) tmp |= BIT(29); - if (bZoneCulled) tmp |= BIT(30); - if (bZoneCulled2) tmp |= BIT(31); + if (bRenderDamaged) tmp |= BIT(24); + if (bBulletProof) tmp |= BIT(25); + if (bFireProof) tmp |= BIT(26); + if (bCollisionProof) tmp |= BIT(27); + if (bMeleeProof) tmp |= BIT(28); + if (bOnlyDamagedByPlayer) tmp |= BIT(29); + if (bStreamingDontDelete) tmp |= BIT(30); + if (bRemoveFromWorld) tmp |= BIT(31); WriteSaveBuf(buf, tmp); tmp = 0; - if (bRemoveFromWorld) tmp |= BIT(0); - if (bHasHitWall) tmp |= BIT(1); - if (bImBeingRendered) tmp |= BIT(2); - if (bTouchingWater) tmp |= BIT(3); - if (bIsSubway) tmp |= BIT(4); - if (bDrawLast) tmp |= BIT(5); - if (bNoBrightHeadLights) tmp |= BIT(6); - if (bDoNotRender) tmp |= BIT(7); - - if (bDistanceFade) tmp |= BIT(8); - if (m_flagE2) tmp |= BIT(9); + if (bHasHitWall) tmp |= BIT(0); + if (bImBeingRendered) tmp |= BIT(1); + if (bTouchingWater) tmp |= BIT(2); + if (bIsSubway) tmp |= BIT(3); + if (bDrawLast) tmp |= BIT(4); + if (bNoBrightHeadLights) tmp |= BIT(5); + if (bDoNotRender) tmp |= BIT(6); + if (bDistanceFade) tmp |= BIT(7); + + if (m_flagE1) tmp |= BIT(8); + if (bDontCastShadowsOn) tmp |= BIT(9); + if (bOffscreen) tmp |= BIT(10); + if (bIsStaticWaitingForCollision) tmp |= BIT(11); + if (bDontStream) tmp |= BIT(12); + if (bUnderwater) tmp |= BIT(13); + if (bHasPreRenderEffects) tmp |= BIT(14); WriteSaveBuf(buf, tmp); } @@ -775,30 +872,35 @@ CEntity::LoadEntityFlags(uint8*& buf) bRenderScorched = !!(tmp & BIT(20)); bHasBlip = !!(tmp & BIT(21)); bIsBIGBuilding = !!(tmp & BIT(22)); - bRenderDamaged = !!(tmp & BIT(23)); + bStreamBIGBuilding = !!(tmp & BIT(23)); - bBulletProof = !!(tmp & BIT(24)); - bFireProof = !!(tmp & BIT(25)); - bCollisionProof = !!(tmp & BIT(26)); - bMeleeProof = !!(tmp & BIT(27)); - bOnlyDamagedByPlayer = !!(tmp & BIT(28)); - bStreamingDontDelete = !!(tmp & BIT(29)); - bZoneCulled = !!(tmp & BIT(30)); - bZoneCulled2 = !!(tmp & BIT(31)); + bRenderDamaged = !!(tmp & BIT(24)); + bBulletProof = !!(tmp & BIT(25)); + bFireProof = !!(tmp & BIT(26)); + bCollisionProof = !!(tmp & BIT(27)); + bMeleeProof = !!(tmp & BIT(28)); + bOnlyDamagedByPlayer = !!(tmp & BIT(29)); + bStreamingDontDelete = !!(tmp & BIT(30)); + bRemoveFromWorld = !!(tmp & BIT(31)); ReadSaveBuf(&tmp, buf); - bRemoveFromWorld = !!(tmp & BIT(0)); - bHasHitWall = !!(tmp & BIT(1)); - bImBeingRendered = !!(tmp & BIT(2)); - bTouchingWater = !!(tmp & BIT(3)); - bIsSubway = !!(tmp & BIT(4)); - bDrawLast = !!(tmp & BIT(5)); - bNoBrightHeadLights = !!(tmp & BIT(6)); - bDoNotRender = !!(tmp & BIT(7)); - - bDistanceFade = !!(tmp & BIT(8)); - m_flagE2 = !!(tmp & BIT(9)); + bHasHitWall = !!(tmp & BIT(0)); + bImBeingRendered = !!(tmp & BIT(1)); + bTouchingWater = !!(tmp & BIT(2)); + bIsSubway = !!(tmp & BIT(3)); + bDrawLast = !!(tmp & BIT(4)); + bNoBrightHeadLights = !!(tmp & BIT(5)); + bDoNotRender = !!(tmp & BIT(6)); + bDistanceFade = !!(tmp & BIT(7)); + + m_flagE1 = !!(tmp & BIT(8)); + bDontCastShadowsOn = !!(tmp & BIT(9)); + bOffscreen = !!(tmp & BIT(10)); + bIsStaticWaitingForCollision = !!(tmp & BIT(11)); + bDontStream = !!(tmp & BIT(12)); + bUnderwater = !!(tmp & BIT(13)); + bHasPreRenderEffects = !!(tmp & BIT(14)); } #endif |