コード例 #1
0
ファイル: baul.c プロジェクト: jurchik/project6014
static void
gas_preprocess (ELEMENT *ElementPtr)
{	
	STARSHIP *StarShipPtr;
	SDWORD dx, dy;
	
	// Baul's gas now flies forward. Slow down the gas smoothly.
	GetCurrentVelocityComponentsSdword (&ElementPtr->velocity, &dx, &dy);
	if (dx != 0 || dy != 0)
	{
		dx = (SDWORD)(dx * 9 / 10);
		dy = (SDWORD)(dy * 9 / 10);
		SetVelocityComponents (&ElementPtr->velocity, dx, dy);
	}
		
	GetElementStarShip (ElementPtr, &StarShipPtr);
	
	// Move to next image frame. (Abusing thrust_wait to slow down the anim.)
	if (ElementPtr->thrust_wait > 0)
		--ElementPtr->thrust_wait;
	else
	{
		// Abusing thrust_wait to slow down the anim. (Should help performance a bit.)
		ElementPtr->thrust_wait = 1;
		
		// This makes the gas animate even if the ships are not moving and the screen is stationary.
		ElementPtr->state_flags |= CHANGING;
		
		if (GetFrameIndex (ElementPtr->current.image.frame) >= LAST_DISSOLVE_INDEX
			&& GetFrameIndex (ElementPtr->current.image.frame) < LAST_DISSOLVE_INDEX + NUM_EMERGE_FRAMES)
			ElementPtr->next.image.frame = IncFrameIndex (ElementPtr->current.image.frame);
		else if (GetFrameIndex (ElementPtr->current.image.frame) < LAST_GAS_INDEX - 1)
			ElementPtr->next.image.frame = IncFrameIndex (ElementPtr->current.image.frame);
		else
			ElementPtr->next.image.frame = SetAbsFrameIndex (ElementPtr->current.image.frame, 0);
	}
	
	// If enemy ship dies, remove the gas (this prevents game crashing upon enemy ship dying with gas on it).
	if ((!(ElementPtr->state_flags & IGNORE_VELOCITY) && ElementPtr->hTarget == 0)
		|| StarShipPtr->RaceDescPtr->ship_info.crew_level == 0)
	{
		ElementPtr->life_span = 0;
		ElementPtr->state_flags |= DISAPPEARING;
	}
	// When the gas has collided with enemy ship, it sticks to the ship until expires.
	// (When the gas is sticking to enemy ship, the gas's IGNORE_VELOCITY flag is disabled.)
	else if (!(ElementPtr->state_flags & IGNORE_VELOCITY) && !(ElementPtr->state_flags & DISAPPEARING))
	{
		ELEMENT *eptr;
		SIZE offs_x, offs_y;
		SBYTE leftOrRight, upOrDown;
		COUNT angle, angleCorrect;
		static BYTE alignment[NUM_SIDES]={0,0};
		
		// eptr points to enemy ship now.
		LockElement (ElementPtr->hTarget, &eptr);
		
		// Make gas's location the same as the enemy ship's.
		ElementPtr->next.location = eptr->next.location;
		
		// Randomize the gas's location so every gas cloud doesn't stick to the same place on the enemy ship.
		GetElementStarShip (eptr, &StarShipPtr);
		angle = (ElementPtr->weapon_element_index) % 16;
		alignment[ElementPtr->playerNr] = ElementPtr->weapon_element_index % 4;
		if (alignment[ElementPtr->playerNr] == 0)
		{
			leftOrRight = -1;
			upOrDown = 1;
			angleCorrect = 0;
		}
		else if (alignment[ElementPtr->playerNr] == 1)
		{
			leftOrRight = 1;
			upOrDown = -1;
			angleCorrect = 0;
		}
		else if (alignment[ElementPtr->playerNr] == 2)
		{
			leftOrRight = -1;
			upOrDown = 1;
			angleCorrect = HALF_CIRCLE / 2;
		}
		else
		{
			leftOrRight = 1;
			upOrDown = -1;
			angleCorrect = HALF_CIRCLE / 2;
		}
		offs_x = SINE (angle - angleCorrect, (ElementPtr->weapon_element_index % 16) * (5 << RESOLUTION_FACTOR));
		offs_y = COSINE (angle - angleCorrect, (ElementPtr->weapon_element_index % 16) * (5 << RESOLUTION_FACTOR));
		ElementPtr->next.location.x = ElementPtr->next.location.x + leftOrRight * offs_x;
		ElementPtr->next.location.y = ElementPtr->next.location.y + upOrDown * offs_y;
	
		if (ElementPtr->turn_wait)
		{
			HELEMENT hEffect;
			
			hEffect = AllocElement ();
			if (hEffect)
			{
				// eptr points to the new gas element now.
				LockElement (hEffect, &eptr);
				eptr->playerNr = ElementPtr->playerNr;
				eptr->state_flags = FINITE_LIFE | GASSY_SUBSTANCE | CHANGING;
				eptr->life_span = 1;
				eptr->thrust_wait = 1;
				eptr->weapon_element_index = ElementPtr->weapon_element_index;
				eptr->current = eptr->next = ElementPtr->next;
				eptr->preprocess_func = gas_preprocess;
				eptr->collision_func = gas_collision;
				// No need to have death_func here: It carries on from the declaration in gas_collision.
				// In fact, if gas_death is put here as death_func, it just messes up the graphics.
				
				SetPrimType (&(GLOBAL (DisplayArray))[eptr->PrimIndex], STAMP_PRIM);
				GetElementStarShip (ElementPtr, &StarShipPtr);
				SetElementStarShip (eptr, StarShipPtr);
				eptr->hTarget = ElementPtr->hTarget;
				
				UnlockElement (hEffect);
				PutElement (hEffect);
			}
		}
		
		UnlockElement (ElementPtr->hTarget);
	}
}
コード例 #2
0
ファイル: thradd.c プロジェクト: smaass/UQM-MegaMod
static void
thraddash_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern,
		COUNT ConcernCounter)
{

	STARSHIP *StarShipPtr;
	EVALUATE_DESC *lpEvalDesc;
	
	lpEvalDesc = &ObjectsOfConcern[ENEMY_SHIP_INDEX];
	if (lpEvalDesc->ObjectPtr)
	{
		SDWORD dx, dy;

		GetCurrentVelocityComponentsSdword (
				&lpEvalDesc->ObjectPtr->velocity, &dx, &dy
				);
		if (lpEvalDesc->which_turn > 8
				|| (long)dx * dx + (long)dy * dy <=
				(long)STATIONARY_SPEED * STATIONARY_SPEED)
			lpEvalDesc->MoveState = PURSUE;
		else
			lpEvalDesc->MoveState = ENTICE;
	}
	ship_intelligence (ShipPtr, ObjectsOfConcern, ConcernCounter);

	GetElementStarShip (ShipPtr, &StarShipPtr);
	if (StarShipPtr->special_counter == 0)
	{
		StarShipPtr->ship_input_state &= ~SPECIAL;
		if (ObjectsOfConcern[ENEMY_WEAPON_INDEX].ObjectPtr
				&& ObjectsOfConcern[ENEMY_WEAPON_INDEX].MoveState == ENTICE)
		{
			if ((StarShipPtr->ship_input_state & THRUST)
					|| (ShipPtr->turn_wait == 0
					&& !(StarShipPtr->ship_input_state & (LEFT | RIGHT)))
					|| NORMALIZE_FACING (ANGLE_TO_FACING (
					GetVelocityTravelAngle (
					&ObjectsOfConcern[ENEMY_WEAPON_INDEX].ObjectPtr->velocity
					) + HALF_CIRCLE + OCTANT)
					- StarShipPtr->ShipFacing) > ANGLE_TO_FACING (QUADRANT))
				StarShipPtr->ship_input_state |= SPECIAL;
		}
		else if (lpEvalDesc->ObjectPtr)
		{
			if (lpEvalDesc->MoveState == PURSUE)
			{
				if (StarShipPtr->RaceDescPtr->ship_info.energy_level >= WEAPON_ENERGY_COST
						+ SPECIAL_ENERGY_COST
						&& ShipPtr->turn_wait == 0
						&& !(StarShipPtr->ship_input_state & (LEFT | RIGHT))
						&& (!(StarShipPtr->cur_status_flags & SPECIAL)
						|| !(StarShipPtr->cur_status_flags
						& (SHIP_AT_MAX_SPEED | SHIP_BEYOND_MAX_SPEED))))
					StarShipPtr->ship_input_state |= SPECIAL;
			}
			else if (lpEvalDesc->MoveState == ENTICE)
			{
				COUNT direction_angle;
				SDWORD delta_x, delta_y;

				delta_x = lpEvalDesc->ObjectPtr->next.location.x
						- ShipPtr->next.location.x;
				delta_y = lpEvalDesc->ObjectPtr->next.location.y
						- ShipPtr->next.location.y;
				direction_angle = ARCTAN (delta_x, delta_y);

				if ((lpEvalDesc->which_turn > 24
						&& !(StarShipPtr->ship_input_state & (LEFT | RIGHT)))
						|| (lpEvalDesc->which_turn <= 16
						&& NORMALIZE_ANGLE (direction_angle
						- (FACING_TO_ANGLE (StarShipPtr->ShipFacing) + HALF_CIRCLE)
						+ QUADRANT) <= HALF_CIRCLE
						&& (lpEvalDesc->which_turn < 12
						|| NORMALIZE_ANGLE (direction_angle
						- (GetVelocityTravelAngle (
								&lpEvalDesc->ObjectPtr->velocity
								) + HALF_CIRCLE)
						+ (OCTANT + 2)) <= ((OCTANT + 2) << 1))))
					StarShipPtr->ship_input_state |= SPECIAL;
			}
		}

		if ((StarShipPtr->ship_input_state & SPECIAL)
				&& StarShipPtr->RaceDescPtr->ship_info.energy_level >=
				SPECIAL_ENERGY_COST)
			StarShipPtr->ship_input_state &= ~THRUST;
	}
}