void BgLoader::CloneFactory(const char* name, const char* newName, bool load, bool* failed) { // Find meshfact to clone. csRef<MeshFact> meshfact = meshfacts.Get(mfStringSet.Request(name), csRef<MeshFact>()); { if(!failed) { // Validation. csString msg; msg.Format("Invalid factory reference '%s' passed for cloning.", name); CS_ASSERT_MSG(msg.GetData(), meshfact.IsValid()); } else if(!meshfact.IsValid()) { *failed = true; return; } } // Create a clone. csRef<MeshFact> newMeshFact = meshfact->Clone(newName); meshfacts.Put(mfStringSet.Request(newName), newMeshFact); // Optionally begin loading. if(load) { LoadMeshFact(newMeshFact); } }
csPtr<iMaterialWrapper> BgLoader::LoadMaterial(const char* name, bool* failed, bool wait) { csRef<Material> material = materials.Get(mStringSet.Request(name), csRef<Material>()); { if(!failed) { // Validation. csString msg; msg.Format("Invalid material reference '%s'", name); CS_ASSERT_MSG(msg.GetData(), material.IsValid()); } else if(!material.IsValid()) { *failed = true; return csPtr<iMaterialWrapper>(0); } } if(LoadMaterial(material, wait)) { return csPtr<iMaterialWrapper>(material->mat); } return csPtr<iMaterialWrapper>(0); }
void psEntityLabels::OnObjectArrived( GEMClientObject* object ) { CS_ASSERT_MSG("Effects Manager must exist before loading entity labels!", psengine->GetEffectManager() ); if(MatchVisibility(object->GetObjectType(), LABEL_NEVER)) return; // The controlled character never shows a label. if (object == celClient->GetMainPlayer()) return; if(object->GetEntityLabel()) { RepaintObjectLabel( object ); } else { CreateLabelOfObject( object ); //TODO: check this code it seems it doesn't check precisely the status // of the label configuration if (visCreatures == LABEL_ONMOUSE || visItems == LABEL_ONMOUSE) { psPoint mouse = PawsManager::GetSingleton().GetMouse()->GetPosition(); GEMClientObject *um = psengine->GetMainWidget()->FindMouseOverObject(mouse.x, mouse.y); if( um != object ) { ShowLabelOfObject(object, false); } } } }
bool celHNavStructBuilder::ParseGraph (iDocumentNode* node, iCelGraph* graph, csHash<csRef<iSector>, const char*> sectors) { csRef<iDocumentNode> nodesNode = node->GetNode("nodes"); csRef<iDocumentNodeIterator> it = nodesNode->GetNodes("node"); size_t nodeCount = it->GetEndPosition(); csArray<csRef<iCelNode> > celNodes(nodeCount); celNodes.SetSize(nodeCount); while (it->HasNext()) { csRef<iDocumentNode> graphNode = it->Next(); size_t id = graphNode->GetAttributeValueAsInt("id"); // Get sector const char* sectorName = graphNode->GetAttributeValue("sector"); csRef<iSector> sector = sectors.Get(sectorName, 0); if(!sector.IsValid()) { csString msg; msg.Format("invalid sector %s in navmesh graph node\n", sectorName); CS_ASSERT_MSG(msg.GetData(),false); } // Get position csVector3 position; float x = graphNode->GetAttributeValueAsFloat("x"); float y = graphNode->GetAttributeValueAsFloat("y"); float z = graphNode->GetAttributeValueAsFloat("z"); position.Set(x, y, z); // Crete node csRef<iCelNode> node = graph->CreateEmptyNode(id); celNodes[id] = node; csRef<iMapNode> mapNode; mapNode.AttachNew(new csMapNode("n")); mapNode->SetPosition(position); mapNode->SetSector(sector); node->SetMapNode(mapNode); } csRef<iDocumentNode> edgesNode = node->GetNode("edges"); it = edgesNode->GetNodes("edge"); while (it->HasNext()) { csRef<iDocumentNode> graphEdge = it->Next(); int from = graphEdge->GetAttributeValueAsInt("from"); int to = graphEdge->GetAttributeValueAsInt("to"); float weight = graphEdge->GetAttributeValueAsFloat("weight"); celNodes[from]->AddSuccessor(celNodes[to], true, weight); } return true; }
csPtr<iMeshFactoryWrapper> BgLoader::LoadFactory(const char* name, bool* failed, bool wait) { csRef<MeshFact> meshfact = meshfacts.Get(mfStringSet.Request(name), csRef<MeshFact>()); { if(!failed) { // Validation. csString msg; msg.Format("Invalid factory reference '%s'", name); CS_ASSERT_MSG(msg.GetData(), meshfact.IsValid()); } else if(!meshfact.IsValid()) { *failed = true; return csPtr<iMeshFactoryWrapper>(0); } } if(LoadMeshFact(meshfact, wait)) { if(!failed) { // Check success. csString msg; msg.Format("Failed to load factory '%s' path: %s filename: %s", name, (const char*) meshfact->path, (const char*) meshfact->filename); CS_ASSERT_MSG(msg.GetData(), meshfact->status->WasSuccessful()); } else if(!meshfact->status->WasSuccessful()) { *failed = true; return csPtr<iMeshFactoryWrapper>(0); } return scfQueryInterfaceSafe<iMeshFactoryWrapper>(meshfact->status->GetResultRefPtr()); } return csPtr<iMeshFactoryWrapper>(0); }
bool Client::Initialize(LPSOCKADDR_IN addr, uint32_t clientnum) { Client::addr=*addr; CS_ASSERT_MSG("Unexpected size for IP address structure!", sizeof(addr->sin_addr.s_addr) + sizeof(addr->sin_port) == 6); Client::clientnum=clientnum; Client::valid=true; outqueue = csPtr<NetPacketQueueRefCount> (new NetPacketQueueRefCount (MAXCLIENTQUEUESIZE)); if (!outqueue) ERRORHALT("No Memory!"); return true; }
bool dbRecord::Execute(uint32 uid) { SetID(uid); CS_ASSERT_MSG("Error: wrong number of expected fields", index == count); if(!prepared) Prepare(); psStopWatch timer; timer.Start(); CS_ASSERT(count != index); csStringArray paramStrings; const char *paramValues[index]; for(unsigned int i = 0; i < index; i++) { csString value; switch(temp[i].type) { case SQL_TYPE_FLOAT: value.Format("%f", temp[i].fValue); break; case SQL_TYPE_INT: value.Format("%i", temp[i].iValue); break; case SQL_TYPE_STRING: value = temp[i].sValue; break; case SQL_TYPE_NULL: break; } paramStrings.Push(value); paramValues[i] = paramStrings.Get(i); } PGresult *res = PQexecPrepared(conn, stmt.GetData(), index, paramValues, NULL, NULL,0); bool result = (res && PQresultStatus(res) != PGRES_FATAL_ERROR); if(result && timer.Stop() > 1000) { csString status; status.Format("SQL query in file %s line %d, has taken %u time to process.\n", file, line, timer.Stop()); if(logcsv) logcsv->Write(CSV_STATUS, status); } return result; }
CS::ShaderVarStringID csLightShaderVarCache::GetLightSVId (LightProperty prop) { if (!strings.IsValid ()) return CS::InvalidShaderVarStringID; if (lightSVIdCache_unnumbered[prop] == csInvalidStringID) { CS_ASSERT_MSG ( "You added stuff to csLightShaderVarCache::LightProperty " "but didn't update " __FILE__, svSuffixes[prop] != 0); csString str; str.Format ("light %s", svSuffixes[prop]); lightSVIdCache_unnumbered[prop] = strings->Request (str); } return lightSVIdCache_unnumbered[prop]; }
CS::ShaderVarStringID csLightShaderVarCache::GetDefaultSVId (DefaultSV var) { static const char* const svNames[_varCount] = { "light ambient", "light count" }; if (!strings.IsValid ()) return CS::InvalidShaderVarStringID; if (defaultVars[var] == csInvalidStringID) { CS_ASSERT_MSG ( "You added stuff to csLightShaderVarCache::DefaultSV " "but didn't update " __FILE__, svNames[var] != 0); defaultVars[var] = strings->Request (svNames[var]); } return defaultVars[var]; }
bool celHNavStructBuilder::ParseMeshes (iDocumentNode* node, csHash<csRef<iSector>, const char*>& sectors, celHNavStruct* navStruct, iVFS* vfs, iCelNavMeshParams* params) { csRef<iEngine> engine = csLoadPluginCheck<iEngine>(objectRegistry, "crystalspace.engine.3d"); if (!engine) { return false; } csRef<iDocumentNodeIterator> it = node->GetNodes("navmesh"); while (it->HasNext()) { csRef<iDocumentNode> navMeshNode = it->Next(); // Get sector const char* sectorName = navMeshNode->GetAttributeValue("sector"); csString sectorNameString(sectorName); if(!sectors.In(sectorName)) { iSector* sector = engine->FindSector(sectorName); if(sector) { sectors.Put(sectorName, sector); } else { csString msg; msg.Format("invalid sector %s in navmesh\n", sectorName); CS_ASSERT_MSG(msg.GetData(),false); } } // Get navmesh int id = navMeshNode->GetAttributeValueAsInt("id"); csString fileName; fileName = id; csRef<iFile> file = vfs->Open(fileName.GetDataSafe(), VFS_FILE_READ); csRef<iCelNavMeshBuilder> builder = csLoadPluginCheck<iCelNavMeshBuilder>(objectRegistry, "cel.navmeshbuilder"); csRef<iCelNavMesh> navMesh = builder->LoadNavMesh(file); navStruct->AddNavMesh(navMesh); } return true; }
bool BgLoader::InWaterArea(const char* sector, csVector3* pos, csColor4** colour) { // Hack to work around the weird sector stuff we do. if(!strcmp("SectorWhereWeKeepEntitiesResidingInUnloadedMaps", sector)) return false; csRef<Sector> s = sectorHash.Get(sStringSet.Request(sector), csRef<Sector>()); CS_ASSERT_MSG("Invalid sector passed to InWaterArea().", s.IsValid()); for(size_t i=0; i<s->waterareas.GetSize(); ++i) { if(s->waterareas[i]->bbox.In(*pos)) { *colour = &s->waterareas[i]->colour; return true; } } return false; }
const char* csConditionEvaluator::ResolveSVIdentifier ( csExpression* expression, CondOperand& operand) { if (expression->type == csExpression::Value) { csExpressionToken::Extractor svIdentifier (expression->valueValue); CS::Graphics::ShaderVarNameParser svParser (svIdentifier.Get()); operand.type = operandSV; operand.svLocation.svName = strings->Request (svParser.GetShaderVarName()); operand.svLocation.indices = AllocSVIndicesInternal (svParser); return 0; } else { const csExpressionToken& t = expression->expressionValue.op; if (!TokenEquals (t.tokenStart, t.tokenLen, ".")) { return SetLastError ("Unexpected operator '%s'", csExpressionToken::Extractor (t).Get ()); } if (expression->expressionValue.left->type != csExpression::Value) { CS_ASSERT_MSG ("It should not happen that the 'left' subexpression " "is not a value", false); return "Left subexpression is not of type 'value'"; } if (expression->expressionValue.right->type != csExpression::Value) { /* @@@ Happens for stuff like vars.foo.bar.baz, where bar.baz * will incarnate here as a right expression of type Expression. * Clearer error msg? */ return "Right subexpression is not of type 'value'"; } { csExpressionToken::Extractor svIdentifier (expression->expressionValue.left->valueValue); CS::Graphics::ShaderVarNameParser svParser (svIdentifier.Get()); operand.type = operandSV; operand.svLocation.svName = strings->Request (svParser.GetShaderVarName()); operand.svLocation.indices = AllocSVIndicesInternal (svParser); operand.svLocation.bufferName = csRenderBuffer::GetBufferNameFromDescr ( svParser.GetShaderVarName()); } const csExpressionToken& right = expression->expressionValue.right->valueValue; if (TokenEquals (right.tokenStart, right.tokenLen, "int")) { operand.type = operandSVValueInt; } else if (TokenEquals (right.tokenStart, right.tokenLen, "float")) { operand.type = operandSVValueFloat; } else if (TokenEquals (right.tokenStart, right.tokenLen, "x")) { operand.type = operandSVValueX; } else if (TokenEquals (right.tokenStart, right.tokenLen, "y")) { operand.type = operandSVValueY; } else if (TokenEquals (right.tokenStart, right.tokenLen, "z")) { operand.type = operandSVValueZ; } else if (TokenEquals (right.tokenStart, right.tokenLen, "w")) { operand.type = operandSVValueW; } else if (TokenEquals (right.tokenStart, right.tokenLen, "buffer")) { operand.type = operandSVValueBuffer; } else if (TokenEquals (right.tokenStart, right.tokenLen, "texture")) { operand.type = operandSVValueTexture; } else { return SetLastError ("Unknown shader variable specializer '%s'", csExpressionToken::Extractor (right).Get ()); } return 0; } CS_ASSERT (false); return 0; }
PID EntityManager::GetMasterFamiliarID(psCharacter *charData) { csHash< csHash< size_t, csString > *, csString > charAttributes; csHash< size_t, csString > *charAttributeList; size_t typeValue = 0, lifecycleValue = 0, attacktoolValue = 0, attacktypeValue = 0; int rank = 0; int currentRank = -1; psFamiliarType *currentFT = NULL; csHash<psFamiliarType*, PID>::GlobalIterator ftIter = familiarTypeList.GetIterator(); psFamiliarType *ft = NULL; // Get Familiar Affinity csString animalAffinity = charData->GetAnimalAffinity(); if ( animalAffinity.Length() == 0 ) { // No animal affinity data was found // just use a random number to grab the familiar type id size_t maxValue = familiarTypeList.GetSize(); size_t pick = psserver->rng->Get( (uint32)maxValue ) + 1; size_t count = 0; while ( count++ < pick && ftIter.HasNext() ) { ft = (psFamiliarType *)ftIter.Next(); } return ft->Id; } // Parse the string into an XML document. csRef<iDocument> xmlDoc = ParseString( animalAffinity ); if(!xmlDoc.IsValid()) { csString msg("Error parsing animal affinity for character "); msg.AppendFmt("%s!\n", charData->fullname.GetData()); CS_ASSERT_MSG(msg.GetData(), xmlDoc.IsValid()); } // Find existing nodes csRef<iDocumentNodeIterator> iter = xmlDoc->GetRoot()->GetNodes(); csRef<iDocumentNode> node; while ( iter->HasNext() ) { node = iter->Next(); csString attribute = csString( node->GetAttributeValue( "attribute" ) ).Downcase(); csString name = csString( node->GetAttributeValue( "name" ) ).Downcase(); size_t value = (size_t)node->GetAttributeValueAsInt( "value" ); if ( attribute.Length() != 0 && name.Length() != 0 ) { charAttributeList = charAttributes.Get( attribute, NULL ); if ( charAttributeList == NULL ) { charAttributeList = new csHash< size_t, csString >(); charAttributes.Put( attribute, charAttributeList ); } charAttributeList->Put( name, value ); } } // For each entry in familiar_definitions while ( ftIter.HasNext() ) { typeValue = lifecycleValue = attacktoolValue = attacktypeValue = 0; // Calculate affinity for all matching attribute categories psFamiliarType *ft = (psFamiliarType *)ftIter.Next(); csHash< size_t, csString > *attribute; attribute = charAttributes.Get( "type", NULL); if ( attribute != NULL ) { typeValue = attribute->Get( ft->Type,0 ); } attribute = charAttributes.Get( "lifecycle", NULL ); if ( attribute != NULL ) { lifecycleValue = attribute->Get( ft->Lifecycle, 0 ); } attribute = charAttributes.Get( "attacktool", NULL ); if ( attribute != NULL ) { attacktoolValue = attribute->Get( ft->AttackTool, 0 ); } attribute = charAttributes.Get( "attacktype", NULL ); if ( attribute != NULL ) { attacktypeValue = attribute->Get( ft->AttackType, 0 ); } rank = CalculateFamiliarAffinity( charData, typeValue, lifecycleValue, attacktoolValue, attacktypeValue ); if ( rank > currentRank ) { currentRank = rank; currentFT = ft; } } // highest value affinity is used as masterId charAttributes.DeleteAll(); if ( currentFT ) return currentFT->Id; else return 0; }
void BgLoader::CleanSector(Sector* sector) { if(!sector->object.IsValid()) return; for(size_t i=0; i<sector->meshes.GetSize(); i++) { if(sector->meshes[i]->object.IsValid()) { sector->meshes[i]->object->GetMovable()->ClearSectors(); sector->meshes[i]->object->GetMovable()->UpdateMove(); engine->GetMeshes()->Remove(sector->meshes[i]->object); sector->meshes[i]->object.Invalidate(); CleanMesh(sector->meshes[i]); --(sector->objectCount); } } for(size_t i=0; i<sector->meshgen.GetSize(); i++) { CleanMeshGen(sector->meshgen[i]); --(sector->objectCount); } for(size_t i=0; i<sector->portals.GetSize(); i++) { if(sector->portals[i]->mObject.IsValid()) { engine->GetMeshes()->Remove(sector->portals[i]->mObject); sector->portals[i]->pObject = NULL; sector->portals[i]->mObject.Invalidate(); sector->activePortals.Delete(sector->portals[i]); --(sector->objectCount); } } for(size_t i=0; i<sector->lights.GetSize(); i++) { if(sector->lights[i]->object.IsValid()) { engine->RemoveLight(sector->lights[i]->object); sector->lights[i]->object.Invalidate(); --(sector->objectCount); } for(size_t j=0; j<sector->lights[i]->sequences.GetSize(); ++j) { if(sector->lights[i]->sequences[j]->status.IsValid()) { for(size_t k=0; k<sector->lights[i]->sequences[j]->triggers.GetSize(); ++k) { if(sector->lights[i]->sequences[j]->triggers[k]->status.IsValid()) { csRef<iSequenceTrigger> st = scfQueryInterface<iSequenceTrigger>(sector->lights[i]->sequences[j]->triggers[k]->status->GetResultRefPtr()); engseq->RemoveTrigger(st); sector->lights[i]->sequences[j]->triggers[k]->status.Invalidate(); } } csRef<iSequenceWrapper> sw = scfQueryInterface<iSequenceWrapper>(sector->lights[i]->sequences[j]->status->GetResultRefPtr()); engseq->RemoveSequence(sw); sector->lights[i]->sequences[j]->status.Invalidate(); } } } // Unload all 'always loaded' meshes before destroying sector. if(sector->objectCount != 0) { for(size_t i=0; i<sector->alwaysLoaded.GetSize(); i++) { sector->alwaysLoaded[i]->object->GetMovable()->ClearSectors(); sector->alwaysLoaded[i]->object->GetMovable()->UpdateMove(); engine->GetMeshes()->Remove(sector->alwaysLoaded[i]->object); sector->alwaysLoaded[i]->object.Invalidate(); CleanMesh(sector->alwaysLoaded[i]); --(sector->objectCount); } } // Remove sequences. for(size_t i=0; i<sector->sequences.GetSize(); ++i) { if(sector->sequences[i]->status.IsValid()) { csRef<iSequenceWrapper> sw = scfQueryInterface<iSequenceWrapper>(sector->sequences[i]->status->GetResultRefPtr()); engseq->RemoveSequence(sw); sector->sequences[i]->status.Invalidate(); } } if(sector->objectCount != 0) { csString msg; msg.Format("Error cleaning sector. Sector still has %zu objects!", sector->objectCount); CS_ASSERT_MSG(msg.GetData(), false); } CS_ASSERT_MSG("Error cleaning sector. Sector is invalid!", sector->object.IsValid()); // Remove the sector from the engine. sector->checked = false; sector->object->QueryObject()->SetObjectParent(0); engine->GetSectors()->Remove(sector->object); sector->object.Invalidate(); }
void NetManager::Broadcast(MsgEntry *me, int scope, int guildID) { switch (scope) { case NetBase::BC_EVERYONE: case NetBase::BC_EVERYONEBUTSELF: { // send the message to each client (except perhaps the client that originated it) uint32_t originalclient = me->clientnum; // Copy message to send out to everyone csRef<MsgEntry> newmsg; newmsg.AttachNew(new MsgEntry(me)); newmsg->msgid = GetRandomID(); // Message is copied again into packet sections, so we can reuse same one. ClientIterator i(clients); while(i.HasNext()) { Client *p = i.Next(); if (scope==NetBase::BC_EVERYONEBUTSELF && p->GetClientNum() == originalclient) continue; // send to superclient only the messages he needs if (p->IsSuperClient()) { // time of the day is needed if (me->GetType()!=MSGTYPE_WEATHER) continue; } // Only clients that finished connecting get broadcastet // stuff if (!p->IsReady()) continue; newmsg->clientnum = p->GetClientNum(); SendMessage (newmsg); } CHECK_FINAL_DECREF(newmsg, "BroadcastMsg"); break; } // TODO: NetBase::BC_GROUP case NetBase::BC_GUILD: { CS_ASSERT_MSG("NetBase::BC_GUILD broadcast must specify guild ID", guildID != -1 ); /** * Send the message to each client with the same guildID */ // Copy message to send out to everyone csRef<MsgEntry> newmsg; newmsg.AttachNew(new MsgEntry(me)); newmsg->msgid = GetRandomID(); // Message is copied again into packet sections, so we can reuse same one. ClientIterator i(clients); while(i.HasNext()) { Client *p = i.Next(); if (p->GetGuildID() == guildID) { newmsg->clientnum = p->GetClientNum(); SendMessage (newmsg); } } CHECK_FINAL_DECREF(newmsg, "GuildMsg"); break; } case NetBase::BC_FINALPACKET: { csRef<MsgEntry> newmsg; newmsg.AttachNew(new MsgEntry(me)); newmsg->msgid = GetRandomID(); LogMessages('F',newmsg); // XXX: This is hacky, but we need to send the message to the client // here and now! Because in the next moment he'll be deleted csRef<psNetPacketEntry> pkt; pkt.AttachNew( new psNetPacketEntry(me->priority, newmsg->clientnum, 0, 0, (uint32_t) newmsg->bytes->GetTotalSize(), (uint16_t) newmsg->bytes->GetTotalSize(), newmsg->bytes)); // this will also delete the pkt SendFinalPacket(pkt); CHECK_FINAL_DECREF(newmsg, "FinalPacket"); break; } default: psprintf("\nIllegal Broadcast scope %d!\n",scope); return; } }
bool BgLoader::LoadMesh(MeshObj* mesh) { if(mesh->object.IsValid()) return true; bool ready = true; for(size_t i=0; i<mesh->meshfacts.GetSize(); i++) { if(!mesh->mftchecked[i]) { mesh->mftchecked[i] = LoadMeshFact(mesh->meshfacts[i]); ready &= mesh->mftchecked[i]; } } if(!ready) return false; for(size_t i=0; i<mesh->materials.GetSize(); i++) { if(!mesh->matchecked[i]) { mesh->matchecked[i] = LoadMaterial(mesh->materials[i]); ready &= mesh->matchecked[i]; } } if(!ready) return false; for(size_t i=0; i<mesh->textures.GetSize(); i++) { if(!mesh->texchecked[i]) { mesh->texchecked[i] = LoadTexture(mesh->textures[i]); ready &= mesh->texchecked[i]; } } if(ready) { if(!mesh->status) mesh->status = tloader->LoadNode(mesh->path, mesh->data); ready = mesh->status->IsFinished(); } // Load sequences. if(ready) { for(size_t i=0; i<mesh->sequences.GetSize(); ++i) { if(mesh->sequences[i]->loaded) continue; if(!mesh->sequences[i]->status) { mesh->sequences[i]->status = tloader->LoadNode(mesh->path, mesh->sequences[i]->data); ready = false; } else { if(ready && mesh->sequences[i]->status->IsFinished()) { if(!mesh->sequences[i]->status->WasSuccessful()) { csString msg; msg.Format("Sequence '%s' in mesh '%s' failed to load.\n", mesh->sequences[i]->name.GetData(), mesh->name.GetData()); CS_ASSERT_MSG(msg.GetData(), false); } mesh->sequences[i]->loaded = true; } else ready = false; } } } // Load triggers if(ready) { for(size_t i=0; i<mesh->sequences.GetSize(); ++i) { for(size_t j=0; j<mesh->sequences[i]->triggers.GetSize(); ++j) { if(mesh->sequences[i]->triggers[j]->loaded) continue; if(!mesh->sequences[i]->triggers[j]->status) { mesh->sequences[i]->triggers[j]->status = tloader->LoadNode(mesh->path, mesh->sequences[i]->triggers[j]->data); ready = false; } else { if(ready && mesh->sequences[i]->triggers[j]->status->IsFinished()) { if(!mesh->sequences[i]->triggers[j]->status->WasSuccessful()) { csString msg; msg.Format("Trigger '%s' in mesh '%s' failed to load.\n", mesh->sequences[i]->triggers[j]->name.GetData(), mesh->name.GetData()); CS_ASSERT_MSG(msg.GetData(), false); } mesh->sequences[i]->triggers[j]->loaded = true; } else ready = false; } } } } return ready; }
void BgLoader::LoadSector(const csBox3& loadBox, const csBox3& unloadBox, Sector* sector, uint depth, bool force, bool loadMeshes, bool portalsOnly) { sector->isLoading = true; if(!sector->object.IsValid()) { { csString msg; msg.AppendFmt("Attempting to load uninit sector %s!\n", sector->name.GetData()); CS_ASSERT_MSG(msg.GetData(), sector->init); if(!sector->init) return; } sector->object = engine->CreateSector(sector->name); sector->object->SetDynamicAmbientLight(sector->ambient); sector->object->SetVisibilityCullerPlugin(sector->culler); sector->object->QueryObject()->SetObjectParent(sector->parent); } if(!force && depth < maxPortalDepth) { // Check other sectors linked to by active portals. for(size_t i=0; i<sector->activePortals.GetSize(); i++) { if(!sector->activePortals[i]->targetSector->isLoading && !sector->activePortals[i]->targetSector->checked) { csBox3 wwLoadBox = loadBox; csBox3 wwUnloadBox = unloadBox; if(sector->activePortals[i]->warp) { csVector3& transform = sector->activePortals[i]->transform; wwLoadBox.SetMin(0, wwLoadBox.MinX()-transform.x); wwLoadBox.SetMin(1, wwLoadBox.MinY()-transform.y); wwLoadBox.SetMin(2, wwLoadBox.MinZ()-transform.z); wwLoadBox.SetMax(0, wwLoadBox.MaxX()-transform.x); wwLoadBox.SetMax(1, wwLoadBox.MaxY()-transform.y); wwLoadBox.SetMax(2, wwLoadBox.MaxZ()-transform.z); wwUnloadBox.SetMin(0, wwUnloadBox.MinX()-transform.x); wwUnloadBox.SetMin(1, wwUnloadBox.MinY()-transform.y); wwUnloadBox.SetMin(2, wwUnloadBox.MinZ()-transform.z); wwUnloadBox.SetMax(0, wwUnloadBox.MaxX()-transform.x); wwUnloadBox.SetMax(1, wwUnloadBox.MaxY()-transform.y); wwUnloadBox.SetMax(2, wwUnloadBox.MaxZ()-transform.z); } LoadSector(wwLoadBox, wwUnloadBox, sector->activePortals[i]->targetSector, depth+1, false, loadMeshes); } } } if(loadMeshes && !portalsOnly) { // Load all meshes which should always be loaded in this sector. for(size_t i=0; i<sector->alwaysLoaded.GetSize(); i++) { if(!sector->alwaysLoaded[i]->loading && !sector->alwaysLoaded[i]->object.IsValid()) { sector->alwaysLoaded[i]->loading = true; loadingMeshes.Push(sector->alwaysLoaded[i]); ++(sector->objectCount); } } // Check all meshes in this sector. for(size_t i=0; i<sector->meshes.GetSize(); i++) { if(!sector->meshes[i]->loading) { if(sector->meshes[i]->InRange(loadBox, force)) { sector->meshes[i]->loading = true; loadingMeshes.Push(sector->meshes[i]); ++(sector->objectCount); } else if(!force && sector->meshes[i]->OutOfRange(unloadBox)) { sector->meshes[i]->object->GetMovable()->ClearSectors(); sector->meshes[i]->object->GetMovable()->UpdateMove(); engine->GetMeshes()->Remove(sector->meshes[i]->object); sector->meshes[i]->object.Invalidate(); deleteQueue.Push(sector->meshes[i]); --(sector->objectCount); } } } // Check all meshgen in this sector. for(size_t i=0; i<sector->meshgen.GetSize(); i++) { if(!sector->meshgen[i]->loading) { if(sector->meshgen[i]->InRange(loadBox, force)) { sector->meshgen[i]->loading = true; loadingMeshGen.Push(sector->meshgen[i]); ++(sector->objectCount); } else if(!force && sector->meshgen[i]->OutOfRange(unloadBox)) { CleanMeshGen(sector->meshgen[i]); --(sector->objectCount); } } } } // Check all portals in this sector... and recurse into the sectors they lead to. for(size_t i=0; i<sector->portals.GetSize(); i++) { if(sector->portals[i]->InRange(loadBox, force)) { bool recurse = true; if(!force && depth >= maxPortalDepth) { // If we've reached the recursion limit then check if the // target sector is valid. If so then create a portal to it. if(sector->portals[i]->targetSector->object.IsValid()) { recurse = false; } else // Else check the next portal. { continue; } } if(force) { if(sector->portals[i]->mObject) { engine->GetMeshes()->Remove(sector->portals[i]->mObject); sector->portals[i]->pObject = NULL; sector->portals[i]->mObject.Invalidate(); sector->activePortals.Delete(sector->portals[i]); --(sector->objectCount); } if(!sector->portals[i]->targetSector->object.IsValid()) { { csString msg; msg.AppendFmt("Attempting to load uninit sector %s!\n", sector->portals[i]->targetSector->name.GetData()); CS_ASSERT_MSG(msg.GetData(), sector->portals[i]->targetSector->init); if(!sector->portals[i]->targetSector->init) return; } sector->portals[i]->targetSector->object = engine->CreateSector(sector->portals[i]->targetSector->name); sector->portals[i]->targetSector->object->SetDynamicAmbientLight(sector->portals[i]->targetSector->ambient); sector->portals[i]->targetSector->object->SetVisibilityCullerPlugin(sector->portals[i]->targetSector->culler); sector->portals[i]->targetSector->object->QueryObject()->SetObjectParent(sector->portals[i]->targetSector->parent); } } else if(!sector->portals[i]->targetSector->isLoading && !sector->portals[i]->targetSector->checked && recurse) { csBox3 wwLoadBox = loadBox; csBox3 wwUnloadBox = unloadBox; if(sector->portals[i]->warp) { csVector3& transform = sector->portals[i]->transform; wwLoadBox.SetMin(0, wwLoadBox.MinX()-transform.x); wwLoadBox.SetMin(1, wwLoadBox.MinY()-transform.y); wwLoadBox.SetMin(2, wwLoadBox.MinZ()-transform.z); wwLoadBox.SetMax(0, wwLoadBox.MaxX()-transform.x); wwLoadBox.SetMax(1, wwLoadBox.MaxY()-transform.y); wwLoadBox.SetMax(2, wwLoadBox.MaxZ()-transform.z); wwUnloadBox.SetMin(0, wwUnloadBox.MinX()-transform.x); wwUnloadBox.SetMin(1, wwUnloadBox.MinY()-transform.y); wwUnloadBox.SetMin(2, wwUnloadBox.MinZ()-transform.z); wwUnloadBox.SetMax(0, wwUnloadBox.MaxX()-transform.x); wwUnloadBox.SetMax(1, wwUnloadBox.MaxY()-transform.y); wwUnloadBox.SetMax(2, wwUnloadBox.MaxZ()-transform.z); } LoadSector(wwLoadBox, wwUnloadBox, sector->portals[i]->targetSector, depth+1, false, loadMeshes); } sector->portals[i]->mObject = engine->CreatePortal(sector->portals[i]->name, sector->object, csVector3(0), sector->portals[i]->targetSector->object, sector->portals[i]->poly.GetVertices(), (int)sector->portals[i]->poly.GetVertexCount(), sector->portals[i]->pObject); if(sector->portals[i]->warp) { sector->portals[i]->pObject->SetWarp(sector->portals[i]->matrix, sector->portals[i]->wv, sector->portals[i]->ww); } if(sector->portals[i]->pfloat) { sector->portals[i]->pObject->GetFlags().SetBool(CS_PORTAL_FLOAT, true); } if(sector->portals[i]->clip) { sector->portals[i]->pObject->GetFlags().SetBool(CS_PORTAL_CLIPDEST, true); } if(sector->portals[i]->zfill) { sector->portals[i]->pObject->GetFlags().SetBool(CS_PORTAL_ZFILL, true); } sector->activePortals.Push(sector->portals[i]); ++(sector->objectCount); } else if(!force && sector->portals[i]->OutOfRange(unloadBox)) { if(!sector->portals[i]->targetSector->isLoading) { csBox3 wwLoadBox = loadBox; csBox3 wwUnloadBox = unloadBox; if(sector->portals[i]->warp) { csVector3& transform = sector->portals[i]->transform; wwLoadBox.SetMin(0, wwLoadBox.MinX()-transform.x); wwLoadBox.SetMin(1, wwLoadBox.MinY()-transform.y); wwLoadBox.SetMin(2, wwLoadBox.MinZ()-transform.z); wwLoadBox.SetMax(0, wwLoadBox.MaxX()-transform.x); wwLoadBox.SetMax(1, wwLoadBox.MaxY()-transform.y); wwLoadBox.SetMax(2, wwLoadBox.MaxZ()-transform.z); wwUnloadBox.SetMin(0, wwUnloadBox.MinX()-transform.x); wwUnloadBox.SetMin(1, wwUnloadBox.MinY()-transform.y); wwUnloadBox.SetMin(2, wwUnloadBox.MinZ()-transform.z); wwUnloadBox.SetMax(0, wwUnloadBox.MaxX()-transform.x); wwUnloadBox.SetMax(1, wwUnloadBox.MaxY()-transform.y); wwUnloadBox.SetMax(2, wwUnloadBox.MaxZ()-transform.z); } LoadSector(wwLoadBox, wwUnloadBox, sector->portals[i]->targetSector, depth+1, false, loadMeshes); } engine->GetMeshes()->Remove(sector->portals[i]->mObject); sector->portals[i]->pObject = NULL; sector->portals[i]->mObject.Invalidate(); sector->activePortals.Delete(sector->portals[i]); --(sector->objectCount); } } if(loadMeshes && !portalsOnly) { // Check all sector lights. for(size_t i=0; i<sector->lights.GetSize(); i++) { if(sector->lights[i]->InRange(loadBox, force)) { sector->lights[i]->object = engine->CreateLight(sector->lights[i]->name, sector->lights[i]->pos, sector->lights[i]->radius, sector->lights[i]->colour, sector->lights[i]->dynamic); sector->lights[i]->object->SetAttenuationMode(sector->lights[i]->attenuation); sector->lights[i]->object->SetType(sector->lights[i]->type); sector->object->GetLights()->Add(sector->lights[i]->object); ++sector->objectCount; // Load all light sequences. for(size_t j=0; j<sector->lights[i]->sequences.GetSize(); ++j) { sector->lights[i]->sequences[j]->status = tloader->LoadNodeWait(vfs->GetCwd(), sector->lights[i]->sequences[j]->data); for(size_t k=0; k<sector->lights[i]->sequences[j]->triggers.GetSize(); ++k) { sector->lights[i]->sequences[j]->triggers[k]->status = tloader->LoadNode(vfs->GetCwd(), sector->lights[i]->sequences[j]->triggers[k]->data); } } } else if(!force && sector->lights[i]->OutOfRange(unloadBox)) { engine->RemoveLight(sector->lights[i]->object); sector->lights[i]->object.Invalidate(); --sector->objectCount; for(size_t j=0; j<sector->lights[i]->sequences.GetSize(); ++j) { if(sector->lights[i]->sequences[j]->status.IsValid()) { for(size_t k=0; k<sector->lights[i]->sequences[j]->triggers.GetSize(); ++k) { if(sector->lights[i]->sequences[j]->triggers[k]->status.IsValid()) { csRef<iSequenceTrigger> st = scfQueryInterface<iSequenceTrigger>(sector->lights[i]->sequences[j]->triggers[k]->status->GetResultRefPtr()); engseq->RemoveTrigger(st); sector->lights[i]->sequences[j]->triggers[k]->status.Invalidate(); } } csRef<iSequenceWrapper> sw = scfQueryInterface<iSequenceWrapper>(sector->lights[i]->sequences[j]->status->GetResultRefPtr()); engseq->RemoveSequence(sw); sector->lights[i]->sequences[j]->status.Invalidate(); } } } } if(loadMeshes && !portalsOnly) { // Load all sector sequences. for(size_t i=0; i<sector->sequences.GetSize(); i++) { if(!sector->sequences[i]->status.IsValid()) { sector->sequences[i]->status = tloader->LoadNode(vfs->GetCwd(), sector->sequences[i]->data); } } } // Check whether this sector is empty and should be unloaded. if(sector->objectCount == sector->alwaysLoaded.GetSize() && sector->object.IsValid()) { // Unload all 'always loaded' meshes before destroying sector. for(size_t i=0; i<sector->alwaysLoaded.GetSize(); i++) { sector->alwaysLoaded[i]->object->GetMovable()->ClearSectors(); sector->alwaysLoaded[i]->object->GetMovable()->UpdateMove(); engine->GetMeshes()->Remove(sector->alwaysLoaded[i]->object); sector->alwaysLoaded[i]->object.Invalidate(); deleteQueue.Push(sector->meshes[i]); --(sector->objectCount); } // Remove sequences. for(size_t i=0; i<sector->sequences.GetSize(); i++) { if(sector->sequences[i]->status.IsValid()) { csRef<iSequenceWrapper> sw = scfQueryInterface<iSequenceWrapper>(sector->sequences[i]->status->GetResultRefPtr()); engseq->RemoveSequence(sw); sector->sequences[i]->status.Invalidate(); } } // Remove the sector from the engine. sector->object->QueryObject()->SetObjectParent(0); engine->GetSectors()->Remove(sector->object); sector->object.Invalidate(); } } sector->checked = true; sector->isLoading = false; }