//-------------------------------------------------------------------
//
//  This code is copyright 2001 by G5 Software.
//  Any unauthorized usage, either in part or in whole of this code
//  is strictly prohibited. Violators WILL be prosecuted to the
//  maximum extent allowed by law.
//
//-------------------------------------------------------------------

class CInteriorMeshObjectPrefix
{
  string GetInteriorMeshObjectId()
  {
    return ConvertIdToInteriorId(Core_GetIdentificator());
  }

  string GetMeshSourceObjectId()
  {
    string ObjectId = Core_GetIdentificator();
    return Core_GetSubString(ObjectId, 1, Core_GetStringLength(ObjectId) - 2);
  }

  bool IsInteriorObjectId(
      string _Id
    )
  {
    return Core_IsStringStartsWith(_Id, "{");
  }

  string ConvertIdToInteriorId(
      string _Id
    )
  {
    return "{" + _Id + "}";
  }
}



class CExplosionGenerator
{
  void GenerateBullets(
      int    _BulletsQty,
      string _BulletType,
      array  _AngleRange,
      float  _Distance,
      array  _TimeRange,
      array  _SpeedRange,
      matrix _Position
    )
  {
    for (int Bullet = 0; Bullet < _BulletsQty; Bullet = Bullet + 1)
    {
      float Alpha = rand(Math_PI);
      float Beta  = rand(_AngleRange[0], _AngleRange[1]);

      vector RandomDirection = _Position * vector(
          sin(Alpha) * cos(Beta),
          cos(Alpha) * cos(Beta),
          sin(Beta)
        );

      Core_ScheduleTask(
          "Bullets",
          OT_CallFunction,
          rand(_TimeRange[0], _TimeRange[1]),
          "CreateBullet",
          _BulletType,
          Core_SetMatrixOrigin(_Position,
            Core_GetMatrixOrigin(_Position) + RandomDirection * _Distance),
          RandomDirection * rand(_SpeedRange[0], _SpeedRange[1])
        );
    }
  }
}



class CUnitLifeControl
  extends CInteriorMeshObjectPrefix, CExplosionGenerator
{
  float  m_DeathPower   = 50.0;
  float  m_MaxHitpoints = 1.0;
  float  m_NowHitpoints = 1.0;
  string m_ExplosionId  = "";
  float  m_DestroyPause = 0.0;
  bool   m_SplashOnHit  = true;
  bool   m_ImmortalMode = false;

  void CUnitLifeControl(
      float  _InitialHP
    )
  {
    m_MaxHitpoints = _InitialHP;
    m_NowHitpoints = _InitialHP;

    SetSpeedThreshold(2.0f);
  }

  void OnObjectLoaded()
  {
    HitpointsWasChanged(m_NowHitpoints);
  }

  void OnToDamage(
      float  _DamageRate,   // damage applied to object
      string _TargetId,     // target object id, "" if none
      string _SourceType,   // source type (explosion type)
      matrix _SourcePlace   // source place
    )
  {
    if (m_ImmortalMode)
      return;

    m_NowHitpoints = m_NowHitpoints - _DamageRate;

    if (m_NowHitpoints <= 0.0)
    {
      m_NowHitpoints = 0.0;
      DetonateObject();
    }

    HitpointsWasChanged(m_NowHitpoints);

    if (_SourceType == "DotExplosion")
    {
      if (m_SplashOnHit)
      {
        GenerateBullets(
            30,
            "BULLETID_BulletHitSplashItem",
            array(Math_HALFPI * 0.5, Math_HALFPI),
            0,
            array(0.0, 0.3),
            array(10.0, 15.0),
            _SourcePlace
          );
      }

      Core_CallFunction(
          "Effects",
          "CreateEffect",
          "EFFECTID_BulletHitObjectEffect",
          _SourcePlace
        );
      Core_CallFunction(
          "Sounds",
          "CreateSound",
          "SOUNDID_BulletHitObjectSound",
          _SourcePlace
        );
    }
  }

  void HitpointsWasChanged(
      float _NowHitpoints
    )
  {
  }

  void CreateDetonateEffects()
  {
  }

  bool m_IsExploded = false;

  void DetonateObject()
  {
    if (m_IsExploded)
      return;
    m_IsExploded = true;

    if ("" != m_ExplosionId)
    {
      Core_CallFunction(
          "Explosions",
          "CreateExplosion",
          m_ExplosionId,
          GetUnitPosition()
        );
    }

    CreateDetonateEffects();
    DestroyComponent();
  }

  void DestroyComponent()
  {
    // Create interior object
    if (0.0 < m_DestroyPause)
    {
      Core_CallFunction(
          SOID_MissionController,
          "CreateComponent",
          GetInteriorMeshObjectId(),
          "InteriorObject",
          "CInteriorMeshObject"
        );
      Core_ScheduleTask(
          SOID_MissionController,
          OT_CallFunction,
          m_DestroyPause,
          "DestroyGameObject",
          GetInteriorMeshObjectId()
        );
    }

    // Destroy object
    Core_PostEventTo(
        SOID_MissionController,
        "DestroyGameObject",
        Core_GetIdentificator()
      );
  }

  void OnCollisionOccured(
      float _fPower
    )
  {
    OnToDamage(
        m_MaxHitpoints * _fPower / m_DeathPower,
        Core_GetIdentificator(),
        "Collision",
        GetUnitPosition()
      );
  }

  void OnUnitStartsMovement()
  {
  }

  void OnUnitStopMovement()
  {
  }
}


class CInteriorMeshObject extends CInteriorMeshObjectPrefix
{
  void CInteriorMeshObject()
  {
    TakeComponentOwnership("Mesh", GetMeshSourceObjectId(), "Mesh");
    SetCompoundObjectPositionable("Mesh");

    Core_RemoveClassificator("Russian");
    Core_RemoveClassificator("German");
    Core_AddClassificator(CLASSIFICATOR_NOTVISIBLEONRADAR);
  }
}


class CMobileGroundUnitStateControl extends CUnitLifeControl
{
  void CMobileGroundUnitStateControl(
      float _InitialHP
    )
  {
    CUnitLifeControl(_InitialHP);
    SetSpeedThreshold(2.0f);
  }

  void OnUnitStartsMovement()
  {
    Core_SendEventTo(Core_GetIdentificator(), "PlayEngineSound");
    Core_SendEventTo(Core_GetIdentificator(), "StartDustGeneration");
  }

  void OnUnitStopMovement()
  {
    Core_SendEventTo(Core_GetIdentificator(), "StopEngineSound");
    Core_SendEventTo(Core_GetIdentificator(), "StopDustGeneration");
  }
}


class CGroundUnitDustGenerator
{
  string DustItemEffect = "EFFECTID_DustEffect";
  float  ItemsPerSecond = 7.5;

  void StartDustGeneration()
  {
    EnableDustGeneration();
  }

  void StopDustGeneration()
  {
    DisableDustGeneration();
  }
}



