name: Keeper
card_text: If this card is Normal or Special Summoned: You can discard 1 card; add 1 "Polymerization" Normal Spell or "Fusion" Normal Spell from your Deck to your hand. You can reveal 1 Fusion Monster in your Extra Deck; Special Summon 1 of the Fusion Materials mentioned on that monster from your GY, in face-down Defense Position. You can only use each effect of "Keeper of Dragon Magic" once per turn. You cannot Special Summon monsters from the Extra Deck, except Fusion Monsters, the turn you activate either of this card's effects.
external_ids: local SETCARD_ID_0 = 0x46 --Polymerization/Fusion
  
lua: local SETCARD_ID_0 = 0x46 --Polymerization/Fusion
  local s, id, o = GetID()
  function s.initial_effect(c)
  	--search
  	local e1 = Effect.CreateEffect(c)
  	e1:SetDescription(aux.Stringid(id, 0))
  	e1:SetCategory(CATEGORY_SEARCH + CATEGORY_TOHAND)
  	e1:SetType(EFFECT_TYPE_SINGLE + EFFECT_TYPE_TRIGGER_O)
  	e1:SetCode(EVENT_SUMMON_SUCCESS)
  	e1:SetProperty(EFFECT_FLAG_DELAY)
  	e1:SetCountLimit(1, id)
  	e1:SetCost(s.thcost)
  	e1:SetTarget(s.thtg)
  	e1:SetOperation(s.thop)
  	c:RegisterEffect(e1)
  	local e2 = e1:Clone()
  	e2:SetCode(EVENT_SPSUMMON_SUCCESS)
  	c:RegisterEffect(e2)
  	--spsummon
  	local e3 = Effect.CreateEffect(c)
  	e3:SetDescription(aux.Stringid(id, 1))
  	e3:SetCategory(CATEGORY_SPECIAL_SUMMON)
  	e3:SetType(EFFECT_TYPE_IGNITION)
  	e3:SetRange(LOCATION_MZONE)
  	e3:SetCountLimit(1, id + 1)
  	e3:SetCost(s.spcost)
  	e3:SetTarget(s.sptg)
  	e3:SetOperation(s.spop)
  	c:RegisterEffect(e3)
  	Duel.AddCustomActivityCounter(id, ACTIVITY_SPSUMMON, s.counterfilter)
  end
  function s.counterfilter(c)
  	return not c:IsSummonLocation(LOCATION_EXTRA) or c:IsType(TYPE_FUSION)
  end
  function s.cost(e, tp, eg, ep, ev, re, r, rp, chk)
  	if chk == 0 then
  		return Duel.GetCustomActivityCount(id, tp, ACTIVITY_SPSUMMON) == 0
  	end
  	local e1 = Effect.CreateEffect(e:GetHandler())
  	e1:SetType(EFFECT_TYPE_FIELD)
  	e1:SetProperty(EFFECT_FLAG_PLAYER_TARGET + EFFECT_FLAG_OATH)
  	e1:SetCode(EFFECT_CANNOT_SPECIAL_SUMMON)
  	e1:SetTargetRange(1, 0)
  	e1:SetTarget(s.splimit)
  	e1:SetReset(RESET_PHASE + PHASE_END)
  	Duel.RegisterEffect(e1, tp)
  end
  function s.splimit(e, c, sump, sumtype, sumpos, targetp, se)
  	return not c:IsType(TYPE_FUSION) and c:IsLocation(LOCATION_EXTRA)
  end
  function s.thcost(e, tp, eg, ep, ev, re, r, rp, chk)
  	if chk == 0 then
  		return Duel.IsExistingMatchingCard(Card.IsDiscardable, tp, LOCATION_HAND, 0, 1, nil) and s.cost(e, tp, eg, ep, ev, re, r, rp, 0)
  	end
  	Duel.DiscardHand(tp, Card.IsDiscardable, 1, 1, REASON_COST + REASON_DISCARD)
  	s.cost(e, tp, eg, ep, ev, re, r, rp, 1)
  end
  function s.thfilter(c)
  	return c:GetType() == TYPE_SPELL and c:IsSetCard(SETCARD_ID_0) and c:IsAbleToHand()
  end
  function s.thtg(e, tp, eg, ep, ev, re, r, rp, chk)
  	if chk == 0 then
  		return Duel.IsExistingMatchingCard(s.thfilter, tp, LOCATION_DECK, 0, 1, nil)
  	end
  	Duel.SetOperationInfo(0, CATEGORY_TOHAND, nil, 1, tp, LOCATION_DECK)
  end
  function s.thop(e, tp, eg, ep, ev, re, r, rp)
  	Duel.Hint(HINT_SELECTMSG, tp, HINTMSG_ATOHAND)
  	local g = Duel.SelectMatchingCard(tp, s.thfilter, tp, LOCATION_DECK, 0, 1, 1, nil)
  	if g:GetCount() > 0 then
  		Duel.SendtoHand(g, nil, REASON_EFFECT)
  		Duel.ConfirmCards(1 - tp, g)
  	end
  end
  function s.filter1(c, e, tp)
  	return c:IsType(TYPE_FUSION) and Duel.IsExistingMatchingCard(s.filter2, tp, LOCATION_GRAVE, 0, 1, nil, e, tp, c)
  end
  function s.filter2(c, e, tp, fc)
  	return c:IsCanBeSpecialSummoned(e, 0, tp, false, false, POS_FACEDOWN_DEFENSE) and aux.IsMaterialListCode(fc, c:GetCode())
  end
  function s.spcost(e, tp, eg, ep, ev, re, r, rp, chk)
  	if chk == 0 then
  		return s.cost(e, tp, eg, ep, ev, re, r, rp, 0) and Duel.IsExistingMatchingCard(s.filter1, tp, LOCATION_EXTRA, 0, 1, nil, e, tp)
  	end
  	Duel.Hint(HINT_SELECTMSG, tp, HINTMSG_CONFIRM)
  	local g = Duel.SelectMatchingCard(tp, s.filter1, tp, LOCATION_EXTRA, 0, 1, 1, nil, e, tp)
  	Duel.ConfirmCards(1 - tp, g)
  	e:SetLabelObject(g:GetFirst())
  	s.cost(e, tp, eg, ep, ev, re, r, rp, 1)
  end
  function s.sptg(e, tp, eg, ep, ev, re, r, rp, chk)
  	if chk == 0 then
  		return Duel.GetLocationCount(tp, LOCATION_MZONE) > 0
  	end
  	Duel.SetOperationInfo(0, CATEGORY_SPECIAL_SUMMON, nil, 1, tp, LOCATION_GRAVE)
  end
  function s.spop(e, tp, eg, ep, ev, re, r, rp)
  	if Duel.GetLocationCount(tp, LOCATION_MZONE) < 1 then
  		return
  	end
  	local fc = e:GetLabelObject()
  	Duel.Hint(HINT_SELECTMSG, tp, HINTMSG_SPSUMMON)
  	local g = Duel.SelectMatchingCard(tp, aux.NecroValleyFilter(s.filter2), tp, LOCATION_GRAVE, 0, 1, 1, nil, e, tp, fc)
  	if g:GetCount() > 0 then
  		Duel.SpecialSummon(g, 0, tp, tp, false, false, POS_FACEDOWN_DEFENSE)
  		Duel.ConfirmCards(1 - tp, g)
  	end
  end
  
  
