Esempio n. 1
0
static void
doggy_collision (ELEMENT *ElementPtr0, POINT *pPt0,
		ELEMENT *ElementPtr1, POINT *pPt1)
{
	collision (ElementPtr0, pPt0, ElementPtr1, pPt1);
	if ((ElementPtr1->state_flags & PLAYER_SHIP)
			&& !elementsOfSamePlayer (ElementPtr0, ElementPtr1))
	{
		STARSHIP *StarShipPtr;

		GetElementStarShip (ElementPtr0, &StarShipPtr);
		ProcessSound (SetAbsSoundIndex (
						/* DOGGY_STEALS_ENERGY */
				StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2), ElementPtr0);
		GetElementStarShip (ElementPtr1, &StarShipPtr);
		if (StarShipPtr->RaceDescPtr->ship_info.energy_level < ENERGY_DRAIN)
			DeltaEnergy (ElementPtr1, -StarShipPtr->RaceDescPtr->ship_info.energy_level);
		else
			DeltaEnergy (ElementPtr1, -ENERGY_DRAIN);
	}
	if (ElementPtr0->thrust_wait <= COLLISION_THRUST_WAIT)
		ElementPtr0->thrust_wait += COLLISION_THRUST_WAIT << 1;
}
Esempio n. 2
0
static void
spawn_crew (ELEMENT *ElementPtr)
{
	if (ElementPtr->state_flags & PLAYER_SHIP)
	{
		HELEMENT hCrew;

		hCrew = AllocElement ();
		if (hCrew != 0)
		{
			ELEMENT *CrewPtr;

			LockElement (hCrew, &CrewPtr);
			CrewPtr->next.location = ElementPtr->next.location;
			CrewPtr->playerNr = ElementPtr->playerNr;
			CrewPtr->state_flags = APPEARING | NONSOLID | FINITE_LIFE;
			CrewPtr->life_span = 0;
			CrewPtr->death_func = spawn_crew;
			CrewPtr->pParent = ElementPtr->pParent;
			CrewPtr->hTarget = 0;
			UnlockElement (hCrew);

			PutElement (hCrew);
		}
	}
	else
	{
		HELEMENT hElement, hNextElement;

		for (hElement = GetHeadElement ();
				hElement != 0; hElement = hNextElement)
		{
			ELEMENT *ObjPtr;

			LockElement (hElement, &ObjPtr);
			hNextElement = GetSuccElement (ObjPtr);

			if ((ObjPtr->state_flags & PLAYER_SHIP)
					&& !elementsOfSamePlayer (ObjPtr, ElementPtr)
					&& ObjPtr->crew_level > 1)
			{
				SIZE dx, dy;
				DWORD d_squared;

				dx = ObjPtr->next.location.x - ElementPtr->next.location.x;
				if (dx < 0)
					dx = -dx;
				dy = ObjPtr->next.location.y - ElementPtr->next.location.y;
				if (dy < 0)
					dy = -dy;

				dx = WORLD_TO_DISPLAY (dx);
				dy = WORLD_TO_DISPLAY (dy);
#define ABANDONER_RANGE (208 << RESOLUTION_FACTOR) // JMS_GFX /* originally SPACE_HEIGHT */
				if (dx <= ABANDONER_RANGE && dy <= ABANDONER_RANGE
						&& (d_squared = (DWORD)((UWORD)dx * (UWORD)dx)
						+ (DWORD)((UWORD)dy * (UWORD)dy)) <=
						(DWORD)((UWORD)ABANDONER_RANGE * (UWORD)ABANDONER_RANGE))
				{
#define MAX_ABANDONERS 8
					COUNT crew_loss;

					crew_loss = ((MAX_ABANDONERS
							* (ABANDONER_RANGE - square_root (d_squared)))
							/ ABANDONER_RANGE) + 1;
					if (crew_loss >= ObjPtr->crew_level)
						crew_loss = ObjPtr->crew_level - 1;

					AbandonShip (ObjPtr, ElementPtr, crew_loss);
				}
			}

			UnlockElement (hElement);
		}
	}
}
Esempio n. 3
0
static void
confusion_collision (ELEMENT *ElementPtr0, POINT *pPt0,
                     ELEMENT *ElementPtr1, POINT *pPt1)
{
    if (ElementPtr1->state_flags & PLAYER_SHIP)
    {
        HELEMENT hConfusionElement, hNextElement;
        ELEMENT *ConfusionPtr;
        STARSHIP *StarShipPtr;

        GetElementStarShip (ElementPtr0, &StarShipPtr);
        for (hConfusionElement = GetHeadElement ();
                hConfusionElement; hConfusionElement = hNextElement)
        {
            LockElement (hConfusionElement, &ConfusionPtr);
            if (elementsOfSamePlayer (ConfusionPtr, ElementPtr0)
                    && ConfusionPtr->current.image.farray ==
                    StarShipPtr->RaceDescPtr->ship_data.special
                    && (ConfusionPtr->state_flags & NONSOLID))
            {
                UnlockElement (hConfusionElement);
                break;
            }
            hNextElement = GetSuccElement (ConfusionPtr);
            UnlockElement (hConfusionElement);
        }

        if (hConfusionElement || (hConfusionElement = AllocElement ()))
        {
            LockElement (hConfusionElement, &ConfusionPtr);

            if (ConfusionPtr->state_flags == 0) /* not allocated before */
            {
                InsertElement (hConfusionElement, GetHeadElement ());

                ConfusionPtr->current = ElementPtr0->next;
                ConfusionPtr->current.image.frame = SetAbsFrameIndex (
                                                        ConfusionPtr->current.image.frame, 8
                                                    );
                ConfusionPtr->next = ConfusionPtr->current;
                ConfusionPtr->playerNr = ElementPtr0->playerNr;
                ConfusionPtr->state_flags = FINITE_LIFE | NONSOLID | CHANGING;
                ConfusionPtr->preprocess_func = confuse_preprocess;
                SetPrimType (
                    &(GLOBAL (DisplayArray))[ConfusionPtr->PrimIndex],
                    NO_PRIM
                );

                SetElementStarShip (ConfusionPtr, StarShipPtr);
                GetElementStarShip (ElementPtr1, &StarShipPtr);
                ConfusionPtr->hTarget = StarShipPtr->hShip;
            }

            ConfusionPtr->life_span = 400;
            ConfusionPtr->turn_wait =
                (BYTE)(1 << ((BYTE)TFB_Random () & 1)); /* LEFT or RIGHT */

            UnlockElement (hConfusionElement);
        }

        ElementPtr0->hit_points = 0;
        ElementPtr0->life_span = 0;
        ElementPtr0->state_flags |= DISAPPEARING | COLLISION | NONSOLID;
    }
    (void) pPt0;  /* Satisfying compiler (unused parameter) */
    (void) pPt1;  /* Satisfying compiler (unused parameter) */
}
static void
spawn_crew (ELEMENT *ElementPtr)
{
	if (ElementPtr->state_flags & PLAYER_SHIP)
	{
		HELEMENT hCrew;

		hCrew = AllocElement ();
		if (hCrew != 0)
		{
			ELEMENT *CrewPtr;

			LockElement (hCrew, &CrewPtr);
			CrewPtr->next.location = ElementPtr->next.location;
			CrewPtr->playerNr = ElementPtr->playerNr;
			CrewPtr->state_flags = APPEARING | NONSOLID | FINITE_LIFE;
			CrewPtr->life_span = 0;
			CrewPtr->death_func = spawn_crew;
			CrewPtr->pParent = ElementPtr->pParent;
			CrewPtr->hTarget = 0;
			UnlockElement (hCrew);

			PutElement (hCrew);
		}
	}
	else
	{
		HELEMENT hElement, hNextElement;

		for (hElement = GetHeadElement ();
				hElement != 0; hElement = hNextElement)
		{
			ELEMENT *ObjPtr;
            STARSHIP *EnemyStarShipPtr;

			LockElement (hElement, &ObjPtr);
            GetElementStarShip (ObjPtr, &EnemyStarShipPtr);
			hNextElement = GetSuccElement (ObjPtr);

			if ((ObjPtr->state_flags & PLAYER_SHIP)
					&& !elementsOfSamePlayer (ObjPtr, ElementPtr)
					&& ObjPtr->crew_level > 1)
			{
				SIZE dx, dy;
				DWORD d_squared;

				dx = ObjPtr->next.location.x - ElementPtr->next.location.x;
				if (dx < 0)
					dx = -dx;
				dy = ObjPtr->next.location.y - ElementPtr->next.location.y;
				if (dy < 0)
					dy = -dy;

				dx = WORLD_TO_DISPLAY (dx);
				dy = WORLD_TO_DISPLAY (dy);
                
				if (dx <= ABANDONER_RANGE && dy <= ABANDONER_RANGE
						&& (d_squared = (DWORD)((UWORD)dx * (UWORD)dx)
						+ (DWORD)((UWORD)dy * (UWORD)dy)) <=
						(DWORD)((UWORD)ABANDONER_RANGE * (UWORD)ABANDONER_RANGE))
				{
					COUNT crew_loss;

					if (EnemyStarShipPtr && EnemyStarShipPtr->SpeciesID == SYREEN_ID)
					{
						crew_loss = ((LIMITED_MAX_ABANDONERS
							* (ABANDONER_RANGE - square_root (d_squared)))
							/ ABANDONER_RANGE) + 1;
					}
					else
					{
						crew_loss = ((MAX_ABANDONERS
							* (ABANDONER_RANGE - square_root (d_squared)))
							/ ABANDONER_RANGE) + 1;
                    }
                    
					if (crew_loss >= ObjPtr->crew_level)
						crew_loss = ObjPtr->crew_level - 1;

					AbandonShip (ObjPtr, ElementPtr, crew_loss);
				}
			}

			UnlockElement (hElement);
		}
	}
}
Esempio n. 5
0
static void
gas_collision (ELEMENT *ElementPtr0, POINT *pPt0, ELEMENT *ElementPtr1, POINT *pPt1)
{
	STARSHIP *StarShipPtr;
	STARSHIP *EnemyStarShipPtr;
	BYTE	 enemyShipIsBaul = 0;
	BYTE	 enemyShipIsChmmr = 0;
	
	// This is the ship this gas cloud belongs to.
	GetElementStarShip (ElementPtr0, &StarShipPtr);
	
	// Check if the colliding element is a ship. If it is not, check if it's a projectile from Baul or Chmmr ship.
	if (!elementsOfSamePlayer(ElementPtr0, ElementPtr1) && !(ElementPtr1->state_flags & PLAYER_SHIP) 
		&& ElementPtr1->playerNr > -1)
	{
		GetElementStarShip (ElementPtr1, &EnemyStarShipPtr);
		if (EnemyStarShipPtr->SpeciesID == BAUL_ID)
			enemyShipIsBaul = 1;
		else if (EnemyStarShipPtr->SpeciesID == CHMMR_ID) 
			enemyShipIsChmmr = 1; // This is important because the gas can stick to zapsats.
	}
	
	// If colliding with Baul's spray weapon or shockwave, EXPLODE!!!
	if (ElementPtr1->current.image.farray == StarShipPtr->RaceDescPtr->ship_data.weapon
		|| (enemyShipIsBaul && ElementPtr1->current.image.farray == EnemyStarShipPtr->RaceDescPtr->ship_data.weapon))
	{
		// Move to shockwave graphics.
		ElementPtr0->current.image.frame = SetAbsFrameIndex (ElementPtr0->current.image.frame, LAST_GAS_INDEX);
		ElementPtr0->next.image.frame = SetAbsFrameIndex (ElementPtr0->current.image.frame, LAST_GAS_INDEX);
		
		// Remove the lock on enemy ship and make the gas die on next turn.
		ElementPtr0->hTarget = 0;
		ElementPtr0->life_span = 1;
		
		// Don't do the gas dissolve anim now that the shockwave appears.
		ElementPtr0->death_func = NULL;
		
		// Generate the actual shockwave.
		generate_shockwave (ElementPtr0, -1); // XXX ElementPtr1->playerNr);
	}
	// If colliding with enemy ship, stick to the ship.
	// Also stick to Chmmr's zapsats.
	else if (ElementPtr0->state_flags & IGNORE_VELOCITY
			 && ElementPtr1->playerNr != ElementPtr0->playerNr
			 && (ElementPtr1->state_flags & PLAYER_SHIP 
				 || (enemyShipIsChmmr && ElementPtr1->mass_points == 10) ))
	{
		HELEMENT hGasElement;
		HELEMENT hTargetElement;
		ELEMENT *GasPtr;
		
		// Create a new gas element which is sticking to the enemy ship.
		if ((hGasElement = AllocElement ()))
		{
			LockElement (hGasElement, &GasPtr);
			
			if (GasPtr->state_flags == 0) /* not allocated before */
			{
				InsertElement (hGasElement, GetHeadElement ());
				
				GasPtr->current = ElementPtr0->next;
				GasPtr->next = GasPtr->current;
				GasPtr->playerNr = ElementPtr0->playerNr;
				GasPtr->state_flags = FINITE_LIFE | GASSY_SUBSTANCE | CHANGING;
				GasPtr->preprocess_func = gas_preprocess;
				GasPtr->collision_func = gas_collision;
				SetPrimType (&(GLOBAL (DisplayArray))[GasPtr->PrimIndex], NO_PRIM);
				
				SetElementStarShip (GasPtr, StarShipPtr);
				GetElementStarShip (ElementPtr1, &StarShipPtr);
				
				// Ships and Chmmr Zapsats require different ways of making them the target of the gas cloud.
				if (ElementPtr1->state_flags & PLAYER_SHIP)
					GasPtr->hTarget = StarShipPtr->hShip;
				else
				{
					GasPtr->life_span = 0;
					LockElement (ElementPtr1, &hTargetElement);
					GasPtr->hTarget = hTargetElement;
				}
			}
			GasPtr->hit_points = ElementPtr0->hit_points;
			GasPtr->life_span = ElementPtr0->life_span;
			GasPtr->thrust_wait = 1;
			GasPtr->weapon_element_index = ElementPtr0->weapon_element_index;
			GasPtr->turn_wait = (BYTE)(1 << ((BYTE)TFB_Random () & 1)); /* LEFT or RIGHT */
			GasPtr->death_func = gas_death;
			
			UnlockElement (hGasElement);
		}
		
		// Erase the original gas element.
		ElementPtr0->hit_points = 0;
		ElementPtr0->life_span = 0;
		ElementPtr0->state_flags |= DISAPPEARING | COLLISION | NONSOLID;
	}
	(void) pPt0;  /* Satisfying compiler (unused parameter) */
	(void) pPt1;  /* Satisfying compiler (unused parameter) */
}
Esempio n. 6
0
static void
chenjesu_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern,
		COUNT ConcernCounter)
{
	EVALUATE_DESC *lpEvalDesc;
	STARSHIP *StarShipPtr;

	GetElementStarShip (ShipPtr, &StarShipPtr);
	StarShipPtr->ship_input_state &= ~SPECIAL;

	lpEvalDesc = &ObjectsOfConcern[ENEMY_SHIP_INDEX];
	if (lpEvalDesc->ObjectPtr)
	{
		STARSHIP *EnemyStarShipPtr;

		GetElementStarShip (lpEvalDesc->ObjectPtr, &EnemyStarShipPtr);
		if ((lpEvalDesc->which_turn <= 16
				&& MANEUVERABILITY (
				&EnemyStarShipPtr->RaceDescPtr->cyborg_control
				) >= MEDIUM_SHIP)
				|| (MANEUVERABILITY (
				&EnemyStarShipPtr->RaceDescPtr->cyborg_control
				) <= SLOW_SHIP
				&& WEAPON_RANGE (
				&EnemyStarShipPtr->RaceDescPtr->cyborg_control
				) >= LONG_RANGE_WEAPON * 3 / 4
				&& (EnemyStarShipPtr->RaceDescPtr->ship_info.ship_flags & SEEKING_WEAPON)))
			lpEvalDesc->MoveState = PURSUE;
	}

	if (StarShipPtr->special_counter == 1
			&& ObjectsOfConcern[ENEMY_WEAPON_INDEX].ObjectPtr
			&& ObjectsOfConcern[ENEMY_WEAPON_INDEX].MoveState == ENTICE
			&& ObjectsOfConcern[ENEMY_WEAPON_INDEX].which_turn <= 8)
	{
		lpEvalDesc = &ObjectsOfConcern[ENEMY_WEAPON_INDEX];
	}

	ship_intelligence (ShipPtr, ObjectsOfConcern, ConcernCounter);

	if (lpEvalDesc->ObjectPtr)
	{
		HELEMENT h, hNext;
		ELEMENT *CrystalPtr;

		h = (StarShipPtr->old_status_flags & WEAPON) ?
				GetTailElement () : (HELEMENT)0;
		for (; h; h = hNext)
		{
			LockElement (h, &CrystalPtr);
			hNext = GetPredElement (CrystalPtr);
			if (!(CrystalPtr->state_flags & NONSOLID)
					&& CrystalPtr->next.image.farray == StarShipPtr->RaceDescPtr->ship_data.weapon
					&& CrystalPtr->preprocess_func
					&& CrystalPtr->life_span > 0
					&& elementsOfSamePlayer (CrystalPtr, ShipPtr))
			{
				if (ObjectsOfConcern[ENEMY_SHIP_INDEX].ObjectPtr)
				{
					COUNT which_turn;

					if ((which_turn = PlotIntercept (CrystalPtr,
							ObjectsOfConcern[ENEMY_SHIP_INDEX].ObjectPtr,
							CrystalPtr->life_span,
							FRAGMENT_RANGE / 2)) == 0
							|| (which_turn == 1
							&& PlotIntercept (CrystalPtr,
							ObjectsOfConcern[ENEMY_SHIP_INDEX].ObjectPtr,
							CrystalPtr->life_span, 0) == 0))
						StarShipPtr->ship_input_state &= ~WEAPON;
					else if (StarShipPtr->weapon_counter == 0)
					{
						StarShipPtr->ship_input_state |= WEAPON;
						lpEvalDesc = &ObjectsOfConcern[ENEMY_SHIP_INDEX];
					}

					UnlockElement (h);
					break;
				}
				hNext = 0;
			}
			UnlockElement (h);
		}

		if (h == 0)
		{
			if (StarShipPtr->old_status_flags & WEAPON)
			{
				StarShipPtr->ship_input_state &= ~WEAPON;
				if (lpEvalDesc == &ObjectsOfConcern[ENEMY_WEAPON_INDEX])
					StarShipPtr->weapon_counter = 3;
			}
			else if (StarShipPtr->weapon_counter == 0
					&& ship_weapons (ShipPtr, lpEvalDesc->ObjectPtr, FRAGMENT_RANGE / 2))
				StarShipPtr->ship_input_state |= WEAPON;
		}
	}

	if (StarShipPtr->special_counter < MAX_DOGGIES)
	{
		if (lpEvalDesc->ObjectPtr
				&& StarShipPtr->RaceDescPtr->ship_info.energy_level <= SPECIAL_ENERGY_COST
				&& !(StarShipPtr->ship_input_state & WEAPON))
			StarShipPtr->ship_input_state |= SPECIAL;
	}
}