/* GL-117 Copyright 2001, 2002 Thomas A. Drexl aka heptargon This file is part of GL-117. GL-117 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. GL-117 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 GL-117; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* This file includes all AI objects instancing models. */ #ifndef IS_AIOBJECT_H #define IS_AIOBJECT_H #include "common.h" // ok #include "model.h" // ok #include "effects.h" // ok // id values of objects // non-AI air objects #define CANNON1 0 #define ASTEROID 50 #define FLARE1 80 #define CHAFF1 85 #define CANNON2 99 // missiles #define MISSILE1 100 #define MISSILE_AIR1 100 #define MISSILE_AIR2 101 #define MISSILE_AIR3 102 #define MISSILE_GROUND1 103 #define MISSILE_GROUND2 104 #define MISSILE_DF1 105 #define MISSILE_FF1 106 #define MISSILE_FF2 107 #define MISSILE_MINE1 180 #define MISSILE2 199 // air units #define AIR 200 #define FIGHTER1 200 #define FIGHTER_FALCON 200 #define FIGHTER_SWALLOW 201 #define FIGHTER_HAWK 202 #define FIGHTER_HAWK2 203 #define FIGHTER_BUZZARD 204 #define FIGHTER_CROW 205 #define FIGHTER_PHOENIX 206 #define FIGHTER_REDARROW 207 #define FIGHTER_BLACKBIRD 208 #define FIGHTER_STORM 209 #define FIGHTER_PILOTED2 249 #define FIGHTER_TRANSPORT 280 #define FIGHTER_TRANSPORT2 281 #define FIGHTER2 299 // moving ground units from here #define MOVING_GROUND 500 #define TANK1 700 #define TANK_AIR1 700 #define TANK_GROUND1 710 #define TANK_TRSAM1 711 #define TANK_PICKUP1 780 #define TANK_TRUCK1 790 #define TANK_TRUCK2 791 #define TANK2 799 // moving water units from here #define MOVING_WATER 800 #define SHIP1 800 #define SHIP_CRUISER 800 #define SHIP_DESTROYER1 810 #define SHIP2 899 // static ground units from here #define STATIC_GROUND 1000 #define FLAK1 1000 #define FLAK_AIR1 1000 #define FLARAK_AIR1 1010 #define FLAK2 1099 // passive static units from here #define STATIC_PASSIVE 10000 #define STATIC_TENT1 10000 #define STATIC_TENT4 10003 #define STATIC_CONTAINER1 10100 #define STATIC_HALL1 10200 #define STATIC_HALL2 10201 #define STATIC_OILRIG1 10300 #define STATIC_COMPLEX1 10301 #define STATIC_RADAR1 10302 #define STATIC_BASE1 10303 #define STATIC_DEPOT1 10304 #define STATIC_BARRIER1 10400 class DynamicObj : public CSpaceObj { public: int id; // object type: FLARAK_AIR1, STATIC_TENT1, FIGHTER_SWALLOW, ... // bool controls; bool active; // deactivated means no AI, no collision control and so on // easymodel==1 is the ancient core of the game ;-) // 1 means that theta will directly alter phi! Computer AI uses this model! // 2 means the realistic model with ailerons, elevator, rudder int easymodel; int ttl; // time to live: cannon and missiles will only live a short time, missiles will sink when ttl<=0 int immunity; // immunity means the object cannot collide with others, needed for shooting missiles/cannon float impact; // this value will be subtracted from the other objects shield when colliding // Imagine a carthesian coordinate system in the landscape, the y-axis pointing up float phi; // angle in x-z plane (polar coordinates) float gamma; // orthogonal angle (polar coordinates) float theta; // roll angle of the fighter! float thrust; // current thrust, not the speed itself! float realspeed; // the current speed, we only want to calculate this once per time step float forcex, forcez, forcey; // the force vectors (orthogonal, should be clear) float braking; // far away from reality: this factorizes the last speed vector with the current conditions (see move method) float manoeverability; // how fast a fighter can alter its direction float nimbility; // how fast a fighter responds to alterations of recXXX (recommended XXX) float maxthrust; // maximum throttle value float rectheta; // roll angle the fighter/object wants to reach float recthrust; // throttle the fighter/object wants to reach float recheight; // height above ground the fighter wants to reach float recgamma; // elevation the fighter wants to reach float maxtheta; // a maximum roll angle the object may achieve, easymodel==1 only! float maxgamma; // a maximum elevation the object may achieve, easymodel==1 only! float elevatoreffect; // number between 1.0 and -0.5, as diving should be less float ruddereffect; float rolleffect; float recelevatoreffect; // number between 1.0 and -0.5, as diving should be less float recruddereffect; float recrolleffect; int party; // usually 0 for enemies, 1 for allieds int points, fighterkills, shipkills, tankkills, otherkills; // statistics int sink; // ships will not explode but sink bool killed; // statistics Space *space; // in which space is this object, there is only one ;-) DynamicObj *source; // missiles must keep track of the object they have been fired from -> statistics int bomber; // act as bomber and prefer groud targets char net [100]; int realism; float accx, accy, accz; float shield, maxshield; // current and initial/maximum shield int net_write (); void net_read (); void activate (); void deactivate (); void dinit (); DynamicObj (); DynamicObj (Space *space2, CModel *o2, float zoom2); void thrustUp (); void thrustDown (); float distance (DynamicObj *target); float distanceXZ (DynamicObj *target); // check whether the object is exploding or sinking and deactivate if necessary void checkExplosion (Uint32 dt); // check the objects shield value and explode/sink if necessary void checkShield (); // check whether the object collides on the ground and alter gamma and y-translation void crashGround (Uint32 dt); // check for collision, simplified model, each model is surrounded by a cube // this works pretty well, but we must use more than one model for complex models or scenes void collide (DynamicObj *d, Uint32 dt); // d must be the medium (laser, missile) void setExplosion (float maxzoom, int len); void setBlackSmoke (float maxzoom, int len); // return heading difference towards enemy int getAngle (DynamicObj *o); // return elevation difference towards enemy int getAngleH (DynamicObj *o); // check for a looping, this is tricky :-) bool checkLooping (); void move (Uint32 dt); }; const int missiletypes = 8; const int missileracks = 6; class AIObj : public DynamicObj { protected: public: bool ai; // AI on/off bool autofire; // cannon fire on/off DynamicObj *target; // targeted object int acttype; // object is doing some action (Immelmann, Loop, ... not yet implemented) // three intellience characteristics which make up a pilot: 0 = best, 400 = worst int intelligence; // valid for every AI object: manoevers, fire rate (tanks), ... int aggressivity; // valid for fighters: fly low, stay near and behind enemy int precision; // valid for fighters: heading calculation // manoevers disable any other AI consideration int manoevertheta, manoeverheight, manoeverthrust; int idle; // counter how long AI object does the same thing (to change direction) int firemissilettl; // minimum time to wait between shooting missiles int firecannonttl; // minimum time to wait between shooting cannon int smokettl; // minimum time to wait between setting smoke elements int missiletype; // only relevant for the player, describes type: AAM, AGM, DF int missiles [missiletypes]; // number of missiles of each type int missilerack [missileracks]; // number of missile racks int missilerackn [missileracks]; // number of missile racks float aw; // current heading difference to target int score; // final score float dtheta, dgamma; // theta/gamma alteration (smooth piloting) float disttarget; // current distance to target int flares; int chaffs; int fireflarettl; int firechaffttl; int ammo; int ttf; // time to fire missile, targeting mechanism CSmoke *smoke; // bright smoke behind the object (fighter&missiles) Uint32 timer; int statfirepower; // firepower (missiles) statistics, number of stars bool dualshot; // one or two cannons? int manoeverstate; // changes to realistic manoevers and turns off easymodel void aiinit (); // initialize variables void missileCount (); void newinit (int id, int party, int intelligence, int precision, int aggressivity); // init new AI object void newinit (int id, int party, int intelligence); // init new AI object (esp. non-fighter) AIObj (); AIObj (Space *space2, CModel *o2, float zoom2); ~AIObj (); void initValues (DynamicObj *dobj, float phi); // init values to shoot cannon or missile void fireCannon (DynamicObj *laser, float phi); void fireCannon (DynamicObj **laser, float phi); void fireCannon (DynamicObj **laser); void fireMissile2 (int id, AIObj *missile, AIObj *target); void fireFlare2 (DynamicObj *flare); void fireChaff2 (DynamicObj *chaff); int firstMissile (); // select first missile type int nextMissile (int from); // select next missile type (cyclic) bool haveMissile (int id); // missile of type id left? bool haveMissile (); // missile of type missiletype left? void decreaseMissile (int id); // decrease missiles by one bool fireMissile (int id, AIObj **missile, AIObj *target); bool fireMissile (AIObj **missile, AIObj *target); bool fireMissile (int id, AIObj **missile); bool fireMissile (AIObj **missile); bool fireFlare (DynamicObj **flare, AIObj **missile); bool fireChaff (DynamicObj **chaff, AIObj **missile); bool fireMissileAir (AIObj **missile, AIObj *target); bool selectMissileAir (AIObj **missile); bool fireMissileAirFF (AIObj **missile, AIObj *target); bool selectMissileAirFF (AIObj **missile); bool fireMissileGround (AIObj **missile); bool selectMissileGround (AIObj **missile); void targetNearestGroundEnemy (AIObj **f); void targetNearestEnemy (AIObj **f); void targetNextEnemy (AIObj **f); void targetLockingEnemy (AIObj **f); void targetNext (AIObj **f); void targetPrevious (AIObj **f); void aiAction (Uint32 dt, AIObj **f, AIObj **m, DynamicObj **c, DynamicObj **flare, DynamicObj **chaff); // core AI method }; #endif