From 7f6002caba3f0a6749820c2772161caf55b8d267 Mon Sep 17 00:00:00 2001 From: neonloop Date: Fri, 7 May 2021 20:00:12 +0000 Subject: Initial commit (uqm-0.8.0) --- src/uqm/ships/yehat/yehat.c | 369 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 369 insertions(+) create mode 100644 src/uqm/ships/yehat/yehat.c (limited to 'src/uqm/ships/yehat/yehat.c') diff --git a/src/uqm/ships/yehat/yehat.c b/src/uqm/ships/yehat/yehat.c new file mode 100644 index 0000000..f3d0fb8 --- /dev/null +++ b/src/uqm/ships/yehat/yehat.c @@ -0,0 +1,369 @@ +//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 "yehat.h" +#include "resinst.h" + +#include "libs/mathlib.h" + +// Core characteristics +#define MAX_CREW 20 +#define MAX_ENERGY 10 +#define ENERGY_REGENERATION 2 +#define ENERGY_WAIT 6 +#define MAX_THRUST 30 +#define THRUST_INCREMENT 6 +#define THRUST_WAIT 2 +#define TURN_WAIT 2 +#define SHIP_MASS 3 + +// Twin Pulse Cannon +#define WEAPON_ENERGY_COST 1 +#define WEAPON_WAIT 0 +#define YEHAT_OFFSET 16 +#define LAUNCH_OFFS DISPLAY_TO_WORLD (8) +#define MISSILE_SPEED DISPLAY_TO_WORLD (20) +#define MISSILE_LIFE 10 +#define MISSILE_HITS 1 +#define MISSILE_DAMAGE 1 +#define MISSILE_OFFSET 1 + +// Force Shield +#define SPECIAL_ENERGY_COST 3 +#define SPECIAL_WAIT 2 +#define SHIELD_LIFE 10 + +static RACE_DESC yehat_desc = +{ + { /* SHIP_INFO */ + FIRES_FORE | SHIELD_DEFENSE, + 23, /* Super Melee cost */ + MAX_CREW, MAX_CREW, + MAX_ENERGY, MAX_ENERGY, + YEHAT_RACE_STRINGS, + YEHAT_ICON_MASK_PMAP_ANIM, + YEHAT_MICON_MASK_PMAP_ANIM, + NULL, NULL, NULL + }, + { /* FLEET_STUFF */ + 750 / SPHERE_RADIUS_INCREMENT * 2, /* Initial SoI radius */ + { /* Known location (center of SoI) */ + 4970, 40, + }, + }, + { + MAX_THRUST, + THRUST_INCREMENT, + ENERGY_REGENERATION, + WEAPON_ENERGY_COST, + SPECIAL_ENERGY_COST, + ENERGY_WAIT, + TURN_WAIT, + THRUST_WAIT, + WEAPON_WAIT, + SPECIAL_WAIT, + SHIP_MASS, + }, + { + { + YEHAT_BIG_MASK_PMAP_ANIM, + YEHAT_MED_MASK_PMAP_ANIM, + YEHAT_SML_MASK_PMAP_ANIM, + }, + { + YEHAT_CANNON_BIG_MASK_PMAP_ANIM, + YEHAT_CANNON_MED_MASK_PMAP_ANIM, + YEHAT_CANNON_SML_MASK_PMAP_ANIM, + }, + { + SHIELD_BIG_MASK_ANIM, + SHIELD_MED_MASK_ANIM, + SHIELD_SML_MASK_ANIM, + }, + { + YEHAT_CAPTAIN_MASK_PMAP_ANIM, + NULL, NULL, NULL, NULL, NULL + }, + YEHAT_VICTORY_SONG, + YEHAT_SHIP_SOUNDS, + { NULL, NULL, NULL }, + { NULL, NULL, NULL }, + { NULL, NULL, NULL }, + NULL, NULL + }, + { + 0, + MISSILE_SPEED * MISSILE_LIFE / 3, + NULL, + }, + (UNINIT_FUNC *) NULL, + (PREPROCESS_FUNC *) NULL, + (POSTPROCESS_FUNC *) NULL, + (INIT_WEAPON_FUNC *) NULL, + 0, + 0, /* CodeRef */ +}; + +static COUNT +initialize_standard_missiles (ELEMENT *ShipPtr, HELEMENT MissileArray[]) +{ + SIZE offs_x, offs_y; + STARSHIP *StarShipPtr; + MISSILE_BLOCK MissileBlock; + + GetElementStarShip (ShipPtr, &StarShipPtr); + MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.weapon; + MissileBlock.face = MissileBlock.index = StarShipPtr->ShipFacing; + MissileBlock.sender = ShipPtr->playerNr; + MissileBlock.flags = IGNORE_SIMILAR; + MissileBlock.pixoffs = YEHAT_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; + + offs_x = -SINE (FACING_TO_ANGLE (MissileBlock.face), LAUNCH_OFFS); + offs_y = COSINE (FACING_TO_ANGLE (MissileBlock.face), LAUNCH_OFFS); + + MissileBlock.cx = ShipPtr->next.location.x + offs_x; + MissileBlock.cy = ShipPtr->next.location.y + offs_y; + MissileArray[0] = initialize_missile (&MissileBlock); + + MissileBlock.cx = ShipPtr->next.location.x - offs_x; + MissileBlock.cy = ShipPtr->next.location.y - offs_y; + MissileArray[1] = initialize_missile (&MissileBlock); + + return (2); +} + +static void +yehat_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern, + COUNT ConcernCounter) +{ + SIZE ShieldStatus; + STARSHIP *StarShipPtr; + EVALUATE_DESC *lpEvalDesc; + + ShieldStatus = -1; + lpEvalDesc = &ObjectsOfConcern[ENEMY_WEAPON_INDEX]; + if (lpEvalDesc->ObjectPtr && lpEvalDesc->MoveState == ENTICE) + { + ShieldStatus = 0; + if (!(lpEvalDesc->ObjectPtr->state_flags & (FINITE_LIFE | CREW_OBJECT))) + lpEvalDesc->MoveState = PURSUE; + else if (lpEvalDesc->ObjectPtr->mass_points + || (lpEvalDesc->ObjectPtr->state_flags & CREW_OBJECT)) + { + if (!(lpEvalDesc->ObjectPtr->state_flags & FINITE_LIFE)) + lpEvalDesc->which_turn <<= 1; + else + { + if ((lpEvalDesc->which_turn >>= 1) == 0) + lpEvalDesc->which_turn = 1; + + if (lpEvalDesc->ObjectPtr->mass_points) + lpEvalDesc->ObjectPtr = 0; + else + lpEvalDesc->MoveState = PURSUE; + } + ShieldStatus = 1; + } + } + + GetElementStarShip (ShipPtr, &StarShipPtr); + if (StarShipPtr->special_counter == 0) + { + StarShipPtr->ship_input_state &= ~SPECIAL; + if (ShieldStatus) + { + if (ShipPtr->life_span <= NORMAL_LIFE + 1 + && (ShieldStatus > 0 || lpEvalDesc->ObjectPtr) + && lpEvalDesc->which_turn <= 2 + && (ShieldStatus > 0 + || (lpEvalDesc->ObjectPtr->state_flags + & PLAYER_SHIP) /* means IMMEDIATE WEAPON */ + || PlotIntercept (lpEvalDesc->ObjectPtr, + ShipPtr, 2, 0)) + && (TFB_Random () & 3)) + StarShipPtr->ship_input_state |= SPECIAL; + + if (lpEvalDesc->ObjectPtr + && !(lpEvalDesc->ObjectPtr->state_flags & CREW_OBJECT)) + lpEvalDesc->ObjectPtr = 0; + } + } + + if ((lpEvalDesc = &ObjectsOfConcern[ENEMY_SHIP_INDEX])->ObjectPtr) + { + STARSHIP *EnemyStarShipPtr; + + GetElementStarShip (lpEvalDesc->ObjectPtr, &EnemyStarShipPtr); + if (!(EnemyStarShipPtr->RaceDescPtr->ship_info.ship_flags + & IMMEDIATE_WEAPON)) + lpEvalDesc->MoveState = PURSUE; + } + ship_intelligence (ShipPtr, ObjectsOfConcern, ConcernCounter); +/* + if (StarShipPtr->RaceDescPtr->ship_info.energy_level <= SPECIAL_ENERGY_COST) + StarShipPtr->ship_input_state &= ~WEAPON; +*/ +} + +static void +yehat_postprocess (ELEMENT *ElementPtr) +{ + if (!(ElementPtr->state_flags & NONSOLID)) + { + STARSHIP *StarShipPtr; + + GetElementStarShip (ElementPtr, &StarShipPtr); + /* take care of shield effect */ + if (StarShipPtr->special_counter > 0) + { + if (ElementPtr->life_span == NORMAL_LIFE) + StarShipPtr->special_counter = 0; + else + { +#ifdef OLD + SetPrimColor ( + &(GLOBAL (DisplayArray))[ElementPtr->PrimIndex], + BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F) + ); + SetPrimType ( + &(GLOBAL (DisplayArray))[ElementPtr->PrimIndex], + STAMPFILL_PRIM + ); +#endif /* OLD */ + + ProcessSound (SetAbsSoundIndex ( + /* YEHAT_SHIELD_ON */ + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); + DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST); + } + } + +#ifdef OLD + if (ElementPtr->life_span > NORMAL_LIFE) + { + HELEMENT hShipElement; + + if (hShipElement = AllocElement ()) + { + ELEMENT *ShipElementPtr; + + InsertElement (hShipElement, GetSuccElement (ElementPtr)); + LockElement (hShipElement, &ShipElementPtr); + ShipElementPtr->playerNr = ElementPtr->playerNr; + ShipElementPtr->state_flags = + /* in place of APPEARING */ + (CHANGING | PRE_PROCESS | POST_PROCESS) + | FINITE_LIFE | NONSOLID; + SetPrimType ( + &(GLOBAL (DisplayArray))[ShipElementPtr->PrimIndex], + STAMP_PRIM + ); + + ShipElementPtr->life_span = 0; /* because preprocessing + * will not be done + */ + ShipElementPtr->current.location = ElementPtr->next.location; + ShipElementPtr->current.image.farray = StarShipPtr->RaceDescPtr->ship_data.ship; + ShipElementPtr->current.image.frame = + SetAbsFrameIndex (StarShipPtr->RaceDescPtr->ship_data.ship[0], + StarShipPtr->ShipFacing); + ShipElementPtr->next = ShipElementPtr->current; + ShipElementPtr->preprocess_func = + ShipElementPtr->postprocess_func = + ShipElementPtr->death_func = NULL; + ZeroVelocityComponents (&ShipElementPtr->velocity); + + UnlockElement (hShipElement); + } + } +#endif /* OLD */ + } +} + +static void +yehat_preprocess (ELEMENT *ElementPtr) +{ + if (!(ElementPtr->state_flags & APPEARING)) + { + STARSHIP *StarShipPtr; + + GetElementStarShip (ElementPtr, &StarShipPtr); + if ((ElementPtr->life_span > NORMAL_LIFE + /* take care of shield effect */ + && --ElementPtr->life_span == NORMAL_LIFE) + || (ElementPtr->life_span == NORMAL_LIFE + && ElementPtr->next.image.farray + == StarShipPtr->RaceDescPtr->ship_data.special)) + { +#ifdef NEVER + SetPrimType ( + &(GLOBAL (DisplayArray))[ElementPtr->PrimIndex], + STAMP_PRIM + ); +#endif /* NEVER */ + + ElementPtr->next.image.farray = StarShipPtr->RaceDescPtr->ship_data.ship; + ElementPtr->next.image.frame = + SetEquFrameIndex (StarShipPtr->RaceDescPtr->ship_data.ship[0], + ElementPtr->next.image.frame); + ElementPtr->state_flags |= CHANGING; + } + + if ((StarShipPtr->cur_status_flags & SPECIAL) + && StarShipPtr->special_counter == 0) + { + if (StarShipPtr->RaceDescPtr->ship_info.energy_level < SPECIAL_ENERGY_COST) + DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST); /* so text will flash */ + else + { + ElementPtr->life_span = SHIELD_LIFE + NORMAL_LIFE; + + ElementPtr->next.image.farray = StarShipPtr->RaceDescPtr->ship_data.special; + ElementPtr->next.image.frame = + SetEquFrameIndex (StarShipPtr->RaceDescPtr->ship_data.special[0], + ElementPtr->next.image.frame); + ElementPtr->state_flags |= CHANGING; + + StarShipPtr->special_counter = + StarShipPtr->RaceDescPtr->characteristics.special_wait; + } + } + } +} + +RACE_DESC* +init_yehat (void) +{ + RACE_DESC *RaceDescPtr; + + yehat_desc.preprocess_func = yehat_preprocess; + yehat_desc.postprocess_func = yehat_postprocess; + yehat_desc.init_weapon_func = initialize_standard_missiles; + yehat_desc.cyborg_control.intelligence_func = yehat_intelligence; + + RaceDescPtr = &yehat_desc; + + return (RaceDescPtr); +} -- cgit v1.2.3