local LD = require("design.LevelDesignLibrary")
local EC = require("design.Encounter")
local tablex = require("core.tablex")
local player, thisObj, thisLevel, enemy
local enabled = true
local spawnConfigs = {}
local spawnDelayTime, spawnOnStart, spawnZone, spawnZoneMonitor, enemyType, spawnMove, spawnConfigTable, goToApproachPoint, approachIsInterruptible, playMoveOnArrival, approachPointArrivalMove, enemyMarkerString, onEnemySpawnedEvents, onEnemyDeathEvents, luaOnSpawnEvents
function IsInitialized()
  if thisObj == nil then
    return false
  end
  return true
end
function OnScriptLoaded(level, obj)
  thisObj = obj
  thisLevel = level
  player = game.Player.FindPlayer()
  local attributes = obj:GetLuaTableAttributes({
    "Event_OnEnemySpawned",
    "Event_OnEnemyDeath",
    "EnemyMarkerString",
    "SpawnOnStart",
    "SpawnDelay",
    "SpawnZoneName"
  })
  onEnemySpawnedEvents = LD.ExtractCallbacksForEvent(level, obj, attributes.Event_OnEnemySpawned)
  onEnemyDeathEvents = LD.ExtractCallbacksForEvent(level, obj, attributes.Event_OnEnemyDeath)
  enemyMarkerString = attributes.EnemyMarkerString
  enemyType, spawnMove, spawnConfigTable, goToApproachPoint, approachIsInterruptible, approachPointArrivalMove = EC.GetSpawnSequenceInfoFromLuaTableAttr(obj, "SpawnSettings")
  if approachPointArrivalMove == nil then
    playMoveOnArrival = false
  elseif approachPointArrivalMove ~= nil then
    playMoveOnArrival = true
  end
  spawnOnStart = attributes.SpawnOnStart
  spawnDelayTime = attributes.SpawnDelay or 0
  if attributes.SpawnZoneName ~= nil then
    local monitors = require("level.MonitorLibrary")
    spawnZone = level:GetGameObject(tostring(attributes.SpawnZoneName))
    spawnZoneMonitor = monitors.CreateEntityZoneMonitor(player, spawnZone)
    spawnZoneMonitor:SetTriggerCountLimit(1)
    spawnZoneMonitor:OnEnter(function()
      SpawnEnemyAsync()
    end, spawnDelayTime)
  end
  game.SubObject.Sleep(obj)
  game.SubObject.SetForgetOnCheckpoint(obj)
end
function OnPreStart(level, obj)
  if spawnOnStart then
    SpawnEnemyAsync()
  end
end
function CheckForValidSpawnWad(spawnWadArg)
  if spawnWadArg ~= nil then
    if type(spawnWadArg) == "string" then
      return game.FindLevel(spawnWadArg)
    else
      local wadName = string.gsub(spawnWadArg.Name, "WAD_", "")
      return game.FindLevel(wadName)
    end
  else
    return thisLevel
  end
end
function convertPowerLevelToString(powerLevelInt)
  local powerLevel = "1"
  if powerLevelInt == 1 then
    powerLevel = "1"
  elseif powerLevelInt == 2 then
    powerLevel = "2"
  elseif powerLevelInt == 3 then
    powerLevel = "3"
  elseif powerLevelInt == 4 then
    powerLevel = "4"
  elseif powerLevelInt == 5 then
    powerLevel = "5"
  elseif powerLevelInt == 6 then
    powerLevel = "6"
  elseif powerLevelInt == 7 then
    powerLevel = "7"
  elseif powerLevelInt == 8 then
    powerLevel = "8"
  elseif powerLevelInt == 9 then
    powerLevel = "9"
  elseif powerLevelInt == 10 then
    powerLevel = "10"
  elseif powerLevelInt == 11 then
    powerLevel = "11"
  elseif powerLevelInt == 12 then
    powerLevel = "12"
  elseif powerLevelInt == 13 then
    powerLevel = "12"
  elseif powerLevelInt == 14 then
    powerLevel = "12"
  elseif powerLevelInt == 15 then
    powerLevel = "12"
  elseif powerLevelInt == 16 then
    powerLevel = "12"
  elseif powerLevelInt == 17 then
    powerLevel = "12"
  elseif powerLevelInt == 18 then
    powerLevel = "12"
  elseif powerLevelInt == 19 then
    powerLevel = "12"
  else
    engine.Warning("Attempting to override power level with unsupported value. Increase current max supported from (15) to new value in EnemySpawner.lua")
  end
  return powerLevel
