void LargeSlimeEntity::dying()
{
  isDying = true;
  game().addKilledEnemy(enemyType, hurtingType);
  if (slimeType == SlimeTypeBlue) game().addCorpse(x, y, FRAME_CORPSE_GIANT_SLIME_BLUE);
  else if (slimeType == SlimeTypeRed) game().addCorpse(x, y, FRAME_CORPSE_GIANT_SLIME_RED);
  else if (slimeType == SlimeTypeStandard) game().addCorpse(x, y, FRAME_CORPSE_GIANT_SLIME);

  float xSlime = x;
  float ySlime = y;

  if (x <= 1.5 * TILE_WIDTH) x = 1.5f * TILE_WIDTH + 2;
  else if (x >= TILE_WIDTH * MAP_WIDTH - 1.5f * TILE_WIDTH) x = TILE_WIDTH * MAP_WIDTH - 1.5f * TILE_WIDTH -3;
  if (y <= 1.5 * TILE_HEIGHT) y = 1.5 * TILE_HEIGHT + 2;
  else if (y >= TILE_HEIGHT * MAP_HEIGHT - 1.5f * TILE_HEIGHT) y = TILE_HEIGHT * MAP_HEIGHT - 1.5f * TILE_HEIGHT -3;

  for (int i = 0; i < 9; i++)
  {
    game().generateBlood(xSlime, ySlime, bloodColor);
    if (i % 2 == 0)
    {
      switch (slimeType)
      {
        case SlimeTypeBlue: new SlimeEntity(x, y, SlimeTypeBlue, true); break;
        case SlimeTypeRed: new SlimeEntity(x, y, SlimeTypeRed, true); break;
        case SlimeTypeViolet: new SlimeEntity(x, y, SlimeTypeViolet, true); break;
        default: new SlimeEntity(x, y, SlimeTypeStandard, true); break;
      }
    }
  }

  game().makeShake(1.0f);
  SoundManager::getInstance().playSound(SOUND_SLIME_SMASH);

  ItemEntity* newItem = new ItemEntity(ItemSilverCoin, x, y);
  newItem->setVelocity(Vector2D(100.0f + rand()% 250));
  newItem->setViscosity(0.96f);

  SpriteEntity* star = new SpriteEntity(ImageManager::getInstance().getImage(IMAGE_GIANT_SLIME), x, y, 128, 128, 8);
  star->setFrame(4);
  star->setFading(true);
  star->setZ(y+ 100);
  star->setAge(-0.4f);
  star->setLifetime(0.3f);
  star->setType(ENTITY_EFFECT);
  star->setSpin(400.0f);
}
void SlimePetEntity::fall()
{
    SpriteEntity* spriteEntity
        = new SpriteEntity(ImageManager::getInstance().getImage(IMAGE_SLIME),
                           x,
                           y + 6,
                           64, 64, 4);
    spriteEntity->setAge(0.0f);
    spriteEntity->setLifetime(3.0f);
    spriteEntity->setShrinking(true);
    spriteEntity->setFading(true);
    spriteEntity->setFrame(16);

    isDying = true;

    SlimePetEntity* newSlime = new SlimePetEntity();
    newSlime->setAge(-4.0f);
}
void GiantSlimeEntity::dying()
{
  isDying = true;
  game().addKilledEnemy(enemyType, hurtingType);
  game().addCorpse(x, y, FRAME_CORPSE_GIANT_SLIME);

  float xSlime = x;
  float ySlime = y;

  if (x <= 1.5 * TILE_WIDTH) x = 1.5f * TILE_WIDTH + 2;
  else if (x >= TILE_WIDTH * MAP_WIDTH - 1.5f * TILE_WIDTH) x = TILE_WIDTH * MAP_WIDTH - 1.5f * TILE_WIDTH -3;
  if (y <= 1.5 * TILE_HEIGHT) y = 1.5 * TILE_HEIGHT + 2;
  else if (y >= TILE_HEIGHT * MAP_HEIGHT - 1.5f * TILE_HEIGHT) y = TILE_HEIGHT * MAP_HEIGHT - 1.5f * TILE_HEIGHT -3;

  for (int i = 0; i < 9; i++)
  {
    game().generateBlood(xSlime, ySlime, bloodColor);
    SlimeEntity* slime = new SlimeEntity(x, y, SlimeTypeStandard, true);
    slime->disableCollidingTemporary();
  }

  game().makeShake(1.0f);
  SoundManager::getInstance().playSound(SOUND_SLIME_SMASH);

  ItemEntity* newItem = new ItemEntity(ItemBossHeart, x, y);
  newItem->setVelocity(Vector2D(100.0f + rand()% 250));
  newItem->setViscosity(0.96f);

  SpriteEntity* star = new SpriteEntity(ImageManager::getInstance().getImage(IMAGE_GIANT_SLIME), x, y, 128, 128, 8);
  star->setFrame(4);
  star->setFading(true);
  star->setZ(y+ 100);
  star->setAge(-0.4f);
  star->setLifetime(0.3f);
  star->setType(ENTITY_EFFECT);
  star->setSpin(400.0f);
}
void JoustTileMapEntity::generateFallingTiles()
{
    for (int i = 0; i < gameMap->getWidth(); i++)
        for (int j = 0; j < gameMap->getHeight(); j++)
        {
            int tile = ((JoustGameMap*)gameMap)->getDifferenceTile(i, j);
            if (tile != 0)
            {
                SpriteEntity* fallingBlock  = new SpriteEntity( image,
                                                                (float)(OFFSET_X + tileWidth * i + tileWidth / 2),
                                                                (float)(OFFSET_Y + tileHeight * j + tileHeight / 2),
                                                                tileWidth,
                                                                tileHeight,
                                                                tilesProLine);
                fallingBlock->setFrame(tile);
                fallingBlock->setLifetime(1.0f);
                fallingBlock->setFading(true);
                fallingBlock->setWeight(30.0f);
                fallingBlock->setSpin(-50.0f + 100.0f * (float)rand() / (float)RAND_MAX);
            }
        }

    ((JoustGameMap*)gameMap)->initDifferenceMap();
}
void CauldronEntity::animate(float delay)
{
  if (isAgonising)
  {
    agonizingDelay -= delay;
    if (agonizingDelay <= 0.0f)
    {
      isDying = true;
      game().addCorpse(x, y, deathFrame);
    }
  }
  else
  {
    SoundManager::getInstance().playSound(SOUND_CAULDRON, false);

    invokeDelay -= delay;
    if (invokeDelay < 0.0f)
    {
      if (cauldronType == CauldronTypeElemental)
      {
        if (game().getEnemyCount() < 9)
        {
          slimeTypeEnum slimeType = SlimeTypeStandard;
          switch (colorState)
          {
            case 0: slimeType = SlimeTypeBlue; break;
            case 1: slimeType = SlimeTypeRed; break;
            case 2: slimeType = SlimeTypeStandard; break;
          }
          SlimeEntity* slime = new SlimeEntity(x, y, slimeType, true);
          slime->disableCollidingTemporary();
          invokeDelay = 3.75f + (float)(rand() % 3000) / 1000.0f;
        }
      }
      else
      {
        SlimeEntity* slime = new SlimeEntity(x, y, SlimeTypeViolet, true);
        slime->disableCollidingTemporary();
        invokeDelay = 1.5f + (float)(rand() % 2500) / 1000.0f;
      }
    }

    if (cauldronType == CauldronTypeElemental)
    {
      colorChangeDelay -= delay;
      if (colorChangeDelay < 0.0f)
      {
        colorChangeDelay = 4.0f + rand()% 50 * 0.1f;
        if (rand() % 2 == 0)
        {
          colorState++;
          if (colorState > 2) colorState = 0;
        }
        else
        {
          colorState--;
          if (colorState < 0) colorState = 2;
        }
      }
    }

    bubbleDelay -= delay;
    if (bubbleDelay < 0.0f)
    {
      bubbleDelay = 0.3f;
      int bubbleFrame = 32;
      if (cauldronType == CauldronTypeElemental)
      {
        switch (colorState)
        {
          case 0: bubbleFrame = 33; break;
          case 1: bubbleFrame = 34; break;
          case 2: bubbleFrame = 35; break;
        }
      }

      for (int i=0; i < 2; i++)
      {
        float xBub = x - 16 + rand() % 32;
        SpriteEntity* bubble = new SpriteEntity(ImageManager::getInstance().getImage(IMAGE_CAULDRON), xBub, y - 20, 8, 8);
        bubble->setZ(z);
        bubble->setFrame(bubbleFrame);
        bubble->setType(ENTITY_EFFECT);
        bubble->setWeight(-20 - rand() % 40);
        bubble->setLifetime(2.0f);
        float bloodScale = 0.3f + (rand() % 20) * 0.1f;
        bubble->setScale(bloodScale, bloodScale);
      }
    }
    frame = hp > hpMax / 2 ? 0 : 1;
    if (cauldronType == CauldronTypeElemental)
    {
      switch (colorState)
      {
        case 0: frame += 2; break;
        case 1: frame += 4; break;
        case 2: frame += 6; break;
      }
    }

    EnemyEntity::animate(delay);
  }
}