Generate a YGOPro Lua script for the following Yu-Gi-Oh card effect:
2 WATER monsters Unaffected by your opponent's monster effects while this card is in the Extra Monster Zone. During the Damage Step, if this card battles an opponent's monster, that opponent's monster is unaffected by card effects, except its own. When this card, or your "Marincess" Link Monster this card points to, is targeted for an attack: You can send 1 "Marincess" monster from your hand to the GY; for that battle, your monster cannot be destroyed by battle, also you take no battle damage.
--海晶乙女クリスタルハート
--Marincess Crystal Heart
--Scripted by Larry126 and AlphaKretin
local s,id=GetID()
function s.initial_effect(c)
	--link summon
	Link.AddProcedure(c,aux.FilterBoolFunctionEx(Card.IsAttribute,ATTRIBUTE_WATER),2,2)
	c:EnableReviveLimit()
	--immune
	local e1=Effect.CreateEffect(c)
	e1:SetType(EFFECT_TYPE_SINGLE)
	e1:SetCode(EFFECT_IMMUNE_EFFECT)
	e1:SetProperty(EFFECT_FLAG_SINGLE_RANGE)
	e1:SetRange(LOCATION_MZONE)
	e1:SetCondition(s.econ)
	e1:SetValue(s.efilter)
	c:RegisterEffect(e1)
	--other immune
	local e2=Effect.CreateEffect(c)
	e2:SetType(EFFECT_TYPE_FIELD)
	e2:SetCode(EFFECT_IMMUNE_EFFECT)
	e2:SetRange(LOCATION_MZONE)
	e2:SetTargetRange(0,LOCATION_MZONE)
	e2:SetCondition(s.imcon)
	e2:SetTarget(s.imtg)
	e2:SetValue(s.imval)
	c:RegisterEffect(e2)
	--protect battle
	local e3=Effect.CreateEffect(c)
	e3:SetDescription(aux.Stringid(id,0))
	e3:SetType(EFFECT_TYPE_FIELD+EFFECT_TYPE_TRIGGER_O)
	e3:SetCode(EVENT_BE_BATTLE_TARGET)
	e3:SetRange(LOCATION_MZONE)
	e3:SetCondition(s.indescond)
	e3:SetCost(s.indescost)
	e3:SetTarget(s.indestg)
	e3:SetOperation(s.indesop)
	c:RegisterEffect(e3)
end
s.listed_series={SET_MARINCESS}
function s.econ(e)
	return e:GetHandler():GetSequence()>4
end
function s.efilter(e,te)
	return te:IsMonsterEffect() and te:GetOwnerPlayer()~=e:GetHandlerPlayer()
end
function s.imcon(e)
	local ph=Duel.GetCurrentPhase()
	return (ph==PHASE_DAMAGE or ph==PHASE_DAMAGE_CAL)
end
function s.imtg(e,c)
	return c==e:GetHandler():GetBattleTarget()
end
function s.imval(e,re)
	return e:GetHandler():GetBattleTarget()~=re:GetOwner()
end
function s.indescond(e,tp,eg,ep,ev,re,r,rp)
	local at=Duel.GetAttackTarget()
	if not at then return false end
	local c=e:GetHandler()
	if at==c then return true end
	local lg=c:GetLinkedGroup()
	return at and at:IsControler(tp) and at:IsFaceup() and at:IsSetCard(SET_MARINCESS) and lg:IsContains(at)
end
function s.costfilter(c)
	return c:IsSetCard(SET_MARINCESS) and c:IsMonster() and c:IsAbleToGraveAsCost()
end
function s.indescost(e,tp,eg,ep,ev,re,r,rp,chk)
	if chk==0 then return Duel.IsExistingMatchingCard(s.costfilter,tp,LOCATION_HAND,0,1,nil) end
	Duel.DiscardHand(tp,s.costfilter,1,1,REASON_COST)
end
function s.indestg(e,tp,eg,ep,ev,re,r,rp,chk)
	if chk==0 then return true end
	Duel.GetAttackTarget():CreateEffectRelation(e)
end
function s.indesop(e,tp,eg,ep,ev,re,r,rp)
	local c=e:GetHandler()
	local at=Duel.GetAttackTarget()
	if at:IsRelateToEffect(e) then
		local e1=Effect.CreateEffect(c)
		e1:SetType(EFFECT_TYPE_SINGLE)
		e1:SetCode(EFFECT_INDESTRUCTABLE_BATTLE)
		e1:SetValue(1)
		e1:SetReset(RESET_EVENT|RESETS_STANDARD|RESET_PHASE|PHASE_DAMAGE)
		at:RegisterEffect(e1)
		local e2=Effect.CreateEffect(c)
		e2:SetType(EFFECT_TYPE_FIELD)
		e2:SetCode(EFFECT_AVOID_BATTLE_DAMAGE)
		e2:SetProperty(EFFECT_FLAG_PLAYER_TARGET)
		e2:SetTargetRange(1,0)
		e2:SetReset(RESET_PHASE|PHASE_DAMAGE)
		Duel.RegisterEffect(e2,tp)
	end
end