int LVL_Npc::lua_activate_neighbours() { QVector<PGE_Phys_Object *> bodies; PGE_RectF posRectC = m_momentum.rectF().withMargin(2.0); m_scene->queryItems(posRectC, &bodies); int found = 0; for(PGE_RenderList::iterator it = bodies.begin(); it != bodies.end(); it++) { PGE_Phys_Object *item = *it; if(item->type != PGE_Phys_Object::LVLNPC) continue; LVL_Npc *body = dynamic_cast<LVL_Npc *>(item); if(!body) continue; if(body == this) continue; if(!body->isVisible()) continue; if(body->killed) continue; if(body->_npc_id != _npc_id) continue; if(!body->isActivated) { body->Activate(); m_scene->active_npcs.push_back(body); found++; } } return found; }
void LevelScene::placeNPC(LevelNPC npcData) { if(!ConfigManager::lvl_npc_indexes.contains(npcData.id)) return; obj_npc* curNpcData = &ConfigManager::lvl_npc_indexes[npcData.id]; LVL_Npc * npc = luaEngine.createLuaNpc(npcData.id); if(!npc) return; npc->setup = curNpcData; npc->data = npcData; npc->init(); npcs.push_back(npc); }
void LVL_Block::transformTo(unsigned long id, int type) { if(id == 0) return; if(type == 2) //Other block { transformTask_block t; t.block = this; t.id = id; t.type = type; m_scene->block_transforms.push_back(t); } if(type == 1) //Other NPC { LevelNPC def = FileFormats::CreateLvlNpc(); def.id = id; def.x = long(round(posX())); def.y = long(round(posY())); def.direct = 0; def.generator = false; def.layer = data.layer; def.attach_layer = ""; def.event_activate = ""; def.event_die = ""; def.event_talk = ""; def.event_emptylayer = ""; LVL_Npc *npc = m_scene->spawnNPC(def, LevelScene::GENERATOR_APPEAR, LevelScene::SPAWN_UP, true); if(npc) { npc->transformedFromBlock = this; npc->transformedFromBlockID = data.id; npc->setCenterPos(m_momentum.centerX(), m_momentum.centerY()); npc->m_momentum.saveOld(); npc->data.x = long(round(npc->m_momentum.x)); npc->data.y = long(round(npc->m_momentum.y)); } destroy(false); } }
void LevelScene::collectGarbageNPCs() { QVector<LVL_Npc *> stillVizible;//Avoid camera crash (which uses a cached render list) while(!dead_npcs.isEmpty()) { LVL_Npc *corpse = dead_npcs.last(); dead_npcs.pop_back(); if(corpse->isInRenderList()) { stillVizible.push_back(corpse);//Avoid camera crash (which uses a cached render list) continue; } #if (QT_VERSION >= 0x050400) active_npcs.removeAll(corpse); npcs.removeAll(corpse); layers.removeRegItem(corpse->data.layer, corpse); #else //He-he, it's a great workaround for a Qt less than 5.4 which has QVector without removeAll() function while(1) { const QVector<LVL_Npc *>::const_iterator ce = active_npcs.cend(), cit = std::find(active_npcs.cbegin(), ce, corpse); if (cit == ce) break; const QVector<LVL_Npc *>::iterator e = active_npcs.end(), it = std::remove(active_npcs.begin() + (cit - active_npcs.cbegin()), e, corpse); active_npcs.erase(it, e); break; } while(1) { const QVector<LVL_Npc *>::const_iterator ce = npcs.cend(), cit = std::find(npcs.cbegin(), ce, corpse); if (cit == ce) break; const QVector<LVL_Npc *>::iterator e = npcs.end(), it = std::remove(npcs.begin() + (cit - npcs.cbegin()), e, corpse); npcs.erase(it, e); break; } #endif luaEngine.destoryLuaNpc(corpse); } dead_npcs.append(stillVizible); }
void LevelScene::placeNPC(LevelNPC& npcData) { if(npcData.id <= 0) return; if(!ConfigManager::lvl_npc_indexes.contains(npcData.id)) return; obj_npc *curNpcData = &ConfigManager::lvl_npc_indexes[npcData.id]; LVL_Npc *npc = m_luaEngine.createLuaNpc(npcData.id); if(!npc) return; npc->setScenePointer(this); npc->setup = curNpcData; npc->data = npcData; npc->init(); m_itemsNpc.push_back(npc); }
LVL_Npc *LevelScene::spawnNPC(LevelNPC npcData, NpcSpawnType sp_type, NpcSpawnDirection sp_dir, bool reSpawnable) { if(!ConfigManager::lvl_npc_indexes.contains(npcData.id)) return NULL; obj_npc* curNpcData = &ConfigManager::lvl_npc_indexes[npcData.id]; LVL_Npc * npc = luaEngine.createLuaNpc(npcData.id); if(!npc) return NULL; npcData.array_id= ++data.npc_array_id; npc->setup = curNpcData; npc->reSpawnable=reSpawnable; npc->data = npcData; npc->init(); npc->Activate(); switch(sp_type) { case GENERATOR_WARP: switch(sp_dir) { case SPAWN_DOWN: npc->setWarpSpawn(LVL_Npc::WARP_TOP); break; case SPAWN_UP: npc->setWarpSpawn(LVL_Npc::WARP_BOTTOM); break; case SPAWN_LEFT: npc->setWarpSpawn(LVL_Npc::WARP_RIGHT); break; case SPAWN_RIGHT: npc->setWarpSpawn(LVL_Npc::WARP_LEFT); break; } break; case GENERATOR_PROJECTILE: break; default: break; } active_npcs.push_back(npc); npcs.push_back(npc); return npc; }
void LevelScene::update() { if(m_luaEngine.shouldShutdown()) { m_fader.setFade(10, 1.0, 1.0); setExiting(0, LvlExit::EXIT_Error); } Scene::update(); if(!m_isPauseMenu) tickAnimations(uTickf); if(!m_isLevelContinues) { //Level exit timeout m_exitLevelDelay -= uTickf; if(m_exitLevelDelay <= 0.0) { m_doExit = true; if(m_fader.isNull()) { if(PGE_MusPlayer::isPlaying()) PGE_MusPlayer::fadeOut(500); m_fader.setFade(10, 1.0, 0.01); } } } if(m_doExit) { if(m_exitLevelCode == LvlExit::EXIT_Closed) { m_fader.setFull(); m_isRunning = false; } else { if(m_fader.isFull()) m_isRunning = false; } } else if(m_isPauseMenu) processPauseMenu(); else { //Update physics is not pause menu updateLua();//Process LUA code m_systemEvents.processEvents(uTickf); m_events.processTimers(uTickf); //update cameras for(PGE_LevelCamera &cam : m_cameras) cam.updatePre(uTickf); processEffects(uTickf); if(!m_isTimeStopped) //if activated Time stop bonus or time disabled by special event { //Make world step processPhysics(uTickf); } while(!m_blockTransforms.empty()) { transformTask_block x = m_blockTransforms.front(); x.block->transformTo_x(x.id); m_blockTransforms.pop_front(); } // Send controller states to controllable objects m_player1Controller->sendControls(); m_player2Controller->sendControls(); //update players for(LVL_Player *plr : m_itemsPlayers) { plr->update(uTickf); if(PGE_Window::showDebugInfo) { m_debug_player_jumping = plr->m_jumpPressed; m_debug_player_onground = plr->onGround(); m_debug_player_foots = (int)plr->l_contactB.size(); } } for(size_t i = 0; i < m_blocksInFade.size(); i++) { if(m_blocksInFade[i]->tickFader(uTickf)) { m_blocksInFade.erase(m_blocksInFade.begin() + (int)i); i--; } } //Process activated NPCs //for(size_t i = 0; i < m_npcActive.size(); i++) for(auto i = m_npcActive.begin(); i != m_npcActive.end();) { LVL_Npc *n = *i; n->update(uTickf); if(n->isKilled()) { i = m_npcActive.erase(i); continue; } else if(n->activationTimeout <= 0) { if(!n->warpSpawing) n->deActivate(); if(n->wasDeactivated) { if(!isVizibleOnScreen(n->m_momentum) || !n->isVisible() || !n->is_activity) { n->wasDeactivated = false; i = m_npcActive.erase(i); continue; } } } ++i; } if(!m_isTimeStopped) //if activated Time stop bonus or time disabled by special event { //Process and resolve collisions processAllCollisions(); } /***************Collect garbage****************/ if(!m_npcDead.empty()) collectGarbageNPCs(); if(!m_playersDead.empty()) collectGarbagePlayers(); if(!m_blocksToDelete.empty()) collectGarbageBlocks(); /**********************************************/ //update cameras for(PGE_LevelCamera &cam : m_cameras) { cam.updatePost(uTickf); //! --------------DRAW HUD-------------------------------------- // TODO: Implement separated render queue for elements of HUD and provide render functions // are will draw HUD elements after world has drawn. LuaEngine *sceneLuaEngine = getLuaEngine(); if(sceneLuaEngine) { if(sceneLuaEngine->isValid() && !sceneLuaEngine->shouldShutdown()) { LuaEvent drawHUDEvent = BindingCore_Events_Engine::createDrawLevelHUDEvent(sceneLuaEngine, &cam, &m_playerStates[(size_t)(cam.playerID - 1)]); sceneLuaEngine->dispatchEvent(drawHUDEvent); } } //! ------------------------------------------------------------ } //Add effects into the render table for(Scene_Effect &item : WorkingEffects) { renderArrayAddFunction([&item](double camPosX, double camPosY) { item.render(camPosX, camPosY); }, item.m_zIndex); } //Clear garbage (be careful!) //luaEngine.runGarbageCollector(); } //Process interprocessing commands cache process_InterprocessCommands(); //Process Z-sort of the render functions renderArrayPrepare(); //Process message boxes m_messages.process(); }
LVL_Npc *LevelScene::spawnNPC(const LevelNPC &npcData, NpcSpawnType sp_type, NpcSpawnDirection sp_dir, bool reSpawnable) { if(npcData.id <= 0) return nullptr; if(!ConfigManager::lvl_npc_indexes.contains(npcData.id)) return nullptr; obj_npc *curNpcData = &ConfigManager::lvl_npc_indexes[npcData.id]; LVL_Npc *npc = m_luaEngine.createLuaNpc(npcData.id); if(!npc) return nullptr; npc->setScenePointer(this); npc->setup = curNpcData; npc->reSpawnable = reSpawnable; npc->data = npcData; npc->data.meta.array_id = ++m_data.npc_array_id; npc->init(); npc->m_spawnedGeneratorType = sp_type; npc->m_spawnedGeneratorDirection = sp_dir; switch(sp_type) { case GENERATOR_WARP: switch(sp_dir) { case SPAWN_DOWN: npc->setWarpSpawn(LVL_Npc::WARP_TOP); break; case SPAWN_UP: npc->setWarpSpawn(LVL_Npc::WARP_BOTTOM); break; case SPAWN_LEFT: npc->setWarpSpawn(LVL_Npc::WARP_RIGHT); break; case SPAWN_RIGHT: npc->setWarpSpawn(LVL_Npc::WARP_LEFT); break; } break; case GENERATOR_PROJECTILE: switch(sp_dir) { case SPAWN_DOWN: npc->setSpeedX(0.0); npc->setSpeedY(ConfigManager::g_setup_npc.projectile_speed); break; case SPAWN_UP: npc->setSpeedX(0.0); npc->setSpeedY(-ConfigManager::g_setup_npc.projectile_speed); break; case SPAWN_LEFT: npc->setSpeedX(-ConfigManager::g_setup_npc.projectile_speed); npc->setSpeedY(0.0); break; case SPAWN_RIGHT: npc->setSpeedX(ConfigManager::g_setup_npc.projectile_speed); npc->setSpeedY(0.0); break; } PGE_Audio::playSound(ConfigManager::g_setup_npc.projectile_sound_id); break; default: break; } npc->Activate(); m_npcActive.push_back(npc); m_itemsNpc.push_back(npc); return npc; }
void PGE_LevelCamera::update(float ticks) { objects_to_render.clear(); if(!cur_section) return; fader.tickFader(ticks); if(isAutoscroll) processAutoscroll(ticks); LvlSceneP::s->queryItems(posRect, &objects_to_render); int contacts = 0; for(int i=0; i<objects_to_render.size();i++) { contacts++; PGE_Phys_Object * visibleBody = objects_to_render[i]; bool renderable=false; if(!visibleBody->isVisible()) { objects_to_render.removeAt(i); i--; continue; } switch(visibleBody->type) { case PGE_Phys_Object::LVLBlock: case PGE_Phys_Object::LVLBGO: case PGE_Phys_Object::LVLNPC: case PGE_Phys_Object::LVLPlayer: case PGE_Phys_Object::LVLEffect: renderable=true; } if(visibleBody->type==PGE_Phys_Object::LVLNPC) { LVL_Npc *npc = dynamic_cast<LVL_Npc*>(visibleBody); if(npc && npc->isVisible()) { if(!npc->isActivated && !npc->wasDeactivated) { npc->Activate(); LvlSceneP::s->active_npcs.push_back(npc); } else { if(npc->wasDeactivated) npc->activationTimeout=0; else { if(npc->is_activity) npc->activationTimeout = npc->setup->deactivetionDelay; else npc->activationTimeout = 150; } } } } if(!PGE_Window::showPhysicsDebug && !renderable) { objects_to_render.removeAt(i); i--; } } //Sort array sortElements(); }