/*
* This file is part of aion-unique <aion-unique.org>.
*
* aion-unique 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.
*
* aion-unique 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 aion-unique. If not, see <http://www.gnu.org/licenses/>.
*/
package com.aionemu.gameserver.controllers.effect;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javolution.util.FastMap;
import com.aionemu.gameserver.model.gameobjects.Creature;
import com.aionemu.gameserver.model.gameobjects.player.Player;
import com.aionemu.gameserver.network.aion.serverpackets.SM_ABNORMAL_EFFECT;
import com.aionemu.gameserver.network.aion.serverpackets.SM_ABNORMAL_STATE;
import com.aionemu.gameserver.skillengine.effect.EffectId;
import com.aionemu.gameserver.skillengine.model.Effect;
import com.aionemu.gameserver.skillengine.model.SkillTargetSlot;
import com.aionemu.gameserver.skillengine.model.SkillType;
import com.aionemu.gameserver.taskmanager.tasks.PacketBroadcaster.BroadcastMode;
import com.aionemu.gameserver.utils.PacketSendUtility;
/**
* @author ATracer
*
*/
public class EffectController
{
private Creature owner;
private Map<String, Effect> passiveEffectMap = new FastMap<String, Effect>().shared();
private Map<String, Effect> noshowEffects = new FastMap<String, Effect>().shared();
private Map<String, Effect> abnormalEffectMap = new FastMap<String, Effect>().shared();
private int abnormals;
public EffectController(Creature owner)
{
this.owner = owner;
}
/**
* @return the owner
*/
public Creature getOwner()
{
return owner;
}
/**
*
* @param effect
*/
public void addEffect(Effect effect)
{
Map<String, Effect> mapToUpdate = getMapForEffect(effect);
Effect existingEffect = mapToUpdate.get(effect.getStack());
if(existingEffect != null)
{
// check stack level
if(existingEffect.getSkillStackLvl() > effect.getSkillStackLvl())
return;
// check skill level (when stack level same)
if(existingEffect.getSkillStackLvl() == effect.getSkillStackLvl()
&& existingEffect.getSkillLevel() > effect.getSkillLevel())
return;
existingEffect.endEffect();
}
if(effect.isToggle() && mapToUpdate.size() >= 3)
{
Iterator<Effect> iter = mapToUpdate.values().iterator();
Effect nextEffect = iter.next();
nextEffect.endEffect();
iter.remove();
}
mapToUpdate.put(effect.getStack(), effect);
effect.startEffect();
if(!effect.isPassive())
{
// effect icon updates
if(owner instanceof Player)
{
updatePlayerEffectIcons();
}
broadCastEffects();
}
}
/**
*
* @param effect
* @return
*/
private Map<String, Effect> getMapForEffect(Effect effect)
{
if(effect.isPassive())
return passiveEffectMap;
if(effect.isToggle())
return noshowEffects;
return abnormalEffectMap;
}
/**
*
* @param stack
* @return abnormalEffectMap
*/
public Effect getAnormalEffect(String stack)
{
return abnormalEffectMap.get(stack);
}
/**
* Broadcasts current effects to all visible objects
*/
public void broadCastEffects()
{
List<Effect> effects = getAbnormalEffects();
PacketSendUtility.broadcastPacket(getOwner(),
new SM_ABNORMAL_EFFECT(getOwner().getObjectId(), abnormals, effects));
}
/**
* Used when player see new player
*
* @param player
*/
public void sendEffectIconsTo(Player player)
{
List<Effect> effects = getAbnormalEffects();
PacketSendUtility.sendPacket(player, new SM_ABNORMAL_EFFECT(getOwner().getObjectId(),
abnormals, effects));
}
/**
*
* @param effect
*/
public void clearEffect(Effect effect)
{
abnormalEffectMap.remove(effect.getStack());
broadCastEffects();
if(owner instanceof Player)
{
updatePlayerEffectIcons();
}
}
/**
* Removes the effect by skillid.
*
* @param skillid
*/
public void removeEffect(int skillid)
{
for(Effect effect : abnormalEffectMap.values()){
if(effect.getSkillId()==skillid){
effect.endEffect();
abnormalEffectMap.remove(effect.getStack());
}
}
broadCastEffects();
if(owner instanceof Player)
{
updatePlayerEffectIcons();
}
}
/**
*
* @param effectId
*/
public void removeEffectByEffectId(int effectId)
{
for(Effect effect : abnormalEffectMap.values()){
if(effect.containsEffectId(effectId)){
effect.endEffect();
abnormalEffectMap.remove(effect.getStack());
}
}
broadCastEffects();
if(owner instanceof Player)
{
updatePlayerEffectIcons();
}
}
/**
* @param skillType
* @param value
*/
public void removeEffectBySkillType(SkillType skillType, int value)
{
for(Effect effect : abnormalEffectMap.values())
{
if(value == 0)
break;
if(effect.getSkillType() == skillType)
{
effect.endEffect();
abnormalEffectMap.remove(effect.getStack());
value--;
}
}
broadCastEffects();
if(owner instanceof Player)
{
updatePlayerEffectIcons();
}
}
/**
* Removes the effect by skillid.
*
* @param skillid
*/
public void removePassiveEffect(int skillid)
{
for(Effect effect : passiveEffectMap.values()){
if(effect.getSkillId()==skillid){
effect.endEffect();
passiveEffectMap.remove(effect.getStack());
}
}
}
/**
*
* @param skillid
*/
public void removeNoshowEffect(int skillid)
{
for(Effect effect : noshowEffects.values()){
if(effect.getSkillId()==skillid){
effect.endEffect();
noshowEffects.remove(effect.getStack());
}
}
}
/**
* @see TargetSlot
* @param targetSlot
*/
public void removeAbnormalEffectsByTargetSlot(SkillTargetSlot targetSlot)
{
for(Effect effect : abnormalEffectMap.values()){
if(effect.getTargetSlot() == targetSlot.ordinal()){
effect.endEffect();
abnormalEffectMap.remove(effect.getStack());
}
}
}
/**
* Removes all effects from controllers and ends them appropriately
* Passive effect will not be removed
*/
public void removeAllEffects()
{
for(Effect effect : abnormalEffectMap.values())
{
effect.endEffect();
}
abnormalEffectMap.clear();
for(Effect effect : noshowEffects.values())
{
effect.endEffect();
}
noshowEffects.clear();
}
public void updatePlayerEffectIcons()
{
getOwner().addPacketBroadcastMask(BroadcastMode.UPDATE_PLAYER_EFFECT_ICONS);
}
public void updatePlayerEffectIconsImpl()
{
List<Effect> effects = getAbnormalEffects();
PacketSendUtility.sendPacket((Player) owner,
new SM_ABNORMAL_STATE(effects, abnormals));
}
private List<Effect> getAbnormalEffects()
{
List<Effect> effects = new ArrayList<Effect>();
Iterator<Effect> iterator = iterator();
while(iterator.hasNext())
{
Effect effect = iterator.next();
if(effect != null)
effects.add(effect);
}
return effects;
}
/**
* ABNORMAL EFFECTS
*/
public void setAbnormal(int mask)
{
abnormals |= mask;
}
public void unsetAbnormal(int mask)
{
abnormals &= ~mask;
}
/**
* Used for checking unique abnormal states
*
* @param effectId
* @return
*/
public boolean isAbnoramlSet(EffectId effectId)
{
return (abnormals & effectId.getEffectId()) == effectId.getEffectId();
}
/**
* Used for compound abnormal state checks
*
* @param effectId
* @return
*/
public boolean isAbnormalState(EffectId effectId)
{
int state = abnormals & effectId.getEffectId();
return state > 0 && state <= effectId.getEffectId();
}
public int getAbnormals()
{
return abnormals;
}
/**
*
* @return
*/
public Iterator<Effect> iterator()
{
return abnormalEffectMap.values().iterator();
}
}