index.js
function () {
    if (beatmap.timingPoints.length === 0) { return; }

    var maxCombo         = 0;
    var sliderMultiplier = parseFloat(beatmap.SliderMultiplier);
    var sliderTickRate   = parseInt(beatmap.SliderTickRate, 10);

    var timingPoints  = beatmap.timingPoints;
    var currentTiming = timingPoints[0];
    var nextOffset    = timingPoints[1] ? timingPoints[1].offset : Infinity;
    var i = 1;

    beatmap.hitObjects.forEach(function (hitObject) {
      if (hitObject.startTime >= nextOffset) {
        currentTiming = timingPoints[i++];
        nextOffset = timingPoints[i] ? timingPoints[i].offset : Infinity;
      }

      var osupxPerBeat = sliderMultiplier * 100 * currentTiming.velocity;
      var tickLength   = osupxPerBeat / sliderTickRate;

      switch (hitObject.objectName) {
        case 'spinner':
        case 'circle':
          maxCombo++;
          break;
        case 'slider':
          var tickPerSide = Math.ceil((Math.floor(hitObject.pixelLength / tickLength * 100) / 100) - 1);
          maxCombo += (hitObject.edges.length - 1) * (tickPerSide + 1) + 1;  // 1 combo for each tick and endpoint
      }
    });

    beatmap.maxCombo = maxCombo;
  }
function () {
    if (beatmap.timingPoints.length === 0) { return; }

    var maxCombo         = 0;
    var sliderMultiplier = parseFloat(beatmap.SliderMultiplier);
    var sliderTickRate   = parseInt(beatmap.SliderTickRate, 10);

    var timingPoints  = beatmap.timingPoints;
    var currentTiming = timingPoints[0];
    var nextOffset    = timingPoints[1] ? timingPoints[1].offset : Infinity;
    var i = 1;

    beatmap.hitObjects.forEach(function (hitObject) {
      if (hitObject.startTime >= nextOffset) {
        currentTiming = timingPoints[i++];
        nextOffset = timingPoints[i] ? timingPoints[i].offset : Infinity;
      }

      var osupxPerBeat = sliderMultiplier * 100 * currentTiming.velocity;
      var tickLength   = osupxPerBeat / sliderTickRate;

      switch (hitObject.objectName) {
        case 'spinner':
        case 'circle':
          maxCombo++;
          break;
        case 'slider':
          var tickPerSide = Math.ceil((Math.floor(hitObject.pixelLength / tickLength * 100) / 100) - 1);
          maxCombo += (hitObject.edges.length - 1) * (tickPerSide + 1) + 1;  // 1 combo for each tick and endpoint
      }
    });

    beatmap.maxCombo = maxCombo;
  }
function ( ) { if ( beatmap . timingPoints . length === 0 ) { return ; } var maxCombo = 0 ; var sliderMultiplier = parseFloat ( beatmap . SliderMultiplier ) ; var sliderTickRate = parseInt ( beatmap . SliderTickRate , 10 ) ; var timingPoints = beatmap . timingPoints ; var currentTiming = timingPoints [ 0 ] ; var nextOffset = timingPoints [ 1 ] ? timingPoints [ 1 ] . offset : Infinity ; var i = 1 ; beatmap . hitObjects . forEach ( function ( hitObject ) { if ( hitObject . startTime >= nextOffset ) { currentTiming = timingPoints [ i ++ ] ; nextOffset = timingPoints [ i ] ? timingPoints [ i ] . offset : Infinity ; } var osupxPerBeat = sliderMultiplier * 100 * currentTiming . velocity ; var tickLength = osupxPerBeat / sliderTickRate ; switch ( hitObject . objectName ) { case 'spinner' : case 'circle' : maxCombo ++ ; break ; case 'slider' : var tickPerSide = Math . ceil ( ( Math . floor ( hitObject . pixelLength / tickLength * 100 ) / 100 ) - 1 ) ; maxCombo += ( hitObject . edges . length - 1 ) * ( tickPerSide + 1 ) + 1 ; // 1 combo for each tick and endpoint } } ) ; beatmap . maxCombo = maxCombo ; }
Browse objects and compute max combo
Browse objects and compute max combo