/* * This file is part of the L2J Mobius project. * * 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 . */ package handlers.effecthandlers; import java.util.Collections; import java.util.HashSet; import java.util.Set; import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.StatsSet; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.effects.AbstractEffect; import com.l2jmobius.gameserver.model.holders.SkillHolder; import com.l2jmobius.gameserver.model.skills.AbnormalType; import com.l2jmobius.gameserver.model.skills.BuffInfo; import com.l2jmobius.gameserver.model.skills.Skill; import com.l2jmobius.gameserver.model.skills.SkillCaster; /** * Synergy effect implementation. */ public final class Synergy extends AbstractEffect { private final Set _requiredSlots; private final Set _optionalSlots; private final int _partyBuffSkillId; private final int _skillLevelScaleTo; private final int _minSlot; public Synergy(StatsSet params) { final String requiredSlots = params.getString("requiredSlots", null); if ((requiredSlots != null) && !requiredSlots.isEmpty()) { _requiredSlots = new HashSet<>(); for (String slot : requiredSlots.split(";")) { _requiredSlots.add(AbnormalType.getAbnormalType(slot)); } } else { _requiredSlots = Collections. emptySet(); } final String optionalSlots = params.getString("optionalSlots", null); if ((optionalSlots != null) && !optionalSlots.isEmpty()) { _optionalSlots = new HashSet<>(); for (String slot : optionalSlots.split(";")) { _optionalSlots.add(AbnormalType.getAbnormalType(slot)); } } else { _optionalSlots = Collections. emptySet(); } _partyBuffSkillId = params.getInt("partyBuffSkillId"); _skillLevelScaleTo = params.getInt("skillLevelScaleTo", 1); _minSlot = params.getInt("minSlot", 2); setTicks(params.getInt("ticks")); } @Override public boolean onActionTime(BuffInfo info) { if (info.getEffector().isDead()) { return false; } for (AbnormalType required : _requiredSlots) { if (!info.getEffector().hasAbnormalType(required)) { return info.getSkill().isToggle(); } } final int abnormalCount = (int) _optionalSlots.stream().filter(info.getEffector()::hasAbnormalType).count(); if (abnormalCount >= _minSlot) { final SkillHolder partyBuff = new SkillHolder(_partyBuffSkillId, Math.max(abnormalCount - 1, _skillLevelScaleTo)); final Skill partyBuffSkill = partyBuff.getSkill(); if (partyBuffSkill != null) { final L2Object target = partyBuffSkill.getTarget(info.getEffector(), info.getEffected(), false, false, false); if ((target != null) && target.isCharacter()) { SkillCaster.triggerCast(info.getEffector(), (L2Character) target, partyBuffSkill); } } else { _log.warning("Skill not found effect called from " + info.getSkill()); } } return info.getSkill().isToggle(); } }