end
function RegisterOnSpawnCallback(fn)
  if luaOnSpawnEvents == nil then
    luaOnSpawnEvents = {}
  end
  luaOnSpawnEvents[#luaOnSpawnEvents + 1] = fn
end
function FireOnSpawnCallbacks(creature)
  if luaOnSpawnEvents ~= nil then
    for _, fn in pairs(luaOnSpawnEvents) do
      fn(creature)
    end
  end
end
function GetSpawnPrestreamLocation(object, locator)
  if locator == nil then
    return object:GetWorldPosition()
  else
    local spawnDirectionJoint = locator:FindJointIndex("SpawnDirection")
    if spawnDirectionJoint ~= nil then
      return locator:GetWorldJointPosition(spawnDirectionJoint)
    else
      return locator:GetWorldPosition()
    end
  end
end
function PrestreamEnemy(argsT)
  if game.IsSpawnEnemiesEnabled() then
    local spawnWad = thisLevel
    local locator, encounterName
    local originalPowerLevel = spawnConfigTable.PowerLevel
    if argsT then
      if argsT.spawnWad then
        spawnWad = CheckForValidSpawnWad(argsT.spawnWad)
        if spawnWad == nil then
          return false
        end
      end
      if argsT.locator then
        locator = argsT.locator
      end
      if argsT.powerLevel then
        local powerLevel = convertPowerLevelToString(argsT.powerLevel)
        spawnConfigTable.PowerLevel = powerLevel
      end
      if argsT.encounter then
        encounterName = argsT.encounter
      end
    end
    if spawnWad == nil then
      spawnConfigTable.PowerLevel = originalPowerLevel
      return false
    end
    local spawnPosition = GetSpawnPrestreamLocation(thisObj, locator)
    spawnConfigTable.thisLevel = string.gsub(tostring(thisLevel), "WAD_", "")
    local configTable = GetCharConfigString(enemyType, spawnConfigTable)
    local spawnConfig, decap
    if configTable ~= nil then
      spawnConfig = configTable.charConfig
      decap = configTable.decap
    end
    if spawnConfig == nil then
      spawnConfig = ""
    end
    table.insert(spawnConfigs, {
      spawnWad = spawnWad.Name,
      powerLevel = spawnConfigTable.PowerLevel,
      config = spawnConfig,
      decap = decap
    })
    game.Encounters.PrestreamEncounterEnemy(spawnWad, spawnPosition, tostring("CRT_" .. enemyType), encounterName, configTable)
    spawnConfigTable.PowerLevel = originalPowerLevel
  end
  return true
end
function PrestreamDecap(spawnWad, spawnPosition, tweakName, encounterName, decap)
  if decap ~= nil and decap.charConfig ~= nil then
    if encounterName ~= nil then
      game.Encounters.PrestreamEncounterEnemy(spawnWad, spawnPosition, tweakName, encounterName, decap)
      if decap.additionalDecap ~= nil then
        for i = 1, #decap.additionalDecap do
          if decap.additionalDecap[i] ~= nil then
            local additionalDecap = {
              charConfig = decap.additionalDecap[i]
            }
            game.Encounters.PrestreamEncounterEnemy(spawnWad, spawnPosition, tweakName, encounterName, additionalDecap)
          end
        end
      end
    elseif decap.useGlobalEncounter ~= nil and decap.useGlobalEncounter == true then
      game.Encounters.RequestGlobalCharacterPrestream(spawnWad, spawnPosition, tweakName, decap.charConfig)
      if decap.additionalDecap ~= nil then
        for i = 1, #decap.additionalDecap do
          if decap.additionalDecap[i] ~= nil then
            game.Encounters.RequestGlobalCharacterPrestream(spawnWad, spawnPosition, tweakName, decap.additionalDecap[i])
          end
        end
      end
    end
  end
end
function SpawnEnemy(argsT)
  if game.IsSpawnEnemiesEnabled() then
    local originalPowerLevel = spawnConfigTable.PowerLevel
    local spawnWad = thisLevel
    local locator, encounterName, bossOverride
    if argsT then
      if argsT.spawnWad then
        spawnWad = CheckForValidSpawnWad(argsT.spawnWad)
      end
      if argsT.locator then
        locator = argsT.locator
      end
      if argsT.powerLevel then
        local powerLevel = convertPowerLevelToString(argsT.powerLevel)
        spawnConfigTable.PowerLevel = powerLevel
      end
      if argsT.EncounterName then
        encounterName = argsT.EncounterName
      end
      if argsT.bossConfigOverride then
        bossOverride = argsT.bossConfigOverride
      end
    end
    local spawnPosition, spawnDirection = GetSpawnTransforms(locator)
    spawnConfigTable.SpawnMove = tostring(spawnMove)
    spawnConfigTable.thisLevel = string.gsub(tostring(thisLevel.Name), "WAD_", "")
    if locator == nil and IsEnabled() or locator ~= nil then
      local spawnConfig, decap
      for i = 1, #spawnConfigs do
        local iter = spawnConfigs[i]
        if iter.spawnWad ~= nil and iter.spawnWad == spawnWad.Name and iter.powerLevel == spawnConfigTable.PowerLevel then
          spawnConfig = iter.config
          decap = iter.decap
          table.remove(spawnConfigs, i)
          break
        end
      end
      if spawnConfig == nil then
        local configTable = GetCharConfigString(enemyType, spawnConfigTable)
        if configTable ~= nil then
          spawnConfig = configTable.charConfig
          decap = configTable.decap
        else
          spawnConfig = nil
        end
      end
      if bossOverride then
        spawnConfig = bossOverride
      end
      enemy = game.AI.Spawn(spawnWad, spawnPosition, spawnDirection, tostring("CRT_" .. enemyType), tostring(spawnMove), spawnConfigTable, spawnConfig)
      PrestreamDecap(spawnWad, spawnPosition, tostring("CRT_" .. enemyType), encounterName, decap)
    end
    if enemy then
      CheckForCallbacks(enemy, locator)
      SetupApproach(enemy, locator)
    end
    spawnConfigTable.PowerLevel = originalPowerLevel
    FireOnSpawnCallbacks(enemy)
    return enemy
  elseif onEnemyDeathEvents ~= nil then
    EnemyDeathCallback()
  end
end
local AsyncSpawnStates = {}
local NextAsyncSpawnId = 0
local StoreAsyncSpawnState = function(state)
  local id = NextAsyncSpawnId
  NextAsyncSpawnId = NextAsyncSpawnId + 1
  AsyncSpawnStates[id] = state
  return id
end
local RetrieveAsyncSpawnState = function(id)
  local state = AsyncSpawnStates[id]
  AsyncSpawnStates[id] = nil
  if tablex.IsEmpty(AsyncSpawnStates) then
    NextAsyncSpawnId = 0
  end
  return state
end
local encounterDeathStates = {}
function EnemySpawnCallback(level, obj, creature, id)
  enemy = creature
  local state = RetrieveAsyncSpawnState(id)
  local locator = state.locator
  local callback = state.callback
  local encounter = state.encounter
  if encounter then
    if encounter.self:IsRunning() then
      SetupDeathCallbackForEncounter(creature, encounter.self, state.encounter.wave, state.encounter.element)
      encounter.self:ForwardSpawnCallbackToEncounter(creature, state.encounter.wave, state.encounter.element, obj, locator)
    else
      creature:Destroy()
      return
    end
  end
  CheckForCallbacks(creature, locator)
  SetupApproach(creature, locator)
  FireOnSpawnCallbacks(creature)
  if callback then
    callback(creature)
  end
  if creature:GetHitPoints() <= 0 then
    EnemyDeathCallback(level, obj, creature)
  end
end
function SetupDeathCallbackForEncounter(creature, encounter, wave, element)
  encounterDeathStates[creature] = {
    encounter = encounter,
    wave = wave,
    element = element
  }
  creature:SetAIDeathCallback(thisObj, "EnemyDeathCallback")
end
function EnemyDeathCallback(level, obj, creature)
  if encounterDeathStates[creature] ~= nil then
    local key = encounterDeathStates[creature]
    key.encounter:ForwardDeathCallbackToEncounter(creature, key.wave, key.element)
    encounterDeathStates[creature] = nil
  end
  LD.ExecuteCallbacksForEvent(thisLevel, thisObj, onEnemyDeathEvents, "EnemyDeathEvent")
end
function SpawnEnemyAsync(argsT)
  if game.IsSpawnEnemiesEnabled() then
    local spawnWad = thisLevel
    local locator, callback, encounter
    local originalPowerLevel = spawnConfigTable.PowerLevel
    if argsT then
      if argsT.spawnWad then
        spawnWad = CheckForValidSpawnWad(argsT.spawnWad)
      end
      if argsT.locator then
        locator = argsT.locator
      end
      if argsT.callback then
        callback = argsT.callback
      end
      if argsT.powerLevel then
        local powerLevel = convertPowerLevelToString(argsT.powerLevel)
        spawnConfigTable.PowerLevel = powerLevel
      end
      if argsT.encounterInfo then
        encounter = argsT.encounterInfo
      end
    end
    local spawnPosition, spawnDirection = GetSpawnTransforms(locator)
    spawnConfigTable.SpawnMove = tostring(spawnMove)
    spawnConfigTable.thisLevel = string.gsub(tostring(thisLevel.Name), "WAD_", "")
    local willSpawn = false
    if locator == nil and IsEnabled() or locator ~= nil then
      local id = StoreAsyncSpawnState({
        locator = locator,
        callback = callback,
        encounter = encounter
      })
      local spawnConfig, decap
      for i = 1, #spawnConfigs do
        local iter = spawnConfigs[i]
        if iter.spawnWad ~= nil and iter.spawnWad == spawnWad.Name and iter.powerLevel == spawnConfigTable.PowerLevel then
          spawnConfig = iter.config
          decap = iter.decap
          table.remove(spawnConfigs, i)
          break
        end
      end
      if spawnConfig == nil then
        local configTable = GetCharConfigString(enemyType, spawnConfigTable)
        if configTable ~= nil then
          spawnConfig = configTable.charConfig
          decap = configTable.decap
        else
          spawnConfig = nil
        end
      end
      local creatureTweaks = tostring("CRT_" .. enemyType)
      willSpawn = game.AI.AsyncSpawn(spawnWad, "EnemySpawnCallback", spawnPosition, spawnDirection, creatureTweaks, {
        branchName = tostring(spawnMove),
        configTable = spawnConfigTable,
        callbackTarget = thisObj,
        id = id,
        configString = spawnConfig
      })
      if encounter ~= nil and encounter.self ~= nil and decap ~= nil and decap.charConfig ~= nil then
        PrestreamDecap(spawnWad, spawnPosition, creatureTweaks, encounter.self.Name, decap)
      end
    end
    spawnConfigTable.PowerLevel = originalPowerLevel
    return willSpawn
  elseif onEnemyDeathEvents ~= nil then
    EnemyDeathCallback()
  end
  return false
end
function GetSpawnTransforms(locator)
  if locator == nil then
    return thisObj:GetWorldJointPosition(thisObj:GetJointIndex("SpawnDirection")), thisObj:GetWorldJointForward(thisObj:GetJointIndex("SpawnDirection"))
  else
    local spawnDirectionJoint = locator:FindJointIndex("SpawnDirection")
    if spawnDirectionJoint ~= nil then
      return locator:GetWorldJointPosition(spawnDirectionJoint), locator:GetWorldJointForward(spawnDirectionJoint)
    else
      return locator:GetWorldPosition(), locator:GetWorldForward()
    end
  end
end
function GetApproachTransforms(locator)
  if locator == nil then
    return thisObj:GetWorldJointPosition(thisObj:GetJointIndex("ApproachPoint")), thisObj:GetWorldJointForward(thisObj:GetJointIndex("ApproachPoint"))
  else
    return locator:GetWorldJointPosition(locator:FindJointIndex("ApproachPoint")), locator:GetWorldJointForward(locator:FindJointIndex("ApproachPoint"))
  end
end
function SetupApproach(enemy, locator)
  if goToApproachPoint == true or playMoveOnArrival == true then
    local aiPuppeteer = game.Puppeteer.NewForce(thisObj, "Spawn Sequence", enemy)
    if approachIsInterruptible then
      aiPuppeteer:OnEvent(function()
        Interrupted(aiPuppeteer)
      end, "kEHitReaction")
    end
    local approachPosition, approachDirection = GetApproachTransforms(locator)
    aiPuppeteer:MonitorPlayingMove()
    aiPuppeteer:OnComplete(function()
      StartPuppeteer(aiPuppeteer, approachPosition, approachDirection)
    end)
  end
end
function CheckForCallbacks(enemy, locator)
  if locator == nil then
    if onEnemyDeathEvents ~= nil then
      enemy:SetAIDeathCallback(thisObj, "EnemyDeathCallback")
    end
    if onEnemySpawnedEvents ~= nil and onEnemySpawnedEvents ~= {} then
      LD.ExecuteCallbacksForEvent(thisLevel, thisObj, onEnemySpawnedEvents, "EnemySpawnedEvent")
    end
    if enemyMarkerString ~= nil and enemyMarkerString ~= "" then
      enemy:AddMarker(enemyMarkerString)
    end
  end
end
function StartPuppeteer(puppeteer, approachLoc, approachDir)
  if puppeteer ~= nil then
    puppeteer:Clear()
    if approachIsInterruptible then
      puppeteer:OnEvent(function()
        Interrupted(puppeteer)
      end, "kEHitReaction")
    end
    if goToApproachPoint == false then
      puppeteer:OnComplete(function()
        AlignOnArrival(puppeteer)
      end)
    elseif goToApproachPoint == true then
      puppeteer:OnComplete(function()
        ApproachLocation(puppeteer, approachLoc, approachDir)
      end)
    end
  end
end
function ApproachLocation(puppeteer, approachLoc, approachDir)
  if puppeteer ~= nil then
    puppeteer:Clear()
    if approachIsInterruptible then
      puppeteer:OnEvent(function()
        Interrupted(puppeteer)
      end, "kEHitReaction")
    end
    local approachParams = {
      pos = approachLoc,
      dir = approachDir,
      speed = 3.8,
      stop = true,
      complete_radius = 0.75
    }
    if puppeteer ~= nil then
      puppeteer:Approach(approachParams)
      if playMoveOnArrival then
        puppeteer:OnArrival(function()
          AlignOnArrival(puppeteer, approachLoc, approachDir)
        end, {pos = approachLoc, radius = 0.75})
      elseif playMoveOnArrival == false then
        puppeteer:OnArrival(function()
          ClearEnemy(puppeteer)
        end, {pos = approachLoc, radius = 0.75})
      end
    end
  end
end
function AlignOnArrival(puppeteer, approachLoc, approachDir)
  if puppeteer ~= nil then
    puppeteer:Clear()
    if approachIsInterruptible then
      puppeteer:OnEvent(function()
        Interrupted(puppeteer)
      end, "kEHitReaction")
    end
    if playMoveOnArrival then
      puppeteer:Align({
        pos = approachLoc,
        aligntime = 0.2,
        facing = approachDir
      })
      puppeteer:OnComplete(function()
        PlayMove(puppeteer)
      end)
    else
      puppeteer:OnComplete(function()
        ClearEnemy(puppeteer)
      end)
    end
  end
end
function PlayMove(puppeteer)
  if puppeteer ~= nil then
    puppeteer:Clear()
    if approachIsInterruptible then
      puppeteer:OnEvent(function()
        Interrupted(puppeteer)
      end, "kEHitReaction")
    end
    puppeteer:StartBranch(tostring(approachPointArrivalMove))
    puppeteer:OnComplete(function()
      ClearEnemy(puppeteer)
    end)
  end
end
function ClearEnemy(puppeteer)
  if puppeteer ~= nil then
    puppeteer:Clear()
    puppeteer = nil
  end
end
function Interrupted(puppeteer)
  if puppeteer ~= nil then
    puppeteer:DetachPuppet()
    puppeteer:Clear()
    puppeteer = nil
  end
end
function Enable()
  enabled = true
end
function Disable()
  enabled = false
end
function IsEnabled()
  return enabled
end
function GetSpawnBranch()
  return spawnMove
end
function GetSpawnPos()
  return thisObj:GetWorldJointPosition(thisObj:GetJointIndex("SpawnDirection"))
end
function GetApproachPos()
  return thisObj:GetWorldJointPosition(thisObj:GetJointIndex("ApproachPoint"))
end
function GetEnemyType()
  return enemyType
end
function GetLastEnemy()
  if enemy ~= nil then
    return enemy
  end
end
function GetPowerLevel(spawnConfigTable)
  if spawnConfigTable ~= nil and spawnConfigTable.PowerLevel ~= nil then
    if spawnConfigTable.PowerLevel == "1" then
      return 1
    elseif spawnConfigTable.PowerLevel == "2" then
      return 2
    elseif spawnConfigTable.PowerLevel == "3" then
      return 3
    elseif spawnConfigTable.PowerLevel == "4" then
      return 4
    elseif spawnConfigTable.PowerLevel == "5" then
      return 5
    elseif spawnConfigTable.PowerLevel == "6" then
      return 6
    elseif spawnConfigTable.PowerLevel == "7" then
      return 7
    elseif spawnConfigTable.PowerLevel == "8" then
      return 8
    elseif spawnConfigTable.PowerLevel == "9" then
      return 9
    elseif spawnConfigTable.PowerLevel == "10" then
      return 10
    elseif spawnConfigTable.PowerLevel == "11" then
      return 11
    elseif spawnConfigTable.PowerLevel == "12" then
      return 12
    else
      return 1
    end
  end
  return 1
end
function GetCharConfigString(enemyType, spawnConfigTable)
  if _G.streamerFuncTable == nil then
    _G.streamerFuncTable = {}
    local funcTable = _G.streamerFuncTable
    funcTable.Bandit00 = GetConfig_Bandit00
    funcTable.BanditHuman00 = GetConfig_BanditHuman00
    funcTable.Brawler00 = GetConfig_Brawler00
    funcTable.Crawler00 = GetConfig_Crawler00
    funcTable.Crawler10 = GetConfig_Crawler10
    funcTable.DarkOne00 = GetConfig_DarkOne00
    funcTable.DarkOneElite00 = GetConfig_DarkOneElite00
    funcTable.Dragon00 = GetConfig_Dragon00
    funcTable.Draugr00 = GetConfig_Draugr00
    funcTable.Draugr00_1hsword = GetConfig_Draugr00_1hsword
    funcTable.Drummer00 = GetConfig_Drummer00
    funcTable.EarthDragon00 = GetConfig_EarthDragon00
    funcTable.Fanatic00 = GetConfig_Fanatic00
    funcTable.Flyer00 = GetConfig_Flyer00
    funcTable.Flyer10 = GetConfig_Flyer10
    funcTable.Freya00 = GetConfig_Freya00
    funcTable.FreyaVines00 = GetConfig_FreyaVines00
    funcTable.goblin00 = GetConfig_Goblin00
    funcTable.Golem00 = GetConfig_Golem00
    funcTable.Golem10 = GetConfig_Golem10
    funcTable.Golem20 = GetConfig_Golem20
    funcTable.Golem30 = GetConfig_Golem30
    funcTable.Jotunn00 = GetConfig_Jotunn00
    funcTable.Jotunn10 = GetConfig_Jotunn10
    funcTable.Jotunn20 = GetConfig_Jotunn20
    funcTable.Projection00 = GetConfig_Projection00
    funcTable.Projection10 = GetConfig_Projection10
    funcTable.Projection20 = GetConfig_Projection20
    funcTable.Traveler00 = GetConfig_Traveler00
    funcTable.Troll00 = GetConfig_Troll00
    funcTable.Troll10 = GetConfig_Troll10
    funcTable.Troll20 = GetConfig_Troll20
    funcTable.Troll30 = GetConfig_Troll30
    funcTable.Valkyrie00 = GetConfig_Valkyrie00
    funcTable.ValkyrieGhost00 = GetConfig_ValkyrieGhost00
    funcTable.Witch00 = GetConfig_Witch00
    funcTable.Witch10 = GetConfig_Witch10
    funcTable.Witch20 = GetConfig_Witch20
    funcTable.Wolf00 = GetConfig_Wolf00
    funcTable.Wolf10 = GetConfig_Wolf10
    funcTable.Wulver00 = GetConfig_Wulver00
    funcTable.Wulver10 = GetConfig_Wulver10
  end
  local initFuncTable = _G.streamerFuncTable
  if initFuncTable[enemyType] ~= nil then
    return initFuncTable[enemyType](spawnConfigTable)
  end
  return nil
end
function GetConfig_Bandit00(spawnConfigTable)
  local charConfig = "Helwalker00"
  local weaponModel = "gosword00"
  local weaponConfig, decap
  local bodyType = spawnConfigTable.BodyType
  local Equipment = spawnConfigTable.Equipment
  if bodyType == nil then
    return {
      charConfig = charConfig,
      weaponModel = weaponModel,
      weaponConfig = weaponConfig
    }
  end
  local powerLevelInt = GetPowerLevel(spawnConfigTable)
  if bodyType == "Seidr" then
    if 5 <= powerLevelInt then
      charConfig = "seidr04_veryhard"
      weaponConfig = "seidrSword_Hard"
      decap = {
        charConfig = "Helwalker02_decap",
        additionalDecap = {
          "seidrSpikes02_decap",
          "seidrSpikes03_decap"
        }
      }
    else
      local bandit00ConfigsSeidrModerate = {
        "seidr01_moderate",
        "seidr02_moderate",
        "seidr03_moderate"
      }
      local randomConfig = math.random(1, #bandit00ConfigsSeidrModerate)
      if randomConfig == 1 then
        decap = {
          charConfig = "Helwalker00_decap",
          additionalDecap = {
            "seidrSpikes01_decap"
          }
        }
      elseif randomConfig == 2 then
        decap = {
          charConfig = "Helwalker03_decap",
          additionalDecap = {
            "seidrSpikes01_decap"
          }
        }
      elseif randomConfig == 3 then
        decap = {
          charConfig = "Helwalker00_decap",
          additionalDecap = {
            "Helwalker04_decap",
            "seidrSpikes04_decap"
          }
        }
      end
      charConfig = bandit00ConfigsSeidrModerate[randomConfig]
      weaponConfig = "seidrSword"
    end
  else
    if powerLevelInt < 4 then
      local bandit00ConfigsHelwalkerModerate = {
        "Helwalker00",
        "Helwalker01",
        "Helwalker02",
        "Helwalker03"
      }
      local randomConfig = math.random(1, #bandit00ConfigsHelwalkerModerate)
      if randomConfig == 1 then
        decap = {
          charConfig = "Helwalker00_decap"
        }
      elseif randomConfig == 2 then
        decap = {
          charConfig = "Helwalker03_decap"
        }
      elseif randomConfig == 3 then
        decap = {
          charConfig = "Helwalker03_decap"
        }
      elseif randomConfig == 4 then
        decap = {
          charConfig = "Helwalker00_decap"
        }
      end
      charConfig = bandit00ConfigsHelwalkerModerate[randomConfig]
      weaponConfig = "helwalkerSword"
    elseif 4 <= powerLevelInt and powerLevelInt < 7 then
      local bandit00ConfigsHelwalkerHard = {
        "Helwalker04_hard",
        "Helwalker05_hard"
      }
      local randomConfig = math.random(1, #bandit00ConfigsHelwalkerHard)
      decap = {
        charConfig = "Helwalker02_decap"
      }
      charConfig = bandit00ConfigsHelwalkerHard[randomConfig]
      weaponConfig = "helwalkerSword_hard"
    else
      charConfig = "Helwalker06_veryhard"
      weaponConfig = "helwalkerSword_hard"
      decap = {
        charConfig = "Helwalker02_decap"
      }
    end
    if spawnConfigTable.IceArmor ~= nil and spawnConfigTable.IceArmor == true then
      if powerLevelInt < 4 then
        charConfig = "HelwalkerIcy_Moderate"
      elseif 4 <= powerLevelInt and powerLevelInt < 7 then
        charConfig = "HelwalkerIcy_Hard"
      elseif 7 <= powerLevelInt then
        charConfig = "HelwalkerIcy_VeryHard"
      end
      decap = {
        charConfig = "Helwalker02_decap",
        additionalDecap = {
          "HelwalkerIcy_decap"
        }
      }
    end
  end
  if Equipment ~= nil and Equipment == "SwordAndShield" then
    weaponModel = "goshield00"
    if bodyType == "Seidr" then
      local shieldConfigs = {
        "bandit00",
        "bandit03",
        "bandit04",
        "bandit05",
        "bandit06",
        "bandit07"
      }
      local randomShieldNum = math.random(1, 5)
      weaponConfig = shieldConfigs[randomShieldNum]
      spawnConfigTable.randomShieldNum = randomShieldNum
    else
      weaponConfig = "helWalker00"
    end
  end
  local attachments = {}
  table.insert(attachments, {model = weaponModel, config = weaponConfig})
  return {
    charConfig = charConfig,
    attachments = attachments,
    decap = decap
  }
end
function GetConfig_BanditHuman00(spawnConfigTable)
  local charConfig = "Bandit01"
  local weaponModel = "gosword00"
  local weaponConfig = "banditSword"
  if spawnConfigTable ~= nil then
    charConfig = "Bandit0" .. math.random(0, 4)
  end
  local attachments = {}
  table.insert(attachments, {model = weaponModel, config = weaponConfig})
  return {charConfig = charConfig, attachments = attachments}
end
function GetConfig_Brawler00(spawnConfigTable)
  local charConfig = "Bandit01"
  local weaponModel = "gomace00"
  local weaponConfig = "seidr"
  local decap
  if spawnConfigTable ~= nil then
    local powerLevelInt = GetPowerLevel(spawnConfigTable)
    local variant = "HELWALKER"
    if spawnConfigTable.Variant ~= nil then
      variant = spawnConfigTable.Variant
    end
    if variant == "Helwalker" then
      if 5 <= powerLevelInt then
        local brawler00ConfigsHelVeryHard = {
          "Helwalker00_veryhard",
          "Helwalker01_veryhard"
        }
        local rand = math.random(1, #brawler00ConfigsHelVeryHard)
        if rand == 1 then
          decap = {
            charConfig = "Helwalker001_decap",
            additionalDecap = {
              "Mask1_decap",
              "Armor_decap1"
            }
          }
        elseif rand == 2 then
          decap = {
            charConfig = "Helwalker001_decap",
            additionalDecap = {
              "Mask2_decap",
              "Armor_decap1"
            }
          }
        end
        charConfig = brawler00ConfigsHelVeryHard[rand]
        weaponConfig = "helwalker_hard"
      else
        local brawler00ConfigsHelModerate = {
          "Helwalker00",
          "Helwalker01"
        }
        local rand = math.random(1, #brawler00ConfigsHelModerate)
        if rand == 1 then
          decap = {
            charConfig = "Helwalker021_decap"
          }
        elseif rand == 2 then
          decap = {
            charConfig = "Helwalker011_decap",
            additionalDecap = {
              "Mask2_decap",
              "Armor_decap1"
            }
          }
        end
        charConfig = brawler00ConfigsHelModerate[rand]
        weaponConfig = "helwalker_easy"
      end
    elseif variant == "Default" then
      if 5 <= powerLevelInt then
        local brawler00ConfigsSeidrVeryHard = {
          "Brawler00_seidr_veryhard",
          "Brawler01_seidr_veryhard"
        }
        local rand = math.random(1, #brawler00ConfigsSeidrVeryHard)
        if rand == 1 then
          decap = {
            charConfig = "Helwalker001_decap",
            additionalDecap = {
              "Mask1_decap",
              "Armor_decap1"
            }
          }
        elseif rand == 2 then
          decap = {
            charConfig = "Helwalker001_decap",
            additionalDecap = {
              "Mask2_decap",
              "Armor_decap1"
            }
          }
        end
        charConfig = brawler00ConfigsSeidrVeryHard[rand]
        weaponConfig = "seidr"
      else
        local brawler00ConfigsSeidrModerate = {
          "Brawler00_seidr",
          "Brawler01_seidr"
        }
        local rand = math.random(1, #brawler00ConfigsSeidrModerate)
        if rand == 1 then
          decap = {
            charConfig = "Helwalker021_decap"
          }
        elseif rand == 2 then
          decap = {
            charConfig = "Helwalker011_decap"
          }
        end
        charConfig = brawler00ConfigsSeidrModerate[rand]
        weaponConfig = "seidr"
      end
    end
  end
  local attachments = {}
  table.insert(attachments, {model = weaponModel, config = weaponConfig})
  return {
    charConfig = charConfig,
    attachments = attachments,
    decap = decap
  }
end
function GetConfig_Crawler00(spawnConfigTable)
  local charConfig = "CrawlerTail_easy"
  local weaponModel, weaponConfig
  if spawnConfigTable ~= nil then
    local powerLevelInt = GetPowerLevel(spawnConfigTable)
    if 4 < powerLevelInt then
      charConfig = "CrawlerTail_hard"
    end
  end
  local attachments = {}
  table.insert(attachments, {model = weaponModel, config = weaponConfig})
  return {charConfig = charConfig, attachments = attachments}
end
function GetConfig_Crawler10(spawnConfigTable)
  local charConfig = "CrawlerMouth_easy"
  local weaponModel, weaponConfig
  if spawnConfigTable ~= nil then
    local powerLevelInt = GetPowerLevel(spawnConfigTable)
    if 4 < powerLevelInt then
      charConfig = "CrawlerMouth_hard"
    end
  end
  local attachments = {}
  table.insert(attachments, {model = weaponModel, config = weaponConfig})
  return {charConfig = charConfig, attachments = attachments}
end
function GetConfig_DarkOne00(spawnConfigTable)
  local charConfig = "Light01"
  local weaponModel = "godarkOneSpear00"
  local weaponConfig = "spear"
  local decap
  if spawnConfigTable ~= nil then
    local pLevelInt = GetPowerLevel(spawnConfigTable)
    local variant = spawnConfigTable.Variant
    if variant ~= nil then
      if variant == "QuickSpear" then
        local random = math.random(1, 2)
        if pLevelInt <= 2 then
          if random == 1 then
            charConfig = "Light01"
          else
            charConfig = "Light02"
          end
          decap = {
            charConfig = "Variant1_decap"
          }
        elseif 3 <= pLevelInt and pLevelInt <= 4 then
          if random == 1 then
            charConfig = "Light01_hard"
            decap = {
              charConfig = "Variant0_decap"
            }
          else
            charConfig = "Light02_hard"
            decap = {
              charConfig = "Variant1_decap"
            }
          end
        elseif 5 <= pLevelInt then
          if random == 1 then
            charConfig = "Light01_veryhard"
            decap = {
              charConfig = "Variant0_decap"
            }
          else
            charConfig = "Light02_veryhard"
            decap = {
              charConfig = "Variant1_decap"
            }
          end
        end
        weaponConfig = "spear"
      elseif variant == "HeavySpear" then
        if pLevelInt <= 2 then
          charConfig = "Heavy01"
        elseif 3 <= pLevelInt and pLevelInt <= 4 then
          charConfig = "Heavy01_hard"
        elseif 5 <= pLevelInt then
          charConfig = "Heavy01_veryhard"
        end
        weaponConfig = "mace"
        decap = {
          charConfig = "Variant3_decap"
        }
      elseif variant == "Summoner" then
        if pLevelInt <= 2 then
          charConfig = "Spawner01"
        elseif 3 <= pLevelInt and pLevelInt <= 4 then
          charConfig = "Spawner01_hard"
        elseif 5 <= pLevelInt then
          charConfig = "Spawner01_veryhard"
        end
        weaponConfig = "spawnerMace"
        decap = {
          charConfig = "Variant2_decap"
        }
      elseif variant == "HiveFighter" then
        local random = math.random(1, 2)
        if random == 1 then
          charConfig = "Light01"
        else
          charConfig = "Light02"
        end
        decap = {
          charConfig = "Variant1_decap"
        }
        weaponConfig = "spear"
      elseif variant == "HiveFighterWeak" then
        local random = math.random(1, 2)
        if random == 1 then
          charConfig = "Light01"
        else
          charConfig = "Light02"
        end
        weaponConfig = "spear"
        decap = {
          charConfig = "Variant1_decap"
        }
      end
    end
  end
  local attachments = {}
  table.insert(attachments, {model = weaponModel, config = weaponConfig})
  return {
    charConfig = charConfig,
    attachments = attachments,
    decap = decap
  }
end
function GetConfig_DarkOneElite00(spawnConfigTable)
  local charConfig = "normalVariant"
  local weaponModel = "godarkOneEliteSpear00"
  local weaponConfig = "eliteHeavy"
  local decap
  if spawnConfigTable ~= nil then
    local pLevelInt = GetPowerLevel(spawnConfigTable)
    local variant = spawnConfigTable.Variant
    if variant ~= nil then
      if variant == "Normal" then
        if 4 < pLevelInt then
          charConfig = "veryhardVariant"
        else
          charConfig = "normalVariant"
        end
        weaponConfig = "eliteHeavy"
        decap = {
          charConfig = "normalVariant_decap"
        }
      else
        charConfig = "hardVariant"
        decap = {
          charConfig = "hardVariant_decap"
        }
        weaponConfig = "eliteBoss"
      end
    end
  end
  local attachments = {}
  table.insert(attachments, {model = weaponModel, config = weaponConfig})
  return {
    charConfig = charConfig,
    attachments = attachments,
    decap = decap
  }
end
function GetConfig_Dragon00(spawnConfigTable)
  local charConfig, weaponModel, weaponConfig
  if spawnConfigTable ~= nil and spawnConfigTable.Variant ~= nil then
    charConfig = "turret" .. spawnConfigTable.Variant
  end
  local attachments = {}
  table.insert(attachments, {model = weaponModel, config = weaponConfig})
  return {charConfig = charConfig, attachments = attachments}
end
function GetConfig_Draugr00(spawnConfigTable)
  local charConfig, weaponModel, decap
  local currentCharConfig = spawnConfigTable.BodyType
  if currentCharConfig == nil then
    return {
      charConfig = charConfig,
      weaponModel = weaponModel,
      weaponConfig = nil
    }
  end
  local powerLevelInt = GetPowerLevel(spawnConfigTable)
  local currentWeaponType = spawnConfigTable.WeaponType
  local hasShield = false
  if currentWeaponType == "OneHand" then
    weaponModel = "godraugrSword00"
  elseif currentWeaponType == "TwoHand" then
    currentCharConfig = "heavy"
    weaponModel = "godraugrTwoHandedAxe00"
  elseif currentWeaponType == "DualWield" then
    currentCharConfig = "light"
    weaponModel = "godraugrAxe01"
  elseif currentWeaponType == "Shield" then
    hasShield = true
    weaponModel = "godraugrSword00"
    currentCharConfig = "medium"
  end
  if spawnConfigTable.TurretMode and spawnConfigTable.TurretModeBreakRange ~= nil and spawnConfigTable.TurretModeBreakRange <= 0 then
    currentCharConfig = "light"
  end
  local shieldString = ""
  if hasShield then
    shieldString = "_ArmShield"
  end
  local difficulty = "_veryeasy"
  if powerLevelInt == 1 then
    difficulty = "_veryeasy"
  elseif 1 < powerLevelInt and powerLevelInt < 4 then
    difficulty = "_easy"
  elseif 4 <= powerLevelInt and powerLevelInt < 6 then
    difficulty = "_moderate"
  elseif 6 <= powerLevelInt and powerLevelInt < 8 then
    difficulty = "_hard"
  else
    difficulty = "_veryhard"
  end
  if currentCharConfig == "light" then
    if difficulty == "_moderate" then
      decap = {
        charConfig = "d_light_decap2"
      }
    else
      decap = {
        charConfig = "d_light_decap1"
      }
    end
  elseif currentCharConfig == "medium" then
    if difficulty == "_moderate" or difficulty == "_easy" then
      decap = {
        charConfig = "d_medium_decap1"
      }
    else
      decap = {
        charConfig = "d_medium_decap2"
      }
    end
  elseif currentCharConfig == "heavy" then
    if difficulty == "_veryeasy" or difficulty == "_easy" then
      decap = {
        charConfig = "d_heavy_decap1"
      }
    else
      decap = {
        charConfig = "d_heavy_decap2"
      }
    end
  end
  charConfig = "d_" .. currentCharConfig .. difficulty .. shieldString
  if 8 < powerLevelInt then
    powerLevelInt = 8
  end
  local weaponConfigs = {
    "veryEasy",
    "easy",
    "easy",
    "moderate",
    "moderate",
    "hard",
    "hard",
    "veryHard"
  }
  local attachments = {}
  table.insert(attachments, {
    model = weaponModel,
    config = weaponConfigs[powerLevelInt]
  })
  return {
    charConfig = charConfig,
    attachments = attachments,
    decap = decap
  }
end
function GetConfig_Draugr00_1hsword(spawnConfigTable)
  return {
    charConfig = "medium_Pristine1",
    attachments = nil
  }
end
function GetConfig_Drummer00(spawnConfigTable)
  return nil
end
function GetConfig_EarthDragon00(spawnConfigTable)
  local decapattachments = {
    "damageState_p1_decap",
    "damageState_p2_decap",
    "damageState_p3_decap",
    "damageState_p4_decap"
  }
  return {
    charConfig = nil,
    attachments = nil,
    decap = {
      useGlobalEncounter = true,
      charConfig = "damageState_p5_decap",
      additionalDecap = decapattachments
    }
  }
end
function GetConfig_Fanatic00(spawnConfigTable)
  local charConfig = "helwalker00"
  local decap = {
    charConfig = "Fanatic_decap"
  }
  if spawnConfigTable ~= nil then
    local variant = spawnConfigTable.Variant
    if variant ~= nil then
      local pLevelInt = GetPowerLevel(spawnConfigTable)
      if variant == "Default-Bomber" then
        charConfig = "fanatic00"
      elseif variant == "Seidr-Bomber" then
        if pLevelInt <= 2 then
          charConfig = "Fanatic00_seidr"
        elseif 3 <= pLevelInt and pLevelInt <= 4 then
          charConfig = "Fanatic00_seidr_hard"
          decap.additionalDecap = {
            "Horns_decap"
          }
        elseif 5 <= pLevelInt then
          charConfig = "Fanatic00_seidr_veryhard"
          decap.additionalDecap = {
            "Horns_decap"
          }
        end
      elseif variant == "Helwalker-Archer" then
        if pLevelInt <= 2 then
          charConfig = "Fanatic00_hel"
        elseif 3 <= pLevelInt and pLevelInt <= 4 then
          charConfig = "Fanatic00_hel_hard"
          decap.additionalDecap = {"Ice_decap"}
        elseif 5 <= pLevelInt then
          charConfig = "Fanatic00_hel_veryhard"
          decap.additionalDecap = {"Ice_decap"}
        end
      elseif variant == "Helwalker-Bomber" then
        if pLevelInt <= 2 then
          charConfig = "Fanatic00_hel"
        elseif 3 <= pLevelInt and pLevelInt <= 4 then
          charConfig = "Fanatic00_hel_hard"
          decap.additionalDecap = {"Ice_decap"}
        elseif 5 <= pLevelInt then
          charConfig = "Fanatic00_hel_veryhard"
          decap.additionalDecap = {"Ice_decap"}
        end
      end
    end
  end
  return {
    charConfig = charConfig,
    attachments = nil,
    decap = decap
  }
end
function GetConfig_Flyer00(spawnConfigTable)
  local charConfig = "Flyer_seidr_easy"
  if spawnConfigTable == nil then
    return {charConfig = charConfig, attachments = nil}
  end
  local flyerType = spawnConfigTable.FlyerType
  local pLevelInt = GetPowerLevel(spawnConfigTable)
  if flyerType == "Seidr" then
    if 4 < pLevelInt then
      charConfig = "Flyer_seidr_hard"
    else
      charConfig = "Flyer_seidr_easy"
    end
  elseif flyerType == "Fire" then
    if 4 < pLevelInt then
      charConfig = "Flyer_fire_hard"
    else
      charConfig = "Flyer_fire_easy"
    end
  elseif flyerType == "Suicide" then
    if 4 < pLevelInt then
      charConfig = "Flyer_suicide_hard"
    else
      charConfig = "Flyer_suicide_easy"
    end
  elseif flyerType == "Ice" then
    if 4 < pLevelInt then
      charConfig = "Flyer_ice_hard"
    else
      charConfig = "Flyer_ice_easy"
    end
  elseif flyerType == "Blind" then
    if 4 < pLevelInt then
      charConfig = "Flyer_blind_hard"
    else
      charConfig = "Flyer_blind_easy"
    end
  elseif flyerType == "Possess" then
    if 4 < pLevelInt then
      charConfig = "Flyer_posses_hard"
    else
      charConfig = "Flyer_posses_easy"
    end
  else
    print("!!!! FLYER !!!! -- something wasnt set correctly on the spawner, so proper config and dTree are not set")
  end
  return {charConfig = charConfig, attachments = nil}
end
function GetConfig_Flyer10(spawnConfigTable)
  return GetConfig_Flyer00(spawnConfigTable)
end
function GetConfig_Freya00(spawnConfigTable)
  return nil
end
function GetConfig_FreyaVines00(spawnConfigTable)
  return nil
end
function GetConfig_Goblin00(spawnConfigTable)
  return nil
end
function GetConfig_Golem00(spawnConfigTable)
  local charConfig = "souleater_moderate"
  if spawnConfigTable ~= nil and spawnConfigTable.BodyType ~= nil and spawnConfigTable.BodyType == "SoulEater_v2" then
    charConfig = "souleater_veryhard"
  end
  return {charConfig = charConfig, attachments = nil}
end
function GetConfig_Golem10(spawnConfigTable)
  local charConfig = "woodland_moderate"
  if spawnConfigTable ~= nil and spawnConfigTable.BodyType ~= nil and spawnConfigTable.BodyType == "Woodland_v2" then
    charConfig = "woodland_veryhard"
  end
  return {charConfig = charConfig, attachments = nil}
end
function GetConfig_Golem20(spawnConfigTable)
  local charConfig = "onyx_moderate"
  if spawnConfigTable ~= nil and spawnConfigTable.BodyType ~= nil and spawnConfigTable.BodyType == "Onyx_v2" then
    charConfig = "onyx_veryhard"
  end
  return {charConfig = charConfig, attachments = nil}
end
function GetConfig_Golem30(spawnConfigTable)
  local charConfig = "frost_moderate"
  if spawnConfigTable ~= nil and spawnConfigTable.BodyType ~= nil and spawnConfigTable.BodyType == "Frost_v2" then
    charConfig = "frost_veryhard1"
  end
  return {charConfig = charConfig, attachments = nil}
end
function GetConfig_Jotunn00(spawnConfigTable)
  local charConfig = "config0"
  local powerLevelInt = GetPowerLevel(spawnConfigTable)
  if powerLevelInt <= 2 then
    charConfig = "config0"
  elseif 3 <= powerLevelInt and powerLevelInt <= 4 then
    charConfig = "config0_hard"
  elseif 5 <= powerLevelInt then
    charConfig = "config0_veryhard"
  end
  local attachments = {}
  return {
    charConfig = charConfig,
    attachments = nil,
    decap = {
      charConfig = "config0_decap"
    }
  }
end
function GetConfig_Jotunn10(spawnConfigTable)
  local charConfig = "config1"
  local powerLevelInt = GetPowerLevel(spawnConfigTable)
  if powerLevelInt <= 2 then
    charConfig = "config1"
  elseif 3 <= powerLevelInt and powerLevelInt <= 4 then
    charConfig = "config1_hard"
  elseif 5 <= powerLevelInt then
    charConfig = "config1_veryhard"
  end
  local attachments = {}
  return {
    charConfig = charConfig,
    attachments = nil,
    decap = {
      charConfig = "config1_decap"
    }
  }
end
function GetConfig_Jotunn20(spawnConfigTable)
  return {
    charConfig = "config1",
    attachments = nil,
    decap = {
      charConfig = "config1_decap"
    }
  }
end
function GetConfig_Projection00(spawnConfigTable)
  local charConfig, decap
  if spawnConfigTable == nil then
    return {charConfig = charConfig, attachments = nil}
  end
  local bodyType = spawnConfigTable.BodyType
  local pLevelInt = GetPowerLevel(spawnConfigTable)
  if bodyType ~= nil then
    if bodyType == "Seidr" then
      if 4 < pLevelInt then
        charConfig = "Projection_seidr_veryhard"
      else
        charConfig = "Projection_seidr_moderate"
      end
      decap = {
        charConfig = "Projection01_decap"
      }
    elseif bodyType == "Hellwalker" then
      if 4 < pLevelInt then
        charConfig = "Projection_helwalker_veryhard"
      else
        charConfig = "Projection_helwalker_moderate"
      end
      decap = {
        charConfig = "Projection01_decap"
      }
    elseif bodyType == "Freya" then
      charConfig = "Projection_freya"
      decap = {
        charConfig = "Projection02_decap"
      }
    end
  end
  return {
    charConfig = charConfig,
    attachments = nil,
    decap = decap
  }
end
function GetConfig_Projection10(spawnConfigTable)
  return GetConfig_Projection00(spawnConfigTable)
end
function GetConfig_Projection20(spawnConfigTable)
  return GetConfig_Projection00(spawnConfigTable)
end
function GetConfig_Traveler00(spawnConfigTable)
  local charConfig
  local weaponModel = "gotsword00"
  local weaponConfig = "config00"
  local decapConfig
  if spawnConfigTable == nil then
    local attachments = {}
    table.insert(attachments, {model = weaponModel, config = weaponConfig})
    return {charConfig = charConfig, attachments = attachments}
  end
  local travelerType = spawnConfigTable.TravelerType
  local pLevelInt = GetPowerLevel(spawnConfigTable)
  if travelerType ~= nil then
    if travelerType == "Turtle" then
      if 4 < pLevelInt then
        charConfig = "SeidrHand_veryhard"
      else
        charConfig = "SeidrHand_moderate"
      end
      weaponConfig = "config20"
      decapConfig = "SeidrHand_decap"
    elseif travelerType == "Berserker" then
      if 4 < pLevelInt then
        charConfig = "Helwalker_veryhard"
      else
        charConfig = "Helwalker_moderate"
      end
      weaponConfig = "config10"
      decapConfig = "Helwalker_decap"
    else
      if 4 < pLevelInt then
        charConfig = "SeidrEye_veryhard"
      else
        charConfig = "SeidrEye_moderate"
      end
      decapConfig = "SeidrEye_decap"
      weaponConfig = "config00"
    end
  end
  local attachments = {}
  table.insert(attachments, {model = weaponModel, config = weaponConfig})
  local decapParam
  if decapConfig ~= nil then
    decapParam = {charConfig = decapConfig}
  end
  return {
    charConfig = charConfig,
    attachments = attachments,
    decap = decapParam
  }
end
function GetConfig_Troll00(spawnConfigTable)
  local charConfig = "troll00"
  local weaponModel = "gotrollStone00"
  local weaponConfig = "trollStone00"
  local decap = {
    charConfig = "troll00_decap"
  }
  if spawnConfigTable == nil then
    local attachments = {}
    table.insert(attachments, {model = weaponModel, config = weaponConfig})
    return {charConfig = charConfig, attachments = attachments}
  end
  local variant = spawnConfigTable.Variant
  if variant ~= nil then
    if variant == "Variant2" then
      charConfig = "troll00_moderate"
      weaponConfig = "trollStone00_moderate"
    elseif variant == "Variant3" then
      charConfig = "troll00_veryhard"
      weaponConfig = "trollStone00_veryhard"
    end
  end
  local attachments = {}
  table.insert(attachments, {model = weaponModel, config = weaponConfig})
  return {
    charConfig = charConfig,
    attachments = attachments,
    decap = decap
  }
end
function GetConfig_Troll10(spawnConfigTable)
  local charConfig = "troll10"
  local weaponModel = "gotrollStone10"
  local weaponConfig = "trollStone10"
  local decap = {
    charConfig = "troll10_decap"
  }
  if spawnConfigTable == nil then
    local attachments = {}
    table.insert(attachments, {model = weaponModel, config = weaponConfig})
    return {charConfig = charConfig, attachments = attachments}
  end
  local variant = spawnConfigTable.Variant
  if variant ~= nil then
    if variant == "Variant2" then
      charConfig = "troll10_veryhard"
      weaponConfig = "trollStone10_veryhard"
    elseif variant == "Variant3" then
      charConfig = "troll10_veryhard"
      weaponConfig = "trollStone10_veryhard"
    end
  end
  local attachments = {}
  table.insert(attachments, {model = weaponModel, config = weaponConfig})
  return {
    charConfig = charConfig,
    attachments = attachments,
    decap = decap
  }
end
function GetConfig_Troll20(spawnConfigTable)
  local charConfig = "troll20"
  local weaponModel = "gotrollStone20"
  local weaponConfig = "trollStone20"
  local decap = {
    charConfig = "troll20_decap"
  }
  if spawnConfigTable == nil then
    local attachments = {}
    table.insert(attachments, {model = weaponModel, config = weaponConfig})
    return {charConfig = charConfig, attachments = attachments}
  end
  local variant = spawnConfigTable.Variant
  local isTwinBrother = false
  if (variant == "Variant1" or variant == nil) and spawnConfigTable.TwinBrother ~= nil and spawnConfigTable.TwinBrother == true then
    isTwinBrother = true
  end
  if variant ~= nil then
    if variant == "Variant2" then
      charConfig = "troll20_veryhard"
      weaponConfig = "trollStone20_veryhard"
    elseif variant == "Variant3" then
      charConfig = "troll20_veryhard"
      weaponConfig = "trollStone20_veryhard"
    elseif isTwinBrother == true then
      charConfig = "troll20_ice"
      weaponConfig = "trollStone20_ice"
    end
  elseif isTwinBrother then
    charConfig = "troll20_ice"
    weaponConfig = "trollStone20_ice"
  end
  local attachments = {}
  table.insert(attachments, {model = weaponModel, config = weaponConfig})
  return {
    charConfig = charConfig,
    attachments = attachments,
    decap = decap
  }
end
function GetConfig_Troll30(spawnConfigTable)
  local attachments = {}
  table.insert(attachments, {
    model = "gotrollStone30",
    config = nil
  })
  return {
    charConfig = "troll30",
    attachments = attachments,
    decap = {
      charConfig = "troll00_decap"
    }
  }
end
function GetConfig_Valkyrie00(spawnConfigTable)
  local charConfig
  if spawnConfigTable ~= nil then
    local valkyrie_type = spawnConfigTable.Type
    if valkyrie_type ~= nil then
      if valkyrie_type == "Slugger" then
        charConfig = "raven"
      elseif valkyrie_type == "Evader" then
        charConfig = "eagle"
      elseif valkyrie_type == "Defender" then
        charConfig = "bear"
      elseif valkyrie_type == "Fire" then
        charConfig = "vulture"
      elseif valkyrie_type == "Ice" then
        charConfig = "boar"
      elseif valkyrie_type == "Shooter" then
        charConfig = "owl"
      elseif valkyrie_type == "Summoner" then
        charConfig = "ram"
      elseif valkyrie_type == "Grappler" then
        charConfig = "stag"
      elseif valkyrie_type == "Queen" then
        charConfig = "queen"
      end
    end
  end
  return {charConfig = charConfig, attachments = nil}
end
function GetConfig_ValkyrieGhost00(spawnConfigTable)
  return nil
end
function GetConfig_Witch00(spawnConfigTable)
  local charConfig = "config00"
  if spawnConfigTable ~= nil then
    local pLevelInt = GetPowerLevel(spawnConfigTable)
    if pLevelInt <= 2 then
      charConfig = "config00"
    elseif pLevelInt <= 4 then
      charConfig = "config00_hard"
    elseif 5 <= pLevelInt then
      charConfig = "config00_veryhard"
    end
  end
  return {
    charConfig = charConfig,
    attachments = nil,
    decap = {
      charConfig = "config00_decap"
    }
  }
end
function GetConfig_Witch10(spawnConfigTable)
  local charConfig = "config10"
  if spawnConfigTable ~= nil then
    local pLevelInt = GetPowerLevel(spawnConfigTable)
    if pLevelInt <= 2 then
      charConfig = "config10"
    elseif pLevelInt <= 4 then
      charConfig = "config10_hard"
    elseif 5 <= pLevelInt then
      charConfig = "config10_veryhard"
    end
  end
  return {
    charConfig = charConfig,
    attachments = nil,
    decap = {
      charConfig = "config10_decap"
    }
  }
end
function GetConfig_Witch20(spawnConfigTable)
  local charConfig = "config20"
  local decap
  if spawnConfigTable ~= nil then
    local pLevelInt = GetPowerLevel(spawnConfigTable)
    if pLevelInt <= 4 then
      charConfig = "config20"
      decap = {
        charConfig = "config20_decap"
      }
    elseif 5 <= pLevelInt then
      charConfig = "config20_veryhard"
      decap = {
        charConfig = "config20_veryhard_decap"
      }
    end
  end
  return {
    charConfig = charConfig,
    attachments = nil,
    decap = decap
  }
end
function GetConfig_Wolf00(spawnConfigTable)
  local charConfig
  if spawnConfigTable ~= nil then
    local bodyType = spawnConfigTable.Variant
    local pLevelInt = GetPowerLevel(spawnConfigTable)
    if bodyType ~= nil then
      if bodyType == "Poison" then
        if pLevelInt <= 2 then
          charConfig = "wolf01_easy"
        elseif 3 <= pLevelInt and pLevelInt <= 4 then
          charConfig = "wolf01_moderate"
        elseif 5 <= pLevelInt then
          charConfig = "wolf01_veryhard"
        end
      elseif pLevelInt <= 2 then
        charConfig = "wolf00_easy"
      elseif 3 <= pLevelInt and pLevelInt <= 4 then
        charConfig = "wolf00_moderate"
      elseif 5 <= pLevelInt then
        charConfig = "wolf00_veryhard"
      end
    end
  end
  return {
    charConfig = charConfig,
    attachments = nil,
    decap = {
      charConfig = "wolf00_decap"
    }
  }
end
function GetConfig_Wolf10(spawnConfigTable)
  return {charConfig = "DarkWolf0", attachments = nil}
end
function GetConfig_Wulver00(spawnConfigTable)
  local charConfig
  if spawnConfigTable ~= nil then
    local wulverType = spawnConfigTable.WulverType
    if wulverType ~= nil then
      local pLevelInt = GetPowerLevel(spawnConfigTable)
      if wulverType == "Power" then
        if pLevelInt <= 2 then
          charConfig = "power_easy"
        elseif pLevelInt <= 4 then
          charConfig = "power_hard"
        elseif 5 <= pLevelInt then
          charConfig = "power_veryhard"
        end
      elseif pLevelInt <= 2 then
        charConfig = "speed_easy"
      elseif pLevelInt <= 4 then
        charConfig = "speed_hard"
      elseif 5 <= pLevelInt then
        charConfig = "speed_veryhard"
      end
    end
  end
  return {charConfig = charConfig, attachments = nil}
end
function GetConfig_Wulver10(spawnConfigTable)
  return GetConfig_Wulver00(spawnConfigTable)
end
