name: Soul
card_text: Place 1 card on top of the Deck from your hand, Deck, or GY, that is "Dark Magician" or mentions "Dark Magician" or "Dark Magician Girl", except "Soul Servant". During your Main Phase: You can banish this card from your GY; draw cards equal to the number of "Palladium" monsters, "Dark Magician", and/or "Dark Magician Girl", with different names, on the field and in the GYs. You can only use this effect of "Soul Servant" once per turn.
external_ids: local CARD_ID_0 = 46986414 --Dark Magician
  local CARD_ID_1 = 38033121 --Dark Magician Girl
  local SETCARD_ID_0 = 0x139 --Palladium
  
lua: local CARD_ID_0 = 46986414 --Dark Magician
  local CARD_ID_1 = 38033121 --Dark Magician Girl
  local SETCARD_ID_0 = 0x139 --Palladium
  local s, id, o = GetID()
  function s.initial_effect(c)
  	aux.AddCodeList(c, CARD_ID_0, CARD_ID_1)
  	--set top
  	local e1 = Effect.CreateEffect(c)
  	e1:SetDescription(aux.Stringid(id, 0))
  	e1:SetType(EFFECT_TYPE_ACTIVATE)
  	e1:SetCode(EVENT_FREE_CHAIN)
  	e1:SetHintTiming(0, TIMING_END_PHASE)
  	e1:SetTarget(s.target)
  	e1:SetOperation(s.activate)
  	c:RegisterEffect(e1)
  	--draw
  	local e2 = Effect.CreateEffect(c)
  	e2:SetDescription(aux.Stringid(id, 1))
  	e2:SetCategory(CATEGORY_DRAW)
  	e2:SetType(EFFECT_TYPE_IGNITION)
  	e2:SetRange(LOCATION_GRAVE)
  	e2:SetCountLimit(1, id)
  	e2:SetCost(aux.bfgcost)
  	e2:SetTarget(s.drtg)
  	e2:SetOperation(s.drop)
  	c:RegisterEffect(e2)
  end
  function s.filter(c)
  	return (aux.IsCodeOrListed(c, CARD_ID_0) or aux.IsCodeOrListed(c, CARD_ID_1)) and not c:IsCode(id) and (c:IsAbleToDeck() or c:IsLocation(LOCATION_DECK))
  end
  function s.target(e, tp, eg, ep, ev, re, r, rp, chk)
  	if chk == 0 then
  		return Duel.IsExistingMatchingCard(s.filter, tp, LOCATION_HAND + LOCATION_DECK + LOCATION_GRAVE, 0, 1, nil)
  	end
  	Duel.SetOperationInfo(0, CATEGORY_TODECK, nil, 1, tp, LOCATION_HAND + LOCATION_GRAVE)
  end
  function s.activate(e, tp, eg, ep, ev, re, r, rp)
  	Duel.Hint(HINT_SELECTMSG, tp, aux.Stringid(id, 2))
  	local g = Duel.SelectMatchingCard(tp, aux.NecroValleyFilter(s.filter), tp, LOCATION_HAND + LOCATION_DECK + LOCATION_GRAVE, 0, 1, 1, nil)
  	local tc = g:GetFirst()
  	if tc then
  		Duel.ShuffleDeck(tp)
  		Duel.HintSelection(g)
  		if tc:IsLocation(LOCATION_DECK) then
  			Duel.MoveSequence(tc, SEQ_DECKTOP)
  		else
  			Duel.SendtoDeck(tc, nil, SEQ_DECKTOP, REASON_EFFECT)
  		end
  		if tc:IsLocation(LOCATION_DECK) then
  			Duel.ConfirmDecktop(tp, 1)
  		end
  	end
  end
  function s.cfilter(c)
  	return (c:IsCode(CARD_ID_0, CARD_ID_1) or (c:IsSetCard(SETCARD_ID_0) and c:IsType(TYPE_MONSTER))) and (c:IsFaceup() or c:IsLocation(LOCATION_GRAVE))
  end
  function s.drtg(e, tp, eg, ep, ev, re, r, rp, chk)
  	local g = Duel.GetMatchingGroup(s.cfilter, tp, LOCATION_ONFIELD + LOCATION_GRAVE, LOCATION_ONFIELD + LOCATION_GRAVE, nil)
  	local ct = g:GetClassCount(Card.GetCode)
  	if chk == 0 then
  		return ct > 0 and Duel.IsPlayerCanDraw(tp, ct)
  	end
  	Duel.SetTargetPlayer(tp)
  	Duel.SetTargetParam(ct)
  	Duel.SetOperationInfo(0, CATEGORY_DRAW, nil, 0, tp, ct)
  end
  function s.drop(e, tp, eg, ep, ev, re, r, rp)
  	local p = Duel.GetChainInfo(0, CHAININFO_TARGET_PLAYER)
  	local g = Duel.GetMatchingGroup(s.cfilter, tp, LOCATION_ONFIELD + LOCATION_GRAVE, LOCATION_ONFIELD + LOCATION_GRAVE, nil)
  	local ct = g:GetClassCount(Card.GetCode)
  	Duel.Draw(p, ct, REASON_EFFECT)
  end
  
  
