コード例 #1
0
//*******************************************************************************
Position HapticObject::getPosition()
{
	hduVector3Dd origin;
	hduVector3Dd pos(origin * m_transformMatrix);
	return Position(pos[0], pos[1], pos[2]);
}
コード例 #2
0
ファイル: Camera.cpp プロジェクト: jiangguang5201314/ZNginx
void CCamera::CheckForMovement()
{
    // Once we have the frame interval, we find the current speed
    float speed = (float)(kSpeed * g_FrameInterval);

    // Before we move our camera we want to store the old position.  We then use
    // this data to test collision detection.
    CVector3 vOldPosition = Position();


/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

    // Store the old view vector to restore it if we collided backwards
    CVector3 vOldView = View();

    // Use a flag to see if we movement backwards or not
    bool bMovedBack = false;

/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *


    // Check if we hit the Up arrow or the 'w' key
    if(GetKeyState(VK_UP) & 0x80 || GetKeyState('W') & 0x80)
    {

        // Move our camera forward by a positive SPEED
        MoveCamera(speed);
    }

    // Check if we hit the Down arrow or the 's' key
    if(GetKeyState(VK_DOWN) & 0x80 || GetKeyState('S') & 0x80)
    {

        // Move our camera backward by a negative SPEED
        MoveCamera(-speed);
        bMovedBack = true;
    }

    // Check if we hit the Left arrow or the 'a' key
    if(GetKeyState(VK_LEFT) & 0x80 || GetKeyState('A') & 0x80)
    {

        // Strafe the camera left
        StrafeCamera(-speed);
    }

    // Check if we hit the Right arrow or the 'd' key
    if(GetKeyState(VK_RIGHT) & 0x80 || GetKeyState('D') & 0x80)
    {

        // Strafe the camera right
        StrafeCamera(speed);
    }

    // Now that we moved, let's get the current position and test our movement
    // vector against the level data to see if there is a collision.
    CVector3 vCurrentPosition = Position();

    // We will not use sphere collision from now on, but AABB collision (box)
//	CVector3 vNewPosition = g_Level.TraceSphere(vOldPosition, vCurrentPosition, 25.0f);


/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

    // We are now using AABB collision now, so we no longer use sphere checks.
    // Below we pass into the TraceBox() function some generic Min and Max values
    // for our bounding box.  We then get the new position if we collided
    CVector3 vNewPosition = g_Level.TraceBox(vOldPosition, vCurrentPosition,
                            CVector3(-20, -50, -20), CVector3(20, 50, 20));

    // We add some code below to make it so when we back into a wall, our view vector
    // doesn't keep going backwards, since we aren't moving backwards.  If we don't
    // do this check, it will turn our camera around and look like a glitch.  Not desired!

    // Check if we collided and we moved backwards
    if(g_Level.Collided() && bMovedBack)
    {
        // If or x or y didn't move, then we are backed into a wall so restore the view vector
        if(vNewPosition.x == vOldPosition.x || vNewPosition.z == vOldPosition.z)
            m_vView = vOldView;
    }

/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *


    // Set the new position that was returned from our trace function
    m_vPosition = vNewPosition;
}
コード例 #3
0
ファイル: spawn.cpp プロジェクト: AhmedWaly/LiveCast
bool Spawns::parseSpawnNode(xmlNodePtr p, bool checkDuplicate)
{
	if(xmlStrcmp(p->name, (const xmlChar*)"spawn"))
		return false;

	int32_t intValue;
	std::string strValue;

	Position centerPos;
	if(!readXMLString(p, "centerpos", strValue))
	{
		if(!readXMLInteger(p, "centerx", intValue))
			return false;

		centerPos.x = intValue;
		if(!readXMLInteger(p, "centery", intValue))
			return false;

		centerPos.y = intValue;
		if(!readXMLInteger(p, "centerz", intValue))
			return false;

		centerPos.z = intValue;
	}
	else
	{
		IntegerVec posVec = vectorAtoi(explodeString(strValue, ","));
		if(posVec.size() < 3)
			return false;

		centerPos = Position(posVec[0], posVec[1], posVec[2]);
	}

	if(!readXMLInteger(p, "radius", intValue))
		return false;

	int32_t radius = intValue;
	Spawn* spawn = new Spawn(centerPos, radius);
	if(checkDuplicate)
	{
		for(SpawnList::iterator it = spawnList.begin(); it != spawnList.end(); ++it)
		{
			if((*it)->getPosition() == centerPos)
				delete *it;
		}
	}

	spawnList.push_back(spawn);
	for(xmlNodePtr tmpNode = p->children; tmpNode; tmpNode = tmpNode->next)
	{
		if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"monster"))
		{
			if(!readXMLString(tmpNode, "name", strValue))
				continue;

			std::string name = strValue;
			int32_t interval = MINSPAWN_INTERVAL / 1000;
			if(readXMLInteger(tmpNode, "spawntime", intValue) || readXMLInteger(tmpNode, "interval", intValue))
			{
				if(intValue <= interval)
				{
					std::clog << "[Warning - Spawns::loadFromXml] " << name << " " << centerPos << " spawntime cannot"
						<< " be less than " << interval << " seconds." << std::endl;
					continue;
				}

				interval = intValue;
			}

			interval *= 1000;
			Position placePos = centerPos;
			if(readXMLInteger(tmpNode, "x", intValue))
				placePos.x += intValue;

			if(readXMLInteger(tmpNode, "y", intValue))
				placePos.y += intValue;

			if(readXMLInteger(tmpNode, "z", intValue))
				placePos.z /*+*/= intValue;

			Direction direction = NORTH;
			if(readXMLInteger(tmpNode, "direction", intValue) && direction >= EAST && direction <= WEST)
				direction = (Direction)intValue;

			spawn->addMonster(name, placePos, direction, interval);
		}
		else if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"npc"))
		{
			if(!readXMLString(tmpNode, "name", strValue))
				continue;

			std::string name = strValue;
			Position placePos = centerPos;
			if(readXMLInteger(tmpNode, "x", intValue))
				placePos.x += intValue;

			if(readXMLInteger(tmpNode, "y", intValue))
				placePos.y += intValue;

			if(readXMLInteger(tmpNode, "z", intValue))
				placePos.z /*+*/= intValue;

			Direction direction = NORTH;
			if(readXMLInteger(tmpNode, "direction", intValue) && direction >= EAST && direction <= WEST)
				direction = (Direction)intValue;

			Npc* npc = Npc::createNpc(name);
			if(!npc)
				continue;

			npc->setMasterPosition(placePos, radius);
			npc->setDirection(direction);
			npcList.push_back(npc);
		}
	}

	return true;
}
コード例 #4
0
/* Test the method 'move2side'*/
TEST_F(PositionVectorTest, test_method_move2side) {	
    PositionVector vec1;
    vec1.push_back(Position(0,1,0));
    vec1.push_back(Position(0,0,0));
    vec1.push_back(Position(1,0,0));
    vec1.move2side(.5);
    EXPECT_EQ(Position(-.5,1), vec1[0]);
    EXPECT_EQ(Position(-.5,-.5), vec1[1]);
    EXPECT_EQ(Position(1,-.5), vec1[2]);
    vec1.move2side(-1);
    EXPECT_EQ(Position(.5,1), vec1[0]);
    EXPECT_EQ(Position(.5,.5), vec1[1]);
    EXPECT_EQ(Position(1,.5), vec1[2]);

    // parallel case
    PositionVector vec2;
    vec2.push_back(Position(0,0,0));
    vec2.push_back(Position(1,0,0));
    vec2.push_back(Position(3,0,0));
    vec2.move2side(.5);
    EXPECT_EQ(Position(0,-.5), vec2[0]);
    EXPECT_EQ(Position(1,-.5), vec2[1]);
    EXPECT_EQ(Position(3,-.5), vec2[2]);
    vec2.move2side(-1);
    EXPECT_EQ(Position(0,.5), vec2[0]);
    EXPECT_EQ(Position(1,.5), vec2[1]);
    EXPECT_EQ(Position(3,.5), vec2[2]);

    // counterparallel case
    {
    PositionVector vec3;
    vec3.push_back(Position(0,0,0));
    vec3.push_back(Position(3,0,0));
    vec3.push_back(Position(1,0,0));
    vec3.move2side(.5);
    EXPECT_EQ(Position(0,-.5), vec3[0]);
    EXPECT_EQ(Position(3.5,0), vec3[1]);
    EXPECT_EQ(Position(1,.5), vec3[2]);
    }
    /*{
    PositionVector vec3;
    vec3.push_back(Position(0,0,0));
    vec3.push_back(Position(3,0,0));
    vec3.push_back(Position(1,0,0));
    vec3.move2side(-.5);
    EXPECT_EQ(Position(0,-.5), vec3[0]);
    EXPECT_EQ(Position(3.5,0), vec3[1]);
    EXPECT_EQ(Position(1,.5), vec3[2]);
    }*/
}
コード例 #5
0
/* Test the method 'distance'*/
TEST_F(PositionVectorTest, test_method_distance) {	
    {
        PositionVector vec1;
        vec1.push_back(Position(1,0));
        vec1.push_back(Position(10,0));
        vec1.push_back(Position(10,5));
        vec1.push_back(Position(20,5));
        Position on(4,0);
        Position left(4,1);
        Position right(4,-1);
        Position left2(4,2);
        Position right2(4,-2);
        Position cornerRight(13,-4);
        Position cornerLeft(7,9);
        Position before(-3,-3);
        Position beyond(24,8);

        EXPECT_EQ(0,  vec1.distance(on));
        EXPECT_EQ(1,  vec1.distance(left));
        EXPECT_EQ(1,  vec1.distance(right));
        EXPECT_EQ(2,  vec1.distance(left2));
        EXPECT_EQ(2,  vec1.distance(right2));
        EXPECT_EQ(5,  vec1.distance(cornerRight));
        EXPECT_EQ(5,  vec1.distance(cornerLeft));

        EXPECT_EQ(GeomHelper::INVALID_OFFSET,  vec1.distance(before, true));
        EXPECT_EQ(GeomHelper::INVALID_OFFSET,  vec1.distance(beyond, true));
        EXPECT_EQ(5,  vec1.distance(before));
        EXPECT_EQ(5,  vec1.distance(beyond));
    }

    { 
        PositionVector vec1; // the same tests as before, mirrored on x-axis
        vec1.push_back(Position(1,0));
        vec1.push_back(Position(10,0));
        vec1.push_back(Position(10,-5));
        vec1.push_back(Position(20,-5));
        Position on(4,0);
        Position left(4,-1);
        Position right(4,1);
        Position left2(4,-2);
        Position right2(4,2);
        Position cornerRight(13,4);
        Position cornerLeft(7,-9);
        Position before(-3,3);
        Position beyond(24,-8);

        EXPECT_EQ(0,  vec1.distance(on));
        EXPECT_EQ(1,  vec1.distance(left));
        EXPECT_EQ(1,  vec1.distance(right));
        EXPECT_EQ(2,  vec1.distance(left2));
        EXPECT_EQ(2,  vec1.distance(right2));
        EXPECT_EQ(5,  vec1.distance(cornerRight));
        EXPECT_EQ(5,  vec1.distance(cornerLeft));

        EXPECT_EQ(GeomHelper::INVALID_OFFSET,  vec1.distance(before, true));
        EXPECT_EQ(GeomHelper::INVALID_OFFSET,  vec1.distance(beyond, true));
        EXPECT_EQ(5,  vec1.distance(before));
        EXPECT_EQ(5,  vec1.distance(beyond));
    }
}
コード例 #6
0
NS_IMETHODIMP
HTMLProgressElement::GetPosition(double* aPosition)
{
  *aPosition = Position();
  return NS_OK;
}
コード例 #7
0
ファイル: spawn.cpp プロジェクト: Alexo25/forgottenserver
bool Spawns::loadFromXml(const std::string& _filename)
{
	if (loaded) {
		return true;
	}

	pugi::xml_document doc;
	pugi::xml_parse_result result = doc.load_file(_filename.c_str());
	if (!result) {
		printXMLError("Error - Spawns::loadFromXml", _filename, result);
		return false;
	}

	filename = _filename;
	loaded = true;

	for (auto spawnNode : doc.child("spawns").children()) {
		Position centerPos(
			pugi::cast<uint16_t>(spawnNode.attribute("centerx").value()),
			pugi::cast<uint16_t>(spawnNode.attribute("centery").value()),
			pugi::cast<uint16_t>(spawnNode.attribute("centerz").value())
		);

		int32_t radius;
		pugi::xml_attribute radiusAttribute = spawnNode.attribute("radius");
		if (radiusAttribute) {
			radius = pugi::cast<int32_t>(radiusAttribute.value());
		} else {
			radius = -1;
		}

		spawnList.emplace_front(centerPos, radius);
		Spawn& spawn = spawnList.front();

		for (auto childNode : spawnNode.children()) {
			if (strcasecmp(childNode.name(), "monster") == 0) {
				pugi::xml_attribute nameAttribute = childNode.attribute("name");
				if (!nameAttribute) {
					continue;
				}

				Direction dir;

				pugi::xml_attribute directionAttribute = childNode.attribute("direction");
				if (directionAttribute) {
					dir = static_cast<Direction>(pugi::cast<uint16_t>(directionAttribute.value()));
				} else {
					dir = DIRECTION_NORTH;
				}

				Position pos(
					centerPos.x + pugi::cast<uint16_t>(childNode.attribute("x").value()),
					centerPos.y + pugi::cast<uint16_t>(childNode.attribute("y").value()),
					centerPos.z
				);
				uint32_t interval = pugi::cast<uint32_t>(childNode.attribute("spawntime").value()) * 1000;
				if (interval > MINSPAWN_INTERVAL) {
					spawn.addMonster(nameAttribute.as_string(), pos, dir, interval);
				} else {
					std::cout << "[Warning - Spawns::loadFromXml] " << nameAttribute.as_string() << ' ' << pos << " spawntime can not be less than " << MINSPAWN_INTERVAL / 1000 << " seconds." << std::endl;
				}
			} else if (strcasecmp(childNode.name(), "npc") == 0) {
				pugi::xml_attribute nameAttribute = childNode.attribute("name");
				if (!nameAttribute) {
					continue;
				}

				Npc* npc = Npc::createNpc(nameAttribute.as_string());
				if (!npc) {
					continue;
				}

				pugi::xml_attribute directionAttribute = childNode.attribute("direction");
				if (directionAttribute) {
					npc->setDirection(static_cast<Direction>(pugi::cast<uint16_t>(directionAttribute.value())));
				}

				npc->setMasterPos(Position(
					centerPos.x + pugi::cast<uint16_t>(childNode.attribute("x").value()),
					centerPos.y + pugi::cast<uint16_t>(childNode.attribute("y").value()),
					centerPos.z
				), radius);
				npcList.push_front(npc);
			}
		}
	}
	return true;
}
コード例 #8
0
ファイル: monster.cpp プロジェクト: milbradt/TFS
bool Monster::getDanceStep(const Position& creaturePos, Direction& dir,	bool keepAttack /*= true*/, bool keepDistance /*= true*/)
{
	assert(attackedCreature);
	bool canDoAttackNow = canUseAttack(creaturePos, attackedCreature);
	const Position& centerPos = attackedCreature->getPosition();

	uint32_t tmpDist, centerToDist = std::max(std::abs(creaturePos.x - centerPos.x), std::abs(creaturePos.y - centerPos.y));
	DirVector dirVector;
	if(!keepDistance || creaturePos.y - centerPos.y >= 0)
	{
		tmpDist = std::max(std::abs((creaturePos.x) - centerPos.x), std::abs((creaturePos.y - 1) - centerPos.y));
		if(tmpDist == centerToDist && canWalkTo(creaturePos, NORTH))
		{
			bool result = true;
			if(keepAttack)
				result = (!canDoAttackNow || canUseAttack(Position(creaturePos.x, creaturePos.y - 1, creaturePos.z), attackedCreature));

			if(result)
				dirVector.push_back(NORTH);
		}
	}

	if(!keepDistance || creaturePos.y - centerPos.y <= 0)
	{
		tmpDist = std::max(std::abs((creaturePos.x) - centerPos.x), std::abs((creaturePos.y + 1) - centerPos.y));
		if(tmpDist == centerToDist && canWalkTo(creaturePos, SOUTH))
		{
			bool result = true;
			if(keepAttack)
				result = (!canDoAttackNow || canUseAttack(Position(creaturePos.x, creaturePos.y + 1, creaturePos.z), attackedCreature));

			if(result)
				dirVector.push_back(SOUTH);
		}
	}

	if(!keepDistance || creaturePos.x - centerPos.x >= 0)
	{
		tmpDist = std::max(std::abs((creaturePos.x + 1) - centerPos.x), std::abs((creaturePos.y) - centerPos.y));
		if(tmpDist == centerToDist && canWalkTo(creaturePos, EAST))
		{
			bool result = true;
			if(keepAttack)
				result = (!canDoAttackNow || canUseAttack(Position(creaturePos.x + 1, creaturePos.y, creaturePos.z), attackedCreature));

			if(result)
				dirVector.push_back(EAST);
		}
	}

	if(!keepDistance || creaturePos.x - centerPos.x <= 0)
	{
		tmpDist = std::max(std::abs((creaturePos.x - 1) - centerPos.x), std::abs((creaturePos.y) - centerPos.y));
		if(tmpDist == centerToDist && canWalkTo(creaturePos, WEST))
		{
			bool result = true;
			if(keepAttack)
				result = (!canDoAttackNow || canUseAttack(Position(creaturePos.x - 1, creaturePos.y, creaturePos.z), attackedCreature));

			if(result)
				dirVector.push_back(WEST);
		}
	}

	if(dirVector.empty())
		return false;

	std::random_shuffle(dirVector.begin(), dirVector.end());
	dir = dirVector[random_range(0, dirVector.size() - 1)];
	return true;
}
コード例 #9
0
ファイル: 025_subroutines.cpp プロジェクト: xdray/oglplus
	void Render(double time)
	{
		gl.Clear().ColorBuffer().DepthBuffer();
		//
		auto camera = CamMatrixf::Orbiting(
			Vec3f(0.0, 1.5, 0.0),
			7.0 + SineWave(time / 11.0)*1.5,
			FullCircles(time / 19.0),
			Degrees(SineWave(time / 20.0) * 30 + 35)
		);
		cube_prog.camera_matrix = camera;
		cube_prog.camera_position = camera.Position();


		// shiny gray/blue checkered cube
		cube_prog.frag_subroutines.Apply(cube_prog.frag_shiny_checker);

		cube_prog.specular_factor = 32;
		cube_prog.color_1 = Vec3f(0.9, 0.8, 0.7);
		cube_prog.color_2 = Vec3f(0.3, 0.4, 0.5);
		cube_prog.tex_scale = Vec2f(4, 4);
		cube_prog.model_matrix =
			ModelMatrixf::RotationY(FullCircles(time / 7.0))*
			ModelMatrixf::Translation( 2.0, 0.0, 0.0)*
			ModelMatrixf::RotationX(Degrees(25 * time));
		cube.Draw();

		// shiny textured cube
		cube_prog.frag_subroutines.Apply(cube_prog.frag_shiny_texture);

		cube_prog.specular_factor = 16;
		cube_prog.tex_scale = Vec2f(1, 1);
		cube_prog.model_matrix =
			ModelMatrixf::RotationY(FullCircles(time / 7.0))*
			ModelMatrixf::Translation(-2.0, 0.0, 0.0)*
			ModelMatrixf::RotationX(Degrees(-17 * time));
		cube.Draw();

		// shiny yellow/black striped cube
		cube_prog.frag_subroutines.Apply(cube_prog.frag_shiny_strips);

		cube_prog.specular_factor = 32;
		cube_prog.color_1 = Vec3f(0.9, 0.9, 0.1);
		cube_prog.color_2 = Vec3f(0.1, 0.1, 0.1);
		cube_prog.tex_scale = Vec2f(16, 16);
		cube_prog.model_matrix =
			ModelMatrixf::RotationY(FullCircles(time / 7.0))*
			ModelMatrixf::Translation( 0.0, 2.0, 0.0)*
			ModelMatrixf::RotationY(Degrees(37 * time));
		cube.Draw();

		// shiny gray/green spiral cube
		cube_prog.frag_subroutines.Apply(cube_prog.frag_shiny_spiral);

		cube_prog.specular_factor = 24;
		cube_prog.color_1 = Vec3f(0.9, 0.9, 0.9);
		cube_prog.color_2 = Vec3f(0.4, 0.9, 0.4);
		cube_prog.tex_scale = Vec2f(1, 1);
		cube_prog.model_matrix =
			ModelMatrixf::RotationY(FullCircles(time / 7.0))*
			ModelMatrixf::Translation( 0.0,-2.0, 0.0)*
			ModelMatrixf::RotationY(Degrees(-13 * time));
		cube.Draw();

		// dull white/red striped cube
		cube_prog.frag_subroutines
			.Assign(
				cube_prog.pixel_light_func,
				cube_prog.dull
			).Assign(
				cube_prog.pixel_color_func,
				cube_prog.strips
			).Apply();

		cube_prog.specular_factor = 32;
		cube_prog.color_2 = Vec3f(1.0, 1.0, 1.0);
		cube_prog.color_1 = Vec3f(0.9, 0.2, 0.2);
		cube_prog.tex_scale = Vec2f(8, 6);
		cube_prog.model_matrix =
			ModelMatrixf::RotationY(FullCircles(time / 7.0))*
			ModelMatrixf::Translation( 0.0, 0.0, 2.0)*
			ModelMatrixf::RotationZ(Degrees(27 * time));
		cube.Draw();

		// dull textured cube
		cube_prog.frag_subroutines
			.Assign(
				cube_prog.pixel_color_func,
				cube_prog.texture_bgr
			).Apply();

		cube_prog.tex_scale = Vec2f(1, 1);
		cube_prog.model_matrix =
			ModelMatrixf::RotationY(FullCircles(time / 7.0))*
			ModelMatrixf::Translation( 0.0, 0.0,-2.0)*
			ModelMatrixf::RotationZ(Degrees(-23 * time));
		cube.Draw();
	}
