summaryrefslogtreecommitdiff
path: root/src/uqm/ships/ilwrath/ilwrath.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/uqm/ships/ilwrath/ilwrath.c')
-rw-r--r--src/uqm/ships/ilwrath/ilwrath.c409
1 files changed, 409 insertions, 0 deletions
diff --git a/src/uqm/ships/ilwrath/ilwrath.c b/src/uqm/ships/ilwrath/ilwrath.c
new file mode 100644
index 0000000..3947081
--- /dev/null
+++ b/src/uqm/ships/ilwrath/ilwrath.c
@@ -0,0 +1,409 @@
+//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 "ilwrath.h"
+#include "resinst.h"
+
+#include "uqm/colors.h"
+#include "uqm/globdata.h"
+
+
+// Core characteristics
+#define MAX_CREW 22
+#define MAX_ENERGY 16
+#define ENERGY_REGENERATION 4
+#define ENERGY_WAIT 4
+#define MAX_THRUST 25
+#define THRUST_INCREMENT 5
+#define THRUST_WAIT 0
+#define TURN_WAIT 2
+#define SHIP_MASS 7
+#define LOOK_AHEAD 4
+ /* Controls how much the auto-turn will attempt to "lead"
+ * its target. */
+
+// Hellfire Spout
+#define WEAPON_ENERGY_COST 1
+#define WEAPON_WAIT 0
+#define MISSILE_LIFE 8
+#define ILWRATH_OFFSET 29
+#define MISSILE_SPEED MAX_THRUST
+#define MISSILE_HITS 1
+#define MISSILE_DAMAGE 1
+#define MISSILE_OFFSET 0
+
+// Cloaking Device
+#define SPECIAL_ENERGY_COST 3
+#define SPECIAL_WAIT 13
+
+static RACE_DESC ilwrath_desc =
+{
+ { /* SHIP_INFO */
+ FIRES_FORE,
+ 10, /* Super Melee cost */
+ MAX_CREW, MAX_CREW,
+ MAX_ENERGY, MAX_ENERGY,
+ ILWRATH_RACE_STRINGS,
+ ILWRATH_ICON_MASK_PMAP_ANIM,
+ ILWRATH_MICON_MASK_PMAP_ANIM,
+ NULL, NULL, NULL
+ },
+ { /* FLEET_STUFF */
+ 1410 / SPHERE_RADIUS_INCREMENT * 2, /* Initial SoI radius */
+ { /* Known location (center of SoI) */
+ 48, 1700,
+ },
+ },
+ {
+ MAX_THRUST,
+ THRUST_INCREMENT,
+ ENERGY_REGENERATION,
+ WEAPON_ENERGY_COST,
+ SPECIAL_ENERGY_COST,
+ ENERGY_WAIT,
+ TURN_WAIT,
+ THRUST_WAIT,
+ WEAPON_WAIT,
+ SPECIAL_WAIT,
+ SHIP_MASS,
+ },
+ {
+ {
+ ILWRATH_BIG_MASK_PMAP_ANIM,
+ ILWRATH_MED_MASK_PMAP_ANIM,
+ ILWRATH_SML_MASK_PMAP_ANIM,
+ },
+ {
+ FIRE_BIG_MASK_PMAP_ANIM,
+ FIRE_MED_MASK_PMAP_ANIM,
+ FIRE_SML_MASK_PMAP_ANIM,
+ },
+ {
+ NULL_RESOURCE,
+ NULL_RESOURCE,
+ NULL_RESOURCE,
+ },
+ {
+ ILWRATH_CAPTAIN_MASK_PMAP_ANIM,
+ NULL, NULL, NULL, NULL, NULL
+ },
+ ILWRATH_VICTORY_SONG,
+ ILWRATH_SHIP_SOUNDS,
+ { NULL, NULL, NULL },
+ { NULL, NULL, NULL },
+ { NULL, NULL, NULL },
+ NULL, NULL
+ },
+ {
+ 0,
+ CLOSE_RANGE_WEAPON,
+ NULL,
+ },
+ (UNINIT_FUNC *) NULL,
+ (PREPROCESS_FUNC *) NULL,
+ (POSTPROCESS_FUNC *) NULL,
+ (INIT_WEAPON_FUNC *) NULL,
+ 0,
+ 0, /* CodeRef */
+};
+
+static void
+flame_preprocess (ELEMENT *ElementPtr)
+{
+ if (ElementPtr->turn_wait > 0)
+ --ElementPtr->turn_wait;
+ else
+ {
+ ElementPtr->next.image.frame =
+ IncFrameIndex (ElementPtr->current.image.frame);
+ ElementPtr->state_flags |= CHANGING;
+
+ ElementPtr->turn_wait = ElementPtr->next_turn;
+ }
+}
+
+static void
+flame_collision (ELEMENT *ElementPtr0, POINT *pPt0,
+ ELEMENT *ElementPtr1, POINT *pPt1)
+{
+ weapon_collision (ElementPtr0, pPt0, ElementPtr1, pPt1);
+ ElementPtr0->state_flags &= ~DISAPPEARING;
+ ElementPtr0->state_flags |= NONSOLID;
+}
+
+static void
+ilwrath_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern,
+ COUNT ConcernCounter)
+{
+ EVALUATE_DESC *lpEvalDesc;
+ STARSHIP *StarShipPtr;
+
+ lpEvalDesc = &ObjectsOfConcern[ENEMY_SHIP_INDEX];
+ lpEvalDesc->MoveState = PURSUE;
+ if (lpEvalDesc->ObjectPtr && lpEvalDesc->which_turn <= 10)
+ /* don't want to dodge when you could be flaming */
+ ObjectsOfConcern[ENEMY_WEAPON_INDEX].ObjectPtr = 0;
+
+ ship_intelligence (ShipPtr, ObjectsOfConcern, ConcernCounter);
+
+ GetElementStarShip (ShipPtr, &StarShipPtr);
+ if (lpEvalDesc->ObjectPtr
+ && (lpEvalDesc->which_turn <= 6
+ || (lpEvalDesc->which_turn <= 10
+ && ObjectsOfConcern[ENEMY_WEAPON_INDEX].which_turn <= 10)))
+ {
+ StarShipPtr->ship_input_state &= ~SPECIAL;
+ if (OBJECT_CLOAKED (ShipPtr))
+ {
+ StarShipPtr->ship_input_state &= ~LEFT | RIGHT;
+ StarShipPtr->ship_input_state |= THRUST;
+ }
+ StarShipPtr->ship_input_state |= WEAPON;
+ }
+ else if (StarShipPtr->special_counter == 0
+ && (LOBYTE (GLOBAL (CurrentActivity)) != IN_ENCOUNTER
+ || !GET_GAME_STATE (PROBE_ILWRATH_ENCOUNTER)))
+ {
+ StarShipPtr->ship_input_state &= ~SPECIAL;
+ if (!OBJECT_CLOAKED (ShipPtr)
+ && !(StarShipPtr->ship_input_state & WEAPON))
+ StarShipPtr->ship_input_state |= SPECIAL;
+ }
+}
+
+static COUNT
+initialize_flame (ELEMENT *ShipPtr, HELEMENT FlameArray[])
+{
+ 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 = 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;
+ ELEMENT *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 void
+ilwrath_preprocess (ELEMENT *ElementPtr)
+{
+ STATUS_FLAGS status_flags;
+ STARSHIP *StarShipPtr;
+ PRIMITIVE *lpPrim;
+
+ GetElementStarShip (ElementPtr, &StarShipPtr);
+ status_flags = StarShipPtr->cur_status_flags;
+ lpPrim = &(GLOBAL (DisplayArray))[ElementPtr->PrimIndex];
+ if (GetPrimType (lpPrim) == STAMPFILL_PRIM)
+ {
+ Color color;
+ BOOLEAN weapon_discharge;
+
+ color = GetPrimColor (lpPrim);
+ weapon_discharge = ((status_flags & WEAPON)
+ && StarShipPtr->RaceDescPtr->ship_info.energy_level >= WEAPON_ENERGY_COST);
+ if (weapon_discharge
+ || (StarShipPtr->special_counter == 0
+ && ((status_flags & SPECIAL) ||
+ !sameColor (color, BLACK_COLOR))))
+ {
+ if (sameColor (color,
+ BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F)))
+ SetPrimType (lpPrim, STAMP_PRIM);
+ else if (sameColor (color,
+ BUILD_COLOR (MAKE_RGB15 (0x0A, 0x1F, 0x1F), 0x0B)))
+ SetPrimColor (lpPrim,
+ BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F));
+ else if (sameColor (color,
+ BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x14), 0x03)))
+ SetPrimColor (lpPrim,
+ BUILD_COLOR (MAKE_RGB15 (0x0A, 0x1F, 0x1F), 0x0B));
+ else if (sameColor (color,
+ BUILD_COLOR (MAKE_RGB15 (0x0A, 0x0A, 0x1F), 0x09)))
+ SetPrimColor (lpPrim,
+ BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x14), 0x03));
+ else if (sameColor (color,
+ BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01)))
+ SetPrimColor (lpPrim,
+ BUILD_COLOR (MAKE_RGB15 (0x0A, 0x0A, 0x1F), 0x09));
+ else
+ {
+ ProcessSound (SetAbsSoundIndex (
+ /* CLOAKING_OFF */
+ StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2), ElementPtr);
+ SetPrimColor (lpPrim,
+ BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01));
+ if (weapon_discharge)
+ {
+ COUNT facing;
+
+ facing = StarShipPtr->ShipFacing;
+ if (TrackShip (ElementPtr, &facing) >= 0)
+ {
+ ELEMENT *eptr;
+ SIZE dx0, dy0, dx1, dy1;
+ VELOCITY_DESC v;
+
+ LockElement (ElementPtr->hTarget, &eptr);
+ v = eptr->velocity;
+ GetNextVelocityComponents (&v, &dx0, &dy0, LOOK_AHEAD);
+ v = ElementPtr->velocity;
+ GetNextVelocityComponents (&v, &dx1, &dy1, LOOK_AHEAD);
+ dx0 = (eptr->current.location.x + dx0)
+ - (ElementPtr->current.location.x + dx1);
+ dy0 = (eptr->current.location.y + dy0)
+ - (ElementPtr->current.location.y + dy1);
+ UnlockElement (ElementPtr->hTarget);
+
+ StarShipPtr->ShipFacing =
+ NORMALIZE_FACING (
+ ANGLE_TO_FACING (ARCTAN (dx0, dy0))
+ );
+#ifdef NOTYET
+ if (ElementPtr->thrust_wait == 0
+ && (StarShipPtr->cur_status_flags & THRUST))
+ {
+ COUNT last_facing;
+
+ do
+ {
+ VELOCITY_DESC temp_v;
+
+ last_facing = StarShipPtr->ShipFacing;
+ inertial_thrust (ElementPtr);
+ temp_v = ElementPtr->velocity;
+ ElementPtr->velocity = v;
+
+ dx0 += dx1;
+ dy0 += dy1;
+ GetNextVelocityComponents (&temp_v,
+ &dx1, &dy1, LOOK_AHEAD);
+ dx0 -= dx1;
+ dy0 -= dy1;
+ StarShipPtr->ShipFacing =
+ NORMALIZE_FACING (
+ ANGLE_TO_FACING (ARCTAN (dx0, dy0))
+ );
+ } while (StarShipPtr->ShipFacing != last_facing);
+ }
+#endif /* NOTYET */
+ if (ElementPtr->turn_wait == 0)
+ ++ElementPtr->turn_wait;
+ ElementPtr->next.image.frame =
+ SetAbsFrameIndex (ElementPtr->next.image.frame,
+ StarShipPtr->ShipFacing);
+ }
+ ElementPtr->hTarget = 0;
+ }
+ }
+
+ ElementPtr->state_flags |= CHANGING;
+ status_flags &= ~SPECIAL;
+ StarShipPtr->special_counter = 0;
+ }
+ else if (!sameColor (color, BLACK_COLOR))
+ {
+ if (sameColor (color,
+ BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01)))
+ {
+ SetPrimColor (lpPrim, BLACK_COLOR);
+ Untarget (ElementPtr);
+ }
+ else if (sameColor (color,
+ BUILD_COLOR (MAKE_RGB15 (0x0A, 0x0A, 0x1F), 0x09)))
+ SetPrimColor (lpPrim,
+ BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01));
+ else if (sameColor (color,
+ BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x14), 0x03)))
+ SetPrimColor (lpPrim,
+ BUILD_COLOR (MAKE_RGB15 (0x0A, 0x0A, 0x1F), 0x09));
+ else if (sameColor (color,
+ BUILD_COLOR (MAKE_RGB15 (0x0A, 0x1F, 0x1F), 0x0B)))
+ SetPrimColor (lpPrim,
+ BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x14), 0x03));
+ else
+ SetPrimColor (lpPrim,
+ BUILD_COLOR (MAKE_RGB15 (0x0A, 0x1F, 0x1F), 0x0B));
+
+ ElementPtr->state_flags |= CHANGING;
+ }
+ }
+
+ if ((status_flags & SPECIAL)
+ && StarShipPtr->special_counter == 0
+ && DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST))
+ {
+ SetPrimColor (lpPrim,
+ BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F));
+ SetPrimType (lpPrim, STAMPFILL_PRIM);
+
+ ProcessSound (SetAbsSoundIndex (
+ /* CLOAKING_ON */
+ StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1),
+ ElementPtr);
+ StarShipPtr->special_counter =
+ StarShipPtr->RaceDescPtr->characteristics.special_wait;
+
+ ElementPtr->state_flags |= CHANGING;
+ }
+}
+
+RACE_DESC*
+init_ilwrath (void)
+{
+ RACE_DESC *RaceDescPtr;
+
+ ilwrath_desc.preprocess_func = ilwrath_preprocess;
+ ilwrath_desc.init_weapon_func = initialize_flame;
+ ilwrath_desc.cyborg_control.intelligence_func = ilwrath_intelligence;
+
+ RaceDescPtr = &ilwrath_desc;
+
+ return (RaceDescPtr);
+}
+