334
%{
#include "Entities/StdH/StdH.h"
%}

uses "Entities/EnemyFly";

enum RobotFlyingChar {
  0 RFC_KAMIKAZE   "Kamikaze",
  1 RFC_FIGHTER    "Fighter",
};

%{
static EntityInfo eiRobotFlying = {
  EIBT_ROBOT, 100.0f, // mass[kg]
  0.0f, 0.0f, 0.0f,  // source  
  0.0f, 0.0f, 0.0f,  // target  
};

#define FIRE_POS      FLOAT3D(0.0f, 0.0f, 0.0f)
%}


class CRobotFlying : CEnemyFly {
name      "RobotFlying";
thumbnail "Thumbnails\\RobotFlying.tbn";

properties:
  1 enum RobotFlyingChar m_rfcChar   "Character" 'C' = RFC_FIGHTER,
components:
  0 class   CLASS_BASE        "Classes\\EnemyFly.ecl",

 10 model   MODEL_KAMIKAZE      "Models\\Enemies\\Robots\\FloatKamikaze\\FloatKamikaze.mdl",
 11 texture TEXTURE_KAMIKAZE    "Models\\Enemies\\Robots\\SentryBall\\Ball.tex",

 12 model   MODEL_FIGHTER       "Models\\Enemies\\Robots\\FlyingFighter\\Ship.mdl",
 13 texture TEXTURE_FIGHTER     "Models\\Enemies\\Robots\\FlyingFighter\\Ship.tex",

// ************** SOUNDS **************
 50 sound   SOUND_IDLE      "Models\\Enemies\\Woman\\Sounds\\Idle.wav",
 51 sound   SOUND_SIGHT     "Models\\Enemies\\Woman\\Sounds\\Sight.wav",
 52 sound   SOUND_WOUND     "Models\\Enemies\\Woman\\Sounds\\Wound.wav",
 53 sound   SOUND_FIRE      "Models\\Enemies\\Woman\\Sounds\\Fire.wav",
 54 sound   SOUND_KICK      "Models\\Enemies\\Woman\\Sounds\\Kick.wav",
 55 sound   SOUND_DEATH     "Models\\Enemies\\Woman\\Sounds\\Death.wav",

functions:
  /* Entity info */
  void *GetEntityInfo(void) {
    return &eiRobotFlying;
  };

  /* Receive damage */
  void ReceiveDamage(CEntity *penInflictor, enum DamageType dmtType,
    FLOAT fDamageAmmount, const FLOAT3D &vHitPoint, const FLOAT3D &vDirection) 
  {
    if (!IsOfSameClass(penInflictor, this)) {
      CEnemyFly::ReceiveDamage(penInflictor, dmtType, fDamageAmmount, vHitPoint, vDirection);
    }
  };

  // virtual anim functions
  void StandingAnim(void) {
//    StartModelAnim(WALKER_ANIM_STAND03, AOF_LOOPING|AOF_NORESTART);
  };
  void WalkingAnim(void) {
//    StartModelAnim(WALKER_ANIM_WALK, AOF_LOOPING|AOF_NORESTART);
  };
  void RunningAnim(void) {
//    StartModelAnim(WALKER_ANIM_WALK, AOF_LOOPING|AOF_NORESTART);
  };
  void RotatingAnim(void) {
//    StartModelAnim(WALKER_ANIM_WALK, AOF_LOOPING|AOF_NORESTART);
  };

  // virtual sound functions
  void IdleSound(void) {
    PlaySound(m_soSound, SOUND_IDLE, SOF_3D);
  };
  void SightSound(void) {
    PlaySound(m_soSound, SOUND_SIGHT, SOF_3D);
  };
  void WoundSound(void) {
    PlaySound(m_soSound, SOUND_WOUND, SOF_3D);
  };
  void DeathSound(void) {
    PlaySound(m_soSound, SOUND_DEATH, SOF_3D);
  };


procedures:
/************************************************************
 *                A T T A C K   E N E M Y                   *
 ************************************************************/
  FlyHit(EVoid) : CEnemyFly::FlyHit {
    if (m_rfcChar==RFC_FIGHTER) {
      jump FlyFire();
//      m_fShootTime = _pTimer->CurrentTick() + 1.0f;
//      return EReturn();
    }

    // when close enough
    if (CalcDist(m_penEnemy) <= 3.0f) {
      // explode
      SetHealth(-45.0f);
      ReceiveDamage(NULL, DMT_EXPLOSION, 10.0f, FLOAT3D(0,0,0), FLOAT3D(0,1,0));
      InflictRangeDamage(this, DMT_EXPLOSION, 20.0f, GetPlacement().pl_PositionVector, 
        2.75f, 8.0f);
    }

    // run to enemy
    m_fShootTime = _pTimer->CurrentTick() + 0.1f;
    return EReturn();
  };