コード例 #10
0
ファイル: ExplosionBState.cpp プロジェクト: AndO3131/OpenXcom
/**
 * Calculates the effects of the explosion.
 */
void ExplosionBState::explode()
{
	bool terrainExplosion = false;
	SavedBattleGame *save = _parent->getSave();
	// after the animation is done, the real explosion/hit takes place
	if (_item)
	{
		if (!_unit && _item->getPreviousOwner())
		{
			_unit = _item->getPreviousOwner();
		}

		BattleUnit *victim = 0;

		if (_areaOfEffect)
		{
			save->getTileEngine()->explode(_center, _power, _item->getRules()->getDamageType(), _item->getRules()->getExplosionRadius(), _unit);
		}
		else if (!_cosmetic)
		{
			ItemDamageType type = _item->getRules()->getDamageType();

			victim = save->getTileEngine()->hit(_center, _power, type, _unit);
		}
		// check if this unit turns others into zombies
		if (!_item->getRules()->getZombieUnit().empty()
			&& victim
			&& victim->getArmor()->getSize() == 1
			&& (victim->getGeoscapeSoldier() || victim->getUnitRules()->getRace() == "STR_CIVILIAN")
			&& victim->getSpawnUnit().empty())
		{
			// converts the victim to a zombie on death
			victim->setRespawn(true);
			victim->setSpawnUnit(_item->getRules()->getZombieUnit());
		}
	}
	if (_tile)
	{
		ItemDamageType DT;
		switch (_tile->getExplosiveType())
		{
		case 0:
			DT = DT_HE;
			break;
		case 5:
			DT = DT_IN;
			break;
		case 6:
			DT = DT_STUN;
			break;
		default:
			DT = DT_SMOKE;
			break;
		}
		if (DT != DT_HE)
		{
			_tile->setExplosive(0,0,true);
		}
		save->getTileEngine()->explode(_center, _power, DT, _power/10);
		terrainExplosion = true;
	}
	if (!_tile && !_item)
	{
		int radius = 6;
		// explosion not caused by terrain or an item, must be by a unit (cyberdisc)
		if (_unit && (_unit->getSpecialAbility() == SPECAB_EXPLODEONDEATH || _unit->getSpecialAbility() == SPECAB_BURN_AND_EXPLODE))
		{
			radius = _parent->getMod()->getItem(_unit->getArmor()->getCorpseGeoscape(), true)->getExplosionRadius();
		}
		save->getTileEngine()->explode(_center, _power, DT_HE, radius);
		terrainExplosion = true;
	}

	if (!_cosmetic)
	{
		// now check for new casualties
		_parent->checkForCasualties(_item, _unit, false, terrainExplosion);
	}

	// if this explosion was caused by a unit shooting, now it's the time to put the gun down
	if (_unit && !_unit->isOut() && _lowerWeapon)
	{
		_unit->aim(false);
		_unit->setCache(0);
	}
	_parent->getMap()->cacheUnits();
	_parent->popState();

	// check for terrain explosions
	Tile *t = save->getTileEngine()->checkForTerrainExplosions();
	if (t)
	{
		Position p = Position(t->getPosition().x * 16, t->getPosition().y * 16, t->getPosition().z * 24);
		p += Position(8,8,0);
		_parent->statePushFront(new ExplosionBState(_parent, p, 0, _unit, t));
	}

	if (_item && (_item->getRules()->getBattleType() == BT_GRENADE || _item->getRules()->getBattleType() == BT_PROXIMITYGRENADE))
	{
		_parent->getSave()->removeItem(_item);
	}
}
コード例 #11
0
ファイル: ExplosionBState.cpp プロジェクト: AndO3131/OpenXcom
/**
 * Initializes the explosion.
 * The animation and sound starts here.
 * If the animation is finished, the actual effect takes place.
 */
