Example #1
0
void Bullet::process_move()
{
	//-------------- update position -----------------//
	//
	// If it gets very close to the destination, fit it
	// to the destination ingoring the normal vector.
	//
	//------------------------------------------------//

	cur_x = origin_x + (int)(go_x-origin_x) * cur_step / total_step;
	cur_y = origin_y + (int)(go_y-origin_y) * cur_step / total_step;

	//cur_step++;

	//------- update frame id. --------//

	if( ++cur_frame > cur_sprite_move()->frame_count )
		cur_frame = 1;

	//----- if the sprite has reach the destintion ----//

	//if( cur_step > total_step )
	if( ++cur_step > total_step )
	{
		check_hit();

		cur_action = SPRITE_DIE;		// Explosion

		// ###### begin Gilbert 17/5 #########//
		// if it has die frame, adjust cur_x, cur_y to be align with the target_x_loc, target_y_loc
		if( sprite_info->die.first_frame_recno )
		{
			next_x = cur_x = target_x_loc * ZOOM_LOC_WIDTH;
			next_y =cur_y = target_y_loc * ZOOM_LOC_HEIGHT;
		}
		// ###### end Gilbert 17/5 #########//

		cur_frame = 1;
	}
	else if( total_step - cur_step == 1 )
	{
		warn_target();
	}
}
Example #2
0
void Tornado::process_move()
{
	int speed = weather.wind_speed() / 6;
	int minSpeed = magic_weather.wind_day > 0 ? 1 : 5;
	if( speed < minSpeed)
		speed = minSpeed;
	if( speed > 10)
		speed = 10;

	double windDir = weather.wind_direct_rad() + (misc.random(31)-15)*PI/180.0;
	cur_x += short(speed * sin(windDir));
	cur_y -= short(speed * cos(windDir));
	if( ++cur_frame > cur_sprite_move()->frame_count )
		cur_frame = 1;
	// static UCHAR nextFrame[] = { 1,6,1,1,1,1,4 };		// 1->6->4->1 ...
	// cur_frame = nextFrame[cur_frame];

	hit_target();
}
Example #3
0
void Sprite::process_move()
{
	#ifdef DEBUG
	int debugStepMagn1 = move_step_magn();
	err_when(abs(cur_x-next_x)>LOCATE_WIDTH*debugStepMagn1 || abs(cur_y-next_y)>LOCATE_HEIGHT*debugStepMagn1);
	#endif

	//---- for some sprite (e.g. elephant), move one step per a few frames ----//

	if( --remain_frames_per_step > 0 )
		return;
	else
		remain_frames_per_step = sprite_info->frames_per_step;

	err_when(cur_x < 0 || cur_y < 0 || cur_x >= MAX_WORLD_X_LOC * LOCATE_WIDTH || cur_y >= MAX_WORLD_Y_LOC * LOCATE_HEIGHT);
	err_when(cur_x-next_x!=0 && cur_y-next_y!=0 && abs(next_x-cur_x)!=abs(next_y-cur_y));

	//----- if the sprite has reach the destintion ----//

	if( cur_x==go_x && cur_y==go_y)
	{
		cur_action = SPRITE_IDLE;
		
		int rc = set_next(cur_x, cur_y);			//********* BUGHERE

		err_when( !rc );

#ifdef DEBUG
		char h, w, blocked=0;
		short x, y;

		for(h=0, y=next_y_loc(); h<sprite_info->loc_height&&!blocked; h++, y++)
		{
			for(w=0, x=next_x_loc(); w<sprite_info->loc_width&&!blocked; w++, x++)
				blocked = world.get_loc(x, y)->unit_recno(mobile_type) != sprite_recno;
		}
		err_if(blocked)
			err_here();
#endif
		cur_frame  = 1;
		return;
	}

	err_when(cur_x-next_x!=0 && cur_y-next_y!=0 && abs(next_x-cur_x)!=abs(next_y-cur_y));

	//---- set the next tile the sprite will be moving towards ---//

	static short vector_x_array[] = {  0,  1, 1, 1, 0, -1, -1, -1 };	// default vectors, temporary only
	static short vector_y_array[] = { -1, -1, 0, 1, 1,  1,  0, -1 };

//	short stepX = sprite_info->speed;
//	short stepY = sprite_info->speed;
	short stepX, stepY;
	stepX = stepY = sprite_speed();

	if( final_dir & 1 )		// diagonal direction slower
	{
		if( stepX >=8  )
		{
			stepY = (stepX -= (unsigned)stepX /4 );			// slightly fast for unsigned division
		}
		else if( stepX >= 3 )
		{
			--stepX;
			--stepY;
		}
	}

	//------------------------------------------//

	if( next_x != go_x || next_y != go_y )		// if next_x==go_x & next_y==go_y, reach destination already, don't move further.
	{
		if( abs(cur_x-next_x) <= stepX && abs(cur_y-next_y) <= stepY )
		{
			int stepMagn = move_step_magn();

			if( !set_next(next_x+stepMagn*move_x_pixel_array[final_dir], next_y+stepMagn*move_y_pixel_array[final_dir], -stepMagn) )
				return;
		}
	}

	err_when(cur_x-next_x!=0 && cur_y-next_y!=0 && abs(next_x-cur_x)!=abs(next_y-cur_y));
	
	//---- if the is blocked, cur_action is changed to SPRITE_WAIT, return now ----//

	if( cur_action != SPRITE_MOVE )
		return;

	//-------------- update position -----------------//
	//
	// If it gets very close to the destination, fit it
	// to the destination ingoring the normal vector.
	//
	//------------------------------------------------//

	short vectorX = vector_x_array[final_dir] * stepX;	// cur_dir may be changed in the above set_next() call
	short vectorY = vector_y_array[final_dir] * stepY;

	if( abs(cur_x-go_x) <= stepX )
		cur_x = go_x;
	else
		cur_x += vectorX;

	if( abs(cur_y-go_y) <= stepY )
		cur_y = go_y;
	else
		cur_y += vectorY;

	err_when(cur_x-next_x!=0 && cur_y-next_y!=0 && abs(next_x-cur_x)!=abs(next_y-cur_y));	// is a better checking if speed in all direction is equal
	#ifdef DEBUG
	int debugStepMagn2 = move_step_magn();
	err_when(abs(cur_x-next_x)>LOCATE_WIDTH*debugStepMagn1 || abs(cur_y-next_y)>LOCATE_HEIGHT*debugStepMagn1);
	#endif

	//-------- check boundary ---------//

	err_when(cur_x < 0 || cur_y < 0 || cur_x >= MAX_WORLD_X_LOC * LOCATE_WIDTH || cur_y >= MAX_WORLD_Y_LOC * LOCATE_HEIGHT);

	//------- update frame id. --------//

	if( ++cur_frame > cur_sprite_move()->frame_count )
		cur_frame = 1;
}
Example #4
0
// --------- begin of function BulletHoming::process_move --------//
void BulletHoming::process_move()
{
	int actualStep = total_step;

	if(target_type == BULLET_TARGET_UNIT)
	{
		Unit *unitPtr;
		if( unit_array.is_deleted(target_recno) || 
			!(unitPtr = unit_array[target_recno]) || 
			!unitPtr->is_visible() )
		{
			// target lost/die, proceed to Bullet::process_move
			target_type = BULLET_TARGET_NONE;
		}
		else
		{
			// ---- calculate new target_x_loc, target_y_loc -----//	

			target_x_loc = unitPtr->next_x_loc();
			target_y_loc = unitPtr->next_y_loc();

			// ---- re-calculate go_x, go_y  ------//
			// go_x/y and origin2_x/y are pointing at the centre of the bullet bitmap
			// it is different from Bullet
			go_x = unitPtr->cur_x + ZOOM_LOC_WIDTH / 2;
			go_y = unitPtr->cur_y + ZOOM_LOC_HEIGHT /2;

			//---------- set bullet movement steps -----------//
			SpriteFrame *spriteFrame = cur_sprite_frame();
			int adjX = spriteFrame->offset_x+spriteFrame->width/2;
			int adjY = spriteFrame->offset_y+spriteFrame->height/2;

			int xStep 	= abs(go_x - (cur_x+adjX))/speed;
			int yStep 	= abs(go_y - (cur_y+adjY))/speed;
			total_step  = cur_step +  MAX(xStep, yStep);

			// a homing bullet has a limited range, if the target go outside the
			// the limit, the bullet can't attack the target
			// in this case, actualStep is the number step from the source
			// to the target; total_step is the max_step
			// otherwise, actualStep is as same as total_step
			
			actualStep = total_step;
			if( total_step > max_step )
			{
				total_step = max_step;
				// target_x_loc and target_y_loc is limited also
				target_x_loc = (cur_x + adjX) + (int)(go_x-(cur_x+adjX)) / (actualStep - total_step) / ZOOM_LOC_WIDTH;
				target_x_loc = (cur_y + adjY) + (int)(go_y-(cur_y+adjY)) / (actualStep - total_step) / ZOOM_LOC_HEIGHT;
			}
		}
	}

//	origin2_x = origin_x;
//	origin2_y = origin_y;

	// origin_x/y and origin2_x/y are pointing at the centre of the bullet bitmap //
	SpriteFrame *spriteFrame = cur_sprite_frame();
	short adjX = spriteFrame->offset_x + spriteFrame->width/2;
	short adjY = spriteFrame->offset_y + spriteFrame->height/2;
	origin_x = cur_x + adjX;
	origin_y = cur_y + adjY;

	cur_x = origin_x + (int)(go_x-origin_x) / (actualStep + 1 - cur_step);
	cur_y = origin_y + (int)(go_y-origin_y) / (actualStep + 1 - cur_step);
	// cur_x, cur_y is temporary pointing at the centre of bullet bitmap

	// detect changing direction
	if( cur_step > 3 )	// not allow changing direction so fast
		set_dir(origin2_x, origin2_y, cur_x, cur_y);

	// change cur_x, cur_y to bitmap reference point
	spriteFrame= cur_sprite_frame();
	adjX = spriteFrame->offset_x + spriteFrame->width/2;
	adjY = spriteFrame->offset_y + spriteFrame->height/2;
	cur_x -= adjX;
	cur_y -= adjY;

	cur_step++;

	//------- update frame id. --------//

	if( ++cur_frame > cur_sprite_move()->frame_count )
		cur_frame = 1;

	//----- if the sprite has reach the destintion ----//

	if( cur_step > total_step )
	{
		check_hit();

		cur_action = SPRITE_DIE;		// Explosion
		// ###### begin Gilbert 17/5 ########//
		// if it has die frame, adjust cur_x, cur_y to be align with the target_x_loc, target_y_loc
		if( sprite_info->die.first_frame_recno )
		{
			next_x = cur_x = target_x_loc * ZOOM_LOC_WIDTH;
			next_y = cur_y = target_y_loc * ZOOM_LOC_HEIGHT;
		}
		// ###### end Gilbert 17/5 ########//
		cur_frame = 1;
	}
	// change of total_step may not call warn_target, so call more warn_target
	else if( total_step - cur_step <= 1 )
	{
		warn_target();
	}
}