static void druuge_postprocess (ELEMENT *ElementPtr) { STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); /* if just fired cannon */ if ((StarShipPtr->cur_status_flags & WEAPON) && StarShipPtr->weapon_counter == StarShipPtr->RaceDescPtr->characteristics.weapon_wait) { COUNT angle; SIZE cur_delta_x, cur_delta_y; StarShipPtr->cur_status_flags &= ~SHIP_AT_MAX_SPEED; angle = FACING_TO_ANGLE (StarShipPtr->ShipFacing) + HALF_CIRCLE; DeltaVelocityComponents (&ElementPtr->velocity, COSINE (angle, RECOIL_VELOCITY), SINE (angle, RECOIL_VELOCITY)); GetCurrentVelocityComponents (&ElementPtr->velocity, &cur_delta_x, &cur_delta_y); if ((long)cur_delta_x * (long)cur_delta_x + (long)cur_delta_y * (long)cur_delta_y > (long)MAX_RECOIL_VELOCITY * (long)MAX_RECOIL_VELOCITY) { angle = ARCTAN (cur_delta_x, cur_delta_y); SetVelocityComponents (&ElementPtr->velocity, COSINE (angle, MAX_RECOIL_VELOCITY), SINE (angle, MAX_RECOIL_VELOCITY)); } } }
static COUNT initialize_bug_missile (ELEMENT *ShipPtr, HELEMENT MissileArray[]) { #define PKUNK_OFFSET 15 #define MISSILE_HITS 1 #define MISSILE_DAMAGE 1 #define MISSILE_OFFSET 1 COUNT i; STARSHIP *StarShipPtr; MISSILE_BLOCK MissileBlock; GetElementStarShip (ShipPtr, &StarShipPtr); MissileBlock.cx = ShipPtr->next.location.x; MissileBlock.cy = ShipPtr->next.location.y; MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.weapon; MissileBlock.index = 0; MissileBlock.sender = ShipPtr->playerNr; MissileBlock.flags = IGNORE_SIMILAR; MissileBlock.pixoffs = PKUNK_OFFSET; MissileBlock.speed = MISSILE_SPEED; MissileBlock.hit_points = MISSILE_HITS; MissileBlock.damage = MISSILE_DAMAGE; MissileBlock.life = MISSILE_LIFE; MissileBlock.preprocess_func = NULL; MissileBlock.blast_offs = MISSILE_OFFSET; for (i = 0; i < 3; ++i) { MissileBlock.face = StarShipPtr->ShipFacing + (ANGLE_TO_FACING (QUADRANT) * i); if (i == 2) MissileBlock.face += ANGLE_TO_FACING (QUADRANT); MissileBlock.face = NORMALIZE_FACING (MissileBlock.face); if ((MissileArray[i] = initialize_missile (&MissileBlock))) { SIZE dx, dy; ELEMENT *MissilePtr; LockElement (MissileArray[i], &MissilePtr); GetCurrentVelocityComponents (&ShipPtr->velocity, &dx, &dy); DeltaVelocityComponents (&MissilePtr->velocity, dx, dy); MissilePtr->current.location.x -= VELOCITY_TO_WORLD (dx); MissilePtr->current.location.y -= VELOCITY_TO_WORLD (dy); MissilePtr->preprocess_func = animate; UnlockElement (MissileArray[i]); } } return (3); }
static COUNT initialize_flame (PELEMENT ShipPtr, HELEMENT FlameArray[]) { #define ILWRATH_OFFSET 29 #define MISSILE_SPEED MAX_THRUST #define MISSILE_HITS 1 #define MISSILE_DAMAGE 1 #define MISSILE_OFFSET 0 STARSHIPPTR StarShipPtr; MISSILE_BLOCK MissileBlock; GetElementStarShip (ShipPtr, &StarShipPtr); MissileBlock.cx = ShipPtr->next.location.x; MissileBlock.cy = ShipPtr->next.location.y; MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.weapon; MissileBlock.face = StarShipPtr->ShipFacing; MissileBlock.index = 0; MissileBlock.sender = (ShipPtr->state_flags & (GOOD_GUY | BAD_GUY)) | IGNORE_SIMILAR; MissileBlock.pixoffs = ILWRATH_OFFSET; MissileBlock.speed = MISSILE_SPEED; MissileBlock.hit_points = MISSILE_HITS; MissileBlock.damage = MISSILE_DAMAGE; MissileBlock.life = MISSILE_LIFE; MissileBlock.preprocess_func = flame_preprocess; MissileBlock.blast_offs = MISSILE_OFFSET; FlameArray[0] = initialize_missile (&MissileBlock); if (FlameArray[0]) { SIZE dx, dy; ELEMENTPTR FlamePtr; LockElement (FlameArray[0], &FlamePtr); GetCurrentVelocityComponents (&ShipPtr->velocity, &dx, &dy); DeltaVelocityComponents (&FlamePtr->velocity, dx, dy); FlamePtr->current.location.x -= VELOCITY_TO_WORLD (dx); FlamePtr->current.location.y -= VELOCITY_TO_WORLD (dy); FlamePtr->collision_func = flame_collision; FlamePtr->turn_wait = 0; UnlockElement (FlameArray[0]); } return (1); }
static COUNT initialize_cannon (ELEMENT *ShipPtr, HELEMENT CannonArray[]) { STARSHIP *StarShipPtr; MISSILE_BLOCK MissileBlock; GetElementStarShip (ShipPtr, &StarShipPtr); MissileBlock.cx = ShipPtr->next.location.x; MissileBlock.cy = ShipPtr->next.location.y; MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.weapon; MissileBlock.face = StarShipPtr->ShipFacing; MissileBlock.index = MissileBlock.face; MissileBlock.sender = ShipPtr->playerNr; MissileBlock.flags = IGNORE_SIMILAR; MissileBlock.pixoffs = DRUUGE_OFFSET; MissileBlock.speed = (MISSILE_SPEED << RESOLUTION_FACTOR); MissileBlock.hit_points = MISSILE_HITS; MissileBlock.damage = MISSILE_DAMAGE; MissileBlock.life = MISSILE_LIFE; MissileBlock.preprocess_func = NULL; MissileBlock.blast_offs = MISSILE_OFFSET; CannonArray[0] = initialize_missile (&MissileBlock); if (CannonArray[0]) { SIZE dx, dy; ELEMENT *CannonPtr; LockElement (CannonArray[0], &CannonPtr); CannonPtr->collision_func = cannon_collision; GetCurrentVelocityComponents (&ShipPtr->velocity, &dx, &dy); dx = dx * 1/2; dy = dy * 1/2; // Add some of the Mauler's velocity to its projectiles. DeltaVelocityComponents (&CannonPtr->velocity, dx, dy); CannonPtr->current.location.x -= VELOCITY_TO_WORLD (dx); CannonPtr->current.location.y -= VELOCITY_TO_WORLD (dy); UnlockElement (CannonArray[0]); } return (1); }
static COUNT initialize_test_pump_up (ELEMENT *ShipPtr, HELEMENT PumpUpArray[]) { STARSHIP *StarShipPtr; MISSILE_BLOCK MissileBlock; //ELEMENT *PumpUpPtr; GetElementStarShip (ShipPtr, &StarShipPtr); MissileBlock.cx = ShipPtr->next.location.x; MissileBlock.cy = ShipPtr->next.location.y; MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.weapon; MissileBlock.face = StarShipPtr->ShipFacing; MissileBlock.index = 0; MissileBlock.sender = ShipPtr->playerNr; MissileBlock.flags = IGNORE_SIMILAR; MissileBlock.pixoffs = MELNORME_OFFSET; MissileBlock.speed = PUMPUP_SPEED; MissileBlock.hit_points = PUMPUP_DAMAGE; MissileBlock.damage = PUMPUP_DAMAGE; MissileBlock.life = PUMPUP_LIFE; MissileBlock.preprocess_func = 0; MissileBlock.blast_offs = 0; PumpUpArray[0] = initialize_missile (&MissileBlock); if (PumpUpArray[0]) { SIZE dx, dy; ELEMENT *MissilePtr; LockElement (PumpUpArray[0], &MissilePtr); GetCurrentVelocityComponents (&ShipPtr->velocity, &dx, &dy); dx = dx * 1/2; dy = dy * 1/2; // Add some of the Trader's velocity to its projectiles. DeltaVelocityComponents (&MissilePtr->velocity, dx, dy); MissilePtr->current.location.x -= VELOCITY_TO_WORLD (dx); MissilePtr->current.location.y -= VELOCITY_TO_WORLD (dy); UnlockElement (PumpUpArray[0]); } return (1); }
static COUNT initialize_confusion (ELEMENT *ShipPtr, HELEMENT ConfusionArray[]) { STARSHIP *StarShipPtr; MISSILE_BLOCK ConfusionBlock; GetElementStarShip (ShipPtr, &StarShipPtr); ConfusionBlock.cx = ShipPtr->next.location.x; ConfusionBlock.cy = ShipPtr->next.location.y; ConfusionBlock.farray = StarShipPtr->RaceDescPtr->ship_data.special; ConfusionBlock.index = 0; ConfusionBlock.face = StarShipPtr->ShipFacing; ConfusionBlock.sender = ShipPtr->playerNr; ConfusionBlock.flags = IGNORE_SIMILAR; ConfusionBlock.pixoffs = MELNORME_OFFSET; ConfusionBlock.speed = CMISSILE_SPEED; ConfusionBlock.hit_points = CMISSILE_HITS; ConfusionBlock.damage = CMISSILE_DAMAGE; ConfusionBlock.life = CMISSILE_LIFE; ConfusionBlock.preprocess_func = confuse_preprocess; ConfusionBlock.blast_offs = CMISSILE_OFFSET; ConfusionArray[0] = initialize_missile (&ConfusionBlock); if (ConfusionArray[0]) { ELEMENT *CMissilePtr; SIZE dx,dy; LockElement (ConfusionArray[0], &CMissilePtr); CMissilePtr->collision_func = confusion_collision; SetElementStarShip (CMissilePtr, StarShipPtr); GetCurrentVelocityComponents (&ShipPtr->velocity, &dx, &dy); dx = dx * 3/4; dy = dy * 3/4; // Add some of the Trader's velocity to its projectiles. DeltaVelocityComponents (&CMissilePtr->velocity, dx, dy); CMissilePtr->current.location.x -= VELOCITY_TO_WORLD (dx); CMissilePtr->current.location.y -= VELOCITY_TO_WORLD (dy); UnlockElement (ConfusionArray[0]); } return (1); }
static void flak_preprocess (ELEMENT *ElementPtr) { if (ElementPtr->turn_wait > 0) --ElementPtr->turn_wait; else { SIZE angle, delta_speed; angle = GetVelocityTravelAngle (&ElementPtr->velocity); delta_speed = WORLD_TO_VELOCITY (MISSILE_DECELERATION); DeltaVelocityComponents (&ElementPtr->velocity, (SIZE)COSINE (angle, -delta_speed), (SIZE)SINE (angle, -delta_speed)); ElementPtr->turn_wait = MISSILE_DECEL_WAIT; ElementPtr->state_flags |= CHANGING; } }
static void cannon_collision (ELEMENT *ElementPtr0, POINT *pPt0, ELEMENT *ElementPtr1, POINT *pPt1) { weapon_collision (ElementPtr0, pPt0, ElementPtr1, pPt1); if ((ElementPtr1->state_flags & PLAYER_SHIP) && ElementPtr1->crew_level && !GRAVITY_MASS (ElementPtr1->mass_points + 1)) { COUNT angle; SIZE cur_delta_x, cur_delta_y; STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr1, &StarShipPtr); StarShipPtr->cur_status_flags &= ~(SHIP_AT_MAX_SPEED | SHIP_BEYOND_MAX_SPEED); angle = FACING_TO_ANGLE ( GetFrameIndex (ElementPtr0->next.image.frame) ); DeltaVelocityComponents (&ElementPtr1->velocity, COSINE (angle, RECOIL_VELOCITY), SINE (angle, RECOIL_VELOCITY)); GetCurrentVelocityComponents (&ElementPtr1->velocity, &cur_delta_x, &cur_delta_y); if ((long)cur_delta_x * (long)cur_delta_x + (long)cur_delta_y * (long)cur_delta_y > (long)MAX_RECOIL_VELOCITY * (long)MAX_RECOIL_VELOCITY) { angle = ARCTAN (cur_delta_x, cur_delta_y); SetVelocityComponents (&ElementPtr1->velocity, COSINE (angle, MAX_RECOIL_VELOCITY), SINE (angle, MAX_RECOIL_VELOCITY)); } } }
static void pump_up_postprocess (ELEMENT *ElementPtr) { if (ElementPtr->state_flags & APPEARING) { ZeroVelocityComponents (&ElementPtr->velocity); } else { HELEMENT hPumpUp; ELEMENT *EPtr; ELEMENT *ShipPtr; STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); LockElement (StarShipPtr->hShip, &ShipPtr); initialize_pump_up (ShipPtr, &hPumpUp); DeltaEnergy (ShipPtr, 0); UnlockElement (StarShipPtr->hShip); LockElement (hPumpUp, &EPtr); EPtr->current.image.frame = ElementPtr->current.image.frame; EPtr->turn_wait = ElementPtr->turn_wait; EPtr->thrust_wait = ElementPtr->thrust_wait; if (--EPtr->thrust_wait == 0) { if ((EPtr->turn_wait & ~REVERSE_DIR) < MAX_PUMP - 1) { ++EPtr->turn_wait; EPtr->current.image.frame = SetRelFrameIndex ( EPtr->current.image.frame, NUM_PUMP_ANIMS); ProcessSound (SetAbsSoundIndex ( StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2), EPtr); } EPtr->thrust_wait = LEVEL_COUNTER; } EPtr->mass_points = EPtr->hit_points = (PUMPUP_DAMAGE << (ElementPtr->turn_wait & ~REVERSE_DIR)); SetElementStarShip (EPtr, StarShipPtr); if (EPtr->thrust_wait & 1) { COUNT frame_index; frame_index = GetFrameIndex (EPtr->current.image.frame); if (((EPtr->turn_wait & REVERSE_DIR) && (frame_index % NUM_PUMP_ANIMS) != 0) || (!(EPtr->turn_wait & REVERSE_DIR) && ((frame_index + 1) % NUM_PUMP_ANIMS) == 0)) { --frame_index; EPtr->turn_wait |= REVERSE_DIR; } else { ++frame_index; EPtr->turn_wait &= ~REVERSE_DIR; } EPtr->current.image.frame = SetAbsFrameIndex ( EPtr->current.image.frame, frame_index); } if (StarShipPtr->cur_status_flags & StarShipPtr->old_status_flags & WEAPON) { StarShipPtr->weapon_counter = WEAPON_WAIT; } else { SIZE dx, dy; COUNT angle; EPtr->life_span = PUMPUP_LIFE; EPtr->preprocess_func = pump_up_preprocess; EPtr->postprocess_func = 0; angle = FACING_TO_ANGLE (StarShipPtr->ShipFacing); SetVelocityComponents (&EPtr->velocity, COSINE (angle, WORLD_TO_VELOCITY (PUMPUP_SPEED)), SINE (angle, WORLD_TO_VELOCITY (PUMPUP_SPEED))); GetCurrentVelocityComponents (&ShipPtr->velocity, &dx, &dy); dx = dx * 1/2; dy = dy * 1/2; // Add some of the Trader's velocity to its projectiles. DeltaVelocityComponents (&EPtr->velocity, dx, dy); EPtr->current.location.x -= VELOCITY_TO_WORLD (dx); EPtr->current.location.y -= VELOCITY_TO_WORLD (dy); ProcessSound (SetAbsSoundIndex ( StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 3), EPtr); } UnlockElement (hPumpUp); PutElement (hPumpUp); SetPrimType (&(GLOBAL (DisplayArray))[ElementPtr->PrimIndex], NO_PRIM); ElementPtr->state_flags |= NONSOLID; } }
static void initialize_diagonal_flame (ELEMENT *ElementPtr) { COUNT i; STARSHIP *StarShipPtr; MISSILE_BLOCK MissileBlock; GetElementStarShip (ElementPtr, &StarShipPtr); MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.weapon; MissileBlock.index = 0; MissileBlock.sender = ElementPtr->playerNr; MissileBlock.flags = IGNORE_SIMILAR; MissileBlock.pixoffs = ILWRATH_OFFSET; MissileBlock.speed = MISSILE_SPEED; MissileBlock.hit_points = MISSILE_HITS; MissileBlock.damage = MISSILE_DAMAGE; MissileBlock.life = MISSILE_LIFE; MissileBlock.preprocess_func = flame_preprocess; MissileBlock.blast_offs = MISSILE_OFFSET; for(i = 0; i < 2; ++i) { HELEMENT hFlame; if (i == 0) { MissileBlock.cx = ElementPtr->next.location.x + COSINE(FACING_TO_ANGLE(StarShipPtr->ShipFacing + 4), -32); MissileBlock.cy = ElementPtr->next.location.y + SINE(FACING_TO_ANGLE(StarShipPtr->ShipFacing + 4), -32); MissileBlock.face = NORMALIZE_FACING (StarShipPtr->ShipFacing + 2); } else { MissileBlock.cx = ElementPtr->next.location.x + COSINE(FACING_TO_ANGLE(StarShipPtr->ShipFacing + 4), 32); MissileBlock.cy = ElementPtr->next.location.y + SINE(FACING_TO_ANGLE(StarShipPtr->ShipFacing + 4), 32); MissileBlock.face = NORMALIZE_FACING (StarShipPtr->ShipFacing - 2); } hFlame = initialize_missile (&MissileBlock); if (hFlame) { SIZE dx, dy; ELEMENT *FlamePtr; LockElement (hFlame, &FlamePtr); SetElementStarShip (FlamePtr, StarShipPtr); FlamePtr->hTarget = 0; GetCurrentVelocityComponents (&ElementPtr->velocity, &dx, &dy); DeltaVelocityComponents (&FlamePtr->velocity, dx, dy); FlamePtr->current.location.x -= VELOCITY_TO_WORLD (dx); FlamePtr->current.location.y -= VELOCITY_TO_WORLD (dy); FlamePtr->collision_func = flame_collision; FlamePtr->turn_wait = 0; UnlockElement (hFlame); PutElement (hFlame); } } }
static COUNT initialize_weapon (ELEMENT *ShipPtr, HELEMENT WeaponArray[]) { COUNT i; STARSHIP *StarShipPtr; MISSILE_BLOCK MissileBlock; GetElementStarShip (ShipPtr, &StarShipPtr); MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.weapon; // MissileBlock.face = StarShipPtr->ShipFacing; MissileBlock.face = MissileBlock.index = StarShipPtr->ShipFacing; MissileBlock.sender = ShipPtr->playerNr; MissileBlock.flags = IGNORE_SIMILAR; MissileBlock.speed = (MISSILE_SPEED << RESOLUTION_FACTOR); MissileBlock.hit_points = MISSILE_HITS; MissileBlock.damage = MISSILE_DAMAGE; MissileBlock.life = MISSILE_LIFE; MissileBlock.blast_offs = MISSILE_OFFSET; MissileBlock.preprocess_func = 0; for (i = 0; i < 2; ++i) { if (i == 0) { MissileBlock.pixoffs = THRADDASH_OFFSET_2; MissileBlock.cx = ShipPtr->next.location.x; MissileBlock.cy = ShipPtr->next.location.y; } else if (StarShipPtr->static_counter == 0) { MissileBlock.pixoffs = THRADDASH_OFFSET_1; MissileBlock.cx = ShipPtr->next.location.x + COSINE(FACING_TO_ANGLE (MissileBlock.face + 4), -25); MissileBlock.cy = ShipPtr->next.location.y + SINE(FACING_TO_ANGLE (MissileBlock.face + 4), -25); } else { MissileBlock.pixoffs = THRADDASH_OFFSET_1; MissileBlock.cx = ShipPtr->next.location.x + COSINE(FACING_TO_ANGLE (MissileBlock.face + 4), 25); MissileBlock.cy = ShipPtr->next.location.y + SINE(FACING_TO_ANGLE (MissileBlock.face + 4), 25); } if ((WeaponArray[i] = initialize_missile (&MissileBlock))) { SIZE dx, dy; ELEMENT *WeaponPtr; LockElement (WeaponArray[i], &WeaponPtr); GetCurrentVelocityComponents (&ShipPtr->velocity, &dx, &dy); DeltaVelocityComponents (&WeaponPtr->velocity, dx, dy); WeaponPtr->current.location.x -= VELOCITY_TO_WORLD (dx); WeaponPtr->current.location.y -= VELOCITY_TO_WORLD (dy); // WeaponPtr->collision_func = repulsor_collision; UnlockElement (WeaponArray[i]); } } return (2); }
// Primary weapon. It must deal at least 1 damage, otherwise it won't interact with other // elements, not even gas. However, we can prevent this damage with a separate collision function. static COUNT initialize_spray (ELEMENT *ShipPtr, HELEMENT SprayArray[]) { STARSHIP *StarShipPtr; MISSILE_BLOCK MissileBlock; SIZE offs_x, offs_y; COUNT i, angle; static COUNT spray_side[NUM_SIDES]={0,0}; GetElementStarShip (ShipPtr, &StarShipPtr); angle = FACING_TO_ANGLE (StarShipPtr->ShipFacing); for (i = 0; i < NUM_SPRAYS; i++) { BYTE damage; // Only the foremost one deals damage if (i == NUM_SPRAYS-1) damage = 1; else damage = 0; // This mechanism can be used to alter the "pipe" from which the spray particles come. spray_side[ShipPtr->playerNr] = (spray_side[ShipPtr->playerNr] + 1) % 2; if(spray_side[ShipPtr->playerNr]) { offs_x = -SINE (angle, SPRAY_HORZ_OFFSET + (i << RESOLUTION_FACTOR)); offs_y = COSINE (angle, SPRAY_HORZ_OFFSET + (i << RESOLUTION_FACTOR)); } else { offs_x = -SINE (angle, SPRAY_HORZ_OFFSET + (i << RESOLUTION_FACTOR)); offs_y = COSINE (angle, SPRAY_HORZ_OFFSET + (i << RESOLUTION_FACTOR)); } MissileBlock.cx = ShipPtr->next.location.x + offs_x; MissileBlock.cy = ShipPtr->next.location.y + offs_y; MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.weapon; MissileBlock.face = StarShipPtr->ShipFacing; MissileBlock.index = 0; MissileBlock.sender = ShipPtr->playerNr; MissileBlock.flags = IGNORE_SIMILAR | GASSY_SUBSTANCE; MissileBlock.pixoffs = 4 + ((i * SPRAY_DIST) << RESOLUTION_FACTOR); MissileBlock.speed = MISSILE_SPEED << RESOLUTION_FACTOR; // JMS_GFX MissileBlock.hit_points = MISSILE_HITS; MissileBlock.damage = damage; MissileBlock.life = MISSILE_LIFE; MissileBlock.preprocess_func = spray_preprocess; MissileBlock.blast_offs = MISSILE_OFFSET; SprayArray[i] = initialize_missile (&MissileBlock); if (SprayArray[i]) { ELEMENT *SprayPtr; LockElement (SprayArray[i], &SprayPtr); SprayPtr->collision_func = spray_collision; SprayPtr->thrust_wait = 1; // This makes the spray shoot in a slight angle towards the centerline. // If you want a "curved" shot, put this mechanism into spray_preprocess // where it accelerates the whot towards the centerline on every frame. offs_x = -SINE (angle, (100 << RESOLUTION_FACTOR)); offs_y = COSINE (angle, (100 << RESOLUTION_FACTOR)); DeltaVelocityComponents (&SprayPtr->velocity, offs_x, offs_y); UnlockElement (SprayArray[i]); } } return (NUM_SPRAYS); }
// Secondary weapon: Gas cloud. // The IGNORE_VELOCITY flag is very important: It doesn't only stop the gas from reacting to gravity, // (see collide.h) but it also makes it possible for the gas to stick to enemy ship (see this file's other gas functions). static void spawn_gas (ELEMENT *ShipPtr) { STARSHIP *StarShipPtr; MISSILE_BLOCK MissileBlock; HELEMENT Missile; SIZE offs_x, offs_y; COUNT angle; static COUNT gas_side[NUM_SIDES] = {0, 0}; static COUNT gas_number[NUM_SIDES] = {0, 0}; GetElementStarShip (ShipPtr, &StarShipPtr); gas_number[ShipPtr->playerNr] = (gas_number[ShipPtr->playerNr] + 1) % 32; gas_side[ShipPtr->playerNr] = (gas_side[ShipPtr->playerNr] + 1) % 2; angle = FACING_TO_ANGLE (StarShipPtr->ShipFacing); // This mechanism can be used to alter the "pipe" from which the gas clouds come. if(gas_side[ShipPtr->playerNr]) { offs_x = -SINE (angle, GAS_HORZ_OFFSET); offs_y = COSINE (angle, GAS_HORZ_OFFSET); } else { offs_x = -SINE (angle, GAS_HORZ_OFFSET); offs_y = COSINE (angle, GAS_HORZ_OFFSET); } MissileBlock.cx = ShipPtr->next.location.x + offs_x; MissileBlock.cy = ShipPtr->next.location.y + offs_y; MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.special; MissileBlock.face = StarShipPtr->ShipFacing;// Baul's gas now flies forward. (this was: (StarShipPtr->ShipFacing - 8) % 16;) MissileBlock.index = LAST_DISSOLVE_INDEX; // Start with the gas emerge animation which is the last .pngs in gasXX.ani MissileBlock.sender = ShipPtr->playerNr; MissileBlock.flags = GASSY_SUBSTANCE | IGNORE_VELOCITY; // Don't erase the IGNORE_VELOCITY. It's very important. MissileBlock.pixoffs = GAS_OFFSET; MissileBlock.speed = GAS_INIT_SPEED; MissileBlock.hit_points = GAS_HITS; MissileBlock.damage = GAS_DAMAGE; MissileBlock.life = GAS_LIFE; MissileBlock.preprocess_func = gas_preprocess; MissileBlock.blast_offs = 0; Missile = initialize_missile (&MissileBlock); if (Missile) { ELEMENT *GasPtr; SIZE dx, dy; // Baul's gas now flies forward. LockElement (Missile, &GasPtr); // Baul's gas now flies forward. GetCurrentVelocityComponents (&ShipPtr->velocity, &dx, &dy); DeltaVelocityComponents (&GasPtr->velocity, dx, dy); GasPtr->current.location.x -= VELOCITY_TO_WORLD (dx); GasPtr->current.location.y -= VELOCITY_TO_WORLD (dy); GasPtr->collision_func = gas_collision; GasPtr->death_func = gas_death; GasPtr->thrust_wait = 1; GasPtr->weapon_element_index = gas_number[ShipPtr->playerNr]; SetElementStarShip (GasPtr, StarShipPtr); ProcessSound (SetAbsSoundIndex (StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), GasPtr); UnlockElement (Missile); PutElement (Missile); } }
static COUNT initialize_flak (ELEMENT *ShipPtr, HELEMENT MissileArray[]) { COUNT i; STARSHIP *StarShipPtr; MISSILE_BLOCK MissileBlock; GetElementStarShip (ShipPtr, &StarShipPtr); MissileBlock.cx = ShipPtr->next.location.x; MissileBlock.cy = ShipPtr->next.location.y; MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.weapon; MissileBlock.face = MissileBlock.index = StarShipPtr->ShipFacing; MissileBlock.sender = ShipPtr->playerNr; MissileBlock.flags = IGNORE_SIMILAR; MissileBlock.pixoffs = SPATHI_FORWARD_OFFSET; MissileBlock.speed = (MISSILE_SPEED << RESOLUTION_FACTOR); MissileBlock.hit_points = MISSILE_HITS; MissileBlock.damage = MISSILE_DAMAGE; MissileBlock.life = MISSILE_LIFE; MissileBlock.preprocess_func = flak_preprocess; MissileBlock.blast_offs = MISSILE_OFFSET; for(i = 0; i < 3; ++i) { if (i == 0) { MissileBlock.cx = ShipPtr->next.location.x; MissileBlock.cy = ShipPtr->next.location.y; } else if (i == 1) { MissileBlock.cx = ShipPtr->next.location.x + COSINE(FACING_TO_ANGLE(StarShipPtr->ShipFacing + 4), 12); MissileBlock.cy = ShipPtr->next.location.y + SINE(FACING_TO_ANGLE(StarShipPtr->ShipFacing + 4), 12); } else if (i == 2) { MissileBlock.cx = ShipPtr->next.location.x + COSINE(FACING_TO_ANGLE(StarShipPtr->ShipFacing + 4), -12); MissileBlock.cy = ShipPtr->next.location.y + SINE(FACING_TO_ANGLE(StarShipPtr->ShipFacing + 4), -12); } if ((MissileArray[i] = initialize_missile (&MissileBlock))) { SIZE dx, dy, angle, speed; ELEMENT *MissilePtr; LockElement (MissileArray[i], &MissilePtr); if (i > 0) { angle = GetVelocityTravelAngle (&MissilePtr->velocity); GetCurrentVelocityComponents(&MissilePtr->velocity, &dx, &dy); speed = square_root (dx*dx + dy*dy); if (i == 1) angle += 1; else if (i == 2) angle -= 1; SetVelocityComponents(&MissilePtr->velocity, COSINE(angle, speed), SINE(angle, speed)); } GetCurrentVelocityComponents (&ShipPtr->velocity, &dx, &dy); // Add the Eluder's velocity to its projectiles. DeltaVelocityComponents (&MissilePtr->velocity, dx, dy); MissilePtr->current.location.x -= VELOCITY_TO_WORLD (dx); MissilePtr->current.location.y -= VELOCITY_TO_WORLD (dy); MissilePtr->turn_wait = 1; UnlockElement (MissileArray[i]); } } return (3); }
BOOLEAN CalculateGravity (ELEMENT *ElementPtr) { BOOLEAN retval, HasGravity; HELEMENT hTestElement, hSuccElement; retval = FALSE; HasGravity = (BOOLEAN)(CollidingElement (ElementPtr) && GRAVITY_MASS (ElementPtr->mass_points + 1)); for (hTestElement = GetHeadElement (); hTestElement != 0; hTestElement = hSuccElement) { BOOLEAN TestHasGravity; ELEMENT *TestElementPtr; LockElement (hTestElement, &TestElementPtr); if (TestElementPtr != ElementPtr && CollidingElement (TestElementPtr) && (TestHasGravity = GRAVITY_MASS (TestElementPtr->mass_points + 1)) != HasGravity) { COUNT abs_dx, abs_dy; SIZE dx, dy; if (!(ElementPtr->state_flags & PRE_PROCESS)) { dx = ElementPtr->current.location.x - TestElementPtr->current.location.x; dy = ElementPtr->current.location.y - TestElementPtr->current.location.y; } else { dx = ElementPtr->next.location.x - TestElementPtr->next.location.x; dy = ElementPtr->next.location.y - TestElementPtr->next.location.y; } #ifdef DEBUG_GRAVITY if (TestElementPtr->state_flags & PLAYER_SHIP) { log_add (log_Debug, "CalculateGravity:"); log_add (log_Debug, "\tdx = %d, dy = %d", dx, dy); } #endif /* DEBUG_GRAVITY */ dx = WRAP_DELTA_X (dx); dy = WRAP_DELTA_Y (dy); #ifdef DEBUG_GRAVITY if (TestElementPtr->state_flags & PLAYER_SHIP) log_add (log_Debug, "\twrap_dx = %d, wrap_dy = %d", dx, dy); #endif /* DEBUG_GRAVITY */ abs_dx = dx >= 0 ? dx : -dx; abs_dy = dy >= 0 ? dy : -dy; abs_dx = WORLD_TO_DISPLAY (abs_dx); abs_dy = WORLD_TO_DISPLAY (abs_dy); #ifdef DEBUG_GRAVITY if (TestElementPtr->state_flags & PLAYER_SHIP) log_add (log_Debug, "\tdisplay_dx = %d, display_dy = %d", abs_dx, abs_dy); #endif /* DEBUG_GRAVITY */ if (abs_dx <= GRAVITY_THRESHOLD && abs_dy <= GRAVITY_THRESHOLD) { DWORD dist_squared; dist_squared = (DWORD)(abs_dx * abs_dx) + (DWORD)(abs_dy * abs_dy); if (dist_squared <= (DWORD)(GRAVITY_THRESHOLD * GRAVITY_THRESHOLD)) { #ifdef NEVER COUNT magnitude; #define DIFUSE_GRAVITY RES_SCALE(175) // JMS_GFX: Because of the ifdef NEVER this is actually never run. Well, changed it for consistency dist_squared += (DWORD)abs_dx * (DIFUSE_GRAVITY << 1) + (DWORD)abs_dy * (DIFUSE_GRAVITY << 1) + ((DWORD)(DIFUSE_GRAVITY * DIFUSE_GRAVITY) << 1); if ((magnitude = (COUNT)((DWORD)(GRAVITY_THRESHOLD * GRAVITY_THRESHOLD) / dist_squared)) == 0) magnitude = 1; #define MAX_MAGNITUDE RES_SCALE(6) // JMS_GFX: Because of the ifdef NEVER this is actually never run. Well, changed it for consistency else if (magnitude > MAX_MAGNITUDE) magnitude = MAX_MAGNITUDE; log_add (log_Debug, "magnitude = %u", magnitude); #endif /* NEVER */ #ifdef DEBUG_GRAVITY if (TestElementPtr->state_flags & PLAYER_SHIP) log_add (log_Debug, "dist_squared = %lu", dist_squared); #endif /* DEBUG_GRAVITY */ if (TestHasGravity) { retval = TRUE; UnlockElement (hTestElement); break; } else { COUNT angle; angle = ARCTAN (dx, dy); DeltaVelocityComponents (&TestElementPtr->velocity, COSINE (angle, WORLD_TO_VELOCITY (RES_SCALE(1))), SINE (angle, WORLD_TO_VELOCITY (RES_SCALE(1)))); // JMS_GFX if (TestElementPtr->state_flags & PLAYER_SHIP) { STARSHIP *StarShipPtr; GetElementStarShip (TestElementPtr, &StarShipPtr); StarShipPtr->cur_status_flags &= ~SHIP_AT_MAX_SPEED; StarShipPtr->cur_status_flags |= SHIP_IN_GRAVITY_WELL; } } } } } hSuccElement = GetSuccElement (TestElementPtr); UnlockElement (hTestElement); } return (retval); }