freeslot("MT_ALTYELLOWSHELL", "S_OYSHELL_STND", "S_OYSHELL_RUN1",  "S_OYSHELL_RUN2", "S_OYSHELL_RUN3", "S_OYSHELL_RUN4", "S_OYSHELL_SPRING1", "S_OYSHELL_SPRING2", "S_OYSHELL_SPRING3", "S_OYSHELL_SPRING4", "S_OYSHELL_DEATH", "SPR_YSHL", "MT_REDSHELL", "S_RSHELL_STND", "S_RSHELL_RUN1",  "S_RSHELL_RUN2", "S_RSHELL_RUN3", "S_RSHELL_RUN4", "S_RSHELL_SPRING1", "S_RSHELL_SPRING2", "S_RSHELL_SPRING3", "S_RSHELL_SPRING4", "S_RSHELL_DEATH", "SPR_RSHL", "MT_ALTREDSHELL", "S_ARSHELL_STND", "S_ARSHELL_RUN1",  "S_ARSHELL_RUN2", "S_ARSHELL_RUN3", "S_ARSHELL_RUN4", "S_ARSHELL_SPRING1", "S_ARSHELL_SPRING2", "S_ARSHELL_SPRING3", "S_ARSHELL_SPRING4", "S_ARSHELL_DEATH")
//Made by Glaber, Midiman, and Monster Iestyn

local function DoAltSpringShell(thing, tmthing)
  if ((thing.type ==  MT_ALTYELLOWSHELL or thing.type ==  MT_REDSHELL or thing.type ==  MT_ALTREDSHELL) and thing.health > 0
   and (tmthing.player or (tmthing.flags & MF_PUSHABLE)) and tmthing.health > 0)

      // Multiplying by -1 inherently flips "less than" and "greater than"
      local tmz, tmznext, thzh
      if (thing.eflags & MFE_VERTICALFLIP)
          tmz = -(tmthing.z + tmthing.height)
          tmznext = -tmthing.momz + tmz
          thzh = -thing.z
      else
          tmz = tmthing.z
          tmznext = tmthing.momz + tmz
          thzh = thing.z + thing.height
      end
      local sprarea = FixedMul(8*FRACUNIT, thing.scale) * P_MobjFlip(thing)
      if ((tmznext <= thzh and tmz > thzh) or (tmznext > thzh - sprarea and tmznext < thzh))
          P_DoSpring(thing, tmthing)
          return true
      elseif (tmz > thzh - sprarea and tmz < thzh) // Don't damage people springing up or down
          return true
      end
  end
end

addHook("MobjCollide", DoAltSpringShell, MT_ALTYELLOWSHELL)
addHook("MobjCollide", DoAltSpringShell, MT_REDSHELL)
addHook("MobjCollide", DoAltSpringShell, MT_ALTREDSHELL)


mobjinfo[MT_ALTYELLOWSHELL] = {
		//$Name "Alternate Yellow Spring Shell"
		//$Sprite YSHLA1
		//$Category Retro Enemies
        doomednum = 153,
        spawnstate = S_OYSHELL_STND,
        spawnhealth = 1,
        seestate = S_OYSHELL_RUN1,
        seesound = sfx_None,
        reactiontime = 32,
        attacksound = sfx_None,
        painstate = S_NULL,
        painchance = TICRATE,
        painsound = sfx_spring,
		meleestate = S_NULL,
		missilestate = S_NULL,
        deathstate = S_OYSHELL_DEATH,
        xdeathstate = S_NULL,
        deathsound = sfx_pop,
        speed = 6,
        radius = 24*FRACUNIT,
        height = 40*FRACUNIT,
        dispoffset = 0,
        mass = 20*FRACUNIT,
        damage = 0,
        activesound = sfx_None,
		raisestate = S_OYSHELL_SPRING1,
        flags = MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE
}

states[S_OYSHELL_STND] = {SPR_YSHL, A, 4, A_Look, 0, 0, S_OYSHELL_STND}
states[S_OYSHELL_RUN1] = {SPR_YSHL, A, 4, A_Chase, 0, 0, S_OYSHELL_RUN2}
states[S_OYSHELL_RUN2] = {SPR_YSHL, B, 4, A_Chase, 0, 0, S_OYSHELL_RUN3}
states[S_OYSHELL_RUN3] = {SPR_YSHL, C, 4, A_Chase, 0, 0, S_OYSHELL_RUN4}
states[S_OYSHELL_RUN4] = {SPR_YSHL, D, 4, A_Chase, 0, 0, S_OYSHELL_RUN1}
states[S_OYSHELL_SPRING1] = {SPR_YSHL, E, 4, A_Pain, 0, 0, S_OYSHELL_SPRING2}
states[S_OYSHELL_SPRING2] = {SPR_YSHL, F, 4, nil, 0, 0, S_OYSHELL_SPRING3}
states[S_OYSHELL_SPRING3] = {SPR_YSHL, G, 4, nil, 0, 0, S_OYSHELL_SPRING4}
states[S_OYSHELL_SPRING4] = {SPR_YSHL, H, 4, nil, 0, 0, S_OYSHELL_RUN1}
states[S_OYSHELL_DEATH] = {SPR_YSHL, A, 0, A_SpawnObjectRelative, 0, (0<<16)+MT_YELLOWSPRING, S_XPLD_FLICKY}//for Spring spawning made easy.

//Puyo
if not(kirbyabilitytable)
    rawset(_G, "kirbyabilitytable", {})
