name: Celestial
card_text: 2+ Fairy monsters
  You can discard 1 card; add 1 "The Sanctuary in the Sky", or 1 card that specifically lists "The Sanctuary in the Sky" in its text, from your Deck to your hand, or, if "The Sanctuary in the Sky" is on the field, you can add 1 Fairy monster instead. If another face-up Fairy monster you control is sent to the GY (except during the Damage Step): You can banish 1 Fairy monster from your GY; Special Summon 1 Fairy monster from your hand whose Level is higher than that banished monster's. You can only use each effect of "Celestial Knightlord Parshath" once per turn.
external_ids: local CARD_ID_1 = 56433456 --The Sanctuary in the Sky
  
lua: local CARD_ID_1 = 56433456 --The Sanctuary in the Sky
  local s, id, o = GetID()
  function s.initial_effect(c)
  	aux.AddCodeList(c, CARD_ID_1)
  	--link summon
  	c:EnableReviveLimit()
  	aux.AddLinkProcedure(c, aux.FilterBoolFunction(Card.IsLinkRace, RACE_FAIRY), 2)
  	--tohand
  	local e1 = Effect.CreateEffect(c)
  	e1:SetDescription(aux.Stringid(id, 0))
  	e1:SetCategory(CATEGORY_TOHAND + CATEGORY_SEARCH)
  	e1:SetType(EFFECT_TYPE_IGNITION)
  	e1:SetRange(LOCATION_MZONE)
  	e1:SetCountLimit(1, id)
  	e1:SetCost(s.thcost)
  	e1:SetTarget(s.thtg)
  	e1:SetOperation(s.thop)
  	c:RegisterEffect(e1)
  	--special summon
  	local e2 = Effect.CreateEffect(c)
  	e2:SetDescription(aux.Stringid(id, 1))
  	e2:SetCategory(CATEGORY_SPECIAL_SUMMON)
  	e2:SetType(EFFECT_TYPE_FIELD + EFFECT_TYPE_TRIGGER_O)
  	e2:SetProperty(EFFECT_FLAG_DELAY)
  	e2:SetCode(EVENT_TO_GRAVE)
  	e2:SetRange(LOCATION_MZONE)
  	e2:SetCountLimit(1, id + 1)
  	e2:SetCondition(s.spcon)
  	e2:SetCost(s.spcost)
  	e2:SetTarget(s.sptg)
  	e2:SetOperation(s.spop)
  	c:RegisterEffect(e2)
  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)
  	end
  	Duel.DiscardHand(tp, Card.IsDiscardable, 1, 1, REASON_COST + REASON_DISCARD)
  end
  function s.thfilter(c, thchk)
  	return (aux.IsCodeOrListed(c, CARD_ID_1) or thchk and c:IsRace(RACE_FAIRY)) and c:IsAbleToHand()
  end
  function s.thtg(e, tp, eg, ep, ev, re, r, rp, chk)
  	local thchk = Duel.IsEnvironment(CARD_ID_1)
  	if chk == 0 then
  		return Duel.IsExistingMatchingCard(s.thfilter, tp, LOCATION_DECK, 0, 1, nil, thchk)
  	end
  	Duel.SetOperationInfo(0, CATEGORY_TOHAND, nil, 1, tp, LOCATION_DECK)
  end
  function s.thop(e, tp, eg, ep, ev, re, r, rp)
  	local thchk = Duel.IsEnvironment(CARD_ID_1)
  	Duel.Hint(HINT_SELECTMSG, tp, HINTMSG_ATOHAND)
  	local g = Duel.SelectMatchingCard(tp, s.thfilter, tp, LOCATION_DECK, 0, 1, 1, nil, thchk)
  	if g:GetCount() > 0 then
  		Duel.SendtoHand(g, nil, REASON_EFFECT)
  		Duel.ConfirmCards(1 - tp, g)
  	end
  end
  function s.cfilter(c, tp)
  	return bit.band(c:GetPreviousRaceOnField(), RACE_FAIRY) ~= 0 and c:IsRace(RACE_FAIRY) and c:IsPreviousControler(tp) and c:IsPreviousLocation(LOCATION_MZONE) and c:IsPreviousPosition(POS_FACEUP)
  end
  function s.spcon(e, tp, eg, ep, ev, re, r, rp)
  	return eg:IsExists(s.cfilter, 1, nil, tp)
  end
  function s.spcost(e, tp, eg, ep, ev, re, r, rp, chk)
  	e:SetLabel(100)
  	return true
  end
  function s.costfilter(c, e, tp)
  	local lv = c:GetLevel()
  	return lv > 0 and c:IsRace(RACE_FAIRY) and Duel.IsExistingMatchingCard(s.spfilter, tp, LOCATION_HAND, 0, 1, nil, lv + 1, e, tp)
  end
  function s.spfilter(c, lv, e, tp)
  	return c:IsLevelAbove(lv) and c:IsRace(RACE_FAIRY) and c:IsCanBeSpecialSummoned(e, 0, tp, false, false)
  end
  function s.sptg(e, tp, eg, ep, ev, re, r, rp, chk)
  	if chk == 0 then
  		if e:GetLabel() ~= 100 then
  			return false
  		end
  		e:SetLabel(0)
  		return Duel.GetLocationCount(tp, LOCATION_MZONE) > 0 and Duel.IsExistingMatchingCard(s.costfilter, tp, LOCATION_GRAVE, 0, 1, nil, e, tp)
  	end
  	Duel.Hint(HINT_SELECTMSG, tp, HINTMSG_REMOVE)
  	local rg = Duel.SelectMatchingCard(tp, s.costfilter, tp, LOCATION_GRAVE, 0, 1, 1, nil, e, tp)
  	e:SetLabel(rg:GetFirst():GetLevel())
  	Duel.Remove(rg, POS_FACEUP, REASON_COST)
  	Duel.SetOperationInfo(0, CATEGORY_SPECIAL_SUMMON, nil, 1, tp, LOCATION_HAND)
  end
  function s.spop(e, tp, eg, ep, ev, re, r, rp)
  	if Duel.GetLocationCount(tp, LOCATION_MZONE) <= 0 then
  		return
  	end
  	local lv = e:GetLabel()
  	Duel.Hint(HINT_SELECTMSG, tp, HINTMSG_SPSUMMON)
  	local g = Duel.SelectMatchingCard(tp, s.spfilter, tp, LOCATION_HAND, 0, 1, 1, nil, lv + 1, e, tp)
  	if g:GetCount() > 0 then
  		Duel.SpecialSummon(g, 0, tp, tp, false, false, POS_FACEUP)
  	end
  end
  
  
