Example #1
0
void Physics::TestCollision(Shape *a, Shape *b) {
	if (!(a->layerMask & b->layerMask)) return;
	if (a->object == b->object) return;
	int typeA = a->GetType(), typeB = b->GetType();
	if (typeA == Polygon::ShapeType && typeB == Polygon::ShapeType)
		return TestCollision((Polygon *)a, (Polygon *)b);
	if (typeA == Circle::ShapeType && typeB == Circle::ShapeType)
		return TestCollision((Circle *)a, (Circle *)b);
	if (typeA == Circle::ShapeType && typeB == Polygon::ShapeType)
		return TestCollision((Circle *)a, (Polygon *)b);
	if (typeA == Polygon::ShapeType && typeB == Circle::ShapeType)
		return TestCollision((Circle *)b, (Polygon *)a);
}
Example #2
0
void Tetris::KeyRepeat(game_info* gi)
{
	if (gi->state != STATE_TETRIS)
	{
		return;
	}

	if (engine.keys[SDLK_UP])
	{
		gi->curdir++;
		gi->curdir %= 4;

		if (TestCollision(gi))
		{
			gi->curdir--;
			gi->curdir += 4;
			gi->curdir %= 4;
		}
		
		engine.PassMessage(MSG_UPDATEPIECE, gi->pos, gi->curdir, gi->curpiece);
	}
	else if (engine.keys[SDLK_LEFT])
	{
		gi->pos--;

		// test collisions!
		if (TestCollision(gi))
		{
			gi->pos++;
		}

		engine.PassMessage(MSG_UPDATEPIECE, gi->pos, gi->curdir, gi->curpiece);
	}
	else if (engine.keys[SDLK_RIGHT])
	{
		gi->pos++;
		

		// test collisions!
		if (TestCollision(gi))
		{
			gi->pos--;
		}	

		engine.PassMessage(MSG_UPDATEPIECE, gi->pos, gi->curdir, gi->curpiece);
	} 
}
Example #3
0
	///	Obj		:	被移动的对象
	///	enDir	:	移动方向
	///	nStep	:	移动步长
	///	return	:	是否移动
	xgc_bool XGameMap::DynamicMoveTo( XGameObject* pObject, XVector3 &vPositionNew, xgc_uint32 nCollistionMask, xgc_uintptr lpContext )
	{
		XGC_CHECK_REENTER_CALL( mDynamicChecker );
		XGC_ASSERT_RETURN( pObject->GetParent() == GetObjectID(), false, "对象不在该场景,却请求在该场景移动。" );
		xgc_bool ret = true;

		XVector3 vPositionOld = pObject->GetPosition();

		if( !( nCollistionMask & EYESHOTAREA_FORCEfLUSH )
			&& vPositionOld == vPositionNew )
		{
			return ret;
		}

		if( !( nCollistionMask & COLLISION_NOMOVEFLAG ) &&
			( false == pObject->GetMoveFlag() || false == GetMoveFlag() ) )
		{
			return false;
		}

		iPoint iOldCell = WorldToCell( vPositionOld.x, vPositionOld.y );
		iPoint iNewCell = WorldToCell( vPositionNew.x, vPositionNew.y );

		if( nCollistionMask & COLLISION_PATH )
		{
			if( TestCollision( iOldCell.x, iOldCell.y, iNewCell.x, iNewCell.y, pObject->GetBarrierFlag() ) )
			{
				// 设置为非碰撞格子的中心点
				XVector2 fPosition = CellToWorld( iNewCell.x, iNewCell.y );
				vPositionNew.x = fPosition.x;
				vPositionNew.y = fPosition.y;
				vPositionNew.z = 0.0f;

				iNewCell = WorldToCell( vPositionNew.x, vPositionNew.y );
				ret = false;
			}
		}

		if( nCollistionMask & COLLISION_DEST )
		{
			if( IsCellBlock( iNewCell.x, iNewCell.y, pObject->GetBarrierFlag() ) )
			{
				return false;
			}
		}

		iPoint iOldArea = WorldToArea( vPositionOld.x, vPositionOld.y );
		iPoint iNewArea = WorldToArea( vPositionNew.x, vPositionNew.y );

		pObject->SetPosition( vPositionNew ); //设置新位置
		ExchangeBlock( pObject, iOldCell, iNewCell );
		//XGC_DEBUG_CODE( CMapBlock *pArea = GetBlock(x,y); if( pArea ) XGC_ASSERT_MSG( pArea->CheckExist(pObj->GetObjID()), "发现飞机。" ); )
		ExchangeArea( pObject, iOldArea, iNewArea, mMapConf.mEyesight, nCollistionMask );
		//放在ExchangeEyeshotArea后触发
		pObject->OnMove( vPositionOld, lpContext );

		return ret;
	}