source_text: Soul
  Place 1 card on top of the Deck from your hand, Deck, or GY, that is "Dark Magician" or mentions "Dark Magician" or "Dark Magician Girl", except "Soul Servant". During your Main Phase: You can banish this card from your GY; draw cards equal to the number of "Palladium" monsters, "Dark Magician", and/or "Dark Magician Girl", with different names, on the field and in the GYs. You can only use this effect of "Soul Servant" once per turn.
target_text: -- Soul
  local CARD_ID_0 = 46986414 --Dark Magician
  local CARD_ID_1 = 38033121 --Dark Magician Girl
  local SETCARD_ID_0 = 0x139 --Palladium
  local s, id, o = GetID()
  function s.initial_effect(c)
  	aux.AddCodeList(c, CARD_ID_0, CARD_ID_1)
  	--set top
  	local e1 = Effect.CreateEffect(c)
  	e1:SetDescription(aux.Stringid(id, 0))
  	e1:SetType(EFFECT_TYPE_ACTIVATE)
  	e1:SetCode(EVENT_FREE_CHAIN)
  	e1:SetHintTiming(0, TIMING_END_PHASE)
  	e1:SetTarget(s.target)
  	e1:SetOperation(s.activate)
  	c:RegisterEffect(e1)
  	--draw
  	local e2 = Effect.CreateEffect(c)
  	e2:SetDescription(aux.Stringid(id, 1))
  	e2:SetCategory(CATEGORY_DRAW)
  	e2:SetType(EFFECT_TYPE_IGNITION)
  	e2:SetRange(LOCATION_GRAVE)
  	e2:SetCountLimit(1, id)
  	e2:SetCost(aux.bfgcost)
  	e2:SetTarget(s.drtg)
  	e2:SetOperation(s.drop)
  	c:RegisterEffect(e2)
  end
  function s.filter(c)
  	return (aux.IsCodeOrListed(c, CARD_ID_0) or aux.IsCodeOrListed(c, CARD_ID_1)) and not c:IsCode(id) and (c:IsAbleToDeck() or c:IsLocation(LOCATION_DECK))
  end
  function s.target(e, tp, eg, ep, ev, re, r, rp, chk)
  	if chk == 0 then
  		return Duel.IsExistingMatchingCard(s.filter, tp, LOCATION_HAND + LOCATION_DECK + LOCATION_GRAVE, 0, 1, nil)
  	end
  	Duel.SetOperationInfo(0, CATEGORY_TODECK, nil, 1, tp, LOCATION_HAND + LOCATION_GRAVE)
  end
  function s.activate(e, tp, eg, ep, ev, re, r, rp)
  	Duel.Hint(HINT_SELECTMSG, tp, aux.Stringid(id, 2))
  	local g = Duel.SelectMatchingCard(tp, aux.NecroValleyFilter(s.filter), tp, LOCATION_HAND + LOCATION_DECK + LOCATION_GRAVE, 0, 1, 1, nil)
  	local tc = g:GetFirst()
  	if tc then
  		Duel.ShuffleDeck(tp)
  		Duel.HintSelection(g)
  		if tc:IsLocation(LOCATION_DECK) then
  			Duel.MoveSequence(tc, SEQ_DECKTOP)
  		else
  			Duel.SendtoDeck(tc, nil, SEQ_DECKTOP, REASON_EFFECT)
  		end
  		if tc:IsLocation(LOCATION_DECK) then
  			Duel.ConfirmDecktop(tp, 1)
  		end
  	end
  end
  function s.cfilter(c)
  	return (c:IsCode(CARD_ID_0, CARD_ID_1) or (c:IsSetCard(SETCARD_ID_0) and c:IsType(TYPE_MONSTER))) and (c:IsFaceup() or c:IsLocation(LOCATION_GRAVE))
  end
  function s.drtg(e, tp, eg, ep, ev, re, r, rp, chk)
  	local g = Duel.GetMatchingGroup(s.cfilter, tp, LOCATION_ONFIELD + LOCATION_GRAVE, LOCATION_ONFIELD + LOCATION_GRAVE, nil)
  	local ct = g:GetClassCount(Card.GetCode)
  	if chk == 0 then
  		return ct > 0 and Duel.IsPlayerCanDraw(tp, ct)
  	end
  	Duel.SetTargetPlayer(tp)
  	Duel.SetTargetParam(ct)
  	Duel.SetOperationInfo(0, CATEGORY_DRAW, nil, 0, tp, ct)
  end
  function s.drop(e, tp, eg, ep, ev, re, r, rp)
  	local p = Duel.GetChainInfo(0, CHAININFO_TARGET_PLAYER)
  	local g = Duel.GetMatchingGroup(s.cfilter, tp, LOCATION_ONFIELD + LOCATION_GRAVE, LOCATION_ONFIELD + LOCATION_GRAVE, nil)
  	local ct = g:GetClassCount(Card.GetCode)
  	Duel.Draw(p, ct, REASON_EFFECT)
  end
  
  