Ejemplo n.º 1
0
bool AiLocation::validate ( void ) const
{
	NAN_CHECK(m_position_p);
	NAN_CHECK(m_radius);
	NAN_CHECK(m_offset_p);

	TerrainObject * terrain = TerrainObject::getInstance();

	if(terrain == NULL) return true;

	float w = terrain->getMapWidthInMeters() / 2.0f;

	bool valid = true;
	
	valid &= (m_position_p.x <=  w);
	valid &= (m_position_p.x >= -w);

	valid &= (m_position_p.z <=  w);
	valid &= (m_position_p.z >= -w);

	float dist2 = getPosition_w().magnitudeSquared();

	valid &= (dist2 >= 9.0f);

	if(!valid)
	{
		DEBUG_WARNING(ConfigServerGame::getReportAiWarnings(),("AiLocation::validate - Location (%f,%f,%f) is OOW or too near the origin - terrain size %fx%f\n",m_position_p.x,m_position_p.y,m_position_p.z,w*2.0f,w*2.0f));
	}

	return valid;
}
	// 新建场景
	void TerrainEditorPlugin::onNewScene(IScene *scene)
	{
		// 找到所有地形,激活之
		IScene::SceneObjectIterator iter = scene->getSceneObjectIterator();
		while(iter.hasMoreElements())
		{
			ISceneObject *obj = iter.getNext();
			if(obj->getType() == TerrainObjectFactory::FACTORY_TYPE)
			{
				TerrainObject *terrain = static_cast<TerrainObject*>(obj);
				activateTerrain(terrain->getOgreTerrain());
			}
		}
	}
bool Ned3DObjectManager::interactEnemyTerrain(EnemyObject &enemy, TerrainObject &terrain)
{
  Terrain *terr = terrain.getTerrain();
  if(terr == NULL) return false;

  //test for enemy collision with terrain
  Vector3 enemyPos = enemy.getPosition();
    
  float terrainHeight = terr->getHeight(enemyPos.x,enemyPos.z);
  if (enemyPos.y < terrainHeight)
  {
    enemyPos.y = terrainHeight;
    //enemy.setPPosition(enemyPos);       
    int tmpHndl = gParticle.createSystem("enemyfeatherssplat");
    gParticle.setSystemPos(tmpHndl, enemyPos);

    int thumpSound = gSoundManager.requestSoundHandle("Thump.wav");
    int instance = gSoundManager.requestInstance(thumpSound);
     if(thumpSound != SoundManager::NOINSTANCE)
  {
    gSoundManager.setPosition(thumpSound,instance,enemyPos);
    gSoundManager.play(thumpSound,instance);
    gSoundManager.releaseInstance(thumpSound,instance);
  }
    
    enemy.killObject();

    return true;
  }
  return false;
}
Ejemplo n.º 4
0
bool Ned3DObjectManager::interactCrowTerrain(CrowObject &crow, TerrainObject &terrain)
{
  Terrain *terr = terrain.getTerrain();
  if(terr == NULL) return false;

  //test for crow collision with terrain
  Vector3 crowPos = crow.getPosition();
    
  float terrainHeight = terr->getHeight(crowPos.x,crowPos.z);
  if (crowPos.y < terrainHeight)
  {
    crowPos.y = terrainHeight;
    crow.setPosition(crowPos);       
    int tmpHndl = gParticle.createSystem("crowfeatherssplat");
    gParticle.setSystemPos(tmpHndl, crowPos);

    int thumpSound = gSoundManager.requestSoundHandle("Thump.wav");
    int instance = gSoundManager.requestInstance(thumpSound);
     if(thumpSound != SoundManager::NOINSTANCE)
  {
    gSoundManager.setPosition(thumpSound,instance,crowPos);
    gSoundManager.play(thumpSound,instance);
    gSoundManager.releaseInstance(thumpSound,instance);
  }
    
    crow.killObject();

    return true;
  }
  return false;
}
Ejemplo n.º 5
0
TerrainObject *Terrain::obj_at_point(const coord::phys3 &point) {
	coord::tile t = point.to_tile3().to_tile();
	TileContent *tc = this->get_data(t);
	if (!tc) {
		return nullptr;
	}


	// prioritise selecting the smallest object
	TerrainObject *smallest = nullptr;
	for (auto obj_ptr : tc->obj) {
		if (obj_ptr->contains(point) &&
		    (!smallest || obj_ptr->min_axis() < smallest->min_axis())) {
			smallest = obj_ptr;
		}
	}
	return smallest;
}
	// 保存场景
	void TerrainEditorPlugin::onPreSaveScene(const String &fileName ,IScene *scene)
	{
		// 找到所有地形,保存之
		IScene::SceneObjectIterator iter = scene->getSceneObjectIterator();
		while(iter.hasMoreElements())
		{
			ISceneObject *obj = iter.getNext();
			if(obj->getType() == TerrainObjectFactory::FACTORY_TYPE)
			{
				TerrainObject *terrain = static_cast<TerrainObject*>(obj);

				String outBasename;
				String outExtention; 
				String outPath;
				StringUtil::splitFullFilename(fileName , outBasename , outExtention , outPath);
				removeTerrainBlockerPass(terrain->getOgreTerrain());
				terrain->save(outBasename);
				addTerrainBlockerPass(terrain->getOgreTerrain());
			}
		}
	}
