/**
   * Spawns a generic sprite animation (see note for particular case)
   *
   * @param typeSprite
   * @param x
   * @param y
   * @param floor floor to spark the animation
   * @param misc money value (just for GOLDCOIN)
   * @param miscPerso perso dying (just for DEATH)
   * @param desc
   * @return Spawned {@link Element} Note: Can return NULL (example: ask for a blue drop, but hero
   *     hasn't necklace ==> nothing spawned)
   */
  public Element spawnSpriteGeneric(
      SpriteAnimation typeSprite,
      int x,
      int y,
      int floor,
      int misc,
      Perso miscPerso,
      ElementDescription desc) {
    Element element = null;
    Element element2 = null;
    ElementDescription elemDesc = null;
    int j;

    switch (typeSprite) {
      case CHIMNEY_SMOKE:
        elemDesc = ElementDescription.SMOKE_SMALL;
        element = new ElementSmoke(x, y);
        element.setZ(6.0f);
        element.setVx(0.2f + 0.1f * (float) Math.random());
        element.setVy(0.0f);
        element.setVz(0.0f);
        element.setAx(-0.01f);
        element.setAy(0.0f);
        element.setAz(0.01f); // + rnd()*0.005f);

        element.setSprModel(elemDesc);

        element.setScrX((int) element.x);
        element.setScrY((int) element.y);

        element.setForeground(true);
        break;

      case BUSHES:
        for (j = 0; j < 8; j++) {
          Element e = new Element();
          e.setX((float) (x + Math.random() * 10 - 5));
          e.setY((float) (y + Math.random() * 6 - 2));
          e.setZ((float) (7 + Math.random() * 10));
          e.setVx(0.2f * (j - 1));
          e.setVz((float) (-0.5f + Math.random() * 3 * 0.1f));
          e.setAx(-0.05f * e.getVx());
          if (misc == 1) {
            e.setNSpr(ElementDescription.NETTLE_LEAF.ordinal());
          } else {
            e.setNSpr(ElementDescription.LEAF_GREEN.ordinal());
          }
          if ((j % 2) == 0) {
            e.reverse = Reverse.HORIZONTAL;
          }
          spawnSprite(e);
          // Peut-ĂȘtre qu'un diamant va apparaitre !
        }
        break;

      case GOLDCOIN:
      case ARROW:
      case FROMGROUND:
        // Diamond, arrows, everything coming from ground
        // First of all : check if this is a right place (no collision, and no lava)
        if (EngineZildo.mapManagement.collide(x, y, miscPerso)) {
          break;
        }
        element = new ElementGoodies();
        element.setX(x);
        element.setY(y);
        element.setZ(4.0f);
        element.setVz(1.5f);
        element.setAz(-0.1f);
        ElementDescription shadow = ElementDescription.SHADOW_MINUS;
        if (typeSprite == SpriteAnimation.GOLDCOIN) {
          switch (misc) {
            case 0:
              element.setDesc(ElementDescription.GOLDCOIN1);
              break;
            case 1:
              element.setDesc(ElementDescription.THREEGOLDCOINS1);
              shadow = ElementDescription.SHADOW;
              break;
            default:
              element.setDesc(ElementDescription.GOLDPURSE1);
              break;
          }
        } else if (typeSprite == SpriteAnimation.FROMGROUND) {
          element.setSprModel(desc);
        } else {
          element.setSprModel(ElementDescription.ARROW_UP);
          element.setY(y - 3);
        }
        // Ombre
        element2 = new Element();
        element2.setX(x);
        element2.setY(y - 2);
        element2.setSprModel(shadow);
        element2.floor = floor;
        spawnSprite(element2);
        element.setLinkedPerso(element2);
        break;

      case BLUE_DROP:
        if (EngineZildo.scriptManagement.isBlueDropDisplayable()) {
          element = new ElementGoodies();
          element.setX(x - 1);
          element.setY(y);
          if (misc == 1) { // Heart should be on the ground
            element.setX(x - 3);
            element.setY(y);
            element.setZ(0);
            element.setSprModel(ElementDescription.DROP_FLOOR);
          } else {
            element.setZ(11.0f);
            // element.setVx(0.15f);
            element.setVz(-0.02f);
            element.setAz(-0.01f);
            // element.setAx(-0.01f);
            element.setSprModel(ElementDescription.DROP_SMALL);
          }
        }
        break;

      case DEATH:
        element = new ElementAnimMort(miscPerso);
        element.setX(x);
        element.setY(y);
        element.setZ(8.0f);
        break;

      case BREAKING_ROCK:
        Angle temp = Angle.NORDOUEST;
        for (j = 0; j < 4; j++) {
          Element e = new Element();
          Point move = temp.coords;
          e.setX(x);
          e.setY(y);
          e.setZ(4);
          e.setVx(0.5f * move.x + (float) Math.random() * 0.2f);
          e.setVy(0.5f * move.y + (float) Math.random() * 0.2f);
          e.setVz(1f);
          e.setAz(-0.08f);
          e.setFx(0.04f);
          e.setFy(0.04f);
          e.setNSpr(ElementDescription.TINY_ROCK.ordinal());
          if (j % 2 == 1) {
            e.rotation = Rotation.UPSIDEDOWN;
          }
          e.alphaV = -10;
          spawnSprite(e);

          temp = Angle.rotate(temp, 1);
        }
        break;

      case FROM_CHEST:
        element = new ElementGoodies(miscPerso);
        element.x = x;
        element.y = y;
        element.z = 16;
        element.vx = 0;
        element.vy = 0.0f;
        element.vz = 0.18f;
        element.ax = 0;
        element.fy = 0.005f;
        element.fz = 0.03f;
        element.setDesc(desc);
        break;
      case STAR_CIRCLE:
        element = new ElementStars(StarKind.CIRCLE, x, y);
        break;
      case STAR_SHINE:
        element = new ElementImpact(x, y, ImpactKind.STAR_YELLOW, null);
        element.setForeground(true);
        break;
      case STAR_TRAIL:
        element = new ElementStars(StarKind.TRAIL, x, y);
        break;
      case CLOUD_FOG:
        element = new ElementClouds(x, y);
        EngineZildo.soundManagement.broadcastSound(BankSound.CannonBall, element);
        break;
      case HEARTS:
        element = new ElementHearts(x, y);
        break;
      case ROCKBALL:
        element =
            new ElementThrown(Angle.EST, x, y, 15, 2.9f, null) {
              @Override
              public void animate() {
                super.animate();
              }
            };
        element.vy = Hasard.intervalle(0.2f);
        element.vz = 1.2f;
        element.az = -0.1f;
        // element.fx = 0.01f;
        element.setDesc(ElementDescription.ROCK_BALL);
        element.setForeground(true);
        break;
      case STAFF_POUM:
        element = new ElementStaffs(x, y);
        break;
      case BIG_FIREBALL:
        element = new ElementFireballs(x, y, Angle.fromInt(misc));
        break;
      case LAVA_DROP:
        element = new ElementImpact(x, y, ImpactKind.LAVA_DROP, null);
        break;
      case DUST:
        element = new ElementImpact(x, y, ImpactKind.DUST, null);
        break;
      case POISONCLOUD:
        element = new ElementPoison(x, y, miscPerso);
        break;
      case WATER_SPLASH:
        element = new ElementImpact(x, y, ImpactKind.WATER_SPLASH, null);
        break;
      case SEWER_SMOKE:
        element = new ElementSewerSmoke(x, y, Angle.fromInt(misc));
        break;
    }
    if (element != null) {
      element.floor = floor;
      spawnSprite(element);
    }

    return element;
  }