void CAI_PlaneSolver::GenerateObstacleNpcs( const AILocalMoveGoal_t &goal, float probeDist ) { if ( !ProbeForNpcs() ) { CAI_BaseNPC **ppAIs = g_AI_Manager.AccessAIs(); Vector minsSelf, maxsSelf; m_pNpc->CollisionProp()->WorldSpaceSurroundingBounds( &minsSelf, &maxsSelf ); float radiusSelf = (minsSelf.AsVector2D() - maxsSelf.AsVector2D()).Length() * 0.5; for ( int i = 0; i < g_AI_Manager.NumAIs(); i++ ) { CAI_BaseNPC *pAI = ppAIs[i]; if ( pAI != m_pNpc && pAI->IsAlive() && ( !goal.pPath || pAI != goal.pPath->GetTarget() ) ) { Vector mins, maxs; pAI->CollisionProp()->WorldSpaceSurroundingBounds( &mins, &maxs ); if ( mins.z < maxsSelf.z + 12.0 && maxs.z > minsSelf.z - 12.0 ) { float radius = (mins.AsVector2D() - maxs.AsVector2D()).Length() * 0.5; float distance = ( pAI->GetAbsOrigin().AsVector2D() - m_pNpc->GetAbsOrigin().AsVector2D() ).Length(); if ( distance - radius < radiusSelf + probeDist ) { AddObstacle( pAI->WorldSpaceCenter(), radius, pAI, AIMST_AVOID_NPC ); } } } } #ifdef SecobMod__Enable_Fixed_Multiplayer_AI CBaseEntity *pPlayer = UTIL_GetNearestPlayer(m_pNpc->GetAbsOrigin()); #else CBaseEntity *pPlayer = UTIL_PlayerByIndex( 1 ); #endif //SecobMod__Enable_Fixed_Multiplayer_AI if ( pPlayer ) { Vector mins, maxs; pPlayer->CollisionProp()->WorldSpaceSurroundingBounds( &mins, &maxs ); if ( mins.z < maxsSelf.z + 12.0 && maxs.z > minsSelf.z - 12.0 ) { float radius = (mins.AsVector2D() - maxs.AsVector2D()).Length(); float distance = ( pPlayer->GetAbsOrigin().AsVector2D() - m_pNpc->GetAbsOrigin().AsVector2D() ).Length(); if ( distance - radius < radiusSelf + probeDist ) { AddObstacle( pPlayer->WorldSpaceCenter(), radius, pPlayer, AIMST_AVOID_NPC ); } } } } }
void CChildView::SetTestObstacles() { for (int i = 0; i < 150; i++) { Rect2Df treerct = _tree->GetBound(); int x = rand() % (int)treerct.GetWidth(); int y = rand() % (int)treerct.GetHeight(); if(rand() / (float)RAND_MAX > 0.5f) AddObstacle(ELMBState::AddCircleObstacle, CPoint(x, y), 5); else AddObstacle(ELMBState::AddOBBObstacle, CPoint(x, y), 5); } }
void RPG_DestructibleEntity::PostInitialize() { RPG_DamageableEntity::PostInitialize(); // Preload the mesh and effect to be used when this prop is destroyed. RPG_VisionEffectHelper::LoadMesh(m_postDestructionMeshFilename); AddComponents(); AddObstacle(); m_health = m_healthMax; CreateEffect(DEFX_Ambient); }
void CChildView::OnLButtonUp(UINT nFlags, CPoint point) { switch (_LMBState) { case ELMBState::AddCircleObstacle: case ELMBState::AddOBBObstacle: AddObstacle(_LMBState, point); break; case ELMBState::IntersectSegment: { _intersectsegment.ChangeOrigin(Vector2Df(point)); CheckIntersect(); Invalidate(); break; } } __super::OnLButtonUp(nFlags, point); }
/* updateScene checks all the object that is inside the scene and updates the scene manager accordingly. The idea behind it is to use spatial partition to manage scene nodes and objects in the game. Load the objects when they come into load radius, unload them when they get out of the hold radius. */ void MapManager::UpdateScene(void) { //first of all update our loaded list UpdateLoadedList(&mFullyLoadedAreaList); //go through the enemy list, see if we need to remove any it from the scene std::vector<EnemyAI*>::iterator enemyIterator; for(enemyIterator = mEnemyList.begin(); enemyIterator != mEnemyList.end(); enemyIterator++) { //check if this enemy position is too far from our player Ogre::Real displacement = (*enemyIterator)->mEnemy->getPosition().distance(mPlayerNode->getPosition()); if(displacement > ENEMY_HOLDRADIUS) { //the enemy is outside hold radius //remove it if((*enemyIterator)->mSpells.empty() == false) { unsigned int i = 0; while(i < (*enemyIterator)->mSpells.size()) { //spell died BaseSpell *PointSpell = (*enemyIterator)->mSpells[i]; PointSpell->kill(Ogre::Root::getSingletonPtr()->getSceneManager("JixLeePuff")); (*enemyIterator)->mSpells.erase((*enemyIterator)->mSpells.begin() + i); delete PointSpell; i++; } } (*enemyIterator)->mEnemy->kill(); mEnemyList.erase(enemyIterator); break; } } //then check if map are still at the safe zone of the map. //meaning we do not worry about moving into a new map which requires a lot of things to do //has our character cross over to another map? //North if(mPlayerNode->getPosition().z < mMapTree->getCurrentMap()->getStartingPosition().z) { mMapTree->traverse(NORTH); } //South if(mPlayerNode->getPosition().z > mMapTree->getCurrentMap()->getEndingPosition().z) { mMapTree->traverse(SOUTH); } //East if(mPlayerNode->getPosition().x > mMapTree->getCurrentMap()->getEndingPosition().x) { mMapTree->traverse(EAST); } //West if(mPlayerNode->getPosition().x < mMapTree->getCurrentMap()->getStartingPosition().x) { mMapTree->traverse(WEST); } //clear surrounding area list if it is not empty if(!mSurroundingAreaList.empty()) mSurroundingAreaList.clear(); //first check to see if the player's load radius has reach beyond the borders of the current map //check one by one //North if((static_cast<int>(mPlayerNode->getPosition().z) - LOADRADIUS) < mMapTree->getCurrentMap()->getStartingPosition().z) { //yes! //get the list of areas been affected in that map Map* temp = mMapTree->getDirectionedMap(NORTH); tempAreaList = temp->GetAllFullAffectingArea(mPlayerNode->getPosition()); //combine the temp area list into surrounding area list CombineVectorList(&tempAreaList, &mSurroundingAreaList); } //South if((static_cast<int>(mPlayerNode->getPosition().z) + LOADRADIUS) > mMapTree->getCurrentMap()->getEndingPosition().z) { //yes! Map* temp = mMapTree->getDirectionedMap(SOUTH); tempAreaList = temp->GetAllFullAffectingArea(mPlayerNode->getPosition()); CombineVectorList(&tempAreaList, &mSurroundingAreaList); } //West if((static_cast<int>(mPlayerNode->getPosition().x) - LOADRADIUS) < mMapTree->getCurrentMap()->getStartingPosition().x) { //yes! Map* temp = mMapTree->getDirectionedMap(WEST); tempAreaList = temp->GetAllFullAffectingArea(mPlayerNode->getPosition()); CombineVectorList(&tempAreaList, &mSurroundingAreaList); } //East if((static_cast<int>(mPlayerNode->getPosition().x) + LOADRADIUS) > mMapTree->getCurrentMap()->getEndingPosition().x) { //yes! Map* temp = mMapTree->getDirectionedMap(EAST); tempAreaList = temp->GetAllFullAffectingArea(mPlayerNode->getPosition()); CombineVectorList(&tempAreaList, &mSurroundingAreaList); } //second check if we need to add or remove our objects in the scene //check if there are new areas come into load radius //get a new list //update the loading list mLoadingAreaList = mMapTree->getCurrentMap()->GetAllFullAffectingArea(mPlayerNode->getPosition()); //combine the surrounding area list into loading area list CombineVectorList(&mSurroundingAreaList, &mLoadingAreaList); //check if the list is empty if(!mLoadingAreaList.empty()) { //no we receive a new list of areas //first add those objects inside std::vector<MapArea*>::iterator newAreaIterator; for(newAreaIterator=mLoadingAreaList.begin(); newAreaIterator!=mLoadingAreaList.end(); newAreaIterator++) { //just incase this area is actually already loaded if((*newAreaIterator)->isLoaded()) continue; //create a scene node for the area char areaString[20]; sprintf(areaString, "map_area_%d", (*newAreaIterator)->getIndex()); //create a node for every area Ogre::SceneNode* areaNode = mMapNode->createChildSceneNode(Ogre::String(areaString)); (*newAreaIterator)->setLoaded(true); //add the ground into the node. char groundString[30]; sprintf(groundString, "map_area_ground_%d", (*newAreaIterator)->getIndex()); Ogre::SceneNode* groundNode = areaNode->createChildSceneNode(groundString); groundNode->attachObject((*newAreaIterator)->getGroundEntity()); groundNode->setPosition((*newAreaIterator)->getCenterPosition()); //now we need to go through the objects to find out which object has to be removed from it std::vector<Objects*>::iterator obstacleIterator; for(obstacleIterator = (*newAreaIterator)->_mObstacleList.begin(); obstacleIterator!=(*newAreaIterator)->_mObstacleList.end(); obstacleIterator++) { //is this object inside the load radius? if(IsObjectInsideRadius((*obstacleIterator), LOADRADIUS)) { AddObstacle((*newAreaIterator), (*obstacleIterator)); } } std::vector<Objects*>::iterator enemyIterator; for(enemyIterator = (*newAreaIterator)->_mEnemySpawnPointList.begin(); enemyIterator!=(*newAreaIterator)->_mEnemySpawnPointList.end(); enemyIterator++) { //no //is this object inside the load radius? if(IsObjectInsideRadius((*enemyIterator), ENEMY_LOADRADIUS)) { AddEnemy((*enemyIterator)); } } std::vector<Objects*>::iterator flamethrowerIterator; for(flamethrowerIterator = (*newAreaIterator)->_mFlameThrowerList.begin(); flamethrowerIterator!=(*newAreaIterator)->_mFlameThrowerList.end(); flamethrowerIterator++) { //no //is this object inside the load radius? if(IsObjectInsideRadius((*flamethrowerIterator), ENEMY_LOADRADIUS)) { AddFlameThrower((*flamethrowerIterator)); } } //then we add the areas inside the list to our fully loaded list mFullyLoadedAreaList.push_back((*newAreaIterator)); } } }
//update that checks the loaded list for adding or removing objects inside void MapManager::UpdateLoadedList(std::vector<MapArea*> *input) { //run through our current list //see if there is anything in the list to be updated std::vector<MapArea*>::iterator loadedIterator; for(loadedIterator = input->begin(); loadedIterator != input->end(); loadedIterator++) { //No matter if the area is fully inside or not, let's check if the area is now outside of the HOLDRADIUS if(!IsAreaInsideLoadRadius((*loadedIterator))) { if(!IsAreaInsideHoldRadius((*loadedIterator))) { //now, time to remove the area node //std::cout << "REMOVING AREA NODE!\n"; char areaString[30]; sprintf(areaString, "map_area_%d", (*loadedIterator)->getIndex()); //get the area node from map node. Ogre::SceneNode* areaNode = (Ogre::SceneNode*)mMapNode->getChild(Ogre::String(areaString)); //delete ground node char groundString[30]; sprintf(groundString, "map_area_ground_%d", (*loadedIterator)->getIndex()); Ogre::SceneNode* groundNode = (Ogre::SceneNode*)areaNode->getChild(Ogre::String(groundString)); groundNode->removeAndDestroyAllChildren(); groundNode->detachAllObjects(); areaNode->removeAndDestroyChild(groundString); areaNode->removeAndDestroyAllChildren(); areaNode->detachAllObjects(); mMapNode->removeAndDestroyChild(areaString); //set the map area to be unloaded (*loadedIterator)->setLoaded(false); //remove it from the list input->erase(loadedIterator); return; } } //since this area is not fully inside, lets check if this object is currently inside the scene std::vector<Objects*>::iterator obstacleIterator; for(obstacleIterator = (*loadedIterator)->_mObstacleList.begin(); obstacleIterator!=(*loadedIterator)->_mObstacleList.end(); obstacleIterator++) { //is this object in the load radius? if(IsObjectInsideRadius((*obstacleIterator), LOADRADIUS)) { //yes //is this object already loaded in the game? if((*obstacleIterator)->mLoaded) { //yes //skip continue; } else { //no //add it into the game AddObstacle((*loadedIterator), (*obstacleIterator)); } } //is this object out of hold radius? else if(!IsObjectInsideRadius((*obstacleIterator), HOLDRADIUS)) { //no //is this object already loaded in the game? if((*obstacleIterator)->mLoaded) { //yes //remove it RemoveObstacle((*loadedIterator),(*obstacleIterator)); } else { //no //skip continue; } } } std::vector<Objects*>::iterator enemyIterator; for(enemyIterator = (*loadedIterator)->_mEnemySpawnPointList.begin(); enemyIterator!=(*loadedIterator)->_mEnemySpawnPointList.end(); enemyIterator++) { //is this object inside the load radius? if(IsObjectInsideRadius((*enemyIterator), ENEMY_LOADRADIUS)) { //yes //is this enemy spawn point already loaded? if(!(*enemyIterator)->mLoaded) { //no //add enemy AddEnemy((*enemyIterator)); } } } std::vector<Objects*>::iterator flamethrowerIterator; for(flamethrowerIterator = (*loadedIterator)->_mFlameThrowerList.begin(); flamethrowerIterator!=(*loadedIterator)->_mFlameThrowerList.end(); flamethrowerIterator++) { //no //is this object inside the load radius? if(!IsObjectInsideRadius((*flamethrowerIterator), ENEMY_LOADRADIUS)) { //no //skip this object continue; } //yes continue whatever we need to do if(!(*flamethrowerIterator)->mLoaded) AddFlameThrower((*flamethrowerIterator)); } } }
/* First time load the objects, only run once when we first create the map. It will load all the objects that is around the player position. Let's just assume we start at the center of a map. If load game is to be implemented, TODO check surrounding maps using current position */ void MapManager::FirstLoadObjects(void) { //first tell the map where we are and ask for the areas that is possibily affected //then we take the list of areas, add all the objects into our scene mFullyLoadedAreaList = mMapTree->getCurrentMap()->GetAllFullAffectingArea(mPlayerNode->getPosition()); //add the objects in the list into the scene. std::vector<MapArea*>::iterator loadedIterator; for(loadedIterator = mFullyLoadedAreaList.begin(); loadedIterator != mFullyLoadedAreaList.end(); loadedIterator++) { char areaString[20]; sprintf(areaString, "map_area_%d", (*loadedIterator)->getIndex()); //create a node for every area Ogre::SceneNode* areaNode = mMapNode->createChildSceneNode(Ogre::String(areaString)); (*loadedIterator)->setLoaded(true); //add the ground into the node. char groundString[30]; sprintf(groundString, "map_area_ground_%d", (*loadedIterator)->getIndex()); Ogre::SceneNode* groundNode = areaNode->createChildSceneNode(groundString); groundNode->attachObject((*loadedIterator)->getGroundEntity()); groundNode->setPosition((*loadedIterator)->getCenterPosition()); //run through the obstacle list std::vector<Objects*>::iterator obstacleIterator; for(obstacleIterator = (*loadedIterator)->_mObstacleList.begin(); obstacleIterator!=(*loadedIterator)->_mObstacleList.end(); obstacleIterator++) { //no //is this object inside the load radius? if(!IsObjectInsideRadius((*obstacleIterator), LOADRADIUS)) { //no //skip this object continue; } //yes continue whatever we need to do AddObstacle((*loadedIterator), (*obstacleIterator)); } std::vector<Objects*>::iterator enemyIterator; for(enemyIterator = (*loadedIterator)->_mEnemySpawnPointList.begin(); enemyIterator!=(*loadedIterator)->_mEnemySpawnPointList.end(); enemyIterator++) { //no //is this object inside the load radius? if(!IsObjectInsideRadius((*enemyIterator), ENEMY_LOADRADIUS)) { //no //skip this object continue; } //yes continue whatever we need to do AddEnemy((*enemyIterator)); } std::vector<Objects*>::iterator flamethrowerIterator; for(flamethrowerIterator = (*loadedIterator)->_mFlameThrowerList.begin(); flamethrowerIterator!=(*loadedIterator)->_mFlameThrowerList.end(); flamethrowerIterator++) { //no //is this object inside the load radius? if(!IsObjectInsideRadius((*flamethrowerIterator), ENEMY_LOADRADIUS)) { //no //skip this object continue; } //yes continue whatever we need to do AddFlameThrower((*flamethrowerIterator)); } } }
BOOL KRegion::LoadTerrainData(const char cszFileName[], KObjAlloctor& rObjectAlloctor) { BOOL bResult = false; BOOL bRetCode = false; IFile* piFile = NULL; IKG_Buffer* piBuffer = NULL; BYTE* pbyBuffer = NULL; size_t uFileSize = 0; size_t uReadBytes = 0; size_t uLeftBytes = 0; BYTE* pbyOffset = NULL; KRegionHeader* pFileHeader = NULL; size_t uBaseCellInfoSize = sizeof(KCell::KBaseInfo) + sizeof(WORD); KCell* pAllocCell = NULL; int nExtCellCount = 0; size_t uExtCellInfoSize = sizeof(int) * 2 + sizeof(KCell::KBaseInfo) + sizeof(WORD) * 2; piFile = g_OpenFile(cszFileName); KGLOG_PROCESS_ERROR(piFile); uFileSize = piFile->Size(); KGLOG_PROCESS_ERROR(uFileSize > 0); piBuffer = KG_MemoryCreateBuffer((unsigned)uFileSize); KGLOG_PROCESS_ERROR(piBuffer); pbyBuffer = (BYTE*)piBuffer->GetData(); KGLOG_PROCESS_ERROR(pbyBuffer); uReadBytes = piFile->Read(pbyBuffer, (unsigned long)uFileSize); KGLOG_PROCESS_ERROR(uReadBytes == uFileSize); KG_COM_RELEASE(piFile); pbyOffset = pbyBuffer; uLeftBytes = uReadBytes; KGLOG_PROCESS_ERROR(uLeftBytes >= sizeof(KRegionHeader)); pFileHeader = (KRegionHeader*)pbyOffset; pbyOffset += sizeof(KRegionHeader); uLeftBytes -= sizeof(KRegionHeader); KGLOG_PROCESS_ERROR(pFileHeader->nRegionX == m_nRegionX); KGLOG_PROCESS_ERROR(pFileHeader->nRegionY == m_nRegionY); KGLOG_PROCESS_ERROR(uLeftBytes >= uBaseCellInfoSize * REGION_GRID_WIDTH * REGION_GRID_HEIGHT); uLeftBytes -= uBaseCellInfoSize * REGION_GRID_WIDTH * REGION_GRID_HEIGHT; for (int nCellY = 0; nCellY < REGION_GRID_HEIGHT; nCellY++) { for (int nCellX = 0; nCellX < REGION_GRID_WIDTH; nCellX++) { KCell* pCell = &m_Cells[nCellX][nCellY]; KCell::KBaseInfo* pBaseInfo = (KCell::KBaseInfo*)pbyOffset; pCell->m_BaseInfo = *pBaseInfo; pCell->m_wLowLayer = 0; pbyOffset += sizeof(KCell::KBaseInfo); pCell->m_wHighLayer = *(WORD*)pbyOffset; pbyOffset += sizeof(WORD); } } KGLOG_PROCESS_ERROR(uLeftBytes >= sizeof(int)); uLeftBytes -= sizeof(int); nExtCellCount = *(int*)pbyOffset; pbyOffset += sizeof(int); KGLOG_PROCESS_ERROR(nExtCellCount >= 0); KGLOG_PROCESS_ERROR(uLeftBytes >= uExtCellInfoSize * nExtCellCount); uLeftBytes -= uExtCellInfoSize * nExtCellCount; for (int nIndex = 0; nIndex < nExtCellCount; nIndex++) { int nCellX = 0; int nCellY = 0; KCell::KBaseInfo* pBaseInfo = NULL; pAllocCell = rObjectAlloctor.NewCell(); KGLOG_PROCESS_ERROR(pAllocCell); nCellX = *(int*)pbyOffset; pbyOffset += sizeof(int); nCellY = *(int*)pbyOffset; pbyOffset += sizeof(int); pBaseInfo = (KCell::KBaseInfo*)pbyOffset; pbyOffset += sizeof(KCell::KBaseInfo); pAllocCell->m_BaseInfo = *pBaseInfo; pAllocCell->m_wHighLayer = *(WORD*)pbyOffset; pbyOffset += sizeof(WORD); pAllocCell->m_wLowLayer = *(WORD*)pbyOffset; pbyOffset += sizeof(WORD); bRetCode = AddObstacle(nCellX, nCellY, pAllocCell); KGLOG_PROCESS_ERROR(bRetCode); pAllocCell = NULL; } if (uLeftBytes >= sizeof(m_dwScriptList)) { memcpy(m_dwScriptList, pbyOffset, sizeof(m_dwScriptList)); pbyOffset += sizeof(m_dwScriptList); uLeftBytes -= sizeof(m_dwScriptList); } KGLOG_PROCESS_ERROR(uLeftBytes == 0); bResult = true; Exit0: if (pAllocCell) { rObjectAlloctor.DeleteCell(pAllocCell); pAllocCell = NULL; } KG_COM_RELEASE(piBuffer); KG_COM_RELEASE(piFile); return bResult; }