1 /* 2 * Shotgun Debugger 3 * Copyright 2005 Game Creation Society 4 * 5 * Programmed by Matt Sarnoff 6 * http://www.contrib.andrew.cmu.edu/~msarnoff 7 * http://www.gamecreation.org 8 * 9 * objects.h - header file for object routines 10 * 11 * This program is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU General Public License 13 * as published by the Free Software Foundation; either version 2 14 * of the License, or (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 24 * 25 * MD2 model loader by DigiBen, www.gametutorials.com. Adapted from his code. 26 * The MD2 model format is copyright id software, inc. 27 */ 28 29 #ifndef _OBJECTS_H_ 30 #define _OBJECTS_H_ 31 32 #include "sdb.h" 33 34 // Types of all objects 35 enum OBJECT_TYPES { 36 37 ENT_PLAYER, ENT_BOX, ENT_BARREL, ENT_STEEL_CRATE, ENT_MISC1, ENT_MISC2, ENT_MISC3, ENT_MISC4, ENT_MISC5, 38 ENT_UNARMED_GUARD, ENT_MIB, ENT_ARMED_DRONE, ENT_HUNTER, ENT_GLADIATOR, 39 ENT_TURRET1, ENT_SLAVE_TURRET, ENT_EMISC1, 40 ENT_EMISC2, ENT_EMISC3, ENT_EMISC4, ENT_EMISC5, 41 42 POWERUP_HEALTH, POWERUP_SHOTGUN_AMMO, POWERUP_ENERGY_CLIP, 43 POWERUP_HEPA_CLIP, POWERUP_LASER_CELL, POWERUP_GRENADE, POWERUP_ESG_BATTERY, 44 POWERUP_KEY1, POWERUP_KEY2, POWERUP_KEY3, WEAPON_RIFLE, 45 WEAPON_SHOTGUN, WEAPON_HEPA, WEAPON_RED_LASER, WEAPON_ESG, 46 47 EXPLODER, BLT_LASER, 48 49 PART_PARTICLE, PART_PARTICLE_BLOOD, PART_PARTICLE_SLIME, PART_PARTICLE_SPARK, PART_PARTICLE_ENERGY, 50 PART_PARTICLE_WOOD, PART_PARTICLE_METAL, PART_PARTICLE_GLOW, PART_HEPA_TRAIL, PART_HEPA_EXPLOSION, PART_HEPA_SPARK, PART_GRENADE_TRAIL, 51 PART_LASER_SPARK1, PART_LASER_SPARK2, PART_ESG_SHOCKWAVE, 52 PART_BIT, 53 PART_MF_RIFLE, PART_MF_SHOTGUN, 54 PART_RIFLE_SHELL, PART_SHOTGUN_SHELL, 55 PART_EXPLOSION, PART_EXPLOSIONPART, 56 PART_SMOKE, 57 58 59 BLT_RIFLE, BLT_SHOTGUN, BLT_HEPA, BLT_GRENADE, BLT_SHRAPNEL, BLT_BLASTER, 60 61 ESG_EXPLODER, 62 NUM_OBJ_TYPES}; 63 #define MAX_ENT 38 64 //#define MAX_POWERUP 24 65 #define MAX_PART 7 66 67 #define IS_ENEMY(x) (x >= ENT_UNARMED_GUARD && x <= ENT_SLAVE_TURRET) 68 #define IS_POWERUP(x) (x >= POWERUP_HEALTH && x <= WEAPON_ESG) 69 #define IS_WEAPON(x) (x >= WEAPON_RIFLE && x <= WEAPON_ESG) 70 #define IS_BULLET(x) (x >= BLT_RIFLE && x <= BLT_BLASTER) 71 #define POWERUP_HEALTH_AMOUNT 25 72 73 // Extra type definitions for particles 74 enum PARTICLE_TYPES { 75 P_PART_PARTICLE, P_PART_PARTICLE_BLOOD, P_PART_PARTICLE_SLIME, P_PART_PARTICLE_SPARK, P_PART_PARTICLE_ENERGY, 76 P_PART_PARTICLE_WOOD, P_PART_PARTICLE_METAL, P_PART_PARTICLE_GLOW, P_PART_HEPA_TRAIL,P_PART_HEPA_EXPLOSION,P_PART_HEPA_SPARK,P_PART_GRENADE_TRAIL, 77 P_PART_LASER_SPARK1, P_PART_LASER_SPARK2, P_PART_ESG_SHOCKWAVE, 78 P_PART_BIT, 79 P_PART_MF_RIFLE, P_PART_MF_SHOTGUN, 80 P_PART_RIFLE_SHELL, P_PART_SHOTGUN_SHELL, 81 P_PART_EXPLOSION, P_PART_EXPLOSIONPART, 82 P_PART_SMOKE, 83 84 P_BLT_RIFLE, P_BLT_SHOTGUN, P_BLT_HEPA, P_BLT_GRENADE, P_BLT_SHRAPNEL, P_BLT_BLASTER, 85 P_ESG_EXPLODER, 86 NUM_PART_TYPES}; 87 88 // Extra type definitions for bullets 89 enum BULLET_TYPES { 90 B_BLT_RIFLE, B_BLT_SHOTGUN, B_BLT_HEPA, B_BLT_GRENADE, B_BLT_SHRAPNEL, B_BLT_BLASTER, 91 NUM_BLT_TYPES}; 92 93 // Laser types 94 enum LASER_TYPES { 95 L_STANDARD, L_CHARGED, 96 NUM_LASER_TYPES}; 97 98 // Death types 99 enum DEATH_TYPES { DEATH_NONE, DEATH_PLAYER, DEATH_SMALL_EXPLOSION, DEATH_EXPLOSION, 100 DEATH_HEPA_EXPLOSION, DEATH_GRENADE_EXPLOSION, DEATH_WOOD, DEATH_ROBOT, DEATH_GLADIATOR, DEATH_POWERUP, DEATH_ESG, NUM_DEATH_TYPES }; 101 102 enum ALERT_TYPES { ALERT_NONE, ALERT_TOUCH, ALERT_SHOT, ALERT_SHOCKWAVE }; 103 104 #define MAX_OBJ_SPRITES 32 105 #define NO_SPRITE -1 106 #define NO_MODEL -1 107 #define NO_ALERT -1000 108 #define INF -1 109 #define ANIM_FWD 1 110 #define ANIM_REV -1 111 #define FORCE_RECT true 112 #define FORCE_POLAR false 113 #define HIT_NOTHING 0 114 #define HIT_DIE 1 115 #define HIT_STOP 2 116 #define HIT_BOUNCE 3 117 #define ANIM_BASE false 118 #define ANIM_TRANSIENT true 119 #define DAMAGE_SHOCKWAVE true 120 #define DAMAGE_BULLET false 121 #define SHOCK_ESG -10000.0 122 123 #define NUM_KEYS 5 124 125 #define JUMP_PAUSE_TIME 0.5 126 #define FALL_KILL_DELAY 2.0 127 #define PUSH_STRENGTH 0.5 128 #define TERMINAL_VELOCITY 100.0 129 #define WALL_COLLISION_THRESHOLD 20.0 130 #define WALL_DAMAGE_THRESHOLD 35.0 131 #define IMPACT_DAMAGE_FACTOR 10.0 132 #define IMPACT_STUN_FACTOR 33.0 133 #define GIB_THRESHOLD -30.0 134 #define AUG_DAMAGE_SUPPRESSION 0.25 135 #define AUG_SPEED_INCREASE 1.4 136 137 138 139 #define texQuad(texnum) glBindTexture(GL_TEXTURE_2D, textures[texnum]); \ 140 glBegin(GL_QUADS); \ 141 glTexCoord2f(0.0, 0.0); \ 142 glVertex2f(-objType[type].spriteSize.c[X]/2, objType[type].spriteSize.c[Y]/2); \ 143 glTexCoord2f(1.0, 0.0); \ 144 glVertex2f(objType[type].spriteSize.c[X]/2, objType[type].spriteSize.c[Y]/2); \ 145 glTexCoord2f(1.0, 1.0); \ 146 glVertex2f(objType[type].spriteSize.c[X]/2, -objType[type].spriteSize.c[Y]/2); \ 147 glTexCoord2f(0.0, 1.0); \ 148 glVertex2f(-objType[type].spriteSize.c[X]/2, -objType[type].spriteSize.c[Y]/2); \ 149 glEnd(); \ 150 151 #define texQuadSize(texnum,w,h) glBindTexture(GL_TEXTURE_2D, textures[texnum]); \ 152 glBegin(GL_QUADS); \ 153 glTexCoord2f(0.0, 0.0); \ 154 glVertex2f(-w/2, h/2); \ 155 glTexCoord2f(1.0, 0.0); \ 156 glVertex2f(w/2, h/2); \ 157 glTexCoord2f(1.0, 1.0); \ 158 glVertex2f(w/2, -h/2); \ 159 glTexCoord2f(0.0, 1.0); \ 160 glVertex2f(-w/2, -h/2); \ 161 glEnd(); \ 162 163 #define texQuadClip(texnum,width,offset) glBindTexture(GL_TEXTURE_2D, textures[texnum]); \ 164 glBegin(GL_QUADS); \ 165 glTexCoord2f(width*offset, 0.0); \ 166 glVertex2f(-objType[type].spriteSize.c[X]/2, objType[type].spriteSize.c[Y]/2); \ 167 glTexCoord2f(width*offset+offset, 0.0); \ 168 glVertex2f(objType[type].spriteSize.c[X]/2, objType[type].spriteSize.c[Y]/2); \ 169 glTexCoord2f(width*offset+offset, 1.0); \ 170 glVertex2f(objType[type].spriteSize.c[X]/2, -objType[type].spriteSize.c[Y]/2); \ 171 glTexCoord2f(width*offset, 1.0); \ 172 glVertex2f(-objType[type].spriteSize.c[X]/2, -objType[type].spriteSize.c[Y]/2); \ 173 glEnd(); \ 174 175 #define addWeapon(wepn,name,full) \ 176 if (augmented) \ 177 pickedUp = false; \ 178 else if (wpn[wepn].addClipAmt() > 0 || !(weapons & (1 << wepn))) \ 179 setMessage(name); \ 180 else \ 181 { \ 182 setMessage(full); \ 183 pickedUp = false; \ 184 } \ 185 weapons |= 1 << wepn; \ 186 187 #define addWeaponSwitch(wepn,name,full) \ 188 if (augmented) \ 189 pickedUp = false; \ 190 else if (wpn[wepn].addClipAmt() > 0 || !(weapons & (1 << wepn))) \ 191 { \ 192 setMessage(name); \ 193 currWeapon = wepn; \ 194 } \ 195 else \ 196 { \ 197 setMessage(full); \ 198 pickedUp = false; \ 199 } \ 200 weapons |= 1 << wepn; \ 201 202 #define addAmmoPowerup(wepn,str,full) \ 203 if (augmented) \ 204 pickedUp = false; \ 205 else if ((iAmt = wpn[wepn].addClipAmt()) > 0) \ 206 setMessage(str, iAmt); \ 207 else \ 208 { \ 209 setMessage(full); \ 210 pickedUp = false; \ 211 } \ 212 213 extern int oID; 214 215 // Data for animation control 216 class Animation 217 { 218 public: Animation()219 Animation() { reset(); } Animation(int nf,float dl,int lp)220 Animation(int nf, float dl, int lp) { set(nf, dl, lp); } define(int nf,float dl,int lp)221 void define(int nf, float dl, int lp) { numFrames = nf; delay = dl; loop = lp; } set(int nf,float dl,int lp)222 void set(int nf, float dl, int lp) { define(nf, dl, lp); reset(); } reset()223 void reset() { done = false; run = true; animTime = frame = numLoops = 0; stopAtFrame = -1; direction = ANIM_FWD; } 224 void update(); 225 NumFrames()226 int NumFrames() { return numFrames; } Loops()227 int Loops() { return loop; } isDone()228 bool isDone() { return done; } Frame()229 int Frame() { return frame; } Delay()230 float Delay() { return delay; } Time()231 float Time() { return animTime; } 232 setDelay(float dl)233 void setDelay(float dl) { delay = dl; } setDirection(int dir)234 void setDirection(int dir) { direction = dir; } freezeAtFrame(int f)235 void freezeAtFrame(int f) { stopAtFrame = f; } 236 237 private: 238 int numFrames; 239 float delay; 240 int loop; 241 bool run; 242 bool done; 243 244 float animTime; 245 int frame; 246 int numLoops; 247 int direction; 248 int stopAtFrame; 249 }; 250 251 class ModelAnimation 252 { 253 public: ModelAnimation()254 ModelAnimation() { reset(); } ModelAnimation(int mdl)255 ModelAnimation(int mdl) { set(mdl); } reset()256 void reset() { model = baseAnim = transientAnim = 0; currAnim = false; currFrame = 0; nextFrame = 1; animTime = 0.0; speed = ANIMATION_SPEED; } set(int mdl)257 void set(int mdl) { reset(); model = mdl; } setSpeed(float s)258 void setSpeed(float s) { speed = s; } 259 void update(); 260 void setAnimation(int val, bool loop); inc()261 void inc() { currFrame++; nextFrame++; } 262 void draw(); 263 //private: 264 int model; 265 int currFrame, nextFrame; 266 int baseAnim, transientAnim; 267 bool currAnim; 268 float animTime; 269 float speed; 270 }; 271 272 // A force vector, applied to the specified object for the specified 273 // length of time. Measured in my force units (essentially the newton 274 // in US units, because the game uses US units) 275 class Force 276 { 277 public: Force()278 Force() { reset(); } Force(int obj,float dur,float a,float b,bool mode)279 Force(int obj, float dur, float a, float b, bool mode) { set(obj,dur,a,b,mode); } 280 void set(int obj, float dur, float a, float b, bool mode); reset()281 void reset() { forceTime = 0; active = false; destroyMe = false; } 282 void apply(); setActive(bool val)283 void setActive(bool val) {active = val;} toBeDestroyed()284 bool toBeDestroyed() { return destroyMe; } 285 private: 286 int target; 287 float duration; 288 Vector2D force; 289 float forceTime; 290 bool active; 291 bool destroyMe; 292 }; 293 294 // An explosion shockwave. 295 class Shockwave 296 { 297 public: Shockwave()298 Shockwave() { reset(); } 299 300 // So much for Kate's syntax highlighting. I originally named "float otr" "float or" 301 // (for "outer radius") and was getting the weirdest syntax errors ("parse error before "||"). 302 // I nearly screwed myself until I finally remembered that "or" is a C++ reserved word. 303 // That's why I changed it to "otr". Shockwave(float x,float y,float ir,float irs,float otr,float ors,float dur,float frc,float hlth,bool ag)304 Shockwave(float x, float y, float ir, float irs, float otr, float ors, float dur, float frc, float hlth, bool ag) 305 { set(x, y, ir, irs, otr, ors, dur, frc, hlth, ag); } 306 void set(float x, float y, float ir, float irs, float otr, float ors, float dur, float frc, float hlth, bool ag); 307 void reset(); 308 void update(); 309 void draw(); 310 bool detect(Vector2D p, float *resultForce, float *resultHealth); PosX()311 float PosX() { return pos.c[X]; } PosY()312 float PosY() { return pos.c[Y]; } setActive(bool val)313 void setActive(bool val) { active = val; } isActive()314 bool isActive() { return active; } toBeDestroyed()315 bool toBeDestroyed() { return destroyMe; } AffectGladiators()316 bool AffectGladiators() { return affectGladiators; } 317 private: 318 Vector2D pos; 319 float innerRad, outerRad; 320 float innerRadSpeed, outerRadSpeed; 321 float duration; 322 float force; 323 float health; 324 bool affectGladiators; 325 float shockTime; 326 bool active; 327 bool destroyMe; 328 }; 329 330 // A set of event-trigger flags. 331 // Value is 0 (do not take the action), 1 or -1 (take the action), 332 // or anywhere in between (analog input is allowed by some functions) 333 class ObjectEventTriggers 334 { 335 public: ObjectEventTriggers()336 ObjectEventTriggers() { reset(); } reset()337 void reset() { LR = FB = strafe = 0.0; jump = fire = grenade = reload = switchWpn = 0; } setLR(float val)338 void setLR(float val) { LR = val; } setFB(float val)339 void setFB(float val) { FB = val; } setStrafe(float val)340 void setStrafe(float val) { strafe = val; } setJump(int val)341 void setJump(int val) { jump = val; } setFire(int val)342 void setFire(int val) { fire = val; } setGrenade(int val)343 void setGrenade(int val) { grenade = val; } setReload(int val)344 void setReload(int val) { reload = val; } setSwitchWpn(int val)345 void setSwitchWpn(int val) { switchWpn = val; } getLR()346 float getLR() { return LR; } getFB()347 float getFB() { return FB; } getStrafe()348 float getStrafe() { return strafe; } getJump()349 int getJump() { return jump; } getFire()350 int getFire() { return fire; } getGrenade()351 int getGrenade() { return grenade; } getReload()352 int getReload() { return reload; } getSwitchWpn()353 int getSwitchWpn() { return switchWpn; } 354 355 private: 356 float LR; // turn left (-1) or right (+1) 357 float FB; // move forward (+1) or backward (-1) 358 float strafe; // strafe left (-1) or right (+1) 359 int jump; // jump 360 int fire; // fire current weapon 361 int grenade; // throw grenade 362 int reload; // reload current weapon 363 int switchWpn; // switch weapon 364 }; 365 366 // Specifications for an object. Different types of object 367 // (particle, etc.) may have an additional, more specific specification. 368 // ObjectType specifies basic information about movement, life, appearance, etc. 369 class ObjectType 370 { 371 public: ObjectType()372 ObjectType() {} ObjectType(float im,float iw,float ih,float ir,float imv,float ijv,float imtv,float ia,float ita,float hlth,int dth,bool cd,bool grav,bool shad)373 ObjectType(float im,float iw,float ih,float ir,float imv,float ijv,float imtv,float ia,float ita,float hlth,int dth,bool cd,bool grav,bool shad) 374 { set(im, iw, ih, ir, imv, ijv, imtv, ia, ita, hlth, dth, grav, shad, cd); } 375 void set(float im,float iw,float ih,float ir,float imv,float ijv,float imtv,float ia,float ita,float hlth,int dth,bool cd,bool grav,bool shad); clearSprites()376 void clearSprites() { for (int i=0;i<MAX_OBJ_SPRITES;i++) sprites[i]=NO_SPRITE; } 377 void setSprites(int num, ...); setModels(int mod1,int mod2)378 void setModels(int mod1, int mod2) { model1 = mod1; numModels = 1; if (mod2 != NO_MODEL) { model2 = mod2; numModels++; } } 379 380 float mass; // object mass (pounds) 381 Vector2D spriteSize;// sprite height and width (note that this may, and probably 382 // will, exceed the dimensions of the actual object. An object's 383 // real size is determined by the bounding-box parameter. 384 float boundRadius; // bounding circle radius 385 386 float maxVel; // maximum velocity (feet per second) 387 float jumpVel; // jump velocity (feet per second) 388 float maxTurnvel; // maximum turn speed (radians per second) 389 390 float accel; // lateral acceleration rate (feet per second squared) 391 float turnAccel; // turning acceleration rate (radians per second squared) 392 393 bool collide; // collision detection on/off? 394 bool gravAffect; // is the object affected by gravity? 395 bool hasShadow; // does the object have a shadow? 396 397 float maxHealth; // maximum health (-1 == indestructible) 398 399 int deathType; // death type 400 401 // Possible appearances of this object. 402 // Each object type uses and controls these sprites in its own way. 403 int sprites[MAX_OBJ_SPRITES]; 404 405 int model1, model2; 406 int numModels; 407 }; 408 409 class ParticleType 410 { 411 public: ParticleType()412 ParticleType() {} ParticleType(float mrl,float mrs,float mrjs,float rv,float mrrv,float fs,float mrfs,float sf,float ss,float sst,int hb,bool gl,float acc,int anf,float ad,float mrad,int al)413 ParticleType(float mrl, float mrs, float mrjs, float rv, float mrrv, float fs, float mrfs, float sf, float ss, float sst, int hb, bool gl, 414 float acc, int anf, float ad, float mrad, int al) 415 { set(mrl, mrs, mrjs, rv, mrrv, fs, mrfs, sf, ss, sst, hb, gl, acc, anf, ad, mrad, al); } 416 void set(float mrl, float mrs, float mrjs, float rv, float mrrv, float fs, float mrfs, float sf, float ss, float sst, int hb, bool gl, 417 float acc, int anf, float ad, float mrad, int al); 418 419 float maxRandAddedToLife; // life, speed, and jump speed are both defined in 420 float maxRandAddedToSpeed; // the ObjectType. 421 float maxRandAddedToJumpSpeed; 422 float minRotVel; // minimum rotational velocity 423 float maxRandAddedToRotVel; 424 float minFadeSpeed; 425 float maxRandAddedToFadeSpeed; 426 float startFade; 427 float scaleSpeed; 428 float scaleStop; 429 int hitBehavior; 430 bool glow; 431 float accel; 432 433 int animNumFrames; 434 float animDelay; 435 float maxRandAddedToAnimDelay; 436 int animLoop; 437 }; 438 439 class BulletType 440 { 441 public: BulletType()442 BulletType() {} BulletType(float dmg,float f)443 BulletType(float dmg, float f) { set(dmg, f); } set(float dmg,float f)444 void set(float dmg, float f) { damage = dmg; impactForce = f; } 445 446 float damage; 447 float impactForce; 448 }; 449 450 class LaserType 451 { 452 public: LaserType()453 LaserType() {} LaserType(int spr,float w,float mr,int mb,float dmg,float fs)454 LaserType(int spr, float w, float mr, int mb, float dmg, float fs) { set(spr, w, mr, mb, dmg, fs); } set(int spr,float w,float mr,int mb,float dmg,float fs)455 void set(int spr, float w, float mr, int mb, float dmg, float fs) 456 { sprite = spr; width = w; maxRange = mr; maxBounces = mb; damage = dmg; fadeSpeed = fs; } 457 458 int sprite; 459 float width; 460 float maxRange; 461 int maxBounces; 462 float damage; 463 float fadeSpeed; 464 }; 465 466 // Base class for objects. 467 class Object : public LevelObject 468 { 469 public: Object()470 Object() { type = 0; pos.set(0,0); vel.set(0,0); reset(); respondTo1 = respondTo2 = 0; setID(); } Object(int typ)471 Object(int typ) { type = typ; reset(); setID(); } Object(int typ,float x,float y,float head,int rt1,int rt2,int tr,int tt)472 Object(int typ, float x, float y, float head, int rt1, int rt2, int tr, int tt) { setID(); set(typ, x, y, head, rt1, rt2, tr, tt); } Object(int typ,float x,float y,float height,float head,int rt1,int rt2,int tr,int tt)473 Object(int typ, float x, float y, float height, float head, int rt1, int rt2, int tr, int tt) { setID(); set(typ, x, y, height, head, rt1, rt2, tr, tt); } set(int typ,float x,float y,float head,int rt1,int rt2,int tr,int tt)474 void set(int typ, float x, float y, float head, int rt1, int rt2, int tr, int tt) 475 { type = typ; reset(); setStartPos(x,y); heading = origHeading = head; trigInit(tr, tt); respondTo1 = rt1; respondTo2 = rt2; fixed = false; augmented = false; spr1 = spr2 = NO_SPRITE; } set(int typ,float x,float y,float height,float head,int rt1,int rt2,int tr,int tt)476 void set(int typ, float x, float y, float height, float head, int rt1, int rt2, int tr, int tt) 477 { type = typ; reset(); setStartPos(x,y); h = height; heading = origHeading = head; trigInit(tr, tt); respondTo1 = rt1; respondTo2 = rt2; fixed = false; augmented = false; spr1 = spr2 = NO_SPRITE; } 478 479 virtual void reset(); 480 virtual void draw(); 481 virtual void drawShadow(); 482 virtual void update(); 483 484 static void resetIDCounter(); 485 void setID(); setPos(float x,float y)486 void setPos(float x, float y) { pos.set(x, y); } setStartPos(float x,float y)487 void setStartPos(float x, float y) { setPos(x, y); origPos.set(x,y); } addPos(Vector2D v)488 void addPos(Vector2D v) { pos += v; } setVel(float x,float y)489 void setVel(float x, float y) { vel.set(x, y); } setHeight(float nh)490 void setHeight(float nh) { h = nh; } setHeading(float nhead)491 void setHeading(float nhead) { heading = nhead; } setLookAngle(float nangle)492 void setLookAngle(float nangle) { lookAngle = nangle; } 493 void turn(float amt); setSpeed(float nspeed)494 void setSpeed(float nspeed) { speed = nspeed; } setHVel(float nhvel)495 void setHVel(float nhvel) { hvel = nhvel; } setTurnVel(float ntvel)496 void setTurnVel(float ntvel) { turnvel = ntvel; } setActive(bool val)497 void setActive(bool val) { active = val; } setHealth(int val)498 void setHealth(int val) { health = val; } 499 void setAnimation(int val, bool anim); 500 void changeVel(Vector2D v); 501 void changeForceVel(Vector2D v); 502 void changeForceVelNoMass(Vector2D v); 503 setDirectionAlert(float ang,int typ)504 void setDirectionAlert(float ang, int typ) { dirAlert = ang; dirAlertType = typ; } 505 void changeHealth(float amt); 506 float changeHealthAmt(float amt); 507 void damage(float amt, bool by); 508 void stun(float amt); 509 void dyingCheck(); 510 511 void kill(bool death); die(float delay)512 void die(float delay) { dying = true; dyingTimer = delay; } 513 void doDeath(); 514 Type()515 int Type() { return type; } Pos()516 Vector2D Pos() { return pos; } Vel()517 Vector2D Vel() { return vel; } 518 ID()519 int ID() { return id; } PosX()520 float PosX() { return pos.c[X]; } PosY()521 float PosY() { return pos.c[Y]; } Heading()522 float Heading() { return heading; } LookAngle()523 float LookAngle() { return lookAngle; } VelX()524 float VelX() { return vel.c[X]; } VelY()525 float VelY() { return vel.c[Y]; } Speed()526 float Speed() { return vel.mag(); } Height()527 float Height() { return h; } HVel()528 float HVel() { return hvel; } Turnvel()529 float Turnvel() { return turnvel; } Health()530 float Health() { return health; } StunTimer()531 float StunTimer() { return stunTimer; } Stunned()532 bool Stunned() { return stunTimer > 0; } Dying()533 bool Dying() { return dying; } Fixed()534 bool Fixed() { return fixed; } Keys()535 int Keys() { return keys; } isActive()536 bool isActive() { return active; } toBeDestroyed()537 bool toBeDestroyed() { return destroyMe; } Falling()538 bool Falling() { return fall; } RespondTo1()539 int RespondTo1() { return respondTo1; } RespondTo2()540 int RespondTo2() { return respondTo2; } DirectionAlert()541 float DirectionAlert() { return dirAlert; } DirectionAlertType()542 float DirectionAlertType() { return dirAlertType; } State()543 int State() { return state; } LastDamageAmount()544 float LastDamageAmount() { return lastDamageAmount; } Augmented()545 bool Augmented() { return augmented; } Augment()546 void Augment() { model[1].set(MDL_PLAYER_TORSO2); augmented = true; } 547 Wpn()548 virtual Weapon* Wpn() {} CurrWeapon()549 virtual int CurrWeapon() {} selectWeapon(int wp)550 virtual void selectWeapon(int wp) {} weaponState(int wp)551 virtual char weaponState(int wp) {} keyState(int wp)552 virtual char keyState(int wp) {} WeaponPoint()553 virtual Vector2D* WeaponPoint() {} 554 giveKey(int key)555 void giveKey(int key) { keys |= 1 << key-1; } givePowerup(int idx)556 virtual void givePowerup(int idx) {} 557 resetCollided()558 void resetCollided() { collided = -1; } setCollided(int with)559 void setCollided(int with) { collided = with; } Collided()560 int Collided() { return collided; } 561 resetShockCollisions()562 void resetShockCollisions() { shockCollisions = 0; } ShockCollisions()563 long long int ShockCollisions() { return shockCollisions; } 564 565 ObjectEventTriggers ev; 566 nextAnimFrame()567 void nextAnimFrame() { model[0].inc(); model[1].inc(); } CurrFrame()568 void CurrFrame() { printf("m1=(%d->%d) m2=(%d->%d)\n", model[0].currFrame+1, model[0].nextFrame+1, model[1].currFrame+1, model[1].nextFrame+1); } setObjectCollisionDetectOnOff(bool s)569 void setObjectCollisionDetectOnOff(bool s) { collideWithObjects = s; } 570 protected: 571 void drawStart(); 572 void drawEnd(); 573 574 void shockwaveCollisionDetect(); 575 void laserCollisionDetect(); 576 Wall* wallCollisionDetect(int cell, Vector2D *inter); 577 bool floorCollisionDetect(int cell, float *fric); 578 void surfaceCollisionDetect(int cell, float *fric, float *hlth); 579 void objectCollisionDetect(int cell); CollideWithObjects()580 bool CollideWithObjects() { return collideWithObjects; } 581 582 void levelCollisionDetection(); 583 584 int id; 585 586 int type; // object type (for lookup in the global objType table) 587 bool augmented; 588 bool collideWithObjects; 589 590 Vector2D pos; // position 591 float h; // height 592 593 Vector2D vel; // x and y velocity components 594 Vector2D moveVel; 595 Vector2D forceVel; 596 float speed; // lateral (x-y) speed (feet per second) 597 float jumpSpeed, jumpHeading, jumpStrafe, jumpPause; 598 599 float hvel; // height velocity 600 601 float heading; // heading 602 float lookAngle; // direction the player is looking in (can be different from movement heading) 603 float turnvel; // turning speed (radians per second) 604 605 Vector2D origPos; 606 float origHeading; 607 608 // The object can be comprised of two independently-controlled sprites 609 // displayed on top of each other. spr1 is the lower sprite, spr2 is the upper 610 // sprite. 611 int spr1, spr2; 612 Animation spr1Anim, spr2Anim; 613 614 ModelAnimation model[2]; 615 bool useModel; 616 617 float health; // health (dead at 0) 618 int keys; // bitfield of keys this object owns 619 620 // Whether an entity is fully alive or not 621 bool active; 622 bool dying; 623 bool damagedBy; 624 float lastDamageAmount; 625 float dyingTimer; 626 627 bool fixed; 628 629 // Set this flag to tell the "higher powers" to deallocate this object. 630 bool destroyMe; 631 632 // Whether an object has just hit the ground 633 bool hitGround; 634 635 bool surfaceHealthSound; 636 637 // Whether we should let this object fall to its DEATH 638 bool fall; 639 float fallTimer; 640 641 float stunTimer; 642 643 int collided; 644 Uint64 shockCollisions; // bit-flags 645 646 float dirAlert; 647 int dirAlertType; 648 649 int respondTo1; 650 int respondTo2; 651 652 float currSurfaceFriction; 653 float currSurfaceHealth; 654 655 int state; 656 }; 657 658 // A static or moving entity (player, enemy, other object) 659 class Entity: public Object 660 { 661 public: Entity()662 Entity() : Object() {} Entity(int typ)663 Entity(int typ) : Object(typ) {} Entity(int typ,float x,float y,float head,int st,bool fix,int rt1,int rt2,int tr,int tt,bool aug)664 Entity(int typ, float x, float y, float head, int st, bool fix, int rt1, int rt2, int tr, int tt, bool aug) : Object(typ, x, y, head, rt1, rt2, tr, tt) { fixed = fix; state = st; if (aug) Augment(); } 665 void reset(); 666 void draw(); 667 void update(); drawShadow()668 void drawShadow() { Object::drawShadow(); } 669 670 void setPlayerAnimations(); 671 selectWeapon(int wp)672 void selectWeapon(int wp) 673 { if (HAS_WEAPON(weapons, wp)) currWeapon = wp; } 674 void selectNextWeapon(); 675 676 void givePowerup(int idx); 677 CurrWeapon()678 int CurrWeapon() { return currWeapon; } Wpn()679 Weapon* Wpn() { return &wpn[currWeapon]; } WeaponPoint()680 Vector2D* WeaponPoint() { return &wpnPos[currWeapon]; } 681 char weaponState(int wp); 682 char keyState(int k); 683 private: 684 int weapons; 685 float grenadeThrowTimer; 686 bool throwGrenade; 687 688 bool jumping; 689 bool jumpReady; 690 691 bool walkSound; 692 693 Weapon wpn[NUM_PLAYER_WEAPONS]; 694 Vector2D wpnPos[NUM_PLAYER_WEAPONS]; 695 int currWeapon; 696 bool switchReady; 697 }; 698 699 // A particle 700 class Particle: public Object 701 { 702 public: Particle()703 Particle() : Object() { color.white(); } Particle(int typ)704 Particle(int typ) : Object(typ) { initType(); } Particle(int typ,float x,float y,float head)705 Particle(int typ, float x, float y, float head) : Object(typ, x, y, head, 0, 0, 0, 0) { initType(); } Particle(int typ,float x,float y,float height,float head)706 Particle(int typ, float x, float y, float height, float head) : Object(typ, x, y, height, head, 0, 0, 0, 0) { initType(); } initType()707 void initType() { pType = type - PART_PARTICLE; color.white(); } 708 void launch(int typ, float x, float y, float height, float head, float alph, int sprite); 709 void launch(int typ, float x, float y, float height, float head, float alph, int sprite, float r, float g, float b); setSpeed(float s)710 void setSpeed(float s) { speed = s; } 711 void reset(); 712 void draw(); 713 void drawShadow(); 714 void update(); 715 void levelCollisionDetection(); 716 protected: 717 int pType; 718 int bounceCount; 719 float rotation; 720 float rotVel; 721 float alpha; 722 float fadeSpeed; 723 float scale; 724 725 float additionalSpeed; 726 727 RGBAColor color; 728 729 Animation anim; 730 731 }; 732 733 // A bullet/projectile 734 class Bullet: public Particle 735 { 736 public: Bullet()737 Bullet() : Particle() {} Bullet(int own,int typ)738 Bullet(int own, int typ) : Particle(typ) { owner = own; bType = type - BLT_RIFLE; } Bullet(int own,int typ,float x,float y,float head)739 Bullet(int own, int typ, float x, float y, float head) : Particle(typ, x, y, head) { owner = own; bType = type - BLT_RIFLE; } Bullet(int own,int typ,float x,float y,float height,float head)740 Bullet(int own, int typ, float x, float y, float height, float head) : Particle(typ, x, y, height, head) { owner = own; bType = type - BLT_RIFLE; } launch(int own,int typ,float x,float y,float height,float head)741 void launch(int own, int typ, float x, float y, float height, float head) 742 { frameDelay = 2; owner = own; bType = typ - BLT_RIFLE; Particle::launch(typ, x, y, height, head, 1.0, 0); } 743 kill(bool death)744 void kill(bool death) { Object::kill(death); } 745 BType()746 int BType() { return bType; } 747 748 void update(); 749 Live()750 bool Live() { return frameDelay == 0; } Owner()751 int Owner() { return owner; } 752 private: 753 int bType; 754 int owner; 755 756 int frameDelay; 757 }; 758 759 class LaserBeam 760 { 761 public: LaserBeam()762 LaserBeam() {} 763 LaserBeam(Vector2D np1, Vector2D np2); 764 765 Vector2D p1, p2; 766 float angle; 767 float length; 768 }; 769 770 // LASER! 771 class Laser 772 { 773 public: Laser()774 Laser() { active = destroyMe = false; live = 0; beams.clear(); } 775 void launch(int typ, float x, float y, float height, float head); 776 void draw(); 777 void update(); Live()778 int Live() { return live; } toBeDestroyed()779 bool toBeDestroyed() { return destroyMe; } Type()780 int Type() { return type; } 781 vector<LaserBeam> beams; 782 private: 783 Wall* wallCollisionDetect(Vector2D pos, float head, float distLeft, Vector2D *inter); 784 785 bool active; 786 int live; 787 bool destroyMe; 788 789 int type; 790 float h; 791 float alpha; 792 }; 793 794 // Array of specification structures for all different types of objects. 795 extern ObjectType objType[NUM_OBJ_TYPES]; 796 extern ParticleType partType[NUM_PART_TYPES]; 797 extern BulletType bltType[NUM_BLT_TYPES]; 798 extern LaserType lasType[NUM_LASER_TYPES]; 799 void initObjectTypes(); 800 801 #endif 802