  FlyFire(EVoid) : CEnemyFly::FlyFire {
    if (m_rfcChar==RFC_KAMIKAZE) {
      m_fShootTime = _pTimer->CurrentTick() + 1.0f;
      return EReturn();
    }

    ShootProjectile(PRT_CYBORG_LASER, FIRE_POS, ANGLE3D(0, 0, 0));
    PlaySound(m_soSound, SOUND_FIRE, SOF_3D);

    return EReturn();
  };

  Death(EVoid) : CEnemyBase::Death {
    // stop moving
    StopMoving();
    DeathSound();     // death sound

    // set physic flags
    SetPhysicsFlags(EPF_MODEL_CORPSE);
    SetCollisionFlags(ECF_CORPSE);
    // robots don't have different collision boxes, so no need to change
    // robots don't have death animations
    return EEnd();
  };

/************************************************************
 *                       M  A  I  N                         *
 ************************************************************/
  Main(EVoid) {
    // must always be fly-only
    m_EeftType = EFT_FLY_ONLY;

    // declare yourself as a model
    InitAsModel();
    SetPhysicsFlags(EPF_MODEL_WALKING);
    SetCollisionFlags(ECF_MODEL);
    SetFlags(GetFlags()|ENF_ALIVE);
    SetHealth(20.0f);
    m_fMaxHealth = 20.0f;
    en_fDensity = 13000.0f;
    // damage/explode properties
    m_fBlowUpAmount = 0.0f;
    m_fBodyParts = 4;
    m_bRobotBlowup = TRUE;
    m_fDamageWounded = 100000.0f;

    // set your appearance
    switch (m_rfcChar) {
    case RFC_KAMIKAZE: {
      SetModel(MODEL_KAMIKAZE);
      SetModelMainTexture(TEXTURE_KAMIKAZE);
      // fly moving properties
      m_fFlyWalkSpeed = FRnd()/2 + 1.0f;
      m_aFlyWalkRotateSpeed = FRnd()*10.0f + 25.0f;
      m_fFlyAttackRunSpeed = FRnd()*2.0f + 8.0f;
      m_aFlyAttackRotateSpeed = FRnd()*25 + 150.0f;
      m_fFlyCloseRunSpeed = FRnd()*2.0f + 6.0f;
      m_aFlyCloseRotateSpeed = FRnd()*50 + 500.0f;
      // attack properties - CAN BE SET
      m_fFlyAttackDistance = 50.0f;
      m_fFlyCloseDistance = 12.5f;
      m_fFlyStopDistance = 0.0f;
      m_fFlyAttackFireTime = 2.0f;
      m_fFlyCloseFireTime = 0.1f;
      m_fFlyIgnoreRange = 200.0f;
      m_fFlyHeight = 1.0f;
      m_iScore = 1000;
          } break;
    case RFC_FIGHTER: {
      SetModel(MODEL_FIGHTER);
      SetModelMainTexture(TEXTURE_FIGHTER);
      // fly moving properties
      m_fFlyWalkSpeed = FRnd()/2 + 1.0f;
      m_aFlyWalkRotateSpeed = FRnd()*10.0f + 25.0f;
      m_fFlyAttackRunSpeed = FRnd()*2.0f + 7.0f;
      m_aFlyAttackRotateSpeed = FRnd()*25 + 150.0f;
      m_fFlyCloseRunSpeed = FRnd()*2.0f + 20.0f;
      m_aFlyCloseRotateSpeed = 150.0f;//FRnd()*50 + 0.0f;
      // attack properties - CAN BE SET
      m_fFlyAttackDistance = 50.0f;
      m_fFlyCloseDistance = 10.0f;
      m_fFlyStopDistance = 0.1f;
      m_fFlyAttackFireTime = 3.0f;
      m_fFlyCloseFireTime = 0.2f;
      m_fFlyIgnoreRange = 200.0f;
      m_fFlyHeight = 2.5f;
          } break;
    default: ASSERT(FALSE);
    }

    // continue behavior in base class
    jump CEnemyFly::MainLoop();
  };
};