void ExplosionBState::init()
{
	if (_item)
	{
		_power = _item->getRules()->getPower();

		// this usually only applies to melee, but as a concession for modders i'll leave it here in case they wanna make bows or something.
		if (_item->getRules()->isStrengthApplied() && _unit)
		{
			_power += _unit->getBaseStats()->strength;
		}

		_areaOfEffect = _item->getRules()->getBattleType() != BT_MELEE &&
						_item->getRules()->getExplosionRadius() != 0 &&
						!_cosmetic;
	}
	else if (_tile)
	{
		_power = _tile->getExplosive();
		_areaOfEffect = true;
	}
	else if (_unit && (_unit->getSpecialAbility() == SPECAB_EXPLODEONDEATH || _unit->getSpecialAbility() == SPECAB_BURN_AND_EXPLODE))
	{
		_power = _parent->getMod()->getItem(_unit->getArmor()->getCorpseGeoscape(), true)->getPower();
		_areaOfEffect = true;
	}
	else
	{
		_power = 120;
		_areaOfEffect = true;
	}

	Tile *t = _parent->getSave()->getTile(Position(_center.x/16, _center.y/16, _center.z/24));
	if (_areaOfEffect)
	{
		if (_power)
		{
			int frame = Mod::EXPLOSION_OFFSET;
			if (_item)
			{
				frame = _item->getRules()->getHitAnimation();
			}
			if (_parent->getDepth() > 0)
			{
				frame -= Explosion::EXPLODE_FRAMES;
			}
			int frameDelay = 0;
			int counter = std::max(1, (_power/5) / 5);
			_parent->getMap()->setBlastFlash(true);
			int lowerLimit = std::max(1, _power/5);
			for (int i = 0; i < lowerLimit; i++)
			{
				int X = RNG::generate(-_power/2,_power/2);
				int Y = RNG::generate(-_power/2,_power/2);
				Position p = _center;
				p.x += X; p.y += Y;
				Explosion *explosion = new Explosion(p, frame, frameDelay, true);
				// add the explosion on the map
				_parent->getMap()->getExplosions()->push_back(explosion);
				if (i > 0 && i % counter == 0)
				{
					frameDelay++;
				}
			}
			_parent->setStateInterval(BattlescapeState::DEFAULT_ANIM_SPEED/2);
			// explosion sound
			if (_power <= 80)
				_parent->getMod()->getSoundByDepth(_parent->getDepth(), Mod::SMALL_EXPLOSION)->play();
			else
				_parent->getMod()->getSoundByDepth(_parent->getDepth(), Mod::LARGE_EXPLOSION)->play();

			_parent->getMap()->getCamera()->centerOnPosition(t->getPosition(), false);
		}
		else
		{
			_parent->popState();
		}
	}
	else
	// create a bullet hit
	{
		_parent->setStateInterval(std::max(1, ((BattlescapeState::DEFAULT_ANIM_SPEED/2) - (10 * _item->getRules()->getExplosionSpeed()))));
		int anim = _item->getRules()->getHitAnimation();
		int sound = _item->getRules()->getHitSound();
		if (_cosmetic) // Play melee animation on hitting and psiing
		{
			anim = _item->getRules()->getMeleeAnimation();
		}

		if (anim != -1)
		{
			Explosion *explosion = new Explosion(_center, anim, 0, false, _cosmetic);
			_parent->getMap()->getExplosions()->push_back(explosion);
		}

		_parent->getMap()->getCamera()->setViewLevel(_center.z / 24);

		BattleUnit *target = t->getUnit();
		if (_cosmetic && _parent->getSave()->getSide() == FACTION_HOSTILE && target && target->getFaction() == FACTION_PLAYER)
		{
			_parent->getMap()->getCamera()->centerOnPosition(t->getPosition(), false);
		}
		if (sound != -1 && !_cosmetic)
		{
			// bullet hit sound
			_parent->getMod()->getSoundByDepth(_parent->getDepth(), sound)->play(-1, _parent->getMap()->getSoundAngle(_center / Position(16,16,24)));
		}
	}
}
コード例 #12
0
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "InstanceScript.h"
#include "naxxramas.h"

