/*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.gameserver.model.actor.instance;
import java.util.List;
import javolution.util.FastList;
import com.l2jserver.gameserver.model.L2Skill;
import com.l2jserver.gameserver.model.actor.L2Attackable;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.L2Trap;
import com.l2jserver.gameserver.model.olympiad.OlympiadGameManager;
import com.l2jserver.gameserver.model.quest.Quest;
import com.l2jserver.gameserver.model.quest.Quest.TrapAction;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
import com.l2jserver.gameserver.templates.chars.L2NpcTemplate;
public class L2TrapInstance extends L2Trap
{
private L2PcInstance _owner;
private int _level;
private boolean _isInArena = false;
private final List<Integer> _playersWhoDetectedMe = new FastList<Integer>();
/**
* @param objectId
* @param template
* @param owner
*/
public L2TrapInstance(int objectId, L2NpcTemplate template,
L2PcInstance owner, int lifeTime, L2Skill skill)
{
super(objectId, template, lifeTime, skill);
setInstanceType(InstanceType.L2TrapInstance);
setInstanceId(owner.getInstanceId());
_owner = owner;
_level = owner.getLevel();
}
public L2TrapInstance(int objectId, L2NpcTemplate template,
int instanceId, int lifeTime, L2Skill skill)
{
super(objectId, template, lifeTime, skill);
setInstanceType(InstanceType.L2TrapInstance);
setInstanceId(instanceId);
_owner = null;
if (skill != null)
_level = skill.getLevel();
else
_level = 1;
}
@Override
public int getLevel()
{
return _level;
}
@Override
public L2PcInstance getOwner()
{
return _owner;
}
@Override
public L2PcInstance getActingPlayer()
{
return _owner;
}
@Override
public void onSpawn()
{
super.onSpawn();
_isInArena = isInsideZone(ZONE_PVP) && !isInsideZone(ZONE_SIEGE);
_playersWhoDetectedMe.clear();
}
@Override
public void deleteMe()
{
if (_owner != null)
{
_owner.setTrap(null);
_owner = null;
}
super.deleteMe();
}
@Override
public void unSummon()
{
if (_owner != null)
{
_owner.setTrap(null);
_owner = null;
}
super.unSummon();
}
@Override
public int getKarma()
{
return _owner != null ? _owner.getKarma() : 0;
}
@Override
public byte getPvpFlag()
{
return _owner != null ? _owner.getPvpFlag() : 0;
}
@Override
public void sendDamageMessage(L2Character target, int damage, boolean mcrit, boolean pcrit, boolean miss)
{
if (miss || _owner == null)
return;
if (_owner.isInOlympiadMode() &&
target instanceof L2PcInstance &&
((L2PcInstance)target).isInOlympiadMode() &&
((L2PcInstance)target).getOlympiadGameId() == _owner.getOlympiadGameId())
{
OlympiadGameManager.getInstance().notifyCompetitorDamage(getOwner(), damage);
}
final SystemMessage sm;
if (target.isInvul() && !(target instanceof L2NpcInstance))
sm = SystemMessage.getSystemMessage(SystemMessageId.ATTACK_WAS_BLOCKED);
else
{
sm = SystemMessage.getSystemMessage(SystemMessageId.C1_GAVE_C2_DAMAGE_OF_S3);
sm.addCharName(this);
sm.addCharName(target);
sm.addNumber(damage);
}
_owner.sendPacket(sm);
}
@Override
public boolean canSee(L2Character cha)
{
if (cha != null && _playersWhoDetectedMe.contains(cha.getObjectId()))
return true;
if (_owner == null || cha == null)
return false;
if (cha == _owner)
return true;
if (cha instanceof L2PcInstance)
{
// observers can't see trap
if (((L2PcInstance)cha).inObserverMode())
return false;
// olympiad competitors can't see trap
if (_owner.isInOlympiadMode()
&& ((L2PcInstance)cha).isInOlympiadMode()
&& ((L2PcInstance)cha).getOlympiadSide() != _owner.getOlympiadSide())
return false;
}
if (_isInArena)
return true;
if (_owner.isInParty()
&& cha.isInParty()
&& _owner.getParty().getPartyLeaderOID() == cha.getParty().getPartyLeaderOID())
return true;
return false;
}
@Override
public void setDetected(L2Character detector)
{
if (_isInArena)
{
super.setDetected(detector);
return;
}
if (_owner != null && _owner.getPvpFlag() == 0 && _owner.getKarma() == 0)
return;
_playersWhoDetectedMe.add(detector.getObjectId());
if (getTemplate().getEventQuests(Quest.QuestEventType.ON_TRAP_ACTION) != null)
for (Quest quest : getTemplate().getEventQuests(Quest.QuestEventType.ON_TRAP_ACTION))
quest.notifyTrapAction(this, detector, TrapAction.TRAP_DETECTED);
super.setDetected(detector);
}
@Override
protected boolean checkTarget(L2Character target)
{
if (!L2Skill.checkForAreaOffensiveSkills(this, target, getSkill(), _isInArena))
return false;
// observers
if (target instanceof L2PcInstance && ((L2PcInstance)target).inObserverMode())
return false;
// olympiad own team and their summons not attacked
if (_owner != null && _owner.isInOlympiadMode())
{
final L2PcInstance player = target.getActingPlayer();
if (player != null
&& player.isInOlympiadMode()
&& player.getOlympiadSide() == _owner.getOlympiadSide())
return false;
}
if (_isInArena)
return true;
// trap owned by players not attack non-flagged players
if (_owner != null)
{
final L2PcInstance player = target.getActingPlayer();
if (target instanceof L2Attackable)
return true;
else if (player == null || (player.getPvpFlag() == 0 && player.getKarma() == 0))
return false;
}
return true;
}
}