source_text: Keeper
  If this card is Normal or Special Summoned: You can discard 1 card; add 1 "Polymerization" Normal Spell or "Fusion" Normal Spell from your Deck to your hand. You can reveal 1 Fusion Monster in your Extra Deck; Special Summon 1 of the Fusion Materials mentioned on that monster from your GY, in face-down Defense Position. You can only use each effect of "Keeper of Dragon Magic" once per turn. You cannot Special Summon monsters from the Extra Deck, except Fusion Monsters, the turn you activate either of this card's effects.
target_text: -- Keeper
  local SETCARD_ID_0 = 0x46 --Polymerization/Fusion
  local s, id, o = GetID()
  function s.initial_effect(c)
  	--search
  	local e1 = Effect.CreateEffect(c)
  	e1:SetDescription(aux.Stringid(id, 0))
  	e1:SetCategory(CATEGORY_SEARCH + CATEGORY_TOHAND)
  	e1:SetType(EFFECT_TYPE_SINGLE + EFFECT_TYPE_TRIGGER_O)
  	e1:SetCode(EVENT_SUMMON_SUCCESS)
  	e1:SetProperty(EFFECT_FLAG_DELAY)
  	e1:SetCountLimit(1, id)
  	e1:SetCost(s.thcost)
  	e1:SetTarget(s.thtg)
  	e1:SetOperation(s.thop)
  	c:RegisterEffect(e1)
  	local e2 = e1:Clone()
  	e2:SetCode(EVENT_SPSUMMON_SUCCESS)
  	c:RegisterEffect(e2)
  	--spsummon
  	local e3 = Effect.CreateEffect(c)
  	e3:SetDescription(aux.Stringid(id, 1))
  	e3:SetCategory(CATEGORY_SPECIAL_SUMMON)
  	e3:SetType(EFFECT_TYPE_IGNITION)
  	e3:SetRange(LOCATION_MZONE)
  	e3:SetCountLimit(1, id + 1)
  	e3:SetCost(s.spcost)
  	e3:SetTarget(s.sptg)
  	e3:SetOperation(s.spop)
  	c:RegisterEffect(e3)
  	Duel.AddCustomActivityCounter(id, ACTIVITY_SPSUMMON, s.counterfilter)
  end
  function s.counterfilter(c)
  	return not c:IsSummonLocation(LOCATION_EXTRA) or c:IsType(TYPE_FUSION)
  end
  function s.cost(e, tp, eg, ep, ev, re, r, rp, chk)
  	if chk == 0 then
  		return Duel.GetCustomActivityCount(id, tp, ACTIVITY_SPSUMMON) == 0
  	end
  	local e1 = Effect.CreateEffect(e:GetHandler())
  	e1:SetType(EFFECT_TYPE_FIELD)
  	e1:SetProperty(EFFECT_FLAG_PLAYER_TARGET + EFFECT_FLAG_OATH)
  	e1:SetCode(EFFECT_CANNOT_SPECIAL_SUMMON)
  	e1:SetTargetRange(1, 0)
  	e1:SetTarget(s.splimit)
  	e1:SetReset(RESET_PHASE + PHASE_END)
  	Duel.RegisterEffect(e1, tp)
  end
  function s.splimit(e, c, sump, sumtype, sumpos, targetp, se)
  	return not c:IsType(TYPE_FUSION) and c:IsLocation(LOCATION_EXTRA)
  end
  function s.thcost(e, tp, eg, ep, ev, re, r, rp, chk)
  	if chk == 0 then
  		return Duel.IsExistingMatchingCard(Card.IsDiscardable, tp, LOCATION_HAND, 0, 1, nil) and s.cost(e, tp, eg, ep, ev, re, r, rp, 0)
  	end
  	Duel.DiscardHand(tp, Card.IsDiscardable, 1, 1, REASON_COST + REASON_DISCARD)
  	s.cost(e, tp, eg, ep, ev, re, r, rp, 1)
  end
  function s.thfilter(c)
  	return c:GetType() == TYPE_SPELL and c:IsSetCard(SETCARD_ID_0) and c:IsAbleToHand()
  end
  function s.thtg(e, tp, eg, ep, ev, re, r, rp, chk)
  	if chk == 0 then
  		return Duel.IsExistingMatchingCard(s.thfilter, tp, LOCATION_DECK, 0, 1, nil)
  	end
  	Duel.SetOperationInfo(0, CATEGORY_TOHAND, nil, 1, tp, LOCATION_DECK)
  end
  function s.thop(e, tp, eg, ep, ev, re, r, rp)
  	Duel.Hint(HINT_SELECTMSG, tp, HINTMSG_ATOHAND)
  	local g = Duel.SelectMatchingCard(tp, s.thfilter, tp, LOCATION_DECK, 0, 1, 1, nil)
  	if g:GetCount() > 0 then
  		Duel.SendtoHand(g, nil, REASON_EFFECT)
  		Duel.ConfirmCards(1 - tp, g)
  	end
  end
  function s.filter1(c, e, tp)
  	return c:IsType(TYPE_FUSION) and Duel.IsExistingMatchingCard(s.filter2, tp, LOCATION_GRAVE, 0, 1, nil, e, tp, c)
  end
  function s.filter2(c, e, tp, fc)
  	return c:IsCanBeSpecialSummoned(e, 0, tp, false, false, POS_FACEDOWN_DEFENSE) and aux.IsMaterialListCode(fc, c:GetCode())
  end
  function s.spcost(e, tp, eg, ep, ev, re, r, rp, chk)
  	if chk == 0 then
  		return s.cost(e, tp, eg, ep, ev, re, r, rp, 0) and Duel.IsExistingMatchingCard(s.filter1, tp, LOCATION_EXTRA, 0, 1, nil, e, tp)
  	end
  	Duel.Hint(HINT_SELECTMSG, tp, HINTMSG_CONFIRM)
  	local g = Duel.SelectMatchingCard(tp, s.filter1, tp, LOCATION_EXTRA, 0, 1, 1, nil, e, tp)
  	Duel.ConfirmCards(1 - tp, g)
  	e:SetLabelObject(g:GetFirst())
  	s.cost(e, tp, eg, ep, ev, re, r, rp, 1)
  end
  function s.sptg(e, tp, eg, ep, ev, re, r, rp, chk)
  	if chk == 0 then
  		return Duel.GetLocationCount(tp, LOCATION_MZONE) > 0
  	end
  	Duel.SetOperationInfo(0, CATEGORY_SPECIAL_SUMMON, nil, 1, tp, LOCATION_GRAVE)
  end
  function s.spop(e, tp, eg, ep, ev, re, r, rp)
  	if Duel.GetLocationCount(tp, LOCATION_MZONE) < 1 then
  		return
  	end
  	local fc = e:GetLabelObject()
  	Duel.Hint(HINT_SELECTMSG, tp, HINTMSG_SPSUMMON)
  	local g = Duel.SelectMatchingCard(tp, aux.NecroValleyFilter(s.filter2), tp, LOCATION_GRAVE, 0, 1, 1, nil, e, tp, fc)
  	if g:GetCount() > 0 then
  		Duel.SpecialSummon(g, 0, tp, tp, false, false, POS_FACEDOWN_DEFENSE)
  		Duel.ConfirmCards(1 - tp, g)
  	end
  end
  
  