local function dissolve(entity)
  entity.Sprite:Play("diseappear")
end

local function land(entity)
  entity.Sprite:Play("splatter")
  playSound("event:/CC/CC_HollowKnight/SFX/Boss SFX/InfectionImpact",entity.Center)
  entity.Speed = vector2(0, 0)
  entity.Collider = getHitbox(16, 4, 0, -4)
  entity:Add(getEntityTimer(1, dissolve))
  entity:Add(getEntityTimer(2))
end

local function getBlob(dir, strength)
  local blob = getNewBasicAttackActor(puppet.Position, getHitbox(10, 10, 0, -10), "infectedBall", 0.85, 200) --change sprite to that of infection blob
  blob.Sprite:Play("spin")
  blob.Speed = normalize(dir, strength * 4)
  blob:Add(getEntityChecker(
    function ()
      return blob.Grounded
    end, land)
  )
  return blob
end

local function a2V(angle)
  local rad = math.rad(angle)
  local result = vector2(math.cos(rad) * puppet.Facing, -math.sin(rad))
  return result
end

--format {angle, speed}
--(degrees, 0° to right)
local blobs = {
  {70, 80}, {60, 90}, {50, 60}, {40, 50}, --front
  {110, 80}, {120, 90}, {130, 60}, {140, 50}, --back
  {320, 40}, {220, 35} --down
}

function onBegin()
  local center = getStoredObjectFromBoss("spawn_center")
  if math.abs(center - puppet.Position.X) > 40 then
    return
  end
  local dist = player.Position.X - puppet.Position.X
  puppet.Facing = dist > 0 and 1 or dist < 0 and -1 or puppet.Facing

  local degreeVariability = 20

  playPuppetAnim("shriekstart")
  playSound("event:/CC/CC_HollowKnight/SFX/Boss SFX/NoskScreamShort",puppet.Center)
  for _, dir in ipairs(blobs) do
    local randomOffset = (seededRandom() % (degreeVariability + 1)) - (degreeVariability / 2)
    --20 means -10 to +10 variability (extra +1 to account for 0°)
    local offset = a2V(dir[1] + randomOffset)
    local blob = getBlob(offset, dir[2])
    addEntity(blob)
    wait(0.03)
  end
  --maybe add wait at some points within the blob spawns?

  --Eruption is always followed by Charge
  forceNextAttackIndex(1)
end