Example #4
0
void WallProjectile::Tick(World & world){
	Uint8 life = 20;
	if(state_i == 1){
		EmitSound(world, world.resources.soundbank["!laserel.wav"], 64);
	}
	if(state_i < 7){
		res_index = state_i;
	}
	if(state_i >= 7){
		if(state_i > 12 + life){
			world.MarkDestroyObject(id);
			res_index = 12;
			return;
		}
		if(state_i >= 12 + life - 5){
			res_index = state_i - life;
		}else{
			res_index = 7;
		}
	}
	if(state_i >= 7){
		Object * object = 0;
		Platform * platform = 0;
		if(TestCollision(*this, world, &platform, &object)){
			Overlay * overlay = (Overlay *)world.CreateObject(ObjectTypes::OVERLAY);
			if(overlay){
				overlay->res_bank = 222;
				overlay->x = x;
				overlay->y = y;
				if(platform){
					if(rand() % 2 == 0){
						overlay->EmitSound(world, world.resources.soundbank["strike03.wav"], 96);
					}else{
						overlay->EmitSound(world, world.resources.soundbank["strike04.wav"], 96);
					}
				}
			}
			float xn = 0, yn = 0;
			if(platform){
				platform->GetNormal(x, y, &xn, &yn);
			}
			for(int i = 0; i < 8; i++){
				Shrapnel * shrapnel = (Shrapnel *)world.CreateObject(ObjectTypes::SHRAPNEL);
				if(shrapnel){
					shrapnel->x = x;
					shrapnel->y = y;
					shrapnel->xv = (rand() % 9) - 4;
					shrapnel->yv = (rand() % 9) - 8;
					shrapnel->xv = (xn * abs(shrapnel->xv)) + (rand() % 9) - 4;
					shrapnel->yv = (yn * abs(shrapnel->yv)) + (rand() % 9) - 8;
				}
			}
			world.MarkDestroyObject(id);
		}
	}
	state_i++;
}
OvBool	OvCollisionFinder::TestCollision(OvBox& _rBox0,OvSphere& _rSphere0)
{
	OvPoint3 kpt3NearPt = (_rBox0.GetPosition() - _rSphere0.GetCenter()).Normalize();
	kpt3NearPt = kpt3NearPt*_rSphere0.GetRadius();
	kpt3NearPt = _rSphere0.GetCenter() + kpt3NearPt;
	for (size_t i = 0 ; i < OvBox::PLANE_COUNT ; ++i)
	{
		if (!TestCollision(_rSphere0,_rBox0.GetPlane((OvBox::BOX_PLANE)i)))
			return false;
	}
	return true;
}
Example #6
0
void Tetris::DropPiece(game_info* gi)
{
	while(!TestCollision(gi))
	{
		gi->fine+=0.25;
	}

	engine.PassMessage(MSG_UPDATEPIECE, gi->pos, gi->curdir, gi->curpiece);
	engine.PassMessage(MSG_UPDATEPIECEY, (unsigned char)((gi->fine / 11.0f) * 255.0f), 0, 0);

	AddPiece(gi);
}
Example #7
0
/// Compare each dynamic entity with every other entity in it's current vfcOctree node,
/// all nodes below it as well the direct parents above it.
int PhysicsOctree::FindCollisions(Entity * targetEntity, List<Collision> & collissionList, int entrySubdivisionLevel)
{
	if (entrySubdivisionLevel == -1)
		entrySubdivisionLevel = this->subdivision;

	int collissionsTested = 0;
	/// First it's current node:
	for (int i = 0; i < entities.Size(); ++i){
		Entity * e = entities[i];
		assert(e && "Nullentity in PhysicsOctree::FindCollisions");
		TestCollision(targetEntity, e, collissionList);
		++collissionsTested;
	}

	/// If entry node, begin all recursion.
	if (this->subdivision == entrySubdivisionLevel){
		/// Then all children
		if (child[0] && this->subdivision >= entrySubdivisionLevel)
		for (int i = 0; i < MAX_CHILDREN; ++i){
			/// Do the actual culling with this continue-statement, yo!
			if (child[i]->IsEntityInside(targetEntity) == OUTSIDE)
				continue;
			collissionsTested += child[i]->FindCollisions(targetEntity, collissionList, entrySubdivisionLevel);
		}
		/// And at last all parents
		if (parent && this->subdivision <= entrySubdivisionLevel)
			collissionsTested += parent->FindCollisions(targetEntity, collissionList, entrySubdivisionLevel);
		return collissionsTested;
	}
	/// Process children if subdivision level is higher (further down the tree.)
	else if (this->subdivision > entrySubdivisionLevel){
		/// Then all children
		if (child[0]){
			for (int i = 0; i < MAX_CHILDREN; ++i){
				/// Do the actual culling with this continue-statement, yo!
				if (child[i]->IsEntityInside(targetEntity) == OUTSIDE)
					continue;
				collissionsTested += child[i]->FindCollisions(targetEntity, collissionList, entrySubdivisionLevel);
			}
		}
		return collissionsTested;
	}
	/// And process parents only if lesser subdivision
	else if (this->subdivision < entrySubdivisionLevel){
		/// Then go to next parent.
		if (parent && this->subdivision <= entrySubdivisionLevel)
			collissionsTested += parent->FindCollisions(targetEntity, collissionList, entrySubdivisionLevel);
		return collissionsTested;
	}
	assert(false && "PhysicsOctree::FindCollisions at a point where it shouldn't be!");
	return 0;
}
Example #8
0
void Map::RotatePiece(int direction)
{
    if (currentPiece == NULL)
        return;

    int rotation[4][4];

    for (int i = 0; i < 4; i++)
        for (int j = 0; j < 4; j++)
            if (direction > 0)
                rotation[j][3-i] = currentPiece->area[i][j];
            else
                rotation[3-j][i] = currentPiece->area[i][j];

    memcpy(currentPiece->area, rotation, sizeof(int) * 4 * 4);

    int result = TestCollision(currentX, currentY);
    int tempX = -1;
    for (int i = 0; i < 5 && result > 0; i++)
    {
        tempX = currentX + (2 - i);
        result = TestCollision(tempX, currentY);
    }

    // Can't rotate it
    if (result > 0)
    {
        for (int i = 0; i < 4; i++)
            for (int j = 0; j < 4; j++)
                if (direction <= 0)
                    currentPiece->area[j][3-i] = rotation[i][j];
                else
                    currentPiece->area[3-j][i] = rotation[i][j];
    }
    else if (tempX > 0)
    {
        currentX = tempX;
    }
}
Example #9
0
void Map::MovePiece(int x, int y)
{
    currentX += x;
    if (currentX > width-1)
        currentX = width -1;
    // HERE IS THE PROBLEM.
    // Not any more, sucker!
    if (currentX < -(width / 2.0f))
        currentX = -(width / 2.0f);

    int response = TestCollision(currentX, currentY);
    if (response > 0)
    {
        if (response == 2)
        {
            PlacePiece(currentX, currentY);
        }
        currentX -= x;
    }

    currentY += y;
    if (currentY <= -(height / 2.0f))
        PlacePiece(currentX, currentY-y);

    response = TestCollision(currentX, currentY);
    if (response > 0)
    {
        PlacePiece(currentX, currentY - y);
        currentY -= y;
    }

    if (response > 0 && currentY > (height / 2.0f))
    {
        // Game Over!
        MessageBox(NULL, "Game Over!", "Game Over!", MB_OK);
        g_App->done = true;
    }
}
Example #10
0
// This runs once every physics timestep.
void update()
{

	if (TestCollision(*aabbCollider, box->GetModelMatrix(), glm::vec3(point->translation[3][0], point->translation[3][1], point->translation[3][2])))
	{
		//Turn red on
		hue[0][0] = 1.0f;
	}
	else
	{
		//Turn red off
		hue[0][0] = 0.0f;
	}
}
Example #11
0
// This runs once every physics timestep.
void update()
{

	//Check if the mouse button is being pressed
	if (isMousePressed)
	{
		//Get the current mouse position
		double currentMouseX, currentMouseY;
		glfwGetCursorPos(window, &currentMouseX, &currentMouseY);

		//Get the difference in mouse position from last frame
		float deltaMouseX = (float)(currentMouseX - prevMouseX);
		float deltaMouseY = (float)(currentMouseY - prevMouseY);

		glm::mat4 yaw;
		glm::mat4 pitch;

		//Rotate the selected shape by an angle equal to the mouse movement
		if (deltaMouseX != 0.0f)
		{
			yaw = glm::rotate(glm::mat4(1.0f), deltaMouseX * rotationSpeed, glm::vec3(0.0f, 1.0f, 0.0f));
			
		}
		if (deltaMouseY != 0.0f)
		{
			pitch = glm::rotate(glm::mat4(1.0f), deltaMouseY * rotationSpeed, glm::vec3(1.0f, 0.0f, 0.0f));
			
		}

		selectedShape->rotation = yaw * pitch * selectedShape->rotation;

		//Update previous positions
		prevMouseX = currentMouseX;
		prevMouseY = currentMouseY;

	}

	if (TestCollision(*boxCollider, box->translation, box->rotation, box->scale, glm::vec3(point->translation[3][0], point->translation[3][1], point->translation[3][2])))
	{
		//Turn red on
		hue[0][0] = 1.0f;
	}
	else
	{
		//Turn red off
		hue[0][0] = 0.0f;
	}
}
Example #12
0
// This runs once every physics timestep.
void update()
{

	if (TestCollision(*sphereCollider,																	//Sphere collider 
		glm::vec3(sphere->translation[3][0], sphere->translation[3][1], sphere->translation[3][2]),		//Sphere position
		glm::vec3(point->translation[3][0], point->translation[3][1], point->translation[3][2])))		//Point position
	{
		//Turn red on
		hue[0][0] = 1.0f;
	}
	else
	{
		//Turn red off
		hue[0][0] = 0.0f;
	}
}
Example #13
0
// This runs once every physics timestep.
void update()
{
	//Check if the mouse button is being pressed
	if (isMousePressed)
	{
		//Get the current mouse position
		double currentMouseX, currentMouseY;
		glfwGetCursorPos(window, &currentMouseX, &currentMouseY);

		//Get the difference in mouse position from last frame
		float deltaMouseX = (float)(currentMouseX - prevMouseX);
		float deltaMouseY = (float)(currentMouseY - prevMouseY);

		//Rotate the selected shape by an angle equal to the mouse movement
		if (deltaMouseX != 0.0f)
		{
			glm::mat4 yaw = glm::rotate(glm::mat4(1.0f), deltaMouseX * rotationSpeed, glm::vec3(0.0f, 1.0f, 0.0f));
			plane->rotation = plane->rotation * yaw;
		}
		if (deltaMouseY != 0.0f)
		{
			glm::mat4 pitch = glm::rotate(glm::mat4(1.0f), deltaMouseY * -rotationSpeed, glm::vec3(1.0f, 0.0f, 0.0f));
			plane->rotation = pitch * plane->rotation;
		}
		
		//Update previous positions
		prevMouseX = currentMouseX;
		prevMouseY = currentMouseY;

	}

	if (TestCollision(*sphereCollider, sphere->translation, *planeCollider, plane->translation, plane->rotation))
	{
		//Turn red on
		hue[0][0] = 1.0f;
	}
	else
	{
		//Turn red off
		hue[0][0] = 0.0f;
	}
}
void FlamerProjectile::Tick(World & world){
	for(int i = 0; i < plumecount; i++){
		if(!plumeids[i]){
			Plume * plume = (Plume *)world.CreateObject(ObjectTypes::PLUME);
			if(plume){
				plume->type = 4;
				plume->xv = (rand() % 17) - 8 + (xv * 8);
				plume->yv = (rand() % 17) - 8 + (yv * 8);
				plume->SetPosition(x + (xv * (i * 1)), y + (yv * (i * 1)));
				plumeids[i] = plume->id;
				plume->state_i = i;
				
			}
		}
	}
	Object * object = 0;
	Platform * platform = 0;
	if(TestCollision(*this, world, &platform, &object)){
		float xn = 0, yn = 0;
		if(platform){
			platform->GetNormal(x, y, &xn, &yn);
			for(int i = 0; i < plumecount; i++){
				Plume * plume = (Plume *)world.GetObjectFromId(plumeids[i]);
				if(plume){
					plume->xv /= 3;
					plume->yv /= 3;
					//world->MarkDestroyObject(plumeids[i]);
				}
			}
		}
		//world->MarkDestroyObject(id);
	}
	res_index = state_i;
	if(state_i >= 14){
		world.MarkDestroyObject(id);
	}
	state_i++;
}
Example #15
0
bool Tetris::TestCollision(game_info *gi)
{
	return TestCollision(gi, (0.5) * (double)gi->pos, gi->fine);
}
Example #16
0
void Tetris::Update(game_info* gi, float deltatime)
{
	if (gi->state == STATE_TETRIS_TRANS)
	{
		gi->rot2 += TRANSITION_SPEED * deltatime;

		if (gi->rot2 >= 180)
		{
			gi->rot2 = 180;
			engine.ChangeState(gi, STATE_BREAKOUT);
		}

		engine.PassMessage(MSG_ROT_BOARD2, (gi->rot2 / 180.0f) * 255.0f, 0,0);
		return;
	}

	if (gi->attacking)
	{
		gi->rot += TETRIS_ATTACK_ROT_SPEED * deltatime;
		gi->attack_rot += TETRIS_ATTACK_ROT_SPEED * deltatime;

		if (gi->attack_rot >= 360)
		{
			gi->rot = -BOARD_NORMAL_ROT;
			gi->attack_rot = 0;

			gi->attacking = 0;

			gi->score += (10 * 100);
			engine.PassMessage(MSG_APPENDSCORE, 100, 10, 0);
		}

		engine.PassMessage(MSG_ROT_BOARD, (gi->rot / 360.0f) * 255.0f, 0,0);
	}


	if (!engine.network_thread)
	{
		if (engine.keys[SDLK_DOWN])
		{
			gi->fine += deltatime * (TETRIS_SPEED + 4.3 + 0.3 * LEVEL);
		}
		else
		{
			gi->fine += deltatime * (TETRIS_SPEED + 0.3 * LEVEL);
		}
	}
	else
	{
		if (engine.keys[SDLK_DOWN])
		{
			gi->fine += deltatime * (TETRIS_SPEED + 4.3);
		}
		else
		{
			gi->fine += deltatime * TETRIS_SPEED;
		}
	}

	//gi->rot2+=50.0 * deltatime;

	if (TestCollision(gi))
	{
		// we collided! oh no!
		if (TestGameOver(gi))
		{
			engine.GameOver();
		}
		else
		{
			AddPiece(gi);
		}
	}

	//printf("%f\n", gi->fine);
	engine.PassMessage(MSG_UPDATEPIECEY, (unsigned char)((gi->fine / 11.0f) * 255.0f), 0, 0);
}
Example #17
0
//*************************************************************************************************
// Test a potential collision pair
//*************************************************************************************************
void PhysicsManager::testCollision(PhysicsBody* body1, PhysicsBody* body2)
{
	TestCollision(body1->getAABB(), body2->getAABB());
	int a = 0;
}
Example #18
0
void RocketProjectile::Tick(World & world){
	if(yv < 0 && xv == 0){ // up
		res_index = 4;
	}
	if(yv < 0 && xv > 0){ // up right
		res_index = 3;
		mirrored = false;
	}
	if(yv == 0 && xv > 0){ // right
		res_index = 0;
		mirrored = false;
	}
	if(yv > 0 && xv > 0){ // down right
		res_index = 1;
		mirrored = false;
	}
	if(yv > 0 && xv == 0){ // down
		res_index = 2;
	}
	if(yv > 0 && xv < 0){ // down left
		res_index = 1;
		mirrored = true;
	}
	if(yv == 0 && xv < 0){ // left
		res_index = 0;
		mirrored = true;
	}
	if(yv < 0 && xv < 0){ // up left
		res_index = 3;
		mirrored = true;
	}
	if(state_i == 100){
		oldxv = xv;
		oldyv = yv;
		xv = ceil(float(xv) * 0.3);
		yv = ceil(float(yv) * 0.3);
		soundchannel = EmitSound(world, world.resources.soundbank["rocket4.wav"], 128);
		state_i = 11;
		res_bank = 87;
	}
	if(state_i == 0){
		oldxv = xv;
		oldyv = yv;
		xv = ceil(float(xv) * 0.2);
		yv = ceil(float(yv) * 0.2);
		soundchannel = EmitSound(world, world.resources.soundbank["rocket9.wav"], 128);
	}
	if(state_i == 3){
		res_bank = 87;
	}
	if(state_i == 11){
		if(xv > 0){
			xv++;
		}else{
			xv--;
		}
		if(yv > 0){
			yv++;
		}else{
			yv--;
		}
		if(abs(xv) > abs(oldxv)){
			xv = oldxv;
		}
		if(abs(yv) > abs(oldyv)){
			yv = oldyv;
		}
		Platform * platform = 0;
		Object * object = 0;
		Sint16 oldx = x;
		Sint16 oldy = y;
		if(TestCollision(*this, world, &platform, &object)){
			float xn = 0, yn = 0;
			if(platform){
				platform->GetNormal(x, y, &xn, &yn);
			}
			int numplumes = 6;
			float anglen = (rand() % 100) / float(100);
			for(int i = 0; i < numplumes; i++){
				Plume * plume = (Plume *)world.CreateObject(ObjectTypes::PLUME);
				if(plume){
					plume->type = 4;
					/*plume->xv = (rand() % 17) - 8;
					plume->yv = (rand() % 17) - 8;
					plume->xv = (xn * abs(plume->xv)) + (rand() % 33) - 16;
					plume->yv = (yn * abs(plume->yv)) + (rand() % 33) - 16;*/
					float angle = (i / float(numplumes)) * (2 * 3.14);
					angle += anglen;
					plume->xv = (sin(angle)) * 15;
					plume->yv = (cos(angle)) * 15;
					if(xn || yn){
						plume->xv = (xn * abs(plume->xv)) + (rand() % 17) - 8;
						plume->yv = (yn * abs(plume->yv)) + (rand() % 17) - 8;
					}
					plume->SetPosition(x, y);
					
					Plume * plume2 = (Plume *)world.CreateObject(ObjectTypes::PLUME);
					if(plume2){
						plume2->type = 4;
						plume2->xv = plume->xv + (rand() % 7) - 3;
						plume2->yv = plume->yv + (rand() % 7) - 3;
						plume2->SetPosition(x, y);
					}
				}
			}
			std::vector<Uint8> types;
			types.push_back(ObjectTypes::PLAYER);
			types.push_back(ObjectTypes::GUARD);
			types.push_back(ObjectTypes::ROBOT);
			types.push_back(ObjectTypes::CIVILIAN);
			types.push_back(ObjectTypes::FIXEDCANNON);
			types.push_back(ObjectTypes::WALLDEFENSE);
			types.push_back(ObjectTypes::TECHSTATION);
			Object * owner = world.GetObjectFromId(ownerid);
			Uint16 teamid = 0;
			bool issecurity = false;
			if(owner){
				switch(owner->type){
					case ObjectTypes::PLAYER:{
						Player * player = static_cast<Player *>(owner);
						Team * team = player->GetTeam(world);
						if(team){
							teamid = team->id;
						}
					}break;
					case ObjectTypes::ROBOT:{
						Robot * robot = static_cast<Robot *>(owner);
						teamid = robot->virusplanter;
						issecurity = world.IsSecurity(*robot);
					}break;
					case ObjectTypes::GUARD:{
						issecurity = true;
					}break;
				}
			}
			std::vector<Object *> objects = world.TestAABB(x - 30, y - 30, x + 30, y + 30, types, ownerid, teamid);
			for(std::vector<Object *>::iterator it = objects.begin(); it != objects.end(); it++){
				if(!object || (object && (*it)->id != object->id)){
					if(!issecurity || (issecurity && !world.IsSecurity(*(*it)))){ // prevents robots/rocket guards from doing slash damage to other security
						Object damageprojectile(ObjectTypes::ROCKETPROJECTILE);
						damageprojectile.healthdamage = healthdamage;
						damageprojectile.shielddamage = shielddamage;
						damageprojectile.ownerid = ownerid;
						(*it)->HandleHit(world, 50, 50, damageprojectile);
					}
				}
			}
			xv = 0;
			yv = 0;
			res_bank = 0xFF;
			if(soundchannel){
				Audio::GetInstance().Stop(soundchannel, 100);
			}
			EmitSound(world, world.resources.soundbank["seekexp1.wav"], 128);
		}
		for(int i = 0; i < 2; i++){
			int xv2 = (signed(oldx) - x) * (1.25 * i);
			int yv2 = (signed(oldy) - y) * (1.25 * i);
			Plume * plume = (Plume *)world.CreateObject(ObjectTypes::PLUME);
			if(plume){
				plume->type = 3;
				plume->xv = rand() % 7 - 3;
				plume->yv = rand() % 7 - 3;
				plume->SetPosition(x + xv2, y + yv2);
			}
		}
	}
	if(state_i < 11 || (state_i >= 11 && xv == 0 && yv == 0)){
		state_i++;
	}
	if(state_i >= 25){
		world.MarkDestroyObject(id);
	}else{
		Player * localplayer = world.GetPeerPlayer(world.localpeerid);
		if(localplayer && ownerid == localplayer->id){
			//if(!world.systemcameraactive[0]){
				world.SetSystemCamera(0, id, 0, 20);
			//}
		}
	}
}