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; 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]) { ELEMENT *CannonPtr; LockElement (CannonArray[0], &CannonPtr); CannonPtr->collision_func = cannon_collision; UnlockElement (CannonArray[0]); } return (1); }
// This is used by AI for testing would it hit the enemy ship with gas. static COUNT initialize_test_gas (ELEMENT *ElementPtr, HELEMENT GasArray[]) { STARSHIP *StarShipPtr; MISSILE_BLOCK MissileBlock; GetElementStarShip (ElementPtr, &StarShipPtr); MissileBlock.cx = ElementPtr->next.location.x; MissileBlock.cy = ElementPtr->next.location.y; MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.special; MissileBlock.face = StarShipPtr->ShipFacing; MissileBlock.index = LAST_DISSOLVE_INDEX; MissileBlock.sender = ElementPtr->playerNr; MissileBlock.flags = GASSY_SUBSTANCE | IGNORE_VELOCITY; MissileBlock.pixoffs = GAS_OFFSET; MissileBlock.speed = GAS_INIT_SPEED; MissileBlock.hit_points = GAS_HITS; MissileBlock.damage = GAS_DAMAGE; MissileBlock.life = 20; // Not GAS_LIFE because this test gas doesn't slow down at all -> life has to be short. MissileBlock.preprocess_func = gas_preprocess; MissileBlock.blast_offs = 0; GasArray[0] = initialize_missile (&MissileBlock); return (1); }
static COUNT initialize_standard_missile (ELEMENT *ShipPtr, HELEMENT MissileArray[]) { #define SPATHI_FORWARD_OFFSET 16 #define MISSILE_HITS 1 #define MISSILE_DAMAGE 1 #define MISSILE_OFFSET 1 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; MissileBlock.hit_points = MISSILE_HITS; MissileBlock.damage = MISSILE_DAMAGE; MissileBlock.life = MISSILE_LIFE; MissileBlock.preprocess_func = NULL; MissileBlock.blast_offs = MISSILE_OFFSET; MissileArray[0] = initialize_missile (&MissileBlock); return (1); }
static COUNT initialize_horn (ELEMENT *ShipPtr, HELEMENT HornArray[]) { #define MISSILE_HITS 1 #define MISSILE_DAMAGE 1 #define MISSILE_OFFSET 2 #define SUPOX_OFFSET 23 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->state_flags & (GOOD_GUY | BAD_GUY)) | IGNORE_SIMILAR; MissileBlock.pixoffs = SUPOX_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; HornArray[0] = initialize_missile (&MissileBlock); 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 = RES_SCALE(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); 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; LockElement (ConfusionArray[0], &CMissilePtr); CMissilePtr->collision_func = confusion_collision; SetElementStarShip (CMissilePtr, StarShipPtr); UnlockElement (ConfusionArray[0]); } return (1); }
static COUNT initialize_dagger (ELEMENT *ShipPtr, HELEMENT DaggerArray[]) { #define SYREEN_OFFSET (30 << RESOLUTION_FACTOR) // JMS_GFX #define MISSILE_HITS 1 #define MISSILE_DAMAGE 2 #define MISSILE_OFFSET (3 << RESOLUTION_FACTOR) // JMS_GFX 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 = SYREEN_OFFSET; MissileBlock.speed = MISSILE_SPEED << RESOLUTION_FACTOR; // JMS_GFX MissileBlock.hit_points = MISSILE_HITS; MissileBlock.damage = MISSILE_DAMAGE; MissileBlock.life = MISSILE_LIFE; MissileBlock.preprocess_func = NULL; MissileBlock.blast_offs = MISSILE_OFFSET; DaggerArray[0] = initialize_missile (&MissileBlock); return (1); }
static COUNT initialize_turret_missile (PELEMENT ShipPtr, HELEMENT MissileArray[]) { #define MISSILE_HITS 2 #define MISSILE_DAMAGE 3 #define MISSILE_OFFSET 1 ELEMENTPTR TurretPtr; 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; LockElement (GetSuccElement (ShipPtr), &TurretPtr); if (TurretPtr->turn_wait == 0 && (StarShipPtr->cur_status_flags & SPECIAL) && (StarShipPtr->cur_status_flags & (LEFT | RIGHT))) { if (StarShipPtr->cur_status_flags & RIGHT) ++TurretPtr->thrust_wait; else --TurretPtr->thrust_wait; TurretPtr->turn_wait = TURRET_WAIT + 1; } MissileBlock.face = MissileBlock.index = NORMALIZE_FACING (StarShipPtr->ShipFacing + TurretPtr->thrust_wait); UnlockElement (GetSuccElement (ShipPtr)); MissileBlock.sender = (ShipPtr->state_flags & (GOOD_GUY | BAD_GUY)) | IGNORE_SIMILAR; MissileBlock.pixoffs = TURRET_OFFSET; MissileBlock.speed = MISSILE_SPEED; MissileBlock.hit_points = MISSILE_HITS; MissileBlock.damage = MISSILE_DAMAGE; MissileBlock.life = MISSILE_LIFE; MissileBlock.preprocess_func = NULL_PTR; MissileBlock.blast_offs = MISSILE_OFFSET; MissileArray[0] = initialize_missile (&MissileBlock); if (MissileArray[0]) { ELEMENTPTR HowitzerPtr; LockElement (MissileArray[0], &HowitzerPtr); HowitzerPtr->collision_func = howitzer_collision; UnlockElement (MissileArray[0]); } return (1); }
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 void crystal_postprocess (ELEMENT *ElementPtr) { #define FRAGMENT_HITS 1 #define FRAGMENT_DAMAGE 2 #define FRAGMENT_OFFSET 2 #define NUM_FRAGMENTS 8 STARSHIP *StarShipPtr; MISSILE_BLOCK MissileBlock; GetElementStarShip (ElementPtr, &StarShipPtr); MissileBlock.cx = ElementPtr->next.location.x; MissileBlock.cy = ElementPtr->next.location.y; MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.weapon; MissileBlock.index = 1; MissileBlock.sender = ElementPtr->playerNr; MissileBlock.flags = IGNORE_SIMILAR; MissileBlock.pixoffs = 0; MissileBlock.speed = FRAGMENT_SPEED; MissileBlock.hit_points = FRAGMENT_HITS; MissileBlock.damage = FRAGMENT_DAMAGE; MissileBlock.life = FRAGMENT_LIFE; MissileBlock.preprocess_func = NULL; MissileBlock.blast_offs = FRAGMENT_OFFSET; for (MissileBlock.face = 0; MissileBlock.face < ANGLE_TO_FACING (FULL_CIRCLE); MissileBlock.face += (ANGLE_TO_FACING (FULL_CIRCLE) / NUM_FRAGMENTS)) { HELEMENT hFragment; hFragment = initialize_missile (&MissileBlock); if (hFragment) { ELEMENT *FragPtr; LockElement (hFragment, &FragPtr); SetElementStarShip (FragPtr, StarShipPtr); UnlockElement (hFragment); PutElement (hFragment); } } ProcessSound (SetAbsSoundIndex ( /* CRYSTAL_FRAGMENTS */ StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); }
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_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_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 spawn_butt_missile (ELEMENT *ShipPtr) { #define SPATHI_REAR_OFFSET 20 #define DISCRIMINATOR_LIFE 30 #define DISCRIMINATOR_HITS 1 #define DISCRIMINATOR_DAMAGE 2 #define DISCRIMINATOR_OFFSET 4 HELEMENT ButtMissile; STARSHIP *StarShipPtr; MISSILE_BLOCK ButtMissileBlock; GetElementStarShip (ShipPtr, &StarShipPtr); ButtMissileBlock.cx = ShipPtr->next.location.x; ButtMissileBlock.cy = ShipPtr->next.location.y; ButtMissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.special; ButtMissileBlock.face = ButtMissileBlock.index = NORMALIZE_FACING (StarShipPtr->ShipFacing + ANGLE_TO_FACING (HALF_CIRCLE)); ButtMissileBlock.sender = ShipPtr->playerNr; ButtMissileBlock.flags = 0; ButtMissileBlock.pixoffs = SPATHI_REAR_OFFSET; ButtMissileBlock.speed = DISCRIMINATOR_SPEED; ButtMissileBlock.hit_points = DISCRIMINATOR_HITS; ButtMissileBlock.damage = DISCRIMINATOR_DAMAGE; ButtMissileBlock.life = DISCRIMINATOR_LIFE; ButtMissileBlock.preprocess_func = butt_missile_preprocess; ButtMissileBlock.blast_offs = DISCRIMINATOR_OFFSET; ButtMissile = initialize_missile (&ButtMissileBlock); if (ButtMissile) { ELEMENT *ButtPtr; LockElement (ButtMissile, &ButtPtr); ButtPtr->turn_wait = TRACK_WAIT; SetElementStarShip (ButtPtr, StarShipPtr); ProcessSound (SetAbsSoundIndex ( /* LAUNCH_BUTT_MISSILE */ StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ButtPtr); UnlockElement (ButtMissile); PutElement (ButtMissile); } }
static COUNT initialize_pump_up (ELEMENT *ShipPtr, HELEMENT PumpUpArray[]) { 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 = 0; MissileBlock.sender = ShipPtr->playerNr; MissileBlock.flags = IGNORE_SIMILAR; MissileBlock.pixoffs = MELNORME_OFFSET; MissileBlock.speed = DISPLAY_TO_WORLD (MELNORME_OFFSET); MissileBlock.hit_points = PUMPUP_DAMAGE; MissileBlock.damage = PUMPUP_DAMAGE; MissileBlock.life = 2; MissileBlock.preprocess_func = 0; MissileBlock.blast_offs = 0; PumpUpArray[0] = initialize_missile (&MissileBlock); if (PumpUpArray[0]) { ELEMENT *PumpUpPtr; LockElement (PumpUpArray[0], &PumpUpPtr); PumpUpPtr->postprocess_func = pump_up_postprocess; PumpUpPtr->collision_func = pump_up_collision; if (antiCheat(ShipPtr, FALSE)) { PumpUpPtr->thrust_wait = 5; } else { PumpUpPtr->thrust_wait = LEVEL_COUNTER; } UnlockElement (PumpUpArray[0]); } return (1); }
static COUNT initialize_bubble (ELEMENT *ShipPtr, HELEMENT BubbleArray[]) { #define ANDROSYNTH_OFFSET (14 << RESOLUTION_FACTOR) // JMS_GFX #define MISSILE_OFFSET (3 << RESOLUTION_FACTOR) // JMS_GFX #define MISSILE_HITS 3 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 = 0; MissileBlock.sender = ShipPtr->playerNr; MissileBlock.flags = IGNORE_SIMILAR; MissileBlock.pixoffs = ANDROSYNTH_OFFSET; MissileBlock.speed = MISSILE_SPEED; MissileBlock.hit_points = MISSILE_HITS; MissileBlock.damage = MISSILE_DAMAGE; MissileBlock.life = MISSILE_LIFE; MissileBlock.preprocess_func = bubble_preprocess; MissileBlock.blast_offs = MISSILE_OFFSET; BubbleArray[0] = initialize_missile (&MissileBlock); if (BubbleArray[0]) { ELEMENT *BubblePtr; LockElement (BubbleArray[0], &BubblePtr); BubblePtr->turn_wait = 0; UnlockElement (BubbleArray[0]); } return (1); }
static COUNT initialize_nuke (ELEMENT *ShipPtr, HELEMENT NukeArray[]) { #define HUMAN_OFFSET (42 << RESOLUTION_FACTOR) // JMS_GFX #define MISSILE_DAMAGE 4 #define MISSILE_HITS 1 #define NUKE_OFFSET (8 << RESOLUTION_FACTOR) // JMS_GFX 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 = 0; MissileBlock.pixoffs = HUMAN_OFFSET; MissileBlock.speed = MISSILE_SPEED << RESOLUTION_FACTOR; // JMS_GFX MissileBlock.hit_points = MISSILE_HITS; MissileBlock.damage = MISSILE_DAMAGE; MissileBlock.life = MISSILE_LIFE; MissileBlock.preprocess_func = nuke_preprocess; MissileBlock.blast_offs = NUKE_OFFSET; NukeArray[0] = initialize_missile (&MissileBlock); if (NukeArray[0]) { ELEMENT *NukePtr; LockElement (NukeArray[0], &NukePtr); NukePtr->turn_wait = TRACK_WAIT; UnlockElement (NukeArray[0]); } return (1); }
static COUNT initialize_nuke (PELEMENT ShipPtr, HELEMENT NukeArray[]) { #define HUMAN_OFFSET 42 #define MISSILE_DAMAGE 4 #define MISSILE_HITS 1 #define NUKE_OFFSET 8 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 = MissileBlock.index = StarShipPtr->ShipFacing; MissileBlock.sender = ShipPtr->state_flags & (GOOD_GUY | BAD_GUY); MissileBlock.pixoffs = HUMAN_OFFSET; MissileBlock.speed = MISSILE_SPEED; MissileBlock.hit_points = MISSILE_HITS; MissileBlock.damage = MISSILE_DAMAGE; MissileBlock.life = MISSILE_LIFE; MissileBlock.preprocess_func = nuke_preprocess; MissileBlock.blast_offs = NUKE_OFFSET; NukeArray[0] = initialize_missile (&MissileBlock); if (NukeArray[0]) { ELEMENTPTR NukePtr; LockElement (NukeArray[0], &NukePtr); NukePtr->turn_wait = TRACK_WAIT; UnlockElement (NukeArray[0]); } return (1); }
static COUNT initialize_horn (ELEMENT *ShipPtr, HELEMENT HornArray[]) { 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 = THRADDASH_OFFSET; MissileBlock.speed = RES_SCALE(MISSILE_SPEED); MissileBlock.hit_points = MISSILE_HITS; MissileBlock.damage = MISSILE_DAMAGE; MissileBlock.life = MISSILE_LIFE; MissileBlock.preprocess_func = NULL; MissileBlock.blast_offs = MISSILE_OFFSET; HornArray[0] = initialize_missile (&MissileBlock); return (1); }
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); }
// 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); }
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 void thraddash_preprocess (ELEMENT *ElementPtr) { STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); if (!(StarShipPtr->cur_status_flags & SPECIAL)) { if ((StarShipPtr->old_status_flags & SPECIAL) && (StarShipPtr->cur_status_flags & SHIP_AT_MAX_SPEED)) StarShipPtr->cur_status_flags |= SHIP_BEYOND_MAX_SPEED; } else if (DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST)) { COUNT max_thrust, thrust_increment; STATUS_FLAGS thrust_status; HELEMENT hTrailElement; if (!(StarShipPtr->old_status_flags & SPECIAL)) StarShipPtr->cur_status_flags &= ~(SHIP_AT_MAX_SPEED | SHIP_BEYOND_MAX_SPEED); if (ElementPtr->thrust_wait == 0) ++ElementPtr->thrust_wait; thrust_increment = StarShipPtr->RaceDescPtr->characteristics.thrust_increment; max_thrust = StarShipPtr->RaceDescPtr->characteristics.max_thrust; StarShipPtr->RaceDescPtr->characteristics.thrust_increment = SPECIAL_THRUST_INCREMENT; StarShipPtr->RaceDescPtr->characteristics.max_thrust = SPECIAL_MAX_THRUST; thrust_status = inertial_thrust (ElementPtr); StarShipPtr->cur_status_flags &= ~(SHIP_AT_MAX_SPEED | SHIP_BEYOND_MAX_SPEED | SHIP_IN_GRAVITY_WELL); StarShipPtr->cur_status_flags |= thrust_status; StarShipPtr->RaceDescPtr->characteristics.thrust_increment = thrust_increment; StarShipPtr->RaceDescPtr->characteristics.max_thrust = max_thrust; { MISSILE_BLOCK MissileBlock; MissileBlock.cx = ElementPtr->next.location.x; MissileBlock.cy = ElementPtr->next.location.y; MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.special; MissileBlock.face = 0; MissileBlock.index = GetFrameCount ( StarShipPtr->RaceDescPtr->ship_data.special[0] ) - 1; MissileBlock.sender = ElementPtr->playerNr; MissileBlock.flags = IGNORE_SIMILAR; MissileBlock.pixoffs = 0; MissileBlock.speed = 0; MissileBlock.hit_points = NAPALM_HITS; MissileBlock.damage = NAPALM_DAMAGE; MissileBlock.life = NAPALM_LIFE; MissileBlock.preprocess_func = flame_napalm_preprocess; MissileBlock.blast_offs = NAPALM_OFFSET; hTrailElement = initialize_missile (&MissileBlock); if (hTrailElement) { ELEMENT *TrailElementPtr; LockElement (hTrailElement, &TrailElementPtr); SetElementStarShip (TrailElementPtr, StarShipPtr); TrailElementPtr->hTarget = 0; /* turn_wait is abused here to store the speed of the decay * animation */ TrailElementPtr->turn_wait = NAPALM_DECAY_RATE; TrailElementPtr->state_flags |= NONSOLID; SetPrimType ( &(GLOBAL (DisplayArray))[TrailElementPtr->PrimIndex], NO_PRIM ); /* normally done during preprocess, but because * object is being inserted at head rather than * appended after tail it may never get preprocessed. */ TrailElementPtr->next = TrailElementPtr->current; TrailElementPtr->state_flags |= PRE_PROCESS; UnlockElement (hTrailElement); InsertElement (hTrailElement, GetHeadElement ()); ProcessSound (SetAbsSoundIndex ( StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); } } } }
static void thraddash_preprocess (ELEMENT *ElementPtr) { STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); // Switch side guns after every shot. if (StarShipPtr->weapon_counter == 1) { if (StarShipPtr->static_counter == 0) ++StarShipPtr->static_counter; else StarShipPtr->static_counter = 0; } if (!(StarShipPtr->cur_status_flags & SPECIAL)) { if (StarShipPtr->old_status_flags & SPECIAL && StarShipPtr->cur_status_flags & SHIP_AT_MAX_SPEED) StarShipPtr->cur_status_flags |= SHIP_BEYOND_MAX_SPEED; } else if (StarShipPtr->RaceDescPtr->ship_info.energy_level >= SPECIAL_ENERGY_COST) { COUNT max_thrust, thrust_increment; STATUS_FLAGS thrust_status; HELEMENT hTrailElement; if (!(StarShipPtr->old_status_flags & SPECIAL)) StarShipPtr->cur_status_flags &= ~(SHIP_AT_MAX_SPEED | SHIP_BEYOND_MAX_SPEED); if (ElementPtr->thrust_wait == 0) ++ElementPtr->thrust_wait; thrust_increment = StarShipPtr->RaceDescPtr->characteristics.thrust_increment; max_thrust = StarShipPtr->RaceDescPtr->characteristics.max_thrust; StarShipPtr->RaceDescPtr->characteristics.thrust_increment = SPECIAL_THRUST_INCREMENT; StarShipPtr->RaceDescPtr->characteristics.max_thrust = SPECIAL_MAX_THRUST; thrust_status = inertial_thrust (ElementPtr); StarShipPtr->cur_status_flags &= ~(SHIP_AT_MAX_SPEED | SHIP_BEYOND_MAX_SPEED | SHIP_IN_GRAVITY_WELL); StarShipPtr->cur_status_flags |= thrust_status; StarShipPtr->RaceDescPtr->characteristics.thrust_increment = thrust_increment; StarShipPtr->RaceDescPtr->characteristics.max_thrust = max_thrust; // Reduce afterburner energy consumption to 2/3. if (StarShipPtr->special_counter == 0) { DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST); StarShipPtr->special_counter = 3; } else if (StarShipPtr->special_counter == 2) DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST); { MISSILE_BLOCK MissileBlock; MissileBlock.cx = ElementPtr->next.location.x; MissileBlock.cy = ElementPtr->next.location.y; MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.special; MissileBlock.face = 0; MissileBlock.index = GetFrameCount (StarShipPtr->RaceDescPtr->ship_data.special[0]) - 1; MissileBlock.sender = ElementPtr->playerNr; MissileBlock.flags = IGNORE_SIMILAR; MissileBlock.pixoffs = 0; MissileBlock.speed = 0; MissileBlock.hit_points = NAPALM_HITS; MissileBlock.damage = NAPALM_DAMAGE; MissileBlock.life = NAPALM_LIFE; MissileBlock.preprocess_func = flame_napalm_preprocess; MissileBlock.blast_offs = NAPALM_OFFSET; hTrailElement = initialize_missile (&MissileBlock); if (hTrailElement) { ELEMENT *TrailElementPtr; LockElement (hTrailElement, &TrailElementPtr); SetElementStarShip (TrailElementPtr, StarShipPtr); TrailElementPtr->hTarget = 0; TrailElementPtr->turn_wait = NAPALM_FADE_WAIT; TrailElementPtr->state_flags |= NONSOLID; SetPrimType ( &(GLOBAL (DisplayArray))[TrailElementPtr->PrimIndex], NO_PRIM ); /* normally done during preprocess, but because * object is being inserted at head rather than * appended after tail it may never get preprocessed. */ TrailElementPtr->next = TrailElementPtr->current; TrailElementPtr->state_flags |= PRE_PROCESS; UnlockElement (hTrailElement); InsertElement (hTrailElement, GetHeadElement ()); ProcessSound (SetAbsSoundIndex ( /* BURNT_TOAST */ StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); } } } else if (StarShipPtr->RaceDescPtr->ship_info.energy_level < SPECIAL_ENERGY_COST) DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST); /* so text will flash */ }
static COUNT initialize_dual_weapons (ELEMENT *ShipPtr, HELEMENT WeaponArray[]) { #define CENTER_OFFS DISPLAY_TO_WORLD (4) COORD cx, cy; COUNT facing, angle; SIZE offs_x, offs_y; STARSHIP *StarShipPtr; GetElementStarShip (ShipPtr, &StarShipPtr); facing = StarShipPtr->ShipFacing; angle = FACING_TO_ANGLE (facing); cx = ShipPtr->next.location.x + COSINE (angle, CENTER_OFFS); cy = ShipPtr->next.location.y + SINE (angle, CENTER_OFFS); if (ShipPtr->next.image.farray == StarShipPtr->RaceDescPtr->ship_data.ship) { #define WING_OFFS DISPLAY_TO_WORLD (10) COORD ex, ey; LASER_BLOCK LaserBlock; ELEMENT *LaserPtr; LaserBlock.sender = ShipPtr->state_flags & (GOOD_GUY | BAD_GUY); LaserBlock.pixoffs = 0; LaserBlock.color = BUILD_COLOR (MAKE_RGB15 (0x1F, 0x0A, 0x0A), 0x0C); LaserBlock.face = facing; ex = cx + COSINE (angle, LASER_RANGE); ey = cy + SINE (angle, LASER_RANGE); offs_x = -SINE (angle, WING_OFFS); offs_y = COSINE (angle, WING_OFFS); LaserBlock.cx = cx + offs_x; LaserBlock.cy = cy + offs_y; LaserBlock.ex = ex - LaserBlock.cx; LaserBlock.ey = ey - LaserBlock.cy; if ((WeaponArray[0] = initialize_laser (&LaserBlock))) { LockElement (WeaponArray[0], &LaserPtr); LaserPtr->collision_func = twin_laser_collision; UnlockElement (WeaponArray[0]); } LaserBlock.cx = cx - offs_x; LaserBlock.cy = cy - offs_y; LaserBlock.ex = ex - LaserBlock.cx; LaserBlock.ey = ey - LaserBlock.cy; if ((WeaponArray[1] = initialize_laser (&LaserBlock))) { LockElement (WeaponArray[1], &LaserPtr); LaserPtr->collision_func = twin_laser_collision; UnlockElement (WeaponArray[1]); } } else { #define MISSILE_HITS 1 #define MISSILE_DAMAGE 1 #define MISSILE_OFFSET 0 #define MISSILE_LIFE 40 #define LAUNCH_OFFS DISPLAY_TO_WORLD (4) MISSILE_BLOCK TorpBlock; ELEMENT *TorpPtr; TorpBlock.farray = StarShipPtr->RaceDescPtr->ship_data.weapon; TorpBlock.sender = (ShipPtr->state_flags & (GOOD_GUY | BAD_GUY)) | IGNORE_SIMILAR; TorpBlock.pixoffs = 0; TorpBlock.speed = MISSILE_SPEED; TorpBlock.hit_points = MISSILE_HITS; TorpBlock.damage = MISSILE_DAMAGE; TorpBlock.life = MISSILE_LIFE; TorpBlock.preprocess_func = missile_preprocess; TorpBlock.blast_offs = MISSILE_OFFSET; TorpBlock.face = TorpBlock.index = NORMALIZE_FACING (facing - 1); offs_x = -SINE (FACING_TO_ANGLE (TorpBlock.face), LAUNCH_OFFS); offs_y = COSINE (FACING_TO_ANGLE (TorpBlock.face), LAUNCH_OFFS); TorpBlock.cx = cx + offs_x; TorpBlock.cy = cy + offs_y; if ((WeaponArray[0] = initialize_missile (&TorpBlock))) { LockElement (WeaponArray[0], &TorpPtr); TorpPtr->turn_wait = TRACK_WAIT; UnlockElement (WeaponArray[0]); } TorpBlock.face = TorpBlock.index = NORMALIZE_FACING (facing + 1); TorpBlock.cx = cx - offs_x; TorpBlock.cy = cy - offs_y; if ((WeaponArray[1] = initialize_missile (&TorpBlock))) { LockElement (WeaponArray[1], &TorpPtr); TorpPtr->turn_wait = TRACK_WAIT; UnlockElement (WeaponArray[1]); } } return (2); }
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); }
// 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); } }