Ejemplo n.º 7
0
void QuadtreeNode::ComputeBoundingBox(const vec3* vertices)
{
	assert(vertices);

	m_BBox.min.y = 100000.0f;
	m_BBox.max.y = -100000.0f;

	if(m_pTerrainChunk) {
		std::vector<GLuint>& tIndices = m_pTerrainChunk->getIndiceArray(0);

		for(GLuint i=0; i<tIndices.size(); i++) {
			vec3 vertex = vertices[ tIndices[i] ];

			if(vertex.y > m_BBox.max.y)	m_BBox.max.y = vertex.y;
			if(vertex.y < m_BBox.min.y)	m_BBox.min.y = vertex.y;
		}

		for(GLuint i=0; i<m_pTerrainChunk->getObjectsArray().size(); i++) {
			TerrainObject* obj = m_pTerrainChunk->getObjectsArray()[ i ];
			Mesh* mesh = obj->getMesh(0);
			BoundingBox bbox = mesh->getBoundingBox();
			bbox.Translate( obj->getPosition() );

			m_BBox.Add( bbox );
		}
	}

	// De la même facon, on traite les fils
	if(m_pChildren) {
		for(int i=0; i<4; i++) {
			m_pChildren[i].ComputeBoundingBox(vertices);

			if(m_BBox.min.y > m_pChildren[i].m_BBox.min.y)	m_BBox.min.y = m_pChildren[i].m_BBox.min.y;
			if(m_BBox.max.y < m_pChildren[i].m_BBox.max.y)	m_BBox.max.y = m_pChildren[i].m_BBox.max.y;
		}
	}
}
bool Ned3DObjectManager::interactPlaneTerrain(PlaneObject &plane, TerrainObject &terrain)
{
  Terrain *terr = terrain.getTerrain();
  if(terr == NULL) return false;

  //test for plane collision with terrain
  Vector3 planePos = plane.getPosition();
  EulerAngles planeOrient = plane.getOrientation();
  Vector3 disp = planePos - disp;
  RotationMatrix planeMatrix;
  planeMatrix.setup(plane.getOrientation()); // get plane's orientation

  float planeBottom = plane.getBoundingBox().min.y;
  float terrainHeight = terr->getHeight(planePos.x,planePos.z);
  if(plane.isPlaneAlive() && planeBottom < terrainHeight)
  { //collision
    Vector3 viewVector = planeMatrix.objectToInertial(Vector3(0,0,1));
    if(viewVector * terr->getNormal(planePos.x,planePos.z) < -0.5f // dot product
      || plane.isCrashing())
    { 
      plane.killPlane();
      int partHndl = gParticle.createSystem("planeexplosion");
      gParticle.setSystemPos(partHndl, plane.getPosition());
      int boomHndl = gSoundManager.requestSoundHandle("Boom.wav");
      int boomInst = gSoundManager.requestInstance(boomHndl);
      if(boomInst != SoundManager::NOINSTANCE)
      {
        gSoundManager.setPosition(boomHndl,boomInst,plane.getPosition());
        gSoundManager.play(boomHndl,boomInst);
        gSoundManager.releaseInstance(boomHndl,boomInst);
      }
      plane.setSpeed(0.0f);
      planePos += 2.0f * viewVector;
      planeOrient.pitch = kPi / 4.0f;
      planeOrient.bank = kPi / 4.0f;
      plane.setOrientation(planeOrient);
    }
    else planePos.y = terrainHeight + planePos.y - planeBottom;
    //plane.setPPosition(planePos);
    return true;
  }
  return false;
}
Ejemplo n.º 9
0
bool GameMain::on_input(SDL_Event *e) {
	Engine &engine = Engine::get();

	switch (e->type) {

	case SDL_QUIT:
		engine.stop();
		break;

	case SDL_MOUSEBUTTONDOWN: { //thanks C++! we need a separate scope because of new variables...

		// a mouse button was pressed...
		// subtract value from window height to get position relative to lower right (0,0).
		coord::window mousepos_window {(coord::pixel_t) e->button.x, (coord::pixel_t) e->button.y};
		coord::camgame mousepos_camgame = mousepos_window.to_camgame();
		// TODO once the terrain elevation milestone is implemented, use a method
		// more suitable for converting camgame to phys3
		coord::phys3 mousepos_phys3 = mousepos_camgame.to_phys3();
		coord::tile mousepos_tile = mousepos_phys3.to_tile3().to_tile();

		if (clicking_active and e->button.button == SDL_BUTTON_LEFT) {
			log::dbg("LMB [window]:    x %9hd y %9hd",
			         mousepos_window.x,
			         mousepos_window.y);
			log::dbg("LMB [camgame]:   x %9hd y %9hd",
			         mousepos_camgame.x,
			         mousepos_camgame.y);

			auto phys_per_tile = openage::coord::settings::phys_per_tile;
			log::dbg("LMB [phys3]:     NE %8.3f SE %8.3f UP %8.3f",
			         ((float) mousepos_phys3.ne) / phys_per_tile,
			         ((float) mousepos_phys3.se) / phys_per_tile,
			         ((float) mousepos_phys3.up) / phys_per_tile);
			log::dbg("LMB [tile]:      NE %8ld SE %8ld",
			         mousepos_tile.ne,
			         mousepos_tile.se);

			TerrainChunk *chunk = terrain->get_create_chunk(mousepos_tile);
			chunk->get_data(mousepos_tile)->terrain_id = editor_current_terrain;
		}
		else if (clicking_active and e->button.button == SDL_BUTTON_RIGHT) {

			// get chunk clicked on, don't create it if it's not there already
			// -> placing buildings in void is forbidden that way
			TerrainChunk *chunk = terrain->get_chunk(mousepos_tile);
			if (chunk == nullptr) {
				break;
			}

			// get object currently standing at the clicked position
			TerrainObject *obj = chunk->get_data(mousepos_tile)->obj;
			if (obj != nullptr) {
				obj->remove();
				this->placed_buildings.erase(obj);
				this->available_sounds[obj->sound_id_destruction].play();
				delete obj;
			} else {
				TestBuilding *newbuilding = this->available_buildings[this->editor_current_building];
				int coloring = util::random_range(1, 8 + 1);
				TerrainObject *newobj = new TerrainObject(
					newbuilding->texture,
					newbuilding->foundation_size,
					coloring,
					newbuilding->sound_id_destruction
				);

				// try to place the obj, it knows best whether it will fit.
				bool obj_placed = newobj->place(terrain, mousepos_tile);
				if (obj_placed) {
					this->available_sounds[newbuilding->sound_id_creation].play();
					this->placed_buildings.insert(newobj);

					if (newbuilding->foundation_terrain > 0) {
						// TODO: use the gamedata terrain lookup!
						newobj->set_ground(newbuilding->foundation_terrain, 0);
					}
				} else {
					delete newobj;
				}
			}
			break;
		}
		else if (not scrolling_active
		         and e->button.button == SDL_BUTTON_MIDDLE) {
			// activate scrolling
			SDL_SetRelativeMouseMode(SDL_TRUE);
			scrolling_active = true;

			// deactivate clicking as long as mousescrolling is active
			clicking_active = false;
		}
		break;
	}

	case SDL_MOUSEBUTTONUP:
		if (scrolling_active and e->button.button == SDL_BUTTON_MIDDLE) {
			// stop scrolling
			SDL_SetRelativeMouseMode(SDL_FALSE);
			scrolling_active = false;

			// reactivate mouse clicks as scrolling is over
			clicking_active = true;
		}
		break;

	case SDL_MOUSEMOTION:

		// scroll, if middle mouse is being pressed
		//  SDL_GetRelativeMouseMode() queries sdl for that.
		if (scrolling_active) {

			// move the cam
			coord::vec2f cam_movement {0.0, 0.0};
			cam_movement.x = e->motion.xrel;
			cam_movement.y = e->motion.yrel;

			// this factor controls the scroll speed
			// cam_movement *= 1;

			// calculate camera position delta from velocity and frame duration
			coord::camgame_delta cam_delta;
			cam_delta.x = cam_movement.x;
			cam_delta.y = - cam_movement.y;

			//update camera phys position
			engine.camgame_phys += cam_delta.to_phys3();
		}
		break;

	case SDL_MOUSEWHEEL:
		if (this->ctrl_active) {
			editor_current_building = util::mod<ssize_t>(editor_current_building + e->wheel.y, this->available_buildings.size());
		}
		else {
			editor_current_terrain = util::mod<ssize_t>(editor_current_terrain + e->wheel.y, this->terrain->terrain_id_count);
		}
		break;

	case SDL_KEYUP:
		switch (((SDL_KeyboardEvent *) e)->keysym.sym) {
		case SDLK_ESCAPE:
			//stop the game
			engine.stop();
			break;
		case SDLK_F1:
			engine.drawing_huds = !engine.drawing_huds;
			break;
		case SDLK_F3:
			engine.drawing_debug_overlay = !engine.drawing_debug_overlay;
			break;
		case SDLK_LCTRL:
			this->ctrl_active = false;
			break;
		}

		break;
	case SDL_KEYDOWN:
		switch (((SDL_KeyboardEvent *) e)->keysym.sym) {
		case SDLK_SPACE:
			this->terrain->blending_enabled = !terrain->blending_enabled;
			break;
		case SDLK_F2:
			engine.get_screenshot_manager().save_screenshot();
			break;
		case SDLK_LCTRL:
			this->ctrl_active = true;
			break;
		}

		break;
	}

	return true;
}