diff options
Diffstat (limited to 'src/uqm/ships/supox/supox.c')
-rw-r--r-- | src/uqm/ships/supox/supox.c | 288 |
1 files changed, 288 insertions, 0 deletions
diff --git a/src/uqm/ships/supox/supox.c b/src/uqm/ships/supox/supox.c new file mode 100644 index 0000000..854c5b3 --- /dev/null +++ b/src/uqm/ships/supox/supox.c @@ -0,0 +1,288 @@ +//Copyright Paul Reiche, Fred Ford. 1992-2002 + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "../ship.h" +#include "supox.h" +#include "resinst.h" + +#include "libs/mathlib.h" + +// Core characteristics +#define MAX_CREW 12 +#define MAX_ENERGY 16 +#define ENERGY_REGENERATION 1 +#define ENERGY_WAIT 4 +#define MAX_THRUST 40 +#define THRUST_INCREMENT 8 +#define THRUST_WAIT 0 +#define TURN_WAIT 1 +#define SHIP_MASS 4 + +// Gob launcher +#define WEAPON_ENERGY_COST 1 +#define WEAPON_WAIT 2 +#define SUPOX_OFFSET 23 +#define MISSILE_OFFSET 2 +#define MISSILE_SPEED DISPLAY_TO_WORLD (30) +#define MISSILE_LIFE 10 +#define MISSILE_HITS 1 +#define MISSILE_DAMAGE 1 + +// Lateral/reverse thrust +#define SPECIAL_ENERGY_COST 1 + /* Unused - uncomment below to enable. */ +#define SPECIAL_WAIT 0 + /* Unused except to initialize supox_desc.special_wait */ + +static RACE_DESC supox_desc = +{ + { /* SHIP_INFO */ + FIRES_FORE, + 16, /* Super Melee cost */ + MAX_CREW, MAX_CREW, + MAX_ENERGY, MAX_ENERGY, + SUPOX_RACE_STRINGS, + SUPOX_ICON_MASK_PMAP_ANIM, + SUPOX_MICON_MASK_PMAP_ANIM, + NULL, NULL, NULL + }, + { /* FLEET_STUFF */ + 333 / SPHERE_RADIUS_INCREMENT * 2, /* Initial SoI radius */ + { /* Known location (center of SoI) */ + 7468, 9246, + }, + }, + { + MAX_THRUST, + THRUST_INCREMENT, + ENERGY_REGENERATION, + WEAPON_ENERGY_COST, + SPECIAL_ENERGY_COST, + ENERGY_WAIT, + TURN_WAIT, + THRUST_WAIT, + WEAPON_WAIT, + SPECIAL_WAIT, + SHIP_MASS, + }, + { + { + SUPOX_BIG_MASK_PMAP_ANIM, + SUPOX_MED_MASK_PMAP_ANIM, + SUPOX_SML_MASK_PMAP_ANIM, + }, + { + GOB_BIG_MASK_PMAP_ANIM, + GOB_MED_MASK_PMAP_ANIM, + GOB_SML_MASK_PMAP_ANIM, + }, + { + NULL_RESOURCE, + NULL_RESOURCE, + NULL_RESOURCE, + }, + { + SUPOX_CAPTAIN_MASK_PMAP_ANIM, + NULL, NULL, NULL, NULL, NULL + }, + SUPOX_VICTORY_SONG, + SUPOX_SHIP_SOUNDS, + { NULL, NULL, NULL }, + { NULL, NULL, NULL }, + { NULL, NULL, NULL }, + NULL, NULL + }, + { + 0, + (MISSILE_SPEED * MISSILE_LIFE) >> 1, + NULL, + }, + (UNINIT_FUNC *) NULL, + (PREPROCESS_FUNC *) NULL, + (POSTPROCESS_FUNC *) NULL, + (INIT_WEAPON_FUNC *) NULL, + 0, + 0, /* CodeRef */ +}; + +static void +supox_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern, + COUNT ConcernCounter) +{ + STARSHIP *StarShipPtr; + EVALUATE_DESC *lpEvalDesc; + + GetElementStarShip (ShipPtr, &StarShipPtr); + + lpEvalDesc = &ObjectsOfConcern[ENEMY_SHIP_INDEX]; + if (StarShipPtr->special_counter || lpEvalDesc->ObjectPtr == 0) + StarShipPtr->ship_input_state &= ~SPECIAL; + else + { + BOOLEAN LinedUp; + COUNT direction_angle; + SIZE 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); + + LinedUp = (BOOLEAN)(NORMALIZE_ANGLE (NORMALIZE_ANGLE (direction_angle + - FACING_TO_ANGLE (StarShipPtr->ShipFacing)) + + QUADRANT) <= HALF_CIRCLE); + + if (!LinedUp + || lpEvalDesc->which_turn > 20 + || NORMALIZE_ANGLE ( + lpEvalDesc->facing + - (FACING_TO_ANGLE (StarShipPtr->ShipFacing) + + HALF_CIRCLE) + OCTANT + ) > QUADRANT) + StarShipPtr->ship_input_state &= ~SPECIAL; + else if (LinedUp && lpEvalDesc->which_turn <= 12) + StarShipPtr->ship_input_state |= SPECIAL; + + if (StarShipPtr->ship_input_state & SPECIAL) + lpEvalDesc->MoveState = PURSUE; + } + + ship_intelligence (ShipPtr, + ObjectsOfConcern, ConcernCounter); + + if (StarShipPtr->ship_input_state & SPECIAL) + StarShipPtr->ship_input_state |= THRUST | WEAPON; + + lpEvalDesc = &ObjectsOfConcern[ENEMY_WEAPON_INDEX]; + if (StarShipPtr->special_counter == 0 + && lpEvalDesc->ObjectPtr + && lpEvalDesc->MoveState == AVOID + && ShipPtr->turn_wait == 0) + { + StarShipPtr->ship_input_state &= ~THRUST; + StarShipPtr->ship_input_state |= SPECIAL; + if (!(StarShipPtr->cur_status_flags & (LEFT | RIGHT))) + StarShipPtr->ship_input_state |= 1 << ((BYTE)TFB_Random () & 1); + else + StarShipPtr->ship_input_state |= + StarShipPtr->cur_status_flags & (LEFT | RIGHT); + } +} + +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 = 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 void +supox_preprocess (ELEMENT *ElementPtr) +{ + STARSHIP *StarShipPtr; + + GetElementStarShip (ElementPtr, &StarShipPtr); + if ((StarShipPtr->cur_status_flags & SPECIAL) +/* + && DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST) +*/ + ) + { + SIZE add_facing; + + add_facing = 0; + if (StarShipPtr->cur_status_flags & THRUST) + { + if (ElementPtr->thrust_wait == 0) + ++ElementPtr->thrust_wait; + + add_facing = ANGLE_TO_FACING (HALF_CIRCLE); + } + if (StarShipPtr->cur_status_flags & LEFT) + { + if (ElementPtr->turn_wait == 0) + ++ElementPtr->turn_wait; + + if (add_facing) + add_facing += ANGLE_TO_FACING (OCTANT); + else + add_facing = -ANGLE_TO_FACING (QUADRANT); + } + else if (StarShipPtr->cur_status_flags & RIGHT) + { + if (ElementPtr->turn_wait == 0) + ++ElementPtr->turn_wait; + + if (add_facing) + add_facing -= ANGLE_TO_FACING (OCTANT); + else + add_facing = ANGLE_TO_FACING (QUADRANT); + } + + if (add_facing) + { + COUNT facing; + STATUS_FLAGS thrust_status; + + facing = StarShipPtr->ShipFacing; + StarShipPtr->ShipFacing = NORMALIZE_FACING ( + facing + add_facing + ); + 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->ShipFacing = facing; + } + } +} + +RACE_DESC* +init_supox (void) +{ + RACE_DESC *RaceDescPtr; + + supox_desc.preprocess_func = supox_preprocess; + supox_desc.init_weapon_func = initialize_horn; + supox_desc.cyborg_control.intelligence_func = supox_intelligence; + + RaceDescPtr = &supox_desc; + + return (RaceDescPtr); +} + |