source_text: Celestial
  2+ Fairy monsters
  You can discard 1 card; add 1 "The Sanctuary in the Sky", or 1 card that specifically lists "The Sanctuary in the Sky" in its text, from your Deck to your hand, or, if "The Sanctuary in the Sky" is on the field, you can add 1 Fairy monster instead. If another face-up Fairy monster you control is sent to the GY (except during the Damage Step): You can banish 1 Fairy monster from your GY; Special Summon 1 Fairy monster from your hand whose Level is higher than that banished monster's. You can only use each effect of "Celestial Knightlord Parshath" once per turn.
target_text: -- Celestial
  local CARD_ID_1 = 56433456 --The Sanctuary in the Sky
  local s, id, o = GetID()
  function s.initial_effect(c)
  	aux.AddCodeList(c, CARD_ID_1)
  	--link summon
  	c:EnableReviveLimit()
  	aux.AddLinkProcedure(c, aux.FilterBoolFunction(Card.IsLinkRace, RACE_FAIRY), 2)
  	--tohand
  	local e1 = Effect.CreateEffect(c)
  	e1:SetDescription(aux.Stringid(id, 0))
  	e1:SetCategory(CATEGORY_TOHAND + CATEGORY_SEARCH)
  	e1:SetType(EFFECT_TYPE_IGNITION)
  	e1:SetRange(LOCATION_MZONE)
  	e1:SetCountLimit(1, id)
  	e1:SetCost(s.thcost)
  	e1:SetTarget(s.thtg)
  	e1:SetOperation(s.thop)
  	c:RegisterEffect(e1)
  	--special summon
  	local e2 = Effect.CreateEffect(c)
  	e2:SetDescription(aux.Stringid(id, 1))
  	e2:SetCategory(CATEGORY_SPECIAL_SUMMON)
  	e2:SetType(EFFECT_TYPE_FIELD + EFFECT_TYPE_TRIGGER_O)
  	e2:SetProperty(EFFECT_FLAG_DELAY)
  	e2:SetCode(EVENT_TO_GRAVE)
  	e2:SetRange(LOCATION_MZONE)
  	e2:SetCountLimit(1, id + 1)
  	e2:SetCondition(s.spcon)
  	e2:SetCost(s.spcost)
  	e2:SetTarget(s.sptg)
  	e2:SetOperation(s.spop)
  	c:RegisterEffect(e2)
  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)
  	end
  	Duel.DiscardHand(tp, Card.IsDiscardable, 1, 1, REASON_COST + REASON_DISCARD)
  end
  function s.thfilter(c, thchk)
  	return (aux.IsCodeOrListed(c, CARD_ID_1) or thchk and c:IsRace(RACE_FAIRY)) and c:IsAbleToHand()
  end
  function s.thtg(e, tp, eg, ep, ev, re, r, rp, chk)
  	local thchk = Duel.IsEnvironment(CARD_ID_1)
  	if chk == 0 then
  		return Duel.IsExistingMatchingCard(s.thfilter, tp, LOCATION_DECK, 0, 1, nil, thchk)
  	end
  	Duel.SetOperationInfo(0, CATEGORY_TOHAND, nil, 1, tp, LOCATION_DECK)
  end
  function s.thop(e, tp, eg, ep, ev, re, r, rp)
  	local thchk = Duel.IsEnvironment(CARD_ID_1)
  	Duel.Hint(HINT_SELECTMSG, tp, HINTMSG_ATOHAND)
  	local g = Duel.SelectMatchingCard(tp, s.thfilter, tp, LOCATION_DECK, 0, 1, 1, nil, thchk)
  	if g:GetCount() > 0 then
  		Duel.SendtoHand(g, nil, REASON_EFFECT)
  		Duel.ConfirmCards(1 - tp, g)
  	end
  end
  function s.cfilter(c, tp)
  	return bit.band(c:GetPreviousRaceOnField(), RACE_FAIRY) ~= 0 and c:IsRace(RACE_FAIRY) and c:IsPreviousControler(tp) and c:IsPreviousLocation(LOCATION_MZONE) and c:IsPreviousPosition(POS_FACEUP)
  end
  function s.spcon(e, tp, eg, ep, ev, re, r, rp)
  	return eg:IsExists(s.cfilter, 1, nil, tp)
  end
  function s.spcost(e, tp, eg, ep, ev, re, r, rp, chk)
  	e:SetLabel(100)
  	return true
  end
  function s.costfilter(c, e, tp)
  	local lv = c:GetLevel()
  	return lv > 0 and c:IsRace(RACE_FAIRY) and Duel.IsExistingMatchingCard(s.spfilter, tp, LOCATION_HAND, 0, 1, nil, lv + 1, e, tp)
  end
  function s.spfilter(c, lv, e, tp)
  	return c:IsLevelAbove(lv) and c:IsRace(RACE_FAIRY) and c:IsCanBeSpecialSummoned(e, 0, tp, false, false)
  end
  function s.sptg(e, tp, eg, ep, ev, re, r, rp, chk)
  	if chk == 0 then
  		if e:GetLabel() ~= 100 then
  			return false
  		end
  		e:SetLabel(0)
  		return Duel.GetLocationCount(tp, LOCATION_MZONE) > 0 and Duel.IsExistingMatchingCard(s.costfilter, tp, LOCATION_GRAVE, 0, 1, nil, e, tp)
  	end
  	Duel.Hint(HINT_SELECTMSG, tp, HINTMSG_REMOVE)
  	local rg = Duel.SelectMatchingCard(tp, s.costfilter, tp, LOCATION_GRAVE, 0, 1, 1, nil, e, tp)
  	e:SetLabel(rg:GetFirst():GetLevel())
  	Duel.Remove(rg, POS_FACEUP, REASON_COST)
  	Duel.SetOperationInfo(0, CATEGORY_SPECIAL_SUMMON, nil, 1, tp, LOCATION_HAND)
  end
  function s.spop(e, tp, eg, ep, ev, re, r, rp)
  	if Duel.GetLocationCount(tp, LOCATION_MZONE) <= 0 then
  		return
  	end
  	local lv = e:GetLabel()
  	Duel.Hint(HINT_SELECTMSG, tp, HINTMSG_SPSUMMON)
  	local g = Duel.SelectMatchingCard(tp, s.spfilter, tp, LOCATION_HAND, 0, 1, 1, nil, lv + 1, e, tp)
  	if g:GetCount() > 0 then
  		Duel.SpecialSummon(g, 0, tp, tp, false, false, POS_FACEUP)
  	end
  end
  
  