#include "roomdestructioncomponent.h" #include "visitors.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace VCtrl { //////////////////////////////////////////////////////////////////////////////// const dtEntity::StringId RoomDestructionComponent::TYPE(dtEntity::SID("RoomDestruction")); //////////////////////////////////////////////////////////////////////////////// void RoomDestructionComponent::OnEnteredWorld() { osg::Shader *vShader = osg::Shader::readShaderFile(osg::Shader::VERTEX, osgDB::findDataFile("shaders/roomdestruction.vert")); osg::Shader *fShader = osg::Shader::readShaderFile(osg::Shader::FRAGMENT, osgDB::findDataFile("shaders/roomdestruction.frag")); if (vShader == nullptr || fShader == nullptr) { LOG_ERROR("Could not load building transparency shaders!"); Q_ASSERT(false); } osg::Program *p = new osg::Program(); p->setName("RoomDestructionShader"); p->addShader(vShader); p->addShader(fShader); dtEntityOSG::LayerComponent *lc; if (mEntity->GetComponent(lc)) { osg::Node *n = lc->GetAttachedComponentNode(); if (n != nullptr) { ClearVertexColorsVisitor v; lc->GetAttachedComponentNode()->accept(v); osg::StateSet *ss = n->getOrCreateStateSet(); ss->setAttributeAndModes(p); ss->addUniform(new osg::Uniform("room_color", osg::Vec4(1, 1, 1, 1))); ss->addUniform(new osg::Uniform("wall_color", osg::Vec4(1, 1, 1, 1))); } } dtEntityOSG::StaticMeshComponent *smc; if (mEntity->GetComponent(smc)) { FindRoomNamesVisitor v; smc->GetNode()->accept(v); for (const auto &roomName: v.mNames) mRoomDestructions[roomName] = 0; } } //////////////////////////////////////////////////////////////////////////// bool RoomDestructionComponent::SetRoomDestructionValue(const std::string &room, float value) { if (mRoomDestructions.find(room) == mRoomDestructions.end()) return false; FindRoomByNumberVisitor fn; fn.setNameToFind(room); dtEntityOSG::LayerComponent *lc; if (!mEntity->GetComponent(lc)) return false; osg::Node *n = lc->GetAttachedComponentNode(); if (n == nullptr) return false; lc->GetAttachedComponentNode()->accept(fn); for (const auto &node : fn.getNodeList()) { RoomDestructionSystem *bts; mEntity->GetEntityManager().GetES(bts); FindRoomComponentsVisitor frc; node->accept(frc); FindExactNameVisitor v(frc.mNamesFound); //LOG_ERROR("Found " + std::to_string(frc.mNamesFound.size()) + " component names"); osg::Node *partNode = lc->GetAttachedComponentNode(); if (partNode) partNode->accept(v); for (const auto &visitedNodes : v.mNodes) { osg::StateSet *ss = visitedNodes->getOrCreateStateSet(); ss->addUniform(new osg::Uniform("room_color", osg::Vec4(1, 1 - value, 1 - value, 1))); } } dtEntity::GetWindowInterface()->RequestRedraw(0); mRoomDestructions[room] = value; return true; } //////////////////////////////////////////////////////////////////////////// bool RoomDestructionComponent::SetBuildingDestructionValue(float value) { for (const auto &rd : mRoomDestructions) SetRoomDestructionValue(rd.first, value); return true; } //////////////////////////////////////////////////////////////////////////// const dtEntity::StringId RoomDestructionSystem::TYPE(dtEntity::SID("RoomDestruction")); RoomDestructionSystem::RoomDestructionSystem(dtEntity::EntityManager &em) : dtEntity::DefaultEntitySystem(em) { mEnterWorldFunctor = dtEntity::MessageFunctor(this, &RoomDestructionSystem::OnEnterWorld); em.RegisterForMessages(dtEntity::EntityAddedToSceneMessage::TYPE, mEnterWorldFunctor, "RoomDestructionSystem::OnEnterWorld"); } //////////////////////////////////////////////////////////////////////////// void RoomDestructionSystem::OnEnterWorld(const dtEntity::Message &msg) { dtEntity::EntityId id = msg.Get(dtEntity::EntityAddedToSceneMessage::AboutEntityId)->UIntValue(); RoomDestructionComponent *bt; if (GetEntityManager().GetComponent(id, bt)) bt->OnEnteredWorld(); } }