diff options
Diffstat (limited to 'src/uqm/ships/arilou/arilou.c')
-rw-r--r-- | src/uqm/ships/arilou/arilou.c | 303 |
1 files changed, 303 insertions, 0 deletions
diff --git a/src/uqm/ships/arilou/arilou.c b/src/uqm/ships/arilou/arilou.c new file mode 100644 index 0000000..78340a3 --- /dev/null +++ b/src/uqm/ships/arilou/arilou.c @@ -0,0 +1,303 @@ +//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 "arilou.h" +#include "resinst.h" + +#include "libs/mathlib.h" + +// Core characteristics +#define MAX_CREW 6 +#define MAX_ENERGY 20 +#define ENERGY_REGENERATION 1 +#define ENERGY_WAIT 6 +#define MAX_THRUST /* DISPLAY_TO_WORLD (10) */ 40 +#define THRUST_INCREMENT MAX_THRUST +#define THRUST_WAIT 0 +#define TURN_WAIT 0 +#define SHIP_MASS 1 + +// Tracking Laser +#define WEAPON_ENERGY_COST 2 +#define WEAPON_WAIT 1 +#define ARILOU_OFFSET 9 +#define LASER_RANGE DISPLAY_TO_WORLD (100 + ARILOU_OFFSET) + +// Teleporter +#define SPECIAL_ENERGY_COST 3 +#define SPECIAL_WAIT 2 +#define HYPER_LIFE 5 + +static RACE_DESC arilou_desc = +{ + { /* SHIP_INFO */ + /* FIRES_FORE | */ IMMEDIATE_WEAPON, + 16, /* Super Melee cost */ + MAX_CREW, MAX_CREW, + MAX_ENERGY, MAX_ENERGY, + ARILOU_RACE_STRINGS, + ARILOU_ICON_MASK_PMAP_ANIM, + ARILOU_MICON_MASK_PMAP_ANIM, + NULL, NULL, NULL + }, + { /* FLEET_STUFF */ + 250 / SPHERE_RADIUS_INCREMENT * 2, /* Initial SoI radius */ + { /* Known location (center of SoI) */ + 438, 6372, + }, + }, + { + MAX_THRUST, + THRUST_INCREMENT, + ENERGY_REGENERATION, + WEAPON_ENERGY_COST, + SPECIAL_ENERGY_COST, + ENERGY_WAIT, + TURN_WAIT, + THRUST_WAIT, + WEAPON_WAIT, + SPECIAL_WAIT, + SHIP_MASS, + }, + { + { + ARILOU_BIG_MASK_PMAP_ANIM, + ARILOU_MED_MASK_PMAP_ANIM, + ARILOU_SML_MASK_PMAP_ANIM, + }, + { + NULL_RESOURCE, + NULL_RESOURCE, + NULL_RESOURCE, + }, + { + WARP_BIG_MASK_PMAP_ANIM, + WARP_MED_MASK_PMAP_ANIM, + WARP_SML_MASK_PMAP_ANIM, + }, + { + ARILOU_CAPTAIN_MASK_PMAP_ANIM, + NULL, NULL, NULL, NULL, NULL + }, + ARILOU_VICTORY_SONG, + ARILOU_SHIP_SOUNDS, + { NULL, NULL, NULL }, + { NULL, NULL, NULL }, + { NULL, NULL, NULL }, + NULL, NULL + }, + { + 0, + LASER_RANGE >> 1, + NULL, + }, + (UNINIT_FUNC *) NULL, + (PREPROCESS_FUNC *) NULL, + (POSTPROCESS_FUNC *) NULL, + (INIT_WEAPON_FUNC *) NULL, + 0, + 0, /* CodeRef */ +}; + +static COUNT +initialize_autoaim_laser (ELEMENT *ShipPtr, HELEMENT LaserArray[]) +{ + COUNT orig_facing; + SIZE delta_facing; + STARSHIP *StarShipPtr; + LASER_BLOCK LaserBlock; + + GetElementStarShip (ShipPtr, &StarShipPtr); + LaserBlock.face = orig_facing = StarShipPtr->ShipFacing; + if ((delta_facing = TrackShip (ShipPtr, &LaserBlock.face)) > 0) + LaserBlock.face = NORMALIZE_FACING (orig_facing + delta_facing); + ShipPtr->hTarget = 0; + + LaserBlock.cx = ShipPtr->next.location.x; + LaserBlock.cy = ShipPtr->next.location.y; + LaserBlock.ex = COSINE (FACING_TO_ANGLE (LaserBlock.face), LASER_RANGE); + LaserBlock.ey = SINE (FACING_TO_ANGLE (LaserBlock.face), LASER_RANGE); + LaserBlock.sender = ShipPtr->playerNr; + LaserBlock.flags = IGNORE_SIMILAR; + LaserBlock.pixoffs = ARILOU_OFFSET; + LaserBlock.color = BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x0A), 0x0E); + LaserArray[0] = initialize_laser (&LaserBlock); + + return (1); +} + +static void +arilou_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern, + COUNT ConcernCounter) +{ + STARSHIP *StarShipPtr; + + GetElementStarShip (ShipPtr, &StarShipPtr); + StarShipPtr->ship_input_state |= THRUST; + + ObjectsOfConcern[ENEMY_SHIP_INDEX].MoveState = ENTICE; + ship_intelligence (ShipPtr, ObjectsOfConcern, ConcernCounter); + + if (StarShipPtr->special_counter == 0) + { + EVALUATE_DESC *lpEvalDesc; + + StarShipPtr->ship_input_state &= ~SPECIAL; + + lpEvalDesc = &ObjectsOfConcern[ENEMY_WEAPON_INDEX]; + if (lpEvalDesc->ObjectPtr && lpEvalDesc->which_turn <= 6) + { + BOOLEAN IsTrackingWeapon; + STARSHIP *EnemyStarShipPtr; + + GetElementStarShip (lpEvalDesc->ObjectPtr, &EnemyStarShipPtr); + if (((EnemyStarShipPtr->RaceDescPtr->ship_info.ship_flags + & SEEKING_WEAPON) && + lpEvalDesc->ObjectPtr->next.image.farray == + EnemyStarShipPtr->RaceDescPtr->ship_data.weapon) || + ((EnemyStarShipPtr->RaceDescPtr->ship_info.ship_flags + & SEEKING_SPECIAL) && + lpEvalDesc->ObjectPtr->next.image.farray == + EnemyStarShipPtr->RaceDescPtr->ship_data.special)) + IsTrackingWeapon = TRUE; + else + IsTrackingWeapon = FALSE; + + if (((lpEvalDesc->ObjectPtr->state_flags & PLAYER_SHIP) /* means IMMEDIATE WEAPON */ + || (IsTrackingWeapon && (lpEvalDesc->which_turn == 1 + || (lpEvalDesc->ObjectPtr->state_flags & CREW_OBJECT))) /* FIGHTERS!!! */ + || PlotIntercept (lpEvalDesc->ObjectPtr, ShipPtr, 3, 0)) + && !(TFB_Random () & 3)) + { + StarShipPtr->ship_input_state &= ~(LEFT | RIGHT | THRUST | WEAPON); + StarShipPtr->ship_input_state |= SPECIAL; + } + } + } + if (StarShipPtr->RaceDescPtr->ship_info.energy_level <= SPECIAL_ENERGY_COST << 1) + StarShipPtr->ship_input_state &= ~WEAPON; +} + +static void +arilou_preprocess (ELEMENT *ElementPtr) +{ + STARSHIP *StarShipPtr; + + GetElementStarShip (ElementPtr, &StarShipPtr); + if (!(ElementPtr->state_flags & NONSOLID)) + { + if (ElementPtr->thrust_wait == 0) + { + ZeroVelocityComponents (&ElementPtr->velocity); + StarShipPtr->cur_status_flags &= ~SHIP_AT_MAX_SPEED; + } + + if ((StarShipPtr->cur_status_flags & SPECIAL) + && StarShipPtr->special_counter == 0 + && DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST)) + { + /* Special key is pressed; start teleport */ + ZeroVelocityComponents (&ElementPtr->velocity); + StarShipPtr->cur_status_flags &= + ~(SHIP_AT_MAX_SPEED | LEFT | RIGHT | THRUST | WEAPON); + + ElementPtr->state_flags |= NONSOLID | FINITE_LIFE | CHANGING; + ElementPtr->life_span = HYPER_LIFE; + + ElementPtr->next.image.farray = + StarShipPtr->RaceDescPtr->ship_data.special; + ElementPtr->next.image.frame = + StarShipPtr->RaceDescPtr->ship_data.special[0]; + + ProcessSound (SetAbsSoundIndex ( + /* HYPERJUMP */ + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); + StarShipPtr->special_counter = + StarShipPtr->RaceDescPtr->characteristics.special_wait; + } + } + else if (ElementPtr->next.image.farray == StarShipPtr->RaceDescPtr->ship_data.special) + { + COUNT life_span; + + StarShipPtr->cur_status_flags = + (StarShipPtr->cur_status_flags + & ~(LEFT | RIGHT | THRUST | WEAPON | SPECIAL)) + | (StarShipPtr->old_status_flags + & (LEFT | RIGHT | THRUST | WEAPON | SPECIAL)); + ++StarShipPtr->weapon_counter; + ++StarShipPtr->special_counter; + ++StarShipPtr->energy_counter; + ++ElementPtr->turn_wait; + ++ElementPtr->thrust_wait; + + if ((life_span = ElementPtr->life_span) == NORMAL_LIFE) + { + /* Ending teleport */ + ElementPtr->state_flags &= ~(NONSOLID | FINITE_LIFE); + ElementPtr->state_flags |= APPEARING; + ElementPtr->current.image.farray = + ElementPtr->next.image.farray = + StarShipPtr->RaceDescPtr->ship_data.ship; + ElementPtr->current.image.frame = + ElementPtr->next.image.frame = + SetAbsFrameIndex (StarShipPtr->RaceDescPtr->ship_data.ship[0], + StarShipPtr->ShipFacing); + InitIntersectStartPoint (ElementPtr); + } + else + { + /* Teleporting in progress */ + --life_span; + if (life_span != 2) + { + if (life_span < 2) + ElementPtr->next.image.frame = + DecFrameIndex (ElementPtr->next.image.frame); + else + ElementPtr->next.image.frame = + IncFrameIndex (ElementPtr->next.image.frame); + } + else + { + ElementPtr->next.location.x = + WRAP_X (DISPLAY_ALIGN_X (TFB_Random ())); + ElementPtr->next.location.y = + WRAP_Y (DISPLAY_ALIGN_Y (TFB_Random ())); + } + } + + ElementPtr->state_flags |= CHANGING; + } +} + +RACE_DESC* +init_arilou (void) +{ + RACE_DESC *RaceDescPtr; + + arilou_desc.preprocess_func = arilou_preprocess; + arilou_desc.init_weapon_func = initialize_autoaim_laser; + arilou_desc.cyborg_control.intelligence_func = arilou_intelligence; + + RaceDescPtr = &arilou_desc; + + return (RaceDescPtr); +} + |