1 /* 2 Copyright (C) 2007, 2010 - Bit-Blot 3 4 This file is part of Aquaria. 5 6 Aquaria is free software; you can redistribute it and/or 7 modify it under the terms of the GNU General Public License 8 as published by the Free Software Foundation; either version 2 9 of the License, or (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 14 15 See the GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 */ 21 #ifndef ENTITY_H 22 #define ENTITY_H 23 24 #include "../BBGE/StateMachine.h" 25 #include "../BBGE/SkeletalSprite.h" 26 #include "../BBGE/ScriptObject.h" 27 28 #include "DSQ.h" 29 #include "Path.h" 30 #include "Hair.h" 31 #include "TileVector.h" 32 33 #include "tinyxml2.h" 34 using namespace tinyxml2; 35 36 class ManaBall; 37 class Path; 38 39 struct BoneLock 40 { BoneLockBoneLock41 BoneLock() : entity(0), bone(0), on(false), origRot(0) {} 42 Entity *entity; 43 Bone *bone; 44 Vector localOffset; 45 bool on; 46 float origRot; 47 Vector wallNormal, circleOffset; 48 int collisionMaskIndex; 49 }; 50 51 enum EV 52 { 53 EV_WALLOUT = 0, 54 EV_WALLTRANS = 1, 55 EV_CLAMPING = 2, 56 EV_SWITCHCLAMP = 3, 57 EV_CLAMPTRANSF = 4, 58 EV_MOVEMENT = 5, 59 EV_COLLIDE = 6, 60 EV_TOUCHDMG = 7, 61 EV_FRICTION = 8, 62 EV_LOOKAT = 9, 63 EV_CRAWLING = 10, 64 EV_ENTITYDIED = 11, 65 EV_TYPEID = 12, 66 EV_COLLIDELEVEL = 13, 67 EV_BONELOCKED = 14, 68 EV_FLIPTOPATH = 15, 69 EV_NOINPUTNOVEL = 16, 70 EV_VINEPUSH = 17, 71 EV_BEASTBURST = 18, // if 1: will not collide with beast on touchAvatarDamage, if 0: will 72 EV_MINIMAP = 19, // should the entity show up on the minimap? 73 EV_SOULSCREAMRADIUS = 20, // 0-n: size of radius for naija's dual form scream attack, -1: always hit 74 EV_WEBSLOW = 21, // 100 by default, multiplied by dt and then divided into vel 75 EV_NOAVOID = 22, // if 1: doEntityAvoidance() will ignore this entity 76 EV_MAX = 23 77 }; 78 79 enum DamageType 80 { 81 DT_NONE = -1, 82 DT_ENEMY = 0, 83 DT_ENEMY_ENERGYBLAST = 1, 84 DT_ENEMY_SHOCK = 2, 85 DT_ENEMY_BITE = 3, 86 DT_ENEMY_TRAP = 4, 87 DT_ENEMY_WEB = 5, 88 DT_ENEMY_BEAM = 6, 89 DT_ENEMY_GAS = 7, 90 DT_ENEMY_INK = 8, 91 DT_ENEMY_POISON = 9, 92 DT_ENEMY_ACTIVEPOISON = 10, 93 DT_ENEMY_CREATOR = 11, 94 DT_ENEMY_MANTISBOMB = 12, 95 DT_ENEMY_REALMAX , 96 DT_ENEMY_MAX = 13, 97 98 DT_AVATAR = 1000, 99 DT_AVATAR_ENERGYBLAST = 1001, 100 DT_AVATAR_SHOCK = 1002, 101 DT_AVATAR_BITE = 1003, 102 DT_AVATAR_VOMIT = 1004, 103 DT_AVATAR_ACID = 1005, 104 DT_AVATAR_SPORECHILD = 1006, 105 DT_AVATAR_LIZAP = 1007, 106 DT_AVATAR_NATURE = 1008, 107 DT_AVATAR_ENERGYROLL = 1009, 108 DT_AVATAR_VINE = 1010, 109 DT_AVATAR_EAT = 1011, 110 DT_AVATAR_EAT_BASICSHOT = 1011, 111 DT_AVATAR_EAT_MAX = 1012, 112 DT_AVATAR_LANCEATTACH = 1013, 113 DT_AVATAR_LANCE = 1014, 114 DT_AVATAR_CREATORSHOT = 1015, 115 DT_AVATAR_DUALFORMLI = 1016, 116 DT_AVATAR_DUALFORMNAIJA = 1017, 117 DT_AVATAR_BUBBLE = 1018, 118 DT_AVATAR_SEED = 1019, 119 DT_AVATAR_PET = 1020, 120 DT_AVATAR_PETNAUTILUS = 1021, 121 DT_AVATAR_PETBITE = 1022, 122 DT_AVATAR_REALMAX , 123 DT_AVATAR_MAX = 1030, 124 DT_TOUCH = 1031, 125 DT_CRUSH = 1032, 126 DT_SPIKES = 1033, 127 DT_STEAM = 1034, 128 DT_WALLHURT = 1035, 129 DT_REALMAX 130 }; 131 132 enum EatType 133 { 134 EAT_NONE = -1, 135 EAT_DEFAULT = 0, 136 EAT_FILE = 1, 137 EAT_MAX 138 }; 139 140 enum ObsCheck 141 { 142 OBSCHECK_RANGE = 0, 143 OBSCHECK_4DIR = 1, 144 OBSCHECK_DOWN = 2, 145 OBSCHECK_8DIR = 3 146 }; 147 148 class Shot; 149 150 struct DamageData 151 { DamageDataDamageData152 DamageData() 153 { 154 damage = 0; 155 attacker = 0; 156 bone = 0; 157 damageType = DT_TOUCH; 158 form = (FormType)0; 159 shot = 0; 160 effectTime = 0; 161 useTimer = true; 162 } 163 FormType form; 164 DamageType damageType; 165 Entity *attacker; 166 Bone *bone; 167 float damage; 168 Vector hitPos; 169 Shot *shot; 170 float effectTime; 171 bool useTimer; 172 }; 173 174 enum EntityType 175 { 176 ET_NOTYPE =-1, 177 ET_AVATAR =0, 178 ET_ENEMY =1, 179 ET_PET =2, 180 ET_FLOCK =3, 181 ET_NEUTRAL =4, 182 ET_INGREDIENT =5 183 }; 184 185 enum EntityProperty 186 { 187 EP_SOLID =0, 188 EP_MOVABLE =1, 189 EP_BATTERY =2, 190 EP_BLOCKER =3, 191 EP_MAX =4 192 }; 193 194 enum BounceType 195 { 196 BOUNCE_NONE = -1, 197 BOUNCE_SIMPLE = 0, 198 BOUNCE_REAL = 1 199 }; 200 201 class Entity : public Quad, public StateMachine, public SoundHolder 202 { 203 public: 204 Entity(); init()205 virtual void init(){} postInit()206 virtual void postInit(){} 207 208 Vector lastPosition; 209 // postInit gets called after the entity IDs are determined 210 int entityTypeIdx; 211 enum ActivationType 212 { 213 ACT_NONE = -1, 214 ACT_CLICK = 0, 215 ACT_RANGE = 1 216 }; 217 void destroy(); 218 //void damage(int amount, Spell *spell=0, Entity *attacker=0); isEntityDead()219 bool isEntityDead() const {return entityDead;} 220 std::string name; 221 Vector vel; 222 InterpolatedVector vel2; 223 float activationRadius; 224 void render(); 225 void update(float dt); 226 227 void spawnParticlesFromCollisionMask(const std::string &p, int intv=1); 228 229 float health; 230 float maxHealth; 231 232 bool setBoneLock(const BoneLock &boneLock); 233 234 void heal(float a, int type=0); 235 236 void push(const Vector &vec, float time, float maxSpeed, float dmg); 237 238 bool canSetState(int state); 239 message(const std::string & msg,int v)240 virtual void message(const std::string &msg, int v) {} messageVariadic(lua_State * L,int nparams)241 virtual int messageVariadic(lua_State *L, int nparams) { return 0; } 242 243 bool isUnderWater(const Vector &o=Vector()); 244 245 //virtual void onHitBySpell(Spell *spell) {} 246 //virtual void onCollide(Entity *e); 247 248 virtual bool damage(const DamageData &d); canShotHit(const DamageData & d)249 virtual bool canShotHit(const DamageData &d) { return true; } 250 251 virtual void songNote(int note); 252 virtual void songNoteDone(int note, float len); lightFlare()253 virtual void lightFlare(){} sporesDropped(const Vector & pos,int type)254 virtual void sporesDropped(const Vector &pos, int type) {} 255 256 bool isPullable(); 257 258 bool isInDarkness(); 259 isPresent()260 bool isPresent() const 261 { 262 return !isDead() && !isEntityDead() && life == 1 && alpha.x != 0; 263 } 264 265 void frozenUpdate(float dt); 266 void rotateToSurfaceNormal(float t, int n=0, int rot=0); 267 268 ActivationType activationType; 269 float activationRange; 270 Entity *followEntity; 271 Entity *ridingOnEntity; 272 bool canBeTargetedByAvatar; saveExtraData(XMLElement * xml)273 virtual void saveExtraData(XMLElement *xml){} loadExtraData(XMLElement * xml)274 virtual void loadExtraData(XMLElement *xml){} 275 Vector startPos; 276 void getEXP(unsigned int exp); 277 void rotateToVec(Vector addVec, float time, float offsetAngle=0); applyVariation(int variation)278 virtual void applyVariation(int variation){} 279 280 void popBubble(); 281 void sound(const std::string &sound, float freq=1, float fadeOut=0); setStopSoundsOnDeath(bool stop)282 void setStopSoundsOnDeath(bool stop) { stopSoundsOnDeath = stop; } 283 284 void freeze(float time); 285 onSceneFlipped()286 virtual void onSceneFlipped() {} 287 288 bool isNearObstruction(int sz, int type=0, TileVector *hitTile=0); 289 290 enum 291 { 292 // MAIN STATES 293 STATE_DEAD =0, 294 STATE_IDLE =1, 295 STATE_PUSH =2, 296 STATE_PUSHDELAY =3, 297 STATE_PLANTED =4, 298 STATE_TRANSFORM =5, 299 STATE_PULLED =6, 300 STATE_FOLLOWNAIJA =7, 301 STATE_DEATHSCENE =8, 302 STATE_ATTACK =9, 303 STATE_CHARGE0 =10, 304 STATE_CHARGE1 =11, 305 STATE_CHARGE2 =12, 306 STATE_CHARGE3 =13, 307 STATE_WAIT =20, 308 STATE_HUG =21, 309 STATE_EATING =22, 310 STATE_FOLLOW =23, 311 STATE_TITLE =24 312 }; onNotify(Entity * notify)313 virtual void onNotify(Entity *notify){} 314 //void followPath(Path *p, int spd, int loop, bool deleteOnEnd = false); 315 float followPath(Path *p, float speed, int dir, bool deleteOnEnd = false); 316 Entity *attachedTo; 317 bool touchAvatarDamage(int radius, float dmg, const Vector &override=Vector(-1,-1,-1), float speed=0, float pushTime = 0, Vector collidePos = Vector(0,0,0)); 318 319 void moveTowards(Vector p, float dt, int spd); 320 void moveAround(Vector p, float dt, int spd, int d); 321 322 void moveTowardsAngle(int angle, float dt, int spd); 323 void moveAroundAngle(int angle, float dt, int spd, int dir); 324 325 void moveTowardsTarget(float dt, int spd, int t=0); 326 void moveAroundTarget(float dt, int spd, int d, int t=0); 327 void moveAroundEntity(float dt, int spd, int d, Entity *e); 328 void moveTowardsGroupCenter(float dt, int spd); 329 void moveTowardsGroupHeading(float dt, int spd); 330 bool doCollisionAvoidance(float dt, int search, float mod, Vector *v = 0, float overrideMaxSpeed=0, int ignoreObs=0, bool onlyVP=false); 331 void doSpellAvoidance(float dt, int range, float mod); 332 void doEntityAvoidance(float dt, int range, float mod, Entity *ignore =0); 333 void setMaxSpeed(float ms); 334 Entity *findTarget(int dist, int type, int t=0); 335 //bool hasTarget() { return target != 0; } 336 bool hasTarget(int t=0); 337 bool isTargetInRange(int range, int t=0); 338 void doGlint(const Vector &position, const Vector &scale=Vector(2,2), const std::string &tex="Glint", RenderObject::BlendTypes bt=BLEND_DEFAULT); 339 Entity *getTargetEntity(int t=0); 340 void setTargetEntity(Entity *e, int t=0); 341 342 void attachEntity(Entity *e, Vector offset); 343 void detachEntity(Entity *e); activate()344 virtual void activate(){} 345 346 SkeletalSprite skeletalSprite; 347 348 void setEntityType(EntityType et); 349 EntityType getEntityType(); 350 void flipToTarget(Vector pos); 351 bool isFollowingPath(); 352 void stopFollowingPath(); 353 void overideMaxSpeed(int ms, float time); 354 void disableOverideMaxSpeed(); 355 int currentEntityTarget; 356 float moveToPos(Vector pos, float speed, int dieOnPathEnd=0, bool swim = false); 357 bool isHit(); 358 bool pathBurst(bool wallJump = false); 359 Timer burstTimer; 360 void revive(float a); 361 void setName(const std::string &name); 362 void doFriction(float dt); 363 void doFriction(float dt, float len); 364 isNormalLayer()365 bool isNormalLayer() const 366 { 367 return layer == LR_ENTITIES || layer == LR_ENTITIES0 || layer == LR_ENTITIES2 || layer == LR_ENTITIES_MINUS2 || layer == LR_ENTITIES_MINUS3; 368 } 369 void watchEntity(Entity *e); 370 void idle(); 371 int followPos; 372 void slowToStopPath(float t); 373 bool isSlowingToStopPath(); 374 Vector lastMove; 375 float damageTime; 376 377 void setEntityProperty(EntityProperty ep, bool value=true); 378 bool isEntityProperty(EntityProperty ep); song(SongType songType)379 virtual void song(SongType songType){} 380 bool updateCurrents(float dt); 381 void updateVel2(float dt, bool override=false); 382 bool isAvatarAttackTarget(); 383 int dropChance; 384 void fillGrid(); 385 bool fillGridFromQuad; 386 387 void setID(int id); 388 int getID(); 389 startPull()390 virtual void startPull() {} 391 virtual void stopPull(); 392 393 bool isInvincible(); 394 395 InterpolatedVector maxSpeedLerp; 396 Hair *hair; 397 398 void assignUniqueID(); 399 int entityID; 400 int getMaxSpeed(); 401 std::string deathSound; 402 virtual std::string getIdleAnimName(); 403 404 void clearDamageTargets(); 405 void setAllDamageTargets(bool v); 406 void setDamageTarget(DamageType dt, bool v); 407 bool isDamageTarget(DamageType dt); 408 409 typedef std::set<DamageType> DisabledDamageTypes; 410 411 int targetRange; getTargetRange()412 int getTargetRange() { return targetRange; } 413 414 Vector getEnergyShotTargetPosition(); 415 int getRandomTargetPoint(); 416 417 Vector ridingOnEntityOffset; 418 void moveOutOfWall(); 419 bool isSittingOnInvisibleIn(); 420 /* 421 void setCrawling(bool on) { crawling = on; } 422 bool isCrawling() { return crawling; } 423 */ 424 void flipToVel(); isInCurrent()425 bool isInCurrent() { return inCurrent; } 426 void clearTargetPoints(); 427 void addTargetPoint(const Vector &point); 428 int getNumTargetPoints(); 429 Vector getTargetPoint(int i); 430 int targetPriority; shiftWorlds(WorldType lastWorld,WorldType worldType)431 virtual void shiftWorlds(WorldType lastWorld, WorldType worldType){} 432 void setCanLeaveWater(bool v); 433 void setSpiritFreeze(bool v); 434 void setPauseFreeze(bool v); 435 void setEatType(EatType et, const std::string &file=""); getEatType()436 EatType getEatType() { return eatType; } 437 void setRiding(Entity *e); 438 Entity *getRiding(); 439 440 void setBounceType(BounceType bt); 441 BounceType getBounceType(); setDieTimer(float v)442 void setDieTimer(float v) { dieTimer = v; } 443 float getHealthPerc(); 444 void setDeathScene(bool v); isDeathScene()445 bool isDeathScene() const { return deathScene; } 446 void generateCollisionMask(int ovrCollideRadius=0); 447 DamageData lastDamage; 448 bool checkSplash(const Vector &override=Vector(0,0,0)); 449 EatData eatData; 450 InterpolatedVector flipScale; 451 bool beautyFlip; 452 void attachLance(); 453 void setInvincible(bool inv); 454 void clampToHit(); 455 bool updateLocalWarpAreas(bool affectAvatar); 456 virtual void entityDied(Entity *e); 457 //bool registerEntityDied; 458 bool clampToSurface(int tcheck=0, Vector usePos=Vector(0,0), TileVector hitTile=TileVector(0,0)); 459 bool checkSurface(int tcheck, int state, float statet); 460 //static Shader blurShader; 461 std::string naijaReaction; 462 Vector lookAtPoint; 463 Vector getLookAtPoint(); 464 465 void setv(EV ev, int v); 466 void setvf(EV ev, float v); 467 int getv(EV ev); 468 float getvf(EV ev); 469 bool isv(EV ev, int v); 470 void setIngredientData(const std::string &name); 471 472 void postUpdate(float dt); getBoneLock()473 BoneLock* getBoneLock() { return &boneLock; } 474 475 virtual void shotHitEntity(Entity *hit, Shot *shot, Bone *b); 476 477 void warpLastPosition(); 478 void addIgnoreShotDamageType(DamageType dt); 479 480 Vector getRidingPosition(); 481 void setRidingPosition(const Vector &pos); 482 void setRidingRotation(float rot); 483 float getRidingRotation(); 484 void setRidingFlip(bool on); 485 bool getRidingFlip(); 486 void setRidingData(const Vector &pos, float rot, bool fh); 487 bool isGoingToBeEaten(); 488 void setPoison(float m, float t); getPoison()489 inline float getPoison() const { return poison; } 490 491 virtual bool canSetBoneLock(); 492 493 void initHair(int numSegments, float segmentLength, float width, const std::string &tex); 494 void updateHair(float dt); 495 void setHairHeadPosition(const Vector &pos); 496 void exertHairForce(const Vector &force, float dt); 497 498 bool isEntityInside(); 499 500 void updateSoundPosition(); 501 getPushVec()502 Vector getPushVec() const { return pushVec; } getPushDamage()503 float getPushDamage() const { return pushDamage; } 504 505 protected: 506 bool calledEntityDied; 507 Path *waterBubble; 508 bool ridingFlip; 509 Vector ridingPosition; 510 float ridingRotation; 511 512 std::vector<DamageType> ignoreShotDamageTypes; 513 Timer vineDamageTimer; 514 float boneLockDelay; onSetBoneLock()515 virtual void onSetBoneLock(){} onUpdateBoneLock()516 virtual void onUpdateBoneLock(){} 517 BoneLock boneLock; onDieNormal()518 virtual void onDieNormal() {} onDieEaten()519 virtual void onDieEaten() {} 520 IngredientData *ingredientData; 521 int vs[EV_MAX]; 522 void onEndOfLife(); 523 524 bool invincible; 525 PauseQuad *lanceGfx; 526 float lanceTimer; 527 float lanceDelay; 528 int lance; 529 Bone *lanceBone; 530 void updateLance(float dt); 531 //InterpolatedVector blurShaderAnim; 532 533 534 int fhScale, fvScale; 535 void onFHScale(); 536 void onFH(); 537 bool deathScene; 538 float dieTimer; 539 BounceType bounceType; 540 Entity* riding; 541 EatType eatType; 542 bool stickToNaijasHead; 543 544 bool spiritFreeze; 545 bool pauseFreeze; 546 bool canLeaveWater; 547 bool wasUnderWater; 548 549 std::vector<Vector>targetPoints; 550 551 Vector getMoveVel(); 552 DisabledDamageTypes disabledDamageTypes; 553 //bool crawling; 554 555 //Vector backupPos, backupVel; onIdle()556 virtual void onIdle() {} onHeal(int type)557 virtual void onHeal(int type){} onDamage(DamageData & d)558 virtual void onDamage(DamageData &d){} onHealthChange(float change)559 virtual void onHealthChange(float change){} 560 bool inCurrent; 561 std::vector<bool> entityProperties; 562 float slowingToStopPathTimer, slowingToStopPath; 563 564 void movementDetails(Vector v); 565 Entity *watchingEntity; 566 virtual void onPathEnd(); 567 bool swimPath; 568 bool deleteOnPathEnd; 569 InterpolatedVector multColor; 570 EntityType entityType; 571 std::vector<Entity*> attachedEntities; 572 std::vector<Vector> attachedEntitiesOffsets; 573 onFreeze()574 virtual void onFreeze(){} 575 576 //Entity *target; 577 std::vector<Entity*>targets; onAlwaysUpdate(float dt)578 virtual void onAlwaysUpdate(float dt){} onUpdateFrozen(float dt)579 virtual void onUpdateFrozen(float dt){} 580 float frozenTimer; 581 Quad *bubble; 582 583 void doDeathEffects(float manaBallEnergy=0, bool die=true); 584 585 void onEnterState(int action); 586 void onExitState(int action); 587 //virtual bool onDamage(int amount, Spell *spell, Entity *attacker); 588 bool invincibleBreak; 589 590 bool entityDead; 591 void onUpdate(float dt); 592 593 Vector pushVec; 594 float pushDamage; 595 596 597 598 Timer damageTimer; 599 600 void updateBoneLock(); 601 602 float pushMaxSpeed; 603 std::string currentAnim; 604 605 606 protected: 607 608 Timer poisonTimer, poisonBitTimer; 609 float poison; 610 private: 611 612 613 float maxSpeed; 614 615 bool stopSoundsOnDeath; 616 617 }; 618 619 #endif 620