summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergeanur <s.anureev@yandex.ua>2020-12-29 12:55:15 +0100
committerSergeanur <s.anureev@yandex.ua>2020-12-29 12:55:15 +0100
commitf75460fc1d83f82b088aaf69d6fba869fc1569f5 (patch)
treeae2bde9908a773eef046c10f8635129dac7b1c2a
parentMerge pull request #904 from Sergeanur/bvf (diff)
downloadre3-f75460fc1d83f82b088aaf69d6fba869fc1569f5.tar
re3-f75460fc1d83f82b088aaf69d6fba869fc1569f5.tar.gz
re3-f75460fc1d83f82b088aaf69d6fba869fc1569f5.tar.bz2
re3-f75460fc1d83f82b088aaf69d6fba869fc1569f5.tar.lz
re3-f75460fc1d83f82b088aaf69d6fba869fc1569f5.tar.xz
re3-f75460fc1d83f82b088aaf69d6fba869fc1569f5.tar.zst
re3-f75460fc1d83f82b088aaf69d6fba869fc1569f5.zip
-rw-r--r--src/core/References.cpp60
-rw-r--r--src/core/World.cpp14
-rw-r--r--src/entities/Entity.cpp833
-rw-r--r--src/entities/Entity.h18
-rw-r--r--src/render/Coronas.cpp192
-rw-r--r--src/render/Particle.cpp35
-rw-r--r--src/render/Renderer.cpp13
-rw-r--r--src/rw/RwHelper.cpp20
8 files changed, 616 insertions, 569 deletions
diff --git a/src/core/References.cpp b/src/core/References.cpp
index 52abbc3e..6b0c868c 100644
--- a/src/core/References.cpp
+++ b/src/core/References.cpp
@@ -22,6 +22,66 @@ CReferences::Init(void)
}
void
+CEntity::RegisterReference(CEntity **pent)
+{
+ if(IsBuilding())
+ return;
+ CReference *ref;
+ // check if already registered
+ for(ref = m_pFirstReference; ref; ref = ref->next)
+ if(ref->pentity == pent)
+ return;
+ // have to allocate new reference
+ ref = CReferences::pEmptyList;
+ if(ref){
+ CReferences::pEmptyList = ref->next;
+
+ ref->pentity = pent;
+ ref->next = m_pFirstReference;
+ m_pFirstReference = ref;
+ return;
+ }
+ return;
+}
+
+// Clear all references to this entity
+void
+CEntity::ResolveReferences(void)
+{
+ CReference *ref;
+ // clear pointers to this entity
+ for(ref = m_pFirstReference; ref; ref = ref->next)
+ if(*ref->pentity == this)
+ *ref->pentity = nil;
+ // free list
+ if(m_pFirstReference){
+ for(ref = m_pFirstReference; ref->next; ref = ref->next)
+ ;
+ ref->next = CReferences::pEmptyList;
+ CReferences::pEmptyList = m_pFirstReference;
+ m_pFirstReference = nil;
+ }
+}
+
+// Free all references that no longer point to this entity
+void
+CEntity::PruneReferences(void)
+{
+ CReference *ref, *next, **lastnextp;
+ lastnextp = &m_pFirstReference;
+ for(ref = m_pFirstReference; ref; ref = next){
+ next = ref->next;
+ if(*ref->pentity == this)
+ lastnextp = &ref->next;
+ else{
+ *lastnextp = ref->next;
+ ref->next = CReferences::pEmptyList;
+ CReferences::pEmptyList = ref;
+ }
+ }
+}
+
+void
CReferences::RemoveReferencesToPlayer(void)
{
if(FindPlayerVehicle())
diff --git a/src/core/World.cpp b/src/core/World.cpp
index b2c1696c..dc99f015 100644
--- a/src/core/World.cpp
+++ b/src/core/World.cpp
@@ -1600,14 +1600,24 @@ CWorld::ExtinguishAllCarFiresInArea(CVector point, float range)
}
}
+inline void
+AddSteamsFromGround(CPtrList& list)
+{
+ CPtrNode *pNode = list.first;
+ while (pNode) {
+ ((CEntity*)pNode->item)->AddSteamsFromGround(nil);
+ pNode = pNode->next;
+ }
+}
+
void
CWorld::AddParticles(void)
{
for(int32 y = 0; y < NUMSECTORS_Y; y++) {
for(int32 x = 0; x < NUMSECTORS_X; x++) {
CSector *pSector = GetSector(x, y);
- CEntity::AddSteamsFromGround(pSector->m_lists[ENTITYLIST_BUILDINGS]);
- CEntity::AddSteamsFromGround(pSector->m_lists[ENTITYLIST_DUMMIES]);
+ AddSteamsFromGround(pSector->m_lists[ENTITYLIST_BUILDINGS]);
+ AddSteamsFromGround(pSector->m_lists[ENTITYLIST_DUMMIES]);
}
}
}
diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp
index 476439fa..db004af3 100644
--- a/src/entities/Entity.cpp
+++ b/src/entities/Entity.cpp
@@ -4,31 +4,24 @@
#include "RwHelper.h"
#include "ModelIndices.h"
#include "Timer.h"
-#include "Placeable.h"
#include "Entity.h"
#include "Object.h"
-#include "ParticleObject.h"
-#include "Lights.h"
#include "World.h"
#include "Camera.h"
#include "Glass.h"
-#include "Clock.h"
#include "Weather.h"
#include "Timecycle.h"
-#include "Bridge.h"
#include "TrafficLights.h"
#include "Coronas.h"
#include "PointLights.h"
#include "Shadows.h"
#include "Pickups.h"
#include "SpecialFX.h"
-#include "References.h"
#include "TxdStore.h"
#include "Zones.h"
+#include "MemoryHeap.h"
#include "Bones.h"
#include "Debug.h"
-#include "Renderer.h"
-#include "MemoryHeap.h"
int gBuildings;
@@ -90,183 +83,16 @@ CEntity::~CEntity(void)
}
void
-CEntity::GetBoundCentre(CVector &out)
-{
- out = m_matrix * CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingSphere.center;
-};
-
-bool
-CEntity::GetIsTouching(CVector const &center, float radius)
+CEntity::SetModelIndex(uint32 id)
{
- return sq(GetBoundRadius()+radius) > (GetBoundCentre()-center).MagnitudeSqr();
-}
-
-bool
-CEntity::GetIsOnScreen(void)
-{
- return TheCamera.IsSphereVisible(GetBoundCentre(), GetBoundRadius(),
- &TheCamera.GetCameraMatrix());
-}
-
-bool
-CEntity::GetIsOnScreenComplex(void)
-{
- RwV3d boundBox[8];
-
- if(TheCamera.IsPointVisible(GetBoundCentre(), &TheCamera.GetCameraMatrix()))
- return true;
-
- CRect rect = GetBoundRect();
- CColModel *colmodel = CModelInfo::GetModelInfo(m_modelIndex)->GetColModel();
- float z = GetPosition().z;
- float minz = z + colmodel->boundingBox.min.z;
- float maxz = z + colmodel->boundingBox.max.z;
- boundBox[0].x = rect.left;
- boundBox[0].y = rect.bottom;
- boundBox[0].z = minz;
- boundBox[1].x = rect.left;
- boundBox[1].y = rect.top;
- boundBox[1].z = minz;
- boundBox[2].x = rect.right;
- boundBox[2].y = rect.bottom;
- boundBox[2].z = minz;
- boundBox[3].x = rect.right;
- boundBox[3].y = rect.top;
- boundBox[3].z = minz;
- boundBox[4].x = rect.left;
- boundBox[4].y = rect.bottom;
- boundBox[4].z = maxz;
- boundBox[5].x = rect.left;
- boundBox[5].y = rect.top;
- boundBox[5].z = maxz;
- boundBox[6].x = rect.right;
- boundBox[6].y = rect.bottom;
- boundBox[6].z = maxz;
- boundBox[7].x = rect.right;
- boundBox[7].y = rect.top;
- boundBox[7].z = maxz;
-
- return TheCamera.IsBoxVisible(boundBox, &TheCamera.GetCameraMatrix());
+ m_modelIndex = id;
+ CreateRwObject();
}
void
-CEntity::Add(void)
+CEntity::SetModelIndexNoCreate(uint32 id)
{
- int x, xstart, xmid, xend;
- int y, ystart, ymid, yend;
- CSector *s;
- CPtrList *list;
-
- CRect bounds = GetBoundRect();
- xstart = CWorld::GetSectorIndexX(bounds.left);
- xend = CWorld::GetSectorIndexX(bounds.right);
- xmid = CWorld::GetSectorIndexX((bounds.left + bounds.right)/2.0f);
- ystart = CWorld::GetSectorIndexY(bounds.top);
- yend = CWorld::GetSectorIndexY(bounds.bottom);
- ymid = CWorld::GetSectorIndexY((bounds.top + bounds.bottom)/2.0f);
- assert(xstart >= 0);
- assert(xend < NUMSECTORS_X);
- assert(ystart >= 0);
- assert(yend < NUMSECTORS_Y);
-
- for(y = ystart; y <= yend; y++)
- for(x = xstart; x <= xend; x++){
- s = CWorld::GetSector(x, y);
- if(x == xmid && y == ymid) switch(m_type){
- case ENTITY_TYPE_BUILDING:
- list = &s->m_lists[ENTITYLIST_BUILDINGS];
- break;
- case ENTITY_TYPE_VEHICLE:
- list = &s->m_lists[ENTITYLIST_VEHICLES];
- break;
- case ENTITY_TYPE_PED:
- list = &s->m_lists[ENTITYLIST_PEDS];
- break;
- case ENTITY_TYPE_OBJECT:
- list = &s->m_lists[ENTITYLIST_OBJECTS];
- break;
- case ENTITY_TYPE_DUMMY:
- list = &s->m_lists[ENTITYLIST_DUMMIES];
- break;
- }else switch(m_type){
- case ENTITY_TYPE_BUILDING:
- list = &s->m_lists[ENTITYLIST_BUILDINGS_OVERLAP];
- break;
- case ENTITY_TYPE_VEHICLE:
- list = &s->m_lists[ENTITYLIST_VEHICLES_OVERLAP];
- break;
- case ENTITY_TYPE_PED:
- list = &s->m_lists[ENTITYLIST_PEDS_OVERLAP];
- break;
- case ENTITY_TYPE_OBJECT:
- list = &s->m_lists[ENTITYLIST_OBJECTS_OVERLAP];
- break;
- case ENTITY_TYPE_DUMMY:
- list = &s->m_lists[ENTITYLIST_DUMMIES_OVERLAP];
- break;
- }
- list->InsertItem(this);
- }
-}
-
-void
-CEntity::Remove(void)
-{
- int x, xstart, xmid, xend;
- int y, ystart, ymid, yend;
- CSector *s;
- CPtrList *list;
-
- CRect bounds = GetBoundRect();
- xstart = CWorld::GetSectorIndexX(bounds.left);
- xend = CWorld::GetSectorIndexX(bounds.right);
- xmid = CWorld::GetSectorIndexX((bounds.left + bounds.right)/2.0f);
- ystart = CWorld::GetSectorIndexY(bounds.top);
- yend = CWorld::GetSectorIndexY(bounds.bottom);
- ymid = CWorld::GetSectorIndexY((bounds.top + bounds.bottom)/2.0f);
- assert(xstart >= 0);
- assert(xend < NUMSECTORS_X);
- assert(ystart >= 0);
- assert(yend < NUMSECTORS_Y);
-
- for(y = ystart; y <= yend; y++)
- for(x = xstart; x <= xend; x++){
- s = CWorld::GetSector(x, y);
- if(x == xmid && y == ymid) switch(m_type){
- case ENTITY_TYPE_BUILDING:
- list = &s->m_lists[ENTITYLIST_BUILDINGS];
- break;
- case ENTITY_TYPE_VEHICLE:
- list = &s->m_lists[ENTITYLIST_VEHICLES];
- break;
- case ENTITY_TYPE_PED:
- list = &s->m_lists[ENTITYLIST_PEDS];
- break;
- case ENTITY_TYPE_OBJECT:
- list = &s->m_lists[ENTITYLIST_OBJECTS];
- break;
- case ENTITY_TYPE_DUMMY:
- list = &s->m_lists[ENTITYLIST_DUMMIES];
- break;
- }else switch(m_type){
- case ENTITY_TYPE_BUILDING:
- list = &s->m_lists[ENTITYLIST_BUILDINGS_OVERLAP];
- break;
- case ENTITY_TYPE_VEHICLE:
- list = &s->m_lists[ENTITYLIST_VEHICLES_OVERLAP];
- break;
- case ENTITY_TYPE_PED:
- list = &s->m_lists[ENTITYLIST_PEDS_OVERLAP];
- break;
- case ENTITY_TYPE_OBJECT:
- list = &s->m_lists[ENTITYLIST_OBJECTS_OVERLAP];
- break;
- case ENTITY_TYPE_DUMMY:
- list = &s->m_lists[ENTITYLIST_DUMMIES_OVERLAP];
- break;
- }
- list->RemoveItem(this);
- }
+ m_modelIndex = id;
}
void
@@ -292,6 +118,48 @@ CEntity::CreateRwObject(void)
}
void
+CEntity::AttachToRwObject(RwObject *obj)
+{
+ m_rwObject = obj;
+ if(m_rwObject){
+ if(RwObjectGetType(m_rwObject) == rpATOMIC)
+ m_matrix.Attach(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)m_rwObject)), false);
+ else if(RwObjectGetType(m_rwObject) == rpCLUMP)
+ m_matrix.Attach(RwFrameGetMatrix(RpClumpGetFrame((RpClump*)m_rwObject)), false);
+ CModelInfo::GetModelInfo(m_modelIndex)->AddRef();
+ }
+}
+
+void
+CEntity::DetachFromRwObject(void)
+{
+ if(m_rwObject)
+ CModelInfo::GetModelInfo(m_modelIndex)->RemoveRef();
+ m_rwObject = nil;
+ m_matrix.Detach();
+}
+
+RpAtomic*
+AtomicRemoveAnimFromSkinCB(RpAtomic *atomic, void *data)
+{
+ if(RpSkinGeometryGetSkin(RpAtomicGetGeometry(atomic))){
+ RpHAnimHierarchy *hier = RpSkinAtomicGetHAnimHierarchy(atomic);
+#ifdef LIBRW
+ if(hier && hier->interpolator->currentAnim){
+ RpHAnimAnimationDestroy(hier->interpolator->currentAnim);
+ hier->interpolator->currentAnim = nil;
+ }
+#else
+ if(hier && hier->pCurrentAnim){
+ RpHAnimAnimationDestroy(hier->pCurrentAnim);
+ hier->pCurrentAnim = nil;
+ }
+#endif
+ }
+ return atomic;
+}
+
+void
CEntity::DeleteRwObject(void)
{
RwFrame *f;
@@ -316,37 +184,6 @@ CEntity::DeleteRwObject(void)
}
}
-void
-CEntity::UpdateRwFrame(void)
-{
- if(m_rwObject){
- if(RwObjectGetType(m_rwObject) == rpATOMIC)
- RwFrameUpdateObjects(RpAtomicGetFrame((RpAtomic*)m_rwObject));
- else if(RwObjectGetType(m_rwObject) == rpCLUMP)
- RwFrameUpdateObjects(RpClumpGetFrame((RpClump*)m_rwObject));
- }
-}
-
-void
-CEntity::SetupBigBuilding(void)
-{
- CSimpleModelInfo *mi;
-
- mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(m_modelIndex);
- bIsBIGBuilding = true;
- 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->GetName());
- }
- }
- if(mi->m_lodDistances[0] > 2000.0f)
- m_level = LEVEL_GENERIC;
-}
-
CRect
CEntity::GetBoundRect(void)
{
@@ -368,6 +205,75 @@ CEntity::GetBoundRect(void)
return rect;
}
+CVector
+CEntity::GetBoundCentre(void)
+{
+ CVector v;
+ GetBoundCentre(v);
+ return v;
+}
+
+void
+CEntity::GetBoundCentre(CVector &out)
+{
+ out = m_matrix * CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingSphere.center;
+}
+
+float
+CEntity::GetBoundRadius(void)
+{
+ return CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingSphere.radius;
+}
+
+void
+CEntity::UpdateRwFrame(void)
+{
+ if(m_rwObject){
+ if(RwObjectGetType(m_rwObject) == rpATOMIC)
+ RwFrameUpdateObjects(RpAtomicGetFrame((RpAtomic*)m_rwObject));
+ else if(RwObjectGetType(m_rwObject) == rpCLUMP)
+ RwFrameUpdateObjects(RpClumpGetFrame((RpClump*)m_rwObject));
+ }
+}
+
+#ifdef PED_SKIN
+void
+CEntity::UpdateRpHAnim(void)
+{
+ RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
+ RpHAnimHierarchyUpdateMatrices(hier);
+
+#if 0
+ int i;
+ char buf[256];
+ if(this == (CEntity*)FindPlayerPed())
+ for(i = 0; i < hier->numNodes; i++){
+ RpHAnimStdInterpFrame *kf = (RpHAnimStdInterpFrame*)rpHANIMHIERARCHYGETINTERPFRAME(hier, i);
+ sprintf(buf, "%6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %d %s",
+ kf->q.imag.x, kf->q.imag.y, kf->q.imag.z, kf->q.real,
+ kf->t.x, kf->t.y, kf->t.z,
+ HIERNODEID(hier, i),
+ ConvertBoneTag2BoneName(HIERNODEID(hier, i)));
+ CDebug::PrintAt(buf, 10, 1+i*3);
+
+ RwMatrix *m = &RpHAnimHierarchyGetMatrixArray(hier)[i];
+ sprintf(buf, "%6.3f %6.3f %6.3f %6.3f",
+ m->right.x, m->up.x, m->at.x, m->pos.x);
+ CDebug::PrintAt(buf, 80, 1+i*3+0);
+ sprintf(buf, "%6.3f %6.3f %6.3f %6.3f",
+ m->right.y, m->up.y, m->at.y, m->pos.y);
+ CDebug::PrintAt(buf, 80, 1+i*3+1);
+ sprintf(buf, "%6.3f %6.3f %6.3f %6.3f",
+ m->right.z, m->up.z, m->at.z, m->pos.z);
+ CDebug::PrintAt(buf, 80, 1+i*3+2);
+ }
+
+ void RenderSkeleton(RpHAnimHierarchy *hier);
+ RenderSkeleton(hier);
+#endif
+}
+#endif
+
void
CEntity::PreRender(void)
{
@@ -463,13 +369,6 @@ CEntity::PreRender(void)
}
void
-CEntity::PreRenderForGlassWindow(void)
-{
- CGlass::AskForObjectToBeRenderedInGlass(this);
- bIsVisible = false;
-}
-
-void
CEntity::Render(void)
{
if(m_rwObject){
@@ -483,352 +382,215 @@ CEntity::Render(void)
}
bool
-CEntity::SetupLighting(void)
+CEntity::GetIsTouching(CVector const &center, float radius)
{
- DeActivateDirectional();
- SetAmbientColours();
- return false;
+ return sq(GetBoundRadius()+radius) > (GetBoundCentre()-center).MagnitudeSqr();
}
-void
-CEntity::AttachToRwObject(RwObject *obj)
+bool
+CEntity::IsVisible(void)
{
- m_rwObject = obj;
- if(m_rwObject){
- if(RwObjectGetType(m_rwObject) == rpATOMIC)
- m_matrix.Attach(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)m_rwObject)), false);
- else if(RwObjectGetType(m_rwObject) == rpCLUMP)
- m_matrix.Attach(RwFrameGetMatrix(RpClumpGetFrame((RpClump*)m_rwObject)), false);
- CModelInfo::GetModelInfo(m_modelIndex)->AddRef();
- }
+ return m_rwObject && bIsVisible && GetIsOnScreen();
}
-void
-CEntity::DetachFromRwObject(void)
+bool
+CEntity::IsVisibleComplex(void)
{
- if(m_rwObject)
- CModelInfo::GetModelInfo(m_modelIndex)->RemoveRef();
- m_rwObject = nil;
- m_matrix.Detach();
+ return m_rwObject && bIsVisible && GetIsOnScreenComplex();
}
-void
-CEntity::RegisterReference(CEntity **pent)
+bool
+CEntity::GetIsOnScreen(void)
{
- if(IsBuilding())
- return;
- CReference *ref;
- // check if already registered
- for(ref = m_pFirstReference; ref; ref = ref->next)
- if(ref->pentity == pent)
- return;
- // have to allocate new reference
- ref = CReferences::pEmptyList;
- if(ref){
- CReferences::pEmptyList = ref->next;
-
- ref->pentity = pent;
- ref->next = m_pFirstReference;
- m_pFirstReference = ref;
- return;
- }
- return;
+ return TheCamera.IsSphereVisible(GetBoundCentre(), GetBoundRadius(),
+ &TheCamera.GetCameraMatrix());
}
-// Clear all references to this entity
-void
-CEntity::ResolveReferences(void)
+bool
+CEntity::GetIsOnScreenComplex(void)
{
- CReference *ref;
- // clear pointers to this entity
- for(ref = m_pFirstReference; ref; ref = ref->next)
- if(*ref->pentity == this)
- *ref->pentity = nil;
- // free list
- if(m_pFirstReference){
- for(ref = m_pFirstReference; ref->next; ref = ref->next)
- ;
- ref->next = CReferences::pEmptyList;
- CReferences::pEmptyList = m_pFirstReference;
- m_pFirstReference = nil;
- }
+ RwV3d boundBox[8];
+
+ if(TheCamera.IsPointVisible(GetBoundCentre(), &TheCamera.GetCameraMatrix()))
+ return true;
+
+ CRect rect = GetBoundRect();
+ CColModel *colmodel = CModelInfo::GetModelInfo(m_modelIndex)->GetColModel();
+ float z = GetPosition().z;
+ float minz = z + colmodel->boundingBox.min.z;
+ float maxz = z + colmodel->boundingBox.max.z;
+ boundBox[0].x = rect.left;
+ boundBox[0].y = rect.bottom;
+ boundBox[0].z = minz;
+ boundBox[1].x = rect.left;
+ boundBox[1].y = rect.top;
+ boundBox[1].z = minz;
+ boundBox[2].x = rect.right;
+ boundBox[2].y = rect.bottom;
+ boundBox[2].z = minz;
+ boundBox[3].x = rect.right;
+ boundBox[3].y = rect.top;
+ boundBox[3].z = minz;
+ boundBox[4].x = rect.left;
+ boundBox[4].y = rect.bottom;
+ boundBox[4].z = maxz;
+ boundBox[5].x = rect.left;
+ boundBox[5].y = rect.top;
+ boundBox[5].z = maxz;
+ boundBox[6].x = rect.right;
+ boundBox[6].y = rect.bottom;
+ boundBox[6].z = maxz;
+ boundBox[7].x = rect.right;
+ boundBox[7].y = rect.top;
+ boundBox[7].z = maxz;
+
+ return TheCamera.IsBoxVisible(boundBox, &TheCamera.GetCameraMatrix());
}
-// Free all references that no longer point to this entity
void
-CEntity::PruneReferences(void)
+CEntity::Add(void)
{
- CReference *ref, *next, **lastnextp;
- lastnextp = &m_pFirstReference;
- for(ref = m_pFirstReference; ref; ref = next){
- next = ref->next;
- if(*ref->pentity == this)
- lastnextp = &ref->next;
- else{
- *lastnextp = ref->next;
- ref->next = CReferences::pEmptyList;
- CReferences::pEmptyList = ref;
+ int x, xstart, xmid, xend;
+ int y, ystart, ymid, yend;
+ CSector *s;
+ CPtrList *list;
+
+ CRect bounds = GetBoundRect();
+ xstart = CWorld::GetSectorIndexX(bounds.left);
+ xend = CWorld::GetSectorIndexX(bounds.right);
+ xmid = CWorld::GetSectorIndexX((bounds.left + bounds.right)/2.0f);
+ ystart = CWorld::GetSectorIndexY(bounds.top);
+ yend = CWorld::GetSectorIndexY(bounds.bottom);
+ ymid = CWorld::GetSectorIndexY((bounds.top + bounds.bottom)/2.0f);
+ assert(xstart >= 0);
+ assert(xend < NUMSECTORS_X);
+ assert(ystart >= 0);
+ assert(yend < NUMSECTORS_Y);
+
+ for(y = ystart; y <= yend; y++)
+ for(x = xstart; x <= xend; x++){
+ s = CWorld::GetSector(x, y);
+ if(x == xmid && y == ymid) switch(m_type){
+ case ENTITY_TYPE_BUILDING:
+ list = &s->m_lists[ENTITYLIST_BUILDINGS];
+ break;
+ case ENTITY_TYPE_VEHICLE:
+ list = &s->m_lists[ENTITYLIST_VEHICLES];
+ break;
+ case ENTITY_TYPE_PED:
+ list = &s->m_lists[ENTITYLIST_PEDS];
+ break;
+ case ENTITY_TYPE_OBJECT:
+ list = &s->m_lists[ENTITYLIST_OBJECTS];
+ break;
+ case ENTITY_TYPE_DUMMY:
+ list = &s->m_lists[ENTITYLIST_DUMMIES];
+ break;
+ }else switch(m_type){
+ case ENTITY_TYPE_BUILDING:
+ list = &s->m_lists[ENTITYLIST_BUILDINGS_OVERLAP];
+ break;
+ case ENTITY_TYPE_VEHICLE:
+ list = &s->m_lists[ENTITYLIST_VEHICLES_OVERLAP];
+ break;
+ case ENTITY_TYPE_PED:
+ list = &s->m_lists[ENTITYLIST_PEDS_OVERLAP];
+ break;
+ case ENTITY_TYPE_OBJECT:
+ list = &s->m_lists[ENTITYLIST_OBJECTS_OVERLAP];
+ break;
+ case ENTITY_TYPE_DUMMY:
+ list = &s->m_lists[ENTITYLIST_DUMMIES_OVERLAP];
+ break;
+ }
+ list->InsertItem(this);
}
- }
}
-#ifdef PED_SKIN
void
-CEntity::UpdateRpHAnim(void)
+CEntity::Remove(void)
{
- RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
- RpHAnimHierarchyUpdateMatrices(hier);
-
-#if 0
- int i;
- char buf[256];
- if(this == (CEntity*)FindPlayerPed())
- for(i = 0; i < hier->numNodes; i++){
- RpHAnimStdInterpFrame *kf = (RpHAnimStdInterpFrame*)rpHANIMHIERARCHYGETINTERPFRAME(hier, i);
- sprintf(buf, "%6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %d %s",
- kf->q.imag.x, kf->q.imag.y, kf->q.imag.z, kf->q.real,
- kf->t.x, kf->t.y, kf->t.z,
- HIERNODEID(hier, i),
- ConvertBoneTag2BoneName(HIERNODEID(hier, i)));
- CDebug::PrintAt(buf, 10, 1+i*3);
+ int x, xstart, xmid, xend;
+ int y, ystart, ymid, yend;
+ CSector *s;
+ CPtrList *list;
- RwMatrix *m = &RpHAnimHierarchyGetMatrixArray(hier)[i];
- sprintf(buf, "%6.3f %6.3f %6.3f %6.3f",
- m->right.x, m->up.x, m->at.x, m->pos.x);
- CDebug::PrintAt(buf, 80, 1+i*3+0);
- sprintf(buf, "%6.3f %6.3f %6.3f %6.3f",
- m->right.y, m->up.y, m->at.y, m->pos.y);
- CDebug::PrintAt(buf, 80, 1+i*3+1);
- sprintf(buf, "%6.3f %6.3f %6.3f %6.3f",
- m->right.z, m->up.z, m->at.z, m->pos.z);
- CDebug::PrintAt(buf, 80, 1+i*3+2);
- }
+ CRect bounds = GetBoundRect();
+ xstart = CWorld::GetSectorIndexX(bounds.left);
+ xend = CWorld::GetSectorIndexX(bounds.right);
+ xmid = CWorld::GetSectorIndexX((bounds.left + bounds.right)/2.0f);
+ ystart = CWorld::GetSectorIndexY(bounds.top);
+ yend = CWorld::GetSectorIndexY(bounds.bottom);
+ ymid = CWorld::GetSectorIndexY((bounds.top + bounds.bottom)/2.0f);
+ assert(xstart >= 0);
+ assert(xend < NUMSECTORS_X);
+ assert(ystart >= 0);
+ assert(yend < NUMSECTORS_Y);
- void RenderSkeleton(RpHAnimHierarchy *hier);
- RenderSkeleton(hier);
-#endif
+ for(y = ystart; y <= yend; y++)
+ for(x = xstart; x <= xend; x++){
+ s = CWorld::GetSector(x, y);
+ if(x == xmid && y == ymid) switch(m_type){
+ case ENTITY_TYPE_BUILDING:
+ list = &s->m_lists[ENTITYLIST_BUILDINGS];
+ break;
+ case ENTITY_TYPE_VEHICLE:
+ list = &s->m_lists[ENTITYLIST_VEHICLES];
+ break;
+ case ENTITY_TYPE_PED:
+ list = &s->m_lists[ENTITYLIST_PEDS];
+ break;
+ case ENTITY_TYPE_OBJECT:
+ list = &s->m_lists[ENTITYLIST_OBJECTS];
+ break;
+ case ENTITY_TYPE_DUMMY:
+ list = &s->m_lists[ENTITYLIST_DUMMIES];
+ break;
+ }else switch(m_type){
+ case ENTITY_TYPE_BUILDING:
+ list = &s->m_lists[ENTITYLIST_BUILDINGS_OVERLAP];
+ break;
+ case ENTITY_TYPE_VEHICLE:
+ list = &s->m_lists[ENTITYLIST_VEHICLES_OVERLAP];
+ break;
+ case ENTITY_TYPE_PED:
+ list = &s->m_lists[ENTITYLIST_PEDS_OVERLAP];
+ break;
+ case ENTITY_TYPE_OBJECT:
+ list = &s->m_lists[ENTITYLIST_OBJECTS_OVERLAP];
+ break;
+ case ENTITY_TYPE_DUMMY:
+ list = &s->m_lists[ENTITYLIST_DUMMIES_OVERLAP];
+ break;
+ }
+ list->RemoveItem(this);
+ }
}
-#endif
-void
-CEntity::AddSteamsFromGround(CVector *unused)
+float
+CEntity::GetDistanceFromCentreOfMassToBaseOfModel(void)
{
- int i, n;
- C2dEffect *effect;
- CVector pos;
-
- n = CModelInfo::GetModelInfo(GetModelIndex())->GetNum2dEffects();
- for(i = 0; i < n; i++){
- effect = CModelInfo::GetModelInfo(GetModelIndex())->Get2dEffect(i);
- if(effect->type != EFFECT_PARTICLE)
- continue;
-
- pos = GetMatrix() * effect->pos;
- switch(effect->particle.particleType){
- case 0:
- CParticleObject::AddObject(POBJECT_PAVEMENT_STEAM, pos, effect->particle.dir, effect->particle.scale, false);
- break;
- case 1:
- CParticleObject::AddObject(POBJECT_WALL_STEAM, pos, effect->particle.dir, effect->particle.scale, false);
- break;
- case 2:
- CParticleObject::AddObject(POBJECT_DRY_ICE, pos, effect->particle.scale, false);
- break;
- case 3:
- CParticleObject::AddObject(POBJECT_SMALL_FIRE, pos, effect->particle.dir, effect->particle.scale, false);
- break;
- case 4:
- CParticleObject::AddObject(POBJECT_DARK_SMOKE, pos, effect->particle.dir, effect->particle.scale, false);
- break;
- }
- }
+ return -CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingBox.min.z;
}
void
-CEntity::ProcessLightsForEntity(void)
+CEntity::SetupBigBuilding(void)
{
- int i, n;
- C2dEffect *effect;
- CVector pos;
- bool lightOn, lightFlickering;
- uint32 flashTimer1, flashTimer2, flashTimer3;
-
- if(bRenderDamaged || !bIsVisible || GetUp().z < 0.96f)
- return;
-
- flashTimer1 = 0;
- flashTimer2 = 0;
- flashTimer3 = 0;
-
- n = CModelInfo::GetModelInfo(GetModelIndex())->GetNum2dEffects();
- for(i = 0; i < n; i++, flashTimer1 += 0x80, flashTimer2 += 0x100, flashTimer3 += 0x200){
- effect = CModelInfo::GetModelInfo(GetModelIndex())->Get2dEffect(i);
-
- if(effect->type != EFFECT_LIGHT)
- continue;
-
- pos = GetMatrix() * effect->pos;
-
- lightOn = false;
- lightFlickering = false;
- switch(effect->light.lightType){
- case LIGHT_ON:
- lightOn = true;
- break;
- case LIGHT_ON_NIGHT:
- if(CClock::GetHours() > 18 || CClock::GetHours() < 7)
- lightOn = true;
- break;
- case LIGHT_FLICKER:
- if((CTimer::GetTimeInMilliseconds() ^ m_randomSeed) & 0x60)
- lightOn = true;
- else
- lightFlickering = true;
- if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed) & 3)
- lightOn = true;
- break;
- case LIGHT_FLICKER_NIGHT:
- if(CClock::GetHours() > 18 || CClock::GetHours() < 7 || CWeather::WetRoads > 0.5f){
- if((CTimer::GetTimeInMilliseconds() ^ m_randomSeed) & 0x60)
- lightOn = true;
- else
- lightFlickering = true;
- if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed) & 3)
- lightOn = true;
- }
- break;
- case LIGHT_FLASH1:
- if((CTimer::GetTimeInMilliseconds() + flashTimer1) & 0x200)
- lightOn = true;
- break;
- case LIGHT_FLASH1_NIGHT:
- if(CClock::GetHours() > 18 || CClock::GetHours() < 7)
- if((CTimer::GetTimeInMilliseconds() + flashTimer1) & 0x200)
- lightOn = true;
- break;
- case LIGHT_FLASH2:
- if((CTimer::GetTimeInMilliseconds() + flashTimer2) & 0x400)
- lightOn = true;
- break;
- case LIGHT_FLASH2_NIGHT:
- if(CClock::GetHours() > 18 || CClock::GetHours() < 7)
- if((CTimer::GetTimeInMilliseconds() + flashTimer2) & 0x400)
- lightOn = true;
- break;
- case LIGHT_FLASH3:
- if((CTimer::GetTimeInMilliseconds() + flashTimer3) & 0x800)
- lightOn = true;
- break;
- case LIGHT_FLASH3_NIGHT:
- if(CClock::GetHours() > 18 || CClock::GetHours() < 7)
- if((CTimer::GetTimeInMilliseconds() + flashTimer3) & 0x800)
- lightOn = true;
- break;
- case LIGHT_RANDOM_FLICKER:
- if(m_randomSeed > 16)
- lightOn = true;
- else{
- if((CTimer::GetTimeInMilliseconds() ^ m_randomSeed*8) & 0x60)
- lightOn = true;
- else
- lightFlickering = true;
- if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed*8) & 3)
- lightOn = true;
- }
- break;
- case LIGHT_RANDOM_FLICKER_NIGHT:
- if(CClock::GetHours() > 18 || CClock::GetHours() < 7){
- if(m_randomSeed > 16)
- lightOn = true;
- else{
- if((CTimer::GetTimeInMilliseconds() ^ m_randomSeed*8) & 0x60)
- lightOn = true;
- else
- lightFlickering = true;
- if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed*8) & 3)
- lightOn = true;
- }
- }
- break;
- case LIGHT_BRIDGE_FLASH1:
- if(CBridge::ShouldLightsBeFlashing() && CTimer::GetTimeInMilliseconds() & 0x200)
- lightOn = true;
- break;
- case LIGHT_BRIDGE_FLASH2:
- if(CBridge::ShouldLightsBeFlashing() && (CTimer::GetTimeInMilliseconds() & 0x1FF) < 60)
- lightOn = true;
- break;
- }
-
- // Corona
- if(lightOn)
- CCoronas::RegisterCorona((uintptr)this + i,
- effect->col.r, effect->col.g, effect->col.b, 255,
- pos, effect->light.size, effect->light.dist,
- effect->light.corona, effect->light.flareType, effect->light.roadReflection,
- effect->light.flags&LIGHTFLAG_LOSCHECK, CCoronas::STREAK_OFF, 0.0f);
- else if(lightFlickering)
- CCoronas::RegisterCorona((uintptr)this + i,
- 0, 0, 0, 255,
- pos, effect->light.size, effect->light.dist,
- effect->light.corona, effect->light.flareType, effect->light.roadReflection,
- effect->light.flags&LIGHTFLAG_LOSCHECK, CCoronas::STREAK_OFF, 0.0f);
-
- // Pointlight
- if(effect->light.flags & LIGHTFLAG_FOG_ALWAYS){
- CPointLights::AddLight(CPointLights::LIGHT_FOGONLY_ALWAYS,
- pos, CVector(0.0f, 0.0f, 0.0f),
- effect->light.range,
- effect->col.r/255.0f, effect->col.g/255.0f, effect->col.b/255.0f,
- CPointLights::FOG_ALWAYS, true);
- }else if(effect->light.flags & LIGHTFLAG_FOG_NORMAL && lightOn && effect->light.range == 0.0f){
- CPointLights::AddLight(CPointLights::LIGHT_FOGONLY,
- pos, CVector(0.0f, 0.0f, 0.0f),
- effect->light.range,
- effect->col.r/255.0f, effect->col.g/255.0f, effect->col.b/255.0f,
- CPointLights::FOG_NORMAL, true);
- }else if(lightOn && effect->light.range != 0.0f){
- if(effect->col.r == 0 && effect->col.g == 0 && effect->col.b == 0){
- CPointLights::AddLight(CPointLights::LIGHT_POINT,
- pos, CVector(0.0f, 0.0f, 0.0f),
- effect->light.range,
- 0.0f, 0.0f, 0.0f,
- CPointLights::FOG_NONE, true);
- }else{
- CPointLights::AddLight(CPointLights::LIGHT_POINT,
- pos, CVector(0.0f, 0.0f, 0.0f),
- effect->light.range,
- effect->col.r*CTimeCycle::GetSpriteBrightness()/255.0f,
- effect->col.g*CTimeCycle::GetSpriteBrightness()/255.0f,
- effect->col.b*CTimeCycle::GetSpriteBrightness()/255.0f,
- // half-useless because LIGHTFLAG_FOG_ALWAYS can't be on
- (effect->light.flags & LIGHTFLAG_FOG) >> 1,
- true);
- }
- }
+ CSimpleModelInfo *mi;
- // Light shadow
- if(effect->light.shadowSize != 0.0f){
- if(lightOn){
- CShadows::StoreStaticShadow((uintptr)this + i, SHADOWTYPE_ADDITIVE,
- effect->light.shadow, &pos,
- effect->light.shadowSize, 0.0f,
- 0.0f, -effect->light.shadowSize,
- 128,
- effect->col.r*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f,
- effect->col.g*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f,
- effect->col.b*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f,
- 15.0f, 1.0f, 40.0f, false, 0.0f);
- }else if(lightFlickering){
- CShadows::StoreStaticShadow((uintptr)this + i, SHADOWTYPE_ADDITIVE,
- effect->light.shadow, &pos,
- effect->light.shadowSize, 0.0f,
- 0.0f, -effect->light.shadowSize,
- 0, 0.0f, 0.0f, 0.0f,
- 15.0f, 1.0f, 40.0f, false, 0.0f);
- }
+ mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(m_modelIndex);
+ bIsBIGBuilding = true;
+ 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->GetName());
}
}
+ if(mi->m_lodDistances[0] > 2000.0f)
+ m_level = LEVEL_GENERIC;
}
float WindTabel[] = {
@@ -917,14 +679,11 @@ CEntity::ModifyMatrixForBannerInWind(void)
UpdateRwFrame();
}
-void
-CEntity::AddSteamsFromGround(CPtrList& list)
+void
+CEntity::PreRenderForGlassWindow(void)
{
- CPtrNode *pNode = list.first;
- while (pNode) {
- ((CEntity*)pNode->item)->AddSteamsFromGround(nil);
- pNode = pNode->next;
- }
+ CGlass::AskForObjectToBeRenderedInGlass(this);
+ bIsVisible = false;
}
#ifdef COMPATIBLE_SAVES
diff --git a/src/entities/Entity.h b/src/entities/Entity.h
index 9372c85d..7ee638d7 100644
--- a/src/entities/Entity.h
+++ b/src/entities/Entity.h
@@ -111,8 +111,8 @@ public:
virtual void Add(void);
virtual void Remove(void);
- virtual void SetModelIndex(uint32 id) { m_modelIndex = id; CreateRwObject(); }
- virtual void SetModelIndexNoCreate(uint32 id) { m_modelIndex = id; }
+ virtual void SetModelIndex(uint32 id);
+ virtual void SetModelIndexNoCreate(uint32 id);
virtual void CreateRwObject(void);
virtual void DeleteRwObject(void);
virtual CRect GetBoundRect(void);
@@ -123,7 +123,7 @@ public:
virtual void PreRender(void);
virtual void Render(void);
virtual bool SetupLighting(void);
- virtual void RemoveLighting(bool) {}
+ virtual void RemoveLighting(bool);
virtual void FlagToDestroyWhenNextProcessed(void) {}
bool IsBuilding(void) { return m_type == ENTITY_TYPE_BUILDING; }
@@ -142,14 +142,14 @@ public:
}
void GetBoundCentre(CVector &out);
- CVector GetBoundCentre(void) { CVector v; GetBoundCentre(v); return v; }
- float GetBoundRadius(void) { return CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingSphere.radius; }
- float GetDistanceFromCentreOfMassToBaseOfModel(void) { return -CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingBox.min.z; }
+ CVector GetBoundCentre(void);
+ float GetBoundRadius(void);
+ float GetDistanceFromCentreOfMassToBaseOfModel(void);
bool GetIsTouching(CVector const &center, float r);
bool GetIsOnScreen(void);
bool GetIsOnScreenComplex(void);
- bool IsVisible(void) { return m_rwObject && bIsVisible && GetIsOnScreen(); }
- bool IsVisibleComplex(void) { return m_rwObject && bIsVisible && GetIsOnScreenComplex(); }
+ bool IsVisible(void);
+ bool IsVisibleComplex(void);
int16 GetModelIndex(void) const { return m_modelIndex; }
void UpdateRwFrame(void);
void SetupBigBuilding(void);
@@ -170,8 +170,6 @@ public:
void ModifyMatrixForTreeInWind(void);
void ModifyMatrixForBannerInWind(void);
void ProcessLightsForEntity(void);
-
- static void AddSteamsFromGround(CPtrList& list);
};
VALIDATE_SIZE(CEntity, 0x64);
diff --git a/src/render/Coronas.cpp b/src/render/Coronas.cpp
index 48f0f6b9..32957259 100644
--- a/src/render/Coronas.cpp
+++ b/src/render/Coronas.cpp
@@ -2,6 +2,7 @@
#include "main.h"
#include "General.h"
+#include "Entity.h"
#include "TxdStore.h"
#include "Camera.h"
#include "Sprite.h"
@@ -11,6 +12,10 @@
#include "Collision.h"
#include "Timecycle.h"
#include "Coronas.h"
+#include "PointLights.h"
+#include "Shadows.h"
+#include "Clock.h"
+#include "Bridge.h"
struct FlareDef
{
@@ -577,3 +582,190 @@ CRegisteredCorona::Update(void)
firstUpdate = false;
registeredThisFrame = false;
}
+
+void
+CEntity::ProcessLightsForEntity(void)
+{
+ int i, n;
+ C2dEffect *effect;
+ CVector pos;
+ bool lightOn, lightFlickering;
+ uint32 flashTimer1, flashTimer2, flashTimer3;
+
+ if(bRenderDamaged || !bIsVisible || GetUp().z < 0.96f)
+ return;
+
+ flashTimer1 = 0;
+ flashTimer2 = 0;
+ flashTimer3 = 0;
+
+ n = CModelInfo::GetModelInfo(GetModelIndex())->GetNum2dEffects();
+ for(i = 0; i < n; i++, flashTimer1 += 0x80, flashTimer2 += 0x100, flashTimer3 += 0x200){
+ effect = CModelInfo::GetModelInfo(GetModelIndex())->Get2dEffect(i);
+
+ if(effect->type != EFFECT_LIGHT)
+ continue;
+
+ pos = GetMatrix() * effect->pos;
+
+ lightOn = false;
+ lightFlickering = false;
+ switch(effect->light.lightType){
+ case LIGHT_ON:
+ lightOn = true;
+ break;
+ case LIGHT_ON_NIGHT:
+ if(CClock::GetHours() > 18 || CClock::GetHours() < 7)
+ lightOn = true;
+ break;
+ case LIGHT_FLICKER:
+ if((CTimer::GetTimeInMilliseconds() ^ m_randomSeed) & 0x60)
+ lightOn = true;
+ else
+ lightFlickering = true;
+ if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed) & 3)
+ lightOn = true;
+ break;
+ case LIGHT_FLICKER_NIGHT:
+ if(CClock::GetHours() > 18 || CClock::GetHours() < 7 || CWeather::WetRoads > 0.5f){
+ if((CTimer::GetTimeInMilliseconds() ^ m_randomSeed) & 0x60)
+ lightOn = true;
+ else
+ lightFlickering = true;
+ if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed) & 3)
+ lightOn = true;
+ }
+ break;
+ case LIGHT_FLASH1:
+ if((CTimer::GetTimeInMilliseconds() + flashTimer1) & 0x200)
+ lightOn = true;
+ break;
+ case LIGHT_FLASH1_NIGHT:
+ if(CClock::GetHours() > 18 || CClock::GetHours() < 7)
+ if((CTimer::GetTimeInMilliseconds() + flashTimer1) & 0x200)
+ lightOn = true;
+ break;
+ case LIGHT_FLASH2:
+ if((CTimer::GetTimeInMilliseconds() + flashTimer2) & 0x400)
+ lightOn = true;
+ break;
+ case LIGHT_FLASH2_NIGHT:
+ if(CClock::GetHours() > 18 || CClock::GetHours() < 7)
+ if((CTimer::GetTimeInMilliseconds() + flashTimer2) & 0x400)
+ lightOn = true;
+ break;
+ case LIGHT_FLASH3:
+ if((CTimer::GetTimeInMilliseconds() + flashTimer3) & 0x800)
+ lightOn = true;
+ break;
+ case LIGHT_FLASH3_NIGHT:
+ if(CClock::GetHours() > 18 || CClock::GetHours() < 7)
+ if((CTimer::GetTimeInMilliseconds() + flashTimer3) & 0x800)
+ lightOn = true;
+ break;
+ case LIGHT_RANDOM_FLICKER:
+ if(m_randomSeed > 16)
+ lightOn = true;
+ else{
+ if((CTimer::GetTimeInMilliseconds() ^ m_randomSeed*8) & 0x60)
+ lightOn = true;
+ else
+ lightFlickering = true;
+ if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed*8) & 3)
+ lightOn = true;
+ }
+ break;
+ case LIGHT_RANDOM_FLICKER_NIGHT:
+ if(CClock::GetHours() > 18 || CClock::GetHours() < 7){
+ if(m_randomSeed > 16)
+ lightOn = true;
+ else{
+ if((CTimer::GetTimeInMilliseconds() ^ m_randomSeed*8) & 0x60)
+ lightOn = true;
+ else
+ lightFlickering = true;
+ if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed*8) & 3)
+ lightOn = true;
+ }
+ }
+ break;
+ case LIGHT_BRIDGE_FLASH1:
+ if(CBridge::ShouldLightsBeFlashing() && CTimer::GetTimeInMilliseconds() & 0x200)
+ lightOn = true;
+ break;
+ case LIGHT_BRIDGE_FLASH2:
+ if(CBridge::ShouldLightsBeFlashing() && (CTimer::GetTimeInMilliseconds() & 0x1FF) < 60)
+ lightOn = true;
+ break;
+ }
+
+ // Corona
+ if(lightOn)
+ CCoronas::RegisterCorona((uintptr)this + i,
+ effect->col.r, effect->col.g, effect->col.b, 255,
+ pos, effect->light.size, effect->light.dist,
+ effect->light.corona, effect->light.flareType, effect->light.roadReflection,
+ effect->light.flags&LIGHTFLAG_LOSCHECK, CCoronas::STREAK_OFF, 0.0f);
+ else if(lightFlickering)
+ CCoronas::RegisterCorona((uintptr)this + i,
+ 0, 0, 0, 255,
+ pos, effect->light.size, effect->light.dist,
+ effect->light.corona, effect->light.flareType, effect->light.roadReflection,
+ effect->light.flags&LIGHTFLAG_LOSCHECK, CCoronas::STREAK_OFF, 0.0f);
+
+ // Pointlight
+ if(effect->light.flags & LIGHTFLAG_FOG_ALWAYS){
+ CPointLights::AddLight(CPointLights::LIGHT_FOGONLY_ALWAYS,
+ pos, CVector(0.0f, 0.0f, 0.0f),
+ effect->light.range,
+ effect->col.r/255.0f, effect->col.g/255.0f, effect->col.b/255.0f,
+ CPointLights::FOG_ALWAYS, true);
+ }else if(effect->light.flags & LIGHTFLAG_FOG_NORMAL && lightOn && effect->light.range == 0.0f){
+ CPointLights::AddLight(CPointLights::LIGHT_FOGONLY,
+ pos, CVector(0.0f, 0.0f, 0.0f),
+ effect->light.range,
+ effect->col.r/255.0f, effect->col.g/255.0f, effect->col.b/255.0f,
+ CPointLights::FOG_NORMAL, true);
+ }else if(lightOn && effect->light.range != 0.0f){
+ if(effect->col.r == 0 && effect->col.g == 0 && effect->col.b == 0){
+ CPointLights::AddLight(CPointLights::LIGHT_POINT,
+ pos, CVector(0.0f, 0.0f, 0.0f),
+ effect->light.range,
+ 0.0f, 0.0f, 0.0f,
+ CPointLights::FOG_NONE, true);
+ }else{
+ CPointLights::AddLight(CPointLights::LIGHT_POINT,
+ pos, CVector(0.0f, 0.0f, 0.0f),
+ effect->light.range,
+ effect->col.r*CTimeCycle::GetSpriteBrightness()/255.0f,
+ effect->col.g*CTimeCycle::GetSpriteBrightness()/255.0f,
+ effect->col.b*CTimeCycle::GetSpriteBrightness()/255.0f,
+ // half-useless because LIGHTFLAG_FOG_ALWAYS can't be on
+ (effect->light.flags & LIGHTFLAG_FOG) >> 1,
+ true);
+ }
+ }
+
+ // Light shadow
+ if(effect->light.shadowSize != 0.0f){
+ if(lightOn){
+ CShadows::StoreStaticShadow((uintptr)this + i, SHADOWTYPE_ADDITIVE,
+ effect->light.shadow, &pos,
+ effect->light.shadowSize, 0.0f,
+ 0.0f, -effect->light.shadowSize,
+ 128,
+ effect->col.r*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f,
+ effect->col.g*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f,
+ effect->col.b*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f,
+ 15.0f, 1.0f, 40.0f, false, 0.0f);
+ }else if(lightFlickering){
+ CShadows::StoreStaticShadow((uintptr)this + i, SHADOWTYPE_ADDITIVE,
+ effect->light.shadow, &pos,
+ effect->light.shadowSize, 0.0f,
+ 0.0f, -effect->light.shadowSize,
+ 0, 0.0f, 0.0f, 0.0f,
+ 15.0f, 1.0f, 40.0f, false, 0.0f);
+ }
+ }
+ }
+}
diff --git a/src/render/Particle.cpp b/src/render/Particle.cpp
index 844b6acd..08137d0c 100644
--- a/src/render/Particle.cpp
+++ b/src/render/Particle.cpp
@@ -3,6 +3,7 @@
#include "General.h"
#include "Timer.h"
#include "TxdStore.h"
+#include "Entity.h"
#include "Sprite.h"
#include "Camera.h"
#include "Collision.h"
@@ -585,6 +586,40 @@ void CParticle::Initialise()
debug("CParticle ready");
}
+void
+CEntity::AddSteamsFromGround(CVector *unused)
+{
+ int i, n;
+ C2dEffect *effect;
+ CVector pos;
+
+ n = CModelInfo::GetModelInfo(GetModelIndex())->GetNum2dEffects();
+ for(i = 0; i < n; i++){
+ effect = CModelInfo::GetModelInfo(GetModelIndex())->Get2dEffect(i);
+ if(effect->type != EFFECT_PARTICLE)
+ continue;
+
+ pos = GetMatrix() * effect->pos;
+ switch(effect->particle.particleType){
+ case 0:
+ CParticleObject::AddObject(POBJECT_PAVEMENT_STEAM, pos, effect->particle.dir, effect->particle.scale, false);
+ break;
+ case 1:
+ CParticleObject::AddObject(POBJECT_WALL_STEAM, pos, effect->particle.dir, effect->particle.scale, false);
+ break;
+ case 2:
+ CParticleObject::AddObject(POBJECT_DRY_ICE, pos, effect->particle.scale, false);
+ break;
+ case 3:
+ CParticleObject::AddObject(POBJECT_SMALL_FIRE, pos, effect->particle.dir, effect->particle.scale, false);
+ break;
+ case 4:
+ CParticleObject::AddObject(POBJECT_DARK_SMOKE, pos, effect->particle.dir, effect->particle.scale, false);
+ break;
+ }
+ }
+}
+
void CParticle::Shutdown()
{
debug("Shutting down CParticle...");
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index d47cac31..2559b743 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -921,6 +921,19 @@ CRenderer::RequestObjectsInFrustum(void)
}
bool
+CEntity::SetupLighting(void)
+{
+ DeActivateDirectional();
+ SetAmbientColours();
+ return false;
+}
+
+void
+CEntity::RemoveLighting(bool)
+{
+}
+
+bool
CPed::SetupLighting(void)
{
ActivateDirectional();
diff --git a/src/rw/RwHelper.cpp b/src/rw/RwHelper.cpp
index e0133985..4ee3a0b3 100644
--- a/src/rw/RwHelper.cpp
+++ b/src/rw/RwHelper.cpp
@@ -324,26 +324,6 @@ HAnimAnimationCreateForHierarchy(RpHAnimHierarchy *hier)
return anim;
}
-RpAtomic*
-AtomicRemoveAnimFromSkinCB(RpAtomic *atomic, void *data)
-{
- if(RpSkinGeometryGetSkin(RpAtomicGetGeometry(atomic))){
- RpHAnimHierarchy *hier = RpSkinAtomicGetHAnimHierarchy(atomic);
-#ifdef LIBRW
- if(hier && hier->interpolator->currentAnim){
- RpHAnimAnimationDestroy(hier->interpolator->currentAnim);
- hier->interpolator->currentAnim = nil;
- }
-#else
- if(hier && hier->pCurrentAnim){
- RpHAnimAnimationDestroy(hier->pCurrentAnim);
- hier->pCurrentAnim = nil;
- }
-#endif
- }
- return atomic;
-}
-
void
RenderSkeleton(RpHAnimHierarchy *hier)
{