BossBoundaryData const boundaries =
{
    /* Arachnid Quarter */
    { BOSS_ANUBREKHAN, new CircleBoundary(Position(3273.376709f, -3475.876709f), Position(3195.668213f, -3475.930176f)) },
    { BOSS_FAERLINA, new RectangleBoundary(3315.0f, 3402.0f, -3727.0f, -3590.0f) },
    { BOSS_FAERLINA, new CircleBoundary(Position(3372.68f, -3648.2f), Position(3316.0f, -3704.26f)) },
    { BOSS_MAEXXNA, new CircleBoundary(Position(3502.2587f, -3892.1697f), Position(3418.7422f, -3840.271f)) },

    /* Plague Quarter */
    { BOSS_NOTH, new RectangleBoundary(2618.0f, 2754.0f, -3557.43f, -3450.0f) },
    { BOSS_HEIGAN, new CircleBoundary(Position(2772.57f, -3685.28f), 56.0f) },
    { BOSS_LOATHEB, new CircleBoundary(Position(2909.0f, -3997.41f), 57.0f) },

    /* Military Quarter */
    { BOSS_RAZUVIOUS, new ZRangeBoundary(260.0f, 287.0f) }, // will not chase onto the upper floor
    { BOSS_GOTHIK, new RectangleBoundary(2627.0f, 2764.0f, -3440.0f, -3275.0f) },
    { BOSS_HORSEMEN, new ParallelogramBoundary(AreaBoundary::DoublePosition(2646.0, -2959.0), AreaBoundary::DoublePosition(2529.0, -3075.0), AreaBoundary::DoublePosition(2506.0, -2854.0)) },

    /* Construct Quarter */
コード例 #13
0
ファイル: physics.cpp プロジェクト: criptych/minengine
Physics::CollisionType Physics::checkCollision(
    const Body &a,
    const Body &b
) {
    const Position &pa = a.getPosition();
    const Position &pb = b.getPosition();
    const BoundingVolume &va = a.getBounds();
    const BoundingVolume &vb = b.getBounds();

    if (va.getType() == vb.getType()) {
        switch (va.getType()) {
            case BoundingVolume::AABB: {
                // box <-> box collision test
                Position minA = pa - Position(va.getDimensions());
                Position maxA = pa + Position(va.getDimensions());
                Position minB = pb - Position(vb.getDimensions());
                Position maxB = pb + Position(vb.getDimensions());

                if (
                    minA.x <= maxB.x + Epsilon && minA.y <= maxB.y + Epsilon && minA.z <= maxB.z + Epsilon &&
                    minB.x <= maxA.x + Epsilon && minB.y <= maxA.y + Epsilon && minB.z <= maxA.z + Epsilon
                ) {
                    if (
                        minA.x < maxB.x - Epsilon && minA.y < maxB.y - Epsilon && minA.z < maxB.z - Epsilon &&
                        minB.x < maxA.x - Epsilon && minB.y < maxA.y - Epsilon && minB.z < maxA.z - Epsilon
                    ) {
                        return CollisionType::Intrusion;
                    } else {
                        return CollisionType::Contact;
                    }
                } else {
                    return CollisionType::None;
                }
            }

            case BoundingVolume::Sphere: {
                // sphere <-> sphere collision test
                Position c = pb - pa;
                LargeDelta r = vb.getRadius() + va.getRadius();
                HugeDelta d = c.x * c.x + c.y * c.y + c.z * c.z - r * r;

                if (d >= Epsilon) {
                    return CollisionType::None;
                } else if (d > -Epsilon) {
                    return CollisionType::Contact;
                } else {
                    return CollisionType::Intrusion;
                }
            }

            case BoundingVolume::Capsule: {
                // capsule <-> capsule collision test
                Position c = pb - pa;
                LargeDelta r = vb.getRadius() + va.getRadius();
                //~ LargeDelta h = b.getHeight() + a.getHeight() - r;
                HugeDelta d = c.x * c.x + c.z * c.z - r * r;

                if (d >= Epsilon) {
                    // out of horizontal range, no need to check vertical
                    return CollisionType::None;
                } else if (d > -Epsilon) {
                    //! @todo vertical contact test
                    return CollisionType::Contact;
                } else {
                    //! @todo vertical intrusion test
                    return CollisionType::Intrusion;
                }
            }
        }
    } else {
        if (va.getType() == BoundingVolume::AABB && vb.getType() == BoundingVolume::Sphere) {
            //! @todo box <-> sphere collision test
        } else if (va.getType() == BoundingVolume::Sphere && vb.getType() == BoundingVolume::AABB) {
            //! @todo sphere <-> box collision test
        } else if (va.getType() == BoundingVolume::AABB && vb.getType() == BoundingVolume::Capsule) {
            //! @todo box <-> capsule collision test
        } else if (va.getType() == BoundingVolume::Capsule && vb.getType() == BoundingVolume::AABB) {
            //! @todo capsule <-> box collision test
        } else if (va.getType() == BoundingVolume::Sphere && vb.getType() == BoundingVolume::Capsule) {
            //! @todo sphere <-> capsule collision test
        } else if (va.getType() == BoundingVolume::Capsule && vb.getType() == BoundingVolume::Sphere) {
            //! @todo capsule <-> sphere collision test
        }
    }

    // no collision, or no test for given bounding volumes
    sf::err() << "no collision test for given bounding volumes (" <<
        va.getType() << ", " << vb.getType() << ")\n";
    return CollisionType::None;
}
コード例 #14
0
ファイル: physics.cpp プロジェクト: criptych/minengine
void Physics::update(Body &b, const sf::Time &t) const {
    float s = t.asSeconds();
    b.mPosition += Position(b.mVelocity.x * s, b.mVelocity.y * s, b.mVelocity.z * s);
}
コード例 #15
0
ファイル: InsertTextCommand.cpp プロジェクト: 1833183060/wke
void InsertTextCommand::doApply()
{
    ASSERT(m_text.find('\n') == notFound);

    if (!endingSelection().isNonOrphanedCaretOrRange())
        return;

    // Delete the current selection.
    // FIXME: This delete operation blows away the typing style.
    if (endingSelection().isRange()) {
        if (performTrivialReplace(m_text, m_selectInsertedText))
            return;
        deleteSelection(false, true, true, false);
        // deleteSelection eventually makes a new endingSelection out of a Position. If that Position doesn't have
        // a renderer (e.g. it is on a <frameset> in the DOM), the VisibleSelection cannot be canonicalized to 
        // anything other than NoSelection. The rest of this function requires a real endingSelection, so bail out.
        if (endingSelection().isNone())
            return;
    }

    Position startPosition(endingSelection().start());
    
    Position placeholder;
    // We want to remove preserved newlines and brs that will collapse (and thus become unnecessary) when content 
    // is inserted just before them.
    // FIXME: We shouldn't really have to do this, but removing placeholders is a workaround for 9661.
    // If the caret is just before a placeholder, downstream will normalize the caret to it.
    Position downstream(startPosition.downstream());
    if (lineBreakExistsAtPosition(downstream)) {
        // FIXME: This doesn't handle placeholders at the end of anonymous blocks.
        VisiblePosition caret(startPosition);
        if (isEndOfBlock(caret) && isStartOfParagraph(caret))
            placeholder = downstream;
        // Don't remove the placeholder yet, otherwise the block we're inserting into would collapse before
        // we get a chance to insert into it.  We check for a placeholder now, though, because doing so requires
        // the creation of a VisiblePosition, and if we did that post-insertion it would force a layout.
    }
    
    // Insert the character at the leftmost candidate.
    startPosition = startPosition.upstream();
    
    // It is possible for the node that contains startPosition to contain only unrendered whitespace,
    // and so deleteInsignificantText could remove it.  Save the position before the node in case that happens.
    Position positionBeforeStartNode(positionInParentBeforeNode(startPosition.containerNode()));
    deleteInsignificantText(startPosition.upstream(), startPosition.downstream());
    if (!startPosition.anchorNode()->inDocument())
        startPosition = positionBeforeStartNode;
    if (!startPosition.isCandidate())
        startPosition = startPosition.downstream();
    
    startPosition = positionAvoidingSpecialElementBoundary(startPosition);
    
    Position endPosition;
    
    if (m_text == "\t") {
        endPosition = insertTab(startPosition);
        startPosition = endPosition.previous();
        if (placeholder.isNotNull())
            removePlaceholderAt(placeholder);
    } else {
        // Make sure the document is set up to receive m_text
        startPosition = positionInsideTextNode(startPosition);
        ASSERT(startPosition.anchorType() == Position::PositionIsOffsetInAnchor);
        ASSERT(startPosition.containerNode());
        ASSERT(startPosition.containerNode()->isTextNode());
        if (placeholder.isNotNull())
            removePlaceholderAt(placeholder);
        RefPtr<Text> textNode = startPosition.containerText();
        const unsigned offset = startPosition.offsetInContainerNode();

        insertTextIntoNode(textNode, offset, m_text);
        endPosition = Position(textNode, offset + m_text.length());

        if (m_rebalanceType == RebalanceLeadingAndTrailingWhitespaces) {
            // The insertion may require adjusting adjacent whitespace, if it is present.
            rebalanceWhitespaceAt(endPosition);
            // Rebalancing on both sides isn't necessary if we've inserted only spaces.
            if (!shouldRebalanceLeadingWhitespaceFor(m_text))
                rebalanceWhitespaceAt(startPosition);
        } else {
            ASSERT(m_rebalanceType == RebalanceAllWhitespaces);
            if (canRebalance(startPosition) && canRebalance(endPosition))
                rebalanceWhitespaceOnTextSubstring(textNode, startPosition.offsetInContainerNode(), endPosition.offsetInContainerNode());
        }
    }

    // We could have inserted a part of composed character sequence,
    // so we are basically treating ending selection as a range to avoid validation.
    // <http://bugs.webkit.org/show_bug.cgi?id=15781>
    VisibleSelection forcedEndingSelection;
    forcedEndingSelection.setWithoutValidation(startPosition, endPosition);
    forcedEndingSelection.setIsDirectional(endingSelection().isDirectional());
    setEndingSelection(forcedEndingSelection);

    // Handle the case where there is a typing style.
    if (RefPtr<EditingStyle> typingStyle = document()->frame()->selection()->typingStyle()) {
        typingStyle->prepareToApplyAt(endPosition, EditingStyle::PreserveWritingDirection);
        if (!typingStyle->isEmpty())
            applyStyle(typingStyle.get());
    }

    if (!m_selectInsertedText)
        setEndingSelection(VisibleSelection(endingSelection().end(), endingSelection().affinity(), endingSelection().isDirectional()));
}
コード例 #16
0
ファイル: possearch.hpp プロジェクト: neivv/teippi
C *PosSearch<C>::FindNearest(const Point &pos, const Rect16 &area, F IsValid, F2 Position)
{
    int right_pos = NewFind(pos.x);
    int left_pos = right_pos - 1;
    int max_dist = INT_MAX;
    C *closest = nullptr;
    bool cont = true;
    while (cont)
    {
        cont = false;
        if (left_pos >= 0)
        {
            int left = left_positions[left_pos];
            int widest_right = left + max_width;
            if (widest_right < area.left || pos.x - widest_right > max_dist)
                left_pos = -1;
            else
            {
                cont = true;
                C *value = &left_to_value[left_pos];
                Point val_pos = Position(*value);
                if (val_pos.y < area.bottom && val_pos.y >= area.top && val_pos.x >= area.left)
                {
                    if (IsValid(*value))
                    {
                        int dist = Distance(pos, val_pos);
                        if (dist < max_dist)
                        {
                            closest = value;
                            max_dist = dist;
                        }
                    }
                }
                left_pos--;
            }
        }
        if (right_pos < (int)Size())
        {
            int right = left_to_right[right_pos];
            int widest_left = right - max_width;
            if (widest_left > area.right || widest_left - pos.x > max_dist)
                right_pos = Size();
            else
            {
                cont = true;
                C *value = &left_to_value[right_pos];
                Point val_pos = Position(*value);
                if (val_pos.y < area.bottom && val_pos.y >= area.top && val_pos.x < area.right)
                {
                    if (IsValid(*value))
                    {
                        int dist = Distance(pos, val_pos);
                        if (dist < max_dist)
                        {
                            closest = value;
                            max_dist = dist;
                        }
                    }
                }
                right_pos++;
            }
        }
    }
    return closest;
}
コード例 #17
0
ファイル: layer_render.cpp プロジェクト: Mapotempo/omim
drape_ptr<LayerRenderer> LayerCacher::RecacheDebugLabels(ref_ptr<dp::TextureManager> textures)
{
  drape_ptr<LayerRenderer> renderer = make_unique_dp<LayerRenderer>();

  float const vs = df::VisualParams::Instance().GetVisualScale();
  DebugInfoLabels debugLabels = DebugInfoLabels(Position(m2::PointF(10.0f * vs, 50.0f * vs), dp::Center));

  debugLabels.AddLabel(textures, "visible: km2, readed: km2, ratio:",
                       [](ScreenBase const & screen, string & content) -> bool
  {
    double const sizeX = screen.PixelRectIn3d().SizeX();
    double const sizeY = screen.PixelRectIn3d().SizeY();

    m2::PointD const p0 = screen.PtoG(screen.P3dtoP(m2::PointD(0.0, 0.0)));
    m2::PointD const p1 = screen.PtoG(screen.P3dtoP(m2::PointD(0.0, sizeY)));
    m2::PointD const p2 = screen.PtoG(screen.P3dtoP(m2::PointD(sizeX, sizeY)));
    m2::PointD const p3 = screen.PtoG(screen.P3dtoP(m2::PointD(sizeX, 0.0)));

    double const areaG = MercatorBounds::AreaOnEarth(p0, p1, p2) +
        MercatorBounds::AreaOnEarth(p2, p3, p0);

    double const sizeX_2d = screen.PixelRect().SizeX();
    double const sizeY_2d = screen.PixelRect().SizeY();

    m2::PointD const p0_2d = screen.PtoG(m2::PointD(0.0, 0.0));
    m2::PointD const p1_2d = screen.PtoG(m2::PointD(0.0, sizeY_2d));
    m2::PointD const p2_2d = screen.PtoG(m2::PointD(sizeX_2d, sizeY_2d));
    m2::PointD const p3_2d = screen.PtoG(m2::PointD(sizeX_2d, 0.0));

    double const areaGTotal = MercatorBounds::AreaOnEarth(p0_2d, p1_2d, p2_2d) +
        MercatorBounds::AreaOnEarth(p2_2d, p3_2d, p0_2d);

    ostringstream out;
    out << fixed << setprecision(2)
        << "visible: " << areaG / 1000000.0 << " km2"
        << ", readed: " << areaGTotal / 1000000.0 << " km2"
        << ", ratio: " << areaGTotal / areaG;
    content.assign(out.str());
    return true;
  });

  debugLabels.AddLabel(textures, "scale2d: m/px, scale2d * vs: m/px",
                       [](ScreenBase const & screen, string & content) -> bool
  {
    double const distanceG = MercatorBounds::DistanceOnEarth(screen.PtoG(screen.PixelRect().LeftBottom()),
                                                            screen.PtoG(screen.PixelRect().RightBottom()));

    double const vs = df::VisualParams::Instance().GetVisualScale();
    double const scale = distanceG / screen.PixelRect().SizeX();

    ostringstream out;
    out << fixed << setprecision(2)
        << "scale2d: " << scale << " m/px"
        << ", scale2d * vs: " << scale * vs << " m/px";
    content.assign(out.str());
    return true;
  });

  debugLabels.AddLabel(textures, "distance: m",
                       [](ScreenBase const & screen, string & content) -> bool
  {
    double const sizeX = screen.PixelRectIn3d().SizeX();
    double const sizeY = screen.PixelRectIn3d().SizeY();

    double const distance = MercatorBounds::DistanceOnEarth(screen.PtoG(screen.P3dtoP(m2::PointD(sizeX / 2.0, 0.0))),
                                                            screen.PtoG(screen.P3dtoP(m2::PointD(sizeX / 2.0, sizeY))));

    ostringstream out;
    out << fixed << setprecision(2)
        << "distance: " << distance << " m";
    content.assign(out.str());
    return true;
  });

  debugLabels.AddLabel(textures, "angle: ",
                       [](ScreenBase const & screen, string & content) -> bool
  {
    ostringstream out;
    out << fixed << setprecision(2)
        << "angle: " << screen.GetRotationAngle() * 180.0 / math::pi;
    content.assign(out.str());
    return true;
  });

  renderer->AddShapeRenderer(WIDGET_DEBUG_INFO, debugLabels.Draw(textures));

  // Flush gui geometry.
  GLFunctions::glFlush();

  return renderer;
}
コード例 #18
0
ファイル: Projectile.cpp プロジェクト: Gilligan-MN/OpenXcom
/**
 * calculateTrajectory.
 * @return true when a trajectory is possible.
 */
bool Projectile::calculateThrow(double accuracy)
{
	Position originVoxel, targetVoxel;
	bool foundCurve = false;

	// object blocking - can't throw here
	if (_save->getTile(_action.target) && _save->getTile(_action.target)->getMapData(MapData::O_OBJECT) && _save->getTile(_action.target)->getMapData(MapData::O_OBJECT)->getTUCost(MT_WALK) == 255)
	{
		return false;
	}

	originVoxel = Position(_origin.x*16 + 8, _origin.y*16 + 8, _origin.z*24);
	originVoxel.z += -_save->getTile(_origin)->getTerrainLevel();
	BattleUnit *bu = _save->getTile(_origin)->getUnit();
	originVoxel.z += bu->getHeight();
	originVoxel.z -= 3;
	if (originVoxel.z >= (_origin.z + 1)*24)
	{
		_origin.z++;
	}


	// determine the target voxel.
	// aim at the center of the floor
	targetVoxel = Position(_action.target.x*16 + 8, _action.target.y*16 + 8, _action.target.z*24 + 2);

	// we try 4 different curvatures to try and reach our goal.
	double curvature = 1.0;
	while (!foundCurve && curvature < 5.0)
	{
		_save->getTileEngine()->calculateParabola(originVoxel, targetVoxel, false, &_trajectory, bu, curvature, 1.0);
		if ((int)_trajectory.at(0).x/16 == (int)targetVoxel.x/16 && (int)_trajectory.at(0).y/16 == (int)targetVoxel.y/16)
		{
			foundCurve = true;
		}
		else
		{
			curvature += 1.0;
		}
		_trajectory.clear();
	}
	if (curvature == 5.0)
	{
		return false;
	}

	// apply some accuracy modifiers
	if (accuracy > 100)
		accuracy = 100;
	static const double maxDeviation = 0.08;
	static const double minDeviation = 0;
	double baseDeviation = (maxDeviation - (maxDeviation * accuracy / 100.0)) + minDeviation;
	double deviation = RNG::boxMuller(0, baseDeviation);

	_trajectory.clear();
	// finally do a line calculation and store this trajectory.
	_save->getTileEngine()->calculateParabola(originVoxel, targetVoxel, true, &_trajectory, bu, curvature, 1.0 + deviation);

	Position endPoint = _trajectory.at(_trajectory.size() - 1);
	endPoint.x /= 16;
	endPoint.y /= 16;
	endPoint.z /= 24;
	// check if the item would land on a tile with a blocking object, if so then we let it fly without deviation, it must land on a valid tile in that case
	if (_save->getTile(endPoint) && _save->getTile(endPoint)->getMapData(MapData::O_OBJECT) && _save->getTile(endPoint)->getMapData(MapData::O_OBJECT)->getTUCost(MT_WALK) == 255)
	{
		_trajectory.clear();
		// finally do a line calculation and store this trajectory.
		_save->getTileEngine()->calculateParabola(originVoxel, targetVoxel, true, &_trajectory, bu, curvature, 1.0);
	}


	return true;
}
コード例 #19
0
ファイル: Camera.cpp プロジェクト: 88er/tutorials
void CCamera::CheckForMovement()
{	
	// Once we have the frame interval, we find the current speed
	float speed = (float)(kSpeed * g_FrameInterval);

	// Store the last position and view of the camera
	CVector3 vOldPosition = Position();
	CVector3 vOldView = View();

	// Use a flag to see if we movement backwards or not
	bool bMovedBack = false;


/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

	// Here is where we subtract the gravity acceleration from our velocity vector.
	// We then add that velocity vector to our camera to effect our camera (or player)
	// This is also how we handle the jump velocity when we hit space bar.
	// Notice that we multiply the gravity by the frame interval (dt).  This makes
	// it so faster video cards don't do a 2 frame jump, while TNT2 cards do 20 frames :)
	// This is necessary to make every computer use the same movement and jump speed.
	g_vVelocity.y -= (float)(kGravity * g_FrameInterval);
	m_vPosition = m_vPosition + g_vVelocity;

/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *


	// Check if we hit the Up arrow or the 'w' key
	if(GetKeyState(VK_UP) & 0x80 || GetKeyState('W') & 0x80) {				

		// Move our camera forward by a positive SPEED
		MoveCamera(speed);				
	}

	// Check if we hit the Down arrow or the 's' key
	if(GetKeyState(VK_DOWN) & 0x80 || GetKeyState('S') & 0x80) {			

		// Move our camera backward by a negative SPEED
		MoveCamera(-speed);	
		bMovedBack = true;
	}

	// Check if we hit the Left arrow or the 'a' key
	if(GetKeyState(VK_LEFT) & 0x80 || GetKeyState('A') & 0x80) {			

		// Strafe the camera left
		StrafeCamera(-speed);
	}

	// Check if we hit the Right arrow or the 'd' key
	if(GetKeyState(VK_RIGHT) & 0x80 || GetKeyState('D') & 0x80) {			

		// Strafe the camera right
		StrafeCamera(speed);
	}	

	// Now that we moved, let's get the current position and test our movement
	// vector against the level data to see if there is a collision.
	CVector3 vCurrentPosition = Position();

	// Check for collision with AABB's and grab the new position
	CVector3 vNewPosition = g_Level.TraceBox(vOldPosition, vCurrentPosition,
		                                     CVector3(-20, -50, -20), CVector3(20, 50, 20));

	// Check if we collided and we moved backwards
	if(g_Level.Collided() && bMovedBack)
	{
		// If or x or y didn't move, then we are backed into a wall so restore the view vector
		if(vNewPosition.x == vOldPosition.x || vNewPosition.z == vOldPosition.z)
			m_vView = vOldView;		
	}

	// Set the new position that was returned from our trace function
	m_vPosition = vNewPosition;


/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

	// After we check for collision, we only want to add the velocity vector to
	// our view vector when we are falling.  If we aren't on the ground then
	// we don't want to push the the camera view down to the ground.  It's okay
	// if the position goes down because the collision detection fixes that so
	// we don't go through the ground, however, it's not natural to push the view
	// down too.  Well, assuming is strong enough to push our face down to the ground :)
	if(!g_Level.IsOnGround())
		m_vView = m_vView + g_vVelocity;
	else
	{
		// If we ARE on the ground, we want to get rid of the jump acceleration
		// that we add when the user hits the space bar.  Below we check to see
		// if our velocity is below 0 then we are done with our jump and can just
		// float back to the ground by the gravity.  We do also add our gravity
		// acceleration to the velocity every frame, so this resets this to zero
		// for that as well.
		if(g_vVelocity.y < 0)
			g_vVelocity.y = 0;
	}

/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *


}
コード例 #20
0
ファイル: Projectile.cpp プロジェクト: Gilligan-MN/OpenXcom
/**
 * calculateTrajectory.
 * @return the objectnumber(0-3) or unit(4) or out of map (5) or -1(no line of fire)
 */
int Projectile::calculateTrajectory(double accuracy)
{
	Position originVoxel, targetVoxel;
	int direction;
	int dirYshift[8] = {1, 1, 8, 15, 15, 15, 8, 1 };
	int dirXshift[8] = {8, 14, 15, 15, 8, 1, 1, 1 };
	// large units : x2

	originVoxel = Position(_origin.x*16, _origin.y*16, _origin.z*24);
	originVoxel.z += -_save->getTile(_origin)->getTerrainLevel();
	BattleUnit *bu = _save->getTile(_origin)->getUnit();
	originVoxel.z += bu->getHeight();
	originVoxel.z -= 3;
	if (originVoxel.z >= (_origin.z + 1)*24)
	{
		_origin.z++;
	}
	direction = bu->getDirection();
	originVoxel.x += dirXshift[direction];
	originVoxel.y += dirYshift[direction];
	// determine the target voxel.
	// aim at the center of the unit, the object, the walls or the floor (in that priority)
	// if there is no LOF to the center, try elsewhere (more outward).
	// Store this target voxel.
	Tile *tile = _save->getTile(_action.target);
	if (tile->getUnit() != 0)
	{
		if (_origin == _action.target)
		{
			// don't shoot at yourself but shoot at the floor
			targetVoxel = Position(_action.target.x*16 + 8, _action.target.y*16 + 8, _action.target.z*24);
		}
		else
		{
			// first try is at half the unit height
			targetVoxel = Position(_action.target.x*16 + 8, _action.target.y*16 + 8, _action.target.z*24 + tile->getUnit()->getUnit()->getStandHeight()/2);
			int test = _save->getTileEngine()->calculateLine(originVoxel, targetVoxel, false, &_trajectory, bu);
			_trajectory.clear();
			if (test != 4)
			{
				// did not hit a unit, try at different heights (for ex: unit behind a window can only be hit in the head)
				targetVoxel = Position(_action.target.x*16 + 8, _action.target.y*16 + 8, _action.target.z*24 + (tile->getUnit()->getUnit()->getStandHeight()*3)/4);
				test = _save->getTileEngine()->calculateLine(originVoxel, targetVoxel, false, &_trajectory, bu);
				_trajectory.clear();
			}
		}
	}
	else if (tile->getMapData(MapData::O_OBJECT) != 0)
	{
		targetVoxel = Position(_action.target.x*16 + 8, _action.target.y*16 + 8, _action.target.z*24 + 10);
	}
	else if (tile->getMapData(MapData::O_NORTHWALL) != 0)
	{
		targetVoxel = Position(_action.target.x*16 + 8, _action.target.y*16, _action.target.z*24 + 10);
	}
	else if (tile->getMapData(MapData::O_WESTWALL) != 0)
	{
		targetVoxel = Position(_action.target.x*16, _action.target.y*16 + 8, _action.target.z*24 + 10);
	}
	else if (tile->getMapData(MapData::O_FLOOR) != 0)
	{
		targetVoxel = Position(_action.target.x*16 + 8, _action.target.y*16 + 8, _action.target.z*24);
	}
	else
	{
		return -1; // no line of fire
	}

	// apply some accuracy modifiers (todo: calculate this)
	// This will results in a new target voxel
	applyAccuracy(originVoxel, &targetVoxel, accuracy);

	// finally do a line calculation and store this trajectory.
	return _save->getTileEngine()->calculateLine(originVoxel, targetVoxel, true, &_trajectory, bu);
}
コード例 #21
0
/* Test the method 'splitAt'*/
TEST_F(PositionVectorTest, test_method_splitAt) {	
    PositionVector vec;
    vec.push_back(Position(0,0));
    vec.push_back(Position(2,0));
    vec.push_back(Position(5,0));
    SUMOReal smallDiff = POSITION_EPS / 2;
    std::pair<PositionVector, PositionVector> result;
    // split in first segment
    result = vec.splitAt(1);
	EXPECT_DOUBLE_EQ(2, result.first.size());
	EXPECT_DOUBLE_EQ(0, result.first[0].x());
	EXPECT_DOUBLE_EQ(1, result.first[1].x());
	EXPECT_DOUBLE_EQ(3, result.second.size());
	EXPECT_DOUBLE_EQ(1, result.second[0].x());
	EXPECT_DOUBLE_EQ(2, result.second[1].x());
	EXPECT_DOUBLE_EQ(5, result.second[2].x());
    // split in second segment
    result = vec.splitAt(4);
	EXPECT_DOUBLE_EQ(3, result.first.size());
	EXPECT_DOUBLE_EQ(0, result.first[0].x());
	EXPECT_DOUBLE_EQ(2, result.first[1].x());
	EXPECT_DOUBLE_EQ(4, result.first[2].x());
	EXPECT_DOUBLE_EQ(2, result.second.size());
	EXPECT_DOUBLE_EQ(4, result.second[0].x());
	EXPECT_DOUBLE_EQ(5, result.second[1].x());
    // split close before inner point
    result = vec.splitAt(2 - smallDiff);
	EXPECT_DOUBLE_EQ(2, result.first.size());
	EXPECT_DOUBLE_EQ(0, result.first[0].x());
	EXPECT_DOUBLE_EQ(2, result.first[1].x());
	EXPECT_DOUBLE_EQ(2, result.second.size());
	EXPECT_DOUBLE_EQ(2, result.second[0].x());
	EXPECT_DOUBLE_EQ(5 ,result.second[1].x());
    // split close after inner point
    result = vec.splitAt(2 + smallDiff);
	EXPECT_DOUBLE_EQ(2, result.first.size());
	EXPECT_DOUBLE_EQ(0, result.first[0].x());
	EXPECT_DOUBLE_EQ(2, result.first[1].x());
	EXPECT_DOUBLE_EQ(2, result.second.size());
	EXPECT_DOUBLE_EQ(2, result.second[0].x());
	EXPECT_DOUBLE_EQ(5 ,result.second[1].x());

    // catch a bug
    vec.push_back(Position(6,0));
    vec.push_back(Position(8,0));
    // split at inner point
    result = vec.splitAt(5);
	EXPECT_DOUBLE_EQ(3, result.first.size());
	EXPECT_DOUBLE_EQ(0, result.first[0].x());
	EXPECT_DOUBLE_EQ(2, result.first[1].x());
	EXPECT_DOUBLE_EQ(5, result.first[2].x());
	EXPECT_DOUBLE_EQ(3, result.second.size());
	EXPECT_DOUBLE_EQ(5, result.second[0].x());
	EXPECT_DOUBLE_EQ(6 ,result.second[1].x());
	EXPECT_DOUBLE_EQ(8 ,result.second[2].x());

    // split short vector
    PositionVector vec2;
    vec2.push_back(Position(0,0));
    vec2.push_back(Position(2,0));
    result = vec2.splitAt(1);
	EXPECT_DOUBLE_EQ(2, result.first.size());
	EXPECT_DOUBLE_EQ(0, result.first[0].x());
	EXPECT_DOUBLE_EQ(1, result.first[1].x());
	EXPECT_DOUBLE_EQ(2, result.second.size());
	EXPECT_DOUBLE_EQ(1, result.second[0].x());
	EXPECT_DOUBLE_EQ(2 ,result.second[1].x());

    // split very short vector
    PositionVector vec3;
    vec3.push_back(Position(0,0));
    vec3.push_back(Position(POSITION_EPS,0));
    // supress expected warning
    MsgHandler::getWarningInstance()->removeRetriever(&OutputDevice::getDevice("stderr"));
    result = vec3.splitAt(smallDiff);
    MsgHandler::getWarningInstance()->addRetriever(&OutputDevice::getDevice("stderr"));

	EXPECT_DOUBLE_EQ(2, result.first.size());
	EXPECT_DOUBLE_EQ(0, result.first[0].x());
	EXPECT_DOUBLE_EQ(smallDiff, result.first[1].x());
	EXPECT_DOUBLE_EQ(2, result.second.size());
	EXPECT_DOUBLE_EQ(smallDiff, result.second[0].x());
	EXPECT_DOUBLE_EQ(POSITION_EPS ,result.second[1].x());
}
コード例 #22
0
ファイル: UnitDieBState.cpp プロジェクト: keeper/OpenXcom
/**
 * Converts unit to a corpse (item).
 */
void UnitDieBState::convertUnitToCorpse()
{
	_parent->getSave()->getBattleState()->showPsiButton(false);
	// in case the unit was unconscious
	_parent->getSave()->removeUnconsciousBodyItem(_unit);
	Position lastPosition = _unit->getPosition();
	int size = _unit->getArmor()->getSize() - 1;
	BattleItem *itemToKeep = 0;
	bool dropItems = !Options::getBool("weaponSelfDestruction") || (_unit->getOriginalFaction() != FACTION_HOSTILE || _unit->getStatus() == STATUS_UNCONSCIOUS);
	// move inventory from unit to the ground for non-large units
	if (size == 0 && dropItems)
	{
		for (std::vector<BattleItem*>::iterator i = _unit->getInventory()->begin(); i != _unit->getInventory()->end(); ++i)
		{
			_parent->dropItem(_unit->getPosition(), (*i));
			if (!(*i)->getRules()->isFixed())
			{
				(*i)->setOwner(0);
			}
			else
			{
				itemToKeep = *i;
			}
		}
	}
	_unit->getInventory()->clear();

	if (itemToKeep != 0)
	{
		_unit->getInventory()->push_back(itemToKeep);
	}

	// remove unit-tile link
	_unit->setTile(0);

	if (size == 0)
	{
		BattleItem *corpse = new BattleItem(_parent->getRuleset()->getItem(_unit->getArmor()->getCorpseItem()),_parent->getSave()->getCurrentItemId());
		corpse->setUnit(_unit);
		_parent->dropItem(_unit->getPosition(), corpse, true);
		if (_parent->getSave()->getTile(lastPosition)->getUnit() == _unit)	// check in case unit was displaced by another unit
		{
			_parent->getSave()->getTile(lastPosition)->setUnit(0);
		}
	}
	else
	{
		int i = 1;
		for (int y = 0; y <= size; y++)
		{
			for (int x = 0; x <= size; x++)
			{
				std::ostringstream ss;
				ss << _unit->getArmor()->getCorpseItem() << i;
				BattleItem *corpse = new BattleItem(_parent->getRuleset()->getItem(ss.str()),_parent->getSave()->getCurrentItemId());
				corpse->setUnit(_unit);
				if (_parent->getSave()->getTile(lastPosition + Position(x,y,0))->getUnit() == _unit) // check in case unit was displaced by another unit
				{
					_parent->getSave()->getTile(lastPosition + Position(x,y,0))->setUnit(0);
				}
				_parent->dropItem(lastPosition + Position(x,y,0), corpse, true);
				i++;
			}
		}
	}

}
コード例 #23
0
/* Test the method 'transformToVectorCoordinates'*/
TEST_F(PositionVectorTest, test_method_transformToVectorCoordinates) {	
    {
        PositionVector vec1;
        vec1.push_back(Position(1,0));
        vec1.push_back(Position(10,0));
        vec1.push_back(Position(10,5));
        vec1.push_back(Position(20,5));
        Position on(4,0);
        Position left(4,1);
        Position right(4,-1);
        Position left2(4,2);
        Position right2(4,-2);
        Position cornerRight(13,-4);
        Position cornerLeft(7,9);
        Position before(0,-1);
        Position beyond(24,9);

        EXPECT_EQ(Position(3, 0),  vec1.transformToVectorCoordinates(on));
        EXPECT_EQ(Position(3, -1),  vec1.transformToVectorCoordinates(left));
        EXPECT_EQ(Position(3, 1),  vec1.transformToVectorCoordinates(right));
        EXPECT_EQ(Position(3, -2),  vec1.transformToVectorCoordinates(left2));
        EXPECT_EQ(Position(3, 2),  vec1.transformToVectorCoordinates(right2));
        EXPECT_EQ(Position(9, 5),  vec1.transformToVectorCoordinates(cornerRight));
        EXPECT_EQ(Position(14, -5),  vec1.transformToVectorCoordinates(cornerLeft));

        EXPECT_EQ(Position::INVALID,  vec1.transformToVectorCoordinates(before));
        EXPECT_EQ(Position::INVALID,  vec1.transformToVectorCoordinates(beyond));
        EXPECT_EQ(Position(-1, 1),  vec1.transformToVectorCoordinates(before, true));
        EXPECT_EQ(Position(28, -4),  vec1.transformToVectorCoordinates(beyond, true));
    }

    { 
        PositionVector vec1; // the same tests as before, mirrored on x-axis
        vec1.push_back(Position(1,0));
        vec1.push_back(Position(10,0));
        vec1.push_back(Position(10,-5));
        vec1.push_back(Position(20,-5));
        Position on(4,0);
        Position left(4,-1);
        Position right(4,1);
        Position left2(4,-2);
        Position right2(4,2);
        Position cornerRight(13,4);
        Position cornerLeft(7,-9);
        Position before(0,1);
        Position beyond(24,-9);

        EXPECT_EQ(Position(3, 0),  vec1.transformToVectorCoordinates(on));
        EXPECT_EQ(Position(3, 1),  vec1.transformToVectorCoordinates(left));
        EXPECT_EQ(Position(3, -1),  vec1.transformToVectorCoordinates(right));
        EXPECT_EQ(Position(3, 2),  vec1.transformToVectorCoordinates(left2));
        EXPECT_EQ(Position(3, -2),  vec1.transformToVectorCoordinates(right2));
        EXPECT_EQ(Position(9, -5),  vec1.transformToVectorCoordinates(cornerRight));
        EXPECT_EQ(Position(14, 5),  vec1.transformToVectorCoordinates(cornerLeft));

        EXPECT_EQ(Position::INVALID,  vec1.transformToVectorCoordinates(before));
        EXPECT_EQ(Position::INVALID,  vec1.transformToVectorCoordinates(beyond));
        EXPECT_EQ(Position(-1, -1),  vec1.transformToVectorCoordinates(before, true));
        EXPECT_EQ(Position(28, 4),  vec1.transformToVectorCoordinates(beyond, true));
    }
}
コード例 #24
0
void VisibleSelection::adjustSelectionToAvoidCrossingEditingBoundaries()
{
    if (m_base.isNull() || m_start.isNull() || m_end.isNull())
        return;

    Node* baseRoot = highestEditableRoot(m_base);
    Node* startRoot = highestEditableRoot(m_start);
    Node* endRoot = highestEditableRoot(m_end);
    
    Node* baseEditableAncestor = lowestEditableAncestor(m_base.containerNode());
    
    // The base, start and end are all in the same region.  No adjustment necessary.
    if (baseRoot == startRoot && baseRoot == endRoot)
        return;
    
    // The selection is based in editable content.
    if (baseRoot) {
        // If the start is outside the base's editable root, cap it at the start of that root.
        // If the start is in non-editable content that is inside the base's editable root, put it
        // at the first editable position after start inside the base's editable root.
        if (startRoot != baseRoot) {
            VisiblePosition first = firstEditablePositionAfterPositionInRoot(m_start, baseRoot);
            m_start = first.deepEquivalent();
            if (m_start.isNull()) {
                ASSERT_NOT_REACHED();
                m_start = m_end;
            }
        }
        // If the end is outside the base's editable root, cap it at the end of that root.
        // If the end is in non-editable content that is inside the base's root, put it
        // at the last editable position before the end inside the base's root.
        if (endRoot != baseRoot) {
            VisiblePosition last = lastEditablePositionBeforePositionInRoot(m_end, baseRoot);
            m_end = last.deepEquivalent();
            if (m_end.isNull())
                m_end = m_start;
        }
    // The selection is based in non-editable content.
    } else {
        // FIXME: Non-editable pieces inside editable content should be atomic, in the same way that editable
        // pieces in non-editable content are atomic.
    
        // The selection ends in editable content or non-editable content inside a different editable ancestor, 
        // move backward until non-editable content inside the same lowest editable ancestor is reached.
        Node* endEditableAncestor = lowestEditableAncestor(m_end.containerNode());
        if (endRoot || endEditableAncestor != baseEditableAncestor) {
            
            Position p = previousVisuallyDistinctCandidate(m_end);
            Node* shadowAncestor = endRoot ? endRoot->shadowAncestorNode() : 0;
            if (p.isNull() && endRoot && (shadowAncestor != endRoot))
                p = positionAfterNode(shadowAncestor);
            while (p.isNotNull() && !(lowestEditableAncestor(p.containerNode()) == baseEditableAncestor && !isEditablePosition(p))) {
                Node* root = editableRootForPosition(p);
                shadowAncestor = root ? root->shadowAncestorNode() : 0;
                p = isAtomicNode(p.containerNode()) ? positionInParentBeforeNode(p.containerNode()) : previousVisuallyDistinctCandidate(p);
                if (p.isNull() && (shadowAncestor != root))
                    p = positionAfterNode(shadowAncestor);
            }
            VisiblePosition previous(p);

            if (previous.isNull()) {
                // The selection crosses an Editing boundary.  This is a
                // programmer error in the editing code.  Happy debugging!
                ASSERT_NOT_REACHED();
                m_base = Position();
                m_extent = Position();
                validate();
                return;
            }
            m_end = previous.deepEquivalent();
        }

        // The selection starts in editable content or non-editable content inside a different editable ancestor, 
        // move forward until non-editable content inside the same lowest editable ancestor is reached.
        Node* startEditableAncestor = lowestEditableAncestor(m_start.containerNode());      
        if (startRoot || startEditableAncestor != baseEditableAncestor) {
            Position p = nextVisuallyDistinctCandidate(m_start);
            Node* shadowAncestor = startRoot ? startRoot->shadowAncestorNode() : 0;
            if (p.isNull() && startRoot && (shadowAncestor != startRoot))
                p = positionBeforeNode(shadowAncestor);
            while (p.isNotNull() && !(lowestEditableAncestor(p.containerNode()) == baseEditableAncestor && !isEditablePosition(p))) {
                Node* root = editableRootForPosition(p);
                shadowAncestor = root ? root->shadowAncestorNode() : 0;
                p = isAtomicNode(p.containerNode()) ? positionInParentAfterNode(p.containerNode()) : nextVisuallyDistinctCandidate(p);
                if (p.isNull() && (shadowAncestor != root))
                    p = positionBeforeNode(shadowAncestor);
            }
            VisiblePosition next(p);
            
            if (next.isNull()) {
                // The selection crosses an Editing boundary.  This is a
                // programmer error in the editing code.  Happy debugging!
                ASSERT_NOT_REACHED();
                m_base = Position();
                m_extent = Position();
                validate();
                return;
            }
            m_start = next.deepEquivalent();
        }
    }
    
    // Correct the extent if necessary.
    if (baseEditableAncestor != lowestEditableAncestor(m_extent.containerNode()))
        m_extent = m_baseIsFirst ? m_end : m_start;
}
コード例 #25
0
/* Test the method 'around'*/
TEST_F(PositionVectorTest, test_method_around) {

	EXPECT_TRUE(vectorPolygon->around(Position(1,1)));
	EXPECT_TRUE(vectorPolygon->around(Position(1,2)));
	EXPECT_FALSE(vectorPolygon->around(Position(4,4)));
	EXPECT_FALSE(vectorPolygon->around(Position(0,0)));

	EXPECT_FALSE(vectorLine->around(Position(1,1)));
	EXPECT_FALSE(vectorLine->around(Position(0,2)));

    // with positive offset
	EXPECT_TRUE(vectorPolygon->around(Position(4,2), 1));
	EXPECT_FALSE(vectorPolygon->around(Position(5,2), 1));
    // what was true remains true
	EXPECT_TRUE(vectorPolygon->around(Position(1,1), POSITION_EPS));
	EXPECT_TRUE(vectorPolygon->around(Position(1,2), POSITION_EPS));

    // with negative offset
	EXPECT_FALSE(vectorPolygon->around(Position(4,2), -POSITION_EPS));
	EXPECT_TRUE(vectorPolygon->around(Position(1,1), -1));
	EXPECT_FALSE(vectorPolygon->around(Position(0.5,0.5), -1));
}
コード例 #26
0
ファイル: CreatureAI.cpp プロジェクト: Refuge89/TrinityCore
int32 CreatureAI::VisualizeBoundary(uint32 duration, Unit* owner, bool fill) const
{
    typedef std::pair<int32, int32> coordinate;

    if (!owner)
        return -1;

    if (!_boundary || _boundary->empty())
        return LANG_CREATURE_MOVEMENT_NOT_BOUNDED;

    std::queue<coordinate> Q;
    std::unordered_set<coordinate> alreadyChecked;
    std::unordered_set<coordinate> outOfBounds;

    Position startPosition = owner->GetPosition();
    if (!CheckBoundary(&startPosition))
    { // fall back to creature position
        startPosition = me->GetPosition();
        if (!CheckBoundary(&startPosition))
        { // fall back to creature home position
            startPosition = me->GetHomePosition();
            if (!CheckBoundary(&startPosition))
                return LANG_CREATURE_NO_INTERIOR_POINT_FOUND;
        }
    }
    float spawnZ = startPosition.GetPositionZ() + BOUNDARY_VISUALIZE_SPAWN_HEIGHT;

    bool boundsWarning = false;
    Q.push({ 0,0 });
    while (!Q.empty())
    {
        coordinate front = Q.front();
        bool hasOutOfBoundsNeighbor = false;
        for (coordinate off : std::initializer_list<coordinate>{{1,0}, {0,1}, {-1,0}, {0,-1}})
        {
            coordinate next(front.first + off.first, front.second + off.second);
            if (next.first > BOUNDARY_VISUALIZE_FAILSAFE_LIMIT || next.first < -BOUNDARY_VISUALIZE_FAILSAFE_LIMIT || next.second > BOUNDARY_VISUALIZE_FAILSAFE_LIMIT || next.second < -BOUNDARY_VISUALIZE_FAILSAFE_LIMIT)
            {
                boundsWarning = true;
                continue;
            }
            if (alreadyChecked.find(next) == alreadyChecked.end()) // never check a coordinate twice
            {
                Position nextPos(startPosition.GetPositionX() + next.first*BOUNDARY_VISUALIZE_STEP_SIZE, startPosition.GetPositionY() + next.second*BOUNDARY_VISUALIZE_STEP_SIZE, startPosition.GetPositionZ());
                if (CheckBoundary(&nextPos))
                    Q.push(next);
                else
                {
                    outOfBounds.insert(next);
                    hasOutOfBoundsNeighbor = true;
                }
                alreadyChecked.insert(next);
            }
            else
                if (outOfBounds.find(next) != outOfBounds.end())
                    hasOutOfBoundsNeighbor = true;
        }
        if (fill || hasOutOfBoundsNeighbor)
            if (TempSummon* point = owner->SummonCreature(BOUNDARY_VISUALIZE_CREATURE, Position(startPosition.GetPositionX() + front.first*BOUNDARY_VISUALIZE_STEP_SIZE, startPosition.GetPositionY() + front.second*BOUNDARY_VISUALIZE_STEP_SIZE, spawnZ), TEMPSUMMON_TIMED_DESPAWN, duration * IN_MILLISECONDS))
            {
                point->SetObjectScale(BOUNDARY_VISUALIZE_CREATURE_SCALE);
                point->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
                point->SetImmuneToAll(true);
                if (!hasOutOfBoundsNeighbor)
                    point->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
            }
        Q.pop();
    }
    return boundsWarning ? LANG_CREATURE_MOVEMENT_MAYBE_UNBOUNDED : 0;
}
コード例 #27
0
String CodeDocument::getAllContent() const
{
    return getTextBetween (Position (*this, 0),
                           Position (*this, lines.size(), 0));
}
コード例 #28
0
ファイル: Window.cpp プロジェクト: kverhun/tic-tac-toe
Window* Window::Create(int x, int y, int w, int h, string title, Color bckg)
{
	return Window::Create(Position(x,y), Size(w,h), title, bckg);
}
コード例 #29
0
ファイル: base_monster.cpp プロジェクト: BubbaXXX/xray-16
void CBaseMonster::update_pos_by_grouping_behaviour ()
{
	if ( !m_grouping_behaviour )
	{
		return;
	}

	Fvector acc = get_steer_manager()->calc_acceleration();

	acc.y = 0; // remove vertical component

	if ( !m_last_grouping_behaviour_update_tick )
	{
		m_last_grouping_behaviour_update_tick = Device.dwTimeGlobal;
	}	

	const float dt = 0.001f * (Device.dwTimeGlobal - m_last_grouping_behaviour_update_tick);
	
	m_last_grouping_behaviour_update_tick = Device.dwTimeGlobal;

	const Fvector old_pos  = Position();
	Fvector       offs     = acc*dt;
	const float   offs_mag = magnitude(offs);

	if ( offs_mag < 0.000001f )
	{
		// too little force applied, ignore it and save cpu
		return;
	}

	// this control maximum offset
	// higher values allow stronger forces, but can lead to jingling
	const float max_offs = 0.005f;
	if ( offs_mag > max_offs )
	{
		offs.set_length(0.005f);
	}

	Fvector   new_pos    = old_pos + offs;


	const u32 old_vertex = ai_location().level_vertex_id();
	u32       new_vertex = ai().level_graph().check_position_in_direction(old_vertex, old_pos, new_pos);

	if ( !ai().level_graph().valid_vertex_id(new_vertex) )
	{
		// aiming out of ai-map, ignore
		return;
	}

	// use physics simulation to slide along obstacles
	character_physics_support()->movement()->VirtualMoveTo(new_pos, new_pos);

	if ( !ai().level_graph().valid_vertex_position(new_pos) )
	{
		// aiming out of ai-map, ignore
		return;
	}

	new_vertex = ai().level_graph().check_position_in_direction(old_vertex, old_pos, new_pos);

	if ( !ai().level_graph().valid_vertex_id(new_vertex) )
	{
		return;
	}

	// finally, new position is valid on the ai-map, we can use it
	character_physics_support()->movement()->SetPosition(new_pos);
	Position() = new_pos;
	ai_location().level_vertex(new_vertex);
}
コード例 #30
0
ファイル: map.cpp プロジェクト: stevecotton/Aethyra
Path Map::findPath(const int startX, const int startY, const int destX,
                   const int destY)
{
    // Path to be built up (empty by default)
    Path path;

    // Declare open list, a list with open tiles sorted on F cost
    std::priority_queue<Location> openList;

    // Reset starting tile's G cost to 0
    MetaTile *startTile = getMetaTile(startX, startY);
    startTile->Gcost = 0;

    // Add the start point to the open list
    openList.push(Location(startX, startY, startTile));

    bool foundPath = false;

    // Keep trying new open tiles until no more tiles to try or target found
    while (!openList.empty() && !foundPath)
    {
        // Take the location with the lowest F cost from the open list.
        Location curr = openList.top();
        openList.pop();

        // If the tile is already on the closed list, this means it has already
        // been processed with a shorter path to the start point (lower G cost)
        if (curr.tile->whichList == mOnClosedList)
            continue;

        // Put the current tile on the closed list
        curr.tile->whichList = mOnClosedList;

        // Check the adjacent tiles
        for (int dy = -1; dy <= 1; dy++)
        {
            for (int dx = -1; dx <= 1; dx++)
            {
                // Calculate location of tile to check
                const int x = curr.x + dx;
                const int y = curr.y + dy;

                // Skip if if we're checking the same tile we're leaving from,
                // or if the new location falls outside of the map boundaries
                if ((dx == 0 && dy == 0) || !contains(x, y))
                {
                    continue;
                }

                MetaTile *newTile = getMetaTile(x, y);

                // Skip if the tile is on the closed list or collides unless
                // its the destination tile
                if (newTile->whichList == mOnClosedList ||
                   (tileCollides(x, y) && !(x == destX && y == destY)))
                {
                    continue;
                }

                // When taking a diagonal step, verify that we can skip the
                // corner. We allow skipping past beings but not past non-
                // walkable tiles.
                if (dx != 0 && dy != 0)
                {
                    MetaTile *t1 = getMetaTile(curr.x, curr.y + dy);
                    MetaTile *t2 = getMetaTile(curr.x + dx, curr.y);

                    if (!(t1->walkable && t2->walkable))
                        continue;
                }

                // Calculate G cost for this route, 10 for moving straight and
                // 14 for moving diagonal (sqrt(200) = 14.1421...)
                int Gcost = curr.tile->Gcost + ((dx == 0 || dy == 0) ? 10 : 14);

                // Skip if Gcost becomes too much
                // Warning: probably not entirely accurate
                if (Gcost > 200)
                {
                    continue;
                }

                if (newTile->whichList != mOnOpenList)
                {
                    // Found a new tile (not on open nor on closed list)
                    // Update Hcost of the new tile using Manhatten distance
                    newTile->Hcost = 10 * (abs(x - destX) + abs(y - destY));

                    // Set the current tile as the parent of the new tile
                    newTile->parentX = curr.x;
                    newTile->parentY = curr.y;

                    // Update Gcost and Fcost of new tile
                    newTile->Gcost = Gcost;
                    newTile->Fcost = Gcost + newTile->Hcost;

                    if (x != destX || y != destY)
                    {
                        // Add this tile to the open list
                        newTile->whichList = mOnOpenList;
                        openList.push(Location(x, y, newTile));
                    }
                    else
                    {
                        // Target location was found
                        foundPath = true;
                    }
                }
                else if (Gcost < newTile->Gcost)
                {
                    // Found a shorter route.
                    // Update Gcost and Fcost of the new tile
                    newTile->Gcost = Gcost;
                    newTile->Fcost = Gcost + newTile->Hcost;

                    // Set the current tile as the parent of the new tile
                    newTile->parentX = curr.x;
                    newTile->parentY = curr.y;

                    // Add this tile to the open list (it's already
                    // there, but this instance has a lower F score)
                    openList.push(Location(x, y, newTile));
                }
            }
        }
    }

    // Two new values to indicate whether a tile is on the open or closed list,
    // this way we don't have to clear all the values between each pathfinding.
    mOnClosedList += 2;
    mOnOpenList += 2;

    // If a path has been found, iterate backwards using the parent locations
    // to extract it.
    if (foundPath)
    {
        int pathX = destX;
        int pathY = destY;

        while (pathX != startX || pathY != startY)
        {
            // Add the new path node to the start of the path list
            path.push_front(Position(pathX, pathY));

            // Find out the next parent
            MetaTile *tile = getMetaTile(pathX, pathY);
            pathX = tile->parentX;
            pathY = tile->parentY;
        }
    }

    return path;
}