end
kirbyabilitytable[MT_ALTYELLOWSHELL] = 9    // Makes MT_ALTYELLOWSHELL give BALL

mobjinfo[MT_REDSHELL] = {
		//$Name "Red Spring Shell"
		//$Sprite RSHLA1
		//$Category Custom Enemies
        doomednum = 2040,
        spawnstate = S_RSHELL_STND,
        spawnhealth = 1,
        seestate = S_RSHELL_RUN1,
        seesound = sfx_None,
        reactiontime = 32,
        attacksound = sfx_None,
        painstate = S_NULL,
        painchance = TICRATE,
        painsound = sfx_spring,
		meleestate = S_NULL,
		missilestate = S_NULL,
        deathstate = S_RSHELL_DEATH,
        xdeathstate = S_NULL,
        deathsound = sfx_pop,
        speed = 6,
        radius = 24*FRACUNIT,
        height = 40*FRACUNIT,
        dispoffset = 0,
        mass = 32*FRACUNIT,
        damage = 0,
        activesound = sfx_None,
		raisestate = S_RSHELL_SPRING1,
        flags = MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE
}

states[S_RSHELL_STND] = {SPR_RSHL, A, 4, A_Look, 0, 0, S_RSHELL_STND}
states[S_RSHELL_RUN1] = {SPR_RSHL, A, 4, A_Chase, 0, 0, S_RSHELL_RUN2}
states[S_RSHELL_RUN2] = {SPR_RSHL, B, 4, A_Chase, 0, 0, S_RSHELL_RUN3}
states[S_RSHELL_RUN3] = {SPR_RSHL, C, 4, A_Chase, 0, 0, S_RSHELL_RUN4}
states[S_RSHELL_RUN4] = {SPR_RSHL, D, 4, A_Chase, 0, 0, S_RSHELL_RUN1}
states[S_RSHELL_SPRING1] = {SPR_RSHL, E, 4, A_Pain, 0, 0, S_RSHELL_SPRING2}
states[S_RSHELL_SPRING2] = {SPR_RSHL, F, 4, nil, 0, 0, S_RSHELL_SPRING3}
states[S_RSHELL_SPRING3] = {SPR_RSHL, G, 4, nil, 0, 0, S_RSHELL_SPRING4}
states[S_RSHELL_SPRING4] = {SPR_RSHL, H, 4, nil, 0, 0, S_RSHELL_RUN1}
states[S_RSHELL_DEATH] = {SPR_RSHL, A, 0, A_SpawnObjectRelative, 0, (0<<16)+MT_REDSPRING, S_XPLD_FLICKY}

//Puyo
if not(kirbyabilitytable)
    rawset(_G, "kirbyabilitytable", {})
end
kirbyabilitytable[MT_REDSHELL] = 9    // Makes MT_REDSHELL give BALL

mobjinfo[MT_ALTREDSHELL] = {
		//$Name "Alt Red Spring Shell"
		//$Sprite RSHLI1
		//$Category Custom Enemies
        doomednum = 2041,
        spawnstate = S_ARSHELL_STND,
        spawnhealth = 1,
        seestate = S_ARSHELL_RUN1,
        seesound = sfx_None,
        reactiontime = 32,
        attacksound = sfx_None,
        painstate = S_NULL,
        painchance = TICRATE,
        painsound = sfx_spring,
	meleestate = S_NULL,
	missilestate = S_NULL,
        deathstate = S_ARSHELL_DEATH,
        xdeathstate = S_NULL,
        deathsound = sfx_pop,
        speed = 6,
        radius = 24*FRACUNIT,
        height = 40*FRACUNIT,
        dispoffset = 0,
        mass = 32*FRACUNIT,
        damage = 0,
        activesound = sfx_None,
		raisestate = S_ARSHELL_SPRING1,
        flags = MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE
}

states[S_ARSHELL_STND] = {SPR_RSHL, I, 4, A_Look, 0, 0, S_ARSHELL_STND}
states[S_ARSHELL_RUN1] = {SPR_RSHL, I, 4, A_Chase, 0, 0, S_ARSHELL_RUN2}
states[S_ARSHELL_RUN2] = {SPR_RSHL, J, 4, A_Chase, 0, 0, S_ARSHELL_RUN3}
states[S_ARSHELL_RUN3] = {SPR_RSHL, K, 4, A_Chase, 0, 0, S_ARSHELL_RUN4}
states[S_ARSHELL_RUN4] = {SPR_RSHL, L, 4, A_Chase, 0, 0, S_ARSHELL_RUN1}
states[S_ARSHELL_SPRING1] = {SPR_RSHL, M, 4, A_Pain, 0, 0, S_ARSHELL_SPRING2}
states[S_ARSHELL_SPRING2] = {SPR_RSHL, N, 4, nil, 0, 0, S_ARSHELL_SPRING3}
states[S_ARSHELL_SPRING3] = {SPR_RSHL, O, 4, nil, 0, 0, S_ARSHELL_SPRING4}
states[S_ARSHELL_SPRING4] = {SPR_RSHL, P, 4, nil, 0, 0, S_ARSHELL_RUN1}
states[S_ARSHELL_DEATH] = {SPR_RSHL, I, 0, A_SpawnObjectRelative, 0, (0<<16)+MT_REDSPRING, S_XPLD_FLICKY}

//Puyo
if not(kirbyabilitytable)
    rawset(_G, "kirbyabilitytable", {})
end
kirbyabilitytable[MT_ALTREDSHELL] = 9    // Makes MT_ALTREDSHELL give BALL
